diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-11 00:00:29 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-11 00:00:29 -0400 |
commit | e4d35be584be88a3db3fa5635a97c62a2ec5aafe (patch) | |
tree | fc22a7fb65697306edd71411959ccee6df60c64d /net | |
parent | 99d825822eade8d827a1817357cbf3f889a552d6 (diff) | |
parent | 38b78a5f18584db6fa7441e0f4531b283b0e6725 (diff) |
Merge branch 'ovl-fixes' into for-linus
Diffstat (limited to 'net')
108 files changed, 1105 insertions, 626 deletions
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 3315b9a598af..4026f198a734 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c | |||
@@ -32,10 +32,21 @@ | |||
32 | 32 | ||
33 | #include "bat_v_elp.h" | 33 | #include "bat_v_elp.h" |
34 | #include "bat_v_ogm.h" | 34 | #include "bat_v_ogm.h" |
35 | #include "hard-interface.h" | ||
35 | #include "hash.h" | 36 | #include "hash.h" |
36 | #include "originator.h" | 37 | #include "originator.h" |
37 | #include "packet.h" | 38 | #include "packet.h" |
38 | 39 | ||
40 | static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) | ||
41 | { | ||
42 | /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can | ||
43 | * set the interface as ACTIVE right away, without any risk of race | ||
44 | * condition | ||
45 | */ | ||
46 | if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) | ||
47 | hard_iface->if_status = BATADV_IF_ACTIVE; | ||
48 | } | ||
49 | |||
39 | static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) | 50 | static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) |
40 | { | 51 | { |
41 | int ret; | 52 | int ret; |
@@ -274,6 +285,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, | |||
274 | 285 | ||
275 | static struct batadv_algo_ops batadv_batman_v __read_mostly = { | 286 | static struct batadv_algo_ops batadv_batman_v __read_mostly = { |
276 | .name = "BATMAN_V", | 287 | .name = "BATMAN_V", |
288 | .bat_iface_activate = batadv_v_iface_activate, | ||
277 | .bat_iface_enable = batadv_v_iface_enable, | 289 | .bat_iface_enable = batadv_v_iface_enable, |
278 | .bat_iface_disable = batadv_v_iface_disable, | 290 | .bat_iface_disable = batadv_v_iface_disable, |
279 | .bat_iface_update_mac = batadv_v_iface_update_mac, | 291 | .bat_iface_update_mac = batadv_v_iface_update_mac, |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index e96d7c745b4a..3e6b2624f980 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -568,6 +568,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, | |||
568 | * be sent to | 568 | * be sent to |
569 | * @bat_priv: the bat priv with all the soft interface information | 569 | * @bat_priv: the bat priv with all the soft interface information |
570 | * @ip_dst: ipv4 to look up in the DHT | 570 | * @ip_dst: ipv4 to look up in the DHT |
571 | * @vid: VLAN identifier | ||
571 | * | 572 | * |
572 | * An originator O is selected if and only if its DHT_ID value is one of three | 573 | * An originator O is selected if and only if its DHT_ID value is one of three |
573 | * closest values (from the LEFT, with wrap around if needed) then the hash | 574 | * closest values (from the LEFT, with wrap around if needed) then the hash |
@@ -576,7 +577,8 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, | |||
576 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. | 577 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. |
577 | */ | 578 | */ |
578 | static struct batadv_dat_candidate * | 579 | static struct batadv_dat_candidate * |
579 | batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | 580 | batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, |
581 | unsigned short vid) | ||
580 | { | 582 | { |
581 | int select; | 583 | int select; |
582 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; | 584 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; |
@@ -592,7 +594,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | |||
592 | return NULL; | 594 | return NULL; |
593 | 595 | ||
594 | dat.ip = ip_dst; | 596 | dat.ip = ip_dst; |
595 | dat.vid = 0; | 597 | dat.vid = vid; |
596 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, | 598 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, |
597 | BATADV_DAT_ADDR_MAX); | 599 | BATADV_DAT_ADDR_MAX); |
598 | 600 | ||
@@ -612,6 +614,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | |||
612 | * @bat_priv: the bat priv with all the soft interface information | 614 | * @bat_priv: the bat priv with all the soft interface information |
613 | * @skb: payload to send | 615 | * @skb: payload to send |
614 | * @ip: the DHT key | 616 | * @ip: the DHT key |
617 | * @vid: VLAN identifier | ||
615 | * @packet_subtype: unicast4addr packet subtype to use | 618 | * @packet_subtype: unicast4addr packet subtype to use |
616 | * | 619 | * |
617 | * This function copies the skb with pskb_copy() and is sent as unicast packet | 620 | * This function copies the skb with pskb_copy() and is sent as unicast packet |
@@ -622,7 +625,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | |||
622 | */ | 625 | */ |
623 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, | 626 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, |
624 | struct sk_buff *skb, __be32 ip, | 627 | struct sk_buff *skb, __be32 ip, |
625 | int packet_subtype) | 628 | unsigned short vid, int packet_subtype) |
626 | { | 629 | { |
627 | int i; | 630 | int i; |
628 | bool ret = false; | 631 | bool ret = false; |
@@ -631,7 +634,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, | |||
631 | struct sk_buff *tmp_skb; | 634 | struct sk_buff *tmp_skb; |
632 | struct batadv_dat_candidate *cand; | 635 | struct batadv_dat_candidate *cand; |
633 | 636 | ||
634 | cand = batadv_dat_select_candidates(bat_priv, ip); | 637 | cand = batadv_dat_select_candidates(bat_priv, ip, vid); |
635 | if (!cand) | 638 | if (!cand) |
636 | goto out; | 639 | goto out; |
637 | 640 | ||
@@ -1022,7 +1025,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | |||
1022 | ret = true; | 1025 | ret = true; |
1023 | } else { | 1026 | } else { |
1024 | /* Send the request to the DHT */ | 1027 | /* Send the request to the DHT */ |
1025 | ret = batadv_dat_send_data(bat_priv, skb, ip_dst, | 1028 | ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, |
1026 | BATADV_P_DAT_DHT_GET); | 1029 | BATADV_P_DAT_DHT_GET); |
1027 | } | 1030 | } |
1028 | out: | 1031 | out: |
@@ -1150,8 +1153,8 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | |||
1150 | /* Send the ARP reply to the candidates for both the IP addresses that | 1153 | /* Send the ARP reply to the candidates for both the IP addresses that |
1151 | * the node obtained from the ARP reply | 1154 | * the node obtained from the ARP reply |
1152 | */ | 1155 | */ |
1153 | batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); | 1156 | batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); |
1154 | batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); | 1157 | batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); |
1155 | } | 1158 | } |
1156 | 1159 | ||
1157 | /** | 1160 | /** |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index b22b2775a0a5..0a7deaf2670a 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -407,6 +407,9 @@ batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) | |||
407 | 407 | ||
408 | batadv_update_min_mtu(hard_iface->soft_iface); | 408 | batadv_update_min_mtu(hard_iface->soft_iface); |
409 | 409 | ||
410 | if (bat_priv->bat_algo_ops->bat_iface_activate) | ||
411 | bat_priv->bat_algo_ops->bat_iface_activate(hard_iface); | ||
412 | |||
410 | out: | 413 | out: |
411 | if (primary_if) | 414 | if (primary_if) |
412 | batadv_hardif_put(primary_if); | 415 | batadv_hardif_put(primary_if); |
@@ -572,8 +575,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, | |||
572 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 575 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
573 | struct batadv_hard_iface *primary_if = NULL; | 576 | struct batadv_hard_iface *primary_if = NULL; |
574 | 577 | ||
575 | if (hard_iface->if_status == BATADV_IF_ACTIVE) | 578 | batadv_hardif_deactivate_interface(hard_iface); |
576 | batadv_hardif_deactivate_interface(hard_iface); | ||
577 | 579 | ||
578 | if (hard_iface->if_status != BATADV_IF_INACTIVE) | 580 | if (hard_iface->if_status != BATADV_IF_INACTIVE) |
579 | goto out; | 581 | goto out; |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index e4cbb0753e37..c355a824713c 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -250,7 +250,6 @@ static void batadv_neigh_node_release(struct kref *ref) | |||
250 | { | 250 | { |
251 | struct hlist_node *node_tmp; | 251 | struct hlist_node *node_tmp; |
252 | struct batadv_neigh_node *neigh_node; | 252 | struct batadv_neigh_node *neigh_node; |
253 | struct batadv_hardif_neigh_node *hardif_neigh; | ||
254 | struct batadv_neigh_ifinfo *neigh_ifinfo; | 253 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
255 | struct batadv_algo_ops *bao; | 254 | struct batadv_algo_ops *bao; |
256 | 255 | ||
@@ -262,13 +261,7 @@ static void batadv_neigh_node_release(struct kref *ref) | |||
262 | batadv_neigh_ifinfo_put(neigh_ifinfo); | 261 | batadv_neigh_ifinfo_put(neigh_ifinfo); |
263 | } | 262 | } |
264 | 263 | ||
265 | hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, | 264 | batadv_hardif_neigh_put(neigh_node->hardif_neigh); |
266 | neigh_node->addr); | ||
267 | if (hardif_neigh) { | ||
268 | /* batadv_hardif_neigh_get() increases refcount too */ | ||
269 | batadv_hardif_neigh_put(hardif_neigh); | ||
270 | batadv_hardif_neigh_put(hardif_neigh); | ||
271 | } | ||
272 | 265 | ||
273 | if (bao->bat_neigh_free) | 266 | if (bao->bat_neigh_free) |
274 | bao->bat_neigh_free(neigh_node); | 267 | bao->bat_neigh_free(neigh_node); |
@@ -663,6 +656,11 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, | |||
663 | ether_addr_copy(neigh_node->addr, neigh_addr); | 656 | ether_addr_copy(neigh_node->addr, neigh_addr); |
664 | neigh_node->if_incoming = hard_iface; | 657 | neigh_node->if_incoming = hard_iface; |
665 | neigh_node->orig_node = orig_node; | 658 | neigh_node->orig_node = orig_node; |
659 | neigh_node->last_seen = jiffies; | ||
660 | |||
661 | /* increment unique neighbor refcount */ | ||
662 | kref_get(&hardif_neigh->refcount); | ||
663 | neigh_node->hardif_neigh = hardif_neigh; | ||
666 | 664 | ||
667 | /* extra reference for return */ | 665 | /* extra reference for return */ |
668 | kref_init(&neigh_node->refcount); | 666 | kref_init(&neigh_node->refcount); |
@@ -672,9 +670,6 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, | |||
672 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | 670 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); |
673 | spin_unlock_bh(&orig_node->neigh_list_lock); | 671 | spin_unlock_bh(&orig_node->neigh_list_lock); |
674 | 672 | ||
675 | /* increment unique neighbor refcount */ | ||
676 | kref_get(&hardif_neigh->refcount); | ||
677 | |||
678 | batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, | 673 | batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, |
679 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", | 674 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", |
680 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); | 675 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 4dd646a52f1a..b781bf753250 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, | |||
105 | neigh_node = NULL; | 105 | neigh_node = NULL; |
106 | 106 | ||
107 | spin_lock_bh(&orig_node->neigh_list_lock); | 107 | spin_lock_bh(&orig_node->neigh_list_lock); |
108 | /* curr_router used earlier may not be the current orig_ifinfo->router | ||
109 | * anymore because it was dereferenced outside of the neigh_list_lock | ||
110 | * protected region. After the new best neighbor has replace the current | ||
111 | * best neighbor the reference counter needs to decrease. Consequently, | ||
112 | * the code needs to ensure the curr_router variable contains a pointer | ||
113 | * to the replaced best neighbor. | ||
114 | */ | ||
115 | curr_router = rcu_dereference_protected(orig_ifinfo->router, true); | ||
116 | |||
108 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); | 117 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); |
109 | spin_unlock_bh(&orig_node->neigh_list_lock); | 118 | spin_unlock_bh(&orig_node->neigh_list_lock); |
110 | batadv_orig_ifinfo_put(orig_ifinfo); | 119 | batadv_orig_ifinfo_put(orig_ifinfo); |
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3ce06e0a91b1..76417850d3fc 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, | |||
675 | 675 | ||
676 | if (pending) { | 676 | if (pending) { |
677 | hlist_del(&forw_packet->list); | 677 | hlist_del(&forw_packet->list); |
678 | if (!forw_packet->own) | ||
679 | atomic_inc(&bat_priv->bcast_queue_left); | ||
680 | |||
678 | batadv_forw_packet_free(forw_packet); | 681 | batadv_forw_packet_free(forw_packet); |
679 | } | 682 | } |
680 | } | 683 | } |
@@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, | |||
702 | 705 | ||
703 | if (pending) { | 706 | if (pending) { |
704 | hlist_del(&forw_packet->list); | 707 | hlist_del(&forw_packet->list); |
708 | if (!forw_packet->own) | ||
709 | atomic_inc(&bat_priv->batman_queue_left); | ||
710 | |||
705 | batadv_forw_packet_free(forw_packet); | 711 | batadv_forw_packet_free(forw_packet); |
706 | } | 712 | } |
707 | } | 713 | } |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0710379491bf..8a136b6a1ff0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
408 | */ | 408 | */ |
409 | nf_reset(skb); | 409 | nf_reset(skb); |
410 | 410 | ||
411 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | ||
412 | goto dropped; | ||
413 | |||
411 | vid = batadv_get_vid(skb, 0); | 414 | vid = batadv_get_vid(skb, 0); |
412 | ethhdr = eth_hdr(skb); | 415 | ethhdr = eth_hdr(skb); |
413 | 416 | ||
414 | switch (ntohs(ethhdr->h_proto)) { | 417 | switch (ntohs(ethhdr->h_proto)) { |
415 | case ETH_P_8021Q: | 418 | case ETH_P_8021Q: |
419 | if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) | ||
420 | goto dropped; | ||
421 | |||
416 | vhdr = (struct vlan_ethhdr *)skb->data; | 422 | vhdr = (struct vlan_ethhdr *)skb->data; |
417 | 423 | ||
418 | if (vhdr->h_vlan_encapsulated_proto != ethertype) | 424 | if (vhdr->h_vlan_encapsulated_proto != ethertype) |
@@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
424 | } | 430 | } |
425 | 431 | ||
426 | /* skb->dev & skb->pkt_type are set here */ | 432 | /* skb->dev & skb->pkt_type are set here */ |
427 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | ||
428 | goto dropped; | ||
429 | skb->protocol = eth_type_trans(skb, soft_iface); | 433 | skb->protocol = eth_type_trans(skb, soft_iface); |
430 | 434 | ||
431 | /* should not be necessary anymore as we use skb_pull_rcsum() | 435 | /* should not be necessary anymore as we use skb_pull_rcsum() |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 0b43e86328a5..9b4551a86535 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -215,6 +215,8 @@ static void batadv_tt_local_entry_release(struct kref *ref) | |||
215 | tt_local_entry = container_of(ref, struct batadv_tt_local_entry, | 215 | tt_local_entry = container_of(ref, struct batadv_tt_local_entry, |
216 | common.refcount); | 216 | common.refcount); |
217 | 217 | ||
218 | batadv_softif_vlan_put(tt_local_entry->vlan); | ||
219 | |||
218 | kfree_rcu(tt_local_entry, common.rcu); | 220 | kfree_rcu(tt_local_entry, common.rcu); |
219 | } | 221 | } |
220 | 222 | ||
@@ -673,6 +675,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, | |||
673 | kref_get(&tt_local->common.refcount); | 675 | kref_get(&tt_local->common.refcount); |
674 | tt_local->last_seen = jiffies; | 676 | tt_local->last_seen = jiffies; |
675 | tt_local->common.added_at = tt_local->last_seen; | 677 | tt_local->common.added_at = tt_local->last_seen; |
678 | tt_local->vlan = vlan; | ||
676 | 679 | ||
677 | /* the batman interface mac and multicast addresses should never be | 680 | /* the batman interface mac and multicast addresses should never be |
678 | * purged | 681 | * purged |
@@ -991,7 +994,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
991 | struct batadv_tt_common_entry *tt_common_entry; | 994 | struct batadv_tt_common_entry *tt_common_entry; |
992 | struct batadv_tt_local_entry *tt_local; | 995 | struct batadv_tt_local_entry *tt_local; |
993 | struct batadv_hard_iface *primary_if; | 996 | struct batadv_hard_iface *primary_if; |
994 | struct batadv_softif_vlan *vlan; | ||
995 | struct hlist_head *head; | 997 | struct hlist_head *head; |
996 | unsigned short vid; | 998 | unsigned short vid; |
997 | u32 i; | 999 | u32 i; |
@@ -1027,14 +1029,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
1027 | last_seen_msecs = last_seen_msecs % 1000; | 1029 | last_seen_msecs = last_seen_msecs % 1000; |
1028 | 1030 | ||
1029 | no_purge = tt_common_entry->flags & np_flag; | 1031 | no_purge = tt_common_entry->flags & np_flag; |
1030 | |||
1031 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
1032 | if (!vlan) { | ||
1033 | seq_printf(seq, "Cannot retrieve VLAN %d\n", | ||
1034 | BATADV_PRINT_VID(vid)); | ||
1035 | continue; | ||
1036 | } | ||
1037 | |||
1038 | seq_printf(seq, | 1032 | seq_printf(seq, |
1039 | " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", | 1033 | " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", |
1040 | tt_common_entry->addr, | 1034 | tt_common_entry->addr, |
@@ -1052,9 +1046,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
1052 | BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), | 1046 | BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), |
1053 | no_purge ? 0 : last_seen_secs, | 1047 | no_purge ? 0 : last_seen_secs, |
1054 | no_purge ? 0 : last_seen_msecs, | 1048 | no_purge ? 0 : last_seen_msecs, |
1055 | vlan->tt.crc); | 1049 | tt_local->vlan->tt.crc); |
1056 | |||
1057 | batadv_softif_vlan_put(vlan); | ||
1058 | } | 1050 | } |
1059 | rcu_read_unlock(); | 1051 | rcu_read_unlock(); |
1060 | } | 1052 | } |
@@ -1099,7 +1091,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, | |||
1099 | { | 1091 | { |
1100 | struct batadv_tt_local_entry *tt_local_entry; | 1092 | struct batadv_tt_local_entry *tt_local_entry; |
1101 | u16 flags, curr_flags = BATADV_NO_FLAGS; | 1093 | u16 flags, curr_flags = BATADV_NO_FLAGS; |
1102 | struct batadv_softif_vlan *vlan; | ||
1103 | void *tt_entry_exists; | 1094 | void *tt_entry_exists; |
1104 | 1095 | ||
1105 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); | 1096 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); |
@@ -1139,14 +1130,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, | |||
1139 | /* extra call to free the local tt entry */ | 1130 | /* extra call to free the local tt entry */ |
1140 | batadv_tt_local_entry_put(tt_local_entry); | 1131 | batadv_tt_local_entry_put(tt_local_entry); |
1141 | 1132 | ||
1142 | /* decrease the reference held for this vlan */ | ||
1143 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
1144 | if (!vlan) | ||
1145 | goto out; | ||
1146 | |||
1147 | batadv_softif_vlan_put(vlan); | ||
1148 | batadv_softif_vlan_put(vlan); | ||
1149 | |||
1150 | out: | 1133 | out: |
1151 | if (tt_local_entry) | 1134 | if (tt_local_entry) |
1152 | batadv_tt_local_entry_put(tt_local_entry); | 1135 | batadv_tt_local_entry_put(tt_local_entry); |
@@ -1219,7 +1202,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) | |||
1219 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 1202 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
1220 | struct batadv_tt_common_entry *tt_common_entry; | 1203 | struct batadv_tt_common_entry *tt_common_entry; |
1221 | struct batadv_tt_local_entry *tt_local; | 1204 | struct batadv_tt_local_entry *tt_local; |
1222 | struct batadv_softif_vlan *vlan; | ||
1223 | struct hlist_node *node_tmp; | 1205 | struct hlist_node *node_tmp; |
1224 | struct hlist_head *head; | 1206 | struct hlist_head *head; |
1225 | u32 i; | 1207 | u32 i; |
@@ -1241,14 +1223,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) | |||
1241 | struct batadv_tt_local_entry, | 1223 | struct batadv_tt_local_entry, |
1242 | common); | 1224 | common); |
1243 | 1225 | ||
1244 | /* decrease the reference held for this vlan */ | ||
1245 | vlan = batadv_softif_vlan_get(bat_priv, | ||
1246 | tt_common_entry->vid); | ||
1247 | if (vlan) { | ||
1248 | batadv_softif_vlan_put(vlan); | ||
1249 | batadv_softif_vlan_put(vlan); | ||
1250 | } | ||
1251 | |||
1252 | batadv_tt_local_entry_put(tt_local); | 1226 | batadv_tt_local_entry_put(tt_local); |
1253 | } | 1227 | } |
1254 | spin_unlock_bh(list_lock); | 1228 | spin_unlock_bh(list_lock); |
@@ -3309,7 +3283,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) | |||
3309 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; | 3283 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; |
3310 | struct batadv_tt_common_entry *tt_common; | 3284 | struct batadv_tt_common_entry *tt_common; |
3311 | struct batadv_tt_local_entry *tt_local; | 3285 | struct batadv_tt_local_entry *tt_local; |
3312 | struct batadv_softif_vlan *vlan; | ||
3313 | struct hlist_node *node_tmp; | 3286 | struct hlist_node *node_tmp; |
3314 | struct hlist_head *head; | 3287 | struct hlist_head *head; |
3315 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 3288 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
@@ -3339,13 +3312,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) | |||
3339 | struct batadv_tt_local_entry, | 3312 | struct batadv_tt_local_entry, |
3340 | common); | 3313 | common); |
3341 | 3314 | ||
3342 | /* decrease the reference held for this vlan */ | ||
3343 | vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); | ||
3344 | if (vlan) { | ||
3345 | batadv_softif_vlan_put(vlan); | ||
3346 | batadv_softif_vlan_put(vlan); | ||
3347 | } | ||
3348 | |||
3349 | batadv_tt_local_entry_put(tt_local); | 3315 | batadv_tt_local_entry_put(tt_local); |
3350 | } | 3316 | } |
3351 | spin_unlock_bh(list_lock); | 3317 | spin_unlock_bh(list_lock); |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 9abfb3e73c34..1e47fbe8bb7b 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -433,6 +433,7 @@ struct batadv_hardif_neigh_node { | |||
433 | * @ifinfo_lock: lock protecting private ifinfo members and list | 433 | * @ifinfo_lock: lock protecting private ifinfo members and list |
434 | * @if_incoming: pointer to incoming hard-interface | 434 | * @if_incoming: pointer to incoming hard-interface |
435 | * @last_seen: when last packet via this neighbor was received | 435 | * @last_seen: when last packet via this neighbor was received |
436 | * @hardif_neigh: hardif_neigh of this neighbor | ||
436 | * @refcount: number of contexts the object is used | 437 | * @refcount: number of contexts the object is used |
437 | * @rcu: struct used for freeing in an RCU-safe manner | 438 | * @rcu: struct used for freeing in an RCU-safe manner |
438 | */ | 439 | */ |
@@ -444,6 +445,7 @@ struct batadv_neigh_node { | |||
444 | spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ | 445 | spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ |
445 | struct batadv_hard_iface *if_incoming; | 446 | struct batadv_hard_iface *if_incoming; |
446 | unsigned long last_seen; | 447 | unsigned long last_seen; |
448 | struct batadv_hardif_neigh_node *hardif_neigh; | ||
447 | struct kref refcount; | 449 | struct kref refcount; |
448 | struct rcu_head rcu; | 450 | struct rcu_head rcu; |
449 | }; | 451 | }; |
@@ -1073,10 +1075,12 @@ struct batadv_tt_common_entry { | |||
1073 | * struct batadv_tt_local_entry - translation table local entry data | 1075 | * struct batadv_tt_local_entry - translation table local entry data |
1074 | * @common: general translation table data | 1076 | * @common: general translation table data |
1075 | * @last_seen: timestamp used for purging stale tt local entries | 1077 | * @last_seen: timestamp used for purging stale tt local entries |
1078 | * @vlan: soft-interface vlan of the entry | ||
1076 | */ | 1079 | */ |
1077 | struct batadv_tt_local_entry { | 1080 | struct batadv_tt_local_entry { |
1078 | struct batadv_tt_common_entry common; | 1081 | struct batadv_tt_common_entry common; |
1079 | unsigned long last_seen; | 1082 | unsigned long last_seen; |
1083 | struct batadv_softif_vlan *vlan; | ||
1080 | }; | 1084 | }; |
1081 | 1085 | ||
1082 | /** | 1086 | /** |
@@ -1250,6 +1254,8 @@ struct batadv_forw_packet { | |||
1250 | * struct batadv_algo_ops - mesh algorithm callbacks | 1254 | * struct batadv_algo_ops - mesh algorithm callbacks |
1251 | * @list: list node for the batadv_algo_list | 1255 | * @list: list node for the batadv_algo_list |
1252 | * @name: name of the algorithm | 1256 | * @name: name of the algorithm |
1257 | * @bat_iface_activate: start routing mechanisms when hard-interface is brought | ||
1258 | * up | ||
1253 | * @bat_iface_enable: init routing info when hard-interface is enabled | 1259 | * @bat_iface_enable: init routing info when hard-interface is enabled |
1254 | * @bat_iface_disable: de-init routing info when hard-interface is disabled | 1260 | * @bat_iface_disable: de-init routing info when hard-interface is disabled |
1255 | * @bat_iface_update_mac: (re-)init mac addresses of the protocol information | 1261 | * @bat_iface_update_mac: (re-)init mac addresses of the protocol information |
@@ -1277,6 +1283,7 @@ struct batadv_forw_packet { | |||
1277 | struct batadv_algo_ops { | 1283 | struct batadv_algo_ops { |
1278 | struct hlist_node list; | 1284 | struct hlist_node list; |
1279 | char *name; | 1285 | char *name; |
1286 | void (*bat_iface_activate)(struct batadv_hard_iface *hard_iface); | ||
1280 | int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); | 1287 | int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); |
1281 | void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); | 1288 | void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); |
1282 | void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); | 1289 | void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); |
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 253bc77eda3b..7dbc80d01eb0 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c | |||
@@ -61,6 +61,19 @@ static void __mdb_entry_fill_flags(struct br_mdb_entry *e, unsigned char flags) | |||
61 | e->flags |= MDB_FLAGS_OFFLOAD; | 61 | e->flags |= MDB_FLAGS_OFFLOAD; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip) | ||
65 | { | ||
66 | memset(ip, 0, sizeof(struct br_ip)); | ||
67 | ip->vid = entry->vid; | ||
68 | ip->proto = entry->addr.proto; | ||
69 | if (ip->proto == htons(ETH_P_IP)) | ||
70 | ip->u.ip4 = entry->addr.u.ip4; | ||
71 | #if IS_ENABLED(CONFIG_IPV6) | ||
72 | else | ||
73 | ip->u.ip6 = entry->addr.u.ip6; | ||
74 | #endif | ||
75 | } | ||
76 | |||
64 | static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, | 77 | static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, |
65 | struct net_device *dev) | 78 | struct net_device *dev) |
66 | { | 79 | { |
@@ -243,9 +256,45 @@ static inline size_t rtnl_mdb_nlmsg_size(void) | |||
243 | + nla_total_size(sizeof(struct br_mdb_entry)); | 256 | + nla_total_size(sizeof(struct br_mdb_entry)); |
244 | } | 257 | } |
245 | 258 | ||
246 | static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, | 259 | struct br_mdb_complete_info { |
247 | int type, struct net_bridge_port_group *pg) | 260 | struct net_bridge_port *port; |
261 | struct br_ip ip; | ||
262 | }; | ||
263 | |||
264 | static void br_mdb_complete(struct net_device *dev, int err, void *priv) | ||
248 | { | 265 | { |
266 | struct br_mdb_complete_info *data = priv; | ||
267 | struct net_bridge_port_group __rcu **pp; | ||
268 | struct net_bridge_port_group *p; | ||
269 | struct net_bridge_mdb_htable *mdb; | ||
270 | struct net_bridge_mdb_entry *mp; | ||
271 | struct net_bridge_port *port = data->port; | ||
272 | struct net_bridge *br = port->br; | ||
273 | |||
274 | if (err) | ||
275 | goto err; | ||
276 | |||
277 | spin_lock_bh(&br->multicast_lock); | ||
278 | mdb = mlock_dereference(br->mdb, br); | ||
279 | mp = br_mdb_ip_get(mdb, &data->ip); | ||
280 | if (!mp) | ||
281 | goto out; | ||
282 | for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; | ||
283 | pp = &p->next) { | ||
284 | if (p->port != port) | ||
285 | continue; | ||
286 | p->flags |= MDB_PG_FLAGS_OFFLOAD; | ||
287 | } | ||
288 | out: | ||
289 | spin_unlock_bh(&br->multicast_lock); | ||
290 | err: | ||
291 | kfree(priv); | ||
292 | } | ||
293 | |||
294 | static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p, | ||
295 | struct br_mdb_entry *entry, int type) | ||
296 | { | ||
297 | struct br_mdb_complete_info *complete_info; | ||
249 | struct switchdev_obj_port_mdb mdb = { | 298 | struct switchdev_obj_port_mdb mdb = { |
250 | .obj = { | 299 | .obj = { |
251 | .id = SWITCHDEV_OBJ_ID_PORT_MDB, | 300 | .id = SWITCHDEV_OBJ_ID_PORT_MDB, |
@@ -268,9 +317,14 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, | |||
268 | 317 | ||
269 | mdb.obj.orig_dev = port_dev; | 318 | mdb.obj.orig_dev = port_dev; |
270 | if (port_dev && type == RTM_NEWMDB) { | 319 | if (port_dev && type == RTM_NEWMDB) { |
271 | err = switchdev_port_obj_add(port_dev, &mdb.obj); | 320 | complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC); |
272 | if (!err && pg) | 321 | if (complete_info) { |
273 | pg->flags |= MDB_PG_FLAGS_OFFLOAD; | 322 | complete_info->port = p; |
323 | __mdb_entry_to_br_ip(entry, &complete_info->ip); | ||
324 | mdb.obj.complete_priv = complete_info; | ||
325 | mdb.obj.complete = br_mdb_complete; | ||
326 | switchdev_port_obj_add(port_dev, &mdb.obj); | ||
327 | } | ||
274 | } else if (port_dev && type == RTM_DELMDB) { | 328 | } else if (port_dev && type == RTM_DELMDB) { |
275 | switchdev_port_obj_del(port_dev, &mdb.obj); | 329 | switchdev_port_obj_del(port_dev, &mdb.obj); |
276 | } | 330 | } |
@@ -291,21 +345,21 @@ errout: | |||
291 | rtnl_set_sk_err(net, RTNLGRP_MDB, err); | 345 | rtnl_set_sk_err(net, RTNLGRP_MDB, err); |
292 | } | 346 | } |
293 | 347 | ||
294 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | 348 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |
295 | int type) | 349 | struct br_ip *group, int type, u8 flags) |
296 | { | 350 | { |
297 | struct br_mdb_entry entry; | 351 | struct br_mdb_entry entry; |
298 | 352 | ||
299 | memset(&entry, 0, sizeof(entry)); | 353 | memset(&entry, 0, sizeof(entry)); |
300 | entry.ifindex = pg->port->dev->ifindex; | 354 | entry.ifindex = port->dev->ifindex; |
301 | entry.addr.proto = pg->addr.proto; | 355 | entry.addr.proto = group->proto; |
302 | entry.addr.u.ip4 = pg->addr.u.ip4; | 356 | entry.addr.u.ip4 = group->u.ip4; |
303 | #if IS_ENABLED(CONFIG_IPV6) | 357 | #if IS_ENABLED(CONFIG_IPV6) |
304 | entry.addr.u.ip6 = pg->addr.u.ip6; | 358 | entry.addr.u.ip6 = group->u.ip6; |
305 | #endif | 359 | #endif |
306 | entry.vid = pg->addr.vid; | 360 | entry.vid = group->vid; |
307 | __mdb_entry_fill_flags(&entry, pg->flags); | 361 | __mdb_entry_fill_flags(&entry, flags); |
308 | __br_mdb_notify(dev, &entry, type, pg); | 362 | __br_mdb_notify(dev, port, &entry, type); |
309 | } | 363 | } |
310 | 364 | ||
311 | static int nlmsg_populate_rtr_fill(struct sk_buff *skb, | 365 | static int nlmsg_populate_rtr_fill(struct sk_buff *skb, |
@@ -450,8 +504,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
450 | } | 504 | } |
451 | 505 | ||
452 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | 506 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, |
453 | struct br_ip *group, unsigned char state, | 507 | struct br_ip *group, unsigned char state) |
454 | struct net_bridge_port_group **pg) | ||
455 | { | 508 | { |
456 | struct net_bridge_mdb_entry *mp; | 509 | struct net_bridge_mdb_entry *mp; |
457 | struct net_bridge_port_group *p; | 510 | struct net_bridge_port_group *p; |
@@ -482,7 +535,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | |||
482 | if (unlikely(!p)) | 535 | if (unlikely(!p)) |
483 | return -ENOMEM; | 536 | return -ENOMEM; |
484 | rcu_assign_pointer(*pp, p); | 537 | rcu_assign_pointer(*pp, p); |
485 | *pg = p; | ||
486 | if (state == MDB_TEMPORARY) | 538 | if (state == MDB_TEMPORARY) |
487 | mod_timer(&p->timer, now + br->multicast_membership_interval); | 539 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
488 | 540 | ||
@@ -490,8 +542,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | |||
490 | } | 542 | } |
491 | 543 | ||
492 | static int __br_mdb_add(struct net *net, struct net_bridge *br, | 544 | static int __br_mdb_add(struct net *net, struct net_bridge *br, |
493 | struct br_mdb_entry *entry, | 545 | struct br_mdb_entry *entry) |
494 | struct net_bridge_port_group **pg) | ||
495 | { | 546 | { |
496 | struct br_ip ip; | 547 | struct br_ip ip; |
497 | struct net_device *dev; | 548 | struct net_device *dev; |
@@ -509,18 +560,10 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, | |||
509 | if (!p || p->br != br || p->state == BR_STATE_DISABLED) | 560 | if (!p || p->br != br || p->state == BR_STATE_DISABLED) |
510 | return -EINVAL; | 561 | return -EINVAL; |
511 | 562 | ||
512 | memset(&ip, 0, sizeof(ip)); | 563 | __mdb_entry_to_br_ip(entry, &ip); |
513 | ip.vid = entry->vid; | ||
514 | ip.proto = entry->addr.proto; | ||
515 | if (ip.proto == htons(ETH_P_IP)) | ||
516 | ip.u.ip4 = entry->addr.u.ip4; | ||
517 | #if IS_ENABLED(CONFIG_IPV6) | ||
518 | else | ||
519 | ip.u.ip6 = entry->addr.u.ip6; | ||
520 | #endif | ||
521 | 564 | ||
522 | spin_lock_bh(&br->multicast_lock); | 565 | spin_lock_bh(&br->multicast_lock); |
523 | ret = br_mdb_add_group(br, p, &ip, entry->state, pg); | 566 | ret = br_mdb_add_group(br, p, &ip, entry->state); |
524 | spin_unlock_bh(&br->multicast_lock); | 567 | spin_unlock_bh(&br->multicast_lock); |
525 | return ret; | 568 | return ret; |
526 | } | 569 | } |
@@ -528,7 +571,6 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, | |||
528 | static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | 571 | static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) |
529 | { | 572 | { |
530 | struct net *net = sock_net(skb->sk); | 573 | struct net *net = sock_net(skb->sk); |
531 | struct net_bridge_port_group *pg; | ||
532 | struct net_bridge_vlan_group *vg; | 574 | struct net_bridge_vlan_group *vg; |
533 | struct net_device *dev, *pdev; | 575 | struct net_device *dev, *pdev; |
534 | struct br_mdb_entry *entry; | 576 | struct br_mdb_entry *entry; |
@@ -558,15 +600,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
558 | if (br_vlan_enabled(br) && vg && entry->vid == 0) { | 600 | if (br_vlan_enabled(br) && vg && entry->vid == 0) { |
559 | list_for_each_entry(v, &vg->vlan_list, vlist) { | 601 | list_for_each_entry(v, &vg->vlan_list, vlist) { |
560 | entry->vid = v->vid; | 602 | entry->vid = v->vid; |
561 | err = __br_mdb_add(net, br, entry, &pg); | 603 | err = __br_mdb_add(net, br, entry); |
562 | if (err) | 604 | if (err) |
563 | break; | 605 | break; |
564 | __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | 606 | __br_mdb_notify(dev, p, entry, RTM_NEWMDB); |
565 | } | 607 | } |
566 | } else { | 608 | } else { |
567 | err = __br_mdb_add(net, br, entry, &pg); | 609 | err = __br_mdb_add(net, br, entry); |
568 | if (!err) | 610 | if (!err) |
569 | __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | 611 | __br_mdb_notify(dev, p, entry, RTM_NEWMDB); |
570 | } | 612 | } |
571 | 613 | ||
572 | return err; | 614 | return err; |
@@ -584,15 +626,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) | |||
584 | if (!netif_running(br->dev) || br->multicast_disabled) | 626 | if (!netif_running(br->dev) || br->multicast_disabled) |
585 | return -EINVAL; | 627 | return -EINVAL; |
586 | 628 | ||
587 | memset(&ip, 0, sizeof(ip)); | 629 | __mdb_entry_to_br_ip(entry, &ip); |
588 | ip.vid = entry->vid; | ||
589 | ip.proto = entry->addr.proto; | ||
590 | if (ip.proto == htons(ETH_P_IP)) | ||
591 | ip.u.ip4 = entry->addr.u.ip4; | ||
592 | #if IS_ENABLED(CONFIG_IPV6) | ||
593 | else | ||
594 | ip.u.ip6 = entry->addr.u.ip6; | ||
595 | #endif | ||
596 | 630 | ||
597 | spin_lock_bh(&br->multicast_lock); | 631 | spin_lock_bh(&br->multicast_lock); |
598 | mdb = mlock_dereference(br->mdb, br); | 632 | mdb = mlock_dereference(br->mdb, br); |
@@ -662,12 +696,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
662 | entry->vid = v->vid; | 696 | entry->vid = v->vid; |
663 | err = __br_mdb_del(br, entry); | 697 | err = __br_mdb_del(br, entry); |
664 | if (!err) | 698 | if (!err) |
665 | __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | 699 | __br_mdb_notify(dev, p, entry, RTM_DELMDB); |
666 | } | 700 | } |
667 | } else { | 701 | } else { |
668 | err = __br_mdb_del(br, entry); | 702 | err = __br_mdb_del(br, entry); |
669 | if (!err) | 703 | if (!err) |
670 | __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | 704 | __br_mdb_notify(dev, p, entry, RTM_DELMDB); |
671 | } | 705 | } |
672 | 706 | ||
673 | return err; | 707 | return err; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a4c15df2b792..191ea66e4d92 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -283,7 +283,8 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
283 | rcu_assign_pointer(*pp, p->next); | 283 | rcu_assign_pointer(*pp, p->next); |
284 | hlist_del_init(&p->mglist); | 284 | hlist_del_init(&p->mglist); |
285 | del_timer(&p->timer); | 285 | del_timer(&p->timer); |
286 | br_mdb_notify(br->dev, p, RTM_DELMDB); | 286 | br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, |
287 | p->flags); | ||
287 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | 288 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
288 | 289 | ||
289 | if (!mp->ports && !mp->mglist && | 290 | if (!mp->ports && !mp->mglist && |
@@ -705,7 +706,7 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
705 | if (unlikely(!p)) | 706 | if (unlikely(!p)) |
706 | goto err; | 707 | goto err; |
707 | rcu_assign_pointer(*pp, p); | 708 | rcu_assign_pointer(*pp, p); |
708 | br_mdb_notify(br->dev, p, RTM_NEWMDB); | 709 | br_mdb_notify(br->dev, port, group, RTM_NEWMDB, 0); |
709 | 710 | ||
710 | found: | 711 | found: |
711 | mod_timer(&p->timer, now + br->multicast_membership_interval); | 712 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
@@ -1461,7 +1462,8 @@ br_multicast_leave_group(struct net_bridge *br, | |||
1461 | hlist_del_init(&p->mglist); | 1462 | hlist_del_init(&p->mglist); |
1462 | del_timer(&p->timer); | 1463 | del_timer(&p->timer); |
1463 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | 1464 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
1464 | br_mdb_notify(br->dev, p, RTM_DELMDB); | 1465 | br_mdb_notify(br->dev, port, group, RTM_DELMDB, |
1466 | p->flags); | ||
1465 | 1467 | ||
1466 | if (!mp->ports && !mp->mglist && | 1468 | if (!mp->ports && !mp->mglist && |
1467 | netif_running(br->dev)) | 1469 | netif_running(br->dev)) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1b5d145dfcbf..d9da857182ef 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -560,8 +560,8 @@ br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, | |||
560 | unsigned char flags); | 560 | unsigned char flags); |
561 | void br_mdb_init(void); | 561 | void br_mdb_init(void); |
562 | void br_mdb_uninit(void); | 562 | void br_mdb_uninit(void); |
563 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | 563 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |
564 | int type); | 564 | struct br_ip *group, int type, u8 flags); |
565 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, | 565 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, |
566 | int type); | 566 | int type); |
567 | 567 | ||
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index e23449094188..9cb7044d0801 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -582,7 +582,7 @@ int br_set_ageing_time(struct net_bridge *br, u32 ageing_time) | |||
582 | int err; | 582 | int err; |
583 | 583 | ||
584 | err = switchdev_port_attr_set(br->dev, &attr); | 584 | err = switchdev_port_attr_set(br->dev, &attr); |
585 | if (err) | 585 | if (err && err != -EOPNOTSUPP) |
586 | return err; | 586 | return err; |
587 | 587 | ||
588 | br->ageing_time = t; | 588 | br->ageing_time = t; |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 67b2e27999aa..5a61f35412a0 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -370,7 +370,11 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, | |||
370 | left - sizeof(struct ebt_entry_match) < m->match_size) | 370 | left - sizeof(struct ebt_entry_match) < m->match_size) |
371 | return -EINVAL; | 371 | return -EINVAL; |
372 | 372 | ||
373 | match = xt_request_find_match(NFPROTO_BRIDGE, m->u.name, 0); | 373 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); |
374 | if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { | ||
375 | request_module("ebt_%s", m->u.name); | ||
376 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); | ||
377 | } | ||
374 | if (IS_ERR(match)) | 378 | if (IS_ERR(match)) |
375 | return PTR_ERR(match); | 379 | return PTR_ERR(match); |
376 | m->u.match = match; | 380 | m->u.match = match; |
@@ -1521,6 +1525,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1521 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 1525 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
1522 | return -EFAULT; | 1526 | return -EFAULT; |
1523 | 1527 | ||
1528 | tmp.name[sizeof(tmp.name) - 1] = '\0'; | ||
1529 | |||
1524 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); | 1530 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
1525 | if (!t) | 1531 | if (!t) |
1526 | return ret; | 1532 | return ret; |
@@ -2332,6 +2338,8 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, | |||
2332 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 2338 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
2333 | return -EFAULT; | 2339 | return -EFAULT; |
2334 | 2340 | ||
2341 | tmp.name[sizeof(tmp.name) - 1] = '\0'; | ||
2342 | |||
2335 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); | 2343 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
2336 | if (!t) | 2344 | if (!t) |
2337 | return ret; | 2345 | return ret; |
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index adc8d7221dbb..77f7e7a9ebe1 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c | |||
@@ -40,7 +40,8 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, | |||
40 | /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) | 40 | /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) |
41 | * or the bridge port (NF_BRIDGE PREROUTING). | 41 | * or the bridge port (NF_BRIDGE PREROUTING). |
42 | */ | 42 | */ |
43 | static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | 43 | static void nft_reject_br_send_v4_tcp_reset(struct net *net, |
44 | struct sk_buff *oldskb, | ||
44 | const struct net_device *dev, | 45 | const struct net_device *dev, |
45 | int hook) | 46 | int hook) |
46 | { | 47 | { |
@@ -48,7 +49,6 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | |||
48 | struct iphdr *niph; | 49 | struct iphdr *niph; |
49 | const struct tcphdr *oth; | 50 | const struct tcphdr *oth; |
50 | struct tcphdr _oth; | 51 | struct tcphdr _oth; |
51 | struct net *net = sock_net(oldskb->sk); | ||
52 | 52 | ||
53 | if (!nft_bridge_iphdr_validate(oldskb)) | 53 | if (!nft_bridge_iphdr_validate(oldskb)) |
54 | return; | 54 | return; |
@@ -75,7 +75,8 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | |||
75 | br_deliver(br_port_get_rcu(dev), nskb); | 75 | br_deliver(br_port_get_rcu(dev), nskb); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, | 78 | static void nft_reject_br_send_v4_unreach(struct net *net, |
79 | struct sk_buff *oldskb, | ||
79 | const struct net_device *dev, | 80 | const struct net_device *dev, |
80 | int hook, u8 code) | 81 | int hook, u8 code) |
81 | { | 82 | { |
@@ -86,7 +87,6 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, | |||
86 | void *payload; | 87 | void *payload; |
87 | __wsum csum; | 88 | __wsum csum; |
88 | u8 proto; | 89 | u8 proto; |
89 | struct net *net = sock_net(oldskb->sk); | ||
90 | 90 | ||
91 | if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) | 91 | if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) |
92 | return; | 92 | return; |
@@ -273,17 +273,17 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr, | |||
273 | case htons(ETH_P_IP): | 273 | case htons(ETH_P_IP): |
274 | switch (priv->type) { | 274 | switch (priv->type) { |
275 | case NFT_REJECT_ICMP_UNREACH: | 275 | case NFT_REJECT_ICMP_UNREACH: |
276 | nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, | 276 | nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, |
277 | pkt->hook, | 277 | pkt->in, pkt->hook, |
278 | priv->icmp_code); | 278 | priv->icmp_code); |
279 | break; | 279 | break; |
280 | case NFT_REJECT_TCP_RST: | 280 | case NFT_REJECT_TCP_RST: |
281 | nft_reject_br_send_v4_tcp_reset(pkt->skb, pkt->in, | 281 | nft_reject_br_send_v4_tcp_reset(pkt->net, pkt->skb, |
282 | pkt->hook); | 282 | pkt->in, pkt->hook); |
283 | break; | 283 | break; |
284 | case NFT_REJECT_ICMPX_UNREACH: | 284 | case NFT_REJECT_ICMPX_UNREACH: |
285 | nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, | 285 | nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, |
286 | pkt->hook, | 286 | pkt->in, pkt->hook, |
287 | nft_reject_icmp_code(priv->icmp_code)); | 287 | nft_reject_icmp_code(priv->icmp_code)); |
288 | break; | 288 | break; |
289 | } | 289 | } |
diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 6b923bcaa2a4..2bc5965fdd1e 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c | |||
@@ -293,13 +293,9 @@ int ceph_auth_create_authorizer(struct ceph_auth_client *ac, | |||
293 | } | 293 | } |
294 | EXPORT_SYMBOL(ceph_auth_create_authorizer); | 294 | EXPORT_SYMBOL(ceph_auth_create_authorizer); |
295 | 295 | ||
296 | void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, | 296 | void ceph_auth_destroy_authorizer(struct ceph_authorizer *a) |
297 | struct ceph_authorizer *a) | ||
298 | { | 297 | { |
299 | mutex_lock(&ac->mutex); | 298 | a->destroy(a); |
300 | if (ac->ops && ac->ops->destroy_authorizer) | ||
301 | ac->ops->destroy_authorizer(ac, a); | ||
302 | mutex_unlock(&ac->mutex); | ||
303 | } | 299 | } |
304 | EXPORT_SYMBOL(ceph_auth_destroy_authorizer); | 300 | EXPORT_SYMBOL(ceph_auth_destroy_authorizer); |
305 | 301 | ||
diff --git a/net/ceph/auth_none.c b/net/ceph/auth_none.c index 8c93fa8d81bc..5f836f02ae36 100644 --- a/net/ceph/auth_none.c +++ b/net/ceph/auth_none.c | |||
@@ -16,7 +16,6 @@ static void reset(struct ceph_auth_client *ac) | |||
16 | struct ceph_auth_none_info *xi = ac->private; | 16 | struct ceph_auth_none_info *xi = ac->private; |
17 | 17 | ||
18 | xi->starting = true; | 18 | xi->starting = true; |
19 | xi->built_authorizer = false; | ||
20 | } | 19 | } |
21 | 20 | ||
22 | static void destroy(struct ceph_auth_client *ac) | 21 | static void destroy(struct ceph_auth_client *ac) |
@@ -39,6 +38,27 @@ static int should_authenticate(struct ceph_auth_client *ac) | |||
39 | return xi->starting; | 38 | return xi->starting; |
40 | } | 39 | } |
41 | 40 | ||
41 | static int ceph_auth_none_build_authorizer(struct ceph_auth_client *ac, | ||
42 | struct ceph_none_authorizer *au) | ||
43 | { | ||
44 | void *p = au->buf; | ||
45 | void *const end = p + sizeof(au->buf); | ||
46 | int ret; | ||
47 | |||
48 | ceph_encode_8_safe(&p, end, 1, e_range); | ||
49 | ret = ceph_entity_name_encode(ac->name, &p, end); | ||
50 | if (ret < 0) | ||
51 | return ret; | ||
52 | |||
53 | ceph_encode_64_safe(&p, end, ac->global_id, e_range); | ||
54 | au->buf_len = p - (void *)au->buf; | ||
55 | dout("%s built authorizer len %d\n", __func__, au->buf_len); | ||
56 | return 0; | ||
57 | |||
58 | e_range: | ||
59 | return -ERANGE; | ||
60 | } | ||
61 | |||
42 | static int build_request(struct ceph_auth_client *ac, void *buf, void *end) | 62 | static int build_request(struct ceph_auth_client *ac, void *buf, void *end) |
43 | { | 63 | { |
44 | return 0; | 64 | return 0; |
@@ -57,32 +77,32 @@ static int handle_reply(struct ceph_auth_client *ac, int result, | |||
57 | return result; | 77 | return result; |
58 | } | 78 | } |
59 | 79 | ||
80 | static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a) | ||
81 | { | ||
82 | kfree(a); | ||
83 | } | ||
84 | |||
60 | /* | 85 | /* |
61 | * build an 'authorizer' with our entity_name and global_id. we can | 86 | * build an 'authorizer' with our entity_name and global_id. it is |
62 | * reuse a single static copy since it is identical for all services | 87 | * identical for all services we connect to. |
63 | * we connect to. | ||
64 | */ | 88 | */ |
65 | static int ceph_auth_none_create_authorizer( | 89 | static int ceph_auth_none_create_authorizer( |
66 | struct ceph_auth_client *ac, int peer_type, | 90 | struct ceph_auth_client *ac, int peer_type, |
67 | struct ceph_auth_handshake *auth) | 91 | struct ceph_auth_handshake *auth) |
68 | { | 92 | { |
69 | struct ceph_auth_none_info *ai = ac->private; | 93 | struct ceph_none_authorizer *au; |
70 | struct ceph_none_authorizer *au = &ai->au; | ||
71 | void *p, *end; | ||
72 | int ret; | 94 | int ret; |
73 | 95 | ||
74 | if (!ai->built_authorizer) { | 96 | au = kmalloc(sizeof(*au), GFP_NOFS); |
75 | p = au->buf; | 97 | if (!au) |
76 | end = p + sizeof(au->buf); | 98 | return -ENOMEM; |
77 | ceph_encode_8(&p, 1); | 99 | |
78 | ret = ceph_entity_name_encode(ac->name, &p, end - 8); | 100 | au->base.destroy = ceph_auth_none_destroy_authorizer; |
79 | if (ret < 0) | 101 | |
80 | goto bad; | 102 | ret = ceph_auth_none_build_authorizer(ac, au); |
81 | ceph_decode_need(&p, end, sizeof(u64), bad2); | 103 | if (ret) { |
82 | ceph_encode_64(&p, ac->global_id); | 104 | kfree(au); |
83 | au->buf_len = p - (void *)au->buf; | 105 | return ret; |
84 | ai->built_authorizer = true; | ||
85 | dout("built authorizer len %d\n", au->buf_len); | ||
86 | } | 106 | } |
87 | 107 | ||
88 | auth->authorizer = (struct ceph_authorizer *) au; | 108 | auth->authorizer = (struct ceph_authorizer *) au; |
@@ -92,17 +112,6 @@ static int ceph_auth_none_create_authorizer( | |||
92 | auth->authorizer_reply_buf_len = sizeof (au->reply_buf); | 112 | auth->authorizer_reply_buf_len = sizeof (au->reply_buf); |
93 | 113 | ||
94 | return 0; | 114 | return 0; |
95 | |||
96 | bad2: | ||
97 | ret = -ERANGE; | ||
98 | bad: | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac, | ||
103 | struct ceph_authorizer *a) | ||
104 | { | ||
105 | /* nothing to do */ | ||
106 | } | 115 | } |
107 | 116 | ||
108 | static const struct ceph_auth_client_ops ceph_auth_none_ops = { | 117 | static const struct ceph_auth_client_ops ceph_auth_none_ops = { |
@@ -114,7 +123,6 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { | |||
114 | .build_request = build_request, | 123 | .build_request = build_request, |
115 | .handle_reply = handle_reply, | 124 | .handle_reply = handle_reply, |
116 | .create_authorizer = ceph_auth_none_create_authorizer, | 125 | .create_authorizer = ceph_auth_none_create_authorizer, |
117 | .destroy_authorizer = ceph_auth_none_destroy_authorizer, | ||
118 | }; | 126 | }; |
119 | 127 | ||
120 | int ceph_auth_none_init(struct ceph_auth_client *ac) | 128 | int ceph_auth_none_init(struct ceph_auth_client *ac) |
@@ -127,7 +135,6 @@ int ceph_auth_none_init(struct ceph_auth_client *ac) | |||
127 | return -ENOMEM; | 135 | return -ENOMEM; |
128 | 136 | ||
129 | xi->starting = true; | 137 | xi->starting = true; |
130 | xi->built_authorizer = false; | ||
131 | 138 | ||
132 | ac->protocol = CEPH_AUTH_NONE; | 139 | ac->protocol = CEPH_AUTH_NONE; |
133 | ac->private = xi; | 140 | ac->private = xi; |
diff --git a/net/ceph/auth_none.h b/net/ceph/auth_none.h index 059a3ce4b53f..62021535ae4a 100644 --- a/net/ceph/auth_none.h +++ b/net/ceph/auth_none.h | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | struct ceph_none_authorizer { | 14 | struct ceph_none_authorizer { |
15 | struct ceph_authorizer base; | ||
15 | char buf[128]; | 16 | char buf[128]; |
16 | int buf_len; | 17 | int buf_len; |
17 | char reply_buf[0]; | 18 | char reply_buf[0]; |
@@ -19,8 +20,6 @@ struct ceph_none_authorizer { | |||
19 | 20 | ||
20 | struct ceph_auth_none_info { | 21 | struct ceph_auth_none_info { |
21 | bool starting; | 22 | bool starting; |
22 | bool built_authorizer; | ||
23 | struct ceph_none_authorizer au; /* we only need one; it's static */ | ||
24 | }; | 23 | }; |
25 | 24 | ||
26 | int ceph_auth_none_init(struct ceph_auth_client *ac); | 25 | int ceph_auth_none_init(struct ceph_auth_client *ac); |
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 9e43a315e662..a0905f04bd13 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c | |||
@@ -565,6 +565,14 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, | |||
565 | return -EAGAIN; | 565 | return -EAGAIN; |
566 | } | 566 | } |
567 | 567 | ||
568 | static void ceph_x_destroy_authorizer(struct ceph_authorizer *a) | ||
569 | { | ||
570 | struct ceph_x_authorizer *au = (void *)a; | ||
571 | |||
572 | ceph_x_authorizer_cleanup(au); | ||
573 | kfree(au); | ||
574 | } | ||
575 | |||
568 | static int ceph_x_create_authorizer( | 576 | static int ceph_x_create_authorizer( |
569 | struct ceph_auth_client *ac, int peer_type, | 577 | struct ceph_auth_client *ac, int peer_type, |
570 | struct ceph_auth_handshake *auth) | 578 | struct ceph_auth_handshake *auth) |
@@ -581,6 +589,8 @@ static int ceph_x_create_authorizer( | |||
581 | if (!au) | 589 | if (!au) |
582 | return -ENOMEM; | 590 | return -ENOMEM; |
583 | 591 | ||
592 | au->base.destroy = ceph_x_destroy_authorizer; | ||
593 | |||
584 | ret = ceph_x_build_authorizer(ac, th, au); | 594 | ret = ceph_x_build_authorizer(ac, th, au); |
585 | if (ret) { | 595 | if (ret) { |
586 | kfree(au); | 596 | kfree(au); |
@@ -643,16 +653,6 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, | |||
643 | return ret; | 653 | return ret; |
644 | } | 654 | } |
645 | 655 | ||
646 | static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac, | ||
647 | struct ceph_authorizer *a) | ||
648 | { | ||
649 | struct ceph_x_authorizer *au = (void *)a; | ||
650 | |||
651 | ceph_x_authorizer_cleanup(au); | ||
652 | kfree(au); | ||
653 | } | ||
654 | |||
655 | |||
656 | static void ceph_x_reset(struct ceph_auth_client *ac) | 656 | static void ceph_x_reset(struct ceph_auth_client *ac) |
657 | { | 657 | { |
658 | struct ceph_x_info *xi = ac->private; | 658 | struct ceph_x_info *xi = ac->private; |
@@ -770,7 +770,6 @@ static const struct ceph_auth_client_ops ceph_x_ops = { | |||
770 | .create_authorizer = ceph_x_create_authorizer, | 770 | .create_authorizer = ceph_x_create_authorizer, |
771 | .update_authorizer = ceph_x_update_authorizer, | 771 | .update_authorizer = ceph_x_update_authorizer, |
772 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, | 772 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, |
773 | .destroy_authorizer = ceph_x_destroy_authorizer, | ||
774 | .invalidate_authorizer = ceph_x_invalidate_authorizer, | 773 | .invalidate_authorizer = ceph_x_invalidate_authorizer, |
775 | .reset = ceph_x_reset, | 774 | .reset = ceph_x_reset, |
776 | .destroy = ceph_x_destroy, | 775 | .destroy = ceph_x_destroy, |
diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h index 40b1a3cf7397..21a5af904bae 100644 --- a/net/ceph/auth_x.h +++ b/net/ceph/auth_x.h | |||
@@ -26,6 +26,7 @@ struct ceph_x_ticket_handler { | |||
26 | 26 | ||
27 | 27 | ||
28 | struct ceph_x_authorizer { | 28 | struct ceph_x_authorizer { |
29 | struct ceph_authorizer base; | ||
29 | struct ceph_crypto_key session_key; | 30 | struct ceph_crypto_key session_key; |
30 | struct ceph_buffer *buf; | 31 | struct ceph_buffer *buf; |
31 | unsigned int service; | 32 | unsigned int service; |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 1831f6353622..a5502898ea33 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -269,7 +269,7 @@ static void _ceph_msgr_exit(void) | |||
269 | } | 269 | } |
270 | 270 | ||
271 | BUG_ON(zero_page == NULL); | 271 | BUG_ON(zero_page == NULL); |
272 | page_cache_release(zero_page); | 272 | put_page(zero_page); |
273 | zero_page = NULL; | 273 | zero_page = NULL; |
274 | 274 | ||
275 | ceph_msgr_slab_exit(); | 275 | ceph_msgr_slab_exit(); |
@@ -282,7 +282,7 @@ int ceph_msgr_init(void) | |||
282 | 282 | ||
283 | BUG_ON(zero_page != NULL); | 283 | BUG_ON(zero_page != NULL); |
284 | zero_page = ZERO_PAGE(0); | 284 | zero_page = ZERO_PAGE(0); |
285 | page_cache_get(zero_page); | 285 | get_page(zero_page); |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * The number of active work items is limited by the number of | 288 | * The number of active work items is limited by the number of |
@@ -1602,7 +1602,7 @@ static int write_partial_skip(struct ceph_connection *con) | |||
1602 | 1602 | ||
1603 | dout("%s %p %d left\n", __func__, con, con->out_skip); | 1603 | dout("%s %p %d left\n", __func__, con, con->out_skip); |
1604 | while (con->out_skip > 0) { | 1604 | while (con->out_skip > 0) { |
1605 | size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE); | 1605 | size_t size = min(con->out_skip, (int) PAGE_SIZE); |
1606 | 1606 | ||
1607 | ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, true); | 1607 | ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, true); |
1608 | if (ret <= 0) | 1608 | if (ret <= 0) |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 32355d9d0103..40a53a70efdf 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1087,10 +1087,8 @@ static void put_osd(struct ceph_osd *osd) | |||
1087 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), | 1087 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), |
1088 | atomic_read(&osd->o_ref) - 1); | 1088 | atomic_read(&osd->o_ref) - 1); |
1089 | if (atomic_dec_and_test(&osd->o_ref)) { | 1089 | if (atomic_dec_and_test(&osd->o_ref)) { |
1090 | struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; | ||
1091 | |||
1092 | if (osd->o_auth.authorizer) | 1090 | if (osd->o_auth.authorizer) |
1093 | ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); | 1091 | ceph_auth_destroy_authorizer(osd->o_auth.authorizer); |
1094 | kfree(osd); | 1092 | kfree(osd); |
1095 | } | 1093 | } |
1096 | } | 1094 | } |
@@ -2984,7 +2982,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, | |||
2984 | struct ceph_auth_handshake *auth = &o->o_auth; | 2982 | struct ceph_auth_handshake *auth = &o->o_auth; |
2985 | 2983 | ||
2986 | if (force_new && auth->authorizer) { | 2984 | if (force_new && auth->authorizer) { |
2987 | ceph_auth_destroy_authorizer(ac, auth->authorizer); | 2985 | ceph_auth_destroy_authorizer(auth->authorizer); |
2988 | auth->authorizer = NULL; | 2986 | auth->authorizer = NULL; |
2989 | } | 2987 | } |
2990 | if (!auth->authorizer) { | 2988 | if (!auth->authorizer) { |
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c index c7c220a736e5..6864007e64fc 100644 --- a/net/ceph/pagelist.c +++ b/net/ceph/pagelist.c | |||
@@ -56,7 +56,7 @@ int ceph_pagelist_append(struct ceph_pagelist *pl, const void *buf, size_t len) | |||
56 | size_t bit = pl->room; | 56 | size_t bit = pl->room; |
57 | int ret; | 57 | int ret; |
58 | 58 | ||
59 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), | 59 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_MASK), |
60 | buf, bit); | 60 | buf, bit); |
61 | pl->length += bit; | 61 | pl->length += bit; |
62 | pl->room -= bit; | 62 | pl->room -= bit; |
@@ -67,7 +67,7 @@ int ceph_pagelist_append(struct ceph_pagelist *pl, const void *buf, size_t len) | |||
67 | return ret; | 67 | return ret; |
68 | } | 68 | } |
69 | 69 | ||
70 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len); | 70 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_MASK), buf, len); |
71 | pl->length += len; | 71 | pl->length += len; |
72 | pl->room -= len; | 72 | pl->room -= len; |
73 | return 0; | 73 | return 0; |
diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index 10297f7a89ba..00d2601407c5 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c | |||
@@ -95,19 +95,19 @@ int ceph_copy_user_to_page_vector(struct page **pages, | |||
95 | loff_t off, size_t len) | 95 | loff_t off, size_t len) |
96 | { | 96 | { |
97 | int i = 0; | 97 | int i = 0; |
98 | int po = off & ~PAGE_CACHE_MASK; | 98 | int po = off & ~PAGE_MASK; |
99 | int left = len; | 99 | int left = len; |
100 | int l, bad; | 100 | int l, bad; |
101 | 101 | ||
102 | while (left > 0) { | 102 | while (left > 0) { |
103 | l = min_t(int, PAGE_CACHE_SIZE-po, left); | 103 | l = min_t(int, PAGE_SIZE-po, left); |
104 | bad = copy_from_user(page_address(pages[i]) + po, data, l); | 104 | bad = copy_from_user(page_address(pages[i]) + po, data, l); |
105 | if (bad == l) | 105 | if (bad == l) |
106 | return -EFAULT; | 106 | return -EFAULT; |
107 | data += l - bad; | 107 | data += l - bad; |
108 | left -= l - bad; | 108 | left -= l - bad; |
109 | po += l - bad; | 109 | po += l - bad; |
110 | if (po == PAGE_CACHE_SIZE) { | 110 | if (po == PAGE_SIZE) { |
111 | po = 0; | 111 | po = 0; |
112 | i++; | 112 | i++; |
113 | } | 113 | } |
@@ -121,17 +121,17 @@ void ceph_copy_to_page_vector(struct page **pages, | |||
121 | loff_t off, size_t len) | 121 | loff_t off, size_t len) |
122 | { | 122 | { |
123 | int i = 0; | 123 | int i = 0; |
124 | size_t po = off & ~PAGE_CACHE_MASK; | 124 | size_t po = off & ~PAGE_MASK; |
125 | size_t left = len; | 125 | size_t left = len; |
126 | 126 | ||
127 | while (left > 0) { | 127 | while (left > 0) { |
128 | size_t l = min_t(size_t, PAGE_CACHE_SIZE-po, left); | 128 | size_t l = min_t(size_t, PAGE_SIZE-po, left); |
129 | 129 | ||
130 | memcpy(page_address(pages[i]) + po, data, l); | 130 | memcpy(page_address(pages[i]) + po, data, l); |
131 | data += l; | 131 | data += l; |
132 | left -= l; | 132 | left -= l; |
133 | po += l; | 133 | po += l; |
134 | if (po == PAGE_CACHE_SIZE) { | 134 | if (po == PAGE_SIZE) { |
135 | po = 0; | 135 | po = 0; |
136 | i++; | 136 | i++; |
137 | } | 137 | } |
@@ -144,17 +144,17 @@ void ceph_copy_from_page_vector(struct page **pages, | |||
144 | loff_t off, size_t len) | 144 | loff_t off, size_t len) |
145 | { | 145 | { |
146 | int i = 0; | 146 | int i = 0; |
147 | size_t po = off & ~PAGE_CACHE_MASK; | 147 | size_t po = off & ~PAGE_MASK; |
148 | size_t left = len; | 148 | size_t left = len; |
149 | 149 | ||
150 | while (left > 0) { | 150 | while (left > 0) { |
151 | size_t l = min_t(size_t, PAGE_CACHE_SIZE-po, left); | 151 | size_t l = min_t(size_t, PAGE_SIZE-po, left); |
152 | 152 | ||
153 | memcpy(data, page_address(pages[i]) + po, l); | 153 | memcpy(data, page_address(pages[i]) + po, l); |
154 | data += l; | 154 | data += l; |
155 | left -= l; | 155 | left -= l; |
156 | po += l; | 156 | po += l; |
157 | if (po == PAGE_CACHE_SIZE) { | 157 | if (po == PAGE_SIZE) { |
158 | po = 0; | 158 | po = 0; |
159 | i++; | 159 | i++; |
160 | } | 160 | } |
@@ -168,25 +168,25 @@ EXPORT_SYMBOL(ceph_copy_from_page_vector); | |||
168 | */ | 168 | */ |
169 | void ceph_zero_page_vector_range(int off, int len, struct page **pages) | 169 | void ceph_zero_page_vector_range(int off, int len, struct page **pages) |
170 | { | 170 | { |
171 | int i = off >> PAGE_CACHE_SHIFT; | 171 | int i = off >> PAGE_SHIFT; |
172 | 172 | ||
173 | off &= ~PAGE_CACHE_MASK; | 173 | off &= ~PAGE_MASK; |
174 | 174 | ||
175 | dout("zero_page_vector_page %u~%u\n", off, len); | 175 | dout("zero_page_vector_page %u~%u\n", off, len); |
176 | 176 | ||
177 | /* leading partial page? */ | 177 | /* leading partial page? */ |
178 | if (off) { | 178 | if (off) { |
179 | int end = min((int)PAGE_CACHE_SIZE, off + len); | 179 | int end = min((int)PAGE_SIZE, off + len); |
180 | dout("zeroing %d %p head from %d\n", i, pages[i], | 180 | dout("zeroing %d %p head from %d\n", i, pages[i], |
181 | (int)off); | 181 | (int)off); |
182 | zero_user_segment(pages[i], off, end); | 182 | zero_user_segment(pages[i], off, end); |
183 | len -= (end - off); | 183 | len -= (end - off); |
184 | i++; | 184 | i++; |
185 | } | 185 | } |
186 | while (len >= PAGE_CACHE_SIZE) { | 186 | while (len >= PAGE_SIZE) { |
187 | dout("zeroing %d %p len=%d\n", i, pages[i], len); | 187 | dout("zeroing %d %p len=%d\n", i, pages[i], len); |
188 | zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); | 188 | zero_user_segment(pages[i], 0, PAGE_SIZE); |
189 | len -= PAGE_CACHE_SIZE; | 189 | len -= PAGE_SIZE; |
190 | i++; | 190 | i++; |
191 | } | 191 | } |
192 | /* trailing partial page? */ | 192 | /* trailing partial page? */ |
diff --git a/net/core/dev.c b/net/core/dev.c index b9bcbe77d913..5c925ac50b95 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2802,7 +2802,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, | |||
2802 | 2802 | ||
2803 | if (skb->ip_summed != CHECKSUM_NONE && | 2803 | if (skb->ip_summed != CHECKSUM_NONE && |
2804 | !can_checksum_protocol(features, type)) { | 2804 | !can_checksum_protocol(features, type)) { |
2805 | features &= ~NETIF_F_CSUM_MASK; | 2805 | features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); |
2806 | } else if (illegal_highdma(skb->dev, skb)) { | 2806 | } else if (illegal_highdma(skb->dev, skb)) { |
2807 | features &= ~NETIF_F_SG; | 2807 | features &= ~NETIF_F_SG; |
2808 | } | 2808 | } |
@@ -4439,6 +4439,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
4439 | NAPI_GRO_CB(skb)->flush = 0; | 4439 | NAPI_GRO_CB(skb)->flush = 0; |
4440 | NAPI_GRO_CB(skb)->free = 0; | 4440 | NAPI_GRO_CB(skb)->free = 0; |
4441 | NAPI_GRO_CB(skb)->encap_mark = 0; | 4441 | NAPI_GRO_CB(skb)->encap_mark = 0; |
4442 | NAPI_GRO_CB(skb)->is_fou = 0; | ||
4442 | NAPI_GRO_CB(skb)->gro_remcsum_start = 0; | 4443 | NAPI_GRO_CB(skb)->gro_remcsum_start = 0; |
4443 | 4444 | ||
4444 | /* Setup for GRO checksum validation */ | 4445 | /* Setup for GRO checksum validation */ |
diff --git a/net/core/filter.c b/net/core/filter.c index b7177d01ecb0..ca7f832b2980 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1149,7 +1149,8 @@ void bpf_prog_destroy(struct bpf_prog *fp) | |||
1149 | } | 1149 | } |
1150 | EXPORT_SYMBOL_GPL(bpf_prog_destroy); | 1150 | EXPORT_SYMBOL_GPL(bpf_prog_destroy); |
1151 | 1151 | ||
1152 | static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk) | 1152 | static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk, |
1153 | bool locked) | ||
1153 | { | 1154 | { |
1154 | struct sk_filter *fp, *old_fp; | 1155 | struct sk_filter *fp, *old_fp; |
1155 | 1156 | ||
@@ -1165,10 +1166,8 @@ static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk) | |||
1165 | return -ENOMEM; | 1166 | return -ENOMEM; |
1166 | } | 1167 | } |
1167 | 1168 | ||
1168 | old_fp = rcu_dereference_protected(sk->sk_filter, | 1169 | old_fp = rcu_dereference_protected(sk->sk_filter, locked); |
1169 | sock_owned_by_user(sk)); | ||
1170 | rcu_assign_pointer(sk->sk_filter, fp); | 1170 | rcu_assign_pointer(sk->sk_filter, fp); |
1171 | |||
1172 | if (old_fp) | 1171 | if (old_fp) |
1173 | sk_filter_uncharge(sk, old_fp); | 1172 | sk_filter_uncharge(sk, old_fp); |
1174 | 1173 | ||
@@ -1247,7 +1246,8 @@ struct bpf_prog *__get_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1247 | * occurs or there is insufficient memory for the filter a negative | 1246 | * occurs or there is insufficient memory for the filter a negative |
1248 | * errno code is returned. On success the return is zero. | 1247 | * errno code is returned. On success the return is zero. |
1249 | */ | 1248 | */ |
1250 | int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | 1249 | int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk, |
1250 | bool locked) | ||
1251 | { | 1251 | { |
1252 | struct bpf_prog *prog = __get_filter(fprog, sk); | 1252 | struct bpf_prog *prog = __get_filter(fprog, sk); |
1253 | int err; | 1253 | int err; |
@@ -1255,7 +1255,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1255 | if (IS_ERR(prog)) | 1255 | if (IS_ERR(prog)) |
1256 | return PTR_ERR(prog); | 1256 | return PTR_ERR(prog); |
1257 | 1257 | ||
1258 | err = __sk_attach_prog(prog, sk); | 1258 | err = __sk_attach_prog(prog, sk, locked); |
1259 | if (err < 0) { | 1259 | if (err < 0) { |
1260 | __bpf_prog_release(prog); | 1260 | __bpf_prog_release(prog); |
1261 | return err; | 1261 | return err; |
@@ -1263,7 +1263,12 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1263 | 1263 | ||
1264 | return 0; | 1264 | return 0; |
1265 | } | 1265 | } |
1266 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 1266 | EXPORT_SYMBOL_GPL(__sk_attach_filter); |
1267 | |||
1268 | int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | ||
1269 | { | ||
1270 | return __sk_attach_filter(fprog, sk, sock_owned_by_user(sk)); | ||
1271 | } | ||
1267 | 1272 | ||
1268 | int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk) | 1273 | int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk) |
1269 | { | 1274 | { |
@@ -1309,7 +1314,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk) | |||
1309 | if (IS_ERR(prog)) | 1314 | if (IS_ERR(prog)) |
1310 | return PTR_ERR(prog); | 1315 | return PTR_ERR(prog); |
1311 | 1316 | ||
1312 | err = __sk_attach_prog(prog, sk); | 1317 | err = __sk_attach_prog(prog, sk, sock_owned_by_user(sk)); |
1313 | if (err < 0) { | 1318 | if (err < 0) { |
1314 | bpf_prog_put(prog); | 1319 | bpf_prog_put(prog); |
1315 | return err; | 1320 | return err; |
@@ -1764,6 +1769,7 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1764 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { | 1769 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { |
1765 | switch (size) { | 1770 | switch (size) { |
1766 | case offsetof(struct bpf_tunnel_key, tunnel_label): | 1771 | case offsetof(struct bpf_tunnel_key, tunnel_label): |
1772 | case offsetof(struct bpf_tunnel_key, tunnel_ext): | ||
1767 | goto set_compat; | 1773 | goto set_compat; |
1768 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): | 1774 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): |
1769 | /* Fixup deprecated structure layouts here, so we have | 1775 | /* Fixup deprecated structure layouts here, so we have |
@@ -1849,6 +1855,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1849 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { | 1855 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { |
1850 | switch (size) { | 1856 | switch (size) { |
1851 | case offsetof(struct bpf_tunnel_key, tunnel_label): | 1857 | case offsetof(struct bpf_tunnel_key, tunnel_label): |
1858 | case offsetof(struct bpf_tunnel_key, tunnel_ext): | ||
1852 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): | 1859 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): |
1853 | /* Fixup deprecated structure layouts here, so we have | 1860 | /* Fixup deprecated structure layouts here, so we have |
1854 | * a common path later on. | 1861 | * a common path later on. |
@@ -1861,7 +1868,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1861 | return -EINVAL; | 1868 | return -EINVAL; |
1862 | } | 1869 | } |
1863 | } | 1870 | } |
1864 | if (unlikely(!(flags & BPF_F_TUNINFO_IPV6) && from->tunnel_label)) | 1871 | if (unlikely((!(flags & BPF_F_TUNINFO_IPV6) && from->tunnel_label) || |
1872 | from->tunnel_ext)) | ||
1865 | return -EINVAL; | 1873 | return -EINVAL; |
1866 | 1874 | ||
1867 | skb_dst_drop(skb); | 1875 | skb_dst_drop(skb); |
@@ -2247,7 +2255,7 @@ static int __init register_sk_filter_ops(void) | |||
2247 | } | 2255 | } |
2248 | late_initcall(register_sk_filter_ops); | 2256 | late_initcall(register_sk_filter_ops); |
2249 | 2257 | ||
2250 | int sk_detach_filter(struct sock *sk) | 2258 | int __sk_detach_filter(struct sock *sk, bool locked) |
2251 | { | 2259 | { |
2252 | int ret = -ENOENT; | 2260 | int ret = -ENOENT; |
2253 | struct sk_filter *filter; | 2261 | struct sk_filter *filter; |
@@ -2255,8 +2263,7 @@ int sk_detach_filter(struct sock *sk) | |||
2255 | if (sock_flag(sk, SOCK_FILTER_LOCKED)) | 2263 | if (sock_flag(sk, SOCK_FILTER_LOCKED)) |
2256 | return -EPERM; | 2264 | return -EPERM; |
2257 | 2265 | ||
2258 | filter = rcu_dereference_protected(sk->sk_filter, | 2266 | filter = rcu_dereference_protected(sk->sk_filter, locked); |
2259 | sock_owned_by_user(sk)); | ||
2260 | if (filter) { | 2267 | if (filter) { |
2261 | RCU_INIT_POINTER(sk->sk_filter, NULL); | 2268 | RCU_INIT_POINTER(sk->sk_filter, NULL); |
2262 | sk_filter_uncharge(sk, filter); | 2269 | sk_filter_uncharge(sk, filter); |
@@ -2265,7 +2272,12 @@ int sk_detach_filter(struct sock *sk) | |||
2265 | 2272 | ||
2266 | return ret; | 2273 | return ret; |
2267 | } | 2274 | } |
2268 | EXPORT_SYMBOL_GPL(sk_detach_filter); | 2275 | EXPORT_SYMBOL_GPL(__sk_detach_filter); |
2276 | |||
2277 | int sk_detach_filter(struct sock *sk) | ||
2278 | { | ||
2279 | return __sk_detach_filter(sk, sock_owned_by_user(sk)); | ||
2280 | } | ||
2269 | 2281 | ||
2270 | int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, | 2282 | int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, |
2271 | unsigned int len) | 2283 | unsigned int len) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f2066772d0f3..a75f7e94b445 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -909,6 +909,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, | |||
909 | + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */ | 909 | + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */ |
910 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ | 910 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ |
911 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ | 911 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ |
912 | + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ | ||
912 | + nla_total_size(1); /* IFLA_PROTO_DOWN */ | 913 | + nla_total_size(1); /* IFLA_PROTO_DOWN */ |
913 | 914 | ||
914 | } | 915 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d04c2d1c8c87..e561f9f07d6d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -4502,13 +4502,16 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) | |||
4502 | __skb_push(skb, offset); | 4502 | __skb_push(skb, offset); |
4503 | err = __vlan_insert_tag(skb, skb->vlan_proto, | 4503 | err = __vlan_insert_tag(skb, skb->vlan_proto, |
4504 | skb_vlan_tag_get(skb)); | 4504 | skb_vlan_tag_get(skb)); |
4505 | if (err) | 4505 | if (err) { |
4506 | __skb_pull(skb, offset); | ||
4506 | return err; | 4507 | return err; |
4508 | } | ||
4509 | |||
4507 | skb->protocol = skb->vlan_proto; | 4510 | skb->protocol = skb->vlan_proto; |
4508 | skb->mac_len += VLAN_HLEN; | 4511 | skb->mac_len += VLAN_HLEN; |
4509 | __skb_pull(skb, offset); | ||
4510 | 4512 | ||
4511 | skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); | 4513 | skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); |
4514 | __skb_pull(skb, offset); | ||
4512 | } | 4515 | } |
4513 | __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); | 4516 | __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); |
4514 | return 0; | 4517 | return 0; |
diff --git a/net/core/sock.c b/net/core/sock.c index b67b9aedb230..7e73c26b6bb4 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -221,7 +221,8 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
221 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 221 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
222 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 222 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
223 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | 223 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
224 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" | 224 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" , |
225 | "sk_lock-AF_MAX" | ||
225 | }; | 226 | }; |
226 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 227 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
227 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 228 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
@@ -237,7 +238,8 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
237 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 238 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
238 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 239 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
239 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | 240 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
240 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" | 241 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" , |
242 | "slock-AF_MAX" | ||
241 | }; | 243 | }; |
242 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 244 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
243 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 245 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
@@ -253,7 +255,8 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
253 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 255 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
254 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 256 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
255 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | 257 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
256 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" | 258 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" , |
259 | "clock-AF_MAX" | ||
257 | }; | 260 | }; |
258 | 261 | ||
259 | /* | 262 | /* |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 607a14f20d88..b1dc096d22f8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -1034,10 +1034,13 @@ source_ok: | |||
1034 | if (!fld.daddr) { | 1034 | if (!fld.daddr) { |
1035 | fld.daddr = fld.saddr; | 1035 | fld.daddr = fld.saddr; |
1036 | 1036 | ||
1037 | err = -EADDRNOTAVAIL; | ||
1038 | if (dev_out) | 1037 | if (dev_out) |
1039 | dev_put(dev_out); | 1038 | dev_put(dev_out); |
1039 | err = -EINVAL; | ||
1040 | dev_out = init_net.loopback_dev; | 1040 | dev_out = init_net.loopback_dev; |
1041 | if (!dev_out->dn_ptr) | ||
1042 | goto out; | ||
1043 | err = -EADDRNOTAVAIL; | ||
1041 | dev_hold(dev_out); | 1044 | dev_hold(dev_out); |
1042 | if (!fld.daddr) { | 1045 | if (!fld.daddr) { |
1043 | fld.daddr = | 1046 | fld.daddr = |
@@ -1110,6 +1113,8 @@ source_ok: | |||
1110 | if (dev_out == NULL) | 1113 | if (dev_out == NULL) |
1111 | goto out; | 1114 | goto out; |
1112 | dn_db = rcu_dereference_raw(dev_out->dn_ptr); | 1115 | dn_db = rcu_dereference_raw(dev_out->dn_ptr); |
1116 | if (!dn_db) | ||
1117 | goto e_inval; | ||
1113 | /* Possible improvement - check all devices for local addr */ | 1118 | /* Possible improvement - check all devices for local addr */ |
1114 | if (dn_dev_islocal(dev_out, fld.daddr)) { | 1119 | if (dn_dev_islocal(dev_out, fld.daddr)) { |
1115 | dev_put(dev_out); | 1120 | dev_put(dev_out); |
@@ -1151,6 +1156,8 @@ select_source: | |||
1151 | dev_put(dev_out); | 1156 | dev_put(dev_out); |
1152 | dev_out = init_net.loopback_dev; | 1157 | dev_out = init_net.loopback_dev; |
1153 | dev_hold(dev_out); | 1158 | dev_hold(dev_out); |
1159 | if (!dev_out->dn_ptr) | ||
1160 | goto e_inval; | ||
1154 | fld.flowidn_oif = dev_out->ifindex; | 1161 | fld.flowidn_oif = dev_out->ifindex; |
1155 | if (res.fi) | 1162 | if (res.fi) |
1156 | dn_fib_info_put(res.fi); | 1163 | dn_fib_info_put(res.fi); |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 8a9246deccfe..63566ec54794 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -904,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) | |||
904 | if (ifa->ifa_flags & IFA_F_SECONDARY) { | 904 | if (ifa->ifa_flags & IFA_F_SECONDARY) { |
905 | prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); | 905 | prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); |
906 | if (!prim) { | 906 | if (!prim) { |
907 | pr_warn("%s: bug: prim == NULL\n", __func__); | 907 | /* if the device has been deleted, we don't perform |
908 | * address promotion | ||
909 | */ | ||
910 | if (!in_dev->dead) | ||
911 | pr_warn("%s: bug: prim == NULL\n", __func__); | ||
908 | return; | 912 | return; |
909 | } | 913 | } |
910 | if (iprim && iprim != prim) { | 914 | if (iprim && iprim != prim) { |
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index a0586b4a197d..a39068b4a4d9 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c | |||
@@ -195,6 +195,17 @@ static struct sk_buff **fou_gro_receive(struct sk_buff **head, | |||
195 | u8 proto = NAPI_GRO_CB(skb)->proto; | 195 | u8 proto = NAPI_GRO_CB(skb)->proto; |
196 | const struct net_offload **offloads; | 196 | const struct net_offload **offloads; |
197 | 197 | ||
198 | /* We can clear the encap_mark for FOU as we are essentially doing | ||
199 | * one of two possible things. We are either adding an L4 tunnel | ||
200 | * header to the outer L3 tunnel header, or we are are simply | ||
201 | * treating the GRE tunnel header as though it is a UDP protocol | ||
202 | * specific header such as VXLAN or GENEVE. | ||
203 | */ | ||
204 | NAPI_GRO_CB(skb)->encap_mark = 0; | ||
205 | |||
206 | /* Flag this frame as already having an outer encap header */ | ||
207 | NAPI_GRO_CB(skb)->is_fou = 1; | ||
208 | |||
198 | rcu_read_lock(); | 209 | rcu_read_lock(); |
199 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | 210 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; |
200 | ops = rcu_dereference(offloads[proto]); | 211 | ops = rcu_dereference(offloads[proto]); |
@@ -352,6 +363,17 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head, | |||
352 | } | 363 | } |
353 | } | 364 | } |
354 | 365 | ||
366 | /* We can clear the encap_mark for GUE as we are essentially doing | ||
367 | * one of two possible things. We are either adding an L4 tunnel | ||
368 | * header to the outer L3 tunnel header, or we are are simply | ||
369 | * treating the GRE tunnel header as though it is a UDP protocol | ||
370 | * specific header such as VXLAN or GENEVE. | ||
371 | */ | ||
372 | NAPI_GRO_CB(skb)->encap_mark = 0; | ||
373 | |||
374 | /* Flag this frame as already having an outer encap header */ | ||
375 | NAPI_GRO_CB(skb)->is_fou = 1; | ||
376 | |||
355 | rcu_read_lock(); | 377 | rcu_read_lock(); |
356 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | 378 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; |
357 | ops = rcu_dereference(offloads[guehdr->proto_ctype]); | 379 | ops = rcu_dereference(offloads[guehdr->proto_ctype]); |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index c47539d04b88..6a5bd4317866 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
@@ -150,6 +150,14 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head, | |||
150 | if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0) | 150 | if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0) |
151 | goto out; | 151 | goto out; |
152 | 152 | ||
153 | /* We can only support GRE_CSUM if we can track the location of | ||
154 | * the GRE header. In the case of FOU/GUE we cannot because the | ||
155 | * outer UDP header displaces the GRE header leaving us in a state | ||
156 | * of limbo. | ||
157 | */ | ||
158 | if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou) | ||
159 | goto out; | ||
160 | |||
153 | type = greh->protocol; | 161 | type = greh->protocol; |
154 | 162 | ||
155 | rcu_read_lock(); | 163 | rcu_read_lock(); |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index bc68eced0105..0d9e9d7bb029 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -470,6 +470,7 @@ static int inet_reuseport_add_sock(struct sock *sk, | |||
470 | const struct sock *sk2, | 470 | const struct sock *sk2, |
471 | bool match_wildcard)) | 471 | bool match_wildcard)) |
472 | { | 472 | { |
473 | struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; | ||
473 | struct sock *sk2; | 474 | struct sock *sk2; |
474 | struct hlist_nulls_node *node; | 475 | struct hlist_nulls_node *node; |
475 | kuid_t uid = sock_i_uid(sk); | 476 | kuid_t uid = sock_i_uid(sk); |
@@ -479,6 +480,7 @@ static int inet_reuseport_add_sock(struct sock *sk, | |||
479 | sk2->sk_family == sk->sk_family && | 480 | sk2->sk_family == sk->sk_family && |
480 | ipv6_only_sock(sk2) == ipv6_only_sock(sk) && | 481 | ipv6_only_sock(sk2) == ipv6_only_sock(sk) && |
481 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if && | 482 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if && |
483 | inet_csk(sk2)->icsk_bind_hash == tb && | ||
482 | sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) && | 484 | sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) && |
483 | saddr_same(sk, sk2, false)) | 485 | saddr_same(sk, sk2, false)) |
484 | return reuseport_add_sock(sk, sk2); | 486 | return reuseport_add_sock(sk, sk2); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 31936d387cfd..205a2b8a5a84 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -179,6 +179,7 @@ static __be16 tnl_flags_to_gre_flags(__be16 tflags) | |||
179 | return flags; | 179 | return flags; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* Fills in tpi and returns header length to be pulled. */ | ||
182 | static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, | 183 | static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, |
183 | bool *csum_err) | 184 | bool *csum_err) |
184 | { | 185 | { |
@@ -238,7 +239,7 @@ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
238 | return -EINVAL; | 239 | return -EINVAL; |
239 | } | 240 | } |
240 | } | 241 | } |
241 | return iptunnel_pull_header(skb, hdr_len, tpi->proto, false); | 242 | return hdr_len; |
242 | } | 243 | } |
243 | 244 | ||
244 | static void ipgre_err(struct sk_buff *skb, u32 info, | 245 | static void ipgre_err(struct sk_buff *skb, u32 info, |
@@ -341,7 +342,7 @@ static void gre_err(struct sk_buff *skb, u32 info) | |||
341 | struct tnl_ptk_info tpi; | 342 | struct tnl_ptk_info tpi; |
342 | bool csum_err = false; | 343 | bool csum_err = false; |
343 | 344 | ||
344 | if (parse_gre_header(skb, &tpi, &csum_err)) { | 345 | if (parse_gre_header(skb, &tpi, &csum_err) < 0) { |
345 | if (!csum_err) /* ignore csum errors. */ | 346 | if (!csum_err) /* ignore csum errors. */ |
346 | return; | 347 | return; |
347 | } | 348 | } |
@@ -419,6 +420,7 @@ static int gre_rcv(struct sk_buff *skb) | |||
419 | { | 420 | { |
420 | struct tnl_ptk_info tpi; | 421 | struct tnl_ptk_info tpi; |
421 | bool csum_err = false; | 422 | bool csum_err = false; |
423 | int hdr_len; | ||
422 | 424 | ||
423 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 425 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
424 | if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { | 426 | if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { |
@@ -428,7 +430,10 @@ static int gre_rcv(struct sk_buff *skb) | |||
428 | } | 430 | } |
429 | #endif | 431 | #endif |
430 | 432 | ||
431 | if (parse_gre_header(skb, &tpi, &csum_err) < 0) | 433 | hdr_len = parse_gre_header(skb, &tpi, &csum_err); |
434 | if (hdr_len < 0) | ||
435 | goto drop; | ||
436 | if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false) < 0) | ||
432 | goto drop; | 437 | goto drop; |
433 | 438 | ||
434 | if (ipgre_rcv(skb, &tpi) == PACKET_RCVD) | 439 | if (ipgre_rcv(skb, &tpi) == PACKET_RCVD) |
@@ -523,7 +528,8 @@ static struct rtable *gre_get_rt(struct sk_buff *skb, | |||
523 | return ip_route_output_key(net, fl); | 528 | return ip_route_output_key(net, fl); |
524 | } | 529 | } |
525 | 530 | ||
526 | static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) | 531 | static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, |
532 | __be16 proto) | ||
527 | { | 533 | { |
528 | struct ip_tunnel_info *tun_info; | 534 | struct ip_tunnel_info *tun_info; |
529 | const struct ip_tunnel_key *key; | 535 | const struct ip_tunnel_key *key; |
@@ -575,7 +581,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) | |||
575 | } | 581 | } |
576 | 582 | ||
577 | flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); | 583 | flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); |
578 | build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB), | 584 | build_header(skb, tunnel_hlen, flags, proto, |
579 | tunnel_id_to_key(tun_info->key.tun_id), 0); | 585 | tunnel_id_to_key(tun_info->key.tun_id), 0); |
580 | 586 | ||
581 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; | 587 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; |
@@ -616,7 +622,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, | |||
616 | const struct iphdr *tnl_params; | 622 | const struct iphdr *tnl_params; |
617 | 623 | ||
618 | if (tunnel->collect_md) { | 624 | if (tunnel->collect_md) { |
619 | gre_fb_xmit(skb, dev); | 625 | gre_fb_xmit(skb, dev, skb->protocol); |
620 | return NETDEV_TX_OK; | 626 | return NETDEV_TX_OK; |
621 | } | 627 | } |
622 | 628 | ||
@@ -660,7 +666,7 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, | |||
660 | struct ip_tunnel *tunnel = netdev_priv(dev); | 666 | struct ip_tunnel *tunnel = netdev_priv(dev); |
661 | 667 | ||
662 | if (tunnel->collect_md) { | 668 | if (tunnel->collect_md) { |
663 | gre_fb_xmit(skb, dev); | 669 | gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); |
664 | return NETDEV_TX_OK; | 670 | return NETDEV_TX_OK; |
665 | } | 671 | } |
666 | 672 | ||
@@ -862,9 +868,16 @@ static void __gre_tunnel_init(struct net_device *dev) | |||
862 | dev->hw_features |= GRE_FEATURES; | 868 | dev->hw_features |= GRE_FEATURES; |
863 | 869 | ||
864 | if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) { | 870 | if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) { |
865 | /* TCP offload with GRE SEQ is not supported. */ | 871 | /* TCP offload with GRE SEQ is not supported, nor |
866 | dev->features |= NETIF_F_GSO_SOFTWARE; | 872 | * can we support 2 levels of outer headers requiring |
867 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | 873 | * an update. |
874 | */ | ||
875 | if (!(tunnel->parms.o_flags & TUNNEL_CSUM) || | ||
876 | (tunnel->encap.type == TUNNEL_ENCAP_NONE)) { | ||
877 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
878 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
879 | } | ||
880 | |||
868 | /* Can use a lockless transmit, unless we generate | 881 | /* Can use a lockless transmit, unless we generate |
869 | * output sequences | 882 | * output sequences |
870 | */ | 883 | */ |
@@ -886,7 +899,7 @@ static int ipgre_tunnel_init(struct net_device *dev) | |||
886 | netif_keep_dst(dev); | 899 | netif_keep_dst(dev); |
887 | dev->addr_len = 4; | 900 | dev->addr_len = 4; |
888 | 901 | ||
889 | if (iph->daddr) { | 902 | if (iph->daddr && !tunnel->collect_md) { |
890 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 903 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
891 | if (ipv4_is_multicast(iph->daddr)) { | 904 | if (ipv4_is_multicast(iph->daddr)) { |
892 | if (!iph->saddr) | 905 | if (!iph->saddr) |
@@ -895,8 +908,9 @@ static int ipgre_tunnel_init(struct net_device *dev) | |||
895 | dev->header_ops = &ipgre_header_ops; | 908 | dev->header_ops = &ipgre_header_ops; |
896 | } | 909 | } |
897 | #endif | 910 | #endif |
898 | } else | 911 | } else if (!tunnel->collect_md) { |
899 | dev->header_ops = &ipgre_header_ops; | 912 | dev->header_ops = &ipgre_header_ops; |
913 | } | ||
900 | 914 | ||
901 | return ip_tunnel_init(dev); | 915 | return ip_tunnel_init(dev); |
902 | } | 916 | } |
@@ -939,6 +953,11 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
939 | if (flags & (GRE_VERSION|GRE_ROUTING)) | 953 | if (flags & (GRE_VERSION|GRE_ROUTING)) |
940 | return -EINVAL; | 954 | return -EINVAL; |
941 | 955 | ||
956 | if (data[IFLA_GRE_COLLECT_METADATA] && | ||
957 | data[IFLA_GRE_ENCAP_TYPE] && | ||
958 | nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) | ||
959 | return -EINVAL; | ||
960 | |||
942 | return 0; | 961 | return 0; |
943 | } | 962 | } |
944 | 963 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 6aad0192443d..a69ed94bda1b 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -326,12 +326,12 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
326 | 326 | ||
327 | if (!IS_ERR(rt)) { | 327 | if (!IS_ERR(rt)) { |
328 | tdev = rt->dst.dev; | 328 | tdev = rt->dst.dev; |
329 | dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, | ||
330 | fl4.saddr); | ||
331 | ip_rt_put(rt); | 329 | ip_rt_put(rt); |
332 | } | 330 | } |
333 | if (dev->type != ARPHRD_ETHER) | 331 | if (dev->type != ARPHRD_ETHER) |
334 | dev->flags |= IFF_POINTOPOINT; | 332 | dev->flags |= IFF_POINTOPOINT; |
333 | |||
334 | dst_cache_reset(&tunnel->dst_cache); | ||
335 | } | 335 | } |
336 | 336 | ||
337 | if (!tdev && tunnel->parms.link) | 337 | if (!tdev && tunnel->parms.link) |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 02dd990af542..6165f30c4d72 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -372,8 +372,8 @@ static int ip6_tun_fill_encap_info(struct sk_buff *skb, | |||
372 | if (nla_put_be64(skb, LWTUNNEL_IP6_ID, tun_info->key.tun_id) || | 372 | if (nla_put_be64(skb, LWTUNNEL_IP6_ID, tun_info->key.tun_id) || |
373 | nla_put_in6_addr(skb, LWTUNNEL_IP6_DST, &tun_info->key.u.ipv6.dst) || | 373 | nla_put_in6_addr(skb, LWTUNNEL_IP6_DST, &tun_info->key.u.ipv6.dst) || |
374 | nla_put_in6_addr(skb, LWTUNNEL_IP6_SRC, &tun_info->key.u.ipv6.src) || | 374 | nla_put_in6_addr(skb, LWTUNNEL_IP6_SRC, &tun_info->key.u.ipv6.src) || |
375 | nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.tos) || | 375 | nla_put_u8(skb, LWTUNNEL_IP6_TC, tun_info->key.tos) || |
376 | nla_put_u8(skb, LWTUNNEL_IP6_TC, tun_info->key.ttl) || | 376 | nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.ttl) || |
377 | nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags)) | 377 | nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags)) |
378 | return -ENOMEM; | 378 | return -ENOMEM; |
379 | 379 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index bf081927e06b..4133b0f513af 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -359,11 +359,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
359 | } | 359 | } |
360 | 360 | ||
361 | /* All zeroes == unconditional rule. */ | 361 | /* All zeroes == unconditional rule. */ |
362 | static inline bool unconditional(const struct arpt_arp *arp) | 362 | static inline bool unconditional(const struct arpt_entry *e) |
363 | { | 363 | { |
364 | static const struct arpt_arp uncond; | 364 | static const struct arpt_arp uncond; |
365 | 365 | ||
366 | return memcmp(arp, &uncond, sizeof(uncond)) == 0; | 366 | return e->target_offset == sizeof(struct arpt_entry) && |
367 | memcmp(&e->arp, &uncond, sizeof(uncond)) == 0; | ||
367 | } | 368 | } |
368 | 369 | ||
369 | /* Figures out from what hook each rule can be called: returns 0 if | 370 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -402,11 +403,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, | |||
402 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); | 403 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); |
403 | 404 | ||
404 | /* Unconditional return/END. */ | 405 | /* Unconditional return/END. */ |
405 | if ((e->target_offset == sizeof(struct arpt_entry) && | 406 | if ((unconditional(e) && |
406 | (strcmp(t->target.u.user.name, | 407 | (strcmp(t->target.u.user.name, |
407 | XT_STANDARD_TARGET) == 0) && | 408 | XT_STANDARD_TARGET) == 0) && |
408 | t->verdict < 0 && unconditional(&e->arp)) || | 409 | t->verdict < 0) || visited) { |
409 | visited) { | ||
410 | unsigned int oldpos, size; | 410 | unsigned int oldpos, size; |
411 | 411 | ||
412 | if ((strcmp(t->target.u.user.name, | 412 | if ((strcmp(t->target.u.user.name, |
@@ -474,14 +474,12 @@ next: | |||
474 | return 1; | 474 | return 1; |
475 | } | 475 | } |
476 | 476 | ||
477 | static inline int check_entry(const struct arpt_entry *e, const char *name) | 477 | static inline int check_entry(const struct arpt_entry *e) |
478 | { | 478 | { |
479 | const struct xt_entry_target *t; | 479 | const struct xt_entry_target *t; |
480 | 480 | ||
481 | if (!arp_checkentry(&e->arp)) { | 481 | if (!arp_checkentry(&e->arp)) |
482 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); | ||
483 | return -EINVAL; | 482 | return -EINVAL; |
484 | } | ||
485 | 483 | ||
486 | if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) | 484 | if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) |
487 | return -EINVAL; | 485 | return -EINVAL; |
@@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) | |||
522 | struct xt_target *target; | 520 | struct xt_target *target; |
523 | int ret; | 521 | int ret; |
524 | 522 | ||
525 | ret = check_entry(e, name); | ||
526 | if (ret) | ||
527 | return ret; | ||
528 | |||
529 | e->counters.pcnt = xt_percpu_counter_alloc(); | 523 | e->counters.pcnt = xt_percpu_counter_alloc(); |
530 | if (IS_ERR_VALUE(e->counters.pcnt)) | 524 | if (IS_ERR_VALUE(e->counters.pcnt)) |
531 | return -ENOMEM; | 525 | return -ENOMEM; |
@@ -557,7 +551,7 @@ static bool check_underflow(const struct arpt_entry *e) | |||
557 | const struct xt_entry_target *t; | 551 | const struct xt_entry_target *t; |
558 | unsigned int verdict; | 552 | unsigned int verdict; |
559 | 553 | ||
560 | if (!unconditional(&e->arp)) | 554 | if (!unconditional(e)) |
561 | return false; | 555 | return false; |
562 | t = arpt_get_target_c(e); | 556 | t = arpt_get_target_c(e); |
563 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 557 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -576,9 +570,11 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
576 | unsigned int valid_hooks) | 570 | unsigned int valid_hooks) |
577 | { | 571 | { |
578 | unsigned int h; | 572 | unsigned int h; |
573 | int err; | ||
579 | 574 | ||
580 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || | 575 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || |
581 | (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { | 576 | (unsigned char *)e + sizeof(struct arpt_entry) >= limit || |
577 | (unsigned char *)e + e->next_offset > limit) { | ||
582 | duprintf("Bad offset %p\n", e); | 578 | duprintf("Bad offset %p\n", e); |
583 | return -EINVAL; | 579 | return -EINVAL; |
584 | } | 580 | } |
@@ -590,6 +586,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
590 | return -EINVAL; | 586 | return -EINVAL; |
591 | } | 587 | } |
592 | 588 | ||
589 | err = check_entry(e); | ||
590 | if (err) | ||
591 | return err; | ||
592 | |||
593 | /* Check hooks & underflows */ | 593 | /* Check hooks & underflows */ |
594 | for (h = 0; h < NF_ARP_NUMHOOKS; h++) { | 594 | for (h = 0; h < NF_ARP_NUMHOOKS; h++) { |
595 | if (!(valid_hooks & (1 << h))) | 595 | if (!(valid_hooks & (1 << h))) |
@@ -598,9 +598,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
598 | newinfo->hook_entry[h] = hook_entries[h]; | 598 | newinfo->hook_entry[h] = hook_entries[h]; |
599 | if ((unsigned char *)e - base == underflows[h]) { | 599 | if ((unsigned char *)e - base == underflows[h]) { |
600 | if (!check_underflow(e)) { | 600 | if (!check_underflow(e)) { |
601 | pr_err("Underflows must be unconditional and " | 601 | pr_debug("Underflows must be unconditional and " |
602 | "use the STANDARD target with " | 602 | "use the STANDARD target with " |
603 | "ACCEPT/DROP\n"); | 603 | "ACCEPT/DROP\n"); |
604 | return -EINVAL; | 604 | return -EINVAL; |
605 | } | 605 | } |
606 | newinfo->underflow[h] = underflows[h]; | 606 | newinfo->underflow[h] = underflows[h]; |
@@ -969,6 +969,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
969 | sizeof(struct arpt_get_entries) + get.size); | 969 | sizeof(struct arpt_get_entries) + get.size); |
970 | return -EINVAL; | 970 | return -EINVAL; |
971 | } | 971 | } |
972 | get.name[sizeof(get.name) - 1] = '\0'; | ||
972 | 973 | ||
973 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); | 974 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
974 | if (!IS_ERR_OR_NULL(t)) { | 975 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1233,7 +1234,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1233 | 1234 | ||
1234 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1235 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1235 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || | 1236 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || |
1236 | (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { | 1237 | (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || |
1238 | (unsigned char *)e + e->next_offset > limit) { | ||
1237 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1239 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1238 | return -EINVAL; | 1240 | return -EINVAL; |
1239 | } | 1241 | } |
@@ -1246,7 +1248,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1246 | } | 1248 | } |
1247 | 1249 | ||
1248 | /* For purposes of check_entry casting the compat entry is fine */ | 1250 | /* For purposes of check_entry casting the compat entry is fine */ |
1249 | ret = check_entry((struct arpt_entry *)e, name); | 1251 | ret = check_entry((struct arpt_entry *)e); |
1250 | if (ret) | 1252 | if (ret) |
1251 | return ret; | 1253 | return ret; |
1252 | 1254 | ||
@@ -1662,6 +1664,7 @@ static int compat_get_entries(struct net *net, | |||
1662 | *len, sizeof(get) + get.size); | 1664 | *len, sizeof(get) + get.size); |
1663 | return -EINVAL; | 1665 | return -EINVAL; |
1664 | } | 1666 | } |
1667 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1665 | 1668 | ||
1666 | xt_compat_lock(NFPROTO_ARP); | 1669 | xt_compat_lock(NFPROTO_ARP); |
1667 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); | 1670 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index dd8c80dc32a2..8f8713b4388f 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -81,6 +81,12 @@ static int __init arptable_filter_init(void) | |||
81 | return ret; | 81 | return ret; |
82 | } | 82 | } |
83 | 83 | ||
84 | ret = arptable_filter_table_init(&init_net); | ||
85 | if (ret) { | ||
86 | unregister_pernet_subsys(&arptable_filter_net_ops); | ||
87 | kfree(arpfilter_ops); | ||
88 | } | ||
89 | |||
84 | return ret; | 90 | return ret; |
85 | } | 91 | } |
86 | 92 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e53f8d6f326d..631c100a1338 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) | |||
168 | 168 | ||
169 | /* All zeroes == unconditional rule. */ | 169 | /* All zeroes == unconditional rule. */ |
170 | /* Mildly perf critical (only if packet tracing is on) */ | 170 | /* Mildly perf critical (only if packet tracing is on) */ |
171 | static inline bool unconditional(const struct ipt_ip *ip) | 171 | static inline bool unconditional(const struct ipt_entry *e) |
172 | { | 172 | { |
173 | static const struct ipt_ip uncond; | 173 | static const struct ipt_ip uncond; |
174 | 174 | ||
175 | return memcmp(ip, &uncond, sizeof(uncond)) == 0; | 175 | return e->target_offset == sizeof(struct ipt_entry) && |
176 | memcmp(&e->ip, &uncond, sizeof(uncond)) == 0; | ||
176 | #undef FWINV | 177 | #undef FWINV |
177 | } | 178 | } |
178 | 179 | ||
@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, | |||
229 | } else if (s == e) { | 230 | } else if (s == e) { |
230 | (*rulenum)++; | 231 | (*rulenum)++; |
231 | 232 | ||
232 | if (s->target_offset == sizeof(struct ipt_entry) && | 233 | if (unconditional(s) && |
233 | strcmp(t->target.u.kernel.target->name, | 234 | strcmp(t->target.u.kernel.target->name, |
234 | XT_STANDARD_TARGET) == 0 && | 235 | XT_STANDARD_TARGET) == 0 && |
235 | t->verdict < 0 && | 236 | t->verdict < 0) { |
236 | unconditional(&s->ip)) { | ||
237 | /* Tail of chains: STANDARD target (return/policy) */ | 237 | /* Tail of chains: STANDARD target (return/policy) */ |
238 | *comment = *chainname == hookname | 238 | *comment = *chainname == hookname |
239 | ? comments[NF_IP_TRACE_COMMENT_POLICY] | 239 | ? comments[NF_IP_TRACE_COMMENT_POLICY] |
@@ -476,11 +476,10 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
476 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 476 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
477 | 477 | ||
478 | /* Unconditional return/END. */ | 478 | /* Unconditional return/END. */ |
479 | if ((e->target_offset == sizeof(struct ipt_entry) && | 479 | if ((unconditional(e) && |
480 | (strcmp(t->target.u.user.name, | 480 | (strcmp(t->target.u.user.name, |
481 | XT_STANDARD_TARGET) == 0) && | 481 | XT_STANDARD_TARGET) == 0) && |
482 | t->verdict < 0 && unconditional(&e->ip)) || | 482 | t->verdict < 0) || visited) { |
483 | visited) { | ||
484 | unsigned int oldpos, size; | 483 | unsigned int oldpos, size; |
485 | 484 | ||
486 | if ((strcmp(t->target.u.user.name, | 485 | if ((strcmp(t->target.u.user.name, |
@@ -569,14 +568,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) | |||
569 | } | 568 | } |
570 | 569 | ||
571 | static int | 570 | static int |
572 | check_entry(const struct ipt_entry *e, const char *name) | 571 | check_entry(const struct ipt_entry *e) |
573 | { | 572 | { |
574 | const struct xt_entry_target *t; | 573 | const struct xt_entry_target *t; |
575 | 574 | ||
576 | if (!ip_checkentry(&e->ip)) { | 575 | if (!ip_checkentry(&e->ip)) |
577 | duprintf("ip check failed %p %s.\n", e, name); | ||
578 | return -EINVAL; | 576 | return -EINVAL; |
579 | } | ||
580 | 577 | ||
581 | if (e->target_offset + sizeof(struct xt_entry_target) > | 578 | if (e->target_offset + sizeof(struct xt_entry_target) > |
582 | e->next_offset) | 579 | e->next_offset) |
@@ -666,10 +663,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
666 | struct xt_mtchk_param mtpar; | 663 | struct xt_mtchk_param mtpar; |
667 | struct xt_entry_match *ematch; | 664 | struct xt_entry_match *ematch; |
668 | 665 | ||
669 | ret = check_entry(e, name); | ||
670 | if (ret) | ||
671 | return ret; | ||
672 | |||
673 | e->counters.pcnt = xt_percpu_counter_alloc(); | 666 | e->counters.pcnt = xt_percpu_counter_alloc(); |
674 | if (IS_ERR_VALUE(e->counters.pcnt)) | 667 | if (IS_ERR_VALUE(e->counters.pcnt)) |
675 | return -ENOMEM; | 668 | return -ENOMEM; |
@@ -721,7 +714,7 @@ static bool check_underflow(const struct ipt_entry *e) | |||
721 | const struct xt_entry_target *t; | 714 | const struct xt_entry_target *t; |
722 | unsigned int verdict; | 715 | unsigned int verdict; |
723 | 716 | ||
724 | if (!unconditional(&e->ip)) | 717 | if (!unconditional(e)) |
725 | return false; | 718 | return false; |
726 | t = ipt_get_target_c(e); | 719 | t = ipt_get_target_c(e); |
727 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 720 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -741,9 +734,11 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
741 | unsigned int valid_hooks) | 734 | unsigned int valid_hooks) |
742 | { | 735 | { |
743 | unsigned int h; | 736 | unsigned int h; |
737 | int err; | ||
744 | 738 | ||
745 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || | 739 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || |
746 | (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { | 740 | (unsigned char *)e + sizeof(struct ipt_entry) >= limit || |
741 | (unsigned char *)e + e->next_offset > limit) { | ||
747 | duprintf("Bad offset %p\n", e); | 742 | duprintf("Bad offset %p\n", e); |
748 | return -EINVAL; | 743 | return -EINVAL; |
749 | } | 744 | } |
@@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
755 | return -EINVAL; | 750 | return -EINVAL; |
756 | } | 751 | } |
757 | 752 | ||
753 | err = check_entry(e); | ||
754 | if (err) | ||
755 | return err; | ||
756 | |||
758 | /* Check hooks & underflows */ | 757 | /* Check hooks & underflows */ |
759 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { | 758 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { |
760 | if (!(valid_hooks & (1 << h))) | 759 | if (!(valid_hooks & (1 << h))) |
@@ -763,9 +762,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
763 | newinfo->hook_entry[h] = hook_entries[h]; | 762 | newinfo->hook_entry[h] = hook_entries[h]; |
764 | if ((unsigned char *)e - base == underflows[h]) { | 763 | if ((unsigned char *)e - base == underflows[h]) { |
765 | if (!check_underflow(e)) { | 764 | if (!check_underflow(e)) { |
766 | pr_err("Underflows must be unconditional and " | 765 | pr_debug("Underflows must be unconditional and " |
767 | "use the STANDARD target with " | 766 | "use the STANDARD target with " |
768 | "ACCEPT/DROP\n"); | 767 | "ACCEPT/DROP\n"); |
769 | return -EINVAL; | 768 | return -EINVAL; |
770 | } | 769 | } |
771 | newinfo->underflow[h] = underflows[h]; | 770 | newinfo->underflow[h] = underflows[h]; |
@@ -1157,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, | |||
1157 | *len, sizeof(get) + get.size); | 1156 | *len, sizeof(get) + get.size); |
1158 | return -EINVAL; | 1157 | return -EINVAL; |
1159 | } | 1158 | } |
1159 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1160 | 1160 | ||
1161 | t = xt_find_table_lock(net, AF_INET, get.name); | 1161 | t = xt_find_table_lock(net, AF_INET, get.name); |
1162 | if (!IS_ERR_OR_NULL(t)) { | 1162 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1493,7 +1493,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1493 | 1493 | ||
1494 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1494 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1495 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || | 1495 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || |
1496 | (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { | 1496 | (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit || |
1497 | (unsigned char *)e + e->next_offset > limit) { | ||
1497 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1498 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1498 | return -EINVAL; | 1499 | return -EINVAL; |
1499 | } | 1500 | } |
@@ -1506,7 +1507,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1506 | } | 1507 | } |
1507 | 1508 | ||
1508 | /* For purposes of check_entry casting the compat entry is fine */ | 1509 | /* For purposes of check_entry casting the compat entry is fine */ |
1509 | ret = check_entry((struct ipt_entry *)e, name); | 1510 | ret = check_entry((struct ipt_entry *)e); |
1510 | if (ret) | 1511 | if (ret) |
1511 | return ret; | 1512 | return ret; |
1512 | 1513 | ||
@@ -1935,6 +1936,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, | |||
1935 | *len, sizeof(get) + get.size); | 1936 | *len, sizeof(get) + get.size); |
1936 | return -EINVAL; | 1937 | return -EINVAL; |
1937 | } | 1938 | } |
1939 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1938 | 1940 | ||
1939 | xt_compat_lock(AF_INET); | 1941 | xt_compat_lock(AF_INET); |
1940 | t = xt_find_table_lock(net, AF_INET, get.name); | 1942 | t = xt_find_table_lock(net, AF_INET, get.name); |
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 7b8fbb352877..db5b87509446 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
@@ -18,10 +18,10 @@ | |||
18 | #include <net/netfilter/nf_conntrack_synproxy.h> | 18 | #include <net/netfilter/nf_conntrack_synproxy.h> |
19 | 19 | ||
20 | static struct iphdr * | 20 | static struct iphdr * |
21 | synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) | 21 | synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, |
22 | __be32 daddr) | ||
22 | { | 23 | { |
23 | struct iphdr *iph; | 24 | struct iphdr *iph; |
24 | struct net *net = sock_net(skb->sk); | ||
25 | 25 | ||
26 | skb_reset_network_header(skb); | 26 | skb_reset_network_header(skb); |
27 | iph = (struct iphdr *)skb_put(skb, sizeof(*iph)); | 27 | iph = (struct iphdr *)skb_put(skb, sizeof(*iph)); |
@@ -40,14 +40,12 @@ synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | static void | 42 | static void |
43 | synproxy_send_tcp(const struct synproxy_net *snet, | 43 | synproxy_send_tcp(struct net *net, |
44 | const struct sk_buff *skb, struct sk_buff *nskb, | 44 | const struct sk_buff *skb, struct sk_buff *nskb, |
45 | struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, | 45 | struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, |
46 | struct iphdr *niph, struct tcphdr *nth, | 46 | struct iphdr *niph, struct tcphdr *nth, |
47 | unsigned int tcp_hdr_size) | 47 | unsigned int tcp_hdr_size) |
48 | { | 48 | { |
49 | struct net *net = nf_ct_net(snet->tmpl); | ||
50 | |||
51 | nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); | 49 | nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); |
52 | nskb->ip_summed = CHECKSUM_PARTIAL; | 50 | nskb->ip_summed = CHECKSUM_PARTIAL; |
53 | nskb->csum_start = (unsigned char *)nth - nskb->head; | 51 | nskb->csum_start = (unsigned char *)nth - nskb->head; |
@@ -72,7 +70,7 @@ free_nskb: | |||
72 | } | 70 | } |
73 | 71 | ||
74 | static void | 72 | static void |
75 | synproxy_send_client_synack(const struct synproxy_net *snet, | 73 | synproxy_send_client_synack(struct net *net, |
76 | const struct sk_buff *skb, const struct tcphdr *th, | 74 | const struct sk_buff *skb, const struct tcphdr *th, |
77 | const struct synproxy_options *opts) | 75 | const struct synproxy_options *opts) |
78 | { | 76 | { |
@@ -91,7 +89,7 @@ synproxy_send_client_synack(const struct synproxy_net *snet, | |||
91 | return; | 89 | return; |
92 | skb_reserve(nskb, MAX_TCP_HEADER); | 90 | skb_reserve(nskb, MAX_TCP_HEADER); |
93 | 91 | ||
94 | niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); | 92 | niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); |
95 | 93 | ||
96 | skb_reset_transport_header(nskb); | 94 | skb_reset_transport_header(nskb); |
97 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 95 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -109,15 +107,16 @@ synproxy_send_client_synack(const struct synproxy_net *snet, | |||
109 | 107 | ||
110 | synproxy_build_options(nth, opts); | 108 | synproxy_build_options(nth, opts); |
111 | 109 | ||
112 | synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, | 110 | synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, |
113 | niph, nth, tcp_hdr_size); | 111 | niph, nth, tcp_hdr_size); |
114 | } | 112 | } |
115 | 113 | ||
116 | static void | 114 | static void |
117 | synproxy_send_server_syn(const struct synproxy_net *snet, | 115 | synproxy_send_server_syn(struct net *net, |
118 | const struct sk_buff *skb, const struct tcphdr *th, | 116 | const struct sk_buff *skb, const struct tcphdr *th, |
119 | const struct synproxy_options *opts, u32 recv_seq) | 117 | const struct synproxy_options *opts, u32 recv_seq) |
120 | { | 118 | { |
119 | struct synproxy_net *snet = synproxy_pernet(net); | ||
121 | struct sk_buff *nskb; | 120 | struct sk_buff *nskb; |
122 | struct iphdr *iph, *niph; | 121 | struct iphdr *iph, *niph; |
123 | struct tcphdr *nth; | 122 | struct tcphdr *nth; |
@@ -132,7 +131,7 @@ synproxy_send_server_syn(const struct synproxy_net *snet, | |||
132 | return; | 131 | return; |
133 | skb_reserve(nskb, MAX_TCP_HEADER); | 132 | skb_reserve(nskb, MAX_TCP_HEADER); |
134 | 133 | ||
135 | niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); | 134 | niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); |
136 | 135 | ||
137 | skb_reset_transport_header(nskb); | 136 | skb_reset_transport_header(nskb); |
138 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 137 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -153,12 +152,12 @@ synproxy_send_server_syn(const struct synproxy_net *snet, | |||
153 | 152 | ||
154 | synproxy_build_options(nth, opts); | 153 | synproxy_build_options(nth, opts); |
155 | 154 | ||
156 | synproxy_send_tcp(snet, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, | 155 | synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, |
157 | niph, nth, tcp_hdr_size); | 156 | niph, nth, tcp_hdr_size); |
158 | } | 157 | } |
159 | 158 | ||
160 | static void | 159 | static void |
161 | synproxy_send_server_ack(const struct synproxy_net *snet, | 160 | synproxy_send_server_ack(struct net *net, |
162 | const struct ip_ct_tcp *state, | 161 | const struct ip_ct_tcp *state, |
163 | const struct sk_buff *skb, const struct tcphdr *th, | 162 | const struct sk_buff *skb, const struct tcphdr *th, |
164 | const struct synproxy_options *opts) | 163 | const struct synproxy_options *opts) |
@@ -177,7 +176,7 @@ synproxy_send_server_ack(const struct synproxy_net *snet, | |||
177 | return; | 176 | return; |
178 | skb_reserve(nskb, MAX_TCP_HEADER); | 177 | skb_reserve(nskb, MAX_TCP_HEADER); |
179 | 178 | ||
180 | niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); | 179 | niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); |
181 | 180 | ||
182 | skb_reset_transport_header(nskb); | 181 | skb_reset_transport_header(nskb); |
183 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 182 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -193,11 +192,11 @@ synproxy_send_server_ack(const struct synproxy_net *snet, | |||
193 | 192 | ||
194 | synproxy_build_options(nth, opts); | 193 | synproxy_build_options(nth, opts); |
195 | 194 | ||
196 | synproxy_send_tcp(snet, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); | 195 | synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); |
197 | } | 196 | } |
198 | 197 | ||
199 | static void | 198 | static void |
200 | synproxy_send_client_ack(const struct synproxy_net *snet, | 199 | synproxy_send_client_ack(struct net *net, |
201 | const struct sk_buff *skb, const struct tcphdr *th, | 200 | const struct sk_buff *skb, const struct tcphdr *th, |
202 | const struct synproxy_options *opts) | 201 | const struct synproxy_options *opts) |
203 | { | 202 | { |
@@ -215,7 +214,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, | |||
215 | return; | 214 | return; |
216 | skb_reserve(nskb, MAX_TCP_HEADER); | 215 | skb_reserve(nskb, MAX_TCP_HEADER); |
217 | 216 | ||
218 | niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); | 217 | niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); |
219 | 218 | ||
220 | skb_reset_transport_header(nskb); | 219 | skb_reset_transport_header(nskb); |
221 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 220 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -231,15 +230,16 @@ synproxy_send_client_ack(const struct synproxy_net *snet, | |||
231 | 230 | ||
232 | synproxy_build_options(nth, opts); | 231 | synproxy_build_options(nth, opts); |
233 | 232 | ||
234 | synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, | 233 | synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, |
235 | niph, nth, tcp_hdr_size); | 234 | niph, nth, tcp_hdr_size); |
236 | } | 235 | } |
237 | 236 | ||
238 | static bool | 237 | static bool |
239 | synproxy_recv_client_ack(const struct synproxy_net *snet, | 238 | synproxy_recv_client_ack(struct net *net, |
240 | const struct sk_buff *skb, const struct tcphdr *th, | 239 | const struct sk_buff *skb, const struct tcphdr *th, |
241 | struct synproxy_options *opts, u32 recv_seq) | 240 | struct synproxy_options *opts, u32 recv_seq) |
242 | { | 241 | { |
242 | struct synproxy_net *snet = synproxy_pernet(net); | ||
243 | int mss; | 243 | int mss; |
244 | 244 | ||
245 | mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); | 245 | mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); |
@@ -255,7 +255,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, | |||
255 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) | 255 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) |
256 | synproxy_check_timestamp_cookie(opts); | 256 | synproxy_check_timestamp_cookie(opts); |
257 | 257 | ||
258 | synproxy_send_server_syn(snet, skb, th, opts, recv_seq); | 258 | synproxy_send_server_syn(net, skb, th, opts, recv_seq); |
259 | return true; | 259 | return true; |
260 | } | 260 | } |
261 | 261 | ||
@@ -263,7 +263,8 @@ static unsigned int | |||
263 | synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) | 263 | synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) |
264 | { | 264 | { |
265 | const struct xt_synproxy_info *info = par->targinfo; | 265 | const struct xt_synproxy_info *info = par->targinfo; |
266 | struct synproxy_net *snet = synproxy_pernet(par->net); | 266 | struct net *net = par->net; |
267 | struct synproxy_net *snet = synproxy_pernet(net); | ||
267 | struct synproxy_options opts = {}; | 268 | struct synproxy_options opts = {}; |
268 | struct tcphdr *th, _th; | 269 | struct tcphdr *th, _th; |
269 | 270 | ||
@@ -292,12 +293,12 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) | |||
292 | XT_SYNPROXY_OPT_SACK_PERM | | 293 | XT_SYNPROXY_OPT_SACK_PERM | |
293 | XT_SYNPROXY_OPT_ECN); | 294 | XT_SYNPROXY_OPT_ECN); |
294 | 295 | ||
295 | synproxy_send_client_synack(snet, skb, th, &opts); | 296 | synproxy_send_client_synack(net, skb, th, &opts); |
296 | return NF_DROP; | 297 | return NF_DROP; |
297 | 298 | ||
298 | } else if (th->ack && !(th->fin || th->rst || th->syn)) { | 299 | } else if (th->ack && !(th->fin || th->rst || th->syn)) { |
299 | /* ACK from client */ | 300 | /* ACK from client */ |
300 | synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); | 301 | synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); |
301 | return NF_DROP; | 302 | return NF_DROP; |
302 | } | 303 | } |
303 | 304 | ||
@@ -308,7 +309,8 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
308 | struct sk_buff *skb, | 309 | struct sk_buff *skb, |
309 | const struct nf_hook_state *nhs) | 310 | const struct nf_hook_state *nhs) |
310 | { | 311 | { |
311 | struct synproxy_net *snet = synproxy_pernet(nhs->net); | 312 | struct net *net = nhs->net; |
313 | struct synproxy_net *snet = synproxy_pernet(net); | ||
312 | enum ip_conntrack_info ctinfo; | 314 | enum ip_conntrack_info ctinfo; |
313 | struct nf_conn *ct; | 315 | struct nf_conn *ct; |
314 | struct nf_conn_synproxy *synproxy; | 316 | struct nf_conn_synproxy *synproxy; |
@@ -365,7 +367,7 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
365 | * therefore we need to add 1 to make the SYN sequence | 367 | * therefore we need to add 1 to make the SYN sequence |
366 | * number match the one of first SYN. | 368 | * number match the one of first SYN. |
367 | */ | 369 | */ |
368 | if (synproxy_recv_client_ack(snet, skb, th, &opts, | 370 | if (synproxy_recv_client_ack(net, skb, th, &opts, |
369 | ntohl(th->seq) + 1)) | 371 | ntohl(th->seq) + 1)) |
370 | this_cpu_inc(snet->stats->cookie_retrans); | 372 | this_cpu_inc(snet->stats->cookie_retrans); |
371 | 373 | ||
@@ -391,12 +393,12 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
391 | XT_SYNPROXY_OPT_SACK_PERM); | 393 | XT_SYNPROXY_OPT_SACK_PERM); |
392 | 394 | ||
393 | swap(opts.tsval, opts.tsecr); | 395 | swap(opts.tsval, opts.tsecr); |
394 | synproxy_send_server_ack(snet, state, skb, th, &opts); | 396 | synproxy_send_server_ack(net, state, skb, th, &opts); |
395 | 397 | ||
396 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); | 398 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); |
397 | 399 | ||
398 | swap(opts.tsval, opts.tsecr); | 400 | swap(opts.tsval, opts.tsecr); |
399 | synproxy_send_client_ack(snet, skb, th, &opts); | 401 | synproxy_send_client_ack(net, skb, th, &opts); |
400 | 402 | ||
401 | consume_skb(skb); | 403 | consume_skb(skb); |
402 | return NF_STOLEN; | 404 | return NF_STOLEN; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 02c62299d717..60398a9370e7 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1438,9 +1438,9 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, | |||
1438 | #endif | 1438 | #endif |
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | static struct rtable *rt_dst_alloc(struct net_device *dev, | 1441 | struct rtable *rt_dst_alloc(struct net_device *dev, |
1442 | unsigned int flags, u16 type, | 1442 | unsigned int flags, u16 type, |
1443 | bool nopolicy, bool noxfrm, bool will_cache) | 1443 | bool nopolicy, bool noxfrm, bool will_cache) |
1444 | { | 1444 | { |
1445 | struct rtable *rt; | 1445 | struct rtable *rt; |
1446 | 1446 | ||
@@ -1468,6 +1468,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev, | |||
1468 | 1468 | ||
1469 | return rt; | 1469 | return rt; |
1470 | } | 1470 | } |
1471 | EXPORT_SYMBOL(rt_dst_alloc); | ||
1471 | 1472 | ||
1472 | /* called in rcu_read_lock() section */ | 1473 | /* called in rcu_read_lock() section */ |
1473 | static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | 1474 | static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
@@ -2045,6 +2046,18 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2045 | */ | 2046 | */ |
2046 | if (fi && res->prefixlen < 4) | 2047 | if (fi && res->prefixlen < 4) |
2047 | fi = NULL; | 2048 | fi = NULL; |
2049 | } else if ((type == RTN_LOCAL) && (orig_oif != 0) && | ||
2050 | (orig_oif != dev_out->ifindex)) { | ||
2051 | /* For local routes that require a particular output interface | ||
2052 | * we do not want to cache the result. Caching the result | ||
2053 | * causes incorrect behaviour when there are multiple source | ||
2054 | * addresses on the interface, the end result being that if the | ||
2055 | * intended recipient is waiting on that interface for the | ||
2056 | * packet he won't receive it because it will be delivered on | ||
2057 | * the loopback interface and the IP_PKTINFO ipi_ifindex will | ||
2058 | * be set to the loopback interface as well. | ||
2059 | */ | ||
2060 | fi = NULL; | ||
2048 | } | 2061 | } |
2049 | 2062 | ||
2050 | fnhe = NULL; | 2063 | fnhe = NULL; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e6e65f79ade8..c124c3c12f7c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1309,6 +1309,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, | |||
1309 | if (skb == tcp_highest_sack(sk)) | 1309 | if (skb == tcp_highest_sack(sk)) |
1310 | tcp_advance_highest_sack(sk, skb); | 1310 | tcp_advance_highest_sack(sk, skb); |
1311 | 1311 | ||
1312 | tcp_skb_collapse_tstamp(prev, skb); | ||
1312 | tcp_unlink_write_queue(skb, sk); | 1313 | tcp_unlink_write_queue(skb, sk); |
1313 | sk_wmem_free_skb(sk, skb); | 1314 | sk_wmem_free_skb(sk, skb); |
1314 | 1315 | ||
@@ -3098,7 +3099,8 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, | |||
3098 | 3099 | ||
3099 | shinfo = skb_shinfo(skb); | 3100 | shinfo = skb_shinfo(skb); |
3100 | if ((shinfo->tx_flags & SKBTX_ACK_TSTAMP) && | 3101 | if ((shinfo->tx_flags & SKBTX_ACK_TSTAMP) && |
3101 | between(shinfo->tskey, prior_snd_una, tcp_sk(sk)->snd_una - 1)) | 3102 | !before(shinfo->tskey, prior_snd_una) && |
3103 | before(shinfo->tskey, tcp_sk(sk)->snd_una)) | ||
3102 | __skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK); | 3104 | __skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK); |
3103 | } | 3105 | } |
3104 | 3106 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7d2dc015cd19..441ae9da3a23 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2441,6 +2441,20 @@ u32 __tcp_select_window(struct sock *sk) | |||
2441 | return window; | 2441 | return window; |
2442 | } | 2442 | } |
2443 | 2443 | ||
2444 | void tcp_skb_collapse_tstamp(struct sk_buff *skb, | ||
2445 | const struct sk_buff *next_skb) | ||
2446 | { | ||
2447 | const struct skb_shared_info *next_shinfo = skb_shinfo(next_skb); | ||
2448 | u8 tsflags = next_shinfo->tx_flags & SKBTX_ANY_TSTAMP; | ||
2449 | |||
2450 | if (unlikely(tsflags)) { | ||
2451 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
2452 | |||
2453 | shinfo->tx_flags |= tsflags; | ||
2454 | shinfo->tskey = next_shinfo->tskey; | ||
2455 | } | ||
2456 | } | ||
2457 | |||
2444 | /* Collapses two adjacent SKB's during retransmission. */ | 2458 | /* Collapses two adjacent SKB's during retransmission. */ |
2445 | static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) | 2459 | static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) |
2446 | { | 2460 | { |
@@ -2484,6 +2498,8 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) | |||
2484 | 2498 | ||
2485 | tcp_adjust_pcount(sk, next_skb, tcp_skb_pcount(next_skb)); | 2499 | tcp_adjust_pcount(sk, next_skb, tcp_skb_pcount(next_skb)); |
2486 | 2500 | ||
2501 | tcp_skb_collapse_tstamp(skb, next_skb); | ||
2502 | |||
2487 | sk_wmem_free_skb(sk, next_skb); | 2503 | sk_wmem_free_skb(sk, next_skb); |
2488 | } | 2504 | } |
2489 | 2505 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 08eed5e16df0..a2e7f55a1f61 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -339,8 +339,13 @@ found: | |||
339 | 339 | ||
340 | hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); | 340 | hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); |
341 | spin_lock(&hslot2->lock); | 341 | spin_lock(&hslot2->lock); |
342 | hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, | 342 | if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && |
343 | &hslot2->head); | 343 | sk->sk_family == AF_INET6) |
344 | hlist_nulls_add_tail_rcu(&udp_sk(sk)->udp_portaddr_node, | ||
345 | &hslot2->head); | ||
346 | else | ||
347 | hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, | ||
348 | &hslot2->head); | ||
344 | hslot2->count++; | 349 | hslot2->count++; |
345 | spin_unlock(&hslot2->lock); | 350 | spin_unlock(&hslot2->lock); |
346 | } | 351 | } |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 27aed1afcf81..8ec4b3089e20 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3176,35 +3176,9 @@ static void addrconf_gre_config(struct net_device *dev) | |||
3176 | } | 3176 | } |
3177 | #endif | 3177 | #endif |
3178 | 3178 | ||
3179 | #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) | ||
3180 | /* If the host route is cached on the addr struct make sure it is associated | ||
3181 | * with the proper table. e.g., enslavement can change and if so the cached | ||
3182 | * host route needs to move to the new table. | ||
3183 | */ | ||
3184 | static void l3mdev_check_host_rt(struct inet6_dev *idev, | ||
3185 | struct inet6_ifaddr *ifp) | ||
3186 | { | ||
3187 | if (ifp->rt) { | ||
3188 | u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; | ||
3189 | |||
3190 | if (tb_id != ifp->rt->rt6i_table->tb6_id) { | ||
3191 | ip6_del_rt(ifp->rt); | ||
3192 | ifp->rt = NULL; | ||
3193 | } | ||
3194 | } | ||
3195 | } | ||
3196 | #else | ||
3197 | static void l3mdev_check_host_rt(struct inet6_dev *idev, | ||
3198 | struct inet6_ifaddr *ifp) | ||
3199 | { | ||
3200 | } | ||
3201 | #endif | ||
3202 | |||
3203 | static int fixup_permanent_addr(struct inet6_dev *idev, | 3179 | static int fixup_permanent_addr(struct inet6_dev *idev, |
3204 | struct inet6_ifaddr *ifp) | 3180 | struct inet6_ifaddr *ifp) |
3205 | { | 3181 | { |
3206 | l3mdev_check_host_rt(idev, ifp); | ||
3207 | |||
3208 | if (!ifp->rt) { | 3182 | if (!ifp->rt) { |
3209 | struct rt6_info *rt; | 3183 | struct rt6_info *rt; |
3210 | 3184 | ||
@@ -3255,6 +3229,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3255 | void *ptr) | 3229 | void *ptr) |
3256 | { | 3230 | { |
3257 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 3231 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
3232 | struct netdev_notifier_changeupper_info *info; | ||
3258 | struct inet6_dev *idev = __in6_dev_get(dev); | 3233 | struct inet6_dev *idev = __in6_dev_get(dev); |
3259 | int run_pending = 0; | 3234 | int run_pending = 0; |
3260 | int err; | 3235 | int err; |
@@ -3303,6 +3278,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3303 | break; | 3278 | break; |
3304 | 3279 | ||
3305 | if (event == NETDEV_UP) { | 3280 | if (event == NETDEV_UP) { |
3281 | /* restore routes for permanent addresses */ | ||
3282 | addrconf_permanent_addr(dev); | ||
3283 | |||
3306 | if (!addrconf_qdisc_ok(dev)) { | 3284 | if (!addrconf_qdisc_ok(dev)) { |
3307 | /* device is not ready yet. */ | 3285 | /* device is not ready yet. */ |
3308 | pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", | 3286 | pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", |
@@ -3336,9 +3314,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3336 | run_pending = 1; | 3314 | run_pending = 1; |
3337 | } | 3315 | } |
3338 | 3316 | ||
3339 | /* restore routes for permanent addresses */ | ||
3340 | addrconf_permanent_addr(dev); | ||
3341 | |||
3342 | switch (dev->type) { | 3317 | switch (dev->type) { |
3343 | #if IS_ENABLED(CONFIG_IPV6_SIT) | 3318 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
3344 | case ARPHRD_SIT: | 3319 | case ARPHRD_SIT: |
@@ -3413,6 +3388,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3413 | if (idev) | 3388 | if (idev) |
3414 | addrconf_type_change(dev, event); | 3389 | addrconf_type_change(dev, event); |
3415 | break; | 3390 | break; |
3391 | |||
3392 | case NETDEV_CHANGEUPPER: | ||
3393 | info = ptr; | ||
3394 | |||
3395 | /* flush all routes if dev is linked to or unlinked from | ||
3396 | * an L3 master device (e.g., VRF) | ||
3397 | */ | ||
3398 | if (info->upper_dev && netif_is_l3_master(info->upper_dev)) | ||
3399 | addrconf_ifdown(dev, 0); | ||
3416 | } | 3400 | } |
3417 | 3401 | ||
3418 | return NOTIFY_OK; | 3402 | return NOTIFY_OK; |
@@ -3438,6 +3422,12 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event) | |||
3438 | ipv6_mc_unmap(idev); | 3422 | ipv6_mc_unmap(idev); |
3439 | } | 3423 | } |
3440 | 3424 | ||
3425 | static bool addr_is_local(const struct in6_addr *addr) | ||
3426 | { | ||
3427 | return ipv6_addr_type(addr) & | ||
3428 | (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); | ||
3429 | } | ||
3430 | |||
3441 | static int addrconf_ifdown(struct net_device *dev, int how) | 3431 | static int addrconf_ifdown(struct net_device *dev, int how) |
3442 | { | 3432 | { |
3443 | struct net *net = dev_net(dev); | 3433 | struct net *net = dev_net(dev); |
@@ -3495,7 +3485,8 @@ restart: | |||
3495 | * address is retained on a down event | 3485 | * address is retained on a down event |
3496 | */ | 3486 | */ |
3497 | if (!keep_addr || | 3487 | if (!keep_addr || |
3498 | !(ifa->flags & IFA_F_PERMANENT)) { | 3488 | !(ifa->flags & IFA_F_PERMANENT) || |
3489 | addr_is_local(&ifa->addr)) { | ||
3499 | hlist_del_init_rcu(&ifa->addr_lst); | 3490 | hlist_del_init_rcu(&ifa->addr_lst); |
3500 | goto restart; | 3491 | goto restart; |
3501 | } | 3492 | } |
@@ -3539,17 +3530,23 @@ restart: | |||
3539 | 3530 | ||
3540 | INIT_LIST_HEAD(&del_list); | 3531 | INIT_LIST_HEAD(&del_list); |
3541 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { | 3532 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { |
3533 | struct rt6_info *rt = NULL; | ||
3534 | |||
3542 | addrconf_del_dad_work(ifa); | 3535 | addrconf_del_dad_work(ifa); |
3543 | 3536 | ||
3544 | write_unlock_bh(&idev->lock); | 3537 | write_unlock_bh(&idev->lock); |
3545 | spin_lock_bh(&ifa->lock); | 3538 | spin_lock_bh(&ifa->lock); |
3546 | 3539 | ||
3547 | if (keep_addr && (ifa->flags & IFA_F_PERMANENT)) { | 3540 | if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && |
3541 | !addr_is_local(&ifa->addr)) { | ||
3548 | /* set state to skip the notifier below */ | 3542 | /* set state to skip the notifier below */ |
3549 | state = INET6_IFADDR_STATE_DEAD; | 3543 | state = INET6_IFADDR_STATE_DEAD; |
3550 | ifa->state = 0; | 3544 | ifa->state = 0; |
3551 | if (!(ifa->flags & IFA_F_NODAD)) | 3545 | if (!(ifa->flags & IFA_F_NODAD)) |
3552 | ifa->flags |= IFA_F_TENTATIVE; | 3546 | ifa->flags |= IFA_F_TENTATIVE; |
3547 | |||
3548 | rt = ifa->rt; | ||
3549 | ifa->rt = NULL; | ||
3553 | } else { | 3550 | } else { |
3554 | state = ifa->state; | 3551 | state = ifa->state; |
3555 | ifa->state = INET6_IFADDR_STATE_DEAD; | 3552 | ifa->state = INET6_IFADDR_STATE_DEAD; |
@@ -3560,6 +3557,9 @@ restart: | |||
3560 | 3557 | ||
3561 | spin_unlock_bh(&ifa->lock); | 3558 | spin_unlock_bh(&ifa->lock); |
3562 | 3559 | ||
3560 | if (rt) | ||
3561 | ip6_del_rt(rt); | ||
3562 | |||
3563 | if (state != INET6_IFADDR_STATE_DEAD) { | 3563 | if (state != INET6_IFADDR_STATE_DEAD) { |
3564 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 3564 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
3565 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); | 3565 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); |
@@ -5325,10 +5325,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
5325 | if (rt) | 5325 | if (rt) |
5326 | ip6_del_rt(rt); | 5326 | ip6_del_rt(rt); |
5327 | } | 5327 | } |
5328 | dst_hold(&ifp->rt->dst); | 5328 | if (ifp->rt) { |
5329 | 5329 | dst_hold(&ifp->rt->dst); | |
5330 | ip6_del_rt(ifp->rt); | 5330 | ip6_del_rt(ifp->rt); |
5331 | 5331 | } | |
5332 | rt_genid_bump_ipv6(net); | 5332 | rt_genid_bump_ipv6(net); |
5333 | break; | 5333 | break; |
5334 | } | 5334 | } |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 428162155280..9dd3882fe6bf 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -40,18 +40,114 @@ static bool ipv6_mapped_addr_any(const struct in6_addr *a) | |||
40 | return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0); | 40 | return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0); |
41 | } | 41 | } |
42 | 42 | ||
43 | static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk) | ||
44 | { | ||
45 | struct inet_sock *inet = inet_sk(sk); | ||
46 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
47 | |||
48 | memset(fl6, 0, sizeof(*fl6)); | ||
49 | fl6->flowi6_proto = sk->sk_protocol; | ||
50 | fl6->daddr = sk->sk_v6_daddr; | ||
51 | fl6->saddr = np->saddr; | ||
52 | fl6->flowi6_oif = sk->sk_bound_dev_if; | ||
53 | fl6->flowi6_mark = sk->sk_mark; | ||
54 | fl6->fl6_dport = inet->inet_dport; | ||
55 | fl6->fl6_sport = inet->inet_sport; | ||
56 | fl6->flowlabel = np->flow_label; | ||
57 | |||
58 | if (!fl6->flowi6_oif) | ||
59 | fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; | ||
60 | |||
61 | if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr)) | ||
62 | fl6->flowi6_oif = np->mcast_oif; | ||
63 | |||
64 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); | ||
65 | } | ||
66 | |||
67 | int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr) | ||
68 | { | ||
69 | struct ip6_flowlabel *flowlabel = NULL; | ||
70 | struct in6_addr *final_p, final; | ||
71 | struct ipv6_txoptions *opt; | ||
72 | struct dst_entry *dst; | ||
73 | struct inet_sock *inet = inet_sk(sk); | ||
74 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
75 | struct flowi6 fl6; | ||
76 | int err = 0; | ||
77 | |||
78 | if (np->sndflow && (np->flow_label & IPV6_FLOWLABEL_MASK)) { | ||
79 | flowlabel = fl6_sock_lookup(sk, np->flow_label); | ||
80 | if (!flowlabel) | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | ip6_datagram_flow_key_init(&fl6, sk); | ||
84 | |||
85 | rcu_read_lock(); | ||
86 | opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); | ||
87 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
88 | rcu_read_unlock(); | ||
89 | |||
90 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | ||
91 | if (IS_ERR(dst)) { | ||
92 | err = PTR_ERR(dst); | ||
93 | goto out; | ||
94 | } | ||
95 | |||
96 | if (fix_sk_saddr) { | ||
97 | if (ipv6_addr_any(&np->saddr)) | ||
98 | np->saddr = fl6.saddr; | ||
99 | |||
100 | if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { | ||
101 | sk->sk_v6_rcv_saddr = fl6.saddr; | ||
102 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | ||
103 | if (sk->sk_prot->rehash) | ||
104 | sk->sk_prot->rehash(sk); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | ip6_dst_store(sk, dst, | ||
109 | ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ? | ||
110 | &sk->sk_v6_daddr : NULL, | ||
111 | #ifdef CONFIG_IPV6_SUBTREES | ||
112 | ipv6_addr_equal(&fl6.saddr, &np->saddr) ? | ||
113 | &np->saddr : | ||
114 | #endif | ||
115 | NULL); | ||
116 | |||
117 | out: | ||
118 | fl6_sock_release(flowlabel); | ||
119 | return err; | ||
120 | } | ||
121 | |||
122 | void ip6_datagram_release_cb(struct sock *sk) | ||
123 | { | ||
124 | struct dst_entry *dst; | ||
125 | |||
126 | if (ipv6_addr_v4mapped(&sk->sk_v6_daddr)) | ||
127 | return; | ||
128 | |||
129 | rcu_read_lock(); | ||
130 | dst = __sk_dst_get(sk); | ||
131 | if (!dst || !dst->obsolete || | ||
132 | dst->ops->check(dst, inet6_sk(sk)->dst_cookie)) { | ||
133 | rcu_read_unlock(); | ||
134 | return; | ||
135 | } | ||
136 | rcu_read_unlock(); | ||
137 | |||
138 | ip6_datagram_dst_update(sk, false); | ||
139 | } | ||
140 | EXPORT_SYMBOL_GPL(ip6_datagram_release_cb); | ||
141 | |||
43 | static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 142 | static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
44 | { | 143 | { |
45 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 144 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
46 | struct inet_sock *inet = inet_sk(sk); | 145 | struct inet_sock *inet = inet_sk(sk); |
47 | struct ipv6_pinfo *np = inet6_sk(sk); | 146 | struct ipv6_pinfo *np = inet6_sk(sk); |
48 | struct in6_addr *daddr, *final_p, final; | 147 | struct in6_addr *daddr; |
49 | struct dst_entry *dst; | ||
50 | struct flowi6 fl6; | ||
51 | struct ip6_flowlabel *flowlabel = NULL; | ||
52 | struct ipv6_txoptions *opt; | ||
53 | int addr_type; | 148 | int addr_type; |
54 | int err; | 149 | int err; |
150 | __be32 fl6_flowlabel = 0; | ||
55 | 151 | ||
56 | if (usin->sin6_family == AF_INET) { | 152 | if (usin->sin6_family == AF_INET) { |
57 | if (__ipv6_only_sock(sk)) | 153 | if (__ipv6_only_sock(sk)) |
@@ -66,15 +162,8 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a | |||
66 | if (usin->sin6_family != AF_INET6) | 162 | if (usin->sin6_family != AF_INET6) |
67 | return -EAFNOSUPPORT; | 163 | return -EAFNOSUPPORT; |
68 | 164 | ||
69 | memset(&fl6, 0, sizeof(fl6)); | 165 | if (np->sndflow) |
70 | if (np->sndflow) { | 166 | fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; |
71 | fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; | ||
72 | if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { | ||
73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | ||
74 | if (!flowlabel) | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | } | ||
78 | 167 | ||
79 | addr_type = ipv6_addr_type(&usin->sin6_addr); | 168 | addr_type = ipv6_addr_type(&usin->sin6_addr); |
80 | 169 | ||
@@ -145,7 +234,7 @@ ipv4_connected: | |||
145 | } | 234 | } |
146 | 235 | ||
147 | sk->sk_v6_daddr = *daddr; | 236 | sk->sk_v6_daddr = *daddr; |
148 | np->flow_label = fl6.flowlabel; | 237 | np->flow_label = fl6_flowlabel; |
149 | 238 | ||
150 | inet->inet_dport = usin->sin6_port; | 239 | inet->inet_dport = usin->sin6_port; |
151 | 240 | ||
@@ -154,59 +243,13 @@ ipv4_connected: | |||
154 | * destination cache for it. | 243 | * destination cache for it. |
155 | */ | 244 | */ |
156 | 245 | ||
157 | fl6.flowi6_proto = sk->sk_protocol; | 246 | err = ip6_datagram_dst_update(sk, true); |
158 | fl6.daddr = sk->sk_v6_daddr; | 247 | if (err) |
159 | fl6.saddr = np->saddr; | ||
160 | fl6.flowi6_oif = sk->sk_bound_dev_if; | ||
161 | fl6.flowi6_mark = sk->sk_mark; | ||
162 | fl6.fl6_dport = inet->inet_dport; | ||
163 | fl6.fl6_sport = inet->inet_sport; | ||
164 | |||
165 | if (!fl6.flowi6_oif) | ||
166 | fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; | ||
167 | |||
168 | if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) | ||
169 | fl6.flowi6_oif = np->mcast_oif; | ||
170 | |||
171 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | ||
172 | |||
173 | rcu_read_lock(); | ||
174 | opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); | ||
175 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
176 | rcu_read_unlock(); | ||
177 | |||
178 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | ||
179 | err = 0; | ||
180 | if (IS_ERR(dst)) { | ||
181 | err = PTR_ERR(dst); | ||
182 | goto out; | 248 | goto out; |
183 | } | ||
184 | |||
185 | /* source address lookup done in ip6_dst_lookup */ | ||
186 | |||
187 | if (ipv6_addr_any(&np->saddr)) | ||
188 | np->saddr = fl6.saddr; | ||
189 | |||
190 | if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { | ||
191 | sk->sk_v6_rcv_saddr = fl6.saddr; | ||
192 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | ||
193 | if (sk->sk_prot->rehash) | ||
194 | sk->sk_prot->rehash(sk); | ||
195 | } | ||
196 | |||
197 | ip6_dst_store(sk, dst, | ||
198 | ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ? | ||
199 | &sk->sk_v6_daddr : NULL, | ||
200 | #ifdef CONFIG_IPV6_SUBTREES | ||
201 | ipv6_addr_equal(&fl6.saddr, &np->saddr) ? | ||
202 | &np->saddr : | ||
203 | #endif | ||
204 | NULL); | ||
205 | 249 | ||
206 | sk->sk_state = TCP_ESTABLISHED; | 250 | sk->sk_state = TCP_ESTABLISHED; |
207 | sk_set_txhash(sk); | 251 | sk_set_txhash(sk); |
208 | out: | 252 | out: |
209 | fl6_sock_release(flowlabel); | ||
210 | return err; | 253 | return err; |
211 | } | 254 | } |
212 | 255 | ||
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c index 2ae3c4fd8aab..41f18de5dcc2 100644 --- a/net/ipv6/ila/ila_lwt.c +++ b/net/ipv6/ila/ila_lwt.c | |||
@@ -120,8 +120,7 @@ nla_put_failure: | |||
120 | 120 | ||
121 | static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) | 121 | static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) |
122 | { | 122 | { |
123 | /* No encapsulation overhead */ | 123 | return nla_total_size(sizeof(u64)); /* ILA_ATTR_LOCATOR */ |
124 | return 0; | ||
125 | } | 124 | } |
126 | 125 | ||
127 | static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b) | 126 | static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b) |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 9428345d3a07..bc972e7152c7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1090,8 +1090,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1090 | int getfrag(void *from, char *to, int offset, int len, | 1090 | int getfrag(void *from, char *to, int offset, int len, |
1091 | int odd, struct sk_buff *skb), | 1091 | int odd, struct sk_buff *skb), |
1092 | void *from, int length, int hh_len, int fragheaderlen, | 1092 | void *from, int length, int hh_len, int fragheaderlen, |
1093 | int transhdrlen, int mtu, unsigned int flags, | 1093 | int exthdrlen, int transhdrlen, int mtu, |
1094 | const struct flowi6 *fl6) | 1094 | unsigned int flags, const struct flowi6 *fl6) |
1095 | 1095 | ||
1096 | { | 1096 | { |
1097 | struct sk_buff *skb; | 1097 | struct sk_buff *skb; |
@@ -1116,7 +1116,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1116 | skb_put(skb, fragheaderlen + transhdrlen); | 1116 | skb_put(skb, fragheaderlen + transhdrlen); |
1117 | 1117 | ||
1118 | /* initialize network header pointer */ | 1118 | /* initialize network header pointer */ |
1119 | skb_reset_network_header(skb); | 1119 | skb_set_network_header(skb, exthdrlen); |
1120 | 1120 | ||
1121 | /* initialize protocol header pointer */ | 1121 | /* initialize protocol header pointer */ |
1122 | skb->transport_header = skb->network_header + fragheaderlen; | 1122 | skb->transport_header = skb->network_header + fragheaderlen; |
@@ -1358,7 +1358,7 @@ emsgsize: | |||
1358 | (rt->dst.dev->features & NETIF_F_UFO) && | 1358 | (rt->dst.dev->features & NETIF_F_UFO) && |
1359 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { | 1359 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { |
1360 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, | 1360 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, |
1361 | hh_len, fragheaderlen, | 1361 | hh_len, fragheaderlen, exthdrlen, |
1362 | transhdrlen, mtu, flags, fl6); | 1362 | transhdrlen, mtu, flags, fl6); |
1363 | if (err) | 1363 | if (err) |
1364 | goto error; | 1364 | goto error; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index eb2ac4bb09ce..1f20345cbc97 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -252,12 +252,12 @@ static int ip6_tnl_create2(struct net_device *dev) | |||
252 | 252 | ||
253 | t = netdev_priv(dev); | 253 | t = netdev_priv(dev); |
254 | 254 | ||
255 | dev->rtnl_link_ops = &ip6_link_ops; | ||
255 | err = register_netdevice(dev); | 256 | err = register_netdevice(dev); |
256 | if (err < 0) | 257 | if (err < 0) |
257 | goto out; | 258 | goto out; |
258 | 259 | ||
259 | strcpy(t->parms.name, dev->name); | 260 | strcpy(t->parms.name, dev->name); |
260 | dev->rtnl_link_ops = &ip6_link_ops; | ||
261 | 261 | ||
262 | dev_hold(dev); | 262 | dev_hold(dev); |
263 | ip6_tnl_link(ip6n, t); | 263 | ip6_tnl_link(ip6n, t); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 84f9baf7aee8..86b67b70b626 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int offset) | |||
198 | 198 | ||
199 | /* All zeroes == unconditional rule. */ | 199 | /* All zeroes == unconditional rule. */ |
200 | /* Mildly perf critical (only if packet tracing is on) */ | 200 | /* Mildly perf critical (only if packet tracing is on) */ |
201 | static inline bool unconditional(const struct ip6t_ip6 *ipv6) | 201 | static inline bool unconditional(const struct ip6t_entry *e) |
202 | { | 202 | { |
203 | static const struct ip6t_ip6 uncond; | 203 | static const struct ip6t_ip6 uncond; |
204 | 204 | ||
205 | return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; | 205 | return e->target_offset == sizeof(struct ip6t_entry) && |
206 | memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; | ||
206 | } | 207 | } |
207 | 208 | ||
208 | static inline const struct xt_entry_target * | 209 | static inline const struct xt_entry_target * |
@@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, | |||
258 | } else if (s == e) { | 259 | } else if (s == e) { |
259 | (*rulenum)++; | 260 | (*rulenum)++; |
260 | 261 | ||
261 | if (s->target_offset == sizeof(struct ip6t_entry) && | 262 | if (unconditional(s) && |
262 | strcmp(t->target.u.kernel.target->name, | 263 | strcmp(t->target.u.kernel.target->name, |
263 | XT_STANDARD_TARGET) == 0 && | 264 | XT_STANDARD_TARGET) == 0 && |
264 | t->verdict < 0 && | 265 | t->verdict < 0) { |
265 | unconditional(&s->ipv6)) { | ||
266 | /* Tail of chains: STANDARD target (return/policy) */ | 266 | /* Tail of chains: STANDARD target (return/policy) */ |
267 | *comment = *chainname == hookname | 267 | *comment = *chainname == hookname |
268 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] | 268 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] |
@@ -488,11 +488,10 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
488 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 488 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
489 | 489 | ||
490 | /* Unconditional return/END. */ | 490 | /* Unconditional return/END. */ |
491 | if ((e->target_offset == sizeof(struct ip6t_entry) && | 491 | if ((unconditional(e) && |
492 | (strcmp(t->target.u.user.name, | 492 | (strcmp(t->target.u.user.name, |
493 | XT_STANDARD_TARGET) == 0) && | 493 | XT_STANDARD_TARGET) == 0) && |
494 | t->verdict < 0 && | 494 | t->verdict < 0) || visited) { |
495 | unconditional(&e->ipv6)) || visited) { | ||
496 | unsigned int oldpos, size; | 495 | unsigned int oldpos, size; |
497 | 496 | ||
498 | if ((strcmp(t->target.u.user.name, | 497 | if ((strcmp(t->target.u.user.name, |
@@ -581,14 +580,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) | |||
581 | } | 580 | } |
582 | 581 | ||
583 | static int | 582 | static int |
584 | check_entry(const struct ip6t_entry *e, const char *name) | 583 | check_entry(const struct ip6t_entry *e) |
585 | { | 584 | { |
586 | const struct xt_entry_target *t; | 585 | const struct xt_entry_target *t; |
587 | 586 | ||
588 | if (!ip6_checkentry(&e->ipv6)) { | 587 | if (!ip6_checkentry(&e->ipv6)) |
589 | duprintf("ip_tables: ip check failed %p %s.\n", e, name); | ||
590 | return -EINVAL; | 588 | return -EINVAL; |
591 | } | ||
592 | 589 | ||
593 | if (e->target_offset + sizeof(struct xt_entry_target) > | 590 | if (e->target_offset + sizeof(struct xt_entry_target) > |
594 | e->next_offset) | 591 | e->next_offset) |
@@ -679,10 +676,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, | |||
679 | struct xt_mtchk_param mtpar; | 676 | struct xt_mtchk_param mtpar; |
680 | struct xt_entry_match *ematch; | 677 | struct xt_entry_match *ematch; |
681 | 678 | ||
682 | ret = check_entry(e, name); | ||
683 | if (ret) | ||
684 | return ret; | ||
685 | |||
686 | e->counters.pcnt = xt_percpu_counter_alloc(); | 679 | e->counters.pcnt = xt_percpu_counter_alloc(); |
687 | if (IS_ERR_VALUE(e->counters.pcnt)) | 680 | if (IS_ERR_VALUE(e->counters.pcnt)) |
688 | return -ENOMEM; | 681 | return -ENOMEM; |
@@ -733,7 +726,7 @@ static bool check_underflow(const struct ip6t_entry *e) | |||
733 | const struct xt_entry_target *t; | 726 | const struct xt_entry_target *t; |
734 | unsigned int verdict; | 727 | unsigned int verdict; |
735 | 728 | ||
736 | if (!unconditional(&e->ipv6)) | 729 | if (!unconditional(e)) |
737 | return false; | 730 | return false; |
738 | t = ip6t_get_target_c(e); | 731 | t = ip6t_get_target_c(e); |
739 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 732 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -753,9 +746,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
753 | unsigned int valid_hooks) | 746 | unsigned int valid_hooks) |
754 | { | 747 | { |
755 | unsigned int h; | 748 | unsigned int h; |
749 | int err; | ||
756 | 750 | ||
757 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || | 751 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || |
758 | (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { | 752 | (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || |
753 | (unsigned char *)e + e->next_offset > limit) { | ||
759 | duprintf("Bad offset %p\n", e); | 754 | duprintf("Bad offset %p\n", e); |
760 | return -EINVAL; | 755 | return -EINVAL; |
761 | } | 756 | } |
@@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
767 | return -EINVAL; | 762 | return -EINVAL; |
768 | } | 763 | } |
769 | 764 | ||
765 | err = check_entry(e); | ||
766 | if (err) | ||
767 | return err; | ||
768 | |||
770 | /* Check hooks & underflows */ | 769 | /* Check hooks & underflows */ |
771 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { | 770 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { |
772 | if (!(valid_hooks & (1 << h))) | 771 | if (!(valid_hooks & (1 << h))) |
@@ -775,9 +774,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
775 | newinfo->hook_entry[h] = hook_entries[h]; | 774 | newinfo->hook_entry[h] = hook_entries[h]; |
776 | if ((unsigned char *)e - base == underflows[h]) { | 775 | if ((unsigned char *)e - base == underflows[h]) { |
777 | if (!check_underflow(e)) { | 776 | if (!check_underflow(e)) { |
778 | pr_err("Underflows must be unconditional and " | 777 | pr_debug("Underflows must be unconditional and " |
779 | "use the STANDARD target with " | 778 | "use the STANDARD target with " |
780 | "ACCEPT/DROP\n"); | 779 | "ACCEPT/DROP\n"); |
781 | return -EINVAL; | 780 | return -EINVAL; |
782 | } | 781 | } |
783 | newinfo->underflow[h] = underflows[h]; | 782 | newinfo->underflow[h] = underflows[h]; |
@@ -1169,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, | |||
1169 | *len, sizeof(get) + get.size); | 1168 | *len, sizeof(get) + get.size); |
1170 | return -EINVAL; | 1169 | return -EINVAL; |
1171 | } | 1170 | } |
1171 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1172 | 1172 | ||
1173 | t = xt_find_table_lock(net, AF_INET6, get.name); | 1173 | t = xt_find_table_lock(net, AF_INET6, get.name); |
1174 | if (!IS_ERR_OR_NULL(t)) { | 1174 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1505,7 +1505,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1505 | 1505 | ||
1506 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1506 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1507 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || | 1507 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || |
1508 | (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { | 1508 | (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || |
1509 | (unsigned char *)e + e->next_offset > limit) { | ||
1509 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1510 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1510 | return -EINVAL; | 1511 | return -EINVAL; |
1511 | } | 1512 | } |
@@ -1518,7 +1519,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1518 | } | 1519 | } |
1519 | 1520 | ||
1520 | /* For purposes of check_entry casting the compat entry is fine */ | 1521 | /* For purposes of check_entry casting the compat entry is fine */ |
1521 | ret = check_entry((struct ip6t_entry *)e, name); | 1522 | ret = check_entry((struct ip6t_entry *)e); |
1522 | if (ret) | 1523 | if (ret) |
1523 | return ret; | 1524 | return ret; |
1524 | 1525 | ||
@@ -1944,6 +1945,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, | |||
1944 | *len, sizeof(get) + get.size); | 1945 | *len, sizeof(get) + get.size); |
1945 | return -EINVAL; | 1946 | return -EINVAL; |
1946 | } | 1947 | } |
1948 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1947 | 1949 | ||
1948 | xt_compat_lock(AF_INET6); | 1950 | xt_compat_lock(AF_INET6); |
1949 | t = xt_find_table_lock(net, AF_INET6, get.name); | 1951 | t = xt_find_table_lock(net, AF_INET6, get.name); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ed446639219c..d916d6ab9ad2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -338,9 +338,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net, | |||
338 | return rt; | 338 | return rt; |
339 | } | 339 | } |
340 | 340 | ||
341 | static struct rt6_info *ip6_dst_alloc(struct net *net, | 341 | struct rt6_info *ip6_dst_alloc(struct net *net, |
342 | struct net_device *dev, | 342 | struct net_device *dev, |
343 | int flags) | 343 | int flags) |
344 | { | 344 | { |
345 | struct rt6_info *rt = __ip6_dst_alloc(net, dev, flags); | 345 | struct rt6_info *rt = __ip6_dst_alloc(net, dev, flags); |
346 | 346 | ||
@@ -364,6 +364,7 @@ static struct rt6_info *ip6_dst_alloc(struct net *net, | |||
364 | 364 | ||
365 | return rt; | 365 | return rt; |
366 | } | 366 | } |
367 | EXPORT_SYMBOL(ip6_dst_alloc); | ||
367 | 368 | ||
368 | static void ip6_dst_destroy(struct dst_entry *dst) | 369 | static void ip6_dst_destroy(struct dst_entry *dst) |
369 | { | 370 | { |
@@ -1417,8 +1418,20 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu); | |||
1417 | 1418 | ||
1418 | void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) | 1419 | void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) |
1419 | { | 1420 | { |
1421 | struct dst_entry *dst; | ||
1422 | |||
1420 | ip6_update_pmtu(skb, sock_net(sk), mtu, | 1423 | ip6_update_pmtu(skb, sock_net(sk), mtu, |
1421 | sk->sk_bound_dev_if, sk->sk_mark); | 1424 | sk->sk_bound_dev_if, sk->sk_mark); |
1425 | |||
1426 | dst = __sk_dst_get(sk); | ||
1427 | if (!dst || !dst->obsolete || | ||
1428 | dst->ops->check(dst, inet6_sk(sk)->dst_cookie)) | ||
1429 | return; | ||
1430 | |||
1431 | bh_lock_sock(sk); | ||
1432 | if (!sock_owned_by_user(sk) && !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) | ||
1433 | ip6_datagram_dst_update(sk, false); | ||
1434 | bh_unlock_sock(sk); | ||
1422 | } | 1435 | } |
1423 | EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); | 1436 | EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); |
1424 | 1437 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fd25e447a5fa..6bc5c664fa46 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -843,8 +843,8 @@ start_lookup: | |||
843 | flush_stack(stack, count, skb, count - 1); | 843 | flush_stack(stack, count, skb, count - 1); |
844 | } else { | 844 | } else { |
845 | if (!inner_flushed) | 845 | if (!inner_flushed) |
846 | UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, | 846 | UDP6_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, |
847 | proto == IPPROTO_UDPLITE); | 847 | proto == IPPROTO_UDPLITE); |
848 | consume_skb(skb); | 848 | consume_skb(skb); |
849 | } | 849 | } |
850 | return 0; | 850 | return 0; |
@@ -1539,6 +1539,7 @@ struct proto udpv6_prot = { | |||
1539 | .sendmsg = udpv6_sendmsg, | 1539 | .sendmsg = udpv6_sendmsg, |
1540 | .recvmsg = udpv6_recvmsg, | 1540 | .recvmsg = udpv6_recvmsg, |
1541 | .backlog_rcv = __udpv6_queue_rcv_skb, | 1541 | .backlog_rcv = __udpv6_queue_rcv_skb, |
1542 | .release_cb = ip6_datagram_release_cb, | ||
1542 | .hash = udp_lib_hash, | 1543 | .hash = udp_lib_hash, |
1543 | .unhash = udp_lib_unhash, | 1544 | .unhash = udp_lib_unhash, |
1544 | .rehash = udp_v6_rehash, | 1545 | .rehash = udp_v6_rehash, |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index afca2eb4dfa7..6edfa9980314 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1376,9 +1376,9 @@ static int l2tp_tunnel_sock_create(struct net *net, | |||
1376 | memcpy(&udp_conf.peer_ip6, cfg->peer_ip6, | 1376 | memcpy(&udp_conf.peer_ip6, cfg->peer_ip6, |
1377 | sizeof(udp_conf.peer_ip6)); | 1377 | sizeof(udp_conf.peer_ip6)); |
1378 | udp_conf.use_udp6_tx_checksums = | 1378 | udp_conf.use_udp6_tx_checksums = |
1379 | cfg->udp6_zero_tx_checksums; | 1379 | ! cfg->udp6_zero_tx_checksums; |
1380 | udp_conf.use_udp6_rx_checksums = | 1380 | udp_conf.use_udp6_rx_checksums = |
1381 | cfg->udp6_zero_rx_checksums; | 1381 | ! cfg->udp6_zero_rx_checksums; |
1382 | } else | 1382 | } else |
1383 | #endif | 1383 | #endif |
1384 | { | 1384 | { |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index ec22078b0914..42de4ccd159f 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *skb) | |||
123 | struct l2tp_tunnel *tunnel = NULL; | 123 | struct l2tp_tunnel *tunnel = NULL; |
124 | int length; | 124 | int length; |
125 | 125 | ||
126 | /* Point to L2TP header */ | ||
127 | optr = ptr = skb->data; | ||
128 | |||
129 | if (!pskb_may_pull(skb, 4)) | 126 | if (!pskb_may_pull(skb, 4)) |
130 | goto discard; | 127 | goto discard; |
131 | 128 | ||
129 | /* Point to L2TP header */ | ||
130 | optr = ptr = skb->data; | ||
132 | session_id = ntohl(*((__be32 *) ptr)); | 131 | session_id = ntohl(*((__be32 *) ptr)); |
133 | ptr += 4; | 132 | ptr += 4; |
134 | 133 | ||
@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *skb) | |||
156 | if (!pskb_may_pull(skb, length)) | 155 | if (!pskb_may_pull(skb, length)) |
157 | goto discard; | 156 | goto discard; |
158 | 157 | ||
158 | /* Point to L2TP header */ | ||
159 | optr = ptr = skb->data; | ||
160 | ptr += 4; | ||
159 | pr_debug("%s: ip recv\n", tunnel->name); | 161 | pr_debug("%s: ip recv\n", tunnel->name); |
160 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); | 162 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
161 | } | 163 | } |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 6b54ff3ff4cb..cd479903d943 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -136,12 +136,11 @@ static int l2tp_ip6_recv(struct sk_buff *skb) | |||
136 | struct l2tp_tunnel *tunnel = NULL; | 136 | struct l2tp_tunnel *tunnel = NULL; |
137 | int length; | 137 | int length; |
138 | 138 | ||
139 | /* Point to L2TP header */ | ||
140 | optr = ptr = skb->data; | ||
141 | |||
142 | if (!pskb_may_pull(skb, 4)) | 139 | if (!pskb_may_pull(skb, 4)) |
143 | goto discard; | 140 | goto discard; |
144 | 141 | ||
142 | /* Point to L2TP header */ | ||
143 | optr = ptr = skb->data; | ||
145 | session_id = ntohl(*((__be32 *) ptr)); | 144 | session_id = ntohl(*((__be32 *) ptr)); |
146 | ptr += 4; | 145 | ptr += 4; |
147 | 146 | ||
@@ -169,6 +168,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb) | |||
169 | if (!pskb_may_pull(skb, length)) | 168 | if (!pskb_may_pull(skb, length)) |
170 | goto discard; | 169 | goto discard; |
171 | 170 | ||
171 | /* Point to L2TP header */ | ||
172 | optr = ptr = skb->data; | ||
173 | ptr += 4; | ||
172 | pr_debug("%s: ip recv\n", tunnel->name); | 174 | pr_debug("%s: ip recv\n", tunnel->name); |
173 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); | 175 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
174 | } | 176 | } |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 283981108ca8..74142d07ad31 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -343,8 +343,10 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local, | |||
343 | struct ieee80211_chanctx *ctx, | 343 | struct ieee80211_chanctx *ctx, |
344 | const struct cfg80211_chan_def *chandef) | 344 | const struct cfg80211_chan_def *chandef) |
345 | { | 345 | { |
346 | if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) | 346 | if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) { |
347 | ieee80211_recalc_chanctx_min_def(local, ctx); | ||
347 | return; | 348 | return; |
349 | } | ||
348 | 350 | ||
349 | WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); | 351 | WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); |
350 | 352 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 804575ff7af5..422003540169 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1719,6 +1719,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
1719 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta); | 1719 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta); |
1720 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); | 1720 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); |
1721 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | 1721 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); |
1722 | enum ieee80211_sta_rx_bandwidth | ||
1723 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width); | ||
1724 | enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta); | ||
1725 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | ||
1722 | void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, | 1726 | void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, |
1723 | struct ieee80211_mgmt *mgmt); | 1727 | struct ieee80211_mgmt *mgmt); |
1724 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 1728 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 453b4e741780..e1cb22c16530 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1761,7 +1761,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1761 | 1761 | ||
1762 | ret = dev_alloc_name(ndev, ndev->name); | 1762 | ret = dev_alloc_name(ndev, ndev->name); |
1763 | if (ret < 0) { | 1763 | if (ret < 0) { |
1764 | free_netdev(ndev); | 1764 | ieee80211_if_free(ndev); |
1765 | return ret; | 1765 | return ret; |
1766 | } | 1766 | } |
1767 | 1767 | ||
@@ -1847,7 +1847,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1847 | 1847 | ||
1848 | ret = register_netdevice(ndev); | 1848 | ret = register_netdevice(ndev); |
1849 | if (ret) { | 1849 | if (ret) { |
1850 | free_netdev(ndev); | 1850 | ieee80211_if_free(ndev); |
1851 | return ret; | 1851 | return ret; |
1852 | } | 1852 | } |
1853 | } | 1853 | } |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 5b6aec1a0630..002244bca948 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -530,7 +530,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
530 | const u8 *target_addr, *orig_addr; | 530 | const u8 *target_addr, *orig_addr; |
531 | const u8 *da; | 531 | const u8 *da; |
532 | u8 target_flags, ttl, flags; | 532 | u8 target_flags, ttl, flags; |
533 | u32 orig_sn, target_sn, lifetime, target_metric; | 533 | u32 orig_sn, target_sn, lifetime, target_metric = 0; |
534 | bool reply = false; | 534 | bool reply = false; |
535 | bool forward = true; | 535 | bool forward = true; |
536 | bool root_is_gate; | 536 | bool root_is_gate; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d20bab5c146c..861b93ffbe92 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -67,6 +67,7 @@ | |||
67 | 67 | ||
68 | static const struct rhashtable_params sta_rht_params = { | 68 | static const struct rhashtable_params sta_rht_params = { |
69 | .nelem_hint = 3, /* start small */ | 69 | .nelem_hint = 3, /* start small */ |
70 | .insecure_elasticity = true, /* Disable chain-length checks. */ | ||
70 | .automatic_shrinking = true, | 71 | .automatic_shrinking = true, |
71 | .head_offset = offsetof(struct sta_info, hash_node), | 72 | .head_offset = offsetof(struct sta_info, hash_node), |
72 | .key_offset = offsetof(struct sta_info, addr), | 73 | .key_offset = offsetof(struct sta_info, addr), |
@@ -258,11 +259,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | |||
258 | } | 259 | } |
259 | 260 | ||
260 | /* Caller must hold local->sta_mtx */ | 261 | /* Caller must hold local->sta_mtx */ |
261 | static void sta_info_hash_add(struct ieee80211_local *local, | 262 | static int sta_info_hash_add(struct ieee80211_local *local, |
262 | struct sta_info *sta) | 263 | struct sta_info *sta) |
263 | { | 264 | { |
264 | rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, | 265 | return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, |
265 | sta_rht_params); | 266 | sta_rht_params); |
266 | } | 267 | } |
267 | 268 | ||
268 | static void sta_deliver_ps_frames(struct work_struct *wk) | 269 | static void sta_deliver_ps_frames(struct work_struct *wk) |
@@ -524,7 +525,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
524 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | 525 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
525 | 526 | ||
526 | /* make the station visible */ | 527 | /* make the station visible */ |
527 | sta_info_hash_add(local, sta); | 528 | err = sta_info_hash_add(local, sta); |
529 | if (err) | ||
530 | goto out_drop_sta; | ||
528 | 531 | ||
529 | list_add_tail_rcu(&sta->list, &local->sta_list); | 532 | list_add_tail_rcu(&sta->list, &local->sta_list); |
530 | 533 | ||
@@ -557,6 +560,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
557 | out_remove: | 560 | out_remove: |
558 | sta_info_hash_del(local, sta); | 561 | sta_info_hash_del(local, sta); |
559 | list_del_rcu(&sta->list); | 562 | list_del_rcu(&sta->list); |
563 | out_drop_sta: | ||
560 | local->num_sta--; | 564 | local->num_sta--; |
561 | synchronize_net(); | 565 | synchronize_net(); |
562 | __cleanup_single_sta(sta); | 566 | __cleanup_single_sta(sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 053f5c4fa495..62193f4bc37b 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -377,7 +377,6 @@ DECLARE_EWMA(signal, 1024, 8) | |||
377 | * @uploaded: set to true when sta is uploaded to the driver | 377 | * @uploaded: set to true when sta is uploaded to the driver |
378 | * @sta: station information we share with the driver | 378 | * @sta: station information we share with the driver |
379 | * @sta_state: duplicates information about station state (for debug) | 379 | * @sta_state: duplicates information about station state (for debug) |
380 | * @beacon_loss_count: number of times beacon loss has triggered | ||
381 | * @rcu_head: RCU head used for freeing this station struct | 380 | * @rcu_head: RCU head used for freeing this station struct |
382 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, | 381 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, |
383 | * taken from HT/VHT capabilities or VHT operating mode notification | 382 | * taken from HT/VHT capabilities or VHT operating mode notification |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index c9eeb3f12808..a29ea813b7d5 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2014, Intel Corporation | 5 | * Copyright 2014, Intel Corporation |
6 | * Copyright 2014 Intel Mobile Communications GmbH | 6 | * Copyright 2014 Intel Mobile Communications GmbH |
7 | * Copyright 2015 Intel Deutschland GmbH | 7 | * Copyright 2015 - 2016 Intel Deutschland GmbH |
8 | * | 8 | * |
9 | * This file is GPLv2 as found in COPYING. | 9 | * This file is GPLv2 as found in COPYING. |
10 | */ | 10 | */ |
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/rtnetlink.h> | 15 | #include <linux/rtnetlink.h> |
16 | #include "ieee80211_i.h" | 16 | #include "ieee80211_i.h" |
17 | #include "driver-ops.h" | 17 | #include "driver-ops.h" |
18 | #include "rate.h" | ||
18 | 19 | ||
19 | /* give usermode some time for retries in setting up the TDLS session */ | 20 | /* give usermode some time for retries in setting up the TDLS session */ |
20 | #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) | 21 | #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) |
@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
302 | /* IEEE802.11ac-2013 Table E-4 */ | 303 | /* IEEE802.11ac-2013 Table E-4 */ |
303 | u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 }; | 304 | u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 }; |
304 | struct cfg80211_chan_def uc = sta->tdls_chandef; | 305 | struct cfg80211_chan_def uc = sta->tdls_chandef; |
305 | enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta); | 306 | enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta); |
306 | int i; | 307 | int i; |
307 | 308 | ||
308 | /* only support upgrading non-narrow channels up to 80Mhz */ | 309 | /* only support upgrading non-narrow channels up to 80Mhz */ |
@@ -313,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
313 | if (max_width > NL80211_CHAN_WIDTH_80) | 314 | if (max_width > NL80211_CHAN_WIDTH_80) |
314 | max_width = NL80211_CHAN_WIDTH_80; | 315 | max_width = NL80211_CHAN_WIDTH_80; |
315 | 316 | ||
316 | if (uc.width == max_width) | 317 | if (uc.width >= max_width) |
317 | return; | 318 | return; |
318 | /* | 319 | /* |
319 | * Channel usage constrains in the IEEE802.11ac-2013 specification only | 320 | * Channel usage constrains in the IEEE802.11ac-2013 specification only |
@@ -324,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
324 | for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++) | 325 | for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++) |
325 | if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) { | 326 | if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) { |
326 | uc.center_freq1 = centers_80mhz[i]; | 327 | uc.center_freq1 = centers_80mhz[i]; |
328 | uc.center_freq2 = 0; | ||
327 | uc.width = NL80211_CHAN_WIDTH_80; | 329 | uc.width = NL80211_CHAN_WIDTH_80; |
328 | break; | 330 | break; |
329 | } | 331 | } |
@@ -332,7 +334,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
332 | return; | 334 | return; |
333 | 335 | ||
334 | /* proceed to downgrade the chandef until usable or the same */ | 336 | /* proceed to downgrade the chandef until usable or the same */ |
335 | while (uc.width > max_width && | 337 | while (uc.width > max_width || |
336 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, | 338 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, |
337 | sdata->wdev.iftype)) | 339 | sdata->wdev.iftype)) |
338 | ieee80211_chandef_downgrade(&uc); | 340 | ieee80211_chandef_downgrade(&uc); |
@@ -1242,18 +1244,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1242 | return ret; | 1244 | return ret; |
1243 | } | 1245 | } |
1244 | 1246 | ||
1245 | static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata) | 1247 | static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata, |
1248 | struct sta_info *sta) | ||
1246 | { | 1249 | { |
1247 | struct ieee80211_local *local = sdata->local; | 1250 | struct ieee80211_local *local = sdata->local; |
1248 | struct ieee80211_chanctx_conf *conf; | 1251 | struct ieee80211_chanctx_conf *conf; |
1249 | struct ieee80211_chanctx *ctx; | 1252 | struct ieee80211_chanctx *ctx; |
1253 | enum nl80211_chan_width width; | ||
1254 | struct ieee80211_supported_band *sband; | ||
1250 | 1255 | ||
1251 | mutex_lock(&local->chanctx_mtx); | 1256 | mutex_lock(&local->chanctx_mtx); |
1252 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | 1257 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
1253 | lockdep_is_held(&local->chanctx_mtx)); | 1258 | lockdep_is_held(&local->chanctx_mtx)); |
1254 | if (conf) { | 1259 | if (conf) { |
1260 | width = conf->def.width; | ||
1261 | sband = local->hw.wiphy->bands[conf->def.chan->band]; | ||
1255 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | 1262 | ctx = container_of(conf, struct ieee80211_chanctx, conf); |
1256 | ieee80211_recalc_chanctx_chantype(local, ctx); | 1263 | ieee80211_recalc_chanctx_chantype(local, ctx); |
1264 | |||
1265 | /* if width changed and a peer is given, update its BW */ | ||
1266 | if (width != conf->def.width && sta && | ||
1267 | test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) { | ||
1268 | enum ieee80211_sta_rx_bandwidth bw; | ||
1269 | |||
1270 | bw = ieee80211_chan_width_to_rx_bw(conf->def.width); | ||
1271 | bw = min(bw, ieee80211_sta_cap_rx_bw(sta)); | ||
1272 | if (bw != sta->sta.bandwidth) { | ||
1273 | sta->sta.bandwidth = bw; | ||
1274 | rate_control_rate_update(local, sband, sta, | ||
1275 | IEEE80211_RC_BW_CHANGED); | ||
1276 | /* | ||
1277 | * if a TDLS peer BW was updated, we need to | ||
1278 | * recalc the chandef width again, to get the | ||
1279 | * correct chanctx min_def | ||
1280 | */ | ||
1281 | ieee80211_recalc_chanctx_chantype(local, ctx); | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1257 | } | 1285 | } |
1258 | mutex_unlock(&local->chanctx_mtx); | 1286 | mutex_unlock(&local->chanctx_mtx); |
1259 | } | 1287 | } |
@@ -1350,8 +1378,6 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1350 | break; | 1378 | break; |
1351 | } | 1379 | } |
1352 | 1380 | ||
1353 | iee80211_tdls_recalc_chanctx(sdata); | ||
1354 | |||
1355 | mutex_lock(&local->sta_mtx); | 1381 | mutex_lock(&local->sta_mtx); |
1356 | sta = sta_info_get(sdata, peer); | 1382 | sta = sta_info_get(sdata, peer); |
1357 | if (!sta) { | 1383 | if (!sta) { |
@@ -1360,6 +1386,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1360 | break; | 1386 | break; |
1361 | } | 1387 | } |
1362 | 1388 | ||
1389 | iee80211_tdls_recalc_chanctx(sdata, sta); | ||
1363 | iee80211_tdls_recalc_ht_protection(sdata, sta); | 1390 | iee80211_tdls_recalc_ht_protection(sdata, sta); |
1364 | 1391 | ||
1365 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); | 1392 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); |
@@ -1390,7 +1417,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1390 | iee80211_tdls_recalc_ht_protection(sdata, NULL); | 1417 | iee80211_tdls_recalc_ht_protection(sdata, NULL); |
1391 | mutex_unlock(&local->sta_mtx); | 1418 | mutex_unlock(&local->sta_mtx); |
1392 | 1419 | ||
1393 | iee80211_tdls_recalc_chanctx(sdata); | 1420 | iee80211_tdls_recalc_chanctx(sdata, NULL); |
1394 | break; | 1421 | break; |
1395 | default: | 1422 | default: |
1396 | ret = -ENOTSUPP; | 1423 | ret = -ENOTSUPP; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 62ad5321257d..21f6602395f7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1116,11 +1116,15 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1116 | reset_agg_timer = true; | 1116 | reset_agg_timer = true; |
1117 | } else { | 1117 | } else { |
1118 | queued = true; | 1118 | queued = true; |
1119 | if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) { | ||
1120 | clear_sta_flag(tx->sta, WLAN_STA_SP); | ||
1121 | ps_dbg(tx->sta->sdata, | ||
1122 | "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n", | ||
1123 | tx->sta->sta.addr, tx->sta->sta.aid); | ||
1124 | } | ||
1119 | info->control.vif = &tx->sdata->vif; | 1125 | info->control.vif = &tx->sdata->vif; |
1120 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1126 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1121 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS | | 1127 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; |
1122 | IEEE80211_TX_CTL_NO_PS_BUFFER | | ||
1123 | IEEE80211_TX_STATUS_EOSP; | ||
1124 | __skb_queue_tail(&tid_tx->pending, skb); | 1128 | __skb_queue_tail(&tid_tx->pending, skb); |
1125 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) | 1129 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) |
1126 | purge_skb = __skb_dequeue(&tid_tx->pending); | 1130 | purge_skb = __skb_dequeue(&tid_tx->pending); |
@@ -1247,7 +1251,8 @@ static void ieee80211_drv_tx(struct ieee80211_local *local, | |||
1247 | struct txq_info *txqi; | 1251 | struct txq_info *txqi; |
1248 | u8 ac; | 1252 | u8 ac; |
1249 | 1253 | ||
1250 | if (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE) | 1254 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || |
1255 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
1251 | goto tx_normal; | 1256 | goto tx_normal; |
1252 | 1257 | ||
1253 | if (!ieee80211_is_data(hdr->frame_control)) | 1258 | if (!ieee80211_is_data(hdr->frame_control)) |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 89e04d55aa18..e590e2ef9eaf 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -319,7 +319,30 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) | |||
319 | return IEEE80211_STA_RX_BW_80; | 319 | return IEEE80211_STA_RX_BW_80; |
320 | } | 320 | } |
321 | 321 | ||
322 | static enum ieee80211_sta_rx_bandwidth | 322 | enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta) |
323 | { | ||
324 | struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; | ||
325 | u32 cap_width; | ||
326 | |||
327 | if (!vht_cap->vht_supported) { | ||
328 | if (!sta->sta.ht_cap.ht_supported) | ||
329 | return NL80211_CHAN_WIDTH_20_NOHT; | ||
330 | |||
331 | return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | ||
332 | NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20; | ||
333 | } | ||
334 | |||
335 | cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; | ||
336 | |||
337 | if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) | ||
338 | return NL80211_CHAN_WIDTH_160; | ||
339 | else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) | ||
340 | return NL80211_CHAN_WIDTH_80P80; | ||
341 | |||
342 | return NL80211_CHAN_WIDTH_80; | ||
343 | } | ||
344 | |||
345 | enum ieee80211_sta_rx_bandwidth | ||
323 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) | 346 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) |
324 | { | 347 | { |
325 | switch (width) { | 348 | switch (width) { |
@@ -347,10 +370,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) | |||
347 | 370 | ||
348 | bw = ieee80211_sta_cap_rx_bw(sta); | 371 | bw = ieee80211_sta_cap_rx_bw(sta); |
349 | bw = min(bw, sta->cur_max_bandwidth); | 372 | bw = min(bw, sta->cur_max_bandwidth); |
350 | 373 | bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width)); | |
351 | /* do not cap the BW of TDLS WIDER_BW peers by the bss */ | ||
352 | if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) | ||
353 | bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width)); | ||
354 | 374 | ||
355 | return bw; | 375 | return bw; |
356 | } | 376 | } |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index b18c5ed42d95..0b80a7140cc4 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -543,6 +543,9 @@ static struct net_device *find_outdev(struct net *net, | |||
543 | if (!dev) | 543 | if (!dev) |
544 | return ERR_PTR(-ENODEV); | 544 | return ERR_PTR(-ENODEV); |
545 | 545 | ||
546 | if (IS_ERR(dev)) | ||
547 | return dev; | ||
548 | |||
546 | /* The caller is holding rtnl anyways, so release the dev reference */ | 549 | /* The caller is holding rtnl anyways, so release the dev reference */ |
547 | dev_put(dev); | 550 | dev_put(dev); |
548 | 551 | ||
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h index b0bc475f641e..2e8e7e5fb4a6 100644 --- a/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/net/netfilter/ipset/ip_set_bitmap_gen.h | |||
@@ -95,7 +95,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) | |||
95 | if (!nested) | 95 | if (!nested) |
96 | goto nla_put_failure; | 96 | goto nla_put_failure; |
97 | if (mtype_do_head(skb, map) || | 97 | if (mtype_do_head(skb, map) || |
98 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 98 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
99 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) | 99 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) |
100 | goto nla_put_failure; | 100 | goto nla_put_failure; |
101 | if (unlikely(ip_set_put_flags(skb, set))) | 101 | if (unlikely(ip_set_put_flags(skb, set))) |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 7e6568cad494..a748b0c2c981 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -497,6 +497,26 @@ __ip_set_put(struct ip_set *set) | |||
497 | write_unlock_bh(&ip_set_ref_lock); | 497 | write_unlock_bh(&ip_set_ref_lock); |
498 | } | 498 | } |
499 | 499 | ||
500 | /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need | ||
501 | * a separate reference counter | ||
502 | */ | ||
503 | static inline void | ||
504 | __ip_set_get_netlink(struct ip_set *set) | ||
505 | { | ||
506 | write_lock_bh(&ip_set_ref_lock); | ||
507 | set->ref_netlink++; | ||
508 | write_unlock_bh(&ip_set_ref_lock); | ||
509 | } | ||
510 | |||
511 | static inline void | ||
512 | __ip_set_put_netlink(struct ip_set *set) | ||
513 | { | ||
514 | write_lock_bh(&ip_set_ref_lock); | ||
515 | BUG_ON(set->ref_netlink == 0); | ||
516 | set->ref_netlink--; | ||
517 | write_unlock_bh(&ip_set_ref_lock); | ||
518 | } | ||
519 | |||
500 | /* Add, del and test set entries from kernel. | 520 | /* Add, del and test set entries from kernel. |
501 | * | 521 | * |
502 | * The set behind the index must exist and must be referenced | 522 | * The set behind the index must exist and must be referenced |
@@ -1002,7 +1022,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, | |||
1002 | if (!attr[IPSET_ATTR_SETNAME]) { | 1022 | if (!attr[IPSET_ATTR_SETNAME]) { |
1003 | for (i = 0; i < inst->ip_set_max; i++) { | 1023 | for (i = 0; i < inst->ip_set_max; i++) { |
1004 | s = ip_set(inst, i); | 1024 | s = ip_set(inst, i); |
1005 | if (s && s->ref) { | 1025 | if (s && (s->ref || s->ref_netlink)) { |
1006 | ret = -IPSET_ERR_BUSY; | 1026 | ret = -IPSET_ERR_BUSY; |
1007 | goto out; | 1027 | goto out; |
1008 | } | 1028 | } |
@@ -1024,7 +1044,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, | |||
1024 | if (!s) { | 1044 | if (!s) { |
1025 | ret = -ENOENT; | 1045 | ret = -ENOENT; |
1026 | goto out; | 1046 | goto out; |
1027 | } else if (s->ref) { | 1047 | } else if (s->ref || s->ref_netlink) { |
1028 | ret = -IPSET_ERR_BUSY; | 1048 | ret = -IPSET_ERR_BUSY; |
1029 | goto out; | 1049 | goto out; |
1030 | } | 1050 | } |
@@ -1171,6 +1191,9 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb, | |||
1171 | from->family == to->family)) | 1191 | from->family == to->family)) |
1172 | return -IPSET_ERR_TYPE_MISMATCH; | 1192 | return -IPSET_ERR_TYPE_MISMATCH; |
1173 | 1193 | ||
1194 | if (from->ref_netlink || to->ref_netlink) | ||
1195 | return -EBUSY; | ||
1196 | |||
1174 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); | 1197 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); |
1175 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); | 1198 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); |
1176 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); | 1199 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); |
@@ -1206,7 +1229,7 @@ ip_set_dump_done(struct netlink_callback *cb) | |||
1206 | if (set->variant->uref) | 1229 | if (set->variant->uref) |
1207 | set->variant->uref(set, cb, false); | 1230 | set->variant->uref(set, cb, false); |
1208 | pr_debug("release set %s\n", set->name); | 1231 | pr_debug("release set %s\n", set->name); |
1209 | __ip_set_put_byindex(inst, index); | 1232 | __ip_set_put_netlink(set); |
1210 | } | 1233 | } |
1211 | return 0; | 1234 | return 0; |
1212 | } | 1235 | } |
@@ -1328,7 +1351,7 @@ dump_last: | |||
1328 | if (!cb->args[IPSET_CB_ARG0]) { | 1351 | if (!cb->args[IPSET_CB_ARG0]) { |
1329 | /* Start listing: make sure set won't be destroyed */ | 1352 | /* Start listing: make sure set won't be destroyed */ |
1330 | pr_debug("reference set\n"); | 1353 | pr_debug("reference set\n"); |
1331 | set->ref++; | 1354 | set->ref_netlink++; |
1332 | } | 1355 | } |
1333 | write_unlock_bh(&ip_set_ref_lock); | 1356 | write_unlock_bh(&ip_set_ref_lock); |
1334 | nlh = start_msg(skb, NETLINK_CB(cb->skb).portid, | 1357 | nlh = start_msg(skb, NETLINK_CB(cb->skb).portid, |
@@ -1396,7 +1419,7 @@ release_refcount: | |||
1396 | if (set->variant->uref) | 1419 | if (set->variant->uref) |
1397 | set->variant->uref(set, cb, false); | 1420 | set->variant->uref(set, cb, false); |
1398 | pr_debug("release set %s\n", set->name); | 1421 | pr_debug("release set %s\n", set->name); |
1399 | __ip_set_put_byindex(inst, index); | 1422 | __ip_set_put_netlink(set); |
1400 | cb->args[IPSET_CB_ARG0] = 0; | 1423 | cb->args[IPSET_CB_ARG0] = 0; |
1401 | } | 1424 | } |
1402 | out: | 1425 | out: |
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index e5336ab36d67..d32fd6b036bf 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h | |||
@@ -1082,7 +1082,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) | |||
1082 | if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask)) | 1082 | if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask)) |
1083 | goto nla_put_failure; | 1083 | goto nla_put_failure; |
1084 | #endif | 1084 | #endif |
1085 | if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 1085 | if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
1086 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) | 1086 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) |
1087 | goto nla_put_failure; | 1087 | goto nla_put_failure; |
1088 | if (unlikely(ip_set_put_flags(skb, set))) | 1088 | if (unlikely(ip_set_put_flags(skb, set))) |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 24c6c1962aea..a2a89e4e0a14 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
@@ -458,7 +458,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb) | |||
458 | if (!nested) | 458 | if (!nested) |
459 | goto nla_put_failure; | 459 | goto nla_put_failure; |
460 | if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || | 460 | if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || |
461 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 461 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
462 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, | 462 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, |
463 | htonl(sizeof(*map) + n * set->dsize))) | 463 | htonl(sizeof(*map) + n * set->dsize))) |
464 | goto nla_put_failure; | 464 | goto nla_put_failure; |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 278f3b9356ef..7cc1d9c22a9f 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -410,6 +410,8 @@ static void tcp_options(const struct sk_buff *skb, | |||
410 | length--; | 410 | length--; |
411 | continue; | 411 | continue; |
412 | default: | 412 | default: |
413 | if (length < 2) | ||
414 | return; | ||
413 | opsize=*ptr++; | 415 | opsize=*ptr++; |
414 | if (opsize < 2) /* "silly options" */ | 416 | if (opsize < 2) /* "silly options" */ |
415 | return; | 417 | return; |
@@ -470,6 +472,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, | |||
470 | length--; | 472 | length--; |
471 | continue; | 473 | continue; |
472 | default: | 474 | default: |
475 | if (length < 2) | ||
476 | return; | ||
473 | opsize = *ptr++; | 477 | opsize = *ptr++; |
474 | if (opsize < 2) /* "silly options" */ | 478 | if (opsize < 2) /* "silly options" */ |
475 | return; | 479 | return; |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 75429997ed41..cb5b630a645b 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -582,7 +582,12 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue, | |||
582 | /* nfnetlink_unicast will either free the nskb or add it to a socket */ | 582 | /* nfnetlink_unicast will either free the nskb or add it to a socket */ |
583 | err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT); | 583 | err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT); |
584 | if (err < 0) { | 584 | if (err < 0) { |
585 | queue->queue_user_dropped++; | 585 | if (queue->flags & NFQA_CFG_F_FAIL_OPEN) { |
586 | failopen = 1; | ||
587 | err = 0; | ||
588 | } else { | ||
589 | queue->queue_user_dropped++; | ||
590 | } | ||
586 | goto err_out_unlock; | 591 | goto err_out_unlock; |
587 | } | 592 | } |
588 | 593 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 215fc08c02ab..330ebd600f25 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -688,7 +688,7 @@ static int netlink_release(struct socket *sock) | |||
688 | 688 | ||
689 | skb_queue_purge(&sk->sk_write_queue); | 689 | skb_queue_purge(&sk->sk_write_queue); |
690 | 690 | ||
691 | if (nlk->portid) { | 691 | if (nlk->portid && nlk->bound) { |
692 | struct netlink_notify n = { | 692 | struct netlink_notify n = { |
693 | .net = sock_net(sk), | 693 | .net = sock_net(sk), |
694 | .protocol = sk->sk_protocol, | 694 | .protocol = sk->sk_protocol, |
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 234a73344c6e..ce947292ae77 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig | |||
@@ -7,7 +7,9 @@ config OPENVSWITCH | |||
7 | depends on INET | 7 | depends on INET |
8 | depends on !NF_CONNTRACK || \ | 8 | depends on !NF_CONNTRACK || \ |
9 | (NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \ | 9 | (NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \ |
10 | (!NF_NAT || NF_NAT))) | 10 | (!NF_NAT || NF_NAT) && \ |
11 | (!NF_NAT_IPV4 || NF_NAT_IPV4) && \ | ||
12 | (!NF_NAT_IPV6 || NF_NAT_IPV6))) | ||
11 | select LIBCRC32C | 13 | select LIBCRC32C |
12 | select MPLS | 14 | select MPLS |
13 | select NET_MPLS_GSO | 15 | select NET_MPLS_GSO |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index e9dd47b2a85b..879185fe183f 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -461,7 +461,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, | |||
461 | mask_ipv6_addr(saddr, key->ipv6_src, mask->ipv6_src, masked); | 461 | mask_ipv6_addr(saddr, key->ipv6_src, mask->ipv6_src, masked); |
462 | 462 | ||
463 | if (unlikely(memcmp(saddr, masked, sizeof(masked)))) { | 463 | if (unlikely(memcmp(saddr, masked, sizeof(masked)))) { |
464 | set_ipv6_addr(skb, key->ipv6_proto, saddr, masked, | 464 | set_ipv6_addr(skb, flow_key->ip.proto, saddr, masked, |
465 | true); | 465 | true); |
466 | memcpy(&flow_key->ipv6.addr.src, masked, | 466 | memcpy(&flow_key->ipv6.addr.src, masked, |
467 | sizeof(flow_key->ipv6.addr.src)); | 467 | sizeof(flow_key->ipv6.addr.src)); |
@@ -483,7 +483,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, | |||
483 | NULL, &flags) | 483 | NULL, &flags) |
484 | != NEXTHDR_ROUTING); | 484 | != NEXTHDR_ROUTING); |
485 | 485 | ||
486 | set_ipv6_addr(skb, key->ipv6_proto, daddr, masked, | 486 | set_ipv6_addr(skb, flow_key->ip.proto, daddr, masked, |
487 | recalc_csum); | 487 | recalc_csum); |
488 | memcpy(&flow_key->ipv6.addr.dst, masked, | 488 | memcpy(&flow_key->ipv6.addr.dst, masked, |
489 | sizeof(flow_key->ipv6.addr.dst)); | 489 | sizeof(flow_key->ipv6.addr.dst)); |
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index dc5eb29fe7d6..b5fea1101faa 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c | |||
@@ -367,6 +367,7 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, | |||
367 | } else if (key->eth.type == htons(ETH_P_IPV6)) { | 367 | } else if (key->eth.type == htons(ETH_P_IPV6)) { |
368 | enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; | 368 | enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; |
369 | 369 | ||
370 | skb_orphan(skb); | ||
370 | memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); | 371 | memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); |
371 | err = nf_ct_frag6_gather(net, skb, user); | 372 | err = nf_ct_frag6_gather(net, skb, user); |
372 | if (err) | 373 | if (err) |
@@ -535,14 +536,15 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, | |||
535 | switch (ctinfo) { | 536 | switch (ctinfo) { |
536 | case IP_CT_RELATED: | 537 | case IP_CT_RELATED: |
537 | case IP_CT_RELATED_REPLY: | 538 | case IP_CT_RELATED_REPLY: |
538 | if (skb->protocol == htons(ETH_P_IP) && | 539 | if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && |
540 | skb->protocol == htons(ETH_P_IP) && | ||
539 | ip_hdr(skb)->protocol == IPPROTO_ICMP) { | 541 | ip_hdr(skb)->protocol == IPPROTO_ICMP) { |
540 | if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, | 542 | if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, |
541 | hooknum)) | 543 | hooknum)) |
542 | err = NF_DROP; | 544 | err = NF_DROP; |
543 | goto push; | 545 | goto push; |
544 | #if IS_ENABLED(CONFIG_NF_NAT_IPV6) | 546 | } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && |
545 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 547 | skb->protocol == htons(ETH_P_IPV6)) { |
546 | __be16 frag_off; | 548 | __be16 frag_off; |
547 | u8 nexthdr = ipv6_hdr(skb)->nexthdr; | 549 | u8 nexthdr = ipv6_hdr(skb)->nexthdr; |
548 | int hdrlen = ipv6_skip_exthdr(skb, | 550 | int hdrlen = ipv6_skip_exthdr(skb, |
@@ -557,7 +559,6 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, | |||
557 | err = NF_DROP; | 559 | err = NF_DROP; |
558 | goto push; | 560 | goto push; |
559 | } | 561 | } |
560 | #endif | ||
561 | } | 562 | } |
562 | /* Non-ICMP, fall thru to initialize if needed. */ | 563 | /* Non-ICMP, fall thru to initialize if needed. */ |
563 | case IP_CT_NEW: | 564 | case IP_CT_NEW: |
@@ -664,11 +665,12 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key, | |||
664 | 665 | ||
665 | /* Determine NAT type. | 666 | /* Determine NAT type. |
666 | * Check if the NAT type can be deduced from the tracked connection. | 667 | * Check if the NAT type can be deduced from the tracked connection. |
667 | * Make sure expected traffic is NATted only when committing. | 668 | * Make sure new expected connections (IP_CT_RELATED) are NATted only |
669 | * when committing. | ||
668 | */ | 670 | */ |
669 | if (info->nat & OVS_CT_NAT && ctinfo != IP_CT_NEW && | 671 | if (info->nat & OVS_CT_NAT && ctinfo != IP_CT_NEW && |
670 | ct->status & IPS_NAT_MASK && | 672 | ct->status & IPS_NAT_MASK && |
671 | (!(ct->status & IPS_EXPECTED_BIT) || info->commit)) { | 673 | (ctinfo != IP_CT_RELATED || info->commit)) { |
672 | /* NAT an established or related connection like before. */ | 674 | /* NAT an established or related connection like before. */ |
673 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) | 675 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) |
674 | /* This is the REPLY direction for a connection | 676 | /* This is the REPLY direction for a connection |
@@ -968,7 +970,8 @@ static int parse_nat(const struct nlattr *attr, | |||
968 | break; | 970 | break; |
969 | 971 | ||
970 | case OVS_NAT_ATTR_IP_MIN: | 972 | case OVS_NAT_ATTR_IP_MIN: |
971 | nla_memcpy(&info->range.min_addr, a, nla_len(a)); | 973 | nla_memcpy(&info->range.min_addr, a, |
974 | sizeof(info->range.min_addr)); | ||
972 | info->range.flags |= NF_NAT_RANGE_MAP_IPS; | 975 | info->range.flags |= NF_NAT_RANGE_MAP_IPS; |
973 | break; | 976 | break; |
974 | 977 | ||
@@ -1238,7 +1241,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1238 | } | 1241 | } |
1239 | 1242 | ||
1240 | if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { | 1243 | if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { |
1241 | if (info->family == NFPROTO_IPV4) { | 1244 | if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && |
1245 | info->family == NFPROTO_IPV4) { | ||
1242 | if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN, | 1246 | if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN, |
1243 | info->range.min_addr.ip) || | 1247 | info->range.min_addr.ip) || |
1244 | (info->range.max_addr.ip | 1248 | (info->range.max_addr.ip |
@@ -1246,8 +1250,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1246 | (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX, | 1250 | (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX, |
1247 | info->range.max_addr.ip)))) | 1251 | info->range.max_addr.ip)))) |
1248 | return false; | 1252 | return false; |
1249 | #if IS_ENABLED(CONFIG_NF_NAT_IPV6) | 1253 | } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && |
1250 | } else if (info->family == NFPROTO_IPV6) { | 1254 | info->family == NFPROTO_IPV6) { |
1251 | if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN, | 1255 | if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN, |
1252 | &info->range.min_addr.in6) || | 1256 | &info->range.min_addr.in6) || |
1253 | (memcmp(&info->range.max_addr.in6, | 1257 | (memcmp(&info->range.max_addr.in6, |
@@ -1256,7 +1260,6 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1256 | (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX, | 1260 | (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX, |
1257 | &info->range.max_addr.in6)))) | 1261 | &info->range.max_addr.in6)))) |
1258 | return false; | 1262 | return false; |
1259 | #endif | ||
1260 | } else { | 1263 | } else { |
1261 | return false; | 1264 | return false; |
1262 | } | 1265 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1ecfa710ca98..18d0becbc46d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -3521,6 +3521,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) | |||
3521 | i->ifindex = mreq->mr_ifindex; | 3521 | i->ifindex = mreq->mr_ifindex; |
3522 | i->alen = mreq->mr_alen; | 3522 | i->alen = mreq->mr_alen; |
3523 | memcpy(i->addr, mreq->mr_address, i->alen); | 3523 | memcpy(i->addr, mreq->mr_address, i->alen); |
3524 | memset(i->addr + i->alen, 0, sizeof(i->addr) - i->alen); | ||
3524 | i->count = 1; | 3525 | i->count = 1; |
3525 | i->next = po->mclist; | 3526 | i->next = po->mclist; |
3526 | po->mclist = i; | 3527 | po->mclist = i; |
@@ -4151,7 +4152,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4151 | 4152 | ||
4152 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ | 4153 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ |
4153 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { | 4154 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { |
4154 | WARN(1, "Tx-ring is not supported.\n"); | 4155 | net_warn_ratelimited("Tx-ring is not supported.\n"); |
4155 | goto out; | 4156 | goto out; |
4156 | } | 4157 | } |
4157 | 4158 | ||
diff --git a/net/rds/cong.c b/net/rds/cong.c index e6144b8246fd..6641bcf7c185 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c | |||
@@ -299,7 +299,7 @@ void rds_cong_set_bit(struct rds_cong_map *map, __be16 port) | |||
299 | i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; | 299 | i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; |
300 | off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; | 300 | off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; |
301 | 301 | ||
302 | __set_bit_le(off, (void *)map->m_page_addrs[i]); | 302 | set_bit_le(off, (void *)map->m_page_addrs[i]); |
303 | } | 303 | } |
304 | 304 | ||
305 | void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) | 305 | void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) |
@@ -313,7 +313,7 @@ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) | |||
313 | i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; | 313 | i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; |
314 | off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; | 314 | off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; |
315 | 315 | ||
316 | __clear_bit_le(off, (void *)map->m_page_addrs[i]); | 316 | clear_bit_le(off, (void *)map->m_page_addrs[i]); |
317 | } | 317 | } |
318 | 318 | ||
319 | static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port) | 319 | static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port) |
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 8764970f0c24..310cabce2311 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -194,7 +194,7 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, | |||
194 | dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version); | 194 | dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version); |
195 | dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version); | 195 | dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version); |
196 | dp->dp_protocol_minor_mask = cpu_to_be16(RDS_IB_SUPPORTED_PROTOCOLS); | 196 | dp->dp_protocol_minor_mask = cpu_to_be16(RDS_IB_SUPPORTED_PROTOCOLS); |
197 | dp->dp_ack_seq = rds_ib_piggyb_ack(ic); | 197 | dp->dp_ack_seq = cpu_to_be64(rds_ib_piggyb_ack(ic)); |
198 | 198 | ||
199 | /* Advertise flow control */ | 199 | /* Advertise flow control */ |
200 | if (ic->i_flowctl) { | 200 | if (ic->i_flowctl) { |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 977fb86065b7..abc8cc805e8d 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -796,7 +796,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, | |||
796 | 796 | ||
797 | addr = kmap_atomic(sg_page(&frag->f_sg)); | 797 | addr = kmap_atomic(sg_page(&frag->f_sg)); |
798 | 798 | ||
799 | src = addr + frag_off; | 799 | src = addr + frag->f_sg.offset + frag_off; |
800 | dst = (void *)map->m_page_addrs[map_page] + map_off; | 800 | dst = (void *)map->m_page_addrs[map_page] + map_off; |
801 | for (k = 0; k < to_copy; k += 8) { | 801 | for (k = 0; k < to_copy; k += 8) { |
802 | /* Record ports that became uncongested, ie | 802 | /* Record ports that became uncongested, ie |
diff --git a/net/rds/page.c b/net/rds/page.c index 616f21f4e7d7..e2b5a5832d3d 100644 --- a/net/rds/page.c +++ b/net/rds/page.c | |||
@@ -135,8 +135,8 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, | |||
135 | if (rem->r_offset != 0) | 135 | if (rem->r_offset != 0) |
136 | rds_stats_inc(s_page_remainder_hit); | 136 | rds_stats_inc(s_page_remainder_hit); |
137 | 137 | ||
138 | rem->r_offset += bytes; | 138 | rem->r_offset += ALIGN(bytes, 8); |
139 | if (rem->r_offset == PAGE_SIZE) { | 139 | if (rem->r_offset >= PAGE_SIZE) { |
140 | __free_page(rem->r_page); | 140 | __free_page(rem->r_page); |
141 | rem->r_page = NULL; | 141 | rem->r_page = NULL; |
142 | } | 142 | } |
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 61ed2a8764ba..86187dad1440 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -127,7 +127,7 @@ void rds_tcp_restore_callbacks(struct socket *sock, | |||
127 | 127 | ||
128 | /* | 128 | /* |
129 | * This is the only path that sets tc->t_sock. Send and receive trust that | 129 | * This is the only path that sets tc->t_sock. Send and receive trust that |
130 | * it is set. The RDS_CONN_CONNECTED bit protects those paths from being | 130 | * it is set. The RDS_CONN_UP bit protects those paths from being |
131 | * called while it isn't set. | 131 | * called while it isn't set. |
132 | */ | 132 | */ |
133 | void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) | 133 | void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) |
@@ -216,6 +216,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
216 | if (!tc) | 216 | if (!tc) |
217 | return -ENOMEM; | 217 | return -ENOMEM; |
218 | 218 | ||
219 | mutex_init(&tc->t_conn_lock); | ||
219 | tc->t_sock = NULL; | 220 | tc->t_sock = NULL; |
220 | tc->t_tinc = NULL; | 221 | tc->t_tinc = NULL; |
221 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); | 222 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); |
diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 64f873c0c6b6..41c228300525 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h | |||
@@ -12,6 +12,10 @@ struct rds_tcp_connection { | |||
12 | 12 | ||
13 | struct list_head t_tcp_node; | 13 | struct list_head t_tcp_node; |
14 | struct rds_connection *conn; | 14 | struct rds_connection *conn; |
15 | /* t_conn_lock synchronizes the connection establishment between | ||
16 | * rds_tcp_accept_one and rds_tcp_conn_connect | ||
17 | */ | ||
18 | struct mutex t_conn_lock; | ||
15 | struct socket *t_sock; | 19 | struct socket *t_sock; |
16 | void *t_orig_write_space; | 20 | void *t_orig_write_space; |
17 | void *t_orig_data_ready; | 21 | void *t_orig_data_ready; |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index 5cb16875c460..49a3fcfed360 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -78,7 +78,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn) | |||
78 | struct socket *sock = NULL; | 78 | struct socket *sock = NULL; |
79 | struct sockaddr_in src, dest; | 79 | struct sockaddr_in src, dest; |
80 | int ret; | 80 | int ret; |
81 | struct rds_tcp_connection *tc = conn->c_transport_data; | ||
82 | |||
83 | mutex_lock(&tc->t_conn_lock); | ||
81 | 84 | ||
85 | if (rds_conn_up(conn)) { | ||
86 | mutex_unlock(&tc->t_conn_lock); | ||
87 | return 0; | ||
88 | } | ||
82 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, | 89 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, |
83 | SOCK_STREAM, IPPROTO_TCP, &sock); | 90 | SOCK_STREAM, IPPROTO_TCP, &sock); |
84 | if (ret < 0) | 91 | if (ret < 0) |
@@ -120,6 +127,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn) | |||
120 | } | 127 | } |
121 | 128 | ||
122 | out: | 129 | out: |
130 | mutex_unlock(&tc->t_conn_lock); | ||
123 | if (sock) | 131 | if (sock) |
124 | sock_release(sock); | 132 | sock_release(sock); |
125 | return ret; | 133 | return ret; |
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 0936a4a32b47..be263cdf268b 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -76,7 +76,9 @@ int rds_tcp_accept_one(struct socket *sock) | |||
76 | struct rds_connection *conn; | 76 | struct rds_connection *conn; |
77 | int ret; | 77 | int ret; |
78 | struct inet_sock *inet; | 78 | struct inet_sock *inet; |
79 | struct rds_tcp_connection *rs_tcp; | 79 | struct rds_tcp_connection *rs_tcp = NULL; |
80 | int conn_state; | ||
81 | struct sock *nsk; | ||
80 | 82 | ||
81 | ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family, | 83 | ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family, |
82 | sock->sk->sk_type, sock->sk->sk_protocol, | 84 | sock->sk->sk_type, sock->sk->sk_protocol, |
@@ -115,28 +117,44 @@ int rds_tcp_accept_one(struct socket *sock) | |||
115 | * rds_tcp_state_change() will do that cleanup | 117 | * rds_tcp_state_change() will do that cleanup |
116 | */ | 118 | */ |
117 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; | 119 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; |
118 | if (rs_tcp->t_sock && | ||
119 | ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | ||
120 | struct sock *nsk = new_sock->sk; | ||
121 | |||
122 | nsk->sk_user_data = NULL; | ||
123 | nsk->sk_prot->disconnect(nsk, 0); | ||
124 | tcp_done(nsk); | ||
125 | new_sock = NULL; | ||
126 | ret = 0; | ||
127 | goto out; | ||
128 | } else if (rs_tcp->t_sock) { | ||
129 | rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | ||
130 | conn->c_outgoing = 0; | ||
131 | } | ||
132 | |||
133 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); | 120 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); |
121 | mutex_lock(&rs_tcp->t_conn_lock); | ||
122 | conn_state = rds_conn_state(conn); | ||
123 | if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) | ||
124 | goto rst_nsk; | ||
125 | if (rs_tcp->t_sock) { | ||
126 | /* Need to resolve a duelling SYN between peers. | ||
127 | * We have an outstanding SYN to this peer, which may | ||
128 | * potentially have transitioned to the RDS_CONN_UP state, | ||
129 | * so we must quiesce any send threads before resetting | ||
130 | * c_transport_data. | ||
131 | */ | ||
132 | wait_event(conn->c_waitq, | ||
133 | !test_bit(RDS_IN_XMIT, &conn->c_flags)); | ||
134 | if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | ||
135 | goto rst_nsk; | ||
136 | } else if (rs_tcp->t_sock) { | ||
137 | rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | ||
138 | conn->c_outgoing = 0; | ||
139 | } | ||
140 | } | ||
134 | rds_tcp_set_callbacks(new_sock, conn); | 141 | rds_tcp_set_callbacks(new_sock, conn); |
135 | rds_connect_complete(conn); | 142 | rds_connect_complete(conn); /* marks RDS_CONN_UP */ |
143 | new_sock = NULL; | ||
144 | ret = 0; | ||
145 | goto out; | ||
146 | rst_nsk: | ||
147 | /* reset the newly returned accept sock and bail */ | ||
148 | nsk = new_sock->sk; | ||
149 | rds_tcp_stats_inc(s_tcp_listen_closed_stale); | ||
150 | nsk->sk_user_data = NULL; | ||
151 | nsk->sk_prot->disconnect(nsk, 0); | ||
152 | tcp_done(nsk); | ||
136 | new_sock = NULL; | 153 | new_sock = NULL; |
137 | ret = 0; | 154 | ret = 0; |
138 | |||
139 | out: | 155 | out: |
156 | if (rs_tcp) | ||
157 | mutex_unlock(&rs_tcp->t_conn_lock); | ||
140 | if (new_sock) | 158 | if (new_sock) |
141 | sock_release(new_sock); | 159 | sock_release(new_sock); |
142 | return ret; | 160 | return ret; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index f18c35024207..80742edea96f 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -159,12 +159,15 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, | |||
159 | if (validate) | 159 | if (validate) |
160 | skb = validate_xmit_skb_list(skb, dev); | 160 | skb = validate_xmit_skb_list(skb, dev); |
161 | 161 | ||
162 | if (skb) { | 162 | if (likely(skb)) { |
163 | HARD_TX_LOCK(dev, txq, smp_processor_id()); | 163 | HARD_TX_LOCK(dev, txq, smp_processor_id()); |
164 | if (!netif_xmit_frozen_or_stopped(txq)) | 164 | if (!netif_xmit_frozen_or_stopped(txq)) |
165 | skb = dev_hard_start_xmit(skb, dev, txq, &ret); | 165 | skb = dev_hard_start_xmit(skb, dev, txq, &ret); |
166 | 166 | ||
167 | HARD_TX_UNLOCK(dev, txq); | 167 | HARD_TX_UNLOCK(dev, txq); |
168 | } else { | ||
169 | spin_lock(root_lock); | ||
170 | return qdisc_qlen(q); | ||
168 | } | 171 | } |
169 | spin_lock(root_lock); | 172 | spin_lock(root_lock); |
170 | 173 | ||
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 9640bb39a5d2..4befe97a9034 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -395,6 +395,25 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | |||
395 | sch->q.qlen++; | 395 | sch->q.qlen++; |
396 | } | 396 | } |
397 | 397 | ||
398 | /* netem can't properly corrupt a megapacket (like we get from GSO), so instead | ||
399 | * when we statistically choose to corrupt one, we instead segment it, returning | ||
400 | * the first packet to be corrupted, and re-enqueue the remaining frames | ||
401 | */ | ||
402 | static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sch) | ||
403 | { | ||
404 | struct sk_buff *segs; | ||
405 | netdev_features_t features = netif_skb_features(skb); | ||
406 | |||
407 | segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | ||
408 | |||
409 | if (IS_ERR_OR_NULL(segs)) { | ||
410 | qdisc_reshape_fail(skb, sch); | ||
411 | return NULL; | ||
412 | } | ||
413 | consume_skb(skb); | ||
414 | return segs; | ||
415 | } | ||
416 | |||
398 | /* | 417 | /* |
399 | * Insert one skb into qdisc. | 418 | * Insert one skb into qdisc. |
400 | * Note: parent depends on return value to account for queue length. | 419 | * Note: parent depends on return value to account for queue length. |
@@ -407,7 +426,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
407 | /* We don't fill cb now as skb_unshare() may invalidate it */ | 426 | /* We don't fill cb now as skb_unshare() may invalidate it */ |
408 | struct netem_skb_cb *cb; | 427 | struct netem_skb_cb *cb; |
409 | struct sk_buff *skb2; | 428 | struct sk_buff *skb2; |
429 | struct sk_buff *segs = NULL; | ||
430 | unsigned int len = 0, last_len, prev_len = qdisc_pkt_len(skb); | ||
431 | int nb = 0; | ||
410 | int count = 1; | 432 | int count = 1; |
433 | int rc = NET_XMIT_SUCCESS; | ||
411 | 434 | ||
412 | /* Random duplication */ | 435 | /* Random duplication */ |
413 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) | 436 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) |
@@ -453,10 +476,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
453 | * do it now in software before we mangle it. | 476 | * do it now in software before we mangle it. |
454 | */ | 477 | */ |
455 | if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { | 478 | if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { |
479 | if (skb_is_gso(skb)) { | ||
480 | segs = netem_segment(skb, sch); | ||
481 | if (!segs) | ||
482 | return NET_XMIT_DROP; | ||
483 | } else { | ||
484 | segs = skb; | ||
485 | } | ||
486 | |||
487 | skb = segs; | ||
488 | segs = segs->next; | ||
489 | |||
456 | if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || | 490 | if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || |
457 | (skb->ip_summed == CHECKSUM_PARTIAL && | 491 | (skb->ip_summed == CHECKSUM_PARTIAL && |
458 | skb_checksum_help(skb))) | 492 | skb_checksum_help(skb))) { |
459 | return qdisc_drop(skb, sch); | 493 | rc = qdisc_drop(skb, sch); |
494 | goto finish_segs; | ||
495 | } | ||
460 | 496 | ||
461 | skb->data[prandom_u32() % skb_headlen(skb)] ^= | 497 | skb->data[prandom_u32() % skb_headlen(skb)] ^= |
462 | 1<<(prandom_u32() % 8); | 498 | 1<<(prandom_u32() % 8); |
@@ -516,6 +552,27 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
516 | sch->qstats.requeues++; | 552 | sch->qstats.requeues++; |
517 | } | 553 | } |
518 | 554 | ||
555 | finish_segs: | ||
556 | if (segs) { | ||
557 | while (segs) { | ||
558 | skb2 = segs->next; | ||
559 | segs->next = NULL; | ||
560 | qdisc_skb_cb(segs)->pkt_len = segs->len; | ||
561 | last_len = segs->len; | ||
562 | rc = qdisc_enqueue(segs, sch); | ||
563 | if (rc != NET_XMIT_SUCCESS) { | ||
564 | if (net_xmit_drop_count(rc)) | ||
565 | qdisc_qstats_drop(sch); | ||
566 | } else { | ||
567 | nb++; | ||
568 | len += last_len; | ||
569 | } | ||
570 | segs = skb2; | ||
571 | } | ||
572 | sch->q.qlen += nb; | ||
573 | if (nb > 1) | ||
574 | qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); | ||
575 | } | ||
519 | return NET_XMIT_SUCCESS; | 576 | return NET_XMIT_SUCCESS; |
520 | } | 577 | } |
521 | 578 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index 736c004abfbc..9844fe573029 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -401,7 +401,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
401 | sk = chunk->skb->sk; | 401 | sk = chunk->skb->sk; |
402 | 402 | ||
403 | /* Allocate the new skb. */ | 403 | /* Allocate the new skb. */ |
404 | nskb = alloc_skb(packet->size + MAX_HEADER, GFP_ATOMIC); | 404 | nskb = alloc_skb(packet->size + MAX_HEADER, gfp); |
405 | if (!nskb) | 405 | if (!nskb) |
406 | goto nomem; | 406 | goto nomem; |
407 | 407 | ||
@@ -523,8 +523,8 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
523 | */ | 523 | */ |
524 | if (auth) | 524 | if (auth) |
525 | sctp_auth_calculate_hmac(asoc, nskb, | 525 | sctp_auth_calculate_hmac(asoc, nskb, |
526 | (struct sctp_auth_chunk *)auth, | 526 | (struct sctp_auth_chunk *)auth, |
527 | GFP_ATOMIC); | 527 | gfp); |
528 | 528 | ||
529 | /* 2) Calculate the Adler-32 checksum of the whole packet, | 529 | /* 2) Calculate the Adler-32 checksum of the whole packet, |
530 | * including the SCTP common header and all the | 530 | * including the SCTP common header and all the |
@@ -705,7 +705,8 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | |||
705 | /* Check whether this chunk and all the rest of pending data will fit | 705 | /* Check whether this chunk and all the rest of pending data will fit |
706 | * or delay in hopes of bundling a full sized packet. | 706 | * or delay in hopes of bundling a full sized packet. |
707 | */ | 707 | */ |
708 | if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead) | 708 | if (chunk->skb->len + q->out_qlen > |
709 | transport->pathmtu - packet->overhead - sizeof(sctp_data_chunk_t) - 4) | ||
709 | /* Enough data queued to fill a packet */ | 710 | /* Enough data queued to fill a packet */ |
710 | return SCTP_XMIT_OK; | 711 | return SCTP_XMIT_OK; |
711 | 712 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 8d3d3625130e..084718f9b3da 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -866,8 +866,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
866 | * sender MUST assure that at least one T3-rtx | 866 | * sender MUST assure that at least one T3-rtx |
867 | * timer is running. | 867 | * timer is running. |
868 | */ | 868 | */ |
869 | if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) | 869 | if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { |
870 | sctp_transport_reset_timers(transport); | 870 | sctp_transport_reset_t3_rtx(transport); |
871 | transport->last_time_sent = jiffies; | ||
872 | } | ||
871 | } | 873 | } |
872 | break; | 874 | break; |
873 | 875 | ||
@@ -924,8 +926,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
924 | error = sctp_outq_flush_rtx(q, packet, | 926 | error = sctp_outq_flush_rtx(q, packet, |
925 | rtx_timeout, &start_timer); | 927 | rtx_timeout, &start_timer); |
926 | 928 | ||
927 | if (start_timer) | 929 | if (start_timer) { |
928 | sctp_transport_reset_timers(transport); | 930 | sctp_transport_reset_t3_rtx(transport); |
931 | transport->last_time_sent = jiffies; | ||
932 | } | ||
929 | 933 | ||
930 | /* This can happen on COOKIE-ECHO resend. Only | 934 | /* This can happen on COOKIE-ECHO resend. Only |
931 | * one chunk can get bundled with a COOKIE-ECHO. | 935 | * one chunk can get bundled with a COOKIE-ECHO. |
@@ -1062,7 +1066,8 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
1062 | list_add_tail(&chunk->transmitted_list, | 1066 | list_add_tail(&chunk->transmitted_list, |
1063 | &transport->transmitted); | 1067 | &transport->transmitted); |
1064 | 1068 | ||
1065 | sctp_transport_reset_timers(transport); | 1069 | sctp_transport_reset_t3_rtx(transport); |
1070 | transport->last_time_sent = jiffies; | ||
1066 | 1071 | ||
1067 | /* Only let one DATA chunk get bundled with a | 1072 | /* Only let one DATA chunk get bundled with a |
1068 | * COOKIE-ECHO chunk. | 1073 | * COOKIE-ECHO chunk. |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 7f0bf798205b..56f364d8f932 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -3080,8 +3080,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
3080 | return SCTP_ERROR_RSRC_LOW; | 3080 | return SCTP_ERROR_RSRC_LOW; |
3081 | 3081 | ||
3082 | /* Start the heartbeat timer. */ | 3082 | /* Start the heartbeat timer. */ |
3083 | if (!mod_timer(&peer->hb_timer, sctp_transport_timeout(peer))) | 3083 | sctp_transport_reset_hb_timer(peer); |
3084 | sctp_transport_hold(peer); | ||
3085 | asoc->new_transport = peer; | 3084 | asoc->new_transport = peer; |
3086 | break; | 3085 | break; |
3087 | case SCTP_PARAM_DEL_IP: | 3086 | case SCTP_PARAM_DEL_IP: |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 7fe56d0acabf..41b081a64752 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -69,8 +69,6 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, | |||
69 | sctp_cmd_seq_t *commands, | 69 | sctp_cmd_seq_t *commands, |
70 | gfp_t gfp); | 70 | gfp_t gfp); |
71 | 71 | ||
72 | static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds, | ||
73 | struct sctp_transport *t); | ||
74 | /******************************************************************** | 72 | /******************************************************************** |
75 | * Helper functions | 73 | * Helper functions |
76 | ********************************************************************/ | 74 | ********************************************************************/ |
@@ -367,6 +365,7 @@ void sctp_generate_heartbeat_event(unsigned long data) | |||
367 | struct sctp_association *asoc = transport->asoc; | 365 | struct sctp_association *asoc = transport->asoc; |
368 | struct sock *sk = asoc->base.sk; | 366 | struct sock *sk = asoc->base.sk; |
369 | struct net *net = sock_net(sk); | 367 | struct net *net = sock_net(sk); |
368 | u32 elapsed, timeout; | ||
370 | 369 | ||
371 | bh_lock_sock(sk); | 370 | bh_lock_sock(sk); |
372 | if (sock_owned_by_user(sk)) { | 371 | if (sock_owned_by_user(sk)) { |
@@ -378,6 +377,16 @@ void sctp_generate_heartbeat_event(unsigned long data) | |||
378 | goto out_unlock; | 377 | goto out_unlock; |
379 | } | 378 | } |
380 | 379 | ||
380 | /* Check if we should still send the heartbeat or reschedule */ | ||
381 | elapsed = jiffies - transport->last_time_sent; | ||
382 | timeout = sctp_transport_timeout(transport); | ||
383 | if (elapsed < timeout) { | ||
384 | elapsed = timeout - elapsed; | ||
385 | if (!mod_timer(&transport->hb_timer, jiffies + elapsed)) | ||
386 | sctp_transport_hold(transport); | ||
387 | goto out_unlock; | ||
388 | } | ||
389 | |||
381 | error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT, | 390 | error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT, |
382 | SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT), | 391 | SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT), |
383 | asoc->state, asoc->ep, asoc, | 392 | asoc->state, asoc->ep, asoc, |
@@ -507,7 +516,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, | |||
507 | 0); | 516 | 0); |
508 | 517 | ||
509 | /* Update the hb timer to resend a heartbeat every rto */ | 518 | /* Update the hb timer to resend a heartbeat every rto */ |
510 | sctp_cmd_hb_timer_update(commands, transport); | 519 | sctp_transport_reset_hb_timer(transport); |
511 | } | 520 | } |
512 | 521 | ||
513 | if (transport->state != SCTP_INACTIVE && | 522 | if (transport->state != SCTP_INACTIVE && |
@@ -634,11 +643,8 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, | |||
634 | * hold a reference on the transport to make sure none of | 643 | * hold a reference on the transport to make sure none of |
635 | * the needed data structures go away. | 644 | * the needed data structures go away. |
636 | */ | 645 | */ |
637 | list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) { | 646 | list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) |
638 | 647 | sctp_transport_reset_hb_timer(t); | |
639 | if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) | ||
640 | sctp_transport_hold(t); | ||
641 | } | ||
642 | } | 648 | } |
643 | 649 | ||
644 | static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, | 650 | static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, |
@@ -669,15 +675,6 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds, | |||
669 | } | 675 | } |
670 | 676 | ||
671 | 677 | ||
672 | /* Helper function to update the heartbeat timer. */ | ||
673 | static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds, | ||
674 | struct sctp_transport *t) | ||
675 | { | ||
676 | /* Update the heartbeat timer. */ | ||
677 | if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) | ||
678 | sctp_transport_hold(t); | ||
679 | } | ||
680 | |||
681 | /* Helper function to handle the reception of an HEARTBEAT ACK. */ | 678 | /* Helper function to handle the reception of an HEARTBEAT ACK. */ |
682 | static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | 679 | static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, |
683 | struct sctp_association *asoc, | 680 | struct sctp_association *asoc, |
@@ -742,8 +739,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
742 | sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); | 739 | sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); |
743 | 740 | ||
744 | /* Update the heartbeat timer. */ | 741 | /* Update the heartbeat timer. */ |
745 | if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) | 742 | sctp_transport_reset_hb_timer(t); |
746 | sctp_transport_hold(t); | ||
747 | 743 | ||
748 | if (was_unconfirmed && asoc->peer.transport_count == 1) | 744 | if (was_unconfirmed && asoc->peer.transport_count == 1) |
749 | sctp_transport_immediate_rtx(t); | 745 | sctp_transport_immediate_rtx(t); |
@@ -1614,7 +1610,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1614 | 1610 | ||
1615 | case SCTP_CMD_HB_TIMER_UPDATE: | 1611 | case SCTP_CMD_HB_TIMER_UPDATE: |
1616 | t = cmd->obj.transport; | 1612 | t = cmd->obj.transport; |
1617 | sctp_cmd_hb_timer_update(commands, t); | 1613 | sctp_transport_reset_hb_timer(t); |
1618 | break; | 1614 | break; |
1619 | 1615 | ||
1620 | case SCTP_CMD_HB_TIMERS_STOP: | 1616 | case SCTP_CMD_HB_TIMERS_STOP: |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 9b6b48c7524e..81b86678be4d 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -183,7 +183,7 @@ static void sctp_transport_destroy(struct sctp_transport *transport) | |||
183 | /* Start T3_rtx timer if it is not already running and update the heartbeat | 183 | /* Start T3_rtx timer if it is not already running and update the heartbeat |
184 | * timer. This routine is called every time a DATA chunk is sent. | 184 | * timer. This routine is called every time a DATA chunk is sent. |
185 | */ | 185 | */ |
186 | void sctp_transport_reset_timers(struct sctp_transport *transport) | 186 | void sctp_transport_reset_t3_rtx(struct sctp_transport *transport) |
187 | { | 187 | { |
188 | /* RFC 2960 6.3.2 Retransmission Timer Rules | 188 | /* RFC 2960 6.3.2 Retransmission Timer Rules |
189 | * | 189 | * |
@@ -197,11 +197,18 @@ void sctp_transport_reset_timers(struct sctp_transport *transport) | |||
197 | if (!mod_timer(&transport->T3_rtx_timer, | 197 | if (!mod_timer(&transport->T3_rtx_timer, |
198 | jiffies + transport->rto)) | 198 | jiffies + transport->rto)) |
199 | sctp_transport_hold(transport); | 199 | sctp_transport_hold(transport); |
200 | } | ||
201 | |||
202 | void sctp_transport_reset_hb_timer(struct sctp_transport *transport) | ||
203 | { | ||
204 | unsigned long expires; | ||
200 | 205 | ||
201 | /* When a data chunk is sent, reset the heartbeat interval. */ | 206 | /* When a data chunk is sent, reset the heartbeat interval. */ |
202 | if (!mod_timer(&transport->hb_timer, | 207 | expires = jiffies + sctp_transport_timeout(transport); |
203 | sctp_transport_timeout(transport))) | 208 | if (time_before(transport->hb_timer.expires, expires) && |
204 | sctp_transport_hold(transport); | 209 | !mod_timer(&transport->hb_timer, |
210 | expires + prandom_u32_max(transport->rto))) | ||
211 | sctp_transport_hold(transport); | ||
205 | } | 212 | } |
206 | 213 | ||
207 | /* This transport has been assigned to an association. | 214 | /* This transport has been assigned to an association. |
@@ -595,13 +602,13 @@ void sctp_transport_burst_reset(struct sctp_transport *t) | |||
595 | unsigned long sctp_transport_timeout(struct sctp_transport *trans) | 602 | unsigned long sctp_transport_timeout(struct sctp_transport *trans) |
596 | { | 603 | { |
597 | /* RTO + timer slack +/- 50% of RTO */ | 604 | /* RTO + timer slack +/- 50% of RTO */ |
598 | unsigned long timeout = (trans->rto >> 1) + prandom_u32_max(trans->rto); | 605 | unsigned long timeout = trans->rto >> 1; |
599 | 606 | ||
600 | if (trans->state != SCTP_UNCONFIRMED && | 607 | if (trans->state != SCTP_UNCONFIRMED && |
601 | trans->state != SCTP_PF) | 608 | trans->state != SCTP_PF) |
602 | timeout += trans->hbinterval; | 609 | timeout += trans->hbinterval; |
603 | 610 | ||
604 | return timeout + jiffies; | 611 | return timeout; |
605 | } | 612 | } |
606 | 613 | ||
607 | /* Reset transport variables to their initial values */ | 614 | /* Reset transport variables to their initial values */ |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 8c6bc795f060..15612ffa8d57 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1728,8 +1728,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp) | |||
1728 | return 0; | 1728 | return 0; |
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | first = snd_buf->page_base >> PAGE_CACHE_SHIFT; | 1731 | first = snd_buf->page_base >> PAGE_SHIFT; |
1732 | last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT; | 1732 | last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; |
1733 | rqstp->rq_enc_pages_num = last - first + 1 + 1; | 1733 | rqstp->rq_enc_pages_num = last - first + 1 + 1; |
1734 | rqstp->rq_enc_pages | 1734 | rqstp->rq_enc_pages |
1735 | = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), | 1735 | = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), |
@@ -1775,10 +1775,10 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1775 | status = alloc_enc_pages(rqstp); | 1775 | status = alloc_enc_pages(rqstp); |
1776 | if (status) | 1776 | if (status) |
1777 | return status; | 1777 | return status; |
1778 | first = snd_buf->page_base >> PAGE_CACHE_SHIFT; | 1778 | first = snd_buf->page_base >> PAGE_SHIFT; |
1779 | inpages = snd_buf->pages + first; | 1779 | inpages = snd_buf->pages + first; |
1780 | snd_buf->pages = rqstp->rq_enc_pages; | 1780 | snd_buf->pages = rqstp->rq_enc_pages; |
1781 | snd_buf->page_base -= first << PAGE_CACHE_SHIFT; | 1781 | snd_buf->page_base -= first << PAGE_SHIFT; |
1782 | /* | 1782 | /* |
1783 | * Give the tail its own page, in case we need extra space in the | 1783 | * Give the tail its own page, in case we need extra space in the |
1784 | * head when wrapping: | 1784 | * head when wrapping: |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index d94a8e1e9f05..244245bcbbd2 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -78,6 +78,7 @@ krb5_encrypt( | |||
78 | memcpy(out, in, length); | 78 | memcpy(out, in, length); |
79 | sg_init_one(sg, out, length); | 79 | sg_init_one(sg, out, length); |
80 | 80 | ||
81 | skcipher_request_set_tfm(req, tfm); | ||
81 | skcipher_request_set_callback(req, 0, NULL, NULL); | 82 | skcipher_request_set_callback(req, 0, NULL, NULL); |
82 | skcipher_request_set_crypt(req, sg, sg, length, local_iv); | 83 | skcipher_request_set_crypt(req, sg, sg, length, local_iv); |
83 | 84 | ||
@@ -115,6 +116,7 @@ krb5_decrypt( | |||
115 | memcpy(out, in, length); | 116 | memcpy(out, in, length); |
116 | sg_init_one(sg, out, length); | 117 | sg_init_one(sg, out, length); |
117 | 118 | ||
119 | skcipher_request_set_tfm(req, tfm); | ||
118 | skcipher_request_set_callback(req, 0, NULL, NULL); | 120 | skcipher_request_set_callback(req, 0, NULL, NULL); |
119 | skcipher_request_set_crypt(req, sg, sg, length, local_iv); | 121 | skcipher_request_set_crypt(req, sg, sg, length, local_iv); |
120 | 122 | ||
@@ -465,7 +467,7 @@ encryptor(struct scatterlist *sg, void *data) | |||
465 | page_pos = desc->pos - outbuf->head[0].iov_len; | 467 | page_pos = desc->pos - outbuf->head[0].iov_len; |
466 | if (page_pos >= 0 && page_pos < outbuf->page_len) { | 468 | if (page_pos >= 0 && page_pos < outbuf->page_len) { |
467 | /* pages are not in place: */ | 469 | /* pages are not in place: */ |
468 | int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT; | 470 | int i = (page_pos + outbuf->page_base) >> PAGE_SHIFT; |
469 | in_page = desc->pages[i]; | 471 | in_page = desc->pages[i]; |
470 | } else { | 472 | } else { |
471 | in_page = sg_page(sg); | 473 | in_page = sg_page(sg); |
@@ -946,7 +948,8 @@ krb5_rc4_setup_seq_key(struct krb5_ctx *kctx, struct crypto_skcipher *cipher, | |||
946 | return PTR_ERR(hmac); | 948 | return PTR_ERR(hmac); |
947 | } | 949 | } |
948 | 950 | ||
949 | desc = kmalloc(sizeof(*desc), GFP_KERNEL); | 951 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), |
952 | GFP_KERNEL); | ||
950 | if (!desc) { | 953 | if (!desc) { |
951 | dprintk("%s: failed to allocate shash descriptor for '%s'\n", | 954 | dprintk("%s: failed to allocate shash descriptor for '%s'\n", |
952 | __func__, kctx->gk5e->cksum_name); | 955 | __func__, kctx->gk5e->cksum_name); |
@@ -1012,7 +1015,8 @@ krb5_rc4_setup_enc_key(struct krb5_ctx *kctx, struct crypto_skcipher *cipher, | |||
1012 | return PTR_ERR(hmac); | 1015 | return PTR_ERR(hmac); |
1013 | } | 1016 | } |
1014 | 1017 | ||
1015 | desc = kmalloc(sizeof(*desc), GFP_KERNEL); | 1018 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), |
1019 | GFP_KERNEL); | ||
1016 | if (!desc) { | 1020 | if (!desc) { |
1017 | dprintk("%s: failed to allocate shash descriptor for '%s'\n", | 1021 | dprintk("%s: failed to allocate shash descriptor for '%s'\n", |
1018 | __func__, kctx->gk5e->cksum_name); | 1022 | __func__, kctx->gk5e->cksum_name); |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 71341ccb9890..65427492b1c9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -451,7 +451,8 @@ context_derive_keys_rc4(struct krb5_ctx *ctx) | |||
451 | goto out_err_free_hmac; | 451 | goto out_err_free_hmac; |
452 | 452 | ||
453 | 453 | ||
454 | desc = kmalloc(sizeof(*desc), GFP_KERNEL); | 454 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), |
455 | GFP_KERNEL); | ||
455 | if (!desc) { | 456 | if (!desc) { |
456 | dprintk("%s: failed to allocate hash descriptor for '%s'\n", | 457 | dprintk("%s: failed to allocate hash descriptor for '%s'\n", |
457 | __func__, ctx->gk5e->cksum_name); | 458 | __func__, ctx->gk5e->cksum_name); |
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 765088e4ad84..a737c2da0837 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c | |||
@@ -79,9 +79,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize) | |||
79 | len -= buf->head[0].iov_len; | 79 | len -= buf->head[0].iov_len; |
80 | if (len <= buf->page_len) { | 80 | if (len <= buf->page_len) { |
81 | unsigned int last = (buf->page_base + len - 1) | 81 | unsigned int last = (buf->page_base + len - 1) |
82 | >>PAGE_CACHE_SHIFT; | 82 | >>PAGE_SHIFT; |
83 | unsigned int offset = (buf->page_base + len - 1) | 83 | unsigned int offset = (buf->page_base + len - 1) |
84 | & (PAGE_CACHE_SIZE - 1); | 84 | & (PAGE_SIZE - 1); |
85 | ptr = kmap_atomic(buf->pages[last]); | 85 | ptr = kmap_atomic(buf->pages[last]); |
86 | pad = *(ptr + offset); | 86 | pad = *(ptr + offset); |
87 | kunmap_atomic(ptr); | 87 | kunmap_atomic(ptr); |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 008c25d1b9f9..553bf95f7003 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -881,7 +881,7 @@ static ssize_t cache_downcall(struct address_space *mapping, | |||
881 | char *kaddr; | 881 | char *kaddr; |
882 | ssize_t ret = -ENOMEM; | 882 | ssize_t ret = -ENOMEM; |
883 | 883 | ||
884 | if (count >= PAGE_CACHE_SIZE) | 884 | if (count >= PAGE_SIZE) |
885 | goto out_slow; | 885 | goto out_slow; |
886 | 886 | ||
887 | page = find_or_create_page(mapping, 0, GFP_KERNEL); | 887 | page = find_or_create_page(mapping, 0, GFP_KERNEL); |
@@ -892,7 +892,7 @@ static ssize_t cache_downcall(struct address_space *mapping, | |||
892 | ret = cache_do_downcall(kaddr, buf, count, cd); | 892 | ret = cache_do_downcall(kaddr, buf, count, cd); |
893 | kunmap(page); | 893 | kunmap(page); |
894 | unlock_page(page); | 894 | unlock_page(page); |
895 | page_cache_release(page); | 895 | put_page(page); |
896 | return ret; | 896 | return ret; |
897 | out_slow: | 897 | out_slow: |
898 | return cache_slow_downcall(buf, count, cd); | 898 | return cache_slow_downcall(buf, count, cd); |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef3e614..fc48eca21fd2 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -1390,8 +1390,8 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
1390 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | 1390 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
1391 | int err; | 1391 | int err; |
1392 | 1392 | ||
1393 | sb->s_blocksize = PAGE_CACHE_SIZE; | 1393 | sb->s_blocksize = PAGE_SIZE; |
1394 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1394 | sb->s_blocksize_bits = PAGE_SHIFT; |
1395 | sb->s_magic = RPCAUTH_GSSMAGIC; | 1395 | sb->s_magic = RPCAUTH_GSSMAGIC; |
1396 | sb->s_op = &s_ops; | 1396 | sb->s_op = &s_ops; |
1397 | sb->s_d_op = &simple_dentry_operations; | 1397 | sb->s_d_op = &simple_dentry_operations; |
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 2df87f78e518..de70c78025d7 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c | |||
@@ -96,8 +96,8 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct | |||
96 | if (base || xdr->page_base) { | 96 | if (base || xdr->page_base) { |
97 | pglen -= base; | 97 | pglen -= base; |
98 | base += xdr->page_base; | 98 | base += xdr->page_base; |
99 | ppage += base >> PAGE_CACHE_SHIFT; | 99 | ppage += base >> PAGE_SHIFT; |
100 | base &= ~PAGE_CACHE_MASK; | 100 | base &= ~PAGE_MASK; |
101 | } | 101 | } |
102 | do { | 102 | do { |
103 | char *kaddr; | 103 | char *kaddr; |
@@ -113,7 +113,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | len = PAGE_CACHE_SIZE; | 116 | len = PAGE_SIZE; |
117 | kaddr = kmap_atomic(*ppage); | 117 | kaddr = kmap_atomic(*ppage); |
118 | if (base) { | 118 | if (base) { |
119 | len -= base; | 119 | len -= base; |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4c1b53..6bdb3865212d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(xdr_inline_pages); | |||
164 | * Note: the addresses pgto_base and pgfrom_base are both calculated in | 164 | * Note: the addresses pgto_base and pgfrom_base are both calculated in |
165 | * the same way: | 165 | * the same way: |
166 | * if a memory area starts at byte 'base' in page 'pages[i]', | 166 | * if a memory area starts at byte 'base' in page 'pages[i]', |
167 | * then its address is given as (i << PAGE_CACHE_SHIFT) + base | 167 | * then its address is given as (i << PAGE_SHIFT) + base |
168 | * Also note: pgfrom_base must be < pgto_base, but the memory areas | 168 | * Also note: pgfrom_base must be < pgto_base, but the memory areas |
169 | * they point to may overlap. | 169 | * they point to may overlap. |
170 | */ | 170 | */ |
@@ -181,20 +181,20 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, | |||
181 | pgto_base += len; | 181 | pgto_base += len; |
182 | pgfrom_base += len; | 182 | pgfrom_base += len; |
183 | 183 | ||
184 | pgto = pages + (pgto_base >> PAGE_CACHE_SHIFT); | 184 | pgto = pages + (pgto_base >> PAGE_SHIFT); |
185 | pgfrom = pages + (pgfrom_base >> PAGE_CACHE_SHIFT); | 185 | pgfrom = pages + (pgfrom_base >> PAGE_SHIFT); |
186 | 186 | ||
187 | pgto_base &= ~PAGE_CACHE_MASK; | 187 | pgto_base &= ~PAGE_MASK; |
188 | pgfrom_base &= ~PAGE_CACHE_MASK; | 188 | pgfrom_base &= ~PAGE_MASK; |
189 | 189 | ||
190 | do { | 190 | do { |
191 | /* Are any pointers crossing a page boundary? */ | 191 | /* Are any pointers crossing a page boundary? */ |
192 | if (pgto_base == 0) { | 192 | if (pgto_base == 0) { |
193 | pgto_base = PAGE_CACHE_SIZE; | 193 | pgto_base = PAGE_SIZE; |
194 | pgto--; | 194 | pgto--; |
195 | } | 195 | } |
196 | if (pgfrom_base == 0) { | 196 | if (pgfrom_base == 0) { |
197 | pgfrom_base = PAGE_CACHE_SIZE; | 197 | pgfrom_base = PAGE_SIZE; |
198 | pgfrom--; | 198 | pgfrom--; |
199 | } | 199 | } |
200 | 200 | ||
@@ -236,11 +236,11 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len) | |||
236 | char *vto; | 236 | char *vto; |
237 | size_t copy; | 237 | size_t copy; |
238 | 238 | ||
239 | pgto = pages + (pgbase >> PAGE_CACHE_SHIFT); | 239 | pgto = pages + (pgbase >> PAGE_SHIFT); |
240 | pgbase &= ~PAGE_CACHE_MASK; | 240 | pgbase &= ~PAGE_MASK; |
241 | 241 | ||
242 | for (;;) { | 242 | for (;;) { |
243 | copy = PAGE_CACHE_SIZE - pgbase; | 243 | copy = PAGE_SIZE - pgbase; |
244 | if (copy > len) | 244 | if (copy > len) |
245 | copy = len; | 245 | copy = len; |
246 | 246 | ||
@@ -253,7 +253,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len) | |||
253 | break; | 253 | break; |
254 | 254 | ||
255 | pgbase += copy; | 255 | pgbase += copy; |
256 | if (pgbase == PAGE_CACHE_SIZE) { | 256 | if (pgbase == PAGE_SIZE) { |
257 | flush_dcache_page(*pgto); | 257 | flush_dcache_page(*pgto); |
258 | pgbase = 0; | 258 | pgbase = 0; |
259 | pgto++; | 259 | pgto++; |
@@ -280,11 +280,11 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) | |||
280 | char *vfrom; | 280 | char *vfrom; |
281 | size_t copy; | 281 | size_t copy; |
282 | 282 | ||
283 | pgfrom = pages + (pgbase >> PAGE_CACHE_SHIFT); | 283 | pgfrom = pages + (pgbase >> PAGE_SHIFT); |
284 | pgbase &= ~PAGE_CACHE_MASK; | 284 | pgbase &= ~PAGE_MASK; |
285 | 285 | ||
286 | do { | 286 | do { |
287 | copy = PAGE_CACHE_SIZE - pgbase; | 287 | copy = PAGE_SIZE - pgbase; |
288 | if (copy > len) | 288 | if (copy > len) |
289 | copy = len; | 289 | copy = len; |
290 | 290 | ||
@@ -293,7 +293,7 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) | |||
293 | kunmap_atomic(vfrom); | 293 | kunmap_atomic(vfrom); |
294 | 294 | ||
295 | pgbase += copy; | 295 | pgbase += copy; |
296 | if (pgbase == PAGE_CACHE_SIZE) { | 296 | if (pgbase == PAGE_SIZE) { |
297 | pgbase = 0; | 297 | pgbase = 0; |
298 | pgfrom++; | 298 | pgfrom++; |
299 | } | 299 | } |
@@ -1038,8 +1038,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
1038 | if (base < buf->page_len) { | 1038 | if (base < buf->page_len) { |
1039 | subbuf->page_len = min(buf->page_len - base, len); | 1039 | subbuf->page_len = min(buf->page_len - base, len); |
1040 | base += buf->page_base; | 1040 | base += buf->page_base; |
1041 | subbuf->page_base = base & ~PAGE_CACHE_MASK; | 1041 | subbuf->page_base = base & ~PAGE_MASK; |
1042 | subbuf->pages = &buf->pages[base >> PAGE_CACHE_SHIFT]; | 1042 | subbuf->pages = &buf->pages[base >> PAGE_SHIFT]; |
1043 | len -= subbuf->page_len; | 1043 | len -= subbuf->page_len; |
1044 | base = 0; | 1044 | base = 0; |
1045 | } else { | 1045 | } else { |
@@ -1297,9 +1297,9 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, | |||
1297 | todo -= avail_here; | 1297 | todo -= avail_here; |
1298 | 1298 | ||
1299 | base += buf->page_base; | 1299 | base += buf->page_base; |
1300 | ppages = buf->pages + (base >> PAGE_CACHE_SHIFT); | 1300 | ppages = buf->pages + (base >> PAGE_SHIFT); |
1301 | base &= ~PAGE_CACHE_MASK; | 1301 | base &= ~PAGE_MASK; |
1302 | avail_page = min_t(unsigned int, PAGE_CACHE_SIZE - base, | 1302 | avail_page = min_t(unsigned int, PAGE_SIZE - base, |
1303 | avail_here); | 1303 | avail_here); |
1304 | c = kmap(*ppages) + base; | 1304 | c = kmap(*ppages) + base; |
1305 | 1305 | ||
@@ -1383,7 +1383,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, | |||
1383 | } | 1383 | } |
1384 | 1384 | ||
1385 | avail_page = min(avail_here, | 1385 | avail_page = min(avail_here, |
1386 | (unsigned int) PAGE_CACHE_SIZE); | 1386 | (unsigned int) PAGE_SIZE); |
1387 | } | 1387 | } |
1388 | base = buf->page_len; /* align to start of tail */ | 1388 | base = buf->page_len; /* align to start of tail */ |
1389 | } | 1389 | } |
@@ -1479,9 +1479,9 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | |||
1479 | if (page_len > len) | 1479 | if (page_len > len) |
1480 | page_len = len; | 1480 | page_len = len; |
1481 | len -= page_len; | 1481 | len -= page_len; |
1482 | page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1); | 1482 | page_offset = (offset + buf->page_base) & (PAGE_SIZE - 1); |
1483 | i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT; | 1483 | i = (offset + buf->page_base) >> PAGE_SHIFT; |
1484 | thislen = PAGE_CACHE_SIZE - page_offset; | 1484 | thislen = PAGE_SIZE - page_offset; |
1485 | do { | 1485 | do { |
1486 | if (thislen > page_len) | 1486 | if (thislen > page_len) |
1487 | thislen = page_len; | 1487 | thislen = page_len; |
@@ -1492,7 +1492,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | |||
1492 | page_len -= thislen; | 1492 | page_len -= thislen; |
1493 | i++; | 1493 | i++; |
1494 | page_offset = 0; | 1494 | page_offset = 0; |
1495 | thislen = PAGE_CACHE_SIZE; | 1495 | thislen = PAGE_SIZE; |
1496 | } while (page_len != 0); | 1496 | } while (page_len != 0); |
1497 | offset = 0; | 1497 | offset = 0; |
1498 | } | 1498 | } |
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 8b5833c1ff2e..b7e01d88bdc5 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -305,6 +305,8 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev, | |||
305 | if (err && err != -EOPNOTSUPP) | 305 | if (err && err != -EOPNOTSUPP) |
306 | netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", | 306 | netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", |
307 | err, attr->id); | 307 | err, attr->id); |
308 | if (attr->complete) | ||
309 | attr->complete(dev, err, attr->complete_priv); | ||
308 | } | 310 | } |
309 | 311 | ||
310 | static int switchdev_port_attr_set_defer(struct net_device *dev, | 312 | static int switchdev_port_attr_set_defer(struct net_device *dev, |
@@ -434,6 +436,8 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev, | |||
434 | if (err && err != -EOPNOTSUPP) | 436 | if (err && err != -EOPNOTSUPP) |
435 | netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", | 437 | netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", |
436 | err, obj->id); | 438 | err, obj->id); |
439 | if (obj->complete) | ||
440 | obj->complete(dev, err, obj->complete_priv); | ||
437 | } | 441 | } |
438 | 442 | ||
439 | static int switchdev_port_obj_add_defer(struct net_device *dev, | 443 | static int switchdev_port_obj_add_defer(struct net_device *dev, |
@@ -502,6 +506,8 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev, | |||
502 | if (err && err != -EOPNOTSUPP) | 506 | if (err && err != -EOPNOTSUPP) |
503 | netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", | 507 | netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", |
504 | err, obj->id); | 508 | err, obj->id); |
509 | if (obj->complete) | ||
510 | obj->complete(dev, err, obj->complete_priv); | ||
505 | } | 511 | } |
506 | 512 | ||
507 | static int switchdev_port_obj_del_defer(struct net_device *dev, | 513 | static int switchdev_port_obj_del_defer(struct net_device *dev, |
@@ -1079,7 +1085,7 @@ nla_put_failure: | |||
1079 | * @filter_dev: filter device | 1085 | * @filter_dev: filter device |
1080 | * @idx: | 1086 | * @idx: |
1081 | * | 1087 | * |
1082 | * Delete FDB entry from switch device. | 1088 | * Dump FDB entries from switch device. |
1083 | */ | 1089 | */ |
1084 | int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, | 1090 | int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, |
1085 | struct net_device *dev, | 1091 | struct net_device *dev, |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 03a842870c52..e2bdb07a49a2 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -69,6 +69,7 @@ static int __net_init tipc_init_net(struct net *net) | |||
69 | if (err) | 69 | if (err) |
70 | goto out_nametbl; | 70 | goto out_nametbl; |
71 | 71 | ||
72 | INIT_LIST_HEAD(&tn->dist_queue); | ||
72 | err = tipc_topsrv_start(net); | 73 | err = tipc_topsrv_start(net); |
73 | if (err) | 74 | if (err) |
74 | goto out_subscr; | 75 | goto out_subscr; |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 5504d63503df..eff58dc53aa1 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -103,6 +103,9 @@ struct tipc_net { | |||
103 | spinlock_t nametbl_lock; | 103 | spinlock_t nametbl_lock; |
104 | struct name_table *nametbl; | 104 | struct name_table *nametbl; |
105 | 105 | ||
106 | /* Name dist queue */ | ||
107 | struct list_head dist_queue; | ||
108 | |||
106 | /* Topology subscription server */ | 109 | /* Topology subscription server */ |
107 | struct tipc_server *topsrv; | 110 | struct tipc_server *topsrv; |
108 | atomic_t subscription_count; | 111 | atomic_t subscription_count; |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index ebe9d0ff6e9e..6b626a64b517 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -40,11 +40,6 @@ | |||
40 | 40 | ||
41 | int sysctl_tipc_named_timeout __read_mostly = 2000; | 41 | int sysctl_tipc_named_timeout __read_mostly = 2000; |
42 | 42 | ||
43 | /** | ||
44 | * struct tipc_dist_queue - queue holding deferred name table updates | ||
45 | */ | ||
46 | static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue); | ||
47 | |||
48 | struct distr_queue_item { | 43 | struct distr_queue_item { |
49 | struct distr_item i; | 44 | struct distr_item i; |
50 | u32 dtype; | 45 | u32 dtype; |
@@ -229,12 +224,31 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr) | |||
229 | kfree_rcu(p, rcu); | 224 | kfree_rcu(p, rcu); |
230 | } | 225 | } |
231 | 226 | ||
227 | /** | ||
228 | * tipc_dist_queue_purge - remove deferred updates from a node that went down | ||
229 | */ | ||
230 | static void tipc_dist_queue_purge(struct net *net, u32 addr) | ||
231 | { | ||
232 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
233 | struct distr_queue_item *e, *tmp; | ||
234 | |||
235 | spin_lock_bh(&tn->nametbl_lock); | ||
236 | list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { | ||
237 | if (e->node != addr) | ||
238 | continue; | ||
239 | list_del(&e->next); | ||
240 | kfree(e); | ||
241 | } | ||
242 | spin_unlock_bh(&tn->nametbl_lock); | ||
243 | } | ||
244 | |||
232 | void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr) | 245 | void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr) |
233 | { | 246 | { |
234 | struct publication *publ, *tmp; | 247 | struct publication *publ, *tmp; |
235 | 248 | ||
236 | list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) | 249 | list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) |
237 | tipc_publ_purge(net, publ, addr); | 250 | tipc_publ_purge(net, publ, addr); |
251 | tipc_dist_queue_purge(net, addr); | ||
238 | } | 252 | } |
239 | 253 | ||
240 | /** | 254 | /** |
@@ -279,9 +293,11 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i, | |||
279 | * tipc_named_add_backlog - add a failed name table update to the backlog | 293 | * tipc_named_add_backlog - add a failed name table update to the backlog |
280 | * | 294 | * |
281 | */ | 295 | */ |
282 | static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | 296 | static void tipc_named_add_backlog(struct net *net, struct distr_item *i, |
297 | u32 type, u32 node) | ||
283 | { | 298 | { |
284 | struct distr_queue_item *e; | 299 | struct distr_queue_item *e; |
300 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
285 | unsigned long now = get_jiffies_64(); | 301 | unsigned long now = get_jiffies_64(); |
286 | 302 | ||
287 | e = kzalloc(sizeof(*e), GFP_ATOMIC); | 303 | e = kzalloc(sizeof(*e), GFP_ATOMIC); |
@@ -291,7 +307,7 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | |||
291 | e->node = node; | 307 | e->node = node; |
292 | e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); | 308 | e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); |
293 | memcpy(e, i, sizeof(*i)); | 309 | memcpy(e, i, sizeof(*i)); |
294 | list_add_tail(&e->next, &tipc_dist_queue); | 310 | list_add_tail(&e->next, &tn->dist_queue); |
295 | } | 311 | } |
296 | 312 | ||
297 | /** | 313 | /** |
@@ -301,10 +317,11 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | |||
301 | void tipc_named_process_backlog(struct net *net) | 317 | void tipc_named_process_backlog(struct net *net) |
302 | { | 318 | { |
303 | struct distr_queue_item *e, *tmp; | 319 | struct distr_queue_item *e, *tmp; |
320 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
304 | char addr[16]; | 321 | char addr[16]; |
305 | unsigned long now = get_jiffies_64(); | 322 | unsigned long now = get_jiffies_64(); |
306 | 323 | ||
307 | list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) { | 324 | list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { |
308 | if (time_after(e->expires, now)) { | 325 | if (time_after(e->expires, now)) { |
309 | if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) | 326 | if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) |
310 | continue; | 327 | continue; |
@@ -344,7 +361,7 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq) | |||
344 | node = msg_orignode(msg); | 361 | node = msg_orignode(msg); |
345 | while (count--) { | 362 | while (count--) { |
346 | if (!tipc_update_nametbl(net, item, node, mtype)) | 363 | if (!tipc_update_nametbl(net, item, node, mtype)) |
347 | tipc_named_add_backlog(item, mtype, node); | 364 | tipc_named_add_backlog(net, item, mtype, node); |
348 | item++; | 365 | item++; |
349 | } | 366 | } |
350 | kfree_skb(skb); | 367 | kfree_skb(skb); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index ace178fd3850..9aaa1bc566ae 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1444,6 +1444,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1444 | int bearer_id = b->identity; | 1444 | int bearer_id = b->identity; |
1445 | struct tipc_link_entry *le; | 1445 | struct tipc_link_entry *le; |
1446 | u16 bc_ack = msg_bcast_ack(hdr); | 1446 | u16 bc_ack = msg_bcast_ack(hdr); |
1447 | u32 self = tipc_own_addr(net); | ||
1447 | int rc = 0; | 1448 | int rc = 0; |
1448 | 1449 | ||
1449 | __skb_queue_head_init(&xmitq); | 1450 | __skb_queue_head_init(&xmitq); |
@@ -1460,6 +1461,10 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1460 | return tipc_node_bc_rcv(net, skb, bearer_id); | 1461 | return tipc_node_bc_rcv(net, skb, bearer_id); |
1461 | } | 1462 | } |
1462 | 1463 | ||
1464 | /* Discard unicast link messages destined for another node */ | ||
1465 | if (unlikely(!msg_short(hdr) && (msg_destnode(hdr) != self))) | ||
1466 | goto discard; | ||
1467 | |||
1463 | /* Locate neighboring node that sent packet */ | 1468 | /* Locate neighboring node that sent packet */ |
1464 | n = tipc_node_find(net, msg_prevnode(hdr)); | 1469 | n = tipc_node_find(net, msg_prevnode(hdr)); |
1465 | if (unlikely(!n)) | 1470 | if (unlikely(!n)) |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 0a369bb440e7..56214736fe88 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -842,7 +842,7 @@ static void vmci_transport_peer_detach_cb(u32 sub_id, | |||
842 | * qp_handle. | 842 | * qp_handle. |
843 | */ | 843 | */ |
844 | if (vmci_handle_is_invalid(e_payload->handle) || | 844 | if (vmci_handle_is_invalid(e_payload->handle) || |
845 | vmci_handle_is_equal(trans->qp_handle, e_payload->handle)) | 845 | !vmci_handle_is_equal(trans->qp_handle, e_payload->handle)) |
846 | return; | 846 | return; |
847 | 847 | ||
848 | /* We don't ask for delayed CBs when we subscribe to this event (we | 848 | /* We don't ask for delayed CBs when we subscribe to this event (we |
@@ -1735,11 +1735,8 @@ static int vmci_transport_dgram_dequeue(struct vsock_sock *vsk, | |||
1735 | /* Retrieve the head sk_buff from the socket's receive queue. */ | 1735 | /* Retrieve the head sk_buff from the socket's receive queue. */ |
1736 | err = 0; | 1736 | err = 0; |
1737 | skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); | 1737 | skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); |
1738 | if (err) | ||
1739 | return err; | ||
1740 | |||
1741 | if (!skb) | 1738 | if (!skb) |
1742 | return -EAGAIN; | 1739 | return err; |
1743 | 1740 | ||
1744 | dg = (struct vmci_datagram *)skb->data; | 1741 | dg = (struct vmci_datagram *)skb->data; |
1745 | if (!dg) | 1742 | if (!dg) |
@@ -2154,7 +2151,7 @@ module_exit(vmci_transport_exit); | |||
2154 | 2151 | ||
2155 | MODULE_AUTHOR("VMware, Inc."); | 2152 | MODULE_AUTHOR("VMware, Inc."); |
2156 | MODULE_DESCRIPTION("VMCI transport for Virtual Sockets"); | 2153 | MODULE_DESCRIPTION("VMCI transport for Virtual Sockets"); |
2157 | MODULE_VERSION("1.0.2.0-k"); | 2154 | MODULE_VERSION("1.0.4.0-k"); |
2158 | MODULE_LICENSE("GPL v2"); | 2155 | MODULE_LICENSE("GPL v2"); |
2159 | MODULE_ALIAS("vmware_vsock"); | 2156 | MODULE_ALIAS("vmware_vsock"); |
2160 | MODULE_ALIAS_NETPROTO(PF_VSOCK); | 2157 | MODULE_ALIAS_NETPROTO(PF_VSOCK); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 98c924260b3d..056a7307862b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -13216,7 +13216,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
13216 | struct wireless_dev *wdev; | 13216 | struct wireless_dev *wdev; |
13217 | struct cfg80211_beacon_registration *reg, *tmp; | 13217 | struct cfg80211_beacon_registration *reg, *tmp; |
13218 | 13218 | ||
13219 | if (state != NETLINK_URELEASE) | 13219 | if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC) |
13220 | return NOTIFY_DONE; | 13220 | return NOTIFY_DONE; |
13221 | 13221 | ||
13222 | rcu_read_lock(); | 13222 | rcu_read_lock(); |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index ad7f5b3f9b61..1c4ad477ce93 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -292,12 +292,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
292 | XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; | 292 | XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; |
293 | 293 | ||
294 | skb_dst_force(skb); | 294 | skb_dst_force(skb); |
295 | dev_hold(skb->dev); | ||
295 | 296 | ||
296 | nexthdr = x->type->input(x, skb); | 297 | nexthdr = x->type->input(x, skb); |
297 | 298 | ||
298 | if (nexthdr == -EINPROGRESS) | 299 | if (nexthdr == -EINPROGRESS) |
299 | return 0; | 300 | return 0; |
300 | resume: | 301 | resume: |
302 | dev_put(skb->dev); | ||
303 | |||
301 | spin_lock(&x->lock); | 304 | spin_lock(&x->lock); |
302 | if (nexthdr <= 0) { | 305 | if (nexthdr <= 0) { |
303 | if (nexthdr == -EBADMSG) { | 306 | if (nexthdr == -EBADMSG) { |