xref: /linux/net/ipv4/ip_gre.c (revision 9f57c67c379d88a10e8ad676426fee5ae7341b14)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *	Linux NET3:	GRE over IP protocol decoder.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *	Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru)
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *	This program is free software; you can redistribute it and/or
71da177e4SLinus Torvalds  *	modify it under the terms of the GNU General Public License
81da177e4SLinus Torvalds  *	as published by the Free Software Foundation; either version
91da177e4SLinus Torvalds  *	2 of the License, or (at your option) any later version.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  */
121da177e4SLinus Torvalds 
13afd46503SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14afd46503SJoe Perches 
154fc268d2SRandy Dunlap #include <linux/capability.h>
161da177e4SLinus Torvalds #include <linux/module.h>
171da177e4SLinus Torvalds #include <linux/types.h>
181da177e4SLinus Torvalds #include <linux/kernel.h>
195a0e3ad6STejun Heo #include <linux/slab.h>
201da177e4SLinus Torvalds #include <asm/uaccess.h>
211da177e4SLinus Torvalds #include <linux/skbuff.h>
221da177e4SLinus Torvalds #include <linux/netdevice.h>
231da177e4SLinus Torvalds #include <linux/in.h>
241da177e4SLinus Torvalds #include <linux/tcp.h>
251da177e4SLinus Torvalds #include <linux/udp.h>
261da177e4SLinus Torvalds #include <linux/if_arp.h>
271da177e4SLinus Torvalds #include <linux/mroute.h>
282e15ea39SPravin B Shelar #include <linux/if_vlan.h>
291da177e4SLinus Torvalds #include <linux/init.h>
301da177e4SLinus Torvalds #include <linux/in6.h>
311da177e4SLinus Torvalds #include <linux/inetdevice.h>
321da177e4SLinus Torvalds #include <linux/igmp.h>
331da177e4SLinus Torvalds #include <linux/netfilter_ipv4.h>
34e1a80002SHerbert Xu #include <linux/etherdevice.h>
3546f25dffSKris Katterjohn #include <linux/if_ether.h>
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds #include <net/sock.h>
381da177e4SLinus Torvalds #include <net/ip.h>
391da177e4SLinus Torvalds #include <net/icmp.h>
401da177e4SLinus Torvalds #include <net/protocol.h>
41c5441932SPravin B Shelar #include <net/ip_tunnels.h>
421da177e4SLinus Torvalds #include <net/arp.h>
431da177e4SLinus Torvalds #include <net/checksum.h>
441da177e4SLinus Torvalds #include <net/dsfield.h>
451da177e4SLinus Torvalds #include <net/inet_ecn.h>
461da177e4SLinus Torvalds #include <net/xfrm.h>
4759a4c759SPavel Emelyanov #include <net/net_namespace.h>
4859a4c759SPavel Emelyanov #include <net/netns/generic.h>
49c19e654dSHerbert Xu #include <net/rtnetlink.h>
5000959adeSDmitry Kozlov #include <net/gre.h>
512e15ea39SPravin B Shelar #include <net/dst_metadata.h>
521da177e4SLinus Torvalds 
53dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
541da177e4SLinus Torvalds #include <net/ipv6.h>
551da177e4SLinus Torvalds #include <net/ip6_fib.h>
561da177e4SLinus Torvalds #include <net/ip6_route.h>
571da177e4SLinus Torvalds #endif
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds /*
601da177e4SLinus Torvalds    Problems & solutions
611da177e4SLinus Torvalds    --------------------
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds    1. The most important issue is detecting local dead loops.
641da177e4SLinus Torvalds    They would cause complete host lockup in transmit, which
651da177e4SLinus Torvalds    would be "resolved" by stack overflow or, if queueing is enabled,
661da177e4SLinus Torvalds    with infinite looping in net_bh.
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds    We cannot track such dead loops during route installation,
691da177e4SLinus Torvalds    it is infeasible task. The most general solutions would be
701da177e4SLinus Torvalds    to keep skb->encapsulation counter (sort of local ttl),
716d0722a2SEric Dumazet    and silently drop packet when it expires. It is a good
72bff52857Sstephen hemminger    solution, but it supposes maintaining new variable in ALL
731da177e4SLinus Torvalds    skb, even if no tunneling is used.
741da177e4SLinus Torvalds 
756d0722a2SEric Dumazet    Current solution: xmit_recursion breaks dead loops. This is a percpu
766d0722a2SEric Dumazet    counter, since when we enter the first ndo_xmit(), cpu migration is
776d0722a2SEric Dumazet    forbidden. We force an exit if this counter reaches RECURSION_LIMIT
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds    2. Networking dead loops would not kill routers, but would really
801da177e4SLinus Torvalds    kill network. IP hop limit plays role of "t->recursion" in this case,
811da177e4SLinus Torvalds    if we copy it from packet being encapsulated to upper header.
821da177e4SLinus Torvalds    It is very good solution, but it introduces two problems:
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds    - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
851da177e4SLinus Torvalds      do not work over tunnels.
861da177e4SLinus Torvalds    - traceroute does not work. I planned to relay ICMP from tunnel,
871da177e4SLinus Torvalds      so that this problem would be solved and traceroute output
881da177e4SLinus Torvalds      would even more informative. This idea appeared to be wrong:
891da177e4SLinus Torvalds      only Linux complies to rfc1812 now (yes, guys, Linux is the only
901da177e4SLinus Torvalds      true router now :-)), all routers (at least, in neighbourhood of mine)
911da177e4SLinus Torvalds      return only 8 bytes of payload. It is the end.
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds    Hence, if we want that OSPF worked or traceroute said something reasonable,
941da177e4SLinus Torvalds    we should search for another solution.
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds    One of them is to parse packet trying to detect inner encapsulation
971da177e4SLinus Torvalds    made by our node. It is difficult or even impossible, especially,
98bff52857Sstephen hemminger    taking into account fragmentation. TO be short, ttl is not solution at all.
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds    Current solution: The solution was UNEXPECTEDLY SIMPLE.
1011da177e4SLinus Torvalds    We force DF flag on tunnels with preconfigured hop limit,
1021da177e4SLinus Torvalds    that is ALL. :-) Well, it does not remove the problem completely,
1031da177e4SLinus Torvalds    but exponential growth of network traffic is changed to linear
1041da177e4SLinus Torvalds    (branches, that exceed pmtu are pruned) and tunnel mtu
105bff52857Sstephen hemminger    rapidly degrades to value <68, where looping stops.
1061da177e4SLinus Torvalds    Yes, it is not good if there exists a router in the loop,
1071da177e4SLinus Torvalds    which does not force DF, even when encapsulating packets have DF set.
1081da177e4SLinus Torvalds    But it is not our problem! Nobody could accuse us, we made
1091da177e4SLinus Torvalds    all that we could make. Even if it is your gated who injected
1101da177e4SLinus Torvalds    fatal route to network, even if it were you who configured
1111da177e4SLinus Torvalds    fatal static route: you are innocent. :-)
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds    Alexey Kuznetsov.
1141da177e4SLinus Torvalds  */
1151da177e4SLinus Torvalds 
116eccc1bb8Sstephen hemminger static bool log_ecn_error = true;
117eccc1bb8Sstephen hemminger module_param(log_ecn_error, bool, 0644);
118eccc1bb8Sstephen hemminger MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
119eccc1bb8Sstephen hemminger 
120c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly;
1211da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev);
122eb8ce741SPavel Emelyanov 
123f99189b1SEric Dumazet static int ipgre_net_id __read_mostly;
124c5441932SPravin B Shelar static int gre_tap_net_id __read_mostly;
125eb8ce741SPavel Emelyanov 
126*9f57c67cSPravin B Shelar static int ip_gre_calc_hlen(__be16 o_flags)
127*9f57c67cSPravin B Shelar {
128*9f57c67cSPravin B Shelar 	int addend = 4;
129*9f57c67cSPravin B Shelar 
130*9f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_CSUM)
131*9f57c67cSPravin B Shelar 		addend += 4;
132*9f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_KEY)
133*9f57c67cSPravin B Shelar 		addend += 4;
134*9f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_SEQ)
135*9f57c67cSPravin B Shelar 		addend += 4;
136*9f57c67cSPravin B Shelar 	return addend;
137*9f57c67cSPravin B Shelar }
138*9f57c67cSPravin B Shelar 
139*9f57c67cSPravin B Shelar static __be16 gre_flags_to_tnl_flags(__be16 flags)
140*9f57c67cSPravin B Shelar {
141*9f57c67cSPravin B Shelar 	__be16 tflags = 0;
142*9f57c67cSPravin B Shelar 
143*9f57c67cSPravin B Shelar 	if (flags & GRE_CSUM)
144*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_CSUM;
145*9f57c67cSPravin B Shelar 	if (flags & GRE_ROUTING)
146*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_ROUTING;
147*9f57c67cSPravin B Shelar 	if (flags & GRE_KEY)
148*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_KEY;
149*9f57c67cSPravin B Shelar 	if (flags & GRE_SEQ)
150*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_SEQ;
151*9f57c67cSPravin B Shelar 	if (flags & GRE_STRICT)
152*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_STRICT;
153*9f57c67cSPravin B Shelar 	if (flags & GRE_REC)
154*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_REC;
155*9f57c67cSPravin B Shelar 	if (flags & GRE_VERSION)
156*9f57c67cSPravin B Shelar 		tflags |= TUNNEL_VERSION;
157*9f57c67cSPravin B Shelar 
158*9f57c67cSPravin B Shelar 	return tflags;
159*9f57c67cSPravin B Shelar }
160*9f57c67cSPravin B Shelar 
161*9f57c67cSPravin B Shelar static __be16 tnl_flags_to_gre_flags(__be16 tflags)
162*9f57c67cSPravin B Shelar {
163*9f57c67cSPravin B Shelar 	__be16 flags = 0;
164*9f57c67cSPravin B Shelar 
165*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_CSUM)
166*9f57c67cSPravin B Shelar 		flags |= GRE_CSUM;
167*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_ROUTING)
168*9f57c67cSPravin B Shelar 		flags |= GRE_ROUTING;
169*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_KEY)
170*9f57c67cSPravin B Shelar 		flags |= GRE_KEY;
171*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_SEQ)
172*9f57c67cSPravin B Shelar 		flags |= GRE_SEQ;
173*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_STRICT)
174*9f57c67cSPravin B Shelar 		flags |= GRE_STRICT;
175*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_REC)
176*9f57c67cSPravin B Shelar 		flags |= GRE_REC;
177*9f57c67cSPravin B Shelar 	if (tflags & TUNNEL_VERSION)
178*9f57c67cSPravin B Shelar 		flags |= GRE_VERSION;
179*9f57c67cSPravin B Shelar 
180*9f57c67cSPravin B Shelar 	return flags;
181*9f57c67cSPravin B Shelar }
182*9f57c67cSPravin B Shelar 
183*9f57c67cSPravin B Shelar static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
184*9f57c67cSPravin B Shelar 			    bool *csum_err)
185*9f57c67cSPravin B Shelar {
186*9f57c67cSPravin B Shelar 	const struct gre_base_hdr *greh;
187*9f57c67cSPravin B Shelar 	__be32 *options;
188*9f57c67cSPravin B Shelar 	int hdr_len;
189*9f57c67cSPravin B Shelar 
190*9f57c67cSPravin B Shelar 	if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
191*9f57c67cSPravin B Shelar 		return -EINVAL;
192*9f57c67cSPravin B Shelar 
193*9f57c67cSPravin B Shelar 	greh = (struct gre_base_hdr *)skb_transport_header(skb);
194*9f57c67cSPravin B Shelar 	if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
195*9f57c67cSPravin B Shelar 		return -EINVAL;
196*9f57c67cSPravin B Shelar 
197*9f57c67cSPravin B Shelar 	tpi->flags = gre_flags_to_tnl_flags(greh->flags);
198*9f57c67cSPravin B Shelar 	hdr_len = ip_gre_calc_hlen(tpi->flags);
199*9f57c67cSPravin B Shelar 
200*9f57c67cSPravin B Shelar 	if (!pskb_may_pull(skb, hdr_len))
201*9f57c67cSPravin B Shelar 		return -EINVAL;
202*9f57c67cSPravin B Shelar 
203*9f57c67cSPravin B Shelar 	greh = (struct gre_base_hdr *)skb_transport_header(skb);
204*9f57c67cSPravin B Shelar 	tpi->proto = greh->protocol;
205*9f57c67cSPravin B Shelar 
206*9f57c67cSPravin B Shelar 	options = (__be32 *)(greh + 1);
207*9f57c67cSPravin B Shelar 	if (greh->flags & GRE_CSUM) {
208*9f57c67cSPravin B Shelar 		if (skb_checksum_simple_validate(skb)) {
209*9f57c67cSPravin B Shelar 			*csum_err = true;
210*9f57c67cSPravin B Shelar 			return -EINVAL;
211*9f57c67cSPravin B Shelar 		}
212*9f57c67cSPravin B Shelar 
213*9f57c67cSPravin B Shelar 		skb_checksum_try_convert(skb, IPPROTO_GRE, 0,
214*9f57c67cSPravin B Shelar 					 null_compute_pseudo);
215*9f57c67cSPravin B Shelar 		options++;
216*9f57c67cSPravin B Shelar 	}
217*9f57c67cSPravin B Shelar 
218*9f57c67cSPravin B Shelar 	if (greh->flags & GRE_KEY) {
219*9f57c67cSPravin B Shelar 		tpi->key = *options;
220*9f57c67cSPravin B Shelar 		options++;
221*9f57c67cSPravin B Shelar 	} else {
222*9f57c67cSPravin B Shelar 		tpi->key = 0;
223*9f57c67cSPravin B Shelar 	}
224*9f57c67cSPravin B Shelar 	if (unlikely(greh->flags & GRE_SEQ)) {
225*9f57c67cSPravin B Shelar 		tpi->seq = *options;
226*9f57c67cSPravin B Shelar 		options++;
227*9f57c67cSPravin B Shelar 	} else {
228*9f57c67cSPravin B Shelar 		tpi->seq = 0;
229*9f57c67cSPravin B Shelar 	}
230*9f57c67cSPravin B Shelar 	/* WCCP version 1 and 2 protocol decoding.
231*9f57c67cSPravin B Shelar 	 * - Change protocol to IP
232*9f57c67cSPravin B Shelar 	 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
233*9f57c67cSPravin B Shelar 	 */
234*9f57c67cSPravin B Shelar 	if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
235*9f57c67cSPravin B Shelar 		tpi->proto = htons(ETH_P_IP);
236*9f57c67cSPravin B Shelar 		if ((*(u8 *)options & 0xF0) != 0x40) {
237*9f57c67cSPravin B Shelar 			hdr_len += 4;
238*9f57c67cSPravin B Shelar 			if (!pskb_may_pull(skb, hdr_len))
239*9f57c67cSPravin B Shelar 				return -EINVAL;
240*9f57c67cSPravin B Shelar 		}
241*9f57c67cSPravin B Shelar 	}
242*9f57c67cSPravin B Shelar 	return iptunnel_pull_header(skb, hdr_len, tpi->proto);
243*9f57c67cSPravin B Shelar }
244*9f57c67cSPravin B Shelar 
245*9f57c67cSPravin B Shelar static void ipgre_err(struct sk_buff *skb, u32 info,
246bda7bb46SPravin B Shelar 		      const struct tnl_ptk_info *tpi)
2471da177e4SLinus Torvalds {
2481da177e4SLinus Torvalds 
249071f92d0SRami Rosen 	/* All the routers (except for Linux) return only
2501da177e4SLinus Torvalds 	   8 bytes of packet payload. It means, that precise relaying of
2511da177e4SLinus Torvalds 	   ICMP in the real Internet is absolutely infeasible.
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds 	   Moreover, Cisco "wise men" put GRE key to the third word
254c5441932SPravin B Shelar 	   in GRE header. It makes impossible maintaining even soft
255c5441932SPravin B Shelar 	   state for keyed GRE tunnels with enabled checksum. Tell
256c5441932SPravin B Shelar 	   them "thank you".
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	   Well, I wonder, rfc1812 was written by Cisco employee,
259bff52857Sstephen hemminger 	   what the hell these idiots break standards established
260bff52857Sstephen hemminger 	   by themselves???
2611da177e4SLinus Torvalds 	   */
262c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
263c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
26496f5a846SEric Dumazet 	const struct iphdr *iph;
26588c7664fSArnaldo Carvalho de Melo 	const int type = icmp_hdr(skb)->type;
26688c7664fSArnaldo Carvalho de Melo 	const int code = icmp_hdr(skb)->code;
2671da177e4SLinus Torvalds 	struct ip_tunnel *t;
268d2083287Sstephen hemminger 
2691da177e4SLinus Torvalds 	switch (type) {
2701da177e4SLinus Torvalds 	default:
2711da177e4SLinus Torvalds 	case ICMP_PARAMETERPROB:
272*9f57c67cSPravin B Shelar 		return;
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds 	case ICMP_DEST_UNREACH:
2751da177e4SLinus Torvalds 		switch (code) {
2761da177e4SLinus Torvalds 		case ICMP_SR_FAILED:
2771da177e4SLinus Torvalds 		case ICMP_PORT_UNREACH:
2781da177e4SLinus Torvalds 			/* Impossible event. */
279*9f57c67cSPravin B Shelar 			return;
2801da177e4SLinus Torvalds 		default:
2811da177e4SLinus Torvalds 			/* All others are translated to HOST_UNREACH.
2821da177e4SLinus Torvalds 			   rfc2003 contains "deep thoughts" about NET_UNREACH,
2831da177e4SLinus Torvalds 			   I believe they are just ether pollution. --ANK
2841da177e4SLinus Torvalds 			 */
2851da177e4SLinus Torvalds 			break;
2861da177e4SLinus Torvalds 		}
2871da177e4SLinus Torvalds 		break;
288*9f57c67cSPravin B Shelar 
2891da177e4SLinus Torvalds 	case ICMP_TIME_EXCEEDED:
2901da177e4SLinus Torvalds 		if (code != ICMP_EXC_TTL)
291*9f57c67cSPravin B Shelar 			return;
2921da177e4SLinus Torvalds 		break;
29355be7a9cSDavid S. Miller 
29455be7a9cSDavid S. Miller 	case ICMP_REDIRECT:
29555be7a9cSDavid S. Miller 		break;
2961da177e4SLinus Torvalds 	}
2971da177e4SLinus Torvalds 
298bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
299c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
300c5441932SPravin B Shelar 	else
301c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
302c5441932SPravin B Shelar 
303c0c0c50fSDuan Jiong 	iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
304bda7bb46SPravin B Shelar 	t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
305bda7bb46SPravin B Shelar 			     iph->daddr, iph->saddr, tpi->key);
306d2083287Sstephen hemminger 
30751456b29SIan Morris 	if (!t)
308*9f57c67cSPravin B Shelar 		return;
30936393395SDavid S. Miller 
31036393395SDavid S. Miller 	if (t->parms.iph.daddr == 0 ||
311f97c1e0cSJoe Perches 	    ipv4_is_multicast(t->parms.iph.daddr))
312*9f57c67cSPravin B Shelar 		return;
3131da177e4SLinus Torvalds 
3141da177e4SLinus Torvalds 	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
315*9f57c67cSPravin B Shelar 		return;
3161da177e4SLinus Torvalds 
317da6185d8SWei Yongjun 	if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
3181da177e4SLinus Torvalds 		t->err_count++;
3191da177e4SLinus Torvalds 	else
3201da177e4SLinus Torvalds 		t->err_count = 1;
3211da177e4SLinus Torvalds 	t->err_time = jiffies;
322*9f57c67cSPravin B Shelar }
323*9f57c67cSPravin B Shelar 
324*9f57c67cSPravin B Shelar static void gre_err(struct sk_buff *skb, u32 info)
325*9f57c67cSPravin B Shelar {
326*9f57c67cSPravin B Shelar 	/* All the routers (except for Linux) return only
327*9f57c67cSPravin B Shelar 	 * 8 bytes of packet payload. It means, that precise relaying of
328*9f57c67cSPravin B Shelar 	 * ICMP in the real Internet is absolutely infeasible.
329*9f57c67cSPravin B Shelar 	 *
330*9f57c67cSPravin B Shelar 	 * Moreover, Cisco "wise men" put GRE key to the third word
331*9f57c67cSPravin B Shelar 	 * in GRE header. It makes impossible maintaining even soft
332*9f57c67cSPravin B Shelar 	 * state for keyed
333*9f57c67cSPravin B Shelar 	 * GRE tunnels with enabled checksum. Tell them "thank you".
334*9f57c67cSPravin B Shelar 	 *
335*9f57c67cSPravin B Shelar 	 * Well, I wonder, rfc1812 was written by Cisco employee,
336*9f57c67cSPravin B Shelar 	 * what the hell these idiots break standards established
337*9f57c67cSPravin B Shelar 	 * by themselves???
338*9f57c67cSPravin B Shelar 	 */
339*9f57c67cSPravin B Shelar 
340*9f57c67cSPravin B Shelar 	const int type = icmp_hdr(skb)->type;
341*9f57c67cSPravin B Shelar 	const int code = icmp_hdr(skb)->code;
342*9f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
343*9f57c67cSPravin B Shelar 	bool csum_err = false;
344*9f57c67cSPravin B Shelar 
345*9f57c67cSPravin B Shelar 	if (parse_gre_header(skb, &tpi, &csum_err)) {
346*9f57c67cSPravin B Shelar 		if (!csum_err)		/* ignore csum errors. */
347*9f57c67cSPravin B Shelar 			return;
348*9f57c67cSPravin B Shelar 	}
349*9f57c67cSPravin B Shelar 
350*9f57c67cSPravin B Shelar 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
351*9f57c67cSPravin B Shelar 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
352*9f57c67cSPravin B Shelar 				 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
353*9f57c67cSPravin B Shelar 		return;
354*9f57c67cSPravin B Shelar 	}
355*9f57c67cSPravin B Shelar 	if (type == ICMP_REDIRECT) {
356*9f57c67cSPravin B Shelar 		ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
357*9f57c67cSPravin B Shelar 			      IPPROTO_GRE, 0);
358*9f57c67cSPravin B Shelar 		return;
359*9f57c67cSPravin B Shelar 	}
360*9f57c67cSPravin B Shelar 
361*9f57c67cSPravin B Shelar 	ipgre_err(skb, info, &tpi);
3621da177e4SLinus Torvalds }
3631da177e4SLinus Torvalds 
3642e15ea39SPravin B Shelar static __be64 key_to_tunnel_id(__be32 key)
3652e15ea39SPravin B Shelar {
3662e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
3672e15ea39SPravin B Shelar 	return (__force __be64)((__force u32)key);
3682e15ea39SPravin B Shelar #else
3692e15ea39SPravin B Shelar 	return (__force __be64)((__force u64)key << 32);
3702e15ea39SPravin B Shelar #endif
3712e15ea39SPravin B Shelar }
3722e15ea39SPravin B Shelar 
3732e15ea39SPravin B Shelar /* Returns the least-significant 32 bits of a __be64. */
3742e15ea39SPravin B Shelar static __be32 tunnel_id_to_key(__be64 x)
3752e15ea39SPravin B Shelar {
3762e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
3772e15ea39SPravin B Shelar 	return (__force __be32)x;
3782e15ea39SPravin B Shelar #else
3792e15ea39SPravin B Shelar 	return (__force __be32)((__force u64)x >> 32);
3802e15ea39SPravin B Shelar #endif
3812e15ea39SPravin B Shelar }
3822e15ea39SPravin B Shelar 
383bda7bb46SPravin B Shelar static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
3841da177e4SLinus Torvalds {
385c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
3862e15ea39SPravin B Shelar 	struct metadata_dst *tun_dst = NULL;
387c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
388b71d1d42SEric Dumazet 	const struct iphdr *iph;
3891da177e4SLinus Torvalds 	struct ip_tunnel *tunnel;
3901da177e4SLinus Torvalds 
391bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
392c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
393c5441932SPravin B Shelar 	else
394c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
395c5441932SPravin B Shelar 
396eddc9ec5SArnaldo Carvalho de Melo 	iph = ip_hdr(skb);
397bda7bb46SPravin B Shelar 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
398bda7bb46SPravin B Shelar 				  iph->saddr, iph->daddr, tpi->key);
3991da177e4SLinus Torvalds 
400d2083287Sstephen hemminger 	if (tunnel) {
4010e3da5bbSTimo Teräs 		skb_pop_mac_header(skb);
4022e15ea39SPravin B Shelar 		if (tunnel->collect_md) {
4032e15ea39SPravin B Shelar 			struct ip_tunnel_info *info;
4042e15ea39SPravin B Shelar 
4052e15ea39SPravin B Shelar 			tun_dst = metadata_dst_alloc(0, GFP_ATOMIC);
4062e15ea39SPravin B Shelar 			if (!tun_dst)
4072e15ea39SPravin B Shelar 				return PACKET_REJECT;
4082e15ea39SPravin B Shelar 
4092e15ea39SPravin B Shelar 			info = &tun_dst->u.tun_info;
4102e15ea39SPravin B Shelar 			info->key.ipv4_src = iph->saddr;
4112e15ea39SPravin B Shelar 			info->key.ipv4_dst = iph->daddr;
4122e15ea39SPravin B Shelar 			info->key.ipv4_tos = iph->tos;
4132e15ea39SPravin B Shelar 			info->key.ipv4_ttl = iph->ttl;
4142e15ea39SPravin B Shelar 
4152e15ea39SPravin B Shelar 			info->mode = IP_TUNNEL_INFO_RX;
4162e15ea39SPravin B Shelar 			info->key.tun_flags = tpi->flags &
4172e15ea39SPravin B Shelar 					      (TUNNEL_CSUM | TUNNEL_KEY);
4182e15ea39SPravin B Shelar 			info->key.tun_id = key_to_tunnel_id(tpi->key);
4192e15ea39SPravin B Shelar 
4202e15ea39SPravin B Shelar 			info->key.tp_src = 0;
4212e15ea39SPravin B Shelar 			info->key.tp_dst = 0;
4222e15ea39SPravin B Shelar 		}
4232e15ea39SPravin B Shelar 
4242e15ea39SPravin B Shelar 		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
425bda7bb46SPravin B Shelar 		return PACKET_RCVD;
4261da177e4SLinus Torvalds 	}
427bda7bb46SPravin B Shelar 	return PACKET_REJECT;
4281da177e4SLinus Torvalds }
4291da177e4SLinus Torvalds 
430*9f57c67cSPravin B Shelar static int gre_rcv(struct sk_buff *skb)
431*9f57c67cSPravin B Shelar {
432*9f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
433*9f57c67cSPravin B Shelar 	bool csum_err = false;
434*9f57c67cSPravin B Shelar 
435*9f57c67cSPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
436*9f57c67cSPravin B Shelar 	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
437*9f57c67cSPravin B Shelar 		/* Looped back packet, drop it! */
438*9f57c67cSPravin B Shelar 		if (rt_is_output_route(skb_rtable(skb)))
439*9f57c67cSPravin B Shelar 			goto drop;
440*9f57c67cSPravin B Shelar 	}
441*9f57c67cSPravin B Shelar #endif
442*9f57c67cSPravin B Shelar 
443*9f57c67cSPravin B Shelar 	if (parse_gre_header(skb, &tpi, &csum_err) < 0)
444*9f57c67cSPravin B Shelar 		goto drop;
445*9f57c67cSPravin B Shelar 
446*9f57c67cSPravin B Shelar 	if (ipgre_rcv(skb, &tpi) == PACKET_RCVD)
447*9f57c67cSPravin B Shelar 		return 0;
448*9f57c67cSPravin B Shelar 
449*9f57c67cSPravin B Shelar 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
450*9f57c67cSPravin B Shelar drop:
451*9f57c67cSPravin B Shelar 	kfree_skb(skb);
452*9f57c67cSPravin B Shelar 	return 0;
453*9f57c67cSPravin B Shelar }
454*9f57c67cSPravin B Shelar 
4552e15ea39SPravin B Shelar static void build_header(struct sk_buff *skb, int hdr_len, __be16 flags,
4562e15ea39SPravin B Shelar 			 __be16 proto, __be32 key, __be32 seq)
4572e15ea39SPravin B Shelar {
4582e15ea39SPravin B Shelar 	struct gre_base_hdr *greh;
4592e15ea39SPravin B Shelar 
4602e15ea39SPravin B Shelar 	skb_push(skb, hdr_len);
4612e15ea39SPravin B Shelar 
4622e15ea39SPravin B Shelar 	skb_reset_transport_header(skb);
4632e15ea39SPravin B Shelar 	greh = (struct gre_base_hdr *)skb->data;
4642e15ea39SPravin B Shelar 	greh->flags = tnl_flags_to_gre_flags(flags);
4652e15ea39SPravin B Shelar 	greh->protocol = proto;
4662e15ea39SPravin B Shelar 
4672e15ea39SPravin B Shelar 	if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
4682e15ea39SPravin B Shelar 		__be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
4692e15ea39SPravin B Shelar 
4702e15ea39SPravin B Shelar 		if (flags & TUNNEL_SEQ) {
4712e15ea39SPravin B Shelar 			*ptr = seq;
4722e15ea39SPravin B Shelar 			ptr--;
4732e15ea39SPravin B Shelar 		}
4742e15ea39SPravin B Shelar 		if (flags & TUNNEL_KEY) {
4752e15ea39SPravin B Shelar 			*ptr = key;
4762e15ea39SPravin B Shelar 			ptr--;
4772e15ea39SPravin B Shelar 		}
4782e15ea39SPravin B Shelar 		if (flags & TUNNEL_CSUM &&
4792e15ea39SPravin B Shelar 		    !(skb_shinfo(skb)->gso_type &
4802e15ea39SPravin B Shelar 		      (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
4812e15ea39SPravin B Shelar 			*ptr = 0;
4822e15ea39SPravin B Shelar 			*(__sum16 *)ptr = csum_fold(skb_checksum(skb, 0,
4832e15ea39SPravin B Shelar 								 skb->len, 0));
4842e15ea39SPravin B Shelar 		}
4852e15ea39SPravin B Shelar 	}
4862e15ea39SPravin B Shelar }
4872e15ea39SPravin B Shelar 
488c5441932SPravin B Shelar static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
489c5441932SPravin B Shelar 		       const struct iphdr *tnl_params,
490c5441932SPravin B Shelar 		       __be16 proto)
491c5441932SPravin B Shelar {
492c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
493c5441932SPravin B Shelar 
494c5441932SPravin B Shelar 	if (tunnel->parms.o_flags & TUNNEL_SEQ)
495c5441932SPravin B Shelar 		tunnel->o_seqno++;
496cef401deSEric Dumazet 
497c5441932SPravin B Shelar 	/* Push GRE header. */
4982e15ea39SPravin B Shelar 	build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
4992e15ea39SPravin B Shelar 		     proto, tunnel->parms.o_key, htonl(tunnel->o_seqno));
5001da177e4SLinus Torvalds 
5012e15ea39SPravin B Shelar 	skb_set_inner_protocol(skb, proto);
502bf3d6a8fSNicolas Dichtel 	ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
5031da177e4SLinus Torvalds }
5041da177e4SLinus Torvalds 
505b2acd1dcSPravin B Shelar static struct sk_buff *gre_handle_offloads(struct sk_buff *skb,
506b2acd1dcSPravin B Shelar 					   bool csum)
507b2acd1dcSPravin B Shelar {
508b2acd1dcSPravin B Shelar 	return iptunnel_handle_offloads(skb, csum,
509b2acd1dcSPravin B Shelar 					csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
510b2acd1dcSPravin B Shelar }
511b2acd1dcSPravin B Shelar 
5122e15ea39SPravin B Shelar static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
5132e15ea39SPravin B Shelar {
5142e15ea39SPravin B Shelar 	struct ip_tunnel_info *tun_info;
5152e15ea39SPravin B Shelar 	struct net *net = dev_net(dev);
5162e15ea39SPravin B Shelar 	const struct ip_tunnel_key *key;
5172e15ea39SPravin B Shelar 	struct flowi4 fl;
5182e15ea39SPravin B Shelar 	struct rtable *rt;
5192e15ea39SPravin B Shelar 	int min_headroom;
5202e15ea39SPravin B Shelar 	int tunnel_hlen;
5212e15ea39SPravin B Shelar 	__be16 df, flags;
5222e15ea39SPravin B Shelar 	int err;
5232e15ea39SPravin B Shelar 
5242e15ea39SPravin B Shelar 	tun_info = skb_tunnel_info(skb, AF_INET);
5252e15ea39SPravin B Shelar 	if (unlikely(!tun_info || tun_info->mode != IP_TUNNEL_INFO_TX))
5262e15ea39SPravin B Shelar 		goto err_free_skb;
5272e15ea39SPravin B Shelar 
5282e15ea39SPravin B Shelar 	key = &tun_info->key;
5292e15ea39SPravin B Shelar 	memset(&fl, 0, sizeof(fl));
5302e15ea39SPravin B Shelar 	fl.daddr = key->ipv4_dst;
5312e15ea39SPravin B Shelar 	fl.saddr = key->ipv4_src;
5322e15ea39SPravin B Shelar 	fl.flowi4_tos = RT_TOS(key->ipv4_tos);
5332e15ea39SPravin B Shelar 	fl.flowi4_mark = skb->mark;
5342e15ea39SPravin B Shelar 	fl.flowi4_proto = IPPROTO_GRE;
5352e15ea39SPravin B Shelar 
5362e15ea39SPravin B Shelar 	rt = ip_route_output_key(net, &fl);
5372e15ea39SPravin B Shelar 	if (IS_ERR(rt))
5382e15ea39SPravin B Shelar 		goto err_free_skb;
5392e15ea39SPravin B Shelar 
5402e15ea39SPravin B Shelar 	tunnel_hlen = ip_gre_calc_hlen(key->tun_flags);
5412e15ea39SPravin B Shelar 
5422e15ea39SPravin B Shelar 	min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
5432e15ea39SPravin B Shelar 			+ tunnel_hlen + sizeof(struct iphdr);
5442e15ea39SPravin B Shelar 	if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
5452e15ea39SPravin B Shelar 		int head_delta = SKB_DATA_ALIGN(min_headroom -
5462e15ea39SPravin B Shelar 						skb_headroom(skb) +
5472e15ea39SPravin B Shelar 						16);
5482e15ea39SPravin B Shelar 		err = pskb_expand_head(skb, max_t(int, head_delta, 0),
5492e15ea39SPravin B Shelar 				       0, GFP_ATOMIC);
5502e15ea39SPravin B Shelar 		if (unlikely(err))
5512e15ea39SPravin B Shelar 			goto err_free_rt;
5522e15ea39SPravin B Shelar 	}
5532e15ea39SPravin B Shelar 
5542e15ea39SPravin B Shelar 	/* Push Tunnel header. */
5552e15ea39SPravin B Shelar 	skb = gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM));
5562e15ea39SPravin B Shelar 	if (IS_ERR(skb)) {
5572e15ea39SPravin B Shelar 		skb = NULL;
5582e15ea39SPravin B Shelar 		goto err_free_rt;
5592e15ea39SPravin B Shelar 	}
5602e15ea39SPravin B Shelar 
5612e15ea39SPravin B Shelar 	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
5622e15ea39SPravin B Shelar 	build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
5632e15ea39SPravin B Shelar 		     tunnel_id_to_key(tun_info->key.tun_id), 0);
5642e15ea39SPravin B Shelar 
5652e15ea39SPravin B Shelar 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
5662e15ea39SPravin B Shelar 	err = iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
5672e15ea39SPravin B Shelar 			    key->ipv4_dst, IPPROTO_GRE,
5682e15ea39SPravin B Shelar 			    key->ipv4_tos, key->ipv4_ttl, df, false);
5692e15ea39SPravin B Shelar 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
5702e15ea39SPravin B Shelar 	return;
5712e15ea39SPravin B Shelar 
5722e15ea39SPravin B Shelar err_free_rt:
5732e15ea39SPravin B Shelar 	ip_rt_put(rt);
5742e15ea39SPravin B Shelar err_free_skb:
5752e15ea39SPravin B Shelar 	kfree_skb(skb);
5762e15ea39SPravin B Shelar 	dev->stats.tx_dropped++;
5772e15ea39SPravin B Shelar }
5782e15ea39SPravin B Shelar 
579c5441932SPravin B Shelar static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
580c5441932SPravin B Shelar 			      struct net_device *dev)
581ee34c1ebSMichal Schmidt {
582c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
583c5441932SPravin B Shelar 	const struct iphdr *tnl_params;
584ee34c1ebSMichal Schmidt 
5852e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
5862e15ea39SPravin B Shelar 		gre_fb_xmit(skb, dev);
5872e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
5882e15ea39SPravin B Shelar 	}
5892e15ea39SPravin B Shelar 
590c5441932SPravin B Shelar 	if (dev->header_ops) {
591c5441932SPravin B Shelar 		/* Need space for new headers */
592c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom -
5932bac7cb3SChen Gang 				      (tunnel->hlen + sizeof(struct iphdr))))
594c5441932SPravin B Shelar 			goto free_skb;
595ee34c1ebSMichal Schmidt 
596c5441932SPravin B Shelar 		tnl_params = (const struct iphdr *)skb->data;
597cbb1e85fSDavid S. Miller 
598c5441932SPravin B Shelar 		/* Pull skb since ip_tunnel_xmit() needs skb->data pointing
599c5441932SPravin B Shelar 		 * to gre header.
600c5441932SPravin B Shelar 		 */
601c5441932SPravin B Shelar 		skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
6028a0033a9STimo Teräs 		skb_reset_mac_header(skb);
603c5441932SPravin B Shelar 	} else {
604c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom))
605c5441932SPravin B Shelar 			goto free_skb;
606c5441932SPravin B Shelar 
607c5441932SPravin B Shelar 		tnl_params = &tunnel->parms.iph;
608ee34c1ebSMichal Schmidt 	}
609e1a80002SHerbert Xu 
6108a0033a9STimo Teräs 	skb = gre_handle_offloads(skb, !!(tunnel->parms.o_flags&TUNNEL_CSUM));
6118a0033a9STimo Teräs 	if (IS_ERR(skb))
6128a0033a9STimo Teräs 		goto out;
6138a0033a9STimo Teräs 
614c5441932SPravin B Shelar 	__gre_xmit(skb, dev, tnl_params, skb->protocol);
615c5441932SPravin B Shelar 	return NETDEV_TX_OK;
616c5441932SPravin B Shelar 
617c5441932SPravin B Shelar free_skb:
6183acfa1e7SEric Dumazet 	kfree_skb(skb);
619c5441932SPravin B Shelar out:
620c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
621c5441932SPravin B Shelar 	return NETDEV_TX_OK;
622ee34c1ebSMichal Schmidt }
623ee34c1ebSMichal Schmidt 
624c5441932SPravin B Shelar static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
625c5441932SPravin B Shelar 				struct net_device *dev)
626c5441932SPravin B Shelar {
627c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
628ee34c1ebSMichal Schmidt 
6292e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
6302e15ea39SPravin B Shelar 		gre_fb_xmit(skb, dev);
6312e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
6322e15ea39SPravin B Shelar 	}
6332e15ea39SPravin B Shelar 
63445f2e997SPravin B Shelar 	skb = gre_handle_offloads(skb, !!(tunnel->parms.o_flags&TUNNEL_CSUM));
635c5441932SPravin B Shelar 	if (IS_ERR(skb))
636c5441932SPravin B Shelar 		goto out;
637ee34c1ebSMichal Schmidt 
638c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom))
639c5441932SPravin B Shelar 		goto free_skb;
64042aa9162SHerbert Xu 
641c5441932SPravin B Shelar 	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
642c5441932SPravin B Shelar 	return NETDEV_TX_OK;
643c5441932SPravin B Shelar 
644c5441932SPravin B Shelar free_skb:
6453acfa1e7SEric Dumazet 	kfree_skb(skb);
646c5441932SPravin B Shelar out:
647c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
648c5441932SPravin B Shelar 	return NETDEV_TX_OK;
64968c33163SPravin B Shelar }
650ee34c1ebSMichal Schmidt 
651c5441932SPravin B Shelar static int ipgre_tunnel_ioctl(struct net_device *dev,
652c5441932SPravin B Shelar 			      struct ifreq *ifr, int cmd)
6531da177e4SLinus Torvalds {
6544565e991STom Herbert 	int err;
6551da177e4SLinus Torvalds 	struct ip_tunnel_parm p;
6561da177e4SLinus Torvalds 
6571da177e4SLinus Torvalds 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
658c5441932SPravin B Shelar 		return -EFAULT;
6596c734fb8SCong Wang 	if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
6601da177e4SLinus Torvalds 		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
6611da177e4SLinus Torvalds 		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
6626c734fb8SCong Wang 		    ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
6631da177e4SLinus Torvalds 			return -EINVAL;
664c5441932SPravin B Shelar 	}
665c5441932SPravin B Shelar 	p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
666c5441932SPravin B Shelar 	p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
667c5441932SPravin B Shelar 
668c5441932SPravin B Shelar 	err = ip_tunnel_ioctl(dev, &p, cmd);
669c5441932SPravin B Shelar 	if (err)
670c5441932SPravin B Shelar 		return err;
671c5441932SPravin B Shelar 
672c5441932SPravin B Shelar 	p.i_flags = tnl_flags_to_gre_flags(p.i_flags);
673c5441932SPravin B Shelar 	p.o_flags = tnl_flags_to_gre_flags(p.o_flags);
674c5441932SPravin B Shelar 
675c5441932SPravin B Shelar 	if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
676c5441932SPravin B Shelar 		return -EFAULT;
6771da177e4SLinus Torvalds 	return 0;
6781da177e4SLinus Torvalds }
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds /* Nice toy. Unfortunately, useless in real life :-)
6811da177e4SLinus Torvalds    It allows to construct virtual multiprotocol broadcast "LAN"
6821da177e4SLinus Torvalds    over the Internet, provided multicast routing is tuned.
6831da177e4SLinus Torvalds 
6841da177e4SLinus Torvalds 
6851da177e4SLinus Torvalds    I have no idea was this bicycle invented before me,
6861da177e4SLinus Torvalds    so that I had to set ARPHRD_IPGRE to a random value.
6871da177e4SLinus Torvalds    I have an impression, that Cisco could make something similar,
6881da177e4SLinus Torvalds    but this feature is apparently missing in IOS<=11.2(8).
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds    I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
6911da177e4SLinus Torvalds    with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds    ping -t 255 224.66.66.66
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds    If nobody answers, mbone does not work.
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds    ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
6981da177e4SLinus Torvalds    ip addr add 10.66.66.<somewhat>/24 dev Universe
6991da177e4SLinus Torvalds    ifconfig Universe up
7001da177e4SLinus Torvalds    ifconfig Universe add fe80::<Your_real_addr>/10
7011da177e4SLinus Torvalds    ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
7021da177e4SLinus Torvalds    ftp 10.66.66.66
7031da177e4SLinus Torvalds    ...
7041da177e4SLinus Torvalds    ftp fec0:6666:6666::193.233.7.65
7051da177e4SLinus Torvalds    ...
7061da177e4SLinus Torvalds  */
7073b04dddeSStephen Hemminger static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
7083b04dddeSStephen Hemminger 			unsigned short type,
7091507850bSEric Dumazet 			const void *daddr, const void *saddr, unsigned int len)
7101da177e4SLinus Torvalds {
7112941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
712c5441932SPravin B Shelar 	struct iphdr *iph;
713c5441932SPravin B Shelar 	struct gre_base_hdr *greh;
714c5441932SPravin B Shelar 
715c5441932SPravin B Shelar 	iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
716c5441932SPravin B Shelar 	greh = (struct gre_base_hdr *)(iph+1);
717c5441932SPravin B Shelar 	greh->flags = tnl_flags_to_gre_flags(t->parms.o_flags);
718c5441932SPravin B Shelar 	greh->protocol = htons(type);
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds 	memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
7211da177e4SLinus Torvalds 
722c5441932SPravin B Shelar 	/* Set the source hardware address. */
7231da177e4SLinus Torvalds 	if (saddr)
7241da177e4SLinus Torvalds 		memcpy(&iph->saddr, saddr, 4);
7256d55cb91STimo Teräs 	if (daddr)
7261da177e4SLinus Torvalds 		memcpy(&iph->daddr, daddr, 4);
7276d55cb91STimo Teräs 	if (iph->daddr)
72877a482bdSTimo Teräs 		return t->hlen + sizeof(*iph);
7291da177e4SLinus Torvalds 
730c5441932SPravin B Shelar 	return -(t->hlen + sizeof(*iph));
7311da177e4SLinus Torvalds }
7321da177e4SLinus Torvalds 
7336a5f44d7STimo Teras static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
7346a5f44d7STimo Teras {
735b71d1d42SEric Dumazet 	const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
7366a5f44d7STimo Teras 	memcpy(haddr, &iph->saddr, 4);
7376a5f44d7STimo Teras 	return 4;
7386a5f44d7STimo Teras }
7396a5f44d7STimo Teras 
7403b04dddeSStephen Hemminger static const struct header_ops ipgre_header_ops = {
7413b04dddeSStephen Hemminger 	.create	= ipgre_header,
7426a5f44d7STimo Teras 	.parse	= ipgre_header_parse,
7433b04dddeSStephen Hemminger };
7443b04dddeSStephen Hemminger 
7456a5f44d7STimo Teras #ifdef CONFIG_NET_IPGRE_BROADCAST
7461da177e4SLinus Torvalds static int ipgre_open(struct net_device *dev)
7471da177e4SLinus Torvalds {
7482941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
7491da177e4SLinus Torvalds 
750f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr)) {
751cbb1e85fSDavid S. Miller 		struct flowi4 fl4;
752cbb1e85fSDavid S. Miller 		struct rtable *rt;
753cbb1e85fSDavid S. Miller 
754b57708adSNicolas Dichtel 		rt = ip_route_output_gre(t->net, &fl4,
75578fbfd8aSDavid S. Miller 					 t->parms.iph.daddr,
75678fbfd8aSDavid S. Miller 					 t->parms.iph.saddr,
75778fbfd8aSDavid S. Miller 					 t->parms.o_key,
75878fbfd8aSDavid S. Miller 					 RT_TOS(t->parms.iph.tos),
75978fbfd8aSDavid S. Miller 					 t->parms.link);
760b23dd4feSDavid S. Miller 		if (IS_ERR(rt))
7611da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
762d8d1f30bSChangli Gao 		dev = rt->dst.dev;
7631da177e4SLinus Torvalds 		ip_rt_put(rt);
76451456b29SIan Morris 		if (!__in_dev_get_rtnl(dev))
7651da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
7661da177e4SLinus Torvalds 		t->mlink = dev->ifindex;
767e5ed6399SHerbert Xu 		ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
7681da177e4SLinus Torvalds 	}
7691da177e4SLinus Torvalds 	return 0;
7701da177e4SLinus Torvalds }
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds static int ipgre_close(struct net_device *dev)
7731da177e4SLinus Torvalds {
7742941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
775b8c26a33SStephen Hemminger 
776f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
7777fee0ca2SDenis V. Lunev 		struct in_device *in_dev;
778b57708adSNicolas Dichtel 		in_dev = inetdev_by_index(t->net, t->mlink);
7798723e1b4SEric Dumazet 		if (in_dev)
7801da177e4SLinus Torvalds 			ip_mc_dec_group(in_dev, t->parms.iph.daddr);
7811da177e4SLinus Torvalds 	}
7821da177e4SLinus Torvalds 	return 0;
7831da177e4SLinus Torvalds }
7841da177e4SLinus Torvalds #endif
7851da177e4SLinus Torvalds 
786b8c26a33SStephen Hemminger static const struct net_device_ops ipgre_netdev_ops = {
787b8c26a33SStephen Hemminger 	.ndo_init		= ipgre_tunnel_init,
788c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
789b8c26a33SStephen Hemminger #ifdef CONFIG_NET_IPGRE_BROADCAST
790b8c26a33SStephen Hemminger 	.ndo_open		= ipgre_open,
791b8c26a33SStephen Hemminger 	.ndo_stop		= ipgre_close,
792b8c26a33SStephen Hemminger #endif
793c5441932SPravin B Shelar 	.ndo_start_xmit		= ipgre_xmit,
794b8c26a33SStephen Hemminger 	.ndo_do_ioctl		= ipgre_tunnel_ioctl,
795c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
796c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
7971e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
798b8c26a33SStephen Hemminger };
799b8c26a33SStephen Hemminger 
8006b78f16eSEric Dumazet #define GRE_FEATURES (NETIF_F_SG |		\
8016b78f16eSEric Dumazet 		      NETIF_F_FRAGLIST |	\
8026b78f16eSEric Dumazet 		      NETIF_F_HIGHDMA |		\
8036b78f16eSEric Dumazet 		      NETIF_F_HW_CSUM)
8046b78f16eSEric Dumazet 
8051da177e4SLinus Torvalds static void ipgre_tunnel_setup(struct net_device *dev)
8061da177e4SLinus Torvalds {
807b8c26a33SStephen Hemminger 	dev->netdev_ops		= &ipgre_netdev_ops;
8085a455275SNicolas Dichtel 	dev->type		= ARPHRD_IPGRE;
809c5441932SPravin B Shelar 	ip_tunnel_setup(dev, ipgre_net_id);
810c5441932SPravin B Shelar }
8111da177e4SLinus Torvalds 
812c5441932SPravin B Shelar static void __gre_tunnel_init(struct net_device *dev)
813c5441932SPravin B Shelar {
814c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
8154565e991STom Herbert 	int t_hlen;
816c5441932SPravin B Shelar 
817c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
8184565e991STom Herbert 	tunnel->tun_hlen = ip_gre_calc_hlen(tunnel->parms.o_flags);
819c5441932SPravin B Shelar 	tunnel->parms.iph.protocol = IPPROTO_GRE;
820c5441932SPravin B Shelar 
8214565e991STom Herbert 	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
8224565e991STom Herbert 
8234565e991STom Herbert 	t_hlen = tunnel->hlen + sizeof(struct iphdr);
8244565e991STom Herbert 
8254565e991STom Herbert 	dev->needed_headroom	= LL_MAX_HEADER + t_hlen + 4;
8264565e991STom Herbert 	dev->mtu		= ETH_DATA_LEN - t_hlen - 4;
8276b78f16eSEric Dumazet 
828b57708adSNicolas Dichtel 	dev->features		|= GRE_FEATURES;
8296b78f16eSEric Dumazet 	dev->hw_features	|= GRE_FEATURES;
830c5441932SPravin B Shelar 
831c5441932SPravin B Shelar 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
832c5441932SPravin B Shelar 		/* TCP offload with GRE SEQ is not supported. */
833c5441932SPravin B Shelar 		dev->features    |= NETIF_F_GSO_SOFTWARE;
834c5441932SPravin B Shelar 		dev->hw_features |= NETIF_F_GSO_SOFTWARE;
835c5441932SPravin B Shelar 		/* Can use a lockless transmit, unless we generate
836c5441932SPravin B Shelar 		 * output sequences
837c5441932SPravin B Shelar 		 */
838c5441932SPravin B Shelar 		dev->features |= NETIF_F_LLTX;
839c5441932SPravin B Shelar 	}
8401da177e4SLinus Torvalds }
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev)
8431da177e4SLinus Torvalds {
844c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
845c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
8461da177e4SLinus Torvalds 
847c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
8481da177e4SLinus Torvalds 
849c5441932SPravin B Shelar 	memcpy(dev->dev_addr, &iph->saddr, 4);
850c5441932SPravin B Shelar 	memcpy(dev->broadcast, &iph->daddr, 4);
8511da177e4SLinus Torvalds 
852c5441932SPravin B Shelar 	dev->flags		= IFF_NOARP;
85302875878SEric Dumazet 	netif_keep_dst(dev);
854c5441932SPravin B Shelar 	dev->addr_len		= 4;
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds 	if (iph->daddr) {
8571da177e4SLinus Torvalds #ifdef CONFIG_NET_IPGRE_BROADCAST
858f97c1e0cSJoe Perches 		if (ipv4_is_multicast(iph->daddr)) {
8591da177e4SLinus Torvalds 			if (!iph->saddr)
8601da177e4SLinus Torvalds 				return -EINVAL;
8611da177e4SLinus Torvalds 			dev->flags = IFF_BROADCAST;
8623b04dddeSStephen Hemminger 			dev->header_ops = &ipgre_header_ops;
8631da177e4SLinus Torvalds 		}
8641da177e4SLinus Torvalds #endif
865ee34c1ebSMichal Schmidt 	} else
8666a5f44d7STimo Teras 		dev->header_ops = &ipgre_header_ops;
8671da177e4SLinus Torvalds 
868c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
86960769a5dSEric Dumazet }
87060769a5dSEric Dumazet 
871*9f57c67cSPravin B Shelar static const struct gre_protocol ipgre_protocol = {
872*9f57c67cSPravin B Shelar 	.handler     = gre_rcv,
873*9f57c67cSPravin B Shelar 	.err_handler = gre_err,
8741da177e4SLinus Torvalds };
8751da177e4SLinus Torvalds 
8762c8c1e72SAlexey Dobriyan static int __net_init ipgre_init_net(struct net *net)
87759a4c759SPavel Emelyanov {
878c5441932SPravin B Shelar 	return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
87959a4c759SPavel Emelyanov }
88059a4c759SPavel Emelyanov 
8812c8c1e72SAlexey Dobriyan static void __net_exit ipgre_exit_net(struct net *net)
88259a4c759SPavel Emelyanov {
883c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
8846c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_link_ops);
88559a4c759SPavel Emelyanov }
88659a4c759SPavel Emelyanov 
88759a4c759SPavel Emelyanov static struct pernet_operations ipgre_net_ops = {
88859a4c759SPavel Emelyanov 	.init = ipgre_init_net,
88959a4c759SPavel Emelyanov 	.exit = ipgre_exit_net,
890cfb8fbf2SEric W. Biederman 	.id   = &ipgre_net_id,
891c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
89259a4c759SPavel Emelyanov };
8931da177e4SLinus Torvalds 
894c19e654dSHerbert Xu static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
895c19e654dSHerbert Xu {
896c19e654dSHerbert Xu 	__be16 flags;
897c19e654dSHerbert Xu 
898c19e654dSHerbert Xu 	if (!data)
899c19e654dSHerbert Xu 		return 0;
900c19e654dSHerbert Xu 
901c19e654dSHerbert Xu 	flags = 0;
902c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
903c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
904c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
905c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
906c19e654dSHerbert Xu 	if (flags & (GRE_VERSION|GRE_ROUTING))
907c19e654dSHerbert Xu 		return -EINVAL;
908c19e654dSHerbert Xu 
909c19e654dSHerbert Xu 	return 0;
910c19e654dSHerbert Xu }
911c19e654dSHerbert Xu 
912e1a80002SHerbert Xu static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
913e1a80002SHerbert Xu {
914e1a80002SHerbert Xu 	__be32 daddr;
915e1a80002SHerbert Xu 
916e1a80002SHerbert Xu 	if (tb[IFLA_ADDRESS]) {
917e1a80002SHerbert Xu 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
918e1a80002SHerbert Xu 			return -EINVAL;
919e1a80002SHerbert Xu 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
920e1a80002SHerbert Xu 			return -EADDRNOTAVAIL;
921e1a80002SHerbert Xu 	}
922e1a80002SHerbert Xu 
923e1a80002SHerbert Xu 	if (!data)
924e1a80002SHerbert Xu 		goto out;
925e1a80002SHerbert Xu 
926e1a80002SHerbert Xu 	if (data[IFLA_GRE_REMOTE]) {
927e1a80002SHerbert Xu 		memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
928e1a80002SHerbert Xu 		if (!daddr)
929e1a80002SHerbert Xu 			return -EINVAL;
930e1a80002SHerbert Xu 	}
931e1a80002SHerbert Xu 
932e1a80002SHerbert Xu out:
933e1a80002SHerbert Xu 	return ipgre_tunnel_validate(tb, data);
934e1a80002SHerbert Xu }
935e1a80002SHerbert Xu 
9362e15ea39SPravin B Shelar static void ipgre_netlink_parms(struct net_device *dev,
9372e15ea39SPravin B Shelar 				struct nlattr *data[],
9382e15ea39SPravin B Shelar 				struct nlattr *tb[],
939c19e654dSHerbert Xu 				struct ip_tunnel_parm *parms)
940c19e654dSHerbert Xu {
9417bb82d92SHerbert Xu 	memset(parms, 0, sizeof(*parms));
942c19e654dSHerbert Xu 
943c19e654dSHerbert Xu 	parms->iph.protocol = IPPROTO_GRE;
944c19e654dSHerbert Xu 
945c19e654dSHerbert Xu 	if (!data)
946c19e654dSHerbert Xu 		return;
947c19e654dSHerbert Xu 
948c19e654dSHerbert Xu 	if (data[IFLA_GRE_LINK])
949c19e654dSHerbert Xu 		parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
950c19e654dSHerbert Xu 
951c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
952c5441932SPravin B Shelar 		parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
953c19e654dSHerbert Xu 
954c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
955c5441932SPravin B Shelar 		parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
956c19e654dSHerbert Xu 
957c19e654dSHerbert Xu 	if (data[IFLA_GRE_IKEY])
958c19e654dSHerbert Xu 		parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
959c19e654dSHerbert Xu 
960c19e654dSHerbert Xu 	if (data[IFLA_GRE_OKEY])
961c19e654dSHerbert Xu 		parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
962c19e654dSHerbert Xu 
963c19e654dSHerbert Xu 	if (data[IFLA_GRE_LOCAL])
96467b61f6cSJiri Benc 		parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
965c19e654dSHerbert Xu 
966c19e654dSHerbert Xu 	if (data[IFLA_GRE_REMOTE])
96767b61f6cSJiri Benc 		parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
968c19e654dSHerbert Xu 
969c19e654dSHerbert Xu 	if (data[IFLA_GRE_TTL])
970c19e654dSHerbert Xu 		parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
971c19e654dSHerbert Xu 
972c19e654dSHerbert Xu 	if (data[IFLA_GRE_TOS])
973c19e654dSHerbert Xu 		parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
974c19e654dSHerbert Xu 
975c19e654dSHerbert Xu 	if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC]))
976c19e654dSHerbert Xu 		parms->iph.frag_off = htons(IP_DF);
9772e15ea39SPravin B Shelar 
9782e15ea39SPravin B Shelar 	if (data[IFLA_GRE_COLLECT_METADATA]) {
9792e15ea39SPravin B Shelar 		struct ip_tunnel *t = netdev_priv(dev);
9802e15ea39SPravin B Shelar 
9812e15ea39SPravin B Shelar 		t->collect_md = true;
9822e15ea39SPravin B Shelar 	}
983c19e654dSHerbert Xu }
984c19e654dSHerbert Xu 
9854565e991STom Herbert /* This function returns true when ENCAP attributes are present in the nl msg */
9864565e991STom Herbert static bool ipgre_netlink_encap_parms(struct nlattr *data[],
9874565e991STom Herbert 				      struct ip_tunnel_encap *ipencap)
9884565e991STom Herbert {
9894565e991STom Herbert 	bool ret = false;
9904565e991STom Herbert 
9914565e991STom Herbert 	memset(ipencap, 0, sizeof(*ipencap));
9924565e991STom Herbert 
9934565e991STom Herbert 	if (!data)
9944565e991STom Herbert 		return ret;
9954565e991STom Herbert 
9964565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_TYPE]) {
9974565e991STom Herbert 		ret = true;
9984565e991STom Herbert 		ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
9994565e991STom Herbert 	}
10004565e991STom Herbert 
10014565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_FLAGS]) {
10024565e991STom Herbert 		ret = true;
10034565e991STom Herbert 		ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
10044565e991STom Herbert 	}
10054565e991STom Herbert 
10064565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_SPORT]) {
10074565e991STom Herbert 		ret = true;
10083e97fa70SSabrina Dubroca 		ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
10094565e991STom Herbert 	}
10104565e991STom Herbert 
10114565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_DPORT]) {
10124565e991STom Herbert 		ret = true;
10133e97fa70SSabrina Dubroca 		ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
10144565e991STom Herbert 	}
10154565e991STom Herbert 
10164565e991STom Herbert 	return ret;
10174565e991STom Herbert }
10184565e991STom Herbert 
1019c5441932SPravin B Shelar static int gre_tap_init(struct net_device *dev)
1020e1a80002SHerbert Xu {
1021c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
1022bec94d43Sstephen hemminger 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1023e1a80002SHerbert Xu 
1024c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
1025e1a80002SHerbert Xu }
1026e1a80002SHerbert Xu 
1027c5441932SPravin B Shelar static const struct net_device_ops gre_tap_netdev_ops = {
1028c5441932SPravin B Shelar 	.ndo_init		= gre_tap_init,
1029c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
1030c5441932SPravin B Shelar 	.ndo_start_xmit		= gre_tap_xmit,
1031b8c26a33SStephen Hemminger 	.ndo_set_mac_address 	= eth_mac_addr,
1032b8c26a33SStephen Hemminger 	.ndo_validate_addr	= eth_validate_addr,
1033c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
1034c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
10351e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
1036b8c26a33SStephen Hemminger };
1037b8c26a33SStephen Hemminger 
1038e1a80002SHerbert Xu static void ipgre_tap_setup(struct net_device *dev)
1039e1a80002SHerbert Xu {
1040e1a80002SHerbert Xu 	ether_setup(dev);
1041c5441932SPravin B Shelar 	dev->netdev_ops		= &gre_tap_netdev_ops;
1042f8c1b7ceSstephen hemminger 	dev->priv_flags 	|= IFF_LIVE_ADDR_CHANGE;
1043c5441932SPravin B Shelar 	ip_tunnel_setup(dev, gre_tap_net_id);
1044e1a80002SHerbert Xu }
1045e1a80002SHerbert Xu 
1046c5441932SPravin B Shelar static int ipgre_newlink(struct net *src_net, struct net_device *dev,
1047c5441932SPravin B Shelar 			 struct nlattr *tb[], struct nlattr *data[])
1048c19e654dSHerbert Xu {
1049c5441932SPravin B Shelar 	struct ip_tunnel_parm p;
10504565e991STom Herbert 	struct ip_tunnel_encap ipencap;
10514565e991STom Herbert 
10524565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
10534565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
10544565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
10554565e991STom Herbert 
10564565e991STom Herbert 		if (err < 0)
10574565e991STom Herbert 			return err;
10584565e991STom Herbert 	}
1059c19e654dSHerbert Xu 
10602e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
1061c5441932SPravin B Shelar 	return ip_tunnel_newlink(dev, tb, &p);
1062c19e654dSHerbert Xu }
1063c19e654dSHerbert Xu 
1064c19e654dSHerbert Xu static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
1065c19e654dSHerbert Xu 			    struct nlattr *data[])
1066c19e654dSHerbert Xu {
1067c19e654dSHerbert Xu 	struct ip_tunnel_parm p;
10684565e991STom Herbert 	struct ip_tunnel_encap ipencap;
10694565e991STom Herbert 
10704565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
10714565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
10724565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
10734565e991STom Herbert 
10744565e991STom Herbert 		if (err < 0)
10754565e991STom Herbert 			return err;
10764565e991STom Herbert 	}
1077c19e654dSHerbert Xu 
10782e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
1079c5441932SPravin B Shelar 	return ip_tunnel_changelink(dev, tb, &p);
1080c19e654dSHerbert Xu }
1081c19e654dSHerbert Xu 
1082c19e654dSHerbert Xu static size_t ipgre_get_size(const struct net_device *dev)
1083c19e654dSHerbert Xu {
1084c19e654dSHerbert Xu 	return
1085c19e654dSHerbert Xu 		/* IFLA_GRE_LINK */
1086c19e654dSHerbert Xu 		nla_total_size(4) +
1087c19e654dSHerbert Xu 		/* IFLA_GRE_IFLAGS */
1088c19e654dSHerbert Xu 		nla_total_size(2) +
1089c19e654dSHerbert Xu 		/* IFLA_GRE_OFLAGS */
1090c19e654dSHerbert Xu 		nla_total_size(2) +
1091c19e654dSHerbert Xu 		/* IFLA_GRE_IKEY */
1092c19e654dSHerbert Xu 		nla_total_size(4) +
1093c19e654dSHerbert Xu 		/* IFLA_GRE_OKEY */
1094c19e654dSHerbert Xu 		nla_total_size(4) +
1095c19e654dSHerbert Xu 		/* IFLA_GRE_LOCAL */
1096c19e654dSHerbert Xu 		nla_total_size(4) +
1097c19e654dSHerbert Xu 		/* IFLA_GRE_REMOTE */
1098c19e654dSHerbert Xu 		nla_total_size(4) +
1099c19e654dSHerbert Xu 		/* IFLA_GRE_TTL */
1100c19e654dSHerbert Xu 		nla_total_size(1) +
1101c19e654dSHerbert Xu 		/* IFLA_GRE_TOS */
1102c19e654dSHerbert Xu 		nla_total_size(1) +
1103c19e654dSHerbert Xu 		/* IFLA_GRE_PMTUDISC */
1104c19e654dSHerbert Xu 		nla_total_size(1) +
11054565e991STom Herbert 		/* IFLA_GRE_ENCAP_TYPE */
11064565e991STom Herbert 		nla_total_size(2) +
11074565e991STom Herbert 		/* IFLA_GRE_ENCAP_FLAGS */
11084565e991STom Herbert 		nla_total_size(2) +
11094565e991STom Herbert 		/* IFLA_GRE_ENCAP_SPORT */
11104565e991STom Herbert 		nla_total_size(2) +
11114565e991STom Herbert 		/* IFLA_GRE_ENCAP_DPORT */
11124565e991STom Herbert 		nla_total_size(2) +
11132e15ea39SPravin B Shelar 		/* IFLA_GRE_COLLECT_METADATA */
11142e15ea39SPravin B Shelar 		nla_total_size(0) +
1115c19e654dSHerbert Xu 		0;
1116c19e654dSHerbert Xu }
1117c19e654dSHerbert Xu 
1118c19e654dSHerbert Xu static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1119c19e654dSHerbert Xu {
1120c19e654dSHerbert Xu 	struct ip_tunnel *t = netdev_priv(dev);
1121c19e654dSHerbert Xu 	struct ip_tunnel_parm *p = &t->parms;
1122c19e654dSHerbert Xu 
1123f3756b79SDavid S. Miller 	if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
1124c5441932SPravin B Shelar 	    nla_put_be16(skb, IFLA_GRE_IFLAGS, tnl_flags_to_gre_flags(p->i_flags)) ||
1125c5441932SPravin B Shelar 	    nla_put_be16(skb, IFLA_GRE_OFLAGS, tnl_flags_to_gre_flags(p->o_flags)) ||
1126f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1127f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1128930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1129930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
1130f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1131f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1132f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1133f3756b79SDavid S. Miller 		       !!(p->iph.frag_off & htons(IP_DF))))
1134f3756b79SDavid S. Miller 		goto nla_put_failure;
11354565e991STom Herbert 
11364565e991STom Herbert 	if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
11374565e991STom Herbert 			t->encap.type) ||
11383e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
11394565e991STom Herbert 			 t->encap.sport) ||
11403e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
11414565e991STom Herbert 			 t->encap.dport) ||
11424565e991STom Herbert 	    nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
1143e1b2cb65STom Herbert 			t->encap.flags))
11444565e991STom Herbert 		goto nla_put_failure;
11454565e991STom Herbert 
11462e15ea39SPravin B Shelar 	if (t->collect_md) {
11472e15ea39SPravin B Shelar 		if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
11482e15ea39SPravin B Shelar 			goto nla_put_failure;
11492e15ea39SPravin B Shelar 	}
11502e15ea39SPravin B Shelar 
1151c19e654dSHerbert Xu 	return 0;
1152c19e654dSHerbert Xu 
1153c19e654dSHerbert Xu nla_put_failure:
1154c19e654dSHerbert Xu 	return -EMSGSIZE;
1155c19e654dSHerbert Xu }
1156c19e654dSHerbert Xu 
1157c19e654dSHerbert Xu static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1158c19e654dSHerbert Xu 	[IFLA_GRE_LINK]		= { .type = NLA_U32 },
1159c19e654dSHerbert Xu 	[IFLA_GRE_IFLAGS]	= { .type = NLA_U16 },
1160c19e654dSHerbert Xu 	[IFLA_GRE_OFLAGS]	= { .type = NLA_U16 },
1161c19e654dSHerbert Xu 	[IFLA_GRE_IKEY]		= { .type = NLA_U32 },
1162c19e654dSHerbert Xu 	[IFLA_GRE_OKEY]		= { .type = NLA_U32 },
11634d74f8baSPatrick McHardy 	[IFLA_GRE_LOCAL]	= { .len = FIELD_SIZEOF(struct iphdr, saddr) },
11644d74f8baSPatrick McHardy 	[IFLA_GRE_REMOTE]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
1165c19e654dSHerbert Xu 	[IFLA_GRE_TTL]		= { .type = NLA_U8 },
1166c19e654dSHerbert Xu 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
1167c19e654dSHerbert Xu 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
11684565e991STom Herbert 	[IFLA_GRE_ENCAP_TYPE]	= { .type = NLA_U16 },
11694565e991STom Herbert 	[IFLA_GRE_ENCAP_FLAGS]	= { .type = NLA_U16 },
11704565e991STom Herbert 	[IFLA_GRE_ENCAP_SPORT]	= { .type = NLA_U16 },
11714565e991STom Herbert 	[IFLA_GRE_ENCAP_DPORT]	= { .type = NLA_U16 },
11722e15ea39SPravin B Shelar 	[IFLA_GRE_COLLECT_METADATA]	= { .type = NLA_FLAG },
1173c19e654dSHerbert Xu };
1174c19e654dSHerbert Xu 
1175c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1176c19e654dSHerbert Xu 	.kind		= "gre",
1177c19e654dSHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1178c19e654dSHerbert Xu 	.policy		= ipgre_policy,
1179c19e654dSHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1180c19e654dSHerbert Xu 	.setup		= ipgre_tunnel_setup,
1181c19e654dSHerbert Xu 	.validate	= ipgre_tunnel_validate,
1182c19e654dSHerbert Xu 	.newlink	= ipgre_newlink,
1183c19e654dSHerbert Xu 	.changelink	= ipgre_changelink,
1184c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1185c19e654dSHerbert Xu 	.get_size	= ipgre_get_size,
1186c19e654dSHerbert Xu 	.fill_info	= ipgre_fill_info,
11871728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1188c19e654dSHerbert Xu };
1189c19e654dSHerbert Xu 
1190e1a80002SHerbert Xu static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1191e1a80002SHerbert Xu 	.kind		= "gretap",
1192e1a80002SHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1193e1a80002SHerbert Xu 	.policy		= ipgre_policy,
1194e1a80002SHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1195e1a80002SHerbert Xu 	.setup		= ipgre_tap_setup,
1196e1a80002SHerbert Xu 	.validate	= ipgre_tap_validate,
1197e1a80002SHerbert Xu 	.newlink	= ipgre_newlink,
1198e1a80002SHerbert Xu 	.changelink	= ipgre_changelink,
1199c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1200e1a80002SHerbert Xu 	.get_size	= ipgre_get_size,
1201e1a80002SHerbert Xu 	.fill_info	= ipgre_fill_info,
12021728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1203e1a80002SHerbert Xu };
1204e1a80002SHerbert Xu 
1205b2acd1dcSPravin B Shelar struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1206b2acd1dcSPravin B Shelar 					u8 name_assign_type)
1207b2acd1dcSPravin B Shelar {
1208b2acd1dcSPravin B Shelar 	struct nlattr *tb[IFLA_MAX + 1];
1209b2acd1dcSPravin B Shelar 	struct net_device *dev;
1210b2acd1dcSPravin B Shelar 	struct ip_tunnel *t;
1211b2acd1dcSPravin B Shelar 	int err;
1212b2acd1dcSPravin B Shelar 
1213b2acd1dcSPravin B Shelar 	memset(&tb, 0, sizeof(tb));
1214b2acd1dcSPravin B Shelar 
1215b2acd1dcSPravin B Shelar 	dev = rtnl_create_link(net, name, name_assign_type,
1216b2acd1dcSPravin B Shelar 			       &ipgre_tap_ops, tb);
1217b2acd1dcSPravin B Shelar 	if (IS_ERR(dev))
1218b2acd1dcSPravin B Shelar 		return dev;
1219b2acd1dcSPravin B Shelar 
1220b2acd1dcSPravin B Shelar 	/* Configure flow based GRE device. */
1221b2acd1dcSPravin B Shelar 	t = netdev_priv(dev);
1222b2acd1dcSPravin B Shelar 	t->collect_md = true;
1223b2acd1dcSPravin B Shelar 
1224b2acd1dcSPravin B Shelar 	err = ipgre_newlink(net, dev, tb, NULL);
1225b2acd1dcSPravin B Shelar 	if (err < 0)
1226b2acd1dcSPravin B Shelar 		goto out;
1227b2acd1dcSPravin B Shelar 	return dev;
1228b2acd1dcSPravin B Shelar out:
1229b2acd1dcSPravin B Shelar 	free_netdev(dev);
1230b2acd1dcSPravin B Shelar 	return ERR_PTR(err);
1231b2acd1dcSPravin B Shelar }
1232b2acd1dcSPravin B Shelar EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1233b2acd1dcSPravin B Shelar 
1234c5441932SPravin B Shelar static int __net_init ipgre_tap_init_net(struct net *net)
1235c5441932SPravin B Shelar {
12362e15ea39SPravin B Shelar 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
1237c5441932SPravin B Shelar }
1238c5441932SPravin B Shelar 
1239c5441932SPravin B Shelar static void __net_exit ipgre_tap_exit_net(struct net *net)
1240c5441932SPravin B Shelar {
1241c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
12426c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_tap_ops);
1243c5441932SPravin B Shelar }
1244c5441932SPravin B Shelar 
1245c5441932SPravin B Shelar static struct pernet_operations ipgre_tap_net_ops = {
1246c5441932SPravin B Shelar 	.init = ipgre_tap_init_net,
1247c5441932SPravin B Shelar 	.exit = ipgre_tap_exit_net,
1248c5441932SPravin B Shelar 	.id   = &gre_tap_net_id,
1249c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
1250c5441932SPravin B Shelar };
12511da177e4SLinus Torvalds 
12521da177e4SLinus Torvalds static int __init ipgre_init(void)
12531da177e4SLinus Torvalds {
12541da177e4SLinus Torvalds 	int err;
12551da177e4SLinus Torvalds 
1256058bd4d2SJoe Perches 	pr_info("GRE over IPv4 tunneling driver\n");
12571da177e4SLinus Torvalds 
1258cfb8fbf2SEric W. Biederman 	err = register_pernet_device(&ipgre_net_ops);
125959a4c759SPavel Emelyanov 	if (err < 0)
1260c2892f02SAlexey Dobriyan 		return err;
1261c2892f02SAlexey Dobriyan 
1262c5441932SPravin B Shelar 	err = register_pernet_device(&ipgre_tap_net_ops);
1263c5441932SPravin B Shelar 	if (err < 0)
1264c5441932SPravin B Shelar 		goto pnet_tap_faied;
1265c5441932SPravin B Shelar 
1266*9f57c67cSPravin B Shelar 	err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
1267c2892f02SAlexey Dobriyan 	if (err < 0) {
1268058bd4d2SJoe Perches 		pr_info("%s: can't add protocol\n", __func__);
1269c2892f02SAlexey Dobriyan 		goto add_proto_failed;
1270c2892f02SAlexey Dobriyan 	}
12717daa0004SPavel Emelyanov 
1272c19e654dSHerbert Xu 	err = rtnl_link_register(&ipgre_link_ops);
1273c19e654dSHerbert Xu 	if (err < 0)
1274c19e654dSHerbert Xu 		goto rtnl_link_failed;
1275c19e654dSHerbert Xu 
1276e1a80002SHerbert Xu 	err = rtnl_link_register(&ipgre_tap_ops);
1277e1a80002SHerbert Xu 	if (err < 0)
1278e1a80002SHerbert Xu 		goto tap_ops_failed;
1279e1a80002SHerbert Xu 
1280c5441932SPravin B Shelar 	return 0;
1281c19e654dSHerbert Xu 
1282e1a80002SHerbert Xu tap_ops_failed:
1283e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
1284c19e654dSHerbert Xu rtnl_link_failed:
1285*9f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1286c2892f02SAlexey Dobriyan add_proto_failed:
1287c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1288c5441932SPravin B Shelar pnet_tap_faied:
1289c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
1290c5441932SPravin B Shelar 	return err;
12911da177e4SLinus Torvalds }
12921da177e4SLinus Torvalds 
1293db44575fSAlexey Kuznetsov static void __exit ipgre_fini(void)
12941da177e4SLinus Torvalds {
1295e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_tap_ops);
1296c19e654dSHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
1297*9f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1298c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1299c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
13001da177e4SLinus Torvalds }
13011da177e4SLinus Torvalds 
13021da177e4SLinus Torvalds module_init(ipgre_init);
13031da177e4SLinus Torvalds module_exit(ipgre_fini);
13041da177e4SLinus Torvalds MODULE_LICENSE("GPL");
13054d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gre");
13064d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gretap");
13078909c9adSVasiliy Kulikov MODULE_ALIAS_NETDEV("gre0");
1308c5441932SPravin B Shelar MODULE_ALIAS_NETDEV("gretap0");
1309