aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5ce74a38552..7e088c055cf 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1349,14 +1349,16 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
1349 BUG(); 1349 BUG();
1350 } 1350 }
1351 xdst = dst_alloc(dst_ops, NULL, 0, 0, 0); 1351 xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
1352 memset(&xdst->u.rt6.rt6i_table, 0, sizeof(*xdst) - sizeof(struct dst_entry));
1353 xfrm_policy_put_afinfo(afinfo);
1354 1352
1355 if (likely(xdst)) 1353 if (likely(xdst)) {
1354 memset(&xdst->u.rt6.rt6i_table, 0,
1355 sizeof(*xdst) - sizeof(struct dst_entry));
1356 xdst->flo.ops = &xfrm_bundle_fc_ops; 1356 xdst->flo.ops = &xfrm_bundle_fc_ops;
1357 else 1357 } else
1358 xdst = ERR_PTR(-ENOBUFS); 1358 xdst = ERR_PTR(-ENOBUFS);
1359 1359
1360 xfrm_policy_put_afinfo(afinfo);
1361
1360 return xdst; 1362 return xdst;
1361} 1363}
1362 1364
@@ -1497,7 +1499,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1497 goto free_dst; 1499 goto free_dst;
1498 1500
1499 /* Copy neighbour for reachability confirmation */ 1501 /* Copy neighbour for reachability confirmation */
1500 dst0->neighbour = neigh_clone(dst->neighbour); 1502 dst_set_neighbour(dst0, neigh_clone(dst_get_neighbour(dst)));
1501 1503
1502 xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len); 1504 xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len);
1503 xfrm_init_pmtu(dst_prev); 1505 xfrm_init_pmtu(dst_prev);
@@ -2274,8 +2276,6 @@ static void __xfrm_garbage_collect(struct net *net)
2274{ 2276{
2275 struct dst_entry *head, *next; 2277 struct dst_entry *head, *next;
2276 2278
2277 flow_cache_flush();
2278
2279 spin_lock_bh(&xfrm_policy_sk_bundle_lock); 2279 spin_lock_bh(&xfrm_policy_sk_bundle_lock);
2280 head = xfrm_policy_sk_bundles; 2280 head = xfrm_policy_sk_bundles;
2281 xfrm_policy_sk_bundles = NULL; 2281 xfrm_policy_sk_bundles = NULL;
@@ -2288,6 +2288,18 @@ static void __xfrm_garbage_collect(struct net *net)
2288 } 2288 }
2289} 2289}
2290 2290
2291static void xfrm_garbage_collect(struct net *net)
2292{
2293 flow_cache_flush();
2294 __xfrm_garbage_collect(net);
2295}
2296
2297static void xfrm_garbage_collect_deferred(struct net *net)
2298{
2299 flow_cache_flush_deferred();
2300 __xfrm_garbage_collect(net);
2301}
2302
2291static void xfrm_init_pmtu(struct dst_entry *dst) 2303static void xfrm_init_pmtu(struct dst_entry *dst)
2292{ 2304{
2293 do { 2305 do {
@@ -2385,6 +2397,11 @@ static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
2385 return dst_mtu(dst->path); 2397 return dst_mtu(dst->path);
2386} 2398}
2387 2399
2400static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
2401{
2402 return dst_neigh_lookup(dst->path, daddr);
2403}
2404
2388int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2405int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2389{ 2406{
2390 struct net *net; 2407 struct net *net;
@@ -2410,8 +2427,10 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2410 dst_ops->negative_advice = xfrm_negative_advice; 2427 dst_ops->negative_advice = xfrm_negative_advice;
2411 if (likely(dst_ops->link_failure == NULL)) 2428 if (likely(dst_ops->link_failure == NULL))
2412 dst_ops->link_failure = xfrm_link_failure; 2429 dst_ops->link_failure = xfrm_link_failure;
2430 if (likely(dst_ops->neigh_lookup == NULL))
2431 dst_ops->neigh_lookup = xfrm_neigh_lookup;
2413 if (likely(afinfo->garbage_collect == NULL)) 2432 if (likely(afinfo->garbage_collect == NULL))
2414 afinfo->garbage_collect = __xfrm_garbage_collect; 2433 afinfo->garbage_collect = xfrm_garbage_collect_deferred;
2415 xfrm_policy_afinfo[afinfo->family] = afinfo; 2434 xfrm_policy_afinfo[afinfo->family] = afinfo;
2416 } 2435 }
2417 write_unlock_bh(&xfrm_policy_afinfo_lock); 2436 write_unlock_bh(&xfrm_policy_afinfo_lock);
@@ -2505,7 +2524,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
2505 2524
2506 switch (event) { 2525 switch (event) {
2507 case NETDEV_DOWN: 2526 case NETDEV_DOWN:
2508 __xfrm_garbage_collect(dev_net(dev)); 2527 xfrm_garbage_collect(dev_net(dev));
2509 } 2528 }
2510 return NOTIFY_DONE; 2529 return NOTIFY_DONE;
2511} 2530}