aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-02-14 13:29:20 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-14 13:29:20 -0500
commite0376d004307e2b882afcf9e73b2ed5b66d57aee (patch)
tree763b8c26622864855b7bf664ff5f30a62cd7d8f3
parent15004cab947314ac0f2fd47169de95ce48bafb15 (diff)
parent7cb8a93968e395e40a72a50da0b6114e752304b4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== 1) Remove a duplicated call to skb_orphan() in pf_key, from Cong Wang. 2) Prepare xfrm and pf_key for algorithms without pf_key support, from Jussi Kivilinna. 3) Fix an unbalanced lock in xfrm_output_one(), from Li RongQing. 4) Add an IPsec state resolution packet queue to handle packets that are send before the states are resolved. 5) xfrm4_policy_fini() is unused since 2.6.11, time to remove it. From Michal Kubecek. 6) The xfrm gc threshold was configurable just in the initial namespace, make it configurable in all namespaces. From Michal Kubecek. 7) We currently can not insert policies with mark and mask such that some flows would be matched from both policies. Allow this if the priorities of these policies are different, the one with the higher priority is used in this case. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--include/net/xfrm.h12
-rw-r--r--net/ipv4/xfrm4_policy.c58
-rw-r--r--net/ipv6/xfrm6_policy.c52
-rw-r--r--net/key/af_key.c40
-rw-r--r--net/xfrm/xfrm_algo.c65
-rw-r--r--net/xfrm/xfrm_output.c2
-rw-r--r--net/xfrm/xfrm_policy.c247
10 files changed, 438 insertions, 41 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index 9a7881066fb3..3da47e0a4a1f 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -61,6 +61,7 @@ struct dst_entry {
61#define DST_NOPEER 0x0040 61#define DST_NOPEER 0x0040
62#define DST_FAKE_RTABLE 0x0080 62#define DST_FAKE_RTABLE 0x0080
63#define DST_XFRM_TUNNEL 0x0100 63#define DST_XFRM_TUNNEL 0x0100
64#define DST_XFRM_QUEUE 0x0200
64 65
65 unsigned short pending_confirm; 66 unsigned short pending_confirm;
66 67
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 9b78862014a4..2ba9de89e8ec 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -22,6 +22,7 @@ struct netns_ipv4 {
22 struct ctl_table_header *frags_hdr; 22 struct ctl_table_header *frags_hdr;
23 struct ctl_table_header *ipv4_hdr; 23 struct ctl_table_header *ipv4_hdr;
24 struct ctl_table_header *route_hdr; 24 struct ctl_table_header *route_hdr;
25 struct ctl_table_header *xfrm4_hdr;
25#endif 26#endif
26 struct ipv4_devconf *devconf_all; 27 struct ipv4_devconf *devconf_all;
27 struct ipv4_devconf *devconf_dflt; 28 struct ipv4_devconf *devconf_dflt;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 214cb0a53359..1242f371718b 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -16,6 +16,7 @@ struct netns_sysctl_ipv6 {
16 struct ctl_table_header *route_hdr; 16 struct ctl_table_header *route_hdr;
17 struct ctl_table_header *icmp_hdr; 17 struct ctl_table_header *icmp_hdr;
18 struct ctl_table_header *frags_hdr; 18 struct ctl_table_header *frags_hdr;
19 struct ctl_table_header *xfrm6_hdr;
19#endif 20#endif
20 int bindv6only; 21 int bindv6only;
21 int flush_delay; 22 int flush_delay;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index de34883e8b16..24c8886fd969 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -501,6 +501,12 @@ struct xfrm_policy_walk {
501 u32 seq; 501 u32 seq;
502}; 502};
503 503
504struct xfrm_policy_queue {
505 struct sk_buff_head hold_queue;
506 struct timer_list hold_timer;
507 unsigned long timeout;
508};
509
504struct xfrm_policy { 510struct xfrm_policy {
505#ifdef CONFIG_NET_NS 511#ifdef CONFIG_NET_NS
506 struct net *xp_net; 512 struct net *xp_net;
@@ -522,6 +528,7 @@ struct xfrm_policy {
522 struct xfrm_lifetime_cfg lft; 528 struct xfrm_lifetime_cfg lft;
523 struct xfrm_lifetime_cur curlft; 529 struct xfrm_lifetime_cur curlft;
524 struct xfrm_policy_walk_entry walk; 530 struct xfrm_policy_walk_entry walk;
531 struct xfrm_policy_queue polq;
525 u8 type; 532 u8 type;
526 u8 action; 533 u8 action;
527 u8 flags; 534 u8 flags;
@@ -1320,6 +1327,7 @@ struct xfrm_algo_desc {
1320 char *name; 1327 char *name;
1321 char *compat; 1328 char *compat;
1322 u8 available:1; 1329 u8 available:1;
1330 u8 pfkey_supported:1;
1323 union { 1331 union {
1324 struct xfrm_algo_aead_info aead; 1332 struct xfrm_algo_aead_info aead;
1325 struct xfrm_algo_auth_info auth; 1333 struct xfrm_algo_auth_info auth;
@@ -1561,8 +1569,8 @@ extern void xfrm_input_init(void);
1561extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq); 1569extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
1562 1570
1563extern void xfrm_probe_algs(void); 1571extern void xfrm_probe_algs(void);
1564extern int xfrm_count_auth_supported(void); 1572extern int xfrm_count_pfkey_auth_supported(void);
1565extern int xfrm_count_enc_supported(void); 1573extern int xfrm_count_pfkey_enc_supported(void);
1566extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx); 1574extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1567extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); 1575extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1568extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); 1576extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 3be0ac2c1920..9a459be24af7 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -262,21 +262,56 @@ static struct ctl_table xfrm4_policy_table[] = {
262 { } 262 { }
263}; 263};
264 264
265static struct ctl_table_header *sysctl_hdr; 265static int __net_init xfrm4_net_init(struct net *net)
266#endif
267
268static void __init xfrm4_policy_init(void)
269{ 266{
270 xfrm_policy_register_afinfo(&xfrm4_policy_afinfo); 267 struct ctl_table *table;
268 struct ctl_table_header *hdr;
269
270 table = xfrm4_policy_table;
271 if (!net_eq(net, &init_net)) {
272 table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL);
273 if (!table)
274 goto err_alloc;
275
276 table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh;
277 }
278
279 hdr = register_net_sysctl(net, "net/ipv4", table);
280 if (!hdr)
281 goto err_reg;
282
283 net->ipv4.xfrm4_hdr = hdr;
284 return 0;
285
286err_reg:
287 if (!net_eq(net, &init_net))
288 kfree(table);
289err_alloc:
290 return -ENOMEM;
271} 291}
272 292
273static void __exit xfrm4_policy_fini(void) 293static void __net_exit xfrm4_net_exit(struct net *net)
274{ 294{
275#ifdef CONFIG_SYSCTL 295 struct ctl_table *table;
276 if (sysctl_hdr) 296
277 unregister_net_sysctl_table(sysctl_hdr); 297 if (net->ipv4.xfrm4_hdr == NULL)
298 return;
299
300 table = net->ipv4.xfrm4_hdr->ctl_table_arg;
301 unregister_net_sysctl_table(net->ipv4.xfrm4_hdr);
302 if (!net_eq(net, &init_net))
303 kfree(table);
304}
305
306static struct pernet_operations __net_initdata xfrm4_net_ops = {
307 .init = xfrm4_net_init,
308 .exit = xfrm4_net_exit,
309};
278#endif 310#endif
279 xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); 311
312static void __init xfrm4_policy_init(void)
313{
314 xfrm_policy_register_afinfo(&xfrm4_policy_afinfo);
280} 315}
281 316
282void __init xfrm4_init(void) 317void __init xfrm4_init(void)
@@ -286,8 +321,7 @@ void __init xfrm4_init(void)
286 xfrm4_state_init(); 321 xfrm4_state_init();
287 xfrm4_policy_init(); 322 xfrm4_policy_init();
288#ifdef CONFIG_SYSCTL 323#ifdef CONFIG_SYSCTL
289 sysctl_hdr = register_net_sysctl(&init_net, "net/ipv4", 324 register_pernet_subsys(&xfrm4_net_ops);
290 xfrm4_policy_table);
291#endif 325#endif
292} 326}
293 327
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 128273744332..4ef7bdb65440 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -320,7 +320,51 @@ static struct ctl_table xfrm6_policy_table[] = {
320 { } 320 { }
321}; 321};
322 322
323static struct ctl_table_header *sysctl_hdr; 323static int __net_init xfrm6_net_init(struct net *net)
324{
325 struct ctl_table *table;
326 struct ctl_table_header *hdr;
327
328 table = xfrm6_policy_table;
329 if (!net_eq(net, &init_net)) {
330 table = kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL);
331 if (!table)
332 goto err_alloc;
333
334 table[0].data = &net->xfrm.xfrm6_dst_ops.gc_thresh;
335 }
336
337 hdr = register_net_sysctl(net, "net/ipv6", table);
338 if (!hdr)
339 goto err_reg;
340
341 net->ipv6.sysctl.xfrm6_hdr = hdr;
342 return 0;
343
344err_reg:
345 if (!net_eq(net, &init_net))
346 kfree(table);
347err_alloc:
348 return -ENOMEM;
349}
350
351static void __net_exit xfrm6_net_exit(struct net *net)
352{
353 struct ctl_table *table;
354
355 if (net->ipv6.sysctl.xfrm6_hdr == NULL)
356 return;
357
358 table = net->ipv6.sysctl.xfrm6_hdr->ctl_table_arg;
359 unregister_net_sysctl_table(net->ipv6.sysctl.xfrm6_hdr);
360 if (!net_eq(net, &init_net))
361 kfree(table);
362}
363
364static struct pernet_operations xfrm6_net_ops = {
365 .init = xfrm6_net_init,
366 .exit = xfrm6_net_exit,
367};
324#endif 368#endif
325 369
326int __init xfrm6_init(void) 370int __init xfrm6_init(void)
@@ -339,8 +383,7 @@ int __init xfrm6_init(void)
339 goto out_policy; 383 goto out_policy;
340 384
341#ifdef CONFIG_SYSCTL 385#ifdef CONFIG_SYSCTL
342 sysctl_hdr = register_net_sysctl(&init_net, "net/ipv6", 386 register_pernet_subsys(&xfrm6_net_ops);
343 xfrm6_policy_table);
344#endif 387#endif
345out: 388out:
346 return ret; 389 return ret;
@@ -352,8 +395,7 @@ out_policy:
352void xfrm6_fini(void) 395void xfrm6_fini(void)
353{ 396{
354#ifdef CONFIG_SYSCTL 397#ifdef CONFIG_SYSCTL
355 if (sysctl_hdr) 398 unregister_pernet_subsys(&xfrm6_net_ops);
356 unregister_net_sysctl_table(sysctl_hdr);
357#endif 399#endif
358 xfrm6_policy_fini(); 400 xfrm6_policy_fini();
359 xfrm6_state_fini(); 401 xfrm6_state_fini();
diff --git a/net/key/af_key.c b/net/key/af_key.c
index cc2630ac8061..7b3ba32ca678 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -203,7 +203,6 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
203 } 203 }
204 if (*skb2 != NULL) { 204 if (*skb2 != NULL) {
205 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) { 205 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
206 skb_orphan(*skb2);
207 skb_set_owner_r(*skb2, sk); 206 skb_set_owner_r(*skb2, sk);
208 skb_queue_tail(&sk->sk_receive_queue, *skb2); 207 skb_queue_tail(&sk->sk_receive_queue, *skb2);
209 sk->sk_data_ready(sk, (*skb2)->len); 208 sk->sk_data_ready(sk, (*skb2)->len);
@@ -816,18 +815,21 @@ static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x,
816 sa->sadb_sa_auth = 0; 815 sa->sadb_sa_auth = 0;
817 if (x->aalg) { 816 if (x->aalg) {
818 struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 817 struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
819 sa->sadb_sa_auth = a ? a->desc.sadb_alg_id : 0; 818 sa->sadb_sa_auth = (a && a->pfkey_supported) ?
819 a->desc.sadb_alg_id : 0;
820 } 820 }
821 sa->sadb_sa_encrypt = 0; 821 sa->sadb_sa_encrypt = 0;
822 BUG_ON(x->ealg && x->calg); 822 BUG_ON(x->ealg && x->calg);
823 if (x->ealg) { 823 if (x->ealg) {
824 struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name, 0); 824 struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name, 0);
825 sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0; 825 sa->sadb_sa_encrypt = (a && a->pfkey_supported) ?
826 a->desc.sadb_alg_id : 0;
826 } 827 }
827 /* KAME compatible: sadb_sa_encrypt is overloaded with calg id */ 828 /* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
828 if (x->calg) { 829 if (x->calg) {
829 struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name, 0); 830 struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name, 0);
830 sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0; 831 sa->sadb_sa_encrypt = (a && a->pfkey_supported) ?
832 a->desc.sadb_alg_id : 0;
831 } 833 }
832 834
833 sa->sadb_sa_flags = 0; 835 sa->sadb_sa_flags = 0;
@@ -1138,7 +1140,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
1138 if (sa->sadb_sa_auth) { 1140 if (sa->sadb_sa_auth) {
1139 int keysize = 0; 1141 int keysize = 0;
1140 struct xfrm_algo_desc *a = xfrm_aalg_get_byid(sa->sadb_sa_auth); 1142 struct xfrm_algo_desc *a = xfrm_aalg_get_byid(sa->sadb_sa_auth);
1141 if (!a) { 1143 if (!a || !a->pfkey_supported) {
1142 err = -ENOSYS; 1144 err = -ENOSYS;
1143 goto out; 1145 goto out;
1144 } 1146 }
@@ -1160,7 +1162,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
1160 if (sa->sadb_sa_encrypt) { 1162 if (sa->sadb_sa_encrypt) {
1161 if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { 1163 if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
1162 struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt); 1164 struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt);
1163 if (!a) { 1165 if (!a || !a->pfkey_supported) {
1164 err = -ENOSYS; 1166 err = -ENOSYS;
1165 goto out; 1167 goto out;
1166 } 1168 }
@@ -1172,7 +1174,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
1172 } else { 1174 } else {
1173 int keysize = 0; 1175 int keysize = 0;
1174 struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt); 1176 struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt);
1175 if (!a) { 1177 if (!a || !a->pfkey_supported) {
1176 err = -ENOSYS; 1178 err = -ENOSYS;
1177 goto out; 1179 goto out;
1178 } 1180 }
@@ -1578,13 +1580,13 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
1578 struct sadb_msg *hdr; 1580 struct sadb_msg *hdr;
1579 int len, auth_len, enc_len, i; 1581 int len, auth_len, enc_len, i;
1580 1582
1581 auth_len = xfrm_count_auth_supported(); 1583 auth_len = xfrm_count_pfkey_auth_supported();
1582 if (auth_len) { 1584 if (auth_len) {
1583 auth_len *= sizeof(struct sadb_alg); 1585 auth_len *= sizeof(struct sadb_alg);
1584 auth_len += sizeof(struct sadb_supported); 1586 auth_len += sizeof(struct sadb_supported);
1585 } 1587 }
1586 1588
1587 enc_len = xfrm_count_enc_supported(); 1589 enc_len = xfrm_count_pfkey_enc_supported();
1588 if (enc_len) { 1590 if (enc_len) {
1589 enc_len *= sizeof(struct sadb_alg); 1591 enc_len *= sizeof(struct sadb_alg);
1590 enc_len += sizeof(struct sadb_supported); 1592 enc_len += sizeof(struct sadb_supported);
@@ -1615,6 +1617,8 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
1615 struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i); 1617 struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);
1616 if (!aalg) 1618 if (!aalg)
1617 break; 1619 break;
1620 if (!aalg->pfkey_supported)
1621 continue;
1618 if (aalg->available) 1622 if (aalg->available)
1619 *ap++ = aalg->desc; 1623 *ap++ = aalg->desc;
1620 } 1624 }
@@ -1634,6 +1638,8 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
1634 struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i); 1638 struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i);
1635 if (!ealg) 1639 if (!ealg)
1636 break; 1640 break;
1641 if (!ealg->pfkey_supported)
1642 continue;
1637 if (ealg->available) 1643 if (ealg->available)
1638 *ap++ = ealg->desc; 1644 *ap++ = ealg->desc;
1639 } 1645 }
@@ -2825,6 +2831,8 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
2825 const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i); 2831 const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);
2826 if (!aalg) 2832 if (!aalg)
2827 break; 2833 break;
2834 if (!aalg->pfkey_supported)
2835 continue;
2828 if (aalg_tmpl_set(t, aalg) && aalg->available) 2836 if (aalg_tmpl_set(t, aalg) && aalg->available)
2829 sz += sizeof(struct sadb_comb); 2837 sz += sizeof(struct sadb_comb);
2830 } 2838 }
@@ -2840,6 +2848,9 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
2840 if (!ealg) 2848 if (!ealg)
2841 break; 2849 break;
2842 2850
2851 if (!ealg->pfkey_supported)
2852 continue;
2853
2843 if (!(ealg_tmpl_set(t, ealg) && ealg->available)) 2854 if (!(ealg_tmpl_set(t, ealg) && ealg->available))
2844 continue; 2855 continue;
2845 2856
@@ -2848,6 +2859,9 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
2848 if (!aalg) 2859 if (!aalg)
2849 break; 2860 break;
2850 2861
2862 if (!aalg->pfkey_supported)
2863 continue;
2864
2851 if (aalg_tmpl_set(t, aalg) && aalg->available) 2865 if (aalg_tmpl_set(t, aalg) && aalg->available)
2852 sz += sizeof(struct sadb_comb); 2866 sz += sizeof(struct sadb_comb);
2853 } 2867 }
@@ -2871,6 +2885,9 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
2871 if (!aalg) 2885 if (!aalg)
2872 break; 2886 break;
2873 2887
2888 if (!aalg->pfkey_supported)
2889 continue;
2890
2874 if (aalg_tmpl_set(t, aalg) && aalg->available) { 2891 if (aalg_tmpl_set(t, aalg) && aalg->available) {
2875 struct sadb_comb *c; 2892 struct sadb_comb *c;
2876 c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb)); 2893 c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));
@@ -2903,6 +2920,9 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
2903 if (!ealg) 2920 if (!ealg)
2904 break; 2921 break;
2905 2922
2923 if (!ealg->pfkey_supported)
2924 continue;
2925
2906 if (!(ealg_tmpl_set(t, ealg) && ealg->available)) 2926 if (!(ealg_tmpl_set(t, ealg) && ealg->available))
2907 continue; 2927 continue;
2908 2928
@@ -2911,6 +2931,8 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
2911 const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k); 2931 const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k);
2912 if (!aalg) 2932 if (!aalg)
2913 break; 2933 break;
2934 if (!aalg->pfkey_supported)
2935 continue;
2914 if (!(aalg_tmpl_set(t, aalg) && aalg->available)) 2936 if (!(aalg_tmpl_set(t, aalg) && aalg->available))
2915 continue; 2937 continue;
2916 c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb)); 2938 c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index f9a549554740..6fb9d00a75dc 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -35,6 +35,8 @@ static struct xfrm_algo_desc aead_list[] = {
35 } 35 }
36 }, 36 },
37 37
38 .pfkey_supported = 1,
39
38 .desc = { 40 .desc = {
39 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8, 41 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
40 .sadb_alg_ivlen = 8, 42 .sadb_alg_ivlen = 8,
@@ -51,6 +53,8 @@ static struct xfrm_algo_desc aead_list[] = {
51 } 53 }
52 }, 54 },
53 55
56 .pfkey_supported = 1,
57
54 .desc = { 58 .desc = {
55 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12, 59 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
56 .sadb_alg_ivlen = 8, 60 .sadb_alg_ivlen = 8,
@@ -67,6 +71,8 @@ static struct xfrm_algo_desc aead_list[] = {
67 } 71 }
68 }, 72 },
69 73
74 .pfkey_supported = 1,
75
70 .desc = { 76 .desc = {
71 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16, 77 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
72 .sadb_alg_ivlen = 8, 78 .sadb_alg_ivlen = 8,
@@ -83,6 +89,8 @@ static struct xfrm_algo_desc aead_list[] = {
83 } 89 }
84 }, 90 },
85 91
92 .pfkey_supported = 1,
93
86 .desc = { 94 .desc = {
87 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8, 95 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
88 .sadb_alg_ivlen = 8, 96 .sadb_alg_ivlen = 8,
@@ -99,6 +107,8 @@ static struct xfrm_algo_desc aead_list[] = {
99 } 107 }
100 }, 108 },
101 109
110 .pfkey_supported = 1,
111
102 .desc = { 112 .desc = {
103 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12, 113 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
104 .sadb_alg_ivlen = 8, 114 .sadb_alg_ivlen = 8,
@@ -115,6 +125,8 @@ static struct xfrm_algo_desc aead_list[] = {
115 } 125 }
116 }, 126 },
117 127
128 .pfkey_supported = 1,
129
118 .desc = { 130 .desc = {
119 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16, 131 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
120 .sadb_alg_ivlen = 8, 132 .sadb_alg_ivlen = 8,
@@ -131,6 +143,8 @@ static struct xfrm_algo_desc aead_list[] = {
131 } 143 }
132 }, 144 },
133 145
146 .pfkey_supported = 1,
147
134 .desc = { 148 .desc = {
135 .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC, 149 .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
136 .sadb_alg_ivlen = 8, 150 .sadb_alg_ivlen = 8,
@@ -151,6 +165,8 @@ static struct xfrm_algo_desc aalg_list[] = {
151 } 165 }
152 }, 166 },
153 167
168 .pfkey_supported = 1,
169
154 .desc = { 170 .desc = {
155 .sadb_alg_id = SADB_X_AALG_NULL, 171 .sadb_alg_id = SADB_X_AALG_NULL,
156 .sadb_alg_ivlen = 0, 172 .sadb_alg_ivlen = 0,
@@ -169,6 +185,8 @@ static struct xfrm_algo_desc aalg_list[] = {
169 } 185 }
170 }, 186 },
171 187
188 .pfkey_supported = 1,
189
172 .desc = { 190 .desc = {
173 .sadb_alg_id = SADB_AALG_MD5HMAC, 191 .sadb_alg_id = SADB_AALG_MD5HMAC,
174 .sadb_alg_ivlen = 0, 192 .sadb_alg_ivlen = 0,
@@ -187,6 +205,8 @@ static struct xfrm_algo_desc aalg_list[] = {
187 } 205 }
188 }, 206 },
189 207
208 .pfkey_supported = 1,
209
190 .desc = { 210 .desc = {
191 .sadb_alg_id = SADB_AALG_SHA1HMAC, 211 .sadb_alg_id = SADB_AALG_SHA1HMAC,
192 .sadb_alg_ivlen = 0, 212 .sadb_alg_ivlen = 0,
@@ -205,6 +225,8 @@ static struct xfrm_algo_desc aalg_list[] = {
205 } 225 }
206 }, 226 },
207 227
228 .pfkey_supported = 1,
229
208 .desc = { 230 .desc = {
209 .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC, 231 .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
210 .sadb_alg_ivlen = 0, 232 .sadb_alg_ivlen = 0,
@@ -222,6 +244,8 @@ static struct xfrm_algo_desc aalg_list[] = {
222 } 244 }
223 }, 245 },
224 246
247 .pfkey_supported = 1,
248
225 .desc = { 249 .desc = {
226 .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC, 250 .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
227 .sadb_alg_ivlen = 0, 251 .sadb_alg_ivlen = 0,
@@ -239,6 +263,8 @@ static struct xfrm_algo_desc aalg_list[] = {
239 } 263 }
240 }, 264 },
241 265
266 .pfkey_supported = 1,
267
242 .desc = { 268 .desc = {
243 .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC, 269 .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
244 .sadb_alg_ivlen = 0, 270 .sadb_alg_ivlen = 0,
@@ -257,6 +283,8 @@ static struct xfrm_algo_desc aalg_list[] = {
257 } 283 }
258 }, 284 },
259 285
286 .pfkey_supported = 1,
287
260 .desc = { 288 .desc = {
261 .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC, 289 .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
262 .sadb_alg_ivlen = 0, 290 .sadb_alg_ivlen = 0,
@@ -274,6 +302,8 @@ static struct xfrm_algo_desc aalg_list[] = {
274 } 302 }
275 }, 303 },
276 304
305 .pfkey_supported = 1,
306
277 .desc = { 307 .desc = {
278 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC, 308 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
279 .sadb_alg_ivlen = 0, 309 .sadb_alg_ivlen = 0,
@@ -295,6 +325,8 @@ static struct xfrm_algo_desc ealg_list[] = {
295 } 325 }
296 }, 326 },
297 327
328 .pfkey_supported = 1,
329
298 .desc = { 330 .desc = {
299 .sadb_alg_id = SADB_EALG_NULL, 331 .sadb_alg_id = SADB_EALG_NULL,
300 .sadb_alg_ivlen = 0, 332 .sadb_alg_ivlen = 0,
@@ -313,6 +345,8 @@ static struct xfrm_algo_desc ealg_list[] = {
313 } 345 }
314 }, 346 },
315 347
348 .pfkey_supported = 1,
349
316 .desc = { 350 .desc = {
317 .sadb_alg_id = SADB_EALG_DESCBC, 351 .sadb_alg_id = SADB_EALG_DESCBC,
318 .sadb_alg_ivlen = 8, 352 .sadb_alg_ivlen = 8,
@@ -331,6 +365,8 @@ static struct xfrm_algo_desc ealg_list[] = {
331 } 365 }
332 }, 366 },
333 367
368 .pfkey_supported = 1,
369
334 .desc = { 370 .desc = {
335 .sadb_alg_id = SADB_EALG_3DESCBC, 371 .sadb_alg_id = SADB_EALG_3DESCBC,
336 .sadb_alg_ivlen = 8, 372 .sadb_alg_ivlen = 8,
@@ -349,6 +385,8 @@ static struct xfrm_algo_desc ealg_list[] = {
349 } 385 }
350 }, 386 },
351 387
388 .pfkey_supported = 1,
389
352 .desc = { 390 .desc = {
353 .sadb_alg_id = SADB_X_EALG_CASTCBC, 391 .sadb_alg_id = SADB_X_EALG_CASTCBC,
354 .sadb_alg_ivlen = 8, 392 .sadb_alg_ivlen = 8,
@@ -367,6 +405,8 @@ static struct xfrm_algo_desc ealg_list[] = {
367 } 405 }
368 }, 406 },
369 407
408 .pfkey_supported = 1,
409
370 .desc = { 410 .desc = {
371 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC, 411 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
372 .sadb_alg_ivlen = 8, 412 .sadb_alg_ivlen = 8,
@@ -385,6 +425,8 @@ static struct xfrm_algo_desc ealg_list[] = {
385 } 425 }
386 }, 426 },
387 427
428 .pfkey_supported = 1,
429
388 .desc = { 430 .desc = {
389 .sadb_alg_id = SADB_X_EALG_AESCBC, 431 .sadb_alg_id = SADB_X_EALG_AESCBC,
390 .sadb_alg_ivlen = 8, 432 .sadb_alg_ivlen = 8,
@@ -403,6 +445,8 @@ static struct xfrm_algo_desc ealg_list[] = {
403 } 445 }
404 }, 446 },
405 447
448 .pfkey_supported = 1,
449
406 .desc = { 450 .desc = {
407 .sadb_alg_id = SADB_X_EALG_SERPENTCBC, 451 .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
408 .sadb_alg_ivlen = 8, 452 .sadb_alg_ivlen = 8,
@@ -421,6 +465,8 @@ static struct xfrm_algo_desc ealg_list[] = {
421 } 465 }
422 }, 466 },
423 467
468 .pfkey_supported = 1,
469
424 .desc = { 470 .desc = {
425 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC, 471 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
426 .sadb_alg_ivlen = 8, 472 .sadb_alg_ivlen = 8,
@@ -439,6 +485,8 @@ static struct xfrm_algo_desc ealg_list[] = {
439 } 485 }
440 }, 486 },
441 487
488 .pfkey_supported = 1,
489
442 .desc = { 490 .desc = {
443 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC, 491 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
444 .sadb_alg_ivlen = 8, 492 .sadb_alg_ivlen = 8,
@@ -456,6 +504,8 @@ static struct xfrm_algo_desc ealg_list[] = {
456 } 504 }
457 }, 505 },
458 506
507 .pfkey_supported = 1,
508
459 .desc = { 509 .desc = {
460 .sadb_alg_id = SADB_X_EALG_AESCTR, 510 .sadb_alg_id = SADB_X_EALG_AESCTR,
461 .sadb_alg_ivlen = 8, 511 .sadb_alg_ivlen = 8,
@@ -473,6 +523,7 @@ static struct xfrm_algo_desc calg_list[] = {
473 .threshold = 90, 523 .threshold = 90,
474 } 524 }
475 }, 525 },
526 .pfkey_supported = 1,
476 .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE } 527 .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
477}, 528},
478{ 529{
@@ -482,6 +533,7 @@ static struct xfrm_algo_desc calg_list[] = {
482 .threshold = 90, 533 .threshold = 90,
483 } 534 }
484 }, 535 },
536 .pfkey_supported = 1,
485 .desc = { .sadb_alg_id = SADB_X_CALG_LZS } 537 .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
486}, 538},
487{ 539{
@@ -491,6 +543,7 @@ static struct xfrm_algo_desc calg_list[] = {
491 .threshold = 50, 543 .threshold = 50,
492 } 544 }
493 }, 545 },
546 .pfkey_supported = 1,
494 .desc = { .sadb_alg_id = SADB_X_CALG_LZJH } 547 .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
495}, 548},
496}; 549};
@@ -714,27 +767,27 @@ void xfrm_probe_algs(void)
714} 767}
715EXPORT_SYMBOL_GPL(xfrm_probe_algs); 768EXPORT_SYMBOL_GPL(xfrm_probe_algs);
716 769
717int xfrm_count_auth_supported(void) 770int xfrm_count_pfkey_auth_supported(void)
718{ 771{
719 int i, n; 772 int i, n;
720 773
721 for (i = 0, n = 0; i < aalg_entries(); i++) 774 for (i = 0, n = 0; i < aalg_entries(); i++)
722 if (aalg_list[i].available) 775 if (aalg_list[i].available && aalg_list[i].pfkey_supported)
723 n++; 776 n++;
724 return n; 777 return n;
725} 778}
726EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); 779EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
727 780
728int xfrm_count_enc_supported(void) 781int xfrm_count_pfkey_enc_supported(void)
729{ 782{
730 int i, n; 783 int i, n;
731 784
732 for (i = 0, n = 0; i < ealg_entries(); i++) 785 for (i = 0, n = 0; i < ealg_entries(); i++)
733 if (ealg_list[i].available) 786 if (ealg_list[i].available && ealg_list[i].pfkey_supported)
734 n++; 787 n++;
735 return n; 788 return n;
736} 789}
737EXPORT_SYMBOL_GPL(xfrm_count_enc_supported); 790EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
738 791
739#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) 792#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
740 793
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 3670526e70b9..bcfda8921b5b 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -64,7 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
64 64
65 if (unlikely(x->km.state != XFRM_STATE_VALID)) { 65 if (unlikely(x->km.state != XFRM_STATE_VALID)) {
66 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID); 66 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
67 goto error_nolock; 67 goto error;
68 } 68 }
69 69
70 err = xfrm_state_check_expire(x); 70 err = xfrm_state_check_expire(x);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6c9aa642a2ba..5b47180986f8 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -35,6 +35,10 @@
35 35
36#include "xfrm_hash.h" 36#include "xfrm_hash.h"
37 37
38#define XFRM_QUEUE_TMO_MIN ((unsigned)(HZ/10))
39#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
40#define XFRM_MAX_QUEUE_LEN 100
41
38DEFINE_MUTEX(xfrm_cfg_mutex); 42DEFINE_MUTEX(xfrm_cfg_mutex);
39EXPORT_SYMBOL(xfrm_cfg_mutex); 43EXPORT_SYMBOL(xfrm_cfg_mutex);
40 44
@@ -51,7 +55,7 @@ static struct kmem_cache *xfrm_dst_cache __read_mostly;
51static void xfrm_init_pmtu(struct dst_entry *dst); 55static void xfrm_init_pmtu(struct dst_entry *dst);
52static int stale_bundle(struct dst_entry *dst); 56static int stale_bundle(struct dst_entry *dst);
53static int xfrm_bundle_ok(struct xfrm_dst *xdst); 57static int xfrm_bundle_ok(struct xfrm_dst *xdst);
54 58static void xfrm_policy_queue_process(unsigned long arg);
55 59
56static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, 60static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
57 int dir); 61 int dir);
@@ -287,8 +291,11 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
287 INIT_HLIST_NODE(&policy->byidx); 291 INIT_HLIST_NODE(&policy->byidx);
288 rwlock_init(&policy->lock); 292 rwlock_init(&policy->lock);
289 atomic_set(&policy->refcnt, 1); 293 atomic_set(&policy->refcnt, 1);
294 skb_queue_head_init(&policy->polq.hold_queue);
290 setup_timer(&policy->timer, xfrm_policy_timer, 295 setup_timer(&policy->timer, xfrm_policy_timer,
291 (unsigned long)policy); 296 (unsigned long)policy);
297 setup_timer(&policy->polq.hold_timer, xfrm_policy_queue_process,
298 (unsigned long)policy);
292 policy->flo.ops = &xfrm_policy_fc_ops; 299 policy->flo.ops = &xfrm_policy_fc_ops;
293 } 300 }
294 return policy; 301 return policy;
@@ -309,6 +316,16 @@ void xfrm_policy_destroy(struct xfrm_policy *policy)
309} 316}
310EXPORT_SYMBOL(xfrm_policy_destroy); 317EXPORT_SYMBOL(xfrm_policy_destroy);
311 318
319static void xfrm_queue_purge(struct sk_buff_head *list)
320{
321 struct sk_buff *skb;
322
323 while ((skb = skb_dequeue(list)) != NULL) {
324 dev_put(skb->dev);
325 kfree_skb(skb);
326 }
327}
328
312/* Rule must be locked. Release descentant resources, announce 329/* Rule must be locked. Release descentant resources, announce
313 * entry dead. The rule must be unlinked from lists to the moment. 330 * entry dead. The rule must be unlinked from lists to the moment.
314 */ 331 */
@@ -319,6 +336,9 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
319 336
320 atomic_inc(&policy->genid); 337 atomic_inc(&policy->genid);
321 338
339 del_timer(&policy->polq.hold_timer);
340 xfrm_queue_purge(&policy->polq.hold_queue);
341
322 if (del_timer(&policy->timer)) 342 if (del_timer(&policy->timer))
323 xfrm_pol_put(policy); 343 xfrm_pol_put(policy);
324 344
@@ -562,6 +582,46 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
562 return 0; 582 return 0;
563} 583}
564 584
585static void xfrm_policy_requeue(struct xfrm_policy *old,
586 struct xfrm_policy *new)
587{
588 struct xfrm_policy_queue *pq = &old->polq;
589 struct sk_buff_head list;
590
591 __skb_queue_head_init(&list);
592
593 spin_lock_bh(&pq->hold_queue.lock);
594 skb_queue_splice_init(&pq->hold_queue, &list);
595 del_timer(&pq->hold_timer);
596 spin_unlock_bh(&pq->hold_queue.lock);
597
598 if (skb_queue_empty(&list))
599 return;
600
601 pq = &new->polq;
602
603 spin_lock_bh(&pq->hold_queue.lock);
604 skb_queue_splice(&list, &pq->hold_queue);
605 pq->timeout = XFRM_QUEUE_TMO_MIN;
606 mod_timer(&pq->hold_timer, jiffies);
607 spin_unlock_bh(&pq->hold_queue.lock);
608}
609
610static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
611 struct xfrm_policy *pol)
612{
613 u32 mark = policy->mark.v & policy->mark.m;
614
615 if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
616 return true;
617
618 if ((mark & pol->mark.m) == pol->mark.v &&
619 policy->priority == pol->priority)
620 return true;
621
622 return false;
623}
624
565int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) 625int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
566{ 626{
567 struct net *net = xp_net(policy); 627 struct net *net = xp_net(policy);
@@ -569,7 +629,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
569 struct xfrm_policy *delpol; 629 struct xfrm_policy *delpol;
570 struct hlist_head *chain; 630 struct hlist_head *chain;
571 struct hlist_node *entry, *newpos; 631 struct hlist_node *entry, *newpos;
572 u32 mark = policy->mark.v & policy->mark.m;
573 632
574 write_lock_bh(&xfrm_policy_lock); 633 write_lock_bh(&xfrm_policy_lock);
575 chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); 634 chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
@@ -578,7 +637,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
578 hlist_for_each_entry(pol, entry, chain, bydst) { 637 hlist_for_each_entry(pol, entry, chain, bydst) {
579 if (pol->type == policy->type && 638 if (pol->type == policy->type &&
580 !selector_cmp(&pol->selector, &policy->selector) && 639 !selector_cmp(&pol->selector, &policy->selector) &&
581 (mark & pol->mark.m) == pol->mark.v && 640 xfrm_policy_mark_match(policy, pol) &&
582 xfrm_sec_ctx_match(pol->security, policy->security) && 641 xfrm_sec_ctx_match(pol->security, policy->security) &&
583 !WARN_ON(delpol)) { 642 !WARN_ON(delpol)) {
584 if (excl) { 643 if (excl) {
@@ -603,8 +662,10 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
603 net->xfrm.policy_count[dir]++; 662 net->xfrm.policy_count[dir]++;
604 atomic_inc(&flow_cache_genid); 663 atomic_inc(&flow_cache_genid);
605 rt_genid_bump(net); 664 rt_genid_bump(net);
606 if (delpol) 665 if (delpol) {
666 xfrm_policy_requeue(delpol, policy);
607 __xfrm_policy_unlink(delpol, dir); 667 __xfrm_policy_unlink(delpol, dir);
668 }
608 policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); 669 policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
609 hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); 670 hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
610 policy->curlft.add_time = get_seconds(); 671 policy->curlft.add_time = get_seconds();
@@ -1115,11 +1176,15 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1115 pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir); 1176 pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
1116 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 1177 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
1117 } 1178 }
1118 if (old_pol) 1179 if (old_pol) {
1180 if (pol)
1181 xfrm_policy_requeue(old_pol, pol);
1182
1119 /* Unlinking succeeds always. This is the only function 1183 /* Unlinking succeeds always. This is the only function
1120 * allowed to delete or replace socket policy. 1184 * allowed to delete or replace socket policy.
1121 */ 1185 */
1122 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); 1186 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
1187 }
1123 write_unlock_bh(&xfrm_policy_lock); 1188 write_unlock_bh(&xfrm_policy_lock);
1124 1189
1125 if (old_pol) { 1190 if (old_pol) {
@@ -1310,6 +1375,8 @@ static struct flow_cache_object *xfrm_bundle_flo_get(struct flow_cache_object *f
1310 * It means we need to try again resolving. */ 1375 * It means we need to try again resolving. */
1311 if (xdst->num_xfrms > 0) 1376 if (xdst->num_xfrms > 0)
1312 return NULL; 1377 return NULL;
1378 } else if (dst->flags & DST_XFRM_QUEUE) {
1379 return NULL;
1313 } else { 1380 } else {
1314 /* Real bundle */ 1381 /* Real bundle */
1315 if (stale_bundle(dst)) 1382 if (stale_bundle(dst))
@@ -1673,6 +1740,171 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
1673 return xdst; 1740 return xdst;
1674} 1741}
1675 1742
1743static void xfrm_policy_queue_process(unsigned long arg)
1744{
1745 int err = 0;
1746 struct sk_buff *skb;
1747 struct sock *sk;
1748 struct dst_entry *dst;
1749 struct net_device *dev;
1750 struct xfrm_policy *pol = (struct xfrm_policy *)arg;
1751 struct xfrm_policy_queue *pq = &pol->polq;
1752 struct flowi fl;
1753 struct sk_buff_head list;
1754
1755 spin_lock(&pq->hold_queue.lock);
1756 skb = skb_peek(&pq->hold_queue);
1757 dst = skb_dst(skb);
1758 sk = skb->sk;
1759 xfrm_decode_session(skb, &fl, dst->ops->family);
1760 spin_unlock(&pq->hold_queue.lock);
1761
1762 dst_hold(dst->path);
1763 dst = xfrm_lookup(xp_net(pol), dst->path, &fl,
1764 sk, 0);
1765 if (IS_ERR(dst))
1766 goto purge_queue;
1767
1768 if (dst->flags & DST_XFRM_QUEUE) {
1769 dst_release(dst);
1770
1771 if (pq->timeout >= XFRM_QUEUE_TMO_MAX)
1772 goto purge_queue;
1773
1774 pq->timeout = pq->timeout << 1;
1775 mod_timer(&pq->hold_timer, jiffies + pq->timeout);
1776 return;
1777 }
1778
1779 dst_release(dst);
1780
1781 __skb_queue_head_init(&list);
1782
1783 spin_lock(&pq->hold_queue.lock);
1784 pq->timeout = 0;
1785 skb_queue_splice_init(&pq->hold_queue, &list);
1786 spin_unlock(&pq->hold_queue.lock);
1787
1788 while (!skb_queue_empty(&list)) {
1789 skb = __skb_dequeue(&list);
1790
1791 xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
1792 dst_hold(skb_dst(skb)->path);
1793 dst = xfrm_lookup(xp_net(pol), skb_dst(skb)->path,
1794 &fl, skb->sk, 0);
1795 if (IS_ERR(dst)) {
1796 dev_put(skb->dev);
1797 kfree_skb(skb);
1798 continue;
1799 }
1800
1801 nf_reset(skb);
1802 skb_dst_drop(skb);
1803 skb_dst_set(skb, dst);
1804
1805 dev = skb->dev;
1806 err = dst_output(skb);
1807 dev_put(dev);
1808 }
1809
1810 return;
1811
1812purge_queue:
1813 pq->timeout = 0;
1814 xfrm_queue_purge(&pq->hold_queue);
1815}
1816
1817static int xdst_queue_output(struct sk_buff *skb)
1818{
1819 unsigned long sched_next;
1820 struct dst_entry *dst = skb_dst(skb);
1821 struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
1822 struct xfrm_policy_queue *pq = &xdst->pols[0]->polq;
1823
1824 if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) {
1825 kfree_skb(skb);
1826 return -EAGAIN;
1827 }
1828
1829 skb_dst_force(skb);
1830 dev_hold(skb->dev);
1831
1832 spin_lock_bh(&pq->hold_queue.lock);
1833
1834 if (!pq->timeout)
1835 pq->timeout = XFRM_QUEUE_TMO_MIN;
1836
1837 sched_next = jiffies + pq->timeout;
1838
1839 if (del_timer(&pq->hold_timer)) {
1840 if (time_before(pq->hold_timer.expires, sched_next))
1841 sched_next = pq->hold_timer.expires;
1842 }
1843
1844 __skb_queue_tail(&pq->hold_queue, skb);
1845 mod_timer(&pq->hold_timer, sched_next);
1846
1847 spin_unlock_bh(&pq->hold_queue.lock);
1848
1849 return 0;
1850}
1851
1852static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
1853 struct dst_entry *dst,
1854 const struct flowi *fl,
1855 int num_xfrms,
1856 u16 family)
1857{
1858 int err;
1859 struct net_device *dev;
1860 struct dst_entry *dst1;
1861 struct xfrm_dst *xdst;
1862
1863 xdst = xfrm_alloc_dst(net, family);
1864 if (IS_ERR(xdst))
1865 return xdst;
1866
1867 if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0 ||
1868 (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP))
1869 return xdst;
1870
1871 dst1 = &xdst->u.dst;
1872 dst_hold(dst);
1873 xdst->route = dst;
1874
1875 dst_copy_metrics(dst1, dst);
1876
1877 dst1->obsolete = DST_OBSOLETE_FORCE_CHK;
1878 dst1->flags |= DST_HOST | DST_XFRM_QUEUE;
1879 dst1->lastuse = jiffies;
1880
1881 dst1->input = dst_discard;
1882 dst1->output = xdst_queue_output;
1883
1884 dst_hold(dst);
1885 dst1->child = dst;
1886 dst1->path = dst;
1887
1888 xfrm_init_path((struct xfrm_dst *)dst1, dst, 0);
1889
1890 err = -ENODEV;
1891 dev = dst->dev;
1892 if (!dev)
1893 goto free_dst;
1894
1895 err = xfrm_fill_dst(xdst, dev, fl);
1896 if (err)
1897 goto free_dst;
1898
1899out:
1900 return xdst;
1901
1902free_dst:
1903 dst_release(dst1);
1904 xdst = ERR_PTR(err);
1905 goto out;
1906}
1907
1676static struct flow_cache_object * 1908static struct flow_cache_object *
1677xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, 1909xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
1678 struct flow_cache_object *oldflo, void *ctx) 1910 struct flow_cache_object *oldflo, void *ctx)
@@ -1751,7 +1983,7 @@ make_dummy_bundle:
1751 /* We found policies, but there's no bundles to instantiate: 1983 /* We found policies, but there's no bundles to instantiate:
1752 * either because the policy blocks, has no transformations or 1984 * either because the policy blocks, has no transformations or
1753 * we could not build template (no xfrm_states).*/ 1985 * we could not build template (no xfrm_states).*/
1754 xdst = xfrm_alloc_dst(net, family); 1986 xdst = xfrm_create_dummy_bundle(net, dst_orig, fl, num_xfrms, family);
1755 if (IS_ERR(xdst)) { 1987 if (IS_ERR(xdst)) {
1756 xfrm_pols_put(pols, num_pols); 1988 xfrm_pols_put(pols, num_pols);
1757 return ERR_CAST(xdst); 1989 return ERR_CAST(xdst);
@@ -2359,6 +2591,9 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
2359 (dst->dev && !netif_running(dst->dev))) 2591 (dst->dev && !netif_running(dst->dev)))
2360 return 0; 2592 return 0;
2361 2593
2594 if (dst->flags & DST_XFRM_QUEUE)
2595 return 1;
2596
2362 last = NULL; 2597 last = NULL;
2363 2598
2364 do { 2599 do {