diff options
Diffstat (limited to 'net')
117 files changed, 1148 insertions, 566 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 175273f38cb1..44ebd5c2cd4a 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -169,6 +169,7 @@ int register_vlan_dev(struct net_device *dev) | |||
169 | if (err < 0) | 169 | if (err < 0) |
170 | goto out_uninit_mvrp; | 170 | goto out_uninit_mvrp; |
171 | 171 | ||
172 | vlan->nest_level = dev_get_nest_level(real_dev, is_vlan_dev) + 1; | ||
172 | err = register_netdevice(dev); | 173 | err = register_netdevice(dev); |
173 | if (err < 0) | 174 | if (err < 0) |
174 | goto out_uninit_mvrp; | 175 | goto out_uninit_mvrp; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6f142f03716d..019efb79708f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -524,6 +524,11 @@ static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass) | |||
524 | netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); | 524 | netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); |
525 | } | 525 | } |
526 | 526 | ||
527 | static int vlan_dev_get_lock_subclass(struct net_device *dev) | ||
528 | { | ||
529 | return vlan_dev_priv(dev)->nest_level; | ||
530 | } | ||
531 | |||
527 | static const struct header_ops vlan_header_ops = { | 532 | static const struct header_ops vlan_header_ops = { |
528 | .create = vlan_dev_hard_header, | 533 | .create = vlan_dev_hard_header, |
529 | .rebuild = vlan_dev_rebuild_header, | 534 | .rebuild = vlan_dev_rebuild_header, |
@@ -559,7 +564,6 @@ static const struct net_device_ops vlan_netdev_ops; | |||
559 | static int vlan_dev_init(struct net_device *dev) | 564 | static int vlan_dev_init(struct net_device *dev) |
560 | { | 565 | { |
561 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 566 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; |
562 | int subclass = 0; | ||
563 | 567 | ||
564 | netif_carrier_off(dev); | 568 | netif_carrier_off(dev); |
565 | 569 | ||
@@ -608,10 +612,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
608 | 612 | ||
609 | SET_NETDEV_DEVTYPE(dev, &vlan_type); | 613 | SET_NETDEV_DEVTYPE(dev, &vlan_type); |
610 | 614 | ||
611 | if (is_vlan_dev(real_dev)) | 615 | vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); |
612 | subclass = 1; | ||
613 | |||
614 | vlan_dev_set_lockdep_class(dev, subclass); | ||
615 | 616 | ||
616 | vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); | 617 | vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); |
617 | if (!vlan_dev_priv(dev)->vlan_pcpu_stats) | 618 | if (!vlan_dev_priv(dev)->vlan_pcpu_stats) |
@@ -783,6 +784,7 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
783 | .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, | 784 | .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, |
784 | #endif | 785 | #endif |
785 | .ndo_fix_features = vlan_dev_fix_features, | 786 | .ndo_fix_features = vlan_dev_fix_features, |
787 | .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, | ||
786 | }; | 788 | }; |
787 | 789 | ||
788 | void vlan_setup(struct net_device *dev) | 790 | void vlan_setup(struct net_device *dev) |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index b3bd4ec3fd94..f04224c32005 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -1545,6 +1545,8 @@ out_neigh: | |||
1545 | if ((orig_neigh_node) && (!is_single_hop_neigh)) | 1545 | if ((orig_neigh_node) && (!is_single_hop_neigh)) |
1546 | batadv_orig_node_free_ref(orig_neigh_node); | 1546 | batadv_orig_node_free_ref(orig_neigh_node); |
1547 | out: | 1547 | out: |
1548 | if (router_ifinfo) | ||
1549 | batadv_neigh_ifinfo_free_ref(router_ifinfo); | ||
1548 | if (router) | 1550 | if (router) |
1549 | batadv_neigh_node_free_ref(router); | 1551 | batadv_neigh_node_free_ref(router); |
1550 | if (router_router) | 1552 | if (router_router) |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index b25fd64d727b..aa5d4946d0d7 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -940,8 +940,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | |||
940 | * additional DAT answer may trigger kernel warnings about | 940 | * additional DAT answer may trigger kernel warnings about |
941 | * a packet coming from the wrong port. | 941 | * a packet coming from the wrong port. |
942 | */ | 942 | */ |
943 | if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, | 943 | if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { |
944 | BATADV_NO_FLAGS)) { | ||
945 | ret = true; | 944 | ret = true; |
946 | goto out; | 945 | goto out; |
947 | } | 946 | } |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index bcc4bea632fa..f14e54a05691 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -418,12 +418,13 @@ bool batadv_frag_send_packet(struct sk_buff *skb, | |||
418 | struct batadv_neigh_node *neigh_node) | 418 | struct batadv_neigh_node *neigh_node) |
419 | { | 419 | { |
420 | struct batadv_priv *bat_priv; | 420 | struct batadv_priv *bat_priv; |
421 | struct batadv_hard_iface *primary_if; | 421 | struct batadv_hard_iface *primary_if = NULL; |
422 | struct batadv_frag_packet frag_header; | 422 | struct batadv_frag_packet frag_header; |
423 | struct sk_buff *skb_fragment; | 423 | struct sk_buff *skb_fragment; |
424 | unsigned mtu = neigh_node->if_incoming->net_dev->mtu; | 424 | unsigned mtu = neigh_node->if_incoming->net_dev->mtu; |
425 | unsigned header_size = sizeof(frag_header); | 425 | unsigned header_size = sizeof(frag_header); |
426 | unsigned max_fragment_size, max_packet_size; | 426 | unsigned max_fragment_size, max_packet_size; |
427 | bool ret = false; | ||
427 | 428 | ||
428 | /* To avoid merge and refragmentation at next-hops we never send | 429 | /* To avoid merge and refragmentation at next-hops we never send |
429 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE | 430 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE |
@@ -483,7 +484,11 @@ bool batadv_frag_send_packet(struct sk_buff *skb, | |||
483 | skb->len + ETH_HLEN); | 484 | skb->len + ETH_HLEN); |
484 | batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); | 485 | batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); |
485 | 486 | ||
486 | return true; | 487 | ret = true; |
488 | |||
487 | out_err: | 489 | out_err: |
488 | return false; | 490 | if (primary_if) |
491 | batadv_hardif_free_ref(primary_if); | ||
492 | |||
493 | return ret; | ||
489 | } | 494 | } |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index c835e137423b..90cff585b37d 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -42,8 +42,10 @@ | |||
42 | 42 | ||
43 | static void batadv_gw_node_free_ref(struct batadv_gw_node *gw_node) | 43 | static void batadv_gw_node_free_ref(struct batadv_gw_node *gw_node) |
44 | { | 44 | { |
45 | if (atomic_dec_and_test(&gw_node->refcount)) | 45 | if (atomic_dec_and_test(&gw_node->refcount)) { |
46 | batadv_orig_node_free_ref(gw_node->orig_node); | ||
46 | kfree_rcu(gw_node, rcu); | 47 | kfree_rcu(gw_node, rcu); |
48 | } | ||
47 | } | 49 | } |
48 | 50 | ||
49 | static struct batadv_gw_node * | 51 | static struct batadv_gw_node * |
@@ -406,9 +408,14 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, | |||
406 | if (gateway->bandwidth_down == 0) | 408 | if (gateway->bandwidth_down == 0) |
407 | return; | 409 | return; |
408 | 410 | ||
411 | if (!atomic_inc_not_zero(&orig_node->refcount)) | ||
412 | return; | ||
413 | |||
409 | gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); | 414 | gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); |
410 | if (!gw_node) | 415 | if (!gw_node) { |
416 | batadv_orig_node_free_ref(orig_node); | ||
411 | return; | 417 | return; |
418 | } | ||
412 | 419 | ||
413 | INIT_HLIST_NODE(&gw_node->list); | 420 | INIT_HLIST_NODE(&gw_node->list); |
414 | gw_node->orig_node = orig_node; | 421 | gw_node->orig_node = orig_node; |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index b851cc580853..fbda6b54baff 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -83,7 +83,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) | |||
83 | return true; | 83 | return true; |
84 | 84 | ||
85 | /* no more parents..stop recursion */ | 85 | /* no more parents..stop recursion */ |
86 | if (net_dev->iflink == net_dev->ifindex) | 86 | if (net_dev->iflink == 0 || net_dev->iflink == net_dev->ifindex) |
87 | return false; | 87 | return false; |
88 | 88 | ||
89 | /* recurse over the parent device */ | 89 | /* recurse over the parent device */ |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ffd9dfbd9b0e..6a484514cd3e 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -501,12 +501,17 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node, | |||
501 | static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) | 501 | static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) |
502 | { | 502 | { |
503 | struct batadv_orig_ifinfo *orig_ifinfo; | 503 | struct batadv_orig_ifinfo *orig_ifinfo; |
504 | struct batadv_neigh_node *router; | ||
504 | 505 | ||
505 | orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu); | 506 | orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu); |
506 | 507 | ||
507 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) | 508 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) |
508 | batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing); | 509 | batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing); |
509 | 510 | ||
511 | /* this is the last reference to this object */ | ||
512 | router = rcu_dereference_protected(orig_ifinfo->router, true); | ||
513 | if (router) | ||
514 | batadv_neigh_node_free_ref_now(router); | ||
510 | kfree(orig_ifinfo); | 515 | kfree(orig_ifinfo); |
511 | } | 516 | } |
512 | 517 | ||
@@ -702,6 +707,47 @@ free_orig_node: | |||
702 | } | 707 | } |
703 | 708 | ||
704 | /** | 709 | /** |
710 | * batadv_purge_neigh_ifinfo - purge obsolete ifinfo entries from neighbor | ||
711 | * @bat_priv: the bat priv with all the soft interface information | ||
712 | * @neigh: orig node which is to be checked | ||
713 | */ | ||
714 | static void | ||
715 | batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv, | ||
716 | struct batadv_neigh_node *neigh) | ||
717 | { | ||
718 | struct batadv_neigh_ifinfo *neigh_ifinfo; | ||
719 | struct batadv_hard_iface *if_outgoing; | ||
720 | struct hlist_node *node_tmp; | ||
721 | |||
722 | spin_lock_bh(&neigh->ifinfo_lock); | ||
723 | |||
724 | /* for all ifinfo objects for this neighinator */ | ||
725 | hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, | ||
726 | &neigh->ifinfo_list, list) { | ||
727 | if_outgoing = neigh_ifinfo->if_outgoing; | ||
728 | |||
729 | /* always keep the default interface */ | ||
730 | if (if_outgoing == BATADV_IF_DEFAULT) | ||
731 | continue; | ||
732 | |||
733 | /* don't purge if the interface is not (going) down */ | ||
734 | if ((if_outgoing->if_status != BATADV_IF_INACTIVE) && | ||
735 | (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) && | ||
736 | (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)) | ||
737 | continue; | ||
738 | |||
739 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
740 | "neighbor/ifinfo purge: neighbor %pM, iface: %s\n", | ||
741 | neigh->addr, if_outgoing->net_dev->name); | ||
742 | |||
743 | hlist_del_rcu(&neigh_ifinfo->list); | ||
744 | batadv_neigh_ifinfo_free_ref(neigh_ifinfo); | ||
745 | } | ||
746 | |||
747 | spin_unlock_bh(&neigh->ifinfo_lock); | ||
748 | } | ||
749 | |||
750 | /** | ||
705 | * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator | 751 | * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator |
706 | * @bat_priv: the bat priv with all the soft interface information | 752 | * @bat_priv: the bat priv with all the soft interface information |
707 | * @orig_node: orig node which is to be checked | 753 | * @orig_node: orig node which is to be checked |
@@ -800,6 +846,11 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, | |||
800 | 846 | ||
801 | hlist_del_rcu(&neigh_node->list); | 847 | hlist_del_rcu(&neigh_node->list); |
802 | batadv_neigh_node_free_ref(neigh_node); | 848 | batadv_neigh_node_free_ref(neigh_node); |
849 | } else { | ||
850 | /* only necessary if not the whole neighbor is to be | ||
851 | * deleted, but some interface has been removed. | ||
852 | */ | ||
853 | batadv_purge_neigh_ifinfo(bat_priv, neigh_node); | ||
803 | } | 854 | } |
804 | } | 855 | } |
805 | 856 | ||
@@ -857,7 +908,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
857 | { | 908 | { |
858 | struct batadv_neigh_node *best_neigh_node; | 909 | struct batadv_neigh_node *best_neigh_node; |
859 | struct batadv_hard_iface *hard_iface; | 910 | struct batadv_hard_iface *hard_iface; |
860 | bool changed; | 911 | bool changed_ifinfo, changed_neigh; |
861 | 912 | ||
862 | if (batadv_has_timed_out(orig_node->last_seen, | 913 | if (batadv_has_timed_out(orig_node->last_seen, |
863 | 2 * BATADV_PURGE_TIMEOUT)) { | 914 | 2 * BATADV_PURGE_TIMEOUT)) { |
@@ -867,10 +918,10 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
867 | jiffies_to_msecs(orig_node->last_seen)); | 918 | jiffies_to_msecs(orig_node->last_seen)); |
868 | return true; | 919 | return true; |
869 | } | 920 | } |
870 | changed = batadv_purge_orig_ifinfo(bat_priv, orig_node); | 921 | changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node); |
871 | changed = changed || batadv_purge_orig_neighbors(bat_priv, orig_node); | 922 | changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node); |
872 | 923 | ||
873 | if (!changed) | 924 | if (!changed_ifinfo && !changed_neigh) |
874 | return false; | 925 | return false; |
875 | 926 | ||
876 | /* first for NULL ... */ | 927 | /* first for NULL ... */ |
@@ -1028,7 +1079,8 @@ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset) | |||
1028 | bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq, hard_iface); | 1079 | bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq, hard_iface); |
1029 | 1080 | ||
1030 | out: | 1081 | out: |
1031 | batadv_hardif_free_ref(hard_iface); | 1082 | if (hard_iface) |
1083 | batadv_hardif_free_ref(hard_iface); | ||
1032 | return 0; | 1084 | return 0; |
1033 | } | 1085 | } |
1034 | 1086 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d958e2dca52f..521fd4f3985e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -819,14 +819,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
819 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { | 819 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { |
820 | struct hci_cp_auth_requested cp; | 820 | struct hci_cp_auth_requested cp; |
821 | 821 | ||
822 | /* encrypt must be pending if auth is also pending */ | ||
823 | set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||
824 | |||
825 | cp.handle = cpu_to_le16(conn->handle); | 822 | cp.handle = cpu_to_le16(conn->handle); |
826 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 823 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
827 | sizeof(cp), &cp); | 824 | sizeof(cp), &cp); |
825 | |||
826 | /* If we're already encrypted set the REAUTH_PEND flag, | ||
827 | * otherwise set the ENCRYPT_PEND. | ||
828 | */ | ||
828 | if (conn->key_type != 0xff) | 829 | if (conn->key_type != 0xff) |
829 | set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); | 830 | set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); |
831 | else | ||
832 | set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||
830 | } | 833 | } |
831 | 834 | ||
832 | return 0; | 835 | return 0; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 49774912cb01..15010a230b6d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -3330,6 +3330,12 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | |||
3330 | if (!conn) | 3330 | if (!conn) |
3331 | goto unlock; | 3331 | goto unlock; |
3332 | 3332 | ||
3333 | /* For BR/EDR the necessary steps are taken through the | ||
3334 | * auth_complete event. | ||
3335 | */ | ||
3336 | if (conn->type != LE_LINK) | ||
3337 | goto unlock; | ||
3338 | |||
3333 | if (!ev->status) | 3339 | if (!ev->status) |
3334 | conn->sec_level = conn->pending_sec_level; | 3340 | conn->sec_level = conn->pending_sec_level; |
3335 | 3341 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 80e1b0f60a30..2acf7fa1fec6 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -859,12 +859,12 @@ static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops, | |||
859 | return NF_STOLEN; | 859 | return NF_STOLEN; |
860 | } | 860 | } |
861 | 861 | ||
862 | #if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV4) | 862 | #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) |
863 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) | 863 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) |
864 | { | 864 | { |
865 | int ret; | 865 | int ret; |
866 | 866 | ||
867 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && | 867 | if (skb->protocol == htons(ETH_P_IP) && |
868 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && | 868 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && |
869 | !skb_is_gso(skb)) { | 869 | !skb_is_gso(skb)) { |
870 | if (br_parse_ip_options(skb)) | 870 | if (br_parse_ip_options(skb)) |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index e74b6d530cb6..e8844d975b32 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -445,6 +445,20 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | 447 | ||
448 | static int br_dev_newlink(struct net *src_net, struct net_device *dev, | ||
449 | struct nlattr *tb[], struct nlattr *data[]) | ||
450 | { | ||
451 | struct net_bridge *br = netdev_priv(dev); | ||
452 | |||
453 | if (tb[IFLA_ADDRESS]) { | ||
454 | spin_lock_bh(&br->lock); | ||
455 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); | ||
456 | spin_unlock_bh(&br->lock); | ||
457 | } | ||
458 | |||
459 | return register_netdevice(dev); | ||
460 | } | ||
461 | |||
448 | static size_t br_get_link_af_size(const struct net_device *dev) | 462 | static size_t br_get_link_af_size(const struct net_device *dev) |
449 | { | 463 | { |
450 | struct net_port_vlans *pv; | 464 | struct net_port_vlans *pv; |
@@ -473,6 +487,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = { | |||
473 | .priv_size = sizeof(struct net_bridge), | 487 | .priv_size = sizeof(struct net_bridge), |
474 | .setup = br_dev_setup, | 488 | .setup = br_dev_setup, |
475 | .validate = br_validate, | 489 | .validate = br_validate, |
490 | .newlink = br_dev_newlink, | ||
476 | .dellink = br_dev_delete, | 491 | .dellink = br_dev_delete, |
477 | }; | 492 | }; |
478 | 493 | ||
diff --git a/net/can/gw.c b/net/can/gw.c index ac31891967da..050a2110d43f 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -804,7 +804,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
804 | u8 limhops = 0; | 804 | u8 limhops = 0; |
805 | int err = 0; | 805 | int err = 0; |
806 | 806 | ||
807 | if (!capable(CAP_NET_ADMIN)) | 807 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
808 | return -EPERM; | 808 | return -EPERM; |
809 | 809 | ||
810 | if (nlmsg_len(nlh) < sizeof(*r)) | 810 | if (nlmsg_len(nlh) < sizeof(*r)) |
@@ -893,7 +893,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
893 | u8 limhops = 0; | 893 | u8 limhops = 0; |
894 | int err = 0; | 894 | int err = 0; |
895 | 895 | ||
896 | if (!capable(CAP_NET_ADMIN)) | 896 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
897 | return -EPERM; | 897 | return -EPERM; |
898 | 898 | ||
899 | if (nlmsg_len(nlh) < sizeof(*r)) | 899 | if (nlmsg_len(nlh) < sizeof(*r)) |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index dac7f9b98687..1948d592aa54 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -557,7 +557,7 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov, | |||
557 | return r; | 557 | return r; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | 560 | static int __ceph_tcp_sendpage(struct socket *sock, struct page *page, |
561 | int offset, size_t size, bool more) | 561 | int offset, size_t size, bool more) |
562 | { | 562 | { |
563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); | 563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); |
@@ -570,6 +570,24 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | |||
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | 572 | ||
573 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | ||
574 | int offset, size_t size, bool more) | ||
575 | { | ||
576 | int ret; | ||
577 | struct kvec iov; | ||
578 | |||
579 | /* sendpage cannot properly handle pages with page_count == 0, | ||
580 | * we need to fallback to sendmsg if that's the case */ | ||
581 | if (page_count(page) >= 1) | ||
582 | return __ceph_tcp_sendpage(sock, page, offset, size, more); | ||
583 | |||
584 | iov.iov_base = kmap(page) + offset; | ||
585 | iov.iov_len = size; | ||
586 | ret = ceph_tcp_sendmsg(sock, &iov, 1, size, more); | ||
587 | kunmap(page); | ||
588 | |||
589 | return ret; | ||
590 | } | ||
573 | 591 | ||
574 | /* | 592 | /* |
575 | * Shutdown/close the socket for the given connection. | 593 | * Shutdown/close the socket for the given connection. |
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index e632b5a52f5b..c547e46084d3 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -329,6 +329,11 @@ static struct crush_map *crush_decode(void *pbyval, void *end) | |||
329 | dout("crush decode tunable chooseleaf_descend_once = %d", | 329 | dout("crush decode tunable chooseleaf_descend_once = %d", |
330 | c->chooseleaf_descend_once); | 330 | c->chooseleaf_descend_once); |
331 | 331 | ||
332 | ceph_decode_need(p, end, sizeof(u8), done); | ||
333 | c->chooseleaf_vary_r = ceph_decode_8(p); | ||
334 | dout("crush decode tunable chooseleaf_vary_r = %d", | ||
335 | c->chooseleaf_vary_r); | ||
336 | |||
332 | done: | 337 | done: |
333 | dout("crush_decode success\n"); | 338 | dout("crush_decode success\n"); |
334 | return c; | 339 | return c; |
@@ -1548,8 +1553,10 @@ static void apply_primary_affinity(struct ceph_osdmap *osdmap, u32 pps, | |||
1548 | return; | 1553 | return; |
1549 | 1554 | ||
1550 | for (i = 0; i < len; i++) { | 1555 | for (i = 0; i < len; i++) { |
1551 | if (osds[i] != CRUSH_ITEM_NONE && | 1556 | int osd = osds[i]; |
1552 | osdmap->osd_primary_affinity[i] != | 1557 | |
1558 | if (osd != CRUSH_ITEM_NONE && | ||
1559 | osdmap->osd_primary_affinity[osd] != | ||
1553 | CEPH_OSD_DEFAULT_PRIMARY_AFFINITY) { | 1560 | CEPH_OSD_DEFAULT_PRIMARY_AFFINITY) { |
1554 | break; | 1561 | break; |
1555 | } | 1562 | } |
@@ -1563,10 +1570,9 @@ static void apply_primary_affinity(struct ceph_osdmap *osdmap, u32 pps, | |||
1563 | * osd's pgs get rejected as primary. | 1570 | * osd's pgs get rejected as primary. |
1564 | */ | 1571 | */ |
1565 | for (i = 0; i < len; i++) { | 1572 | for (i = 0; i < len; i++) { |
1566 | int osd; | 1573 | int osd = osds[i]; |
1567 | u32 aff; | 1574 | u32 aff; |
1568 | 1575 | ||
1569 | osd = osds[i]; | ||
1570 | if (osd == CRUSH_ITEM_NONE) | 1576 | if (osd == CRUSH_ITEM_NONE) |
1571 | continue; | 1577 | continue; |
1572 | 1578 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 14dac0654f28..9abc503b19b7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2284,7 +2284,7 @@ EXPORT_SYMBOL(skb_checksum_help); | |||
2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) | 2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) |
2285 | { | 2285 | { |
2286 | __be16 type = skb->protocol; | 2286 | __be16 type = skb->protocol; |
2287 | int vlan_depth = ETH_HLEN; | 2287 | int vlan_depth = skb->mac_len; |
2288 | 2288 | ||
2289 | /* Tunnel gso handlers can set protocol to ethernet. */ | 2289 | /* Tunnel gso handlers can set protocol to ethernet. */ |
2290 | if (type == htons(ETH_P_TEB)) { | 2290 | if (type == htons(ETH_P_TEB)) { |
@@ -2418,7 +2418,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault); | |||
2418 | * 2. No high memory really exists on this machine. | 2418 | * 2. No high memory really exists on this machine. |
2419 | */ | 2419 | */ |
2420 | 2420 | ||
2421 | static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb) | 2421 | static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) |
2422 | { | 2422 | { |
2423 | #ifdef CONFIG_HIGHMEM | 2423 | #ifdef CONFIG_HIGHMEM |
2424 | int i; | 2424 | int i; |
@@ -2493,38 +2493,36 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) | |||
2493 | } | 2493 | } |
2494 | 2494 | ||
2495 | static netdev_features_t harmonize_features(struct sk_buff *skb, | 2495 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2496 | const struct net_device *dev, | 2496 | netdev_features_t features) |
2497 | netdev_features_t features) | ||
2498 | { | 2497 | { |
2499 | int tmp; | 2498 | int tmp; |
2500 | 2499 | ||
2501 | if (skb->ip_summed != CHECKSUM_NONE && | 2500 | if (skb->ip_summed != CHECKSUM_NONE && |
2502 | !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) { | 2501 | !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) { |
2503 | features &= ~NETIF_F_ALL_CSUM; | 2502 | features &= ~NETIF_F_ALL_CSUM; |
2504 | } else if (illegal_highdma(dev, skb)) { | 2503 | } else if (illegal_highdma(skb->dev, skb)) { |
2505 | features &= ~NETIF_F_SG; | 2504 | features &= ~NETIF_F_SG; |
2506 | } | 2505 | } |
2507 | 2506 | ||
2508 | return features; | 2507 | return features; |
2509 | } | 2508 | } |
2510 | 2509 | ||
2511 | netdev_features_t netif_skb_dev_features(struct sk_buff *skb, | 2510 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
2512 | const struct net_device *dev) | ||
2513 | { | 2511 | { |
2514 | __be16 protocol = skb->protocol; | 2512 | __be16 protocol = skb->protocol; |
2515 | netdev_features_t features = dev->features; | 2513 | netdev_features_t features = skb->dev->features; |
2516 | 2514 | ||
2517 | if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs) | 2515 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) |
2518 | features &= ~NETIF_F_GSO_MASK; | 2516 | features &= ~NETIF_F_GSO_MASK; |
2519 | 2517 | ||
2520 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { | 2518 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { |
2521 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2519 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2522 | protocol = veh->h_vlan_encapsulated_proto; | 2520 | protocol = veh->h_vlan_encapsulated_proto; |
2523 | } else if (!vlan_tx_tag_present(skb)) { | 2521 | } else if (!vlan_tx_tag_present(skb)) { |
2524 | return harmonize_features(skb, dev, features); | 2522 | return harmonize_features(skb, features); |
2525 | } | 2523 | } |
2526 | 2524 | ||
2527 | features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | | 2525 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | |
2528 | NETIF_F_HW_VLAN_STAG_TX); | 2526 | NETIF_F_HW_VLAN_STAG_TX); |
2529 | 2527 | ||
2530 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) | 2528 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) |
@@ -2532,9 +2530,9 @@ netdev_features_t netif_skb_dev_features(struct sk_buff *skb, | |||
2532 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | | 2530 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | |
2533 | NETIF_F_HW_VLAN_STAG_TX; | 2531 | NETIF_F_HW_VLAN_STAG_TX; |
2534 | 2532 | ||
2535 | return harmonize_features(skb, dev, features); | 2533 | return harmonize_features(skb, features); |
2536 | } | 2534 | } |
2537 | EXPORT_SYMBOL(netif_skb_dev_features); | 2535 | EXPORT_SYMBOL(netif_skb_features); |
2538 | 2536 | ||
2539 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 2537 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
2540 | struct netdev_queue *txq) | 2538 | struct netdev_queue *txq) |
@@ -3953,6 +3951,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
3953 | } | 3951 | } |
3954 | NAPI_GRO_CB(skb)->count = 1; | 3952 | NAPI_GRO_CB(skb)->count = 1; |
3955 | NAPI_GRO_CB(skb)->age = jiffies; | 3953 | NAPI_GRO_CB(skb)->age = jiffies; |
3954 | NAPI_GRO_CB(skb)->last = skb; | ||
3956 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); | 3955 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); |
3957 | skb->next = napi->gro_list; | 3956 | skb->next = napi->gro_list; |
3958 | napi->gro_list = skb; | 3957 | napi->gro_list = skb; |
@@ -4543,6 +4542,32 @@ void *netdev_adjacent_get_private(struct list_head *adj_list) | |||
4543 | EXPORT_SYMBOL(netdev_adjacent_get_private); | 4542 | EXPORT_SYMBOL(netdev_adjacent_get_private); |
4544 | 4543 | ||
4545 | /** | 4544 | /** |
4545 | * netdev_upper_get_next_dev_rcu - Get the next dev from upper list | ||
4546 | * @dev: device | ||
4547 | * @iter: list_head ** of the current position | ||
4548 | * | ||
4549 | * Gets the next device from the dev's upper list, starting from iter | ||
4550 | * position. The caller must hold RCU read lock. | ||
4551 | */ | ||
4552 | struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, | ||
4553 | struct list_head **iter) | ||
4554 | { | ||
4555 | struct netdev_adjacent *upper; | ||
4556 | |||
4557 | WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); | ||
4558 | |||
4559 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | ||
4560 | |||
4561 | if (&upper->list == &dev->adj_list.upper) | ||
4562 | return NULL; | ||
4563 | |||
4564 | *iter = &upper->list; | ||
4565 | |||
4566 | return upper->dev; | ||
4567 | } | ||
4568 | EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); | ||
4569 | |||
4570 | /** | ||
4546 | * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list | 4571 | * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list |
4547 | * @dev: device | 4572 | * @dev: device |
4548 | * @iter: list_head ** of the current position | 4573 | * @iter: list_head ** of the current position |
@@ -4624,6 +4649,32 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev, | |||
4624 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); | 4649 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); |
4625 | 4650 | ||
4626 | /** | 4651 | /** |
4652 | * netdev_lower_get_next - Get the next device from the lower neighbour | ||
4653 | * list | ||
4654 | * @dev: device | ||
4655 | * @iter: list_head ** of the current position | ||
4656 | * | ||
4657 | * Gets the next netdev_adjacent from the dev's lower neighbour | ||
4658 | * list, starting from iter position. The caller must hold RTNL lock or | ||
4659 | * its own locking that guarantees that the neighbour lower | ||
4660 | * list will remain unchainged. | ||
4661 | */ | ||
4662 | void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter) | ||
4663 | { | ||
4664 | struct netdev_adjacent *lower; | ||
4665 | |||
4666 | lower = list_entry((*iter)->next, struct netdev_adjacent, list); | ||
4667 | |||
4668 | if (&lower->list == &dev->adj_list.lower) | ||
4669 | return NULL; | ||
4670 | |||
4671 | *iter = &lower->list; | ||
4672 | |||
4673 | return lower->dev; | ||
4674 | } | ||
4675 | EXPORT_SYMBOL(netdev_lower_get_next); | ||
4676 | |||
4677 | /** | ||
4627 | * netdev_lower_get_first_private_rcu - Get the first ->private from the | 4678 | * netdev_lower_get_first_private_rcu - Get the first ->private from the |
4628 | * lower neighbour list, RCU | 4679 | * lower neighbour list, RCU |
4629 | * variant | 4680 | * variant |
@@ -5073,6 +5124,30 @@ void *netdev_lower_dev_get_private(struct net_device *dev, | |||
5073 | } | 5124 | } |
5074 | EXPORT_SYMBOL(netdev_lower_dev_get_private); | 5125 | EXPORT_SYMBOL(netdev_lower_dev_get_private); |
5075 | 5126 | ||
5127 | |||
5128 | int dev_get_nest_level(struct net_device *dev, | ||
5129 | bool (*type_check)(struct net_device *dev)) | ||
5130 | { | ||
5131 | struct net_device *lower = NULL; | ||
5132 | struct list_head *iter; | ||
5133 | int max_nest = -1; | ||
5134 | int nest; | ||
5135 | |||
5136 | ASSERT_RTNL(); | ||
5137 | |||
5138 | netdev_for_each_lower_dev(dev, lower, iter) { | ||
5139 | nest = dev_get_nest_level(lower, type_check); | ||
5140 | if (max_nest < nest) | ||
5141 | max_nest = nest; | ||
5142 | } | ||
5143 | |||
5144 | if (type_check(dev)) | ||
5145 | max_nest++; | ||
5146 | |||
5147 | return max_nest; | ||
5148 | } | ||
5149 | EXPORT_SYMBOL(dev_get_nest_level); | ||
5150 | |||
5076 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 5151 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
5077 | { | 5152 | { |
5078 | const struct net_device_ops *ops = dev->netdev_ops; | 5153 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -5542,7 +5617,7 @@ static int dev_new_index(struct net *net) | |||
5542 | 5617 | ||
5543 | /* Delayed registration/unregisteration */ | 5618 | /* Delayed registration/unregisteration */ |
5544 | static LIST_HEAD(net_todo_list); | 5619 | static LIST_HEAD(net_todo_list); |
5545 | static DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq); | 5620 | DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq); |
5546 | 5621 | ||
5547 | static void net_set_todo(struct net_device *dev) | 5622 | static void net_set_todo(struct net_device *dev) |
5548 | { | 5623 | { |
diff --git a/net/core/dst.c b/net/core/dst.c index ca4231ec7347..80d6286c8b62 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -142,12 +142,12 @@ loop: | |||
142 | mutex_unlock(&dst_gc_mutex); | 142 | mutex_unlock(&dst_gc_mutex); |
143 | } | 143 | } |
144 | 144 | ||
145 | int dst_discard(struct sk_buff *skb) | 145 | int dst_discard_sk(struct sock *sk, struct sk_buff *skb) |
146 | { | 146 | { |
147 | kfree_skb(skb); | 147 | kfree_skb(skb); |
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | EXPORT_SYMBOL(dst_discard); | 150 | EXPORT_SYMBOL(dst_discard_sk); |
151 | 151 | ||
152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { | 152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { |
153 | /* This initializer is needed to force linker to place this variable | 153 | /* This initializer is needed to force linker to place this variable |
@@ -184,7 +184,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
184 | dst->xfrm = NULL; | 184 | dst->xfrm = NULL; |
185 | #endif | 185 | #endif |
186 | dst->input = dst_discard; | 186 | dst->input = dst_discard; |
187 | dst->output = dst_discard; | 187 | dst->output = dst_discard_sk; |
188 | dst->error = 0; | 188 | dst->error = 0; |
189 | dst->obsolete = initial_obsolete; | 189 | dst->obsolete = initial_obsolete; |
190 | dst->header_len = 0; | 190 | dst->header_len = 0; |
@@ -209,8 +209,10 @@ static void ___dst_free(struct dst_entry *dst) | |||
209 | /* The first case (dev==NULL) is required, when | 209 | /* The first case (dev==NULL) is required, when |
210 | protocol module is unloaded. | 210 | protocol module is unloaded. |
211 | */ | 211 | */ |
212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) | 212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
213 | dst->input = dst->output = dst_discard; | 213 | dst->input = dst_discard; |
214 | dst->output = dst_discard_sk; | ||
215 | } | ||
214 | dst->obsolete = DST_OBSOLETE_DEAD; | 216 | dst->obsolete = DST_OBSOLETE_DEAD; |
215 | } | 217 | } |
216 | 218 | ||
@@ -361,7 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
361 | return; | 363 | return; |
362 | 364 | ||
363 | if (!unregister) { | 365 | if (!unregister) { |
364 | dst->input = dst->output = dst_discard; | 366 | dst->input = dst_discard; |
367 | dst->output = dst_discard_sk; | ||
365 | } else { | 368 | } else { |
366 | dst->dev = dev_net(dst->dev)->loopback_dev; | 369 | dst->dev = dev_net(dst->dev)->loopback_dev; |
367 | dev_hold(dst->dev); | 370 | dev_hold(dst->dev); |
diff --git a/net/core/filter.c b/net/core/filter.c index e08b3822c72a..9d79ca0a6e8e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -122,6 +122,13 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* Register mappings for user programs. */ | ||
126 | #define A_REG 0 | ||
127 | #define X_REG 7 | ||
128 | #define TMP_REG 8 | ||
129 | #define ARG2_REG 2 | ||
130 | #define ARG3_REG 3 | ||
131 | |||
125 | /** | 132 | /** |
126 | * __sk_run_filter - run a filter on a given context | 133 | * __sk_run_filter - run a filter on a given context |
127 | * @ctx: buffer to run the filter on | 134 | * @ctx: buffer to run the filter on |
@@ -242,6 +249,8 @@ unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn) | |||
242 | 249 | ||
243 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; | 250 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; |
244 | regs[ARG1_REG] = (u64) (unsigned long) ctx; | 251 | regs[ARG1_REG] = (u64) (unsigned long) ctx; |
252 | regs[A_REG] = 0; | ||
253 | regs[X_REG] = 0; | ||
245 | 254 | ||
246 | select_insn: | 255 | select_insn: |
247 | goto *jumptable[insn->code]; | 256 | goto *jumptable[insn->code]; |
@@ -600,6 +609,9 @@ static u64 __skb_get_nlattr(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
600 | if (skb_is_nonlinear(skb)) | 609 | if (skb_is_nonlinear(skb)) |
601 | return 0; | 610 | return 0; |
602 | 611 | ||
612 | if (skb->len < sizeof(struct nlattr)) | ||
613 | return 0; | ||
614 | |||
603 | if (A > skb->len - sizeof(struct nlattr)) | 615 | if (A > skb->len - sizeof(struct nlattr)) |
604 | return 0; | 616 | return 0; |
605 | 617 | ||
@@ -618,11 +630,14 @@ static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
618 | if (skb_is_nonlinear(skb)) | 630 | if (skb_is_nonlinear(skb)) |
619 | return 0; | 631 | return 0; |
620 | 632 | ||
633 | if (skb->len < sizeof(struct nlattr)) | ||
634 | return 0; | ||
635 | |||
621 | if (A > skb->len - sizeof(struct nlattr)) | 636 | if (A > skb->len - sizeof(struct nlattr)) |
622 | return 0; | 637 | return 0; |
623 | 638 | ||
624 | nla = (struct nlattr *) &skb->data[A]; | 639 | nla = (struct nlattr *) &skb->data[A]; |
625 | if (nla->nla_len > A - skb->len) | 640 | if (nla->nla_len > skb->len - A) |
626 | return 0; | 641 | return 0; |
627 | 642 | ||
628 | nla = nla_find_nested(nla, X); | 643 | nla = nla_find_nested(nla, X); |
@@ -637,13 +652,6 @@ static u64 __get_raw_cpu_id(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
637 | return raw_smp_processor_id(); | 652 | return raw_smp_processor_id(); |
638 | } | 653 | } |
639 | 654 | ||
640 | /* Register mappings for user programs. */ | ||
641 | #define A_REG 0 | ||
642 | #define X_REG 7 | ||
643 | #define TMP_REG 8 | ||
644 | #define ARG2_REG 2 | ||
645 | #define ARG3_REG 3 | ||
646 | |||
647 | static bool convert_bpf_extensions(struct sock_filter *fp, | 655 | static bool convert_bpf_extensions(struct sock_filter *fp, |
648 | struct sock_filter_int **insnp) | 656 | struct sock_filter_int **insnp) |
649 | { | 657 | { |
@@ -1737,7 +1745,6 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) | |||
1737 | [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, | 1745 | [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, |
1738 | [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, | 1746 | [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, |
1739 | [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, | 1747 | [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, |
1740 | [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, | ||
1741 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, | 1748 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, |
1742 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, | 1749 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, |
1743 | [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, | 1750 | [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8f8a96ef9f3f..32d872eec7f5 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1248,8 +1248,8 @@ void __neigh_set_probe_once(struct neighbour *neigh) | |||
1248 | neigh->updated = jiffies; | 1248 | neigh->updated = jiffies; |
1249 | if (!(neigh->nud_state & NUD_FAILED)) | 1249 | if (!(neigh->nud_state & NUD_FAILED)) |
1250 | return; | 1250 | return; |
1251 | neigh->nud_state = NUD_PROBE; | 1251 | neigh->nud_state = NUD_INCOMPLETE; |
1252 | atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES)); | 1252 | atomic_set(&neigh->probes, neigh_max_probes(neigh)); |
1253 | neigh_add_timer(neigh, | 1253 | neigh_add_timer(neigh, |
1254 | jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); | 1254 | jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); |
1255 | } | 1255 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 81d3a9a08453..7c8ffd974961 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | static LIST_HEAD(pernet_list); | 25 | static LIST_HEAD(pernet_list); |
26 | static struct list_head *first_device = &pernet_list; | 26 | static struct list_head *first_device = &pernet_list; |
27 | static DEFINE_MUTEX(net_mutex); | 27 | DEFINE_MUTEX(net_mutex); |
28 | 28 | ||
29 | LIST_HEAD(net_namespace_list); | 29 | LIST_HEAD(net_namespace_list); |
30 | EXPORT_SYMBOL_GPL(net_namespace_list); | 30 | EXPORT_SYMBOL_GPL(net_namespace_list); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d4ff41739b0f..2d8d8fcfa060 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -353,15 +353,46 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops) | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL_GPL(__rtnl_link_unregister); | 354 | EXPORT_SYMBOL_GPL(__rtnl_link_unregister); |
355 | 355 | ||
356 | /* Return with the rtnl_lock held when there are no network | ||
357 | * devices unregistering in any network namespace. | ||
358 | */ | ||
359 | static void rtnl_lock_unregistering_all(void) | ||
360 | { | ||
361 | struct net *net; | ||
362 | bool unregistering; | ||
363 | DEFINE_WAIT(wait); | ||
364 | |||
365 | for (;;) { | ||
366 | prepare_to_wait(&netdev_unregistering_wq, &wait, | ||
367 | TASK_UNINTERRUPTIBLE); | ||
368 | unregistering = false; | ||
369 | rtnl_lock(); | ||
370 | for_each_net(net) { | ||
371 | if (net->dev_unreg_count > 0) { | ||
372 | unregistering = true; | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | if (!unregistering) | ||
377 | break; | ||
378 | __rtnl_unlock(); | ||
379 | schedule(); | ||
380 | } | ||
381 | finish_wait(&netdev_unregistering_wq, &wait); | ||
382 | } | ||
383 | |||
356 | /** | 384 | /** |
357 | * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. | 385 | * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. |
358 | * @ops: struct rtnl_link_ops * to unregister | 386 | * @ops: struct rtnl_link_ops * to unregister |
359 | */ | 387 | */ |
360 | void rtnl_link_unregister(struct rtnl_link_ops *ops) | 388 | void rtnl_link_unregister(struct rtnl_link_ops *ops) |
361 | { | 389 | { |
362 | rtnl_lock(); | 390 | /* Close the race with cleanup_net() */ |
391 | mutex_lock(&net_mutex); | ||
392 | rtnl_lock_unregistering_all(); | ||
363 | __rtnl_link_unregister(ops); | 393 | __rtnl_link_unregister(ops); |
364 | rtnl_unlock(); | 394 | rtnl_unlock(); |
395 | mutex_unlock(&net_mutex); | ||
365 | } | 396 | } |
366 | EXPORT_SYMBOL_GPL(rtnl_link_unregister); | 397 | EXPORT_SYMBOL_GPL(rtnl_link_unregister); |
367 | 398 | ||
@@ -774,7 +805,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
774 | return 0; | 805 | return 0; |
775 | } | 806 | } |
776 | 807 | ||
777 | static size_t rtnl_port_size(const struct net_device *dev) | 808 | static size_t rtnl_port_size(const struct net_device *dev, |
809 | u32 ext_filter_mask) | ||
778 | { | 810 | { |
779 | size_t port_size = nla_total_size(4) /* PORT_VF */ | 811 | size_t port_size = nla_total_size(4) /* PORT_VF */ |
780 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ | 812 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ |
@@ -790,7 +822,8 @@ static size_t rtnl_port_size(const struct net_device *dev) | |||
790 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) | 822 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) |
791 | + port_size; | 823 | + port_size; |
792 | 824 | ||
793 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 825 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
826 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
794 | return 0; | 827 | return 0; |
795 | if (dev_num_vf(dev->dev.parent)) | 828 | if (dev_num_vf(dev->dev.parent)) |
796 | return port_self_size + vf_ports_size + | 829 | return port_self_size + vf_ports_size + |
@@ -826,7 +859,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, | |||
826 | + nla_total_size(ext_filter_mask | 859 | + nla_total_size(ext_filter_mask |
827 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ | 860 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ |
828 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ | 861 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ |
829 | + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ | 862 | + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ |
830 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ | 863 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ |
831 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ | 864 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ |
832 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ | 865 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ |
@@ -888,11 +921,13 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) | |||
888 | return 0; | 921 | return 0; |
889 | } | 922 | } |
890 | 923 | ||
891 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev) | 924 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev, |
925 | u32 ext_filter_mask) | ||
892 | { | 926 | { |
893 | int err; | 927 | int err; |
894 | 928 | ||
895 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 929 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
930 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
896 | return 0; | 931 | return 0; |
897 | 932 | ||
898 | err = rtnl_port_self_fill(skb, dev); | 933 | err = rtnl_port_self_fill(skb, dev); |
@@ -1079,7 +1114,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1079 | nla_nest_end(skb, vfinfo); | 1114 | nla_nest_end(skb, vfinfo); |
1080 | } | 1115 | } |
1081 | 1116 | ||
1082 | if (rtnl_port_fill(skb, dev)) | 1117 | if (rtnl_port_fill(skb, dev, ext_filter_mask)) |
1083 | goto nla_put_failure; | 1118 | goto nla_put_failure; |
1084 | 1119 | ||
1085 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { | 1120 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { |
@@ -1198,6 +1233,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1198 | struct hlist_head *head; | 1233 | struct hlist_head *head; |
1199 | struct nlattr *tb[IFLA_MAX+1]; | 1234 | struct nlattr *tb[IFLA_MAX+1]; |
1200 | u32 ext_filter_mask = 0; | 1235 | u32 ext_filter_mask = 0; |
1236 | int err; | ||
1201 | 1237 | ||
1202 | s_h = cb->args[0]; | 1238 | s_h = cb->args[0]; |
1203 | s_idx = cb->args[1]; | 1239 | s_idx = cb->args[1]; |
@@ -1218,11 +1254,17 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1218 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | 1254 | hlist_for_each_entry_rcu(dev, head, index_hlist) { |
1219 | if (idx < s_idx) | 1255 | if (idx < s_idx) |
1220 | goto cont; | 1256 | goto cont; |
1221 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1257 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
1222 | NETLINK_CB(cb->skb).portid, | 1258 | NETLINK_CB(cb->skb).portid, |
1223 | cb->nlh->nlmsg_seq, 0, | 1259 | cb->nlh->nlmsg_seq, 0, |
1224 | NLM_F_MULTI, | 1260 | NLM_F_MULTI, |
1225 | ext_filter_mask) <= 0) | 1261 | ext_filter_mask); |
1262 | /* If we ran out of room on the first message, | ||
1263 | * we're in trouble | ||
1264 | */ | ||
1265 | WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); | ||
1266 | |||
1267 | if (err <= 0) | ||
1226 | goto out; | 1268 | goto out; |
1227 | 1269 | ||
1228 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 1270 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
@@ -1395,7 +1437,8 @@ static int do_set_master(struct net_device *dev, int ifindex) | |||
1395 | return 0; | 1437 | return 0; |
1396 | } | 1438 | } |
1397 | 1439 | ||
1398 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 1440 | static int do_setlink(const struct sk_buff *skb, |
1441 | struct net_device *dev, struct ifinfomsg *ifm, | ||
1399 | struct nlattr **tb, char *ifname, int modified) | 1442 | struct nlattr **tb, char *ifname, int modified) |
1400 | { | 1443 | { |
1401 | const struct net_device_ops *ops = dev->netdev_ops; | 1444 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -1407,7 +1450,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1407 | err = PTR_ERR(net); | 1450 | err = PTR_ERR(net); |
1408 | goto errout; | 1451 | goto errout; |
1409 | } | 1452 | } |
1410 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { | 1453 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { |
1411 | err = -EPERM; | 1454 | err = -EPERM; |
1412 | goto errout; | 1455 | goto errout; |
1413 | } | 1456 | } |
@@ -1661,7 +1704,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1661 | if (err < 0) | 1704 | if (err < 0) |
1662 | goto errout; | 1705 | goto errout; |
1663 | 1706 | ||
1664 | err = do_setlink(dev, ifm, tb, ifname, 0); | 1707 | err = do_setlink(skb, dev, ifm, tb, ifname, 0); |
1665 | errout: | 1708 | errout: |
1666 | return err; | 1709 | return err; |
1667 | } | 1710 | } |
@@ -1778,7 +1821,8 @@ err: | |||
1778 | } | 1821 | } |
1779 | EXPORT_SYMBOL(rtnl_create_link); | 1822 | EXPORT_SYMBOL(rtnl_create_link); |
1780 | 1823 | ||
1781 | static int rtnl_group_changelink(struct net *net, int group, | 1824 | static int rtnl_group_changelink(const struct sk_buff *skb, |
1825 | struct net *net, int group, | ||
1782 | struct ifinfomsg *ifm, | 1826 | struct ifinfomsg *ifm, |
1783 | struct nlattr **tb) | 1827 | struct nlattr **tb) |
1784 | { | 1828 | { |
@@ -1787,7 +1831,7 @@ static int rtnl_group_changelink(struct net *net, int group, | |||
1787 | 1831 | ||
1788 | for_each_netdev(net, dev) { | 1832 | for_each_netdev(net, dev) { |
1789 | if (dev->group == group) { | 1833 | if (dev->group == group) { |
1790 | err = do_setlink(dev, ifm, tb, NULL, 0); | 1834 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); |
1791 | if (err < 0) | 1835 | if (err < 0) |
1792 | return err; | 1836 | return err; |
1793 | } | 1837 | } |
@@ -1929,12 +1973,12 @@ replay: | |||
1929 | modified = 1; | 1973 | modified = 1; |
1930 | } | 1974 | } |
1931 | 1975 | ||
1932 | return do_setlink(dev, ifm, tb, ifname, modified); | 1976 | return do_setlink(skb, dev, ifm, tb, ifname, modified); |
1933 | } | 1977 | } |
1934 | 1978 | ||
1935 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | 1979 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
1936 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | 1980 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) |
1937 | return rtnl_group_changelink(net, | 1981 | return rtnl_group_changelink(skb, net, |
1938 | nla_get_u32(tb[IFLA_GROUP]), | 1982 | nla_get_u32(tb[IFLA_GROUP]), |
1939 | ifm, tb); | 1983 | ifm, tb); |
1940 | return -ENODEV; | 1984 | return -ENODEV; |
@@ -2321,7 +2365,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2321 | int err = -EINVAL; | 2365 | int err = -EINVAL; |
2322 | __u8 *addr; | 2366 | __u8 *addr; |
2323 | 2367 | ||
2324 | if (!capable(CAP_NET_ADMIN)) | 2368 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
2325 | return -EPERM; | 2369 | return -EPERM; |
2326 | 2370 | ||
2327 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); | 2371 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
@@ -2773,7 +2817,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2773 | sz_idx = type>>2; | 2817 | sz_idx = type>>2; |
2774 | kind = type&3; | 2818 | kind = type&3; |
2775 | 2819 | ||
2776 | if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN)) | 2820 | if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) |
2777 | return -EPERM; | 2821 | return -EPERM; |
2778 | 2822 | ||
2779 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 2823 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1b62343f5837..8383b2bddeb9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3076,7 +3076,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
3076 | if (unlikely(p->len + len >= 65536)) | 3076 | if (unlikely(p->len + len >= 65536)) |
3077 | return -E2BIG; | 3077 | return -E2BIG; |
3078 | 3078 | ||
3079 | lp = NAPI_GRO_CB(p)->last ?: p; | 3079 | lp = NAPI_GRO_CB(p)->last; |
3080 | pinfo = skb_shinfo(lp); | 3080 | pinfo = skb_shinfo(lp); |
3081 | 3081 | ||
3082 | if (headlen <= offset) { | 3082 | if (headlen <= offset) { |
@@ -3192,7 +3192,7 @@ merge: | |||
3192 | 3192 | ||
3193 | __skb_pull(skb, offset); | 3193 | __skb_pull(skb, offset); |
3194 | 3194 | ||
3195 | if (!NAPI_GRO_CB(p)->last) | 3195 | if (NAPI_GRO_CB(p)->last == p) |
3196 | skb_shinfo(p)->frag_list = skb; | 3196 | skb_shinfo(p)->frag_list = skb; |
3197 | else | 3197 | else |
3198 | NAPI_GRO_CB(p)->last->next = skb; | 3198 | NAPI_GRO_CB(p)->last->next = skb; |
diff --git a/net/core/sock.c b/net/core/sock.c index b4fff008136f..664ee4295b6f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -145,6 +145,55 @@ | |||
145 | static DEFINE_MUTEX(proto_list_mutex); | 145 | static DEFINE_MUTEX(proto_list_mutex); |
146 | static LIST_HEAD(proto_list); | 146 | static LIST_HEAD(proto_list); |
147 | 147 | ||
148 | /** | ||
149 | * sk_ns_capable - General socket capability test | ||
150 | * @sk: Socket to use a capability on or through | ||
151 | * @user_ns: The user namespace of the capability to use | ||
152 | * @cap: The capability to use | ||
153 | * | ||
154 | * Test to see if the opener of the socket had when the socket was | ||
155 | * created and the current process has the capability @cap in the user | ||
156 | * namespace @user_ns. | ||
157 | */ | ||
158 | bool sk_ns_capable(const struct sock *sk, | ||
159 | struct user_namespace *user_ns, int cap) | ||
160 | { | ||
161 | return file_ns_capable(sk->sk_socket->file, user_ns, cap) && | ||
162 | ns_capable(user_ns, cap); | ||
163 | } | ||
164 | EXPORT_SYMBOL(sk_ns_capable); | ||
165 | |||
166 | /** | ||
167 | * sk_capable - Socket global capability test | ||
168 | * @sk: Socket to use a capability on or through | ||
169 | * @cap: The global capbility to use | ||
170 | * | ||
171 | * Test to see if the opener of the socket had when the socket was | ||
172 | * created and the current process has the capability @cap in all user | ||
173 | * namespaces. | ||
174 | */ | ||
175 | bool sk_capable(const struct sock *sk, int cap) | ||
176 | { | ||
177 | return sk_ns_capable(sk, &init_user_ns, cap); | ||
178 | } | ||
179 | EXPORT_SYMBOL(sk_capable); | ||
180 | |||
181 | /** | ||
182 | * sk_net_capable - Network namespace socket capability test | ||
183 | * @sk: Socket to use a capability on or through | ||
184 | * @cap: The capability to use | ||
185 | * | ||
186 | * Test to see if the opener of the socket had when the socke was created | ||
187 | * and the current process has the capability @cap over the network namespace | ||
188 | * the socket is a member of. | ||
189 | */ | ||
190 | bool sk_net_capable(const struct sock *sk, int cap) | ||
191 | { | ||
192 | return sk_ns_capable(sk, sock_net(sk)->user_ns, cap); | ||
193 | } | ||
194 | EXPORT_SYMBOL(sk_net_capable); | ||
195 | |||
196 | |||
148 | #ifdef CONFIG_MEMCG_KMEM | 197 | #ifdef CONFIG_MEMCG_KMEM |
149 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 198 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
150 | { | 199 | { |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index d7af18859322..a4216a4c9572 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) | |||
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); | 50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); |
51 | 51 | ||
52 | int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | 52 | int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, |
53 | struct sk_buff *skb, int attrtype) | 53 | struct sk_buff *skb, int attrtype) |
54 | { | 54 | { |
55 | struct sock_fprog_kern *fprog; | 55 | struct sock_fprog_kern *fprog; |
@@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | |||
58 | unsigned int flen; | 58 | unsigned int flen; |
59 | int err = 0; | 59 | int err = 0; |
60 | 60 | ||
61 | if (!ns_capable(user_ns, CAP_NET_ADMIN)) { | 61 | if (!may_report_filterinfo) { |
62 | nla_reserve(skb, attrtype, 0); | 62 | nla_reserve(skb, attrtype, 0); |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
diff --git a/net/core/utils.c b/net/core/utils.c index 2f737bf90b3f..eed34338736c 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -348,8 +348,8 @@ static void __net_random_once_deferred(struct work_struct *w) | |||
348 | { | 348 | { |
349 | struct __net_random_once_work *work = | 349 | struct __net_random_once_work *work = |
350 | container_of(w, struct __net_random_once_work, work); | 350 | container_of(w, struct __net_random_once_work, work); |
351 | if (!static_key_enabled(work->key)) | 351 | BUG_ON(!static_key_enabled(work->key)); |
352 | static_key_slow_inc(work->key); | 352 | static_key_slow_dec(work->key); |
353 | kfree(work); | 353 | kfree(work); |
354 | } | 354 | } |
355 | 355 | ||
@@ -367,7 +367,7 @@ static void __net_random_once_disable_jump(struct static_key *key) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | bool __net_get_random_once(void *buf, int nbytes, bool *done, | 369 | bool __net_get_random_once(void *buf, int nbytes, bool *done, |
370 | struct static_key *done_key) | 370 | struct static_key *once_key) |
371 | { | 371 | { |
372 | static DEFINE_SPINLOCK(lock); | 372 | static DEFINE_SPINLOCK(lock); |
373 | unsigned long flags; | 373 | unsigned long flags; |
@@ -382,7 +382,7 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done, | |||
382 | *done = true; | 382 | *done = true; |
383 | spin_unlock_irqrestore(&lock, flags); | 383 | spin_unlock_irqrestore(&lock, flags); |
384 | 384 | ||
385 | __net_random_once_disable_jump(done_key); | 385 | __net_random_once_disable_jump(once_key); |
386 | 386 | ||
387 | return true; | 387 | return true; |
388 | } | 388 | } |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 553644402670..f8b98d89c285 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -1669,7 +1669,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1669 | struct nlmsghdr *reply_nlh = NULL; | 1669 | struct nlmsghdr *reply_nlh = NULL; |
1670 | const struct reply_func *fn; | 1670 | const struct reply_func *fn; |
1671 | 1671 | ||
1672 | if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN)) | 1672 | if ((nlh->nlmsg_type == RTM_SETDCB) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1673 | return -EPERM; | 1673 | return -EPERM; |
1674 | 1674 | ||
1675 | ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, | 1675 | ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, |
diff --git a/net/dccp/output.c b/net/dccp/output.c index 8876078859da..0248e8a3460c 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -138,7 +138,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
138 | 138 | ||
139 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); | 139 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
140 | 140 | ||
141 | err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl); | 141 | err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl); |
142 | return net_xmit_eval(err); | 142 | return net_xmit_eval(err); |
143 | } | 143 | } |
144 | return -ENOBUFS; | 144 | return -ENOBUFS; |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index a603823a3e27..3b726f31c64c 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -574,7 +574,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
574 | struct dn_ifaddr __rcu **ifap; | 574 | struct dn_ifaddr __rcu **ifap; |
575 | int err = -EINVAL; | 575 | int err = -EINVAL; |
576 | 576 | ||
577 | if (!capable(CAP_NET_ADMIN)) | 577 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
578 | return -EPERM; | 578 | return -EPERM; |
579 | 579 | ||
580 | if (!net_eq(net, &init_net)) | 580 | if (!net_eq(net, &init_net)) |
@@ -618,7 +618,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
618 | struct dn_ifaddr *ifa; | 618 | struct dn_ifaddr *ifa; |
619 | int err; | 619 | int err; |
620 | 620 | ||
621 | if (!capable(CAP_NET_ADMIN)) | 621 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
622 | return -EPERM; | 622 | return -EPERM; |
623 | 623 | ||
624 | if (!net_eq(net, &init_net)) | 624 | if (!net_eq(net, &init_net)) |
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 57dc159245ec..d332aefb0846 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -505,7 +505,7 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
505 | struct nlattr *attrs[RTA_MAX+1]; | 505 | struct nlattr *attrs[RTA_MAX+1]; |
506 | int err; | 506 | int err; |
507 | 507 | ||
508 | if (!capable(CAP_NET_ADMIN)) | 508 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
509 | return -EPERM; | 509 | return -EPERM; |
510 | 510 | ||
511 | if (!net_eq(net, &init_net)) | 511 | if (!net_eq(net, &init_net)) |
@@ -530,7 +530,7 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
530 | struct nlattr *attrs[RTA_MAX+1]; | 530 | struct nlattr *attrs[RTA_MAX+1]; |
531 | int err; | 531 | int err; |
532 | 532 | ||
533 | if (!capable(CAP_NET_ADMIN)) | 533 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
534 | return -EPERM; | 534 | return -EPERM; |
535 | 535 | ||
536 | if (!net_eq(net, &init_net)) | 536 | if (!net_eq(net, &init_net)) |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index ce0cbbfe0f43..daccc4a36d80 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -752,7 +752,7 @@ static int dn_to_neigh_output(struct sk_buff *skb) | |||
752 | return n->output(n, skb); | 752 | return n->output(n, skb); |
753 | } | 753 | } |
754 | 754 | ||
755 | static int dn_output(struct sk_buff *skb) | 755 | static int dn_output(struct sock *sk, struct sk_buff *skb) |
756 | { | 756 | { |
757 | struct dst_entry *dst = skb_dst(skb); | 757 | struct dst_entry *dst = skb_dst(skb); |
758 | struct dn_route *rt = (struct dn_route *)dst; | 758 | struct dn_route *rt = (struct dn_route *)dst; |
@@ -838,6 +838,18 @@ drop: | |||
838 | * Used to catch bugs. This should never normally get | 838 | * Used to catch bugs. This should never normally get |
839 | * called. | 839 | * called. |
840 | */ | 840 | */ |
841 | static int dn_rt_bug_sk(struct sock *sk, struct sk_buff *skb) | ||
842 | { | ||
843 | struct dn_skb_cb *cb = DN_SKB_CB(skb); | ||
844 | |||
845 | net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n", | ||
846 | le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); | ||
847 | |||
848 | kfree_skb(skb); | ||
849 | |||
850 | return NET_RX_DROP; | ||
851 | } | ||
852 | |||
841 | static int dn_rt_bug(struct sk_buff *skb) | 853 | static int dn_rt_bug(struct sk_buff *skb) |
842 | { | 854 | { |
843 | struct dn_skb_cb *cb = DN_SKB_CB(skb); | 855 | struct dn_skb_cb *cb = DN_SKB_CB(skb); |
@@ -1463,7 +1475,7 @@ make_route: | |||
1463 | 1475 | ||
1464 | rt->n = neigh; | 1476 | rt->n = neigh; |
1465 | rt->dst.lastuse = jiffies; | 1477 | rt->dst.lastuse = jiffies; |
1466 | rt->dst.output = dn_rt_bug; | 1478 | rt->dst.output = dn_rt_bug_sk; |
1467 | switch (res.type) { | 1479 | switch (res.type) { |
1468 | case RTN_UNICAST: | 1480 | case RTN_UNICAST: |
1469 | rt->dst.input = dn_forward; | 1481 | rt->dst.input = dn_forward; |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index e83015cecfa7..e4d9560a910b 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
@@ -107,7 +107,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) | |||
107 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 107 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
108 | return; | 108 | return; |
109 | 109 | ||
110 | if (!capable(CAP_NET_ADMIN)) | 110 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
111 | RCV_SKB_FAIL(-EPERM); | 111 | RCV_SKB_FAIL(-EPERM); |
112 | 112 | ||
113 | /* Eventually we might send routing messages too */ | 113 | /* Eventually we might send routing messages too */ |
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 0eb5d5e76dfb..5db37cef50a9 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -406,8 +406,9 @@ static int dsa_of_probe(struct platform_device *pdev) | |||
406 | goto out_free; | 406 | goto out_free; |
407 | } | 407 | } |
408 | 408 | ||
409 | chip_index = 0; | 409 | chip_index = -1; |
410 | for_each_available_child_of_node(np, child) { | 410 | for_each_available_child_of_node(np, child) { |
411 | chip_index++; | ||
411 | cd = &pd->chip[chip_index]; | 412 | cd = &pd->chip[chip_index]; |
412 | 413 | ||
413 | cd->mii_bus = &mdio_bus->dev; | 414 | cd->mii_bus = &mdio_bus->dev; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8c54870db792..6d6dd345bc4d 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1650,6 +1650,39 @@ static int __init init_ipv4_mibs(void) | |||
1650 | return register_pernet_subsys(&ipv4_mib_ops); | 1650 | return register_pernet_subsys(&ipv4_mib_ops); |
1651 | } | 1651 | } |
1652 | 1652 | ||
1653 | static __net_init int inet_init_net(struct net *net) | ||
1654 | { | ||
1655 | /* | ||
1656 | * Set defaults for local port range | ||
1657 | */ | ||
1658 | seqlock_init(&net->ipv4.ip_local_ports.lock); | ||
1659 | net->ipv4.ip_local_ports.range[0] = 32768; | ||
1660 | net->ipv4.ip_local_ports.range[1] = 61000; | ||
1661 | |||
1662 | seqlock_init(&net->ipv4.ping_group_range.lock); | ||
1663 | /* | ||
1664 | * Sane defaults - nobody may create ping sockets. | ||
1665 | * Boot scripts should set this to distro-specific group. | ||
1666 | */ | ||
1667 | net->ipv4.ping_group_range.range[0] = make_kgid(&init_user_ns, 1); | ||
1668 | net->ipv4.ping_group_range.range[1] = make_kgid(&init_user_ns, 0); | ||
1669 | return 0; | ||
1670 | } | ||
1671 | |||
1672 | static __net_exit void inet_exit_net(struct net *net) | ||
1673 | { | ||
1674 | } | ||
1675 | |||
1676 | static __net_initdata struct pernet_operations af_inet_ops = { | ||
1677 | .init = inet_init_net, | ||
1678 | .exit = inet_exit_net, | ||
1679 | }; | ||
1680 | |||
1681 | static int __init init_inet_pernet_ops(void) | ||
1682 | { | ||
1683 | return register_pernet_subsys(&af_inet_ops); | ||
1684 | } | ||
1685 | |||
1653 | static int ipv4_proc_init(void); | 1686 | static int ipv4_proc_init(void); |
1654 | 1687 | ||
1655 | /* | 1688 | /* |
@@ -1794,6 +1827,9 @@ static int __init inet_init(void) | |||
1794 | if (ip_mr_init()) | 1827 | if (ip_mr_init()) |
1795 | pr_crit("%s: Cannot init ipv4 mroute\n", __func__); | 1828 | pr_crit("%s: Cannot init ipv4 mroute\n", __func__); |
1796 | #endif | 1829 | #endif |
1830 | |||
1831 | if (init_inet_pernet_ops()) | ||
1832 | pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); | ||
1797 | /* | 1833 | /* |
1798 | * Initialise per-cpu ipv4 mibs | 1834 | * Initialise per-cpu ipv4 mibs |
1799 | */ | 1835 | */ |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1a629f870274..255aa9946fe7 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, | |||
250 | bool dev_match; | 250 | bool dev_match; |
251 | 251 | ||
252 | fl4.flowi4_oif = 0; | 252 | fl4.flowi4_oif = 0; |
253 | fl4.flowi4_iif = oif; | 253 | fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX; |
254 | fl4.daddr = src; | 254 | fl4.daddr = src; |
255 | fl4.saddr = dst; | 255 | fl4.saddr = dst; |
256 | fl4.flowi4_tos = tos; | 256 | fl4.flowi4_tos = tos; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index b53f0bf84dca..b10cd43a4722 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, | |||
631 | .daddr = nh->nh_gw, | 631 | .daddr = nh->nh_gw, |
632 | .flowi4_scope = cfg->fc_scope + 1, | 632 | .flowi4_scope = cfg->fc_scope + 1, |
633 | .flowi4_oif = nh->nh_oif, | 633 | .flowi4_oif = nh->nh_oif, |
634 | .flowi4_iif = LOOPBACK_IFINDEX, | ||
634 | }; | 635 | }; |
635 | 636 | ||
636 | /* It is not necessary, but requires a bit of thinking */ | 637 | /* It is not necessary, but requires a bit of thinking */ |
@@ -820,13 +821,13 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
820 | fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); | 821 | fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); |
821 | if (fi == NULL) | 822 | if (fi == NULL) |
822 | goto failure; | 823 | goto failure; |
824 | fib_info_cnt++; | ||
823 | if (cfg->fc_mx) { | 825 | if (cfg->fc_mx) { |
824 | fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); | 826 | fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); |
825 | if (!fi->fib_metrics) | 827 | if (!fi->fib_metrics) |
826 | goto failure; | 828 | goto failure; |
827 | } else | 829 | } else |
828 | fi->fib_metrics = (u32 *) dst_default_metrics; | 830 | fi->fib_metrics = (u32 *) dst_default_metrics; |
829 | fib_info_cnt++; | ||
830 | 831 | ||
831 | fi->fib_net = hold_net(net); | 832 | fi->fib_net = hold_net(net); |
832 | fi->fib_protocol = cfg->fc_protocol; | 833 | fi->fib_protocol = cfg->fc_protocol; |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 0d1e2cb877ec..a56b8e6e866a 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -37,11 +37,11 @@ void inet_get_local_port_range(struct net *net, int *low, int *high) | |||
37 | unsigned int seq; | 37 | unsigned int seq; |
38 | 38 | ||
39 | do { | 39 | do { |
40 | seq = read_seqbegin(&net->ipv4.sysctl_local_ports.lock); | 40 | seq = read_seqbegin(&net->ipv4.ip_local_ports.lock); |
41 | 41 | ||
42 | *low = net->ipv4.sysctl_local_ports.range[0]; | 42 | *low = net->ipv4.ip_local_ports.range[0]; |
43 | *high = net->ipv4.sysctl_local_ports.range[1]; | 43 | *high = net->ipv4.ip_local_ports.range[1]; |
44 | } while (read_seqretry(&net->ipv4.sysctl_local_ports.lock, seq)); | 44 | } while (read_seqretry(&net->ipv4.ip_local_ports.lock, seq)); |
45 | } | 45 | } |
46 | EXPORT_SYMBOL(inet_get_local_port_range); | 46 | EXPORT_SYMBOL(inet_get_local_port_range); |
47 | 47 | ||
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index be8abe73bb9f..6f111e48e11c 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -42,12 +42,12 @@ | |||
42 | static bool ip_may_fragment(const struct sk_buff *skb) | 42 | static bool ip_may_fragment(const struct sk_buff *skb) |
43 | { | 43 | { |
44 | return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) || | 44 | return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) || |
45 | !skb->local_df; | 45 | skb->local_df; |
46 | } | 46 | } |
47 | 47 | ||
48 | static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) | 48 | static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) |
49 | { | 49 | { |
50 | if (skb->len <= mtu || skb->local_df) | 50 | if (skb->len <= mtu) |
51 | return false; | 51 | return false; |
52 | 52 | ||
53 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) | 53 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) |
@@ -56,53 +56,6 @@ static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) | |||
56 | return true; | 56 | return true; |
57 | } | 57 | } |
58 | 58 | ||
59 | static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb) | ||
60 | { | ||
61 | unsigned int mtu; | ||
62 | |||
63 | if (skb->local_df || !skb_is_gso(skb)) | ||
64 | return false; | ||
65 | |||
66 | mtu = ip_dst_mtu_maybe_forward(skb_dst(skb), true); | ||
67 | |||
68 | /* if seglen > mtu, do software segmentation for IP fragmentation on | ||
69 | * output. DF bit cannot be set since ip_forward would have sent | ||
70 | * icmp error. | ||
71 | */ | ||
72 | return skb_gso_network_seglen(skb) > mtu; | ||
73 | } | ||
74 | |||
75 | /* called if GSO skb needs to be fragmented on forward */ | ||
76 | static int ip_forward_finish_gso(struct sk_buff *skb) | ||
77 | { | ||
78 | struct dst_entry *dst = skb_dst(skb); | ||
79 | netdev_features_t features; | ||
80 | struct sk_buff *segs; | ||
81 | int ret = 0; | ||
82 | |||
83 | features = netif_skb_dev_features(skb, dst->dev); | ||
84 | segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | ||
85 | if (IS_ERR(segs)) { | ||
86 | kfree_skb(skb); | ||
87 | return -ENOMEM; | ||
88 | } | ||
89 | |||
90 | consume_skb(skb); | ||
91 | |||
92 | do { | ||
93 | struct sk_buff *nskb = segs->next; | ||
94 | int err; | ||
95 | |||
96 | segs->next = NULL; | ||
97 | err = dst_output(segs); | ||
98 | |||
99 | if (err && ret == 0) | ||
100 | ret = err; | ||
101 | segs = nskb; | ||
102 | } while (segs); | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | 59 | ||
107 | static int ip_forward_finish(struct sk_buff *skb) | 60 | static int ip_forward_finish(struct sk_buff *skb) |
108 | { | 61 | { |
@@ -114,9 +67,6 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
114 | if (unlikely(opt->optlen)) | 67 | if (unlikely(opt->optlen)) |
115 | ip_forward_options(skb); | 68 | ip_forward_options(skb); |
116 | 69 | ||
117 | if (ip_gso_exceeds_dst_mtu(skb)) | ||
118 | return ip_forward_finish_gso(skb); | ||
119 | |||
120 | return dst_output(skb); | 70 | return dst_output(skb); |
121 | } | 71 | } |
122 | 72 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index c10a3ce5cbff..ed32313e307c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -232,8 +232,9 @@ static void ip_expire(unsigned long arg) | |||
232 | * "Fragment Reassembly Timeout" message, per RFC792. | 232 | * "Fragment Reassembly Timeout" message, per RFC792. |
233 | */ | 233 | */ |
234 | if (qp->user == IP_DEFRAG_AF_PACKET || | 234 | if (qp->user == IP_DEFRAG_AF_PACKET || |
235 | (qp->user == IP_DEFRAG_CONNTRACK_IN && | 235 | ((qp->user >= IP_DEFRAG_CONNTRACK_IN) && |
236 | skb_rtable(head)->rt_type != RTN_LOCAL)) | 236 | (qp->user <= __IP_DEFRAG_CONNTRACK_IN_END) && |
237 | (skb_rtable(head)->rt_type != RTN_LOCAL))) | ||
237 | goto out_rcu_unlock; | 238 | goto out_rcu_unlock; |
238 | 239 | ||
239 | 240 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 1a0755fea491..a52f50187b54 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -101,17 +101,17 @@ int __ip_local_out(struct sk_buff *skb) | |||
101 | skb_dst(skb)->dev, dst_output); | 101 | skb_dst(skb)->dev, dst_output); |
102 | } | 102 | } |
103 | 103 | ||
104 | int ip_local_out(struct sk_buff *skb) | 104 | int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) |
105 | { | 105 | { |
106 | int err; | 106 | int err; |
107 | 107 | ||
108 | err = __ip_local_out(skb); | 108 | err = __ip_local_out(skb); |
109 | if (likely(err == 1)) | 109 | if (likely(err == 1)) |
110 | err = dst_output(skb); | 110 | err = dst_output_sk(sk, skb); |
111 | 111 | ||
112 | return err; | 112 | return err; |
113 | } | 113 | } |
114 | EXPORT_SYMBOL_GPL(ip_local_out); | 114 | EXPORT_SYMBOL_GPL(ip_local_out_sk); |
115 | 115 | ||
116 | static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) | 116 | static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) |
117 | { | 117 | { |
@@ -211,6 +211,48 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
211 | return -EINVAL; | 211 | return -EINVAL; |
212 | } | 212 | } |
213 | 213 | ||
214 | static int ip_finish_output_gso(struct sk_buff *skb) | ||
215 | { | ||
216 | netdev_features_t features; | ||
217 | struct sk_buff *segs; | ||
218 | int ret = 0; | ||
219 | |||
220 | /* common case: locally created skb or seglen is <= mtu */ | ||
221 | if (((IPCB(skb)->flags & IPSKB_FORWARDED) == 0) || | ||
222 | skb_gso_network_seglen(skb) <= ip_skb_dst_mtu(skb)) | ||
223 | return ip_finish_output2(skb); | ||
224 | |||
225 | /* Slowpath - GSO segment length is exceeding the dst MTU. | ||
226 | * | ||
227 | * This can happen in two cases: | ||
228 | * 1) TCP GRO packet, DF bit not set | ||
229 | * 2) skb arrived via virtio-net, we thus get TSO/GSO skbs directly | ||
230 | * from host network stack. | ||
231 | */ | ||
232 | features = netif_skb_features(skb); | ||
233 | segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | ||
234 | if (IS_ERR(segs)) { | ||
235 | kfree_skb(skb); | ||
236 | return -ENOMEM; | ||
237 | } | ||
238 | |||
239 | consume_skb(skb); | ||
240 | |||
241 | do { | ||
242 | struct sk_buff *nskb = segs->next; | ||
243 | int err; | ||
244 | |||
245 | segs->next = NULL; | ||
246 | err = ip_fragment(segs, ip_finish_output2); | ||
247 | |||
248 | if (err && ret == 0) | ||
249 | ret = err; | ||
250 | segs = nskb; | ||
251 | } while (segs); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
214 | static int ip_finish_output(struct sk_buff *skb) | 256 | static int ip_finish_output(struct sk_buff *skb) |
215 | { | 257 | { |
216 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) | 258 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) |
@@ -220,15 +262,17 @@ static int ip_finish_output(struct sk_buff *skb) | |||
220 | return dst_output(skb); | 262 | return dst_output(skb); |
221 | } | 263 | } |
222 | #endif | 264 | #endif |
223 | if (skb->len > ip_skb_dst_mtu(skb) && !skb_is_gso(skb)) | 265 | if (skb_is_gso(skb)) |
266 | return ip_finish_output_gso(skb); | ||
267 | |||
268 | if (skb->len > ip_skb_dst_mtu(skb)) | ||
224 | return ip_fragment(skb, ip_finish_output2); | 269 | return ip_fragment(skb, ip_finish_output2); |
225 | else | 270 | |
226 | return ip_finish_output2(skb); | 271 | return ip_finish_output2(skb); |
227 | } | 272 | } |
228 | 273 | ||
229 | int ip_mc_output(struct sk_buff *skb) | 274 | int ip_mc_output(struct sock *sk, struct sk_buff *skb) |
230 | { | 275 | { |
231 | struct sock *sk = skb->sk; | ||
232 | struct rtable *rt = skb_rtable(skb); | 276 | struct rtable *rt = skb_rtable(skb); |
233 | struct net_device *dev = rt->dst.dev; | 277 | struct net_device *dev = rt->dst.dev; |
234 | 278 | ||
@@ -287,7 +331,7 @@ int ip_mc_output(struct sk_buff *skb) | |||
287 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 331 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
288 | } | 332 | } |
289 | 333 | ||
290 | int ip_output(struct sk_buff *skb) | 334 | int ip_output(struct sock *sk, struct sk_buff *skb) |
291 | { | 335 | { |
292 | struct net_device *dev = skb_dst(skb)->dev; | 336 | struct net_device *dev = skb_dst(skb)->dev; |
293 | 337 | ||
@@ -315,9 +359,9 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4) | |||
315 | sizeof(fl4->saddr) + sizeof(fl4->daddr)); | 359 | sizeof(fl4->saddr) + sizeof(fl4->daddr)); |
316 | } | 360 | } |
317 | 361 | ||
318 | int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) | 362 | /* Note: skb->sk can be different from sk, in case of tunnels */ |
363 | int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl) | ||
319 | { | 364 | { |
320 | struct sock *sk = skb->sk; | ||
321 | struct inet_sock *inet = inet_sk(sk); | 365 | struct inet_sock *inet = inet_sk(sk); |
322 | struct ip_options_rcu *inet_opt; | 366 | struct ip_options_rcu *inet_opt; |
323 | struct flowi4 *fl4; | 367 | struct flowi4 *fl4; |
@@ -389,6 +433,7 @@ packet_routed: | |||
389 | ip_select_ident_more(skb, &rt->dst, sk, | 433 | ip_select_ident_more(skb, &rt->dst, sk, |
390 | (skb_shinfo(skb)->gso_segs ?: 1) - 1); | 434 | (skb_shinfo(skb)->gso_segs ?: 1) - 1); |
391 | 435 | ||
436 | /* TODO : should we use skb->sk here instead of sk ? */ | ||
392 | skb->priority = sk->sk_priority; | 437 | skb->priority = sk->sk_priority; |
393 | skb->mark = sk->sk_mark; | 438 | skb->mark = sk->sk_mark; |
394 | 439 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e77381d1df9a..2acc2337d38b 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -442,6 +442,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, | |||
442 | tunnel->i_seqno = ntohl(tpi->seq) + 1; | 442 | tunnel->i_seqno = ntohl(tpi->seq) + 1; |
443 | } | 443 | } |
444 | 444 | ||
445 | skb_reset_network_header(skb); | ||
446 | |||
445 | err = IP_ECN_decapsulate(iph, skb); | 447 | err = IP_ECN_decapsulate(iph, skb); |
446 | if (unlikely(err)) { | 448 | if (unlikely(err)) { |
447 | if (log_ecn_error) | 449 | if (log_ecn_error) |
@@ -538,9 +540,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
538 | unsigned int max_headroom; /* The extra header space needed */ | 540 | unsigned int max_headroom; /* The extra header space needed */ |
539 | __be32 dst; | 541 | __be32 dst; |
540 | int err; | 542 | int err; |
541 | bool connected = true; | 543 | bool connected; |
542 | 544 | ||
543 | inner_iph = (const struct iphdr *)skb_inner_network_header(skb); | 545 | inner_iph = (const struct iphdr *)skb_inner_network_header(skb); |
546 | connected = (tunnel->parms.iph.daddr != 0); | ||
544 | 547 | ||
545 | dst = tnl_params->daddr; | 548 | dst = tnl_params->daddr; |
546 | if (dst == 0) { | 549 | if (dst == 0) { |
@@ -670,7 +673,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
670 | return; | 673 | return; |
671 | } | 674 | } |
672 | 675 | ||
673 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol, | 676 | err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol, |
674 | tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 677 | tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); |
675 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 678 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
676 | 679 | ||
@@ -722,19 +725,18 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn, | |||
722 | int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) | 725 | int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) |
723 | { | 726 | { |
724 | int err = 0; | 727 | int err = 0; |
725 | struct ip_tunnel *t; | 728 | struct ip_tunnel *t = netdev_priv(dev); |
726 | struct net *net = dev_net(dev); | 729 | struct net *net = t->net; |
727 | struct ip_tunnel *tunnel = netdev_priv(dev); | 730 | struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id); |
728 | struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id); | ||
729 | 731 | ||
730 | BUG_ON(!itn->fb_tunnel_dev); | 732 | BUG_ON(!itn->fb_tunnel_dev); |
731 | switch (cmd) { | 733 | switch (cmd) { |
732 | case SIOCGETTUNNEL: | 734 | case SIOCGETTUNNEL: |
733 | t = NULL; | 735 | if (dev == itn->fb_tunnel_dev) { |
734 | if (dev == itn->fb_tunnel_dev) | ||
735 | t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); | 736 | t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); |
736 | if (t == NULL) | 737 | if (t == NULL) |
737 | t = netdev_priv(dev); | 738 | t = netdev_priv(dev); |
739 | } | ||
738 | memcpy(p, &t->parms, sizeof(*p)); | 740 | memcpy(p, &t->parms, sizeof(*p)); |
739 | break; | 741 | break; |
740 | 742 | ||
@@ -881,6 +883,7 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, | |||
881 | */ | 883 | */ |
882 | if (!IS_ERR(itn->fb_tunnel_dev)) { | 884 | if (!IS_ERR(itn->fb_tunnel_dev)) { |
883 | itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; | 885 | itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; |
886 | itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev); | ||
884 | ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev)); | 887 | ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev)); |
885 | } | 888 | } |
886 | rtnl_unlock(); | 889 | rtnl_unlock(); |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index e0c2b1d2ea4e..bcf206c79005 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <net/netns/generic.h> | 46 | #include <net/netns/generic.h> |
47 | #include <net/rtnetlink.h> | 47 | #include <net/rtnetlink.h> |
48 | 48 | ||
49 | int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, | 49 | int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, |
50 | __be32 src, __be32 dst, __u8 proto, | 50 | __be32 src, __be32 dst, __u8 proto, |
51 | __u8 tos, __u8 ttl, __be16 df, bool xnet) | 51 | __u8 tos, __u8 ttl, __be16 df, bool xnet) |
52 | { | 52 | { |
@@ -76,7 +76,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, | |||
76 | iph->ttl = ttl; | 76 | iph->ttl = ttl; |
77 | __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); | 77 | __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); |
78 | 78 | ||
79 | err = ip_local_out(skb); | 79 | err = ip_local_out_sk(sk, skb); |
80 | if (unlikely(net_xmit_eval(err))) | 80 | if (unlikely(net_xmit_eval(err))) |
81 | pkt_len = 0; | 81 | pkt_len = 0; |
82 | return pkt_len; | 82 | return pkt_len; |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index afcee51b90ed..13ef00f1e17b 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -239,6 +239,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
239 | static int vti4_err(struct sk_buff *skb, u32 info) | 239 | static int vti4_err(struct sk_buff *skb, u32 info) |
240 | { | 240 | { |
241 | __be32 spi; | 241 | __be32 spi; |
242 | __u32 mark; | ||
242 | struct xfrm_state *x; | 243 | struct xfrm_state *x; |
243 | struct ip_tunnel *tunnel; | 244 | struct ip_tunnel *tunnel; |
244 | struct ip_esp_hdr *esph; | 245 | struct ip_esp_hdr *esph; |
@@ -254,6 +255,8 @@ static int vti4_err(struct sk_buff *skb, u32 info) | |||
254 | if (!tunnel) | 255 | if (!tunnel) |
255 | return -1; | 256 | return -1; |
256 | 257 | ||
258 | mark = be32_to_cpu(tunnel->parms.o_key); | ||
259 | |||
257 | switch (protocol) { | 260 | switch (protocol) { |
258 | case IPPROTO_ESP: | 261 | case IPPROTO_ESP: |
259 | esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2)); | 262 | esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2)); |
@@ -281,7 +284,7 @@ static int vti4_err(struct sk_buff *skb, u32 info) | |||
281 | return 0; | 284 | return 0; |
282 | } | 285 | } |
283 | 286 | ||
284 | x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, | 287 | x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr, |
285 | spi, protocol, AF_INET); | 288 | spi, protocol, AF_INET); |
286 | if (!x) | 289 | if (!x) |
287 | return 0; | 290 | return 0; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 28863570dd60..d84dc8d4c916 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | |||
455 | struct mr_table *mrt; | 455 | struct mr_table *mrt; |
456 | struct flowi4 fl4 = { | 456 | struct flowi4 fl4 = { |
457 | .flowi4_oif = dev->ifindex, | 457 | .flowi4_oif = dev->ifindex, |
458 | .flowi4_iif = skb->skb_iif, | 458 | .flowi4_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, |
459 | .flowi4_mark = skb->mark, | 459 | .flowi4_mark = skb->mark, |
460 | }; | 460 | }; |
461 | int err; | 461 | int err; |
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index c49dcd0284a0..4bfaedf9b34e 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c | |||
@@ -89,11 +89,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
89 | if (ipv4_is_multicast(iph->daddr)) { | 89 | if (ipv4_is_multicast(iph->daddr)) { |
90 | if (ipv4_is_zeronet(iph->saddr)) | 90 | if (ipv4_is_zeronet(iph->saddr)) |
91 | return ipv4_is_local_multicast(iph->daddr) ^ invert; | 91 | return ipv4_is_local_multicast(iph->daddr) ^ invert; |
92 | flow.flowi4_iif = 0; | ||
93 | } else { | ||
94 | flow.flowi4_iif = LOOPBACK_IFINDEX; | ||
95 | } | 92 | } |
96 | 93 | flow.flowi4_iif = LOOPBACK_IFINDEX; | |
97 | flow.daddr = iph->saddr; | 94 | flow.daddr = iph->saddr; |
98 | flow.saddr = rpfilter_get_saddr(iph->daddr); | 95 | flow.saddr = rpfilter_get_saddr(iph->daddr); |
99 | flow.flowi4_oif = 0; | 96 | flow.flowi4_oif = 0; |
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index 12e13bd82b5b..f40f321b41fc 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #endif | 22 | #endif |
23 | #include <net/netfilter/nf_conntrack_zones.h> | 23 | #include <net/netfilter/nf_conntrack_zones.h> |
24 | 24 | ||
25 | /* Returns new sk_buff, or NULL */ | ||
26 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | 25 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) |
27 | { | 26 | { |
28 | int err; | 27 | int err; |
@@ -33,8 +32,10 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | |||
33 | err = ip_defrag(skb, user); | 32 | err = ip_defrag(skb, user); |
34 | local_bh_enable(); | 33 | local_bh_enable(); |
35 | 34 | ||
36 | if (!err) | 35 | if (!err) { |
37 | ip_send_check(ip_hdr(skb)); | 36 | ip_send_check(ip_hdr(skb)); |
37 | skb->local_df = 1; | ||
38 | } | ||
38 | 39 | ||
39 | return err; | 40 | return err; |
40 | } | 41 | } |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index f4b19e5dde54..044a0ddf6a79 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -236,15 +236,15 @@ exit: | |||
236 | static void inet_get_ping_group_range_net(struct net *net, kgid_t *low, | 236 | static void inet_get_ping_group_range_net(struct net *net, kgid_t *low, |
237 | kgid_t *high) | 237 | kgid_t *high) |
238 | { | 238 | { |
239 | kgid_t *data = net->ipv4.sysctl_ping_group_range; | 239 | kgid_t *data = net->ipv4.ping_group_range.range; |
240 | unsigned int seq; | 240 | unsigned int seq; |
241 | 241 | ||
242 | do { | 242 | do { |
243 | seq = read_seqbegin(&net->ipv4.sysctl_local_ports.lock); | 243 | seq = read_seqbegin(&net->ipv4.ping_group_range.lock); |
244 | 244 | ||
245 | *low = data[0]; | 245 | *low = data[0]; |
246 | *high = data[1]; | 246 | *high = data[1]; |
247 | } while (read_seqretry(&net->ipv4.sysctl_local_ports.lock, seq)); | 247 | } while (read_seqretry(&net->ipv4.ping_group_range.lock, seq)); |
248 | } | 248 | } |
249 | 249 | ||
250 | 250 | ||
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk) | |||
252 | { | 252 | { |
253 | struct net *net = sock_net(sk); | 253 | struct net *net = sock_net(sk); |
254 | kgid_t group = current_egid(); | 254 | kgid_t group = current_egid(); |
255 | struct group_info *group_info = get_current_groups(); | 255 | struct group_info *group_info; |
256 | int i, j, count = group_info->ngroups; | 256 | int i, j, count; |
257 | kgid_t low, high; | 257 | kgid_t low, high; |
258 | int ret = 0; | ||
258 | 259 | ||
259 | inet_get_ping_group_range_net(net, &low, &high); | 260 | inet_get_ping_group_range_net(net, &low, &high); |
260 | if (gid_lte(low, group) && gid_lte(group, high)) | 261 | if (gid_lte(low, group) && gid_lte(group, high)) |
261 | return 0; | 262 | return 0; |
262 | 263 | ||
264 | group_info = get_current_groups(); | ||
265 | count = group_info->ngroups; | ||
263 | for (i = 0; i < group_info->nblocks; i++) { | 266 | for (i = 0; i < group_info->nblocks; i++) { |
264 | int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); | 267 | int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); |
265 | for (j = 0; j < cp_count; j++) { | 268 | for (j = 0; j < cp_count; j++) { |
266 | kgid_t gid = group_info->blocks[i][j]; | 269 | kgid_t gid = group_info->blocks[i][j]; |
267 | if (gid_lte(low, gid) && gid_lte(gid, high)) | 270 | if (gid_lte(low, gid) && gid_lte(gid, high)) |
268 | return 0; | 271 | goto out_release_group; |
269 | } | 272 | } |
270 | 273 | ||
271 | count -= cp_count; | 274 | count -= cp_count; |
272 | } | 275 | } |
273 | 276 | ||
274 | return -EACCES; | 277 | ret = -EACCES; |
278 | |||
279 | out_release_group: | ||
280 | put_group_info(group_info); | ||
281 | return ret; | ||
275 | } | 282 | } |
276 | EXPORT_SYMBOL_GPL(ping_init_sock); | 283 | EXPORT_SYMBOL_GPL(ping_init_sock); |
277 | 284 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 34d094cadb11..5e676be3daeb 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1129,7 +1129,7 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
1129 | dst_set_expires(&rt->dst, 0); | 1129 | dst_set_expires(&rt->dst, 0); |
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | static int ip_rt_bug(struct sk_buff *skb) | 1132 | static int ip_rt_bug(struct sock *sk, struct sk_buff *skb) |
1133 | { | 1133 | { |
1134 | pr_debug("%s: %pI4 -> %pI4, %s\n", | 1134 | pr_debug("%s: %pI4 -> %pI4, %s\n", |
1135 | __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, | 1135 | __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, |
@@ -1519,7 +1519,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1519 | struct in_device *out_dev; | 1519 | struct in_device *out_dev; |
1520 | unsigned int flags = 0; | 1520 | unsigned int flags = 0; |
1521 | bool do_cache; | 1521 | bool do_cache; |
1522 | u32 itag; | 1522 | u32 itag = 0; |
1523 | 1523 | ||
1524 | /* get a working reference to the output device */ | 1524 | /* get a working reference to the output device */ |
1525 | out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res)); | 1525 | out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res)); |
@@ -1700,8 +1700,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1700 | 1700 | ||
1701 | if (res.type == RTN_LOCAL) { | 1701 | if (res.type == RTN_LOCAL) { |
1702 | err = fib_validate_source(skb, saddr, daddr, tos, | 1702 | err = fib_validate_source(skb, saddr, daddr, tos, |
1703 | LOOPBACK_IFINDEX, | 1703 | 0, dev, in_dev, &itag); |
1704 | dev, in_dev, &itag); | ||
1705 | if (err < 0) | 1704 | if (err < 0) |
1706 | goto martian_source_keep_err; | 1705 | goto martian_source_keep_err; |
1707 | goto local_input; | 1706 | goto local_input; |
@@ -2218,7 +2217,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
2218 | 2217 | ||
2219 | new->__use = 1; | 2218 | new->__use = 1; |
2220 | new->input = dst_discard; | 2219 | new->input = dst_discard; |
2221 | new->output = dst_discard; | 2220 | new->output = dst_discard_sk; |
2222 | 2221 | ||
2223 | new->dev = ort->dst.dev; | 2222 | new->dev = ort->dst.dev; |
2224 | if (new->dev) | 2223 | if (new->dev) |
@@ -2357,7 +2356,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, | |||
2357 | } | 2356 | } |
2358 | } else | 2357 | } else |
2359 | #endif | 2358 | #endif |
2360 | if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) | 2359 | if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex)) |
2361 | goto nla_put_failure; | 2360 | goto nla_put_failure; |
2362 | } | 2361 | } |
2363 | 2362 | ||
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 44eba052b43d..5cde8f263d40 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -45,10 +45,10 @@ static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; | |||
45 | /* Update system visible IP port range */ | 45 | /* Update system visible IP port range */ |
46 | static void set_local_port_range(struct net *net, int range[2]) | 46 | static void set_local_port_range(struct net *net, int range[2]) |
47 | { | 47 | { |
48 | write_seqlock(&net->ipv4.sysctl_local_ports.lock); | 48 | write_seqlock(&net->ipv4.ip_local_ports.lock); |
49 | net->ipv4.sysctl_local_ports.range[0] = range[0]; | 49 | net->ipv4.ip_local_ports.range[0] = range[0]; |
50 | net->ipv4.sysctl_local_ports.range[1] = range[1]; | 50 | net->ipv4.ip_local_ports.range[1] = range[1]; |
51 | write_sequnlock(&net->ipv4.sysctl_local_ports.lock); | 51 | write_sequnlock(&net->ipv4.ip_local_ports.lock); |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Validate changes from /proc interface. */ | 54 | /* Validate changes from /proc interface. */ |
@@ -57,7 +57,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write, | |||
57 | size_t *lenp, loff_t *ppos) | 57 | size_t *lenp, loff_t *ppos) |
58 | { | 58 | { |
59 | struct net *net = | 59 | struct net *net = |
60 | container_of(table->data, struct net, ipv4.sysctl_local_ports.range); | 60 | container_of(table->data, struct net, ipv4.ip_local_ports.range); |
61 | int ret; | 61 | int ret; |
62 | int range[2]; | 62 | int range[2]; |
63 | struct ctl_table tmp = { | 63 | struct ctl_table tmp = { |
@@ -87,14 +87,14 @@ static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low | |||
87 | { | 87 | { |
88 | kgid_t *data = table->data; | 88 | kgid_t *data = table->data; |
89 | struct net *net = | 89 | struct net *net = |
90 | container_of(table->data, struct net, ipv4.sysctl_ping_group_range); | 90 | container_of(table->data, struct net, ipv4.ping_group_range.range); |
91 | unsigned int seq; | 91 | unsigned int seq; |
92 | do { | 92 | do { |
93 | seq = read_seqbegin(&net->ipv4.sysctl_local_ports.lock); | 93 | seq = read_seqbegin(&net->ipv4.ip_local_ports.lock); |
94 | 94 | ||
95 | *low = data[0]; | 95 | *low = data[0]; |
96 | *high = data[1]; | 96 | *high = data[1]; |
97 | } while (read_seqretry(&net->ipv4.sysctl_local_ports.lock, seq)); | 97 | } while (read_seqretry(&net->ipv4.ip_local_ports.lock, seq)); |
98 | } | 98 | } |
99 | 99 | ||
100 | /* Update system visible IP port range */ | 100 | /* Update system visible IP port range */ |
@@ -102,11 +102,11 @@ static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t hig | |||
102 | { | 102 | { |
103 | kgid_t *data = table->data; | 103 | kgid_t *data = table->data; |
104 | struct net *net = | 104 | struct net *net = |
105 | container_of(table->data, struct net, ipv4.sysctl_ping_group_range); | 105 | container_of(table->data, struct net, ipv4.ping_group_range.range); |
106 | write_seqlock(&net->ipv4.sysctl_local_ports.lock); | 106 | write_seqlock(&net->ipv4.ip_local_ports.lock); |
107 | data[0] = low; | 107 | data[0] = low; |
108 | data[1] = high; | 108 | data[1] = high; |
109 | write_sequnlock(&net->ipv4.sysctl_local_ports.lock); | 109 | write_sequnlock(&net->ipv4.ip_local_ports.lock); |
110 | } | 110 | } |
111 | 111 | ||
112 | /* Validate changes from /proc interface. */ | 112 | /* Validate changes from /proc interface. */ |
@@ -805,7 +805,7 @@ static struct ctl_table ipv4_net_table[] = { | |||
805 | }, | 805 | }, |
806 | { | 806 | { |
807 | .procname = "ping_group_range", | 807 | .procname = "ping_group_range", |
808 | .data = &init_net.ipv4.sysctl_ping_group_range, | 808 | .data = &init_net.ipv4.ping_group_range.range, |
809 | .maxlen = sizeof(gid_t)*2, | 809 | .maxlen = sizeof(gid_t)*2, |
810 | .mode = 0644, | 810 | .mode = 0644, |
811 | .proc_handler = ipv4_ping_group_range, | 811 | .proc_handler = ipv4_ping_group_range, |
@@ -819,8 +819,8 @@ static struct ctl_table ipv4_net_table[] = { | |||
819 | }, | 819 | }, |
820 | { | 820 | { |
821 | .procname = "ip_local_port_range", | 821 | .procname = "ip_local_port_range", |
822 | .maxlen = sizeof(init_net.ipv4.sysctl_local_ports.range), | 822 | .maxlen = sizeof(init_net.ipv4.ip_local_ports.range), |
823 | .data = &init_net.ipv4.sysctl_local_ports.range, | 823 | .data = &init_net.ipv4.ip_local_ports.range, |
824 | .mode = 0644, | 824 | .mode = 0644, |
825 | .proc_handler = ipv4_local_port_range, | 825 | .proc_handler = ipv4_local_port_range, |
826 | }, | 826 | }, |
@@ -858,20 +858,6 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) | |||
858 | table[i].data += (void *)net - (void *)&init_net; | 858 | table[i].data += (void *)net - (void *)&init_net; |
859 | } | 859 | } |
860 | 860 | ||
861 | /* | ||
862 | * Sane defaults - nobody may create ping sockets. | ||
863 | * Boot scripts should set this to distro-specific group. | ||
864 | */ | ||
865 | net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1); | ||
866 | net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0); | ||
867 | |||
868 | /* | ||
869 | * Set defaults for local port range | ||
870 | */ | ||
871 | seqlock_init(&net->ipv4.sysctl_local_ports.lock); | ||
872 | net->ipv4.sysctl_local_ports.range[0] = 32768; | ||
873 | net->ipv4.sysctl_local_ports.range[1] = 61000; | ||
874 | |||
875 | net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", table); | 861 | net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", table); |
876 | if (net->ipv4.ipv4_hdr == NULL) | 862 | if (net->ipv4.ipv4_hdr == NULL) |
877 | goto err_reg; | 863 | goto err_reg; |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 8bf224516ba2..b4f1b29b08bd 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
@@ -409,7 +409,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) | |||
409 | ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; | 409 | ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; |
410 | ratio += cnt; | 410 | ratio += cnt; |
411 | 411 | ||
412 | ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT); | 412 | ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT); |
413 | } | 413 | } |
414 | 414 | ||
415 | /* Some calls are for duplicates without timetamps */ | 415 | /* Some calls are for duplicates without timetamps */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 699fb102e971..12d6016bdd9a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -981,7 +981,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
981 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, | 981 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, |
982 | tcp_skb_pcount(skb)); | 982 | tcp_skb_pcount(skb)); |
983 | 983 | ||
984 | err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl); | 984 | err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl); |
985 | if (likely(err <= 0)) | 985 | if (likely(err <= 0)) |
986 | return err; | 986 | return err; |
987 | 987 | ||
@@ -2441,8 +2441,14 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2441 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2441 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
2442 | } | 2442 | } |
2443 | 2443 | ||
2444 | if (likely(!err)) | 2444 | if (likely(!err)) { |
2445 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; | 2445 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; |
2446 | /* Update global TCP statistics. */ | ||
2447 | TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
2448 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) | ||
2449 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | ||
2450 | tp->total_retrans++; | ||
2451 | } | ||
2446 | return err; | 2452 | return err; |
2447 | } | 2453 | } |
2448 | 2454 | ||
@@ -2452,12 +2458,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2452 | int err = __tcp_retransmit_skb(sk, skb); | 2458 | int err = __tcp_retransmit_skb(sk, skb); |
2453 | 2459 | ||
2454 | if (err == 0) { | 2460 | if (err == 0) { |
2455 | /* Update global TCP statistics. */ | ||
2456 | TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
2457 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) | ||
2458 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | ||
2459 | tp->total_retrans++; | ||
2460 | |||
2461 | #if FASTRETRANS_DEBUG > 0 | 2461 | #if FASTRETRANS_DEBUG > 0 |
2462 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { | 2462 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { |
2463 | net_dbg_ratelimited("retrans_out leaked\n"); | 2463 | net_dbg_ratelimited("retrans_out leaked\n"); |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index baa0f63731fd..186a8ecf92fa 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -62,10 +62,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
62 | if (err) | 62 | if (err) |
63 | return err; | 63 | return err; |
64 | 64 | ||
65 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | 65 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; |
66 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED; | ||
67 | |||
68 | skb->protocol = htons(ETH_P_IP); | ||
69 | 66 | ||
70 | return x->outer_mode->output2(x, skb); | 67 | return x->outer_mode->output2(x, skb); |
71 | } | 68 | } |
@@ -73,27 +70,34 @@ EXPORT_SYMBOL(xfrm4_prepare_output); | |||
73 | 70 | ||
74 | int xfrm4_output_finish(struct sk_buff *skb) | 71 | int xfrm4_output_finish(struct sk_buff *skb) |
75 | { | 72 | { |
76 | #ifdef CONFIG_NETFILTER | 73 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
77 | if (!skb_dst(skb)->xfrm) { | 74 | skb->protocol = htons(ETH_P_IP); |
78 | IPCB(skb)->flags |= IPSKB_REROUTED; | ||
79 | return dst_output(skb); | ||
80 | } | ||
81 | 75 | ||
76 | #ifdef CONFIG_NETFILTER | ||
82 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; | 77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; |
83 | #endif | 78 | #endif |
84 | 79 | ||
85 | skb->protocol = htons(ETH_P_IP); | ||
86 | return xfrm_output(skb); | 80 | return xfrm_output(skb); |
87 | } | 81 | } |
88 | 82 | ||
89 | int xfrm4_output(struct sk_buff *skb) | 83 | static int __xfrm4_output(struct sk_buff *skb) |
90 | { | 84 | { |
91 | struct dst_entry *dst = skb_dst(skb); | 85 | struct xfrm_state *x = skb_dst(skb)->xfrm; |
92 | struct xfrm_state *x = dst->xfrm; | 86 | |
87 | #ifdef CONFIG_NETFILTER | ||
88 | if (!x) { | ||
89 | IPCB(skb)->flags |= IPSKB_REROUTED; | ||
90 | return dst_output(skb); | ||
91 | } | ||
92 | #endif | ||
93 | 93 | ||
94 | return x->outer_mode->afinfo->output_finish(skb); | ||
95 | } | ||
96 | |||
97 | int xfrm4_output(struct sock *sk, struct sk_buff *skb) | ||
98 | { | ||
94 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, | 99 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, |
95 | NULL, dst->dev, | 100 | NULL, skb_dst(skb)->dev, __xfrm4_output, |
96 | x->outer_mode->afinfo->output_finish, | ||
97 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 101 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
98 | } | 102 | } |
99 | 103 | ||
diff --git a/net/ipv4/xfrm4_protocol.c b/net/ipv4/xfrm4_protocol.c index 7f7b243e8139..a2ce0101eaac 100644 --- a/net/ipv4/xfrm4_protocol.c +++ b/net/ipv4/xfrm4_protocol.c | |||
@@ -50,8 +50,12 @@ int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err) | |||
50 | { | 50 | { |
51 | int ret; | 51 | int ret; |
52 | struct xfrm4_protocol *handler; | 52 | struct xfrm4_protocol *handler; |
53 | struct xfrm4_protocol __rcu **head = proto_handlers(protocol); | ||
53 | 54 | ||
54 | for_each_protocol_rcu(*proto_handlers(protocol), handler) | 55 | if (!head) |
56 | return 0; | ||
57 | |||
58 | for_each_protocol_rcu(*head, handler) | ||
55 | if ((ret = handler->cb_handler(skb, err)) <= 0) | 59 | if ((ret = handler->cb_handler(skb, err)) <= 0) |
56 | return ret; | 60 | return ret; |
57 | 61 | ||
@@ -64,15 +68,20 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
64 | { | 68 | { |
65 | int ret; | 69 | int ret; |
66 | struct xfrm4_protocol *handler; | 70 | struct xfrm4_protocol *handler; |
71 | struct xfrm4_protocol __rcu **head = proto_handlers(nexthdr); | ||
67 | 72 | ||
68 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; | 73 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; |
69 | XFRM_SPI_SKB_CB(skb)->family = AF_INET; | 74 | XFRM_SPI_SKB_CB(skb)->family = AF_INET; |
70 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); | 75 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); |
71 | 76 | ||
72 | for_each_protocol_rcu(*proto_handlers(nexthdr), handler) | 77 | if (!head) |
78 | goto out; | ||
79 | |||
80 | for_each_protocol_rcu(*head, handler) | ||
73 | if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL) | 81 | if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL) |
74 | return ret; | 82 | return ret; |
75 | 83 | ||
84 | out: | ||
76 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 85 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
77 | 86 | ||
78 | kfree_skb(skb); | 87 | kfree_skb(skb); |
@@ -208,6 +217,9 @@ int xfrm4_protocol_register(struct xfrm4_protocol *handler, | |||
208 | int ret = -EEXIST; | 217 | int ret = -EEXIST; |
209 | int priority = handler->priority; | 218 | int priority = handler->priority; |
210 | 219 | ||
220 | if (!proto_handlers(protocol) || !netproto(protocol)) | ||
221 | return -EINVAL; | ||
222 | |||
211 | mutex_lock(&xfrm4_protocol_mutex); | 223 | mutex_lock(&xfrm4_protocol_mutex); |
212 | 224 | ||
213 | if (!rcu_dereference_protected(*proto_handlers(protocol), | 225 | if (!rcu_dereference_protected(*proto_handlers(protocol), |
@@ -250,6 +262,9 @@ int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, | |||
250 | struct xfrm4_protocol *t; | 262 | struct xfrm4_protocol *t; |
251 | int ret = -ENOENT; | 263 | int ret = -ENOENT; |
252 | 264 | ||
265 | if (!proto_handlers(protocol) || !netproto(protocol)) | ||
266 | return -EINVAL; | ||
267 | |||
253 | mutex_lock(&xfrm4_protocol_mutex); | 268 | mutex_lock(&xfrm4_protocol_mutex); |
254 | 269 | ||
255 | for (pprev = proto_handlers(protocol); | 270 | for (pprev = proto_handlers(protocol); |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c9138189415a..d4ade34ab375 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -224,9 +224,8 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, | |||
224 | return dst; | 224 | return dst; |
225 | } | 225 | } |
226 | 226 | ||
227 | int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | 227 | int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused) |
228 | { | 228 | { |
229 | struct sock *sk = skb->sk; | ||
230 | struct ipv6_pinfo *np = inet6_sk(sk); | 229 | struct ipv6_pinfo *np = inet6_sk(sk); |
231 | struct flowi6 fl6; | 230 | struct flowi6 fl6; |
232 | struct dst_entry *dst; | 231 | struct dst_entry *dst; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 34e0ded5c14b..87891f5f57b5 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1459,7 +1459,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
1459 | 1459 | ||
1460 | if (w->skip) { | 1460 | if (w->skip) { |
1461 | w->skip--; | 1461 | w->skip--; |
1462 | continue; | 1462 | goto skip; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | err = w->func(w); | 1465 | err = w->func(w); |
@@ -1469,6 +1469,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
1469 | w->count++; | 1469 | w->count++; |
1470 | continue; | 1470 | continue; |
1471 | } | 1471 | } |
1472 | skip: | ||
1472 | w->state = FWS_U; | 1473 | w->state = FWS_U; |
1473 | case FWS_U: | 1474 | case FWS_U: |
1474 | if (fn == w->root) | 1475 | if (fn == w->root) |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index c98338b81d30..9d921462b57f 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -1559,6 +1559,15 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[], | |||
1559 | return 0; | 1559 | return 0; |
1560 | } | 1560 | } |
1561 | 1561 | ||
1562 | static void ip6gre_dellink(struct net_device *dev, struct list_head *head) | ||
1563 | { | ||
1564 | struct net *net = dev_net(dev); | ||
1565 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); | ||
1566 | |||
1567 | if (dev != ign->fb_tunnel_dev) | ||
1568 | unregister_netdevice_queue(dev, head); | ||
1569 | } | ||
1570 | |||
1562 | static size_t ip6gre_get_size(const struct net_device *dev) | 1571 | static size_t ip6gre_get_size(const struct net_device *dev) |
1563 | { | 1572 | { |
1564 | return | 1573 | return |
@@ -1636,6 +1645,7 @@ static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { | |||
1636 | .validate = ip6gre_tunnel_validate, | 1645 | .validate = ip6gre_tunnel_validate, |
1637 | .newlink = ip6gre_newlink, | 1646 | .newlink = ip6gre_newlink, |
1638 | .changelink = ip6gre_changelink, | 1647 | .changelink = ip6gre_changelink, |
1648 | .dellink = ip6gre_dellink, | ||
1639 | .get_size = ip6gre_get_size, | 1649 | .get_size = ip6gre_get_size, |
1640 | .fill_info = ip6gre_fill_info, | 1650 | .fill_info = ip6gre_fill_info, |
1641 | }; | 1651 | }; |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 59f95affceb0..b2f091566f88 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -196,7 +196,6 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
196 | unsigned int off; | 196 | unsigned int off; |
197 | u16 flush = 1; | 197 | u16 flush = 1; |
198 | int proto; | 198 | int proto; |
199 | __wsum csum; | ||
200 | 199 | ||
201 | off = skb_gro_offset(skb); | 200 | off = skb_gro_offset(skb); |
202 | hlen = off + sizeof(*iph); | 201 | hlen = off + sizeof(*iph); |
@@ -264,13 +263,10 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
264 | 263 | ||
265 | NAPI_GRO_CB(skb)->flush |= flush; | 264 | NAPI_GRO_CB(skb)->flush |= flush; |
266 | 265 | ||
267 | csum = skb->csum; | 266 | skb_gro_postpull_rcsum(skb, iph, nlen); |
268 | skb_postpull_rcsum(skb, iph, skb_network_header_len(skb)); | ||
269 | 267 | ||
270 | pp = ops->callbacks.gro_receive(head, skb); | 268 | pp = ops->callbacks.gro_receive(head, skb); |
271 | 269 | ||
272 | skb->csum = csum; | ||
273 | |||
274 | out_unlock: | 270 | out_unlock: |
275 | rcu_read_unlock(); | 271 | rcu_read_unlock(); |
276 | 272 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 3284d61577c0..fbf11562b54c 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb) | |||
132 | return ip6_finish_output2(skb); | 132 | return ip6_finish_output2(skb); |
133 | } | 133 | } |
134 | 134 | ||
135 | int ip6_output(struct sk_buff *skb) | 135 | int ip6_output(struct sock *sk, struct sk_buff *skb) |
136 | { | 136 | { |
137 | struct net_device *dev = skb_dst(skb)->dev; | 137 | struct net_device *dev = skb_dst(skb)->dev; |
138 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); | 138 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
@@ -344,12 +344,16 @@ static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) | |||
344 | 344 | ||
345 | static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) | 345 | static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) |
346 | { | 346 | { |
347 | if (skb->len <= mtu || skb->local_df) | 347 | if (skb->len <= mtu) |
348 | return false; | 348 | return false; |
349 | 349 | ||
350 | /* ipv6 conntrack defrag sets max_frag_size + local_df */ | ||
350 | if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) | 351 | if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) |
351 | return true; | 352 | return true; |
352 | 353 | ||
354 | if (skb->local_df) | ||
355 | return false; | ||
356 | |||
353 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) | 357 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) |
354 | return false; | 358 | return false; |
355 | 359 | ||
@@ -1225,7 +1229,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1225 | unsigned int maxnonfragsize, headersize; | 1229 | unsigned int maxnonfragsize, headersize; |
1226 | 1230 | ||
1227 | headersize = sizeof(struct ipv6hdr) + | 1231 | headersize = sizeof(struct ipv6hdr) + |
1228 | (opt ? opt->tot_len : 0) + | 1232 | (opt ? opt->opt_flen + opt->opt_nflen : 0) + |
1229 | (dst_allfrag(&rt->dst) ? | 1233 | (dst_allfrag(&rt->dst) ? |
1230 | sizeof(struct frag_hdr) : 0) + | 1234 | sizeof(struct frag_hdr) : 0) + |
1231 | rt->rt6i_nfheader_len; | 1235 | rt->rt6i_nfheader_len; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index e1df691d78be..f6a66bb4114d 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1340,8 +1340,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1340 | int err = 0; | 1340 | int err = 0; |
1341 | struct ip6_tnl_parm p; | 1341 | struct ip6_tnl_parm p; |
1342 | struct __ip6_tnl_parm p1; | 1342 | struct __ip6_tnl_parm p1; |
1343 | struct ip6_tnl *t = NULL; | 1343 | struct ip6_tnl *t = netdev_priv(dev); |
1344 | struct net *net = dev_net(dev); | 1344 | struct net *net = t->net; |
1345 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); | 1345 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); |
1346 | 1346 | ||
1347 | switch (cmd) { | 1347 | switch (cmd) { |
@@ -1353,11 +1353,11 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1353 | } | 1353 | } |
1354 | ip6_tnl_parm_from_user(&p1, &p); | 1354 | ip6_tnl_parm_from_user(&p1, &p); |
1355 | t = ip6_tnl_locate(net, &p1, 0); | 1355 | t = ip6_tnl_locate(net, &p1, 0); |
1356 | if (t == NULL) | ||
1357 | t = netdev_priv(dev); | ||
1356 | } else { | 1358 | } else { |
1357 | memset(&p, 0, sizeof(p)); | 1359 | memset(&p, 0, sizeof(p)); |
1358 | } | 1360 | } |
1359 | if (t == NULL) | ||
1360 | t = netdev_priv(dev); | ||
1361 | ip6_tnl_parm_to_user(&p, &t->parms); | 1361 | ip6_tnl_parm_to_user(&p, &t->parms); |
1362 | if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { | 1362 | if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { |
1363 | err = -EFAULT; | 1363 | err = -EFAULT; |
@@ -1557,7 +1557,7 @@ static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
1557 | { | 1557 | { |
1558 | u8 proto; | 1558 | u8 proto; |
1559 | 1559 | ||
1560 | if (!data) | 1560 | if (!data || !data[IFLA_IPTUN_PROTO]) |
1561 | return 0; | 1561 | return 0; |
1562 | 1562 | ||
1563 | proto = nla_get_u8(data[IFLA_IPTUN_PROTO]); | 1563 | proto = nla_get_u8(data[IFLA_IPTUN_PROTO]); |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index b7c0f827140b..6cc9f9371cc5 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -511,6 +511,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
511 | u8 type, u8 code, int offset, __be32 info) | 511 | u8 type, u8 code, int offset, __be32 info) |
512 | { | 512 | { |
513 | __be32 spi; | 513 | __be32 spi; |
514 | __u32 mark; | ||
514 | struct xfrm_state *x; | 515 | struct xfrm_state *x; |
515 | struct ip6_tnl *t; | 516 | struct ip6_tnl *t; |
516 | struct ip_esp_hdr *esph; | 517 | struct ip_esp_hdr *esph; |
@@ -524,6 +525,8 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
524 | if (!t) | 525 | if (!t) |
525 | return -1; | 526 | return -1; |
526 | 527 | ||
528 | mark = be32_to_cpu(t->parms.o_key); | ||
529 | |||
527 | switch (protocol) { | 530 | switch (protocol) { |
528 | case IPPROTO_ESP: | 531 | case IPPROTO_ESP: |
529 | esph = (struct ip_esp_hdr *)(skb->data + offset); | 532 | esph = (struct ip_esp_hdr *)(skb->data + offset); |
@@ -545,7 +548,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
545 | type != NDISC_REDIRECT) | 548 | type != NDISC_REDIRECT) |
546 | return 0; | 549 | return 0; |
547 | 550 | ||
548 | x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, | 551 | x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr, |
549 | spi, protocol, AF_INET6); | 552 | spi, protocol, AF_INET6); |
550 | if (!x) | 553 | if (!x) |
551 | return 0; | 554 | return 0; |
@@ -1097,7 +1100,6 @@ static int __init vti6_tunnel_init(void) | |||
1097 | 1100 | ||
1098 | err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP); | 1101 | err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP); |
1099 | if (err < 0) { | 1102 | if (err < 0) { |
1100 | unregister_pernet_device(&vti6_net_ops); | ||
1101 | pr_err("%s: can't register vti6 protocol\n", __func__); | 1103 | pr_err("%s: can't register vti6 protocol\n", __func__); |
1102 | 1104 | ||
1103 | goto out; | 1105 | goto out; |
@@ -1106,7 +1108,6 @@ static int __init vti6_tunnel_init(void) | |||
1106 | err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH); | 1108 | err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH); |
1107 | if (err < 0) { | 1109 | if (err < 0) { |
1108 | xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); | 1110 | xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); |
1109 | unregister_pernet_device(&vti6_net_ops); | ||
1110 | pr_err("%s: can't register vti6 protocol\n", __func__); | 1111 | pr_err("%s: can't register vti6 protocol\n", __func__); |
1111 | 1112 | ||
1112 | goto out; | 1113 | goto out; |
@@ -1116,7 +1117,6 @@ static int __init vti6_tunnel_init(void) | |||
1116 | if (err < 0) { | 1117 | if (err < 0) { |
1117 | xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH); | 1118 | xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH); |
1118 | xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); | 1119 | xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); |
1119 | unregister_pernet_device(&vti6_net_ops); | ||
1120 | pr_err("%s: can't register vti6 protocol\n", __func__); | 1120 | pr_err("%s: can't register vti6 protocol\n", __func__); |
1121 | 1121 | ||
1122 | goto out; | 1122 | goto out; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 8737400af0a0..8250474ab7dc 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, | |||
700 | struct mr6_table *mrt; | 700 | struct mr6_table *mrt; |
701 | struct flowi6 fl6 = { | 701 | struct flowi6 fl6 = { |
702 | .flowi6_oif = dev->ifindex, | 702 | .flowi6_oif = dev->ifindex, |
703 | .flowi6_iif = skb->skb_iif, | 703 | .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, |
704 | .flowi6_mark = skb->mark, | 704 | .flowi6_mark = skb->mark, |
705 | }; | 705 | }; |
706 | int err; | 706 | int err; |
@@ -1633,7 +1633,7 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) | |||
1633 | { | 1633 | { |
1634 | struct mr6_table *mrt; | 1634 | struct mr6_table *mrt; |
1635 | struct flowi6 fl6 = { | 1635 | struct flowi6 fl6 = { |
1636 | .flowi6_iif = skb->skb_iif, | 1636 | .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, |
1637 | .flowi6_oif = skb->dev->ifindex, | 1637 | .flowi6_oif = skb->dev->ifindex, |
1638 | .flowi6_mark = skb->mark, | 1638 | .flowi6_mark = skb->mark, |
1639 | }; | 1639 | }; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 09a22f4f36c9..ca8d4ea48a5d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -851,7 +851,7 @@ out: | |||
851 | static void ndisc_recv_na(struct sk_buff *skb) | 851 | static void ndisc_recv_na(struct sk_buff *skb) |
852 | { | 852 | { |
853 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); | 853 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); |
854 | const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; | 854 | struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; |
855 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; | 855 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; |
856 | u8 *lladdr = NULL; | 856 | u8 *lladdr = NULL; |
857 | u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + | 857 | u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + |
@@ -944,10 +944,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
944 | /* | 944 | /* |
945 | * Change: router to host | 945 | * Change: router to host |
946 | */ | 946 | */ |
947 | struct rt6_info *rt; | 947 | rt6_clean_tohost(dev_net(dev), saddr); |
948 | rt = rt6_get_dflt_router(saddr, dev); | ||
949 | if (rt) | ||
950 | ip6_del_rt(rt); | ||
951 | } | 948 | } |
952 | 949 | ||
953 | out: | 950 | out: |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 95f3f1da0d7f..d38e6a8d8b9f 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -30,13 +30,15 @@ int ip6_route_me_harder(struct sk_buff *skb) | |||
30 | .daddr = iph->daddr, | 30 | .daddr = iph->daddr, |
31 | .saddr = iph->saddr, | 31 | .saddr = iph->saddr, |
32 | }; | 32 | }; |
33 | int err; | ||
33 | 34 | ||
34 | dst = ip6_route_output(net, skb->sk, &fl6); | 35 | dst = ip6_route_output(net, skb->sk, &fl6); |
35 | if (dst->error) { | 36 | err = dst->error; |
37 | if (err) { | ||
36 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 38 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
37 | LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); | 39 | LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); |
38 | dst_release(dst); | 40 | dst_release(dst); |
39 | return dst->error; | 41 | return err; |
40 | } | 42 | } |
41 | 43 | ||
42 | /* Drop old route. */ | 44 | /* Drop old route. */ |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index e0983f3648a6..790e0c6b19e1 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -33,6 +33,7 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
33 | struct ipv6hdr *iph = ipv6_hdr(skb); | 33 | struct ipv6hdr *iph = ipv6_hdr(skb); |
34 | bool ret = false; | 34 | bool ret = false; |
35 | struct flowi6 fl6 = { | 35 | struct flowi6 fl6 = { |
36 | .flowi6_iif = LOOPBACK_IFINDEX, | ||
36 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, | 37 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, |
37 | .flowi6_proto = iph->nexthdr, | 38 | .flowi6_proto = iph->nexthdr, |
38 | .daddr = iph->saddr, | 39 | .daddr = iph->saddr, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5015c50a5ba7..6ebdb7b6744c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -84,9 +84,9 @@ static void ip6_dst_ifdown(struct dst_entry *, | |||
84 | static int ip6_dst_gc(struct dst_ops *ops); | 84 | static int ip6_dst_gc(struct dst_ops *ops); |
85 | 85 | ||
86 | static int ip6_pkt_discard(struct sk_buff *skb); | 86 | static int ip6_pkt_discard(struct sk_buff *skb); |
87 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 87 | static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb); |
88 | static int ip6_pkt_prohibit(struct sk_buff *skb); | 88 | static int ip6_pkt_prohibit(struct sk_buff *skb); |
89 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | 89 | static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb); |
90 | static void ip6_link_failure(struct sk_buff *skb); | 90 | static void ip6_link_failure(struct sk_buff *skb); |
91 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 91 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
92 | struct sk_buff *skb, u32 mtu); | 92 | struct sk_buff *skb, u32 mtu); |
@@ -290,7 +290,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = { | |||
290 | .obsolete = DST_OBSOLETE_FORCE_CHK, | 290 | .obsolete = DST_OBSOLETE_FORCE_CHK, |
291 | .error = -EINVAL, | 291 | .error = -EINVAL, |
292 | .input = dst_discard, | 292 | .input = dst_discard, |
293 | .output = dst_discard, | 293 | .output = dst_discard_sk, |
294 | }, | 294 | }, |
295 | .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), | 295 | .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), |
296 | .rt6i_protocol = RTPROT_KERNEL, | 296 | .rt6i_protocol = RTPROT_KERNEL, |
@@ -1058,7 +1058,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori | |||
1058 | 1058 | ||
1059 | new->__use = 1; | 1059 | new->__use = 1; |
1060 | new->input = dst_discard; | 1060 | new->input = dst_discard; |
1061 | new->output = dst_discard; | 1061 | new->output = dst_discard_sk; |
1062 | 1062 | ||
1063 | if (dst_metrics_read_only(&ort->dst)) | 1063 | if (dst_metrics_read_only(&ort->dst)) |
1064 | new->_metrics = ort->dst._metrics; | 1064 | new->_metrics = ort->dst._metrics; |
@@ -1273,6 +1273,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark) | |||
1273 | struct flowi6 fl6; | 1273 | struct flowi6 fl6; |
1274 | 1274 | ||
1275 | memset(&fl6, 0, sizeof(fl6)); | 1275 | memset(&fl6, 0, sizeof(fl6)); |
1276 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1276 | fl6.flowi6_oif = oif; | 1277 | fl6.flowi6_oif = oif; |
1277 | fl6.flowi6_mark = mark; | 1278 | fl6.flowi6_mark = mark; |
1278 | fl6.daddr = iph->daddr; | 1279 | fl6.daddr = iph->daddr; |
@@ -1294,6 +1295,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif, | |||
1294 | struct flowi6 fl6; | 1295 | struct flowi6 fl6; |
1295 | 1296 | ||
1296 | memset(&fl6, 0, sizeof(fl6)); | 1297 | memset(&fl6, 0, sizeof(fl6)); |
1298 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1297 | fl6.flowi6_oif = oif; | 1299 | fl6.flowi6_oif = oif; |
1298 | fl6.flowi6_mark = mark; | 1300 | fl6.flowi6_mark = mark; |
1299 | fl6.daddr = msg->dest; | 1301 | fl6.daddr = msg->dest; |
@@ -1338,7 +1340,7 @@ static unsigned int ip6_mtu(const struct dst_entry *dst) | |||
1338 | unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); | 1340 | unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); |
1339 | 1341 | ||
1340 | if (mtu) | 1342 | if (mtu) |
1341 | return mtu; | 1343 | goto out; |
1342 | 1344 | ||
1343 | mtu = IPV6_MIN_MTU; | 1345 | mtu = IPV6_MIN_MTU; |
1344 | 1346 | ||
@@ -1348,7 +1350,8 @@ static unsigned int ip6_mtu(const struct dst_entry *dst) | |||
1348 | mtu = idev->cnf.mtu6; | 1350 | mtu = idev->cnf.mtu6; |
1349 | rcu_read_unlock(); | 1351 | rcu_read_unlock(); |
1350 | 1352 | ||
1351 | return mtu; | 1353 | out: |
1354 | return min_t(unsigned int, mtu, IP6_MAX_MTU); | ||
1352 | } | 1355 | } |
1353 | 1356 | ||
1354 | static struct dst_entry *icmp6_dst_gc_list; | 1357 | static struct dst_entry *icmp6_dst_gc_list; |
@@ -1576,7 +1579,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1576 | switch (cfg->fc_type) { | 1579 | switch (cfg->fc_type) { |
1577 | case RTN_BLACKHOLE: | 1580 | case RTN_BLACKHOLE: |
1578 | rt->dst.error = -EINVAL; | 1581 | rt->dst.error = -EINVAL; |
1579 | rt->dst.output = dst_discard; | 1582 | rt->dst.output = dst_discard_sk; |
1580 | rt->dst.input = dst_discard; | 1583 | rt->dst.input = dst_discard; |
1581 | break; | 1584 | break; |
1582 | case RTN_PROHIBIT: | 1585 | case RTN_PROHIBIT: |
@@ -2128,7 +2131,7 @@ static int ip6_pkt_discard(struct sk_buff *skb) | |||
2128 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); | 2131 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); |
2129 | } | 2132 | } |
2130 | 2133 | ||
2131 | static int ip6_pkt_discard_out(struct sk_buff *skb) | 2134 | static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb) |
2132 | { | 2135 | { |
2133 | skb->dev = skb_dst(skb)->dev; | 2136 | skb->dev = skb_dst(skb)->dev; |
2134 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2137 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
@@ -2139,7 +2142,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb) | |||
2139 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2142 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
2140 | } | 2143 | } |
2141 | 2144 | ||
2142 | static int ip6_pkt_prohibit_out(struct sk_buff *skb) | 2145 | static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb) |
2143 | { | 2146 | { |
2144 | skb->dev = skb_dst(skb)->dev; | 2147 | skb->dev = skb_dst(skb)->dev; |
2145 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2148 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
@@ -2231,6 +2234,27 @@ void rt6_remove_prefsrc(struct inet6_ifaddr *ifp) | |||
2231 | fib6_clean_all(net, fib6_remove_prefsrc, &adni); | 2234 | fib6_clean_all(net, fib6_remove_prefsrc, &adni); |
2232 | } | 2235 | } |
2233 | 2236 | ||
2237 | #define RTF_RA_ROUTER (RTF_ADDRCONF | RTF_DEFAULT | RTF_GATEWAY) | ||
2238 | #define RTF_CACHE_GATEWAY (RTF_GATEWAY | RTF_CACHE) | ||
2239 | |||
2240 | /* Remove routers and update dst entries when gateway turn into host. */ | ||
2241 | static int fib6_clean_tohost(struct rt6_info *rt, void *arg) | ||
2242 | { | ||
2243 | struct in6_addr *gateway = (struct in6_addr *)arg; | ||
2244 | |||
2245 | if ((((rt->rt6i_flags & RTF_RA_ROUTER) == RTF_RA_ROUTER) || | ||
2246 | ((rt->rt6i_flags & RTF_CACHE_GATEWAY) == RTF_CACHE_GATEWAY)) && | ||
2247 | ipv6_addr_equal(gateway, &rt->rt6i_gateway)) { | ||
2248 | return -1; | ||
2249 | } | ||
2250 | return 0; | ||
2251 | } | ||
2252 | |||
2253 | void rt6_clean_tohost(struct net *net, struct in6_addr *gateway) | ||
2254 | { | ||
2255 | fib6_clean_all(net, fib6_clean_tohost, gateway); | ||
2256 | } | ||
2257 | |||
2234 | struct arg_dev_net { | 2258 | struct arg_dev_net { |
2235 | struct net_device *dev; | 2259 | struct net_device *dev; |
2236 | struct net *net; | 2260 | struct net *net; |
@@ -2706,6 +2730,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh) | |||
2706 | if (tb[RTA_OIF]) | 2730 | if (tb[RTA_OIF]) |
2707 | oif = nla_get_u32(tb[RTA_OIF]); | 2731 | oif = nla_get_u32(tb[RTA_OIF]); |
2708 | 2732 | ||
2733 | if (tb[RTA_MARK]) | ||
2734 | fl6.flowi6_mark = nla_get_u32(tb[RTA_MARK]); | ||
2735 | |||
2709 | if (iif) { | 2736 | if (iif) { |
2710 | struct net_device *dev; | 2737 | struct net_device *dev; |
2711 | int flags = 0; | 2738 | int flags = 0; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1693c8d885f0..e5a453ca302e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -974,8 +974,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
974 | goto out; | 974 | goto out; |
975 | } | 975 | } |
976 | 976 | ||
977 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, | 977 | err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, |
978 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 978 | IPPROTO_IPV6, tos, ttl, df, |
979 | !net_eq(tunnel->net, dev_net(dev))); | ||
979 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 980 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
980 | return NETDEV_TX_OK; | 981 | return NETDEV_TX_OK; |
981 | 982 | ||
@@ -1126,8 +1127,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1126 | int err = 0; | 1127 | int err = 0; |
1127 | struct ip_tunnel_parm p; | 1128 | struct ip_tunnel_parm p; |
1128 | struct ip_tunnel_prl prl; | 1129 | struct ip_tunnel_prl prl; |
1129 | struct ip_tunnel *t; | 1130 | struct ip_tunnel *t = netdev_priv(dev); |
1130 | struct net *net = dev_net(dev); | 1131 | struct net *net = t->net; |
1131 | struct sit_net *sitn = net_generic(net, sit_net_id); | 1132 | struct sit_net *sitn = net_generic(net, sit_net_id); |
1132 | #ifdef CONFIG_IPV6_SIT_6RD | 1133 | #ifdef CONFIG_IPV6_SIT_6RD |
1133 | struct ip_tunnel_6rd ip6rd; | 1134 | struct ip_tunnel_6rd ip6rd; |
@@ -1138,16 +1139,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1138 | #ifdef CONFIG_IPV6_SIT_6RD | 1139 | #ifdef CONFIG_IPV6_SIT_6RD |
1139 | case SIOCGET6RD: | 1140 | case SIOCGET6RD: |
1140 | #endif | 1141 | #endif |
1141 | t = NULL; | ||
1142 | if (dev == sitn->fb_tunnel_dev) { | 1142 | if (dev == sitn->fb_tunnel_dev) { |
1143 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { | 1143 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { |
1144 | err = -EFAULT; | 1144 | err = -EFAULT; |
1145 | break; | 1145 | break; |
1146 | } | 1146 | } |
1147 | t = ipip6_tunnel_locate(net, &p, 0); | 1147 | t = ipip6_tunnel_locate(net, &p, 0); |
1148 | if (t == NULL) | ||
1149 | t = netdev_priv(dev); | ||
1148 | } | 1150 | } |
1149 | if (t == NULL) | ||
1150 | t = netdev_priv(dev); | ||
1151 | 1151 | ||
1152 | err = -EFAULT; | 1152 | err = -EFAULT; |
1153 | if (cmd == SIOCGETTUNNEL) { | 1153 | if (cmd == SIOCGETTUNNEL) { |
@@ -1243,9 +1243,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1243 | err = -EINVAL; | 1243 | err = -EINVAL; |
1244 | if (dev == sitn->fb_tunnel_dev) | 1244 | if (dev == sitn->fb_tunnel_dev) |
1245 | goto done; | 1245 | goto done; |
1246 | err = -ENOENT; | ||
1247 | if (!(t = netdev_priv(dev))) | ||
1248 | goto done; | ||
1249 | err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); | 1246 | err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); |
1250 | break; | 1247 | break; |
1251 | 1248 | ||
@@ -1261,9 +1258,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1261 | err = -EFAULT; | 1258 | err = -EFAULT; |
1262 | if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) | 1259 | if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) |
1263 | goto done; | 1260 | goto done; |
1264 | err = -ENOENT; | ||
1265 | if (!(t = netdev_priv(dev))) | ||
1266 | goto done; | ||
1267 | 1261 | ||
1268 | switch (cmd) { | 1262 | switch (cmd) { |
1269 | case SIOCDELPRL: | 1263 | case SIOCDELPRL: |
@@ -1291,8 +1285,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1291 | sizeof(ip6rd))) | 1285 | sizeof(ip6rd))) |
1292 | goto done; | 1286 | goto done; |
1293 | 1287 | ||
1294 | t = netdev_priv(dev); | ||
1295 | |||
1296 | if (cmd != SIOCDEL6RD) { | 1288 | if (cmd != SIOCDEL6RD) { |
1297 | err = ipip6_tunnel_update_6rd(t, &ip6rd); | 1289 | err = ipip6_tunnel_update_6rd(t, &ip6rd); |
1298 | if (err < 0) | 1290 | if (err < 0) |
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 0d78132ff18a..8517d3cd1aed 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
@@ -42,7 +42,7 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
42 | if (NAPI_GRO_CB(skb)->flush) | 42 | if (NAPI_GRO_CB(skb)->flush) |
43 | goto skip_csum; | 43 | goto skip_csum; |
44 | 44 | ||
45 | wsum = skb->csum; | 45 | wsum = NAPI_GRO_CB(skb)->csum; |
46 | 46 | ||
47 | switch (skb->ip_summed) { | 47 | switch (skb->ip_summed) { |
48 | case CHECKSUM_NONE: | 48 | case CHECKSUM_NONE: |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6cd625e37706..b930d080c66f 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -114,12 +114,6 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
114 | if (err) | 114 | if (err) |
115 | return err; | 115 | return err; |
116 | 116 | ||
117 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||
118 | #ifdef CONFIG_NETFILTER | ||
119 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | ||
120 | #endif | ||
121 | |||
122 | skb->protocol = htons(ETH_P_IPV6); | ||
123 | skb->local_df = 1; | 117 | skb->local_df = 1; |
124 | 118 | ||
125 | return x->outer_mode->output2(x, skb); | 119 | return x->outer_mode->output2(x, skb); |
@@ -128,11 +122,13 @@ EXPORT_SYMBOL(xfrm6_prepare_output); | |||
128 | 122 | ||
129 | int xfrm6_output_finish(struct sk_buff *skb) | 123 | int xfrm6_output_finish(struct sk_buff *skb) |
130 | { | 124 | { |
125 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||
126 | skb->protocol = htons(ETH_P_IPV6); | ||
127 | |||
131 | #ifdef CONFIG_NETFILTER | 128 | #ifdef CONFIG_NETFILTER |
132 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | 129 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; |
133 | #endif | 130 | #endif |
134 | 131 | ||
135 | skb->protocol = htons(ETH_P_IPV6); | ||
136 | return xfrm_output(skb); | 132 | return xfrm_output(skb); |
137 | } | 133 | } |
138 | 134 | ||
@@ -142,6 +138,13 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
142 | struct xfrm_state *x = dst->xfrm; | 138 | struct xfrm_state *x = dst->xfrm; |
143 | int mtu; | 139 | int mtu; |
144 | 140 | ||
141 | #ifdef CONFIG_NETFILTER | ||
142 | if (!x) { | ||
143 | IP6CB(skb)->flags |= IP6SKB_REROUTED; | ||
144 | return dst_output(skb); | ||
145 | } | ||
146 | #endif | ||
147 | |||
145 | if (skb->protocol == htons(ETH_P_IPV6)) | 148 | if (skb->protocol == htons(ETH_P_IPV6)) |
146 | mtu = ip6_skb_dst_mtu(skb); | 149 | mtu = ip6_skb_dst_mtu(skb); |
147 | else | 150 | else |
@@ -163,8 +166,9 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
163 | return x->outer_mode->afinfo->output_finish(skb); | 166 | return x->outer_mode->afinfo->output_finish(skb); |
164 | } | 167 | } |
165 | 168 | ||
166 | int xfrm6_output(struct sk_buff *skb) | 169 | int xfrm6_output(struct sock *sk, struct sk_buff *skb) |
167 | { | 170 | { |
168 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, | 171 | return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, |
169 | skb_dst(skb)->dev, __xfrm6_output); | 172 | NULL, skb_dst(skb)->dev, __xfrm6_output, |
173 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); | ||
170 | } | 174 | } |
diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c index 6ab989c486f7..54d13f8dbbae 100644 --- a/net/ipv6/xfrm6_protocol.c +++ b/net/ipv6/xfrm6_protocol.c | |||
@@ -50,6 +50,10 @@ int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err) | |||
50 | { | 50 | { |
51 | int ret; | 51 | int ret; |
52 | struct xfrm6_protocol *handler; | 52 | struct xfrm6_protocol *handler; |
53 | struct xfrm6_protocol __rcu **head = proto_handlers(protocol); | ||
54 | |||
55 | if (!head) | ||
56 | return 0; | ||
53 | 57 | ||
54 | for_each_protocol_rcu(*proto_handlers(protocol), handler) | 58 | for_each_protocol_rcu(*proto_handlers(protocol), handler) |
55 | if ((ret = handler->cb_handler(skb, err)) <= 0) | 59 | if ((ret = handler->cb_handler(skb, err)) <= 0) |
@@ -184,10 +188,12 @@ int xfrm6_protocol_register(struct xfrm6_protocol *handler, | |||
184 | struct xfrm6_protocol __rcu **pprev; | 188 | struct xfrm6_protocol __rcu **pprev; |
185 | struct xfrm6_protocol *t; | 189 | struct xfrm6_protocol *t; |
186 | bool add_netproto = false; | 190 | bool add_netproto = false; |
187 | |||
188 | int ret = -EEXIST; | 191 | int ret = -EEXIST; |
189 | int priority = handler->priority; | 192 | int priority = handler->priority; |
190 | 193 | ||
194 | if (!proto_handlers(protocol) || !netproto(protocol)) | ||
195 | return -EINVAL; | ||
196 | |||
191 | mutex_lock(&xfrm6_protocol_mutex); | 197 | mutex_lock(&xfrm6_protocol_mutex); |
192 | 198 | ||
193 | if (!rcu_dereference_protected(*proto_handlers(protocol), | 199 | if (!rcu_dereference_protected(*proto_handlers(protocol), |
@@ -230,6 +236,9 @@ int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, | |||
230 | struct xfrm6_protocol *t; | 236 | struct xfrm6_protocol *t; |
231 | int ret = -ENOENT; | 237 | int ret = -ENOENT; |
232 | 238 | ||
239 | if (!proto_handlers(protocol) || !netproto(protocol)) | ||
240 | return -EINVAL; | ||
241 | |||
233 | mutex_lock(&xfrm6_protocol_mutex); | 242 | mutex_lock(&xfrm6_protocol_mutex); |
234 | 243 | ||
235 | for (pprev = proto_handlers(protocol); | 244 | for (pprev = proto_handlers(protocol); |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 01e77b0ae075..8c9d7302c846 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1830,7 +1830,7 @@ static void iucv_callback_txdone(struct iucv_path *path, | |||
1830 | spin_lock_irqsave(&list->lock, flags); | 1830 | spin_lock_irqsave(&list->lock, flags); |
1831 | 1831 | ||
1832 | while (list_skb != (struct sk_buff *)list) { | 1832 | while (list_skb != (struct sk_buff *)list) { |
1833 | if (msg->tag != IUCV_SKB_CB(list_skb)->tag) { | 1833 | if (msg->tag == IUCV_SKB_CB(list_skb)->tag) { |
1834 | this = list_skb; | 1834 | this = list_skb; |
1835 | break; | 1835 | break; |
1836 | } | 1836 | } |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 47f7a5490555..a4e37d7158dc 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1131,10 +1131,10 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, | |||
1131 | skb->local_df = 1; | 1131 | skb->local_df = 1; |
1132 | #if IS_ENABLED(CONFIG_IPV6) | 1132 | #if IS_ENABLED(CONFIG_IPV6) |
1133 | if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) | 1133 | if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) |
1134 | error = inet6_csk_xmit(skb, NULL); | 1134 | error = inet6_csk_xmit(tunnel->sock, skb, NULL); |
1135 | else | 1135 | else |
1136 | #endif | 1136 | #endif |
1137 | error = ip_queue_xmit(skb, fl); | 1137 | error = ip_queue_xmit(tunnel->sock, skb, fl); |
1138 | 1138 | ||
1139 | /* Update stats */ | 1139 | /* Update stats */ |
1140 | if (error >= 0) { | 1140 | if (error >= 0) { |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0b44d855269c..3397fe6897c0 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -487,7 +487,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
487 | 487 | ||
488 | xmit: | 488 | xmit: |
489 | /* Queue the packet to IP for output */ | 489 | /* Queue the packet to IP for output */ |
490 | rc = ip_queue_xmit(skb, &inet->cork.fl); | 490 | rc = ip_queue_xmit(sk, skb, &inet->cork.fl); |
491 | rcu_read_unlock(); | 491 | rcu_read_unlock(); |
492 | 492 | ||
493 | error: | 493 | error: |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index bd1fd8ea5105..75b5dd2c9267 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
249 | 249 | ||
250 | if (!local->use_chanctx) { | 250 | if (!local->use_chanctx) { |
251 | local->_oper_chandef = *chandef; | 251 | local->_oper_chandef = *chandef; |
252 | ieee80211_hw_config(local, 0); | 252 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
253 | } else { | 253 | } else { |
254 | err = drv_add_chanctx(local, ctx); | 254 | err = drv_add_chanctx(local, ctx); |
255 | if (err) { | 255 | if (err) { |
@@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, | |||
286 | check_single_channel = true; | 286 | check_single_channel = true; |
287 | local->hw.conf.radar_enabled = false; | 287 | local->hw.conf.radar_enabled = false; |
288 | 288 | ||
289 | ieee80211_hw_config(local, 0); | 289 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
290 | } else { | 290 | } else { |
291 | drv_remove_chanctx(local, ctx); | 291 | drv_remove_chanctx(local, ctx); |
292 | } | 292 | } |
@@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | |||
492 | rx_chains_static = max(rx_chains_static, needed_static); | 492 | rx_chains_static = max(rx_chains_static, needed_static); |
493 | rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); | 493 | rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); |
494 | } | 494 | } |
495 | |||
496 | /* Disable SMPS for the monitor interface */ | ||
497 | sdata = rcu_dereference(local->monitor_sdata); | ||
498 | if (sdata && | ||
499 | rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf) | ||
500 | rx_chains_dynamic = rx_chains_static = local->rx_chains; | ||
501 | |||
495 | rcu_read_unlock(); | 502 | rcu_read_unlock(); |
496 | 503 | ||
497 | if (!local->use_chanctx) { | 504 | if (!local->use_chanctx) { |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 222c28b75315..f169b6ee94ee 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -317,6 +317,7 @@ struct ieee80211_roc_work { | |||
317 | 317 | ||
318 | bool started, abort, hw_begun, notified; | 318 | bool started, abort, hw_begun, notified; |
319 | bool to_be_freed; | 319 | bool to_be_freed; |
320 | bool on_channel; | ||
320 | 321 | ||
321 | unsigned long hw_start_time; | 322 | unsigned long hw_start_time; |
322 | 323 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b055f6a55c68..4c1bf61bc778 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | |||
148 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 148 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
149 | if (!rcu_access_pointer(sdata->vif.chanctx_conf)) | 149 | if (!rcu_access_pointer(sdata->vif.chanctx_conf)) |
150 | continue; | 150 | continue; |
151 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
152 | continue; | ||
151 | power = min(power, sdata->vif.bss_conf.txpower); | 153 | power = min(power, sdata->vif.bss_conf.txpower); |
152 | } | 154 | } |
153 | rcu_read_unlock(); | 155 | rcu_read_unlock(); |
@@ -199,7 +201,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
199 | { | 201 | { |
200 | struct ieee80211_local *local = sdata->local; | 202 | struct ieee80211_local *local = sdata->local; |
201 | 203 | ||
202 | if (!changed) | 204 | if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
203 | return; | 205 | return; |
204 | 206 | ||
205 | drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); | 207 | drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dee50aefd6e8..27600a9808ba 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3598,18 +3598,24 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata) | |||
3598 | 3598 | ||
3599 | sdata_lock(sdata); | 3599 | sdata_lock(sdata); |
3600 | 3600 | ||
3601 | if (ifmgd->auth_data) { | 3601 | if (ifmgd->auth_data || ifmgd->assoc_data) { |
3602 | const u8 *bssid = ifmgd->auth_data ? | ||
3603 | ifmgd->auth_data->bss->bssid : | ||
3604 | ifmgd->assoc_data->bss->bssid; | ||
3605 | |||
3602 | /* | 3606 | /* |
3603 | * If we are trying to authenticate while suspending, cfg80211 | 3607 | * If we are trying to authenticate / associate while suspending, |
3604 | * won't know and won't actually abort those attempts, thus we | 3608 | * cfg80211 won't know and won't actually abort those attempts, |
3605 | * need to do that ourselves. | 3609 | * thus we need to do that ourselves. |
3606 | */ | 3610 | */ |
3607 | ieee80211_send_deauth_disassoc(sdata, | 3611 | ieee80211_send_deauth_disassoc(sdata, bssid, |
3608 | ifmgd->auth_data->bss->bssid, | ||
3609 | IEEE80211_STYPE_DEAUTH, | 3612 | IEEE80211_STYPE_DEAUTH, |
3610 | WLAN_REASON_DEAUTH_LEAVING, | 3613 | WLAN_REASON_DEAUTH_LEAVING, |
3611 | false, frame_buf); | 3614 | false, frame_buf); |
3612 | ieee80211_destroy_auth_data(sdata, false); | 3615 | if (ifmgd->assoc_data) |
3616 | ieee80211_destroy_assoc_data(sdata, false); | ||
3617 | if (ifmgd->auth_data) | ||
3618 | ieee80211_destroy_auth_data(sdata, false); | ||
3613 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 3619 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
3614 | IEEE80211_DEAUTH_FRAME_LEN); | 3620 | IEEE80211_DEAUTH_FRAME_LEN); |
3615 | } | 3621 | } |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 0c2a29484c07..7a17decd27f9 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -333,7 +333,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
333 | container_of(work, struct ieee80211_roc_work, work.work); | 333 | container_of(work, struct ieee80211_roc_work, work.work); |
334 | struct ieee80211_sub_if_data *sdata = roc->sdata; | 334 | struct ieee80211_sub_if_data *sdata = roc->sdata; |
335 | struct ieee80211_local *local = sdata->local; | 335 | struct ieee80211_local *local = sdata->local; |
336 | bool started; | 336 | bool started, on_channel; |
337 | 337 | ||
338 | mutex_lock(&local->mtx); | 338 | mutex_lock(&local->mtx); |
339 | 339 | ||
@@ -354,13 +354,26 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
354 | if (!roc->started) { | 354 | if (!roc->started) { |
355 | struct ieee80211_roc_work *dep; | 355 | struct ieee80211_roc_work *dep; |
356 | 356 | ||
357 | /* start this ROC */ | 357 | WARN_ON(local->use_chanctx); |
358 | |||
359 | /* If actually operating on the desired channel (with at least | ||
360 | * 20 MHz channel width) don't stop all the operations but still | ||
361 | * treat it as though the ROC operation started properly, so | ||
362 | * other ROC operations won't interfere with this one. | ||
363 | */ | ||
364 | roc->on_channel = roc->chan == local->_oper_chandef.chan && | ||
365 | local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 && | ||
366 | local->_oper_chandef.width != NL80211_CHAN_WIDTH_10; | ||
358 | 367 | ||
359 | /* switch channel etc */ | 368 | /* start this ROC */ |
360 | ieee80211_recalc_idle(local); | 369 | ieee80211_recalc_idle(local); |
361 | 370 | ||
362 | local->tmp_channel = roc->chan; | 371 | if (!roc->on_channel) { |
363 | ieee80211_hw_config(local, 0); | 372 | ieee80211_offchannel_stop_vifs(local); |
373 | |||
374 | local->tmp_channel = roc->chan; | ||
375 | ieee80211_hw_config(local, 0); | ||
376 | } | ||
364 | 377 | ||
365 | /* tell userspace or send frame */ | 378 | /* tell userspace or send frame */ |
366 | ieee80211_handle_roc_started(roc); | 379 | ieee80211_handle_roc_started(roc); |
@@ -379,9 +392,10 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
379 | finish: | 392 | finish: |
380 | list_del(&roc->list); | 393 | list_del(&roc->list); |
381 | started = roc->started; | 394 | started = roc->started; |
395 | on_channel = roc->on_channel; | ||
382 | ieee80211_roc_notify_destroy(roc, !roc->abort); | 396 | ieee80211_roc_notify_destroy(roc, !roc->abort); |
383 | 397 | ||
384 | if (started) { | 398 | if (started && !on_channel) { |
385 | ieee80211_flush_queues(local, NULL); | 399 | ieee80211_flush_queues(local, NULL); |
386 | 400 | ||
387 | local->tmp_channel = NULL; | 401 | local->tmp_channel = NULL; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 216c45b949e5..2b608b2b70ec 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1231,7 +1231,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1231 | if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) && | 1231 | if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) && |
1232 | test_sta_flag(sta, WLAN_STA_AUTHORIZED)) { | 1232 | test_sta_flag(sta, WLAN_STA_AUTHORIZED)) { |
1233 | sta->last_rx = jiffies; | 1233 | sta->last_rx = jiffies; |
1234 | if (ieee80211_is_data(hdr->frame_control)) { | 1234 | if (ieee80211_is_data(hdr->frame_control) && |
1235 | !is_multicast_ether_addr(hdr->addr1)) { | ||
1235 | sta->last_rx_rate_idx = status->rate_idx; | 1236 | sta->last_rx_rate_idx = status->rate_idx; |
1236 | sta->last_rx_rate_flag = status->flag; | 1237 | sta->last_rx_rate_flag = status->flag; |
1237 | sta->last_rx_rate_vht_flag = status->vht_flag; | 1238 | sta->last_rx_rate_vht_flag = status->vht_flag; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 137a192e64bc..847d92f6bef6 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1148,7 +1148,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1148 | atomic_dec(&ps->num_sta_ps); | 1148 | atomic_dec(&ps->num_sta_ps); |
1149 | 1149 | ||
1150 | /* This station just woke up and isn't aware of our SMPS state */ | 1150 | /* This station just woke up and isn't aware of our SMPS state */ |
1151 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, | 1151 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1152 | !ieee80211_smps_is_restrictive(sta->known_smps_mode, | ||
1152 | sdata->smps_mode) && | 1153 | sdata->smps_mode) && |
1153 | sta->known_smps_mode != sdata->bss->req_smps && | 1154 | sta->known_smps_mode != sdata->bss->req_smps && |
1154 | sta_info_tx_streams(sta) != 1) { | 1155 | sta_info_tx_streams(sta) != 1) { |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index e6e574a307c8..60cb7a665976 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -314,10 +314,9 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_local *local, | |||
314 | !is_multicast_ether_addr(hdr->addr1)) | 314 | !is_multicast_ether_addr(hdr->addr1)) |
315 | txflags |= IEEE80211_RADIOTAP_F_TX_FAIL; | 315 | txflags |= IEEE80211_RADIOTAP_F_TX_FAIL; |
316 | 316 | ||
317 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | 317 | if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
318 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
319 | txflags |= IEEE80211_RADIOTAP_F_TX_CTS; | 318 | txflags |= IEEE80211_RADIOTAP_F_TX_CTS; |
320 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | 319 | if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
321 | txflags |= IEEE80211_RADIOTAP_F_TX_RTS; | 320 | txflags |= IEEE80211_RADIOTAP_F_TX_RTS; |
322 | 321 | ||
323 | put_unaligned_le16(txflags, pos); | 322 | put_unaligned_le16(txflags, pos); |
@@ -618,6 +617,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
618 | sta, true, acked); | 617 | sta, true, acked); |
619 | 618 | ||
620 | if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && | 619 | if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && |
620 | (ieee80211_is_data(hdr->frame_control)) && | ||
621 | (rates_idx != -1)) | 621 | (rates_idx != -1)) |
622 | sta->last_tx_rate = info->status.rates[rates_idx]; | 622 | sta->last_tx_rate = info->status.rates[rates_idx]; |
623 | 623 | ||
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index a0b0aea76525..cec5b60487a4 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -21,10 +21,10 @@ | |||
21 | 21 | ||
22 | #define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ | 22 | #define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ |
23 | __field(bool, p2p) \ | 23 | __field(bool, p2p) \ |
24 | __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") | 24 | __string(vif_name, sdata->name) |
25 | #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ | 25 | #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ |
26 | __entry->p2p = sdata->vif.p2p; \ | 26 | __entry->p2p = sdata->vif.p2p; \ |
27 | __assign_str(vif_name, sdata->dev ? sdata->dev->name : sdata->name) | 27 | __assign_str(vif_name, sdata->name) |
28 | #define VIF_PR_FMT " vif:%s(%d%s)" | 28 | #define VIF_PR_FMT " vif:%s(%d%s)" |
29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" | 29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" |
30 | 30 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 275c94f995f7..3c365837e910 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1780,7 +1780,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1780 | mutex_unlock(&local->mtx); | 1780 | mutex_unlock(&local->mtx); |
1781 | 1781 | ||
1782 | if (sched_scan_stopped) | 1782 | if (sched_scan_stopped) |
1783 | cfg80211_sched_scan_stopped(local->hw.wiphy); | 1783 | cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy); |
1784 | 1784 | ||
1785 | /* | 1785 | /* |
1786 | * If this is for hw restart things are still running. | 1786 | * If this is for hw restart things are still running. |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index e9e36a256165..9265adfdabfc 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -129,9 +129,12 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
129 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) | 129 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) |
130 | return; | 130 | return; |
131 | 131 | ||
132 | /* A VHT STA must support 40 MHz */ | 132 | /* |
133 | if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | 133 | * A VHT STA must support 40 MHz, but if we verify that here |
134 | return; | 134 | * then we break a few things - some APs (e.g. Netgear R6300v2 |
135 | * and others based on the BCM4360 chipset) will unset this | ||
136 | * capability bit when operating in 20 MHz. | ||
137 | */ | ||
135 | 138 | ||
136 | vht_cap->vht_supported = true; | 139 | vht_cap->vht_supported = true; |
137 | 140 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 6dba48efe01e..75421f2ba8be 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1795,6 +1795,7 @@ int nf_conntrack_init_net(struct net *net) | |||
1795 | int cpu; | 1795 | int cpu; |
1796 | 1796 | ||
1797 | atomic_set(&net->ct.count, 0); | 1797 | atomic_set(&net->ct.count, 0); |
1798 | seqcount_init(&net->ct.generation); | ||
1798 | 1799 | ||
1799 | net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu); | 1800 | net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu); |
1800 | if (!net->ct.pcpu_lists) | 1801 | if (!net->ct.pcpu_lists) |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index ccc46fa5edbc..58579634427d 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1336,6 +1336,9 @@ ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
1336 | #ifdef CONFIG_NF_NAT_NEEDED | 1336 | #ifdef CONFIG_NF_NAT_NEEDED |
1337 | int ret; | 1337 | int ret; |
1338 | 1338 | ||
1339 | if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC]) | ||
1340 | return 0; | ||
1341 | |||
1339 | ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST, | 1342 | ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST, |
1340 | cda[CTA_NAT_DST]); | 1343 | cda[CTA_NAT_DST]); |
1341 | if (ret < 0) | 1344 | if (ret < 0) |
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 7bd03decd36c..825c3e3f8305 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c | |||
@@ -605,32 +605,14 @@ static struct nf_conntrack_helper pptp __read_mostly = { | |||
605 | .expect_policy = &pptp_exp_policy, | 605 | .expect_policy = &pptp_exp_policy, |
606 | }; | 606 | }; |
607 | 607 | ||
608 | static void nf_conntrack_pptp_net_exit(struct net *net) | ||
609 | { | ||
610 | nf_ct_gre_keymap_flush(net); | ||
611 | } | ||
612 | |||
613 | static struct pernet_operations nf_conntrack_pptp_net_ops = { | ||
614 | .exit = nf_conntrack_pptp_net_exit, | ||
615 | }; | ||
616 | |||
617 | static int __init nf_conntrack_pptp_init(void) | 608 | static int __init nf_conntrack_pptp_init(void) |
618 | { | 609 | { |
619 | int rv; | 610 | return nf_conntrack_helper_register(&pptp); |
620 | |||
621 | rv = nf_conntrack_helper_register(&pptp); | ||
622 | if (rv < 0) | ||
623 | return rv; | ||
624 | rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops); | ||
625 | if (rv < 0) | ||
626 | nf_conntrack_helper_unregister(&pptp); | ||
627 | return rv; | ||
628 | } | 611 | } |
629 | 612 | ||
630 | static void __exit nf_conntrack_pptp_fini(void) | 613 | static void __exit nf_conntrack_pptp_fini(void) |
631 | { | 614 | { |
632 | nf_conntrack_helper_unregister(&pptp); | 615 | nf_conntrack_helper_unregister(&pptp); |
633 | unregister_pernet_subsys(&nf_conntrack_pptp_net_ops); | ||
634 | } | 616 | } |
635 | 617 | ||
636 | module_init(nf_conntrack_pptp_init); | 618 | module_init(nf_conntrack_pptp_init); |
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 9d9c0dade602..d5665739e3b1 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c | |||
@@ -66,7 +66,7 @@ static inline struct netns_proto_gre *gre_pernet(struct net *net) | |||
66 | return net_generic(net, proto_gre_net_id); | 66 | return net_generic(net, proto_gre_net_id); |
67 | } | 67 | } |
68 | 68 | ||
69 | void nf_ct_gre_keymap_flush(struct net *net) | 69 | static void nf_ct_gre_keymap_flush(struct net *net) |
70 | { | 70 | { |
71 | struct netns_proto_gre *net_gre = gre_pernet(net); | 71 | struct netns_proto_gre *net_gre = gre_pernet(net); |
72 | struct nf_ct_gre_keymap *km, *tmp; | 72 | struct nf_ct_gre_keymap *km, *tmp; |
@@ -78,7 +78,6 @@ void nf_ct_gre_keymap_flush(struct net *net) | |||
78 | } | 78 | } |
79 | write_unlock_bh(&net_gre->keymap_lock); | 79 | write_unlock_bh(&net_gre->keymap_lock); |
80 | } | 80 | } |
81 | EXPORT_SYMBOL(nf_ct_gre_keymap_flush); | ||
82 | 81 | ||
83 | static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, | 82 | static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, |
84 | const struct nf_conntrack_tuple *t) | 83 | const struct nf_conntrack_tuple *t) |
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 90998a6ff8b9..345acfb1720b 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
@@ -25,9 +25,8 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr, | |||
25 | struct nft_data data[NFT_REG_MAX + 1]) | 25 | struct nft_data data[NFT_REG_MAX + 1]) |
26 | { | 26 | { |
27 | const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); | 27 | const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); |
28 | u32 mask; | 28 | u32 mask = nft_cmp_fast_mask(priv->len); |
29 | 29 | ||
30 | mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - priv->len); | ||
31 | if ((data[priv->sreg].data[0] & mask) == priv->data) | 30 | if ((data[priv->sreg].data[0] & mask) == priv->data) |
32 | return; | 31 | return; |
33 | data[NFT_REG_VERDICT].verdict = NFT_BREAK; | 32 | data[NFT_REG_VERDICT].verdict = NFT_BREAK; |
@@ -67,20 +66,6 @@ struct nft_jumpstack { | |||
67 | int rulenum; | 66 | int rulenum; |
68 | }; | 67 | }; |
69 | 68 | ||
70 | static inline void | ||
71 | nft_chain_stats(const struct nft_chain *this, const struct nft_pktinfo *pkt, | ||
72 | struct nft_jumpstack *jumpstack, unsigned int stackptr) | ||
73 | { | ||
74 | struct nft_stats __percpu *stats; | ||
75 | const struct nft_chain *chain = stackptr ? jumpstack[0].chain : this; | ||
76 | |||
77 | rcu_read_lock_bh(); | ||
78 | stats = rcu_dereference(nft_base_chain(chain)->stats); | ||
79 | __this_cpu_inc(stats->pkts); | ||
80 | __this_cpu_add(stats->bytes, pkt->skb->len); | ||
81 | rcu_read_unlock_bh(); | ||
82 | } | ||
83 | |||
84 | enum nft_trace { | 69 | enum nft_trace { |
85 | NFT_TRACE_RULE, | 70 | NFT_TRACE_RULE, |
86 | NFT_TRACE_RETURN, | 71 | NFT_TRACE_RETURN, |
@@ -118,13 +103,14 @@ static void nft_trace_packet(const struct nft_pktinfo *pkt, | |||
118 | unsigned int | 103 | unsigned int |
119 | nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) | 104 | nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) |
120 | { | 105 | { |
121 | const struct nft_chain *chain = ops->priv; | 106 | const struct nft_chain *chain = ops->priv, *basechain = chain; |
122 | const struct nft_rule *rule; | 107 | const struct nft_rule *rule; |
123 | const struct nft_expr *expr, *last; | 108 | const struct nft_expr *expr, *last; |
124 | struct nft_data data[NFT_REG_MAX + 1]; | 109 | struct nft_data data[NFT_REG_MAX + 1]; |
125 | unsigned int stackptr = 0; | 110 | unsigned int stackptr = 0; |
126 | struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; | 111 | struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; |
127 | int rulenum = 0; | 112 | struct nft_stats __percpu *stats; |
113 | int rulenum; | ||
128 | /* | 114 | /* |
129 | * Cache cursor to avoid problems in case that the cursor is updated | 115 | * Cache cursor to avoid problems in case that the cursor is updated |
130 | * while traversing the ruleset. | 116 | * while traversing the ruleset. |
@@ -132,6 +118,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) | |||
132 | unsigned int gencursor = ACCESS_ONCE(chain->net->nft.gencursor); | 118 | unsigned int gencursor = ACCESS_ONCE(chain->net->nft.gencursor); |
133 | 119 | ||
134 | do_chain: | 120 | do_chain: |
121 | rulenum = 0; | ||
135 | rule = list_entry(&chain->rules, struct nft_rule, list); | 122 | rule = list_entry(&chain->rules, struct nft_rule, list); |
136 | next_rule: | 123 | next_rule: |
137 | data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; | 124 | data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; |
@@ -157,8 +144,10 @@ next_rule: | |||
157 | switch (data[NFT_REG_VERDICT].verdict) { | 144 | switch (data[NFT_REG_VERDICT].verdict) { |
158 | case NFT_BREAK: | 145 | case NFT_BREAK: |
159 | data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; | 146 | data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; |
160 | /* fall through */ | 147 | continue; |
161 | case NFT_CONTINUE: | 148 | case NFT_CONTINUE: |
149 | if (unlikely(pkt->skb->nf_trace)) | ||
150 | nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); | ||
162 | continue; | 151 | continue; |
163 | } | 152 | } |
164 | break; | 153 | break; |
@@ -184,37 +173,44 @@ next_rule: | |||
184 | jumpstack[stackptr].rule = rule; | 173 | jumpstack[stackptr].rule = rule; |
185 | jumpstack[stackptr].rulenum = rulenum; | 174 | jumpstack[stackptr].rulenum = rulenum; |
186 | stackptr++; | 175 | stackptr++; |
187 | /* fall through */ | 176 | chain = data[NFT_REG_VERDICT].chain; |
177 | goto do_chain; | ||
188 | case NFT_GOTO: | 178 | case NFT_GOTO: |
179 | if (unlikely(pkt->skb->nf_trace)) | ||
180 | nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); | ||
181 | |||
189 | chain = data[NFT_REG_VERDICT].chain; | 182 | chain = data[NFT_REG_VERDICT].chain; |
190 | goto do_chain; | 183 | goto do_chain; |
191 | case NFT_RETURN: | 184 | case NFT_RETURN: |
192 | if (unlikely(pkt->skb->nf_trace)) | 185 | if (unlikely(pkt->skb->nf_trace)) |
193 | nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); | 186 | nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); |
194 | 187 | break; | |
195 | /* fall through */ | ||
196 | case NFT_CONTINUE: | 188 | case NFT_CONTINUE: |
189 | if (unlikely(pkt->skb->nf_trace && !(chain->flags & NFT_BASE_CHAIN))) | ||
190 | nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN); | ||
197 | break; | 191 | break; |
198 | default: | 192 | default: |
199 | WARN_ON(1); | 193 | WARN_ON(1); |
200 | } | 194 | } |
201 | 195 | ||
202 | if (stackptr > 0) { | 196 | if (stackptr > 0) { |
203 | if (unlikely(pkt->skb->nf_trace)) | ||
204 | nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN); | ||
205 | |||
206 | stackptr--; | 197 | stackptr--; |
207 | chain = jumpstack[stackptr].chain; | 198 | chain = jumpstack[stackptr].chain; |
208 | rule = jumpstack[stackptr].rule; | 199 | rule = jumpstack[stackptr].rule; |
209 | rulenum = jumpstack[stackptr].rulenum; | 200 | rulenum = jumpstack[stackptr].rulenum; |
210 | goto next_rule; | 201 | goto next_rule; |
211 | } | 202 | } |
212 | nft_chain_stats(chain, pkt, jumpstack, stackptr); | ||
213 | 203 | ||
214 | if (unlikely(pkt->skb->nf_trace)) | 204 | if (unlikely(pkt->skb->nf_trace)) |
215 | nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_POLICY); | 205 | nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); |
206 | |||
207 | rcu_read_lock_bh(); | ||
208 | stats = rcu_dereference(nft_base_chain(basechain)->stats); | ||
209 | __this_cpu_inc(stats->pkts); | ||
210 | __this_cpu_add(stats->bytes, pkt->skb->len); | ||
211 | rcu_read_unlock_bh(); | ||
216 | 212 | ||
217 | return nft_base_chain(chain)->policy; | 213 | return nft_base_chain(basechain)->policy; |
218 | } | 214 | } |
219 | EXPORT_SYMBOL_GPL(nft_do_chain); | 215 | EXPORT_SYMBOL_GPL(nft_do_chain); |
220 | 216 | ||
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index e8138da4c14f..23ef77c60fff 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -256,15 +256,15 @@ replay: | |||
256 | #endif | 256 | #endif |
257 | { | 257 | { |
258 | nfnl_unlock(subsys_id); | 258 | nfnl_unlock(subsys_id); |
259 | kfree_skb(nskb); | 259 | netlink_ack(skb, nlh, -EOPNOTSUPP); |
260 | return netlink_ack(skb, nlh, -EOPNOTSUPP); | 260 | return kfree_skb(nskb); |
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | if (!ss->commit || !ss->abort) { | 264 | if (!ss->commit || !ss->abort) { |
265 | nfnl_unlock(subsys_id); | 265 | nfnl_unlock(subsys_id); |
266 | kfree_skb(nskb); | 266 | netlink_ack(skb, nlh, -EOPNOTSUPP); |
267 | return netlink_ack(skb, nlh, -EOPNOTSUPP); | 267 | return kfree_skb(skb); |
268 | } | 268 | } |
269 | 269 | ||
270 | while (skb->len >= nlmsg_total_size(0)) { | 270 | while (skb->len >= nlmsg_total_size(0)) { |
@@ -368,14 +368,13 @@ done: | |||
368 | static void nfnetlink_rcv(struct sk_buff *skb) | 368 | static void nfnetlink_rcv(struct sk_buff *skb) |
369 | { | 369 | { |
370 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | 370 | struct nlmsghdr *nlh = nlmsg_hdr(skb); |
371 | struct net *net = sock_net(skb->sk); | ||
372 | int msglen; | 371 | int msglen; |
373 | 372 | ||
374 | if (nlh->nlmsg_len < NLMSG_HDRLEN || | 373 | if (nlh->nlmsg_len < NLMSG_HDRLEN || |
375 | skb->len < nlh->nlmsg_len) | 374 | skb->len < nlh->nlmsg_len) |
376 | return; | 375 | return; |
377 | 376 | ||
378 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { | 377 | if (!netlink_net_capable(skb, CAP_NET_ADMIN)) { |
379 | netlink_ack(skb, nlh, -EPERM); | 378 | netlink_ack(skb, nlh, -EPERM); |
380 | return; | 379 | return; |
381 | } | 380 | } |
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c index 954925db414d..e2b3f51c81f1 100644 --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c | |||
@@ -128,7 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, | |||
128 | BUG_ON(err < 0); | 128 | BUG_ON(err < 0); |
129 | desc.len *= BITS_PER_BYTE; | 129 | desc.len *= BITS_PER_BYTE; |
130 | 130 | ||
131 | mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - desc.len); | 131 | mask = nft_cmp_fast_mask(desc.len); |
132 | priv->data = data.data[0] & mask; | 132 | priv->data = data.data[0] & mask; |
133 | priv->len = desc.len; | 133 | priv->len = desc.len; |
134 | return 0; | 134 | return 0; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 894cda0206bb..81dca96d2be6 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1360,7 +1360,72 @@ retry: | |||
1360 | return err; | 1360 | return err; |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | static inline int netlink_capable(const struct socket *sock, unsigned int flag) | 1363 | /** |
1364 | * __netlink_ns_capable - General netlink message capability test | ||
1365 | * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace. | ||
1366 | * @user_ns: The user namespace of the capability to use | ||
1367 | * @cap: The capability to use | ||
1368 | * | ||
1369 | * Test to see if the opener of the socket we received the message | ||
1370 | * from had when the netlink socket was created and the sender of the | ||
1371 | * message has has the capability @cap in the user namespace @user_ns. | ||
1372 | */ | ||
1373 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, | ||
1374 | struct user_namespace *user_ns, int cap) | ||
1375 | { | ||
1376 | return sk_ns_capable(nsp->sk, user_ns, cap); | ||
1377 | } | ||
1378 | EXPORT_SYMBOL(__netlink_ns_capable); | ||
1379 | |||
1380 | /** | ||
1381 | * netlink_ns_capable - General netlink message capability test | ||
1382 | * @skb: socket buffer holding a netlink command from userspace | ||
1383 | * @user_ns: The user namespace of the capability to use | ||
1384 | * @cap: The capability to use | ||
1385 | * | ||
1386 | * Test to see if the opener of the socket we received the message | ||
1387 | * from had when the netlink socket was created and the sender of the | ||
1388 | * message has has the capability @cap in the user namespace @user_ns. | ||
1389 | */ | ||
1390 | bool netlink_ns_capable(const struct sk_buff *skb, | ||
1391 | struct user_namespace *user_ns, int cap) | ||
1392 | { | ||
1393 | return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap); | ||
1394 | } | ||
1395 | EXPORT_SYMBOL(netlink_ns_capable); | ||
1396 | |||
1397 | /** | ||
1398 | * netlink_capable - Netlink global message capability test | ||
1399 | * @skb: socket buffer holding a netlink command from userspace | ||
1400 | * @cap: The capability to use | ||
1401 | * | ||
1402 | * Test to see if the opener of the socket we received the message | ||
1403 | * from had when the netlink socket was created and the sender of the | ||
1404 | * message has has the capability @cap in all user namespaces. | ||
1405 | */ | ||
1406 | bool netlink_capable(const struct sk_buff *skb, int cap) | ||
1407 | { | ||
1408 | return netlink_ns_capable(skb, &init_user_ns, cap); | ||
1409 | } | ||
1410 | EXPORT_SYMBOL(netlink_capable); | ||
1411 | |||
1412 | /** | ||
1413 | * netlink_net_capable - Netlink network namespace message capability test | ||
1414 | * @skb: socket buffer holding a netlink command from userspace | ||
1415 | * @cap: The capability to use | ||
1416 | * | ||
1417 | * Test to see if the opener of the socket we received the message | ||
1418 | * from had when the netlink socket was created and the sender of the | ||
1419 | * message has has the capability @cap over the network namespace of | ||
1420 | * the socket we received the message from. | ||
1421 | */ | ||
1422 | bool netlink_net_capable(const struct sk_buff *skb, int cap) | ||
1423 | { | ||
1424 | return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap); | ||
1425 | } | ||
1426 | EXPORT_SYMBOL(netlink_net_capable); | ||
1427 | |||
1428 | static inline int netlink_allowed(const struct socket *sock, unsigned int flag) | ||
1364 | { | 1429 | { |
1365 | return (nl_table[sock->sk->sk_protocol].flags & flag) || | 1430 | return (nl_table[sock->sk->sk_protocol].flags & flag) || |
1366 | ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); | 1431 | ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); |
@@ -1428,7 +1493,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
1428 | 1493 | ||
1429 | /* Only superuser is allowed to listen multicasts */ | 1494 | /* Only superuser is allowed to listen multicasts */ |
1430 | if (nladdr->nl_groups) { | 1495 | if (nladdr->nl_groups) { |
1431 | if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) | 1496 | if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) |
1432 | return -EPERM; | 1497 | return -EPERM; |
1433 | err = netlink_realloc_groups(sk); | 1498 | err = netlink_realloc_groups(sk); |
1434 | if (err) | 1499 | if (err) |
@@ -1490,7 +1555,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, | |||
1490 | return -EINVAL; | 1555 | return -EINVAL; |
1491 | 1556 | ||
1492 | if ((nladdr->nl_groups || nladdr->nl_pid) && | 1557 | if ((nladdr->nl_groups || nladdr->nl_pid) && |
1493 | !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) | 1558 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
1494 | return -EPERM; | 1559 | return -EPERM; |
1495 | 1560 | ||
1496 | if (!nlk->portid) | 1561 | if (!nlk->portid) |
@@ -2096,7 +2161,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
2096 | break; | 2161 | break; |
2097 | case NETLINK_ADD_MEMBERSHIP: | 2162 | case NETLINK_ADD_MEMBERSHIP: |
2098 | case NETLINK_DROP_MEMBERSHIP: { | 2163 | case NETLINK_DROP_MEMBERSHIP: { |
2099 | if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) | 2164 | if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) |
2100 | return -EPERM; | 2165 | return -EPERM; |
2101 | err = netlink_realloc_groups(sk); | 2166 | err = netlink_realloc_groups(sk); |
2102 | if (err) | 2167 | if (err) |
@@ -2247,7 +2312,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2247 | dst_group = ffs(addr->nl_groups); | 2312 | dst_group = ffs(addr->nl_groups); |
2248 | err = -EPERM; | 2313 | err = -EPERM; |
2249 | if ((dst_group || dst_portid) && | 2314 | if ((dst_group || dst_portid) && |
2250 | !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) | 2315 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
2251 | goto out; | 2316 | goto out; |
2252 | } else { | 2317 | } else { |
2253 | dst_portid = nlk->dst_portid; | 2318 | dst_portid = nlk->dst_portid; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index b1dcdb932a86..a3ba3ca0ff92 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -561,7 +561,7 @@ static int genl_family_rcv_msg(struct genl_family *family, | |||
561 | return -EOPNOTSUPP; | 561 | return -EOPNOTSUPP; |
562 | 562 | ||
563 | if ((ops->flags & GENL_ADMIN_PERM) && | 563 | if ((ops->flags & GENL_ADMIN_PERM) && |
564 | !capable(CAP_NET_ADMIN)) | 564 | !netlink_capable(skb, CAP_NET_ADMIN)) |
565 | return -EPERM; | 565 | return -EPERM; |
566 | 566 | ||
567 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { | 567 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index a3d6951602db..ebb6e2442554 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -174,7 +174,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
174 | 174 | ||
175 | skb->local_df = 1; | 175 | skb->local_df = 1; |
176 | 176 | ||
177 | return iptunnel_xmit(rt, skb, fl.saddr, | 177 | return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, |
178 | OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, | 178 | OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, |
179 | OVS_CB(skb)->tun_key->ipv4_tos, | 179 | OVS_CB(skb)->tun_key->ipv4_tos, |
180 | OVS_CB(skb)->tun_key->ipv4_ttl, df, false); | 180 | OVS_CB(skb)->tun_key->ipv4_ttl, df, false); |
diff --git a/net/packet/diag.c b/net/packet/diag.c index 533ce4ff108a..92f2c7107eec 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c | |||
@@ -128,6 +128,7 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb) | |||
128 | 128 | ||
129 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | 129 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, |
130 | struct packet_diag_req *req, | 130 | struct packet_diag_req *req, |
131 | bool may_report_filterinfo, | ||
131 | struct user_namespace *user_ns, | 132 | struct user_namespace *user_ns, |
132 | u32 portid, u32 seq, u32 flags, int sk_ino) | 133 | u32 portid, u32 seq, u32 flags, int sk_ino) |
133 | { | 134 | { |
@@ -172,7 +173,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | |||
172 | goto out_nlmsg_trim; | 173 | goto out_nlmsg_trim; |
173 | 174 | ||
174 | if ((req->pdiag_show & PACKET_SHOW_FILTER) && | 175 | if ((req->pdiag_show & PACKET_SHOW_FILTER) && |
175 | sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER)) | 176 | sock_diag_put_filterinfo(may_report_filterinfo, sk, skb, |
177 | PACKET_DIAG_FILTER)) | ||
176 | goto out_nlmsg_trim; | 178 | goto out_nlmsg_trim; |
177 | 179 | ||
178 | return nlmsg_end(skb, nlh); | 180 | return nlmsg_end(skb, nlh); |
@@ -188,9 +190,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
188 | struct packet_diag_req *req; | 190 | struct packet_diag_req *req; |
189 | struct net *net; | 191 | struct net *net; |
190 | struct sock *sk; | 192 | struct sock *sk; |
193 | bool may_report_filterinfo; | ||
191 | 194 | ||
192 | net = sock_net(skb->sk); | 195 | net = sock_net(skb->sk); |
193 | req = nlmsg_data(cb->nlh); | 196 | req = nlmsg_data(cb->nlh); |
197 | may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN); | ||
194 | 198 | ||
195 | mutex_lock(&net->packet.sklist_lock); | 199 | mutex_lock(&net->packet.sklist_lock); |
196 | sk_for_each(sk, &net->packet.sklist) { | 200 | sk_for_each(sk, &net->packet.sklist) { |
@@ -200,6 +204,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
200 | goto next; | 204 | goto next; |
201 | 205 | ||
202 | if (sk_diag_fill(sk, skb, req, | 206 | if (sk_diag_fill(sk, skb, req, |
207 | may_report_filterinfo, | ||
203 | sk_user_ns(NETLINK_CB(cb->skb).sk), | 208 | sk_user_ns(NETLINK_CB(cb->skb).sk), |
204 | NETLINK_CB(cb->skb).portid, | 209 | NETLINK_CB(cb->skb).portid, |
205 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 210 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index dc15f4300808..b64151ade6b3 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -70,10 +70,10 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
70 | int err; | 70 | int err; |
71 | u8 pnaddr; | 71 | u8 pnaddr; |
72 | 72 | ||
73 | if (!capable(CAP_NET_ADMIN)) | 73 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
74 | return -EPERM; | 74 | return -EPERM; |
75 | 75 | ||
76 | if (!capable(CAP_SYS_ADMIN)) | 76 | if (!netlink_capable(skb, CAP_SYS_ADMIN)) |
77 | return -EPERM; | 77 | return -EPERM; |
78 | 78 | ||
79 | ASSERT_RTNL(); | 79 | ASSERT_RTNL(); |
@@ -233,10 +233,10 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
233 | int err; | 233 | int err; |
234 | u8 dst; | 234 | u8 dst; |
235 | 235 | ||
236 | if (!capable(CAP_NET_ADMIN)) | 236 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
237 | return -EPERM; | 237 | return -EPERM; |
238 | 238 | ||
239 | if (!capable(CAP_SYS_ADMIN)) | 239 | if (!netlink_capable(skb, CAP_SYS_ADMIN)) |
240 | return -EPERM; | 240 | return -EPERM; |
241 | 241 | ||
242 | ASSERT_RTNL(); | 242 | ASSERT_RTNL(); |
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index 7633a752c65e..0ad080790a32 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
@@ -99,7 +99,7 @@ static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, | |||
99 | _debug("tktlen: %x", tktlen); | 99 | _debug("tktlen: %x", tktlen); |
100 | if (tktlen > AFSTOKEN_RK_TIX_MAX) | 100 | if (tktlen > AFSTOKEN_RK_TIX_MAX) |
101 | return -EKEYREJECTED; | 101 | return -EKEYREJECTED; |
102 | if (8 * 4 + tktlen != toklen) | 102 | if (toklen < 8 * 4 + tktlen) |
103 | return -EKEYREJECTED; | 103 | return -EKEYREJECTED; |
104 | 104 | ||
105 | plen = sizeof(*token) + sizeof(*token->kad) + tktlen; | 105 | plen = sizeof(*token) + sizeof(*token->kad) + tktlen; |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 8a5ba5add4bc..648778aef1a2 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -948,7 +948,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) | |||
948 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; | 948 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; |
949 | int ret = 0, ovr = 0; | 949 | int ret = 0, ovr = 0; |
950 | 950 | ||
951 | if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN)) | 951 | if ((n->nlmsg_type != RTM_GETACTION) && !netlink_capable(skb, CAP_NET_ADMIN)) |
952 | return -EPERM; | 952 | return -EPERM; |
953 | 953 | ||
954 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); | 954 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 29a30a14c315..bdbdb1a7920a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -134,7 +134,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) | |||
134 | int err; | 134 | int err; |
135 | int tp_created = 0; | 135 | int tp_created = 0; |
136 | 136 | ||
137 | if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) | 137 | if ((n->nlmsg_type != RTM_GETTFILTER) && !netlink_capable(skb, CAP_NET_ADMIN)) |
138 | return -EPERM; | 138 | return -EPERM; |
139 | 139 | ||
140 | replay: | 140 | replay: |
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index eed8404443d8..f435a88d899a 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c | |||
@@ -188,6 +188,12 @@ static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = { | |||
188 | [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 }, | 188 | [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 }, |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static void tcindex_filter_result_init(struct tcindex_filter_result *r) | ||
192 | { | ||
193 | memset(r, 0, sizeof(*r)); | ||
194 | tcf_exts_init(&r->exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); | ||
195 | } | ||
196 | |||
191 | static int | 197 | static int |
192 | tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | 198 | tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, |
193 | u32 handle, struct tcindex_data *p, | 199 | u32 handle, struct tcindex_data *p, |
@@ -207,15 +213,11 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
207 | return err; | 213 | return err; |
208 | 214 | ||
209 | memcpy(&cp, p, sizeof(cp)); | 215 | memcpy(&cp, p, sizeof(cp)); |
210 | memset(&new_filter_result, 0, sizeof(new_filter_result)); | 216 | tcindex_filter_result_init(&new_filter_result); |
211 | tcf_exts_init(&new_filter_result.exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); | ||
212 | 217 | ||
218 | tcindex_filter_result_init(&cr); | ||
213 | if (old_r) | 219 | if (old_r) |
214 | memcpy(&cr, r, sizeof(cr)); | 220 | cr.res = r->res; |
215 | else { | ||
216 | memset(&cr, 0, sizeof(cr)); | ||
217 | tcf_exts_init(&cr.exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); | ||
218 | } | ||
219 | 221 | ||
220 | if (tb[TCA_TCINDEX_HASH]) | 222 | if (tb[TCA_TCINDEX_HASH]) |
221 | cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); | 223 | cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); |
@@ -267,9 +269,14 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
267 | err = -ENOMEM; | 269 | err = -ENOMEM; |
268 | if (!cp.perfect && !cp.h) { | 270 | if (!cp.perfect && !cp.h) { |
269 | if (valid_perfect_hash(&cp)) { | 271 | if (valid_perfect_hash(&cp)) { |
272 | int i; | ||
273 | |||
270 | cp.perfect = kcalloc(cp.hash, sizeof(*r), GFP_KERNEL); | 274 | cp.perfect = kcalloc(cp.hash, sizeof(*r), GFP_KERNEL); |
271 | if (!cp.perfect) | 275 | if (!cp.perfect) |
272 | goto errout; | 276 | goto errout; |
277 | for (i = 0; i < cp.hash; i++) | ||
278 | tcf_exts_init(&cp.perfect[i].exts, TCA_TCINDEX_ACT, | ||
279 | TCA_TCINDEX_POLICE); | ||
273 | balloc = 1; | 280 | balloc = 1; |
274 | } else { | 281 | } else { |
275 | cp.h = kcalloc(cp.hash, sizeof(f), GFP_KERNEL); | 282 | cp.h = kcalloc(cp.hash, sizeof(f), GFP_KERNEL); |
@@ -295,14 +302,17 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
295 | tcf_bind_filter(tp, &cr.res, base); | 302 | tcf_bind_filter(tp, &cr.res, base); |
296 | } | 303 | } |
297 | 304 | ||
298 | tcf_exts_change(tp, &cr.exts, &e); | 305 | if (old_r) |
306 | tcf_exts_change(tp, &r->exts, &e); | ||
307 | else | ||
308 | tcf_exts_change(tp, &cr.exts, &e); | ||
299 | 309 | ||
300 | tcf_tree_lock(tp); | 310 | tcf_tree_lock(tp); |
301 | if (old_r && old_r != r) | 311 | if (old_r && old_r != r) |
302 | memset(old_r, 0, sizeof(*old_r)); | 312 | tcindex_filter_result_init(old_r); |
303 | 313 | ||
304 | memcpy(p, &cp, sizeof(cp)); | 314 | memcpy(p, &cp, sizeof(cp)); |
305 | memcpy(r, &cr, sizeof(cr)); | 315 | r->res = cr.res; |
306 | 316 | ||
307 | if (r == &new_filter_result) { | 317 | if (r == &new_filter_result) { |
308 | struct tcindex_filter **fp; | 318 | struct tcindex_filter **fp; |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index a0b84e0e22de..400769014bbd 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -1084,7 +1084,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n) | |||
1084 | struct Qdisc *p = NULL; | 1084 | struct Qdisc *p = NULL; |
1085 | int err; | 1085 | int err; |
1086 | 1086 | ||
1087 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) | 1087 | if ((n->nlmsg_type != RTM_GETQDISC) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1088 | return -EPERM; | 1088 | return -EPERM; |
1089 | 1089 | ||
1090 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1090 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
@@ -1151,7 +1151,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n) | |||
1151 | struct Qdisc *q, *p; | 1151 | struct Qdisc *q, *p; |
1152 | int err; | 1152 | int err; |
1153 | 1153 | ||
1154 | if (!capable(CAP_NET_ADMIN)) | 1154 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
1155 | return -EPERM; | 1155 | return -EPERM; |
1156 | 1156 | ||
1157 | replay: | 1157 | replay: |
@@ -1490,7 +1490,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n) | |||
1490 | u32 qid; | 1490 | u32 qid; |
1491 | int err; | 1491 | int err; |
1492 | 1492 | ||
1493 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) | 1493 | if ((n->nlmsg_type != RTM_GETTCLASS) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1494 | return -EPERM; | 1494 | return -EPERM; |
1495 | 1495 | ||
1496 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1496 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index edee03d922e2..6e957c3b9854 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c | |||
@@ -553,11 +553,6 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) | |||
553 | if (err < 0) | 553 | if (err < 0) |
554 | return err; | 554 | return err; |
555 | 555 | ||
556 | sch_tree_lock(sch); | ||
557 | |||
558 | if (tb[TCA_HHF_BACKLOG_LIMIT]) | ||
559 | sch->limit = nla_get_u32(tb[TCA_HHF_BACKLOG_LIMIT]); | ||
560 | |||
561 | if (tb[TCA_HHF_QUANTUM]) | 556 | if (tb[TCA_HHF_QUANTUM]) |
562 | new_quantum = nla_get_u32(tb[TCA_HHF_QUANTUM]); | 557 | new_quantum = nla_get_u32(tb[TCA_HHF_QUANTUM]); |
563 | 558 | ||
@@ -567,6 +562,12 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) | |||
567 | non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight; | 562 | non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight; |
568 | if (non_hh_quantum > INT_MAX) | 563 | if (non_hh_quantum > INT_MAX) |
569 | return -EINVAL; | 564 | return -EINVAL; |
565 | |||
566 | sch_tree_lock(sch); | ||
567 | |||
568 | if (tb[TCA_HHF_BACKLOG_LIMIT]) | ||
569 | sch->limit = nla_get_u32(tb[TCA_HHF_BACKLOG_LIMIT]); | ||
570 | |||
570 | q->quantum = new_quantum; | 571 | q->quantum = new_quantum; |
571 | q->hhf_non_hh_weight = new_hhf_non_hh_weight; | 572 | q->hhf_non_hh_weight = new_hhf_non_hh_weight; |
572 | 573 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 4f6d6f9d1274..39579c3e0d14 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1395,35 +1395,44 @@ static inline bool sctp_peer_needs_update(struct sctp_association *asoc) | |||
1395 | return false; | 1395 | return false; |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | /* Update asoc's rwnd for the approximated state in the buffer, | 1398 | /* Increase asoc's rwnd by len and send any window update SACK if needed. */ |
1399 | * and check whether SACK needs to be sent. | 1399 | void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len) |
1400 | */ | ||
1401 | void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer) | ||
1402 | { | 1400 | { |
1403 | int rx_count; | ||
1404 | struct sctp_chunk *sack; | 1401 | struct sctp_chunk *sack; |
1405 | struct timer_list *timer; | 1402 | struct timer_list *timer; |
1406 | 1403 | ||
1407 | if (asoc->ep->rcvbuf_policy) | 1404 | if (asoc->rwnd_over) { |
1408 | rx_count = atomic_read(&asoc->rmem_alloc); | 1405 | if (asoc->rwnd_over >= len) { |
1409 | else | 1406 | asoc->rwnd_over -= len; |
1410 | rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); | 1407 | } else { |
1408 | asoc->rwnd += (len - asoc->rwnd_over); | ||
1409 | asoc->rwnd_over = 0; | ||
1410 | } | ||
1411 | } else { | ||
1412 | asoc->rwnd += len; | ||
1413 | } | ||
1411 | 1414 | ||
1412 | if ((asoc->base.sk->sk_rcvbuf - rx_count) > 0) | 1415 | /* If we had window pressure, start recovering it |
1413 | asoc->rwnd = (asoc->base.sk->sk_rcvbuf - rx_count) >> 1; | 1416 | * once our rwnd had reached the accumulated pressure |
1414 | else | 1417 | * threshold. The idea is to recover slowly, but up |
1415 | asoc->rwnd = 0; | 1418 | * to the initial advertised window. |
1419 | */ | ||
1420 | if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) { | ||
1421 | int change = min(asoc->pathmtu, asoc->rwnd_press); | ||
1422 | asoc->rwnd += change; | ||
1423 | asoc->rwnd_press -= change; | ||
1424 | } | ||
1416 | 1425 | ||
1417 | pr_debug("%s: asoc:%p rwnd=%u, rx_count=%d, sk_rcvbuf=%d\n", | 1426 | pr_debug("%s: asoc:%p rwnd increased by %d to (%u, %u) - %u\n", |
1418 | __func__, asoc, asoc->rwnd, rx_count, | 1427 | __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, |
1419 | asoc->base.sk->sk_rcvbuf); | 1428 | asoc->a_rwnd); |
1420 | 1429 | ||
1421 | /* Send a window update SACK if the rwnd has increased by at least the | 1430 | /* Send a window update SACK if the rwnd has increased by at least the |
1422 | * minimum of the association's PMTU and half of the receive buffer. | 1431 | * minimum of the association's PMTU and half of the receive buffer. |
1423 | * The algorithm used is similar to the one described in | 1432 | * The algorithm used is similar to the one described in |
1424 | * Section 4.2.3.3 of RFC 1122. | 1433 | * Section 4.2.3.3 of RFC 1122. |
1425 | */ | 1434 | */ |
1426 | if (update_peer && sctp_peer_needs_update(asoc)) { | 1435 | if (sctp_peer_needs_update(asoc)) { |
1427 | asoc->a_rwnd = asoc->rwnd; | 1436 | asoc->a_rwnd = asoc->rwnd; |
1428 | 1437 | ||
1429 | pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u " | 1438 | pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u " |
@@ -1445,6 +1454,45 @@ void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer) | |||
1445 | } | 1454 | } |
1446 | } | 1455 | } |
1447 | 1456 | ||
1457 | /* Decrease asoc's rwnd by len. */ | ||
1458 | void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len) | ||
1459 | { | ||
1460 | int rx_count; | ||
1461 | int over = 0; | ||
1462 | |||
1463 | if (unlikely(!asoc->rwnd || asoc->rwnd_over)) | ||
1464 | pr_debug("%s: association:%p has asoc->rwnd:%u, " | ||
1465 | "asoc->rwnd_over:%u!\n", __func__, asoc, | ||
1466 | asoc->rwnd, asoc->rwnd_over); | ||
1467 | |||
1468 | if (asoc->ep->rcvbuf_policy) | ||
1469 | rx_count = atomic_read(&asoc->rmem_alloc); | ||
1470 | else | ||
1471 | rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); | ||
1472 | |||
1473 | /* If we've reached or overflowed our receive buffer, announce | ||
1474 | * a 0 rwnd if rwnd would still be positive. Store the | ||
1475 | * the potential pressure overflow so that the window can be restored | ||
1476 | * back to original value. | ||
1477 | */ | ||
1478 | if (rx_count >= asoc->base.sk->sk_rcvbuf) | ||
1479 | over = 1; | ||
1480 | |||
1481 | if (asoc->rwnd >= len) { | ||
1482 | asoc->rwnd -= len; | ||
1483 | if (over) { | ||
1484 | asoc->rwnd_press += asoc->rwnd; | ||
1485 | asoc->rwnd = 0; | ||
1486 | } | ||
1487 | } else { | ||
1488 | asoc->rwnd_over = len - asoc->rwnd; | ||
1489 | asoc->rwnd = 0; | ||
1490 | } | ||
1491 | |||
1492 | pr_debug("%s: asoc:%p rwnd decreased by %d to (%u, %u, %u)\n", | ||
1493 | __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, | ||
1494 | asoc->rwnd_press); | ||
1495 | } | ||
1448 | 1496 | ||
1449 | /* Build the bind address list for the association based on info from the | 1497 | /* Build the bind address list for the association based on info from the |
1450 | * local endpoint and the remote peer. | 1498 | * local endpoint and the remote peer. |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 683c7d1b1306..0e8529113dc5 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -386,14 +386,13 @@ nomem: | |||
386 | */ | 386 | */ |
387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) | 387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) |
388 | { | 388 | { |
389 | struct net *net = sock_net(asoc->base.sk); | ||
390 | struct sctp_auth_bytes *secret; | 389 | struct sctp_auth_bytes *secret; |
391 | struct sctp_shared_key *ep_key; | 390 | struct sctp_shared_key *ep_key; |
392 | 391 | ||
393 | /* If we don't support AUTH, or peer is not capable | 392 | /* If we don't support AUTH, or peer is not capable |
394 | * we don't need to do anything. | 393 | * we don't need to do anything. |
395 | */ | 394 | */ |
396 | if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | 395 | if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) |
397 | return 0; | 396 | return 0; |
398 | 397 | ||
399 | /* If the key_id is non-zero and we couldn't find an | 398 | /* If the key_id is non-zero and we couldn't find an |
@@ -440,16 +439,16 @@ struct sctp_shared_key *sctp_auth_get_shkey( | |||
440 | */ | 439 | */ |
441 | int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) | 440 | int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) |
442 | { | 441 | { |
443 | struct net *net = sock_net(ep->base.sk); | ||
444 | struct crypto_hash *tfm = NULL; | 442 | struct crypto_hash *tfm = NULL; |
445 | __u16 id; | 443 | __u16 id; |
446 | 444 | ||
447 | /* if the transforms are already allocted, we are done */ | 445 | /* If AUTH extension is disabled, we are done */ |
448 | if (!net->sctp.auth_enable) { | 446 | if (!ep->auth_enable) { |
449 | ep->auth_hmacs = NULL; | 447 | ep->auth_hmacs = NULL; |
450 | return 0; | 448 | return 0; |
451 | } | 449 | } |
452 | 450 | ||
451 | /* If the transforms are already allocated, we are done */ | ||
453 | if (ep->auth_hmacs) | 452 | if (ep->auth_hmacs) |
454 | return 0; | 453 | return 0; |
455 | 454 | ||
@@ -665,12 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param) | |||
665 | /* Check if peer requested that this chunk is authenticated */ | 664 | /* Check if peer requested that this chunk is authenticated */ |
666 | int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | 665 | int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) |
667 | { | 666 | { |
668 | struct net *net; | ||
669 | if (!asoc) | 667 | if (!asoc) |
670 | return 0; | 668 | return 0; |
671 | 669 | ||
672 | net = sock_net(asoc->base.sk); | 670 | if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) |
673 | if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | ||
674 | return 0; | 671 | return 0; |
675 | 672 | ||
676 | return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); | 673 | return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); |
@@ -679,12 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | |||
679 | /* Check if we requested that peer authenticate this chunk. */ | 676 | /* Check if we requested that peer authenticate this chunk. */ |
680 | int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | 677 | int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) |
681 | { | 678 | { |
682 | struct net *net; | ||
683 | if (!asoc) | 679 | if (!asoc) |
684 | return 0; | 680 | return 0; |
685 | 681 | ||
686 | net = sock_net(asoc->base.sk); | 682 | if (!asoc->ep->auth_enable) |
687 | if (!net->sctp.auth_enable) | ||
688 | return 0; | 683 | return 0; |
689 | 684 | ||
690 | return __sctp_auth_cid(chunk, | 685 | return __sctp_auth_cid(chunk, |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 8e5fdea05216..3d9f429858dc 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -68,7 +68,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
68 | if (!ep->digest) | 68 | if (!ep->digest) |
69 | return NULL; | 69 | return NULL; |
70 | 70 | ||
71 | if (net->sctp.auth_enable) { | 71 | ep->auth_enable = net->sctp.auth_enable; |
72 | if (ep->auth_enable) { | ||
72 | /* Allocate space for HMACS and CHUNKS authentication | 73 | /* Allocate space for HMACS and CHUNKS authentication |
73 | * variables. There are arrays that we encode directly | 74 | * variables. There are arrays that we encode directly |
74 | * into parameters to make the rest of the operations easier. | 75 | * into parameters to make the rest of the operations easier. |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 4e1d0fcb028e..44cbb54c8574 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -491,8 +491,13 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
491 | continue; | 491 | continue; |
492 | if ((laddr->state == SCTP_ADDR_SRC) && | 492 | if ((laddr->state == SCTP_ADDR_SRC) && |
493 | (AF_INET == laddr->a.sa.sa_family)) { | 493 | (AF_INET == laddr->a.sa.sa_family)) { |
494 | fl4->saddr = laddr->a.v4.sin_addr.s_addr; | ||
495 | fl4->fl4_sport = laddr->a.v4.sin_port; | 494 | fl4->fl4_sport = laddr->a.v4.sin_port; |
495 | flowi4_update_output(fl4, | ||
496 | asoc->base.sk->sk_bound_dev_if, | ||
497 | RT_CONN_FLAGS(asoc->base.sk), | ||
498 | daddr->v4.sin_addr.s_addr, | ||
499 | laddr->a.v4.sin_addr.s_addr); | ||
500 | |||
496 | rt = ip_route_output_key(sock_net(sk), fl4); | 501 | rt = ip_route_output_key(sock_net(sk), fl4); |
497 | if (!IS_ERR(rt)) { | 502 | if (!IS_ERR(rt)) { |
498 | dst = &rt->dst; | 503 | dst = &rt->dst; |
@@ -957,7 +962,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, | |||
957 | 962 | ||
958 | SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); | 963 | SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); |
959 | 964 | ||
960 | return ip_queue_xmit(skb, &transport->fl); | 965 | return ip_queue_xmit(&inet->sk, skb, &transport->fl); |
961 | } | 966 | } |
962 | 967 | ||
963 | static struct sctp_af sctp_af_inet; | 968 | static struct sctp_af sctp_af_inet; |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 3a1767ef3201..fee5552ddf92 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -219,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
219 | gfp_t gfp, int vparam_len) | 219 | gfp_t gfp, int vparam_len) |
220 | { | 220 | { |
221 | struct net *net = sock_net(asoc->base.sk); | 221 | struct net *net = sock_net(asoc->base.sk); |
222 | struct sctp_endpoint *ep = asoc->ep; | ||
222 | sctp_inithdr_t init; | 223 | sctp_inithdr_t init; |
223 | union sctp_params addrs; | 224 | union sctp_params addrs; |
224 | size_t chunksize; | 225 | size_t chunksize; |
@@ -278,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
278 | chunksize += vparam_len; | 279 | chunksize += vparam_len; |
279 | 280 | ||
280 | /* Account for AUTH related parameters */ | 281 | /* Account for AUTH related parameters */ |
281 | if (net->sctp.auth_enable) { | 282 | if (ep->auth_enable) { |
282 | /* Add random parameter length*/ | 283 | /* Add random parameter length*/ |
283 | chunksize += sizeof(asoc->c.auth_random); | 284 | chunksize += sizeof(asoc->c.auth_random); |
284 | 285 | ||
@@ -363,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
363 | } | 364 | } |
364 | 365 | ||
365 | /* Add SCTP-AUTH chunks to the parameter list */ | 366 | /* Add SCTP-AUTH chunks to the parameter list */ |
366 | if (net->sctp.auth_enable) { | 367 | if (ep->auth_enable) { |
367 | sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), | 368 | sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), |
368 | asoc->c.auth_random); | 369 | asoc->c.auth_random); |
369 | if (auth_hmacs) | 370 | if (auth_hmacs) |
@@ -2010,7 +2011,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc, | |||
2010 | /* if the peer reports AUTH, assume that he | 2011 | /* if the peer reports AUTH, assume that he |
2011 | * supports AUTH. | 2012 | * supports AUTH. |
2012 | */ | 2013 | */ |
2013 | if (net->sctp.auth_enable) | 2014 | if (asoc->ep->auth_enable) |
2014 | asoc->peer.auth_capable = 1; | 2015 | asoc->peer.auth_capable = 1; |
2015 | break; | 2016 | break; |
2016 | case SCTP_CID_ASCONF: | 2017 | case SCTP_CID_ASCONF: |
@@ -2102,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
2102 | * SCTP_IERROR_NO_ERROR - continue with the chunk | 2103 | * SCTP_IERROR_NO_ERROR - continue with the chunk |
2103 | */ | 2104 | */ |
2104 | static sctp_ierror_t sctp_verify_param(struct net *net, | 2105 | static sctp_ierror_t sctp_verify_param(struct net *net, |
2106 | const struct sctp_endpoint *ep, | ||
2105 | const struct sctp_association *asoc, | 2107 | const struct sctp_association *asoc, |
2106 | union sctp_params param, | 2108 | union sctp_params param, |
2107 | sctp_cid_t cid, | 2109 | sctp_cid_t cid, |
@@ -2152,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2152 | goto fallthrough; | 2154 | goto fallthrough; |
2153 | 2155 | ||
2154 | case SCTP_PARAM_RANDOM: | 2156 | case SCTP_PARAM_RANDOM: |
2155 | if (!net->sctp.auth_enable) | 2157 | if (!ep->auth_enable) |
2156 | goto fallthrough; | 2158 | goto fallthrough; |
2157 | 2159 | ||
2158 | /* SCTP-AUTH: Secion 6.1 | 2160 | /* SCTP-AUTH: Secion 6.1 |
@@ -2169,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2169 | break; | 2171 | break; |
2170 | 2172 | ||
2171 | case SCTP_PARAM_CHUNKS: | 2173 | case SCTP_PARAM_CHUNKS: |
2172 | if (!net->sctp.auth_enable) | 2174 | if (!ep->auth_enable) |
2173 | goto fallthrough; | 2175 | goto fallthrough; |
2174 | 2176 | ||
2175 | /* SCTP-AUTH: Section 3.2 | 2177 | /* SCTP-AUTH: Section 3.2 |
@@ -2185,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2185 | break; | 2187 | break; |
2186 | 2188 | ||
2187 | case SCTP_PARAM_HMAC_ALGO: | 2189 | case SCTP_PARAM_HMAC_ALGO: |
2188 | if (!net->sctp.auth_enable) | 2190 | if (!ep->auth_enable) |
2189 | goto fallthrough; | 2191 | goto fallthrough; |
2190 | 2192 | ||
2191 | hmacs = (struct sctp_hmac_algo_param *)param.p; | 2193 | hmacs = (struct sctp_hmac_algo_param *)param.p; |
@@ -2220,10 +2222,9 @@ fallthrough: | |||
2220 | } | 2222 | } |
2221 | 2223 | ||
2222 | /* Verify the INIT packet before we process it. */ | 2224 | /* Verify the INIT packet before we process it. */ |
2223 | int sctp_verify_init(struct net *net, const struct sctp_association *asoc, | 2225 | int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, |
2224 | sctp_cid_t cid, | 2226 | const struct sctp_association *asoc, sctp_cid_t cid, |
2225 | sctp_init_chunk_t *peer_init, | 2227 | sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, |
2226 | struct sctp_chunk *chunk, | ||
2227 | struct sctp_chunk **errp) | 2228 | struct sctp_chunk **errp) |
2228 | { | 2229 | { |
2229 | union sctp_params param; | 2230 | union sctp_params param; |
@@ -2264,8 +2265,8 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc, | |||
2264 | 2265 | ||
2265 | /* Verify all the variable length parameters */ | 2266 | /* Verify all the variable length parameters */ |
2266 | sctp_walk_params(param, peer_init, init_hdr.params) { | 2267 | sctp_walk_params(param, peer_init, init_hdr.params) { |
2267 | 2268 | result = sctp_verify_param(net, ep, asoc, param, cid, | |
2268 | result = sctp_verify_param(net, asoc, param, cid, chunk, errp); | 2269 | chunk, errp); |
2269 | switch (result) { | 2270 | switch (result) { |
2270 | case SCTP_IERROR_ABORT: | 2271 | case SCTP_IERROR_ABORT: |
2271 | case SCTP_IERROR_NOMEM: | 2272 | case SCTP_IERROR_NOMEM: |
@@ -2497,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc, | |||
2497 | struct sctp_af *af; | 2498 | struct sctp_af *af; |
2498 | union sctp_addr_param *addr_param; | 2499 | union sctp_addr_param *addr_param; |
2499 | struct sctp_transport *t; | 2500 | struct sctp_transport *t; |
2501 | struct sctp_endpoint *ep = asoc->ep; | ||
2500 | 2502 | ||
2501 | /* We maintain all INIT parameters in network byte order all the | 2503 | /* We maintain all INIT parameters in network byte order all the |
2502 | * time. This allows us to not worry about whether the parameters | 2504 | * time. This allows us to not worry about whether the parameters |
@@ -2636,7 +2638,7 @@ do_addr_param: | |||
2636 | goto fall_through; | 2638 | goto fall_through; |
2637 | 2639 | ||
2638 | case SCTP_PARAM_RANDOM: | 2640 | case SCTP_PARAM_RANDOM: |
2639 | if (!net->sctp.auth_enable) | 2641 | if (!ep->auth_enable) |
2640 | goto fall_through; | 2642 | goto fall_through; |
2641 | 2643 | ||
2642 | /* Save peer's random parameter */ | 2644 | /* Save peer's random parameter */ |
@@ -2649,7 +2651,7 @@ do_addr_param: | |||
2649 | break; | 2651 | break; |
2650 | 2652 | ||
2651 | case SCTP_PARAM_HMAC_ALGO: | 2653 | case SCTP_PARAM_HMAC_ALGO: |
2652 | if (!net->sctp.auth_enable) | 2654 | if (!ep->auth_enable) |
2653 | goto fall_through; | 2655 | goto fall_through; |
2654 | 2656 | ||
2655 | /* Save peer's HMAC list */ | 2657 | /* Save peer's HMAC list */ |
@@ -2665,7 +2667,7 @@ do_addr_param: | |||
2665 | break; | 2667 | break; |
2666 | 2668 | ||
2667 | case SCTP_PARAM_CHUNKS: | 2669 | case SCTP_PARAM_CHUNKS: |
2668 | if (!net->sctp.auth_enable) | 2670 | if (!ep->auth_enable) |
2669 | goto fall_through; | 2671 | goto fall_through; |
2670 | 2672 | ||
2671 | asoc->peer.peer_chunks = kmemdup(param.p, | 2673 | asoc->peer.peer_chunks = kmemdup(param.p, |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 5d6883ff00c3..fef2acdf4a2e 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -496,11 +496,10 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, | |||
496 | 496 | ||
497 | /* If the transport error count is greater than the pf_retrans | 497 | /* If the transport error count is greater than the pf_retrans |
498 | * threshold, and less than pathmaxrtx, and if the current state | 498 | * threshold, and less than pathmaxrtx, and if the current state |
499 | * is not SCTP_UNCONFIRMED, then mark this transport as Partially | 499 | * is SCTP_ACTIVE, then mark this transport as Partially Failed, |
500 | * Failed, see SCTP Quick Failover Draft, section 5.1 | 500 | * see SCTP Quick Failover Draft, section 5.1 |
501 | */ | 501 | */ |
502 | if ((transport->state != SCTP_PF) && | 502 | if ((transport->state == SCTP_ACTIVE) && |
503 | (transport->state != SCTP_UNCONFIRMED) && | ||
504 | (asoc->pf_retrans < transport->pathmaxrxt) && | 503 | (asoc->pf_retrans < transport->pathmaxrxt) && |
505 | (transport->error_count > asoc->pf_retrans)) { | 504 | (transport->error_count > asoc->pf_retrans)) { |
506 | 505 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 01e002430c85..5170a1ff95a1 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -357,7 +357,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, | |||
357 | 357 | ||
358 | /* Verify the INIT chunk before processing it. */ | 358 | /* Verify the INIT chunk before processing it. */ |
359 | err_chunk = NULL; | 359 | err_chunk = NULL; |
360 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 360 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
361 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 361 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
362 | &err_chunk)) { | 362 | &err_chunk)) { |
363 | /* This chunk contains fatal error. It is to be discarded. | 363 | /* This chunk contains fatal error. It is to be discarded. |
@@ -524,7 +524,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, | |||
524 | 524 | ||
525 | /* Verify the INIT chunk before processing it. */ | 525 | /* Verify the INIT chunk before processing it. */ |
526 | err_chunk = NULL; | 526 | err_chunk = NULL; |
527 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 527 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
528 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 528 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
529 | &err_chunk)) { | 529 | &err_chunk)) { |
530 | 530 | ||
@@ -1430,7 +1430,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1430 | 1430 | ||
1431 | /* Verify the INIT chunk before processing it. */ | 1431 | /* Verify the INIT chunk before processing it. */ |
1432 | err_chunk = NULL; | 1432 | err_chunk = NULL; |
1433 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 1433 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
1434 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 1434 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
1435 | &err_chunk)) { | 1435 | &err_chunk)) { |
1436 | /* This chunk contains fatal error. It is to be discarded. | 1436 | /* This chunk contains fatal error. It is to be discarded. |
@@ -6178,7 +6178,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6178 | * PMTU. In cases, such as loopback, this might be a rather | 6178 | * PMTU. In cases, such as loopback, this might be a rather |
6179 | * large spill over. | 6179 | * large spill over. |
6180 | */ | 6180 | */ |
6181 | if ((!chunk->data_accepted) && (!asoc->rwnd || | 6181 | if ((!chunk->data_accepted) && (!asoc->rwnd || asoc->rwnd_over || |
6182 | (datalen > asoc->rwnd + asoc->frag_point))) { | 6182 | (datalen > asoc->rwnd + asoc->frag_point))) { |
6183 | 6183 | ||
6184 | /* If this is the next TSN, consider reneging to make | 6184 | /* If this is the next TSN, consider reneging to make |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e13519e9df80..fee06b99a4da 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2115,6 +2115,12 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
2115 | sctp_skb_pull(skb, copied); | 2115 | sctp_skb_pull(skb, copied); |
2116 | skb_queue_head(&sk->sk_receive_queue, skb); | 2116 | skb_queue_head(&sk->sk_receive_queue, skb); |
2117 | 2117 | ||
2118 | /* When only partial message is copied to the user, increase | ||
2119 | * rwnd by that amount. If all the data in the skb is read, | ||
2120 | * rwnd is updated when the event is freed. | ||
2121 | */ | ||
2122 | if (!sctp_ulpevent_is_notification(event)) | ||
2123 | sctp_assoc_rwnd_increase(event->asoc, copied); | ||
2118 | goto out; | 2124 | goto out; |
2119 | } else if ((event->msg_flags & MSG_NOTIFICATION) || | 2125 | } else if ((event->msg_flags & MSG_NOTIFICATION) || |
2120 | (event->msg_flags & MSG_EOR)) | 2126 | (event->msg_flags & MSG_EOR)) |
@@ -3315,10 +3321,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3315 | char __user *optval, | 3321 | char __user *optval, |
3316 | unsigned int optlen) | 3322 | unsigned int optlen) |
3317 | { | 3323 | { |
3318 | struct net *net = sock_net(sk); | 3324 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3319 | struct sctp_authchunk val; | 3325 | struct sctp_authchunk val; |
3320 | 3326 | ||
3321 | if (!net->sctp.auth_enable) | 3327 | if (!ep->auth_enable) |
3322 | return -EACCES; | 3328 | return -EACCES; |
3323 | 3329 | ||
3324 | if (optlen != sizeof(struct sctp_authchunk)) | 3330 | if (optlen != sizeof(struct sctp_authchunk)) |
@@ -3335,7 +3341,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3335 | } | 3341 | } |
3336 | 3342 | ||
3337 | /* add this chunk id to the endpoint */ | 3343 | /* add this chunk id to the endpoint */ |
3338 | return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk); | 3344 | return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk); |
3339 | } | 3345 | } |
3340 | 3346 | ||
3341 | /* | 3347 | /* |
@@ -3348,12 +3354,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3348 | char __user *optval, | 3354 | char __user *optval, |
3349 | unsigned int optlen) | 3355 | unsigned int optlen) |
3350 | { | 3356 | { |
3351 | struct net *net = sock_net(sk); | 3357 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3352 | struct sctp_hmacalgo *hmacs; | 3358 | struct sctp_hmacalgo *hmacs; |
3353 | u32 idents; | 3359 | u32 idents; |
3354 | int err; | 3360 | int err; |
3355 | 3361 | ||
3356 | if (!net->sctp.auth_enable) | 3362 | if (!ep->auth_enable) |
3357 | return -EACCES; | 3363 | return -EACCES; |
3358 | 3364 | ||
3359 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3365 | if (optlen < sizeof(struct sctp_hmacalgo)) |
@@ -3370,7 +3376,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3370 | goto out; | 3376 | goto out; |
3371 | } | 3377 | } |
3372 | 3378 | ||
3373 | err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs); | 3379 | err = sctp_auth_ep_set_hmacs(ep, hmacs); |
3374 | out: | 3380 | out: |
3375 | kfree(hmacs); | 3381 | kfree(hmacs); |
3376 | return err; | 3382 | return err; |
@@ -3386,12 +3392,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3386 | char __user *optval, | 3392 | char __user *optval, |
3387 | unsigned int optlen) | 3393 | unsigned int optlen) |
3388 | { | 3394 | { |
3389 | struct net *net = sock_net(sk); | 3395 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3390 | struct sctp_authkey *authkey; | 3396 | struct sctp_authkey *authkey; |
3391 | struct sctp_association *asoc; | 3397 | struct sctp_association *asoc; |
3392 | int ret; | 3398 | int ret; |
3393 | 3399 | ||
3394 | if (!net->sctp.auth_enable) | 3400 | if (!ep->auth_enable) |
3395 | return -EACCES; | 3401 | return -EACCES; |
3396 | 3402 | ||
3397 | if (optlen <= sizeof(struct sctp_authkey)) | 3403 | if (optlen <= sizeof(struct sctp_authkey)) |
@@ -3412,7 +3418,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3412 | goto out; | 3418 | goto out; |
3413 | } | 3419 | } |
3414 | 3420 | ||
3415 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); | 3421 | ret = sctp_auth_set_key(ep, asoc, authkey); |
3416 | out: | 3422 | out: |
3417 | kzfree(authkey); | 3423 | kzfree(authkey); |
3418 | return ret; | 3424 | return ret; |
@@ -3428,11 +3434,11 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3428 | char __user *optval, | 3434 | char __user *optval, |
3429 | unsigned int optlen) | 3435 | unsigned int optlen) |
3430 | { | 3436 | { |
3431 | struct net *net = sock_net(sk); | 3437 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3432 | struct sctp_authkeyid val; | 3438 | struct sctp_authkeyid val; |
3433 | struct sctp_association *asoc; | 3439 | struct sctp_association *asoc; |
3434 | 3440 | ||
3435 | if (!net->sctp.auth_enable) | 3441 | if (!ep->auth_enable) |
3436 | return -EACCES; | 3442 | return -EACCES; |
3437 | 3443 | ||
3438 | if (optlen != sizeof(struct sctp_authkeyid)) | 3444 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3444,8 +3450,7 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3444 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3450 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3445 | return -EINVAL; | 3451 | return -EINVAL; |
3446 | 3452 | ||
3447 | return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc, | 3453 | return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber); |
3448 | val.scact_keynumber); | ||
3449 | } | 3454 | } |
3450 | 3455 | ||
3451 | /* | 3456 | /* |
@@ -3457,11 +3462,11 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3457 | char __user *optval, | 3462 | char __user *optval, |
3458 | unsigned int optlen) | 3463 | unsigned int optlen) |
3459 | { | 3464 | { |
3460 | struct net *net = sock_net(sk); | 3465 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3461 | struct sctp_authkeyid val; | 3466 | struct sctp_authkeyid val; |
3462 | struct sctp_association *asoc; | 3467 | struct sctp_association *asoc; |
3463 | 3468 | ||
3464 | if (!net->sctp.auth_enable) | 3469 | if (!ep->auth_enable) |
3465 | return -EACCES; | 3470 | return -EACCES; |
3466 | 3471 | ||
3467 | if (optlen != sizeof(struct sctp_authkeyid)) | 3472 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3473,8 +3478,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3473 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3478 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3474 | return -EINVAL; | 3479 | return -EINVAL; |
3475 | 3480 | ||
3476 | return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc, | 3481 | return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber); |
3477 | val.scact_keynumber); | ||
3478 | 3482 | ||
3479 | } | 3483 | } |
3480 | 3484 | ||
@@ -5381,16 +5385,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5381 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | 5385 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, |
5382 | char __user *optval, int __user *optlen) | 5386 | char __user *optval, int __user *optlen) |
5383 | { | 5387 | { |
5384 | struct net *net = sock_net(sk); | 5388 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5385 | struct sctp_hmacalgo __user *p = (void __user *)optval; | 5389 | struct sctp_hmacalgo __user *p = (void __user *)optval; |
5386 | struct sctp_hmac_algo_param *hmacs; | 5390 | struct sctp_hmac_algo_param *hmacs; |
5387 | __u16 data_len = 0; | 5391 | __u16 data_len = 0; |
5388 | u32 num_idents; | 5392 | u32 num_idents; |
5389 | 5393 | ||
5390 | if (!net->sctp.auth_enable) | 5394 | if (!ep->auth_enable) |
5391 | return -EACCES; | 5395 | return -EACCES; |
5392 | 5396 | ||
5393 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; | 5397 | hmacs = ep->auth_hmacs_list; |
5394 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); | 5398 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5395 | 5399 | ||
5396 | if (len < sizeof(struct sctp_hmacalgo) + data_len) | 5400 | if (len < sizeof(struct sctp_hmacalgo) + data_len) |
@@ -5411,11 +5415,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | |||
5411 | static int sctp_getsockopt_active_key(struct sock *sk, int len, | 5415 | static int sctp_getsockopt_active_key(struct sock *sk, int len, |
5412 | char __user *optval, int __user *optlen) | 5416 | char __user *optval, int __user *optlen) |
5413 | { | 5417 | { |
5414 | struct net *net = sock_net(sk); | 5418 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5415 | struct sctp_authkeyid val; | 5419 | struct sctp_authkeyid val; |
5416 | struct sctp_association *asoc; | 5420 | struct sctp_association *asoc; |
5417 | 5421 | ||
5418 | if (!net->sctp.auth_enable) | 5422 | if (!ep->auth_enable) |
5419 | return -EACCES; | 5423 | return -EACCES; |
5420 | 5424 | ||
5421 | if (len < sizeof(struct sctp_authkeyid)) | 5425 | if (len < sizeof(struct sctp_authkeyid)) |
@@ -5430,7 +5434,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5430 | if (asoc) | 5434 | if (asoc) |
5431 | val.scact_keynumber = asoc->active_key_id; | 5435 | val.scact_keynumber = asoc->active_key_id; |
5432 | else | 5436 | else |
5433 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; | 5437 | val.scact_keynumber = ep->active_key_id; |
5434 | 5438 | ||
5435 | len = sizeof(struct sctp_authkeyid); | 5439 | len = sizeof(struct sctp_authkeyid); |
5436 | if (put_user(len, optlen)) | 5440 | if (put_user(len, optlen)) |
@@ -5444,7 +5448,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5444 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | 5448 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, |
5445 | char __user *optval, int __user *optlen) | 5449 | char __user *optval, int __user *optlen) |
5446 | { | 5450 | { |
5447 | struct net *net = sock_net(sk); | 5451 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5448 | struct sctp_authchunks __user *p = (void __user *)optval; | 5452 | struct sctp_authchunks __user *p = (void __user *)optval; |
5449 | struct sctp_authchunks val; | 5453 | struct sctp_authchunks val; |
5450 | struct sctp_association *asoc; | 5454 | struct sctp_association *asoc; |
@@ -5452,7 +5456,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5452 | u32 num_chunks = 0; | 5456 | u32 num_chunks = 0; |
5453 | char __user *to; | 5457 | char __user *to; |
5454 | 5458 | ||
5455 | if (!net->sctp.auth_enable) | 5459 | if (!ep->auth_enable) |
5456 | return -EACCES; | 5460 | return -EACCES; |
5457 | 5461 | ||
5458 | if (len < sizeof(struct sctp_authchunks)) | 5462 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5489,7 +5493,7 @@ num: | |||
5489 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | 5493 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, |
5490 | char __user *optval, int __user *optlen) | 5494 | char __user *optval, int __user *optlen) |
5491 | { | 5495 | { |
5492 | struct net *net = sock_net(sk); | 5496 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5493 | struct sctp_authchunks __user *p = (void __user *)optval; | 5497 | struct sctp_authchunks __user *p = (void __user *)optval; |
5494 | struct sctp_authchunks val; | 5498 | struct sctp_authchunks val; |
5495 | struct sctp_association *asoc; | 5499 | struct sctp_association *asoc; |
@@ -5497,7 +5501,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5497 | u32 num_chunks = 0; | 5501 | u32 num_chunks = 0; |
5498 | char __user *to; | 5502 | char __user *to; |
5499 | 5503 | ||
5500 | if (!net->sctp.auth_enable) | 5504 | if (!ep->auth_enable) |
5501 | return -EACCES; | 5505 | return -EACCES; |
5502 | 5506 | ||
5503 | if (len < sizeof(struct sctp_authchunks)) | 5507 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5514,7 +5518,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5514 | if (asoc) | 5518 | if (asoc) |
5515 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; | 5519 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; |
5516 | else | 5520 | else |
5517 | ch = sctp_sk(sk)->ep->auth_chunk_list; | 5521 | ch = ep->auth_chunk_list; |
5518 | 5522 | ||
5519 | if (!ch) | 5523 | if (!ch) |
5520 | goto num; | 5524 | goto num; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 35c8923b5554..c82fdc1eab7c 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | |||
64 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | 64 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, |
65 | void __user *buffer, size_t *lenp, | 65 | void __user *buffer, size_t *lenp, |
66 | loff_t *ppos); | 66 | loff_t *ppos); |
67 | static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | ||
68 | void __user *buffer, size_t *lenp, | ||
69 | loff_t *ppos); | ||
67 | 70 | ||
68 | static struct ctl_table sctp_table[] = { | 71 | static struct ctl_table sctp_table[] = { |
69 | { | 72 | { |
@@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = { | |||
266 | .data = &init_net.sctp.auth_enable, | 269 | .data = &init_net.sctp.auth_enable, |
267 | .maxlen = sizeof(int), | 270 | .maxlen = sizeof(int), |
268 | .mode = 0644, | 271 | .mode = 0644, |
269 | .proc_handler = proc_dointvec, | 272 | .proc_handler = proc_sctp_do_auth, |
270 | }, | 273 | }, |
271 | { | 274 | { |
272 | .procname = "addr_scope_policy", | 275 | .procname = "addr_scope_policy", |
@@ -400,6 +403,37 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | |||
400 | return ret; | 403 | return ret; |
401 | } | 404 | } |
402 | 405 | ||
406 | static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | ||
407 | void __user *buffer, size_t *lenp, | ||
408 | loff_t *ppos) | ||
409 | { | ||
410 | struct net *net = current->nsproxy->net_ns; | ||
411 | struct ctl_table tbl; | ||
412 | int new_value, ret; | ||
413 | |||
414 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
415 | tbl.maxlen = sizeof(unsigned int); | ||
416 | |||
417 | if (write) | ||
418 | tbl.data = &new_value; | ||
419 | else | ||
420 | tbl.data = &net->sctp.auth_enable; | ||
421 | |||
422 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
423 | |||
424 | if (write) { | ||
425 | struct sock *sk = net->sctp.ctl_sock; | ||
426 | |||
427 | net->sctp.auth_enable = new_value; | ||
428 | /* Update the value in the control socket */ | ||
429 | lock_sock(sk); | ||
430 | sctp_sk(sk)->ep->auth_enable = new_value; | ||
431 | release_sock(sk); | ||
432 | } | ||
433 | |||
434 | return ret; | ||
435 | } | ||
436 | |||
403 | int sctp_sysctl_net_register(struct net *net) | 437 | int sctp_sysctl_net_register(struct net *net) |
404 | { | 438 | { |
405 | struct ctl_table *table = sctp_net_table; | 439 | struct ctl_table *table = sctp_net_table; |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 8d198ae03606..85c64658bd0b 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -989,7 +989,7 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | |||
989 | skb = sctp_event2skb(event); | 989 | skb = sctp_event2skb(event); |
990 | /* Set the owner and charge rwnd for bytes received. */ | 990 | /* Set the owner and charge rwnd for bytes received. */ |
991 | sctp_ulpevent_set_owner(event, asoc); | 991 | sctp_ulpevent_set_owner(event, asoc); |
992 | sctp_assoc_rwnd_update(asoc, false); | 992 | sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb)); |
993 | 993 | ||
994 | if (!skb->data_len) | 994 | if (!skb->data_len) |
995 | return; | 995 | return; |
@@ -1011,7 +1011,6 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
1011 | { | 1011 | { |
1012 | struct sk_buff *skb, *frag; | 1012 | struct sk_buff *skb, *frag; |
1013 | unsigned int len; | 1013 | unsigned int len; |
1014 | struct sctp_association *asoc; | ||
1015 | 1014 | ||
1016 | /* Current stack structures assume that the rcv buffer is | 1015 | /* Current stack structures assume that the rcv buffer is |
1017 | * per socket. For UDP style sockets this is not true as | 1016 | * per socket. For UDP style sockets this is not true as |
@@ -1036,11 +1035,8 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
1036 | } | 1035 | } |
1037 | 1036 | ||
1038 | done: | 1037 | done: |
1039 | asoc = event->asoc; | 1038 | sctp_assoc_rwnd_increase(event->asoc, len); |
1040 | sctp_association_hold(asoc); | ||
1041 | sctp_ulpevent_release_owner(event); | 1039 | sctp_ulpevent_release_owner(event); |
1042 | sctp_assoc_rwnd_update(asoc, true); | ||
1043 | sctp_association_put(asoc); | ||
1044 | } | 1040 | } |
1045 | 1041 | ||
1046 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) | 1042 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) |
diff --git a/net/socket.c b/net/socket.c index 1b1e7e6a960f..abf56b2a14f9 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1880,8 +1880,8 @@ out: | |||
1880 | * Receive a datagram from a socket. | 1880 | * Receive a datagram from a socket. |
1881 | */ | 1881 | */ |
1882 | 1882 | ||
1883 | asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size, | 1883 | SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, |
1884 | unsigned int flags) | 1884 | unsigned int, flags) |
1885 | { | 1885 | { |
1886 | return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); | 1886 | return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); |
1887 | } | 1887 | } |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 3aaf73de9e2d..ad844d365340 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
47 | int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); | 47 | int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); |
48 | u16 cmd; | 48 | u16 cmd; |
49 | 49 | ||
50 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) | 50 | if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN))) |
51 | cmd = TIPC_CMD_NOT_NET_ADMIN; | 51 | cmd = TIPC_CMD_NOT_NET_ADMIN; |
52 | else | 52 | else |
53 | cmd = req_userhdr->cmd; | 53 | cmd = req_userhdr->cmd; |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5adfd94c5b85..85d232bed87d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -1925,9 +1925,23 @@ static struct miscdevice vsock_device = { | |||
1925 | .fops = &vsock_device_ops, | 1925 | .fops = &vsock_device_ops, |
1926 | }; | 1926 | }; |
1927 | 1927 | ||
1928 | static int __vsock_core_init(void) | 1928 | int __vsock_core_init(const struct vsock_transport *t, struct module *owner) |
1929 | { | 1929 | { |
1930 | int err; | 1930 | int err = mutex_lock_interruptible(&vsock_register_mutex); |
1931 | |||
1932 | if (err) | ||
1933 | return err; | ||
1934 | |||
1935 | if (transport) { | ||
1936 | err = -EBUSY; | ||
1937 | goto err_busy; | ||
1938 | } | ||
1939 | |||
1940 | /* Transport must be the owner of the protocol so that it can't | ||
1941 | * unload while there are open sockets. | ||
1942 | */ | ||
1943 | vsock_proto.owner = owner; | ||
1944 | transport = t; | ||
1931 | 1945 | ||
1932 | vsock_init_tables(); | 1946 | vsock_init_tables(); |
1933 | 1947 | ||
@@ -1951,36 +1965,19 @@ static int __vsock_core_init(void) | |||
1951 | goto err_unregister_proto; | 1965 | goto err_unregister_proto; |
1952 | } | 1966 | } |
1953 | 1967 | ||
1968 | mutex_unlock(&vsock_register_mutex); | ||
1954 | return 0; | 1969 | return 0; |
1955 | 1970 | ||
1956 | err_unregister_proto: | 1971 | err_unregister_proto: |
1957 | proto_unregister(&vsock_proto); | 1972 | proto_unregister(&vsock_proto); |
1958 | err_misc_deregister: | 1973 | err_misc_deregister: |
1959 | misc_deregister(&vsock_device); | 1974 | misc_deregister(&vsock_device); |
1960 | return err; | 1975 | transport = NULL; |
1961 | } | 1976 | err_busy: |
1962 | |||
1963 | int vsock_core_init(const struct vsock_transport *t) | ||
1964 | { | ||
1965 | int retval = mutex_lock_interruptible(&vsock_register_mutex); | ||
1966 | if (retval) | ||
1967 | return retval; | ||
1968 | |||
1969 | if (transport) { | ||
1970 | retval = -EBUSY; | ||
1971 | goto out; | ||
1972 | } | ||
1973 | |||
1974 | transport = t; | ||
1975 | retval = __vsock_core_init(); | ||
1976 | if (retval) | ||
1977 | transport = NULL; | ||
1978 | |||
1979 | out: | ||
1980 | mutex_unlock(&vsock_register_mutex); | 1977 | mutex_unlock(&vsock_register_mutex); |
1981 | return retval; | 1978 | return err; |
1982 | } | 1979 | } |
1983 | EXPORT_SYMBOL_GPL(vsock_core_init); | 1980 | EXPORT_SYMBOL_GPL(__vsock_core_init); |
1984 | 1981 | ||
1985 | void vsock_core_exit(void) | 1982 | void vsock_core_exit(void) |
1986 | { | 1983 | { |
@@ -2000,5 +1997,5 @@ EXPORT_SYMBOL_GPL(vsock_core_exit); | |||
2000 | 1997 | ||
2001 | MODULE_AUTHOR("VMware, Inc."); | 1998 | MODULE_AUTHOR("VMware, Inc."); |
2002 | MODULE_DESCRIPTION("VMware Virtual Socket Family"); | 1999 | MODULE_DESCRIPTION("VMware Virtual Socket Family"); |
2003 | MODULE_VERSION("1.0.0.0-k"); | 2000 | MODULE_VERSION("1.0.1.0-k"); |
2004 | MODULE_LICENSE("GPL v2"); | 2001 | MODULE_LICENSE("GPL v2"); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 7d09a712cb1f..88f108edfb58 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -284,14 +284,22 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy) | |||
284 | } | 284 | } |
285 | EXPORT_SYMBOL(cfg80211_sched_scan_results); | 285 | EXPORT_SYMBOL(cfg80211_sched_scan_results); |
286 | 286 | ||
287 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | 287 | void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy) |
288 | { | 288 | { |
289 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 289 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
290 | 290 | ||
291 | ASSERT_RTNL(); | ||
292 | |||
291 | trace_cfg80211_sched_scan_stopped(wiphy); | 293 | trace_cfg80211_sched_scan_stopped(wiphy); |
292 | 294 | ||
293 | rtnl_lock(); | ||
294 | __cfg80211_stop_sched_scan(rdev, true); | 295 | __cfg80211_stop_sched_scan(rdev, true); |
296 | } | ||
297 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl); | ||
298 | |||
299 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | ||
300 | { | ||
301 | rtnl_lock(); | ||
302 | cfg80211_sched_scan_stopped_rtnl(wiphy); | ||
295 | rtnl_unlock(); | 303 | rtnl_unlock(); |
296 | } | 304 | } |
297 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | 305 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index acdcb4a81817..3546a77033de 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -234,7 +234,6 @@ void cfg80211_conn_work(struct work_struct *work) | |||
234 | NULL, 0, NULL, 0, | 234 | NULL, 0, NULL, 0, |
235 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 235 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
236 | false, NULL); | 236 | false, NULL); |
237 | cfg80211_sme_free(wdev); | ||
238 | } | 237 | } |
239 | wdev_unlock(wdev); | 238 | wdev_unlock(wdev); |
240 | } | 239 | } |
@@ -648,6 +647,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
648 | cfg80211_unhold_bss(bss_from_pub(bss)); | 647 | cfg80211_unhold_bss(bss_from_pub(bss)); |
649 | cfg80211_put_bss(wdev->wiphy, bss); | 648 | cfg80211_put_bss(wdev->wiphy, bss); |
650 | } | 649 | } |
650 | cfg80211_sme_free(wdev); | ||
651 | return; | 651 | return; |
652 | } | 652 | } |
653 | 653 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f02f511b7107..c08fbd11ceff 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1842,7 +1842,7 @@ purge_queue: | |||
1842 | xfrm_pol_put(pol); | 1842 | xfrm_pol_put(pol); |
1843 | } | 1843 | } |
1844 | 1844 | ||
1845 | static int xdst_queue_output(struct sk_buff *skb) | 1845 | static int xdst_queue_output(struct sock *sk, struct sk_buff *skb) |
1846 | { | 1846 | { |
1847 | unsigned long sched_next; | 1847 | unsigned long sched_next; |
1848 | struct dst_entry *dst = skb_dst(skb); | 1848 | struct dst_entry *dst = skb_dst(skb); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8f131c10a6f3..51398ae6cda8 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -2377,7 +2377,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2377 | link = &xfrm_dispatch[type]; | 2377 | link = &xfrm_dispatch[type]; |
2378 | 2378 | ||
2379 | /* All operations require privileges, even GET */ | 2379 | /* All operations require privileges, even GET */ |
2380 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 2380 | if (!netlink_net_capable(skb, CAP_NET_ADMIN)) |
2381 | return -EPERM; | 2381 | return -EPERM; |
2382 | 2382 | ||
2383 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 2383 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |