Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (25 commits)
  [Bluetooth] Use work queue to trigger URB submission
  [Bluetooth] Add locking for bt_proto array manipulation
  [Bluetooth] Check if DLC is still attached to the TTY
  [Bluetooth] Fix reference count when connection lookup fails
  [Bluetooth] Disconnect HID interrupt channel first
  [Bluetooth] Support concurrent connect requests
  [Bluetooth] Make use of virtual devices tree
  [Bluetooth] Handle return values from driver core functions
  [Bluetooth] Fix compat ioctl for BNEP, CMTP and HIDP
  [IPV6] sit: Add missing MODULE_LICENSE
  [IPV6]: Remove bogus WARN_ON in Proxy-NA handling.
  [IPv6] rules: Use RT6_LOOKUP_F_HAS_SADDR and fix source based selectors
  [XFRM]: Fix xfrm_state_num going negative.
  [NET]: reduce sizeof(struct inet_peer), cleanup, change in peer_check_expire()
  NetLabel: the CIPSOv4 passthrough mapping does not pass categories correctly
  NetLabel: better error handling involving mls_export_cat()
  NetLabel: only deref the CIPSOv4 standard map fields when using standard mapping
  [BRIDGE]: flush forwarding table when device carrier off
  [NETFILTER]: ctnetlink: Remove debugging messages
  [NETFILTER]: Update MAINTAINERS entry
  ...
This commit is contained in:
Linus Torvalds 2006-10-16 08:33:06 -07:00
commit 5206a79d7b
42 changed files with 407 additions and 284 deletions

View File

@ -2049,11 +2049,13 @@ P: Marc Boucher
P: James Morris P: James Morris
P: Harald Welte P: Harald Welte
P: Jozsef Kadlecsik P: Jozsef Kadlecsik
M: coreteam@netfilter.org P: Patrick McHardy
M: kaber@trash.net
L: netfilter-devel@lists.netfilter.org
L: netfilter@lists.netfilter.org
L: coreteam@netfilter.org
W: http://www.netfilter.org/ W: http://www.netfilter.org/
W: http://www.iptables.org/ W: http://www.iptables.org/
L: netfilter@lists.netfilter.org
L: netfilter-devel@lists.netfilter.org
S: Supported S: Supported
NETLABEL NETLABEL

View File

@ -29,7 +29,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/timer.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/firmware.h> #include <linux/firmware.h>
@ -43,7 +42,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "1.0" #define VERSION "1.1"
static int ignore = 0; static int ignore = 0;
@ -72,7 +71,7 @@ struct bcm203x_data {
unsigned long state; unsigned long state;
struct timer_list timer; struct work_struct work;
struct urb *urb; struct urb *urb;
unsigned char *buffer; unsigned char *buffer;
@ -105,7 +104,7 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY; data->state = BCM203X_SELECT_MEMORY;
mod_timer(&data->timer, jiffies + (HZ / 10)); schedule_work(&data->work);
break; break;
case BCM203X_SELECT_MEMORY: case BCM203X_SELECT_MEMORY:
@ -158,9 +157,9 @@ static void bcm203x_complete(struct urb *urb)
} }
} }
static void bcm203x_timer(unsigned long user_data) static void bcm203x_work(void *user_data)
{ {
struct bcm203x_data *data = (struct bcm203x_data *) user_data; struct bcm203x_data *data = user_data;
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
BT_ERR("Can't submit URB"); BT_ERR("Can't submit URB");
@ -247,13 +246,11 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
release_firmware(firmware); release_firmware(firmware);
init_timer(&data->timer); INIT_WORK(&data->work, bcm203x_work, (void *) data);
data->timer.function = bcm203x_timer;
data->timer.data = (unsigned long) data;
usb_set_intfdata(intf, data); usb_set_intfdata(intf, data);
mod_timer(&data->timer, jiffies + HZ); schedule_work(&data->work);
return 0; return 0;
} }

View File

@ -153,6 +153,7 @@ struct hci_conn {
__u8 mode; __u8 mode;
__u8 type; __u8 type;
__u8 out; __u8 out;
__u8 attempt;
__u8 dev_class[3]; __u8 dev_class[3];
__u8 features[8]; __u8 features[8];
__u16 interval; __u16 interval;
@ -289,6 +290,22 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
return NULL; return NULL;
} }
static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
__u8 type, __u16 state)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct hci_conn *c;
list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->type == type && c->state == state)
return c;
}
return NULL;
}
void hci_acl_connect(struct hci_conn *conn);
void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
void hci_add_sco(struct hci_conn *conn, __u16 handle); void hci_add_sco(struct hci_conn *conn, __u16 handle);

View File

@ -19,7 +19,7 @@ struct inet_peer
{ {
struct inet_peer *avl_left, *avl_right; struct inet_peer *avl_left, *avl_right;
struct inet_peer *unused_next, **unused_prevp; struct inet_peer *unused_next, **unused_prevp;
unsigned long dtime; /* the time of last use of not __u32 dtime; /* the time of last use of not
* referenced entries */ * referenced entries */
atomic_t refcnt; atomic_t refcnt;
__be32 v4daddr; /* peer's address */ __be32 v4daddr; /* peer's address */
@ -35,21 +35,8 @@ void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */ /* can be called with or without local BH being disabled */
struct inet_peer *inet_getpeer(__be32 daddr, int create); struct inet_peer *inet_getpeer(__be32 daddr, int create);
extern spinlock_t inet_peer_unused_lock;
extern struct inet_peer **inet_peer_unused_tailp;
/* can be called from BH context or outside */ /* can be called from BH context or outside */
static inline void inet_putpeer(struct inet_peer *p) extern void inet_putpeer(struct inet_peer *p);
{
spin_lock_bh(&inet_peer_unused_lock);
if (atomic_dec_and_test(&p->refcnt)) {
p->unused_prevp = inet_peer_unused_tailp;
p->unused_next = NULL;
*inet_peer_unused_tailp = p;
inet_peer_unused_tailp = &p->unused_next;
p->dtime = jiffies;
}
spin_unlock_bh(&inet_peer_unused_lock);
}
extern spinlock_t inet_peer_idlock; extern spinlock_t inet_peer_idlock;
/* can be called with or without local BH being disabled */ /* can be called with or without local BH being disabled */

View File

@ -48,41 +48,56 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.10" #define VERSION "2.11"
/* Bluetooth sockets */ /* Bluetooth sockets */
#define BT_MAX_PROTO 8 #define BT_MAX_PROTO 8
static struct net_proto_family *bt_proto[BT_MAX_PROTO]; static struct net_proto_family *bt_proto[BT_MAX_PROTO];
static DEFINE_RWLOCK(bt_proto_lock);
int bt_sock_register(int proto, struct net_proto_family *ops) int bt_sock_register(int proto, struct net_proto_family *ops)
{ {
int err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO) if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL; return -EINVAL;
if (bt_proto[proto]) write_lock(&bt_proto_lock);
return -EEXIST;
bt_proto[proto] = ops; if (bt_proto[proto])
return 0; err = -EEXIST;
else
bt_proto[proto] = ops;
write_unlock(&bt_proto_lock);
return err;
} }
EXPORT_SYMBOL(bt_sock_register); EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto) int bt_sock_unregister(int proto)
{ {
int err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO) if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL; return -EINVAL;
if (!bt_proto[proto]) write_lock(&bt_proto_lock);
return -ENOENT;
bt_proto[proto] = NULL; if (!bt_proto[proto])
return 0; err = -ENOENT;
else
bt_proto[proto] = NULL;
write_unlock(&bt_proto_lock);
return err;
} }
EXPORT_SYMBOL(bt_sock_unregister); EXPORT_SYMBOL(bt_sock_unregister);
static int bt_sock_create(struct socket *sock, int proto) static int bt_sock_create(struct socket *sock, int proto)
{ {
int err = 0; int err;
if (proto < 0 || proto >= BT_MAX_PROTO) if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL; return -EINVAL;
@ -92,11 +107,18 @@ static int bt_sock_create(struct socket *sock, int proto)
request_module("bt-proto-%d", proto); request_module("bt-proto-%d", proto);
} }
#endif #endif
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
read_lock(&bt_proto_lock);
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(sock, proto); err = bt_proto[proto]->create(sock, proto);
module_put(bt_proto[proto]->owner); module_put(bt_proto[proto]->owner);
} }
read_unlock(&bt_proto_lock);
return err; return err;
} }

View File

@ -528,12 +528,10 @@ static struct device *bnep_get_device(struct bnep_session *session)
return NULL; return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
hci_dev_put(hdev); hci_dev_put(hdev);
return &conn->dev; return conn ? &conn->dev : NULL;
} }
int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)

View File

@ -43,6 +43,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/compat.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/system.h> #include <asm/system.h>
@ -146,24 +147,56 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return 0; return 0;
} }
#ifdef CONFIG_COMPAT
static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
if (cmd == BNEPGETCONNLIST) {
struct bnep_connlist_req cl;
uint32_t uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
cl.ci = compat_ptr(uci);
if (cl.cnum <= 0)
return -EINVAL;
err = bnep_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
err = -EFAULT;
return err;
}
return bnep_sock_ioctl(sock, cmd, arg);
}
#endif
static const struct proto_ops bnep_sock_ops = { static const struct proto_ops bnep_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = bnep_sock_release, .release = bnep_sock_release,
.ioctl = bnep_sock_ioctl, .ioctl = bnep_sock_ioctl,
.bind = sock_no_bind, #ifdef CONFIG_COMPAT
.getname = sock_no_getname, .compat_ioctl = bnep_sock_compat_ioctl,
.sendmsg = sock_no_sendmsg, #endif
.recvmsg = sock_no_recvmsg, .bind = sock_no_bind,
.poll = sock_no_poll, .getname = sock_no_getname,
.listen = sock_no_listen, .sendmsg = sock_no_sendmsg,
.shutdown = sock_no_shutdown, .recvmsg = sock_no_recvmsg,
.setsockopt = sock_no_setsockopt, .poll = sock_no_poll,
.getsockopt = sock_no_getsockopt, .listen = sock_no_listen,
.connect = sock_no_connect, .shutdown = sock_no_shutdown,
.socketpair = sock_no_socketpair, .setsockopt = sock_no_setsockopt,
.accept = sock_no_accept, .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap .connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
}; };
static struct proto bnep_proto = { static struct proto bnep_proto = {
@ -181,7 +214,7 @@ static int bnep_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW) if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT; return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1); sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;

View File

@ -34,6 +34,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/compat.h>
#include <net/sock.h> #include <net/sock.h>
#include <linux/isdn/capilli.h> #include <linux/isdn/capilli.h>
@ -137,11 +138,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return -EINVAL; return -EINVAL;
} }
#ifdef CONFIG_COMPAT
static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
if (cmd == CMTPGETCONNLIST) {
struct cmtp_connlist_req cl;
uint32_t uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
cl.ci = compat_ptr(uci);
if (cl.cnum <= 0)
return -EINVAL;
err = cmtp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
err = -EFAULT;
return err;
}
return cmtp_sock_ioctl(sock, cmd, arg);
}
#endif
static const struct proto_ops cmtp_sock_ops = { static const struct proto_ops cmtp_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = cmtp_sock_release, .release = cmtp_sock_release,
.ioctl = cmtp_sock_ioctl, .ioctl = cmtp_sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = cmtp_sock_compat_ioctl,
#endif
.bind = sock_no_bind, .bind = sock_no_bind,
.getname = sock_no_getname, .getname = sock_no_getname,
.sendmsg = sock_no_sendmsg, .sendmsg = sock_no_sendmsg,
@ -172,7 +205,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW) if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT; return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1); sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;

View File

@ -51,7 +51,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
static void hci_acl_connect(struct hci_conn *conn) void hci_acl_connect(struct hci_conn *conn)
{ {
struct hci_dev *hdev = conn->hdev; struct hci_dev *hdev = conn->hdev;
struct inquiry_entry *ie; struct inquiry_entry *ie;
@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn)
conn->out = 1; conn->out = 1;
conn->link_mode = HCI_LM_MASTER; conn->link_mode = HCI_LM_MASTER;
conn->attempt++;
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst); bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02; cp.pscan_rep_mode = 0x02;
@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn)
cp.role_switch = 0x01; cp.role_switch = 0x01;
else else
cp.role_switch = 0x00; cp.role_switch = 0x00;
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
} }

View File

@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
if (status) { if (status) {
if (conn && conn->state == BT_CONNECT) { if (conn && conn->state == BT_CONNECT) {
conn->state = BT_CLOSED; if (status != 0x0c || conn->attempt > 2) {
hci_proto_connect_cfm(conn, status); conn->state = BT_CLOSED;
hci_conn_del(conn); hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
} else
conn->state = BT_CONNECT2;
} }
} else { } else {
if (!conn) { if (!conn) {
@ -728,7 +731,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
struct hci_conn *conn; struct hci_conn *conn, *pend;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (ev->status) if (ev->status)
hci_conn_del(conn); hci_conn_del(conn);
pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
if (pend)
hci_acl_connect(pend);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }

View File

@ -618,7 +618,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
sock->ops = &hci_sock_ops; sock->ops = &hci_sock_ops;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1); sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;

View File

@ -242,10 +242,14 @@ static void add_conn(void *data)
struct hci_conn *conn = data; struct hci_conn *conn = data;
int i; int i;
device_register(&conn->dev); if (device_register(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
}
for (i = 0; conn_attrs[i]; i++) for (i = 0; conn_attrs[i]; i++)
device_create_file(&conn->dev, conn_attrs[i]); if (device_create_file(&conn->dev, conn_attrs[i]) < 0)
BT_ERR("Failed to create connection attribute");
} }
void hci_conn_add_sysfs(struct hci_conn *conn) void hci_conn_add_sysfs(struct hci_conn *conn)
@ -295,11 +299,7 @@ int hci_register_sysfs(struct hci_dev *hdev)
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
dev->class = bt_class; dev->class = bt_class;
dev->parent = hdev->parent;
if (hdev->parent)
dev->parent = hdev->parent;
else
dev->parent = &bt_platform->dev;
strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
@ -312,7 +312,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
return err; return err;
for (i = 0; bt_attrs[i]; i++) for (i = 0; bt_attrs[i]; i++)
device_create_file(dev, bt_attrs[i]); if (device_create_file(dev, bt_attrs[i]) < 0)
BT_ERR("Failed to create device attribute");
return 0; return 0;
} }

View File

@ -510,11 +510,11 @@ static int hidp_session(void *arg)
if (intr_sk->sk_state != BT_CONNECTED) if (intr_sk->sk_state != BT_CONNECTED)
wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ); wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
fput(session->ctrl_sock->file); fput(session->intr_sock->file);
wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ); wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
fput(session->intr_sock->file); fput(session->ctrl_sock->file);
__hidp_unlink_session(session); __hidp_unlink_session(session);
@ -541,12 +541,10 @@ static struct device *hidp_get_device(struct hidp_session *session)
return NULL; return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
hci_dev_put(hdev); hci_dev_put(hdev);
return &conn->dev; return conn ? &conn->dev : NULL;
} }
static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)

View File

@ -35,6 +35,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/compat.h>
#include <net/sock.h> #include <net/sock.h>
#include "hidp.h" #include "hidp.h"
@ -143,11 +144,88 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return -EINVAL; return -EINVAL;
} }
#ifdef CONFIG_COMPAT
struct compat_hidp_connadd_req {
int ctrl_sock; // Connected control socket
int intr_sock; // Connteted interrupt socket
__u16 parser;
__u16 rd_size;
compat_uptr_t rd_data;
__u8 country;
__u8 subclass;
__u16 vendor;
__u16 product;
__u16 version;
__u32 flags;
__u32 idle_to;
char name[128];
};
static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
if (cmd == HIDPGETCONNLIST) {
struct hidp_connlist_req cl;
uint32_t uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
cl.ci = compat_ptr(uci);
if (cl.cnum <= 0)
return -EINVAL;
err = hidp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
err = -EFAULT;
return err;
} else if (cmd == HIDPCONNADD) {
struct compat_hidp_connadd_req ca;
struct hidp_connadd_req __user *uca;
uca = compat_alloc_user_space(sizeof(*uca));
if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
return -EFAULT;
if (put_user(ca.ctrl_sock, &uca->ctrl_sock) ||
put_user(ca.intr_sock, &uca->intr_sock) ||
put_user(ca.parser, &uca->parser) ||
put_user(ca.rd_size, &uca->parser) ||
put_user(compat_ptr(ca.rd_data), &uca->rd_data) ||
put_user(ca.country, &uca->country) ||
put_user(ca.subclass, &uca->subclass) ||
put_user(ca.vendor, &uca->vendor) ||
put_user(ca.product, &uca->product) ||
put_user(ca.version, &uca->version) ||
put_user(ca.flags, &uca->flags) ||
put_user(ca.idle_to, &uca->idle_to) ||
copy_to_user(&uca->name[0], &ca.name[0], 128))
return -EFAULT;
arg = (unsigned long) uca;
/* Fall through. We don't actually write back any _changes_
to the structure anyway, so there's no need to copy back
into the original compat version */
}
return hidp_sock_ioctl(sock, cmd, arg);
}
#endif
static const struct proto_ops hidp_sock_ops = { static const struct proto_ops hidp_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = hidp_sock_release, .release = hidp_sock_release,
.ioctl = hidp_sock_ioctl, .ioctl = hidp_sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = hidp_sock_compat_ioctl,
#endif
.bind = sock_no_bind, .bind = sock_no_bind,
.getname = sock_no_getname, .getname = sock_no_getname,
.sendmsg = sock_no_sendmsg, .sendmsg = sock_no_sendmsg,
@ -178,7 +256,7 @@ static int hidp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW) if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT; return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1); sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;

View File

@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
sock->ops = &l2cap_sock_ops; sock->ops = &l2cap_sock_ops;
sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL); sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;
@ -2216,7 +2216,8 @@ static int __init l2cap_init(void)
goto error; goto error;
} }
class_create_file(bt_class, &class_attr_l2cap); if (class_create_file(bt_class, &class_attr_l2cap) < 0)
BT_ERR("Failed to create L2CAP info file");
BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP ver %s", VERSION);
BT_INFO("L2CAP socket layer initialized"); BT_INFO("L2CAP socket layer initialized");

View File

@ -2058,7 +2058,8 @@ static int __init rfcomm_init(void)
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
class_create_file(bt_class, &class_attr_rfcomm_dlc); if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
BT_ERR("Failed to create RFCOMM info file");
rfcomm_init_sockets(); rfcomm_init_sockets();

View File

@ -336,7 +336,8 @@ static int rfcomm_sock_create(struct socket *sock, int protocol)
sock->ops = &rfcomm_sock_ops; sock->ops = &rfcomm_sock_ops;
if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL))) sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM; return -ENOMEM;
rfcomm_sock_init(sk, NULL); rfcomm_sock_init(sk, NULL);
@ -944,7 +945,8 @@ int __init rfcomm_init_sockets(void)
if (err < 0) if (err < 0)
goto error; goto error;
class_create_file(bt_class, &class_attr_rfcomm); if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
BT_ERR("Failed to create RFCOMM info file");
BT_INFO("RFCOMM socket layer initialized"); BT_INFO("RFCOMM socket layer initialized");

View File

@ -172,12 +172,10 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
return NULL; return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
if (!conn)
return NULL;
hci_dev_put(hdev); hci_dev_put(hdev);
return &conn->dev; return conn ? &conn->dev : NULL;
} }
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
@ -767,6 +765,9 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
BT_DBG("tty %p termios %p", tty, old); BT_DBG("tty %p termios %p", tty, old);
if (!dev)
return;
/* Handle turning off CRTSCTS */ /* Handle turning off CRTSCTS */
if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
BT_DBG("Turning off CRTSCTS unsupported"); BT_DBG("Turning off CRTSCTS unsupported");

View File

@ -452,7 +452,8 @@ static int sco_sock_create(struct socket *sock, int protocol)
sock->ops = &sco_sock_ops; sock->ops = &sco_sock_ops;
if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL))) sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM; return -ENOMEM;
sco_sock_init(sk, NULL); sco_sock_init(sk, NULL);
@ -967,7 +968,8 @@ static int __init sco_init(void)
goto error; goto error;
} }
class_create_file(bt_class, &class_attr_sco); if (class_create_file(bt_class, &class_attr_sco) < 0)
BT_ERR("Failed to create SCO info file");
BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO (Voice Link) ver %s", VERSION);
BT_INFO("SCO socket layer initialized"); BT_INFO("SCO socket layer initialized");

View File

@ -128,7 +128,10 @@ void br_fdb_cleanup(unsigned long _data)
mod_timer(&br->gc_timer, jiffies + HZ/10); mod_timer(&br->gc_timer, jiffies + HZ/10);
} }
void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
void br_fdb_delete_by_port(struct net_bridge *br,
const struct net_bridge_port *p,
int do_all)
{ {
int i; int i;
@ -142,6 +145,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
if (f->dst != p) if (f->dst != p)
continue; continue;
if (f->is_static && !do_all)
continue;
/* /*
* if multiple ports all have the same device address * if multiple ports all have the same device address
* then when one port is deleted, assign * then when one port is deleted, assign

View File

@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p)
br_stp_disable_port(p); br_stp_disable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
br_fdb_delete_by_port(br, p); br_fdb_delete_by_port(br, p, 1);
list_del_rcu(&p->list); list_del_rcu(&p->list);
@ -448,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
return 0; return 0;
err2: err2:
br_fdb_delete_by_port(br, p); br_fdb_delete_by_port(br, p, 1);
err1: err1:
kobject_del(&p->kobj); kobject_del(&p->kobj);
err0: err0:

View File

@ -143,7 +143,7 @@ extern void br_fdb_changeaddr(struct net_bridge_port *p,
const unsigned char *newaddr); const unsigned char *newaddr);
extern void br_fdb_cleanup(unsigned long arg); extern void br_fdb_cleanup(unsigned long arg);
extern void br_fdb_delete_by_port(struct net_bridge *br, extern void br_fdb_delete_by_port(struct net_bridge *br,
struct net_bridge_port *p); const struct net_bridge_port *p, int do_all);
extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
const unsigned char *addr); const unsigned char *addr);
extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,

View File

@ -113,6 +113,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
del_timer(&p->forward_delay_timer); del_timer(&p->forward_delay_timer);
del_timer(&p->hold_timer); del_timer(&p->hold_timer);
br_fdb_delete_by_port(br, p, 0);
br_configuration_update(br); br_configuration_update(br);
br_port_state_selection(br); br_port_state_selection(br);

View File

@ -269,7 +269,7 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
{ {
return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
(fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
#ifdef CONFIG_IP_ROUTE_FWMARK #ifdef CONFIG_DECNET_ROUTE_FWMARK
(fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) | (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) |
#endif #endif
(fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |

View File

@ -773,13 +773,15 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
{ {
int cat = -1; int cat = -1;
u32 bitmap_len_bits = bitmap_len * 8; u32 bitmap_len_bits = bitmap_len * 8;
u32 cipso_cat_size = doi_def->map.std->cat.cipso_size; u32 cipso_cat_size;
u32 *cipso_array = doi_def->map.std->cat.cipso; u32 *cipso_array;
switch (doi_def->type) { switch (doi_def->type) {
case CIPSO_V4_MAP_PASS: case CIPSO_V4_MAP_PASS:
return 0; return 0;
case CIPSO_V4_MAP_STD: case CIPSO_V4_MAP_STD:
cipso_cat_size = doi_def->map.std->cat.cipso_size;
cipso_array = doi_def->map.std->cat.cipso;
for (;;) { for (;;) {
cat = cipso_v4_bitmap_walk(bitmap, cat = cipso_v4_bitmap_walk(bitmap,
bitmap_len_bits, bitmap_len_bits,
@ -825,19 +827,21 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
u32 net_spot_max = 0; u32 net_spot_max = 0;
u32 host_clen_bits = host_cat_len * 8; u32 host_clen_bits = host_cat_len * 8;
u32 net_clen_bits = net_cat_len * 8; u32 net_clen_bits = net_cat_len * 8;
u32 host_cat_size = doi_def->map.std->cat.local_size; u32 host_cat_size;
u32 *host_cat_array = doi_def->map.std->cat.local; u32 *host_cat_array;
switch (doi_def->type) { switch (doi_def->type) {
case CIPSO_V4_MAP_PASS: case CIPSO_V4_MAP_PASS:
net_spot_max = host_cat_len - 1; net_spot_max = host_cat_len;
while (net_spot_max > 0 && host_cat[net_spot_max] == 0) while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
net_spot_max--; net_spot_max--;
if (net_spot_max > net_cat_len) if (net_spot_max > net_cat_len)
return -EINVAL; return -EINVAL;
memcpy(net_cat, host_cat, net_spot_max); memcpy(net_cat, host_cat, net_spot_max);
return net_spot_max; return net_spot_max;
case CIPSO_V4_MAP_STD: case CIPSO_V4_MAP_STD:
host_cat_size = doi_def->map.std->cat.local_size;
host_cat_array = doi_def->map.std->cat.local;
for (;;) { for (;;) {
host_spot = cipso_v4_bitmap_walk(host_cat, host_spot = cipso_v4_bitmap_walk(host_cat,
host_clen_bits, host_clen_bits,
@ -893,8 +897,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
int net_spot = -1; int net_spot = -1;
u32 net_clen_bits = net_cat_len * 8; u32 net_clen_bits = net_cat_len * 8;
u32 host_clen_bits = host_cat_len * 8; u32 host_clen_bits = host_cat_len * 8;
u32 net_cat_size = doi_def->map.std->cat.cipso_size; u32 net_cat_size;
u32 *net_cat_array = doi_def->map.std->cat.cipso; u32 *net_cat_array;
switch (doi_def->type) { switch (doi_def->type) {
case CIPSO_V4_MAP_PASS: case CIPSO_V4_MAP_PASS:
@ -903,6 +907,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
memcpy(host_cat, net_cat, net_cat_len); memcpy(host_cat, net_cat, net_cat_len);
return net_cat_len; return net_cat_len;
case CIPSO_V4_MAP_STD: case CIPSO_V4_MAP_STD:
net_cat_size = doi_def->map.std->cat.cipso_size;
net_cat_array = doi_def->map.std->cat.cipso;
for (;;) { for (;;) {
net_spot = cipso_v4_bitmap_walk(net_cat, net_spot = cipso_v4_bitmap_walk(net_cat,
net_clen_bits, net_clen_bits,

View File

@ -94,10 +94,8 @@ int inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */
int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */ int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */
static struct inet_peer *inet_peer_unused_head; static struct inet_peer *inet_peer_unused_head;
/* Exported for inet_putpeer inline function. */ static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head; static DEFINE_SPINLOCK(inet_peer_unused_lock);
DEFINE_SPINLOCK(inet_peer_unused_lock);
#define PEER_MAX_CLEANUP_WORK 30
static void peer_check_expire(unsigned long dummy); static void peer_check_expire(unsigned long dummy);
static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0); static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
@ -340,7 +338,8 @@ static int cleanup_once(unsigned long ttl)
spin_lock_bh(&inet_peer_unused_lock); spin_lock_bh(&inet_peer_unused_lock);
p = inet_peer_unused_head; p = inet_peer_unused_head;
if (p != NULL) { if (p != NULL) {
if (time_after(p->dtime + ttl, jiffies)) { __u32 delta = (__u32)jiffies - p->dtime;
if (delta < ttl) {
/* Do not prune fresh entries. */ /* Do not prune fresh entries. */
spin_unlock_bh(&inet_peer_unused_lock); spin_unlock_bh(&inet_peer_unused_lock);
return -1; return -1;
@ -432,7 +431,7 @@ out_free:
/* Called with local BH disabled. */ /* Called with local BH disabled. */
static void peer_check_expire(unsigned long dummy) static void peer_check_expire(unsigned long dummy)
{ {
int i; unsigned long now = jiffies;
int ttl; int ttl;
if (peer_total >= inet_peer_threshold) if (peer_total >= inet_peer_threshold)
@ -441,7 +440,10 @@ static void peer_check_expire(unsigned long dummy)
ttl = inet_peer_maxttl ttl = inet_peer_maxttl
- (inet_peer_maxttl - inet_peer_minttl) / HZ * - (inet_peer_maxttl - inet_peer_minttl) / HZ *
peer_total / inet_peer_threshold * HZ; peer_total / inet_peer_threshold * HZ;
for (i = 0; i < PEER_MAX_CLEANUP_WORK && !cleanup_once(ttl); i++); while (!cleanup_once(ttl)) {
if (jiffies != now)
break;
}
/* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
* interval depending on the total number of entries (more entries, * interval depending on the total number of entries (more entries,
@ -455,3 +457,16 @@ static void peer_check_expire(unsigned long dummy)
peer_total / inet_peer_threshold * HZ; peer_total / inet_peer_threshold * HZ;
add_timer(&peer_periodic_timer); add_timer(&peer_periodic_timer);
} }
void inet_putpeer(struct inet_peer *p)
{
spin_lock_bh(&inet_peer_unused_lock);
if (atomic_dec_and_test(&p->refcnt)) {
p->unused_prevp = inet_peer_unused_tailp;
p->unused_next = NULL;
*inet_peer_unused_tailp = p;
inet_peer_unused_tailp = &p->unused_next;
p->dtime = (__u32)jiffies;
}
spin_unlock_bh(&inet_peer_unused_lock);
}

View File

@ -1196,6 +1196,8 @@ err1:
static void __exit arp_tables_fini(void) static void __exit arp_tables_fini(void)
{ {
nf_unregister_sockopt(&arpt_sockopts); nf_unregister_sockopt(&arpt_sockopts);
xt_unregister_target(&arpt_error_target);
xt_unregister_target(&arpt_standard_target);
xt_proto_fini(NF_ARP); xt_proto_fini(NF_ARP);
} }

View File

@ -44,13 +44,6 @@ MODULE_LICENSE("GPL");
static char __initdata version[] = "0.90"; static char __initdata version[] = "0.90";
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static inline int static inline int
ctnetlink_dump_tuples_proto(struct sk_buff *skb, ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct ip_conntrack_tuple *tuple, const struct ip_conntrack_tuple *tuple,
@ -398,7 +391,6 @@ nfattr_failure:
static int ctnetlink_done(struct netlink_callback *cb) static int ctnetlink_done(struct netlink_callback *cb)
{ {
DEBUGP("entered %s\n", __FUNCTION__);
if (cb->args[1]) if (cb->args[1])
ip_conntrack_put((struct ip_conntrack *)cb->args[1]); ip_conntrack_put((struct ip_conntrack *)cb->args[1]);
return 0; return 0;
@ -411,9 +403,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct ip_conntrack_tuple_hash *h; struct ip_conntrack_tuple_hash *h;
struct list_head *i; struct list_head *i;
DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
cb->args[0], *id);
read_lock_bh(&ip_conntrack_lock); read_lock_bh(&ip_conntrack_lock);
last = (struct ip_conntrack *)cb->args[1]; last = (struct ip_conntrack *)cb->args[1];
for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) { for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
@ -452,7 +441,6 @@ out:
if (last) if (last)
ip_conntrack_put(last); ip_conntrack_put(last);
DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
return skb->len; return skb->len;
} }
@ -466,8 +454,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
{ {
struct nfattr *tb[CTA_IP_MAX]; struct nfattr *tb[CTA_IP_MAX];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_IP_MAX, attr); nfattr_parse_nested(tb, CTA_IP_MAX, attr);
if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
@ -481,8 +467,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
return -EINVAL; return -EINVAL;
tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]); tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -503,8 +487,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
struct ip_conntrack_protocol *proto; struct ip_conntrack_protocol *proto;
int ret = 0; int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
@ -531,8 +513,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
struct nfattr *tb[CTA_TUPLE_MAX]; struct nfattr *tb[CTA_TUPLE_MAX];
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(tuple, 0, sizeof(*tuple)); memset(tuple, 0, sizeof(*tuple));
nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
@ -557,10 +537,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
else else
tuple->dst.dir = IP_CT_DIR_ORIGINAL; tuple->dst.dir = IP_CT_DIR_ORIGINAL;
DUMP_TUPLE(tuple);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -577,8 +553,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
struct nfattr *tb[CTA_PROTONAT_MAX]; struct nfattr *tb[CTA_PROTONAT_MAX];
struct ip_nat_protocol *npt; struct ip_nat_protocol *npt;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
@ -597,7 +571,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
ip_nat_proto_put(npt); ip_nat_proto_put(npt);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -613,8 +586,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
struct nfattr *tb[CTA_NAT_MAX]; struct nfattr *tb[CTA_NAT_MAX];
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(range, 0, sizeof(*range)); memset(range, 0, sizeof(*range));
nfattr_parse_nested(tb, CTA_NAT_MAX, nat); nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
@ -640,7 +611,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
if (err < 0) if (err < 0)
return err; return err;
DEBUGP("leaving\n");
return 0; return 0;
} }
#endif #endif
@ -650,8 +620,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
{ {
struct nfattr *tb[CTA_HELP_MAX]; struct nfattr *tb[CTA_HELP_MAX];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_HELP_MAX, attr); nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
if (!tb[CTA_HELP_NAME-1]) if (!tb[CTA_HELP_NAME-1])
@ -679,8 +647,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack *ct; struct ip_conntrack *ct;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min)) if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL; return -EINVAL;
@ -698,10 +664,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err; return err;
h = ip_conntrack_find_get(&tuple, NULL); h = ip_conntrack_find_get(&tuple, NULL);
if (!h) { if (!h)
DEBUGP("tuple not found in conntrack hash\n");
return -ENOENT; return -ENOENT;
}
ct = tuplehash_to_ctrack(h); ct = tuplehash_to_ctrack(h);
@ -716,7 +680,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct->timeout.function((unsigned long)ct); ct->timeout.function((unsigned long)ct);
ip_conntrack_put(ct); ip_conntrack_put(ct);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -731,8 +694,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct sk_buff *skb2 = NULL; struct sk_buff *skb2 = NULL;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nlh->nlmsg_flags & NLM_F_DUMP) { if (nlh->nlmsg_flags & NLM_F_DUMP) {
struct nfgenmsg *msg = NLMSG_DATA(nlh); struct nfgenmsg *msg = NLMSG_DATA(nlh);
u32 rlen; u32 rlen;
@ -770,11 +731,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err; return err;
h = ip_conntrack_find_get(&tuple, NULL); h = ip_conntrack_find_get(&tuple, NULL);
if (!h) { if (!h)
DEBUGP("tuple not found in conntrack hash");
return -ENOENT; return -ENOENT;
}
DEBUGP("tuple found\n");
ct = tuplehash_to_ctrack(h); ct = tuplehash_to_ctrack(h);
err = -ENOMEM; err = -ENOMEM;
@ -795,7 +754,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (err < 0) if (err < 0)
goto out; goto out;
DEBUGP("leaving\n");
return 0; return 0;
free: free:
@ -866,8 +824,6 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[])
char *helpname; char *helpname;
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
/* don't change helper of sibling connections */ /* don't change helper of sibling connections */
if (ct->master) if (ct->master)
return -EINVAL; return -EINVAL;
@ -938,8 +894,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
{ {
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (cda[CTA_HELP-1]) { if (cda[CTA_HELP-1]) {
err = ctnetlink_change_helper(ct, cda); err = ctnetlink_change_helper(ct, cda);
if (err < 0) if (err < 0)
@ -969,7 +923,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
#endif #endif
DEBUGP("all done\n");
return 0; return 0;
} }
@ -981,8 +934,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct ip_conntrack *ct; struct ip_conntrack *ct;
int err = -EINVAL; int err = -EINVAL;
DEBUGP("entered %s\n", __FUNCTION__);
ct = ip_conntrack_alloc(otuple, rtuple); ct = ip_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct)) if (ct == NULL || IS_ERR(ct))
return -ENOMEM; return -ENOMEM;
@ -1017,7 +968,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
if (ct->helper) if (ct->helper)
ip_conntrack_helper_put(ct->helper); ip_conntrack_helper_put(ct->helper);
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0; return 0;
err: err:
@ -1033,8 +983,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack_tuple_hash *h = NULL; struct ip_conntrack_tuple_hash *h = NULL;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min)) if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL; return -EINVAL;
@ -1058,7 +1006,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (h == NULL) { if (h == NULL) {
write_unlock_bh(&ip_conntrack_lock); write_unlock_bh(&ip_conntrack_lock);
DEBUGP("no such conntrack, create new\n");
err = -ENOENT; err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE) if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
@ -1074,7 +1021,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
/* We manipulate the conntrack inside the global conntrack table lock, /* We manipulate the conntrack inside the global conntrack table lock,
* so there's no need to increase the refcount */ * so there's no need to increase the refcount */
DEBUGP("conntrack found\n");
err = -EEXIST; err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL)) if (!(nlh->nlmsg_flags & NLM_F_EXCL))
err = ctnetlink_change_conntrack(tuplehash_to_ctrack(h), cda); err = ctnetlink_change_conntrack(tuplehash_to_ctrack(h), cda);
@ -1249,8 +1195,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct list_head *i; struct list_head *i;
u_int32_t *id = (u_int32_t *) &cb->args[0]; u_int32_t *id = (u_int32_t *) &cb->args[0];
DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
read_lock_bh(&ip_conntrack_lock); read_lock_bh(&ip_conntrack_lock);
list_for_each_prev(i, &ip_conntrack_expect_list) { list_for_each_prev(i, &ip_conntrack_expect_list) {
exp = (struct ip_conntrack_expect *) i; exp = (struct ip_conntrack_expect *) i;
@ -1266,8 +1210,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
out: out:
read_unlock_bh(&ip_conntrack_lock); read_unlock_bh(&ip_conntrack_lock);
DEBUGP("leaving, last id=%llu\n", *id);
return skb->len; return skb->len;
} }
@ -1285,8 +1227,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
struct sk_buff *skb2; struct sk_buff *skb2;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL; return -EINVAL;
@ -1437,8 +1377,6 @@ ctnetlink_create_expect(struct nfattr *cda[])
struct ip_conntrack *ct; struct ip_conntrack *ct;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
/* caller guarantees that those three CTA_EXPECT_* exist */ /* caller guarantees that those three CTA_EXPECT_* exist */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
if (err < 0) if (err < 0)
@ -1490,8 +1428,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack_expect *exp; struct ip_conntrack_expect *exp;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL; return -EINVAL;
@ -1520,8 +1456,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_change_expect(exp, cda); err = ctnetlink_change_expect(exp, cda);
write_unlock_bh(&ip_conntrack_lock); write_unlock_bh(&ip_conntrack_lock);
DEBUGP("leaving\n");
return err; return err;
} }

View File

@ -28,7 +28,7 @@ static inline int
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{ {
struct iphdr *iph = (*pskb)->nh.iph; struct iphdr *iph = (*pskb)->nh.iph;
__be16 oldtos; u_int16_t oldtos;
if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
if (!skb_make_writable(pskb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@ -37,8 +37,8 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
oldtos = iph->tos; oldtos = iph->tos;
iph->tos &= ~IPT_ECN_IP_MASK; iph->tos &= ~IPT_ECN_IP_MASK;
iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
iph->check); htons(iph->tos), iph->check);
} }
return 1; return 1;
} }

View File

@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
{ {
const struct ipt_tos_target_info *tosinfo = targinfo; const struct ipt_tos_target_info *tosinfo = targinfo;
struct iphdr *iph = (*pskb)->nh.iph; struct iphdr *iph = (*pskb)->nh.iph;
__be16 oldtos; u_int16_t oldtos;
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
if (!skb_make_writable(pskb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@ -38,8 +38,8 @@ target(struct sk_buff **pskb,
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
oldtos = iph->tos; oldtos = iph->tos;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
iph->check); htons(iph->tos), iph->check);
} }
return IPT_CONTINUE; return IPT_CONTINUE;
} }

View File

@ -117,12 +117,15 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
{ {
struct fib6_rule *r = (struct fib6_rule *) rule; struct fib6_rule *r = (struct fib6_rule *) rule;
if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) if (r->dst.plen &&
!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
return 0; return 0;
if ((flags & RT6_LOOKUP_F_HAS_SADDR) && if (r->src.plen) {
!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) if (!(flags & RT6_LOOKUP_F_HAS_SADDR) ||
return 0; !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
return 0;
}
if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
return 0; return 0;

View File

@ -967,8 +967,6 @@ static void ndisc_recv_na(struct sk_buff *skb)
ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
/* XXX: idev->cnf.prixy_ndp */ /* XXX: idev->cnf.prixy_ndp */
WARN_ON(skb->dst != NULL &&
((struct rt6_info *)skb->dst)->rt6i_idev);
goto out; goto out;
} }

View File

@ -529,13 +529,17 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
.nl_u = { .nl_u = {
.ip6_u = { .ip6_u = {
.daddr = *daddr, .daddr = *daddr,
/* TODO: saddr */
}, },
}, },
}; };
struct dst_entry *dst; struct dst_entry *dst;
int flags = strict ? RT6_LOOKUP_F_IFACE : 0; int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
if (saddr) {
memcpy(&fl.fl6_src, saddr, sizeof(*saddr));
flags |= RT6_LOOKUP_F_HAS_SADDR;
}
dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
if (dst->error == 0) if (dst->error == 0)
return (struct rt6_info *) dst; return (struct rt6_info *) dst;
@ -697,6 +701,7 @@ out2:
void ip6_route_input(struct sk_buff *skb) void ip6_route_input(struct sk_buff *skb)
{ {
struct ipv6hdr *iph = skb->nh.ipv6h; struct ipv6hdr *iph = skb->nh.ipv6h;
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi fl = { struct flowi fl = {
.iif = skb->dev->ifindex, .iif = skb->dev->ifindex,
.nl_u = { .nl_u = {
@ -711,7 +716,9 @@ void ip6_route_input(struct sk_buff *skb)
}, },
.proto = iph->nexthdr, .proto = iph->nexthdr,
}; };
int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0;
if (rt6_need_strict(&iph->daddr))
flags |= RT6_LOOKUP_F_IFACE;
skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
} }
@ -794,6 +801,9 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
if (rt6_need_strict(&fl->fl6_dst)) if (rt6_need_strict(&fl->fl6_dst))
flags |= RT6_LOOKUP_F_IFACE; flags |= RT6_LOOKUP_F_IFACE;
if (!ipv6_addr_any(&fl->fl6_src))
flags |= RT6_LOOKUP_F_HAS_SADDR;
return fib6_rule_lookup(fl, flags, ip6_pol_route_output); return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
} }
@ -1345,6 +1355,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
struct in6_addr *gateway, struct in6_addr *gateway,
struct net_device *dev) struct net_device *dev)
{ {
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct ip6rd_flowi rdfl = { struct ip6rd_flowi rdfl = {
.fl = { .fl = {
.oif = dev->ifindex, .oif = dev->ifindex,
@ -1357,7 +1368,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
}, },
.gateway = *gateway, .gateway = *gateway,
}; };
int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0;
if (rt6_need_strict(dest))
flags |= RT6_LOOKUP_F_IFACE;
return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
} }

View File

@ -853,3 +853,4 @@ int __init sit_init(void)
module_init(sit_init); module_init(sit_init);
module_exit(sit_cleanup); module_exit(sit_cleanup);
MODULE_LICENSE("GPL");

View File

@ -209,7 +209,9 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_CONNSECMARK config NETFILTER_XT_TARGET_CONNSECMARK
tristate '"CONNSECMARK" target support' tristate '"CONNSECMARK" target support'
depends on NETFILTER_XTABLES && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK) depends on NETFILTER_XTABLES && \
((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \
(IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK))
help help
The CONNSECMARK target copies security markings from packets The CONNSECMARK target copies security markings from packets
to connections, and restores security markings from connections to connections, and restores security markings from connections

View File

@ -47,13 +47,6 @@ MODULE_LICENSE("GPL");
static char __initdata version[] = "0.93"; static char __initdata version[] = "0.93";
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static inline int static inline int
ctnetlink_dump_tuples_proto(struct sk_buff *skb, ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
@ -410,7 +403,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
{ {
if (cb->args[1]) if (cb->args[1])
nf_ct_put((struct nf_conn *)cb->args[1]); nf_ct_put((struct nf_conn *)cb->args[1]);
DEBUGP("entered %s\n", __FUNCTION__);
return 0; return 0;
} }
@ -425,9 +417,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family; u_int8_t l3proto = nfmsg->nfgen_family;
DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
cb->args[0], *id);
read_lock_bh(&nf_conntrack_lock); read_lock_bh(&nf_conntrack_lock);
last = (struct nf_conn *)cb->args[1]; last = (struct nf_conn *)cb->args[1];
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
@ -471,7 +460,6 @@ out:
if (last) if (last)
nf_ct_put(last); nf_ct_put(last);
DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
return skb->len; return skb->len;
} }
@ -482,8 +470,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
struct nf_conntrack_l3proto *l3proto; struct nf_conntrack_l3proto *l3proto;
int ret = 0; int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_IP_MAX, attr); nfattr_parse_nested(tb, CTA_IP_MAX, attr);
l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
@ -493,8 +479,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
nf_ct_l3proto_put(l3proto); nf_ct_l3proto_put(l3proto);
DEBUGP("leaving\n");
return ret; return ret;
} }
@ -510,8 +494,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
struct nf_conntrack_protocol *proto; struct nf_conntrack_protocol *proto;
int ret = 0; int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
@ -538,8 +520,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
struct nfattr *tb[CTA_TUPLE_MAX]; struct nfattr *tb[CTA_TUPLE_MAX];
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(tuple, 0, sizeof(*tuple)); memset(tuple, 0, sizeof(*tuple));
nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
@ -566,10 +546,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
else else
tuple->dst.dir = IP_CT_DIR_ORIGINAL; tuple->dst.dir = IP_CT_DIR_ORIGINAL;
NF_CT_DUMP_TUPLE(tuple);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -586,8 +562,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
struct nfattr *tb[CTA_PROTONAT_MAX]; struct nfattr *tb[CTA_PROTONAT_MAX];
struct ip_nat_protocol *npt; struct ip_nat_protocol *npt;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
@ -606,7 +580,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
ip_nat_proto_put(npt); ip_nat_proto_put(npt);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -622,8 +595,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
struct nfattr *tb[CTA_NAT_MAX]; struct nfattr *tb[CTA_NAT_MAX];
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(range, 0, sizeof(*range)); memset(range, 0, sizeof(*range));
nfattr_parse_nested(tb, CTA_NAT_MAX, nat); nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
@ -649,7 +620,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
if (err < 0) if (err < 0)
return err; return err;
DEBUGP("leaving\n");
return 0; return 0;
} }
#endif #endif
@ -659,8 +629,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
{ {
struct nfattr *tb[CTA_HELP_MAX]; struct nfattr *tb[CTA_HELP_MAX];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_HELP_MAX, attr); nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
if (!tb[CTA_HELP_NAME-1]) if (!tb[CTA_HELP_NAME-1])
@ -690,8 +658,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family; u_int8_t u3 = nfmsg->nfgen_family;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min)) if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL; return -EINVAL;
@ -709,10 +675,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err; return err;
h = nf_conntrack_find_get(&tuple, NULL); h = nf_conntrack_find_get(&tuple, NULL);
if (!h) { if (!h)
DEBUGP("tuple not found in conntrack hash\n");
return -ENOENT; return -ENOENT;
}
ct = nf_ct_tuplehash_to_ctrack(h); ct = nf_ct_tuplehash_to_ctrack(h);
@ -727,7 +691,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct->timeout.function((unsigned long)ct); ct->timeout.function((unsigned long)ct);
nf_ct_put(ct); nf_ct_put(ct);
DEBUGP("leaving\n");
return 0; return 0;
} }
@ -744,8 +707,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family; u_int8_t u3 = nfmsg->nfgen_family;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nlh->nlmsg_flags & NLM_F_DUMP) { if (nlh->nlmsg_flags & NLM_F_DUMP) {
u32 rlen; u32 rlen;
@ -779,11 +740,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err; return err;
h = nf_conntrack_find_get(&tuple, NULL); h = nf_conntrack_find_get(&tuple, NULL);
if (!h) { if (!h)
DEBUGP("tuple not found in conntrack hash");
return -ENOENT; return -ENOENT;
}
DEBUGP("tuple found\n");
ct = nf_ct_tuplehash_to_ctrack(h); ct = nf_ct_tuplehash_to_ctrack(h);
err = -ENOMEM; err = -ENOMEM;
@ -804,7 +763,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (err < 0) if (err < 0)
goto out; goto out;
DEBUGP("leaving\n");
return 0; return 0;
free: free:
@ -876,8 +834,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
char *helpname; char *helpname;
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (!help) { if (!help) {
/* FIXME: we need to reallocate and rehash */ /* FIXME: we need to reallocate and rehash */
return -EBUSY; return -EBUSY;
@ -954,8 +910,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
{ {
int err; int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (cda[CTA_HELP-1]) { if (cda[CTA_HELP-1]) {
err = ctnetlink_change_helper(ct, cda); err = ctnetlink_change_helper(ct, cda);
if (err < 0) if (err < 0)
@ -985,7 +939,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif #endif
DEBUGP("all done\n");
return 0; return 0;
} }
@ -997,8 +950,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct nf_conn *ct; struct nf_conn *ct;
int err = -EINVAL; int err = -EINVAL;
DEBUGP("entered %s\n", __FUNCTION__);
ct = nf_conntrack_alloc(otuple, rtuple); ct = nf_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct)) if (ct == NULL || IS_ERR(ct))
return -ENOMEM; return -ENOMEM;
@ -1028,7 +979,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
add_timer(&ct->timeout); add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct); nf_conntrack_hash_insert(ct);
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0; return 0;
err: err:
@ -1046,8 +996,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family; u_int8_t u3 = nfmsg->nfgen_family;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min)) if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL; return -EINVAL;
@ -1071,7 +1019,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (h == NULL) { if (h == NULL) {
write_unlock_bh(&nf_conntrack_lock); write_unlock_bh(&nf_conntrack_lock);
DEBUGP("no such conntrack, create new\n");
err = -ENOENT; err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE) if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
@ -1087,7 +1034,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
/* We manipulate the conntrack inside the global conntrack table lock, /* We manipulate the conntrack inside the global conntrack table lock,
* so there's no need to increase the refcount */ * so there's no need to increase the refcount */
DEBUGP("conntrack found\n");
err = -EEXIST; err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL)) if (!(nlh->nlmsg_flags & NLM_F_EXCL))
err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
@ -1268,8 +1214,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family; u_int8_t l3proto = nfmsg->nfgen_family;
DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
read_lock_bh(&nf_conntrack_lock); read_lock_bh(&nf_conntrack_lock);
list_for_each_prev(i, &nf_conntrack_expect_list) { list_for_each_prev(i, &nf_conntrack_expect_list) {
exp = (struct nf_conntrack_expect *) i; exp = (struct nf_conntrack_expect *) i;
@ -1287,8 +1231,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
out: out:
read_unlock_bh(&nf_conntrack_lock); read_unlock_bh(&nf_conntrack_lock);
DEBUGP("leaving, last id=%llu\n", *id);
return skb->len; return skb->len;
} }
@ -1308,8 +1250,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family; u_int8_t u3 = nfmsg->nfgen_family;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL; return -EINVAL;
@ -1460,8 +1400,6 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
struct nf_conn_help *help; struct nf_conn_help *help;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
/* caller guarantees that those three CTA_EXPECT_* exist */ /* caller guarantees that those three CTA_EXPECT_* exist */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
if (err < 0) if (err < 0)
@ -1516,8 +1454,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family; u_int8_t u3 = nfmsg->nfgen_family;
int err = 0; int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL; return -EINVAL;
@ -1546,8 +1482,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_change_expect(exp, cda); err = ctnetlink_change_expect(exp, cda);
write_unlock_bh(&nf_conntrack_lock); write_unlock_bh(&nf_conntrack_lock);
DEBUGP("leaving\n");
return err; return err;
} }

View File

@ -68,7 +68,7 @@ static int __init xt_nfqueue_init(void)
static void __exit xt_nfqueue_fini(void) static void __exit xt_nfqueue_fini(void)
{ {
xt_register_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target)); xt_unregister_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target));
} }
module_init(xt_nfqueue_init); module_init(xt_nfqueue_init);

View File

@ -147,7 +147,7 @@ static int __init xt_connmark_init(void)
static void __exit xt_connmark_fini(void) static void __exit xt_connmark_fini(void)
{ {
xt_register_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match)); xt_unregister_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match));
} }
module_init(xt_connmark_init); module_init(xt_connmark_init);

View File

@ -614,6 +614,14 @@ out:
return x; return x;
} }
static void xfrm_hash_grow_check(int have_hash_collision)
{
if (have_hash_collision &&
(xfrm_state_hmask + 1) < xfrm_state_hashmax &&
xfrm_state_num > xfrm_state_hmask)
schedule_work(&xfrm_hash_work);
}
static void __xfrm_state_insert(struct xfrm_state *x) static void __xfrm_state_insert(struct xfrm_state *x)
{ {
unsigned int h; unsigned int h;
@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
xfrm_state_num++; xfrm_state_num++;
if (x->bydst.next != NULL && xfrm_hash_grow_check(x->bydst.next != NULL);
(xfrm_state_hmask + 1) < xfrm_state_hashmax &&
xfrm_state_num > xfrm_state_hmask)
schedule_work(&xfrm_hash_work);
} }
/* xfrm_state_lock is held */ /* xfrm_state_lock is held */
@ -753,6 +758,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
h = xfrm_src_hash(daddr, saddr, family); h = xfrm_src_hash(daddr, saddr, family);
hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
wake_up(&km_waitq); wake_up(&km_waitq);
xfrm_state_num++;
xfrm_hash_grow_check(x->bydst.next != NULL);
} }
return x; return x;

View File

@ -93,11 +93,15 @@ int ebitmap_export(const struct ebitmap *src,
size_t bitmap_byte; size_t bitmap_byte;
unsigned char bitmask; unsigned char bitmask;
if (src->highbit == 0) {
*dst = NULL;
*dst_len = 0;
return 0;
}
bitmap_len = src->highbit / 8; bitmap_len = src->highbit / 8;
if (src->highbit % 7) if (src->highbit % 7)
bitmap_len += 1; bitmap_len += 1;
if (bitmap_len == 0)
return -EINVAL;
bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) +
sizeof(MAPTYPE), sizeof(MAPTYPE),

View File

@ -640,8 +640,13 @@ int mls_export_cat(const struct context *context,
{ {
int rc = -EPERM; int rc = -EPERM;
if (!selinux_mls_enabled) if (!selinux_mls_enabled) {
*low = NULL;
*low_len = 0;
*high = NULL;
*high_len = 0;
return 0; return 0;
}
if (low != NULL) { if (low != NULL) {
rc = ebitmap_export(&context->range.level[0].cat, rc = ebitmap_export(&context->range.level[0].cat,
@ -661,10 +666,16 @@ int mls_export_cat(const struct context *context,
return 0; return 0;
export_cat_failure: export_cat_failure:
if (low != NULL) if (low != NULL) {
kfree(*low); kfree(*low);
if (high != NULL) *low = NULL;
*low_len = 0;
}
if (high != NULL) {
kfree(*high); kfree(*high);
*high = NULL;
*high_len = 0;
}
return rc; return rc;
} }

View File

@ -2399,31 +2399,33 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
if (!ss_initialized) if (!ss_initialized)
return 0; return 0;
netlbl_secattr_init(&secattr);
POLICY_RDLOCK; POLICY_RDLOCK;
ctx = sidtab_search(&sidtab, sid); ctx = sidtab_search(&sidtab, sid);
if (ctx == NULL) if (ctx == NULL)
goto netlbl_socket_setsid_return; goto netlbl_socket_setsid_return;
netlbl_secattr_init(&secattr);
secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
GFP_ATOMIC); GFP_ATOMIC);
mls_export_lvl(ctx, &secattr.mls_lvl, NULL); mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
secattr.mls_lvl_vld = 1; secattr.mls_lvl_vld = 1;
mls_export_cat(ctx, rc = mls_export_cat(ctx,
&secattr.mls_cat, &secattr.mls_cat,
&secattr.mls_cat_len, &secattr.mls_cat_len,
NULL, NULL,
NULL); NULL);
if (rc != 0)
goto netlbl_socket_setsid_return;
rc = netlbl_socket_setattr(sock, &secattr); rc = netlbl_socket_setattr(sock, &secattr);
if (rc == 0) if (rc == 0)
sksec->nlbl_state = NLBL_LABELED; sksec->nlbl_state = NLBL_LABELED;
netlbl_secattr_destroy(&secattr);
netlbl_socket_setsid_return: netlbl_socket_setsid_return:
POLICY_RDUNLOCK; POLICY_RDUNLOCK;
netlbl_secattr_destroy(&secattr);
return rc; return rc;
} }