diff options
author | Ross Zwisler <ross.zwisler@linux.intel.com> | 2018-02-03 02:26:10 -0500 |
---|---|---|
committer | Ross Zwisler <ross.zwisler@linux.intel.com> | 2018-02-03 02:26:10 -0500 |
commit | d121f07691415df824e6b60520f782f6d13b3c81 (patch) | |
tree | 422ad3cc6fd631604fef4e469e49bacba8202e52 /net | |
parent | 59858d3d54cfad1f8db67c2c07e4dd33bb6ed955 (diff) | |
parent | 569d0365f571fa6421a5c80bc30d1b2cdab857fe (diff) |
Merge branch 'for-4.16/dax' into libnvdimm-for-next
Diffstat (limited to 'net')
111 files changed, 1019 insertions, 519 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 985046ae4231..80f5c79053a4 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -839,7 +839,6 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) | |||
839 | if (IS_ERR(file)) { | 839 | if (IS_ERR(file)) { |
840 | pr_err("%s (%d): failed to map fd\n", | 840 | pr_err("%s (%d): failed to map fd\n", |
841 | __func__, task_pid_nr(current)); | 841 | __func__, task_pid_nr(current)); |
842 | sock_release(csocket); | ||
843 | kfree(p); | 842 | kfree(p); |
844 | return PTR_ERR(file); | 843 | return PTR_ERR(file); |
845 | } | 844 | } |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 1b659ab652fb..bbe8414b6ee7 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -1214,7 +1214,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1214 | orig_node->last_seen = jiffies; | 1214 | orig_node->last_seen = jiffies; |
1215 | 1215 | ||
1216 | /* find packet count of corresponding one hop neighbor */ | 1216 | /* find packet count of corresponding one hop neighbor */ |
1217 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); | 1217 | spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1218 | if_num = if_incoming->if_num; | 1218 | if_num = if_incoming->if_num; |
1219 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; | 1219 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; |
1220 | neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); | 1220 | neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); |
@@ -1224,7 +1224,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1224 | } else { | 1224 | } else { |
1225 | neigh_rq_count = 0; | 1225 | neigh_rq_count = 0; |
1226 | } | 1226 | } |
1227 | spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); | 1227 | spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1228 | 1228 | ||
1229 | /* pay attention to not get a value bigger than 100 % */ | 1229 | /* pay attention to not get a value bigger than 100 % */ |
1230 | if (orig_eq_count > neigh_rq_count) | 1230 | if (orig_eq_count > neigh_rq_count) |
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 341ceab8338d..e0e2bfcd6b3e 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c | |||
@@ -814,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv, | |||
814 | } | 814 | } |
815 | 815 | ||
816 | orig_gw = batadv_gw_node_get(bat_priv, orig_node); | 816 | orig_gw = batadv_gw_node_get(bat_priv, orig_node); |
817 | if (!orig_node) | 817 | if (!orig_gw) |
818 | goto out; | 818 | goto out; |
819 | 819 | ||
820 | if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) | 820 | if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index a98cf1104a30..ebe6e38934e4 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -499,6 +499,8 @@ int batadv_frag_send_packet(struct sk_buff *skb, | |||
499 | */ | 499 | */ |
500 | if (skb->priority >= 256 && skb->priority <= 263) | 500 | if (skb->priority >= 256 && skb->priority <= 263) |
501 | frag_header.priority = skb->priority - 256; | 501 | frag_header.priority = skb->priority - 256; |
502 | else | ||
503 | frag_header.priority = 0; | ||
502 | 504 | ||
503 | ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); | 505 | ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); |
504 | ether_addr_copy(frag_header.dest, orig_node->orig); | 506 | ether_addr_copy(frag_header.dest, orig_node->orig); |
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 15cd2139381e..ebc4e2241c77 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c | |||
@@ -482,7 +482,7 @@ static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars) | |||
482 | 482 | ||
483 | /** | 483 | /** |
484 | * batadv_tp_sender_timeout - timer that fires in case of packet loss | 484 | * batadv_tp_sender_timeout - timer that fires in case of packet loss |
485 | * @arg: address of the related tp_vars | 485 | * @t: address to timer_list inside tp_vars |
486 | * | 486 | * |
487 | * If fired it means that there was packet loss. | 487 | * If fired it means that there was packet loss. |
488 | * Switch to Slow Start, set the ss_threshold to half of the current cwnd and | 488 | * Switch to Slow Start, set the ss_threshold to half of the current cwnd and |
@@ -1106,7 +1106,7 @@ static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars) | |||
1106 | /** | 1106 | /** |
1107 | * batadv_tp_receiver_shutdown - stop a tp meter receiver when timeout is | 1107 | * batadv_tp_receiver_shutdown - stop a tp meter receiver when timeout is |
1108 | * reached without received ack | 1108 | * reached without received ack |
1109 | * @arg: address of the related tp_vars | 1109 | * @t: address to timer_list inside tp_vars |
1110 | */ | 1110 | */ |
1111 | static void batadv_tp_receiver_shutdown(struct timer_list *t) | 1111 | static void batadv_tp_receiver_shutdown(struct timer_list *t) |
1112 | { | 1112 | { |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index d0ef0a8e8831..015f465c514b 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -1262,19 +1262,20 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev, | |||
1262 | struct net_bridge *br = netdev_priv(dev); | 1262 | struct net_bridge *br = netdev_priv(dev); |
1263 | int err; | 1263 | int err; |
1264 | 1264 | ||
1265 | err = register_netdevice(dev); | ||
1266 | if (err) | ||
1267 | return err; | ||
1268 | |||
1265 | if (tb[IFLA_ADDRESS]) { | 1269 | if (tb[IFLA_ADDRESS]) { |
1266 | spin_lock_bh(&br->lock); | 1270 | spin_lock_bh(&br->lock); |
1267 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); | 1271 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); |
1268 | spin_unlock_bh(&br->lock); | 1272 | spin_unlock_bh(&br->lock); |
1269 | } | 1273 | } |
1270 | 1274 | ||
1271 | err = register_netdevice(dev); | ||
1272 | if (err) | ||
1273 | return err; | ||
1274 | |||
1275 | err = br_changelink(dev, tb, data, extack); | 1275 | err = br_changelink(dev, tb, data, extack); |
1276 | if (err) | 1276 | if (err) |
1277 | unregister_netdevice(dev); | 1277 | br_dev_delete(dev, NULL); |
1278 | |||
1278 | return err; | 1279 | return err; |
1279 | } | 1280 | } |
1280 | 1281 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 07ed21d64f92..01ee854454a8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1106,7 +1106,7 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) | |||
1106 | * when the name is long and there isn't enough space left | 1106 | * when the name is long and there isn't enough space left |
1107 | * for the digits, or if all bits are used. | 1107 | * for the digits, or if all bits are used. |
1108 | */ | 1108 | */ |
1109 | return p ? -ENFILE : -EEXIST; | 1109 | return -ENFILE; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | static int dev_alloc_name_ns(struct net *net, | 1112 | static int dev_alloc_name_ns(struct net *net, |
@@ -3904,7 +3904,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, | |||
3904 | hroom > 0 ? ALIGN(hroom, NET_SKB_PAD) : 0, | 3904 | hroom > 0 ? ALIGN(hroom, NET_SKB_PAD) : 0, |
3905 | troom > 0 ? troom + 128 : 0, GFP_ATOMIC)) | 3905 | troom > 0 ? troom + 128 : 0, GFP_ATOMIC)) |
3906 | goto do_drop; | 3906 | goto do_drop; |
3907 | if (troom > 0 && __skb_linearize(skb)) | 3907 | if (skb_linearize(skb)) |
3908 | goto do_drop; | 3908 | goto do_drop; |
3909 | } | 3909 | } |
3910 | 3910 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b797832565d3..60a71be75aea 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -267,7 +267,7 @@ struct net *get_net_ns_by_id(struct net *net, int id) | |||
267 | spin_lock_bh(&net->nsid_lock); | 267 | spin_lock_bh(&net->nsid_lock); |
268 | peer = idr_find(&net->netns_ids, id); | 268 | peer = idr_find(&net->netns_ids, id); |
269 | if (peer) | 269 | if (peer) |
270 | get_net(peer); | 270 | peer = maybe_get_net(peer); |
271 | spin_unlock_bh(&net->nsid_lock); | 271 | spin_unlock_bh(&net->nsid_lock); |
272 | rcu_read_unlock(); | 272 | rcu_read_unlock(); |
273 | 273 | ||
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 1c4810919a0a..b9057478d69c 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
19 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
20 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6b0ff396fa9d..08f574081315 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1177,12 +1177,12 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
1177 | int i, new_frags; | 1177 | int i, new_frags; |
1178 | u32 d_off; | 1178 | u32 d_off; |
1179 | 1179 | ||
1180 | if (!num_frags) | ||
1181 | return 0; | ||
1182 | |||
1183 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) | 1180 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) |
1184 | return -EINVAL; | 1181 | return -EINVAL; |
1185 | 1182 | ||
1183 | if (!num_frags) | ||
1184 | goto release; | ||
1185 | |||
1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1187 | for (i = 0; i < new_frags; i++) { | 1187 | for (i = 0; i < new_frags; i++) { |
1188 | page = alloc_page(gfp_mask); | 1188 | page = alloc_page(gfp_mask); |
@@ -1238,6 +1238,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
1238 | __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); | 1238 | __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); |
1239 | skb_shinfo(skb)->nr_frags = new_frags; | 1239 | skb_shinfo(skb)->nr_frags = new_frags; |
1240 | 1240 | ||
1241 | release: | ||
1241 | skb_zcopy_clear(skb, false); | 1242 | skb_zcopy_clear(skb, false); |
1242 | return 0; | 1243 | return 0; |
1243 | } | 1244 | } |
@@ -3654,8 +3655,6 @@ normal: | |||
3654 | 3655 | ||
3655 | skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & | 3656 | skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & |
3656 | SKBTX_SHARED_FRAG; | 3657 | SKBTX_SHARED_FRAG; |
3657 | if (skb_zerocopy_clone(nskb, head_skb, GFP_ATOMIC)) | ||
3658 | goto err; | ||
3659 | 3658 | ||
3660 | while (pos < offset + len) { | 3659 | while (pos < offset + len) { |
3661 | if (i >= nfrags) { | 3660 | if (i >= nfrags) { |
@@ -3681,6 +3680,8 @@ normal: | |||
3681 | 3680 | ||
3682 | if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) | 3681 | if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) |
3683 | goto err; | 3682 | goto err; |
3683 | if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) | ||
3684 | goto err; | ||
3684 | 3685 | ||
3685 | *nskb_frag = *frag; | 3686 | *nskb_frag = *frag; |
3686 | __skb_frag_ref(nskb_frag); | 3687 | __skb_frag_ref(nskb_frag); |
@@ -4293,7 +4294,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
4293 | struct sock *sk = skb->sk; | 4294 | struct sock *sk = skb->sk; |
4294 | 4295 | ||
4295 | if (!skb_may_tx_timestamp(sk, false)) | 4296 | if (!skb_may_tx_timestamp(sk, false)) |
4296 | return; | 4297 | goto err; |
4297 | 4298 | ||
4298 | /* Take a reference to prevent skb_orphan() from freeing the socket, | 4299 | /* Take a reference to prevent skb_orphan() from freeing the socket, |
4299 | * but only if the socket refcount is not zero. | 4300 | * but only if the socket refcount is not zero. |
@@ -4302,7 +4303,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
4302 | *skb_hwtstamps(skb) = *hwtstamps; | 4303 | *skb_hwtstamps(skb) = *hwtstamps; |
4303 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); | 4304 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); |
4304 | sock_put(sk); | 4305 | sock_put(sk); |
4306 | return; | ||
4305 | } | 4307 | } |
4308 | |||
4309 | err: | ||
4310 | kfree_skb(skb); | ||
4306 | } | 4311 | } |
4307 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); | 4312 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); |
4308 | 4313 | ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index abd07a443219..178bb9833311 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -57,10 +57,16 @@ void dccp_time_wait(struct sock *sk, int state, int timeo) | |||
57 | if (state == DCCP_TIME_WAIT) | 57 | if (state == DCCP_TIME_WAIT) |
58 | timeo = DCCP_TIMEWAIT_LEN; | 58 | timeo = DCCP_TIMEWAIT_LEN; |
59 | 59 | ||
60 | /* tw_timer is pinned, so we need to make sure BH are disabled | ||
61 | * in following section, otherwise timer handler could run before | ||
62 | * we complete the initialization. | ||
63 | */ | ||
64 | local_bh_disable(); | ||
60 | inet_twsk_schedule(tw, timeo); | 65 | inet_twsk_schedule(tw, timeo); |
61 | /* Linkage updates. */ | 66 | /* Linkage updates. */ |
62 | __inet_twsk_hashdance(tw, sk, &dccp_hashinfo); | 67 | __inet_twsk_hashdance(tw, sk, &dccp_hashinfo); |
63 | inet_twsk_put(tw); | 68 | inet_twsk_put(tw); |
69 | local_bh_enable(); | ||
64 | } else { | 70 | } else { |
65 | /* Sorry, if we're out of memory, just CLOSE this | 71 | /* Sorry, if we're out of memory, just CLOSE this |
66 | * socket up. We've got bigger problems than | 72 | * socket up. We've got bigger problems than |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index b68168fcc06a..9d43c1f40274 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -259,6 +259,7 @@ int dccp_disconnect(struct sock *sk, int flags) | |||
259 | { | 259 | { |
260 | struct inet_connection_sock *icsk = inet_csk(sk); | 260 | struct inet_connection_sock *icsk = inet_csk(sk); |
261 | struct inet_sock *inet = inet_sk(sk); | 261 | struct inet_sock *inet = inet_sk(sk); |
262 | struct dccp_sock *dp = dccp_sk(sk); | ||
262 | int err = 0; | 263 | int err = 0; |
263 | const int old_state = sk->sk_state; | 264 | const int old_state = sk->sk_state; |
264 | 265 | ||
@@ -278,6 +279,10 @@ int dccp_disconnect(struct sock *sk, int flags) | |||
278 | sk->sk_err = ECONNRESET; | 279 | sk->sk_err = ECONNRESET; |
279 | 280 | ||
280 | dccp_clear_xmit_timers(sk); | 281 | dccp_clear_xmit_timers(sk); |
282 | ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); | ||
283 | ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); | ||
284 | dp->dccps_hc_rx_ccid = NULL; | ||
285 | dp->dccps_hc_tx_ccid = NULL; | ||
281 | 286 | ||
282 | __skb_queue_purge(&sk->sk_receive_queue); | 287 | __skb_queue_purge(&sk->sk_receive_queue); |
283 | __skb_queue_purge(&sk->sk_write_queue); | 288 | __skb_queue_purge(&sk->sk_write_queue); |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index d6e7a642493b..a95a55f79137 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/of_net.h> | 16 | #include <linux/of_net.h> |
17 | #include <linux/of_mdio.h> | 17 | #include <linux/of_mdio.h> |
18 | #include <linux/mdio.h> | 18 | #include <linux/mdio.h> |
19 | #include <linux/list.h> | ||
20 | #include <net/rtnetlink.h> | 19 | #include <net/rtnetlink.h> |
21 | #include <net/pkt_cls.h> | 20 | #include <net/pkt_cls.h> |
22 | #include <net/tc_act/tc_mirred.h> | 21 | #include <net/tc_act/tc_mirred.h> |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index a4573bccd6da..7a93359fbc72 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1428,7 +1428,7 @@ skip: | |||
1428 | 1428 | ||
1429 | static bool inetdev_valid_mtu(unsigned int mtu) | 1429 | static bool inetdev_valid_mtu(unsigned int mtu) |
1430 | { | 1430 | { |
1431 | return mtu >= 68; | 1431 | return mtu >= IPV4_MIN_MTU; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | static void inetdev_send_gratuitous_arp(struct net_device *dev, | 1434 | static void inetdev_send_gratuitous_arp(struct net_device *dev, |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index f52d27a422c3..08259d078b1c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -1298,14 +1298,19 @@ err_table_hash_alloc: | |||
1298 | 1298 | ||
1299 | static void ip_fib_net_exit(struct net *net) | 1299 | static void ip_fib_net_exit(struct net *net) |
1300 | { | 1300 | { |
1301 | unsigned int i; | 1301 | int i; |
1302 | 1302 | ||
1303 | rtnl_lock(); | 1303 | rtnl_lock(); |
1304 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1304 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1305 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); | 1305 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); |
1306 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); | 1306 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); |
1307 | #endif | 1307 | #endif |
1308 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { | 1308 | /* Destroy the tables in reverse order to guarantee that the |
1309 | * local table, ID 255, is destroyed before the main table, ID | ||
1310 | * 254. This is necessary as the local table may contain | ||
1311 | * references to data contained in the main table. | ||
1312 | */ | ||
1313 | for (i = FIB_TABLE_HASHSZ - 1; i >= 0; i--) { | ||
1309 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; | 1314 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; |
1310 | struct hlist_node *tmp; | 1315 | struct hlist_node *tmp; |
1311 | struct fib_table *tb; | 1316 | struct fib_table *tb; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index f04d944f8abe..c586597da20d 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -698,7 +698,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) | |||
698 | 698 | ||
699 | nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { | 699 | nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { |
700 | int type = nla_type(nla); | 700 | int type = nla_type(nla); |
701 | u32 val; | 701 | u32 fi_val, val; |
702 | 702 | ||
703 | if (!type) | 703 | if (!type) |
704 | continue; | 704 | continue; |
@@ -715,7 +715,11 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) | |||
715 | val = nla_get_u32(nla); | 715 | val = nla_get_u32(nla); |
716 | } | 716 | } |
717 | 717 | ||
718 | if (fi->fib_metrics->metrics[type - 1] != val) | 718 | fi_val = fi->fib_metrics->metrics[type - 1]; |
719 | if (type == RTAX_FEATURES) | ||
720 | fi_val &= ~DST_FEATURE_ECN_CA; | ||
721 | |||
722 | if (fi_val != val) | ||
719 | return false; | 723 | return false; |
720 | } | 724 | } |
721 | 725 | ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d1f8f302dbf3..726f6b608274 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/rtnetlink.h> | 89 | #include <linux/rtnetlink.h> |
90 | #include <linux/times.h> | 90 | #include <linux/times.h> |
91 | #include <linux/pkt_sched.h> | 91 | #include <linux/pkt_sched.h> |
92 | #include <linux/byteorder/generic.h> | ||
92 | 93 | ||
93 | #include <net/net_namespace.h> | 94 | #include <net/net_namespace.h> |
94 | #include <net/arp.h> | 95 | #include <net/arp.h> |
@@ -321,6 +322,23 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) | |||
321 | return scount; | 322 | return scount; |
322 | } | 323 | } |
323 | 324 | ||
325 | /* source address selection per RFC 3376 section 4.2.13 */ | ||
326 | static __be32 igmpv3_get_srcaddr(struct net_device *dev, | ||
327 | const struct flowi4 *fl4) | ||
328 | { | ||
329 | struct in_device *in_dev = __in_dev_get_rcu(dev); | ||
330 | |||
331 | if (!in_dev) | ||
332 | return htonl(INADDR_ANY); | ||
333 | |||
334 | for_ifa(in_dev) { | ||
335 | if (inet_ifa_match(fl4->saddr, ifa)) | ||
336 | return fl4->saddr; | ||
337 | } endfor_ifa(in_dev); | ||
338 | |||
339 | return htonl(INADDR_ANY); | ||
340 | } | ||
341 | |||
324 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) | 342 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) |
325 | { | 343 | { |
326 | struct sk_buff *skb; | 344 | struct sk_buff *skb; |
@@ -368,7 +386,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) | |||
368 | pip->frag_off = htons(IP_DF); | 386 | pip->frag_off = htons(IP_DF); |
369 | pip->ttl = 1; | 387 | pip->ttl = 1; |
370 | pip->daddr = fl4.daddr; | 388 | pip->daddr = fl4.daddr; |
371 | pip->saddr = fl4.saddr; | 389 | pip->saddr = igmpv3_get_srcaddr(dev, &fl4); |
372 | pip->protocol = IPPROTO_IGMP; | 390 | pip->protocol = IPPROTO_IGMP; |
373 | pip->tot_len = 0; /* filled in later */ | 391 | pip->tot_len = 0; /* filled in later */ |
374 | ip_select_ident(net, skb, NULL); | 392 | ip_select_ident(net, skb, NULL); |
@@ -404,16 +422,17 @@ static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) | |||
404 | } | 422 | } |
405 | 423 | ||
406 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, | 424 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, |
407 | int type, struct igmpv3_grec **ppgr) | 425 | int type, struct igmpv3_grec **ppgr, unsigned int mtu) |
408 | { | 426 | { |
409 | struct net_device *dev = pmc->interface->dev; | 427 | struct net_device *dev = pmc->interface->dev; |
410 | struct igmpv3_report *pih; | 428 | struct igmpv3_report *pih; |
411 | struct igmpv3_grec *pgr; | 429 | struct igmpv3_grec *pgr; |
412 | 430 | ||
413 | if (!skb) | 431 | if (!skb) { |
414 | skb = igmpv3_newpack(dev, dev->mtu); | 432 | skb = igmpv3_newpack(dev, mtu); |
415 | if (!skb) | 433 | if (!skb) |
416 | return NULL; | 434 | return NULL; |
435 | } | ||
417 | pgr = skb_put(skb, sizeof(struct igmpv3_grec)); | 436 | pgr = skb_put(skb, sizeof(struct igmpv3_grec)); |
418 | pgr->grec_type = type; | 437 | pgr->grec_type = type; |
419 | pgr->grec_auxwords = 0; | 438 | pgr->grec_auxwords = 0; |
@@ -436,12 +455,17 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
436 | struct igmpv3_grec *pgr = NULL; | 455 | struct igmpv3_grec *pgr = NULL; |
437 | struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 456 | struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
438 | int scount, stotal, first, isquery, truncate; | 457 | int scount, stotal, first, isquery, truncate; |
458 | unsigned int mtu; | ||
439 | 459 | ||
440 | if (pmc->multiaddr == IGMP_ALL_HOSTS) | 460 | if (pmc->multiaddr == IGMP_ALL_HOSTS) |
441 | return skb; | 461 | return skb; |
442 | if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) | 462 | if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) |
443 | return skb; | 463 | return skb; |
444 | 464 | ||
465 | mtu = READ_ONCE(dev->mtu); | ||
466 | if (mtu < IPV4_MIN_MTU) | ||
467 | return skb; | ||
468 | |||
445 | isquery = type == IGMPV3_MODE_IS_INCLUDE || | 469 | isquery = type == IGMPV3_MODE_IS_INCLUDE || |
446 | type == IGMPV3_MODE_IS_EXCLUDE; | 470 | type == IGMPV3_MODE_IS_EXCLUDE; |
447 | truncate = type == IGMPV3_MODE_IS_EXCLUDE || | 471 | truncate = type == IGMPV3_MODE_IS_EXCLUDE || |
@@ -462,7 +486,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
462 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 486 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
463 | if (skb) | 487 | if (skb) |
464 | igmpv3_sendpack(skb); | 488 | igmpv3_sendpack(skb); |
465 | skb = igmpv3_newpack(dev, dev->mtu); | 489 | skb = igmpv3_newpack(dev, mtu); |
466 | } | 490 | } |
467 | } | 491 | } |
468 | first = 1; | 492 | first = 1; |
@@ -498,12 +522,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
498 | pgr->grec_nsrcs = htons(scount); | 522 | pgr->grec_nsrcs = htons(scount); |
499 | if (skb) | 523 | if (skb) |
500 | igmpv3_sendpack(skb); | 524 | igmpv3_sendpack(skb); |
501 | skb = igmpv3_newpack(dev, dev->mtu); | 525 | skb = igmpv3_newpack(dev, mtu); |
502 | first = 1; | 526 | first = 1; |
503 | scount = 0; | 527 | scount = 0; |
504 | } | 528 | } |
505 | if (first) { | 529 | if (first) { |
506 | skb = add_grhead(skb, pmc, type, &pgr); | 530 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
507 | first = 0; | 531 | first = 0; |
508 | } | 532 | } |
509 | if (!skb) | 533 | if (!skb) |
@@ -538,7 +562,7 @@ empty_source: | |||
538 | igmpv3_sendpack(skb); | 562 | igmpv3_sendpack(skb); |
539 | skb = NULL; /* add_grhead will get a new one */ | 563 | skb = NULL; /* add_grhead will get a new one */ |
540 | } | 564 | } |
541 | skb = add_grhead(skb, pmc, type, &pgr); | 565 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
542 | } | 566 | } |
543 | } | 567 | } |
544 | if (pgr) | 568 | if (pgr) |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index c690cd0d9b3f..b563e0c46bac 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -93,7 +93,7 @@ static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * Enter the time wait state. | 96 | * Enter the time wait state. This is called with locally disabled BH. |
97 | * Essentially we whip up a timewait bucket, copy the relevant info into it | 97 | * Essentially we whip up a timewait bucket, copy the relevant info into it |
98 | * from the SK, and mess with hash chains and list linkage. | 98 | * from the SK, and mess with hash chains and list linkage. |
99 | */ | 99 | */ |
@@ -111,7 +111,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
111 | */ | 111 | */ |
112 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num, | 112 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num, |
113 | hashinfo->bhash_size)]; | 113 | hashinfo->bhash_size)]; |
114 | spin_lock_bh(&bhead->lock); | 114 | spin_lock(&bhead->lock); |
115 | tw->tw_tb = icsk->icsk_bind_hash; | 115 | tw->tw_tb = icsk->icsk_bind_hash; |
116 | WARN_ON(!icsk->icsk_bind_hash); | 116 | WARN_ON(!icsk->icsk_bind_hash); |
117 | inet_twsk_add_bind_node(tw, &tw->tw_tb->owners); | 117 | inet_twsk_add_bind_node(tw, &tw->tw_tb->owners); |
@@ -137,7 +137,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
137 | if (__sk_nulls_del_node_init_rcu(sk)) | 137 | if (__sk_nulls_del_node_init_rcu(sk)) |
138 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 138 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
139 | 139 | ||
140 | spin_unlock_bh(lock); | 140 | spin_unlock(lock); |
141 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(__inet_twsk_hashdance); | 142 | EXPORT_SYMBOL_GPL(__inet_twsk_hashdance); |
143 | 143 | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index bb6239169b1a..45ffd3d045d2 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -266,7 +266,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
266 | len = gre_hdr_len + sizeof(*ershdr); | 266 | len = gre_hdr_len + sizeof(*ershdr); |
267 | 267 | ||
268 | if (unlikely(!pskb_may_pull(skb, len))) | 268 | if (unlikely(!pskb_may_pull(skb, len))) |
269 | return -ENOMEM; | 269 | return PACKET_REJECT; |
270 | 270 | ||
271 | iph = ip_hdr(skb); | 271 | iph = ip_hdr(skb); |
272 | ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len); | 272 | ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len); |
@@ -1310,6 +1310,7 @@ static const struct net_device_ops erspan_netdev_ops = { | |||
1310 | static void ipgre_tap_setup(struct net_device *dev) | 1310 | static void ipgre_tap_setup(struct net_device *dev) |
1311 | { | 1311 | { |
1312 | ether_setup(dev); | 1312 | ether_setup(dev); |
1313 | dev->max_mtu = 0; | ||
1313 | dev->netdev_ops = &gre_tap_netdev_ops; | 1314 | dev->netdev_ops = &gre_tap_netdev_ops; |
1314 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 1315 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
1315 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | 1316 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index fe6fee728ce4..5ddb1cb52bd4 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -349,8 +349,8 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
349 | dev->needed_headroom = t_hlen + hlen; | 349 | dev->needed_headroom = t_hlen + hlen; |
350 | mtu -= (dev->hard_header_len + t_hlen); | 350 | mtu -= (dev->hard_header_len + t_hlen); |
351 | 351 | ||
352 | if (mtu < 68) | 352 | if (mtu < IPV4_MIN_MTU) |
353 | mtu = 68; | 353 | mtu = IPV4_MIN_MTU; |
354 | 354 | ||
355 | return mtu; | 355 | return mtu; |
356 | } | 356 | } |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f88221aebc9d..0c3c944a7b72 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -373,7 +373,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo, | |||
373 | if (!xt_find_jump_offset(offsets, newpos, | 373 | if (!xt_find_jump_offset(offsets, newpos, |
374 | newinfo->number)) | 374 | newinfo->number)) |
375 | return 0; | 375 | return 0; |
376 | e = entry0 + newpos; | ||
377 | } else { | 376 | } else { |
378 | /* ... this is a fallthru */ | 377 | /* ... this is a fallthru */ |
379 | newpos = pos + e->next_offset; | 378 | newpos = pos + e->next_offset; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4cbe5e80f3bf..2e0d339028bb 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -439,7 +439,6 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
439 | if (!xt_find_jump_offset(offsets, newpos, | 439 | if (!xt_find_jump_offset(offsets, newpos, |
440 | newinfo->number)) | 440 | newinfo->number)) |
441 | return 0; | 441 | return 0; |
442 | e = entry0 + newpos; | ||
443 | } else { | 442 | } else { |
444 | /* ... this is a fallthru */ | 443 | /* ... this is a fallthru */ |
445 | newpos = pos + e->next_offset; | 444 | newpos = pos + e->next_offset; |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 17b4ca562944..69060e3abe85 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -813,12 +813,13 @@ static int clusterip_net_init(struct net *net) | |||
813 | 813 | ||
814 | static void clusterip_net_exit(struct net *net) | 814 | static void clusterip_net_exit(struct net *net) |
815 | { | 815 | { |
816 | #ifdef CONFIG_PROC_FS | ||
817 | struct clusterip_net *cn = net_generic(net, clusterip_net_id); | 816 | struct clusterip_net *cn = net_generic(net, clusterip_net_id); |
817 | #ifdef CONFIG_PROC_FS | ||
818 | proc_remove(cn->procdir); | 818 | proc_remove(cn->procdir); |
819 | cn->procdir = NULL; | 819 | cn->procdir = NULL; |
820 | #endif | 820 | #endif |
821 | nf_unregister_net_hook(net, &cip_arp_ops); | 821 | nf_unregister_net_hook(net, &cip_arp_ops); |
822 | WARN_ON_ONCE(!list_empty(&cn->configs)); | ||
822 | } | 823 | } |
823 | 824 | ||
824 | static struct pernet_operations clusterip_net_ops = { | 825 | static struct pernet_operations clusterip_net_ops = { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 33b70bfd1122..125c1eab3eaa 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -513,11 +513,16 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
513 | int err; | 513 | int err; |
514 | struct ip_options_data opt_copy; | 514 | struct ip_options_data opt_copy; |
515 | struct raw_frag_vec rfv; | 515 | struct raw_frag_vec rfv; |
516 | int hdrincl; | ||
516 | 517 | ||
517 | err = -EMSGSIZE; | 518 | err = -EMSGSIZE; |
518 | if (len > 0xFFFF) | 519 | if (len > 0xFFFF) |
519 | goto out; | 520 | goto out; |
520 | 521 | ||
522 | /* hdrincl should be READ_ONCE(inet->hdrincl) | ||
523 | * but READ_ONCE() doesn't work with bit fields | ||
524 | */ | ||
525 | hdrincl = inet->hdrincl; | ||
521 | /* | 526 | /* |
522 | * Check the flags. | 527 | * Check the flags. |
523 | */ | 528 | */ |
@@ -593,7 +598,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
593 | /* Linux does not mangle headers on raw sockets, | 598 | /* Linux does not mangle headers on raw sockets, |
594 | * so that IP options + IP_HDRINCL is non-sense. | 599 | * so that IP options + IP_HDRINCL is non-sense. |
595 | */ | 600 | */ |
596 | if (inet->hdrincl) | 601 | if (hdrincl) |
597 | goto done; | 602 | goto done; |
598 | if (ipc.opt->opt.srr) { | 603 | if (ipc.opt->opt.srr) { |
599 | if (!daddr) | 604 | if (!daddr) |
@@ -615,12 +620,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
615 | 620 | ||
616 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 621 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
617 | RT_SCOPE_UNIVERSE, | 622 | RT_SCOPE_UNIVERSE, |
618 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 623 | hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
619 | inet_sk_flowi_flags(sk) | | 624 | inet_sk_flowi_flags(sk) | |
620 | (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), | 625 | (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), |
621 | daddr, saddr, 0, 0, sk->sk_uid); | 626 | daddr, saddr, 0, 0, sk->sk_uid); |
622 | 627 | ||
623 | if (!inet->hdrincl) { | 628 | if (!hdrincl) { |
624 | rfv.msg = msg; | 629 | rfv.msg = msg; |
625 | rfv.hlen = 0; | 630 | rfv.hlen = 0; |
626 | 631 | ||
@@ -645,7 +650,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
645 | goto do_confirm; | 650 | goto do_confirm; |
646 | back_from_confirm: | 651 | back_from_confirm: |
647 | 652 | ||
648 | if (inet->hdrincl) | 653 | if (hdrincl) |
649 | err = raw_send_hdrinc(sk, &fl4, msg, len, | 654 | err = raw_send_hdrinc(sk, &fl4, msg, len, |
650 | &rt, msg->msg_flags, &ipc.sockc); | 655 | &rt, msg->msg_flags, &ipc.sockc); |
651 | 656 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index bf97317e6c97..f08eebe60446 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2412,6 +2412,7 @@ int tcp_disconnect(struct sock *sk, int flags) | |||
2412 | tp->snd_cwnd_cnt = 0; | 2412 | tp->snd_cwnd_cnt = 0; |
2413 | tp->window_clamp = 0; | 2413 | tp->window_clamp = 0; |
2414 | tcp_set_ca_state(sk, TCP_CA_Open); | 2414 | tcp_set_ca_state(sk, TCP_CA_Open); |
2415 | tp->is_sack_reneg = 0; | ||
2415 | tcp_clear_retrans(tp); | 2416 | tcp_clear_retrans(tp); |
2416 | inet_csk_delack_init(sk); | 2417 | inet_csk_delack_init(sk); |
2417 | /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 | 2418 | /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 |
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c index 69ee877574d0..8322f26e770e 100644 --- a/net/ipv4/tcp_bbr.c +++ b/net/ipv4/tcp_bbr.c | |||
@@ -110,7 +110,8 @@ struct bbr { | |||
110 | u32 lt_last_lost; /* LT intvl start: tp->lost */ | 110 | u32 lt_last_lost; /* LT intvl start: tp->lost */ |
111 | u32 pacing_gain:10, /* current gain for setting pacing rate */ | 111 | u32 pacing_gain:10, /* current gain for setting pacing rate */ |
112 | cwnd_gain:10, /* current gain for setting cwnd */ | 112 | cwnd_gain:10, /* current gain for setting cwnd */ |
113 | full_bw_cnt:3, /* number of rounds without large bw gains */ | 113 | full_bw_reached:1, /* reached full bw in Startup? */ |
114 | full_bw_cnt:2, /* number of rounds without large bw gains */ | ||
114 | cycle_idx:3, /* current index in pacing_gain cycle array */ | 115 | cycle_idx:3, /* current index in pacing_gain cycle array */ |
115 | has_seen_rtt:1, /* have we seen an RTT sample yet? */ | 116 | has_seen_rtt:1, /* have we seen an RTT sample yet? */ |
116 | unused_b:5; | 117 | unused_b:5; |
@@ -180,7 +181,7 @@ static bool bbr_full_bw_reached(const struct sock *sk) | |||
180 | { | 181 | { |
181 | const struct bbr *bbr = inet_csk_ca(sk); | 182 | const struct bbr *bbr = inet_csk_ca(sk); |
182 | 183 | ||
183 | return bbr->full_bw_cnt >= bbr_full_bw_cnt; | 184 | return bbr->full_bw_reached; |
184 | } | 185 | } |
185 | 186 | ||
186 | /* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ | 187 | /* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ |
@@ -717,6 +718,7 @@ static void bbr_check_full_bw_reached(struct sock *sk, | |||
717 | return; | 718 | return; |
718 | } | 719 | } |
719 | ++bbr->full_bw_cnt; | 720 | ++bbr->full_bw_cnt; |
721 | bbr->full_bw_reached = bbr->full_bw_cnt >= bbr_full_bw_cnt; | ||
720 | } | 722 | } |
721 | 723 | ||
722 | /* If pipe is probably full, drain the queue and then enter steady-state. */ | 724 | /* If pipe is probably full, drain the queue and then enter steady-state. */ |
@@ -850,6 +852,7 @@ static void bbr_init(struct sock *sk) | |||
850 | bbr->restore_cwnd = 0; | 852 | bbr->restore_cwnd = 0; |
851 | bbr->round_start = 0; | 853 | bbr->round_start = 0; |
852 | bbr->idle_restart = 0; | 854 | bbr->idle_restart = 0; |
855 | bbr->full_bw_reached = 0; | ||
853 | bbr->full_bw = 0; | 856 | bbr->full_bw = 0; |
854 | bbr->full_bw_cnt = 0; | 857 | bbr->full_bw_cnt = 0; |
855 | bbr->cycle_mstamp = 0; | 858 | bbr->cycle_mstamp = 0; |
@@ -871,6 +874,11 @@ static u32 bbr_sndbuf_expand(struct sock *sk) | |||
871 | */ | 874 | */ |
872 | static u32 bbr_undo_cwnd(struct sock *sk) | 875 | static u32 bbr_undo_cwnd(struct sock *sk) |
873 | { | 876 | { |
877 | struct bbr *bbr = inet_csk_ca(sk); | ||
878 | |||
879 | bbr->full_bw = 0; /* spurious slow-down; reset full pipe detection */ | ||
880 | bbr->full_bw_cnt = 0; | ||
881 | bbr_reset_lt_bw_sampling(sk); | ||
874 | return tcp_sk(sk)->snd_cwnd; | 882 | return tcp_sk(sk)->snd_cwnd; |
875 | } | 883 | } |
876 | 884 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 734cfc8ff76e..45f750e85714 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -508,9 +508,6 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) | |||
508 | u32 new_sample = tp->rcv_rtt_est.rtt_us; | 508 | u32 new_sample = tp->rcv_rtt_est.rtt_us; |
509 | long m = sample; | 509 | long m = sample; |
510 | 510 | ||
511 | if (m == 0) | ||
512 | m = 1; | ||
513 | |||
514 | if (new_sample != 0) { | 511 | if (new_sample != 0) { |
515 | /* If we sample in larger samples in the non-timestamp | 512 | /* If we sample in larger samples in the non-timestamp |
516 | * case, we could grossly overestimate the RTT especially | 513 | * case, we could grossly overestimate the RTT especially |
@@ -547,6 +544,8 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp) | |||
547 | if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) | 544 | if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) |
548 | return; | 545 | return; |
549 | delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time); | 546 | delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time); |
547 | if (!delta_us) | ||
548 | delta_us = 1; | ||
550 | tcp_rcv_rtt_update(tp, delta_us, 1); | 549 | tcp_rcv_rtt_update(tp, delta_us, 1); |
551 | 550 | ||
552 | new_measure: | 551 | new_measure: |
@@ -563,8 +562,11 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, | |||
563 | (TCP_SKB_CB(skb)->end_seq - | 562 | (TCP_SKB_CB(skb)->end_seq - |
564 | TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) { | 563 | TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) { |
565 | u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; | 564 | u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; |
566 | u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); | 565 | u32 delta_us; |
567 | 566 | ||
567 | if (!delta) | ||
568 | delta = 1; | ||
569 | delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); | ||
568 | tcp_rcv_rtt_update(tp, delta_us, 0); | 570 | tcp_rcv_rtt_update(tp, delta_us, 0); |
569 | } | 571 | } |
570 | } | 572 | } |
@@ -579,6 +581,7 @@ void tcp_rcv_space_adjust(struct sock *sk) | |||
579 | int time; | 581 | int time; |
580 | int copied; | 582 | int copied; |
581 | 583 | ||
584 | tcp_mstamp_refresh(tp); | ||
582 | time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); | 585 | time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); |
583 | if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) | 586 | if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) |
584 | return; | 587 | return; |
@@ -1941,6 +1944,8 @@ void tcp_enter_loss(struct sock *sk) | |||
1941 | if (is_reneg) { | 1944 | if (is_reneg) { |
1942 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING); | 1945 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING); |
1943 | tp->sacked_out = 0; | 1946 | tp->sacked_out = 0; |
1947 | /* Mark SACK reneging until we recover from this loss event. */ | ||
1948 | tp->is_sack_reneg = 1; | ||
1944 | } | 1949 | } |
1945 | tcp_clear_all_retrans_hints(tp); | 1950 | tcp_clear_all_retrans_hints(tp); |
1946 | 1951 | ||
@@ -2326,6 +2331,7 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss) | |||
2326 | } | 2331 | } |
2327 | tp->snd_cwnd_stamp = tcp_jiffies32; | 2332 | tp->snd_cwnd_stamp = tcp_jiffies32; |
2328 | tp->undo_marker = 0; | 2333 | tp->undo_marker = 0; |
2334 | tp->rack.advanced = 1; /* Force RACK to re-exam losses */ | ||
2329 | } | 2335 | } |
2330 | 2336 | ||
2331 | static inline bool tcp_may_undo(const struct tcp_sock *tp) | 2337 | static inline bool tcp_may_undo(const struct tcp_sock *tp) |
@@ -2364,6 +2370,7 @@ static bool tcp_try_undo_recovery(struct sock *sk) | |||
2364 | return true; | 2370 | return true; |
2365 | } | 2371 | } |
2366 | tcp_set_ca_state(sk, TCP_CA_Open); | 2372 | tcp_set_ca_state(sk, TCP_CA_Open); |
2373 | tp->is_sack_reneg = 0; | ||
2367 | return false; | 2374 | return false; |
2368 | } | 2375 | } |
2369 | 2376 | ||
@@ -2397,8 +2404,10 @@ static bool tcp_try_undo_loss(struct sock *sk, bool frto_undo) | |||
2397 | NET_INC_STATS(sock_net(sk), | 2404 | NET_INC_STATS(sock_net(sk), |
2398 | LINUX_MIB_TCPSPURIOUSRTOS); | 2405 | LINUX_MIB_TCPSPURIOUSRTOS); |
2399 | inet_csk(sk)->icsk_retransmits = 0; | 2406 | inet_csk(sk)->icsk_retransmits = 0; |
2400 | if (frto_undo || tcp_is_sack(tp)) | 2407 | if (frto_undo || tcp_is_sack(tp)) { |
2401 | tcp_set_ca_state(sk, TCP_CA_Open); | 2408 | tcp_set_ca_state(sk, TCP_CA_Open); |
2409 | tp->is_sack_reneg = 0; | ||
2410 | } | ||
2402 | return true; | 2411 | return true; |
2403 | } | 2412 | } |
2404 | return false; | 2413 | return false; |
@@ -3495,6 +3504,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3495 | struct tcp_sacktag_state sack_state; | 3504 | struct tcp_sacktag_state sack_state; |
3496 | struct rate_sample rs = { .prior_delivered = 0 }; | 3505 | struct rate_sample rs = { .prior_delivered = 0 }; |
3497 | u32 prior_snd_una = tp->snd_una; | 3506 | u32 prior_snd_una = tp->snd_una; |
3507 | bool is_sack_reneg = tp->is_sack_reneg; | ||
3498 | u32 ack_seq = TCP_SKB_CB(skb)->seq; | 3508 | u32 ack_seq = TCP_SKB_CB(skb)->seq; |
3499 | u32 ack = TCP_SKB_CB(skb)->ack_seq; | 3509 | u32 ack = TCP_SKB_CB(skb)->ack_seq; |
3500 | bool is_dupack = false; | 3510 | bool is_dupack = false; |
@@ -3611,7 +3621,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3611 | 3621 | ||
3612 | delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ | 3622 | delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ |
3613 | lost = tp->lost - lost; /* freshly marked lost */ | 3623 | lost = tp->lost - lost; /* freshly marked lost */ |
3614 | tcp_rate_gen(sk, delivered, lost, sack_state.rate); | 3624 | tcp_rate_gen(sk, delivered, lost, is_sack_reneg, sack_state.rate); |
3615 | tcp_cong_control(sk, ack, delivered, flag, sack_state.rate); | 3625 | tcp_cong_control(sk, ack, delivered, flag, sack_state.rate); |
3616 | tcp_xmit_recovery(sk, rexmit); | 3626 | tcp_xmit_recovery(sk, rexmit); |
3617 | return 1; | 3627 | return 1; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c6bc0c4d19c6..94e28350f420 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -848,7 +848,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
848 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 848 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
849 | req->ts_recent, | 849 | req->ts_recent, |
850 | 0, | 850 | 0, |
851 | tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr, | 851 | tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, |
852 | AF_INET), | 852 | AF_INET), |
853 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, | 853 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, |
854 | ip_hdr(skb)->tos); | 854 | ip_hdr(skb)->tos); |
@@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb) | |||
1591 | } | 1591 | } |
1592 | EXPORT_SYMBOL(tcp_filter); | 1592 | EXPORT_SYMBOL(tcp_filter); |
1593 | 1593 | ||
1594 | static void tcp_v4_restore_cb(struct sk_buff *skb) | ||
1595 | { | ||
1596 | memmove(IPCB(skb), &TCP_SKB_CB(skb)->header.h4, | ||
1597 | sizeof(struct inet_skb_parm)); | ||
1598 | } | ||
1599 | |||
1600 | static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph, | ||
1601 | const struct tcphdr *th) | ||
1602 | { | ||
1603 | /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB() | ||
1604 | * barrier() makes sure compiler wont play fool^Waliasing games. | ||
1605 | */ | ||
1606 | memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb), | ||
1607 | sizeof(struct inet_skb_parm)); | ||
1608 | barrier(); | ||
1609 | |||
1610 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
1611 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
1612 | skb->len - th->doff * 4); | ||
1613 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
1614 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
1615 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
1616 | TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); | ||
1617 | TCP_SKB_CB(skb)->sacked = 0; | ||
1618 | TCP_SKB_CB(skb)->has_rxtstamp = | ||
1619 | skb->tstamp || skb_hwtstamps(skb)->hwtstamp; | ||
1620 | } | ||
1621 | |||
1594 | /* | 1622 | /* |
1595 | * From tcp_input.c | 1623 | * From tcp_input.c |
1596 | */ | 1624 | */ |
@@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1631 | 1659 | ||
1632 | th = (const struct tcphdr *)skb->data; | 1660 | th = (const struct tcphdr *)skb->data; |
1633 | iph = ip_hdr(skb); | 1661 | iph = ip_hdr(skb); |
1634 | /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB() | ||
1635 | * barrier() makes sure compiler wont play fool^Waliasing games. | ||
1636 | */ | ||
1637 | memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb), | ||
1638 | sizeof(struct inet_skb_parm)); | ||
1639 | barrier(); | ||
1640 | |||
1641 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
1642 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
1643 | skb->len - th->doff * 4); | ||
1644 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
1645 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
1646 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
1647 | TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); | ||
1648 | TCP_SKB_CB(skb)->sacked = 0; | ||
1649 | TCP_SKB_CB(skb)->has_rxtstamp = | ||
1650 | skb->tstamp || skb_hwtstamps(skb)->hwtstamp; | ||
1651 | |||
1652 | lookup: | 1662 | lookup: |
1653 | sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, | 1663 | sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, |
1654 | th->dest, sdif, &refcounted); | 1664 | th->dest, sdif, &refcounted); |
@@ -1679,14 +1689,19 @@ process: | |||
1679 | sock_hold(sk); | 1689 | sock_hold(sk); |
1680 | refcounted = true; | 1690 | refcounted = true; |
1681 | nsk = NULL; | 1691 | nsk = NULL; |
1682 | if (!tcp_filter(sk, skb)) | 1692 | if (!tcp_filter(sk, skb)) { |
1693 | th = (const struct tcphdr *)skb->data; | ||
1694 | iph = ip_hdr(skb); | ||
1695 | tcp_v4_fill_cb(skb, iph, th); | ||
1683 | nsk = tcp_check_req(sk, skb, req, false); | 1696 | nsk = tcp_check_req(sk, skb, req, false); |
1697 | } | ||
1684 | if (!nsk) { | 1698 | if (!nsk) { |
1685 | reqsk_put(req); | 1699 | reqsk_put(req); |
1686 | goto discard_and_relse; | 1700 | goto discard_and_relse; |
1687 | } | 1701 | } |
1688 | if (nsk == sk) { | 1702 | if (nsk == sk) { |
1689 | reqsk_put(req); | 1703 | reqsk_put(req); |
1704 | tcp_v4_restore_cb(skb); | ||
1690 | } else if (tcp_child_process(sk, nsk, skb)) { | 1705 | } else if (tcp_child_process(sk, nsk, skb)) { |
1691 | tcp_v4_send_reset(nsk, skb); | 1706 | tcp_v4_send_reset(nsk, skb); |
1692 | goto discard_and_relse; | 1707 | goto discard_and_relse; |
@@ -1712,6 +1727,7 @@ process: | |||
1712 | goto discard_and_relse; | 1727 | goto discard_and_relse; |
1713 | th = (const struct tcphdr *)skb->data; | 1728 | th = (const struct tcphdr *)skb->data; |
1714 | iph = ip_hdr(skb); | 1729 | iph = ip_hdr(skb); |
1730 | tcp_v4_fill_cb(skb, iph, th); | ||
1715 | 1731 | ||
1716 | skb->dev = NULL; | 1732 | skb->dev = NULL; |
1717 | 1733 | ||
@@ -1742,6 +1758,8 @@ no_tcp_socket: | |||
1742 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | 1758 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) |
1743 | goto discard_it; | 1759 | goto discard_it; |
1744 | 1760 | ||
1761 | tcp_v4_fill_cb(skb, iph, th); | ||
1762 | |||
1745 | if (tcp_checksum_complete(skb)) { | 1763 | if (tcp_checksum_complete(skb)) { |
1746 | csum_error: | 1764 | csum_error: |
1747 | __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); | 1765 | __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); |
@@ -1768,6 +1786,8 @@ do_time_wait: | |||
1768 | goto discard_it; | 1786 | goto discard_it; |
1769 | } | 1787 | } |
1770 | 1788 | ||
1789 | tcp_v4_fill_cb(skb, iph, th); | ||
1790 | |||
1771 | if (tcp_checksum_complete(skb)) { | 1791 | if (tcp_checksum_complete(skb)) { |
1772 | inet_twsk_put(inet_twsk(sk)); | 1792 | inet_twsk_put(inet_twsk(sk)); |
1773 | goto csum_error; | 1793 | goto csum_error; |
@@ -1784,6 +1804,7 @@ do_time_wait: | |||
1784 | if (sk2) { | 1804 | if (sk2) { |
1785 | inet_twsk_deschedule_put(inet_twsk(sk)); | 1805 | inet_twsk_deschedule_put(inet_twsk(sk)); |
1786 | sk = sk2; | 1806 | sk = sk2; |
1807 | tcp_v4_restore_cb(skb); | ||
1787 | refcounted = false; | 1808 | refcounted = false; |
1788 | goto process; | 1809 | goto process; |
1789 | } | 1810 | } |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index e36eff0403f4..b079b619b60c 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -310,10 +310,16 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
310 | if (state == TCP_TIME_WAIT) | 310 | if (state == TCP_TIME_WAIT) |
311 | timeo = TCP_TIMEWAIT_LEN; | 311 | timeo = TCP_TIMEWAIT_LEN; |
312 | 312 | ||
313 | /* tw_timer is pinned, so we need to make sure BH are disabled | ||
314 | * in following section, otherwise timer handler could run before | ||
315 | * we complete the initialization. | ||
316 | */ | ||
317 | local_bh_disable(); | ||
313 | inet_twsk_schedule(tw, timeo); | 318 | inet_twsk_schedule(tw, timeo); |
314 | /* Linkage updates. */ | 319 | /* Linkage updates. */ |
315 | __inet_twsk_hashdance(tw, sk, &tcp_hashinfo); | 320 | __inet_twsk_hashdance(tw, sk, &tcp_hashinfo); |
316 | inet_twsk_put(tw); | 321 | inet_twsk_put(tw); |
322 | local_bh_enable(); | ||
317 | } else { | 323 | } else { |
318 | /* Sorry, if we're out of memory, just CLOSE this | 324 | /* Sorry, if we're out of memory, just CLOSE this |
319 | * socket up. We've got bigger problems than | 325 | * socket up. We've got bigger problems than |
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c index 3330a370d306..c61240e43923 100644 --- a/net/ipv4/tcp_rate.c +++ b/net/ipv4/tcp_rate.c | |||
@@ -106,7 +106,7 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb, | |||
106 | 106 | ||
107 | /* Update the connection delivery information and generate a rate sample. */ | 107 | /* Update the connection delivery information and generate a rate sample. */ |
108 | void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, | 108 | void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, |
109 | struct rate_sample *rs) | 109 | bool is_sack_reneg, struct rate_sample *rs) |
110 | { | 110 | { |
111 | struct tcp_sock *tp = tcp_sk(sk); | 111 | struct tcp_sock *tp = tcp_sk(sk); |
112 | u32 snd_us, ack_us; | 112 | u32 snd_us, ack_us; |
@@ -124,8 +124,12 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, | |||
124 | 124 | ||
125 | rs->acked_sacked = delivered; /* freshly ACKed or SACKed */ | 125 | rs->acked_sacked = delivered; /* freshly ACKed or SACKed */ |
126 | rs->losses = lost; /* freshly marked lost */ | 126 | rs->losses = lost; /* freshly marked lost */ |
127 | /* Return an invalid sample if no timing information is available. */ | 127 | /* Return an invalid sample if no timing information is available or |
128 | if (!rs->prior_mstamp) { | 128 | * in recovery from loss with SACK reneging. Rate samples taken during |
129 | * a SACK reneging event may overestimate bw by including packets that | ||
130 | * were SACKed before the reneg. | ||
131 | */ | ||
132 | if (!rs->prior_mstamp || is_sack_reneg) { | ||
129 | rs->delivered = -1; | 133 | rs->delivered = -1; |
130 | rs->interval_us = -1; | 134 | rs->interval_us = -1; |
131 | return; | 135 | return; |
diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c index d3ea89020c69..3a81720ac0c4 100644 --- a/net/ipv4/tcp_recovery.c +++ b/net/ipv4/tcp_recovery.c | |||
@@ -55,7 +55,8 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout) | |||
55 | * to queuing or delayed ACKs. | 55 | * to queuing or delayed ACKs. |
56 | */ | 56 | */ |
57 | reo_wnd = 1000; | 57 | reo_wnd = 1000; |
58 | if ((tp->rack.reord || !tp->lost_out) && min_rtt != ~0U) { | 58 | if ((tp->rack.reord || inet_csk(sk)->icsk_ca_state < TCP_CA_Recovery) && |
59 | min_rtt != ~0U) { | ||
59 | reo_wnd = max((min_rtt >> 2) * tp->rack.reo_wnd_steps, reo_wnd); | 60 | reo_wnd = max((min_rtt >> 2) * tp->rack.reo_wnd_steps, reo_wnd); |
60 | reo_wnd = min(reo_wnd, tp->srtt_us >> 3); | 61 | reo_wnd = min(reo_wnd, tp->srtt_us >> 3); |
61 | } | 62 | } |
@@ -79,12 +80,12 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout) | |||
79 | */ | 80 | */ |
80 | remaining = tp->rack.rtt_us + reo_wnd - | 81 | remaining = tp->rack.rtt_us + reo_wnd - |
81 | tcp_stamp_us_delta(tp->tcp_mstamp, skb->skb_mstamp); | 82 | tcp_stamp_us_delta(tp->tcp_mstamp, skb->skb_mstamp); |
82 | if (remaining < 0) { | 83 | if (remaining <= 0) { |
83 | tcp_rack_mark_skb_lost(sk, skb); | 84 | tcp_rack_mark_skb_lost(sk, skb); |
84 | list_del_init(&skb->tcp_tsorted_anchor); | 85 | list_del_init(&skb->tcp_tsorted_anchor); |
85 | } else { | 86 | } else { |
86 | /* Record maximum wait time (+1 to avoid 0) */ | 87 | /* Record maximum wait time */ |
87 | *reo_timeout = max_t(u32, *reo_timeout, 1 + remaining); | 88 | *reo_timeout = max_t(u32, *reo_timeout, remaining); |
88 | } | 89 | } |
89 | } | 90 | } |
90 | } | 91 | } |
@@ -116,13 +117,8 @@ void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, | |||
116 | { | 117 | { |
117 | u32 rtt_us; | 118 | u32 rtt_us; |
118 | 119 | ||
119 | if (tp->rack.mstamp && | ||
120 | !tcp_rack_sent_after(xmit_time, tp->rack.mstamp, | ||
121 | end_seq, tp->rack.end_seq)) | ||
122 | return; | ||
123 | |||
124 | rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, xmit_time); | 120 | rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, xmit_time); |
125 | if (sacked & TCPCB_RETRANS) { | 121 | if (rtt_us < tcp_min_rtt(tp) && (sacked & TCPCB_RETRANS)) { |
126 | /* If the sacked packet was retransmitted, it's ambiguous | 122 | /* If the sacked packet was retransmitted, it's ambiguous |
127 | * whether the retransmission or the original (or the prior | 123 | * whether the retransmission or the original (or the prior |
128 | * retransmission) was sacked. | 124 | * retransmission) was sacked. |
@@ -133,13 +129,15 @@ void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, | |||
133 | * so it's at least one RTT (i.e., retransmission is at least | 129 | * so it's at least one RTT (i.e., retransmission is at least |
134 | * an RTT later). | 130 | * an RTT later). |
135 | */ | 131 | */ |
136 | if (rtt_us < tcp_min_rtt(tp)) | 132 | return; |
137 | return; | ||
138 | } | 133 | } |
139 | tp->rack.rtt_us = rtt_us; | ||
140 | tp->rack.mstamp = xmit_time; | ||
141 | tp->rack.end_seq = end_seq; | ||
142 | tp->rack.advanced = 1; | 134 | tp->rack.advanced = 1; |
135 | tp->rack.rtt_us = rtt_us; | ||
136 | if (tcp_rack_sent_after(xmit_time, tp->rack.mstamp, | ||
137 | end_seq, tp->rack.end_seq)) { | ||
138 | tp->rack.mstamp = xmit_time; | ||
139 | tp->rack.end_seq = end_seq; | ||
140 | } | ||
143 | } | 141 | } |
144 | 142 | ||
145 | /* We have waited long enough to accommodate reordering. Mark the expired | 143 | /* We have waited long enough to accommodate reordering. Mark the expired |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 16df6dd44b98..968fda198376 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -264,6 +264,7 @@ void tcp_delack_timer_handler(struct sock *sk) | |||
264 | icsk->icsk_ack.pingpong = 0; | 264 | icsk->icsk_ack.pingpong = 0; |
265 | icsk->icsk_ack.ato = TCP_ATO_MIN; | 265 | icsk->icsk_ack.ato = TCP_ATO_MIN; |
266 | } | 266 | } |
267 | tcp_mstamp_refresh(tcp_sk(sk)); | ||
267 | tcp_send_ack(sk); | 268 | tcp_send_ack(sk); |
268 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKS); | 269 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKS); |
269 | } | 270 | } |
@@ -632,6 +633,7 @@ static void tcp_keepalive_timer (struct timer_list *t) | |||
632 | goto out; | 633 | goto out; |
633 | } | 634 | } |
634 | 635 | ||
636 | tcp_mstamp_refresh(tp); | ||
635 | if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { | 637 | if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { |
636 | if (tp->linger2 >= 0) { | 638 | if (tp->linger2 >= 0) { |
637 | const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; | 639 | const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index e50b7fea57ee..bcfc00e88756 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -23,6 +23,12 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
23 | return xfrm4_extract_header(skb); | 23 | return xfrm4_extract_header(skb); |
24 | } | 24 | } |
25 | 25 | ||
26 | static int xfrm4_rcv_encap_finish2(struct net *net, struct sock *sk, | ||
27 | struct sk_buff *skb) | ||
28 | { | ||
29 | return dst_input(skb); | ||
30 | } | ||
31 | |||
26 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | 32 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, |
27 | struct sk_buff *skb) | 33 | struct sk_buff *skb) |
28 | { | 34 | { |
@@ -33,7 +39,11 @@ static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | |||
33 | iph->tos, skb->dev)) | 39 | iph->tos, skb->dev)) |
34 | goto drop; | 40 | goto drop; |
35 | } | 41 | } |
36 | return dst_input(skb); | 42 | |
43 | if (xfrm_trans_queue(skb, xfrm4_rcv_encap_finish2)) | ||
44 | goto drop; | ||
45 | |||
46 | return 0; | ||
37 | drop: | 47 | drop: |
38 | kfree_skb(skb); | 48 | kfree_skb(skb); |
39 | return NET_RX_DROP; | 49 | return NET_RX_DROP; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c26f71234b9c..c9441ca45399 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -210,7 +210,6 @@ lookup_protocol: | |||
210 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; | 210 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; |
211 | np->mc_loop = 1; | 211 | np->mc_loop = 1; |
212 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 212 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
213 | np->autoflowlabel = ip6_default_np_autolabel(net); | ||
214 | np->repflow = net->ipv6.sysctl.flowlabel_reflect; | 213 | np->repflow = net->ipv6.sysctl.flowlabel_reflect; |
215 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; | 214 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; |
216 | 215 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 4cfd8e0696fe..772695960890 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -1014,6 +1014,36 @@ static void ip6gre_tunnel_setup(struct net_device *dev) | |||
1014 | eth_random_addr(dev->perm_addr); | 1014 | eth_random_addr(dev->perm_addr); |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1018 | NETIF_F_FRAGLIST | \ | ||
1019 | NETIF_F_HIGHDMA | \ | ||
1020 | NETIF_F_HW_CSUM) | ||
1021 | |||
1022 | static void ip6gre_tnl_init_features(struct net_device *dev) | ||
1023 | { | ||
1024 | struct ip6_tnl *nt = netdev_priv(dev); | ||
1025 | |||
1026 | dev->features |= GRE6_FEATURES; | ||
1027 | dev->hw_features |= GRE6_FEATURES; | ||
1028 | |||
1029 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1030 | /* TCP offload with GRE SEQ is not supported, nor | ||
1031 | * can we support 2 levels of outer headers requiring | ||
1032 | * an update. | ||
1033 | */ | ||
1034 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1035 | nt->encap.type == TUNNEL_ENCAP_NONE) { | ||
1036 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1037 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1038 | } | ||
1039 | |||
1040 | /* Can use a lockless transmit, unless we generate | ||
1041 | * output sequences | ||
1042 | */ | ||
1043 | dev->features |= NETIF_F_LLTX; | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1017 | static int ip6gre_tunnel_init_common(struct net_device *dev) | 1047 | static int ip6gre_tunnel_init_common(struct net_device *dev) |
1018 | { | 1048 | { |
1019 | struct ip6_tnl *tunnel; | 1049 | struct ip6_tnl *tunnel; |
@@ -1048,6 +1078,8 @@ static int ip6gre_tunnel_init_common(struct net_device *dev) | |||
1048 | if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | 1078 | if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) |
1049 | dev->mtu -= 8; | 1079 | dev->mtu -= 8; |
1050 | 1080 | ||
1081 | ip6gre_tnl_init_features(dev); | ||
1082 | |||
1051 | return 0; | 1083 | return 0; |
1052 | } | 1084 | } |
1053 | 1085 | ||
@@ -1298,16 +1330,12 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = { | |||
1298 | .ndo_get_iflink = ip6_tnl_get_iflink, | 1330 | .ndo_get_iflink = ip6_tnl_get_iflink, |
1299 | }; | 1331 | }; |
1300 | 1332 | ||
1301 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1302 | NETIF_F_FRAGLIST | \ | ||
1303 | NETIF_F_HIGHDMA | \ | ||
1304 | NETIF_F_HW_CSUM) | ||
1305 | |||
1306 | static void ip6gre_tap_setup(struct net_device *dev) | 1333 | static void ip6gre_tap_setup(struct net_device *dev) |
1307 | { | 1334 | { |
1308 | 1335 | ||
1309 | ether_setup(dev); | 1336 | ether_setup(dev); |
1310 | 1337 | ||
1338 | dev->max_mtu = 0; | ||
1311 | dev->netdev_ops = &ip6gre_tap_netdev_ops; | 1339 | dev->netdev_ops = &ip6gre_tap_netdev_ops; |
1312 | dev->needs_free_netdev = true; | 1340 | dev->needs_free_netdev = true; |
1313 | dev->priv_destructor = ip6gre_dev_free; | 1341 | dev->priv_destructor = ip6gre_dev_free; |
@@ -1382,26 +1410,6 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev, | |||
1382 | nt->net = dev_net(dev); | 1410 | nt->net = dev_net(dev); |
1383 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); | 1411 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); |
1384 | 1412 | ||
1385 | dev->features |= GRE6_FEATURES; | ||
1386 | dev->hw_features |= GRE6_FEATURES; | ||
1387 | |||
1388 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1389 | /* TCP offload with GRE SEQ is not supported, nor | ||
1390 | * can we support 2 levels of outer headers requiring | ||
1391 | * an update. | ||
1392 | */ | ||
1393 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1394 | (nt->encap.type == TUNNEL_ENCAP_NONE)) { | ||
1395 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1396 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1397 | } | ||
1398 | |||
1399 | /* Can use a lockless transmit, unless we generate | ||
1400 | * output sequences | ||
1401 | */ | ||
1402 | dev->features |= NETIF_F_LLTX; | ||
1403 | } | ||
1404 | |||
1405 | err = register_netdevice(dev); | 1413 | err = register_netdevice(dev); |
1406 | if (err) | 1414 | if (err) |
1407 | goto out; | 1415 | goto out; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 5110a418cc4d..f7dd51c42314 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -166,6 +166,14 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
166 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); | 166 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); |
167 | } | 167 | } |
168 | 168 | ||
169 | static bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np) | ||
170 | { | ||
171 | if (!np->autoflowlabel_set) | ||
172 | return ip6_default_np_autolabel(net); | ||
173 | else | ||
174 | return np->autoflowlabel; | ||
175 | } | ||
176 | |||
169 | /* | 177 | /* |
170 | * xmit an sk_buff (used by TCP, SCTP and DCCP) | 178 | * xmit an sk_buff (used by TCP, SCTP and DCCP) |
171 | * Note : socket lock is not held for SYNACK packets, but might be modified | 179 | * Note : socket lock is not held for SYNACK packets, but might be modified |
@@ -230,7 +238,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | |||
230 | hlimit = ip6_dst_hoplimit(dst); | 238 | hlimit = ip6_dst_hoplimit(dst); |
231 | 239 | ||
232 | ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, | 240 | ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, |
233 | np->autoflowlabel, fl6)); | 241 | ip6_autoflowlabel(net, np), fl6)); |
234 | 242 | ||
235 | hdr->payload_len = htons(seg_len); | 243 | hdr->payload_len = htons(seg_len); |
236 | hdr->nexthdr = proto; | 244 | hdr->nexthdr = proto; |
@@ -1626,7 +1634,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, | |||
1626 | 1634 | ||
1627 | ip6_flow_hdr(hdr, v6_cork->tclass, | 1635 | ip6_flow_hdr(hdr, v6_cork->tclass, |
1628 | ip6_make_flowlabel(net, skb, fl6->flowlabel, | 1636 | ip6_make_flowlabel(net, skb, fl6->flowlabel, |
1629 | np->autoflowlabel, fl6)); | 1637 | ip6_autoflowlabel(net, np), fl6)); |
1630 | hdr->hop_limit = v6_cork->hop_limit; | 1638 | hdr->hop_limit = v6_cork->hop_limit; |
1631 | hdr->nexthdr = proto; | 1639 | hdr->nexthdr = proto; |
1632 | hdr->saddr = fl6->saddr; | 1640 | hdr->saddr = fl6->saddr; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3d3092adf1d2..931c38f6ff4a 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -904,7 +904,7 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto, | |||
904 | if (t->parms.collect_md) { | 904 | if (t->parms.collect_md) { |
905 | tun_dst = ipv6_tun_rx_dst(skb, 0, 0, 0); | 905 | tun_dst = ipv6_tun_rx_dst(skb, 0, 0, 0); |
906 | if (!tun_dst) | 906 | if (!tun_dst) |
907 | return 0; | 907 | goto drop; |
908 | } | 908 | } |
909 | ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate, | 909 | ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate, |
910 | log_ecn_error); | 910 | log_ecn_error); |
@@ -1123,8 +1123,13 @@ route_lookup: | |||
1123 | max_headroom += 8; | 1123 | max_headroom += 8; |
1124 | mtu -= 8; | 1124 | mtu -= 8; |
1125 | } | 1125 | } |
1126 | if (mtu < IPV6_MIN_MTU) | 1126 | if (skb->protocol == htons(ETH_P_IPV6)) { |
1127 | mtu = IPV6_MIN_MTU; | 1127 | if (mtu < IPV6_MIN_MTU) |
1128 | mtu = IPV6_MIN_MTU; | ||
1129 | } else if (mtu < 576) { | ||
1130 | mtu = 576; | ||
1131 | } | ||
1132 | |||
1128 | if (skb_dst(skb) && !t->parms.collect_md) | 1133 | if (skb_dst(skb) && !t->parms.collect_md) |
1129 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 1134 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); |
1130 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { | 1135 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index b9404feabd78..2d4680e0376f 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -886,6 +886,7 @@ pref_skip_coa: | |||
886 | break; | 886 | break; |
887 | case IPV6_AUTOFLOWLABEL: | 887 | case IPV6_AUTOFLOWLABEL: |
888 | np->autoflowlabel = valbool; | 888 | np->autoflowlabel = valbool; |
889 | np->autoflowlabel_set = 1; | ||
889 | retv = 0; | 890 | retv = 0; |
890 | break; | 891 | break; |
891 | case IPV6_RECVFRAGSIZE: | 892 | case IPV6_RECVFRAGSIZE: |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index fc6d7d143f2c..844642682b83 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1682,16 +1682,16 @@ static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) | |||
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | 1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, |
1685 | int type, struct mld2_grec **ppgr) | 1685 | int type, struct mld2_grec **ppgr, unsigned int mtu) |
1686 | { | 1686 | { |
1687 | struct net_device *dev = pmc->idev->dev; | ||
1688 | struct mld2_report *pmr; | 1687 | struct mld2_report *pmr; |
1689 | struct mld2_grec *pgr; | 1688 | struct mld2_grec *pgr; |
1690 | 1689 | ||
1691 | if (!skb) | 1690 | if (!skb) { |
1692 | skb = mld_newpack(pmc->idev, dev->mtu); | 1691 | skb = mld_newpack(pmc->idev, mtu); |
1693 | if (!skb) | 1692 | if (!skb) |
1694 | return NULL; | 1693 | return NULL; |
1694 | } | ||
1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); | 1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); |
1696 | pgr->grec_type = type; | 1696 | pgr->grec_type = type; |
1697 | pgr->grec_auxwords = 0; | 1697 | pgr->grec_auxwords = 0; |
@@ -1714,10 +1714,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1714 | struct mld2_grec *pgr = NULL; | 1714 | struct mld2_grec *pgr = NULL; |
1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
1716 | int scount, stotal, first, isquery, truncate; | 1716 | int scount, stotal, first, isquery, truncate; |
1717 | unsigned int mtu; | ||
1717 | 1718 | ||
1718 | if (pmc->mca_flags & MAF_NOREPORT) | 1719 | if (pmc->mca_flags & MAF_NOREPORT) |
1719 | return skb; | 1720 | return skb; |
1720 | 1721 | ||
1722 | mtu = READ_ONCE(dev->mtu); | ||
1723 | if (mtu < IPV6_MIN_MTU) | ||
1724 | return skb; | ||
1725 | |||
1721 | isquery = type == MLD2_MODE_IS_INCLUDE || | 1726 | isquery = type == MLD2_MODE_IS_INCLUDE || |
1722 | type == MLD2_MODE_IS_EXCLUDE; | 1727 | type == MLD2_MODE_IS_EXCLUDE; |
1723 | truncate = type == MLD2_MODE_IS_EXCLUDE || | 1728 | truncate = type == MLD2_MODE_IS_EXCLUDE || |
@@ -1738,7 +1743,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1738 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 1743 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
1739 | if (skb) | 1744 | if (skb) |
1740 | mld_sendpack(skb); | 1745 | mld_sendpack(skb); |
1741 | skb = mld_newpack(idev, dev->mtu); | 1746 | skb = mld_newpack(idev, mtu); |
1742 | } | 1747 | } |
1743 | } | 1748 | } |
1744 | first = 1; | 1749 | first = 1; |
@@ -1774,12 +1779,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1774 | pgr->grec_nsrcs = htons(scount); | 1779 | pgr->grec_nsrcs = htons(scount); |
1775 | if (skb) | 1780 | if (skb) |
1776 | mld_sendpack(skb); | 1781 | mld_sendpack(skb); |
1777 | skb = mld_newpack(idev, dev->mtu); | 1782 | skb = mld_newpack(idev, mtu); |
1778 | first = 1; | 1783 | first = 1; |
1779 | scount = 0; | 1784 | scount = 0; |
1780 | } | 1785 | } |
1781 | if (first) { | 1786 | if (first) { |
1782 | skb = add_grhead(skb, pmc, type, &pgr); | 1787 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1783 | first = 0; | 1788 | first = 0; |
1784 | } | 1789 | } |
1785 | if (!skb) | 1790 | if (!skb) |
@@ -1814,7 +1819,7 @@ empty_source: | |||
1814 | mld_sendpack(skb); | 1819 | mld_sendpack(skb); |
1815 | skb = NULL; /* add_grhead will get a new one */ | 1820 | skb = NULL; /* add_grhead will get a new one */ |
1816 | } | 1821 | } |
1817 | skb = add_grhead(skb, pmc, type, &pgr); | 1822 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1818 | } | 1823 | } |
1819 | } | 1824 | } |
1820 | if (pgr) | 1825 | if (pgr) |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f06e25065a34..1d7ae9366335 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -458,7 +458,6 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
458 | if (!xt_find_jump_offset(offsets, newpos, | 458 | if (!xt_find_jump_offset(offsets, newpos, |
459 | newinfo->number)) | 459 | newinfo->number)) |
460 | return 0; | 460 | return 0; |
461 | e = entry0 + newpos; | ||
462 | } else { | 461 | } else { |
463 | /* ... this is a fallthru */ | 462 | /* ... this is a fallthru */ |
464 | newpos = pos + e->next_offset; | 463 | newpos = pos + e->next_offset; |
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c index 2b1a15846f9a..92c0047e7e33 100644 --- a/net/ipv6/netfilter/ip6t_MASQUERADE.c +++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c | |||
@@ -33,13 +33,19 @@ static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par) | |||
33 | 33 | ||
34 | if (range->flags & NF_NAT_RANGE_MAP_IPS) | 34 | if (range->flags & NF_NAT_RANGE_MAP_IPS) |
35 | return -EINVAL; | 35 | return -EINVAL; |
36 | return 0; | 36 | return nf_ct_netns_get(par->net, par->family); |
37 | } | ||
38 | |||
39 | static void masquerade_tg6_destroy(const struct xt_tgdtor_param *par) | ||
40 | { | ||
41 | nf_ct_netns_put(par->net, par->family); | ||
37 | } | 42 | } |
38 | 43 | ||
39 | static struct xt_target masquerade_tg6_reg __read_mostly = { | 44 | static struct xt_target masquerade_tg6_reg __read_mostly = { |
40 | .name = "MASQUERADE", | 45 | .name = "MASQUERADE", |
41 | .family = NFPROTO_IPV6, | 46 | .family = NFPROTO_IPV6, |
42 | .checkentry = masquerade_tg6_checkentry, | 47 | .checkentry = masquerade_tg6_checkentry, |
48 | .destroy = masquerade_tg6_destroy, | ||
43 | .target = masquerade_tg6, | 49 | .target = masquerade_tg6, |
44 | .targetsize = sizeof(struct nf_nat_range), | 50 | .targetsize = sizeof(struct nf_nat_range), |
45 | .table = "nat", | 51 | .table = "nat", |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7a8d1500d374..0458b761f3c5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2336,6 +2336,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
2336 | } | 2336 | } |
2337 | 2337 | ||
2338 | rt->dst.flags |= DST_HOST; | 2338 | rt->dst.flags |= DST_HOST; |
2339 | rt->dst.input = ip6_input; | ||
2339 | rt->dst.output = ip6_output; | 2340 | rt->dst.output = ip6_output; |
2340 | rt->rt6i_gateway = fl6->daddr; | 2341 | rt->rt6i_gateway = fl6->daddr; |
2341 | rt->rt6i_dst.addr = fl6->daddr; | 2342 | rt->rt6i_dst.addr = fl6->daddr; |
@@ -4297,19 +4298,13 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
4297 | if (!ipv6_addr_any(&fl6.saddr)) | 4298 | if (!ipv6_addr_any(&fl6.saddr)) |
4298 | flags |= RT6_LOOKUP_F_HAS_SADDR; | 4299 | flags |= RT6_LOOKUP_F_HAS_SADDR; |
4299 | 4300 | ||
4300 | if (!fibmatch) | 4301 | dst = ip6_route_input_lookup(net, dev, &fl6, flags); |
4301 | dst = ip6_route_input_lookup(net, dev, &fl6, flags); | ||
4302 | else | ||
4303 | dst = ip6_route_lookup(net, &fl6, 0); | ||
4304 | 4302 | ||
4305 | rcu_read_unlock(); | 4303 | rcu_read_unlock(); |
4306 | } else { | 4304 | } else { |
4307 | fl6.flowi6_oif = oif; | 4305 | fl6.flowi6_oif = oif; |
4308 | 4306 | ||
4309 | if (!fibmatch) | 4307 | dst = ip6_route_output(net, NULL, &fl6); |
4310 | dst = ip6_route_output(net, NULL, &fl6); | ||
4311 | else | ||
4312 | dst = ip6_route_lookup(net, &fl6, 0); | ||
4313 | } | 4308 | } |
4314 | 4309 | ||
4315 | 4310 | ||
@@ -4326,6 +4321,15 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
4326 | goto errout; | 4321 | goto errout; |
4327 | } | 4322 | } |
4328 | 4323 | ||
4324 | if (fibmatch && rt->dst.from) { | ||
4325 | struct rt6_info *ort = container_of(rt->dst.from, | ||
4326 | struct rt6_info, dst); | ||
4327 | |||
4328 | dst_hold(&ort->dst); | ||
4329 | ip6_rt_put(rt); | ||
4330 | rt = ort; | ||
4331 | } | ||
4332 | |||
4329 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 4333 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
4330 | if (!skb) { | 4334 | if (!skb) { |
4331 | ip6_rt_put(rt); | 4335 | ip6_rt_put(rt); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d60ddcb0bfe2..d7dc23c1b2ca 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -1098,6 +1098,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p, | |||
1098 | ipip6_tunnel_link(sitn, t); | 1098 | ipip6_tunnel_link(sitn, t); |
1099 | t->parms.iph.ttl = p->iph.ttl; | 1099 | t->parms.iph.ttl = p->iph.ttl; |
1100 | t->parms.iph.tos = p->iph.tos; | 1100 | t->parms.iph.tos = p->iph.tos; |
1101 | t->parms.iph.frag_off = p->iph.frag_off; | ||
1101 | if (t->parms.link != p->link || t->fwmark != fwmark) { | 1102 | if (t->parms.link != p->link || t->fwmark != fwmark) { |
1102 | t->parms.link = p->link; | 1103 | t->parms.link = p->link; |
1103 | t->fwmark = fwmark; | 1104 | t->fwmark = fwmark; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6bb98c93edfe..7178476b3d2f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -994,7 +994,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
994 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | 994 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
995 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 995 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
996 | req->ts_recent, sk->sk_bound_dev_if, | 996 | req->ts_recent, sk->sk_bound_dev_if, |
997 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), | 997 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), |
998 | 0, 0); | 998 | 0, 0); |
999 | } | 999 | } |
1000 | 1000 | ||
@@ -1454,7 +1454,6 @@ process: | |||
1454 | struct sock *nsk; | 1454 | struct sock *nsk; |
1455 | 1455 | ||
1456 | sk = req->rsk_listener; | 1456 | sk = req->rsk_listener; |
1457 | tcp_v6_fill_cb(skb, hdr, th); | ||
1458 | if (tcp_v6_inbound_md5_hash(sk, skb)) { | 1457 | if (tcp_v6_inbound_md5_hash(sk, skb)) { |
1459 | sk_drops_add(sk, skb); | 1458 | sk_drops_add(sk, skb); |
1460 | reqsk_put(req); | 1459 | reqsk_put(req); |
@@ -1467,8 +1466,12 @@ process: | |||
1467 | sock_hold(sk); | 1466 | sock_hold(sk); |
1468 | refcounted = true; | 1467 | refcounted = true; |
1469 | nsk = NULL; | 1468 | nsk = NULL; |
1470 | if (!tcp_filter(sk, skb)) | 1469 | if (!tcp_filter(sk, skb)) { |
1470 | th = (const struct tcphdr *)skb->data; | ||
1471 | hdr = ipv6_hdr(skb); | ||
1472 | tcp_v6_fill_cb(skb, hdr, th); | ||
1471 | nsk = tcp_check_req(sk, skb, req, false); | 1473 | nsk = tcp_check_req(sk, skb, req, false); |
1474 | } | ||
1472 | if (!nsk) { | 1475 | if (!nsk) { |
1473 | reqsk_put(req); | 1476 | reqsk_put(req); |
1474 | goto discard_and_relse; | 1477 | goto discard_and_relse; |
@@ -1492,8 +1495,6 @@ process: | |||
1492 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1495 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
1493 | goto discard_and_relse; | 1496 | goto discard_and_relse; |
1494 | 1497 | ||
1495 | tcp_v6_fill_cb(skb, hdr, th); | ||
1496 | |||
1497 | if (tcp_v6_inbound_md5_hash(sk, skb)) | 1498 | if (tcp_v6_inbound_md5_hash(sk, skb)) |
1498 | goto discard_and_relse; | 1499 | goto discard_and_relse; |
1499 | 1500 | ||
@@ -1501,6 +1502,7 @@ process: | |||
1501 | goto discard_and_relse; | 1502 | goto discard_and_relse; |
1502 | th = (const struct tcphdr *)skb->data; | 1503 | th = (const struct tcphdr *)skb->data; |
1503 | hdr = ipv6_hdr(skb); | 1504 | hdr = ipv6_hdr(skb); |
1505 | tcp_v6_fill_cb(skb, hdr, th); | ||
1504 | 1506 | ||
1505 | skb->dev = NULL; | 1507 | skb->dev = NULL; |
1506 | 1508 | ||
@@ -1590,7 +1592,6 @@ do_time_wait: | |||
1590 | tcp_v6_timewait_ack(sk, skb); | 1592 | tcp_v6_timewait_ack(sk, skb); |
1591 | break; | 1593 | break; |
1592 | case TCP_TW_RST: | 1594 | case TCP_TW_RST: |
1593 | tcp_v6_restore_cb(skb); | ||
1594 | tcp_v6_send_reset(sk, skb); | 1595 | tcp_v6_send_reset(sk, skb); |
1595 | inet_twsk_deschedule_put(inet_twsk(sk)); | 1596 | inet_twsk_deschedule_put(inet_twsk(sk)); |
1596 | goto discard_it; | 1597 | goto discard_it; |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index fe04e23af986..841f4a07438e 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -32,6 +32,14 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
32 | } | 32 | } |
33 | EXPORT_SYMBOL(xfrm6_rcv_spi); | 33 | EXPORT_SYMBOL(xfrm6_rcv_spi); |
34 | 34 | ||
35 | static int xfrm6_transport_finish2(struct net *net, struct sock *sk, | ||
36 | struct sk_buff *skb) | ||
37 | { | ||
38 | if (xfrm_trans_queue(skb, ip6_rcv_finish)) | ||
39 | __kfree_skb(skb); | ||
40 | return -1; | ||
41 | } | ||
42 | |||
35 | int xfrm6_transport_finish(struct sk_buff *skb, int async) | 43 | int xfrm6_transport_finish(struct sk_buff *skb, int async) |
36 | { | 44 | { |
37 | struct xfrm_offload *xo = xfrm_offload(skb); | 45 | struct xfrm_offload *xo = xfrm_offload(skb); |
@@ -56,7 +64,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) | |||
56 | 64 | ||
57 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, | 65 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, |
58 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, | 66 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, |
59 | ip6_rcv_finish); | 67 | xfrm6_transport_finish2); |
60 | return -1; | 68 | return -1; |
61 | } | 69 | } |
62 | 70 | ||
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index 0b750a22c4b9..d4e98f20fc2a 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
@@ -1625,60 +1625,30 @@ static struct proto kcm_proto = { | |||
1625 | }; | 1625 | }; |
1626 | 1626 | ||
1627 | /* Clone a kcm socket. */ | 1627 | /* Clone a kcm socket. */ |
1628 | static int kcm_clone(struct socket *osock, struct kcm_clone *info, | 1628 | static struct file *kcm_clone(struct socket *osock) |
1629 | struct socket **newsockp) | ||
1630 | { | 1629 | { |
1631 | struct socket *newsock; | 1630 | struct socket *newsock; |
1632 | struct sock *newsk; | 1631 | struct sock *newsk; |
1633 | struct file *newfile; | ||
1634 | int err, newfd; | ||
1635 | 1632 | ||
1636 | err = -ENFILE; | ||
1637 | newsock = sock_alloc(); | 1633 | newsock = sock_alloc(); |
1638 | if (!newsock) | 1634 | if (!newsock) |
1639 | goto out; | 1635 | return ERR_PTR(-ENFILE); |
1640 | 1636 | ||
1641 | newsock->type = osock->type; | 1637 | newsock->type = osock->type; |
1642 | newsock->ops = osock->ops; | 1638 | newsock->ops = osock->ops; |
1643 | 1639 | ||
1644 | __module_get(newsock->ops->owner); | 1640 | __module_get(newsock->ops->owner); |
1645 | 1641 | ||
1646 | newfd = get_unused_fd_flags(0); | ||
1647 | if (unlikely(newfd < 0)) { | ||
1648 | err = newfd; | ||
1649 | goto out_fd_fail; | ||
1650 | } | ||
1651 | |||
1652 | newfile = sock_alloc_file(newsock, 0, osock->sk->sk_prot_creator->name); | ||
1653 | if (IS_ERR(newfile)) { | ||
1654 | err = PTR_ERR(newfile); | ||
1655 | goto out_sock_alloc_fail; | ||
1656 | } | ||
1657 | |||
1658 | newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL, | 1642 | newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL, |
1659 | &kcm_proto, true); | 1643 | &kcm_proto, true); |
1660 | if (!newsk) { | 1644 | if (!newsk) { |
1661 | err = -ENOMEM; | 1645 | sock_release(newsock); |
1662 | goto out_sk_alloc_fail; | 1646 | return ERR_PTR(-ENOMEM); |
1663 | } | 1647 | } |
1664 | |||
1665 | sock_init_data(newsock, newsk); | 1648 | sock_init_data(newsock, newsk); |
1666 | init_kcm_sock(kcm_sk(newsk), kcm_sk(osock->sk)->mux); | 1649 | init_kcm_sock(kcm_sk(newsk), kcm_sk(osock->sk)->mux); |
1667 | 1650 | ||
1668 | fd_install(newfd, newfile); | 1651 | return sock_alloc_file(newsock, 0, osock->sk->sk_prot_creator->name); |
1669 | *newsockp = newsock; | ||
1670 | info->fd = newfd; | ||
1671 | |||
1672 | return 0; | ||
1673 | |||
1674 | out_sk_alloc_fail: | ||
1675 | fput(newfile); | ||
1676 | out_sock_alloc_fail: | ||
1677 | put_unused_fd(newfd); | ||
1678 | out_fd_fail: | ||
1679 | sock_release(newsock); | ||
1680 | out: | ||
1681 | return err; | ||
1682 | } | 1652 | } |
1683 | 1653 | ||
1684 | static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1654 | static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
@@ -1708,17 +1678,25 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1708 | } | 1678 | } |
1709 | case SIOCKCMCLONE: { | 1679 | case SIOCKCMCLONE: { |
1710 | struct kcm_clone info; | 1680 | struct kcm_clone info; |
1711 | struct socket *newsock = NULL; | 1681 | struct file *file; |
1712 | 1682 | ||
1713 | err = kcm_clone(sock, &info, &newsock); | 1683 | info.fd = get_unused_fd_flags(0); |
1714 | if (!err) { | 1684 | if (unlikely(info.fd < 0)) |
1715 | if (copy_to_user((void __user *)arg, &info, | 1685 | return info.fd; |
1716 | sizeof(info))) { | ||
1717 | err = -EFAULT; | ||
1718 | sys_close(info.fd); | ||
1719 | } | ||
1720 | } | ||
1721 | 1686 | ||
1687 | file = kcm_clone(sock); | ||
1688 | if (IS_ERR(file)) { | ||
1689 | put_unused_fd(info.fd); | ||
1690 | return PTR_ERR(file); | ||
1691 | } | ||
1692 | if (copy_to_user((void __user *)arg, &info, | ||
1693 | sizeof(info))) { | ||
1694 | put_unused_fd(info.fd); | ||
1695 | fput(file); | ||
1696 | return -EFAULT; | ||
1697 | } | ||
1698 | fd_install(info.fd, file); | ||
1699 | err = 0; | ||
1722 | break; | 1700 | break; |
1723 | } | 1701 | } |
1724 | default: | 1702 | default: |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 167f83b853e6..1621b6ab17ba 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -291,16 +291,15 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, | |||
291 | int i; | 291 | int i; |
292 | 292 | ||
293 | mutex_lock(&sta->ampdu_mlme.mtx); | 293 | mutex_lock(&sta->ampdu_mlme.mtx); |
294 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 294 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
295 | ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, | 295 | ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, |
296 | WLAN_REASON_QSTA_LEAVE_QBSS, | 296 | WLAN_REASON_QSTA_LEAVE_QBSS, |
297 | reason != AGG_STOP_DESTROY_STA && | 297 | reason != AGG_STOP_DESTROY_STA && |
298 | reason != AGG_STOP_PEER_REQUEST); | 298 | reason != AGG_STOP_PEER_REQUEST); |
299 | } | ||
300 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
301 | 299 | ||
302 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | 300 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
303 | ___ieee80211_stop_tx_ba_session(sta, i, reason); | 301 | ___ieee80211_stop_tx_ba_session(sta, i, reason); |
302 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
304 | 303 | ||
305 | /* stopping might queue the work again - so cancel only afterwards */ | 304 | /* stopping might queue the work again - so cancel only afterwards */ |
306 | cancel_work_sync(&sta->ampdu_mlme.work); | 305 | cancel_work_sync(&sta->ampdu_mlme.work); |
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c index cf1bf2605c10..dc6347342e34 100644 --- a/net/netfilter/nf_conntrack_h323_asn1.c +++ b/net/netfilter/nf_conntrack_h323_asn1.c | |||
@@ -103,7 +103,6 @@ struct bitstr { | |||
103 | #define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;} | 103 | #define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;} |
104 | #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;} | 104 | #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;} |
105 | #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;} | 105 | #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;} |
106 | #define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND) | ||
107 | static unsigned int get_len(struct bitstr *bs); | 106 | static unsigned int get_len(struct bitstr *bs); |
108 | static unsigned int get_bit(struct bitstr *bs); | 107 | static unsigned int get_bit(struct bitstr *bs); |
109 | static unsigned int get_bits(struct bitstr *bs, unsigned int b); | 108 | static unsigned int get_bits(struct bitstr *bs, unsigned int b); |
@@ -165,6 +164,19 @@ static unsigned int get_len(struct bitstr *bs) | |||
165 | return v; | 164 | return v; |
166 | } | 165 | } |
167 | 166 | ||
167 | static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits) | ||
168 | { | ||
169 | bits += bs->bit; | ||
170 | bytes += bits / BITS_PER_BYTE; | ||
171 | if (bits % BITS_PER_BYTE > 0) | ||
172 | bytes++; | ||
173 | |||
174 | if (*bs->cur + bytes > *bs->end) | ||
175 | return 1; | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
168 | /****************************************************************************/ | 180 | /****************************************************************************/ |
169 | static unsigned int get_bit(struct bitstr *bs) | 181 | static unsigned int get_bit(struct bitstr *bs) |
170 | { | 182 | { |
@@ -279,8 +291,8 @@ static int decode_bool(struct bitstr *bs, const struct field_t *f, | |||
279 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 291 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
280 | 292 | ||
281 | INC_BIT(bs); | 293 | INC_BIT(bs); |
282 | 294 | if (nf_h323_error_boundary(bs, 0, 0)) | |
283 | CHECK_BOUND(bs, 0); | 295 | return H323_ERROR_BOUND; |
284 | return H323_ERROR_NONE; | 296 | return H323_ERROR_NONE; |
285 | } | 297 | } |
286 | 298 | ||
@@ -293,11 +305,14 @@ static int decode_oid(struct bitstr *bs, const struct field_t *f, | |||
293 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 305 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
294 | 306 | ||
295 | BYTE_ALIGN(bs); | 307 | BYTE_ALIGN(bs); |
296 | CHECK_BOUND(bs, 1); | 308 | if (nf_h323_error_boundary(bs, 1, 0)) |
309 | return H323_ERROR_BOUND; | ||
310 | |||
297 | len = *bs->cur++; | 311 | len = *bs->cur++; |
298 | bs->cur += len; | 312 | bs->cur += len; |
313 | if (nf_h323_error_boundary(bs, 0, 0)) | ||
314 | return H323_ERROR_BOUND; | ||
299 | 315 | ||
300 | CHECK_BOUND(bs, 0); | ||
301 | return H323_ERROR_NONE; | 316 | return H323_ERROR_NONE; |
302 | } | 317 | } |
303 | 318 | ||
@@ -319,6 +334,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
319 | bs->cur += 2; | 334 | bs->cur += 2; |
320 | break; | 335 | break; |
321 | case CONS: /* 64K < Range < 4G */ | 336 | case CONS: /* 64K < Range < 4G */ |
337 | if (nf_h323_error_boundary(bs, 0, 2)) | ||
338 | return H323_ERROR_BOUND; | ||
322 | len = get_bits(bs, 2) + 1; | 339 | len = get_bits(bs, 2) + 1; |
323 | BYTE_ALIGN(bs); | 340 | BYTE_ALIGN(bs); |
324 | if (base && (f->attr & DECODE)) { /* timeToLive */ | 341 | if (base && (f->attr & DECODE)) { /* timeToLive */ |
@@ -330,7 +347,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
330 | break; | 347 | break; |
331 | case UNCO: | 348 | case UNCO: |
332 | BYTE_ALIGN(bs); | 349 | BYTE_ALIGN(bs); |
333 | CHECK_BOUND(bs, 2); | 350 | if (nf_h323_error_boundary(bs, 2, 0)) |
351 | return H323_ERROR_BOUND; | ||
334 | len = get_len(bs); | 352 | len = get_len(bs); |
335 | bs->cur += len; | 353 | bs->cur += len; |
336 | break; | 354 | break; |
@@ -341,7 +359,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
341 | 359 | ||
342 | PRINT("\n"); | 360 | PRINT("\n"); |
343 | 361 | ||
344 | CHECK_BOUND(bs, 0); | 362 | if (nf_h323_error_boundary(bs, 0, 0)) |
363 | return H323_ERROR_BOUND; | ||
345 | return H323_ERROR_NONE; | 364 | return H323_ERROR_NONE; |
346 | } | 365 | } |
347 | 366 | ||
@@ -357,7 +376,8 @@ static int decode_enum(struct bitstr *bs, const struct field_t *f, | |||
357 | INC_BITS(bs, f->sz); | 376 | INC_BITS(bs, f->sz); |
358 | } | 377 | } |
359 | 378 | ||
360 | CHECK_BOUND(bs, 0); | 379 | if (nf_h323_error_boundary(bs, 0, 0)) |
380 | return H323_ERROR_BOUND; | ||
361 | return H323_ERROR_NONE; | 381 | return H323_ERROR_NONE; |
362 | } | 382 | } |
363 | 383 | ||
@@ -375,12 +395,14 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f, | |||
375 | len = f->lb; | 395 | len = f->lb; |
376 | break; | 396 | break; |
377 | case WORD: /* 2-byte length */ | 397 | case WORD: /* 2-byte length */ |
378 | CHECK_BOUND(bs, 2); | 398 | if (nf_h323_error_boundary(bs, 2, 0)) |
399 | return H323_ERROR_BOUND; | ||
379 | len = (*bs->cur++) << 8; | 400 | len = (*bs->cur++) << 8; |
380 | len += (*bs->cur++) + f->lb; | 401 | len += (*bs->cur++) + f->lb; |
381 | break; | 402 | break; |
382 | case SEMI: | 403 | case SEMI: |
383 | CHECK_BOUND(bs, 2); | 404 | if (nf_h323_error_boundary(bs, 2, 0)) |
405 | return H323_ERROR_BOUND; | ||
384 | len = get_len(bs); | 406 | len = get_len(bs); |
385 | break; | 407 | break; |
386 | default: | 408 | default: |
@@ -391,7 +413,8 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f, | |||
391 | bs->cur += len >> 3; | 413 | bs->cur += len >> 3; |
392 | bs->bit = len & 7; | 414 | bs->bit = len & 7; |
393 | 415 | ||
394 | CHECK_BOUND(bs, 0); | 416 | if (nf_h323_error_boundary(bs, 0, 0)) |
417 | return H323_ERROR_BOUND; | ||
395 | return H323_ERROR_NONE; | 418 | return H323_ERROR_NONE; |
396 | } | 419 | } |
397 | 420 | ||
@@ -404,12 +427,15 @@ static int decode_numstr(struct bitstr *bs, const struct field_t *f, | |||
404 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 427 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
405 | 428 | ||
406 | /* 2 <= Range <= 255 */ | 429 | /* 2 <= Range <= 255 */ |
430 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
431 | return H323_ERROR_BOUND; | ||
407 | len = get_bits(bs, f->sz) + f->lb; | 432 | len = get_bits(bs, f->sz) + f->lb; |
408 | 433 | ||
409 | BYTE_ALIGN(bs); | 434 | BYTE_ALIGN(bs); |
410 | INC_BITS(bs, (len << 2)); | 435 | INC_BITS(bs, (len << 2)); |
411 | 436 | ||
412 | CHECK_BOUND(bs, 0); | 437 | if (nf_h323_error_boundary(bs, 0, 0)) |
438 | return H323_ERROR_BOUND; | ||
413 | return H323_ERROR_NONE; | 439 | return H323_ERROR_NONE; |
414 | } | 440 | } |
415 | 441 | ||
@@ -440,15 +466,19 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f, | |||
440 | break; | 466 | break; |
441 | case BYTE: /* Range == 256 */ | 467 | case BYTE: /* Range == 256 */ |
442 | BYTE_ALIGN(bs); | 468 | BYTE_ALIGN(bs); |
443 | CHECK_BOUND(bs, 1); | 469 | if (nf_h323_error_boundary(bs, 1, 0)) |
470 | return H323_ERROR_BOUND; | ||
444 | len = (*bs->cur++) + f->lb; | 471 | len = (*bs->cur++) + f->lb; |
445 | break; | 472 | break; |
446 | case SEMI: | 473 | case SEMI: |
447 | BYTE_ALIGN(bs); | 474 | BYTE_ALIGN(bs); |
448 | CHECK_BOUND(bs, 2); | 475 | if (nf_h323_error_boundary(bs, 2, 0)) |
476 | return H323_ERROR_BOUND; | ||
449 | len = get_len(bs) + f->lb; | 477 | len = get_len(bs) + f->lb; |
450 | break; | 478 | break; |
451 | default: /* 2 <= Range <= 255 */ | 479 | default: /* 2 <= Range <= 255 */ |
480 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
481 | return H323_ERROR_BOUND; | ||
452 | len = get_bits(bs, f->sz) + f->lb; | 482 | len = get_bits(bs, f->sz) + f->lb; |
453 | BYTE_ALIGN(bs); | 483 | BYTE_ALIGN(bs); |
454 | break; | 484 | break; |
@@ -458,7 +488,8 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f, | |||
458 | 488 | ||
459 | PRINT("\n"); | 489 | PRINT("\n"); |
460 | 490 | ||
461 | CHECK_BOUND(bs, 0); | 491 | if (nf_h323_error_boundary(bs, 0, 0)) |
492 | return H323_ERROR_BOUND; | ||
462 | return H323_ERROR_NONE; | 493 | return H323_ERROR_NONE; |
463 | } | 494 | } |
464 | 495 | ||
@@ -473,10 +504,13 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, | |||
473 | switch (f->sz) { | 504 | switch (f->sz) { |
474 | case BYTE: /* Range == 256 */ | 505 | case BYTE: /* Range == 256 */ |
475 | BYTE_ALIGN(bs); | 506 | BYTE_ALIGN(bs); |
476 | CHECK_BOUND(bs, 1); | 507 | if (nf_h323_error_boundary(bs, 1, 0)) |
508 | return H323_ERROR_BOUND; | ||
477 | len = (*bs->cur++) + f->lb; | 509 | len = (*bs->cur++) + f->lb; |
478 | break; | 510 | break; |
479 | default: /* 2 <= Range <= 255 */ | 511 | default: /* 2 <= Range <= 255 */ |
512 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
513 | return H323_ERROR_BOUND; | ||
480 | len = get_bits(bs, f->sz) + f->lb; | 514 | len = get_bits(bs, f->sz) + f->lb; |
481 | BYTE_ALIGN(bs); | 515 | BYTE_ALIGN(bs); |
482 | break; | 516 | break; |
@@ -484,7 +518,8 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, | |||
484 | 518 | ||
485 | bs->cur += len << 1; | 519 | bs->cur += len << 1; |
486 | 520 | ||
487 | CHECK_BOUND(bs, 0); | 521 | if (nf_h323_error_boundary(bs, 0, 0)) |
522 | return H323_ERROR_BOUND; | ||
488 | return H323_ERROR_NONE; | 523 | return H323_ERROR_NONE; |
489 | } | 524 | } |
490 | 525 | ||
@@ -503,9 +538,13 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
503 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; | 538 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; |
504 | 539 | ||
505 | /* Extensible? */ | 540 | /* Extensible? */ |
541 | if (nf_h323_error_boundary(bs, 0, 1)) | ||
542 | return H323_ERROR_BOUND; | ||
506 | ext = (f->attr & EXT) ? get_bit(bs) : 0; | 543 | ext = (f->attr & EXT) ? get_bit(bs) : 0; |
507 | 544 | ||
508 | /* Get fields bitmap */ | 545 | /* Get fields bitmap */ |
546 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
547 | return H323_ERROR_BOUND; | ||
509 | bmp = get_bitmap(bs, f->sz); | 548 | bmp = get_bitmap(bs, f->sz); |
510 | if (base) | 549 | if (base) |
511 | *(unsigned int *)base = bmp; | 550 | *(unsigned int *)base = bmp; |
@@ -525,9 +564,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
525 | 564 | ||
526 | /* Decode */ | 565 | /* Decode */ |
527 | if (son->attr & OPEN) { /* Open field */ | 566 | if (son->attr & OPEN) { /* Open field */ |
528 | CHECK_BOUND(bs, 2); | 567 | if (nf_h323_error_boundary(bs, 2, 0)) |
568 | return H323_ERROR_BOUND; | ||
529 | len = get_len(bs); | 569 | len = get_len(bs); |
530 | CHECK_BOUND(bs, len); | 570 | if (nf_h323_error_boundary(bs, len, 0)) |
571 | return H323_ERROR_BOUND; | ||
531 | if (!base || !(son->attr & DECODE)) { | 572 | if (!base || !(son->attr & DECODE)) { |
532 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, | 573 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, |
533 | " ", son->name); | 574 | " ", son->name); |
@@ -555,8 +596,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
555 | return H323_ERROR_NONE; | 596 | return H323_ERROR_NONE; |
556 | 597 | ||
557 | /* Get the extension bitmap */ | 598 | /* Get the extension bitmap */ |
599 | if (nf_h323_error_boundary(bs, 0, 7)) | ||
600 | return H323_ERROR_BOUND; | ||
558 | bmp2_len = get_bits(bs, 7) + 1; | 601 | bmp2_len = get_bits(bs, 7) + 1; |
559 | CHECK_BOUND(bs, (bmp2_len + 7) >> 3); | 602 | if (nf_h323_error_boundary(bs, 0, bmp2_len)) |
603 | return H323_ERROR_BOUND; | ||
560 | bmp2 = get_bitmap(bs, bmp2_len); | 604 | bmp2 = get_bitmap(bs, bmp2_len); |
561 | bmp |= bmp2 >> f->sz; | 605 | bmp |= bmp2 >> f->sz; |
562 | if (base) | 606 | if (base) |
@@ -567,9 +611,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
567 | for (opt = 0; opt < bmp2_len; opt++, i++, son++) { | 611 | for (opt = 0; opt < bmp2_len; opt++, i++, son++) { |
568 | /* Check Range */ | 612 | /* Check Range */ |
569 | if (i >= f->ub) { /* Newer Version? */ | 613 | if (i >= f->ub) { /* Newer Version? */ |
570 | CHECK_BOUND(bs, 2); | 614 | if (nf_h323_error_boundary(bs, 2, 0)) |
615 | return H323_ERROR_BOUND; | ||
571 | len = get_len(bs); | 616 | len = get_len(bs); |
572 | CHECK_BOUND(bs, len); | 617 | if (nf_h323_error_boundary(bs, len, 0)) |
618 | return H323_ERROR_BOUND; | ||
573 | bs->cur += len; | 619 | bs->cur += len; |
574 | continue; | 620 | continue; |
575 | } | 621 | } |
@@ -583,9 +629,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
583 | if (!((0x80000000 >> opt) & bmp2)) /* Not present */ | 629 | if (!((0x80000000 >> opt) & bmp2)) /* Not present */ |
584 | continue; | 630 | continue; |
585 | 631 | ||
586 | CHECK_BOUND(bs, 2); | 632 | if (nf_h323_error_boundary(bs, 2, 0)) |
633 | return H323_ERROR_BOUND; | ||
587 | len = get_len(bs); | 634 | len = get_len(bs); |
588 | CHECK_BOUND(bs, len); | 635 | if (nf_h323_error_boundary(bs, len, 0)) |
636 | return H323_ERROR_BOUND; | ||
589 | if (!base || !(son->attr & DECODE)) { | 637 | if (!base || !(son->attr & DECODE)) { |
590 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", | 638 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", |
591 | son->name); | 639 | son->name); |
@@ -623,22 +671,27 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f, | |||
623 | switch (f->sz) { | 671 | switch (f->sz) { |
624 | case BYTE: | 672 | case BYTE: |
625 | BYTE_ALIGN(bs); | 673 | BYTE_ALIGN(bs); |
626 | CHECK_BOUND(bs, 1); | 674 | if (nf_h323_error_boundary(bs, 1, 0)) |
675 | return H323_ERROR_BOUND; | ||
627 | count = *bs->cur++; | 676 | count = *bs->cur++; |
628 | break; | 677 | break; |
629 | case WORD: | 678 | case WORD: |
630 | BYTE_ALIGN(bs); | 679 | BYTE_ALIGN(bs); |
631 | CHECK_BOUND(bs, 2); | 680 | if (nf_h323_error_boundary(bs, 2, 0)) |
681 | return H323_ERROR_BOUND; | ||
632 | count = *bs->cur++; | 682 | count = *bs->cur++; |
633 | count <<= 8; | 683 | count <<= 8; |
634 | count += *bs->cur++; | 684 | count += *bs->cur++; |
635 | break; | 685 | break; |
636 | case SEMI: | 686 | case SEMI: |
637 | BYTE_ALIGN(bs); | 687 | BYTE_ALIGN(bs); |
638 | CHECK_BOUND(bs, 2); | 688 | if (nf_h323_error_boundary(bs, 2, 0)) |
689 | return H323_ERROR_BOUND; | ||
639 | count = get_len(bs); | 690 | count = get_len(bs); |
640 | break; | 691 | break; |
641 | default: | 692 | default: |
693 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
694 | return H323_ERROR_BOUND; | ||
642 | count = get_bits(bs, f->sz); | 695 | count = get_bits(bs, f->sz); |
643 | break; | 696 | break; |
644 | } | 697 | } |
@@ -658,8 +711,11 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f, | |||
658 | for (i = 0; i < count; i++) { | 711 | for (i = 0; i < count; i++) { |
659 | if (son->attr & OPEN) { | 712 | if (son->attr & OPEN) { |
660 | BYTE_ALIGN(bs); | 713 | BYTE_ALIGN(bs); |
714 | if (nf_h323_error_boundary(bs, 2, 0)) | ||
715 | return H323_ERROR_BOUND; | ||
661 | len = get_len(bs); | 716 | len = get_len(bs); |
662 | CHECK_BOUND(bs, len); | 717 | if (nf_h323_error_boundary(bs, len, 0)) |
718 | return H323_ERROR_BOUND; | ||
663 | if (!base || !(son->attr & DECODE)) { | 719 | if (!base || !(son->attr & DECODE)) { |
664 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, | 720 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, |
665 | " ", son->name); | 721 | " ", son->name); |
@@ -710,11 +766,17 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
710 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; | 766 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; |
711 | 767 | ||
712 | /* Decode the choice index number */ | 768 | /* Decode the choice index number */ |
769 | if (nf_h323_error_boundary(bs, 0, 1)) | ||
770 | return H323_ERROR_BOUND; | ||
713 | if ((f->attr & EXT) && get_bit(bs)) { | 771 | if ((f->attr & EXT) && get_bit(bs)) { |
714 | ext = 1; | 772 | ext = 1; |
773 | if (nf_h323_error_boundary(bs, 0, 7)) | ||
774 | return H323_ERROR_BOUND; | ||
715 | type = get_bits(bs, 7) + f->lb; | 775 | type = get_bits(bs, 7) + f->lb; |
716 | } else { | 776 | } else { |
717 | ext = 0; | 777 | ext = 0; |
778 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
779 | return H323_ERROR_BOUND; | ||
718 | type = get_bits(bs, f->sz); | 780 | type = get_bits(bs, f->sz); |
719 | if (type >= f->lb) | 781 | if (type >= f->lb) |
720 | return H323_ERROR_RANGE; | 782 | return H323_ERROR_RANGE; |
@@ -727,8 +789,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
727 | /* Check Range */ | 789 | /* Check Range */ |
728 | if (type >= f->ub) { /* Newer version? */ | 790 | if (type >= f->ub) { /* Newer version? */ |
729 | BYTE_ALIGN(bs); | 791 | BYTE_ALIGN(bs); |
792 | if (nf_h323_error_boundary(bs, 2, 0)) | ||
793 | return H323_ERROR_BOUND; | ||
730 | len = get_len(bs); | 794 | len = get_len(bs); |
731 | CHECK_BOUND(bs, len); | 795 | if (nf_h323_error_boundary(bs, len, 0)) |
796 | return H323_ERROR_BOUND; | ||
732 | bs->cur += len; | 797 | bs->cur += len; |
733 | return H323_ERROR_NONE; | 798 | return H323_ERROR_NONE; |
734 | } | 799 | } |
@@ -742,8 +807,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
742 | 807 | ||
743 | if (ext || (son->attr & OPEN)) { | 808 | if (ext || (son->attr & OPEN)) { |
744 | BYTE_ALIGN(bs); | 809 | BYTE_ALIGN(bs); |
810 | if (nf_h323_error_boundary(bs, len, 0)) | ||
811 | return H323_ERROR_BOUND; | ||
745 | len = get_len(bs); | 812 | len = get_len(bs); |
746 | CHECK_BOUND(bs, len); | 813 | if (nf_h323_error_boundary(bs, len, 0)) |
814 | return H323_ERROR_BOUND; | ||
747 | if (!base || !(son->attr & DECODE)) { | 815 | if (!base || !(son->attr & DECODE)) { |
748 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", | 816 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", |
749 | son->name); | 817 | son->name); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 59c08997bfdf..382d49792f42 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <net/netfilter/nf_conntrack_zones.h> | 45 | #include <net/netfilter/nf_conntrack_zones.h> |
46 | #include <net/netfilter/nf_conntrack_timestamp.h> | 46 | #include <net/netfilter/nf_conntrack_timestamp.h> |
47 | #include <net/netfilter/nf_conntrack_labels.h> | 47 | #include <net/netfilter/nf_conntrack_labels.h> |
48 | #include <net/netfilter/nf_conntrack_seqadj.h> | ||
49 | #include <net/netfilter/nf_conntrack_synproxy.h> | 48 | #include <net/netfilter/nf_conntrack_synproxy.h> |
50 | #ifdef CONFIG_NF_NAT_NEEDED | 49 | #ifdef CONFIG_NF_NAT_NEEDED |
51 | #include <net/netfilter/nf_nat_core.h> | 50 | #include <net/netfilter/nf_nat_core.h> |
@@ -1566,9 +1565,11 @@ static int ctnetlink_change_helper(struct nf_conn *ct, | |||
1566 | static int ctnetlink_change_timeout(struct nf_conn *ct, | 1565 | static int ctnetlink_change_timeout(struct nf_conn *ct, |
1567 | const struct nlattr * const cda[]) | 1566 | const struct nlattr * const cda[]) |
1568 | { | 1567 | { |
1569 | u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT])); | 1568 | u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; |
1570 | 1569 | ||
1571 | ct->timeout = nfct_time_stamp + timeout * HZ; | 1570 | if (timeout > INT_MAX) |
1571 | timeout = INT_MAX; | ||
1572 | ct->timeout = nfct_time_stamp + (u32)timeout; | ||
1572 | 1573 | ||
1573 | if (test_bit(IPS_DYING_BIT, &ct->status)) | 1574 | if (test_bit(IPS_DYING_BIT, &ct->status)) |
1574 | return -ETIME; | 1575 | return -ETIME; |
@@ -1768,6 +1769,7 @@ ctnetlink_create_conntrack(struct net *net, | |||
1768 | int err = -EINVAL; | 1769 | int err = -EINVAL; |
1769 | struct nf_conntrack_helper *helper; | 1770 | struct nf_conntrack_helper *helper; |
1770 | struct nf_conn_tstamp *tstamp; | 1771 | struct nf_conn_tstamp *tstamp; |
1772 | u64 timeout; | ||
1771 | 1773 | ||
1772 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); | 1774 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); |
1773 | if (IS_ERR(ct)) | 1775 | if (IS_ERR(ct)) |
@@ -1776,7 +1778,10 @@ ctnetlink_create_conntrack(struct net *net, | |||
1776 | if (!cda[CTA_TIMEOUT]) | 1778 | if (!cda[CTA_TIMEOUT]) |
1777 | goto err1; | 1779 | goto err1; |
1778 | 1780 | ||
1779 | ct->timeout = nfct_time_stamp + ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; | 1781 | timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; |
1782 | if (timeout > INT_MAX) | ||
1783 | timeout = INT_MAX; | ||
1784 | ct->timeout = (u32)timeout + nfct_time_stamp; | ||
1780 | 1785 | ||
1781 | rcu_read_lock(); | 1786 | rcu_read_lock(); |
1782 | if (cda[CTA_HELP]) { | 1787 | if (cda[CTA_HELP]) { |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index b12fc07111d0..37ef35b861f2 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -1039,6 +1039,9 @@ static int tcp_packet(struct nf_conn *ct, | |||
1039 | IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && | 1039 | IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && |
1040 | timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) | 1040 | timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) |
1041 | timeout = timeouts[TCP_CONNTRACK_UNACK]; | 1041 | timeout = timeouts[TCP_CONNTRACK_UNACK]; |
1042 | else if (ct->proto.tcp.last_win == 0 && | ||
1043 | timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) | ||
1044 | timeout = timeouts[TCP_CONNTRACK_RETRANS]; | ||
1042 | else | 1045 | else |
1043 | timeout = timeouts[new_state]; | 1046 | timeout = timeouts[new_state]; |
1044 | spin_unlock_bh(&ct->lock); | 1047 | spin_unlock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index d8327b43e4dc..10798b357481 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -5847,6 +5847,12 @@ static int __net_init nf_tables_init_net(struct net *net) | |||
5847 | return 0; | 5847 | return 0; |
5848 | } | 5848 | } |
5849 | 5849 | ||
5850 | static void __net_exit nf_tables_exit_net(struct net *net) | ||
5851 | { | ||
5852 | WARN_ON_ONCE(!list_empty(&net->nft.af_info)); | ||
5853 | WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); | ||
5854 | } | ||
5855 | |||
5850 | int __nft_release_basechain(struct nft_ctx *ctx) | 5856 | int __nft_release_basechain(struct nft_ctx *ctx) |
5851 | { | 5857 | { |
5852 | struct nft_rule *rule, *nr; | 5858 | struct nft_rule *rule, *nr; |
@@ -5917,6 +5923,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) | |||
5917 | 5923 | ||
5918 | static struct pernet_operations nf_tables_net_ops = { | 5924 | static struct pernet_operations nf_tables_net_ops = { |
5919 | .init = nf_tables_init_net, | 5925 | .init = nf_tables_init_net, |
5926 | .exit = nf_tables_exit_net, | ||
5920 | }; | 5927 | }; |
5921 | 5928 | ||
5922 | static int __init nf_tables_module_init(void) | 5929 | static int __init nf_tables_module_init(void) |
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 41628b393673..d33ce6d5ebce 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/list.h> | 18 | #include <linux/list.h> |
19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
20 | #include <linux/capability.h> | ||
20 | #include <net/netlink.h> | 21 | #include <net/netlink.h> |
21 | #include <net/sock.h> | 22 | #include <net/sock.h> |
22 | 23 | ||
@@ -407,6 +408,9 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl, | |||
407 | struct nfnl_cthelper *nlcth; | 408 | struct nfnl_cthelper *nlcth; |
408 | int ret = 0; | 409 | int ret = 0; |
409 | 410 | ||
411 | if (!capable(CAP_NET_ADMIN)) | ||
412 | return -EPERM; | ||
413 | |||
410 | if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE]) | 414 | if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE]) |
411 | return -EINVAL; | 415 | return -EINVAL; |
412 | 416 | ||
@@ -611,6 +615,9 @@ static int nfnl_cthelper_get(struct net *net, struct sock *nfnl, | |||
611 | struct nfnl_cthelper *nlcth; | 615 | struct nfnl_cthelper *nlcth; |
612 | bool tuple_set = false; | 616 | bool tuple_set = false; |
613 | 617 | ||
618 | if (!capable(CAP_NET_ADMIN)) | ||
619 | return -EPERM; | ||
620 | |||
614 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 621 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
615 | struct netlink_dump_control c = { | 622 | struct netlink_dump_control c = { |
616 | .dump = nfnl_cthelper_dump_table, | 623 | .dump = nfnl_cthelper_dump_table, |
@@ -678,6 +685,9 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl, | |||
678 | struct nfnl_cthelper *nlcth, *n; | 685 | struct nfnl_cthelper *nlcth, *n; |
679 | int j = 0, ret; | 686 | int j = 0, ret; |
680 | 687 | ||
688 | if (!capable(CAP_NET_ADMIN)) | ||
689 | return -EPERM; | ||
690 | |||
681 | if (tb[NFCTH_NAME]) | 691 | if (tb[NFCTH_NAME]) |
682 | helper_name = nla_data(tb[NFCTH_NAME]); | 692 | helper_name = nla_data(tb[NFCTH_NAME]); |
683 | 693 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e5afab86381c..e955bec0acc6 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(struct net *net) | |||
1093 | 1093 | ||
1094 | static void __net_exit nfnl_log_net_exit(struct net *net) | 1094 | static void __net_exit nfnl_log_net_exit(struct net *net) |
1095 | { | 1095 | { |
1096 | struct nfnl_log_net *log = nfnl_log_pernet(net); | ||
1097 | unsigned int i; | ||
1098 | |||
1096 | #ifdef CONFIG_PROC_FS | 1099 | #ifdef CONFIG_PROC_FS |
1097 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); | 1100 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); |
1098 | #endif | 1101 | #endif |
1099 | nf_log_unset(net, &nfulnl_logger); | 1102 | nf_log_unset(net, &nfulnl_logger); |
1103 | for (i = 0; i < INSTANCE_BUCKETS; i++) | ||
1104 | WARN_ON_ONCE(!hlist_empty(&log->instance_table[i])); | ||
1100 | } | 1105 | } |
1101 | 1106 | ||
1102 | static struct pernet_operations nfnl_log_net_ops = { | 1107 | static struct pernet_operations nfnl_log_net_ops = { |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a16356cacec3..c09b36755ed7 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_init(struct net *net) | |||
1512 | 1512 | ||
1513 | static void __net_exit nfnl_queue_net_exit(struct net *net) | 1513 | static void __net_exit nfnl_queue_net_exit(struct net *net) |
1514 | { | 1514 | { |
1515 | struct nfnl_queue_net *q = nfnl_queue_pernet(net); | ||
1516 | unsigned int i; | ||
1517 | |||
1515 | nf_unregister_queue_handler(net); | 1518 | nf_unregister_queue_handler(net); |
1516 | #ifdef CONFIG_PROC_FS | 1519 | #ifdef CONFIG_PROC_FS |
1517 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); | 1520 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); |
1518 | #endif | 1521 | #endif |
1522 | for (i = 0; i < INSTANCE_BUCKETS; i++) | ||
1523 | WARN_ON_ONCE(!hlist_empty(&q->instance_table[i])); | ||
1519 | } | 1524 | } |
1520 | 1525 | ||
1521 | static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) | 1526 | static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) |
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index a0a93d987a3b..47ec1046ad11 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c | |||
@@ -214,6 +214,8 @@ static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { | |||
214 | [NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 }, | 214 | [NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 }, |
215 | [NFTA_EXTHDR_LEN] = { .type = NLA_U32 }, | 215 | [NFTA_EXTHDR_LEN] = { .type = NLA_U32 }, |
216 | [NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 }, | 216 | [NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 }, |
217 | [NFTA_EXTHDR_OP] = { .type = NLA_U32 }, | ||
218 | [NFTA_EXTHDR_SREG] = { .type = NLA_U32 }, | ||
217 | }; | 219 | }; |
218 | 220 | ||
219 | static int nft_exthdr_init(const struct nft_ctx *ctx, | 221 | static int nft_exthdr_init(const struct nft_ctx *ctx, |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index a77dd514297c..55802e97f906 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -1729,8 +1729,17 @@ static int __net_init xt_net_init(struct net *net) | |||
1729 | return 0; | 1729 | return 0; |
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | static void __net_exit xt_net_exit(struct net *net) | ||
1733 | { | ||
1734 | int i; | ||
1735 | |||
1736 | for (i = 0; i < NFPROTO_NUMPROTO; i++) | ||
1737 | WARN_ON_ONCE(!list_empty(&net->xt.tables[i])); | ||
1738 | } | ||
1739 | |||
1732 | static struct pernet_operations xt_net_ops = { | 1740 | static struct pernet_operations xt_net_ops = { |
1733 | .init = xt_net_init, | 1741 | .init = xt_net_init, |
1742 | .exit = xt_net_exit, | ||
1734 | }; | 1743 | }; |
1735 | 1744 | ||
1736 | static int __init xt_init(void) | 1745 | static int __init xt_init(void) |
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 041da0d9c06f..1f7fbd3c7e5a 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c | |||
@@ -27,6 +27,9 @@ static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len, | |||
27 | { | 27 | { |
28 | struct sock_fprog_kern program; | 28 | struct sock_fprog_kern program; |
29 | 29 | ||
30 | if (len > XT_BPF_MAX_NUM_INSTR) | ||
31 | return -EINVAL; | ||
32 | |||
30 | program.len = len; | 33 | program.len = len; |
31 | program.filter = insns; | 34 | program.filter = insns; |
32 | 35 | ||
@@ -55,6 +58,9 @@ static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret) | |||
55 | mm_segment_t oldfs = get_fs(); | 58 | mm_segment_t oldfs = get_fs(); |
56 | int retval, fd; | 59 | int retval, fd; |
57 | 60 | ||
61 | if (strnlen(path, XT_BPF_PATH_MAX) == XT_BPF_PATH_MAX) | ||
62 | return -EINVAL; | ||
63 | |||
58 | set_fs(KERNEL_DS); | 64 | set_fs(KERNEL_DS); |
59 | fd = bpf_obj_get_user(path, 0); | 65 | fd = bpf_obj_get_user(path, 0); |
60 | set_fs(oldfs); | 66 | set_fs(oldfs); |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 36e14b1f061d..a34f314a8c23 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | 21 | ||
22 | #include <linux/capability.h> | ||
22 | #include <linux/if.h> | 23 | #include <linux/if.h> |
23 | #include <linux/inetdevice.h> | 24 | #include <linux/inetdevice.h> |
24 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
@@ -70,6 +71,9 @@ static int xt_osf_add_callback(struct net *net, struct sock *ctnl, | |||
70 | struct xt_osf_finger *kf = NULL, *sf; | 71 | struct xt_osf_finger *kf = NULL, *sf; |
71 | int err = 0; | 72 | int err = 0; |
72 | 73 | ||
74 | if (!capable(CAP_NET_ADMIN)) | ||
75 | return -EPERM; | ||
76 | |||
73 | if (!osf_attrs[OSF_ATTR_FINGER]) | 77 | if (!osf_attrs[OSF_ATTR_FINGER]) |
74 | return -EINVAL; | 78 | return -EINVAL; |
75 | 79 | ||
@@ -115,6 +119,9 @@ static int xt_osf_remove_callback(struct net *net, struct sock *ctnl, | |||
115 | struct xt_osf_finger *sf; | 119 | struct xt_osf_finger *sf; |
116 | int err = -ENOENT; | 120 | int err = -ENOENT; |
117 | 121 | ||
122 | if (!capable(CAP_NET_ADMIN)) | ||
123 | return -EPERM; | ||
124 | |||
118 | if (!osf_attrs[OSF_ATTR_FINGER]) | 125 | if (!osf_attrs[OSF_ATTR_FINGER]) |
119 | return -EINVAL; | 126 | return -EINVAL; |
120 | 127 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index b9e0ee4e22f5..79cc1bf36e4a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -253,6 +253,9 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb, | |||
253 | struct sock *sk = skb->sk; | 253 | struct sock *sk = skb->sk; |
254 | int ret = -ENOMEM; | 254 | int ret = -ENOMEM; |
255 | 255 | ||
256 | if (!net_eq(dev_net(dev), sock_net(sk))) | ||
257 | return 0; | ||
258 | |||
256 | dev_hold(dev); | 259 | dev_hold(dev); |
257 | 260 | ||
258 | if (is_vmalloc_addr(skb->head)) | 261 | if (is_vmalloc_addr(skb->head)) |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index dbe2379329c5..f039064ce922 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -579,6 +579,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
579 | return -EINVAL; | 579 | return -EINVAL; |
580 | 580 | ||
581 | skb_reset_network_header(skb); | 581 | skb_reset_network_header(skb); |
582 | key->eth.type = skb->protocol; | ||
582 | } else { | 583 | } else { |
583 | eth = eth_hdr(skb); | 584 | eth = eth_hdr(skb); |
584 | ether_addr_copy(key->eth.src, eth->h_source); | 585 | ether_addr_copy(key->eth.src, eth->h_source); |
@@ -592,15 +593,23 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
592 | if (unlikely(parse_vlan(skb, key))) | 593 | if (unlikely(parse_vlan(skb, key))) |
593 | return -ENOMEM; | 594 | return -ENOMEM; |
594 | 595 | ||
595 | skb->protocol = parse_ethertype(skb); | 596 | key->eth.type = parse_ethertype(skb); |
596 | if (unlikely(skb->protocol == htons(0))) | 597 | if (unlikely(key->eth.type == htons(0))) |
597 | return -ENOMEM; | 598 | return -ENOMEM; |
598 | 599 | ||
600 | /* Multiple tagged packets need to retain TPID to satisfy | ||
601 | * skb_vlan_pop(), which will later shift the ethertype into | ||
602 | * skb->protocol. | ||
603 | */ | ||
604 | if (key->eth.cvlan.tci & htons(VLAN_TAG_PRESENT)) | ||
605 | skb->protocol = key->eth.cvlan.tpid; | ||
606 | else | ||
607 | skb->protocol = key->eth.type; | ||
608 | |||
599 | skb_reset_network_header(skb); | 609 | skb_reset_network_header(skb); |
600 | __skb_push(skb, skb->data - skb_mac_header(skb)); | 610 | __skb_push(skb, skb->data - skb_mac_header(skb)); |
601 | } | 611 | } |
602 | skb_reset_mac_len(skb); | 612 | skb_reset_mac_len(skb); |
603 | key->eth.type = skb->protocol; | ||
604 | 613 | ||
605 | /* Network layer. */ | 614 | /* Network layer. */ |
606 | if (key->eth.type == htons(ETH_P_IP)) { | 615 | if (key->eth.type == htons(ETH_P_IP)) { |
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 8886f15abe90..bc2f1e0977d6 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -183,7 +183,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, | |||
183 | long i; | 183 | long i; |
184 | int ret; | 184 | int ret; |
185 | 185 | ||
186 | if (rs->rs_bound_addr == 0) { | 186 | if (rs->rs_bound_addr == 0 || !rs->rs_transport) { |
187 | ret = -ENOTCONN; /* XXX not a great errno */ | 187 | ret = -ENOTCONN; /* XXX not a great errno */ |
188 | goto out; | 188 | goto out; |
189 | } | 189 | } |
diff --git a/net/rds/send.c b/net/rds/send.c index b52cdc8ae428..f72466c63f0c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1009,6 +1009,9 @@ static int rds_rdma_bytes(struct msghdr *msg, size_t *rdma_bytes) | |||
1009 | continue; | 1009 | continue; |
1010 | 1010 | ||
1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { | 1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { |
1012 | if (cmsg->cmsg_len < | ||
1013 | CMSG_LEN(sizeof(struct rds_rdma_args))) | ||
1014 | return -EINVAL; | ||
1012 | args = CMSG_DATA(cmsg); | 1015 | args = CMSG_DATA(cmsg); |
1013 | *rdma_bytes += args->remote_vec.bytes; | 1016 | *rdma_bytes += args->remote_vec.bytes; |
1014 | } | 1017 | } |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 8f7cf4c042be..dcd818fa837e 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -860,6 +860,7 @@ static void rxrpc_sock_destructor(struct sock *sk) | |||
860 | static int rxrpc_release_sock(struct sock *sk) | 860 | static int rxrpc_release_sock(struct sock *sk) |
861 | { | 861 | { |
862 | struct rxrpc_sock *rx = rxrpc_sk(sk); | 862 | struct rxrpc_sock *rx = rxrpc_sk(sk); |
863 | struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk)); | ||
863 | 864 | ||
864 | _enter("%p{%d,%d}", sk, sk->sk_state, refcount_read(&sk->sk_refcnt)); | 865 | _enter("%p{%d,%d}", sk, sk->sk_state, refcount_read(&sk->sk_refcnt)); |
865 | 866 | ||
@@ -895,8 +896,8 @@ static int rxrpc_release_sock(struct sock *sk) | |||
895 | rxrpc_release_calls_on_socket(rx); | 896 | rxrpc_release_calls_on_socket(rx); |
896 | flush_workqueue(rxrpc_workqueue); | 897 | flush_workqueue(rxrpc_workqueue); |
897 | rxrpc_purge_queue(&sk->sk_receive_queue); | 898 | rxrpc_purge_queue(&sk->sk_receive_queue); |
898 | rxrpc_queue_work(&rx->local->rxnet->service_conn_reaper); | 899 | rxrpc_queue_work(&rxnet->service_conn_reaper); |
899 | rxrpc_queue_work(&rx->local->rxnet->client_conn_reaper); | 900 | rxrpc_queue_work(&rxnet->client_conn_reaper); |
900 | 901 | ||
901 | rxrpc_put_local(rx->local); | 902 | rxrpc_put_local(rx->local); |
902 | rx->local = NULL; | 903 | rx->local = NULL; |
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index bda952ffe6a6..ad2ab1103189 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c | |||
@@ -123,7 +123,7 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | |||
123 | else | 123 | else |
124 | ack_at = expiry; | 124 | ack_at = expiry; |
125 | 125 | ||
126 | ack_at = jiffies + expiry; | 126 | ack_at += now; |
127 | if (time_before(ack_at, call->ack_at)) { | 127 | if (time_before(ack_at, call->ack_at)) { |
128 | WRITE_ONCE(call->ack_at, ack_at); | 128 | WRITE_ONCE(call->ack_at, ack_at); |
129 | rxrpc_reduce_call_timer(call, ack_at, now, | 129 | rxrpc_reduce_call_timer(call, ack_at, now, |
@@ -426,7 +426,7 @@ recheck_state: | |||
426 | next = call->expect_rx_by; | 426 | next = call->expect_rx_by; |
427 | 427 | ||
428 | #define set(T) { t = READ_ONCE(T); if (time_before(t, next)) next = t; } | 428 | #define set(T) { t = READ_ONCE(T); if (time_before(t, next)) next = t; } |
429 | 429 | ||
430 | set(call->expect_req_by); | 430 | set(call->expect_req_by); |
431 | set(call->expect_term_by); | 431 | set(call->expect_term_by); |
432 | set(call->ack_at); | 432 | set(call->ack_at); |
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 9e9a8db1bc9c..4ca11be6be3c 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c | |||
@@ -30,22 +30,18 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
30 | struct rxrpc_skb_priv *sp = skb ? rxrpc_skb(skb) : NULL; | 30 | struct rxrpc_skb_priv *sp = skb ? rxrpc_skb(skb) : NULL; |
31 | struct rxrpc_channel *chan; | 31 | struct rxrpc_channel *chan; |
32 | struct msghdr msg; | 32 | struct msghdr msg; |
33 | struct kvec iov; | 33 | struct kvec iov[3]; |
34 | struct { | 34 | struct { |
35 | struct rxrpc_wire_header whdr; | 35 | struct rxrpc_wire_header whdr; |
36 | union { | 36 | union { |
37 | struct { | 37 | __be32 abort_code; |
38 | __be32 code; | 38 | struct rxrpc_ackpacket ack; |
39 | } abort; | ||
40 | struct { | ||
41 | struct rxrpc_ackpacket ack; | ||
42 | u8 padding[3]; | ||
43 | struct rxrpc_ackinfo info; | ||
44 | }; | ||
45 | }; | 39 | }; |
46 | } __attribute__((packed)) pkt; | 40 | } __attribute__((packed)) pkt; |
41 | struct rxrpc_ackinfo ack_info; | ||
47 | size_t len; | 42 | size_t len; |
48 | u32 serial, mtu, call_id; | 43 | int ioc; |
44 | u32 serial, mtu, call_id, padding; | ||
49 | 45 | ||
50 | _enter("%d", conn->debug_id); | 46 | _enter("%d", conn->debug_id); |
51 | 47 | ||
@@ -66,6 +62,13 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
66 | msg.msg_controllen = 0; | 62 | msg.msg_controllen = 0; |
67 | msg.msg_flags = 0; | 63 | msg.msg_flags = 0; |
68 | 64 | ||
65 | iov[0].iov_base = &pkt; | ||
66 | iov[0].iov_len = sizeof(pkt.whdr); | ||
67 | iov[1].iov_base = &padding; | ||
68 | iov[1].iov_len = 3; | ||
69 | iov[2].iov_base = &ack_info; | ||
70 | iov[2].iov_len = sizeof(ack_info); | ||
71 | |||
69 | pkt.whdr.epoch = htonl(conn->proto.epoch); | 72 | pkt.whdr.epoch = htonl(conn->proto.epoch); |
70 | pkt.whdr.cid = htonl(conn->proto.cid); | 73 | pkt.whdr.cid = htonl(conn->proto.cid); |
71 | pkt.whdr.callNumber = htonl(call_id); | 74 | pkt.whdr.callNumber = htonl(call_id); |
@@ -80,8 +83,10 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
80 | len = sizeof(pkt.whdr); | 83 | len = sizeof(pkt.whdr); |
81 | switch (chan->last_type) { | 84 | switch (chan->last_type) { |
82 | case RXRPC_PACKET_TYPE_ABORT: | 85 | case RXRPC_PACKET_TYPE_ABORT: |
83 | pkt.abort.code = htonl(chan->last_abort); | 86 | pkt.abort_code = htonl(chan->last_abort); |
84 | len += sizeof(pkt.abort); | 87 | iov[0].iov_len += sizeof(pkt.abort_code); |
88 | len += sizeof(pkt.abort_code); | ||
89 | ioc = 1; | ||
85 | break; | 90 | break; |
86 | 91 | ||
87 | case RXRPC_PACKET_TYPE_ACK: | 92 | case RXRPC_PACKET_TYPE_ACK: |
@@ -94,13 +99,19 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
94 | pkt.ack.serial = htonl(skb ? sp->hdr.serial : 0); | 99 | pkt.ack.serial = htonl(skb ? sp->hdr.serial : 0); |
95 | pkt.ack.reason = skb ? RXRPC_ACK_DUPLICATE : RXRPC_ACK_IDLE; | 100 | pkt.ack.reason = skb ? RXRPC_ACK_DUPLICATE : RXRPC_ACK_IDLE; |
96 | pkt.ack.nAcks = 0; | 101 | pkt.ack.nAcks = 0; |
97 | pkt.info.rxMTU = htonl(rxrpc_rx_mtu); | 102 | ack_info.rxMTU = htonl(rxrpc_rx_mtu); |
98 | pkt.info.maxMTU = htonl(mtu); | 103 | ack_info.maxMTU = htonl(mtu); |
99 | pkt.info.rwind = htonl(rxrpc_rx_window_size); | 104 | ack_info.rwind = htonl(rxrpc_rx_window_size); |
100 | pkt.info.jumbo_max = htonl(rxrpc_rx_jumbo_max); | 105 | ack_info.jumbo_max = htonl(rxrpc_rx_jumbo_max); |
101 | pkt.whdr.flags |= RXRPC_SLOW_START_OK; | 106 | pkt.whdr.flags |= RXRPC_SLOW_START_OK; |
102 | len += sizeof(pkt.ack) + sizeof(pkt.info); | 107 | padding = 0; |
108 | iov[0].iov_len += sizeof(pkt.ack); | ||
109 | len += sizeof(pkt.ack) + 3 + sizeof(ack_info); | ||
110 | ioc = 3; | ||
103 | break; | 111 | break; |
112 | |||
113 | default: | ||
114 | return; | ||
104 | } | 115 | } |
105 | 116 | ||
106 | /* Resync with __rxrpc_disconnect_call() and check that the last call | 117 | /* Resync with __rxrpc_disconnect_call() and check that the last call |
@@ -110,9 +121,6 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
110 | if (READ_ONCE(chan->last_call) != call_id) | 121 | if (READ_ONCE(chan->last_call) != call_id) |
111 | return; | 122 | return; |
112 | 123 | ||
113 | iov.iov_base = &pkt; | ||
114 | iov.iov_len = len; | ||
115 | |||
116 | serial = atomic_inc_return(&conn->serial); | 124 | serial = atomic_inc_return(&conn->serial); |
117 | pkt.whdr.serial = htonl(serial); | 125 | pkt.whdr.serial = htonl(serial); |
118 | 126 | ||
@@ -127,7 +135,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
127 | break; | 135 | break; |
128 | } | 136 | } |
129 | 137 | ||
130 | kernel_sendmsg(conn->params.local->socket, &msg, &iov, 1, len); | 138 | kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len); |
131 | _leave(""); | 139 | _leave(""); |
132 | return; | 140 | return; |
133 | } | 141 | } |
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 1aad04a32d5e..c628351eb900 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c | |||
@@ -424,7 +424,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work) | |||
424 | if (earliest != now + MAX_JIFFY_OFFSET) { | 424 | if (earliest != now + MAX_JIFFY_OFFSET) { |
425 | _debug("reschedule reaper %ld", (long)earliest - (long)now); | 425 | _debug("reschedule reaper %ld", (long)earliest - (long)now); |
426 | ASSERT(time_after(earliest, now)); | 426 | ASSERT(time_after(earliest, now)); |
427 | rxrpc_set_service_reap_timer(rxnet, earliest); | 427 | rxrpc_set_service_reap_timer(rxnet, earliest); |
428 | } | 428 | } |
429 | 429 | ||
430 | while (!list_empty(&graveyard)) { | 430 | while (!list_empty(&graveyard)) { |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 23a5e61d8f79..6fc61400337f 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
@@ -976,7 +976,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call, | |||
976 | rxrpc_reduce_call_timer(call, expect_rx_by, now, | 976 | rxrpc_reduce_call_timer(call, expect_rx_by, now, |
977 | rxrpc_timer_set_for_normal); | 977 | rxrpc_timer_set_for_normal); |
978 | } | 978 | } |
979 | 979 | ||
980 | switch (sp->hdr.type) { | 980 | switch (sp->hdr.type) { |
981 | case RXRPC_PACKET_TYPE_DATA: | 981 | case RXRPC_PACKET_TYPE_DATA: |
982 | rxrpc_input_data(call, skb, skew); | 982 | rxrpc_input_data(call, skb, skew); |
@@ -1213,7 +1213,7 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1213 | goto reupgrade; | 1213 | goto reupgrade; |
1214 | conn->service_id = sp->hdr.serviceId; | 1214 | conn->service_id = sp->hdr.serviceId; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | if (sp->hdr.callNumber == 0) { | 1217 | if (sp->hdr.callNumber == 0) { |
1218 | /* Connection-level packet */ | 1218 | /* Connection-level packet */ |
1219 | _debug("CONN %p {%d}", conn, conn->debug_id); | 1219 | _debug("CONN %p {%d}", conn, conn->debug_id); |
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index a1c53ac066a1..09f2a3e05221 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
@@ -233,7 +233,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | |||
233 | if (resend_at < 1) | 233 | if (resend_at < 1) |
234 | resend_at = 1; | 234 | resend_at = 1; |
235 | 235 | ||
236 | resend_at = now + rxrpc_resend_timeout; | 236 | resend_at += now; |
237 | WRITE_ONCE(call->resend_at, resend_at); | 237 | WRITE_ONCE(call->resend_at, resend_at); |
238 | rxrpc_reduce_call_timer(call, resend_at, now, | 238 | rxrpc_reduce_call_timer(call, resend_at, now, |
239 | rxrpc_timer_set_for_send); | 239 | rxrpc_timer_set_for_send); |
diff --git a/net/sched/act_meta_mark.c b/net/sched/act_meta_mark.c index 1e3f10e5da99..6445184b2759 100644 --- a/net/sched/act_meta_mark.c +++ b/net/sched/act_meta_mark.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
23 | #include <uapi/linux/tc_act/tc_ife.h> | 23 | #include <uapi/linux/tc_act/tc_ife.h> |
24 | #include <net/tc_act/tc_ife.h> | 24 | #include <net/tc_act/tc_ife.h> |
25 | #include <linux/rtnetlink.h> | ||
26 | 25 | ||
27 | static int skbmark_encode(struct sk_buff *skb, void *skbdata, | 26 | static int skbmark_encode(struct sk_buff *skb, void *skbdata, |
28 | struct tcf_meta_info *e) | 27 | struct tcf_meta_info *e) |
diff --git a/net/sched/act_meta_skbtcindex.c b/net/sched/act_meta_skbtcindex.c index 2ea1f26c9e96..7221437ca3a6 100644 --- a/net/sched/act_meta_skbtcindex.c +++ b/net/sched/act_meta_skbtcindex.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
23 | #include <uapi/linux/tc_act/tc_ife.h> | 23 | #include <uapi/linux/tc_act/tc_ife.h> |
24 | #include <net/tc_act/tc_ife.h> | 24 | #include <net/tc_act/tc_ife.h> |
25 | #include <linux/rtnetlink.h> | ||
26 | 25 | ||
27 | static int skbtcindex_encode(struct sk_buff *skb, void *skbdata, | 26 | static int skbtcindex_encode(struct sk_buff *skb, void *skbdata, |
28 | struct tcf_meta_info *e) | 27 | struct tcf_meta_info *e) |
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 8b5abcd2f32f..9438969290a6 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c | |||
@@ -96,23 +96,16 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, | |||
96 | return ret; | 96 | return ret; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void tcf_sample_cleanup_rcu(struct rcu_head *rcu) | 99 | static void tcf_sample_cleanup(struct tc_action *a, int bind) |
100 | { | 100 | { |
101 | struct tcf_sample *s = container_of(rcu, struct tcf_sample, rcu); | 101 | struct tcf_sample *s = to_sample(a); |
102 | struct psample_group *psample_group; | 102 | struct psample_group *psample_group; |
103 | 103 | ||
104 | psample_group = rcu_dereference_protected(s->psample_group, 1); | 104 | psample_group = rtnl_dereference(s->psample_group); |
105 | RCU_INIT_POINTER(s->psample_group, NULL); | 105 | RCU_INIT_POINTER(s->psample_group, NULL); |
106 | psample_group_put(psample_group); | 106 | psample_group_put(psample_group); |
107 | } | 107 | } |
108 | 108 | ||
109 | static void tcf_sample_cleanup(struct tc_action *a, int bind) | ||
110 | { | ||
111 | struct tcf_sample *s = to_sample(a); | ||
112 | |||
113 | call_rcu(&s->rcu, tcf_sample_cleanup_rcu); | ||
114 | } | ||
115 | |||
116 | static bool tcf_sample_dev_ok_push(struct net_device *dev) | 109 | static bool tcf_sample_dev_ok_push(struct net_device *dev) |
117 | { | 110 | { |
118 | switch (dev->type) { | 111 | switch (dev->type) { |
@@ -264,7 +257,6 @@ static int __init sample_init_module(void) | |||
264 | 257 | ||
265 | static void __exit sample_cleanup_module(void) | 258 | static void __exit sample_cleanup_module(void) |
266 | { | 259 | { |
267 | rcu_barrier(); | ||
268 | tcf_unregister_action(&act_sample_ops, &sample_net_ops); | 260 | tcf_unregister_action(&act_sample_ops, &sample_net_ops); |
269 | } | 261 | } |
270 | 262 | ||
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index ddcf04b4ab43..b9d63d2246e6 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/kmod.h> | 25 | #include <linux/kmod.h> |
26 | #include <linux/err.h> | ||
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <net/net_namespace.h> | 27 | #include <net/net_namespace.h> |
29 | #include <net/sock.h> | 28 | #include <net/sock.h> |
@@ -352,6 +351,8 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, | |||
352 | { | 351 | { |
353 | struct tcf_chain *chain; | 352 | struct tcf_chain *chain; |
354 | 353 | ||
354 | if (!block) | ||
355 | return; | ||
355 | /* Hold a refcnt for all chains, except 0, so that they don't disappear | 356 | /* Hold a refcnt for all chains, except 0, so that they don't disappear |
356 | * while we are iterating. | 357 | * while we are iterating. |
357 | */ | 358 | */ |
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 6fe798c2df1a..8d78e7f4ecc3 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c | |||
@@ -42,7 +42,6 @@ struct cls_bpf_prog { | |||
42 | struct list_head link; | 42 | struct list_head link; |
43 | struct tcf_result res; | 43 | struct tcf_result res; |
44 | bool exts_integrated; | 44 | bool exts_integrated; |
45 | bool offloaded; | ||
46 | u32 gen_flags; | 45 | u32 gen_flags; |
47 | struct tcf_exts exts; | 46 | struct tcf_exts exts; |
48 | u32 handle; | 47 | u32 handle; |
@@ -148,33 +147,37 @@ static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog) | |||
148 | } | 147 | } |
149 | 148 | ||
150 | static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, | 149 | static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, |
151 | enum tc_clsbpf_command cmd) | 150 | struct cls_bpf_prog *oldprog) |
152 | { | 151 | { |
153 | bool addorrep = cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE; | ||
154 | struct tcf_block *block = tp->chain->block; | 152 | struct tcf_block *block = tp->chain->block; |
155 | bool skip_sw = tc_skip_sw(prog->gen_flags); | ||
156 | struct tc_cls_bpf_offload cls_bpf = {}; | 153 | struct tc_cls_bpf_offload cls_bpf = {}; |
154 | struct cls_bpf_prog *obj; | ||
155 | bool skip_sw; | ||
157 | int err; | 156 | int err; |
158 | 157 | ||
158 | skip_sw = prog && tc_skip_sw(prog->gen_flags); | ||
159 | obj = prog ?: oldprog; | ||
160 | |||
159 | tc_cls_common_offload_init(&cls_bpf.common, tp); | 161 | tc_cls_common_offload_init(&cls_bpf.common, tp); |
160 | cls_bpf.command = cmd; | 162 | cls_bpf.command = TC_CLSBPF_OFFLOAD; |
161 | cls_bpf.exts = &prog->exts; | 163 | cls_bpf.exts = &obj->exts; |
162 | cls_bpf.prog = prog->filter; | 164 | cls_bpf.prog = prog ? prog->filter : NULL; |
163 | cls_bpf.name = prog->bpf_name; | 165 | cls_bpf.oldprog = oldprog ? oldprog->filter : NULL; |
164 | cls_bpf.exts_integrated = prog->exts_integrated; | 166 | cls_bpf.name = obj->bpf_name; |
165 | cls_bpf.gen_flags = prog->gen_flags; | 167 | cls_bpf.exts_integrated = obj->exts_integrated; |
168 | cls_bpf.gen_flags = obj->gen_flags; | ||
166 | 169 | ||
167 | err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw); | 170 | err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw); |
168 | if (addorrep) { | 171 | if (prog) { |
169 | if (err < 0) { | 172 | if (err < 0) { |
170 | cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY); | 173 | cls_bpf_offload_cmd(tp, oldprog, prog); |
171 | return err; | 174 | return err; |
172 | } else if (err > 0) { | 175 | } else if (err > 0) { |
173 | prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; | 176 | prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; |
174 | } | 177 | } |
175 | } | 178 | } |
176 | 179 | ||
177 | if (addorrep && skip_sw && !(prog->gen_flags & TCA_CLS_FLAGS_IN_HW)) | 180 | if (prog && skip_sw && !(prog->gen_flags & TCA_CLS_FLAGS_IN_HW)) |
178 | return -EINVAL; | 181 | return -EINVAL; |
179 | 182 | ||
180 | return 0; | 183 | return 0; |
@@ -183,38 +186,17 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, | |||
183 | static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, | 186 | static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, |
184 | struct cls_bpf_prog *oldprog) | 187 | struct cls_bpf_prog *oldprog) |
185 | { | 188 | { |
186 | struct cls_bpf_prog *obj = prog; | 189 | if (prog && oldprog && prog->gen_flags != oldprog->gen_flags) |
187 | enum tc_clsbpf_command cmd; | 190 | return -EINVAL; |
188 | bool skip_sw; | ||
189 | int ret; | ||
190 | |||
191 | skip_sw = tc_skip_sw(prog->gen_flags) || | ||
192 | (oldprog && tc_skip_sw(oldprog->gen_flags)); | ||
193 | |||
194 | if (oldprog && oldprog->offloaded) { | ||
195 | if (!tc_skip_hw(prog->gen_flags)) { | ||
196 | cmd = TC_CLSBPF_REPLACE; | ||
197 | } else if (!tc_skip_sw(prog->gen_flags)) { | ||
198 | obj = oldprog; | ||
199 | cmd = TC_CLSBPF_DESTROY; | ||
200 | } else { | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | } else { | ||
204 | if (tc_skip_hw(prog->gen_flags)) | ||
205 | return skip_sw ? -EINVAL : 0; | ||
206 | cmd = TC_CLSBPF_ADD; | ||
207 | } | ||
208 | |||
209 | ret = cls_bpf_offload_cmd(tp, obj, cmd); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | 191 | ||
213 | obj->offloaded = true; | 192 | if (prog && tc_skip_hw(prog->gen_flags)) |
214 | if (oldprog) | 193 | prog = NULL; |
215 | oldprog->offloaded = false; | 194 | if (oldprog && tc_skip_hw(oldprog->gen_flags)) |
195 | oldprog = NULL; | ||
196 | if (!prog && !oldprog) | ||
197 | return 0; | ||
216 | 198 | ||
217 | return 0; | 199 | return cls_bpf_offload_cmd(tp, prog, oldprog); |
218 | } | 200 | } |
219 | 201 | ||
220 | static void cls_bpf_stop_offload(struct tcf_proto *tp, | 202 | static void cls_bpf_stop_offload(struct tcf_proto *tp, |
@@ -222,25 +204,26 @@ static void cls_bpf_stop_offload(struct tcf_proto *tp, | |||
222 | { | 204 | { |
223 | int err; | 205 | int err; |
224 | 206 | ||
225 | if (!prog->offloaded) | 207 | err = cls_bpf_offload_cmd(tp, NULL, prog); |
226 | return; | 208 | if (err) |
227 | |||
228 | err = cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY); | ||
229 | if (err) { | ||
230 | pr_err("Stopping hardware offload failed: %d\n", err); | 209 | pr_err("Stopping hardware offload failed: %d\n", err); |
231 | return; | ||
232 | } | ||
233 | |||
234 | prog->offloaded = false; | ||
235 | } | 210 | } |
236 | 211 | ||
237 | static void cls_bpf_offload_update_stats(struct tcf_proto *tp, | 212 | static void cls_bpf_offload_update_stats(struct tcf_proto *tp, |
238 | struct cls_bpf_prog *prog) | 213 | struct cls_bpf_prog *prog) |
239 | { | 214 | { |
240 | if (!prog->offloaded) | 215 | struct tcf_block *block = tp->chain->block; |
241 | return; | 216 | struct tc_cls_bpf_offload cls_bpf = {}; |
217 | |||
218 | tc_cls_common_offload_init(&cls_bpf.common, tp); | ||
219 | cls_bpf.command = TC_CLSBPF_STATS; | ||
220 | cls_bpf.exts = &prog->exts; | ||
221 | cls_bpf.prog = prog->filter; | ||
222 | cls_bpf.name = prog->bpf_name; | ||
223 | cls_bpf.exts_integrated = prog->exts_integrated; | ||
224 | cls_bpf.gen_flags = prog->gen_flags; | ||
242 | 225 | ||
243 | cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_STATS); | 226 | tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, false); |
244 | } | 227 | } |
245 | 228 | ||
246 | static int cls_bpf_init(struct tcf_proto *tp) | 229 | static int cls_bpf_init(struct tcf_proto *tp) |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index ac152b4f4247..507859cdd1cb 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <net/netlink.h> | 45 | #include <net/netlink.h> |
46 | #include <net/act_api.h> | 46 | #include <net/act_api.h> |
47 | #include <net/pkt_cls.h> | 47 | #include <net/pkt_cls.h> |
48 | #include <linux/netdevice.h> | ||
49 | #include <linux/idr.h> | 48 | #include <linux/idr.h> |
50 | 49 | ||
51 | struct tc_u_knode { | 50 | struct tc_u_knode { |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b6c4f536876b..0f1eab99ff4e 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, | |||
795 | tcm->tcm_info = refcount_read(&q->refcnt); | 795 | tcm->tcm_info = refcount_read(&q->refcnt); |
796 | if (nla_put_string(skb, TCA_KIND, q->ops->id)) | 796 | if (nla_put_string(skb, TCA_KIND, q->ops->id)) |
797 | goto nla_put_failure; | 797 | goto nla_put_failure; |
798 | if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED))) | ||
799 | goto nla_put_failure; | ||
798 | if (q->ops->dump && q->ops->dump(q, skb) < 0) | 800 | if (q->ops->dump && q->ops->dump(q, skb) < 0) |
799 | goto nla_put_failure; | 801 | goto nla_put_failure; |
800 | qlen = q->q.qlen; | 802 | qlen = q->q.qlen; |
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index b30a2c70bd48..531250fceb9e 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c | |||
@@ -369,6 +369,9 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt) | |||
369 | 369 | ||
370 | ctl = nla_data(tb[TCA_CHOKE_PARMS]); | 370 | ctl = nla_data(tb[TCA_CHOKE_PARMS]); |
371 | 371 | ||
372 | if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) | ||
373 | return -EINVAL; | ||
374 | |||
372 | if (ctl->limit > CHOKE_MAX_QUEUE) | 375 | if (ctl->limit > CHOKE_MAX_QUEUE) |
373 | return -EINVAL; | 376 | return -EINVAL; |
374 | 377 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 3839cbbdc32b..661c7144b53a 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/if_vlan.h> | 28 | #include <linux/if_vlan.h> |
29 | #include <linux/if_macvlan.h> | ||
29 | #include <net/sch_generic.h> | 30 | #include <net/sch_generic.h> |
30 | #include <net/pkt_sched.h> | 31 | #include <net/pkt_sched.h> |
31 | #include <net/dst.h> | 32 | #include <net/dst.h> |
@@ -277,6 +278,8 @@ unsigned long dev_trans_start(struct net_device *dev) | |||
277 | 278 | ||
278 | if (is_vlan_dev(dev)) | 279 | if (is_vlan_dev(dev)) |
279 | dev = vlan_dev_real_dev(dev); | 280 | dev = vlan_dev_real_dev(dev); |
281 | else if (netif_is_macvlan(dev)) | ||
282 | dev = macvlan_dev_real_dev(dev); | ||
280 | res = netdev_get_tx_queue(dev, 0)->trans_start; | 283 | res = netdev_get_tx_queue(dev, 0)->trans_start; |
281 | for (i = 1; i < dev->num_tx_queues; i++) { | 284 | for (i = 1; i < dev->num_tx_queues; i++) { |
282 | val = netdev_get_tx_queue(dev, i)->trans_start; | 285 | val = netdev_get_tx_queue(dev, i)->trans_start; |
@@ -1037,6 +1040,8 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1037 | 1040 | ||
1038 | if (!tp_head) { | 1041 | if (!tp_head) { |
1039 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); | 1042 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); |
1043 | /* Wait for flying RCU callback before it is freed. */ | ||
1044 | rcu_barrier_bh(); | ||
1040 | return; | 1045 | return; |
1041 | } | 1046 | } |
1042 | 1047 | ||
@@ -1052,7 +1057,7 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1052 | rcu_assign_pointer(*miniqp->p_miniq, miniq); | 1057 | rcu_assign_pointer(*miniqp->p_miniq, miniq); |
1053 | 1058 | ||
1054 | if (miniq_old) | 1059 | if (miniq_old) |
1055 | /* This is counterpart of the rcu barrier above. We need to | 1060 | /* This is counterpart of the rcu barriers above. We need to |
1056 | * block potential new user of miniq_old until all readers | 1061 | * block potential new user of miniq_old until all readers |
1057 | * are not seeing it. | 1062 | * are not seeing it. |
1058 | */ | 1063 | */ |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 17c7130454bd..bc30f9186ac6 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -356,6 +356,9 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, | |||
356 | struct gred_sched *table = qdisc_priv(sch); | 356 | struct gred_sched *table = qdisc_priv(sch); |
357 | struct gred_sched_data *q = table->tab[dp]; | 357 | struct gred_sched_data *q = table->tab[dp]; |
358 | 358 | ||
359 | if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) | ||
360 | return -EINVAL; | ||
361 | |||
359 | if (!q) { | 362 | if (!q) { |
360 | table->tab[dp] = q = *prealloc; | 363 | table->tab[dp] = q = *prealloc; |
361 | *prealloc = NULL; | 364 | *prealloc = NULL; |
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 5ecc38f35d47..fc1286f499c1 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
@@ -68,6 +68,8 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) | |||
68 | struct net_device *dev = qdisc_dev(sch); | 68 | struct net_device *dev = qdisc_dev(sch); |
69 | int err; | 69 | int err; |
70 | 70 | ||
71 | net_inc_ingress_queue(); | ||
72 | |||
71 | mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress); | 73 | mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress); |
72 | 74 | ||
73 | q->block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; | 75 | q->block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; |
@@ -78,7 +80,6 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) | |||
78 | if (err) | 80 | if (err) |
79 | return err; | 81 | return err; |
80 | 82 | ||
81 | net_inc_ingress_queue(); | ||
82 | sch->flags |= TCQ_F_CPUSTATS; | 83 | sch->flags |= TCQ_F_CPUSTATS; |
83 | 84 | ||
84 | return 0; | 85 | return 0; |
@@ -172,6 +173,9 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) | |||
172 | struct net_device *dev = qdisc_dev(sch); | 173 | struct net_device *dev = qdisc_dev(sch); |
173 | int err; | 174 | int err; |
174 | 175 | ||
176 | net_inc_ingress_queue(); | ||
177 | net_inc_egress_queue(); | ||
178 | |||
175 | mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress); | 179 | mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress); |
176 | 180 | ||
177 | q->ingress_block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; | 181 | q->ingress_block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; |
@@ -190,18 +194,11 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) | |||
190 | 194 | ||
191 | err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); | 195 | err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); |
192 | if (err) | 196 | if (err) |
193 | goto err_egress_block_get; | 197 | return err; |
194 | |||
195 | net_inc_ingress_queue(); | ||
196 | net_inc_egress_queue(); | ||
197 | 198 | ||
198 | sch->flags |= TCQ_F_CPUSTATS; | 199 | sch->flags |= TCQ_F_CPUSTATS; |
199 | 200 | ||
200 | return 0; | 201 | return 0; |
201 | |||
202 | err_egress_block_get: | ||
203 | tcf_block_put_ext(q->ingress_block, sch, &q->ingress_block_info); | ||
204 | return err; | ||
205 | } | 202 | } |
206 | 203 | ||
207 | static void clsact_destroy(struct Qdisc *sch) | 204 | static void clsact_destroy(struct Qdisc *sch) |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 7f8ea9e297c3..f0747eb87dc4 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable) | |||
157 | .handle = sch->handle, | 157 | .handle = sch->handle, |
158 | .parent = sch->parent, | 158 | .parent = sch->parent, |
159 | }; | 159 | }; |
160 | int err; | ||
160 | 161 | ||
161 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) | 162 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) |
162 | return -EOPNOTSUPP; | 163 | return -EOPNOTSUPP; |
@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable) | |||
171 | opt.command = TC_RED_DESTROY; | 172 | opt.command = TC_RED_DESTROY; |
172 | } | 173 | } |
173 | 174 | ||
174 | return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt); | 175 | err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt); |
176 | |||
177 | if (!err && enable) | ||
178 | sch->flags |= TCQ_F_OFFLOADED; | ||
179 | else | ||
180 | sch->flags &= ~TCQ_F_OFFLOADED; | ||
181 | |||
182 | return err; | ||
175 | } | 183 | } |
176 | 184 | ||
177 | static void red_destroy(struct Qdisc *sch) | 185 | static void red_destroy(struct Qdisc *sch) |
@@ -212,6 +220,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
212 | max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; | 220 | max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; |
213 | 221 | ||
214 | ctl = nla_data(tb[TCA_RED_PARMS]); | 222 | ctl = nla_data(tb[TCA_RED_PARMS]); |
223 | if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) | ||
224 | return -EINVAL; | ||
215 | 225 | ||
216 | if (ctl->limit > 0) { | 226 | if (ctl->limit > 0) { |
217 | child = fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit); | 227 | child = fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit); |
@@ -272,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt) | |||
272 | return red_change(sch, opt); | 282 | return red_change(sch, opt); |
273 | } | 283 | } |
274 | 284 | ||
275 | static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) | 285 | static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt) |
276 | { | 286 | { |
277 | struct net_device *dev = qdisc_dev(sch); | 287 | struct net_device *dev = qdisc_dev(sch); |
278 | struct tc_red_qopt_offload hw_stats = { | 288 | struct tc_red_qopt_offload hw_stats = { |
@@ -284,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) | |||
284 | .stats.qstats = &sch->qstats, | 294 | .stats.qstats = &sch->qstats, |
285 | }, | 295 | }, |
286 | }; | 296 | }; |
287 | int err; | ||
288 | 297 | ||
289 | opt->flags &= ~TC_RED_OFFLOADED; | 298 | if (!(sch->flags & TCQ_F_OFFLOADED)) |
290 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) | ||
291 | return 0; | ||
292 | |||
293 | err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, | ||
294 | &hw_stats); | ||
295 | if (err == -EOPNOTSUPP) | ||
296 | return 0; | 299 | return 0; |
297 | 300 | ||
298 | if (!err) | 301 | return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, |
299 | opt->flags |= TC_RED_OFFLOADED; | 302 | &hw_stats); |
300 | |||
301 | return err; | ||
302 | } | 303 | } |
303 | 304 | ||
304 | static int red_dump(struct Qdisc *sch, struct sk_buff *skb) | 305 | static int red_dump(struct Qdisc *sch, struct sk_buff *skb) |
@@ -317,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
317 | int err; | 318 | int err; |
318 | 319 | ||
319 | sch->qstats.backlog = q->qdisc->qstats.backlog; | 320 | sch->qstats.backlog = q->qdisc->qstats.backlog; |
320 | err = red_dump_offload(sch, &opt); | 321 | err = red_dump_offload_stats(sch, &opt); |
321 | if (err) | 322 | if (err) |
322 | goto nla_put_failure; | 323 | goto nla_put_failure; |
323 | 324 | ||
@@ -345,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d) | |||
345 | .marked = q->stats.prob_mark + q->stats.forced_mark, | 346 | .marked = q->stats.prob_mark + q->stats.forced_mark, |
346 | }; | 347 | }; |
347 | 348 | ||
348 | if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) { | 349 | if (sch->flags & TCQ_F_OFFLOADED) { |
349 | struct red_stats hw_stats = {0}; | 350 | struct red_stats hw_stats = {0}; |
350 | struct tc_red_qopt_offload hw_stats_request = { | 351 | struct tc_red_qopt_offload hw_stats_request = { |
351 | .command = TC_RED_XSTATS, | 352 | .command = TC_RED_XSTATS, |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 09c1203c1711..930e5bd26d3d 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -639,6 +639,9 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) | |||
639 | if (ctl->divisor && | 639 | if (ctl->divisor && |
640 | (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) | 640 | (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) |
641 | return -EINVAL; | 641 | return -EINVAL; |
642 | if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, | ||
643 | ctl_v1->Wlog)) | ||
644 | return -EINVAL; | ||
642 | if (ctl_v1 && ctl_v1->qth_min) { | 645 | if (ctl_v1 && ctl_v1->qth_min) { |
643 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 646 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
644 | if (!p) | 647 | if (!p) |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 7b261afc47b9..7f8baa48e7c2 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) | |||
53 | msg->send_failed = 0; | 53 | msg->send_failed = 0; |
54 | msg->send_error = 0; | 54 | msg->send_error = 0; |
55 | msg->can_delay = 1; | 55 | msg->can_delay = 1; |
56 | msg->abandoned = 0; | ||
56 | msg->expires_at = 0; | 57 | msg->expires_at = 0; |
57 | INIT_LIST_HEAD(&msg->chunks); | 58 | INIT_LIST_HEAD(&msg->chunks); |
58 | } | 59 | } |
@@ -304,6 +305,13 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) | |||
304 | if (!chunk->asoc->peer.prsctp_capable) | 305 | if (!chunk->asoc->peer.prsctp_capable) |
305 | return 0; | 306 | return 0; |
306 | 307 | ||
308 | if (chunk->msg->abandoned) | ||
309 | return 1; | ||
310 | |||
311 | if (!chunk->has_tsn && | ||
312 | !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG)) | ||
313 | return 0; | ||
314 | |||
307 | if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && | 315 | if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && |
308 | time_after(jiffies, chunk->msg->expires_at)) { | 316 | time_after(jiffies, chunk->msg->expires_at)) { |
309 | struct sctp_stream_out *streamout = | 317 | struct sctp_stream_out *streamout = |
@@ -316,6 +324,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) | |||
316 | chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; | 324 | chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; |
317 | streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; | 325 | streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; |
318 | } | 326 | } |
327 | chunk->msg->abandoned = 1; | ||
319 | return 1; | 328 | return 1; |
320 | } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && | 329 | } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && |
321 | chunk->sent_count > chunk->sinfo.sinfo_timetolive) { | 330 | chunk->sent_count > chunk->sinfo.sinfo_timetolive) { |
@@ -324,10 +333,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) | |||
324 | 333 | ||
325 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; | 334 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; |
326 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; | 335 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; |
336 | chunk->msg->abandoned = 1; | ||
327 | return 1; | 337 | return 1; |
328 | } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) && | 338 | } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) && |
329 | chunk->msg->expires_at && | 339 | chunk->msg->expires_at && |
330 | time_after(jiffies, chunk->msg->expires_at)) { | 340 | time_after(jiffies, chunk->msg->expires_at)) { |
341 | chunk->msg->abandoned = 1; | ||
331 | return 1; | 342 | return 1; |
332 | } | 343 | } |
333 | /* PRIO policy is processed by sendmsg, not here */ | 344 | /* PRIO policy is processed by sendmsg, not here */ |
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index 3f619fdcbf0a..291c97b07058 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
@@ -78,6 +78,9 @@ const char *sctp_cname(const union sctp_subtype cid) | |||
78 | case SCTP_CID_AUTH: | 78 | case SCTP_CID_AUTH: |
79 | return "AUTH"; | 79 | return "AUTH"; |
80 | 80 | ||
81 | case SCTP_CID_RECONF: | ||
82 | return "RECONF"; | ||
83 | |||
81 | default: | 84 | default: |
82 | break; | 85 | break; |
83 | } | 86 | } |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 4db012aa25f7..7d67feeeffc1 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -364,10 +364,12 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, | |||
364 | list_for_each_entry_safe(chk, temp, queue, transmitted_list) { | 364 | list_for_each_entry_safe(chk, temp, queue, transmitted_list) { |
365 | struct sctp_stream_out *streamout; | 365 | struct sctp_stream_out *streamout; |
366 | 366 | ||
367 | if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | 367 | if (!chk->msg->abandoned && |
368 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) | 368 | (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || |
369 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) | ||
369 | continue; | 370 | continue; |
370 | 371 | ||
372 | chk->msg->abandoned = 1; | ||
371 | list_del_init(&chk->transmitted_list); | 373 | list_del_init(&chk->transmitted_list); |
372 | sctp_insert_list(&asoc->outqueue.abandoned, | 374 | sctp_insert_list(&asoc->outqueue.abandoned, |
373 | &chk->transmitted_list); | 375 | &chk->transmitted_list); |
@@ -377,7 +379,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, | |||
377 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 379 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
378 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 380 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
379 | 381 | ||
380 | if (!chk->tsn_gap_acked) { | 382 | if (queue != &asoc->outqueue.retransmit && |
383 | !chk->tsn_gap_acked) { | ||
381 | if (chk->transport) | 384 | if (chk->transport) |
382 | chk->transport->flight_size -= | 385 | chk->transport->flight_size -= |
383 | sctp_data_size(chk); | 386 | sctp_data_size(chk); |
@@ -403,10 +406,13 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc, | |||
403 | q->sched->unsched_all(&asoc->stream); | 406 | q->sched->unsched_all(&asoc->stream); |
404 | 407 | ||
405 | list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { | 408 | list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { |
406 | if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | 409 | if (!chk->msg->abandoned && |
407 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) | 410 | (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) || |
411 | !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | ||
412 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) | ||
408 | continue; | 413 | continue; |
409 | 414 | ||
415 | chk->msg->abandoned = 1; | ||
410 | sctp_sched_dequeue_common(q, chk); | 416 | sctp_sched_dequeue_common(q, chk); |
411 | asoc->sent_cnt_removable--; | 417 | asoc->sent_cnt_removable--; |
412 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; | 418 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; |
@@ -1434,7 +1440,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1434 | /* If this chunk has not been acked, stop | 1440 | /* If this chunk has not been acked, stop |
1435 | * considering it as 'outstanding'. | 1441 | * considering it as 'outstanding'. |
1436 | */ | 1442 | */ |
1437 | if (!tchunk->tsn_gap_acked) { | 1443 | if (transmitted_queue != &q->retransmit && |
1444 | !tchunk->tsn_gap_acked) { | ||
1438 | if (tchunk->transport) | 1445 | if (tchunk->transport) |
1439 | tchunk->transport->flight_size -= | 1446 | tchunk->transport->flight_size -= |
1440 | sctp_data_size(tchunk); | 1447 | sctp_data_size(tchunk); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 014847e25648..b4fb6e4886d2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3891,13 +3891,17 @@ static int sctp_setsockopt_reset_streams(struct sock *sk, | |||
3891 | struct sctp_association *asoc; | 3891 | struct sctp_association *asoc; |
3892 | int retval = -EINVAL; | 3892 | int retval = -EINVAL; |
3893 | 3893 | ||
3894 | if (optlen < sizeof(struct sctp_reset_streams)) | 3894 | if (optlen < sizeof(*params)) |
3895 | return -EINVAL; | 3895 | return -EINVAL; |
3896 | 3896 | ||
3897 | params = memdup_user(optval, optlen); | 3897 | params = memdup_user(optval, optlen); |
3898 | if (IS_ERR(params)) | 3898 | if (IS_ERR(params)) |
3899 | return PTR_ERR(params); | 3899 | return PTR_ERR(params); |
3900 | 3900 | ||
3901 | if (params->srs_number_streams * sizeof(__u16) > | ||
3902 | optlen - sizeof(*params)) | ||
3903 | goto out; | ||
3904 | |||
3901 | asoc = sctp_id2assoc(sk, params->srs_assoc_id); | 3905 | asoc = sctp_id2assoc(sk, params->srs_assoc_id); |
3902 | if (!asoc) | 3906 | if (!asoc) |
3903 | goto out; | 3907 | goto out; |
@@ -4494,7 +4498,7 @@ static int sctp_init_sock(struct sock *sk) | |||
4494 | SCTP_DBG_OBJCNT_INC(sock); | 4498 | SCTP_DBG_OBJCNT_INC(sock); |
4495 | 4499 | ||
4496 | local_bh_disable(); | 4500 | local_bh_disable(); |
4497 | percpu_counter_inc(&sctp_sockets_allocated); | 4501 | sk_sockets_allocated_inc(sk); |
4498 | sock_prot_inuse_add(net, sk->sk_prot, 1); | 4502 | sock_prot_inuse_add(net, sk->sk_prot, 1); |
4499 | 4503 | ||
4500 | /* Nothing can fail after this block, otherwise | 4504 | /* Nothing can fail after this block, otherwise |
@@ -4538,7 +4542,7 @@ static void sctp_destroy_sock(struct sock *sk) | |||
4538 | } | 4542 | } |
4539 | sctp_endpoint_free(sp->ep); | 4543 | sctp_endpoint_free(sp->ep); |
4540 | local_bh_disable(); | 4544 | local_bh_disable(); |
4541 | percpu_counter_dec(&sctp_sockets_allocated); | 4545 | sk_sockets_allocated_dec(sk); |
4542 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 4546 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
4543 | local_bh_enable(); | 4547 | local_bh_enable(); |
4544 | } | 4548 | } |
@@ -5080,7 +5084,6 @@ static int sctp_getsockopt_peeloff_common(struct sock *sk, sctp_peeloff_arg_t *p | |||
5080 | *newfile = sock_alloc_file(newsock, 0, NULL); | 5084 | *newfile = sock_alloc_file(newsock, 0, NULL); |
5081 | if (IS_ERR(*newfile)) { | 5085 | if (IS_ERR(*newfile)) { |
5082 | put_unused_fd(retval); | 5086 | put_unused_fd(retval); |
5083 | sock_release(newsock); | ||
5084 | retval = PTR_ERR(*newfile); | 5087 | retval = PTR_ERR(*newfile); |
5085 | *newfile = NULL; | 5088 | *newfile = NULL; |
5086 | return retval; | 5089 | return retval; |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index a71be33f3afe..e36ec5dd64c6 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -1084,29 +1084,21 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, | |||
1084 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | 1084 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, |
1085 | gfp_t gfp) | 1085 | gfp_t gfp) |
1086 | { | 1086 | { |
1087 | struct sctp_association *asoc; | 1087 | struct sctp_association *asoc = ulpq->asoc; |
1088 | __u16 needed, freed; | 1088 | __u32 freed = 0; |
1089 | 1089 | __u16 needed; | |
1090 | asoc = ulpq->asoc; | ||
1091 | 1090 | ||
1092 | if (chunk) { | 1091 | needed = ntohs(chunk->chunk_hdr->length) - |
1093 | needed = ntohs(chunk->chunk_hdr->length); | 1092 | sizeof(struct sctp_data_chunk); |
1094 | needed -= sizeof(struct sctp_data_chunk); | ||
1095 | } else | ||
1096 | needed = SCTP_DEFAULT_MAXWINDOW; | ||
1097 | |||
1098 | freed = 0; | ||
1099 | 1093 | ||
1100 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { | 1094 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { |
1101 | freed = sctp_ulpq_renege_order(ulpq, needed); | 1095 | freed = sctp_ulpq_renege_order(ulpq, needed); |
1102 | if (freed < needed) { | 1096 | if (freed < needed) |
1103 | freed += sctp_ulpq_renege_frags(ulpq, needed - freed); | 1097 | freed += sctp_ulpq_renege_frags(ulpq, needed - freed); |
1104 | } | ||
1105 | } | 1098 | } |
1106 | /* If able to free enough room, accept this chunk. */ | 1099 | /* If able to free enough room, accept this chunk. */ |
1107 | if (chunk && (freed >= needed)) { | 1100 | if (freed >= needed) { |
1108 | int retval; | 1101 | int retval = sctp_ulpq_tail_data(ulpq, chunk, gfp); |
1109 | retval = sctp_ulpq_tail_data(ulpq, chunk, gfp); | ||
1110 | /* | 1102 | /* |
1111 | * Enter partial delivery if chunk has not been | 1103 | * Enter partial delivery if chunk has not been |
1112 | * delivered; otherwise, drain the reassembly queue. | 1104 | * delivered; otherwise, drain the reassembly queue. |
diff --git a/net/socket.c b/net/socket.c index 42d8e9c9ccd5..05f361faec45 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -406,8 +406,10 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) | |||
406 | name.len = strlen(name.name); | 406 | name.len = strlen(name.name); |
407 | } | 407 | } |
408 | path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); | 408 | path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); |
409 | if (unlikely(!path.dentry)) | 409 | if (unlikely(!path.dentry)) { |
410 | sock_release(sock); | ||
410 | return ERR_PTR(-ENOMEM); | 411 | return ERR_PTR(-ENOMEM); |
412 | } | ||
411 | path.mnt = mntget(sock_mnt); | 413 | path.mnt = mntget(sock_mnt); |
412 | 414 | ||
413 | d_instantiate(path.dentry, SOCK_INODE(sock)); | 415 | d_instantiate(path.dentry, SOCK_INODE(sock)); |
@@ -415,9 +417,11 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) | |||
415 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, | 417 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, |
416 | &socket_file_ops); | 418 | &socket_file_ops); |
417 | if (IS_ERR(file)) { | 419 | if (IS_ERR(file)) { |
418 | /* drop dentry, keep inode */ | 420 | /* drop dentry, keep inode for a bit */ |
419 | ihold(d_inode(path.dentry)); | 421 | ihold(d_inode(path.dentry)); |
420 | path_put(&path); | 422 | path_put(&path); |
423 | /* ... and now kill it properly */ | ||
424 | sock_release(sock); | ||
421 | return file; | 425 | return file; |
422 | } | 426 | } |
423 | 427 | ||
@@ -1330,19 +1334,9 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) | |||
1330 | 1334 | ||
1331 | retval = sock_create(family, type, protocol, &sock); | 1335 | retval = sock_create(family, type, protocol, &sock); |
1332 | if (retval < 0) | 1336 | if (retval < 0) |
1333 | goto out; | 1337 | return retval; |
1334 | |||
1335 | retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); | ||
1336 | if (retval < 0) | ||
1337 | goto out_release; | ||
1338 | |||
1339 | out: | ||
1340 | /* It may be already another descriptor 8) Not kernel problem. */ | ||
1341 | return retval; | ||
1342 | 1338 | ||
1343 | out_release: | 1339 | return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); |
1344 | sock_release(sock); | ||
1345 | return retval; | ||
1346 | } | 1340 | } |
1347 | 1341 | ||
1348 | /* | 1342 | /* |
@@ -1366,87 +1360,72 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, | |||
1366 | flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; | 1360 | flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; |
1367 | 1361 | ||
1368 | /* | 1362 | /* |
1363 | * reserve descriptors and make sure we won't fail | ||
1364 | * to return them to userland. | ||
1365 | */ | ||
1366 | fd1 = get_unused_fd_flags(flags); | ||
1367 | if (unlikely(fd1 < 0)) | ||
1368 | return fd1; | ||
1369 | |||
1370 | fd2 = get_unused_fd_flags(flags); | ||
1371 | if (unlikely(fd2 < 0)) { | ||
1372 | put_unused_fd(fd1); | ||
1373 | return fd2; | ||
1374 | } | ||
1375 | |||
1376 | err = put_user(fd1, &usockvec[0]); | ||
1377 | if (err) | ||
1378 | goto out; | ||
1379 | |||
1380 | err = put_user(fd2, &usockvec[1]); | ||
1381 | if (err) | ||
1382 | goto out; | ||
1383 | |||
1384 | /* | ||
1369 | * Obtain the first socket and check if the underlying protocol | 1385 | * Obtain the first socket and check if the underlying protocol |
1370 | * supports the socketpair call. | 1386 | * supports the socketpair call. |
1371 | */ | 1387 | */ |
1372 | 1388 | ||
1373 | err = sock_create(family, type, protocol, &sock1); | 1389 | err = sock_create(family, type, protocol, &sock1); |
1374 | if (err < 0) | 1390 | if (unlikely(err < 0)) |
1375 | goto out; | 1391 | goto out; |
1376 | 1392 | ||
1377 | err = sock_create(family, type, protocol, &sock2); | 1393 | err = sock_create(family, type, protocol, &sock2); |
1378 | if (err < 0) | 1394 | if (unlikely(err < 0)) { |
1379 | goto out_release_1; | 1395 | sock_release(sock1); |
1380 | 1396 | goto out; | |
1381 | err = sock1->ops->socketpair(sock1, sock2); | ||
1382 | if (err < 0) | ||
1383 | goto out_release_both; | ||
1384 | |||
1385 | fd1 = get_unused_fd_flags(flags); | ||
1386 | if (unlikely(fd1 < 0)) { | ||
1387 | err = fd1; | ||
1388 | goto out_release_both; | ||
1389 | } | 1397 | } |
1390 | 1398 | ||
1391 | fd2 = get_unused_fd_flags(flags); | 1399 | err = sock1->ops->socketpair(sock1, sock2); |
1392 | if (unlikely(fd2 < 0)) { | 1400 | if (unlikely(err < 0)) { |
1393 | err = fd2; | 1401 | sock_release(sock2); |
1394 | goto out_put_unused_1; | 1402 | sock_release(sock1); |
1403 | goto out; | ||
1395 | } | 1404 | } |
1396 | 1405 | ||
1397 | newfile1 = sock_alloc_file(sock1, flags, NULL); | 1406 | newfile1 = sock_alloc_file(sock1, flags, NULL); |
1398 | if (IS_ERR(newfile1)) { | 1407 | if (IS_ERR(newfile1)) { |
1399 | err = PTR_ERR(newfile1); | 1408 | err = PTR_ERR(newfile1); |
1400 | goto out_put_unused_both; | 1409 | sock_release(sock2); |
1410 | goto out; | ||
1401 | } | 1411 | } |
1402 | 1412 | ||
1403 | newfile2 = sock_alloc_file(sock2, flags, NULL); | 1413 | newfile2 = sock_alloc_file(sock2, flags, NULL); |
1404 | if (IS_ERR(newfile2)) { | 1414 | if (IS_ERR(newfile2)) { |
1405 | err = PTR_ERR(newfile2); | 1415 | err = PTR_ERR(newfile2); |
1406 | goto out_fput_1; | 1416 | fput(newfile1); |
1417 | goto out; | ||
1407 | } | 1418 | } |
1408 | 1419 | ||
1409 | err = put_user(fd1, &usockvec[0]); | ||
1410 | if (err) | ||
1411 | goto out_fput_both; | ||
1412 | |||
1413 | err = put_user(fd2, &usockvec[1]); | ||
1414 | if (err) | ||
1415 | goto out_fput_both; | ||
1416 | |||
1417 | audit_fd_pair(fd1, fd2); | 1420 | audit_fd_pair(fd1, fd2); |
1418 | 1421 | ||
1419 | fd_install(fd1, newfile1); | 1422 | fd_install(fd1, newfile1); |
1420 | fd_install(fd2, newfile2); | 1423 | fd_install(fd2, newfile2); |
1421 | /* fd1 and fd2 may be already another descriptors. | ||
1422 | * Not kernel problem. | ||
1423 | */ | ||
1424 | |||
1425 | return 0; | 1424 | return 0; |
1426 | 1425 | ||
1427 | out_fput_both: | 1426 | out: |
1428 | fput(newfile2); | ||
1429 | fput(newfile1); | ||
1430 | put_unused_fd(fd2); | ||
1431 | put_unused_fd(fd1); | ||
1432 | goto out; | ||
1433 | |||
1434 | out_fput_1: | ||
1435 | fput(newfile1); | ||
1436 | put_unused_fd(fd2); | ||
1437 | put_unused_fd(fd1); | ||
1438 | sock_release(sock2); | ||
1439 | goto out; | ||
1440 | |||
1441 | out_put_unused_both: | ||
1442 | put_unused_fd(fd2); | 1427 | put_unused_fd(fd2); |
1443 | out_put_unused_1: | ||
1444 | put_unused_fd(fd1); | 1428 | put_unused_fd(fd1); |
1445 | out_release_both: | ||
1446 | sock_release(sock2); | ||
1447 | out_release_1: | ||
1448 | sock_release(sock1); | ||
1449 | out: | ||
1450 | return err; | 1429 | return err; |
1451 | } | 1430 | } |
1452 | 1431 | ||
@@ -1562,7 +1541,6 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, | |||
1562 | if (IS_ERR(newfile)) { | 1541 | if (IS_ERR(newfile)) { |
1563 | err = PTR_ERR(newfile); | 1542 | err = PTR_ERR(newfile); |
1564 | put_unused_fd(newfd); | 1543 | put_unused_fd(newfd); |
1565 | sock_release(newsock); | ||
1566 | goto out_put; | 1544 | goto out_put; |
1567 | } | 1545 | } |
1568 | 1546 | ||
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index c5fda15ba319..1fdab5c4eda8 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c | |||
@@ -401,7 +401,7 @@ void strp_data_ready(struct strparser *strp) | |||
401 | * allows a thread in BH context to safely check if the process | 401 | * allows a thread in BH context to safely check if the process |
402 | * lock is held. In this case, if the lock is held, queue work. | 402 | * lock is held. In this case, if the lock is held, queue work. |
403 | */ | 403 | */ |
404 | if (sock_owned_by_user(strp->sk)) { | 404 | if (sock_owned_by_user_nocheck(strp->sk)) { |
405 | queue_work(strp_wq, &strp->work); | 405 | queue_work(strp_wq, &strp->work); |
406 | return; | 406 | return; |
407 | } | 407 | } |
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index c4778cae58ef..444380f968f1 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c | |||
@@ -231,6 +231,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
231 | goto out_free_groups; | 231 | goto out_free_groups; |
232 | creds->cr_group_info->gid[i] = kgid; | 232 | creds->cr_group_info->gid[i] = kgid; |
233 | } | 233 | } |
234 | groups_sort(creds->cr_group_info); | ||
234 | 235 | ||
235 | return 0; | 236 | return 0; |
236 | out_free_groups: | 237 | out_free_groups: |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 5dd4e6c9fef2..26531193fce4 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -481,6 +481,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
481 | goto out; | 481 | goto out; |
482 | rsci.cred.cr_group_info->gid[i] = kgid; | 482 | rsci.cred.cr_group_info->gid[i] = kgid; |
483 | } | 483 | } |
484 | groups_sort(rsci.cred.cr_group_info); | ||
484 | 485 | ||
485 | /* mech name */ | 486 | /* mech name */ |
486 | len = qword_get(&mesg, buf, mlen); | 487 | len = qword_get(&mesg, buf, mlen); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 740b67d5a733..af7f28fb8102 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -520,6 +520,7 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
520 | ug.gi->gid[i] = kgid; | 520 | ug.gi->gid[i] = kgid; |
521 | } | 521 | } |
522 | 522 | ||
523 | groups_sort(ug.gi); | ||
523 | ugp = unix_gid_lookup(cd, uid); | 524 | ugp = unix_gid_lookup(cd, uid); |
524 | if (ugp) { | 525 | if (ugp) { |
525 | struct cache_head *ch; | 526 | struct cache_head *ch; |
@@ -819,6 +820,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
819 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); | 820 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); |
820 | cred->cr_group_info->gid[i] = kgid; | 821 | cred->cr_group_info->gid[i] = kgid; |
821 | } | 822 | } |
823 | groups_sort(cred->cr_group_info); | ||
822 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { | 824 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { |
823 | *authp = rpc_autherr_badverf; | 825 | *authp = rpc_autherr_badverf; |
824 | return SVC_DENIED; | 826 | return SVC_DENIED; |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 333b9d697ae5..33b74fd84051 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -1001,6 +1001,7 @@ void xprt_transmit(struct rpc_task *task) | |||
1001 | { | 1001 | { |
1002 | struct rpc_rqst *req = task->tk_rqstp; | 1002 | struct rpc_rqst *req = task->tk_rqstp; |
1003 | struct rpc_xprt *xprt = req->rq_xprt; | 1003 | struct rpc_xprt *xprt = req->rq_xprt; |
1004 | unsigned int connect_cookie; | ||
1004 | int status, numreqs; | 1005 | int status, numreqs; |
1005 | 1006 | ||
1006 | dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); | 1007 | dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); |
@@ -1024,6 +1025,7 @@ void xprt_transmit(struct rpc_task *task) | |||
1024 | } else if (!req->rq_bytes_sent) | 1025 | } else if (!req->rq_bytes_sent) |
1025 | return; | 1026 | return; |
1026 | 1027 | ||
1028 | connect_cookie = xprt->connect_cookie; | ||
1027 | req->rq_xtime = ktime_get(); | 1029 | req->rq_xtime = ktime_get(); |
1028 | status = xprt->ops->send_request(task); | 1030 | status = xprt->ops->send_request(task); |
1029 | trace_xprt_transmit(xprt, req->rq_xid, status); | 1031 | trace_xprt_transmit(xprt, req->rq_xid, status); |
@@ -1047,20 +1049,28 @@ void xprt_transmit(struct rpc_task *task) | |||
1047 | xprt->stat.bklog_u += xprt->backlog.qlen; | 1049 | xprt->stat.bklog_u += xprt->backlog.qlen; |
1048 | xprt->stat.sending_u += xprt->sending.qlen; | 1050 | xprt->stat.sending_u += xprt->sending.qlen; |
1049 | xprt->stat.pending_u += xprt->pending.qlen; | 1051 | xprt->stat.pending_u += xprt->pending.qlen; |
1052 | spin_unlock_bh(&xprt->transport_lock); | ||
1050 | 1053 | ||
1051 | /* Don't race with disconnect */ | 1054 | req->rq_connect_cookie = connect_cookie; |
1052 | if (!xprt_connected(xprt)) | 1055 | if (rpc_reply_expected(task) && !READ_ONCE(req->rq_reply_bytes_recvd)) { |
1053 | task->tk_status = -ENOTCONN; | ||
1054 | else { | ||
1055 | /* | 1056 | /* |
1056 | * Sleep on the pending queue since | 1057 | * Sleep on the pending queue if we're expecting a reply. |
1057 | * we're expecting a reply. | 1058 | * The spinlock ensures atomicity between the test of |
1059 | * req->rq_reply_bytes_recvd, and the call to rpc_sleep_on(). | ||
1058 | */ | 1060 | */ |
1059 | if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) | 1061 | spin_lock(&xprt->recv_lock); |
1062 | if (!req->rq_reply_bytes_recvd) { | ||
1060 | rpc_sleep_on(&xprt->pending, task, xprt_timer); | 1063 | rpc_sleep_on(&xprt->pending, task, xprt_timer); |
1061 | req->rq_connect_cookie = xprt->connect_cookie; | 1064 | /* |
1065 | * Send an extra queue wakeup call if the | ||
1066 | * connection was dropped in case the call to | ||
1067 | * rpc_sleep_on() raced. | ||
1068 | */ | ||
1069 | if (!xprt_connected(xprt)) | ||
1070 | xprt_wake_pending_tasks(xprt, -ENOTCONN); | ||
1071 | } | ||
1072 | spin_unlock(&xprt->recv_lock); | ||
1062 | } | 1073 | } |
1063 | spin_unlock_bh(&xprt->transport_lock); | ||
1064 | } | 1074 | } |
1065 | 1075 | ||
1066 | static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task) | 1076 | static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task) |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index ed34dc0f144c..a3f2ab283aeb 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -1408,11 +1408,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) | |||
1408 | dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n", | 1408 | dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n", |
1409 | __func__, rep, req, be32_to_cpu(rep->rr_xid)); | 1409 | __func__, rep, req, be32_to_cpu(rep->rr_xid)); |
1410 | 1410 | ||
1411 | if (list_empty(&req->rl_registered) && | 1411 | queue_work_on(req->rl_cpu, rpcrdma_receive_wq, &rep->rr_work); |
1412 | !test_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags)) | ||
1413 | rpcrdma_complete_rqst(rep); | ||
1414 | else | ||
1415 | queue_work(rpcrdma_receive_wq, &rep->rr_work); | ||
1416 | return; | 1412 | return; |
1417 | 1413 | ||
1418 | out_badstatus: | 1414 | out_badstatus: |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 646c24494ea7..6ee1ad8978f3 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/sunrpc/addr.h> | 54 | #include <linux/sunrpc/addr.h> |
55 | #include <linux/smp.h> | ||
55 | 56 | ||
56 | #include "xprt_rdma.h" | 57 | #include "xprt_rdma.h" |
57 | 58 | ||
@@ -656,6 +657,7 @@ xprt_rdma_allocate(struct rpc_task *task) | |||
656 | task->tk_pid, __func__, rqst->rq_callsize, | 657 | task->tk_pid, __func__, rqst->rq_callsize, |
657 | rqst->rq_rcvsize, req); | 658 | rqst->rq_rcvsize, req); |
658 | 659 | ||
660 | req->rl_cpu = smp_processor_id(); | ||
659 | req->rl_connect_cookie = 0; /* our reserved value */ | 661 | req->rl_connect_cookie = 0; /* our reserved value */ |
660 | rpcrdma_set_xprtdata(rqst, req); | 662 | rpcrdma_set_xprtdata(rqst, req); |
661 | rqst->rq_buffer = req->rl_sendbuf->rg_base; | 663 | rqst->rq_buffer = req->rl_sendbuf->rg_base; |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 710b3f77db82..8607c029c0dd 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -83,7 +83,7 @@ rpcrdma_alloc_wq(void) | |||
83 | struct workqueue_struct *recv_wq; | 83 | struct workqueue_struct *recv_wq; |
84 | 84 | ||
85 | recv_wq = alloc_workqueue("xprtrdma_receive", | 85 | recv_wq = alloc_workqueue("xprtrdma_receive", |
86 | WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_HIGHPRI, | 86 | WQ_MEM_RECLAIM | WQ_HIGHPRI, |
87 | 0); | 87 | 0); |
88 | if (!recv_wq) | 88 | if (!recv_wq) |
89 | return -ENOMEM; | 89 | return -ENOMEM; |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 51686d9eac5f..1342f743f1c4 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -342,6 +342,7 @@ enum { | |||
342 | struct rpcrdma_buffer; | 342 | struct rpcrdma_buffer; |
343 | struct rpcrdma_req { | 343 | struct rpcrdma_req { |
344 | struct list_head rl_list; | 344 | struct list_head rl_list; |
345 | int rl_cpu; | ||
345 | unsigned int rl_connect_cookie; | 346 | unsigned int rl_connect_cookie; |
346 | struct rpcrdma_buffer *rl_buffer; | 347 | struct rpcrdma_buffer *rl_buffer; |
347 | struct rpcrdma_rep *rl_reply; | 348 | struct rpcrdma_rep *rl_reply; |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 47ec121574ce..c8001471da6c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -324,6 +324,7 @@ restart: | |||
324 | if (res) { | 324 | if (res) { |
325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", | 325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", |
326 | name, -res); | 326 | name, -res); |
327 | kfree(b); | ||
327 | return -EINVAL; | 328 | return -EINVAL; |
328 | } | 329 | } |
329 | 330 | ||
@@ -347,8 +348,10 @@ restart: | |||
347 | if (skb) | 348 | if (skb) |
348 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); | 349 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); |
349 | 350 | ||
350 | if (tipc_mon_create(net, bearer_id)) | 351 | if (tipc_mon_create(net, bearer_id)) { |
352 | bearer_disable(net, b); | ||
351 | return -ENOMEM; | 353 | return -ENOMEM; |
354 | } | ||
352 | 355 | ||
353 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 356 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
354 | name, | 357 | name, |
diff --git a/net/tipc/group.c b/net/tipc/group.c index 95fec2c057d6..8e12ab55346b 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -351,8 +351,7 @@ void tipc_group_update_member(struct tipc_member *m, int len) | |||
351 | if (m->window >= ADV_IDLE) | 351 | if (m->window >= ADV_IDLE) |
352 | return; | 352 | return; |
353 | 353 | ||
354 | if (!list_empty(&m->congested)) | 354 | list_del_init(&m->congested); |
355 | return; | ||
356 | 355 | ||
357 | /* Sort member into congested members' list */ | 356 | /* Sort member into congested members' list */ |
358 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { | 357 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { |
@@ -369,18 +368,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack) | |||
369 | u16 prev = grp->bc_snd_nxt - 1; | 368 | u16 prev = grp->bc_snd_nxt - 1; |
370 | struct tipc_member *m; | 369 | struct tipc_member *m; |
371 | struct rb_node *n; | 370 | struct rb_node *n; |
371 | u16 ackers = 0; | ||
372 | 372 | ||
373 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { | 373 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { |
374 | m = container_of(n, struct tipc_member, tree_node); | 374 | m = container_of(n, struct tipc_member, tree_node); |
375 | if (tipc_group_is_enabled(m)) { | 375 | if (tipc_group_is_enabled(m)) { |
376 | tipc_group_update_member(m, len); | 376 | tipc_group_update_member(m, len); |
377 | m->bc_acked = prev; | 377 | m->bc_acked = prev; |
378 | ackers++; | ||
378 | } | 379 | } |
379 | } | 380 | } |
380 | 381 | ||
381 | /* Mark number of acknowledges to expect, if any */ | 382 | /* Mark number of acknowledges to expect, if any */ |
382 | if (ack) | 383 | if (ack) |
383 | grp->bc_ackers = grp->member_cnt; | 384 | grp->bc_ackers = ackers; |
384 | grp->bc_snd_nxt++; | 385 | grp->bc_snd_nxt++; |
385 | } | 386 | } |
386 | 387 | ||
@@ -648,6 +649,7 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
648 | } else if (mtyp == GRP_REMIT_MSG) { | 649 | } else if (mtyp == GRP_REMIT_MSG) { |
649 | msg_set_grp_remitted(hdr, m->window); | 650 | msg_set_grp_remitted(hdr, m->window); |
650 | } | 651 | } |
652 | msg_set_dest_droppable(hdr, true); | ||
651 | __skb_queue_tail(xmitq, skb); | 653 | __skb_queue_tail(xmitq, skb); |
652 | } | 654 | } |
653 | 655 | ||
@@ -689,15 +691,16 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
689 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 691 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
690 | __skb_queue_tail(inputq, m->event_msg); | 692 | __skb_queue_tail(inputq, m->event_msg); |
691 | } | 693 | } |
692 | if (m->window < ADV_IDLE) | 694 | list_del_init(&m->congested); |
693 | tipc_group_update_member(m, 0); | 695 | tipc_group_update_member(m, 0); |
694 | else | ||
695 | list_del_init(&m->congested); | ||
696 | return; | 696 | return; |
697 | case GRP_LEAVE_MSG: | 697 | case GRP_LEAVE_MSG: |
698 | if (!m) | 698 | if (!m) |
699 | return; | 699 | return; |
700 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); | 700 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); |
701 | list_del_init(&m->list); | ||
702 | list_del_init(&m->congested); | ||
703 | *usr_wakeup = true; | ||
701 | 704 | ||
702 | /* Wait until WITHDRAW event is received */ | 705 | /* Wait until WITHDRAW event is received */ |
703 | if (m->state != MBR_LEAVING) { | 706 | if (m->state != MBR_LEAVING) { |
@@ -709,8 +712,6 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
709 | ehdr = buf_msg(m->event_msg); | 712 | ehdr = buf_msg(m->event_msg); |
710 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 713 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
711 | __skb_queue_tail(inputq, m->event_msg); | 714 | __skb_queue_tail(inputq, m->event_msg); |
712 | *usr_wakeup = true; | ||
713 | list_del_init(&m->congested); | ||
714 | return; | 715 | return; |
715 | case GRP_ADV_MSG: | 716 | case GRP_ADV_MSG: |
716 | if (!m) | 717 | if (!m) |
@@ -849,19 +850,29 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
849 | *usr_wakeup = true; | 850 | *usr_wakeup = true; |
850 | m->usr_pending = false; | 851 | m->usr_pending = false; |
851 | node_up = tipc_node_is_up(net, node); | 852 | node_up = tipc_node_is_up(net, node); |
852 | 853 | m->event_msg = NULL; | |
853 | /* Hold back event if more messages might be expected */ | 854 | |
854 | if (m->state != MBR_LEAVING && node_up) { | 855 | if (node_up) { |
855 | m->event_msg = skb; | 856 | /* Hold back event if a LEAVE msg should be expected */ |
856 | tipc_group_decr_active(grp, m); | 857 | if (m->state != MBR_LEAVING) { |
857 | m->state = MBR_LEAVING; | 858 | m->event_msg = skb; |
858 | } else { | 859 | tipc_group_decr_active(grp, m); |
859 | if (node_up) | 860 | m->state = MBR_LEAVING; |
861 | } else { | ||
860 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 862 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); |
861 | else | 863 | __skb_queue_tail(inputq, skb); |
864 | } | ||
865 | } else { | ||
866 | if (m->state != MBR_LEAVING) { | ||
867 | tipc_group_decr_active(grp, m); | ||
868 | m->state = MBR_LEAVING; | ||
862 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); | 869 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); |
870 | } else { | ||
871 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | ||
872 | } | ||
863 | __skb_queue_tail(inputq, skb); | 873 | __skb_queue_tail(inputq, skb); |
864 | } | 874 | } |
875 | list_del_init(&m->list); | ||
865 | list_del_init(&m->congested); | 876 | list_del_init(&m->congested); |
866 | } | 877 | } |
867 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | 878 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); |
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 8e884ed06d4b..32dc33a94bc7 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c | |||
@@ -642,9 +642,13 @@ void tipc_mon_delete(struct net *net, int bearer_id) | |||
642 | { | 642 | { |
643 | struct tipc_net *tn = tipc_net(net); | 643 | struct tipc_net *tn = tipc_net(net); |
644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); | 644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); |
645 | struct tipc_peer *self = get_self(net, bearer_id); | 645 | struct tipc_peer *self; |
646 | struct tipc_peer *peer, *tmp; | 646 | struct tipc_peer *peer, *tmp; |
647 | 647 | ||
648 | if (!mon) | ||
649 | return; | ||
650 | |||
651 | self = get_self(net, bearer_id); | ||
648 | write_lock_bh(&mon->lock); | 652 | write_lock_bh(&mon->lock); |
649 | tn->monitors[bearer_id] = NULL; | 653 | tn->monitors[bearer_id] = NULL; |
650 | list_for_each_entry_safe(peer, tmp, &self->list, list) { | 654 | list_for_each_entry_safe(peer, tmp, &self->list, list) { |
diff --git a/net/tipc/server.c b/net/tipc/server.c index acaef80fb88c..d60c30342327 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
@@ -314,6 +314,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con) | |||
314 | newcon->usr_data = s->tipc_conn_new(newcon->conid); | 314 | newcon->usr_data = s->tipc_conn_new(newcon->conid); |
315 | if (!newcon->usr_data) { | 315 | if (!newcon->usr_data) { |
316 | sock_release(newsock); | 316 | sock_release(newsock); |
317 | conn_put(newcon); | ||
317 | return -ENOMEM; | 318 | return -ENOMEM; |
318 | } | 319 | } |
319 | 320 | ||
@@ -511,7 +512,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, | |||
511 | s = con->server; | 512 | s = con->server; |
512 | scbr = s->tipc_conn_new(*conid); | 513 | scbr = s->tipc_conn_new(*conid); |
513 | if (!scbr) { | 514 | if (!scbr) { |
514 | tipc_close_conn(con); | 515 | conn_put(con); |
515 | return false; | 516 | return false; |
516 | } | 517 | } |
517 | 518 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 5d18c0caa92b..3b4084480377 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -727,11 +727,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
727 | 727 | ||
728 | switch (sk->sk_state) { | 728 | switch (sk->sk_state) { |
729 | case TIPC_ESTABLISHED: | 729 | case TIPC_ESTABLISHED: |
730 | case TIPC_CONNECTING: | ||
730 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) | 731 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) |
731 | revents |= POLLOUT; | 732 | revents |= POLLOUT; |
732 | /* fall thru' */ | 733 | /* fall thru' */ |
733 | case TIPC_LISTEN: | 734 | case TIPC_LISTEN: |
734 | case TIPC_CONNECTING: | ||
735 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 735 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
736 | revents |= POLLIN | POLLRDNORM; | 736 | revents |= POLLIN | POLLRDNORM; |
737 | break; | 737 | break; |
@@ -1140,7 +1140,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | |||
1140 | __skb_dequeue(arrvq); | 1140 | __skb_dequeue(arrvq); |
1141 | __skb_queue_tail(inputq, skb); | 1141 | __skb_queue_tail(inputq, skb); |
1142 | } | 1142 | } |
1143 | refcount_dec(&skb->users); | 1143 | kfree_skb(skb); |
1144 | spin_unlock_bh(&inputq->lock); | 1144 | spin_unlock_bh(&inputq->lock); |
1145 | continue; | 1145 | continue; |
1146 | } | 1146 | } |
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index ecca64fc6a6f..3deabcab4882 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c | |||
@@ -371,10 +371,6 @@ static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
371 | goto rcu_out; | 371 | goto rcu_out; |
372 | } | 372 | } |
373 | 373 | ||
374 | tipc_rcv(sock_net(sk), skb, b); | ||
375 | rcu_read_unlock(); | ||
376 | return 0; | ||
377 | |||
378 | rcu_out: | 374 | rcu_out: |
379 | rcu_read_unlock(); | 375 | rcu_read_unlock(); |
380 | out: | 376 | out: |
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index 5583df708b8c..a827547aa102 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c | |||
@@ -487,7 +487,7 @@ static void hvs_release(struct vsock_sock *vsk) | |||
487 | 487 | ||
488 | lock_sock(sk); | 488 | lock_sock(sk); |
489 | 489 | ||
490 | sk->sk_state = SS_DISCONNECTING; | 490 | sk->sk_state = TCP_CLOSING; |
491 | vsock_remove_sock(vsk); | 491 | vsock_remove_sock(vsk); |
492 | 492 | ||
493 | release_sock(sk); | 493 | release_sock(sk); |
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 278d979c211a..1d84f91bbfb0 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -23,19 +23,36 @@ ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),) | |||
23 | cfg80211-y += extra-certs.o | 23 | cfg80211-y += extra-certs.o |
24 | endif | 24 | endif |
25 | 25 | ||
26 | $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.x509) | 26 | $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex) |
27 | @$(kecho) " GEN $@" | 27 | @$(kecho) " GEN $@" |
28 | @echo '#include "reg.h"' > $@ | 28 | @(echo '#include "reg.h"'; \ |
29 | @echo 'const u8 shipped_regdb_certs[] = {' >> $@ | 29 | echo 'const u8 shipped_regdb_certs[] = {'; \ |
30 | @for f in $^ ; do hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ ; done | 30 | cat $^ ; \ |
31 | @echo '};' >> $@ | 31 | echo '};'; \ |
32 | @echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);' >> $@ | 32 | echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \ |
33 | ) > $@ | ||
33 | 34 | ||
34 | $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \ | 35 | $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \ |
35 | $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509) | 36 | $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509) |
36 | @$(kecho) " GEN $@" | 37 | @$(kecho) " GEN $@" |
37 | @echo '#include "reg.h"' > $@ | 38 | @(set -e; \ |
38 | @echo 'const u8 extra_regdb_certs[] = {' >> $@ | 39 | allf=""; \ |
39 | @for f in $^ ; do test -f $$f && hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ || true ; done | 40 | for f in $^ ; do \ |
40 | @echo '};' >> $@ | 41 | # similar to hexdump -v -e '1/1 "0x%.2x," "\n"' \ |
41 | @echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);' >> $@ | 42 | thisf=$$(od -An -v -tx1 < $$f | \ |
43 | sed -e 's/ /\n/g' | \ | ||
44 | sed -e 's/^[0-9a-f]\+$$/\0/;t;d' | \ | ||
45 | sed -e 's/^/0x/;s/$$/,/'); \ | ||
46 | # file should not be empty - maybe command substitution failed? \ | ||
47 | test ! -z "$$thisf";\ | ||
48 | allf=$$allf$$thisf;\ | ||
49 | done; \ | ||
50 | ( \ | ||
51 | echo '#include "reg.h"'; \ | ||
52 | echo 'const u8 extra_regdb_certs[] = {'; \ | ||
53 | echo "$$allf"; \ | ||
54 | echo '};'; \ | ||
55 | echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);'; \ | ||
56 | ) > $@) | ||
57 | |||
58 | clean-files += shipped-certs.c extra-certs.c | ||
diff --git a/net/wireless/certs/sforshee.hex b/net/wireless/certs/sforshee.hex new file mode 100644 index 000000000000..14ea66643ffa --- /dev/null +++ b/net/wireless/certs/sforshee.hex | |||
@@ -0,0 +1,86 @@ | |||
1 | /* Seth Forshee's regdb certificate */ | ||
2 | 0x30, 0x82, 0x02, 0xa4, 0x30, 0x82, 0x01, 0x8c, | ||
3 | 0x02, 0x09, 0x00, 0xb2, 0x8d, 0xdf, 0x47, 0xae, | ||
4 | 0xf9, 0xce, 0xa7, 0x30, 0x0d, 0x06, 0x09, 0x2a, | ||
5 | 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, | ||
6 | 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, | ||
7 | 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x73, | ||
8 | 0x66, 0x6f, 0x72, 0x73, 0x68, 0x65, 0x65, 0x30, | ||
9 | 0x20, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x30, | ||
10 | 0x36, 0x31, 0x39, 0x34, 0x30, 0x33, 0x35, 0x5a, | ||
11 | 0x18, 0x0f, 0x32, 0x31, 0x31, 0x37, 0x30, 0x39, | ||
12 | 0x31, 0x32, 0x31, 0x39, 0x34, 0x30, 0x33, 0x35, | ||
13 | 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, | ||
14 | 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x73, 0x66, | ||
15 | 0x6f, 0x72, 0x73, 0x68, 0x65, 0x65, 0x30, 0x82, | ||
16 | 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, | ||
17 | 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, | ||
18 | 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, | ||
19 | 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb5, | ||
20 | 0x40, 0xe3, 0x9c, 0x28, 0x84, 0x39, 0x03, 0xf2, | ||
21 | 0x39, 0xd7, 0x66, 0x2c, 0x41, 0x38, 0x15, 0xac, | ||
22 | 0x7e, 0xa5, 0x83, 0x71, 0x25, 0x7e, 0x90, 0x7c, | ||
23 | 0x68, 0xdd, 0x6f, 0x3f, 0xd9, 0xd7, 0x59, 0x38, | ||
24 | 0x9f, 0x7c, 0x6a, 0x52, 0xc2, 0x03, 0x2a, 0x2d, | ||
25 | 0x7e, 0x66, 0xf4, 0x1e, 0xb3, 0x12, 0x70, 0x20, | ||
26 | 0x5b, 0xd4, 0x97, 0x32, 0x3d, 0x71, 0x8b, 0x3b, | ||
27 | 0x1b, 0x08, 0x17, 0x14, 0x6b, 0x61, 0xc4, 0x57, | ||
28 | 0x8b, 0x96, 0x16, 0x1c, 0xfd, 0x24, 0xd5, 0x0b, | ||
29 | 0x09, 0xf9, 0x68, 0x11, 0x84, 0xfb, 0xca, 0x51, | ||
30 | 0x0c, 0xd1, 0x45, 0x19, 0xda, 0x10, 0x44, 0x8a, | ||
31 | 0xd9, 0xfe, 0x76, 0xa9, 0xfd, 0x60, 0x2d, 0x18, | ||
32 | 0x0b, 0x28, 0x95, 0xb2, 0x2d, 0xea, 0x88, 0x98, | ||
33 | 0xb8, 0xd1, 0x56, 0x21, 0xf0, 0x53, 0x1f, 0xf1, | ||
34 | 0x02, 0x6f, 0xe9, 0x46, 0x9b, 0x93, 0x5f, 0x28, | ||
35 | 0x90, 0x0f, 0xac, 0x36, 0xfa, 0x68, 0x23, 0x71, | ||
36 | 0x57, 0x56, 0xf6, 0xcc, 0xd3, 0xdf, 0x7d, 0x2a, | ||
37 | 0xd9, 0x1b, 0x73, 0x45, 0xeb, 0xba, 0x27, 0x85, | ||
38 | 0xef, 0x7a, 0x7f, 0xa5, 0xcb, 0x80, 0xc7, 0x30, | ||
39 | 0x36, 0xd2, 0x53, 0xee, 0xec, 0xac, 0x1e, 0xe7, | ||
40 | 0x31, 0xf1, 0x36, 0xa2, 0x9c, 0x63, 0xc6, 0x65, | ||
41 | 0x5b, 0x7f, 0x25, 0x75, 0x68, 0xa1, 0xea, 0xd3, | ||
42 | 0x7e, 0x00, 0x5c, 0x9a, 0x5e, 0xd8, 0x20, 0x18, | ||
43 | 0x32, 0x77, 0x07, 0x29, 0x12, 0x66, 0x1e, 0x36, | ||
44 | 0x73, 0xe7, 0x97, 0x04, 0x41, 0x37, 0xb1, 0xb1, | ||
45 | 0x72, 0x2b, 0xf4, 0xa1, 0x29, 0x20, 0x7c, 0x96, | ||
46 | 0x79, 0x0b, 0x2b, 0xd0, 0xd8, 0xde, 0xc8, 0x6c, | ||
47 | 0x3f, 0x93, 0xfb, 0xc5, 0xee, 0x78, 0x52, 0x11, | ||
48 | 0x15, 0x1b, 0x7a, 0xf6, 0xe2, 0x68, 0x99, 0xe7, | ||
49 | 0xfb, 0x46, 0x16, 0x84, 0xe3, 0xc7, 0xa1, 0xe6, | ||
50 | 0xe0, 0xd2, 0x46, 0xd5, 0xe1, 0xc4, 0x5f, 0xa0, | ||
51 | 0x66, 0xf4, 0xda, 0xc4, 0xff, 0x95, 0x1d, 0x02, | ||
52 | 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, | ||
53 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, | ||
54 | 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, | ||
55 | 0x87, 0x03, 0xda, 0xf2, 0x82, 0xc2, 0xdd, 0xaf, | ||
56 | 0x7c, 0x44, 0x2f, 0x86, 0xd3, 0x5f, 0x4c, 0x93, | ||
57 | 0x48, 0xb9, 0xfe, 0x07, 0x17, 0xbb, 0x21, 0xf7, | ||
58 | 0x25, 0x23, 0x4e, 0xaa, 0x22, 0x0c, 0x16, 0xb9, | ||
59 | 0x73, 0xae, 0x9d, 0x46, 0x7c, 0x75, 0xd9, 0xc3, | ||
60 | 0x49, 0x57, 0x47, 0xbf, 0x33, 0xb7, 0x97, 0xec, | ||
61 | 0xf5, 0x40, 0x75, 0xc0, 0x46, 0x22, 0xf0, 0xa0, | ||
62 | 0x5d, 0x9c, 0x79, 0x13, 0xa1, 0xff, 0xb8, 0xa3, | ||
63 | 0x2f, 0x7b, 0x8e, 0x06, 0x3f, 0xc8, 0xb6, 0xe4, | ||
64 | 0x6a, 0x28, 0xf2, 0x34, 0x5c, 0x23, 0x3f, 0x32, | ||
65 | 0xc0, 0xe6, 0xad, 0x0f, 0xac, 0xcf, 0x55, 0x74, | ||
66 | 0x47, 0x73, 0xd3, 0x01, 0x85, 0xb7, 0x0b, 0x22, | ||
67 | 0x56, 0x24, 0x7d, 0x9f, 0x09, 0xa9, 0x0e, 0x86, | ||
68 | 0x9e, 0x37, 0x5b, 0x9c, 0x6d, 0x02, 0xd9, 0x8c, | ||
69 | 0xc8, 0x50, 0x6a, 0xe2, 0x59, 0xf3, 0x16, 0x06, | ||
70 | 0xea, 0xb2, 0x42, 0xb5, 0x58, 0xfe, 0xba, 0xd1, | ||
71 | 0x81, 0x57, 0x1a, 0xef, 0xb2, 0x38, 0x88, 0x58, | ||
72 | 0xf6, 0xaa, 0xc4, 0x2e, 0x8b, 0x5a, 0x27, 0xe4, | ||
73 | 0xa5, 0xe8, 0xa4, 0xca, 0x67, 0x5c, 0xac, 0x72, | ||
74 | 0x67, 0xc3, 0x6f, 0x13, 0xc3, 0x2d, 0x35, 0x79, | ||
75 | 0xd7, 0x8a, 0xe7, 0xf5, 0xd4, 0x21, 0x30, 0x4a, | ||
76 | 0xd5, 0xf6, 0xa3, 0xd9, 0x79, 0x56, 0xf2, 0x0f, | ||
77 | 0x10, 0xf7, 0x7d, 0xd0, 0x51, 0x93, 0x2f, 0x47, | ||
78 | 0xf8, 0x7d, 0x4b, 0x0a, 0x84, 0x55, 0x12, 0x0a, | ||
79 | 0x7d, 0x4e, 0x3b, 0x1f, 0x2b, 0x2f, 0xfc, 0x28, | ||
80 | 0xb3, 0x69, 0x34, 0xe1, 0x80, 0x80, 0xbb, 0xe2, | ||
81 | 0xaf, 0xb9, 0xd6, 0x30, 0xf1, 0x1d, 0x54, 0x87, | ||
82 | 0x23, 0x99, 0x9f, 0x51, 0x03, 0x4c, 0x45, 0x7d, | ||
83 | 0x02, 0x65, 0x73, 0xab, 0xfd, 0xcf, 0x94, 0xcc, | ||
84 | 0x0d, 0x3a, 0x60, 0xfd, 0x3c, 0x14, 0x2f, 0x16, | ||
85 | 0x33, 0xa9, 0x21, 0x1f, 0xcb, 0x50, 0xb1, 0x8f, | ||
86 | 0x03, 0xee, 0xa0, 0x66, 0xa9, 0x16, 0x79, 0x14, | ||
diff --git a/net/wireless/certs/sforshee.x509 b/net/wireless/certs/sforshee.x509 deleted file mode 100644 index c6f8f9d6b988..000000000000 --- a/net/wireless/certs/sforshee.x509 +++ /dev/null | |||
Binary files differ | |||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b1ac23ca20c8..213d0c498c97 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2610,7 +2610,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2610 | case NL80211_IFTYPE_AP: | 2610 | case NL80211_IFTYPE_AP: |
2611 | if (wdev->ssid_len && | 2611 | if (wdev->ssid_len && |
2612 | nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) | 2612 | nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) |
2613 | goto nla_put_failure; | 2613 | goto nla_put_failure_locked; |
2614 | break; | 2614 | break; |
2615 | case NL80211_IFTYPE_STATION: | 2615 | case NL80211_IFTYPE_STATION: |
2616 | case NL80211_IFTYPE_P2P_CLIENT: | 2616 | case NL80211_IFTYPE_P2P_CLIENT: |
@@ -2623,7 +2623,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2623 | if (!ssid_ie) | 2623 | if (!ssid_ie) |
2624 | break; | 2624 | break; |
2625 | if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) | 2625 | if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) |
2626 | goto nla_put_failure; | 2626 | goto nla_put_failure_locked; |
2627 | break; | 2627 | break; |
2628 | } | 2628 | } |
2629 | default: | 2629 | default: |
@@ -2635,6 +2635,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2635 | genlmsg_end(msg, hdr); | 2635 | genlmsg_end(msg, hdr); |
2636 | return 0; | 2636 | return 0; |
2637 | 2637 | ||
2638 | nla_put_failure_locked: | ||
2639 | wdev_unlock(wdev); | ||
2638 | nla_put_failure: | 2640 | nla_put_failure: |
2639 | genlmsg_cancel(msg, hdr); | 2641 | genlmsg_cancel(msg, hdr); |
2640 | return -EMSGSIZE; | 2642 | return -EMSGSIZE; |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 347ab31574d5..3f6f6f8c9fa5 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -8,15 +8,29 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bottom_half.h> | ||
12 | #include <linux/interrupt.h> | ||
11 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
13 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/percpu.h> | ||
14 | #include <net/dst.h> | 17 | #include <net/dst.h> |
15 | #include <net/ip.h> | 18 | #include <net/ip.h> |
16 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
17 | #include <net/ip_tunnels.h> | 20 | #include <net/ip_tunnels.h> |
18 | #include <net/ip6_tunnel.h> | 21 | #include <net/ip6_tunnel.h> |
19 | 22 | ||
23 | struct xfrm_trans_tasklet { | ||
24 | struct tasklet_struct tasklet; | ||
25 | struct sk_buff_head queue; | ||
26 | }; | ||
27 | |||
28 | struct xfrm_trans_cb { | ||
29 | int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb); | ||
30 | }; | ||
31 | |||
32 | #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0])) | ||
33 | |||
20 | static struct kmem_cache *secpath_cachep __read_mostly; | 34 | static struct kmem_cache *secpath_cachep __read_mostly; |
21 | 35 | ||
22 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); | 36 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); |
@@ -25,6 +39,8 @@ static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[AF_INET6 + 1]; | |||
25 | static struct gro_cells gro_cells; | 39 | static struct gro_cells gro_cells; |
26 | static struct net_device xfrm_napi_dev; | 40 | static struct net_device xfrm_napi_dev; |
27 | 41 | ||
42 | static DEFINE_PER_CPU(struct xfrm_trans_tasklet, xfrm_trans_tasklet); | ||
43 | |||
28 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) | 44 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) |
29 | { | 45 | { |
30 | int err = 0; | 46 | int err = 0; |
@@ -207,7 +223,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
207 | xfrm_address_t *daddr; | 223 | xfrm_address_t *daddr; |
208 | struct xfrm_mode *inner_mode; | 224 | struct xfrm_mode *inner_mode; |
209 | u32 mark = skb->mark; | 225 | u32 mark = skb->mark; |
210 | unsigned int family; | 226 | unsigned int family = AF_UNSPEC; |
211 | int decaps = 0; | 227 | int decaps = 0; |
212 | int async = 0; | 228 | int async = 0; |
213 | bool xfrm_gro = false; | 229 | bool xfrm_gro = false; |
@@ -216,6 +232,16 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
216 | 232 | ||
217 | if (encap_type < 0) { | 233 | if (encap_type < 0) { |
218 | x = xfrm_input_state(skb); | 234 | x = xfrm_input_state(skb); |
235 | |||
236 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { | ||
237 | if (x->km.state == XFRM_STATE_ACQ) | ||
238 | XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR); | ||
239 | else | ||
240 | XFRM_INC_STATS(net, | ||
241 | LINUX_MIB_XFRMINSTATEINVALID); | ||
242 | goto drop; | ||
243 | } | ||
244 | |||
219 | family = x->outer_mode->afinfo->family; | 245 | family = x->outer_mode->afinfo->family; |
220 | 246 | ||
221 | /* An encap_type of -1 indicates async resumption. */ | 247 | /* An encap_type of -1 indicates async resumption. */ |
@@ -467,9 +493,41 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) | |||
467 | } | 493 | } |
468 | EXPORT_SYMBOL(xfrm_input_resume); | 494 | EXPORT_SYMBOL(xfrm_input_resume); |
469 | 495 | ||
496 | static void xfrm_trans_reinject(unsigned long data) | ||
497 | { | ||
498 | struct xfrm_trans_tasklet *trans = (void *)data; | ||
499 | struct sk_buff_head queue; | ||
500 | struct sk_buff *skb; | ||
501 | |||
502 | __skb_queue_head_init(&queue); | ||
503 | skb_queue_splice_init(&trans->queue, &queue); | ||
504 | |||
505 | while ((skb = __skb_dequeue(&queue))) | ||
506 | XFRM_TRANS_SKB_CB(skb)->finish(dev_net(skb->dev), NULL, skb); | ||
507 | } | ||
508 | |||
509 | int xfrm_trans_queue(struct sk_buff *skb, | ||
510 | int (*finish)(struct net *, struct sock *, | ||
511 | struct sk_buff *)) | ||
512 | { | ||
513 | struct xfrm_trans_tasklet *trans; | ||
514 | |||
515 | trans = this_cpu_ptr(&xfrm_trans_tasklet); | ||
516 | |||
517 | if (skb_queue_len(&trans->queue) >= netdev_max_backlog) | ||
518 | return -ENOBUFS; | ||
519 | |||
520 | XFRM_TRANS_SKB_CB(skb)->finish = finish; | ||
521 | skb_queue_tail(&trans->queue, skb); | ||
522 | tasklet_schedule(&trans->tasklet); | ||
523 | return 0; | ||
524 | } | ||
525 | EXPORT_SYMBOL(xfrm_trans_queue); | ||
526 | |||
470 | void __init xfrm_input_init(void) | 527 | void __init xfrm_input_init(void) |
471 | { | 528 | { |
472 | int err; | 529 | int err; |
530 | int i; | ||
473 | 531 | ||
474 | init_dummy_netdev(&xfrm_napi_dev); | 532 | init_dummy_netdev(&xfrm_napi_dev); |
475 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); | 533 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); |
@@ -480,4 +538,13 @@ void __init xfrm_input_init(void) | |||
480 | sizeof(struct sec_path), | 538 | sizeof(struct sec_path), |
481 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, | 539 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
482 | NULL); | 540 | NULL); |
541 | |||
542 | for_each_possible_cpu(i) { | ||
543 | struct xfrm_trans_tasklet *trans; | ||
544 | |||
545 | trans = &per_cpu(xfrm_trans_tasklet, i); | ||
546 | __skb_queue_head_init(&trans->queue); | ||
547 | tasklet_init(&trans->tasklet, xfrm_trans_reinject, | ||
548 | (unsigned long)trans); | ||
549 | } | ||
483 | } | 550 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9542975eb2f9..70aa5cb0c659 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1168,9 +1168,15 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, | |||
1168 | again: | 1168 | again: |
1169 | pol = rcu_dereference(sk->sk_policy[dir]); | 1169 | pol = rcu_dereference(sk->sk_policy[dir]); |
1170 | if (pol != NULL) { | 1170 | if (pol != NULL) { |
1171 | bool match = xfrm_selector_match(&pol->selector, fl, family); | 1171 | bool match; |
1172 | int err = 0; | 1172 | int err = 0; |
1173 | 1173 | ||
1174 | if (pol->family != family) { | ||
1175 | pol = NULL; | ||
1176 | goto out; | ||
1177 | } | ||
1178 | |||
1179 | match = xfrm_selector_match(&pol->selector, fl, family); | ||
1174 | if (match) { | 1180 | if (match) { |
1175 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { | 1181 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { |
1176 | pol = NULL; | 1182 | pol = NULL; |
@@ -1833,6 +1839,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, | |||
1833 | sizeof(struct xfrm_policy *) * num_pols) == 0 && | 1839 | sizeof(struct xfrm_policy *) * num_pols) == 0 && |
1834 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { | 1840 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { |
1835 | dst_hold(&xdst->u.dst); | 1841 | dst_hold(&xdst->u.dst); |
1842 | xfrm_pols_put(pols, num_pols); | ||
1836 | while (err > 0) | 1843 | while (err > 0) |
1837 | xfrm_state_put(xfrm[--err]); | 1844 | xfrm_state_put(xfrm[--err]); |
1838 | return xdst; | 1845 | return xdst; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 065d89606888..500b3391f474 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1343,6 +1343,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, | |||
1343 | 1343 | ||
1344 | if (orig->aead) { | 1344 | if (orig->aead) { |
1345 | x->aead = xfrm_algo_aead_clone(orig->aead); | 1345 | x->aead = xfrm_algo_aead_clone(orig->aead); |
1346 | x->geniv = orig->geniv; | ||
1346 | if (!x->aead) | 1347 | if (!x->aead) |
1347 | goto error; | 1348 | goto error; |
1348 | } | 1349 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 983b0233767b..bdb48e5dba04 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1419,11 +1419,14 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | |||
1419 | 1419 | ||
1420 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | 1420 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) |
1421 | { | 1421 | { |
1422 | u16 prev_family; | ||
1422 | int i; | 1423 | int i; |
1423 | 1424 | ||
1424 | if (nr > XFRM_MAX_DEPTH) | 1425 | if (nr > XFRM_MAX_DEPTH) |
1425 | return -EINVAL; | 1426 | return -EINVAL; |
1426 | 1427 | ||
1428 | prev_family = family; | ||
1429 | |||
1427 | for (i = 0; i < nr; i++) { | 1430 | for (i = 0; i < nr; i++) { |
1428 | /* We never validated the ut->family value, so many | 1431 | /* We never validated the ut->family value, so many |
1429 | * applications simply leave it at zero. The check was | 1432 | * applications simply leave it at zero. The check was |
@@ -1435,6 +1438,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1435 | if (!ut[i].family) | 1438 | if (!ut[i].family) |
1436 | ut[i].family = family; | 1439 | ut[i].family = family; |
1437 | 1440 | ||
1441 | if ((ut[i].mode == XFRM_MODE_TRANSPORT) && | ||
1442 | (ut[i].family != prev_family)) | ||
1443 | return -EINVAL; | ||
1444 | |||
1445 | prev_family = ut[i].family; | ||
1446 | |||
1438 | switch (ut[i].family) { | 1447 | switch (ut[i].family) { |
1439 | case AF_INET: | 1448 | case AF_INET: |
1440 | break; | 1449 | break; |
@@ -1445,6 +1454,21 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1445 | default: | 1454 | default: |
1446 | return -EINVAL; | 1455 | return -EINVAL; |
1447 | } | 1456 | } |
1457 | |||
1458 | switch (ut[i].id.proto) { | ||
1459 | case IPPROTO_AH: | ||
1460 | case IPPROTO_ESP: | ||
1461 | case IPPROTO_COMP: | ||
1462 | #if IS_ENABLED(CONFIG_IPV6) | ||
1463 | case IPPROTO_ROUTING: | ||
1464 | case IPPROTO_DSTOPTS: | ||
1465 | #endif | ||
1466 | case IPSEC_PROTO_ANY: | ||
1467 | break; | ||
1468 | default: | ||
1469 | return -EINVAL; | ||
1470 | } | ||
1471 | |||
1448 | } | 1472 | } |
1449 | 1473 | ||
1450 | return 0; | 1474 | return 0; |
@@ -2470,7 +2494,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { | |||
2470 | [XFRMA_PROTO] = { .type = NLA_U8 }, | 2494 | [XFRMA_PROTO] = { .type = NLA_U8 }, |
2471 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, | 2495 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, |
2472 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, | 2496 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, |
2473 | [XFRMA_OUTPUT_MARK] = { .len = NLA_U32 }, | 2497 | [XFRMA_OUTPUT_MARK] = { .type = NLA_U32 }, |
2474 | }; | 2498 | }; |
2475 | 2499 | ||
2476 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { | 2500 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { |