diff options
Diffstat (limited to 'net')
166 files changed, 2053 insertions, 1939 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index bd93c45778d4..de78c9dd713b 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -240,10 +240,8 @@ static int unregister_vlan_dev(struct net_device *real_dev, | |||
| 240 | * interlock with HW accelerating devices or SW vlan | 240 | * interlock with HW accelerating devices or SW vlan |
| 241 | * input packet processing. | 241 | * input packet processing. |
| 242 | */ | 242 | */ |
| 243 | if (real_dev->features & | 243 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) |
| 244 | (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER)) { | ||
| 245 | real_dev->vlan_rx_kill_vid(real_dev, vlan_id); | 244 | real_dev->vlan_rx_kill_vid(real_dev, vlan_id); |
| 246 | } | ||
| 247 | 245 | ||
| 248 | vlan_group_set_device(grp, vlan_id, NULL); | 246 | vlan_group_set_device(grp, vlan_id, NULL); |
| 249 | synchronize_net(); | 247 | synchronize_net(); |
| @@ -409,16 +407,14 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, | |||
| 409 | } | 407 | } |
| 410 | 408 | ||
| 411 | if ((real_dev->features & NETIF_F_HW_VLAN_RX) && | 409 | if ((real_dev->features & NETIF_F_HW_VLAN_RX) && |
| 412 | (real_dev->vlan_rx_register == NULL || | 410 | !real_dev->vlan_rx_register) { |
| 413 | real_dev->vlan_rx_kill_vid == NULL)) { | ||
| 414 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", | 411 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", |
| 415 | __FUNCTION__, real_dev->name); | 412 | __FUNCTION__, real_dev->name); |
| 416 | goto out_put_dev; | 413 | goto out_put_dev; |
| 417 | } | 414 | } |
| 418 | 415 | ||
| 419 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && | 416 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && |
| 420 | (real_dev->vlan_rx_add_vid == NULL || | 417 | (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) { |
| 421 | real_dev->vlan_rx_kill_vid == NULL)) { | ||
| 422 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", | 418 | printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", |
| 423 | __FUNCTION__, real_dev->name); | 419 | __FUNCTION__, real_dev->name); |
| 424 | goto out_put_dev; | 420 | goto out_put_dev; |
| @@ -740,8 +736,7 @@ static int vlan_ioctl_handler(void __user *arg) | |||
| 740 | case SET_VLAN_NAME_TYPE_CMD: | 736 | case SET_VLAN_NAME_TYPE_CMD: |
| 741 | if (!capable(CAP_NET_ADMIN)) | 737 | if (!capable(CAP_NET_ADMIN)) |
| 742 | return -EPERM; | 738 | return -EPERM; |
| 743 | if ((args.u.name_type >= 0) && | 739 | if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) { |
| 744 | (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { | ||
| 745 | vlan_name_type = args.u.name_type; | 740 | vlan_name_type = args.u.name_type; |
| 746 | err = 0; | 741 | err = 0; |
| 747 | } else { | 742 | } else { |
diff --git a/net/Kconfig b/net/Kconfig index caeacd16656a..f3de72978ab6 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -218,6 +218,7 @@ config FIB_RULES | |||
| 218 | bool | 218 | bool |
| 219 | 219 | ||
| 220 | menu "Wireless" | 220 | menu "Wireless" |
| 221 | depends on !S390 | ||
| 221 | 222 | ||
| 222 | source "net/wireless/Kconfig" | 223 | source "net/wireless/Kconfig" |
| 223 | source "net/mac80211/Kconfig" | 224 | source "net/mac80211/Kconfig" |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index f6a92a0b7aa6..fbdfb1224ae1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
| @@ -1844,7 +1844,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { | |||
| 1844 | .sendpage = sock_no_sendpage, | 1844 | .sendpage = sock_no_sendpage, |
| 1845 | }; | 1845 | }; |
| 1846 | 1846 | ||
| 1847 | #include <linux/smp_lock.h> | ||
| 1848 | SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK); | 1847 | SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK); |
| 1849 | 1848 | ||
| 1850 | static struct notifier_block ddp_notifier = { | 1849 | static struct notifier_block ddp_notifier = { |
diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig index 43dd86fca4d3..2a72aa96a568 100644 --- a/net/ax25/Kconfig +++ b/net/ax25/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menuconfig HAMRADIO | 5 | menuconfig HAMRADIO |
| 6 | depends on NET | 6 | depends on NET && !S390 |
| 7 | bool "Amateur Radio support" | 7 | bool "Amateur Radio support" |
| 8 | help | 8 | help |
| 9 | If you want to connect your Linux box to an amateur radio, answer Y | 9 | If you want to connect your Linux box to an amateur radio, answer Y |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 6ded95272a53..429e13a6c6ad 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/timer.h> | 24 | #include <linux/timer.h> |
| 25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
| 26 | #include <linux/smp_lock.h> | ||
| 27 | #include <linux/sockios.h> | 26 | #include <linux/sockios.h> |
| 28 | #include <linux/net.h> | 27 | #include <linux/net.h> |
| 29 | #include <net/ax25.h> | 28 | #include <net/ax25.h> |
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 6929490d095a..7725da95a767 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menuconfig BT | 5 | menuconfig BT |
| 6 | depends on NET | 6 | depends on NET && !S390 |
| 7 | tristate "Bluetooth subsystem support" | 7 | tristate "Bluetooth subsystem support" |
| 8 | help | 8 | help |
| 9 | Bluetooth is low-cost, low-power, short-range wireless technology. | 9 | Bluetooth is low-cost, low-power, short-range wireless technology. |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ab2db55982ca..1c8f4a0c5f43 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/wait.h> | 38 | #include <linux/wait.h> |
| 39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
| 40 | #include <linux/smp_lock.h> | ||
| 41 | #include <linux/net.h> | 40 | #include <linux/net.h> |
| 42 | #include <net/sock.h> | 41 | #include <net/sock.h> |
| 43 | 42 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index bfc9a35bad33..1dae3dfc66a9 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
| @@ -665,7 +665,8 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, | |||
| 665 | /* Detach sockets from device */ | 665 | /* Detach sockets from device */ |
| 666 | read_lock(&hci_sk_list.lock); | 666 | read_lock(&hci_sk_list.lock); |
| 667 | sk_for_each(sk, node, &hci_sk_list.head) { | 667 | sk_for_each(sk, node, &hci_sk_list.head) { |
| 668 | lock_sock(sk); | 668 | local_bh_disable(); |
| 669 | bh_lock_sock_nested(sk); | ||
| 669 | if (hci_pi(sk)->hdev == hdev) { | 670 | if (hci_pi(sk)->hdev == hdev) { |
| 670 | hci_pi(sk)->hdev = NULL; | 671 | hci_pi(sk)->hdev = NULL; |
| 671 | sk->sk_err = EPIPE; | 672 | sk->sk_err = EPIPE; |
| @@ -674,7 +675,8 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, | |||
| 674 | 675 | ||
| 675 | hci_dev_put(hdev); | 676 | hci_dev_put(hdev); |
| 676 | } | 677 | } |
| 677 | release_sock(sk); | 678 | bh_unlock_sock(sk); |
| 679 | local_bh_enable(); | ||
| 678 | } | 680 | } |
| 679 | read_unlock(&hci_sk_list.lock); | 681 | read_unlock(&hci_sk_list.lock); |
| 680 | } | 682 | } |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index d342e89b8bdd..ceadfcf457c1 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -174,7 +174,7 @@ static inline int hidp_queue_event(struct hidp_session *session, struct input_de | |||
| 174 | 174 | ||
| 175 | static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 175 | static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
| 176 | { | 176 | { |
| 177 | struct hid_device *hid = dev->private; | 177 | struct hid_device *hid = input_get_drvdata(dev); |
| 178 | struct hidp_session *session = hid->driver_data; | 178 | struct hidp_session *session = hid->driver_data; |
| 179 | 179 | ||
| 180 | return hidp_queue_event(session, dev, type, code, value); | 180 | return hidp_queue_event(session, dev, type, code, value); |
| @@ -182,7 +182,7 @@ static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigne | |||
| 182 | 182 | ||
| 183 | static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 183 | static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
| 184 | { | 184 | { |
| 185 | struct hidp_session *session = dev->private; | 185 | struct hidp_session *session = input_get_drvdata(dev); |
| 186 | 186 | ||
| 187 | return hidp_queue_event(session, dev, type, code, value); | 187 | return hidp_queue_event(session, dev, type, code, value); |
| 188 | } | 188 | } |
| @@ -630,7 +630,7 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co | |||
| 630 | struct input_dev *input = session->input; | 630 | struct input_dev *input = session->input; |
| 631 | int i; | 631 | int i; |
| 632 | 632 | ||
| 633 | input->private = session; | 633 | input_set_drvdata(input, session); |
| 634 | 634 | ||
| 635 | input->name = "Bluetooth HID Boot Protocol Device"; | 635 | input->name = "Bluetooth HID Boot Protocol Device"; |
| 636 | 636 | ||
| @@ -663,7 +663,7 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co | |||
| 663 | input->relbit[0] |= BIT(REL_WHEEL); | 663 | input->relbit[0] |= BIT(REL_WHEEL); |
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | input->cdev.dev = hidp_get_device(session); | 666 | input->dev.parent = hidp_get_device(session); |
| 667 | 667 | ||
| 668 | input->event = hidp_input_event; | 668 | input->event = hidp_input_event; |
| 669 | 669 | ||
| @@ -737,10 +737,8 @@ static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_conn | |||
| 737 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | 737 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) |
| 738 | hidp_send_report(session, report); | 738 | hidp_send_report(session, report); |
| 739 | 739 | ||
| 740 | if (hidinput_connect(hid) == 0) { | 740 | if (hidinput_connect(hid) == 0) |
| 741 | hid->claimed |= HID_CLAIMED_INPUT; | 741 | hid->claimed |= HID_CLAIMED_INPUT; |
| 742 | hid_ff_init(hid); | ||
| 743 | } | ||
| 744 | } | 742 | } |
| 745 | 743 | ||
| 746 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) | 744 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) |
| @@ -864,7 +862,7 @@ failed: | |||
| 864 | if (session->hid) | 862 | if (session->hid) |
| 865 | hid_free_device(session->hid); | 863 | hid_free_device(session->hid); |
| 866 | 864 | ||
| 867 | kfree(session->input); | 865 | input_free_device(session->input); |
| 868 | kfree(session); | 866 | kfree(session); |
| 869 | return err; | 867 | return err; |
| 870 | } | 868 | } |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index a59b1fb63b76..670ff95ca64b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -507,6 +507,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | /* Default config options */ | 509 | /* Default config options */ |
| 510 | pi->conf_len = 0; | ||
| 510 | pi->conf_mtu = L2CAP_DEFAULT_MTU; | 511 | pi->conf_mtu = L2CAP_DEFAULT_MTU; |
| 511 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 512 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
| 512 | } | 513 | } |
| @@ -1271,42 +1272,6 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned | |||
| 1271 | return len; | 1272 | return len; |
| 1272 | } | 1273 | } |
| 1273 | 1274 | ||
| 1274 | static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len) | ||
| 1275 | { | ||
| 1276 | int type, hint, olen; | ||
| 1277 | unsigned long val; | ||
| 1278 | void *ptr = data; | ||
| 1279 | |||
| 1280 | BT_DBG("sk %p len %d", sk, len); | ||
| 1281 | |||
| 1282 | while (len >= L2CAP_CONF_OPT_SIZE) { | ||
| 1283 | len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val); | ||
| 1284 | |||
| 1285 | hint = type & 0x80; | ||
| 1286 | type &= 0x7f; | ||
| 1287 | |||
| 1288 | switch (type) { | ||
| 1289 | case L2CAP_CONF_MTU: | ||
| 1290 | l2cap_pi(sk)->conf_mtu = val; | ||
| 1291 | break; | ||
| 1292 | |||
| 1293 | case L2CAP_CONF_FLUSH_TO: | ||
| 1294 | l2cap_pi(sk)->flush_to = val; | ||
| 1295 | break; | ||
| 1296 | |||
| 1297 | case L2CAP_CONF_QOS: | ||
| 1298 | break; | ||
| 1299 | |||
| 1300 | default: | ||
| 1301 | if (hint) | ||
| 1302 | break; | ||
| 1303 | |||
| 1304 | /* FIXME: Reject unknown option */ | ||
| 1305 | break; | ||
| 1306 | } | ||
| 1307 | } | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | 1275 | static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) |
| 1311 | { | 1276 | { |
| 1312 | struct l2cap_conf_opt *opt = *ptr; | 1277 | struct l2cap_conf_opt *opt = *ptr; |
| @@ -1358,39 +1323,75 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
| 1358 | return ptr - data; | 1323 | return ptr - data; |
| 1359 | } | 1324 | } |
| 1360 | 1325 | ||
| 1361 | static inline int l2cap_conf_output(struct sock *sk, void **ptr) | 1326 | static int l2cap_parse_conf_req(struct sock *sk, void *data) |
| 1362 | { | 1327 | { |
| 1363 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1328 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
| 1364 | int result = 0; | 1329 | struct l2cap_conf_rsp *rsp = data; |
| 1330 | void *ptr = rsp->data; | ||
| 1331 | void *req = pi->conf_req; | ||
| 1332 | int len = pi->conf_len; | ||
| 1333 | int type, hint, olen; | ||
| 1334 | unsigned long val; | ||
| 1335 | u16 result = L2CAP_CONF_SUCCESS; | ||
| 1365 | 1336 | ||
| 1366 | /* Configure output options and let the other side know | 1337 | BT_DBG("sk %p", sk); |
| 1367 | * which ones we don't like. */ | 1338 | |
| 1368 | if (pi->conf_mtu < pi->omtu) | 1339 | while (len >= L2CAP_CONF_OPT_SIZE) { |
| 1369 | result = L2CAP_CONF_UNACCEPT; | 1340 | len -= l2cap_get_conf_opt(&req, &type, &olen, &val); |
| 1370 | else | ||
| 1371 | pi->omtu = pi->conf_mtu; | ||
| 1372 | 1341 | ||
| 1373 | l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); | 1342 | hint = type & 0x80; |
| 1343 | type &= 0x7f; | ||
| 1344 | |||
| 1345 | switch (type) { | ||
| 1346 | case L2CAP_CONF_MTU: | ||
| 1347 | pi->conf_mtu = val; | ||
| 1348 | break; | ||
| 1349 | |||
| 1350 | case L2CAP_CONF_FLUSH_TO: | ||
| 1351 | pi->flush_to = val; | ||
| 1352 | break; | ||
| 1353 | |||
| 1354 | case L2CAP_CONF_QOS: | ||
| 1355 | break; | ||
| 1356 | |||
| 1357 | default: | ||
| 1358 | if (hint) | ||
| 1359 | break; | ||
| 1360 | |||
| 1361 | result = L2CAP_CONF_UNKNOWN; | ||
| 1362 | *((u8 *) ptr++) = type; | ||
| 1363 | break; | ||
| 1364 | } | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | if (result == L2CAP_CONF_SUCCESS) { | ||
| 1368 | /* Configure output options and let the other side know | ||
| 1369 | * which ones we don't like. */ | ||
| 1370 | |||
| 1371 | if (pi->conf_mtu < pi->omtu) | ||
| 1372 | result = L2CAP_CONF_UNACCEPT; | ||
| 1373 | else | ||
| 1374 | pi->omtu = pi->conf_mtu; | ||
| 1375 | |||
| 1376 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); | ||
| 1377 | } | ||
| 1374 | 1378 | ||
| 1375 | BT_DBG("sk %p result %d", sk, result); | 1379 | rsp->scid = cpu_to_le16(pi->dcid); |
| 1376 | return result; | 1380 | rsp->result = cpu_to_le16(result); |
| 1381 | rsp->flags = cpu_to_le16(0x0000); | ||
| 1382 | |||
| 1383 | return ptr - data; | ||
| 1377 | } | 1384 | } |
| 1378 | 1385 | ||
| 1379 | static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result) | 1386 | static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags) |
| 1380 | { | 1387 | { |
| 1381 | struct l2cap_conf_rsp *rsp = data; | 1388 | struct l2cap_conf_rsp *rsp = data; |
| 1382 | void *ptr = rsp->data; | 1389 | void *ptr = rsp->data; |
| 1383 | u16 flags = 0; | ||
| 1384 | |||
| 1385 | BT_DBG("sk %p complete %d", sk, result ? 1 : 0); | ||
| 1386 | 1390 | ||
| 1387 | if (result) | 1391 | BT_DBG("sk %p", sk); |
| 1388 | *result = l2cap_conf_output(sk, &ptr); | ||
| 1389 | else | ||
| 1390 | flags = 0x0001; | ||
| 1391 | 1392 | ||
| 1392 | rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1393 | rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
| 1393 | rsp->result = cpu_to_le16(result ? *result : 0); | 1394 | rsp->result = cpu_to_le16(result); |
| 1394 | rsp->flags = cpu_to_le16(flags); | 1395 | rsp->flags = cpu_to_le16(flags); |
| 1395 | 1396 | ||
| 1396 | return ptr - data; | 1397 | return ptr - data; |
| @@ -1535,7 +1536,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
| 1535 | u16 dcid, flags; | 1536 | u16 dcid, flags; |
| 1536 | u8 rsp[64]; | 1537 | u8 rsp[64]; |
| 1537 | struct sock *sk; | 1538 | struct sock *sk; |
| 1538 | int result; | 1539 | int len; |
| 1539 | 1540 | ||
| 1540 | dcid = __le16_to_cpu(req->dcid); | 1541 | dcid = __le16_to_cpu(req->dcid); |
| 1541 | flags = __le16_to_cpu(req->flags); | 1542 | flags = __le16_to_cpu(req->flags); |
| @@ -1548,25 +1549,40 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
| 1548 | if (sk->sk_state == BT_DISCONN) | 1549 | if (sk->sk_state == BT_DISCONN) |
| 1549 | goto unlock; | 1550 | goto unlock; |
| 1550 | 1551 | ||
| 1551 | l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); | 1552 | /* Reject if config buffer is too small. */ |
| 1553 | len = cmd->len - sizeof(*req); | ||
| 1554 | if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { | ||
| 1555 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | ||
| 1556 | l2cap_build_conf_rsp(sk, rsp, | ||
| 1557 | L2CAP_CONF_REJECT, flags), rsp); | ||
| 1558 | goto unlock; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | /* Store config. */ | ||
| 1562 | memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len); | ||
| 1563 | l2cap_pi(sk)->conf_len += len; | ||
| 1552 | 1564 | ||
| 1553 | if (flags & 0x0001) { | 1565 | if (flags & 0x0001) { |
| 1554 | /* Incomplete config. Send empty response. */ | 1566 | /* Incomplete config. Send empty response. */ |
| 1555 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 1567 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
| 1556 | l2cap_build_conf_rsp(sk, rsp, NULL), rsp); | 1568 | l2cap_build_conf_rsp(sk, rsp, |
| 1569 | L2CAP_CONF_SUCCESS, 0x0001), rsp); | ||
| 1557 | goto unlock; | 1570 | goto unlock; |
| 1558 | } | 1571 | } |
| 1559 | 1572 | ||
| 1560 | /* Complete config. */ | 1573 | /* Complete config. */ |
| 1561 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 1574 | len = l2cap_parse_conf_req(sk, rsp); |
| 1562 | l2cap_build_conf_rsp(sk, rsp, &result), rsp); | 1575 | if (len < 0) |
| 1563 | |||
| 1564 | if (result) | ||
| 1565 | goto unlock; | 1576 | goto unlock; |
| 1566 | 1577 | ||
| 1567 | /* Output config done */ | 1578 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); |
| 1579 | |||
| 1580 | /* Output config done. */ | ||
| 1568 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 1581 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
| 1569 | 1582 | ||
| 1583 | /* Reset config buffer. */ | ||
| 1584 | l2cap_pi(sk)->conf_len = 0; | ||
| 1585 | |||
| 1570 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { | 1586 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { |
| 1571 | sk->sk_state = BT_CONNECTED; | 1587 | sk->sk_state = BT_CONNECTED; |
| 1572 | l2cap_chan_ready(sk); | 1588 | l2cap_chan_ready(sk); |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 91b017016d5b..3fc697293819 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -121,6 +121,7 @@ void br_fdb_cleanup(unsigned long _data) | |||
| 121 | { | 121 | { |
| 122 | struct net_bridge *br = (struct net_bridge *)_data; | 122 | struct net_bridge *br = (struct net_bridge *)_data; |
| 123 | unsigned long delay = hold_time(br); | 123 | unsigned long delay = hold_time(br); |
| 124 | unsigned long next_timer = jiffies + br->forward_delay; | ||
| 124 | int i; | 125 | int i; |
| 125 | 126 | ||
| 126 | spin_lock_bh(&br->hash_lock); | 127 | spin_lock_bh(&br->hash_lock); |
| @@ -129,14 +130,21 @@ void br_fdb_cleanup(unsigned long _data) | |||
| 129 | struct hlist_node *h, *n; | 130 | struct hlist_node *h, *n; |
| 130 | 131 | ||
| 131 | hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) { | 132 | hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) { |
| 132 | if (!f->is_static && | 133 | unsigned long this_timer; |
| 133 | time_before_eq(f->ageing_timer + delay, jiffies)) | 134 | if (f->is_static) |
| 135 | continue; | ||
| 136 | this_timer = f->ageing_timer + delay; | ||
| 137 | if (time_before_eq(this_timer, jiffies)) | ||
| 134 | fdb_delete(f); | 138 | fdb_delete(f); |
| 139 | else if (this_timer < next_timer) | ||
| 140 | next_timer = this_timer; | ||
| 135 | } | 141 | } |
| 136 | } | 142 | } |
| 137 | spin_unlock_bh(&br->hash_lock); | 143 | spin_unlock_bh(&br->hash_lock); |
| 138 | 144 | ||
| 139 | mod_timer(&br->gc_timer, jiffies + HZ/10); | 145 | /* Add HZ/4 to ensure we round the jiffies upwards to be after the next |
| 146 | * timer, otherwise we might round down and will have no-op run. */ | ||
| 147 | mod_timer(&br->gc_timer, round_jiffies(next_timer + HZ/4)); | ||
| 140 | } | 148 | } |
| 141 | 149 | ||
| 142 | /* Completely flush all dynamic entries in forwarding database.*/ | 150 | /* Completely flush all dynamic entries in forwarding database.*/ |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index ebb0861e9bd5..e38034aa56f5 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
| 14 | */ | 14 | */ |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <linux/smp_lock.h> | ||
| 17 | 16 | ||
| 18 | #include "br_private.h" | 17 | #include "br_private.h" |
| 19 | #include "br_private_stp.h" | 18 | #include "br_private_stp.h" |
| @@ -179,7 +178,8 @@ void br_transmit_config(struct net_bridge_port *p) | |||
| 179 | br_send_config_bpdu(p, &bpdu); | 178 | br_send_config_bpdu(p, &bpdu); |
| 180 | p->topology_change_ack = 0; | 179 | p->topology_change_ack = 0; |
| 181 | p->config_pending = 0; | 180 | p->config_pending = 0; |
| 182 | mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME); | 181 | mod_timer(&p->hold_timer, |
| 182 | round_jiffies(jiffies + BR_HOLD_TIME)); | ||
| 183 | } | 183 | } |
| 184 | } | 184 | } |
| 185 | 185 | ||
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 3e246b37020e..a786e7863200 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/smp_lock.h> | ||
| 18 | #include <linux/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
| 19 | #include <linux/rtnetlink.h> | 18 | #include <linux/rtnetlink.h> |
| 20 | 19 | ||
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c index 030aa798fea7..77f5255e6915 100644 --- a/net/bridge/br_stp_timer.c +++ b/net/bridge/br_stp_timer.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/times.h> | 17 | #include <linux/times.h> |
| 18 | #include <linux/smp_lock.h> | ||
| 19 | 18 | ||
| 20 | #include "br_private.h" | 19 | #include "br_private.h" |
| 21 | #include "br_private_stp.h" | 20 | #include "br_private_stp.h" |
| @@ -43,7 +42,7 @@ static void br_hello_timer_expired(unsigned long arg) | |||
| 43 | if (br->dev->flags & IFF_UP) { | 42 | if (br->dev->flags & IFF_UP) { |
| 44 | br_config_bpdu_generation(br); | 43 | br_config_bpdu_generation(br); |
| 45 | 44 | ||
| 46 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | 45 | mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time)); |
| 47 | } | 46 | } |
| 48 | spin_unlock(&br->lock); | 47 | spin_unlock(&br->lock); |
| 49 | } | 48 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 4317c1be4d3f..26090621ea6b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -116,6 +116,7 @@ | |||
| 116 | #include <linux/dmaengine.h> | 116 | #include <linux/dmaengine.h> |
| 117 | #include <linux/err.h> | 117 | #include <linux/err.h> |
| 118 | #include <linux/ctype.h> | 118 | #include <linux/ctype.h> |
| 119 | #include <linux/if_arp.h> | ||
| 119 | 120 | ||
| 120 | /* | 121 | /* |
| 121 | * The list of packet types we will receive (as opposed to discard) | 122 | * The list of packet types we will receive (as opposed to discard) |
| @@ -217,6 +218,73 @@ extern void netdev_unregister_sysfs(struct net_device *); | |||
| 217 | #define netdev_unregister_sysfs(dev) do { } while(0) | 218 | #define netdev_unregister_sysfs(dev) do { } while(0) |
| 218 | #endif | 219 | #endif |
| 219 | 220 | ||
| 221 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 222 | /* | ||
| 223 | * register_netdevice() inits dev->_xmit_lock and sets lockdep class | ||
| 224 | * according to dev->type | ||
| 225 | */ | ||
| 226 | static const unsigned short netdev_lock_type[] = | ||
| 227 | {ARPHRD_NETROM, ARPHRD_ETHER, ARPHRD_EETHER, ARPHRD_AX25, | ||
| 228 | ARPHRD_PRONET, ARPHRD_CHAOS, ARPHRD_IEEE802, ARPHRD_ARCNET, | ||
| 229 | ARPHRD_APPLETLK, ARPHRD_DLCI, ARPHRD_ATM, ARPHRD_METRICOM, | ||
| 230 | ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP, | ||
| 231 | ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD, | ||
| 232 | ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25, | ||
| 233 | ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_LAPB, ARPHRD_DDCMP, | ||
| 234 | ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD, | ||
| 235 | ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI, | ||
| 236 | ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, | ||
| 237 | ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, | ||
| 238 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, | ||
| 239 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, | ||
| 240 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_VOID, | ||
| 241 | ARPHRD_NONE}; | ||
| 242 | |||
| 243 | static const char *netdev_lock_name[] = | ||
| 244 | {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", | ||
| 245 | "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET", | ||
| 246 | "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM", | ||
| 247 | "_xmit_IEEE1394", "_xmit_EUI64", "_xmit_INFINIBAND", "_xmit_SLIP", | ||
| 248 | "_xmit_CSLIP", "_xmit_SLIP6", "_xmit_CSLIP6", "_xmit_RSRVD", | ||
| 249 | "_xmit_ADAPT", "_xmit_ROSE", "_xmit_X25", "_xmit_HWX25", | ||
| 250 | "_xmit_PPP", "_xmit_CISCO", "_xmit_LAPB", "_xmit_DDCMP", | ||
| 251 | "_xmit_RAWHDLC", "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD", | ||
| 252 | "_xmit_SKIP", "_xmit_LOOPBACK", "_xmit_LOCALTLK", "_xmit_FDDI", | ||
| 253 | "_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE", | ||
| 254 | "_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET", | ||
| 255 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", | ||
| 256 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", | ||
| 257 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_VOID", | ||
| 258 | "_xmit_NONE"}; | ||
| 259 | |||
| 260 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; | ||
| 261 | |||
| 262 | static inline unsigned short netdev_lock_pos(unsigned short dev_type) | ||
| 263 | { | ||
| 264 | int i; | ||
| 265 | |||
| 266 | for (i = 0; i < ARRAY_SIZE(netdev_lock_type); i++) | ||
| 267 | if (netdev_lock_type[i] == dev_type) | ||
| 268 | return i; | ||
| 269 | /* the last key is used by default */ | ||
| 270 | return ARRAY_SIZE(netdev_lock_type) - 1; | ||
| 271 | } | ||
| 272 | |||
| 273 | static inline void netdev_set_lockdep_class(spinlock_t *lock, | ||
| 274 | unsigned short dev_type) | ||
| 275 | { | ||
| 276 | int i; | ||
| 277 | |||
| 278 | i = netdev_lock_pos(dev_type); | ||
| 279 | lockdep_set_class_and_name(lock, &netdev_xmit_lock_key[i], | ||
| 280 | netdev_lock_name[i]); | ||
| 281 | } | ||
| 282 | #else | ||
| 283 | static inline void netdev_set_lockdep_class(spinlock_t *lock, | ||
| 284 | unsigned short dev_type) | ||
| 285 | { | ||
| 286 | } | ||
| 287 | #endif | ||
| 220 | 288 | ||
| 221 | /******************************************************************************* | 289 | /******************************************************************************* |
| 222 | 290 | ||
| @@ -2509,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev) | |||
| 2509 | 2577 | ||
| 2510 | int dev_change_flags(struct net_device *dev, unsigned flags) | 2578 | int dev_change_flags(struct net_device *dev, unsigned flags) |
| 2511 | { | 2579 | { |
| 2512 | int ret; | 2580 | int ret, changes; |
| 2513 | int old_flags = dev->flags; | 2581 | int old_flags = dev->flags; |
| 2514 | 2582 | ||
| 2515 | /* | 2583 | /* |
| @@ -2564,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
| 2564 | dev_set_allmulti(dev, inc); | 2632 | dev_set_allmulti(dev, inc); |
| 2565 | } | 2633 | } |
| 2566 | 2634 | ||
| 2567 | if (old_flags ^ dev->flags) | 2635 | /* Exclude state transition flags, already notified */ |
| 2568 | rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags); | 2636 | changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING); |
| 2637 | if (changes) | ||
| 2638 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); | ||
| 2569 | 2639 | ||
| 2570 | return ret; | 2640 | return ret; |
| 2571 | } | 2641 | } |
| @@ -3001,6 +3071,7 @@ int register_netdevice(struct net_device *dev) | |||
| 3001 | 3071 | ||
| 3002 | spin_lock_init(&dev->queue_lock); | 3072 | spin_lock_init(&dev->queue_lock); |
| 3003 | spin_lock_init(&dev->_xmit_lock); | 3073 | spin_lock_init(&dev->_xmit_lock); |
| 3074 | netdev_set_lockdep_class(&dev->_xmit_lock, dev->type); | ||
| 3004 | dev->xmit_lock_owner = -1; | 3075 | dev->xmit_lock_owner = -1; |
| 3005 | spin_lock_init(&dev->ingress_lock); | 3076 | spin_lock_init(&dev->ingress_lock); |
| 3006 | 3077 | ||
| @@ -3245,7 +3316,6 @@ void netdev_run_todo(void) | |||
| 3245 | continue; | 3316 | continue; |
| 3246 | } | 3317 | } |
| 3247 | 3318 | ||
| 3248 | netdev_unregister_sysfs(dev); | ||
| 3249 | dev->reg_state = NETREG_UNREGISTERED; | 3319 | dev->reg_state = NETREG_UNREGISTERED; |
| 3250 | 3320 | ||
| 3251 | netdev_wait_allrefs(dev); | 3321 | netdev_wait_allrefs(dev); |
| @@ -3256,11 +3326,11 @@ void netdev_run_todo(void) | |||
| 3256 | BUG_TRAP(!dev->ip6_ptr); | 3326 | BUG_TRAP(!dev->ip6_ptr); |
| 3257 | BUG_TRAP(!dev->dn_ptr); | 3327 | BUG_TRAP(!dev->dn_ptr); |
| 3258 | 3328 | ||
| 3259 | /* It must be the very last action, | ||
| 3260 | * after this 'dev' may point to freed up memory. | ||
| 3261 | */ | ||
| 3262 | if (dev->destructor) | 3329 | if (dev->destructor) |
| 3263 | dev->destructor(dev); | 3330 | dev->destructor(dev); |
| 3331 | |||
| 3332 | /* Free network device */ | ||
| 3333 | kobject_put(&dev->dev.kobj); | ||
| 3264 | } | 3334 | } |
| 3265 | 3335 | ||
| 3266 | out: | 3336 | out: |
| @@ -3411,6 +3481,9 @@ void unregister_netdevice(struct net_device *dev) | |||
| 3411 | /* Notifier chain MUST detach us from master device. */ | 3481 | /* Notifier chain MUST detach us from master device. */ |
| 3412 | BUG_TRAP(!dev->master); | 3482 | BUG_TRAP(!dev->master); |
| 3413 | 3483 | ||
| 3484 | /* Remove entries from sysfs */ | ||
| 3485 | netdev_unregister_sysfs(dev); | ||
| 3486 | |||
| 3414 | /* Finish processing unregister after unlock */ | 3487 | /* Finish processing unregister after unlock */ |
| 3415 | net_set_todo(dev); | 3488 | net_set_todo(dev); |
| 3416 | 3489 | ||
| @@ -3450,7 +3523,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
| 3450 | unsigned int cpu, oldcpu = (unsigned long)ocpu; | 3523 | unsigned int cpu, oldcpu = (unsigned long)ocpu; |
| 3451 | struct softnet_data *sd, *oldsd; | 3524 | struct softnet_data *sd, *oldsd; |
| 3452 | 3525 | ||
| 3453 | if (action != CPU_DEAD) | 3526 | if (action != CPU_DEAD && action != CPU_DEAD_FROZEN) |
| 3454 | return NOTIFY_OK; | 3527 | return NOTIFY_OK; |
| 3455 | 3528 | ||
| 3456 | local_irq_disable(); | 3529 | local_irq_disable(); |
diff --git a/net/core/dst.c b/net/core/dst.c index 764bccb3d992..c6a05879d58c 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
| @@ -111,13 +111,7 @@ out: | |||
| 111 | spin_unlock(&dst_lock); | 111 | spin_unlock(&dst_lock); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static int dst_discard_in(struct sk_buff *skb) | 114 | static int dst_discard(struct sk_buff *skb) |
| 115 | { | ||
| 116 | kfree_skb(skb); | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int dst_discard_out(struct sk_buff *skb) | ||
| 121 | { | 115 | { |
| 122 | kfree_skb(skb); | 116 | kfree_skb(skb); |
| 123 | return 0; | 117 | return 0; |
| @@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops) | |||
| 138 | dst->ops = ops; | 132 | dst->ops = ops; |
| 139 | dst->lastuse = jiffies; | 133 | dst->lastuse = jiffies; |
| 140 | dst->path = dst; | 134 | dst->path = dst; |
| 141 | dst->input = dst_discard_in; | 135 | dst->input = dst->output = dst_discard; |
| 142 | dst->output = dst_discard_out; | ||
| 143 | #if RT_CACHE_DEBUG >= 2 | 136 | #if RT_CACHE_DEBUG >= 2 |
| 144 | atomic_inc(&dst_total); | 137 | atomic_inc(&dst_total); |
| 145 | #endif | 138 | #endif |
| @@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst) | |||
| 153 | protocol module is unloaded. | 146 | protocol module is unloaded. |
| 154 | */ | 147 | */ |
| 155 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { | 148 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
| 156 | dst->input = dst_discard_in; | 149 | dst->input = dst->output = dst_discard; |
| 157 | dst->output = dst_discard_out; | ||
| 158 | } | 150 | } |
| 159 | dst->obsolete = 2; | 151 | dst->obsolete = 2; |
| 160 | } | 152 | } |
| @@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
| 242 | return; | 234 | return; |
| 243 | 235 | ||
| 244 | if (!unregister) { | 236 | if (!unregister) { |
| 245 | dst->input = dst_discard_in; | 237 | dst->input = dst->output = dst_discard; |
| 246 | dst->output = dst_discard_out; | ||
| 247 | } else { | 238 | } else { |
| 248 | dst->dev = &loopback_dev; | 239 | dst->dev = &loopback_dev; |
| 249 | dev_hold(&loopback_dev); | 240 | dev_hold(&loopback_dev); |
diff --git a/net/core/flow.c b/net/core/flow.c index 5d25697920b1..051430545a05 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
| @@ -338,7 +338,7 @@ static int flow_cache_cpu(struct notifier_block *nfb, | |||
| 338 | unsigned long action, | 338 | unsigned long action, |
| 339 | void *hcpu) | 339 | void *hcpu) |
| 340 | { | 340 | { |
| 341 | if (action == CPU_DEAD) | 341 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) |
| 342 | __flow_cache_shrink((unsigned long)hcpu, 0); | 342 | __flow_cache_shrink((unsigned long)hcpu, 0); |
| 343 | return NOTIFY_OK; | 343 | return NOTIFY_OK; |
| 344 | } | 344 | } |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index e3c26a9ccad6..a5e372b9ec4d 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/rtnetlink.h> | 19 | #include <linux/rtnetlink.h> |
| 20 | #include <linux/jiffies.h> | 20 | #include <linux/jiffies.h> |
| 21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 22 | #include <linux/list.h> | ||
| 23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 24 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
| 25 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
| @@ -27,8 +26,7 @@ | |||
| 27 | 26 | ||
| 28 | 27 | ||
| 29 | enum lw_bits { | 28 | enum lw_bits { |
| 30 | LW_RUNNING = 0, | 29 | LW_URGENT = 0, |
| 31 | LW_SE_USED | ||
| 32 | }; | 30 | }; |
| 33 | 31 | ||
| 34 | static unsigned long linkwatch_flags; | 32 | static unsigned long linkwatch_flags; |
| @@ -37,17 +35,9 @@ static unsigned long linkwatch_nextevent; | |||
| 37 | static void linkwatch_event(struct work_struct *dummy); | 35 | static void linkwatch_event(struct work_struct *dummy); |
| 38 | static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event); | 36 | static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event); |
| 39 | 37 | ||
| 40 | static LIST_HEAD(lweventlist); | 38 | static struct net_device *lweventlist; |
| 41 | static DEFINE_SPINLOCK(lweventlist_lock); | 39 | static DEFINE_SPINLOCK(lweventlist_lock); |
| 42 | 40 | ||
| 43 | struct lw_event { | ||
| 44 | struct list_head list; | ||
| 45 | struct net_device *dev; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* Avoid kmalloc() for most systems */ | ||
| 49 | static struct lw_event singleevent; | ||
| 50 | |||
| 51 | static unsigned char default_operstate(const struct net_device *dev) | 41 | static unsigned char default_operstate(const struct net_device *dev) |
| 52 | { | 42 | { |
| 53 | if (!netif_carrier_ok(dev)) | 43 | if (!netif_carrier_ok(dev)) |
| @@ -87,25 +77,102 @@ static void rfc2863_policy(struct net_device *dev) | |||
| 87 | } | 77 | } |
| 88 | 78 | ||
| 89 | 79 | ||
| 90 | /* Must be called with the rtnl semaphore held */ | 80 | static int linkwatch_urgent_event(struct net_device *dev) |
| 91 | void linkwatch_run_queue(void) | ||
| 92 | { | 81 | { |
| 93 | struct list_head head, *n, *next; | 82 | return netif_running(dev) && netif_carrier_ok(dev) && |
| 83 | dev->qdisc != dev->qdisc_sleeping; | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | static void linkwatch_add_event(struct net_device *dev) | ||
| 88 | { | ||
| 89 | unsigned long flags; | ||
| 90 | |||
| 91 | spin_lock_irqsave(&lweventlist_lock, flags); | ||
| 92 | dev->link_watch_next = lweventlist; | ||
| 93 | lweventlist = dev; | ||
| 94 | spin_unlock_irqrestore(&lweventlist_lock, flags); | ||
| 95 | } | ||
| 96 | |||
| 97 | |||
| 98 | static void linkwatch_schedule_work(int urgent) | ||
| 99 | { | ||
| 100 | unsigned long delay = linkwatch_nextevent - jiffies; | ||
| 101 | |||
| 102 | if (test_bit(LW_URGENT, &linkwatch_flags)) | ||
| 103 | return; | ||
| 104 | |||
| 105 | /* Minimise down-time: drop delay for up event. */ | ||
| 106 | if (urgent) { | ||
| 107 | if (test_and_set_bit(LW_URGENT, &linkwatch_flags)) | ||
| 108 | return; | ||
| 109 | delay = 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | /* If we wrap around we'll delay it by at most HZ. */ | ||
| 113 | if (delay > HZ) | ||
| 114 | delay = 0; | ||
| 115 | |||
| 116 | /* | ||
| 117 | * This is true if we've scheduled it immeditately or if we don't | ||
| 118 | * need an immediate execution and it's already pending. | ||
| 119 | */ | ||
| 120 | if (schedule_delayed_work(&linkwatch_work, delay) == !delay) | ||
| 121 | return; | ||
| 122 | |||
| 123 | /* Don't bother if there is nothing urgent. */ | ||
| 124 | if (!test_bit(LW_URGENT, &linkwatch_flags)) | ||
| 125 | return; | ||
| 126 | |||
| 127 | /* It's already running which is good enough. */ | ||
| 128 | if (!cancel_delayed_work(&linkwatch_work)) | ||
| 129 | return; | ||
| 130 | |||
| 131 | /* Otherwise we reschedule it again for immediate exection. */ | ||
| 132 | schedule_delayed_work(&linkwatch_work, 0); | ||
| 133 | } | ||
| 134 | |||
| 135 | |||
| 136 | static void __linkwatch_run_queue(int urgent_only) | ||
| 137 | { | ||
| 138 | struct net_device *next; | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Limit the number of linkwatch events to one | ||
| 142 | * per second so that a runaway driver does not | ||
| 143 | * cause a storm of messages on the netlink | ||
| 144 | * socket. This limit does not apply to up events | ||
| 145 | * while the device qdisc is down. | ||
| 146 | */ | ||
| 147 | if (!urgent_only) | ||
| 148 | linkwatch_nextevent = jiffies + HZ; | ||
| 149 | /* Limit wrap-around effect on delay. */ | ||
| 150 | else if (time_after(linkwatch_nextevent, jiffies + HZ)) | ||
| 151 | linkwatch_nextevent = jiffies; | ||
| 152 | |||
| 153 | clear_bit(LW_URGENT, &linkwatch_flags); | ||
| 94 | 154 | ||
| 95 | spin_lock_irq(&lweventlist_lock); | 155 | spin_lock_irq(&lweventlist_lock); |
| 96 | list_replace_init(&lweventlist, &head); | 156 | next = lweventlist; |
| 157 | lweventlist = NULL; | ||
| 97 | spin_unlock_irq(&lweventlist_lock); | 158 | spin_unlock_irq(&lweventlist_lock); |
| 98 | 159 | ||
| 99 | list_for_each_safe(n, next, &head) { | 160 | while (next) { |
| 100 | struct lw_event *event = list_entry(n, struct lw_event, list); | 161 | struct net_device *dev = next; |
| 101 | struct net_device *dev = event->dev; | ||
| 102 | 162 | ||
| 103 | if (event == &singleevent) { | 163 | next = dev->link_watch_next; |
| 104 | clear_bit(LW_SE_USED, &linkwatch_flags); | 164 | |
| 105 | } else { | 165 | if (urgent_only && !linkwatch_urgent_event(dev)) { |
| 106 | kfree(event); | 166 | linkwatch_add_event(dev); |
| 167 | continue; | ||
| 107 | } | 168 | } |
| 108 | 169 | ||
| 170 | /* | ||
| 171 | * Make sure the above read is complete since it can be | ||
| 172 | * rewritten as soon as we clear the bit below. | ||
| 173 | */ | ||
| 174 | smp_mb__before_clear_bit(); | ||
| 175 | |||
| 109 | /* We are about to handle this device, | 176 | /* We are about to handle this device, |
| 110 | * so new events can be accepted | 177 | * so new events can be accepted |
| 111 | */ | 178 | */ |
| @@ -124,58 +191,39 @@ void linkwatch_run_queue(void) | |||
| 124 | 191 | ||
| 125 | dev_put(dev); | 192 | dev_put(dev); |
| 126 | } | 193 | } |
| 194 | |||
| 195 | if (lweventlist) | ||
| 196 | linkwatch_schedule_work(0); | ||
| 127 | } | 197 | } |
| 128 | 198 | ||
| 129 | 199 | ||
| 130 | static void linkwatch_event(struct work_struct *dummy) | 200 | /* Must be called with the rtnl semaphore held */ |
| 201 | void linkwatch_run_queue(void) | ||
| 131 | { | 202 | { |
| 132 | /* Limit the number of linkwatch events to one | 203 | __linkwatch_run_queue(0); |
| 133 | * per second so that a runaway driver does not | 204 | } |
| 134 | * cause a storm of messages on the netlink | ||
| 135 | * socket | ||
| 136 | */ | ||
| 137 | linkwatch_nextevent = jiffies + HZ; | ||
| 138 | clear_bit(LW_RUNNING, &linkwatch_flags); | ||
| 139 | 205 | ||
| 206 | |||
| 207 | static void linkwatch_event(struct work_struct *dummy) | ||
| 208 | { | ||
| 140 | rtnl_lock(); | 209 | rtnl_lock(); |
| 141 | linkwatch_run_queue(); | 210 | __linkwatch_run_queue(time_after(linkwatch_nextevent, jiffies)); |
| 142 | rtnl_unlock(); | 211 | rtnl_unlock(); |
| 143 | } | 212 | } |
| 144 | 213 | ||
| 145 | 214 | ||
| 146 | void linkwatch_fire_event(struct net_device *dev) | 215 | void linkwatch_fire_event(struct net_device *dev) |
| 147 | { | 216 | { |
| 148 | if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) { | 217 | int urgent = linkwatch_urgent_event(dev); |
| 149 | unsigned long flags; | ||
| 150 | struct lw_event *event; | ||
| 151 | |||
| 152 | if (test_and_set_bit(LW_SE_USED, &linkwatch_flags)) { | ||
| 153 | event = kmalloc(sizeof(struct lw_event), GFP_ATOMIC); | ||
| 154 | |||
| 155 | if (unlikely(event == NULL)) { | ||
| 156 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); | ||
| 157 | return; | ||
| 158 | } | ||
| 159 | } else { | ||
| 160 | event = &singleevent; | ||
| 161 | } | ||
| 162 | 218 | ||
| 219 | if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) { | ||
| 163 | dev_hold(dev); | 220 | dev_hold(dev); |
| 164 | event->dev = dev; | ||
| 165 | |||
| 166 | spin_lock_irqsave(&lweventlist_lock, flags); | ||
| 167 | list_add_tail(&event->list, &lweventlist); | ||
| 168 | spin_unlock_irqrestore(&lweventlist_lock, flags); | ||
| 169 | 221 | ||
| 170 | if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) { | 222 | linkwatch_add_event(dev); |
| 171 | unsigned long delay = linkwatch_nextevent - jiffies; | 223 | } else if (!urgent) |
| 224 | return; | ||
| 172 | 225 | ||
| 173 | /* If we wrap around we'll delay it by at most HZ. */ | 226 | linkwatch_schedule_work(urgent); |
| 174 | if (delay > HZ) | ||
| 175 | delay = 0; | ||
| 176 | schedule_delayed_work(&linkwatch_work, delay); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | 227 | } |
| 180 | 228 | ||
| 181 | EXPORT_SYMBOL(linkwatch_fire_event); | 229 | EXPORT_SYMBOL(linkwatch_fire_event); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 6f3bb73053c2..9df26a07f067 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | |||
| 1761 | return NULL; | 1761 | return NULL; |
| 1762 | } | 1762 | } |
| 1763 | 1763 | ||
| 1764 | static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | 1764 | static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = { |
| 1765 | [NDTA_NAME] = { .type = NLA_STRING }, | 1765 | [NDTA_NAME] = { .type = NLA_STRING }, |
| 1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, | 1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, |
| 1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, | 1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, |
| @@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | |||
| 1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, | 1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, |
| 1771 | }; | 1771 | }; |
| 1772 | 1772 | ||
| 1773 | static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { | 1773 | static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { |
| 1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, | 1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, |
| 1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, | 1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, |
| 1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, | 1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index b21307b15b82..5c19b0646d7a 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -456,9 +456,15 @@ static struct class net_class = { | |||
| 456 | #endif | 456 | #endif |
| 457 | }; | 457 | }; |
| 458 | 458 | ||
| 459 | /* Delete sysfs entries but hold kobject reference until after all | ||
| 460 | * netdev references are gone. | ||
| 461 | */ | ||
| 459 | void netdev_unregister_sysfs(struct net_device * net) | 462 | void netdev_unregister_sysfs(struct net_device * net) |
| 460 | { | 463 | { |
| 461 | device_del(&(net->dev)); | 464 | struct device *dev = &(net->dev); |
| 465 | |||
| 466 | kobject_get(&dev->kobj); | ||
| 467 | device_del(dev); | ||
| 462 | } | 468 | } |
| 463 | 469 | ||
| 464 | /* Create sysfs entries for network device. */ | 470 | /* Create sysfs entries for network device. */ |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index b316435b0e2a..758dafe284c0 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | * Copyright (C) 2002 Red Hat, Inc. | 9 | * Copyright (C) 2002 Red Hat, Inc. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/smp_lock.h> | ||
| 13 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
| 14 | #include <linux/etherdevice.h> | 13 | #include <linux/etherdevice.h> |
| 15 | #include <linux/string.h> | 14 | #include <linux/string.h> |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b92a322872a8..9cd3a1cb60ef 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -117,7 +117,6 @@ | |||
| 117 | #include <linux/module.h> | 117 | #include <linux/module.h> |
| 118 | #include <linux/moduleparam.h> | 118 | #include <linux/moduleparam.h> |
| 119 | #include <linux/kernel.h> | 119 | #include <linux/kernel.h> |
| 120 | #include <linux/smp_lock.h> | ||
| 121 | #include <linux/mutex.h> | 120 | #include <linux/mutex.h> |
| 122 | #include <linux/sched.h> | 121 | #include <linux/sched.h> |
| 123 | #include <linux/slab.h> | 122 | #include <linux/slab.h> |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 8c971a2efe2a..02e8bf084277 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -437,7 +437,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
| 437 | a->tx_compressed = b->tx_compressed; | 437 | a->tx_compressed = b->tx_compressed; |
| 438 | }; | 438 | }; |
| 439 | 439 | ||
| 440 | static inline size_t if_nlmsg_size(int iwbuflen) | 440 | static inline size_t if_nlmsg_size(void) |
| 441 | { | 441 | { |
| 442 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | 442 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
| 443 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | 443 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ |
| @@ -452,13 +452,12 @@ static inline size_t if_nlmsg_size(int iwbuflen) | |||
| 452 | + nla_total_size(4) /* IFLA_LINK */ | 452 | + nla_total_size(4) /* IFLA_LINK */ |
| 453 | + nla_total_size(4) /* IFLA_MASTER */ | 453 | + nla_total_size(4) /* IFLA_MASTER */ |
| 454 | + nla_total_size(1) /* IFLA_OPERSTATE */ | 454 | + nla_total_size(1) /* IFLA_OPERSTATE */ |
| 455 | + nla_total_size(1) /* IFLA_LINKMODE */ | 455 | + nla_total_size(1); /* IFLA_LINKMODE */ |
| 456 | + nla_total_size(iwbuflen); | ||
| 457 | } | 456 | } |
| 458 | 457 | ||
| 459 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 458 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
| 460 | void *iwbuf, int iwbuflen, int type, u32 pid, | 459 | int type, u32 pid, u32 seq, u32 change, |
| 461 | u32 seq, u32 change, unsigned int flags) | 460 | unsigned int flags) |
| 462 | { | 461 | { |
| 463 | struct ifinfomsg *ifm; | 462 | struct ifinfomsg *ifm; |
| 464 | struct nlmsghdr *nlh; | 463 | struct nlmsghdr *nlh; |
| @@ -523,9 +522,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 523 | } | 522 | } |
| 524 | } | 523 | } |
| 525 | 524 | ||
| 526 | if (iwbuf) | ||
| 527 | NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf); | ||
| 528 | |||
| 529 | return nlmsg_end(skb, nlh); | 525 | return nlmsg_end(skb, nlh); |
| 530 | 526 | ||
| 531 | nla_put_failure: | 527 | nla_put_failure: |
| @@ -543,7 +539,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 543 | for_each_netdev(dev) { | 539 | for_each_netdev(dev) { |
| 544 | if (idx < s_idx) | 540 | if (idx < s_idx) |
| 545 | goto cont; | 541 | goto cont; |
| 546 | if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, | 542 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
| 547 | NETLINK_CB(cb->skb).pid, | 543 | NETLINK_CB(cb->skb).pid, |
| 548 | cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) | 544 | cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) |
| 549 | break; | 545 | break; |
| @@ -555,7 +551,7 @@ cont: | |||
| 555 | return skb->len; | 551 | return skb->len; |
| 556 | } | 552 | } |
| 557 | 553 | ||
| 558 | static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { | 554 | static const struct nla_policy ifla_policy[IFLA_MAX+1] = { |
| 559 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, | 555 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, |
| 560 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | 556 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, |
| 561 | [IFLA_MTU] = { .type = NLA_U32 }, | 557 | [IFLA_MTU] = { .type = NLA_U32 }, |
| @@ -584,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 584 | 580 | ||
| 585 | err = -EINVAL; | 581 | err = -EINVAL; |
| 586 | ifm = nlmsg_data(nlh); | 582 | ifm = nlmsg_data(nlh); |
| 587 | if (ifm->ifi_index >= 0) | 583 | if (ifm->ifi_index > 0) |
| 588 | dev = dev_get_by_index(ifm->ifi_index); | 584 | dev = dev_get_by_index(ifm->ifi_index); |
| 589 | else if (tb[IFLA_IFNAME]) | 585 | else if (tb[IFLA_IFNAME]) |
| 590 | dev = dev_get_by_name(ifname); | 586 | dev = dev_get_by_name(ifname); |
| @@ -676,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 676 | * name provided implies that a name change has been | 672 | * name provided implies that a name change has been |
| 677 | * requested. | 673 | * requested. |
| 678 | */ | 674 | */ |
| 679 | if (ifm->ifi_index >= 0 && ifname[0]) { | 675 | if (ifm->ifi_index > 0 && ifname[0]) { |
| 680 | err = dev_change_name(dev, ifname); | 676 | err = dev_change_name(dev, ifname); |
| 681 | if (err < 0) | 677 | if (err < 0) |
| 682 | goto errout_dev; | 678 | goto errout_dev; |
| @@ -689,8 +685,15 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 689 | } | 685 | } |
| 690 | 686 | ||
| 691 | 687 | ||
| 692 | if (ifm->ifi_flags) | 688 | if (ifm->ifi_flags || ifm->ifi_change) { |
| 693 | dev_change_flags(dev, ifm->ifi_flags); | 689 | unsigned int flags = ifm->ifi_flags; |
| 690 | |||
| 691 | /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ | ||
| 692 | if (ifm->ifi_change) | ||
| 693 | flags = (flags & ifm->ifi_change) | | ||
| 694 | (dev->flags & ~ifm->ifi_change); | ||
| 695 | dev_change_flags(dev, flags); | ||
| 696 | } | ||
| 694 | 697 | ||
| 695 | if (tb[IFLA_TXQLEN]) | 698 | if (tb[IFLA_TXQLEN]) |
| 696 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); | 699 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); |
| @@ -730,8 +733,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 730 | struct nlattr *tb[IFLA_MAX+1]; | 733 | struct nlattr *tb[IFLA_MAX+1]; |
| 731 | struct net_device *dev = NULL; | 734 | struct net_device *dev = NULL; |
| 732 | struct sk_buff *nskb; | 735 | struct sk_buff *nskb; |
| 733 | char *iw_buf = NULL, *iw = NULL; | ||
| 734 | int iw_buf_len = 0; | ||
| 735 | int err; | 736 | int err; |
| 736 | 737 | ||
| 737 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 738 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
| @@ -739,21 +740,21 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 739 | return err; | 740 | return err; |
| 740 | 741 | ||
| 741 | ifm = nlmsg_data(nlh); | 742 | ifm = nlmsg_data(nlh); |
| 742 | if (ifm->ifi_index >= 0) { | 743 | if (ifm->ifi_index > 0) { |
| 743 | dev = dev_get_by_index(ifm->ifi_index); | 744 | dev = dev_get_by_index(ifm->ifi_index); |
| 744 | if (dev == NULL) | 745 | if (dev == NULL) |
| 745 | return -ENODEV; | 746 | return -ENODEV; |
| 746 | } else | 747 | } else |
| 747 | return -EINVAL; | 748 | return -EINVAL; |
| 748 | 749 | ||
| 749 | nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL); | 750 | nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); |
| 750 | if (nskb == NULL) { | 751 | if (nskb == NULL) { |
| 751 | err = -ENOBUFS; | 752 | err = -ENOBUFS; |
| 752 | goto errout; | 753 | goto errout; |
| 753 | } | 754 | } |
| 754 | 755 | ||
| 755 | err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, | 756 | err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, |
| 756 | NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); | 757 | nlh->nlmsg_seq, 0, 0); |
| 757 | if (err < 0) { | 758 | if (err < 0) { |
| 758 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ | 759 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ |
| 759 | WARN_ON(err == -EMSGSIZE); | 760 | WARN_ON(err == -EMSGSIZE); |
| @@ -762,7 +763,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 762 | } | 763 | } |
| 763 | err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); | 764 | err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); |
| 764 | errout: | 765 | errout: |
| 765 | kfree(iw_buf); | ||
| 766 | dev_put(dev); | 766 | dev_put(dev); |
| 767 | 767 | ||
| 768 | return err; | 768 | return err; |
| @@ -797,11 +797,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | |||
| 797 | struct sk_buff *skb; | 797 | struct sk_buff *skb; |
| 798 | int err = -ENOBUFS; | 798 | int err = -ENOBUFS; |
| 799 | 799 | ||
| 800 | skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL); | 800 | skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); |
| 801 | if (skb == NULL) | 801 | if (skb == NULL) |
| 802 | goto errout; | 802 | goto errout; |
| 803 | 803 | ||
| 804 | err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); | 804 | err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0); |
| 805 | if (err < 0) { | 805 | if (err < 0) { |
| 806 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ | 806 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ |
| 807 | WARN_ON(err == -EMSGSIZE); | 807 | WARN_ON(err == -EMSGSIZE); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 142257307fa2..7c6a34e21eee 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -644,11 +644,10 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
| 644 | 644 | ||
| 645 | /* Copy only real data... and, alas, header. This should be | 645 | /* Copy only real data... and, alas, header. This should be |
| 646 | * optimized for the cases when header is void. */ | 646 | * optimized for the cases when header is void. */ |
| 647 | memcpy(data + nhead, skb->head, | ||
| 648 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 647 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
| 649 | skb->tail); | 648 | memcpy(data + nhead, skb->head, skb->tail); |
| 650 | #else | 649 | #else |
| 651 | skb->tail - skb->head); | 650 | memcpy(data + nhead, skb->head, skb->tail - skb->head); |
| 652 | #endif | 651 | #endif |
| 653 | memcpy(data + size, skb_end_pointer(skb), | 652 | memcpy(data + size, skb_end_pointer(skb), |
| 654 | sizeof(struct skb_shared_info)); | 653 | sizeof(struct skb_shared_info)); |
diff --git a/net/core/sock.c b/net/core/sock.c index 22183c2ef284..c14ce0198d25 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -206,7 +206,19 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) | |||
| 206 | return -EINVAL; | 206 | return -EINVAL; |
| 207 | if (copy_from_user(&tv, optval, sizeof(tv))) | 207 | if (copy_from_user(&tv, optval, sizeof(tv))) |
| 208 | return -EFAULT; | 208 | return -EFAULT; |
| 209 | 209 | if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC) | |
| 210 | return -EDOM; | ||
| 211 | |||
| 212 | if (tv.tv_sec < 0) { | ||
| 213 | static int warned = 0; | ||
| 214 | *timeo_p = 0; | ||
| 215 | if (warned < 10 && net_ratelimit()) | ||
| 216 | warned++; | ||
| 217 | printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) " | ||
| 218 | "tries to set negative timeout\n", | ||
| 219 | current->comm, current->pid); | ||
| 220 | return 0; | ||
| 221 | } | ||
| 210 | *timeo_p = MAX_SCHEDULE_TIMEOUT; | 222 | *timeo_p = MAX_SCHEDULE_TIMEOUT; |
| 211 | if (tv.tv_sec == 0 && tv.tv_usec == 0) | 223 | if (tv.tv_sec == 0 && tv.tv_usec == 0) |
| 212 | return 0; | 224 | return 0; |
| @@ -986,7 +998,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | |||
| 986 | __sk_dst_set(sk, dst); | 998 | __sk_dst_set(sk, dst); |
| 987 | sk->sk_route_caps = dst->dev->features; | 999 | sk->sk_route_caps = dst->dev->features; |
| 988 | if (sk->sk_route_caps & NETIF_F_GSO) | 1000 | if (sk->sk_route_caps & NETIF_F_GSO) |
| 989 | sk->sk_route_caps |= NETIF_F_GSO_MASK; | 1001 | sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; |
| 990 | if (sk_can_gso(sk)) { | 1002 | if (sk_can_gso(sk)) { |
| 991 | if (dst->header_len) | 1003 | if (dst->header_len) |
| 992 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 1004 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index b29712033dd4..6d5ea9762040 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
| @@ -24,6 +24,8 @@ extern int sysctl_core_destroy_delay; | |||
| 24 | #ifdef CONFIG_XFRM | 24 | #ifdef CONFIG_XFRM |
| 25 | extern u32 sysctl_xfrm_aevent_etime; | 25 | extern u32 sysctl_xfrm_aevent_etime; |
| 26 | extern u32 sysctl_xfrm_aevent_rseqth; | 26 | extern u32 sysctl_xfrm_aevent_rseqth; |
| 27 | extern int sysctl_xfrm_larval_drop; | ||
| 28 | extern u32 sysctl_xfrm_acq_expires; | ||
| 27 | #endif | 29 | #endif |
| 28 | 30 | ||
| 29 | ctl_table core_table[] = { | 31 | ctl_table core_table[] = { |
| @@ -118,6 +120,22 @@ ctl_table core_table[] = { | |||
| 118 | .mode = 0644, | 120 | .mode = 0644, |
| 119 | .proc_handler = &proc_dointvec | 121 | .proc_handler = &proc_dointvec |
| 120 | }, | 122 | }, |
| 123 | { | ||
| 124 | .ctl_name = CTL_UNNUMBERED, | ||
| 125 | .procname = "xfrm_larval_drop", | ||
| 126 | .data = &sysctl_xfrm_larval_drop, | ||
| 127 | .maxlen = sizeof(int), | ||
| 128 | .mode = 0644, | ||
| 129 | .proc_handler = &proc_dointvec | ||
| 130 | }, | ||
| 131 | { | ||
| 132 | .ctl_name = CTL_UNNUMBERED, | ||
| 133 | .procname = "xfrm_acq_expires", | ||
| 134 | .data = &sysctl_xfrm_acq_expires, | ||
| 135 | .maxlen = sizeof(int), | ||
| 136 | .mode = 0644, | ||
| 137 | .proc_handler = &proc_dointvec | ||
| 138 | }, | ||
| 121 | #endif /* CONFIG_XFRM */ | 139 | #endif /* CONFIG_XFRM */ |
| 122 | #endif /* CONFIG_NET */ | 140 | #endif /* CONFIG_NET */ |
| 123 | { | 141 | { |
diff --git a/net/core/utils.c b/net/core/utils.c index adecfd281ae9..2030bb8c2d30 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
| @@ -139,16 +139,16 @@ int in4_pton(const char *src, int srclen, | |||
| 139 | while(1) { | 139 | while(1) { |
| 140 | int c; | 140 | int c; |
| 141 | c = xdigit2bin(srclen > 0 ? *s : '\0', delim); | 141 | c = xdigit2bin(srclen > 0 ? *s : '\0', delim); |
| 142 | if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) { | 142 | if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) { |
| 143 | goto out; | 143 | goto out; |
| 144 | } | 144 | } |
| 145 | if (c & (IN6PTON_DOT | IN6PTON_DELIM)) { | 145 | if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) { |
| 146 | if (w == 0) | 146 | if (w == 0) |
| 147 | goto out; | 147 | goto out; |
| 148 | *d++ = w & 0xff; | 148 | *d++ = w & 0xff; |
| 149 | w = 0; | 149 | w = 0; |
| 150 | i++; | 150 | i++; |
| 151 | if (c & IN6PTON_DELIM) { | 151 | if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { |
| 152 | if (i != 4) | 152 | if (i != 4) |
| 153 | goto out; | 153 | goto out; |
| 154 | break; | 154 | break; |
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index b8a68dd41000..0549e4719b13 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | menu "DCCP Configuration (EXPERIMENTAL)" | 1 | menuconfig IP_DCCP |
| 2 | depends on INET && EXPERIMENTAL | ||
| 3 | |||
| 4 | config IP_DCCP | ||
| 5 | tristate "The DCCP Protocol (EXPERIMENTAL)" | 2 | tristate "The DCCP Protocol (EXPERIMENTAL)" |
| 3 | depends on INET && EXPERIMENTAL | ||
| 6 | ---help--- | 4 | ---help--- |
| 7 | Datagram Congestion Control Protocol (RFC 4340) | 5 | Datagram Congestion Control Protocol (RFC 4340) |
| 8 | 6 | ||
| @@ -19,19 +17,20 @@ config IP_DCCP | |||
| 19 | 17 | ||
| 20 | If in doubt, say N. | 18 | If in doubt, say N. |
| 21 | 19 | ||
| 20 | if IP_DCCP | ||
| 21 | |||
| 22 | config INET_DCCP_DIAG | 22 | config INET_DCCP_DIAG |
| 23 | depends on IP_DCCP && INET_DIAG | 23 | depends on INET_DIAG |
| 24 | def_tristate y if (IP_DCCP = y && INET_DIAG = y) | 24 | def_tristate y if (IP_DCCP = y && INET_DIAG = y) |
| 25 | def_tristate m | 25 | def_tristate m |
| 26 | 26 | ||
| 27 | config IP_DCCP_ACKVEC | 27 | config IP_DCCP_ACKVEC |
| 28 | depends on IP_DCCP | ||
| 29 | bool | 28 | bool |
| 30 | 29 | ||
| 31 | source "net/dccp/ccids/Kconfig" | 30 | source "net/dccp/ccids/Kconfig" |
| 32 | 31 | ||
| 33 | menu "DCCP Kernel Hacking" | 32 | menu "DCCP Kernel Hacking" |
| 34 | depends on IP_DCCP && DEBUG_KERNEL=y | 33 | depends on DEBUG_KERNEL=y |
| 35 | 34 | ||
| 36 | config IP_DCCP_DEBUG | 35 | config IP_DCCP_DEBUG |
| 37 | bool "DCCP debug messages" | 36 | bool "DCCP debug messages" |
| @@ -61,4 +60,4 @@ config NET_DCCPPROBE | |||
| 61 | 60 | ||
| 62 | endmenu | 61 | endmenu |
| 63 | 62 | ||
| 64 | endmenu | 63 | endif # IP_DDCP |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index d7d9ce737244..ec7fa4d67f08 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
| @@ -419,7 +419,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, | |||
| 419 | 419 | ||
| 420 | static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | 420 | static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) |
| 421 | { | 421 | { |
| 422 | const struct dccp_sock *dp = dccp_sk(sk); | ||
| 423 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 422 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
| 424 | struct ccid3_options_received *opt_recv; | 423 | struct ccid3_options_received *opt_recv; |
| 425 | struct dccp_tx_hist_entry *packet; | 424 | struct dccp_tx_hist_entry *packet; |
| @@ -491,7 +490,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 491 | ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " | 490 | ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " |
| 492 | "R_sample=%uus, X=%u\n", dccp_role(sk), | 491 | "R_sample=%uus, X=%u\n", dccp_role(sk), |
| 493 | sk, hctx->ccid3hctx_s, | 492 | sk, hctx->ccid3hctx_s, |
| 494 | dp->dccps_mss_cache, r_sample, | 493 | dccp_sk(sk)->dccps_mss_cache, r_sample, |
| 495 | (unsigned)(hctx->ccid3hctx_x >> 6)); | 494 | (unsigned)(hctx->ccid3hctx_x >> 6)); |
| 496 | 495 | ||
| 497 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); | 496 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 64eac2515aa2..31737cdf156a 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
| @@ -1043,9 +1043,13 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 1043 | if (final_p) | 1043 | if (final_p) |
| 1044 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 1044 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 1045 | 1045 | ||
| 1046 | err = xfrm_lookup(&dst, &fl, sk, 1); | 1046 | err = __xfrm_lookup(&dst, &fl, sk, 1); |
| 1047 | if (err < 0) | 1047 | if (err < 0) { |
| 1048 | goto failure; | 1048 | if (err == -EREMOTE) |
| 1049 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
| 1050 | if (err < 0) | ||
| 1051 | goto failure; | ||
| 1052 | } | ||
| 1049 | 1053 | ||
| 1050 | if (saddr == NULL) { | 1054 | if (saddr == NULL) { |
| 1051 | saddr = &fl.fl6_src; | 1055 | saddr = &fl.fl6_src; |
diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 1f5e3ba62065..43a3adb027e7 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c | |||
| @@ -128,7 +128,7 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, | |||
| 128 | int error = 0, cnt = 0; | 128 | int error = 0, cnt = 0; |
| 129 | unsigned char *tbuf; | 129 | unsigned char *tbuf; |
| 130 | 130 | ||
| 131 | if (!buf || len < 0) | 131 | if (!buf) |
| 132 | return -EINVAL; | 132 | return -EINVAL; |
| 133 | 133 | ||
| 134 | if (len == 0) | 134 | if (len == 0) |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 9fbe87c93802..bfa910b6ad25 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
| @@ -1839,7 +1839,7 @@ static inline int dn_queue_too_long(struct dn_scp *scp, struct sk_buff_head *que | |||
| 1839 | } | 1839 | } |
| 1840 | 1840 | ||
| 1841 | /* | 1841 | /* |
| 1842 | * The DECnet spec requires the the "routing layer" accepts packets which | 1842 | * The DECnet spec requires that the "routing layer" accepts packets which |
| 1843 | * are at least 230 bytes in size. This excludes any headers which the NSP | 1843 | * are at least 230 bytes in size. This excludes any headers which the NSP |
| 1844 | * layer might add, so we always assume that we'll be using the maximal | 1844 | * layer might add, so we always assume that we'll be using the maximal |
| 1845 | * length header on data packets. The variation in length is due to the | 1845 | * length header on data packets. The variation in length is due to the |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 764a56a13e38..ab41c1879fd4 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
| @@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) | |||
| 638 | return dn_dev; | 638 | return dn_dev; |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { | 641 | static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { |
| 642 | [IFA_ADDRESS] = { .type = NLA_U16 }, | 642 | [IFA_ADDRESS] = { .type = NLA_U16 }, |
| 643 | [IFA_LOCAL] = { .type = NLA_U16 }, | 643 | [IFA_LOCAL] = { .type = NLA_U16 }, |
| 644 | [IFA_LABEL] = { .type = NLA_STRING, | 644 | [IFA_LABEL] = { .type = NLA_STRING, |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 17a1932216d6..84ff3dd37070 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
| @@ -108,7 +108,7 @@ errout: | |||
| 108 | return err; | 108 | return err; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 111 | static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = { |
| 112 | FRA_GENERIC_POLICY, | 112 | FRA_GENERIC_POLICY, |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c index 305a09de85a5..960ad13f5e9f 100644 --- a/net/ieee80211/ieee80211_geo.c +++ b/net/ieee80211/ieee80211_geo.c | |||
| @@ -94,6 +94,21 @@ int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel) | |||
| 94 | return -1; | 94 | return -1; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee, u8 channel) | ||
| 98 | { | ||
| 99 | const struct ieee80211_channel * ch; | ||
| 100 | |||
| 101 | /* Driver needs to initialize the geography map before using | ||
| 102 | * these helper functions */ | ||
| 103 | if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) | ||
| 104 | return 0; | ||
| 105 | |||
| 106 | ch = ieee80211_get_channel(ieee, channel); | ||
| 107 | if (!ch->channel) | ||
| 108 | return 0; | ||
| 109 | return ch->freq; | ||
| 110 | } | ||
| 111 | |||
| 97 | u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq) | 112 | u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq) |
| 98 | { | 113 | { |
| 99 | int i; | 114 | int i; |
| @@ -174,6 +189,7 @@ EXPORT_SYMBOL(ieee80211_get_channel); | |||
| 174 | EXPORT_SYMBOL(ieee80211_get_channel_flags); | 189 | EXPORT_SYMBOL(ieee80211_get_channel_flags); |
| 175 | EXPORT_SYMBOL(ieee80211_is_valid_channel); | 190 | EXPORT_SYMBOL(ieee80211_is_valid_channel); |
| 176 | EXPORT_SYMBOL(ieee80211_freq_to_channel); | 191 | EXPORT_SYMBOL(ieee80211_freq_to_channel); |
| 192 | EXPORT_SYMBOL(ieee80211_channel_to_freq); | ||
| 177 | EXPORT_SYMBOL(ieee80211_channel_to_index); | 193 | EXPORT_SYMBOL(ieee80211_channel_to_index); |
| 178 | EXPORT_SYMBOL(ieee80211_set_geo); | 194 | EXPORT_SYMBOL(ieee80211_set_geo); |
| 179 | EXPORT_SYMBOL(ieee80211_get_geo); | 195 | EXPORT_SYMBOL(ieee80211_get_geo); |
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 7ec6610841ba..17ad278696ed 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c | |||
| @@ -140,7 +140,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
| 140 | 140 | ||
| 141 | dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); | 141 | dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); |
| 142 | if (!dev) { | 142 | if (!dev) { |
| 143 | IEEE80211_ERROR("Unable to network device.\n"); | 143 | IEEE80211_ERROR("Unable to allocate network device.\n"); |
| 144 | goto failed; | 144 | goto failed; |
| 145 | } | 145 | } |
| 146 | ieee = netdev_priv(dev); | 146 | ieee = netdev_priv(dev); |
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index cee5e13bc427..523a137d49dd 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c | |||
| @@ -89,15 +89,17 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee, | |||
| 89 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); | 89 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* Add frequency/channel */ | 92 | /* Add channel and frequency */ |
| 93 | iwe.cmd = SIOCGIWFREQ; | 93 | iwe.cmd = SIOCGIWFREQ; |
| 94 | /* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode); | ||
| 95 | iwe.u.freq.e = 3; */ | ||
| 96 | iwe.u.freq.m = network->channel; | 94 | iwe.u.freq.m = network->channel; |
| 97 | iwe.u.freq.e = 0; | 95 | iwe.u.freq.e = 0; |
| 98 | iwe.u.freq.i = 0; | 96 | iwe.u.freq.i = 0; |
| 99 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); | 97 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); |
| 100 | 98 | ||
| 99 | iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel); | ||
| 100 | iwe.u.freq.e = 6; | ||
| 101 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); | ||
| 102 | |||
| 101 | /* Add encryption capability */ | 103 | /* Add encryption capability */ |
| 102 | iwe.cmd = SIOCGIWENCODE; | 104 | iwe.cmd = SIOCGIWENCODE; |
| 103 | if (network->capability & WLAN_CAPABILITY_PRIVACY) | 105 | if (network->capability & WLAN_CAPABILITY_PRIVACY) |
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index e9cdc6615ddc..c308756c2f9d 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
| @@ -33,7 +33,10 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
| 33 | struct ieee80211softmac_device *softmac; | 33 | struct ieee80211softmac_device *softmac; |
| 34 | struct net_device *dev; | 34 | struct net_device *dev; |
| 35 | 35 | ||
| 36 | dev = alloc_ieee80211(sizeof(struct ieee80211softmac_device) + sizeof_priv); | 36 | dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv); |
| 37 | if (!dev) | ||
| 38 | return NULL; | ||
| 39 | |||
| 37 | softmac = ieee80211_priv(dev); | 40 | softmac = ieee80211_priv(dev); |
| 38 | softmac->dev = dev; | 41 | softmac->dev = dev; |
| 39 | softmac->ieee = netdev_priv(dev); | 42 | softmac->ieee = netdev_priv(dev); |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index e62aee0ec4c5..010fbb2d45e9 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
| @@ -43,11 +43,11 @@ config IP_ADVANCED_ROUTER | |||
| 43 | asymmetric routing (packets from you to a host take a different path | 43 | asymmetric routing (packets from you to a host take a different path |
| 44 | than packets from that host to you) or if you operate a non-routing | 44 | than packets from that host to you) or if you operate a non-routing |
| 45 | host which has several IP addresses on different interfaces. To turn | 45 | host which has several IP addresses on different interfaces. To turn |
| 46 | rp_filter off use: | 46 | rp_filter on use: |
| 47 | 47 | ||
| 48 | echo 0 > /proc/sys/net/ipv4/conf/<device>/rp_filter | 48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter |
| 49 | or | 49 | or |
| 50 | echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter | 50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter |
| 51 | 51 | ||
| 52 | If unsure, say N here. | 52 | If unsure, say N here. |
| 53 | 53 | ||
| @@ -130,7 +130,7 @@ config IP_ROUTE_MULTIPATH_RR | |||
| 130 | tristate "MULTIPATH: round robin algorithm" | 130 | tristate "MULTIPATH: round robin algorithm" |
| 131 | depends on IP_ROUTE_MULTIPATH_CACHED | 131 | depends on IP_ROUTE_MULTIPATH_CACHED |
| 132 | help | 132 | help |
| 133 | Mulitpath routes are chosen according to Round Robin | 133 | Multipath routes are chosen according to Round Robin |
| 134 | 134 | ||
| 135 | config IP_ROUTE_MULTIPATH_RANDOM | 135 | config IP_ROUTE_MULTIPATH_RANDOM |
| 136 | tristate "MULTIPATH: random algorithm" | 136 | tristate "MULTIPATH: random algorithm" |
| @@ -577,6 +577,7 @@ config TCP_CONG_VENO | |||
| 577 | config TCP_CONG_YEAH | 577 | config TCP_CONG_YEAH |
| 578 | tristate "YeAH TCP" | 578 | tristate "YeAH TCP" |
| 579 | depends on EXPERIMENTAL | 579 | depends on EXPERIMENTAL |
| 580 | select TCP_CONG_VEGAS | ||
| 580 | default n | 581 | default n |
| 581 | ---help--- | 582 | ---help--- |
| 582 | YeAH-TCP is a sender-side high-speed enabled TCP congestion control | 583 | YeAH-TCP is a sender-side high-speed enabled TCP congestion control |
| @@ -651,7 +652,7 @@ config TCP_MD5SIG | |||
| 651 | select CRYPTO | 652 | select CRYPTO |
| 652 | select CRYPTO_MD5 | 653 | select CRYPTO_MD5 |
| 653 | ---help--- | 654 | ---help--- |
| 654 | RFC2385 specifices a method of giving MD5 protection to TCP sessions. | 655 | RFC2385 specifies a method of giving MD5 protection to TCP sessions. |
| 655 | Its main (only?) use is to protect BGP sessions between core routers | 656 | Its main (only?) use is to protect BGP sessions between core routers |
| 656 | on the Internet. | 657 | on the Internet. |
| 657 | 658 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 16aae8ef5555..041fba3fa0aa 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -92,7 +92,6 @@ | |||
| 92 | #include <asm/uaccess.h> | 92 | #include <asm/uaccess.h> |
| 93 | #include <asm/system.h> | 93 | #include <asm/system.h> |
| 94 | 94 | ||
| 95 | #include <linux/smp_lock.h> | ||
| 96 | #include <linux/inet.h> | 95 | #include <linux/inet.h> |
| 97 | #include <linux/igmp.h> | 96 | #include <linux/igmp.h> |
| 98 | #include <linux/inetdevice.h> | 97 | #include <linux/inetdevice.h> |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7110779a0244..e00767e8ebd9 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
| @@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb) | |||
| 877 | 877 | ||
| 878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); | 878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); |
| 879 | 879 | ||
| 880 | if (ipv4_devconf.arp_accept) { | 880 | if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) { |
| 881 | /* Unsolicited ARP is not accepted by default. | 881 | /* Unsolicited ARP is not accepted by default. |
| 882 | It is possible, that this option should be enabled for some | 882 | It is possible, that this option should be enabled for some |
| 883 | devices (strip is candidate) | 883 | devices (strip is candidate) |
| @@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev) | |||
| 987 | return 0; | 987 | return 0; |
| 988 | } | 988 | } |
| 989 | if (dev == NULL) { | 989 | if (dev == NULL) { |
| 990 | ipv4_devconf.proxy_arp = 1; | 990 | IPV4_DEVCONF_ALL(PROXY_ARP) = 1; |
| 991 | return 0; | 991 | return 0; |
| 992 | } | 992 | } |
| 993 | if (__in_dev_get_rtnl(dev)) { | 993 | if (__in_dev_get_rtnl(dev)) { |
| 994 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; | 994 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1); |
| 995 | return 0; | 995 | return 0; |
| 996 | } | 996 | } |
| 997 | return -ENXIO; | 997 | return -ENXIO; |
| @@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev) | |||
| 1093 | return pneigh_delete(&arp_tbl, &ip, dev); | 1093 | return pneigh_delete(&arp_tbl, &ip, dev); |
| 1094 | if (mask == 0) { | 1094 | if (mask == 0) { |
| 1095 | if (dev == NULL) { | 1095 | if (dev == NULL) { |
| 1096 | ipv4_devconf.proxy_arp = 0; | 1096 | IPV4_DEVCONF_ALL(PROXY_ARP) = 0; |
| 1097 | return 0; | 1097 | return 0; |
| 1098 | } | 1098 | } |
| 1099 | if (__in_dev_get_rtnl(dev)) { | 1099 | if (__in_dev_get_rtnl(dev)) { |
| 1100 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; | 1100 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), |
| 1101 | PROXY_ARP, 0); | ||
| 1101 | return 0; | 1102 | return 0; |
| 1102 | } | 1103 | } |
| 1103 | return -ENXIO; | 1104 | return -ENXIO; |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index e1f18489db1d..ab56a052ce31 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <net/cipso_ipv4.h> | 45 | #include <net/cipso_ipv4.h> |
| 46 | #include <asm/atomic.h> | 46 | #include <asm/atomic.h> |
| 47 | #include <asm/bug.h> | 47 | #include <asm/bug.h> |
| 48 | #include <asm/unaligned.h> | ||
| 48 | 49 | ||
| 49 | struct cipso_v4_domhsh_entry { | 50 | struct cipso_v4_domhsh_entry { |
| 50 | char *domain; | 51 | char *domain; |
| @@ -629,7 +630,7 @@ doi_walk_return: | |||
| 629 | * @domain: the domain to add | 630 | * @domain: the domain to add |
| 630 | * | 631 | * |
| 631 | * Description: | 632 | * Description: |
| 632 | * Adds the @domain to the the DOI specified by @doi_def, this function | 633 | * Adds the @domain to the DOI specified by @doi_def, this function |
| 633 | * should only be called by external functions (i.e. NetLabel). This function | 634 | * should only be called by external functions (i.e. NetLabel). This function |
| 634 | * does allocate memory. Returns zero on success, negative values on failure. | 635 | * does allocate memory. Returns zero on success, negative values on failure. |
| 635 | * | 636 | * |
| @@ -1000,7 +1001,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def, | |||
| 1000 | return -EFAULT; | 1001 | return -EFAULT; |
| 1001 | 1002 | ||
| 1002 | for (iter = 0; iter < enumcat_len; iter += 2) { | 1003 | for (iter = 0; iter < enumcat_len; iter += 2) { |
| 1003 | cat = ntohs(*((__be16 *)&enumcat[iter])); | 1004 | cat = ntohs(get_unaligned((__be16 *)&enumcat[iter])); |
| 1004 | if (cat <= cat_prev) | 1005 | if (cat <= cat_prev) |
| 1005 | return -EFAULT; | 1006 | return -EFAULT; |
| 1006 | cat_prev = cat; | 1007 | cat_prev = cat; |
| @@ -1068,8 +1069,8 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def, | |||
| 1068 | 1069 | ||
| 1069 | for (iter = 0; iter < net_cat_len; iter += 2) { | 1070 | for (iter = 0; iter < net_cat_len; iter += 2) { |
| 1070 | ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, | 1071 | ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, |
| 1071 | ntohs(*((__be16 *)&net_cat[iter])), | 1072 | ntohs(get_unaligned((__be16 *)&net_cat[iter])), |
| 1072 | GFP_ATOMIC); | 1073 | GFP_ATOMIC); |
| 1073 | if (ret_val != 0) | 1074 | if (ret_val != 0) |
| 1074 | return ret_val; | 1075 | return ret_val; |
| 1075 | } | 1076 | } |
| @@ -1102,9 +1103,10 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def, | |||
| 1102 | return -EFAULT; | 1103 | return -EFAULT; |
| 1103 | 1104 | ||
| 1104 | for (iter = 0; iter < rngcat_len; iter += 4) { | 1105 | for (iter = 0; iter < rngcat_len; iter += 4) { |
| 1105 | cat_high = ntohs(*((__be16 *)&rngcat[iter])); | 1106 | cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter])); |
| 1106 | if ((iter + 4) <= rngcat_len) | 1107 | if ((iter + 4) <= rngcat_len) |
| 1107 | cat_low = ntohs(*((__be16 *)&rngcat[iter + 2])); | 1108 | cat_low = ntohs( |
| 1109 | get_unaligned((__be16 *)&rngcat[iter + 2])); | ||
| 1108 | else | 1110 | else |
| 1109 | cat_low = 0; | 1111 | cat_low = 0; |
| 1110 | 1112 | ||
| @@ -1201,9 +1203,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def, | |||
| 1201 | u16 cat_high; | 1203 | u16 cat_high; |
| 1202 | 1204 | ||
| 1203 | for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { | 1205 | for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { |
| 1204 | cat_high = ntohs(*((__be16 *)&net_cat[net_iter])); | 1206 | cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter])); |
| 1205 | if ((net_iter + 4) <= net_cat_len) | 1207 | if ((net_iter + 4) <= net_cat_len) |
| 1206 | cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2])); | 1208 | cat_low = ntohs( |
| 1209 | get_unaligned((__be16 *)&net_cat[net_iter + 2])); | ||
| 1207 | else | 1210 | else |
| 1208 | cat_low = 0; | 1211 | cat_low = 0; |
| 1209 | 1212 | ||
| @@ -1565,7 +1568,7 @@ int cipso_v4_validate(unsigned char **option) | |||
| 1565 | } | 1568 | } |
| 1566 | 1569 | ||
| 1567 | rcu_read_lock(); | 1570 | rcu_read_lock(); |
| 1568 | doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2]))); | 1571 | doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2]))); |
| 1569 | if (doi_def == NULL) { | 1572 | if (doi_def == NULL) { |
| 1570 | err_offset = 2; | 1573 | err_offset = 2; |
| 1571 | goto validate_return_locked; | 1574 | goto validate_return_locked; |
| @@ -1709,22 +1712,22 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) | |||
| 1709 | } | 1712 | } |
| 1710 | 1713 | ||
| 1711 | /** | 1714 | /** |
| 1712 | * cipso_v4_socket_setattr - Add a CIPSO option to a socket | 1715 | * cipso_v4_sock_setattr - Add a CIPSO option to a socket |
| 1713 | * @sock: the socket | 1716 | * @sk: the socket |
| 1714 | * @doi_def: the CIPSO DOI to use | 1717 | * @doi_def: the CIPSO DOI to use |
| 1715 | * @secattr: the specific security attributes of the socket | 1718 | * @secattr: the specific security attributes of the socket |
| 1716 | * | 1719 | * |
| 1717 | * Description: | 1720 | * Description: |
| 1718 | * Set the CIPSO option on the given socket using the DOI definition and | 1721 | * Set the CIPSO option on the given socket using the DOI definition and |
| 1719 | * security attributes passed to the function. This function requires | 1722 | * security attributes passed to the function. This function requires |
| 1720 | * exclusive access to @sock->sk, which means it either needs to be in the | 1723 | * exclusive access to @sk, which means it either needs to be in the |
| 1721 | * process of being created or locked via lock_sock(sock->sk). Returns zero on | 1724 | * process of being created or locked. Returns zero on success and negative |
| 1722 | * success and negative values on failure. | 1725 | * values on failure. |
| 1723 | * | 1726 | * |
| 1724 | */ | 1727 | */ |
| 1725 | int cipso_v4_socket_setattr(const struct socket *sock, | 1728 | int cipso_v4_sock_setattr(struct sock *sk, |
| 1726 | const struct cipso_v4_doi *doi_def, | 1729 | const struct cipso_v4_doi *doi_def, |
| 1727 | const struct netlbl_lsm_secattr *secattr) | 1730 | const struct netlbl_lsm_secattr *secattr) |
| 1728 | { | 1731 | { |
| 1729 | int ret_val = -EPERM; | 1732 | int ret_val = -EPERM; |
| 1730 | u32 iter; | 1733 | u32 iter; |
| @@ -1732,7 +1735,6 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
| 1732 | u32 buf_len = 0; | 1735 | u32 buf_len = 0; |
| 1733 | u32 opt_len; | 1736 | u32 opt_len; |
| 1734 | struct ip_options *opt = NULL; | 1737 | struct ip_options *opt = NULL; |
| 1735 | struct sock *sk; | ||
| 1736 | struct inet_sock *sk_inet; | 1738 | struct inet_sock *sk_inet; |
| 1737 | struct inet_connection_sock *sk_conn; | 1739 | struct inet_connection_sock *sk_conn; |
| 1738 | 1740 | ||
| @@ -1740,7 +1742,6 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
| 1740 | * defined yet but it is not a problem as the only users of these | 1742 | * defined yet but it is not a problem as the only users of these |
| 1741 | * "lite" PF_INET sockets are functions which do an accept() call | 1743 | * "lite" PF_INET sockets are functions which do an accept() call |
| 1742 | * afterwards so we will label the socket as part of the accept(). */ | 1744 | * afterwards so we will label the socket as part of the accept(). */ |
| 1743 | sk = sock->sk; | ||
| 1744 | if (sk == NULL) | 1745 | if (sk == NULL) |
| 1745 | return 0; | 1746 | return 0; |
| 1746 | 1747 | ||
| @@ -1858,7 +1859,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
| 1858 | if (ret_val == 0) | 1859 | if (ret_val == 0) |
| 1859 | return ret_val; | 1860 | return ret_val; |
| 1860 | 1861 | ||
| 1861 | doi = ntohl(*(__be32 *)&cipso_ptr[2]); | 1862 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); |
| 1862 | rcu_read_lock(); | 1863 | rcu_read_lock(); |
| 1863 | doi_def = cipso_v4_doi_search(doi); | 1864 | doi_def = cipso_v4_doi_search(doi); |
| 1864 | if (doi_def == NULL) { | 1865 | if (doi_def == NULL) { |
| @@ -1892,29 +1893,6 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
| 1892 | } | 1893 | } |
| 1893 | 1894 | ||
| 1894 | /** | 1895 | /** |
| 1895 | * cipso_v4_socket_getattr - Get the security attributes from a socket | ||
| 1896 | * @sock: the socket | ||
| 1897 | * @secattr: the security attributes | ||
| 1898 | * | ||
| 1899 | * Description: | ||
| 1900 | * Query @sock to see if there is a CIPSO option attached to the socket and if | ||
| 1901 | * there is return the CIPSO security attributes in @secattr. Returns zero on | ||
| 1902 | * success and negative values on failure. | ||
| 1903 | * | ||
| 1904 | */ | ||
| 1905 | int cipso_v4_socket_getattr(const struct socket *sock, | ||
| 1906 | struct netlbl_lsm_secattr *secattr) | ||
| 1907 | { | ||
| 1908 | int ret_val; | ||
| 1909 | |||
| 1910 | lock_sock(sock->sk); | ||
| 1911 | ret_val = cipso_v4_sock_getattr(sock->sk, secattr); | ||
| 1912 | release_sock(sock->sk); | ||
| 1913 | |||
| 1914 | return ret_val; | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | /** | ||
| 1918 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option | 1896 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option |
| 1919 | * @skb: the packet | 1897 | * @skb: the packet |
| 1920 | * @secattr: the security attributes | 1898 | * @secattr: the security attributes |
| @@ -1936,7 +1914,7 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | |||
| 1936 | if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) | 1914 | if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) |
| 1937 | return 0; | 1915 | return 0; |
| 1938 | 1916 | ||
| 1939 | doi = ntohl(*(__be32 *)&cipso_ptr[2]); | 1917 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); |
| 1940 | rcu_read_lock(); | 1918 | rcu_read_lock(); |
| 1941 | doi_def = cipso_v4_doi_search(doi); | 1919 | doi_def = cipso_v4_doi_search(doi); |
| 1942 | if (doi_def == NULL) | 1920 | if (doi_def == NULL) |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index dd02a45d0f67..0301dd468cf4 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
| @@ -50,8 +50,12 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 50 | RT_CONN_FLAGS(sk), oif, | 50 | RT_CONN_FLAGS(sk), oif, |
| 51 | sk->sk_protocol, | 51 | sk->sk_protocol, |
| 52 | inet->sport, usin->sin_port, sk, 1); | 52 | inet->sport, usin->sin_port, sk, 1); |
| 53 | if (err) | 53 | if (err) { |
| 54 | if (err == -ENETUNREACH) | ||
| 55 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | ||
| 54 | return err; | 56 | return err; |
| 57 | } | ||
| 58 | |||
| 55 | if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) { | 59 | if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) { |
| 56 | ip_rt_put(rt); | 60 | ip_rt_put(rt); |
| 57 | return -EACCES; | 61 | return -EACCES; |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 7f95e6e9beeb..abf6352f990f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -64,21 +64,27 @@ | |||
| 64 | #include <net/rtnetlink.h> | 64 | #include <net/rtnetlink.h> |
| 65 | 65 | ||
| 66 | struct ipv4_devconf ipv4_devconf = { | 66 | struct ipv4_devconf ipv4_devconf = { |
| 67 | .accept_redirects = 1, | 67 | .data = { |
| 68 | .send_redirects = 1, | 68 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
| 69 | .secure_redirects = 1, | 69 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
| 70 | .shared_media = 1, | 70 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
| 71 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, | ||
| 72 | }, | ||
| 71 | }; | 73 | }; |
| 72 | 74 | ||
| 73 | static struct ipv4_devconf ipv4_devconf_dflt = { | 75 | static struct ipv4_devconf ipv4_devconf_dflt = { |
| 74 | .accept_redirects = 1, | 76 | .data = { |
| 75 | .send_redirects = 1, | 77 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
| 76 | .secure_redirects = 1, | 78 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
| 77 | .shared_media = 1, | 79 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
| 78 | .accept_source_route = 1, | 80 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, |
| 81 | [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1, | ||
| 82 | }, | ||
| 79 | }; | 83 | }; |
| 80 | 84 | ||
| 81 | static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { | 85 | #define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr) |
| 86 | |||
| 87 | static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = { | ||
| 82 | [IFA_LOCAL] = { .type = NLA_U32 }, | 88 | [IFA_LOCAL] = { .type = NLA_U32 }, |
| 83 | [IFA_ADDRESS] = { .type = NLA_U32 }, | 89 | [IFA_ADDRESS] = { .type = NLA_U32 }, |
| 84 | [IFA_BROADCAST] = { .type = NLA_U32 }, | 90 | [IFA_BROADCAST] = { .type = NLA_U32 }, |
| @@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev) | |||
| 141 | } | 147 | } |
| 142 | } | 148 | } |
| 143 | 149 | ||
| 144 | struct in_device *inetdev_init(struct net_device *dev) | 150 | static struct in_device *inetdev_init(struct net_device *dev) |
| 145 | { | 151 | { |
| 146 | struct in_device *in_dev; | 152 | struct in_device *in_dev; |
| 147 | 153 | ||
| @@ -321,12 +327,8 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
| 321 | } | 327 | } |
| 322 | 328 | ||
| 323 | } | 329 | } |
| 324 | if (destroy) { | 330 | if (destroy) |
| 325 | inet_free_ifa(ifa1); | 331 | inet_free_ifa(ifa1); |
| 326 | |||
| 327 | if (!in_dev->ifa_list) | ||
| 328 | inetdev_destroy(in_dev); | ||
| 329 | } | ||
| 330 | } | 332 | } |
| 331 | 333 | ||
| 332 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 334 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, |
| @@ -399,12 +401,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) | |||
| 399 | ASSERT_RTNL(); | 401 | ASSERT_RTNL(); |
| 400 | 402 | ||
| 401 | if (!in_dev) { | 403 | if (!in_dev) { |
| 402 | in_dev = inetdev_init(dev); | 404 | inet_free_ifa(ifa); |
| 403 | if (!in_dev) { | 405 | return -ENOBUFS; |
| 404 | inet_free_ifa(ifa); | ||
| 405 | return -ENOBUFS; | ||
| 406 | } | ||
| 407 | } | 406 | } |
| 407 | ipv4_devconf_setall(in_dev); | ||
| 408 | if (ifa->ifa_dev != in_dev) { | 408 | if (ifa->ifa_dev != in_dev) { |
| 409 | BUG_TRAP(!ifa->ifa_dev); | 409 | BUG_TRAP(!ifa->ifa_dev); |
| 410 | in_dev_hold(in_dev); | 410 | in_dev_hold(in_dev); |
| @@ -514,13 +514,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) | |||
| 514 | 514 | ||
| 515 | in_dev = __in_dev_get_rtnl(dev); | 515 | in_dev = __in_dev_get_rtnl(dev); |
| 516 | if (in_dev == NULL) { | 516 | if (in_dev == NULL) { |
| 517 | in_dev = inetdev_init(dev); | 517 | err = -ENOBUFS; |
| 518 | if (in_dev == NULL) { | 518 | goto errout; |
| 519 | err = -ENOBUFS; | ||
| 520 | goto errout; | ||
| 521 | } | ||
| 522 | } | 519 | } |
| 523 | 520 | ||
| 521 | ipv4_devconf_setall(in_dev); | ||
| 522 | |||
| 524 | ifa = inet_alloc_ifa(); | 523 | ifa = inet_alloc_ifa(); |
| 525 | if (ifa == NULL) { | 524 | if (ifa == NULL) { |
| 526 | /* | 525 | /* |
| @@ -1057,11 +1056,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
| 1057 | if (!in_dev) { | 1056 | if (!in_dev) { |
| 1058 | if (event == NETDEV_REGISTER) { | 1057 | if (event == NETDEV_REGISTER) { |
| 1059 | in_dev = inetdev_init(dev); | 1058 | in_dev = inetdev_init(dev); |
| 1060 | if (!in_dev) | ||
| 1061 | panic("devinet: Failed to create loopback\n"); | ||
| 1062 | if (dev == &loopback_dev) { | 1059 | if (dev == &loopback_dev) { |
| 1063 | in_dev->cnf.no_xfrm = 1; | 1060 | if (!in_dev) |
| 1064 | in_dev->cnf.no_policy = 1; | 1061 | panic("devinet: " |
| 1062 | "Failed to create loopback\n"); | ||
| 1063 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); | ||
| 1064 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); | ||
| 1065 | } | 1065 | } |
| 1066 | } | 1066 | } |
| 1067 | goto out; | 1067 | goto out; |
| @@ -1237,13 +1237,98 @@ errout: | |||
| 1237 | 1237 | ||
| 1238 | #ifdef CONFIG_SYSCTL | 1238 | #ifdef CONFIG_SYSCTL |
| 1239 | 1239 | ||
| 1240 | static void devinet_copy_dflt_conf(int i) | ||
| 1241 | { | ||
| 1242 | struct net_device *dev; | ||
| 1243 | |||
| 1244 | read_lock(&dev_base_lock); | ||
| 1245 | for_each_netdev(dev) { | ||
| 1246 | struct in_device *in_dev; | ||
| 1247 | rcu_read_lock(); | ||
| 1248 | in_dev = __in_dev_get_rcu(dev); | ||
| 1249 | if (in_dev && !test_bit(i, in_dev->cnf.state)) | ||
| 1250 | in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i]; | ||
| 1251 | rcu_read_unlock(); | ||
| 1252 | } | ||
| 1253 | read_unlock(&dev_base_lock); | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | static int devinet_conf_proc(ctl_table *ctl, int write, | ||
| 1257 | struct file* filp, void __user *buffer, | ||
| 1258 | size_t *lenp, loff_t *ppos) | ||
| 1259 | { | ||
| 1260 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | ||
| 1261 | |||
| 1262 | if (write) { | ||
| 1263 | struct ipv4_devconf *cnf = ctl->extra1; | ||
| 1264 | int i = (int *)ctl->data - cnf->data; | ||
| 1265 | |||
| 1266 | set_bit(i, cnf->state); | ||
| 1267 | |||
| 1268 | if (cnf == &ipv4_devconf_dflt) | ||
| 1269 | devinet_copy_dflt_conf(i); | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | return ret; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen, | ||
| 1276 | void __user *oldval, size_t __user *oldlenp, | ||
| 1277 | void __user *newval, size_t newlen) | ||
| 1278 | { | ||
| 1279 | struct ipv4_devconf *cnf; | ||
| 1280 | int *valp = table->data; | ||
| 1281 | int new; | ||
| 1282 | int i; | ||
| 1283 | |||
| 1284 | if (!newval || !newlen) | ||
| 1285 | return 0; | ||
| 1286 | |||
| 1287 | if (newlen != sizeof(int)) | ||
| 1288 | return -EINVAL; | ||
| 1289 | |||
| 1290 | if (get_user(new, (int __user *)newval)) | ||
| 1291 | return -EFAULT; | ||
| 1292 | |||
| 1293 | if (new == *valp) | ||
| 1294 | return 0; | ||
| 1295 | |||
| 1296 | if (oldval && oldlenp) { | ||
| 1297 | size_t len; | ||
| 1298 | |||
| 1299 | if (get_user(len, oldlenp)) | ||
| 1300 | return -EFAULT; | ||
| 1301 | |||
| 1302 | if (len) { | ||
| 1303 | if (len > table->maxlen) | ||
| 1304 | len = table->maxlen; | ||
| 1305 | if (copy_to_user(oldval, valp, len)) | ||
| 1306 | return -EFAULT; | ||
| 1307 | if (put_user(len, oldlenp)) | ||
| 1308 | return -EFAULT; | ||
| 1309 | } | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | *valp = new; | ||
| 1313 | |||
| 1314 | cnf = table->extra1; | ||
| 1315 | i = (int *)table->data - cnf->data; | ||
| 1316 | |||
| 1317 | set_bit(i, cnf->state); | ||
| 1318 | |||
| 1319 | if (cnf == &ipv4_devconf_dflt) | ||
| 1320 | devinet_copy_dflt_conf(i); | ||
| 1321 | |||
| 1322 | return 1; | ||
| 1323 | } | ||
| 1324 | |||
| 1240 | void inet_forward_change(void) | 1325 | void inet_forward_change(void) |
| 1241 | { | 1326 | { |
| 1242 | struct net_device *dev; | 1327 | struct net_device *dev; |
| 1243 | int on = ipv4_devconf.forwarding; | 1328 | int on = IPV4_DEVCONF_ALL(FORWARDING); |
| 1244 | 1329 | ||
| 1245 | ipv4_devconf.accept_redirects = !on; | 1330 | IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on; |
| 1246 | ipv4_devconf_dflt.forwarding = on; | 1331 | IPV4_DEVCONF_DFLT(FORWARDING) = on; |
| 1247 | 1332 | ||
| 1248 | read_lock(&dev_base_lock); | 1333 | read_lock(&dev_base_lock); |
| 1249 | for_each_netdev(dev) { | 1334 | for_each_netdev(dev) { |
| @@ -1251,7 +1336,7 @@ void inet_forward_change(void) | |||
| 1251 | rcu_read_lock(); | 1336 | rcu_read_lock(); |
| 1252 | in_dev = __in_dev_get_rcu(dev); | 1337 | in_dev = __in_dev_get_rcu(dev); |
| 1253 | if (in_dev) | 1338 | if (in_dev) |
| 1254 | in_dev->cnf.forwarding = on; | 1339 | IN_DEV_CONF_SET(in_dev, FORWARDING, on); |
| 1255 | rcu_read_unlock(); | 1340 | rcu_read_unlock(); |
| 1256 | } | 1341 | } |
| 1257 | read_unlock(&dev_base_lock); | 1342 | read_unlock(&dev_base_lock); |
| @@ -1268,9 +1353,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, | |||
| 1268 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 1353 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
| 1269 | 1354 | ||
| 1270 | if (write && *valp != val) { | 1355 | if (write && *valp != val) { |
| 1271 | if (valp == &ipv4_devconf.forwarding) | 1356 | if (valp == &IPV4_DEVCONF_ALL(FORWARDING)) |
| 1272 | inet_forward_change(); | 1357 | inet_forward_change(); |
| 1273 | else if (valp != &ipv4_devconf_dflt.forwarding) | 1358 | else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING)) |
| 1274 | rt_cache_flush(0); | 1359 | rt_cache_flush(0); |
| 1275 | } | 1360 | } |
| 1276 | 1361 | ||
| @@ -1295,42 +1380,43 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, | |||
| 1295 | void __user *oldval, size_t __user *oldlenp, | 1380 | void __user *oldval, size_t __user *oldlenp, |
| 1296 | void __user *newval, size_t newlen) | 1381 | void __user *newval, size_t newlen) |
| 1297 | { | 1382 | { |
| 1298 | int *valp = table->data; | 1383 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, |
| 1299 | int new; | 1384 | newval, newlen); |
| 1300 | 1385 | ||
| 1301 | if (!newval || !newlen) | 1386 | if (ret == 1) |
| 1302 | return 0; | 1387 | rt_cache_flush(0); |
| 1303 | 1388 | ||
| 1304 | if (newlen != sizeof(int)) | 1389 | return ret; |
| 1305 | return -EINVAL; | 1390 | } |
| 1306 | 1391 | ||
| 1307 | if (get_user(new, (int __user *)newval)) | ||
| 1308 | return -EFAULT; | ||
| 1309 | 1392 | ||
| 1310 | if (new == *valp) | 1393 | #define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \ |
| 1311 | return 0; | 1394 | { \ |
| 1395 | .ctl_name = NET_IPV4_CONF_ ## attr, \ | ||
| 1396 | .procname = name, \ | ||
| 1397 | .data = ipv4_devconf.data + \ | ||
| 1398 | NET_IPV4_CONF_ ## attr - 1, \ | ||
| 1399 | .maxlen = sizeof(int), \ | ||
| 1400 | .mode = mval, \ | ||
| 1401 | .proc_handler = proc, \ | ||
| 1402 | .strategy = sysctl, \ | ||
| 1403 | .extra1 = &ipv4_devconf, \ | ||
| 1404 | } | ||
| 1312 | 1405 | ||
| 1313 | if (oldval && oldlenp) { | 1406 | #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \ |
| 1314 | size_t len; | 1407 | DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \ |
| 1408 | devinet_conf_sysctl) | ||
| 1315 | 1409 | ||
| 1316 | if (get_user(len, oldlenp)) | 1410 | #define DEVINET_SYSCTL_RO_ENTRY(attr, name) \ |
| 1317 | return -EFAULT; | 1411 | DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \ |
| 1412 | devinet_conf_sysctl) | ||
| 1318 | 1413 | ||
| 1319 | if (len) { | 1414 | #define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \ |
| 1320 | if (len > table->maxlen) | 1415 | DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl) |
| 1321 | len = table->maxlen; | ||
| 1322 | if (copy_to_user(oldval, valp, len)) | ||
| 1323 | return -EFAULT; | ||
| 1324 | if (put_user(len, oldlenp)) | ||
| 1325 | return -EFAULT; | ||
| 1326 | } | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | *valp = new; | ||
| 1330 | rt_cache_flush(0); | ||
| 1331 | return 1; | ||
| 1332 | } | ||
| 1333 | 1416 | ||
| 1417 | #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ | ||
| 1418 | DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \ | ||
| 1419 | ipv4_doint_and_flush_strategy) | ||
| 1334 | 1420 | ||
| 1335 | static struct devinet_sysctl_table { | 1421 | static struct devinet_sysctl_table { |
| 1336 | struct ctl_table_header *sysctl_header; | 1422 | struct ctl_table_header *sysctl_header; |
| @@ -1341,178 +1427,34 @@ static struct devinet_sysctl_table { | |||
| 1341 | ctl_table devinet_root_dir[2]; | 1427 | ctl_table devinet_root_dir[2]; |
| 1342 | } devinet_sysctl = { | 1428 | } devinet_sysctl = { |
| 1343 | .devinet_vars = { | 1429 | .devinet_vars = { |
| 1344 | { | 1430 | DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding", |
| 1345 | .ctl_name = NET_IPV4_CONF_FORWARDING, | 1431 | devinet_sysctl_forward, |
| 1346 | .procname = "forwarding", | 1432 | devinet_conf_sysctl), |
| 1347 | .data = &ipv4_devconf.forwarding, | 1433 | DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"), |
| 1348 | .maxlen = sizeof(int), | 1434 | |
| 1349 | .mode = 0644, | 1435 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"), |
| 1350 | .proc_handler = &devinet_sysctl_forward, | 1436 | DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"), |
| 1351 | }, | 1437 | DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"), |
| 1352 | { | 1438 | DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"), |
| 1353 | .ctl_name = NET_IPV4_CONF_MC_FORWARDING, | 1439 | DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"), |
| 1354 | .procname = "mc_forwarding", | 1440 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, |
| 1355 | .data = &ipv4_devconf.mc_forwarding, | 1441 | "accept_source_route"), |
| 1356 | .maxlen = sizeof(int), | 1442 | DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), |
| 1357 | .mode = 0444, | 1443 | DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), |
| 1358 | .proc_handler = &proc_dointvec, | 1444 | DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), |
| 1359 | }, | 1445 | DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"), |
| 1360 | { | 1446 | DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"), |
| 1361 | .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, | 1447 | DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"), |
| 1362 | .procname = "accept_redirects", | 1448 | DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"), |
| 1363 | .data = &ipv4_devconf.accept_redirects, | 1449 | DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"), |
| 1364 | .maxlen = sizeof(int), | 1450 | DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), |
| 1365 | .mode = 0644, | 1451 | |
| 1366 | .proc_handler = &proc_dointvec, | 1452 | DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), |
| 1367 | }, | 1453 | DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), |
| 1368 | { | 1454 | DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION, |
| 1369 | .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, | 1455 | "force_igmp_version"), |
| 1370 | .procname = "secure_redirects", | 1456 | DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, |
| 1371 | .data = &ipv4_devconf.secure_redirects, | 1457 | "promote_secondaries"), |
| 1372 | .maxlen = sizeof(int), | ||
| 1373 | .mode = 0644, | ||
| 1374 | .proc_handler = &proc_dointvec, | ||
| 1375 | }, | ||
| 1376 | { | ||
| 1377 | .ctl_name = NET_IPV4_CONF_SHARED_MEDIA, | ||
| 1378 | .procname = "shared_media", | ||
| 1379 | .data = &ipv4_devconf.shared_media, | ||
| 1380 | .maxlen = sizeof(int), | ||
| 1381 | .mode = 0644, | ||
| 1382 | .proc_handler = &proc_dointvec, | ||
| 1383 | }, | ||
| 1384 | { | ||
| 1385 | .ctl_name = NET_IPV4_CONF_RP_FILTER, | ||
| 1386 | .procname = "rp_filter", | ||
| 1387 | .data = &ipv4_devconf.rp_filter, | ||
| 1388 | .maxlen = sizeof(int), | ||
| 1389 | .mode = 0644, | ||
| 1390 | .proc_handler = &proc_dointvec, | ||
| 1391 | }, | ||
| 1392 | { | ||
| 1393 | .ctl_name = NET_IPV4_CONF_SEND_REDIRECTS, | ||
| 1394 | .procname = "send_redirects", | ||
| 1395 | .data = &ipv4_devconf.send_redirects, | ||
| 1396 | .maxlen = sizeof(int), | ||
| 1397 | .mode = 0644, | ||
| 1398 | .proc_handler = &proc_dointvec, | ||
| 1399 | }, | ||
| 1400 | { | ||
| 1401 | .ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, | ||
| 1402 | .procname = "accept_source_route", | ||
| 1403 | .data = &ipv4_devconf.accept_source_route, | ||
| 1404 | .maxlen = sizeof(int), | ||
| 1405 | .mode = 0644, | ||
| 1406 | .proc_handler = &proc_dointvec, | ||
| 1407 | }, | ||
| 1408 | { | ||
| 1409 | .ctl_name = NET_IPV4_CONF_PROXY_ARP, | ||
| 1410 | .procname = "proxy_arp", | ||
| 1411 | .data = &ipv4_devconf.proxy_arp, | ||
| 1412 | .maxlen = sizeof(int), | ||
| 1413 | .mode = 0644, | ||
| 1414 | .proc_handler = &proc_dointvec, | ||
| 1415 | }, | ||
| 1416 | { | ||
| 1417 | .ctl_name = NET_IPV4_CONF_MEDIUM_ID, | ||
| 1418 | .procname = "medium_id", | ||
| 1419 | .data = &ipv4_devconf.medium_id, | ||
| 1420 | .maxlen = sizeof(int), | ||
| 1421 | .mode = 0644, | ||
| 1422 | .proc_handler = &proc_dointvec, | ||
| 1423 | }, | ||
| 1424 | { | ||
| 1425 | .ctl_name = NET_IPV4_CONF_BOOTP_RELAY, | ||
| 1426 | .procname = "bootp_relay", | ||
| 1427 | .data = &ipv4_devconf.bootp_relay, | ||
| 1428 | .maxlen = sizeof(int), | ||
| 1429 | .mode = 0644, | ||
| 1430 | .proc_handler = &proc_dointvec, | ||
| 1431 | }, | ||
| 1432 | { | ||
| 1433 | .ctl_name = NET_IPV4_CONF_LOG_MARTIANS, | ||
| 1434 | .procname = "log_martians", | ||
| 1435 | .data = &ipv4_devconf.log_martians, | ||
| 1436 | .maxlen = sizeof(int), | ||
| 1437 | .mode = 0644, | ||
| 1438 | .proc_handler = &proc_dointvec, | ||
| 1439 | }, | ||
| 1440 | { | ||
| 1441 | .ctl_name = NET_IPV4_CONF_TAG, | ||
| 1442 | .procname = "tag", | ||
| 1443 | .data = &ipv4_devconf.tag, | ||
| 1444 | .maxlen = sizeof(int), | ||
| 1445 | .mode = 0644, | ||
| 1446 | .proc_handler = &proc_dointvec, | ||
| 1447 | }, | ||
| 1448 | { | ||
| 1449 | .ctl_name = NET_IPV4_CONF_ARPFILTER, | ||
| 1450 | .procname = "arp_filter", | ||
| 1451 | .data = &ipv4_devconf.arp_filter, | ||
| 1452 | .maxlen = sizeof(int), | ||
| 1453 | .mode = 0644, | ||
| 1454 | .proc_handler = &proc_dointvec, | ||
| 1455 | }, | ||
| 1456 | { | ||
| 1457 | .ctl_name = NET_IPV4_CONF_ARP_ANNOUNCE, | ||
| 1458 | .procname = "arp_announce", | ||
| 1459 | .data = &ipv4_devconf.arp_announce, | ||
| 1460 | .maxlen = sizeof(int), | ||
| 1461 | .mode = 0644, | ||
| 1462 | .proc_handler = &proc_dointvec, | ||
| 1463 | }, | ||
| 1464 | { | ||
| 1465 | .ctl_name = NET_IPV4_CONF_ARP_IGNORE, | ||
| 1466 | .procname = "arp_ignore", | ||
| 1467 | .data = &ipv4_devconf.arp_ignore, | ||
| 1468 | .maxlen = sizeof(int), | ||
| 1469 | .mode = 0644, | ||
| 1470 | .proc_handler = &proc_dointvec, | ||
| 1471 | }, | ||
| 1472 | { | ||
| 1473 | .ctl_name = NET_IPV4_CONF_ARP_ACCEPT, | ||
| 1474 | .procname = "arp_accept", | ||
| 1475 | .data = &ipv4_devconf.arp_accept, | ||
| 1476 | .maxlen = sizeof(int), | ||
| 1477 | .mode = 0644, | ||
| 1478 | .proc_handler = &proc_dointvec, | ||
| 1479 | }, | ||
| 1480 | { | ||
| 1481 | .ctl_name = NET_IPV4_CONF_NOXFRM, | ||
| 1482 | .procname = "disable_xfrm", | ||
| 1483 | .data = &ipv4_devconf.no_xfrm, | ||
| 1484 | .maxlen = sizeof(int), | ||
| 1485 | .mode = 0644, | ||
| 1486 | .proc_handler = &ipv4_doint_and_flush, | ||
| 1487 | .strategy = &ipv4_doint_and_flush_strategy, | ||
| 1488 | }, | ||
| 1489 | { | ||
| 1490 | .ctl_name = NET_IPV4_CONF_NOPOLICY, | ||
| 1491 | .procname = "disable_policy", | ||
| 1492 | .data = &ipv4_devconf.no_policy, | ||
| 1493 | .maxlen = sizeof(int), | ||
| 1494 | .mode = 0644, | ||
| 1495 | .proc_handler = &ipv4_doint_and_flush, | ||
| 1496 | .strategy = &ipv4_doint_and_flush_strategy, | ||
| 1497 | }, | ||
| 1498 | { | ||
| 1499 | .ctl_name = NET_IPV4_CONF_FORCE_IGMP_VERSION, | ||
| 1500 | .procname = "force_igmp_version", | ||
| 1501 | .data = &ipv4_devconf.force_igmp_version, | ||
| 1502 | .maxlen = sizeof(int), | ||
| 1503 | .mode = 0644, | ||
| 1504 | .proc_handler = &ipv4_doint_and_flush, | ||
| 1505 | .strategy = &ipv4_doint_and_flush_strategy, | ||
| 1506 | }, | ||
| 1507 | { | ||
| 1508 | .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES, | ||
| 1509 | .procname = "promote_secondaries", | ||
| 1510 | .data = &ipv4_devconf.promote_secondaries, | ||
| 1511 | .maxlen = sizeof(int), | ||
| 1512 | .mode = 0644, | ||
| 1513 | .proc_handler = &ipv4_doint_and_flush, | ||
| 1514 | .strategy = &ipv4_doint_and_flush_strategy, | ||
| 1515 | }, | ||
| 1516 | }, | 1458 | }, |
| 1517 | .devinet_dev = { | 1459 | .devinet_dev = { |
| 1518 | { | 1460 | { |
| @@ -1561,6 +1503,7 @@ static void devinet_sysctl_register(struct in_device *in_dev, | |||
| 1561 | return; | 1503 | return; |
| 1562 | for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { | 1504 | for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { |
| 1563 | t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; | 1505 | t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; |
| 1506 | t->devinet_vars[i].extra1 = p; | ||
| 1564 | } | 1507 | } |
| 1565 | 1508 | ||
| 1566 | if (dev) { | 1509 | if (dev) { |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 837f2957fa83..311d633f7f39 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -250,8 +250,6 @@ e_inval: | |||
| 250 | return -EINVAL; | 250 | return -EINVAL; |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | #ifndef CONFIG_IP_NOSIOCRT | ||
| 254 | |||
| 255 | static inline __be32 sk_extract_addr(struct sockaddr *addr) | 253 | static inline __be32 sk_extract_addr(struct sockaddr *addr) |
| 256 | { | 254 | { |
| 257 | return ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 255 | return ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
| @@ -443,16 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg) | |||
| 443 | return -EINVAL; | 441 | return -EINVAL; |
| 444 | } | 442 | } |
| 445 | 443 | ||
| 446 | #else | 444 | const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { |
| 447 | |||
| 448 | int ip_rt_ioctl(unsigned int cmd, void *arg) | ||
| 449 | { | ||
| 450 | return -EINVAL; | ||
| 451 | } | ||
| 452 | |||
| 453 | #endif | ||
| 454 | |||
| 455 | struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { | ||
| 456 | [RTA_DST] = { .type = NLA_U32 }, | 445 | [RTA_DST] = { .type = NLA_U32 }, |
| 457 | [RTA_SRC] = { .type = NLA_U32 }, | 446 | [RTA_SRC] = { .type = NLA_U32 }, |
| 458 | [RTA_IIF] = { .type = NLA_U32 }, | 447 | [RTA_IIF] = { .type = NLA_U32 }, |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 9cfecf1215c9..07e843a47dde 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
| @@ -456,6 +456,8 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 456 | fib_release_info(fi_drop); | 456 | fib_release_info(fi_drop); |
| 457 | if (state & FA_S_ACCESSED) | 457 | if (state & FA_S_ACCESSED) |
| 458 | rt_cache_flush(-1); | 458 | rt_cache_flush(-1); |
| 459 | rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id, | ||
| 460 | &cfg->fc_nlinfo, NLM_F_REPLACE); | ||
| 459 | return 0; | 461 | return 0; |
| 460 | } | 462 | } |
| 461 | 463 | ||
| @@ -523,7 +525,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 523 | rt_cache_flush(-1); | 525 | rt_cache_flush(-1); |
| 524 | 526 | ||
| 525 | rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id, | 527 | rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id, |
| 526 | &cfg->fc_nlinfo); | 528 | &cfg->fc_nlinfo, 0); |
| 527 | return 0; | 529 | return 0; |
| 528 | 530 | ||
| 529 | out_free_new_fa: | 531 | out_free_new_fa: |
| @@ -589,7 +591,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg) | |||
| 589 | 591 | ||
| 590 | fa = fa_to_delete; | 592 | fa = fa_to_delete; |
| 591 | rtmsg_fib(RTM_DELROUTE, key, fa, cfg->fc_dst_len, | 593 | rtmsg_fib(RTM_DELROUTE, key, fa, cfg->fc_dst_len, |
| 592 | tb->tb_id, &cfg->fc_nlinfo); | 594 | tb->tb_id, &cfg->fc_nlinfo, 0); |
| 593 | 595 | ||
| 594 | kill_fn = 0; | 596 | kill_fn = 0; |
| 595 | write_lock_bh(&fib_hash_lock); | 597 | write_lock_bh(&fib_hash_lock); |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 0e8b70bad4e1..eef9eec17e0c 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
| @@ -30,7 +30,8 @@ extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
| 30 | int dst_len, u8 tos, struct fib_info *fi, | 30 | int dst_len, u8 tos, struct fib_info *fi, |
| 31 | unsigned int); | 31 | unsigned int); |
| 32 | extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, | 32 | extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, |
| 33 | int dst_len, u32 tb_id, struct nl_info *info); | 33 | int dst_len, u32 tb_id, struct nl_info *info, |
| 34 | unsigned int nlm_flags); | ||
| 34 | extern struct fib_alias *fib_find_alias(struct list_head *fah, | 35 | extern struct fib_alias *fib_find_alias(struct list_head *fah, |
| 35 | u8 tos, u32 prio); | 36 | u8 tos, u32 prio); |
| 36 | extern int fib_detect_death(struct fib_info *fi, int order, | 37 | extern int fib_detect_death(struct fib_info *fi, int order, |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 33083ad52e9f..2a947840210e 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void) | |||
| 169 | return NULL; | 169 | return NULL; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | 172 | static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { |
| 173 | FRA_GENERIC_POLICY, | 173 | FRA_GENERIC_POLICY, |
| 174 | [FRA_FLOW] = { .type = NLA_U32 }, | 174 | [FRA_FLOW] = { .type = NLA_U32 }, |
| 175 | }; | 175 | }; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 406ea7050aed..bb94550d95c3 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
| @@ -301,7 +301,8 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi) | |||
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, | 303 | void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, |
| 304 | int dst_len, u32 tb_id, struct nl_info *info) | 304 | int dst_len, u32 tb_id, struct nl_info *info, |
| 305 | unsigned int nlm_flags) | ||
| 305 | { | 306 | { |
| 306 | struct sk_buff *skb; | 307 | struct sk_buff *skb; |
| 307 | u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; | 308 | u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; |
| @@ -313,7 +314,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, | |||
| 313 | 314 | ||
| 314 | err = fib_dump_info(skb, info->pid, seq, event, tb_id, | 315 | err = fib_dump_info(skb, info->pid, seq, event, tb_id, |
| 315 | fa->fa_type, fa->fa_scope, key, dst_len, | 316 | fa->fa_type, fa->fa_scope, key, dst_len, |
| 316 | fa->fa_tos, fa->fa_info, 0); | 317 | fa->fa_tos, fa->fa_info, nlm_flags); |
| 317 | if (err < 0) { | 318 | if (err < 0) { |
| 318 | /* -EMSGSIZE implies BUG in fib_nlmsg_size() */ | 319 | /* -EMSGSIZE implies BUG in fib_nlmsg_size() */ |
| 319 | WARN_ON(err == -EMSGSIZE); | 320 | WARN_ON(err == -EMSGSIZE); |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 9be7da7c3a8f..30e332ade61b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
| @@ -1226,6 +1226,8 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 1226 | fib_release_info(fi_drop); | 1226 | fib_release_info(fi_drop); |
| 1227 | if (state & FA_S_ACCESSED) | 1227 | if (state & FA_S_ACCESSED) |
| 1228 | rt_cache_flush(-1); | 1228 | rt_cache_flush(-1); |
| 1229 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, | ||
| 1230 | tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE); | ||
| 1229 | 1231 | ||
| 1230 | goto succeeded; | 1232 | goto succeeded; |
| 1231 | } | 1233 | } |
| @@ -1278,7 +1280,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 1278 | 1280 | ||
| 1279 | rt_cache_flush(-1); | 1281 | rt_cache_flush(-1); |
| 1280 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, | 1282 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, |
| 1281 | &cfg->fc_nlinfo); | 1283 | &cfg->fc_nlinfo, 0); |
| 1282 | succeeded: | 1284 | succeeded: |
| 1283 | return 0; | 1285 | return 0; |
| 1284 | 1286 | ||
| @@ -1624,7 +1626,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) | |||
| 1624 | 1626 | ||
| 1625 | fa = fa_to_delete; | 1627 | fa = fa_to_delete; |
| 1626 | rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, | 1628 | rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, |
| 1627 | &cfg->fc_nlinfo); | 1629 | &cfg->fc_nlinfo, 0); |
| 1628 | 1630 | ||
| 1629 | l = fib_find_node(t, key); | 1631 | l = fib_find_node(t, key); |
| 1630 | li = find_leaf_info(l, plen); | 1632 | li = find_leaf_info(l, plen); |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index d38cbba92a4d..02a899bec196 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -514,9 +514,15 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 514 | 514 | ||
| 515 | saddr = iph->daddr; | 515 | saddr = iph->daddr; |
| 516 | if (!(rt->rt_flags & RTCF_LOCAL)) { | 516 | if (!(rt->rt_flags & RTCF_LOCAL)) { |
| 517 | if (sysctl_icmp_errors_use_inbound_ifaddr) | 517 | struct net_device *dev = NULL; |
| 518 | saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); | 518 | |
| 519 | else | 519 | if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) |
| 520 | dev = dev_get_by_index(rt->fl.iif); | ||
| 521 | |||
| 522 | if (dev) { | ||
| 523 | saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK); | ||
| 524 | dev_put(dev); | ||
| 525 | } else | ||
| 520 | saddr = 0; | 526 | saddr = 0; |
| 521 | } | 527 | } |
| 522 | 528 | ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f4dd47453108..a646409c2d06 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -128,14 +128,16 @@ | |||
| 128 | * contradict to specs provided this delay is small enough. | 128 | * contradict to specs provided this delay is small enough. |
| 129 | */ | 129 | */ |
| 130 | 130 | ||
| 131 | #define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \ | 131 | #define IGMP_V1_SEEN(in_dev) \ |
| 132 | (in_dev)->cnf.force_igmp_version == 1 || \ | 132 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \ |
| 133 | ((in_dev)->mr_v1_seen && \ | 133 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \ |
| 134 | time_before(jiffies, (in_dev)->mr_v1_seen))) | 134 | ((in_dev)->mr_v1_seen && \ |
| 135 | #define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \ | 135 | time_before(jiffies, (in_dev)->mr_v1_seen))) |
| 136 | (in_dev)->cnf.force_igmp_version == 2 || \ | 136 | #define IGMP_V2_SEEN(in_dev) \ |
| 137 | ((in_dev)->mr_v2_seen && \ | 137 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \ |
| 138 | time_before(jiffies, (in_dev)->mr_v2_seen))) | 138 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \ |
| 139 | ((in_dev)->mr_v2_seen && \ | ||
| 140 | time_before(jiffies, (in_dev)->mr_v2_seen))) | ||
| 139 | 141 | ||
| 140 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); | 142 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); |
| 141 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); | 143 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 43fb1600f1f0..fbe7714f21d0 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -31,10 +31,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg); | |||
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * This array holds the first and last local port number. | 33 | * This array holds the first and last local port number. |
| 34 | * For high-usage systems, use sysctl to change this to | ||
| 35 | * 32768-61000 | ||
| 36 | */ | 34 | */ |
| 37 | int sysctl_local_port_range[2] = { 1024, 4999 }; | 35 | int sysctl_local_port_range[2] = { 32768, 61000 }; |
| 38 | 36 | ||
| 39 | int inet_csk_bind_conflict(const struct sock *sk, | 37 | int inet_csk_bind_conflict(const struct sock *sk, |
| 40 | const struct inet_bind_bucket *tb) | 38 | const struct inet_bind_bucket *tb) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d6427d918512..34ea4547ebbe 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
| 1352 | } | 1352 | } |
| 1353 | 1353 | ||
| 1354 | { | 1354 | { |
| 1355 | struct flowi fl = { .nl_u = { .ip4_u = | 1355 | struct flowi fl = { .oif = arg->bound_dev_if, |
| 1356 | .nl_u = { .ip4_u = | ||
| 1356 | { .daddr = daddr, | 1357 | { .daddr = daddr, |
| 1357 | .saddr = rt->rt_spec_dst, | 1358 | .saddr = rt->rt_spec_dst, |
| 1358 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, | 1359 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, |
| @@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
| 1376 | inet->tos = ip_hdr(skb)->tos; | 1377 | inet->tos = ip_hdr(skb)->tos; |
| 1377 | sk->sk_priority = skb->priority; | 1378 | sk->sk_priority = skb->priority; |
| 1378 | sk->sk_protocol = ip_hdr(skb)->protocol; | 1379 | sk->sk_protocol = ip_hdr(skb)->protocol; |
| 1380 | sk->sk_bound_dev_if = arg->bound_dev_if; | ||
| 1379 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, | 1381 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, |
| 1380 | &ipc, rt, MSG_DONTWAIT); | 1382 | &ipc, rt, MSG_DONTWAIT); |
| 1381 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { | 1383 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 0ebae413ae87..d96582acdf69 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) | |||
| 152 | dev->flags |= IFF_MULTICAST; | 152 | dev->flags |= IFF_MULTICAST; |
| 153 | 153 | ||
| 154 | in_dev = __in_dev_get_rtnl(dev); | 154 | in_dev = __in_dev_get_rtnl(dev); |
| 155 | if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) | 155 | if (in_dev == NULL) |
| 156 | goto failure; | 156 | goto failure; |
| 157 | in_dev->cnf.rp_filter = 0; | 157 | |
| 158 | ipv4_devconf_setall(in_dev); | ||
| 159 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
| 158 | 160 | ||
| 159 | if (dev_open(dev)) | 161 | if (dev_open(dev)) |
| 160 | goto failure; | 162 | goto failure; |
| @@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void) | |||
| 218 | } | 220 | } |
| 219 | dev->iflink = 0; | 221 | dev->iflink = 0; |
| 220 | 222 | ||
| 221 | if ((in_dev = inetdev_init(dev)) == NULL) | 223 | rcu_read_lock(); |
| 224 | if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { | ||
| 225 | rcu_read_unlock(); | ||
| 222 | goto failure; | 226 | goto failure; |
| 227 | } | ||
| 223 | 228 | ||
| 224 | in_dev->cnf.rp_filter = 0; | 229 | ipv4_devconf_setall(in_dev); |
| 230 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
| 231 | rcu_read_unlock(); | ||
| 225 | 232 | ||
| 226 | if (dev_open(dev)) | 233 | if (dev_open(dev)) |
| 227 | goto failure; | 234 | goto failure; |
| @@ -281,7 +288,7 @@ static int vif_delete(int vifi) | |||
| 281 | dev_set_allmulti(dev, -1); | 288 | dev_set_allmulti(dev, -1); |
| 282 | 289 | ||
| 283 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { | 290 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { |
| 284 | in_dev->cnf.mc_forwarding--; | 291 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; |
| 285 | ip_rt_multicast_event(in_dev); | 292 | ip_rt_multicast_event(in_dev); |
| 286 | } | 293 | } |
| 287 | 294 | ||
| @@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
| 426 | 433 | ||
| 427 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 434 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) |
| 428 | return -EADDRNOTAVAIL; | 435 | return -EADDRNOTAVAIL; |
| 429 | in_dev->cnf.mc_forwarding++; | 436 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
| 430 | dev_set_allmulti(dev, +1); | 437 | dev_set_allmulti(dev, +1); |
| 431 | ip_rt_multicast_event(in_dev); | 438 | ip_rt_multicast_event(in_dev); |
| 432 | 439 | ||
| @@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk) | |||
| 841 | { | 848 | { |
| 842 | rtnl_lock(); | 849 | rtnl_lock(); |
| 843 | if (sk == mroute_socket) { | 850 | if (sk == mroute_socket) { |
| 844 | ipv4_devconf.mc_forwarding--; | 851 | IPV4_DEVCONF_ALL(MC_FORWARDING)--; |
| 845 | 852 | ||
| 846 | write_lock_bh(&mrt_lock); | 853 | write_lock_bh(&mrt_lock); |
| 847 | mroute_socket=NULL; | 854 | mroute_socket=NULL; |
| @@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt | |||
| 890 | mroute_socket=sk; | 897 | mroute_socket=sk; |
| 891 | write_unlock_bh(&mrt_lock); | 898 | write_unlock_bh(&mrt_lock); |
| 892 | 899 | ||
| 893 | ipv4_devconf.mc_forwarding++; | 900 | IPV4_DEVCONF_ALL(MC_FORWARDING)++; |
| 894 | } | 901 | } |
| 895 | rtnl_unlock(); | 902 | rtnl_unlock(); |
| 896 | return ret; | 903 | return ret; |
diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig index 891b9355cf96..09d0c3f35669 100644 --- a/net/ipv4/ipvs/Kconfig +++ b/net/ipv4/ipvs/Kconfig | |||
| @@ -1,10 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # IP Virtual Server configuration | 2 | # IP Virtual Server configuration |
| 3 | # | 3 | # |
| 4 | menu "IP: Virtual Server Configuration" | 4 | menuconfig IP_VS |
| 5 | depends on NETFILTER | ||
| 6 | |||
| 7 | config IP_VS | ||
| 8 | tristate "IP virtual server support (EXPERIMENTAL)" | 5 | tristate "IP virtual server support (EXPERIMENTAL)" |
| 9 | depends on NETFILTER | 6 | depends on NETFILTER |
| 10 | ---help--- | 7 | ---help--- |
| @@ -25,9 +22,10 @@ config IP_VS | |||
| 25 | If you want to compile it in kernel, say Y. To compile it as a | 22 | If you want to compile it in kernel, say Y. To compile it as a |
| 26 | module, choose M here. If unsure, say N. | 23 | module, choose M here. If unsure, say N. |
| 27 | 24 | ||
| 25 | if IP_VS | ||
| 26 | |||
| 28 | config IP_VS_DEBUG | 27 | config IP_VS_DEBUG |
| 29 | bool "IP virtual server debugging" | 28 | bool "IP virtual server debugging" |
| 30 | depends on IP_VS | ||
| 31 | ---help--- | 29 | ---help--- |
| 32 | Say Y here if you want to get additional messages useful in | 30 | Say Y here if you want to get additional messages useful in |
| 33 | debugging the IP virtual server code. You can change the debug | 31 | debugging the IP virtual server code. You can change the debug |
| @@ -35,7 +33,6 @@ config IP_VS_DEBUG | |||
| 35 | 33 | ||
| 36 | config IP_VS_TAB_BITS | 34 | config IP_VS_TAB_BITS |
| 37 | int "IPVS connection table size (the Nth power of 2)" | 35 | int "IPVS connection table size (the Nth power of 2)" |
| 38 | depends on IP_VS | ||
| 39 | default "12" | 36 | default "12" |
| 40 | ---help--- | 37 | ---help--- |
| 41 | The IPVS connection hash table uses the chaining scheme to handle | 38 | The IPVS connection hash table uses the chaining scheme to handle |
| @@ -61,42 +58,35 @@ config IP_VS_TAB_BITS | |||
| 61 | needed for your box. | 58 | needed for your box. |
| 62 | 59 | ||
| 63 | comment "IPVS transport protocol load balancing support" | 60 | comment "IPVS transport protocol load balancing support" |
| 64 | depends on IP_VS | ||
| 65 | 61 | ||
| 66 | config IP_VS_PROTO_TCP | 62 | config IP_VS_PROTO_TCP |
| 67 | bool "TCP load balancing support" | 63 | bool "TCP load balancing support" |
| 68 | depends on IP_VS | ||
| 69 | ---help--- | 64 | ---help--- |
| 70 | This option enables support for load balancing TCP transport | 65 | This option enables support for load balancing TCP transport |
| 71 | protocol. Say Y if unsure. | 66 | protocol. Say Y if unsure. |
| 72 | 67 | ||
| 73 | config IP_VS_PROTO_UDP | 68 | config IP_VS_PROTO_UDP |
| 74 | bool "UDP load balancing support" | 69 | bool "UDP load balancing support" |
| 75 | depends on IP_VS | ||
| 76 | ---help--- | 70 | ---help--- |
| 77 | This option enables support for load balancing UDP transport | 71 | This option enables support for load balancing UDP transport |
| 78 | protocol. Say Y if unsure. | 72 | protocol. Say Y if unsure. |
| 79 | 73 | ||
| 80 | config IP_VS_PROTO_ESP | 74 | config IP_VS_PROTO_ESP |
| 81 | bool "ESP load balancing support" | 75 | bool "ESP load balancing support" |
| 82 | depends on IP_VS | ||
| 83 | ---help--- | 76 | ---help--- |
| 84 | This option enables support for load balancing ESP (Encapsulation | 77 | This option enables support for load balancing ESP (Encapsulation |
| 85 | Security Payload) transport protocol. Say Y if unsure. | 78 | Security Payload) transport protocol. Say Y if unsure. |
| 86 | 79 | ||
| 87 | config IP_VS_PROTO_AH | 80 | config IP_VS_PROTO_AH |
| 88 | bool "AH load balancing support" | 81 | bool "AH load balancing support" |
| 89 | depends on IP_VS | ||
| 90 | ---help--- | 82 | ---help--- |
| 91 | This option enables support for load balancing AH (Authentication | 83 | This option enables support for load balancing AH (Authentication |
| 92 | Header) transport protocol. Say Y if unsure. | 84 | Header) transport protocol. Say Y if unsure. |
| 93 | 85 | ||
| 94 | comment "IPVS scheduler" | 86 | comment "IPVS scheduler" |
| 95 | depends on IP_VS | ||
| 96 | 87 | ||
| 97 | config IP_VS_RR | 88 | config IP_VS_RR |
| 98 | tristate "round-robin scheduling" | 89 | tristate "round-robin scheduling" |
| 99 | depends on IP_VS | ||
| 100 | ---help--- | 90 | ---help--- |
| 101 | The robin-robin scheduling algorithm simply directs network | 91 | The robin-robin scheduling algorithm simply directs network |
| 102 | connections to different real servers in a round-robin manner. | 92 | connections to different real servers in a round-robin manner. |
| @@ -106,7 +96,6 @@ config IP_VS_RR | |||
| 106 | 96 | ||
| 107 | config IP_VS_WRR | 97 | config IP_VS_WRR |
| 108 | tristate "weighted round-robin scheduling" | 98 | tristate "weighted round-robin scheduling" |
| 109 | depends on IP_VS | ||
| 110 | ---help--- | 99 | ---help--- |
| 111 | The weighted robin-robin scheduling algorithm directs network | 100 | The weighted robin-robin scheduling algorithm directs network |
| 112 | connections to different real servers based on server weights | 101 | connections to different real servers based on server weights |
| @@ -120,7 +109,6 @@ config IP_VS_WRR | |||
| 120 | 109 | ||
| 121 | config IP_VS_LC | 110 | config IP_VS_LC |
| 122 | tristate "least-connection scheduling" | 111 | tristate "least-connection scheduling" |
| 123 | depends on IP_VS | ||
| 124 | ---help--- | 112 | ---help--- |
| 125 | The least-connection scheduling algorithm directs network | 113 | The least-connection scheduling algorithm directs network |
| 126 | connections to the server with the least number of active | 114 | connections to the server with the least number of active |
| @@ -131,7 +119,6 @@ config IP_VS_LC | |||
| 131 | 119 | ||
| 132 | config IP_VS_WLC | 120 | config IP_VS_WLC |
| 133 | tristate "weighted least-connection scheduling" | 121 | tristate "weighted least-connection scheduling" |
| 134 | depends on IP_VS | ||
| 135 | ---help--- | 122 | ---help--- |
| 136 | The weighted least-connection scheduling algorithm directs network | 123 | The weighted least-connection scheduling algorithm directs network |
| 137 | connections to the server with the least active connections | 124 | connections to the server with the least active connections |
| @@ -142,7 +129,6 @@ config IP_VS_WLC | |||
| 142 | 129 | ||
| 143 | config IP_VS_LBLC | 130 | config IP_VS_LBLC |
| 144 | tristate "locality-based least-connection scheduling" | 131 | tristate "locality-based least-connection scheduling" |
| 145 | depends on IP_VS | ||
| 146 | ---help--- | 132 | ---help--- |
| 147 | The locality-based least-connection scheduling algorithm is for | 133 | The locality-based least-connection scheduling algorithm is for |
| 148 | destination IP load balancing. It is usually used in cache cluster. | 134 | destination IP load balancing. It is usually used in cache cluster. |
| @@ -157,7 +143,6 @@ config IP_VS_LBLC | |||
| 157 | 143 | ||
| 158 | config IP_VS_LBLCR | 144 | config IP_VS_LBLCR |
| 159 | tristate "locality-based least-connection with replication scheduling" | 145 | tristate "locality-based least-connection with replication scheduling" |
| 160 | depends on IP_VS | ||
| 161 | ---help--- | 146 | ---help--- |
| 162 | The locality-based least-connection with replication scheduling | 147 | The locality-based least-connection with replication scheduling |
| 163 | algorithm is also for destination IP load balancing. It is | 148 | algorithm is also for destination IP load balancing. It is |
| @@ -176,7 +161,6 @@ config IP_VS_LBLCR | |||
| 176 | 161 | ||
| 177 | config IP_VS_DH | 162 | config IP_VS_DH |
| 178 | tristate "destination hashing scheduling" | 163 | tristate "destination hashing scheduling" |
| 179 | depends on IP_VS | ||
| 180 | ---help--- | 164 | ---help--- |
| 181 | The destination hashing scheduling algorithm assigns network | 165 | The destination hashing scheduling algorithm assigns network |
| 182 | connections to the servers through looking up a statically assigned | 166 | connections to the servers through looking up a statically assigned |
| @@ -187,7 +171,6 @@ config IP_VS_DH | |||
| 187 | 171 | ||
| 188 | config IP_VS_SH | 172 | config IP_VS_SH |
| 189 | tristate "source hashing scheduling" | 173 | tristate "source hashing scheduling" |
| 190 | depends on IP_VS | ||
| 191 | ---help--- | 174 | ---help--- |
| 192 | The source hashing scheduling algorithm assigns network | 175 | The source hashing scheduling algorithm assigns network |
| 193 | connections to the servers through looking up a statically assigned | 176 | connections to the servers through looking up a statically assigned |
| @@ -198,7 +181,6 @@ config IP_VS_SH | |||
| 198 | 181 | ||
| 199 | config IP_VS_SED | 182 | config IP_VS_SED |
| 200 | tristate "shortest expected delay scheduling" | 183 | tristate "shortest expected delay scheduling" |
| 201 | depends on IP_VS | ||
| 202 | ---help--- | 184 | ---help--- |
| 203 | The shortest expected delay scheduling algorithm assigns network | 185 | The shortest expected delay scheduling algorithm assigns network |
| 204 | connections to the server with the shortest expected delay. The | 186 | connections to the server with the shortest expected delay. The |
| @@ -212,7 +194,6 @@ config IP_VS_SED | |||
| 212 | 194 | ||
| 213 | config IP_VS_NQ | 195 | config IP_VS_NQ |
| 214 | tristate "never queue scheduling" | 196 | tristate "never queue scheduling" |
| 215 | depends on IP_VS | ||
| 216 | ---help--- | 197 | ---help--- |
| 217 | The never queue scheduling algorithm adopts a two-speed model. | 198 | The never queue scheduling algorithm adopts a two-speed model. |
| 218 | When there is an idle server available, the job will be sent to | 199 | When there is an idle server available, the job will be sent to |
| @@ -225,11 +206,10 @@ config IP_VS_NQ | |||
| 225 | module, choose M here. If unsure, say N. | 206 | module, choose M here. If unsure, say N. |
| 226 | 207 | ||
| 227 | comment 'IPVS application helper' | 208 | comment 'IPVS application helper' |
| 228 | depends on IP_VS | ||
| 229 | 209 | ||
| 230 | config IP_VS_FTP | 210 | config IP_VS_FTP |
| 231 | tristate "FTP protocol helper" | 211 | tristate "FTP protocol helper" |
| 232 | depends on IP_VS && IP_VS_PROTO_TCP | 212 | depends on IP_VS_PROTO_TCP |
| 233 | ---help--- | 213 | ---help--- |
| 234 | FTP is a protocol that transfers IP address and/or port number in | 214 | FTP is a protocol that transfers IP address and/or port number in |
| 235 | the payload. In the virtual server via Network Address Translation, | 215 | the payload. In the virtual server via Network Address Translation, |
| @@ -241,4 +221,4 @@ config IP_VS_FTP | |||
| 241 | If you want to compile it in kernel, say Y. To compile it as a | 221 | If you want to compile it in kernel, say Y. To compile it as a |
| 242 | module, choose M here. If unsure, say N. | 222 | module, choose M here. If unsure, say N. |
| 243 | 223 | ||
| 244 | endmenu | 224 | endif # IP_VS |
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index b3050a6817e7..68fe1d4d0210 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
| @@ -2387,6 +2387,7 @@ void ip_vs_control_cleanup(void) | |||
| 2387 | EnterFunction(2); | 2387 | EnterFunction(2); |
| 2388 | ip_vs_trash_cleanup(); | 2388 | ip_vs_trash_cleanup(); |
| 2389 | cancel_rearming_delayed_work(&defense_work); | 2389 | cancel_rearming_delayed_work(&defense_work); |
| 2390 | cancel_work_sync(&defense_work.work); | ||
| 2390 | ip_vs_kill_estimator(&ip_vs_stats); | 2391 | ip_vs_kill_estimator(&ip_vs_stats); |
| 2391 | unregister_sysctl_table(sysctl_header); | 2392 | unregister_sysctl_table(sysctl_header); |
| 2392 | proc_net_remove("ip_vs_stats"); | 2393 | proc_net_remove("ip_vs_stats"); |
diff --git a/net/ipv4/ipvs/ip_vs_sed.c b/net/ipv4/ipvs/ip_vs_sed.c index ff366f7390d9..dd7c128f9db3 100644 --- a/net/ipv4/ipvs/ip_vs_sed.c +++ b/net/ipv4/ipvs/ip_vs_sed.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | * The SED algorithm attempts to minimize each job's expected delay until | 18 | * The SED algorithm attempts to minimize each job's expected delay until |
| 19 | * completion. The expected delay that the job will experience is | 19 | * completion. The expected delay that the job will experience is |
| 20 | * (Ci + 1) / Ui if sent to the ith server, in which Ci is the number of | 20 | * (Ci + 1) / Ui if sent to the ith server, in which Ci is the number of |
| 21 | * jobs on the the ith server and Ui is the fixed service rate (weight) of | 21 | * jobs on the ith server and Ui is the fixed service rate (weight) of |
| 22 | * the ith server. The SED algorithm adopts a greedy policy that each does | 22 | * the ith server. The SED algorithm adopts a greedy policy that each does |
| 23 | * what is in its own best interest, i.e. to join the queue which would | 23 | * what is in its own best interest, i.e. to join the queue which would |
| 24 | * minimize its expected delay of completion. | 24 | * minimize its expected delay of completion. |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 7edea2a1696c..75c023062533 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
| @@ -15,128 +15,34 @@ MODULE_DESCRIPTION("arptables filter table"); | |||
| 15 | #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ | 15 | #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ |
| 16 | (1 << NF_ARP_FORWARD)) | 16 | (1 << NF_ARP_FORWARD)) |
| 17 | 17 | ||
| 18 | /* Standard entry. */ | ||
| 19 | struct arpt_standard | ||
| 20 | { | ||
| 21 | struct arpt_entry entry; | ||
| 22 | struct arpt_standard_target target; | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct arpt_error_target | ||
| 26 | { | ||
| 27 | struct arpt_entry_target target; | ||
| 28 | char errorname[ARPT_FUNCTION_MAXNAMELEN]; | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct arpt_error | ||
| 32 | { | ||
| 33 | struct arpt_entry entry; | ||
| 34 | struct arpt_error_target target; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct | 18 | static struct |
| 38 | { | 19 | { |
| 39 | struct arpt_replace repl; | 20 | struct arpt_replace repl; |
| 40 | struct arpt_standard entries[3]; | 21 | struct arpt_standard entries[3]; |
| 41 | struct arpt_error term; | 22 | struct arpt_error term; |
| 42 | } initial_table __initdata | 23 | } initial_table __initdata = { |
| 43 | = { { "filter", FILTER_VALID_HOOKS, 4, | 24 | .repl = { |
| 44 | sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error), | 25 | .name = "filter", |
| 45 | { [NF_ARP_IN] = 0, | 26 | .valid_hooks = FILTER_VALID_HOOKS, |
| 46 | [NF_ARP_OUT] = sizeof(struct arpt_standard), | 27 | .num_entries = 4, |
| 47 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), }, | 28 | .size = sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error), |
| 48 | { [NF_ARP_IN] = 0, | 29 | .hook_entry = { |
| 49 | [NF_ARP_OUT] = sizeof(struct arpt_standard), | 30 | [NF_ARP_IN] = 0, |
| 50 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), }, | 31 | [NF_ARP_OUT] = sizeof(struct arpt_standard), |
| 51 | 0, NULL, { } }, | 32 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), |
| 52 | { | 33 | }, |
| 53 | /* ARP_IN */ | 34 | .underflow = { |
| 54 | { | 35 | [NF_ARP_IN] = 0, |
| 55 | { | 36 | [NF_ARP_OUT] = sizeof(struct arpt_standard), |
| 56 | { | 37 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), |
| 57 | { 0 }, { 0 }, { 0 }, { 0 }, | 38 | }, |
| 58 | 0, 0, | 39 | }, |
| 59 | { { 0, }, { 0, } }, | 40 | .entries = { |
| 60 | { { 0, }, { 0, } }, | 41 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_IN */ |
| 61 | 0, 0, | 42 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_OUT */ |
| 62 | 0, 0, | 43 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_FORWARD */ |
| 63 | 0, 0, | 44 | }, |
| 64 | "", "", { 0 }, { 0 }, | 45 | .term = ARPT_ERROR_INIT, |
| 65 | 0, 0 | ||
| 66 | }, | ||
| 67 | sizeof(struct arpt_entry), | ||
| 68 | sizeof(struct arpt_standard), | ||
| 69 | 0, | ||
| 70 | { 0, 0 }, { } }, | ||
| 71 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
| 72 | -NF_ACCEPT - 1 } | ||
| 73 | }, | ||
| 74 | /* ARP_OUT */ | ||
| 75 | { | ||
| 76 | { | ||
| 77 | { | ||
| 78 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
| 79 | 0, 0, | ||
| 80 | { { 0, }, { 0, } }, | ||
| 81 | { { 0, }, { 0, } }, | ||
| 82 | 0, 0, | ||
| 83 | 0, 0, | ||
| 84 | 0, 0, | ||
| 85 | "", "", { 0 }, { 0 }, | ||
| 86 | 0, 0 | ||
| 87 | }, | ||
| 88 | sizeof(struct arpt_entry), | ||
| 89 | sizeof(struct arpt_standard), | ||
| 90 | 0, | ||
| 91 | { 0, 0 }, { } }, | ||
| 92 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
| 93 | -NF_ACCEPT - 1 } | ||
| 94 | }, | ||
| 95 | /* ARP_FORWARD */ | ||
| 96 | { | ||
| 97 | { | ||
| 98 | { | ||
| 99 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
| 100 | 0, 0, | ||
| 101 | { { 0, }, { 0, } }, | ||
| 102 | { { 0, }, { 0, } }, | ||
| 103 | 0, 0, | ||
| 104 | 0, 0, | ||
| 105 | 0, 0, | ||
| 106 | "", "", { 0 }, { 0 }, | ||
| 107 | 0, 0 | ||
| 108 | }, | ||
| 109 | sizeof(struct arpt_entry), | ||
| 110 | sizeof(struct arpt_standard), | ||
| 111 | 0, | ||
| 112 | { 0, 0 }, { } }, | ||
| 113 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
| 114 | -NF_ACCEPT - 1 } | ||
| 115 | } | ||
| 116 | }, | ||
| 117 | /* ERROR */ | ||
| 118 | { | ||
| 119 | { | ||
| 120 | { | ||
| 121 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
| 122 | 0, 0, | ||
| 123 | { { 0, }, { 0, } }, | ||
| 124 | { { 0, }, { 0, } }, | ||
| 125 | 0, 0, | ||
| 126 | 0, 0, | ||
| 127 | 0, 0, | ||
| 128 | "", "", { 0 }, { 0 }, | ||
| 129 | 0, 0 | ||
| 130 | }, | ||
| 131 | sizeof(struct arpt_entry), | ||
| 132 | sizeof(struct arpt_error), | ||
| 133 | 0, | ||
| 134 | { 0, 0 }, { } }, | ||
| 135 | { { { { ARPT_ALIGN(sizeof(struct arpt_error_target)), ARPT_ERROR_TARGET } }, | ||
| 136 | { } }, | ||
| 137 | "ERROR" | ||
| 138 | } | ||
| 139 | } | ||
| 140 | }; | 46 | }; |
| 141 | 47 | ||
| 142 | static struct arpt_table packet_filter = { | 48 | static struct arpt_table packet_filter = { |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e3f83bf160d9..9bacf1a03630 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name) | |||
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | static inline int check_match(struct ipt_entry_match *m, const char *name, | 501 | static inline int check_match(struct ipt_entry_match *m, const char *name, |
| 502 | const struct ipt_ip *ip, unsigned int hookmask) | 502 | const struct ipt_ip *ip, unsigned int hookmask, |
| 503 | unsigned int *i) | ||
| 503 | { | 504 | { |
| 504 | struct xt_match *match; | 505 | struct xt_match *match; |
| 505 | int ret; | 506 | int ret; |
| @@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name, | |||
| 515 | m->u.kernel.match->name); | 516 | m->u.kernel.match->name); |
| 516 | ret = -EINVAL; | 517 | ret = -EINVAL; |
| 517 | } | 518 | } |
| 519 | if (!ret) | ||
| 520 | (*i)++; | ||
| 518 | return ret; | 521 | return ret; |
| 519 | } | 522 | } |
| 520 | 523 | ||
| @@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m, | |||
| 537 | } | 540 | } |
| 538 | m->u.kernel.match = match; | 541 | m->u.kernel.match = match; |
| 539 | 542 | ||
| 540 | ret = check_match(m, name, ip, hookmask); | 543 | ret = check_match(m, name, ip, hookmask, i); |
| 541 | if (ret) | 544 | if (ret) |
| 542 | goto err; | 545 | goto err; |
| 543 | 546 | ||
| 544 | (*i)++; | ||
| 545 | return 0; | 547 | return 0; |
| 546 | err: | 548 | err: |
| 547 | module_put(m->u.kernel.match->me); | 549 | module_put(m->u.kernel.match->me); |
| @@ -1425,7 +1427,7 @@ out: | |||
| 1425 | } | 1427 | } |
| 1426 | 1428 | ||
| 1427 | static inline int | 1429 | static inline int |
| 1428 | compat_check_calc_match(struct ipt_entry_match *m, | 1430 | compat_find_calc_match(struct ipt_entry_match *m, |
| 1429 | const char *name, | 1431 | const char *name, |
| 1430 | const struct ipt_ip *ip, | 1432 | const struct ipt_ip *ip, |
| 1431 | unsigned int hookmask, | 1433 | unsigned int hookmask, |
| @@ -1449,6 +1451,31 @@ compat_check_calc_match(struct ipt_entry_match *m, | |||
| 1449 | } | 1451 | } |
| 1450 | 1452 | ||
| 1451 | static inline int | 1453 | static inline int |
| 1454 | compat_release_match(struct ipt_entry_match *m, unsigned int *i) | ||
| 1455 | { | ||
| 1456 | if (i && (*i)-- == 0) | ||
| 1457 | return 1; | ||
| 1458 | |||
| 1459 | module_put(m->u.kernel.match->me); | ||
| 1460 | return 0; | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | static inline int | ||
| 1464 | compat_release_entry(struct ipt_entry *e, unsigned int *i) | ||
| 1465 | { | ||
| 1466 | struct ipt_entry_target *t; | ||
| 1467 | |||
| 1468 | if (i && (*i)-- == 0) | ||
| 1469 | return 1; | ||
| 1470 | |||
| 1471 | /* Cleanup all matches */ | ||
| 1472 | IPT_MATCH_ITERATE(e, compat_release_match, NULL); | ||
| 1473 | t = ipt_get_target(e); | ||
| 1474 | module_put(t->u.kernel.target->me); | ||
| 1475 | return 0; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | static inline int | ||
| 1452 | check_compat_entry_size_and_hooks(struct ipt_entry *e, | 1479 | check_compat_entry_size_and_hooks(struct ipt_entry *e, |
| 1453 | struct xt_table_info *newinfo, | 1480 | struct xt_table_info *newinfo, |
| 1454 | unsigned int *size, | 1481 | unsigned int *size, |
| @@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
| 1485 | off = 0; | 1512 | off = 0; |
| 1486 | entry_offset = (void *)e - (void *)base; | 1513 | entry_offset = (void *)e - (void *)base; |
| 1487 | j = 0; | 1514 | j = 0; |
| 1488 | ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, | 1515 | ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip, |
| 1489 | e->comefrom, &off, &j); | 1516 | e->comefrom, &off, &j); |
| 1490 | if (ret != 0) | 1517 | if (ret != 0) |
| 1491 | goto cleanup_matches; | 1518 | goto release_matches; |
| 1492 | 1519 | ||
| 1493 | t = ipt_get_target(e); | 1520 | t = ipt_get_target(e); |
| 1494 | target = try_then_request_module(xt_find_target(AF_INET, | 1521 | target = try_then_request_module(xt_find_target(AF_INET, |
| @@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
| 1499 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", | 1526 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", |
| 1500 | t->u.user.name); | 1527 | t->u.user.name); |
| 1501 | ret = target ? PTR_ERR(target) : -ENOENT; | 1528 | ret = target ? PTR_ERR(target) : -ENOENT; |
| 1502 | goto cleanup_matches; | 1529 | goto release_matches; |
| 1503 | } | 1530 | } |
| 1504 | t->u.kernel.target = target; | 1531 | t->u.kernel.target = target; |
| 1505 | 1532 | ||
| @@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
| 1526 | 1553 | ||
| 1527 | out: | 1554 | out: |
| 1528 | module_put(t->u.kernel.target->me); | 1555 | module_put(t->u.kernel.target->me); |
| 1529 | cleanup_matches: | 1556 | release_matches: |
| 1530 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | 1557 | IPT_MATCH_ITERATE(e, compat_release_match, &j); |
| 1531 | return ret; | 1558 | return ret; |
| 1532 | } | 1559 | } |
| 1533 | 1560 | ||
| @@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
| 1574 | return ret; | 1601 | return ret; |
| 1575 | } | 1602 | } |
| 1576 | 1603 | ||
| 1577 | static inline int compat_check_entry(struct ipt_entry *e, const char *name) | 1604 | static inline int compat_check_entry(struct ipt_entry *e, const char *name, |
| 1605 | unsigned int *i) | ||
| 1578 | { | 1606 | { |
| 1579 | int ret; | 1607 | int j, ret; |
| 1580 | 1608 | ||
| 1581 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom); | 1609 | j = 0; |
| 1610 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); | ||
| 1582 | if (ret) | 1611 | if (ret) |
| 1583 | return ret; | 1612 | goto cleanup_matches; |
| 1613 | |||
| 1614 | ret = check_target(e, name); | ||
| 1615 | if (ret) | ||
| 1616 | goto cleanup_matches; | ||
| 1584 | 1617 | ||
| 1585 | return check_target(e, name); | 1618 | (*i)++; |
| 1619 | return 0; | ||
| 1620 | |||
| 1621 | cleanup_matches: | ||
| 1622 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
| 1623 | return ret; | ||
| 1586 | } | 1624 | } |
| 1587 | 1625 | ||
| 1588 | static int | 1626 | static int |
| @@ -1673,10 +1711,17 @@ translate_compat_table(const char *name, | |||
| 1673 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) | 1711 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) |
| 1674 | goto free_newinfo; | 1712 | goto free_newinfo; |
| 1675 | 1713 | ||
| 1714 | i = 0; | ||
| 1676 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1715 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, |
| 1677 | name); | 1716 | name, &i); |
| 1678 | if (ret) | 1717 | if (ret) { |
| 1679 | goto free_newinfo; | 1718 | j -= i; |
| 1719 | IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i, | ||
| 1720 | compat_release_entry, &j); | ||
| 1721 | IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); | ||
| 1722 | xt_free_table_info(newinfo); | ||
| 1723 | return ret; | ||
| 1724 | } | ||
| 1680 | 1725 | ||
| 1681 | /* And one copy for every other CPU */ | 1726 | /* And one copy for every other CPU */ |
| 1682 | for_each_possible_cpu(i) | 1727 | for_each_possible_cpu(i) |
| @@ -1691,7 +1736,7 @@ translate_compat_table(const char *name, | |||
| 1691 | free_newinfo: | 1736 | free_newinfo: |
| 1692 | xt_free_table_info(newinfo); | 1737 | xt_free_table_info(newinfo); |
| 1693 | out: | 1738 | out: |
| 1694 | IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); | 1739 | IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); |
| 1695 | return ret; | 1740 | return ret; |
| 1696 | out_unlock: | 1741 | out_unlock: |
| 1697 | compat_flush_offsets(); | 1742 | compat_flush_offsets(); |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 42728909eba0..4f51c1d7d2d6 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
| @@ -26,53 +26,29 @@ static struct | |||
| 26 | struct ipt_replace repl; | 26 | struct ipt_replace repl; |
| 27 | struct ipt_standard entries[3]; | 27 | struct ipt_standard entries[3]; |
| 28 | struct ipt_error term; | 28 | struct ipt_error term; |
| 29 | } initial_table __initdata | 29 | } initial_table __initdata = { |
| 30 | = { { "filter", FILTER_VALID_HOOKS, 4, | 30 | .repl = { |
| 31 | sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), | 31 | .name = "filter", |
| 32 | { [NF_IP_LOCAL_IN] = 0, | 32 | .valid_hooks = FILTER_VALID_HOOKS, |
| 33 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), | 33 | .num_entries = 4, |
| 34 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 34 | .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), |
| 35 | { [NF_IP_LOCAL_IN] = 0, | 35 | .hook_entry = { |
| 36 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), | 36 | [NF_IP_LOCAL_IN] = 0, |
| 37 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 37 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), |
| 38 | 0, NULL, { } }, | 38 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, |
| 39 | { | 39 | }, |
| 40 | /* LOCAL_IN */ | 40 | .underflow = { |
| 41 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 41 | [NF_IP_LOCAL_IN] = 0, |
| 42 | 0, | 42 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), |
| 43 | sizeof(struct ipt_entry), | 43 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, |
| 44 | sizeof(struct ipt_standard), | 44 | }, |
| 45 | 0, { 0, 0 }, { } }, | 45 | }, |
| 46 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | 46 | .entries = { |
| 47 | -NF_ACCEPT - 1 } }, | 47 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
| 48 | /* FORWARD */ | 48 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
| 49 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 49 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 50 | 0, | 50 | }, |
| 51 | sizeof(struct ipt_entry), | 51 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 52 | sizeof(struct ipt_standard), | ||
| 53 | 0, { 0, 0 }, { } }, | ||
| 54 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 55 | -NF_ACCEPT - 1 } }, | ||
| 56 | /* LOCAL_OUT */ | ||
| 57 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 58 | 0, | ||
| 59 | sizeof(struct ipt_entry), | ||
| 60 | sizeof(struct ipt_standard), | ||
| 61 | 0, { 0, 0 }, { } }, | ||
| 62 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 63 | -NF_ACCEPT - 1 } } | ||
| 64 | }, | ||
| 65 | /* ERROR */ | ||
| 66 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 67 | 0, | ||
| 68 | sizeof(struct ipt_entry), | ||
| 69 | sizeof(struct ipt_error), | ||
| 70 | 0, { 0, 0 }, { } }, | ||
| 71 | { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, | ||
| 72 | { } }, | ||
| 73 | "ERROR" | ||
| 74 | } | ||
| 75 | } | ||
| 76 | }; | 52 | }; |
| 77 | 53 | ||
| 78 | static struct xt_table packet_filter = { | 54 | static struct xt_table packet_filter = { |
| @@ -105,7 +81,8 @@ ipt_local_out_hook(unsigned int hook, | |||
| 105 | if ((*pskb)->len < sizeof(struct iphdr) | 81 | if ((*pskb)->len < sizeof(struct iphdr) |
| 106 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | 82 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { |
| 107 | if (net_ratelimit()) | 83 | if (net_ratelimit()) |
| 108 | printk("ipt_hook: happy cracking.\n"); | 84 | printk("iptable_filter: ignoring short SOCK_RAW " |
| 85 | "packet.\n"); | ||
| 109 | return NF_ACCEPT; | 86 | return NF_ACCEPT; |
| 110 | } | 87 | } |
| 111 | 88 | ||
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 9278802f2742..902446f7cbca 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
| @@ -33,73 +33,35 @@ static struct | |||
| 33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
| 34 | struct ipt_standard entries[5]; | 34 | struct ipt_standard entries[5]; |
| 35 | struct ipt_error term; | 35 | struct ipt_error term; |
| 36 | } initial_table __initdata | 36 | } initial_table __initdata = { |
| 37 | = { { "mangle", MANGLE_VALID_HOOKS, 6, | 37 | .repl = { |
| 38 | sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error), | 38 | .name = "mangle", |
| 39 | { [NF_IP_PRE_ROUTING] = 0, | 39 | .valid_hooks = MANGLE_VALID_HOOKS, |
| 40 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), | 40 | .num_entries = 6, |
| 41 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, | 41 | .size = sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error), |
| 42 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, | 42 | .hook_entry = { |
| 43 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, | 43 | [NF_IP_PRE_ROUTING] = 0, |
| 44 | { [NF_IP_PRE_ROUTING] = 0, | 44 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), |
| 45 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), | 45 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, |
| 46 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, | 46 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, |
| 47 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, | 47 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4, |
| 48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, | 48 | }, |
| 49 | 0, NULL, { } }, | 49 | .underflow = { |
| 50 | { | 50 | [NF_IP_PRE_ROUTING] = 0, |
| 51 | /* PRE_ROUTING */ | 51 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), |
| 52 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 52 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, |
| 53 | 0, | 53 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, |
| 54 | sizeof(struct ipt_entry), | 54 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4, |
| 55 | sizeof(struct ipt_standard), | 55 | }, |
| 56 | 0, { 0, 0 }, { } }, | 56 | }, |
| 57 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | 57 | .entries = { |
| 58 | -NF_ACCEPT - 1 } }, | 58 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
| 59 | /* LOCAL_IN */ | 59 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
| 60 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 60 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
| 61 | 0, | 61 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 62 | sizeof(struct ipt_entry), | 62 | IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
| 63 | sizeof(struct ipt_standard), | 63 | }, |
| 64 | 0, { 0, 0 }, { } }, | 64 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 65 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 66 | -NF_ACCEPT - 1 } }, | ||
| 67 | /* FORWARD */ | ||
| 68 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 69 | 0, | ||
| 70 | sizeof(struct ipt_entry), | ||
| 71 | sizeof(struct ipt_standard), | ||
| 72 | 0, { 0, 0 }, { } }, | ||
| 73 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 74 | -NF_ACCEPT - 1 } }, | ||
| 75 | /* LOCAL_OUT */ | ||
| 76 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 77 | 0, | ||
| 78 | sizeof(struct ipt_entry), | ||
| 79 | sizeof(struct ipt_standard), | ||
| 80 | 0, { 0, 0 }, { } }, | ||
| 81 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 82 | -NF_ACCEPT - 1 } }, | ||
| 83 | /* POST_ROUTING */ | ||
| 84 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 85 | 0, | ||
| 86 | sizeof(struct ipt_entry), | ||
| 87 | sizeof(struct ipt_standard), | ||
| 88 | 0, { 0, 0 }, { } }, | ||
| 89 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
| 90 | -NF_ACCEPT - 1 } }, | ||
| 91 | }, | ||
| 92 | /* ERROR */ | ||
| 93 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 94 | 0, | ||
| 95 | sizeof(struct ipt_entry), | ||
| 96 | sizeof(struct ipt_error), | ||
| 97 | 0, { 0, 0 }, { } }, | ||
| 98 | { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, | ||
| 99 | { } }, | ||
| 100 | "ERROR" | ||
| 101 | } | ||
| 102 | } | ||
| 103 | }; | 65 | }; |
| 104 | 66 | ||
| 105 | static struct xt_table packet_mangler = { | 67 | static struct xt_table packet_mangler = { |
| @@ -138,7 +100,8 @@ ipt_local_hook(unsigned int hook, | |||
| 138 | if ((*pskb)->len < sizeof(struct iphdr) | 100 | if ((*pskb)->len < sizeof(struct iphdr) |
| 139 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | 101 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { |
| 140 | if (net_ratelimit()) | 102 | if (net_ratelimit()) |
| 141 | printk("ipt_hook: happy cracking.\n"); | 103 | printk("iptable_mangle: ignoring short SOCK_RAW " |
| 104 | "packet.\n"); | ||
| 142 | return NF_ACCEPT; | 105 | return NF_ACCEPT; |
| 143 | } | 106 | } |
| 144 | 107 | ||
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 18c3d4c9ff51..d6e503395684 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 7 | #include <linux/netfilter_ipv4/ip_tables.h> | 7 | #include <linux/netfilter_ipv4/ip_tables.h> |
| 8 | #include <net/ip.h> | ||
| 8 | 9 | ||
| 9 | #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) | 10 | #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) |
| 10 | 11 | ||
| @@ -21,62 +22,18 @@ static struct | |||
| 21 | .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), | 22 | .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), |
| 22 | .hook_entry = { | 23 | .hook_entry = { |
| 23 | [NF_IP_PRE_ROUTING] = 0, | 24 | [NF_IP_PRE_ROUTING] = 0, |
| 24 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, | 25 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) |
| 26 | }, | ||
| 25 | .underflow = { | 27 | .underflow = { |
| 26 | [NF_IP_PRE_ROUTING] = 0, | 28 | [NF_IP_PRE_ROUTING] = 0, |
| 27 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, | 29 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) |
| 30 | }, | ||
| 28 | }, | 31 | }, |
| 29 | .entries = { | 32 | .entries = { |
| 30 | /* PRE_ROUTING */ | 33 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
| 31 | { | 34 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 32 | .entry = { | ||
| 33 | .target_offset = sizeof(struct ipt_entry), | ||
| 34 | .next_offset = sizeof(struct ipt_standard), | ||
| 35 | }, | ||
| 36 | .target = { | ||
| 37 | .target = { | ||
| 38 | .u = { | ||
| 39 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
| 40 | }, | ||
| 41 | }, | ||
| 42 | .verdict = -NF_ACCEPT - 1, | ||
| 43 | }, | ||
| 44 | }, | ||
| 45 | |||
| 46 | /* LOCAL_OUT */ | ||
| 47 | { | ||
| 48 | .entry = { | ||
| 49 | .target_offset = sizeof(struct ipt_entry), | ||
| 50 | .next_offset = sizeof(struct ipt_standard), | ||
| 51 | }, | ||
| 52 | .target = { | ||
| 53 | .target = { | ||
| 54 | .u = { | ||
| 55 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
| 56 | }, | ||
| 57 | }, | ||
| 58 | .verdict = -NF_ACCEPT - 1, | ||
| 59 | }, | ||
| 60 | }, | ||
| 61 | }, | 35 | }, |
| 62 | /* ERROR */ | 36 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 63 | .term = { | ||
| 64 | .entry = { | ||
| 65 | .target_offset = sizeof(struct ipt_entry), | ||
| 66 | .next_offset = sizeof(struct ipt_error), | ||
| 67 | }, | ||
| 68 | .target = { | ||
| 69 | .target = { | ||
| 70 | .u = { | ||
| 71 | .user = { | ||
| 72 | .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), | ||
| 73 | .name = IPT_ERROR_TARGET, | ||
| 74 | }, | ||
| 75 | }, | ||
| 76 | }, | ||
| 77 | .errorname = "ERROR", | ||
| 78 | }, | ||
| 79 | } | ||
| 80 | }; | 37 | }; |
| 81 | 38 | ||
| 82 | static struct xt_table packet_raw = { | 39 | static struct xt_table packet_raw = { |
| @@ -98,6 +55,24 @@ ipt_hook(unsigned int hook, | |||
| 98 | return ipt_do_table(pskb, hook, in, out, &packet_raw); | 55 | return ipt_do_table(pskb, hook, in, out, &packet_raw); |
| 99 | } | 56 | } |
| 100 | 57 | ||
| 58 | static unsigned int | ||
| 59 | ipt_local_hook(unsigned int hook, | ||
| 60 | struct sk_buff **pskb, | ||
| 61 | const struct net_device *in, | ||
| 62 | const struct net_device *out, | ||
| 63 | int (*okfn)(struct sk_buff *)) | ||
| 64 | { | ||
| 65 | /* root is playing with raw sockets. */ | ||
| 66 | if ((*pskb)->len < sizeof(struct iphdr) || | ||
| 67 | ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | ||
| 68 | if (net_ratelimit()) | ||
| 69 | printk("iptable_raw: ignoring short SOCK_RAW" | ||
| 70 | "packet.\n"); | ||
| 71 | return NF_ACCEPT; | ||
| 72 | } | ||
| 73 | return ipt_do_table(pskb, hook, in, out, &packet_raw); | ||
| 74 | } | ||
| 75 | |||
| 101 | /* 'raw' is the very first table. */ | 76 | /* 'raw' is the very first table. */ |
| 102 | static struct nf_hook_ops ipt_ops[] = { | 77 | static struct nf_hook_ops ipt_ops[] = { |
| 103 | { | 78 | { |
| @@ -108,7 +83,7 @@ static struct nf_hook_ops ipt_ops[] = { | |||
| 108 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
| 109 | }, | 84 | }, |
| 110 | { | 85 | { |
| 111 | .hook = ipt_hook, | 86 | .hook = ipt_local_hook, |
| 112 | .pf = PF_INET, | 87 | .pf = PF_INET, |
| 113 | .hooknum = NF_IP_LOCAL_OUT, | 88 | .hooknum = NF_IP_LOCAL_OUT, |
| 114 | .priority = NF_IP_PRI_RAW, | 89 | .priority = NF_IP_PRI_RAW, |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 0654eaae70c9..6dc72a815f77 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
| 133 | struct nf_conn *ct; | 133 | struct nf_conn *ct; |
| 134 | enum ip_conntrack_info ctinfo; | 134 | enum ip_conntrack_info ctinfo; |
| 135 | struct nf_conn_help *help; | 135 | struct nf_conn_help *help; |
| 136 | struct nf_conntrack_helper *helper; | ||
| 136 | 137 | ||
| 137 | /* This is where we call the helper: as the packet goes out. */ | 138 | /* This is where we call the helper: as the packet goes out. */ |
| 138 | ct = nf_ct_get(*pskb, &ctinfo); | 139 | ct = nf_ct_get(*pskb, &ctinfo); |
| @@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
| 140 | return NF_ACCEPT; | 141 | return NF_ACCEPT; |
| 141 | 142 | ||
| 142 | help = nfct_help(ct); | 143 | help = nfct_help(ct); |
| 143 | if (!help || !help->helper) | 144 | if (!help) |
| 144 | return NF_ACCEPT; | 145 | return NF_ACCEPT; |
| 145 | 146 | /* rcu_read_lock()ed by nf_hook_slow */ | |
| 146 | return help->helper->help(pskb, | 147 | helper = rcu_dereference(help->helper); |
| 147 | skb_network_offset(*pskb) + ip_hdrlen(*pskb), | 148 | if (!helper) |
| 148 | ct, ctinfo); | 149 | return NF_ACCEPT; |
| 150 | return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb), | ||
| 151 | ct, ctinfo); | ||
| 149 | } | 152 | } |
| 150 | 153 | ||
| 151 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 154 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, |
| @@ -154,12 +157,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
| 154 | const struct net_device *out, | 157 | const struct net_device *out, |
| 155 | int (*okfn)(struct sk_buff *)) | 158 | int (*okfn)(struct sk_buff *)) |
| 156 | { | 159 | { |
| 157 | #if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE) | ||
| 158 | /* Previously seen (loopback)? Ignore. Do this before | 160 | /* Previously seen (loopback)? Ignore. Do this before |
| 159 | fragment check. */ | 161 | fragment check. */ |
| 160 | if ((*pskb)->nfct) | 162 | if ((*pskb)->nfct) |
| 161 | return NF_ACCEPT; | 163 | return NF_ACCEPT; |
| 162 | #endif | ||
| 163 | 164 | ||
| 164 | /* Gather fragments. */ | 165 | /* Gather fragments. */ |
| 165 | if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 166 | if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c index 751b59801755..e6bc8e5a72f1 100644 --- a/net/ipv4/netfilter/nf_nat_ftp.c +++ b/net/ipv4/netfilter/nf_nat_ftp.c | |||
| @@ -40,8 +40,7 @@ mangle_rfc959_packet(struct sk_buff **pskb, | |||
| 40 | unsigned int matchoff, | 40 | unsigned int matchoff, |
| 41 | unsigned int matchlen, | 41 | unsigned int matchlen, |
| 42 | struct nf_conn *ct, | 42 | struct nf_conn *ct, |
| 43 | enum ip_conntrack_info ctinfo, | 43 | enum ip_conntrack_info ctinfo) |
| 44 | u32 *seq) | ||
| 45 | { | 44 | { |
| 46 | char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")]; | 45 | char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")]; |
| 47 | 46 | ||
| @@ -50,7 +49,6 @@ mangle_rfc959_packet(struct sk_buff **pskb, | |||
| 50 | 49 | ||
| 51 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); | 50 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); |
| 52 | 51 | ||
| 53 | *seq += strlen(buffer) - matchlen; | ||
| 54 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, | 52 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, |
| 55 | matchlen, buffer, strlen(buffer)); | 53 | matchlen, buffer, strlen(buffer)); |
| 56 | } | 54 | } |
| @@ -63,8 +61,7 @@ mangle_eprt_packet(struct sk_buff **pskb, | |||
| 63 | unsigned int matchoff, | 61 | unsigned int matchoff, |
| 64 | unsigned int matchlen, | 62 | unsigned int matchlen, |
| 65 | struct nf_conn *ct, | 63 | struct nf_conn *ct, |
| 66 | enum ip_conntrack_info ctinfo, | 64 | enum ip_conntrack_info ctinfo) |
| 67 | u32 *seq) | ||
| 68 | { | 65 | { |
| 69 | char buffer[sizeof("|1|255.255.255.255|65535|")]; | 66 | char buffer[sizeof("|1|255.255.255.255|65535|")]; |
| 70 | 67 | ||
| @@ -72,7 +69,6 @@ mangle_eprt_packet(struct sk_buff **pskb, | |||
| 72 | 69 | ||
| 73 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); | 70 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); |
| 74 | 71 | ||
| 75 | *seq += strlen(buffer) - matchlen; | ||
| 76 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, | 72 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, |
| 77 | matchlen, buffer, strlen(buffer)); | 73 | matchlen, buffer, strlen(buffer)); |
| 78 | } | 74 | } |
| @@ -85,8 +81,7 @@ mangle_epsv_packet(struct sk_buff **pskb, | |||
| 85 | unsigned int matchoff, | 81 | unsigned int matchoff, |
| 86 | unsigned int matchlen, | 82 | unsigned int matchlen, |
| 87 | struct nf_conn *ct, | 83 | struct nf_conn *ct, |
| 88 | enum ip_conntrack_info ctinfo, | 84 | enum ip_conntrack_info ctinfo) |
| 89 | u32 *seq) | ||
| 90 | { | 85 | { |
| 91 | char buffer[sizeof("|||65535|")]; | 86 | char buffer[sizeof("|||65535|")]; |
| 92 | 87 | ||
| @@ -94,14 +89,13 @@ mangle_epsv_packet(struct sk_buff **pskb, | |||
| 94 | 89 | ||
| 95 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); | 90 | DEBUGP("calling nf_nat_mangle_tcp_packet\n"); |
| 96 | 91 | ||
| 97 | *seq += strlen(buffer) - matchlen; | ||
| 98 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, | 92 | return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, |
| 99 | matchlen, buffer, strlen(buffer)); | 93 | matchlen, buffer, strlen(buffer)); |
| 100 | } | 94 | } |
| 101 | 95 | ||
| 102 | static int (*mangle[])(struct sk_buff **, __be32, u_int16_t, | 96 | static int (*mangle[])(struct sk_buff **, __be32, u_int16_t, |
| 103 | unsigned int, unsigned int, struct nf_conn *, | 97 | unsigned int, unsigned int, struct nf_conn *, |
| 104 | enum ip_conntrack_info, u32 *seq) | 98 | enum ip_conntrack_info) |
| 105 | = { | 99 | = { |
| 106 | [NF_CT_FTP_PORT] = mangle_rfc959_packet, | 100 | [NF_CT_FTP_PORT] = mangle_rfc959_packet, |
| 107 | [NF_CT_FTP_PASV] = mangle_rfc959_packet, | 101 | [NF_CT_FTP_PASV] = mangle_rfc959_packet, |
| @@ -116,8 +110,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb, | |||
| 116 | enum nf_ct_ftp_type type, | 110 | enum nf_ct_ftp_type type, |
| 117 | unsigned int matchoff, | 111 | unsigned int matchoff, |
| 118 | unsigned int matchlen, | 112 | unsigned int matchlen, |
| 119 | struct nf_conntrack_expect *exp, | 113 | struct nf_conntrack_expect *exp) |
| 120 | u32 *seq) | ||
| 121 | { | 114 | { |
| 122 | __be32 newip; | 115 | __be32 newip; |
| 123 | u_int16_t port; | 116 | u_int16_t port; |
| @@ -145,8 +138,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb, | |||
| 145 | if (port == 0) | 138 | if (port == 0) |
| 146 | return NF_DROP; | 139 | return NF_DROP; |
| 147 | 140 | ||
| 148 | if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo, | 141 | if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) { |
| 149 | seq)) { | ||
| 150 | nf_conntrack_unexpect_related(exp); | 142 | nf_conntrack_unexpect_related(exp); |
| 151 | return NF_DROP; | 143 | return NF_DROP; |
| 152 | } | 144 | } |
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index fcebc968d37f..c5d2a2d690b8 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c | |||
| @@ -455,9 +455,9 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct, | |||
| 455 | if (idx > 0 && | 455 | if (idx > 0 && |
| 456 | get_h225_addr(ct, *data, &taddr[0], &addr, &port) && | 456 | get_h225_addr(ct, *data, &taddr[0], &addr, &port) && |
| 457 | (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { | 457 | (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { |
| 458 | set_h225_addr_hook(pskb, data, 0, &taddr[0], | 458 | set_h225_addr(pskb, data, 0, &taddr[0], |
| 459 | &ct->tuplehash[!dir].tuple.dst.u3, | 459 | &ct->tuplehash[!dir].tuple.dst.u3, |
| 460 | info->sig_port[!dir]); | 460 | info->sig_port[!dir]); |
| 461 | } | 461 | } |
| 462 | } else { | 462 | } else { |
| 463 | nf_conntrack_unexpect_related(exp); | 463 | nf_conntrack_unexpect_related(exp); |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index 2534f718ab92..6740736c5e79 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
| @@ -46,77 +46,20 @@ static struct | |||
| 46 | .hook_entry = { | 46 | .hook_entry = { |
| 47 | [NF_IP_PRE_ROUTING] = 0, | 47 | [NF_IP_PRE_ROUTING] = 0, |
| 48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), | 48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), |
| 49 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 49 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 |
| 50 | }, | ||
| 50 | .underflow = { | 51 | .underflow = { |
| 51 | [NF_IP_PRE_ROUTING] = 0, | 52 | [NF_IP_PRE_ROUTING] = 0, |
| 52 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), | 53 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), |
| 53 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 54 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 |
| 55 | }, | ||
| 54 | }, | 56 | }, |
| 55 | .entries = { | 57 | .entries = { |
| 56 | /* PRE_ROUTING */ | 58 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
| 57 | { | 59 | IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
| 58 | .entry = { | 60 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 59 | .target_offset = sizeof(struct ipt_entry), | ||
| 60 | .next_offset = sizeof(struct ipt_standard), | ||
| 61 | }, | ||
| 62 | .target = { | ||
| 63 | .target = { | ||
| 64 | .u = { | ||
| 65 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
| 66 | }, | ||
| 67 | }, | ||
| 68 | .verdict = -NF_ACCEPT - 1, | ||
| 69 | }, | ||
| 70 | }, | ||
| 71 | /* POST_ROUTING */ | ||
| 72 | { | ||
| 73 | .entry = { | ||
| 74 | .target_offset = sizeof(struct ipt_entry), | ||
| 75 | .next_offset = sizeof(struct ipt_standard), | ||
| 76 | }, | ||
| 77 | .target = { | ||
| 78 | .target = { | ||
| 79 | .u = { | ||
| 80 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
| 81 | }, | ||
| 82 | }, | ||
| 83 | .verdict = -NF_ACCEPT - 1, | ||
| 84 | }, | ||
| 85 | }, | ||
| 86 | /* LOCAL_OUT */ | ||
| 87 | { | ||
| 88 | .entry = { | ||
| 89 | .target_offset = sizeof(struct ipt_entry), | ||
| 90 | .next_offset = sizeof(struct ipt_standard), | ||
| 91 | }, | ||
| 92 | .target = { | ||
| 93 | .target = { | ||
| 94 | .u = { | ||
| 95 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
| 96 | }, | ||
| 97 | }, | ||
| 98 | .verdict = -NF_ACCEPT - 1, | ||
| 99 | }, | ||
| 100 | }, | ||
| 101 | }, | 61 | }, |
| 102 | /* ERROR */ | 62 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 103 | .term = { | ||
| 104 | .entry = { | ||
| 105 | .target_offset = sizeof(struct ipt_entry), | ||
| 106 | .next_offset = sizeof(struct ipt_error), | ||
| 107 | }, | ||
| 108 | .target = { | ||
| 109 | .target = { | ||
| 110 | .u = { | ||
| 111 | .user = { | ||
| 112 | .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), | ||
| 113 | .name = IPT_ERROR_TARGET, | ||
| 114 | }, | ||
| 115 | }, | ||
| 116 | }, | ||
| 117 | .errorname = "ERROR", | ||
| 118 | }, | ||
| 119 | } | ||
| 120 | }; | 63 | }; |
| 121 | 64 | ||
| 122 | static struct xt_table nat_table = { | 65 | static struct xt_table nat_table = { |
| @@ -230,9 +173,7 @@ static int ipt_dnat_checkentry(const char *tablename, | |||
| 230 | } | 173 | } |
| 231 | 174 | ||
| 232 | inline unsigned int | 175 | inline unsigned int |
| 233 | alloc_null_binding(struct nf_conn *ct, | 176 | alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) |
| 234 | struct nf_nat_info *info, | ||
| 235 | unsigned int hooknum) | ||
| 236 | { | 177 | { |
| 237 | /* Force range to this IP; let proto decide mapping for | 178 | /* Force range to this IP; let proto decide mapping for |
| 238 | per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). | 179 | per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). |
| @@ -251,9 +192,7 @@ alloc_null_binding(struct nf_conn *ct, | |||
| 251 | } | 192 | } |
| 252 | 193 | ||
| 253 | unsigned int | 194 | unsigned int |
| 254 | alloc_null_binding_confirmed(struct nf_conn *ct, | 195 | alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum) |
| 255 | struct nf_nat_info *info, | ||
| 256 | unsigned int hooknum) | ||
| 257 | { | 196 | { |
| 258 | __be32 ip | 197 | __be32 ip |
| 259 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | 198 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC |
| @@ -275,8 +214,7 @@ int nf_nat_rule_find(struct sk_buff **pskb, | |||
| 275 | unsigned int hooknum, | 214 | unsigned int hooknum, |
| 276 | const struct net_device *in, | 215 | const struct net_device *in, |
| 277 | const struct net_device *out, | 216 | const struct net_device *out, |
| 278 | struct nf_conn *ct, | 217 | struct nf_conn *ct) |
| 279 | struct nf_nat_info *info) | ||
| 280 | { | 218 | { |
| 281 | int ret; | 219 | int ret; |
| 282 | 220 | ||
| @@ -285,7 +223,7 @@ int nf_nat_rule_find(struct sk_buff **pskb, | |||
| 285 | if (ret == NF_ACCEPT) { | 223 | if (ret == NF_ACCEPT) { |
| 286 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) | 224 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) |
| 287 | /* NUL mapping */ | 225 | /* NUL mapping */ |
| 288 | ret = alloc_null_binding(ct, info, hooknum); | 226 | ret = alloc_null_binding(ct, hooknum); |
| 289 | } | 227 | } |
| 290 | return ret; | 228 | return ret; |
| 291 | } | 229 | } |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 64bbed2ba780..55dac36dbc85 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
| @@ -80,7 +80,6 @@ nf_nat_fn(unsigned int hooknum, | |||
| 80 | struct nf_conn *ct; | 80 | struct nf_conn *ct; |
| 81 | enum ip_conntrack_info ctinfo; | 81 | enum ip_conntrack_info ctinfo; |
| 82 | struct nf_conn_nat *nat; | 82 | struct nf_conn_nat *nat; |
| 83 | struct nf_nat_info *info; | ||
| 84 | /* maniptype == SRC for postrouting. */ | 83 | /* maniptype == SRC for postrouting. */ |
| 85 | enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum); | 84 | enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum); |
| 86 | 85 | ||
| @@ -129,7 +128,6 @@ nf_nat_fn(unsigned int hooknum, | |||
| 129 | } | 128 | } |
| 130 | /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ | 129 | /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ |
| 131 | case IP_CT_NEW: | 130 | case IP_CT_NEW: |
| 132 | info = &nat->info; | ||
| 133 | 131 | ||
| 134 | /* Seen it before? This can happen for loopback, retrans, | 132 | /* Seen it before? This can happen for loopback, retrans, |
| 135 | or local packets.. */ | 133 | or local packets.. */ |
| @@ -138,14 +136,13 @@ nf_nat_fn(unsigned int hooknum, | |||
| 138 | 136 | ||
| 139 | if (unlikely(nf_ct_is_confirmed(ct))) | 137 | if (unlikely(nf_ct_is_confirmed(ct))) |
| 140 | /* NAT module was loaded late */ | 138 | /* NAT module was loaded late */ |
| 141 | ret = alloc_null_binding_confirmed(ct, info, | 139 | ret = alloc_null_binding_confirmed(ct, hooknum); |
| 142 | hooknum); | ||
| 143 | else if (hooknum == NF_IP_LOCAL_IN) | 140 | else if (hooknum == NF_IP_LOCAL_IN) |
| 144 | /* LOCAL_IN hook doesn't have a chain! */ | 141 | /* LOCAL_IN hook doesn't have a chain! */ |
| 145 | ret = alloc_null_binding(ct, info, hooknum); | 142 | ret = alloc_null_binding(ct, hooknum); |
| 146 | else | 143 | else |
| 147 | ret = nf_nat_rule_find(pskb, hooknum, in, out, | 144 | ret = nf_nat_rule_find(pskb, hooknum, in, out, |
| 148 | ct, info); | 145 | ct); |
| 149 | 146 | ||
| 150 | if (ret != NF_ACCEPT) { | 147 | if (ret != NF_ACCEPT) { |
| 151 | return ret; | 148 | return ret; |
| @@ -160,10 +157,8 @@ nf_nat_fn(unsigned int hooknum, | |||
| 160 | /* ESTABLISHED */ | 157 | /* ESTABLISHED */ |
| 161 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || | 158 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || |
| 162 | ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); | 159 | ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); |
| 163 | info = &nat->info; | ||
| 164 | } | 160 | } |
| 165 | 161 | ||
| 166 | NF_CT_ASSERT(info); | ||
| 167 | return nf_nat_packet(ct, ctinfo, hooknum, pskb); | 162 | return nf_nat_packet(ct, ctinfo, hooknum, pskb); |
| 168 | } | 163 | } |
| 169 | 164 | ||
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 37ab5802ca08..3b690cf2a4ee 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -109,6 +109,17 @@ static const struct snmp_mib snmp4_ipstats_list[] = { | |||
| 109 | SNMP_MIB_SENTINEL | 109 | SNMP_MIB_SENTINEL |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | /* Following RFC4293 items are displayed in /proc/net/netstat */ | ||
| 113 | static const struct snmp_mib snmp4_ipextstats_list[] = { | ||
| 114 | SNMP_MIB_ITEM("InNoRoutes", IPSTATS_MIB_INNOROUTES), | ||
| 115 | SNMP_MIB_ITEM("InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS), | ||
| 116 | SNMP_MIB_ITEM("InMcastPkts", IPSTATS_MIB_INMCASTPKTS), | ||
| 117 | SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), | ||
| 118 | SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), | ||
| 119 | SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), | ||
| 120 | SNMP_MIB_SENTINEL | ||
| 121 | }; | ||
| 122 | |||
| 112 | static const struct snmp_mib snmp4_icmp_list[] = { | 123 | static const struct snmp_mib snmp4_icmp_list[] = { |
| 113 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), | 124 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), |
| 114 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), | 125 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), |
| @@ -249,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 249 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); | 260 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); |
| 250 | 261 | ||
| 251 | seq_printf(seq, "\nIp: %d %d", | 262 | seq_printf(seq, "\nIp: %d %d", |
| 252 | ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); | 263 | IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl); |
| 253 | 264 | ||
| 254 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) | 265 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) |
| 255 | seq_printf(seq, " %lu", | 266 | seq_printf(seq, " %lu", |
| @@ -338,6 +349,16 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
| 338 | snmp_fold_field((void **)net_statistics, | 349 | snmp_fold_field((void **)net_statistics, |
| 339 | snmp4_net_list[i].entry)); | 350 | snmp4_net_list[i].entry)); |
| 340 | 351 | ||
| 352 | seq_puts(seq, "\nIpExt:"); | ||
| 353 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) | ||
| 354 | seq_printf(seq, " %s", snmp4_ipextstats_list[i].name); | ||
| 355 | |||
| 356 | seq_puts(seq, "\nIpExt:"); | ||
| 357 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) | ||
| 358 | seq_printf(seq, " %lu", | ||
| 359 | snmp_fold_field((void **)ip_statistics, | ||
| 360 | snmp4_ipextstats_list[i].entry)); | ||
| 361 | |||
| 341 | seq_putc(seq, '\n'); | 362 | seq_putc(seq, '\n'); |
| 342 | return 0; | 363 | return 0; |
| 343 | } | 364 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index cb76e3c725a0..29ca63e81ced 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1636 | 1636 | ||
| 1637 | atomic_set(&rth->u.dst.__refcnt, 1); | 1637 | atomic_set(&rth->u.dst.__refcnt, 1); |
| 1638 | rth->u.dst.flags= DST_HOST; | 1638 | rth->u.dst.flags= DST_HOST; |
| 1639 | if (in_dev->cnf.no_policy) | 1639 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
| 1640 | rth->u.dst.flags |= DST_NOPOLICY; | 1640 | rth->u.dst.flags |= DST_NOPOLICY; |
| 1641 | rth->fl.fl4_dst = daddr; | 1641 | rth->fl.fl4_dst = daddr; |
| 1642 | rth->rt_dst = daddr; | 1642 | rth->rt_dst = daddr; |
| @@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb, | |||
| 1778 | if (res->fi->fib_nhs > 1) | 1778 | if (res->fi->fib_nhs > 1) |
| 1779 | rth->u.dst.flags |= DST_BALANCED; | 1779 | rth->u.dst.flags |= DST_BALANCED; |
| 1780 | #endif | 1780 | #endif |
| 1781 | if (in_dev->cnf.no_policy) | 1781 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
| 1782 | rth->u.dst.flags |= DST_NOPOLICY; | 1782 | rth->u.dst.flags |= DST_NOPOLICY; |
| 1783 | if (out_dev->cnf.no_xfrm) | 1783 | if (IN_DEV_CONF_GET(out_dev, NOXFRM)) |
| 1784 | rth->u.dst.flags |= DST_NOXFRM; | 1784 | rth->u.dst.flags |= DST_NOXFRM; |
| 1785 | rth->fl.fl4_dst = daddr; | 1785 | rth->fl.fl4_dst = daddr; |
| 1786 | rth->rt_dst = daddr; | 1786 | rth->rt_dst = daddr; |
| @@ -2021,7 +2021,7 @@ local_input: | |||
| 2021 | 2021 | ||
| 2022 | atomic_set(&rth->u.dst.__refcnt, 1); | 2022 | atomic_set(&rth->u.dst.__refcnt, 1); |
| 2023 | rth->u.dst.flags= DST_HOST; | 2023 | rth->u.dst.flags= DST_HOST; |
| 2024 | if (in_dev->cnf.no_policy) | 2024 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
| 2025 | rth->u.dst.flags |= DST_NOPOLICY; | 2025 | rth->u.dst.flags |= DST_NOPOLICY; |
| 2026 | rth->fl.fl4_dst = daddr; | 2026 | rth->fl.fl4_dst = daddr; |
| 2027 | rth->rt_dst = daddr; | 2027 | rth->rt_dst = daddr; |
| @@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result, | |||
| 2218 | rth->u.dst.flags |= DST_BALANCED; | 2218 | rth->u.dst.flags |= DST_BALANCED; |
| 2219 | } | 2219 | } |
| 2220 | #endif | 2220 | #endif |
| 2221 | if (in_dev->cnf.no_xfrm) | 2221 | if (IN_DEV_CONF_GET(in_dev, NOXFRM)) |
| 2222 | rth->u.dst.flags |= DST_NOXFRM; | 2222 | rth->u.dst.flags |= DST_NOXFRM; |
| 2223 | if (in_dev->cnf.no_policy) | 2223 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
| 2224 | rth->u.dst.flags |= DST_NOPOLICY; | 2224 | rth->u.dst.flags |= DST_NOPOLICY; |
| 2225 | 2225 | ||
| 2226 | rth->fl.fl4_dst = oldflp->fl4_dst; | 2226 | rth->fl.fl4_dst = oldflp->fl4_dst; |
| @@ -2396,7 +2396,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) | |||
| 2396 | 2396 | ||
| 2397 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ | 2397 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ |
| 2398 | dev_out = ip_dev_find(oldflp->fl4_src); | 2398 | dev_out = ip_dev_find(oldflp->fl4_src); |
| 2399 | if ((dev_out == NULL) && !(sysctl_ip_nonlocal_bind)) | 2399 | if (dev_out == NULL) |
| 2400 | goto out; | 2400 | goto out; |
| 2401 | 2401 | ||
| 2402 | /* I removed check for oif == dev_out->oif here. | 2402 | /* I removed check for oif == dev_out->oif here. |
| @@ -2407,7 +2407,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) | |||
| 2407 | of another iface. --ANK | 2407 | of another iface. --ANK |
| 2408 | */ | 2408 | */ |
| 2409 | 2409 | ||
| 2410 | if (dev_out && oldflp->oif == 0 | 2410 | if (oldflp->oif == 0 |
| 2411 | && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) { | 2411 | && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) { |
| 2412 | /* Special hack: user can direct multicasts | 2412 | /* Special hack: user can direct multicasts |
| 2413 | and limited broadcast via necessary interface | 2413 | and limited broadcast via necessary interface |
| @@ -2598,6 +2598,69 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) | |||
| 2598 | 2598 | ||
| 2599 | EXPORT_SYMBOL_GPL(__ip_route_output_key); | 2599 | EXPORT_SYMBOL_GPL(__ip_route_output_key); |
| 2600 | 2600 | ||
| 2601 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | ||
| 2602 | { | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | static struct dst_ops ipv4_dst_blackhole_ops = { | ||
| 2606 | .family = AF_INET, | ||
| 2607 | .protocol = __constant_htons(ETH_P_IP), | ||
| 2608 | .destroy = ipv4_dst_destroy, | ||
| 2609 | .check = ipv4_dst_check, | ||
| 2610 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | ||
| 2611 | .entry_size = sizeof(struct rtable), | ||
| 2612 | }; | ||
| 2613 | |||
| 2614 | |||
| 2615 | static int ipv4_blackhole_output(struct sk_buff *skb) | ||
| 2616 | { | ||
| 2617 | kfree_skb(skb); | ||
| 2618 | return 0; | ||
| 2619 | } | ||
| 2620 | |||
| 2621 | static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk) | ||
| 2622 | { | ||
| 2623 | struct rtable *ort = *rp; | ||
| 2624 | struct rtable *rt = (struct rtable *) | ||
| 2625 | dst_alloc(&ipv4_dst_blackhole_ops); | ||
| 2626 | |||
| 2627 | if (rt) { | ||
| 2628 | struct dst_entry *new = &rt->u.dst; | ||
| 2629 | |||
| 2630 | atomic_set(&new->__refcnt, 1); | ||
| 2631 | new->__use = 1; | ||
| 2632 | new->input = ipv4_blackhole_output; | ||
| 2633 | new->output = ipv4_blackhole_output; | ||
| 2634 | memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); | ||
| 2635 | |||
| 2636 | new->dev = ort->u.dst.dev; | ||
| 2637 | if (new->dev) | ||
| 2638 | dev_hold(new->dev); | ||
| 2639 | |||
| 2640 | rt->fl = ort->fl; | ||
| 2641 | |||
| 2642 | rt->idev = ort->idev; | ||
| 2643 | if (rt->idev) | ||
| 2644 | in_dev_hold(rt->idev); | ||
| 2645 | rt->rt_flags = ort->rt_flags; | ||
| 2646 | rt->rt_type = ort->rt_type; | ||
| 2647 | rt->rt_dst = ort->rt_dst; | ||
| 2648 | rt->rt_src = ort->rt_src; | ||
| 2649 | rt->rt_iif = ort->rt_iif; | ||
| 2650 | rt->rt_gateway = ort->rt_gateway; | ||
| 2651 | rt->rt_spec_dst = ort->rt_spec_dst; | ||
| 2652 | rt->peer = ort->peer; | ||
| 2653 | if (rt->peer) | ||
| 2654 | atomic_inc(&rt->peer->refcnt); | ||
| 2655 | |||
| 2656 | dst_free(new); | ||
| 2657 | } | ||
| 2658 | |||
| 2659 | dst_release(&(*rp)->u.dst); | ||
| 2660 | *rp = rt; | ||
| 2661 | return (rt ? 0 : -ENOMEM); | ||
| 2662 | } | ||
| 2663 | |||
| 2601 | int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags) | 2664 | int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags) |
| 2602 | { | 2665 | { |
| 2603 | int err; | 2666 | int err; |
| @@ -2610,7 +2673,11 @@ int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, | |||
| 2610 | flp->fl4_src = (*rp)->rt_src; | 2673 | flp->fl4_src = (*rp)->rt_src; |
| 2611 | if (!flp->fl4_dst) | 2674 | if (!flp->fl4_dst) |
| 2612 | flp->fl4_dst = (*rp)->rt_dst; | 2675 | flp->fl4_dst = (*rp)->rt_dst; |
| 2613 | return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags); | 2676 | err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags); |
| 2677 | if (err == -EREMOTE) | ||
| 2678 | err = ipv4_dst_blackhole(rp, flp, sk); | ||
| 2679 | |||
| 2680 | return err; | ||
| 2614 | } | 2681 | } |
| 2615 | 2682 | ||
| 2616 | return 0; | 2683 | return 0; |
| @@ -2692,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
| 2692 | __be32 dst = rt->rt_dst; | 2759 | __be32 dst = rt->rt_dst; |
| 2693 | 2760 | ||
| 2694 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && | 2761 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && |
| 2695 | ipv4_devconf.mc_forwarding) { | 2762 | IPV4_DEVCONF_ALL(MC_FORWARDING)) { |
| 2696 | int err = ipmr_get_route(skb, r, nowait); | 2763 | int err = ipmr_get_route(skb, r, nowait); |
| 2697 | if (err <= 0) { | 2764 | if (err <= 0) { |
| 2698 | if (!nowait) { | 2765 | if (!nowait) { |
| @@ -3139,6 +3206,8 @@ int __init ip_rt_init(void) | |||
| 3139 | kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, | 3206 | kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, |
| 3140 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 3207 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
| 3141 | 3208 | ||
| 3209 | ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep; | ||
| 3210 | |||
| 3142 | rt_hash_table = (struct rt_hash_bucket *) | 3211 | rt_hash_table = (struct rt_hash_bucket *) |
| 3143 | alloc_large_system_hash("IP route cache", | 3212 | alloc_large_system_hash("IP route cache", |
| 3144 | sizeof(struct rt_hash_bucket), | 3213 | sizeof(struct rt_hash_bucket), |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 6817d6485df5..53ef0f4bbdaa 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
| @@ -37,12 +37,12 @@ static | |||
| 37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, | 37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, |
| 38 | void __user *buffer, size_t *lenp, loff_t *ppos) | 38 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 39 | { | 39 | { |
| 40 | int val = ipv4_devconf.forwarding; | 40 | int val = IPV4_DEVCONF_ALL(FORWARDING); |
| 41 | int ret; | 41 | int ret; |
| 42 | 42 | ||
| 43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
| 44 | 44 | ||
| 45 | if (write && ipv4_devconf.forwarding != val) | 45 | if (write && IPV4_DEVCONF_ALL(FORWARDING) != val) |
| 46 | inet_forward_change(); | 46 | inet_forward_change(); |
| 47 | 47 | ||
| 48 | return ret; | 48 | return ret; |
| @@ -222,7 +222,7 @@ ctl_table ipv4_table[] = { | |||
| 222 | { | 222 | { |
| 223 | .ctl_name = NET_IPV4_FORWARD, | 223 | .ctl_name = NET_IPV4_FORWARD, |
| 224 | .procname = "ip_forward", | 224 | .procname = "ip_forward", |
| 225 | .data = &ipv4_devconf.forwarding, | 225 | .data = &IPV4_DEVCONF_ALL(FORWARDING), |
| 226 | .maxlen = sizeof(int), | 226 | .maxlen = sizeof(int), |
| 227 | .mode = 0644, | 227 | .mode = 0644, |
| 228 | .proc_handler = &ipv4_sysctl_forward, | 228 | .proc_handler = &ipv4_sysctl_forward, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8b124eafbb90..cd3c7e95de9e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -252,7 +252,6 @@ | |||
| 252 | #include <linux/fcntl.h> | 252 | #include <linux/fcntl.h> |
| 253 | #include <linux/poll.h> | 253 | #include <linux/poll.h> |
| 254 | #include <linux/init.h> | 254 | #include <linux/init.h> |
| 255 | #include <linux/smp_lock.h> | ||
| 256 | #include <linux/fs.h> | 255 | #include <linux/fs.h> |
| 257 | #include <linux/random.h> | 256 | #include <linux/random.h> |
| 258 | #include <linux/bootmem.h> | 257 | #include <linux/bootmem.h> |
| @@ -1675,9 +1674,8 @@ adjudge_to_death: | |||
| 1675 | } | 1674 | } |
| 1676 | if (sk->sk_state != TCP_CLOSE) { | 1675 | if (sk->sk_state != TCP_CLOSE) { |
| 1677 | sk_stream_mem_reclaim(sk); | 1676 | sk_stream_mem_reclaim(sk); |
| 1678 | if (atomic_read(sk->sk_prot->orphan_count) > sysctl_tcp_max_orphans || | 1677 | if (tcp_too_many_orphans(sk, |
| 1679 | (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | 1678 | atomic_read(sk->sk_prot->orphan_count))) { |
| 1680 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { | ||
| 1681 | if (net_ratelimit()) | 1679 | if (net_ratelimit()) |
| 1682 | printk(KERN_INFO "TCP: too many of orphaned " | 1680 | printk(KERN_INFO "TCP: too many of orphaned " |
| 1683 | "sockets\n"); | 1681 | "sockets\n"); |
| @@ -2466,13 +2464,10 @@ void __init tcp_init(void) | |||
| 2466 | order++) | 2464 | order++) |
| 2467 | ; | 2465 | ; |
| 2468 | if (order >= 4) { | 2466 | if (order >= 4) { |
| 2469 | sysctl_local_port_range[0] = 32768; | ||
| 2470 | sysctl_local_port_range[1] = 61000; | ||
| 2471 | tcp_death_row.sysctl_max_tw_buckets = 180000; | 2467 | tcp_death_row.sysctl_max_tw_buckets = 180000; |
| 2472 | sysctl_tcp_max_orphans = 4096 << (order - 4); | 2468 | sysctl_tcp_max_orphans = 4096 << (order - 4); |
| 2473 | sysctl_max_syn_backlog = 1024; | 2469 | sysctl_max_syn_backlog = 1024; |
| 2474 | } else if (order < 3) { | 2470 | } else if (order < 3) { |
| 2475 | sysctl_local_port_range[0] = 1024 * (3 - order); | ||
| 2476 | tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); | 2471 | tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); |
| 2477 | sysctl_tcp_max_orphans >>= (3 - order); | 2472 | sysctl_tcp_max_orphans >>= (3 - order); |
| 2478 | sysctl_max_syn_backlog = 128; | 2473 | sysctl_max_syn_backlog = 128; |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 86b26539e54b..1260e52ad772 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -276,30 +276,34 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
| 276 | 276 | ||
| 277 | 277 | ||
| 278 | /* | 278 | /* |
| 279 | * Slow start (exponential increase) with | 279 | * Slow start is used when congestion window is less than slow start |
| 280 | * RFC3742 Limited Slow Start (fast linear increase) support. | 280 | * threshold. This version implements the basic RFC2581 version |
| 281 | * and optionally supports: | ||
| 282 | * RFC3742 Limited Slow Start - growth limited to max_ssthresh | ||
| 283 | * RFC3465 Appropriate Byte Counting - growth limited by bytes acknowledged | ||
| 281 | */ | 284 | */ |
| 282 | void tcp_slow_start(struct tcp_sock *tp) | 285 | void tcp_slow_start(struct tcp_sock *tp) |
| 283 | { | 286 | { |
| 284 | int cnt = 0; | 287 | int cnt; /* increase in packets */ |
| 285 | 288 | ||
| 286 | if (sysctl_tcp_abc) { | 289 | /* RFC3465: ABC Slow start |
| 287 | /* RFC3465: Slow Start | 290 | * Increase only after a full MSS of bytes is acked |
| 288 | * TCP sender SHOULD increase cwnd by the number of | 291 | * |
| 289 | * previously unacknowledged bytes ACKed by each incoming | 292 | * TCP sender SHOULD increase cwnd by the number of |
| 290 | * acknowledgment, provided the increase is not more than L | 293 | * previously unacknowledged bytes ACKed by each incoming |
| 291 | */ | 294 | * acknowledgment, provided the increase is not more than L |
| 292 | if (tp->bytes_acked < tp->mss_cache) | 295 | */ |
| 293 | return; | 296 | if (sysctl_tcp_abc && tp->bytes_acked < tp->mss_cache) |
| 294 | } | 297 | return; |
| 295 | 298 | ||
| 296 | if (sysctl_tcp_max_ssthresh > 0 && | 299 | if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh) |
| 297 | tp->snd_cwnd > sysctl_tcp_max_ssthresh) | 300 | cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */ |
| 298 | cnt += sysctl_tcp_max_ssthresh>>1; | ||
| 299 | else | 301 | else |
| 300 | cnt += tp->snd_cwnd; | 302 | cnt = tp->snd_cwnd; /* exponential increase */ |
| 301 | 303 | ||
| 302 | /* RFC3465: We MAY increase by 2 if discovered delayed ack */ | 304 | /* RFC3465: ABC |
| 305 | * We MAY increase by 2 if discovered delayed ack | ||
| 306 | */ | ||
| 303 | if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) | 307 | if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) |
| 304 | cnt <<= 1; | 308 | cnt <<= 1; |
| 305 | tp->bytes_acked = 0; | 309 | tp->bytes_acked = 0; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 7641b2761a14..74683d81c3f1 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -1501,6 +1501,8 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
| 1501 | tcp_set_ca_state(sk, TCP_CA_Loss); | 1501 | tcp_set_ca_state(sk, TCP_CA_Loss); |
| 1502 | tp->high_seq = tp->snd_nxt; | 1502 | tp->high_seq = tp->snd_nxt; |
| 1503 | TCP_ECN_queue_cwr(tp); | 1503 | TCP_ECN_queue_cwr(tp); |
| 1504 | /* Abort FRTO algorithm if one is in progress */ | ||
| 1505 | tp->frto_counter = 0; | ||
| 1504 | 1506 | ||
| 1505 | clear_all_retrans_hints(tp); | 1507 | clear_all_retrans_hints(tp); |
| 1506 | } | 1508 | } |
| @@ -2405,8 +2407,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
| 2405 | struct sk_buff *skb; | 2407 | struct sk_buff *skb; |
| 2406 | __u32 now = tcp_time_stamp; | 2408 | __u32 now = tcp_time_stamp; |
| 2407 | int acked = 0; | 2409 | int acked = 0; |
| 2410 | int prior_packets = tp->packets_out; | ||
| 2408 | __s32 seq_rtt = -1; | 2411 | __s32 seq_rtt = -1; |
| 2409 | u32 pkts_acked = 0; | ||
| 2410 | ktime_t last_ackt = ktime_set(0,0); | 2412 | ktime_t last_ackt = ktime_set(0,0); |
| 2411 | 2413 | ||
| 2412 | while ((skb = tcp_write_queue_head(sk)) && | 2414 | while ((skb = tcp_write_queue_head(sk)) && |
| @@ -2435,7 +2437,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
| 2435 | */ | 2437 | */ |
| 2436 | if (!(scb->flags & TCPCB_FLAG_SYN)) { | 2438 | if (!(scb->flags & TCPCB_FLAG_SYN)) { |
| 2437 | acked |= FLAG_DATA_ACKED; | 2439 | acked |= FLAG_DATA_ACKED; |
| 2438 | ++pkts_acked; | ||
| 2439 | } else { | 2440 | } else { |
| 2440 | acked |= FLAG_SYN_ACKED; | 2441 | acked |= FLAG_SYN_ACKED; |
| 2441 | tp->retrans_stamp = 0; | 2442 | tp->retrans_stamp = 0; |
| @@ -2479,6 +2480,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
| 2479 | } | 2480 | } |
| 2480 | 2481 | ||
| 2481 | if (acked&FLAG_ACKED) { | 2482 | if (acked&FLAG_ACKED) { |
| 2483 | u32 pkts_acked = prior_packets - tp->packets_out; | ||
| 2482 | const struct tcp_congestion_ops *ca_ops | 2484 | const struct tcp_congestion_ops *ca_ops |
| 2483 | = inet_csk(sk)->icsk_ca_ops; | 2485 | = inet_csk(sk)->icsk_ca_ops; |
| 2484 | 2486 | ||
| @@ -2608,6 +2610,7 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp) | |||
| 2608 | { | 2610 | { |
| 2609 | tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); | 2611 | tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); |
| 2610 | tp->snd_cwnd_cnt = 0; | 2612 | tp->snd_cwnd_cnt = 0; |
| 2613 | TCP_ECN_queue_cwr(tp); | ||
| 2611 | tcp_moderate_cwnd(tp); | 2614 | tcp_moderate_cwnd(tp); |
| 2612 | } | 2615 | } |
| 2613 | 2616 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a3e7f839fc5..97e294e82679 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -192,8 +192,11 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 192 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, | 192 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, |
| 193 | IPPROTO_TCP, | 193 | IPPROTO_TCP, |
| 194 | inet->sport, usin->sin_port, sk, 1); | 194 | inet->sport, usin->sin_port, sk, 1); |
| 195 | if (tmp < 0) | 195 | if (tmp < 0) { |
| 196 | if (tmp == -ENETUNREACH) | ||
| 197 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | ||
| 196 | return tmp; | 198 | return tmp; |
| 199 | } | ||
| 197 | 200 | ||
| 198 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { | 201 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { |
| 199 | ip_rt_put(rt); | 202 | ip_rt_put(rt); |
| @@ -702,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
| 702 | ip_hdr(skb)->saddr, /* XXX */ | 705 | ip_hdr(skb)->saddr, /* XXX */ |
| 703 | arg.iov[0].iov_len, IPPROTO_TCP, 0); | 706 | arg.iov[0].iov_len, IPPROTO_TCP, 0); |
| 704 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 707 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
| 708 | if (twsk) | ||
| 709 | arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; | ||
| 705 | 710 | ||
| 706 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); | 711 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); |
| 707 | 712 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0faacf9c419d..53232dd6fb48 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | #include <linux/compiler.h> | 41 | #include <linux/compiler.h> |
| 42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
| 43 | #include <linux/smp_lock.h> | ||
| 44 | 43 | ||
| 45 | /* People can turn this off for buggy TCP's found in printers etc. */ | 44 | /* People can turn this off for buggy TCP's found in printers etc. */ |
| 46 | int sysctl_tcp_retrans_collapse __read_mostly = 1; | 45 | int sysctl_tcp_retrans_collapse __read_mostly = 1; |
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 3938d5dbdf20..d9323dfff826 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
| @@ -63,6 +63,9 @@ struct { | |||
| 63 | * FIXME: causes an extra copy | 63 | * FIXME: causes an extra copy |
| 64 | */ | 64 | */ |
| 65 | static void printl(const char *fmt, ...) | 65 | static void printl(const char *fmt, ...) |
| 66 | __attribute__ ((format (printf, 1, 2))); | ||
| 67 | |||
| 68 | static void printl(const char *fmt, ...) | ||
| 66 | { | 69 | { |
| 67 | va_list args; | 70 | va_list args; |
| 68 | int len; | 71 | int len; |
| @@ -95,7 +98,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 95 | /* Only update if port matches */ | 98 | /* Only update if port matches */ |
| 96 | if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port) | 99 | if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port) |
| 97 | && (full || tp->snd_cwnd != tcpw.lastcwnd)) { | 100 | && (full || tp->snd_cwnd != tcpw.lastcwnd)) { |
| 98 | printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u\n", | 101 | printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n", |
| 99 | NIPQUAD(inet->saddr), ntohs(inet->sport), | 102 | NIPQUAD(inet->saddr), ntohs(inet->sport), |
| 100 | NIPQUAD(inet->daddr), ntohs(inet->dport), | 103 | NIPQUAD(inet->daddr), ntohs(inet->dport), |
| 101 | skb->len, tp->snd_nxt, tp->snd_una, | 104 | skb->len, tp->snd_nxt, tp->snd_una, |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 2ca97b20929d..e9b151b3a598 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
| @@ -78,9 +78,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) | |||
| 78 | if (sk->sk_err_soft) | 78 | if (sk->sk_err_soft) |
| 79 | orphans <<= 1; | 79 | orphans <<= 1; |
| 80 | 80 | ||
| 81 | if (orphans >= sysctl_tcp_max_orphans || | 81 | if (tcp_too_many_orphans(sk, orphans)) { |
| 82 | (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | ||
| 83 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { | ||
| 84 | if (net_ratelimit()) | 82 | if (net_ratelimit()) |
| 85 | printk(KERN_INFO "Out of socket memory\n"); | 83 | printk(KERN_INFO "Out of socket memory\n"); |
| 86 | 84 | ||
| @@ -294,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk) | |||
| 294 | * we cannot allow such beasts to hang infinitely. | 292 | * we cannot allow such beasts to hang infinitely. |
| 295 | */ | 293 | */ |
| 296 | #ifdef TCP_DEBUG | 294 | #ifdef TCP_DEBUG |
| 297 | if (net_ratelimit()) { | 295 | if (1) { |
| 298 | struct inet_sock *inet = inet_sk(sk); | 296 | struct inet_sock *inet = inet_sk(sk); |
| 299 | printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", | 297 | LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", |
| 300 | NIPQUAD(inet->daddr), ntohs(inet->dport), | 298 | NIPQUAD(inet->daddr), ntohs(inet->dport), |
| 301 | inet->num, tp->snd_una, tp->snd_nxt); | 299 | inet->num, tp->snd_una, tp->snd_nxt); |
| 302 | } | 300 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 113e0c4c8a92..facb7e29304e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -114,33 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock); | |||
| 114 | 114 | ||
| 115 | static int udp_port_rover; | 115 | static int udp_port_rover; |
| 116 | 116 | ||
| 117 | /* | 117 | static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[]) |
| 118 | * Note about this hash function : | ||
| 119 | * Typical use is probably daddr = 0, only dport is going to vary hash | ||
| 120 | */ | ||
| 121 | static inline unsigned int hash_port_and_addr(__u16 port, __be32 addr) | ||
| 122 | { | ||
| 123 | addr ^= addr >> 16; | ||
| 124 | addr ^= addr >> 8; | ||
| 125 | return port ^ addr; | ||
| 126 | } | ||
| 127 | |||
| 128 | static inline int __udp_lib_port_inuse(unsigned int hash, int port, | ||
| 129 | __be32 daddr, struct hlist_head udptable[]) | ||
| 130 | { | 118 | { |
| 131 | struct sock *sk; | 119 | struct sock *sk; |
| 132 | struct hlist_node *node; | 120 | struct hlist_node *node; |
| 133 | struct inet_sock *inet; | ||
| 134 | 121 | ||
| 135 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | 122 | sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) |
| 136 | if (sk->sk_hash != hash) | 123 | if (sk->sk_hash == num) |
| 137 | continue; | ||
| 138 | inet = inet_sk(sk); | ||
| 139 | if (inet->num != port) | ||
| 140 | continue; | ||
| 141 | if (inet->rcv_saddr == daddr) | ||
| 142 | return 1; | 124 | return 1; |
| 143 | } | ||
| 144 | return 0; | 125 | return 0; |
| 145 | } | 126 | } |
| 146 | 127 | ||
| @@ -161,7 +142,6 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 161 | struct hlist_node *node; | 142 | struct hlist_node *node; |
| 162 | struct hlist_head *head; | 143 | struct hlist_head *head; |
| 163 | struct sock *sk2; | 144 | struct sock *sk2; |
| 164 | unsigned int hash; | ||
| 165 | int error = 1; | 145 | int error = 1; |
| 166 | 146 | ||
| 167 | write_lock_bh(&udp_hash_lock); | 147 | write_lock_bh(&udp_hash_lock); |
| @@ -176,9 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 176 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { | 156 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { |
| 177 | int size; | 157 | int size; |
| 178 | 158 | ||
| 179 | hash = hash_port_and_addr(result, | 159 | head = &udptable[result & (UDP_HTABLE_SIZE - 1)]; |
| 180 | inet_sk(sk)->rcv_saddr); | ||
| 181 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
| 182 | if (hlist_empty(head)) { | 160 | if (hlist_empty(head)) { |
| 183 | if (result > sysctl_local_port_range[1]) | 161 | if (result > sysctl_local_port_range[1]) |
| 184 | result = sysctl_local_port_range[0] + | 162 | result = sysctl_local_port_range[0] + |
| @@ -203,17 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 203 | result = sysctl_local_port_range[0] | 181 | result = sysctl_local_port_range[0] |
| 204 | + ((result - sysctl_local_port_range[0]) & | 182 | + ((result - sysctl_local_port_range[0]) & |
| 205 | (UDP_HTABLE_SIZE - 1)); | 183 | (UDP_HTABLE_SIZE - 1)); |
| 206 | hash = hash_port_and_addr(result, 0); | 184 | if (! __udp_lib_lport_inuse(result, udptable)) |
| 207 | if (__udp_lib_port_inuse(hash, result, | ||
| 208 | 0, udptable)) | ||
| 209 | continue; | ||
| 210 | if (!inet_sk(sk)->rcv_saddr) | ||
| 211 | break; | ||
| 212 | |||
| 213 | hash = hash_port_and_addr(result, | ||
| 214 | inet_sk(sk)->rcv_saddr); | ||
| 215 | if (! __udp_lib_port_inuse(hash, result, | ||
| 216 | inet_sk(sk)->rcv_saddr, udptable)) | ||
| 217 | break; | 185 | break; |
| 218 | } | 186 | } |
| 219 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) | 187 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) |
| @@ -221,41 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 221 | gotit: | 189 | gotit: |
| 222 | *port_rover = snum = result; | 190 | *port_rover = snum = result; |
| 223 | } else { | 191 | } else { |
| 224 | hash = hash_port_and_addr(snum, 0); | 192 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
| 225 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
| 226 | 193 | ||
| 227 | sk_for_each(sk2, node, head) | 194 | sk_for_each(sk2, node, head) |
| 228 | if (sk2->sk_hash == hash && | 195 | if (sk2->sk_hash == snum && |
| 229 | sk2 != sk && | 196 | sk2 != sk && |
| 230 | inet_sk(sk2)->num == snum && | 197 | (!sk2->sk_reuse || !sk->sk_reuse) && |
| 231 | (!sk2->sk_reuse || !sk->sk_reuse) && | 198 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if |
| 232 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || | 199 | || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && |
| 233 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && | 200 | (*saddr_comp)(sk, sk2) ) |
| 234 | (*saddr_comp)(sk, sk2)) | ||
| 235 | goto fail; | 201 | goto fail; |
| 236 | |||
| 237 | if (inet_sk(sk)->rcv_saddr) { | ||
| 238 | hash = hash_port_and_addr(snum, | ||
| 239 | inet_sk(sk)->rcv_saddr); | ||
| 240 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
| 241 | |||
| 242 | sk_for_each(sk2, node, head) | ||
| 243 | if (sk2->sk_hash == hash && | ||
| 244 | sk2 != sk && | ||
| 245 | inet_sk(sk2)->num == snum && | ||
| 246 | (!sk2->sk_reuse || !sk->sk_reuse) && | ||
| 247 | (!sk2->sk_bound_dev_if || | ||
| 248 | !sk->sk_bound_dev_if || | ||
| 249 | sk2->sk_bound_dev_if == | ||
| 250 | sk->sk_bound_dev_if) && | ||
| 251 | (*saddr_comp)(sk, sk2)) | ||
| 252 | goto fail; | ||
| 253 | } | ||
| 254 | } | 202 | } |
| 255 | inet_sk(sk)->num = snum; | 203 | inet_sk(sk)->num = snum; |
| 256 | sk->sk_hash = hash; | 204 | sk->sk_hash = snum; |
| 257 | if (sk_unhashed(sk)) { | 205 | if (sk_unhashed(sk)) { |
| 258 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 206 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
| 259 | sk_add_node(sk, head); | 207 | sk_add_node(sk, head); |
| 260 | sock_prot_inc_use(sk->sk_prot); | 208 | sock_prot_inc_use(sk->sk_prot); |
| 261 | } | 209 | } |
| @@ -294,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport, | |||
| 294 | { | 242 | { |
| 295 | struct sock *sk, *result = NULL; | 243 | struct sock *sk, *result = NULL; |
| 296 | struct hlist_node *node; | 244 | struct hlist_node *node; |
| 297 | unsigned int hash, hashwild; | 245 | unsigned short hnum = ntohs(dport); |
| 298 | int score, best = -1, hport = ntohs(dport); | 246 | int badness = -1; |
| 299 | |||
| 300 | hash = hash_port_and_addr(hport, daddr); | ||
| 301 | hashwild = hash_port_and_addr(hport, 0); | ||
| 302 | 247 | ||
| 303 | read_lock(&udp_hash_lock); | 248 | read_lock(&udp_hash_lock); |
| 304 | 249 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | |
| 305 | lookup: | ||
| 306 | |||
| 307 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | ||
| 308 | struct inet_sock *inet = inet_sk(sk); | 250 | struct inet_sock *inet = inet_sk(sk); |
| 309 | 251 | ||
| 310 | if (sk->sk_hash != hash || ipv6_only_sock(sk) || | 252 | if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) { |
| 311 | inet->num != hport) | 253 | int score = (sk->sk_family == PF_INET ? 1 : 0); |
| 312 | continue; | 254 | if (inet->rcv_saddr) { |
| 313 | 255 | if (inet->rcv_saddr != daddr) | |
| 314 | score = (sk->sk_family == PF_INET ? 1 : 0); | 256 | continue; |
| 315 | if (inet->rcv_saddr) { | 257 | score+=2; |
| 316 | if (inet->rcv_saddr != daddr) | 258 | } |
| 317 | continue; | 259 | if (inet->daddr) { |
| 318 | score+=2; | 260 | if (inet->daddr != saddr) |
| 319 | } | 261 | continue; |
| 320 | if (inet->daddr) { | 262 | score+=2; |
| 321 | if (inet->daddr != saddr) | 263 | } |
| 322 | continue; | 264 | if (inet->dport) { |
| 323 | score+=2; | 265 | if (inet->dport != sport) |
| 324 | } | 266 | continue; |
| 325 | if (inet->dport) { | 267 | score+=2; |
| 326 | if (inet->dport != sport) | 268 | } |
| 327 | continue; | 269 | if (sk->sk_bound_dev_if) { |
| 328 | score+=2; | 270 | if (sk->sk_bound_dev_if != dif) |
| 329 | } | 271 | continue; |
| 330 | if (sk->sk_bound_dev_if) { | 272 | score+=2; |
| 331 | if (sk->sk_bound_dev_if != dif) | 273 | } |
| 332 | continue; | 274 | if (score == 9) { |
| 333 | score+=2; | 275 | result = sk; |
| 334 | } | 276 | break; |
| 335 | if (score == 9) { | 277 | } else if (score > badness) { |
| 336 | result = sk; | 278 | result = sk; |
| 337 | goto found; | 279 | badness = score; |
| 338 | } else if (score > best) { | 280 | } |
| 339 | result = sk; | ||
| 340 | best = score; | ||
| 341 | } | 281 | } |
| 342 | } | 282 | } |
| 343 | |||
| 344 | if (hash != hashwild) { | ||
| 345 | hash = hashwild; | ||
| 346 | goto lookup; | ||
| 347 | } | ||
| 348 | found: | ||
| 349 | if (result) | 283 | if (result) |
| 350 | sock_hold(result); | 284 | sock_hold(result); |
| 351 | read_unlock(&udp_hash_lock); | 285 | read_unlock(&udp_hash_lock); |
| 352 | return result; | 286 | return result; |
| 353 | } | 287 | } |
| 354 | 288 | ||
| 355 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, | 289 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, |
| 356 | int hport, __be32 loc_addr, | 290 | __be16 loc_port, __be32 loc_addr, |
| 357 | __be16 rmt_port, __be32 rmt_addr, | 291 | __be16 rmt_port, __be32 rmt_addr, |
| 358 | int dif) | 292 | int dif) |
| 359 | { | 293 | { |
| 360 | struct hlist_node *node; | 294 | struct hlist_node *node; |
| 361 | struct sock *s = sk; | 295 | struct sock *s = sk; |
| 296 | unsigned short hnum = ntohs(loc_port); | ||
| 362 | 297 | ||
| 363 | sk_for_each_from(s, node) { | 298 | sk_for_each_from(s, node) { |
| 364 | struct inet_sock *inet = inet_sk(s); | 299 | struct inet_sock *inet = inet_sk(s); |
| 365 | 300 | ||
| 366 | if (s->sk_hash != hnum || | 301 | if (s->sk_hash != hnum || |
| 367 | inet->num != hport || | ||
| 368 | (inet->daddr && inet->daddr != rmt_addr) || | 302 | (inet->daddr && inet->daddr != rmt_addr) || |
| 369 | (inet->dport != rmt_port && inet->dport) || | 303 | (inet->dport != rmt_port && inet->dport) || |
| 370 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || | 304 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || |
| @@ -699,8 +633,11 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 699 | .dport = dport } } }; | 633 | .dport = dport } } }; |
| 700 | security_sk_classify_flow(sk, &fl); | 634 | security_sk_classify_flow(sk, &fl); |
| 701 | err = ip_route_output_flow(&rt, &fl, sk, 1); | 635 | err = ip_route_output_flow(&rt, &fl, sk, 1); |
| 702 | if (err) | 636 | if (err) { |
| 637 | if (err == -ENETUNREACH) | ||
| 638 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | ||
| 703 | goto out; | 639 | goto out; |
| 640 | } | ||
| 704 | 641 | ||
| 705 | err = -EACCES; | 642 | err = -EACCES; |
| 706 | if ((rt->rt_flags & RTCF_BROADCAST) && | 643 | if ((rt->rt_flags & RTCF_BROADCAST) && |
| @@ -983,7 +920,7 @@ int udp_disconnect(struct sock *sk, int flags) | |||
| 983 | } | 920 | } |
| 984 | 921 | ||
| 985 | /* return: | 922 | /* return: |
| 986 | * 1 if the the UDP system should process it | 923 | * 1 if the UDP system should process it |
| 987 | * 0 if we should drop this packet | 924 | * 0 if we should drop this packet |
| 988 | * -1 if it should get processed by xfrm4_rcv_encap | 925 | * -1 if it should get processed by xfrm4_rcv_encap |
| 989 | */ | 926 | */ |
| @@ -1195,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
| 1195 | __be32 saddr, __be32 daddr, | 1132 | __be32 saddr, __be32 daddr, |
| 1196 | struct hlist_head udptable[]) | 1133 | struct hlist_head udptable[]) |
| 1197 | { | 1134 | { |
| 1198 | struct sock *sk, *skw, *sknext; | 1135 | struct sock *sk; |
| 1199 | int dif; | 1136 | int dif; |
| 1200 | int hport = ntohs(uh->dest); | ||
| 1201 | unsigned int hash = hash_port_and_addr(hport, daddr); | ||
| 1202 | unsigned int hashwild = hash_port_and_addr(hport, 0); | ||
| 1203 | |||
| 1204 | dif = skb->dev->ifindex; | ||
| 1205 | 1137 | ||
| 1206 | read_lock(&udp_hash_lock); | 1138 | read_lock(&udp_hash_lock); |
| 1207 | 1139 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | |
| 1208 | sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]); | 1140 | dif = skb->dev->ifindex; |
| 1209 | skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]); | 1141 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
| 1210 | |||
| 1211 | sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif); | ||
| 1212 | if (!sk) { | ||
| 1213 | hash = hashwild; | ||
| 1214 | sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source, | ||
| 1215 | saddr, dif); | ||
| 1216 | } | ||
| 1217 | if (sk) { | 1142 | if (sk) { |
| 1143 | struct sock *sknext = NULL; | ||
| 1144 | |||
| 1218 | do { | 1145 | do { |
| 1219 | struct sk_buff *skb1 = skb; | 1146 | struct sk_buff *skb1 = skb; |
| 1220 | sknext = udp_v4_mcast_next(sk_next(sk), hash, hport, | 1147 | |
| 1221 | daddr, uh->source, saddr, dif); | 1148 | sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr, |
| 1222 | if (!sknext && hash != hashwild) { | 1149 | uh->source, saddr, dif); |
| 1223 | hash = hashwild; | ||
| 1224 | sknext = udp_v4_mcast_next(skw, hash, hport, | ||
| 1225 | daddr, uh->source, saddr, dif); | ||
| 1226 | } | ||
| 1227 | if (sknext) | 1150 | if (sknext) |
| 1228 | skb1 = skb_clone(skb, GFP_ATOMIC); | 1151 | skb1 = skb_clone(skb, GFP_ATOMIC); |
| 1229 | 1152 | ||
| 1230 | if (skb1) { | 1153 | if (skb1) { |
| 1231 | int ret = udp_queue_rcv_skb(sk, skb1); | 1154 | int ret = udp_queue_rcv_skb(sk, skb1); |
| 1232 | if (ret > 0) | 1155 | if (ret > 0) |
| 1233 | /* | 1156 | /* we should probably re-process instead |
| 1234 | * we should probably re-process | 1157 | * of dropping packets here. */ |
| 1235 | * instead of dropping packets here. | ||
| 1236 | */ | ||
| 1237 | kfree_skb(skb1); | 1158 | kfree_skb(skb1); |
| 1238 | } | 1159 | } |
| 1239 | sk = sknext; | 1160 | sk = sknext; |
| @@ -1320,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
| 1320 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); | 1241 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); |
| 1321 | 1242 | ||
| 1322 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, | 1243 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, |
| 1323 | skb->dev->ifindex, udptable); | 1244 | skb->dev->ifindex, udptable ); |
| 1324 | 1245 | ||
| 1325 | if (sk != NULL) { | 1246 | if (sk != NULL) { |
| 1326 | int ret = udp_queue_rcv_skb(sk, skb); | 1247 | int ret = udp_queue_rcv_skb(sk, skb); |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 5ceca951d73f..fa1902dc81b8 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
| @@ -139,10 +139,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
| 139 | nf_reset(skb); | 139 | nf_reset(skb); |
| 140 | 140 | ||
| 141 | if (decaps) { | 141 | if (decaps) { |
| 142 | if (!(skb->dev->flags&IFF_LOOPBACK)) { | 142 | dst_release(skb->dst); |
| 143 | dst_release(skb->dst); | 143 | skb->dst = NULL; |
| 144 | skb->dst = NULL; | ||
| 145 | } | ||
| 146 | netif_rx(skb); | 144 | netif_rx(skb); |
| 147 | return 0; | 145 | return 0; |
| 148 | } else { | 146 | } else { |
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index a2f2e6a5ec5d..9963700e74c1 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
| @@ -85,6 +85,8 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 85 | top_iph->saddr = x->props.saddr.a4; | 85 | top_iph->saddr = x->props.saddr.a4; |
| 86 | top_iph->daddr = x->id.daddr.a4; | 86 | top_iph->daddr = x->id.daddr.a4; |
| 87 | 87 | ||
| 88 | skb->protocol = htons(ETH_P_IP); | ||
| 89 | |||
| 88 | memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); | 90 | memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); |
| 89 | return 0; | 91 | return 0; |
| 90 | } | 92 | } |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d02685c6bc69..5a5f8bd4597a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2154,15 +2154,6 @@ static void addrconf_dev_config(struct net_device *dev) | |||
| 2154 | 2154 | ||
| 2155 | ASSERT_RTNL(); | 2155 | ASSERT_RTNL(); |
| 2156 | 2156 | ||
| 2157 | if ((dev->type != ARPHRD_ETHER) && | ||
| 2158 | (dev->type != ARPHRD_FDDI) && | ||
| 2159 | (dev->type != ARPHRD_IEEE802_TR) && | ||
| 2160 | (dev->type != ARPHRD_ARCNET) && | ||
| 2161 | (dev->type != ARPHRD_INFINIBAND)) { | ||
| 2162 | /* Alas, we support only Ethernet autoconfiguration. */ | ||
| 2163 | return; | ||
| 2164 | } | ||
| 2165 | |||
| 2166 | idev = addrconf_add_dev(dev); | 2157 | idev = addrconf_add_dev(dev); |
| 2167 | if (idev == NULL) | 2158 | if (idev == NULL) |
| 2168 | return; | 2159 | return; |
| @@ -2250,13 +2241,33 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) | |||
| 2250 | ip6_tnl_add_linklocal(idev); | 2241 | ip6_tnl_add_linklocal(idev); |
| 2251 | } | 2242 | } |
| 2252 | 2243 | ||
| 2244 | static int ipv6_hwtype(struct net_device *dev) | ||
| 2245 | { | ||
| 2246 | if ((dev->type == ARPHRD_ETHER) || | ||
| 2247 | (dev->type == ARPHRD_LOOPBACK) || | ||
| 2248 | (dev->type == ARPHRD_SIT) || | ||
| 2249 | (dev->type == ARPHRD_TUNNEL6) || | ||
| 2250 | (dev->type == ARPHRD_FDDI) || | ||
| 2251 | (dev->type == ARPHRD_IEEE802_TR) || | ||
| 2252 | (dev->type == ARPHRD_ARCNET) || | ||
| 2253 | (dev->type == ARPHRD_INFINIBAND)) | ||
| 2254 | return 1; | ||
| 2255 | |||
| 2256 | return 0; | ||
| 2257 | } | ||
| 2258 | |||
| 2253 | static int addrconf_notify(struct notifier_block *this, unsigned long event, | 2259 | static int addrconf_notify(struct notifier_block *this, unsigned long event, |
| 2254 | void * data) | 2260 | void * data) |
| 2255 | { | 2261 | { |
| 2256 | struct net_device *dev = (struct net_device *) data; | 2262 | struct net_device *dev = (struct net_device *) data; |
| 2257 | struct inet6_dev *idev = __in6_dev_get(dev); | 2263 | struct inet6_dev *idev; |
| 2258 | int run_pending = 0; | 2264 | int run_pending = 0; |
| 2259 | 2265 | ||
| 2266 | if (!ipv6_hwtype(dev)) | ||
| 2267 | return NOTIFY_OK; | ||
| 2268 | |||
| 2269 | idev = __in6_dev_get(dev); | ||
| 2270 | |||
| 2260 | switch(event) { | 2271 | switch(event) { |
| 2261 | case NETDEV_REGISTER: | 2272 | case NETDEV_REGISTER: |
| 2262 | if (!idev) { | 2273 | if (!idev) { |
| @@ -2979,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) | |||
| 2979 | return pfx; | 2990 | return pfx; |
| 2980 | } | 2991 | } |
| 2981 | 2992 | ||
| 2982 | static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { | 2993 | static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { |
| 2983 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, | 2994 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
| 2984 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, | 2995 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
| 2985 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, | 2996 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
| @@ -4204,6 +4215,10 @@ int __init addrconf_init(void) | |||
| 4204 | return err; | 4215 | return err; |
| 4205 | 4216 | ||
| 4206 | ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); | 4217 | ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); |
| 4218 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 4219 | ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev); | ||
| 4220 | ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev); | ||
| 4221 | #endif | ||
| 4207 | 4222 | ||
| 4208 | register_netdevice_notifier(&ipv6_dev_notf); | 4223 | register_netdevice_notifier(&ipv6_dev_notf); |
| 4209 | 4224 | ||
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 18cb928c8d92..6dd377253cf7 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #include <linux/inet.h> | 42 | #include <linux/inet.h> |
| 43 | #include <linux/netdevice.h> | 43 | #include <linux/netdevice.h> |
| 44 | #include <linux/icmpv6.h> | 44 | #include <linux/icmpv6.h> |
| 45 | #include <linux/smp_lock.h> | ||
| 46 | #include <linux/netfilter_ipv6.h> | 45 | #include <linux/netfilter_ipv6.h> |
| 47 | 46 | ||
| 48 | #include <net/ip.h> | 47 | #include <net/ip.h> |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index b696c8401200..128f94c79c64 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
| @@ -247,7 +247,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 247 | memcpy(tmp_base, top_iph, sizeof(tmp_base)); | 247 | memcpy(tmp_base, top_iph, sizeof(tmp_base)); |
| 248 | 248 | ||
| 249 | tmp_ext = NULL; | 249 | tmp_ext = NULL; |
| 250 | extlen = skb_transport_offset(skb) + sizeof(struct ipv6hdr); | 250 | extlen = skb_transport_offset(skb) - sizeof(struct ipv6hdr); |
| 251 | if (extlen) { | 251 | if (extlen) { |
| 252 | extlen += sizeof(*tmp_ext); | 252 | extlen += sizeof(*tmp_ext); |
| 253 | tmp_ext = kmalloc(extlen, GFP_ATOMIC); | 253 | tmp_ext = kmalloc(extlen, GFP_ATOMIC); |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 403eee66b9c5..b1fe7ac5dc90 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -177,8 +177,12 @@ ipv4_connected: | |||
| 177 | if (final_p) | 177 | if (final_p) |
| 178 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 178 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 179 | 179 | ||
| 180 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 180 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
| 181 | goto out; | 181 | if (err == -EREMOTE) |
| 182 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
| 183 | if (err < 0) | ||
| 184 | goto out; | ||
| 185 | } | ||
| 182 | 186 | ||
| 183 | /* source address lookup done in ip6_dst_lookup */ | 187 | /* source address lookup done in ip6_dst_lookup */ |
| 184 | 188 | ||
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 6d8e4ac7bdad..14be0b9b77a5 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -660,6 +660,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); | |||
| 660 | Hop-by-hop options. | 660 | Hop-by-hop options. |
| 661 | **********************************/ | 661 | **********************************/ |
| 662 | 662 | ||
| 663 | /* | ||
| 664 | * Note: we cannot rely on skb->dst before we assign it in ip6_route_input(). | ||
| 665 | */ | ||
| 666 | static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) | ||
| 667 | { | ||
| 668 | return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev); | ||
| 669 | } | ||
| 670 | |||
| 663 | /* Router Alert as of RFC 2711 */ | 671 | /* Router Alert as of RFC 2711 */ |
| 664 | 672 | ||
| 665 | static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) | 673 | static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) |
| @@ -688,25 +696,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) | |||
| 688 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { | 696 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { |
| 689 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", | 697 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", |
| 690 | nh[optoff+1]); | 698 | nh[optoff+1]); |
| 691 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 699 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), |
| 692 | IPSTATS_MIB_INHDRERRORS); | 700 | IPSTATS_MIB_INHDRERRORS); |
| 693 | goto drop; | 701 | goto drop; |
| 694 | } | 702 | } |
| 695 | 703 | ||
| 696 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); | 704 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); |
| 697 | if (pkt_len <= IPV6_MAXPLEN) { | 705 | if (pkt_len <= IPV6_MAXPLEN) { |
| 698 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 706 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); |
| 699 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); | 707 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); |
| 700 | return 0; | 708 | return 0; |
| 701 | } | 709 | } |
| 702 | if (ipv6_hdr(skb)->payload_len) { | 710 | if (ipv6_hdr(skb)->payload_len) { |
| 703 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 711 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); |
| 704 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); | 712 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); |
| 705 | return 0; | 713 | return 0; |
| 706 | } | 714 | } |
| 707 | 715 | ||
| 708 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { | 716 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { |
| 709 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); | 717 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); |
| 710 | goto drop; | 718 | goto drop; |
| 711 | } | 719 | } |
| 712 | 720 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index fc3882c90604..53b3998a486c 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
| 157 | return 1; | 157 | return 1; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | 160 | static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = { |
| 161 | FRA_GENERIC_POLICY, | 161 | FRA_GENERIC_POLICY, |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ca08ee88d07f..662a7d9681fd 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -619,14 +619,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
| 619 | 619 | ||
| 620 | ins = &fn->leaf; | 620 | ins = &fn->leaf; |
| 621 | 621 | ||
| 622 | if (fn->fn_flags&RTN_TL_ROOT && | ||
| 623 | fn->leaf == &ip6_null_entry && | ||
| 624 | !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){ | ||
| 625 | fn->leaf = rt; | ||
| 626 | rt->u.dst.rt6_next = NULL; | ||
| 627 | goto out; | ||
| 628 | } | ||
| 629 | |||
| 630 | for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) { | 622 | for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) { |
| 631 | /* | 623 | /* |
| 632 | * Search for duplicates | 624 | * Search for duplicates |
| @@ -666,7 +658,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
| 666 | * insert node | 658 | * insert node |
| 667 | */ | 659 | */ |
| 668 | 660 | ||
| 669 | out: | ||
| 670 | rt->u.dst.rt6_next = iter; | 661 | rt->u.dst.rt6_next = iter; |
| 671 | *ins = rt; | 662 | *ins = rt; |
| 672 | rt->rt6i_node = fn; | 663 | rt->rt6i_node = fn; |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index be0ee8a34f9b..30a5cb1b203e 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
| @@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb) | |||
| 235 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); | 235 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); |
| 236 | 236 | ||
| 237 | hdr = ipv6_hdr(skb); | 237 | hdr = ipv6_hdr(skb); |
| 238 | deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || | 238 | deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || |
| 239 | ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); | 239 | ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); |
| 240 | 240 | ||
| 241 | /* | 241 | /* |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index f508171bab73..4704b5fc3085 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -463,10 +463,17 @@ int ip6_forward(struct sk_buff *skb) | |||
| 463 | */ | 463 | */ |
| 464 | if (xrlim_allow(dst, 1*HZ)) | 464 | if (xrlim_allow(dst, 1*HZ)) |
| 465 | ndisc_send_redirect(skb, n, target); | 465 | ndisc_send_redirect(skb, n, target); |
| 466 | } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK | 466 | } else { |
| 467 | |IPV6_ADDR_LINKLOCAL)) { | 467 | int addrtype = ipv6_addr_type(&hdr->saddr); |
| 468 | |||
| 468 | /* This check is security critical. */ | 469 | /* This check is security critical. */ |
| 469 | goto error; | 470 | if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) |
| 471 | goto error; | ||
| 472 | if (addrtype & IPV6_ADDR_LINKLOCAL) { | ||
| 473 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, | ||
| 474 | ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); | ||
| 475 | goto error; | ||
| 476 | } | ||
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | if (skb->len > dst_mtu(dst)) { | 479 | if (skb->len > dst_mtu(dst)) { |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index bbe99f842f9f..838b8ddee8c0 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
| @@ -28,7 +28,7 @@ config IP6_NF_QUEUE | |||
| 28 | packets which enables users to receive the filtered packets | 28 | packets which enables users to receive the filtered packets |
| 29 | with QUEUE target using libipq. | 29 | with QUEUE target using libipq. |
| 30 | 30 | ||
| 31 | THis option enables the old IPv6-only "ip6_queue" implementation | 31 | This option enables the old IPv6-only "ip6_queue" implementation |
| 32 | which has been obsoleted by the new "nfnetlink_queue" code (see | 32 | which has been obsoleted by the new "nfnetlink_queue" code (see |
| 33 | CONFIG_NETFILTER_NETLINK_QUEUE). | 33 | CONFIG_NETFILTER_NETLINK_QUEUE). |
| 34 | 34 | ||
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 76f0cf66f95c..7e32e2aaf7f7 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
| @@ -24,53 +24,29 @@ static struct | |||
| 24 | struct ip6t_replace repl; | 24 | struct ip6t_replace repl; |
| 25 | struct ip6t_standard entries[3]; | 25 | struct ip6t_standard entries[3]; |
| 26 | struct ip6t_error term; | 26 | struct ip6t_error term; |
| 27 | } initial_table __initdata | 27 | } initial_table __initdata = { |
| 28 | = { { "filter", FILTER_VALID_HOOKS, 4, | 28 | .repl = { |
| 29 | sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), | 29 | .name = "filter", |
| 30 | { [NF_IP6_LOCAL_IN] = 0, | 30 | .valid_hooks = FILTER_VALID_HOOKS, |
| 31 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), | 31 | .num_entries = 4, |
| 32 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, | 32 | .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), |
| 33 | { [NF_IP6_LOCAL_IN] = 0, | 33 | .hook_entry = { |
| 34 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), | 34 | [NF_IP6_LOCAL_IN] = 0, |
| 35 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, | 35 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), |
| 36 | 0, NULL, { } }, | 36 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 |
| 37 | { | 37 | }, |
| 38 | /* LOCAL_IN */ | 38 | .underflow = { |
| 39 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 39 | [NF_IP6_LOCAL_IN] = 0, |
| 40 | 0, | 40 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), |
| 41 | sizeof(struct ip6t_entry), | 41 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 |
| 42 | sizeof(struct ip6t_standard), | 42 | }, |
| 43 | 0, { 0, 0 }, { } }, | 43 | }, |
| 44 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | 44 | .entries = { |
| 45 | -NF_ACCEPT - 1 } }, | 45 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
| 46 | /* FORWARD */ | 46 | IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
| 47 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 47 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 48 | 0, | 48 | }, |
| 49 | sizeof(struct ip6t_entry), | 49 | .term = IP6T_ERROR_INIT, /* ERROR */ |
| 50 | sizeof(struct ip6t_standard), | ||
| 51 | 0, { 0, 0 }, { } }, | ||
| 52 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 53 | -NF_ACCEPT - 1 } }, | ||
| 54 | /* LOCAL_OUT */ | ||
| 55 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 56 | 0, | ||
| 57 | sizeof(struct ip6t_entry), | ||
| 58 | sizeof(struct ip6t_standard), | ||
| 59 | 0, { 0, 0 }, { } }, | ||
| 60 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 61 | -NF_ACCEPT - 1 } } | ||
| 62 | }, | ||
| 63 | /* ERROR */ | ||
| 64 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 65 | 0, | ||
| 66 | sizeof(struct ip6t_entry), | ||
| 67 | sizeof(struct ip6t_error), | ||
| 68 | 0, { 0, 0 }, { } }, | ||
| 69 | { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, | ||
| 70 | { } }, | ||
| 71 | "ERROR" | ||
| 72 | } | ||
| 73 | } | ||
| 74 | }; | 50 | }; |
| 75 | 51 | ||
| 76 | static struct xt_table packet_filter = { | 52 | static struct xt_table packet_filter = { |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index a9f10e32c163..f2d26495f413 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
| @@ -32,73 +32,35 @@ static struct | |||
| 32 | struct ip6t_replace repl; | 32 | struct ip6t_replace repl; |
| 33 | struct ip6t_standard entries[5]; | 33 | struct ip6t_standard entries[5]; |
| 34 | struct ip6t_error term; | 34 | struct ip6t_error term; |
| 35 | } initial_table __initdata | 35 | } initial_table __initdata = { |
| 36 | = { { "mangle", MANGLE_VALID_HOOKS, 6, | 36 | .repl = { |
| 37 | sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error), | 37 | .name = "mangle", |
| 38 | { [NF_IP6_PRE_ROUTING] = 0, | 38 | .valid_hooks = MANGLE_VALID_HOOKS, |
| 39 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), | 39 | .num_entries = 6, |
| 40 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, | 40 | .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error), |
| 41 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, | 41 | .hook_entry = { |
| 42 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, | 42 | [NF_IP6_PRE_ROUTING] = 0, |
| 43 | { [NF_IP6_PRE_ROUTING] = 0, | 43 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), |
| 44 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), | 44 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, |
| 45 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, | 45 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, |
| 46 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, | 46 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4, |
| 47 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, | 47 | }, |
| 48 | 0, NULL, { } }, | 48 | .underflow = { |
| 49 | { | 49 | [NF_IP6_PRE_ROUTING] = 0, |
| 50 | /* PRE_ROUTING */ | 50 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), |
| 51 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 51 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, |
| 52 | 0, | 52 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, |
| 53 | sizeof(struct ip6t_entry), | 53 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4, |
| 54 | sizeof(struct ip6t_standard), | 54 | }, |
| 55 | 0, { 0, 0 }, { } }, | 55 | }, |
| 56 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | 56 | .entries = { |
| 57 | -NF_ACCEPT - 1 } }, | 57 | IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
| 58 | /* LOCAL_IN */ | 58 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
| 59 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 59 | IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
| 60 | 0, | 60 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 61 | sizeof(struct ip6t_entry), | 61 | IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
| 62 | sizeof(struct ip6t_standard), | 62 | }, |
| 63 | 0, { 0, 0 }, { } }, | 63 | .term = IP6T_ERROR_INIT, /* ERROR */ |
| 64 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 65 | -NF_ACCEPT - 1 } }, | ||
| 66 | /* FORWARD */ | ||
| 67 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 68 | 0, | ||
| 69 | sizeof(struct ip6t_entry), | ||
| 70 | sizeof(struct ip6t_standard), | ||
| 71 | 0, { 0, 0 }, { } }, | ||
| 72 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 73 | -NF_ACCEPT - 1 } }, | ||
| 74 | /* LOCAL_OUT */ | ||
| 75 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 76 | 0, | ||
| 77 | sizeof(struct ip6t_entry), | ||
| 78 | sizeof(struct ip6t_standard), | ||
| 79 | 0, { 0, 0 }, { } }, | ||
| 80 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 81 | -NF_ACCEPT - 1 } }, | ||
| 82 | /* POST_ROUTING */ | ||
| 83 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 84 | 0, | ||
| 85 | sizeof(struct ip6t_entry), | ||
| 86 | sizeof(struct ip6t_standard), | ||
| 87 | 0, { 0, 0 }, { } }, | ||
| 88 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
| 89 | -NF_ACCEPT - 1 } } | ||
| 90 | }, | ||
| 91 | /* ERROR */ | ||
| 92 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
| 93 | 0, | ||
| 94 | sizeof(struct ip6t_entry), | ||
| 95 | sizeof(struct ip6t_error), | ||
| 96 | 0, { 0, 0 }, { } }, | ||
| 97 | { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, | ||
| 98 | { } }, | ||
| 99 | "ERROR" | ||
| 100 | } | ||
| 101 | } | ||
| 102 | }; | 64 | }; |
| 103 | 65 | ||
| 104 | static struct xt_table packet_mangler = { | 66 | static struct xt_table packet_mangler = { |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index a3eb5b8ce18d..0acda45d455d 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
| @@ -35,56 +35,10 @@ static struct | |||
| 35 | }, | 35 | }, |
| 36 | }, | 36 | }, |
| 37 | .entries = { | 37 | .entries = { |
| 38 | /* PRE_ROUTING */ | 38 | IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
| 39 | { | 39 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
| 40 | .entry = { | ||
| 41 | .target_offset = sizeof(struct ip6t_entry), | ||
| 42 | .next_offset = sizeof(struct ip6t_standard), | ||
| 43 | }, | ||
| 44 | .target = { | ||
| 45 | .target = { | ||
| 46 | .u = { | ||
| 47 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)), | ||
| 48 | }, | ||
| 49 | }, | ||
| 50 | .verdict = -NF_ACCEPT - 1, | ||
| 51 | }, | ||
| 52 | }, | ||
| 53 | |||
| 54 | /* LOCAL_OUT */ | ||
| 55 | { | ||
| 56 | .entry = { | ||
| 57 | .target_offset = sizeof(struct ip6t_entry), | ||
| 58 | .next_offset = sizeof(struct ip6t_standard), | ||
| 59 | }, | ||
| 60 | .target = { | ||
| 61 | .target = { | ||
| 62 | .u = { | ||
| 63 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)), | ||
| 64 | }, | ||
| 65 | }, | ||
| 66 | .verdict = -NF_ACCEPT - 1, | ||
| 67 | }, | ||
| 68 | }, | ||
| 69 | }, | 40 | }, |
| 70 | /* ERROR */ | 41 | .term = IP6T_ERROR_INIT, /* ERROR */ |
| 71 | .term = { | ||
| 72 | .entry = { | ||
| 73 | .target_offset = sizeof(struct ip6t_entry), | ||
| 74 | .next_offset = sizeof(struct ip6t_error), | ||
| 75 | }, | ||
| 76 | .target = { | ||
| 77 | .target = { | ||
| 78 | .u = { | ||
| 79 | .user = { | ||
| 80 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_error_target)), | ||
| 81 | .name = IP6T_ERROR_TARGET, | ||
| 82 | }, | ||
| 83 | }, | ||
| 84 | }, | ||
| 85 | .errorname = "ERROR", | ||
| 86 | }, | ||
| 87 | } | ||
| 88 | }; | 42 | }; |
| 89 | 43 | ||
| 90 | static struct xt_table packet_raw = { | 44 | static struct xt_table packet_raw = { |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 6d2a08205111..1b1797f1f33d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
| 160 | { | 160 | { |
| 161 | struct nf_conn *ct; | 161 | struct nf_conn *ct; |
| 162 | struct nf_conn_help *help; | 162 | struct nf_conn_help *help; |
| 163 | struct nf_conntrack_helper *helper; | ||
| 163 | enum ip_conntrack_info ctinfo; | 164 | enum ip_conntrack_info ctinfo; |
| 164 | unsigned int ret, protoff; | 165 | unsigned int ret, protoff; |
| 165 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 166 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; |
| @@ -172,18 +173,21 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
| 172 | goto out; | 173 | goto out; |
| 173 | 174 | ||
| 174 | help = nfct_help(ct); | 175 | help = nfct_help(ct); |
| 175 | if (!help || !help->helper) | 176 | if (!help) |
| 177 | goto out; | ||
| 178 | /* rcu_read_lock()ed by nf_hook_slow */ | ||
| 179 | helper = rcu_dereference(help->helper); | ||
| 180 | if (!helper) | ||
| 176 | goto out; | 181 | goto out; |
| 177 | 182 | ||
| 178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 183 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, |
| 179 | (*pskb)->len - extoff); | 184 | (*pskb)->len - extoff); |
| 180 | if (protoff < 0 || protoff > (*pskb)->len || | 185 | if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { |
| 181 | pnum == NEXTHDR_FRAGMENT) { | ||
| 182 | DEBUGP("proto header not found\n"); | 186 | DEBUGP("proto header not found\n"); |
| 183 | return NF_ACCEPT; | 187 | return NF_ACCEPT; |
| 184 | } | 188 | } |
| 185 | 189 | ||
| 186 | ret = help->helper->help(pskb, protoff, ct, ctinfo); | 190 | ret = helper->help(pskb, protoff, ct, ctinfo); |
| 187 | if (ret != NF_ACCEPT) | 191 | if (ret != NF_ACCEPT) |
| 188 | return ret; | 192 | return ret; |
| 189 | out: | 193 | out: |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 0be790d250f9..8814b95b2326 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
| @@ -168,8 +168,7 @@ icmpv6_error_message(struct sk_buff *skb, | |||
| 168 | skb->len - inip6off | 168 | skb->len - inip6off |
| 169 | - sizeof(struct ipv6hdr)); | 169 | - sizeof(struct ipv6hdr)); |
| 170 | 170 | ||
| 171 | if ((inprotoff < 0) || (inprotoff > skb->len) || | 171 | if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) { |
| 172 | (inprotonum == NEXTHDR_FRAGMENT)) { | ||
| 173 | DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n"); | 172 | DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n"); |
| 174 | return -NF_ACCEPT; | 173 | return -NF_ACCEPT; |
| 175 | } | 174 | } |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 009a1047fc3f..a58459a76684 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -818,8 +818,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 818 | if (final_p) | 818 | if (final_p) |
| 819 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 819 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 820 | 820 | ||
| 821 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 821 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
| 822 | goto out; | 822 | if (err == -EREMOTE) |
| 823 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
| 824 | if (err < 0) | ||
| 825 | goto out; | ||
| 826 | } | ||
| 823 | 827 | ||
| 824 | if (hlimit < 0) { | 828 | if (hlimit < 0) { |
| 825 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 829 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b46ad53044ba..fe8d9837f9f8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -119,6 +119,19 @@ static struct dst_ops ip6_dst_ops = { | |||
| 119 | .entry_size = sizeof(struct rt6_info), | 119 | .entry_size = sizeof(struct rt6_info), |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | ||
| 123 | { | ||
| 124 | } | ||
| 125 | |||
| 126 | static struct dst_ops ip6_dst_blackhole_ops = { | ||
| 127 | .family = AF_INET6, | ||
| 128 | .protocol = __constant_htons(ETH_P_IPV6), | ||
| 129 | .destroy = ip6_dst_destroy, | ||
| 130 | .check = ip6_dst_check, | ||
| 131 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | ||
| 132 | .entry_size = sizeof(struct rt6_info), | ||
| 133 | }; | ||
| 134 | |||
| 122 | struct rt6_info ip6_null_entry = { | 135 | struct rt6_info ip6_null_entry = { |
| 123 | .u = { | 136 | .u = { |
| 124 | .dst = { | 137 | .dst = { |
| @@ -833,6 +846,54 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) | |||
| 833 | 846 | ||
| 834 | EXPORT_SYMBOL(ip6_route_output); | 847 | EXPORT_SYMBOL(ip6_route_output); |
| 835 | 848 | ||
| 849 | static int ip6_blackhole_output(struct sk_buff *skb) | ||
| 850 | { | ||
| 851 | kfree_skb(skb); | ||
| 852 | return 0; | ||
| 853 | } | ||
| 854 | |||
| 855 | int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl) | ||
| 856 | { | ||
| 857 | struct rt6_info *ort = (struct rt6_info *) *dstp; | ||
| 858 | struct rt6_info *rt = (struct rt6_info *) | ||
| 859 | dst_alloc(&ip6_dst_blackhole_ops); | ||
| 860 | struct dst_entry *new = NULL; | ||
| 861 | |||
| 862 | if (rt) { | ||
| 863 | new = &rt->u.dst; | ||
| 864 | |||
| 865 | atomic_set(&new->__refcnt, 1); | ||
| 866 | new->__use = 1; | ||
| 867 | new->input = ip6_blackhole_output; | ||
| 868 | new->output = ip6_blackhole_output; | ||
| 869 | |||
| 870 | memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); | ||
| 871 | new->dev = ort->u.dst.dev; | ||
| 872 | if (new->dev) | ||
| 873 | dev_hold(new->dev); | ||
| 874 | rt->rt6i_idev = ort->rt6i_idev; | ||
| 875 | if (rt->rt6i_idev) | ||
| 876 | in6_dev_hold(rt->rt6i_idev); | ||
| 877 | rt->rt6i_expires = 0; | ||
| 878 | |||
| 879 | ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); | ||
| 880 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; | ||
| 881 | rt->rt6i_metric = 0; | ||
| 882 | |||
| 883 | memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); | ||
| 884 | #ifdef CONFIG_IPV6_SUBTREES | ||
| 885 | memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); | ||
| 886 | #endif | ||
| 887 | |||
| 888 | dst_free(new); | ||
| 889 | } | ||
| 890 | |||
| 891 | dst_release(*dstp); | ||
| 892 | *dstp = new; | ||
| 893 | return (new ? 0 : -ENOMEM); | ||
| 894 | } | ||
| 895 | EXPORT_SYMBOL_GPL(ip6_dst_blackhole); | ||
| 896 | |||
| 836 | /* | 897 | /* |
| 837 | * Destination cache support functions | 898 | * Destination cache support functions |
| 838 | */ | 899 | */ |
| @@ -1938,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu) | |||
| 1938 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); | 1999 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); |
| 1939 | } | 2000 | } |
| 1940 | 2001 | ||
| 1941 | static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { | 2002 | static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { |
| 1942 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, | 2003 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, |
| 1943 | [RTA_OIF] = { .type = NLA_U32 }, | 2004 | [RTA_OIF] = { .type = NLA_U32 }, |
| 1944 | [RTA_IIF] = { .type = NLA_U32 }, | 2005 | [RTA_IIF] = { .type = NLA_U32 }, |
| @@ -2495,6 +2556,8 @@ void __init ip6_route_init(void) | |||
| 2495 | ip6_dst_ops.kmem_cachep = | 2556 | ip6_dst_ops.kmem_cachep = |
| 2496 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, | 2557 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, |
| 2497 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 2558 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
| 2559 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; | ||
| 2560 | |||
| 2498 | fib6_init(); | 2561 | fib6_init(); |
| 2499 | #ifdef CONFIG_PROC_FS | 2562 | #ifdef CONFIG_PROC_FS |
| 2500 | p = proc_net_create("ipv6_route", 0, rt6_proc_info); | 2563 | p = proc_net_create("ipv6_route", 0, rt6_proc_info); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e2f25ea43b68..4f06a51ad4fd 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -265,8 +265,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 265 | if (final_p) | 265 | if (final_p) |
| 266 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 266 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 267 | 267 | ||
| 268 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 268 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
| 269 | goto failure; | 269 | if (err == -EREMOTE) |
| 270 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
| 271 | if (err < 0) | ||
| 272 | goto failure; | ||
| 273 | } | ||
| 270 | 274 | ||
| 271 | if (saddr == NULL) { | 275 | if (saddr == NULL) { |
| 272 | saddr = &fl.fl6_src; | 276 | saddr = &fl.fl6_src; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b083c09e3d2d..4210951edb6e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -748,8 +748,12 @@ do_udp_sendmsg: | |||
| 748 | if (final_p) | 748 | if (final_p) |
| 749 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 749 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 750 | 750 | ||
| 751 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 751 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
| 752 | goto out; | 752 | if (err == -EREMOTE) |
| 753 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
| 754 | if (err < 0) | ||
| 755 | goto out; | ||
| 756 | } | ||
| 753 | 757 | ||
| 754 | if (hlimit < 0) { | 758 | if (hlimit < 0) { |
| 755 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 759 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index d7ed8aa56ec1..c858537cec4b 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
| @@ -104,10 +104,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
| 104 | nf_reset(skb); | 104 | nf_reset(skb); |
| 105 | 105 | ||
| 106 | if (decaps) { | 106 | if (decaps) { |
| 107 | if (!(skb->dev->flags&IFF_LOOPBACK)) { | 107 | dst_release(skb->dst); |
| 108 | dst_release(skb->dst); | 108 | skb->dst = NULL; |
| 109 | skb->dst = NULL; | ||
| 110 | } | ||
| 111 | netif_rx(skb); | 109 | netif_rx(skb); |
| 112 | return -1; | 110 | return -1; |
| 113 | } else { | 111 | } else { |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index a6c0cdf46ad6..9fc95bc6509f 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
| @@ -80,6 +80,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 80 | top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); | 80 | top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); |
| 81 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); | 81 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); |
| 82 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); | 82 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); |
| 83 | skb->protocol = htons(ETH_P_IPV6); | ||
| 83 | return 0; | 84 | return 0; |
| 84 | } | 85 | } |
| 85 | 86 | ||
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 392f8bc92691..8400525177ab 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
| @@ -87,7 +87,7 @@ 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, size_t 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(__be32 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); |
| @@ -1961,7 +1961,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | |||
| 1961 | .sendpage = sock_no_sendpage, | 1961 | .sendpage = sock_no_sendpage, |
| 1962 | }; | 1962 | }; |
| 1963 | 1963 | ||
| 1964 | #include <linux/smp_lock.h> | ||
| 1965 | SOCKOPS_WRAP(ipx_dgram, PF_IPX); | 1964 | SOCKOPS_WRAP(ipx_dgram, PF_IPX); |
| 1966 | 1965 | ||
| 1967 | static struct packet_type ipx_8023_packet_type = { | 1966 | static struct packet_type ipx_8023_packet_type = { |
diff --git a/net/irda/Kconfig b/net/irda/Kconfig index 9efb17ba48ac..c8671a7ffb3c 100644 --- a/net/irda/Kconfig +++ b/net/irda/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menuconfig IRDA | 5 | menuconfig IRDA |
| 6 | depends on NET | 6 | depends on NET && !S390 |
| 7 | tristate "IrDA (infrared) subsystem support" | 7 | tristate "IrDA (infrared) subsystem support" |
| 8 | select CRC_CCITT | 8 | select CRC_CCITT |
| 9 | ---help--- | 9 | ---help--- |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 06c97c60d542..dcd7e325b283 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
| @@ -2538,7 +2538,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | |||
| 2538 | }; | 2538 | }; |
| 2539 | #endif /* CONFIG_IRDA_ULTRA */ | 2539 | #endif /* CONFIG_IRDA_ULTRA */ |
| 2540 | 2540 | ||
| 2541 | #include <linux/smp_lock.h> | ||
| 2542 | SOCKOPS_WRAP(irda_stream, PF_IRDA); | 2541 | SOCKOPS_WRAP(irda_stream, PF_IRDA); |
| 2543 | SOCKOPS_WRAP(irda_seqpacket, PF_IRDA); | 2542 | SOCKOPS_WRAP(irda_seqpacket, PF_IRDA); |
| 2544 | SOCKOPS_WRAP(irda_dgram, PF_IRDA); | 2543 | SOCKOPS_WRAP(irda_dgram, PF_IRDA); |
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index fb3faf72e850..b7333061016d 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c | |||
| @@ -556,6 +556,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
| 556 | 556 | ||
| 557 | switch (action) { | 557 | switch (action) { |
| 558 | case CPU_UP_PREPARE: | 558 | case CPU_UP_PREPARE: |
| 559 | case CPU_UP_PREPARE_FROZEN: | ||
| 559 | if (!percpu_populate(iucv_irq_data, | 560 | if (!percpu_populate(iucv_irq_data, |
| 560 | sizeof(struct iucv_irq_data), | 561 | sizeof(struct iucv_irq_data), |
| 561 | GFP_KERNEL|GFP_DMA, cpu)) | 562 | GFP_KERNEL|GFP_DMA, cpu)) |
| @@ -567,15 +568,20 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
| 567 | } | 568 | } |
| 568 | break; | 569 | break; |
| 569 | case CPU_UP_CANCELED: | 570 | case CPU_UP_CANCELED: |
| 571 | case CPU_UP_CANCELED_FROZEN: | ||
| 570 | case CPU_DEAD: | 572 | case CPU_DEAD: |
| 573 | case CPU_DEAD_FROZEN: | ||
| 571 | percpu_depopulate(iucv_param, cpu); | 574 | percpu_depopulate(iucv_param, cpu); |
| 572 | percpu_depopulate(iucv_irq_data, cpu); | 575 | percpu_depopulate(iucv_irq_data, cpu); |
| 573 | break; | 576 | break; |
| 574 | case CPU_ONLINE: | 577 | case CPU_ONLINE: |
| 578 | case CPU_ONLINE_FROZEN: | ||
| 575 | case CPU_DOWN_FAILED: | 579 | case CPU_DOWN_FAILED: |
| 580 | case CPU_DOWN_FAILED_FROZEN: | ||
| 576 | smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); | 581 | smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); |
| 577 | break; | 582 | break; |
| 578 | case CPU_DOWN_PREPARE: | 583 | case CPU_DOWN_PREPARE: |
| 584 | case CPU_DOWN_PREPARE_FROZEN: | ||
| 579 | cpumask = iucv_buffer_cpumask; | 585 | cpumask = iucv_buffer_cpumask; |
| 580 | cpu_clear(cpu, cpumask); | 586 | cpu_clear(cpu, cpumask); |
| 581 | if (cpus_empty(cpumask)) | 587 | if (cpus_empty(cpumask)) |
diff --git a/net/key/af_key.c b/net/key/af_key.c index a99444142dc7..0f8304b0246b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
| 1448 | int err; | 1448 | int err; |
| 1449 | struct km_event c; | 1449 | struct km_event c; |
| 1450 | 1450 | ||
| 1451 | xfrm_probe_algs(); | ||
| 1452 | |||
| 1453 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); | 1451 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); |
| 1454 | if (IS_ERR(x)) | 1452 | if (IS_ERR(x)) |
| 1455 | return PTR_ERR(x); | 1453 | return PTR_ERR(x); |
| @@ -1684,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
| 1684 | unsigned proto; | 1682 | unsigned proto; |
| 1685 | struct km_event c; | 1683 | struct km_event c; |
| 1686 | struct xfrm_audit audit_info; | 1684 | struct xfrm_audit audit_info; |
| 1685 | int err; | ||
| 1687 | 1686 | ||
| 1688 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); | 1687 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
| 1689 | if (proto == 0) | 1688 | if (proto == 0) |
| @@ -1691,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
| 1691 | 1690 | ||
| 1692 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 1691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
| 1693 | audit_info.secid = 0; | 1692 | audit_info.secid = 0; |
| 1694 | xfrm_state_flush(proto, &audit_info); | 1693 | err = xfrm_state_flush(proto, &audit_info); |
| 1694 | if (err) | ||
| 1695 | return err; | ||
| 1695 | c.data.proto = proto; | 1696 | c.data.proto = proto; |
| 1696 | c.seq = hdr->sadb_msg_seq; | 1697 | c.seq = hdr->sadb_msg_seq; |
| 1697 | c.pid = hdr->sadb_msg_pid; | 1698 | c.pid = hdr->sadb_msg_pid; |
| @@ -2685,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2685 | { | 2686 | { |
| 2686 | struct km_event c; | 2687 | struct km_event c; |
| 2687 | struct xfrm_audit audit_info; | 2688 | struct xfrm_audit audit_info; |
| 2689 | int err; | ||
| 2688 | 2690 | ||
| 2689 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 2691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
| 2690 | audit_info.secid = 0; | 2692 | audit_info.secid = 0; |
| 2691 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2693 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); |
| 2694 | if (err) | ||
| 2695 | return err; | ||
| 2692 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2696 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
| 2693 | c.event = XFRM_MSG_FLUSHPOLICY; | 2697 | c.event = XFRM_MSG_FLUSHPOLICY; |
| 2694 | c.pid = hdr->sadb_msg_pid; | 2698 | c.pid = hdr->sadb_msg_pid; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 7d9fa38b6a7d..6b8a103cf9e6 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
| @@ -324,7 +324,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
| 324 | memset(&laddr, 0, sizeof(laddr)); | 324 | memset(&laddr, 0, sizeof(laddr)); |
| 325 | memset(&daddr, 0, sizeof(daddr)); | 325 | memset(&daddr, 0, sizeof(daddr)); |
| 326 | /* | 326 | /* |
| 327 | * FIXME: check if the the address is multicast, | 327 | * FIXME: check if the address is multicast, |
| 328 | * only SOCK_DGRAM can do this. | 328 | * only SOCK_DGRAM can do this. |
| 329 | */ | 329 | */ |
| 330 | memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); | 330 | memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 6e36df67f8d5..4e84f24fd439 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
| @@ -2474,6 +2474,8 @@ static int ieee80211_open(struct net_device *dev) | |||
| 2474 | if (sdata->type == IEEE80211_IF_TYPE_STA && | 2474 | if (sdata->type == IEEE80211_IF_TYPE_STA && |
| 2475 | !local->user_space_mlme) | 2475 | !local->user_space_mlme) |
| 2476 | netif_carrier_off(dev); | 2476 | netif_carrier_off(dev); |
| 2477 | else | ||
| 2478 | netif_carrier_on(dev); | ||
| 2477 | 2479 | ||
| 2478 | netif_start_queue(dev); | 2480 | netif_start_queue(dev); |
| 2479 | return 0; | 2481 | return 0; |
| @@ -3278,8 +3280,10 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
| 3278 | return TXRX_DROP; | 3280 | return TXRX_DROP; |
| 3279 | } | 3281 | } |
| 3280 | } | 3282 | } |
| 3281 | while ((skb = __skb_dequeue(&entry->skb_list))) | 3283 | while ((skb = __skb_dequeue(&entry->skb_list))) { |
| 3282 | memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len); | 3284 | memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len); |
| 3285 | dev_kfree_skb(skb); | ||
| 3286 | } | ||
| 3283 | 3287 | ||
| 3284 | /* Complete frame has been reassembled - process it now */ | 3288 | /* Complete frame has been reassembled - process it now */ |
| 3285 | rx->fragmented = 1; | 3289 | rx->fragmented = 1; |
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 822917debeff..9f30ae4c2ab3 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, | 17 | * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, |
| 18 | * SSID) | 18 | * SSID) |
| 19 | */ | 19 | */ |
| 20 | #include <linux/delay.h> | ||
| 20 | #include <linux/if_ether.h> | 21 | #include <linux/if_ether.h> |
| 21 | #include <linux/skbuff.h> | 22 | #include <linux/skbuff.h> |
| 22 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
| @@ -27,7 +28,6 @@ | |||
| 27 | #include <linux/rtnetlink.h> | 28 | #include <linux/rtnetlink.h> |
| 28 | #include <net/iw_handler.h> | 29 | #include <net/iw_handler.h> |
| 29 | #include <asm/types.h> | 30 | #include <asm/types.h> |
| 30 | #include <asm/delay.h> | ||
| 31 | 31 | ||
| 32 | #include <net/mac80211.h> | 32 | #include <net/mac80211.h> |
| 33 | #include "ieee80211_i.h" | 33 | #include "ieee80211_i.h" |
| @@ -1155,6 +1155,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, | |||
| 1155 | if (status_code != WLAN_STATUS_SUCCESS) { | 1155 | if (status_code != WLAN_STATUS_SUCCESS) { |
| 1156 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", | 1156 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", |
| 1157 | dev->name, status_code); | 1157 | dev->name, status_code); |
| 1158 | if (status_code == WLAN_STATUS_REASSOC_NO_ASSOC) | ||
| 1159 | ifsta->prev_bssid_set = 0; | ||
| 1158 | return; | 1160 | return; |
| 1159 | } | 1161 | } |
| 1160 | 1162 | ||
| @@ -2995,7 +2997,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
| 2995 | { | 2997 | { |
| 2996 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2998 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 2997 | struct sta_info *sta; | 2999 | struct sta_info *sta; |
| 2998 | struct ieee80211_sub_if_data *sdata = NULL; | 3000 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2999 | 3001 | ||
| 3000 | /* TODO: Could consider removing the least recently used entry and | 3002 | /* TODO: Could consider removing the least recently used entry and |
| 3001 | * allow new one to be added. */ | 3003 | * allow new one to be added. */ |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index ea6211cade0a..a567dae8e5fd 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -197,7 +197,7 @@ config NF_CONNTRACK_PPTP | |||
| 197 | 197 | ||
| 198 | Please note that not all PPTP modes of operation are supported yet. | 198 | Please note that not all PPTP modes of operation are supported yet. |
| 199 | Specifically these limitations exist: | 199 | Specifically these limitations exist: |
| 200 | - Blindy assumes that control connections are always established | 200 | - Blindly assumes that control connections are always established |
| 201 | in PNS->PAC direction. This is a violation of RFC2637. | 201 | in PNS->PAC direction. This is a violation of RFC2637. |
| 202 | - Only supports a single call within each session | 202 | - Only supports a single call within each session |
| 203 | 203 | ||
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index b8869eab7650..0568f2e86b59 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c | |||
| @@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void) | |||
| 208 | { | 208 | { |
| 209 | int ret, i; | 209 | int ret, i; |
| 210 | 210 | ||
| 211 | ret = -ENOMEM; | ||
| 212 | for (i = 0; i < ARRAY_SIZE(search); i++) { | 211 | for (i = 0; i < ARRAY_SIZE(search); i++) { |
| 213 | search[i].ts = textsearch_prepare(ts_algo, search[i].string, | 212 | search[i].ts = textsearch_prepare(ts_algo, search[i].string, |
| 214 | search[i].len, | 213 | search[i].len, |
| 215 | GFP_KERNEL, TS_AUTOLOAD); | 214 | GFP_KERNEL, TS_AUTOLOAD); |
| 216 | if (search[i].ts == NULL) | 215 | if (IS_ERR(search[i].ts)) { |
| 216 | ret = PTR_ERR(search[i].ts); | ||
| 217 | goto err1; | 217 | goto err1; |
| 218 | } | ||
| 218 | } | 219 | } |
| 219 | ret = nf_conntrack_helper_register(&amanda_helper[0]); | 220 | ret = nf_conntrack_helper_register(&amanda_helper[0]); |
| 220 | if (ret < 0) | 221 | if (ret < 0) |
| @@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void) | |||
| 227 | err2: | 228 | err2: |
| 228 | nf_conntrack_helper_unregister(&amanda_helper[0]); | 229 | nf_conntrack_helper_unregister(&amanda_helper[0]); |
| 229 | err1: | 230 | err1: |
| 230 | for (; i >= 0; i--) { | 231 | while (--i >= 0) |
| 231 | if (search[i].ts) | 232 | textsearch_destroy(search[i].ts); |
| 232 | textsearch_destroy(search[i].ts); | 233 | |
| 233 | } | ||
| 234 | return ret; | 234 | return ret; |
| 235 | } | 235 | } |
| 236 | 236 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e132c8ae8784..7a15e30356f2 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -298,8 +298,6 @@ static void | |||
| 298 | destroy_conntrack(struct nf_conntrack *nfct) | 298 | destroy_conntrack(struct nf_conntrack *nfct) |
| 299 | { | 299 | { |
| 300 | struct nf_conn *ct = (struct nf_conn *)nfct; | 300 | struct nf_conn *ct = (struct nf_conn *)nfct; |
| 301 | struct nf_conn_help *help = nfct_help(ct); | ||
| 302 | struct nf_conntrack_l3proto *l3proto; | ||
| 303 | struct nf_conntrack_l4proto *l4proto; | 301 | struct nf_conntrack_l4proto *l4proto; |
| 304 | typeof(nf_conntrack_destroyed) destroyed; | 302 | typeof(nf_conntrack_destroyed) destroyed; |
| 305 | 303 | ||
| @@ -310,17 +308,10 @@ destroy_conntrack(struct nf_conntrack *nfct) | |||
| 310 | nf_conntrack_event(IPCT_DESTROY, ct); | 308 | nf_conntrack_event(IPCT_DESTROY, ct); |
| 311 | set_bit(IPS_DYING_BIT, &ct->status); | 309 | set_bit(IPS_DYING_BIT, &ct->status); |
| 312 | 310 | ||
| 313 | if (help && help->helper && help->helper->destroy) | ||
| 314 | help->helper->destroy(ct); | ||
| 315 | |||
| 316 | /* To make sure we don't get any weird locking issues here: | 311 | /* To make sure we don't get any weird locking issues here: |
| 317 | * destroy_conntrack() MUST NOT be called with a write lock | 312 | * destroy_conntrack() MUST NOT be called with a write lock |
| 318 | * to nf_conntrack_lock!!! -HW */ | 313 | * to nf_conntrack_lock!!! -HW */ |
| 319 | rcu_read_lock(); | 314 | rcu_read_lock(); |
| 320 | l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num); | ||
| 321 | if (l3proto && l3proto->destroy) | ||
| 322 | l3proto->destroy(ct); | ||
| 323 | |||
| 324 | l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, | 315 | l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, |
| 325 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum); | 316 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum); |
| 326 | if (l4proto && l4proto->destroy) | 317 | if (l4proto && l4proto->destroy) |
| @@ -358,6 +349,16 @@ destroy_conntrack(struct nf_conntrack *nfct) | |||
| 358 | static void death_by_timeout(unsigned long ul_conntrack) | 349 | static void death_by_timeout(unsigned long ul_conntrack) |
| 359 | { | 350 | { |
| 360 | struct nf_conn *ct = (void *)ul_conntrack; | 351 | struct nf_conn *ct = (void *)ul_conntrack; |
| 352 | struct nf_conn_help *help = nfct_help(ct); | ||
| 353 | struct nf_conntrack_helper *helper; | ||
| 354 | |||
| 355 | if (help) { | ||
| 356 | rcu_read_lock(); | ||
| 357 | helper = rcu_dereference(help->helper); | ||
| 358 | if (helper && helper->destroy) | ||
| 359 | helper->destroy(ct); | ||
| 360 | rcu_read_unlock(); | ||
| 361 | } | ||
| 361 | 362 | ||
| 362 | write_lock_bh(&nf_conntrack_lock); | 363 | write_lock_bh(&nf_conntrack_lock); |
| 363 | /* Inside lock so preempt is disabled on module removal path. | 364 | /* Inside lock so preempt is disabled on module removal path. |
| @@ -666,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
| 666 | unsigned int dataoff) | 667 | unsigned int dataoff) |
| 667 | { | 668 | { |
| 668 | struct nf_conn *conntrack; | 669 | struct nf_conn *conntrack; |
| 670 | struct nf_conn_help *help; | ||
| 669 | struct nf_conntrack_tuple repl_tuple; | 671 | struct nf_conntrack_tuple repl_tuple; |
| 670 | struct nf_conntrack_expect *exp; | 672 | struct nf_conntrack_expect *exp; |
| 671 | u_int32_t features = 0; | 673 | u_int32_t features = 0; |
| @@ -696,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
| 696 | write_lock_bh(&nf_conntrack_lock); | 698 | write_lock_bh(&nf_conntrack_lock); |
| 697 | exp = find_expectation(tuple); | 699 | exp = find_expectation(tuple); |
| 698 | 700 | ||
| 701 | help = nfct_help(conntrack); | ||
| 699 | if (exp) { | 702 | if (exp) { |
| 700 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", | 703 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", |
| 701 | conntrack, exp); | 704 | conntrack, exp); |
| @@ -703,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
| 703 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); | 706 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); |
| 704 | conntrack->master = exp->master; | 707 | conntrack->master = exp->master; |
| 705 | if (exp->helper) | 708 | if (exp->helper) |
| 706 | nfct_help(conntrack)->helper = exp->helper; | 709 | rcu_assign_pointer(help->helper, exp->helper); |
| 707 | #ifdef CONFIG_NF_CONNTRACK_MARK | 710 | #ifdef CONFIG_NF_CONNTRACK_MARK |
| 708 | conntrack->mark = exp->master->mark; | 711 | conntrack->mark = exp->master->mark; |
| 709 | #endif | 712 | #endif |
| @@ -713,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
| 713 | nf_conntrack_get(&conntrack->master->ct_general); | 716 | nf_conntrack_get(&conntrack->master->ct_general); |
| 714 | NF_CT_STAT_INC(expect_new); | 717 | NF_CT_STAT_INC(expect_new); |
| 715 | } else { | 718 | } else { |
| 716 | struct nf_conn_help *help = nfct_help(conntrack); | 719 | if (help) { |
| 717 | 720 | /* not in hash table yet, so not strictly necessary */ | |
| 718 | if (help) | 721 | rcu_assign_pointer(help->helper, |
| 719 | help->helper = __nf_ct_helper_find(&repl_tuple); | 722 | __nf_ct_helper_find(&repl_tuple)); |
| 723 | } | ||
| 720 | NF_CT_STAT_INC(new); | 724 | NF_CT_STAT_INC(new); |
| 721 | } | 725 | } |
| 722 | 726 | ||
| @@ -893,8 +897,14 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, | |||
| 893 | NF_CT_DUMP_TUPLE(newreply); | 897 | NF_CT_DUMP_TUPLE(newreply); |
| 894 | 898 | ||
| 895 | ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; | 899 | ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; |
| 896 | if (!ct->master && help && help->expecting == 0) | 900 | if (!ct->master && help && help->expecting == 0) { |
| 897 | help->helper = __nf_ct_helper_find(newreply); | 901 | struct nf_conntrack_helper *helper; |
| 902 | helper = __nf_ct_helper_find(newreply); | ||
| 903 | if (helper) | ||
| 904 | memset(&help->help, 0, sizeof(help->help)); | ||
| 905 | /* not in hash table yet, so not strictly necessary */ | ||
| 906 | rcu_assign_pointer(help->helper, helper); | ||
| 907 | } | ||
| 898 | write_unlock_bh(&nf_conntrack_lock); | 908 | write_unlock_bh(&nf_conntrack_lock); |
| 899 | } | 909 | } |
| 900 | EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); | 910 | EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); |
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index c31af29a4439..504fb6c083f9 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
| @@ -177,7 +177,7 @@ void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp) | |||
| 177 | struct nf_conntrack_expect *i; | 177 | struct nf_conntrack_expect *i; |
| 178 | 178 | ||
| 179 | write_lock_bh(&nf_conntrack_lock); | 179 | write_lock_bh(&nf_conntrack_lock); |
| 180 | /* choose the the oldest expectation to evict */ | 180 | /* choose the oldest expectation to evict */ |
| 181 | list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) { | 181 | list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) { |
| 182 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { | 182 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { |
| 183 | nf_ct_unlink_expect(i); | 183 | nf_ct_unlink_expect(i); |
| @@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) | |||
| 337 | NF_CT_ASSERT(master_help); | 337 | NF_CT_ASSERT(master_help); |
| 338 | 338 | ||
| 339 | write_lock_bh(&nf_conntrack_lock); | 339 | write_lock_bh(&nf_conntrack_lock); |
| 340 | if (!master_help->helper) { | ||
| 341 | ret = -ESHUTDOWN; | ||
| 342 | goto out; | ||
| 343 | } | ||
| 340 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { | 344 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { |
| 341 | if (expect_matches(i, expect)) { | 345 | if (expect_matches(i, expect)) { |
| 342 | /* Refresh timer: if it's dying, ignore.. */ | 346 | /* Refresh timer: if it's dying, ignore.. */ |
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index a186799f6542..82db2aa53bfc 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
| @@ -48,8 +48,7 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb, | |||
| 48 | enum nf_ct_ftp_type type, | 48 | enum nf_ct_ftp_type type, |
| 49 | unsigned int matchoff, | 49 | unsigned int matchoff, |
| 50 | unsigned int matchlen, | 50 | unsigned int matchlen, |
| 51 | struct nf_conntrack_expect *exp, | 51 | struct nf_conntrack_expect *exp); |
| 52 | u32 *seq); | ||
| 53 | EXPORT_SYMBOL_GPL(nf_nat_ftp_hook); | 52 | EXPORT_SYMBOL_GPL(nf_nat_ftp_hook); |
| 54 | 53 | ||
| 55 | #if 0 | 54 | #if 0 |
| @@ -335,15 +334,17 @@ static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir, | |||
| 335 | if (info->seq_aft_nl[dir][i] == nl_seq) | 334 | if (info->seq_aft_nl[dir][i] == nl_seq) |
| 336 | return; | 335 | return; |
| 337 | 336 | ||
| 338 | if (oldest == info->seq_aft_nl_num[dir] | 337 | if (oldest == info->seq_aft_nl_num[dir] || |
| 339 | || before(info->seq_aft_nl[dir][i], oldest)) | 338 | before(info->seq_aft_nl[dir][i], |
| 339 | info->seq_aft_nl[dir][oldest])) | ||
| 340 | oldest = i; | 340 | oldest = i; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { | 343 | if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { |
| 344 | info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; | 344 | info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; |
| 345 | nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); | 345 | nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); |
| 346 | } else if (oldest != NUM_SEQ_TO_REMEMBER) { | 346 | } else if (oldest != NUM_SEQ_TO_REMEMBER && |
| 347 | after(nl_seq, info->seq_aft_nl[dir][oldest])) { | ||
| 347 | info->seq_aft_nl[dir][oldest] = nl_seq; | 348 | info->seq_aft_nl[dir][oldest] = nl_seq; |
| 348 | nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); | 349 | nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); |
| 349 | } | 350 | } |
| @@ -519,7 +520,7 @@ static int help(struct sk_buff **pskb, | |||
| 519 | nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook); | 520 | nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook); |
| 520 | if (nf_nat_ftp && ct->status & IPS_NAT_MASK) | 521 | if (nf_nat_ftp && ct->status & IPS_NAT_MASK) |
| 521 | ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype, | 522 | ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype, |
| 522 | matchoff, matchlen, exp, &seq); | 523 | matchoff, matchlen, exp); |
| 523 | else { | 524 | else { |
| 524 | /* Can't expect this? Best to drop packet now. */ | 525 | /* Can't expect this? Best to drop packet now. */ |
| 525 | if (nf_conntrack_expect_related(exp) != 0) | 526 | if (nf_conntrack_expect_related(exp) != 0) |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index b284db73ca7c..a1b95acad297 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -520,6 +520,16 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct, | |||
| 520 | } | 520 | } |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | if ((olca->options & eOpenLogicalChannelAck_separateStack) && | ||
| 524 | olca->separateStack.networkAddress.choice == | ||
| 525 | eNetworkAccessParameters_networkAddress_localAreaAddress) { | ||
| 526 | ret = expect_t120(pskb, ct, ctinfo, data, dataoff, | ||
| 527 | &olca->separateStack.networkAddress. | ||
| 528 | localAreaAddress); | ||
| 529 | if (ret < 0) | ||
| 530 | return -1; | ||
| 531 | } | ||
| 532 | |||
| 523 | return 0; | 533 | return 0; |
| 524 | } | 534 | } |
| 525 | 535 | ||
| @@ -640,7 +650,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data, | |||
| 640 | case eTransportAddress_ip6Address: | 650 | case eTransportAddress_ip6Address: |
| 641 | if (family != AF_INET6) | 651 | if (family != AF_INET6) |
| 642 | return 0; | 652 | return 0; |
| 643 | p = data + taddr->ip6Address.ip6; | 653 | p = data + taddr->ip6Address.ip; |
| 644 | len = 16; | 654 | len = 16; |
| 645 | break; | 655 | break; |
| 646 | default: | 656 | default: |
| @@ -977,30 +987,6 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct, | |||
| 977 | } | 987 | } |
| 978 | 988 | ||
| 979 | /****************************************************************************/ | 989 | /****************************************************************************/ |
| 980 | static int process_information(struct sk_buff **pskb, | ||
| 981 | struct nf_conn *ct, | ||
| 982 | enum ip_conntrack_info ctinfo, | ||
| 983 | unsigned char **data, int dataoff, | ||
| 984 | Information_UUIE *info) | ||
| 985 | { | ||
| 986 | int ret; | ||
| 987 | int i; | ||
| 988 | |||
| 989 | DEBUGP("nf_ct_q931: Information\n"); | ||
| 990 | |||
| 991 | if (info->options & eInformation_UUIE_fastStart) { | ||
| 992 | for (i = 0; i < info->fastStart.count; i++) { | ||
| 993 | ret = process_olc(pskb, ct, ctinfo, data, dataoff, | ||
| 994 | &info->fastStart.item[i]); | ||
| 995 | if (ret < 0) | ||
| 996 | return -1; | ||
| 997 | } | ||
| 998 | } | ||
| 999 | |||
| 1000 | return 0; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | /****************************************************************************/ | ||
| 1004 | static int process_facility(struct sk_buff **pskb, struct nf_conn *ct, | 990 | static int process_facility(struct sk_buff **pskb, struct nf_conn *ct, |
| 1005 | enum ip_conntrack_info ctinfo, | 991 | enum ip_conntrack_info ctinfo, |
| 1006 | unsigned char **data, int dataoff, | 992 | unsigned char **data, int dataoff, |
| @@ -1096,11 +1082,6 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct, | |||
| 1096 | ret = process_alerting(pskb, ct, ctinfo, data, dataoff, | 1082 | ret = process_alerting(pskb, ct, ctinfo, data, dataoff, |
| 1097 | &pdu->h323_message_body.alerting); | 1083 | &pdu->h323_message_body.alerting); |
| 1098 | break; | 1084 | break; |
| 1099 | case eH323_UU_PDU_h323_message_body_information: | ||
| 1100 | ret = process_information(pskb, ct, ctinfo, data, dataoff, | ||
| 1101 | &pdu->h323_message_body. | ||
| 1102 | information); | ||
| 1103 | break; | ||
| 1104 | case eH323_UU_PDU_h323_message_body_facility: | 1085 | case eH323_UU_PDU_h323_message_body_facility: |
| 1105 | ret = process_facility(pskb, ct, ctinfo, data, dataoff, | 1086 | ret = process_facility(pskb, ct, ctinfo, data, dataoff, |
| 1106 | &pdu->h323_message_body.facility); | 1087 | &pdu->h323_message_body.facility); |
diff --git a/net/netfilter/nf_conntrack_h323_types.c b/net/netfilter/nf_conntrack_h323_types.c index 4c6f8b3b1208..3a21fdf1a265 100644 --- a/net/netfilter/nf_conntrack_h323_types.c +++ b/net/netfilter/nf_conntrack_h323_types.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006 | 1 | /* Generated by Jing Min Zhao's ASN.1 parser, May 16 2007 |
| 2 | * | 2 | * |
| 3 | * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> | 3 | * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
| 4 | * | 4 | * |
| @@ -37,7 +37,7 @@ static field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */ | |||
| 37 | 37 | ||
| 38 | static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */ | 38 | static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */ |
| 39 | {FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE, | 39 | {FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE, |
| 40 | offsetof(TransportAddress_ip6Address, ip6), NULL}, | 40 | offsetof(TransportAddress_ip6Address, ip), NULL}, |
| 41 | {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL}, | 41 | {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL}, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| @@ -67,7 +67,8 @@ static field_t _TransportAddress[] = { /* CHOICE */ | |||
| 67 | {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0, | 67 | {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0, |
| 68 | _TransportAddress_ipxAddress}, | 68 | _TransportAddress_ipxAddress}, |
| 69 | {FNAME("ip6Address") SEQ, 0, 2, 2, DECODE | EXT, | 69 | {FNAME("ip6Address") SEQ, 0, 2, 2, DECODE | EXT, |
| 70 | offsetof(TransportAddress, ip6Address), _TransportAddress_ip6Address}, | 70 | offsetof(TransportAddress, ip6Address), |
| 71 | _TransportAddress_ip6Address}, | ||
| 71 | {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, | 72 | {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, |
| 72 | {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL}, | 73 | {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL}, |
| 73 | {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, | 74 | {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, |
| @@ -638,7 +639,8 @@ static field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */ | |||
| 638 | }; | 639 | }; |
| 639 | 640 | ||
| 640 | static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */ | 641 | static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */ |
| 641 | {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, | 642 | {FNAME("network") OCTSTR, FIXD, 16, 0, DECODE, |
| 643 | offsetof(UnicastAddress_iP6Address, network), NULL}, | ||
| 642 | {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL}, | 644 | {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL}, |
| 643 | }; | 645 | }; |
| 644 | 646 | ||
| @@ -665,8 +667,8 @@ static field_t _UnicastAddress[] = { /* CHOICE */ | |||
| 665 | offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress}, | 667 | offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress}, |
| 666 | {FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0, | 668 | {FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0, |
| 667 | _UnicastAddress_iPXAddress}, | 669 | _UnicastAddress_iPXAddress}, |
| 668 | {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0, | 670 | {FNAME("iP6Address") SEQ, 0, 2, 2, DECODE | EXT, |
| 669 | _UnicastAddress_iP6Address}, | 671 | offsetof(UnicastAddress, iP6Address), _UnicastAddress_iP6Address}, |
| 670 | {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, | 672 | {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, |
| 671 | {FNAME("iPSourceRouteAddress") SEQ, 0, 4, 4, SKIP | EXT, 0, | 673 | {FNAME("iPSourceRouteAddress") SEQ, 0, 4, 4, SKIP | EXT, 0, |
| 672 | _UnicastAddress_iPSourceRouteAddress}, | 674 | _UnicastAddress_iPSourceRouteAddress}, |
| @@ -984,19 +986,12 @@ static field_t _Alerting_UUIE[] = { /* SEQUENCE */ | |||
| 984 | {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL}, | 986 | {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL}, |
| 985 | }; | 987 | }; |
| 986 | 988 | ||
| 987 | static field_t _Information_UUIE_fastStart[] = { /* SEQUENCE OF */ | ||
| 988 | {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT, | ||
| 989 | sizeof(OpenLogicalChannel), _OpenLogicalChannel} | ||
| 990 | , | ||
| 991 | }; | ||
| 992 | |||
| 993 | static field_t _Information_UUIE[] = { /* SEQUENCE */ | 989 | static field_t _Information_UUIE[] = { /* SEQUENCE */ |
| 994 | {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL}, | 990 | {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL}, |
| 995 | {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL}, | 991 | {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL}, |
| 996 | {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL}, | 992 | {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL}, |
| 997 | {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL}, | 993 | {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL}, |
| 998 | {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT, | 994 | {FNAME("fastStart") SEQOF, SEMI, 0, 30, SKIP | OPT, 0, NULL}, |
| 999 | offsetof(Information_UUIE, fastStart), _Information_UUIE_fastStart}, | ||
| 1000 | {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL}, | 995 | {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL}, |
| 1001 | {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL}, | 996 | {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL}, |
| 1002 | }; | 997 | }; |
| @@ -1343,9 +1338,7 @@ static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */ | |||
| 1343 | offsetof(H323_UU_PDU_h323_message_body, connect), _Connect_UUIE}, | 1338 | offsetof(H323_UU_PDU_h323_message_body, connect), _Connect_UUIE}, |
| 1344 | {FNAME("alerting") SEQ, 1, 3, 17, DECODE | EXT, | 1339 | {FNAME("alerting") SEQ, 1, 3, 17, DECODE | EXT, |
| 1345 | offsetof(H323_UU_PDU_h323_message_body, alerting), _Alerting_UUIE}, | 1340 | offsetof(H323_UU_PDU_h323_message_body, alerting), _Alerting_UUIE}, |
| 1346 | {FNAME("information") SEQ, 0, 1, 7, DECODE | EXT, | 1341 | {FNAME("information") SEQ, 0, 1, 7, SKIP | EXT, 0, _Information_UUIE}, |
| 1347 | offsetof(H323_UU_PDU_h323_message_body, information), | ||
| 1348 | _Information_UUIE}, | ||
| 1349 | {FNAME("releaseComplete") SEQ, 1, 2, 11, SKIP | EXT, 0, | 1342 | {FNAME("releaseComplete") SEQ, 1, 2, 11, SKIP | EXT, 0, |
| 1350 | _ReleaseComplete_UUIE}, | 1343 | _ReleaseComplete_UUIE}, |
| 1351 | {FNAME("facility") SEQ, 3, 5, 21, DECODE | EXT, | 1344 | {FNAME("facility") SEQ, 3, 5, 21, DECODE | EXT, |
| @@ -1430,7 +1423,9 @@ static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */ | |||
| 1430 | DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck, | 1423 | DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck, |
| 1431 | reverseLogicalChannelParameters), | 1424 | reverseLogicalChannelParameters), |
| 1432 | _OpenLogicalChannelAck_reverseLogicalChannelParameters}, | 1425 | _OpenLogicalChannelAck_reverseLogicalChannelParameters}, |
| 1433 | {FNAME("separateStack") SEQ, 2, 4, 5, SKIP | EXT | OPT, 0, NULL}, | 1426 | {FNAME("separateStack") SEQ, 2, 4, 5, DECODE | EXT | OPT, |
| 1427 | offsetof(OpenLogicalChannelAck, separateStack), | ||
| 1428 | _NetworkAccessParameters}, | ||
| 1434 | {FNAME("forwardMultiplexAckParameters") CHOICE, 0, 1, 1, | 1429 | {FNAME("forwardMultiplexAckParameters") CHOICE, 0, 1, 1, |
| 1435 | DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck, | 1430 | DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck, |
| 1436 | forwardMultiplexAckParameters), | 1431 | forwardMultiplexAckParameters), |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 0743be4434b0..f868b7fbd9b4 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
| @@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i, | |||
| 93 | 93 | ||
| 94 | if (help && help->helper == me) { | 94 | if (help && help->helper == me) { |
| 95 | nf_conntrack_event(IPCT_HELPER, ct); | 95 | nf_conntrack_event(IPCT_HELPER, ct); |
| 96 | help->helper = NULL; | 96 | rcu_assign_pointer(help->helper, NULL); |
| 97 | } | 97 | } |
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index aa1a97ee514b..3f73327794ab 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
| 171 | { | 171 | { |
| 172 | struct nfattr *nest_helper; | 172 | struct nfattr *nest_helper; |
| 173 | const struct nf_conn_help *help = nfct_help(ct); | 173 | const struct nf_conn_help *help = nfct_help(ct); |
| 174 | struct nf_conntrack_helper *helper; | ||
| 174 | 175 | ||
| 175 | if (!help || !help->helper) | 176 | if (!help) |
| 176 | return 0; | 177 | return 0; |
| 177 | 178 | ||
| 179 | rcu_read_lock(); | ||
| 180 | helper = rcu_dereference(help->helper); | ||
| 181 | if (!helper) | ||
| 182 | goto out; | ||
| 183 | |||
| 178 | nest_helper = NFA_NEST(skb, CTA_HELP); | 184 | nest_helper = NFA_NEST(skb, CTA_HELP); |
| 179 | NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name); | 185 | NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); |
| 180 | 186 | ||
| 181 | if (help->helper->to_nfattr) | 187 | if (helper->to_nfattr) |
| 182 | help->helper->to_nfattr(skb, ct); | 188 | helper->to_nfattr(skb, ct); |
| 183 | 189 | ||
| 184 | NFA_NEST_END(skb, nest_helper); | 190 | NFA_NEST_END(skb, nest_helper); |
| 185 | 191 | out: | |
| 192 | rcu_read_unlock(); | ||
| 186 | return 0; | 193 | return 0; |
| 187 | 194 | ||
| 188 | nfattr_failure: | 195 | nfattr_failure: |
| 196 | rcu_read_unlock(); | ||
| 189 | return -1; | 197 | return -1; |
| 190 | } | 198 | } |
| 191 | 199 | ||
| @@ -830,11 +838,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
| 830 | char *helpname; | 838 | char *helpname; |
| 831 | int err; | 839 | int err; |
| 832 | 840 | ||
| 833 | if (!help) { | ||
| 834 | /* FIXME: we need to reallocate and rehash */ | ||
| 835 | return -EBUSY; | ||
| 836 | } | ||
| 837 | |||
| 838 | /* don't change helper of sibling connections */ | 841 | /* don't change helper of sibling connections */ |
| 839 | if (ct->master) | 842 | if (ct->master) |
| 840 | return -EINVAL; | 843 | return -EINVAL; |
| @@ -843,26 +846,35 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
| 843 | if (err < 0) | 846 | if (err < 0) |
| 844 | return err; | 847 | return err; |
| 845 | 848 | ||
| 846 | helper = __nf_conntrack_helper_find_byname(helpname); | 849 | if (!strcmp(helpname, "")) { |
| 847 | if (!helper) { | 850 | if (help && help->helper) { |
| 848 | if (!strcmp(helpname, "")) | ||
| 849 | helper = NULL; | ||
| 850 | else | ||
| 851 | return -EINVAL; | ||
| 852 | } | ||
| 853 | |||
| 854 | if (help->helper) { | ||
| 855 | if (!helper) { | ||
| 856 | /* we had a helper before ... */ | 851 | /* we had a helper before ... */ |
| 857 | nf_ct_remove_expectations(ct); | 852 | nf_ct_remove_expectations(ct); |
| 858 | help->helper = NULL; | 853 | rcu_assign_pointer(help->helper, NULL); |
| 859 | } else { | ||
| 860 | /* need to zero data of old helper */ | ||
| 861 | memset(&help->help, 0, sizeof(help->help)); | ||
| 862 | } | 854 | } |
| 855 | |||
| 856 | return 0; | ||
| 857 | } | ||
| 858 | |||
| 859 | if (!help) { | ||
| 860 | /* FIXME: we need to reallocate and rehash */ | ||
| 861 | return -EBUSY; | ||
| 863 | } | 862 | } |
| 864 | 863 | ||
| 865 | help->helper = helper; | 864 | helper = __nf_conntrack_helper_find_byname(helpname); |
| 865 | if (helper == NULL) | ||
| 866 | return -EINVAL; | ||
| 867 | |||
| 868 | if (help->helper == helper) | ||
| 869 | return 0; | ||
| 870 | |||
| 871 | if (help->helper) | ||
| 872 | /* we had a helper before ... */ | ||
| 873 | nf_ct_remove_expectations(ct); | ||
| 874 | |||
| 875 | /* need to zero data of old helper */ | ||
| 876 | memset(&help->help, 0, sizeof(help->help)); | ||
| 877 | rcu_assign_pointer(help->helper, helper); | ||
| 866 | 878 | ||
| 867 | return 0; | 879 | return 0; |
| 868 | } | 880 | } |
| @@ -946,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
| 946 | struct nf_conn *ct; | 958 | struct nf_conn *ct; |
| 947 | int err = -EINVAL; | 959 | int err = -EINVAL; |
| 948 | struct nf_conn_help *help; | 960 | struct nf_conn_help *help; |
| 961 | struct nf_conntrack_helper *helper = NULL; | ||
| 949 | 962 | ||
| 950 | ct = nf_conntrack_alloc(otuple, rtuple); | 963 | ct = nf_conntrack_alloc(otuple, rtuple); |
| 951 | if (ct == NULL || IS_ERR(ct)) | 964 | if (ct == NULL || IS_ERR(ct)) |
| @@ -976,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
| 976 | #endif | 989 | #endif |
| 977 | 990 | ||
| 978 | help = nfct_help(ct); | 991 | help = nfct_help(ct); |
| 979 | if (help) | 992 | if (help) { |
| 980 | help->helper = nf_ct_helper_find_get(rtuple); | 993 | helper = nf_ct_helper_find_get(rtuple); |
| 994 | /* not in hash table yet so not strictly necessary */ | ||
| 995 | rcu_assign_pointer(help->helper, helper); | ||
| 996 | } | ||
| 981 | 997 | ||
| 982 | add_timer(&ct->timeout); | 998 | add_timer(&ct->timeout); |
| 983 | nf_conntrack_hash_insert(ct); | 999 | nf_conntrack_hash_insert(ct); |
| 984 | 1000 | ||
| 985 | if (help && help->helper) | 1001 | if (helper) |
| 986 | nf_ct_helper_put(help->helper); | 1002 | nf_ct_helper_put(helper); |
| 987 | 1003 | ||
| 988 | return 0; | 1004 | return 0; |
| 989 | 1005 | ||
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 5434472420fe..339c397d1b5f 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c | |||
| @@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, | |||
| 100 | struct nf_conn_help *help = nfct_help(ct); | 100 | struct nf_conn_help *help = nfct_help(ct); |
| 101 | struct nf_ct_gre_keymap **kmp, *km; | 101 | struct nf_ct_gre_keymap **kmp, *km; |
| 102 | 102 | ||
| 103 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
| 104 | kmp = &help->help.ct_pptp_info.keymap[dir]; | 103 | kmp = &help->help.ct_pptp_info.keymap[dir]; |
| 105 | if (*kmp) { | 104 | if (*kmp) { |
| 106 | /* check whether it's a retransmission */ | 105 | /* check whether it's a retransmission */ |
| @@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct) | |||
| 137 | enum ip_conntrack_dir dir; | 136 | enum ip_conntrack_dir dir; |
| 138 | 137 | ||
| 139 | DEBUGP("entering for ct %p\n", ct); | 138 | DEBUGP("entering for ct %p\n", ct); |
| 140 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
| 141 | 139 | ||
| 142 | write_lock_bh(&nf_ct_gre_lock); | 140 | write_lock_bh(&nf_ct_gre_lock); |
| 143 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { | 141 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index f4ea8fe07a53..189ded5f378b 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
| @@ -134,12 +134,66 @@ static void destroy(const struct xt_match *match, void *matchinfo) | |||
| 134 | nf_ct_l3proto_module_put(match->family); | 134 | nf_ct_l3proto_module_put(match->family); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | #ifdef CONFIG_COMPAT | ||
| 138 | struct compat_xt_conntrack_info | ||
| 139 | { | ||
| 140 | compat_uint_t statemask; | ||
| 141 | compat_uint_t statusmask; | ||
| 142 | struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; | ||
| 143 | struct in_addr sipmsk[IP_CT_DIR_MAX]; | ||
| 144 | struct in_addr dipmsk[IP_CT_DIR_MAX]; | ||
| 145 | compat_ulong_t expires_min; | ||
| 146 | compat_ulong_t expires_max; | ||
| 147 | u_int8_t flags; | ||
| 148 | u_int8_t invflags; | ||
| 149 | }; | ||
| 150 | |||
| 151 | static void compat_from_user(void *dst, void *src) | ||
| 152 | { | ||
| 153 | struct compat_xt_conntrack_info *cm = src; | ||
| 154 | struct xt_conntrack_info m = { | ||
| 155 | .statemask = cm->statemask, | ||
| 156 | .statusmask = cm->statusmask, | ||
| 157 | .expires_min = cm->expires_min, | ||
| 158 | .expires_max = cm->expires_max, | ||
| 159 | .flags = cm->flags, | ||
| 160 | .invflags = cm->invflags, | ||
| 161 | }; | ||
| 162 | memcpy(m.tuple, cm->tuple, sizeof(m.tuple)); | ||
| 163 | memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk)); | ||
| 164 | memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk)); | ||
| 165 | memcpy(dst, &m, sizeof(m)); | ||
| 166 | } | ||
| 167 | |||
| 168 | static int compat_to_user(void __user *dst, void *src) | ||
| 169 | { | ||
| 170 | struct xt_conntrack_info *m = src; | ||
| 171 | struct compat_xt_conntrack_info cm = { | ||
| 172 | .statemask = m->statemask, | ||
| 173 | .statusmask = m->statusmask, | ||
| 174 | .expires_min = m->expires_min, | ||
| 175 | .expires_max = m->expires_max, | ||
| 176 | .flags = m->flags, | ||
| 177 | .invflags = m->invflags, | ||
| 178 | }; | ||
| 179 | memcpy(cm.tuple, m->tuple, sizeof(cm.tuple)); | ||
| 180 | memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk)); | ||
| 181 | memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk)); | ||
| 182 | return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; | ||
| 183 | } | ||
| 184 | #endif | ||
| 185 | |||
| 137 | static struct xt_match conntrack_match = { | 186 | static struct xt_match conntrack_match = { |
| 138 | .name = "conntrack", | 187 | .name = "conntrack", |
| 139 | .match = match, | 188 | .match = match, |
| 140 | .checkentry = checkentry, | 189 | .checkentry = checkentry, |
| 141 | .destroy = destroy, | 190 | .destroy = destroy, |
| 142 | .matchsize = sizeof(struct xt_conntrack_info), | 191 | .matchsize = sizeof(struct xt_conntrack_info), |
| 192 | #ifdef CONFIG_COMPAT | ||
| 193 | .compatsize = sizeof(struct compat_xt_conntrack_info), | ||
| 194 | .compat_from_user = compat_from_user, | ||
| 195 | .compat_to_user = compat_to_user, | ||
| 196 | #endif | ||
| 143 | .family = AF_INET, | 197 | .family = AF_INET, |
| 144 | .me = THIS_MODULE, | 198 | .me = THIS_MODULE, |
| 145 | }; | 199 | }; |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 07e47dbcb0a9..24b660f16ce3 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
| @@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = { | |||
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | /* NetLabel Netlink attribute policy */ | 61 | /* NetLabel Netlink attribute policy */ |
| 62 | static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { |
| 63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, | 63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, |
| 64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, | 64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, |
| 65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, | 65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index f2535e7f2869..b165712aaa70 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
| @@ -246,19 +246,18 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, | |||
| 246 | 246 | ||
| 247 | /** | 247 | /** |
| 248 | * netlbl_socket_setattr - Label a socket using the correct protocol | 248 | * netlbl_socket_setattr - Label a socket using the correct protocol |
| 249 | * @sock: the socket to label | 249 | * @sk: the socket to label |
| 250 | * @secattr: the security attributes | 250 | * @secattr: the security attributes |
| 251 | * | 251 | * |
| 252 | * Description: | 252 | * Description: |
| 253 | * Attach the correct label to the given socket using the security attributes | 253 | * Attach the correct label to the given socket using the security attributes |
| 254 | * specified in @secattr. This function requires exclusive access to | 254 | * specified in @secattr. This function requires exclusive access to @sk, |
| 255 | * @sock->sk, which means it either needs to be in the process of being | 255 | * which means it either needs to be in the process of being created or locked. |
| 256 | * created or locked via lock_sock(sock->sk). Returns zero on success, | 256 | * Returns zero on success, negative values on failure. |
| 257 | * negative values on failure. | ||
| 258 | * | 257 | * |
| 259 | */ | 258 | */ |
| 260 | int netlbl_socket_setattr(const struct socket *sock, | 259 | int netlbl_sock_setattr(struct sock *sk, |
| 261 | const struct netlbl_lsm_secattr *secattr) | 260 | const struct netlbl_lsm_secattr *secattr) |
| 262 | { | 261 | { |
| 263 | int ret_val = -ENOENT; | 262 | int ret_val = -ENOENT; |
| 264 | struct netlbl_dom_map *dom_entry; | 263 | struct netlbl_dom_map *dom_entry; |
| @@ -269,9 +268,9 @@ int netlbl_socket_setattr(const struct socket *sock, | |||
| 269 | goto socket_setattr_return; | 268 | goto socket_setattr_return; |
| 270 | switch (dom_entry->type) { | 269 | switch (dom_entry->type) { |
| 271 | case NETLBL_NLTYPE_CIPSOV4: | 270 | case NETLBL_NLTYPE_CIPSOV4: |
| 272 | ret_val = cipso_v4_socket_setattr(sock, | 271 | ret_val = cipso_v4_sock_setattr(sk, |
| 273 | dom_entry->type_def.cipsov4, | 272 | dom_entry->type_def.cipsov4, |
| 274 | secattr); | 273 | secattr); |
| 275 | break; | 274 | break; |
| 276 | case NETLBL_NLTYPE_UNLABELED: | 275 | case NETLBL_NLTYPE_UNLABELED: |
| 277 | ret_val = 0; | 276 | ret_val = 0; |
| @@ -309,30 +308,6 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
| 309 | } | 308 | } |
| 310 | 309 | ||
| 311 | /** | 310 | /** |
| 312 | * netlbl_socket_getattr - Determine the security attributes of a socket | ||
| 313 | * @sock: the socket | ||
| 314 | * @secattr: the security attributes | ||
| 315 | * | ||
| 316 | * Description: | ||
| 317 | * Examines the given socket to see any NetLabel style labeling has been | ||
| 318 | * applied to the socket, if so it parses the socket label and returns the | ||
| 319 | * security attributes in @secattr. Returns zero on success, negative values | ||
| 320 | * on failure. | ||
| 321 | * | ||
| 322 | */ | ||
| 323 | int netlbl_socket_getattr(const struct socket *sock, | ||
| 324 | struct netlbl_lsm_secattr *secattr) | ||
| 325 | { | ||
| 326 | int ret_val; | ||
| 327 | |||
| 328 | ret_val = cipso_v4_socket_getattr(sock, secattr); | ||
| 329 | if (ret_val == 0) | ||
| 330 | return 0; | ||
| 331 | |||
| 332 | return netlbl_unlabel_getattr(secattr); | ||
| 333 | } | ||
| 334 | |||
| 335 | /** | ||
| 336 | * netlbl_skbuff_getattr - Determine the security attributes of a packet | 311 | * netlbl_skbuff_getattr - Determine the security attributes of a packet |
| 337 | * @skb: the packet | 312 | * @skb: the packet |
| 338 | * @secattr: the security attributes | 313 | * @secattr: the security attributes |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index e8c80f33f3d7..e00fc219c72b 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
| @@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = { | |||
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | /* NetLabel Netlink attribute policy */ | 61 | /* NetLabel Netlink attribute policy */ |
| 62 | static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { |
| 63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, | 63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, |
| 64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, | 64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, |
| 65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, | 65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index b931edee4b8b..5c303c68af1d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
| @@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | /* NetLabel Netlink attribute policy */ | 63 | /* NetLabel Netlink attribute policy */ |
| 64 | static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { | 64 | static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { |
| 65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, | 65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 507828d7d4ae..1f15821c8da4 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <linux/rtnetlink.h> | 45 | #include <linux/rtnetlink.h> |
| 46 | #include <linux/proc_fs.h> | 46 | #include <linux/proc_fs.h> |
| 47 | #include <linux/seq_file.h> | 47 | #include <linux/seq_file.h> |
| 48 | #include <linux/smp_lock.h> | ||
| 49 | #include <linux/notifier.h> | 48 | #include <linux/notifier.h> |
| 50 | #include <linux/security.h> | 49 | #include <linux/security.h> |
| 51 | #include <linux/jhash.h> | 50 | #include <linux/jhash.h> |
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index df5f820a4c32..c591212793ee 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
| @@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { | |||
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | static int validate_nla(struct nlattr *nla, int maxtype, | 26 | static int validate_nla(struct nlattr *nla, int maxtype, |
| 27 | struct nla_policy *policy) | 27 | const struct nla_policy *policy) |
| 28 | { | 28 | { |
| 29 | struct nla_policy *pt; | 29 | const struct nla_policy *pt; |
| 30 | int minlen = 0, attrlen = nla_len(nla); | 30 | int minlen = 0, attrlen = nla_len(nla); |
| 31 | 31 | ||
| 32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) | 32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) |
| @@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype, | |||
| 99 | * Returns 0 on success or a negative error code. | 99 | * Returns 0 on success or a negative error code. |
| 100 | */ | 100 | */ |
| 101 | int nla_validate(struct nlattr *head, int len, int maxtype, | 101 | int nla_validate(struct nlattr *head, int len, int maxtype, |
| 102 | struct nla_policy *policy) | 102 | const struct nla_policy *policy) |
| 103 | { | 103 | { |
| 104 | struct nlattr *nla; | 104 | struct nlattr *nla; |
| 105 | int rem, err; | 105 | int rem, err; |
| @@ -130,7 +130,7 @@ errout: | |||
| 130 | * Returns 0 on success or a negative error code. | 130 | * Returns 0 on success or a negative error code. |
| 131 | */ | 131 | */ |
| 132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, | 132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, |
| 133 | struct nla_policy *policy) | 133 | const struct nla_policy *policy) |
| 134 | { | 134 | { |
| 135 | struct nlattr *nla; | 135 | struct nlattr *nla; |
| 136 | int rem, err; | 136 | int rem, err; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 6e31234a4196..b9ab62f938d0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | |||
| 472 | return skb; | 472 | return skb; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { | 475 | static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { |
| 476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, | 476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, |
| 477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, | 477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, |
| 478 | .len = GENL_NAMSIZ - 1 }, | 478 | .len = GENL_NAMSIZ - 1 }, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 02e401cd683f..f8b83014ccca 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -83,22 +83,6 @@ | |||
| 83 | #include <net/inet_common.h> | 83 | #include <net/inet_common.h> |
| 84 | #endif | 84 | #endif |
| 85 | 85 | ||
| 86 | #define CONFIG_SOCK_PACKET 1 | ||
| 87 | |||
| 88 | /* | ||
| 89 | Proposed replacement for SIOC{ADD,DEL}MULTI and | ||
| 90 | IFF_PROMISC, IFF_ALLMULTI flags. | ||
| 91 | |||
| 92 | It is more expensive, but I believe, | ||
| 93 | it is really correct solution: reentereble, safe and fault tolerant. | ||
| 94 | |||
| 95 | IFF_PROMISC/IFF_ALLMULTI/SIOC{ADD/DEL}MULTI are faked by keeping | ||
| 96 | reference count and global flag, so that real status is | ||
| 97 | (gflag|(count != 0)), so that we can use obsolete faulty interface | ||
| 98 | not harming clever users. | ||
| 99 | */ | ||
| 100 | #define CONFIG_PACKET_MULTICAST 1 | ||
| 101 | |||
| 102 | /* | 86 | /* |
| 103 | Assumptions: | 87 | Assumptions: |
| 104 | - if device has no dev->hard_header routine, it adds and removes ll header | 88 | - if device has no dev->hard_header routine, it adds and removes ll header |
| @@ -159,7 +143,6 @@ static atomic_t packet_socks_nr; | |||
| 159 | 143 | ||
| 160 | /* Private packet socket structures. */ | 144 | /* Private packet socket structures. */ |
| 161 | 145 | ||
| 162 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 163 | struct packet_mclist | 146 | struct packet_mclist |
| 164 | { | 147 | { |
| 165 | struct packet_mclist *next; | 148 | struct packet_mclist *next; |
| @@ -179,7 +162,7 @@ struct packet_mreq_max | |||
| 179 | unsigned short mr_alen; | 162 | unsigned short mr_alen; |
| 180 | unsigned char mr_address[MAX_ADDR_LEN]; | 163 | unsigned char mr_address[MAX_ADDR_LEN]; |
| 181 | }; | 164 | }; |
| 182 | #endif | 165 | |
| 183 | #ifdef CONFIG_PACKET_MMAP | 166 | #ifdef CONFIG_PACKET_MMAP |
| 184 | static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing); | 167 | static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing); |
| 185 | #endif | 168 | #endif |
| @@ -205,9 +188,7 @@ struct packet_sock { | |||
| 205 | origdev:1; | 188 | origdev:1; |
| 206 | int ifindex; /* bound device */ | 189 | int ifindex; /* bound device */ |
| 207 | __be16 num; | 190 | __be16 num; |
| 208 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 209 | struct packet_mclist *mclist; | 191 | struct packet_mclist *mclist; |
| 210 | #endif | ||
| 211 | #ifdef CONFIG_PACKET_MMAP | 192 | #ifdef CONFIG_PACKET_MMAP |
| 212 | atomic_t mapped; | 193 | atomic_t mapped; |
| 213 | unsigned int pg_vec_order; | 194 | unsigned int pg_vec_order; |
| @@ -263,7 +244,6 @@ static void packet_sock_destruct(struct sock *sk) | |||
| 263 | 244 | ||
| 264 | static const struct proto_ops packet_ops; | 245 | static const struct proto_ops packet_ops; |
| 265 | 246 | ||
| 266 | #ifdef CONFIG_SOCK_PACKET | ||
| 267 | static const struct proto_ops packet_ops_spkt; | 247 | static const struct proto_ops packet_ops_spkt; |
| 268 | 248 | ||
| 269 | static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | 249 | static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) |
| @@ -435,7 +415,6 @@ out_unlock: | |||
| 435 | dev_put(dev); | 415 | dev_put(dev); |
| 436 | return err; | 416 | return err; |
| 437 | } | 417 | } |
| 438 | #endif | ||
| 439 | 418 | ||
| 440 | static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, | 419 | static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, |
| 441 | unsigned int res) | 420 | unsigned int res) |
| @@ -851,9 +830,7 @@ static int packet_release(struct socket *sock) | |||
| 851 | __sock_put(sk); | 830 | __sock_put(sk); |
| 852 | } | 831 | } |
| 853 | 832 | ||
| 854 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 855 | packet_flush_mclist(sk); | 833 | packet_flush_mclist(sk); |
| 856 | #endif | ||
| 857 | 834 | ||
| 858 | #ifdef CONFIG_PACKET_MMAP | 835 | #ifdef CONFIG_PACKET_MMAP |
| 859 | if (po->pg_vec) { | 836 | if (po->pg_vec) { |
| @@ -936,8 +913,6 @@ out_unlock: | |||
| 936 | * Bind a packet socket to a device | 913 | * Bind a packet socket to a device |
| 937 | */ | 914 | */ |
| 938 | 915 | ||
| 939 | #ifdef CONFIG_SOCK_PACKET | ||
| 940 | |||
| 941 | static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 916 | static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
| 942 | { | 917 | { |
| 943 | struct sock *sk=sock->sk; | 918 | struct sock *sk=sock->sk; |
| @@ -960,7 +935,6 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add | |||
| 960 | } | 935 | } |
| 961 | return err; | 936 | return err; |
| 962 | } | 937 | } |
| 963 | #endif | ||
| 964 | 938 | ||
| 965 | static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 939 | static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
| 966 | { | 940 | { |
| @@ -1012,11 +986,8 @@ static int packet_create(struct socket *sock, int protocol) | |||
| 1012 | 986 | ||
| 1013 | if (!capable(CAP_NET_RAW)) | 987 | if (!capable(CAP_NET_RAW)) |
| 1014 | return -EPERM; | 988 | return -EPERM; |
| 1015 | if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW | 989 | if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW && |
| 1016 | #ifdef CONFIG_SOCK_PACKET | 990 | sock->type != SOCK_PACKET) |
| 1017 | && sock->type != SOCK_PACKET | ||
| 1018 | #endif | ||
| 1019 | ) | ||
| 1020 | return -ESOCKTNOSUPPORT; | 991 | return -ESOCKTNOSUPPORT; |
| 1021 | 992 | ||
| 1022 | sock->state = SS_UNCONNECTED; | 993 | sock->state = SS_UNCONNECTED; |
| @@ -1027,10 +998,9 @@ static int packet_create(struct socket *sock, int protocol) | |||
| 1027 | goto out; | 998 | goto out; |
| 1028 | 999 | ||
| 1029 | sock->ops = &packet_ops; | 1000 | sock->ops = &packet_ops; |
| 1030 | #ifdef CONFIG_SOCK_PACKET | ||
| 1031 | if (sock->type == SOCK_PACKET) | 1001 | if (sock->type == SOCK_PACKET) |
| 1032 | sock->ops = &packet_ops_spkt; | 1002 | sock->ops = &packet_ops_spkt; |
| 1033 | #endif | 1003 | |
| 1034 | sock_init_data(sock, sk); | 1004 | sock_init_data(sock, sk); |
| 1035 | 1005 | ||
| 1036 | po = pkt_sk(sk); | 1006 | po = pkt_sk(sk); |
| @@ -1046,10 +1016,10 @@ static int packet_create(struct socket *sock, int protocol) | |||
| 1046 | 1016 | ||
| 1047 | spin_lock_init(&po->bind_lock); | 1017 | spin_lock_init(&po->bind_lock); |
| 1048 | po->prot_hook.func = packet_rcv; | 1018 | po->prot_hook.func = packet_rcv; |
| 1049 | #ifdef CONFIG_SOCK_PACKET | 1019 | |
| 1050 | if (sock->type == SOCK_PACKET) | 1020 | if (sock->type == SOCK_PACKET) |
| 1051 | po->prot_hook.func = packet_rcv_spkt; | 1021 | po->prot_hook.func = packet_rcv_spkt; |
| 1052 | #endif | 1022 | |
| 1053 | po->prot_hook.af_packet_priv = sk; | 1023 | po->prot_hook.af_packet_priv = sk; |
| 1054 | 1024 | ||
| 1055 | if (proto) { | 1025 | if (proto) { |
| @@ -1169,7 +1139,6 @@ out: | |||
| 1169 | return err; | 1139 | return err; |
| 1170 | } | 1140 | } |
| 1171 | 1141 | ||
| 1172 | #ifdef CONFIG_SOCK_PACKET | ||
| 1173 | static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, | 1142 | static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, |
| 1174 | int *uaddr_len, int peer) | 1143 | int *uaddr_len, int peer) |
| 1175 | { | 1144 | { |
| @@ -1190,7 +1159,6 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, | |||
| 1190 | 1159 | ||
| 1191 | return 0; | 1160 | return 0; |
| 1192 | } | 1161 | } |
| 1193 | #endif | ||
| 1194 | 1162 | ||
| 1195 | static int packet_getname(struct socket *sock, struct sockaddr *uaddr, | 1163 | static int packet_getname(struct socket *sock, struct sockaddr *uaddr, |
| 1196 | int *uaddr_len, int peer) | 1164 | int *uaddr_len, int peer) |
| @@ -1221,7 +1189,6 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 1221 | return 0; | 1189 | return 0; |
| 1222 | } | 1190 | } |
| 1223 | 1191 | ||
| 1224 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 1225 | static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) | 1192 | static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) |
| 1226 | { | 1193 | { |
| 1227 | switch (i->type) { | 1194 | switch (i->type) { |
| @@ -1349,7 +1316,6 @@ static void packet_flush_mclist(struct sock *sk) | |||
| 1349 | } | 1316 | } |
| 1350 | rtnl_unlock(); | 1317 | rtnl_unlock(); |
| 1351 | } | 1318 | } |
| 1352 | #endif | ||
| 1353 | 1319 | ||
| 1354 | static int | 1320 | static int |
| 1355 | packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 1321 | packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) |
| @@ -1362,7 +1328,6 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | |||
| 1362 | return -ENOPROTOOPT; | 1328 | return -ENOPROTOOPT; |
| 1363 | 1329 | ||
| 1364 | switch(optname) { | 1330 | switch(optname) { |
| 1365 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 1366 | case PACKET_ADD_MEMBERSHIP: | 1331 | case PACKET_ADD_MEMBERSHIP: |
| 1367 | case PACKET_DROP_MEMBERSHIP: | 1332 | case PACKET_DROP_MEMBERSHIP: |
| 1368 | { | 1333 | { |
| @@ -1383,7 +1348,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | |||
| 1383 | ret = packet_mc_drop(sk, &mreq); | 1348 | ret = packet_mc_drop(sk, &mreq); |
| 1384 | return ret; | 1349 | return ret; |
| 1385 | } | 1350 | } |
| 1386 | #endif | 1351 | |
| 1387 | #ifdef CONFIG_PACKET_MMAP | 1352 | #ifdef CONFIG_PACKET_MMAP |
| 1388 | case PACKET_RX_RING: | 1353 | case PACKET_RX_RING: |
| 1389 | { | 1354 | { |
| @@ -1506,11 +1471,10 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void | |||
| 1506 | 1471 | ||
| 1507 | switch (msg) { | 1472 | switch (msg) { |
| 1508 | case NETDEV_UNREGISTER: | 1473 | case NETDEV_UNREGISTER: |
| 1509 | #ifdef CONFIG_PACKET_MULTICAST | ||
| 1510 | if (po->mclist) | 1474 | if (po->mclist) |
| 1511 | packet_dev_mclist(dev, po->mclist, -1); | 1475 | packet_dev_mclist(dev, po->mclist, -1); |
| 1512 | // fallthrough | 1476 | /* fallthrough */ |
| 1513 | #endif | 1477 | |
| 1514 | case NETDEV_DOWN: | 1478 | case NETDEV_DOWN: |
| 1515 | if (dev->ifindex == po->ifindex) { | 1479 | if (dev->ifindex == po->ifindex) { |
| 1516 | spin_lock(&po->bind_lock); | 1480 | spin_lock(&po->bind_lock); |
| @@ -1856,7 +1820,6 @@ out: | |||
| 1856 | #endif | 1820 | #endif |
| 1857 | 1821 | ||
| 1858 | 1822 | ||
| 1859 | #ifdef CONFIG_SOCK_PACKET | ||
| 1860 | static const struct proto_ops packet_ops_spkt = { | 1823 | static const struct proto_ops packet_ops_spkt = { |
| 1861 | .family = PF_PACKET, | 1824 | .family = PF_PACKET, |
| 1862 | .owner = THIS_MODULE, | 1825 | .owner = THIS_MODULE, |
| @@ -1877,7 +1840,6 @@ static const struct proto_ops packet_ops_spkt = { | |||
| 1877 | .mmap = sock_no_mmap, | 1840 | .mmap = sock_no_mmap, |
| 1878 | .sendpage = sock_no_sendpage, | 1841 | .sendpage = sock_no_sendpage, |
| 1879 | }; | 1842 | }; |
| 1880 | #endif | ||
| 1881 | 1843 | ||
| 1882 | static const struct proto_ops packet_ops = { | 1844 | static const struct proto_ops packet_ops = { |
| 1883 | .family = PF_PACKET, | 1845 | .family = PF_PACKET, |
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index a973603e3880..f3986d498b40 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
| @@ -296,7 +296,7 @@ struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type) | |||
| 296 | struct device *dev; | 296 | struct device *dev; |
| 297 | 297 | ||
| 298 | rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); | 298 | rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); |
| 299 | if (rfkill) | 299 | if (!rfkill) |
| 300 | return NULL; | 300 | return NULL; |
| 301 | 301 | ||
| 302 | mutex_init(&rfkill->mutex); | 302 | mutex_init(&rfkill->mutex); |
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig index 91b3d52f6f1a..e662f1d07664 100644 --- a/net/rxrpc/Kconfig +++ b/net/rxrpc/Kconfig | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | config AF_RXRPC | 5 | config AF_RXRPC |
| 6 | tristate "RxRPC session sockets" | 6 | tristate "RxRPC session sockets" |
| 7 | depends on EXPERIMENTAL | 7 | depends on INET && EXPERIMENTAL |
| 8 | select KEYS | 8 | select KEYS |
| 9 | help | 9 | help |
| 10 | Say Y or M here to include support for RxRPC session sockets (just | 10 | Say Y or M here to include support for RxRPC session sockets (just |
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c index 4d92d88ff1fc..3c04b00dab74 100644 --- a/net/rxrpc/ar-call.c +++ b/net/rxrpc/ar-call.c | |||
| @@ -15,6 +15,25 @@ | |||
| 15 | #include <net/af_rxrpc.h> | 15 | #include <net/af_rxrpc.h> |
| 16 | #include "ar-internal.h" | 16 | #include "ar-internal.h" |
| 17 | 17 | ||
| 18 | const char *rxrpc_call_states[] = { | ||
| 19 | [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq", | ||
| 20 | [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", | ||
| 21 | [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl", | ||
| 22 | [RXRPC_CALL_CLIENT_FINAL_ACK] = "ClFnlACK", | ||
| 23 | [RXRPC_CALL_SERVER_SECURING] = "SvSecure", | ||
| 24 | [RXRPC_CALL_SERVER_ACCEPTING] = "SvAccept", | ||
| 25 | [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq", | ||
| 26 | [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq", | ||
| 27 | [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl", | ||
| 28 | [RXRPC_CALL_SERVER_AWAIT_ACK] = "SvAwtACK", | ||
| 29 | [RXRPC_CALL_COMPLETE] = "Complete", | ||
| 30 | [RXRPC_CALL_SERVER_BUSY] = "SvBusy ", | ||
| 31 | [RXRPC_CALL_REMOTELY_ABORTED] = "RmtAbort", | ||
| 32 | [RXRPC_CALL_LOCALLY_ABORTED] = "LocAbort", | ||
| 33 | [RXRPC_CALL_NETWORK_ERROR] = "NetError", | ||
| 34 | [RXRPC_CALL_DEAD] = "Dead ", | ||
| 35 | }; | ||
| 36 | |||
| 18 | struct kmem_cache *rxrpc_call_jar; | 37 | struct kmem_cache *rxrpc_call_jar; |
| 19 | LIST_HEAD(rxrpc_calls); | 38 | LIST_HEAD(rxrpc_calls); |
| 20 | DEFINE_RWLOCK(rxrpc_call_lock); | 39 | DEFINE_RWLOCK(rxrpc_call_lock); |
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index ce08b78647ce..90fa107a8af9 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c | |||
| @@ -59,14 +59,14 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) | |||
| 59 | 59 | ||
| 60 | ret = ip_route_output_key(&rt, &fl); | 60 | ret = ip_route_output_key(&rt, &fl); |
| 61 | if (ret < 0) { | 61 | if (ret < 0) { |
| 62 | kleave(" [route err %d]", ret); | 62 | _leave(" [route err %d]", ret); |
| 63 | return; | 63 | return; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | peer->if_mtu = dst_mtu(&rt->u.dst); | 66 | peer->if_mtu = dst_mtu(&rt->u.dst); |
| 67 | dst_release(&rt->u.dst); | 67 | dst_release(&rt->u.dst); |
| 68 | 68 | ||
| 69 | kleave(" [if_mtu %u]", peer->if_mtu); | 69 | _leave(" [if_mtu %u]", peer->if_mtu); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | /* | 72 | /* |
diff --git a/net/rxrpc/ar-proc.c b/net/rxrpc/ar-proc.c index 58f4b4e5cece..1c0be0e77b16 100644 --- a/net/rxrpc/ar-proc.c +++ b/net/rxrpc/ar-proc.c | |||
| @@ -25,25 +25,6 @@ static const char *rxrpc_conn_states[] = { | |||
| 25 | [RXRPC_CONN_NETWORK_ERROR] = "NetError", | 25 | [RXRPC_CONN_NETWORK_ERROR] = "NetError", |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | const char *rxrpc_call_states[] = { | ||
| 29 | [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq", | ||
| 30 | [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", | ||
| 31 | [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl", | ||
| 32 | [RXRPC_CALL_CLIENT_FINAL_ACK] = "ClFnlACK", | ||
| 33 | [RXRPC_CALL_SERVER_SECURING] = "SvSecure", | ||
| 34 | [RXRPC_CALL_SERVER_ACCEPTING] = "SvAccept", | ||
| 35 | [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq", | ||
| 36 | [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq", | ||
| 37 | [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl", | ||
| 38 | [RXRPC_CALL_SERVER_AWAIT_ACK] = "SvAwtACK", | ||
| 39 | [RXRPC_CALL_COMPLETE] = "Complete", | ||
| 40 | [RXRPC_CALL_SERVER_BUSY] = "SvBusy ", | ||
| 41 | [RXRPC_CALL_REMOTELY_ABORTED] = "RmtAbort", | ||
| 42 | [RXRPC_CALL_LOCALLY_ABORTED] = "LocAbort", | ||
| 43 | [RXRPC_CALL_NETWORK_ERROR] = "NetError", | ||
| 44 | [RXRPC_CALL_DEAD] = "Dead ", | ||
| 45 | }; | ||
| 46 | |||
| 47 | /* | 28 | /* |
| 48 | * generate a list of extant and dead calls in /proc/net/rxrpc_calls | 29 | * generate a list of extant and dead calls in /proc/net/rxrpc_calls |
| 49 | */ | 30 | */ |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 45b3cda86a21..6f8684b5617e 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -164,8 +164,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a, | |||
| 164 | printk("offset must be on 32 bit boundaries\n"); | 164 | printk("offset must be on 32 bit boundaries\n"); |
| 165 | goto bad; | 165 | goto bad; |
| 166 | } | 166 | } |
| 167 | if (skb->len < 0 || | 167 | if (offset > 0 && offset > skb->len) { |
| 168 | (offset > 0 && offset > skb->len)) { | ||
| 169 | printk("offset %d cant exceed pkt length %d\n", | 168 | printk("offset %d cant exceed pkt length %d\n", |
| 170 | offset, skb->len); | 169 | offset, skb->len); |
| 171 | goto bad; | 170 | goto bad; |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index be7d299acd73..d1c383fca82c 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
| @@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch) | |||
| 599 | /* races ? */ | 599 | /* races ? */ |
| 600 | while ((flow = p->flows)) { | 600 | while ((flow = p->flows)) { |
| 601 | tcf_destroy_chain(flow->filter_list); | 601 | tcf_destroy_chain(flow->filter_list); |
| 602 | flow->filter_list = NULL; | ||
| 602 | if (flow->ref > 1) | 603 | if (flow->ref > 1) |
| 603 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, | 604 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, |
| 604 | flow->ref); | 605 | flow->ref); |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index a294542cb8e4..ee2d5967d109 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
| @@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch) | |||
| 1748 | * classes from root to leafs which means that filters can still | 1748 | * classes from root to leafs which means that filters can still |
| 1749 | * be bound to classes which have been destroyed already. --TGR '04 | 1749 | * be bound to classes which have been destroyed already. --TGR '04 |
| 1750 | */ | 1750 | */ |
| 1751 | for (h = 0; h < 16; h++) | 1751 | for (h = 0; h < 16; h++) { |
| 1752 | for (cl = q->classes[h]; cl; cl = cl->next) | 1752 | for (cl = q->classes[h]; cl; cl = cl->next) { |
| 1753 | tcf_destroy_chain(cl->filter_list); | 1753 | tcf_destroy_chain(cl->filter_list); |
| 1754 | 1754 | cl->filter_list = NULL; | |
| 1755 | } | ||
| 1756 | } | ||
| 1755 | for (h = 0; h < 16; h++) { | 1757 | for (h = 0; h < 16; h++) { |
| 1756 | struct cbq_class *next; | 1758 | struct cbq_class *next; |
| 1757 | 1759 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 3385ee592541..f4d34480a093 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
| @@ -71,12 +71,9 @@ void qdisc_unlock_tree(struct net_device *dev) | |||
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | /* Kick device. | 73 | /* Kick device. |
| 74 | Note, that this procedure can be called by a watchdog timer, so that | ||
| 75 | we do not check dev->tbusy flag here. | ||
| 76 | 74 | ||
| 77 | Returns: 0 - queue is empty. | 75 | Returns: 0 - queue is empty or throttled. |
| 78 | >0 - queue is not empty, but throttled. | 76 | >0 - queue is not empty. |
| 79 | <0 - queue is not empty. Device is throttled, if dev->tbusy != 0. | ||
| 80 | 77 | ||
| 81 | NOTE: Called under dev->queue_lock with locally disabled BH. | 78 | NOTE: Called under dev->queue_lock with locally disabled BH. |
| 82 | */ | 79 | */ |
| @@ -115,7 +112,7 @@ static inline int qdisc_restart(struct net_device *dev) | |||
| 115 | kfree_skb(skb); | 112 | kfree_skb(skb); |
| 116 | if (net_ratelimit()) | 113 | if (net_ratelimit()) |
| 117 | printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name); | 114 | printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name); |
| 118 | return -1; | 115 | goto out; |
| 119 | } | 116 | } |
| 120 | __get_cpu_var(netdev_rx_stat).cpu_collision++; | 117 | __get_cpu_var(netdev_rx_stat).cpu_collision++; |
| 121 | goto requeue; | 118 | goto requeue; |
| @@ -135,10 +132,12 @@ static inline int qdisc_restart(struct net_device *dev) | |||
| 135 | netif_tx_unlock(dev); | 132 | netif_tx_unlock(dev); |
| 136 | } | 133 | } |
| 137 | spin_lock(&dev->queue_lock); | 134 | spin_lock(&dev->queue_lock); |
| 138 | return -1; | 135 | q = dev->qdisc; |
| 136 | goto out; | ||
| 139 | } | 137 | } |
| 140 | if (ret == NETDEV_TX_LOCKED && nolock) { | 138 | if (ret == NETDEV_TX_LOCKED && nolock) { |
| 141 | spin_lock(&dev->queue_lock); | 139 | spin_lock(&dev->queue_lock); |
| 140 | q = dev->qdisc; | ||
| 142 | goto collision; | 141 | goto collision; |
| 143 | } | 142 | } |
| 144 | } | 143 | } |
| @@ -163,26 +162,28 @@ static inline int qdisc_restart(struct net_device *dev) | |||
| 163 | */ | 162 | */ |
| 164 | 163 | ||
| 165 | requeue: | 164 | requeue: |
| 166 | if (skb->next) | 165 | if (unlikely(q == &noop_qdisc)) |
| 166 | kfree_skb(skb); | ||
| 167 | else if (skb->next) | ||
| 167 | dev->gso_skb = skb; | 168 | dev->gso_skb = skb; |
| 168 | else | 169 | else |
| 169 | q->ops->requeue(skb, q); | 170 | q->ops->requeue(skb, q); |
| 170 | netif_schedule(dev); | 171 | netif_schedule(dev); |
| 171 | return 1; | ||
| 172 | } | 172 | } |
| 173 | return 0; | ||
| 174 | |||
| 175 | out: | ||
| 173 | BUG_ON((int) q->q.qlen < 0); | 176 | BUG_ON((int) q->q.qlen < 0); |
| 174 | return q->q.qlen; | 177 | return q->q.qlen; |
| 175 | } | 178 | } |
| 176 | 179 | ||
| 177 | void __qdisc_run(struct net_device *dev) | 180 | void __qdisc_run(struct net_device *dev) |
| 178 | { | 181 | { |
| 179 | if (unlikely(dev->qdisc == &noop_qdisc)) | 182 | do { |
| 180 | goto out; | 183 | if (!qdisc_restart(dev)) |
| 184 | break; | ||
| 185 | } while (!netif_queue_stopped(dev)); | ||
| 181 | 186 | ||
| 182 | while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) | ||
| 183 | /* NOTHING */; | ||
| 184 | |||
| 185 | out: | ||
| 186 | clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); | 187 | clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); |
| 187 | } | 188 | } |
| 188 | 189 | ||
| @@ -223,7 +224,8 @@ void __netdev_watchdog_up(struct net_device *dev) | |||
| 223 | if (dev->tx_timeout) { | 224 | if (dev->tx_timeout) { |
| 224 | if (dev->watchdog_timeo <= 0) | 225 | if (dev->watchdog_timeo <= 0) |
| 225 | dev->watchdog_timeo = 5*HZ; | 226 | dev->watchdog_timeo = 5*HZ; |
| 226 | if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo)) | 227 | if (!mod_timer(&dev->watchdog_timer, |
| 228 | round_jiffies(jiffies + dev->watchdog_timeo))) | ||
| 227 | dev_hold(dev); | 229 | dev_hold(dev); |
| 228 | } | 230 | } |
| 229 | } | 231 | } |
| @@ -544,6 +546,7 @@ void dev_activate(struct net_device *dev) | |||
| 544 | void dev_deactivate(struct net_device *dev) | 546 | void dev_deactivate(struct net_device *dev) |
| 545 | { | 547 | { |
| 546 | struct Qdisc *qdisc; | 548 | struct Qdisc *qdisc; |
| 549 | struct sk_buff *skb; | ||
| 547 | 550 | ||
| 548 | spin_lock_bh(&dev->queue_lock); | 551 | spin_lock_bh(&dev->queue_lock); |
| 549 | qdisc = dev->qdisc; | 552 | qdisc = dev->qdisc; |
| @@ -551,8 +554,12 @@ void dev_deactivate(struct net_device *dev) | |||
| 551 | 554 | ||
| 552 | qdisc_reset(qdisc); | 555 | qdisc_reset(qdisc); |
| 553 | 556 | ||
| 557 | skb = dev->gso_skb; | ||
| 558 | dev->gso_skb = NULL; | ||
| 554 | spin_unlock_bh(&dev->queue_lock); | 559 | spin_unlock_bh(&dev->queue_lock); |
| 555 | 560 | ||
| 561 | kfree_skb(skb); | ||
| 562 | |||
| 556 | dev_watchdog_down(dev); | 563 | dev_watchdog_down(dev); |
| 557 | 564 | ||
| 558 | /* Wait for outstanding dev_queue_xmit calls. */ | 565 | /* Wait for outstanding dev_queue_xmit calls. */ |
| @@ -561,11 +568,6 @@ void dev_deactivate(struct net_device *dev) | |||
| 561 | /* Wait for outstanding qdisc_run calls. */ | 568 | /* Wait for outstanding qdisc_run calls. */ |
| 562 | while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) | 569 | while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) |
| 563 | yield(); | 570 | yield(); |
| 564 | |||
| 565 | if (dev->gso_skb) { | ||
| 566 | kfree_skb(dev->gso_skb); | ||
| 567 | dev->gso_skb = NULL; | ||
| 568 | } | ||
| 569 | } | 571 | } |
| 570 | 572 | ||
| 571 | void dev_init_scheduler(struct net_device *dev) | 573 | void dev_init_scheduler(struct net_device *dev) |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 99bcec8dd04c..035788c5b7f8 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -976,8 +976,9 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
| 976 | 976 | ||
| 977 | if (q->now >= q->near_ev_cache[level]) { | 977 | if (q->now >= q->near_ev_cache[level]) { |
| 978 | event = htb_do_events(q, level); | 978 | event = htb_do_events(q, level); |
| 979 | q->near_ev_cache[level] = event ? event : | 979 | if (!event) |
| 980 | PSCHED_TICKS_PER_SEC; | 980 | event = q->now + PSCHED_TICKS_PER_SEC; |
| 981 | q->near_ev_cache[level] = event; | ||
| 981 | } else | 982 | } else |
| 982 | event = q->near_ev_cache[level]; | 983 | event = q->near_ev_cache[level]; |
| 983 | 984 | ||
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 269a6e17c6c4..6d7542c26e47 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
| @@ -75,7 +75,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
| 75 | band = res.classid; | 75 | band = res.classid; |
| 76 | } | 76 | } |
| 77 | band = TC_H_MIN(band) - 1; | 77 | band = TC_H_MIN(band) - 1; |
| 78 | if (band > q->bands) | 78 | if (band >= q->bands) |
| 79 | return q->queues[q->prio2band[0]]; | 79 | return q->queues[q->prio2band[0]]; |
| 80 | 80 | ||
| 81 | return q->queues[band]; | 81 | return q->queues[band]; |
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index d24914db7861..f05ad9a30b4c 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
| @@ -94,14 +94,13 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 94 | struct net_device *dev = sch->dev; | 94 | struct net_device *dev = sch->dev; |
| 95 | struct teql_sched_data *q = qdisc_priv(sch); | 95 | struct teql_sched_data *q = qdisc_priv(sch); |
| 96 | 96 | ||
| 97 | __skb_queue_tail(&q->q, skb); | 97 | if (q->q.qlen < dev->tx_queue_len) { |
| 98 | if (q->q.qlen <= dev->tx_queue_len) { | 98 | __skb_queue_tail(&q->q, skb); |
| 99 | sch->bstats.bytes += skb->len; | 99 | sch->bstats.bytes += skb->len; |
| 100 | sch->bstats.packets++; | 100 | sch->bstats.packets++; |
| 101 | return 0; | 101 | return 0; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | __skb_unlink(skb, &q->q); | ||
| 105 | kfree_skb(skb); | 104 | kfree_skb(skb); |
| 106 | sch->qstats.drops++; | 105 | sch->qstats.drops++; |
| 107 | return NET_XMIT_DROP; | 106 | return NET_XMIT_DROP; |
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 9cba49e2ad43..8210f549c492 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig | |||
| @@ -2,11 +2,9 @@ | |||
| 2 | # SCTP configuration | 2 | # SCTP configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menu "SCTP Configuration (EXPERIMENTAL)" | 5 | menuconfig IP_SCTP |
| 6 | depends on INET && EXPERIMENTAL | ||
| 7 | |||
| 8 | config IP_SCTP | ||
| 9 | tristate "The SCTP Protocol (EXPERIMENTAL)" | 6 | tristate "The SCTP Protocol (EXPERIMENTAL)" |
| 7 | depends on INET && EXPERIMENTAL | ||
| 10 | depends on IPV6 || IPV6=n | 8 | depends on IPV6 || IPV6=n |
| 11 | select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 | 9 | select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 |
| 12 | select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 | 10 | select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 |
| @@ -36,9 +34,10 @@ config IP_SCTP | |||
| 36 | 34 | ||
| 37 | If in doubt, say N. | 35 | If in doubt, say N. |
| 38 | 36 | ||
| 37 | if IP_SCTP | ||
| 38 | |||
| 39 | config SCTP_DBG_MSG | 39 | config SCTP_DBG_MSG |
| 40 | bool "SCTP: Debug messages" | 40 | bool "SCTP: Debug messages" |
| 41 | depends on IP_SCTP | ||
| 42 | help | 41 | help |
| 43 | If you say Y, this will enable verbose debugging messages. | 42 | If you say Y, this will enable verbose debugging messages. |
| 44 | 43 | ||
| @@ -47,7 +46,6 @@ config SCTP_DBG_MSG | |||
| 47 | 46 | ||
| 48 | config SCTP_DBG_OBJCNT | 47 | config SCTP_DBG_OBJCNT |
| 49 | bool "SCTP: Debug object counts" | 48 | bool "SCTP: Debug object counts" |
| 50 | depends on IP_SCTP | ||
| 51 | help | 49 | help |
| 52 | If you say Y, this will enable debugging support for counting the | 50 | If you say Y, this will enable debugging support for counting the |
| 53 | type of objects that are currently allocated. This is useful for | 51 | type of objects that are currently allocated. This is useful for |
| @@ -59,7 +57,6 @@ config SCTP_DBG_OBJCNT | |||
| 59 | 57 | ||
| 60 | choice | 58 | choice |
| 61 | prompt "SCTP: Cookie HMAC Algorithm" | 59 | prompt "SCTP: Cookie HMAC Algorithm" |
| 62 | depends on IP_SCTP | ||
| 63 | default SCTP_HMAC_MD5 | 60 | default SCTP_HMAC_MD5 |
| 64 | help | 61 | help |
| 65 | HMAC algorithm to be used during association initialization. It | 62 | HMAC algorithm to be used during association initialization. It |
| @@ -86,4 +83,5 @@ config SCTP_HMAC_MD5 | |||
| 86 | advised to use either HMAC-MD5 or HMAC-SHA1. | 83 | advised to use either HMAC-MD5 or HMAC-SHA1. |
| 87 | 84 | ||
| 88 | endchoice | 85 | endchoice |
| 89 | endmenu | 86 | |
| 87 | endif # IP_SCTP | ||
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 83ef411772f4..77fb7b06a9c4 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * This file is part of the SCTP kernel reference Implementation | 4 | * This file is part of the SCTP kernel reference Implementation |
| 5 | * | 5 | * |
| 6 | * This file contains the code relating the the chunk abstraction. | 6 | * This file contains the code relating the chunk abstraction. |
| 7 | * | 7 | * |
| 8 | * The SCTP reference implementation is free software; | 8 | * The SCTP reference implementation is free software; |
| 9 | * you can redistribute it and/or modify it under the terms of | 9 | * you can redistribute it and/or modify it under the terms of |
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index e8c0f7435d7f..80f70aa53386 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
| @@ -77,8 +77,6 @@ static const char *sctp_cid_tbl[SCTP_NUM_BASE_CHUNK_TYPES] = { | |||
| 77 | /* Lookup "chunk type" debug name. */ | 77 | /* Lookup "chunk type" debug name. */ |
| 78 | const char *sctp_cname(const sctp_subtype_t cid) | 78 | const char *sctp_cname(const sctp_subtype_t cid) |
| 79 | { | 79 | { |
| 80 | if (cid.chunk < 0) | ||
| 81 | return "illegal chunk id"; | ||
| 82 | if (cid.chunk <= SCTP_CID_BASE_MAX) | 80 | if (cid.chunk <= SCTP_CID_BASE_MAX) |
| 83 | return sctp_cid_tbl[cid.chunk]; | 81 | return sctp_cid_tbl[cid.chunk]; |
| 84 | 82 | ||
| @@ -146,8 +144,6 @@ static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = { | |||
| 146 | /* Lookup primitive debug name. */ | 144 | /* Lookup primitive debug name. */ |
| 147 | const char *sctp_pname(const sctp_subtype_t id) | 145 | const char *sctp_pname(const sctp_subtype_t id) |
| 148 | { | 146 | { |
| 149 | if (id.primitive < 0) | ||
| 150 | return "illegal primitive"; | ||
| 151 | if (id.primitive <= SCTP_EVENT_PRIMITIVE_MAX) | 147 | if (id.primitive <= SCTP_EVENT_PRIMITIVE_MAX) |
| 152 | return sctp_primitive_tbl[id.primitive]; | 148 | return sctp_primitive_tbl[id.primitive]; |
| 153 | return "unknown_primitive"; | 149 | return "unknown_primitive"; |
| @@ -161,8 +157,6 @@ static const char *sctp_other_tbl[] = { | |||
| 161 | /* Lookup "other" debug name. */ | 157 | /* Lookup "other" debug name. */ |
| 162 | const char *sctp_oname(const sctp_subtype_t id) | 158 | const char *sctp_oname(const sctp_subtype_t id) |
| 163 | { | 159 | { |
| 164 | if (id.other < 0) | ||
| 165 | return "illegal 'other' event"; | ||
| 166 | if (id.other <= SCTP_EVENT_OTHER_MAX) | 160 | if (id.other <= SCTP_EVENT_OTHER_MAX) |
| 167 | return sctp_other_tbl[id.other]; | 161 | return sctp_other_tbl[id.other]; |
| 168 | return "unknown 'other' event"; | 162 | return "unknown 'other' event"; |
| @@ -184,8 +178,6 @@ static const char *sctp_timer_tbl[] = { | |||
| 184 | /* Lookup timer debug name. */ | 178 | /* Lookup timer debug name. */ |
| 185 | const char *sctp_tname(const sctp_subtype_t id) | 179 | const char *sctp_tname(const sctp_subtype_t id) |
| 186 | { | 180 | { |
| 187 | if (id.timeout < 0) | ||
| 188 | return "illegal 'timer' event"; | ||
| 189 | if (id.timeout <= SCTP_EVENT_TIMEOUT_MAX) | 181 | if (id.timeout <= SCTP_EVENT_TIMEOUT_MAX) |
| 190 | return sctp_timer_tbl[id.timeout]; | 182 | return sctp_timer_tbl[id.timeout]; |
| 191 | return "unknown_timer"; | 183 | return "unknown_timer"; |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 523071c7902f..70a91ece3c49 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
| @@ -960,7 +960,7 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, | |||
| 960 | if (state > SCTP_STATE_MAX) | 960 | if (state > SCTP_STATE_MAX) |
| 961 | return &bug; | 961 | return &bug; |
| 962 | 962 | ||
| 963 | if (cid >= 0 && cid <= SCTP_CID_BASE_MAX) | 963 | if (cid <= SCTP_CID_BASE_MAX) |
| 964 | return &chunk_event_table[cid][state]; | 964 | return &chunk_event_table[cid][state]; |
| 965 | 965 | ||
| 966 | if (sctp_prsctp_enable) { | 966 | if (sctp_prsctp_enable) { |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9f1a908776de..4dcdabf56473 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2586,7 +2586,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt | |||
| 2586 | * | 2586 | * |
| 2587 | * 7.1.2 SCTP_ASSOCINFO | 2587 | * 7.1.2 SCTP_ASSOCINFO |
| 2588 | * | 2588 | * |
| 2589 | * This option is used to tune the the maximum retransmission attempts | 2589 | * This option is used to tune the maximum retransmission attempts |
| 2590 | * of the association. | 2590 | * of the association. |
| 2591 | * Returns an error if the new association retransmission value is | 2591 | * Returns an error if the new association retransmission value is |
| 2592 | * greater than the sum of the retransmission value of the peer. | 2592 | * greater than the sum of the retransmission value of the peer. |
| @@ -4164,6 +4164,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
| 4164 | rwlock_t *addr_lock; | 4164 | rwlock_t *addr_lock; |
| 4165 | int err = 0; | 4165 | int err = 0; |
| 4166 | void *addrs; | 4166 | void *addrs; |
| 4167 | void *buf; | ||
| 4167 | int bytes_copied = 0; | 4168 | int bytes_copied = 0; |
| 4168 | 4169 | ||
| 4169 | if (len != sizeof(struct sctp_getaddrs_old)) | 4170 | if (len != sizeof(struct sctp_getaddrs_old)) |
| @@ -4217,13 +4218,14 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
| 4217 | } | 4218 | } |
| 4218 | } | 4219 | } |
| 4219 | 4220 | ||
| 4221 | buf = addrs; | ||
| 4220 | list_for_each(pos, &bp->address_list) { | 4222 | list_for_each(pos, &bp->address_list) { |
| 4221 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 4223 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); |
| 4222 | memcpy(&temp, &addr->a, sizeof(temp)); | 4224 | memcpy(&temp, &addr->a, sizeof(temp)); |
| 4223 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4225 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
| 4224 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4226 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
| 4225 | memcpy(addrs, &temp, addrlen); | 4227 | memcpy(buf, &temp, addrlen); |
| 4226 | to += addrlen; | 4228 | buf += addrlen; |
| 4227 | bytes_copied += addrlen; | 4229 | bytes_copied += addrlen; |
| 4228 | cnt ++; | 4230 | cnt ++; |
| 4229 | if (cnt >= getaddrs.addr_num) break; | 4231 | if (cnt >= getaddrs.addr_num) break; |
| @@ -4266,6 +4268,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
| 4266 | size_t space_left; | 4268 | size_t space_left; |
| 4267 | int bytes_copied = 0; | 4269 | int bytes_copied = 0; |
| 4268 | void *addrs; | 4270 | void *addrs; |
| 4271 | void *buf; | ||
| 4269 | 4272 | ||
| 4270 | if (len <= sizeof(struct sctp_getaddrs)) | 4273 | if (len <= sizeof(struct sctp_getaddrs)) |
| 4271 | return -EINVAL; | 4274 | return -EINVAL; |
| @@ -4316,6 +4319,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
| 4316 | } | 4319 | } |
| 4317 | } | 4320 | } |
| 4318 | 4321 | ||
| 4322 | buf = addrs; | ||
| 4319 | list_for_each(pos, &bp->address_list) { | 4323 | list_for_each(pos, &bp->address_list) { |
| 4320 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 4324 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); |
| 4321 | memcpy(&temp, &addr->a, sizeof(temp)); | 4325 | memcpy(&temp, &addr->a, sizeof(temp)); |
| @@ -4325,8 +4329,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
| 4325 | err = -ENOMEM; /*fixme: right error?*/ | 4329 | err = -ENOMEM; /*fixme: right error?*/ |
| 4326 | goto error; | 4330 | goto error; |
| 4327 | } | 4331 | } |
| 4328 | memcpy(addrs, &temp, addrlen); | 4332 | memcpy(buf, &temp, addrlen); |
| 4329 | to += addrlen; | 4333 | buf += addrlen; |
| 4330 | bytes_copied += addrlen; | 4334 | bytes_copied += addrlen; |
| 4331 | cnt ++; | 4335 | cnt ++; |
| 4332 | space_left -= addrlen; | 4336 | space_left -= addrlen; |
| @@ -4547,7 +4551,7 @@ static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, | |||
| 4547 | * | 4551 | * |
| 4548 | * 7.1.2 SCTP_ASSOCINFO | 4552 | * 7.1.2 SCTP_ASSOCINFO |
| 4549 | * | 4553 | * |
| 4550 | * This option is used to tune the the maximum retransmission attempts | 4554 | * This option is used to tune the maximum retransmission attempts |
| 4551 | * of the association. | 4555 | * of the association. |
| 4552 | * Returns an error if the new association retransmission value is | 4556 | * Returns an error if the new association retransmission value is |
| 4553 | * greater than the sum of the retransmission value of the peer. | 4557 | * greater than the sum of the retransmission value of the peer. |
| @@ -5227,7 +5231,12 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
| 5227 | /* Allocate HMAC for generating cookie. */ | 5231 | /* Allocate HMAC for generating cookie. */ |
| 5228 | if (sctp_hmac_alg) { | 5232 | if (sctp_hmac_alg) { |
| 5229 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5233 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
| 5230 | if (!tfm) { | 5234 | if (IS_ERR(tfm)) { |
| 5235 | if (net_ratelimit()) { | ||
| 5236 | printk(KERN_INFO | ||
| 5237 | "SCTP: failed to load transform for %s: %ld\n", | ||
| 5238 | sctp_hmac_alg, PTR_ERR(tfm)); | ||
| 5239 | } | ||
| 5231 | err = -ENOSYS; | 5240 | err = -ENOSYS; |
| 5232 | goto out; | 5241 | goto out; |
| 5233 | } | 5242 | } |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 661ea2dd78ba..bfecb353ab3d 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -141,11 +141,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | |||
| 141 | * an ABORT, so we need to include it in the sac_info. | 141 | * an ABORT, so we need to include it in the sac_info. |
| 142 | */ | 142 | */ |
| 143 | if (chunk) { | 143 | if (chunk) { |
| 144 | /* sctp_inqu_pop() has allready pulled off the chunk | ||
| 145 | * header. We need to put it back temporarily | ||
| 146 | */ | ||
| 147 | skb_push(chunk->skb, sizeof(sctp_chunkhdr_t)); | ||
| 148 | |||
| 149 | /* Copy the chunk data to a new skb and reserve enough | 144 | /* Copy the chunk data to a new skb and reserve enough |
| 150 | * head room to use as notification. | 145 | * head room to use as notification. |
| 151 | */ | 146 | */ |
| @@ -155,9 +150,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | |||
| 155 | if (!skb) | 150 | if (!skb) |
| 156 | goto fail; | 151 | goto fail; |
| 157 | 152 | ||
| 158 | /* put back the chunk header now that we have a copy */ | ||
| 159 | skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); | ||
| 160 | |||
| 161 | /* Embed the event fields inside the cloned skb. */ | 153 | /* Embed the event fields inside the cloned skb. */ |
| 162 | event = sctp_skb2event(skb); | 154 | event = sctp_skb2event(skb); |
| 163 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); | 155 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); |
| @@ -168,7 +160,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | |||
| 168 | 160 | ||
| 169 | /* Trim the buffer to the right length. */ | 161 | /* Trim the buffer to the right length. */ |
| 170 | skb_trim(skb, sizeof(struct sctp_assoc_change) + | 162 | skb_trim(skb, sizeof(struct sctp_assoc_change) + |
| 171 | ntohs(chunk->chunk_hdr->length)); | 163 | ntohs(chunk->chunk_hdr->length) - |
| 164 | sizeof(sctp_chunkhdr_t)); | ||
| 172 | } else { | 165 | } else { |
| 173 | event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change), | 166 | event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change), |
| 174 | MSG_NOTIFICATION, gfp); | 167 | MSG_NOTIFICATION, gfp); |
diff --git a/net/socket.c b/net/socket.c index 759825b7ca26..f4530196a70a 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -261,8 +261,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | |||
| 261 | { | 261 | { |
| 262 | struct socket_alloc *ei = (struct socket_alloc *)foo; | 262 | struct socket_alloc *ei = (struct socket_alloc *)foo; |
| 263 | 263 | ||
| 264 | if (flags & SLAB_CTOR_CONSTRUCTOR) | 264 | inode_init_once(&ei->vfs_inode); |
| 265 | inode_init_once(&ei->vfs_inode); | ||
| 266 | } | 265 | } |
| 267 | 266 | ||
| 268 | static int init_inodecache(void) | 267 | static int init_inodecache(void) |
| @@ -313,8 +312,19 @@ static int sockfs_delete_dentry(struct dentry *dentry) | |||
| 313 | dentry->d_flags |= DCACHE_UNHASHED; | 312 | dentry->d_flags |= DCACHE_UNHASHED; |
| 314 | return 0; | 313 | return 0; |
| 315 | } | 314 | } |
| 315 | |||
| 316 | /* | ||
| 317 | * sockfs_dname() is called from d_path(). | ||
| 318 | */ | ||
| 319 | static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) | ||
| 320 | { | ||
| 321 | return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]", | ||
| 322 | dentry->d_inode->i_ino); | ||
| 323 | } | ||
| 324 | |||
| 316 | static struct dentry_operations sockfs_dentry_operations = { | 325 | static struct dentry_operations sockfs_dentry_operations = { |
| 317 | .d_delete = sockfs_delete_dentry, | 326 | .d_delete = sockfs_delete_dentry, |
| 327 | .d_dname = sockfs_dname, | ||
| 318 | }; | 328 | }; |
| 319 | 329 | ||
| 320 | /* | 330 | /* |
| @@ -354,14 +364,9 @@ static int sock_alloc_fd(struct file **filep) | |||
| 354 | 364 | ||
| 355 | static int sock_attach_fd(struct socket *sock, struct file *file) | 365 | static int sock_attach_fd(struct socket *sock, struct file *file) |
| 356 | { | 366 | { |
| 357 | struct qstr this; | 367 | struct qstr name = { .name = "" }; |
| 358 | char name[32]; | ||
| 359 | |||
| 360 | this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); | ||
| 361 | this.name = name; | ||
| 362 | this.hash = 0; | ||
| 363 | 368 | ||
| 364 | file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); | 369 | file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); |
| 365 | if (unlikely(!file->f_path.dentry)) | 370 | if (unlikely(!file->f_path.dentry)) |
| 366 | return -ENOMEM; | 371 | return -ENOMEM; |
| 367 | 372 | ||
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index db298b501c81..099a983797da 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -924,6 +924,7 @@ static inline int | |||
| 924 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | 924 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) |
| 925 | { | 925 | { |
| 926 | struct rsc *rsci; | 926 | struct rsc *rsci; |
| 927 | int rc; | ||
| 927 | 928 | ||
| 928 | if (rsip->major_status != GSS_S_COMPLETE) | 929 | if (rsip->major_status != GSS_S_COMPLETE) |
| 929 | return gss_write_null_verf(rqstp); | 930 | return gss_write_null_verf(rqstp); |
| @@ -932,7 +933,9 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | |||
| 932 | rsip->major_status = GSS_S_NO_CONTEXT; | 933 | rsip->major_status = GSS_S_NO_CONTEXT; |
| 933 | return gss_write_null_verf(rqstp); | 934 | return gss_write_null_verf(rqstp); |
| 934 | } | 935 | } |
| 935 | return gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); | 936 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); |
| 937 | cache_put(&rsci->h, &rsc_cache); | ||
| 938 | return rc; | ||
| 936 | } | 939 | } |
| 937 | 940 | ||
| 938 | /* | 941 | /* |
| @@ -1089,6 +1092,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1089 | } | 1092 | } |
| 1090 | goto complete; | 1093 | goto complete; |
| 1091 | case RPC_GSS_PROC_DESTROY: | 1094 | case RPC_GSS_PROC_DESTROY: |
| 1095 | if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) | ||
| 1096 | goto auth_err; | ||
| 1092 | set_bit(CACHE_NEGATIVE, &rsci->h.flags); | 1097 | set_bit(CACHE_NEGATIVE, &rsci->h.flags); |
| 1093 | if (resv->iov_len + 4 > PAGE_SIZE) | 1098 | if (resv->iov_len + 4 > PAGE_SIZE) |
| 1094 | goto drop; | 1099 | goto drop; |
| @@ -1196,13 +1201,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp) | |||
| 1196 | if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, | 1201 | if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, |
| 1197 | integ_len)) | 1202 | integ_len)) |
| 1198 | BUG(); | 1203 | BUG(); |
| 1199 | if (resbuf->page_len == 0 | 1204 | if (resbuf->tail[0].iov_base == NULL) { |
| 1200 | && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE | ||
| 1201 | < PAGE_SIZE) { | ||
| 1202 | BUG_ON(resbuf->tail[0].iov_len); | ||
| 1203 | /* Use head for everything */ | ||
| 1204 | resv = &resbuf->head[0]; | ||
| 1205 | } else if (resbuf->tail[0].iov_base == NULL) { | ||
| 1206 | if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) | 1205 | if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) |
| 1207 | goto out_err; | 1206 | goto out_err; |
| 1208 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base | 1207 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index ad39b47e05bc..5887457dc936 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -828,23 +828,23 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) | |||
| 828 | { | 828 | { |
| 829 | struct rpc_inode *rpci = (struct rpc_inode *) foo; | 829 | struct rpc_inode *rpci = (struct rpc_inode *) foo; |
| 830 | 830 | ||
| 831 | if (flags & SLAB_CTOR_CONSTRUCTOR) { | 831 | inode_init_once(&rpci->vfs_inode); |
| 832 | inode_init_once(&rpci->vfs_inode); | 832 | rpci->private = NULL; |
| 833 | rpci->private = NULL; | 833 | rpci->nreaders = 0; |
| 834 | rpci->nreaders = 0; | 834 | rpci->nwriters = 0; |
| 835 | rpci->nwriters = 0; | 835 | INIT_LIST_HEAD(&rpci->in_upcall); |
| 836 | INIT_LIST_HEAD(&rpci->in_upcall); | 836 | INIT_LIST_HEAD(&rpci->pipe); |
| 837 | INIT_LIST_HEAD(&rpci->pipe); | 837 | rpci->pipelen = 0; |
| 838 | rpci->pipelen = 0; | 838 | init_waitqueue_head(&rpci->waitq); |
| 839 | init_waitqueue_head(&rpci->waitq); | 839 | INIT_DELAYED_WORK(&rpci->queue_timeout, |
| 840 | INIT_DELAYED_WORK(&rpci->queue_timeout, | 840 | rpc_timeout_upcall_queue); |
| 841 | rpc_timeout_upcall_queue); | 841 | rpci->ops = NULL; |
| 842 | rpci->ops = NULL; | ||
| 843 | } | ||
| 844 | } | 842 | } |
| 845 | 843 | ||
| 846 | int register_rpc_pipefs(void) | 844 | int register_rpc_pipefs(void) |
| 847 | { | 845 | { |
| 846 | int err; | ||
| 847 | |||
| 848 | rpc_inode_cachep = kmem_cache_create("rpc_inode_cache", | 848 | rpc_inode_cachep = kmem_cache_create("rpc_inode_cache", |
| 849 | sizeof(struct rpc_inode), | 849 | sizeof(struct rpc_inode), |
| 850 | 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| | 850 | 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| |
| @@ -852,7 +852,12 @@ int register_rpc_pipefs(void) | |||
| 852 | init_once, NULL); | 852 | init_once, NULL); |
| 853 | if (!rpc_inode_cachep) | 853 | if (!rpc_inode_cachep) |
| 854 | return -ENOMEM; | 854 | return -ENOMEM; |
| 855 | register_filesystem(&rpc_pipe_fs_type); | 855 | err = register_filesystem(&rpc_pipe_fs_type); |
| 856 | if (err) { | ||
| 857 | kmem_cache_destroy(rpc_inode_cachep); | ||
| 858 | return err; | ||
| 859 | } | ||
| 860 | |||
| 856 | return 0; | 861 | return 0; |
| 857 | } | 862 | } |
| 858 | 863 | ||
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 4a53e94f8134..944d75396fb3 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -736,6 +736,11 @@ static void rpc_async_schedule(struct work_struct *work) | |||
| 736 | __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); | 736 | __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | struct rpc_buffer { | ||
| 740 | size_t len; | ||
| 741 | char data[]; | ||
| 742 | }; | ||
| 743 | |||
| 739 | /** | 744 | /** |
| 740 | * rpc_malloc - allocate an RPC buffer | 745 | * rpc_malloc - allocate an RPC buffer |
| 741 | * @task: RPC task that will use this buffer | 746 | * @task: RPC task that will use this buffer |
| @@ -754,18 +759,22 @@ static void rpc_async_schedule(struct work_struct *work) | |||
| 754 | */ | 759 | */ |
| 755 | void *rpc_malloc(struct rpc_task *task, size_t size) | 760 | void *rpc_malloc(struct rpc_task *task, size_t size) |
| 756 | { | 761 | { |
| 757 | size_t *buf; | 762 | struct rpc_buffer *buf; |
| 758 | gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT; | 763 | gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT; |
| 759 | 764 | ||
| 760 | size += sizeof(size_t); | 765 | size += sizeof(struct rpc_buffer); |
| 761 | if (size <= RPC_BUFFER_MAXSIZE) | 766 | if (size <= RPC_BUFFER_MAXSIZE) |
| 762 | buf = mempool_alloc(rpc_buffer_mempool, gfp); | 767 | buf = mempool_alloc(rpc_buffer_mempool, gfp); |
| 763 | else | 768 | else |
| 764 | buf = kmalloc(size, gfp); | 769 | buf = kmalloc(size, gfp); |
| 765 | *buf = size; | 770 | |
| 766 | dprintk("RPC: %5u allocated buffer of size %u at %p\n", | 771 | if (!buf) |
| 772 | return NULL; | ||
| 773 | |||
| 774 | buf->len = size; | ||
| 775 | dprintk("RPC: %5u allocated buffer of size %zu at %p\n", | ||
| 767 | task->tk_pid, size, buf); | 776 | task->tk_pid, size, buf); |
| 768 | return (void *) ++buf; | 777 | return &buf->data; |
| 769 | } | 778 | } |
| 770 | 779 | ||
| 771 | /** | 780 | /** |
| @@ -775,15 +784,18 @@ void *rpc_malloc(struct rpc_task *task, size_t size) | |||
| 775 | */ | 784 | */ |
| 776 | void rpc_free(void *buffer) | 785 | void rpc_free(void *buffer) |
| 777 | { | 786 | { |
| 778 | size_t size, *buf = (size_t *) buffer; | 787 | size_t size; |
| 788 | struct rpc_buffer *buf; | ||
| 779 | 789 | ||
| 780 | if (!buffer) | 790 | if (!buffer) |
| 781 | return; | 791 | return; |
| 782 | size = *buf; | ||
| 783 | buf--; | ||
| 784 | 792 | ||
| 785 | dprintk("RPC: freeing buffer of size %u at %p\n", | 793 | buf = container_of(buffer, struct rpc_buffer, data); |
| 794 | size = buf->len; | ||
| 795 | |||
| 796 | dprintk("RPC: freeing buffer of size %zu at %p\n", | ||
| 786 | size, buf); | 797 | size, buf); |
| 798 | |||
| 787 | if (size <= RPC_BUFFER_MAXSIZE) | 799 | if (size <= RPC_BUFFER_MAXSIZE) |
| 788 | mempool_free(buf, rpc_buffer_mempool); | 800 | mempool_free(buf, rpc_buffer_mempool); |
| 789 | else | 801 | else |
| @@ -977,8 +989,6 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) | |||
| 977 | spin_unlock(&rpc_sched_lock); | 989 | spin_unlock(&rpc_sched_lock); |
| 978 | } | 990 | } |
| 979 | 991 | ||
| 980 | static DECLARE_MUTEX_LOCKED(rpciod_running); | ||
| 981 | |||
| 982 | static void rpciod_killall(void) | 992 | static void rpciod_killall(void) |
| 983 | { | 993 | { |
| 984 | unsigned long flags; | 994 | unsigned long flags; |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 43ecf62f12ef..73075dec83c0 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
| @@ -134,11 +134,7 @@ EXPORT_SYMBOL(nfsd_debug); | |||
| 134 | EXPORT_SYMBOL(nlm_debug); | 134 | EXPORT_SYMBOL(nlm_debug); |
| 135 | #endif | 135 | #endif |
| 136 | 136 | ||
| 137 | extern int register_rpc_pipefs(void); | ||
| 138 | extern void unregister_rpc_pipefs(void); | ||
| 139 | extern struct cache_detail ip_map_cache, unix_gid_cache; | 137 | extern struct cache_detail ip_map_cache, unix_gid_cache; |
| 140 | extern int init_socket_xprt(void); | ||
| 141 | extern void cleanup_socket_xprt(void); | ||
| 142 | 138 | ||
| 143 | static int __init | 139 | static int __init |
| 144 | init_sunrpc(void) | 140 | init_sunrpc(void) |
| @@ -146,9 +142,11 @@ init_sunrpc(void) | |||
| 146 | int err = register_rpc_pipefs(); | 142 | int err = register_rpc_pipefs(); |
| 147 | if (err) | 143 | if (err) |
| 148 | goto out; | 144 | goto out; |
| 149 | err = rpc_init_mempool() != 0; | 145 | err = rpc_init_mempool(); |
| 150 | if (err) | 146 | if (err) { |
| 147 | unregister_rpc_pipefs(); | ||
| 151 | goto out; | 148 | goto out; |
| 149 | } | ||
| 152 | #ifdef RPC_DEBUG | 150 | #ifdef RPC_DEBUG |
| 153 | rpc_register_sysctl(); | 151 | rpc_register_sysctl(); |
| 154 | #endif | 152 | #endif |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index b7503c103ae8..e673ef993904 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -907,7 +907,7 @@ svc_process(struct svc_rqst *rqstp) | |||
| 907 | * better idea of reply size | 907 | * better idea of reply size |
| 908 | */ | 908 | */ |
| 909 | if (procp->pc_xdrressize) | 909 | if (procp->pc_xdrressize) |
| 910 | svc_reserve(rqstp, procp->pc_xdrressize<<2); | 910 | svc_reserve_auth(rqstp, procp->pc_xdrressize<<2); |
| 911 | 911 | ||
| 912 | /* Call the function that processes the request. */ | 912 | /* Call the function that processes the request. */ |
| 913 | if (!versp->vs_dispatch) { | 913 | if (!versp->vs_dispatch) { |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index f5c3808bf85a..af7c5f05c6e1 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
| @@ -64,7 +64,7 @@ int svc_set_client(struct svc_rqst *rqstp) | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | /* A request, which was authenticated, has now executed. | 66 | /* A request, which was authenticated, has now executed. |
| 67 | * Time to finalise the the credentials and verifier | 67 | * Time to finalise the credentials and verifier |
| 68 | * and release and resources | 68 | * and release and resources |
| 69 | */ | 69 | */ |
| 70 | int svc_authorise(struct svc_rqst *rqstp) | 70 | int svc_authorise(struct svc_rqst *rqstp) |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 2bd23ea2aa8b..07dcd20cbee4 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
| @@ -385,7 +385,7 @@ ip_map_cached_get(struct svc_rqst *rqstp) | |||
| 385 | { | 385 | { |
| 386 | struct ip_map *ipm; | 386 | struct ip_map *ipm; |
| 387 | struct svc_sock *svsk = rqstp->rq_sock; | 387 | struct svc_sock *svsk = rqstp->rq_sock; |
| 388 | spin_lock_bh(&svsk->sk_defer_lock); | 388 | spin_lock(&svsk->sk_lock); |
| 389 | ipm = svsk->sk_info_authunix; | 389 | ipm = svsk->sk_info_authunix; |
| 390 | if (ipm != NULL) { | 390 | if (ipm != NULL) { |
| 391 | if (!cache_valid(&ipm->h)) { | 391 | if (!cache_valid(&ipm->h)) { |
| @@ -395,13 +395,13 @@ ip_map_cached_get(struct svc_rqst *rqstp) | |||
| 395 | * same IP address. | 395 | * same IP address. |
| 396 | */ | 396 | */ |
| 397 | svsk->sk_info_authunix = NULL; | 397 | svsk->sk_info_authunix = NULL; |
| 398 | spin_unlock_bh(&svsk->sk_defer_lock); | 398 | spin_unlock(&svsk->sk_lock); |
| 399 | cache_put(&ipm->h, &ip_map_cache); | 399 | cache_put(&ipm->h, &ip_map_cache); |
| 400 | return NULL; | 400 | return NULL; |
| 401 | } | 401 | } |
| 402 | cache_get(&ipm->h); | 402 | cache_get(&ipm->h); |
| 403 | } | 403 | } |
| 404 | spin_unlock_bh(&svsk->sk_defer_lock); | 404 | spin_unlock(&svsk->sk_lock); |
| 405 | return ipm; | 405 | return ipm; |
| 406 | } | 406 | } |
| 407 | 407 | ||
| @@ -410,14 +410,14 @@ ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm) | |||
| 410 | { | 410 | { |
| 411 | struct svc_sock *svsk = rqstp->rq_sock; | 411 | struct svc_sock *svsk = rqstp->rq_sock; |
| 412 | 412 | ||
| 413 | spin_lock_bh(&svsk->sk_defer_lock); | 413 | spin_lock(&svsk->sk_lock); |
| 414 | if (svsk->sk_sock->type == SOCK_STREAM && | 414 | if (svsk->sk_sock->type == SOCK_STREAM && |
| 415 | svsk->sk_info_authunix == NULL) { | 415 | svsk->sk_info_authunix == NULL) { |
| 416 | /* newly cached, keep the reference */ | 416 | /* newly cached, keep the reference */ |
| 417 | svsk->sk_info_authunix = ipm; | 417 | svsk->sk_info_authunix = ipm; |
| 418 | ipm = NULL; | 418 | ipm = NULL; |
| 419 | } | 419 | } |
| 420 | spin_unlock_bh(&svsk->sk_defer_lock); | 420 | spin_unlock(&svsk->sk_lock); |
| 421 | if (ipm) | 421 | if (ipm) |
| 422 | cache_put(&ipm->h, &ip_map_cache); | 422 | cache_put(&ipm->h, &ip_map_cache); |
| 423 | } | 423 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 22f61aee4824..5baf48de2558 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -53,7 +53,8 @@ | |||
| 53 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | 53 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. |
| 54 | * when both need to be taken (rare), svc_serv->sv_lock is first. | 54 | * when both need to be taken (rare), svc_serv->sv_lock is first. |
| 55 | * BKL protects svc_serv->sv_nrthread. | 55 | * BKL protects svc_serv->sv_nrthread. |
| 56 | * svc_sock->sk_defer_lock protects the svc_sock->sk_deferred list | 56 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list |
| 57 | * and the ->sk_info_authunix cache. | ||
| 57 | * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply. | 58 | * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply. |
| 58 | * | 59 | * |
| 59 | * Some flags can be set to certain values at any time | 60 | * Some flags can be set to certain values at any time |
| @@ -787,15 +788,20 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
| 787 | } | 788 | } |
| 788 | 789 | ||
| 789 | clear_bit(SK_DATA, &svsk->sk_flags); | 790 | clear_bit(SK_DATA, &svsk->sk_flags); |
| 790 | while ((err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, | 791 | skb = NULL; |
| 791 | 0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 || | 792 | err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, |
| 792 | (skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { | 793 | 0, 0, MSG_PEEK | MSG_DONTWAIT); |
| 793 | if (err == -EAGAIN) { | 794 | if (err >= 0) |
| 794 | svc_sock_received(svsk); | 795 | skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err); |
| 795 | return err; | 796 | |
| 797 | if (skb == NULL) { | ||
| 798 | if (err != -EAGAIN) { | ||
| 799 | /* possibly an icmp error */ | ||
| 800 | dprintk("svc: recvfrom returned error %d\n", -err); | ||
| 801 | set_bit(SK_DATA, &svsk->sk_flags); | ||
| 796 | } | 802 | } |
| 797 | /* possibly an icmp error */ | 803 | svc_sock_received(svsk); |
| 798 | dprintk("svc: recvfrom returned error %d\n", -err); | 804 | return -EAGAIN; |
| 799 | } | 805 | } |
| 800 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); | 806 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); |
| 801 | if (skb->tstamp.tv64 == 0) { | 807 | if (skb->tstamp.tv64 == 0) { |
| @@ -1633,7 +1639,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
| 1633 | svsk->sk_server = serv; | 1639 | svsk->sk_server = serv; |
| 1634 | atomic_set(&svsk->sk_inuse, 1); | 1640 | atomic_set(&svsk->sk_inuse, 1); |
| 1635 | svsk->sk_lastrecv = get_seconds(); | 1641 | svsk->sk_lastrecv = get_seconds(); |
| 1636 | spin_lock_init(&svsk->sk_defer_lock); | 1642 | spin_lock_init(&svsk->sk_lock); |
| 1637 | INIT_LIST_HEAD(&svsk->sk_deferred); | 1643 | INIT_LIST_HEAD(&svsk->sk_deferred); |
| 1638 | INIT_LIST_HEAD(&svsk->sk_ready); | 1644 | INIT_LIST_HEAD(&svsk->sk_ready); |
| 1639 | mutex_init(&svsk->sk_mutex); | 1645 | mutex_init(&svsk->sk_mutex); |
| @@ -1857,9 +1863,9 @@ static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | |||
| 1857 | dprintk("revisit queued\n"); | 1863 | dprintk("revisit queued\n"); |
| 1858 | svsk = dr->svsk; | 1864 | svsk = dr->svsk; |
| 1859 | dr->svsk = NULL; | 1865 | dr->svsk = NULL; |
| 1860 | spin_lock_bh(&svsk->sk_defer_lock); | 1866 | spin_lock(&svsk->sk_lock); |
| 1861 | list_add(&dr->handle.recent, &svsk->sk_deferred); | 1867 | list_add(&dr->handle.recent, &svsk->sk_deferred); |
| 1862 | spin_unlock_bh(&svsk->sk_defer_lock); | 1868 | spin_unlock(&svsk->sk_lock); |
| 1863 | set_bit(SK_DEFERRED, &svsk->sk_flags); | 1869 | set_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1864 | svc_sock_enqueue(svsk); | 1870 | svc_sock_enqueue(svsk); |
| 1865 | svc_sock_put(svsk); | 1871 | svc_sock_put(svsk); |
| @@ -1925,7 +1931,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | |||
| 1925 | 1931 | ||
| 1926 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) | 1932 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) |
| 1927 | return NULL; | 1933 | return NULL; |
| 1928 | spin_lock_bh(&svsk->sk_defer_lock); | 1934 | spin_lock(&svsk->sk_lock); |
| 1929 | clear_bit(SK_DEFERRED, &svsk->sk_flags); | 1935 | clear_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1930 | if (!list_empty(&svsk->sk_deferred)) { | 1936 | if (!list_empty(&svsk->sk_deferred)) { |
| 1931 | dr = list_entry(svsk->sk_deferred.next, | 1937 | dr = list_entry(svsk->sk_deferred.next, |
| @@ -1934,6 +1940,6 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | |||
| 1934 | list_del_init(&dr->handle.recent); | 1940 | list_del_init(&dr->handle.recent); |
| 1935 | set_bit(SK_DEFERRED, &svsk->sk_flags); | 1941 | set_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1936 | } | 1942 | } |
| 1937 | spin_unlock_bh(&svsk->sk_defer_lock); | 1943 | spin_unlock(&svsk->sk_lock); |
| 1938 | return dr; | 1944 | return dr; |
| 1939 | } | 1945 | } |
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index f9e367d946eb..3b30d1130b61 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig | |||
| @@ -2,11 +2,9 @@ | |||
| 2 | # TIPC configuration | 2 | # TIPC configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menu "TIPC Configuration (EXPERIMENTAL)" | 5 | menuconfig TIPC |
| 6 | depends on INET && EXPERIMENTAL | ||
| 7 | |||
| 8 | config TIPC | ||
| 9 | tristate "The TIPC Protocol (EXPERIMENTAL)" | 6 | tristate "The TIPC Protocol (EXPERIMENTAL)" |
| 7 | depends on INET && EXPERIMENTAL | ||
| 10 | ---help--- | 8 | ---help--- |
| 11 | The Transparent Inter Process Communication (TIPC) protocol is | 9 | The Transparent Inter Process Communication (TIPC) protocol is |
| 12 | specially designed for intra cluster communication. This protocol | 10 | specially designed for intra cluster communication. This protocol |
| @@ -22,9 +20,10 @@ config TIPC | |||
| 22 | 20 | ||
| 23 | If in doubt, say N. | 21 | If in doubt, say N. |
| 24 | 22 | ||
| 23 | if TIPC | ||
| 24 | |||
| 25 | config TIPC_ADVANCED | 25 | config TIPC_ADVANCED |
| 26 | bool "TIPC: Advanced configuration" | 26 | bool "TIPC: Advanced configuration" |
| 27 | depends on TIPC | ||
| 28 | default n | 27 | default n |
| 29 | help | 28 | help |
| 30 | Saying Y here will open some advanced configuration | 29 | Saying Y here will open some advanced configuration |
| @@ -33,7 +32,7 @@ config TIPC_ADVANCED | |||
| 33 | 32 | ||
| 34 | config TIPC_ZONES | 33 | config TIPC_ZONES |
| 35 | int "Maximum number of zones in network" | 34 | int "Maximum number of zones in network" |
| 36 | depends on TIPC && TIPC_ADVANCED | 35 | depends on TIPC_ADVANCED |
| 37 | default "3" | 36 | default "3" |
| 38 | help | 37 | help |
| 39 | Max number of zones inside TIPC network. Max supported value | 38 | Max number of zones inside TIPC network. Max supported value |
| @@ -44,7 +43,7 @@ config TIPC_ZONES | |||
| 44 | 43 | ||
| 45 | config TIPC_CLUSTERS | 44 | config TIPC_CLUSTERS |
| 46 | int "Maximum number of clusters in a zone" | 45 | int "Maximum number of clusters in a zone" |
| 47 | depends on TIPC && TIPC_ADVANCED | 46 | depends on TIPC_ADVANCED |
| 48 | default "1" | 47 | default "1" |
| 49 | help | 48 | help |
| 50 | ***Only 1 (one cluster in a zone) is supported by current code. | 49 | ***Only 1 (one cluster in a zone) is supported by current code. |
| @@ -59,7 +58,7 @@ config TIPC_CLUSTERS | |||
| 59 | 58 | ||
| 60 | config TIPC_NODES | 59 | config TIPC_NODES |
| 61 | int "Maximum number of nodes in cluster" | 60 | int "Maximum number of nodes in cluster" |
| 62 | depends on TIPC && TIPC_ADVANCED | 61 | depends on TIPC_ADVANCED |
| 63 | default "255" | 62 | default "255" |
| 64 | help | 63 | help |
| 65 | Maximum number of nodes inside a TIPC cluster. Maximum | 64 | Maximum number of nodes inside a TIPC cluster. Maximum |
| @@ -70,7 +69,7 @@ config TIPC_NODES | |||
| 70 | 69 | ||
| 71 | config TIPC_SLAVE_NODES | 70 | config TIPC_SLAVE_NODES |
| 72 | int "Maximum number of slave nodes in cluster" | 71 | int "Maximum number of slave nodes in cluster" |
| 73 | depends on TIPC && TIPC_ADVANCED | 72 | depends on TIPC_ADVANCED |
| 74 | default "0" | 73 | default "0" |
| 75 | help | 74 | help |
| 76 | ***This capability is not supported by current code.*** | 75 | ***This capability is not supported by current code.*** |
| @@ -83,7 +82,7 @@ config TIPC_SLAVE_NODES | |||
| 83 | 82 | ||
| 84 | config TIPC_PORTS | 83 | config TIPC_PORTS |
| 85 | int "Maximum number of ports in a node" | 84 | int "Maximum number of ports in a node" |
| 86 | depends on TIPC && TIPC_ADVANCED | 85 | depends on TIPC_ADVANCED |
| 87 | default "8191" | 86 | default "8191" |
| 88 | help | 87 | help |
| 89 | Maximum number of ports within a node. Maximum | 88 | Maximum number of ports within a node. Maximum |
| @@ -94,7 +93,7 @@ config TIPC_PORTS | |||
| 94 | 93 | ||
| 95 | config TIPC_LOG | 94 | config TIPC_LOG |
| 96 | int "Size of log buffer" | 95 | int "Size of log buffer" |
| 97 | depends on TIPC && TIPC_ADVANCED | 96 | depends on TIPC_ADVANCED |
| 98 | default 0 | 97 | default 0 |
| 99 | help | 98 | help |
| 100 | Size (in bytes) of TIPC's internal log buffer, which records the | 99 | Size (in bytes) of TIPC's internal log buffer, which records the |
| @@ -106,7 +105,6 @@ config TIPC_LOG | |||
| 106 | 105 | ||
| 107 | config TIPC_DEBUG | 106 | config TIPC_DEBUG |
| 108 | bool "Enable debugging support" | 107 | bool "Enable debugging support" |
| 109 | depends on TIPC | ||
| 110 | default n | 108 | default n |
| 111 | help | 109 | help |
| 112 | This will enable debugging of TIPC. | 110 | This will enable debugging of TIPC. |
| @@ -114,4 +112,4 @@ config TIPC_DEBUG | |||
| 114 | Only say Y here if you are having trouble with TIPC. It will | 112 | Only say Y here if you are having trouble with TIPC. It will |
| 115 | enable the display of detailed information about what is going on. | 113 | enable the display of detailed information about what is going on. |
| 116 | 114 | ||
| 117 | endmenu | 115 | endif # TIPC |
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 0ee6ded18f3a..77d2d9ce8962 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c | |||
| @@ -120,18 +120,20 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
| 120 | 120 | ||
| 121 | static int enable_bearer(struct tipc_bearer *tb_ptr) | 121 | static int enable_bearer(struct tipc_bearer *tb_ptr) |
| 122 | { | 122 | { |
| 123 | struct net_device *dev, *pdev; | 123 | struct net_device *dev = NULL; |
| 124 | struct net_device *pdev = NULL; | ||
| 124 | struct eth_bearer *eb_ptr = ð_bearers[0]; | 125 | struct eth_bearer *eb_ptr = ð_bearers[0]; |
| 125 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; | 126 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; |
| 126 | char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; | 127 | char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; |
| 127 | 128 | ||
| 128 | /* Find device with specified name */ | 129 | /* Find device with specified name */ |
| 129 | dev = NULL; | 130 | |
| 130 | for_each_netdev(pdev) | 131 | for_each_netdev(pdev){ |
| 131 | if (!strncmp(dev->name, driver_name, IFNAMSIZ)) { | 132 | if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { |
| 132 | dev = pdev; | 133 | dev = pdev; |
| 133 | break; | 134 | break; |
| 134 | } | 135 | } |
| 136 | } | ||
| 135 | if (!dev) | 137 | if (!dev) |
| 136 | return -ENODEV; | 138 | return -ENODEV; |
| 137 | 139 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index aec8cf165e1a..d70fa30d4294 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -111,7 +111,6 @@ | |||
| 111 | #include <net/scm.h> | 111 | #include <net/scm.h> |
| 112 | #include <linux/init.h> | 112 | #include <linux/init.h> |
| 113 | #include <linux/poll.h> | 113 | #include <linux/poll.h> |
| 114 | #include <linux/smp_lock.h> | ||
| 115 | #include <linux/rtnetlink.h> | 114 | #include <linux/rtnetlink.h> |
| 116 | #include <linux/mount.h> | 115 | #include <linux/mount.h> |
| 117 | #include <net/checksum.h> | 116 | #include <net/checksum.h> |
| @@ -175,11 +174,11 @@ static struct sock *unix_peer_get(struct sock *s) | |||
| 175 | { | 174 | { |
| 176 | struct sock *peer; | 175 | struct sock *peer; |
| 177 | 176 | ||
| 178 | unix_state_rlock(s); | 177 | unix_state_lock(s); |
| 179 | peer = unix_peer(s); | 178 | peer = unix_peer(s); |
| 180 | if (peer) | 179 | if (peer) |
| 181 | sock_hold(peer); | 180 | sock_hold(peer); |
| 182 | unix_state_runlock(s); | 181 | unix_state_unlock(s); |
| 183 | return peer; | 182 | return peer; |
| 184 | } | 183 | } |
| 185 | 184 | ||
| @@ -370,7 +369,7 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
| 370 | unix_remove_socket(sk); | 369 | unix_remove_socket(sk); |
| 371 | 370 | ||
| 372 | /* Clear state */ | 371 | /* Clear state */ |
| 373 | unix_state_wlock(sk); | 372 | unix_state_lock(sk); |
| 374 | sock_orphan(sk); | 373 | sock_orphan(sk); |
| 375 | sk->sk_shutdown = SHUTDOWN_MASK; | 374 | sk->sk_shutdown = SHUTDOWN_MASK; |
| 376 | dentry = u->dentry; | 375 | dentry = u->dentry; |
| @@ -379,7 +378,7 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
| 379 | u->mnt = NULL; | 378 | u->mnt = NULL; |
| 380 | state = sk->sk_state; | 379 | state = sk->sk_state; |
| 381 | sk->sk_state = TCP_CLOSE; | 380 | sk->sk_state = TCP_CLOSE; |
| 382 | unix_state_wunlock(sk); | 381 | unix_state_unlock(sk); |
| 383 | 382 | ||
| 384 | wake_up_interruptible_all(&u->peer_wait); | 383 | wake_up_interruptible_all(&u->peer_wait); |
| 385 | 384 | ||
| @@ -387,12 +386,12 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
| 387 | 386 | ||
| 388 | if (skpair!=NULL) { | 387 | if (skpair!=NULL) { |
| 389 | if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { | 388 | if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { |
| 390 | unix_state_wlock(skpair); | 389 | unix_state_lock(skpair); |
| 391 | /* No more writes */ | 390 | /* No more writes */ |
| 392 | skpair->sk_shutdown = SHUTDOWN_MASK; | 391 | skpair->sk_shutdown = SHUTDOWN_MASK; |
| 393 | if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) | 392 | if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) |
| 394 | skpair->sk_err = ECONNRESET; | 393 | skpair->sk_err = ECONNRESET; |
| 395 | unix_state_wunlock(skpair); | 394 | unix_state_unlock(skpair); |
| 396 | skpair->sk_state_change(skpair); | 395 | skpair->sk_state_change(skpair); |
| 397 | read_lock(&skpair->sk_callback_lock); | 396 | read_lock(&skpair->sk_callback_lock); |
| 398 | sk_wake_async(skpair,1,POLL_HUP); | 397 | sk_wake_async(skpair,1,POLL_HUP); |
| @@ -449,7 +448,7 @@ static int unix_listen(struct socket *sock, int backlog) | |||
| 449 | err = -EINVAL; | 448 | err = -EINVAL; |
| 450 | if (!u->addr) | 449 | if (!u->addr) |
| 451 | goto out; /* No listens on an unbound socket */ | 450 | goto out; /* No listens on an unbound socket */ |
| 452 | unix_state_wlock(sk); | 451 | unix_state_lock(sk); |
| 453 | if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) | 452 | if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) |
| 454 | goto out_unlock; | 453 | goto out_unlock; |
| 455 | if (backlog > sk->sk_max_ack_backlog) | 454 | if (backlog > sk->sk_max_ack_backlog) |
| @@ -463,7 +462,7 @@ static int unix_listen(struct socket *sock, int backlog) | |||
| 463 | err = 0; | 462 | err = 0; |
| 464 | 463 | ||
| 465 | out_unlock: | 464 | out_unlock: |
| 466 | unix_state_wunlock(sk); | 465 | unix_state_unlock(sk); |
| 467 | out: | 466 | out: |
| 468 | return err; | 467 | return err; |
| 469 | } | 468 | } |
| @@ -859,6 +858,31 @@ out_mknod_parent: | |||
| 859 | goto out_up; | 858 | goto out_up; |
| 860 | } | 859 | } |
| 861 | 860 | ||
| 861 | static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) | ||
| 862 | { | ||
| 863 | if (unlikely(sk1 == sk2) || !sk2) { | ||
| 864 | unix_state_lock(sk1); | ||
| 865 | return; | ||
| 866 | } | ||
| 867 | if (sk1 < sk2) { | ||
| 868 | unix_state_lock(sk1); | ||
| 869 | unix_state_lock_nested(sk2); | ||
| 870 | } else { | ||
| 871 | unix_state_lock(sk2); | ||
| 872 | unix_state_lock_nested(sk1); | ||
| 873 | } | ||
| 874 | } | ||
| 875 | |||
| 876 | static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) | ||
| 877 | { | ||
| 878 | if (unlikely(sk1 == sk2) || !sk2) { | ||
| 879 | unix_state_unlock(sk1); | ||
| 880 | return; | ||
| 881 | } | ||
| 882 | unix_state_unlock(sk1); | ||
| 883 | unix_state_unlock(sk2); | ||
| 884 | } | ||
| 885 | |||
| 862 | static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | 886 | static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, |
| 863 | int alen, int flags) | 887 | int alen, int flags) |
| 864 | { | 888 | { |
| @@ -878,11 +902,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
| 878 | !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0) | 902 | !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0) |
| 879 | goto out; | 903 | goto out; |
| 880 | 904 | ||
| 905 | restart: | ||
| 881 | other=unix_find_other(sunaddr, alen, sock->type, hash, &err); | 906 | other=unix_find_other(sunaddr, alen, sock->type, hash, &err); |
| 882 | if (!other) | 907 | if (!other) |
| 883 | goto out; | 908 | goto out; |
| 884 | 909 | ||
| 885 | unix_state_wlock(sk); | 910 | unix_state_double_lock(sk, other); |
| 911 | |||
| 912 | /* Apparently VFS overslept socket death. Retry. */ | ||
| 913 | if (sock_flag(other, SOCK_DEAD)) { | ||
| 914 | unix_state_double_unlock(sk, other); | ||
| 915 | sock_put(other); | ||
| 916 | goto restart; | ||
| 917 | } | ||
| 886 | 918 | ||
| 887 | err = -EPERM; | 919 | err = -EPERM; |
| 888 | if (!unix_may_send(sk, other)) | 920 | if (!unix_may_send(sk, other)) |
| @@ -897,7 +929,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
| 897 | * 1003.1g breaking connected state with AF_UNSPEC | 929 | * 1003.1g breaking connected state with AF_UNSPEC |
| 898 | */ | 930 | */ |
| 899 | other = NULL; | 931 | other = NULL; |
| 900 | unix_state_wlock(sk); | 932 | unix_state_double_lock(sk, other); |
| 901 | } | 933 | } |
| 902 | 934 | ||
| 903 | /* | 935 | /* |
| @@ -906,19 +938,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
| 906 | if (unix_peer(sk)) { | 938 | if (unix_peer(sk)) { |
| 907 | struct sock *old_peer = unix_peer(sk); | 939 | struct sock *old_peer = unix_peer(sk); |
| 908 | unix_peer(sk)=other; | 940 | unix_peer(sk)=other; |
| 909 | unix_state_wunlock(sk); | 941 | unix_state_double_unlock(sk, other); |
| 910 | 942 | ||
| 911 | if (other != old_peer) | 943 | if (other != old_peer) |
| 912 | unix_dgram_disconnected(sk, old_peer); | 944 | unix_dgram_disconnected(sk, old_peer); |
| 913 | sock_put(old_peer); | 945 | sock_put(old_peer); |
| 914 | } else { | 946 | } else { |
| 915 | unix_peer(sk)=other; | 947 | unix_peer(sk)=other; |
| 916 | unix_state_wunlock(sk); | 948 | unix_state_double_unlock(sk, other); |
| 917 | } | 949 | } |
| 918 | return 0; | 950 | return 0; |
| 919 | 951 | ||
| 920 | out_unlock: | 952 | out_unlock: |
| 921 | unix_state_wunlock(sk); | 953 | unix_state_double_unlock(sk, other); |
| 922 | sock_put(other); | 954 | sock_put(other); |
| 923 | out: | 955 | out: |
| 924 | return err; | 956 | return err; |
| @@ -937,7 +969,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) | |||
| 937 | (skb_queue_len(&other->sk_receive_queue) > | 969 | (skb_queue_len(&other->sk_receive_queue) > |
| 938 | other->sk_max_ack_backlog); | 970 | other->sk_max_ack_backlog); |
| 939 | 971 | ||
| 940 | unix_state_runlock(other); | 972 | unix_state_unlock(other); |
| 941 | 973 | ||
| 942 | if (sched) | 974 | if (sched) |
| 943 | timeo = schedule_timeout(timeo); | 975 | timeo = schedule_timeout(timeo); |
| @@ -995,11 +1027,11 @@ restart: | |||
| 995 | goto out; | 1027 | goto out; |
| 996 | 1028 | ||
| 997 | /* Latch state of peer */ | 1029 | /* Latch state of peer */ |
| 998 | unix_state_rlock(other); | 1030 | unix_state_lock(other); |
| 999 | 1031 | ||
| 1000 | /* Apparently VFS overslept socket death. Retry. */ | 1032 | /* Apparently VFS overslept socket death. Retry. */ |
| 1001 | if (sock_flag(other, SOCK_DEAD)) { | 1033 | if (sock_flag(other, SOCK_DEAD)) { |
| 1002 | unix_state_runlock(other); | 1034 | unix_state_unlock(other); |
| 1003 | sock_put(other); | 1035 | sock_put(other); |
| 1004 | goto restart; | 1036 | goto restart; |
| 1005 | } | 1037 | } |
| @@ -1049,18 +1081,18 @@ restart: | |||
| 1049 | goto out_unlock; | 1081 | goto out_unlock; |
| 1050 | } | 1082 | } |
| 1051 | 1083 | ||
| 1052 | unix_state_wlock_nested(sk); | 1084 | unix_state_lock_nested(sk); |
| 1053 | 1085 | ||
| 1054 | if (sk->sk_state != st) { | 1086 | if (sk->sk_state != st) { |
| 1055 | unix_state_wunlock(sk); | 1087 | unix_state_unlock(sk); |
| 1056 | unix_state_runlock(other); | 1088 | unix_state_unlock(other); |
| 1057 | sock_put(other); | 1089 | sock_put(other); |
| 1058 | goto restart; | 1090 | goto restart; |
| 1059 | } | 1091 | } |
| 1060 | 1092 | ||
| 1061 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); | 1093 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); |
| 1062 | if (err) { | 1094 | if (err) { |
| 1063 | unix_state_wunlock(sk); | 1095 | unix_state_unlock(sk); |
| 1064 | goto out_unlock; | 1096 | goto out_unlock; |
| 1065 | } | 1097 | } |
| 1066 | 1098 | ||
| @@ -1097,7 +1129,7 @@ restart: | |||
| 1097 | smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ | 1129 | smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ |
| 1098 | unix_peer(sk) = newsk; | 1130 | unix_peer(sk) = newsk; |
| 1099 | 1131 | ||
| 1100 | unix_state_wunlock(sk); | 1132 | unix_state_unlock(sk); |
| 1101 | 1133 | ||
| 1102 | /* take ten and and send info to listening sock */ | 1134 | /* take ten and and send info to listening sock */ |
| 1103 | spin_lock(&other->sk_receive_queue.lock); | 1135 | spin_lock(&other->sk_receive_queue.lock); |
| @@ -1106,14 +1138,14 @@ restart: | |||
| 1106 | * is installed to listening socket. */ | 1138 | * is installed to listening socket. */ |
| 1107 | atomic_inc(&newu->inflight); | 1139 | atomic_inc(&newu->inflight); |
| 1108 | spin_unlock(&other->sk_receive_queue.lock); | 1140 | spin_unlock(&other->sk_receive_queue.lock); |
| 1109 | unix_state_runlock(other); | 1141 | unix_state_unlock(other); |
| 1110 | other->sk_data_ready(other, 0); | 1142 | other->sk_data_ready(other, 0); |
| 1111 | sock_put(other); | 1143 | sock_put(other); |
| 1112 | return 0; | 1144 | return 0; |
| 1113 | 1145 | ||
| 1114 | out_unlock: | 1146 | out_unlock: |
| 1115 | if (other) | 1147 | if (other) |
| 1116 | unix_state_runlock(other); | 1148 | unix_state_unlock(other); |
| 1117 | 1149 | ||
| 1118 | out: | 1150 | out: |
| 1119 | if (skb) | 1151 | if (skb) |
| @@ -1179,10 +1211,10 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 1179 | wake_up_interruptible(&unix_sk(sk)->peer_wait); | 1211 | wake_up_interruptible(&unix_sk(sk)->peer_wait); |
| 1180 | 1212 | ||
| 1181 | /* attach accepted sock to socket */ | 1213 | /* attach accepted sock to socket */ |
| 1182 | unix_state_wlock(tsk); | 1214 | unix_state_lock(tsk); |
| 1183 | newsock->state = SS_CONNECTED; | 1215 | newsock->state = SS_CONNECTED; |
| 1184 | sock_graft(tsk, newsock); | 1216 | sock_graft(tsk, newsock); |
| 1185 | unix_state_wunlock(tsk); | 1217 | unix_state_unlock(tsk); |
| 1186 | return 0; | 1218 | return 0; |
| 1187 | 1219 | ||
| 1188 | out: | 1220 | out: |
| @@ -1209,7 +1241,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ | |||
| 1209 | } | 1241 | } |
| 1210 | 1242 | ||
| 1211 | u = unix_sk(sk); | 1243 | u = unix_sk(sk); |
| 1212 | unix_state_rlock(sk); | 1244 | unix_state_lock(sk); |
| 1213 | if (!u->addr) { | 1245 | if (!u->addr) { |
| 1214 | sunaddr->sun_family = AF_UNIX; | 1246 | sunaddr->sun_family = AF_UNIX; |
| 1215 | sunaddr->sun_path[0] = 0; | 1247 | sunaddr->sun_path[0] = 0; |
| @@ -1220,7 +1252,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ | |||
| 1220 | *uaddr_len = addr->len; | 1252 | *uaddr_len = addr->len; |
| 1221 | memcpy(sunaddr, addr->name, *uaddr_len); | 1253 | memcpy(sunaddr, addr->name, *uaddr_len); |
| 1222 | } | 1254 | } |
| 1223 | unix_state_runlock(sk); | 1255 | unix_state_unlock(sk); |
| 1224 | sock_put(sk); | 1256 | sock_put(sk); |
| 1225 | out: | 1257 | out: |
| 1226 | return err; | 1258 | return err; |
| @@ -1338,7 +1370,7 @@ restart: | |||
| 1338 | goto out_free; | 1370 | goto out_free; |
| 1339 | } | 1371 | } |
| 1340 | 1372 | ||
| 1341 | unix_state_rlock(other); | 1373 | unix_state_lock(other); |
| 1342 | err = -EPERM; | 1374 | err = -EPERM; |
| 1343 | if (!unix_may_send(sk, other)) | 1375 | if (!unix_may_send(sk, other)) |
| 1344 | goto out_unlock; | 1376 | goto out_unlock; |
| @@ -1348,20 +1380,20 @@ restart: | |||
| 1348 | * Check with 1003.1g - what should | 1380 | * Check with 1003.1g - what should |
| 1349 | * datagram error | 1381 | * datagram error |
| 1350 | */ | 1382 | */ |
| 1351 | unix_state_runlock(other); | 1383 | unix_state_unlock(other); |
| 1352 | sock_put(other); | 1384 | sock_put(other); |
| 1353 | 1385 | ||
| 1354 | err = 0; | 1386 | err = 0; |
| 1355 | unix_state_wlock(sk); | 1387 | unix_state_lock(sk); |
| 1356 | if (unix_peer(sk) == other) { | 1388 | if (unix_peer(sk) == other) { |
| 1357 | unix_peer(sk)=NULL; | 1389 | unix_peer(sk)=NULL; |
| 1358 | unix_state_wunlock(sk); | 1390 | unix_state_unlock(sk); |
| 1359 | 1391 | ||
| 1360 | unix_dgram_disconnected(sk, other); | 1392 | unix_dgram_disconnected(sk, other); |
| 1361 | sock_put(other); | 1393 | sock_put(other); |
| 1362 | err = -ECONNREFUSED; | 1394 | err = -ECONNREFUSED; |
| 1363 | } else { | 1395 | } else { |
| 1364 | unix_state_wunlock(sk); | 1396 | unix_state_unlock(sk); |
| 1365 | } | 1397 | } |
| 1366 | 1398 | ||
| 1367 | other = NULL; | 1399 | other = NULL; |
| @@ -1398,14 +1430,14 @@ restart: | |||
| 1398 | } | 1430 | } |
| 1399 | 1431 | ||
| 1400 | skb_queue_tail(&other->sk_receive_queue, skb); | 1432 | skb_queue_tail(&other->sk_receive_queue, skb); |
| 1401 | unix_state_runlock(other); | 1433 | unix_state_unlock(other); |
| 1402 | other->sk_data_ready(other, len); | 1434 | other->sk_data_ready(other, len); |
| 1403 | sock_put(other); | 1435 | sock_put(other); |
| 1404 | scm_destroy(siocb->scm); | 1436 | scm_destroy(siocb->scm); |
| 1405 | return len; | 1437 | return len; |
| 1406 | 1438 | ||
| 1407 | out_unlock: | 1439 | out_unlock: |
| 1408 | unix_state_runlock(other); | 1440 | unix_state_unlock(other); |
| 1409 | out_free: | 1441 | out_free: |
| 1410 | kfree_skb(skb); | 1442 | kfree_skb(skb); |
| 1411 | out: | 1443 | out: |
| @@ -1495,14 +1527,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1495 | goto out_err; | 1527 | goto out_err; |
| 1496 | } | 1528 | } |
| 1497 | 1529 | ||
| 1498 | unix_state_rlock(other); | 1530 | unix_state_lock(other); |
| 1499 | 1531 | ||
| 1500 | if (sock_flag(other, SOCK_DEAD) || | 1532 | if (sock_flag(other, SOCK_DEAD) || |
| 1501 | (other->sk_shutdown & RCV_SHUTDOWN)) | 1533 | (other->sk_shutdown & RCV_SHUTDOWN)) |
| 1502 | goto pipe_err_free; | 1534 | goto pipe_err_free; |
| 1503 | 1535 | ||
| 1504 | skb_queue_tail(&other->sk_receive_queue, skb); | 1536 | skb_queue_tail(&other->sk_receive_queue, skb); |
| 1505 | unix_state_runlock(other); | 1537 | unix_state_unlock(other); |
| 1506 | other->sk_data_ready(other, size); | 1538 | other->sk_data_ready(other, size); |
| 1507 | sent+=size; | 1539 | sent+=size; |
| 1508 | } | 1540 | } |
| @@ -1513,7 +1545,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1513 | return sent; | 1545 | return sent; |
| 1514 | 1546 | ||
| 1515 | pipe_err_free: | 1547 | pipe_err_free: |
| 1516 | unix_state_runlock(other); | 1548 | unix_state_unlock(other); |
| 1517 | kfree_skb(skb); | 1549 | kfree_skb(skb); |
| 1518 | pipe_err: | 1550 | pipe_err: |
| 1519 | if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL)) | 1551 | if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL)) |
| @@ -1642,7 +1674,7 @@ static long unix_stream_data_wait(struct sock * sk, long timeo) | |||
| 1642 | { | 1674 | { |
| 1643 | DEFINE_WAIT(wait); | 1675 | DEFINE_WAIT(wait); |
| 1644 | 1676 | ||
| 1645 | unix_state_rlock(sk); | 1677 | unix_state_lock(sk); |
| 1646 | 1678 | ||
| 1647 | for (;;) { | 1679 | for (;;) { |
| 1648 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1680 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
| @@ -1655,14 +1687,14 @@ static long unix_stream_data_wait(struct sock * sk, long timeo) | |||
| 1655 | break; | 1687 | break; |
| 1656 | 1688 | ||
| 1657 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1689 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
| 1658 | unix_state_runlock(sk); | 1690 | unix_state_unlock(sk); |
| 1659 | timeo = schedule_timeout(timeo); | 1691 | timeo = schedule_timeout(timeo); |
| 1660 | unix_state_rlock(sk); | 1692 | unix_state_lock(sk); |
| 1661 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1693 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
| 1662 | } | 1694 | } |
| 1663 | 1695 | ||
| 1664 | finish_wait(sk->sk_sleep, &wait); | 1696 | finish_wait(sk->sk_sleep, &wait); |
| 1665 | unix_state_runlock(sk); | 1697 | unix_state_unlock(sk); |
| 1666 | return timeo; | 1698 | return timeo; |
| 1667 | } | 1699 | } |
| 1668 | 1700 | ||
| @@ -1712,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1712 | int chunk; | 1744 | int chunk; |
| 1713 | struct sk_buff *skb; | 1745 | struct sk_buff *skb; |
| 1714 | 1746 | ||
| 1747 | unix_state_lock(sk); | ||
| 1715 | skb = skb_dequeue(&sk->sk_receive_queue); | 1748 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1716 | if (skb==NULL) | 1749 | if (skb==NULL) |
| 1717 | { | 1750 | { |
| 1718 | if (copied >= target) | 1751 | if (copied >= target) |
| 1719 | break; | 1752 | goto unlock; |
| 1720 | 1753 | ||
| 1721 | /* | 1754 | /* |
| 1722 | * POSIX 1003.1g mandates this order. | 1755 | * POSIX 1003.1g mandates this order. |
| 1723 | */ | 1756 | */ |
| 1724 | 1757 | ||
| 1725 | if ((err = sock_error(sk)) != 0) | 1758 | if ((err = sock_error(sk)) != 0) |
| 1726 | break; | 1759 | goto unlock; |
| 1727 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1760 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 1728 | break; | 1761 | goto unlock; |
| 1762 | |||
| 1763 | unix_state_unlock(sk); | ||
| 1729 | err = -EAGAIN; | 1764 | err = -EAGAIN; |
| 1730 | if (!timeo) | 1765 | if (!timeo) |
| 1731 | break; | 1766 | break; |
| @@ -1739,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1739 | } | 1774 | } |
| 1740 | mutex_lock(&u->readlock); | 1775 | mutex_lock(&u->readlock); |
| 1741 | continue; | 1776 | continue; |
| 1777 | unlock: | ||
| 1778 | unix_state_unlock(sk); | ||
| 1779 | break; | ||
| 1742 | } | 1780 | } |
| 1781 | unix_state_unlock(sk); | ||
| 1743 | 1782 | ||
| 1744 | if (check_creds) { | 1783 | if (check_creds) { |
| 1745 | /* Never glue messages from different writers */ | 1784 | /* Never glue messages from different writers */ |
| @@ -1817,12 +1856,12 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
| 1817 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); | 1856 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); |
| 1818 | 1857 | ||
| 1819 | if (mode) { | 1858 | if (mode) { |
| 1820 | unix_state_wlock(sk); | 1859 | unix_state_lock(sk); |
| 1821 | sk->sk_shutdown |= mode; | 1860 | sk->sk_shutdown |= mode; |
| 1822 | other=unix_peer(sk); | 1861 | other=unix_peer(sk); |
| 1823 | if (other) | 1862 | if (other) |
| 1824 | sock_hold(other); | 1863 | sock_hold(other); |
| 1825 | unix_state_wunlock(sk); | 1864 | unix_state_unlock(sk); |
| 1826 | sk->sk_state_change(sk); | 1865 | sk->sk_state_change(sk); |
| 1827 | 1866 | ||
| 1828 | if (other && | 1867 | if (other && |
| @@ -1834,9 +1873,9 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
| 1834 | peer_mode |= SEND_SHUTDOWN; | 1873 | peer_mode |= SEND_SHUTDOWN; |
| 1835 | if (mode&SEND_SHUTDOWN) | 1874 | if (mode&SEND_SHUTDOWN) |
| 1836 | peer_mode |= RCV_SHUTDOWN; | 1875 | peer_mode |= RCV_SHUTDOWN; |
| 1837 | unix_state_wlock(other); | 1876 | unix_state_lock(other); |
| 1838 | other->sk_shutdown |= peer_mode; | 1877 | other->sk_shutdown |= peer_mode; |
| 1839 | unix_state_wunlock(other); | 1878 | unix_state_unlock(other); |
| 1840 | other->sk_state_change(other); | 1879 | other->sk_state_change(other); |
| 1841 | read_lock(&other->sk_callback_lock); | 1880 | read_lock(&other->sk_callback_lock); |
| 1842 | if (peer_mode == SHUTDOWN_MASK) | 1881 | if (peer_mode == SHUTDOWN_MASK) |
| @@ -1974,7 +2013,7 @@ static int unix_seq_show(struct seq_file *seq, void *v) | |||
| 1974 | else { | 2013 | else { |
| 1975 | struct sock *s = v; | 2014 | struct sock *s = v; |
| 1976 | struct unix_sock *u = unix_sk(s); | 2015 | struct unix_sock *u = unix_sk(s); |
| 1977 | unix_state_rlock(s); | 2016 | unix_state_lock(s); |
| 1978 | 2017 | ||
| 1979 | seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu", | 2018 | seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu", |
| 1980 | s, | 2019 | s, |
| @@ -2002,7 +2041,7 @@ static int unix_seq_show(struct seq_file *seq, void *v) | |||
| 2002 | for ( ; i < len; i++) | 2041 | for ( ; i < len; i++) |
| 2003 | seq_putc(seq, u->addr->name->sun_path[i]); | 2042 | seq_putc(seq, u->addr->name->sun_path[i]); |
| 2004 | } | 2043 | } |
| 2005 | unix_state_runlock(s); | 2044 | unix_state_unlock(s); |
| 2006 | seq_putc(seq, '\n'); | 2045 | seq_putc(seq, '\n'); |
| 2007 | } | 2046 | } |
| 2008 | 2047 | ||
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 7a19e0ede289..849cc06bd914 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c | |||
| @@ -454,7 +454,7 @@ static int wanrouter_device_setup(struct wan_device *wandev, | |||
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | if (conf->data_size && conf->data) { | 456 | if (conf->data_size && conf->data) { |
| 457 | if (conf->data_size > 128000 || conf->data_size < 0) { | 457 | if (conf->data_size > 128000) { |
| 458 | printk(KERN_INFO | 458 | printk(KERN_INFO |
| 459 | "%s: ERROR, Invalid firmware data size %i !\n", | 459 | "%s: ERROR, Invalid firmware data size %i !\n", |
| 460 | wandev->name, conf->data_size); | 460 | wandev->name, conf->data_size); |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 0d6002fc77b2..479927cb45ca 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
| @@ -1605,7 +1605,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | |||
| 1605 | .sendpage = sock_no_sendpage, | 1605 | .sendpage = sock_no_sendpage, |
| 1606 | }; | 1606 | }; |
| 1607 | 1607 | ||
| 1608 | #include <linux/smp_lock.h> | ||
| 1609 | SOCKOPS_WRAP(x25_proto, AF_X25); | 1608 | SOCKOPS_WRAP(x25_proto, AF_X25); |
| 1610 | 1609 | ||
| 1611 | static struct packet_type x25_packet_type = { | 1610 | static struct packet_type x25_packet_type = { |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 6249a9405bb8..5ced62c19c63 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
| @@ -347,67 +347,44 @@ static inline int calg_entries(void) | |||
| 347 | return ARRAY_SIZE(calg_list); | 347 | return ARRAY_SIZE(calg_list); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | /* Todo: generic iterators */ | 350 | struct xfrm_algo_list { |
| 351 | struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) | 351 | struct xfrm_algo_desc *algs; |
| 352 | { | 352 | int entries; |
| 353 | int i; | 353 | u32 type; |
| 354 | 354 | u32 mask; | |
| 355 | for (i = 0; i < aalg_entries(); i++) { | 355 | }; |
| 356 | if (aalg_list[i].desc.sadb_alg_id == alg_id) { | ||
| 357 | if (aalg_list[i].available) | ||
| 358 | return &aalg_list[i]; | ||
| 359 | else | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | } | ||
| 363 | return NULL; | ||
| 364 | } | ||
| 365 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); | ||
| 366 | |||
| 367 | struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) | ||
| 368 | { | ||
| 369 | int i; | ||
| 370 | 356 | ||
| 371 | for (i = 0; i < ealg_entries(); i++) { | 357 | static const struct xfrm_algo_list xfrm_aalg_list = { |
| 372 | if (ealg_list[i].desc.sadb_alg_id == alg_id) { | 358 | .algs = aalg_list, |
| 373 | if (ealg_list[i].available) | 359 | .entries = ARRAY_SIZE(aalg_list), |
| 374 | return &ealg_list[i]; | 360 | .type = CRYPTO_ALG_TYPE_HASH, |
| 375 | else | 361 | .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC, |
| 376 | break; | 362 | }; |
| 377 | } | ||
| 378 | } | ||
| 379 | return NULL; | ||
| 380 | } | ||
| 381 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); | ||
| 382 | 363 | ||
| 383 | struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) | 364 | static const struct xfrm_algo_list xfrm_ealg_list = { |
| 384 | { | 365 | .algs = ealg_list, |
| 385 | int i; | 366 | .entries = ARRAY_SIZE(ealg_list), |
| 367 | .type = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 368 | .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, | ||
| 369 | }; | ||
| 386 | 370 | ||
| 387 | for (i = 0; i < calg_entries(); i++) { | 371 | static const struct xfrm_algo_list xfrm_calg_list = { |
| 388 | if (calg_list[i].desc.sadb_alg_id == alg_id) { | 372 | .algs = calg_list, |
| 389 | if (calg_list[i].available) | 373 | .entries = ARRAY_SIZE(calg_list), |
| 390 | return &calg_list[i]; | 374 | .type = CRYPTO_ALG_TYPE_COMPRESS, |
| 391 | else | 375 | .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, |
| 392 | break; | 376 | }; |
| 393 | } | ||
| 394 | } | ||
| 395 | return NULL; | ||
| 396 | } | ||
| 397 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); | ||
| 398 | 377 | ||
| 399 | static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | 378 | static struct xfrm_algo_desc *xfrm_find_algo( |
| 400 | int entries, u32 type, u32 mask, | 379 | const struct xfrm_algo_list *algo_list, |
| 401 | char *name, int probe) | 380 | int match(const struct xfrm_algo_desc *entry, const void *data), |
| 381 | const void *data, int probe) | ||
| 402 | { | 382 | { |
| 383 | struct xfrm_algo_desc *list = algo_list->algs; | ||
| 403 | int i, status; | 384 | int i, status; |
| 404 | 385 | ||
| 405 | if (!name) | 386 | for (i = 0; i < algo_list->entries; i++) { |
| 406 | return NULL; | 387 | if (!match(list + i, data)) |
| 407 | |||
| 408 | for (i = 0; i < entries; i++) { | ||
| 409 | if (strcmp(name, list[i].name) && | ||
| 410 | (!list[i].compat || strcmp(name, list[i].compat))) | ||
| 411 | continue; | 388 | continue; |
| 412 | 389 | ||
| 413 | if (list[i].available) | 390 | if (list[i].available) |
| @@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | |||
| 416 | if (!probe) | 393 | if (!probe) |
| 417 | break; | 394 | break; |
| 418 | 395 | ||
| 419 | status = crypto_has_alg(list[i].name, type, | 396 | status = crypto_has_alg(list[i].name, algo_list->type, |
| 420 | mask | CRYPTO_ALG_ASYNC); | 397 | algo_list->mask); |
| 421 | if (!status) | 398 | if (!status) |
| 422 | break; | 399 | break; |
| 423 | 400 | ||
| @@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | |||
| 427 | return NULL; | 404 | return NULL; |
| 428 | } | 405 | } |
| 429 | 406 | ||
| 407 | static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, | ||
| 408 | const void *data) | ||
| 409 | { | ||
| 410 | return entry->desc.sadb_alg_id == (unsigned long)data; | ||
| 411 | } | ||
| 412 | |||
| 413 | struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) | ||
| 414 | { | ||
| 415 | return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, | ||
| 416 | (void *)(unsigned long)alg_id, 1); | ||
| 417 | } | ||
| 418 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); | ||
| 419 | |||
| 420 | struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) | ||
| 421 | { | ||
| 422 | return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, | ||
| 423 | (void *)(unsigned long)alg_id, 1); | ||
| 424 | } | ||
| 425 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); | ||
| 426 | |||
| 427 | struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) | ||
| 428 | { | ||
| 429 | return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, | ||
| 430 | (void *)(unsigned long)alg_id, 1); | ||
| 431 | } | ||
| 432 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); | ||
| 433 | |||
| 434 | static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, | ||
| 435 | const void *data) | ||
| 436 | { | ||
| 437 | const char *name = data; | ||
| 438 | |||
| 439 | return name && (!strcmp(name, entry->name) || | ||
| 440 | (entry->compat && !strcmp(name, entry->compat))); | ||
| 441 | } | ||
| 442 | |||
| 430 | struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) | 443 | struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) |
| 431 | { | 444 | { |
| 432 | return xfrm_get_byname(aalg_list, aalg_entries(), | 445 | return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, |
| 433 | CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, | 446 | probe); |
| 434 | name, probe); | ||
| 435 | } | 447 | } |
| 436 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); | 448 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); |
| 437 | 449 | ||
| 438 | struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) | 450 | struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) |
| 439 | { | 451 | { |
| 440 | return xfrm_get_byname(ealg_list, ealg_entries(), | 452 | return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, |
| 441 | CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, | 453 | probe); |
| 442 | name, probe); | ||
| 443 | } | 454 | } |
| 444 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); | 455 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); |
| 445 | 456 | ||
| 446 | struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) | 457 | struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) |
| 447 | { | 458 | { |
| 448 | return xfrm_get_byname(calg_list, calg_entries(), | 459 | return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, |
| 449 | CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, | 460 | probe); |
| 450 | name, probe); | ||
| 451 | } | 461 | } |
| 452 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); | 462 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); |
| 453 | 463 | ||
diff --git a/net/xfrm/xfrm_hash.c b/net/xfrm/xfrm_hash.c index 37643bb8768a..55ab5792af56 100644 --- a/net/xfrm/xfrm_hash.c +++ b/net/xfrm/xfrm_hash.c | |||
| @@ -22,7 +22,8 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz) | |||
| 22 | n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL); | 22 | n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL); |
| 23 | else | 23 | else |
| 24 | n = (struct hlist_head *) | 24 | n = (struct hlist_head *) |
| 25 | __get_free_pages(GFP_KERNEL, get_order(sz)); | 25 | __get_free_pages(GFP_KERNEL | __GFP_NOWARN, |
| 26 | get_order(sz)); | ||
| 26 | 27 | ||
| 27 | if (n) | 28 | if (n) |
| 28 | memset(n, 0, sz); | 29 | memset(n, 0, sz); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 95271e8426a1..157bfbd250ba 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -26,9 +26,12 @@ | |||
| 26 | #include <net/xfrm.h> | 26 | #include <net/xfrm.h> |
| 27 | #include <net/ip.h> | 27 | #include <net/ip.h> |
| 28 | #include <linux/audit.h> | 28 | #include <linux/audit.h> |
| 29 | #include <linux/cache.h> | ||
| 29 | 30 | ||
| 30 | #include "xfrm_hash.h" | 31 | #include "xfrm_hash.h" |
| 31 | 32 | ||
| 33 | int sysctl_xfrm_larval_drop __read_mostly; | ||
| 34 | |||
| 32 | DEFINE_MUTEX(xfrm_cfg_mutex); | 35 | DEFINE_MUTEX(xfrm_cfg_mutex); |
| 33 | EXPORT_SYMBOL(xfrm_cfg_mutex); | 36 | EXPORT_SYMBOL(xfrm_cfg_mutex); |
| 34 | 37 | ||
| @@ -796,6 +799,10 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
| 796 | struct hlist_head *chain; | 799 | struct hlist_head *chain; |
| 797 | struct hlist_node *entry; | 800 | struct hlist_node *entry; |
| 798 | 801 | ||
| 802 | *err = -ENOENT; | ||
| 803 | if (xfrm_policy_id2dir(id) != dir) | ||
| 804 | return NULL; | ||
| 805 | |||
| 799 | *err = 0; | 806 | *err = 0; |
| 800 | write_lock_bh(&xfrm_policy_lock); | 807 | write_lock_bh(&xfrm_policy_lock); |
| 801 | chain = xfrm_policy_byidx + idx_hash(id); | 808 | chain = xfrm_policy_byidx + idx_hash(id); |
| @@ -827,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
| 827 | } | 834 | } |
| 828 | EXPORT_SYMBOL(xfrm_policy_byid); | 835 | EXPORT_SYMBOL(xfrm_policy_byid); |
| 829 | 836 | ||
| 830 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | 837 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 838 | static inline int | ||
| 839 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
| 831 | { | 840 | { |
| 832 | int dir; | 841 | int dir, err = 0; |
| 842 | |||
| 843 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | ||
| 844 | struct xfrm_policy *pol; | ||
| 845 | struct hlist_node *entry; | ||
| 846 | int i; | ||
| 847 | |||
| 848 | hlist_for_each_entry(pol, entry, | ||
| 849 | &xfrm_policy_inexact[dir], bydst) { | ||
| 850 | if (pol->type != type) | ||
| 851 | continue; | ||
| 852 | err = security_xfrm_policy_delete(pol); | ||
| 853 | if (err) { | ||
| 854 | xfrm_audit_log(audit_info->loginuid, | ||
| 855 | audit_info->secid, | ||
| 856 | AUDIT_MAC_IPSEC_DELSPD, 0, | ||
| 857 | pol, NULL); | ||
| 858 | return err; | ||
| 859 | } | ||
| 860 | } | ||
| 861 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | ||
| 862 | hlist_for_each_entry(pol, entry, | ||
| 863 | xfrm_policy_bydst[dir].table + i, | ||
| 864 | bydst) { | ||
| 865 | if (pol->type != type) | ||
| 866 | continue; | ||
| 867 | err = security_xfrm_policy_delete(pol); | ||
| 868 | if (err) { | ||
| 869 | xfrm_audit_log(audit_info->loginuid, | ||
| 870 | audit_info->secid, | ||
| 871 | AUDIT_MAC_IPSEC_DELSPD, | ||
| 872 | 0, pol, NULL); | ||
| 873 | return err; | ||
| 874 | } | ||
| 875 | } | ||
| 876 | } | ||
| 877 | } | ||
| 878 | return err; | ||
| 879 | } | ||
| 880 | #else | ||
| 881 | static inline int | ||
| 882 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
| 883 | { | ||
| 884 | return 0; | ||
| 885 | } | ||
| 886 | #endif | ||
| 887 | |||
| 888 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | ||
| 889 | { | ||
| 890 | int dir, err = 0; | ||
| 833 | 891 | ||
| 834 | write_lock_bh(&xfrm_policy_lock); | 892 | write_lock_bh(&xfrm_policy_lock); |
| 893 | |||
| 894 | err = xfrm_policy_flush_secctx_check(type, audit_info); | ||
| 895 | if (err) | ||
| 896 | goto out; | ||
| 897 | |||
| 835 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 898 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
| 836 | struct xfrm_policy *pol; | 899 | struct xfrm_policy *pol; |
| 837 | struct hlist_node *entry; | 900 | struct hlist_node *entry; |
| @@ -884,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
| 884 | xfrm_policy_count[dir] -= killed; | 947 | xfrm_policy_count[dir] -= killed; |
| 885 | } | 948 | } |
| 886 | atomic_inc(&flow_cache_genid); | 949 | atomic_inc(&flow_cache_genid); |
| 950 | out: | ||
| 887 | write_unlock_bh(&xfrm_policy_lock); | 951 | write_unlock_bh(&xfrm_policy_lock); |
| 952 | return err; | ||
| 888 | } | 953 | } |
| 889 | EXPORT_SYMBOL(xfrm_policy_flush); | 954 | EXPORT_SYMBOL(xfrm_policy_flush); |
| 890 | 955 | ||
| @@ -1386,8 +1451,8 @@ static int stale_bundle(struct dst_entry *dst); | |||
| 1386 | * At the moment we eat a raw IP route. Mostly to speed up lookups | 1451 | * At the moment we eat a raw IP route. Mostly to speed up lookups |
| 1387 | * on interfaces with disabled IPsec. | 1452 | * on interfaces with disabled IPsec. |
| 1388 | */ | 1453 | */ |
| 1389 | int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | 1454 | int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, |
| 1390 | struct sock *sk, int flags) | 1455 | struct sock *sk, int flags) |
| 1391 | { | 1456 | { |
| 1392 | struct xfrm_policy *policy; | 1457 | struct xfrm_policy *policy; |
| 1393 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; | 1458 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; |
| @@ -1505,6 +1570,13 @@ restart: | |||
| 1505 | 1570 | ||
| 1506 | if (unlikely(nx<0)) { | 1571 | if (unlikely(nx<0)) { |
| 1507 | err = nx; | 1572 | err = nx; |
| 1573 | if (err == -EAGAIN && sysctl_xfrm_larval_drop) { | ||
| 1574 | /* EREMOTE tells the caller to generate | ||
| 1575 | * a one-shot blackhole route. | ||
| 1576 | */ | ||
| 1577 | xfrm_pol_put(policy); | ||
| 1578 | return -EREMOTE; | ||
| 1579 | } | ||
| 1508 | if (err == -EAGAIN && flags) { | 1580 | if (err == -EAGAIN && flags) { |
| 1509 | DECLARE_WAITQUEUE(wait, current); | 1581 | DECLARE_WAITQUEUE(wait, current); |
| 1510 | 1582 | ||
| @@ -1594,6 +1666,21 @@ error: | |||
| 1594 | *dst_p = NULL; | 1666 | *dst_p = NULL; |
| 1595 | return err; | 1667 | return err; |
| 1596 | } | 1668 | } |
| 1669 | EXPORT_SYMBOL(__xfrm_lookup); | ||
| 1670 | |||
| 1671 | int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | ||
| 1672 | struct sock *sk, int flags) | ||
| 1673 | { | ||
| 1674 | int err = __xfrm_lookup(dst_p, fl, sk, flags); | ||
| 1675 | |||
| 1676 | if (err == -EREMOTE) { | ||
| 1677 | dst_release(*dst_p); | ||
| 1678 | *dst_p = NULL; | ||
| 1679 | err = -EAGAIN; | ||
| 1680 | } | ||
| 1681 | |||
| 1682 | return err; | ||
| 1683 | } | ||
| 1597 | EXPORT_SYMBOL(xfrm_lookup); | 1684 | EXPORT_SYMBOL(xfrm_lookup); |
| 1598 | 1685 | ||
| 1599 | static inline int | 1686 | static inline int |
| @@ -2554,4 +2641,3 @@ restore_state: | |||
| 2554 | } | 2641 | } |
| 2555 | EXPORT_SYMBOL(xfrm_migrate); | 2642 | EXPORT_SYMBOL(xfrm_migrate); |
| 2556 | #endif | 2643 | #endif |
| 2557 | |||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 9955ff4da0a2..85f3f43a6cca 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -21,18 +21,21 @@ | |||
| 21 | #include <linux/cache.h> | 21 | #include <linux/cache.h> |
| 22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
| 23 | #include <linux/audit.h> | 23 | #include <linux/audit.h> |
| 24 | #include <linux/cache.h> | ||
| 24 | 25 | ||
| 25 | #include "xfrm_hash.h" | 26 | #include "xfrm_hash.h" |
| 26 | 27 | ||
| 27 | struct sock *xfrm_nl; | 28 | struct sock *xfrm_nl; |
| 28 | EXPORT_SYMBOL(xfrm_nl); | 29 | EXPORT_SYMBOL(xfrm_nl); |
| 29 | 30 | ||
| 30 | u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME; | 31 | u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME; |
| 31 | EXPORT_SYMBOL(sysctl_xfrm_aevent_etime); | 32 | EXPORT_SYMBOL(sysctl_xfrm_aevent_etime); |
| 32 | 33 | ||
| 33 | u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE; | 34 | u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE; |
| 34 | EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth); | 35 | EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth); |
| 35 | 36 | ||
| 37 | u32 sysctl_xfrm_acq_expires __read_mostly = 30; | ||
| 38 | |||
| 36 | /* Each xfrm_state may be linked to two tables: | 39 | /* Each xfrm_state may be linked to two tables: |
| 37 | 40 | ||
| 38 | 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl) | 41 | 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl) |
| @@ -388,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
| 388 | } | 391 | } |
| 389 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
| 390 | 393 | ||
| 391 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | 394 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 395 | static inline int | ||
| 396 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
| 392 | { | 397 | { |
| 393 | int i; | 398 | int i, err = 0; |
| 394 | int err = 0; | 399 | |
| 400 | for (i = 0; i <= xfrm_state_hmask; i++) { | ||
| 401 | struct hlist_node *entry; | ||
| 402 | struct xfrm_state *x; | ||
| 403 | |||
| 404 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | ||
| 405 | if (xfrm_id_proto_match(x->id.proto, proto) && | ||
| 406 | (err = security_xfrm_state_delete(x)) != 0) { | ||
| 407 | xfrm_audit_log(audit_info->loginuid, | ||
| 408 | audit_info->secid, | ||
| 409 | AUDIT_MAC_IPSEC_DELSA, | ||
| 410 | 0, NULL, x); | ||
| 411 | |||
| 412 | return err; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | return err; | ||
| 418 | } | ||
| 419 | #else | ||
| 420 | static inline int | ||
| 421 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
| 422 | { | ||
| 423 | return 0; | ||
| 424 | } | ||
| 425 | #endif | ||
| 426 | |||
| 427 | int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | ||
| 428 | { | ||
| 429 | int i, err = 0; | ||
| 395 | 430 | ||
| 396 | spin_lock_bh(&xfrm_state_lock); | 431 | spin_lock_bh(&xfrm_state_lock); |
| 432 | err = xfrm_state_flush_secctx_check(proto, audit_info); | ||
| 433 | if (err) | ||
| 434 | goto out; | ||
| 435 | |||
| 397 | for (i = 0; i <= xfrm_state_hmask; i++) { | 436 | for (i = 0; i <= xfrm_state_hmask; i++) { |
| 398 | struct hlist_node *entry; | 437 | struct hlist_node *entry; |
| 399 | struct xfrm_state *x; | 438 | struct xfrm_state *x; |
| @@ -416,8 +455,12 @@ restart: | |||
| 416 | } | 455 | } |
| 417 | } | 456 | } |
| 418 | } | 457 | } |
| 458 | err = 0; | ||
| 459 | |||
| 460 | out: | ||
| 419 | spin_unlock_bh(&xfrm_state_lock); | 461 | spin_unlock_bh(&xfrm_state_lock); |
| 420 | wake_up(&km_waitq); | 462 | wake_up(&km_waitq); |
| 463 | return err; | ||
| 421 | } | 464 | } |
| 422 | EXPORT_SYMBOL(xfrm_state_flush); | 465 | EXPORT_SYMBOL(xfrm_state_flush); |
| 423 | 466 | ||
| @@ -622,8 +665,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
| 622 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family); | 665 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family); |
| 623 | hlist_add_head(&x->byspi, xfrm_state_byspi+h); | 666 | hlist_add_head(&x->byspi, xfrm_state_byspi+h); |
| 624 | } | 667 | } |
| 625 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 668 | x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; |
| 626 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 669 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
| 627 | add_timer(&x->timer); | 670 | add_timer(&x->timer); |
| 628 | xfrm_state_num++; | 671 | xfrm_state_num++; |
| 629 | xfrm_hash_grow_check(x->bydst.next != NULL); | 672 | xfrm_hash_grow_check(x->bydst.next != NULL); |
| @@ -772,9 +815,9 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
| 772 | x->props.family = family; | 815 | x->props.family = family; |
| 773 | x->props.mode = mode; | 816 | x->props.mode = mode; |
| 774 | x->props.reqid = reqid; | 817 | x->props.reqid = reqid; |
| 775 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 818 | x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; |
| 776 | xfrm_state_hold(x); | 819 | xfrm_state_hold(x); |
| 777 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 820 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
| 778 | add_timer(&x->timer); | 821 | add_timer(&x->timer); |
| 779 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); | 822 | hlist_add_head(&x->bydst, xfrm_state_bydst+h); |
| 780 | h = xfrm_src_hash(daddr, saddr, family); | 823 | h = xfrm_src_hash(daddr, saddr, family); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14c7e590c31..c06883bf620e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1418 | struct km_event c; | 1418 | struct km_event c; |
| 1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
| 1420 | struct xfrm_audit audit_info; | 1420 | struct xfrm_audit audit_info; |
| 1421 | int err; | ||
| 1421 | 1422 | ||
| 1422 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1423 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
| 1423 | audit_info.secid = NETLINK_CB(skb).sid; | 1424 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1424 | xfrm_state_flush(p->proto, &audit_info); | 1425 | err = xfrm_state_flush(p->proto, &audit_info); |
| 1426 | if (err) | ||
| 1427 | return err; | ||
| 1425 | c.data.proto = p->proto; | 1428 | c.data.proto = p->proto; |
| 1426 | c.event = nlh->nlmsg_type; | 1429 | c.event = nlh->nlmsg_type; |
| 1427 | c.seq = nlh->nlmsg_seq; | 1430 | c.seq = nlh->nlmsg_seq; |
| @@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1582 | 1585 | ||
| 1583 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1586 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
| 1584 | audit_info.secid = NETLINK_CB(skb).sid; | 1587 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1585 | xfrm_policy_flush(type, &audit_info); | 1588 | err = xfrm_policy_flush(type, &audit_info); |
| 1589 | if (err) | ||
| 1590 | return err; | ||
| 1586 | c.data.type = type; | 1591 | c.data.type = type; |
| 1587 | c.event = nlh->nlmsg_type; | 1592 | c.event = nlh->nlmsg_type; |
| 1588 | c.seq = nlh->nlmsg_seq; | 1593 | c.seq = nlh->nlmsg_seq; |
