xref: /linux/net/ipv4/ip_gre.c (revision aed069df099cd1a27900acb56bb892ec24c66ac4)
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>
272e15ea39SPravin B Shelar #include <linux/if_vlan.h>
281da177e4SLinus Torvalds #include <linux/init.h>
291da177e4SLinus Torvalds #include <linux/in6.h>
301da177e4SLinus Torvalds #include <linux/inetdevice.h>
311da177e4SLinus Torvalds #include <linux/igmp.h>
321da177e4SLinus Torvalds #include <linux/netfilter_ipv4.h>
33e1a80002SHerbert Xu #include <linux/etherdevice.h>
3446f25dffSKris Katterjohn #include <linux/if_ether.h>
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds #include <net/sock.h>
371da177e4SLinus Torvalds #include <net/ip.h>
381da177e4SLinus Torvalds #include <net/icmp.h>
391da177e4SLinus Torvalds #include <net/protocol.h>
40c5441932SPravin B Shelar #include <net/ip_tunnels.h>
411da177e4SLinus Torvalds #include <net/arp.h>
421da177e4SLinus Torvalds #include <net/checksum.h>
431da177e4SLinus Torvalds #include <net/dsfield.h>
441da177e4SLinus Torvalds #include <net/inet_ecn.h>
451da177e4SLinus Torvalds #include <net/xfrm.h>
4659a4c759SPavel Emelyanov #include <net/net_namespace.h>
4759a4c759SPavel Emelyanov #include <net/netns/generic.h>
48c19e654dSHerbert Xu #include <net/rtnetlink.h>
4900959adeSDmitry Kozlov #include <net/gre.h>
502e15ea39SPravin B Shelar #include <net/dst_metadata.h>
511da177e4SLinus Torvalds 
52dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
531da177e4SLinus Torvalds #include <net/ipv6.h>
541da177e4SLinus Torvalds #include <net/ip6_fib.h>
551da177e4SLinus Torvalds #include <net/ip6_route.h>
561da177e4SLinus Torvalds #endif
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /*
591da177e4SLinus Torvalds    Problems & solutions
601da177e4SLinus Torvalds    --------------------
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds    1. The most important issue is detecting local dead loops.
631da177e4SLinus Torvalds    They would cause complete host lockup in transmit, which
641da177e4SLinus Torvalds    would be "resolved" by stack overflow or, if queueing is enabled,
651da177e4SLinus Torvalds    with infinite looping in net_bh.
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds    We cannot track such dead loops during route installation,
681da177e4SLinus Torvalds    it is infeasible task. The most general solutions would be
691da177e4SLinus Torvalds    to keep skb->encapsulation counter (sort of local ttl),
706d0722a2SEric Dumazet    and silently drop packet when it expires. It is a good
71bff52857Sstephen hemminger    solution, but it supposes maintaining new variable in ALL
721da177e4SLinus Torvalds    skb, even if no tunneling is used.
731da177e4SLinus Torvalds 
746d0722a2SEric Dumazet    Current solution: xmit_recursion breaks dead loops. This is a percpu
756d0722a2SEric Dumazet    counter, since when we enter the first ndo_xmit(), cpu migration is
766d0722a2SEric Dumazet    forbidden. We force an exit if this counter reaches RECURSION_LIMIT
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds    2. Networking dead loops would not kill routers, but would really
791da177e4SLinus Torvalds    kill network. IP hop limit plays role of "t->recursion" in this case,
801da177e4SLinus Torvalds    if we copy it from packet being encapsulated to upper header.
811da177e4SLinus Torvalds    It is very good solution, but it introduces two problems:
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds    - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
841da177e4SLinus Torvalds      do not work over tunnels.
851da177e4SLinus Torvalds    - traceroute does not work. I planned to relay ICMP from tunnel,
861da177e4SLinus Torvalds      so that this problem would be solved and traceroute output
871da177e4SLinus Torvalds      would even more informative. This idea appeared to be wrong:
881da177e4SLinus Torvalds      only Linux complies to rfc1812 now (yes, guys, Linux is the only
891da177e4SLinus Torvalds      true router now :-)), all routers (at least, in neighbourhood of mine)
901da177e4SLinus Torvalds      return only 8 bytes of payload. It is the end.
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds    Hence, if we want that OSPF worked or traceroute said something reasonable,
931da177e4SLinus Torvalds    we should search for another solution.
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds    One of them is to parse packet trying to detect inner encapsulation
961da177e4SLinus Torvalds    made by our node. It is difficult or even impossible, especially,
97bff52857Sstephen hemminger    taking into account fragmentation. TO be short, ttl is not solution at all.
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds    Current solution: The solution was UNEXPECTEDLY SIMPLE.
1001da177e4SLinus Torvalds    We force DF flag on tunnels with preconfigured hop limit,
1011da177e4SLinus Torvalds    that is ALL. :-) Well, it does not remove the problem completely,
1021da177e4SLinus Torvalds    but exponential growth of network traffic is changed to linear
1031da177e4SLinus Torvalds    (branches, that exceed pmtu are pruned) and tunnel mtu
104bff52857Sstephen hemminger    rapidly degrades to value <68, where looping stops.
1051da177e4SLinus Torvalds    Yes, it is not good if there exists a router in the loop,
1061da177e4SLinus Torvalds    which does not force DF, even when encapsulating packets have DF set.
1071da177e4SLinus Torvalds    But it is not our problem! Nobody could accuse us, we made
1081da177e4SLinus Torvalds    all that we could make. Even if it is your gated who injected
1091da177e4SLinus Torvalds    fatal route to network, even if it were you who configured
1101da177e4SLinus Torvalds    fatal static route: you are innocent. :-)
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds    Alexey Kuznetsov.
1131da177e4SLinus Torvalds  */
1141da177e4SLinus Torvalds 
115eccc1bb8Sstephen hemminger static bool log_ecn_error = true;
116eccc1bb8Sstephen hemminger module_param(log_ecn_error, bool, 0644);
117eccc1bb8Sstephen hemminger MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
118eccc1bb8Sstephen hemminger 
119c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly;
1201da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev);
121eb8ce741SPavel Emelyanov 
122f99189b1SEric Dumazet static int ipgre_net_id __read_mostly;
123c5441932SPravin B Shelar static int gre_tap_net_id __read_mostly;
124eb8ce741SPavel Emelyanov 
1259f57c67cSPravin B Shelar static int ip_gre_calc_hlen(__be16 o_flags)
1269f57c67cSPravin B Shelar {
1279f57c67cSPravin B Shelar 	int addend = 4;
1289f57c67cSPravin B Shelar 
1299f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_CSUM)
1309f57c67cSPravin B Shelar 		addend += 4;
1319f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_KEY)
1329f57c67cSPravin B Shelar 		addend += 4;
1339f57c67cSPravin B Shelar 	if (o_flags & TUNNEL_SEQ)
1349f57c67cSPravin B Shelar 		addend += 4;
1359f57c67cSPravin B Shelar 	return addend;
1369f57c67cSPravin B Shelar }
1379f57c67cSPravin B Shelar 
1389f57c67cSPravin B Shelar static __be16 gre_flags_to_tnl_flags(__be16 flags)
1399f57c67cSPravin B Shelar {
1409f57c67cSPravin B Shelar 	__be16 tflags = 0;
1419f57c67cSPravin B Shelar 
1429f57c67cSPravin B Shelar 	if (flags & GRE_CSUM)
1439f57c67cSPravin B Shelar 		tflags |= TUNNEL_CSUM;
1449f57c67cSPravin B Shelar 	if (flags & GRE_ROUTING)
1459f57c67cSPravin B Shelar 		tflags |= TUNNEL_ROUTING;
1469f57c67cSPravin B Shelar 	if (flags & GRE_KEY)
1479f57c67cSPravin B Shelar 		tflags |= TUNNEL_KEY;
1489f57c67cSPravin B Shelar 	if (flags & GRE_SEQ)
1499f57c67cSPravin B Shelar 		tflags |= TUNNEL_SEQ;
1509f57c67cSPravin B Shelar 	if (flags & GRE_STRICT)
1519f57c67cSPravin B Shelar 		tflags |= TUNNEL_STRICT;
1529f57c67cSPravin B Shelar 	if (flags & GRE_REC)
1539f57c67cSPravin B Shelar 		tflags |= TUNNEL_REC;
1549f57c67cSPravin B Shelar 	if (flags & GRE_VERSION)
1559f57c67cSPravin B Shelar 		tflags |= TUNNEL_VERSION;
1569f57c67cSPravin B Shelar 
1579f57c67cSPravin B Shelar 	return tflags;
1589f57c67cSPravin B Shelar }
1599f57c67cSPravin B Shelar 
1609f57c67cSPravin B Shelar static __be16 tnl_flags_to_gre_flags(__be16 tflags)
1619f57c67cSPravin B Shelar {
1629f57c67cSPravin B Shelar 	__be16 flags = 0;
1639f57c67cSPravin B Shelar 
1649f57c67cSPravin B Shelar 	if (tflags & TUNNEL_CSUM)
1659f57c67cSPravin B Shelar 		flags |= GRE_CSUM;
1669f57c67cSPravin B Shelar 	if (tflags & TUNNEL_ROUTING)
1679f57c67cSPravin B Shelar 		flags |= GRE_ROUTING;
1689f57c67cSPravin B Shelar 	if (tflags & TUNNEL_KEY)
1699f57c67cSPravin B Shelar 		flags |= GRE_KEY;
1709f57c67cSPravin B Shelar 	if (tflags & TUNNEL_SEQ)
1719f57c67cSPravin B Shelar 		flags |= GRE_SEQ;
1729f57c67cSPravin B Shelar 	if (tflags & TUNNEL_STRICT)
1739f57c67cSPravin B Shelar 		flags |= GRE_STRICT;
1749f57c67cSPravin B Shelar 	if (tflags & TUNNEL_REC)
1759f57c67cSPravin B Shelar 		flags |= GRE_REC;
1769f57c67cSPravin B Shelar 	if (tflags & TUNNEL_VERSION)
1779f57c67cSPravin B Shelar 		flags |= GRE_VERSION;
1789f57c67cSPravin B Shelar 
1799f57c67cSPravin B Shelar 	return flags;
1809f57c67cSPravin B Shelar }
1819f57c67cSPravin B Shelar 
1829f57c67cSPravin B Shelar static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
1839f57c67cSPravin B Shelar 			    bool *csum_err)
1849f57c67cSPravin B Shelar {
1859f57c67cSPravin B Shelar 	const struct gre_base_hdr *greh;
1869f57c67cSPravin B Shelar 	__be32 *options;
1879f57c67cSPravin B Shelar 	int hdr_len;
1889f57c67cSPravin B Shelar 
1899f57c67cSPravin B Shelar 	if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
1909f57c67cSPravin B Shelar 		return -EINVAL;
1919f57c67cSPravin B Shelar 
1929f57c67cSPravin B Shelar 	greh = (struct gre_base_hdr *)skb_transport_header(skb);
1939f57c67cSPravin B Shelar 	if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
1949f57c67cSPravin B Shelar 		return -EINVAL;
1959f57c67cSPravin B Shelar 
1969f57c67cSPravin B Shelar 	tpi->flags = gre_flags_to_tnl_flags(greh->flags);
1979f57c67cSPravin B Shelar 	hdr_len = ip_gre_calc_hlen(tpi->flags);
1989f57c67cSPravin B Shelar 
1999f57c67cSPravin B Shelar 	if (!pskb_may_pull(skb, hdr_len))
2009f57c67cSPravin B Shelar 		return -EINVAL;
2019f57c67cSPravin B Shelar 
2029f57c67cSPravin B Shelar 	greh = (struct gre_base_hdr *)skb_transport_header(skb);
2039f57c67cSPravin B Shelar 	tpi->proto = greh->protocol;
2049f57c67cSPravin B Shelar 
2059f57c67cSPravin B Shelar 	options = (__be32 *)(greh + 1);
2069f57c67cSPravin B Shelar 	if (greh->flags & GRE_CSUM) {
2079f57c67cSPravin B Shelar 		if (skb_checksum_simple_validate(skb)) {
2089f57c67cSPravin B Shelar 			*csum_err = true;
2099f57c67cSPravin B Shelar 			return -EINVAL;
2109f57c67cSPravin B Shelar 		}
2119f57c67cSPravin B Shelar 
2129f57c67cSPravin B Shelar 		skb_checksum_try_convert(skb, IPPROTO_GRE, 0,
2139f57c67cSPravin B Shelar 					 null_compute_pseudo);
2149f57c67cSPravin B Shelar 		options++;
2159f57c67cSPravin B Shelar 	}
2169f57c67cSPravin B Shelar 
2179f57c67cSPravin B Shelar 	if (greh->flags & GRE_KEY) {
2189f57c67cSPravin B Shelar 		tpi->key = *options;
2199f57c67cSPravin B Shelar 		options++;
2209f57c67cSPravin B Shelar 	} else {
2219f57c67cSPravin B Shelar 		tpi->key = 0;
2229f57c67cSPravin B Shelar 	}
2239f57c67cSPravin B Shelar 	if (unlikely(greh->flags & GRE_SEQ)) {
2249f57c67cSPravin B Shelar 		tpi->seq = *options;
2259f57c67cSPravin B Shelar 		options++;
2269f57c67cSPravin B Shelar 	} else {
2279f57c67cSPravin B Shelar 		tpi->seq = 0;
2289f57c67cSPravin B Shelar 	}
2299f57c67cSPravin B Shelar 	/* WCCP version 1 and 2 protocol decoding.
2309f57c67cSPravin B Shelar 	 * - Change protocol to IP
2319f57c67cSPravin B Shelar 	 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
2329f57c67cSPravin B Shelar 	 */
2339f57c67cSPravin B Shelar 	if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
2349f57c67cSPravin B Shelar 		tpi->proto = htons(ETH_P_IP);
2359f57c67cSPravin B Shelar 		if ((*(u8 *)options & 0xF0) != 0x40) {
2369f57c67cSPravin B Shelar 			hdr_len += 4;
2379f57c67cSPravin B Shelar 			if (!pskb_may_pull(skb, hdr_len))
2389f57c67cSPravin B Shelar 				return -EINVAL;
2399f57c67cSPravin B Shelar 		}
2409f57c67cSPravin B Shelar 	}
2417f290c94SJiri Benc 	return iptunnel_pull_header(skb, hdr_len, tpi->proto, false);
2429f57c67cSPravin B Shelar }
2439f57c67cSPravin B Shelar 
2449f57c67cSPravin B Shelar static void ipgre_err(struct sk_buff *skb, u32 info,
245bda7bb46SPravin B Shelar 		      const struct tnl_ptk_info *tpi)
2461da177e4SLinus Torvalds {
2471da177e4SLinus Torvalds 
248071f92d0SRami Rosen 	/* All the routers (except for Linux) return only
2491da177e4SLinus Torvalds 	   8 bytes of packet payload. It means, that precise relaying of
2501da177e4SLinus Torvalds 	   ICMP in the real Internet is absolutely infeasible.
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	   Moreover, Cisco "wise men" put GRE key to the third word
253c5441932SPravin B Shelar 	   in GRE header. It makes impossible maintaining even soft
254c5441932SPravin B Shelar 	   state for keyed GRE tunnels with enabled checksum. Tell
255c5441932SPravin B Shelar 	   them "thank you".
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	   Well, I wonder, rfc1812 was written by Cisco employee,
258bff52857Sstephen hemminger 	   what the hell these idiots break standards established
259bff52857Sstephen hemminger 	   by themselves???
2601da177e4SLinus Torvalds 	   */
261c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
262c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
26396f5a846SEric Dumazet 	const struct iphdr *iph;
26488c7664fSArnaldo Carvalho de Melo 	const int type = icmp_hdr(skb)->type;
26588c7664fSArnaldo Carvalho de Melo 	const int code = icmp_hdr(skb)->code;
2661da177e4SLinus Torvalds 	struct ip_tunnel *t;
267d2083287Sstephen hemminger 
2681da177e4SLinus Torvalds 	switch (type) {
2691da177e4SLinus Torvalds 	default:
2701da177e4SLinus Torvalds 	case ICMP_PARAMETERPROB:
2719f57c67cSPravin B Shelar 		return;
2721da177e4SLinus Torvalds 
2731da177e4SLinus Torvalds 	case ICMP_DEST_UNREACH:
2741da177e4SLinus Torvalds 		switch (code) {
2751da177e4SLinus Torvalds 		case ICMP_SR_FAILED:
2761da177e4SLinus Torvalds 		case ICMP_PORT_UNREACH:
2771da177e4SLinus Torvalds 			/* Impossible event. */
2789f57c67cSPravin B Shelar 			return;
2791da177e4SLinus Torvalds 		default:
2801da177e4SLinus Torvalds 			/* All others are translated to HOST_UNREACH.
2811da177e4SLinus Torvalds 			   rfc2003 contains "deep thoughts" about NET_UNREACH,
2821da177e4SLinus Torvalds 			   I believe they are just ether pollution. --ANK
2831da177e4SLinus Torvalds 			 */
2841da177e4SLinus Torvalds 			break;
2851da177e4SLinus Torvalds 		}
2861da177e4SLinus Torvalds 		break;
2879f57c67cSPravin B Shelar 
2881da177e4SLinus Torvalds 	case ICMP_TIME_EXCEEDED:
2891da177e4SLinus Torvalds 		if (code != ICMP_EXC_TTL)
2909f57c67cSPravin B Shelar 			return;
2911da177e4SLinus Torvalds 		break;
29255be7a9cSDavid S. Miller 
29355be7a9cSDavid S. Miller 	case ICMP_REDIRECT:
29455be7a9cSDavid S. Miller 		break;
2951da177e4SLinus Torvalds 	}
2961da177e4SLinus Torvalds 
297bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
298c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
299c5441932SPravin B Shelar 	else
300c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
301c5441932SPravin B Shelar 
302c0c0c50fSDuan Jiong 	iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
303bda7bb46SPravin B Shelar 	t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
304bda7bb46SPravin B Shelar 			     iph->daddr, iph->saddr, tpi->key);
305d2083287Sstephen hemminger 
30651456b29SIan Morris 	if (!t)
3079f57c67cSPravin B Shelar 		return;
30836393395SDavid S. Miller 
30936393395SDavid S. Miller 	if (t->parms.iph.daddr == 0 ||
310f97c1e0cSJoe Perches 	    ipv4_is_multicast(t->parms.iph.daddr))
3119f57c67cSPravin B Shelar 		return;
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds 	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
3149f57c67cSPravin B Shelar 		return;
3151da177e4SLinus Torvalds 
316da6185d8SWei Yongjun 	if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
3171da177e4SLinus Torvalds 		t->err_count++;
3181da177e4SLinus Torvalds 	else
3191da177e4SLinus Torvalds 		t->err_count = 1;
3201da177e4SLinus Torvalds 	t->err_time = jiffies;
3219f57c67cSPravin B Shelar }
3229f57c67cSPravin B Shelar 
3239f57c67cSPravin B Shelar static void gre_err(struct sk_buff *skb, u32 info)
3249f57c67cSPravin B Shelar {
3259f57c67cSPravin B Shelar 	/* All the routers (except for Linux) return only
3269f57c67cSPravin B Shelar 	 * 8 bytes of packet payload. It means, that precise relaying of
3279f57c67cSPravin B Shelar 	 * ICMP in the real Internet is absolutely infeasible.
3289f57c67cSPravin B Shelar 	 *
3299f57c67cSPravin B Shelar 	 * Moreover, Cisco "wise men" put GRE key to the third word
3309f57c67cSPravin B Shelar 	 * in GRE header. It makes impossible maintaining even soft
3319f57c67cSPravin B Shelar 	 * state for keyed
3329f57c67cSPravin B Shelar 	 * GRE tunnels with enabled checksum. Tell them "thank you".
3339f57c67cSPravin B Shelar 	 *
3349f57c67cSPravin B Shelar 	 * Well, I wonder, rfc1812 was written by Cisco employee,
3359f57c67cSPravin B Shelar 	 * what the hell these idiots break standards established
3369f57c67cSPravin B Shelar 	 * by themselves???
3379f57c67cSPravin B Shelar 	 */
3389f57c67cSPravin B Shelar 
3399f57c67cSPravin B Shelar 	const int type = icmp_hdr(skb)->type;
3409f57c67cSPravin B Shelar 	const int code = icmp_hdr(skb)->code;
3419f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
3429f57c67cSPravin B Shelar 	bool csum_err = false;
3439f57c67cSPravin B Shelar 
3449f57c67cSPravin B Shelar 	if (parse_gre_header(skb, &tpi, &csum_err)) {
3459f57c67cSPravin B Shelar 		if (!csum_err)		/* ignore csum errors. */
3469f57c67cSPravin B Shelar 			return;
3479f57c67cSPravin B Shelar 	}
3489f57c67cSPravin B Shelar 
3499f57c67cSPravin B Shelar 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
3509f57c67cSPravin B Shelar 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
3519f57c67cSPravin B Shelar 				 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
3529f57c67cSPravin B Shelar 		return;
3539f57c67cSPravin B Shelar 	}
3549f57c67cSPravin B Shelar 	if (type == ICMP_REDIRECT) {
3559f57c67cSPravin B Shelar 		ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
3569f57c67cSPravin B Shelar 			      IPPROTO_GRE, 0);
3579f57c67cSPravin B Shelar 		return;
3589f57c67cSPravin B Shelar 	}
3599f57c67cSPravin B Shelar 
3609f57c67cSPravin B Shelar 	ipgre_err(skb, info, &tpi);
3611da177e4SLinus Torvalds }
3621da177e4SLinus Torvalds 
3632e15ea39SPravin B Shelar static __be64 key_to_tunnel_id(__be32 key)
3642e15ea39SPravin B Shelar {
3652e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
3662e15ea39SPravin B Shelar 	return (__force __be64)((__force u32)key);
3672e15ea39SPravin B Shelar #else
3682e15ea39SPravin B Shelar 	return (__force __be64)((__force u64)key << 32);
3692e15ea39SPravin B Shelar #endif
3702e15ea39SPravin B Shelar }
3712e15ea39SPravin B Shelar 
3722e15ea39SPravin B Shelar /* Returns the least-significant 32 bits of a __be64. */
3732e15ea39SPravin B Shelar static __be32 tunnel_id_to_key(__be64 x)
3742e15ea39SPravin B Shelar {
3752e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
3762e15ea39SPravin B Shelar 	return (__force __be32)x;
3772e15ea39SPravin B Shelar #else
3782e15ea39SPravin B Shelar 	return (__force __be32)((__force u64)x >> 32);
3792e15ea39SPravin B Shelar #endif
3802e15ea39SPravin B Shelar }
3812e15ea39SPravin B Shelar 
382bda7bb46SPravin B Shelar static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
3831da177e4SLinus Torvalds {
384c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
3852e15ea39SPravin B Shelar 	struct metadata_dst *tun_dst = NULL;
386c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
387b71d1d42SEric Dumazet 	const struct iphdr *iph;
3881da177e4SLinus Torvalds 	struct ip_tunnel *tunnel;
3891da177e4SLinus Torvalds 
390bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
391c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
392c5441932SPravin B Shelar 	else
393c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
394c5441932SPravin B Shelar 
395eddc9ec5SArnaldo Carvalho de Melo 	iph = ip_hdr(skb);
396bda7bb46SPravin B Shelar 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
397bda7bb46SPravin B Shelar 				  iph->saddr, iph->daddr, tpi->key);
3981da177e4SLinus Torvalds 
399d2083287Sstephen hemminger 	if (tunnel) {
4000e3da5bbSTimo Teräs 		skb_pop_mac_header(skb);
4012e15ea39SPravin B Shelar 		if (tunnel->collect_md) {
402c29a70d2SPravin B Shelar 			__be16 flags;
403c29a70d2SPravin B Shelar 			__be64 tun_id;
4042e15ea39SPravin B Shelar 
405c29a70d2SPravin B Shelar 			flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
406c29a70d2SPravin B Shelar 			tun_id = key_to_tunnel_id(tpi->key);
407c29a70d2SPravin B Shelar 			tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
4082e15ea39SPravin B Shelar 			if (!tun_dst)
4092e15ea39SPravin B Shelar 				return PACKET_REJECT;
4102e15ea39SPravin B Shelar 		}
4112e15ea39SPravin B Shelar 
4122e15ea39SPravin B Shelar 		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
413bda7bb46SPravin B Shelar 		return PACKET_RCVD;
4141da177e4SLinus Torvalds 	}
415bda7bb46SPravin B Shelar 	return PACKET_REJECT;
4161da177e4SLinus Torvalds }
4171da177e4SLinus Torvalds 
4189f57c67cSPravin B Shelar static int gre_rcv(struct sk_buff *skb)
4199f57c67cSPravin B Shelar {
4209f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
4219f57c67cSPravin B Shelar 	bool csum_err = false;
4229f57c67cSPravin B Shelar 
4239f57c67cSPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
4249f57c67cSPravin B Shelar 	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
4259f57c67cSPravin B Shelar 		/* Looped back packet, drop it! */
4269f57c67cSPravin B Shelar 		if (rt_is_output_route(skb_rtable(skb)))
4279f57c67cSPravin B Shelar 			goto drop;
4289f57c67cSPravin B Shelar 	}
4299f57c67cSPravin B Shelar #endif
4309f57c67cSPravin B Shelar 
4319f57c67cSPravin B Shelar 	if (parse_gre_header(skb, &tpi, &csum_err) < 0)
4329f57c67cSPravin B Shelar 		goto drop;
4339f57c67cSPravin B Shelar 
4349f57c67cSPravin B Shelar 	if (ipgre_rcv(skb, &tpi) == PACKET_RCVD)
4359f57c67cSPravin B Shelar 		return 0;
4369f57c67cSPravin B Shelar 
4379f57c67cSPravin B Shelar 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
4389f57c67cSPravin B Shelar drop:
4399f57c67cSPravin B Shelar 	kfree_skb(skb);
4409f57c67cSPravin B Shelar 	return 0;
4419f57c67cSPravin B Shelar }
4429f57c67cSPravin B Shelar 
44353936107SEdward Cree static __sum16 gre_checksum(struct sk_buff *skb)
44453936107SEdward Cree {
44553936107SEdward Cree 	__wsum csum;
44653936107SEdward Cree 
44753936107SEdward Cree 	if (skb->ip_summed == CHECKSUM_PARTIAL)
44853936107SEdward Cree 		csum = lco_csum(skb);
44953936107SEdward Cree 	else
45053936107SEdward Cree 		csum = skb_checksum(skb, 0, skb->len, 0);
45153936107SEdward Cree 	return csum_fold(csum);
45253936107SEdward Cree }
45353936107SEdward Cree 
4542e15ea39SPravin B Shelar static void build_header(struct sk_buff *skb, int hdr_len, __be16 flags,
4552e15ea39SPravin B Shelar 			 __be16 proto, __be32 key, __be32 seq)
4562e15ea39SPravin B Shelar {
4572e15ea39SPravin B Shelar 	struct gre_base_hdr *greh;
4582e15ea39SPravin B Shelar 
4592e15ea39SPravin B Shelar 	skb_push(skb, hdr_len);
4602e15ea39SPravin B Shelar 
4612e15ea39SPravin B Shelar 	skb_reset_transport_header(skb);
4622e15ea39SPravin B Shelar 	greh = (struct gre_base_hdr *)skb->data;
4632e15ea39SPravin B Shelar 	greh->flags = tnl_flags_to_gre_flags(flags);
4642e15ea39SPravin B Shelar 	greh->protocol = proto;
4652e15ea39SPravin B Shelar 
4662e15ea39SPravin B Shelar 	if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
4672e15ea39SPravin B Shelar 		__be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
4682e15ea39SPravin B Shelar 
4692e15ea39SPravin B Shelar 		if (flags & TUNNEL_SEQ) {
4702e15ea39SPravin B Shelar 			*ptr = seq;
4712e15ea39SPravin B Shelar 			ptr--;
4722e15ea39SPravin B Shelar 		}
4732e15ea39SPravin B Shelar 		if (flags & TUNNEL_KEY) {
4742e15ea39SPravin B Shelar 			*ptr = key;
4752e15ea39SPravin B Shelar 			ptr--;
4762e15ea39SPravin B Shelar 		}
4772e15ea39SPravin B Shelar 		if (flags & TUNNEL_CSUM &&
4782e15ea39SPravin B Shelar 		    !(skb_shinfo(skb)->gso_type &
4792e15ea39SPravin B Shelar 		      (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
4802e15ea39SPravin B Shelar 			*ptr = 0;
48153936107SEdward Cree 			*(__sum16 *)ptr = gre_checksum(skb);
4822e15ea39SPravin B Shelar 		}
4832e15ea39SPravin B Shelar 	}
4842e15ea39SPravin B Shelar }
4852e15ea39SPravin B Shelar 
486c5441932SPravin B Shelar static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
487c5441932SPravin B Shelar 		       const struct iphdr *tnl_params,
488c5441932SPravin B Shelar 		       __be16 proto)
489c5441932SPravin B Shelar {
490c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
491c5441932SPravin B Shelar 
492c5441932SPravin B Shelar 	if (tunnel->parms.o_flags & TUNNEL_SEQ)
493c5441932SPravin B Shelar 		tunnel->o_seqno++;
494cef401deSEric Dumazet 
495c5441932SPravin B Shelar 	/* Push GRE header. */
4962e15ea39SPravin B Shelar 	build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
4972e15ea39SPravin B Shelar 		     proto, tunnel->parms.o_key, htonl(tunnel->o_seqno));
4981da177e4SLinus Torvalds 
4992e15ea39SPravin B Shelar 	skb_set_inner_protocol(skb, proto);
500bf3d6a8fSNicolas Dichtel 	ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
5011da177e4SLinus Torvalds }
5021da177e4SLinus Torvalds 
503*aed069dfSAlexander Duyck static int gre_handle_offloads(struct sk_buff *skb, bool csum)
504b2acd1dcSPravin B Shelar {
5056fa79666SEdward Cree 	return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
506b2acd1dcSPravin B Shelar }
507b2acd1dcSPravin B Shelar 
508fc4099f1SPravin B Shelar static struct rtable *gre_get_rt(struct sk_buff *skb,
509fc4099f1SPravin B Shelar 				 struct net_device *dev,
510fc4099f1SPravin B Shelar 				 struct flowi4 *fl,
511fc4099f1SPravin B Shelar 				 const struct ip_tunnel_key *key)
512fc4099f1SPravin B Shelar {
513fc4099f1SPravin B Shelar 	struct net *net = dev_net(dev);
514fc4099f1SPravin B Shelar 
515fc4099f1SPravin B Shelar 	memset(fl, 0, sizeof(*fl));
516fc4099f1SPravin B Shelar 	fl->daddr = key->u.ipv4.dst;
517fc4099f1SPravin B Shelar 	fl->saddr = key->u.ipv4.src;
518fc4099f1SPravin B Shelar 	fl->flowi4_tos = RT_TOS(key->tos);
519fc4099f1SPravin B Shelar 	fl->flowi4_mark = skb->mark;
520fc4099f1SPravin B Shelar 	fl->flowi4_proto = IPPROTO_GRE;
521fc4099f1SPravin B Shelar 
522fc4099f1SPravin B Shelar 	return ip_route_output_key(net, fl);
523fc4099f1SPravin B Shelar }
524fc4099f1SPravin B Shelar 
5252e15ea39SPravin B Shelar static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
5262e15ea39SPravin B Shelar {
5272e15ea39SPravin B Shelar 	struct ip_tunnel_info *tun_info;
5282e15ea39SPravin B Shelar 	const struct ip_tunnel_key *key;
529db3c6139SDaniel Borkmann 	struct rtable *rt = NULL;
5302e15ea39SPravin B Shelar 	struct flowi4 fl;
5312e15ea39SPravin B Shelar 	int min_headroom;
5322e15ea39SPravin B Shelar 	int tunnel_hlen;
5332e15ea39SPravin B Shelar 	__be16 df, flags;
534db3c6139SDaniel Borkmann 	bool use_cache;
5352e15ea39SPravin B Shelar 	int err;
5362e15ea39SPravin B Shelar 
53761adedf3SJiri Benc 	tun_info = skb_tunnel_info(skb);
5387f9562a1SJiri Benc 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
5397f9562a1SJiri Benc 		     ip_tunnel_info_af(tun_info) != AF_INET))
5402e15ea39SPravin B Shelar 		goto err_free_skb;
5412e15ea39SPravin B Shelar 
5422e15ea39SPravin B Shelar 	key = &tun_info->key;
543db3c6139SDaniel Borkmann 	use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
544db3c6139SDaniel Borkmann 	if (use_cache)
545db3c6139SDaniel Borkmann 		rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
5463c1cb4d2SPaolo Abeni 	if (!rt) {
547fc4099f1SPravin B Shelar 		rt = gre_get_rt(skb, dev, &fl, key);
5482e15ea39SPravin B Shelar 		if (IS_ERR(rt))
5492e15ea39SPravin B Shelar 				goto err_free_skb;
550db3c6139SDaniel Borkmann 		if (use_cache)
5513c1cb4d2SPaolo Abeni 			dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
5523c1cb4d2SPaolo Abeni 					  fl.saddr);
5533c1cb4d2SPaolo Abeni 	}
5542e15ea39SPravin B Shelar 
5552e15ea39SPravin B Shelar 	tunnel_hlen = ip_gre_calc_hlen(key->tun_flags);
5562e15ea39SPravin B Shelar 
5572e15ea39SPravin B Shelar 	min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
5582e15ea39SPravin B Shelar 			+ tunnel_hlen + sizeof(struct iphdr);
5592e15ea39SPravin B Shelar 	if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
5602e15ea39SPravin B Shelar 		int head_delta = SKB_DATA_ALIGN(min_headroom -
5612e15ea39SPravin B Shelar 						skb_headroom(skb) +
5622e15ea39SPravin B Shelar 						16);
5632e15ea39SPravin B Shelar 		err = pskb_expand_head(skb, max_t(int, head_delta, 0),
5642e15ea39SPravin B Shelar 				       0, GFP_ATOMIC);
5652e15ea39SPravin B Shelar 		if (unlikely(err))
5662e15ea39SPravin B Shelar 			goto err_free_rt;
5672e15ea39SPravin B Shelar 	}
5682e15ea39SPravin B Shelar 
5692e15ea39SPravin B Shelar 	/* Push Tunnel header. */
570*aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
5712e15ea39SPravin B Shelar 		goto err_free_rt;
5722e15ea39SPravin B Shelar 
5732e15ea39SPravin B Shelar 	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
5742e15ea39SPravin B Shelar 	build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
5752e15ea39SPravin B Shelar 		     tunnel_id_to_key(tun_info->key.tun_id), 0);
5762e15ea39SPravin B Shelar 
5772e15ea39SPravin B Shelar 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
578039f5062SPravin B Shelar 
579039f5062SPravin B Shelar 	iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
5807c383fb2SJiri Benc 		      key->tos, key->ttl, df, false);
5812e15ea39SPravin B Shelar 	return;
5822e15ea39SPravin B Shelar 
5832e15ea39SPravin B Shelar err_free_rt:
5842e15ea39SPravin B Shelar 	ip_rt_put(rt);
5852e15ea39SPravin B Shelar err_free_skb:
5862e15ea39SPravin B Shelar 	kfree_skb(skb);
5872e15ea39SPravin B Shelar 	dev->stats.tx_dropped++;
5882e15ea39SPravin B Shelar }
5892e15ea39SPravin B Shelar 
590fc4099f1SPravin B Shelar static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
591fc4099f1SPravin B Shelar {
592fc4099f1SPravin B Shelar 	struct ip_tunnel_info *info = skb_tunnel_info(skb);
593fc4099f1SPravin B Shelar 	struct rtable *rt;
594fc4099f1SPravin B Shelar 	struct flowi4 fl4;
595fc4099f1SPravin B Shelar 
596fc4099f1SPravin B Shelar 	if (ip_tunnel_info_af(info) != AF_INET)
597fc4099f1SPravin B Shelar 		return -EINVAL;
598fc4099f1SPravin B Shelar 
599fc4099f1SPravin B Shelar 	rt = gre_get_rt(skb, dev, &fl4, &info->key);
600fc4099f1SPravin B Shelar 	if (IS_ERR(rt))
601fc4099f1SPravin B Shelar 		return PTR_ERR(rt);
602fc4099f1SPravin B Shelar 
603fc4099f1SPravin B Shelar 	ip_rt_put(rt);
604fc4099f1SPravin B Shelar 	info->key.u.ipv4.src = fl4.saddr;
605fc4099f1SPravin B Shelar 	return 0;
606fc4099f1SPravin B Shelar }
607fc4099f1SPravin B Shelar 
608c5441932SPravin B Shelar static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
609c5441932SPravin B Shelar 			      struct net_device *dev)
610ee34c1ebSMichal Schmidt {
611c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
612c5441932SPravin B Shelar 	const struct iphdr *tnl_params;
613ee34c1ebSMichal Schmidt 
6142e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
6152e15ea39SPravin B Shelar 		gre_fb_xmit(skb, dev);
6162e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
6172e15ea39SPravin B Shelar 	}
6182e15ea39SPravin B Shelar 
619c5441932SPravin B Shelar 	if (dev->header_ops) {
620c5441932SPravin B Shelar 		/* Need space for new headers */
621c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom -
6222bac7cb3SChen Gang 				      (tunnel->hlen + sizeof(struct iphdr))))
623c5441932SPravin B Shelar 			goto free_skb;
624ee34c1ebSMichal Schmidt 
625c5441932SPravin B Shelar 		tnl_params = (const struct iphdr *)skb->data;
626cbb1e85fSDavid S. Miller 
627c5441932SPravin B Shelar 		/* Pull skb since ip_tunnel_xmit() needs skb->data pointing
628c5441932SPravin B Shelar 		 * to gre header.
629c5441932SPravin B Shelar 		 */
630c5441932SPravin B Shelar 		skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
6318a0033a9STimo Teräs 		skb_reset_mac_header(skb);
632c5441932SPravin B Shelar 	} else {
633c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom))
634c5441932SPravin B Shelar 			goto free_skb;
635c5441932SPravin B Shelar 
636c5441932SPravin B Shelar 		tnl_params = &tunnel->parms.iph;
637ee34c1ebSMichal Schmidt 	}
638e1a80002SHerbert Xu 
639*aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
640*aed069dfSAlexander Duyck 		goto free_skb;
6418a0033a9STimo Teräs 
642c5441932SPravin B Shelar 	__gre_xmit(skb, dev, tnl_params, skb->protocol);
643c5441932SPravin B Shelar 	return NETDEV_TX_OK;
644c5441932SPravin B Shelar 
645c5441932SPravin B Shelar free_skb:
6463acfa1e7SEric Dumazet 	kfree_skb(skb);
647c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
648c5441932SPravin B Shelar 	return NETDEV_TX_OK;
649ee34c1ebSMichal Schmidt }
650ee34c1ebSMichal Schmidt 
651c5441932SPravin B Shelar static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
652c5441932SPravin B Shelar 				struct net_device *dev)
653c5441932SPravin B Shelar {
654c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
655ee34c1ebSMichal Schmidt 
6562e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
6572e15ea39SPravin B Shelar 		gre_fb_xmit(skb, dev);
6582e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
6592e15ea39SPravin B Shelar 	}
6602e15ea39SPravin B Shelar 
661*aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
662*aed069dfSAlexander Duyck 		goto free_skb;
663ee34c1ebSMichal Schmidt 
664c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom))
665c5441932SPravin B Shelar 		goto free_skb;
66642aa9162SHerbert Xu 
667c5441932SPravin B Shelar 	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
668c5441932SPravin B Shelar 	return NETDEV_TX_OK;
669c5441932SPravin B Shelar 
670c5441932SPravin B Shelar free_skb:
6713acfa1e7SEric Dumazet 	kfree_skb(skb);
672c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
673c5441932SPravin B Shelar 	return NETDEV_TX_OK;
67468c33163SPravin B Shelar }
675ee34c1ebSMichal Schmidt 
676c5441932SPravin B Shelar static int ipgre_tunnel_ioctl(struct net_device *dev,
677c5441932SPravin B Shelar 			      struct ifreq *ifr, int cmd)
6781da177e4SLinus Torvalds {
6794565e991STom Herbert 	int err;
6801da177e4SLinus Torvalds 	struct ip_tunnel_parm p;
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
683c5441932SPravin B Shelar 		return -EFAULT;
6846c734fb8SCong Wang 	if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
6851da177e4SLinus Torvalds 		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
6861da177e4SLinus Torvalds 		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
6876c734fb8SCong Wang 		    ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
6881da177e4SLinus Torvalds 			return -EINVAL;
689c5441932SPravin B Shelar 	}
690c5441932SPravin B Shelar 	p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
691c5441932SPravin B Shelar 	p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
692c5441932SPravin B Shelar 
693c5441932SPravin B Shelar 	err = ip_tunnel_ioctl(dev, &p, cmd);
694c5441932SPravin B Shelar 	if (err)
695c5441932SPravin B Shelar 		return err;
696c5441932SPravin B Shelar 
697c5441932SPravin B Shelar 	p.i_flags = tnl_flags_to_gre_flags(p.i_flags);
698c5441932SPravin B Shelar 	p.o_flags = tnl_flags_to_gre_flags(p.o_flags);
699c5441932SPravin B Shelar 
700c5441932SPravin B Shelar 	if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
701c5441932SPravin B Shelar 		return -EFAULT;
7021da177e4SLinus Torvalds 	return 0;
7031da177e4SLinus Torvalds }
7041da177e4SLinus Torvalds 
7051da177e4SLinus Torvalds /* Nice toy. Unfortunately, useless in real life :-)
7061da177e4SLinus Torvalds    It allows to construct virtual multiprotocol broadcast "LAN"
7071da177e4SLinus Torvalds    over the Internet, provided multicast routing is tuned.
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 
7101da177e4SLinus Torvalds    I have no idea was this bicycle invented before me,
7111da177e4SLinus Torvalds    so that I had to set ARPHRD_IPGRE to a random value.
7121da177e4SLinus Torvalds    I have an impression, that Cisco could make something similar,
7131da177e4SLinus Torvalds    but this feature is apparently missing in IOS<=11.2(8).
7141da177e4SLinus Torvalds 
7151da177e4SLinus Torvalds    I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
7161da177e4SLinus Torvalds    with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds    ping -t 255 224.66.66.66
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds    If nobody answers, mbone does not work.
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds    ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
7231da177e4SLinus Torvalds    ip addr add 10.66.66.<somewhat>/24 dev Universe
7241da177e4SLinus Torvalds    ifconfig Universe up
7251da177e4SLinus Torvalds    ifconfig Universe add fe80::<Your_real_addr>/10
7261da177e4SLinus Torvalds    ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
7271da177e4SLinus Torvalds    ftp 10.66.66.66
7281da177e4SLinus Torvalds    ...
7291da177e4SLinus Torvalds    ftp fec0:6666:6666::193.233.7.65
7301da177e4SLinus Torvalds    ...
7311da177e4SLinus Torvalds  */
7323b04dddeSStephen Hemminger static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
7333b04dddeSStephen Hemminger 			unsigned short type,
7341507850bSEric Dumazet 			const void *daddr, const void *saddr, unsigned int len)
7351da177e4SLinus Torvalds {
7362941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
737c5441932SPravin B Shelar 	struct iphdr *iph;
738c5441932SPravin B Shelar 	struct gre_base_hdr *greh;
739c5441932SPravin B Shelar 
740c5441932SPravin B Shelar 	iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
741c5441932SPravin B Shelar 	greh = (struct gre_base_hdr *)(iph+1);
742c5441932SPravin B Shelar 	greh->flags = tnl_flags_to_gre_flags(t->parms.o_flags);
743c5441932SPravin B Shelar 	greh->protocol = htons(type);
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds 	memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
7461da177e4SLinus Torvalds 
747c5441932SPravin B Shelar 	/* Set the source hardware address. */
7481da177e4SLinus Torvalds 	if (saddr)
7491da177e4SLinus Torvalds 		memcpy(&iph->saddr, saddr, 4);
7506d55cb91STimo Teräs 	if (daddr)
7511da177e4SLinus Torvalds 		memcpy(&iph->daddr, daddr, 4);
7526d55cb91STimo Teräs 	if (iph->daddr)
75377a482bdSTimo Teräs 		return t->hlen + sizeof(*iph);
7541da177e4SLinus Torvalds 
755c5441932SPravin B Shelar 	return -(t->hlen + sizeof(*iph));
7561da177e4SLinus Torvalds }
7571da177e4SLinus Torvalds 
7586a5f44d7STimo Teras static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
7596a5f44d7STimo Teras {
760b71d1d42SEric Dumazet 	const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
7616a5f44d7STimo Teras 	memcpy(haddr, &iph->saddr, 4);
7626a5f44d7STimo Teras 	return 4;
7636a5f44d7STimo Teras }
7646a5f44d7STimo Teras 
7653b04dddeSStephen Hemminger static const struct header_ops ipgre_header_ops = {
7663b04dddeSStephen Hemminger 	.create	= ipgre_header,
7676a5f44d7STimo Teras 	.parse	= ipgre_header_parse,
7683b04dddeSStephen Hemminger };
7693b04dddeSStephen Hemminger 
7706a5f44d7STimo Teras #ifdef CONFIG_NET_IPGRE_BROADCAST
7711da177e4SLinus Torvalds static int ipgre_open(struct net_device *dev)
7721da177e4SLinus Torvalds {
7732941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
7741da177e4SLinus Torvalds 
775f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr)) {
776cbb1e85fSDavid S. Miller 		struct flowi4 fl4;
777cbb1e85fSDavid S. Miller 		struct rtable *rt;
778cbb1e85fSDavid S. Miller 
779b57708adSNicolas Dichtel 		rt = ip_route_output_gre(t->net, &fl4,
78078fbfd8aSDavid S. Miller 					 t->parms.iph.daddr,
78178fbfd8aSDavid S. Miller 					 t->parms.iph.saddr,
78278fbfd8aSDavid S. Miller 					 t->parms.o_key,
78378fbfd8aSDavid S. Miller 					 RT_TOS(t->parms.iph.tos),
78478fbfd8aSDavid S. Miller 					 t->parms.link);
785b23dd4feSDavid S. Miller 		if (IS_ERR(rt))
7861da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
787d8d1f30bSChangli Gao 		dev = rt->dst.dev;
7881da177e4SLinus Torvalds 		ip_rt_put(rt);
78951456b29SIan Morris 		if (!__in_dev_get_rtnl(dev))
7901da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
7911da177e4SLinus Torvalds 		t->mlink = dev->ifindex;
792e5ed6399SHerbert Xu 		ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
7931da177e4SLinus Torvalds 	}
7941da177e4SLinus Torvalds 	return 0;
7951da177e4SLinus Torvalds }
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds static int ipgre_close(struct net_device *dev)
7981da177e4SLinus Torvalds {
7992941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
800b8c26a33SStephen Hemminger 
801f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
8027fee0ca2SDenis V. Lunev 		struct in_device *in_dev;
803b57708adSNicolas Dichtel 		in_dev = inetdev_by_index(t->net, t->mlink);
8048723e1b4SEric Dumazet 		if (in_dev)
8051da177e4SLinus Torvalds 			ip_mc_dec_group(in_dev, t->parms.iph.daddr);
8061da177e4SLinus Torvalds 	}
8071da177e4SLinus Torvalds 	return 0;
8081da177e4SLinus Torvalds }
8091da177e4SLinus Torvalds #endif
8101da177e4SLinus Torvalds 
811b8c26a33SStephen Hemminger static const struct net_device_ops ipgre_netdev_ops = {
812b8c26a33SStephen Hemminger 	.ndo_init		= ipgre_tunnel_init,
813c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
814b8c26a33SStephen Hemminger #ifdef CONFIG_NET_IPGRE_BROADCAST
815b8c26a33SStephen Hemminger 	.ndo_open		= ipgre_open,
816b8c26a33SStephen Hemminger 	.ndo_stop		= ipgre_close,
817b8c26a33SStephen Hemminger #endif
818c5441932SPravin B Shelar 	.ndo_start_xmit		= ipgre_xmit,
819b8c26a33SStephen Hemminger 	.ndo_do_ioctl		= ipgre_tunnel_ioctl,
820c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
821c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
8221e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
823b8c26a33SStephen Hemminger };
824b8c26a33SStephen Hemminger 
8256b78f16eSEric Dumazet #define GRE_FEATURES (NETIF_F_SG |		\
8266b78f16eSEric Dumazet 		      NETIF_F_FRAGLIST |	\
8276b78f16eSEric Dumazet 		      NETIF_F_HIGHDMA |		\
8286b78f16eSEric Dumazet 		      NETIF_F_HW_CSUM)
8296b78f16eSEric Dumazet 
8301da177e4SLinus Torvalds static void ipgre_tunnel_setup(struct net_device *dev)
8311da177e4SLinus Torvalds {
832b8c26a33SStephen Hemminger 	dev->netdev_ops		= &ipgre_netdev_ops;
8335a455275SNicolas Dichtel 	dev->type		= ARPHRD_IPGRE;
834c5441932SPravin B Shelar 	ip_tunnel_setup(dev, ipgre_net_id);
835c5441932SPravin B Shelar }
8361da177e4SLinus Torvalds 
837c5441932SPravin B Shelar static void __gre_tunnel_init(struct net_device *dev)
838c5441932SPravin B Shelar {
839c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
8404565e991STom Herbert 	int t_hlen;
841c5441932SPravin B Shelar 
842c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
8434565e991STom Herbert 	tunnel->tun_hlen = ip_gre_calc_hlen(tunnel->parms.o_flags);
844c5441932SPravin B Shelar 	tunnel->parms.iph.protocol = IPPROTO_GRE;
845c5441932SPravin B Shelar 
8464565e991STom Herbert 	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
8474565e991STom Herbert 
8484565e991STom Herbert 	t_hlen = tunnel->hlen + sizeof(struct iphdr);
8494565e991STom Herbert 
8504565e991STom Herbert 	dev->needed_headroom	= LL_MAX_HEADER + t_hlen + 4;
8514565e991STom Herbert 	dev->mtu		= ETH_DATA_LEN - t_hlen - 4;
8526b78f16eSEric Dumazet 
853b57708adSNicolas Dichtel 	dev->features		|= GRE_FEATURES;
8546b78f16eSEric Dumazet 	dev->hw_features	|= GRE_FEATURES;
855c5441932SPravin B Shelar 
856c5441932SPravin B Shelar 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
857a0ca153fSAlexander Duyck 		/* TCP offload with GRE SEQ is not supported, nor
858a0ca153fSAlexander Duyck 		 * can we support 2 levels of outer headers requiring
859a0ca153fSAlexander Duyck 		 * an update.
860a0ca153fSAlexander Duyck 		 */
861a0ca153fSAlexander Duyck 		if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
862a0ca153fSAlexander Duyck 		    (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
863c5441932SPravin B Shelar 			dev->features    |= NETIF_F_GSO_SOFTWARE;
864c5441932SPravin B Shelar 			dev->hw_features |= NETIF_F_GSO_SOFTWARE;
865a0ca153fSAlexander Duyck 		}
866a0ca153fSAlexander Duyck 
867c5441932SPravin B Shelar 		/* Can use a lockless transmit, unless we generate
868c5441932SPravin B Shelar 		 * output sequences
869c5441932SPravin B Shelar 		 */
870c5441932SPravin B Shelar 		dev->features |= NETIF_F_LLTX;
871c5441932SPravin B Shelar 	}
8721da177e4SLinus Torvalds }
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev)
8751da177e4SLinus Torvalds {
876c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
877c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
8781da177e4SLinus Torvalds 
879c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
8801da177e4SLinus Torvalds 
881c5441932SPravin B Shelar 	memcpy(dev->dev_addr, &iph->saddr, 4);
882c5441932SPravin B Shelar 	memcpy(dev->broadcast, &iph->daddr, 4);
8831da177e4SLinus Torvalds 
884c5441932SPravin B Shelar 	dev->flags		= IFF_NOARP;
88502875878SEric Dumazet 	netif_keep_dst(dev);
886c5441932SPravin B Shelar 	dev->addr_len		= 4;
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds 	if (iph->daddr) {
8891da177e4SLinus Torvalds #ifdef CONFIG_NET_IPGRE_BROADCAST
890f97c1e0cSJoe Perches 		if (ipv4_is_multicast(iph->daddr)) {
8911da177e4SLinus Torvalds 			if (!iph->saddr)
8921da177e4SLinus Torvalds 				return -EINVAL;
8931da177e4SLinus Torvalds 			dev->flags = IFF_BROADCAST;
8943b04dddeSStephen Hemminger 			dev->header_ops = &ipgre_header_ops;
8951da177e4SLinus Torvalds 		}
8961da177e4SLinus Torvalds #endif
897ee34c1ebSMichal Schmidt 	} else
8986a5f44d7STimo Teras 		dev->header_ops = &ipgre_header_ops;
8991da177e4SLinus Torvalds 
900c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
90160769a5dSEric Dumazet }
90260769a5dSEric Dumazet 
9039f57c67cSPravin B Shelar static const struct gre_protocol ipgre_protocol = {
9049f57c67cSPravin B Shelar 	.handler     = gre_rcv,
9059f57c67cSPravin B Shelar 	.err_handler = gre_err,
9061da177e4SLinus Torvalds };
9071da177e4SLinus Torvalds 
9082c8c1e72SAlexey Dobriyan static int __net_init ipgre_init_net(struct net *net)
90959a4c759SPavel Emelyanov {
910c5441932SPravin B Shelar 	return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
91159a4c759SPavel Emelyanov }
91259a4c759SPavel Emelyanov 
9132c8c1e72SAlexey Dobriyan static void __net_exit ipgre_exit_net(struct net *net)
91459a4c759SPavel Emelyanov {
915c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
9166c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_link_ops);
91759a4c759SPavel Emelyanov }
91859a4c759SPavel Emelyanov 
91959a4c759SPavel Emelyanov static struct pernet_operations ipgre_net_ops = {
92059a4c759SPavel Emelyanov 	.init = ipgre_init_net,
92159a4c759SPavel Emelyanov 	.exit = ipgre_exit_net,
922cfb8fbf2SEric W. Biederman 	.id   = &ipgre_net_id,
923c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
92459a4c759SPavel Emelyanov };
9251da177e4SLinus Torvalds 
926c19e654dSHerbert Xu static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
927c19e654dSHerbert Xu {
928c19e654dSHerbert Xu 	__be16 flags;
929c19e654dSHerbert Xu 
930c19e654dSHerbert Xu 	if (!data)
931c19e654dSHerbert Xu 		return 0;
932c19e654dSHerbert Xu 
933c19e654dSHerbert Xu 	flags = 0;
934c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
935c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
936c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
937c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
938c19e654dSHerbert Xu 	if (flags & (GRE_VERSION|GRE_ROUTING))
939c19e654dSHerbert Xu 		return -EINVAL;
940c19e654dSHerbert Xu 
941c19e654dSHerbert Xu 	return 0;
942c19e654dSHerbert Xu }
943c19e654dSHerbert Xu 
944e1a80002SHerbert Xu static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
945e1a80002SHerbert Xu {
946e1a80002SHerbert Xu 	__be32 daddr;
947e1a80002SHerbert Xu 
948e1a80002SHerbert Xu 	if (tb[IFLA_ADDRESS]) {
949e1a80002SHerbert Xu 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
950e1a80002SHerbert Xu 			return -EINVAL;
951e1a80002SHerbert Xu 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
952e1a80002SHerbert Xu 			return -EADDRNOTAVAIL;
953e1a80002SHerbert Xu 	}
954e1a80002SHerbert Xu 
955e1a80002SHerbert Xu 	if (!data)
956e1a80002SHerbert Xu 		goto out;
957e1a80002SHerbert Xu 
958e1a80002SHerbert Xu 	if (data[IFLA_GRE_REMOTE]) {
959e1a80002SHerbert Xu 		memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
960e1a80002SHerbert Xu 		if (!daddr)
961e1a80002SHerbert Xu 			return -EINVAL;
962e1a80002SHerbert Xu 	}
963e1a80002SHerbert Xu 
964e1a80002SHerbert Xu out:
965e1a80002SHerbert Xu 	return ipgre_tunnel_validate(tb, data);
966e1a80002SHerbert Xu }
967e1a80002SHerbert Xu 
9682e15ea39SPravin B Shelar static void ipgre_netlink_parms(struct net_device *dev,
9692e15ea39SPravin B Shelar 				struct nlattr *data[],
9702e15ea39SPravin B Shelar 				struct nlattr *tb[],
971c19e654dSHerbert Xu 				struct ip_tunnel_parm *parms)
972c19e654dSHerbert Xu {
9737bb82d92SHerbert Xu 	memset(parms, 0, sizeof(*parms));
974c19e654dSHerbert Xu 
975c19e654dSHerbert Xu 	parms->iph.protocol = IPPROTO_GRE;
976c19e654dSHerbert Xu 
977c19e654dSHerbert Xu 	if (!data)
978c19e654dSHerbert Xu 		return;
979c19e654dSHerbert Xu 
980c19e654dSHerbert Xu 	if (data[IFLA_GRE_LINK])
981c19e654dSHerbert Xu 		parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
982c19e654dSHerbert Xu 
983c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
984c5441932SPravin B Shelar 		parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
985c19e654dSHerbert Xu 
986c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
987c5441932SPravin B Shelar 		parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
988c19e654dSHerbert Xu 
989c19e654dSHerbert Xu 	if (data[IFLA_GRE_IKEY])
990c19e654dSHerbert Xu 		parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
991c19e654dSHerbert Xu 
992c19e654dSHerbert Xu 	if (data[IFLA_GRE_OKEY])
993c19e654dSHerbert Xu 		parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
994c19e654dSHerbert Xu 
995c19e654dSHerbert Xu 	if (data[IFLA_GRE_LOCAL])
99667b61f6cSJiri Benc 		parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
997c19e654dSHerbert Xu 
998c19e654dSHerbert Xu 	if (data[IFLA_GRE_REMOTE])
99967b61f6cSJiri Benc 		parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
1000c19e654dSHerbert Xu 
1001c19e654dSHerbert Xu 	if (data[IFLA_GRE_TTL])
1002c19e654dSHerbert Xu 		parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
1003c19e654dSHerbert Xu 
1004c19e654dSHerbert Xu 	if (data[IFLA_GRE_TOS])
1005c19e654dSHerbert Xu 		parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
1006c19e654dSHerbert Xu 
1007c19e654dSHerbert Xu 	if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC]))
1008c19e654dSHerbert Xu 		parms->iph.frag_off = htons(IP_DF);
10092e15ea39SPravin B Shelar 
10102e15ea39SPravin B Shelar 	if (data[IFLA_GRE_COLLECT_METADATA]) {
10112e15ea39SPravin B Shelar 		struct ip_tunnel *t = netdev_priv(dev);
10122e15ea39SPravin B Shelar 
10132e15ea39SPravin B Shelar 		t->collect_md = true;
10142e15ea39SPravin B Shelar 	}
1015c19e654dSHerbert Xu }
1016c19e654dSHerbert Xu 
10174565e991STom Herbert /* This function returns true when ENCAP attributes are present in the nl msg */
10184565e991STom Herbert static bool ipgre_netlink_encap_parms(struct nlattr *data[],
10194565e991STom Herbert 				      struct ip_tunnel_encap *ipencap)
10204565e991STom Herbert {
10214565e991STom Herbert 	bool ret = false;
10224565e991STom Herbert 
10234565e991STom Herbert 	memset(ipencap, 0, sizeof(*ipencap));
10244565e991STom Herbert 
10254565e991STom Herbert 	if (!data)
10264565e991STom Herbert 		return ret;
10274565e991STom Herbert 
10284565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_TYPE]) {
10294565e991STom Herbert 		ret = true;
10304565e991STom Herbert 		ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
10314565e991STom Herbert 	}
10324565e991STom Herbert 
10334565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_FLAGS]) {
10344565e991STom Herbert 		ret = true;
10354565e991STom Herbert 		ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
10364565e991STom Herbert 	}
10374565e991STom Herbert 
10384565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_SPORT]) {
10394565e991STom Herbert 		ret = true;
10403e97fa70SSabrina Dubroca 		ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
10414565e991STom Herbert 	}
10424565e991STom Herbert 
10434565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_DPORT]) {
10444565e991STom Herbert 		ret = true;
10453e97fa70SSabrina Dubroca 		ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
10464565e991STom Herbert 	}
10474565e991STom Herbert 
10484565e991STom Herbert 	return ret;
10494565e991STom Herbert }
10504565e991STom Herbert 
1051c5441932SPravin B Shelar static int gre_tap_init(struct net_device *dev)
1052e1a80002SHerbert Xu {
1053c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
1054bec94d43Sstephen hemminger 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1055e1a80002SHerbert Xu 
1056c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
1057e1a80002SHerbert Xu }
1058e1a80002SHerbert Xu 
1059c5441932SPravin B Shelar static const struct net_device_ops gre_tap_netdev_ops = {
1060c5441932SPravin B Shelar 	.ndo_init		= gre_tap_init,
1061c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
1062c5441932SPravin B Shelar 	.ndo_start_xmit		= gre_tap_xmit,
1063b8c26a33SStephen Hemminger 	.ndo_set_mac_address 	= eth_mac_addr,
1064b8c26a33SStephen Hemminger 	.ndo_validate_addr	= eth_validate_addr,
1065c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
1066c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
10671e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
1068fc4099f1SPravin B Shelar 	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
1069b8c26a33SStephen Hemminger };
1070b8c26a33SStephen Hemminger 
1071e1a80002SHerbert Xu static void ipgre_tap_setup(struct net_device *dev)
1072e1a80002SHerbert Xu {
1073e1a80002SHerbert Xu 	ether_setup(dev);
1074c5441932SPravin B Shelar 	dev->netdev_ops	= &gre_tap_netdev_ops;
1075d13b161cSJiri Benc 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1076f8c1b7ceSstephen hemminger 	dev->priv_flags	|= IFF_LIVE_ADDR_CHANGE;
1077c5441932SPravin B Shelar 	ip_tunnel_setup(dev, gre_tap_net_id);
1078e1a80002SHerbert Xu }
1079e1a80002SHerbert Xu 
1080c5441932SPravin B Shelar static int ipgre_newlink(struct net *src_net, struct net_device *dev,
1081c5441932SPravin B Shelar 			 struct nlattr *tb[], struct nlattr *data[])
1082c19e654dSHerbert Xu {
1083c5441932SPravin B Shelar 	struct ip_tunnel_parm p;
10844565e991STom Herbert 	struct ip_tunnel_encap ipencap;
10854565e991STom Herbert 
10864565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
10874565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
10884565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
10894565e991STom Herbert 
10904565e991STom Herbert 		if (err < 0)
10914565e991STom Herbert 			return err;
10924565e991STom Herbert 	}
1093c19e654dSHerbert Xu 
10942e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
1095c5441932SPravin B Shelar 	return ip_tunnel_newlink(dev, tb, &p);
1096c19e654dSHerbert Xu }
1097c19e654dSHerbert Xu 
1098c19e654dSHerbert Xu static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
1099c19e654dSHerbert Xu 			    struct nlattr *data[])
1100c19e654dSHerbert Xu {
1101c19e654dSHerbert Xu 	struct ip_tunnel_parm p;
11024565e991STom Herbert 	struct ip_tunnel_encap ipencap;
11034565e991STom Herbert 
11044565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
11054565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
11064565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
11074565e991STom Herbert 
11084565e991STom Herbert 		if (err < 0)
11094565e991STom Herbert 			return err;
11104565e991STom Herbert 	}
1111c19e654dSHerbert Xu 
11122e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
1113c5441932SPravin B Shelar 	return ip_tunnel_changelink(dev, tb, &p);
1114c19e654dSHerbert Xu }
1115c19e654dSHerbert Xu 
1116c19e654dSHerbert Xu static size_t ipgre_get_size(const struct net_device *dev)
1117c19e654dSHerbert Xu {
1118c19e654dSHerbert Xu 	return
1119c19e654dSHerbert Xu 		/* IFLA_GRE_LINK */
1120c19e654dSHerbert Xu 		nla_total_size(4) +
1121c19e654dSHerbert Xu 		/* IFLA_GRE_IFLAGS */
1122c19e654dSHerbert Xu 		nla_total_size(2) +
1123c19e654dSHerbert Xu 		/* IFLA_GRE_OFLAGS */
1124c19e654dSHerbert Xu 		nla_total_size(2) +
1125c19e654dSHerbert Xu 		/* IFLA_GRE_IKEY */
1126c19e654dSHerbert Xu 		nla_total_size(4) +
1127c19e654dSHerbert Xu 		/* IFLA_GRE_OKEY */
1128c19e654dSHerbert Xu 		nla_total_size(4) +
1129c19e654dSHerbert Xu 		/* IFLA_GRE_LOCAL */
1130c19e654dSHerbert Xu 		nla_total_size(4) +
1131c19e654dSHerbert Xu 		/* IFLA_GRE_REMOTE */
1132c19e654dSHerbert Xu 		nla_total_size(4) +
1133c19e654dSHerbert Xu 		/* IFLA_GRE_TTL */
1134c19e654dSHerbert Xu 		nla_total_size(1) +
1135c19e654dSHerbert Xu 		/* IFLA_GRE_TOS */
1136c19e654dSHerbert Xu 		nla_total_size(1) +
1137c19e654dSHerbert Xu 		/* IFLA_GRE_PMTUDISC */
1138c19e654dSHerbert Xu 		nla_total_size(1) +
11394565e991STom Herbert 		/* IFLA_GRE_ENCAP_TYPE */
11404565e991STom Herbert 		nla_total_size(2) +
11414565e991STom Herbert 		/* IFLA_GRE_ENCAP_FLAGS */
11424565e991STom Herbert 		nla_total_size(2) +
11434565e991STom Herbert 		/* IFLA_GRE_ENCAP_SPORT */
11444565e991STom Herbert 		nla_total_size(2) +
11454565e991STom Herbert 		/* IFLA_GRE_ENCAP_DPORT */
11464565e991STom Herbert 		nla_total_size(2) +
11472e15ea39SPravin B Shelar 		/* IFLA_GRE_COLLECT_METADATA */
11482e15ea39SPravin B Shelar 		nla_total_size(0) +
1149c19e654dSHerbert Xu 		0;
1150c19e654dSHerbert Xu }
1151c19e654dSHerbert Xu 
1152c19e654dSHerbert Xu static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1153c19e654dSHerbert Xu {
1154c19e654dSHerbert Xu 	struct ip_tunnel *t = netdev_priv(dev);
1155c19e654dSHerbert Xu 	struct ip_tunnel_parm *p = &t->parms;
1156c19e654dSHerbert Xu 
1157f3756b79SDavid S. Miller 	if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
1158c5441932SPravin B Shelar 	    nla_put_be16(skb, IFLA_GRE_IFLAGS, tnl_flags_to_gre_flags(p->i_flags)) ||
1159c5441932SPravin B Shelar 	    nla_put_be16(skb, IFLA_GRE_OFLAGS, tnl_flags_to_gre_flags(p->o_flags)) ||
1160f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1161f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1162930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1163930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
1164f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1165f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1166f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1167f3756b79SDavid S. Miller 		       !!(p->iph.frag_off & htons(IP_DF))))
1168f3756b79SDavid S. Miller 		goto nla_put_failure;
11694565e991STom Herbert 
11704565e991STom Herbert 	if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
11714565e991STom Herbert 			t->encap.type) ||
11723e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
11734565e991STom Herbert 			 t->encap.sport) ||
11743e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
11754565e991STom Herbert 			 t->encap.dport) ||
11764565e991STom Herbert 	    nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
1177e1b2cb65STom Herbert 			t->encap.flags))
11784565e991STom Herbert 		goto nla_put_failure;
11794565e991STom Herbert 
11802e15ea39SPravin B Shelar 	if (t->collect_md) {
11812e15ea39SPravin B Shelar 		if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
11822e15ea39SPravin B Shelar 			goto nla_put_failure;
11832e15ea39SPravin B Shelar 	}
11842e15ea39SPravin B Shelar 
1185c19e654dSHerbert Xu 	return 0;
1186c19e654dSHerbert Xu 
1187c19e654dSHerbert Xu nla_put_failure:
1188c19e654dSHerbert Xu 	return -EMSGSIZE;
1189c19e654dSHerbert Xu }
1190c19e654dSHerbert Xu 
1191c19e654dSHerbert Xu static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1192c19e654dSHerbert Xu 	[IFLA_GRE_LINK]		= { .type = NLA_U32 },
1193c19e654dSHerbert Xu 	[IFLA_GRE_IFLAGS]	= { .type = NLA_U16 },
1194c19e654dSHerbert Xu 	[IFLA_GRE_OFLAGS]	= { .type = NLA_U16 },
1195c19e654dSHerbert Xu 	[IFLA_GRE_IKEY]		= { .type = NLA_U32 },
1196c19e654dSHerbert Xu 	[IFLA_GRE_OKEY]		= { .type = NLA_U32 },
11974d74f8baSPatrick McHardy 	[IFLA_GRE_LOCAL]	= { .len = FIELD_SIZEOF(struct iphdr, saddr) },
11984d74f8baSPatrick McHardy 	[IFLA_GRE_REMOTE]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
1199c19e654dSHerbert Xu 	[IFLA_GRE_TTL]		= { .type = NLA_U8 },
1200c19e654dSHerbert Xu 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
1201c19e654dSHerbert Xu 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
12024565e991STom Herbert 	[IFLA_GRE_ENCAP_TYPE]	= { .type = NLA_U16 },
12034565e991STom Herbert 	[IFLA_GRE_ENCAP_FLAGS]	= { .type = NLA_U16 },
12044565e991STom Herbert 	[IFLA_GRE_ENCAP_SPORT]	= { .type = NLA_U16 },
12054565e991STom Herbert 	[IFLA_GRE_ENCAP_DPORT]	= { .type = NLA_U16 },
12062e15ea39SPravin B Shelar 	[IFLA_GRE_COLLECT_METADATA]	= { .type = NLA_FLAG },
1207c19e654dSHerbert Xu };
1208c19e654dSHerbert Xu 
1209c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1210c19e654dSHerbert Xu 	.kind		= "gre",
1211c19e654dSHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1212c19e654dSHerbert Xu 	.policy		= ipgre_policy,
1213c19e654dSHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1214c19e654dSHerbert Xu 	.setup		= ipgre_tunnel_setup,
1215c19e654dSHerbert Xu 	.validate	= ipgre_tunnel_validate,
1216c19e654dSHerbert Xu 	.newlink	= ipgre_newlink,
1217c19e654dSHerbert Xu 	.changelink	= ipgre_changelink,
1218c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1219c19e654dSHerbert Xu 	.get_size	= ipgre_get_size,
1220c19e654dSHerbert Xu 	.fill_info	= ipgre_fill_info,
12211728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1222c19e654dSHerbert Xu };
1223c19e654dSHerbert Xu 
1224e1a80002SHerbert Xu static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1225e1a80002SHerbert Xu 	.kind		= "gretap",
1226e1a80002SHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1227e1a80002SHerbert Xu 	.policy		= ipgre_policy,
1228e1a80002SHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1229e1a80002SHerbert Xu 	.setup		= ipgre_tap_setup,
1230e1a80002SHerbert Xu 	.validate	= ipgre_tap_validate,
1231e1a80002SHerbert Xu 	.newlink	= ipgre_newlink,
1232e1a80002SHerbert Xu 	.changelink	= ipgre_changelink,
1233c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1234e1a80002SHerbert Xu 	.get_size	= ipgre_get_size,
1235e1a80002SHerbert Xu 	.fill_info	= ipgre_fill_info,
12361728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1237e1a80002SHerbert Xu };
1238e1a80002SHerbert Xu 
1239b2acd1dcSPravin B Shelar struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1240b2acd1dcSPravin B Shelar 					u8 name_assign_type)
1241b2acd1dcSPravin B Shelar {
1242b2acd1dcSPravin B Shelar 	struct nlattr *tb[IFLA_MAX + 1];
1243b2acd1dcSPravin B Shelar 	struct net_device *dev;
1244b2acd1dcSPravin B Shelar 	struct ip_tunnel *t;
1245b2acd1dcSPravin B Shelar 	int err;
1246b2acd1dcSPravin B Shelar 
1247b2acd1dcSPravin B Shelar 	memset(&tb, 0, sizeof(tb));
1248b2acd1dcSPravin B Shelar 
1249b2acd1dcSPravin B Shelar 	dev = rtnl_create_link(net, name, name_assign_type,
1250b2acd1dcSPravin B Shelar 			       &ipgre_tap_ops, tb);
1251b2acd1dcSPravin B Shelar 	if (IS_ERR(dev))
1252b2acd1dcSPravin B Shelar 		return dev;
1253b2acd1dcSPravin B Shelar 
1254b2acd1dcSPravin B Shelar 	/* Configure flow based GRE device. */
1255b2acd1dcSPravin B Shelar 	t = netdev_priv(dev);
1256b2acd1dcSPravin B Shelar 	t->collect_md = true;
1257b2acd1dcSPravin B Shelar 
1258b2acd1dcSPravin B Shelar 	err = ipgre_newlink(net, dev, tb, NULL);
1259b2acd1dcSPravin B Shelar 	if (err < 0)
1260b2acd1dcSPravin B Shelar 		goto out;
12617e059158SDavid Wragg 
12627e059158SDavid Wragg 	/* openvswitch users expect packet sizes to be unrestricted,
12637e059158SDavid Wragg 	 * so set the largest MTU we can.
12647e059158SDavid Wragg 	 */
12657e059158SDavid Wragg 	err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
12667e059158SDavid Wragg 	if (err)
12677e059158SDavid Wragg 		goto out;
12687e059158SDavid Wragg 
1269b2acd1dcSPravin B Shelar 	return dev;
1270b2acd1dcSPravin B Shelar out:
1271b2acd1dcSPravin B Shelar 	free_netdev(dev);
1272b2acd1dcSPravin B Shelar 	return ERR_PTR(err);
1273b2acd1dcSPravin B Shelar }
1274b2acd1dcSPravin B Shelar EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1275b2acd1dcSPravin B Shelar 
1276c5441932SPravin B Shelar static int __net_init ipgre_tap_init_net(struct net *net)
1277c5441932SPravin B Shelar {
12782e15ea39SPravin B Shelar 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
1279c5441932SPravin B Shelar }
1280c5441932SPravin B Shelar 
1281c5441932SPravin B Shelar static void __net_exit ipgre_tap_exit_net(struct net *net)
1282c5441932SPravin B Shelar {
1283c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
12846c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_tap_ops);
1285c5441932SPravin B Shelar }
1286c5441932SPravin B Shelar 
1287c5441932SPravin B Shelar static struct pernet_operations ipgre_tap_net_ops = {
1288c5441932SPravin B Shelar 	.init = ipgre_tap_init_net,
1289c5441932SPravin B Shelar 	.exit = ipgre_tap_exit_net,
1290c5441932SPravin B Shelar 	.id   = &gre_tap_net_id,
1291c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
1292c5441932SPravin B Shelar };
12931da177e4SLinus Torvalds 
12941da177e4SLinus Torvalds static int __init ipgre_init(void)
12951da177e4SLinus Torvalds {
12961da177e4SLinus Torvalds 	int err;
12971da177e4SLinus Torvalds 
1298058bd4d2SJoe Perches 	pr_info("GRE over IPv4 tunneling driver\n");
12991da177e4SLinus Torvalds 
1300cfb8fbf2SEric W. Biederman 	err = register_pernet_device(&ipgre_net_ops);
130159a4c759SPavel Emelyanov 	if (err < 0)
1302c2892f02SAlexey Dobriyan 		return err;
1303c2892f02SAlexey Dobriyan 
1304c5441932SPravin B Shelar 	err = register_pernet_device(&ipgre_tap_net_ops);
1305c5441932SPravin B Shelar 	if (err < 0)
1306c5441932SPravin B Shelar 		goto pnet_tap_faied;
1307c5441932SPravin B Shelar 
13089f57c67cSPravin B Shelar 	err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
1309c2892f02SAlexey Dobriyan 	if (err < 0) {
1310058bd4d2SJoe Perches 		pr_info("%s: can't add protocol\n", __func__);
1311c2892f02SAlexey Dobriyan 		goto add_proto_failed;
1312c2892f02SAlexey Dobriyan 	}
13137daa0004SPavel Emelyanov 
1314c19e654dSHerbert Xu 	err = rtnl_link_register(&ipgre_link_ops);
1315c19e654dSHerbert Xu 	if (err < 0)
1316c19e654dSHerbert Xu 		goto rtnl_link_failed;
1317c19e654dSHerbert Xu 
1318e1a80002SHerbert Xu 	err = rtnl_link_register(&ipgre_tap_ops);
1319e1a80002SHerbert Xu 	if (err < 0)
1320e1a80002SHerbert Xu 		goto tap_ops_failed;
1321e1a80002SHerbert Xu 
1322c5441932SPravin B Shelar 	return 0;
1323c19e654dSHerbert Xu 
1324e1a80002SHerbert Xu tap_ops_failed:
1325e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
1326c19e654dSHerbert Xu rtnl_link_failed:
13279f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1328c2892f02SAlexey Dobriyan add_proto_failed:
1329c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1330c5441932SPravin B Shelar pnet_tap_faied:
1331c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
1332c5441932SPravin B Shelar 	return err;
13331da177e4SLinus Torvalds }
13341da177e4SLinus Torvalds 
1335db44575fSAlexey Kuznetsov static void __exit ipgre_fini(void)
13361da177e4SLinus Torvalds {
1337e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_tap_ops);
1338c19e654dSHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
13399f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1340c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1341c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
13421da177e4SLinus Torvalds }
13431da177e4SLinus Torvalds 
13441da177e4SLinus Torvalds module_init(ipgre_init);
13451da177e4SLinus Torvalds module_exit(ipgre_fini);
13461da177e4SLinus Torvalds MODULE_LICENSE("GPL");
13474d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gre");
13484d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gretap");
13498909c9adSVasiliy Kulikov MODULE_ALIAS_NETDEV("gre0");
1350c5441932SPravin B Shelar MODULE_ALIAS_NETDEV("gretap0");
1351