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 <[EMAIL PROTECTED]>
> ---
>  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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to