diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-07-28 04:03:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-07-28 04:03:00 -0400 |
commit | ca5bc6cd5de5b53eb8fd6fea39aa3fe2a1e8c3d9 (patch) | |
tree | 75beaae2d4b6bc654eb28994dd5906d8dcf5ef46 /net | |
parent | c1221321b7c25b53204447cff9949a6d5a7ddddc (diff) | |
parent | d8d28c8f00e84a72e8bee39a85835635417bee49 (diff) |
Merge branch 'sched/urgent' into sched/core, to merge fixes before applying new changes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net')
46 files changed, 474 insertions, 309 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index ad2ac3c00398..dd11f612e03e 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -627,8 +627,6 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
627 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 627 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); |
628 | int i; | 628 | int i; |
629 | 629 | ||
630 | free_percpu(vlan->vlan_pcpu_stats); | ||
631 | vlan->vlan_pcpu_stats = NULL; | ||
632 | for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { | 630 | for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { |
633 | while ((pm = vlan->egress_priority_map[i]) != NULL) { | 631 | while ((pm = vlan->egress_priority_map[i]) != NULL) { |
634 | vlan->egress_priority_map[i] = pm->next; | 632 | vlan->egress_priority_map[i] = pm->next; |
@@ -785,6 +783,15 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
785 | .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, | 783 | .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, |
786 | }; | 784 | }; |
787 | 785 | ||
786 | static void vlan_dev_free(struct net_device *dev) | ||
787 | { | ||
788 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | ||
789 | |||
790 | free_percpu(vlan->vlan_pcpu_stats); | ||
791 | vlan->vlan_pcpu_stats = NULL; | ||
792 | free_netdev(dev); | ||
793 | } | ||
794 | |||
788 | void vlan_setup(struct net_device *dev) | 795 | void vlan_setup(struct net_device *dev) |
789 | { | 796 | { |
790 | ether_setup(dev); | 797 | ether_setup(dev); |
@@ -794,7 +801,7 @@ void vlan_setup(struct net_device *dev) | |||
794 | dev->tx_queue_len = 0; | 801 | dev->tx_queue_len = 0; |
795 | 802 | ||
796 | dev->netdev_ops = &vlan_netdev_ops; | 803 | dev->netdev_ops = &vlan_netdev_ops; |
797 | dev->destructor = free_netdev; | 804 | dev->destructor = vlan_dev_free; |
798 | dev->ethtool_ops = &vlan_ethtool_ops; | 805 | dev->ethtool_ops = &vlan_ethtool_ops; |
799 | 806 | ||
800 | memset(dev->broadcast, 0, ETH_ALEN); | 807 | memset(dev->broadcast, 0, ETH_ALEN); |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 01a1082e02b3..bfcf6be1d665 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -1489,8 +1489,6 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, | |||
1489 | goto drop; | 1489 | goto drop; |
1490 | 1490 | ||
1491 | /* Queue packet (standard) */ | 1491 | /* Queue packet (standard) */ |
1492 | skb->sk = sock; | ||
1493 | |||
1494 | if (sock_queue_rcv_skb(sock, skb) < 0) | 1492 | if (sock_queue_rcv_skb(sock, skb) < 0) |
1495 | goto drop; | 1493 | goto drop; |
1496 | 1494 | ||
@@ -1644,7 +1642,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
1644 | if (!skb) | 1642 | if (!skb) |
1645 | goto out; | 1643 | goto out; |
1646 | 1644 | ||
1647 | skb->sk = sk; | ||
1648 | skb_reserve(skb, ddp_dl->header_length); | 1645 | skb_reserve(skb, ddp_dl->header_length); |
1649 | skb_reserve(skb, dev->hard_header_len); | 1646 | skb_reserve(skb, dev->hard_header_len); |
1650 | skb->dev = dev; | 1647 | skb->dev = dev; |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 6f0d9ec37950..a957c8140721 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -800,11 +800,6 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, | |||
800 | bla_dst = (struct batadv_bla_claim_dst *)hw_dst; | 800 | bla_dst = (struct batadv_bla_claim_dst *)hw_dst; |
801 | bla_dst_own = &bat_priv->bla.claim_dest; | 801 | bla_dst_own = &bat_priv->bla.claim_dest; |
802 | 802 | ||
803 | /* check if it is a claim packet in general */ | ||
804 | if (memcmp(bla_dst->magic, bla_dst_own->magic, | ||
805 | sizeof(bla_dst->magic)) != 0) | ||
806 | return 0; | ||
807 | |||
808 | /* if announcement packet, use the source, | 803 | /* if announcement packet, use the source, |
809 | * otherwise assume it is in the hw_src | 804 | * otherwise assume it is in the hw_src |
810 | */ | 805 | */ |
@@ -866,12 +861,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
866 | struct batadv_hard_iface *primary_if, | 861 | struct batadv_hard_iface *primary_if, |
867 | struct sk_buff *skb) | 862 | struct sk_buff *skb) |
868 | { | 863 | { |
869 | struct batadv_bla_claim_dst *bla_dst; | 864 | struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; |
870 | uint8_t *hw_src, *hw_dst; | 865 | uint8_t *hw_src, *hw_dst; |
871 | struct vlan_ethhdr *vhdr; | 866 | struct vlan_hdr *vhdr, vhdr_buf; |
872 | struct ethhdr *ethhdr; | 867 | struct ethhdr *ethhdr; |
873 | struct arphdr *arphdr; | 868 | struct arphdr *arphdr; |
874 | unsigned short vid; | 869 | unsigned short vid; |
870 | int vlan_depth = 0; | ||
875 | __be16 proto; | 871 | __be16 proto; |
876 | int headlen; | 872 | int headlen; |
877 | int ret; | 873 | int ret; |
@@ -882,9 +878,24 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
882 | proto = ethhdr->h_proto; | 878 | proto = ethhdr->h_proto; |
883 | headlen = ETH_HLEN; | 879 | headlen = ETH_HLEN; |
884 | if (vid & BATADV_VLAN_HAS_TAG) { | 880 | if (vid & BATADV_VLAN_HAS_TAG) { |
885 | vhdr = vlan_eth_hdr(skb); | 881 | /* Traverse the VLAN/Ethertypes. |
886 | proto = vhdr->h_vlan_encapsulated_proto; | 882 | * |
887 | headlen += VLAN_HLEN; | 883 | * At this point it is known that the first protocol is a VLAN |
884 | * header, so start checking at the encapsulated protocol. | ||
885 | * | ||
886 | * The depth of the VLAN headers is recorded to drop BLA claim | ||
887 | * frames encapsulated into multiple VLAN headers (QinQ). | ||
888 | */ | ||
889 | do { | ||
890 | vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN, | ||
891 | &vhdr_buf); | ||
892 | if (!vhdr) | ||
893 | return 0; | ||
894 | |||
895 | proto = vhdr->h_vlan_encapsulated_proto; | ||
896 | headlen += VLAN_HLEN; | ||
897 | vlan_depth++; | ||
898 | } while (proto == htons(ETH_P_8021Q)); | ||
888 | } | 899 | } |
889 | 900 | ||
890 | if (proto != htons(ETH_P_ARP)) | 901 | if (proto != htons(ETH_P_ARP)) |
@@ -914,6 +925,19 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
914 | hw_src = (uint8_t *)arphdr + sizeof(struct arphdr); | 925 | hw_src = (uint8_t *)arphdr + sizeof(struct arphdr); |
915 | hw_dst = hw_src + ETH_ALEN + 4; | 926 | hw_dst = hw_src + ETH_ALEN + 4; |
916 | bla_dst = (struct batadv_bla_claim_dst *)hw_dst; | 927 | bla_dst = (struct batadv_bla_claim_dst *)hw_dst; |
928 | bla_dst_own = &bat_priv->bla.claim_dest; | ||
929 | |||
930 | /* check if it is a claim frame in general */ | ||
931 | if (memcmp(bla_dst->magic, bla_dst_own->magic, | ||
932 | sizeof(bla_dst->magic)) != 0) | ||
933 | return 0; | ||
934 | |||
935 | /* check if there is a claim frame encapsulated deeper in (QinQ) and | ||
936 | * drop that, as this is not supported by BLA but should also not be | ||
937 | * sent via the mesh. | ||
938 | */ | ||
939 | if (vlan_depth > 1) | ||
940 | return 1; | ||
917 | 941 | ||
918 | /* check if it is a claim frame. */ | 942 | /* check if it is a claim frame. */ |
919 | ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, | 943 | ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index e7ee65dc20bf..cbd677f48c00 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -448,10 +448,15 @@ out: | |||
448 | * possibly free it | 448 | * possibly free it |
449 | * @softif_vlan: the vlan object to release | 449 | * @softif_vlan: the vlan object to release |
450 | */ | 450 | */ |
451 | void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan) | 451 | void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *vlan) |
452 | { | 452 | { |
453 | if (atomic_dec_and_test(&softif_vlan->refcount)) | 453 | if (atomic_dec_and_test(&vlan->refcount)) { |
454 | kfree_rcu(softif_vlan, rcu); | 454 | spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock); |
455 | hlist_del_rcu(&vlan->list); | ||
456 | spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); | ||
457 | |||
458 | kfree_rcu(vlan, rcu); | ||
459 | } | ||
455 | } | 460 | } |
456 | 461 | ||
457 | /** | 462 | /** |
@@ -505,6 +510,7 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | |||
505 | if (!vlan) | 510 | if (!vlan) |
506 | return -ENOMEM; | 511 | return -ENOMEM; |
507 | 512 | ||
513 | vlan->bat_priv = bat_priv; | ||
508 | vlan->vid = vid; | 514 | vlan->vid = vid; |
509 | atomic_set(&vlan->refcount, 1); | 515 | atomic_set(&vlan->refcount, 1); |
510 | 516 | ||
@@ -516,6 +522,10 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | |||
516 | return err; | 522 | return err; |
517 | } | 523 | } |
518 | 524 | ||
525 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
526 | hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); | ||
527 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
528 | |||
519 | /* add a new TT local entry. This one will be marked with the NOPURGE | 529 | /* add a new TT local entry. This one will be marked with the NOPURGE |
520 | * flag | 530 | * flag |
521 | */ | 531 | */ |
@@ -523,10 +533,6 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | |||
523 | bat_priv->soft_iface->dev_addr, vid, | 533 | bat_priv->soft_iface->dev_addr, vid, |
524 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); | 534 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); |
525 | 535 | ||
526 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
527 | hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); | ||
528 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
529 | |||
530 | return 0; | 536 | return 0; |
531 | } | 537 | } |
532 | 538 | ||
@@ -538,18 +544,13 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | |||
538 | static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, | 544 | static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, |
539 | struct batadv_softif_vlan *vlan) | 545 | struct batadv_softif_vlan *vlan) |
540 | { | 546 | { |
541 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
542 | hlist_del_rcu(&vlan->list); | ||
543 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
544 | |||
545 | batadv_sysfs_del_vlan(bat_priv, vlan); | ||
546 | |||
547 | /* explicitly remove the associated TT local entry because it is marked | 547 | /* explicitly remove the associated TT local entry because it is marked |
548 | * with the NOPURGE flag | 548 | * with the NOPURGE flag |
549 | */ | 549 | */ |
550 | batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, | 550 | batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, |
551 | vlan->vid, "vlan interface destroyed", false); | 551 | vlan->vid, "vlan interface destroyed", false); |
552 | 552 | ||
553 | batadv_sysfs_del_vlan(bat_priv, vlan); | ||
553 | batadv_softif_vlan_free_ref(vlan); | 554 | batadv_softif_vlan_free_ref(vlan); |
554 | } | 555 | } |
555 | 556 | ||
@@ -567,6 +568,8 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, | |||
567 | unsigned short vid) | 568 | unsigned short vid) |
568 | { | 569 | { |
569 | struct batadv_priv *bat_priv = netdev_priv(dev); | 570 | struct batadv_priv *bat_priv = netdev_priv(dev); |
571 | struct batadv_softif_vlan *vlan; | ||
572 | int ret; | ||
570 | 573 | ||
571 | /* only 802.1Q vlans are supported. | 574 | /* only 802.1Q vlans are supported. |
572 | * batman-adv does not know how to handle other types | 575 | * batman-adv does not know how to handle other types |
@@ -576,7 +579,36 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, | |||
576 | 579 | ||
577 | vid |= BATADV_VLAN_HAS_TAG; | 580 | vid |= BATADV_VLAN_HAS_TAG; |
578 | 581 | ||
579 | return batadv_softif_create_vlan(bat_priv, vid); | 582 | /* if a new vlan is getting created and it already exists, it means that |
583 | * it was not deleted yet. batadv_softif_vlan_get() increases the | ||
584 | * refcount in order to revive the object. | ||
585 | * | ||
586 | * if it does not exist then create it. | ||
587 | */ | ||
588 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
589 | if (!vlan) | ||
590 | return batadv_softif_create_vlan(bat_priv, vid); | ||
591 | |||
592 | /* recreate the sysfs object if it was already destroyed (and it should | ||
593 | * be since we received a kill_vid() for this vlan | ||
594 | */ | ||
595 | if (!vlan->kobj) { | ||
596 | ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); | ||
597 | if (ret) { | ||
598 | batadv_softif_vlan_free_ref(vlan); | ||
599 | return ret; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* add a new TT local entry. This one will be marked with the NOPURGE | ||
604 | * flag. This must be added again, even if the vlan object already | ||
605 | * exists, because the entry was deleted by kill_vid() | ||
606 | */ | ||
607 | batadv_tt_local_add(bat_priv->soft_iface, | ||
608 | bat_priv->soft_iface->dev_addr, vid, | ||
609 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); | ||
610 | |||
611 | return 0; | ||
580 | } | 612 | } |
581 | 613 | ||
582 | /** | 614 | /** |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index d636bde72c9a..5f59e7f899a0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -511,6 +511,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | |||
511 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 511 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
512 | struct batadv_tt_local_entry *tt_local; | 512 | struct batadv_tt_local_entry *tt_local; |
513 | struct batadv_tt_global_entry *tt_global = NULL; | 513 | struct batadv_tt_global_entry *tt_global = NULL; |
514 | struct batadv_softif_vlan *vlan; | ||
514 | struct net_device *in_dev = NULL; | 515 | struct net_device *in_dev = NULL; |
515 | struct hlist_head *head; | 516 | struct hlist_head *head; |
516 | struct batadv_tt_orig_list_entry *orig_entry; | 517 | struct batadv_tt_orig_list_entry *orig_entry; |
@@ -572,6 +573,9 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | |||
572 | if (!tt_local) | 573 | if (!tt_local) |
573 | goto out; | 574 | goto out; |
574 | 575 | ||
576 | /* increase the refcounter of the related vlan */ | ||
577 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
578 | |||
575 | batadv_dbg(BATADV_DBG_TT, bat_priv, | 579 | batadv_dbg(BATADV_DBG_TT, bat_priv, |
576 | "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n", | 580 | "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n", |
577 | addr, BATADV_PRINT_VID(vid), | 581 | addr, BATADV_PRINT_VID(vid), |
@@ -604,6 +608,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | |||
604 | if (unlikely(hash_added != 0)) { | 608 | if (unlikely(hash_added != 0)) { |
605 | /* remove the reference for the hash */ | 609 | /* remove the reference for the hash */ |
606 | batadv_tt_local_entry_free_ref(tt_local); | 610 | batadv_tt_local_entry_free_ref(tt_local); |
611 | batadv_softif_vlan_free_ref(vlan); | ||
607 | goto out; | 612 | goto out; |
608 | } | 613 | } |
609 | 614 | ||
@@ -1009,6 +1014,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | |||
1009 | { | 1014 | { |
1010 | struct batadv_tt_local_entry *tt_local_entry; | 1015 | struct batadv_tt_local_entry *tt_local_entry; |
1011 | uint16_t flags, curr_flags = BATADV_NO_FLAGS; | 1016 | uint16_t flags, curr_flags = BATADV_NO_FLAGS; |
1017 | struct batadv_softif_vlan *vlan; | ||
1012 | 1018 | ||
1013 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); | 1019 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); |
1014 | if (!tt_local_entry) | 1020 | if (!tt_local_entry) |
@@ -1039,6 +1045,11 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | |||
1039 | hlist_del_rcu(&tt_local_entry->common.hash_entry); | 1045 | hlist_del_rcu(&tt_local_entry->common.hash_entry); |
1040 | batadv_tt_local_entry_free_ref(tt_local_entry); | 1046 | batadv_tt_local_entry_free_ref(tt_local_entry); |
1041 | 1047 | ||
1048 | /* decrease the reference held for this vlan */ | ||
1049 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
1050 | batadv_softif_vlan_free_ref(vlan); | ||
1051 | batadv_softif_vlan_free_ref(vlan); | ||
1052 | |||
1042 | out: | 1053 | out: |
1043 | if (tt_local_entry) | 1054 | if (tt_local_entry) |
1044 | batadv_tt_local_entry_free_ref(tt_local_entry); | 1055 | batadv_tt_local_entry_free_ref(tt_local_entry); |
@@ -1111,6 +1122,7 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) | |||
1111 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 1122 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
1112 | struct batadv_tt_common_entry *tt_common_entry; | 1123 | struct batadv_tt_common_entry *tt_common_entry; |
1113 | struct batadv_tt_local_entry *tt_local; | 1124 | struct batadv_tt_local_entry *tt_local; |
1125 | struct batadv_softif_vlan *vlan; | ||
1114 | struct hlist_node *node_tmp; | 1126 | struct hlist_node *node_tmp; |
1115 | struct hlist_head *head; | 1127 | struct hlist_head *head; |
1116 | uint32_t i; | 1128 | uint32_t i; |
@@ -1131,6 +1143,13 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) | |||
1131 | tt_local = container_of(tt_common_entry, | 1143 | tt_local = container_of(tt_common_entry, |
1132 | struct batadv_tt_local_entry, | 1144 | struct batadv_tt_local_entry, |
1133 | common); | 1145 | common); |
1146 | |||
1147 | /* decrease the reference held for this vlan */ | ||
1148 | vlan = batadv_softif_vlan_get(bat_priv, | ||
1149 | tt_common_entry->vid); | ||
1150 | batadv_softif_vlan_free_ref(vlan); | ||
1151 | batadv_softif_vlan_free_ref(vlan); | ||
1152 | |||
1134 | batadv_tt_local_entry_free_ref(tt_local); | 1153 | batadv_tt_local_entry_free_ref(tt_local); |
1135 | } | 1154 | } |
1136 | spin_unlock_bh(list_lock); | 1155 | spin_unlock_bh(list_lock); |
@@ -3139,6 +3158,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) | |||
3139 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; | 3158 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; |
3140 | struct batadv_tt_common_entry *tt_common; | 3159 | struct batadv_tt_common_entry *tt_common; |
3141 | struct batadv_tt_local_entry *tt_local; | 3160 | struct batadv_tt_local_entry *tt_local; |
3161 | struct batadv_softif_vlan *vlan; | ||
3142 | struct hlist_node *node_tmp; | 3162 | struct hlist_node *node_tmp; |
3143 | struct hlist_head *head; | 3163 | struct hlist_head *head; |
3144 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 3164 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
@@ -3167,6 +3187,12 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) | |||
3167 | tt_local = container_of(tt_common, | 3187 | tt_local = container_of(tt_common, |
3168 | struct batadv_tt_local_entry, | 3188 | struct batadv_tt_local_entry, |
3169 | common); | 3189 | common); |
3190 | |||
3191 | /* decrease the reference held for this vlan */ | ||
3192 | vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); | ||
3193 | batadv_softif_vlan_free_ref(vlan); | ||
3194 | batadv_softif_vlan_free_ref(vlan); | ||
3195 | |||
3170 | batadv_tt_local_entry_free_ref(tt_local); | 3196 | batadv_tt_local_entry_free_ref(tt_local); |
3171 | } | 3197 | } |
3172 | spin_unlock_bh(list_lock); | 3198 | spin_unlock_bh(list_lock); |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 34891a56773f..8854c05622a9 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -687,6 +687,7 @@ struct batadv_priv_nc { | |||
687 | 687 | ||
688 | /** | 688 | /** |
689 | * struct batadv_softif_vlan - per VLAN attributes set | 689 | * struct batadv_softif_vlan - per VLAN attributes set |
690 | * @bat_priv: pointer to the mesh object | ||
690 | * @vid: VLAN identifier | 691 | * @vid: VLAN identifier |
691 | * @kobj: kobject for sysfs vlan subdirectory | 692 | * @kobj: kobject for sysfs vlan subdirectory |
692 | * @ap_isolation: AP isolation state | 693 | * @ap_isolation: AP isolation state |
@@ -696,6 +697,7 @@ struct batadv_priv_nc { | |||
696 | * @rcu: struct used for freeing in a RCU-safe manner | 697 | * @rcu: struct used for freeing in a RCU-safe manner |
697 | */ | 698 | */ |
698 | struct batadv_softif_vlan { | 699 | struct batadv_softif_vlan { |
700 | struct batadv_priv *bat_priv; | ||
699 | unsigned short vid; | 701 | unsigned short vid; |
700 | struct kobject *kobj; | 702 | struct kobject *kobj; |
701 | atomic_t ap_isolation; /* boolean */ | 703 | atomic_t ap_isolation; /* boolean */ |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index ca01d1861854..a7a27bc2c0b1 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -289,10 +289,20 @@ static void hci_conn_timeout(struct work_struct *work) | |||
289 | { | 289 | { |
290 | struct hci_conn *conn = container_of(work, struct hci_conn, | 290 | struct hci_conn *conn = container_of(work, struct hci_conn, |
291 | disc_work.work); | 291 | disc_work.work); |
292 | int refcnt = atomic_read(&conn->refcnt); | ||
292 | 293 | ||
293 | BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); | 294 | BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); |
294 | 295 | ||
295 | if (atomic_read(&conn->refcnt)) | 296 | WARN_ON(refcnt < 0); |
297 | |||
298 | /* FIXME: It was observed that in pairing failed scenario, refcnt | ||
299 | * drops below 0. Probably this is because l2cap_conn_del calls | ||
300 | * l2cap_chan_del for each channel, and inside l2cap_chan_del conn is | ||
301 | * dropped. After that loop hci_chan_del is called which also drops | ||
302 | * conn. For now make sure that ACL is alive if refcnt is higher then 0, | ||
303 | * otherwise drop it. | ||
304 | */ | ||
305 | if (refcnt > 0) | ||
296 | return; | 306 | return; |
297 | 307 | ||
298 | switch (conn->state) { | 308 | switch (conn->state) { |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index f2829a7932e2..e33a982161c1 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -385,6 +385,16 @@ static const u8 gen_method[5][5] = { | |||
385 | { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, | 385 | { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, |
386 | }; | 386 | }; |
387 | 387 | ||
388 | static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) | ||
389 | { | ||
390 | /* If either side has unknown io_caps, use JUST WORKS */ | ||
391 | if (local_io > SMP_IO_KEYBOARD_DISPLAY || | ||
392 | remote_io > SMP_IO_KEYBOARD_DISPLAY) | ||
393 | return JUST_WORKS; | ||
394 | |||
395 | return gen_method[remote_io][local_io]; | ||
396 | } | ||
397 | |||
388 | static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | 398 | static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, |
389 | u8 local_io, u8 remote_io) | 399 | u8 local_io, u8 remote_io) |
390 | { | 400 | { |
@@ -401,14 +411,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
401 | BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); | 411 | BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); |
402 | 412 | ||
403 | /* If neither side wants MITM, use JUST WORKS */ | 413 | /* If neither side wants MITM, use JUST WORKS */ |
404 | /* If either side has unknown io_caps, use JUST WORKS */ | ||
405 | /* Otherwise, look up method from the table */ | 414 | /* Otherwise, look up method from the table */ |
406 | if (!(auth & SMP_AUTH_MITM) || | 415 | if (!(auth & SMP_AUTH_MITM)) |
407 | local_io > SMP_IO_KEYBOARD_DISPLAY || | ||
408 | remote_io > SMP_IO_KEYBOARD_DISPLAY) | ||
409 | method = JUST_WORKS; | 416 | method = JUST_WORKS; |
410 | else | 417 | else |
411 | method = gen_method[remote_io][local_io]; | 418 | method = get_auth_method(smp, local_io, remote_io); |
412 | 419 | ||
413 | /* If not bonding, don't ask user to confirm a Zero TK */ | 420 | /* If not bonding, don't ask user to confirm a Zero TK */ |
414 | if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) | 421 | if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) |
@@ -669,7 +676,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
669 | { | 676 | { |
670 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; | 677 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; |
671 | struct smp_chan *smp; | 678 | struct smp_chan *smp; |
672 | u8 key_size, auth; | 679 | u8 key_size, auth, sec_level; |
673 | int ret; | 680 | int ret; |
674 | 681 | ||
675 | BT_DBG("conn %p", conn); | 682 | BT_DBG("conn %p", conn); |
@@ -695,7 +702,19 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
695 | /* We didn't start the pairing, so match remote */ | 702 | /* We didn't start the pairing, so match remote */ |
696 | auth = req->auth_req; | 703 | auth = req->auth_req; |
697 | 704 | ||
698 | conn->hcon->pending_sec_level = authreq_to_seclevel(auth); | 705 | sec_level = authreq_to_seclevel(auth); |
706 | if (sec_level > conn->hcon->pending_sec_level) | ||
707 | conn->hcon->pending_sec_level = sec_level; | ||
708 | |||
709 | /* If we need MITM check that it can be acheived */ | ||
710 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { | ||
711 | u8 method; | ||
712 | |||
713 | method = get_auth_method(smp, conn->hcon->io_capability, | ||
714 | req->io_capability); | ||
715 | if (method == JUST_WORKS || method == JUST_CFM) | ||
716 | return SMP_AUTH_REQUIREMENTS; | ||
717 | } | ||
699 | 718 | ||
700 | build_pairing_cmd(conn, req, &rsp, auth); | 719 | build_pairing_cmd(conn, req, &rsp, auth); |
701 | 720 | ||
@@ -743,6 +762,16 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
743 | if (check_enc_key_size(conn, key_size)) | 762 | if (check_enc_key_size(conn, key_size)) |
744 | return SMP_ENC_KEY_SIZE; | 763 | return SMP_ENC_KEY_SIZE; |
745 | 764 | ||
765 | /* If we need MITM check that it can be acheived */ | ||
766 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { | ||
767 | u8 method; | ||
768 | |||
769 | method = get_auth_method(smp, req->io_capability, | ||
770 | rsp->io_capability); | ||
771 | if (method == JUST_WORKS || method == JUST_CFM) | ||
772 | return SMP_AUTH_REQUIREMENTS; | ||
773 | } | ||
774 | |||
746 | get_random_bytes(smp->prnd, sizeof(smp->prnd)); | 775 | get_random_bytes(smp->prnd, sizeof(smp->prnd)); |
747 | 776 | ||
748 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; | 777 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; |
@@ -838,6 +867,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
838 | struct smp_cmd_pairing cp; | 867 | struct smp_cmd_pairing cp; |
839 | struct hci_conn *hcon = conn->hcon; | 868 | struct hci_conn *hcon = conn->hcon; |
840 | struct smp_chan *smp; | 869 | struct smp_chan *smp; |
870 | u8 sec_level; | ||
841 | 871 | ||
842 | BT_DBG("conn %p", conn); | 872 | BT_DBG("conn %p", conn); |
843 | 873 | ||
@@ -847,7 +877,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
847 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) | 877 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) |
848 | return SMP_CMD_NOTSUPP; | 878 | return SMP_CMD_NOTSUPP; |
849 | 879 | ||
850 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); | 880 | sec_level = authreq_to_seclevel(rp->auth_req); |
881 | if (sec_level > hcon->pending_sec_level) | ||
882 | hcon->pending_sec_level = sec_level; | ||
851 | 883 | ||
852 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) | 884 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
853 | return 0; | 885 | return 0; |
@@ -901,9 +933,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
901 | if (smp_sufficient_security(hcon, sec_level)) | 933 | if (smp_sufficient_security(hcon, sec_level)) |
902 | return 1; | 934 | return 1; |
903 | 935 | ||
936 | if (sec_level > hcon->pending_sec_level) | ||
937 | hcon->pending_sec_level = sec_level; | ||
938 | |||
904 | if (hcon->link_mode & HCI_LM_MASTER) | 939 | if (hcon->link_mode & HCI_LM_MASTER) |
905 | if (smp_ltk_encrypt(conn, sec_level)) | 940 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
906 | goto done; | 941 | return 0; |
907 | 942 | ||
908 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 943 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) |
909 | return 0; | 944 | return 0; |
@@ -918,7 +953,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
918 | * requires it. | 953 | * requires it. |
919 | */ | 954 | */ |
920 | if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || | 955 | if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || |
921 | sec_level > BT_SECURITY_MEDIUM) | 956 | hcon->pending_sec_level > BT_SECURITY_MEDIUM) |
922 | authreq |= SMP_AUTH_MITM; | 957 | authreq |= SMP_AUTH_MITM; |
923 | 958 | ||
924 | if (hcon->link_mode & HCI_LM_MASTER) { | 959 | if (hcon->link_mode & HCI_LM_MASTER) { |
@@ -937,9 +972,6 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
937 | 972 | ||
938 | set_bit(SMP_FLAG_INITIATOR, &smp->flags); | 973 | set_bit(SMP_FLAG_INITIATOR, &smp->flags); |
939 | 974 | ||
940 | done: | ||
941 | hcon->pending_sec_level = sec_level; | ||
942 | |||
943 | return 0; | 975 | return 0; |
944 | } | 976 | } |
945 | 977 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 30eedf677913..367a586d0c8a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -148,6 +148,9 @@ struct list_head ptype_all __read_mostly; /* Taps */ | |||
148 | static struct list_head offload_base __read_mostly; | 148 | static struct list_head offload_base __read_mostly; |
149 | 149 | ||
150 | static int netif_rx_internal(struct sk_buff *skb); | 150 | static int netif_rx_internal(struct sk_buff *skb); |
151 | static int call_netdevice_notifiers_info(unsigned long val, | ||
152 | struct net_device *dev, | ||
153 | struct netdev_notifier_info *info); | ||
151 | 154 | ||
152 | /* | 155 | /* |
153 | * The @dev_base_head list is protected by @dev_base_lock and the rtnl | 156 | * The @dev_base_head list is protected by @dev_base_lock and the rtnl |
@@ -1207,7 +1210,11 @@ EXPORT_SYMBOL(netdev_features_change); | |||
1207 | void netdev_state_change(struct net_device *dev) | 1210 | void netdev_state_change(struct net_device *dev) |
1208 | { | 1211 | { |
1209 | if (dev->flags & IFF_UP) { | 1212 | if (dev->flags & IFF_UP) { |
1210 | call_netdevice_notifiers(NETDEV_CHANGE, dev); | 1213 | struct netdev_notifier_change_info change_info; |
1214 | |||
1215 | change_info.flags_changed = 0; | ||
1216 | call_netdevice_notifiers_info(NETDEV_CHANGE, dev, | ||
1217 | &change_info.info); | ||
1211 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL); | 1218 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL); |
1212 | } | 1219 | } |
1213 | } | 1220 | } |
@@ -4089,6 +4096,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
4089 | skb->vlan_tci = 0; | 4096 | skb->vlan_tci = 0; |
4090 | skb->dev = napi->dev; | 4097 | skb->dev = napi->dev; |
4091 | skb->skb_iif = 0; | 4098 | skb->skb_iif = 0; |
4099 | skb->encapsulation = 0; | ||
4100 | skb_shinfo(skb)->gso_type = 0; | ||
4092 | skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); | 4101 | skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); |
4093 | 4102 | ||
4094 | napi->skb = skb; | 4103 | napi->skb = skb; |
@@ -4227,9 +4236,8 @@ static int process_backlog(struct napi_struct *napi, int quota) | |||
4227 | #endif | 4236 | #endif |
4228 | napi->weight = weight_p; | 4237 | napi->weight = weight_p; |
4229 | local_irq_disable(); | 4238 | local_irq_disable(); |
4230 | while (work < quota) { | 4239 | while (1) { |
4231 | struct sk_buff *skb; | 4240 | struct sk_buff *skb; |
4232 | unsigned int qlen; | ||
4233 | 4241 | ||
4234 | while ((skb = __skb_dequeue(&sd->process_queue))) { | 4242 | while ((skb = __skb_dequeue(&sd->process_queue))) { |
4235 | local_irq_enable(); | 4243 | local_irq_enable(); |
@@ -4243,24 +4251,24 @@ static int process_backlog(struct napi_struct *napi, int quota) | |||
4243 | } | 4251 | } |
4244 | 4252 | ||
4245 | rps_lock(sd); | 4253 | rps_lock(sd); |
4246 | qlen = skb_queue_len(&sd->input_pkt_queue); | 4254 | if (skb_queue_empty(&sd->input_pkt_queue)) { |
4247 | if (qlen) | ||
4248 | skb_queue_splice_tail_init(&sd->input_pkt_queue, | ||
4249 | &sd->process_queue); | ||
4250 | |||
4251 | if (qlen < quota - work) { | ||
4252 | /* | 4255 | /* |
4253 | * Inline a custom version of __napi_complete(). | 4256 | * Inline a custom version of __napi_complete(). |
4254 | * only current cpu owns and manipulates this napi, | 4257 | * only current cpu owns and manipulates this napi, |
4255 | * and NAPI_STATE_SCHED is the only possible flag set on backlog. | 4258 | * and NAPI_STATE_SCHED is the only possible flag set |
4256 | * we can use a plain write instead of clear_bit(), | 4259 | * on backlog. |
4260 | * We can use a plain write instead of clear_bit(), | ||
4257 | * and we dont need an smp_mb() memory barrier. | 4261 | * and we dont need an smp_mb() memory barrier. |
4258 | */ | 4262 | */ |
4259 | list_del(&napi->poll_list); | 4263 | list_del(&napi->poll_list); |
4260 | napi->state = 0; | 4264 | napi->state = 0; |
4265 | rps_unlock(sd); | ||
4261 | 4266 | ||
4262 | quota = work + qlen; | 4267 | break; |
4263 | } | 4268 | } |
4269 | |||
4270 | skb_queue_splice_tail_init(&sd->input_pkt_queue, | ||
4271 | &sd->process_queue); | ||
4264 | rps_unlock(sd); | 4272 | rps_unlock(sd); |
4265 | } | 4273 | } |
4266 | local_irq_enable(); | 4274 | local_irq_enable(); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 32d872eec7f5..559890b0f0a2 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -3059,11 +3059,12 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
3059 | memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0, | 3059 | memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0, |
3060 | sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL])); | 3060 | sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL])); |
3061 | } else { | 3061 | } else { |
3062 | struct neigh_table *tbl = p->tbl; | ||
3062 | dev_name_source = "default"; | 3063 | dev_name_source = "default"; |
3063 | t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = (int *)(p + 1); | 3064 | t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = &tbl->gc_interval; |
3064 | t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = (int *)(p + 1) + 1; | 3065 | t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = &tbl->gc_thresh1; |
3065 | t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = (int *)(p + 1) + 2; | 3066 | t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = &tbl->gc_thresh2; |
3066 | t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3; | 3067 | t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = &tbl->gc_thresh3; |
3067 | } | 3068 | } |
3068 | 3069 | ||
3069 | if (handler) { | 3070 | if (handler) { |
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index 9acec61f5433..dd8696a3dbec 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c | |||
@@ -150,7 +150,7 @@ int dns_query(const char *type, const char *name, size_t namelen, | |||
150 | goto put; | 150 | goto put; |
151 | 151 | ||
152 | memcpy(*_result, upayload->data, len); | 152 | memcpy(*_result, upayload->data, len); |
153 | *_result[len] = '\0'; | 153 | (*_result)[len] = '\0'; |
154 | 154 | ||
155 | if (_expiry) | 155 | if (_expiry) |
156 | *_expiry = rkey->expiry; | 156 | *_expiry = rkey->expiry; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d5e6836cf772..d156b3c5f363 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1429,6 +1429,9 @@ static int inet_gro_complete(struct sk_buff *skb, int nhoff) | |||
1429 | int proto = iph->protocol; | 1429 | int proto = iph->protocol; |
1430 | int err = -ENOSYS; | 1430 | int err = -ENOSYS; |
1431 | 1431 | ||
1432 | if (skb->encapsulation) | ||
1433 | skb_set_inner_network_header(skb, nhoff); | ||
1434 | |||
1432 | csum_replace2(&iph->check, iph->tot_len, newlen); | 1435 | csum_replace2(&iph->check, iph->tot_len, newlen); |
1433 | iph->tot_len = newlen; | 1436 | iph->tot_len = newlen; |
1434 | 1437 | ||
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 4e9619bca732..0485bf7f8f03 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c | |||
@@ -68,6 +68,7 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, | |||
68 | 68 | ||
69 | skb_push(skb, hdr_len); | 69 | skb_push(skb, hdr_len); |
70 | 70 | ||
71 | skb_reset_transport_header(skb); | ||
71 | greh = (struct gre_base_hdr *)skb->data; | 72 | greh = (struct gre_base_hdr *)skb->data; |
72 | greh->flags = tnl_flags_to_gre_flags(tpi->flags); | 73 | greh->flags = tnl_flags_to_gre_flags(tpi->flags); |
73 | greh->protocol = tpi->proto; | 74 | greh->protocol = tpi->proto; |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index eb92deb12666..f0bdd47bbbcb 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
@@ -263,6 +263,9 @@ static int gre_gro_complete(struct sk_buff *skb, int nhoff) | |||
263 | int err = -ENOENT; | 263 | int err = -ENOENT; |
264 | __be16 type; | 264 | __be16 type; |
265 | 265 | ||
266 | skb->encapsulation = 1; | ||
267 | skb_shinfo(skb)->gso_type = SKB_GSO_GRE; | ||
268 | |||
266 | type = greh->protocol; | 269 | type = greh->protocol; |
267 | if (greh->flags & GRE_KEY) | 270 | if (greh->flags & GRE_KEY) |
268 | grehlen += GRE_HEADER_SECTION; | 271 | grehlen += GRE_HEADER_SECTION; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 79c3d947a481..42b7bcf8045b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -739,8 +739,6 @@ static void icmp_unreach(struct sk_buff *skb) | |||
739 | /* fall through */ | 739 | /* fall through */ |
740 | case 0: | 740 | case 0: |
741 | info = ntohs(icmph->un.frag.mtu); | 741 | info = ntohs(icmph->un.frag.mtu); |
742 | if (!info) | ||
743 | goto out; | ||
744 | } | 742 | } |
745 | break; | 743 | break; |
746 | case ICMP_SR_FAILED: | 744 | case ICMP_SR_FAILED: |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 6748d420f714..db710b059bab 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1944,6 +1944,10 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1944 | 1944 | ||
1945 | rtnl_lock(); | 1945 | rtnl_lock(); |
1946 | in_dev = ip_mc_find_dev(net, imr); | 1946 | in_dev = ip_mc_find_dev(net, imr); |
1947 | if (!in_dev) { | ||
1948 | ret = -ENODEV; | ||
1949 | goto out; | ||
1950 | } | ||
1947 | ifindex = imr->imr_ifindex; | 1951 | ifindex = imr->imr_ifindex; |
1948 | for (imlp = &inet->mc_list; | 1952 | for (imlp = &inet->mc_list; |
1949 | (iml = rtnl_dereference(*imlp)) != NULL; | 1953 | (iml = rtnl_dereference(*imlp)) != NULL; |
@@ -1961,16 +1965,14 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1961 | 1965 | ||
1962 | *imlp = iml->next_rcu; | 1966 | *imlp = iml->next_rcu; |
1963 | 1967 | ||
1964 | if (in_dev) | 1968 | ip_mc_dec_group(in_dev, group); |
1965 | ip_mc_dec_group(in_dev, group); | ||
1966 | rtnl_unlock(); | 1969 | rtnl_unlock(); |
1967 | /* decrease mem now to avoid the memleak warning */ | 1970 | /* decrease mem now to avoid the memleak warning */ |
1968 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); | 1971 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); |
1969 | kfree_rcu(iml, rcu); | 1972 | kfree_rcu(iml, rcu); |
1970 | return 0; | 1973 | return 0; |
1971 | } | 1974 | } |
1972 | if (!in_dev) | 1975 | out: |
1973 | ret = -ENODEV; | ||
1974 | rtnl_unlock(); | 1976 | rtnl_unlock(); |
1975 | return ret; | 1977 | return ret; |
1976 | } | 1978 | } |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 5e7aecea05cd..ad382499bace 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -288,6 +288,10 @@ int ip_options_compile(struct net *net, | |||
288 | optptr++; | 288 | optptr++; |
289 | continue; | 289 | continue; |
290 | } | 290 | } |
291 | if (unlikely(l < 2)) { | ||
292 | pp_ptr = optptr; | ||
293 | goto error; | ||
294 | } | ||
291 | optlen = optptr[1]; | 295 | optlen = optptr[1]; |
292 | if (optlen < 2 || optlen > l) { | 296 | if (optlen < 2 || optlen > l) { |
293 | pp_ptr = optptr; | 297 | pp_ptr = optptr; |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 54b6731dab55..6f9de61dce5f 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -169,6 +169,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
169 | 169 | ||
170 | hlist_for_each_entry_rcu(t, head, hash_node) { | 170 | hlist_for_each_entry_rcu(t, head, hash_node) { |
171 | if (remote != t->parms.iph.daddr || | 171 | if (remote != t->parms.iph.daddr || |
172 | t->parms.iph.saddr != 0 || | ||
172 | !(t->dev->flags & IFF_UP)) | 173 | !(t->dev->flags & IFF_UP)) |
173 | continue; | 174 | continue; |
174 | 175 | ||
@@ -185,10 +186,11 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
185 | head = &itn->tunnels[hash]; | 186 | head = &itn->tunnels[hash]; |
186 | 187 | ||
187 | hlist_for_each_entry_rcu(t, head, hash_node) { | 188 | hlist_for_each_entry_rcu(t, head, hash_node) { |
188 | if ((local != t->parms.iph.saddr && | 189 | if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) && |
189 | (local != t->parms.iph.daddr || | 190 | (local != t->parms.iph.daddr || !ipv4_is_multicast(local))) |
190 | !ipv4_is_multicast(local))) || | 191 | continue; |
191 | !(t->dev->flags & IFF_UP)) | 192 | |
193 | if (!(t->dev->flags & IFF_UP)) | ||
192 | continue; | 194 | continue; |
193 | 195 | ||
194 | if (!ip_tunnel_key_match(&t->parms, flags, key)) | 196 | if (!ip_tunnel_key_match(&t->parms, flags, key)) |
@@ -205,6 +207,8 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
205 | 207 | ||
206 | hlist_for_each_entry_rcu(t, head, hash_node) { | 208 | hlist_for_each_entry_rcu(t, head, hash_node) { |
207 | if (t->parms.i_key != key || | 209 | if (t->parms.i_key != key || |
210 | t->parms.iph.saddr != 0 || | ||
211 | t->parms.iph.daddr != 0 || | ||
208 | !(t->dev->flags & IFF_UP)) | 212 | !(t->dev->flags & IFF_UP)) |
209 | continue; | 213 | continue; |
210 | 214 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 082239ffe34a..3162ea923ded 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1010,7 +1010,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1010 | const struct iphdr *iph = (const struct iphdr *) skb->data; | 1010 | const struct iphdr *iph = (const struct iphdr *) skb->data; |
1011 | struct flowi4 fl4; | 1011 | struct flowi4 fl4; |
1012 | struct rtable *rt; | 1012 | struct rtable *rt; |
1013 | struct dst_entry *dst; | 1013 | struct dst_entry *odst = NULL; |
1014 | bool new = false; | 1014 | bool new = false; |
1015 | 1015 | ||
1016 | bh_lock_sock(sk); | 1016 | bh_lock_sock(sk); |
@@ -1018,16 +1018,17 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1018 | if (!ip_sk_accept_pmtu(sk)) | 1018 | if (!ip_sk_accept_pmtu(sk)) |
1019 | goto out; | 1019 | goto out; |
1020 | 1020 | ||
1021 | rt = (struct rtable *) __sk_dst_get(sk); | 1021 | odst = sk_dst_get(sk); |
1022 | 1022 | ||
1023 | if (sock_owned_by_user(sk) || !rt) { | 1023 | if (sock_owned_by_user(sk) || !odst) { |
1024 | __ipv4_sk_update_pmtu(skb, sk, mtu); | 1024 | __ipv4_sk_update_pmtu(skb, sk, mtu); |
1025 | goto out; | 1025 | goto out; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); | 1028 | __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); |
1029 | 1029 | ||
1030 | if (!__sk_dst_check(sk, 0)) { | 1030 | rt = (struct rtable *)odst; |
1031 | if (odst->obsolete && odst->ops->check(odst, 0) == NULL) { | ||
1031 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); | 1032 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); |
1032 | if (IS_ERR(rt)) | 1033 | if (IS_ERR(rt)) |
1033 | goto out; | 1034 | goto out; |
@@ -1037,8 +1038,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1037 | 1038 | ||
1038 | __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); | 1039 | __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); |
1039 | 1040 | ||
1040 | dst = dst_check(&rt->dst, 0); | 1041 | if (!dst_check(&rt->dst, 0)) { |
1041 | if (!dst) { | ||
1042 | if (new) | 1042 | if (new) |
1043 | dst_release(&rt->dst); | 1043 | dst_release(&rt->dst); |
1044 | 1044 | ||
@@ -1050,10 +1050,11 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | if (new) | 1052 | if (new) |
1053 | __sk_dst_set(sk, &rt->dst); | 1053 | sk_dst_set(sk, &rt->dst); |
1054 | 1054 | ||
1055 | out: | 1055 | out: |
1056 | bh_unlock_sock(sk); | 1056 | bh_unlock_sock(sk); |
1057 | dst_release(odst); | ||
1057 | } | 1058 | } |
1058 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); | 1059 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); |
1059 | 1060 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index eb1dde37e678..9d2118e5fbc7 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1108,7 +1108,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1108 | if (unlikely(tp->repair)) { | 1108 | if (unlikely(tp->repair)) { |
1109 | if (tp->repair_queue == TCP_RECV_QUEUE) { | 1109 | if (tp->repair_queue == TCP_RECV_QUEUE) { |
1110 | copied = tcp_send_rcvq(sk, msg, size); | 1110 | copied = tcp_send_rcvq(sk, msg, size); |
1111 | goto out; | 1111 | goto out_nopush; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | err = -EINVAL; | 1114 | err = -EINVAL; |
@@ -1282,6 +1282,7 @@ wait_for_memory: | |||
1282 | out: | 1282 | out: |
1283 | if (copied) | 1283 | if (copied) |
1284 | tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); | 1284 | tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); |
1285 | out_nopush: | ||
1285 | release_sock(sk); | 1286 | release_sock(sk); |
1286 | return copied + copied_syn; | 1287 | return copied + copied_syn; |
1287 | 1288 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b5c23756965a..40639c288dc2 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1106,7 +1106,7 @@ static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, | |||
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | /* D-SACK for already forgotten data... Do dumb counting. */ | 1108 | /* D-SACK for already forgotten data... Do dumb counting. */ |
1109 | if (dup_sack && tp->undo_marker && tp->undo_retrans && | 1109 | if (dup_sack && tp->undo_marker && tp->undo_retrans > 0 && |
1110 | !after(end_seq_0, prior_snd_una) && | 1110 | !after(end_seq_0, prior_snd_una) && |
1111 | after(end_seq_0, tp->undo_marker)) | 1111 | after(end_seq_0, tp->undo_marker)) |
1112 | tp->undo_retrans--; | 1112 | tp->undo_retrans--; |
@@ -1187,7 +1187,7 @@ static u8 tcp_sacktag_one(struct sock *sk, | |||
1187 | 1187 | ||
1188 | /* Account D-SACK for retransmitted packet. */ | 1188 | /* Account D-SACK for retransmitted packet. */ |
1189 | if (dup_sack && (sacked & TCPCB_RETRANS)) { | 1189 | if (dup_sack && (sacked & TCPCB_RETRANS)) { |
1190 | if (tp->undo_marker && tp->undo_retrans && | 1190 | if (tp->undo_marker && tp->undo_retrans > 0 && |
1191 | after(end_seq, tp->undo_marker)) | 1191 | after(end_seq, tp->undo_marker)) |
1192 | tp->undo_retrans--; | 1192 | tp->undo_retrans--; |
1193 | if (sacked & TCPCB_SACKED_ACKED) | 1193 | if (sacked & TCPCB_SACKED_ACKED) |
@@ -1893,7 +1893,7 @@ static void tcp_clear_retrans_partial(struct tcp_sock *tp) | |||
1893 | tp->lost_out = 0; | 1893 | tp->lost_out = 0; |
1894 | 1894 | ||
1895 | tp->undo_marker = 0; | 1895 | tp->undo_marker = 0; |
1896 | tp->undo_retrans = 0; | 1896 | tp->undo_retrans = -1; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | void tcp_clear_retrans(struct tcp_sock *tp) | 1899 | void tcp_clear_retrans(struct tcp_sock *tp) |
@@ -2665,7 +2665,7 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) | |||
2665 | 2665 | ||
2666 | tp->prior_ssthresh = 0; | 2666 | tp->prior_ssthresh = 0; |
2667 | tp->undo_marker = tp->snd_una; | 2667 | tp->undo_marker = tp->snd_una; |
2668 | tp->undo_retrans = tp->retrans_out; | 2668 | tp->undo_retrans = tp->retrans_out ? : -1; |
2669 | 2669 | ||
2670 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { | 2670 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { |
2671 | if (!ece_ack) | 2671 | if (!ece_ack) |
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index 4e86c59ec7f7..55046ecd083e 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
@@ -309,7 +309,7 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff) | |||
309 | 309 | ||
310 | th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr, | 310 | th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr, |
311 | iph->daddr, 0); | 311 | iph->daddr, 0); |
312 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | 312 | skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; |
313 | 313 | ||
314 | return tcp_gro_complete(skb); | 314 | return tcp_gro_complete(skb); |
315 | } | 315 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index d92bce0ea24e..179b51e6bda3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2525,8 +2525,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2525 | if (!tp->retrans_stamp) | 2525 | if (!tp->retrans_stamp) |
2526 | tp->retrans_stamp = TCP_SKB_CB(skb)->when; | 2526 | tp->retrans_stamp = TCP_SKB_CB(skb)->when; |
2527 | 2527 | ||
2528 | tp->undo_retrans += tcp_skb_pcount(skb); | ||
2529 | |||
2530 | /* snd_nxt is stored to detect loss of retransmitted segment, | 2528 | /* snd_nxt is stored to detect loss of retransmitted segment, |
2531 | * see tcp_input.c tcp_sacktag_write_queue(). | 2529 | * see tcp_input.c tcp_sacktag_write_queue(). |
2532 | */ | 2530 | */ |
@@ -2534,6 +2532,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2534 | } else if (err != -EBUSY) { | 2532 | } else if (err != -EBUSY) { |
2535 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL); | 2533 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL); |
2536 | } | 2534 | } |
2535 | |||
2536 | if (tp->undo_retrans < 0) | ||
2537 | tp->undo_retrans = 0; | ||
2538 | tp->undo_retrans += tcp_skb_pcount(skb); | ||
2537 | return err; | 2539 | return err; |
2538 | } | 2540 | } |
2539 | 2541 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d92f94b7e402..7d5a8661df76 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1588,8 +1588,11 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1588 | goto csum_error; | 1588 | goto csum_error; |
1589 | 1589 | ||
1590 | 1590 | ||
1591 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) | 1591 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) { |
1592 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, | ||
1593 | is_udplite); | ||
1592 | goto drop; | 1594 | goto drop; |
1595 | } | ||
1593 | 1596 | ||
1594 | rc = 0; | 1597 | rc = 0; |
1595 | 1598 | ||
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 08b367c6b9cf..617f0958e164 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1301,8 +1301,17 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1301 | len = ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr); | 1301 | len = ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr); |
1302 | len -= skb_network_header_len(skb); | 1302 | len -= skb_network_header_len(skb); |
1303 | 1303 | ||
1304 | /* Drop queries with not link local source */ | 1304 | /* RFC3810 6.2 |
1305 | if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) | 1305 | * Upon reception of an MLD message that contains a Query, the node |
1306 | * checks if the source address of the message is a valid link-local | ||
1307 | * address, if the Hop Limit is set to 1, and if the Router Alert | ||
1308 | * option is present in the Hop-By-Hop Options header of the IPv6 | ||
1309 | * packet. If any of these checks fails, the packet is dropped. | ||
1310 | */ | ||
1311 | if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) || | ||
1312 | ipv6_hdr(skb)->hop_limit != 1 || | ||
1313 | !(IP6CB(skb)->flags & IP6SKB_ROUTERALERT) || | ||
1314 | IP6CB(skb)->ra != htons(IPV6_OPT_ROUTERALERT_MLD)) | ||
1306 | return -EINVAL; | 1315 | return -EINVAL; |
1307 | 1316 | ||
1308 | idev = __in6_dev_get(skb->dev); | 1317 | idev = __in6_dev_get(skb->dev); |
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 8517d3cd1aed..01b0ff9a0c2c 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
@@ -73,7 +73,7 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff) | |||
73 | 73 | ||
74 | th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr, | 74 | th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr, |
75 | &iph->daddr, 0); | 75 | &iph->daddr, 0); |
76 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 76 | skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; |
77 | 77 | ||
78 | return tcp_gro_complete(skb); | 78 | return tcp_gro_complete(skb); |
79 | } | 79 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 95c834799288..7092ff78fd84 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -674,8 +674,11 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
674 | goto csum_error; | 674 | goto csum_error; |
675 | } | 675 | } |
676 | 676 | ||
677 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) | 677 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) { |
678 | UDP6_INC_STATS_BH(sock_net(sk), | ||
679 | UDP_MIB_RCVBUFERRORS, is_udplite); | ||
678 | goto drop; | 680 | goto drop; |
681 | } | ||
679 | 682 | ||
680 | skb_dst_drop(skb); | 683 | skb_dst_drop(skb); |
681 | 684 | ||
@@ -690,6 +693,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
690 | bh_unlock_sock(sk); | 693 | bh_unlock_sock(sk); |
691 | 694 | ||
692 | return rc; | 695 | return rc; |
696 | |||
693 | csum_error: | 697 | csum_error: |
694 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite); | 698 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite); |
695 | drop: | 699 | drop: |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 950909f04ee6..13752d96275e 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -1365,7 +1365,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, | |||
1365 | int err; | 1365 | int err; |
1366 | 1366 | ||
1367 | if (level != SOL_PPPOL2TP) | 1367 | if (level != SOL_PPPOL2TP) |
1368 | return udp_prot.setsockopt(sk, level, optname, optval, optlen); | 1368 | return -EINVAL; |
1369 | 1369 | ||
1370 | if (optlen < sizeof(int)) | 1370 | if (optlen < sizeof(int)) |
1371 | return -EINVAL; | 1371 | return -EINVAL; |
@@ -1491,7 +1491,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, | |||
1491 | struct pppol2tp_session *ps; | 1491 | struct pppol2tp_session *ps; |
1492 | 1492 | ||
1493 | if (level != SOL_PPPOL2TP) | 1493 | if (level != SOL_PPPOL2TP) |
1494 | return udp_prot.getsockopt(sk, level, optname, optval, optlen); | 1494 | return -EINVAL; |
1495 | 1495 | ||
1496 | if (get_user(len, optlen)) | 1496 | if (get_user(len, optlen)) |
1497 | return -EFAULT; | 1497 | return -EFAULT; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 6886601afe1c..a6cda52ed920 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1096,11 +1096,12 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1096 | int err; | 1096 | int err; |
1097 | 1097 | ||
1098 | /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ | 1098 | /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ |
1099 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 6 + extra_len); | 1099 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN + |
1100 | 24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN); | ||
1100 | if (!skb) | 1101 | if (!skb) |
1101 | return; | 1102 | return; |
1102 | 1103 | ||
1103 | skb_reserve(skb, local->hw.extra_tx_headroom); | 1104 | skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN); |
1104 | 1105 | ||
1105 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); | 1106 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); |
1106 | memset(mgmt, 0, 24 + 6); | 1107 | memset(mgmt, 0, 24 + 6); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index ab4566cfcbe4..8746ff9a8357 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -35,7 +35,7 @@ int nft_register_afinfo(struct net *net, struct nft_af_info *afi) | |||
35 | { | 35 | { |
36 | INIT_LIST_HEAD(&afi->tables); | 36 | INIT_LIST_HEAD(&afi->tables); |
37 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 37 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
38 | list_add_tail(&afi->list, &net->nft.af_info); | 38 | list_add_tail_rcu(&afi->list, &net->nft.af_info); |
39 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 39 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(nft_register_afinfo); | |||
51 | void nft_unregister_afinfo(struct nft_af_info *afi) | 51 | void nft_unregister_afinfo(struct nft_af_info *afi) |
52 | { | 52 | { |
53 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 53 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
54 | list_del(&afi->list); | 54 | list_del_rcu(&afi->list); |
55 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 55 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(nft_unregister_afinfo); | 57 | EXPORT_SYMBOL_GPL(nft_unregister_afinfo); |
@@ -277,11 +277,14 @@ static int nf_tables_dump_tables(struct sk_buff *skb, | |||
277 | struct net *net = sock_net(skb->sk); | 277 | struct net *net = sock_net(skb->sk); |
278 | int family = nfmsg->nfgen_family; | 278 | int family = nfmsg->nfgen_family; |
279 | 279 | ||
280 | list_for_each_entry(afi, &net->nft.af_info, list) { | 280 | rcu_read_lock(); |
281 | cb->seq = net->nft.base_seq; | ||
282 | |||
283 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { | ||
281 | if (family != NFPROTO_UNSPEC && family != afi->family) | 284 | if (family != NFPROTO_UNSPEC && family != afi->family) |
282 | continue; | 285 | continue; |
283 | 286 | ||
284 | list_for_each_entry(table, &afi->tables, list) { | 287 | list_for_each_entry_rcu(table, &afi->tables, list) { |
285 | if (idx < s_idx) | 288 | if (idx < s_idx) |
286 | goto cont; | 289 | goto cont; |
287 | if (idx > s_idx) | 290 | if (idx > s_idx) |
@@ -294,11 +297,14 @@ static int nf_tables_dump_tables(struct sk_buff *skb, | |||
294 | NLM_F_MULTI, | 297 | NLM_F_MULTI, |
295 | afi->family, table) < 0) | 298 | afi->family, table) < 0) |
296 | goto done; | 299 | goto done; |
300 | |||
301 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
297 | cont: | 302 | cont: |
298 | idx++; | 303 | idx++; |
299 | } | 304 | } |
300 | } | 305 | } |
301 | done: | 306 | done: |
307 | rcu_read_unlock(); | ||
302 | cb->args[0] = idx; | 308 | cb->args[0] = idx; |
303 | return skb->len; | 309 | return skb->len; |
304 | } | 310 | } |
@@ -407,6 +413,9 @@ static int nf_tables_updtable(struct nft_ctx *ctx) | |||
407 | if (flags & ~NFT_TABLE_F_DORMANT) | 413 | if (flags & ~NFT_TABLE_F_DORMANT) |
408 | return -EINVAL; | 414 | return -EINVAL; |
409 | 415 | ||
416 | if (flags == ctx->table->flags) | ||
417 | return 0; | ||
418 | |||
410 | trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, | 419 | trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, |
411 | sizeof(struct nft_trans_table)); | 420 | sizeof(struct nft_trans_table)); |
412 | if (trans == NULL) | 421 | if (trans == NULL) |
@@ -514,7 +523,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, | |||
514 | module_put(afi->owner); | 523 | module_put(afi->owner); |
515 | return err; | 524 | return err; |
516 | } | 525 | } |
517 | list_add_tail(&table->list, &afi->tables); | 526 | list_add_tail_rcu(&table->list, &afi->tables); |
518 | return 0; | 527 | return 0; |
519 | } | 528 | } |
520 | 529 | ||
@@ -546,7 +555,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb, | |||
546 | if (err < 0) | 555 | if (err < 0) |
547 | return err; | 556 | return err; |
548 | 557 | ||
549 | list_del(&table->list); | 558 | list_del_rcu(&table->list); |
550 | return 0; | 559 | return 0; |
551 | } | 560 | } |
552 | 561 | ||
@@ -635,13 +644,20 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats) | |||
635 | { | 644 | { |
636 | struct nft_stats *cpu_stats, total; | 645 | struct nft_stats *cpu_stats, total; |
637 | struct nlattr *nest; | 646 | struct nlattr *nest; |
647 | unsigned int seq; | ||
648 | u64 pkts, bytes; | ||
638 | int cpu; | 649 | int cpu; |
639 | 650 | ||
640 | memset(&total, 0, sizeof(total)); | 651 | memset(&total, 0, sizeof(total)); |
641 | for_each_possible_cpu(cpu) { | 652 | for_each_possible_cpu(cpu) { |
642 | cpu_stats = per_cpu_ptr(stats, cpu); | 653 | cpu_stats = per_cpu_ptr(stats, cpu); |
643 | total.pkts += cpu_stats->pkts; | 654 | do { |
644 | total.bytes += cpu_stats->bytes; | 655 | seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp); |
656 | pkts = cpu_stats->pkts; | ||
657 | bytes = cpu_stats->bytes; | ||
658 | } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq)); | ||
659 | total.pkts += pkts; | ||
660 | total.bytes += bytes; | ||
645 | } | 661 | } |
646 | nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS); | 662 | nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS); |
647 | if (nest == NULL) | 663 | if (nest == NULL) |
@@ -761,12 +777,15 @@ static int nf_tables_dump_chains(struct sk_buff *skb, | |||
761 | struct net *net = sock_net(skb->sk); | 777 | struct net *net = sock_net(skb->sk); |
762 | int family = nfmsg->nfgen_family; | 778 | int family = nfmsg->nfgen_family; |
763 | 779 | ||
764 | list_for_each_entry(afi, &net->nft.af_info, list) { | 780 | rcu_read_lock(); |
781 | cb->seq = net->nft.base_seq; | ||
782 | |||
783 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { | ||
765 | if (family != NFPROTO_UNSPEC && family != afi->family) | 784 | if (family != NFPROTO_UNSPEC && family != afi->family) |
766 | continue; | 785 | continue; |
767 | 786 | ||
768 | list_for_each_entry(table, &afi->tables, list) { | 787 | list_for_each_entry_rcu(table, &afi->tables, list) { |
769 | list_for_each_entry(chain, &table->chains, list) { | 788 | list_for_each_entry_rcu(chain, &table->chains, list) { |
770 | if (idx < s_idx) | 789 | if (idx < s_idx) |
771 | goto cont; | 790 | goto cont; |
772 | if (idx > s_idx) | 791 | if (idx > s_idx) |
@@ -778,17 +797,19 @@ static int nf_tables_dump_chains(struct sk_buff *skb, | |||
778 | NLM_F_MULTI, | 797 | NLM_F_MULTI, |
779 | afi->family, table, chain) < 0) | 798 | afi->family, table, chain) < 0) |
780 | goto done; | 799 | goto done; |
800 | |||
801 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
781 | cont: | 802 | cont: |
782 | idx++; | 803 | idx++; |
783 | } | 804 | } |
784 | } | 805 | } |
785 | } | 806 | } |
786 | done: | 807 | done: |
808 | rcu_read_unlock(); | ||
787 | cb->args[0] = idx; | 809 | cb->args[0] = idx; |
788 | return skb->len; | 810 | return skb->len; |
789 | } | 811 | } |
790 | 812 | ||
791 | |||
792 | static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb, | 813 | static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb, |
793 | const struct nlmsghdr *nlh, | 814 | const struct nlmsghdr *nlh, |
794 | const struct nlattr * const nla[]) | 815 | const struct nlattr * const nla[]) |
@@ -861,7 +882,7 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr) | |||
861 | if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS]) | 882 | if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS]) |
862 | return ERR_PTR(-EINVAL); | 883 | return ERR_PTR(-EINVAL); |
863 | 884 | ||
864 | newstats = alloc_percpu(struct nft_stats); | 885 | newstats = netdev_alloc_pcpu_stats(struct nft_stats); |
865 | if (newstats == NULL) | 886 | if (newstats == NULL) |
866 | return ERR_PTR(-ENOMEM); | 887 | return ERR_PTR(-ENOMEM); |
867 | 888 | ||
@@ -1077,7 +1098,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
1077 | } | 1098 | } |
1078 | basechain->stats = stats; | 1099 | basechain->stats = stats; |
1079 | } else { | 1100 | } else { |
1080 | stats = alloc_percpu(struct nft_stats); | 1101 | stats = netdev_alloc_pcpu_stats(struct nft_stats); |
1081 | if (IS_ERR(stats)) { | 1102 | if (IS_ERR(stats)) { |
1082 | module_put(type->owner); | 1103 | module_put(type->owner); |
1083 | kfree(basechain); | 1104 | kfree(basechain); |
@@ -1130,7 +1151,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
1130 | goto err2; | 1151 | goto err2; |
1131 | 1152 | ||
1132 | table->use++; | 1153 | table->use++; |
1133 | list_add_tail(&chain->list, &table->chains); | 1154 | list_add_tail_rcu(&chain->list, &table->chains); |
1134 | return 0; | 1155 | return 0; |
1135 | err2: | 1156 | err2: |
1136 | if (!(table->flags & NFT_TABLE_F_DORMANT) && | 1157 | if (!(table->flags & NFT_TABLE_F_DORMANT) && |
@@ -1180,7 +1201,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb, | |||
1180 | return err; | 1201 | return err; |
1181 | 1202 | ||
1182 | table->use--; | 1203 | table->use--; |
1183 | list_del(&chain->list); | 1204 | list_del_rcu(&chain->list); |
1184 | return 0; | 1205 | return 0; |
1185 | } | 1206 | } |
1186 | 1207 | ||
@@ -1199,9 +1220,9 @@ int nft_register_expr(struct nft_expr_type *type) | |||
1199 | { | 1220 | { |
1200 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 1221 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
1201 | if (type->family == NFPROTO_UNSPEC) | 1222 | if (type->family == NFPROTO_UNSPEC) |
1202 | list_add_tail(&type->list, &nf_tables_expressions); | 1223 | list_add_tail_rcu(&type->list, &nf_tables_expressions); |
1203 | else | 1224 | else |
1204 | list_add(&type->list, &nf_tables_expressions); | 1225 | list_add_rcu(&type->list, &nf_tables_expressions); |
1205 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 1226 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
1206 | return 0; | 1227 | return 0; |
1207 | } | 1228 | } |
@@ -1216,7 +1237,7 @@ EXPORT_SYMBOL_GPL(nft_register_expr); | |||
1216 | void nft_unregister_expr(struct nft_expr_type *type) | 1237 | void nft_unregister_expr(struct nft_expr_type *type) |
1217 | { | 1238 | { |
1218 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 1239 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
1219 | list_del(&type->list); | 1240 | list_del_rcu(&type->list); |
1220 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 1241 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
1221 | } | 1242 | } |
1222 | EXPORT_SYMBOL_GPL(nft_unregister_expr); | 1243 | EXPORT_SYMBOL_GPL(nft_unregister_expr); |
@@ -1549,16 +1570,17 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
1549 | unsigned int idx = 0, s_idx = cb->args[0]; | 1570 | unsigned int idx = 0, s_idx = cb->args[0]; |
1550 | struct net *net = sock_net(skb->sk); | 1571 | struct net *net = sock_net(skb->sk); |
1551 | int family = nfmsg->nfgen_family; | 1572 | int family = nfmsg->nfgen_family; |
1552 | u8 genctr = ACCESS_ONCE(net->nft.genctr); | ||
1553 | u8 gencursor = ACCESS_ONCE(net->nft.gencursor); | ||
1554 | 1573 | ||
1555 | list_for_each_entry(afi, &net->nft.af_info, list) { | 1574 | rcu_read_lock(); |
1575 | cb->seq = net->nft.base_seq; | ||
1576 | |||
1577 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { | ||
1556 | if (family != NFPROTO_UNSPEC && family != afi->family) | 1578 | if (family != NFPROTO_UNSPEC && family != afi->family) |
1557 | continue; | 1579 | continue; |
1558 | 1580 | ||
1559 | list_for_each_entry(table, &afi->tables, list) { | 1581 | list_for_each_entry_rcu(table, &afi->tables, list) { |
1560 | list_for_each_entry(chain, &table->chains, list) { | 1582 | list_for_each_entry_rcu(chain, &table->chains, list) { |
1561 | list_for_each_entry(rule, &chain->rules, list) { | 1583 | list_for_each_entry_rcu(rule, &chain->rules, list) { |
1562 | if (!nft_rule_is_active(net, rule)) | 1584 | if (!nft_rule_is_active(net, rule)) |
1563 | goto cont; | 1585 | goto cont; |
1564 | if (idx < s_idx) | 1586 | if (idx < s_idx) |
@@ -1572,6 +1594,8 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
1572 | NLM_F_MULTI | NLM_F_APPEND, | 1594 | NLM_F_MULTI | NLM_F_APPEND, |
1573 | afi->family, table, chain, rule) < 0) | 1595 | afi->family, table, chain, rule) < 0) |
1574 | goto done; | 1596 | goto done; |
1597 | |||
1598 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
1575 | cont: | 1599 | cont: |
1576 | idx++; | 1600 | idx++; |
1577 | } | 1601 | } |
@@ -1579,9 +1603,7 @@ cont: | |||
1579 | } | 1603 | } |
1580 | } | 1604 | } |
1581 | done: | 1605 | done: |
1582 | /* Invalidate this dump, a transition to the new generation happened */ | 1606 | rcu_read_unlock(); |
1583 | if (gencursor != net->nft.gencursor || genctr != net->nft.genctr) | ||
1584 | return -EBUSY; | ||
1585 | 1607 | ||
1586 | cb->args[0] = idx; | 1608 | cb->args[0] = idx; |
1587 | return skb->len; | 1609 | return skb->len; |
@@ -1932,7 +1954,7 @@ static LIST_HEAD(nf_tables_set_ops); | |||
1932 | int nft_register_set(struct nft_set_ops *ops) | 1954 | int nft_register_set(struct nft_set_ops *ops) |
1933 | { | 1955 | { |
1934 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 1956 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
1935 | list_add_tail(&ops->list, &nf_tables_set_ops); | 1957 | list_add_tail_rcu(&ops->list, &nf_tables_set_ops); |
1936 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 1958 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
1937 | return 0; | 1959 | return 0; |
1938 | } | 1960 | } |
@@ -1941,7 +1963,7 @@ EXPORT_SYMBOL_GPL(nft_register_set); | |||
1941 | void nft_unregister_set(struct nft_set_ops *ops) | 1963 | void nft_unregister_set(struct nft_set_ops *ops) |
1942 | { | 1964 | { |
1943 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 1965 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
1944 | list_del(&ops->list); | 1966 | list_del_rcu(&ops->list); |
1945 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 1967 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
1946 | } | 1968 | } |
1947 | EXPORT_SYMBOL_GPL(nft_unregister_set); | 1969 | EXPORT_SYMBOL_GPL(nft_unregister_set); |
@@ -2234,7 +2256,10 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2234 | if (cb->args[1]) | 2256 | if (cb->args[1]) |
2235 | return skb->len; | 2257 | return skb->len; |
2236 | 2258 | ||
2237 | list_for_each_entry(set, &ctx->table->sets, list) { | 2259 | rcu_read_lock(); |
2260 | cb->seq = ctx->net->nft.base_seq; | ||
2261 | |||
2262 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { | ||
2238 | if (idx < s_idx) | 2263 | if (idx < s_idx) |
2239 | goto cont; | 2264 | goto cont; |
2240 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, | 2265 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, |
@@ -2242,11 +2267,13 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2242 | cb->args[0] = idx; | 2267 | cb->args[0] = idx; |
2243 | goto done; | 2268 | goto done; |
2244 | } | 2269 | } |
2270 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
2245 | cont: | 2271 | cont: |
2246 | idx++; | 2272 | idx++; |
2247 | } | 2273 | } |
2248 | cb->args[1] = 1; | 2274 | cb->args[1] = 1; |
2249 | done: | 2275 | done: |
2276 | rcu_read_unlock(); | ||
2250 | return skb->len; | 2277 | return skb->len; |
2251 | } | 2278 | } |
2252 | 2279 | ||
@@ -2260,7 +2287,10 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2260 | if (cb->args[1]) | 2287 | if (cb->args[1]) |
2261 | return skb->len; | 2288 | return skb->len; |
2262 | 2289 | ||
2263 | list_for_each_entry(table, &ctx->afi->tables, list) { | 2290 | rcu_read_lock(); |
2291 | cb->seq = ctx->net->nft.base_seq; | ||
2292 | |||
2293 | list_for_each_entry_rcu(table, &ctx->afi->tables, list) { | ||
2264 | if (cur_table) { | 2294 | if (cur_table) { |
2265 | if (cur_table != table) | 2295 | if (cur_table != table) |
2266 | continue; | 2296 | continue; |
@@ -2269,7 +2299,7 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2269 | } | 2299 | } |
2270 | ctx->table = table; | 2300 | ctx->table = table; |
2271 | idx = 0; | 2301 | idx = 0; |
2272 | list_for_each_entry(set, &ctx->table->sets, list) { | 2302 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { |
2273 | if (idx < s_idx) | 2303 | if (idx < s_idx) |
2274 | goto cont; | 2304 | goto cont; |
2275 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, | 2305 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, |
@@ -2278,12 +2308,14 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2278 | cb->args[2] = (unsigned long) table; | 2308 | cb->args[2] = (unsigned long) table; |
2279 | goto done; | 2309 | goto done; |
2280 | } | 2310 | } |
2311 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
2281 | cont: | 2312 | cont: |
2282 | idx++; | 2313 | idx++; |
2283 | } | 2314 | } |
2284 | } | 2315 | } |
2285 | cb->args[1] = 1; | 2316 | cb->args[1] = 1; |
2286 | done: | 2317 | done: |
2318 | rcu_read_unlock(); | ||
2287 | return skb->len; | 2319 | return skb->len; |
2288 | } | 2320 | } |
2289 | 2321 | ||
@@ -2300,7 +2332,10 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2300 | if (cb->args[1]) | 2332 | if (cb->args[1]) |
2301 | return skb->len; | 2333 | return skb->len; |
2302 | 2334 | ||
2303 | list_for_each_entry(afi, &net->nft.af_info, list) { | 2335 | rcu_read_lock(); |
2336 | cb->seq = net->nft.base_seq; | ||
2337 | |||
2338 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { | ||
2304 | if (cur_family) { | 2339 | if (cur_family) { |
2305 | if (afi->family != cur_family) | 2340 | if (afi->family != cur_family) |
2306 | continue; | 2341 | continue; |
@@ -2308,7 +2343,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2308 | cur_family = 0; | 2343 | cur_family = 0; |
2309 | } | 2344 | } |
2310 | 2345 | ||
2311 | list_for_each_entry(table, &afi->tables, list) { | 2346 | list_for_each_entry_rcu(table, &afi->tables, list) { |
2312 | if (cur_table) { | 2347 | if (cur_table) { |
2313 | if (cur_table != table) | 2348 | if (cur_table != table) |
2314 | continue; | 2349 | continue; |
@@ -2319,7 +2354,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2319 | ctx->table = table; | 2354 | ctx->table = table; |
2320 | ctx->afi = afi; | 2355 | ctx->afi = afi; |
2321 | idx = 0; | 2356 | idx = 0; |
2322 | list_for_each_entry(set, &ctx->table->sets, list) { | 2357 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { |
2323 | if (idx < s_idx) | 2358 | if (idx < s_idx) |
2324 | goto cont; | 2359 | goto cont; |
2325 | if (nf_tables_fill_set(skb, ctx, set, | 2360 | if (nf_tables_fill_set(skb, ctx, set, |
@@ -2330,6 +2365,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2330 | cb->args[3] = afi->family; | 2365 | cb->args[3] = afi->family; |
2331 | goto done; | 2366 | goto done; |
2332 | } | 2367 | } |
2368 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
2333 | cont: | 2369 | cont: |
2334 | idx++; | 2370 | idx++; |
2335 | } | 2371 | } |
@@ -2339,6 +2375,7 @@ cont: | |||
2339 | } | 2375 | } |
2340 | cb->args[1] = 1; | 2376 | cb->args[1] = 1; |
2341 | done: | 2377 | done: |
2378 | rcu_read_unlock(); | ||
2342 | return skb->len; | 2379 | return skb->len; |
2343 | } | 2380 | } |
2344 | 2381 | ||
@@ -2597,7 +2634,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb, | |||
2597 | if (err < 0) | 2634 | if (err < 0) |
2598 | goto err2; | 2635 | goto err2; |
2599 | 2636 | ||
2600 | list_add_tail(&set->list, &table->sets); | 2637 | list_add_tail_rcu(&set->list, &table->sets); |
2601 | table->use++; | 2638 | table->use++; |
2602 | return 0; | 2639 | return 0; |
2603 | 2640 | ||
@@ -2617,7 +2654,7 @@ static void nft_set_destroy(struct nft_set *set) | |||
2617 | 2654 | ||
2618 | static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) | 2655 | static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) |
2619 | { | 2656 | { |
2620 | list_del(&set->list); | 2657 | list_del_rcu(&set->list); |
2621 | nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC); | 2658 | nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC); |
2622 | nft_set_destroy(set); | 2659 | nft_set_destroy(set); |
2623 | } | 2660 | } |
@@ -2652,7 +2689,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb, | |||
2652 | if (err < 0) | 2689 | if (err < 0) |
2653 | return err; | 2690 | return err; |
2654 | 2691 | ||
2655 | list_del(&set->list); | 2692 | list_del_rcu(&set->list); |
2656 | ctx.table->use--; | 2693 | ctx.table->use--; |
2657 | return 0; | 2694 | return 0; |
2658 | } | 2695 | } |
@@ -2704,14 +2741,14 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, | |||
2704 | } | 2741 | } |
2705 | bind: | 2742 | bind: |
2706 | binding->chain = ctx->chain; | 2743 | binding->chain = ctx->chain; |
2707 | list_add_tail(&binding->list, &set->bindings); | 2744 | list_add_tail_rcu(&binding->list, &set->bindings); |
2708 | return 0; | 2745 | return 0; |
2709 | } | 2746 | } |
2710 | 2747 | ||
2711 | void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, | 2748 | void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, |
2712 | struct nft_set_binding *binding) | 2749 | struct nft_set_binding *binding) |
2713 | { | 2750 | { |
2714 | list_del(&binding->list); | 2751 | list_del_rcu(&binding->list); |
2715 | 2752 | ||
2716 | if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS && | 2753 | if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS && |
2717 | !(set->flags & NFT_SET_INACTIVE)) | 2754 | !(set->flags & NFT_SET_INACTIVE)) |
@@ -3346,7 +3383,7 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
3346 | struct nft_set *set; | 3383 | struct nft_set *set; |
3347 | 3384 | ||
3348 | /* Bump generation counter, invalidate any dump in progress */ | 3385 | /* Bump generation counter, invalidate any dump in progress */ |
3349 | net->nft.genctr++; | 3386 | while (++net->nft.base_seq == 0); |
3350 | 3387 | ||
3351 | /* A new generation has just started */ | 3388 | /* A new generation has just started */ |
3352 | net->nft.gencursor = gencursor_next(net); | 3389 | net->nft.gencursor = gencursor_next(net); |
@@ -3491,12 +3528,12 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3491 | } | 3528 | } |
3492 | nft_trans_destroy(trans); | 3529 | nft_trans_destroy(trans); |
3493 | } else { | 3530 | } else { |
3494 | list_del(&trans->ctx.table->list); | 3531 | list_del_rcu(&trans->ctx.table->list); |
3495 | } | 3532 | } |
3496 | break; | 3533 | break; |
3497 | case NFT_MSG_DELTABLE: | 3534 | case NFT_MSG_DELTABLE: |
3498 | list_add_tail(&trans->ctx.table->list, | 3535 | list_add_tail_rcu(&trans->ctx.table->list, |
3499 | &trans->ctx.afi->tables); | 3536 | &trans->ctx.afi->tables); |
3500 | nft_trans_destroy(trans); | 3537 | nft_trans_destroy(trans); |
3501 | break; | 3538 | break; |
3502 | case NFT_MSG_NEWCHAIN: | 3539 | case NFT_MSG_NEWCHAIN: |
@@ -3507,7 +3544,7 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3507 | nft_trans_destroy(trans); | 3544 | nft_trans_destroy(trans); |
3508 | } else { | 3545 | } else { |
3509 | trans->ctx.table->use--; | 3546 | trans->ctx.table->use--; |
3510 | list_del(&trans->ctx.chain->list); | 3547 | list_del_rcu(&trans->ctx.chain->list); |
3511 | if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT) && | 3548 | if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT) && |
3512 | trans->ctx.chain->flags & NFT_BASE_CHAIN) { | 3549 | trans->ctx.chain->flags & NFT_BASE_CHAIN) { |
3513 | nf_unregister_hooks(nft_base_chain(trans->ctx.chain)->ops, | 3550 | nf_unregister_hooks(nft_base_chain(trans->ctx.chain)->ops, |
@@ -3517,8 +3554,8 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3517 | break; | 3554 | break; |
3518 | case NFT_MSG_DELCHAIN: | 3555 | case NFT_MSG_DELCHAIN: |
3519 | trans->ctx.table->use++; | 3556 | trans->ctx.table->use++; |
3520 | list_add_tail(&trans->ctx.chain->list, | 3557 | list_add_tail_rcu(&trans->ctx.chain->list, |
3521 | &trans->ctx.table->chains); | 3558 | &trans->ctx.table->chains); |
3522 | nft_trans_destroy(trans); | 3559 | nft_trans_destroy(trans); |
3523 | break; | 3560 | break; |
3524 | case NFT_MSG_NEWRULE: | 3561 | case NFT_MSG_NEWRULE: |
@@ -3532,12 +3569,12 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3532 | break; | 3569 | break; |
3533 | case NFT_MSG_NEWSET: | 3570 | case NFT_MSG_NEWSET: |
3534 | trans->ctx.table->use--; | 3571 | trans->ctx.table->use--; |
3535 | list_del(&nft_trans_set(trans)->list); | 3572 | list_del_rcu(&nft_trans_set(trans)->list); |
3536 | break; | 3573 | break; |
3537 | case NFT_MSG_DELSET: | 3574 | case NFT_MSG_DELSET: |
3538 | trans->ctx.table->use++; | 3575 | trans->ctx.table->use++; |
3539 | list_add_tail(&nft_trans_set(trans)->list, | 3576 | list_add_tail_rcu(&nft_trans_set(trans)->list, |
3540 | &trans->ctx.table->sets); | 3577 | &trans->ctx.table->sets); |
3541 | nft_trans_destroy(trans); | 3578 | nft_trans_destroy(trans); |
3542 | break; | 3579 | break; |
3543 | case NFT_MSG_NEWSETELEM: | 3580 | case NFT_MSG_NEWSETELEM: |
@@ -3951,6 +3988,7 @@ static int nf_tables_init_net(struct net *net) | |||
3951 | { | 3988 | { |
3952 | INIT_LIST_HEAD(&net->nft.af_info); | 3989 | INIT_LIST_HEAD(&net->nft.af_info); |
3953 | INIT_LIST_HEAD(&net->nft.commit_list); | 3990 | INIT_LIST_HEAD(&net->nft.commit_list); |
3991 | net->nft.base_seq = 1; | ||
3954 | return 0; | 3992 | return 0; |
3955 | } | 3993 | } |
3956 | 3994 | ||
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 345acfb1720b..3b90eb2b2c55 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
@@ -109,7 +109,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) | |||
109 | struct nft_data data[NFT_REG_MAX + 1]; | 109 | struct nft_data data[NFT_REG_MAX + 1]; |
110 | unsigned int stackptr = 0; | 110 | unsigned int stackptr = 0; |
111 | struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; | 111 | struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; |
112 | struct nft_stats __percpu *stats; | 112 | struct nft_stats *stats; |
113 | int rulenum; | 113 | int rulenum; |
114 | /* | 114 | /* |
115 | * Cache cursor to avoid problems in case that the cursor is updated | 115 | * Cache cursor to avoid problems in case that the cursor is updated |
@@ -205,9 +205,11 @@ next_rule: | |||
205 | nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); | 205 | nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); |
206 | 206 | ||
207 | rcu_read_lock_bh(); | 207 | rcu_read_lock_bh(); |
208 | stats = rcu_dereference(nft_base_chain(basechain)->stats); | 208 | stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats)); |
209 | __this_cpu_inc(stats->pkts); | 209 | u64_stats_update_begin(&stats->syncp); |
210 | __this_cpu_add(stats->bytes, pkt->skb->len); | 210 | stats->pkts++; |
211 | stats->bytes += pkt->skb->len; | ||
212 | u64_stats_update_end(&stats->syncp); | ||
211 | rcu_read_unlock_bh(); | 213 | rcu_read_unlock_bh(); |
212 | 214 | ||
213 | return nft_base_chain(basechain)->policy; | 215 | return nft_base_chain(basechain)->policy; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 15c731f03fa6..e6fac7e3db52 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -636,7 +636,7 @@ static unsigned int netlink_poll(struct file *file, struct socket *sock, | |||
636 | while (nlk->cb_running && netlink_dump_space(nlk)) { | 636 | while (nlk->cb_running && netlink_dump_space(nlk)) { |
637 | err = netlink_dump(sk); | 637 | err = netlink_dump(sk); |
638 | if (err < 0) { | 638 | if (err < 0) { |
639 | sk->sk_err = err; | 639 | sk->sk_err = -err; |
640 | sk->sk_error_report(sk); | 640 | sk->sk_error_report(sk); |
641 | break; | 641 | break; |
642 | } | 642 | } |
@@ -2483,7 +2483,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
2483 | atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { | 2483 | atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { |
2484 | ret = netlink_dump(sk); | 2484 | ret = netlink_dump(sk); |
2485 | if (ret) { | 2485 | if (ret) { |
2486 | sk->sk_err = ret; | 2486 | sk->sk_err = -ret; |
2487 | sk->sk_error_report(sk); | 2487 | sk->sk_error_report(sk); |
2488 | } | 2488 | } |
2489 | } | 2489 | } |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index c36856a457ca..e70d8b18e962 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -551,6 +551,8 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
551 | 551 | ||
552 | case OVS_ACTION_ATTR_SAMPLE: | 552 | case OVS_ACTION_ATTR_SAMPLE: |
553 | err = sample(dp, skb, a); | 553 | err = sample(dp, skb, a); |
554 | if (unlikely(err)) /* skb already freed. */ | ||
555 | return err; | ||
554 | break; | 556 | break; |
555 | } | 557 | } |
556 | 558 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 0d407bca81e3..9db4bf6740d1 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2013 Nicira, Inc. | 2 | * Copyright (c) 2007-2014 Nicira, Inc. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of version 2 of the GNU General Public | 5 | * modify it under the terms of version 2 of the GNU General Public |
@@ -276,7 +276,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) | |||
276 | OVS_CB(skb)->flow = flow; | 276 | OVS_CB(skb)->flow = flow; |
277 | OVS_CB(skb)->pkt_key = &key; | 277 | OVS_CB(skb)->pkt_key = &key; |
278 | 278 | ||
279 | ovs_flow_stats_update(OVS_CB(skb)->flow, skb); | 279 | ovs_flow_stats_update(OVS_CB(skb)->flow, key.tp.flags, skb); |
280 | ovs_execute_actions(dp, skb); | 280 | ovs_execute_actions(dp, skb); |
281 | stats_counter = &stats->n_hit; | 281 | stats_counter = &stats->n_hit; |
282 | 282 | ||
@@ -889,8 +889,11 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
889 | } | 889 | } |
890 | /* The unmasked key has to be the same for flow updates. */ | 890 | /* The unmasked key has to be the same for flow updates. */ |
891 | if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) { | 891 | if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) { |
892 | error = -EEXIST; | 892 | flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); |
893 | goto err_unlock_ovs; | 893 | if (!flow) { |
894 | error = -ENOENT; | ||
895 | goto err_unlock_ovs; | ||
896 | } | ||
894 | } | 897 | } |
895 | /* Update actions. */ | 898 | /* Update actions. */ |
896 | old_acts = ovsl_dereference(flow->sf_acts); | 899 | old_acts = ovsl_dereference(flow->sf_acts); |
@@ -981,16 +984,12 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
981 | goto err_unlock_ovs; | 984 | goto err_unlock_ovs; |
982 | } | 985 | } |
983 | /* Check that the flow exists. */ | 986 | /* Check that the flow exists. */ |
984 | flow = ovs_flow_tbl_lookup(&dp->table, &key); | 987 | flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); |
985 | if (unlikely(!flow)) { | 988 | if (unlikely(!flow)) { |
986 | error = -ENOENT; | 989 | error = -ENOENT; |
987 | goto err_unlock_ovs; | 990 | goto err_unlock_ovs; |
988 | } | 991 | } |
989 | /* The unmasked key has to be the same for flow updates. */ | 992 | |
990 | if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) { | ||
991 | error = -EEXIST; | ||
992 | goto err_unlock_ovs; | ||
993 | } | ||
994 | /* Update actions, if present. */ | 993 | /* Update actions, if present. */ |
995 | if (likely(acts)) { | 994 | if (likely(acts)) { |
996 | old_acts = ovsl_dereference(flow->sf_acts); | 995 | old_acts = ovsl_dereference(flow->sf_acts); |
@@ -1063,8 +1062,8 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1063 | goto unlock; | 1062 | goto unlock; |
1064 | } | 1063 | } |
1065 | 1064 | ||
1066 | flow = ovs_flow_tbl_lookup(&dp->table, &key); | 1065 | flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); |
1067 | if (!flow || !ovs_flow_cmp_unmasked_key(flow, &match)) { | 1066 | if (!flow) { |
1068 | err = -ENOENT; | 1067 | err = -ENOENT; |
1069 | goto unlock; | 1068 | goto unlock; |
1070 | } | 1069 | } |
@@ -1113,8 +1112,8 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
1113 | goto unlock; | 1112 | goto unlock; |
1114 | } | 1113 | } |
1115 | 1114 | ||
1116 | flow = ovs_flow_tbl_lookup(&dp->table, &key); | 1115 | flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); |
1117 | if (unlikely(!flow || !ovs_flow_cmp_unmasked_key(flow, &match))) { | 1116 | if (unlikely(!flow)) { |
1118 | err = -ENOENT; | 1117 | err = -ENOENT; |
1119 | goto unlock; | 1118 | goto unlock; |
1120 | } | 1119 | } |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 334751cb1528..d07ab538fc9d 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -61,10 +61,10 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies) | |||
61 | 61 | ||
62 | #define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF)) | 62 | #define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF)) |
63 | 63 | ||
64 | void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb) | 64 | void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, |
65 | struct sk_buff *skb) | ||
65 | { | 66 | { |
66 | struct flow_stats *stats; | 67 | struct flow_stats *stats; |
67 | __be16 tcp_flags = flow->key.tp.flags; | ||
68 | int node = numa_node_id(); | 68 | int node = numa_node_id(); |
69 | 69 | ||
70 | stats = rcu_dereference(flow->stats[node]); | 70 | stats = rcu_dereference(flow->stats[node]); |
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index ac395d2cd821..5e5aaed3a85b 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2013 Nicira, Inc. | 2 | * Copyright (c) 2007-2014 Nicira, Inc. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of version 2 of the GNU General Public | 5 | * modify it under the terms of version 2 of the GNU General Public |
@@ -180,7 +180,8 @@ struct arp_eth_header { | |||
180 | unsigned char ar_tip[4]; /* target IP address */ | 180 | unsigned char ar_tip[4]; /* target IP address */ |
181 | } __packed; | 181 | } __packed; |
182 | 182 | ||
183 | void ovs_flow_stats_update(struct sw_flow *, struct sk_buff *); | 183 | void ovs_flow_stats_update(struct sw_flow *, __be16 tcp_flags, |
184 | struct sk_buff *); | ||
184 | void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, | 185 | void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, |
185 | unsigned long *used, __be16 *tcp_flags); | 186 | unsigned long *used, __be16 *tcp_flags); |
186 | void ovs_flow_stats_clear(struct sw_flow *); | 187 | void ovs_flow_stats_clear(struct sw_flow *); |
diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index 574c3abc9b30..cf2d853646f0 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c | |||
@@ -456,6 +456,22 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl, | |||
456 | return ovs_flow_tbl_lookup_stats(tbl, key, &n_mask_hit); | 456 | return ovs_flow_tbl_lookup_stats(tbl, key, &n_mask_hit); |
457 | } | 457 | } |
458 | 458 | ||
459 | struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, | ||
460 | struct sw_flow_match *match) | ||
461 | { | ||
462 | struct table_instance *ti = rcu_dereference_ovsl(tbl->ti); | ||
463 | struct sw_flow_mask *mask; | ||
464 | struct sw_flow *flow; | ||
465 | |||
466 | /* Always called under ovs-mutex. */ | ||
467 | list_for_each_entry(mask, &tbl->mask_list, list) { | ||
468 | flow = masked_flow_lookup(ti, match->key, mask); | ||
469 | if (flow && ovs_flow_cmp_unmasked_key(flow, match)) /* Found */ | ||
470 | return flow; | ||
471 | } | ||
472 | return NULL; | ||
473 | } | ||
474 | |||
459 | int ovs_flow_tbl_num_masks(const struct flow_table *table) | 475 | int ovs_flow_tbl_num_masks(const struct flow_table *table) |
460 | { | 476 | { |
461 | struct sw_flow_mask *mask; | 477 | struct sw_flow_mask *mask; |
diff --git a/net/openvswitch/flow_table.h b/net/openvswitch/flow_table.h index ca8a5820f615..5918bff7f3f6 100644 --- a/net/openvswitch/flow_table.h +++ b/net/openvswitch/flow_table.h | |||
@@ -76,7 +76,8 @@ struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *, | |||
76 | u32 *n_mask_hit); | 76 | u32 *n_mask_hit); |
77 | struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *, | 77 | struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *, |
78 | const struct sw_flow_key *); | 78 | const struct sw_flow_key *); |
79 | 79 | struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, | |
80 | struct sw_flow_match *match); | ||
80 | bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, | 81 | bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, |
81 | struct sw_flow_match *match); | 82 | struct sw_flow_match *match); |
82 | 83 | ||
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 35ec4fed09e2..f49148a07da2 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -110,6 +110,22 @@ static int gre_rcv(struct sk_buff *skb, | |||
110 | return PACKET_RCVD; | 110 | return PACKET_RCVD; |
111 | } | 111 | } |
112 | 112 | ||
113 | /* Called with rcu_read_lock and BH disabled. */ | ||
114 | static int gre_err(struct sk_buff *skb, u32 info, | ||
115 | const struct tnl_ptk_info *tpi) | ||
116 | { | ||
117 | struct ovs_net *ovs_net; | ||
118 | struct vport *vport; | ||
119 | |||
120 | ovs_net = net_generic(dev_net(skb->dev), ovs_net_id); | ||
121 | vport = rcu_dereference(ovs_net->vport_net.gre_vport); | ||
122 | |||
123 | if (unlikely(!vport)) | ||
124 | return PACKET_REJECT; | ||
125 | else | ||
126 | return PACKET_RCVD; | ||
127 | } | ||
128 | |||
113 | static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | 129 | static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) |
114 | { | 130 | { |
115 | struct net *net = ovs_dp_get_net(vport->dp); | 131 | struct net *net = ovs_dp_get_net(vport->dp); |
@@ -186,6 +202,7 @@ error: | |||
186 | 202 | ||
187 | static struct gre_cisco_protocol gre_protocol = { | 203 | static struct gre_cisco_protocol gre_protocol = { |
188 | .handler = gre_rcv, | 204 | .handler = gre_rcv, |
205 | .err_handler = gre_err, | ||
189 | .priority = 1, | 206 | .priority = 1, |
190 | }; | 207 | }; |
191 | 208 | ||
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index c39b583ace32..70c0be8d0121 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/errno.h> | 38 | #include <linux/errno.h> |
39 | #include <linux/rtnetlink.h> | 39 | #include <linux/rtnetlink.h> |
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/bitmap.h> | ||
41 | #include <net/netlink.h> | 42 | #include <net/netlink.h> |
42 | #include <net/act_api.h> | 43 | #include <net/act_api.h> |
43 | #include <net/pkt_cls.h> | 44 | #include <net/pkt_cls.h> |
@@ -460,17 +461,25 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg) | |||
460 | return 0; | 461 | return 0; |
461 | } | 462 | } |
462 | 463 | ||
464 | #define NR_U32_NODE (1<<12) | ||
463 | static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) | 465 | static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) |
464 | { | 466 | { |
465 | struct tc_u_knode *n; | 467 | struct tc_u_knode *n; |
466 | unsigned int i = 0x7FF; | 468 | unsigned long i; |
469 | unsigned long *bitmap = kzalloc(BITS_TO_LONGS(NR_U32_NODE) * sizeof(unsigned long), | ||
470 | GFP_KERNEL); | ||
471 | if (!bitmap) | ||
472 | return handle | 0xFFF; | ||
467 | 473 | ||
468 | for (n = ht->ht[TC_U32_HASH(handle)]; n; n = n->next) | 474 | for (n = ht->ht[TC_U32_HASH(handle)]; n; n = n->next) |
469 | if (i < TC_U32_NODE(n->handle)) | 475 | set_bit(TC_U32_NODE(n->handle), bitmap); |
470 | i = TC_U32_NODE(n->handle); | ||
471 | i++; | ||
472 | 476 | ||
473 | return handle | (i > 0xFFF ? 0xFFF : i); | 477 | i = find_next_zero_bit(bitmap, NR_U32_NODE, 0x800); |
478 | if (i >= NR_U32_NODE) | ||
479 | i = find_next_zero_bit(bitmap, NR_U32_NODE, 1); | ||
480 | |||
481 | kfree(bitmap); | ||
482 | return handle | (i >= NR_U32_NODE ? 0xFFF : i); | ||
474 | } | 483 | } |
475 | 484 | ||
476 | static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { | 485 | static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 85c64658bd0b..b6842fdb53d4 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -366,9 +366,10 @@ fail: | |||
366 | * specification [SCTP] and any extensions for a list of possible | 366 | * specification [SCTP] and any extensions for a list of possible |
367 | * error formats. | 367 | * error formats. |
368 | */ | 368 | */ |
369 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | 369 | struct sctp_ulpevent * |
370 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | 370 | sctp_ulpevent_make_remote_error(const struct sctp_association *asoc, |
371 | __u16 flags, gfp_t gfp) | 371 | struct sctp_chunk *chunk, __u16 flags, |
372 | gfp_t gfp) | ||
372 | { | 373 | { |
373 | struct sctp_ulpevent *event; | 374 | struct sctp_ulpevent *event; |
374 | struct sctp_remote_error *sre; | 375 | struct sctp_remote_error *sre; |
@@ -387,8 +388,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | |||
387 | /* Copy the skb to a new skb with room for us to prepend | 388 | /* Copy the skb to a new skb with room for us to prepend |
388 | * notification with. | 389 | * notification with. |
389 | */ | 390 | */ |
390 | skb = skb_copy_expand(chunk->skb, sizeof(struct sctp_remote_error), | 391 | skb = skb_copy_expand(chunk->skb, sizeof(*sre), 0, gfp); |
391 | 0, gfp); | ||
392 | 392 | ||
393 | /* Pull off the rest of the cause TLV from the chunk. */ | 393 | /* Pull off the rest of the cause TLV from the chunk. */ |
394 | skb_pull(chunk->skb, elen); | 394 | skb_pull(chunk->skb, elen); |
@@ -399,62 +399,21 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | |||
399 | event = sctp_skb2event(skb); | 399 | event = sctp_skb2event(skb); |
400 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); | 400 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); |
401 | 401 | ||
402 | sre = (struct sctp_remote_error *) | 402 | sre = (struct sctp_remote_error *) skb_push(skb, sizeof(*sre)); |
403 | skb_push(skb, sizeof(struct sctp_remote_error)); | ||
404 | 403 | ||
405 | /* Trim the buffer to the right length. */ | 404 | /* Trim the buffer to the right length. */ |
406 | skb_trim(skb, sizeof(struct sctp_remote_error) + elen); | 405 | skb_trim(skb, sizeof(*sre) + elen); |
407 | 406 | ||
408 | /* Socket Extensions for SCTP | 407 | /* RFC6458, Section 6.1.3. SCTP_REMOTE_ERROR */ |
409 | * 5.3.1.3 SCTP_REMOTE_ERROR | 408 | memset(sre, 0, sizeof(*sre)); |
410 | * | ||
411 | * sre_type: | ||
412 | * It should be SCTP_REMOTE_ERROR. | ||
413 | */ | ||
414 | sre->sre_type = SCTP_REMOTE_ERROR; | 409 | sre->sre_type = SCTP_REMOTE_ERROR; |
415 | |||
416 | /* | ||
417 | * Socket Extensions for SCTP | ||
418 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
419 | * | ||
420 | * sre_flags: 16 bits (unsigned integer) | ||
421 | * Currently unused. | ||
422 | */ | ||
423 | sre->sre_flags = 0; | 410 | sre->sre_flags = 0; |
424 | |||
425 | /* Socket Extensions for SCTP | ||
426 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
427 | * | ||
428 | * sre_length: sizeof (__u32) | ||
429 | * | ||
430 | * This field is the total length of the notification data, | ||
431 | * including the notification header. | ||
432 | */ | ||
433 | sre->sre_length = skb->len; | 411 | sre->sre_length = skb->len; |
434 | |||
435 | /* Socket Extensions for SCTP | ||
436 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
437 | * | ||
438 | * sre_error: 16 bits (unsigned integer) | ||
439 | * This value represents one of the Operational Error causes defined in | ||
440 | * the SCTP specification, in network byte order. | ||
441 | */ | ||
442 | sre->sre_error = cause; | 412 | sre->sre_error = cause; |
443 | |||
444 | /* Socket Extensions for SCTP | ||
445 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
446 | * | ||
447 | * sre_assoc_id: sizeof (sctp_assoc_t) | ||
448 | * | ||
449 | * The association id field, holds the identifier for the association. | ||
450 | * All notifications for a given association have the same association | ||
451 | * identifier. For TCP style socket, this field is ignored. | ||
452 | */ | ||
453 | sctp_ulpevent_set_owner(event, asoc); | 413 | sctp_ulpevent_set_owner(event, asoc); |
454 | sre->sre_assoc_id = sctp_assoc2id(asoc); | 414 | sre->sre_assoc_id = sctp_assoc2id(asoc); |
455 | 415 | ||
456 | return event; | 416 | return event; |
457 | |||
458 | fail: | 417 | fail: |
459 | return NULL; | 418 | return NULL; |
460 | } | 419 | } |
@@ -899,7 +858,9 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event) | |||
899 | return notification->sn_header.sn_type; | 858 | return notification->sn_header.sn_type; |
900 | } | 859 | } |
901 | 860 | ||
902 | /* Copy out the sndrcvinfo into a msghdr. */ | 861 | /* RFC6458, Section 5.3.2. SCTP Header Information Structure |
862 | * (SCTP_SNDRCV, DEPRECATED) | ||
863 | */ | ||
903 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | 864 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, |
904 | struct msghdr *msghdr) | 865 | struct msghdr *msghdr) |
905 | { | 866 | { |
@@ -908,74 +869,21 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
908 | if (sctp_ulpevent_is_notification(event)) | 869 | if (sctp_ulpevent_is_notification(event)) |
909 | return; | 870 | return; |
910 | 871 | ||
911 | /* Sockets API Extensions for SCTP | 872 | memset(&sinfo, 0, sizeof(sinfo)); |
912 | * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) | ||
913 | * | ||
914 | * sinfo_stream: 16 bits (unsigned integer) | ||
915 | * | ||
916 | * For recvmsg() the SCTP stack places the message's stream number in | ||
917 | * this value. | ||
918 | */ | ||
919 | sinfo.sinfo_stream = event->stream; | 873 | sinfo.sinfo_stream = event->stream; |
920 | /* sinfo_ssn: 16 bits (unsigned integer) | ||
921 | * | ||
922 | * For recvmsg() this value contains the stream sequence number that | ||
923 | * the remote endpoint placed in the DATA chunk. For fragmented | ||
924 | * messages this is the same number for all deliveries of the message | ||
925 | * (if more than one recvmsg() is needed to read the message). | ||
926 | */ | ||
927 | sinfo.sinfo_ssn = event->ssn; | 874 | sinfo.sinfo_ssn = event->ssn; |
928 | /* sinfo_ppid: 32 bits (unsigned integer) | ||
929 | * | ||
930 | * In recvmsg() this value is | ||
931 | * the same information that was passed by the upper layer in the peer | ||
932 | * application. Please note that byte order issues are NOT accounted | ||
933 | * for and this information is passed opaquely by the SCTP stack from | ||
934 | * one end to the other. | ||
935 | */ | ||
936 | sinfo.sinfo_ppid = event->ppid; | 875 | sinfo.sinfo_ppid = event->ppid; |
937 | /* sinfo_flags: 16 bits (unsigned integer) | ||
938 | * | ||
939 | * This field may contain any of the following flags and is composed of | ||
940 | * a bitwise OR of these values. | ||
941 | * | ||
942 | * recvmsg() flags: | ||
943 | * | ||
944 | * SCTP_UNORDERED - This flag is present when the message was sent | ||
945 | * non-ordered. | ||
946 | */ | ||
947 | sinfo.sinfo_flags = event->flags; | 876 | sinfo.sinfo_flags = event->flags; |
948 | /* sinfo_tsn: 32 bit (unsigned integer) | ||
949 | * | ||
950 | * For the receiving side, this field holds a TSN that was | ||
951 | * assigned to one of the SCTP Data Chunks. | ||
952 | */ | ||
953 | sinfo.sinfo_tsn = event->tsn; | 877 | sinfo.sinfo_tsn = event->tsn; |
954 | /* sinfo_cumtsn: 32 bit (unsigned integer) | ||
955 | * | ||
956 | * This field will hold the current cumulative TSN as | ||
957 | * known by the underlying SCTP layer. Note this field is | ||
958 | * ignored when sending and only valid for a receive | ||
959 | * operation when sinfo_flags are set to SCTP_UNORDERED. | ||
960 | */ | ||
961 | sinfo.sinfo_cumtsn = event->cumtsn; | 878 | sinfo.sinfo_cumtsn = event->cumtsn; |
962 | /* sinfo_assoc_id: sizeof (sctp_assoc_t) | ||
963 | * | ||
964 | * The association handle field, sinfo_assoc_id, holds the identifier | ||
965 | * for the association announced in the COMMUNICATION_UP notification. | ||
966 | * All notifications for a given association have the same identifier. | ||
967 | * Ignored for one-to-one style sockets. | ||
968 | */ | ||
969 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); | 879 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); |
970 | 880 | /* Context value that is set via SCTP_CONTEXT socket option. */ | |
971 | /* context value that is set via SCTP_CONTEXT socket option. */ | ||
972 | sinfo.sinfo_context = event->asoc->default_rcv_context; | 881 | sinfo.sinfo_context = event->asoc->default_rcv_context; |
973 | |||
974 | /* These fields are not used while receiving. */ | 882 | /* These fields are not used while receiving. */ |
975 | sinfo.sinfo_timetolive = 0; | 883 | sinfo.sinfo_timetolive = 0; |
976 | 884 | ||
977 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, | 885 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, |
978 | sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); | 886 | sizeof(sinfo), &sinfo); |
979 | } | 887 | } |
980 | 888 | ||
981 | /* Do accounting for bytes received and hold a reference to the association | 889 | /* Do accounting for bytes received and hold a reference to the association |
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 26631679a1fa..55c6c9d3e1ce 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -559,6 +559,7 @@ receive: | |||
559 | 559 | ||
560 | buf = node->bclink.deferred_head; | 560 | buf = node->bclink.deferred_head; |
561 | node->bclink.deferred_head = buf->next; | 561 | node->bclink.deferred_head = buf->next; |
562 | buf->next = NULL; | ||
562 | node->bclink.deferred_size--; | 563 | node->bclink.deferred_size--; |
563 | goto receive; | 564 | goto receive; |
564 | } | 565 | } |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 8be6e94a1ca9..0a37a472c29f 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -101,9 +101,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* tipc_buf_append(): Append a buffer to the fragment list of another buffer | 103 | /* tipc_buf_append(): Append a buffer to the fragment list of another buffer |
104 | * Let first buffer become head buffer | 104 | * @*headbuf: in: NULL for first frag, otherwise value returned from prev call |
105 | * Returns 1 and sets *buf to headbuf if chain is complete, otherwise 0 | 105 | * out: set when successful non-complete reassembly, otherwise NULL |
106 | * Leaves headbuf pointer at NULL if failure | 106 | * @*buf: in: the buffer to append. Always defined |
107 | * out: head buf after sucessful complete reassembly, otherwise NULL | ||
108 | * Returns 1 when reassembly complete, otherwise 0 | ||
107 | */ | 109 | */ |
108 | int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) | 110 | int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) |
109 | { | 111 | { |
@@ -122,6 +124,7 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) | |||
122 | goto out_free; | 124 | goto out_free; |
123 | head = *headbuf = frag; | 125 | head = *headbuf = frag; |
124 | skb_frag_list_init(head); | 126 | skb_frag_list_init(head); |
127 | *buf = NULL; | ||
125 | return 0; | 128 | return 0; |
126 | } | 129 | } |
127 | if (!head) | 130 | if (!head) |
@@ -150,5 +153,7 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) | |||
150 | out_free: | 153 | out_free: |
151 | pr_warn_ratelimited("Unable to build fragment list\n"); | 154 | pr_warn_ratelimited("Unable to build fragment list\n"); |
152 | kfree_skb(*buf); | 155 | kfree_skb(*buf); |
156 | kfree_skb(*headbuf); | ||
157 | *buf = *headbuf = NULL; | ||
153 | return 0; | 158 | return 0; |
154 | } | 159 | } |
diff --git a/net/wireless/core.h b/net/wireless/core.h index e9afbf10e756..7e3a3cef7df9 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -424,7 +424,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start) | |||
424 | if (end >= start) | 424 | if (end >= start) |
425 | return jiffies_to_msecs(end - start); | 425 | return jiffies_to_msecs(end - start); |
426 | 426 | ||
427 | return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); | 427 | return jiffies_to_msecs(end + (ULONG_MAX - start) + 1); |
428 | } | 428 | } |
429 | 429 | ||
430 | void | 430 | void |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ba4f1723c83a..6668daf69326 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1497,18 +1497,17 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1497 | } | 1497 | } |
1498 | CMD(start_p2p_device, START_P2P_DEVICE); | 1498 | CMD(start_p2p_device, START_P2P_DEVICE); |
1499 | CMD(set_mcast_rate, SET_MCAST_RATE); | 1499 | CMD(set_mcast_rate, SET_MCAST_RATE); |
1500 | #ifdef CONFIG_NL80211_TESTMODE | ||
1501 | CMD(testmode_cmd, TESTMODE); | ||
1502 | #endif | ||
1500 | if (state->split) { | 1503 | if (state->split) { |
1501 | CMD(crit_proto_start, CRIT_PROTOCOL_START); | 1504 | CMD(crit_proto_start, CRIT_PROTOCOL_START); |
1502 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); | 1505 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); |
1503 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1506 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1504 | CMD(channel_switch, CHANNEL_SWITCH); | 1507 | CMD(channel_switch, CHANNEL_SWITCH); |
1508 | CMD(set_qos_map, SET_QOS_MAP); | ||
1505 | } | 1509 | } |
1506 | CMD(set_qos_map, SET_QOS_MAP); | 1510 | /* add into the if now */ |
1507 | |||
1508 | #ifdef CONFIG_NL80211_TESTMODE | ||
1509 | CMD(testmode_cmd, TESTMODE); | ||
1510 | #endif | ||
1511 | |||
1512 | #undef CMD | 1511 | #undef CMD |
1513 | 1512 | ||
1514 | if (rdev->ops->connect || rdev->ops->auth) { | 1513 | if (rdev->ops->connect || rdev->ops->auth) { |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 558b0e3a02d8..1afdf45db38f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -935,7 +935,7 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, | |||
935 | if (!band_rule_found) | 935 | if (!band_rule_found) |
936 | band_rule_found = freq_in_rule_band(fr, center_freq); | 936 | band_rule_found = freq_in_rule_band(fr, center_freq); |
937 | 937 | ||
938 | bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(5)); | 938 | bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20)); |
939 | 939 | ||
940 | if (band_rule_found && bw_fits) | 940 | if (band_rule_found && bw_fits) |
941 | return rr; | 941 | return rr; |
@@ -1019,10 +1019,10 @@ static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, | |||
1019 | } | 1019 | } |
1020 | #endif | 1020 | #endif |
1021 | 1021 | ||
1022 | /* Find an ieee80211_reg_rule such that a 5MHz channel with frequency | 1022 | /* |
1023 | * chan->center_freq fits there. | 1023 | * Note that right now we assume the desired channel bandwidth |
1024 | * If there is no such reg_rule, disable the channel, otherwise set the | 1024 | * is always 20 MHz for each individual channel (HT40 uses 20 MHz |
1025 | * flags corresponding to the bandwidths allowed in the particular reg_rule | 1025 | * per channel, the primary and the extension channel). |
1026 | */ | 1026 | */ |
1027 | static void handle_channel(struct wiphy *wiphy, | 1027 | static void handle_channel(struct wiphy *wiphy, |
1028 | enum nl80211_reg_initiator initiator, | 1028 | enum nl80211_reg_initiator initiator, |
@@ -1083,12 +1083,8 @@ static void handle_channel(struct wiphy *wiphy, | |||
1083 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | 1083 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1084 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1084 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1085 | 1085 | ||
1086 | if (max_bandwidth_khz < MHZ_TO_KHZ(10)) | ||
1087 | bw_flags = IEEE80211_CHAN_NO_10MHZ; | ||
1088 | if (max_bandwidth_khz < MHZ_TO_KHZ(20)) | ||
1089 | bw_flags |= IEEE80211_CHAN_NO_20MHZ; | ||
1090 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1086 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1091 | bw_flags |= IEEE80211_CHAN_NO_HT40; | 1087 | bw_flags = IEEE80211_CHAN_NO_HT40; |
1092 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) | 1088 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) |
1093 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; | 1089 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; |
1094 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) | 1090 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) |
@@ -1522,12 +1518,8 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1522 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | 1518 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1523 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1519 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1524 | 1520 | ||
1525 | if (max_bandwidth_khz < MHZ_TO_KHZ(10)) | ||
1526 | bw_flags = IEEE80211_CHAN_NO_10MHZ; | ||
1527 | if (max_bandwidth_khz < MHZ_TO_KHZ(20)) | ||
1528 | bw_flags |= IEEE80211_CHAN_NO_20MHZ; | ||
1529 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1521 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1530 | bw_flags |= IEEE80211_CHAN_NO_HT40; | 1522 | bw_flags = IEEE80211_CHAN_NO_HT40; |
1531 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) | 1523 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) |
1532 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; | 1524 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; |
1533 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) | 1525 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) |