aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h50
-rw-r--r--include/uapi/linux/xfrm.h4
-rw-r--r--net/ipv4/xfrm4_policy.c1
-rw-r--r--net/ipv4/xfrm4_protocol.c13
-rw-r--r--net/ipv6/Makefile2
-rw-r--r--net/ipv6/ah6.c24
-rw-r--r--net/ipv6/esp6.c26
-rw-r--r--net/ipv6/ip6_vti.c308
-rw-r--r--net/ipv6/ipcomp6.c22
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c63
-rw-r--r--net/ipv6/xfrm6_policy.c7
-rw-r--r--net/ipv6/xfrm6_protocol.c270
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/xfrm/xfrm_input.c75
-rw-r--r--net/xfrm/xfrm_state.c4
-rw-r--r--net/xfrm/xfrm_user.c8
16 files changed, 668 insertions, 211 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 23bfd4591e8b..32682ae47b3f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -121,7 +121,7 @@ struct xfrm_state_walk {
121 u8 dying; 121 u8 dying;
122 u8 proto; 122 u8 proto;
123 u32 seq; 123 u32 seq;
124 struct xfrm_filter *filter; 124 struct xfrm_address_filter *filter;
125}; 125};
126 126
127/* Full description of state of transformer. */ 127/* Full description of state of transformer. */
@@ -349,6 +349,16 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
349struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); 349struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
350void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); 350void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
351 351
352struct xfrm_input_afinfo {
353 unsigned int family;
354 struct module *owner;
355 int (*callback)(struct sk_buff *skb, u8 protocol,
356 int err);
357};
358
359int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo);
360int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo);
361
352void xfrm_state_delete_tunnel(struct xfrm_state *x); 362void xfrm_state_delete_tunnel(struct xfrm_state *x);
353 363
354struct xfrm_type { 364struct xfrm_type {
@@ -1364,18 +1374,22 @@ struct xfrm4_protocol {
1364 int priority; 1374 int priority;
1365}; 1375};
1366 1376
1367/* XFRM tunnel handlers. */ 1377struct xfrm6_protocol {
1368struct xfrm_tunnel {
1369 int (*handler)(struct sk_buff *skb); 1378 int (*handler)(struct sk_buff *skb);
1370 int (*err_handler)(struct sk_buff *skb, u32 info); 1379 int (*cb_handler)(struct sk_buff *skb, int err);
1380 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1381 u8 type, u8 code, int offset, __be32 info);
1371 1382
1372 struct xfrm_tunnel __rcu *next; 1383 struct xfrm6_protocol __rcu *next;
1373 int priority; 1384 int priority;
1374}; 1385};
1375 1386
1376struct xfrm_tunnel_notifier { 1387/* XFRM tunnel handlers. */
1388struct xfrm_tunnel {
1377 int (*handler)(struct sk_buff *skb); 1389 int (*handler)(struct sk_buff *skb);
1378 struct xfrm_tunnel_notifier __rcu *next; 1390 int (*err_handler)(struct sk_buff *skb, u32 info);
1391
1392 struct xfrm_tunnel __rcu *next;
1379 int priority; 1393 int priority;
1380}; 1394};
1381 1395
@@ -1392,11 +1406,14 @@ void xfrm4_init(void);
1392int xfrm_state_init(struct net *net); 1406int xfrm_state_init(struct net *net);
1393void xfrm_state_fini(struct net *net); 1407void xfrm_state_fini(struct net *net);
1394void xfrm4_state_init(void); 1408void xfrm4_state_init(void);
1409void xfrm4_protocol_init(void);
1395#ifdef CONFIG_XFRM 1410#ifdef CONFIG_XFRM
1396int xfrm6_init(void); 1411int xfrm6_init(void);
1397void xfrm6_fini(void); 1412void xfrm6_fini(void);
1398int xfrm6_state_init(void); 1413int xfrm6_state_init(void);
1399void xfrm6_state_fini(void); 1414void xfrm6_state_fini(void);
1415int xfrm6_protocol_init(void);
1416void xfrm6_protocol_fini(void);
1400#else 1417#else
1401static inline int xfrm6_init(void) 1418static inline int xfrm6_init(void)
1402{ 1419{
@@ -1423,7 +1440,7 @@ static inline void xfrm_sysctl_fini(struct net *net)
1423#endif 1440#endif
1424 1441
1425void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto, 1442void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1426 struct xfrm_filter *filter); 1443 struct xfrm_address_filter *filter);
1427int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, 1444int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1428 int (*func)(struct xfrm_state *, int, void*), void *); 1445 int (*func)(struct xfrm_state *, int, void*), void *);
1429void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net); 1446void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
@@ -1531,8 +1548,6 @@ int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char prot
1531int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); 1548int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1532int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); 1549int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
1533void xfrm4_local_error(struct sk_buff *skb, u32 mtu); 1550void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1534int xfrm6_mode_tunnel_input_register(struct xfrm_tunnel_notifier *handler);
1535int xfrm6_mode_tunnel_input_deregister(struct xfrm_tunnel_notifier *handler);
1536int xfrm6_extract_header(struct sk_buff *skb); 1551int xfrm6_extract_header(struct sk_buff *skb);
1537int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); 1552int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1538int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); 1553int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
@@ -1541,6 +1556,9 @@ int xfrm6_rcv(struct sk_buff *skb);
1541int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, 1556int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1542 xfrm_address_t *saddr, u8 proto); 1557 xfrm_address_t *saddr, u8 proto);
1543void xfrm6_local_error(struct sk_buff *skb, u32 mtu); 1558void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
1559int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
1560int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
1561int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
1544int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); 1562int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
1545int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); 1563int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
1546__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); 1564__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
@@ -1784,18 +1802,6 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
1784 return ret; 1802 return ret;
1785} 1803}
1786 1804
1787static inline int xfrm_rcv_cb(struct sk_buff *skb, unsigned int family,
1788 u8 protocol, int err)
1789{
1790 switch(family) {
1791#ifdef CONFIG_INET
1792 case AF_INET:
1793 return xfrm4_rcv_cb(skb, protocol, err);
1794#endif
1795 }
1796 return 0;
1797}
1798
1799static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x, 1805static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
1800 unsigned int family) 1806 unsigned int family)
1801{ 1807{
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 6550c679584f..25e5dd916ba4 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -299,7 +299,7 @@ enum xfrm_attr_type_t {
299 XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */ 299 XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */
300 XFRMA_SA_EXTRA_FLAGS, /* __u32 */ 300 XFRMA_SA_EXTRA_FLAGS, /* __u32 */
301 XFRMA_PROTO, /* __u8 */ 301 XFRMA_PROTO, /* __u8 */
302 XFRMA_FILTER, /* struct xfrm_filter */ 302 XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */
303 __XFRMA_MAX 303 __XFRMA_MAX
304 304
305#define XFRMA_MAX (__XFRMA_MAX - 1) 305#define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -476,7 +476,7 @@ struct xfrm_user_mapping {
476 __be16 new_sport; 476 __be16 new_sport;
477}; 477};
478 478
479struct xfrm_filter { 479struct xfrm_address_filter {
480 xfrm_address_t saddr; 480 xfrm_address_t saddr;
481 xfrm_address_t daddr; 481 xfrm_address_t daddr;
482 __u16 family; 482 __u16 family;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index e1a63930a967..6156f68a1e90 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -325,6 +325,7 @@ void __init xfrm4_init(void)
325 325
326 xfrm4_state_init(); 326 xfrm4_state_init();
327 xfrm4_policy_init(); 327 xfrm4_policy_init();
328 xfrm4_protocol_init();
328#ifdef CONFIG_SYSCTL 329#ifdef CONFIG_SYSCTL
329 register_pernet_subsys(&xfrm4_net_ops); 330 register_pernet_subsys(&xfrm4_net_ops);
330#endif 331#endif
diff --git a/net/ipv4/xfrm4_protocol.c b/net/ipv4/xfrm4_protocol.c
index cdc09efca442..7f7b243e8139 100644
--- a/net/ipv4/xfrm4_protocol.c
+++ b/net/ipv4/xfrm4_protocol.c
@@ -179,6 +179,12 @@ static const struct net_protocol ipcomp4_protocol = {
179 .netns_ok = 1, 179 .netns_ok = 1,
180}; 180};
181 181
182static struct xfrm_input_afinfo xfrm4_input_afinfo = {
183 .family = AF_INET,
184 .owner = THIS_MODULE,
185 .callback = xfrm4_rcv_cb,
186};
187
182static inline const struct net_protocol *netproto(unsigned char protocol) 188static inline const struct net_protocol *netproto(unsigned char protocol)
183{ 189{
184 switch (protocol) { 190 switch (protocol) {
@@ -199,7 +205,6 @@ int xfrm4_protocol_register(struct xfrm4_protocol *handler,
199 struct xfrm4_protocol __rcu **pprev; 205 struct xfrm4_protocol __rcu **pprev;
200 struct xfrm4_protocol *t; 206 struct xfrm4_protocol *t;
201 bool add_netproto = false; 207 bool add_netproto = false;
202
203 int ret = -EEXIST; 208 int ret = -EEXIST;
204 int priority = handler->priority; 209 int priority = handler->priority;
205 210
@@ -273,3 +278,9 @@ int xfrm4_protocol_deregister(struct xfrm4_protocol *handler,
273 return ret; 278 return ret;
274} 279}
275EXPORT_SYMBOL(xfrm4_protocol_deregister); 280EXPORT_SYMBOL(xfrm4_protocol_deregister);
281
282void __init xfrm4_protocol_init(void)
283{
284 xfrm_input_register_afinfo(&xfrm4_input_afinfo);
285}
286EXPORT_SYMBOL(xfrm4_protocol_init);
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 17bb830872db..2fe68364bb20 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -16,7 +16,7 @@ ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o
16ipv6-$(CONFIG_IPV6_MROUTE) += ip6mr.o 16ipv6-$(CONFIG_IPV6_MROUTE) += ip6mr.o
17 17
18ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ 18ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
19 xfrm6_output.o 19 xfrm6_output.o xfrm6_protocol.o
20ipv6-$(CONFIG_NETFILTER) += netfilter.o 20ipv6-$(CONFIG_NETFILTER) += netfilter.o
21ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o 21ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
22ipv6-$(CONFIG_PROC_FS) += proc.o 22ipv6-$(CONFIG_PROC_FS) += proc.o
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 6c5f0949e0ab..72a4930bdc0a 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -643,8 +643,8 @@ out:
643 return err; 643 return err;
644} 644}
645 645
646static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 646static int ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
647 u8 type, u8 code, int offset, __be32 info) 647 u8 type, u8 code, int offset, __be32 info)
648{ 648{
649 struct net *net = dev_net(skb->dev); 649 struct net *net = dev_net(skb->dev);
650 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 650 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
@@ -653,17 +653,19 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
653 653
654 if (type != ICMPV6_PKT_TOOBIG && 654 if (type != ICMPV6_PKT_TOOBIG &&
655 type != NDISC_REDIRECT) 655 type != NDISC_REDIRECT)
656 return; 656 return 0;
657 657
658 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); 658 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
659 if (!x) 659 if (!x)
660 return; 660 return 0;
661 661
662 if (type == NDISC_REDIRECT) 662 if (type == NDISC_REDIRECT)
663 ip6_redirect(skb, net, skb->dev->ifindex, 0); 663 ip6_redirect(skb, net, skb->dev->ifindex, 0);
664 else 664 else
665 ip6_update_pmtu(skb, net, info, 0, 0); 665 ip6_update_pmtu(skb, net, info, 0, 0);
666 xfrm_state_put(x); 666 xfrm_state_put(x);
667
668 return 0;
667} 669}
668 670
669static int ah6_init_state(struct xfrm_state *x) 671static int ah6_init_state(struct xfrm_state *x)
@@ -748,6 +750,11 @@ static void ah6_destroy(struct xfrm_state *x)
748 kfree(ahp); 750 kfree(ahp);
749} 751}
750 752
753static int ah6_rcv_cb(struct sk_buff *skb, int err)
754{
755 return 0;
756}
757
751static const struct xfrm_type ah6_type = 758static const struct xfrm_type ah6_type =
752{ 759{
753 .description = "AH6", 760 .description = "AH6",
@@ -761,10 +768,11 @@ static const struct xfrm_type ah6_type =
761 .hdr_offset = xfrm6_find_1stfragopt, 768 .hdr_offset = xfrm6_find_1stfragopt,
762}; 769};
763 770
764static const struct inet6_protocol ah6_protocol = { 771static struct xfrm6_protocol ah6_protocol = {
765 .handler = xfrm6_rcv, 772 .handler = xfrm6_rcv,
773 .cb_handler = ah6_rcv_cb,
766 .err_handler = ah6_err, 774 .err_handler = ah6_err,
767 .flags = INET6_PROTO_NOPOLICY, 775 .priority = 0,
768}; 776};
769 777
770static int __init ah6_init(void) 778static int __init ah6_init(void)
@@ -774,7 +782,7 @@ static int __init ah6_init(void)
774 return -EAGAIN; 782 return -EAGAIN;
775 } 783 }
776 784
777 if (inet6_add_protocol(&ah6_protocol, IPPROTO_AH) < 0) { 785 if (xfrm6_protocol_register(&ah6_protocol, IPPROTO_AH) < 0) {
778 pr_info("%s: can't add protocol\n", __func__); 786 pr_info("%s: can't add protocol\n", __func__);
779 xfrm_unregister_type(&ah6_type, AF_INET6); 787 xfrm_unregister_type(&ah6_type, AF_INET6);
780 return -EAGAIN; 788 return -EAGAIN;
@@ -785,7 +793,7 @@ static int __init ah6_init(void)
785 793
786static void __exit ah6_fini(void) 794static void __exit ah6_fini(void)
787{ 795{
788 if (inet6_del_protocol(&ah6_protocol, IPPROTO_AH) < 0) 796 if (xfrm6_protocol_deregister(&ah6_protocol, IPPROTO_AH) < 0)
789 pr_info("%s: can't remove protocol\n", __func__); 797 pr_info("%s: can't remove protocol\n", __func__);
790 798
791 if (xfrm_unregister_type(&ah6_type, AF_INET6) < 0) 799 if (xfrm_unregister_type(&ah6_type, AF_INET6) < 0)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 6eef8a7e35f2..d15da1377149 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -421,8 +421,8 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
421 net_adj) & ~(blksize - 1)) + net_adj - 2; 421 net_adj) & ~(blksize - 1)) + net_adj - 2;
422} 422}
423 423
424static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 424static int esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
425 u8 type, u8 code, int offset, __be32 info) 425 u8 type, u8 code, int offset, __be32 info)
426{ 426{
427 struct net *net = dev_net(skb->dev); 427 struct net *net = dev_net(skb->dev);
428 const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data; 428 const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data;
@@ -431,18 +431,20 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
431 431
432 if (type != ICMPV6_PKT_TOOBIG && 432 if (type != ICMPV6_PKT_TOOBIG &&
433 type != NDISC_REDIRECT) 433 type != NDISC_REDIRECT)
434 return; 434 return 0;
435 435
436 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, 436 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
437 esph->spi, IPPROTO_ESP, AF_INET6); 437 esph->spi, IPPROTO_ESP, AF_INET6);
438 if (!x) 438 if (!x)
439 return; 439 return 0;
440 440
441 if (type == NDISC_REDIRECT) 441 if (type == NDISC_REDIRECT)
442 ip6_redirect(skb, net, skb->dev->ifindex, 0); 442 ip6_redirect(skb, net, skb->dev->ifindex, 0);
443 else 443 else
444 ip6_update_pmtu(skb, net, info, 0, 0); 444 ip6_update_pmtu(skb, net, info, 0, 0);
445 xfrm_state_put(x); 445 xfrm_state_put(x);
446
447 return 0;
446} 448}
447 449
448static void esp6_destroy(struct xfrm_state *x) 450static void esp6_destroy(struct xfrm_state *x)
@@ -614,6 +616,11 @@ error:
614 return err; 616 return err;
615} 617}
616 618
619static int esp6_rcv_cb(struct sk_buff *skb, int err)
620{
621 return 0;
622}
623
617static const struct xfrm_type esp6_type = 624static const struct xfrm_type esp6_type =
618{ 625{
619 .description = "ESP6", 626 .description = "ESP6",
@@ -628,10 +635,11 @@ static const struct xfrm_type esp6_type =
628 .hdr_offset = xfrm6_find_1stfragopt, 635 .hdr_offset = xfrm6_find_1stfragopt,
629}; 636};
630 637
631static const struct inet6_protocol esp6_protocol = { 638static struct xfrm6_protocol esp6_protocol = {
632 .handler = xfrm6_rcv, 639 .handler = xfrm6_rcv,
640 .cb_handler = esp6_rcv_cb,
633 .err_handler = esp6_err, 641 .err_handler = esp6_err,
634 .flags = INET6_PROTO_NOPOLICY, 642 .priority = 0,
635}; 643};
636 644
637static int __init esp6_init(void) 645static int __init esp6_init(void)
@@ -640,7 +648,7 @@ static int __init esp6_init(void)
640 pr_info("%s: can't add xfrm type\n", __func__); 648 pr_info("%s: can't add xfrm type\n", __func__);
641 return -EAGAIN; 649 return -EAGAIN;
642 } 650 }
643 if (inet6_add_protocol(&esp6_protocol, IPPROTO_ESP) < 0) { 651 if (xfrm6_protocol_register(&esp6_protocol, IPPROTO_ESP) < 0) {
644 pr_info("%s: can't add protocol\n", __func__); 652 pr_info("%s: can't add protocol\n", __func__);
645 xfrm_unregister_type(&esp6_type, AF_INET6); 653 xfrm_unregister_type(&esp6_type, AF_INET6);
646 return -EAGAIN; 654 return -EAGAIN;
@@ -651,7 +659,7 @@ static int __init esp6_init(void)
651 659
652static void __exit esp6_fini(void) 660static void __exit esp6_fini(void)
653{ 661{
654 if (inet6_del_protocol(&esp6_protocol, IPPROTO_ESP) < 0) 662 if (xfrm6_protocol_deregister(&esp6_protocol, IPPROTO_ESP) < 0)
655 pr_info("%s: can't remove protocol\n", __func__); 663 pr_info("%s: can't remove protocol\n", __func__);
656 if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0) 664 if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0)
657 pr_info("%s: can't remove xfrm type\n", __func__); 665 pr_info("%s: can't remove xfrm type\n", __func__);
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 864914399391..b7c0f827140b 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -278,7 +278,6 @@ static void vti6_dev_uninit(struct net_device *dev)
278 RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); 278 RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
279 else 279 else
280 vti6_tnl_unlink(ip6n, t); 280 vti6_tnl_unlink(ip6n, t);
281 ip6_tnl_dst_reset(t);
282 dev_put(dev); 281 dev_put(dev);
283} 282}
284 283
@@ -288,11 +287,8 @@ static int vti6_rcv(struct sk_buff *skb)
288 const struct ipv6hdr *ipv6h = ipv6_hdr(skb); 287 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
289 288
290 rcu_read_lock(); 289 rcu_read_lock();
291
292 if ((t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, 290 if ((t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
293 &ipv6h->daddr)) != NULL) { 291 &ipv6h->daddr)) != NULL) {
294 struct pcpu_sw_netstats *tstats;
295
296 if (t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) { 292 if (t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) {
297 rcu_read_unlock(); 293 rcu_read_unlock();
298 goto discard; 294 goto discard;
@@ -309,27 +305,58 @@ static int vti6_rcv(struct sk_buff *skb)
309 goto discard; 305 goto discard;
310 } 306 }
311 307
312 tstats = this_cpu_ptr(t->dev->tstats); 308 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
313 u64_stats_update_begin(&tstats->syncp); 309 skb->mark = be32_to_cpu(t->parms.i_key);
314 tstats->rx_packets++;
315 tstats->rx_bytes += skb->len;
316 u64_stats_update_end(&tstats->syncp);
317
318 skb->mark = 0;
319 secpath_reset(skb);
320 skb->dev = t->dev;
321 310
322 rcu_read_unlock(); 311 rcu_read_unlock();
323 return 0; 312
313 return xfrm6_rcv(skb);
324 } 314 }
325 rcu_read_unlock(); 315 rcu_read_unlock();
326 return 1; 316 return -EINVAL;
327
328discard: 317discard:
329 kfree_skb(skb); 318 kfree_skb(skb);
330 return 0; 319 return 0;
331} 320}
332 321
322static int vti6_rcv_cb(struct sk_buff *skb, int err)
323{
324 unsigned short family;
325 struct net_device *dev;
326 struct pcpu_sw_netstats *tstats;
327 struct xfrm_state *x;
328 struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6;
329
330 if (!t)
331 return 1;
332
333 dev = t->dev;
334
335 if (err) {
336 dev->stats.rx_errors++;
337 dev->stats.rx_dropped++;
338
339 return 0;
340 }
341
342 x = xfrm_input_state(skb);
343 family = x->inner_mode->afinfo->family;
344
345 if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family))
346 return -EPERM;
347
348 skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev)));
349 skb->dev = dev;
350
351 tstats = this_cpu_ptr(dev->tstats);
352 u64_stats_update_begin(&tstats->syncp);
353 tstats->rx_packets++;
354 tstats->rx_bytes += skb->len;
355 u64_stats_update_end(&tstats->syncp);
356
357 return 0;
358}
359
333/** 360/**
334 * vti6_addr_conflict - compare packet addresses to tunnel's own 361 * vti6_addr_conflict - compare packet addresses to tunnel's own
335 * @t: the outgoing tunnel device 362 * @t: the outgoing tunnel device
@@ -349,44 +376,56 @@ vti6_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
349 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 376 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
350} 377}
351 378
379static bool vti6_state_check(const struct xfrm_state *x,
380 const struct in6_addr *dst,
381 const struct in6_addr *src)
382{
383 xfrm_address_t *daddr = (xfrm_address_t *)dst;
384 xfrm_address_t *saddr = (xfrm_address_t *)src;
385
386 /* if there is no transform then this tunnel is not functional.
387 * Or if the xfrm is not mode tunnel.
388 */
389 if (!x || x->props.mode != XFRM_MODE_TUNNEL ||
390 x->props.family != AF_INET6)
391 return false;
392
393 if (ipv6_addr_any(dst))
394 return xfrm_addr_equal(saddr, &x->props.saddr, AF_INET6);
395
396 if (!xfrm_state_addr_check(x, daddr, saddr, AF_INET6))
397 return false;
398
399 return true;
400}
401
352/** 402/**
353 * vti6_xmit - send a packet 403 * vti6_xmit - send a packet
354 * @skb: the outgoing socket buffer 404 * @skb: the outgoing socket buffer
355 * @dev: the outgoing tunnel device 405 * @dev: the outgoing tunnel device
406 * @fl: the flow informations for the xfrm_lookup
356 **/ 407 **/
357static int vti6_xmit(struct sk_buff *skb, struct net_device *dev) 408static int
409vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
358{ 410{
359 struct net *net = dev_net(dev);
360 struct ip6_tnl *t = netdev_priv(dev); 411 struct ip6_tnl *t = netdev_priv(dev);
361 struct net_device_stats *stats = &t->dev->stats; 412 struct net_device_stats *stats = &t->dev->stats;
362 struct dst_entry *dst = NULL, *ndst = NULL; 413 struct dst_entry *dst = skb_dst(skb);
363 struct flowi6 fl6;
364 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
365 struct net_device *tdev; 414 struct net_device *tdev;
366 int err = -1; 415 int err = -1;
367 416
368 if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || 417 if (!dst)
369 !ip6_tnl_xmit_ctl(t) || vti6_addr_conflict(t, ipv6h)) 418 goto tx_err_link_failure;
370 return err;
371
372 dst = ip6_tnl_dst_check(t);
373 if (!dst) {
374 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
375
376 ndst = ip6_route_output(net, NULL, &fl6);
377 419
378 if (ndst->error) 420 dst_hold(dst);
379 goto tx_err_link_failure; 421 dst = xfrm_lookup(t->net, dst, fl, NULL, 0);
380 ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(&fl6), NULL, 0); 422 if (IS_ERR(dst)) {
381 if (IS_ERR(ndst)) { 423 err = PTR_ERR(dst);
382 err = PTR_ERR(ndst); 424 dst = NULL;
383 ndst = NULL; 425 goto tx_err_link_failure;
384 goto tx_err_link_failure;
385 }
386 dst = ndst;
387 } 426 }
388 427
389 if (!dst->xfrm || dst->xfrm->props.mode != XFRM_MODE_TUNNEL) 428 if (!vti6_state_check(dst->xfrm, &t->parms.raddr, &t->parms.laddr))
390 goto tx_err_link_failure; 429 goto tx_err_link_failure;
391 430
392 tdev = dst->dev; 431 tdev = dst->dev;
@@ -398,14 +437,21 @@ static int vti6_xmit(struct sk_buff *skb, struct net_device *dev)
398 goto tx_err_dst_release; 437 goto tx_err_dst_release;
399 } 438 }
400 439
440 skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
441 skb_dst_set(skb, dst);
442 skb->dev = skb_dst(skb)->dev;
401 443
402 skb_dst_drop(skb); 444 err = dst_output(skb);
403 skb_dst_set_noref(skb, dst); 445 if (net_xmit_eval(err) == 0) {
446 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
404 447
405 ip6tunnel_xmit(skb, dev); 448 u64_stats_update_begin(&tstats->syncp);
406 if (ndst) { 449 tstats->tx_bytes += skb->len;
407 dev->mtu = dst_mtu(ndst); 450 tstats->tx_packets++;
408 ip6_tnl_dst_store(t, ndst); 451 u64_stats_update_end(&tstats->syncp);
452 } else {
453 stats->tx_errors++;
454 stats->tx_aborted_errors++;
409 } 455 }
410 456
411 return 0; 457 return 0;
@@ -413,7 +459,7 @@ tx_err_link_failure:
413 stats->tx_carrier_errors++; 459 stats->tx_carrier_errors++;
414 dst_link_failure(skb); 460 dst_link_failure(skb);
415tx_err_dst_release: 461tx_err_dst_release:
416 dst_release(ndst); 462 dst_release(dst);
417 return err; 463 return err;
418} 464}
419 465
@@ -422,16 +468,33 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
422{ 468{
423 struct ip6_tnl *t = netdev_priv(dev); 469 struct ip6_tnl *t = netdev_priv(dev);
424 struct net_device_stats *stats = &t->dev->stats; 470 struct net_device_stats *stats = &t->dev->stats;
471 struct ipv6hdr *ipv6h;
472 struct flowi fl;
425 int ret; 473 int ret;
426 474
475 memset(&fl, 0, sizeof(fl));
476 skb->mark = be32_to_cpu(t->parms.o_key);
477
427 switch (skb->protocol) { 478 switch (skb->protocol) {
428 case htons(ETH_P_IPV6): 479 case htons(ETH_P_IPV6):
429 ret = vti6_xmit(skb, dev); 480 ipv6h = ipv6_hdr(skb);
481
482 if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) ||
483 !ip6_tnl_xmit_ctl(t) || vti6_addr_conflict(t, ipv6h))
484 goto tx_err;
485
486 xfrm_decode_session(skb, &fl, AF_INET6);
487 memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
488 break;
489 case htons(ETH_P_IP):
490 xfrm_decode_session(skb, &fl, AF_INET);
491 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
430 break; 492 break;
431 default: 493 default:
432 goto tx_err; 494 goto tx_err;
433 } 495 }
434 496
497 ret = vti6_xmit(skb, dev, &fl);
435 if (ret < 0) 498 if (ret < 0)
436 goto tx_err; 499 goto tx_err;
437 500
@@ -444,24 +507,66 @@ tx_err:
444 return NETDEV_TX_OK; 507 return NETDEV_TX_OK;
445} 508}
446 509
510static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
511 u8 type, u8 code, int offset, __be32 info)
512{
513 __be32 spi;
514 struct xfrm_state *x;
515 struct ip6_tnl *t;
516 struct ip_esp_hdr *esph;
517 struct ip_auth_hdr *ah;
518 struct ip_comp_hdr *ipch;
519 struct net *net = dev_net(skb->dev);
520 const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data;
521 int protocol = iph->nexthdr;
522
523 t = vti6_tnl_lookup(dev_net(skb->dev), &iph->daddr, &iph->saddr);
524 if (!t)
525 return -1;
526
527 switch (protocol) {
528 case IPPROTO_ESP:
529 esph = (struct ip_esp_hdr *)(skb->data + offset);
530 spi = esph->spi;
531 break;
532 case IPPROTO_AH:
533 ah = (struct ip_auth_hdr *)(skb->data + offset);
534 spi = ah->spi;
535 break;
536 case IPPROTO_COMP:
537 ipch = (struct ip_comp_hdr *)(skb->data + offset);
538 spi = htonl(ntohs(ipch->cpi));
539 break;
540 default:
541 return 0;
542 }
543
544 if (type != ICMPV6_PKT_TOOBIG &&
545 type != NDISC_REDIRECT)
546 return 0;
547
548 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
549 spi, protocol, AF_INET6);
550 if (!x)
551 return 0;
552
553 if (type == NDISC_REDIRECT)
554 ip6_redirect(skb, net, skb->dev->ifindex, 0);
555 else
556 ip6_update_pmtu(skb, net, info, 0, 0);
557 xfrm_state_put(x);
558
559 return 0;
560}
561
447static void vti6_link_config(struct ip6_tnl *t) 562static void vti6_link_config(struct ip6_tnl *t)
448{ 563{
449 struct dst_entry *dst;
450 struct net_device *dev = t->dev; 564 struct net_device *dev = t->dev;
451 struct __ip6_tnl_parm *p = &t->parms; 565 struct __ip6_tnl_parm *p = &t->parms;
452 struct flowi6 *fl6 = &t->fl.u.ip6;
453 566
454 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); 567 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
455 memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); 568 memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
456 569
457 /* Set up flowi template */
458 fl6->saddr = p->laddr;
459 fl6->daddr = p->raddr;
460 fl6->flowi6_oif = p->link;
461 fl6->flowi6_mark = be32_to_cpu(p->i_key);
462 fl6->flowi6_proto = p->proto;
463 fl6->flowlabel = 0;
464
465 p->flags &= ~(IP6_TNL_F_CAP_XMIT | IP6_TNL_F_CAP_RCV | 570 p->flags &= ~(IP6_TNL_F_CAP_XMIT | IP6_TNL_F_CAP_RCV |
466 IP6_TNL_F_CAP_PER_PACKET); 571 IP6_TNL_F_CAP_PER_PACKET);
467 p->flags |= ip6_tnl_get_cap(t, &p->laddr, &p->raddr); 572 p->flags |= ip6_tnl_get_cap(t, &p->laddr, &p->raddr);
@@ -472,28 +577,6 @@ static void vti6_link_config(struct ip6_tnl *t)
472 dev->flags &= ~IFF_POINTOPOINT; 577 dev->flags &= ~IFF_POINTOPOINT;
473 578
474 dev->iflink = p->link; 579 dev->iflink = p->link;
475
476 if (p->flags & IP6_TNL_F_CAP_XMIT) {
477
478 dst = ip6_route_output(dev_net(dev), NULL, fl6);
479 if (dst->error)
480 return;
481
482 dst = xfrm_lookup(dev_net(dev), dst, flowi6_to_flowi(fl6),
483 NULL, 0);
484 if (IS_ERR(dst))
485 return;
486
487 if (dst->dev) {
488 dev->hard_header_len = dst->dev->hard_header_len;
489
490 dev->mtu = dst_mtu(dst);
491
492 if (dev->mtu < IPV6_MIN_MTU)
493 dev->mtu = IPV6_MIN_MTU;
494 }
495 dst_release(dst);
496 }
497} 580}
498 581
499/** 582/**
@@ -720,7 +803,6 @@ static void vti6_dev_setup(struct net_device *dev)
720 t = netdev_priv(dev); 803 t = netdev_priv(dev);
721 dev->flags |= IFF_NOARP; 804 dev->flags |= IFF_NOARP;
722 dev->addr_len = sizeof(struct in6_addr); 805 dev->addr_len = sizeof(struct in6_addr);
723 dev->features |= NETIF_F_NETNS_LOCAL;
724 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 806 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
725} 807}
726 808
@@ -908,11 +990,6 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = {
908 .fill_info = vti6_fill_info, 990 .fill_info = vti6_fill_info,
909}; 991};
910 992
911static struct xfrm_tunnel_notifier vti6_handler __read_mostly = {
912 .handler = vti6_rcv,
913 .priority = 1,
914};
915
916static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n) 993static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n)
917{ 994{
918 int h; 995 int h;
@@ -984,6 +1061,27 @@ static struct pernet_operations vti6_net_ops = {
984 .size = sizeof(struct vti6_net), 1061 .size = sizeof(struct vti6_net),
985}; 1062};
986 1063
1064static struct xfrm6_protocol vti_esp6_protocol __read_mostly = {
1065 .handler = vti6_rcv,
1066 .cb_handler = vti6_rcv_cb,
1067 .err_handler = vti6_err,
1068 .priority = 100,
1069};
1070
1071static struct xfrm6_protocol vti_ah6_protocol __read_mostly = {
1072 .handler = vti6_rcv,
1073 .cb_handler = vti6_rcv_cb,
1074 .err_handler = vti6_err,
1075 .priority = 100,
1076};
1077
1078static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = {
1079 .handler = vti6_rcv,
1080 .cb_handler = vti6_rcv_cb,
1081 .err_handler = vti6_err,
1082 .priority = 100,
1083};
1084
987/** 1085/**
988 * vti6_tunnel_init - register protocol and reserve needed resources 1086 * vti6_tunnel_init - register protocol and reserve needed resources
989 * 1087 *
@@ -997,11 +1095,33 @@ static int __init vti6_tunnel_init(void)
997 if (err < 0) 1095 if (err < 0)
998 goto out_pernet; 1096 goto out_pernet;
999 1097
1000 err = xfrm6_mode_tunnel_input_register(&vti6_handler); 1098 err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP);
1001 if (err < 0) { 1099 if (err < 0) {
1002 pr_err("%s: can't register vti6\n", __func__); 1100 unregister_pernet_device(&vti6_net_ops);
1101 pr_err("%s: can't register vti6 protocol\n", __func__);
1102
1003 goto out; 1103 goto out;
1004 } 1104 }
1105
1106 err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH);
1107 if (err < 0) {
1108 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1109 unregister_pernet_device(&vti6_net_ops);
1110 pr_err("%s: can't register vti6 protocol\n", __func__);
1111
1112 goto out;
1113 }
1114
1115 err = xfrm6_protocol_register(&vti_ipcomp6_protocol, IPPROTO_COMP);
1116 if (err < 0) {
1117 xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
1118 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1119 unregister_pernet_device(&vti6_net_ops);
1120 pr_err("%s: can't register vti6 protocol\n", __func__);
1121
1122 goto out;
1123 }
1124
1005 err = rtnl_link_register(&vti6_link_ops); 1125 err = rtnl_link_register(&vti6_link_ops);
1006 if (err < 0) 1126 if (err < 0)
1007 goto rtnl_link_failed; 1127 goto rtnl_link_failed;
@@ -1009,7 +1129,9 @@ static int __init vti6_tunnel_init(void)
1009 return 0; 1129 return 0;
1010 1130
1011rtnl_link_failed: 1131rtnl_link_failed:
1012 xfrm6_mode_tunnel_input_deregister(&vti6_handler); 1132 xfrm6_protocol_deregister(&vti_ipcomp6_protocol, IPPROTO_COMP);
1133 xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
1134 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1013out: 1135out:
1014 unregister_pernet_device(&vti6_net_ops); 1136 unregister_pernet_device(&vti6_net_ops);
1015out_pernet: 1137out_pernet:
@@ -1022,8 +1144,12 @@ out_pernet:
1022static void __exit vti6_tunnel_cleanup(void) 1144static void __exit vti6_tunnel_cleanup(void)
1023{ 1145{
1024 rtnl_link_unregister(&vti6_link_ops); 1146 rtnl_link_unregister(&vti6_link_ops);
1025 if (xfrm6_mode_tunnel_input_deregister(&vti6_handler)) 1147 if (xfrm6_protocol_deregister(&vti_ipcomp6_protocol, IPPROTO_COMP))
1026 pr_info("%s: can't deregister vti6\n", __func__); 1148 pr_info("%s: can't deregister protocol\n", __func__);
1149 if (xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH))
1150 pr_info("%s: can't deregister protocol\n", __func__);
1151 if (xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP))
1152 pr_info("%s: can't deregister protocol\n", __func__);
1027 1153
1028 unregister_pernet_device(&vti6_net_ops); 1154 unregister_pernet_device(&vti6_net_ops);
1029} 1155}
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index da9becb42e81..d1c793cffcb5 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -53,7 +53,7 @@
53#include <linux/icmpv6.h> 53#include <linux/icmpv6.h>
54#include <linux/mutex.h> 54#include <linux/mutex.h>
55 55
56static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 56static int ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
57 u8 type, u8 code, int offset, __be32 info) 57 u8 type, u8 code, int offset, __be32 info)
58{ 58{
59 struct net *net = dev_net(skb->dev); 59 struct net *net = dev_net(skb->dev);
@@ -65,19 +65,21 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
65 65
66 if (type != ICMPV6_PKT_TOOBIG && 66 if (type != ICMPV6_PKT_TOOBIG &&
67 type != NDISC_REDIRECT) 67 type != NDISC_REDIRECT)
68 return; 68 return 0;
69 69
70 spi = htonl(ntohs(ipcomph->cpi)); 70 spi = htonl(ntohs(ipcomph->cpi));
71 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, 71 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
72 spi, IPPROTO_COMP, AF_INET6); 72 spi, IPPROTO_COMP, AF_INET6);
73 if (!x) 73 if (!x)
74 return; 74 return 0;
75 75
76 if (type == NDISC_REDIRECT) 76 if (type == NDISC_REDIRECT)
77 ip6_redirect(skb, net, skb->dev->ifindex, 0); 77 ip6_redirect(skb, net, skb->dev->ifindex, 0);
78 else 78 else
79 ip6_update_pmtu(skb, net, info, 0, 0); 79 ip6_update_pmtu(skb, net, info, 0, 0);
80 xfrm_state_put(x); 80 xfrm_state_put(x);
81
82 return 0;
81} 83}
82 84
83static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) 85static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
@@ -174,6 +176,11 @@ out:
174 return err; 176 return err;
175} 177}
176 178
179static int ipcomp6_rcv_cb(struct sk_buff *skb, int err)
180{
181 return 0;
182}
183
177static const struct xfrm_type ipcomp6_type = 184static const struct xfrm_type ipcomp6_type =
178{ 185{
179 .description = "IPCOMP6", 186 .description = "IPCOMP6",
@@ -186,11 +193,12 @@ static const struct xfrm_type ipcomp6_type =
186 .hdr_offset = xfrm6_find_1stfragopt, 193 .hdr_offset = xfrm6_find_1stfragopt,
187}; 194};
188 195
189static const struct inet6_protocol ipcomp6_protocol = 196static struct xfrm6_protocol ipcomp6_protocol =
190{ 197{
191 .handler = xfrm6_rcv, 198 .handler = xfrm6_rcv,
199 .cb_handler = ipcomp6_rcv_cb,
192 .err_handler = ipcomp6_err, 200 .err_handler = ipcomp6_err,
193 .flags = INET6_PROTO_NOPOLICY, 201 .priority = 0,
194}; 202};
195 203
196static int __init ipcomp6_init(void) 204static int __init ipcomp6_init(void)
@@ -199,7 +207,7 @@ static int __init ipcomp6_init(void)
199 pr_info("%s: can't add xfrm type\n", __func__); 207 pr_info("%s: can't add xfrm type\n", __func__);
200 return -EAGAIN; 208 return -EAGAIN;
201 } 209 }
202 if (inet6_add_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) { 210 if (xfrm6_protocol_register(&ipcomp6_protocol, IPPROTO_COMP) < 0) {
203 pr_info("%s: can't add protocol\n", __func__); 211 pr_info("%s: can't add protocol\n", __func__);
204 xfrm_unregister_type(&ipcomp6_type, AF_INET6); 212 xfrm_unregister_type(&ipcomp6_type, AF_INET6);
205 return -EAGAIN; 213 return -EAGAIN;
@@ -209,7 +217,7 @@ static int __init ipcomp6_init(void)
209 217
210static void __exit ipcomp6_fini(void) 218static void __exit ipcomp6_fini(void)
211{ 219{
212 if (inet6_del_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) 220 if (xfrm6_protocol_deregister(&ipcomp6_protocol, IPPROTO_COMP) < 0)
213 pr_info("%s: can't remove protocol\n", __func__); 221 pr_info("%s: can't remove protocol\n", __func__);
214 if (xfrm_unregister_type(&ipcomp6_type, AF_INET6) < 0) 222 if (xfrm_unregister_type(&ipcomp6_type, AF_INET6) < 0)
215 pr_info("%s: can't remove xfrm type\n", __func__); 223 pr_info("%s: can't remove xfrm type\n", __func__);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index cb04f7a16b5e..901ef6f8addc 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -18,65 +18,6 @@
18#include <net/ipv6.h> 18#include <net/ipv6.h>
19#include <net/xfrm.h> 19#include <net/xfrm.h>
20 20
21/* Informational hook. The decap is still done here. */
22static struct xfrm_tunnel_notifier __rcu *rcv_notify_handlers __read_mostly;
23static DEFINE_MUTEX(xfrm6_mode_tunnel_input_mutex);
24
25int xfrm6_mode_tunnel_input_register(struct xfrm_tunnel_notifier *handler)
26{
27 struct xfrm_tunnel_notifier __rcu **pprev;
28 struct xfrm_tunnel_notifier *t;
29 int ret = -EEXIST;
30 int priority = handler->priority;
31
32 mutex_lock(&xfrm6_mode_tunnel_input_mutex);
33
34 for (pprev = &rcv_notify_handlers;
35 (t = rcu_dereference_protected(*pprev,
36 lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
37 pprev = &t->next) {
38 if (t->priority > priority)
39 break;
40 if (t->priority == priority)
41 goto err;
42
43 }
44
45 handler->next = *pprev;
46 rcu_assign_pointer(*pprev, handler);
47
48 ret = 0;
49
50err:
51 mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
52 return ret;
53}
54EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_register);
55
56int xfrm6_mode_tunnel_input_deregister(struct xfrm_tunnel_notifier *handler)
57{
58 struct xfrm_tunnel_notifier __rcu **pprev;
59 struct xfrm_tunnel_notifier *t;
60 int ret = -ENOENT;
61
62 mutex_lock(&xfrm6_mode_tunnel_input_mutex);
63 for (pprev = &rcv_notify_handlers;
64 (t = rcu_dereference_protected(*pprev,
65 lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
66 pprev = &t->next) {
67 if (t == handler) {
68 *pprev = handler->next;
69 ret = 0;
70 break;
71 }
72 }
73 mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
74 synchronize_net();
75
76 return ret;
77}
78EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_deregister);
79
80static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) 21static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
81{ 22{
82 const struct ipv6hdr *outer_iph = ipv6_hdr(skb); 23 const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
@@ -130,7 +71,6 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
130 71
131static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) 72static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
132{ 73{
133 struct xfrm_tunnel_notifier *handler;
134 int err = -EINVAL; 74 int err = -EINVAL;
135 75
136 if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) 76 if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
@@ -138,9 +78,6 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
138 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 78 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
139 goto out; 79 goto out;
140 80
141 for_each_input_rcu(rcv_notify_handlers, handler)
142 handler->handler(skb);
143
144 err = skb_unclone(skb, GFP_ATOMIC); 81 err = skb_unclone(skb, GFP_ATOMIC);
145 if (err) 82 if (err)
146 goto out; 83 goto out;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 5f8e128c512d..2a0bbda2c76a 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -389,11 +389,17 @@ int __init xfrm6_init(void)
389 if (ret) 389 if (ret)
390 goto out_policy; 390 goto out_policy;
391 391
392 ret = xfrm6_protocol_init();
393 if (ret)
394 goto out_state;
395
392#ifdef CONFIG_SYSCTL 396#ifdef CONFIG_SYSCTL
393 register_pernet_subsys(&xfrm6_net_ops); 397 register_pernet_subsys(&xfrm6_net_ops);
394#endif 398#endif
395out: 399out:
396 return ret; 400 return ret;
401out_state:
402 xfrm6_state_fini();
397out_policy: 403out_policy:
398 xfrm6_policy_fini(); 404 xfrm6_policy_fini();
399 goto out; 405 goto out;
@@ -404,6 +410,7 @@ void xfrm6_fini(void)
404#ifdef CONFIG_SYSCTL 410#ifdef CONFIG_SYSCTL
405 unregister_pernet_subsys(&xfrm6_net_ops); 411 unregister_pernet_subsys(&xfrm6_net_ops);
406#endif 412#endif
413 xfrm6_protocol_fini();
407 xfrm6_policy_fini(); 414 xfrm6_policy_fini();
408 xfrm6_state_fini(); 415 xfrm6_state_fini();
409 dst_entries_destroy(&xfrm6_dst_ops); 416 dst_entries_destroy(&xfrm6_dst_ops);
diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
new file mode 100644
index 000000000000..6ab989c486f7
--- /dev/null
+++ b/net/ipv6/xfrm6_protocol.c
@@ -0,0 +1,270 @@
1/* xfrm6_protocol.c - Generic xfrm protocol multiplexer for ipv6.
2 *
3 * Copyright (C) 2013 secunet Security Networks AG
4 *
5 * Author:
6 * Steffen Klassert <steffen.klassert@secunet.com>
7 *
8 * Based on:
9 * net/ipv4/xfrm4_protocol.c
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/init.h>
18#include <linux/mutex.h>
19#include <linux/skbuff.h>
20#include <linux/icmpv6.h>
21#include <net/ipv6.h>
22#include <net/protocol.h>
23#include <net/xfrm.h>
24
25static struct xfrm6_protocol __rcu *esp6_handlers __read_mostly;
26static struct xfrm6_protocol __rcu *ah6_handlers __read_mostly;
27static struct xfrm6_protocol __rcu *ipcomp6_handlers __read_mostly;
28static DEFINE_MUTEX(xfrm6_protocol_mutex);
29
30static inline struct xfrm6_protocol __rcu **proto_handlers(u8 protocol)
31{
32 switch (protocol) {
33 case IPPROTO_ESP:
34 return &esp6_handlers;
35 case IPPROTO_AH:
36 return &ah6_handlers;
37 case IPPROTO_COMP:
38 return &ipcomp6_handlers;
39 }
40
41 return NULL;
42}
43
44#define for_each_protocol_rcu(head, handler) \
45 for (handler = rcu_dereference(head); \
46 handler != NULL; \
47 handler = rcu_dereference(handler->next)) \
48
49int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
50{
51 int ret;
52 struct xfrm6_protocol *handler;
53
54 for_each_protocol_rcu(*proto_handlers(protocol), handler)
55 if ((ret = handler->cb_handler(skb, err)) <= 0)
56 return ret;
57
58 return 0;
59}
60EXPORT_SYMBOL(xfrm6_rcv_cb);
61
62static int xfrm6_esp_rcv(struct sk_buff *skb)
63{
64 int ret;
65 struct xfrm6_protocol *handler;
66
67 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
68
69 for_each_protocol_rcu(esp6_handlers, handler)
70 if ((ret = handler->handler(skb)) != -EINVAL)
71 return ret;
72
73 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
74
75 kfree_skb(skb);
76 return 0;
77}
78
79static void xfrm6_esp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
80 u8 type, u8 code, int offset, __be32 info)
81{
82 struct xfrm6_protocol *handler;
83
84 for_each_protocol_rcu(esp6_handlers, handler)
85 if (!handler->err_handler(skb, opt, type, code, offset, info))
86 break;
87}
88
89static int xfrm6_ah_rcv(struct sk_buff *skb)
90{
91 int ret;
92 struct xfrm6_protocol *handler;
93
94 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
95
96 for_each_protocol_rcu(ah6_handlers, handler)
97 if ((ret = handler->handler(skb)) != -EINVAL)
98 return ret;
99
100 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
101
102 kfree_skb(skb);
103 return 0;
104}
105
106static void xfrm6_ah_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 u8 type, u8 code, int offset, __be32 info)
108{
109 struct xfrm6_protocol *handler;
110
111 for_each_protocol_rcu(ah6_handlers, handler)
112 if (!handler->err_handler(skb, opt, type, code, offset, info))
113 break;
114}
115
116static int xfrm6_ipcomp_rcv(struct sk_buff *skb)
117{
118 int ret;
119 struct xfrm6_protocol *handler;
120
121 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
122
123 for_each_protocol_rcu(ipcomp6_handlers, handler)
124 if ((ret = handler->handler(skb)) != -EINVAL)
125 return ret;
126
127 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
128
129 kfree_skb(skb);
130 return 0;
131}
132
133static void xfrm6_ipcomp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
134 u8 type, u8 code, int offset, __be32 info)
135{
136 struct xfrm6_protocol *handler;
137
138 for_each_protocol_rcu(ipcomp6_handlers, handler)
139 if (!handler->err_handler(skb, opt, type, code, offset, info))
140 break;
141}
142
143static const struct inet6_protocol esp6_protocol = {
144 .handler = xfrm6_esp_rcv,
145 .err_handler = xfrm6_esp_err,
146 .flags = INET6_PROTO_NOPOLICY,
147};
148
149static const struct inet6_protocol ah6_protocol = {
150 .handler = xfrm6_ah_rcv,
151 .err_handler = xfrm6_ah_err,
152 .flags = INET6_PROTO_NOPOLICY,
153};
154
155static const struct inet6_protocol ipcomp6_protocol = {
156 .handler = xfrm6_ipcomp_rcv,
157 .err_handler = xfrm6_ipcomp_err,
158 .flags = INET6_PROTO_NOPOLICY,
159};
160
161static struct xfrm_input_afinfo xfrm6_input_afinfo = {
162 .family = AF_INET6,
163 .owner = THIS_MODULE,
164 .callback = xfrm6_rcv_cb,
165};
166
167static inline const struct inet6_protocol *netproto(unsigned char protocol)
168{
169 switch (protocol) {
170 case IPPROTO_ESP:
171 return &esp6_protocol;
172 case IPPROTO_AH:
173 return &ah6_protocol;
174 case IPPROTO_COMP:
175 return &ipcomp6_protocol;
176 }
177
178 return NULL;
179}
180
181int xfrm6_protocol_register(struct xfrm6_protocol *handler,
182 unsigned char protocol)
183{
184 struct xfrm6_protocol __rcu **pprev;
185 struct xfrm6_protocol *t;
186 bool add_netproto = false;
187
188 int ret = -EEXIST;
189 int priority = handler->priority;
190
191 mutex_lock(&xfrm6_protocol_mutex);
192
193 if (!rcu_dereference_protected(*proto_handlers(protocol),
194 lockdep_is_held(&xfrm6_protocol_mutex)))
195 add_netproto = true;
196
197 for (pprev = proto_handlers(protocol);
198 (t = rcu_dereference_protected(*pprev,
199 lockdep_is_held(&xfrm6_protocol_mutex))) != NULL;
200 pprev = &t->next) {
201 if (t->priority < priority)
202 break;
203 if (t->priority == priority)
204 goto err;
205 }
206
207 handler->next = *pprev;
208 rcu_assign_pointer(*pprev, handler);
209
210 ret = 0;
211
212err:
213 mutex_unlock(&xfrm6_protocol_mutex);
214
215 if (add_netproto) {
216 if (inet6_add_protocol(netproto(protocol), protocol)) {
217 pr_err("%s: can't add protocol\n", __func__);
218 ret = -EAGAIN;
219 }
220 }
221
222 return ret;
223}
224EXPORT_SYMBOL(xfrm6_protocol_register);
225
226int xfrm6_protocol_deregister(struct xfrm6_protocol *handler,
227 unsigned char protocol)
228{
229 struct xfrm6_protocol __rcu **pprev;
230 struct xfrm6_protocol *t;
231 int ret = -ENOENT;
232
233 mutex_lock(&xfrm6_protocol_mutex);
234
235 for (pprev = proto_handlers(protocol);
236 (t = rcu_dereference_protected(*pprev,
237 lockdep_is_held(&xfrm6_protocol_mutex))) != NULL;
238 pprev = &t->next) {
239 if (t == handler) {
240 *pprev = handler->next;
241 ret = 0;
242 break;
243 }
244 }
245
246 if (!rcu_dereference_protected(*proto_handlers(protocol),
247 lockdep_is_held(&xfrm6_protocol_mutex))) {
248 if (inet6_del_protocol(netproto(protocol), protocol) < 0) {
249 pr_err("%s: can't remove protocol\n", __func__);
250 ret = -EAGAIN;
251 }
252 }
253
254 mutex_unlock(&xfrm6_protocol_mutex);
255
256 synchronize_net();
257
258 return ret;
259}
260EXPORT_SYMBOL(xfrm6_protocol_deregister);
261
262int __init xfrm6_protocol_init(void)
263{
264 return xfrm_input_register_afinfo(&xfrm6_input_afinfo);
265}
266
267void xfrm6_protocol_fini(void)
268{
269 xfrm_input_unregister_afinfo(&xfrm6_input_afinfo);
270}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a50d979b5926..12651b42aad8 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1799,7 +1799,7 @@ static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1799static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 1799static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
1800{ 1800{
1801 u8 proto; 1801 u8 proto;
1802 struct xfrm_filter *filter = NULL; 1802 struct xfrm_address_filter *filter = NULL;
1803 struct pfkey_sock *pfk = pfkey_sk(sk); 1803 struct pfkey_sock *pfk = pfkey_sk(sk);
1804 1804
1805 if (pfk->dump.dump != NULL) 1805 if (pfk->dump.dump != NULL)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 4218164f4f5e..85d1d4764612 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -16,6 +16,81 @@
16 16
17static struct kmem_cache *secpath_cachep __read_mostly; 17static struct kmem_cache *secpath_cachep __read_mostly;
18 18
19static DEFINE_SPINLOCK(xfrm_input_afinfo_lock);
20static struct xfrm_input_afinfo __rcu *xfrm_input_afinfo[NPROTO];
21
22int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo)
23{
24 int err = 0;
25
26 if (unlikely(afinfo == NULL))
27 return -EINVAL;
28 if (unlikely(afinfo->family >= NPROTO))
29 return -EAFNOSUPPORT;
30 spin_lock_bh(&xfrm_input_afinfo_lock);
31 if (unlikely(xfrm_input_afinfo[afinfo->family] != NULL))
32 err = -ENOBUFS;
33 else
34 rcu_assign_pointer(xfrm_input_afinfo[afinfo->family], afinfo);
35 spin_unlock_bh(&xfrm_input_afinfo_lock);
36 return err;
37}
38EXPORT_SYMBOL(xfrm_input_register_afinfo);
39
40int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo)
41{
42 int err = 0;
43
44 if (unlikely(afinfo == NULL))
45 return -EINVAL;
46 if (unlikely(afinfo->family >= NPROTO))
47 return -EAFNOSUPPORT;
48 spin_lock_bh(&xfrm_input_afinfo_lock);
49 if (likely(xfrm_input_afinfo[afinfo->family] != NULL)) {
50 if (unlikely(xfrm_input_afinfo[afinfo->family] != afinfo))
51 err = -EINVAL;
52 else
53 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->family], NULL);
54 }
55 spin_unlock_bh(&xfrm_input_afinfo_lock);
56 synchronize_rcu();
57 return err;
58}
59EXPORT_SYMBOL(xfrm_input_unregister_afinfo);
60
61static struct xfrm_input_afinfo *xfrm_input_get_afinfo(unsigned int family)
62{
63 struct xfrm_input_afinfo *afinfo;
64
65 if (unlikely(family >= NPROTO))
66 return NULL;
67 rcu_read_lock();
68 afinfo = rcu_dereference(xfrm_input_afinfo[family]);
69 if (unlikely(!afinfo))
70 rcu_read_unlock();
71 return afinfo;
72}
73
74static void xfrm_input_put_afinfo(struct xfrm_input_afinfo *afinfo)
75{
76 rcu_read_unlock();
77}
78
79static int xfrm_rcv_cb(struct sk_buff *skb, unsigned int family, u8 protocol,
80 int err)
81{
82 int ret;
83 struct xfrm_input_afinfo *afinfo = xfrm_input_get_afinfo(family);
84
85 if (!afinfo)
86 return -EAFNOSUPPORT;
87
88 ret = afinfo->callback(skb, protocol, err);
89 xfrm_input_put_afinfo(afinfo);
90
91 return ret;
92}
93
19void __secpath_destroy(struct sec_path *sp) 94void __secpath_destroy(struct sec_path *sp)
20{ 95{
21 int i; 96 int i;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 06970fee9155..8e9c781a6bba 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1609,7 +1609,7 @@ unlock:
1609EXPORT_SYMBOL(xfrm_alloc_spi); 1609EXPORT_SYMBOL(xfrm_alloc_spi);
1610 1610
1611static bool __xfrm_state_filter_match(struct xfrm_state *x, 1611static bool __xfrm_state_filter_match(struct xfrm_state *x,
1612 struct xfrm_filter *filter) 1612 struct xfrm_address_filter *filter)
1613{ 1613{
1614 if (filter) { 1614 if (filter) {
1615 if ((filter->family == AF_INET || 1615 if ((filter->family == AF_INET ||
@@ -1668,7 +1668,7 @@ out:
1668EXPORT_SYMBOL(xfrm_state_walk); 1668EXPORT_SYMBOL(xfrm_state_walk);
1669 1669
1670void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto, 1670void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1671 struct xfrm_filter *filter) 1671 struct xfrm_address_filter *filter)
1672{ 1672{
1673 INIT_LIST_HEAD(&walk->all); 1673 INIT_LIST_HEAD(&walk->all);
1674 walk->proto = proto; 1674 walk->proto = proto;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 195dbe230b98..cdd9e9c7ff0e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -899,7 +899,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
899 899
900 if (!cb->args[0]) { 900 if (!cb->args[0]) {
901 struct nlattr *attrs[XFRMA_MAX+1]; 901 struct nlattr *attrs[XFRMA_MAX+1];
902 struct xfrm_filter *filter = NULL; 902 struct xfrm_address_filter *filter = NULL;
903 u8 proto = 0; 903 u8 proto = 0;
904 int err; 904 int err;
905 905
@@ -910,12 +910,12 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
910 if (err < 0) 910 if (err < 0)
911 return err; 911 return err;
912 912
913 if (attrs[XFRMA_FILTER]) { 913 if (attrs[XFRMA_ADDRESS_FILTER]) {
914 filter = kmalloc(sizeof(*filter), GFP_KERNEL); 914 filter = kmalloc(sizeof(*filter), GFP_KERNEL);
915 if (filter == NULL) 915 if (filter == NULL)
916 return -ENOMEM; 916 return -ENOMEM;
917 917
918 memcpy(filter, nla_data(attrs[XFRMA_FILTER]), 918 memcpy(filter, nla_data(attrs[XFRMA_ADDRESS_FILTER]),
919 sizeof(*filter)); 919 sizeof(*filter));
920 } 920 }
921 921
@@ -2329,7 +2329,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
2329 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) }, 2329 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) },
2330 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 }, 2330 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 },
2331 [XFRMA_PROTO] = { .type = NLA_U8 }, 2331 [XFRMA_PROTO] = { .type = NLA_U8 },
2332 [XFRMA_FILTER] = { .len = sizeof(struct xfrm_filter) }, 2332 [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) },
2333}; 2333};
2334 2334
2335static const struct xfrm_link { 2335static const struct xfrm_link {