diff options
Diffstat (limited to 'net')
43 files changed, 350 insertions, 145 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e8..ce0684a1fc83 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
| @@ -325,6 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
| 325 | 325 | ||
| 326 | soft_iface->last_rx = jiffies; | 326 | soft_iface->last_rx = jiffies; |
| 327 | 327 | ||
| 328 | /* Let the bridge loop avoidance check the packet. If will | ||
| 329 | * not handle it, we can safely push it up. | ||
| 330 | */ | ||
| 331 | if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) | ||
| 332 | goto out; | ||
| 333 | |||
| 328 | if (orig_node) | 334 | if (orig_node) |
| 329 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, | 335 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, |
| 330 | ethhdr->h_source); | 336 | ethhdr->h_source); |
| @@ -332,12 +338,6 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
| 332 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) | 338 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) |
| 333 | goto dropped; | 339 | goto dropped; |
| 334 | 340 | ||
| 335 | /* Let the bridge loop avoidance check the packet. If will | ||
| 336 | * not handle it, we can safely push it up. | ||
| 337 | */ | ||
| 338 | if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) | ||
| 339 | goto out; | ||
| 340 | |||
| 341 | netif_rx(skb); | 341 | netif_rx(skb); |
| 342 | goto out; | 342 | goto out; |
| 343 | 343 | ||
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd371b2f..baae71585804 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
| @@ -769,6 +769,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
| 769 | */ | 769 | */ |
| 770 | tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; | 770 | tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; |
| 771 | 771 | ||
| 772 | /* the change can carry possible "attribute" flags like the | ||
| 773 | * TT_CLIENT_WIFI, therefore they have to be copied in the | ||
| 774 | * client entry | ||
| 775 | */ | ||
| 776 | tt_global_entry->common.flags |= flags; | ||
| 777 | |||
| 772 | /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only | 778 | /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only |
| 773 | * one originator left in the list and we previously received a | 779 | * one originator left in the list and we previously received a |
| 774 | * delete + roaming change for this originator. | 780 | * delete + roaming change for this originator. |
| @@ -1496,7 +1502,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, | |||
| 1496 | 1502 | ||
| 1497 | memcpy(tt_change->addr, tt_common_entry->addr, | 1503 | memcpy(tt_change->addr, tt_common_entry->addr, |
| 1498 | ETH_ALEN); | 1504 | ETH_ALEN); |
| 1499 | tt_change->flags = BATADV_NO_FLAGS; | 1505 | tt_change->flags = tt_common_entry->flags; |
| 1500 | 1506 | ||
| 1501 | tt_count++; | 1507 | tt_count++; |
| 1502 | tt_change++; | 1508 | tt_change++; |
| @@ -2450,6 +2456,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, | |||
| 2450 | { | 2456 | { |
| 2451 | bool ret = false; | 2457 | bool ret = false; |
| 2452 | 2458 | ||
| 2459 | /* if the originator is a backbone node (meaning it belongs to the same | ||
| 2460 | * LAN of this node) the temporary client must not be added because to | ||
| 2461 | * reach such destination the node must use the LAN instead of the mesh | ||
| 2462 | */ | ||
| 2463 | if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) | ||
| 2464 | goto out; | ||
| 2465 | |||
| 2453 | if (!batadv_tt_global_add(bat_priv, orig_node, addr, | 2466 | if (!batadv_tt_global_add(bat_priv, orig_node, addr, |
| 2454 | BATADV_TT_CLIENT_TEMP, | 2467 | BATADV_TT_CLIENT_TEMP, |
| 2455 | atomic_read(&orig_node->last_ttvn))) | 2468 | atomic_read(&orig_node->last_ttvn))) |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8a0ce706aebd..a0a2f97b9c62 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) | |||
| 1754 | if (hdev->dev_type != HCI_AMP) | 1754 | if (hdev->dev_type != HCI_AMP) |
| 1755 | set_bit(HCI_AUTO_OFF, &hdev->dev_flags); | 1755 | set_bit(HCI_AUTO_OFF, &hdev->dev_flags); |
| 1756 | 1756 | ||
| 1757 | schedule_work(&hdev->power_on); | ||
| 1758 | |||
| 1759 | hci_notify(hdev, HCI_DEV_REG); | 1757 | hci_notify(hdev, HCI_DEV_REG); |
| 1760 | hci_dev_hold(hdev); | 1758 | hci_dev_hold(hdev); |
| 1761 | 1759 | ||
| 1760 | schedule_work(&hdev->power_on); | ||
| 1761 | |||
| 1762 | return id; | 1762 | return id; |
| 1763 | 1763 | ||
| 1764 | err_wqueue: | 1764 | err_wqueue: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index aa2ea0a8142c..91de4239da66 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
| @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 326 | struct hci_dev *d; | 326 | struct hci_dev *d; |
| 327 | size_t rp_len; | 327 | size_t rp_len; |
| 328 | u16 count; | 328 | u16 count; |
| 329 | int i, err; | 329 | int err; |
| 330 | 330 | ||
| 331 | BT_DBG("sock %p", sk); | 331 | BT_DBG("sock %p", sk); |
| 332 | 332 | ||
| @@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 347 | return -ENOMEM; | 347 | return -ENOMEM; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | rp->num_controllers = cpu_to_le16(count); | 350 | count = 0; |
| 351 | |||
| 352 | i = 0; | ||
| 353 | list_for_each_entry(d, &hci_dev_list, list) { | 351 | list_for_each_entry(d, &hci_dev_list, list) { |
| 354 | if (test_bit(HCI_SETUP, &d->dev_flags)) | 352 | if (test_bit(HCI_SETUP, &d->dev_flags)) |
| 355 | continue; | 353 | continue; |
| @@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 357 | if (!mgmt_valid_hdev(d)) | 355 | if (!mgmt_valid_hdev(d)) |
| 358 | continue; | 356 | continue; |
| 359 | 357 | ||
| 360 | rp->index[i++] = cpu_to_le16(d->id); | 358 | rp->index[count++] = cpu_to_le16(d->id); |
| 361 | BT_DBG("Added hci%u", d->id); | 359 | BT_DBG("Added hci%u", d->id); |
| 362 | } | 360 | } |
| 363 | 361 | ||
| 362 | rp->num_controllers = cpu_to_le16(count); | ||
| 363 | rp_len = sizeof(*rp) + (2 * count); | ||
| 364 | |||
| 364 | read_unlock(&hci_dev_list_lock); | 365 | read_unlock(&hci_dev_list_lock); |
| 365 | 366 | ||
| 366 | err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, | 367 | err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, |
| @@ -1366,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 1366 | continue; | 1367 | continue; |
| 1367 | 1368 | ||
| 1368 | list_del(&match->list); | 1369 | list_del(&match->list); |
| 1370 | kfree(match); | ||
| 1369 | found++; | 1371 | found++; |
| 1370 | } | 1372 | } |
| 1371 | 1373 | ||
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2ac8d50861e0..a5923378bdf0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) | |||
| 267 | 267 | ||
| 268 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); | 268 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); |
| 269 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, | 269 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, |
| 270 | hcon->dst_type, reason); | 270 | hcon->dst_type, HCI_ERROR_AUTH_FAILURE); |
| 271 | 271 | ||
| 272 | cancel_delayed_work_sync(&conn->security_timer); | 272 | cancel_delayed_work_sync(&conn->security_timer); |
| 273 | 273 | ||
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 159aa8bef9e7..3ef1759403b4 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
| @@ -2300,10 +2300,11 @@ restart: | |||
| 2300 | mutex_unlock(&con->mutex); | 2300 | mutex_unlock(&con->mutex); |
| 2301 | return; | 2301 | return; |
| 2302 | } else { | 2302 | } else { |
| 2303 | con->ops->put(con); | ||
| 2304 | dout("con_work %p FAILED to back off %lu\n", con, | 2303 | dout("con_work %p FAILED to back off %lu\n", con, |
| 2305 | con->delay); | 2304 | con->delay); |
| 2305 | set_bit(CON_FLAG_BACKOFF, &con->flags); | ||
| 2306 | } | 2306 | } |
| 2307 | goto done; | ||
| 2307 | } | 2308 | } |
| 2308 | 2309 | ||
| 2309 | if (con->state == CON_STATE_STANDBY) { | 2310 | if (con->state == CON_STATE_STANDBY) { |
| @@ -2749,7 +2750,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) | |||
| 2749 | msg = con->ops->alloc_msg(con, hdr, skip); | 2750 | msg = con->ops->alloc_msg(con, hdr, skip); |
| 2750 | mutex_lock(&con->mutex); | 2751 | mutex_lock(&con->mutex); |
| 2751 | if (con->state != CON_STATE_OPEN) { | 2752 | if (con->state != CON_STATE_OPEN) { |
| 2752 | ceph_msg_put(msg); | 2753 | if (msg) |
| 2754 | ceph_msg_put(msg); | ||
| 2753 | return -EAGAIN; | 2755 | return -EAGAIN; |
| 2754 | } | 2756 | } |
| 2755 | con->in_msg = msg; | 2757 | con->in_msg = msg; |
diff --git a/net/core/dev.c b/net/core/dev.c index 09cb3f6dc40c..c0946cb2b354 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
| 1666 | 1666 | ||
| 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) |
| 1668 | { | 1668 | { |
| 1669 | if (ptype->af_packet_priv == NULL) | 1669 | if (!ptype->af_packet_priv || !skb->sk) |
| 1670 | return false; | 1670 | return false; |
| 1671 | 1671 | ||
| 1672 | if (ptype->id_match) | 1672 | if (ptype->id_match) |
| @@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
| 2818 | if (unlikely(tcpu != next_cpu) && | 2818 | if (unlikely(tcpu != next_cpu) && |
| 2819 | (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || | 2819 | (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || |
| 2820 | ((int)(per_cpu(softnet_data, tcpu).input_queue_head - | 2820 | ((int)(per_cpu(softnet_data, tcpu).input_queue_head - |
| 2821 | rflow->last_qtail)) >= 0)) | 2821 | rflow->last_qtail)) >= 0)) { |
| 2822 | tcpu = next_cpu; | ||
| 2822 | rflow = set_rps_cpu(dev, skb, rflow, next_cpu); | 2823 | rflow = set_rps_cpu(dev, skb, rflow, next_cpu); |
| 2824 | } | ||
| 2823 | 2825 | ||
| 2824 | if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { | 2826 | if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { |
| 2825 | *rflowp = rflow; | 2827 | *rflowp = rflow; |
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17db2d56..b079c7bbc157 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c | |||
| @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, | |||
| 319 | */ | 319 | */ |
| 320 | ha = list_first_entry(&dev->dev_addrs.list, | 320 | ha = list_first_entry(&dev->dev_addrs.list, |
| 321 | struct netdev_hw_addr, list); | 321 | struct netdev_hw_addr, list); |
| 322 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | 322 | if (!memcmp(ha->addr, addr, dev->addr_len) && |
| 323 | ha->type == addr_type && ha->refcount == 1) | ||
| 323 | return -ENOENT; | 324 | return -ENOENT; |
| 324 | 325 | ||
| 325 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, | 326 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 76d4c2c3c89b..fad649ae4dec 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -2192,7 +2192,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, | |||
| 2192 | goto skip; | 2192 | goto skip; |
| 2193 | 2193 | ||
| 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, | 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, |
| 2195 | portid, seq, 0, NTF_SELF); | 2195 | portid, seq, |
| 2196 | RTM_NEWNEIGH, NTF_SELF); | ||
| 2196 | if (err < 0) | 2197 | if (err < 0) |
| 2197 | return err; | 2198 | return err; |
| 2198 | skip: | 2199 | skip: |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 535584c00f91..0c34bfabc11f 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -892,13 +892,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) | 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) |
| 893 | { | 893 | { |
| 894 | const struct inet_diag_handler *handler; | 894 | const struct inet_diag_handler *handler; |
| 895 | int err = 0; | ||
| 895 | 896 | ||
| 896 | handler = inet_diag_lock_handler(r->sdiag_protocol); | 897 | handler = inet_diag_lock_handler(r->sdiag_protocol); |
| 897 | if (!IS_ERR(handler)) | 898 | if (!IS_ERR(handler)) |
| 898 | handler->dump(skb, cb, r, bc); | 899 | handler->dump(skb, cb, r, bc); |
| 900 | else | ||
| 901 | err = PTR_ERR(handler); | ||
| 899 | inet_diag_unlock_handler(handler); | 902 | inet_diag_unlock_handler(handler); |
| 900 | 903 | ||
| 901 | return skb->len; | 904 | return err ? : skb->len; |
| 902 | } | 905 | } |
| 903 | 906 | ||
| 904 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | 907 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5eea4a811042..14bbfcf717ac 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
| 457 | struct inet_sock *inet = inet_sk(sk); | 457 | struct inet_sock *inet = inet_sk(sk); |
| 458 | int val = 0, err; | 458 | int val = 0, err; |
| 459 | 459 | ||
| 460 | if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | | 460 | switch (optname) { |
| 461 | (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | | 461 | case IP_PKTINFO: |
| 462 | (1<<IP_RETOPTS) | (1<<IP_TOS) | | 462 | case IP_RECVTTL: |
| 463 | (1<<IP_TTL) | (1<<IP_HDRINCL) | | 463 | case IP_RECVOPTS: |
| 464 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | | 464 | case IP_RECVTOS: |
| 465 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | 465 | case IP_RETOPTS: |
| 466 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) | | 466 | case IP_TOS: |
| 467 | (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) || | 467 | case IP_TTL: |
| 468 | optname == IP_UNICAST_IF || | 468 | case IP_HDRINCL: |
| 469 | optname == IP_MULTICAST_TTL || | 469 | case IP_MTU_DISCOVER: |
| 470 | optname == IP_MULTICAST_ALL || | 470 | case IP_RECVERR: |
| 471 | optname == IP_MULTICAST_LOOP || | 471 | case IP_ROUTER_ALERT: |
| 472 | optname == IP_RECVORIGDSTADDR) { | 472 | case IP_FREEBIND: |
| 473 | case IP_PASSSEC: | ||
| 474 | case IP_TRANSPARENT: | ||
| 475 | case IP_MINTTL: | ||
| 476 | case IP_NODEFRAG: | ||
| 477 | case IP_UNICAST_IF: | ||
| 478 | case IP_MULTICAST_TTL: | ||
| 479 | case IP_MULTICAST_ALL: | ||
| 480 | case IP_MULTICAST_LOOP: | ||
| 481 | case IP_RECVORIGDSTADDR: | ||
| 473 | if (optlen >= sizeof(int)) { | 482 | if (optlen >= sizeof(int)) { |
| 474 | if (get_user(val, (int __user *) optval)) | 483 | if (get_user(val, (int __user *) optval)) |
| 475 | return -EFAULT; | 484 | return -EFAULT; |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092f999f..858fddf6482a 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
| @@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb) | |||
| 338 | if (tunnel != NULL) { | 338 | if (tunnel != NULL) { |
| 339 | struct pcpu_tstats *tstats; | 339 | struct pcpu_tstats *tstats; |
| 340 | 340 | ||
| 341 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | ||
| 342 | return -1; | ||
| 343 | |||
| 341 | tstats = this_cpu_ptr(tunnel->dev->tstats); | 344 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
| 342 | u64_stats_update_begin(&tstats->syncp); | 345 | u64_stats_update_begin(&tstats->syncp); |
| 343 | tstats->rx_packets++; | 346 | tstats->rx_packets++; |
| 344 | tstats->rx_bytes += skb->len; | 347 | tstats->rx_bytes += skb->len; |
| 345 | u64_stats_update_end(&tstats->syncp); | 348 | u64_stats_update_end(&tstats->syncp); |
| 346 | 349 | ||
| 350 | skb->mark = 0; | ||
| 351 | secpath_reset(skb); | ||
| 347 | skb->dev = tunnel->dev; | 352 | skb->dev = tunnel->dev; |
| 348 | return 1; | 353 | return 1; |
| 349 | } | 354 | } |
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c index 9e0ffaf1d942..a82047282dbb 100644 --- a/net/ipv4/netfilter/iptable_nat.c +++ b/net/ipv4/netfilter/iptable_nat.c | |||
| @@ -184,7 +184,8 @@ nf_nat_ipv4_out(unsigned int hooknum, | |||
| 184 | 184 | ||
| 185 | if ((ct->tuplehash[dir].tuple.src.u3.ip != | 185 | if ((ct->tuplehash[dir].tuple.src.u3.ip != |
| 186 | ct->tuplehash[!dir].tuple.dst.u3.ip) || | 186 | ct->tuplehash[!dir].tuple.dst.u3.ip) || |
| 187 | (ct->tuplehash[dir].tuple.src.u.all != | 187 | (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && |
| 188 | ct->tuplehash[dir].tuple.src.u.all != | ||
| 188 | ct->tuplehash[!dir].tuple.dst.u.all)) | 189 | ct->tuplehash[!dir].tuple.dst.u.all)) |
| 189 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) | 190 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) |
| 190 | ret = NF_DROP; | 191 | ret = NF_DROP; |
| @@ -221,6 +222,7 @@ nf_nat_ipv4_local_fn(unsigned int hooknum, | |||
| 221 | } | 222 | } |
| 222 | #ifdef CONFIG_XFRM | 223 | #ifdef CONFIG_XFRM |
| 223 | else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && | 224 | else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && |
| 225 | ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && | ||
| 224 | ct->tuplehash[dir].tuple.dst.u.all != | 226 | ct->tuplehash[dir].tuple.dst.u.all != |
| 225 | ct->tuplehash[!dir].tuple.src.u.all) | 227 | ct->tuplehash[!dir].tuple.src.u.all) |
| 226 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) | 228 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 197c0008503c..083092e3aed6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1212,7 +1212,7 @@ new_segment: | |||
| 1212 | wait_for_sndbuf: | 1212 | wait_for_sndbuf: |
| 1213 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 1213 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
| 1214 | wait_for_memory: | 1214 | wait_for_memory: |
| 1215 | if (copied && likely(!tp->repair)) | 1215 | if (copied) |
| 1216 | tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); | 1216 | tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); |
| 1217 | 1217 | ||
| 1218 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) | 1218 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) |
| @@ -1223,7 +1223,7 @@ wait_for_memory: | |||
| 1223 | } | 1223 | } |
| 1224 | 1224 | ||
| 1225 | out: | 1225 | out: |
| 1226 | if (copied && likely(!tp->repair)) | 1226 | if (copied) |
| 1227 | tcp_push(sk, flags, mss_now, tp->nonagle); | 1227 | tcp_push(sk, flags, mss_now, tp->nonagle); |
| 1228 | release_sock(sk); | 1228 | release_sock(sk); |
| 1229 | return copied + copied_syn; | 1229 | return copied + copied_syn; |
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 813b43a76fec..834857f3c871 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c | |||
| @@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, | |||
| 313 | .tcpv_rttcnt = ca->cnt_rtt, | 313 | .tcpv_rttcnt = ca->cnt_rtt, |
| 314 | .tcpv_minrtt = ca->base_rtt, | 314 | .tcpv_minrtt = ca->base_rtt, |
| 315 | }; | 315 | }; |
| 316 | u64 t = ca->sum_rtt; | ||
| 317 | 316 | ||
| 318 | do_div(t, ca->cnt_rtt); | 317 | if (info.tcpv_rttcnt > 0) { |
| 319 | info.tcpv_rtt = t; | 318 | u64 t = ca->sum_rtt; |
| 320 | 319 | ||
| 320 | do_div(t, info.tcpv_rttcnt); | ||
| 321 | info.tcpv_rtt = t; | ||
| 322 | } | ||
| 321 | nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); | 323 | nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); |
| 322 | } | 324 | } |
| 323 | } | 325 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 1db663983587..609ff98aeb47 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -4529,6 +4529,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) | |||
| 4529 | struct tcphdr *th; | 4529 | struct tcphdr *th; |
| 4530 | bool fragstolen; | 4530 | bool fragstolen; |
| 4531 | 4531 | ||
| 4532 | if (size == 0) | ||
| 4533 | return 0; | ||
| 4534 | |||
| 4532 | skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); | 4535 | skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); |
| 4533 | if (!skb) | 4536 | if (!skb) |
| 4534 | goto err; | 4537 | goto err; |
| @@ -5310,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | |||
| 5310 | goto discard; | 5313 | goto discard; |
| 5311 | } | 5314 | } |
| 5312 | 5315 | ||
| 5313 | /* ts_recent update must be made after we are sure that the packet | ||
| 5314 | * is in window. | ||
| 5315 | */ | ||
| 5316 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 5317 | |||
| 5318 | /* step 3: check security and precedence [ignored] */ | 5316 | /* step 3: check security and precedence [ignored] */ |
| 5319 | 5317 | ||
| 5320 | /* step 4: Check for a SYN | 5318 | /* step 4: Check for a SYN |
| @@ -5549,6 +5547,11 @@ step5: | |||
| 5549 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) | 5547 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) |
| 5550 | goto discard; | 5548 | goto discard; |
| 5551 | 5549 | ||
| 5550 | /* ts_recent update must be made after we are sure that the packet | ||
| 5551 | * is in window. | ||
| 5552 | */ | ||
| 5553 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 5554 | |||
| 5552 | tcp_rcv_rtt_measure_ts(sk, skb); | 5555 | tcp_rcv_rtt_measure_ts(sk, skb); |
| 5553 | 5556 | ||
| 5554 | /* Process urgent data. */ | 5557 | /* Process urgent data. */ |
| @@ -6127,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 6127 | } else | 6130 | } else |
| 6128 | goto discard; | 6131 | goto discard; |
| 6129 | 6132 | ||
| 6133 | /* ts_recent update must be made after we are sure that the packet | ||
| 6134 | * is in window. | ||
| 6135 | */ | ||
| 6136 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 6137 | |||
| 6130 | /* step 6: check the URG bit */ | 6138 | /* step 6: check the URG bit */ |
| 6131 | tcp_urg(sk, skb, th); | 6139 | tcp_urg(sk, skb, th); |
| 6132 | 6140 | ||
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 4c752a6e0bcd..f696d7c2e9fa 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #include <linux/rcupdate.h> | 1 | #include <linux/rcupdate.h> |
| 2 | #include <linux/spinlock.h> | 2 | #include <linux/spinlock.h> |
| 3 | #include <linux/jiffies.h> | 3 | #include <linux/jiffies.h> |
| 4 | #include <linux/bootmem.h> | ||
| 5 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 6 | #include <linux/cache.h> | 5 | #include <linux/cache.h> |
| 7 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
| @@ -9,6 +8,7 @@ | |||
| 9 | #include <linux/tcp.h> | 8 | #include <linux/tcp.h> |
| 10 | #include <linux/hash.h> | 9 | #include <linux/hash.h> |
| 11 | #include <linux/tcp_metrics.h> | 10 | #include <linux/tcp_metrics.h> |
| 11 | #include <linux/vmalloc.h> | ||
| 12 | 12 | ||
| 13 | #include <net/inet_connection_sock.h> | 13 | #include <net/inet_connection_sock.h> |
| 14 | #include <net/net_namespace.h> | 14 | #include <net/net_namespace.h> |
| @@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr, | |||
| 864 | } | 864 | } |
| 865 | a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; | 865 | a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; |
| 866 | if (a) { | 866 | if (a) { |
| 867 | if (nla_len(a) != sizeof(sizeof(struct in6_addr))) | 867 | if (nla_len(a) != sizeof(struct in6_addr)) |
| 868 | return -EINVAL; | 868 | return -EINVAL; |
| 869 | addr->family = AF_INET6; | 869 | addr->family = AF_INET6; |
| 870 | memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); | 870 | memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); |
| @@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net) | |||
| 1034 | net->ipv4.tcp_metrics_hash_log = order_base_2(slots); | 1034 | net->ipv4.tcp_metrics_hash_log = order_base_2(slots); |
| 1035 | size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; | 1035 | size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; |
| 1036 | 1036 | ||
| 1037 | net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); | 1037 | net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); |
| 1038 | if (!net->ipv4.tcp_metrics_hash) | ||
| 1039 | net->ipv4.tcp_metrics_hash = vzalloc(size); | ||
| 1040 | |||
| 1038 | if (!net->ipv4.tcp_metrics_hash) | 1041 | if (!net->ipv4.tcp_metrics_hash) |
| 1039 | return -ENOMEM; | 1042 | return -ENOMEM; |
| 1040 | 1043 | ||
| @@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) | |||
| 1055 | tm = next; | 1058 | tm = next; |
| 1056 | } | 1059 | } |
| 1057 | } | 1060 | } |
| 1058 | kfree(net->ipv4.tcp_metrics_hash); | 1061 | if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) |
| 1062 | vfree(net->ipv4.tcp_metrics_hash); | ||
| 1063 | else | ||
| 1064 | kfree(net->ipv4.tcp_metrics_hash); | ||
| 1059 | } | 1065 | } |
| 1060 | 1066 | ||
| 1061 | static __net_initdata struct pernet_operations tcp_net_metrics_ops = { | 1067 | static __net_initdata struct pernet_operations tcp_net_metrics_ops = { |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c177..2798706cb063 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); | 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); |
| 1987 | BUG_ON(!tso_segs); | 1987 | BUG_ON(!tso_segs); |
| 1988 | 1988 | ||
| 1989 | if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) | ||
| 1990 | goto repair; /* Skip network transmission */ | ||
| 1991 | |||
| 1989 | cwnd_quota = tcp_cwnd_test(tp, skb); | 1992 | cwnd_quota = tcp_cwnd_test(tp, skb); |
| 1990 | if (!cwnd_quota) | 1993 | if (!cwnd_quota) |
| 1991 | break; | 1994 | break; |
| @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 2026 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) | 2029 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) |
| 2027 | break; | 2030 | break; |
| 2028 | 2031 | ||
| 2032 | repair: | ||
| 2029 | /* Advance the send_head. This one is sent out. | 2033 | /* Advance the send_head. This one is sent out. |
| 2030 | * This call will increment packets_out. | 2034 | * This call will increment packets_out. |
| 2031 | */ | 2035 | */ |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 0185679c5f53..d5cb3c4e66f8 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) | |||
| 1633 | /* IFLA_GRE_OKEY */ | 1633 | /* IFLA_GRE_OKEY */ |
| 1634 | nla_total_size(4) + | 1634 | nla_total_size(4) + |
| 1635 | /* IFLA_GRE_LOCAL */ | 1635 | /* IFLA_GRE_LOCAL */ |
| 1636 | nla_total_size(4) + | 1636 | nla_total_size(sizeof(struct in6_addr)) + |
| 1637 | /* IFLA_GRE_REMOTE */ | 1637 | /* IFLA_GRE_REMOTE */ |
| 1638 | nla_total_size(4) + | 1638 | nla_total_size(sizeof(struct in6_addr)) + |
| 1639 | /* IFLA_GRE_TTL */ | 1639 | /* IFLA_GRE_TTL */ |
| 1640 | nla_total_size(1) + | 1640 | nla_total_size(1) + |
| 1641 | /* IFLA_GRE_TOS */ | 1641 | /* IFLA_GRE_TOS */ |
| @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || | 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || |
| 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || | 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || |
| 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || | 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || |
| 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || | 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || |
| 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || | 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || |
| 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || | 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || |
| 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ | 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ |
| 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || | 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e1..e02faed6d17e 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -827,6 +827,7 @@ pref_skip_coa: | |||
| 827 | if (val < 0 || val > 255) | 827 | if (val < 0 || val > 255) |
| 828 | goto e_inval; | 828 | goto e_inval; |
| 829 | np->min_hopcount = val; | 829 | np->min_hopcount = val; |
| 830 | retv = 0; | ||
| 830 | break; | 831 | break; |
| 831 | case IPV6_DONTFRAG: | 832 | case IPV6_DONTFRAG: |
| 832 | np->dontfrag = valbool; | 833 | np->dontfrag = valbool; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ff36194a71aa..2edce30ef733 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 535 | { | 535 | { |
| 536 | struct inet6_dev *idev; | 536 | struct inet6_dev *idev; |
| 537 | struct inet6_ifaddr *ifa; | 537 | struct inet6_ifaddr *ifa; |
| 538 | struct in6_addr mcaddr; | 538 | struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; |
| 539 | 539 | ||
| 540 | idev = in6_dev_get(dev); | 540 | idev = in6_dev_get(dev); |
| 541 | if (!idev) | 541 | if (!idev) |
| @@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 543 | 543 | ||
| 544 | read_lock_bh(&idev->lock); | 544 | read_lock_bh(&idev->lock); |
| 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { |
| 546 | addrconf_addr_solict_mult(&ifa->addr, &mcaddr); | ||
| 547 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, | 546 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, |
| 548 | /*router=*/ !!idev->cnf.forwarding, | 547 | /*router=*/ !!idev->cnf.forwarding, |
| 549 | /*solicited=*/ false, /*override=*/ true, | 548 | /*solicited=*/ false, /*override=*/ true, |
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index e418bd6350a4..d57dab17a182 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c | |||
| @@ -186,7 +186,8 @@ nf_nat_ipv6_out(unsigned int hooknum, | |||
| 186 | 186 | ||
| 187 | if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, | 187 | if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, |
| 188 | &ct->tuplehash[!dir].tuple.dst.u3) || | 188 | &ct->tuplehash[!dir].tuple.dst.u3) || |
| 189 | (ct->tuplehash[dir].tuple.src.u.all != | 189 | (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && |
| 190 | ct->tuplehash[dir].tuple.src.u.all != | ||
| 190 | ct->tuplehash[!dir].tuple.dst.u.all)) | 191 | ct->tuplehash[!dir].tuple.dst.u.all)) |
| 191 | if (nf_xfrm_me_harder(skb, AF_INET6) < 0) | 192 | if (nf_xfrm_me_harder(skb, AF_INET6) < 0) |
| 192 | ret = NF_DROP; | 193 | ret = NF_DROP; |
| @@ -222,6 +223,7 @@ nf_nat_ipv6_local_fn(unsigned int hooknum, | |||
| 222 | } | 223 | } |
| 223 | #ifdef CONFIG_XFRM | 224 | #ifdef CONFIG_XFRM |
| 224 | else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | 225 | else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && |
| 226 | ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && | ||
| 225 | ct->tuplehash[dir].tuple.dst.u.all != | 227 | ct->tuplehash[dir].tuple.dst.u.all != |
| 226 | ct->tuplehash[!dir].tuple.src.u.all) | 228 | ct->tuplehash[!dir].tuple.src.u.all) |
| 227 | if (nf_xfrm_me_harder(skb, AF_INET6)) | 229 | if (nf_xfrm_me_harder(skb, AF_INET6)) |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 18bd9bbbd1c6..22c8ea951185 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { | |||
| 85 | { } | 85 | { } |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | static int __net_init nf_ct_frag6_sysctl_register(struct net *net) | 88 | static int nf_ct_frag6_sysctl_register(struct net *net) |
| 89 | { | 89 | { |
| 90 | struct ctl_table *table; | 90 | struct ctl_table *table; |
| 91 | struct ctl_table_header *hdr; | 91 | struct ctl_table_header *hdr; |
| @@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) | |||
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | #else | 129 | #else |
| 130 | static int __net_init nf_ct_frag6_sysctl_register(struct net *net) | 130 | static int nf_ct_frag6_sysctl_register(struct net *net) |
| 131 | { | 131 | { |
| 132 | return 0; | 132 | return 0; |
| 133 | } | 133 | } |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 37b8b8ba31f7..76125c57ee6d 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
| @@ -291,6 +291,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p | |||
| 291 | 291 | ||
| 292 | out_del_dev: | 292 | out_del_dev: |
| 293 | free_netdev(dev); | 293 | free_netdev(dev); |
| 294 | spriv->dev = NULL; | ||
| 294 | out_del_session: | 295 | out_del_session: |
| 295 | l2tp_session_delete(session); | 296 | l2tp_session_delete(session); |
| 296 | out: | 297 | out: |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 05f3a313db88..7371f676cf41 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -2594,6 +2594,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | |||
| 2594 | else | 2594 | else |
| 2595 | local->probe_req_reg--; | 2595 | local->probe_req_reg--; |
| 2596 | 2596 | ||
| 2597 | if (!local->open_count) | ||
| 2598 | break; | ||
| 2599 | |||
| 2597 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | 2600 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); |
| 2598 | break; | 2601 | break; |
| 2599 | default: | 2602 | default: |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 5f3620f0bc0a..bf87c70ac6c5 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
| 1108 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | 1108 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; |
| 1109 | sdata->u.ibss.ibss_join_req = jiffies; | 1109 | sdata->u.ibss.ibss_join_req = jiffies; |
| 1110 | 1110 | ||
| 1111 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); | 1111 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); |
| 1112 | sdata->u.ibss.ssid_len = params->ssid_len; | 1112 | sdata->u.ibss.ssid_len = params->ssid_len; |
| 1113 | 1113 | ||
| 1114 | mutex_unlock(&sdata->u.ibss.mtx); | 1114 | mutex_unlock(&sdata->u.ibss.mtx); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c804550465b..156e5835e37f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1314,6 +1314,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
| 1314 | struct net_device *dev); | 1314 | struct net_device *dev); |
| 1315 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | 1315 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, |
| 1316 | struct net_device *dev); | 1316 | struct net_device *dev); |
| 1317 | void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, | ||
| 1318 | struct sk_buff_head *skbs); | ||
| 1317 | 1319 | ||
| 1318 | /* HT */ | 1320 | /* HT */ |
| 1319 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | 1321 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c80c4490351c..f57f597972f8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -871,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 871 | local->hw.wiphy->cipher_suites, | 871 | local->hw.wiphy->cipher_suites, |
| 872 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | 872 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, |
| 873 | GFP_KERNEL); | 873 | GFP_KERNEL); |
| 874 | if (!suites) | 874 | if (!suites) { |
| 875 | return -ENOMEM; | 875 | result = -ENOMEM; |
| 876 | goto fail_wiphy_register; | ||
| 877 | } | ||
| 876 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { | 878 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { |
| 877 | u32 suite = local->hw.wiphy->cipher_suites[r]; | 879 | u32 suite = local->hw.wiphy->cipher_suites[r]; |
| 878 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | 880 | if (suite == WLAN_CIPHER_SUITE_WEP40 || |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 61c621e9273f..00ade7feb2e3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
| 531 | 531 | ||
| 532 | if (ieee80211_is_action(hdr->frame_control)) { | 532 | if (ieee80211_is_action(hdr->frame_control)) { |
| 533 | u8 category; | 533 | u8 category; |
| 534 | |||
| 535 | /* make sure category field is present */ | ||
| 536 | if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) | ||
| 537 | return RX_DROP_MONITOR; | ||
| 538 | |||
| 534 | mgmt = (struct ieee80211_mgmt *)hdr; | 539 | mgmt = (struct ieee80211_mgmt *)hdr; |
| 535 | category = mgmt->u.action.category; | 540 | category = mgmt->u.action.category; |
| 536 | if (category != WLAN_CATEGORY_MESH_ACTION && | 541 | if (category != WLAN_CATEGORY_MESH_ACTION && |
| @@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
| 883 | */ | 888 | */ |
| 884 | if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && | 889 | if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && |
| 885 | ieee80211_is_data_present(hdr->frame_control)) { | 890 | ieee80211_is_data_present(hdr->frame_control)) { |
| 886 | u16 ethertype; | 891 | unsigned int hdrlen; |
| 887 | u8 *payload; | 892 | __be16 ethertype; |
| 888 | 893 | ||
| 889 | payload = rx->skb->data + | 894 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 890 | ieee80211_hdrlen(hdr->frame_control); | 895 | |
| 891 | ethertype = (payload[6] << 8) | payload[7]; | 896 | if (rx->skb->len < hdrlen + 8) |
| 892 | if (cpu_to_be16(ethertype) == | 897 | return RX_DROP_MONITOR; |
| 893 | rx->sdata->control_port_protocol) | 898 | |
| 899 | skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); | ||
| 900 | if (ethertype == rx->sdata->control_port_protocol) | ||
| 894 | return RX_CONTINUE; | 901 | return RX_CONTINUE; |
| 895 | } | 902 | } |
| 896 | 903 | ||
| @@ -1462,11 +1469,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
| 1462 | 1469 | ||
| 1463 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 1470 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 1464 | fc = hdr->frame_control; | 1471 | fc = hdr->frame_control; |
| 1472 | |||
| 1473 | if (ieee80211_is_ctl(fc)) | ||
| 1474 | return RX_CONTINUE; | ||
| 1475 | |||
| 1465 | sc = le16_to_cpu(hdr->seq_ctrl); | 1476 | sc = le16_to_cpu(hdr->seq_ctrl); |
| 1466 | frag = sc & IEEE80211_SCTL_FRAG; | 1477 | frag = sc & IEEE80211_SCTL_FRAG; |
| 1467 | 1478 | ||
| 1468 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || | 1479 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || |
| 1469 | (rx->skb)->len < 24 || | ||
| 1470 | is_multicast_ether_addr(hdr->addr1))) { | 1480 | is_multicast_ether_addr(hdr->addr1))) { |
| 1471 | /* not fragmented */ | 1481 | /* not fragmented */ |
| 1472 | goto out; | 1482 | goto out; |
| @@ -1889,6 +1899,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1889 | 1899 | ||
| 1890 | hdr = (struct ieee80211_hdr *) skb->data; | 1900 | hdr = (struct ieee80211_hdr *) skb->data; |
| 1891 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1901 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 1902 | |||
| 1903 | /* make sure fixed part of mesh header is there, also checks skb len */ | ||
| 1904 | if (!pskb_may_pull(rx->skb, hdrlen + 6)) | ||
| 1905 | return RX_DROP_MONITOR; | ||
| 1906 | |||
| 1907 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | ||
| 1908 | |||
| 1909 | /* make sure full mesh header is there, also checks skb len */ | ||
| 1910 | if (!pskb_may_pull(rx->skb, | ||
| 1911 | hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) | ||
| 1912 | return RX_DROP_MONITOR; | ||
| 1913 | |||
| 1914 | /* reload pointers */ | ||
| 1915 | hdr = (struct ieee80211_hdr *) skb->data; | ||
| 1892 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 1916 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
| 1893 | 1917 | ||
| 1894 | /* frame is in RMC, don't forward */ | 1918 | /* frame is in RMC, don't forward */ |
| @@ -1897,7 +1921,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1897 | mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) | 1921 | mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) |
| 1898 | return RX_DROP_MONITOR; | 1922 | return RX_DROP_MONITOR; |
| 1899 | 1923 | ||
| 1900 | if (!ieee80211_is_data(hdr->frame_control)) | 1924 | if (!ieee80211_is_data(hdr->frame_control) || |
| 1925 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
| 1901 | return RX_CONTINUE; | 1926 | return RX_CONTINUE; |
| 1902 | 1927 | ||
| 1903 | if (!mesh_hdr->ttl) | 1928 | if (!mesh_hdr->ttl) |
| @@ -1911,9 +1936,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1911 | if (is_multicast_ether_addr(hdr->addr1)) { | 1936 | if (is_multicast_ether_addr(hdr->addr1)) { |
| 1912 | mpp_addr = hdr->addr3; | 1937 | mpp_addr = hdr->addr3; |
| 1913 | proxied_addr = mesh_hdr->eaddr1; | 1938 | proxied_addr = mesh_hdr->eaddr1; |
| 1914 | } else { | 1939 | } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { |
| 1940 | /* has_a4 already checked in ieee80211_rx_mesh_check */ | ||
| 1915 | mpp_addr = hdr->addr4; | 1941 | mpp_addr = hdr->addr4; |
| 1916 | proxied_addr = mesh_hdr->eaddr2; | 1942 | proxied_addr = mesh_hdr->eaddr2; |
| 1943 | } else { | ||
| 1944 | return RX_DROP_MONITOR; | ||
| 1917 | } | 1945 | } |
| 1918 | 1946 | ||
| 1919 | rcu_read_lock(); | 1947 | rcu_read_lock(); |
| @@ -1941,12 +1969,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1941 | } | 1969 | } |
| 1942 | skb_set_queue_mapping(skb, q); | 1970 | skb_set_queue_mapping(skb, q); |
| 1943 | 1971 | ||
| 1944 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
| 1945 | goto out; | ||
| 1946 | |||
| 1947 | if (!--mesh_hdr->ttl) { | 1972 | if (!--mesh_hdr->ttl) { |
| 1948 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); | 1973 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); |
| 1949 | return RX_DROP_MONITOR; | 1974 | goto out; |
| 1950 | } | 1975 | } |
| 1951 | 1976 | ||
| 1952 | if (!ifmsh->mshcfg.dot11MeshForwarding) | 1977 | if (!ifmsh->mshcfg.dot11MeshForwarding) |
| @@ -2353,6 +2378,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2353 | } | 2378 | } |
| 2354 | break; | 2379 | break; |
| 2355 | case WLAN_CATEGORY_SELF_PROTECTED: | 2380 | case WLAN_CATEGORY_SELF_PROTECTED: |
| 2381 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 2382 | sizeof(mgmt->u.action.u.self_prot.action_code))) | ||
| 2383 | break; | ||
| 2384 | |||
| 2356 | switch (mgmt->u.action.u.self_prot.action_code) { | 2385 | switch (mgmt->u.action.u.self_prot.action_code) { |
| 2357 | case WLAN_SP_MESH_PEERING_OPEN: | 2386 | case WLAN_SP_MESH_PEERING_OPEN: |
| 2358 | case WLAN_SP_MESH_PEERING_CLOSE: | 2387 | case WLAN_SP_MESH_PEERING_CLOSE: |
| @@ -2371,6 +2400,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2371 | } | 2400 | } |
| 2372 | break; | 2401 | break; |
| 2373 | case WLAN_CATEGORY_MESH_ACTION: | 2402 | case WLAN_CATEGORY_MESH_ACTION: |
| 2403 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 2404 | sizeof(mgmt->u.action.u.mesh_action.action_code))) | ||
| 2405 | break; | ||
| 2406 | |||
| 2374 | if (!ieee80211_vif_is_mesh(&sdata->vif)) | 2407 | if (!ieee80211_vif_is_mesh(&sdata->vif)) |
| 2375 | break; | 2408 | break; |
| 2376 | if (mesh_action_is_path_sel(mgmt) && | 2409 | if (mesh_action_is_path_sel(mgmt) && |
| @@ -2913,10 +2946,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
| 2913 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 2946 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
| 2914 | local->dot11ReceivedFragmentCount++; | 2947 | local->dot11ReceivedFragmentCount++; |
| 2915 | 2948 | ||
| 2916 | if (ieee80211_is_mgmt(fc)) | 2949 | if (ieee80211_is_mgmt(fc)) { |
| 2917 | err = skb_linearize(skb); | 2950 | /* drop frame if too short for header */ |
| 2918 | else | 2951 | if (skb->len < ieee80211_hdrlen(fc)) |
| 2952 | err = -ENOBUFS; | ||
| 2953 | else | ||
| 2954 | err = skb_linearize(skb); | ||
| 2955 | } else { | ||
| 2919 | err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); | 2956 | err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); |
| 2957 | } | ||
| 2920 | 2958 | ||
| 2921 | if (err) { | 2959 | if (err) { |
| 2922 | dev_kfree_skb(skb); | 2960 | dev_kfree_skb(skb); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde24fd3..43e60b5a7546 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
| 917 | struct cfg80211_sched_scan_request *req) | 917 | struct cfg80211_sched_scan_request *req) |
| 918 | { | 918 | { |
| 919 | struct ieee80211_local *local = sdata->local; | 919 | struct ieee80211_local *local = sdata->local; |
| 920 | struct ieee80211_sched_scan_ies sched_scan_ies; | 920 | struct ieee80211_sched_scan_ies sched_scan_ies = {}; |
| 921 | int ret, i; | 921 | int ret, i; |
| 922 | 922 | ||
| 923 | mutex_lock(&local->mtx); | 923 | mutex_lock(&local->mtx); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0a4e4c04db89..d2eb64e12353 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk) | |||
| 117 | 117 | ||
| 118 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 118 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 119 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); | 119 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); |
| 120 | __skb_queue_purge(&sta->ps_tx_buf[ac]); | 120 | ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); |
| 121 | __skb_queue_purge(&sta->tx_filtered[ac]); | 121 | ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | #ifdef CONFIG_MAC80211_MESH | 124 | #ifdef CONFIG_MAC80211_MESH |
| @@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) | |||
| 141 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); | 141 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); |
| 142 | if (!tid_tx) | 142 | if (!tid_tx) |
| 143 | continue; | 143 | continue; |
| 144 | __skb_queue_purge(&tid_tx->pending); | 144 | ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); |
| 145 | kfree(tid_tx); | 145 | kfree(tid_tx); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| @@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 961 | struct ieee80211_local *local = sdata->local; | 961 | struct ieee80211_local *local = sdata->local; |
| 962 | struct sk_buff_head pending; | 962 | struct sk_buff_head pending; |
| 963 | int filtered = 0, buffered = 0, ac; | 963 | int filtered = 0, buffered = 0, ac; |
| 964 | unsigned long flags; | ||
| 964 | 965 | ||
| 965 | clear_sta_flag(sta, WLAN_STA_SP); | 966 | clear_sta_flag(sta, WLAN_STA_SP); |
| 966 | 967 | ||
| @@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 976 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 977 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 977 | int count = skb_queue_len(&pending), tmp; | 978 | int count = skb_queue_len(&pending), tmp; |
| 978 | 979 | ||
| 980 | spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); | ||
| 979 | skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); | 981 | skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); |
| 982 | spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); | ||
| 980 | tmp = skb_queue_len(&pending); | 983 | tmp = skb_queue_len(&pending); |
| 981 | filtered += tmp - count; | 984 | filtered += tmp - count; |
| 982 | count = tmp; | 985 | count = tmp; |
| 983 | 986 | ||
| 987 | spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); | ||
| 984 | skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); | 988 | skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); |
| 989 | spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); | ||
| 985 | tmp = skb_queue_len(&pending); | 990 | tmp = skb_queue_len(&pending); |
| 986 | buffered += tmp - count; | 991 | buffered += tmp - count; |
| 987 | } | 992 | } |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3af0cc4130f1..101eb88a2b78 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
| @@ -668,3 +668,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 668 | dev_kfree_skb_any(skb); | 668 | dev_kfree_skb_any(skb); |
| 669 | } | 669 | } |
| 670 | EXPORT_SYMBOL(ieee80211_free_txskb); | 670 | EXPORT_SYMBOL(ieee80211_free_txskb); |
| 671 | |||
| 672 | void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, | ||
| 673 | struct sk_buff_head *skbs) | ||
| 674 | { | ||
| 675 | struct sk_buff *skb; | ||
| 676 | |||
| 677 | while ((skb = __skb_dequeue(skbs))) | ||
| 678 | ieee80211_free_txskb(hw, skb); | ||
| 679 | } | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9bf83f36657..b858ebe41fda 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
| 1358 | if (tx->skb) | 1358 | if (tx->skb) |
| 1359 | ieee80211_free_txskb(&tx->local->hw, tx->skb); | 1359 | ieee80211_free_txskb(&tx->local->hw, tx->skb); |
| 1360 | else | 1360 | else |
| 1361 | __skb_queue_purge(&tx->skbs); | 1361 | ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); |
| 1362 | return -1; | 1362 | return -1; |
| 1363 | } else if (unlikely(res == TX_QUEUED)) { | 1363 | } else if (unlikely(res == TX_QUEUED)) { |
| 1364 | I802_DEBUG_INC(tx->local->tx_handlers_queued); | 1364 | I802_DEBUG_INC(tx->local->tx_handlers_queued); |
| @@ -2120,10 +2120,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 2120 | */ | 2120 | */ |
| 2121 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) | 2121 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) |
| 2122 | { | 2122 | { |
| 2123 | struct sk_buff *skb; | ||
| 2123 | int i; | 2124 | int i; |
| 2124 | 2125 | ||
| 2125 | for (i = 0; i < local->hw.queues; i++) | 2126 | for (i = 0; i < local->hw.queues; i++) { |
| 2126 | skb_queue_purge(&local->pending[i]); | 2127 | while ((skb = skb_dequeue(&local->pending[i])) != NULL) |
| 2128 | ieee80211_free_txskb(&local->hw, skb); | ||
| 2129 | } | ||
| 2127 | } | 2130 | } |
| 2128 | 2131 | ||
| 2129 | /* | 2132 | /* |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 94e586873979..0151ae33c4cd 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -643,13 +643,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 643 | break; | 643 | break; |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | if (id != WLAN_EID_VENDOR_SPECIFIC && | 646 | switch (id) { |
| 647 | id != WLAN_EID_QUIET && | 647 | case WLAN_EID_SSID: |
| 648 | test_bit(id, seen_elems)) { | 648 | case WLAN_EID_SUPP_RATES: |
| 649 | elems->parse_error = true; | 649 | case WLAN_EID_FH_PARAMS: |
| 650 | left -= elen; | 650 | case WLAN_EID_DS_PARAMS: |
| 651 | pos += elen; | 651 | case WLAN_EID_CF_PARAMS: |
| 652 | continue; | 652 | case WLAN_EID_TIM: |
| 653 | case WLAN_EID_IBSS_PARAMS: | ||
| 654 | case WLAN_EID_CHALLENGE: | ||
| 655 | case WLAN_EID_RSN: | ||
| 656 | case WLAN_EID_ERP_INFO: | ||
| 657 | case WLAN_EID_EXT_SUPP_RATES: | ||
| 658 | case WLAN_EID_HT_CAPABILITY: | ||
| 659 | case WLAN_EID_HT_OPERATION: | ||
| 660 | case WLAN_EID_VHT_CAPABILITY: | ||
| 661 | case WLAN_EID_VHT_OPERATION: | ||
| 662 | case WLAN_EID_MESH_ID: | ||
| 663 | case WLAN_EID_MESH_CONFIG: | ||
| 664 | case WLAN_EID_PEER_MGMT: | ||
| 665 | case WLAN_EID_PREQ: | ||
| 666 | case WLAN_EID_PREP: | ||
| 667 | case WLAN_EID_PERR: | ||
| 668 | case WLAN_EID_RANN: | ||
| 669 | case WLAN_EID_CHANNEL_SWITCH: | ||
| 670 | case WLAN_EID_EXT_CHANSWITCH_ANN: | ||
| 671 | case WLAN_EID_COUNTRY: | ||
| 672 | case WLAN_EID_PWR_CONSTRAINT: | ||
| 673 | case WLAN_EID_TIMEOUT_INTERVAL: | ||
| 674 | if (test_bit(id, seen_elems)) { | ||
| 675 | elems->parse_error = true; | ||
| 676 | left -= elen; | ||
| 677 | pos += elen; | ||
| 678 | continue; | ||
| 679 | } | ||
| 680 | break; | ||
| 653 | } | 681 | } |
| 654 | 682 | ||
| 655 | if (calc_crc && id < 64 && (filter & (1ULL << id))) | 683 | if (calc_crc && id < 64 && (filter & (1ULL << id))) |
| @@ -1463,6 +1491,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1463 | list_for_each_entry(sdata, &local->interfaces, list) { | 1491 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 1464 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1492 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 1465 | continue; | 1493 | continue; |
| 1494 | if (!sdata->u.mgd.associated) | ||
| 1495 | continue; | ||
| 1466 | 1496 | ||
| 1467 | ieee80211_send_nullfunc(local, sdata, 0); | 1497 | ieee80211_send_nullfunc(local, sdata, 0); |
| 1468 | } | 1498 | } |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 1b30b0dee708..962795e839ab 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -753,7 +753,8 @@ static int callforward_do_filter(const union nf_inet_addr *src, | |||
| 753 | flowi4_to_flowi(&fl1), false)) { | 753 | flowi4_to_flowi(&fl1), false)) { |
| 754 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, | 754 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
| 755 | flowi4_to_flowi(&fl2), false)) { | 755 | flowi4_to_flowi(&fl2), false)) { |
| 756 | if (rt1->rt_gateway == rt2->rt_gateway && | 756 | if (rt_nexthop(rt1, fl1.daddr) == |
| 757 | rt_nexthop(rt2, fl2.daddr) && | ||
| 757 | rt1->dst.dev == rt2->dst.dev) | 758 | rt1->dst.dev == rt2->dst.dev) |
| 758 | ret = 1; | 759 | ret = 1; |
| 759 | dst_release(&rt2->dst); | 760 | dst_release(&rt2->dst); |
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index f0dd83cff906..9687fa1c2275 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
| @@ -84,18 +84,19 @@ | |||
| 84 | * grp->index is the index of the group; and grp->slot_shift | 84 | * grp->index is the index of the group; and grp->slot_shift |
| 85 | * is the shift for the corresponding (scaled) sigma_i. | 85 | * is the shift for the corresponding (scaled) sigma_i. |
| 86 | */ | 86 | */ |
| 87 | #define QFQ_MAX_INDEX 19 | 87 | #define QFQ_MAX_INDEX 24 |
| 88 | #define QFQ_MAX_WSHIFT 16 | 88 | #define QFQ_MAX_WSHIFT 12 |
| 89 | 89 | ||
| 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) | 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) |
| 91 | #define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT) | 91 | #define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT) |
| 92 | 92 | ||
| 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ | 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ |
| 94 | #define ONE_FP (1UL << FRAC_BITS) | 94 | #define ONE_FP (1UL << FRAC_BITS) |
| 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) | 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) |
| 96 | 96 | ||
| 97 | #define QFQ_MTU_SHIFT 11 | 97 | #define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */ |
| 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) | 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) |
| 99 | #define QFQ_MIN_LMAX 256 /* min possible lmax for a class */ | ||
| 99 | 100 | ||
| 100 | /* | 101 | /* |
| 101 | * Possible group states. These values are used as indexes for the bitmaps | 102 | * Possible group states. These values are used as indexes for the bitmaps |
| @@ -231,6 +232,32 @@ static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl, | |||
| 231 | q->wsum += delta_w; | 232 | q->wsum += delta_w; |
| 232 | } | 233 | } |
| 233 | 234 | ||
| 235 | static void qfq_update_reactivate_class(struct qfq_sched *q, | ||
| 236 | struct qfq_class *cl, | ||
| 237 | u32 inv_w, u32 lmax, int delta_w) | ||
| 238 | { | ||
| 239 | bool need_reactivation = false; | ||
| 240 | int i = qfq_calc_index(inv_w, lmax); | ||
| 241 | |||
| 242 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | ||
| 243 | /* | ||
| 244 | * shift cl->F back, to not charge the | ||
| 245 | * class for the not-yet-served head | ||
| 246 | * packet | ||
| 247 | */ | ||
| 248 | cl->F = cl->S; | ||
| 249 | /* remove class from its slot in the old group */ | ||
| 250 | qfq_deactivate_class(q, cl); | ||
| 251 | need_reactivation = true; | ||
| 252 | } | ||
| 253 | |||
| 254 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 255 | |||
| 256 | if (need_reactivation) /* activate in new group */ | ||
| 257 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 234 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 261 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
| 235 | struct nlattr **tca, unsigned long *arg) | 262 | struct nlattr **tca, unsigned long *arg) |
| 236 | { | 263 | { |
| @@ -238,7 +265,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 238 | struct qfq_class *cl = (struct qfq_class *)*arg; | 265 | struct qfq_class *cl = (struct qfq_class *)*arg; |
| 239 | struct nlattr *tb[TCA_QFQ_MAX + 1]; | 266 | struct nlattr *tb[TCA_QFQ_MAX + 1]; |
| 240 | u32 weight, lmax, inv_w; | 267 | u32 weight, lmax, inv_w; |
| 241 | int i, err; | 268 | int err; |
| 242 | int delta_w; | 269 | int delta_w; |
| 243 | 270 | ||
| 244 | if (tca[TCA_OPTIONS] == NULL) { | 271 | if (tca[TCA_OPTIONS] == NULL) { |
| @@ -270,16 +297,14 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 270 | 297 | ||
| 271 | if (tb[TCA_QFQ_LMAX]) { | 298 | if (tb[TCA_QFQ_LMAX]) { |
| 272 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); | 299 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); |
| 273 | if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { | 300 | if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { |
| 274 | pr_notice("qfq: invalid max length %u\n", lmax); | 301 | pr_notice("qfq: invalid max length %u\n", lmax); |
| 275 | return -EINVAL; | 302 | return -EINVAL; |
| 276 | } | 303 | } |
| 277 | } else | 304 | } else |
| 278 | lmax = 1UL << QFQ_MTU_SHIFT; | 305 | lmax = psched_mtu(qdisc_dev(sch)); |
| 279 | 306 | ||
| 280 | if (cl != NULL) { | 307 | if (cl != NULL) { |
| 281 | bool need_reactivation = false; | ||
| 282 | |||
| 283 | if (tca[TCA_RATE]) { | 308 | if (tca[TCA_RATE]) { |
| 284 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, | 309 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, |
| 285 | qdisc_root_sleeping_lock(sch), | 310 | qdisc_root_sleeping_lock(sch), |
| @@ -291,24 +316,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 291 | if (lmax == cl->lmax && inv_w == cl->inv_w) | 316 | if (lmax == cl->lmax && inv_w == cl->inv_w) |
| 292 | return 0; /* nothing to update */ | 317 | return 0; /* nothing to update */ |
| 293 | 318 | ||
| 294 | i = qfq_calc_index(inv_w, lmax); | ||
| 295 | sch_tree_lock(sch); | 319 | sch_tree_lock(sch); |
| 296 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | 320 | qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); |
| 297 | /* | ||
| 298 | * shift cl->F back, to not charge the | ||
| 299 | * class for the not-yet-served head | ||
| 300 | * packet | ||
| 301 | */ | ||
| 302 | cl->F = cl->S; | ||
| 303 | /* remove class from its slot in the old group */ | ||
| 304 | qfq_deactivate_class(q, cl); | ||
| 305 | need_reactivation = true; | ||
| 306 | } | ||
| 307 | |||
| 308 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 309 | |||
| 310 | if (need_reactivation) /* activate in new group */ | ||
| 311 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 312 | sch_tree_unlock(sch); | 321 | sch_tree_unlock(sch); |
| 313 | 322 | ||
| 314 | return 0; | 323 | return 0; |
| @@ -663,15 +672,48 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) | |||
| 663 | 672 | ||
| 664 | 673 | ||
| 665 | /* | 674 | /* |
| 666 | * XXX we should make sure that slot becomes less than 32. | 675 | * If the weight and lmax (max_pkt_size) of the classes do not change, |
| 667 | * This is guaranteed by the input values. | 676 | * then QFQ guarantees that the slot index is never higher than |
| 668 | * roundedS is always cl->S rounded on grp->slot_shift bits. | 677 | * 2 + ((1<<QFQ_MTU_SHIFT)/QFQ_MIN_LMAX) * (QFQ_MAX_WEIGHT/QFQ_MAX_WSUM). |
| 678 | * | ||
| 679 | * With the current values of the above constants, the index is | ||
| 680 | * then guaranteed to never be higher than 2 + 256 * (1 / 16) = 18. | ||
| 681 | * | ||
| 682 | * When the weight of a class is increased or the lmax of the class is | ||
| 683 | * decreased, a new class with smaller slot size may happen to be | ||
| 684 | * activated. The activation of this class should be properly delayed | ||
| 685 | * to when the service of the class has finished in the ideal system | ||
| 686 | * tracked by QFQ. If the activation of the class is not delayed to | ||
| 687 | * this reference time instant, then this class may be unjustly served | ||
| 688 | * before other classes waiting for service. This may cause | ||
| 689 | * (unfrequently) the above bound to the slot index to be violated for | ||
| 690 | * some of these unlucky classes. | ||
| 691 | * | ||
| 692 | * Instead of delaying the activation of the new class, which is quite | ||
| 693 | * complex, the following inaccurate but simple solution is used: if | ||
| 694 | * the slot index is higher than QFQ_MAX_SLOTS-2, then the timestamps | ||
| 695 | * of the class are shifted backward so as to let the slot index | ||
| 696 | * become equal to QFQ_MAX_SLOTS-2. This threshold is used because, if | ||
| 697 | * the slot index is above it, then the data structure implementing | ||
| 698 | * the bucket list either gets immediately corrupted or may get | ||
| 699 | * corrupted on a possible next packet arrival that causes the start | ||
| 700 | * time of the group to be shifted backward. | ||
| 669 | */ | 701 | */ |
| 670 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, | 702 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, |
| 671 | u64 roundedS) | 703 | u64 roundedS) |
| 672 | { | 704 | { |
| 673 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; | 705 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; |
| 674 | unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; | 706 | unsigned int i; /* slot index in the bucket list */ |
| 707 | |||
| 708 | if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { | ||
| 709 | u64 deltaS = roundedS - grp->S - | ||
| 710 | ((u64)(QFQ_MAX_SLOTS - 2)<<grp->slot_shift); | ||
| 711 | cl->S -= deltaS; | ||
| 712 | cl->F -= deltaS; | ||
| 713 | slot = QFQ_MAX_SLOTS - 2; | ||
| 714 | } | ||
| 715 | |||
| 716 | i = (grp->front + slot) % QFQ_MAX_SLOTS; | ||
| 675 | 717 | ||
| 676 | hlist_add_head(&cl->next, &grp->slots[i]); | 718 | hlist_add_head(&cl->next, &grp->slots[i]); |
| 677 | __set_bit(slot, &grp->full_slots); | 719 | __set_bit(slot, &grp->full_slots); |
| @@ -892,6 +934,13 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 892 | } | 934 | } |
| 893 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); | 935 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); |
| 894 | 936 | ||
| 937 | if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { | ||
| 938 | pr_debug("qfq: increasing maxpkt from %u to %u for class %u", | ||
| 939 | cl->lmax, qdisc_pkt_len(skb), cl->common.classid); | ||
| 940 | qfq_update_reactivate_class(q, cl, cl->inv_w, | ||
| 941 | qdisc_pkt_len(skb), 0); | ||
| 942 | } | ||
| 943 | |||
| 895 | err = qdisc_enqueue(skb, cl->qdisc); | 944 | err = qdisc_enqueue(skb, cl->qdisc); |
| 896 | if (unlikely(err != NET_XMIT_SUCCESS)) { | 945 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
| 897 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); | 946 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea269faf4..9966e7b16451 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { | |||
| 102 | .open = sctp_snmp_seq_open, | 102 | .open = sctp_snmp_seq_open, |
| 103 | .read = seq_read, | 103 | .read = seq_read, |
| 104 | .llseek = seq_lseek, | 104 | .llseek = seq_lseek, |
| 105 | .release = single_release, | 105 | .release = single_release_net, |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | /* Set up the proc fs entry for 'snmp' object. */ | 108 | /* Set up the proc fs entry for 'snmp' object. */ |
| @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { | |||
| 251 | .open = sctp_eps_seq_open, | 251 | .open = sctp_eps_seq_open, |
| 252 | .read = seq_read, | 252 | .read = seq_read, |
| 253 | .llseek = seq_lseek, | 253 | .llseek = seq_lseek, |
| 254 | .release = seq_release, | 254 | .release = seq_release_net, |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | /* Set up the proc fs entry for 'eps' object. */ | 257 | /* Set up the proc fs entry for 'eps' object. */ |
| @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { | |||
| 372 | .open = sctp_assocs_seq_open, | 372 | .open = sctp_assocs_seq_open, |
| 373 | .read = seq_read, | 373 | .read = seq_read, |
| 374 | .llseek = seq_lseek, | 374 | .llseek = seq_lseek, |
| 375 | .release = seq_release, | 375 | .release = seq_release_net, |
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | /* Set up the proc fs entry for 'assocs' object. */ | 378 | /* Set up the proc fs entry for 'assocs' object. */ |
| @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { | |||
| 517 | .open = sctp_remaddr_seq_open, | 517 | .open = sctp_remaddr_seq_open, |
| 518 | .read = seq_read, | 518 | .read = seq_read, |
| 519 | .llseek = seq_lseek, | 519 | .llseek = seq_lseek, |
| 520 | .release = seq_release, | 520 | .release = seq_release_net, |
| 521 | }; | 521 | }; |
| 522 | 522 | ||
| 523 | int __net_init sctp_remaddr_proc_init(struct net *net) | 523 | int __net_init sctp_remaddr_proc_init(struct net *net) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 59d16ea927f0..a60d1f8b41c5 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -974,7 +974,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
| 974 | void *addr_buf; | 974 | void *addr_buf; |
| 975 | struct sctp_af *af; | 975 | struct sctp_af *af; |
| 976 | 976 | ||
| 977 | SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" | 977 | SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p" |
| 978 | " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); | 978 | " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); |
| 979 | 979 | ||
| 980 | if (unlikely(addrs_size <= 0)) | 980 | if (unlikely(addrs_size <= 0)) |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 5a3d675d2f2f..a9c0bbccad6b 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
| @@ -172,7 +172,7 @@ out_free: | |||
| 172 | xprt_free_allocation(req); | 172 | xprt_free_allocation(req); |
| 173 | 173 | ||
| 174 | dprintk("RPC: setup backchannel transport failed\n"); | 174 | dprintk("RPC: setup backchannel transport failed\n"); |
| 175 | return -1; | 175 | return -ENOMEM; |
| 176 | } | 176 | } |
| 177 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); | 177 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); |
| 178 | 178 | ||
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index 111ff8300ae5..b36f0fcd9bdf 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -116,7 +116,6 @@ void tipc_handler_stop(void) | |||
| 116 | return; | 116 | return; |
| 117 | 117 | ||
| 118 | handler_enabled = 0; | 118 | handler_enabled = 0; |
| 119 | tasklet_disable(&tipc_tasklet); | ||
| 120 | tasklet_kill(&tipc_tasklet); | 119 | tasklet_kill(&tipc_tasklet); |
| 121 | 120 | ||
| 122 | spin_lock_bh(&qitem_lock); | 121 | spin_lock_bh(&qitem_lock); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 443d4d7deea2..3f7253052088 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -526,8 +526,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 526 | for (i = 0; i < sband->n_channels; i++) { | 526 | for (i = 0; i < sband->n_channels; i++) { |
| 527 | sband->channels[i].orig_flags = | 527 | sband->channels[i].orig_flags = |
| 528 | sband->channels[i].flags; | 528 | sband->channels[i].flags; |
| 529 | sband->channels[i].orig_mag = | 529 | sband->channels[i].orig_mag = INT_MAX; |
| 530 | sband->channels[i].max_antenna_gain; | ||
| 531 | sband->channels[i].orig_mpwr = | 530 | sband->channels[i].orig_mpwr = |
| 532 | sband->channels[i].max_power; | 531 | sband->channels[i].max_power; |
| 533 | sband->channels[i].band = band; | 532 | sband->channels[i].band = band; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3b8cbbc214db..b75756b05af7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = { | |||
| 141 | .reg_rules = { | 141 | .reg_rules = { |
| 142 | /* IEEE 802.11b/g, channels 1..11 */ | 142 | /* IEEE 802.11b/g, channels 1..11 */ |
| 143 | REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), | 143 | REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), |
| 144 | /* IEEE 802.11b/g, channels 12..13. No HT40 | 144 | /* IEEE 802.11b/g, channels 12..13. */ |
| 145 | * channel fits here. */ | 145 | REG_RULE(2467-10, 2472+10, 40, 6, 20, |
| 146 | REG_RULE(2467-10, 2472+10, 20, 6, 20, | ||
| 147 | NL80211_RRF_PASSIVE_SCAN | | 146 | NL80211_RRF_PASSIVE_SCAN | |
| 148 | NL80211_RRF_NO_IBSS), | 147 | NL80211_RRF_NO_IBSS), |
| 149 | /* IEEE 802.11 channel 14 - Only JP enables | 148 | /* IEEE 802.11 channel 14 - Only JP enables |
| @@ -908,7 +907,7 @@ static void handle_channel(struct wiphy *wiphy, | |||
| 908 | map_regdom_flags(reg_rule->flags) | bw_flags; | 907 | map_regdom_flags(reg_rule->flags) | bw_flags; |
| 909 | chan->max_antenna_gain = chan->orig_mag = | 908 | chan->max_antenna_gain = chan->orig_mag = |
| 910 | (int) MBI_TO_DBI(power_rule->max_antenna_gain); | 909 | (int) MBI_TO_DBI(power_rule->max_antenna_gain); |
| 911 | chan->max_power = chan->orig_mpwr = | 910 | chan->max_reg_power = chan->max_power = chan->orig_mpwr = |
| 912 | (int) MBM_TO_DBM(power_rule->max_eirp); | 911 | (int) MBM_TO_DBM(power_rule->max_eirp); |
| 913 | return; | 912 | return; |
| 914 | } | 913 | } |
| @@ -1331,7 +1330,8 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
| 1331 | 1330 | ||
| 1332 | chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; | 1331 | chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; |
| 1333 | chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); | 1332 | chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); |
| 1334 | chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); | 1333 | chan->max_reg_power = chan->max_power = |
| 1334 | (int) MBM_TO_DBM(power_rule->max_eirp); | ||
| 1335 | } | 1335 | } |
| 1336 | 1336 | ||
| 1337 | static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, | 1337 | static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index ef35f4ef2aa6..2762e8329986 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -309,23 +309,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | |||
| 309 | } | 309 | } |
| 310 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); | 310 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); |
| 311 | 311 | ||
| 312 | static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | 312 | unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) |
| 313 | { | 313 | { |
| 314 | int ae = meshhdr->flags & MESH_FLAGS_AE; | 314 | int ae = meshhdr->flags & MESH_FLAGS_AE; |
| 315 | /* 7.1.3.5a.2 */ | 315 | /* 802.11-2012, 8.2.4.7.3 */ |
| 316 | switch (ae) { | 316 | switch (ae) { |
| 317 | default: | ||
| 317 | case 0: | 318 | case 0: |
| 318 | return 6; | 319 | return 6; |
| 319 | case MESH_FLAGS_AE_A4: | 320 | case MESH_FLAGS_AE_A4: |
| 320 | return 12; | 321 | return 12; |
| 321 | case MESH_FLAGS_AE_A5_A6: | 322 | case MESH_FLAGS_AE_A5_A6: |
| 322 | return 18; | 323 | return 18; |
| 323 | case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): | ||
| 324 | return 24; | ||
| 325 | default: | ||
| 326 | return 6; | ||
| 327 | } | 324 | } |
| 328 | } | 325 | } |
| 326 | EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); | ||
| 329 | 327 | ||
| 330 | int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | 328 | int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, |
| 331 | enum nl80211_iftype iftype) | 329 | enum nl80211_iftype iftype) |
| @@ -373,6 +371,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
| 373 | /* make sure meshdr->flags is on the linear part */ | 371 | /* make sure meshdr->flags is on the linear part */ |
| 374 | if (!pskb_may_pull(skb, hdrlen + 1)) | 372 | if (!pskb_may_pull(skb, hdrlen + 1)) |
| 375 | return -1; | 373 | return -1; |
| 374 | if (meshdr->flags & MESH_FLAGS_AE_A4) | ||
| 375 | return -1; | ||
| 376 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { | 376 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { |
| 377 | skb_copy_bits(skb, hdrlen + | 377 | skb_copy_bits(skb, hdrlen + |
| 378 | offsetof(struct ieee80211s_hdr, eaddr1), | 378 | offsetof(struct ieee80211s_hdr, eaddr1), |
| @@ -397,6 +397,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
| 397 | /* make sure meshdr->flags is on the linear part */ | 397 | /* make sure meshdr->flags is on the linear part */ |
| 398 | if (!pskb_may_pull(skb, hdrlen + 1)) | 398 | if (!pskb_may_pull(skb, hdrlen + 1)) |
| 399 | return -1; | 399 | return -1; |
| 400 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) | ||
| 401 | return -1; | ||
| 400 | if (meshdr->flags & MESH_FLAGS_AE_A4) | 402 | if (meshdr->flags & MESH_FLAGS_AE_A4) |
| 401 | skb_copy_bits(skb, hdrlen + | 403 | skb_copy_bits(skb, hdrlen + |
| 402 | offsetof(struct ieee80211s_hdr, eaddr1), | 404 | offsetof(struct ieee80211s_hdr, eaddr1), |
