[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <461DC6A8.9040501@linux-ipv6.org>
Date: Thu, 12 Apr 2007 14:42:00 +0900
From: Masahide NAKAMURA <nakam@...ux-ipv6.org>
To: davem@...emloft.net
Cc: Masahide NAKAMURA <nakam@...ux-ipv6.org>, netdev@...r.kernel.org
Subject: Re: [RFC] [PATCH] [XFRM]: Restrict upper layer information by bundle.
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@...ux-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
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists