aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_algo.c4
-rw-r--r--net/xfrm/xfrm_input.c5
-rw-r--r--net/xfrm/xfrm_policy.c37
-rw-r--r--net/xfrm/xfrm_user.c3
4 files changed, 37 insertions, 12 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 58064d9e565..791ab2e77f3 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = {
462 .desc = { 462 .desc = {
463 .sadb_alg_id = SADB_X_EALG_AESCTR, 463 .sadb_alg_id = SADB_X_EALG_AESCTR,
464 .sadb_alg_ivlen = 8, 464 .sadb_alg_ivlen = 8,
465 .sadb_alg_minbits = 128, 465 .sadb_alg_minbits = 160,
466 .sadb_alg_maxbits = 256 466 .sadb_alg_maxbits = 288
467 } 467 }
468}, 468},
469}; 469};
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index a026b0ef244..54a0dc2e2f8 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -212,6 +212,11 @@ resume:
212 /* only the first xfrm gets the encap type */ 212 /* only the first xfrm gets the encap type */
213 encap_type = 0; 213 encap_type = 0;
214 214
215 if (async && x->repl->check(x, skb, seq)) {
216 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
217 goto drop_unlock;
218 }
219
215 x->repl->advance(x, seq); 220 x->repl->advance(x, seq);
216 221
217 x->curlft.bytes += skb->len; 222 x->curlft.bytes += skb->len;
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}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c658cb3bc7c..0256b8a0a7c 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2299,7 +2299,8 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2299 if (link->dump == NULL) 2299 if (link->dump == NULL)
2300 return -EINVAL; 2300 return -EINVAL;
2301 2301
2302 return netlink_dump_start(net->xfrm.nlsk, skb, nlh, link->dump, link->done); 2302 return netlink_dump_start(net->xfrm.nlsk, skb, nlh,
2303 link->dump, link->done, 0);
2303 } 2304 }
2304 2305
2305 err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, 2306 err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,