1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Linux NET3: IP/IP protocol decoder.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Authors:
6*4882a593Smuzhiyun * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Fixes:
9*4882a593Smuzhiyun * Alan Cox : Merged and made usable non modular (its so tiny its silly as
10*4882a593Smuzhiyun * a module taking up 2 pages).
11*4882a593Smuzhiyun * Alan Cox : Fixed bug with 1.3.18 and IPIP not working (now needs to set skb->h.iph)
12*4882a593Smuzhiyun * to keep ip_forward happy.
13*4882a593Smuzhiyun * Alan Cox : More fixes for 1.3.21, and firewall fix. Maybe this will work soon 8).
14*4882a593Smuzhiyun * Kai Schulte : Fixed #defines for IP_FIREWALL->FIREWALL
15*4882a593Smuzhiyun * David Woodhouse : Perform some basic ICMP handling.
16*4882a593Smuzhiyun * IPIP Routing without decapsulation.
17*4882a593Smuzhiyun * Carlos Picoto : GRE over IP support
18*4882a593Smuzhiyun * Alexey Kuznetsov: Reworked. Really, now it is truncated version of ipv4/ip_gre.c.
19*4882a593Smuzhiyun * I do not want to merge them together.
20*4882a593Smuzhiyun */
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /* tunnel.c: an IP tunnel driver
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun The purpose of this driver is to provide an IP tunnel through
25*4882a593Smuzhiyun which you can tunnel network traffic transparently across subnets.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun This was written by looking at Nick Holloway's dummy driver
28*4882a593Smuzhiyun Thanks for the great code!
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun -Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun Minor tweaks:
33*4882a593Smuzhiyun Cleaned up the code a little and added some pre-1.3.0 tweaks.
34*4882a593Smuzhiyun dev->hard_header/hard_header_len changed to use no headers.
35*4882a593Smuzhiyun Comments/bracketing tweaked.
36*4882a593Smuzhiyun Made the tunnels use dev->name not tunnel: when error reporting.
37*4882a593Smuzhiyun Added tx_dropped stat
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun -Alan Cox (alan@lxorguk.ukuu.org.uk) 21 March 95
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun Reworked:
42*4882a593Smuzhiyun Changed to tunnel to destination gateway in addition to the
43*4882a593Smuzhiyun tunnel's pointopoint address
44*4882a593Smuzhiyun Almost completely rewritten
45*4882a593Smuzhiyun Note: There is currently no firewall or ICMP handling done.
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun -Sam Lantinga (slouken@cs.ucdavis.edu) 02/13/96
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* Things I wish I had known when writing the tunnel driver:
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun When the tunnel_xmit() function is called, the skb contains the
54*4882a593Smuzhiyun packet to be sent (plus a great deal of extra info), and dev
55*4882a593Smuzhiyun contains the tunnel device that _we_ are.
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun When we are passed a packet, we are expected to fill in the
58*4882a593Smuzhiyun source address with our source IP address.
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun What is the proper way to allocate, copy and free a buffer?
61*4882a593Smuzhiyun After you allocate it, it is a "0 length" chunk of memory
62*4882a593Smuzhiyun starting at zero. If you want to add headers to the buffer
63*4882a593Smuzhiyun later, you'll have to call "skb_reserve(skb, amount)" with
64*4882a593Smuzhiyun the amount of memory you want reserved. Then, you call
65*4882a593Smuzhiyun "skb_put(skb, amount)" with the amount of space you want in
66*4882a593Smuzhiyun the buffer. skb_put() returns a pointer to the top (#0) of
67*4882a593Smuzhiyun that buffer. skb->len is set to the amount of space you have
68*4882a593Smuzhiyun "allocated" with skb_put(). You can then write up to skb->len
69*4882a593Smuzhiyun bytes to that buffer. If you need more, you can call skb_put()
70*4882a593Smuzhiyun again with the additional amount of space you need. You can
71*4882a593Smuzhiyun find out how much more space you can allocate by calling
72*4882a593Smuzhiyun "skb_tailroom(skb)".
73*4882a593Smuzhiyun Now, to add header space, call "skb_push(skb, header_len)".
74*4882a593Smuzhiyun This creates space at the beginning of the buffer and returns
75*4882a593Smuzhiyun a pointer to this new space. If later you need to strip a
76*4882a593Smuzhiyun header from a buffer, call "skb_pull(skb, header_len)".
77*4882a593Smuzhiyun skb_headroom() will return how much space is left at the top
78*4882a593Smuzhiyun of the buffer (before the main data). Remember, this headroom
79*4882a593Smuzhiyun space must be reserved before the skb_put() function is called.
80*4882a593Smuzhiyun */
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /*
83*4882a593Smuzhiyun This version of net/ipv4/ipip.c is cloned of net/ipv4/ip_gre.c
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun For comments look at net/ipv4/ip_gre.c --ANK
86*4882a593Smuzhiyun */
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #include <linux/capability.h>
90*4882a593Smuzhiyun #include <linux/module.h>
91*4882a593Smuzhiyun #include <linux/types.h>
92*4882a593Smuzhiyun #include <linux/kernel.h>
93*4882a593Smuzhiyun #include <linux/slab.h>
94*4882a593Smuzhiyun #include <linux/uaccess.h>
95*4882a593Smuzhiyun #include <linux/skbuff.h>
96*4882a593Smuzhiyun #include <linux/netdevice.h>
97*4882a593Smuzhiyun #include <linux/in.h>
98*4882a593Smuzhiyun #include <linux/tcp.h>
99*4882a593Smuzhiyun #include <linux/udp.h>
100*4882a593Smuzhiyun #include <linux/if_arp.h>
101*4882a593Smuzhiyun #include <linux/init.h>
102*4882a593Smuzhiyun #include <linux/netfilter_ipv4.h>
103*4882a593Smuzhiyun #include <linux/if_ether.h>
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun #include <net/sock.h>
106*4882a593Smuzhiyun #include <net/ip.h>
107*4882a593Smuzhiyun #include <net/icmp.h>
108*4882a593Smuzhiyun #include <net/ip_tunnels.h>
109*4882a593Smuzhiyun #include <net/inet_ecn.h>
110*4882a593Smuzhiyun #include <net/xfrm.h>
111*4882a593Smuzhiyun #include <net/net_namespace.h>
112*4882a593Smuzhiyun #include <net/netns/generic.h>
113*4882a593Smuzhiyun #include <net/dst_metadata.h>
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun static bool log_ecn_error = true;
116*4882a593Smuzhiyun module_param(log_ecn_error, bool, 0644);
117*4882a593Smuzhiyun MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun static unsigned int ipip_net_id __read_mostly;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun static int ipip_tunnel_init(struct net_device *dev);
122*4882a593Smuzhiyun static struct rtnl_link_ops ipip_link_ops __read_mostly;
123*4882a593Smuzhiyun
ipip_err(struct sk_buff * skb,u32 info)124*4882a593Smuzhiyun static int ipip_err(struct sk_buff *skb, u32 info)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun /* All the routers (except for Linux) return only
127*4882a593Smuzhiyun * 8 bytes of packet payload. It means, that precise relaying of
128*4882a593Smuzhiyun * ICMP in the real Internet is absolutely infeasible.
129*4882a593Smuzhiyun */
130*4882a593Smuzhiyun struct net *net = dev_net(skb->dev);
131*4882a593Smuzhiyun struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
132*4882a593Smuzhiyun const struct iphdr *iph = (const struct iphdr *)skb->data;
133*4882a593Smuzhiyun const int type = icmp_hdr(skb)->type;
134*4882a593Smuzhiyun const int code = icmp_hdr(skb)->code;
135*4882a593Smuzhiyun struct ip_tunnel *t;
136*4882a593Smuzhiyun int err = 0;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
139*4882a593Smuzhiyun iph->daddr, iph->saddr, 0);
140*4882a593Smuzhiyun if (!t) {
141*4882a593Smuzhiyun err = -ENOENT;
142*4882a593Smuzhiyun goto out;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun switch (type) {
146*4882a593Smuzhiyun case ICMP_DEST_UNREACH:
147*4882a593Smuzhiyun switch (code) {
148*4882a593Smuzhiyun case ICMP_SR_FAILED:
149*4882a593Smuzhiyun /* Impossible event. */
150*4882a593Smuzhiyun goto out;
151*4882a593Smuzhiyun default:
152*4882a593Smuzhiyun /* All others are translated to HOST_UNREACH.
153*4882a593Smuzhiyun * rfc2003 contains "deep thoughts" about NET_UNREACH,
154*4882a593Smuzhiyun * I believe they are just ether pollution. --ANK
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun break;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun break;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun case ICMP_TIME_EXCEEDED:
161*4882a593Smuzhiyun if (code != ICMP_EXC_TTL)
162*4882a593Smuzhiyun goto out;
163*4882a593Smuzhiyun break;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun case ICMP_REDIRECT:
166*4882a593Smuzhiyun break;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun default:
169*4882a593Smuzhiyun goto out;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
173*4882a593Smuzhiyun ipv4_update_pmtu(skb, net, info, t->parms.link, iph->protocol);
174*4882a593Smuzhiyun goto out;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun if (type == ICMP_REDIRECT) {
178*4882a593Smuzhiyun ipv4_redirect(skb, net, t->parms.link, iph->protocol);
179*4882a593Smuzhiyun goto out;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (t->parms.iph.daddr == 0) {
183*4882a593Smuzhiyun err = -ENOENT;
184*4882a593Smuzhiyun goto out;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
188*4882a593Smuzhiyun goto out;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
191*4882a593Smuzhiyun t->err_count++;
192*4882a593Smuzhiyun else
193*4882a593Smuzhiyun t->err_count = 1;
194*4882a593Smuzhiyun t->err_time = jiffies;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun out:
197*4882a593Smuzhiyun return err;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun static const struct tnl_ptk_info ipip_tpi = {
201*4882a593Smuzhiyun /* no tunnel info required for ipip. */
202*4882a593Smuzhiyun .proto = htons(ETH_P_IP),
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
206*4882a593Smuzhiyun static const struct tnl_ptk_info mplsip_tpi = {
207*4882a593Smuzhiyun /* no tunnel info required for mplsip. */
208*4882a593Smuzhiyun .proto = htons(ETH_P_MPLS_UC),
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun #endif
211*4882a593Smuzhiyun
ipip_tunnel_rcv(struct sk_buff * skb,u8 ipproto)212*4882a593Smuzhiyun static int ipip_tunnel_rcv(struct sk_buff *skb, u8 ipproto)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun struct net *net = dev_net(skb->dev);
215*4882a593Smuzhiyun struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
216*4882a593Smuzhiyun struct metadata_dst *tun_dst = NULL;
217*4882a593Smuzhiyun struct ip_tunnel *tunnel;
218*4882a593Smuzhiyun const struct iphdr *iph;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun iph = ip_hdr(skb);
221*4882a593Smuzhiyun tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
222*4882a593Smuzhiyun iph->saddr, iph->daddr, 0);
223*4882a593Smuzhiyun if (tunnel) {
224*4882a593Smuzhiyun const struct tnl_ptk_info *tpi;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun if (tunnel->parms.iph.protocol != ipproto &&
227*4882a593Smuzhiyun tunnel->parms.iph.protocol != 0)
228*4882a593Smuzhiyun goto drop;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
231*4882a593Smuzhiyun goto drop;
232*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
233*4882a593Smuzhiyun if (ipproto == IPPROTO_MPLS)
234*4882a593Smuzhiyun tpi = &mplsip_tpi;
235*4882a593Smuzhiyun else
236*4882a593Smuzhiyun #endif
237*4882a593Smuzhiyun tpi = &ipip_tpi;
238*4882a593Smuzhiyun if (iptunnel_pull_header(skb, 0, tpi->proto, false))
239*4882a593Smuzhiyun goto drop;
240*4882a593Smuzhiyun if (tunnel->collect_md) {
241*4882a593Smuzhiyun tun_dst = ip_tun_rx_dst(skb, 0, 0, 0);
242*4882a593Smuzhiyun if (!tun_dst)
243*4882a593Smuzhiyun return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun return ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun return -1;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun drop:
251*4882a593Smuzhiyun kfree_skb(skb);
252*4882a593Smuzhiyun return 0;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
ipip_rcv(struct sk_buff * skb)255*4882a593Smuzhiyun static int ipip_rcv(struct sk_buff *skb)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun return ipip_tunnel_rcv(skb, IPPROTO_IPIP);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
mplsip_rcv(struct sk_buff * skb)261*4882a593Smuzhiyun static int mplsip_rcv(struct sk_buff *skb)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun return ipip_tunnel_rcv(skb, IPPROTO_MPLS);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun #endif
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /*
268*4882a593Smuzhiyun * This function assumes it is being called from dev_queue_xmit()
269*4882a593Smuzhiyun * and that skb is filled properly by that function.
270*4882a593Smuzhiyun */
ipip_tunnel_xmit(struct sk_buff * skb,struct net_device * dev)271*4882a593Smuzhiyun static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb,
272*4882a593Smuzhiyun struct net_device *dev)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun struct ip_tunnel *tunnel = netdev_priv(dev);
275*4882a593Smuzhiyun const struct iphdr *tiph = &tunnel->parms.iph;
276*4882a593Smuzhiyun u8 ipproto;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun if (!pskb_inet_may_pull(skb))
279*4882a593Smuzhiyun goto tx_error;
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun switch (skb->protocol) {
282*4882a593Smuzhiyun case htons(ETH_P_IP):
283*4882a593Smuzhiyun ipproto = IPPROTO_IPIP;
284*4882a593Smuzhiyun break;
285*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
286*4882a593Smuzhiyun case htons(ETH_P_MPLS_UC):
287*4882a593Smuzhiyun ipproto = IPPROTO_MPLS;
288*4882a593Smuzhiyun break;
289*4882a593Smuzhiyun #endif
290*4882a593Smuzhiyun default:
291*4882a593Smuzhiyun goto tx_error;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun if (tiph->protocol != ipproto && tiph->protocol != 0)
295*4882a593Smuzhiyun goto tx_error;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
298*4882a593Smuzhiyun goto tx_error;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun skb_set_inner_ipproto(skb, ipproto);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun if (tunnel->collect_md)
303*4882a593Smuzhiyun ip_md_tunnel_xmit(skb, dev, ipproto, 0);
304*4882a593Smuzhiyun else
305*4882a593Smuzhiyun ip_tunnel_xmit(skb, dev, tiph, ipproto);
306*4882a593Smuzhiyun return NETDEV_TX_OK;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun tx_error:
309*4882a593Smuzhiyun kfree_skb(skb);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun dev->stats.tx_errors++;
312*4882a593Smuzhiyun return NETDEV_TX_OK;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
ipip_tunnel_ioctl_verify_protocol(u8 ipproto)315*4882a593Smuzhiyun static bool ipip_tunnel_ioctl_verify_protocol(u8 ipproto)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun switch (ipproto) {
318*4882a593Smuzhiyun case 0:
319*4882a593Smuzhiyun case IPPROTO_IPIP:
320*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
321*4882a593Smuzhiyun case IPPROTO_MPLS:
322*4882a593Smuzhiyun #endif
323*4882a593Smuzhiyun return true;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun return false;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun static int
ipip_tunnel_ctl(struct net_device * dev,struct ip_tunnel_parm * p,int cmd)330*4882a593Smuzhiyun ipip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
333*4882a593Smuzhiyun if (p->iph.version != 4 ||
334*4882a593Smuzhiyun !ipip_tunnel_ioctl_verify_protocol(p->iph.protocol) ||
335*4882a593Smuzhiyun p->iph.ihl != 5 || (p->iph.frag_off & htons(~IP_DF)))
336*4882a593Smuzhiyun return -EINVAL;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun p->i_key = p->o_key = 0;
340*4882a593Smuzhiyun p->i_flags = p->o_flags = 0;
341*4882a593Smuzhiyun return ip_tunnel_ctl(dev, p, cmd);
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun static const struct net_device_ops ipip_netdev_ops = {
345*4882a593Smuzhiyun .ndo_init = ipip_tunnel_init,
346*4882a593Smuzhiyun .ndo_uninit = ip_tunnel_uninit,
347*4882a593Smuzhiyun .ndo_start_xmit = ipip_tunnel_xmit,
348*4882a593Smuzhiyun .ndo_do_ioctl = ip_tunnel_ioctl,
349*4882a593Smuzhiyun .ndo_change_mtu = ip_tunnel_change_mtu,
350*4882a593Smuzhiyun .ndo_get_stats64 = ip_tunnel_get_stats64,
351*4882a593Smuzhiyun .ndo_get_iflink = ip_tunnel_get_iflink,
352*4882a593Smuzhiyun .ndo_tunnel_ctl = ipip_tunnel_ctl,
353*4882a593Smuzhiyun };
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun #define IPIP_FEATURES (NETIF_F_SG | \
356*4882a593Smuzhiyun NETIF_F_FRAGLIST | \
357*4882a593Smuzhiyun NETIF_F_HIGHDMA | \
358*4882a593Smuzhiyun NETIF_F_GSO_SOFTWARE | \
359*4882a593Smuzhiyun NETIF_F_HW_CSUM)
360*4882a593Smuzhiyun
ipip_tunnel_setup(struct net_device * dev)361*4882a593Smuzhiyun static void ipip_tunnel_setup(struct net_device *dev)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun dev->netdev_ops = &ipip_netdev_ops;
364*4882a593Smuzhiyun dev->header_ops = &ip_tunnel_header_ops;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun dev->type = ARPHRD_TUNNEL;
367*4882a593Smuzhiyun dev->flags = IFF_NOARP;
368*4882a593Smuzhiyun dev->addr_len = 4;
369*4882a593Smuzhiyun dev->features |= NETIF_F_LLTX;
370*4882a593Smuzhiyun netif_keep_dst(dev);
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun dev->features |= IPIP_FEATURES;
373*4882a593Smuzhiyun dev->hw_features |= IPIP_FEATURES;
374*4882a593Smuzhiyun ip_tunnel_setup(dev, ipip_net_id);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
ipip_tunnel_init(struct net_device * dev)377*4882a593Smuzhiyun static int ipip_tunnel_init(struct net_device *dev)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun struct ip_tunnel *tunnel = netdev_priv(dev);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
382*4882a593Smuzhiyun memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun tunnel->tun_hlen = 0;
385*4882a593Smuzhiyun tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
386*4882a593Smuzhiyun return ip_tunnel_init(dev);
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
ipip_tunnel_validate(struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)389*4882a593Smuzhiyun static int ipip_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
390*4882a593Smuzhiyun struct netlink_ext_ack *extack)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun u8 proto;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun if (!data || !data[IFLA_IPTUN_PROTO])
395*4882a593Smuzhiyun return 0;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
398*4882a593Smuzhiyun if (proto != IPPROTO_IPIP && proto != IPPROTO_MPLS && proto != 0)
399*4882a593Smuzhiyun return -EINVAL;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun return 0;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
ipip_netlink_parms(struct nlattr * data[],struct ip_tunnel_parm * parms,bool * collect_md,__u32 * fwmark)404*4882a593Smuzhiyun static void ipip_netlink_parms(struct nlattr *data[],
405*4882a593Smuzhiyun struct ip_tunnel_parm *parms, bool *collect_md,
406*4882a593Smuzhiyun __u32 *fwmark)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun memset(parms, 0, sizeof(*parms));
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun parms->iph.version = 4;
411*4882a593Smuzhiyun parms->iph.protocol = IPPROTO_IPIP;
412*4882a593Smuzhiyun parms->iph.ihl = 5;
413*4882a593Smuzhiyun *collect_md = false;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun if (!data)
416*4882a593Smuzhiyun return;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun if (data[IFLA_IPTUN_LINK])
419*4882a593Smuzhiyun parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (data[IFLA_IPTUN_LOCAL])
422*4882a593Smuzhiyun parms->iph.saddr = nla_get_in_addr(data[IFLA_IPTUN_LOCAL]);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun if (data[IFLA_IPTUN_REMOTE])
425*4882a593Smuzhiyun parms->iph.daddr = nla_get_in_addr(data[IFLA_IPTUN_REMOTE]);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if (data[IFLA_IPTUN_TTL]) {
428*4882a593Smuzhiyun parms->iph.ttl = nla_get_u8(data[IFLA_IPTUN_TTL]);
429*4882a593Smuzhiyun if (parms->iph.ttl)
430*4882a593Smuzhiyun parms->iph.frag_off = htons(IP_DF);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun if (data[IFLA_IPTUN_TOS])
434*4882a593Smuzhiyun parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun if (data[IFLA_IPTUN_PROTO])
437*4882a593Smuzhiyun parms->iph.protocol = nla_get_u8(data[IFLA_IPTUN_PROTO]);
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC]))
440*4882a593Smuzhiyun parms->iph.frag_off = htons(IP_DF);
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun if (data[IFLA_IPTUN_COLLECT_METADATA])
443*4882a593Smuzhiyun *collect_md = true;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun if (data[IFLA_IPTUN_FWMARK])
446*4882a593Smuzhiyun *fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun /* This function returns true when ENCAP attributes are present in the nl msg */
ipip_netlink_encap_parms(struct nlattr * data[],struct ip_tunnel_encap * ipencap)450*4882a593Smuzhiyun static bool ipip_netlink_encap_parms(struct nlattr *data[],
451*4882a593Smuzhiyun struct ip_tunnel_encap *ipencap)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun bool ret = false;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun memset(ipencap, 0, sizeof(*ipencap));
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun if (!data)
458*4882a593Smuzhiyun return ret;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun if (data[IFLA_IPTUN_ENCAP_TYPE]) {
461*4882a593Smuzhiyun ret = true;
462*4882a593Smuzhiyun ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]);
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun if (data[IFLA_IPTUN_ENCAP_FLAGS]) {
466*4882a593Smuzhiyun ret = true;
467*4882a593Smuzhiyun ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]);
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun if (data[IFLA_IPTUN_ENCAP_SPORT]) {
471*4882a593Smuzhiyun ret = true;
472*4882a593Smuzhiyun ipencap->sport = nla_get_be16(data[IFLA_IPTUN_ENCAP_SPORT]);
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun if (data[IFLA_IPTUN_ENCAP_DPORT]) {
476*4882a593Smuzhiyun ret = true;
477*4882a593Smuzhiyun ipencap->dport = nla_get_be16(data[IFLA_IPTUN_ENCAP_DPORT]);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun return ret;
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun
ipip_newlink(struct net * src_net,struct net_device * dev,struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)483*4882a593Smuzhiyun static int ipip_newlink(struct net *src_net, struct net_device *dev,
484*4882a593Smuzhiyun struct nlattr *tb[], struct nlattr *data[],
485*4882a593Smuzhiyun struct netlink_ext_ack *extack)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun struct ip_tunnel *t = netdev_priv(dev);
488*4882a593Smuzhiyun struct ip_tunnel_parm p;
489*4882a593Smuzhiyun struct ip_tunnel_encap ipencap;
490*4882a593Smuzhiyun __u32 fwmark = 0;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (ipip_netlink_encap_parms(data, &ipencap)) {
493*4882a593Smuzhiyun int err = ip_tunnel_encap_setup(t, &ipencap);
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun if (err < 0)
496*4882a593Smuzhiyun return err;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun ipip_netlink_parms(data, &p, &t->collect_md, &fwmark);
500*4882a593Smuzhiyun return ip_tunnel_newlink(dev, tb, &p, fwmark);
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
ipip_changelink(struct net_device * dev,struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)503*4882a593Smuzhiyun static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
504*4882a593Smuzhiyun struct nlattr *data[],
505*4882a593Smuzhiyun struct netlink_ext_ack *extack)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun struct ip_tunnel *t = netdev_priv(dev);
508*4882a593Smuzhiyun struct ip_tunnel_parm p;
509*4882a593Smuzhiyun struct ip_tunnel_encap ipencap;
510*4882a593Smuzhiyun bool collect_md;
511*4882a593Smuzhiyun __u32 fwmark = t->fwmark;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun if (ipip_netlink_encap_parms(data, &ipencap)) {
514*4882a593Smuzhiyun int err = ip_tunnel_encap_setup(t, &ipencap);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun if (err < 0)
517*4882a593Smuzhiyun return err;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun ipip_netlink_parms(data, &p, &collect_md, &fwmark);
521*4882a593Smuzhiyun if (collect_md)
522*4882a593Smuzhiyun return -EINVAL;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
525*4882a593Smuzhiyun (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr))
526*4882a593Smuzhiyun return -EINVAL;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun return ip_tunnel_changelink(dev, tb, &p, fwmark);
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
ipip_get_size(const struct net_device * dev)531*4882a593Smuzhiyun static size_t ipip_get_size(const struct net_device *dev)
532*4882a593Smuzhiyun {
533*4882a593Smuzhiyun return
534*4882a593Smuzhiyun /* IFLA_IPTUN_LINK */
535*4882a593Smuzhiyun nla_total_size(4) +
536*4882a593Smuzhiyun /* IFLA_IPTUN_LOCAL */
537*4882a593Smuzhiyun nla_total_size(4) +
538*4882a593Smuzhiyun /* IFLA_IPTUN_REMOTE */
539*4882a593Smuzhiyun nla_total_size(4) +
540*4882a593Smuzhiyun /* IFLA_IPTUN_TTL */
541*4882a593Smuzhiyun nla_total_size(1) +
542*4882a593Smuzhiyun /* IFLA_IPTUN_TOS */
543*4882a593Smuzhiyun nla_total_size(1) +
544*4882a593Smuzhiyun /* IFLA_IPTUN_PROTO */
545*4882a593Smuzhiyun nla_total_size(1) +
546*4882a593Smuzhiyun /* IFLA_IPTUN_PMTUDISC */
547*4882a593Smuzhiyun nla_total_size(1) +
548*4882a593Smuzhiyun /* IFLA_IPTUN_ENCAP_TYPE */
549*4882a593Smuzhiyun nla_total_size(2) +
550*4882a593Smuzhiyun /* IFLA_IPTUN_ENCAP_FLAGS */
551*4882a593Smuzhiyun nla_total_size(2) +
552*4882a593Smuzhiyun /* IFLA_IPTUN_ENCAP_SPORT */
553*4882a593Smuzhiyun nla_total_size(2) +
554*4882a593Smuzhiyun /* IFLA_IPTUN_ENCAP_DPORT */
555*4882a593Smuzhiyun nla_total_size(2) +
556*4882a593Smuzhiyun /* IFLA_IPTUN_COLLECT_METADATA */
557*4882a593Smuzhiyun nla_total_size(0) +
558*4882a593Smuzhiyun /* IFLA_IPTUN_FWMARK */
559*4882a593Smuzhiyun nla_total_size(4) +
560*4882a593Smuzhiyun 0;
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun
ipip_fill_info(struct sk_buff * skb,const struct net_device * dev)563*4882a593Smuzhiyun static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun struct ip_tunnel *tunnel = netdev_priv(dev);
566*4882a593Smuzhiyun struct ip_tunnel_parm *parm = &tunnel->parms;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
569*4882a593Smuzhiyun nla_put_in_addr(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) ||
570*4882a593Smuzhiyun nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
571*4882a593Smuzhiyun nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
572*4882a593Smuzhiyun nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
573*4882a593Smuzhiyun nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->iph.protocol) ||
574*4882a593Smuzhiyun nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
575*4882a593Smuzhiyun !!(parm->iph.frag_off & htons(IP_DF))) ||
576*4882a593Smuzhiyun nla_put_u32(skb, IFLA_IPTUN_FWMARK, tunnel->fwmark))
577*4882a593Smuzhiyun goto nla_put_failure;
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
580*4882a593Smuzhiyun tunnel->encap.type) ||
581*4882a593Smuzhiyun nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT,
582*4882a593Smuzhiyun tunnel->encap.sport) ||
583*4882a593Smuzhiyun nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT,
584*4882a593Smuzhiyun tunnel->encap.dport) ||
585*4882a593Smuzhiyun nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
586*4882a593Smuzhiyun tunnel->encap.flags))
587*4882a593Smuzhiyun goto nla_put_failure;
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun if (tunnel->collect_md)
590*4882a593Smuzhiyun if (nla_put_flag(skb, IFLA_IPTUN_COLLECT_METADATA))
591*4882a593Smuzhiyun goto nla_put_failure;
592*4882a593Smuzhiyun return 0;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun nla_put_failure:
595*4882a593Smuzhiyun return -EMSGSIZE;
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
599*4882a593Smuzhiyun [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
600*4882a593Smuzhiyun [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 },
601*4882a593Smuzhiyun [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 },
602*4882a593Smuzhiyun [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
603*4882a593Smuzhiyun [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
604*4882a593Smuzhiyun [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
605*4882a593Smuzhiyun [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
606*4882a593Smuzhiyun [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 },
607*4882a593Smuzhiyun [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
608*4882a593Smuzhiyun [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 },
609*4882a593Smuzhiyun [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
610*4882a593Smuzhiyun [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
611*4882a593Smuzhiyun [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
612*4882a593Smuzhiyun };
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun static struct rtnl_link_ops ipip_link_ops __read_mostly = {
615*4882a593Smuzhiyun .kind = "ipip",
616*4882a593Smuzhiyun .maxtype = IFLA_IPTUN_MAX,
617*4882a593Smuzhiyun .policy = ipip_policy,
618*4882a593Smuzhiyun .priv_size = sizeof(struct ip_tunnel),
619*4882a593Smuzhiyun .setup = ipip_tunnel_setup,
620*4882a593Smuzhiyun .validate = ipip_tunnel_validate,
621*4882a593Smuzhiyun .newlink = ipip_newlink,
622*4882a593Smuzhiyun .changelink = ipip_changelink,
623*4882a593Smuzhiyun .dellink = ip_tunnel_dellink,
624*4882a593Smuzhiyun .get_size = ipip_get_size,
625*4882a593Smuzhiyun .fill_info = ipip_fill_info,
626*4882a593Smuzhiyun .get_link_net = ip_tunnel_get_link_net,
627*4882a593Smuzhiyun };
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun static struct xfrm_tunnel ipip_handler __read_mostly = {
630*4882a593Smuzhiyun .handler = ipip_rcv,
631*4882a593Smuzhiyun .err_handler = ipip_err,
632*4882a593Smuzhiyun .priority = 1,
633*4882a593Smuzhiyun };
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
636*4882a593Smuzhiyun static struct xfrm_tunnel mplsip_handler __read_mostly = {
637*4882a593Smuzhiyun .handler = mplsip_rcv,
638*4882a593Smuzhiyun .err_handler = ipip_err,
639*4882a593Smuzhiyun .priority = 1,
640*4882a593Smuzhiyun };
641*4882a593Smuzhiyun #endif
642*4882a593Smuzhiyun
ipip_init_net(struct net * net)643*4882a593Smuzhiyun static int __net_init ipip_init_net(struct net *net)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0");
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
ipip_exit_batch_net(struct list_head * list_net)648*4882a593Smuzhiyun static void __net_exit ipip_exit_batch_net(struct list_head *list_net)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun ip_tunnel_delete_nets(list_net, ipip_net_id, &ipip_link_ops);
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun static struct pernet_operations ipip_net_ops = {
654*4882a593Smuzhiyun .init = ipip_init_net,
655*4882a593Smuzhiyun .exit_batch = ipip_exit_batch_net,
656*4882a593Smuzhiyun .id = &ipip_net_id,
657*4882a593Smuzhiyun .size = sizeof(struct ip_tunnel_net),
658*4882a593Smuzhiyun };
659*4882a593Smuzhiyun
ipip_init(void)660*4882a593Smuzhiyun static int __init ipip_init(void)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun int err;
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun pr_info("ipip: IPv4 and MPLS over IPv4 tunneling driver\n");
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun err = register_pernet_device(&ipip_net_ops);
667*4882a593Smuzhiyun if (err < 0)
668*4882a593Smuzhiyun return err;
669*4882a593Smuzhiyun err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
670*4882a593Smuzhiyun if (err < 0) {
671*4882a593Smuzhiyun pr_info("%s: can't register tunnel\n", __func__);
672*4882a593Smuzhiyun goto xfrm_tunnel_ipip_failed;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
675*4882a593Smuzhiyun err = xfrm4_tunnel_register(&mplsip_handler, AF_MPLS);
676*4882a593Smuzhiyun if (err < 0) {
677*4882a593Smuzhiyun pr_info("%s: can't register tunnel\n", __func__);
678*4882a593Smuzhiyun goto xfrm_tunnel_mplsip_failed;
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun #endif
681*4882a593Smuzhiyun err = rtnl_link_register(&ipip_link_ops);
682*4882a593Smuzhiyun if (err < 0)
683*4882a593Smuzhiyun goto rtnl_link_failed;
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun out:
686*4882a593Smuzhiyun return err;
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun rtnl_link_failed:
689*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
690*4882a593Smuzhiyun xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS);
691*4882a593Smuzhiyun xfrm_tunnel_mplsip_failed:
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun #endif
694*4882a593Smuzhiyun xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
695*4882a593Smuzhiyun xfrm_tunnel_ipip_failed:
696*4882a593Smuzhiyun unregister_pernet_device(&ipip_net_ops);
697*4882a593Smuzhiyun goto out;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
ipip_fini(void)700*4882a593Smuzhiyun static void __exit ipip_fini(void)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun rtnl_link_unregister(&ipip_link_ops);
703*4882a593Smuzhiyun if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
704*4882a593Smuzhiyun pr_info("%s: can't deregister tunnel\n", __func__);
705*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MPLS)
706*4882a593Smuzhiyun if (xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS))
707*4882a593Smuzhiyun pr_info("%s: can't deregister tunnel\n", __func__);
708*4882a593Smuzhiyun #endif
709*4882a593Smuzhiyun unregister_pernet_device(&ipip_net_ops);
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun module_init(ipip_init);
713*4882a593Smuzhiyun module_exit(ipip_fini);
714*4882a593Smuzhiyun MODULE_LICENSE("GPL");
715*4882a593Smuzhiyun MODULE_ALIAS_RTNL_LINK("ipip");
716*4882a593Smuzhiyun MODULE_ALIAS_NETDEV("tunl0");
717