aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {