Commit 5206a79d authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 29da7eb0 3f530692
......@@ -2049,11 +2049,13 @@ P: Marc Boucher
P: James Morris
P: Harald Welte
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.iptables.org/
L: netfilter@lists.netfilter.org
L: netfilter-devel@lists.netfilter.org
S: Supported
NETLABEL
......
......@@ -29,7 +29,6 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/device.h>
#include <linux/firmware.h>
......@@ -43,7 +42,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "1.0"
#define VERSION "1.1"
static int ignore = 0;
......@@ -72,7 +71,7 @@ struct bcm203x_data {
unsigned long state;
struct timer_list timer;
struct work_struct work;
struct urb *urb;
unsigned char *buffer;
......@@ -105,7 +104,7 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY;
mod_timer(&data->timer, jiffies + (HZ / 10));
schedule_work(&data->work);
break;
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)
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);
init_timer(&data->timer);
data->timer.function = bcm203x_timer;
data->timer.data = (unsigned long) data;
INIT_WORK(&data->work, bcm203x_work, (void *) data);
usb_set_intfdata(intf, data);
mod_timer(&data->timer, jiffies + HZ);
schedule_work(&data->work);
return 0;
}
......
......@@ -153,6 +153,7 @@ struct hci_conn {
__u8 mode;
__u8 type;
__u8 out;
__u8 attempt;
__u8 dev_class[3];
__u8 features[8];
__u16 interval;
......@@ -289,6 +290,22 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
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_add_sco(struct hci_conn *conn, __u16 handle);
......
......@@ -19,7 +19,7 @@ struct inet_peer
{
struct inet_peer *avl_left, *avl_right;
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 */
atomic_t refcnt;
__be32 v4daddr; /* peer's address */
......@@ -35,21 +35,8 @@ void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */
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 */
static inline 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 void inet_putpeer(struct inet_peer *p);
extern spinlock_t inet_peer_idlock;
/* can be called with or without local BH being disabled */
......
......@@ -48,41 +48,56 @@
#define BT_DBG(D...)
#endif
#define VERSION "2.10"
#define VERSION "2.11"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
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 err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
write_lock(&bt_proto_lock);
if (bt_proto[proto])
return -EEXIST;
err = -EEXIST;
else
bt_proto[proto] = ops;
bt_proto[proto] = ops;
return 0;
write_unlock(&bt_proto_lock);
return err;
}
EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto)
{
int err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
write_lock(&bt_proto_lock);
if (!bt_proto[proto])
return -ENOENT;
err = -ENOENT;
else
bt_proto[proto] = NULL;
bt_proto[proto] = NULL;
return 0;
write_unlock(&bt_proto_lock);
return err;
}
EXPORT_SYMBOL(bt_sock_unregister);
static int bt_sock_create(struct socket *sock, int proto)
{
int err = 0;
int err;
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
......@@ -92,11 +107,18 @@ static int bt_sock_create(struct socket *sock, int proto)
request_module("bt-proto-%d", proto);
}
#endif
err = -EPROTONOSUPPORT;
read_lock(&bt_proto_lock);
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(sock, proto);
module_put(bt_proto[proto]->owner);
}
read_unlock(&bt_proto_lock);
return err;
}
......
......@@ -528,12 +528,10 @@ static struct device *bnep_get_device(struct bnep_session *session)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
hci_dev_put(hdev);
return &conn->dev;
return conn ? &conn->dev : NULL;
}
int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
......
......@@ -43,6 +43,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/init.h>
#include <linux/compat.h>
#include <net/sock.h>
#include <asm/system.h>
......@@ -146,24 +147,56 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
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 = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = bnep_sock_release,
.ioctl = bnep_sock_ioctl,
.bind = sock_no_bind,
.getname = sock_no_getname,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
.poll = sock_no_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = bnep_sock_release,
.ioctl = bnep_sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = bnep_sock_compat_ioctl,
#endif
.bind = sock_no_bind,
.getname = sock_no_getname,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
.poll = sock_no_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
};
static struct proto bnep_proto = {
......@@ -181,7 +214,7 @@ static int bnep_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1);
sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
if (!sk)
return -ENOMEM;
......
......@@ -34,6 +34,7 @@
#include <linux/socket.h>
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/compat.h>
#include <net/sock.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;
}
#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 = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = cmtp_sock_release,
.ioctl = cmtp_sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = cmtp_sock_compat_ioctl,
#endif
.bind = sock_no_bind,
.getname = sock_no_getname,
.sendmsg = sock_no_sendmsg,
......@@ -172,7 +205,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1);
sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
if (!sk)
return -ENOMEM;
......
......@@ -51,7 +51,7 @@
#define BT_DBG(D...)
#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 inquiry_entry *ie;
......@@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn)
conn->out = 1;
conn->link_mode = HCI_LM_MASTER;
conn->attempt++;
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
......@@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn)
cp.role_switch = 0x01;
else
cp.role_switch = 0x00;
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
}
......
......@@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
if (status) {
if (conn && conn->state == BT_CONNECT) {
conn->state = BT_CLOSED;
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
if (status != 0x0c || conn->attempt > 2) {
conn->state = BT_CLOSED;
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
} else
conn->state = BT_CONNECT2;
}
} else {
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)
{
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);
......@@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (ev->status)
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);
}
......
......@@ -618,7 +618,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
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)
return -ENOMEM;
......
......@@ -242,10 +242,14 @@ static void add_conn(void *data)
struct hci_conn *conn = data;
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++)
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)
......@@ -295,11 +299,7 @@ int hci_register_sysfs(struct hci_dev *hdev)
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
dev->class = bt_class;
if (hdev->parent)
dev->parent = hdev->parent;
else
dev->parent = &bt_platform->dev;
dev->parent = hdev->parent;
strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
......@@ -312,7 +312,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
return err;
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;
}
......
......@@ -510,11 +510,11 @@ static int hidp_session(void *arg)
if (intr_sk->sk_state != BT_CONNECTED)
wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
fput(session->ctrl_sock->file);
fput(session->intr_sock->file);
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);
......@@ -541,12 +541,10 @@ static struct device *hidp_get_device(struct hidp_session *session)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
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)
......
......@@ -35,6 +35,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/init.h>
#include <linux/compat.h>
#include <net/sock.h>
#include "hidp.h"
......@@ -143,11 +144,88 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
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 = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hidp_sock_release,
.ioctl = hidp_sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = hidp_sock_compat_ioctl,
#endif
.bind = sock_no_bind,
.getname = sock_no_getname,
.sendmsg = sock_no_sendmsg,
......@@ -178,7 +256,7 @@ static int hidp_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1);
sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
if (!sk)
return -ENOMEM;
......
......@@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
sock->ops = &l2cap_sock_ops;
sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL);
sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM;
......@@ -2216,7 +2216,8 @@ static int __init l2cap_init(void)
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 socket layer initialized");
......
......@@ -2058,7 +2058,8 @@ static int __init rfcomm_init(void)
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();
......
......@@ -336,7 +336,8 @@ static int rfcomm_sock_create(struct socket *sock, int protocol)
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;
rfcomm_sock_init(sk, NULL);
......@@ -944,7 +945,8 @@ int __init rfcomm_init_sockets(void)
if (err < 0)
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");
......
......@@ -172,12 +172,10 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
if (!conn)
return NULL;
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)
......@@ -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);
if (!dev)
return;
/* Handle turning off CRTSCTS */
if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
BT_DBG("Turning off CRTSCTS unsupported");
......
......@@ -452,7 +452,8 @@ static int sco_sock_create(struct socket *sock, int protocol)
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;
sco_sock_init(sk, NULL);
......@@ -967,7 +968,8 @@ static int __init sco_init(void)
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 socket layer initialized");
......
......@@ -128,7 +128,10 @@ void br_fdb_cleanup(unsigned long _data)
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;
......@@ -142,6 +145,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
if (f->dst != p)
continue;
if (f->is_static && !do_all)
continue;
/*
* if multiple ports all have the same device address
* then when one port is deleted, assign
......
......@@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p)
br_stp_disable_port(p);
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);
......@@ -448,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
return 0;
err2:
br_fdb_delete_by_port(br, p);
br_fdb_delete_by_port(br, p, 1);
err1:
kobject_del(&p->kobj);
err0:
......
......@@ -143,7 +143,7 @@ extern void br_fdb_changeaddr(struct net_bridge_port *p,
const unsigned char *newaddr);
extern void br_fdb_cleanup(unsigned long arg);
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,
const unsigned char *addr);
extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,
......
......@@ -113,6 +113,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
del_timer(&p->forward_delay_timer);
del_timer(&p->hold_timer);
br_fdb_delete_by_port(br, p, 0);
br_configuration_update(br);
br_port_state_selection(br);
......
......@@ -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) |
(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) |
#endif
(fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
......
......@@ -773,13 +773,15 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
{
int cat = -1;
u32 bitmap_len_bits = bitmap_len * 8;
u32 cipso_cat_size = doi_def->map.std->cat.cipso_size;
u32 *cipso_array = doi_def->map.std->cat.cipso;
u32 cipso_cat_size;
u32 *cipso_array;
switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
return 0;
case CIPSO_V4_MAP_STD:
cipso_cat_size = doi_def->map.std->cat.cipso_size;
cipso_array = doi_def->map.std->cat.cipso;
for (;;) {
cat = cipso_v4_bitmap_walk(bitmap,
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 host_clen_bits = host_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_array = doi_def->map.std->cat.local;
u32 host_cat_size;
u32 *host_cat_array;
switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
net_spot_max = host_cat_len - 1;
while (net_spot_max > 0 && host_cat[net_spot_max] == 0)
net_spot_max = host_cat_len;
while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
net_spot_max--;
if (net_spot_max > net_cat_len)
return -EINVAL;
memcpy(net_cat, host_cat, net_spot_max);
return net_spot_max;
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 (;;) {
host_spot = cipso_v4_bitmap_walk(host_cat,
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;
u32 net_clen_bits = net_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_array = doi_def->map.std->cat.cipso;
u32 net_cat_size;
u32 *net_cat_array;
switch (doi_def->type) {
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);
return net_cat_len;
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 (;;) {
net_spot = cipso_v4_bitmap_walk(net_cat,
net_clen_bits,
......
......@@ -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 */
static struct inet_peer *inet_peer_unused_head;
/* Exported for inet_putpeer inline function. */
struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
DEFINE_SPINLOCK(inet_peer_unused_lock);
#define PEER_MAX_CLEANUP_WORK 30
static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
static DEFINE_SPINLOCK(inet_peer_unused_lock);
static void peer_check_expire(unsigned long dummy);
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);
p = inet_peer_unused_head;
if (p != NULL) {
if (time_after(p->dtime + ttl, jiffies)) {
__u32 delta = (__u32)jiffies - p->dtime;
if (delta < ttl) {
/* Do not prune fresh entries. */
spin_unlock_bh(&inet_peer_unused_lock);
return -1;
......@@ -432,7 +431,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create)
/* Called with local BH disabled. */
static void peer_check_expire(unsigned long dummy)
{
int i;
unsigned long now = jiffies;
int ttl;
if (peer_total >= inet_peer_threshold)
......@@ -441,7 +440,10 @@ static void peer_check_expire(unsigned long dummy)
ttl = inet_peer_maxttl
- (inet_peer_maxttl - inet_peer_minttl) / 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
* 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;
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);
}
......@@ -1196,6 +1196,8 @@ static int __init arp_tables_init(void)
static void __exit arp_tables_fini(void)
{
nf_unregister_sockopt(&arpt_sockopts);
xt_unregister_target(&arpt_error_target);
xt_unregister_target(&arpt_standard_target);
xt_proto_fini(NF_ARP);
}
......
......@@ -44,13 +44,6 @@ MODULE_LICENSE("GPL");
static char __initdata version[] = "0.90";
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static inline int
ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct ip_conntrack_tuple *tuple,
......@@ -398,7 +391,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
static int ctnetlink_done(struct netlink_callback *cb)
{
DEBUGP("entered %s\n", __FUNCTION__);
if (cb->args[1])
ip_conntrack_put((struct ip_conntrack *)cb->args[1]);
return 0;
......@@ -411,9 +403,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct ip_conntrack_tuple_hash *h;
struct list_head *i;
DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
cb->args[0], *id);
read_lock_bh(&ip_conntrack_lock);
last = (struct ip_conntrack *)cb->args[1];
for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
......@@ -452,7 +441,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
if (last)
ip_conntrack_put(last);
DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
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];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_IP_MAX, attr);
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;
tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
DEBUGP("leaving\n");
return 0;
}
......@@ -503,8 +487,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
struct ip_conntrack_protocol *proto;
int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
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];
int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(tuple, 0, sizeof(*tuple));
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
tuple->dst.dir = IP_CT_DIR_ORIGINAL;
DUMP_TUPLE(tuple);
DEBUGP("leaving\n");
return 0;
}
......@@ -577,8 +553,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
struct nfattr *tb[CTA_PROTONAT_MAX];
struct ip_nat_protocol *npt;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
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);
DEBUGP("leaving\n");
return 0;
}
......@@ -613,8 +586,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
struct nfattr *tb[CTA_NAT_MAX];
int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(range, 0, sizeof(*range));
nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
......@@ -640,7 +611,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
if (err < 0)
return err;
DEBUGP("leaving\n");
return 0;
}
#endif
......@@ -650,8 +620,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
{
struct nfattr *tb[CTA_HELP_MAX];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
if (!tb[CTA_HELP_NAME-1])
......@@ -679,8 +647,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack *ct;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
......@@ -698,10 +664,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
h = ip_conntrack_find_get(&tuple, NULL);
if (!h) {
DEBUGP("tuple not found in conntrack hash\n");
if (!h)
return -ENOENT;
}
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);
ip_conntrack_put(ct);
DEBUGP("leaving\n");
return 0;
}
......@@ -731,8 +694,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct sk_buff *skb2 = NULL;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nlh->nlmsg_flags & NLM_F_DUMP) {
struct nfgenmsg *msg = NLMSG_DATA(nlh);
u32 rlen;
......@@ -770,11 +731,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
h = ip_conntrack_find_get(&tuple, NULL);
if (!h) {
DEBUGP("tuple not found in conntrack hash");
if (!h)
return -ENOENT;
}
DEBUGP("tuple found\n");
ct = tuplehash_to_ctrack(h);
err = -ENOMEM;
......@@ -795,7 +754,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (err < 0)
goto out;
DEBUGP("leaving\n");
return 0;
free:
......@@ -866,8 +824,6 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[])
char *helpname;
int err;
DEBUGP("entered %s\n", __FUNCTION__);
/* don't change helper of sibling connections */
if (ct->master)
return -EINVAL;
......@@ -938,8 +894,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
{
int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (cda[CTA_HELP-1]) {
err = ctnetlink_change_helper(ct, cda);
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]));
#endif
DEBUGP("all done\n");
return 0;
}
......@@ -981,8 +934,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct ip_conntrack *ct;
int err = -EINVAL;
DEBUGP("entered %s\n", __FUNCTION__);
ct = ip_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct))
return -ENOMEM;
......@@ -1017,7 +968,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
if (ct->helper)
ip_conntrack_helper_put(ct->helper);
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0;
err:
......@@ -1033,8 +983,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack_tuple_hash *h = NULL;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
......@@ -1058,7 +1006,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (h == NULL) {
write_unlock_bh(&ip_conntrack_lock);
DEBUGP("no such conntrack, create new\n");
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
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,
* so there's no need to increase the refcount */
DEBUGP("conntrack found\n");
err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL))
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;
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);
list_for_each_prev(i, &ip_conntrack_expect_list) {
exp = (struct ip_conntrack_expect *) i;
......@@ -1266,8 +1210,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
out:
read_unlock_bh(&ip_conntrack_lock);
DEBUGP("leaving, last id=%llu\n", *id);
return skb->len;
}
......@@ -1285,8 +1227,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
struct sk_buff *skb2;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
......@@ -1437,8 +1377,6 @@ ctnetlink_create_expect(struct nfattr *cda[])
struct ip_conntrack *ct;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
/* caller guarantees that those three CTA_EXPECT_* exist */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
if (err < 0)
......@@ -1490,8 +1428,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack_expect *exp;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
......@@ -1520,8 +1456,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_change_expect(exp, cda);
write_unlock_bh(&ip_conntrack_lock);
DEBUGP("leaving\n");
return err;
}
......
......@@ -28,7 +28,7 @@ static inline int
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
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 (!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;
iph->tos &= ~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);
iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
htons(iph->tos), iph->check);
}
return 1;
}
......
......@@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
{
const struct ipt_tos_target_info *tosinfo = targinfo;
struct iphdr *iph = (*pskb)->nh.iph;
__be16 oldtos;
u_int16_t oldtos;
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
......@@ -38,8 +38,8 @@ target(struct sk_buff **pskb,
iph = (*pskb)->nh.iph;
oldtos = iph->tos;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
iph->check);
iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
htons(iph->tos), iph->check);
}
return IPT_CONTINUE;
}
......
......@@ -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;
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;
if ((flags & RT6_LOOKUP_F_HAS_SADDR) &&
!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
return 0;
if (r->src.plen) {
if (!(flags & RT6_LOOKUP_F_HAS_SADDR) ||
!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))
return 0;
......
......@@ -967,8 +967,6 @@ static void ndisc_recv_na(struct sk_buff *skb)
ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
/* XXX: idev->cnf.prixy_ndp */
WARN_ON(skb->dst != NULL &&
((struct rt6_info *)skb->dst)->rt6i_idev);
goto out;
}
......
......@@ -529,13 +529,17 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
.nl_u = {
.ip6_u = {
.daddr = *daddr,
/* TODO: saddr */
},
},
};
struct dst_entry *dst;
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);
if (dst->error == 0)
return (struct rt6_info *) dst;
......@@ -697,6 +701,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
void ip6_route_input(struct sk_buff *skb)
{
struct ipv6hdr *iph = skb->nh.ipv6h;
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi fl = {
.iif = skb->dev->ifindex,
.nl_u = {
......@@ -711,7 +716,9 @@ void ip6_route_input(struct sk_buff *skb)
},
.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);
}
......@@ -794,6 +801,9 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
if (rt6_need_strict(&fl->fl6_dst))
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);
}
......@@ -1345,6 +1355,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
struct in6_addr *gateway,
struct net_device *dev)
{
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct ip6rd_flowi rdfl = {
.fl = {
.oif = dev->ifindex,
......@@ -1357,7 +1368,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
},
.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);
}
......
......@@ -853,3 +853,4 @@ int __init sit_init(void)
module_init(sit_init);
module_exit(sit_cleanup);
MODULE_LICENSE("GPL");
......@@ -209,7 +209,9 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_CONNSECMARK
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
The CONNSECMARK target copies security markings from packets
to connections, and restores security markings from connections
......
......@@ -47,13 +47,6 @@ MODULE_LICENSE("GPL");
static char __initdata version[] = "0.93";
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static inline int
ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
......@@ -410,7 +403,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
{
if (cb->args[1])
nf_ct_put((struct nf_conn *)cb->args[1]);
DEBUGP("entered %s\n", __FUNCTION__);
return 0;
}
......@@ -425,9 +417,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
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);
last = (struct nf_conn *)cb->args[1];
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
......@@ -471,7 +460,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
if (last)
nf_ct_put(last);
DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
return skb->len;
}
......@@ -482,8 +470,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
struct nf_conntrack_l3proto *l3proto;
int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_IP_MAX, attr);
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);
DEBUGP("leaving\n");
return ret;
}
......@@ -510,8 +494,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
struct nf_conntrack_protocol *proto;
int ret = 0;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
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];
int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(tuple, 0, sizeof(*tuple));
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
tuple->dst.dir = IP_CT_DIR_ORIGINAL;
NF_CT_DUMP_TUPLE(tuple);
DEBUGP("leaving\n");
return 0;
}
......@@ -586,8 +562,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
struct nfattr *tb[CTA_PROTONAT_MAX];
struct ip_nat_protocol *npt;
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
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);
DEBUGP("leaving\n");
return 0;
}
......@@ -622,8 +595,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
struct nfattr *tb[CTA_NAT_MAX];
int err;
DEBUGP("entered %s\n", __FUNCTION__);
memset(range, 0, sizeof(*range));
nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
......@@ -649,7 +620,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
if (err < 0)
return err;
DEBUGP("leaving\n");
return 0;
}
#endif
......@@ -659,8 +629,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
{
struct nfattr *tb[CTA_HELP_MAX];
DEBUGP("entered %s\n", __FUNCTION__);
nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
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;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
......@@ -709,10 +675,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
h = nf_conntrack_find_get(&tuple, NULL);
if (!h) {
DEBUGP("tuple not found in conntrack hash\n");
if (!h)
return -ENOENT;
}
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);
nf_ct_put(ct);
DEBUGP("leaving\n");
return 0;
}
......@@ -744,8 +707,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nlh->nlmsg_flags & NLM_F_DUMP) {
u32 rlen;
......@@ -779,11 +740,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
h = nf_conntrack_find_get(&tuple, NULL);
if (!h) {
DEBUGP("tuple not found in conntrack hash");
if (!h)
return -ENOENT;
}
DEBUGP("tuple found\n");
ct = nf_ct_tuplehash_to_ctrack(h);
err = -ENOMEM;
......@@ -804,7 +763,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (err < 0)
goto out;
DEBUGP("leaving\n");
return 0;
free:
......@@ -876,8 +834,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
char *helpname;
int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (!help) {
/* FIXME: we need to reallocate and rehash */
return -EBUSY;
......@@ -954,8 +910,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
{
int err;
DEBUGP("entered %s\n", __FUNCTION__);
if (cda[CTA_HELP-1]) {
err = ctnetlink_change_helper(ct, cda);
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]));
#endif
DEBUGP("all done\n");
return 0;
}
......@@ -997,8 +950,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct nf_conn *ct;
int err = -EINVAL;
DEBUGP("entered %s\n", __FUNCTION__);
ct = nf_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct))
return -ENOMEM;
......@@ -1028,7 +979,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0;
err:
......@@ -1046,8 +996,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
......@@ -1071,7 +1019,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (h == NULL) {
write_unlock_bh(&nf_conntrack_lock);
DEBUGP("no such conntrack, create new\n");
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
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,
* so there's no need to increase the refcount */
DEBUGP("conntrack found\n");
err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL))
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);
u_int8_t l3proto = nfmsg->nfgen_family;
DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
read_lock_bh(&nf_conntrack_lock);
list_for_each_prev(i, &nf_conntrack_expect_list) {
exp = (struct nf_conntrack_expect *) i;
......@@ -1287,8 +1231,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
out:
read_unlock_bh(&nf_conntrack_lock);
DEBUGP("leaving, last id=%llu\n", *id);
return skb->len;
}
......@@ -1308,8 +1250,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
......@@ -1460,8 +1400,6 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
struct nf_conn_help *help;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
/* caller guarantees that those three CTA_EXPECT_* exist */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
if (err < 0)
......@@ -1516,8 +1454,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
......@@ -1546,8 +1482,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = ctnetlink_change_expect(exp, cda);
write_unlock_bh(&nf_conntrack_lock);
DEBUGP("leaving\n");
return err;
}
......
......@@ -68,7 +68,7 @@ static int __init xt_nfqueue_init(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);
......
......@@ -147,7 +147,7 @@ static int __init xt_connmark_init(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);
......
......@@ -614,6 +614,14 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
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)
{
unsigned int h;
......@@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
xfrm_state_num++;
if (x->bydst.next != NULL &&
(xfrm_state_hmask + 1) < xfrm_state_hashmax &&
xfrm_state_num > xfrm_state_hmask)
schedule_work(&xfrm_hash_work);
xfrm_hash_grow_check(x->bydst.next != NULL);
}
/* 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);
hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
wake_up(&km_waitq);
xfrm_state_num++;
xfrm_hash_grow_check(x->bydst.next != NULL);
}
return x;
......
......@@ -93,11 +93,15 @@ int ebitmap_export(const struct ebitmap *src,
size_t bitmap_byte;
unsigned char bitmask;
if (src->highbit == 0) {
*dst = NULL;
*dst_len = 0;
return 0;
}
bitmap_len = src->highbit / 8;
if (src->highbit % 7)
bitmap_len += 1;
if (bitmap_len == 0)
return -EINVAL;
bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) +
sizeof(MAPTYPE),
......
......@@ -640,8 +640,13 @@ int mls_export_cat(const struct context *context,
{
int rc = -EPERM;
if (!selinux_mls_enabled)
if (!selinux_mls_enabled) {
*low = NULL;
*low_len = 0;
*high = NULL;
*high_len = 0;
return 0;
}
if (low != NULL) {
rc = ebitmap_export(&context->range.level[0].cat,
......@@ -661,10 +666,16 @@ int mls_export_cat(const struct context *context,
return 0;
export_cat_failure:
if (low != NULL)
if (low != NULL) {
kfree(*low);
if (high != NULL)
*low = NULL;
*low_len = 0;
}
if (high != NULL) {
kfree(*high);
*high = NULL;
*high_len = 0;
}
return rc;
}
......
......@@ -2399,31 +2399,33 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
if (!ss_initialized)
return 0;
netlbl_secattr_init(&secattr);
POLICY_RDLOCK;
ctx = sidtab_search(&sidtab, sid);
if (ctx == NULL)
goto netlbl_socket_setsid_return;
netlbl_secattr_init(&secattr);
secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
GFP_ATOMIC);
mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
secattr.mls_lvl_vld = 1;
mls_export_cat(ctx,
&secattr.mls_cat,
&secattr.mls_cat_len,
NULL,
NULL);
rc = mls_export_cat(ctx,
&secattr.mls_cat,
&secattr.mls_cat_len,
NULL,
NULL);
if (rc != 0)
goto netlbl_socket_setsid_return;
rc = netlbl_socket_setattr(sock, &secattr);
if (rc == 0)
sksec->nlbl_state = NLBL_LABELED;
netlbl_secattr_destroy(&secattr);
netlbl_socket_setsid_return:
POLICY_RDUNLOCK;
netlbl_secattr_destroy(&secattr);
return rc;
}
......
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