summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2017-11-28 15:45:44 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-30 09:54:26 -0500
commitb6ca8bd5a9198c70c48297390723e4e56bd6e879 (patch)
tree11d7a2c8f9dcdeb28582721da6fcb0705837db25 /include/net
parent45b018beddb631fb9a0ecbc3ba103521b03c4c80 (diff)
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.h3
-rw-r--r--include/net/xfrm.h15
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;