Commit 9a6008b6 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 0bfe221f 7e09b979
......@@ -1798,7 +1798,7 @@ S: Maintained
PPP OVER ETHERNET
P: Michal Ostrowski
M: mostrows@styx.uwaterloo.ca
M: mostrows@speakeasy.net
S: Maintained
PREEMPTIBLE KERNEL
......
......@@ -113,6 +113,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* Queue packet */
skb_queue_tail(&tun->readq, skb);
dev->trans_start = jiffies;
/* Notify and wake up reader process */
if (tun->flags & TUN_FASYNC)
......@@ -259,6 +260,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx_ni(skb);
tun->dev->last_rx = jiffies;
tun->stats.rx_packets++;
tun->stats.rx_bytes += len;
......
......@@ -16,6 +16,7 @@
#ifndef _LINUX_CRYPTO_H
#define _LINUX_CRYPTO_H
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
......@@ -121,7 +122,14 @@ int crypto_unregister_alg(struct crypto_alg *alg);
/*
* Algorithm query interface.
*/
#ifdef CONFIG_CRYPTO
int crypto_alg_available(const char *name, u32 flags);
#else
static inline int crypto_alg_available(const char *name, u32 flags)
{
return 0;
}
#endif
/*
* Transforms: user-instantiated objects which encapsulate algorithms
......
......@@ -122,33 +122,6 @@ do { \
#define IP_NF_ASSERT(x)
#endif
struct ip_conntrack_expect
{
/* Internal linked list (global expectation list) */
struct list_head list;
/* We expect this tuple, with the following mask */
struct ip_conntrack_tuple tuple, mask;
/* Function to call after setup and insertion */
void (*expectfn)(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
/* The conntrack of the master connection */
struct ip_conntrack *master;
/* Timer function; deletes the expectation. */
struct timer_list timeout;
#ifdef CONFIG_IP_NF_NAT_NEEDED
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
union ip_conntrack_manip_proto saved_proto;
/* Direction relative to the master connection. */
enum ip_conntrack_dir dir;
#endif
};
struct ip_conntrack_counter
{
u_int64_t packets;
......@@ -206,6 +179,33 @@ struct ip_conntrack
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
};
struct ip_conntrack_expect
{
/* Internal linked list (global expectation list) */
struct list_head list;
/* We expect this tuple, with the following mask */
struct ip_conntrack_tuple tuple, mask;
/* Function to call after setup and insertion */
void (*expectfn)(struct ip_conntrack *new,
struct ip_conntrack_expect *this);
/* The conntrack of the master connection */
struct ip_conntrack *master;
/* Timer function; deletes the expectation. */
struct timer_list timeout;
#ifdef CONFIG_IP_NF_NAT_NEEDED
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
union ip_conntrack_manip_proto saved_proto;
/* Direction relative to the master connection. */
enum ip_conntrack_dir dir;
#endif
};
static inline struct ip_conntrack *
tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
{
......@@ -301,6 +301,7 @@ struct ip_conntrack_stat
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
#ifdef CONFIG_IP_NF_NAT_NEEDED
static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
enum ip_nat_manip_type manip)
{
......@@ -308,5 +309,7 @@ static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
}
#endif /* CONFIG_IP_NF_NAT_NEEDED */
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_H */
......@@ -13,7 +13,7 @@ struct tftphdr {
#define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5
unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
extern unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack_expect *exp);
......
......@@ -22,11 +22,32 @@
#define IPT_CONNTRACK_STATUS 0x40
#define IPT_CONNTRACK_EXPIRES 0x80
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
{
struct {
__u32 ip;
union {
__u16 all;
} u;
} src;
struct {
__u32 ip;
union {
__u16 all;
} u;
/* The protocol. */
u16 protonum;
} dst;
};
struct ipt_conntrack_info
{
unsigned int statemask, statusmask;
struct ip_conntrack_tuple tuple[IP_CT_DIR_MAX];
struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
unsigned long expires_min, expires_max;
......
......@@ -25,5 +25,6 @@ struct ipt_multiport_v1
u_int8_t count; /* Number of ports */
u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
u_int8_t pflags[IPT_MULTI_PORTS]; /* Port flags */
u_int8_t invert; /* Invert flag */
};
#endif /*_IPT_MULTIPORT_H*/
......@@ -28,6 +28,7 @@
#define RFCOMM_CONN_TIMEOUT (HZ * 30)
#define RFCOMM_DISC_TIMEOUT (HZ * 20)
#define RFCOMM_AUTH_TIMEOUT (HZ * 25)
#define RFCOMM_DEFAULT_MTU 127
#define RFCOMM_DEFAULT_CREDITS 7
......@@ -198,14 +199,18 @@ struct rfcomm_dlc {
/* DLC and session flags */
#define RFCOMM_RX_THROTTLED 0
#define RFCOMM_TX_THROTTLED 1
#define RFCOMM_MSC_PENDING 2
#define RFCOMM_TIMED_OUT 3
#define RFCOMM_TIMED_OUT 2
#define RFCOMM_MSC_PENDING 3
#define RFCOMM_AUTH_PENDING 4
#define RFCOMM_AUTH_ACCEPT 5
#define RFCOMM_AUTH_REJECT 6
/* Scheduling flags and events */
#define RFCOMM_SCHED_STATE 0
#define RFCOMM_SCHED_RX 1
#define RFCOMM_SCHED_TX 2
#define RFCOMM_SCHED_TIMEO 3
#define RFCOMM_SCHED_AUTH 4
#define RFCOMM_SCHED_WAKEUP 31
/* MSC exchange flags */
......
......@@ -873,9 +873,9 @@ extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name);
extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name);
extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name);
extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
struct crypto_tfm;
typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);
......
......@@ -11,8 +11,8 @@ void vlan_proc_cleanup (void);
#define vlan_proc_init() (0)
#define vlan_proc_cleanup() do {} while(0)
#define vlan_proc_add_dev(dev) ((void)(dev), 0)
#define vlan_proc_rem_dev(dev) ((void)(dev), 0)
#define vlan_proc_add_dev(dev) ({(void)(dev), 0;})
#define vlan_proc_rem_dev(dev) ({(void)(dev), 0;})
#endif
......
......@@ -35,6 +35,7 @@
#include <linux/socket.h>
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/wait.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
......@@ -440,10 +441,8 @@ static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_
static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
DECLARE_WAITQUEUE(wait, current);
struct cmtp_session *session = ctrl->driverdata;
struct cmtp_application *application;
unsigned long timeo = CMTP_INTEROP_TIMEOUT;
BT_DBG("ctrl %p appl %d", ctrl, appl);
......@@ -458,20 +457,8 @@ static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
CAPI_FUNCTION_RELEASE, NULL, 0);
add_wait_queue(&session->wait, &wait);
while (timeo) {
set_current_state(TASK_INTERRUPTIBLE);
if (application->state == BT_CLOSED)
break;
if (signal_pending(current))
break;
timeo = schedule_timeout(timeo);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&session->wait, &wait);
wait_event_interruptible_timeout(session->wait,
(application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
cmtp_application_del(session, application);
}
......@@ -541,9 +528,8 @@ static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, in
int cmtp_attach_device(struct cmtp_session *session)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long timeo = CMTP_INTEROP_TIMEOUT;
unsigned char buf[4];
long ret;
BT_DBG("session %p", session);
......@@ -552,30 +538,17 @@ int cmtp_attach_device(struct cmtp_session *session)
cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
CAPI_FUNCTION_GET_PROFILE, buf, 4);
add_wait_queue(&session->wait, &wait);
while (timeo) {
set_current_state(TASK_INTERRUPTIBLE);
if (session->ncontroller)
break;
if (signal_pending(current))
break;
timeo = schedule_timeout(timeo);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&session->wait, &wait);
ret = wait_event_interruptible_timeout(session->wait,
session->ncontroller, CMTP_INTEROP_TIMEOUT);
BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
if (!timeo)
if (!ret)
return -ETIMEDOUT;
if (!session->ncontroller)
return -ENODEV;
if (session->ncontroller > 1)
BT_INFO("Setting up only CAPI controller 1");
......
......@@ -36,6 +36,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <net/sock.h>
#include <linux/input.h>
......@@ -74,6 +75,8 @@ static unsigned char hidp_keycode[256] = {
150,158,159,128,136,177,178,176,142,152,173,140
};
static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
{
struct hidp_session *session;
......@@ -175,6 +178,11 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
for (i = 0; i < 8; i++)
input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
/* If all the key codes have been set to 0x01, it means
* too many keys were pressed at the same time. */
if (!memcmp(udata + 2, hidp_mkeyspat, 6))
break;
for (i = 2; i < 8; i++) {
if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
if (hidp_keycode[keys[i]])
......@@ -459,7 +467,6 @@ static int hidp_session(void *arg)
struct sk_buff *skb;
int vendor = 0x0000, product = 0x0000;
wait_queue_t ctrl_wait, intr_wait;
unsigned long timeo = HZ;
BT_DBG("session %p", session);
......@@ -504,28 +511,12 @@ static int hidp_session(void *arg)
hidp_del_timer(session);
if (intr_sk->sk_state != BT_CONNECTED) {
init_waitqueue_entry(&ctrl_wait, current);
add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
while (timeo && ctrl_sk->sk_state != BT_CLOSED) {
set_current_state(TASK_INTERRUPTIBLE);
timeo = schedule_timeout(timeo);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
timeo = HZ;
}
if (intr_sk->sk_state != BT_CONNECTED)
wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
fput(session->ctrl_sock->file);
init_waitqueue_entry(&intr_wait, current);
add_wait_queue(intr_sk->sk_sleep, &intr_wait);
while (timeo && intr_sk->sk_state != BT_CLOSED) {
set_current_state(TASK_INTERRUPTIBLE);
timeo = schedule_timeout(timeo);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
fput(session->intr_sock->file);
......
......@@ -47,10 +47,11 @@
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#define VERSION "1.4"
#define VERSION "1.5"
#ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG
......@@ -1094,6 +1095,35 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
return 0;
}
static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) {
if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon))
return 1;
} else if (d->link_mode & RFCOMM_LM_AUTH) {
if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon))
return 1;
}
return 0;
}
static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
{
BT_DBG("dlc %p", d);
rfcomm_send_ua(d->session, d->dlci);
rfcomm_dlc_lock(d);
d->state = BT_CONNECTED;
d->state_change(d, 0);
rfcomm_dlc_unlock(d);
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
}
static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
{
struct rfcomm_dlc *d;
......@@ -1116,14 +1146,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
if (d) {
if (d->state == BT_OPEN) {
/* DLC was previously opened by PN request */
rfcomm_send_ua(s, dlci);
rfcomm_dlc_lock(d);
d->state = BT_CONNECTED;
d->state_change(d, 0);
rfcomm_dlc_unlock(d);
if (rfcomm_check_link_mode(d)) {
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
return 0;
}
rfcomm_send_msc(s, 1, dlci, d->v24_sig);
rfcomm_dlc_accept(d);
}
return 0;
}
......@@ -1135,14 +1164,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
d->addr = __addr(s->initiator, dlci);
rfcomm_dlc_link(s, d);
rfcomm_send_ua(s, dlci);
rfcomm_dlc_lock(d);
d->state = BT_CONNECTED;
d->state_change(d, 0);
rfcomm_dlc_unlock(d);
if (rfcomm_check_link_mode(d)) {
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
return 0;
}
rfcomm_send_msc(s, 1, dlci, d->v24_sig);
rfcomm_dlc_accept(d);
} else {
rfcomm_send_dm(s, dlci);
}
......@@ -1480,7 +1508,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
/* Trim FCS */
skb->len--; skb->tail--;
fcs = *(u8 *) skb->tail;
if (__check_fcs(skb->data, type, fcs)) {
BT_ERR("bad checksum in packet");
kfree_skb(skb);
......@@ -1491,7 +1519,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
skb_pull(skb, 3);
else
skb_pull(skb, 4);
switch (type) {
case RFCOMM_SABM:
if (__test_pf(hdr->ctrl))
......@@ -1559,7 +1587,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
/* Send pending MSC */
if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
if (d->cfc) {
/* CFC enabled.
* Give them some credits */
......@@ -1605,11 +1633,27 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list);
if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
__rfcomm_dlc_close(d, ETIMEDOUT);
continue;
}
if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
rfcomm_dlc_clear_timer(d);
rfcomm_dlc_accept(d);
if (d->link_mode & RFCOMM_LM_SECURE) {
struct sock *sk = s->sock->sk;
hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon);
}
continue;
} else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
rfcomm_dlc_clear_timer(d);
rfcomm_send_dm(s, d->dlci);
__rfcomm_dlc_close(d, ECONNREFUSED);
continue;
}
if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
continue;
......@@ -1733,7 +1777,7 @@ static inline void rfcomm_process_sessions(void)
rfcomm_session_put(s);
}
rfcomm_unlock();
}
......@@ -1842,6 +1886,77 @@ static int rfcomm_run(void *unused)
return 0;
}
static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status)
{
struct rfcomm_session *s;
struct rfcomm_dlc *d;
struct list_head *p, *n;
BT_DBG("conn %p status 0x%02x", conn, status);
s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
if (!s)
return;
rfcomm_session_hold(s);
list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list);
if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE))
continue;
if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
continue;
if (!status)
set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
else
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
}
rfcomm_session_put(s);
rfcomm_schedule(RFCOMM_SCHED_AUTH);
}
static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
{
struct rfcomm_session *s;
struct rfcomm_dlc *d;
struct list_head *p, *n;
BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
if (!s)
return;
rfcomm_session_hold(s);
list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list);
if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
continue;
if (!status && encrypt)
set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
else
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
}
rfcomm_session_put(s);
rfcomm_schedule(RFCOMM_SCHED_AUTH);
}
static struct hci_cb rfcomm_cb = {
.name = "RFCOMM",
.auth_cfm = rfcomm_auth_cfm,
.encrypt_cfm = rfcomm_encrypt_cfm
};
/* ---- Proc fs support ---- */
#ifdef CONFIG_PROC_FS
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
......@@ -1959,6 +2074,8 @@ static int __init rfcomm_init(void)
{
l2cap_load();
hci_register_cb(&rfcomm_cb);
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
BT_INFO("RFCOMM ver %s", VERSION);
......@@ -1976,6 +2093,8 @@ static int __init rfcomm_init(void)
static void __exit rfcomm_exit(void)
{
hci_unregister_cb(&rfcomm_cb);
/* Terminate working thread.
* ie. Set terminate flag and wake it up */
atomic_inc(&terminate);
......
......@@ -117,8 +117,13 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
bh_unlock_sock(sk);
if (parent && sk->sk_zapped)
if (parent && sk->sk_zapped) {
/* We have to drop DLC lock here, otherwise
* rfcomm_sock_destruct() will dead lock. */
rfcomm_dlc_unlock(d);
rfcomm_sock_kill(sk);
rfcomm_dlc_lock(d);
}
}
/* ---- Socket functions ---- */
......@@ -184,7 +189,7 @@ static void rfcomm_sock_destruct(struct sock *sk)
rfcomm_dlc_lock(d);
rfcomm_pi(sk)->dlc = NULL;
/* Detach DLC if it's owned by this socket */
if (d->owner == sk)
d->owner = NULL;
......
......@@ -1556,6 +1556,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
sizeof(struct ndmsg));
struct ndmsg *ndm = NLMSG_DATA(nlh);
nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0;
ndm->ndm_family = n->ops->family;
ndm->ndm_flags = n->flags;
ndm->ndm_type = n->type;
......
......@@ -65,27 +65,25 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
}
void netpoll_poll(struct netpoll *np)
/*
* Check whether delayed processing was scheduled for our current CPU,
* and then manually invoke NAPI polling to pump data off the card.
*
* In cases where there is bi-directional communications, reading only
* one message at a time can lead to packets being dropped by the
* network adapter, forcing superfluous retries and possibly timeouts.
* Thus, we set our budget to greater than 1.
*/
static void poll_napi(struct netpoll *np)
{
/*
* In cases where there is bi-directional communications, reading
* only one message at a time can lead to packets being dropped by
* the network adapter, forcing superfluous retries and possibly
* timeouts. Thus, we set our budget to a more reasonable value.
*/
int budget = 16;
unsigned long flags;
struct softnet_data *queue;
if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
return;
/* Process pending work on NIC */
np->dev->poll_controller(np->dev);
/* If scheduling is stopped, tickle NAPI bits */
spin_lock_irqsave(&netpoll_poll_lock, flags);
if (np->dev->poll &&
test_bit(__LINK_STATE_RX_SCHED, &np->dev->state)) {
queue = &__get_cpu_var(softnet_data);
if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
!list_empty(&queue->poll_list)) {
np->dev->netpoll_rx |= NETPOLL_RX_DROP;
atomic_inc(&trapped);
......@@ -95,6 +93,17 @@ void netpoll_poll(struct netpoll *np)
np->dev->netpoll_rx &= ~NETPOLL_RX_DROP;
}
spin_unlock_irqrestore(&netpoll_poll_lock, flags);
}
void netpoll_poll(struct netpoll *np)
{
if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
return;
/* Process pending work on NIC */
np->dev->poll_controller(np->dev);
if (np->dev->poll)
poll_napi(np);
zap_completion_queue();
}
......
......@@ -236,7 +236,7 @@ static int ah_init_state(struct xfrm_state *x, void *args)
* we need for AH processing. This lookup cannot fail here
* after a successful crypto_alloc_tfm().
*/
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
......@@ -392,7 +392,7 @@ static int esp_init_state(struct xfrm_state *x, void *args)
goto error;
esp->auth.icv = esp_hmac_digest;
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
......@@ -472,7 +472,7 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args)
goto error_tunnel;
}
calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0);
BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd;
......
......@@ -209,9 +209,14 @@ static int help(struct sk_buff **pskb,
DEBUGP("tcph->seq = %u\n", th->seq);
seq = ntohl(th->seq) + (addr_beg_p - ib_ptr);
/* We refer to the reverse direction ("!dir")
* tuples here, because we're expecting
* something in the other * direction.
* Doesn't matter unless NAT is happening. */
exp->tuple = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
{ ct->tuplehash[dir].tuple.src.ip, { .tcp = { htons(dcc_port) } },
{ ct->tuplehash[!dir].tuple.dst.ip,
{ .tcp = { htons(dcc_port) } },
IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
......
......@@ -83,7 +83,10 @@ static unsigned int help(struct sk_buff **pskb,
* 0x01, \n: terminators
*/
sprintf(buffer, "%u %u", ntohl(exp->tuple.src.ip), port);
/* AAA = "us", ie. where server normally talks to. */
sprintf(buffer, "%u %u",
ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
port);
DEBUGP("ip_nat_irc: Inserting '%s' == %u.%u.%u.%u, port %u\n",
buffer, NIPQUAD(exp->tuple.src.ip), port);
......
......@@ -181,7 +181,7 @@ static int ipt_snat_checkentry(const char *tablename,
return 0;
}
if (targinfosize != sizeof(struct ip_nat_multi_range_compat)) {
if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
DEBUGP("SNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
......@@ -214,7 +214,7 @@ static int ipt_dnat_checkentry(const char *tablename,
return 0;
}
if (targinfosize != sizeof(struct ip_nat_multi_range_compat)) {
if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
DEBUGP("DNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
......
......@@ -29,6 +29,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#define CLUSTERIP_VERSION "0.6"
......
......@@ -64,30 +64,31 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
if (minfo->flags == IPT_MULTIPORT_SOURCE
&& src >= s && src <= e)
return 1;
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION
&& dst >= s && dst <= e)
return 1;
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER
&& ((dst >= s && dst <= e)
|| (src >= s && src <= e)))
return 1;
return 1 ^ minfo->invert;
} else {
/* exact port matching */
duprintf("src or dst matches with %d?\n", s);
if (minfo->flags == IPT_MULTIPORT_SOURCE
&& src == s)
return 1;
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION
&& dst == s)
return 1;
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER
&& (src == s || dst == s))
return 1;
return 1 ^ minfo->invert;
}
}
return 0;
return minfo->invert;
}
static int
......
......@@ -375,7 +375,7 @@ static int ah6_init_state(struct xfrm_state *x, void *args)
* we need for AH processing. This lookup cannot fail here
* after a successful crypto_alloc_tfm().
*/
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
......@@ -329,7 +329,7 @@ static int esp6_init_state(struct xfrm_state *x, void *args)
goto error;
esp->auth.icv = esp_hmac_digest;
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
......@@ -468,7 +468,7 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args)
goto error_tunnel;
}
calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0);
BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd;
......
......@@ -665,18 +665,18 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
sa->sadb_sa_state = SADB_SASTATE_DEAD;
sa->sadb_sa_auth = 0;
if (x->aalg) {
struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name);
struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
sa->sadb_sa_auth = a ? a->desc.sadb_alg_id : 0;
}
sa->sadb_sa_encrypt = 0;
BUG_ON(x->ealg && x->calg);
if (x->ealg) {
struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name);
struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name, 0);
sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
}
/* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
if (x->calg) {
struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name);
struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name, 0);
sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
}
......
......@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
#include <linux/crypto.h>
#include <net/xfrm.h>
#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
#include <net/ah.h>
......@@ -346,58 +347,48 @@ struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
return NULL;
}
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name)
static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
int entries, char *name,
int probe)
{
int i;
int i, status;
if (!name)
return NULL;
for (i=0; i < aalg_entries(); i++) {
if (strcmp(name, aalg_list[i].name) == 0) {
if (aalg_list[i].available)
return &aalg_list[i];
else
break;
}
}
return NULL;
}
for (i = 0; i < entries; i++) {
if (!strcmp(name, list[i].name))
continue;
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name)
{
int i;
if (list[i].available)
return &list[i];
if (!name)
return NULL;
if (!probe)
break;
for (i=0; i < ealg_entries(); i++) {
if (strcmp(name, ealg_list[i].name) == 0) {
if (ealg_list[i].available)
return &ealg_list[i];
else
break;
}
status = crypto_alg_available(name, 0);
if (!status)
break;
list[i].available = status;
return &list[i];
}
return NULL;
}
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name)
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
{
int i;
return xfrm_get_byname(aalg_list, aalg_entries(), name, probe);
}
if (!name)
return NULL;
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
{
return xfrm_get_byname(ealg_list, ealg_entries(), name, probe);
}
for (i=0; i < calg_entries(); i++) {
if (strcmp(name, calg_list[i].name) == 0) {
if (calg_list[i].available)
return &calg_list[i];
else
break;
}
}
return NULL;
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
{
return xfrm_get_byname(calg_list, calg_entries(), name, probe);
}
struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
......
......@@ -156,7 +156,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
}
static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
struct xfrm_algo_desc *(*get_byname)(char *),
struct xfrm_algo_desc *(*get_byname)(char *, int),
struct rtattr *u_arg)
{
struct rtattr *rta = u_arg;
......@@ -168,7 +168,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
ualg = RTA_DATA(rta);
algo = get_byname(ualg->alg_name);
algo = get_byname(ualg->alg_name, 1);
if (!algo)
return -ENOSYS;
*props = algo->desc.sadb_alg_id;
......@@ -273,8 +273,6 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
if (err)
return err;
xfrm_probe_algs();
x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
if (!x)
return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment