All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/2] Fix issues in xfrm_migrate
@ 2022-01-06  0:52 Yan Yan
  2022-01-06  0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
  2022-01-06  0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan
  0 siblings, 2 replies; 15+ messages in thread
From: Yan Yan @ 2022-01-06  0:52 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong, Yan Yan

This patch series include two patches to fix two issues in xfrm_migrate.

PATCH 1/2 enables distinguishing SAs and SPs based on if_id during the
xfrm_migrate flow. It fixes the problem that when there are multiple
existing SPs with the same direction, the same xfrm_selector and
different endpoint addresses, xfrm_migrate might fail.

PATCH 2/2 enables xfrm_migrate to handle address family change by
breaking the original xfrm_state_clone method into two steps so as to
update the props.family before running xfrm_init_state.

Yan Yan (2):
  xfrm: Check if_id in xfrm_migrate
  xfrm: Fix xfrm migrate issues when address family changes

 include/net/xfrm.h     |  5 +++--
 net/key/af_key.c       |  2 +-
 net/xfrm/xfrm_policy.c | 14 ++++++++------
 net/xfrm/xfrm_state.c  | 40 ++++++++++++++++++++++++++++------------
 net/xfrm/xfrm_user.c   |  6 +++++-
 5 files changed, 45 insertions(+), 22 deletions(-)


base-commit: 18343b80691560f41c3339119a2e9314d4672c77
-- 
2.34.1.448.ga2b2bfdf31-goog


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-06  0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan
@ 2022-01-06  0:52 ` Yan Yan
  2022-01-06 12:22   ` kernel test robot
  2022-01-06 15:55     ` kernel test robot
  2022-01-06  0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan
  1 sibling, 2 replies; 15+ messages in thread
From: Yan Yan @ 2022-01-06  0:52 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong, Yan Yan

This patch enables distinguishing SAs and SPs based on if_id during
the xfrm_migrate flow. This ensures support for xfrm interfaces
throughout the SA/SP lifecycle.

When there are multiple existing SPs with the same direction,
the same xfrm_selector and different endpoint addresses,
xfrm_migrate might fail with ENODATA.

Specifically, the code path for performing xfrm_migrate is:
  Stage 1: find policy to migrate with
    xfrm_migrate_policy_find(sel, dir, type, net)
  Stage 2: find and update state(s) with
    xfrm_migrate_state_find(mp, net)
  Stage 3: update endpoint address(es) of template(s) with
    xfrm_policy_migrate(pol, m, num_migrate)

Currently "Stage 1" always returns the first xfrm_policy that
matches, and "Stage 3" looks for the xfrm_tmpl that matches the
old endpoint address. Thus if there are multiple xfrm_policy
with same selector, direction, type and net, "Stage 1" might
rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA
because it cannot find a xfrm_tmpl with the matching endpoint
address.

The fix is to allow userspace to pass an if_id and add if_id
to the matching rule in Stage 1 and Stage 2 since if_id is a
unique ID for xfrm_policy and xfrm_state. For compatibility,
if_id will only be checked if the attribute is set.

Tested with additions to Android's kernel unit test suite:
https://android-review.googlesource.com/c/kernel/tests/+/1668886

Signed-off-by: Yan Yan <evitayan@google.com>
---
 include/net/xfrm.h     |  5 +++--
 net/key/af_key.c       |  2 +-
 net/xfrm/xfrm_policy.c | 14 ++++++++------
 net/xfrm/xfrm_state.c  |  7 ++++++-
 net/xfrm/xfrm_user.c   |  6 +++++-
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 83b46da8873d..faee50259fd4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1676,14 +1676,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	       const struct xfrm_migrate *m, int num_bundles,
 	       const struct xfrm_kmaddress *k,
 	       const struct xfrm_encap_tmpl *encap);
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+						u32 if_id);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 				      struct xfrm_migrate *m,
 				      struct xfrm_encap_tmpl *encap);
 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);
+		 struct xfrm_encap_tmpl *encap, u32 if_id);
 #endif
 
 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index de24a7d474df..9bf52a09b5ff 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2623,7 +2623,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
 	}
 
 	return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-			    kma ? &k : NULL, net, NULL);
+			    kma ? &k : NULL, net, NULL, 0);
 
  out:
 	return err;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1a06585022ab..cd656b4ec5b9 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4235,7 +4235,7 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
 }
 
 static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
-						    u8 dir, u8 type, struct net *net)
+						    u8 dir, u8 type, struct net *net, u32 if_id)
 {
 	struct xfrm_policy *pol, *ret = NULL;
 	struct hlist_head *chain;
@@ -4244,7 +4244,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 	spin_lock_bh(&net->xfrm.xfrm_policy_lock);
 	chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
 	hlist_for_each_entry(pol, chain, bydst) {
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			priority = ret->priority;
@@ -4256,7 +4257,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 		if ((pol->priority >= priority) && ret)
 			break;
 
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			break;
@@ -4372,7 +4374,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
 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)
+		 struct xfrm_encap_tmpl *encap, u32 if_id)
 {
 	int i, err, nx_cur = 0, nx_new = 0;
 	struct xfrm_policy *pol = NULL;
@@ -4391,14 +4393,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	}
 
 	/* Stage 1 - find policy */
-	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
+	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
 		err = -ENOENT;
 		goto out;
 	}
 
 	/* Stage 2 - find and update state(s) */
 	for (i = 0, mp = m; i < num_migrate; i++, mp++) {
-		if ((x = xfrm_migrate_state_find(mp, net))) {
+		if (x = xfrm_migrate_state_find(mp, net, if_id)) {
 			x_cur[nx_cur] = x;
 			nx_cur++;
 			xc = xfrm_state_migrate(x, mp, encap);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 0407272a990c..f52767685b13 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1603,7 +1603,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
 	return NULL;
 }
 
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+						u32 if_id)
 {
 	unsigned int h;
 	struct xfrm_state *x = NULL;
@@ -1619,6 +1620,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 				continue;
 			if (m->reqid && x->props.reqid != m->reqid)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
@@ -1634,6 +1637,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 			if (x->props.mode != m->mode ||
 			    x->id.proto != m->proto)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e3e26f4da6c2..eda02c5544ae 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2580,6 +2580,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;
+	u32 if_id = 0;
 
 	if (attrs[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
@@ -2604,7 +2605,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 			return -ENOMEM;
 	}
 
-	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap);
+	if (attrs[XFRMA_IF_ID])
+		if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
+
+	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id);
 
 	kfree(encap);
 
-- 
2.34.1.448.ga2b2bfdf31-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes
  2022-01-06  0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan
  2022-01-06  0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
@ 2022-01-06  0:52 ` Yan Yan
  2022-01-12  7:57   ` Steffen Klassert
  1 sibling, 1 reply; 15+ messages in thread
From: Yan Yan @ 2022-01-06  0:52 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong, Yan Yan

xfrm_migrate cannot handle address family change of an xfrm_state.
The symptons are the xfrm_state will be migrated to a wrong address,
and sending as well as receiving packets wil be broken.

This commit fixes it by breaking the original xfrm_state_clone
method into two steps so as to update the props.family before
running xfrm_init_state. As the result, xfrm_state's inner mode,
outer mode, type and IP header length in xfrm_state_migrate can
be updated with the new address family.

Tested with additions to Android's kernel unit test suite:
https://android-review.googlesource.com/c/kernel/tests/+/1885354

Signed-off-by: Yan Yan <evitayan@google.com>
---
 net/xfrm/xfrm_state.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f52767685b13..cac212039bf9 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1504,8 +1504,8 @@ static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx *secu
 	return 0;
 }
 
-static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
-					   struct xfrm_encap_tmpl *encap)
+static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig,
+					    struct xfrm_encap_tmpl *encap)
 {
 	struct net *net = xs_net(orig);
 	struct xfrm_state *x = xfrm_state_alloc(net);
@@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
 	memcpy(&x->mark, &orig->mark, sizeof(x->mark));
 	memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
 
-	if (xfrm_init_state(x) < 0)
-		goto error;
+	return x;
+
+ error:
+	xfrm_state_put(x);
+out:
+	return NULL;
+}
+
+static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x)
+{
+	int err = xfrm_init_state(x);
+
+	if (err < 0)
+		return err;
 
 	x->props.flags = orig->props.flags;
 	x->props.extra_flags = orig->props.extra_flags;
@@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
 	x->replay = orig->replay;
 	x->preplay = orig->preplay;
 
-	return x;
-
- error:
-	xfrm_state_put(x);
-out:
-	return NULL;
+	return 0;
 }
 
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
@@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 {
 	struct xfrm_state *xc;
 
-	xc = xfrm_state_clone(x, encap);
+	xc = xfrm_state_clone1(x, encap);
 	if (!xc)
 		return NULL;
 
+	xc->props.family = m->new_family;
+	if (xfrm_state_clone2(x, xc) < 0)
+		goto error;
+
 	memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr));
 	memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));
 
-- 
2.34.1.448.ga2b2bfdf31-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-06  0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
@ 2022-01-06 12:22   ` kernel test robot
  2022-01-06 15:55     ` kernel test robot
  1 sibling, 0 replies; 15+ messages in thread
From: kernel test robot @ 2022-01-06 12:22 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2870 bytes --]

Hi Yan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77]

url:    https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
base:   18343b80691560f41c3339119a2e9314d4672c77
config: arc-randconfig-r032-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062019.VFveWcCu-lkp(a)intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
        git checkout 2be451f5a66efd5951102e188daee7c730f55dc7
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash net/xfrm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   net/xfrm/xfrm_policy.c: In function 'xfrm_migrate':
>> net/xfrm/xfrm_policy.c:4403:21: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    4403 |                 if (x = xfrm_migrate_state_find(mp, net, if_id)) {
         |                     ^


vim +4403 net/xfrm/xfrm_policy.c

  4373	
  4374	int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  4375			 struct xfrm_migrate *m, int num_migrate,
  4376			 struct xfrm_kmaddress *k, struct net *net,
  4377			 struct xfrm_encap_tmpl *encap, u32 if_id)
  4378	{
  4379		int i, err, nx_cur = 0, nx_new = 0;
  4380		struct xfrm_policy *pol = NULL;
  4381		struct xfrm_state *x, *xc;
  4382		struct xfrm_state *x_cur[XFRM_MAX_DEPTH];
  4383		struct xfrm_state *x_new[XFRM_MAX_DEPTH];
  4384		struct xfrm_migrate *mp;
  4385	
  4386		/* Stage 0 - sanity checks */
  4387		if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
  4388			goto out;
  4389	
  4390		if (dir >= XFRM_POLICY_MAX) {
  4391			err = -EINVAL;
  4392			goto out;
  4393		}
  4394	
  4395		/* Stage 1 - find policy */
  4396		if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
  4397			err = -ENOENT;
  4398			goto out;
  4399		}
  4400	
  4401		/* Stage 2 - find and update state(s) */
  4402		for (i = 0, mp = m; i < num_migrate; i++, mp++) {
> 4403			if (x = xfrm_migrate_state_find(mp, net, if_id)) {

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-06  0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
@ 2022-01-06 15:55     ` kernel test robot
  2022-01-06 15:55     ` kernel test robot
  1 sibling, 0 replies; 15+ messages in thread
From: kernel test robot @ 2022-01-06 15:55 UTC (permalink / raw)
  To: Yan Yan; +Cc: llvm, kbuild-all

Hi Yan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77]

url:    https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
base:   18343b80691560f41c3339119a2e9314d4672c77
config: riscv-randconfig-r002-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062313.QMYcwsyC-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
        git checkout 2be451f5a66efd5951102e188daee7c730f55dc7
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash net/xfrm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> net/xfrm/xfrm_policy.c:4403:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                       ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/xfrm/xfrm_policy.c:4403:9: note: place parentheses around the assignment to silence this warning
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                         ^
                       (                                          )
   net/xfrm/xfrm_policy.c:4403:9: note: use '==' to turn this assignment into an equality comparison
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                         ^
                         ==
   8 warnings generated.


vim +4403 net/xfrm/xfrm_policy.c

  4373	
  4374	int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  4375			 struct xfrm_migrate *m, int num_migrate,
  4376			 struct xfrm_kmaddress *k, struct net *net,
  4377			 struct xfrm_encap_tmpl *encap, u32 if_id)
  4378	{
  4379		int i, err, nx_cur = 0, nx_new = 0;
  4380		struct xfrm_policy *pol = NULL;
  4381		struct xfrm_state *x, *xc;
  4382		struct xfrm_state *x_cur[XFRM_MAX_DEPTH];
  4383		struct xfrm_state *x_new[XFRM_MAX_DEPTH];
  4384		struct xfrm_migrate *mp;
  4385	
  4386		/* Stage 0 - sanity checks */
  4387		if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
  4388			goto out;
  4389	
  4390		if (dir >= XFRM_POLICY_MAX) {
  4391			err = -EINVAL;
  4392			goto out;
  4393		}
  4394	
  4395		/* Stage 1 - find policy */
  4396		if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
  4397			err = -ENOENT;
  4398			goto out;
  4399		}
  4400	
  4401		/* Stage 2 - find and update state(s) */
  4402		for (i = 0, mp = m; i < num_migrate; i++, mp++) {
> 4403			if (x = xfrm_migrate_state_find(mp, net, if_id)) {

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
@ 2022-01-06 15:55     ` kernel test robot
  0 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2022-01-06 15:55 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 7961 bytes --]

Hi Yan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77]

url:    https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
base:   18343b80691560f41c3339119a2e9314d4672c77
config: riscv-randconfig-r002-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062313.QMYcwsyC-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707
        git checkout 2be451f5a66efd5951102e188daee7c730f55dc7
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash net/xfrm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from net/xfrm/xfrm_policy.c:24:
   In file included from include/linux/netdevice.h:37:
   In file included from include/net/net_namespace.h:40:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> net/xfrm/xfrm_policy.c:4403:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                       ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/xfrm/xfrm_policy.c:4403:9: note: place parentheses around the assignment to silence this warning
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                         ^
                       (                                          )
   net/xfrm/xfrm_policy.c:4403:9: note: use '==' to turn this assignment into an equality comparison
                   if (x = xfrm_migrate_state_find(mp, net, if_id)) {
                         ^
                         ==
   8 warnings generated.


vim +4403 net/xfrm/xfrm_policy.c

  4373	
  4374	int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  4375			 struct xfrm_migrate *m, int num_migrate,
  4376			 struct xfrm_kmaddress *k, struct net *net,
  4377			 struct xfrm_encap_tmpl *encap, u32 if_id)
  4378	{
  4379		int i, err, nx_cur = 0, nx_new = 0;
  4380		struct xfrm_policy *pol = NULL;
  4381		struct xfrm_state *x, *xc;
  4382		struct xfrm_state *x_cur[XFRM_MAX_DEPTH];
  4383		struct xfrm_state *x_new[XFRM_MAX_DEPTH];
  4384		struct xfrm_migrate *mp;
  4385	
  4386		/* Stage 0 - sanity checks */
  4387		if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
  4388			goto out;
  4389	
  4390		if (dir >= XFRM_POLICY_MAX) {
  4391			err = -EINVAL;
  4392			goto out;
  4393		}
  4394	
  4395		/* Stage 1 - find policy */
  4396		if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
  4397			err = -ENOENT;
  4398			goto out;
  4399		}
  4400	
  4401		/* Stage 2 - find and update state(s) */
  4402		for (i = 0, mp = m; i < num_migrate; i++, mp++) {
> 4403			if (x = xfrm_migrate_state_find(mp, net, if_id)) {

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes
  2022-01-06  0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan
@ 2022-01-12  7:57   ` Steffen Klassert
  2022-01-19  0:03     ` Yan Yan
  0 siblings, 1 reply; 15+ messages in thread
From: Steffen Klassert @ 2022-01-12  7:57 UTC (permalink / raw)
  To: Yan Yan
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong

On Wed, Jan 05, 2022 at 04:52:51PM -0800, Yan Yan wrote:

...

> -static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
> -					   struct xfrm_encap_tmpl *encap)
> +static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig,
> +					    struct xfrm_encap_tmpl *encap)
>  {
>  	struct net *net = xs_net(orig);
>  	struct xfrm_state *x = xfrm_state_alloc(net);
> @@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
>  	memcpy(&x->mark, &orig->mark, sizeof(x->mark));
>  	memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
>  
> -	if (xfrm_init_state(x) < 0)
> -		goto error;
> +	return x;
> +
> + error:
> +	xfrm_state_put(x);
> +out:
> +	return NULL;
> +}
> +
> +static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x)

I'm not a frind of numbering function names, this just invites to
create xfrm_state_clone3 :)

> +{
> +	int err = xfrm_init_state(x);
> +
> +	if (err < 0)
> +		return err;
>  
>  	x->props.flags = orig->props.flags;
>  	x->props.extra_flags = orig->props.extra_flags;
> @@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
>  	x->replay = orig->replay;
>  	x->preplay = orig->preplay;
>  
> -	return x;
> -
> - error:
> -	xfrm_state_put(x);
> -out:
> -	return NULL;
> +	return 0;
>  }
>  
>  struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
> @@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
>  {
>  	struct xfrm_state *xc;
>  
> -	xc = xfrm_state_clone(x, encap);
> +	xc = xfrm_state_clone1(x, encap);
>  	if (!xc)
>  		return NULL;
>  
> +	xc->props.family = m->new_family;
> +	if (xfrm_state_clone2(x, xc) < 0)
> +		goto error;

xfrm_state_migrate() is the only function that calls xfrm_state_clone().
Wouldn't it be better to move xfrm_init_state() out of xfrm_state_clone()
and call it afterwards?

This would also fix the replay window initialization on ESN because
currently x->props.flags (which holds XFRM_STATE_ESN) is initialized
after xfrm_init_state().


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes
  2022-01-12  7:57   ` Steffen Klassert
@ 2022-01-19  0:03     ` Yan Yan
  0 siblings, 0 replies; 15+ messages in thread
From: Yan Yan @ 2022-01-19  0:03 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski,
	Lorenzo Colitti, Maciej Żenczykowski, nharold, benedictwong

Thanks Steffen, I will pull out xfrm_init_state() as you suggested.

On Tue, Jan 11, 2022 at 11:57 PM Steffen Klassert
<steffen.klassert@secunet.com> wrote:
>
> On Wed, Jan 05, 2022 at 04:52:51PM -0800, Yan Yan wrote:
>
> ...
>
> > -static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
> > -                                        struct xfrm_encap_tmpl *encap)
> > +static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig,
> > +                                         struct xfrm_encap_tmpl *encap)
> >  {
> >       struct net *net = xs_net(orig);
> >       struct xfrm_state *x = xfrm_state_alloc(net);
> > @@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
> >       memcpy(&x->mark, &orig->mark, sizeof(x->mark));
> >       memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
> >
> > -     if (xfrm_init_state(x) < 0)
> > -             goto error;
> > +     return x;
> > +
> > + error:
> > +     xfrm_state_put(x);
> > +out:
> > +     return NULL;
> > +}
> > +
> > +static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x)
>
> I'm not a frind of numbering function names, this just invites to
> create xfrm_state_clone3 :)
>
> > +{
> > +     int err = xfrm_init_state(x);
> > +
> > +     if (err < 0)
> > +             return err;
> >
> >       x->props.flags = orig->props.flags;
> >       x->props.extra_flags = orig->props.extra_flags;
> > @@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
> >       x->replay = orig->replay;
> >       x->preplay = orig->preplay;
> >
> > -     return x;
> > -
> > - error:
> > -     xfrm_state_put(x);
> > -out:
> > -     return NULL;
> > +     return 0;
> >  }
> >
> >  struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
> > @@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
> >  {
> >       struct xfrm_state *xc;
> >
> > -     xc = xfrm_state_clone(x, encap);
> > +     xc = xfrm_state_clone1(x, encap);
> >       if (!xc)
> >               return NULL;
> >
> > +     xc->props.family = m->new_family;
> > +     if (xfrm_state_clone2(x, xc) < 0)
> > +             goto error;
>
> xfrm_state_migrate() is the only function that calls xfrm_state_clone().
> Wouldn't it be better to move xfrm_init_state() out of xfrm_state_clone()
> and call it afterwards?
>
> This would also fix the replay window initialization on ESN because
> currently x->props.flags (which holds XFRM_STATE_ESN) is initialized
> after xfrm_init_state().
>


-- 
--
Best,
Yan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-12 22:53   ` Yan Yan
@ 2022-01-17 11:46     ` Steffen Klassert
  0 siblings, 0 replies; 15+ messages in thread
From: Steffen Klassert @ 2022-01-17 11:46 UTC (permalink / raw)
  To: Yan Yan
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski,
	Lorenzo Colitti, Maciej Żenczykowski, Nathan Harold,
	Benedict Wong

Hi Yan,

On Wed, Jan 12, 2022 at 02:53:31PM -0800, Yan Yan wrote:
> Hi Steffen,
> 
> The Jan 7th patch fixes the following warning (reported by the kernel
> test robot) by adding parentheses.
>    net/xfrm/xfrm_policy.c: In function 'xfrm_migrate':
> >> net/xfrm/xfrm_policy.c:4403:21: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
>     4403 |                 if (x = xfrm_migrate_state_find(mp, net, if_id)) {
>          |                     ^
> 
> In the Jan 7th patch, this line becomes "if ((x =
> xfrm_migrate_state_find(mp, net, if_id))) {"

I thought that was already fixed in the previous version.
Please mark updated patches as v2 etc. and describe the
changes you did in the new version.

Please resend your patchset and add a proper 'Fixes:'
tag to the patches.

Thanks!

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-12  7:32 ` Steffen Klassert
@ 2022-01-12 22:53   ` Yan Yan
  2022-01-17 11:46     ` Steffen Klassert
  0 siblings, 1 reply; 15+ messages in thread
From: Yan Yan @ 2022-01-12 22:53 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski,
	Lorenzo Colitti, Maciej Żenczykowski, Nathan Harold,
	Benedict Wong

Hi Steffen,

The Jan 7th patch fixes the following warning (reported by the kernel
test robot) by adding parentheses.
   net/xfrm/xfrm_policy.c: In function 'xfrm_migrate':
>> net/xfrm/xfrm_policy.c:4403:21: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    4403 |                 if (x = xfrm_migrate_state_find(mp, net, if_id)) {
         |                     ^

In the Jan 7th patch, this line becomes "if ((x =
xfrm_migrate_state_find(mp, net, if_id))) {"


On Tue, Jan 11, 2022 at 11:32 PM Steffen Klassert
<steffen.klassert@secunet.com> wrote:
>
> On Fri, Jan 07, 2022 at 05:32:30PM -0800, Yan Yan wrote:
> > This patch enables distinguishing SAs and SPs based on if_id during
> > the xfrm_migrate flow. This ensures support for xfrm interfaces
> > throughout the SA/SP lifecycle.
> >
> > When there are multiple existing SPs with the same direction,
> > the same xfrm_selector and different endpoint addresses,
> > xfrm_migrate might fail with ENODATA.
> >
> > Specifically, the code path for performing xfrm_migrate is:
> >   Stage 1: find policy to migrate with
> >     xfrm_migrate_policy_find(sel, dir, type, net)
> >   Stage 2: find and update state(s) with
> >     xfrm_migrate_state_find(mp, net)
> >   Stage 3: update endpoint address(es) of template(s) with
> >     xfrm_policy_migrate(pol, m, num_migrate)
> >
> > Currently "Stage 1" always returns the first xfrm_policy that
> > matches, and "Stage 3" looks for the xfrm_tmpl that matches the
> > old endpoint address. Thus if there are multiple xfrm_policy
> > with same selector, direction, type and net, "Stage 1" might
> > rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA
> > because it cannot find a xfrm_tmpl with the matching endpoint
> > address.
> >
> > The fix is to allow userspace to pass an if_id and add if_id
> > to the matching rule in Stage 1 and Stage 2 since if_id is a
> > unique ID for xfrm_policy and xfrm_state. For compatibility,
> > if_id will only be checked if the attribute is set.
> >
> > Tested with additions to Android's kernel unit test suite:
> > https://android-review.googlesource.com/c/kernel/tests/+/1668886
> >
> > Signed-off-by: Yan Yan <evitayan@google.com>
>
> What is the difference between this patch and the one with
> the same subject you sent on Jan 5th?



-- 
--
Best,
Yan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2022-01-08  1:32 [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate Yan Yan
@ 2022-01-12  7:32 ` Steffen Klassert
  2022-01-12 22:53   ` Yan Yan
  0 siblings, 1 reply; 15+ messages in thread
From: Steffen Klassert @ 2022-01-12  7:32 UTC (permalink / raw)
  To: Yan Yan
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong

On Fri, Jan 07, 2022 at 05:32:30PM -0800, Yan Yan wrote:
> This patch enables distinguishing SAs and SPs based on if_id during
> the xfrm_migrate flow. This ensures support for xfrm interfaces
> throughout the SA/SP lifecycle.
> 
> When there are multiple existing SPs with the same direction,
> the same xfrm_selector and different endpoint addresses,
> xfrm_migrate might fail with ENODATA.
> 
> Specifically, the code path for performing xfrm_migrate is:
>   Stage 1: find policy to migrate with
>     xfrm_migrate_policy_find(sel, dir, type, net)
>   Stage 2: find and update state(s) with
>     xfrm_migrate_state_find(mp, net)
>   Stage 3: update endpoint address(es) of template(s) with
>     xfrm_policy_migrate(pol, m, num_migrate)
> 
> Currently "Stage 1" always returns the first xfrm_policy that
> matches, and "Stage 3" looks for the xfrm_tmpl that matches the
> old endpoint address. Thus if there are multiple xfrm_policy
> with same selector, direction, type and net, "Stage 1" might
> rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA
> because it cannot find a xfrm_tmpl with the matching endpoint
> address.
> 
> The fix is to allow userspace to pass an if_id and add if_id
> to the matching rule in Stage 1 and Stage 2 since if_id is a
> unique ID for xfrm_policy and xfrm_state. For compatibility,
> if_id will only be checked if the attribute is set.
> 
> Tested with additions to Android's kernel unit test suite:
> https://android-review.googlesource.com/c/kernel/tests/+/1668886
> 
> Signed-off-by: Yan Yan <evitayan@google.com>

What is the difference between this patch and the one with
the same subject you sent on Jan 5th?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
@ 2022-01-08  1:32 Yan Yan
  2022-01-12  7:32 ` Steffen Klassert
  0 siblings, 1 reply; 15+ messages in thread
From: Yan Yan @ 2022-01-08  1:32 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo,
	maze, nharold, benedictwong, Yan Yan

This patch enables distinguishing SAs and SPs based on if_id during
the xfrm_migrate flow. This ensures support for xfrm interfaces
throughout the SA/SP lifecycle.

When there are multiple existing SPs with the same direction,
the same xfrm_selector and different endpoint addresses,
xfrm_migrate might fail with ENODATA.

Specifically, the code path for performing xfrm_migrate is:
  Stage 1: find policy to migrate with
    xfrm_migrate_policy_find(sel, dir, type, net)
  Stage 2: find and update state(s) with
    xfrm_migrate_state_find(mp, net)
  Stage 3: update endpoint address(es) of template(s) with
    xfrm_policy_migrate(pol, m, num_migrate)

Currently "Stage 1" always returns the first xfrm_policy that
matches, and "Stage 3" looks for the xfrm_tmpl that matches the
old endpoint address. Thus if there are multiple xfrm_policy
with same selector, direction, type and net, "Stage 1" might
rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA
because it cannot find a xfrm_tmpl with the matching endpoint
address.

The fix is to allow userspace to pass an if_id and add if_id
to the matching rule in Stage 1 and Stage 2 since if_id is a
unique ID for xfrm_policy and xfrm_state. For compatibility,
if_id will only be checked if the attribute is set.

Tested with additions to Android's kernel unit test suite:
https://android-review.googlesource.com/c/kernel/tests/+/1668886

Signed-off-by: Yan Yan <evitayan@google.com>
---
 include/net/xfrm.h     |  5 +++--
 net/key/af_key.c       |  2 +-
 net/xfrm/xfrm_policy.c | 14 ++++++++------
 net/xfrm/xfrm_state.c  |  7 ++++++-
 net/xfrm/xfrm_user.c   |  6 +++++-
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 83b46da8873d..faee50259fd4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1676,14 +1676,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	       const struct xfrm_migrate *m, int num_bundles,
 	       const struct xfrm_kmaddress *k,
 	       const struct xfrm_encap_tmpl *encap);
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+						u32 if_id);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 				      struct xfrm_migrate *m,
 				      struct xfrm_encap_tmpl *encap);
 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);
+		 struct xfrm_encap_tmpl *encap, u32 if_id);
 #endif
 
 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index de24a7d474df..9bf52a09b5ff 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2623,7 +2623,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
 	}
 
 	return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-			    kma ? &k : NULL, net, NULL);
+			    kma ? &k : NULL, net, NULL, 0);
 
  out:
 	return err;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1a06585022ab..a5e903ec2b3b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4235,7 +4235,7 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
 }
 
 static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
-						    u8 dir, u8 type, struct net *net)
+						    u8 dir, u8 type, struct net *net, u32 if_id)
 {
 	struct xfrm_policy *pol, *ret = NULL;
 	struct hlist_head *chain;
@@ -4244,7 +4244,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 	spin_lock_bh(&net->xfrm.xfrm_policy_lock);
 	chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
 	hlist_for_each_entry(pol, chain, bydst) {
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			priority = ret->priority;
@@ -4256,7 +4257,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 		if ((pol->priority >= priority) && ret)
 			break;
 
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			break;
@@ -4372,7 +4374,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
 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)
+		 struct xfrm_encap_tmpl *encap, u32 if_id)
 {
 	int i, err, nx_cur = 0, nx_new = 0;
 	struct xfrm_policy *pol = NULL;
@@ -4391,14 +4393,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	}
 
 	/* Stage 1 - find policy */
-	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
+	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
 		err = -ENOENT;
 		goto out;
 	}
 
 	/* Stage 2 - find and update state(s) */
 	for (i = 0, mp = m; i < num_migrate; i++, mp++) {
-		if ((x = xfrm_migrate_state_find(mp, net))) {
+		if ((x = xfrm_migrate_state_find(mp, net, if_id))) {
 			x_cur[nx_cur] = x;
 			nx_cur++;
 			xc = xfrm_state_migrate(x, mp, encap);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 0407272a990c..f52767685b13 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1603,7 +1603,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
 	return NULL;
 }
 
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+						u32 if_id)
 {
 	unsigned int h;
 	struct xfrm_state *x = NULL;
@@ -1619,6 +1620,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 				continue;
 			if (m->reqid && x->props.reqid != m->reqid)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
@@ -1634,6 +1637,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 			if (x->props.mode != m->mode ||
 			    x->id.proto != m->proto)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e3e26f4da6c2..eda02c5544ae 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2580,6 +2580,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;
+	u32 if_id = 0;
 
 	if (attrs[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
@@ -2604,7 +2605,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 			return -ENOMEM;
 	}
 
-	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap);
+	if (attrs[XFRMA_IF_ID])
+		if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
+
+	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id);
 
 	kfree(encap);
 
-- 
2.34.1.575.g55b058a8bb-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2021-12-23  0:45 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
@ 2021-12-25 18:30     ` kernel test robot
  0 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2021-12-25 18:30 UTC (permalink / raw)
  To: Yan Yan, steffen.klassert
  Cc: kbuild-all, herbert, davem, netdev, nharold, benedictwong, maze,
	lorenzo, Yan Yan

Hi Yan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on klassert-ipsec-next/master]
[also build test ERROR on klassert-ipsec/master net-next/master net/master v5.16-rc6 next-20211224]
[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]

url:    https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20211223-084725
base:   https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
config: x86_64-rhel-8.3 (https://download.01.org/0day-ci/archive/20211226/202112260218.oyI4rj2f-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/a1b1a05814d4ac913aa4af753da7e116a3d58342
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20211223-084725
        git checkout a1b1a05814d4ac913aa4af753da7e116a3d58342
        # save the config file to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpio/ net/key/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   net/key/af_key.c: In function 'pfkey_migrate':
>> net/key/af_key.c:2625:9: error: too few arguments to function 'xfrm_migrate'
    2625 |  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:1683:5: note: declared here
    1683 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
         |     ^~~~~~~~~~~~


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

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

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
@ 2021-12-25 18:30     ` kernel test robot
  0 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2021-12-25 18:30 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 9855 bytes --]

Hi Yan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on klassert-ipsec-next/master]
[also build test ERROR on klassert-ipsec/master net-next/master net/master v5.16-rc6 next-20211224]
[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]

url:    https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20211223-084725
base:   https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
config: x86_64-rhel-8.3 (https://download.01.org/0day-ci/archive/20211226/202112260218.oyI4rj2f-lkp(a)intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/a1b1a05814d4ac913aa4af753da7e116a3d58342
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20211223-084725
        git checkout a1b1a05814d4ac913aa4af753da7e116a3d58342
        # save the config file to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpio/ net/key/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   net/key/af_key.c: In function 'pfkey_migrate':
>> net/key/af_key.c:2625:9: error: too few arguments to function 'xfrm_migrate'
    2625 |  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:1683:5: note: declared here
    1683 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
         |     ^~~~~~~~~~~~


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

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

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate
  2021-12-23  0:45 [PATCH v1 0/2] Fix issues " Yan Yan
@ 2021-12-23  0:45 ` Yan Yan
  2021-12-25 18:30     ` kernel test robot
  0 siblings, 1 reply; 15+ messages in thread
From: Yan Yan @ 2021-12-23  0:45 UTC (permalink / raw)
  To: steffen.klassert
  Cc: herbert, davem, netdev, nharold, benedictwong, maze, lorenzo, Yan Yan

This patch enables distinguishing SAs and SPs based on if_id during
the xfrm_migrate flow. This ensures support for xfrm interfaces
throughout the SA/SP lifecycle.

When there are multiple existing SPs with the same direction,
the same xfrm_selector and different endpoint addresses,
xfrm_migrate might fail with ENODATA.

Specifically, the code path for performing xfrm_migrate is:
  Stage 1: find policy to migrate with
    xfrm_migrate_policy_find(sel, dir, type, net)
  Stage 2: find and update state(s) with
    xfrm_migrate_state_find(mp, net)
  Stage 3: update endpoint address(es) of template(s) with
    xfrm_policy_migrate(pol, m, num_migrate)

Currently "Stage 1" always returns the first xfrm_policy that
matches, and "Stage 3" looks for the xfrm_tmpl that matches the
old endpoint address. Thus if there are multiple xfrm_policy
with same selector, direction, type and net, "Stage 1" might
rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA
because it cannot find a xfrm_tmpl with the matching endpoint
address.

The fix is to allow userspace to pass an if_id and add if_id
to the matching rule in Stage 1 and Stage 2 since if_id is a
unique ID for xfrm_policy and xfrm_state. For compatibility,
if_id will only be checked if the attribute is set.

Tested with additions to Android's kernel unit test suite:
https://android-review.googlesource.com/c/kernel/tests/+/1668886

Signed-off-by: Yan Yan <evitayan@google.com>
---
 include/net/xfrm.h     |  5 +++--
 net/xfrm/xfrm_policy.c | 14 ++++++++------
 net/xfrm/xfrm_state.c  |  7 ++++++-
 net/xfrm/xfrm_user.c   |  6 +++++-
 4 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2308210793a0..4fdd0c44b705 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1675,14 +1675,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	       const struct xfrm_migrate *m, int num_bundles,
 	       const struct xfrm_kmaddress *k,
 	       const struct xfrm_encap_tmpl *encap);
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+				 	   u32 if_id);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 				      struct xfrm_migrate *m,
 				      struct xfrm_encap_tmpl *encap);
 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);
+		 struct xfrm_encap_tmpl *encap, u32 if_id);
 #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 1a06585022ab..cd656b4ec5b9 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4235,7 +4235,7 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
 }
 
 static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
-						    u8 dir, u8 type, struct net *net)
+						    u8 dir, u8 type, struct net *net, u32 if_id)
 {
 	struct xfrm_policy *pol, *ret = NULL;
 	struct hlist_head *chain;
@@ -4244,7 +4244,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 	spin_lock_bh(&net->xfrm.xfrm_policy_lock);
 	chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
 	hlist_for_each_entry(pol, chain, bydst) {
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			priority = ret->priority;
@@ -4256,7 +4257,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
 		if ((pol->priority >= priority) && ret)
 			break;
 
-		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+		if ((if_id == 0 || pol->if_id == if_id) &&
+		    xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
 			ret = pol;
 			break;
@@ -4372,7 +4374,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
 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)
+		 struct xfrm_encap_tmpl *encap, u32 if_id)
 {
 	int i, err, nx_cur = 0, nx_new = 0;
 	struct xfrm_policy *pol = NULL;
@@ -4391,14 +4393,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	}
 
 	/* Stage 1 - find policy */
-	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
+	if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
 		err = -ENOENT;
 		goto out;
 	}
 
 	/* Stage 2 - find and update state(s) */
 	for (i = 0, mp = m; i < num_migrate; i++, mp++) {
-		if ((x = xfrm_migrate_state_find(mp, net))) {
+		if (x = xfrm_migrate_state_find(mp, net, if_id)) {
 			x_cur[nx_cur] = x;
 			nx_cur++;
 			xc = xfrm_state_migrate(x, mp, encap);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index a2f4001221d1..74d4283ed282 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1602,7 +1602,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
 	return NULL;
 }
 
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+				           u32 if_id)
 {
 	unsigned int h;
 	struct xfrm_state *x = NULL;
@@ -1618,6 +1619,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 				continue;
 			if (m->reqid && x->props.reqid != m->reqid)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
@@ -1633,6 +1636,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 			if (x->props.mode != m->mode ||
 			    x->id.proto != m->proto)
 				continue;
+			if (if_id != 0 && x->if_id != if_id)
+				continue;
 			if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
 					     m->old_family) ||
 			    !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7c36cc1f3d79..8cbbe8107543 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2579,6 +2579,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;
+	u32 if_id = 0;
 
 	if (attrs[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
@@ -2603,7 +2604,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 			return -ENOMEM;
 	}
 
-	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap);
+	if (attrs[XFRMA_IF_ID])
+		if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
+
+	err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id);
 
 	kfree(encap);
 
-- 
2.34.1.307.g9b7440fafd-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-01-19  0:03 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-06  0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan
2022-01-06  0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
2022-01-06 12:22   ` kernel test robot
2022-01-06 15:55   ` kernel test robot
2022-01-06 15:55     ` kernel test robot
2022-01-06  0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan
2022-01-12  7:57   ` Steffen Klassert
2022-01-19  0:03     ` Yan Yan
  -- strict thread matches above, loose matches on Subject: below --
2022-01-08  1:32 [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate Yan Yan
2022-01-12  7:32 ` Steffen Klassert
2022-01-12 22:53   ` Yan Yan
2022-01-17 11:46     ` Steffen Klassert
2021-12-23  0:45 [PATCH v1 0/2] Fix issues " Yan Yan
2021-12-23  0:45 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan
2021-12-25 18:30   ` kernel test robot
2021-12-25 18:30     ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.