aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-01 23:51:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-01 23:51:18 -0400
commitc46a024ea5eb0165114dbbc8c82c29b7bcf66e71 (patch)
treec91b0abf09c1fa5ddd566572dafa735aea05b592 /net
parent2459c6099b14b363e7212819a2d823cc167a1cd5 (diff)
parente453581dd518f60b45a8d2b9cf344e2a87d5267e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Various VTI tunnel (mark handling, PMTU) bug fixes from Alexander Duyck and Steffen Klassert. 2) Revert ethtool PHY query change, it wasn't correct. The PHY address selected by the driver running the PHY to MAC connection decides what PHY address GET ethtool operations return information from. 3) Fix handling of sequence number bits for encryption IV generation in ESP driver, from Herbert Xu. 4) UDP can return -EAGAIN when we hit a bad checksum on receive, even when there are other packets in the receive queue which is wrong. Just respect the error returned from the generic socket recv datagram helper. From Eric Dumazet. 5) Fix BNA driver firmware loading on big-endian systems, from Ivan Vecera. 6) Fix regression in that we were inheriting the congestion control of the listening socket for new connections, the intended behavior always was to use the default in this case. From Neal Cardwell. 7) Fix NULL deref in brcmfmac driver, from Arend van Spriel. 8) OTP parsing fix in iwlwifi from Liad Kaufman. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (26 commits) vti6: Add pmtu handling to vti6_xmit. Revert "net: core: 'ethtool' issue with querying phy settings" bnx2x: Move statistics implementation into semaphores xen: netback: read hotplug script once at start of day. xen: netback: fix printf format string warning Revert "netfilter: ensure number of counters is >0 in do_replace()" net: dsa: Properly propagate errors from dsa_switch_setup_one tcp: fix child sockets to use system default congestion control if not set udp: fix behavior of wrong checksums sfc: free multiple Rx buffers when required bna: fix soft lock-up during firmware initialization failure bna: remove unreasonable iocpf timer start bna: fix firmware loading on big-endian machines bridge: fix br_multicast_query_expired() bug via-rhine: Resigning as maintainer brcmfmac: avoid null pointer access when brcmf_msgbuf_get_pktid() fails mac80211: Fix mac80211.h docbook comments iwlwifi: nvm: fix otp parsing in 8000 hw family iwlwifi: pcie: fix tracking of cmd_in_flight ip_vti/ip6_vti: Preserve skb->mark after rcv_cb call ...
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_multicast.c2
-rw-r--r--net/bridge/netfilter/ebtables.c4
-rw-r--r--net/core/ethtool.c10
-rw-r--r--net/dsa/dsa.c4
-rw-r--r--net/ipv4/esp4.c3
-rw-r--r--net/ipv4/ip_vti.c14
-rw-r--r--net/ipv4/tcp_cong.c5
-rw-r--r--net/ipv4/tcp_minisocks.c5
-rw-r--r--net/ipv4/udp.c6
-rw-r--r--net/ipv6/esp6.c3
-rw-r--r--net/ipv6/ip6_vti.c27
-rw-r--r--net/ipv6/udp.c6
-rw-r--r--net/xfrm/xfrm_input.c17
-rw-r--r--net/xfrm/xfrm_replay.c2
-rw-r--r--net/xfrm/xfrm_state.c2
15 files changed, 73 insertions, 37 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index a3abe6ed111e..22fd0419b314 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1822,7 +1822,7 @@ static void br_multicast_query_expired(struct net_bridge *br,
1822 if (query->startup_sent < br->multicast_startup_query_count) 1822 if (query->startup_sent < br->multicast_startup_query_count)
1823 query->startup_sent++; 1823 query->startup_sent++;
1824 1824
1825 RCU_INIT_POINTER(querier, NULL); 1825 RCU_INIT_POINTER(querier->port, NULL);
1826 br_multicast_send_query(br, NULL, query); 1826 br_multicast_send_query(br, NULL, query);
1827 spin_unlock(&br->multicast_lock); 1827 spin_unlock(&br->multicast_lock);
1828} 1828}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 24c7c96bf5f8..91180a7fc943 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1117,8 +1117,6 @@ static int do_replace(struct net *net, const void __user *user,
1117 return -ENOMEM; 1117 return -ENOMEM;
1118 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) 1118 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
1119 return -ENOMEM; 1119 return -ENOMEM;
1120 if (tmp.num_counters == 0)
1121 return -EINVAL;
1122 1120
1123 tmp.name[sizeof(tmp.name) - 1] = 0; 1121 tmp.name[sizeof(tmp.name) - 1] = 0;
1124 1122
@@ -2161,8 +2159,6 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
2161 return -ENOMEM; 2159 return -ENOMEM;
2162 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) 2160 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
2163 return -ENOMEM; 2161 return -ENOMEM;
2164 if (tmp.num_counters == 0)
2165 return -EINVAL;
2166 2162
2167 memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry)); 2163 memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
2168 2164
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 1347e11f5cc9..1d00b8922902 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -359,15 +359,7 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
359 int err; 359 int err;
360 struct ethtool_cmd cmd; 360 struct ethtool_cmd cmd;
361 361
362 if (!dev->ethtool_ops->get_settings) 362 err = __ethtool_get_settings(dev, &cmd);
363 return -EOPNOTSUPP;
364
365 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
366 return -EFAULT;
367
368 cmd.cmd = ETHTOOL_GSET;
369
370 err = dev->ethtool_ops->get_settings(dev, &cmd);
371 if (err < 0) 363 if (err < 0)
372 return err; 364 return err;
373 365
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index e6f6cc3a1bcf..392e29a0227d 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -359,7 +359,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
359 */ 359 */
360 ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); 360 ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
361 if (ds == NULL) 361 if (ds == NULL)
362 return NULL; 362 return ERR_PTR(-ENOMEM);
363 363
364 ds->dst = dst; 364 ds->dst = dst;
365 ds->index = index; 365 ds->index = index;
@@ -370,7 +370,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
370 370
371 ret = dsa_switch_setup_one(ds, parent); 371 ret = dsa_switch_setup_one(ds, parent);
372 if (ret) 372 if (ret)
373 return NULL; 373 return ERR_PTR(ret);
374 374
375 return ds; 375 return ds;
376} 376}
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 421a80b09b62..30b544f025ac 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -256,7 +256,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
256 aead_givcrypt_set_crypt(req, sg, sg, clen, iv); 256 aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
257 aead_givcrypt_set_assoc(req, asg, assoclen); 257 aead_givcrypt_set_assoc(req, asg, assoclen);
258 aead_givcrypt_set_giv(req, esph->enc_data, 258 aead_givcrypt_set_giv(req, esph->enc_data,
259 XFRM_SKB_CB(skb)->seq.output.low); 259 XFRM_SKB_CB(skb)->seq.output.low +
260 ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32));
260 261
261 ESP_SKB_CB(skb)->tmp = tmp; 262 ESP_SKB_CB(skb)->tmp = tmp;
262 err = crypto_aead_givencrypt(req); 263 err = crypto_aead_givencrypt(req);
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 9f7269f3c54a..0c152087ca15 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -65,7 +65,6 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
65 goto drop; 65 goto drop;
66 66
67 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; 67 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
68 skb->mark = be32_to_cpu(tunnel->parms.i_key);
69 68
70 return xfrm_input(skb, nexthdr, spi, encap_type); 69 return xfrm_input(skb, nexthdr, spi, encap_type);
71 } 70 }
@@ -91,6 +90,8 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
91 struct pcpu_sw_netstats *tstats; 90 struct pcpu_sw_netstats *tstats;
92 struct xfrm_state *x; 91 struct xfrm_state *x;
93 struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; 92 struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
93 u32 orig_mark = skb->mark;
94 int ret;
94 95
95 if (!tunnel) 96 if (!tunnel)
96 return 1; 97 return 1;
@@ -107,7 +108,11 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
107 x = xfrm_input_state(skb); 108 x = xfrm_input_state(skb);
108 family = x->inner_mode->afinfo->family; 109 family = x->inner_mode->afinfo->family;
109 110
110 if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) 111 skb->mark = be32_to_cpu(tunnel->parms.i_key);
112 ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
113 skb->mark = orig_mark;
114
115 if (!ret)
111 return -EPERM; 116 return -EPERM;
112 117
113 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev))); 118 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev)));
@@ -216,8 +221,6 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
216 221
217 memset(&fl, 0, sizeof(fl)); 222 memset(&fl, 0, sizeof(fl));
218 223
219 skb->mark = be32_to_cpu(tunnel->parms.o_key);
220
221 switch (skb->protocol) { 224 switch (skb->protocol) {
222 case htons(ETH_P_IP): 225 case htons(ETH_P_IP):
223 xfrm_decode_session(skb, &fl, AF_INET); 226 xfrm_decode_session(skb, &fl, AF_INET);
@@ -233,6 +236,9 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
233 return NETDEV_TX_OK; 236 return NETDEV_TX_OK;
234 } 237 }
235 238
239 /* override mark with tunnel output key */
240 fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key);
241
236 return vti_xmit(skb, dev, &fl); 242 return vti_xmit(skb, dev, &fl);
237} 243}
238 244
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 7a5ae50c80c8..84be008c945c 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -187,6 +187,7 @@ static void tcp_reinit_congestion_control(struct sock *sk,
187 187
188 tcp_cleanup_congestion_control(sk); 188 tcp_cleanup_congestion_control(sk);
189 icsk->icsk_ca_ops = ca; 189 icsk->icsk_ca_ops = ca;
190 icsk->icsk_ca_setsockopt = 1;
190 191
191 if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) 192 if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
192 icsk->icsk_ca_ops->init(sk); 193 icsk->icsk_ca_ops->init(sk);
@@ -335,8 +336,10 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
335 rcu_read_lock(); 336 rcu_read_lock();
336 ca = __tcp_ca_find_autoload(name); 337 ca = __tcp_ca_find_autoload(name);
337 /* No change asking for existing value */ 338 /* No change asking for existing value */
338 if (ca == icsk->icsk_ca_ops) 339 if (ca == icsk->icsk_ca_ops) {
340 icsk->icsk_ca_setsockopt = 1;
339 goto out; 341 goto out;
342 }
340 if (!ca) 343 if (!ca)
341 err = -ENOENT; 344 err = -ENOENT;
342 else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || 345 else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index b5732a54f2ad..17e7339ee5ca 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -420,7 +420,10 @@ void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst)
420 rcu_read_unlock(); 420 rcu_read_unlock();
421 } 421 }
422 422
423 if (!ca_got_dst && !try_module_get(icsk->icsk_ca_ops->owner)) 423 /* If no valid choice made yet, assign current system default ca. */
424 if (!ca_got_dst &&
425 (!icsk->icsk_ca_setsockopt ||
426 !try_module_get(icsk->icsk_ca_ops->owner)))
424 tcp_assign_congestion_control(sk); 427 tcp_assign_congestion_control(sk);
425 428
426 tcp_set_ca_state(sk, TCP_CA_Open); 429 tcp_set_ca_state(sk, TCP_CA_Open);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d10b7e0112eb..1c92ea67baef 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1345,10 +1345,8 @@ csum_copy_err:
1345 } 1345 }
1346 unlock_sock_fast(sk, slow); 1346 unlock_sock_fast(sk, slow);
1347 1347
1348 if (noblock) 1348 /* starting over for a new packet, but check if we need to yield */
1349 return -EAGAIN; 1349 cond_resched();
1350
1351 /* starting over for a new packet */
1352 msg->msg_flags &= ~MSG_TRUNC; 1350 msg->msg_flags &= ~MSG_TRUNC;
1353 goto try_again; 1351 goto try_again;
1354} 1352}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 31f1b5d5e2ef..7c07ce36aae2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -248,7 +248,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
248 aead_givcrypt_set_crypt(req, sg, sg, clen, iv); 248 aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
249 aead_givcrypt_set_assoc(req, asg, assoclen); 249 aead_givcrypt_set_assoc(req, asg, assoclen);
250 aead_givcrypt_set_giv(req, esph->enc_data, 250 aead_givcrypt_set_giv(req, esph->enc_data,
251 XFRM_SKB_CB(skb)->seq.output.low); 251 XFRM_SKB_CB(skb)->seq.output.low +
252 ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32));
252 253
253 ESP_SKB_CB(skb)->tmp = tmp; 254 ESP_SKB_CB(skb)->tmp = tmp;
254 err = crypto_aead_givencrypt(req); 255 err = crypto_aead_givencrypt(req);
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index ed9d681207fa..0224c032dca5 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -322,7 +322,6 @@ static int vti6_rcv(struct sk_buff *skb)
322 } 322 }
323 323
324 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; 324 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
325 skb->mark = be32_to_cpu(t->parms.i_key);
326 325
327 rcu_read_unlock(); 326 rcu_read_unlock();
328 327
@@ -342,6 +341,8 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
342 struct pcpu_sw_netstats *tstats; 341 struct pcpu_sw_netstats *tstats;
343 struct xfrm_state *x; 342 struct xfrm_state *x;
344 struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; 343 struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6;
344 u32 orig_mark = skb->mark;
345 int ret;
345 346
346 if (!t) 347 if (!t)
347 return 1; 348 return 1;
@@ -358,7 +359,11 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
358 x = xfrm_input_state(skb); 359 x = xfrm_input_state(skb);
359 family = x->inner_mode->afinfo->family; 360 family = x->inner_mode->afinfo->family;
360 361
361 if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) 362 skb->mark = be32_to_cpu(t->parms.i_key);
363 ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
364 skb->mark = orig_mark;
365
366 if (!ret)
362 return -EPERM; 367 return -EPERM;
363 368
364 skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev))); 369 skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev)));
@@ -430,6 +435,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
430 struct net_device *tdev; 435 struct net_device *tdev;
431 struct xfrm_state *x; 436 struct xfrm_state *x;
432 int err = -1; 437 int err = -1;
438 int mtu;
433 439
434 if (!dst) 440 if (!dst)
435 goto tx_err_link_failure; 441 goto tx_err_link_failure;
@@ -463,6 +469,19 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
463 skb_dst_set(skb, dst); 469 skb_dst_set(skb, dst);
464 skb->dev = skb_dst(skb)->dev; 470 skb->dev = skb_dst(skb)->dev;
465 471
472 mtu = dst_mtu(dst);
473 if (!skb->ignore_df && skb->len > mtu) {
474 skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu);
475
476 if (skb->protocol == htons(ETH_P_IPV6))
477 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
478 else
479 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
480 htonl(mtu));
481
482 return -EMSGSIZE;
483 }
484
466 err = dst_output(skb); 485 err = dst_output(skb);
467 if (net_xmit_eval(err) == 0) { 486 if (net_xmit_eval(err) == 0) {
468 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); 487 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
@@ -495,7 +514,6 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
495 int ret; 514 int ret;
496 515
497 memset(&fl, 0, sizeof(fl)); 516 memset(&fl, 0, sizeof(fl));
498 skb->mark = be32_to_cpu(t->parms.o_key);
499 517
500 switch (skb->protocol) { 518 switch (skb->protocol) {
501 case htons(ETH_P_IPV6): 519 case htons(ETH_P_IPV6):
@@ -516,6 +534,9 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
516 goto tx_err; 534 goto tx_err;
517 } 535 }
518 536
537 /* override mark with tunnel output key */
538 fl.flowi_mark = be32_to_cpu(t->parms.o_key);
539
519 ret = vti6_xmit(skb, dev, &fl); 540 ret = vti6_xmit(skb, dev, &fl);
520 if (ret < 0) 541 if (ret < 0)
521 goto tx_err; 542 goto tx_err;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c2ec41617a35..e51fc3eee6db 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -525,10 +525,8 @@ csum_copy_err:
525 } 525 }
526 unlock_sock_fast(sk, slow); 526 unlock_sock_fast(sk, slow);
527 527
528 if (noblock) 528 /* starting over for a new packet, but check if we need to yield */
529 return -EAGAIN; 529 cond_resched();
530
531 /* starting over for a new packet */
532 msg->msg_flags &= ~MSG_TRUNC; 530 msg->msg_flags &= ~MSG_TRUNC;
533 goto try_again; 531 goto try_again;
534} 532}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 526c4feb3b50..b58286ecd156 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -13,6 +13,8 @@
13#include <net/dst.h> 13#include <net/dst.h>
14#include <net/ip.h> 14#include <net/ip.h>
15#include <net/xfrm.h> 15#include <net/xfrm.h>
16#include <net/ip_tunnels.h>
17#include <net/ip6_tunnel.h>
16 18
17static struct kmem_cache *secpath_cachep __read_mostly; 19static struct kmem_cache *secpath_cachep __read_mostly;
18 20
@@ -186,6 +188,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
186 struct xfrm_state *x = NULL; 188 struct xfrm_state *x = NULL;
187 xfrm_address_t *daddr; 189 xfrm_address_t *daddr;
188 struct xfrm_mode *inner_mode; 190 struct xfrm_mode *inner_mode;
191 u32 mark = skb->mark;
189 unsigned int family; 192 unsigned int family;
190 int decaps = 0; 193 int decaps = 0;
191 int async = 0; 194 int async = 0;
@@ -203,6 +206,18 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
203 XFRM_SPI_SKB_CB(skb)->daddroff); 206 XFRM_SPI_SKB_CB(skb)->daddroff);
204 family = XFRM_SPI_SKB_CB(skb)->family; 207 family = XFRM_SPI_SKB_CB(skb)->family;
205 208
209 /* if tunnel is present override skb->mark value with tunnel i_key */
210 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) {
211 switch (family) {
212 case AF_INET:
213 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
214 break;
215 case AF_INET6:
216 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
217 break;
218 }
219 }
220
206 /* Allocate new secpath or COW existing one. */ 221 /* Allocate new secpath or COW existing one. */
207 if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { 222 if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
208 struct sec_path *sp; 223 struct sec_path *sp;
@@ -229,7 +244,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
229 goto drop; 244 goto drop;
230 } 245 }
231 246
232 x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family); 247 x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family);
233 if (x == NULL) { 248 if (x == NULL) {
234 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); 249 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
235 xfrm_audit_state_notfound(skb, family, spi, seq); 250 xfrm_audit_state_notfound(skb, family, spi, seq);
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index dab57daae408..4fd725a0c500 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -99,6 +99,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
99 99
100 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { 100 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
101 XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq; 101 XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
102 XFRM_SKB_CB(skb)->seq.output.hi = 0;
102 if (unlikely(x->replay.oseq == 0)) { 103 if (unlikely(x->replay.oseq == 0)) {
103 x->replay.oseq--; 104 x->replay.oseq--;
104 xfrm_audit_state_replay_overflow(x, skb); 105 xfrm_audit_state_replay_overflow(x, skb);
@@ -177,6 +178,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
177 178
178 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { 179 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
179 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; 180 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
181 XFRM_SKB_CB(skb)->seq.output.hi = 0;
180 if (unlikely(replay_esn->oseq == 0)) { 182 if (unlikely(replay_esn->oseq == 0)) {
181 replay_esn->oseq--; 183 replay_esn->oseq--;
182 xfrm_audit_state_replay_overflow(x, skb); 184 xfrm_audit_state_replay_overflow(x, skb);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f5e39e35d73a..96688cd0f6f1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -927,8 +927,8 @@ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
927 x->id.spi != spi) 927 x->id.spi != spi)
928 continue; 928 continue;
929 929
930 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
931 xfrm_state_hold(x); 930 xfrm_state_hold(x);
931 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
932 return x; 932 return x;
933 } 933 }
934 spin_unlock_bh(&net->xfrm.xfrm_state_lock); 934 spin_unlock_bh(&net->xfrm.xfrm_state_lock);