linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
@ 2013-02-02 17:27 Romain KUNTZ
  2013-02-05  8:12 ` Steffen Klassert
  0 siblings, 1 reply; 14+ messages in thread
From: Romain KUNTZ @ 2013-02-02 17:27 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, davem, herbert, Emmanuel THIERRY, linux-kernel

The current algorithm to insert XFRM policies with a mark and a mask
allows the insertion of more generic policies, but fails when trying
to install more specific policies.

For example, executing the below commands in that order succeed:
 ip -6 xfrm policy flush
 ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
 ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out

But it fails in the reverse order:
 ip -6 xfrm policy flush
 ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
 ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
 RTNETLINK answers: File exists

This patch modifies the tests on the marks and masks and takes the most
straightforward way: compare the mask and mark separately. It requires to 
give the xfrm_mark structure as an argument to some of the xfrm_policy_*
functions, instead of just the mark.

This patch covers the problem for XFRM policies, a similar problem
exists with XFRM states. If the proposed solution is satisfactory, I 
will propose a similar patch for the states. Comments are welcome.

Signed-off-by: Emmanuel Thierry <emmanuel.thierry@telecom-bretagne.eu>
Signed-off-by: Romain Kuntz <r.kuntz@ipflavors.com>
---
 include/net/xfrm.h     |    6 ++++--
 net/xfrm/xfrm_policy.c |   18 +++++++++++-------
 net/xfrm/xfrm_user.c   |   13 +++++++------
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 63445ed..cdd79b7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1529,12 +1529,14 @@ extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
 	int (*func)(struct xfrm_policy *, int, int, void*), void *);
 extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark,
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
+					  struct xfrm_mark *mark,
 					  u8 type, int dir,
 					  struct xfrm_selector *sel,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err);
-struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, u32 id, int delete, int *err);
+struct xfrm_policy *xfrm_policy_byid(struct net *net, struct xfrm_mark *mark,
+				     u8, int dir, u32 id, int delete, int *err);
 int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 07c5857..d9fe665 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -569,7 +569,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	struct xfrm_policy *delpol;
 	struct hlist_head *chain;
 	struct hlist_node *entry, *newpos;
-	u32 mark = policy->mark.v & policy->mark.m;
 
 	write_lock_bh(&xfrm_policy_lock);
 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
@@ -578,7 +577,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == policy->type &&
 		    !selector_cmp(&pol->selector, &policy->selector) &&
-		    (mark & pol->mark.m) == pol->mark.v &&
+		    policy->mark.v == pol->mark.v &&
+		    policy->mark.m == pol->mark.m &&
 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
 		    !WARN_ON(delpol)) {
 			if (excl) {
@@ -623,7 +623,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 }
 EXPORT_SYMBOL(xfrm_policy_insert);
 
-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
+					  struct xfrm_mark *mark, u8 type,
 					  int dir, struct xfrm_selector *sel,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err)
@@ -638,7 +639,8 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == type &&
-		    (mark & pol->mark.m) == pol->mark.v &&
+		    mark->v == pol->mark.v &&
+		    mark->m == pol->mark.m &&
 		    !selector_cmp(sel, &pol->selector) &&
 		    xfrm_sec_ctx_match(ctx, pol->security)) {
 			xfrm_pol_hold(pol);
@@ -663,8 +665,9 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
-				     int dir, u32 id, int delete, int *err)
+struct xfrm_policy *xfrm_policy_byid(struct net *net, struct xfrm_mark *mark,
+				     u8 type, int dir, u32 id,
+				     int delete, int *err)
 {
 	struct xfrm_policy *pol, *ret;
 	struct hlist_head *chain;
@@ -680,7 +683,8 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, byidx) {
 		if (pol->type == type && pol->index == id &&
-		    (mark & pol->mark.m) == pol->mark.v) {
+		    mark->v == pol->mark.v &&
+		    mark->m == pol->mark.m) {
 			xfrm_pol_hold(pol);
 			if (delete) {
 				*err = security_xfrm_policy_delete(
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index eb872b2..2d41902 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1602,7 +1602,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	struct km_event c;
 	int delete;
 	struct xfrm_mark m;
-	u32 mark = xfrm_mark_get(attrs, &m);
+	xfrm_mark_get(attrs, &m);
 
 	p = nlmsg_data(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
@@ -1616,7 +1616,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err);
+		xp = xfrm_policy_byid(net, &m, type, p->dir,
+				      p->index, delete, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1633,7 +1634,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel,
+		xp = xfrm_policy_bysel_ctx(net, &m, type, p->dir, &p->sel,
 					   ctx, delete, &err);
 		security_xfrm_policy_free(ctx);
 	}
@@ -1905,7 +1906,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err = -ENOENT;
 	struct xfrm_mark m;
-	u32 mark = xfrm_mark_get(attrs, &m);
+	xfrm_mark_get(attrs, &m);
 
 	err = copy_from_user_policy_type(&type, attrs);
 	if (err)
@@ -1916,7 +1917,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err);
+		xp = xfrm_policy_byid(net, &m, type, p->dir, p->index, 0, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1933,7 +1934,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir,
+		xp = xfrm_policy_bysel_ctx(net, &m, type, p->dir,
 					   &p->sel, ctx, 0, &err);
 		security_xfrm_policy_free(ctx);
 	}
-- 
1.7.2.5



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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-02 17:27 [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask Romain KUNTZ
@ 2013-02-05  8:12 ` Steffen Klassert
  2013-02-06 13:14   ` jamal
  0 siblings, 1 reply; 14+ messages in thread
From: Steffen Klassert @ 2013-02-05  8:12 UTC (permalink / raw)
  To: Romain KUNTZ
  Cc: netdev, davem, herbert, Emmanuel THIERRY, linux-kernel, Jamal Hadi Salim

Cc Jamal, he introduced the xfrm_mark framework and knows it
probably the best.

On Sat, Feb 02, 2013 at 06:27:03PM +0100, Romain KUNTZ wrote:
> The current algorithm to insert XFRM policies with a mark and a mask
> allows the insertion of more generic policies, but fails when trying
> to install more specific policies.
> 

Hm, I think we will not match always the right policy if we allow both
orders. Lets take your example and assume we have a flow with mark 1.
The policy lookup is a linear search, so we use the first matching
policy. xfrm_policy_match() does the following check on the mark:

if (... || (fl->flowi_mark & pol->mark.m) != pol->mark.v || ...)
	return -ESRCH

> For example, executing the below commands in that order succeed:
>  ip -6 xfrm policy flush
>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out

The policy with mark 1 is the first we find. The policy passes the
mark check and if the flow matches the selectors, we use this policy.

> 
> But it fails in the reverse order:
>  ip -6 xfrm policy flush
>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>  RTNETLINK answers: File exists

With this scenario, we would find the policy with mark and mask 0 first.
This policy passes the mark check too. So we would use this policy if the
flow matches the selectors, but the flow asked for a policy with mark 1.

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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-05  8:12 ` Steffen Klassert
@ 2013-02-06 13:14   ` jamal
  2013-02-06 13:53     ` Emmanuel Thierry
  0 siblings, 1 reply; 14+ messages in thread
From: jamal @ 2013-02-06 13:14 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: Romain KUNTZ, netdev, davem, herbert, Emmanuel THIERRY,
	linux-kernel, Jamal Hadi Salim

Hi Steffen,

On 13-02-05 03:12 AM, Steffen Klassert wrote:
>> For example, executing the below commands in that order succeed:
>>   ip -6 xfrm policy flush
>>   ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>   ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
> The policy with mark 1 is the first we find. The policy passes the
> mark check and if the flow matches the selectors, we use this policy.
>
>> But it fails in the reverse order:
>>   ip -6 xfrm policy flush
>>   ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>   ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>   RTNETLINK answers: File exists
> With this scenario, we would find the policy with mark and mask 0 first.
> This policy passes the mark check too. So we would use this policy if the
> flow matches the selectors, but the flow asked for a policy with mark 1.

I think the intent Romain is expressing is reasonable and should resolved at
insertion time(xfrm_policy_insert()).
i.e even though the policy (such as mark=1) is inserted afterwards, at
insertion time if it proves it is more specific and not duplicate, it 
should be
inserted ahead of the mark=0.
The runtime check will work then.

cheers,
jamal






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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-06 13:14   ` jamal
@ 2013-02-06 13:53     ` Emmanuel Thierry
  2013-02-06 14:30       ` Jamal Hadi Salim
  2013-02-07 10:49       ` Steffen Klassert
  0 siblings, 2 replies; 14+ messages in thread
From: Emmanuel Thierry @ 2013-02-06 13:53 UTC (permalink / raw)
  To: jamal
  Cc: Steffen Klassert, Romain KUNTZ, netdev, davem, herbert,
	linux-kernel, Jamal Hadi Salim


Hello,

Le 6 févr. 2013 à 14:14, jamal a écrit :

> 
> On 13-02-05 03:12 AM, Steffen Klassert wrote:
>>> For example, executing the below commands in that order succeed:
>>>  ip -6 xfrm policy flush
>>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>> The policy with mark 1 is the first we find. The policy passes the
>> mark check and if the flow matches the selectors, we use this policy.
>> 
>>> But it fails in the reverse order:
>>>  ip -6 xfrm policy flush
>>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>  RTNETLINK answers: File exists
>> With this scenario, we would find the policy with mark and mask 0 first.
>> This policy passes the mark check too. So we would use this policy if the
>> flow matches the selectors, but the flow asked for a policy with mark 1.
> 
> I think the intent Romain is expressing is reasonable and should resolved at
> insertion time(xfrm_policy_insert()).
> i.e even though the policy (such as mark=1) is inserted afterwards, at
> insertion time if it proves it is more specific and not duplicate, it should be
> inserted ahead of the mark=0.
> The runtime check will work then.

Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.
Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?

ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005

ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003

Best regards
Emmanuel Thierry


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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-06 13:53     ` Emmanuel Thierry
@ 2013-02-06 14:30       ` Jamal Hadi Salim
  2013-02-06 14:39         ` Emmanuel Thierry
  2013-02-07 10:49       ` Steffen Klassert
  1 sibling, 1 reply; 14+ messages in thread
From: Jamal Hadi Salim @ 2013-02-06 14:30 UTC (permalink / raw)
  To: Emmanuel Thierry
  Cc: Steffen Klassert, Romain KUNTZ, netdev, davem, herbert,
	linux-kernel, Jamal Hadi Salim

On 13-02-06 08:53 AM, Emmanuel Thierry wrote:
> Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.

I think priorities are the way to go in cases of ambiguity.

> Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?
>
> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005
>
> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003

They look different to me, no? i.e i dont see a conflict - one has 
mark=5 and the other
has mark=3.

cheers,
jamal


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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-06 14:30       ` Jamal Hadi Salim
@ 2013-02-06 14:39         ` Emmanuel Thierry
  2013-02-06 15:50           ` Jamal Hadi Salim
  0 siblings, 1 reply; 14+ messages in thread
From: Emmanuel Thierry @ 2013-02-06 14:39 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: Steffen Klassert, Romain KUNTZ, netdev, davem, herbert,
	linux-kernel, Jamal Hadi Salim


Le 6 févr. 2013 à 15:30, Jamal Hadi Salim a écrit :

> On 13-02-06 08:53 AM, Emmanuel Thierry wrote:
>> Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.
> 
> I think priorities are the way to go in cases of ambiguity.
> 
>> Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?
>> 
>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005
>> 
>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003
> 
> They look different to me, no? i.e i dont see a conflict - one has mark=5 and the other
> has mark=3.

I think you misread the example !
Marks are both 1, masks are different.

This case is more complex than a policy with no mark (so mark=0 and mask=0) versus a policy with an exact mark (so mark=1 and mask=0xffffffff), and i wanted to know if the algorithm would take these kind of cases into account.

Best regards
Emmanuel Thierry


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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-06 14:39         ` Emmanuel Thierry
@ 2013-02-06 15:50           ` Jamal Hadi Salim
  0 siblings, 0 replies; 14+ messages in thread
From: Jamal Hadi Salim @ 2013-02-06 15:50 UTC (permalink / raw)
  To: Emmanuel Thierry
  Cc: Steffen Klassert, Romain KUNTZ, netdev, davem, herbert,
	linux-kernel, Jamal Hadi Salim

On 13-02-06 09:39 AM, Emmanuel Thierry wrote:
>

> I think you misread the example !

I did ;->

> Marks are both 1, masks are different.
>
> This case is more complex than a policy
> with no mark (so mark=0 and mask=0) versus
> a policy with an exact mark (so mark=1 and mask=0xffffffff),
> and i wanted to know if the algorithm would take these kind of cases into account.
>

Aha. I think this is pushing the envelope a little - are there good use 
cases for this?
certainly you could insert with most exact mask first. No such check is 
made at the moment.

cheers,
jamal

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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-06 13:53     ` Emmanuel Thierry
  2013-02-06 14:30       ` Jamal Hadi Salim
@ 2013-02-07 10:49       ` Steffen Klassert
  2013-02-07 11:08         ` Emmanuel Thierry
  1 sibling, 1 reply; 14+ messages in thread
From: Steffen Klassert @ 2013-02-07 10:49 UTC (permalink / raw)
  To: Emmanuel Thierry
  Cc: jamal, Romain KUNTZ, netdev, davem, herbert, linux-kernel,
	Jamal Hadi Salim

On Wed, Feb 06, 2013 at 02:53:48PM +0100, Emmanuel Thierry wrote:
> 
> Hello,
> 
> Le 6 févr. 2013 à 14:14, jamal a écrit :
> 
> > 
> > On 13-02-05 03:12 AM, Steffen Klassert wrote:
> >>> For example, executing the below commands in that order succeed:
> >>>  ip -6 xfrm policy flush
> >>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
> >>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
> >> The policy with mark 1 is the first we find. The policy passes the
> >> mark check and if the flow matches the selectors, we use this policy.
> >> 
> >>> But it fails in the reverse order:
> >>>  ip -6 xfrm policy flush
> >>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
> >>>  ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
> >>>  RTNETLINK answers: File exists
> >> With this scenario, we would find the policy with mark and mask 0 first.
> >> This policy passes the mark check too. So we would use this policy if the
> >> flow matches the selectors, but the flow asked for a policy with mark 1.
> > 
> > I think the intent Romain is expressing is reasonable and should resolved at
> > insertion time(xfrm_policy_insert()).
> > i.e even though the policy (such as mark=1) is inserted afterwards, at
> > insertion time if it proves it is more specific and not duplicate, it should be
> > inserted ahead of the mark=0.
> > The runtime check will work then.
> 
> Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.
> Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?
> 
> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005
> 
> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003
> 

We can't decide on the order of these two policies, so we should not
allow to insert both. At least not if the have the same priority,
but we could insert both if they have different priorities.

Would the patch below meet your requirements?

---
 net/xfrm/xfrm_policy.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6c9aa64..b169a69 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -562,6 +562,21 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
 	return 0;
 }
 
+static bool xfrm_mark_match(struct xfrm_policy *policy,
+			    struct xfrm_policy *pol)
+{
+	u32 mark = policy->mark.v & policy->mark.m;
+
+	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
+		return true;
+
+	if ((mark & pol->mark.m) == pol->mark.v &&
+	    policy->priority == pol->priority)
+		return true;
+
+	return false;
+}
+
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 {
 	struct net *net = xp_net(policy);
@@ -569,7 +584,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	struct xfrm_policy *delpol;
 	struct hlist_head *chain;
 	struct hlist_node *entry, *newpos;
-	u32 mark = policy->mark.v & policy->mark.m;
 
 	write_lock_bh(&xfrm_policy_lock);
 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
@@ -578,7 +592,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == policy->type &&
 		    !selector_cmp(&pol->selector, &policy->selector) &&
-		    (mark & pol->mark.m) == pol->mark.v &&
+		    xfrm_mark_match(policy, pol) &&
 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
 		    !WARN_ON(delpol)) {
 			if (excl) {
-- 
1.7.2.5


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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-07 10:49       ` Steffen Klassert
@ 2013-02-07 11:08         ` Emmanuel Thierry
  2013-02-07 11:16           ` Emmanuel Thierry
  2013-02-07 12:54           ` Steffen Klassert
  0 siblings, 2 replies; 14+ messages in thread
From: Emmanuel Thierry @ 2013-02-07 11:08 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: jamal, Romain KUNTZ, netdev, davem, herbert, linux-kernel,
	Jamal Hadi Salim

Hello,

Le 7 févr. 2013 à 11:49, Steffen Klassert <steffen.klassert@secunet.com> a écrit :

> On Wed, Feb 06, 2013 at 02:53:48PM +0100, Emmanuel Thierry wrote:
>> 
>> Le 6 févr. 2013 à 14:14, jamal a écrit :
>> 
>>> 
>>> On 13-02-05 03:12 AM, Steffen Klassert wrote:
>>>>> For example, executing the below commands in that order succeed:
>>>>> ip -6 xfrm policy flush
>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>>> The policy with mark 1 is the first we find. The policy passes the
>>>> mark check and if the flow matches the selectors, we use this policy.
>>>> 
>>>>> But it fails in the reverse order:
>>>>> ip -6 xfrm policy flush
>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>>> RTNETLINK answers: File exists
>>>> With this scenario, we would find the policy with mark and mask 0 first.
>>>> This policy passes the mark check too. So we would use this policy if the
>>>> flow matches the selectors, but the flow asked for a policy with mark 1.
>>> 
>>> I think the intent Romain is expressing is reasonable and should resolved at
>>> insertion time(xfrm_policy_insert()).
>>> i.e even though the policy (such as mark=1) is inserted afterwards, at
>>> insertion time if it proves it is more specific and not duplicate, it should be
>>> inserted ahead of the mark=0.
>>> The runtime check will work then.
>> 
>> Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.
>> Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?
>> 
>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005
>> 
>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003
>> 
> 
> We can't decide on the order of these two policies, so we should not
> allow to insert both. At least not if the have the same priority,
> but we could insert both if they have different priorities.
> 
> Would the patch below meet your requirements?
> 
> ---
> net/xfrm/xfrm_policy.c |   18 ++++++++++++++++--
> 1 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 6c9aa64..b169a69 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -562,6 +562,21 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
> 	return 0;
> }
> 
> +static bool xfrm_mark_match(struct xfrm_policy *policy,
> +			    struct xfrm_policy *pol)
> +{
> +	u32 mark = policy->mark.v & policy->mark.m;
> +
> +	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
> +		return true;
> +
> +	if ((mark & pol->mark.m) == pol->mark.v &&
> +	    policy->priority == pol->priority)
> +		return true;
> +
> +	return false;
> +}
> +
> int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
> {
> 	struct net *net = xp_net(policy);
> @@ -569,7 +584,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
> 	struct xfrm_policy *delpol;
> 	struct hlist_head *chain;
> 	struct hlist_node *entry, *newpos;
> -	u32 mark = policy->mark.v & policy->mark.m;
> 
> 	write_lock_bh(&xfrm_policy_lock);
> 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
> @@ -578,7 +592,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
> 	hlist_for_each_entry(pol, entry, chain, bydst) {
> 		if (pol->type == policy->type &&
> 		    !selector_cmp(&pol->selector, &policy->selector) &&
> -		    (mark & pol->mark.m) == pol->mark.v &&
> +		    xfrm_mark_match(policy, pol) &&
> 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
> 		    !WARN_ON(delpol)) {
> 			if (excl) {
> -- 
> 1.7.2.5
> 

This is a nice idea, however you keep the insertion asymmetric. The usage of xfrm marks in non-conflicting cases will be made possible, but it stays disturbing for a user as the initial example will still have the same behavior:
* Inserting the marked one then the unmarked will succeed
* Inserting the unmarked then the marked one will fail
This gives to the user the feeling of an indeterministic behavior of the xfrm module.

On the base of your patch, i'd propose to make it symmetric (handmade patch below).

Best regards
Emmanuel Thierry

--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c

 static bool xfrm_mark_match(struct xfrm_policy *policy,
 			    struct xfrm_policy *pol)
 {
 	u32 mark = policy->mark.v & policy->mark.m;
+	u32 mark2 = pol->mark.v & pol->mark.m;
 
 	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
 		return true;
 
 	if ((mark & pol->mark.m) == pol->mark.v &&
+	    (mark2 & policy->mark.m) == policy->mark.v &&
 	    policy->priority == pol->priority)
 		return true;
 
 	return false;
 }



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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-07 11:08         ` Emmanuel Thierry
@ 2013-02-07 11:16           ` Emmanuel Thierry
  2013-02-07 12:54           ` Steffen Klassert
  1 sibling, 0 replies; 14+ messages in thread
From: Emmanuel Thierry @ 2013-02-07 11:16 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: jamal, Romain KUNTZ, netdev, davem, herbert, linux-kernel,
	Jamal Hadi Salim


Le 7 févr. 2013 à 12:08, Emmanuel Thierry <emmanuel.thierry@telecom-bretagne.eu> a écrit :

> Hello,
> 
> Le 7 févr. 2013 à 11:49, Steffen Klassert <steffen.klassert@secunet.com> a écrit :
> 
>> On Wed, Feb 06, 2013 at 02:53:48PM +0100, Emmanuel Thierry wrote:
>>> 
>>> Le 6 févr. 2013 à 14:14, jamal a écrit :
>>> 
>>>> 
>>>> On 13-02-05 03:12 AM, Steffen Klassert wrote:
>>>>>> For example, executing the below commands in that order succeed:
>>>>>> ip -6 xfrm policy flush
>>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>>>> The policy with mark 1 is the first we find. The policy passes the
>>>>> mark check and if the flow matches the selectors, we use this policy.
>>>>> 
>>>>>> But it fails in the reverse order:
>>>>>> ip -6 xfrm policy flush
>>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out
>>>>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 1 mask 0xffffffff
>>>>>> RTNETLINK answers: File exists
>>>>> With this scenario, we would find the policy with mark and mask 0 first.
>>>>> This policy passes the mark check too. So we would use this policy if the
>>>>> flow matches the selectors, but the flow asked for a policy with mark 1.
>>>> 
>>>> I think the intent Romain is expressing is reasonable and should resolved at
>>>> insertion time(xfrm_policy_insert()).
>>>> i.e even though the policy (such as mark=1) is inserted afterwards, at
>>>> insertion time if it proves it is more specific and not duplicate, it should be
>>>> inserted ahead of the mark=0.
>>>> The runtime check will work then.
>>> 
>>> Actually, we didn't think about this problem since we work with priorities, putting the default policy (without a mark) at a minor priority than the marked one.
>>> Your remark makes clearer the ideas behind the design of XFRM, but this leads to an interesting concern. If on policy insertion, the policy were inserted depending on the accuracy of the mark (the more the mask is specific, the more the mark must be put at the beginning of the list), how would we decide which is the more specific between these ones ?
>>> 
>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000005
>>> 
>>> ip -6 xfrm policy add src fd00::1/128 dst fd00::2/128 dir out mark 0x00000001 mask 0x00000003
>>> 
>> 
>> We can't decide on the order of these two policies, so we should not
>> allow to insert both. At least not if the have the same priority,
>> but we could insert both if they have different priorities.
>> 
>> Would the patch below meet your requirements?
>> 
>> ---
>> net/xfrm/xfrm_policy.c |   18 ++++++++++++++++--
>> 1 files changed, 16 insertions(+), 2 deletions(-)
>> 
>> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
>> index 6c9aa64..b169a69 100644
>> --- a/net/xfrm/xfrm_policy.c
>> +++ b/net/xfrm/xfrm_policy.c
>> @@ -562,6 +562,21 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
>> 	return 0;
>> }
>> 
>> +static bool xfrm_mark_match(struct xfrm_policy *policy,
>> +			    struct xfrm_policy *pol)
>> +{
>> +	u32 mark = policy->mark.v & policy->mark.m;
>> +
>> +	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
>> +		return true;
>> +
>> +	if ((mark & pol->mark.m) == pol->mark.v &&
>> +	    policy->priority == pol->priority)
>> +		return true;
>> +
>> +	return false;
>> +}
>> +
>> int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
>> {
>> 	struct net *net = xp_net(policy);
>> @@ -569,7 +584,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
>> 	struct xfrm_policy *delpol;
>> 	struct hlist_head *chain;
>> 	struct hlist_node *entry, *newpos;
>> -	u32 mark = policy->mark.v & policy->mark.m;
>> 
>> 	write_lock_bh(&xfrm_policy_lock);
>> 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
>> @@ -578,7 +592,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
>> 	hlist_for_each_entry(pol, entry, chain, bydst) {
>> 		if (pol->type == policy->type &&
>> 		    !selector_cmp(&pol->selector, &policy->selector) &&
>> -		    (mark & pol->mark.m) == pol->mark.v &&
>> +		    xfrm_mark_match(policy, pol) &&
>> 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
>> 		    !WARN_ON(delpol)) {
>> 			if (excl) {
>> -- 
>> 1.7.2.5
>> 
> 
> This is a nice idea, however you keep the insertion asymmetric. The usage of xfrm marks in non-conflicting cases will be made possible, but it stays disturbing for a user as the initial example will still have the same behavior:
> * Inserting the marked one then the unmarked will succeed
> * Inserting the unmarked then the marked one will fail
> This gives to the user the feeling of an indeterministic behavior of the xfrm module.
> 
> On the base of your patch, i'd propose to make it symmetric (handmade patch below).
> 
> Best regards
> Emmanuel Thierry


Excuse the problem of logic, i sent it too quickly, here is the correct proposal:


--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c

 static bool xfrm_mark_match(struct xfrm_policy *policy,
 			    struct xfrm_policy *pol)
 {
 	u32 mark = policy->mark.v & policy->mark.m;
+	u32 mark2 = pol->mark.v & pol->mark.m;
 
 	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
 		return true;
 
-	if ((mark & pol->mark.m) == pol->mark.v &&
+	if (((mark & pol->mark.m) == pol->mark.v ||
+	    (mark2 & policy->mark.m) == policy->mark.v) &&
 	    policy->priority == pol->priority)
 		return true;
 
 	return false;
 }






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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-07 11:08         ` Emmanuel Thierry
  2013-02-07 11:16           ` Emmanuel Thierry
@ 2013-02-07 12:54           ` Steffen Klassert
  2013-02-08 14:16             ` Emmanuel Thierry
  1 sibling, 1 reply; 14+ messages in thread
From: Steffen Klassert @ 2013-02-07 12:54 UTC (permalink / raw)
  To: Emmanuel Thierry
  Cc: jamal, Romain KUNTZ, netdev, davem, herbert, linux-kernel,
	Jamal Hadi Salim

On Thu, Feb 07, 2013 at 12:08:22PM +0100, Emmanuel Thierry wrote:
> 
> This is a nice idea, however you keep the insertion asymmetric. The usage of xfrm marks in non-conflicting cases will be made possible, but it stays disturbing for a user as the initial example will still have the same behavior:
> * Inserting the marked one then the unmarked will succeed
> * Inserting the unmarked then the marked one will fail
> This gives to the user the feeling of an indeterministic behavior of the xfrm module.

This was intended. Inserting the marked one then the unmarked
is a working scenario. Some users might rely on it, so we can't
change this as you proposed.

On the other hand, inserting the unmarked one then the marked
might result in a wrong policy lookup, so we can't allow this.
The only possibility we have, is inserting with different
priorites and that's what I'm proposing.

I fear we have to live with that asymmetric behaviour if
both policies have the same priority.


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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-07 12:54           ` Steffen Klassert
@ 2013-02-08 14:16             ` Emmanuel Thierry
  2013-02-11 12:57               ` Romain KUNTZ
  0 siblings, 1 reply; 14+ messages in thread
From: Emmanuel Thierry @ 2013-02-08 14:16 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: jamal, Romain KUNTZ, netdev, davem, herbert, linux-kernel,
	Jamal Hadi Salim

Hello,

Le 7 févr. 2013 à 13:54, Steffen Klassert <steffen.klassert@secunet.com> a écrit :

> On Thu, Feb 07, 2013 at 12:08:22PM +0100, Emmanuel Thierry wrote:
>> 
>> This is a nice idea, however you keep the insertion asymmetric. The usage of xfrm marks in non-conflicting cases will be made possible, but it stays disturbing for a user as the initial example will still have the same behavior:
>> * Inserting the marked one then the unmarked will succeed
>> * Inserting the unmarked then the marked one will fail
>> This gives to the user the feeling of an indeterministic behavior of the xfrm module.
> 
> This was intended. Inserting the marked one then the unmarked
> is a working scenario. Some users might rely on it, so we can't
> change this as you proposed.
> 
> On the other hand, inserting the unmarked one then the marked
> might result in a wrong policy lookup, so we can't allow this.
> The only possibility we have, is inserting with different
> priorites and that's what I'm proposing.
> 
> I fear we have to live with that asymmetric behaviour if
> both policies have the same priority.
> 

Ok, actually i understand the concern of backward compatibility you expose. It is true that users might be disturbed if we change such a behavior they would rely on.
Anyway, i'm ok with your patch.

Best regards
Emmanuel Thierry

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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-08 14:16             ` Emmanuel Thierry
@ 2013-02-11 12:57               ` Romain KUNTZ
  2013-02-11 13:04                 ` Steffen Klassert
  0 siblings, 1 reply; 14+ messages in thread
From: Romain KUNTZ @ 2013-02-11 12:57 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: jamal, netdev, davem, herbert, Emmanuel THIERRY, linux-kernel,
	Jamal Hadi Salim

Hi Steffen,

Do you plan to resubmit a patch to the mailing list or shall we take care of that?

Thank you,
Romain

On Feb 8, 2013, at 15:16 , Emmanuel Thierry <emmanuel.thierry@telecom-bretagne.eu> wrote:

> Hello,
> 
> Le 7 févr. 2013 à 13:54, Steffen Klassert <steffen.klassert@secunet.com> a écrit :
> 
>> On Thu, Feb 07, 2013 at 12:08:22PM +0100, Emmanuel Thierry wrote:
>>> 
>>> This is a nice idea, however you keep the insertion asymmetric. The usage of xfrm marks in non-conflicting cases will be made possible, but it stays disturbing for a user as the initial example will still have the same behavior:
>>> * Inserting the marked one then the unmarked will succeed
>>> * Inserting the unmarked then the marked one will fail
>>> This gives to the user the feeling of an indeterministic behavior of the xfrm module.
>> 
>> This was intended. Inserting the marked one then the unmarked
>> is a working scenario. Some users might rely on it, so we can't
>> change this as you proposed.
>> 
>> On the other hand, inserting the unmarked one then the marked
>> might result in a wrong policy lookup, so we can't allow this.
>> The only possibility we have, is inserting with different
>> priorites and that's what I'm proposing.
>> 
>> I fear we have to live with that asymmetric behaviour if
>> both policies have the same priority.
>> 
> 
> Ok, actually i understand the concern of backward compatibility you expose. It is true that users might be disturbed if we change such a behavior they would rely on.
> Anyway, i'm ok with your patch.
> 
> Best regards
> Emmanuel Thierry

-- 
Romain KUNTZ
IP flavors | http://www.ipflavors.com
+33 (0)6 61 29 50 52
r.kuntz@ipflavors.com




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

* Re: [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask.
  2013-02-11 12:57               ` Romain KUNTZ
@ 2013-02-11 13:04                 ` Steffen Klassert
  0 siblings, 0 replies; 14+ messages in thread
From: Steffen Klassert @ 2013-02-11 13:04 UTC (permalink / raw)
  To: Romain KUNTZ
  Cc: jamal, netdev, davem, herbert, Emmanuel THIERRY, linux-kernel,
	Jamal Hadi Salim

On Mon, Feb 11, 2013 at 01:57:59PM +0100, Romain KUNTZ wrote:
> Hi Steffen,
> 
> Do you plan to resubmit a patch to the mailing list or shall we take care of that?
> 

I'm testing with the patch below. If it shows no regression,
I'll apply it to the ipsec-next tree.

Subject: [PATCH] xfrm: Allow inserting policies with matching mark and
 different priorities

We currently can not insert policies with mark and mask
such that some flows would be matched from both policies.
We make this possible when the priority of these policies
are different. If both policies match a flow, the one with
the higher priority is used.

Reported-by: Emmanuel Thierry <emmanuel.thierry@telecom-bretagne.eu>
Reported-by: Romain Kuntz <r.kuntz@ipflavors.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_policy.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 456b11b..257dfb1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -607,6 +607,21 @@ static void xfrm_policy_requeue(struct xfrm_policy *old,
 	spin_unlock_bh(&pq->hold_queue.lock);
 }
 
+static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
+				   struct xfrm_policy *pol)
+{
+	u32 mark = policy->mark.v & policy->mark.m;
+
+	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
+		return true;
+
+	if ((mark & pol->mark.m) == pol->mark.v &&
+	    policy->priority == pol->priority)
+		return true;
+
+	return false;
+}
+
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 {
 	struct net *net = xp_net(policy);
@@ -614,7 +629,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	struct xfrm_policy *delpol;
 	struct hlist_head *chain;
 	struct hlist_node *entry, *newpos;
-	u32 mark = policy->mark.v & policy->mark.m;
 
 	write_lock_bh(&xfrm_policy_lock);
 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
@@ -623,7 +637,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == policy->type &&
 		    !selector_cmp(&pol->selector, &policy->selector) &&
-		    (mark & pol->mark.m) == pol->mark.v &&
+		    xfrm_policy_mark_match(policy, pol) &&
 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
 		    !WARN_ON(delpol)) {
 			if (excl) {
-- 
1.7.9.5


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

end of thread, other threads:[~2013-02-11 13:04 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-02 17:27 [RFC PATCH] xfrm: fix handling of XFRM policies mark and mask Romain KUNTZ
2013-02-05  8:12 ` Steffen Klassert
2013-02-06 13:14   ` jamal
2013-02-06 13:53     ` Emmanuel Thierry
2013-02-06 14:30       ` Jamal Hadi Salim
2013-02-06 14:39         ` Emmanuel Thierry
2013-02-06 15:50           ` Jamal Hadi Salim
2013-02-07 10:49       ` Steffen Klassert
2013-02-07 11:08         ` Emmanuel Thierry
2013-02-07 11:16           ` Emmanuel Thierry
2013-02-07 12:54           ` Steffen Klassert
2013-02-08 14:16             ` Emmanuel Thierry
2013-02-11 12:57               ` Romain KUNTZ
2013-02-11 13:04                 ` Steffen Klassert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).