xref: /OK3568_Linux_fs/kernel/net/ipv4/ip_vti.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *	Linux NET3: IP/IP protocol decoder modified to support
4*4882a593Smuzhiyun  *		    virtual tunnel interface
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  *	Authors:
7*4882a593Smuzhiyun  *		Saurabh Mohan (saurabh.mohan@vyatta.com) 05/07/2012
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun /*
11*4882a593Smuzhiyun    This version of net/ipv4/ip_vti.c is cloned of net/ipv4/ipip.c
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun    For comments look at net/ipv4/ip_gre.c --ANK
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <linux/capability.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/types.h>
20*4882a593Smuzhiyun #include <linux/kernel.h>
21*4882a593Smuzhiyun #include <linux/uaccess.h>
22*4882a593Smuzhiyun #include <linux/skbuff.h>
23*4882a593Smuzhiyun #include <linux/netdevice.h>
24*4882a593Smuzhiyun #include <linux/in.h>
25*4882a593Smuzhiyun #include <linux/tcp.h>
26*4882a593Smuzhiyun #include <linux/udp.h>
27*4882a593Smuzhiyun #include <linux/if_arp.h>
28*4882a593Smuzhiyun #include <linux/init.h>
29*4882a593Smuzhiyun #include <linux/netfilter_ipv4.h>
30*4882a593Smuzhiyun #include <linux/if_ether.h>
31*4882a593Smuzhiyun #include <linux/icmpv6.h>
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #include <net/sock.h>
34*4882a593Smuzhiyun #include <net/ip.h>
35*4882a593Smuzhiyun #include <net/icmp.h>
36*4882a593Smuzhiyun #include <net/ip_tunnels.h>
37*4882a593Smuzhiyun #include <net/inet_ecn.h>
38*4882a593Smuzhiyun #include <net/xfrm.h>
39*4882a593Smuzhiyun #include <net/net_namespace.h>
40*4882a593Smuzhiyun #include <net/netns/generic.h>
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static struct rtnl_link_ops vti_link_ops __read_mostly;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun static unsigned int vti_net_id __read_mostly;
45*4882a593Smuzhiyun static int vti_tunnel_init(struct net_device *dev);
46*4882a593Smuzhiyun 
vti_input(struct sk_buff * skb,int nexthdr,__be32 spi,int encap_type,bool update_skb_dev)47*4882a593Smuzhiyun static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
48*4882a593Smuzhiyun 		     int encap_type, bool update_skb_dev)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun 	struct ip_tunnel *tunnel;
51*4882a593Smuzhiyun 	const struct iphdr *iph = ip_hdr(skb);
52*4882a593Smuzhiyun 	struct net *net = dev_net(skb->dev);
53*4882a593Smuzhiyun 	struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
56*4882a593Smuzhiyun 				  iph->saddr, iph->daddr, 0);
57*4882a593Smuzhiyun 	if (tunnel) {
58*4882a593Smuzhiyun 		if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
59*4882a593Smuzhiyun 			goto drop;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 		if (update_skb_dev)
64*4882a593Smuzhiyun 			skb->dev = tunnel->dev;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 		return xfrm_input(skb, nexthdr, spi, encap_type);
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return -EINVAL;
70*4882a593Smuzhiyun drop:
71*4882a593Smuzhiyun 	kfree_skb(skb);
72*4882a593Smuzhiyun 	return 0;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
vti_input_proto(struct sk_buff * skb,int nexthdr,__be32 spi,int encap_type)75*4882a593Smuzhiyun static int vti_input_proto(struct sk_buff *skb, int nexthdr, __be32 spi,
76*4882a593Smuzhiyun 			   int encap_type)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	return vti_input(skb, nexthdr, spi, encap_type, false);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
vti_rcv(struct sk_buff * skb,__be32 spi,bool update_skb_dev)81*4882a593Smuzhiyun static int vti_rcv(struct sk_buff *skb, __be32 spi, bool update_skb_dev)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
84*4882a593Smuzhiyun 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	return vti_input(skb, ip_hdr(skb)->protocol, spi, 0, update_skb_dev);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
vti_rcv_proto(struct sk_buff * skb)89*4882a593Smuzhiyun static int vti_rcv_proto(struct sk_buff *skb)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	return vti_rcv(skb, 0, false);
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
vti_rcv_cb(struct sk_buff * skb,int err)94*4882a593Smuzhiyun static int vti_rcv_cb(struct sk_buff *skb, int err)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	unsigned short family;
97*4882a593Smuzhiyun 	struct net_device *dev;
98*4882a593Smuzhiyun 	struct xfrm_state *x;
99*4882a593Smuzhiyun 	const struct xfrm_mode *inner_mode;
100*4882a593Smuzhiyun 	struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
101*4882a593Smuzhiyun 	u32 orig_mark = skb->mark;
102*4882a593Smuzhiyun 	int ret;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	if (!tunnel)
105*4882a593Smuzhiyun 		return 1;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	dev = tunnel->dev;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	if (err) {
110*4882a593Smuzhiyun 		dev->stats.rx_errors++;
111*4882a593Smuzhiyun 		dev->stats.rx_dropped++;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 		return 0;
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	x = xfrm_input_state(skb);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	inner_mode = &x->inner_mode;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	if (x->sel.family == AF_UNSPEC) {
121*4882a593Smuzhiyun 		inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
122*4882a593Smuzhiyun 		if (inner_mode == NULL) {
123*4882a593Smuzhiyun 			XFRM_INC_STATS(dev_net(skb->dev),
124*4882a593Smuzhiyun 				       LINUX_MIB_XFRMINSTATEMODEERROR);
125*4882a593Smuzhiyun 			return -EINVAL;
126*4882a593Smuzhiyun 		}
127*4882a593Smuzhiyun 	}
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	family = inner_mode->family;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	skb->mark = be32_to_cpu(tunnel->parms.i_key);
132*4882a593Smuzhiyun 	ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
133*4882a593Smuzhiyun 	skb->mark = orig_mark;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	if (!ret)
136*4882a593Smuzhiyun 		return -EPERM;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev)));
139*4882a593Smuzhiyun 	skb->dev = dev;
140*4882a593Smuzhiyun 	dev_sw_netstats_rx_add(dev, skb->len);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	return 0;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
vti_state_check(const struct xfrm_state * x,__be32 dst,__be32 src)145*4882a593Smuzhiyun static bool vti_state_check(const struct xfrm_state *x, __be32 dst, __be32 src)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	xfrm_address_t *daddr = (xfrm_address_t *)&dst;
148*4882a593Smuzhiyun 	xfrm_address_t *saddr = (xfrm_address_t *)&src;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/* if there is no transform then this tunnel is not functional.
151*4882a593Smuzhiyun 	 * Or if the xfrm is not mode tunnel.
152*4882a593Smuzhiyun 	 */
153*4882a593Smuzhiyun 	if (!x || x->props.mode != XFRM_MODE_TUNNEL ||
154*4882a593Smuzhiyun 	    x->props.family != AF_INET)
155*4882a593Smuzhiyun 		return false;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	if (!dst)
158*4882a593Smuzhiyun 		return xfrm_addr_equal(saddr, &x->props.saddr, AF_INET);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	if (!xfrm_state_addr_check(x, daddr, saddr, AF_INET))
161*4882a593Smuzhiyun 		return false;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	return true;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
vti_xmit(struct sk_buff * skb,struct net_device * dev,struct flowi * fl)166*4882a593Smuzhiyun static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
167*4882a593Smuzhiyun 			    struct flowi *fl)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	struct ip_tunnel *tunnel = netdev_priv(dev);
170*4882a593Smuzhiyun 	struct ip_tunnel_parm *parms = &tunnel->parms;
171*4882a593Smuzhiyun 	struct dst_entry *dst = skb_dst(skb);
172*4882a593Smuzhiyun 	struct net_device *tdev;	/* Device to other host */
173*4882a593Smuzhiyun 	int pkt_len = skb->len;
174*4882a593Smuzhiyun 	int err;
175*4882a593Smuzhiyun 	int mtu;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	if (!dst) {
178*4882a593Smuzhiyun 		switch (skb->protocol) {
179*4882a593Smuzhiyun 		case htons(ETH_P_IP): {
180*4882a593Smuzhiyun 			struct rtable *rt;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 			fl->u.ip4.flowi4_oif = dev->ifindex;
183*4882a593Smuzhiyun 			fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
184*4882a593Smuzhiyun 			rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
185*4882a593Smuzhiyun 			if (IS_ERR(rt)) {
186*4882a593Smuzhiyun 				dev->stats.tx_carrier_errors++;
187*4882a593Smuzhiyun 				goto tx_error_icmp;
188*4882a593Smuzhiyun 			}
189*4882a593Smuzhiyun 			dst = &rt->dst;
190*4882a593Smuzhiyun 			skb_dst_set(skb, dst);
191*4882a593Smuzhiyun 			break;
192*4882a593Smuzhiyun 		}
193*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
194*4882a593Smuzhiyun 		case htons(ETH_P_IPV6):
195*4882a593Smuzhiyun 			fl->u.ip6.flowi6_oif = dev->ifindex;
196*4882a593Smuzhiyun 			fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
197*4882a593Smuzhiyun 			dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
198*4882a593Smuzhiyun 			if (dst->error) {
199*4882a593Smuzhiyun 				dst_release(dst);
200*4882a593Smuzhiyun 				dst = NULL;
201*4882a593Smuzhiyun 				dev->stats.tx_carrier_errors++;
202*4882a593Smuzhiyun 				goto tx_error_icmp;
203*4882a593Smuzhiyun 			}
204*4882a593Smuzhiyun 			skb_dst_set(skb, dst);
205*4882a593Smuzhiyun 			break;
206*4882a593Smuzhiyun #endif
207*4882a593Smuzhiyun 		default:
208*4882a593Smuzhiyun 			dev->stats.tx_carrier_errors++;
209*4882a593Smuzhiyun 			goto tx_error_icmp;
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	dst_hold(dst);
214*4882a593Smuzhiyun 	dst = xfrm_lookup_route(tunnel->net, dst, fl, NULL, 0);
215*4882a593Smuzhiyun 	if (IS_ERR(dst)) {
216*4882a593Smuzhiyun 		dev->stats.tx_carrier_errors++;
217*4882a593Smuzhiyun 		goto tx_error_icmp;
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (dst->flags & DST_XFRM_QUEUE)
221*4882a593Smuzhiyun 		goto queued;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	if (!vti_state_check(dst->xfrm, parms->iph.daddr, parms->iph.saddr)) {
224*4882a593Smuzhiyun 		dev->stats.tx_carrier_errors++;
225*4882a593Smuzhiyun 		dst_release(dst);
226*4882a593Smuzhiyun 		goto tx_error_icmp;
227*4882a593Smuzhiyun 	}
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	tdev = dst->dev;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	if (tdev == dev) {
232*4882a593Smuzhiyun 		dst_release(dst);
233*4882a593Smuzhiyun 		dev->stats.collisions++;
234*4882a593Smuzhiyun 		goto tx_error;
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	mtu = dst_mtu(dst);
238*4882a593Smuzhiyun 	if (skb->len > mtu) {
239*4882a593Smuzhiyun 		skb_dst_update_pmtu_no_confirm(skb, mtu);
240*4882a593Smuzhiyun 		if (skb->protocol == htons(ETH_P_IP)) {
241*4882a593Smuzhiyun 			icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
242*4882a593Smuzhiyun 				      htonl(mtu));
243*4882a593Smuzhiyun 		} else {
244*4882a593Smuzhiyun 			if (mtu < IPV6_MIN_MTU)
245*4882a593Smuzhiyun 				mtu = IPV6_MIN_MTU;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 			icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
248*4882a593Smuzhiyun 		}
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 		dst_release(dst);
251*4882a593Smuzhiyun 		goto tx_error;
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun queued:
255*4882a593Smuzhiyun 	skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
256*4882a593Smuzhiyun 	skb_dst_set(skb, dst);
257*4882a593Smuzhiyun 	skb->dev = skb_dst(skb)->dev;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	err = dst_output(tunnel->net, skb->sk, skb);
260*4882a593Smuzhiyun 	if (net_xmit_eval(err) == 0)
261*4882a593Smuzhiyun 		err = pkt_len;
262*4882a593Smuzhiyun 	iptunnel_xmit_stats(dev, err);
263*4882a593Smuzhiyun 	return NETDEV_TX_OK;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun tx_error_icmp:
266*4882a593Smuzhiyun 	dst_link_failure(skb);
267*4882a593Smuzhiyun tx_error:
268*4882a593Smuzhiyun 	dev->stats.tx_errors++;
269*4882a593Smuzhiyun 	kfree_skb(skb);
270*4882a593Smuzhiyun 	return NETDEV_TX_OK;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun /* This function assumes it is being called from dev_queue_xmit()
274*4882a593Smuzhiyun  * and that skb is filled properly by that function.
275*4882a593Smuzhiyun  */
vti_tunnel_xmit(struct sk_buff * skb,struct net_device * dev)276*4882a593Smuzhiyun static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun 	struct ip_tunnel *tunnel = netdev_priv(dev);
279*4882a593Smuzhiyun 	struct flowi fl;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	if (!pskb_inet_may_pull(skb))
282*4882a593Smuzhiyun 		goto tx_err;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	memset(&fl, 0, sizeof(fl));
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	switch (skb->protocol) {
287*4882a593Smuzhiyun 	case htons(ETH_P_IP):
288*4882a593Smuzhiyun 		xfrm_decode_session(skb, &fl, AF_INET);
289*4882a593Smuzhiyun 		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
290*4882a593Smuzhiyun 		break;
291*4882a593Smuzhiyun 	case htons(ETH_P_IPV6):
292*4882a593Smuzhiyun 		xfrm_decode_session(skb, &fl, AF_INET6);
293*4882a593Smuzhiyun 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
294*4882a593Smuzhiyun 		break;
295*4882a593Smuzhiyun 	default:
296*4882a593Smuzhiyun 		goto tx_err;
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	/* override mark with tunnel output key */
300*4882a593Smuzhiyun 	fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	return vti_xmit(skb, dev, &fl);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun tx_err:
305*4882a593Smuzhiyun 	dev->stats.tx_errors++;
306*4882a593Smuzhiyun 	kfree_skb(skb);
307*4882a593Smuzhiyun 	return NETDEV_TX_OK;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
vti4_err(struct sk_buff * skb,u32 info)310*4882a593Smuzhiyun static int vti4_err(struct sk_buff *skb, u32 info)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	__be32 spi;
313*4882a593Smuzhiyun 	__u32 mark;
314*4882a593Smuzhiyun 	struct xfrm_state *x;
315*4882a593Smuzhiyun 	struct ip_tunnel *tunnel;
316*4882a593Smuzhiyun 	struct ip_esp_hdr *esph;
317*4882a593Smuzhiyun 	struct ip_auth_hdr *ah ;
318*4882a593Smuzhiyun 	struct ip_comp_hdr *ipch;
319*4882a593Smuzhiyun 	struct net *net = dev_net(skb->dev);
320*4882a593Smuzhiyun 	const struct iphdr *iph = (const struct iphdr *)skb->data;
321*4882a593Smuzhiyun 	int protocol = iph->protocol;
322*4882a593Smuzhiyun 	struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
325*4882a593Smuzhiyun 				  iph->daddr, iph->saddr, 0);
326*4882a593Smuzhiyun 	if (!tunnel)
327*4882a593Smuzhiyun 		return -1;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	mark = be32_to_cpu(tunnel->parms.o_key);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	switch (protocol) {
332*4882a593Smuzhiyun 	case IPPROTO_ESP:
333*4882a593Smuzhiyun 		esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
334*4882a593Smuzhiyun 		spi = esph->spi;
335*4882a593Smuzhiyun 		break;
336*4882a593Smuzhiyun 	case IPPROTO_AH:
337*4882a593Smuzhiyun 		ah = (struct ip_auth_hdr *)(skb->data+(iph->ihl<<2));
338*4882a593Smuzhiyun 		spi = ah->spi;
339*4882a593Smuzhiyun 		break;
340*4882a593Smuzhiyun 	case IPPROTO_COMP:
341*4882a593Smuzhiyun 		ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
342*4882a593Smuzhiyun 		spi = htonl(ntohs(ipch->cpi));
343*4882a593Smuzhiyun 		break;
344*4882a593Smuzhiyun 	default:
345*4882a593Smuzhiyun 		return 0;
346*4882a593Smuzhiyun 	}
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	switch (icmp_hdr(skb)->type) {
349*4882a593Smuzhiyun 	case ICMP_DEST_UNREACH:
350*4882a593Smuzhiyun 		if (icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
351*4882a593Smuzhiyun 			return 0;
352*4882a593Smuzhiyun 	case ICMP_REDIRECT:
353*4882a593Smuzhiyun 		break;
354*4882a593Smuzhiyun 	default:
355*4882a593Smuzhiyun 		return 0;
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr,
359*4882a593Smuzhiyun 			      spi, protocol, AF_INET);
360*4882a593Smuzhiyun 	if (!x)
361*4882a593Smuzhiyun 		return 0;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
364*4882a593Smuzhiyun 		ipv4_update_pmtu(skb, net, info, 0, protocol);
365*4882a593Smuzhiyun 	else
366*4882a593Smuzhiyun 		ipv4_redirect(skb, net, 0, protocol);
367*4882a593Smuzhiyun 	xfrm_state_put(x);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	return 0;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun static int
vti_tunnel_ctl(struct net_device * dev,struct ip_tunnel_parm * p,int cmd)373*4882a593Smuzhiyun vti_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun 	int err = 0;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
378*4882a593Smuzhiyun 		if (p->iph.version != 4 || p->iph.protocol != IPPROTO_IPIP ||
379*4882a593Smuzhiyun 		    p->iph.ihl != 5)
380*4882a593Smuzhiyun 			return -EINVAL;
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	if (!(p->i_flags & GRE_KEY))
384*4882a593Smuzhiyun 		p->i_key = 0;
385*4882a593Smuzhiyun 	if (!(p->o_flags & GRE_KEY))
386*4882a593Smuzhiyun 		p->o_key = 0;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	p->i_flags = VTI_ISVTI;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	err = ip_tunnel_ctl(dev, p, cmd);
391*4882a593Smuzhiyun 	if (err)
392*4882a593Smuzhiyun 		return err;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	if (cmd != SIOCDELTUNNEL) {
395*4882a593Smuzhiyun 		p->i_flags |= GRE_KEY;
396*4882a593Smuzhiyun 		p->o_flags |= GRE_KEY;
397*4882a593Smuzhiyun 	}
398*4882a593Smuzhiyun 	return 0;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun static const struct net_device_ops vti_netdev_ops = {
402*4882a593Smuzhiyun 	.ndo_init	= vti_tunnel_init,
403*4882a593Smuzhiyun 	.ndo_uninit	= ip_tunnel_uninit,
404*4882a593Smuzhiyun 	.ndo_start_xmit	= vti_tunnel_xmit,
405*4882a593Smuzhiyun 	.ndo_do_ioctl	= ip_tunnel_ioctl,
406*4882a593Smuzhiyun 	.ndo_change_mtu	= ip_tunnel_change_mtu,
407*4882a593Smuzhiyun 	.ndo_get_stats64 = ip_tunnel_get_stats64,
408*4882a593Smuzhiyun 	.ndo_get_iflink = ip_tunnel_get_iflink,
409*4882a593Smuzhiyun 	.ndo_tunnel_ctl	= vti_tunnel_ctl,
410*4882a593Smuzhiyun };
411*4882a593Smuzhiyun 
vti_tunnel_setup(struct net_device * dev)412*4882a593Smuzhiyun static void vti_tunnel_setup(struct net_device *dev)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	dev->netdev_ops		= &vti_netdev_ops;
415*4882a593Smuzhiyun 	dev->header_ops		= &ip_tunnel_header_ops;
416*4882a593Smuzhiyun 	dev->type		= ARPHRD_TUNNEL;
417*4882a593Smuzhiyun 	ip_tunnel_setup(dev, vti_net_id);
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun 
vti_tunnel_init(struct net_device * dev)420*4882a593Smuzhiyun static int vti_tunnel_init(struct net_device *dev)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	struct ip_tunnel *tunnel = netdev_priv(dev);
423*4882a593Smuzhiyun 	struct iphdr *iph = &tunnel->parms.iph;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	memcpy(dev->dev_addr, &iph->saddr, 4);
426*4882a593Smuzhiyun 	memcpy(dev->broadcast, &iph->daddr, 4);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	dev->flags		= IFF_NOARP;
429*4882a593Smuzhiyun 	dev->addr_len		= 4;
430*4882a593Smuzhiyun 	dev->features		|= NETIF_F_LLTX;
431*4882a593Smuzhiyun 	netif_keep_dst(dev);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	return ip_tunnel_init(dev);
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun 
vti_fb_tunnel_init(struct net_device * dev)436*4882a593Smuzhiyun static void __net_init vti_fb_tunnel_init(struct net_device *dev)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun 	struct ip_tunnel *tunnel = netdev_priv(dev);
439*4882a593Smuzhiyun 	struct iphdr *iph = &tunnel->parms.iph;
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	iph->version		= 4;
442*4882a593Smuzhiyun 	iph->protocol		= IPPROTO_IPIP;
443*4882a593Smuzhiyun 	iph->ihl		= 5;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun static struct xfrm4_protocol vti_esp4_protocol __read_mostly = {
447*4882a593Smuzhiyun 	.handler	=	vti_rcv_proto,
448*4882a593Smuzhiyun 	.input_handler	=	vti_input_proto,
449*4882a593Smuzhiyun 	.cb_handler	=	vti_rcv_cb,
450*4882a593Smuzhiyun 	.err_handler	=	vti4_err,
451*4882a593Smuzhiyun 	.priority	=	100,
452*4882a593Smuzhiyun };
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun static struct xfrm4_protocol vti_ah4_protocol __read_mostly = {
455*4882a593Smuzhiyun 	.handler	=	vti_rcv_proto,
456*4882a593Smuzhiyun 	.input_handler	=	vti_input_proto,
457*4882a593Smuzhiyun 	.cb_handler	=	vti_rcv_cb,
458*4882a593Smuzhiyun 	.err_handler	=	vti4_err,
459*4882a593Smuzhiyun 	.priority	=	100,
460*4882a593Smuzhiyun };
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = {
463*4882a593Smuzhiyun 	.handler	=	vti_rcv_proto,
464*4882a593Smuzhiyun 	.input_handler	=	vti_input_proto,
465*4882a593Smuzhiyun 	.cb_handler	=	vti_rcv_cb,
466*4882a593Smuzhiyun 	.err_handler	=	vti4_err,
467*4882a593Smuzhiyun 	.priority	=	100,
468*4882a593Smuzhiyun };
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
vti_rcv_tunnel(struct sk_buff * skb)471*4882a593Smuzhiyun static int vti_rcv_tunnel(struct sk_buff *skb)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun 	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
474*4882a593Smuzhiyun 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	return vti_input(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr, 0, false);
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun static struct xfrm_tunnel vti_ipip_handler __read_mostly = {
480*4882a593Smuzhiyun 	.handler	=	vti_rcv_tunnel,
481*4882a593Smuzhiyun 	.cb_handler	=	vti_rcv_cb,
482*4882a593Smuzhiyun 	.err_handler	=	vti4_err,
483*4882a593Smuzhiyun 	.priority	=	0,
484*4882a593Smuzhiyun };
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
487*4882a593Smuzhiyun static struct xfrm_tunnel vti_ipip6_handler __read_mostly = {
488*4882a593Smuzhiyun 	.handler	=	vti_rcv_tunnel,
489*4882a593Smuzhiyun 	.cb_handler	=	vti_rcv_cb,
490*4882a593Smuzhiyun 	.err_handler	=	vti4_err,
491*4882a593Smuzhiyun 	.priority	=	0,
492*4882a593Smuzhiyun };
493*4882a593Smuzhiyun #endif
494*4882a593Smuzhiyun #endif
495*4882a593Smuzhiyun 
vti_init_net(struct net * net)496*4882a593Smuzhiyun static int __net_init vti_init_net(struct net *net)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	int err;
499*4882a593Smuzhiyun 	struct ip_tunnel_net *itn;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	err = ip_tunnel_init_net(net, vti_net_id, &vti_link_ops, "ip_vti0");
502*4882a593Smuzhiyun 	if (err)
503*4882a593Smuzhiyun 		return err;
504*4882a593Smuzhiyun 	itn = net_generic(net, vti_net_id);
505*4882a593Smuzhiyun 	if (itn->fb_tunnel_dev)
506*4882a593Smuzhiyun 		vti_fb_tunnel_init(itn->fb_tunnel_dev);
507*4882a593Smuzhiyun 	return 0;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun 
vti_exit_batch_net(struct list_head * list_net)510*4882a593Smuzhiyun static void __net_exit vti_exit_batch_net(struct list_head *list_net)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun 	ip_tunnel_delete_nets(list_net, vti_net_id, &vti_link_ops);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun static struct pernet_operations vti_net_ops = {
516*4882a593Smuzhiyun 	.init = vti_init_net,
517*4882a593Smuzhiyun 	.exit_batch = vti_exit_batch_net,
518*4882a593Smuzhiyun 	.id   = &vti_net_id,
519*4882a593Smuzhiyun 	.size = sizeof(struct ip_tunnel_net),
520*4882a593Smuzhiyun };
521*4882a593Smuzhiyun 
vti_tunnel_validate(struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)522*4882a593Smuzhiyun static int vti_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
523*4882a593Smuzhiyun 			       struct netlink_ext_ack *extack)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	return 0;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun 
vti_netlink_parms(struct nlattr * data[],struct ip_tunnel_parm * parms,__u32 * fwmark)528*4882a593Smuzhiyun static void vti_netlink_parms(struct nlattr *data[],
529*4882a593Smuzhiyun 			      struct ip_tunnel_parm *parms,
530*4882a593Smuzhiyun 			      __u32 *fwmark)
531*4882a593Smuzhiyun {
532*4882a593Smuzhiyun 	memset(parms, 0, sizeof(*parms));
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	parms->iph.protocol = IPPROTO_IPIP;
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	if (!data)
537*4882a593Smuzhiyun 		return;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	parms->i_flags = VTI_ISVTI;
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	if (data[IFLA_VTI_LINK])
542*4882a593Smuzhiyun 		parms->link = nla_get_u32(data[IFLA_VTI_LINK]);
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	if (data[IFLA_VTI_IKEY])
545*4882a593Smuzhiyun 		parms->i_key = nla_get_be32(data[IFLA_VTI_IKEY]);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	if (data[IFLA_VTI_OKEY])
548*4882a593Smuzhiyun 		parms->o_key = nla_get_be32(data[IFLA_VTI_OKEY]);
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	if (data[IFLA_VTI_LOCAL])
551*4882a593Smuzhiyun 		parms->iph.saddr = nla_get_in_addr(data[IFLA_VTI_LOCAL]);
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	if (data[IFLA_VTI_REMOTE])
554*4882a593Smuzhiyun 		parms->iph.daddr = nla_get_in_addr(data[IFLA_VTI_REMOTE]);
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	if (data[IFLA_VTI_FWMARK])
557*4882a593Smuzhiyun 		*fwmark = nla_get_u32(data[IFLA_VTI_FWMARK]);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
vti_newlink(struct net * src_net,struct net_device * dev,struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)560*4882a593Smuzhiyun static int vti_newlink(struct net *src_net, struct net_device *dev,
561*4882a593Smuzhiyun 		       struct nlattr *tb[], struct nlattr *data[],
562*4882a593Smuzhiyun 		       struct netlink_ext_ack *extack)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun 	struct ip_tunnel_parm parms;
565*4882a593Smuzhiyun 	__u32 fwmark = 0;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	vti_netlink_parms(data, &parms, &fwmark);
568*4882a593Smuzhiyun 	return ip_tunnel_newlink(dev, tb, &parms, fwmark);
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun 
vti_changelink(struct net_device * dev,struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)571*4882a593Smuzhiyun static int vti_changelink(struct net_device *dev, struct nlattr *tb[],
572*4882a593Smuzhiyun 			  struct nlattr *data[],
573*4882a593Smuzhiyun 			  struct netlink_ext_ack *extack)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	struct ip_tunnel *t = netdev_priv(dev);
576*4882a593Smuzhiyun 	__u32 fwmark = t->fwmark;
577*4882a593Smuzhiyun 	struct ip_tunnel_parm p;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	vti_netlink_parms(data, &p, &fwmark);
580*4882a593Smuzhiyun 	return ip_tunnel_changelink(dev, tb, &p, fwmark);
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
vti_get_size(const struct net_device * dev)583*4882a593Smuzhiyun static size_t vti_get_size(const struct net_device *dev)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	return
586*4882a593Smuzhiyun 		/* IFLA_VTI_LINK */
587*4882a593Smuzhiyun 		nla_total_size(4) +
588*4882a593Smuzhiyun 		/* IFLA_VTI_IKEY */
589*4882a593Smuzhiyun 		nla_total_size(4) +
590*4882a593Smuzhiyun 		/* IFLA_VTI_OKEY */
591*4882a593Smuzhiyun 		nla_total_size(4) +
592*4882a593Smuzhiyun 		/* IFLA_VTI_LOCAL */
593*4882a593Smuzhiyun 		nla_total_size(4) +
594*4882a593Smuzhiyun 		/* IFLA_VTI_REMOTE */
595*4882a593Smuzhiyun 		nla_total_size(4) +
596*4882a593Smuzhiyun 		/* IFLA_VTI_FWMARK */
597*4882a593Smuzhiyun 		nla_total_size(4) +
598*4882a593Smuzhiyun 		0;
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun 
vti_fill_info(struct sk_buff * skb,const struct net_device * dev)601*4882a593Smuzhiyun static int vti_fill_info(struct sk_buff *skb, const struct net_device *dev)
602*4882a593Smuzhiyun {
603*4882a593Smuzhiyun 	struct ip_tunnel *t = netdev_priv(dev);
604*4882a593Smuzhiyun 	struct ip_tunnel_parm *p = &t->parms;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	if (nla_put_u32(skb, IFLA_VTI_LINK, p->link) ||
607*4882a593Smuzhiyun 	    nla_put_be32(skb, IFLA_VTI_IKEY, p->i_key) ||
608*4882a593Smuzhiyun 	    nla_put_be32(skb, IFLA_VTI_OKEY, p->o_key) ||
609*4882a593Smuzhiyun 	    nla_put_in_addr(skb, IFLA_VTI_LOCAL, p->iph.saddr) ||
610*4882a593Smuzhiyun 	    nla_put_in_addr(skb, IFLA_VTI_REMOTE, p->iph.daddr) ||
611*4882a593Smuzhiyun 	    nla_put_u32(skb, IFLA_VTI_FWMARK, t->fwmark))
612*4882a593Smuzhiyun 		return -EMSGSIZE;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	return 0;
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun static const struct nla_policy vti_policy[IFLA_VTI_MAX + 1] = {
618*4882a593Smuzhiyun 	[IFLA_VTI_LINK]		= { .type = NLA_U32 },
619*4882a593Smuzhiyun 	[IFLA_VTI_IKEY]		= { .type = NLA_U32 },
620*4882a593Smuzhiyun 	[IFLA_VTI_OKEY]		= { .type = NLA_U32 },
621*4882a593Smuzhiyun 	[IFLA_VTI_LOCAL]	= { .len = sizeof_field(struct iphdr, saddr) },
622*4882a593Smuzhiyun 	[IFLA_VTI_REMOTE]	= { .len = sizeof_field(struct iphdr, daddr) },
623*4882a593Smuzhiyun 	[IFLA_VTI_FWMARK]	= { .type = NLA_U32 },
624*4882a593Smuzhiyun };
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun static struct rtnl_link_ops vti_link_ops __read_mostly = {
627*4882a593Smuzhiyun 	.kind		= "vti",
628*4882a593Smuzhiyun 	.maxtype	= IFLA_VTI_MAX,
629*4882a593Smuzhiyun 	.policy		= vti_policy,
630*4882a593Smuzhiyun 	.priv_size	= sizeof(struct ip_tunnel),
631*4882a593Smuzhiyun 	.setup		= vti_tunnel_setup,
632*4882a593Smuzhiyun 	.validate	= vti_tunnel_validate,
633*4882a593Smuzhiyun 	.newlink	= vti_newlink,
634*4882a593Smuzhiyun 	.changelink	= vti_changelink,
635*4882a593Smuzhiyun 	.dellink        = ip_tunnel_dellink,
636*4882a593Smuzhiyun 	.get_size	= vti_get_size,
637*4882a593Smuzhiyun 	.fill_info	= vti_fill_info,
638*4882a593Smuzhiyun 	.get_link_net	= ip_tunnel_get_link_net,
639*4882a593Smuzhiyun };
640*4882a593Smuzhiyun 
vti_init(void)641*4882a593Smuzhiyun static int __init vti_init(void)
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun 	const char *msg;
644*4882a593Smuzhiyun 	int err;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	pr_info("IPv4 over IPsec tunneling driver\n");
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	msg = "tunnel device";
649*4882a593Smuzhiyun 	err = register_pernet_device(&vti_net_ops);
650*4882a593Smuzhiyun 	if (err < 0)
651*4882a593Smuzhiyun 		goto pernet_dev_failed;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	msg = "tunnel protocols";
654*4882a593Smuzhiyun 	err = xfrm4_protocol_register(&vti_esp4_protocol, IPPROTO_ESP);
655*4882a593Smuzhiyun 	if (err < 0)
656*4882a593Smuzhiyun 		goto xfrm_proto_esp_failed;
657*4882a593Smuzhiyun 	err = xfrm4_protocol_register(&vti_ah4_protocol, IPPROTO_AH);
658*4882a593Smuzhiyun 	if (err < 0)
659*4882a593Smuzhiyun 		goto xfrm_proto_ah_failed;
660*4882a593Smuzhiyun 	err = xfrm4_protocol_register(&vti_ipcomp4_protocol, IPPROTO_COMP);
661*4882a593Smuzhiyun 	if (err < 0)
662*4882a593Smuzhiyun 		goto xfrm_proto_comp_failed;
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
665*4882a593Smuzhiyun 	msg = "ipip tunnel";
666*4882a593Smuzhiyun 	err = xfrm4_tunnel_register(&vti_ipip_handler, AF_INET);
667*4882a593Smuzhiyun 	if (err < 0)
668*4882a593Smuzhiyun 		goto xfrm_tunnel_ipip_failed;
669*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
670*4882a593Smuzhiyun 	err = xfrm4_tunnel_register(&vti_ipip6_handler, AF_INET6);
671*4882a593Smuzhiyun 	if (err < 0)
672*4882a593Smuzhiyun 		goto xfrm_tunnel_ipip6_failed;
673*4882a593Smuzhiyun #endif
674*4882a593Smuzhiyun #endif
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 	msg = "netlink interface";
677*4882a593Smuzhiyun 	err = rtnl_link_register(&vti_link_ops);
678*4882a593Smuzhiyun 	if (err < 0)
679*4882a593Smuzhiyun 		goto rtnl_link_failed;
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	return err;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun rtnl_link_failed:
684*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
685*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
686*4882a593Smuzhiyun 	xfrm4_tunnel_deregister(&vti_ipip6_handler, AF_INET6);
687*4882a593Smuzhiyun xfrm_tunnel_ipip6_failed:
688*4882a593Smuzhiyun #endif
689*4882a593Smuzhiyun 	xfrm4_tunnel_deregister(&vti_ipip_handler, AF_INET);
690*4882a593Smuzhiyun xfrm_tunnel_ipip_failed:
691*4882a593Smuzhiyun #endif
692*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
693*4882a593Smuzhiyun xfrm_proto_comp_failed:
694*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
695*4882a593Smuzhiyun xfrm_proto_ah_failed:
696*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
697*4882a593Smuzhiyun xfrm_proto_esp_failed:
698*4882a593Smuzhiyun 	unregister_pernet_device(&vti_net_ops);
699*4882a593Smuzhiyun pernet_dev_failed:
700*4882a593Smuzhiyun 	pr_err("vti init: failed to register %s\n", msg);
701*4882a593Smuzhiyun 	return err;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
vti_fini(void)704*4882a593Smuzhiyun static void __exit vti_fini(void)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	rtnl_link_unregister(&vti_link_ops);
707*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
708*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
709*4882a593Smuzhiyun 	xfrm4_tunnel_deregister(&vti_ipip6_handler, AF_INET6);
710*4882a593Smuzhiyun #endif
711*4882a593Smuzhiyun 	xfrm4_tunnel_deregister(&vti_ipip_handler, AF_INET);
712*4882a593Smuzhiyun #endif
713*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
714*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
715*4882a593Smuzhiyun 	xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
716*4882a593Smuzhiyun 	unregister_pernet_device(&vti_net_ops);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun module_init(vti_init);
720*4882a593Smuzhiyun module_exit(vti_fini);
721*4882a593Smuzhiyun MODULE_LICENSE("GPL");
722*4882a593Smuzhiyun MODULE_ALIAS_RTNL_LINK("vti");
723*4882a593Smuzhiyun MODULE_ALIAS_NETDEV("ip_vti0");
724