Message ID | 1470921479-25592-7-git-send-email-fw@strlen.de |
---|---|
State | Awaiting Upstream, archived |
Delegated to: | David Miller |
Headers | show |
Le 11/08/2016 à 15:17, Florian Westphal a écrit : > Don't acquire the readlock anymore and rely on rcu alone. > > In case writer on other CPU changed policy at the wrong moment (after we > obtained sk policy pointer but before we could obtain the reference) > just repeat the lookup. > > Signed-off-by: Florian Westphal <fw@strlen.de> Since this patch, our IKEv1 Transport tests (using charon) fail to establish the connection. If I revert it, the IKE negociation is ok again. charon logs are enclosed. I didn't had time to investigate now, but any idea is welcomed ;-) Regards, Nicolas /var/log/syslog:Nov 16 16:28:47 router charon: 04[CFG] received stroke: add connection 'mytunnel-17' /var/log/syslog:Nov 16 16:28:47 router charon: 04[CFG] added configuration 'mytunnel-17' /var/log/syslog:Nov 16 16:28:47 router charon: 08[CFG] received stroke: route 'mytunnel-17' /var/log/syslog:Nov 16 16:28:52 router charon: 13[KNL] creating acquire job for policy 10.125.0.1/32[gre] === 10.125.0.2/32[gre] with reqid {1} /var/log/syslog:Nov 16 16:28:52 router charon: 13[IKE] initiating Aggressive Mode IKE_SA mytunnel-17[1] to 10.125.0.2 /var/log/syslog:Nov 16 16:28:52 router charon: 13[ENC] generating AGGRESSIVE request 0 [ SA KE No ID V V V V V ] /var/log/syslog:Nov 16 16:28:52 router charon: 13[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:28:56 router charon: 07[IKE] sending retransmit 1 of request message ID 0, seq 1 /var/log/syslog:Nov 16 16:28:56 router charon: 07[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:29:04 router charon: 08[IKE] sending retransmit 2 of request message ID 0, seq 1 /var/log/syslog:Nov 16 16:29:04 router charon: 08[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:29:17 router charon: 09[IKE] sending retransmit 3 of request message ID 0, seq 1 /var/log/syslog:Nov 16 16:29:17 router charon: 09[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:29:40 router charon: 11[IKE] sending retransmit 4 of request message ID 0, seq 1 /var/log/syslog:Nov 16 16:29:40 router charon: 11[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:30:22 router charon: 05[IKE] sending retransmit 5 of request message ID 0, seq 1 /var/log/syslog:Nov 16 16:30:22 router charon: 05[NET] sending packet: from 10.125.0.1[500] to 10.125.0.2[500] (548 bytes) /var/log/syslog:Nov 16 16:31:37 router charon: 15[KNL] creating delete job for CHILD_SA ESP/0x00000000/10.125.0.2 /var/log/syslog:Nov 16 16:31:37 router charon: 13[JOB] CHILD_SA ESP/0x00000000/10.125.0.2 not found for delete /var/log/syslog:Nov 16 16:31:38 router charon: 09[IKE] giving up after 5 retransmits /var/log/syslog:Nov 16 16:31:38 router charon: 09[IKE] establishing IKE_SA failed, peer not responding
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 398661c..575a48b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1249,10 +1249,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, const struct flowi *fl) { struct xfrm_policy *pol; - struct net *net = sock_net(sk); rcu_read_lock(); - read_lock_bh(&net->xfrm.xfrm_policy_lock); + again: pol = rcu_dereference(sk->sk_policy[dir]); if (pol != NULL) { bool match = xfrm_selector_match(&pol->selector, fl, @@ -1267,8 +1266,8 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, err = security_xfrm_policy_lookup(pol->security, fl->flowi_secid, policy_to_flow_dir(dir)); - if (!err) - xfrm_pol_hold(pol); + if (!err && !xfrm_pol_hold_rcu(pol)) + goto again; else if (err == -ESRCH) pol = NULL; else @@ -1277,7 +1276,6 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, pol = NULL; } out: - read_unlock_bh(&net->xfrm.xfrm_policy_lock); rcu_read_unlock(); return pol; }
Don't acquire the readlock anymore and rely on rcu alone. In case writer on other CPU changed policy at the wrong moment (after we obtained sk policy pointer but before we could obtain the reference) just repeat the lookup. Signed-off-by: Florian Westphal <fw@strlen.de> --- net/xfrm/xfrm_policy.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)