aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-05-03 19:27:10 -0400
committerDavid S. Miller <davem@davemloft.net>2005-05-03 19:27:10 -0400
commitaabc9761b69f1bfa30a78f7005be95cc9cc06175 (patch)
tree50dc9f510011ac03656aeba0595b2b0b5c5f5e22 /net/xfrm
parentd5d75cd6b10ddad2f375b61092754474ad78aec7 (diff)
[IPSEC]: Store idev entries
I found a bug that stopped IPsec/IPv6 from working. About a month ago IPv6 started using rt6i_idev->dev on the cached socket dst entries. If the cached socket dst entry is IPsec, then rt6i_idev will be NULL. Since we want to look at the rt6i_idev of the original route in this case, the easiest fix is to store rt6i_idev in the IPsec dst entry just as we do for a number of other IPv6 route attributes. Unfortunately this means that we need some new code to handle the references to rt6i_idev. That's why this patch is bigger than it would otherwise be. I've also done the same thing for IPv4 since it is conceivable that once these idev attributes start getting used for accounting, we probably need to dereference them for IPv4 IPsec entries too. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c25
1 files changed, 2 insertions, 23 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 80828078733d..55ed979db144 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst)
1028 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); 1028 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC);
1029} 1029}
1030 1030
1031static void xfrm_dst_destroy(struct dst_entry *dst) 1031void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
1032{ 1032{
1033 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
1034
1035 dst_release(xdst->route);
1036
1037 if (!dst->xfrm)
1038 return;
1039 xfrm_state_put(dst->xfrm);
1040 dst->xfrm = NULL;
1041}
1042
1043static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
1044 int unregister)
1045{
1046 if (!unregister)
1047 return;
1048
1049 while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { 1033 while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
1050 dst->dev = &loopback_dev; 1034 dst->dev = &loopback_dev;
1051 dev_hold(&loopback_dev); 1035 dev_hold(&loopback_dev);
1052 dev_put(dev); 1036 dev_put(dev);
1053 } 1037 }
1054} 1038}
1039EXPORT_SYMBOL(xfrm_dst_ifdown);
1055 1040
1056static void xfrm_link_failure(struct sk_buff *skb) 1041static void xfrm_link_failure(struct sk_buff *skb)
1057{ 1042{
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1262 dst_ops->kmem_cachep = xfrm_dst_cache; 1247 dst_ops->kmem_cachep = xfrm_dst_cache;
1263 if (likely(dst_ops->check == NULL)) 1248 if (likely(dst_ops->check == NULL))
1264 dst_ops->check = xfrm_dst_check; 1249 dst_ops->check = xfrm_dst_check;
1265 if (likely(dst_ops->destroy == NULL))
1266 dst_ops->destroy = xfrm_dst_destroy;
1267 if (likely(dst_ops->ifdown == NULL))
1268 dst_ops->ifdown = xfrm_dst_ifdown;
1269 if (likely(dst_ops->negative_advice == NULL)) 1250 if (likely(dst_ops->negative_advice == NULL))
1270 dst_ops->negative_advice = xfrm_negative_advice; 1251 dst_ops->negative_advice = xfrm_negative_advice;
1271 if (likely(dst_ops->link_failure == NULL)) 1252 if (likely(dst_ops->link_failure == NULL))
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
1297 xfrm_policy_afinfo[afinfo->family] = NULL; 1278 xfrm_policy_afinfo[afinfo->family] = NULL;
1298 dst_ops->kmem_cachep = NULL; 1279 dst_ops->kmem_cachep = NULL;
1299 dst_ops->check = NULL; 1280 dst_ops->check = NULL;
1300 dst_ops->destroy = NULL;
1301 dst_ops->ifdown = NULL;
1302 dst_ops->negative_advice = NULL; 1281 dst_ops->negative_advice = NULL;
1303 dst_ops->link_failure = NULL; 1282 dst_ops->link_failure = NULL;
1304 dst_ops->get_mss = NULL; 1283 dst_ops->get_mss = NULL;