.. | .. |
---|
37 | 37 | #include <net/ip.h> |
---|
38 | 38 | #include <net/ipv6.h> |
---|
39 | 39 | #include <net/ip6_route.h> |
---|
| 40 | +#include <net/ip_tunnels.h> |
---|
40 | 41 | #include <net/addrconf.h> |
---|
41 | 42 | #include <net/xfrm.h> |
---|
42 | 43 | #include <net/net_namespace.h> |
---|
.. | .. |
---|
47 | 48 | static void xfrmi_dev_setup(struct net_device *dev); |
---|
48 | 49 | static struct rtnl_link_ops xfrmi_link_ops __read_mostly; |
---|
49 | 50 | static unsigned int xfrmi_net_id __read_mostly; |
---|
| 51 | +static const struct net_device_ops xfrmi_netdev_ops; |
---|
| 52 | + |
---|
| 53 | +#define XFRMI_HASH_BITS 8 |
---|
| 54 | +#define XFRMI_HASH_SIZE BIT(XFRMI_HASH_BITS) |
---|
50 | 55 | |
---|
51 | 56 | struct xfrmi_net { |
---|
52 | 57 | /* lists for storing interfaces in use */ |
---|
53 | | - struct xfrm_if __rcu *xfrmi[1]; |
---|
| 58 | + struct xfrm_if __rcu *xfrmi[XFRMI_HASH_SIZE]; |
---|
54 | 59 | }; |
---|
55 | 60 | |
---|
56 | 61 | #define for_each_xfrmi_rcu(start, xi) \ |
---|
57 | 62 | for (xi = rcu_dereference(start); xi; xi = rcu_dereference(xi->next)) |
---|
| 63 | + |
---|
| 64 | +static u32 xfrmi_hash(u32 if_id) |
---|
| 65 | +{ |
---|
| 66 | + return hash_32(if_id, XFRMI_HASH_BITS); |
---|
| 67 | +} |
---|
58 | 68 | |
---|
59 | 69 | static struct xfrm_if *xfrmi_lookup(struct net *net, struct xfrm_state *x) |
---|
60 | 70 | { |
---|
61 | 71 | struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id); |
---|
62 | 72 | struct xfrm_if *xi; |
---|
63 | 73 | |
---|
64 | | - for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) { |
---|
| 74 | + for_each_xfrmi_rcu(xfrmn->xfrmi[xfrmi_hash(x->if_id)], xi) { |
---|
65 | 75 | if (x->if_id == xi->p.if_id && |
---|
66 | 76 | (xi->dev->flags & IFF_UP)) |
---|
67 | 77 | return xi; |
---|
.. | .. |
---|
73 | 83 | static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb, |
---|
74 | 84 | unsigned short family) |
---|
75 | 85 | { |
---|
76 | | - struct xfrmi_net *xfrmn; |
---|
77 | | - struct xfrm_if *xi; |
---|
| 86 | + struct net_device *dev; |
---|
78 | 87 | int ifindex = 0; |
---|
79 | 88 | |
---|
80 | 89 | if (!secpath_exists(skb) || !skb->dev) |
---|
.. | .. |
---|
88 | 97 | ifindex = inet_sdif(skb); |
---|
89 | 98 | break; |
---|
90 | 99 | } |
---|
91 | | - if (!ifindex) |
---|
92 | | - ifindex = skb->dev->ifindex; |
---|
93 | 100 | |
---|
94 | | - xfrmn = net_generic(xs_net(xfrm_input_state(skb)), xfrmi_net_id); |
---|
| 101 | + if (ifindex) { |
---|
| 102 | + struct net *net = xs_net(xfrm_input_state(skb)); |
---|
95 | 103 | |
---|
96 | | - for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) { |
---|
97 | | - if (ifindex == xi->dev->ifindex && |
---|
98 | | - (xi->dev->flags & IFF_UP)) |
---|
99 | | - return xi; |
---|
| 104 | + dev = dev_get_by_index_rcu(net, ifindex); |
---|
| 105 | + } else { |
---|
| 106 | + dev = skb->dev; |
---|
100 | 107 | } |
---|
101 | 108 | |
---|
102 | | - return NULL; |
---|
| 109 | + if (!dev || !(dev->flags & IFF_UP)) |
---|
| 110 | + return NULL; |
---|
| 111 | + if (dev->netdev_ops != &xfrmi_netdev_ops) |
---|
| 112 | + return NULL; |
---|
| 113 | + |
---|
| 114 | + return netdev_priv(dev); |
---|
103 | 115 | } |
---|
104 | 116 | |
---|
105 | 117 | static void xfrmi_link(struct xfrmi_net *xfrmn, struct xfrm_if *xi) |
---|
106 | 118 | { |
---|
107 | | - struct xfrm_if __rcu **xip = &xfrmn->xfrmi[0]; |
---|
| 119 | + struct xfrm_if __rcu **xip = &xfrmn->xfrmi[xfrmi_hash(xi->p.if_id)]; |
---|
108 | 120 | |
---|
109 | 121 | rcu_assign_pointer(xi->next , rtnl_dereference(*xip)); |
---|
110 | 122 | rcu_assign_pointer(*xip, xi); |
---|
.. | .. |
---|
115 | 127 | struct xfrm_if __rcu **xip; |
---|
116 | 128 | struct xfrm_if *iter; |
---|
117 | 129 | |
---|
118 | | - for (xip = &xfrmn->xfrmi[0]; |
---|
| 130 | + for (xip = &xfrmn->xfrmi[xfrmi_hash(xi->p.if_id)]; |
---|
119 | 131 | (iter = rtnl_dereference(*xip)) != NULL; |
---|
120 | 132 | xip = &iter->next) { |
---|
121 | 133 | if (xi == iter) { |
---|
.. | .. |
---|
145 | 157 | if (err < 0) |
---|
146 | 158 | goto out; |
---|
147 | 159 | |
---|
148 | | - dev_hold(dev); |
---|
149 | 160 | xfrmi_link(xfrmn, xi); |
---|
150 | 161 | |
---|
151 | 162 | return 0; |
---|
.. | .. |
---|
160 | 171 | struct xfrm_if *xi; |
---|
161 | 172 | struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id); |
---|
162 | 173 | |
---|
163 | | - for (xip = &xfrmn->xfrmi[0]; |
---|
| 174 | + for (xip = &xfrmn->xfrmi[xfrmi_hash(p->if_id)]; |
---|
164 | 175 | (xi = rtnl_dereference(*xip)) != NULL; |
---|
165 | 176 | xip = &xi->next) |
---|
166 | 177 | if (xi->p.if_id == p->if_id) |
---|
.. | .. |
---|
175 | 186 | struct xfrmi_net *xfrmn = net_generic(xi->net, xfrmi_net_id); |
---|
176 | 187 | |
---|
177 | 188 | xfrmi_unlink(xfrmn, xi); |
---|
178 | | - dev_put(dev); |
---|
179 | 189 | } |
---|
180 | 190 | |
---|
181 | 191 | static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet) |
---|
.. | .. |
---|
185 | 195 | skb->skb_iif = 0; |
---|
186 | 196 | skb->ignore_df = 0; |
---|
187 | 197 | skb_dst_drop(skb); |
---|
188 | | - nf_reset(skb); |
---|
| 198 | + nf_reset_ct(skb); |
---|
189 | 199 | nf_reset_trace(skb); |
---|
190 | 200 | |
---|
191 | 201 | if (!xnet) |
---|
.. | .. |
---|
199 | 209 | |
---|
200 | 210 | static int xfrmi_rcv_cb(struct sk_buff *skb, int err) |
---|
201 | 211 | { |
---|
202 | | - struct pcpu_sw_netstats *tstats; |
---|
203 | | - struct xfrm_mode *inner_mode; |
---|
| 212 | + const struct xfrm_mode *inner_mode; |
---|
204 | 213 | struct net_device *dev; |
---|
205 | 214 | struct xfrm_state *x; |
---|
206 | 215 | struct xfrm_if *xi; |
---|
207 | 216 | bool xnet; |
---|
208 | 217 | |
---|
209 | | - if (err && !skb->sp) |
---|
| 218 | + if (err && !secpath_exists(skb)) |
---|
210 | 219 | return 0; |
---|
211 | 220 | |
---|
212 | 221 | x = xfrm_input_state(skb); |
---|
.. | .. |
---|
228 | 237 | xnet = !net_eq(xi->net, dev_net(skb->dev)); |
---|
229 | 238 | |
---|
230 | 239 | if (xnet) { |
---|
231 | | - inner_mode = x->inner_mode; |
---|
| 240 | + inner_mode = &x->inner_mode; |
---|
232 | 241 | |
---|
233 | 242 | if (x->sel.family == AF_UNSPEC) { |
---|
234 | 243 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); |
---|
.. | .. |
---|
240 | 249 | } |
---|
241 | 250 | |
---|
242 | 251 | if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, |
---|
243 | | - inner_mode->afinfo->family)) |
---|
| 252 | + inner_mode->family)) |
---|
244 | 253 | return -EPERM; |
---|
245 | 254 | } |
---|
246 | 255 | |
---|
247 | 256 | xfrmi_scrub_packet(skb, xnet); |
---|
248 | | - |
---|
249 | | - tstats = this_cpu_ptr(dev->tstats); |
---|
250 | | - |
---|
251 | | - u64_stats_update_begin(&tstats->syncp); |
---|
252 | | - tstats->rx_packets++; |
---|
253 | | - tstats->rx_bytes += skb->len; |
---|
254 | | - u64_stats_update_end(&tstats->syncp); |
---|
| 257 | + dev_sw_netstats_rx_add(dev, skb->len); |
---|
255 | 258 | |
---|
256 | 259 | return 0; |
---|
257 | 260 | } |
---|
.. | .. |
---|
300 | 303 | if (mtu < IPV6_MIN_MTU) |
---|
301 | 304 | mtu = IPV6_MIN_MTU; |
---|
302 | 305 | |
---|
303 | | - icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
---|
| 306 | + if (skb->len > 1280) |
---|
| 307 | + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
---|
| 308 | + else |
---|
| 309 | + goto xmit; |
---|
304 | 310 | } else { |
---|
305 | 311 | if (!(ip_hdr(skb)->frag_off & htons(IP_DF))) |
---|
306 | 312 | goto xmit; |
---|
.. | .. |
---|
451 | 457 | } |
---|
452 | 458 | |
---|
453 | 459 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) |
---|
454 | | - ipv4_update_pmtu(skb, net, info, 0, 0, protocol, 0); |
---|
| 460 | + ipv4_update_pmtu(skb, net, info, 0, protocol); |
---|
455 | 461 | else |
---|
456 | | - ipv4_redirect(skb, net, 0, 0, protocol, 0); |
---|
| 462 | + ipv4_redirect(skb, net, 0, protocol); |
---|
457 | 463 | xfrm_state_put(x); |
---|
458 | 464 | |
---|
459 | 465 | return 0; |
---|
.. | .. |
---|
541 | 547 | static void xfrmi_get_stats64(struct net_device *dev, |
---|
542 | 548 | struct rtnl_link_stats64 *s) |
---|
543 | 549 | { |
---|
544 | | - int cpu; |
---|
545 | | - |
---|
546 | | - if (!dev->tstats) |
---|
547 | | - return; |
---|
548 | | - |
---|
549 | | - for_each_possible_cpu(cpu) { |
---|
550 | | - struct pcpu_sw_netstats *stats; |
---|
551 | | - struct pcpu_sw_netstats tmp; |
---|
552 | | - int start; |
---|
553 | | - |
---|
554 | | - stats = per_cpu_ptr(dev->tstats, cpu); |
---|
555 | | - do { |
---|
556 | | - start = u64_stats_fetch_begin_irq(&stats->syncp); |
---|
557 | | - tmp.rx_packets = stats->rx_packets; |
---|
558 | | - tmp.rx_bytes = stats->rx_bytes; |
---|
559 | | - tmp.tx_packets = stats->tx_packets; |
---|
560 | | - tmp.tx_bytes = stats->tx_bytes; |
---|
561 | | - } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); |
---|
562 | | - |
---|
563 | | - s->rx_packets += tmp.rx_packets; |
---|
564 | | - s->rx_bytes += tmp.rx_bytes; |
---|
565 | | - s->tx_packets += tmp.tx_packets; |
---|
566 | | - s->tx_bytes += tmp.tx_bytes; |
---|
567 | | - } |
---|
| 550 | + dev_fetch_sw_netstats(s, dev->tstats); |
---|
568 | 551 | |
---|
569 | 552 | s->rx_dropped = dev->stats.rx_dropped; |
---|
570 | 553 | s->tx_dropped = dev->stats.tx_dropped; |
---|
.. | .. |
---|
589 | 572 | static void xfrmi_dev_setup(struct net_device *dev) |
---|
590 | 573 | { |
---|
591 | 574 | dev->netdev_ops = &xfrmi_netdev_ops; |
---|
| 575 | + dev->header_ops = &ip_tunnel_header_ops; |
---|
592 | 576 | dev->type = ARPHRD_NONE; |
---|
593 | 577 | dev->mtu = ETH_DATA_LEN; |
---|
594 | 578 | dev->min_mtu = ETH_MIN_MTU; |
---|
.. | .. |
---|
698 | 682 | struct net *net = xi->net; |
---|
699 | 683 | struct xfrm_if_parms p = {}; |
---|
700 | 684 | |
---|
| 685 | + xfrmi_netlink_parms(data, &p); |
---|
701 | 686 | if (!p.if_id) { |
---|
702 | 687 | NL_SET_ERR_MSG(extack, "if_id must be non zero"); |
---|
703 | 688 | return -EINVAL; |
---|
704 | 689 | } |
---|
705 | 690 | |
---|
706 | | - xfrmi_netlink_parms(data, &p); |
---|
707 | 691 | xi = xfrmi_locate(net, &p); |
---|
708 | 692 | if (!xi) { |
---|
709 | 693 | xi = netdev_priv(dev); |
---|
.. | .. |
---|
739 | 723 | return -EMSGSIZE; |
---|
740 | 724 | } |
---|
741 | 725 | |
---|
742 | | -struct net *xfrmi_get_link_net(const struct net_device *dev) |
---|
| 726 | +static struct net *xfrmi_get_link_net(const struct net_device *dev) |
---|
743 | 727 | { |
---|
744 | 728 | struct xfrm_if *xi = netdev_priv(dev); |
---|
745 | 729 | |
---|
.. | .. |
---|
766 | 750 | .get_link_net = xfrmi_get_link_net, |
---|
767 | 751 | }; |
---|
768 | 752 | |
---|
769 | | -static void __net_exit xfrmi_destroy_interfaces(struct xfrmi_net *xfrmn) |
---|
770 | | -{ |
---|
771 | | - struct xfrm_if *xi; |
---|
772 | | - LIST_HEAD(list); |
---|
773 | | - |
---|
774 | | - xi = rtnl_dereference(xfrmn->xfrmi[0]); |
---|
775 | | - if (!xi) |
---|
776 | | - return; |
---|
777 | | - |
---|
778 | | - unregister_netdevice_queue(xi->dev, &list); |
---|
779 | | - unregister_netdevice_many(&list); |
---|
780 | | -} |
---|
781 | | - |
---|
782 | | -static int __net_init xfrmi_init_net(struct net *net) |
---|
783 | | -{ |
---|
784 | | - return 0; |
---|
785 | | -} |
---|
786 | | - |
---|
787 | | -static void __net_exit xfrmi_exit_net(struct net *net) |
---|
788 | | -{ |
---|
789 | | - struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id); |
---|
790 | | - |
---|
791 | | - rtnl_lock(); |
---|
792 | | - xfrmi_destroy_interfaces(xfrmn); |
---|
793 | | - rtnl_unlock(); |
---|
794 | | -} |
---|
795 | | - |
---|
796 | 753 | static void __net_exit xfrmi_exit_batch_net(struct list_head *net_exit_list) |
---|
797 | 754 | { |
---|
798 | 755 | struct net *net; |
---|
.. | .. |
---|
803 | 760 | struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id); |
---|
804 | 761 | struct xfrm_if __rcu **xip; |
---|
805 | 762 | struct xfrm_if *xi; |
---|
| 763 | + int i; |
---|
806 | 764 | |
---|
807 | | - for (xip = &xfrmn->xfrmi[0]; |
---|
808 | | - (xi = rtnl_dereference(*xip)) != NULL; |
---|
809 | | - xip = &xi->next) |
---|
810 | | - unregister_netdevice_queue(xi->dev, &list); |
---|
| 765 | + for (i = 0; i < XFRMI_HASH_SIZE; i++) { |
---|
| 766 | + for (xip = &xfrmn->xfrmi[i]; |
---|
| 767 | + (xi = rtnl_dereference(*xip)) != NULL; |
---|
| 768 | + xip = &xi->next) |
---|
| 769 | + unregister_netdevice_queue(xi->dev, &list); |
---|
| 770 | + } |
---|
811 | 771 | } |
---|
812 | 772 | unregister_netdevice_many(&list); |
---|
813 | 773 | rtnl_unlock(); |
---|
.. | .. |
---|
815 | 775 | |
---|
816 | 776 | static struct pernet_operations xfrmi_net_ops = { |
---|
817 | 777 | .exit_batch = xfrmi_exit_batch_net, |
---|
818 | | - .init = xfrmi_init_net, |
---|
819 | | - .exit = xfrmi_exit_net, |
---|
820 | 778 | .id = &xfrmi_net_id, |
---|
821 | 779 | .size = sizeof(struct xfrmi_net), |
---|
822 | 780 | }; |
---|
823 | 781 | |
---|
824 | 782 | static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = { |
---|
825 | 783 | .handler = xfrm6_rcv, |
---|
| 784 | + .input_handler = xfrm_input, |
---|
826 | 785 | .cb_handler = xfrmi_rcv_cb, |
---|
827 | 786 | .err_handler = xfrmi6_err, |
---|
828 | 787 | .priority = 10, |
---|
.. | .. |
---|
830 | 789 | |
---|
831 | 790 | static struct xfrm6_protocol xfrmi_ah6_protocol __read_mostly = { |
---|
832 | 791 | .handler = xfrm6_rcv, |
---|
| 792 | + .input_handler = xfrm_input, |
---|
833 | 793 | .cb_handler = xfrmi_rcv_cb, |
---|
834 | 794 | .err_handler = xfrmi6_err, |
---|
835 | 795 | .priority = 10, |
---|
.. | .. |
---|
837 | 797 | |
---|
838 | 798 | static struct xfrm6_protocol xfrmi_ipcomp6_protocol __read_mostly = { |
---|
839 | 799 | .handler = xfrm6_rcv, |
---|
| 800 | + .input_handler = xfrm_input, |
---|
840 | 801 | .cb_handler = xfrmi_rcv_cb, |
---|
841 | 802 | .err_handler = xfrmi6_err, |
---|
842 | 803 | .priority = 10, |
---|
843 | 804 | }; |
---|
| 805 | + |
---|
| 806 | +#if IS_REACHABLE(CONFIG_INET6_XFRM_TUNNEL) |
---|
| 807 | +static int xfrmi6_rcv_tunnel(struct sk_buff *skb) |
---|
| 808 | +{ |
---|
| 809 | + const xfrm_address_t *saddr; |
---|
| 810 | + __be32 spi; |
---|
| 811 | + |
---|
| 812 | + saddr = (const xfrm_address_t *)&ipv6_hdr(skb)->saddr; |
---|
| 813 | + spi = xfrm6_tunnel_spi_lookup(dev_net(skb->dev), saddr); |
---|
| 814 | + |
---|
| 815 | + return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL); |
---|
| 816 | +} |
---|
| 817 | + |
---|
| 818 | +static struct xfrm6_tunnel xfrmi_ipv6_handler __read_mostly = { |
---|
| 819 | + .handler = xfrmi6_rcv_tunnel, |
---|
| 820 | + .cb_handler = xfrmi_rcv_cb, |
---|
| 821 | + .err_handler = xfrmi6_err, |
---|
| 822 | + .priority = 2, |
---|
| 823 | +}; |
---|
| 824 | + |
---|
| 825 | +static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = { |
---|
| 826 | + .handler = xfrmi6_rcv_tunnel, |
---|
| 827 | + .cb_handler = xfrmi_rcv_cb, |
---|
| 828 | + .err_handler = xfrmi6_err, |
---|
| 829 | + .priority = 2, |
---|
| 830 | +}; |
---|
| 831 | +#endif |
---|
844 | 832 | |
---|
845 | 833 | static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = { |
---|
846 | 834 | .handler = xfrm4_rcv, |
---|
.. | .. |
---|
866 | 854 | .priority = 10, |
---|
867 | 855 | }; |
---|
868 | 856 | |
---|
| 857 | +#if IS_REACHABLE(CONFIG_INET_XFRM_TUNNEL) |
---|
| 858 | +static int xfrmi4_rcv_tunnel(struct sk_buff *skb) |
---|
| 859 | +{ |
---|
| 860 | + return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr); |
---|
| 861 | +} |
---|
| 862 | + |
---|
| 863 | +static struct xfrm_tunnel xfrmi_ipip_handler __read_mostly = { |
---|
| 864 | + .handler = xfrmi4_rcv_tunnel, |
---|
| 865 | + .cb_handler = xfrmi_rcv_cb, |
---|
| 866 | + .err_handler = xfrmi4_err, |
---|
| 867 | + .priority = 3, |
---|
| 868 | +}; |
---|
| 869 | + |
---|
| 870 | +static struct xfrm_tunnel xfrmi_ipip6_handler __read_mostly = { |
---|
| 871 | + .handler = xfrmi4_rcv_tunnel, |
---|
| 872 | + .cb_handler = xfrmi_rcv_cb, |
---|
| 873 | + .err_handler = xfrmi4_err, |
---|
| 874 | + .priority = 2, |
---|
| 875 | +}; |
---|
| 876 | +#endif |
---|
| 877 | + |
---|
869 | 878 | static int __init xfrmi4_init(void) |
---|
870 | 879 | { |
---|
871 | 880 | int err; |
---|
.. | .. |
---|
879 | 888 | err = xfrm4_protocol_register(&xfrmi_ipcomp4_protocol, IPPROTO_COMP); |
---|
880 | 889 | if (err < 0) |
---|
881 | 890 | goto xfrm_proto_comp_failed; |
---|
| 891 | +#if IS_REACHABLE(CONFIG_INET_XFRM_TUNNEL) |
---|
| 892 | + err = xfrm4_tunnel_register(&xfrmi_ipip_handler, AF_INET); |
---|
| 893 | + if (err < 0) |
---|
| 894 | + goto xfrm_tunnel_ipip_failed; |
---|
| 895 | + err = xfrm4_tunnel_register(&xfrmi_ipip6_handler, AF_INET6); |
---|
| 896 | + if (err < 0) |
---|
| 897 | + goto xfrm_tunnel_ipip6_failed; |
---|
| 898 | +#endif |
---|
882 | 899 | |
---|
883 | 900 | return 0; |
---|
884 | 901 | |
---|
| 902 | +#if IS_REACHABLE(CONFIG_INET_XFRM_TUNNEL) |
---|
| 903 | +xfrm_tunnel_ipip6_failed: |
---|
| 904 | + xfrm4_tunnel_deregister(&xfrmi_ipip_handler, AF_INET); |
---|
| 905 | +xfrm_tunnel_ipip_failed: |
---|
| 906 | + xfrm4_protocol_deregister(&xfrmi_ipcomp4_protocol, IPPROTO_COMP); |
---|
| 907 | +#endif |
---|
885 | 908 | xfrm_proto_comp_failed: |
---|
886 | 909 | xfrm4_protocol_deregister(&xfrmi_ah4_protocol, IPPROTO_AH); |
---|
887 | 910 | xfrm_proto_ah_failed: |
---|
.. | .. |
---|
892 | 915 | |
---|
893 | 916 | static void xfrmi4_fini(void) |
---|
894 | 917 | { |
---|
| 918 | +#if IS_REACHABLE(CONFIG_INET_XFRM_TUNNEL) |
---|
| 919 | + xfrm4_tunnel_deregister(&xfrmi_ipip6_handler, AF_INET6); |
---|
| 920 | + xfrm4_tunnel_deregister(&xfrmi_ipip_handler, AF_INET); |
---|
| 921 | +#endif |
---|
895 | 922 | xfrm4_protocol_deregister(&xfrmi_ipcomp4_protocol, IPPROTO_COMP); |
---|
896 | 923 | xfrm4_protocol_deregister(&xfrmi_ah4_protocol, IPPROTO_AH); |
---|
897 | 924 | xfrm4_protocol_deregister(&xfrmi_esp4_protocol, IPPROTO_ESP); |
---|
.. | .. |
---|
910 | 937 | err = xfrm6_protocol_register(&xfrmi_ipcomp6_protocol, IPPROTO_COMP); |
---|
911 | 938 | if (err < 0) |
---|
912 | 939 | goto xfrm_proto_comp_failed; |
---|
| 940 | +#if IS_REACHABLE(CONFIG_INET6_XFRM_TUNNEL) |
---|
| 941 | + err = xfrm6_tunnel_register(&xfrmi_ipv6_handler, AF_INET6); |
---|
| 942 | + if (err < 0) |
---|
| 943 | + goto xfrm_tunnel_ipv6_failed; |
---|
| 944 | + err = xfrm6_tunnel_register(&xfrmi_ip6ip_handler, AF_INET); |
---|
| 945 | + if (err < 0) |
---|
| 946 | + goto xfrm_tunnel_ip6ip_failed; |
---|
| 947 | +#endif |
---|
913 | 948 | |
---|
914 | 949 | return 0; |
---|
915 | 950 | |
---|
| 951 | +#if IS_REACHABLE(CONFIG_INET6_XFRM_TUNNEL) |
---|
| 952 | +xfrm_tunnel_ip6ip_failed: |
---|
| 953 | + xfrm6_tunnel_deregister(&xfrmi_ipv6_handler, AF_INET6); |
---|
| 954 | +xfrm_tunnel_ipv6_failed: |
---|
| 955 | + xfrm6_protocol_deregister(&xfrmi_ipcomp6_protocol, IPPROTO_COMP); |
---|
| 956 | +#endif |
---|
916 | 957 | xfrm_proto_comp_failed: |
---|
917 | 958 | xfrm6_protocol_deregister(&xfrmi_ah6_protocol, IPPROTO_AH); |
---|
918 | 959 | xfrm_proto_ah_failed: |
---|
.. | .. |
---|
923 | 964 | |
---|
924 | 965 | static void xfrmi6_fini(void) |
---|
925 | 966 | { |
---|
| 967 | +#if IS_REACHABLE(CONFIG_INET6_XFRM_TUNNEL) |
---|
| 968 | + xfrm6_tunnel_deregister(&xfrmi_ip6ip_handler, AF_INET); |
---|
| 969 | + xfrm6_tunnel_deregister(&xfrmi_ipv6_handler, AF_INET6); |
---|
| 970 | +#endif |
---|
926 | 971 | xfrm6_protocol_deregister(&xfrmi_ipcomp6_protocol, IPPROTO_COMP); |
---|
927 | 972 | xfrm6_protocol_deregister(&xfrmi_ah6_protocol, IPPROTO_AH); |
---|
928 | 973 | xfrm6_protocol_deregister(&xfrmi_esp6_protocol, IPPROTO_ESP); |
---|