diff options
Diffstat (limited to 'net')
152 files changed, 1604 insertions, 1057 deletions
diff --git a/net/Kconfig b/net/Kconfig index a81aca43932f..67e39ad8b8b6 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -63,6 +63,7 @@ config INET | |||
63 | if INET | 63 | if INET |
64 | source "net/ipv4/Kconfig" | 64 | source "net/ipv4/Kconfig" |
65 | source "net/ipv6/Kconfig" | 65 | source "net/ipv6/Kconfig" |
66 | source "net/netlabel/Kconfig" | ||
66 | 67 | ||
67 | endif # if INET | 68 | endif # if INET |
68 | 69 | ||
@@ -249,8 +250,6 @@ source "net/ieee80211/Kconfig" | |||
249 | config WIRELESS_EXT | 250 | config WIRELESS_EXT |
250 | bool | 251 | bool |
251 | 252 | ||
252 | source "net/netlabel/Kconfig" | ||
253 | |||
254 | config FIB_RULES | 253 | config FIB_RULES |
255 | bool | 254 | bool |
256 | 255 | ||
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 708e2e0371af..485e35c3b28b 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -1584,7 +1584,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
1584 | 1584 | ||
1585 | if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { | 1585 | if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { |
1586 | rt = atrtr_find(&usat->sat_addr); | 1586 | rt = atrtr_find(&usat->sat_addr); |
1587 | dev = rt->dev; | ||
1588 | } else { | 1587 | } else { |
1589 | struct atalk_addr at_hint; | 1588 | struct atalk_addr at_hint; |
1590 | 1589 | ||
@@ -1592,7 +1591,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
1592 | at_hint.s_net = at->src_net; | 1591 | at_hint.s_net = at->src_net; |
1593 | 1592 | ||
1594 | rt = atrtr_find(&at_hint); | 1593 | rt = atrtr_find(&at_hint); |
1595 | dev = rt->dev; | ||
1596 | } | 1594 | } |
1597 | if (!rt) | 1595 | if (!rt) |
1598 | return -ENETUNREACH; | 1596 | return -ENETUNREACH; |
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c index c0a4ae28fcfa..62f6ed1f2f98 100644 --- a/net/atm/atm_sysfs.c +++ b/net/atm/atm_sysfs.c | |||
@@ -141,7 +141,7 @@ static struct class atm_class = { | |||
141 | int atm_register_sysfs(struct atm_dev *adev) | 141 | int atm_register_sysfs(struct atm_dev *adev) |
142 | { | 142 | { |
143 | struct class_device *cdev = &adev->class_dev; | 143 | struct class_device *cdev = &adev->class_dev; |
144 | int i, err; | 144 | int i, j, err; |
145 | 145 | ||
146 | cdev->class = &atm_class; | 146 | cdev->class = &atm_class; |
147 | class_set_devdata(cdev, adev); | 147 | class_set_devdata(cdev, adev); |
@@ -151,10 +151,19 @@ int atm_register_sysfs(struct atm_dev *adev) | |||
151 | if (err < 0) | 151 | if (err < 0) |
152 | return err; | 152 | return err; |
153 | 153 | ||
154 | for (i = 0; atm_attrs[i]; i++) | 154 | for (i = 0; atm_attrs[i]; i++) { |
155 | class_device_create_file(cdev, atm_attrs[i]); | 155 | err = class_device_create_file(cdev, atm_attrs[i]); |
156 | if (err) | ||
157 | goto err_out; | ||
158 | } | ||
156 | 159 | ||
157 | return 0; | 160 | return 0; |
161 | |||
162 | err_out: | ||
163 | for (j = 0; j < i; j++) | ||
164 | class_device_remove_file(cdev, atm_attrs[j]); | ||
165 | class_device_del(cdev); | ||
166 | return err; | ||
158 | } | 167 | } |
159 | 168 | ||
160 | void atm_unregister_sysfs(struct atm_dev *adev) | 169 | void atm_unregister_sysfs(struct atm_dev *adev) |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 305a099b7477..67df99e2e5c8 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -48,41 +48,56 @@ | |||
48 | #define BT_DBG(D...) | 48 | #define BT_DBG(D...) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define VERSION "2.10" | 51 | #define VERSION "2.11" |
52 | 52 | ||
53 | /* Bluetooth sockets */ | 53 | /* Bluetooth sockets */ |
54 | #define BT_MAX_PROTO 8 | 54 | #define BT_MAX_PROTO 8 |
55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; | 55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; |
56 | static DEFINE_RWLOCK(bt_proto_lock); | ||
56 | 57 | ||
57 | int bt_sock_register(int proto, struct net_proto_family *ops) | 58 | int bt_sock_register(int proto, struct net_proto_family *ops) |
58 | { | 59 | { |
60 | int err = 0; | ||
61 | |||
59 | if (proto < 0 || proto >= BT_MAX_PROTO) | 62 | if (proto < 0 || proto >= BT_MAX_PROTO) |
60 | return -EINVAL; | 63 | return -EINVAL; |
61 | 64 | ||
65 | write_lock(&bt_proto_lock); | ||
66 | |||
62 | if (bt_proto[proto]) | 67 | if (bt_proto[proto]) |
63 | return -EEXIST; | 68 | err = -EEXIST; |
69 | else | ||
70 | bt_proto[proto] = ops; | ||
64 | 71 | ||
65 | bt_proto[proto] = ops; | 72 | write_unlock(&bt_proto_lock); |
66 | return 0; | 73 | |
74 | return err; | ||
67 | } | 75 | } |
68 | EXPORT_SYMBOL(bt_sock_register); | 76 | EXPORT_SYMBOL(bt_sock_register); |
69 | 77 | ||
70 | int bt_sock_unregister(int proto) | 78 | int bt_sock_unregister(int proto) |
71 | { | 79 | { |
80 | int err = 0; | ||
81 | |||
72 | if (proto < 0 || proto >= BT_MAX_PROTO) | 82 | if (proto < 0 || proto >= BT_MAX_PROTO) |
73 | return -EINVAL; | 83 | return -EINVAL; |
74 | 84 | ||
85 | write_lock(&bt_proto_lock); | ||
86 | |||
75 | if (!bt_proto[proto]) | 87 | if (!bt_proto[proto]) |
76 | return -ENOENT; | 88 | err = -ENOENT; |
89 | else | ||
90 | bt_proto[proto] = NULL; | ||
77 | 91 | ||
78 | bt_proto[proto] = NULL; | 92 | write_unlock(&bt_proto_lock); |
79 | return 0; | 93 | |
94 | return err; | ||
80 | } | 95 | } |
81 | EXPORT_SYMBOL(bt_sock_unregister); | 96 | EXPORT_SYMBOL(bt_sock_unregister); |
82 | 97 | ||
83 | static int bt_sock_create(struct socket *sock, int proto) | 98 | static int bt_sock_create(struct socket *sock, int proto) |
84 | { | 99 | { |
85 | int err = 0; | 100 | int err; |
86 | 101 | ||
87 | if (proto < 0 || proto >= BT_MAX_PROTO) | 102 | if (proto < 0 || proto >= BT_MAX_PROTO) |
88 | return -EINVAL; | 103 | return -EINVAL; |
@@ -92,11 +107,18 @@ static int bt_sock_create(struct socket *sock, int proto) | |||
92 | request_module("bt-proto-%d", proto); | 107 | request_module("bt-proto-%d", proto); |
93 | } | 108 | } |
94 | #endif | 109 | #endif |
110 | |||
95 | err = -EPROTONOSUPPORT; | 111 | err = -EPROTONOSUPPORT; |
112 | |||
113 | read_lock(&bt_proto_lock); | ||
114 | |||
96 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { | 115 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { |
97 | err = bt_proto[proto]->create(sock, proto); | 116 | err = bt_proto[proto]->create(sock, proto); |
98 | module_put(bt_proto[proto]->owner); | 117 | module_put(bt_proto[proto]->owner); |
99 | } | 118 | } |
119 | |||
120 | read_unlock(&bt_proto_lock); | ||
121 | |||
100 | return err; | 122 | return err; |
101 | } | 123 | } |
102 | 124 | ||
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 2312d050eeed..4d3424c2421c 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -528,12 +528,10 @@ static struct device *bnep_get_device(struct bnep_session *session) | |||
528 | return NULL; | 528 | return NULL; |
529 | 529 | ||
530 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 530 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
531 | if (!conn) | ||
532 | return NULL; | ||
533 | 531 | ||
534 | hci_dev_put(hdev); | 532 | hci_dev_put(hdev); |
535 | 533 | ||
536 | return &conn->dev; | 534 | return conn ? &conn->dev : NULL; |
537 | } | 535 | } |
538 | 536 | ||
539 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | 537 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) |
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 28c55835422a..5563db1bf526 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/ioctl.h> | 43 | #include <linux/ioctl.h> |
44 | #include <linux/file.h> | 44 | #include <linux/file.h> |
45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <linux/compat.h> | ||
46 | #include <net/sock.h> | 47 | #include <net/sock.h> |
47 | 48 | ||
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
@@ -146,24 +147,56 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
150 | #ifdef CONFIG_COMPAT | ||
151 | static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
152 | { | ||
153 | if (cmd == BNEPGETCONNLIST) { | ||
154 | struct bnep_connlist_req cl; | ||
155 | uint32_t uci; | ||
156 | int err; | ||
157 | |||
158 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
159 | get_user(uci, (u32 __user *) (arg + 4))) | ||
160 | return -EFAULT; | ||
161 | |||
162 | cl.ci = compat_ptr(uci); | ||
163 | |||
164 | if (cl.cnum <= 0) | ||
165 | return -EINVAL; | ||
166 | |||
167 | err = bnep_get_connlist(&cl); | ||
168 | |||
169 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
170 | err = -EFAULT; | ||
171 | |||
172 | return err; | ||
173 | } | ||
174 | |||
175 | return bnep_sock_ioctl(sock, cmd, arg); | ||
176 | } | ||
177 | #endif | ||
178 | |||
149 | static const struct proto_ops bnep_sock_ops = { | 179 | static const struct proto_ops bnep_sock_ops = { |
150 | .family = PF_BLUETOOTH, | 180 | .family = PF_BLUETOOTH, |
151 | .owner = THIS_MODULE, | 181 | .owner = THIS_MODULE, |
152 | .release = bnep_sock_release, | 182 | .release = bnep_sock_release, |
153 | .ioctl = bnep_sock_ioctl, | 183 | .ioctl = bnep_sock_ioctl, |
154 | .bind = sock_no_bind, | 184 | #ifdef CONFIG_COMPAT |
155 | .getname = sock_no_getname, | 185 | .compat_ioctl = bnep_sock_compat_ioctl, |
156 | .sendmsg = sock_no_sendmsg, | 186 | #endif |
157 | .recvmsg = sock_no_recvmsg, | 187 | .bind = sock_no_bind, |
158 | .poll = sock_no_poll, | 188 | .getname = sock_no_getname, |
159 | .listen = sock_no_listen, | 189 | .sendmsg = sock_no_sendmsg, |
160 | .shutdown = sock_no_shutdown, | 190 | .recvmsg = sock_no_recvmsg, |
161 | .setsockopt = sock_no_setsockopt, | 191 | .poll = sock_no_poll, |
162 | .getsockopt = sock_no_getsockopt, | 192 | .listen = sock_no_listen, |
163 | .connect = sock_no_connect, | 193 | .shutdown = sock_no_shutdown, |
164 | .socketpair = sock_no_socketpair, | 194 | .setsockopt = sock_no_setsockopt, |
165 | .accept = sock_no_accept, | 195 | .getsockopt = sock_no_getsockopt, |
166 | .mmap = sock_no_mmap | 196 | .connect = sock_no_connect, |
197 | .socketpair = sock_no_socketpair, | ||
198 | .accept = sock_no_accept, | ||
199 | .mmap = sock_no_mmap | ||
167 | }; | 200 | }; |
168 | 201 | ||
169 | static struct proto bnep_proto = { | 202 | static struct proto bnep_proto = { |
@@ -181,7 +214,7 @@ static int bnep_sock_create(struct socket *sock, int protocol) | |||
181 | if (sock->type != SOCK_RAW) | 214 | if (sock->type != SOCK_RAW) |
182 | return -ESOCKTNOSUPPORT; | 215 | return -ESOCKTNOSUPPORT; |
183 | 216 | ||
184 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1); | 217 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); |
185 | if (!sk) | 218 | if (!sk) |
186 | return -ENOMEM; | 219 | return -ENOMEM; |
187 | 220 | ||
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 10ad7fd91d83..53295d33dc5c 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/socket.h> | 34 | #include <linux/socket.h> |
35 | #include <linux/ioctl.h> | 35 | #include <linux/ioctl.h> |
36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
37 | #include <linux/compat.h> | ||
37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
38 | 39 | ||
39 | #include <linux/isdn/capilli.h> | 40 | #include <linux/isdn/capilli.h> |
@@ -137,11 +138,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
137 | return -EINVAL; | 138 | return -EINVAL; |
138 | } | 139 | } |
139 | 140 | ||
141 | #ifdef CONFIG_COMPAT | ||
142 | static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
143 | { | ||
144 | if (cmd == CMTPGETCONNLIST) { | ||
145 | struct cmtp_connlist_req cl; | ||
146 | uint32_t uci; | ||
147 | int err; | ||
148 | |||
149 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
150 | get_user(uci, (u32 __user *) (arg + 4))) | ||
151 | return -EFAULT; | ||
152 | |||
153 | cl.ci = compat_ptr(uci); | ||
154 | |||
155 | if (cl.cnum <= 0) | ||
156 | return -EINVAL; | ||
157 | |||
158 | err = cmtp_get_connlist(&cl); | ||
159 | |||
160 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
161 | err = -EFAULT; | ||
162 | |||
163 | return err; | ||
164 | } | ||
165 | |||
166 | return cmtp_sock_ioctl(sock, cmd, arg); | ||
167 | } | ||
168 | #endif | ||
169 | |||
140 | static const struct proto_ops cmtp_sock_ops = { | 170 | static const struct proto_ops cmtp_sock_ops = { |
141 | .family = PF_BLUETOOTH, | 171 | .family = PF_BLUETOOTH, |
142 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
143 | .release = cmtp_sock_release, | 173 | .release = cmtp_sock_release, |
144 | .ioctl = cmtp_sock_ioctl, | 174 | .ioctl = cmtp_sock_ioctl, |
175 | #ifdef CONFIG_COMPAT | ||
176 | .compat_ioctl = cmtp_sock_compat_ioctl, | ||
177 | #endif | ||
145 | .bind = sock_no_bind, | 178 | .bind = sock_no_bind, |
146 | .getname = sock_no_getname, | 179 | .getname = sock_no_getname, |
147 | .sendmsg = sock_no_sendmsg, | 180 | .sendmsg = sock_no_sendmsg, |
@@ -172,7 +205,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol) | |||
172 | if (sock->type != SOCK_RAW) | 205 | if (sock->type != SOCK_RAW) |
173 | return -ESOCKTNOSUPPORT; | 206 | return -ESOCKTNOSUPPORT; |
174 | 207 | ||
175 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1); | 208 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1); |
176 | if (!sk) | 209 | if (!sk) |
177 | return -ENOMEM; | 210 | return -ENOMEM; |
178 | 211 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 90e3a285a17e..6cd5711fa28a 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #define BT_DBG(D...) | 51 | #define BT_DBG(D...) |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | static void hci_acl_connect(struct hci_conn *conn) | 54 | void hci_acl_connect(struct hci_conn *conn) |
55 | { | 55 | { |
56 | struct hci_dev *hdev = conn->hdev; | 56 | struct hci_dev *hdev = conn->hdev; |
57 | struct inquiry_entry *ie; | 57 | struct inquiry_entry *ie; |
@@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn) | |||
63 | conn->out = 1; | 63 | conn->out = 1; |
64 | conn->link_mode = HCI_LM_MASTER; | 64 | conn->link_mode = HCI_LM_MASTER; |
65 | 65 | ||
66 | conn->attempt++; | ||
67 | |||
66 | memset(&cp, 0, sizeof(cp)); | 68 | memset(&cp, 0, sizeof(cp)); |
67 | bacpy(&cp.bdaddr, &conn->dst); | 69 | bacpy(&cp.bdaddr, &conn->dst); |
68 | cp.pscan_rep_mode = 0x02; | 70 | cp.pscan_rep_mode = 0x02; |
@@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn) | |||
80 | cp.role_switch = 0x01; | 82 | cp.role_switch = 0x01; |
81 | else | 83 | else |
82 | cp.role_switch = 0x00; | 84 | cp.role_switch = 0x00; |
83 | 85 | ||
84 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); | 86 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); |
85 | } | 87 | } |
86 | 88 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d43d0c890975..bb94e6da223c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -57,6 +57,7 @@ | |||
57 | static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) | 57 | static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) |
58 | { | 58 | { |
59 | __u8 status; | 59 | __u8 status; |
60 | struct hci_conn *pend; | ||
60 | 61 | ||
61 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 62 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
62 | 63 | ||
@@ -71,6 +72,15 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
71 | clear_bit(HCI_INQUIRY, &hdev->flags); | 72 | clear_bit(HCI_INQUIRY, &hdev->flags); |
72 | hci_req_complete(hdev, status); | 73 | hci_req_complete(hdev, status); |
73 | } | 74 | } |
75 | |||
76 | hci_dev_lock(hdev); | ||
77 | |||
78 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
79 | if (pend) | ||
80 | hci_acl_connect(pend); | ||
81 | |||
82 | hci_dev_unlock(hdev); | ||
83 | |||
74 | break; | 84 | break; |
75 | 85 | ||
76 | default: | 86 | default: |
@@ -414,9 +424,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
414 | 424 | ||
415 | if (status) { | 425 | if (status) { |
416 | if (conn && conn->state == BT_CONNECT) { | 426 | if (conn && conn->state == BT_CONNECT) { |
417 | conn->state = BT_CLOSED; | 427 | if (status != 0x0c || conn->attempt > 2) { |
418 | hci_proto_connect_cfm(conn, status); | 428 | conn->state = BT_CLOSED; |
419 | hci_conn_del(conn); | 429 | hci_proto_connect_cfm(conn, status); |
430 | hci_conn_del(conn); | ||
431 | } else | ||
432 | conn->state = BT_CONNECT2; | ||
420 | } | 433 | } |
421 | } else { | 434 | } else { |
422 | if (!conn) { | 435 | if (!conn) { |
@@ -562,11 +575,20 @@ static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status) | |||
562 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 575 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
563 | { | 576 | { |
564 | __u8 status = *((__u8 *) skb->data); | 577 | __u8 status = *((__u8 *) skb->data); |
578 | struct hci_conn *pend; | ||
565 | 579 | ||
566 | BT_DBG("%s status %d", hdev->name, status); | 580 | BT_DBG("%s status %d", hdev->name, status); |
567 | 581 | ||
568 | clear_bit(HCI_INQUIRY, &hdev->flags); | 582 | clear_bit(HCI_INQUIRY, &hdev->flags); |
569 | hci_req_complete(hdev, status); | 583 | hci_req_complete(hdev, status); |
584 | |||
585 | hci_dev_lock(hdev); | ||
586 | |||
587 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
588 | if (pend) | ||
589 | hci_acl_connect(pend); | ||
590 | |||
591 | hci_dev_unlock(hdev); | ||
570 | } | 592 | } |
571 | 593 | ||
572 | /* Inquiry Result */ | 594 | /* Inquiry Result */ |
@@ -728,7 +750,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
728 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 750 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
729 | { | 751 | { |
730 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; | 752 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; |
731 | struct hci_conn *conn; | 753 | struct hci_conn *conn, *pend; |
732 | 754 | ||
733 | BT_DBG("%s", hdev->name); | 755 | BT_DBG("%s", hdev->name); |
734 | 756 | ||
@@ -801,6 +823,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
801 | if (ev->status) | 823 | if (ev->status) |
802 | hci_conn_del(conn); | 824 | hci_conn_del(conn); |
803 | 825 | ||
826 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
827 | if (pend) | ||
828 | hci_acl_connect(pend); | ||
829 | |||
804 | hci_dev_unlock(hdev); | 830 | hci_dev_unlock(hdev); |
805 | } | 831 | } |
806 | 832 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 1a35d343e08a..711a085eca5b 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -120,10 +120,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
120 | if (!hci_test_bit(evt, &flt->event_mask)) | 120 | if (!hci_test_bit(evt, &flt->event_mask)) |
121 | continue; | 121 | continue; |
122 | 122 | ||
123 | if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && | 123 | if (flt->opcode && |
124 | flt->opcode != *(__u16 *)(skb->data + 3)) || | 124 | ((evt == HCI_EV_CMD_COMPLETE && |
125 | (evt == HCI_EV_CMD_STATUS && | 125 | flt->opcode != |
126 | flt->opcode != *(__u16 *)(skb->data + 4)))) | 126 | get_unaligned((__u16 *)(skb->data + 3))) || |
127 | (evt == HCI_EV_CMD_STATUS && | ||
128 | flt->opcode != | ||
129 | get_unaligned((__u16 *)(skb->data + 4))))) | ||
127 | continue; | 130 | continue; |
128 | } | 131 | } |
129 | 132 | ||
@@ -618,7 +621,7 @@ static int hci_sock_create(struct socket *sock, int protocol) | |||
618 | 621 | ||
619 | sock->ops = &hci_sock_ops; | 622 | sock->ops = &hci_sock_ops; |
620 | 623 | ||
621 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1); | 624 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1); |
622 | if (!sk) | 625 | if (!sk) |
623 | return -ENOMEM; | 626 | return -ENOMEM; |
624 | 627 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 989b22d9042e..3eeeb7a86e75 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -242,10 +242,14 @@ static void add_conn(void *data) | |||
242 | struct hci_conn *conn = data; | 242 | struct hci_conn *conn = data; |
243 | int i; | 243 | int i; |
244 | 244 | ||
245 | device_register(&conn->dev); | 245 | if (device_register(&conn->dev) < 0) { |
246 | BT_ERR("Failed to register connection device"); | ||
247 | return; | ||
248 | } | ||
246 | 249 | ||
247 | for (i = 0; conn_attrs[i]; i++) | 250 | for (i = 0; conn_attrs[i]; i++) |
248 | device_create_file(&conn->dev, conn_attrs[i]); | 251 | if (device_create_file(&conn->dev, conn_attrs[i]) < 0) |
252 | BT_ERR("Failed to create connection attribute"); | ||
249 | } | 253 | } |
250 | 254 | ||
251 | void hci_conn_add_sysfs(struct hci_conn *conn) | 255 | void hci_conn_add_sysfs(struct hci_conn *conn) |
@@ -255,7 +259,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
255 | 259 | ||
256 | BT_DBG("conn %p", conn); | 260 | BT_DBG("conn %p", conn); |
257 | 261 | ||
258 | conn->dev.parent = &hdev->dev; | 262 | conn->dev.bus = &bt_bus; |
263 | conn->dev.parent = &hdev->dev; | ||
264 | |||
259 | conn->dev.release = bt_release; | 265 | conn->dev.release = bt_release; |
260 | 266 | ||
261 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, | 267 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, |
@@ -295,11 +301,7 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
295 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 301 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); |
296 | 302 | ||
297 | dev->class = bt_class; | 303 | dev->class = bt_class; |
298 | 304 | dev->parent = hdev->parent; | |
299 | if (hdev->parent) | ||
300 | dev->parent = hdev->parent; | ||
301 | else | ||
302 | dev->parent = &bt_platform->dev; | ||
303 | 305 | ||
304 | strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); | 306 | strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); |
305 | 307 | ||
@@ -312,7 +314,8 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
312 | return err; | 314 | return err; |
313 | 315 | ||
314 | for (i = 0; bt_attrs[i]; i++) | 316 | for (i = 0; bt_attrs[i]; i++) |
315 | device_create_file(dev, bt_attrs[i]); | 317 | if (device_create_file(dev, bt_attrs[i]) < 0) |
318 | BT_ERR("Failed to create device attribute"); | ||
316 | 319 | ||
317 | return 0; | 320 | return 0; |
318 | } | 321 | } |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 03b5dadb4951..66782010f82c 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -507,14 +507,12 @@ static int hidp_session(void *arg) | |||
507 | 507 | ||
508 | hidp_del_timer(session); | 508 | hidp_del_timer(session); |
509 | 509 | ||
510 | if (intr_sk->sk_state != BT_CONNECTED) | 510 | fput(session->intr_sock->file); |
511 | wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ); | ||
512 | |||
513 | fput(session->ctrl_sock->file); | ||
514 | 511 | ||
515 | wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ); | 512 | wait_event_timeout(*(ctrl_sk->sk_sleep), |
513 | (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); | ||
516 | 514 | ||
517 | fput(session->intr_sock->file); | 515 | fput(session->ctrl_sock->file); |
518 | 516 | ||
519 | __hidp_unlink_session(session); | 517 | __hidp_unlink_session(session); |
520 | 518 | ||
@@ -541,12 +539,10 @@ static struct device *hidp_get_device(struct hidp_session *session) | |||
541 | return NULL; | 539 | return NULL; |
542 | 540 | ||
543 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 541 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
544 | if (!conn) | ||
545 | return NULL; | ||
546 | 542 | ||
547 | hci_dev_put(hdev); | 543 | hci_dev_put(hdev); |
548 | 544 | ||
549 | return &conn->dev; | 545 | return conn ? &conn->dev : NULL; |
550 | } | 546 | } |
551 | 547 | ||
552 | static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) | 548 | static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) |
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 099646e4e2ef..407fba43c1b9 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/ioctl.h> | 35 | #include <linux/ioctl.h> |
36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/compat.h> | ||
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
39 | 40 | ||
40 | #include "hidp.h" | 41 | #include "hidp.h" |
@@ -143,11 +144,88 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
143 | return -EINVAL; | 144 | return -EINVAL; |
144 | } | 145 | } |
145 | 146 | ||
147 | #ifdef CONFIG_COMPAT | ||
148 | struct compat_hidp_connadd_req { | ||
149 | int ctrl_sock; // Connected control socket | ||
150 | int intr_sock; // Connteted interrupt socket | ||
151 | __u16 parser; | ||
152 | __u16 rd_size; | ||
153 | compat_uptr_t rd_data; | ||
154 | __u8 country; | ||
155 | __u8 subclass; | ||
156 | __u16 vendor; | ||
157 | __u16 product; | ||
158 | __u16 version; | ||
159 | __u32 flags; | ||
160 | __u32 idle_to; | ||
161 | char name[128]; | ||
162 | }; | ||
163 | |||
164 | static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
165 | { | ||
166 | if (cmd == HIDPGETCONNLIST) { | ||
167 | struct hidp_connlist_req cl; | ||
168 | uint32_t uci; | ||
169 | int err; | ||
170 | |||
171 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
172 | get_user(uci, (u32 __user *) (arg + 4))) | ||
173 | return -EFAULT; | ||
174 | |||
175 | cl.ci = compat_ptr(uci); | ||
176 | |||
177 | if (cl.cnum <= 0) | ||
178 | return -EINVAL; | ||
179 | |||
180 | err = hidp_get_connlist(&cl); | ||
181 | |||
182 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
183 | err = -EFAULT; | ||
184 | |||
185 | return err; | ||
186 | } else if (cmd == HIDPCONNADD) { | ||
187 | struct compat_hidp_connadd_req ca; | ||
188 | struct hidp_connadd_req __user *uca; | ||
189 | |||
190 | uca = compat_alloc_user_space(sizeof(*uca)); | ||
191 | |||
192 | if (copy_from_user(&ca, (void *) arg, sizeof(ca))) | ||
193 | return -EFAULT; | ||
194 | |||
195 | if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || | ||
196 | put_user(ca.intr_sock, &uca->intr_sock) || | ||
197 | put_user(ca.parser, &uca->parser) || | ||
198 | put_user(ca.rd_size, &uca->parser) || | ||
199 | put_user(compat_ptr(ca.rd_data), &uca->rd_data) || | ||
200 | put_user(ca.country, &uca->country) || | ||
201 | put_user(ca.subclass, &uca->subclass) || | ||
202 | put_user(ca.vendor, &uca->vendor) || | ||
203 | put_user(ca.product, &uca->product) || | ||
204 | put_user(ca.version, &uca->version) || | ||
205 | put_user(ca.flags, &uca->flags) || | ||
206 | put_user(ca.idle_to, &uca->idle_to) || | ||
207 | copy_to_user(&uca->name[0], &ca.name[0], 128)) | ||
208 | return -EFAULT; | ||
209 | |||
210 | arg = (unsigned long) uca; | ||
211 | |||
212 | /* Fall through. We don't actually write back any _changes_ | ||
213 | to the structure anyway, so there's no need to copy back | ||
214 | into the original compat version */ | ||
215 | } | ||
216 | |||
217 | return hidp_sock_ioctl(sock, cmd, arg); | ||
218 | } | ||
219 | #endif | ||
220 | |||
146 | static const struct proto_ops hidp_sock_ops = { | 221 | static const struct proto_ops hidp_sock_ops = { |
147 | .family = PF_BLUETOOTH, | 222 | .family = PF_BLUETOOTH, |
148 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
149 | .release = hidp_sock_release, | 224 | .release = hidp_sock_release, |
150 | .ioctl = hidp_sock_ioctl, | 225 | .ioctl = hidp_sock_ioctl, |
226 | #ifdef CONFIG_COMPAT | ||
227 | .compat_ioctl = hidp_sock_compat_ioctl, | ||
228 | #endif | ||
151 | .bind = sock_no_bind, | 229 | .bind = sock_no_bind, |
152 | .getname = sock_no_getname, | 230 | .getname = sock_no_getname, |
153 | .sendmsg = sock_no_sendmsg, | 231 | .sendmsg = sock_no_sendmsg, |
@@ -178,7 +256,7 @@ static int hidp_sock_create(struct socket *sock, int protocol) | |||
178 | if (sock->type != SOCK_RAW) | 256 | if (sock->type != SOCK_RAW) |
179 | return -ESOCKTNOSUPPORT; | 257 | return -ESOCKTNOSUPPORT; |
180 | 258 | ||
181 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1); | 259 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1); |
182 | if (!sk) | 260 | if (!sk) |
183 | return -ENOMEM; | 261 | return -ENOMEM; |
184 | 262 | ||
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index d56f60b392ac..bbf78e6a7bc3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol) | |||
559 | 559 | ||
560 | sock->ops = &l2cap_sock_ops; | 560 | sock->ops = &l2cap_sock_ops; |
561 | 561 | ||
562 | sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL); | 562 | sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC); |
563 | if (!sk) | 563 | if (!sk) |
564 | return -ENOMEM; | 564 | return -ENOMEM; |
565 | 565 | ||
@@ -1353,12 +1353,12 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr) | |||
1353 | 1353 | ||
1354 | /* Configure output options and let the other side know | 1354 | /* Configure output options and let the other side know |
1355 | * which ones we don't like. */ | 1355 | * which ones we don't like. */ |
1356 | if (pi->conf_mtu < pi->omtu) { | 1356 | if (pi->conf_mtu < pi->omtu) |
1357 | l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); | ||
1358 | result = L2CAP_CONF_UNACCEPT; | 1357 | result = L2CAP_CONF_UNACCEPT; |
1359 | } else { | 1358 | else |
1360 | pi->omtu = pi->conf_mtu; | 1359 | pi->omtu = pi->conf_mtu; |
1361 | } | 1360 | |
1361 | l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); | ||
1362 | 1362 | ||
1363 | BT_DBG("sk %p result %d", sk, result); | 1363 | BT_DBG("sk %p result %d", sk, result); |
1364 | return result; | 1364 | return result; |
@@ -1533,6 +1533,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
1533 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) | 1533 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) |
1534 | return -ENOENT; | 1534 | return -ENOENT; |
1535 | 1535 | ||
1536 | if (sk->sk_state == BT_DISCONN) | ||
1537 | goto unlock; | ||
1538 | |||
1536 | l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); | 1539 | l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); |
1537 | 1540 | ||
1538 | if (flags & 0x0001) { | 1541 | if (flags & 0x0001) { |
@@ -2216,7 +2219,8 @@ static int __init l2cap_init(void) | |||
2216 | goto error; | 2219 | goto error; |
2217 | } | 2220 | } |
2218 | 2221 | ||
2219 | class_create_file(bt_class, &class_attr_l2cap); | 2222 | if (class_create_file(bt_class, &class_attr_l2cap) < 0) |
2223 | BT_ERR("Failed to create L2CAP info file"); | ||
2220 | 2224 | ||
2221 | BT_INFO("L2CAP ver %s", VERSION); | 2225 | BT_INFO("L2CAP ver %s", VERSION); |
2222 | BT_INFO("L2CAP socket layer initialized"); | 2226 | BT_INFO("L2CAP socket layer initialized"); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 468df3b953f6..ddc4e9d5963e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -2058,7 +2058,8 @@ static int __init rfcomm_init(void) | |||
2058 | 2058 | ||
2059 | kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); | 2059 | kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); |
2060 | 2060 | ||
2061 | class_create_file(bt_class, &class_attr_rfcomm_dlc); | 2061 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) |
2062 | BT_ERR("Failed to create RFCOMM info file"); | ||
2062 | 2063 | ||
2063 | rfcomm_init_sockets(); | 2064 | rfcomm_init_sockets(); |
2064 | 2065 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 220fee04e7f2..544d65b7baa7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -336,7 +336,8 @@ static int rfcomm_sock_create(struct socket *sock, int protocol) | |||
336 | 336 | ||
337 | sock->ops = &rfcomm_sock_ops; | 337 | sock->ops = &rfcomm_sock_ops; |
338 | 338 | ||
339 | if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL))) | 339 | sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC); |
340 | if (!sk) | ||
340 | return -ENOMEM; | 341 | return -ENOMEM; |
341 | 342 | ||
342 | rfcomm_sock_init(sk, NULL); | 343 | rfcomm_sock_init(sk, NULL); |
@@ -944,7 +945,8 @@ int __init rfcomm_init_sockets(void) | |||
944 | if (err < 0) | 945 | if (err < 0) |
945 | goto error; | 946 | goto error; |
946 | 947 | ||
947 | class_create_file(bt_class, &class_attr_rfcomm); | 948 | if (class_create_file(bt_class, &class_attr_rfcomm) < 0) |
949 | BT_ERR("Failed to create RFCOMM info file"); | ||
948 | 950 | ||
949 | BT_INFO("RFCOMM socket layer initialized"); | 951 | BT_INFO("RFCOMM socket layer initialized"); |
950 | 952 | ||
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 1958ad1b8541..1fb5d42f37ae 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -172,12 +172,10 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | |||
172 | return NULL; | 172 | return NULL; |
173 | 173 | ||
174 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | 174 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); |
175 | if (!conn) | ||
176 | return NULL; | ||
177 | 175 | ||
178 | hci_dev_put(hdev); | 176 | hci_dev_put(hdev); |
179 | 177 | ||
180 | return &conn->dev; | 178 | return conn ? &conn->dev : NULL; |
181 | } | 179 | } |
182 | 180 | ||
183 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 181 | 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) | |||
767 | 765 | ||
768 | BT_DBG("tty %p termios %p", tty, old); | 766 | BT_DBG("tty %p termios %p", tty, old); |
769 | 767 | ||
768 | if (!dev || !dev->dlc || !dev->dlc->session) | ||
769 | return; | ||
770 | |||
770 | /* Handle turning off CRTSCTS */ | 771 | /* Handle turning off CRTSCTS */ |
771 | if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) | 772 | if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) |
772 | BT_DBG("Turning off CRTSCTS unsupported"); | 773 | BT_DBG("Turning off CRTSCTS unsupported"); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 7714a2ec3854..5d13d4f31753 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -452,7 +452,8 @@ static int sco_sock_create(struct socket *sock, int protocol) | |||
452 | 452 | ||
453 | sock->ops = &sco_sock_ops; | 453 | sock->ops = &sco_sock_ops; |
454 | 454 | ||
455 | if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL))) | 455 | sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC); |
456 | if (!sk) | ||
456 | return -ENOMEM; | 457 | return -ENOMEM; |
457 | 458 | ||
458 | sco_sock_init(sk, NULL); | 459 | sco_sock_init(sk, NULL); |
@@ -967,7 +968,8 @@ static int __init sco_init(void) | |||
967 | goto error; | 968 | goto error; |
968 | } | 969 | } |
969 | 970 | ||
970 | class_create_file(bt_class, &class_attr_sco); | 971 | if (class_create_file(bt_class, &class_attr_sco) < 0) |
972 | BT_ERR("Failed to create SCO info file"); | ||
971 | 973 | ||
972 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | 974 | BT_INFO("SCO (Voice Link) ver %s", VERSION); |
973 | BT_INFO("SCO socket layer initialized"); | 975 | BT_INFO("SCO socket layer initialized"); |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 3a73b8c94271..d9f04864d15d 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -128,7 +128,10 @@ void br_fdb_cleanup(unsigned long _data) | |||
128 | mod_timer(&br->gc_timer, jiffies + HZ/10); | 128 | mod_timer(&br->gc_timer, jiffies + HZ/10); |
129 | } | 129 | } |
130 | 130 | ||
131 | void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p) | 131 | |
132 | void br_fdb_delete_by_port(struct net_bridge *br, | ||
133 | const struct net_bridge_port *p, | ||
134 | int do_all) | ||
132 | { | 135 | { |
133 | int i; | 136 | int i; |
134 | 137 | ||
@@ -142,6 +145,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p) | |||
142 | if (f->dst != p) | 145 | if (f->dst != p) |
143 | continue; | 146 | continue; |
144 | 147 | ||
148 | if (f->is_static && !do_all) | ||
149 | continue; | ||
145 | /* | 150 | /* |
146 | * if multiple ports all have the same device address | 151 | * if multiple ports all have the same device address |
147 | * then when one port is deleted, assign | 152 | * then when one port is deleted, assign |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b1211d5342f6..f753c40c11d2 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p) | |||
163 | br_stp_disable_port(p); | 163 | br_stp_disable_port(p); |
164 | spin_unlock_bh(&br->lock); | 164 | spin_unlock_bh(&br->lock); |
165 | 165 | ||
166 | br_fdb_delete_by_port(br, p); | 166 | br_fdb_delete_by_port(br, p, 1); |
167 | 167 | ||
168 | list_del_rcu(&p->list); | 168 | list_del_rcu(&p->list); |
169 | 169 | ||
@@ -448,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
448 | 448 | ||
449 | return 0; | 449 | return 0; |
450 | err2: | 450 | err2: |
451 | br_fdb_delete_by_port(br, p); | 451 | br_fdb_delete_by_port(br, p, 1); |
452 | err1: | 452 | err1: |
453 | kobject_del(&p->kobj); | 453 | kobject_del(&p->kobj); |
454 | err0: | 454 | err0: |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c491fb2f280e..74258d86f256 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -143,7 +143,7 @@ extern void br_fdb_changeaddr(struct net_bridge_port *p, | |||
143 | const unsigned char *newaddr); | 143 | const unsigned char *newaddr); |
144 | extern void br_fdb_cleanup(unsigned long arg); | 144 | extern void br_fdb_cleanup(unsigned long arg); |
145 | extern void br_fdb_delete_by_port(struct net_bridge *br, | 145 | extern void br_fdb_delete_by_port(struct net_bridge *br, |
146 | struct net_bridge_port *p); | 146 | const struct net_bridge_port *p, int do_all); |
147 | extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, | 147 | extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, |
148 | const unsigned char *addr); | 148 | const unsigned char *addr); |
149 | extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, | 149 | extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 14cd025079af..d294224592db 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -113,6 +113,8 @@ void br_stp_disable_port(struct net_bridge_port *p) | |||
113 | del_timer(&p->forward_delay_timer); | 113 | del_timer(&p->forward_delay_timer); |
114 | del_timer(&p->hold_timer); | 114 | del_timer(&p->hold_timer); |
115 | 115 | ||
116 | br_fdb_delete_by_port(br, p, 0); | ||
117 | |||
116 | br_configuration_update(br); | 118 | br_configuration_update(br); |
117 | 119 | ||
118 | br_port_state_selection(br); | 120 | br_port_state_selection(br); |
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index 96bcb2ff59ab..de9d1a9473f2 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c | |||
@@ -376,7 +376,7 @@ int br_sysfs_addbr(struct net_device *dev) | |||
376 | 376 | ||
377 | err = sysfs_create_bin_file(brobj, &bridge_forward); | 377 | err = sysfs_create_bin_file(brobj, &bridge_forward); |
378 | if (err) { | 378 | if (err) { |
379 | pr_info("%s: can't create attribue file %s/%s\n", | 379 | pr_info("%s: can't create attribute file %s/%s\n", |
380 | __FUNCTION__, dev->name, bridge_forward.attr.name); | 380 | __FUNCTION__, dev->name, bridge_forward.attr.name); |
381 | goto out2; | 381 | goto out2; |
382 | } | 382 | } |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3df55b2bd91d..9f85666f29f7 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -86,7 +86,7 @@ static inline int ebt_do_match (struct ebt_entry_match *m, | |||
86 | static inline int ebt_dev_check(char *entry, const struct net_device *device) | 86 | static inline int ebt_dev_check(char *entry, const struct net_device *device) |
87 | { | 87 | { |
88 | int i = 0; | 88 | int i = 0; |
89 | char *devname = device->name; | 89 | const char *devname = device->name; |
90 | 90 | ||
91 | if (*entry == '\0') | 91 | if (*entry == '\0') |
92 | return 0; | 92 | return 0; |
diff --git a/net/compat.c b/net/compat.c index d5d69fa15d07..52d32f1bc728 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -285,8 +285,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) | |||
285 | 285 | ||
286 | if (i > 0) { | 286 | if (i > 0) { |
287 | int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); | 287 | int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); |
288 | if (!err) | 288 | err = put_user(SOL_SOCKET, &cm->cmsg_level); |
289 | err = put_user(SOL_SOCKET, &cm->cmsg_level); | ||
290 | if (!err) | 289 | if (!err) |
291 | err = put_user(SCM_RIGHTS, &cm->cmsg_type); | 290 | err = put_user(SCM_RIGHTS, &cm->cmsg_type); |
292 | if (!err) | 291 | if (!err) |
diff --git a/net/core/dev.c b/net/core/dev.c index 4d891beab138..81c426adcd1e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3502,8 +3502,6 @@ static int __init net_dev_init(void) | |||
3502 | 3502 | ||
3503 | BUG_ON(!dev_boot_phase); | 3503 | BUG_ON(!dev_boot_phase); |
3504 | 3504 | ||
3505 | net_random_init(); | ||
3506 | |||
3507 | if (dev_proc_init()) | 3505 | if (dev_proc_init()) |
3508 | goto out; | 3506 | goto out; |
3509 | 3507 | ||
diff --git a/net/core/flow.c b/net/core/flow.c index f23e7e386543..b16d31ae5e54 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsigned long arg) | |||
85 | add_timer(&flow_hash_rnd_timer); | 85 | add_timer(&flow_hash_rnd_timer); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void flow_entry_kill(int cpu, struct flow_cache_entry *fle) | ||
89 | { | ||
90 | if (fle->object) | ||
91 | atomic_dec(fle->object_ref); | ||
92 | kmem_cache_free(flow_cachep, fle); | ||
93 | flow_count(cpu)--; | ||
94 | } | ||
95 | |||
88 | static void __flow_cache_shrink(int cpu, int shrink_to) | 96 | static void __flow_cache_shrink(int cpu, int shrink_to) |
89 | { | 97 | { |
90 | struct flow_cache_entry *fle, **flp; | 98 | struct flow_cache_entry *fle, **flp; |
@@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, int shrink_to) | |||
100 | } | 108 | } |
101 | while ((fle = *flp) != NULL) { | 109 | while ((fle = *flp) != NULL) { |
102 | *flp = fle->next; | 110 | *flp = fle->next; |
103 | if (fle->object) | 111 | flow_entry_kill(cpu, fle); |
104 | atomic_dec(fle->object_ref); | ||
105 | kmem_cache_free(flow_cachep, fle); | ||
106 | flow_count(cpu)--; | ||
107 | } | 112 | } |
108 | } | 113 | } |
109 | } | 114 | } |
@@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | |||
220 | 225 | ||
221 | nocache: | 226 | nocache: |
222 | { | 227 | { |
228 | int err; | ||
223 | void *obj; | 229 | void *obj; |
224 | atomic_t *obj_ref; | 230 | atomic_t *obj_ref; |
225 | 231 | ||
226 | resolver(key, family, dir, &obj, &obj_ref); | 232 | err = resolver(key, family, dir, &obj, &obj_ref); |
227 | 233 | ||
228 | if (fle) { | 234 | if (fle) { |
229 | fle->genid = atomic_read(&flow_cache_genid); | 235 | if (err) { |
230 | 236 | /* Force security policy check on next lookup */ | |
231 | if (fle->object) | 237 | *head = fle->next; |
232 | atomic_dec(fle->object_ref); | 238 | flow_entry_kill(cpu, fle); |
233 | 239 | } else { | |
234 | fle->object = obj; | 240 | fle->genid = atomic_read(&flow_cache_genid); |
235 | fle->object_ref = obj_ref; | 241 | |
236 | if (obj) | 242 | if (fle->object) |
237 | atomic_inc(fle->object_ref); | 243 | atomic_dec(fle->object_ref); |
244 | |||
245 | fle->object = obj; | ||
246 | fle->object_ref = obj_ref; | ||
247 | if (obj) | ||
248 | atomic_inc(fle->object_ref); | ||
249 | } | ||
238 | } | 250 | } |
239 | local_bh_enable(); | 251 | local_bh_enable(); |
240 | 252 | ||
253 | if (err) | ||
254 | obj = ERR_PTR(err); | ||
241 | return obj; | 255 | return obj; |
242 | } | 256 | } |
243 | } | 257 | } |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index ead5920c26d6..6589adb14cbf 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -335,13 +335,19 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | |||
335 | memcpy(skb->data, msg, len); | 335 | memcpy(skb->data, msg, len); |
336 | skb->len += len; | 336 | skb->len += len; |
337 | 337 | ||
338 | udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); | 338 | skb->h.uh = udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); |
339 | udph->source = htons(np->local_port); | 339 | udph->source = htons(np->local_port); |
340 | udph->dest = htons(np->remote_port); | 340 | udph->dest = htons(np->remote_port); |
341 | udph->len = htons(udp_len); | 341 | udph->len = htons(udp_len); |
342 | udph->check = 0; | 342 | udph->check = 0; |
343 | udph->check = csum_tcpudp_magic(htonl(np->local_ip), | ||
344 | htonl(np->remote_ip), | ||
345 | udp_len, IPPROTO_UDP, | ||
346 | csum_partial((unsigned char *)udph, udp_len, 0)); | ||
347 | if (udph->check == 0) | ||
348 | udph->check = -1; | ||
343 | 349 | ||
344 | iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); | 350 | skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); |
345 | 351 | ||
346 | /* iph->version = 4; iph->ihl = 5; */ | 352 | /* iph->version = 4; iph->ihl = 5; */ |
347 | put_unaligned(0x45, (unsigned char *)iph); | 353 | put_unaligned(0x45, (unsigned char *)iph); |
@@ -357,8 +363,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | |||
357 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); | 363 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); |
358 | 364 | ||
359 | eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); | 365 | eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); |
360 | 366 | skb->mac.raw = skb->data; | |
361 | eth->h_proto = htons(ETH_P_IP); | 367 | skb->protocol = eth->h_proto = htons(ETH_P_IP); |
362 | memcpy(eth->h_source, np->local_mac, 6); | 368 | memcpy(eth->h_source, np->local_mac, 6); |
363 | memcpy(eth->h_dest, np->remote_mac, 6); | 369 | memcpy(eth->h_dest, np->remote_mac, 6); |
364 | 370 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index dd023fd28304..733d86d0a4fb 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -2304,6 +2304,12 @@ static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) | |||
2304 | *mpls |= MPLS_STACK_BOTTOM; | 2304 | *mpls |= MPLS_STACK_BOTTOM; |
2305 | } | 2305 | } |
2306 | 2306 | ||
2307 | static inline __be16 build_tci(unsigned int id, unsigned int cfi, | ||
2308 | unsigned int prio) | ||
2309 | { | ||
2310 | return htons(id | (cfi << 12) | (prio << 13)); | ||
2311 | } | ||
2312 | |||
2307 | static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | 2313 | static struct sk_buff *fill_packet_ipv4(struct net_device *odev, |
2308 | struct pktgen_dev *pkt_dev) | 2314 | struct pktgen_dev *pkt_dev) |
2309 | { | 2315 | { |
@@ -2353,16 +2359,16 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2353 | if (pkt_dev->vlan_id != 0xffff) { | 2359 | if (pkt_dev->vlan_id != 0xffff) { |
2354 | if(pkt_dev->svlan_id != 0xffff) { | 2360 | if(pkt_dev->svlan_id != 0xffff) { |
2355 | svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); | 2361 | svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); |
2356 | *svlan_tci = htons(pkt_dev->svlan_id); | 2362 | *svlan_tci = build_tci(pkt_dev->svlan_id, |
2357 | *svlan_tci |= pkt_dev->svlan_p << 5; | 2363 | pkt_dev->svlan_cfi, |
2358 | *svlan_tci |= pkt_dev->svlan_cfi << 4; | 2364 | pkt_dev->svlan_p); |
2359 | svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); | 2365 | svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); |
2360 | *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); | 2366 | *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); |
2361 | } | 2367 | } |
2362 | vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); | 2368 | vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); |
2363 | *vlan_tci = htons(pkt_dev->vlan_id); | 2369 | *vlan_tci = build_tci(pkt_dev->vlan_id, |
2364 | *vlan_tci |= pkt_dev->vlan_p << 5; | 2370 | pkt_dev->vlan_cfi, |
2365 | *vlan_tci |= pkt_dev->vlan_cfi << 4; | 2371 | pkt_dev->vlan_p); |
2366 | vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); | 2372 | vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); |
2367 | *vlan_encapsulated_proto = __constant_htons(ETH_P_IP); | 2373 | *vlan_encapsulated_proto = __constant_htons(ETH_P_IP); |
2368 | } | 2374 | } |
@@ -2689,16 +2695,16 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2689 | if (pkt_dev->vlan_id != 0xffff) { | 2695 | if (pkt_dev->vlan_id != 0xffff) { |
2690 | if(pkt_dev->svlan_id != 0xffff) { | 2696 | if(pkt_dev->svlan_id != 0xffff) { |
2691 | svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); | 2697 | svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); |
2692 | *svlan_tci = htons(pkt_dev->svlan_id); | 2698 | *svlan_tci = build_tci(pkt_dev->svlan_id, |
2693 | *svlan_tci |= pkt_dev->svlan_p << 5; | 2699 | pkt_dev->svlan_cfi, |
2694 | *svlan_tci |= pkt_dev->svlan_cfi << 4; | 2700 | pkt_dev->svlan_p); |
2695 | svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); | 2701 | svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); |
2696 | *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); | 2702 | *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); |
2697 | } | 2703 | } |
2698 | vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); | 2704 | vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); |
2699 | *vlan_tci = htons(pkt_dev->vlan_id); | 2705 | *vlan_tci = build_tci(pkt_dev->vlan_id, |
2700 | *vlan_tci |= pkt_dev->vlan_p << 5; | 2706 | pkt_dev->vlan_cfi, |
2701 | *vlan_tci |= pkt_dev->vlan_cfi << 4; | 2707 | pkt_dev->vlan_p); |
2702 | vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); | 2708 | vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); |
2703 | *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6); | 2709 | *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6); |
2704 | } | 2710 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 221e4038216b..02f3c7947898 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -602,7 +602,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
602 | goto errout; | 602 | goto errout; |
603 | } | 603 | } |
604 | 604 | ||
605 | err = rtnl_unicast(skb, NETLINK_CB(skb).pid); | 605 | err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); |
606 | errout: | 606 | errout: |
607 | kfree(iw_buf); | 607 | kfree(iw_buf); |
608 | dev_put(dev); | 608 | dev_put(dev); |
diff --git a/net/core/scm.c b/net/core/scm.c index 649d01ef35b6..271cf060ef8c 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -245,8 +245,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
245 | if (i > 0) | 245 | if (i > 0) |
246 | { | 246 | { |
247 | int cmlen = CMSG_LEN(i*sizeof(int)); | 247 | int cmlen = CMSG_LEN(i*sizeof(int)); |
248 | if (!err) | 248 | err = put_user(SOL_SOCKET, &cm->cmsg_level); |
249 | err = put_user(SOL_SOCKET, &cm->cmsg_level); | ||
250 | if (!err) | 249 | if (!err) |
251 | err = put_user(SCM_RIGHTS, &cm->cmsg_type); | 250 | err = put_user(SCM_RIGHTS, &cm->cmsg_type); |
252 | if (!err) | 251 | if (!err) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3c23760c5827..b8b106358040 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -639,6 +639,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | |||
639 | n->csum = skb->csum; | 639 | n->csum = skb->csum; |
640 | n->ip_summed = skb->ip_summed; | 640 | n->ip_summed = skb->ip_summed; |
641 | 641 | ||
642 | n->truesize += skb->data_len; | ||
642 | n->data_len = skb->data_len; | 643 | n->data_len = skb->data_len; |
643 | n->len = skb->len; | 644 | n->len = skb->len; |
644 | 645 | ||
@@ -1946,7 +1947,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
1946 | do { | 1947 | do { |
1947 | struct sk_buff *nskb; | 1948 | struct sk_buff *nskb; |
1948 | skb_frag_t *frag; | 1949 | skb_frag_t *frag; |
1949 | int hsize, nsize; | 1950 | int hsize; |
1950 | int k; | 1951 | int k; |
1951 | int size; | 1952 | int size; |
1952 | 1953 | ||
@@ -1957,11 +1958,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
1957 | hsize = skb_headlen(skb) - offset; | 1958 | hsize = skb_headlen(skb) - offset; |
1958 | if (hsize < 0) | 1959 | if (hsize < 0) |
1959 | hsize = 0; | 1960 | hsize = 0; |
1960 | nsize = hsize + doffset; | 1961 | if (hsize > len || !sg) |
1961 | if (nsize > len + doffset || !sg) | 1962 | hsize = len; |
1962 | nsize = len + doffset; | ||
1963 | 1963 | ||
1964 | nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); | 1964 | nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); |
1965 | if (unlikely(!nskb)) | 1965 | if (unlikely(!nskb)) |
1966 | goto err; | 1966 | goto err; |
1967 | 1967 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index b77e155cbe6c..ee6cd2541d35 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -823,7 +823,7 @@ static void inline sock_lock_init(struct sock *sk) | |||
823 | af_family_slock_key_strings[sk->sk_family]); | 823 | af_family_slock_key_strings[sk->sk_family]); |
824 | lockdep_init_map(&sk->sk_lock.dep_map, | 824 | lockdep_init_map(&sk->sk_lock.dep_map, |
825 | af_family_key_strings[sk->sk_family], | 825 | af_family_key_strings[sk->sk_family], |
826 | af_family_keys + sk->sk_family); | 826 | af_family_keys + sk->sk_family, 0); |
827 | } | 827 | } |
828 | 828 | ||
829 | /** | 829 | /** |
@@ -1160,7 +1160,7 @@ static struct sk_buff *sock_alloc_send_pskb(struct sock *sk, | |||
1160 | goto failure; | 1160 | goto failure; |
1161 | 1161 | ||
1162 | if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { | 1162 | if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { |
1163 | skb = alloc_skb(header_len, sk->sk_allocation); | 1163 | skb = alloc_skb(header_len, gfp_mask); |
1164 | if (skb) { | 1164 | if (skb) { |
1165 | int npages; | 1165 | int npages; |
1166 | int i; | 1166 | int i; |
diff --git a/net/core/utils.c b/net/core/utils.c index 94c5d761c830..d93fe64f6693 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -30,119 +30,6 @@ | |||
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | 32 | ||
33 | /* | ||
34 | This is a maximally equidistributed combined Tausworthe generator | ||
35 | based on code from GNU Scientific Library 1.5 (30 Jun 2004) | ||
36 | |||
37 | x_n = (s1_n ^ s2_n ^ s3_n) | ||
38 | |||
39 | s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) | ||
40 | s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25)) | ||
41 | s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11)) | ||
42 | |||
43 | The period of this generator is about 2^88. | ||
44 | |||
45 | From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe | ||
46 | Generators", Mathematics of Computation, 65, 213 (1996), 203--213. | ||
47 | |||
48 | This is available on the net from L'Ecuyer's home page, | ||
49 | |||
50 | http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps | ||
51 | ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps | ||
52 | |||
53 | There is an erratum in the paper "Tables of Maximally | ||
54 | Equidistributed Combined LFSR Generators", Mathematics of | ||
55 | Computation, 68, 225 (1999), 261--269: | ||
56 | http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps | ||
57 | |||
58 | ... the k_j most significant bits of z_j must be non- | ||
59 | zero, for each j. (Note: this restriction also applies to the | ||
60 | computer code given in [4], but was mistakenly not mentioned in | ||
61 | that paper.) | ||
62 | |||
63 | This affects the seeding procedure by imposing the requirement | ||
64 | s1 > 1, s2 > 7, s3 > 15. | ||
65 | |||
66 | */ | ||
67 | struct nrnd_state { | ||
68 | u32 s1, s2, s3; | ||
69 | }; | ||
70 | |||
71 | static DEFINE_PER_CPU(struct nrnd_state, net_rand_state); | ||
72 | |||
73 | static u32 __net_random(struct nrnd_state *state) | ||
74 | { | ||
75 | #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) | ||
76 | |||
77 | state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); | ||
78 | state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); | ||
79 | state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); | ||
80 | |||
81 | return (state->s1 ^ state->s2 ^ state->s3); | ||
82 | } | ||
83 | |||
84 | static void __net_srandom(struct nrnd_state *state, unsigned long s) | ||
85 | { | ||
86 | if (s == 0) | ||
87 | s = 1; /* default seed is 1 */ | ||
88 | |||
89 | #define LCG(n) (69069 * n) | ||
90 | state->s1 = LCG(s); | ||
91 | state->s2 = LCG(state->s1); | ||
92 | state->s3 = LCG(state->s2); | ||
93 | |||
94 | /* "warm it up" */ | ||
95 | __net_random(state); | ||
96 | __net_random(state); | ||
97 | __net_random(state); | ||
98 | __net_random(state); | ||
99 | __net_random(state); | ||
100 | __net_random(state); | ||
101 | } | ||
102 | |||
103 | |||
104 | unsigned long net_random(void) | ||
105 | { | ||
106 | unsigned long r; | ||
107 | struct nrnd_state *state = &get_cpu_var(net_rand_state); | ||
108 | r = __net_random(state); | ||
109 | put_cpu_var(state); | ||
110 | return r; | ||
111 | } | ||
112 | |||
113 | |||
114 | void net_srandom(unsigned long entropy) | ||
115 | { | ||
116 | struct nrnd_state *state = &get_cpu_var(net_rand_state); | ||
117 | __net_srandom(state, state->s1^entropy); | ||
118 | put_cpu_var(state); | ||
119 | } | ||
120 | |||
121 | void __init net_random_init(void) | ||
122 | { | ||
123 | int i; | ||
124 | |||
125 | for_each_possible_cpu(i) { | ||
126 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | ||
127 | __net_srandom(state, i+jiffies); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static int net_random_reseed(void) | ||
132 | { | ||
133 | int i; | ||
134 | unsigned long seed; | ||
135 | |||
136 | for_each_possible_cpu(i) { | ||
137 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | ||
138 | |||
139 | get_random_bytes(&seed, sizeof(seed)); | ||
140 | __net_srandom(state, seed); | ||
141 | } | ||
142 | return 0; | ||
143 | } | ||
144 | late_initcall(net_random_reseed); | ||
145 | |||
146 | int net_msg_cost = 5*HZ; | 33 | int net_msg_cost = 5*HZ; |
147 | int net_msg_burst = 10; | 34 | int net_msg_burst = 10; |
148 | 35 | ||
@@ -153,10 +40,7 @@ int net_ratelimit(void) | |||
153 | { | 40 | { |
154 | return __printk_ratelimit(net_msg_cost, net_msg_burst); | 41 | return __printk_ratelimit(net_msg_cost, net_msg_burst); |
155 | } | 42 | } |
156 | |||
157 | EXPORT_SYMBOL(net_random); | ||
158 | EXPORT_SYMBOL(net_ratelimit); | 43 | EXPORT_SYMBOL(net_ratelimit); |
159 | EXPORT_SYMBOL(net_srandom); | ||
160 | 44 | ||
161 | /* | 45 | /* |
162 | * Convert an ASCII string to binary IP. | 46 | * Convert an ASCII string to binary IP. |
diff --git a/net/core/wireless.c b/net/core/wireless.c index ffff0da46c6e..cb1b8728d7ee 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device * dev, | |||
748 | int extra_size; | 748 | int extra_size; |
749 | int user_length = 0; | 749 | int user_length = 0; |
750 | int err; | 750 | int err; |
751 | int essid_compat = 0; | ||
751 | 752 | ||
752 | /* Calculate space needed by arguments. Always allocate | 753 | /* Calculate space needed by arguments. Always allocate |
753 | * for max space. Easier, and won't last long... */ | 754 | * for max space. Easier, and won't last long... */ |
754 | extra_size = descr->max_tokens * descr->token_size; | 755 | extra_size = descr->max_tokens * descr->token_size; |
755 | 756 | ||
757 | /* Check need for ESSID compatibility for WE < 21 */ | ||
758 | switch (cmd) { | ||
759 | case SIOCSIWESSID: | ||
760 | case SIOCGIWESSID: | ||
761 | case SIOCSIWNICKN: | ||
762 | case SIOCGIWNICKN: | ||
763 | if (iwr->u.data.length == descr->max_tokens + 1) | ||
764 | essid_compat = 1; | ||
765 | else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) { | ||
766 | char essid[IW_ESSID_MAX_SIZE + 1]; | ||
767 | |||
768 | err = copy_from_user(essid, iwr->u.data.pointer, | ||
769 | iwr->u.data.length * | ||
770 | descr->token_size); | ||
771 | if (err) | ||
772 | return -EFAULT; | ||
773 | |||
774 | if (essid[iwr->u.data.length - 1] == '\0') | ||
775 | essid_compat = 1; | ||
776 | } | ||
777 | break; | ||
778 | default: | ||
779 | break; | ||
780 | } | ||
781 | |||
782 | iwr->u.data.length -= essid_compat; | ||
783 | |||
756 | /* Check what user space is giving us */ | 784 | /* Check what user space is giving us */ |
757 | if(IW_IS_SET(cmd)) { | 785 | if(IW_IS_SET(cmd)) { |
758 | /* Check NULL pointer */ | 786 | /* Check NULL pointer */ |
@@ -795,7 +823,8 @@ static int ioctl_standard_call(struct net_device * dev, | |||
795 | #endif /* WE_IOCTL_DEBUG */ | 823 | #endif /* WE_IOCTL_DEBUG */ |
796 | 824 | ||
797 | /* Create the kernel buffer */ | 825 | /* Create the kernel buffer */ |
798 | extra = kmalloc(extra_size, GFP_KERNEL); | 826 | /* kzalloc ensures NULL-termination for essid_compat */ |
827 | extra = kzalloc(extra_size, GFP_KERNEL); | ||
799 | if (extra == NULL) { | 828 | if (extra == NULL) { |
800 | return -ENOMEM; | 829 | return -ENOMEM; |
801 | } | 830 | } |
@@ -819,6 +848,8 @@ static int ioctl_standard_call(struct net_device * dev, | |||
819 | /* Call the handler */ | 848 | /* Call the handler */ |
820 | ret = handler(dev, &info, &(iwr->u), extra); | 849 | ret = handler(dev, &info, &(iwr->u), extra); |
821 | 850 | ||
851 | iwr->u.data.length += essid_compat; | ||
852 | |||
822 | /* If we have something to return to the user */ | 853 | /* If we have something to return to the user */ |
823 | if (!ret && IW_IS_GET(cmd)) { | 854 | if (!ret && IW_IS_GET(cmd)) { |
824 | /* Check if there is enough buffer up there */ | 855 | /* Check if there is enough buffer up there */ |
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index e2a095d0fd80..ef8919cca74b 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig | |||
@@ -4,15 +4,15 @@ menu "DCCP Configuration (EXPERIMENTAL)" | |||
4 | config IP_DCCP | 4 | config IP_DCCP |
5 | tristate "The DCCP Protocol (EXPERIMENTAL)" | 5 | tristate "The DCCP Protocol (EXPERIMENTAL)" |
6 | ---help--- | 6 | ---help--- |
7 | Datagram Congestion Control Protocol | 7 | Datagram Congestion Control Protocol (RFC 4340) |
8 | 8 | ||
9 | From draft-ietf-dccp-spec-11 <http://www.icir.org/kohler/dcp/draft-ietf-dccp-spec-11.txt>. | 9 | From http://www.ietf.org/rfc/rfc4340.txt: |
10 | 10 | ||
11 | The Datagram Congestion Control Protocol (DCCP) is a transport | 11 | The Datagram Congestion Control Protocol (DCCP) is a transport |
12 | protocol that implements bidirectional, unicast connections of | 12 | protocol that implements bidirectional, unicast connections of |
13 | congestion-controlled, unreliable datagrams. It should be suitable | 13 | congestion-controlled, unreliable datagrams. It should be suitable |
14 | for use by applications such as streaming media, Internet telephony, | 14 | for use by applications such as streaming media, Internet telephony, |
15 | and on-line games | 15 | and on-line games. |
16 | 16 | ||
17 | To compile this protocol support as a module, choose M here: the | 17 | To compile this protocol support as a module, choose M here: the |
18 | module will be called dccp. | 18 | module will be called dccp. |
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 4d176d33983f..f8208874ac7d 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c | |||
@@ -113,7 +113,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | |||
113 | 113 | ||
114 | memcpy(to, from, len); | 114 | memcpy(to, from, len); |
115 | /* | 115 | /* |
116 | * From draft-ietf-dccp-spec-11.txt: | 116 | * From RFC 4340, A.2: |
117 | * | 117 | * |
118 | * For each acknowledgement it sends, the HC-Receiver will add an | 118 | * For each acknowledgement it sends, the HC-Receiver will add an |
119 | * acknowledgement record. ack_seqno will equal the HC-Receiver | 119 | * acknowledgement record. ack_seqno will equal the HC-Receiver |
@@ -224,7 +224,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, | |||
224 | } | 224 | } |
225 | 225 | ||
226 | /* | 226 | /* |
227 | * Implements the draft-ietf-dccp-spec-11.txt Appendix A | 227 | * Implements the RFC 4340, Appendix A |
228 | */ | 228 | */ |
229 | int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | 229 | int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, |
230 | const u64 ackno, const u8 state) | 230 | const u64 ackno, const u8 state) |
@@ -237,7 +237,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | |||
237 | * We may well decide to do buffer compression, etc, but for now lets | 237 | * We may well decide to do buffer compression, etc, but for now lets |
238 | * just drop. | 238 | * just drop. |
239 | * | 239 | * |
240 | * From Appendix A: | 240 | * From Appendix A.1.1 (`New Packets'): |
241 | * | 241 | * |
242 | * Of course, the circular buffer may overflow, either when the | 242 | * Of course, the circular buffer may overflow, either when the |
243 | * HC-Sender is sending data at a very high rate, when the | 243 | * HC-Sender is sending data at a very high rate, when the |
@@ -274,9 +274,9 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | |||
274 | /* | 274 | /* |
275 | * A.1.2. Old Packets | 275 | * A.1.2. Old Packets |
276 | * | 276 | * |
277 | * When a packet with Sequence Number S arrives, and | 277 | * When a packet with Sequence Number S <= buf_ackno |
278 | * S <= buf_ackno, the HC-Receiver will scan the table | 278 | * arrives, the HC-Receiver will scan the table for |
279 | * for the byte corresponding to S. (Indexing structures | 279 | * the byte corresponding to S. (Indexing structures |
280 | * could reduce the complexity of this scan.) | 280 | * could reduce the complexity of this scan.) |
281 | */ | 281 | */ |
282 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); | 282 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); |
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 2424effac7f6..cf8f20ce23a9 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h | |||
@@ -28,8 +28,7 @@ | |||
28 | 28 | ||
29 | /** struct dccp_ackvec - ack vector | 29 | /** struct dccp_ackvec - ack vector |
30 | * | 30 | * |
31 | * This data structure is the one defined in the DCCP draft | 31 | * This data structure is the one defined in RFC 4340, Appendix A. |
32 | * Appendix A. | ||
33 | * | 32 | * |
34 | * @dccpav_buf_head - circular buffer head | 33 | * @dccpav_buf_head - circular buffer head |
35 | * @dccpav_buf_tail - circular buffer tail | 34 | * @dccpav_buf_tail - circular buffer tail |
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig index 32752f750447..8533dabfb9f8 100644 --- a/net/dccp/ccids/Kconfig +++ b/net/dccp/ccids/Kconfig | |||
@@ -22,11 +22,11 @@ config IP_DCCP_CCID2 | |||
22 | for lost packets, would prefer CCID 2 to CCID 3. On-line games may | 22 | for lost packets, would prefer CCID 2 to CCID 3. On-line games may |
23 | also prefer CCID 2. | 23 | also prefer CCID 2. |
24 | 24 | ||
25 | CCID 2 is further described in: | 25 | CCID 2 is further described in RFC 4341, |
26 | http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid2-10.txt | 26 | http://www.ietf.org/rfc/rfc4341.txt |
27 | 27 | ||
28 | This text was extracted from: | 28 | This text was extracted from RFC 4340 (sec. 10.1), |
29 | http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt | 29 | http://www.ietf.org/rfc/rfc4340.txt |
30 | 30 | ||
31 | If in doubt, say M. | 31 | If in doubt, say M. |
32 | 32 | ||
@@ -53,15 +53,14 @@ config IP_DCCP_CCID3 | |||
53 | suitable than CCID 2 for applications such streaming media where a | 53 | suitable than CCID 2 for applications such streaming media where a |
54 | relatively smooth sending rate is of importance. | 54 | relatively smooth sending rate is of importance. |
55 | 55 | ||
56 | CCID 3 is further described in: | 56 | CCID 3 is further described in RFC 4342, |
57 | 57 | http://www.ietf.org/rfc/rfc4342.txt | |
58 | http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid3-11.txt. | ||
59 | 58 | ||
60 | The TFRC congestion control algorithms were initially described in | 59 | The TFRC congestion control algorithms were initially described in |
61 | RFC 3448. | 60 | RFC 3448. |
62 | 61 | ||
63 | This text was extracted from: | 62 | This text was extracted from RFC 4340 (sec. 10.2), |
64 | http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt | 63 | http://www.ietf.org/rfc/rfc4340.txt |
65 | 64 | ||
66 | If in doubt, say M. | 65 | If in doubt, say M. |
67 | 66 | ||
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 2efb505aeb35..162032baeac0 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * This implementation should follow: draft-ietf-dccp-ccid2-10.txt | 26 | * This implementation should follow RFC 4341 |
27 | * | 27 | * |
28 | * BUGS: | 28 | * BUGS: |
29 | * - sequence number wrapping | 29 | * - sequence number wrapping |
@@ -352,14 +352,14 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
352 | 352 | ||
353 | #ifdef CONFIG_IP_DCCP_CCID2_DEBUG | 353 | #ifdef CONFIG_IP_DCCP_CCID2_DEBUG |
354 | ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); | 354 | ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); |
355 | ccid2_pr_debug("Sent: seq=%llu\n", seq); | 355 | ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq); |
356 | do { | 356 | do { |
357 | struct ccid2_seq *seqp = hctx->ccid2hctx_seqt; | 357 | struct ccid2_seq *seqp = hctx->ccid2hctx_seqt; |
358 | 358 | ||
359 | while (seqp != hctx->ccid2hctx_seqh) { | 359 | while (seqp != hctx->ccid2hctx_seqh) { |
360 | ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", | 360 | ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", |
361 | seqp->ccid2s_seq, seqp->ccid2s_acked, | 361 | (unsigned long long)seqp->ccid2s_seq, |
362 | seqp->ccid2s_sent); | 362 | seqp->ccid2s_acked, seqp->ccid2s_sent); |
363 | seqp = seqp->ccid2s_next; | 363 | seqp = seqp->ccid2s_next; |
364 | } | 364 | } |
365 | } while (0); | 365 | } while (0); |
@@ -480,7 +480,8 @@ static inline void ccid2_new_ack(struct sock *sk, | |||
480 | /* first measurement */ | 480 | /* first measurement */ |
481 | if (hctx->ccid2hctx_srtt == -1) { | 481 | if (hctx->ccid2hctx_srtt == -1) { |
482 | ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", | 482 | ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", |
483 | r, jiffies, seqp->ccid2s_seq); | 483 | r, jiffies, |
484 | (unsigned long long)seqp->ccid2s_seq); | ||
484 | ccid2_change_srtt(hctx, r); | 485 | ccid2_change_srtt(hctx, r); |
485 | hctx->ccid2hctx_rttvar = r >> 1; | 486 | hctx->ccid2hctx_rttvar = r >> 1; |
486 | } else { | 487 | } else { |
@@ -636,8 +637,9 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
636 | u64 ackno_end_rl; | 637 | u64 ackno_end_rl; |
637 | 638 | ||
638 | dccp_set_seqno(&ackno_end_rl, ackno - rl); | 639 | dccp_set_seqno(&ackno_end_rl, ackno - rl); |
639 | ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno, | 640 | ccid2_pr_debug("ackvec start:%llu end:%llu\n", |
640 | ackno_end_rl); | 641 | (unsigned long long)ackno, |
642 | (unsigned long long)ackno_end_rl); | ||
641 | /* if the seqno we are analyzing is larger than the | 643 | /* if the seqno we are analyzing is larger than the |
642 | * current ackno, then move towards the tail of our | 644 | * current ackno, then move towards the tail of our |
643 | * seqnos. | 645 | * seqnos. |
@@ -672,7 +674,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
672 | 674 | ||
673 | seqp->ccid2s_acked = 1; | 675 | seqp->ccid2s_acked = 1; |
674 | ccid2_pr_debug("Got ack for %llu\n", | 676 | ccid2_pr_debug("Got ack for %llu\n", |
675 | seqp->ccid2s_seq); | 677 | (unsigned long long)seqp->ccid2s_seq); |
676 | ccid2_hc_tx_dec_pipe(sk); | 678 | ccid2_hc_tx_dec_pipe(sk); |
677 | } | 679 | } |
678 | if (seqp == hctx->ccid2hctx_seqt) { | 680 | if (seqp == hctx->ccid2hctx_seqt) { |
@@ -718,7 +720,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
718 | while (1) { | 720 | while (1) { |
719 | if (!seqp->ccid2s_acked) { | 721 | if (!seqp->ccid2s_acked) { |
720 | ccid2_pr_debug("Packet lost: %llu\n", | 722 | ccid2_pr_debug("Packet lost: %llu\n", |
721 | seqp->ccid2s_seq); | 723 | (unsigned long long)seqp->ccid2s_seq); |
722 | /* XXX need to traverse from tail -> head in | 724 | /* XXX need to traverse from tail -> head in |
723 | * order to detect multiple congestion events in | 725 | * order to detect multiple congestion events in |
724 | * one ack vector. | 726 | * one ack vector. |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 67d2dc0e7c67..cec23ad286de 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -379,8 +379,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
379 | packet->dccphtx_seqno = dp->dccps_gss; | 379 | packet->dccphtx_seqno = dp->dccps_gss; |
380 | /* | 380 | /* |
381 | * Check if win_count have changed | 381 | * Check if win_count have changed |
382 | * Algorithm in "8.1. Window Counter Valuer" in | 382 | * Algorithm in "8.1. Window Counter Value" in RFC 4342. |
383 | * draft-ietf-dccp-ccid3-11.txt | ||
384 | */ | 383 | */ |
385 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); | 384 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); |
386 | if (likely(hctx->ccid3hctx_rtt > 8)) | 385 | if (likely(hctx->ccid3hctx_rtt > 8)) |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 0a21be437ed3..272e8584564e 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -50,7 +50,7 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); | |||
50 | #define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT | 50 | #define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT |
51 | * state, about 60 seconds */ | 51 | * state, about 60 seconds */ |
52 | 52 | ||
53 | /* draft-ietf-dccp-spec-11.txt initial RTO value */ | 53 | /* RFC 1122, 4.2.3.1 initial RTO value */ |
54 | #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ)) | 54 | #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ)) |
55 | 55 | ||
56 | /* Maximal interval between probes for local resources. */ | 56 | /* Maximal interval between probes for local resources. */ |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 7f9dc6ac58c9..1d24881ac0ab 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -216,11 +216,11 @@ send_sync: | |||
216 | dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, | 216 | dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, |
217 | DCCP_PKT_SYNCACK); | 217 | DCCP_PKT_SYNCACK); |
218 | /* | 218 | /* |
219 | * From the draft: | 219 | * From RFC 4340, sec. 5.7 |
220 | * | 220 | * |
221 | * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets | 221 | * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets |
222 | * MAY have non-zero-length application data areas, whose | 222 | * MAY have non-zero-length application data areas, whose |
223 | * contents * receivers MUST ignore. | 223 | * contents receivers MUST ignore. |
224 | */ | 224 | */ |
225 | goto discard; | 225 | goto discard; |
226 | } | 226 | } |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index bf692c1c116f..e08e7688a263 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -183,7 +183,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk, | |||
183 | dccp_sync_mss(sk, mtu); | 183 | dccp_sync_mss(sk, mtu); |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * From: draft-ietf-dccp-spec-11.txt | 186 | * From RFC 4340, sec. 14.1: |
187 | * | 187 | * |
188 | * DCCP-Sync packets are the best choice for upward | 188 | * DCCP-Sync packets are the best choice for upward |
189 | * probing, since DCCP-Sync probes do not risk application | 189 | * probing, since DCCP-Sync probes do not risk application |
@@ -311,7 +311,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) | |||
311 | } | 311 | } |
312 | 312 | ||
313 | if (sk->sk_state == DCCP_TIME_WAIT) { | 313 | if (sk->sk_state == DCCP_TIME_WAIT) { |
314 | inet_twsk_put((struct inet_timewait_sock *)sk); | 314 | inet_twsk_put(inet_twsk(sk)); |
315 | return; | 315 | return; |
316 | } | 316 | } |
317 | 317 | ||
@@ -449,6 +449,8 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk, | |||
449 | dccp_hdr(skb)->dccph_sport); | 449 | dccp_hdr(skb)->dccph_sport); |
450 | } | 450 | } |
451 | 451 | ||
452 | static struct request_sock_ops dccp_request_sock_ops; | ||
453 | |||
452 | int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 454 | int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
453 | { | 455 | { |
454 | struct inet_request_sock *ireq; | 456 | struct inet_request_sock *ireq; |
@@ -489,7 +491,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
489 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 491 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
490 | goto drop; | 492 | goto drop; |
491 | 493 | ||
492 | req = reqsk_alloc(sk->sk_prot->rsk_prot); | 494 | req = reqsk_alloc(&dccp_request_sock_ops); |
493 | if (req == NULL) | 495 | if (req == NULL) |
494 | goto drop; | 496 | goto drop; |
495 | 497 | ||
@@ -614,7 +616,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
614 | bh_lock_sock(nsk); | 616 | bh_lock_sock(nsk); |
615 | return nsk; | 617 | return nsk; |
616 | } | 618 | } |
617 | inet_twsk_put((struct inet_timewait_sock *)nsk); | 619 | inet_twsk_put(inet_twsk(nsk)); |
618 | return NULL; | 620 | return NULL; |
619 | } | 621 | } |
620 | 622 | ||
@@ -731,7 +733,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) | |||
731 | dccp_hdr_reset(skb)->dccph_reset_code = | 733 | dccp_hdr_reset(skb)->dccph_reset_code = |
732 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; | 734 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; |
733 | 735 | ||
734 | /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ | 736 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ |
735 | seqno = 0; | 737 | seqno = 0; |
736 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 738 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
737 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); | 739 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); |
@@ -980,7 +982,7 @@ discard_and_relse: | |||
980 | goto discard_it; | 982 | goto discard_it; |
981 | 983 | ||
982 | do_time_wait: | 984 | do_time_wait: |
983 | inet_twsk_put((struct inet_timewait_sock *)sk); | 985 | inet_twsk_put(inet_twsk(sk)); |
984 | goto no_dccp_socket; | 986 | goto no_dccp_socket; |
985 | } | 987 | } |
986 | 988 | ||
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 7a47399cf31f..fc4242c0767c 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -277,7 +277,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
277 | __u64 seq; | 277 | __u64 seq; |
278 | 278 | ||
279 | sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, | 279 | sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, |
280 | &hdr->saddr, dh->dccph_sport, skb->dev->ifindex); | 280 | &hdr->saddr, dh->dccph_sport, inet6_iif(skb)); |
281 | 281 | ||
282 | if (sk == NULL) { | 282 | if (sk == NULL) { |
283 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); | 283 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); |
@@ -285,7 +285,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
285 | } | 285 | } |
286 | 286 | ||
287 | if (sk->sk_state == DCCP_TIME_WAIT) { | 287 | if (sk->sk_state == DCCP_TIME_WAIT) { |
288 | inet_twsk_put((struct inet_timewait_sock *)sk); | 288 | inet_twsk_put(inet_twsk(sk)); |
289 | return; | 289 | return; |
290 | } | 290 | } |
291 | 291 | ||
@@ -550,7 +550,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) | |||
550 | dccp_hdr_reset(skb)->dccph_reset_code = | 550 | dccp_hdr_reset(skb)->dccph_reset_code = |
551 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; | 551 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; |
552 | 552 | ||
553 | /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ | 553 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ |
554 | seqno = 0; | 554 | seqno = 0; |
555 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 555 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
556 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); | 556 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); |
@@ -663,7 +663,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
663 | bh_lock_sock(nsk); | 663 | bh_lock_sock(nsk); |
664 | return nsk; | 664 | return nsk; |
665 | } | 665 | } |
666 | inet_twsk_put((struct inet_timewait_sock *)nsk); | 666 | inet_twsk_put(inet_twsk(nsk)); |
667 | return NULL; | 667 | return NULL; |
668 | } | 668 | } |
669 | 669 | ||
@@ -672,7 +672,6 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
672 | 672 | ||
673 | static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | 673 | static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) |
674 | { | 674 | { |
675 | struct inet_request_sock *ireq; | ||
676 | struct dccp_sock dp; | 675 | struct dccp_sock dp; |
677 | struct request_sock *req; | 676 | struct request_sock *req; |
678 | struct dccp_request_sock *dreq; | 677 | struct dccp_request_sock *dreq; |
@@ -701,7 +700,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
701 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 700 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
702 | goto drop; | 701 | goto drop; |
703 | 702 | ||
704 | req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot); | 703 | req = inet6_reqsk_alloc(&dccp6_request_sock_ops); |
705 | if (req == NULL) | 704 | if (req == NULL) |
706 | goto drop; | 705 | goto drop; |
707 | 706 | ||
@@ -713,7 +712,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
713 | goto drop_and_free; | 712 | goto drop_and_free; |
714 | 713 | ||
715 | ireq6 = inet6_rsk(req); | 714 | ireq6 = inet6_rsk(req); |
716 | ireq = inet_rsk(req); | ||
717 | ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); | 715 | ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); |
718 | ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); | 716 | ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); |
719 | req->rcv_wnd = dccp_feat_default_sequence_window; | 717 | req->rcv_wnd = dccp_feat_default_sequence_window; |
@@ -997,6 +995,10 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
997 | if (sk->sk_state == DCCP_OPEN) { /* Fast path */ | 995 | if (sk->sk_state == DCCP_OPEN) { /* Fast path */ |
998 | if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) | 996 | if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) |
999 | goto reset; | 997 | goto reset; |
998 | if (opt_skb) { | ||
999 | /* This is where we would goto ipv6_pktoptions. */ | ||
1000 | __kfree_skb(opt_skb); | ||
1001 | } | ||
1000 | return 0; | 1002 | return 0; |
1001 | } | 1003 | } |
1002 | 1004 | ||
@@ -1021,6 +1023,10 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1021 | 1023 | ||
1022 | if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) | 1024 | if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) |
1023 | goto reset; | 1025 | goto reset; |
1026 | if (opt_skb) { | ||
1027 | /* This is where we would goto ipv6_pktoptions. */ | ||
1028 | __kfree_skb(opt_skb); | ||
1029 | } | ||
1024 | return 0; | 1030 | return 0; |
1025 | 1031 | ||
1026 | reset: | 1032 | reset: |
@@ -1109,7 +1115,7 @@ discard_and_relse: | |||
1109 | goto discard_it; | 1115 | goto discard_it; |
1110 | 1116 | ||
1111 | do_time_wait: | 1117 | do_time_wait: |
1112 | inet_twsk_put((struct inet_timewait_sock *)sk); | 1118 | inet_twsk_put(inet_twsk(sk)); |
1113 | goto no_dccp_socket; | 1119 | goto no_dccp_socket; |
1114 | } | 1120 | } |
1115 | 1121 | ||
diff --git a/net/dccp/options.c b/net/dccp/options.c index 07a34696ac97..fb0db1f7cd7b 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -215,7 +215,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
215 | elapsed_time); | 215 | elapsed_time); |
216 | break; | 216 | break; |
217 | /* | 217 | /* |
218 | * From draft-ietf-dccp-spec-11.txt: | 218 | * From RFC 4340, sec. 10.3: |
219 | * | 219 | * |
220 | * Option numbers 128 through 191 are for | 220 | * Option numbers 128 through 191 are for |
221 | * options sent from the HC-Sender to the | 221 | * options sent from the HC-Sender to the |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 70e027375682..21f20f21dd32 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -166,7 +166,7 @@ static struct hlist_head *dn_find_list(struct sock *sk) | |||
166 | if (scp->addr.sdn_flags & SDF_WILD) | 166 | if (scp->addr.sdn_flags & SDF_WILD) |
167 | return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL; | 167 | return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL; |
168 | 168 | ||
169 | return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK]; | 169 | return &dn_sk_hash[dn_ntohs(scp->addrloc) & DN_SK_HASH_MASK]; |
170 | } | 170 | } |
171 | 171 | ||
172 | /* | 172 | /* |
@@ -180,7 +180,7 @@ static int check_port(__le16 port) | |||
180 | if (port == 0) | 180 | if (port == 0) |
181 | return -1; | 181 | return -1; |
182 | 182 | ||
183 | sk_for_each(sk, node, &dn_sk_hash[port & DN_SK_HASH_MASK]) { | 183 | sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(port) & DN_SK_HASH_MASK]) { |
184 | struct dn_scp *scp = DN_SK(sk); | 184 | struct dn_scp *scp = DN_SK(sk); |
185 | if (scp->addrloc == port) | 185 | if (scp->addrloc == port) |
186 | return -1; | 186 | return -1; |
@@ -194,12 +194,12 @@ static unsigned short port_alloc(struct sock *sk) | |||
194 | static unsigned short port = 0x2000; | 194 | static unsigned short port = 0x2000; |
195 | unsigned short i_port = port; | 195 | unsigned short i_port = port; |
196 | 196 | ||
197 | while(check_port(++port) != 0) { | 197 | while(check_port(dn_htons(++port)) != 0) { |
198 | if (port == i_port) | 198 | if (port == i_port) |
199 | return 0; | 199 | return 0; |
200 | } | 200 | } |
201 | 201 | ||
202 | scp->addrloc = port; | 202 | scp->addrloc = dn_htons(port); |
203 | 203 | ||
204 | return 1; | 204 | return 1; |
205 | } | 205 | } |
@@ -418,7 +418,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb) | |||
418 | struct dn_scp *scp; | 418 | struct dn_scp *scp; |
419 | 419 | ||
420 | read_lock(&dn_hash_lock); | 420 | read_lock(&dn_hash_lock); |
421 | sk_for_each(sk, node, &dn_sk_hash[cb->dst_port & DN_SK_HASH_MASK]) { | 421 | sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(cb->dst_port) & DN_SK_HASH_MASK]) { |
422 | scp = DN_SK(sk); | 422 | scp = DN_SK(sk); |
423 | if (cb->src != dn_saddr2dn(&scp->peer)) | 423 | if (cb->src != dn_saddr2dn(&scp->peer)) |
424 | continue; | 424 | continue; |
@@ -1016,13 +1016,14 @@ static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) | |||
1016 | 1016 | ||
1017 | static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) | 1017 | static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) |
1018 | { | 1018 | { |
1019 | unsigned char *ptr = skb->data; | 1019 | unsigned char *ptr = skb->data; |
1020 | 1020 | u16 len = *ptr++; /* yes, it's 8bit on the wire */ | |
1021 | opt->opt_optl = *ptr++; | 1021 | |
1022 | opt->opt_status = 0; | 1022 | BUG_ON(len > 16); /* we've checked the contents earlier */ |
1023 | memcpy(opt->opt_data, ptr, opt->opt_optl); | 1023 | opt->opt_optl = dn_htons(len); |
1024 | skb_pull(skb, dn_ntohs(opt->opt_optl) + 1); | 1024 | opt->opt_status = 0; |
1025 | 1025 | memcpy(opt->opt_data, ptr, len); | |
1026 | skb_pull(skb, len + 1); | ||
1026 | } | 1027 | } |
1027 | 1028 | ||
1028 | static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) | 1029 | static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) |
@@ -1178,8 +1179,10 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len | |||
1178 | if (peer) { | 1179 | if (peer) { |
1179 | if ((sock->state != SS_CONNECTED && | 1180 | if ((sock->state != SS_CONNECTED && |
1180 | sock->state != SS_CONNECTING) && | 1181 | sock->state != SS_CONNECTING) && |
1181 | scp->accept_mode == ACC_IMMED) | 1182 | scp->accept_mode == ACC_IMMED) { |
1183 | release_sock(sk); | ||
1182 | return -ENOTCONN; | 1184 | return -ENOTCONN; |
1185 | } | ||
1183 | 1186 | ||
1184 | memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn)); | 1187 | memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn)); |
1185 | } else { | 1188 | } else { |
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 72ecc6e62ec4..7683d4f754d2 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c | |||
@@ -360,9 +360,9 @@ static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb) | |||
360 | scp->max_window = decnet_no_fc_max_cwnd; | 360 | scp->max_window = decnet_no_fc_max_cwnd; |
361 | 361 | ||
362 | if (skb->len > 0) { | 362 | if (skb->len > 0) { |
363 | unsigned char dlen = *skb->data; | 363 | u16 dlen = *skb->data; |
364 | if ((dlen <= 16) && (dlen <= skb->len)) { | 364 | if ((dlen <= 16) && (dlen <= skb->len)) { |
365 | scp->conndata_in.opt_optl = dn_htons((__u16)dlen); | 365 | scp->conndata_in.opt_optl = dn_htons(dlen); |
366 | memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen); | 366 | memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen); |
367 | } | 367 | } |
368 | } | 368 | } |
@@ -404,9 +404,9 @@ static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb) | |||
404 | memset(scp->discdata_in.opt_data, 0, 16); | 404 | memset(scp->discdata_in.opt_data, 0, 16); |
405 | 405 | ||
406 | if (skb->len > 0) { | 406 | if (skb->len > 0) { |
407 | unsigned char dlen = *skb->data; | 407 | u16 dlen = *skb->data; |
408 | if ((dlen <= 16) && (dlen <= skb->len)) { | 408 | if ((dlen <= 16) && (dlen <= skb->len)) { |
409 | scp->discdata_in.opt_optl = dn_htons((__u16)dlen); | 409 | scp->discdata_in.opt_optl = dn_htons(dlen); |
410 | memcpy(scp->discdata_in.opt_data, skb->data + 1, dlen); | 410 | memcpy(scp->discdata_in.opt_data, skb->data + 1, dlen); |
411 | } | 411 | } |
412 | } | 412 | } |
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index c2e21cd89b3c..b342e4e8f5f8 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c | |||
@@ -526,7 +526,7 @@ void dn_send_conn_conf(struct sock *sk, gfp_t gfp) | |||
526 | struct nsp_conn_init_msg *msg; | 526 | struct nsp_conn_init_msg *msg; |
527 | __u8 len = (__u8)dn_ntohs(scp->conndata_out.opt_optl); | 527 | __u8 len = (__u8)dn_ntohs(scp->conndata_out.opt_optl); |
528 | 528 | ||
529 | if ((skb = dn_alloc_skb(sk, 50 + dn_ntohs(scp->conndata_out.opt_optl), gfp)) == NULL) | 529 | if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL) |
530 | return; | 530 | return; |
531 | 531 | ||
532 | msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg)); | 532 | msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg)); |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index dd0761e3d280..23489f7232d2 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -267,9 +267,14 @@ static void dn_dst_link_failure(struct sk_buff *skb) | |||
267 | 267 | ||
268 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 268 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) |
269 | { | 269 | { |
270 | return memcmp(&fl1->nl_u.dn_u, &fl2->nl_u.dn_u, sizeof(fl1->nl_u.dn_u)) == 0 && | 270 | return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | |
271 | fl1->oif == fl2->oif && | 271 | (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | |
272 | fl1->iif == fl2->iif; | 272 | #ifdef CONFIG_DECNET_ROUTE_FWMARK |
273 | (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) | | ||
274 | #endif | ||
275 | (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | | ||
276 | (fl1->oif ^ fl2->oif) | | ||
277 | (fl1->iif ^ fl2->iif)) == 0; | ||
273 | } | 278 | } |
274 | 279 | ||
275 | static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) | 280 | static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) |
@@ -1270,7 +1275,6 @@ static int dn_route_input_slow(struct sk_buff *skb) | |||
1270 | goto e_inval; | 1275 | goto e_inval; |
1271 | 1276 | ||
1272 | res.type = RTN_LOCAL; | 1277 | res.type = RTN_LOCAL; |
1273 | flags |= RTCF_DIRECTSRC; | ||
1274 | } else { | 1278 | } else { |
1275 | __le16 src_map = fl.fld_src; | 1279 | __le16 src_map = fl.fld_src; |
1276 | free_res = 1; | 1280 | free_res = 1; |
@@ -1341,7 +1345,7 @@ static int dn_route_input_slow(struct sk_buff *skb) | |||
1341 | goto make_route; | 1345 | goto make_route; |
1342 | 1346 | ||
1343 | /* Packet was intra-ethernet, so we know its on-link */ | 1347 | /* Packet was intra-ethernet, so we know its on-link */ |
1344 | if (cb->rt_flags | DN_RT_F_IE) { | 1348 | if (cb->rt_flags & DN_RT_F_IE) { |
1345 | gateway = cb->src; | 1349 | gateway = cb->src; |
1346 | flags |= RTCF_DIRECTSRC; | 1350 | flags |= RTCF_DIRECTSRC; |
1347 | goto make_route; | 1351 | goto make_route; |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 3e0c882c90bf..590e0a72495c 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -124,8 +124,8 @@ static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | |||
124 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | 124 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) |
125 | { | 125 | { |
126 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; | 126 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; |
127 | u16 daddr = fl->fld_dst; | 127 | __le16 daddr = fl->fld_dst; |
128 | u16 saddr = fl->fld_src; | 128 | __le16 saddr = fl->fld_src; |
129 | 129 | ||
130 | if (((saddr ^ r->src) & r->srcmask) || | 130 | if (((saddr ^ r->src) & r->srcmask) || |
131 | ((daddr ^ r->dst) & r->dstmask)) | 131 | ((daddr ^ r->dst) & r->dstmask)) |
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig index f7e84e9d13ad..a64be6cdf078 100644 --- a/net/ieee80211/Kconfig +++ b/net/ieee80211/Kconfig | |||
@@ -32,6 +32,7 @@ config IEEE80211_CRYPT_WEP | |||
32 | depends on IEEE80211 | 32 | depends on IEEE80211 |
33 | select CRYPTO | 33 | select CRYPTO |
34 | select CRYPTO_ARC4 | 34 | select CRYPTO_ARC4 |
35 | select CRYPTO_ECB | ||
35 | select CRC32 | 36 | select CRC32 |
36 | ---help--- | 37 | ---help--- |
37 | Include software based cipher suites in support of IEEE | 38 | Include software based cipher suites in support of IEEE |
@@ -58,6 +59,7 @@ config IEEE80211_CRYPT_TKIP | |||
58 | depends on IEEE80211 && NET_RADIO | 59 | depends on IEEE80211 && NET_RADIO |
59 | select CRYPTO | 60 | select CRYPTO |
60 | select CRYPTO_MICHAEL_MIC | 61 | select CRYPTO_MICHAEL_MIC |
62 | select CRYPTO_ECB | ||
61 | select CRC32 | 63 | select CRC32 |
62 | ---help--- | 64 | ---help--- |
63 | Include software based cipher suites in support of IEEE 802.11i | 65 | Include software based cipher suites in support of IEEE 802.11i |
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 770704183a1b..2759312a4204 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -1078,12 +1078,12 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element | |||
1078 | 1078 | ||
1079 | while (length >= sizeof(*info_element)) { | 1079 | while (length >= sizeof(*info_element)) { |
1080 | if (sizeof(*info_element) + info_element->len > length) { | 1080 | if (sizeof(*info_element) + info_element->len > length) { |
1081 | IEEE80211_ERROR("Info elem: parse failed: " | 1081 | IEEE80211_DEBUG_MGMT("Info elem: parse failed: " |
1082 | "info_element->len + 2 > left : " | 1082 | "info_element->len + 2 > left : " |
1083 | "info_element->len+2=%zd left=%d, id=%d.\n", | 1083 | "info_element->len+2=%zd left=%d, id=%d.\n", |
1084 | info_element->len + | 1084 | info_element->len + |
1085 | sizeof(*info_element), | 1085 | sizeof(*info_element), |
1086 | length, info_element->id); | 1086 | length, info_element->id); |
1087 | /* We stop processing but don't return an error here | 1087 | /* We stop processing but don't return an error here |
1088 | * because some misbehaviour APs break this rule. ie. | 1088 | * because some misbehaviour APs break this rule. ie. |
1089 | * Orinoco AP1000. */ | 1089 | * Orinoco AP1000. */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index 589f6d2c548a..cf51c87a971d 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft | |||
48 | dprintk(KERN_INFO PFX "sent association request!\n"); | 48 | dprintk(KERN_INFO PFX "sent association request!\n"); |
49 | 49 | ||
50 | spin_lock_irqsave(&mac->lock, flags); | 50 | spin_lock_irqsave(&mac->lock, flags); |
51 | mac->associated = 0; /* just to make sure */ | 51 | mac->associnfo.associated = 0; /* just to make sure */ |
52 | 52 | ||
53 | /* Set a timer for timeout */ | 53 | /* Set a timer for timeout */ |
54 | /* FIXME: make timeout configurable */ | 54 | /* FIXME: make timeout configurable */ |
@@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d) | |||
62 | { | 62 | { |
63 | struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; | 63 | struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; |
64 | struct ieee80211softmac_network *n; | 64 | struct ieee80211softmac_network *n; |
65 | unsigned long flags; | ||
66 | 65 | ||
67 | spin_lock_irqsave(&mac->lock, flags); | 66 | mutex_lock(&mac->associnfo.mutex); |
68 | /* we might race against ieee80211softmac_handle_assoc_response, | 67 | /* we might race against ieee80211softmac_handle_assoc_response, |
69 | * so make sure only one of us does something */ | 68 | * so make sure only one of us does something */ |
70 | if (!mac->associnfo.associating) { | 69 | if (!mac->associnfo.associating) |
71 | spin_unlock_irqrestore(&mac->lock, flags); | 70 | goto out; |
72 | return; | ||
73 | } | ||
74 | mac->associnfo.associating = 0; | 71 | mac->associnfo.associating = 0; |
75 | mac->associnfo.bssvalid = 0; | 72 | mac->associnfo.bssvalid = 0; |
76 | mac->associated = 0; | 73 | mac->associnfo.associated = 0; |
77 | 74 | ||
78 | n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); | 75 | n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); |
79 | spin_unlock_irqrestore(&mac->lock, flags); | ||
80 | 76 | ||
81 | dprintk(KERN_INFO PFX "assoc request timed out!\n"); | 77 | dprintk(KERN_INFO PFX "assoc request timed out!\n"); |
82 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); | 78 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); |
79 | out: | ||
80 | mutex_unlock(&mac->associnfo.mutex); | ||
83 | } | 81 | } |
84 | 82 | ||
85 | void | 83 | void |
@@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac) | |||
93 | 91 | ||
94 | netif_carrier_off(mac->dev); | 92 | netif_carrier_off(mac->dev); |
95 | 93 | ||
96 | mac->associated = 0; | 94 | mac->associnfo.associated = 0; |
97 | mac->associnfo.bssvalid = 0; | 95 | mac->associnfo.bssvalid = 0; |
98 | mac->associnfo.associating = 0; | 96 | mac->associnfo.associating = 0; |
99 | ieee80211softmac_init_bss(mac); | 97 | ieee80211softmac_init_bss(mac); |
@@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reas | |||
107 | { | 105 | { |
108 | struct ieee80211softmac_network *found; | 106 | struct ieee80211softmac_network *found; |
109 | 107 | ||
110 | if (mac->associnfo.bssvalid && mac->associated) { | 108 | if (mac->associnfo.bssvalid && mac->associnfo.associated) { |
111 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 109 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
112 | if (found) | 110 | if (found) |
113 | ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); | 111 | ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); |
@@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d) | |||
196 | int bssvalid; | 194 | int bssvalid; |
197 | unsigned long flags; | 195 | unsigned long flags; |
198 | 196 | ||
197 | mutex_lock(&mac->associnfo.mutex); | ||
198 | |||
199 | if (!mac->associnfo.associating) | ||
200 | goto out; | ||
201 | |||
199 | /* ieee80211_disassoc might clear this */ | 202 | /* ieee80211_disassoc might clear this */ |
200 | bssvalid = mac->associnfo.bssvalid; | 203 | bssvalid = mac->associnfo.bssvalid; |
201 | 204 | ||
202 | /* meh */ | 205 | /* meh */ |
203 | if (mac->associated) | 206 | if (mac->associnfo.associated) |
204 | ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); | 207 | ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
205 | 208 | ||
206 | spin_lock_irqsave(&mac->lock, flags); | ||
207 | mac->associnfo.associating = 1; | ||
208 | spin_unlock_irqrestore(&mac->lock, flags); | ||
209 | |||
210 | /* try to find the requested network in our list, if we found one already */ | 209 | /* try to find the requested network in our list, if we found one already */ |
211 | if (bssvalid || mac->associnfo.bssfixed) | 210 | if (bssvalid || mac->associnfo.bssfixed) |
212 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 211 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
@@ -260,10 +259,8 @@ ieee80211softmac_assoc_work(void *d) | |||
260 | 259 | ||
261 | if (!found) { | 260 | if (!found) { |
262 | if (mac->associnfo.scan_retry > 0) { | 261 | if (mac->associnfo.scan_retry > 0) { |
263 | spin_lock_irqsave(&mac->lock, flags); | ||
264 | mac->associnfo.scan_retry--; | 262 | mac->associnfo.scan_retry--; |
265 | spin_unlock_irqrestore(&mac->lock, flags); | 263 | |
266 | |||
267 | /* We know of no such network. Let's scan. | 264 | /* We know of no such network. Let's scan. |
268 | * NB: this also happens if we had no memory to copy the network info... | 265 | * NB: this also happens if we had no memory to copy the network info... |
269 | * Maybe we can hope to have more memory after scanning finishes ;) | 266 | * Maybe we can hope to have more memory after scanning finishes ;) |
@@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d) | |||
272 | ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); | 269 | ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); |
273 | if (ieee80211softmac_start_scan(mac)) | 270 | if (ieee80211softmac_start_scan(mac)) |
274 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); | 271 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); |
275 | return; | 272 | goto out; |
276 | } else { | 273 | } else { |
277 | spin_lock_irqsave(&mac->lock, flags); | ||
278 | mac->associnfo.associating = 0; | 274 | mac->associnfo.associating = 0; |
279 | mac->associated = 0; | 275 | mac->associnfo.associated = 0; |
280 | spin_unlock_irqrestore(&mac->lock, flags); | ||
281 | 276 | ||
282 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); | 277 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); |
283 | /* reset the retry counter for the next user request since we | 278 | /* reset the retry counter for the next user request since we |
284 | * break out and don't reschedule ourselves after this point. */ | 279 | * break out and don't reschedule ourselves after this point. */ |
285 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | 280 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; |
286 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); | 281 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); |
287 | return; | 282 | goto out; |
288 | } | 283 | } |
289 | } | 284 | } |
290 | 285 | ||
@@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d) | |||
297 | /* copy the ESSID for displaying it */ | 292 | /* copy the ESSID for displaying it */ |
298 | mac->associnfo.associate_essid.len = found->essid.len; | 293 | mac->associnfo.associate_essid.len = found->essid.len; |
299 | memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); | 294 | memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); |
300 | 295 | ||
301 | /* we found a network! authenticate (if necessary) and associate to it. */ | 296 | /* we found a network! authenticate (if necessary) and associate to it. */ |
302 | if (found->authenticating) { | 297 | if (found->authenticating) { |
303 | dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); | 298 | dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); |
@@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d) | |||
305 | mac->associnfo.assoc_wait = 1; | 300 | mac->associnfo.assoc_wait = 1; |
306 | ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); | 301 | ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); |
307 | } | 302 | } |
308 | return; | 303 | goto out; |
309 | } | 304 | } |
310 | if (!found->authenticated && !found->authenticating) { | 305 | if (!found->authenticated && !found->authenticating) { |
311 | /* This relies on the fact that _auth_req only queues the work, | 306 | /* This relies on the fact that _auth_req only queues the work, |
@@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d) | |||
321 | mac->associnfo.assoc_wait = 0; | 316 | mac->associnfo.assoc_wait = 0; |
322 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); | 317 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); |
323 | } | 318 | } |
324 | return; | 319 | goto out; |
325 | } | 320 | } |
326 | /* finally! now we can start associating */ | 321 | /* finally! now we can start associating */ |
327 | mac->associnfo.assoc_wait = 0; | 322 | mac->associnfo.assoc_wait = 0; |
328 | ieee80211softmac_assoc(mac, found); | 323 | ieee80211softmac_assoc(mac, found); |
324 | |||
325 | out: | ||
326 | mutex_unlock(&mac->associnfo.mutex); | ||
329 | } | 327 | } |
330 | 328 | ||
331 | /* call this to do whatever is necessary when we're associated */ | 329 | /* call this to do whatever is necessary when we're associated */ |
@@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac, | |||
341 | mac->bssinfo.supported_rates = net->supported_rates; | 339 | mac->bssinfo.supported_rates = net->supported_rates; |
342 | ieee80211softmac_recalc_txrates(mac); | 340 | ieee80211softmac_recalc_txrates(mac); |
343 | 341 | ||
344 | mac->associated = 1; | 342 | mac->associnfo.associated = 1; |
345 | 343 | ||
346 | mac->associnfo.short_preamble_available = | 344 | mac->associnfo.short_preamble_available = |
347 | (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; | 345 | (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; |
@@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, | |||
421 | dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); | 419 | dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); |
422 | mac->associnfo.associating = 0; | 420 | mac->associnfo.associating = 0; |
423 | mac->associnfo.bssvalid = 0; | 421 | mac->associnfo.bssvalid = 0; |
424 | mac->associated = 0; | 422 | mac->associnfo.associated = 0; |
425 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); | 423 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); |
426 | } | 424 | } |
427 | 425 | ||
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c index 82bfddbf33a2..b96931001b43 100644 --- a/net/ieee80211/softmac/ieee80211softmac_io.c +++ b/net/ieee80211/softmac/ieee80211softmac_io.c | |||
@@ -304,7 +304,7 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt, | |||
304 | 2 + /* Auth Transaction Seq */ | 304 | 2 + /* Auth Transaction Seq */ |
305 | 2 + /* Status Code */ | 305 | 2 + /* Status Code */ |
306 | /* Challenge Text IE */ | 306 | /* Challenge Text IE */ |
307 | is_shared_response ? 0 : 1 + 1 + net->challenge_len | 307 | (is_shared_response ? 1 + 1 + net->challenge_len : 0) |
308 | ); | 308 | ); |
309 | if (unlikely((*pkt) == NULL)) | 309 | if (unlikely((*pkt) == NULL)) |
310 | return 0; | 310 | return 0; |
@@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struct net_device *dev, | |||
475 | { | 475 | { |
476 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | 476 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); |
477 | 477 | ||
478 | if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) | 478 | /* This might race, but we don't really care and it's not worth |
479 | ieee80211softmac_process_erp(mac, network->erp_value); | 479 | * adding heavyweight locking in this fastpath. |
480 | */ | ||
481 | if (mac->associnfo.associated) { | ||
482 | if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) | ||
483 | ieee80211softmac_process_erp(mac, network->erp_value); | ||
484 | } | ||
480 | 485 | ||
481 | return 0; | 486 | return 0; |
482 | } | 487 | } |
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index addea1cf73ae..33aff4f4a471 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
@@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
57 | INIT_LIST_HEAD(&softmac->network_list); | 57 | INIT_LIST_HEAD(&softmac->network_list); |
58 | INIT_LIST_HEAD(&softmac->events); | 58 | INIT_LIST_HEAD(&softmac->events); |
59 | 59 | ||
60 | mutex_init(&softmac->associnfo.mutex); | ||
60 | INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); | 61 | INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); |
61 | INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); | 62 | INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); |
62 | softmac->start_scan = ieee80211softmac_start_scan_implementation; | 63 | softmac->start_scan = ieee80211softmac_start_scan_implementation; |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 2aa779d18f38..23068a830f7d 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
73 | struct ieee80211softmac_network *n; | 73 | struct ieee80211softmac_network *n; |
74 | struct ieee80211softmac_auth_queue_item *authptr; | 74 | struct ieee80211softmac_auth_queue_item *authptr; |
75 | int length = 0; | 75 | int length = 0; |
76 | unsigned long flags; | 76 | |
77 | mutex_lock(&sm->associnfo.mutex); | ||
77 | 78 | ||
78 | /* Check if we're already associating to this or another network | 79 | /* Check if we're already associating to this or another network |
79 | * If it's another network, cancel and start over with our new network | 80 | * If it's another network, cancel and start over with our new network |
80 | * If it's our network, ignore the change, we're already doing it! | 81 | * If it's our network, ignore the change, we're already doing it! |
81 | */ | 82 | */ |
82 | if((sm->associnfo.associating || sm->associated) && | 83 | if((sm->associnfo.associating || sm->associnfo.associated) && |
83 | (data->essid.flags && data->essid.length)) { | 84 | (data->essid.flags && data->essid.length)) { |
84 | /* Get the associating network */ | 85 | /* Get the associating network */ |
85 | n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); | 86 | n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); |
@@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
87 | !memcmp(n->essid.data, extra, n->essid.len)) { | 88 | !memcmp(n->essid.data, extra, n->essid.len)) { |
88 | dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", | 89 | dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", |
89 | MAC_ARG(sm->associnfo.bssid)); | 90 | MAC_ARG(sm->associnfo.bssid)); |
90 | return 0; | 91 | goto out; |
91 | } else { | 92 | } else { |
92 | dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); | 93 | dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); |
93 | spin_lock_irqsave(&sm->lock,flags); | ||
94 | /* Cancel assoc work */ | 94 | /* Cancel assoc work */ |
95 | cancel_delayed_work(&sm->associnfo.work); | 95 | cancel_delayed_work(&sm->associnfo.work); |
96 | /* We don't have to do this, but it's a little cleaner */ | 96 | /* We don't have to do this, but it's a little cleaner */ |
@@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
98 | cancel_delayed_work(&authptr->work); | 98 | cancel_delayed_work(&authptr->work); |
99 | sm->associnfo.bssvalid = 0; | 99 | sm->associnfo.bssvalid = 0; |
100 | sm->associnfo.bssfixed = 0; | 100 | sm->associnfo.bssfixed = 0; |
101 | spin_unlock_irqrestore(&sm->lock,flags); | ||
102 | flush_scheduled_work(); | 101 | flush_scheduled_work(); |
102 | sm->associnfo.associating = 0; | ||
103 | sm->associnfo.associated = 0; | ||
103 | } | 104 | } |
104 | } | 105 | } |
105 | 106 | ||
106 | 107 | ||
107 | spin_lock_irqsave(&sm->lock, flags); | ||
108 | |||
109 | sm->associnfo.static_essid = 0; | 108 | sm->associnfo.static_essid = 0; |
110 | sm->associnfo.assoc_wait = 0; | 109 | sm->associnfo.assoc_wait = 0; |
111 | 110 | ||
@@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
121 | * If applicable, we have already copied the data in */ | 120 | * If applicable, we have already copied the data in */ |
122 | sm->associnfo.req_essid.len = length; | 121 | sm->associnfo.req_essid.len = length; |
123 | 122 | ||
123 | sm->associnfo.associating = 1; | ||
124 | /* queue lower level code to do work (if necessary) */ | 124 | /* queue lower level code to do work (if necessary) */ |
125 | schedule_work(&sm->associnfo.work); | 125 | schedule_work(&sm->associnfo.work); |
126 | out: | ||
127 | mutex_unlock(&sm->associnfo.mutex); | ||
126 | 128 | ||
127 | spin_unlock_irqrestore(&sm->lock, flags); | ||
128 | return 0; | 129 | return 0; |
129 | } | 130 | } |
130 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); | 131 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); |
@@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev, | |||
136 | char *extra) | 137 | char *extra) |
137 | { | 138 | { |
138 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | 139 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); |
139 | unsigned long flags; | ||
140 | 140 | ||
141 | /* avoid getting inconsistent information */ | 141 | mutex_lock(&sm->associnfo.mutex); |
142 | spin_lock_irqsave(&sm->lock, flags); | ||
143 | /* If all fails, return ANY (empty) */ | 142 | /* If all fails, return ANY (empty) */ |
144 | data->essid.length = 0; | 143 | data->essid.length = 0; |
145 | data->essid.flags = 0; /* active */ | 144 | data->essid.flags = 0; /* active */ |
@@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev, | |||
152 | } | 151 | } |
153 | 152 | ||
154 | /* If we're associating/associated, return that */ | 153 | /* If we're associating/associated, return that */ |
155 | if (sm->associated || sm->associnfo.associating) { | 154 | if (sm->associnfo.associated || sm->associnfo.associating) { |
156 | data->essid.length = sm->associnfo.associate_essid.len; | 155 | data->essid.length = sm->associnfo.associate_essid.len; |
157 | data->essid.flags = 1; /* active */ | 156 | data->essid.flags = 1; /* active */ |
158 | memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); | 157 | memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); |
159 | } | 158 | } |
160 | spin_unlock_irqrestore(&sm->lock, flags); | 159 | mutex_unlock(&sm->associnfo.mutex); |
160 | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); | 163 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); |
@@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev, | |||
322 | { | 322 | { |
323 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 323 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
324 | int err = 0; | 324 | int err = 0; |
325 | unsigned long flags; | ||
326 | 325 | ||
327 | spin_lock_irqsave(&mac->lock, flags); | 326 | mutex_lock(&mac->associnfo.mutex); |
328 | if (mac->associnfo.bssvalid) | 327 | if (mac->associnfo.bssvalid) |
329 | memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); | 328 | memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); |
330 | else | 329 | else |
331 | memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); | 330 | memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); |
332 | data->ap_addr.sa_family = ARPHRD_ETHER; | 331 | data->ap_addr.sa_family = ARPHRD_ETHER; |
333 | spin_unlock_irqrestore(&mac->lock, flags); | 332 | mutex_unlock(&mac->associnfo.mutex); |
333 | |||
334 | return err; | 334 | return err; |
335 | } | 335 | } |
336 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); | 336 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); |
@@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
342 | char *extra) | 342 | char *extra) |
343 | { | 343 | { |
344 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 344 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
345 | unsigned long flags; | ||
346 | 345 | ||
347 | /* sanity check */ | 346 | /* sanity check */ |
348 | if (data->ap_addr.sa_family != ARPHRD_ETHER) { | 347 | if (data->ap_addr.sa_family != ARPHRD_ETHER) { |
349 | return -EINVAL; | 348 | return -EINVAL; |
350 | } | 349 | } |
351 | 350 | ||
352 | spin_lock_irqsave(&mac->lock, flags); | 351 | mutex_lock(&mac->associnfo.mutex); |
353 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { | 352 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { |
354 | /* the bssid we have is not to be fixed any longer, | 353 | /* the bssid we have is not to be fixed any longer, |
355 | * and we should reassociate to the best AP. */ | 354 | * and we should reassociate to the best AP. */ |
356 | mac->associnfo.bssfixed = 0; | 355 | mac->associnfo.bssfixed = 0; |
357 | /* force reassociation */ | 356 | /* force reassociation */ |
358 | mac->associnfo.bssvalid = 0; | 357 | mac->associnfo.bssvalid = 0; |
359 | if (mac->associated) | 358 | if (mac->associnfo.associated) |
360 | schedule_work(&mac->associnfo.work); | 359 | schedule_work(&mac->associnfo.work); |
361 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | 360 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { |
362 | /* the bssid we have is no longer fixed */ | 361 | /* the bssid we have is no longer fixed */ |
363 | mac->associnfo.bssfixed = 0; | 362 | mac->associnfo.bssfixed = 0; |
364 | } else { | 363 | } else { |
365 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { | 364 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { |
366 | if (mac->associnfo.associating || mac->associated) { | 365 | if (mac->associnfo.associating || mac->associnfo.associated) { |
367 | /* bssid unchanged and associated or associating - just return */ | 366 | /* bssid unchanged and associated or associating - just return */ |
368 | goto out; | 367 | goto out; |
369 | } | 368 | } |
@@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
378 | } | 377 | } |
379 | 378 | ||
380 | out: | 379 | out: |
381 | spin_unlock_irqrestore(&mac->lock, flags); | 380 | mutex_unlock(&mac->associnfo.mutex); |
381 | |||
382 | return 0; | 382 | return 0; |
383 | } | 383 | } |
384 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); | 384 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); |
@@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev, | |||
394 | int err = 0; | 394 | int err = 0; |
395 | char *buf; | 395 | char *buf; |
396 | int i; | 396 | int i; |
397 | 397 | ||
398 | mutex_lock(&mac->associnfo.mutex); | ||
398 | spin_lock_irqsave(&mac->lock, flags); | 399 | spin_lock_irqsave(&mac->lock, flags); |
399 | /* bleh. shouldn't be locked for that kmalloc... */ | 400 | /* bleh. shouldn't be locked for that kmalloc... */ |
400 | 401 | ||
@@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev, | |||
432 | 433 | ||
433 | out: | 434 | out: |
434 | spin_unlock_irqrestore(&mac->lock, flags); | 435 | spin_unlock_irqrestore(&mac->lock, flags); |
436 | mutex_unlock(&mac->associnfo.mutex); | ||
437 | |||
435 | return err; | 438 | return err; |
436 | } | 439 | } |
437 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); | 440 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); |
@@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, | |||
446 | unsigned long flags; | 449 | unsigned long flags; |
447 | int err = 0; | 450 | int err = 0; |
448 | int space = wrqu->data.length; | 451 | int space = wrqu->data.length; |
449 | 452 | ||
453 | mutex_lock(&mac->associnfo.mutex); | ||
450 | spin_lock_irqsave(&mac->lock, flags); | 454 | spin_lock_irqsave(&mac->lock, flags); |
451 | 455 | ||
452 | wrqu->data.length = 0; | 456 | wrqu->data.length = 0; |
@@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, | |||
459 | err = -E2BIG; | 463 | err = -E2BIG; |
460 | } | 464 | } |
461 | spin_unlock_irqrestore(&mac->lock, flags); | 465 | spin_unlock_irqrestore(&mac->lock, flags); |
466 | mutex_lock(&mac->associnfo.mutex); | ||
467 | |||
462 | return err; | 468 | return err; |
463 | } | 469 | } |
464 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); | 470 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); |
@@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, | |||
473 | struct iw_mlme *mlme = (struct iw_mlme *)extra; | 479 | struct iw_mlme *mlme = (struct iw_mlme *)extra; |
474 | u16 reason = cpu_to_le16(mlme->reason_code); | 480 | u16 reason = cpu_to_le16(mlme->reason_code); |
475 | struct ieee80211softmac_network *net; | 481 | struct ieee80211softmac_network *net; |
482 | int err = -EINVAL; | ||
483 | |||
484 | mutex_lock(&mac->associnfo.mutex); | ||
476 | 485 | ||
477 | if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { | 486 | if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { |
478 | printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); | 487 | printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); |
479 | return -EINVAL; | 488 | goto out; |
480 | } | 489 | } |
481 | 490 | ||
482 | switch (mlme->cmd) { | 491 | switch (mlme->cmd) { |
@@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, | |||
484 | net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); | 493 | net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); |
485 | if (!net) { | 494 | if (!net) { |
486 | printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); | 495 | printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); |
487 | return -EINVAL; | 496 | goto out; |
488 | } | 497 | } |
489 | return ieee80211softmac_deauth_req(mac, net, reason); | 498 | return ieee80211softmac_deauth_req(mac, net, reason); |
490 | case IW_MLME_DISASSOC: | 499 | case IW_MLME_DISASSOC: |
491 | ieee80211softmac_send_disassoc_req(mac, reason); | 500 | ieee80211softmac_send_disassoc_req(mac, reason); |
492 | return 0; | 501 | mac->associnfo.associated = 0; |
502 | mac->associnfo.associating = 0; | ||
503 | err = 0; | ||
504 | goto out; | ||
493 | default: | 505 | default: |
494 | return -EOPNOTSUPP; | 506 | err = -EOPNOTSUPP; |
495 | } | 507 | } |
508 | |||
509 | out: | ||
510 | mutex_unlock(&mac->associnfo.mutex); | ||
511 | |||
512 | return err; | ||
496 | } | 513 | } |
497 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); | 514 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index a8e2e879a647..6460233407c7 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <net/tcp.h> | 43 | #include <net/tcp.h> |
44 | #include <net/netlabel.h> | 44 | #include <net/netlabel.h> |
45 | #include <net/cipso_ipv4.h> | 45 | #include <net/cipso_ipv4.h> |
46 | #include <asm/atomic.h> | ||
46 | #include <asm/bug.h> | 47 | #include <asm/bug.h> |
47 | 48 | ||
48 | struct cipso_v4_domhsh_entry { | 49 | struct cipso_v4_domhsh_entry { |
@@ -79,7 +80,7 @@ struct cipso_v4_map_cache_entry { | |||
79 | unsigned char *key; | 80 | unsigned char *key; |
80 | size_t key_len; | 81 | size_t key_len; |
81 | 82 | ||
82 | struct netlbl_lsm_cache lsm_data; | 83 | struct netlbl_lsm_cache *lsm_data; |
83 | 84 | ||
84 | u32 activity; | 85 | u32 activity; |
85 | struct list_head list; | 86 | struct list_head list; |
@@ -188,13 +189,14 @@ static void cipso_v4_doi_domhsh_free(struct rcu_head *entry) | |||
188 | * @entry: the entry to free | 189 | * @entry: the entry to free |
189 | * | 190 | * |
190 | * Description: | 191 | * Description: |
191 | * This function frees the memory associated with a cache entry. | 192 | * This function frees the memory associated with a cache entry including the |
193 | * LSM cache data if there are no longer any users, i.e. reference count == 0. | ||
192 | * | 194 | * |
193 | */ | 195 | */ |
194 | static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) | 196 | static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) |
195 | { | 197 | { |
196 | if (entry->lsm_data.free) | 198 | if (entry->lsm_data) |
197 | entry->lsm_data.free(entry->lsm_data.data); | 199 | netlbl_secattr_cache_free(entry->lsm_data); |
198 | kfree(entry->key); | 200 | kfree(entry->key); |
199 | kfree(entry); | 201 | kfree(entry); |
200 | } | 202 | } |
@@ -315,8 +317,8 @@ static int cipso_v4_cache_check(const unsigned char *key, | |||
315 | entry->key_len == key_len && | 317 | entry->key_len == key_len && |
316 | memcmp(entry->key, key, key_len) == 0) { | 318 | memcmp(entry->key, key, key_len) == 0) { |
317 | entry->activity += 1; | 319 | entry->activity += 1; |
318 | secattr->cache.free = entry->lsm_data.free; | 320 | atomic_inc(&entry->lsm_data->refcount); |
319 | secattr->cache.data = entry->lsm_data.data; | 321 | secattr->cache = entry->lsm_data; |
320 | if (prev_entry == NULL) { | 322 | if (prev_entry == NULL) { |
321 | spin_unlock_bh(&cipso_v4_cache[bkt].lock); | 323 | spin_unlock_bh(&cipso_v4_cache[bkt].lock); |
322 | return 0; | 324 | return 0; |
@@ -383,8 +385,8 @@ int cipso_v4_cache_add(const struct sk_buff *skb, | |||
383 | memcpy(entry->key, cipso_ptr, cipso_ptr_len); | 385 | memcpy(entry->key, cipso_ptr, cipso_ptr_len); |
384 | entry->key_len = cipso_ptr_len; | 386 | entry->key_len = cipso_ptr_len; |
385 | entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); | 387 | entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); |
386 | entry->lsm_data.free = secattr->cache.free; | 388 | atomic_inc(&secattr->cache->refcount); |
387 | entry->lsm_data.data = secattr->cache.data; | 389 | entry->lsm_data = secattr->cache; |
388 | 390 | ||
389 | bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); | 391 | bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); |
390 | spin_lock_bh(&cipso_v4_cache[bkt].lock); | 392 | spin_lock_bh(&cipso_v4_cache[bkt].lock); |
@@ -771,13 +773,15 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def, | |||
771 | { | 773 | { |
772 | int cat = -1; | 774 | int cat = -1; |
773 | u32 bitmap_len_bits = bitmap_len * 8; | 775 | u32 bitmap_len_bits = bitmap_len * 8; |
774 | u32 cipso_cat_size = doi_def->map.std->cat.cipso_size; | 776 | u32 cipso_cat_size; |
775 | u32 *cipso_array = doi_def->map.std->cat.cipso; | 777 | u32 *cipso_array; |
776 | 778 | ||
777 | switch (doi_def->type) { | 779 | switch (doi_def->type) { |
778 | case CIPSO_V4_MAP_PASS: | 780 | case CIPSO_V4_MAP_PASS: |
779 | return 0; | 781 | return 0; |
780 | case CIPSO_V4_MAP_STD: | 782 | case CIPSO_V4_MAP_STD: |
783 | cipso_cat_size = doi_def->map.std->cat.cipso_size; | ||
784 | cipso_array = doi_def->map.std->cat.cipso; | ||
781 | for (;;) { | 785 | for (;;) { |
782 | cat = cipso_v4_bitmap_walk(bitmap, | 786 | cat = cipso_v4_bitmap_walk(bitmap, |
783 | bitmap_len_bits, | 787 | bitmap_len_bits, |
@@ -823,19 +827,21 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, | |||
823 | u32 net_spot_max = 0; | 827 | u32 net_spot_max = 0; |
824 | u32 host_clen_bits = host_cat_len * 8; | 828 | u32 host_clen_bits = host_cat_len * 8; |
825 | u32 net_clen_bits = net_cat_len * 8; | 829 | u32 net_clen_bits = net_cat_len * 8; |
826 | u32 host_cat_size = doi_def->map.std->cat.local_size; | 830 | u32 host_cat_size; |
827 | u32 *host_cat_array = doi_def->map.std->cat.local; | 831 | u32 *host_cat_array; |
828 | 832 | ||
829 | switch (doi_def->type) { | 833 | switch (doi_def->type) { |
830 | case CIPSO_V4_MAP_PASS: | 834 | case CIPSO_V4_MAP_PASS: |
831 | net_spot_max = host_cat_len - 1; | 835 | net_spot_max = host_cat_len; |
832 | while (net_spot_max > 0 && host_cat[net_spot_max] == 0) | 836 | while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0) |
833 | net_spot_max--; | 837 | net_spot_max--; |
834 | if (net_spot_max > net_cat_len) | 838 | if (net_spot_max > net_cat_len) |
835 | return -EINVAL; | 839 | return -EINVAL; |
836 | memcpy(net_cat, host_cat, net_spot_max); | 840 | memcpy(net_cat, host_cat, net_spot_max); |
837 | return net_spot_max; | 841 | return net_spot_max; |
838 | case CIPSO_V4_MAP_STD: | 842 | case CIPSO_V4_MAP_STD: |
843 | host_cat_size = doi_def->map.std->cat.local_size; | ||
844 | host_cat_array = doi_def->map.std->cat.local; | ||
839 | for (;;) { | 845 | for (;;) { |
840 | host_spot = cipso_v4_bitmap_walk(host_cat, | 846 | host_spot = cipso_v4_bitmap_walk(host_cat, |
841 | host_clen_bits, | 847 | host_clen_bits, |
@@ -891,8 +897,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, | |||
891 | int net_spot = -1; | 897 | int net_spot = -1; |
892 | u32 net_clen_bits = net_cat_len * 8; | 898 | u32 net_clen_bits = net_cat_len * 8; |
893 | u32 host_clen_bits = host_cat_len * 8; | 899 | u32 host_clen_bits = host_cat_len * 8; |
894 | u32 net_cat_size = doi_def->map.std->cat.cipso_size; | 900 | u32 net_cat_size; |
895 | u32 *net_cat_array = doi_def->map.std->cat.cipso; | 901 | u32 *net_cat_array; |
896 | 902 | ||
897 | switch (doi_def->type) { | 903 | switch (doi_def->type) { |
898 | case CIPSO_V4_MAP_PASS: | 904 | case CIPSO_V4_MAP_PASS: |
@@ -901,6 +907,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, | |||
901 | memcpy(host_cat, net_cat, net_cat_len); | 907 | memcpy(host_cat, net_cat, net_cat_len); |
902 | return net_cat_len; | 908 | return net_cat_len; |
903 | case CIPSO_V4_MAP_STD: | 909 | case CIPSO_V4_MAP_STD: |
910 | net_cat_size = doi_def->map.std->cat.cipso_size; | ||
911 | net_cat_array = doi_def->map.std->cat.cipso; | ||
904 | for (;;) { | 912 | for (;;) { |
905 | net_spot = cipso_v4_bitmap_walk(net_cat, | 913 | net_spot = cipso_v4_bitmap_walk(net_cat, |
906 | net_clen_bits, | 914 | net_clen_bits, |
@@ -1299,7 +1307,8 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
1299 | 1307 | ||
1300 | /* We can't use ip_options_get() directly because it makes a call to | 1308 | /* We can't use ip_options_get() directly because it makes a call to |
1301 | * ip_options_get_alloc() which allocates memory with GFP_KERNEL and | 1309 | * ip_options_get_alloc() which allocates memory with GFP_KERNEL and |
1302 | * we can't block here. */ | 1310 | * we won't always have CAP_NET_RAW even though we _always_ want to |
1311 | * set the IPOPT_CIPSO option. */ | ||
1303 | opt_len = (buf_len + 3) & ~3; | 1312 | opt_len = (buf_len + 3) & ~3; |
1304 | opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); | 1313 | opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); |
1305 | if (opt == NULL) { | 1314 | if (opt == NULL) { |
@@ -1309,11 +1318,9 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
1309 | memcpy(opt->__data, buf, buf_len); | 1318 | memcpy(opt->__data, buf, buf_len); |
1310 | opt->optlen = opt_len; | 1319 | opt->optlen = opt_len; |
1311 | opt->is_data = 1; | 1320 | opt->is_data = 1; |
1321 | opt->cipso = sizeof(struct iphdr); | ||
1312 | kfree(buf); | 1322 | kfree(buf); |
1313 | buf = NULL; | 1323 | buf = NULL; |
1314 | ret_val = ip_options_compile(opt, NULL); | ||
1315 | if (ret_val != 0) | ||
1316 | goto socket_setattr_failure; | ||
1317 | 1324 | ||
1318 | sk_inet = inet_sk(sk); | 1325 | sk_inet = inet_sk(sk); |
1319 | if (sk_inet->is_icsk) { | 1326 | if (sk_inet->is_icsk) { |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 9c399a70dd5d..af0190d8b6c0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -482,9 +482,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
482 | memset(cfg, 0, sizeof(*cfg)); | 482 | memset(cfg, 0, sizeof(*cfg)); |
483 | 483 | ||
484 | rtm = nlmsg_data(nlh); | 484 | rtm = nlmsg_data(nlh); |
485 | cfg->fc_family = rtm->rtm_family; | ||
486 | cfg->fc_dst_len = rtm->rtm_dst_len; | 485 | cfg->fc_dst_len = rtm->rtm_dst_len; |
487 | cfg->fc_src_len = rtm->rtm_src_len; | ||
488 | cfg->fc_tos = rtm->rtm_tos; | 486 | cfg->fc_tos = rtm->rtm_tos; |
489 | cfg->fc_table = rtm->rtm_table; | 487 | cfg->fc_table = rtm->rtm_table; |
490 | cfg->fc_protocol = rtm->rtm_protocol; | 488 | cfg->fc_protocol = rtm->rtm_protocol; |
@@ -501,9 +499,6 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
501 | case RTA_DST: | 499 | case RTA_DST: |
502 | cfg->fc_dst = nla_get_be32(attr); | 500 | cfg->fc_dst = nla_get_be32(attr); |
503 | break; | 501 | break; |
504 | case RTA_SRC: | ||
505 | cfg->fc_src = nla_get_be32(attr); | ||
506 | break; | ||
507 | case RTA_OIF: | 502 | case RTA_OIF: |
508 | cfg->fc_oif = nla_get_u32(attr); | 503 | cfg->fc_oif = nla_get_u32(attr); |
509 | break; | 504 | break; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 2b1a54b59c48..f072f3875af8 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -94,10 +94,8 @@ int inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */ | |||
94 | int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */ | 94 | int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */ |
95 | 95 | ||
96 | static struct inet_peer *inet_peer_unused_head; | 96 | static struct inet_peer *inet_peer_unused_head; |
97 | /* Exported for inet_putpeer inline function. */ | 97 | static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head; |
98 | struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head; | 98 | static DEFINE_SPINLOCK(inet_peer_unused_lock); |
99 | DEFINE_SPINLOCK(inet_peer_unused_lock); | ||
100 | #define PEER_MAX_CLEANUP_WORK 30 | ||
101 | 99 | ||
102 | static void peer_check_expire(unsigned long dummy); | 100 | static void peer_check_expire(unsigned long dummy); |
103 | static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0); | 101 | static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0); |
@@ -340,7 +338,8 @@ static int cleanup_once(unsigned long ttl) | |||
340 | spin_lock_bh(&inet_peer_unused_lock); | 338 | spin_lock_bh(&inet_peer_unused_lock); |
341 | p = inet_peer_unused_head; | 339 | p = inet_peer_unused_head; |
342 | if (p != NULL) { | 340 | if (p != NULL) { |
343 | if (time_after(p->dtime + ttl, jiffies)) { | 341 | __u32 delta = (__u32)jiffies - p->dtime; |
342 | if (delta < ttl) { | ||
344 | /* Do not prune fresh entries. */ | 343 | /* Do not prune fresh entries. */ |
345 | spin_unlock_bh(&inet_peer_unused_lock); | 344 | spin_unlock_bh(&inet_peer_unused_lock); |
346 | return -1; | 345 | return -1; |
@@ -432,7 +431,7 @@ out_free: | |||
432 | /* Called with local BH disabled. */ | 431 | /* Called with local BH disabled. */ |
433 | static void peer_check_expire(unsigned long dummy) | 432 | static void peer_check_expire(unsigned long dummy) |
434 | { | 433 | { |
435 | int i; | 434 | unsigned long now = jiffies; |
436 | int ttl; | 435 | int ttl; |
437 | 436 | ||
438 | if (peer_total >= inet_peer_threshold) | 437 | if (peer_total >= inet_peer_threshold) |
@@ -441,7 +440,10 @@ static void peer_check_expire(unsigned long dummy) | |||
441 | ttl = inet_peer_maxttl | 440 | ttl = inet_peer_maxttl |
442 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * | 441 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * |
443 | peer_total / inet_peer_threshold * HZ; | 442 | peer_total / inet_peer_threshold * HZ; |
444 | for (i = 0; i < PEER_MAX_CLEANUP_WORK && !cleanup_once(ttl); i++); | 443 | while (!cleanup_once(ttl)) { |
444 | if (jiffies != now) | ||
445 | break; | ||
446 | } | ||
445 | 447 | ||
446 | /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime | 448 | /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime |
447 | * interval depending on the total number of entries (more entries, | 449 | * interval depending on the total number of entries (more entries, |
@@ -455,3 +457,16 @@ static void peer_check_expire(unsigned long dummy) | |||
455 | peer_total / inet_peer_threshold * HZ; | 457 | peer_total / inet_peer_threshold * HZ; |
456 | add_timer(&peer_periodic_timer); | 458 | add_timer(&peer_periodic_timer); |
457 | } | 459 | } |
460 | |||
461 | void inet_putpeer(struct inet_peer *p) | ||
462 | { | ||
463 | spin_lock_bh(&inet_peer_unused_lock); | ||
464 | if (atomic_dec_and_test(&p->refcnt)) { | ||
465 | p->unused_prevp = inet_peer_unused_tailp; | ||
466 | p->unused_next = NULL; | ||
467 | *inet_peer_unused_tailp = p; | ||
468 | inet_peer_unused_tailp = &p->unused_next; | ||
469 | p->dtime = (__u32)jiffies; | ||
470 | } | ||
471 | spin_unlock_bh(&inet_peer_unused_lock); | ||
472 | } | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f5fba051df3d..d5b5dec075b8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -611,8 +611,8 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
611 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header | 611 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header |
612 | */ | 612 | */ |
613 | if (flags == 0 && | 613 | if (flags == 0 && |
614 | skb->protocol == __constant_htons(ETH_P_WCCP)) { | 614 | skb->protocol == htons(ETH_P_WCCP)) { |
615 | skb->protocol = __constant_htons(ETH_P_IP); | 615 | skb->protocol = htons(ETH_P_IP); |
616 | if ((*(h + offset) & 0xF0) != 0x40) | 616 | if ((*(h + offset) & 0xF0) != 0x40) |
617 | offset += 4; | 617 | offset += 4; |
618 | } | 618 | } |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 8dabbfc31267..9f02917d6f45 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) | |||
443 | opt->router_alert = optptr - iph; | 443 | opt->router_alert = optptr - iph; |
444 | break; | 444 | break; |
445 | case IPOPT_CIPSO: | 445 | case IPOPT_CIPSO: |
446 | if (opt->cipso) { | 446 | if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) { |
447 | pp_ptr = optptr; | 447 | pp_ptr = optptr; |
448 | goto error; | 448 | goto error; |
449 | } | 449 | } |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f8ce84759159..955a07abb91d 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -420,7 +420,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
420 | { | 420 | { |
421 | struct arphdr *rarp; | 421 | struct arphdr *rarp; |
422 | unsigned char *rarp_ptr; | 422 | unsigned char *rarp_ptr; |
423 | unsigned long sip, tip; | 423 | u32 sip, tip; |
424 | unsigned char *sha, *tha; /* s for "source", t for "target" */ | 424 | unsigned char *sha, *tha; /* s for "source", t for "target" */ |
425 | struct ic_device *d; | 425 | struct ic_device *d; |
426 | 426 | ||
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c index 6d398f10aa91..687c1de1146f 100644 --- a/net/ipv4/ipvs/ip_vs_ftp.c +++ b/net/ipv4/ipvs/ip_vs_ftp.c | |||
@@ -200,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
200 | from = n_cp->vaddr; | 200 | from = n_cp->vaddr; |
201 | port = n_cp->vport; | 201 | port = n_cp->vport; |
202 | sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), | 202 | sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), |
203 | ntohs(port)&255, (ntohs(port)>>8)&255); | 203 | (ntohs(port)>>8)&255, ntohs(port)&255); |
204 | buf_len = strlen(buf); | 204 | buf_len = strlen(buf); |
205 | 205 | ||
206 | /* | 206 | /* |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index bfe779e74590..6ff05c3a32e6 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
@@ -117,7 +117,7 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip, | |||
117 | { | 117 | { |
118 | tcph->check = | 118 | tcph->check = |
119 | ip_vs_check_diff(~oldip, newip, | 119 | ip_vs_check_diff(~oldip, newip, |
120 | ip_vs_check_diff(oldport ^ htonl(0xFFFF), | 120 | ip_vs_check_diff(oldport ^ htons(0xFFFF), |
121 | newport, tcph->check)); | 121 | newport, tcph->check)); |
122 | } | 122 | } |
123 | 123 | ||
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 54aa7603591f..691c8b637b29 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
@@ -122,10 +122,10 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip, | |||
122 | { | 122 | { |
123 | uhdr->check = | 123 | uhdr->check = |
124 | ip_vs_check_diff(~oldip, newip, | 124 | ip_vs_check_diff(~oldip, newip, |
125 | ip_vs_check_diff(oldport ^ htonl(0xFFFF), | 125 | ip_vs_check_diff(oldport ^ htons(0xFFFF), |
126 | newport, uhdr->check)); | 126 | newport, uhdr->check)); |
127 | if (!uhdr->check) | 127 | if (!uhdr->check) |
128 | uhdr->check = htonl(0xFFFF); | 128 | uhdr->check = -1; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int | 131 | static int |
@@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb, | |||
173 | cp->protocol, | 173 | cp->protocol, |
174 | (*pskb)->csum); | 174 | (*pskb)->csum); |
175 | if (udph->check == 0) | 175 | if (udph->check == 0) |
176 | udph->check = htonl(0xFFFF); | 176 | udph->check = -1; |
177 | IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", | 177 | IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", |
178 | pp->name, udph->check, | 178 | pp->name, udph->check, |
179 | (char*)&(udph->check) - (char*)udph); | 179 | (char*)&(udph->check) - (char*)udph); |
@@ -228,7 +228,7 @@ udp_dnat_handler(struct sk_buff **pskb, | |||
228 | cp->protocol, | 228 | cp->protocol, |
229 | (*pskb)->csum); | 229 | (*pskb)->csum); |
230 | if (udph->check == 0) | 230 | if (udph->check == 0) |
231 | udph->check = 0xFFFF; | 231 | udph->check = -1; |
232 | (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; | 232 | (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; |
233 | } | 233 | } |
234 | return 1; | 234 | return 1; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 17e1a687ab45..413c2d0a1f3d 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -466,7 +466,13 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
466 | return -EINVAL; | 466 | return -EINVAL; |
467 | } | 467 | } |
468 | 468 | ||
469 | if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset) | ||
470 | return -EINVAL; | ||
471 | |||
469 | t = arpt_get_target(e); | 472 | t = arpt_get_target(e); |
473 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
474 | return -EINVAL; | ||
475 | |||
470 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, | 476 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, |
471 | t->u.user.revision), | 477 | t->u.user.revision), |
472 | "arpt_%s", t->u.user.name); | 478 | "arpt_%s", t->u.user.name); |
@@ -621,20 +627,18 @@ static int translate_table(const char *name, | |||
621 | } | 627 | } |
622 | } | 628 | } |
623 | 629 | ||
624 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
625 | duprintf("Looping hook\n"); | ||
626 | return -ELOOP; | ||
627 | } | ||
628 | |||
629 | /* Finally, each sanity check must pass */ | 630 | /* Finally, each sanity check must pass */ |
630 | i = 0; | 631 | i = 0; |
631 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 632 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
632 | check_entry, name, size, &i); | 633 | check_entry, name, size, &i); |
633 | 634 | ||
634 | if (ret != 0) { | 635 | if (ret != 0) |
635 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 636 | goto cleanup; |
636 | cleanup_entry, &i); | 637 | |
637 | return ret; | 638 | ret = -ELOOP; |
639 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
640 | duprintf("Looping hook\n"); | ||
641 | goto cleanup; | ||
638 | } | 642 | } |
639 | 643 | ||
640 | /* And one copy for every other CPU */ | 644 | /* And one copy for every other CPU */ |
@@ -643,6 +647,9 @@ static int translate_table(const char *name, | |||
643 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 647 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
644 | } | 648 | } |
645 | 649 | ||
650 | return 0; | ||
651 | cleanup: | ||
652 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
646 | return ret; | 653 | return ret; |
647 | } | 654 | } |
648 | 655 | ||
@@ -1196,6 +1203,8 @@ err1: | |||
1196 | static void __exit arp_tables_fini(void) | 1203 | static void __exit arp_tables_fini(void) |
1197 | { | 1204 | { |
1198 | nf_unregister_sockopt(&arpt_sockopts); | 1205 | nf_unregister_sockopt(&arpt_sockopts); |
1206 | xt_unregister_target(&arpt_error_target); | ||
1207 | xt_unregister_target(&arpt_standard_target); | ||
1199 | xt_proto_fini(NF_ARP); | 1208 | xt_proto_fini(NF_ARP); |
1200 | } | 1209 | } |
1201 | 1210 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 53b6dffea6c2..262d0d44ec1b 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -44,13 +44,6 @@ MODULE_LICENSE("GPL"); | |||
44 | 44 | ||
45 | static char __initdata version[] = "0.90"; | 45 | static char __initdata version[] = "0.90"; |
46 | 46 | ||
47 | #if 0 | ||
48 | #define DEBUGP printk | ||
49 | #else | ||
50 | #define DEBUGP(format, args...) | ||
51 | #endif | ||
52 | |||
53 | |||
54 | static inline int | 47 | static inline int |
55 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, | 48 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, |
56 | const struct ip_conntrack_tuple *tuple, | 49 | const struct ip_conntrack_tuple *tuple, |
@@ -398,7 +391,6 @@ nfattr_failure: | |||
398 | 391 | ||
399 | static int ctnetlink_done(struct netlink_callback *cb) | 392 | static int ctnetlink_done(struct netlink_callback *cb) |
400 | { | 393 | { |
401 | DEBUGP("entered %s\n", __FUNCTION__); | ||
402 | if (cb->args[1]) | 394 | if (cb->args[1]) |
403 | ip_conntrack_put((struct ip_conntrack *)cb->args[1]); | 395 | ip_conntrack_put((struct ip_conntrack *)cb->args[1]); |
404 | return 0; | 396 | return 0; |
@@ -411,9 +403,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
411 | struct ip_conntrack_tuple_hash *h; | 403 | struct ip_conntrack_tuple_hash *h; |
412 | struct list_head *i; | 404 | struct list_head *i; |
413 | 405 | ||
414 | DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, | ||
415 | cb->args[0], *id); | ||
416 | |||
417 | read_lock_bh(&ip_conntrack_lock); | 406 | read_lock_bh(&ip_conntrack_lock); |
418 | last = (struct ip_conntrack *)cb->args[1]; | 407 | last = (struct ip_conntrack *)cb->args[1]; |
419 | for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) { | 408 | for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) { |
@@ -452,7 +441,6 @@ out: | |||
452 | if (last) | 441 | if (last) |
453 | ip_conntrack_put(last); | 442 | ip_conntrack_put(last); |
454 | 443 | ||
455 | DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); | ||
456 | return skb->len; | 444 | return skb->len; |
457 | } | 445 | } |
458 | 446 | ||
@@ -466,8 +454,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple) | |||
466 | { | 454 | { |
467 | struct nfattr *tb[CTA_IP_MAX]; | 455 | struct nfattr *tb[CTA_IP_MAX]; |
468 | 456 | ||
469 | DEBUGP("entered %s\n", __FUNCTION__); | ||
470 | |||
471 | nfattr_parse_nested(tb, CTA_IP_MAX, attr); | 457 | nfattr_parse_nested(tb, CTA_IP_MAX, attr); |
472 | 458 | ||
473 | if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) | 459 | 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) | |||
481 | return -EINVAL; | 467 | return -EINVAL; |
482 | tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]); | 468 | tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]); |
483 | 469 | ||
484 | DEBUGP("leaving\n"); | ||
485 | |||
486 | return 0; | 470 | return 0; |
487 | } | 471 | } |
488 | 472 | ||
@@ -503,8 +487,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr, | |||
503 | struct ip_conntrack_protocol *proto; | 487 | struct ip_conntrack_protocol *proto; |
504 | int ret = 0; | 488 | int ret = 0; |
505 | 489 | ||
506 | DEBUGP("entered %s\n", __FUNCTION__); | ||
507 | |||
508 | nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); | 490 | nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); |
509 | 491 | ||
510 | if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) | 492 | 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, | |||
531 | struct nfattr *tb[CTA_TUPLE_MAX]; | 513 | struct nfattr *tb[CTA_TUPLE_MAX]; |
532 | int err; | 514 | int err; |
533 | 515 | ||
534 | DEBUGP("entered %s\n", __FUNCTION__); | ||
535 | |||
536 | memset(tuple, 0, sizeof(*tuple)); | 516 | memset(tuple, 0, sizeof(*tuple)); |
537 | 517 | ||
538 | nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); | 518 | 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, | |||
557 | else | 537 | else |
558 | tuple->dst.dir = IP_CT_DIR_ORIGINAL; | 538 | tuple->dst.dir = IP_CT_DIR_ORIGINAL; |
559 | 539 | ||
560 | DUMP_TUPLE(tuple); | ||
561 | |||
562 | DEBUGP("leaving\n"); | ||
563 | |||
564 | return 0; | 540 | return 0; |
565 | } | 541 | } |
566 | 542 | ||
@@ -577,8 +553,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, | |||
577 | struct nfattr *tb[CTA_PROTONAT_MAX]; | 553 | struct nfattr *tb[CTA_PROTONAT_MAX]; |
578 | struct ip_nat_protocol *npt; | 554 | struct ip_nat_protocol *npt; |
579 | 555 | ||
580 | DEBUGP("entered %s\n", __FUNCTION__); | ||
581 | |||
582 | nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); | 556 | nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); |
583 | 557 | ||
584 | if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) | 558 | if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) |
@@ -597,7 +571,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, | |||
597 | 571 | ||
598 | ip_nat_proto_put(npt); | 572 | ip_nat_proto_put(npt); |
599 | 573 | ||
600 | DEBUGP("leaving\n"); | ||
601 | return 0; | 574 | return 0; |
602 | } | 575 | } |
603 | 576 | ||
@@ -613,8 +586,6 @@ ctnetlink_parse_nat(struct nfattr *nat, | |||
613 | struct nfattr *tb[CTA_NAT_MAX]; | 586 | struct nfattr *tb[CTA_NAT_MAX]; |
614 | int err; | 587 | int err; |
615 | 588 | ||
616 | DEBUGP("entered %s\n", __FUNCTION__); | ||
617 | |||
618 | memset(range, 0, sizeof(*range)); | 589 | memset(range, 0, sizeof(*range)); |
619 | 590 | ||
620 | nfattr_parse_nested(tb, CTA_NAT_MAX, nat); | 591 | nfattr_parse_nested(tb, CTA_NAT_MAX, nat); |
@@ -640,7 +611,6 @@ ctnetlink_parse_nat(struct nfattr *nat, | |||
640 | if (err < 0) | 611 | if (err < 0) |
641 | return err; | 612 | return err; |
642 | 613 | ||
643 | DEBUGP("leaving\n"); | ||
644 | return 0; | 614 | return 0; |
645 | } | 615 | } |
646 | #endif | 616 | #endif |
@@ -650,8 +620,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name) | |||
650 | { | 620 | { |
651 | struct nfattr *tb[CTA_HELP_MAX]; | 621 | struct nfattr *tb[CTA_HELP_MAX]; |
652 | 622 | ||
653 | DEBUGP("entered %s\n", __FUNCTION__); | ||
654 | |||
655 | nfattr_parse_nested(tb, CTA_HELP_MAX, attr); | 623 | nfattr_parse_nested(tb, CTA_HELP_MAX, attr); |
656 | 624 | ||
657 | if (!tb[CTA_HELP_NAME-1]) | 625 | if (!tb[CTA_HELP_NAME-1]) |
@@ -679,8 +647,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
679 | struct ip_conntrack *ct; | 647 | struct ip_conntrack *ct; |
680 | int err = 0; | 648 | int err = 0; |
681 | 649 | ||
682 | DEBUGP("entered %s\n", __FUNCTION__); | ||
683 | |||
684 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) | 650 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) |
685 | return -EINVAL; | 651 | return -EINVAL; |
686 | 652 | ||
@@ -698,10 +664,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
698 | return err; | 664 | return err; |
699 | 665 | ||
700 | h = ip_conntrack_find_get(&tuple, NULL); | 666 | h = ip_conntrack_find_get(&tuple, NULL); |
701 | if (!h) { | 667 | if (!h) |
702 | DEBUGP("tuple not found in conntrack hash\n"); | ||
703 | return -ENOENT; | 668 | return -ENOENT; |
704 | } | ||
705 | 669 | ||
706 | ct = tuplehash_to_ctrack(h); | 670 | ct = tuplehash_to_ctrack(h); |
707 | 671 | ||
@@ -716,7 +680,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
716 | ct->timeout.function((unsigned long)ct); | 680 | ct->timeout.function((unsigned long)ct); |
717 | 681 | ||
718 | ip_conntrack_put(ct); | 682 | ip_conntrack_put(ct); |
719 | DEBUGP("leaving\n"); | ||
720 | 683 | ||
721 | return 0; | 684 | return 0; |
722 | } | 685 | } |
@@ -731,8 +694,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
731 | struct sk_buff *skb2 = NULL; | 694 | struct sk_buff *skb2 = NULL; |
732 | int err = 0; | 695 | int err = 0; |
733 | 696 | ||
734 | DEBUGP("entered %s\n", __FUNCTION__); | ||
735 | |||
736 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 697 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
737 | struct nfgenmsg *msg = NLMSG_DATA(nlh); | 698 | struct nfgenmsg *msg = NLMSG_DATA(nlh); |
738 | u32 rlen; | 699 | u32 rlen; |
@@ -770,11 +731,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
770 | return err; | 731 | return err; |
771 | 732 | ||
772 | h = ip_conntrack_find_get(&tuple, NULL); | 733 | h = ip_conntrack_find_get(&tuple, NULL); |
773 | if (!h) { | 734 | if (!h) |
774 | DEBUGP("tuple not found in conntrack hash"); | ||
775 | return -ENOENT; | 735 | return -ENOENT; |
776 | } | 736 | |
777 | DEBUGP("tuple found\n"); | ||
778 | ct = tuplehash_to_ctrack(h); | 737 | ct = tuplehash_to_ctrack(h); |
779 | 738 | ||
780 | err = -ENOMEM; | 739 | err = -ENOMEM; |
@@ -795,7 +754,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
795 | if (err < 0) | 754 | if (err < 0) |
796 | goto out; | 755 | goto out; |
797 | 756 | ||
798 | DEBUGP("leaving\n"); | ||
799 | return 0; | 757 | return 0; |
800 | 758 | ||
801 | free: | 759 | free: |
@@ -866,8 +824,6 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[]) | |||
866 | char *helpname; | 824 | char *helpname; |
867 | int err; | 825 | int err; |
868 | 826 | ||
869 | DEBUGP("entered %s\n", __FUNCTION__); | ||
870 | |||
871 | /* don't change helper of sibling connections */ | 827 | /* don't change helper of sibling connections */ |
872 | if (ct->master) | 828 | if (ct->master) |
873 | return -EINVAL; | 829 | return -EINVAL; |
@@ -938,8 +894,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) | |||
938 | { | 894 | { |
939 | int err; | 895 | int err; |
940 | 896 | ||
941 | DEBUGP("entered %s\n", __FUNCTION__); | ||
942 | |||
943 | if (cda[CTA_HELP-1]) { | 897 | if (cda[CTA_HELP-1]) { |
944 | err = ctnetlink_change_helper(ct, cda); | 898 | err = ctnetlink_change_helper(ct, cda); |
945 | if (err < 0) | 899 | if (err < 0) |
@@ -969,7 +923,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) | |||
969 | ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); | 923 | ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); |
970 | #endif | 924 | #endif |
971 | 925 | ||
972 | DEBUGP("all done\n"); | ||
973 | return 0; | 926 | return 0; |
974 | } | 927 | } |
975 | 928 | ||
@@ -981,8 +934,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
981 | struct ip_conntrack *ct; | 934 | struct ip_conntrack *ct; |
982 | int err = -EINVAL; | 935 | int err = -EINVAL; |
983 | 936 | ||
984 | DEBUGP("entered %s\n", __FUNCTION__); | ||
985 | |||
986 | ct = ip_conntrack_alloc(otuple, rtuple); | 937 | ct = ip_conntrack_alloc(otuple, rtuple); |
987 | if (ct == NULL || IS_ERR(ct)) | 938 | if (ct == NULL || IS_ERR(ct)) |
988 | return -ENOMEM; | 939 | return -ENOMEM; |
@@ -1017,7 +968,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
1017 | if (ct->helper) | 968 | if (ct->helper) |
1018 | ip_conntrack_helper_put(ct->helper); | 969 | ip_conntrack_helper_put(ct->helper); |
1019 | 970 | ||
1020 | DEBUGP("conntrack with id %u inserted\n", ct->id); | ||
1021 | return 0; | 971 | return 0; |
1022 | 972 | ||
1023 | err: | 973 | err: |
@@ -1033,8 +983,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1033 | struct ip_conntrack_tuple_hash *h = NULL; | 983 | struct ip_conntrack_tuple_hash *h = NULL; |
1034 | int err = 0; | 984 | int err = 0; |
1035 | 985 | ||
1036 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1037 | |||
1038 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) | 986 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) |
1039 | return -EINVAL; | 987 | return -EINVAL; |
1040 | 988 | ||
@@ -1058,7 +1006,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1058 | 1006 | ||
1059 | if (h == NULL) { | 1007 | if (h == NULL) { |
1060 | write_unlock_bh(&ip_conntrack_lock); | 1008 | write_unlock_bh(&ip_conntrack_lock); |
1061 | DEBUGP("no such conntrack, create new\n"); | ||
1062 | err = -ENOENT; | 1009 | err = -ENOENT; |
1063 | if (nlh->nlmsg_flags & NLM_F_CREATE) | 1010 | if (nlh->nlmsg_flags & NLM_F_CREATE) |
1064 | err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); | 1011 | err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); |
@@ -1074,7 +1021,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1074 | 1021 | ||
1075 | /* We manipulate the conntrack inside the global conntrack table lock, | 1022 | /* We manipulate the conntrack inside the global conntrack table lock, |
1076 | * so there's no need to increase the refcount */ | 1023 | * so there's no need to increase the refcount */ |
1077 | DEBUGP("conntrack found\n"); | ||
1078 | err = -EEXIST; | 1024 | err = -EEXIST; |
1079 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) | 1025 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) |
1080 | err = ctnetlink_change_conntrack(tuplehash_to_ctrack(h), cda); | 1026 | 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) | |||
1249 | struct list_head *i; | 1195 | struct list_head *i; |
1250 | u_int32_t *id = (u_int32_t *) &cb->args[0]; | 1196 | u_int32_t *id = (u_int32_t *) &cb->args[0]; |
1251 | 1197 | ||
1252 | DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id); | ||
1253 | |||
1254 | read_lock_bh(&ip_conntrack_lock); | 1198 | read_lock_bh(&ip_conntrack_lock); |
1255 | list_for_each_prev(i, &ip_conntrack_expect_list) { | 1199 | list_for_each_prev(i, &ip_conntrack_expect_list) { |
1256 | exp = (struct ip_conntrack_expect *) i; | 1200 | exp = (struct ip_conntrack_expect *) i; |
@@ -1266,8 +1210,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
1266 | out: | 1210 | out: |
1267 | read_unlock_bh(&ip_conntrack_lock); | 1211 | read_unlock_bh(&ip_conntrack_lock); |
1268 | 1212 | ||
1269 | DEBUGP("leaving, last id=%llu\n", *id); | ||
1270 | |||
1271 | return skb->len; | 1213 | return skb->len; |
1272 | } | 1214 | } |
1273 | 1215 | ||
@@ -1285,8 +1227,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1285 | struct sk_buff *skb2; | 1227 | struct sk_buff *skb2; |
1286 | int err = 0; | 1228 | int err = 0; |
1287 | 1229 | ||
1288 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1289 | |||
1290 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) | 1230 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) |
1291 | return -EINVAL; | 1231 | return -EINVAL; |
1292 | 1232 | ||
@@ -1437,8 +1377,6 @@ ctnetlink_create_expect(struct nfattr *cda[]) | |||
1437 | struct ip_conntrack *ct; | 1377 | struct ip_conntrack *ct; |
1438 | int err = 0; | 1378 | int err = 0; |
1439 | 1379 | ||
1440 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1441 | |||
1442 | /* caller guarantees that those three CTA_EXPECT_* exist */ | 1380 | /* caller guarantees that those three CTA_EXPECT_* exist */ |
1443 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); | 1381 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); |
1444 | if (err < 0) | 1382 | if (err < 0) |
@@ -1490,8 +1428,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1490 | struct ip_conntrack_expect *exp; | 1428 | struct ip_conntrack_expect *exp; |
1491 | int err = 0; | 1429 | int err = 0; |
1492 | 1430 | ||
1493 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1494 | |||
1495 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) | 1431 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) |
1496 | return -EINVAL; | 1432 | return -EINVAL; |
1497 | 1433 | ||
@@ -1520,8 +1456,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1520 | err = ctnetlink_change_expect(exp, cda); | 1456 | err = ctnetlink_change_expect(exp, cda); |
1521 | write_unlock_bh(&ip_conntrack_lock); | 1457 | write_unlock_bh(&ip_conntrack_lock); |
1522 | 1458 | ||
1523 | DEBUGP("leaving\n"); | ||
1524 | |||
1525 | return err; | 1459 | return err; |
1526 | } | 1460 | } |
1527 | 1461 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 7edad790478a..97556cc2e4e0 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -351,9 +351,10 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
351 | if (v->data_len < sizeof(*user_iph)) | 351 | if (v->data_len < sizeof(*user_iph)) |
352 | return 0; | 352 | return 0; |
353 | diff = v->data_len - e->skb->len; | 353 | diff = v->data_len - e->skb->len; |
354 | if (diff < 0) | 354 | if (diff < 0) { |
355 | skb_trim(e->skb, v->data_len); | 355 | if (pskb_trim(e->skb, v->data_len)) |
356 | else if (diff > 0) { | 356 | return -ENOMEM; |
357 | } else if (diff > 0) { | ||
357 | if (v->data_len > 0xFFFF) | 358 | if (v->data_len > 0xFFFF) |
358 | return -EINVAL; | 359 | return -EINVAL; |
359 | if (diff > skb_tailroom(e->skb)) { | 360 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 78a44b01c035..8a455439b128 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -547,12 +547,18 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
547 | return -EINVAL; | 547 | return -EINVAL; |
548 | } | 548 | } |
549 | 549 | ||
550 | if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset) | ||
551 | return -EINVAL; | ||
552 | |||
550 | j = 0; | 553 | j = 0; |
551 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); | 554 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); |
552 | if (ret != 0) | 555 | if (ret != 0) |
553 | goto cleanup_matches; | 556 | goto cleanup_matches; |
554 | 557 | ||
555 | t = ipt_get_target(e); | 558 | t = ipt_get_target(e); |
559 | ret = -EINVAL; | ||
560 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
561 | goto cleanup_matches; | ||
556 | target = try_then_request_module(xt_find_target(AF_INET, | 562 | target = try_then_request_module(xt_find_target(AF_INET, |
557 | t->u.user.name, | 563 | t->u.user.name, |
558 | t->u.user.revision), | 564 | t->u.user.revision), |
@@ -712,19 +718,17 @@ translate_table(const char *name, | |||
712 | } | 718 | } |
713 | } | 719 | } |
714 | 720 | ||
715 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
716 | return -ELOOP; | ||
717 | |||
718 | /* Finally, each sanity check must pass */ | 721 | /* Finally, each sanity check must pass */ |
719 | i = 0; | 722 | i = 0; |
720 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 723 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
721 | check_entry, name, size, &i); | 724 | check_entry, name, size, &i); |
722 | 725 | ||
723 | if (ret != 0) { | 726 | if (ret != 0) |
724 | IPT_ENTRY_ITERATE(entry0, newinfo->size, | 727 | goto cleanup; |
725 | cleanup_entry, &i); | 728 | |
726 | return ret; | 729 | ret = -ELOOP; |
727 | } | 730 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
731 | goto cleanup; | ||
728 | 732 | ||
729 | /* And one copy for every other CPU */ | 733 | /* And one copy for every other CPU */ |
730 | for_each_possible_cpu(i) { | 734 | for_each_possible_cpu(i) { |
@@ -732,6 +736,9 @@ translate_table(const char *name, | |||
732 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 736 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
733 | } | 737 | } |
734 | 738 | ||
739 | return 0; | ||
740 | cleanup: | ||
741 | IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
735 | return ret; | 742 | return ret; |
736 | } | 743 | } |
737 | 744 | ||
@@ -1463,6 +1470,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1463 | return -EINVAL; | 1470 | return -EINVAL; |
1464 | } | 1471 | } |
1465 | 1472 | ||
1473 | if (e->target_offset + sizeof(struct compat_xt_entry_target) > | ||
1474 | e->next_offset) | ||
1475 | return -EINVAL; | ||
1476 | |||
1466 | off = 0; | 1477 | off = 0; |
1467 | entry_offset = (void *)e - (void *)base; | 1478 | entry_offset = (void *)e - (void *)base; |
1468 | j = 0; | 1479 | j = 0; |
@@ -1472,6 +1483,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1472 | goto cleanup_matches; | 1483 | goto cleanup_matches; |
1473 | 1484 | ||
1474 | t = ipt_get_target(e); | 1485 | t = ipt_get_target(e); |
1486 | ret = -EINVAL; | ||
1487 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
1488 | goto cleanup_matches; | ||
1475 | target = try_then_request_module(xt_find_target(AF_INET, | 1489 | target = try_then_request_module(xt_find_target(AF_INET, |
1476 | t->u.user.name, | 1490 | t->u.user.name, |
1477 | t->u.user.revision), | 1491 | t->u.user.revision), |
@@ -1513,7 +1527,7 @@ cleanup_matches: | |||
1513 | 1527 | ||
1514 | static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | 1528 | static inline int compat_copy_match_from_user(struct ipt_entry_match *m, |
1515 | void **dstptr, compat_uint_t *size, const char *name, | 1529 | void **dstptr, compat_uint_t *size, const char *name, |
1516 | const struct ipt_ip *ip, unsigned int hookmask, int *i) | 1530 | const struct ipt_ip *ip, unsigned int hookmask) |
1517 | { | 1531 | { |
1518 | struct ipt_entry_match *dm; | 1532 | struct ipt_entry_match *dm; |
1519 | struct ipt_match *match; | 1533 | struct ipt_match *match; |
@@ -1526,22 +1540,13 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | |||
1526 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), | 1540 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), |
1527 | name, hookmask, ip->proto, | 1541 | name, hookmask, ip->proto, |
1528 | ip->invflags & IPT_INV_PROTO); | 1542 | ip->invflags & IPT_INV_PROTO); |
1529 | if (ret) | 1543 | if (!ret && m->u.kernel.match->checkentry |
1530 | goto err; | ||
1531 | |||
1532 | if (m->u.kernel.match->checkentry | ||
1533 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, | 1544 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, |
1534 | hookmask)) { | 1545 | hookmask)) { |
1535 | duprintf("ip_tables: check failed for `%s'.\n", | 1546 | duprintf("ip_tables: check failed for `%s'.\n", |
1536 | m->u.kernel.match->name); | 1547 | m->u.kernel.match->name); |
1537 | ret = -EINVAL; | 1548 | ret = -EINVAL; |
1538 | goto err; | ||
1539 | } | 1549 | } |
1540 | (*i)++; | ||
1541 | return 0; | ||
1542 | |||
1543 | err: | ||
1544 | module_put(m->u.kernel.match->me); | ||
1545 | return ret; | 1550 | return ret; |
1546 | } | 1551 | } |
1547 | 1552 | ||
@@ -1553,19 +1558,18 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1553 | struct ipt_target *target; | 1558 | struct ipt_target *target; |
1554 | struct ipt_entry *de; | 1559 | struct ipt_entry *de; |
1555 | unsigned int origsize; | 1560 | unsigned int origsize; |
1556 | int ret, h, j; | 1561 | int ret, h; |
1557 | 1562 | ||
1558 | ret = 0; | 1563 | ret = 0; |
1559 | origsize = *size; | 1564 | origsize = *size; |
1560 | de = (struct ipt_entry *)*dstptr; | 1565 | de = (struct ipt_entry *)*dstptr; |
1561 | memcpy(de, e, sizeof(struct ipt_entry)); | 1566 | memcpy(de, e, sizeof(struct ipt_entry)); |
1562 | 1567 | ||
1563 | j = 0; | ||
1564 | *dstptr += sizeof(struct compat_ipt_entry); | 1568 | *dstptr += sizeof(struct compat_ipt_entry); |
1565 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, | 1569 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, |
1566 | name, &de->ip, de->comefrom, &j); | 1570 | name, &de->ip, de->comefrom); |
1567 | if (ret) | 1571 | if (ret) |
1568 | goto cleanup_matches; | 1572 | goto err; |
1569 | de->target_offset = e->target_offset - (origsize - *size); | 1573 | de->target_offset = e->target_offset - (origsize - *size); |
1570 | t = ipt_get_target(e); | 1574 | t = ipt_get_target(e); |
1571 | target = t->u.kernel.target; | 1575 | target = t->u.kernel.target; |
@@ -1599,12 +1603,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1599 | goto err; | 1603 | goto err; |
1600 | } | 1604 | } |
1601 | ret = 0; | 1605 | ret = 0; |
1602 | return ret; | ||
1603 | |||
1604 | err: | 1606 | err: |
1605 | module_put(t->u.kernel.target->me); | ||
1606 | cleanup_matches: | ||
1607 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
1608 | return ret; | 1607 | return ret; |
1609 | } | 1608 | } |
1610 | 1609 | ||
@@ -1618,7 +1617,7 @@ translate_compat_table(const char *name, | |||
1618 | unsigned int *hook_entries, | 1617 | unsigned int *hook_entries, |
1619 | unsigned int *underflows) | 1618 | unsigned int *underflows) |
1620 | { | 1619 | { |
1621 | unsigned int i; | 1620 | unsigned int i, j; |
1622 | struct xt_table_info *newinfo, *info; | 1621 | struct xt_table_info *newinfo, *info; |
1623 | void *pos, *entry0, *entry1; | 1622 | void *pos, *entry0, *entry1; |
1624 | unsigned int size; | 1623 | unsigned int size; |
@@ -1636,21 +1635,21 @@ translate_compat_table(const char *name, | |||
1636 | } | 1635 | } |
1637 | 1636 | ||
1638 | duprintf("translate_compat_table: size %u\n", info->size); | 1637 | duprintf("translate_compat_table: size %u\n", info->size); |
1639 | i = 0; | 1638 | j = 0; |
1640 | xt_compat_lock(AF_INET); | 1639 | xt_compat_lock(AF_INET); |
1641 | /* Walk through entries, checking offsets. */ | 1640 | /* Walk through entries, checking offsets. */ |
1642 | ret = IPT_ENTRY_ITERATE(entry0, total_size, | 1641 | ret = IPT_ENTRY_ITERATE(entry0, total_size, |
1643 | check_compat_entry_size_and_hooks, | 1642 | check_compat_entry_size_and_hooks, |
1644 | info, &size, entry0, | 1643 | info, &size, entry0, |
1645 | entry0 + total_size, | 1644 | entry0 + total_size, |
1646 | hook_entries, underflows, &i, name); | 1645 | hook_entries, underflows, &j, name); |
1647 | if (ret != 0) | 1646 | if (ret != 0) |
1648 | goto out_unlock; | 1647 | goto out_unlock; |
1649 | 1648 | ||
1650 | ret = -EINVAL; | 1649 | ret = -EINVAL; |
1651 | if (i != number) { | 1650 | if (j != number) { |
1652 | duprintf("translate_compat_table: %u not %u entries\n", | 1651 | duprintf("translate_compat_table: %u not %u entries\n", |
1653 | i, number); | 1652 | j, number); |
1654 | goto out_unlock; | 1653 | goto out_unlock; |
1655 | } | 1654 | } |
1656 | 1655 | ||
@@ -1709,8 +1708,10 @@ translate_compat_table(const char *name, | |||
1709 | free_newinfo: | 1708 | free_newinfo: |
1710 | xt_free_table_info(newinfo); | 1709 | xt_free_table_info(newinfo); |
1711 | out: | 1710 | out: |
1711 | IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); | ||
1712 | return ret; | 1712 | return ret; |
1713 | out_unlock: | 1713 | out_unlock: |
1714 | compat_flush_offsets(); | ||
1714 | xt_compat_unlock(AF_INET); | 1715 | xt_compat_unlock(AF_INET); |
1715 | goto out; | 1716 | goto out; |
1716 | } | 1717 | } |
@@ -1932,6 +1933,9 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1932 | { | 1933 | { |
1933 | int ret; | 1934 | int ret; |
1934 | 1935 | ||
1936 | if (!capable(CAP_NET_ADMIN)) | ||
1937 | return -EPERM; | ||
1938 | |||
1935 | switch (cmd) { | 1939 | switch (cmd) { |
1936 | case IPT_SO_GET_INFO: | 1940 | case IPT_SO_GET_INFO: |
1937 | ret = get_info(user, len, 1); | 1941 | ret = get_info(user, len, 1); |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index 12a818a2462f..1aa4517fbcdb 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -28,7 +28,7 @@ static inline int | |||
28 | set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) | 28 | set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) |
29 | { | 29 | { |
30 | struct iphdr *iph = (*pskb)->nh.iph; | 30 | struct iphdr *iph = (*pskb)->nh.iph; |
31 | __be16 oldtos; | 31 | u_int16_t oldtos; |
32 | 32 | ||
33 | if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { | 33 | if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { |
34 | if (!skb_make_writable(pskb, sizeof(struct iphdr))) | 34 | 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) | |||
37 | oldtos = iph->tos; | 37 | oldtos = iph->tos; |
38 | iph->tos &= ~IPT_ECN_IP_MASK; | 38 | iph->tos &= ~IPT_ECN_IP_MASK; |
39 | iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); | 39 | iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); |
40 | iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, | 40 | iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), |
41 | iph->check); | 41 | htons(iph->tos), iph->check); |
42 | } | 42 | } |
43 | return 1; | 43 | return 1; |
44 | } | 44 | } |
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c index 6b8b14ccc3d3..83b80b3a5d2f 100644 --- a/net/ipv4/netfilter/ipt_TOS.c +++ b/net/ipv4/netfilter/ipt_TOS.c | |||
@@ -30,7 +30,7 @@ target(struct sk_buff **pskb, | |||
30 | { | 30 | { |
31 | const struct ipt_tos_target_info *tosinfo = targinfo; | 31 | const struct ipt_tos_target_info *tosinfo = targinfo; |
32 | struct iphdr *iph = (*pskb)->nh.iph; | 32 | struct iphdr *iph = (*pskb)->nh.iph; |
33 | __be16 oldtos; | 33 | u_int16_t oldtos; |
34 | 34 | ||
35 | if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { | 35 | if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { |
36 | if (!skb_make_writable(pskb, sizeof(struct iphdr))) | 36 | if (!skb_make_writable(pskb, sizeof(struct iphdr))) |
@@ -38,8 +38,8 @@ target(struct sk_buff **pskb, | |||
38 | iph = (*pskb)->nh.iph; | 38 | iph = (*pskb)->nh.iph; |
39 | oldtos = iph->tos; | 39 | oldtos = iph->tos; |
40 | iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; | 40 | iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; |
41 | iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, | 41 | iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), |
42 | iph->check); | 42 | htons(iph->tos), iph->check); |
43 | } | 43 | } |
44 | return IPT_CONTINUE; | 44 | return IPT_CONTINUE; |
45 | } | 45 | } |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b430cf2a4f66..5c31dead2bdc 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -329,7 +329,7 @@ error: | |||
329 | return err; | 329 | return err; |
330 | } | 330 | } |
331 | 331 | ||
332 | static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 332 | static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) |
333 | { | 333 | { |
334 | struct iovec *iov; | 334 | struct iovec *iov; |
335 | u8 __user *type = NULL; | 335 | u8 __user *type = NULL; |
@@ -338,7 +338,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
338 | unsigned int i; | 338 | unsigned int i; |
339 | 339 | ||
340 | if (!msg->msg_iov) | 340 | if (!msg->msg_iov) |
341 | return; | 341 | return 0; |
342 | 342 | ||
343 | for (i = 0; i < msg->msg_iovlen; i++) { | 343 | for (i = 0; i < msg->msg_iovlen; i++) { |
344 | iov = &msg->msg_iov[i]; | 344 | iov = &msg->msg_iov[i]; |
@@ -360,8 +360,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
360 | code = iov->iov_base; | 360 | code = iov->iov_base; |
361 | 361 | ||
362 | if (type && code) { | 362 | if (type && code) { |
363 | get_user(fl->fl_icmp_type, type); | 363 | if (get_user(fl->fl_icmp_type, type) || |
364 | get_user(fl->fl_icmp_code, code); | 364 | get_user(fl->fl_icmp_code, code)) |
365 | return -EFAULT; | ||
365 | probed = 1; | 366 | probed = 1; |
366 | } | 367 | } |
367 | break; | 368 | break; |
@@ -372,6 +373,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
372 | if (probed) | 373 | if (probed) |
373 | break; | 374 | break; |
374 | } | 375 | } |
376 | return 0; | ||
375 | } | 377 | } |
376 | 378 | ||
377 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 379 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
@@ -480,8 +482,11 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
480 | .proto = inet->hdrincl ? IPPROTO_RAW : | 482 | .proto = inet->hdrincl ? IPPROTO_RAW : |
481 | sk->sk_protocol, | 483 | sk->sk_protocol, |
482 | }; | 484 | }; |
483 | if (!inet->hdrincl) | 485 | if (!inet->hdrincl) { |
484 | raw_probe_proto_opt(&fl, msg); | 486 | err = raw_probe_proto_opt(&fl, msg); |
487 | if (err) | ||
488 | goto done; | ||
489 | } | ||
485 | 490 | ||
486 | security_sk_classify_flow(sk, &fl); | 491 | security_sk_classify_flow(sk, &fl); |
487 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); | 492 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c41ddba02e9d..925ee4dfc32c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -566,9 +566,15 @@ static inline u32 rt_score(struct rtable *rt) | |||
566 | 566 | ||
567 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 567 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) |
568 | { | 568 | { |
569 | return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 && | 569 | return ((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | |
570 | fl1->oif == fl2->oif && | 570 | (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) | |
571 | fl1->iif == fl2->iif; | 571 | #ifdef CONFIG_IP_ROUTE_FWMARK |
572 | (fl1->nl_u.ip4_u.fwmark ^ fl2->nl_u.ip4_u.fwmark) | | ||
573 | #endif | ||
574 | (*(u16 *)&fl1->nl_u.ip4_u.tos ^ | ||
575 | *(u16 *)&fl2->nl_u.ip4_u.tos) | | ||
576 | (fl1->oif ^ fl2->oif) | | ||
577 | (fl1->iif ^ fl2->iif)) == 0; | ||
572 | } | 578 | } |
573 | 579 | ||
574 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | 580 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e82a5be894b5..15061b314411 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -129,13 +129,6 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, | |||
129 | return ret; | 129 | return ret; |
130 | } | 130 | } |
131 | 131 | ||
132 | static int __init tcp_congestion_default(void) | ||
133 | { | ||
134 | return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); | ||
135 | } | ||
136 | |||
137 | late_initcall(tcp_congestion_default); | ||
138 | |||
139 | ctl_table ipv4_table[] = { | 132 | ctl_table ipv4_table[] = { |
140 | { | 133 | { |
141 | .ctl_name = NET_IPV4_TCP_TIMESTAMPS, | 134 | .ctl_name = NET_IPV4_TCP_TIMESTAMPS, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 66e9a729f6df..c05e8edaf544 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2270,7 +2270,7 @@ void __init tcp_init(void) | |||
2270 | thash_entries, | 2270 | thash_entries, |
2271 | (num_physpages >= 128 * 1024) ? | 2271 | (num_physpages >= 128 * 1024) ? |
2272 | 13 : 15, | 2272 | 13 : 15, |
2273 | HASH_HIGHMEM, | 2273 | 0, |
2274 | &tcp_hashinfo.ehash_size, | 2274 | &tcp_hashinfo.ehash_size, |
2275 | NULL, | 2275 | NULL, |
2276 | 0); | 2276 | 0); |
@@ -2286,7 +2286,7 @@ void __init tcp_init(void) | |||
2286 | tcp_hashinfo.ehash_size, | 2286 | tcp_hashinfo.ehash_size, |
2287 | (num_physpages >= 128 * 1024) ? | 2287 | (num_physpages >= 128 * 1024) ? |
2288 | 13 : 15, | 2288 | 13 : 15, |
2289 | HASH_HIGHMEM, | 2289 | 0, |
2290 | &tcp_hashinfo.bhash_size, | 2290 | &tcp_hashinfo.bhash_size, |
2291 | NULL, | 2291 | NULL, |
2292 | 64 * 1024); | 2292 | 64 * 1024); |
@@ -2316,9 +2316,10 @@ void __init tcp_init(void) | |||
2316 | sysctl_max_syn_backlog = 128; | 2316 | sysctl_max_syn_backlog = 128; |
2317 | } | 2317 | } |
2318 | 2318 | ||
2319 | sysctl_tcp_mem[0] = 768 << order; | 2319 | /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ |
2320 | sysctl_tcp_mem[1] = 1024 << order; | 2320 | sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; |
2321 | sysctl_tcp_mem[2] = 1536 << order; | 2321 | sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; |
2322 | sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; | ||
2322 | 2323 | ||
2323 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); | 2324 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); |
2324 | max_share = min(4UL*1024*1024, limit); | 2325 | max_share = min(4UL*1024*1024, limit); |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index af0aca1e6be6..1e2982f4acd4 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -131,6 +131,14 @@ int tcp_set_default_congestion_control(const char *name) | |||
131 | return ret; | 131 | return ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* Set default value from kernel configuration at bootup */ | ||
135 | static int __init tcp_congestion_default(void) | ||
136 | { | ||
137 | return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); | ||
138 | } | ||
139 | late_initcall(tcp_congestion_default); | ||
140 | |||
141 | |||
134 | /* Get current default congestion control */ | 142 | /* Get current default congestion control */ |
135 | void tcp_get_default_congestion_control(char *name) | 143 | void tcp_get_default_congestion_control(char *name) |
136 | { | 144 | { |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index a60ef38d75c6..6ad184802266 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
@@ -190,7 +190,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) | |||
190 | */ | 190 | */ |
191 | 191 | ||
192 | /* change the unit from HZ to bictcp_HZ */ | 192 | /* change the unit from HZ to bictcp_HZ */ |
193 | t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start) | 193 | t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start) |
194 | << BICTCP_HZ) / HZ; | 194 | << BICTCP_HZ) / HZ; |
195 | 195 | ||
196 | if (t < ca->bic_K) /* t - K */ | 196 | if (t < ca->bic_K) /* t - K */ |
@@ -259,7 +259,7 @@ static inline void measure_delay(struct sock *sk) | |||
259 | (s32)(tcp_time_stamp - ca->epoch_start) < HZ) | 259 | (s32)(tcp_time_stamp - ca->epoch_start) < HZ) |
260 | return; | 260 | return; |
261 | 261 | ||
262 | delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; | 262 | delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3; |
263 | if (delay == 0) | 263 | if (delay == 0) |
264 | delay = 1; | 264 | delay = 1; |
265 | 265 | ||
@@ -366,7 +366,7 @@ static int __init cubictcp_register(void) | |||
366 | 366 | ||
367 | beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); | 367 | beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); |
368 | 368 | ||
369 | cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */ | 369 | cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */ |
370 | 370 | ||
371 | /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 | 371 | /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 |
372 | * so K = cubic_root( (wmax-cwnd)*rtt/c ) | 372 | * so K = cubic_root( (wmax-cwnd)*rtt/c ) |
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 682e7d5b6f2f..283be3cb4667 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c | |||
@@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, 0644); | |||
23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); | 23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); |
24 | 24 | ||
25 | struct htcp { | 25 | struct htcp { |
26 | u16 alpha; /* Fixed point arith, << 7 */ | 26 | u32 alpha; /* Fixed point arith, << 7 */ |
27 | u8 beta; /* Fixed point arith, << 7 */ | 27 | u8 beta; /* Fixed point arith, << 7 */ |
28 | u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ | 28 | u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ |
29 | u32 last_cong; /* Time since last congestion event end */ | 29 | u32 last_cong; /* Time since last congestion event end */ |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c83938b8fcb1..22ef8bd26620 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -355,7 +355,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
355 | return; | 355 | return; |
356 | } | 356 | } |
357 | if (sk->sk_state == TCP_TIME_WAIT) { | 357 | if (sk->sk_state == TCP_TIME_WAIT) { |
358 | inet_twsk_put((struct inet_timewait_sock *)sk); | 358 | inet_twsk_put(inet_twsk(sk)); |
359 | return; | 359 | return; |
360 | } | 360 | } |
361 | 361 | ||
@@ -373,7 +373,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
373 | seq = ntohl(th->seq); | 373 | seq = ntohl(th->seq); |
374 | if (sk->sk_state != TCP_LISTEN && | 374 | if (sk->sk_state != TCP_LISTEN && |
375 | !between(seq, tp->snd_una, tp->snd_nxt)) { | 375 | !between(seq, tp->snd_una, tp->snd_nxt)) { |
376 | NET_INC_STATS(LINUX_MIB_OUTOFWINDOWICMPS); | 376 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); |
377 | goto out; | 377 | goto out; |
378 | } | 378 | } |
379 | 379 | ||
@@ -578,7 +578,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | |||
578 | struct tcphdr *th = skb->h.th; | 578 | struct tcphdr *th = skb->h.th; |
579 | struct { | 579 | struct { |
580 | struct tcphdr th; | 580 | struct tcphdr th; |
581 | u32 tsopt[3]; | 581 | u32 tsopt[TCPOLEN_TSTAMP_ALIGNED >> 2]; |
582 | } rep; | 582 | } rep; |
583 | struct ip_reply_arg arg; | 583 | struct ip_reply_arg arg; |
584 | 584 | ||
@@ -960,7 +960,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
960 | bh_lock_sock(nsk); | 960 | bh_lock_sock(nsk); |
961 | return nsk; | 961 | return nsk; |
962 | } | 962 | } |
963 | inet_twsk_put((struct inet_timewait_sock *)nsk); | 963 | inet_twsk_put(inet_twsk(nsk)); |
964 | return NULL; | 964 | return NULL; |
965 | } | 965 | } |
966 | 966 | ||
@@ -1154,26 +1154,24 @@ discard_and_relse: | |||
1154 | 1154 | ||
1155 | do_time_wait: | 1155 | do_time_wait: |
1156 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 1156 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
1157 | inet_twsk_put((struct inet_timewait_sock *) sk); | 1157 | inet_twsk_put(inet_twsk(sk)); |
1158 | goto discard_it; | 1158 | goto discard_it; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { | 1161 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { |
1162 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1162 | TCP_INC_STATS_BH(TCP_MIB_INERRS); |
1163 | inet_twsk_put((struct inet_timewait_sock *) sk); | 1163 | inet_twsk_put(inet_twsk(sk)); |
1164 | goto discard_it; | 1164 | goto discard_it; |
1165 | } | 1165 | } |
1166 | switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, | 1166 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
1167 | skb, th)) { | ||
1168 | case TCP_TW_SYN: { | 1167 | case TCP_TW_SYN: { |
1169 | struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, | 1168 | struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, |
1170 | skb->nh.iph->daddr, | 1169 | skb->nh.iph->daddr, |
1171 | th->dest, | 1170 | th->dest, |
1172 | inet_iif(skb)); | 1171 | inet_iif(skb)); |
1173 | if (sk2) { | 1172 | if (sk2) { |
1174 | inet_twsk_deschedule((struct inet_timewait_sock *)sk, | 1173 | inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); |
1175 | &tcp_death_row); | 1174 | inet_twsk_put(inet_twsk(sk)); |
1176 | inet_twsk_put((struct inet_timewait_sock *)sk); | ||
1177 | sk = sk2; | 1175 | sk = sk2; |
1178 | goto process; | 1176 | goto process; |
1179 | } | 1177 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9a253faefc81..ca406157724c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -273,10 +273,10 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, | |||
273 | __u32 tstamp) | 273 | __u32 tstamp) |
274 | { | 274 | { |
275 | if (tp->rx_opt.tstamp_ok) { | 275 | if (tp->rx_opt.tstamp_ok) { |
276 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | 276 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
277 | (TCPOPT_NOP << 16) | | 277 | (TCPOPT_NOP << 16) | |
278 | (TCPOPT_TIMESTAMP << 8) | | 278 | (TCPOPT_TIMESTAMP << 8) | |
279 | TCPOLEN_TIMESTAMP); | 279 | TCPOLEN_TIMESTAMP); |
280 | *ptr++ = htonl(tstamp); | 280 | *ptr++ = htonl(tstamp); |
281 | *ptr++ = htonl(tp->rx_opt.ts_recent); | 281 | *ptr++ = htonl(tp->rx_opt.ts_recent); |
282 | } | 282 | } |
@@ -325,18 +325,27 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack, | |||
325 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | 325 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); |
326 | if (ts) { | 326 | if (ts) { |
327 | if(sack) | 327 | if(sack) |
328 | *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | | 328 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | |
329 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 329 | (TCPOLEN_SACK_PERM << 16) | |
330 | (TCPOPT_TIMESTAMP << 8) | | ||
331 | TCPOLEN_TIMESTAMP); | ||
330 | else | 332 | else |
331 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 333 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
332 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 334 | (TCPOPT_NOP << 16) | |
335 | (TCPOPT_TIMESTAMP << 8) | | ||
336 | TCPOLEN_TIMESTAMP); | ||
333 | *ptr++ = htonl(tstamp); /* TSVAL */ | 337 | *ptr++ = htonl(tstamp); /* TSVAL */ |
334 | *ptr++ = htonl(ts_recent); /* TSECR */ | 338 | *ptr++ = htonl(ts_recent); /* TSECR */ |
335 | } else if(sack) | 339 | } else if(sack) |
336 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 340 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
337 | (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); | 341 | (TCPOPT_NOP << 16) | |
342 | (TCPOPT_SACK_PERM << 8) | | ||
343 | TCPOLEN_SACK_PERM); | ||
338 | if (offer_wscale) | 344 | if (offer_wscale) |
339 | *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); | 345 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
346 | (TCPOPT_WINDOW << 16) | | ||
347 | (TCPOLEN_WINDOW << 8) | | ||
348 | (wscale)); | ||
340 | } | 349 | } |
341 | 350 | ||
342 | /* This routine actually transmits TCP packets queued in by | 351 | /* This routine actually transmits TCP packets queued in by |
@@ -1087,10 +1096,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1087 | u32 send_win, cong_win, limit, in_flight; | 1096 | u32 send_win, cong_win, limit, in_flight; |
1088 | 1097 | ||
1089 | if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) | 1098 | if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) |
1090 | return 0; | 1099 | goto send_now; |
1091 | 1100 | ||
1092 | if (icsk->icsk_ca_state != TCP_CA_Open) | 1101 | if (icsk->icsk_ca_state != TCP_CA_Open) |
1093 | return 0; | 1102 | goto send_now; |
1103 | |||
1104 | /* Defer for less than two clock ticks. */ | ||
1105 | if (!tp->tso_deferred && ((jiffies<<1)>>1) - (tp->tso_deferred>>1) > 1) | ||
1106 | goto send_now; | ||
1094 | 1107 | ||
1095 | in_flight = tcp_packets_in_flight(tp); | 1108 | in_flight = tcp_packets_in_flight(tp); |
1096 | 1109 | ||
@@ -1106,7 +1119,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1106 | 1119 | ||
1107 | /* If a full-sized TSO skb can be sent, do it. */ | 1120 | /* If a full-sized TSO skb can be sent, do it. */ |
1108 | if (limit >= 65536) | 1121 | if (limit >= 65536) |
1109 | return 0; | 1122 | goto send_now; |
1110 | 1123 | ||
1111 | if (sysctl_tcp_tso_win_divisor) { | 1124 | if (sysctl_tcp_tso_win_divisor) { |
1112 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1125 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
@@ -1116,7 +1129,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1116 | */ | 1129 | */ |
1117 | chunk /= sysctl_tcp_tso_win_divisor; | 1130 | chunk /= sysctl_tcp_tso_win_divisor; |
1118 | if (limit >= chunk) | 1131 | if (limit >= chunk) |
1119 | return 0; | 1132 | goto send_now; |
1120 | } else { | 1133 | } else { |
1121 | /* Different approach, try not to defer past a single | 1134 | /* Different approach, try not to defer past a single |
1122 | * ACK. Receiver should ACK every other full sized | 1135 | * ACK. Receiver should ACK every other full sized |
@@ -1124,11 +1137,17 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1124 | * then send now. | 1137 | * then send now. |
1125 | */ | 1138 | */ |
1126 | if (limit > tcp_max_burst(tp) * tp->mss_cache) | 1139 | if (limit > tcp_max_burst(tp) * tp->mss_cache) |
1127 | return 0; | 1140 | goto send_now; |
1128 | } | 1141 | } |
1129 | 1142 | ||
1130 | /* Ok, it looks like it is advisable to defer. */ | 1143 | /* Ok, it looks like it is advisable to defer. */ |
1144 | tp->tso_deferred = 1 | (jiffies<<1); | ||
1145 | |||
1131 | return 1; | 1146 | return 1; |
1147 | |||
1148 | send_now: | ||
1149 | tp->tso_deferred = 0; | ||
1150 | return 0; | ||
1132 | } | 1151 | } |
1133 | 1152 | ||
1134 | /* Create a new MTU probe if we are ready. | 1153 | /* Create a new MTU probe if we are ready. |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7a7a00147e55..1bed0cdf53e3 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -52,7 +52,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) | |||
52 | xdst->u.rt.fl.fl4_dst == fl->fl4_dst && | 52 | xdst->u.rt.fl.fl4_dst == fl->fl4_dst && |
53 | xdst->u.rt.fl.fl4_src == fl->fl4_src && | 53 | xdst->u.rt.fl.fl4_src == fl->fl4_src && |
54 | xdst->u.rt.fl.fl4_tos == fl->fl4_tos && | 54 | xdst->u.rt.fl.fl4_tos == fl->fl4_tos && |
55 | xfrm_bundle_ok(xdst, fl, AF_INET, 0)) { | 55 | xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) { |
56 | dst_clone(dst); | 56 | dst_clone(dst); |
57 | break; | 57 | break; |
58 | } | 58 | } |
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index a460e8132b4d..6e48f52e197c 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
@@ -153,6 +153,19 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION | |||
153 | ---help--- | 153 | ---help--- |
154 | Support for MIPv6 route optimization mode. | 154 | Support for MIPv6 route optimization mode. |
155 | 155 | ||
156 | config IPV6_SIT | ||
157 | tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" | ||
158 | depends on IPV6 | ||
159 | default y | ||
160 | ---help--- | ||
161 | Tunneling means encapsulating data of one protocol type within | ||
162 | another protocol and sending it over a channel that understands the | ||
163 | encapsulating protocol. This driver implements encapsulation of IPv6 | ||
164 | into IPv4 packets. This is useful if you want to connect two IPv6 | ||
165 | networks over an IPv4-only path. | ||
166 | |||
167 | Saying M here will produce a module called sit.ko. If unsure, say Y. | ||
168 | |||
156 | config IPV6_TUNNEL | 169 | config IPV6_TUNNEL |
157 | tristate "IPv6: IPv6-in-IPv6 tunnel" | 170 | tristate "IPv6: IPv6-in-IPv6 tunnel" |
158 | select INET6_TUNNEL | 171 | select INET6_TUNNEL |
@@ -162,9 +175,16 @@ config IPV6_TUNNEL | |||
162 | 175 | ||
163 | If unsure, say N. | 176 | If unsure, say N. |
164 | 177 | ||
178 | config IPV6_MULTIPLE_TABLES | ||
179 | bool "IPv6: Multiple Routing Tables" | ||
180 | depends on IPV6 && EXPERIMENTAL | ||
181 | select FIB_RULES | ||
182 | ---help--- | ||
183 | Support multiple routing tables. | ||
184 | |||
165 | config IPV6_SUBTREES | 185 | config IPV6_SUBTREES |
166 | bool "IPv6: source address based routing" | 186 | bool "IPv6: source address based routing" |
167 | depends on IPV6 && EXPERIMENTAL | 187 | depends on IPV6_MULTIPLE_TABLES |
168 | ---help--- | 188 | ---help--- |
169 | Enable routing by source address or prefix. | 189 | Enable routing by source address or prefix. |
170 | 190 | ||
@@ -176,13 +196,6 @@ config IPV6_SUBTREES | |||
176 | 196 | ||
177 | If unsure, say N. | 197 | If unsure, say N. |
178 | 198 | ||
179 | config IPV6_MULTIPLE_TABLES | ||
180 | bool "IPv6: Multiple Routing Tables" | ||
181 | depends on IPV6 && EXPERIMENTAL | ||
182 | select FIB_RULES | ||
183 | ---help--- | ||
184 | Support multiple routing tables. | ||
185 | |||
186 | config IPV6_ROUTE_FWMARK | 199 | config IPV6_ROUTE_FWMARK |
187 | bool "IPv6: use netfilter MARK value as routing key" | 200 | bool "IPv6: use netfilter MARK value as routing key" |
188 | depends on IPV6_MULTIPLE_TABLES && NETFILTER | 201 | depends on IPV6_MULTIPLE_TABLES && NETFILTER |
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index 87274e47fe32..addcc011bc01 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_IPV6) += ipv6.o | 5 | obj-$(CONFIG_IPV6) += ipv6.o |
6 | 6 | ||
7 | ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \ | 7 | ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ |
8 | route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ | 8 | route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ |
9 | protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ | 9 | protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ |
10 | exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ | 10 | exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ |
@@ -29,6 +29,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o | |||
29 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o | 29 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o |
30 | obj-$(CONFIG_NETFILTER) += netfilter/ | 30 | obj-$(CONFIG_NETFILTER) += netfilter/ |
31 | 31 | ||
32 | obj-$(CONFIG_IPV6_SIT) += sit.o | ||
32 | obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o | 33 | obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o |
33 | 34 | ||
34 | obj-y += exthdrs_core.o | 35 | obj-y += exthdrs_core.o |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e03c33b2465b..b312a5f7a759 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -396,8 +396,10 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
396 | ndev->regen_timer.data = (unsigned long) ndev; | 396 | ndev->regen_timer.data = (unsigned long) ndev; |
397 | if ((dev->flags&IFF_LOOPBACK) || | 397 | if ((dev->flags&IFF_LOOPBACK) || |
398 | dev->type == ARPHRD_TUNNEL || | 398 | dev->type == ARPHRD_TUNNEL || |
399 | dev->type == ARPHRD_NONE || | 399 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) |
400 | dev->type == ARPHRD_SIT) { | 400 | dev->type == ARPHRD_SIT || |
401 | #endif | ||
402 | dev->type == ARPHRD_NONE) { | ||
401 | printk(KERN_INFO | 403 | printk(KERN_INFO |
402 | "%s: Disabled Privacy Extensions\n", | 404 | "%s: Disabled Privacy Extensions\n", |
403 | dev->name); | 405 | dev->name); |
@@ -1546,8 +1548,10 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1546 | This thing is done here expecting that the whole | 1548 | This thing is done here expecting that the whole |
1547 | class of non-broadcast devices need not cloning. | 1549 | class of non-broadcast devices need not cloning. |
1548 | */ | 1550 | */ |
1551 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
1549 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) | 1552 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) |
1550 | cfg.fc_flags |= RTF_NONEXTHOP; | 1553 | cfg.fc_flags |= RTF_NONEXTHOP; |
1554 | #endif | ||
1551 | 1555 | ||
1552 | ip6_route_add(&cfg); | 1556 | ip6_route_add(&cfg); |
1553 | } | 1557 | } |
@@ -1569,6 +1573,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1569 | ip6_route_add(&cfg); | 1573 | ip6_route_add(&cfg); |
1570 | } | 1574 | } |
1571 | 1575 | ||
1576 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
1572 | static void sit_route_add(struct net_device *dev) | 1577 | static void sit_route_add(struct net_device *dev) |
1573 | { | 1578 | { |
1574 | struct fib6_config cfg = { | 1579 | struct fib6_config cfg = { |
@@ -1582,6 +1587,7 @@ static void sit_route_add(struct net_device *dev) | |||
1582 | /* prefix length - 96 bits "::d.d.d.d" */ | 1587 | /* prefix length - 96 bits "::d.d.d.d" */ |
1583 | ip6_route_add(&cfg); | 1588 | ip6_route_add(&cfg); |
1584 | } | 1589 | } |
1590 | #endif | ||
1585 | 1591 | ||
1586 | static void addrconf_add_lroute(struct net_device *dev) | 1592 | static void addrconf_add_lroute(struct net_device *dev) |
1587 | { | 1593 | { |
@@ -1852,6 +1858,7 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1852 | if (dev == NULL) | 1858 | if (dev == NULL) |
1853 | goto err_exit; | 1859 | goto err_exit; |
1854 | 1860 | ||
1861 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
1855 | if (dev->type == ARPHRD_SIT) { | 1862 | if (dev->type == ARPHRD_SIT) { |
1856 | struct ifreq ifr; | 1863 | struct ifreq ifr; |
1857 | mm_segment_t oldfs; | 1864 | mm_segment_t oldfs; |
@@ -1881,6 +1888,7 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1881 | err = dev_open(dev); | 1888 | err = dev_open(dev); |
1882 | } | 1889 | } |
1883 | } | 1890 | } |
1891 | #endif | ||
1884 | 1892 | ||
1885 | err_exit: | 1893 | err_exit: |
1886 | rtnl_unlock(); | 1894 | rtnl_unlock(); |
@@ -2010,6 +2018,7 @@ int addrconf_del_ifaddr(void __user *arg) | |||
2010 | return err; | 2018 | return err; |
2011 | } | 2019 | } |
2012 | 2020 | ||
2021 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
2013 | static void sit_add_v4_addrs(struct inet6_dev *idev) | 2022 | static void sit_add_v4_addrs(struct inet6_dev *idev) |
2014 | { | 2023 | { |
2015 | struct inet6_ifaddr * ifp; | 2024 | struct inet6_ifaddr * ifp; |
@@ -2078,6 +2087,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2078 | } | 2087 | } |
2079 | } | 2088 | } |
2080 | } | 2089 | } |
2090 | #endif | ||
2081 | 2091 | ||
2082 | static void init_loopback(struct net_device *dev) | 2092 | static void init_loopback(struct net_device *dev) |
2083 | { | 2093 | { |
@@ -2141,6 +2151,7 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2141 | addrconf_add_linklocal(idev, &addr); | 2151 | addrconf_add_linklocal(idev, &addr); |
2142 | } | 2152 | } |
2143 | 2153 | ||
2154 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
2144 | static void addrconf_sit_config(struct net_device *dev) | 2155 | static void addrconf_sit_config(struct net_device *dev) |
2145 | { | 2156 | { |
2146 | struct inet6_dev *idev; | 2157 | struct inet6_dev *idev; |
@@ -2166,6 +2177,7 @@ static void addrconf_sit_config(struct net_device *dev) | |||
2166 | } else | 2177 | } else |
2167 | sit_route_add(dev); | 2178 | sit_route_add(dev); |
2168 | } | 2179 | } |
2180 | #endif | ||
2169 | 2181 | ||
2170 | static inline int | 2182 | static inline int |
2171 | ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | 2183 | ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) |
@@ -2260,9 +2272,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2260 | } | 2272 | } |
2261 | 2273 | ||
2262 | switch(dev->type) { | 2274 | switch(dev->type) { |
2275 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
2263 | case ARPHRD_SIT: | 2276 | case ARPHRD_SIT: |
2264 | addrconf_sit_config(dev); | 2277 | addrconf_sit_config(dev); |
2265 | break; | 2278 | break; |
2279 | #endif | ||
2266 | case ARPHRD_TUNNEL6: | 2280 | case ARPHRD_TUNNEL6: |
2267 | addrconf_ip6_tnl_config(dev); | 2281 | addrconf_ip6_tnl_config(dev); |
2268 | break; | 2282 | break; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e94eccb99707..858cae29581c 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -850,7 +850,6 @@ static int __init inet6_init(void) | |||
850 | err = addrconf_init(); | 850 | err = addrconf_init(); |
851 | if (err) | 851 | if (err) |
852 | goto addrconf_fail; | 852 | goto addrconf_fail; |
853 | sit_init(); | ||
854 | 853 | ||
855 | /* Init v6 extension headers. */ | 854 | /* Init v6 extension headers. */ |
856 | ipv6_rthdr_init(); | 855 | ipv6_rthdr_init(); |
@@ -927,7 +926,6 @@ static void __exit inet6_exit(void) | |||
927 | mip6_fini(); | 926 | mip6_fini(); |
928 | #endif | 927 | #endif |
929 | /* Cleanup code parts. */ | 928 | /* Cleanup code parts. */ |
930 | sit_cleanup(); | ||
931 | ip6_flowlabel_cleanup(); | 929 | ip6_flowlabel_cleanup(); |
932 | addrconf_cleanup(); | 930 | addrconf_cleanup(); |
933 | ip6_route_cleanup(); | 931 | ip6_route_cleanup(); |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index d8c1057e8b00..1896ecb52899 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -117,12 +117,15 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
117 | { | 117 | { |
118 | struct fib6_rule *r = (struct fib6_rule *) rule; | 118 | struct fib6_rule *r = (struct fib6_rule *) rule; |
119 | 119 | ||
120 | if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) | 120 | if (r->dst.plen && |
121 | !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) | ||
121 | return 0; | 122 | return 0; |
122 | 123 | ||
123 | if ((flags & RT6_LOOKUP_F_HAS_SADDR) && | 124 | if (r->src.plen) { |
124 | !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) | 125 | if (!(flags & RT6_LOOKUP_F_HAS_SADDR) || |
125 | return 0; | 126 | !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) |
127 | return 0; | ||
128 | } | ||
126 | 129 | ||
127 | if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) | 130 | if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) |
128 | return 0; | 131 | return 0; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 8fcae7a6510b..f98ca30d7c1f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -169,7 +169,6 @@ static __inline__ void rt6_release(struct rt6_info *rt) | |||
169 | 169 | ||
170 | static struct fib6_table fib6_main_tbl = { | 170 | static struct fib6_table fib6_main_tbl = { |
171 | .tb6_id = RT6_TABLE_MAIN, | 171 | .tb6_id = RT6_TABLE_MAIN, |
172 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
173 | .tb6_root = { | 172 | .tb6_root = { |
174 | .leaf = &ip6_null_entry, | 173 | .leaf = &ip6_null_entry, |
175 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 174 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
@@ -187,6 +186,12 @@ static void fib6_link_table(struct fib6_table *tb) | |||
187 | { | 186 | { |
188 | unsigned int h; | 187 | unsigned int h; |
189 | 188 | ||
189 | /* | ||
190 | * Initialize table lock at a single place to give lockdep a key, | ||
191 | * tables aren't visible prior to being linked to the list. | ||
192 | */ | ||
193 | rwlock_init(&tb->tb6_lock); | ||
194 | |||
190 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); | 195 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); |
191 | 196 | ||
192 | /* | 197 | /* |
@@ -199,7 +204,6 @@ static void fib6_link_table(struct fib6_table *tb) | |||
199 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 204 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
200 | static struct fib6_table fib6_local_tbl = { | 205 | static struct fib6_table fib6_local_tbl = { |
201 | .tb6_id = RT6_TABLE_LOCAL, | 206 | .tb6_id = RT6_TABLE_LOCAL, |
202 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
203 | .tb6_root = { | 207 | .tb6_root = { |
204 | .leaf = &ip6_null_entry, | 208 | .leaf = &ip6_null_entry, |
205 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 209 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
@@ -213,7 +217,6 @@ static struct fib6_table *fib6_alloc_table(u32 id) | |||
213 | table = kzalloc(sizeof(*table), GFP_ATOMIC); | 217 | table = kzalloc(sizeof(*table), GFP_ATOMIC); |
214 | if (table != NULL) { | 218 | if (table != NULL) { |
215 | table->tb6_id = id; | 219 | table->tb6_id = id; |
216 | table->tb6_lock = RW_LOCK_UNLOCKED; | ||
217 | table->tb6_root.leaf = &ip6_null_entry; | 220 | table->tb6_root.leaf = &ip6_null_entry; |
218 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; | 221 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; |
219 | } | 222 | } |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 1d672b0547f2..6d4533b58dca 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -330,8 +330,10 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int * | |||
330 | fl->share = freq->flr_share; | 330 | fl->share = freq->flr_share; |
331 | addr_type = ipv6_addr_type(&freq->flr_dst); | 331 | addr_type = ipv6_addr_type(&freq->flr_dst); |
332 | if ((addr_type&IPV6_ADDR_MAPPED) | 332 | if ((addr_type&IPV6_ADDR_MAPPED) |
333 | || addr_type == IPV6_ADDR_ANY) | 333 | || addr_type == IPV6_ADDR_ANY) { |
334 | err = -EINVAL; | ||
334 | goto done; | 335 | goto done; |
336 | } | ||
335 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); | 337 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); |
336 | atomic_set(&fl->users, 1); | 338 | atomic_set(&fl->users, 1); |
337 | switch (fl->share) { | 339 | switch (fl->share) { |
@@ -587,6 +589,8 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo | |||
587 | while (!fl) { | 589 | while (!fl) { |
588 | if (++state->bucket <= FL_HASH_MASK) | 590 | if (++state->bucket <= FL_HASH_MASK) |
589 | fl = fl_ht[state->bucket]; | 591 | fl = fl_ht[state->bucket]; |
592 | else | ||
593 | break; | ||
590 | } | 594 | } |
591 | return fl; | 595 | return fl; |
592 | } | 596 | } |
@@ -623,9 +627,13 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) | |||
623 | read_unlock_bh(&ip6_fl_lock); | 627 | read_unlock_bh(&ip6_fl_lock); |
624 | } | 628 | } |
625 | 629 | ||
626 | static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | 630 | static int ip6fl_seq_show(struct seq_file *seq, void *v) |
627 | { | 631 | { |
628 | while(fl) { | 632 | if (v == SEQ_START_TOKEN) |
633 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
634 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
635 | else { | ||
636 | struct ip6_flowlabel *fl = v; | ||
629 | seq_printf(seq, | 637 | seq_printf(seq, |
630 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", | 638 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", |
631 | (unsigned)ntohl(fl->label), | 639 | (unsigned)ntohl(fl->label), |
@@ -636,17 +644,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | |||
636 | (long)(fl->expires - jiffies)/HZ, | 644 | (long)(fl->expires - jiffies)/HZ, |
637 | NIP6(fl->dst), | 645 | NIP6(fl->dst), |
638 | fl->opt ? fl->opt->opt_nflen : 0); | 646 | fl->opt ? fl->opt->opt_nflen : 0); |
639 | fl = fl->next; | ||
640 | } | 647 | } |
641 | } | ||
642 | |||
643 | static int ip6fl_seq_show(struct seq_file *seq, void *v) | ||
644 | { | ||
645 | if (v == SEQ_START_TOKEN) | ||
646 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
647 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
648 | else | ||
649 | ip6fl_fl_seq_show(seq, v); | ||
650 | return 0; | 648 | return 0; |
651 | } | 649 | } |
652 | 650 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 84d7ebdb9d21..b9f40290d12a 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb) | |||
542 | skb->dev = t->dev; | 542 | skb->dev = t->dev; |
543 | dst_release(skb->dst); | 543 | dst_release(skb->dst); |
544 | skb->dst = NULL; | 544 | skb->dst = NULL; |
545 | nf_reset(skb); | ||
545 | if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) | 546 | if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) |
546 | ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); | 547 | ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); |
547 | ip6ip6_ecn_decapsulate(ipv6h, skb); | 548 | ip6ip6_ecn_decapsulate(ipv6h, skb); |
@@ -1149,6 +1150,20 @@ fail: | |||
1149 | return err; | 1150 | return err; |
1150 | } | 1151 | } |
1151 | 1152 | ||
1153 | static void __exit ip6ip6_destroy_tunnels(void) | ||
1154 | { | ||
1155 | int h; | ||
1156 | struct ip6_tnl *t; | ||
1157 | |||
1158 | for (h = 0; h < HASH_SIZE; h++) { | ||
1159 | while ((t = tnls_r_l[h]) != NULL) | ||
1160 | unregister_netdevice(t->dev); | ||
1161 | } | ||
1162 | |||
1163 | t = tnls_wc[0]; | ||
1164 | unregister_netdevice(t->dev); | ||
1165 | } | ||
1166 | |||
1152 | /** | 1167 | /** |
1153 | * ip6_tunnel_cleanup - free resources and unregister protocol | 1168 | * ip6_tunnel_cleanup - free resources and unregister protocol |
1154 | **/ | 1169 | **/ |
@@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void) | |||
1158 | if (xfrm6_tunnel_deregister(&ip6ip6_handler)) | 1173 | if (xfrm6_tunnel_deregister(&ip6ip6_handler)) |
1159 | printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); | 1174 | printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); |
1160 | 1175 | ||
1161 | unregister_netdev(ip6ip6_fb_tnl_dev); | 1176 | rtnl_lock(); |
1177 | ip6ip6_destroy_tunnels(); | ||
1178 | rtnl_unlock(); | ||
1162 | } | 1179 | } |
1163 | 1180 | ||
1164 | module_init(ip6_tunnel_init); | 1181 | module_init(ip6_tunnel_init); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0304b5fe8d6a..73eb8c33e9f0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -967,8 +967,6 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
967 | ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && | 967 | ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && |
968 | pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { | 968 | pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { |
969 | /* XXX: idev->cnf.prixy_ndp */ | 969 | /* XXX: idev->cnf.prixy_ndp */ |
970 | WARN_ON(skb->dst != NULL && | ||
971 | ((struct rt6_info *)skb->dst)->rt6i_idev); | ||
972 | goto out; | 970 | goto out; |
973 | } | 971 | } |
974 | 972 | ||
@@ -1744,6 +1742,7 @@ int __init ndisc_init(struct net_proto_family *ops) | |||
1744 | 1742 | ||
1745 | void ndisc_cleanup(void) | 1743 | void ndisc_cleanup(void) |
1746 | { | 1744 | { |
1745 | unregister_netdevice_notifier(&ndisc_netdev_notifier); | ||
1747 | #ifdef CONFIG_SYSCTL | 1746 | #ifdef CONFIG_SYSCTL |
1748 | neigh_sysctl_unregister(&nd_tbl.parms); | 1747 | neigh_sysctl_unregister(&nd_tbl.parms); |
1749 | #endif | 1748 | #endif |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 4bc4e5b33794..d7c45a9c15fe 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -40,7 +40,7 @@ config IP6_NF_QUEUE | |||
40 | To compile it as a module, choose M here. If unsure, say N. | 40 | To compile it as a module, choose M here. If unsure, say N. |
41 | 41 | ||
42 | config IP6_NF_IPTABLES | 42 | config IP6_NF_IPTABLES |
43 | tristate "IP6 tables support (required for filtering/masq/NAT)" | 43 | tristate "IP6 tables support (required for filtering)" |
44 | depends on NETFILTER_XTABLES | 44 | depends on NETFILTER_XTABLES |
45 | help | 45 | help |
46 | ip6tables is a general, extensible packet identification framework. | 46 | ip6tables is a general, extensible packet identification framework. |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9510c24ca8d2..9fec832ee08b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -349,9 +349,10 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
349 | if (v->data_len < sizeof(*user_iph)) | 349 | if (v->data_len < sizeof(*user_iph)) |
350 | return 0; | 350 | return 0; |
351 | diff = v->data_len - e->skb->len; | 351 | diff = v->data_len - e->skb->len; |
352 | if (diff < 0) | 352 | if (diff < 0) { |
353 | skb_trim(e->skb, v->data_len); | 353 | if (pskb_trim(e->skb, v->data_len)) |
354 | else if (diff > 0) { | 354 | return -ENOMEM; |
355 | } else if (diff > 0) { | ||
355 | if (v->data_len > 0xFFFF) | 356 | if (v->data_len > 0xFFFF) |
356 | return -EINVAL; | 357 | return -EINVAL; |
357 | if (diff > skb_tailroom(e->skb)) { | 358 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4ab368fa0b8f..204e02162d49 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *skb, | |||
111 | const char *outdev, | 111 | const char *outdev, |
112 | const struct ip6t_ip6 *ip6info, | 112 | const struct ip6t_ip6 *ip6info, |
113 | unsigned int *protoff, | 113 | unsigned int *protoff, |
114 | int *fragoff) | 114 | int *fragoff, int *hotdrop) |
115 | { | 115 | { |
116 | size_t i; | 116 | size_t i; |
117 | unsigned long ret; | 117 | unsigned long ret; |
@@ -169,9 +169,11 @@ ip6_packet_match(const struct sk_buff *skb, | |||
169 | unsigned short _frag_off; | 169 | unsigned short _frag_off; |
170 | 170 | ||
171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); | 171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); |
172 | if (protohdr < 0) | 172 | if (protohdr < 0) { |
173 | if (_frag_off == 0) | ||
174 | *hotdrop = 1; | ||
173 | return 0; | 175 | return 0; |
174 | 176 | } | |
175 | *fragoff = _frag_off; | 177 | *fragoff = _frag_off; |
176 | 178 | ||
177 | dprintf("Packet protocol %hi ?= %s%hi.\n", | 179 | dprintf("Packet protocol %hi ?= %s%hi.\n", |
@@ -290,7 +292,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
290 | IP_NF_ASSERT(e); | 292 | IP_NF_ASSERT(e); |
291 | IP_NF_ASSERT(back); | 293 | IP_NF_ASSERT(back); |
292 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, | 294 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, |
293 | &protoff, &offset)) { | 295 | &protoff, &offset, &hotdrop)) { |
294 | struct ip6t_entry_target *t; | 296 | struct ip6t_entry_target *t; |
295 | 297 | ||
296 | if (IP6T_MATCH_ITERATE(e, do_match, | 298 | if (IP6T_MATCH_ITERATE(e, do_match, |
@@ -584,12 +586,19 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
584 | return -EINVAL; | 586 | return -EINVAL; |
585 | } | 587 | } |
586 | 588 | ||
589 | if (e->target_offset + sizeof(struct ip6t_entry_target) > | ||
590 | e->next_offset) | ||
591 | return -EINVAL; | ||
592 | |||
587 | j = 0; | 593 | j = 0; |
588 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); | 594 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); |
589 | if (ret != 0) | 595 | if (ret != 0) |
590 | goto cleanup_matches; | 596 | goto cleanup_matches; |
591 | 597 | ||
592 | t = ip6t_get_target(e); | 598 | t = ip6t_get_target(e); |
599 | ret = -EINVAL; | ||
600 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
601 | goto cleanup_matches; | ||
593 | target = try_then_request_module(xt_find_target(AF_INET6, | 602 | target = try_then_request_module(xt_find_target(AF_INET6, |
594 | t->u.user.name, | 603 | t->u.user.name, |
595 | t->u.user.revision), | 604 | t->u.user.revision), |
@@ -749,19 +758,17 @@ translate_table(const char *name, | |||
749 | } | 758 | } |
750 | } | 759 | } |
751 | 760 | ||
752 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
753 | return -ELOOP; | ||
754 | |||
755 | /* Finally, each sanity check must pass */ | 761 | /* Finally, each sanity check must pass */ |
756 | i = 0; | 762 | i = 0; |
757 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 763 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
758 | check_entry, name, size, &i); | 764 | check_entry, name, size, &i); |
759 | 765 | ||
760 | if (ret != 0) { | 766 | if (ret != 0) |
761 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 767 | goto cleanup; |
762 | cleanup_entry, &i); | 768 | |
763 | return ret; | 769 | ret = -ELOOP; |
764 | } | 770 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
771 | goto cleanup; | ||
765 | 772 | ||
766 | /* And one copy for every other CPU */ | 773 | /* And one copy for every other CPU */ |
767 | for_each_possible_cpu(i) { | 774 | for_each_possible_cpu(i) { |
@@ -769,6 +776,9 @@ translate_table(const char *name, | |||
769 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 776 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
770 | } | 777 | } |
771 | 778 | ||
779 | return 0; | ||
780 | cleanup: | ||
781 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
772 | return ret; | 782 | return ret; |
773 | } | 783 | } |
774 | 784 | ||
@@ -1438,6 +1448,9 @@ static void __exit ip6_tables_fini(void) | |||
1438 | * If target header is found, its offset is set in *offset and return protocol | 1448 | * If target header is found, its offset is set in *offset and return protocol |
1439 | * number. Otherwise, return -1. | 1449 | * number. Otherwise, return -1. |
1440 | * | 1450 | * |
1451 | * If the first fragment doesn't contain the final protocol header or | ||
1452 | * NEXTHDR_NONE it is considered invalid. | ||
1453 | * | ||
1441 | * Note that non-1st fragment is special case that "the protocol number | 1454 | * Note that non-1st fragment is special case that "the protocol number |
1442 | * of last header" is "next header" field in Fragment header. In this case, | 1455 | * of last header" is "next header" field in Fragment header. In this case, |
1443 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff | 1456 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff |
@@ -1461,12 +1474,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
1461 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { | 1474 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { |
1462 | if (target < 0) | 1475 | if (target < 0) |
1463 | break; | 1476 | break; |
1464 | return -1; | 1477 | return -ENOENT; |
1465 | } | 1478 | } |
1466 | 1479 | ||
1467 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); | 1480 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); |
1468 | if (hp == NULL) | 1481 | if (hp == NULL) |
1469 | return -1; | 1482 | return -EBADMSG; |
1470 | if (nexthdr == NEXTHDR_FRAGMENT) { | 1483 | if (nexthdr == NEXTHDR_FRAGMENT) { |
1471 | unsigned short _frag_off, *fp; | 1484 | unsigned short _frag_off, *fp; |
1472 | fp = skb_header_pointer(skb, | 1485 | fp = skb_header_pointer(skb, |
@@ -1475,18 +1488,18 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
1475 | sizeof(_frag_off), | 1488 | sizeof(_frag_off), |
1476 | &_frag_off); | 1489 | &_frag_off); |
1477 | if (fp == NULL) | 1490 | if (fp == NULL) |
1478 | return -1; | 1491 | return -EBADMSG; |
1479 | 1492 | ||
1480 | _frag_off = ntohs(*fp) & ~0x7; | 1493 | _frag_off = ntohs(*fp) & ~0x7; |
1481 | if (_frag_off) { | 1494 | if (_frag_off) { |
1482 | if (target < 0 && | 1495 | if (target < 0 && |
1483 | ((!ipv6_ext_hdr(hp->nexthdr)) || | 1496 | ((!ipv6_ext_hdr(hp->nexthdr)) || |
1484 | nexthdr == NEXTHDR_NONE)) { | 1497 | hp->nexthdr == NEXTHDR_NONE)) { |
1485 | if (fragoff) | 1498 | if (fragoff) |
1486 | *fragoff = _frag_off; | 1499 | *fragoff = _frag_off; |
1487 | return hp->nexthdr; | 1500 | return hp->nexthdr; |
1488 | } | 1501 | } |
1489 | return -1; | 1502 | return -ENOENT; |
1490 | } | 1503 | } |
1491 | hdrlen = 8; | 1504 | hdrlen = 8; |
1492 | } else if (nexthdr == NEXTHDR_AUTH) | 1505 | } else if (nexthdr == NEXTHDR_AUTH) |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index ec1b1608156c..46486645eb75 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -54,9 +54,14 @@ match(const struct sk_buff *skb, | |||
54 | const struct ip6t_ah *ahinfo = matchinfo; | 54 | const struct ip6t_ah *ahinfo = matchinfo; |
55 | unsigned int ptr; | 55 | unsigned int ptr; |
56 | unsigned int hdrlen = 0; | 56 | unsigned int hdrlen = 0; |
57 | int err; | ||
57 | 58 | ||
58 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) | 59 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); |
60 | if (err < 0) { | ||
61 | if (err != -ENOENT) | ||
62 | *hotdrop = 1; | ||
59 | return 0; | 63 | return 0; |
64 | } | ||
60 | 65 | ||
61 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); | 66 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); |
62 | if (ah == NULL) { | 67 | if (ah == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 78d9c8b9e28a..cd22eaaccdca 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -52,9 +52,14 @@ match(const struct sk_buff *skb, | |||
52 | struct frag_hdr _frag, *fh; | 52 | struct frag_hdr _frag, *fh; |
53 | const struct ip6t_frag *fraginfo = matchinfo; | 53 | const struct ip6t_frag *fraginfo = matchinfo; |
54 | unsigned int ptr; | 54 | unsigned int ptr; |
55 | int err; | ||
55 | 56 | ||
56 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) | 57 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); |
58 | if (err < 0) { | ||
59 | if (err != -ENOENT) | ||
60 | *hotdrop = 1; | ||
57 | return 0; | 61 | return 0; |
62 | } | ||
58 | 63 | ||
59 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); | 64 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); |
60 | if (fh == NULL) { | 65 | if (fh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d32a205e3af2..3f25babe0440 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -65,9 +65,14 @@ match(const struct sk_buff *skb, | |||
65 | u8 _opttype, *tp = NULL; | 65 | u8 _opttype, *tp = NULL; |
66 | u8 _optlen, *lp = NULL; | 66 | u8 _optlen, *lp = NULL; |
67 | unsigned int optlen; | 67 | unsigned int optlen; |
68 | int err; | ||
68 | 69 | ||
69 | if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) | 70 | err = ipv6_find_hdr(skb, &ptr, match->data, NULL); |
71 | if (err < 0) { | ||
72 | if (err != -ENOENT) | ||
73 | *hotdrop = 1; | ||
70 | return 0; | 74 | return 0; |
75 | } | ||
71 | 76 | ||
72 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); | 77 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); |
73 | if (oh == NULL) { | 78 | if (oh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index bcb2e168a5bc..54d7d14134fd 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -58,9 +58,14 @@ match(const struct sk_buff *skb, | |||
58 | unsigned int hdrlen = 0; | 58 | unsigned int hdrlen = 0; |
59 | unsigned int ret = 0; | 59 | unsigned int ret = 0; |
60 | struct in6_addr *ap, _addr; | 60 | struct in6_addr *ap, _addr; |
61 | int err; | ||
61 | 62 | ||
62 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) | 63 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); |
64 | if (err < 0) { | ||
65 | if (err != -ENOENT) | ||
66 | *hotdrop = 1; | ||
63 | return 0; | 67 | return 0; |
68 | } | ||
64 | 69 | ||
65 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); | 70 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); |
66 | if (rh == NULL) { | 71 | if (rh == NULL) { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d09329ca3267..d6dedc4aec77 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -604,7 +604,7 @@ error: | |||
604 | return err; | 604 | return err; |
605 | } | 605 | } |
606 | 606 | ||
607 | static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 607 | static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) |
608 | { | 608 | { |
609 | struct iovec *iov; | 609 | struct iovec *iov; |
610 | u8 __user *type = NULL; | 610 | u8 __user *type = NULL; |
@@ -616,7 +616,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
616 | int i; | 616 | int i; |
617 | 617 | ||
618 | if (!msg->msg_iov) | 618 | if (!msg->msg_iov) |
619 | return; | 619 | return 0; |
620 | 620 | ||
621 | for (i = 0; i < msg->msg_iovlen; i++) { | 621 | for (i = 0; i < msg->msg_iovlen; i++) { |
622 | iov = &msg->msg_iov[i]; | 622 | iov = &msg->msg_iov[i]; |
@@ -638,8 +638,9 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
638 | code = iov->iov_base; | 638 | code = iov->iov_base; |
639 | 639 | ||
640 | if (type && code) { | 640 | if (type && code) { |
641 | get_user(fl->fl_icmp_type, type); | 641 | if (get_user(fl->fl_icmp_type, type) || |
642 | get_user(fl->fl_icmp_code, code); | 642 | get_user(fl->fl_icmp_code, code)) |
643 | return -EFAULT; | ||
643 | probed = 1; | 644 | probed = 1; |
644 | } | 645 | } |
645 | break; | 646 | break; |
@@ -650,7 +651,8 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
650 | /* check if type field is readable or not. */ | 651 | /* check if type field is readable or not. */ |
651 | if (iov->iov_len > 2 - len) { | 652 | if (iov->iov_len > 2 - len) { |
652 | u8 __user *p = iov->iov_base; | 653 | u8 __user *p = iov->iov_base; |
653 | get_user(fl->fl_mh_type, &p[2 - len]); | 654 | if (get_user(fl->fl_mh_type, &p[2 - len])) |
655 | return -EFAULT; | ||
654 | probed = 1; | 656 | probed = 1; |
655 | } else | 657 | } else |
656 | len += iov->iov_len; | 658 | len += iov->iov_len; |
@@ -664,6 +666,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
664 | if (probed) | 666 | if (probed) |
665 | break; | 667 | break; |
666 | } | 668 | } |
669 | return 0; | ||
667 | } | 670 | } |
668 | 671 | ||
669 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 672 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, |
@@ -787,7 +790,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
787 | opt = ipv6_fixup_options(&opt_space, opt); | 790 | opt = ipv6_fixup_options(&opt_space, opt); |
788 | 791 | ||
789 | fl.proto = proto; | 792 | fl.proto = proto; |
790 | rawv6_probe_proto_opt(&fl, msg); | 793 | err = rawv6_probe_proto_opt(&fl, msg); |
794 | if (err) | ||
795 | goto out; | ||
791 | 796 | ||
792 | ipv6_addr_copy(&fl.fl6_dst, daddr); | 797 | ipv6_addr_copy(&fl.fl6_dst, daddr); |
793 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | 798 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d6b4b4f48d18..b39ae99122d5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -141,6 +141,10 @@ struct rt6_info ip6_null_entry = { | |||
141 | 141 | ||
142 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 142 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
143 | 143 | ||
144 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
145 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
146 | static int ip6_pkt_blk_hole(struct sk_buff *skb); | ||
147 | |||
144 | struct rt6_info ip6_prohibit_entry = { | 148 | struct rt6_info ip6_prohibit_entry = { |
145 | .u = { | 149 | .u = { |
146 | .dst = { | 150 | .dst = { |
@@ -150,8 +154,8 @@ struct rt6_info ip6_prohibit_entry = { | |||
150 | .obsolete = -1, | 154 | .obsolete = -1, |
151 | .error = -EACCES, | 155 | .error = -EACCES, |
152 | .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, | 156 | .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, |
153 | .input = ip6_pkt_discard, | 157 | .input = ip6_pkt_prohibit, |
154 | .output = ip6_pkt_discard_out, | 158 | .output = ip6_pkt_prohibit_out, |
155 | .ops = &ip6_dst_ops, | 159 | .ops = &ip6_dst_ops, |
156 | .path = (struct dst_entry*)&ip6_prohibit_entry, | 160 | .path = (struct dst_entry*)&ip6_prohibit_entry, |
157 | } | 161 | } |
@@ -170,8 +174,8 @@ struct rt6_info ip6_blk_hole_entry = { | |||
170 | .obsolete = -1, | 174 | .obsolete = -1, |
171 | .error = -EINVAL, | 175 | .error = -EINVAL, |
172 | .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, | 176 | .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, |
173 | .input = ip6_pkt_discard, | 177 | .input = ip6_pkt_blk_hole, |
174 | .output = ip6_pkt_discard_out, | 178 | .output = ip6_pkt_blk_hole, |
175 | .ops = &ip6_dst_ops, | 179 | .ops = &ip6_dst_ops, |
176 | .path = (struct dst_entry*)&ip6_blk_hole_entry, | 180 | .path = (struct dst_entry*)&ip6_blk_hole_entry, |
177 | } | 181 | } |
@@ -326,6 +330,8 @@ static int inline rt6_check_neigh(struct rt6_info *rt) | |||
326 | read_lock_bh(&neigh->lock); | 330 | read_lock_bh(&neigh->lock); |
327 | if (neigh->nud_state & NUD_VALID) | 331 | if (neigh->nud_state & NUD_VALID) |
328 | m = 2; | 332 | m = 2; |
333 | else if (!(neigh->nud_state & NUD_FAILED)) | ||
334 | m = 1; | ||
329 | read_unlock_bh(&neigh->lock); | 335 | read_unlock_bh(&neigh->lock); |
330 | } | 336 | } |
331 | return m; | 337 | return m; |
@@ -343,9 +349,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif, | |||
343 | m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; | 349 | m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; |
344 | #endif | 350 | #endif |
345 | n = rt6_check_neigh(rt); | 351 | n = rt6_check_neigh(rt); |
346 | if (n > 1) | 352 | if (!n && (strict & RT6_LOOKUP_F_REACHABLE)) |
347 | m |= 16; | ||
348 | else if (!n && strict & RT6_LOOKUP_F_REACHABLE) | ||
349 | return -1; | 353 | return -1; |
350 | return m; | 354 | return m; |
351 | } | 355 | } |
@@ -376,10 +380,11 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | |||
376 | continue; | 380 | continue; |
377 | 381 | ||
378 | if (m > mpri) { | 382 | if (m > mpri) { |
379 | rt6_probe(match); | 383 | if (strict & RT6_LOOKUP_F_REACHABLE) |
384 | rt6_probe(match); | ||
380 | match = rt; | 385 | match = rt; |
381 | mpri = m; | 386 | mpri = m; |
382 | } else { | 387 | } else if (strict & RT6_LOOKUP_F_REACHABLE) { |
383 | rt6_probe(rt); | 388 | rt6_probe(rt); |
384 | } | 389 | } |
385 | } | 390 | } |
@@ -484,7 +489,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
484 | do { \ | 489 | do { \ |
485 | if (rt == &ip6_null_entry) { \ | 490 | if (rt == &ip6_null_entry) { \ |
486 | struct fib6_node *pn; \ | 491 | struct fib6_node *pn; \ |
487 | while (fn) { \ | 492 | while (1) { \ |
488 | if (fn->fn_flags & RTN_TL_ROOT) \ | 493 | if (fn->fn_flags & RTN_TL_ROOT) \ |
489 | goto out; \ | 494 | goto out; \ |
490 | pn = fn->parent; \ | 495 | pn = fn->parent; \ |
@@ -529,13 +534,17 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, | |||
529 | .nl_u = { | 534 | .nl_u = { |
530 | .ip6_u = { | 535 | .ip6_u = { |
531 | .daddr = *daddr, | 536 | .daddr = *daddr, |
532 | /* TODO: saddr */ | ||
533 | }, | 537 | }, |
534 | }, | 538 | }, |
535 | }; | 539 | }; |
536 | struct dst_entry *dst; | 540 | struct dst_entry *dst; |
537 | int flags = strict ? RT6_LOOKUP_F_IFACE : 0; | 541 | int flags = strict ? RT6_LOOKUP_F_IFACE : 0; |
538 | 542 | ||
543 | if (saddr) { | ||
544 | memcpy(&fl.fl6_src, saddr, sizeof(*saddr)); | ||
545 | flags |= RT6_LOOKUP_F_HAS_SADDR; | ||
546 | } | ||
547 | |||
539 | dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); | 548 | dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); |
540 | if (dst->error == 0) | 549 | if (dst->error == 0) |
541 | return (struct rt6_info *) dst; | 550 | return (struct rt6_info *) dst; |
@@ -614,8 +623,6 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d | |||
614 | ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); | 623 | ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); |
615 | rt->rt6i_dst.plen = 128; | 624 | rt->rt6i_dst.plen = 128; |
616 | rt->rt6i_flags |= RTF_CACHE; | 625 | rt->rt6i_flags |= RTF_CACHE; |
617 | if (rt->rt6i_flags & RTF_REJECT) | ||
618 | rt->u.dst.error = ort->u.dst.error; | ||
619 | rt->u.dst.flags |= DST_HOST; | 626 | rt->u.dst.flags |= DST_HOST; |
620 | rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop); | 627 | rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop); |
621 | } | 628 | } |
@@ -630,7 +637,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, | |||
630 | int strict = 0; | 637 | int strict = 0; |
631 | int attempts = 3; | 638 | int attempts = 3; |
632 | int err; | 639 | int err; |
633 | int reachable = RT6_LOOKUP_F_REACHABLE; | 640 | int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; |
634 | 641 | ||
635 | strict |= flags & RT6_LOOKUP_F_IFACE; | 642 | strict |= flags & RT6_LOOKUP_F_IFACE; |
636 | 643 | ||
@@ -697,6 +704,7 @@ out2: | |||
697 | void ip6_route_input(struct sk_buff *skb) | 704 | void ip6_route_input(struct sk_buff *skb) |
698 | { | 705 | { |
699 | struct ipv6hdr *iph = skb->nh.ipv6h; | 706 | struct ipv6hdr *iph = skb->nh.ipv6h; |
707 | int flags = RT6_LOOKUP_F_HAS_SADDR; | ||
700 | struct flowi fl = { | 708 | struct flowi fl = { |
701 | .iif = skb->dev->ifindex, | 709 | .iif = skb->dev->ifindex, |
702 | .nl_u = { | 710 | .nl_u = { |
@@ -711,7 +719,9 @@ void ip6_route_input(struct sk_buff *skb) | |||
711 | }, | 719 | }, |
712 | .proto = iph->nexthdr, | 720 | .proto = iph->nexthdr, |
713 | }; | 721 | }; |
714 | int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0; | 722 | |
723 | if (rt6_need_strict(&iph->daddr)) | ||
724 | flags |= RT6_LOOKUP_F_IFACE; | ||
715 | 725 | ||
716 | skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); | 726 | skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); |
717 | } | 727 | } |
@@ -724,7 +734,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, | |||
724 | int strict = 0; | 734 | int strict = 0; |
725 | int attempts = 3; | 735 | int attempts = 3; |
726 | int err; | 736 | int err; |
727 | int reachable = RT6_LOOKUP_F_REACHABLE; | 737 | int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; |
728 | 738 | ||
729 | strict |= flags & RT6_LOOKUP_F_IFACE; | 739 | strict |= flags & RT6_LOOKUP_F_IFACE; |
730 | 740 | ||
@@ -794,6 +804,9 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) | |||
794 | if (rt6_need_strict(&fl->fl6_dst)) | 804 | if (rt6_need_strict(&fl->fl6_dst)) |
795 | flags |= RT6_LOOKUP_F_IFACE; | 805 | flags |= RT6_LOOKUP_F_IFACE; |
796 | 806 | ||
807 | if (!ipv6_addr_any(&fl->fl6_src)) | ||
808 | flags |= RT6_LOOKUP_F_HAS_SADDR; | ||
809 | |||
797 | return fib6_rule_lookup(fl, flags, ip6_pol_route_output); | 810 | return fib6_rule_lookup(fl, flags, ip6_pol_route_output); |
798 | } | 811 | } |
799 | 812 | ||
@@ -1345,6 +1358,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, | |||
1345 | struct in6_addr *gateway, | 1358 | struct in6_addr *gateway, |
1346 | struct net_device *dev) | 1359 | struct net_device *dev) |
1347 | { | 1360 | { |
1361 | int flags = RT6_LOOKUP_F_HAS_SADDR; | ||
1348 | struct ip6rd_flowi rdfl = { | 1362 | struct ip6rd_flowi rdfl = { |
1349 | .fl = { | 1363 | .fl = { |
1350 | .oif = dev->ifindex, | 1364 | .oif = dev->ifindex, |
@@ -1357,7 +1371,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, | |||
1357 | }, | 1371 | }, |
1358 | .gateway = *gateway, | 1372 | .gateway = *gateway, |
1359 | }; | 1373 | }; |
1360 | int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0; | 1374 | |
1375 | if (rt6_need_strict(dest)) | ||
1376 | flags |= RT6_LOOKUP_F_IFACE; | ||
1361 | 1377 | ||
1362 | return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); | 1378 | return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); |
1363 | } | 1379 | } |
@@ -1527,6 +1543,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) | |||
1527 | rt->u.dst.output = ort->u.dst.output; | 1543 | rt->u.dst.output = ort->u.dst.output; |
1528 | 1544 | ||
1529 | memcpy(rt->u.dst.metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); | 1545 | memcpy(rt->u.dst.metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); |
1546 | rt->u.dst.error = ort->u.dst.error; | ||
1530 | rt->u.dst.dev = ort->u.dst.dev; | 1547 | rt->u.dst.dev = ort->u.dst.dev; |
1531 | if (rt->u.dst.dev) | 1548 | if (rt->u.dst.dev) |
1532 | dev_hold(rt->u.dst.dev); | 1549 | dev_hold(rt->u.dst.dev); |
@@ -1730,24 +1747,50 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) | |||
1730 | * Drop the packet on the floor | 1747 | * Drop the packet on the floor |
1731 | */ | 1748 | */ |
1732 | 1749 | ||
1733 | static int ip6_pkt_discard(struct sk_buff *skb) | 1750 | static inline int ip6_pkt_drop(struct sk_buff *skb, int code) |
1734 | { | 1751 | { |
1735 | int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); | 1752 | int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); |
1736 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) | 1753 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) |
1737 | IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); | 1754 | IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); |
1738 | 1755 | ||
1739 | IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); | 1756 | IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); |
1740 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); | 1757 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); |
1741 | kfree_skb(skb); | 1758 | kfree_skb(skb); |
1742 | return 0; | 1759 | return 0; |
1743 | } | 1760 | } |
1744 | 1761 | ||
1762 | static int ip6_pkt_discard(struct sk_buff *skb) | ||
1763 | { | ||
1764 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE); | ||
1765 | } | ||
1766 | |||
1745 | static int ip6_pkt_discard_out(struct sk_buff *skb) | 1767 | static int ip6_pkt_discard_out(struct sk_buff *skb) |
1746 | { | 1768 | { |
1747 | skb->dev = skb->dst->dev; | 1769 | skb->dev = skb->dst->dev; |
1748 | return ip6_pkt_discard(skb); | 1770 | return ip6_pkt_discard(skb); |
1749 | } | 1771 | } |
1750 | 1772 | ||
1773 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
1774 | |||
1775 | static int ip6_pkt_prohibit(struct sk_buff *skb) | ||
1776 | { | ||
1777 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED); | ||
1778 | } | ||
1779 | |||
1780 | static int ip6_pkt_prohibit_out(struct sk_buff *skb) | ||
1781 | { | ||
1782 | skb->dev = skb->dst->dev; | ||
1783 | return ip6_pkt_prohibit(skb); | ||
1784 | } | ||
1785 | |||
1786 | static int ip6_pkt_blk_hole(struct sk_buff *skb) | ||
1787 | { | ||
1788 | kfree_skb(skb); | ||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | #endif | ||
1793 | |||
1751 | /* | 1794 | /* |
1752 | * Allocate a dst for local (unicast / anycast) address. | 1795 | * Allocate a dst for local (unicast / anycast) address. |
1753 | */ | 1796 | */ |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 836eecd7e62b..be699f85b2c7 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -850,3 +850,8 @@ int __init sit_init(void) | |||
850 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); | 850 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); |
851 | goto out; | 851 | goto out; |
852 | } | 852 | } |
853 | |||
854 | module_init(sit_init); | ||
855 | module_exit(sit_cleanup); | ||
856 | MODULE_LICENSE("GPL"); | ||
857 | MODULE_ALIAS("sit0"); | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3b6575478fcc..4c2a7c0cafef 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -329,7 +329,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
329 | } | 329 | } |
330 | 330 | ||
331 | if (sk->sk_state == TCP_TIME_WAIT) { | 331 | if (sk->sk_state == TCP_TIME_WAIT) { |
332 | inet_twsk_put((struct inet_timewait_sock *)sk); | 332 | inet_twsk_put(inet_twsk(sk)); |
333 | return; | 333 | return; |
334 | } | 334 | } |
335 | 335 | ||
@@ -653,7 +653,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
653 | int tot_len = sizeof(struct tcphdr); | 653 | int tot_len = sizeof(struct tcphdr); |
654 | 654 | ||
655 | if (ts) | 655 | if (ts) |
656 | tot_len += 3*4; | 656 | tot_len += TCPOLEN_TSTAMP_ALIGNED; |
657 | 657 | ||
658 | buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, | 658 | buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, |
659 | GFP_ATOMIC); | 659 | GFP_ATOMIC); |
@@ -749,7 +749,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
749 | bh_lock_sock(nsk); | 749 | bh_lock_sock(nsk); |
750 | return nsk; | 750 | return nsk; |
751 | } | 751 | } |
752 | inet_twsk_put((struct inet_timewait_sock *)nsk); | 752 | inet_twsk_put(inet_twsk(nsk)); |
753 | return NULL; | 753 | return NULL; |
754 | } | 754 | } |
755 | 755 | ||
@@ -1283,18 +1283,17 @@ discard_and_relse: | |||
1283 | 1283 | ||
1284 | do_time_wait: | 1284 | do_time_wait: |
1285 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 1285 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
1286 | inet_twsk_put((struct inet_timewait_sock *)sk); | 1286 | inet_twsk_put(inet_twsk(sk)); |
1287 | goto discard_it; | 1287 | goto discard_it; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1290 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
1291 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1291 | TCP_INC_STATS_BH(TCP_MIB_INERRS); |
1292 | inet_twsk_put((struct inet_timewait_sock *)sk); | 1292 | inet_twsk_put(inet_twsk(sk)); |
1293 | goto discard_it; | 1293 | goto discard_it; |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, | 1296 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
1297 | skb, th)) { | ||
1298 | case TCP_TW_SYN: | 1297 | case TCP_TW_SYN: |
1299 | { | 1298 | { |
1300 | struct sock *sk2; | 1299 | struct sock *sk2; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e0c3934a7e4b..c83f23e51c46 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -242,14 +242,13 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
242 | { | 242 | { |
243 | struct ipv6_pinfo *np; | 243 | struct ipv6_pinfo *np; |
244 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; | 244 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; |
245 | struct net_device *dev = skb->dev; | ||
246 | struct in6_addr *saddr = &hdr->saddr; | 245 | struct in6_addr *saddr = &hdr->saddr; |
247 | struct in6_addr *daddr = &hdr->daddr; | 246 | struct in6_addr *daddr = &hdr->daddr; |
248 | struct udphdr *uh = (struct udphdr*)(skb->data+offset); | 247 | struct udphdr *uh = (struct udphdr*)(skb->data+offset); |
249 | struct sock *sk; | 248 | struct sock *sk; |
250 | int err; | 249 | int err; |
251 | 250 | ||
252 | sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex); | 251 | sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb)); |
253 | 252 | ||
254 | if (sk == NULL) | 253 | if (sk == NULL) |
255 | return; | 254 | return; |
@@ -348,7 +347,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh, | |||
348 | 347 | ||
349 | read_lock(&udp_hash_lock); | 348 | read_lock(&udp_hash_lock); |
350 | sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | 349 | sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); |
351 | dif = skb->dev->ifindex; | 350 | dif = inet6_iif(skb); |
352 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 351 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
353 | if (!sk) { | 352 | if (!sk) { |
354 | kfree_skb(skb); | 353 | kfree_skb(skb); |
@@ -429,7 +428,7 @@ static int udpv6_rcv(struct sk_buff **pskb) | |||
429 | * check socket cache ... must talk to Alan about his plans | 428 | * check socket cache ... must talk to Alan about his plans |
430 | * for sock caches... i'll skip this for now. | 429 | * for sock caches... i'll skip this for now. |
431 | */ | 430 | */ |
432 | sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); | 431 | sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb)); |
433 | 432 | ||
434 | if (sk == NULL) { | 433 | if (sk == NULL) { |
435 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 434 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 6a252e2134d1..d400f8fae129 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -25,12 +25,14 @@ | |||
25 | static struct dst_ops xfrm6_dst_ops; | 25 | static struct dst_ops xfrm6_dst_ops; |
26 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; | 26 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; |
27 | 27 | ||
28 | static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) | 28 | static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl) |
29 | { | 29 | { |
30 | int err = 0; | 30 | struct dst_entry *dst = ip6_route_output(NULL, fl); |
31 | *dst = (struct xfrm_dst*)ip6_route_output(NULL, fl); | 31 | int err = dst->error; |
32 | if (!*dst) | 32 | if (!err) |
33 | err = -ENETUNREACH; | 33 | *xdst = (struct xfrm_dst *) dst; |
34 | else | ||
35 | dst_release(dst); | ||
34 | return err; | 36 | return err; |
35 | } | 37 | } |
36 | 38 | ||
@@ -73,7 +75,7 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy) | |||
73 | xdst->u.rt6.rt6i_src.plen); | 75 | xdst->u.rt6.rt6i_src.plen); |
74 | if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && | 76 | if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && |
75 | ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && | 77 | ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && |
76 | xfrm_bundle_ok(xdst, fl, AF_INET6, | 78 | xfrm_bundle_ok(policy, xdst, fl, AF_INET6, |
77 | (xdst->u.rt6.rt6i_dst.plen != 128 || | 79 | (xdst->u.rt6.rt6i_dst.plen != 128 || |
78 | xdst->u.rt6.rt6i_src.plen != 128))) { | 80 | xdst->u.rt6.rt6i_src.plen != 128))) { |
79 | dst_clone(dst); | 81 | dst_clone(dst); |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 7af227bb1551..7931e4f898d4 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -135,7 +135,7 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) | |||
135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); | 135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); |
136 | spi = x6spi ? x6spi->spi : 0; | 136 | spi = x6spi ? x6spi->spi : 0; |
137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); | 137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); |
138 | return spi; | 138 | return htonl(spi); |
139 | } | 139 | } |
140 | 140 | ||
141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); | 141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); |
@@ -210,7 +210,7 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) | |||
210 | spi = __xfrm6_tunnel_alloc_spi(saddr); | 210 | spi = __xfrm6_tunnel_alloc_spi(saddr); |
211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); | 211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); |
212 | 212 | ||
213 | return spi; | 213 | return htonl(spi); |
214 | } | 214 | } |
215 | 215 | ||
216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); | 216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index bef3f61569f7..76c661566dfd 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -83,13 +83,13 @@ DEFINE_SPINLOCK(ipx_interfaces_lock); | |||
83 | struct ipx_interface *ipx_primary_net; | 83 | struct ipx_interface *ipx_primary_net; |
84 | struct ipx_interface *ipx_internal_net; | 84 | struct ipx_interface *ipx_internal_net; |
85 | 85 | ||
86 | extern int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, | 86 | extern int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, |
87 | unsigned char *node); | 87 | unsigned char *node); |
88 | extern void ipxrtr_del_routes(struct ipx_interface *intrfc); | 88 | extern void ipxrtr_del_routes(struct ipx_interface *intrfc); |
89 | extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | 89 | extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, |
90 | struct iovec *iov, int len, int noblock); | 90 | struct iovec *iov, int len, int noblock); |
91 | extern int ipxrtr_route_skb(struct sk_buff *skb); | 91 | extern int ipxrtr_route_skb(struct sk_buff *skb); |
92 | extern struct ipx_route *ipxrtr_lookup(__u32 net); | 92 | extern struct ipx_route *ipxrtr_lookup(__be32 net); |
93 | extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); | 93 | extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); |
94 | 94 | ||
95 | #undef IPX_REFCNT_DEBUG | 95 | #undef IPX_REFCNT_DEBUG |
@@ -177,7 +177,7 @@ static void ipxitf_clear_primary_net(void) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, | 179 | static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, |
180 | unsigned short datalink) | 180 | __be16 datalink) |
181 | { | 181 | { |
182 | struct ipx_interface *i; | 182 | struct ipx_interface *i; |
183 | 183 | ||
@@ -190,7 +190,7 @@ out: | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, | 192 | static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, |
193 | unsigned short datalink) | 193 | __be16 datalink) |
194 | { | 194 | { |
195 | struct ipx_interface *i; | 195 | struct ipx_interface *i; |
196 | 196 | ||
@@ -202,7 +202,7 @@ static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, | |||
202 | return i; | 202 | return i; |
203 | } | 203 | } |
204 | 204 | ||
205 | struct ipx_interface *ipxitf_find_using_net(__u32 net) | 205 | struct ipx_interface *ipxitf_find_using_net(__be32 net) |
206 | { | 206 | { |
207 | struct ipx_interface *i; | 207 | struct ipx_interface *i; |
208 | 208 | ||
@@ -237,7 +237,7 @@ static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk) | |||
237 | 237 | ||
238 | /* caller must hold intrfc->if_sklist_lock */ | 238 | /* caller must hold intrfc->if_sklist_lock */ |
239 | static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, | 239 | static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, |
240 | unsigned short port) | 240 | __be16 port) |
241 | { | 241 | { |
242 | struct sock *s; | 242 | struct sock *s; |
243 | struct hlist_node *node; | 243 | struct hlist_node *node; |
@@ -252,7 +252,7 @@ found: | |||
252 | 252 | ||
253 | /* caller must hold a reference to intrfc */ | 253 | /* caller must hold a reference to intrfc */ |
254 | static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, | 254 | static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, |
255 | unsigned short port) | 255 | __be16 port) |
256 | { | 256 | { |
257 | struct sock *s; | 257 | struct sock *s; |
258 | 258 | ||
@@ -268,7 +268,7 @@ static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, | |||
268 | #ifdef CONFIG_IPX_INTERN | 268 | #ifdef CONFIG_IPX_INTERN |
269 | static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, | 269 | static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, |
270 | unsigned char *ipx_node, | 270 | unsigned char *ipx_node, |
271 | unsigned short port) | 271 | __be16 port) |
272 | { | 272 | { |
273 | struct sock *s; | 273 | struct sock *s; |
274 | struct hlist_node *node; | 274 | struct hlist_node *node; |
@@ -600,10 +600,10 @@ int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node) | |||
600 | 600 | ||
601 | /* see if we need to include the netnum in the route list */ | 601 | /* see if we need to include the netnum in the route list */ |
602 | if (IPX_SKB_CB(skb)->last_hop.index >= 0) { | 602 | if (IPX_SKB_CB(skb)->last_hop.index >= 0) { |
603 | u32 *last_hop = (u32 *)(((u8 *) skb->data) + | 603 | __be32 *last_hop = (__be32 *)(((u8 *) skb->data) + |
604 | sizeof(struct ipxhdr) + | 604 | sizeof(struct ipxhdr) + |
605 | IPX_SKB_CB(skb)->last_hop.index * | 605 | IPX_SKB_CB(skb)->last_hop.index * |
606 | sizeof(u32)); | 606 | sizeof(__be32)); |
607 | *last_hop = IPX_SKB_CB(skb)->last_hop.netnum; | 607 | *last_hop = IPX_SKB_CB(skb)->last_hop.netnum; |
608 | IPX_SKB_CB(skb)->last_hop.index = -1; | 608 | IPX_SKB_CB(skb)->last_hop.index = -1; |
609 | } | 609 | } |
@@ -772,7 +772,7 @@ static void ipxitf_discover_netnum(struct ipx_interface *intrfc, | |||
772 | } else { | 772 | } else { |
773 | printk(KERN_WARNING "IPX: Network number collision " | 773 | printk(KERN_WARNING "IPX: Network number collision " |
774 | "%lx\n %s %s and %s %s\n", | 774 | "%lx\n %s %s and %s %s\n", |
775 | (unsigned long) htonl(cb->ipx_source_net), | 775 | (unsigned long) ntohl(cb->ipx_source_net), |
776 | ipx_device_name(i), | 776 | ipx_device_name(i), |
777 | ipx_frame_name(i->if_dlink_type), | 777 | ipx_frame_name(i->if_dlink_type), |
778 | ipx_device_name(intrfc), | 778 | ipx_device_name(intrfc), |
@@ -812,7 +812,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) | |||
812 | int i, rc = -EINVAL; | 812 | int i, rc = -EINVAL; |
813 | struct ipx_interface *ifcs; | 813 | struct ipx_interface *ifcs; |
814 | char *c; | 814 | char *c; |
815 | u32 *l; | 815 | __be32 *l; |
816 | 816 | ||
817 | /* Illegal packet - too many hops or too short */ | 817 | /* Illegal packet - too many hops or too short */ |
818 | /* We decide to throw it away: no broadcasting, no local processing. | 818 | /* We decide to throw it away: no broadcasting, no local processing. |
@@ -833,7 +833,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) | |||
833 | goto out; | 833 | goto out; |
834 | 834 | ||
835 | c = ((u8 *) ipx) + sizeof(struct ipxhdr); | 835 | c = ((u8 *) ipx) + sizeof(struct ipxhdr); |
836 | l = (u32 *) c; | 836 | l = (__be32 *) c; |
837 | 837 | ||
838 | /* Don't broadcast packet if already seen this net */ | 838 | /* Don't broadcast packet if already seen this net */ |
839 | for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) | 839 | for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) |
@@ -855,7 +855,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) | |||
855 | /* That aren't in the list */ | 855 | /* That aren't in the list */ |
856 | if (ifcs == intrfc) | 856 | if (ifcs == intrfc) |
857 | continue; | 857 | continue; |
858 | l = (__u32 *) c; | 858 | l = (__be32 *) c; |
859 | /* don't consider the last entry in the packet list, | 859 | /* don't consider the last entry in the packet list, |
860 | * it is our netnum, and it is not there yet */ | 860 | * it is our netnum, and it is not there yet */ |
861 | for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) | 861 | for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) |
@@ -885,8 +885,8 @@ static void ipxitf_insert(struct ipx_interface *intrfc) | |||
885 | ipx_primary_net = intrfc; | 885 | ipx_primary_net = intrfc; |
886 | } | 886 | } |
887 | 887 | ||
888 | static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, | 888 | static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __be32 netnum, |
889 | unsigned short dlink_type, | 889 | __be16 dlink_type, |
890 | struct datalink_proto *dlink, | 890 | struct datalink_proto *dlink, |
891 | unsigned char internal, | 891 | unsigned char internal, |
892 | int ipx_offset) | 892 | int ipx_offset) |
@@ -960,7 +960,7 @@ static __be16 ipx_map_frame_type(unsigned char type) | |||
960 | static int ipxitf_create(struct ipx_interface_definition *idef) | 960 | static int ipxitf_create(struct ipx_interface_definition *idef) |
961 | { | 961 | { |
962 | struct net_device *dev; | 962 | struct net_device *dev; |
963 | unsigned short dlink_type = 0; | 963 | __be16 dlink_type = 0; |
964 | struct datalink_proto *datalink = NULL; | 964 | struct datalink_proto *datalink = NULL; |
965 | struct ipx_interface *intrfc; | 965 | struct ipx_interface *intrfc; |
966 | int rc; | 966 | int rc; |
@@ -1073,7 +1073,7 @@ out: | |||
1073 | static int ipxitf_delete(struct ipx_interface_definition *idef) | 1073 | static int ipxitf_delete(struct ipx_interface_definition *idef) |
1074 | { | 1074 | { |
1075 | struct net_device *dev = NULL; | 1075 | struct net_device *dev = NULL; |
1076 | unsigned short dlink_type = 0; | 1076 | __be16 dlink_type = 0; |
1077 | struct ipx_interface *intrfc; | 1077 | struct ipx_interface *intrfc; |
1078 | int rc = 0; | 1078 | int rc = 0; |
1079 | 1079 | ||
@@ -1110,7 +1110,7 @@ out: | |||
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, | 1112 | static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, |
1113 | unsigned short dlink_type) | 1113 | __be16 dlink_type) |
1114 | { | 1114 | { |
1115 | struct ipx_interface *intrfc = NULL; | 1115 | struct ipx_interface *intrfc = NULL; |
1116 | struct datalink_proto *datalink; | 1116 | struct datalink_proto *datalink; |
@@ -1122,7 +1122,7 @@ static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, | |||
1122 | if (dev->addr_len > IPX_NODE_LEN) | 1122 | if (dev->addr_len > IPX_NODE_LEN) |
1123 | goto out; | 1123 | goto out; |
1124 | 1124 | ||
1125 | switch (htons(dlink_type)) { | 1125 | switch (ntohs(dlink_type)) { |
1126 | case ETH_P_IPX: datalink = pEII_datalink; break; | 1126 | case ETH_P_IPX: datalink = pEII_datalink; break; |
1127 | case ETH_P_802_2: datalink = p8022_datalink; break; | 1127 | case ETH_P_802_2: datalink = p8022_datalink; break; |
1128 | case ETH_P_SNAP: datalink = pSNAP_datalink; break; | 1128 | case ETH_P_SNAP: datalink = pSNAP_datalink; break; |
@@ -1234,27 +1234,27 @@ static int ipxitf_ioctl(unsigned int cmd, void __user *arg) | |||
1234 | /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ | 1234 | /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ |
1235 | /* This functions should *not* mess with packet contents */ | 1235 | /* This functions should *not* mess with packet contents */ |
1236 | 1236 | ||
1237 | __u16 ipx_cksum(struct ipxhdr *packet, int length) | 1237 | __be16 ipx_cksum(struct ipxhdr *packet, int length) |
1238 | { | 1238 | { |
1239 | /* | 1239 | /* |
1240 | * NOTE: sum is a net byte order quantity, which optimizes the | 1240 | * NOTE: sum is a net byte order quantity, which optimizes the |
1241 | * loop. This only works on big and little endian machines. (I | 1241 | * loop. This only works on big and little endian machines. (I |
1242 | * don't know of a machine that isn't.) | 1242 | * don't know of a machine that isn't.) |
1243 | */ | 1243 | */ |
1244 | /* start at ipx_dest - We skip the checksum field and start with | 1244 | /* handle the first 3 words separately; checksum should be skipped |
1245 | * ipx_type before the loop, not considering ipx_tctrl in the calc */ | 1245 | * and ipx_tctrl masked out */ |
1246 | __u16 *p = (__u16 *)&packet->ipx_dest; | 1246 | __u16 *p = (__u16 *)packet; |
1247 | __u32 i = (length >> 1) - 1; /* Number of complete words */ | 1247 | __u32 sum = p[1] + (p[2] & (__force u16)htons(0x00ff)); |
1248 | __u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl); | 1248 | __u32 i = (length >> 1) - 3; /* Number of remaining complete words */ |
1249 | 1249 | ||
1250 | /* Loop through all complete words except the checksum field, | 1250 | /* Loop through them */ |
1251 | * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */ | 1251 | p += 3; |
1252 | while (--i) | 1252 | while (i--) |
1253 | sum += *p++; | 1253 | sum += *p++; |
1254 | 1254 | ||
1255 | /* Add on the last part word if it exists */ | 1255 | /* Add on the last part word if it exists */ |
1256 | if (packet->ipx_pktsize & htons(1)) | 1256 | if (packet->ipx_pktsize & htons(1)) |
1257 | sum += ntohs(0xff00) & *p; | 1257 | sum += (__force u16)htons(0xff00) & *p; |
1258 | 1258 | ||
1259 | /* Do final fixup */ | 1259 | /* Do final fixup */ |
1260 | sum = (sum & 0xffff) + (sum >> 16); | 1260 | sum = (sum & 0xffff) + (sum >> 16); |
@@ -1263,10 +1263,17 @@ __u16 ipx_cksum(struct ipxhdr *packet, int length) | |||
1263 | if (sum >= 0x10000) | 1263 | if (sum >= 0x10000) |
1264 | sum++; | 1264 | sum++; |
1265 | 1265 | ||
1266 | return ~sum; | 1266 | /* |
1267 | * Leave 0 alone; we don't want 0xffff here. Note that we can't get | ||
1268 | * here with 0x10000, so this check is the same as ((__u16)sum) | ||
1269 | */ | ||
1270 | if (sum) | ||
1271 | sum = ~sum; | ||
1272 | |||
1273 | return (__force __be16)sum; | ||
1267 | } | 1274 | } |
1268 | 1275 | ||
1269 | const char *ipx_frame_name(unsigned short frame) | 1276 | const char *ipx_frame_name(__be16 frame) |
1270 | { | 1277 | { |
1271 | char* rc = "None"; | 1278 | char* rc = "None"; |
1272 | 1279 | ||
@@ -1401,7 +1408,7 @@ out: | |||
1401 | 1408 | ||
1402 | /* caller must hold a reference to intrfc */ | 1409 | /* caller must hold a reference to intrfc */ |
1403 | 1410 | ||
1404 | static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) | 1411 | static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) |
1405 | { | 1412 | { |
1406 | unsigned short socketNum = intrfc->if_sknum; | 1413 | unsigned short socketNum = intrfc->if_sknum; |
1407 | 1414 | ||
@@ -1410,7 +1417,7 @@ static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) | |||
1410 | if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) | 1417 | if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) |
1411 | socketNum = IPX_MIN_EPHEMERAL_SOCKET; | 1418 | socketNum = IPX_MIN_EPHEMERAL_SOCKET; |
1412 | 1419 | ||
1413 | while (__ipxitf_find_socket(intrfc, ntohs(socketNum))) | 1420 | while (__ipxitf_find_socket(intrfc, htons(socketNum))) |
1414 | if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) | 1421 | if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) |
1415 | socketNum = IPX_MIN_EPHEMERAL_SOCKET; | 1422 | socketNum = IPX_MIN_EPHEMERAL_SOCKET; |
1416 | else | 1423 | else |
@@ -1419,7 +1426,7 @@ static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) | |||
1419 | spin_unlock_bh(&intrfc->if_sklist_lock); | 1426 | spin_unlock_bh(&intrfc->if_sklist_lock); |
1420 | intrfc->if_sknum = socketNum; | 1427 | intrfc->if_sknum = socketNum; |
1421 | 1428 | ||
1422 | return ntohs(socketNum); | 1429 | return htons(socketNum); |
1423 | } | 1430 | } |
1424 | 1431 | ||
1425 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 1432 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
@@ -1473,7 +1480,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1473 | ipxs->port)) { | 1480 | ipxs->port)) { |
1474 | SOCK_DEBUG(sk, | 1481 | SOCK_DEBUG(sk, |
1475 | "IPX: bind failed because port %X in use.\n", | 1482 | "IPX: bind failed because port %X in use.\n", |
1476 | ntohs((int)addr->sipx_port)); | 1483 | ntohs(addr->sipx_port)); |
1477 | goto out_put; | 1484 | goto out_put; |
1478 | } | 1485 | } |
1479 | } else { | 1486 | } else { |
@@ -1488,7 +1495,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1488 | if (ipxitf_find_socket(intrfc, addr->sipx_port)) { | 1495 | if (ipxitf_find_socket(intrfc, addr->sipx_port)) { |
1489 | SOCK_DEBUG(sk, | 1496 | SOCK_DEBUG(sk, |
1490 | "IPX: bind failed because port %X in use.\n", | 1497 | "IPX: bind failed because port %X in use.\n", |
1491 | ntohs((int)addr->sipx_port)); | 1498 | ntohs(addr->sipx_port)); |
1492 | goto out_put; | 1499 | goto out_put; |
1493 | } | 1500 | } |
1494 | } | 1501 | } |
@@ -1665,7 +1672,7 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty | |||
1665 | intrfc = ipxitf_find_using_phys(dev, pt->type); | 1672 | intrfc = ipxitf_find_using_phys(dev, pt->type); |
1666 | if (!intrfc) { | 1673 | if (!intrfc) { |
1667 | if (ipxcfg_auto_create_interfaces && | 1674 | if (ipxcfg_auto_create_interfaces && |
1668 | ntohl(IPX_SKB_CB(skb)->ipx_dest_net)) { | 1675 | IPX_SKB_CB(skb)->ipx_dest_net) { |
1669 | intrfc = ipxitf_auto_create(dev, pt->type); | 1676 | intrfc = ipxitf_auto_create(dev, pt->type); |
1670 | if (intrfc) | 1677 | if (intrfc) |
1671 | ipxitf_hold(intrfc); | 1678 | ipxitf_hold(intrfc); |
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index 4c0c71206e54..b7463dfca63e 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c | |||
@@ -260,22 +260,22 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) | |||
260 | ipxs = ipx_sk(s); | 260 | ipxs = ipx_sk(s); |
261 | #ifdef CONFIG_IPX_INTERN | 261 | #ifdef CONFIG_IPX_INTERN |
262 | seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", | 262 | seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", |
263 | (unsigned long)htonl(ipxs->intrfc->if_netnum), | 263 | (unsigned long)ntohl(ipxs->intrfc->if_netnum), |
264 | ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3], | 264 | ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3], |
265 | ipxs->node[4], ipxs->node[5], htons(ipxs->port)); | 265 | ipxs->node[4], ipxs->node[5], ntohs(ipxs->port)); |
266 | #else | 266 | #else |
267 | seq_printf(seq, "%08lX:%04X ", (unsigned long) htonl(ipxs->intrfc->if_netnum), | 267 | seq_printf(seq, "%08lX:%04X ", (unsigned long) ntohl(ipxs->intrfc->if_netnum), |
268 | htons(ipxs->port)); | 268 | ntohs(ipxs->port)); |
269 | #endif /* CONFIG_IPX_INTERN */ | 269 | #endif /* CONFIG_IPX_INTERN */ |
270 | if (s->sk_state != TCP_ESTABLISHED) | 270 | if (s->sk_state != TCP_ESTABLISHED) |
271 | seq_printf(seq, "%-28s", "Not_Connected"); | 271 | seq_printf(seq, "%-28s", "Not_Connected"); |
272 | else { | 272 | else { |
273 | seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", | 273 | seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", |
274 | (unsigned long)htonl(ipxs->dest_addr.net), | 274 | (unsigned long)ntohl(ipxs->dest_addr.net), |
275 | ipxs->dest_addr.node[0], ipxs->dest_addr.node[1], | 275 | ipxs->dest_addr.node[0], ipxs->dest_addr.node[1], |
276 | ipxs->dest_addr.node[2], ipxs->dest_addr.node[3], | 276 | ipxs->dest_addr.node[2], ipxs->dest_addr.node[3], |
277 | ipxs->dest_addr.node[4], ipxs->dest_addr.node[5], | 277 | ipxs->dest_addr.node[4], ipxs->dest_addr.node[5], |
278 | htons(ipxs->dest_addr.sock)); | 278 | ntohs(ipxs->dest_addr.sock)); |
279 | } | 279 | } |
280 | 280 | ||
281 | seq_printf(seq, "%08X %08X %02X %03d\n", | 281 | seq_printf(seq, "%08X %08X %02X %03d\n", |
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c index a30dbb1e08fb..68560ee0d797 100644 --- a/net/ipx/ipx_route.c +++ b/net/ipx/ipx_route.c | |||
@@ -19,17 +19,17 @@ DEFINE_RWLOCK(ipx_routes_lock); | |||
19 | 19 | ||
20 | extern struct ipx_interface *ipx_internal_net; | 20 | extern struct ipx_interface *ipx_internal_net; |
21 | 21 | ||
22 | extern __u16 ipx_cksum(struct ipxhdr *packet, int length); | 22 | extern __be16 ipx_cksum(struct ipxhdr *packet, int length); |
23 | extern struct ipx_interface *ipxitf_find_using_net(__u32 net); | 23 | extern struct ipx_interface *ipxitf_find_using_net(__be32 net); |
24 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, | 24 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, |
25 | struct sk_buff *skb, int copy); | 25 | struct sk_buff *skb, int copy); |
26 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, | 26 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, |
27 | struct sk_buff *skb, int copy); | 27 | struct sk_buff *skb, int copy); |
28 | extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, | 28 | extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, |
29 | char *node); | 29 | char *node); |
30 | extern struct ipx_interface *ipxitf_find_using_net(__u32 net); | 30 | extern struct ipx_interface *ipxitf_find_using_net(__be32 net); |
31 | 31 | ||
32 | struct ipx_route *ipxrtr_lookup(__u32 net) | 32 | struct ipx_route *ipxrtr_lookup(__be32 net) |
33 | { | 33 | { |
34 | struct ipx_route *r; | 34 | struct ipx_route *r; |
35 | 35 | ||
@@ -48,7 +48,7 @@ unlock: | |||
48 | /* | 48 | /* |
49 | * Caller must hold a reference to intrfc | 49 | * Caller must hold a reference to intrfc |
50 | */ | 50 | */ |
51 | int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, | 51 | int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, |
52 | unsigned char *node) | 52 | unsigned char *node) |
53 | { | 53 | { |
54 | struct ipx_route *rt; | 54 | struct ipx_route *rt; |
@@ -118,7 +118,7 @@ out: | |||
118 | return rc; | 118 | return rc; |
119 | } | 119 | } |
120 | 120 | ||
121 | static int ipxrtr_delete(__u32 net) | 121 | static int ipxrtr_delete(__be32 net) |
122 | { | 122 | { |
123 | struct ipx_route *r, *tmp; | 123 | struct ipx_route *r, *tmp; |
124 | int rc; | 124 | int rc; |
@@ -238,7 +238,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | |||
238 | 238 | ||
239 | /* Apply checksum. Not allowed on 802.3 links. */ | 239 | /* Apply checksum. Not allowed on 802.3 links. */ |
240 | if (sk->sk_no_check || intrfc->if_dlink_type == htons(IPX_FRAME_8023)) | 240 | if (sk->sk_no_check || intrfc->if_dlink_type == htons(IPX_FRAME_8023)) |
241 | ipx->ipx_checksum = 0xFFFF; | 241 | ipx->ipx_checksum = htons(0xFFFF); |
242 | else | 242 | else |
243 | ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); | 243 | ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); |
244 | 244 | ||
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 5073261b9d0c..fede83763095 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c | |||
@@ -1678,7 +1678,8 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) | |||
1678 | * every IrLAP connection and check every LSAP associated with each | 1678 | * every IrLAP connection and check every LSAP associated with each |
1679 | * the connection. | 1679 | * the connection. |
1680 | */ | 1680 | */ |
1681 | spin_lock_irqsave(&irlmp->links->hb_spinlock, flags); | 1681 | spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags, |
1682 | SINGLE_DEPTH_NESTING); | ||
1682 | lap = (struct lap_cb *) hashbin_get_first(irlmp->links); | 1683 | lap = (struct lap_cb *) hashbin_get_first(irlmp->links); |
1683 | while (lap != NULL) { | 1684 | while (lap != NULL) { |
1684 | IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); | 1685 | IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); |
diff --git a/net/key/af_key.c b/net/key/af_key.c index ff98e70b0931..20ff7cca1d07 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2928,11 +2928,6 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
2928 | if (*dir) | 2928 | if (*dir) |
2929 | goto out; | 2929 | goto out; |
2930 | } | 2930 | } |
2931 | else { | ||
2932 | *dir = security_xfrm_sock_policy_alloc(xp, sk); | ||
2933 | if (*dir) | ||
2934 | goto out; | ||
2935 | } | ||
2936 | 2931 | ||
2937 | *dir = pol->sadb_x_policy_dir-1; | 2932 | *dir = pol->sadb_x_policy_dir-1; |
2938 | return xp; | 2933 | return xp; |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index ce94732b8e23..f619c6527266 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -209,7 +209,9 @@ config NETFILTER_XT_TARGET_SECMARK | |||
209 | 209 | ||
210 | config NETFILTER_XT_TARGET_CONNSECMARK | 210 | config NETFILTER_XT_TARGET_CONNSECMARK |
211 | tristate '"CONNSECMARK" target support' | 211 | tristate '"CONNSECMARK" target support' |
212 | depends on NETFILTER_XTABLES && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK) | 212 | depends on NETFILTER_XTABLES && \ |
213 | ((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \ | ||
214 | (IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK)) | ||
213 | help | 215 | help |
214 | The CONNSECMARK target copies security markings from packets | 216 | The CONNSECMARK target copies security markings from packets |
215 | to connections, and restores security markings from connections | 217 | to connections, and restores security markings from connections |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 093b3ddc513c..836541e509fe 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1520,9 +1520,10 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data), | |||
1520 | if (iter(ct, data)) | 1520 | if (iter(ct, data)) |
1521 | goto found; | 1521 | goto found; |
1522 | } | 1522 | } |
1523 | write_unlock_bh(&nf_conntrack_lock); | ||
1523 | return NULL; | 1524 | return NULL; |
1524 | found: | 1525 | found: |
1525 | atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); | 1526 | atomic_inc(&ct->ct_general.use); |
1526 | write_unlock_bh(&nf_conntrack_lock); | 1527 | write_unlock_bh(&nf_conntrack_lock); |
1527 | return ct; | 1528 | return ct; |
1528 | } | 1529 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 1721f7c78c77..bd0156a28ecd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -47,13 +47,6 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | static char __initdata version[] = "0.93"; | 48 | static char __initdata version[] = "0.93"; |
49 | 49 | ||
50 | #if 0 | ||
51 | #define DEBUGP printk | ||
52 | #else | ||
53 | #define DEBUGP(format, args...) | ||
54 | #endif | ||
55 | |||
56 | |||
57 | static inline int | 50 | static inline int |
58 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, | 51 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, |
59 | const struct nf_conntrack_tuple *tuple, | 52 | const struct nf_conntrack_tuple *tuple, |
@@ -410,7 +403,6 @@ static int ctnetlink_done(struct netlink_callback *cb) | |||
410 | { | 403 | { |
411 | if (cb->args[1]) | 404 | if (cb->args[1]) |
412 | nf_ct_put((struct nf_conn *)cb->args[1]); | 405 | nf_ct_put((struct nf_conn *)cb->args[1]); |
413 | DEBUGP("entered %s\n", __FUNCTION__); | ||
414 | return 0; | 406 | return 0; |
415 | } | 407 | } |
416 | 408 | ||
@@ -425,9 +417,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
425 | struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); | 417 | struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); |
426 | u_int8_t l3proto = nfmsg->nfgen_family; | 418 | u_int8_t l3proto = nfmsg->nfgen_family; |
427 | 419 | ||
428 | DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, | ||
429 | cb->args[0], *id); | ||
430 | |||
431 | read_lock_bh(&nf_conntrack_lock); | 420 | read_lock_bh(&nf_conntrack_lock); |
432 | last = (struct nf_conn *)cb->args[1]; | 421 | last = (struct nf_conn *)cb->args[1]; |
433 | for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { | 422 | for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { |
@@ -471,7 +460,6 @@ out: | |||
471 | if (last) | 460 | if (last) |
472 | nf_ct_put(last); | 461 | nf_ct_put(last); |
473 | 462 | ||
474 | DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); | ||
475 | return skb->len; | 463 | return skb->len; |
476 | } | 464 | } |
477 | 465 | ||
@@ -482,8 +470,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) | |||
482 | struct nf_conntrack_l3proto *l3proto; | 470 | struct nf_conntrack_l3proto *l3proto; |
483 | int ret = 0; | 471 | int ret = 0; |
484 | 472 | ||
485 | DEBUGP("entered %s\n", __FUNCTION__); | ||
486 | |||
487 | nfattr_parse_nested(tb, CTA_IP_MAX, attr); | 473 | nfattr_parse_nested(tb, CTA_IP_MAX, attr); |
488 | 474 | ||
489 | l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); | 475 | 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) | |||
493 | 479 | ||
494 | nf_ct_l3proto_put(l3proto); | 480 | nf_ct_l3proto_put(l3proto); |
495 | 481 | ||
496 | DEBUGP("leaving\n"); | ||
497 | |||
498 | return ret; | 482 | return ret; |
499 | } | 483 | } |
500 | 484 | ||
@@ -510,8 +494,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr, | |||
510 | struct nf_conntrack_protocol *proto; | 494 | struct nf_conntrack_protocol *proto; |
511 | int ret = 0; | 495 | int ret = 0; |
512 | 496 | ||
513 | DEBUGP("entered %s\n", __FUNCTION__); | ||
514 | |||
515 | nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); | 497 | nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); |
516 | 498 | ||
517 | if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) | 499 | 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, | |||
538 | struct nfattr *tb[CTA_TUPLE_MAX]; | 520 | struct nfattr *tb[CTA_TUPLE_MAX]; |
539 | int err; | 521 | int err; |
540 | 522 | ||
541 | DEBUGP("entered %s\n", __FUNCTION__); | ||
542 | |||
543 | memset(tuple, 0, sizeof(*tuple)); | 523 | memset(tuple, 0, sizeof(*tuple)); |
544 | 524 | ||
545 | nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); | 525 | 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, | |||
566 | else | 546 | else |
567 | tuple->dst.dir = IP_CT_DIR_ORIGINAL; | 547 | tuple->dst.dir = IP_CT_DIR_ORIGINAL; |
568 | 548 | ||
569 | NF_CT_DUMP_TUPLE(tuple); | ||
570 | |||
571 | DEBUGP("leaving\n"); | ||
572 | |||
573 | return 0; | 549 | return 0; |
574 | } | 550 | } |
575 | 551 | ||
@@ -586,8 +562,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, | |||
586 | struct nfattr *tb[CTA_PROTONAT_MAX]; | 562 | struct nfattr *tb[CTA_PROTONAT_MAX]; |
587 | struct ip_nat_protocol *npt; | 563 | struct ip_nat_protocol *npt; |
588 | 564 | ||
589 | DEBUGP("entered %s\n", __FUNCTION__); | ||
590 | |||
591 | nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); | 565 | nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); |
592 | 566 | ||
593 | if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) | 567 | if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) |
@@ -606,7 +580,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, | |||
606 | 580 | ||
607 | ip_nat_proto_put(npt); | 581 | ip_nat_proto_put(npt); |
608 | 582 | ||
609 | DEBUGP("leaving\n"); | ||
610 | return 0; | 583 | return 0; |
611 | } | 584 | } |
612 | 585 | ||
@@ -622,8 +595,6 @@ ctnetlink_parse_nat(struct nfattr *nat, | |||
622 | struct nfattr *tb[CTA_NAT_MAX]; | 595 | struct nfattr *tb[CTA_NAT_MAX]; |
623 | int err; | 596 | int err; |
624 | 597 | ||
625 | DEBUGP("entered %s\n", __FUNCTION__); | ||
626 | |||
627 | memset(range, 0, sizeof(*range)); | 598 | memset(range, 0, sizeof(*range)); |
628 | 599 | ||
629 | nfattr_parse_nested(tb, CTA_NAT_MAX, nat); | 600 | nfattr_parse_nested(tb, CTA_NAT_MAX, nat); |
@@ -649,7 +620,6 @@ ctnetlink_parse_nat(struct nfattr *nat, | |||
649 | if (err < 0) | 620 | if (err < 0) |
650 | return err; | 621 | return err; |
651 | 622 | ||
652 | DEBUGP("leaving\n"); | ||
653 | return 0; | 623 | return 0; |
654 | } | 624 | } |
655 | #endif | 625 | #endif |
@@ -659,8 +629,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name) | |||
659 | { | 629 | { |
660 | struct nfattr *tb[CTA_HELP_MAX]; | 630 | struct nfattr *tb[CTA_HELP_MAX]; |
661 | 631 | ||
662 | DEBUGP("entered %s\n", __FUNCTION__); | ||
663 | |||
664 | nfattr_parse_nested(tb, CTA_HELP_MAX, attr); | 632 | nfattr_parse_nested(tb, CTA_HELP_MAX, attr); |
665 | 633 | ||
666 | if (!tb[CTA_HELP_NAME-1]) | 634 | if (!tb[CTA_HELP_NAME-1]) |
@@ -690,8 +658,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
690 | u_int8_t u3 = nfmsg->nfgen_family; | 658 | u_int8_t u3 = nfmsg->nfgen_family; |
691 | int err = 0; | 659 | int err = 0; |
692 | 660 | ||
693 | DEBUGP("entered %s\n", __FUNCTION__); | ||
694 | |||
695 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) | 661 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) |
696 | return -EINVAL; | 662 | return -EINVAL; |
697 | 663 | ||
@@ -709,10 +675,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
709 | return err; | 675 | return err; |
710 | 676 | ||
711 | h = nf_conntrack_find_get(&tuple, NULL); | 677 | h = nf_conntrack_find_get(&tuple, NULL); |
712 | if (!h) { | 678 | if (!h) |
713 | DEBUGP("tuple not found in conntrack hash\n"); | ||
714 | return -ENOENT; | 679 | return -ENOENT; |
715 | } | ||
716 | 680 | ||
717 | ct = nf_ct_tuplehash_to_ctrack(h); | 681 | ct = nf_ct_tuplehash_to_ctrack(h); |
718 | 682 | ||
@@ -727,7 +691,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
727 | ct->timeout.function((unsigned long)ct); | 691 | ct->timeout.function((unsigned long)ct); |
728 | 692 | ||
729 | nf_ct_put(ct); | 693 | nf_ct_put(ct); |
730 | DEBUGP("leaving\n"); | ||
731 | 694 | ||
732 | return 0; | 695 | return 0; |
733 | } | 696 | } |
@@ -744,8 +707,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
744 | u_int8_t u3 = nfmsg->nfgen_family; | 707 | u_int8_t u3 = nfmsg->nfgen_family; |
745 | int err = 0; | 708 | int err = 0; |
746 | 709 | ||
747 | DEBUGP("entered %s\n", __FUNCTION__); | ||
748 | |||
749 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 710 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
750 | u32 rlen; | 711 | u32 rlen; |
751 | 712 | ||
@@ -779,11 +740,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
779 | return err; | 740 | return err; |
780 | 741 | ||
781 | h = nf_conntrack_find_get(&tuple, NULL); | 742 | h = nf_conntrack_find_get(&tuple, NULL); |
782 | if (!h) { | 743 | if (!h) |
783 | DEBUGP("tuple not found in conntrack hash"); | ||
784 | return -ENOENT; | 744 | return -ENOENT; |
785 | } | 745 | |
786 | DEBUGP("tuple found\n"); | ||
787 | ct = nf_ct_tuplehash_to_ctrack(h); | 746 | ct = nf_ct_tuplehash_to_ctrack(h); |
788 | 747 | ||
789 | err = -ENOMEM; | 748 | err = -ENOMEM; |
@@ -804,7 +763,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
804 | if (err < 0) | 763 | if (err < 0) |
805 | goto out; | 764 | goto out; |
806 | 765 | ||
807 | DEBUGP("leaving\n"); | ||
808 | return 0; | 766 | return 0; |
809 | 767 | ||
810 | free: | 768 | free: |
@@ -876,8 +834,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
876 | char *helpname; | 834 | char *helpname; |
877 | int err; | 835 | int err; |
878 | 836 | ||
879 | DEBUGP("entered %s\n", __FUNCTION__); | ||
880 | |||
881 | if (!help) { | 837 | if (!help) { |
882 | /* FIXME: we need to reallocate and rehash */ | 838 | /* FIXME: we need to reallocate and rehash */ |
883 | return -EBUSY; | 839 | return -EBUSY; |
@@ -954,8 +910,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) | |||
954 | { | 910 | { |
955 | int err; | 911 | int err; |
956 | 912 | ||
957 | DEBUGP("entered %s\n", __FUNCTION__); | ||
958 | |||
959 | if (cda[CTA_HELP-1]) { | 913 | if (cda[CTA_HELP-1]) { |
960 | err = ctnetlink_change_helper(ct, cda); | 914 | err = ctnetlink_change_helper(ct, cda); |
961 | if (err < 0) | 915 | if (err < 0) |
@@ -985,7 +939,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) | |||
985 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); | 939 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); |
986 | #endif | 940 | #endif |
987 | 941 | ||
988 | DEBUGP("all done\n"); | ||
989 | return 0; | 942 | return 0; |
990 | } | 943 | } |
991 | 944 | ||
@@ -997,8 +950,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
997 | struct nf_conn *ct; | 950 | struct nf_conn *ct; |
998 | int err = -EINVAL; | 951 | int err = -EINVAL; |
999 | 952 | ||
1000 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1001 | |||
1002 | ct = nf_conntrack_alloc(otuple, rtuple); | 953 | ct = nf_conntrack_alloc(otuple, rtuple); |
1003 | if (ct == NULL || IS_ERR(ct)) | 954 | if (ct == NULL || IS_ERR(ct)) |
1004 | return -ENOMEM; | 955 | return -ENOMEM; |
@@ -1028,7 +979,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
1028 | add_timer(&ct->timeout); | 979 | add_timer(&ct->timeout); |
1029 | nf_conntrack_hash_insert(ct); | 980 | nf_conntrack_hash_insert(ct); |
1030 | 981 | ||
1031 | DEBUGP("conntrack with id %u inserted\n", ct->id); | ||
1032 | return 0; | 982 | return 0; |
1033 | 983 | ||
1034 | err: | 984 | err: |
@@ -1046,8 +996,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1046 | u_int8_t u3 = nfmsg->nfgen_family; | 996 | u_int8_t u3 = nfmsg->nfgen_family; |
1047 | int err = 0; | 997 | int err = 0; |
1048 | 998 | ||
1049 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1050 | |||
1051 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) | 999 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) |
1052 | return -EINVAL; | 1000 | return -EINVAL; |
1053 | 1001 | ||
@@ -1071,7 +1019,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1071 | 1019 | ||
1072 | if (h == NULL) { | 1020 | if (h == NULL) { |
1073 | write_unlock_bh(&nf_conntrack_lock); | 1021 | write_unlock_bh(&nf_conntrack_lock); |
1074 | DEBUGP("no such conntrack, create new\n"); | ||
1075 | err = -ENOENT; | 1022 | err = -ENOENT; |
1076 | if (nlh->nlmsg_flags & NLM_F_CREATE) | 1023 | if (nlh->nlmsg_flags & NLM_F_CREATE) |
1077 | err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); | 1024 | err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); |
@@ -1087,7 +1034,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1087 | 1034 | ||
1088 | /* We manipulate the conntrack inside the global conntrack table lock, | 1035 | /* We manipulate the conntrack inside the global conntrack table lock, |
1089 | * so there's no need to increase the refcount */ | 1036 | * so there's no need to increase the refcount */ |
1090 | DEBUGP("conntrack found\n"); | ||
1091 | err = -EEXIST; | 1037 | err = -EEXIST; |
1092 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) | 1038 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) |
1093 | err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); | 1039 | 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) | |||
1268 | struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); | 1214 | struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); |
1269 | u_int8_t l3proto = nfmsg->nfgen_family; | 1215 | u_int8_t l3proto = nfmsg->nfgen_family; |
1270 | 1216 | ||
1271 | DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id); | ||
1272 | |||
1273 | read_lock_bh(&nf_conntrack_lock); | 1217 | read_lock_bh(&nf_conntrack_lock); |
1274 | list_for_each_prev(i, &nf_conntrack_expect_list) { | 1218 | list_for_each_prev(i, &nf_conntrack_expect_list) { |
1275 | exp = (struct nf_conntrack_expect *) i; | 1219 | exp = (struct nf_conntrack_expect *) i; |
@@ -1287,8 +1231,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
1287 | out: | 1231 | out: |
1288 | read_unlock_bh(&nf_conntrack_lock); | 1232 | read_unlock_bh(&nf_conntrack_lock); |
1289 | 1233 | ||
1290 | DEBUGP("leaving, last id=%llu\n", *id); | ||
1291 | |||
1292 | return skb->len; | 1234 | return skb->len; |
1293 | } | 1235 | } |
1294 | 1236 | ||
@@ -1308,8 +1250,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1308 | u_int8_t u3 = nfmsg->nfgen_family; | 1250 | u_int8_t u3 = nfmsg->nfgen_family; |
1309 | int err = 0; | 1251 | int err = 0; |
1310 | 1252 | ||
1311 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1312 | |||
1313 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) | 1253 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) |
1314 | return -EINVAL; | 1254 | return -EINVAL; |
1315 | 1255 | ||
@@ -1460,8 +1400,6 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3) | |||
1460 | struct nf_conn_help *help; | 1400 | struct nf_conn_help *help; |
1461 | int err = 0; | 1401 | int err = 0; |
1462 | 1402 | ||
1463 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1464 | |||
1465 | /* caller guarantees that those three CTA_EXPECT_* exist */ | 1403 | /* caller guarantees that those three CTA_EXPECT_* exist */ |
1466 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); | 1404 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); |
1467 | if (err < 0) | 1405 | if (err < 0) |
@@ -1516,8 +1454,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1516 | u_int8_t u3 = nfmsg->nfgen_family; | 1454 | u_int8_t u3 = nfmsg->nfgen_family; |
1517 | int err = 0; | 1455 | int err = 0; |
1518 | 1456 | ||
1519 | DEBUGP("entered %s\n", __FUNCTION__); | ||
1520 | |||
1521 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) | 1457 | if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) |
1522 | return -EINVAL; | 1458 | return -EINVAL; |
1523 | 1459 | ||
@@ -1546,8 +1482,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1546 | err = ctnetlink_change_expect(exp, cda); | 1482 | err = ctnetlink_change_expect(exp, cda); |
1547 | write_unlock_bh(&nf_conntrack_lock); | 1483 | write_unlock_bh(&nf_conntrack_lock); |
1548 | 1484 | ||
1549 | DEBUGP("leaving\n"); | ||
1550 | |||
1551 | return err; | 1485 | return err; |
1552 | } | 1486 | } |
1553 | 1487 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index b59d3b2bde21..1e5207b80fe5 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -427,7 +427,7 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
427 | nfmsg->version = NFNETLINK_V0; | 427 | nfmsg->version = NFNETLINK_V0; |
428 | nfmsg->res_id = htons(inst->group_num); | 428 | nfmsg->res_id = htons(inst->group_num); |
429 | 429 | ||
430 | pmsg.hw_protocol = htons(skb->protocol); | 430 | pmsg.hw_protocol = skb->protocol; |
431 | pmsg.hook = hooknum; | 431 | pmsg.hook = hooknum; |
432 | 432 | ||
433 | NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); | 433 | NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); |
@@ -544,7 +544,7 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
544 | } | 544 | } |
545 | /* global sequence number */ | 545 | /* global sequence number */ |
546 | if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { | 546 | if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { |
547 | tmp_uint = atomic_inc_return(&global_seq); | 547 | tmp_uint = htonl(atomic_inc_return(&global_seq)); |
548 | NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); | 548 | NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); |
549 | } | 549 | } |
550 | 550 | ||
@@ -878,7 +878,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
878 | params = NFA_DATA(nfula[NFULA_CFG_MODE-1]); | 878 | params = NFA_DATA(nfula[NFULA_CFG_MODE-1]); |
879 | 879 | ||
880 | nfulnl_set_mode(inst, params->copy_mode, | 880 | nfulnl_set_mode(inst, params->copy_mode, |
881 | ntohs(params->copy_range)); | 881 | ntohl(params->copy_range)); |
882 | } | 882 | } |
883 | 883 | ||
884 | if (nfula[NFULA_CFG_TIMEOUT-1]) { | 884 | if (nfula[NFULA_CFG_TIMEOUT-1]) { |
@@ -896,8 +896,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
896 | } | 896 | } |
897 | 897 | ||
898 | if (nfula[NFULA_CFG_QTHRESH-1]) { | 898 | if (nfula[NFULA_CFG_QTHRESH-1]) { |
899 | u_int32_t qthresh = | 899 | __be32 qthresh = |
900 | *(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]); | 900 | *(__be32 *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]); |
901 | 901 | ||
902 | nfulnl_set_qthresh(inst, ntohl(qthresh)); | 902 | nfulnl_set_qthresh(inst, ntohl(qthresh)); |
903 | } | 903 | } |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 8eb2473d83e1..e815a9aa6e95 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -414,7 +414,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
414 | nfmsg->res_id = htons(queue->queue_num); | 414 | nfmsg->res_id = htons(queue->queue_num); |
415 | 415 | ||
416 | pmsg.packet_id = htonl(entry->id); | 416 | pmsg.packet_id = htonl(entry->id); |
417 | pmsg.hw_protocol = htons(entskb->protocol); | 417 | pmsg.hw_protocol = entskb->protocol; |
418 | pmsg.hook = entinf->hook; | 418 | pmsg.hook = entinf->hook; |
419 | 419 | ||
420 | NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); | 420 | NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); |
@@ -622,9 +622,10 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) | |||
622 | int diff; | 622 | int diff; |
623 | 623 | ||
624 | diff = data_len - e->skb->len; | 624 | diff = data_len - e->skb->len; |
625 | if (diff < 0) | 625 | if (diff < 0) { |
626 | skb_trim(e->skb, data_len); | 626 | if (pskb_trim(e->skb, data_len)) |
627 | else if (diff > 0) { | 627 | return -ENOMEM; |
628 | } else if (diff > 0) { | ||
628 | if (data_len > 0xFFFF) | 629 | if (data_len > 0xFFFF) |
629 | return -EINVAL; | 630 | return -EINVAL; |
630 | if (diff > skb_tailroom(e->skb)) { | 631 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c index db9b896e57c8..39e117502bd7 100644 --- a/net/netfilter/xt_NFQUEUE.c +++ b/net/netfilter/xt_NFQUEUE.c | |||
@@ -68,7 +68,7 @@ static int __init xt_nfqueue_init(void) | |||
68 | 68 | ||
69 | static void __exit xt_nfqueue_fini(void) | 69 | static void __exit xt_nfqueue_fini(void) |
70 | { | 70 | { |
71 | xt_register_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target)); | 71 | xt_unregister_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target)); |
72 | } | 72 | } |
73 | 73 | ||
74 | module_init(xt_nfqueue_init); | 74 | module_init(xt_nfqueue_init); |
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index 92a5726ef237..a8f03057dbde 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c | |||
@@ -147,7 +147,7 @@ static int __init xt_connmark_init(void) | |||
147 | 147 | ||
148 | static void __exit xt_connmark_fini(void) | 148 | static void __exit xt_connmark_fini(void) |
149 | { | 149 | { |
150 | xt_register_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match)); | 150 | xt_unregister_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match)); |
151 | } | 151 | } |
152 | 152 | ||
153 | module_init(xt_connmark_init); | 153 | module_init(xt_connmark_init); |
diff --git a/net/netlabel/Kconfig b/net/netlabel/Kconfig index 9f7121ae13e9..56958c85f2b4 100644 --- a/net/netlabel/Kconfig +++ b/net/netlabel/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config NETLABEL | 5 | config NETLABEL |
6 | bool "NetLabel subsystem support" | 6 | bool "NetLabel subsystem support" |
7 | depends on NET && SECURITY | 7 | depends on SECURITY |
8 | default n | 8 | default n |
9 | ---help--- | 9 | ---help--- |
10 | NetLabel provides support for explicit network packet labeling | 10 | NetLabel provides support for explicit network packet labeling |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 54fb7de3c2b1..ff971103fd0c 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -200,7 +200,7 @@ void netlbl_cache_invalidate(void) | |||
200 | int netlbl_cache_add(const struct sk_buff *skb, | 200 | int netlbl_cache_add(const struct sk_buff *skb, |
201 | const struct netlbl_lsm_secattr *secattr) | 201 | const struct netlbl_lsm_secattr *secattr) |
202 | { | 202 | { |
203 | if (secattr->cache.data == NULL) | 203 | if (secattr->cache == NULL) |
204 | return -ENOMSG; | 204 | return -ENOMSG; |
205 | 205 | ||
206 | if (CIPSO_V4_OPTEXIST(skb)) | 206 | if (CIPSO_V4_OPTEXIST(skb)) |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d56e0d21f919..d527c8977b1f 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1075,8 +1075,9 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, | |||
1075 | return -EINVAL; | 1075 | return -EINVAL; |
1076 | len = sizeof(int); | 1076 | len = sizeof(int); |
1077 | val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; | 1077 | val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; |
1078 | put_user(len, optlen); | 1078 | if (put_user(len, optlen) || |
1079 | put_user(val, optval); | 1079 | put_user(val, optval)) |
1080 | return -EFAULT; | ||
1080 | err = 0; | 1081 | err = 0; |
1081 | break; | 1082 | break; |
1082 | default: | 1083 | default: |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index bb3ddd4784b1..4b52fa78935a 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -786,11 +786,10 @@ static long htb_do_events(struct htb_sched *q, int level) | |||
786 | for (i = 0; i < 500; i++) { | 786 | for (i = 0; i < 500; i++) { |
787 | struct htb_class *cl; | 787 | struct htb_class *cl; |
788 | long diff; | 788 | long diff; |
789 | struct rb_node *p = q->wait_pq[level].rb_node; | 789 | struct rb_node *p = rb_first(&q->wait_pq[level]); |
790 | |||
790 | if (!p) | 791 | if (!p) |
791 | return 0; | 792 | return 0; |
792 | while (p->rb_left) | ||
793 | p = p->rb_left; | ||
794 | 793 | ||
795 | cl = rb_entry(p, struct htb_class, pq_node); | 794 | cl = rb_entry(p, struct htb_class, pq_node); |
796 | if (time_after(cl->pq_key, q->jiffies)) { | 795 | if (time_after(cl->pq_key, q->jiffies)) { |
@@ -1285,8 +1284,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) | |||
1285 | struct htb_class, sibling)); | 1284 | struct htb_class, sibling)); |
1286 | 1285 | ||
1287 | /* note: this delete may happen twice (see htb_delete) */ | 1286 | /* note: this delete may happen twice (see htb_delete) */ |
1288 | if (!hlist_unhashed(&cl->hlist)) | 1287 | hlist_del_init(&cl->hlist); |
1289 | hlist_del(&cl->hlist); | ||
1290 | list_del(&cl->sibling); | 1288 | list_del(&cl->sibling); |
1291 | 1289 | ||
1292 | if (cl->prio_activity) | 1290 | if (cl->prio_activity) |
@@ -1334,8 +1332,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) | |||
1334 | sch_tree_lock(sch); | 1332 | sch_tree_lock(sch); |
1335 | 1333 | ||
1336 | /* delete from hash and active; remainder in destroy_class */ | 1334 | /* delete from hash and active; remainder in destroy_class */ |
1337 | if (!hlist_unhashed(&cl->hlist)) | 1335 | hlist_del_init(&cl->hlist); |
1338 | hlist_del(&cl->hlist); | ||
1339 | 1336 | ||
1340 | if (cl->prio_activity) | 1337 | if (cl->prio_activity) |
1341 | htb_deactivate(q, cl); | 1338 | htb_deactivate(q, cl); |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 45939bafbdf8..0441876aa1e7 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License. |
8 | * | 8 | * |
9 | * Many of the algorithms and ideas for this came from | 9 | * Many of the algorithms and ideas for this came from |
10 | * NIST Net which is not copyrighted. | 10 | * NIST Net which is not copyrighted. |
@@ -170,6 +170,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
170 | return NET_XMIT_BYPASS; | 170 | return NET_XMIT_BYPASS; |
171 | } | 171 | } |
172 | 172 | ||
173 | skb_orphan(skb); | ||
174 | |||
173 | /* | 175 | /* |
174 | * If we need to duplicate packet, then re-insert at top of the | 176 | * If we need to duplicate packet, then re-insert at top of the |
175 | * qdisc tree, since parent queuer expects that only one | 177 | * qdisc tree, since parent queuer expects that only one |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 27329ce9c311..ed0445fe85e7 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -346,11 +346,18 @@ void sctp_association_free(struct sctp_association *asoc) | |||
346 | struct list_head *pos, *temp; | 346 | struct list_head *pos, *temp; |
347 | int i; | 347 | int i; |
348 | 348 | ||
349 | list_del(&asoc->asocs); | 349 | /* Only real associations count against the endpoint, so |
350 | * don't bother for if this is a temporary association. | ||
351 | */ | ||
352 | if (!asoc->temp) { | ||
353 | list_del(&asoc->asocs); | ||
350 | 354 | ||
351 | /* Decrement the backlog value for a TCP-style listening socket. */ | 355 | /* Decrement the backlog value for a TCP-style listening |
352 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) | 356 | * socket. |
353 | sk->sk_ack_backlog--; | 357 | */ |
358 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) | ||
359 | sk->sk_ack_backlog--; | ||
360 | } | ||
354 | 361 | ||
355 | /* Mark as dead, so other users can know this structure is | 362 | /* Mark as dead, so other users can know this structure is |
356 | * going away. | 363 | * going away. |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 35c49ff2d062..9b6b394b66f6 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -144,6 +144,13 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, | |||
144 | { | 144 | { |
145 | struct sock *sk = ep->base.sk; | 145 | struct sock *sk = ep->base.sk; |
146 | 146 | ||
147 | /* If this is a temporary association, don't bother | ||
148 | * since we'll be removing it shortly and don't | ||
149 | * want anyone to find it anyway. | ||
150 | */ | ||
151 | if (asoc->temp) | ||
152 | return; | ||
153 | |||
147 | /* Now just add it to our list of asocs */ | 154 | /* Now just add it to our list of asocs */ |
148 | list_add_tail(&asoc->asocs, &ep->asocs); | 155 | list_add_tail(&asoc->asocs, &ep->asocs); |
149 | 156 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 64f630102532..6d82f400d13c 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -135,6 +135,9 @@ int sctp_rcv(struct sk_buff *skb) | |||
135 | 135 | ||
136 | SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS); | 136 | SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS); |
137 | 137 | ||
138 | if (skb_linearize(skb)) | ||
139 | goto discard_it; | ||
140 | |||
138 | sh = (struct sctphdr *) skb->h.raw; | 141 | sh = (struct sctphdr *) skb->h.raw; |
139 | 142 | ||
140 | /* Pull up the IP and SCTP headers. */ | 143 | /* Pull up the IP and SCTP headers. */ |
@@ -768,6 +771,9 @@ static void __sctp_hash_established(struct sctp_association *asoc) | |||
768 | /* Add an association to the hash. Local BH-safe. */ | 771 | /* Add an association to the hash. Local BH-safe. */ |
769 | void sctp_hash_established(struct sctp_association *asoc) | 772 | void sctp_hash_established(struct sctp_association *asoc) |
770 | { | 773 | { |
774 | if (asoc->temp) | ||
775 | return; | ||
776 | |||
771 | sctp_local_bh_disable(); | 777 | sctp_local_bh_disable(); |
772 | __sctp_hash_established(asoc); | 778 | __sctp_hash_established(asoc); |
773 | sctp_local_bh_enable(); | 779 | sctp_local_bh_enable(); |
@@ -801,6 +807,9 @@ static void __sctp_unhash_established(struct sctp_association *asoc) | |||
801 | /* Remove association from the hash table. Local BH-safe. */ | 807 | /* Remove association from the hash table. Local BH-safe. */ |
802 | void sctp_unhash_established(struct sctp_association *asoc) | 808 | void sctp_unhash_established(struct sctp_association *asoc) |
803 | { | 809 | { |
810 | if (asoc->temp) | ||
811 | return; | ||
812 | |||
804 | sctp_local_bh_disable(); | 813 | sctp_local_bh_disable(); |
805 | __sctp_unhash_established(asoc); | 814 | __sctp_unhash_established(asoc); |
806 | sctp_local_bh_enable(); | 815 | sctp_local_bh_enable(); |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 249e5033c1a8..78071c6e6cf1 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -215,17 +215,17 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, | |||
215 | } | 215 | } |
216 | 216 | ||
217 | dst = ip6_route_output(NULL, &fl); | 217 | dst = ip6_route_output(NULL, &fl); |
218 | if (dst) { | 218 | if (!dst->error) { |
219 | struct rt6_info *rt; | 219 | struct rt6_info *rt; |
220 | rt = (struct rt6_info *)dst; | 220 | rt = (struct rt6_info *)dst; |
221 | SCTP_DEBUG_PRINTK( | 221 | SCTP_DEBUG_PRINTK( |
222 | "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", | 222 | "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", |
223 | NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr)); | 223 | NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr)); |
224 | } else { | 224 | return dst; |
225 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | ||
226 | } | 225 | } |
227 | 226 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | |
228 | return dst; | 227 | dst_release(dst); |
228 | return NULL; | ||
229 | } | 229 | } |
230 | 230 | ||
231 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 | 231 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index a356d8d310a9..7f49e769080e 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -344,7 +344,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
344 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 344 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
345 | assoc->state, hash, assoc->assoc_id, | 345 | assoc->state, hash, assoc->assoc_id, |
346 | assoc->sndbuf_used, | 346 | assoc->sndbuf_used, |
347 | (sk->sk_rcvbuf - assoc->rwnd), | 347 | atomic_read(&assoc->rmem_alloc), |
348 | sock_i_uid(sk), sock_i_ino(sk), | 348 | sock_i_uid(sk), sock_i_ino(sk), |
349 | epb->bind_addr.port, | 349 | epb->bind_addr.port, |
350 | assoc->peer.port); | 350 | assoc->peer.port); |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index fac7674438a4..5b4f82fd98f8 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -591,7 +591,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, | |||
591 | newinet->dport = htons(asoc->peer.port); | 591 | newinet->dport = htons(asoc->peer.port); |
592 | newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; | 592 | newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; |
593 | newinet->pmtudisc = inet->pmtudisc; | 593 | newinet->pmtudisc = inet->pmtudisc; |
594 | newinet->id = 0; | 594 | newinet->id = asoc->next_tsn ^ jiffies; |
595 | 595 | ||
596 | newinet->uc_ttl = -1; | 596 | newinet->uc_ttl = -1; |
597 | newinet->mc_loop = 1; | 597 | newinet->mc_loop = 1; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 3fe906d65069..935bc9187fd8 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -821,7 +821,7 @@ out: | |||
821 | * addrs is a pointer to an array of one or more socket addresses. Each | 821 | * addrs is a pointer to an array of one or more socket addresses. Each |
822 | * address is contained in its appropriate structure (i.e. struct | 822 | * address is contained in its appropriate structure (i.e. struct |
823 | * sockaddr_in or struct sockaddr_in6) the family of the address type | 823 | * sockaddr_in or struct sockaddr_in6) the family of the address type |
824 | * must be used to distengish the address length (note that this | 824 | * must be used to distinguish the address length (note that this |
825 | * representation is termed a "packed array" of addresses). The caller | 825 | * representation is termed a "packed array" of addresses). The caller |
826 | * specifies the number of addresses in the array with addrcnt. | 826 | * specifies the number of addresses in the array with addrcnt. |
827 | * | 827 | * |
@@ -3372,6 +3372,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, | |||
3372 | { | 3372 | { |
3373 | struct sock *sk = asoc->base.sk; | 3373 | struct sock *sk = asoc->base.sk; |
3374 | struct socket *sock; | 3374 | struct socket *sock; |
3375 | struct inet_sock *inetsk; | ||
3375 | int err = 0; | 3376 | int err = 0; |
3376 | 3377 | ||
3377 | /* An association cannot be branched off from an already peeled-off | 3378 | /* An association cannot be branched off from an already peeled-off |
@@ -3389,6 +3390,14 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, | |||
3389 | * asoc to the newsk. | 3390 | * asoc to the newsk. |
3390 | */ | 3391 | */ |
3391 | sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); | 3392 | sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); |
3393 | |||
3394 | /* Make peeled-off sockets more like 1-1 accepted sockets. | ||
3395 | * Set the daddr and initialize id to something more random | ||
3396 | */ | ||
3397 | inetsk = inet_sk(sock->sk); | ||
3398 | inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; | ||
3399 | inetsk->id = asoc->next_tsn ^ jiffies; | ||
3400 | |||
3392 | *sockp = sock; | 3401 | *sockp = sock; |
3393 | 3402 | ||
3394 | return err; | 3403 | return err; |
@@ -5362,6 +5371,20 @@ static void sctp_wfree(struct sk_buff *skb) | |||
5362 | sctp_association_put(asoc); | 5371 | sctp_association_put(asoc); |
5363 | } | 5372 | } |
5364 | 5373 | ||
5374 | /* Do accounting for the receive space on the socket. | ||
5375 | * Accounting for the association is done in ulpevent.c | ||
5376 | * We set this as a destructor for the cloned data skbs so that | ||
5377 | * accounting is done at the correct time. | ||
5378 | */ | ||
5379 | void sctp_sock_rfree(struct sk_buff *skb) | ||
5380 | { | ||
5381 | struct sock *sk = skb->sk; | ||
5382 | struct sctp_ulpevent *event = sctp_skb2event(skb); | ||
5383 | |||
5384 | atomic_sub(event->rmem_len, &sk->sk_rmem_alloc); | ||
5385 | } | ||
5386 | |||
5387 | |||
5365 | /* Helper function to wait for space in the sndbuf. */ | 5388 | /* Helper function to wait for space in the sndbuf. */ |
5366 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | 5389 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, |
5367 | size_t msg_len) | 5390 | size_t msg_len) |
@@ -5634,10 +5657,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5634 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { | 5657 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { |
5635 | event = sctp_skb2event(skb); | 5658 | event = sctp_skb2event(skb); |
5636 | if (event->asoc == assoc) { | 5659 | if (event->asoc == assoc) { |
5637 | sock_rfree(skb); | 5660 | sctp_sock_rfree(skb); |
5638 | __skb_unlink(skb, &oldsk->sk_receive_queue); | 5661 | __skb_unlink(skb, &oldsk->sk_receive_queue); |
5639 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | 5662 | __skb_queue_tail(&newsk->sk_receive_queue, skb); |
5640 | skb_set_owner_r(skb, newsk); | 5663 | sctp_skb_set_owner_r(skb, newsk); |
5641 | } | 5664 | } |
5642 | } | 5665 | } |
5643 | 5666 | ||
@@ -5665,10 +5688,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5665 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { | 5688 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { |
5666 | event = sctp_skb2event(skb); | 5689 | event = sctp_skb2event(skb); |
5667 | if (event->asoc == assoc) { | 5690 | if (event->asoc == assoc) { |
5668 | sock_rfree(skb); | 5691 | sctp_sock_rfree(skb); |
5669 | __skb_unlink(skb, &oldsp->pd_lobby); | 5692 | __skb_unlink(skb, &oldsp->pd_lobby); |
5670 | __skb_queue_tail(queue, skb); | 5693 | __skb_queue_tail(queue, skb); |
5671 | skb_set_owner_r(skb, newsk); | 5694 | sctp_skb_set_owner_r(skb, newsk); |
5672 | } | 5695 | } |
5673 | } | 5696 | } |
5674 | 5697 | ||
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index ee236784a6bb..a015283a9087 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -55,10 +55,13 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event); | |||
55 | 55 | ||
56 | 56 | ||
57 | /* Initialize an ULP event from an given skb. */ | 57 | /* Initialize an ULP event from an given skb. */ |
58 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) | 58 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, |
59 | int msg_flags, | ||
60 | unsigned int len) | ||
59 | { | 61 | { |
60 | memset(event, 0, sizeof(struct sctp_ulpevent)); | 62 | memset(event, 0, sizeof(struct sctp_ulpevent)); |
61 | event->msg_flags = msg_flags; | 63 | event->msg_flags = msg_flags; |
64 | event->rmem_len = len; | ||
62 | } | 65 | } |
63 | 66 | ||
64 | /* Create a new sctp_ulpevent. */ | 67 | /* Create a new sctp_ulpevent. */ |
@@ -73,7 +76,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, | |||
73 | goto fail; | 76 | goto fail; |
74 | 77 | ||
75 | event = sctp_skb2event(skb); | 78 | event = sctp_skb2event(skb); |
76 | sctp_ulpevent_init(event, msg_flags); | 79 | sctp_ulpevent_init(event, msg_flags, skb->truesize); |
77 | 80 | ||
78 | return event; | 81 | return event; |
79 | 82 | ||
@@ -101,17 +104,16 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event, | |||
101 | sctp_association_hold((struct sctp_association *)asoc); | 104 | sctp_association_hold((struct sctp_association *)asoc); |
102 | skb = sctp_event2skb(event); | 105 | skb = sctp_event2skb(event); |
103 | event->asoc = (struct sctp_association *)asoc; | 106 | event->asoc = (struct sctp_association *)asoc; |
104 | atomic_add(skb->truesize, &event->asoc->rmem_alloc); | 107 | atomic_add(event->rmem_len, &event->asoc->rmem_alloc); |
105 | skb_set_owner_r(skb, asoc->base.sk); | 108 | sctp_skb_set_owner_r(skb, asoc->base.sk); |
106 | } | 109 | } |
107 | 110 | ||
108 | /* A simple destructor to give up the reference to the association. */ | 111 | /* A simple destructor to give up the reference to the association. */ |
109 | static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) | 112 | static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) |
110 | { | 113 | { |
111 | struct sctp_association *asoc = event->asoc; | 114 | struct sctp_association *asoc = event->asoc; |
112 | struct sk_buff *skb = sctp_event2skb(event); | ||
113 | 115 | ||
114 | atomic_sub(skb->truesize, &asoc->rmem_alloc); | 116 | atomic_sub(event->rmem_len, &asoc->rmem_alloc); |
115 | sctp_association_put(asoc); | 117 | sctp_association_put(asoc); |
116 | } | 118 | } |
117 | 119 | ||
@@ -372,7 +374,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | |||
372 | 374 | ||
373 | /* Embed the event fields inside the cloned skb. */ | 375 | /* Embed the event fields inside the cloned skb. */ |
374 | event = sctp_skb2event(skb); | 376 | event = sctp_skb2event(skb); |
375 | sctp_ulpevent_init(event, MSG_NOTIFICATION); | 377 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); |
376 | 378 | ||
377 | sre = (struct sctp_remote_error *) | 379 | sre = (struct sctp_remote_error *) |
378 | skb_push(skb, sizeof(struct sctp_remote_error)); | 380 | skb_push(skb, sizeof(struct sctp_remote_error)); |
@@ -464,7 +466,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed( | |||
464 | 466 | ||
465 | /* Embed the event fields inside the cloned skb. */ | 467 | /* Embed the event fields inside the cloned skb. */ |
466 | event = sctp_skb2event(skb); | 468 | event = sctp_skb2event(skb); |
467 | sctp_ulpevent_init(event, MSG_NOTIFICATION); | 469 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); |
468 | 470 | ||
469 | ssf = (struct sctp_send_failed *) | 471 | ssf = (struct sctp_send_failed *) |
470 | skb_push(skb, sizeof(struct sctp_send_failed)); | 472 | skb_push(skb, sizeof(struct sctp_send_failed)); |
@@ -682,8 +684,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | |||
682 | /* Embed the event fields inside the cloned skb. */ | 684 | /* Embed the event fields inside the cloned skb. */ |
683 | event = sctp_skb2event(skb); | 685 | event = sctp_skb2event(skb); |
684 | 686 | ||
685 | /* Initialize event with flags 0. */ | 687 | /* Initialize event with flags 0 and correct length |
686 | sctp_ulpevent_init(event, 0); | 688 | * Since this is a clone of the original skb, only account for |
689 | * the data of this chunk as other chunks will be accounted separately. | ||
690 | */ | ||
691 | sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff)); | ||
687 | 692 | ||
688 | sctp_ulpevent_receive_data(event, asoc); | 693 | sctp_ulpevent_receive_data(event, asoc); |
689 | 694 | ||
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 575e556aeb3e..e1d144275f97 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -309,7 +309,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu | |||
309 | if (!new) | 309 | if (!new) |
310 | return NULL; /* try again later */ | 310 | return NULL; /* try again later */ |
311 | 311 | ||
312 | new->sk = f_frag->sk; | 312 | sctp_skb_set_owner_r(new, f_frag->sk); |
313 | 313 | ||
314 | skb_shinfo(new)->frag_list = pos; | 314 | skb_shinfo(new)->frag_list = pos; |
315 | } else | 315 | } else |
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index 919d5ba7ca0a..e52afab413de 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c | |||
@@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task) | |||
101 | /* Autobind on cloned rpc clients is discouraged */ | 101 | /* Autobind on cloned rpc clients is discouraged */ |
102 | BUG_ON(clnt->cl_parent != clnt); | 102 | BUG_ON(clnt->cl_parent != clnt); |
103 | 103 | ||
104 | if (xprt_test_and_set_binding(xprt)) { | 104 | /* Put self on queue before sending rpcbind request, in case |
105 | task->tk_status = -EACCES; /* tell caller to check again */ | 105 | * pmap_getport_done completes before we return from rpc_run_task */ |
106 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); | 106 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); |
107 | return; | 107 | |
108 | } | 108 | status = -EACCES; /* tell caller to check again */ |
109 | if (xprt_test_and_set_binding(xprt)) | ||
110 | goto bailout_nofree; | ||
109 | 111 | ||
110 | /* Someone else may have bound if we slept */ | 112 | /* Someone else may have bound if we slept */ |
111 | status = 0; | 113 | status = 0; |
@@ -134,8 +136,6 @@ void rpc_getport(struct rpc_task *task) | |||
134 | goto bailout; | 136 | goto bailout; |
135 | rpc_release_task(child); | 137 | rpc_release_task(child); |
136 | 138 | ||
137 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); | ||
138 | |||
139 | task->tk_xprt->stat.bind_count++; | 139 | task->tk_xprt->stat.bind_count++; |
140 | return; | 140 | return; |
141 | 141 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2807fa0eab40..eb44ec929ca1 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -828,6 +828,11 @@ svc_process(struct svc_rqst *rqstp) | |||
828 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 828 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
829 | 829 | ||
830 | /* Encode reply */ | 830 | /* Encode reply */ |
831 | if (*statp == rpc_drop_reply) { | ||
832 | if (procp->pc_release) | ||
833 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); | ||
834 | goto dropit; | ||
835 | } | ||
831 | if (*statp == rpc_success && (xdr = procp->pc_encode) | 836 | if (*statp == rpc_success && (xdr = procp->pc_encode) |
832 | && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { | 837 | && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { |
833 | dprintk("svc: failed to encode reply\n"); | 838 | dprintk("svc: failed to encode reply\n"); |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 8f2320aded5c..ee9bb1522d5e 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
@@ -126,6 +126,7 @@ void auth_domain_put(struct auth_domain *dom) | |||
126 | if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { | 126 | if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { |
127 | hlist_del(&dom->hash); | 127 | hlist_del(&dom->hash); |
128 | dom->flavour->domain_release(dom); | 128 | dom->flavour->domain_release(dom); |
129 | spin_unlock(&auth_domain_lock); | ||
129 | } | 130 | } |
130 | } | 131 | } |
131 | 132 | ||
@@ -147,10 +148,8 @@ auth_domain_lookup(char *name, struct auth_domain *new) | |||
147 | return hp; | 148 | return hp; |
148 | } | 149 | } |
149 | } | 150 | } |
150 | if (new) { | 151 | if (new) |
151 | hlist_add_head(&new->hash, head); | 152 | hlist_add_head(&new->hash, head); |
152 | kref_get(&new->ref); | ||
153 | } | ||
154 | spin_unlock(&auth_domain_lock); | 153 | spin_unlock(&auth_domain_lock); |
155 | return new; | 154 | return new; |
156 | } | 155 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 61e307cca13d..64ca1f61dd94 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -299,9 +299,15 @@ void svc_reserve(struct svc_rqst *rqstp, int space) | |||
299 | static inline void | 299 | static inline void |
300 | svc_sock_put(struct svc_sock *svsk) | 300 | svc_sock_put(struct svc_sock *svsk) |
301 | { | 301 | { |
302 | if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { | 302 | if (atomic_dec_and_test(&svsk->sk_inuse) && |
303 | test_bit(SK_DEAD, &svsk->sk_flags)) { | ||
303 | dprintk("svc: releasing dead socket\n"); | 304 | dprintk("svc: releasing dead socket\n"); |
304 | sock_release(svsk->sk_sock); | 305 | if (svsk->sk_sock->file) |
306 | sockfd_put(svsk->sk_sock); | ||
307 | else | ||
308 | sock_release(svsk->sk_sock); | ||
309 | if (svsk->sk_info_authunix != NULL) | ||
310 | svcauth_unix_info_release(svsk->sk_info_authunix); | ||
305 | kfree(svsk); | 311 | kfree(svsk); |
306 | } | 312 | } |
307 | } | 313 | } |
@@ -973,7 +979,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
973 | return 0; | 979 | return 0; |
974 | } | 980 | } |
975 | 981 | ||
976 | if (test_bit(SK_CONN, &svsk->sk_flags)) { | 982 | if (svsk->sk_sk->sk_state == TCP_LISTEN) { |
977 | svc_tcp_accept(svsk); | 983 | svc_tcp_accept(svsk); |
978 | svc_sock_received(svsk); | 984 | svc_sock_received(svsk); |
979 | return 0; | 985 | return 0; |
@@ -1604,20 +1610,13 @@ svc_delete_socket(struct svc_sock *svsk) | |||
1604 | if (test_bit(SK_TEMP, &svsk->sk_flags)) | 1610 | if (test_bit(SK_TEMP, &svsk->sk_flags)) |
1605 | serv->sv_tmpcnt--; | 1611 | serv->sv_tmpcnt--; |
1606 | 1612 | ||
1607 | if (!atomic_read(&svsk->sk_inuse)) { | 1613 | /* This atomic_inc should be needed - svc_delete_socket |
1608 | spin_unlock_bh(&serv->sv_lock); | 1614 | * should have the semantic of dropping a reference. |
1609 | if (svsk->sk_sock->file) | 1615 | * But it doesn't yet.... |
1610 | sockfd_put(svsk->sk_sock); | 1616 | */ |
1611 | else | 1617 | atomic_inc(&svsk->sk_inuse); |
1612 | sock_release(svsk->sk_sock); | 1618 | spin_unlock_bh(&serv->sv_lock); |
1613 | if (svsk->sk_info_authunix != NULL) | 1619 | svc_sock_put(svsk); |
1614 | svcauth_unix_info_release(svsk->sk_info_authunix); | ||
1615 | kfree(svsk); | ||
1616 | } else { | ||
1617 | spin_unlock_bh(&serv->sv_lock); | ||
1618 | dprintk(KERN_NOTICE "svc: server socket destroy delayed\n"); | ||
1619 | /* svsk->sk_server = NULL; */ | ||
1620 | } | ||
1621 | } | 1620 | } |
1622 | 1621 | ||
1623 | /* | 1622 | /* |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 28100e019225..757fc91ef25d 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1366,7 +1366,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1366 | if (xprt->slot == NULL) | 1366 | if (xprt->slot == NULL) |
1367 | return -ENOMEM; | 1367 | return -ENOMEM; |
1368 | 1368 | ||
1369 | if (ntohs(addr->sin_port != 0)) | 1369 | if (ntohs(addr->sin_port) != 0) |
1370 | xprt_set_bound(xprt); | 1370 | xprt_set_bound(xprt); |
1371 | xprt->port = xs_get_random_port(); | 1371 | xprt->port = xs_get_random_port(); |
1372 | 1372 | ||
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 75a5968c2139..39744a33bd36 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/bearer.c: TIPC bearer code | 2 | * net/tipc/bearer.c: TIPC bearer code |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2006, Ericsson AB | 4 | * Copyright (c) 1996-2006, Ericsson AB |
5 | * Copyright (c) 2004-2005, Wind River Systems | 5 | * Copyright (c) 2004-2006, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -191,14 +191,14 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) | |||
191 | if ((i < media_count) && (m_ptr->addr2str != NULL)) { | 191 | if ((i < media_count) && (m_ptr->addr2str != NULL)) { |
192 | char addr_str[MAX_ADDR_STR]; | 192 | char addr_str[MAX_ADDR_STR]; |
193 | 193 | ||
194 | tipc_printf(pb, "%s(%s) ", m_ptr->name, | 194 | tipc_printf(pb, "%s(%s)", m_ptr->name, |
195 | m_ptr->addr2str(a, addr_str, sizeof(addr_str))); | 195 | m_ptr->addr2str(a, addr_str, sizeof(addr_str))); |
196 | } else { | 196 | } else { |
197 | unchar *addr = (unchar *)&a->dev_addr; | 197 | unchar *addr = (unchar *)&a->dev_addr; |
198 | 198 | ||
199 | tipc_printf(pb, "UNKNOWN(%u):", media_type); | 199 | tipc_printf(pb, "UNKNOWN(%u)", media_type); |
200 | for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { | 200 | for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { |
201 | tipc_printf(pb, "%02x ", addr[i]); | 201 | tipc_printf(pb, "-%02x", addr[i]); |
202 | } | 202 | } |
203 | } | 203 | } |
204 | } | 204 | } |
diff --git a/net/tipc/config.c b/net/tipc/config.c index 285e1bc2d880..ed1351ed05e1 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/config.c: TIPC configuration management code | 2 | * net/tipc/config.c: TIPC configuration management code |
3 | * | 3 | * |
4 | * Copyright (c) 2002-2006, Ericsson AB | 4 | * Copyright (c) 2002-2006, Ericsson AB |
5 | * Copyright (c) 2004-2005, Wind River Systems | 5 | * Copyright (c) 2004-2006, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -613,7 +613,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
613 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); | 613 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); |
614 | break; | 614 | break; |
615 | default: | 615 | default: |
616 | rep_tlv_buf = NULL; | 616 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
617 | " (unknown command)"); | ||
617 | break; | 618 | break; |
618 | } | 619 | } |
619 | 620 | ||
diff --git a/net/tipc/core.c b/net/tipc/core.c index 0539a8362858..6f5b7ee31180 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -57,7 +57,7 @@ void tipc_socket_stop(void); | |||
57 | int tipc_netlink_start(void); | 57 | int tipc_netlink_start(void); |
58 | void tipc_netlink_stop(void); | 58 | void tipc_netlink_stop(void); |
59 | 59 | ||
60 | #define TIPC_MOD_VER "1.6.1" | 60 | #define TIPC_MOD_VER "1.6.2" |
61 | 61 | ||
62 | #ifndef CONFIG_TIPC_ZONES | 62 | #ifndef CONFIG_TIPC_ZONES |
63 | #define CONFIG_TIPC_ZONES 3 | 63 | #define CONFIG_TIPC_ZONES 3 |
@@ -90,7 +90,7 @@ int tipc_random; | |||
90 | atomic_t tipc_user_count = ATOMIC_INIT(0); | 90 | atomic_t tipc_user_count = ATOMIC_INIT(0); |
91 | 91 | ||
92 | const char tipc_alphabet[] = | 92 | const char tipc_alphabet[] = |
93 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; | 93 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; |
94 | 94 | ||
95 | /* configurable TIPC parameters */ | 95 | /* configurable TIPC parameters */ |
96 | 96 | ||
diff --git a/net/tipc/core.h b/net/tipc/core.h index 762aac2572be..4638947c2326 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -65,7 +65,7 @@ | |||
65 | #define assert(i) BUG_ON(!(i)) | 65 | #define assert(i) BUG_ON(!(i)) |
66 | 66 | ||
67 | struct tipc_msg; | 67 | struct tipc_msg; |
68 | extern struct print_buf *TIPC_CONS, *TIPC_LOG; | 68 | extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; |
69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); | 69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); |
70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); | 70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); |
71 | void tipc_printf(struct print_buf *, const char *fmt, ...); | 71 | void tipc_printf(struct print_buf *, const char *fmt, ...); |
@@ -83,9 +83,9 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); | |||
83 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) | 83 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) |
84 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) | 84 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) |
85 | 85 | ||
86 | #define dbg(fmt, arg...) do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) | 86 | #define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) |
87 | #define msg_dbg(msg, txt) do {if (DBG_OUTPUT) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) | 87 | #define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) |
88 | #define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) | 88 | #define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) |
89 | 89 | ||
90 | 90 | ||
91 | /* | 91 | /* |
@@ -94,11 +94,11 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); | |||
94 | * here, or on a per .c file basis, by redefining these symbols. The following | 94 | * here, or on a per .c file basis, by redefining these symbols. The following |
95 | * print buffer options are available: | 95 | * print buffer options are available: |
96 | * | 96 | * |
97 | * NULL : Output to null print buffer (i.e. print nowhere) | 97 | * TIPC_NULL : null buffer (i.e. print nowhere) |
98 | * TIPC_CONS : Output to system console | 98 | * TIPC_CONS : system console |
99 | * TIPC_LOG : Output to TIPC log buffer | 99 | * TIPC_LOG : TIPC log buffer |
100 | * &buf : Output to user-defined buffer (struct print_buf *) | 100 | * &buf : user-defined buffer (struct print_buf *) |
101 | * TIPC_TEE(&buf_a,&buf_b) : Output to two print buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG) ) | 101 | * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG)) |
102 | */ | 102 | */ |
103 | 103 | ||
104 | #ifndef TIPC_OUTPUT | 104 | #ifndef TIPC_OUTPUT |
@@ -106,7 +106,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); | |||
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | #ifndef DBG_OUTPUT | 108 | #ifndef DBG_OUTPUT |
109 | #define DBG_OUTPUT NULL | 109 | #define DBG_OUTPUT TIPC_NULL |
110 | #endif | 110 | #endif |
111 | 111 | ||
112 | #else | 112 | #else |
@@ -136,7 +136,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); | |||
136 | #define TIPC_OUTPUT TIPC_CONS | 136 | #define TIPC_OUTPUT TIPC_CONS |
137 | 137 | ||
138 | #undef DBG_OUTPUT | 138 | #undef DBG_OUTPUT |
139 | #define DBG_OUTPUT NULL | 139 | #define DBG_OUTPUT TIPC_NULL |
140 | 140 | ||
141 | #endif | 141 | #endif |
142 | 142 | ||
@@ -275,11 +275,15 @@ static inline void k_term_timer(struct timer_list *timer) | |||
275 | /* | 275 | /* |
276 | * TIPC message buffer code | 276 | * TIPC message buffer code |
277 | * | 277 | * |
278 | * TIPC message buffer headroom leaves room for 14 byte Ethernet header, | 278 | * TIPC message buffer headroom reserves space for a link-level header |
279 | * (in case the message is sent off-node), | ||
279 | * while ensuring TIPC header is word aligned for quicker access | 280 | * while ensuring TIPC header is word aligned for quicker access |
281 | * | ||
282 | * The largest header currently supported is 18 bytes, which is used when | ||
283 | * the standard 14 byte Ethernet header has 4 added bytes for VLAN info | ||
280 | */ | 284 | */ |
281 | 285 | ||
282 | #define BUF_HEADROOM 16u | 286 | #define BUF_HEADROOM 20u |
283 | 287 | ||
284 | struct tipc_skb_cb { | 288 | struct tipc_skb_cb { |
285 | void *handle; | 289 | void *handle; |
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 55130655e1ed..d8af4c28695d 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/dbg.c: TIPC print buffer routines for debuggign | 2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2006, Ericsson AB | 4 | * Copyright (c) 1996-2006, Ericsson AB |
5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2006, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -38,11 +38,12 @@ | |||
38 | #include "config.h" | 38 | #include "config.h" |
39 | #include "dbg.h" | 39 | #include "dbg.h" |
40 | 40 | ||
41 | #define MAX_STRING 512 | 41 | static char print_string[TIPC_PB_MAX_STR]; |
42 | |||
43 | static char print_string[MAX_STRING]; | ||
44 | static DEFINE_SPINLOCK(print_lock); | 42 | static DEFINE_SPINLOCK(print_lock); |
45 | 43 | ||
44 | static struct print_buf null_buf = { NULL, 0, NULL, NULL }; | ||
45 | struct print_buf *TIPC_NULL = &null_buf; | ||
46 | |||
46 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; | 47 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; |
47 | struct print_buf *TIPC_CONS = &cons_buf; | 48 | struct print_buf *TIPC_CONS = &cons_buf; |
48 | 49 | ||
@@ -62,68 +63,83 @@ struct print_buf *TIPC_LOG = &log_buf; | |||
62 | /* | 63 | /* |
63 | * Locking policy when using print buffers. | 64 | * Locking policy when using print buffers. |
64 | * | 65 | * |
65 | * 1) Routines of the form printbuf_XXX() rely on the caller to prevent | 66 | * The following routines use 'print_lock' for protection: |
66 | * simultaneous use of the print buffer(s) being manipulated. | 67 | * 1) tipc_printf() - to protect its print buffer(s) and 'print_string' |
67 | * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of | 68 | * 2) TIPC_TEE() - to protect its print buffer(s) |
68 | * 'print_string' and to protect its print buffer(s). | 69 | * 3) tipc_dump() - to protect its print buffer(s) and 'print_string' |
69 | * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s). | 70 | * 4) tipc_log_XXX() - to protect TIPC_LOG |
70 | * 4) Routines of the form log_XXX() uses 'print_lock' to protect TIPC_LOG. | 71 | * |
72 | * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent | ||
73 | * simultaneous use of the print buffer(s) being manipulated. | ||
71 | */ | 74 | */ |
72 | 75 | ||
73 | /** | 76 | /** |
74 | * tipc_printbuf_init - initialize print buffer to empty | 77 | * tipc_printbuf_init - initialize print buffer to empty |
78 | * @pb: pointer to print buffer structure | ||
79 | * @raw: pointer to character array used by print buffer | ||
80 | * @size: size of character array | ||
81 | * | ||
82 | * Makes the print buffer a null device that discards anything written to it | ||
83 | * if the character array is too small (or absent). | ||
75 | */ | 84 | */ |
76 | 85 | ||
77 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz) | 86 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) |
78 | { | 87 | { |
79 | if (!pb || !raw || (sz < (MAX_STRING + 1))) | 88 | pb->buf = raw; |
80 | return; | 89 | pb->crs = raw; |
81 | 90 | pb->size = size; | |
82 | pb->crs = pb->buf = raw; | ||
83 | pb->size = sz; | ||
84 | pb->next = NULL; | 91 | pb->next = NULL; |
85 | pb->buf[0] = 0; | 92 | |
86 | pb->buf[sz-1] = ~0; | 93 | if (size < TIPC_PB_MIN_SIZE) { |
94 | pb->buf = NULL; | ||
95 | } else if (raw) { | ||
96 | pb->buf[0] = 0; | ||
97 | pb->buf[size-1] = ~0; | ||
98 | } | ||
87 | } | 99 | } |
88 | 100 | ||
89 | /** | 101 | /** |
90 | * tipc_printbuf_reset - reinitialize print buffer to empty state | 102 | * tipc_printbuf_reset - reinitialize print buffer to empty state |
103 | * @pb: pointer to print buffer structure | ||
91 | */ | 104 | */ |
92 | 105 | ||
93 | void tipc_printbuf_reset(struct print_buf *pb) | 106 | void tipc_printbuf_reset(struct print_buf *pb) |
94 | { | 107 | { |
95 | if (pb && pb->buf) | 108 | tipc_printbuf_init(pb, pb->buf, pb->size); |
96 | tipc_printbuf_init(pb, pb->buf, pb->size); | ||
97 | } | 109 | } |
98 | 110 | ||
99 | /** | 111 | /** |
100 | * tipc_printbuf_empty - test if print buffer is in empty state | 112 | * tipc_printbuf_empty - test if print buffer is in empty state |
113 | * @pb: pointer to print buffer structure | ||
114 | * | ||
115 | * Returns non-zero if print buffer is empty. | ||
101 | */ | 116 | */ |
102 | 117 | ||
103 | int tipc_printbuf_empty(struct print_buf *pb) | 118 | int tipc_printbuf_empty(struct print_buf *pb) |
104 | { | 119 | { |
105 | return (!pb || !pb->buf || (pb->crs == pb->buf)); | 120 | return (!pb->buf || (pb->crs == pb->buf)); |
106 | } | 121 | } |
107 | 122 | ||
108 | /** | 123 | /** |
109 | * tipc_printbuf_validate - check for print buffer overflow | 124 | * tipc_printbuf_validate - check for print buffer overflow |
125 | * @pb: pointer to print buffer structure | ||
110 | * | 126 | * |
111 | * Verifies that a print buffer has captured all data written to it. | 127 | * Verifies that a print buffer has captured all data written to it. |
112 | * If data has been lost, linearize buffer and prepend an error message | 128 | * If data has been lost, linearize buffer and prepend an error message |
113 | * | 129 | * |
114 | * Returns length of print buffer data string (including trailing NULL) | 130 | * Returns length of print buffer data string (including trailing NUL) |
115 | */ | 131 | */ |
116 | 132 | ||
117 | int tipc_printbuf_validate(struct print_buf *pb) | 133 | int tipc_printbuf_validate(struct print_buf *pb) |
118 | { | 134 | { |
119 | char *err = " *** PRINT BUFFER WRAPPED AROUND ***\n"; | 135 | char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; |
120 | char *cp_buf; | 136 | char *cp_buf; |
121 | struct print_buf cb; | 137 | struct print_buf cb; |
122 | 138 | ||
123 | if (!pb || !pb->buf) | 139 | if (!pb->buf) |
124 | return 0; | 140 | return 0; |
125 | 141 | ||
126 | if (pb->buf[pb->size - 1] == '\0') { | 142 | if (pb->buf[pb->size - 1] == 0) { |
127 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); | 143 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); |
128 | if (cp_buf != NULL){ | 144 | if (cp_buf != NULL){ |
129 | tipc_printbuf_init(&cb, cp_buf, pb->size); | 145 | tipc_printbuf_init(&cb, cp_buf, pb->size); |
@@ -141,6 +157,8 @@ int tipc_printbuf_validate(struct print_buf *pb) | |||
141 | 157 | ||
142 | /** | 158 | /** |
143 | * tipc_printbuf_move - move print buffer contents to another print buffer | 159 | * tipc_printbuf_move - move print buffer contents to another print buffer |
160 | * @pb_to: pointer to destination print buffer structure | ||
161 | * @pb_from: pointer to source print buffer structure | ||
144 | * | 162 | * |
145 | * Current contents of destination print buffer (if any) are discarded. | 163 | * Current contents of destination print buffer (if any) are discarded. |
146 | * Source print buffer becomes empty if a successful move occurs. | 164 | * Source print buffer becomes empty if a successful move occurs. |
@@ -152,21 +170,22 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
152 | 170 | ||
153 | /* Handle the cases where contents can't be moved */ | 171 | /* Handle the cases where contents can't be moved */ |
154 | 172 | ||
155 | if (!pb_to || !pb_to->buf) | 173 | if (!pb_to->buf) |
156 | return; | 174 | return; |
157 | 175 | ||
158 | if (!pb_from || !pb_from->buf) { | 176 | if (!pb_from->buf) { |
159 | tipc_printbuf_reset(pb_to); | 177 | tipc_printbuf_reset(pb_to); |
160 | return; | 178 | return; |
161 | } | 179 | } |
162 | 180 | ||
163 | if (pb_to->size < pb_from->size) { | 181 | if (pb_to->size < pb_from->size) { |
164 | tipc_printbuf_reset(pb_to); | 182 | tipc_printbuf_reset(pb_to); |
165 | tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***"); | 183 | tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); |
166 | return; | 184 | return; |
167 | } | 185 | } |
168 | 186 | ||
169 | /* Copy data from char after cursor to end (if used) */ | 187 | /* Copy data from char after cursor to end (if used) */ |
188 | |||
170 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; | 189 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; |
171 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { | 190 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { |
172 | strcpy(pb_to->buf, pb_from->crs + 1); | 191 | strcpy(pb_to->buf, pb_from->crs + 1); |
@@ -175,6 +194,7 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
175 | pb_to->crs = pb_to->buf; | 194 | pb_to->crs = pb_to->buf; |
176 | 195 | ||
177 | /* Copy data from start to cursor (always) */ | 196 | /* Copy data from start to cursor (always) */ |
197 | |||
178 | len = pb_from->crs - pb_from->buf; | 198 | len = pb_from->crs - pb_from->buf; |
179 | strcpy(pb_to->crs, pb_from->buf); | 199 | strcpy(pb_to->crs, pb_from->buf); |
180 | pb_to->crs += len; | 200 | pb_to->crs += len; |
@@ -184,6 +204,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
184 | 204 | ||
185 | /** | 205 | /** |
186 | * tipc_printf - append formatted output to print buffer chain | 206 | * tipc_printf - append formatted output to print buffer chain |
207 | * @pb: pointer to chain of print buffers (may be NULL) | ||
208 | * @fmt: formatted info to be printed | ||
187 | */ | 209 | */ |
188 | 210 | ||
189 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) | 211 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) |
@@ -195,8 +217,8 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
195 | 217 | ||
196 | spin_lock_bh(&print_lock); | 218 | spin_lock_bh(&print_lock); |
197 | FORMAT(print_string, chars_to_add, fmt); | 219 | FORMAT(print_string, chars_to_add, fmt); |
198 | if (chars_to_add >= MAX_STRING) | 220 | if (chars_to_add >= TIPC_PB_MAX_STR) |
199 | strcpy(print_string, "*** STRING TOO LONG ***"); | 221 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); |
200 | 222 | ||
201 | while (pb) { | 223 | while (pb) { |
202 | if (pb == TIPC_CONS) | 224 | if (pb == TIPC_CONS) |
@@ -206,6 +228,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
206 | if (chars_to_add <= chars_left) { | 228 | if (chars_to_add <= chars_left) { |
207 | strcpy(pb->crs, print_string); | 229 | strcpy(pb->crs, print_string); |
208 | pb->crs += chars_to_add; | 230 | pb->crs += chars_to_add; |
231 | } else if (chars_to_add >= (pb->size - 1)) { | ||
232 | strcpy(pb->buf, print_string + chars_to_add + 1 | ||
233 | - pb->size); | ||
234 | pb->crs = pb->buf + pb->size - 1; | ||
209 | } else { | 235 | } else { |
210 | strcpy(pb->buf, print_string + chars_left); | 236 | strcpy(pb->buf, print_string + chars_left); |
211 | save_char = print_string[chars_left]; | 237 | save_char = print_string[chars_left]; |
@@ -224,6 +250,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
224 | 250 | ||
225 | /** | 251 | /** |
226 | * TIPC_TEE - perform next output operation on both print buffers | 252 | * TIPC_TEE - perform next output operation on both print buffers |
253 | * @b0: pointer to chain of print buffers (may be NULL) | ||
254 | * @b1: pointer to print buffer to add to chain | ||
255 | * | ||
256 | * Returns pointer to print buffer chain. | ||
227 | */ | 257 | */ |
228 | 258 | ||
229 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | 259 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) |
@@ -232,8 +262,6 @@ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | |||
232 | 262 | ||
233 | if (!b0 || (b0 == b1)) | 263 | if (!b0 || (b0 == b1)) |
234 | return b1; | 264 | return b1; |
235 | if (!b1) | ||
236 | return b0; | ||
237 | 265 | ||
238 | spin_lock_bh(&print_lock); | 266 | spin_lock_bh(&print_lock); |
239 | while (pb->next) { | 267 | while (pb->next) { |
@@ -256,7 +284,7 @@ static void print_to_console(char *crs, int len) | |||
256 | int rest = len; | 284 | int rest = len; |
257 | 285 | ||
258 | while (rest > 0) { | 286 | while (rest > 0) { |
259 | int sz = rest < MAX_STRING ? rest : MAX_STRING; | 287 | int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; |
260 | char c = crs[sz]; | 288 | char c = crs[sz]; |
261 | 289 | ||
262 | crs[sz] = 0; | 290 | crs[sz] = 0; |
@@ -275,36 +303,48 @@ static void printbuf_dump(struct print_buf *pb) | |||
275 | { | 303 | { |
276 | int len; | 304 | int len; |
277 | 305 | ||
306 | if (!pb->buf) { | ||
307 | printk("*** PRINT BUFFER NOT ALLOCATED ***"); | ||
308 | return; | ||
309 | } | ||
310 | |||
278 | /* Dump print buffer from char after cursor to end (if used) */ | 311 | /* Dump print buffer from char after cursor to end (if used) */ |
312 | |||
279 | len = pb->buf + pb->size - pb->crs - 2; | 313 | len = pb->buf + pb->size - pb->crs - 2; |
280 | if ((pb->buf[pb->size - 1] == 0) && (len > 0)) | 314 | if ((pb->buf[pb->size - 1] == 0) && (len > 0)) |
281 | print_to_console(pb->crs + 1, len); | 315 | print_to_console(pb->crs + 1, len); |
282 | 316 | ||
283 | /* Dump print buffer from start to cursor (always) */ | 317 | /* Dump print buffer from start to cursor (always) */ |
318 | |||
284 | len = pb->crs - pb->buf; | 319 | len = pb->crs - pb->buf; |
285 | print_to_console(pb->buf, len); | 320 | print_to_console(pb->buf, len); |
286 | } | 321 | } |
287 | 322 | ||
288 | /** | 323 | /** |
289 | * tipc_dump - dump non-console print buffer(s) to console | 324 | * tipc_dump - dump non-console print buffer(s) to console |
325 | * @pb: pointer to chain of print buffers | ||
290 | */ | 326 | */ |
291 | 327 | ||
292 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) | 328 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) |
293 | { | 329 | { |
330 | struct print_buf *pb_next; | ||
294 | int len; | 331 | int len; |
295 | 332 | ||
296 | spin_lock_bh(&print_lock); | 333 | spin_lock_bh(&print_lock); |
297 | FORMAT(TIPC_CONS->buf, len, fmt); | 334 | FORMAT(print_string, len, fmt); |
298 | printk(TIPC_CONS->buf); | 335 | printk(print_string); |
299 | 336 | ||
300 | for (; pb; pb = pb->next) { | 337 | for (; pb; pb = pb->next) { |
301 | if (pb == TIPC_CONS) | 338 | if (pb != TIPC_CONS) { |
302 | continue; | 339 | printk("\n---- Start of %s log dump ----\n\n", |
303 | printk("\n---- Start of dump,%s log ----\n\n", | 340 | (pb == TIPC_LOG) ? "global" : "local"); |
304 | (pb == TIPC_LOG) ? "global" : "local"); | 341 | printbuf_dump(pb); |
305 | printbuf_dump(pb); | 342 | tipc_printbuf_reset(pb); |
306 | tipc_printbuf_reset(pb); | 343 | printk("\n---- End of dump ----\n"); |
307 | printk("\n-------- End of dump --------\n"); | 344 | } |
345 | pb_next = pb->next; | ||
346 | pb->next = NULL; | ||
347 | pb = pb_next; | ||
308 | } | 348 | } |
309 | spin_unlock_bh(&print_lock); | 349 | spin_unlock_bh(&print_lock); |
310 | } | 350 | } |
@@ -324,7 +364,8 @@ void tipc_log_stop(void) | |||
324 | } | 364 | } |
325 | 365 | ||
326 | /** | 366 | /** |
327 | * tipc_log_reinit - set TIPC log print buffer to specified size | 367 | * tipc_log_reinit - (re)initialize TIPC log print buffer |
368 | * @log_size: print buffer size to use | ||
328 | */ | 369 | */ |
329 | 370 | ||
330 | void tipc_log_reinit(int log_size) | 371 | void tipc_log_reinit(int log_size) |
@@ -332,10 +373,11 @@ void tipc_log_reinit(int log_size) | |||
332 | tipc_log_stop(); | 373 | tipc_log_stop(); |
333 | 374 | ||
334 | if (log_size) { | 375 | if (log_size) { |
335 | if (log_size <= MAX_STRING) | 376 | if (log_size < TIPC_PB_MIN_SIZE) |
336 | log_size = MAX_STRING + 1; | 377 | log_size = TIPC_PB_MIN_SIZE; |
337 | spin_lock_bh(&print_lock); | 378 | spin_lock_bh(&print_lock); |
338 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); | 379 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), |
380 | log_size); | ||
339 | spin_unlock_bh(&print_lock); | 381 | spin_unlock_bh(&print_lock); |
340 | } | 382 | } |
341 | } | 383 | } |
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h index 227f050d2a52..467c0bc78a79 100644 --- a/net/tipc/dbg.h +++ b/net/tipc/dbg.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines | 2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines |
3 | * | 3 | * |
4 | * Copyright (c) 1997-2006, Ericsson AB | 4 | * Copyright (c) 1997-2006, Ericsson AB |
5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2006, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -37,6 +37,14 @@ | |||
37 | #ifndef _TIPC_DBG_H | 37 | #ifndef _TIPC_DBG_H |
38 | #define _TIPC_DBG_H | 38 | #define _TIPC_DBG_H |
39 | 39 | ||
40 | /** | ||
41 | * struct print_buf - TIPC print buffer structure | ||
42 | * @buf: pointer to character array containing print buffer contents | ||
43 | * @size: size of character array | ||
44 | * @crs: pointer to first unused space in character array (i.e. final NUL) | ||
45 | * @next: used to link print buffers when printing to more than one at a time | ||
46 | */ | ||
47 | |||
40 | struct print_buf { | 48 | struct print_buf { |
41 | char *buf; | 49 | char *buf; |
42 | u32 size; | 50 | u32 size; |
@@ -44,7 +52,10 @@ struct print_buf { | |||
44 | struct print_buf *next; | 52 | struct print_buf *next; |
45 | }; | 53 | }; |
46 | 54 | ||
47 | void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 sz); | 55 | #define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ |
56 | #define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ | ||
57 | |||
58 | void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); | ||
48 | void tipc_printbuf_reset(struct print_buf *pb); | 59 | void tipc_printbuf_reset(struct print_buf *pb); |
49 | int tipc_printbuf_empty(struct print_buf *pb); | 60 | int tipc_printbuf_empty(struct print_buf *pb); |
50 | int tipc_printbuf_validate(struct print_buf *pb); | 61 | int tipc_printbuf_validate(struct print_buf *pb); |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index ee94de92ae99..3b0cd12f37da 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
@@ -132,6 +132,28 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /** | 134 | /** |
135 | * disc_dupl_alert - issue node address duplication alert | ||
136 | * @b_ptr: pointer to bearer detecting duplication | ||
137 | * @node_addr: duplicated node address | ||
138 | * @media_addr: media address advertised by duplicated node | ||
139 | */ | ||
140 | |||
141 | static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, | ||
142 | struct tipc_media_addr *media_addr) | ||
143 | { | ||
144 | char node_addr_str[16]; | ||
145 | char media_addr_str[64]; | ||
146 | struct print_buf pb; | ||
147 | |||
148 | addr_string_fill(node_addr_str, node_addr); | ||
149 | tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); | ||
150 | tipc_media_addr_printf(&pb, media_addr); | ||
151 | tipc_printbuf_validate(&pb); | ||
152 | warn("Duplicate %s using %s seen on <%s>\n", | ||
153 | node_addr_str, media_addr_str, b_ptr->publ.name); | ||
154 | } | ||
155 | |||
156 | /** | ||
135 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) | 157 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) |
136 | * @buf: buffer containing message | 158 | * @buf: buffer containing message |
137 | */ | 159 | */ |
@@ -157,8 +179,11 @@ void tipc_disc_recv_msg(struct sk_buff *buf) | |||
157 | return; | 179 | return; |
158 | if (!tipc_addr_node_valid(orig)) | 180 | if (!tipc_addr_node_valid(orig)) |
159 | return; | 181 | return; |
160 | if (orig == tipc_own_addr) | 182 | if (orig == tipc_own_addr) { |
183 | if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr))) | ||
184 | disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); | ||
161 | return; | 185 | return; |
186 | } | ||
162 | if (!in_scope(dest, tipc_own_addr)) | 187 | if (!in_scope(dest, tipc_own_addr)) |
163 | return; | 188 | return; |
164 | if (is_slave(tipc_own_addr) && is_slave(orig)) | 189 | if (is_slave(tipc_own_addr) && is_slave(orig)) |
@@ -170,7 +195,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf) | |||
170 | struct sk_buff *rbuf; | 195 | struct sk_buff *rbuf; |
171 | struct tipc_media_addr *addr; | 196 | struct tipc_media_addr *addr; |
172 | struct node *n_ptr = tipc_node_find(orig); | 197 | struct node *n_ptr = tipc_node_find(orig); |
173 | int link_up; | 198 | int link_fully_up; |
199 | |||
174 | dbg(" in own cluster\n"); | 200 | dbg(" in own cluster\n"); |
175 | if (n_ptr == NULL) { | 201 | if (n_ptr == NULL) { |
176 | n_ptr = tipc_node_create(orig); | 202 | n_ptr = tipc_node_create(orig); |
@@ -190,14 +216,19 @@ void tipc_disc_recv_msg(struct sk_buff *buf) | |||
190 | } | 216 | } |
191 | addr = &link->media_addr; | 217 | addr = &link->media_addr; |
192 | if (memcmp(addr, &media_addr, sizeof(*addr))) { | 218 | if (memcmp(addr, &media_addr, sizeof(*addr))) { |
219 | if (tipc_link_is_up(link) || (!link->started)) { | ||
220 | disc_dupl_alert(b_ptr, orig, &media_addr); | ||
221 | spin_unlock_bh(&n_ptr->lock); | ||
222 | return; | ||
223 | } | ||
193 | warn("Resetting link <%s>, peer interface address changed\n", | 224 | warn("Resetting link <%s>, peer interface address changed\n", |
194 | link->name); | 225 | link->name); |
195 | memcpy(addr, &media_addr, sizeof(*addr)); | 226 | memcpy(addr, &media_addr, sizeof(*addr)); |
196 | tipc_link_reset(link); | 227 | tipc_link_reset(link); |
197 | } | 228 | } |
198 | link_up = tipc_link_is_up(link); | 229 | link_fully_up = (link->state == WORKING_WORKING); |
199 | spin_unlock_bh(&n_ptr->lock); | 230 | spin_unlock_bh(&n_ptr->lock); |
200 | if ((type == DSC_RESP_MSG) || link_up) | 231 | if ((type == DSC_RESP_MSG) || link_fully_up) |
201 | return; | 232 | return; |
202 | rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); | 233 | rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); |
203 | if (rbuf != NULL) { | 234 | if (rbuf != NULL) { |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 53bc8cb5adbc..1bb983c8130b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -132,7 +132,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
132 | * allow the output from multiple links to be intermixed. For this reason | 132 | * allow the output from multiple links to be intermixed. For this reason |
133 | * routines of the form "dbg_link_XXX()" have been created that will capture | 133 | * routines of the form "dbg_link_XXX()" have been created that will capture |
134 | * debug info into a link's personal print buffer, which can then be dumped | 134 | * debug info into a link's personal print buffer, which can then be dumped |
135 | * into the TIPC system log (LOG) upon request. | 135 | * into the TIPC system log (TIPC_LOG) upon request. |
136 | * | 136 | * |
137 | * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size | 137 | * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size |
138 | * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, | 138 | * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, |
@@ -141,7 +141,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
141 | * when there is only a single link in the system being debugged. | 141 | * when there is only a single link in the system being debugged. |
142 | * | 142 | * |
143 | * Notes: | 143 | * Notes: |
144 | * - When enabled, LINK_LOG_BUF_SIZE should be set to at least 1000 (bytes) | 144 | * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE |
145 | * - "l_ptr" must be valid when using dbg_link_XXX() macros | 145 | * - "l_ptr" must be valid when using dbg_link_XXX() macros |
146 | */ | 146 | */ |
147 | 147 | ||
@@ -159,13 +159,13 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
159 | 159 | ||
160 | static void dbg_print_link(struct link *l_ptr, const char *str) | 160 | static void dbg_print_link(struct link *l_ptr, const char *str) |
161 | { | 161 | { |
162 | if (DBG_OUTPUT) | 162 | if (DBG_OUTPUT != TIPC_NULL) |
163 | link_print(l_ptr, DBG_OUTPUT, str); | 163 | link_print(l_ptr, DBG_OUTPUT, str); |
164 | } | 164 | } |
165 | 165 | ||
166 | static void dbg_print_buf_chain(struct sk_buff *root_buf) | 166 | static void dbg_print_buf_chain(struct sk_buff *root_buf) |
167 | { | 167 | { |
168 | if (DBG_OUTPUT) { | 168 | if (DBG_OUTPUT != TIPC_NULL) { |
169 | struct sk_buff *buf = root_buf; | 169 | struct sk_buff *buf = root_buf; |
170 | 170 | ||
171 | while (buf) { | 171 | while (buf) { |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index f0b063bcc2a9..03bd659c43ca 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -122,7 +122,7 @@ void tipc_named_publish(struct publication *publ) | |||
122 | struct sk_buff *buf; | 122 | struct sk_buff *buf; |
123 | struct distr_item *item; | 123 | struct distr_item *item; |
124 | 124 | ||
125 | list_add(&publ->local_list, &publ_root); | 125 | list_add_tail(&publ->local_list, &publ_root); |
126 | publ_cnt++; | 126 | publ_cnt++; |
127 | 127 | ||
128 | buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); | 128 | buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index fc6d09630ccd..886bda5e88db 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -648,7 +648,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
648 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 648 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
649 | " (network address)"); | 649 | " (network address)"); |
650 | 650 | ||
651 | if (!tipc_nodes) | 651 | if (tipc_mode != TIPC_NET_MODE) |
652 | return tipc_cfg_reply_none(); | 652 | return tipc_cfg_reply_none(); |
653 | 653 | ||
654 | /* Get space for all unicast links + multicast link */ | 654 | /* Get space for all unicast links + multicast link */ |
diff --git a/net/tipc/port.c b/net/tipc/port.c index b9c8c6b9e94f..b7f3199523ca 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -505,8 +505,13 @@ static void port_timeout(unsigned long ref) | |||
505 | struct port *p_ptr = tipc_port_lock(ref); | 505 | struct port *p_ptr = tipc_port_lock(ref); |
506 | struct sk_buff *buf = NULL; | 506 | struct sk_buff *buf = NULL; |
507 | 507 | ||
508 | if (!p_ptr || !p_ptr->publ.connected) | 508 | if (!p_ptr) |
509 | return; | ||
510 | |||
511 | if (!p_ptr->publ.connected) { | ||
512 | tipc_port_unlock(p_ptr); | ||
509 | return; | 513 | return; |
514 | } | ||
510 | 515 | ||
511 | /* Last probe answered ? */ | 516 | /* Last probe answered ? */ |
512 | if (p_ptr->probing_state == PROBING) { | 517 | if (p_ptr->probing_state == PROBING) { |
@@ -1131,11 +1136,12 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
1131 | int res = -EINVAL; | 1136 | int res = -EINVAL; |
1132 | 1137 | ||
1133 | p_ptr = tipc_port_lock(ref); | 1138 | p_ptr = tipc_port_lock(ref); |
1139 | if (!p_ptr) | ||
1140 | return -EINVAL; | ||
1141 | |||
1134 | dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " | 1142 | dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " |
1135 | "lower = %u, upper = %u\n", | 1143 | "lower = %u, upper = %u\n", |
1136 | ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); | 1144 | ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); |
1137 | if (!p_ptr) | ||
1138 | return -EINVAL; | ||
1139 | if (p_ptr->publ.connected) | 1145 | if (p_ptr->publ.connected) |
1140 | goto exit; | 1146 | goto exit; |
1141 | if (seq->lower > seq->upper) | 1147 | if (seq->lower > seq->upper) |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index acfb852e7c98..2a6a5a6b4c12 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2006, Ericsson AB | 4 | * Copyright (c) 2001-2006, Ericsson AB |
5 | * Copyright (c) 2004-2005, Wind River Systems | 5 | * Copyright (c) 2004-2006, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -629,6 +629,9 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
629 | return -ENOTCONN; | 629 | return -ENOTCONN; |
630 | } | 630 | } |
631 | 631 | ||
632 | if (unlikely(m->msg_name)) | ||
633 | return -EISCONN; | ||
634 | |||
632 | /* | 635 | /* |
633 | * Send each iovec entry using one or more messages | 636 | * Send each iovec entry using one or more messages |
634 | * | 637 | * |
@@ -641,6 +644,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
641 | curr_iovlen = m->msg_iovlen; | 644 | curr_iovlen = m->msg_iovlen; |
642 | my_msg.msg_iov = &my_iov; | 645 | my_msg.msg_iov = &my_iov; |
643 | my_msg.msg_iovlen = 1; | 646 | my_msg.msg_iovlen = 1; |
647 | my_msg.msg_flags = m->msg_flags; | ||
648 | my_msg.msg_name = NULL; | ||
644 | bytes_sent = 0; | 649 | bytes_sent = 0; |
645 | 650 | ||
646 | while (curr_iovlen--) { | 651 | while (curr_iovlen--) { |
@@ -1203,7 +1208,8 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | |||
1203 | atomic_inc(&tipc_queue_size); | 1208 | atomic_inc(&tipc_queue_size); |
1204 | skb_queue_tail(&sock->sk->sk_receive_queue, buf); | 1209 | skb_queue_tail(&sock->sk->sk_receive_queue, buf); |
1205 | 1210 | ||
1206 | wake_up_interruptible(sock->sk->sk_sleep); | 1211 | if (waitqueue_active(sock->sk->sk_sleep)) |
1212 | wake_up_interruptible(sock->sk->sk_sleep); | ||
1207 | return TIPC_OK; | 1213 | return TIPC_OK; |
1208 | } | 1214 | } |
1209 | 1215 | ||
@@ -1218,7 +1224,8 @@ static void wakeupdispatch(struct tipc_port *tport) | |||
1218 | { | 1224 | { |
1219 | struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; | 1225 | struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; |
1220 | 1226 | ||
1221 | wake_up_interruptible(tsock->sk.sk_sleep); | 1227 | if (waitqueue_active(tsock->sk.sk_sleep)) |
1228 | wake_up_interruptible(tsock->sk.sk_sleep); | ||
1222 | } | 1229 | } |
1223 | 1230 | ||
1224 | /** | 1231 | /** |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index c51600ba5f4a..7a918f12a5df 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -155,7 +155,7 @@ void tipc_subscr_report_overlap(struct subscription *sub, | |||
155 | sub->seq.upper, found_lower, found_upper); | 155 | sub->seq.upper, found_lower, found_upper); |
156 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) | 156 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) |
157 | return; | 157 | return; |
158 | if (!must && (sub->filter != TIPC_SUB_PORTS)) | 158 | if (!must && !(sub->filter & TIPC_SUB_PORTS)) |
159 | return; | 159 | return; |
160 | subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); | 160 | subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); |
161 | } | 161 | } |
@@ -176,6 +176,13 @@ static void subscr_timeout(struct subscription *sub) | |||
176 | if (subscriber == NULL) | 176 | if (subscriber == NULL) |
177 | return; | 177 | return; |
178 | 178 | ||
179 | /* Validate timeout (in case subscription is being cancelled) */ | ||
180 | |||
181 | if (sub->timeout == TIPC_WAIT_FOREVER) { | ||
182 | tipc_ref_unlock(subscriber_ref); | ||
183 | return; | ||
184 | } | ||
185 | |||
179 | /* Unlink subscription from name table */ | 186 | /* Unlink subscription from name table */ |
180 | 187 | ||
181 | tipc_nametbl_unsubscribe(sub); | 188 | tipc_nametbl_unsubscribe(sub); |
@@ -199,6 +206,20 @@ static void subscr_timeout(struct subscription *sub) | |||
199 | } | 206 | } |
200 | 207 | ||
201 | /** | 208 | /** |
209 | * subscr_del - delete a subscription within a subscription list | ||
210 | * | ||
211 | * Called with subscriber locked. | ||
212 | */ | ||
213 | |||
214 | static void subscr_del(struct subscription *sub) | ||
215 | { | ||
216 | tipc_nametbl_unsubscribe(sub); | ||
217 | list_del(&sub->subscription_list); | ||
218 | kfree(sub); | ||
219 | atomic_dec(&topsrv.subscription_count); | ||
220 | } | ||
221 | |||
222 | /** | ||
202 | * subscr_terminate - terminate communication with a subscriber | 223 | * subscr_terminate - terminate communication with a subscriber |
203 | * | 224 | * |
204 | * Called with subscriber locked. Routine must temporarily release this lock | 225 | * Called with subscriber locked. Routine must temporarily release this lock |
@@ -227,12 +248,9 @@ static void subscr_terminate(struct subscriber *subscriber) | |||
227 | k_cancel_timer(&sub->timer); | 248 | k_cancel_timer(&sub->timer); |
228 | k_term_timer(&sub->timer); | 249 | k_term_timer(&sub->timer); |
229 | } | 250 | } |
230 | tipc_nametbl_unsubscribe(sub); | 251 | dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n", |
231 | list_del(&sub->subscription_list); | ||
232 | dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n", | ||
233 | sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); | 252 | sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); |
234 | kfree(sub); | 253 | subscr_del(sub); |
235 | atomic_dec(&topsrv.subscription_count); | ||
236 | } | 254 | } |
237 | 255 | ||
238 | /* Sever connection to subscriber */ | 256 | /* Sever connection to subscriber */ |
@@ -253,6 +271,49 @@ static void subscr_terminate(struct subscriber *subscriber) | |||
253 | } | 271 | } |
254 | 272 | ||
255 | /** | 273 | /** |
274 | * subscr_cancel - handle subscription cancellation request | ||
275 | * | ||
276 | * Called with subscriber locked. Routine must temporarily release this lock | ||
277 | * to enable the subscription timeout routine to finish without deadlocking; | ||
278 | * the lock is then reclaimed to allow caller to release it upon return. | ||
279 | * | ||
280 | * Note that fields of 's' use subscriber's endianness! | ||
281 | */ | ||
282 | |||
283 | static void subscr_cancel(struct tipc_subscr *s, | ||
284 | struct subscriber *subscriber) | ||
285 | { | ||
286 | struct subscription *sub; | ||
287 | struct subscription *sub_temp; | ||
288 | int found = 0; | ||
289 | |||
290 | /* Find first matching subscription, exit if not found */ | ||
291 | |||
292 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | ||
293 | subscription_list) { | ||
294 | if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { | ||
295 | found = 1; | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | if (!found) | ||
300 | return; | ||
301 | |||
302 | /* Cancel subscription timer (if used), then delete subscription */ | ||
303 | |||
304 | if (sub->timeout != TIPC_WAIT_FOREVER) { | ||
305 | sub->timeout = TIPC_WAIT_FOREVER; | ||
306 | spin_unlock_bh(subscriber->lock); | ||
307 | k_cancel_timer(&sub->timer); | ||
308 | k_term_timer(&sub->timer); | ||
309 | spin_lock_bh(subscriber->lock); | ||
310 | } | ||
311 | dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", | ||
312 | sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); | ||
313 | subscr_del(sub); | ||
314 | } | ||
315 | |||
316 | /** | ||
256 | * subscr_subscribe - create subscription for subscriber | 317 | * subscr_subscribe - create subscription for subscriber |
257 | * | 318 | * |
258 | * Called with subscriber locked | 319 | * Called with subscriber locked |
@@ -263,6 +324,21 @@ static void subscr_subscribe(struct tipc_subscr *s, | |||
263 | { | 324 | { |
264 | struct subscription *sub; | 325 | struct subscription *sub; |
265 | 326 | ||
327 | /* Determine/update subscriber's endianness */ | ||
328 | |||
329 | if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) | ||
330 | subscriber->swap = 0; | ||
331 | else | ||
332 | subscriber->swap = 1; | ||
333 | |||
334 | /* Detect & process a subscription cancellation request */ | ||
335 | |||
336 | if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { | ||
337 | s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); | ||
338 | subscr_cancel(s, subscriber); | ||
339 | return; | ||
340 | } | ||
341 | |||
266 | /* Refuse subscription if global limit exceeded */ | 342 | /* Refuse subscription if global limit exceeded */ |
267 | 343 | ||
268 | if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { | 344 | if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { |
@@ -281,13 +357,6 @@ static void subscr_subscribe(struct tipc_subscr *s, | |||
281 | return; | 357 | return; |
282 | } | 358 | } |
283 | 359 | ||
284 | /* Determine/update subscriber's endianness */ | ||
285 | |||
286 | if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE)) | ||
287 | subscriber->swap = 0; | ||
288 | else | ||
289 | subscriber->swap = 1; | ||
290 | |||
291 | /* Initialize subscription object */ | 360 | /* Initialize subscription object */ |
292 | 361 | ||
293 | memset(sub, 0, sizeof(*sub)); | 362 | memset(sub, 0, sizeof(*sub)); |
@@ -296,8 +365,8 @@ static void subscr_subscribe(struct tipc_subscr *s, | |||
296 | sub->seq.upper = htohl(s->seq.upper, subscriber->swap); | 365 | sub->seq.upper = htohl(s->seq.upper, subscriber->swap); |
297 | sub->timeout = htohl(s->timeout, subscriber->swap); | 366 | sub->timeout = htohl(s->timeout, subscriber->swap); |
298 | sub->filter = htohl(s->filter, subscriber->swap); | 367 | sub->filter = htohl(s->filter, subscriber->swap); |
299 | if ((((sub->filter != TIPC_SUB_PORTS) | 368 | if ((!(sub->filter & TIPC_SUB_PORTS) |
300 | && (sub->filter != TIPC_SUB_SERVICE))) | 369 | == !(sub->filter & TIPC_SUB_SERVICE)) |
301 | || (sub->seq.lower > sub->seq.upper)) { | 370 | || (sub->seq.lower > sub->seq.upper)) { |
302 | warn("Subscription rejected, illegal request\n"); | 371 | warn("Subscription rejected, illegal request\n"); |
303 | kfree(sub); | 372 | kfree(sub); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2a7861661f14..7736b23c3f03 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -883,30 +883,32 @@ out: | |||
883 | } | 883 | } |
884 | EXPORT_SYMBOL(xfrm_policy_walk); | 884 | EXPORT_SYMBOL(xfrm_policy_walk); |
885 | 885 | ||
886 | /* Find policy to apply to this flow. */ | 886 | /* |
887 | 887 | * Find policy to apply to this flow. | |
888 | * | ||
889 | * Returns 0 if policy found, else an -errno. | ||
890 | */ | ||
888 | static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, | 891 | static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, |
889 | u8 type, u16 family, int dir) | 892 | u8 type, u16 family, int dir) |
890 | { | 893 | { |
891 | struct xfrm_selector *sel = &pol->selector; | 894 | struct xfrm_selector *sel = &pol->selector; |
892 | int match; | 895 | int match, ret = -ESRCH; |
893 | 896 | ||
894 | if (pol->family != family || | 897 | if (pol->family != family || |
895 | pol->type != type) | 898 | pol->type != type) |
896 | return 0; | 899 | return ret; |
897 | 900 | ||
898 | match = xfrm_selector_match(sel, fl, family); | 901 | match = xfrm_selector_match(sel, fl, family); |
899 | if (match) { | 902 | if (match) |
900 | if (!security_xfrm_policy_lookup(pol, fl->secid, dir)) | 903 | ret = security_xfrm_policy_lookup(pol, fl->secid, dir); |
901 | return 1; | ||
902 | } | ||
903 | 904 | ||
904 | return 0; | 905 | return ret; |
905 | } | 906 | } |
906 | 907 | ||
907 | static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | 908 | static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, |
908 | u16 family, u8 dir) | 909 | u16 family, u8 dir) |
909 | { | 910 | { |
911 | int err; | ||
910 | struct xfrm_policy *pol, *ret; | 912 | struct xfrm_policy *pol, *ret; |
911 | xfrm_address_t *daddr, *saddr; | 913 | xfrm_address_t *daddr, *saddr; |
912 | struct hlist_node *entry; | 914 | struct hlist_node *entry; |
@@ -922,7 +924,15 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | |||
922 | chain = policy_hash_direct(daddr, saddr, family, dir); | 924 | chain = policy_hash_direct(daddr, saddr, family, dir); |
923 | ret = NULL; | 925 | ret = NULL; |
924 | hlist_for_each_entry(pol, entry, chain, bydst) { | 926 | hlist_for_each_entry(pol, entry, chain, bydst) { |
925 | if (xfrm_policy_match(pol, fl, type, family, dir)) { | 927 | err = xfrm_policy_match(pol, fl, type, family, dir); |
928 | if (err) { | ||
929 | if (err == -ESRCH) | ||
930 | continue; | ||
931 | else { | ||
932 | ret = ERR_PTR(err); | ||
933 | goto fail; | ||
934 | } | ||
935 | } else { | ||
926 | ret = pol; | 936 | ret = pol; |
927 | priority = ret->priority; | 937 | priority = ret->priority; |
928 | break; | 938 | break; |
@@ -930,36 +940,53 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | |||
930 | } | 940 | } |
931 | chain = &xfrm_policy_inexact[dir]; | 941 | chain = &xfrm_policy_inexact[dir]; |
932 | hlist_for_each_entry(pol, entry, chain, bydst) { | 942 | hlist_for_each_entry(pol, entry, chain, bydst) { |
933 | if (xfrm_policy_match(pol, fl, type, family, dir) && | 943 | err = xfrm_policy_match(pol, fl, type, family, dir); |
934 | pol->priority < priority) { | 944 | if (err) { |
945 | if (err == -ESRCH) | ||
946 | continue; | ||
947 | else { | ||
948 | ret = ERR_PTR(err); | ||
949 | goto fail; | ||
950 | } | ||
951 | } else if (pol->priority < priority) { | ||
935 | ret = pol; | 952 | ret = pol; |
936 | break; | 953 | break; |
937 | } | 954 | } |
938 | } | 955 | } |
939 | if (ret) | 956 | if (ret) |
940 | xfrm_pol_hold(ret); | 957 | xfrm_pol_hold(ret); |
958 | fail: | ||
941 | read_unlock_bh(&xfrm_policy_lock); | 959 | read_unlock_bh(&xfrm_policy_lock); |
942 | 960 | ||
943 | return ret; | 961 | return ret; |
944 | } | 962 | } |
945 | 963 | ||
946 | static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | 964 | static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, |
947 | void **objp, atomic_t **obj_refp) | 965 | void **objp, atomic_t **obj_refp) |
948 | { | 966 | { |
949 | struct xfrm_policy *pol; | 967 | struct xfrm_policy *pol; |
968 | int err = 0; | ||
950 | 969 | ||
951 | #ifdef CONFIG_XFRM_SUB_POLICY | 970 | #ifdef CONFIG_XFRM_SUB_POLICY |
952 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); | 971 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); |
953 | if (pol) | 972 | if (IS_ERR(pol)) { |
973 | err = PTR_ERR(pol); | ||
974 | pol = NULL; | ||
975 | } | ||
976 | if (pol || err) | ||
954 | goto end; | 977 | goto end; |
955 | #endif | 978 | #endif |
956 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); | 979 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); |
957 | 980 | if (IS_ERR(pol)) { | |
981 | err = PTR_ERR(pol); | ||
982 | pol = NULL; | ||
983 | } | ||
958 | #ifdef CONFIG_XFRM_SUB_POLICY | 984 | #ifdef CONFIG_XFRM_SUB_POLICY |
959 | end: | 985 | end: |
960 | #endif | 986 | #endif |
961 | if ((*objp = (void *) pol) != NULL) | 987 | if ((*objp = (void *) pol) != NULL) |
962 | *obj_refp = &pol->refcnt; | 988 | *obj_refp = &pol->refcnt; |
989 | return err; | ||
963 | } | 990 | } |
964 | 991 | ||
965 | static inline int policy_to_flow_dir(int dir) | 992 | static inline int policy_to_flow_dir(int dir) |
@@ -989,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
989 | sk->sk_family); | 1016 | sk->sk_family); |
990 | int err = 0; | 1017 | int err = 0; |
991 | 1018 | ||
992 | if (match) | 1019 | if (match) { |
993 | err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); | 1020 | err = security_xfrm_policy_lookup(pol, fl->secid, |
994 | 1021 | policy_to_flow_dir(dir)); | |
995 | if (match && !err) | 1022 | if (!err) |
996 | xfrm_pol_hold(pol); | 1023 | xfrm_pol_hold(pol); |
997 | else | 1024 | else if (err == -ESRCH) |
1025 | pol = NULL; | ||
1026 | else | ||
1027 | pol = ERR_PTR(err); | ||
1028 | } else | ||
998 | pol = NULL; | 1029 | pol = NULL; |
999 | } | 1030 | } |
1000 | read_unlock_bh(&xfrm_policy_lock); | 1031 | read_unlock_bh(&xfrm_policy_lock); |
@@ -1286,8 +1317,11 @@ restart: | |||
1286 | pol_dead = 0; | 1317 | pol_dead = 0; |
1287 | xfrm_nr = 0; | 1318 | xfrm_nr = 0; |
1288 | 1319 | ||
1289 | if (sk && sk->sk_policy[1]) | 1320 | if (sk && sk->sk_policy[1]) { |
1290 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | 1321 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); |
1322 | if (IS_ERR(policy)) | ||
1323 | return PTR_ERR(policy); | ||
1324 | } | ||
1291 | 1325 | ||
1292 | if (!policy) { | 1326 | if (!policy) { |
1293 | /* To accelerate a bit... */ | 1327 | /* To accelerate a bit... */ |
@@ -1297,6 +1331,8 @@ restart: | |||
1297 | 1331 | ||
1298 | policy = flow_cache_lookup(fl, dst_orig->ops->family, | 1332 | policy = flow_cache_lookup(fl, dst_orig->ops->family, |
1299 | dir, xfrm_policy_lookup); | 1333 | dir, xfrm_policy_lookup); |
1334 | if (IS_ERR(policy)) | ||
1335 | return PTR_ERR(policy); | ||
1300 | } | 1336 | } |
1301 | 1337 | ||
1302 | if (!policy) | 1338 | if (!policy) |
@@ -1343,6 +1379,10 @@ restart: | |||
1343 | fl, family, | 1379 | fl, family, |
1344 | XFRM_POLICY_OUT); | 1380 | XFRM_POLICY_OUT); |
1345 | if (pols[1]) { | 1381 | if (pols[1]) { |
1382 | if (IS_ERR(pols[1])) { | ||
1383 | err = PTR_ERR(pols[1]); | ||
1384 | goto error; | ||
1385 | } | ||
1346 | if (pols[1]->action == XFRM_POLICY_BLOCK) { | 1386 | if (pols[1]->action == XFRM_POLICY_BLOCK) { |
1347 | err = -EPERM; | 1387 | err = -EPERM; |
1348 | goto error; | 1388 | goto error; |
@@ -1574,13 +1614,19 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
1574 | } | 1614 | } |
1575 | 1615 | ||
1576 | pol = NULL; | 1616 | pol = NULL; |
1577 | if (sk && sk->sk_policy[dir]) | 1617 | if (sk && sk->sk_policy[dir]) { |
1578 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); | 1618 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); |
1619 | if (IS_ERR(pol)) | ||
1620 | return 0; | ||
1621 | } | ||
1579 | 1622 | ||
1580 | if (!pol) | 1623 | if (!pol) |
1581 | pol = flow_cache_lookup(&fl, family, fl_dir, | 1624 | pol = flow_cache_lookup(&fl, family, fl_dir, |
1582 | xfrm_policy_lookup); | 1625 | xfrm_policy_lookup); |
1583 | 1626 | ||
1627 | if (IS_ERR(pol)) | ||
1628 | return 0; | ||
1629 | |||
1584 | if (!pol) { | 1630 | if (!pol) { |
1585 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { | 1631 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { |
1586 | xfrm_secpath_reject(xerr_idx, skb, &fl); | 1632 | xfrm_secpath_reject(xerr_idx, skb, &fl); |
@@ -1599,6 +1645,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
1599 | &fl, family, | 1645 | &fl, family, |
1600 | XFRM_POLICY_IN); | 1646 | XFRM_POLICY_IN); |
1601 | if (pols[1]) { | 1647 | if (pols[1]) { |
1648 | if (IS_ERR(pols[1])) | ||
1649 | return 0; | ||
1602 | pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; | 1650 | pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; |
1603 | npols ++; | 1651 | npols ++; |
1604 | } | 1652 | } |
@@ -1706,7 +1754,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | |||
1706 | 1754 | ||
1707 | static int stale_bundle(struct dst_entry *dst) | 1755 | static int stale_bundle(struct dst_entry *dst) |
1708 | { | 1756 | { |
1709 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); | 1757 | return !xfrm_bundle_ok(NULL, (struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); |
1710 | } | 1758 | } |
1711 | 1759 | ||
1712 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) | 1760 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
@@ -1828,7 +1876,8 @@ EXPORT_SYMBOL(xfrm_init_pmtu); | |||
1828 | * still valid. | 1876 | * still valid. |
1829 | */ | 1877 | */ |
1830 | 1878 | ||
1831 | int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict) | 1879 | int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, |
1880 | struct flowi *fl, int family, int strict) | ||
1832 | { | 1881 | { |
1833 | struct dst_entry *dst = &first->u.dst; | 1882 | struct dst_entry *dst = &first->u.dst; |
1834 | struct xfrm_dst *last; | 1883 | struct xfrm_dst *last; |
@@ -1845,7 +1894,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int str | |||
1845 | 1894 | ||
1846 | if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) | 1895 | if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) |
1847 | return 0; | 1896 | return 0; |
1848 | if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm)) | 1897 | if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) |
1849 | return 0; | 1898 | return 0; |
1850 | if (dst->xfrm->km.state != XFRM_STATE_VALID) | 1899 | if (dst->xfrm->km.state != XFRM_STATE_VALID) |
1851 | return 0; | 1900 | return 0; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 39b8bf3a9ded..899de9ed22a6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
505 | x->id.proto, family); | 505 | x->id.proto, family); |
506 | } | 506 | } |
507 | 507 | ||
508 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
509 | { | ||
510 | if (have_hash_collision && | ||
511 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
512 | xfrm_state_num > xfrm_state_hmask) | ||
513 | schedule_work(&xfrm_hash_work); | ||
514 | } | ||
515 | |||
508 | struct xfrm_state * | 516 | struct xfrm_state * |
509 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 517 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, |
510 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 518 | struct flowi *fl, struct xfrm_tmpl *tmpl, |
@@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
598 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 606 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; |
599 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 607 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; |
600 | add_timer(&x->timer); | 608 | add_timer(&x->timer); |
609 | xfrm_state_num++; | ||
610 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
601 | } else { | 611 | } else { |
602 | x->km.state = XFRM_STATE_DEAD; | 612 | x->km.state = XFRM_STATE_DEAD; |
603 | xfrm_state_put(x); | 613 | xfrm_state_put(x); |
@@ -642,10 +652,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
642 | 652 | ||
643 | xfrm_state_num++; | 653 | xfrm_state_num++; |
644 | 654 | ||
645 | if (x->bydst.next != NULL && | 655 | xfrm_hash_grow_check(x->bydst.next != NULL); |
646 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
647 | xfrm_state_num > xfrm_state_hmask) | ||
648 | schedule_work(&xfrm_hash_work); | ||
649 | } | 656 | } |
650 | 657 | ||
651 | /* xfrm_state_lock is held */ | 658 | /* xfrm_state_lock is held */ |
@@ -753,6 +760,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
753 | h = xfrm_src_hash(daddr, saddr, family); | 760 | h = xfrm_src_hash(daddr, saddr, family); |
754 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 761 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
755 | wake_up(&km_waitq); | 762 | wake_up(&km_waitq); |
763 | |||
764 | xfrm_state_num++; | ||
765 | |||
766 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
756 | } | 767 | } |
757 | 768 | ||
758 | return x; | 769 | return x; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d54b3a70d5df..c4cde57d9216 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -323,7 +323,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
323 | x->props.replay_window = p->replay_window; | 323 | x->props.replay_window = p->replay_window; |
324 | x->props.reqid = p->reqid; | 324 | x->props.reqid = p->reqid; |
325 | x->props.family = p->family; | 325 | x->props.family = p->family; |
326 | x->props.saddr = p->saddr; | 326 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); |
327 | x->props.flags = p->flags; | 327 | x->props.flags = p->flags; |
328 | } | 328 | } |
329 | 329 | ||
@@ -545,7 +545,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) | |||
545 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); | 545 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); |
546 | memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); | 546 | memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); |
547 | memcpy(&p->stats, &x->stats, sizeof(p->stats)); | 547 | memcpy(&p->stats, &x->stats, sizeof(p->stats)); |
548 | p->saddr = x->props.saddr; | 548 | memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr)); |
549 | p->mode = x->props.mode; | 549 | p->mode = x->props.mode; |
550 | p->replay_window = x->props.replay_window; | 550 | p->replay_window = x->props.replay_window; |
551 | p->reqid = x->props.reqid; | 551 | p->reqid = x->props.reqid; |
@@ -1927,6 +1927,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
1927 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 1927 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
1928 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); | 1928 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); |
1929 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 1929 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
1930 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
1931 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
1932 | #endif | ||
1930 | skb = alloc_skb(len, GFP_ATOMIC); | 1933 | skb = alloc_skb(len, GFP_ATOMIC); |
1931 | if (skb == NULL) | 1934 | if (skb == NULL) |
1932 | return -ENOMEM; | 1935 | return -ENOMEM; |
@@ -1992,15 +1995,6 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | |||
1992 | xp->type = XFRM_POLICY_TYPE_MAIN; | 1995 | xp->type = XFRM_POLICY_TYPE_MAIN; |
1993 | copy_templates(xp, ut, nr); | 1996 | copy_templates(xp, ut, nr); |
1994 | 1997 | ||
1995 | if (!xp->security) { | ||
1996 | int err = security_xfrm_sock_policy_alloc(xp, sk); | ||
1997 | if (err) { | ||
1998 | kfree(xp); | ||
1999 | *dir = err; | ||
2000 | return NULL; | ||
2001 | } | ||
2002 | } | ||
2003 | |||
2004 | *dir = p->dir; | 1998 | *dir = p->dir; |
2005 | 1999 | ||
2006 | return xp; | 2000 | return xp; |
@@ -2043,6 +2037,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
2043 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 2037 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
2044 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); | 2038 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); |
2045 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 2039 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
2040 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
2041 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2042 | #endif | ||
2046 | skb = alloc_skb(len, GFP_ATOMIC); | 2043 | skb = alloc_skb(len, GFP_ATOMIC); |
2047 | if (skb == NULL) | 2044 | if (skb == NULL) |
2048 | return -ENOMEM; | 2045 | return -ENOMEM; |
@@ -2069,6 +2066,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2069 | len += RTA_SPACE(headlen); | 2066 | len += RTA_SPACE(headlen); |
2070 | headlen = sizeof(*id); | 2067 | headlen = sizeof(*id); |
2071 | } | 2068 | } |
2069 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
2070 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2071 | #endif | ||
2072 | len += NLMSG_SPACE(headlen); | 2072 | len += NLMSG_SPACE(headlen); |
2073 | 2073 | ||
2074 | skb = alloc_skb(len, GFP_ATOMIC); | 2074 | skb = alloc_skb(len, GFP_ATOMIC); |
@@ -2115,10 +2115,12 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
2115 | struct nlmsghdr *nlh; | 2115 | struct nlmsghdr *nlh; |
2116 | struct sk_buff *skb; | 2116 | struct sk_buff *skb; |
2117 | unsigned char *b; | 2117 | unsigned char *b; |
2118 | int len = 0; | ||
2118 | #ifdef CONFIG_XFRM_SUB_POLICY | 2119 | #ifdef CONFIG_XFRM_SUB_POLICY |
2119 | struct xfrm_userpolicy_type upt; | 2120 | struct xfrm_userpolicy_type upt; |
2121 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2120 | #endif | 2122 | #endif |
2121 | int len = NLMSG_LENGTH(0); | 2123 | len += NLMSG_LENGTH(0); |
2122 | 2124 | ||
2123 | skb = alloc_skb(len, GFP_ATOMIC); | 2125 | skb = alloc_skb(len, GFP_ATOMIC); |
2124 | if (skb == NULL) | 2126 | if (skb == NULL) |