aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-08-29 11:39:34 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-08-29 11:39:34 -0400
commit83b7a664a0c7c39ccfa4c72535dc1c001d4e7a18 (patch)
tree5ba3bbbe977c2047658b41e22d6b2abd5686bf15 /net/xfrm/xfrm_policy.c
parent[GFS2] Allow mounting of gfs2 and gfs2meta at the same time (diff)
parentMerge master.kernel.org:/home/rmk/linux-2.6-serial (diff)
downloadlinux-dev-83b7a664a0c7c39ccfa4c72535dc1c001d4e7a18.tar.xz
linux-dev-83b7a664a0c7c39ccfa4c72535dc1c001d4e7a18.zip
Merge branch 'master' into gfs2
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index f35bc676128c..3da67ca2c3ce 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1134,12 +1134,33 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
}
EXPORT_SYMBOL(__xfrm_route_forward);
+/* Optimize later using cookies and generation ids. */
+
static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
{
- /* If it is marked obsolete, which is how we even get here,
- * then we have purged it from the policy bundle list and we
- * did that for a good reason.
+ /* Code (such as __xfrm4_bundle_create()) sets dst->obsolete
+ * to "-1" to force all XFRM destinations to get validated by
+ * dst_ops->check on every use. We do this because when a
+ * normal route referenced by an XFRM dst is obsoleted we do
+ * not go looking around for all parent referencing XFRM dsts
+ * so that we can invalidate them. It is just too much work.
+ * Instead we make the checks here on every use. For example:
+ *
+ * XFRM dst A --> IPv4 dst X
+ *
+ * X is the "xdst->route" of A (X is also the "dst->path" of A
+ * in this example). If X is marked obsolete, "A" will not
+ * notice. That's what we are validating here via the
+ * stale_bundle() check.
+ *
+ * When a policy's bundle is pruned, we dst_free() the XFRM
+ * dst which causes it's ->obsolete field to be set to a
+ * positive non-zero integer. If an XFRM dst has been pruned
+ * like this, we want to force a new route lookup.
*/
+ if (dst->obsolete < 0 && !stale_bundle(dst))
+ return dst;
+
return NULL;
}