Skip to content

Commit 0aebd81

Browse files
committed
Merge tag 'ipsec-2026-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2026-02-20 1) Check the value of ipv6_dev_get_saddr() to fix an uninitialized saddr in xfrm6_get_saddr(). From Jiayuan Chen. 2) Skip the templates check for packet offload in tunnel mode. Is was already done by the hardware and causes an unexpected XfrmInTmplMismatch increase. From Leon Romanovsky. 3) Fix a unregister_netdevice stall due to not dropped refcounts by always flushing xfrm state and policy on a NETDEV_UNREGISTER event. From Tetsuo Handa. * tag 'ipsec-2026-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec: xfrm: always flush state and policy upon NETDEV_UNREGISTER event xfrm: skip templates check for packet offload tunnel mode xfrm6: fix uninitialized saddr in xfrm6_get_saddr() ==================== Link: https://patch.msgid.link/20260220094133.14219-1-steffen.klassert@secunet.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 9b8eecc + 4efa91a commit 0aebd81

3 files changed

Lines changed: 25 additions & 5 deletions

File tree

net/ipv6/xfrm6_policy.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr,
5757
struct dst_entry *dst;
5858
struct net_device *dev;
5959
struct inet6_dev *idev;
60+
int err;
6061

6162
dst = xfrm6_dst_lookup(params);
6263
if (IS_ERR(dst))
@@ -68,9 +69,11 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr,
6869
return -EHOSTUNREACH;
6970
}
7071
dev = idev->dev;
71-
ipv6_dev_get_saddr(dev_net(dev), dev, &params->daddr->in6, 0,
72-
&saddr->in6);
72+
err = ipv6_dev_get_saddr(dev_net(dev), dev, &params->daddr->in6, 0,
73+
&saddr->in6);
7374
dst_release(dst);
75+
if (err)
76+
return -EHOSTUNREACH;
7477
return 0;
7578
}
7679

net/xfrm/xfrm_device.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,14 @@ static int xfrm_dev_down(struct net_device *dev)
544544
return NOTIFY_DONE;
545545
}
546546

547+
static int xfrm_dev_unregister(struct net_device *dev)
548+
{
549+
xfrm_dev_state_flush(dev_net(dev), dev, true);
550+
xfrm_dev_policy_flush(dev_net(dev), dev, true);
551+
552+
return NOTIFY_DONE;
553+
}
554+
547555
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
548556
{
549557
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
@@ -556,8 +564,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
556564
return xfrm_api_check(dev);
557565

558566
case NETDEV_DOWN:
559-
case NETDEV_UNREGISTER:
560567
return xfrm_dev_down(dev);
568+
569+
case NETDEV_UNREGISTER:
570+
return xfrm_dev_unregister(dev);
561571
}
562572
return NOTIFY_DONE;
563573
}

net/xfrm/xfrm_policy.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3801,8 +3801,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
38013801
struct xfrm_tmpl *tp[XFRM_MAX_DEPTH];
38023802
struct xfrm_tmpl *stp[XFRM_MAX_DEPTH];
38033803
struct xfrm_tmpl **tpp = tp;
3804+
int i, k = 0;
38043805
int ti = 0;
3805-
int i, k;
38063806

38073807
sp = skb_sec_path(skb);
38083808
if (!sp)
@@ -3828,6 +3828,12 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
38283828
tpp = stp;
38293829
}
38303830

3831+
if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET && sp == &dummy)
3832+
/* This policy template was already checked by HW
3833+
* and secpath was removed in __xfrm_policy_check2.
3834+
*/
3835+
goto out;
3836+
38313837
/* For each tunnel xfrm, find the first matching tmpl.
38323838
* For each tmpl before that, find corresponding xfrm.
38333839
* Order is _important_. Later we will implement
@@ -3837,7 +3843,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
38373843
* verified to allow them to be skipped in future policy
38383844
* checks (e.g. nested tunnels).
38393845
*/
3840-
for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
3846+
for (i = xfrm_nr - 1; i >= 0; i--) {
38413847
k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
38423848
if (k < 0) {
38433849
if (k < -1)
@@ -3853,6 +3859,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
38533859
goto reject;
38543860
}
38553861

3862+
out:
38563863
xfrm_pols_put(pols, npols);
38573864
sp->verified_cnt = k;
38583865

0 commit comments

Comments
 (0)