diff mbox series

[ipsec,v2,1/1] xfrm: Migrate offload configuration

Message ID 20250220073515.3177296-2-chiachangwang@google.com (mailing list archive)
State Awaiting Upstream
Delegated to: Netdev Maintainers
Headers show
Series Update offload configuration with SA | expand

Checks

Context Check Description
netdev/series_format warning Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 0 this patch: 7
netdev/build_tools success Errors and warnings before: 26 (+1) this patch: 26 (+1)
netdev/cc_maintainers warning 5 maintainers not CCed: herbert@gondor.apana.org.au pabeni@redhat.com edumazet@google.com horms@kernel.org kuba@kernel.org
netdev/build_clang fail Errors and warnings before: 0 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 241 this patch: 234
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 97 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Chiachang Wang Feb. 20, 2025, 7:35 a.m. UTC
Add hardware offload configuration to XFRM_MSG_MIGRATE
using an option netlink attribute XFRMA_OFFLOAD_DEV.

In the existing xfrm_state_migrate(), the xfrm_init_state()
is called assuming no hardware offload by default. Even the
original xfrm_state is configured with offload, the setting will
be reset. If the device is configured with hardware offload,
it's reasonable to allow the device to maintain its hardware
offload mode. But the device will end up with offload disabled
after receiving a migration event when the device migrates the
connection from one netdev to another one.

The devices that support migration may work with different
underlying networks, such as mobile devices. The hardware setting
should be forwarded to the different netdev based on the
migration configuration. This change provides the capability
for user space to migrate from one netdev to another.

Test: Tested with kernel test in the Android tree located
      in https://android.googlesource.com/kernel/tests/
      The xfrm_tunnel_test.py under the tests folder in
      particular.

v1 -> v2:
- Address review feedback to correct the logic in the
  xfrm_state_migrate in the migration offload configuration
  change.
- Revise the commit message for "xfrm: Migrate offload configuration"

Signed-off-by: Chiachang Wang <chiachangwang@google.com>
---
 include/net/xfrm.h     |  8 ++++++--
 net/xfrm/xfrm_policy.c |  4 ++--
 net/xfrm/xfrm_state.c  | 14 +++++++++++---
 net/xfrm/xfrm_user.c   | 15 +++++++++++++--
 4 files changed, 32 insertions(+), 9 deletions(-)

--
2.48.1.601.g30ceb7b040-goog

Comments

kernel test robot Feb. 21, 2025, 11:02 a.m. UTC | #1
Hi Chiachang,

kernel test robot noticed the following build errors:

[auto build test ERROR on klassert-ipsec-next/master]
[also build test ERROR on linus/master v6.14-rc3 next-20250221]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Chiachang-Wang/xfrm-Migrate-offload-configuration/20250220-153752
base:   https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
patch link:    https://lore.kernel.org/r/20250220073515.3177296-2-chiachangwang%40google.com
patch subject: [PATCH ipsec v2 1/1] xfrm: Migrate offload configuration
config: i386-buildonly-randconfig-004-20250221 (https://download.01.org/0day-ci/archive/20250221/202502211807.52eely9f-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250221/202502211807.52eely9f-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502211807.52eely9f-lkp@intel.com/

All errors (new ones prefixed by >>):

   net/key/af_key.c: In function 'pfkey_migrate':
>> net/key/af_key.c:2632:16: error: too few arguments to function 'xfrm_migrate'
    2632 |         return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
         |                ^~~~~~~~~~~~
   In file included from net/key/af_key.c:28:
   include/net/xfrm.h:1883:5: note: declared here
    1883 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
         |     ^~~~~~~~~~~~


vim +/xfrm_migrate +2632 net/key/af_key.c

08de61beab8a21c Shinta Sugimoto   2007-02-08  2546  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2547  static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
4c93fbb0626080d David S. Miller   2011-02-25  2548  			 const struct sadb_msg *hdr, void * const *ext_hdrs)
08de61beab8a21c Shinta Sugimoto   2007-02-08  2549  {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2550  	int i, len, ret, err = -EINVAL;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2551  	u8 dir;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2552  	struct sadb_address *sa;
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2553  	struct sadb_x_kmaddress *kma;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2554  	struct sadb_x_policy *pol;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2555  	struct sadb_x_ipsecrequest *rq;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2556  	struct xfrm_selector sel;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2557  	struct xfrm_migrate m[XFRM_MAX_DEPTH];
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2558  	struct xfrm_kmaddress k;
8d549c4f5d92d80 Fan Du            2013-11-07  2559  	struct net *net = sock_net(sk);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2560  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2561  	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1],
08de61beab8a21c Shinta Sugimoto   2007-02-08  2562  				     ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||
08de61beab8a21c Shinta Sugimoto   2007-02-08  2563  	    !ext_hdrs[SADB_X_EXT_POLICY - 1]) {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2564  		err = -EINVAL;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2565  		goto out;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2566  	}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2567  
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2568  	kma = ext_hdrs[SADB_X_EXT_KMADDRESS - 1];
08de61beab8a21c Shinta Sugimoto   2007-02-08  2569  	pol = ext_hdrs[SADB_X_EXT_POLICY - 1];
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2570  
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2571  	if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2572  		err = -EINVAL;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2573  		goto out;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2574  	}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2575  
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2576  	if (kma) {
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2577  		/* convert sadb_x_kmaddress to xfrm_kmaddress */
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2578  		k.reserved = kma->sadb_x_kmaddress_reserved;
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2579  		ret = parse_sockaddr_pair((struct sockaddr *)(kma + 1),
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2580  					  8*(kma->sadb_x_kmaddress_len) - sizeof(*kma),
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2581  					  &k.local, &k.remote, &k.family);
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2582  		if (ret < 0) {
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2583  			err = ret;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2584  			goto out;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2585  		}
13c1d18931ebb5c Arnaud Ebalard    2008-10-05  2586  	}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2587  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2588  	dir = pol->sadb_x_policy_dir - 1;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2589  	memset(&sel, 0, sizeof(sel));
08de61beab8a21c Shinta Sugimoto   2007-02-08  2590  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2591  	/* set source address info of selector */
08de61beab8a21c Shinta Sugimoto   2007-02-08  2592  	sa = ext_hdrs[SADB_EXT_ADDRESS_SRC - 1];
08de61beab8a21c Shinta Sugimoto   2007-02-08  2593  	sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2594  	sel.prefixlen_s = sa->sadb_address_prefixlen;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2595  	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2596  	sel.sport = ((struct sockaddr_in *)(sa + 1))->sin_port;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2597  	if (sel.sport)
582ee43dad8e411 Al Viro           2007-07-26  2598  		sel.sport_mask = htons(0xffff);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2599  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2600  	/* set destination address info of selector */
47162c0b7e26ef2 Himangi Saraogi   2014-05-30  2601  	sa = ext_hdrs[SADB_EXT_ADDRESS_DST - 1];
08de61beab8a21c Shinta Sugimoto   2007-02-08  2602  	pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2603  	sel.prefixlen_d = sa->sadb_address_prefixlen;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2604  	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2605  	sel.dport = ((struct sockaddr_in *)(sa + 1))->sin_port;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2606  	if (sel.dport)
582ee43dad8e411 Al Viro           2007-07-26  2607  		sel.dport_mask = htons(0xffff);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2608  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2609  	rq = (struct sadb_x_ipsecrequest *)(pol + 1);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2610  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2611  	/* extract ipsecrequests */
08de61beab8a21c Shinta Sugimoto   2007-02-08  2612  	i = 0;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2613  	len = pol->sadb_x_policy_len * 8 - sizeof(struct sadb_x_policy);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2614  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2615  	while (len > 0 && i < XFRM_MAX_DEPTH) {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2616  		ret = ipsecrequests_to_migrate(rq, len, &m[i]);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2617  		if (ret < 0) {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2618  			err = ret;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2619  			goto out;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2620  		} else {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2621  			rq = (struct sadb_x_ipsecrequest *)((u8 *)rq + ret);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2622  			len -= ret;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2623  			i++;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2624  		}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2625  	}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2626  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2627  	if (!i || len > 0) {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2628  		err = -EINVAL;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2629  		goto out;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2630  	}
08de61beab8a21c Shinta Sugimoto   2007-02-08  2631  
13c1d18931ebb5c Arnaud Ebalard    2008-10-05 @2632  	return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
bd12240337f4352 Sabrina Dubroca   2022-11-24  2633  			    kma ? &k : NULL, net, NULL, 0, NULL);
08de61beab8a21c Shinta Sugimoto   2007-02-08  2634  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2635   out:
08de61beab8a21c Shinta Sugimoto   2007-02-08  2636  	return err;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2637  }
08de61beab8a21c Shinta Sugimoto   2007-02-08  2638  #else
08de61beab8a21c Shinta Sugimoto   2007-02-08  2639  static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
7f6daa635c28ed6 Stephen Hemminger 2011-03-01  2640  			 const struct sadb_msg *hdr, void * const *ext_hdrs)
08de61beab8a21c Shinta Sugimoto   2007-02-08  2641  {
08de61beab8a21c Shinta Sugimoto   2007-02-08  2642  	return -ENOPROTOOPT;
08de61beab8a21c Shinta Sugimoto   2007-02-08  2643  }
08de61beab8a21c Shinta Sugimoto   2007-02-08  2644  #endif
08de61beab8a21c Shinta Sugimoto   2007-02-08  2645  
08de61beab8a21c Shinta Sugimoto   2007-02-08  2646
diff mbox series

Patch

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 32c09e85a64c..a1359f912298 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1822,12 +1822,16 @@  struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 						u32 if_id);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 				      struct xfrm_migrate *m,
-				      struct xfrm_encap_tmpl *encap);
+				      struct xfrm_encap_tmpl *encap,
+				      struct net *net,
+				      struct xfrm_user_offload *xuo,
+				      struct netlink_ext_ack *extack);
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 		 struct xfrm_migrate *m, int num_bundles,
 		 struct xfrm_kmaddress *k, struct net *net,
 		 struct xfrm_encap_tmpl *encap, u32 if_id,
-		 struct netlink_ext_ack *extack);
+		 struct netlink_ext_ack *extack,
+		 struct xfrm_user_offload *xuo);
 #endif

 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4408c11c0835..3f5a06f3f0d2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4622,7 +4622,7 @@  int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 		 struct xfrm_migrate *m, int num_migrate,
 		 struct xfrm_kmaddress *k, struct net *net,
 		 struct xfrm_encap_tmpl *encap, u32 if_id,
-		 struct netlink_ext_ack *extack)
+		 struct netlink_ext_ack *extack, struct xfrm_user_offload *xuo)
 {
 	int i, err, nx_cur = 0, nx_new = 0;
 	struct xfrm_policy *pol = NULL;
@@ -4655,7 +4655,7 @@  int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 		if ((x = xfrm_migrate_state_find(mp, net, if_id))) {
 			x_cur[nx_cur] = x;
 			nx_cur++;
-			xc = xfrm_state_migrate(x, mp, encap);
+			xc = xfrm_state_migrate(x, mp, encap, net, xuo, extack);
 			if (xc) {
 				x_new[nx_new] = xc;
 				nx_new++;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 67ca7ac955a3..87d5e17b0498 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2007,22 +2007,30 @@  EXPORT_SYMBOL(xfrm_migrate_state_find);

 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 				      struct xfrm_migrate *m,
-				      struct xfrm_encap_tmpl *encap)
+				      struct xfrm_encap_tmpl *encap,
+				      struct net *net,
+				      struct xfrm_user_offload *xuo,
+				      struct netlink_ext_ack *extack)
 {
 	struct xfrm_state *xc;
-
+	bool offload = (xuo);
 	xc = xfrm_state_clone(x, encap);
 	if (!xc)
 		return NULL;

 	xc->props.family = m->new_family;

-	if (xfrm_init_state(xc) < 0)
+	if (__xfrm_init_state(xc, true, offload, NULL) < 0)
 		goto error;

+	x->km.state = XFRM_STATE_VALID;
 	memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr));
 	memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));

+	/* configure the hardware if offload is requested */
+	if (offload && xfrm_dev_state_add(net, xc, xuo, extack))
+		goto error;
+
 	/* add state */
 	if (xfrm_addr_equal(&x->id.daddr, &m->new_daddr, m->new_family)) {
 		/* a care is needed when the destination address of the
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b2876e09328b..505ae2427822 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2989,6 +2989,7 @@  static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 	int n = 0;
 	struct net *net = sock_net(skb->sk);
 	struct xfrm_encap_tmpl  *encap = NULL;
+	struct xfrm_user_offload *xuo = NULL;
 	u32 if_id = 0;

 	if (!attrs[XFRMA_MIGRATE]) {
@@ -3019,11 +3020,21 @@  static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (attrs[XFRMA_IF_ID])
 		if_id = nla_get_u32(attrs[XFRMA_IF_ID]);

+	if (attrs[XFRMA_OFFLOAD_DEV]) {
+		xuo = kmemdup(nla_data(attrs[XFRMA_OFFLOAD_DEV]),
+			      sizeof(*xuo), GFP_KERNEL);
+		if (!xuo) {
+			err = -ENOMEM;
+			goto error;
+		}
+	}
+
 	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap,
-			   if_id, extack);
+			   if_id, extack, xuo);

+error:
 	kfree(encap);
-
+	kfree(xuo);
 	return err;
 }
 #else