diff options
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 37 |
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 | ||
2291 | static void xfrm_garbage_collect(struct net *net) | ||
2292 | { | ||
2293 | flow_cache_flush(); | ||
2294 | __xfrm_garbage_collect(net); | ||
2295 | } | ||
2296 | |||
2297 | static void xfrm_garbage_collect_deferred(struct net *net) | ||
2298 | { | ||
2299 | flow_cache_flush_deferred(); | ||
2300 | __xfrm_garbage_collect(net); | ||
2301 | } | ||
2302 | |||
2291 | static void xfrm_init_pmtu(struct dst_entry *dst) | 2303 | static 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 | ||
2400 | static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
2401 | { | ||
2402 | return dst_neigh_lookup(dst->path, daddr); | ||
2403 | } | ||
2404 | |||
2388 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2405 | int 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 | } |