netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
@ 2007-04-06  7:25 Masahide NAKAMURA
  2007-04-12  5:42 ` Masahide NAKAMURA
  2007-04-30  7:34 ` David Miller
  0 siblings, 2 replies; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-06  7:25 UTC (permalink / raw)
  To: davem; +Cc: netdev, Masahide NAKAMURA

On MIPv6 usage, XFRM sub policy is enabled.
When main (IPsec) and sub (MIPv6) policy selectors have the same
address set but different upper layer information (i.e. protocol
number and its ports or type/code), multiple bundle should be created.
However, currently we have issue to use the same bundle created for
the first time with all flows covered by the case.

It is useful for the bundle to have the upper layer information
to be restructured correctly if it does not match with the flow.

1. Bundle was created by two policies
Selector from another policy is added to xfrm_dst.
If the flow does not match the selector, it goes to slow path to
restructure new bundle by single policy.

2. Bundle was created by one policy
Flow cache is added to xfrm_dst as originated one. If the flow does
not match the cache, it goes to slow path to try searching another
policy.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 include/net/flow.h     |    6 +++++
 include/net/xfrm.h     |   10 ++++++++
 net/xfrm/xfrm_policy.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/include/net/flow.h b/include/net/flow.h
index ce4b10d..f3cc1f8 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -97,4 +97,10 @@ extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
 extern void flow_cache_flush(void);
 extern atomic_t flow_cache_genid;
 
+static inline int flow_cache_uli_match(struct flowi *fl1, struct flowi *fl2)
+{
+	return (fl1->proto == fl2->proto &&
+		!memcmp(&fl1->uli_u, &fl2->uli_u, sizeof(fl1->uli_u)));
+}
+
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5a00aa8..c216c5e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -584,6 +584,10 @@ struct xfrm_dst
 		struct rt6_info		rt6;
 	} u;
 	struct dst_entry *route;
+#ifdef CONFIG_XFRM_SUB_POLICY
+	struct flowi *origin;
+	struct xfrm_selector *partner;
+#endif
 	u32 genid;
 	u32 route_mtu_cached;
 	u32 child_mtu_cached;
@@ -596,6 +600,12 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
 	dst_release(xdst->route);
 	if (likely(xdst->u.dst.xfrm))
 		xfrm_state_put(xdst->u.dst.xfrm);
+#ifdef CONFIG_XFRM_SUB_POLICY
+	kfree(xdst->origin);
+	xdst->origin = NULL;
+	kfree(xdst->partner);
+	xdst->partner = NULL;
+#endif
 }
 
 extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1942575..4a2f68f 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1330,6 +1330,40 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
 	return err;
 }
 
+static int inline
+xfrm_dst_alloc_copy(void **target, void *src, int size)
+{
+	if (!*target) {
+		*target = kmalloc(size, GFP_ATOMIC);
+		if (!*target)
+			return -ENOMEM;
+	}
+	memcpy(*target, src, size);
+	return 0;
+}
+
+static int inline
+xfrm_dst_update_parent(struct dst_entry *dst, struct xfrm_selector *sel)
+{
+#ifdef CONFIG_XFRM_SUB_POLICY
+	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+	return xfrm_dst_alloc_copy((void **)&(xdst->partner),
+				   sel, sizeof(*sel));
+#else
+	return 0;
+#endif
+}
+
+static int inline
+xfrm_dst_update_origin(struct dst_entry *dst, struct flowi *fl)
+{
+#ifdef CONFIG_XFRM_SUB_POLICY
+	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+	return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
+#else
+	return 0;
+#endif
+}
 
 static int stale_bundle(struct dst_entry *dst);
 
@@ -1518,6 +1552,18 @@ restart:
 			err = -EHOSTUNREACH;
 			goto error;
 		}
+
+		if (npols > 1)
+			err = xfrm_dst_update_parent(dst, &pols[1]->selector);
+		else
+			err = xfrm_dst_update_origin(dst, fl);
+		if (unlikely(err)) {
+			write_unlock_bh(&policy->lock);
+			if (dst)
+				dst_free(dst);
+			goto error;
+		}
+
 		dst->next = policy->bundles;
 		policy->bundles = dst;
 		dst_hold(dst);
@@ -1933,6 +1979,15 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
 	if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) ||
 	    (dst->dev && !netif_running(dst->dev)))
 		return 0;
+#ifdef CONFIG_XFRM_SUB_POLICY
+	if (fl) {
+		if (first->origin && !flow_cache_uli_match(first->origin, fl))
+			return 0;
+		if (first->partner &&
+		    !xfrm_selector_match(first->partner, fl, family))
+			return 0;
+	}
+#endif
 
 	last = NULL;
 
-- 
1.5.0.1.GIT


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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-06  7:25 [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle Masahide NAKAMURA
@ 2007-04-12  5:42 ` Masahide NAKAMURA
  2007-04-12  6:24   ` David Miller
  2007-04-30  7:34 ` David Miller
  1 sibling, 1 reply; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-12  5:42 UTC (permalink / raw)
  To: davem; +Cc: Masahide NAKAMURA, netdev

Hello,

I sent the patch, which is required for IPsec usage by Mobile IPv6.
I have not obtained any comments yet. Does anybody have it?

I hope it to be applied.

Thanks,


Masahide NAKAMURA wrote:
> On MIPv6 usage, XFRM sub policy is enabled.
> When main (IPsec) and sub (MIPv6) policy selectors have the same
> address set but different upper layer information (i.e. protocol
> number and its ports or type/code), multiple bundle should be created.
> However, currently we have issue to use the same bundle created for
> the first time with all flows covered by the case.
> 
> It is useful for the bundle to have the upper layer information
> to be restructured correctly if it does not match with the flow.
> 
> 1. Bundle was created by two policies
> Selector from another policy is added to xfrm_dst.
> If the flow does not match the selector, it goes to slow path to
> restructure new bundle by single policy.
> 
> 2. Bundle was created by one policy
> Flow cache is added to xfrm_dst as originated one. If the flow does
> not match the cache, it goes to slow path to try searching another
> policy.
> 
> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
> ---
>  include/net/flow.h     |    6 +++++
>  include/net/xfrm.h     |   10 ++++++++
>  net/xfrm/xfrm_policy.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 71 insertions(+), 0 deletions(-)
> 
> diff --git a/include/net/flow.h b/include/net/flow.h
> index ce4b10d..f3cc1f8 100644
> --- a/include/net/flow.h
> +++ b/include/net/flow.h
> @@ -97,4 +97,10 @@ extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
>  extern void flow_cache_flush(void);
>  extern atomic_t flow_cache_genid;
>  
> +static inline int flow_cache_uli_match(struct flowi *fl1, struct flowi *fl2)
> +{
> +	return (fl1->proto == fl2->proto &&
> +		!memcmp(&fl1->uli_u, &fl2->uli_u, sizeof(fl1->uli_u)));
> +}
> +
>  #endif
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index 5a00aa8..c216c5e 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -584,6 +584,10 @@ struct xfrm_dst
>  		struct rt6_info		rt6;
>  	} u;
>  	struct dst_entry *route;
> +#ifdef CONFIG_XFRM_SUB_POLICY
> +	struct flowi *origin;
> +	struct xfrm_selector *partner;
> +#endif
>  	u32 genid;
>  	u32 route_mtu_cached;
>  	u32 child_mtu_cached;
> @@ -596,6 +600,12 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
>  	dst_release(xdst->route);
>  	if (likely(xdst->u.dst.xfrm))
>  		xfrm_state_put(xdst->u.dst.xfrm);
> +#ifdef CONFIG_XFRM_SUB_POLICY
> +	kfree(xdst->origin);
> +	xdst->origin = NULL;
> +	kfree(xdst->partner);
> +	xdst->partner = NULL;
> +#endif
>  }
>  
>  extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 1942575..4a2f68f 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -1330,6 +1330,40 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
>  	return err;
>  }
>  
> +static int inline
> +xfrm_dst_alloc_copy(void **target, void *src, int size)
> +{
> +	if (!*target) {
> +		*target = kmalloc(size, GFP_ATOMIC);
> +		if (!*target)
> +			return -ENOMEM;
> +	}
> +	memcpy(*target, src, size);
> +	return 0;
> +}
> +
> +static int inline
> +xfrm_dst_update_parent(struct dst_entry *dst, struct xfrm_selector *sel)
> +{
> +#ifdef CONFIG_XFRM_SUB_POLICY
> +	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
> +	return xfrm_dst_alloc_copy((void **)&(xdst->partner),
> +				   sel, sizeof(*sel));
> +#else
> +	return 0;
> +#endif
> +}
> +
> +static int inline
> +xfrm_dst_update_origin(struct dst_entry *dst, struct flowi *fl)
> +{
> +#ifdef CONFIG_XFRM_SUB_POLICY
> +	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
> +	return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
> +#else
> +	return 0;
> +#endif
> +}
>  
>  static int stale_bundle(struct dst_entry *dst);
>  
> @@ -1518,6 +1552,18 @@ restart:
>  			err = -EHOSTUNREACH;
>  			goto error;
>  		}
> +
> +		if (npols > 1)
> +			err = xfrm_dst_update_parent(dst, &pols[1]->selector);
> +		else
> +			err = xfrm_dst_update_origin(dst, fl);
> +		if (unlikely(err)) {
> +			write_unlock_bh(&policy->lock);
> +			if (dst)
> +				dst_free(dst);
> +			goto error;
> +		}
> +
>  		dst->next = policy->bundles;
>  		policy->bundles = dst;
>  		dst_hold(dst);
> @@ -1933,6 +1979,15 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
>  	if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) ||
>  	    (dst->dev && !netif_running(dst->dev)))
>  		return 0;
> +#ifdef CONFIG_XFRM_SUB_POLICY
> +	if (fl) {
> +		if (first->origin && !flow_cache_uli_match(first->origin, fl))
> +			return 0;
> +		if (first->partner &&
> +		    !xfrm_selector_match(first->partner, fl, family))
> +			return 0;
> +	}
> +#endif
>  
>  	last = NULL;
>  


-- 
Masahide NAKAMURA

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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-12  5:42 ` Masahide NAKAMURA
@ 2007-04-12  6:24   ` David Miller
  2007-04-12  6:53     ` Masahide NAKAMURA
  0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2007-04-12  6:24 UTC (permalink / raw)
  To: nakam; +Cc: netdev

From: Masahide NAKAMURA <nakam@linux-ipv6.org>
Date: Thu, 12 Apr 2007 14:42:00 +0900

> Hello,
> 
> I sent the patch, which is required for IPsec usage by Mobile IPv6.
> I have not obtained any comments yet. Does anybody have it?
> 
> I hope it to be applied.

It is in my backlog.  I was struggling with a bug that consumed
a lot of my time, but now I think I've fixed that bug so I can
process patches at a normal rate again.

Please be patient :-)

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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-12  6:24   ` David Miller
@ 2007-04-12  6:53     ` Masahide NAKAMURA
  2007-04-30  4:36       ` Masahide NAKAMURA
  0 siblings, 1 reply; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-12  6:53 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

David Miller wrote:
> From: Masahide NAKAMURA <nakam@linux-ipv6.org>
> Date: Thu, 12 Apr 2007 14:42:00 +0900
> 
>> Hello,
>>
>> I sent the patch, which is required for IPsec usage by Mobile IPv6.
>> I have not obtained any comments yet. Does anybody have it?
>>
>> I hope it to be applied.
> 
> It is in my backlog.  I was struggling with a bug that consumed
> a lot of my time, but now I think I've fixed that bug so I can
> process patches at a normal rate again.
> 
> Please be patient :-)

OK, I understand. Thanks.


-- 
Masahide NAKAMURA

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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-12  6:53     ` Masahide NAKAMURA
@ 2007-04-30  4:36       ` Masahide NAKAMURA
  2007-04-30  5:21         ` David Miller
  0 siblings, 1 reply; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-30  4:36 UTC (permalink / raw)
  To: Masahide NAKAMURA; +Cc: David Miller, netdev

Hello,

On Thu, 12 Apr 2007 15:53:33 +0900
Masahide NAKAMURA <nakam@linux-ipv6.org> wrote:

> David Miller wrote:
> > From: Masahide NAKAMURA <nakam@linux-ipv6.org>
> > Date: Thu, 12 Apr 2007 14:42:00 +0900
> > 
> >> Hello,
> >>
> >> I sent the patch, which is required for IPsec usage by Mobile IPv6.
> >> I have not obtained any comments yet. Does anybody have it?
> >>
> >> I hope it to be applied.
> > 
> > It is in my backlog.  I was struggling with a bug that consumed
> > a lot of my time, but now I think I've fixed that bug so I can
> > process patches at a normal rate again.
> > 
> > Please be patient :-)
> 
> OK, I understand. Thanks.


Can you have a time to check this?
If it is lost, I can send it again.

Regards,

-- 
Masahide NAKAMURA


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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-30  4:36       ` Masahide NAKAMURA
@ 2007-04-30  5:21         ` David Miller
  2007-04-30 16:30           ` Masahide NAKAMURA
  0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2007-04-30  5:21 UTC (permalink / raw)
  To: nakam; +Cc: netdev

From: Masahide NAKAMURA <nakam@linux-ipv6.org>
Date: Mon, 30 Apr 2007 13:36:03 +0900

> Can you have a time to check this?
> If it is lost, I can send it again.

I still have it, I just have not processed it yet.  Each time you try
to remind me and I have to reply with the same exact answer every
time, that takes up time I could be spending getting to your patch.

The way my backlog works is that I process all the things that take
very little brain power first, then if I still have energy left I try
to tackle the entries that require thinking.

Most days I never get to that latter type of entry, and sadly your's
fails into that category.

So you either must be patient or clone me.

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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-06  7:25 [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle Masahide NAKAMURA
  2007-04-12  5:42 ` Masahide NAKAMURA
@ 2007-04-30  7:34 ` David Miller
  2007-04-30 16:30   ` Masahide NAKAMURA
  1 sibling, 1 reply; 9+ messages in thread
From: David Miller @ 2007-04-30  7:34 UTC (permalink / raw)
  To: nakam; +Cc: netdev

From: Masahide NAKAMURA <nakam@linux-ipv6.org>
Date: Fri,  6 Apr 2007 16:25:39 +0900

> On MIPv6 usage, XFRM sub policy is enabled.
> When main (IPsec) and sub (MIPv6) policy selectors have the same
> address set but different upper layer information (i.e. protocol
> number and its ports or type/code), multiple bundle should be created.
> However, currently we have issue to use the same bundle created for
> the first time with all flows covered by the case.
> 
> It is useful for the bundle to have the upper layer information
> to be restructured correctly if it does not match with the flow.
> 
> 1. Bundle was created by two policies
> Selector from another policy is added to xfrm_dst.
> If the flow does not match the selector, it goes to slow path to
> restructure new bundle by single policy.
> 
> 2. Bundle was created by one policy
> Flow cache is added to xfrm_dst as originated one. If the flow does
> not match the cache, it goes to slow path to try searching another
> policy.
> 
> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>

This is an OK solution for the problem for now.

My senses tell me that there is probably some cleaner way to
handle this problem.  If you come up with a better idea for it,
please feel free to bounce your ideas to me.

Thanks.

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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-30  5:21         ` David Miller
@ 2007-04-30 16:30           ` Masahide NAKAMURA
  0 siblings, 0 replies; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-30 16:30 UTC (permalink / raw)
  To: David Miller; +Cc: netdev


On Sun, 29 Apr 2007 22:21:45 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Masahide NAKAMURA <nakam@linux-ipv6.org>
> Date: Mon, 30 Apr 2007 13:36:03 +0900
> 
> > Can you have a time to check this?
> > If it is lost, I can send it again.
> 
> I still have it, I just have not processed it yet.  Each time you try
> to remind me and I have to reply with the same exact answer every
> time, that takes up time I could be spending getting to your patch.
> 
> The way my backlog works is that I process all the things that take
> very little brain power first, then if I still have energy left I try
> to tackle the entries that require thinking.
> 
> Most days I never get to that latter type of entry, and sadly your's
> fails into that category.
> 
> So you either must be patient or clone me.

David, I'm sorry that I bothered
and thank you for clarify.

-- 
Masahide NAKAMURA


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

* Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
  2007-04-30  7:34 ` David Miller
@ 2007-04-30 16:30   ` Masahide NAKAMURA
  0 siblings, 0 replies; 9+ messages in thread
From: Masahide NAKAMURA @ 2007-04-30 16:30 UTC (permalink / raw)
  To: David Miller; +Cc: netdev


On Mon, 30 Apr 2007 00:34:37 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Masahide NAKAMURA <nakam@linux-ipv6.org>
> Date: Fri,  6 Apr 2007 16:25:39 +0900
> 
> > On MIPv6 usage, XFRM sub policy is enabled.
> > When main (IPsec) and sub (MIPv6) policy selectors have the same
> > address set but different upper layer information (i.e. protocol
> > number and its ports or type/code), multiple bundle should be created.
> > However, currently we have issue to use the same bundle created for
> > the first time with all flows covered by the case.
> > 
> > It is useful for the bundle to have the upper layer information
> > to be restructured correctly if it does not match with the flow.
> > 
> > 1. Bundle was created by two policies
> > Selector from another policy is added to xfrm_dst.
> > If the flow does not match the selector, it goes to slow path to
> > restructure new bundle by single policy.
> > 
> > 2. Bundle was created by one policy
> > Flow cache is added to xfrm_dst as originated one. If the flow does
> > not match the cache, it goes to slow path to try searching another
> > policy.
> > 
> > Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
> 
> This is an OK solution for the problem for now.
> 
> My senses tell me that there is probably some cleaner way to
> handle this problem.  If you come up with a better idea for it,
> please feel free to bounce your ideas to me.

I get it. It is added to my TODOs to find another way (which may include
design level change) to achive it.

Thank you,

-- 
Masahide NAKAMURA


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

end of thread, other threads:[~2007-04-30 16:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-06  7:25 [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle Masahide NAKAMURA
2007-04-12  5:42 ` Masahide NAKAMURA
2007-04-12  6:24   ` David Miller
2007-04-12  6:53     ` Masahide NAKAMURA
2007-04-30  4:36       ` Masahide NAKAMURA
2007-04-30  5:21         ` David Miller
2007-04-30 16:30           ` Masahide NAKAMURA
2007-04-30  7:34 ` David Miller
2007-04-30 16:30   ` Masahide NAKAMURA

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).