Message ID | 20250122120941.2634198-2-chiachangwang@google.com (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Update offload configuration with SA | expand |
On Wed, Jan 22, 2025 at 12:09:40PM +0000, Chiachang Wang wrote: > The offload setting is set to HW when the ipsec session is > initialized but cannot be changed until the session is torn > down. The session administrator should be able to update > the SA via netlink message. > > This patch ensures that when a SA is updated, the associated > offload configuration is also updated. This is necessary to > maintain consistency between the SA and the offload device, > especially when the device is configured for IPSec offload. > > Any offload changes to the SA are reflected in the kernel > and offload device. > > Test: Enable both in/out crypto offload, and verify with > Android device on WiFi/cellular network, including > 1. WiFi + crypto offload -> WiFi + no offload > 2. WiFi + no offload -> WiFi + crypto offload > 3. Cellular + crypto offload -> Cellular + no offload > 4. Cellular + no offload -> Cellular + crypto offload Can you please provide iproute2/*swan commands here? I would like to test it too and not rely on rely on vague "Android device" thing. > Signed-off-by: Chiachang Wang <chiachangwang@google.com> > --- > net/xfrm/xfrm_state.c | 24 +++++++++++++++++++++++- > 1 file changed, 23 insertions(+), 1 deletion(-) > > diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c > index 67ca7ac955a3..46d75980eb2e 100644 > --- a/net/xfrm/xfrm_state.c > +++ b/net/xfrm/xfrm_state.c > @@ -2047,7 +2047,8 @@ int xfrm_state_update(struct xfrm_state *x) > int err; > int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); > struct net *net = xs_net(x); > - > + struct xfrm_dev_offload *xso; > + struct net_device *old_dev; > to_put = NULL; > > spin_lock_bh(&net->xfrm.xfrm_state_lock); > @@ -2124,7 +2125,28 @@ int xfrm_state_update(struct xfrm_state *x) > __xfrm_state_bump_genids(x1); > spin_unlock_bh(&net->xfrm.xfrm_state_lock); > } > +#ifdef CONFIG_XFRM_OFFLOAD > + x1->type_offload = x->type_offload; > + > + if (memcmp(&x1->xso, &x->xso, sizeof(x1->xso))) { > + old_dev = x1->xso.dev; > + memcpy(&x1->xso, &x->xso, sizeof(x1->xso)); > + > + if (old_dev) > + old_dev->xfrmdev_ops->xdo_dev_state_delete(x1); > + > + if (x1->xso.dev) { > + xso = &x1->xso; > + netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC); > + err = xso->dev->xfrmdev_ops->xdo_dev_state_add(x1, NULL); You should perform whole delete/free/add cycle. Can we have X with offload while x1 without offload? > > + if (err) { > + netdev_put(xso->dev, &xso->dev_tracker); > + goto fail; In such case, you deleted offload from x1 and left "broken" system. > + } > + } > + } > +#endif > err = 0; > x->km.state = XFRM_STATE_DEAD; > __xfrm_state_put(x); > -- > 2.48.1.262.g85cc9f2d1e-goog > >
On Wed, Jan 22, 2025 at 12:09:40PM +0000, Chiachang Wang wrote: > The offload setting is set to HW when the ipsec session is > initialized but cannot be changed until the session is torn > down. The session administrator should be able to update > the SA via netlink message. > > This patch ensures that when a SA is updated, the associated > offload configuration is also updated. This is necessary to > maintain consistency between the SA and the offload device, > especially when the device is configured for IPSec offload. > > Any offload changes to the SA are reflected in the kernel > and offload device. > > Test: Enable both in/out crypto offload, and verify with > Android device on WiFi/cellular network, including > 1. WiFi + crypto offload -> WiFi + no offload > 2. WiFi + no offload -> WiFi + crypto offload > 3. Cellular + crypto offload -> Cellular + no offload > 4. Cellular + no offload -> Cellular + crypto offload > Signed-off-by: Chiachang Wang <chiachangwang@google.com> > --- > net/xfrm/xfrm_state.c | 24 +++++++++++++++++++++++- > 1 file changed, 23 insertions(+), 1 deletion(-) > > diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c ... > @@ -2124,7 +2125,28 @@ int xfrm_state_update(struct xfrm_state *x) > __xfrm_state_bump_genids(x1); > spin_unlock_bh(&net->xfrm.xfrm_state_lock); > } > +#ifdef CONFIG_XFRM_OFFLOAD > + x1->type_offload = x->type_offload; > + > + if (memcmp(&x1->xso, &x->xso, sizeof(x1->xso))) { > + old_dev = x1->xso.dev; > + memcpy(&x1->xso, &x->xso, sizeof(x1->xso)); > + > + if (old_dev) > + old_dev->xfrmdev_ops->xdo_dev_state_delete(x1); > + > + if (x1->xso.dev) { > + xso = &x1->xso; > + netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC); > + err = xso->dev->xfrmdev_ops->xdo_dev_state_add(x1, NULL); > > + if (err) { > + netdev_put(xso->dev, &xso->dev_tracker); > + goto fail; > + } > + } > + } > +#endif For consistency, it looks like all of the code above should be indented by one more tabstop. > err = 0; > x->km.state = XFRM_STATE_DEAD; > __xfrm_state_put(x);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 67ca7ac955a3..46d75980eb2e 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2047,7 +2047,8 @@ int xfrm_state_update(struct xfrm_state *x) int err; int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); struct net *net = xs_net(x); - + struct xfrm_dev_offload *xso; + struct net_device *old_dev; to_put = NULL; spin_lock_bh(&net->xfrm.xfrm_state_lock); @@ -2124,7 +2125,28 @@ int xfrm_state_update(struct xfrm_state *x) __xfrm_state_bump_genids(x1); spin_unlock_bh(&net->xfrm.xfrm_state_lock); } +#ifdef CONFIG_XFRM_OFFLOAD + x1->type_offload = x->type_offload; + + if (memcmp(&x1->xso, &x->xso, sizeof(x1->xso))) { + old_dev = x1->xso.dev; + memcpy(&x1->xso, &x->xso, sizeof(x1->xso)); + + if (old_dev) + old_dev->xfrmdev_ops->xdo_dev_state_delete(x1); + + if (x1->xso.dev) { + xso = &x1->xso; + netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC); + err = xso->dev->xfrmdev_ops->xdo_dev_state_add(x1, NULL); + if (err) { + netdev_put(xso->dev, &xso->dev_tracker); + goto fail; + } + } + } +#endif err = 0; x->km.state = XFRM_STATE_DEAD; __xfrm_state_put(x);
The offload setting is set to HW when the ipsec session is initialized but cannot be changed until the session is torn down. The session administrator should be able to update the SA via netlink message. This patch ensures that when a SA is updated, the associated offload configuration is also updated. This is necessary to maintain consistency between the SA and the offload device, especially when the device is configured for IPSec offload. Any offload changes to the SA are reflected in the kernel and offload device. Test: Enable both in/out crypto offload, and verify with Android device on WiFi/cellular network, including 1. WiFi + crypto offload -> WiFi + no offload 2. WiFi + no offload -> WiFi + crypto offload 3. Cellular + crypto offload -> Cellular + no offload 4. Cellular + no offload -> Cellular + crypto offload Signed-off-by: Chiachang Wang <chiachangwang@google.com> --- net/xfrm/xfrm_state.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)