diff options
author | David Miller <davem@davemloft.net> | 2017-11-28 15:45:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-30 09:54:26 -0500 |
commit | b6ca8bd5a9198c70c48297390723e4e56bd6e879 (patch) | |
tree | 11d7a2c8f9dcdeb28582721da6fcb0705837db25 /include/net | |
parent | 45b018beddb631fb9a0ecbc3ba103521b03c4c80 (diff) | |
download | linux-b6ca8bd5a9198c70c48297390723e4e56bd6e879.tar.bz2 |
xfrm: Move child route linkage into xfrm_dst.
XFRM bundle child chains look like this:
xdst1 --> xdst2 --> xdst3 --> path_dst
All of xdstN are xfrm_dst objects and xdst->u.dst.xfrm is non-NULL.
The final child pointer in the chain, here called 'path_dst', is some
other kind of route such as an ipv4 or ipv6 one.
The xfrm output path pops routes, one at a time, via the child
pointer, until we hit one which has a dst->xfrm pointer which
is NULL.
We can easily preserve the above mechanisms with child sitting
only in the xfrm_dst structure. All children in the chain
before we break out of the xfrm_output() loop have dst->xfrm
non-NULL and are therefore xfrm_dst objects.
Since we break out of the loop when we find dst->xfrm NULL, we
will not try to dereference 'dst' as if it were an xfrm_dst.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/dst.h | 3 | ||||
-rw-r--r-- | include/net/xfrm.h | 15 |
2 files changed, 11 insertions, 7 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index acbb3fb89c4d..cef46207408c 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -35,7 +35,6 @@ struct sk_buff; struct dst_entry { struct net_device *dev; struct rcu_head rcu_head; - struct dst_entry *child; struct dst_ops *ops; unsigned long _metrics; unsigned long expires; @@ -89,7 +88,7 @@ struct dst_entry { * Align __refcnt to a 64 bytes alignment * (L1_CACHE_SIZE would be too much) */ - long __pad_to_align_refcnt[2]; + long __pad_to_align_refcnt[3]; #endif /* * __refcnt wants to be on a different cache line from diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 4c08eb0d46ce..0009dab61528 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -968,7 +968,7 @@ static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_c /* A struct encoding bundle of transformations to apply to some set of flow. * - * dst->child points to the next element of bundle. + * xdst->child points to the next element of bundle. * dst->xfrm points to an instanse of transformer. * * Due to unfortunate limitations of current routing cache, which we @@ -984,6 +984,7 @@ struct xfrm_dst { struct rt6_info rt6; } u; struct dst_entry *route; + struct dst_entry *child; struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; int num_pols, num_xfrms; u32 xfrm_genid; @@ -997,8 +998,10 @@ struct xfrm_dst { static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst) { #ifdef CONFIG_XFRM - if (dst->xfrm) - return dst->child; + if (dst->xfrm) { + struct xfrm_dst *xdst = (struct xfrm_dst *) dst; + return xdst->child; + } #endif return NULL; } @@ -1006,7 +1009,7 @@ static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst) #ifdef CONFIG_XFRM static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child) { - xdst->u.dst.child = child; + xdst->child = child; } static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) @@ -1880,12 +1883,14 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) { struct xfrm_state *x = dst->xfrm; + struct xfrm_dst *xdst; if (!x || !x->type_offload) return false; + xdst = (struct xfrm_dst *) dst; if (x->xso.offload_handle && (x->xso.dev == dst->path->dev) && - !dst->child->xfrm) + !xdst->child->xfrm) return true; return false; |