diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-10 23:02:51 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-10 23:02:51 -0400 |
commit | 3873691e5ab34fa26948643d038a2b98c4437298 (patch) | |
tree | 5327469194c2167830bce38b56a618b754cdbeea /net | |
parent | c2050a454c7f123d7a57fa1d76ff61bd43643abb (diff) | |
parent | aadfa8019e8114539cfa0b1eb2e5a9c83094a590 (diff) |
Merge remote-tracking branch 'ovl/rename2' into for-linus
Diffstat (limited to 'net')
68 files changed, 482 insertions, 270 deletions
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 7d170010beb9..ee08540ce503 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c | |||
@@ -335,7 +335,7 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) | |||
335 | goto out; | 335 | goto out; |
336 | 336 | ||
337 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); | 337 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); |
338 | elp_buff = skb_push(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); | 338 | elp_buff = skb_put(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); |
339 | elp_packet = (struct batadv_elp_packet *)elp_buff; | 339 | elp_packet = (struct batadv_elp_packet *)elp_buff; |
340 | memset(elp_packet, 0, BATADV_ELP_HLEN); | 340 | memset(elp_packet, 0, BATADV_ELP_HLEN); |
341 | 341 | ||
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 7602c001e92b..3d199478c405 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -470,6 +470,29 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, | |||
470 | } | 470 | } |
471 | 471 | ||
472 | /** | 472 | /** |
473 | * batadv_last_bonding_get - Get last_bonding_candidate of orig_node | ||
474 | * @orig_node: originator node whose last bonding candidate should be retrieved | ||
475 | * | ||
476 | * Return: last bonding candidate of router or NULL if not found | ||
477 | * | ||
478 | * The object is returned with refcounter increased by 1. | ||
479 | */ | ||
480 | static struct batadv_orig_ifinfo * | ||
481 | batadv_last_bonding_get(struct batadv_orig_node *orig_node) | ||
482 | { | ||
483 | struct batadv_orig_ifinfo *last_bonding_candidate; | ||
484 | |||
485 | spin_lock_bh(&orig_node->neigh_list_lock); | ||
486 | last_bonding_candidate = orig_node->last_bonding_candidate; | ||
487 | |||
488 | if (last_bonding_candidate) | ||
489 | kref_get(&last_bonding_candidate->refcount); | ||
490 | spin_unlock_bh(&orig_node->neigh_list_lock); | ||
491 | |||
492 | return last_bonding_candidate; | ||
493 | } | ||
494 | |||
495 | /** | ||
473 | * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node | 496 | * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node |
474 | * @orig_node: originator node whose bonding candidates should be replaced | 497 | * @orig_node: originator node whose bonding candidates should be replaced |
475 | * @new_candidate: new bonding candidate or NULL | 498 | * @new_candidate: new bonding candidate or NULL |
@@ -539,7 +562,7 @@ batadv_find_router(struct batadv_priv *bat_priv, | |||
539 | * router - obviously there are no other candidates. | 562 | * router - obviously there are no other candidates. |
540 | */ | 563 | */ |
541 | rcu_read_lock(); | 564 | rcu_read_lock(); |
542 | last_candidate = orig_node->last_bonding_candidate; | 565 | last_candidate = batadv_last_bonding_get(orig_node); |
543 | if (last_candidate) | 566 | if (last_candidate) |
544 | last_cand_router = rcu_dereference(last_candidate->router); | 567 | last_cand_router = rcu_dereference(last_candidate->router); |
545 | 568 | ||
@@ -631,6 +654,9 @@ next: | |||
631 | batadv_orig_ifinfo_put(next_candidate); | 654 | batadv_orig_ifinfo_put(next_candidate); |
632 | } | 655 | } |
633 | 656 | ||
657 | if (last_candidate) | ||
658 | batadv_orig_ifinfo_put(last_candidate); | ||
659 | |||
634 | return router; | 660 | return router; |
635 | } | 661 | } |
636 | 662 | ||
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 8e486203d133..abe11f085479 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -80,13 +80,10 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, | |||
80 | 80 | ||
81 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; | 81 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; |
82 | 82 | ||
83 | if (dev->flags & IFF_NOARP) | 83 | if ((dev->flags & IFF_NOARP) || |
84 | !pskb_may_pull(skb, arp_hdr_len(dev))) | ||
84 | return; | 85 | return; |
85 | 86 | ||
86 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) { | ||
87 | dev->stats.tx_dropped++; | ||
88 | return; | ||
89 | } | ||
90 | parp = arp_hdr(skb); | 87 | parp = arp_hdr(skb); |
91 | 88 | ||
92 | if (parp->ar_pro != htons(ETH_P_IP) || | 89 | if (parp->ar_pro != htons(ETH_P_IP) || |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a5423a1eec05..c5fea9393946 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1138,7 +1138,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, | |||
1138 | } else { | 1138 | } else { |
1139 | err = br_ip6_multicast_add_group(br, port, | 1139 | err = br_ip6_multicast_add_group(br, port, |
1140 | &grec->grec_mca, vid); | 1140 | &grec->grec_mca, vid); |
1141 | if (!err) | 1141 | if (err) |
1142 | break; | 1142 | break; |
1143 | } | 1143 | } |
1144 | } | 1144 | } |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index cceac5bb658f..0833c251aef7 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -368,6 +368,8 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, | |||
368 | 368 | ||
369 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); | 369 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); |
370 | if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { | 370 | if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { |
371 | if (!IS_ERR(match)) | ||
372 | module_put(match->me); | ||
371 | request_module("ebt_%s", m->u.name); | 373 | request_module("ebt_%s", m->u.name); |
372 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); | 374 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); |
373 | } | 375 | } |
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c index 4b901d9f2e7c..ad47a921b701 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c | |||
@@ -86,6 +86,7 @@ static const struct nft_expr_ops nft_meta_bridge_set_ops = { | |||
86 | .init = nft_meta_set_init, | 86 | .init = nft_meta_set_init, |
87 | .destroy = nft_meta_set_destroy, | 87 | .destroy = nft_meta_set_destroy, |
88 | .dump = nft_meta_set_dump, | 88 | .dump = nft_meta_set_dump, |
89 | .validate = nft_meta_set_validate, | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | static const struct nft_expr_ops * | 92 | static const struct nft_expr_ops * |
diff --git a/net/core/dev.c b/net/core/dev.c index dd6ce598de89..ea6312057a71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3975,6 +3975,22 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, | |||
3975 | } | 3975 | } |
3976 | 3976 | ||
3977 | /** | 3977 | /** |
3978 | * netdev_is_rx_handler_busy - check if receive handler is registered | ||
3979 | * @dev: device to check | ||
3980 | * | ||
3981 | * Check if a receive handler is already registered for a given device. | ||
3982 | * Return true if there one. | ||
3983 | * | ||
3984 | * The caller must hold the rtnl_mutex. | ||
3985 | */ | ||
3986 | bool netdev_is_rx_handler_busy(struct net_device *dev) | ||
3987 | { | ||
3988 | ASSERT_RTNL(); | ||
3989 | return dev && rtnl_dereference(dev->rx_handler); | ||
3990 | } | ||
3991 | EXPORT_SYMBOL_GPL(netdev_is_rx_handler_busy); | ||
3992 | |||
3993 | /** | ||
3978 | * netdev_rx_handler_register - register receive handler | 3994 | * netdev_rx_handler_register - register receive handler |
3979 | * @dev: device to register a handler for | 3995 | * @dev: device to register a handler for |
3980 | * @rx_handler: receive handler to register | 3996 | * @rx_handler: receive handler to register |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 61ad43f61c5e..52742a02814f 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -680,11 +680,13 @@ EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric); | |||
680 | void __skb_get_hash(struct sk_buff *skb) | 680 | void __skb_get_hash(struct sk_buff *skb) |
681 | { | 681 | { |
682 | struct flow_keys keys; | 682 | struct flow_keys keys; |
683 | u32 hash; | ||
683 | 684 | ||
684 | __flow_hash_secret_init(); | 685 | __flow_hash_secret_init(); |
685 | 686 | ||
686 | __skb_set_sw_hash(skb, ___skb_get_hash(skb, &keys, hashrnd), | 687 | hash = ___skb_get_hash(skb, &keys, hashrnd); |
687 | flow_keys_have_l4(&keys)); | 688 | |
689 | __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); | ||
688 | } | 690 | } |
689 | EXPORT_SYMBOL(__skb_get_hash); | 691 | EXPORT_SYMBOL(__skb_get_hash); |
690 | 692 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 25dab8b60223..fd7b41edf1ce 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1362,7 +1362,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
1362 | if (!try_module_get(prot->owner)) | 1362 | if (!try_module_get(prot->owner)) |
1363 | goto out_free_sec; | 1363 | goto out_free_sec; |
1364 | sk_tx_queue_clear(sk); | 1364 | sk_tx_queue_clear(sk); |
1365 | cgroup_sk_alloc(&sk->sk_cgrp_data); | ||
1366 | } | 1365 | } |
1367 | 1366 | ||
1368 | return sk; | 1367 | return sk; |
@@ -1422,6 +1421,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1422 | sock_net_set(sk, net); | 1421 | sock_net_set(sk, net); |
1423 | atomic_set(&sk->sk_wmem_alloc, 1); | 1422 | atomic_set(&sk->sk_wmem_alloc, 1); |
1424 | 1423 | ||
1424 | cgroup_sk_alloc(&sk->sk_cgrp_data); | ||
1425 | sock_update_classid(&sk->sk_cgrp_data); | 1425 | sock_update_classid(&sk->sk_cgrp_data); |
1426 | sock_update_netprioidx(&sk->sk_cgrp_data); | 1426 | sock_update_netprioidx(&sk->sk_cgrp_data); |
1427 | } | 1427 | } |
@@ -1566,6 +1566,9 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1566 | newsk->sk_priority = 0; | 1566 | newsk->sk_priority = 0; |
1567 | newsk->sk_incoming_cpu = raw_smp_processor_id(); | 1567 | newsk->sk_incoming_cpu = raw_smp_processor_id(); |
1568 | atomic64_set(&newsk->sk_cookie, 0); | 1568 | atomic64_set(&newsk->sk_cookie, 0); |
1569 | |||
1570 | cgroup_sk_alloc(&newsk->sk_cgrp_data); | ||
1571 | |||
1569 | /* | 1572 | /* |
1570 | * Before updating sk_refcnt, we must commit prior changes to memory | 1573 | * Before updating sk_refcnt, we must commit prior changes to memory |
1571 | * (Documentation/RCU/rculist_nulls.txt for details) | 1574 | * (Documentation/RCU/rculist_nulls.txt for details) |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 415e117967c7..062a67ca9a21 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -2232,7 +2232,7 @@ static struct devinet_sysctl_table { | |||
2232 | }; | 2232 | }; |
2233 | 2233 | ||
2234 | static int __devinet_sysctl_register(struct net *net, char *dev_name, | 2234 | static int __devinet_sysctl_register(struct net *net, char *dev_name, |
2235 | struct ipv4_devconf *p) | 2235 | int ifindex, struct ipv4_devconf *p) |
2236 | { | 2236 | { |
2237 | int i; | 2237 | int i; |
2238 | struct devinet_sysctl_table *t; | 2238 | struct devinet_sysctl_table *t; |
@@ -2255,6 +2255,8 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name, | |||
2255 | goto free; | 2255 | goto free; |
2256 | 2256 | ||
2257 | p->sysctl = t; | 2257 | p->sysctl = t; |
2258 | |||
2259 | inet_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p); | ||
2258 | return 0; | 2260 | return 0; |
2259 | 2261 | ||
2260 | free: | 2262 | free: |
@@ -2286,7 +2288,7 @@ static int devinet_sysctl_register(struct in_device *idev) | |||
2286 | if (err) | 2288 | if (err) |
2287 | return err; | 2289 | return err; |
2288 | err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, | 2290 | err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, |
2289 | &idev->cnf); | 2291 | idev->dev->ifindex, &idev->cnf); |
2290 | if (err) | 2292 | if (err) |
2291 | neigh_sysctl_unregister(idev->arp_parms); | 2293 | neigh_sysctl_unregister(idev->arp_parms); |
2292 | return err; | 2294 | return err; |
@@ -2347,11 +2349,12 @@ static __net_init int devinet_init_net(struct net *net) | |||
2347 | } | 2349 | } |
2348 | 2350 | ||
2349 | #ifdef CONFIG_SYSCTL | 2351 | #ifdef CONFIG_SYSCTL |
2350 | err = __devinet_sysctl_register(net, "all", all); | 2352 | err = __devinet_sysctl_register(net, "all", NETCONFA_IFINDEX_ALL, all); |
2351 | if (err < 0) | 2353 | if (err < 0) |
2352 | goto err_reg_all; | 2354 | goto err_reg_all; |
2353 | 2355 | ||
2354 | err = __devinet_sysctl_register(net, "default", dflt); | 2356 | err = __devinet_sysctl_register(net, "default", |
2357 | NETCONFA_IFINDEX_DEFAULT, dflt); | ||
2355 | if (err < 0) | 2358 | if (err < 0) |
2356 | goto err_reg_dflt; | 2359 | goto err_reg_dflt; |
2357 | 2360 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index ef2ebeb89d0f..1b25daf8c7f1 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -509,6 +509,7 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, | |||
509 | if (!dev) | 509 | if (!dev) |
510 | return -ENODEV; | 510 | return -ENODEV; |
511 | cfg->fc_oif = dev->ifindex; | 511 | cfg->fc_oif = dev->ifindex; |
512 | cfg->fc_table = l3mdev_fib_table(dev); | ||
512 | if (colon) { | 513 | if (colon) { |
513 | struct in_ifaddr *ifa; | 514 | struct in_ifaddr *ifa; |
514 | struct in_device *in_dev = __in_dev_get_rtnl(dev); | 515 | struct in_device *in_dev = __in_dev_get_rtnl(dev); |
@@ -1027,7 +1028,7 @@ no_promotions: | |||
1027 | * First of all, we scan fib_info list searching | 1028 | * First of all, we scan fib_info list searching |
1028 | * for stray nexthop entries, then ignite fib_flush. | 1029 | * for stray nexthop entries, then ignite fib_flush. |
1029 | */ | 1030 | */ |
1030 | if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) | 1031 | if (fib_sync_down_addr(dev, ifa->ifa_local)) |
1031 | fib_flush(dev_net(dev)); | 1032 | fib_flush(dev_net(dev)); |
1032 | } | 1033 | } |
1033 | } | 1034 | } |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 539fa264e67d..e9f56225e53f 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -1057,6 +1057,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
1057 | fi->fib_priority = cfg->fc_priority; | 1057 | fi->fib_priority = cfg->fc_priority; |
1058 | fi->fib_prefsrc = cfg->fc_prefsrc; | 1058 | fi->fib_prefsrc = cfg->fc_prefsrc; |
1059 | fi->fib_type = cfg->fc_type; | 1059 | fi->fib_type = cfg->fc_type; |
1060 | fi->fib_tb_id = cfg->fc_table; | ||
1060 | 1061 | ||
1061 | fi->fib_nhs = nhs; | 1062 | fi->fib_nhs = nhs; |
1062 | change_nexthops(fi) { | 1063 | change_nexthops(fi) { |
@@ -1337,18 +1338,21 @@ nla_put_failure: | |||
1337 | * referring to it. | 1338 | * referring to it. |
1338 | * - device went down -> we must shutdown all nexthops going via it. | 1339 | * - device went down -> we must shutdown all nexthops going via it. |
1339 | */ | 1340 | */ |
1340 | int fib_sync_down_addr(struct net *net, __be32 local) | 1341 | int fib_sync_down_addr(struct net_device *dev, __be32 local) |
1341 | { | 1342 | { |
1342 | int ret = 0; | 1343 | int ret = 0; |
1343 | unsigned int hash = fib_laddr_hashfn(local); | 1344 | unsigned int hash = fib_laddr_hashfn(local); |
1344 | struct hlist_head *head = &fib_info_laddrhash[hash]; | 1345 | struct hlist_head *head = &fib_info_laddrhash[hash]; |
1346 | struct net *net = dev_net(dev); | ||
1347 | int tb_id = l3mdev_fib_table(dev); | ||
1345 | struct fib_info *fi; | 1348 | struct fib_info *fi; |
1346 | 1349 | ||
1347 | if (!fib_info_laddrhash || local == 0) | 1350 | if (!fib_info_laddrhash || local == 0) |
1348 | return 0; | 1351 | return 0; |
1349 | 1352 | ||
1350 | hlist_for_each_entry(fi, head, fib_lhash) { | 1353 | hlist_for_each_entry(fi, head, fib_lhash) { |
1351 | if (!net_eq(fi->fib_net, net)) | 1354 | if (!net_eq(fi->fib_net, net) || |
1355 | fi->fib_tb_id != tb_id) | ||
1352 | continue; | 1356 | continue; |
1353 | if (fi->fib_prefsrc == local) { | 1357 | if (fi->fib_prefsrc == local) { |
1354 | fi->fib_flags |= RTNH_F_DEAD; | 1358 | fi->fib_flags |= RTNH_F_DEAD; |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 4b351af3e67b..d6feabb03516 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -312,6 +312,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
312 | { | 312 | { |
313 | const struct iphdr *iph = ip_hdr(skb); | 313 | const struct iphdr *iph = ip_hdr(skb); |
314 | struct rtable *rt; | 314 | struct rtable *rt; |
315 | struct net_device *dev = skb->dev; | ||
315 | 316 | ||
316 | /* if ingress device is enslaved to an L3 master device pass the | 317 | /* if ingress device is enslaved to an L3 master device pass the |
317 | * skb to its handler for processing | 318 | * skb to its handler for processing |
@@ -341,7 +342,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
341 | */ | 342 | */ |
342 | if (!skb_valid_dst(skb)) { | 343 | if (!skb_valid_dst(skb)) { |
343 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, | 344 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, |
344 | iph->tos, skb->dev); | 345 | iph->tos, dev); |
345 | if (unlikely(err)) { | 346 | if (unlikely(err)) { |
346 | if (err == -EXDEV) | 347 | if (err == -EXDEV) |
347 | __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); | 348 | __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); |
@@ -370,7 +371,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
370 | __IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len); | 371 | __IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len); |
371 | } else if (skb->pkt_type == PACKET_BROADCAST || | 372 | } else if (skb->pkt_type == PACKET_BROADCAST || |
372 | skb->pkt_type == PACKET_MULTICAST) { | 373 | skb->pkt_type == PACKET_MULTICAST) { |
373 | struct in_device *in_dev = __in_dev_get_rcu(skb->dev); | 374 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
374 | 375 | ||
375 | /* RFC 1122 3.3.6: | 376 | /* RFC 1122 3.3.6: |
376 | * | 377 | * |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index cc701fa70b12..5d7944f394d9 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -88,6 +88,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
88 | struct net_device *dev; | 88 | struct net_device *dev; |
89 | struct pcpu_sw_netstats *tstats; | 89 | struct pcpu_sw_netstats *tstats; |
90 | struct xfrm_state *x; | 90 | struct xfrm_state *x; |
91 | struct xfrm_mode *inner_mode; | ||
91 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; | 92 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; |
92 | u32 orig_mark = skb->mark; | 93 | u32 orig_mark = skb->mark; |
93 | int ret; | 94 | int ret; |
@@ -105,7 +106,19 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
105 | } | 106 | } |
106 | 107 | ||
107 | x = xfrm_input_state(skb); | 108 | x = xfrm_input_state(skb); |
108 | family = x->inner_mode->afinfo->family; | 109 | |
110 | inner_mode = x->inner_mode; | ||
111 | |||
112 | if (x->sel.family == AF_UNSPEC) { | ||
113 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | ||
114 | if (inner_mode == NULL) { | ||
115 | XFRM_INC_STATS(dev_net(skb->dev), | ||
116 | LINUX_MIB_XFRMINSTATEMODEERROR); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | family = inner_mode->afinfo->family; | ||
109 | 122 | ||
110 | skb->mark = be32_to_cpu(tunnel->parms.i_key); | 123 | skb->mark = be32_to_cpu(tunnel->parms.i_key); |
111 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | 124 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 26253328d227..a87bcd2d4a94 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -2076,6 +2076,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
2076 | struct rta_mfc_stats mfcs; | 2076 | struct rta_mfc_stats mfcs; |
2077 | struct nlattr *mp_attr; | 2077 | struct nlattr *mp_attr; |
2078 | struct rtnexthop *nhp; | 2078 | struct rtnexthop *nhp; |
2079 | unsigned long lastuse; | ||
2079 | int ct; | 2080 | int ct; |
2080 | 2081 | ||
2081 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2082 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
@@ -2105,12 +2106,14 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
2105 | 2106 | ||
2106 | nla_nest_end(skb, mp_attr); | 2107 | nla_nest_end(skb, mp_attr); |
2107 | 2108 | ||
2109 | lastuse = READ_ONCE(c->mfc_un.res.lastuse); | ||
2110 | lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0; | ||
2111 | |||
2108 | mfcs.mfcs_packets = c->mfc_un.res.pkt; | 2112 | mfcs.mfcs_packets = c->mfc_un.res.pkt; |
2109 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; | 2113 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; |
2110 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; | 2114 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; |
2111 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || | 2115 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || |
2112 | nla_put_u64_64bit(skb, RTA_EXPIRES, | 2116 | nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse), |
2113 | jiffies_to_clock_t(c->mfc_un.res.lastuse), | ||
2114 | RTA_PAD)) | 2117 | RTA_PAD)) |
2115 | return -EMSGSIZE; | 2118 | return -EMSGSIZE; |
2116 | 2119 | ||
diff --git a/net/ipv4/netfilter/nft_chain_route_ipv4.c b/net/ipv4/netfilter/nft_chain_route_ipv4.c index 2375b0a8be46..30493beb611a 100644 --- a/net/ipv4/netfilter/nft_chain_route_ipv4.c +++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c | |||
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, | |||
31 | __be32 saddr, daddr; | 31 | __be32 saddr, daddr; |
32 | u_int8_t tos; | 32 | u_int8_t tos; |
33 | const struct iphdr *iph; | 33 | const struct iphdr *iph; |
34 | int err; | ||
34 | 35 | ||
35 | /* root is playing with raw sockets. */ | 36 | /* root is playing with raw sockets. */ |
36 | if (skb->len < sizeof(struct iphdr) || | 37 | if (skb->len < sizeof(struct iphdr) || |
@@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(void *priv, | |||
46 | tos = iph->tos; | 47 | tos = iph->tos; |
47 | 48 | ||
48 | ret = nft_do_chain(&pkt, priv); | 49 | ret = nft_do_chain(&pkt, priv); |
49 | if (ret != NF_DROP && ret != NF_QUEUE) { | 50 | if (ret != NF_DROP && ret != NF_STOLEN) { |
50 | iph = ip_hdr(skb); | 51 | iph = ip_hdr(skb); |
51 | 52 | ||
52 | if (iph->saddr != saddr || | 53 | if (iph->saddr != saddr || |
53 | iph->daddr != daddr || | 54 | iph->daddr != daddr || |
54 | skb->mark != mark || | 55 | skb->mark != mark || |
55 | iph->tos != tos) | 56 | iph->tos != tos) { |
56 | if (ip_route_me_harder(state->net, skb, RTN_UNSPEC)) | 57 | err = ip_route_me_harder(state->net, skb, RTN_UNSPEC); |
57 | ret = NF_DROP; | 58 | if (err < 0) |
59 | ret = NF_DROP_ERR(err); | ||
60 | } | ||
58 | } | 61 | } |
59 | return ret; | 62 | return ret; |
60 | } | 63 | } |
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c index c24f41c816b3..2c2553b9026c 100644 --- a/net/ipv4/netfilter/nft_reject_ipv4.c +++ b/net/ipv4/netfilter/nft_reject_ipv4.c | |||
@@ -46,6 +46,7 @@ static const struct nft_expr_ops nft_reject_ipv4_ops = { | |||
46 | .eval = nft_reject_ipv4_eval, | 46 | .eval = nft_reject_ipv4_eval, |
47 | .init = nft_reject_init, | 47 | .init = nft_reject_init, |
48 | .dump = nft_reject_dump, | 48 | .dump = nft_reject_dump, |
49 | .validate = nft_reject_validate, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { | 52 | static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a1f2830d8110..b5b47a26d4ec 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -476,12 +476,18 @@ u32 ip_idents_reserve(u32 hash, int segs) | |||
476 | atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; | 476 | atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; |
477 | u32 old = ACCESS_ONCE(*p_tstamp); | 477 | u32 old = ACCESS_ONCE(*p_tstamp); |
478 | u32 now = (u32)jiffies; | 478 | u32 now = (u32)jiffies; |
479 | u32 delta = 0; | 479 | u32 new, delta = 0; |
480 | 480 | ||
481 | if (old != now && cmpxchg(p_tstamp, old, now) == old) | 481 | if (old != now && cmpxchg(p_tstamp, old, now) == old) |
482 | delta = prandom_u32_max(now - old); | 482 | delta = prandom_u32_max(now - old); |
483 | 483 | ||
484 | return atomic_add_return(segs + delta, p_id) - segs; | 484 | /* Do not use atomic_add_return() as it makes UBSAN unhappy */ |
485 | do { | ||
486 | old = (u32)atomic_read(p_id); | ||
487 | new = old + delta + segs; | ||
488 | } while (atomic_cmpxchg(p_id, old, new) != old); | ||
489 | |||
490 | return new - segs; | ||
485 | } | 491 | } |
486 | EXPORT_SYMBOL(ip_idents_reserve); | 492 | EXPORT_SYMBOL(ip_idents_reserve); |
487 | 493 | ||
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 54d9f9b0120f..4e777a3243f9 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c | |||
@@ -150,6 +150,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb) | |||
150 | tp->segs_in = 0; | 150 | tp->segs_in = 0; |
151 | tcp_segs_in(tp, skb); | 151 | tcp_segs_in(tp, skb); |
152 | __skb_pull(skb, tcp_hdrlen(skb)); | 152 | __skb_pull(skb, tcp_hdrlen(skb)); |
153 | sk_forced_mem_schedule(sk, skb->truesize); | ||
153 | skb_set_owner_r(skb, sk); | 154 | skb_set_owner_r(skb, sk); |
154 | 155 | ||
155 | TCP_SKB_CB(skb)->seq++; | 156 | TCP_SKB_CB(skb)->seq++; |
@@ -226,6 +227,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, | |||
226 | tcp_fastopen_add_skb(child, skb); | 227 | tcp_fastopen_add_skb(child, skb); |
227 | 228 | ||
228 | tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; | 229 | tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; |
230 | tp->rcv_wup = tp->rcv_nxt; | ||
229 | /* tcp_conn_request() is sending the SYNACK, | 231 | /* tcp_conn_request() is sending the SYNACK, |
230 | * and queues the child into listener accept queue. | 232 | * and queues the child into listener accept queue. |
231 | */ | 233 | */ |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3ebf45b38bc3..08323bd95f2a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5885,7 +5885,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) | |||
5885 | * so release it. | 5885 | * so release it. |
5886 | */ | 5886 | */ |
5887 | if (req) { | 5887 | if (req) { |
5888 | tp->total_retrans = req->num_retrans; | 5888 | inet_csk(sk)->icsk_retransmits = 0; |
5889 | reqsk_fastopen_remove(sk, req, false); | 5889 | reqsk_fastopen_remove(sk, req, false); |
5890 | } else { | 5890 | } else { |
5891 | /* Make sure socket is routed, for correct metrics. */ | 5891 | /* Make sure socket is routed, for correct metrics. */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index bdaef7fd6e47..5288cec4a2b2 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2605,7 +2605,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) | |||
2605 | * copying overhead: fragmentation, tunneling, mangling etc. | 2605 | * copying overhead: fragmentation, tunneling, mangling etc. |
2606 | */ | 2606 | */ |
2607 | if (atomic_read(&sk->sk_wmem_alloc) > | 2607 | if (atomic_read(&sk->sk_wmem_alloc) > |
2608 | min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf)) | 2608 | min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), |
2609 | sk->sk_sndbuf)) | ||
2609 | return -EAGAIN; | 2610 | return -EAGAIN; |
2610 | 2611 | ||
2611 | if (skb_still_in_host_queue(sk, skb)) | 2612 | if (skb_still_in_host_queue(sk, skb)) |
@@ -2830,7 +2831,7 @@ begin_fwd: | |||
2830 | if (tcp_retransmit_skb(sk, skb, segs)) | 2831 | if (tcp_retransmit_skb(sk, skb, segs)) |
2831 | return; | 2832 | return; |
2832 | 2833 | ||
2833 | NET_INC_STATS(sock_net(sk), mib_idx); | 2834 | NET_ADD_STATS(sock_net(sk), mib_idx, tcp_skb_pcount(skb)); |
2834 | 2835 | ||
2835 | if (tcp_in_cwnd_reduction(sk)) | 2836 | if (tcp_in_cwnd_reduction(sk)) |
2836 | tp->prr_out += tcp_skb_pcount(skb); | 2837 | tp->prr_out += tcp_skb_pcount(skb); |
@@ -3567,6 +3568,8 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) | |||
3567 | if (!res) { | 3568 | if (!res) { |
3568 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | 3569 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); |
3569 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | 3570 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); |
3571 | if (unlikely(tcp_passive_fastopen(sk))) | ||
3572 | tcp_sk(sk)->total_retrans++; | ||
3570 | } | 3573 | } |
3571 | return res; | 3574 | return res; |
3572 | } | 3575 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index d84930b2dd95..f712b411f6ed 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -384,6 +384,7 @@ static void tcp_fastopen_synack_timer(struct sock *sk) | |||
384 | */ | 384 | */ |
385 | inet_rtx_syn_ack(sk, req); | 385 | inet_rtx_syn_ack(sk, req); |
386 | req->num_timeout++; | 386 | req->num_timeout++; |
387 | icsk->icsk_retransmits++; | ||
387 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 388 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
388 | TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); | 389 | TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); |
389 | } | 390 | } |
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index 028eb046ea40..9c5fc973267f 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c | |||
@@ -76,7 +76,7 @@ static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 acked) | |||
76 | if (!tcp_is_cwnd_limited(sk)) | 76 | if (!tcp_is_cwnd_limited(sk)) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | if (tp->snd_cwnd <= tp->snd_ssthresh) | 79 | if (tcp_in_slow_start(tp)) |
80 | tcp_slow_start(tp, acked); | 80 | tcp_slow_start(tp, acked); |
81 | 81 | ||
82 | else if (!yeah->doing_reno_now) { | 82 | else if (!yeah->doing_reno_now) { |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b644a23c3db0..41f5b504a782 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -29,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, | |||
29 | memset(fl4, 0, sizeof(*fl4)); | 29 | memset(fl4, 0, sizeof(*fl4)); |
30 | fl4->daddr = daddr->a4; | 30 | fl4->daddr = daddr->a4; |
31 | fl4->flowi4_tos = tos; | 31 | fl4->flowi4_tos = tos; |
32 | fl4->flowi4_oif = oif; | 32 | fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif); |
33 | if (saddr) | 33 | if (saddr) |
34 | fl4->saddr = saddr->a4; | 34 | fl4->saddr = saddr->a4; |
35 | 35 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index f418d2eaeddd..2f1f5d439788 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -778,7 +778,14 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
778 | } | 778 | } |
779 | 779 | ||
780 | if (p == &net->ipv6.devconf_all->forwarding) { | 780 | if (p == &net->ipv6.devconf_all->forwarding) { |
781 | int old_dflt = net->ipv6.devconf_dflt->forwarding; | ||
782 | |||
781 | net->ipv6.devconf_dflt->forwarding = newf; | 783 | net->ipv6.devconf_dflt->forwarding = newf; |
784 | if ((!newf) ^ (!old_dflt)) | ||
785 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
786 | NETCONFA_IFINDEX_DEFAULT, | ||
787 | net->ipv6.devconf_dflt); | ||
788 | |||
782 | addrconf_forward_change(net, newf); | 789 | addrconf_forward_change(net, newf); |
783 | if ((!newf) ^ (!old)) | 790 | if ((!newf) ^ (!old)) |
784 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | 791 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, |
@@ -1941,6 +1948,7 @@ errdad: | |||
1941 | spin_unlock_bh(&ifp->lock); | 1948 | spin_unlock_bh(&ifp->lock); |
1942 | 1949 | ||
1943 | addrconf_mod_dad_work(ifp, 0); | 1950 | addrconf_mod_dad_work(ifp, 0); |
1951 | in6_ifa_put(ifp); | ||
1944 | } | 1952 | } |
1945 | 1953 | ||
1946 | /* Join to solicited addr multicast group. | 1954 | /* Join to solicited addr multicast group. |
@@ -3850,6 +3858,7 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3850 | addrconf_dad_begin(ifp); | 3858 | addrconf_dad_begin(ifp); |
3851 | goto out; | 3859 | goto out; |
3852 | } else if (action == DAD_ABORT) { | 3860 | } else if (action == DAD_ABORT) { |
3861 | in6_ifa_hold(ifp); | ||
3853 | addrconf_dad_stop(ifp, 1); | 3862 | addrconf_dad_stop(ifp, 1); |
3854 | if (disable_ipv6) | 3863 | if (disable_ipv6) |
3855 | addrconf_ifdown(idev->dev, 0); | 3864 | addrconf_ifdown(idev->dev, 0); |
@@ -6025,7 +6034,7 @@ static const struct ctl_table addrconf_sysctl[] = { | |||
6025 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, | 6034 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, |
6026 | struct inet6_dev *idev, struct ipv6_devconf *p) | 6035 | struct inet6_dev *idev, struct ipv6_devconf *p) |
6027 | { | 6036 | { |
6028 | int i; | 6037 | int i, ifindex; |
6029 | struct ctl_table *table; | 6038 | struct ctl_table *table; |
6030 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; | 6039 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; |
6031 | 6040 | ||
@@ -6045,6 +6054,13 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name, | |||
6045 | if (!p->sysctl_header) | 6054 | if (!p->sysctl_header) |
6046 | goto free; | 6055 | goto free; |
6047 | 6056 | ||
6057 | if (!strcmp(dev_name, "all")) | ||
6058 | ifindex = NETCONFA_IFINDEX_ALL; | ||
6059 | else if (!strcmp(dev_name, "default")) | ||
6060 | ifindex = NETCONFA_IFINDEX_DEFAULT; | ||
6061 | else | ||
6062 | ifindex = idev->dev->ifindex; | ||
6063 | inet6_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p); | ||
6048 | return 0; | 6064 | return 0; |
6049 | 6065 | ||
6050 | free: | 6066 | free: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 7b0481e3738f..888543debe4e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1174,6 +1174,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1174 | encap_limit = t->parms.encap_limit; | 1174 | encap_limit = t->parms.encap_limit; |
1175 | 1175 | ||
1176 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); | 1176 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
1177 | fl6.flowi6_proto = IPPROTO_IPIP; | ||
1177 | 1178 | ||
1178 | dsfield = ipv4_get_dsfield(iph); | 1179 | dsfield = ipv4_get_dsfield(iph); |
1179 | 1180 | ||
@@ -1233,6 +1234,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1233 | encap_limit = t->parms.encap_limit; | 1234 | encap_limit = t->parms.encap_limit; |
1234 | 1235 | ||
1235 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); | 1236 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
1237 | fl6.flowi6_proto = IPPROTO_IPV6; | ||
1236 | 1238 | ||
1237 | dsfield = ipv6_get_dsfield(ipv6h); | 1239 | dsfield = ipv6_get_dsfield(ipv6h); |
1238 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) | 1240 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index d90a11f14040..5bd3afdcc771 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -321,11 +321,9 @@ static int vti6_rcv(struct sk_buff *skb) | |||
321 | goto discard; | 321 | goto discard; |
322 | } | 322 | } |
323 | 323 | ||
324 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; | ||
325 | |||
326 | rcu_read_unlock(); | 324 | rcu_read_unlock(); |
327 | 325 | ||
328 | return xfrm6_rcv(skb); | 326 | return xfrm6_rcv_tnl(skb, t); |
329 | } | 327 | } |
330 | rcu_read_unlock(); | 328 | rcu_read_unlock(); |
331 | return -EINVAL; | 329 | return -EINVAL; |
@@ -340,6 +338,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
340 | struct net_device *dev; | 338 | struct net_device *dev; |
341 | struct pcpu_sw_netstats *tstats; | 339 | struct pcpu_sw_netstats *tstats; |
342 | struct xfrm_state *x; | 340 | struct xfrm_state *x; |
341 | struct xfrm_mode *inner_mode; | ||
343 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; | 342 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; |
344 | u32 orig_mark = skb->mark; | 343 | u32 orig_mark = skb->mark; |
345 | int ret; | 344 | int ret; |
@@ -357,7 +356,19 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
357 | } | 356 | } |
358 | 357 | ||
359 | x = xfrm_input_state(skb); | 358 | x = xfrm_input_state(skb); |
360 | family = x->inner_mode->afinfo->family; | 359 | |
360 | inner_mode = x->inner_mode; | ||
361 | |||
362 | if (x->sel.family == AF_UNSPEC) { | ||
363 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | ||
364 | if (inner_mode == NULL) { | ||
365 | XFRM_INC_STATS(dev_net(skb->dev), | ||
366 | LINUX_MIB_XFRMINSTATEMODEERROR); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | family = inner_mode->afinfo->family; | ||
361 | 372 | ||
362 | skb->mark = be32_to_cpu(t->parms.i_key); | 373 | skb->mark = be32_to_cpu(t->parms.i_key); |
363 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | 374 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 6122f9c5cc49..fccb5dd91902 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -2239,6 +2239,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | |||
2239 | struct rta_mfc_stats mfcs; | 2239 | struct rta_mfc_stats mfcs; |
2240 | struct nlattr *mp_attr; | 2240 | struct nlattr *mp_attr; |
2241 | struct rtnexthop *nhp; | 2241 | struct rtnexthop *nhp; |
2242 | unsigned long lastuse; | ||
2242 | int ct; | 2243 | int ct; |
2243 | 2244 | ||
2244 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2245 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
@@ -2269,12 +2270,14 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | |||
2269 | 2270 | ||
2270 | nla_nest_end(skb, mp_attr); | 2271 | nla_nest_end(skb, mp_attr); |
2271 | 2272 | ||
2273 | lastuse = READ_ONCE(c->mfc_un.res.lastuse); | ||
2274 | lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0; | ||
2275 | |||
2272 | mfcs.mfcs_packets = c->mfc_un.res.pkt; | 2276 | mfcs.mfcs_packets = c->mfc_un.res.pkt; |
2273 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; | 2277 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; |
2274 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; | 2278 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; |
2275 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || | 2279 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || |
2276 | nla_put_u64_64bit(skb, RTA_EXPIRES, | 2280 | nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse), |
2277 | jiffies_to_clock_t(c->mfc_un.res.lastuse), | ||
2278 | RTA_PAD)) | 2281 | RTA_PAD)) |
2279 | return -EMSGSIZE; | 2282 | return -EMSGSIZE; |
2280 | 2283 | ||
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c index 71d995ff3108..2535223ba956 100644 --- a/net/ipv6/netfilter/nft_chain_route_ipv6.c +++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c | |||
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, | |||
31 | struct in6_addr saddr, daddr; | 31 | struct in6_addr saddr, daddr; |
32 | u_int8_t hop_limit; | 32 | u_int8_t hop_limit; |
33 | u32 mark, flowlabel; | 33 | u32 mark, flowlabel; |
34 | int err; | ||
34 | 35 | ||
35 | /* malformed packet, drop it */ | 36 | /* malformed packet, drop it */ |
36 | if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0) | 37 | if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0) |
@@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(void *priv, | |||
46 | flowlabel = *((u32 *)ipv6_hdr(skb)); | 47 | flowlabel = *((u32 *)ipv6_hdr(skb)); |
47 | 48 | ||
48 | ret = nft_do_chain(&pkt, priv); | 49 | ret = nft_do_chain(&pkt, priv); |
49 | if (ret != NF_DROP && ret != NF_QUEUE && | 50 | if (ret != NF_DROP && ret != NF_STOLEN && |
50 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || | 51 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || |
51 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || | 52 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || |
52 | skb->mark != mark || | 53 | skb->mark != mark || |
53 | ipv6_hdr(skb)->hop_limit != hop_limit || | 54 | ipv6_hdr(skb)->hop_limit != hop_limit || |
54 | flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) | 55 | flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) { |
55 | return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP; | 56 | err = ip6_route_me_harder(state->net, skb); |
57 | if (err < 0) | ||
58 | ret = NF_DROP_ERR(err); | ||
59 | } | ||
56 | 60 | ||
57 | return ret; | 61 | return ret; |
58 | } | 62 | } |
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c index 533cd5719c59..92bda9908bb9 100644 --- a/net/ipv6/netfilter/nft_reject_ipv6.c +++ b/net/ipv6/netfilter/nft_reject_ipv6.c | |||
@@ -47,6 +47,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = { | |||
47 | .eval = nft_reject_ipv6_eval, | 47 | .eval = nft_reject_ipv6_eval, |
48 | .init = nft_reject_init, | 48 | .init = nft_reject_init, |
49 | .dump = nft_reject_dump, | 49 | .dump = nft_reject_dump, |
50 | .validate = nft_reject_validate, | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { | 53 | static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 0900352c924c..0e983b694ee8 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
@@ -126,8 +126,10 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
126 | rt = (struct rt6_info *) dst; | 126 | rt = (struct rt6_info *) dst; |
127 | 127 | ||
128 | np = inet6_sk(sk); | 128 | np = inet6_sk(sk); |
129 | if (!np) | 129 | if (!np) { |
130 | return -EBADF; | 130 | err = -EBADF; |
131 | goto dst_err_out; | ||
132 | } | ||
131 | 133 | ||
132 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) | 134 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) |
133 | fl6.flowi6_oif = np->mcast_oif; | 135 | fl6.flowi6_oif = np->mcast_oif; |
@@ -163,6 +165,9 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
163 | } | 165 | } |
164 | release_sock(sk); | 166 | release_sock(sk); |
165 | 167 | ||
168 | dst_err_out: | ||
169 | dst_release(dst); | ||
170 | |||
166 | if (err) | 171 | if (err) |
167 | return err; | 172 | return err; |
168 | 173 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 49817555449e..e3a224b97905 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1986,9 +1986,18 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) | |||
1986 | if (!(gwa_type & IPV6_ADDR_UNICAST)) | 1986 | if (!(gwa_type & IPV6_ADDR_UNICAST)) |
1987 | goto out; | 1987 | goto out; |
1988 | 1988 | ||
1989 | if (cfg->fc_table) | 1989 | if (cfg->fc_table) { |
1990 | grt = ip6_nh_lookup_table(net, cfg, gw_addr); | 1990 | grt = ip6_nh_lookup_table(net, cfg, gw_addr); |
1991 | 1991 | ||
1992 | if (grt) { | ||
1993 | if (grt->rt6i_flags & RTF_GATEWAY || | ||
1994 | (dev && dev != grt->dst.dev)) { | ||
1995 | ip6_rt_put(grt); | ||
1996 | grt = NULL; | ||
1997 | } | ||
1998 | } | ||
1999 | } | ||
2000 | |||
1992 | if (!grt) | 2001 | if (!grt) |
1993 | grt = rt6_lookup(net, gw_addr, NULL, | 2002 | grt = rt6_lookup(net, gw_addr, NULL, |
1994 | cfg->fc_ifindex, 1); | 2003 | cfg->fc_ifindex, 1); |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 0eaab1fa6be5..b5789562aded 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -21,8 +21,10 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
21 | return xfrm6_extract_header(skb); | 21 | return xfrm6_extract_header(skb); |
22 | } | 22 | } |
23 | 23 | ||
24 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) | 24 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, |
25 | struct ip6_tnl *t) | ||
25 | { | 26 | { |
27 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; | ||
26 | XFRM_SPI_SKB_CB(skb)->family = AF_INET6; | 28 | XFRM_SPI_SKB_CB(skb)->family = AF_INET6; |
27 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); | 29 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); |
28 | return xfrm_input(skb, nexthdr, spi, 0); | 30 | return xfrm_input(skb, nexthdr, spi, 0); |
@@ -48,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) | |||
48 | return -1; | 50 | return -1; |
49 | } | 51 | } |
50 | 52 | ||
51 | int xfrm6_rcv(struct sk_buff *skb) | 53 | int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t) |
52 | { | 54 | { |
53 | return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], | 55 | return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], |
54 | 0); | 56 | 0, t); |
55 | } | 57 | } |
56 | EXPORT_SYMBOL(xfrm6_rcv); | 58 | EXPORT_SYMBOL(xfrm6_rcv_tnl); |
57 | 59 | ||
60 | int xfrm6_rcv(struct sk_buff *skb) | ||
61 | { | ||
62 | return xfrm6_rcv_tnl(skb, NULL); | ||
63 | } | ||
64 | EXPORT_SYMBOL(xfrm6_rcv); | ||
58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | 65 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, |
59 | xfrm_address_t *saddr, u8 proto) | 66 | xfrm_address_t *saddr, u8 proto) |
60 | { | 67 | { |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 6cc97003e4a9..70a86adad875 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, | |||
36 | int err; | 36 | int err; |
37 | 37 | ||
38 | memset(&fl6, 0, sizeof(fl6)); | 38 | memset(&fl6, 0, sizeof(fl6)); |
39 | fl6.flowi6_oif = oif; | 39 | fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif); |
40 | fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; | 40 | fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; |
41 | memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); | 41 | memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); |
42 | if (saddr) | 42 | if (saddr) |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 5743044cd660..e1c0bbe7996c 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -236,7 +236,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) | |||
236 | __be32 spi; | 236 | __be32 spi; |
237 | 237 | ||
238 | spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); | 238 | spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); |
239 | return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi); | 239 | return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL); |
240 | } | 240 | } |
241 | 241 | ||
242 | static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 242 | static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 8d2f7c9b491d..ccc244406fb9 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -832,7 +832,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
832 | struct sock *sk = sock->sk; | 832 | struct sock *sk = sock->sk; |
833 | struct irda_sock *new, *self = irda_sk(sk); | 833 | struct irda_sock *new, *self = irda_sk(sk); |
834 | struct sock *newsk; | 834 | struct sock *newsk; |
835 | struct sk_buff *skb; | 835 | struct sk_buff *skb = NULL; |
836 | int err; | 836 | int err; |
837 | 837 | ||
838 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | 838 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); |
@@ -900,7 +900,6 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
900 | err = -EPERM; /* value does not seem to make sense. -arnd */ | 900 | err = -EPERM; /* value does not seem to make sense. -arnd */ |
901 | if (!new->tsap) { | 901 | if (!new->tsap) { |
902 | pr_debug("%s(), dup failed!\n", __func__); | 902 | pr_debug("%s(), dup failed!\n", __func__); |
903 | kfree_skb(skb); | ||
904 | goto out; | 903 | goto out; |
905 | } | 904 | } |
906 | 905 | ||
@@ -919,7 +918,6 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
919 | /* Clean up the original one to keep it in listen state */ | 918 | /* Clean up the original one to keep it in listen state */ |
920 | irttp_listen(self->tsap); | 919 | irttp_listen(self->tsap); |
921 | 920 | ||
922 | kfree_skb(skb); | ||
923 | sk->sk_ack_backlog--; | 921 | sk->sk_ack_backlog--; |
924 | 922 | ||
925 | newsock->state = SS_CONNECTED; | 923 | newsock->state = SS_CONNECTED; |
@@ -927,6 +925,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
927 | irda_connect_response(new); | 925 | irda_connect_response(new); |
928 | err = 0; | 926 | err = 0; |
929 | out: | 927 | out: |
928 | kfree_skb(skb); | ||
930 | release_sock(sk); | 929 | release_sock(sk); |
931 | return err; | 930 | return err; |
932 | } | 931 | } |
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index cb39e05b166c..411693288648 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/socket.h> | 13 | #include <linux/socket.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/syscalls.h> | ||
16 | #include <net/kcm.h> | 17 | #include <net/kcm.h> |
17 | #include <net/netns/generic.h> | 18 | #include <net/netns/generic.h> |
18 | #include <net/sock.h> | 19 | #include <net/sock.h> |
@@ -2029,7 +2030,7 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
2029 | if (copy_to_user((void __user *)arg, &info, | 2030 | if (copy_to_user((void __user *)arg, &info, |
2030 | sizeof(info))) { | 2031 | sizeof(info))) { |
2031 | err = -EFAULT; | 2032 | err = -EFAULT; |
2032 | sock_release(newsock); | 2033 | sys_close(info.fd); |
2033 | } | 2034 | } |
2034 | } | 2035 | } |
2035 | 2036 | ||
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 1e40dacaa137..a2ed3bda4ddc 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1855,6 +1855,9 @@ static __net_exit void l2tp_exit_net(struct net *net) | |||
1855 | (void)l2tp_tunnel_delete(tunnel); | 1855 | (void)l2tp_tunnel_delete(tunnel); |
1856 | } | 1856 | } |
1857 | rcu_read_unlock_bh(); | 1857 | rcu_read_unlock_bh(); |
1858 | |||
1859 | flush_workqueue(l2tp_wq); | ||
1860 | rcu_barrier(); | ||
1858 | } | 1861 | } |
1859 | 1862 | ||
1860 | static struct pernet_operations l2tp_net_ops = { | 1863 | static struct pernet_operations l2tp_net_ops = { |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a9aff6079c42..afa94687d5e1 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -261,10 +261,16 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, | |||
261 | .timeout = timeout, | 261 | .timeout = timeout, |
262 | .ssn = start_seq_num, | 262 | .ssn = start_seq_num, |
263 | }; | 263 | }; |
264 | |||
265 | int i, ret = -EOPNOTSUPP; | 264 | int i, ret = -EOPNOTSUPP; |
266 | u16 status = WLAN_STATUS_REQUEST_DECLINED; | 265 | u16 status = WLAN_STATUS_REQUEST_DECLINED; |
267 | 266 | ||
267 | if (tid >= IEEE80211_FIRST_TSPEC_TSID) { | ||
268 | ht_dbg(sta->sdata, | ||
269 | "STA %pM requests BA session on unsupported tid %d\n", | ||
270 | sta->sta.addr, tid); | ||
271 | goto end_no_lock; | ||
272 | } | ||
273 | |||
268 | if (!sta->sta.ht_cap.ht_supported) { | 274 | if (!sta->sta.ht_cap.ht_supported) { |
269 | ht_dbg(sta->sdata, | 275 | ht_dbg(sta->sdata, |
270 | "STA %pM erroneously requests BA session on tid %d w/o QoS\n", | 276 | "STA %pM erroneously requests BA session on tid %d w/o QoS\n", |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 5650c46bf91a..45319cc01121 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -584,6 +584,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
584 | ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) | 584 | ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) |
585 | return -EINVAL; | 585 | return -EINVAL; |
586 | 586 | ||
587 | if (WARN_ON(tid >= IEEE80211_FIRST_TSPEC_TSID)) | ||
588 | return -EINVAL; | ||
589 | |||
587 | ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", | 590 | ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", |
588 | pubsta->addr, tid); | 591 | pubsta->addr, tid); |
589 | 592 | ||
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 8f9c3bde835f..faccef977670 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -746,6 +746,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
746 | sta = next_hop_deref_protected(mpath); | 746 | sta = next_hop_deref_protected(mpath); |
747 | if (mpath->flags & MESH_PATH_ACTIVE && | 747 | if (mpath->flags & MESH_PATH_ACTIVE && |
748 | ether_addr_equal(ta, sta->sta.addr) && | 748 | ether_addr_equal(ta, sta->sta.addr) && |
749 | !(mpath->flags & MESH_PATH_FIXED) && | ||
749 | (!(mpath->flags & MESH_PATH_SN_VALID) || | 750 | (!(mpath->flags & MESH_PATH_SN_VALID) || |
750 | SN_GT(target_sn, mpath->sn) || target_sn == 0)) { | 751 | SN_GT(target_sn, mpath->sn) || target_sn == 0)) { |
751 | mpath->flags &= ~MESH_PATH_ACTIVE; | 752 | mpath->flags &= ~MESH_PATH_ACTIVE; |
@@ -1012,7 +1013,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
1012 | goto enddiscovery; | 1013 | goto enddiscovery; |
1013 | 1014 | ||
1014 | spin_lock_bh(&mpath->state_lock); | 1015 | spin_lock_bh(&mpath->state_lock); |
1015 | if (mpath->flags & MESH_PATH_DELETED) { | 1016 | if (mpath->flags & (MESH_PATH_DELETED | MESH_PATH_FIXED)) { |
1016 | spin_unlock_bh(&mpath->state_lock); | 1017 | spin_unlock_bh(&mpath->state_lock); |
1017 | goto enddiscovery; | 1018 | goto enddiscovery; |
1018 | } | 1019 | } |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 6db2ddfa0695..f0e6175a9821 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -826,7 +826,7 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) | |||
826 | mpath->metric = 0; | 826 | mpath->metric = 0; |
827 | mpath->hop_count = 0; | 827 | mpath->hop_count = 0; |
828 | mpath->exp_time = 0; | 828 | mpath->exp_time = 0; |
829 | mpath->flags |= MESH_PATH_FIXED; | 829 | mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; |
830 | mesh_path_activate(mpath); | 830 | mesh_path_activate(mpath); |
831 | spin_unlock_bh(&mpath->state_lock); | 831 | spin_unlock_bh(&mpath->state_lock); |
832 | mesh_path_tx_pending(mpath); | 832 | mesh_path_tx_pending(mpath); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 76b737dcc36f..aa58df80ede0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1616,7 +1616,6 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1616 | 1616 | ||
1617 | sta_info_recalc_tim(sta); | 1617 | sta_info_recalc_tim(sta); |
1618 | } else { | 1618 | } else { |
1619 | unsigned long tids = sta->txq_buffered_tids & driver_release_tids; | ||
1620 | int tid; | 1619 | int tid; |
1621 | 1620 | ||
1622 | /* | 1621 | /* |
@@ -1648,7 +1647,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1648 | for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { | 1647 | for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { |
1649 | struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); | 1648 | struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); |
1650 | 1649 | ||
1651 | if (!(tids & BIT(tid)) || txqi->tin.backlog_packets) | 1650 | if (!(driver_release_tids & BIT(tid)) || |
1651 | txqi->tin.backlog_packets) | ||
1652 | continue; | 1652 | continue; |
1653 | 1653 | ||
1654 | sta_info_recalc_tim(sta); | 1654 | sta_info_recalc_tim(sta); |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index b5d28f14b9cf..afca7d103684 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -333,10 +333,11 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
333 | if (!uc.center_freq1) | 333 | if (!uc.center_freq1) |
334 | return; | 334 | return; |
335 | 335 | ||
336 | /* proceed to downgrade the chandef until usable or the same */ | 336 | /* proceed to downgrade the chandef until usable or the same as AP BW */ |
337 | while (uc.width > max_width || | 337 | while (uc.width > max_width || |
338 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, | 338 | (uc.width > sta->tdls_chandef.width && |
339 | sdata->wdev.iftype)) | 339 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, |
340 | sdata->wdev.iftype))) | ||
340 | ieee80211_chandef_downgrade(&uc); | 341 | ieee80211_chandef_downgrade(&uc); |
341 | 342 | ||
342 | if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { | 343 | if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 502396694f47..18b285e06bc8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -796,6 +796,36 @@ static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid) | |||
796 | return ret; | 796 | return ret; |
797 | } | 797 | } |
798 | 798 | ||
799 | static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, | ||
800 | struct ieee80211_vif *vif, | ||
801 | struct ieee80211_sta *pubsta, | ||
802 | struct sk_buff *skb) | ||
803 | { | ||
804 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
805 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
806 | struct ieee80211_txq *txq = NULL; | ||
807 | |||
808 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || | ||
809 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
810 | return NULL; | ||
811 | |||
812 | if (!ieee80211_is_data(hdr->frame_control)) | ||
813 | return NULL; | ||
814 | |||
815 | if (pubsta) { | ||
816 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; | ||
817 | |||
818 | txq = pubsta->txq[tid]; | ||
819 | } else if (vif) { | ||
820 | txq = vif->txq; | ||
821 | } | ||
822 | |||
823 | if (!txq) | ||
824 | return NULL; | ||
825 | |||
826 | return to_txq_info(txq); | ||
827 | } | ||
828 | |||
799 | static ieee80211_tx_result debug_noinline | 829 | static ieee80211_tx_result debug_noinline |
800 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | 830 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) |
801 | { | 831 | { |
@@ -853,7 +883,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
853 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 883 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
854 | tx->sta->tx_stats.msdu[tid]++; | 884 | tx->sta->tx_stats.msdu[tid]++; |
855 | 885 | ||
856 | if (!tx->sta->sta.txq[0]) | 886 | if (!ieee80211_get_txq(tx->local, info->control.vif, &tx->sta->sta, |
887 | tx->skb)) | ||
857 | hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); | 888 | hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); |
858 | 889 | ||
859 | return TX_CONTINUE; | 890 | return TX_CONTINUE; |
@@ -1243,36 +1274,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1243 | return TX_CONTINUE; | 1274 | return TX_CONTINUE; |
1244 | } | 1275 | } |
1245 | 1276 | ||
1246 | static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, | ||
1247 | struct ieee80211_vif *vif, | ||
1248 | struct ieee80211_sta *pubsta, | ||
1249 | struct sk_buff *skb) | ||
1250 | { | ||
1251 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1252 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1253 | struct ieee80211_txq *txq = NULL; | ||
1254 | |||
1255 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || | ||
1256 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
1257 | return NULL; | ||
1258 | |||
1259 | if (!ieee80211_is_data(hdr->frame_control)) | ||
1260 | return NULL; | ||
1261 | |||
1262 | if (pubsta) { | ||
1263 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; | ||
1264 | |||
1265 | txq = pubsta->txq[tid]; | ||
1266 | } else if (vif) { | ||
1267 | txq = vif->txq; | ||
1268 | } | ||
1269 | |||
1270 | if (!txq) | ||
1271 | return NULL; | ||
1272 | |||
1273 | return to_txq_info(txq); | ||
1274 | } | ||
1275 | |||
1276 | static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) | 1277 | static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) |
1277 | { | 1278 | { |
1278 | IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); | 1279 | IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); |
@@ -1514,8 +1515,12 @@ out: | |||
1514 | spin_unlock_bh(&fq->lock); | 1515 | spin_unlock_bh(&fq->lock); |
1515 | 1516 | ||
1516 | if (skb && skb_has_frag_list(skb) && | 1517 | if (skb && skb_has_frag_list(skb) && |
1517 | !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) | 1518 | !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) { |
1518 | skb_linearize(skb); | 1519 | if (skb_linearize(skb)) { |
1520 | ieee80211_free_txskb(&local->hw, skb); | ||
1521 | return NULL; | ||
1522 | } | ||
1523 | } | ||
1519 | 1524 | ||
1520 | return skb; | 1525 | return skb; |
1521 | } | 1526 | } |
@@ -3264,7 +3269,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, | |||
3264 | 3269 | ||
3265 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { | 3270 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { |
3266 | *ieee80211_get_qos_ctl(hdr) = tid; | 3271 | *ieee80211_get_qos_ctl(hdr) = tid; |
3267 | if (!sta->sta.txq[0]) | 3272 | if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb)) |
3268 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); | 3273 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); |
3269 | } else { | 3274 | } else { |
3270 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 3275 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index dd2c43abf9e2..9934b0c93c1e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, | |||
1035 | if (IS_ERR(ct)) | 1035 | if (IS_ERR(ct)) |
1036 | return (struct nf_conntrack_tuple_hash *)ct; | 1036 | return (struct nf_conntrack_tuple_hash *)ct; |
1037 | 1037 | ||
1038 | if (tmpl && nfct_synproxy(tmpl)) { | 1038 | if (!nf_ct_add_synproxy(ct, tmpl)) { |
1039 | nfct_seqadj_ext_add(ct); | 1039 | nf_conntrack_free(ct); |
1040 | nfct_synproxy_ext_add(ct); | 1040 | return ERR_PTR(-ENOMEM); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; | 1043 | timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index de31818417b8..ecee105bbada 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
@@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
441 | ct->status |= IPS_DST_NAT; | 441 | ct->status |= IPS_DST_NAT; |
442 | 442 | ||
443 | if (nfct_help(ct)) | 443 | if (nfct_help(ct)) |
444 | nfct_seqadj_ext_add(ct); | 444 | if (!nfct_seqadj_ext_add(ct)) |
445 | return NF_DROP; | ||
445 | } | 446 | } |
446 | 447 | ||
447 | if (maniptype == NF_NAT_MANIP_SRC) { | 448 | if (maniptype == NF_NAT_MANIP_SRC) { |
@@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct, | |||
807 | if (err < 0) | 808 | if (err < 0) |
808 | return err; | 809 | return err; |
809 | 810 | ||
810 | return nf_nat_setup_info(ct, &range, manip); | 811 | return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0; |
811 | } | 812 | } |
812 | #else | 813 | #else |
813 | static int | 814 | static int |
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c index 5eefe4a355c6..75d696f11045 100644 --- a/net/netfilter/nf_tables_netdev.c +++ b/net/netfilter/nf_tables_netdev.c | |||
@@ -30,7 +30,6 @@ nft_netdev_set_pktinfo_ipv4(struct nft_pktinfo *pkt, | |||
30 | if (!iph) | 30 | if (!iph) |
31 | return; | 31 | return; |
32 | 32 | ||
33 | iph = ip_hdr(skb); | ||
34 | if (iph->ihl < 5 || iph->version != 4) | 33 | if (iph->ihl < 5 || iph->version != 4) |
35 | return; | 34 | return; |
36 | 35 | ||
diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c index 39eb1cc62e91..fa24a5b398b1 100644 --- a/net/netfilter/nf_tables_trace.c +++ b/net/netfilter/nf_tables_trace.c | |||
@@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_traceinfo *info) | |||
237 | break; | 237 | break; |
238 | case NFT_TRACETYPE_POLICY: | 238 | case NFT_TRACETYPE_POLICY: |
239 | if (nla_put_be32(skb, NFTA_TRACE_POLICY, | 239 | if (nla_put_be32(skb, NFTA_TRACE_POLICY, |
240 | info->basechain->policy)) | 240 | htonl(info->basechain->policy))) |
241 | goto nla_put_failure; | 241 | goto nla_put_failure; |
242 | break; | 242 | break; |
243 | } | 243 | } |
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 70eb2f6a3b01..d44d89b56127 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c | |||
@@ -343,12 +343,12 @@ static int nfnl_acct_del(struct net *net, struct sock *nfnl, | |||
343 | struct sk_buff *skb, const struct nlmsghdr *nlh, | 343 | struct sk_buff *skb, const struct nlmsghdr *nlh, |
344 | const struct nlattr * const tb[]) | 344 | const struct nlattr * const tb[]) |
345 | { | 345 | { |
346 | char *acct_name; | 346 | struct nf_acct *cur, *tmp; |
347 | struct nf_acct *cur; | ||
348 | int ret = -ENOENT; | 347 | int ret = -ENOENT; |
348 | char *acct_name; | ||
349 | 349 | ||
350 | if (!tb[NFACCT_NAME]) { | 350 | if (!tb[NFACCT_NAME]) { |
351 | list_for_each_entry(cur, &net->nfnl_acct_list, head) | 351 | list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head) |
352 | nfnl_acct_try_del(cur); | 352 | nfnl_acct_try_del(cur); |
353 | 353 | ||
354 | return 0; | 354 | return 0; |
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 68216cdc7083..139e0867e56e 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c | |||
@@ -98,31 +98,28 @@ static int cttimeout_new_timeout(struct net *net, struct sock *ctnl, | |||
98 | break; | 98 | break; |
99 | } | 99 | } |
100 | 100 | ||
101 | l4proto = nf_ct_l4proto_find_get(l3num, l4num); | ||
102 | |||
103 | /* This protocol is not supportted, skip. */ | ||
104 | if (l4proto->l4proto != l4num) { | ||
105 | ret = -EOPNOTSUPP; | ||
106 | goto err_proto_put; | ||
107 | } | ||
108 | |||
109 | if (matching) { | 101 | if (matching) { |
110 | if (nlh->nlmsg_flags & NLM_F_REPLACE) { | 102 | if (nlh->nlmsg_flags & NLM_F_REPLACE) { |
111 | /* You cannot replace one timeout policy by another of | 103 | /* You cannot replace one timeout policy by another of |
112 | * different kind, sorry. | 104 | * different kind, sorry. |
113 | */ | 105 | */ |
114 | if (matching->l3num != l3num || | 106 | if (matching->l3num != l3num || |
115 | matching->l4proto->l4proto != l4num) { | 107 | matching->l4proto->l4proto != l4num) |
116 | ret = -EINVAL; | 108 | return -EINVAL; |
117 | goto err_proto_put; | 109 | |
118 | } | 110 | return ctnl_timeout_parse_policy(&matching->data, |
119 | 111 | matching->l4proto, net, | |
120 | ret = ctnl_timeout_parse_policy(&matching->data, | 112 | cda[CTA_TIMEOUT_DATA]); |
121 | l4proto, net, | ||
122 | cda[CTA_TIMEOUT_DATA]); | ||
123 | return ret; | ||
124 | } | 113 | } |
125 | ret = -EBUSY; | 114 | |
115 | return -EBUSY; | ||
116 | } | ||
117 | |||
118 | l4proto = nf_ct_l4proto_find_get(l3num, l4num); | ||
119 | |||
120 | /* This protocol is not supportted, skip. */ | ||
121 | if (l4proto->l4proto != l4num) { | ||
122 | ret = -EOPNOTSUPP; | ||
126 | goto err_proto_put; | 123 | goto err_proto_put; |
127 | } | 124 | } |
128 | 125 | ||
@@ -305,7 +302,16 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout) | |||
305 | const struct hlist_nulls_node *nn; | 302 | const struct hlist_nulls_node *nn; |
306 | unsigned int last_hsize; | 303 | unsigned int last_hsize; |
307 | spinlock_t *lock; | 304 | spinlock_t *lock; |
308 | int i; | 305 | int i, cpu; |
306 | |||
307 | for_each_possible_cpu(cpu) { | ||
308 | struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); | ||
309 | |||
310 | spin_lock_bh(&pcpu->lock); | ||
311 | hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode) | ||
312 | untimeout(h, timeout); | ||
313 | spin_unlock_bh(&pcpu->lock); | ||
314 | } | ||
309 | 315 | ||
310 | local_bh_disable(); | 316 | local_bh_disable(); |
311 | restart: | 317 | restart: |
@@ -350,12 +356,13 @@ static int cttimeout_del_timeout(struct net *net, struct sock *ctnl, | |||
350 | const struct nlmsghdr *nlh, | 356 | const struct nlmsghdr *nlh, |
351 | const struct nlattr * const cda[]) | 357 | const struct nlattr * const cda[]) |
352 | { | 358 | { |
353 | struct ctnl_timeout *cur; | 359 | struct ctnl_timeout *cur, *tmp; |
354 | int ret = -ENOENT; | 360 | int ret = -ENOENT; |
355 | char *name; | 361 | char *name; |
356 | 362 | ||
357 | if (!cda[CTA_TIMEOUT_NAME]) { | 363 | if (!cda[CTA_TIMEOUT_NAME]) { |
358 | list_for_each_entry(cur, &net->nfct_timeout_list, head) | 364 | list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, |
365 | head) | ||
359 | ctnl_timeout_try_del(net, cur); | 366 | ctnl_timeout_try_del(net, cur); |
360 | 367 | ||
361 | return 0; | 368 | return 0; |
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 2863f3493038..8a6bc7630912 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c | |||
@@ -291,10 +291,16 @@ int nft_meta_get_init(const struct nft_ctx *ctx, | |||
291 | } | 291 | } |
292 | EXPORT_SYMBOL_GPL(nft_meta_get_init); | 292 | EXPORT_SYMBOL_GPL(nft_meta_get_init); |
293 | 293 | ||
294 | static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx) | 294 | int nft_meta_set_validate(const struct nft_ctx *ctx, |
295 | const struct nft_expr *expr, | ||
296 | const struct nft_data **data) | ||
295 | { | 297 | { |
298 | struct nft_meta *priv = nft_expr_priv(expr); | ||
296 | unsigned int hooks; | 299 | unsigned int hooks; |
297 | 300 | ||
301 | if (priv->key != NFT_META_PKTTYPE) | ||
302 | return 0; | ||
303 | |||
298 | switch (ctx->afi->family) { | 304 | switch (ctx->afi->family) { |
299 | case NFPROTO_BRIDGE: | 305 | case NFPROTO_BRIDGE: |
300 | hooks = 1 << NF_BR_PRE_ROUTING; | 306 | hooks = 1 << NF_BR_PRE_ROUTING; |
@@ -308,6 +314,7 @@ static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx) | |||
308 | 314 | ||
309 | return nft_chain_validate_hooks(ctx->chain, hooks); | 315 | return nft_chain_validate_hooks(ctx->chain, hooks); |
310 | } | 316 | } |
317 | EXPORT_SYMBOL_GPL(nft_meta_set_validate); | ||
311 | 318 | ||
312 | int nft_meta_set_init(const struct nft_ctx *ctx, | 319 | int nft_meta_set_init(const struct nft_ctx *ctx, |
313 | const struct nft_expr *expr, | 320 | const struct nft_expr *expr, |
@@ -327,15 +334,16 @@ int nft_meta_set_init(const struct nft_ctx *ctx, | |||
327 | len = sizeof(u8); | 334 | len = sizeof(u8); |
328 | break; | 335 | break; |
329 | case NFT_META_PKTTYPE: | 336 | case NFT_META_PKTTYPE: |
330 | err = nft_meta_set_init_pkttype(ctx); | ||
331 | if (err) | ||
332 | return err; | ||
333 | len = sizeof(u8); | 337 | len = sizeof(u8); |
334 | break; | 338 | break; |
335 | default: | 339 | default: |
336 | return -EOPNOTSUPP; | 340 | return -EOPNOTSUPP; |
337 | } | 341 | } |
338 | 342 | ||
343 | err = nft_meta_set_validate(ctx, expr, NULL); | ||
344 | if (err < 0) | ||
345 | return err; | ||
346 | |||
339 | priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); | 347 | priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); |
340 | err = nft_validate_register_load(priv->sreg, len); | 348 | err = nft_validate_register_load(priv->sreg, len); |
341 | if (err < 0) | 349 | if (err < 0) |
@@ -407,6 +415,7 @@ static const struct nft_expr_ops nft_meta_set_ops = { | |||
407 | .init = nft_meta_set_init, | 415 | .init = nft_meta_set_init, |
408 | .destroy = nft_meta_set_destroy, | 416 | .destroy = nft_meta_set_destroy, |
409 | .dump = nft_meta_set_dump, | 417 | .dump = nft_meta_set_dump, |
418 | .validate = nft_meta_set_validate, | ||
410 | }; | 419 | }; |
411 | 420 | ||
412 | static const struct nft_expr_ops * | 421 | static const struct nft_expr_ops * |
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c index 0522fc9bfb0a..c64de3f7379d 100644 --- a/net/netfilter/nft_reject.c +++ b/net/netfilter/nft_reject.c | |||
@@ -26,11 +26,27 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { | |||
26 | }; | 26 | }; |
27 | EXPORT_SYMBOL_GPL(nft_reject_policy); | 27 | EXPORT_SYMBOL_GPL(nft_reject_policy); |
28 | 28 | ||
29 | int nft_reject_validate(const struct nft_ctx *ctx, | ||
30 | const struct nft_expr *expr, | ||
31 | const struct nft_data **data) | ||
32 | { | ||
33 | return nft_chain_validate_hooks(ctx->chain, | ||
34 | (1 << NF_INET_LOCAL_IN) | | ||
35 | (1 << NF_INET_FORWARD) | | ||
36 | (1 << NF_INET_LOCAL_OUT)); | ||
37 | } | ||
38 | EXPORT_SYMBOL_GPL(nft_reject_validate); | ||
39 | |||
29 | int nft_reject_init(const struct nft_ctx *ctx, | 40 | int nft_reject_init(const struct nft_ctx *ctx, |
30 | const struct nft_expr *expr, | 41 | const struct nft_expr *expr, |
31 | const struct nlattr * const tb[]) | 42 | const struct nlattr * const tb[]) |
32 | { | 43 | { |
33 | struct nft_reject *priv = nft_expr_priv(expr); | 44 | struct nft_reject *priv = nft_expr_priv(expr); |
45 | int err; | ||
46 | |||
47 | err = nft_reject_validate(ctx, expr, NULL); | ||
48 | if (err < 0) | ||
49 | return err; | ||
34 | 50 | ||
35 | if (tb[NFTA_REJECT_TYPE] == NULL) | 51 | if (tb[NFTA_REJECT_TYPE] == NULL) |
36 | return -EINVAL; | 52 | return -EINVAL; |
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c index 759ca5248a3d..e79d9ca2ffee 100644 --- a/net/netfilter/nft_reject_inet.c +++ b/net/netfilter/nft_reject_inet.c | |||
@@ -66,7 +66,11 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx, | |||
66 | const struct nlattr * const tb[]) | 66 | const struct nlattr * const tb[]) |
67 | { | 67 | { |
68 | struct nft_reject *priv = nft_expr_priv(expr); | 68 | struct nft_reject *priv = nft_expr_priv(expr); |
69 | int icmp_code; | 69 | int icmp_code, err; |
70 | |||
71 | err = nft_reject_validate(ctx, expr, NULL); | ||
72 | if (err < 0) | ||
73 | return err; | ||
70 | 74 | ||
71 | if (tb[NFTA_REJECT_TYPE] == NULL) | 75 | if (tb[NFTA_REJECT_TYPE] == NULL) |
72 | return -EINVAL; | 76 | return -EINVAL; |
@@ -124,6 +128,7 @@ static const struct nft_expr_ops nft_reject_inet_ops = { | |||
124 | .eval = nft_reject_inet_eval, | 128 | .eval = nft_reject_inet_eval, |
125 | .init = nft_reject_inet_init, | 129 | .init = nft_reject_inet_init, |
126 | .dump = nft_reject_inet_dump, | 130 | .dump = nft_reject_inet_dump, |
131 | .validate = nft_reject_validate, | ||
127 | }; | 132 | }; |
128 | 133 | ||
129 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { | 134 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 69444d32ecda..1555fb8c68e0 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -796,27 +796,34 @@ struct sctp_hash_cmp_arg { | |||
796 | static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, | 796 | static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, |
797 | const void *ptr) | 797 | const void *ptr) |
798 | { | 798 | { |
799 | struct sctp_transport *t = (struct sctp_transport *)ptr; | ||
799 | const struct sctp_hash_cmp_arg *x = arg->key; | 800 | const struct sctp_hash_cmp_arg *x = arg->key; |
800 | const struct sctp_transport *t = ptr; | 801 | struct sctp_association *asoc; |
801 | struct sctp_association *asoc = t->asoc; | 802 | int err = 1; |
802 | const struct net *net = x->net; | ||
803 | 803 | ||
804 | if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) | 804 | if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) |
805 | return 1; | 805 | return err; |
806 | if (!net_eq(sock_net(asoc->base.sk), net)) | 806 | if (!sctp_transport_hold(t)) |
807 | return 1; | 807 | return err; |
808 | |||
809 | asoc = t->asoc; | ||
810 | if (!net_eq(sock_net(asoc->base.sk), x->net)) | ||
811 | goto out; | ||
808 | if (x->ep) { | 812 | if (x->ep) { |
809 | if (x->ep != asoc->ep) | 813 | if (x->ep != asoc->ep) |
810 | return 1; | 814 | goto out; |
811 | } else { | 815 | } else { |
812 | if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) | 816 | if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) |
813 | return 1; | 817 | goto out; |
814 | if (!sctp_bind_addr_match(&asoc->base.bind_addr, | 818 | if (!sctp_bind_addr_match(&asoc->base.bind_addr, |
815 | x->laddr, sctp_sk(asoc->base.sk))) | 819 | x->laddr, sctp_sk(asoc->base.sk))) |
816 | return 1; | 820 | goto out; |
817 | } | 821 | } |
818 | 822 | ||
819 | return 0; | 823 | err = 0; |
824 | out: | ||
825 | sctp_transport_put(t); | ||
826 | return err; | ||
820 | } | 827 | } |
821 | 828 | ||
822 | static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed) | 829 | static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed) |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 1f1682b9a6a8..31b7bc35895d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -878,7 +878,7 @@ static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, | |||
878 | struct sctp_chunk *chunk, | 878 | struct sctp_chunk *chunk, |
879 | u16 chunk_len) | 879 | u16 chunk_len) |
880 | { | 880 | { |
881 | size_t psize, pmtu; | 881 | size_t psize, pmtu, maxsize; |
882 | sctp_xmit_t retval = SCTP_XMIT_OK; | 882 | sctp_xmit_t retval = SCTP_XMIT_OK; |
883 | 883 | ||
884 | psize = packet->size; | 884 | psize = packet->size; |
@@ -906,6 +906,17 @@ static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, | |||
906 | goto out; | 906 | goto out; |
907 | } | 907 | } |
908 | 908 | ||
909 | /* Similarly, if this chunk was built before a PMTU | ||
910 | * reduction, we have to fragment it at IP level now. So | ||
911 | * if the packet already contains something, we need to | ||
912 | * flush. | ||
913 | */ | ||
914 | maxsize = pmtu - packet->overhead; | ||
915 | if (packet->auth) | ||
916 | maxsize -= WORD_ROUND(packet->auth->skb->len); | ||
917 | if (chunk_len > maxsize) | ||
918 | retval = SCTP_XMIT_PMTU_FULL; | ||
919 | |||
909 | /* It is also okay to fragment if the chunk we are | 920 | /* It is also okay to fragment if the chunk we are |
910 | * adding is a control chunk, but only if current packet | 921 | * adding is a control chunk, but only if current packet |
911 | * is not a GSO one otherwise it causes fragmentation of | 922 | * is not a GSO one otherwise it causes fragmentation of |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 1d281816f2bf..d8582028b346 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -569,9 +569,10 @@ gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) | |||
569 | struct rsc *found; | 569 | struct rsc *found; |
570 | 570 | ||
571 | memset(&rsci, 0, sizeof(rsci)); | 571 | memset(&rsci, 0, sizeof(rsci)); |
572 | rsci.handle.data = handle->data; | 572 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) |
573 | rsci.handle.len = handle->len; | 573 | return NULL; |
574 | found = rsc_lookup(cd, &rsci); | 574 | found = rsc_lookup(cd, &rsci); |
575 | rsc_free(&rsci); | ||
575 | if (!found) | 576 | if (!found) |
576 | return NULL; | 577 | return NULL; |
577 | if (cache_check(cd, &found->h, NULL)) | 578 | if (cache_check(cd, &found->h, NULL)) |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 536d0be3f61b..799cce6cbe45 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/prefetch.h> | 52 | #include <linux/prefetch.h> |
53 | #include <linux/sunrpc/addr.h> | 53 | #include <linux/sunrpc/addr.h> |
54 | #include <linux/sunrpc/svc_rdma.h> | ||
54 | #include <asm/bitops.h> | 55 | #include <asm/bitops.h> |
55 | #include <linux/module.h> /* try_module_get()/module_put() */ | 56 | #include <linux/module.h> /* try_module_get()/module_put() */ |
56 | 57 | ||
@@ -923,7 +924,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) | |||
923 | } | 924 | } |
924 | 925 | ||
925 | INIT_LIST_HEAD(&buf->rb_recv_bufs); | 926 | INIT_LIST_HEAD(&buf->rb_recv_bufs); |
926 | for (i = 0; i < buf->rb_max_requests; i++) { | 927 | for (i = 0; i < buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; i++) { |
927 | struct rpcrdma_rep *rep; | 928 | struct rpcrdma_rep *rep; |
928 | 929 | ||
929 | rep = rpcrdma_create_rep(r_xprt); | 930 | rep = rpcrdma_create_rep(r_xprt); |
@@ -1018,6 +1019,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1018 | rep = rpcrdma_buffer_get_rep_locked(buf); | 1019 | rep = rpcrdma_buffer_get_rep_locked(buf); |
1019 | rpcrdma_destroy_rep(ia, rep); | 1020 | rpcrdma_destroy_rep(ia, rep); |
1020 | } | 1021 | } |
1022 | buf->rb_send_count = 0; | ||
1021 | 1023 | ||
1022 | spin_lock(&buf->rb_reqslock); | 1024 | spin_lock(&buf->rb_reqslock); |
1023 | while (!list_empty(&buf->rb_allreqs)) { | 1025 | while (!list_empty(&buf->rb_allreqs)) { |
@@ -1032,6 +1034,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1032 | spin_lock(&buf->rb_reqslock); | 1034 | spin_lock(&buf->rb_reqslock); |
1033 | } | 1035 | } |
1034 | spin_unlock(&buf->rb_reqslock); | 1036 | spin_unlock(&buf->rb_reqslock); |
1037 | buf->rb_recv_count = 0; | ||
1035 | 1038 | ||
1036 | rpcrdma_destroy_mrs(buf); | 1039 | rpcrdma_destroy_mrs(buf); |
1037 | } | 1040 | } |
@@ -1074,8 +1077,27 @@ rpcrdma_put_mw(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw) | |||
1074 | spin_unlock(&buf->rb_mwlock); | 1077 | spin_unlock(&buf->rb_mwlock); |
1075 | } | 1078 | } |
1076 | 1079 | ||
1080 | static struct rpcrdma_rep * | ||
1081 | rpcrdma_buffer_get_rep(struct rpcrdma_buffer *buffers) | ||
1082 | { | ||
1083 | /* If an RPC previously completed without a reply (say, a | ||
1084 | * credential problem or a soft timeout occurs) then hold off | ||
1085 | * on supplying more Receive buffers until the number of new | ||
1086 | * pending RPCs catches up to the number of posted Receives. | ||
1087 | */ | ||
1088 | if (unlikely(buffers->rb_send_count < buffers->rb_recv_count)) | ||
1089 | return NULL; | ||
1090 | |||
1091 | if (unlikely(list_empty(&buffers->rb_recv_bufs))) | ||
1092 | return NULL; | ||
1093 | buffers->rb_recv_count++; | ||
1094 | return rpcrdma_buffer_get_rep_locked(buffers); | ||
1095 | } | ||
1096 | |||
1077 | /* | 1097 | /* |
1078 | * Get a set of request/reply buffers. | 1098 | * Get a set of request/reply buffers. |
1099 | * | ||
1100 | * Reply buffer (if available) is attached to send buffer upon return. | ||
1079 | */ | 1101 | */ |
1080 | struct rpcrdma_req * | 1102 | struct rpcrdma_req * |
1081 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | 1103 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) |
@@ -1085,21 +1107,15 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | |||
1085 | spin_lock(&buffers->rb_lock); | 1107 | spin_lock(&buffers->rb_lock); |
1086 | if (list_empty(&buffers->rb_send_bufs)) | 1108 | if (list_empty(&buffers->rb_send_bufs)) |
1087 | goto out_reqbuf; | 1109 | goto out_reqbuf; |
1110 | buffers->rb_send_count++; | ||
1088 | req = rpcrdma_buffer_get_req_locked(buffers); | 1111 | req = rpcrdma_buffer_get_req_locked(buffers); |
1089 | if (list_empty(&buffers->rb_recv_bufs)) | 1112 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1090 | goto out_repbuf; | ||
1091 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1092 | spin_unlock(&buffers->rb_lock); | 1113 | spin_unlock(&buffers->rb_lock); |
1093 | return req; | 1114 | return req; |
1094 | 1115 | ||
1095 | out_reqbuf: | 1116 | out_reqbuf: |
1096 | spin_unlock(&buffers->rb_lock); | 1117 | spin_unlock(&buffers->rb_lock); |
1097 | pr_warn("rpcrdma: out of request buffers (%p)\n", buffers); | 1118 | pr_warn("RPC: %s: out of request buffers\n", __func__); |
1098 | return NULL; | ||
1099 | out_repbuf: | ||
1100 | list_add(&req->rl_free, &buffers->rb_send_bufs); | ||
1101 | spin_unlock(&buffers->rb_lock); | ||
1102 | pr_warn("rpcrdma: out of reply buffers (%p)\n", buffers); | ||
1103 | return NULL; | 1119 | return NULL; |
1104 | } | 1120 | } |
1105 | 1121 | ||
@@ -1117,9 +1133,12 @@ rpcrdma_buffer_put(struct rpcrdma_req *req) | |||
1117 | req->rl_reply = NULL; | 1133 | req->rl_reply = NULL; |
1118 | 1134 | ||
1119 | spin_lock(&buffers->rb_lock); | 1135 | spin_lock(&buffers->rb_lock); |
1136 | buffers->rb_send_count--; | ||
1120 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); | 1137 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); |
1121 | if (rep) | 1138 | if (rep) { |
1139 | buffers->rb_recv_count--; | ||
1122 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1140 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1141 | } | ||
1123 | spin_unlock(&buffers->rb_lock); | 1142 | spin_unlock(&buffers->rb_lock); |
1124 | } | 1143 | } |
1125 | 1144 | ||
@@ -1133,8 +1152,7 @@ rpcrdma_recv_buffer_get(struct rpcrdma_req *req) | |||
1133 | struct rpcrdma_buffer *buffers = req->rl_buffer; | 1152 | struct rpcrdma_buffer *buffers = req->rl_buffer; |
1134 | 1153 | ||
1135 | spin_lock(&buffers->rb_lock); | 1154 | spin_lock(&buffers->rb_lock); |
1136 | if (!list_empty(&buffers->rb_recv_bufs)) | 1155 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1137 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1138 | spin_unlock(&buffers->rb_lock); | 1156 | spin_unlock(&buffers->rb_lock); |
1139 | } | 1157 | } |
1140 | 1158 | ||
@@ -1148,6 +1166,7 @@ rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep) | |||
1148 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; | 1166 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; |
1149 | 1167 | ||
1150 | spin_lock(&buffers->rb_lock); | 1168 | spin_lock(&buffers->rb_lock); |
1169 | buffers->rb_recv_count--; | ||
1151 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1170 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1152 | spin_unlock(&buffers->rb_lock); | 1171 | spin_unlock(&buffers->rb_lock); |
1153 | } | 1172 | } |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 670fad57153a..a71b0f5897d8 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -321,6 +321,7 @@ struct rpcrdma_buffer { | |||
321 | char *rb_pool; | 321 | char *rb_pool; |
322 | 322 | ||
323 | spinlock_t rb_lock; /* protect buf lists */ | 323 | spinlock_t rb_lock; /* protect buf lists */ |
324 | int rb_send_count, rb_recv_count; | ||
324 | struct list_head rb_send_bufs; | 325 | struct list_head rb_send_bufs; |
325 | struct list_head rb_recv_bufs; | 326 | struct list_head rb_recv_bufs; |
326 | u32 rb_max_requests; | 327 | u32 rb_max_requests; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 8ede3bc52481..bf168838a029 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1074,7 +1074,7 @@ static void xs_udp_data_receive(struct sock_xprt *transport) | |||
1074 | skb = skb_recv_datagram(sk, 0, 1, &err); | 1074 | skb = skb_recv_datagram(sk, 0, 1, &err); |
1075 | if (skb != NULL) { | 1075 | if (skb != NULL) { |
1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); | 1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); |
1077 | skb_free_datagram(sk, skb); | 1077 | skb_free_datagram_locked(sk, skb); |
1078 | continue; | 1078 | continue; |
1079 | } | 1079 | } |
1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) | 1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 6b626a64b517..a04fe9be1c60 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -62,6 +62,8 @@ static void publ_to_item(struct distr_item *i, struct publication *p) | |||
62 | 62 | ||
63 | /** | 63 | /** |
64 | * named_prepare_buf - allocate & initialize a publication message | 64 | * named_prepare_buf - allocate & initialize a publication message |
65 | * | ||
66 | * The buffer returned is of size INT_H_SIZE + payload size | ||
65 | */ | 67 | */ |
66 | static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size, | 68 | static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size, |
67 | u32 dest) | 69 | u32 dest) |
@@ -141,9 +143,9 @@ static void named_distribute(struct net *net, struct sk_buff_head *list, | |||
141 | struct publication *publ; | 143 | struct publication *publ; |
142 | struct sk_buff *skb = NULL; | 144 | struct sk_buff *skb = NULL; |
143 | struct distr_item *item = NULL; | 145 | struct distr_item *item = NULL; |
144 | uint msg_dsz = (tipc_node_get_mtu(net, dnode, 0) / ITEM_SIZE) * | 146 | u32 msg_dsz = ((tipc_node_get_mtu(net, dnode, 0) - INT_H_SIZE) / |
145 | ITEM_SIZE; | 147 | ITEM_SIZE) * ITEM_SIZE; |
146 | uint msg_rem = msg_dsz; | 148 | u32 msg_rem = msg_dsz; |
147 | 149 | ||
148 | list_for_each_entry(publ, pls, local_list) { | 150 | list_for_each_entry(publ, pls, local_list) { |
149 | /* Prepare next buffer: */ | 151 | /* Prepare next buffer: */ |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f1dffe84f0d5..8309687a56b0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -661,11 +661,11 @@ static int unix_set_peek_off(struct sock *sk, int val) | |||
661 | { | 661 | { |
662 | struct unix_sock *u = unix_sk(sk); | 662 | struct unix_sock *u = unix_sk(sk); |
663 | 663 | ||
664 | if (mutex_lock_interruptible(&u->readlock)) | 664 | if (mutex_lock_interruptible(&u->iolock)) |
665 | return -EINTR; | 665 | return -EINTR; |
666 | 666 | ||
667 | sk->sk_peek_off = val; | 667 | sk->sk_peek_off = val; |
668 | mutex_unlock(&u->readlock); | 668 | mutex_unlock(&u->iolock); |
669 | 669 | ||
670 | return 0; | 670 | return 0; |
671 | } | 671 | } |
@@ -779,7 +779,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
779 | spin_lock_init(&u->lock); | 779 | spin_lock_init(&u->lock); |
780 | atomic_long_set(&u->inflight, 0); | 780 | atomic_long_set(&u->inflight, 0); |
781 | INIT_LIST_HEAD(&u->link); | 781 | INIT_LIST_HEAD(&u->link); |
782 | mutex_init(&u->readlock); /* single task reading lock */ | 782 | mutex_init(&u->iolock); /* single task reading lock */ |
783 | mutex_init(&u->bindlock); /* single task binding lock */ | ||
783 | init_waitqueue_head(&u->peer_wait); | 784 | init_waitqueue_head(&u->peer_wait); |
784 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); | 785 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); |
785 | unix_insert_socket(unix_sockets_unbound(sk), sk); | 786 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
@@ -848,7 +849,7 @@ static int unix_autobind(struct socket *sock) | |||
848 | int err; | 849 | int err; |
849 | unsigned int retries = 0; | 850 | unsigned int retries = 0; |
850 | 851 | ||
851 | err = mutex_lock_interruptible(&u->readlock); | 852 | err = mutex_lock_interruptible(&u->bindlock); |
852 | if (err) | 853 | if (err) |
853 | return err; | 854 | return err; |
854 | 855 | ||
@@ -895,7 +896,7 @@ retry: | |||
895 | spin_unlock(&unix_table_lock); | 896 | spin_unlock(&unix_table_lock); |
896 | err = 0; | 897 | err = 0; |
897 | 898 | ||
898 | out: mutex_unlock(&u->readlock); | 899 | out: mutex_unlock(&u->bindlock); |
899 | return err; | 900 | return err; |
900 | } | 901 | } |
901 | 902 | ||
@@ -954,20 +955,32 @@ fail: | |||
954 | return NULL; | 955 | return NULL; |
955 | } | 956 | } |
956 | 957 | ||
957 | static int unix_mknod(struct dentry *dentry, const struct path *path, umode_t mode, | 958 | static int unix_mknod(const char *sun_path, umode_t mode, struct path *res) |
958 | struct path *res) | ||
959 | { | 959 | { |
960 | int err; | 960 | struct dentry *dentry; |
961 | struct path path; | ||
962 | int err = 0; | ||
963 | /* | ||
964 | * Get the parent directory, calculate the hash for last | ||
965 | * component. | ||
966 | */ | ||
967 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
968 | err = PTR_ERR(dentry); | ||
969 | if (IS_ERR(dentry)) | ||
970 | return err; | ||
961 | 971 | ||
962 | err = security_path_mknod(path, dentry, mode, 0); | 972 | /* |
973 | * All right, let's create it. | ||
974 | */ | ||
975 | err = security_path_mknod(&path, dentry, mode, 0); | ||
963 | if (!err) { | 976 | if (!err) { |
964 | err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0); | 977 | err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0); |
965 | if (!err) { | 978 | if (!err) { |
966 | res->mnt = mntget(path->mnt); | 979 | res->mnt = mntget(path.mnt); |
967 | res->dentry = dget(dentry); | 980 | res->dentry = dget(dentry); |
968 | } | 981 | } |
969 | } | 982 | } |
970 | 983 | done_path_create(&path, dentry); | |
971 | return err; | 984 | return err; |
972 | } | 985 | } |
973 | 986 | ||
@@ -978,12 +991,10 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
978 | struct unix_sock *u = unix_sk(sk); | 991 | struct unix_sock *u = unix_sk(sk); |
979 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; | 992 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; |
980 | char *sun_path = sunaddr->sun_path; | 993 | char *sun_path = sunaddr->sun_path; |
981 | int err, name_err; | 994 | int err; |
982 | unsigned int hash; | 995 | unsigned int hash; |
983 | struct unix_address *addr; | 996 | struct unix_address *addr; |
984 | struct hlist_head *list; | 997 | struct hlist_head *list; |
985 | struct path path; | ||
986 | struct dentry *dentry; | ||
987 | 998 | ||
988 | err = -EINVAL; | 999 | err = -EINVAL; |
989 | if (sunaddr->sun_family != AF_UNIX) | 1000 | if (sunaddr->sun_family != AF_UNIX) |
@@ -999,34 +1010,14 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
999 | goto out; | 1010 | goto out; |
1000 | addr_len = err; | 1011 | addr_len = err; |
1001 | 1012 | ||
1002 | name_err = 0; | 1013 | err = mutex_lock_interruptible(&u->bindlock); |
1003 | dentry = NULL; | ||
1004 | if (sun_path[0]) { | ||
1005 | /* Get the parent directory, calculate the hash for last | ||
1006 | * component. | ||
1007 | */ | ||
1008 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
1009 | |||
1010 | if (IS_ERR(dentry)) { | ||
1011 | /* delay report until after 'already bound' check */ | ||
1012 | name_err = PTR_ERR(dentry); | ||
1013 | dentry = NULL; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | err = mutex_lock_interruptible(&u->readlock); | ||
1018 | if (err) | 1014 | if (err) |
1019 | goto out_path; | 1015 | goto out; |
1020 | 1016 | ||
1021 | err = -EINVAL; | 1017 | err = -EINVAL; |
1022 | if (u->addr) | 1018 | if (u->addr) |
1023 | goto out_up; | 1019 | goto out_up; |
1024 | 1020 | ||
1025 | if (name_err) { | ||
1026 | err = name_err == -EEXIST ? -EADDRINUSE : name_err; | ||
1027 | goto out_up; | ||
1028 | } | ||
1029 | |||
1030 | err = -ENOMEM; | 1021 | err = -ENOMEM; |
1031 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); | 1022 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); |
1032 | if (!addr) | 1023 | if (!addr) |
@@ -1037,11 +1028,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1037 | addr->hash = hash ^ sk->sk_type; | 1028 | addr->hash = hash ^ sk->sk_type; |
1038 | atomic_set(&addr->refcnt, 1); | 1029 | atomic_set(&addr->refcnt, 1); |
1039 | 1030 | ||
1040 | if (dentry) { | 1031 | if (sun_path[0]) { |
1041 | struct path u_path; | 1032 | struct path path; |
1042 | umode_t mode = S_IFSOCK | | 1033 | umode_t mode = S_IFSOCK | |
1043 | (SOCK_INODE(sock)->i_mode & ~current_umask()); | 1034 | (SOCK_INODE(sock)->i_mode & ~current_umask()); |
1044 | err = unix_mknod(dentry, &path, mode, &u_path); | 1035 | err = unix_mknod(sun_path, mode, &path); |
1045 | if (err) { | 1036 | if (err) { |
1046 | if (err == -EEXIST) | 1037 | if (err == -EEXIST) |
1047 | err = -EADDRINUSE; | 1038 | err = -EADDRINUSE; |
@@ -1049,9 +1040,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1049 | goto out_up; | 1040 | goto out_up; |
1050 | } | 1041 | } |
1051 | addr->hash = UNIX_HASH_SIZE; | 1042 | addr->hash = UNIX_HASH_SIZE; |
1052 | hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); | 1043 | hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1); |
1053 | spin_lock(&unix_table_lock); | 1044 | spin_lock(&unix_table_lock); |
1054 | u->path = u_path; | 1045 | u->path = path; |
1055 | list = &unix_socket_table[hash]; | 1046 | list = &unix_socket_table[hash]; |
1056 | } else { | 1047 | } else { |
1057 | spin_lock(&unix_table_lock); | 1048 | spin_lock(&unix_table_lock); |
@@ -1073,11 +1064,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1073 | out_unlock: | 1064 | out_unlock: |
1074 | spin_unlock(&unix_table_lock); | 1065 | spin_unlock(&unix_table_lock); |
1075 | out_up: | 1066 | out_up: |
1076 | mutex_unlock(&u->readlock); | 1067 | mutex_unlock(&u->bindlock); |
1077 | out_path: | ||
1078 | if (dentry) | ||
1079 | done_path_create(&path, dentry); | ||
1080 | |||
1081 | out: | 1068 | out: |
1082 | return err; | 1069 | return err; |
1083 | } | 1070 | } |
@@ -1969,17 +1956,17 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, | |||
1969 | if (false) { | 1956 | if (false) { |
1970 | alloc_skb: | 1957 | alloc_skb: |
1971 | unix_state_unlock(other); | 1958 | unix_state_unlock(other); |
1972 | mutex_unlock(&unix_sk(other)->readlock); | 1959 | mutex_unlock(&unix_sk(other)->iolock); |
1973 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, | 1960 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, |
1974 | &err, 0); | 1961 | &err, 0); |
1975 | if (!newskb) | 1962 | if (!newskb) |
1976 | goto err; | 1963 | goto err; |
1977 | } | 1964 | } |
1978 | 1965 | ||
1979 | /* we must acquire readlock as we modify already present | 1966 | /* we must acquire iolock as we modify already present |
1980 | * skbs in the sk_receive_queue and mess with skb->len | 1967 | * skbs in the sk_receive_queue and mess with skb->len |
1981 | */ | 1968 | */ |
1982 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); | 1969 | err = mutex_lock_interruptible(&unix_sk(other)->iolock); |
1983 | if (err) { | 1970 | if (err) { |
1984 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; | 1971 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; |
1985 | goto err; | 1972 | goto err; |
@@ -2046,7 +2033,7 @@ alloc_skb: | |||
2046 | } | 2033 | } |
2047 | 2034 | ||
2048 | unix_state_unlock(other); | 2035 | unix_state_unlock(other); |
2049 | mutex_unlock(&unix_sk(other)->readlock); | 2036 | mutex_unlock(&unix_sk(other)->iolock); |
2050 | 2037 | ||
2051 | other->sk_data_ready(other); | 2038 | other->sk_data_ready(other); |
2052 | scm_destroy(&scm); | 2039 | scm_destroy(&scm); |
@@ -2055,7 +2042,7 @@ alloc_skb: | |||
2055 | err_state_unlock: | 2042 | err_state_unlock: |
2056 | unix_state_unlock(other); | 2043 | unix_state_unlock(other); |
2057 | err_unlock: | 2044 | err_unlock: |
2058 | mutex_unlock(&unix_sk(other)->readlock); | 2045 | mutex_unlock(&unix_sk(other)->iolock); |
2059 | err: | 2046 | err: |
2060 | kfree_skb(newskb); | 2047 | kfree_skb(newskb); |
2061 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) | 2048 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) |
@@ -2123,7 +2110,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2123 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 2110 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2124 | 2111 | ||
2125 | do { | 2112 | do { |
2126 | mutex_lock(&u->readlock); | 2113 | mutex_lock(&u->iolock); |
2127 | 2114 | ||
2128 | skip = sk_peek_offset(sk, flags); | 2115 | skip = sk_peek_offset(sk, flags); |
2129 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, | 2116 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, |
@@ -2131,14 +2118,14 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2131 | if (skb) | 2118 | if (skb) |
2132 | break; | 2119 | break; |
2133 | 2120 | ||
2134 | mutex_unlock(&u->readlock); | 2121 | mutex_unlock(&u->iolock); |
2135 | 2122 | ||
2136 | if (err != -EAGAIN) | 2123 | if (err != -EAGAIN) |
2137 | break; | 2124 | break; |
2138 | } while (timeo && | 2125 | } while (timeo && |
2139 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); | 2126 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); |
2140 | 2127 | ||
2141 | if (!skb) { /* implies readlock unlocked */ | 2128 | if (!skb) { /* implies iolock unlocked */ |
2142 | unix_state_lock(sk); | 2129 | unix_state_lock(sk); |
2143 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ | 2130 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ |
2144 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && | 2131 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && |
@@ -2203,7 +2190,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2203 | 2190 | ||
2204 | out_free: | 2191 | out_free: |
2205 | skb_free_datagram(sk, skb); | 2192 | skb_free_datagram(sk, skb); |
2206 | mutex_unlock(&u->readlock); | 2193 | mutex_unlock(&u->iolock); |
2207 | out: | 2194 | out: |
2208 | return err; | 2195 | return err; |
2209 | } | 2196 | } |
@@ -2298,7 +2285,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) | |||
2298 | /* Lock the socket to prevent queue disordering | 2285 | /* Lock the socket to prevent queue disordering |
2299 | * while sleeps in memcpy_tomsg | 2286 | * while sleeps in memcpy_tomsg |
2300 | */ | 2287 | */ |
2301 | mutex_lock(&u->readlock); | 2288 | mutex_lock(&u->iolock); |
2302 | 2289 | ||
2303 | if (flags & MSG_PEEK) | 2290 | if (flags & MSG_PEEK) |
2304 | skip = sk_peek_offset(sk, flags); | 2291 | skip = sk_peek_offset(sk, flags); |
@@ -2340,7 +2327,7 @@ again: | |||
2340 | break; | 2327 | break; |
2341 | } | 2328 | } |
2342 | 2329 | ||
2343 | mutex_unlock(&u->readlock); | 2330 | mutex_unlock(&u->iolock); |
2344 | 2331 | ||
2345 | timeo = unix_stream_data_wait(sk, timeo, last, | 2332 | timeo = unix_stream_data_wait(sk, timeo, last, |
2346 | last_len); | 2333 | last_len); |
@@ -2351,7 +2338,7 @@ again: | |||
2351 | goto out; | 2338 | goto out; |
2352 | } | 2339 | } |
2353 | 2340 | ||
2354 | mutex_lock(&u->readlock); | 2341 | mutex_lock(&u->iolock); |
2355 | goto redo; | 2342 | goto redo; |
2356 | unlock: | 2343 | unlock: |
2357 | unix_state_unlock(sk); | 2344 | unix_state_unlock(sk); |
@@ -2454,7 +2441,7 @@ unlock: | |||
2454 | } | 2441 | } |
2455 | } while (size); | 2442 | } while (size); |
2456 | 2443 | ||
2457 | mutex_unlock(&u->readlock); | 2444 | mutex_unlock(&u->iolock); |
2458 | if (state->msg) | 2445 | if (state->msg) |
2459 | scm_recv(sock, state->msg, &scm, flags); | 2446 | scm_recv(sock, state->msg, &scm, flags); |
2460 | else | 2447 | else |
@@ -2495,9 +2482,9 @@ static ssize_t skb_unix_socket_splice(struct sock *sk, | |||
2495 | int ret; | 2482 | int ret; |
2496 | struct unix_sock *u = unix_sk(sk); | 2483 | struct unix_sock *u = unix_sk(sk); |
2497 | 2484 | ||
2498 | mutex_unlock(&u->readlock); | 2485 | mutex_unlock(&u->iolock); |
2499 | ret = splice_to_pipe(pipe, spd); | 2486 | ret = splice_to_pipe(pipe, spd); |
2500 | mutex_lock(&u->readlock); | 2487 | mutex_lock(&u->iolock); |
2501 | 2488 | ||
2502 | return ret; | 2489 | return ret; |
2503 | } | 2490 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f02653a08993..4809f4d2cdcc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6978,7 +6978,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
6978 | 6978 | ||
6979 | params.n_counter_offsets_presp = len / sizeof(u16); | 6979 | params.n_counter_offsets_presp = len / sizeof(u16); |
6980 | if (rdev->wiphy.max_num_csa_counters && | 6980 | if (rdev->wiphy.max_num_csa_counters && |
6981 | (params.n_counter_offsets_beacon > | 6981 | (params.n_counter_offsets_presp > |
6982 | rdev->wiphy.max_num_csa_counters)) | 6982 | rdev->wiphy.max_num_csa_counters)) |
6983 | return -EINVAL; | 6983 | return -EINVAL; |
6984 | 6984 | ||
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index dbb2738e356a..6250b1cfcde5 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -958,29 +958,8 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, | |||
958 | return private(dev, iwr, cmd, info, handler); | 958 | return private(dev, iwr, cmd, info, handler); |
959 | } | 959 | } |
960 | /* Old driver API : call driver ioctl handler */ | 960 | /* Old driver API : call driver ioctl handler */ |
961 | if (dev->netdev_ops->ndo_do_ioctl) { | 961 | if (dev->netdev_ops->ndo_do_ioctl) |
962 | #ifdef CONFIG_COMPAT | 962 | return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); |
963 | if (info->flags & IW_REQUEST_FLAG_COMPAT) { | ||
964 | int ret = 0; | ||
965 | struct iwreq iwr_lcl; | ||
966 | struct compat_iw_point *iwp_compat = (void *) &iwr->u.data; | ||
967 | |||
968 | memcpy(&iwr_lcl, iwr, sizeof(struct iwreq)); | ||
969 | iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer); | ||
970 | iwr_lcl.u.data.length = iwp_compat->length; | ||
971 | iwr_lcl.u.data.flags = iwp_compat->flags; | ||
972 | |||
973 | ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd); | ||
974 | |||
975 | iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer); | ||
976 | iwp_compat->length = iwr_lcl.u.data.length; | ||
977 | iwp_compat->flags = iwr_lcl.u.data.flags; | ||
978 | |||
979 | return ret; | ||
980 | } else | ||
981 | #endif | ||
982 | return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); | ||
983 | } | ||
984 | return -EOPNOTSUPP; | 963 | return -EOPNOTSUPP; |
985 | } | 964 | } |
986 | 965 | ||
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 1c4ad477ce93..6e3f0254d8a1 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
207 | family = XFRM_SPI_SKB_CB(skb)->family; | 207 | family = XFRM_SPI_SKB_CB(skb)->family; |
208 | 208 | ||
209 | /* if tunnel is present override skb->mark value with tunnel i_key */ | 209 | /* if tunnel is present override skb->mark value with tunnel i_key */ |
210 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { | 210 | switch (family) { |
211 | switch (family) { | 211 | case AF_INET: |
212 | case AF_INET: | 212 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) |
213 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); | 213 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); |
214 | break; | 214 | break; |
215 | case AF_INET6: | 215 | case AF_INET6: |
216 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) | ||
216 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); | 217 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); |
217 | break; | 218 | break; |
218 | } | ||
219 | } | 219 | } |
220 | 220 | ||
221 | /* Allocate new secpath or COW existing one. */ | 221 | /* Allocate new secpath or COW existing one. */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b5e665b3cfb0..45f9cf97ea25 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work) | |||
626 | 626 | ||
627 | /* re-insert all policies by order of creation */ | 627 | /* re-insert all policies by order of creation */ |
628 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { | 628 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { |
629 | if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) { | ||
630 | /* skip socket policies */ | ||
631 | continue; | ||
632 | } | ||
629 | newpos = NULL; | 633 | newpos = NULL; |
630 | chain = policy_hash_bysel(net, &policy->selector, | 634 | chain = policy_hash_bysel(net, &policy->selector, |
631 | policy->family, | 635 | policy->family, |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 9895a8c56d8c..a30f898dc1c5 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -332,6 +332,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) | |||
332 | { | 332 | { |
333 | tasklet_hrtimer_cancel(&x->mtimer); | 333 | tasklet_hrtimer_cancel(&x->mtimer); |
334 | del_timer_sync(&x->rtimer); | 334 | del_timer_sync(&x->rtimer); |
335 | kfree(x->aead); | ||
335 | kfree(x->aalg); | 336 | kfree(x->aalg); |
336 | kfree(x->ealg); | 337 | kfree(x->ealg); |
337 | kfree(x->calg); | 338 | kfree(x->calg); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d516845e16e3..08892091cfe3 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -581,9 +581,12 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
581 | if (err) | 581 | if (err) |
582 | goto error; | 582 | goto error; |
583 | 583 | ||
584 | if (attrs[XFRMA_SEC_CTX] && | 584 | if (attrs[XFRMA_SEC_CTX]) { |
585 | security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX]))) | 585 | err = security_xfrm_state_alloc(x, |
586 | goto error; | 586 | nla_data(attrs[XFRMA_SEC_CTX])); |
587 | if (err) | ||
588 | goto error; | ||
589 | } | ||
587 | 590 | ||
588 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, | 591 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, |
589 | attrs[XFRMA_REPLAY_ESN_VAL]))) | 592 | attrs[XFRMA_REPLAY_ESN_VAL]))) |
@@ -896,7 +899,8 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb) | |||
896 | struct sock *sk = cb->skb->sk; | 899 | struct sock *sk = cb->skb->sk; |
897 | struct net *net = sock_net(sk); | 900 | struct net *net = sock_net(sk); |
898 | 901 | ||
899 | xfrm_state_walk_done(walk, net); | 902 | if (cb->args[0]) |
903 | xfrm_state_walk_done(walk, net); | ||
900 | return 0; | 904 | return 0; |
901 | } | 905 | } |
902 | 906 | ||
@@ -921,8 +925,6 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | |||
921 | u8 proto = 0; | 925 | u8 proto = 0; |
922 | int err; | 926 | int err; |
923 | 927 | ||
924 | cb->args[0] = 1; | ||
925 | |||
926 | err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, | 928 | err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, |
927 | xfrma_policy); | 929 | xfrma_policy); |
928 | if (err < 0) | 930 | if (err < 0) |
@@ -939,6 +941,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | |||
939 | proto = nla_get_u8(attrs[XFRMA_PROTO]); | 941 | proto = nla_get_u8(attrs[XFRMA_PROTO]); |
940 | 942 | ||
941 | xfrm_state_walk_init(walk, proto, filter); | 943 | xfrm_state_walk_init(walk, proto, filter); |
944 | cb->args[0] = 1; | ||
942 | } | 945 | } |
943 | 946 | ||
944 | (void) xfrm_state_walk(net, walk, dump_one_state, &info); | 947 | (void) xfrm_state_walk(net, walk, dump_one_state, &info); |
@@ -2051,9 +2054,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2051 | if (up->hard) { | 2054 | if (up->hard) { |
2052 | xfrm_policy_delete(xp, p->dir); | 2055 | xfrm_policy_delete(xp, p->dir); |
2053 | xfrm_audit_policy_delete(xp, 1, true); | 2056 | xfrm_audit_policy_delete(xp, 1, true); |
2054 | } else { | ||
2055 | // reset the timers here? | ||
2056 | WARN(1, "Don't know what to do with soft policy expire\n"); | ||
2057 | } | 2057 | } |
2058 | km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); | 2058 | km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); |
2059 | 2059 | ||
@@ -2117,7 +2117,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2117 | 2117 | ||
2118 | err = verify_newpolicy_info(&ua->policy); | 2118 | err = verify_newpolicy_info(&ua->policy); |
2119 | if (err) | 2119 | if (err) |
2120 | goto bad_policy; | 2120 | goto free_state; |
2121 | 2121 | ||
2122 | /* build an XP */ | 2122 | /* build an XP */ |
2123 | xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); | 2123 | xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); |
@@ -2149,8 +2149,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2149 | 2149 | ||
2150 | return 0; | 2150 | return 0; |
2151 | 2151 | ||
2152 | bad_policy: | ||
2153 | WARN(1, "BAD policy passed\n"); | ||
2154 | free_state: | 2152 | free_state: |
2155 | kfree(x); | 2153 | kfree(x); |
2156 | nomem: | 2154 | nomem: |