diff options
Diffstat (limited to 'net')
32 files changed, 236 insertions, 117 deletions
diff --git a/net/Kconfig b/net/Kconfig index 2ddc9046868e..6dfe1c636a80 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | menuconfig NET | 5 | menuconfig NET |
| 6 | bool "Networking support" | 6 | bool "Networking support" |
| 7 | select NLATTR | 7 | select NLATTR |
| 8 | select GENERIC_NET_UTILS | ||
| 8 | ---help--- | 9 | ---help--- |
| 9 | Unless you really know what you are doing, you should say Y here. | 10 | Unless you really know what you are doing, you should say Y here. |
| 10 | The reason is that some programs need kernel networking support even | 11 | The reason is that some programs need kernel networking support even |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d817c932d634..ace5e55fe5a3 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt) | |||
| 341 | 341 | ||
| 342 | static void bredr_setup(struct hci_request *req) | 342 | static void bredr_setup(struct hci_request *req) |
| 343 | { | 343 | { |
| 344 | struct hci_cp_delete_stored_link_key cp; | ||
| 345 | __le16 param; | 344 | __le16 param; |
| 346 | __u8 flt_type; | 345 | __u8 flt_type; |
| 347 | 346 | ||
| @@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req) | |||
| 365 | param = __constant_cpu_to_le16(0x7d00); | 364 | param = __constant_cpu_to_le16(0x7d00); |
| 366 | hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | 365 | hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); |
| 367 | 366 | ||
| 368 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
| 369 | cp.delete_all = 0x01; | ||
| 370 | hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
| 371 | |||
| 372 | /* Read page scan parameters */ | 367 | /* Read page scan parameters */ |
| 373 | if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { | 368 | if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { |
| 374 | hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); | 369 | hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); |
| @@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
| 602 | struct hci_dev *hdev = req->hdev; | 597 | struct hci_dev *hdev = req->hdev; |
| 603 | u8 p; | 598 | u8 p; |
| 604 | 599 | ||
| 600 | /* Only send HCI_Delete_Stored_Link_Key if it is supported */ | ||
| 601 | if (hdev->commands[6] & 0x80) { | ||
| 602 | struct hci_cp_delete_stored_link_key cp; | ||
| 603 | |||
| 604 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
| 605 | cp.delete_all = 0x01; | ||
| 606 | hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, | ||
| 607 | sizeof(cp), &cp); | ||
| 608 | } | ||
| 609 | |||
| 605 | if (hdev->commands[5] & 0x10) | 610 | if (hdev->commands[5] & 0x10) |
| 606 | hci_setup_link_policy(req); | 611 | hci_setup_link_policy(req); |
| 607 | 612 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24bee07ee4ce..68843a28a7af 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -2852,6 +2852,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, | |||
| 2852 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", | 2852 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", |
| 2853 | conn, code, ident, dlen); | 2853 | conn, code, ident, dlen); |
| 2854 | 2854 | ||
| 2855 | if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) | ||
| 2856 | return NULL; | ||
| 2857 | |||
| 2855 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; | 2858 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; |
| 2856 | count = min_t(unsigned int, conn->mtu, len); | 2859 | count = min_t(unsigned int, conn->mtu, len); |
| 2857 | 2860 | ||
| @@ -4330,7 +4333,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, | |||
| 4330 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 4333 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
| 4331 | u16 type, result; | 4334 | u16 type, result; |
| 4332 | 4335 | ||
| 4333 | if (cmd_len != sizeof(*rsp)) | 4336 | if (cmd_len < sizeof(*rsp)) |
| 4334 | return -EPROTO; | 4337 | return -EPROTO; |
| 4335 | 4338 | ||
| 4336 | type = __le16_to_cpu(rsp->type); | 4339 | type = __le16_to_cpu(rsp->type); |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 81f2389f78eb..d6448e35e027 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -465,8 +465,9 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
| 465 | skb_set_transport_header(skb, skb->len); | 465 | skb_set_transport_header(skb, skb->len); |
| 466 | mldq = (struct mld_msg *) icmp6_hdr(skb); | 466 | mldq = (struct mld_msg *) icmp6_hdr(skb); |
| 467 | 467 | ||
| 468 | interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : | 468 | interval = ipv6_addr_any(group) ? |
| 469 | br->multicast_query_response_interval; | 469 | br->multicast_query_response_interval : |
| 470 | br->multicast_last_member_interval; | ||
| 470 | 471 | ||
| 471 | mldq->mld_type = ICMPV6_MGM_QUERY; | 472 | mldq->mld_type = ICMPV6_MGM_QUERY; |
| 472 | mldq->mld_code = 0; | 473 | mldq->mld_code = 0; |
diff --git a/net/core/dev.c b/net/core/dev.c index fc1e289397f5..faebb398fb46 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -792,6 +792,40 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex) | |||
| 792 | EXPORT_SYMBOL(dev_get_by_index); | 792 | EXPORT_SYMBOL(dev_get_by_index); |
| 793 | 793 | ||
| 794 | /** | 794 | /** |
| 795 | * netdev_get_name - get a netdevice name, knowing its ifindex. | ||
| 796 | * @net: network namespace | ||
| 797 | * @name: a pointer to the buffer where the name will be stored. | ||
| 798 | * @ifindex: the ifindex of the interface to get the name from. | ||
| 799 | * | ||
| 800 | * The use of raw_seqcount_begin() and cond_resched() before | ||
| 801 | * retrying is required as we want to give the writers a chance | ||
| 802 | * to complete when CONFIG_PREEMPT is not set. | ||
| 803 | */ | ||
| 804 | int netdev_get_name(struct net *net, char *name, int ifindex) | ||
| 805 | { | ||
| 806 | struct net_device *dev; | ||
| 807 | unsigned int seq; | ||
| 808 | |||
| 809 | retry: | ||
| 810 | seq = raw_seqcount_begin(&devnet_rename_seq); | ||
| 811 | rcu_read_lock(); | ||
| 812 | dev = dev_get_by_index_rcu(net, ifindex); | ||
| 813 | if (!dev) { | ||
| 814 | rcu_read_unlock(); | ||
| 815 | return -ENODEV; | ||
| 816 | } | ||
| 817 | |||
| 818 | strcpy(name, dev->name); | ||
| 819 | rcu_read_unlock(); | ||
| 820 | if (read_seqcount_retry(&devnet_rename_seq, seq)) { | ||
| 821 | cond_resched(); | ||
| 822 | goto retry; | ||
| 823 | } | ||
| 824 | |||
| 825 | return 0; | ||
| 826 | } | ||
| 827 | |||
| 828 | /** | ||
| 795 | * dev_getbyhwaddr_rcu - find a device by its hardware address | 829 | * dev_getbyhwaddr_rcu - find a device by its hardware address |
| 796 | * @net: the applicable net namespace | 830 | * @net: the applicable net namespace |
| 797 | * @type: media type of device | 831 | * @type: media type of device |
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 6cc0481faade..5b7d0e1d0664 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c | |||
| @@ -19,9 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | static int dev_ifname(struct net *net, struct ifreq __user *arg) | 20 | static int dev_ifname(struct net *net, struct ifreq __user *arg) |
| 21 | { | 21 | { |
| 22 | struct net_device *dev; | ||
| 23 | struct ifreq ifr; | 22 | struct ifreq ifr; |
| 24 | unsigned seq; | 23 | int error; |
| 25 | 24 | ||
| 26 | /* | 25 | /* |
| 27 | * Fetch the caller's info block. | 26 | * Fetch the caller's info block. |
| @@ -30,19 +29,9 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg) | |||
| 30 | if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) | 29 | if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) |
| 31 | return -EFAULT; | 30 | return -EFAULT; |
| 32 | 31 | ||
| 33 | retry: | 32 | error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex); |
| 34 | seq = read_seqcount_begin(&devnet_rename_seq); | 33 | if (error) |
| 35 | rcu_read_lock(); | 34 | return error; |
| 36 | dev = dev_get_by_index_rcu(net, ifr.ifr_ifindex); | ||
| 37 | if (!dev) { | ||
| 38 | rcu_read_unlock(); | ||
| 39 | return -ENODEV; | ||
| 40 | } | ||
| 41 | |||
| 42 | strcpy(ifr.ifr_name, dev->name); | ||
| 43 | rcu_read_unlock(); | ||
| 44 | if (read_seqcount_retry(&devnet_rename_seq, seq)) | ||
| 45 | goto retry; | ||
| 46 | 35 | ||
| 47 | if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) | 36 | if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) |
| 48 | return -EFAULT; | 37 | return -EFAULT; |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 22efdaa76ebf..ce91766eeca9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -60,10 +60,10 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
| 60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", | 60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", |
| 61 | [NETIF_F_HIGHDMA_BIT] = "highdma", | 61 | [NETIF_F_HIGHDMA_BIT] = "highdma", |
| 62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", | 62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", |
| 63 | [NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-ctag-hw-insert", | 63 | [NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-hw-insert", |
| 64 | 64 | ||
| 65 | [NETIF_F_HW_VLAN_CTAG_RX_BIT] = "rx-vlan-ctag-hw-parse", | 65 | [NETIF_F_HW_VLAN_CTAG_RX_BIT] = "rx-vlan-hw-parse", |
| 66 | [NETIF_F_HW_VLAN_CTAG_FILTER_BIT] = "rx-vlan-ctag-filter", | 66 | [NETIF_F_HW_VLAN_CTAG_FILTER_BIT] = "rx-vlan-filter", |
| 67 | [NETIF_F_HW_VLAN_STAG_TX_BIT] = "tx-vlan-stag-hw-insert", | 67 | [NETIF_F_HW_VLAN_STAG_TX_BIT] = "tx-vlan-stag-hw-insert", |
| 68 | [NETIF_F_HW_VLAN_STAG_RX_BIT] = "rx-vlan-stag-hw-parse", | 68 | [NETIF_F_HW_VLAN_STAG_RX_BIT] = "rx-vlan-stag-hw-parse", |
| 69 | [NETIF_F_HW_VLAN_STAG_FILTER_BIT] = "rx-vlan-stag-filter", | 69 | [NETIF_F_HW_VLAN_STAG_FILTER_BIT] = "rx-vlan-stag-filter", |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index cec074be8c43..35a9f0804b6f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 13 | 13 | ||
| 14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
| 15 | #include <linux/kernel.h> | ||
| 15 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
| 16 | #include <linux/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
| 17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cfd777bd6bd0..1c1738cc4538 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -483,15 +483,8 @@ EXPORT_SYMBOL(skb_add_rx_frag); | |||
| 483 | 483 | ||
| 484 | static void skb_drop_list(struct sk_buff **listp) | 484 | static void skb_drop_list(struct sk_buff **listp) |
| 485 | { | 485 | { |
| 486 | struct sk_buff *list = *listp; | 486 | kfree_skb_list(*listp); |
| 487 | |||
| 488 | *listp = NULL; | 487 | *listp = NULL; |
| 489 | |||
| 490 | do { | ||
| 491 | struct sk_buff *this = list; | ||
| 492 | list = list->next; | ||
| 493 | kfree_skb(this); | ||
| 494 | } while (list); | ||
| 495 | } | 488 | } |
| 496 | 489 | ||
| 497 | static inline void skb_drop_fraglist(struct sk_buff *skb) | 490 | static inline void skb_drop_fraglist(struct sk_buff *skb) |
| @@ -651,6 +644,17 @@ void kfree_skb(struct sk_buff *skb) | |||
| 651 | } | 644 | } |
| 652 | EXPORT_SYMBOL(kfree_skb); | 645 | EXPORT_SYMBOL(kfree_skb); |
| 653 | 646 | ||
| 647 | void kfree_skb_list(struct sk_buff *segs) | ||
| 648 | { | ||
| 649 | while (segs) { | ||
| 650 | struct sk_buff *next = segs->next; | ||
| 651 | |||
| 652 | kfree_skb(segs); | ||
| 653 | segs = next; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | EXPORT_SYMBOL(kfree_skb_list); | ||
| 657 | |||
| 654 | /** | 658 | /** |
| 655 | * skb_tx_error - report an sk_buff xmit error | 659 | * skb_tx_error - report an sk_buff xmit error |
| 656 | * @skb: buffer that triggered an error | 660 | * @skb: buffer that triggered an error |
diff --git a/net/core/sock.c b/net/core/sock.c index 88868a9d21da..d6d024cfaaaf 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -571,9 +571,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, | |||
| 571 | int ret = -ENOPROTOOPT; | 571 | int ret = -ENOPROTOOPT; |
| 572 | #ifdef CONFIG_NETDEVICES | 572 | #ifdef CONFIG_NETDEVICES |
| 573 | struct net *net = sock_net(sk); | 573 | struct net *net = sock_net(sk); |
| 574 | struct net_device *dev; | ||
| 575 | char devname[IFNAMSIZ]; | 574 | char devname[IFNAMSIZ]; |
| 576 | unsigned seq; | ||
| 577 | 575 | ||
| 578 | if (sk->sk_bound_dev_if == 0) { | 576 | if (sk->sk_bound_dev_if == 0) { |
| 579 | len = 0; | 577 | len = 0; |
| @@ -584,20 +582,9 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, | |||
| 584 | if (len < IFNAMSIZ) | 582 | if (len < IFNAMSIZ) |
| 585 | goto out; | 583 | goto out; |
| 586 | 584 | ||
| 587 | retry: | 585 | ret = netdev_get_name(net, devname, sk->sk_bound_dev_if); |
| 588 | seq = read_seqcount_begin(&devnet_rename_seq); | 586 | if (ret) |
| 589 | rcu_read_lock(); | ||
| 590 | dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); | ||
| 591 | ret = -ENODEV; | ||
| 592 | if (!dev) { | ||
| 593 | rcu_read_unlock(); | ||
| 594 | goto out; | 587 | goto out; |
| 595 | } | ||
| 596 | |||
| 597 | strcpy(devname, dev->name); | ||
| 598 | rcu_read_unlock(); | ||
| 599 | if (read_seqcount_retry(&devnet_rename_seq, seq)) | ||
| 600 | goto retry; | ||
| 601 | 588 | ||
| 602 | len = strlen(devname) + 1; | 589 | len = strlen(devname) + 1; |
| 603 | 590 | ||
diff --git a/net/core/utils.c b/net/core/utils.c index 3c7f5b51b979..aa88e23fc87a 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
| @@ -338,25 +338,3 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, | |||
| 338 | csum_unfold(*sum))); | 338 | csum_unfold(*sum))); |
| 339 | } | 339 | } |
| 340 | EXPORT_SYMBOL(inet_proto_csum_replace16); | 340 | EXPORT_SYMBOL(inet_proto_csum_replace16); |
| 341 | |||
| 342 | int mac_pton(const char *s, u8 *mac) | ||
| 343 | { | ||
| 344 | int i; | ||
| 345 | |||
| 346 | /* XX:XX:XX:XX:XX:XX */ | ||
| 347 | if (strlen(s) < 3 * ETH_ALEN - 1) | ||
| 348 | return 0; | ||
| 349 | |||
| 350 | /* Don't dirty result unless string is valid MAC. */ | ||
| 351 | for (i = 0; i < ETH_ALEN; i++) { | ||
| 352 | if (!isxdigit(s[i * 3]) || !isxdigit(s[i * 3 + 1])) | ||
| 353 | return 0; | ||
| 354 | if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':') | ||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | for (i = 0; i < ETH_ALEN; i++) { | ||
| 358 | mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]); | ||
| 359 | } | ||
| 360 | return 1; | ||
| 361 | } | ||
| 362 | EXPORT_SYMBOL(mac_pton); | ||
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index b2e805af9b87..7856d1651d05 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c | |||
| @@ -178,7 +178,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
| 178 | 178 | ||
| 179 | err = __skb_linearize(skb); | 179 | err = __skb_linearize(skb); |
| 180 | if (err) { | 180 | if (err) { |
| 181 | kfree_skb(segs); | 181 | kfree_skb_list(segs); |
| 182 | segs = ERR_PTR(err); | 182 | segs = ERR_PTR(err); |
| 183 | goto out; | 183 | goto out; |
| 184 | } | 184 | } |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index ff4b781b1056..32b0e978c8e0 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
| @@ -125,15 +125,16 @@ static void ulog_send(struct ulog_net *ulog, unsigned int nlgroupnum) | |||
| 125 | /* timer function to flush queue in flushtimeout time */ | 125 | /* timer function to flush queue in flushtimeout time */ |
| 126 | static void ulog_timer(unsigned long data) | 126 | static void ulog_timer(unsigned long data) |
| 127 | { | 127 | { |
| 128 | unsigned int groupnum = *((unsigned int *)data); | ||
| 128 | struct ulog_net *ulog = container_of((void *)data, | 129 | struct ulog_net *ulog = container_of((void *)data, |
| 129 | struct ulog_net, | 130 | struct ulog_net, |
| 130 | nlgroup[*(unsigned int *)data]); | 131 | nlgroup[groupnum]); |
| 131 | pr_debug("timer function called, calling ulog_send\n"); | 132 | pr_debug("timer function called, calling ulog_send\n"); |
| 132 | 133 | ||
| 133 | /* lock to protect against somebody modifying our structure | 134 | /* lock to protect against somebody modifying our structure |
| 134 | * from ipt_ulog_target at the same time */ | 135 | * from ipt_ulog_target at the same time */ |
| 135 | spin_lock_bh(&ulog->lock); | 136 | spin_lock_bh(&ulog->lock); |
| 136 | ulog_send(ulog, data); | 137 | ulog_send(ulog, groupnum); |
| 137 | spin_unlock_bh(&ulog->lock); | 138 | spin_unlock_bh(&ulog->lock); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| @@ -407,8 +408,11 @@ static int __net_init ulog_tg_net_init(struct net *net) | |||
| 407 | 408 | ||
| 408 | spin_lock_init(&ulog->lock); | 409 | spin_lock_init(&ulog->lock); |
| 409 | /* initialize ulog_buffers */ | 410 | /* initialize ulog_buffers */ |
| 410 | for (i = 0; i < ULOG_MAXNLGROUPS; i++) | 411 | for (i = 0; i < ULOG_MAXNLGROUPS; i++) { |
| 411 | setup_timer(&ulog->ulog_buffers[i].timer, ulog_timer, i); | 412 | ulog->nlgroup[i] = i; |
| 413 | setup_timer(&ulog->ulog_buffers[i].timer, ulog_timer, | ||
| 414 | (unsigned long)&ulog->nlgroup[i]); | ||
| 415 | } | ||
| 412 | 416 | ||
| 413 | ulog->nflognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg); | 417 | ulog->nflognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg); |
| 414 | if (!ulog->nflognl) | 418 | if (!ulog->nflognl) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 719652305a29..7999fc55c83b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1003,7 +1003,7 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, | |||
| 1003 | struct tcp_sock *tp = tcp_sk(sk); | 1003 | struct tcp_sock *tp = tcp_sk(sk); |
| 1004 | struct tcp_md5sig_info *md5sig; | 1004 | struct tcp_md5sig_info *md5sig; |
| 1005 | 1005 | ||
| 1006 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); | 1006 | key = tcp_md5_do_lookup(sk, addr, family); |
| 1007 | if (key) { | 1007 | if (key) { |
| 1008 | /* Pre-existing entry - just update that one. */ | 1008 | /* Pre-existing entry - just update that one. */ |
| 1009 | memcpy(key->key, newkey, newkeylen); | 1009 | memcpy(key->key, newkey, newkeylen); |
| @@ -1048,7 +1048,7 @@ int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family) | |||
| 1048 | struct tcp_md5sig_key *key; | 1048 | struct tcp_md5sig_key *key; |
| 1049 | struct tcp_md5sig_info *md5sig; | 1049 | struct tcp_md5sig_info *md5sig; |
| 1050 | 1050 | ||
| 1051 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); | 1051 | key = tcp_md5_do_lookup(sk, addr, family); |
| 1052 | if (!key) | 1052 | if (!key) |
| 1053 | return -ENOENT; | 1053 | return -ENOENT; |
| 1054 | hlist_del_rcu(&key->node); | 1054 | hlist_del_rcu(&key->node); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1bbf744c2cc3..4ab4c38958c6 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2655,6 +2655,9 @@ static void init_loopback(struct net_device *dev) | |||
| 2655 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | 2655 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) |
| 2656 | continue; | 2656 | continue; |
| 2657 | 2657 | ||
| 2658 | if (sp_ifa->rt) | ||
| 2659 | continue; | ||
| 2660 | |||
| 2658 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2661 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); |
| 2659 | 2662 | ||
| 2660 | /* Failure cases are ignored */ | 2663 | /* Failure cases are ignored */ |
| @@ -4303,6 +4306,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4303 | struct inet6_ifaddr *ifp; | 4306 | struct inet6_ifaddr *ifp; |
| 4304 | struct net_device *dev = idev->dev; | 4307 | struct net_device *dev = idev->dev; |
| 4305 | bool update_rs = false; | 4308 | bool update_rs = false; |
| 4309 | struct in6_addr ll_addr; | ||
| 4306 | 4310 | ||
| 4307 | if (token == NULL) | 4311 | if (token == NULL) |
| 4308 | return -EINVAL; | 4312 | return -EINVAL; |
| @@ -4322,11 +4326,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4322 | 4326 | ||
| 4323 | write_unlock_bh(&idev->lock); | 4327 | write_unlock_bh(&idev->lock); |
| 4324 | 4328 | ||
| 4325 | if (!idev->dead && (idev->if_flags & IF_READY)) { | 4329 | if (!idev->dead && (idev->if_flags & IF_READY) && |
| 4326 | struct in6_addr ll_addr; | 4330 | !ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | |
| 4327 | 4331 | IFA_F_OPTIMISTIC)) { | |
| 4328 | ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | | ||
| 4329 | IFA_F_OPTIMISTIC); | ||
| 4330 | 4332 | ||
| 4331 | /* If we're not ready, then normal ifup will take care | 4333 | /* If we're not ready, then normal ifup will take care |
| 4332 | * of this. Otherwise, we need to request our rs here. | 4334 | * of this. Otherwise, we need to request our rs here. |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index dae1949019d7..d5d20cde8d92 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -381,9 +381,8 @@ int ip6_forward(struct sk_buff *skb) | |||
| 381 | * cannot be fragmented, because there is no warranty | 381 | * cannot be fragmented, because there is no warranty |
| 382 | * that different fragments will go along one path. --ANK | 382 | * that different fragments will go along one path. --ANK |
| 383 | */ | 383 | */ |
| 384 | if (opt->ra) { | 384 | if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) { |
| 385 | u8 *ptr = skb_network_header(skb) + opt->ra; | 385 | if (ip6_call_ra_chain(skb, ntohs(opt->ra))) |
| 386 | if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3])) | ||
| 387 | return 0; | 386 | return 0; |
| 388 | } | 387 | } |
| 389 | 388 | ||
| @@ -822,11 +821,17 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, | |||
| 822 | const struct flowi6 *fl6) | 821 | const struct flowi6 *fl6) |
| 823 | { | 822 | { |
| 824 | struct ipv6_pinfo *np = inet6_sk(sk); | 823 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 825 | struct rt6_info *rt = (struct rt6_info *)dst; | 824 | struct rt6_info *rt; |
| 826 | 825 | ||
| 827 | if (!dst) | 826 | if (!dst) |
| 828 | goto out; | 827 | goto out; |
| 829 | 828 | ||
| 829 | if (dst->ops->family != AF_INET6) { | ||
| 830 | dst_release(dst); | ||
| 831 | return NULL; | ||
| 832 | } | ||
| 833 | |||
| 834 | rt = (struct rt6_info *)dst; | ||
| 830 | /* Yes, checking route validity in not connected | 835 | /* Yes, checking route validity in not connected |
| 831 | * case is not very simple. Take into account, | 836 | * case is not very simple. Take into account, |
| 832 | * that we do not support routing by source, TOS, | 837 | * that we do not support routing by source, TOS, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2712ab22a174..ca4ffcc287f1 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1493,7 +1493,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
| 1493 | */ | 1493 | */ |
| 1494 | 1494 | ||
| 1495 | if (ha) | 1495 | if (ha) |
| 1496 | ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR, ha); | 1496 | ndisc_fill_addr_option(buff, ND_OPT_TARGET_LL_ADDR, ha); |
| 1497 | 1497 | ||
| 1498 | /* | 1498 | /* |
| 1499 | * build redirect option and copy skb over to the new packet. | 1499 | * build redirect option and copy skb over to the new packet. |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 97bcf2bae857..c9b6a6e6a1e8 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -204,7 +204,7 @@ static unsigned int __ipv6_conntrack_in(struct net *net, | |||
| 204 | if (ct != NULL && !nf_ct_is_untracked(ct)) { | 204 | if (ct != NULL && !nf_ct_is_untracked(ct)) { |
| 205 | help = nfct_help(ct); | 205 | help = nfct_help(ct); |
| 206 | if ((help && help->helper) || !nf_ct_is_confirmed(ct)) { | 206 | if ((help && help->helper) || !nf_ct_is_confirmed(ct)) { |
| 207 | nf_conntrack_get_reasm(skb); | 207 | nf_conntrack_get_reasm(reasm); |
| 208 | NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm, | 208 | NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm, |
| 209 | (struct net_device *)in, | 209 | (struct net_device *)in, |
| 210 | (struct net_device *)out, | 210 | (struct net_device *)out, |
diff --git a/net/key/af_key.c b/net/key/af_key.c index c5fbd7589681..9da862070dd8 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1710,6 +1710,7 @@ static int key_notify_sa_flush(const struct km_event *c) | |||
| 1710 | hdr->sadb_msg_version = PF_KEY_V2; | 1710 | hdr->sadb_msg_version = PF_KEY_V2; |
| 1711 | hdr->sadb_msg_errno = (uint8_t) 0; | 1711 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 1712 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 1712 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 1713 | hdr->sadb_msg_reserved = 0; | ||
| 1713 | 1714 | ||
| 1714 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); | 1715 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 1715 | 1716 | ||
| @@ -2699,6 +2700,7 @@ static int key_notify_policy_flush(const struct km_event *c) | |||
| 2699 | hdr->sadb_msg_errno = (uint8_t) 0; | 2700 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 2700 | hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; | 2701 | hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; |
| 2701 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 2702 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 2703 | hdr->sadb_msg_reserved = 0; | ||
| 2702 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); | 2704 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 2703 | return 0; | 2705 | return 0; |
| 2704 | 2706 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1a89c80e6407..4fdb306e42e0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1057,6 +1057,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
| 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
| 1059 | 1059 | ||
| 1060 | if (sdata->wdev.cac_started) { | ||
| 1061 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | ||
| 1062 | cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, | ||
| 1063 | GFP_KERNEL); | ||
| 1064 | } | ||
| 1065 | |||
| 1060 | drv_stop_ap(sdata->local, sdata); | 1066 | drv_stop_ap(sdata->local, sdata); |
| 1061 | 1067 | ||
| 1062 | /* free all potentially still buffered bcast frames */ | 1068 | /* free all potentially still buffered bcast frames */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 44be28cfc6c4..9ca8e3278cc0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1497,10 +1497,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | |||
| 1497 | ieee80211_tx_skb_tid(sdata, skb, 7); | 1497 | ieee80211_tx_skb_tid(sdata, skb, 7); |
| 1498 | } | 1498 | } |
| 1499 | 1499 | ||
| 1500 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 1500 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
| 1501 | struct ieee802_11_elems *elems, | 1501 | struct ieee802_11_elems *elems, |
| 1502 | u64 filter, u32 crc); | 1502 | u64 filter, u32 crc); |
| 1503 | static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | 1503 | static inline void ieee802_11_parse_elems(const u8 *start, size_t len, |
| 1504 | bool action, | ||
| 1504 | struct ieee802_11_elems *elems) | 1505 | struct ieee802_11_elems *elems) |
| 1505 | { | 1506 | { |
| 1506 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); | 1507 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a8c2130c8ba4..741448b30825 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -2522,8 +2522,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2522 | u16 capab_info, aid; | 2522 | u16 capab_info, aid; |
| 2523 | struct ieee802_11_elems elems; | 2523 | struct ieee802_11_elems elems; |
| 2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
| 2525 | const struct cfg80211_bss_ies *bss_ies = NULL; | ||
| 2526 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; | ||
| 2525 | u32 changed = 0; | 2527 | u32 changed = 0; |
| 2526 | int err; | 2528 | int err; |
| 2529 | bool ret; | ||
| 2527 | 2530 | ||
| 2528 | /* AssocResp and ReassocResp have identical structure */ | 2531 | /* AssocResp and ReassocResp have identical structure */ |
| 2529 | 2532 | ||
| @@ -2555,21 +2558,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2555 | ifmgd->aid = aid; | 2558 | ifmgd->aid = aid; |
| 2556 | 2559 | ||
| 2557 | /* | 2560 | /* |
| 2561 | * Some APs are erroneously not including some information in their | ||
| 2562 | * (re)association response frames. Try to recover by using the data | ||
| 2563 | * from the beacon or probe response. This seems to afflict mobile | ||
| 2564 | * 2G/3G/4G wifi routers, reported models include the "Onda PN51T", | ||
| 2565 | * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device. | ||
| 2566 | */ | ||
| 2567 | if ((assoc_data->wmm && !elems.wmm_param) || | ||
| 2568 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | ||
| 2569 | (!elems.ht_cap_elem || !elems.ht_operation)) || | ||
| 2570 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | ||
| 2571 | (!elems.vht_cap_elem || !elems.vht_operation))) { | ||
| 2572 | const struct cfg80211_bss_ies *ies; | ||
| 2573 | struct ieee802_11_elems bss_elems; | ||
| 2574 | |||
| 2575 | rcu_read_lock(); | ||
| 2576 | ies = rcu_dereference(cbss->ies); | ||
| 2577 | if (ies) | ||
| 2578 | bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, | ||
| 2579 | GFP_ATOMIC); | ||
| 2580 | rcu_read_unlock(); | ||
| 2581 | if (!bss_ies) | ||
| 2582 | return false; | ||
| 2583 | |||
| 2584 | ieee802_11_parse_elems(bss_ies->data, bss_ies->len, | ||
| 2585 | false, &bss_elems); | ||
| 2586 | if (assoc_data->wmm && | ||
| 2587 | !elems.wmm_param && bss_elems.wmm_param) { | ||
| 2588 | elems.wmm_param = bss_elems.wmm_param; | ||
| 2589 | sdata_info(sdata, | ||
| 2590 | "AP bug: WMM param missing from AssocResp\n"); | ||
| 2591 | } | ||
| 2592 | |||
| 2593 | /* | ||
| 2594 | * Also check if we requested HT/VHT, otherwise the AP doesn't | ||
| 2595 | * have to include the IEs in the (re)association response. | ||
| 2596 | */ | ||
| 2597 | if (!elems.ht_cap_elem && bss_elems.ht_cap_elem && | ||
| 2598 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
| 2599 | elems.ht_cap_elem = bss_elems.ht_cap_elem; | ||
| 2600 | sdata_info(sdata, | ||
| 2601 | "AP bug: HT capability missing from AssocResp\n"); | ||
| 2602 | } | ||
| 2603 | if (!elems.ht_operation && bss_elems.ht_operation && | ||
| 2604 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
| 2605 | elems.ht_operation = bss_elems.ht_operation; | ||
| 2606 | sdata_info(sdata, | ||
| 2607 | "AP bug: HT operation missing from AssocResp\n"); | ||
| 2608 | } | ||
| 2609 | if (!elems.vht_cap_elem && bss_elems.vht_cap_elem && | ||
| 2610 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
| 2611 | elems.vht_cap_elem = bss_elems.vht_cap_elem; | ||
| 2612 | sdata_info(sdata, | ||
| 2613 | "AP bug: VHT capa missing from AssocResp\n"); | ||
| 2614 | } | ||
| 2615 | if (!elems.vht_operation && bss_elems.vht_operation && | ||
| 2616 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
| 2617 | elems.vht_operation = bss_elems.vht_operation; | ||
| 2618 | sdata_info(sdata, | ||
| 2619 | "AP bug: VHT operation missing from AssocResp\n"); | ||
| 2620 | } | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | /* | ||
| 2558 | * We previously checked these in the beacon/probe response, so | 2624 | * We previously checked these in the beacon/probe response, so |
| 2559 | * they should be present here. This is just a safety net. | 2625 | * they should be present here. This is just a safety net. |
| 2560 | */ | 2626 | */ |
| 2561 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | 2627 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && |
| 2562 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { | 2628 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { |
| 2563 | sdata_info(sdata, | 2629 | sdata_info(sdata, |
| 2564 | "HT AP is missing WMM params or HT capability/operation in AssocResp\n"); | 2630 | "HT AP is missing WMM params or HT capability/operation\n"); |
| 2565 | return false; | 2631 | ret = false; |
| 2632 | goto out; | ||
| 2566 | } | 2633 | } |
| 2567 | 2634 | ||
| 2568 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | 2635 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && |
| 2569 | (!elems.vht_cap_elem || !elems.vht_operation)) { | 2636 | (!elems.vht_cap_elem || !elems.vht_operation)) { |
| 2570 | sdata_info(sdata, | 2637 | sdata_info(sdata, |
| 2571 | "VHT AP is missing VHT capability/operation in AssocResp\n"); | 2638 | "VHT AP is missing VHT capability/operation\n"); |
| 2572 | return false; | 2639 | ret = false; |
| 2640 | goto out; | ||
| 2573 | } | 2641 | } |
| 2574 | 2642 | ||
| 2575 | mutex_lock(&sdata->local->sta_mtx); | 2643 | mutex_lock(&sdata->local->sta_mtx); |
| @@ -2580,7 +2648,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2580 | sta = sta_info_get(sdata, cbss->bssid); | 2648 | sta = sta_info_get(sdata, cbss->bssid); |
| 2581 | if (WARN_ON(!sta)) { | 2649 | if (WARN_ON(!sta)) { |
| 2582 | mutex_unlock(&sdata->local->sta_mtx); | 2650 | mutex_unlock(&sdata->local->sta_mtx); |
| 2583 | return false; | 2651 | ret = false; |
| 2652 | goto out; | ||
| 2584 | } | 2653 | } |
| 2585 | 2654 | ||
| 2586 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; | 2655 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; |
| @@ -2633,7 +2702,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2633 | sta->sta.addr); | 2702 | sta->sta.addr); |
| 2634 | WARN_ON(__sta_info_destroy(sta)); | 2703 | WARN_ON(__sta_info_destroy(sta)); |
| 2635 | mutex_unlock(&sdata->local->sta_mtx); | 2704 | mutex_unlock(&sdata->local->sta_mtx); |
| 2636 | return false; | 2705 | ret = false; |
| 2706 | goto out; | ||
| 2637 | } | 2707 | } |
| 2638 | 2708 | ||
| 2639 | mutex_unlock(&sdata->local->sta_mtx); | 2709 | mutex_unlock(&sdata->local->sta_mtx); |
| @@ -2673,7 +2743,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2673 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 2743 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
| 2674 | ieee80211_sta_reset_beacon_monitor(sdata); | 2744 | ieee80211_sta_reset_beacon_monitor(sdata); |
| 2675 | 2745 | ||
| 2676 | return true; | 2746 | ret = true; |
| 2747 | out: | ||
| 2748 | kfree(bss_ies); | ||
| 2749 | return ret; | ||
| 2677 | } | 2750 | } |
| 2678 | 2751 | ||
| 2679 | static enum rx_mgmt_action __must_check | 2752 | static enum rx_mgmt_action __must_check |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index d3f414fe67e0..a02bef35b134 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
| @@ -615,7 +615,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata, | |||
| 615 | if (rates[i].idx < 0) | 615 | if (rates[i].idx < 0) |
| 616 | break; | 616 | break; |
| 617 | 617 | ||
| 618 | rate_idx_match_mask(&rates[i], sband, mask, chan_width, | 618 | rate_idx_match_mask(&rates[i], sband, chan_width, mask, |
| 619 | mcs_mask); | 619 | mcs_mask); |
| 620 | } | 620 | } |
| 621 | } | 621 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 27e07150eb46..72e6292955bb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -661,12 +661,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
| 661 | } | 661 | } |
| 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
| 663 | 663 | ||
| 664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 664 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
| 665 | struct ieee802_11_elems *elems, | 665 | struct ieee802_11_elems *elems, |
| 666 | u64 filter, u32 crc) | 666 | u64 filter, u32 crc) |
| 667 | { | 667 | { |
| 668 | size_t left = len; | 668 | size_t left = len; |
| 669 | u8 *pos = start; | 669 | const u8 *pos = start; |
| 670 | bool calc_crc = filter != 0; | 670 | bool calc_crc = filter != 0; |
| 671 | DECLARE_BITMAP(seen_elems, 256); | 671 | DECLARE_BITMAP(seen_elems, 256); |
| 672 | const u8 *ie; | 672 | const u8 *ie; |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 05565d2b3a61..23b8eb53a569 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -1442,7 +1442,8 @@ ignore_ipip: | |||
| 1442 | 1442 | ||
| 1443 | /* do the statistics and put it back */ | 1443 | /* do the statistics and put it back */ |
| 1444 | ip_vs_in_stats(cp, skb); | 1444 | ip_vs_in_stats(cp, skb); |
| 1445 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) | 1445 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol || |
| 1446 | IPPROTO_SCTP == cih->protocol) | ||
| 1446 | offset += 2 * sizeof(__u16); | 1447 | offset += 2 * sizeof(__u16); |
| 1447 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph); | 1448 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph); |
| 1448 | 1449 | ||
diff --git a/net/netfilter/nf_conntrack_labels.c b/net/netfilter/nf_conntrack_labels.c index 8fe2e99428b7..355d2ef08094 100644 --- a/net/netfilter/nf_conntrack_labels.c +++ b/net/netfilter/nf_conntrack_labels.c | |||
| @@ -45,7 +45,7 @@ int nf_connlabel_set(struct nf_conn *ct, u16 bit) | |||
| 45 | if (test_bit(bit, labels->bits)) | 45 | if (test_bit(bit, labels->bits)) |
| 46 | return 0; | 46 | return 0; |
| 47 | 47 | ||
| 48 | if (test_and_set_bit(bit, labels->bits)) | 48 | if (!test_and_set_bit(bit, labels->bits)) |
| 49 | nf_conntrack_event_cache(IPCT_LABEL, ct); | 49 | nf_conntrack_event_cache(IPCT_LABEL, ct); |
| 50 | 50 | ||
| 51 | return 0; | 51 | return 0; |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6d0f8a17c5b7..ecf065f94032 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1825,6 +1825,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1825 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | | 1825 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | |
| 1826 | (1 << IPCT_ASSURED) | | 1826 | (1 << IPCT_ASSURED) | |
| 1827 | (1 << IPCT_HELPER) | | 1827 | (1 << IPCT_HELPER) | |
| 1828 | (1 << IPCT_LABEL) | | ||
| 1828 | (1 << IPCT_PROTOINFO) | | 1829 | (1 << IPCT_PROTOINFO) | |
| 1829 | (1 << IPCT_NATSEQADJ) | | 1830 | (1 << IPCT_NATSEQADJ) | |
| 1830 | (1 << IPCT_MARK), | 1831 | (1 << IPCT_MARK), |
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index 96ccdf78a29f..dac11f73868e 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c | |||
| @@ -230,9 +230,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, | |||
| 230 | &ct->tuplehash[!dir].tuple.src.u3, | 230 | &ct->tuplehash[!dir].tuple.src.u3, |
| 231 | false); | 231 | false); |
| 232 | if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, | 232 | if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, |
| 233 | poff, plen, buffer, buflen)) | 233 | poff, plen, buffer, buflen)) { |
| 234 | nf_ct_helper_log(skb, ct, "cannot mangle received"); | 234 | nf_ct_helper_log(skb, ct, "cannot mangle received"); |
| 235 | return NF_DROP; | 235 | return NF_DROP; |
| 236 | } | ||
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /* The rport= parameter (RFC 3581) contains the port number | 239 | /* The rport= parameter (RFC 3581) contains the port number |
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index afaebc766933..7011c71646f0 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
| @@ -45,17 +45,22 @@ optlen(const u_int8_t *opt, unsigned int offset) | |||
| 45 | 45 | ||
| 46 | static int | 46 | static int |
| 47 | tcpmss_mangle_packet(struct sk_buff *skb, | 47 | tcpmss_mangle_packet(struct sk_buff *skb, |
| 48 | const struct xt_tcpmss_info *info, | 48 | const struct xt_action_param *par, |
| 49 | unsigned int in_mtu, | 49 | unsigned int in_mtu, |
| 50 | unsigned int tcphoff, | 50 | unsigned int tcphoff, |
| 51 | unsigned int minlen) | 51 | unsigned int minlen) |
| 52 | { | 52 | { |
| 53 | const struct xt_tcpmss_info *info = par->targinfo; | ||
| 53 | struct tcphdr *tcph; | 54 | struct tcphdr *tcph; |
| 54 | unsigned int tcplen, i; | 55 | unsigned int tcplen, i; |
| 55 | __be16 oldval; | 56 | __be16 oldval; |
| 56 | u16 newmss; | 57 | u16 newmss; |
| 57 | u8 *opt; | 58 | u8 *opt; |
| 58 | 59 | ||
| 60 | /* This is a fragment, no TCP header is available */ | ||
| 61 | if (par->fragoff != 0) | ||
| 62 | return XT_CONTINUE; | ||
| 63 | |||
| 59 | if (!skb_make_writable(skb, skb->len)) | 64 | if (!skb_make_writable(skb, skb->len)) |
| 60 | return -1; | 65 | return -1; |
| 61 | 66 | ||
| @@ -125,11 +130,17 @@ tcpmss_mangle_packet(struct sk_buff *skb, | |||
| 125 | 130 | ||
| 126 | skb_put(skb, TCPOLEN_MSS); | 131 | skb_put(skb, TCPOLEN_MSS); |
| 127 | 132 | ||
| 128 | /* RFC 879 states that the default MSS is 536 without specific | 133 | /* |
| 129 | * knowledge that the destination host is prepared to accept larger. | 134 | * IPv4: RFC 1122 states "If an MSS option is not received at |
| 130 | * Since no MSS was provided, we MUST NOT set a value > 536. | 135 | * connection setup, TCP MUST assume a default send MSS of 536". |
| 136 | * IPv6: RFC 2460 states IPv6 has a minimum MTU of 1280 and a minimum | ||
| 137 | * length IPv6 header of 60, ergo the default MSS value is 1220 | ||
| 138 | * Since no MSS was provided, we must use the default values | ||
| 131 | */ | 139 | */ |
| 132 | newmss = min(newmss, (u16)536); | 140 | if (par->family == NFPROTO_IPV4) |
| 141 | newmss = min(newmss, (u16)536); | ||
| 142 | else | ||
| 143 | newmss = min(newmss, (u16)1220); | ||
| 133 | 144 | ||
| 134 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); | 145 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); |
| 135 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); | 146 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); |
| @@ -188,7 +199,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 188 | __be16 newlen; | 199 | __be16 newlen; |
| 189 | int ret; | 200 | int ret; |
| 190 | 201 | ||
| 191 | ret = tcpmss_mangle_packet(skb, par->targinfo, | 202 | ret = tcpmss_mangle_packet(skb, par, |
| 192 | tcpmss_reverse_mtu(skb, PF_INET), | 203 | tcpmss_reverse_mtu(skb, PF_INET), |
| 193 | iph->ihl * 4, | 204 | iph->ihl * 4, |
| 194 | sizeof(*iph) + sizeof(struct tcphdr)); | 205 | sizeof(*iph) + sizeof(struct tcphdr)); |
| @@ -217,7 +228,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 217 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off); | 228 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off); |
| 218 | if (tcphoff < 0) | 229 | if (tcphoff < 0) |
| 219 | return NF_DROP; | 230 | return NF_DROP; |
| 220 | ret = tcpmss_mangle_packet(skb, par->targinfo, | 231 | ret = tcpmss_mangle_packet(skb, par, |
| 221 | tcpmss_reverse_mtu(skb, PF_INET6), | 232 | tcpmss_reverse_mtu(skb, PF_INET6), |
| 222 | tcphoff, | 233 | tcphoff, |
| 223 | sizeof(*ipv6h) + sizeof(struct tcphdr)); | 234 | sizeof(*ipv6h) + sizeof(struct tcphdr)); |
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index 1eb1a44bfd3d..b68fa191710f 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c | |||
| @@ -48,11 +48,13 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
| 48 | return NF_DROP; | 48 | return NF_DROP; |
| 49 | 49 | ||
| 50 | len = skb->len - tcphoff; | 50 | len = skb->len - tcphoff; |
| 51 | if (len < (int)sizeof(struct tcphdr) || | 51 | if (len < (int)sizeof(struct tcphdr)) |
| 52 | tcp_hdr(skb)->doff * 4 > len) | ||
| 53 | return NF_DROP; | 52 | return NF_DROP; |
| 54 | 53 | ||
| 55 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); | 54 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); |
| 55 | if (tcph->doff * 4 > len) | ||
| 56 | return NF_DROP; | ||
| 57 | |||
| 56 | opt = (u_int8_t *)tcph; | 58 | opt = (u_int8_t *)tcph; |
| 57 | 59 | ||
| 58 | /* | 60 | /* |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 29b4ba93ab3c..b05ace4c5f12 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -1330,7 +1330,7 @@ static int wait_for_gss_proxy(struct net *net, struct file *file) | |||
| 1330 | static ssize_t write_gssp(struct file *file, const char __user *buf, | 1330 | static ssize_t write_gssp(struct file *file, const char __user *buf, |
| 1331 | size_t count, loff_t *ppos) | 1331 | size_t count, loff_t *ppos) |
| 1332 | { | 1332 | { |
| 1333 | struct net *net = PDE_DATA(file->f_path.dentry->d_inode); | 1333 | struct net *net = PDE_DATA(file_inode(file)); |
| 1334 | char tbuf[20]; | 1334 | char tbuf[20]; |
| 1335 | unsigned long i; | 1335 | unsigned long i; |
| 1336 | int res; | 1336 | int res; |
| @@ -1358,7 +1358,7 @@ static ssize_t write_gssp(struct file *file, const char __user *buf, | |||
| 1358 | static ssize_t read_gssp(struct file *file, char __user *buf, | 1358 | static ssize_t read_gssp(struct file *file, char __user *buf, |
| 1359 | size_t count, loff_t *ppos) | 1359 | size_t count, loff_t *ppos) |
| 1360 | { | 1360 | { |
| 1361 | struct net *net = PDE_DATA(file->f_path.dentry->d_inode); | 1361 | struct net *net = PDE_DATA(file_inode(file)); |
| 1362 | unsigned long p = *ppos; | 1362 | unsigned long p = *ppos; |
| 1363 | char tbuf[10]; | 1363 | char tbuf[10]; |
| 1364 | size_t len; | 1364 | size_t len; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d5aed3bb3945..b14b7e3cb6e6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -1564,12 +1564,17 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1564 | struct cfg80211_registered_device *dev; | 1564 | struct cfg80211_registered_device *dev; |
| 1565 | s64 filter_wiphy = -1; | 1565 | s64 filter_wiphy = -1; |
| 1566 | bool split = false; | 1566 | bool split = false; |
| 1567 | struct nlattr **tb = nl80211_fam.attrbuf; | 1567 | struct nlattr **tb; |
| 1568 | int res; | 1568 | int res; |
| 1569 | 1569 | ||
| 1570 | /* will be zeroed in nlmsg_parse() */ | ||
| 1571 | tb = kmalloc(sizeof(*tb) * (NL80211_ATTR_MAX + 1), GFP_KERNEL); | ||
| 1572 | if (!tb) | ||
| 1573 | return -ENOMEM; | ||
| 1574 | |||
| 1570 | mutex_lock(&cfg80211_mutex); | 1575 | mutex_lock(&cfg80211_mutex); |
| 1571 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 1576 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
| 1572 | tb, nl80211_fam.maxattr, nl80211_policy); | 1577 | tb, NL80211_ATTR_MAX, nl80211_policy); |
| 1573 | if (res == 0) { | 1578 | if (res == 0) { |
| 1574 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; | 1579 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; |
| 1575 | if (tb[NL80211_ATTR_WIPHY]) | 1580 | if (tb[NL80211_ATTR_WIPHY]) |
| @@ -1583,6 +1588,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1583 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | 1588 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); |
| 1584 | if (!netdev) { | 1589 | if (!netdev) { |
| 1585 | mutex_unlock(&cfg80211_mutex); | 1590 | mutex_unlock(&cfg80211_mutex); |
| 1591 | kfree(tb); | ||
| 1586 | return -ENODEV; | 1592 | return -ENODEV; |
| 1587 | } | 1593 | } |
| 1588 | if (netdev->ieee80211_ptr) { | 1594 | if (netdev->ieee80211_ptr) { |
| @@ -1593,6 +1599,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1593 | dev_put(netdev); | 1599 | dev_put(netdev); |
| 1594 | } | 1600 | } |
| 1595 | } | 1601 | } |
| 1602 | kfree(tb); | ||
| 1596 | 1603 | ||
| 1597 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1604 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { |
| 1598 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1605 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) |
