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 ...@@ -1798,7 +1798,7 @@ S: Maintained
PPP OVER ETHERNET PPP OVER ETHERNET
P: Michal Ostrowski P: Michal Ostrowski
M: mostrows@styx.uwaterloo.ca M: mostrows@speakeasy.net
S: Maintained S: Maintained
PREEMPTIBLE KERNEL PREEMPTIBLE KERNEL
......
...@@ -113,6 +113,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -113,6 +113,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* Queue packet */ /* Queue packet */
skb_queue_tail(&tun->readq, skb); skb_queue_tail(&tun->readq, skb);
dev->trans_start = jiffies;
/* Notify and wake up reader process */ /* Notify and wake up reader process */
if (tun->flags & TUN_FASYNC) if (tun->flags & TUN_FASYNC)
...@@ -259,6 +260,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, ...@@ -259,6 +260,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx_ni(skb); netif_rx_ni(skb);
tun->dev->last_rx = jiffies;
tun->stats.rx_packets++; tun->stats.rx_packets++;
tun->stats.rx_bytes += len; tun->stats.rx_bytes += len;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef _LINUX_CRYPTO_H #ifndef _LINUX_CRYPTO_H
#define _LINUX_CRYPTO_H #define _LINUX_CRYPTO_H
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -121,7 +122,14 @@ int crypto_unregister_alg(struct crypto_alg *alg); ...@@ -121,7 +122,14 @@ int crypto_unregister_alg(struct crypto_alg *alg);
/* /*
* Algorithm query interface. * Algorithm query interface.
*/ */
#ifdef CONFIG_CRYPTO
int crypto_alg_available(const char *name, u32 flags); 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 * Transforms: user-instantiated objects which encapsulate algorithms
......
...@@ -122,33 +122,6 @@ do { \ ...@@ -122,33 +122,6 @@ do { \
#define IP_NF_ASSERT(x) #define IP_NF_ASSERT(x)
#endif #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 struct ip_conntrack_counter
{ {
u_int64_t packets; u_int64_t packets;
...@@ -206,6 +179,33 @@ struct ip_conntrack ...@@ -206,6 +179,33 @@ struct ip_conntrack
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; 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 * static inline struct ip_conntrack *
tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash) tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
{ {
...@@ -301,6 +301,7 @@ struct ip_conntrack_stat ...@@ -301,6 +301,7 @@ struct ip_conntrack_stat
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++) #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, static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
enum ip_nat_manip_type manip) enum ip_nat_manip_type manip)
{ {
...@@ -308,5 +309,7 @@ static inline int ip_nat_initialized(struct ip_conntrack *conntrack, ...@@ -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_SRC_NAT_DONE_BIT, &conntrack->status);
return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status); return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
} }
#endif /* CONFIG_IP_NF_NAT_NEEDED */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_H */ #endif /* _IP_CONNTRACK_H */
...@@ -13,7 +13,7 @@ struct tftphdr { ...@@ -13,7 +13,7 @@ struct tftphdr {
#define TFTP_OPCODE_ACK 4 #define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5 #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, enum ip_conntrack_info ctinfo,
struct ip_conntrack_expect *exp); struct ip_conntrack_expect *exp);
......
...@@ -22,11 +22,32 @@ ...@@ -22,11 +22,32 @@
#define IPT_CONNTRACK_STATUS 0x40 #define IPT_CONNTRACK_STATUS 0x40
#define IPT_CONNTRACK_EXPIRES 0x80 #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 struct ipt_conntrack_info
{ {
unsigned int statemask, statusmask; 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]; struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
unsigned long expires_min, expires_max; unsigned long expires_min, expires_max;
......
...@@ -25,5 +25,6 @@ struct ipt_multiport_v1 ...@@ -25,5 +25,6 @@ struct ipt_multiport_v1
u_int8_t count; /* Number of ports */ u_int8_t count; /* Number of ports */
u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */ u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
u_int8_t pflags[IPT_MULTI_PORTS]; /* Port flags */ u_int8_t pflags[IPT_MULTI_PORTS]; /* Port flags */
u_int8_t invert; /* Invert flag */
}; };
#endif /*_IPT_MULTIPORT_H*/ #endif /*_IPT_MULTIPORT_H*/
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define RFCOMM_CONN_TIMEOUT (HZ * 30) #define RFCOMM_CONN_TIMEOUT (HZ * 30)
#define RFCOMM_DISC_TIMEOUT (HZ * 20) #define RFCOMM_DISC_TIMEOUT (HZ * 20)
#define RFCOMM_AUTH_TIMEOUT (HZ * 25)
#define RFCOMM_DEFAULT_MTU 127 #define RFCOMM_DEFAULT_MTU 127
#define RFCOMM_DEFAULT_CREDITS 7 #define RFCOMM_DEFAULT_CREDITS 7
...@@ -198,14 +199,18 @@ struct rfcomm_dlc { ...@@ -198,14 +199,18 @@ struct rfcomm_dlc {
/* DLC and session flags */ /* DLC and session flags */
#define RFCOMM_RX_THROTTLED 0 #define RFCOMM_RX_THROTTLED 0
#define RFCOMM_TX_THROTTLED 1 #define RFCOMM_TX_THROTTLED 1
#define RFCOMM_MSC_PENDING 2 #define RFCOMM_TIMED_OUT 2
#define RFCOMM_TIMED_OUT 3 #define RFCOMM_MSC_PENDING 3
#define RFCOMM_AUTH_PENDING 4
#define RFCOMM_AUTH_ACCEPT 5
#define RFCOMM_AUTH_REJECT 6
/* Scheduling flags and events */ /* Scheduling flags and events */
#define RFCOMM_SCHED_STATE 0 #define RFCOMM_SCHED_STATE 0
#define RFCOMM_SCHED_RX 1 #define RFCOMM_SCHED_RX 1
#define RFCOMM_SCHED_TX 2 #define RFCOMM_SCHED_TX 2
#define RFCOMM_SCHED_TIMEO 3 #define RFCOMM_SCHED_TIMEO 3
#define RFCOMM_SCHED_AUTH 4
#define RFCOMM_SCHED_WAKEUP 31 #define RFCOMM_SCHED_WAKEUP 31
/* MSC exchange flags */ /* MSC exchange flags */
......
...@@ -873,9 +873,9 @@ extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); ...@@ -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_aalg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_ealg_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_calg_get_byid(int alg_id);
extern struct xfrm_algo_desc *xfrm_aalg_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); extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name); extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
struct crypto_tfm; struct crypto_tfm;
typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int); typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);
......
...@@ -11,8 +11,8 @@ void vlan_proc_cleanup (void); ...@@ -11,8 +11,8 @@ void vlan_proc_cleanup (void);
#define vlan_proc_init() (0) #define vlan_proc_init() (0)
#define vlan_proc_cleanup() do {} while(0) #define vlan_proc_cleanup() do {} while(0)
#define vlan_proc_add_dev(dev) ((void)(dev), 0) #define vlan_proc_add_dev(dev) ({(void)(dev), 0;})
#define vlan_proc_rem_dev(dev) ((void)(dev), 0) #define vlan_proc_rem_dev(dev) ({(void)(dev), 0;})
#endif #endif
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/wait.h>
#include <net/sock.h> #include <net/sock.h>
#include <linux/isdn/capilli.h> #include <linux/isdn/capilli.h>
...@@ -440,10 +441,8 @@ static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_ ...@@ -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) static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
{ {
DECLARE_WAITQUEUE(wait, current);
struct cmtp_session *session = ctrl->driverdata; struct cmtp_session *session = ctrl->driverdata;
struct cmtp_application *application; struct cmtp_application *application;
unsigned long timeo = CMTP_INTEROP_TIMEOUT;
BT_DBG("ctrl %p appl %d", ctrl, appl); BT_DBG("ctrl %p appl %d", ctrl, appl);
...@@ -458,20 +457,8 @@ static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 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, cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
CAPI_FUNCTION_RELEASE, NULL, 0); CAPI_FUNCTION_RELEASE, NULL, 0);
add_wait_queue(&session->wait, &wait); wait_event_interruptible_timeout(session->wait,
while (timeo) { (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
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);
cmtp_application_del(session, application); 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 ...@@ -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) int cmtp_attach_device(struct cmtp_session *session)
{ {
DECLARE_WAITQUEUE(wait, current);
unsigned long timeo = CMTP_INTEROP_TIMEOUT;
unsigned char buf[4]; unsigned char buf[4];
long ret;
BT_DBG("session %p", session); BT_DBG("session %p", session);
...@@ -552,30 +538,17 @@ int cmtp_attach_device(struct cmtp_session *session) ...@@ -552,30 +538,17 @@ int cmtp_attach_device(struct cmtp_session *session)
cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM, cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
CAPI_FUNCTION_GET_PROFILE, buf, 4); CAPI_FUNCTION_GET_PROFILE, buf, 4);
add_wait_queue(&session->wait, &wait); ret = wait_event_interruptible_timeout(session->wait,
while (timeo) { session->ncontroller, CMTP_INTEROP_TIMEOUT);
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);
BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name); BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
if (!timeo) if (!ret)
return -ETIMEDOUT; return -ETIMEDOUT;
if (!session->ncontroller) if (!session->ncontroller)
return -ENODEV; return -ENODEV;
if (session->ncontroller > 1) if (session->ncontroller > 1)
BT_INFO("Setting up only CAPI controller 1"); BT_INFO("Setting up only CAPI controller 1");
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/wait.h>
#include <net/sock.h> #include <net/sock.h>
#include <linux/input.h> #include <linux/input.h>
...@@ -74,6 +75,8 @@ static unsigned char hidp_keycode[256] = { ...@@ -74,6 +75,8 @@ static unsigned char hidp_keycode[256] = {
150,158,159,128,136,177,178,176,142,152,173,140 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) static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
{ {
struct hidp_session *session; struct hidp_session *session;
...@@ -175,6 +178,11 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) ...@@ -175,6 +178,11 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1); 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++) { for (i = 2; i < 8; i++) {
if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) { if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
if (hidp_keycode[keys[i]]) if (hidp_keycode[keys[i]])
...@@ -459,7 +467,6 @@ static int hidp_session(void *arg) ...@@ -459,7 +467,6 @@ static int hidp_session(void *arg)
struct sk_buff *skb; struct sk_buff *skb;
int vendor = 0x0000, product = 0x0000; int vendor = 0x0000, product = 0x0000;
wait_queue_t ctrl_wait, intr_wait; wait_queue_t ctrl_wait, intr_wait;
unsigned long timeo = HZ;
BT_DBG("session %p", session); BT_DBG("session %p", session);
...@@ -504,28 +511,12 @@ static int hidp_session(void *arg) ...@@ -504,28 +511,12 @@ static int hidp_session(void *arg)
hidp_del_timer(session); hidp_del_timer(session);
if (intr_sk->sk_state != BT_CONNECTED) { if (intr_sk->sk_state != BT_CONNECTED)
init_waitqueue_entry(&ctrl_wait, current); wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
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;
}
fput(session->ctrl_sock->file); fput(session->ctrl_sock->file);
init_waitqueue_entry(&intr_wait, current); wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
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);
fput(session->intr_sock->file); fput(session->intr_sock->file);
......
...@@ -47,10 +47,11 @@ ...@@ -47,10 +47,11 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h> #include <net/bluetooth/rfcomm.h>
#define VERSION "1.4" #define VERSION "1.5"
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG #undef BT_DBG
...@@ -1094,6 +1095,35 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) ...@@ -1094,6 +1095,35 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
return 0; 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) static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
{ {
struct rfcomm_dlc *d; struct rfcomm_dlc *d;
...@@ -1116,14 +1146,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) ...@@ -1116,14 +1146,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
if (d) { if (d) {
if (d->state == BT_OPEN) { if (d->state == BT_OPEN) {
/* DLC was previously opened by PN request */ /* DLC was previously opened by PN request */
rfcomm_send_ua(s, dlci); if (rfcomm_check_link_mode(d)) {
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
rfcomm_dlc_lock(d); rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
d->state = BT_CONNECTED; return 0;
d->state_change(d, 0); }
rfcomm_dlc_unlock(d);
rfcomm_send_msc(s, 1, dlci, d->v24_sig); rfcomm_dlc_accept(d);
} }
return 0; return 0;
} }
...@@ -1135,14 +1164,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) ...@@ -1135,14 +1164,13 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
d->addr = __addr(s->initiator, dlci); d->addr = __addr(s->initiator, dlci);
rfcomm_dlc_link(s, d); rfcomm_dlc_link(s, d);
rfcomm_send_ua(s, dlci); if (rfcomm_check_link_mode(d)) {
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
rfcomm_dlc_lock(d); rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
d->state = BT_CONNECTED; return 0;
d->state_change(d, 0); }
rfcomm_dlc_unlock(d);
rfcomm_send_msc(s, 1, dlci, d->v24_sig); rfcomm_dlc_accept(d);
} else { } else {
rfcomm_send_dm(s, dlci); rfcomm_send_dm(s, dlci);
} }
...@@ -1480,7 +1508,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) ...@@ -1480,7 +1508,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
/* Trim FCS */ /* Trim FCS */
skb->len--; skb->tail--; skb->len--; skb->tail--;
fcs = *(u8 *) skb->tail; fcs = *(u8 *) skb->tail;
if (__check_fcs(skb->data, type, fcs)) { if (__check_fcs(skb->data, type, fcs)) {
BT_ERR("bad checksum in packet"); BT_ERR("bad checksum in packet");
kfree_skb(skb); kfree_skb(skb);
...@@ -1491,7 +1519,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) ...@@ -1491,7 +1519,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
skb_pull(skb, 3); skb_pull(skb, 3);
else else
skb_pull(skb, 4); skb_pull(skb, 4);
switch (type) { switch (type) {
case RFCOMM_SABM: case RFCOMM_SABM:
if (__test_pf(hdr->ctrl)) if (__test_pf(hdr->ctrl))
...@@ -1559,7 +1587,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d) ...@@ -1559,7 +1587,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
/* Send pending MSC */ /* Send pending MSC */
if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags)) if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
if (d->cfc) { if (d->cfc) {
/* CFC enabled. /* CFC enabled.
* Give them some credits */ * Give them some credits */
...@@ -1605,11 +1633,27 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) ...@@ -1605,11 +1633,27 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
list_for_each_safe(p, n, &s->dlcs) { list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list); d = list_entry(p, struct rfcomm_dlc, list);
if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) { if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
__rfcomm_dlc_close(d, ETIMEDOUT); __rfcomm_dlc_close(d, ETIMEDOUT);
continue; 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)) if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
continue; continue;
...@@ -1733,7 +1777,7 @@ static inline void rfcomm_process_sessions(void) ...@@ -1733,7 +1777,7 @@ static inline void rfcomm_process_sessions(void)
rfcomm_session_put(s); rfcomm_session_put(s);
} }
rfcomm_unlock(); rfcomm_unlock();
} }
...@@ -1842,6 +1886,77 @@ static int rfcomm_run(void *unused) ...@@ -1842,6 +1886,77 @@ static int rfcomm_run(void *unused)
return 0; 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 ---- */ /* ---- Proc fs support ---- */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos) static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
...@@ -1959,6 +2074,8 @@ static int __init rfcomm_init(void) ...@@ -1959,6 +2074,8 @@ static int __init rfcomm_init(void)
{ {
l2cap_load(); l2cap_load();
hci_register_cb(&rfcomm_cb);
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
BT_INFO("RFCOMM ver %s", VERSION); BT_INFO("RFCOMM ver %s", VERSION);
...@@ -1976,6 +2093,8 @@ static int __init rfcomm_init(void) ...@@ -1976,6 +2093,8 @@ static int __init rfcomm_init(void)
static void __exit rfcomm_exit(void) static void __exit rfcomm_exit(void)
{ {
hci_unregister_cb(&rfcomm_cb);
/* Terminate working thread. /* Terminate working thread.
* ie. Set terminate flag and wake it up */ * ie. Set terminate flag and wake it up */
atomic_inc(&terminate); atomic_inc(&terminate);
......
...@@ -117,8 +117,13 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) ...@@ -117,8 +117,13 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
bh_unlock_sock(sk); 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_sock_kill(sk);
rfcomm_dlc_lock(d);
}
} }
/* ---- Socket functions ---- */ /* ---- Socket functions ---- */
...@@ -184,7 +189,7 @@ static void rfcomm_sock_destruct(struct sock *sk) ...@@ -184,7 +189,7 @@ static void rfcomm_sock_destruct(struct sock *sk)
rfcomm_dlc_lock(d); rfcomm_dlc_lock(d);
rfcomm_pi(sk)->dlc = NULL; rfcomm_pi(sk)->dlc = NULL;
/* Detach DLC if it's owned by this socket */ /* Detach DLC if it's owned by this socket */
if (d->owner == sk) if (d->owner == sk)
d->owner = NULL; d->owner = NULL;
......
...@@ -1556,6 +1556,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, ...@@ -1556,6 +1556,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
sizeof(struct ndmsg)); sizeof(struct ndmsg));
struct ndmsg *ndm = NLMSG_DATA(nlh); struct ndmsg *ndm = NLMSG_DATA(nlh);
nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0;
ndm->ndm_family = n->ops->family; ndm->ndm_family = n->ops->family;
ndm->ndm_flags = n->flags; ndm->ndm_flags = n->flags;
ndm->ndm_type = n->type; ndm->ndm_type = n->type;
......
...@@ -65,27 +65,25 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, ...@@ -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)); 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; int budget = 16;
unsigned long flags; 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); spin_lock_irqsave(&netpoll_poll_lock, flags);
if (np->dev->poll && queue = &__get_cpu_var(softnet_data);
test_bit(__LINK_STATE_RX_SCHED, &np->dev->state)) { if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
!list_empty(&queue->poll_list)) {
np->dev->netpoll_rx |= NETPOLL_RX_DROP; np->dev->netpoll_rx |= NETPOLL_RX_DROP;
atomic_inc(&trapped); atomic_inc(&trapped);
...@@ -95,6 +93,17 @@ void netpoll_poll(struct netpoll *np) ...@@ -95,6 +93,17 @@ void netpoll_poll(struct netpoll *np)
np->dev->netpoll_rx &= ~NETPOLL_RX_DROP; np->dev->netpoll_rx &= ~NETPOLL_RX_DROP;
} }
spin_unlock_irqrestore(&netpoll_poll_lock, flags); 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(); zap_completion_queue();
} }
......
...@@ -236,7 +236,7 @@ static int ah_init_state(struct xfrm_state *x, void *args) ...@@ -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 * we need for AH processing. This lookup cannot fail here
* after a successful crypto_alloc_tfm(). * 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); BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 != if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
...@@ -392,7 +392,7 @@ static int esp_init_state(struct xfrm_state *x, void *args) ...@@ -392,7 +392,7 @@ static int esp_init_state(struct xfrm_state *x, void *args)
goto error; goto error;
esp->auth.icv = esp_hmac_digest; 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); BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 != if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
...@@ -472,7 +472,7 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args) ...@@ -472,7 +472,7 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args)
goto error_tunnel; 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); BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold; ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd; x->data = ipcd;
......
...@@ -209,9 +209,14 @@ static int help(struct sk_buff **pskb, ...@@ -209,9 +209,14 @@ static int help(struct sk_buff **pskb,
DEBUGP("tcph->seq = %u\n", th->seq); DEBUGP("tcph->seq = %u\n", th->seq);
seq = ntohl(th->seq) + (addr_beg_p - ib_ptr); 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) exp->tuple = ((struct ip_conntrack_tuple)
{ { 0, { 0 } }, { { 0, { 0 } },
{ ct->tuplehash[dir].tuple.src.ip, { .tcp = { htons(dcc_port) } }, { ct->tuplehash[!dir].tuple.dst.ip,
{ .tcp = { htons(dcc_port) } },
IPPROTO_TCP }}); IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple) exp->mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } }, { { 0, { 0 } },
......
...@@ -83,7 +83,10 @@ static unsigned int help(struct sk_buff **pskb, ...@@ -83,7 +83,10 @@ static unsigned int help(struct sk_buff **pskb,
* 0x01, \n: terminators * 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", DEBUGP("ip_nat_irc: Inserting '%s' == %u.%u.%u.%u, port %u\n",
buffer, NIPQUAD(exp->tuple.src.ip), port); buffer, NIPQUAD(exp->tuple.src.ip), port);
......
...@@ -181,7 +181,7 @@ static int ipt_snat_checkentry(const char *tablename, ...@@ -181,7 +181,7 @@ static int ipt_snat_checkentry(const char *tablename,
return 0; 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", DEBUGP("SNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize); targinfosize, mr->rangesize);
return 0; return 0;
...@@ -214,7 +214,7 @@ static int ipt_dnat_checkentry(const char *tablename, ...@@ -214,7 +214,7 @@ static int ipt_dnat_checkentry(const char *tablename,
return 0; 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", DEBUGP("DNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize); targinfosize, mr->rangesize);
return 0; return 0;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
#include <linux/netfilter_ipv4/ip_conntrack.h> #include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#define CLUSTERIP_VERSION "0.6" #define CLUSTERIP_VERSION "0.6"
......
...@@ -64,30 +64,31 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo, ...@@ -64,30 +64,31 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
if (minfo->flags == IPT_MULTIPORT_SOURCE if (minfo->flags == IPT_MULTIPORT_SOURCE
&& src >= s && src <= e) && src >= s && src <= e)
return 1; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION if (minfo->flags == IPT_MULTIPORT_DESTINATION
&& dst >= s && dst <= e) && dst >= s && dst <= e)
return 1; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER if (minfo->flags == IPT_MULTIPORT_EITHER
&& ((dst >= s && dst <= e) && ((dst >= s && dst <= e)
|| (src >= s && src <= e))) || (src >= s && src <= e)))
return 1; return 1 ^ minfo->invert;
} else { } else {
/* exact port matching */ /* exact port matching */
duprintf("src or dst matches with %d?\n", s); duprintf("src or dst matches with %d?\n", s);
if (minfo->flags == IPT_MULTIPORT_SOURCE if (minfo->flags == IPT_MULTIPORT_SOURCE
&& src == s) && src == s)
return 1; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION if (minfo->flags == IPT_MULTIPORT_DESTINATION
&& dst == s) && dst == s)
return 1; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER if (minfo->flags == IPT_MULTIPORT_EITHER
&& (src == s || dst == s)) && (src == s || dst == s))
return 1; return 1 ^ minfo->invert;
} }
} }
return 0; return minfo->invert;
} }
static int static int
......
...@@ -375,7 +375,7 @@ static int ah6_init_state(struct xfrm_state *x, void *args) ...@@ -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 * we need for AH processing. This lookup cannot fail here
* after a successful crypto_alloc_tfm(). * 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); BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 != if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
...@@ -329,7 +329,7 @@ static int esp6_init_state(struct xfrm_state *x, void *args) ...@@ -329,7 +329,7 @@ static int esp6_init_state(struct xfrm_state *x, void *args)
goto error; goto error;
esp->auth.icv = esp_hmac_digest; 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); BUG_ON(!aalg_desc);
if (aalg_desc->uinfo.auth.icv_fullbits/8 != if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
......
...@@ -468,7 +468,7 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args) ...@@ -468,7 +468,7 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args)
goto error_tunnel; 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); BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold; ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd; x->data = ipcd;
......
...@@ -665,18 +665,18 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, ...@@ -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_state = SADB_SASTATE_DEAD;
sa->sadb_sa_auth = 0; sa->sadb_sa_auth = 0;
if (x->aalg) { 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_auth = a ? a->desc.sadb_alg_id : 0;
} }
sa->sadb_sa_encrypt = 0; sa->sadb_sa_encrypt = 0;
BUG_ON(x->ealg && x->calg); BUG_ON(x->ealg && x->calg);
if (x->ealg) { 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; sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
} }
/* KAME compatible: sadb_sa_encrypt is overloaded with calg id */ /* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
if (x->calg) { 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; sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pfkeyv2.h> #include <linux/pfkeyv2.h>
#include <linux/crypto.h>
#include <net/xfrm.h> #include <net/xfrm.h>
#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
#include <net/ah.h> #include <net/ah.h>
...@@ -346,58 +347,48 @@ struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) ...@@ -346,58 +347,48 @@ struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
return NULL; 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) if (!name)
return NULL; return NULL;
for (i=0; i < aalg_entries(); i++) { for (i = 0; i < entries; i++) {
if (strcmp(name, aalg_list[i].name) == 0) { if (!strcmp(name, list[i].name))
if (aalg_list[i].available) continue;
return &aalg_list[i];
else
break;
}
}
return NULL;
}
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name) if (list[i].available)
{ return &list[i];
int i;
if (!name) if (!probe)
return NULL; break;
for (i=0; i < ealg_entries(); i++) { status = crypto_alg_available(name, 0);
if (strcmp(name, ealg_list[i].name) == 0) { if (!status)
if (ealg_list[i].available) break;
return &ealg_list[i];
else list[i].available = status;
break; return &list[i];
}
} }
return NULL; 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) struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
return NULL; {
return xfrm_get_byname(ealg_list, ealg_entries(), name, probe);
}
for (i=0; i < calg_entries(); i++) { struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
if (strcmp(name, calg_list[i].name) == 0) { {
if (calg_list[i].available) return xfrm_get_byname(calg_list, calg_entries(), name, probe);
return &calg_list[i];
else
break;
}
}
return NULL;
} }
struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) 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, ...@@ -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, 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 *u_arg)
{ {
struct rtattr *rta = u_arg; struct rtattr *rta = u_arg;
...@@ -168,7 +168,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, ...@@ -168,7 +168,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
ualg = RTA_DATA(rta); ualg = RTA_DATA(rta);
algo = get_byname(ualg->alg_name); algo = get_byname(ualg->alg_name, 1);
if (!algo) if (!algo)
return -ENOSYS; return -ENOSYS;
*props = algo->desc.sadb_alg_id; *props = algo->desc.sadb_alg_id;
...@@ -273,8 +273,6 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) ...@@ -273,8 +273,6 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
if (err) if (err)
return err; return err;
xfrm_probe_algs();
x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err); x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
if (!x) if (!x)
return err; 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