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:
commit
5206a79d7b
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) |
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue