xref: /linux/net/ipv4/ip_gre.c (revision cba653210056cf47cc1969f831f05ddfb99ee2bd)
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 void ipgre_err(struct sk_buff *skb, u32 info,
126bda7bb46SPravin B Shelar 		      const struct tnl_ptk_info *tpi)
1271da177e4SLinus Torvalds {
1281da177e4SLinus Torvalds 
129071f92d0SRami Rosen 	/* All the routers (except for Linux) return only
1301da177e4SLinus Torvalds 	   8 bytes of packet payload. It means, that precise relaying of
1311da177e4SLinus Torvalds 	   ICMP in the real Internet is absolutely infeasible.
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	   Moreover, Cisco "wise men" put GRE key to the third word
134c5441932SPravin B Shelar 	   in GRE header. It makes impossible maintaining even soft
135c5441932SPravin B Shelar 	   state for keyed GRE tunnels with enabled checksum. Tell
136c5441932SPravin B Shelar 	   them "thank you".
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 	   Well, I wonder, rfc1812 was written by Cisco employee,
139bff52857Sstephen hemminger 	   what the hell these idiots break standards established
140bff52857Sstephen hemminger 	   by themselves???
1411da177e4SLinus Torvalds 	   */
142c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
143c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
14496f5a846SEric Dumazet 	const struct iphdr *iph;
14588c7664fSArnaldo Carvalho de Melo 	const int type = icmp_hdr(skb)->type;
14688c7664fSArnaldo Carvalho de Melo 	const int code = icmp_hdr(skb)->code;
1471da177e4SLinus Torvalds 	struct ip_tunnel *t;
148d2083287Sstephen hemminger 
1491da177e4SLinus Torvalds 	switch (type) {
1501da177e4SLinus Torvalds 	default:
1511da177e4SLinus Torvalds 	case ICMP_PARAMETERPROB:
1529f57c67cSPravin B Shelar 		return;
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds 	case ICMP_DEST_UNREACH:
1551da177e4SLinus Torvalds 		switch (code) {
1561da177e4SLinus Torvalds 		case ICMP_SR_FAILED:
1571da177e4SLinus Torvalds 		case ICMP_PORT_UNREACH:
1581da177e4SLinus Torvalds 			/* Impossible event. */
1599f57c67cSPravin B Shelar 			return;
1601da177e4SLinus Torvalds 		default:
1611da177e4SLinus Torvalds 			/* All others are translated to HOST_UNREACH.
1621da177e4SLinus Torvalds 			   rfc2003 contains "deep thoughts" about NET_UNREACH,
1631da177e4SLinus Torvalds 			   I believe they are just ether pollution. --ANK
1641da177e4SLinus Torvalds 			 */
1651da177e4SLinus Torvalds 			break;
1661da177e4SLinus Torvalds 		}
1671da177e4SLinus Torvalds 		break;
1689f57c67cSPravin B Shelar 
1691da177e4SLinus Torvalds 	case ICMP_TIME_EXCEEDED:
1701da177e4SLinus Torvalds 		if (code != ICMP_EXC_TTL)
1719f57c67cSPravin B Shelar 			return;
1721da177e4SLinus Torvalds 		break;
17355be7a9cSDavid S. Miller 
17455be7a9cSDavid S. Miller 	case ICMP_REDIRECT:
17555be7a9cSDavid S. Miller 		break;
1761da177e4SLinus Torvalds 	}
1771da177e4SLinus Torvalds 
178bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
179c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
180c5441932SPravin B Shelar 	else
181c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
182c5441932SPravin B Shelar 
183c0c0c50fSDuan Jiong 	iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
184bda7bb46SPravin B Shelar 	t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
185bda7bb46SPravin B Shelar 			     iph->daddr, iph->saddr, tpi->key);
186d2083287Sstephen hemminger 
18751456b29SIan Morris 	if (!t)
1889f57c67cSPravin B Shelar 		return;
18936393395SDavid S. Miller 
19036393395SDavid S. Miller 	if (t->parms.iph.daddr == 0 ||
191f97c1e0cSJoe Perches 	    ipv4_is_multicast(t->parms.iph.daddr))
1929f57c67cSPravin B Shelar 		return;
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds 	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
1959f57c67cSPravin B Shelar 		return;
1961da177e4SLinus Torvalds 
197da6185d8SWei Yongjun 	if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
1981da177e4SLinus Torvalds 		t->err_count++;
1991da177e4SLinus Torvalds 	else
2001da177e4SLinus Torvalds 		t->err_count = 1;
2011da177e4SLinus Torvalds 	t->err_time = jiffies;
2029f57c67cSPravin B Shelar }
2039f57c67cSPravin B Shelar 
2049f57c67cSPravin B Shelar static void gre_err(struct sk_buff *skb, u32 info)
2059f57c67cSPravin B Shelar {
2069f57c67cSPravin B Shelar 	/* All the routers (except for Linux) return only
2079f57c67cSPravin B Shelar 	 * 8 bytes of packet payload. It means, that precise relaying of
2089f57c67cSPravin B Shelar 	 * ICMP in the real Internet is absolutely infeasible.
2099f57c67cSPravin B Shelar 	 *
2109f57c67cSPravin B Shelar 	 * Moreover, Cisco "wise men" put GRE key to the third word
2119f57c67cSPravin B Shelar 	 * in GRE header. It makes impossible maintaining even soft
2129f57c67cSPravin B Shelar 	 * state for keyed
2139f57c67cSPravin B Shelar 	 * GRE tunnels with enabled checksum. Tell them "thank you".
2149f57c67cSPravin B Shelar 	 *
2159f57c67cSPravin B Shelar 	 * Well, I wonder, rfc1812 was written by Cisco employee,
2169f57c67cSPravin B Shelar 	 * what the hell these idiots break standards established
2179f57c67cSPravin B Shelar 	 * by themselves???
2189f57c67cSPravin B Shelar 	 */
2199f57c67cSPravin B Shelar 
2209f57c67cSPravin B Shelar 	const int type = icmp_hdr(skb)->type;
2219f57c67cSPravin B Shelar 	const int code = icmp_hdr(skb)->code;
2229f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
2239f57c67cSPravin B Shelar 	bool csum_err = false;
22495f5c64cSTom Herbert 	int hdr_len;
2259f57c67cSPravin B Shelar 
22695f5c64cSTom Herbert 	if (gre_parse_header(skb, &tpi, &csum_err, &hdr_len)) {
2279f57c67cSPravin B Shelar 		if (!csum_err)		/* ignore csum errors. */
2289f57c67cSPravin B Shelar 			return;
2299f57c67cSPravin B Shelar 	}
2309f57c67cSPravin B Shelar 
23195f5c64cSTom Herbert 	if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false))
23295f5c64cSTom Herbert 		return;
23395f5c64cSTom Herbert 
2349f57c67cSPravin B Shelar 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
2359f57c67cSPravin B Shelar 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
2369f57c67cSPravin B Shelar 				 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
2379f57c67cSPravin B Shelar 		return;
2389f57c67cSPravin B Shelar 	}
2399f57c67cSPravin B Shelar 	if (type == ICMP_REDIRECT) {
2409f57c67cSPravin B Shelar 		ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
2419f57c67cSPravin B Shelar 			      IPPROTO_GRE, 0);
2429f57c67cSPravin B Shelar 		return;
2439f57c67cSPravin B Shelar 	}
2449f57c67cSPravin B Shelar 
2459f57c67cSPravin B Shelar 	ipgre_err(skb, info, &tpi);
2461da177e4SLinus Torvalds }
2471da177e4SLinus Torvalds 
2482e15ea39SPravin B Shelar static __be64 key_to_tunnel_id(__be32 key)
2492e15ea39SPravin B Shelar {
2502e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
2512e15ea39SPravin B Shelar 	return (__force __be64)((__force u32)key);
2522e15ea39SPravin B Shelar #else
2532e15ea39SPravin B Shelar 	return (__force __be64)((__force u64)key << 32);
2542e15ea39SPravin B Shelar #endif
2552e15ea39SPravin B Shelar }
2562e15ea39SPravin B Shelar 
2572e15ea39SPravin B Shelar /* Returns the least-significant 32 bits of a __be64. */
2582e15ea39SPravin B Shelar static __be32 tunnel_id_to_key(__be64 x)
2592e15ea39SPravin B Shelar {
2602e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
2612e15ea39SPravin B Shelar 	return (__force __be32)x;
2622e15ea39SPravin B Shelar #else
2632e15ea39SPravin B Shelar 	return (__force __be32)((__force u64)x >> 32);
2642e15ea39SPravin B Shelar #endif
2652e15ea39SPravin B Shelar }
2662e15ea39SPravin B Shelar 
267bda7bb46SPravin B Shelar static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
2681da177e4SLinus Torvalds {
269c5441932SPravin B Shelar 	struct net *net = dev_net(skb->dev);
2702e15ea39SPravin B Shelar 	struct metadata_dst *tun_dst = NULL;
271c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
272b71d1d42SEric Dumazet 	const struct iphdr *iph;
2731da177e4SLinus Torvalds 	struct ip_tunnel *tunnel;
2741da177e4SLinus Torvalds 
275bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
276c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
277c5441932SPravin B Shelar 	else
278c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
279c5441932SPravin B Shelar 
280eddc9ec5SArnaldo Carvalho de Melo 	iph = ip_hdr(skb);
281bda7bb46SPravin B Shelar 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
282bda7bb46SPravin B Shelar 				  iph->saddr, iph->daddr, tpi->key);
2831da177e4SLinus Torvalds 
284d2083287Sstephen hemminger 	if (tunnel) {
2850e3da5bbSTimo Teräs 		skb_pop_mac_header(skb);
2862e15ea39SPravin B Shelar 		if (tunnel->collect_md) {
287c29a70d2SPravin B Shelar 			__be16 flags;
288c29a70d2SPravin B Shelar 			__be64 tun_id;
2892e15ea39SPravin B Shelar 
290c29a70d2SPravin B Shelar 			flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
291c29a70d2SPravin B Shelar 			tun_id = key_to_tunnel_id(tpi->key);
292c29a70d2SPravin B Shelar 			tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
2932e15ea39SPravin B Shelar 			if (!tun_dst)
2942e15ea39SPravin B Shelar 				return PACKET_REJECT;
2952e15ea39SPravin B Shelar 		}
2962e15ea39SPravin B Shelar 
2972e15ea39SPravin B Shelar 		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
298bda7bb46SPravin B Shelar 		return PACKET_RCVD;
2991da177e4SLinus Torvalds 	}
300bda7bb46SPravin B Shelar 	return PACKET_REJECT;
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
3039f57c67cSPravin B Shelar static int gre_rcv(struct sk_buff *skb)
3049f57c67cSPravin B Shelar {
3059f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
3069f57c67cSPravin B Shelar 	bool csum_err = false;
30795f5c64cSTom Herbert 	int hdr_len;
3089f57c67cSPravin B Shelar 
3099f57c67cSPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
3109f57c67cSPravin B Shelar 	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
3119f57c67cSPravin B Shelar 		/* Looped back packet, drop it! */
3129f57c67cSPravin B Shelar 		if (rt_is_output_route(skb_rtable(skb)))
3139f57c67cSPravin B Shelar 			goto drop;
3149f57c67cSPravin B Shelar 	}
3159f57c67cSPravin B Shelar #endif
3169f57c67cSPravin B Shelar 
31795f5c64cSTom Herbert 	if (gre_parse_header(skb, &tpi, &csum_err, &hdr_len) < 0)
31895f5c64cSTom Herbert 		goto drop;
31995f5c64cSTom Herbert 
32095f5c64cSTom Herbert 	if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false))
3219f57c67cSPravin B Shelar 		goto drop;
3229f57c67cSPravin B Shelar 
3239f57c67cSPravin B Shelar 	if (ipgre_rcv(skb, &tpi) == PACKET_RCVD)
3249f57c67cSPravin B Shelar 		return 0;
3259f57c67cSPravin B Shelar 
3269f57c67cSPravin B Shelar 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
3279f57c67cSPravin B Shelar drop:
3289f57c67cSPravin B Shelar 	kfree_skb(skb);
3299f57c67cSPravin B Shelar 	return 0;
3309f57c67cSPravin B Shelar }
3319f57c67cSPravin B Shelar 
332c5441932SPravin B Shelar static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
333c5441932SPravin B Shelar 		       const struct iphdr *tnl_params,
334c5441932SPravin B Shelar 		       __be16 proto)
335c5441932SPravin B Shelar {
336c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
337c5441932SPravin B Shelar 
338c5441932SPravin B Shelar 	if (tunnel->parms.o_flags & TUNNEL_SEQ)
339c5441932SPravin B Shelar 		tunnel->o_seqno++;
340cef401deSEric Dumazet 
341c5441932SPravin B Shelar 	/* Push GRE header. */
342182a352dSTom Herbert 	gre_build_header(skb, tunnel->tun_hlen,
343182a352dSTom Herbert 			 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
344182a352dSTom Herbert 			 htonl(tunnel->o_seqno));
3451da177e4SLinus Torvalds 
3462e15ea39SPravin B Shelar 	skb_set_inner_protocol(skb, proto);
347bf3d6a8fSNicolas Dichtel 	ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
3481da177e4SLinus Torvalds }
3491da177e4SLinus Torvalds 
350aed069dfSAlexander Duyck static int gre_handle_offloads(struct sk_buff *skb, bool csum)
351b2acd1dcSPravin B Shelar {
3526fa79666SEdward Cree 	return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
353b2acd1dcSPravin B Shelar }
354b2acd1dcSPravin B Shelar 
355fc4099f1SPravin B Shelar static struct rtable *gre_get_rt(struct sk_buff *skb,
356fc4099f1SPravin B Shelar 				 struct net_device *dev,
357fc4099f1SPravin B Shelar 				 struct flowi4 *fl,
358fc4099f1SPravin B Shelar 				 const struct ip_tunnel_key *key)
359fc4099f1SPravin B Shelar {
360fc4099f1SPravin B Shelar 	struct net *net = dev_net(dev);
361fc4099f1SPravin B Shelar 
362fc4099f1SPravin B Shelar 	memset(fl, 0, sizeof(*fl));
363fc4099f1SPravin B Shelar 	fl->daddr = key->u.ipv4.dst;
364fc4099f1SPravin B Shelar 	fl->saddr = key->u.ipv4.src;
365fc4099f1SPravin B Shelar 	fl->flowi4_tos = RT_TOS(key->tos);
366fc4099f1SPravin B Shelar 	fl->flowi4_mark = skb->mark;
367fc4099f1SPravin B Shelar 	fl->flowi4_proto = IPPROTO_GRE;
368fc4099f1SPravin B Shelar 
369fc4099f1SPravin B Shelar 	return ip_route_output_key(net, fl);
370fc4099f1SPravin B Shelar }
371fc4099f1SPravin B Shelar 
3722090714eSJiri Benc static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
3732090714eSJiri Benc 			__be16 proto)
3742e15ea39SPravin B Shelar {
3752e15ea39SPravin B Shelar 	struct ip_tunnel_info *tun_info;
3762e15ea39SPravin B Shelar 	const struct ip_tunnel_key *key;
377db3c6139SDaniel Borkmann 	struct rtable *rt = NULL;
3782e15ea39SPravin B Shelar 	struct flowi4 fl;
3792e15ea39SPravin B Shelar 	int min_headroom;
3802e15ea39SPravin B Shelar 	int tunnel_hlen;
3812e15ea39SPravin B Shelar 	__be16 df, flags;
382db3c6139SDaniel Borkmann 	bool use_cache;
3832e15ea39SPravin B Shelar 	int err;
3842e15ea39SPravin B Shelar 
38561adedf3SJiri Benc 	tun_info = skb_tunnel_info(skb);
3867f9562a1SJiri Benc 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
3877f9562a1SJiri Benc 		     ip_tunnel_info_af(tun_info) != AF_INET))
3882e15ea39SPravin B Shelar 		goto err_free_skb;
3892e15ea39SPravin B Shelar 
3902e15ea39SPravin B Shelar 	key = &tun_info->key;
391db3c6139SDaniel Borkmann 	use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
392db3c6139SDaniel Borkmann 	if (use_cache)
393db3c6139SDaniel Borkmann 		rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
3943c1cb4d2SPaolo Abeni 	if (!rt) {
395fc4099f1SPravin B Shelar 		rt = gre_get_rt(skb, dev, &fl, key);
3962e15ea39SPravin B Shelar 		if (IS_ERR(rt))
3972e15ea39SPravin B Shelar 				goto err_free_skb;
398db3c6139SDaniel Borkmann 		if (use_cache)
3993c1cb4d2SPaolo Abeni 			dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
4003c1cb4d2SPaolo Abeni 					  fl.saddr);
4013c1cb4d2SPaolo Abeni 	}
4022e15ea39SPravin B Shelar 
40395f5c64cSTom Herbert 	tunnel_hlen = gre_calc_hlen(key->tun_flags);
4042e15ea39SPravin B Shelar 
4052e15ea39SPravin B Shelar 	min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
4062e15ea39SPravin B Shelar 			+ tunnel_hlen + sizeof(struct iphdr);
4072e15ea39SPravin B Shelar 	if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
4082e15ea39SPravin B Shelar 		int head_delta = SKB_DATA_ALIGN(min_headroom -
4092e15ea39SPravin B Shelar 						skb_headroom(skb) +
4102e15ea39SPravin B Shelar 						16);
4112e15ea39SPravin B Shelar 		err = pskb_expand_head(skb, max_t(int, head_delta, 0),
4122e15ea39SPravin B Shelar 				       0, GFP_ATOMIC);
4132e15ea39SPravin B Shelar 		if (unlikely(err))
4142e15ea39SPravin B Shelar 			goto err_free_rt;
4152e15ea39SPravin B Shelar 	}
4162e15ea39SPravin B Shelar 
4172e15ea39SPravin B Shelar 	/* Push Tunnel header. */
418aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
4192e15ea39SPravin B Shelar 		goto err_free_rt;
4202e15ea39SPravin B Shelar 
4212e15ea39SPravin B Shelar 	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
422*cba65321SDavid S. Miller 	gre_build_header(skb, tunnel_hlen, flags, proto,
4232e15ea39SPravin B Shelar 			 tunnel_id_to_key(tun_info->key.tun_id), 0);
4242e15ea39SPravin B Shelar 
4252e15ea39SPravin B Shelar 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
426039f5062SPravin B Shelar 
427039f5062SPravin B Shelar 	iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
4287c383fb2SJiri Benc 		      key->tos, key->ttl, df, false);
4292e15ea39SPravin B Shelar 	return;
4302e15ea39SPravin B Shelar 
4312e15ea39SPravin B Shelar err_free_rt:
4322e15ea39SPravin B Shelar 	ip_rt_put(rt);
4332e15ea39SPravin B Shelar err_free_skb:
4342e15ea39SPravin B Shelar 	kfree_skb(skb);
4352e15ea39SPravin B Shelar 	dev->stats.tx_dropped++;
4362e15ea39SPravin B Shelar }
4372e15ea39SPravin B Shelar 
438fc4099f1SPravin B Shelar static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
439fc4099f1SPravin B Shelar {
440fc4099f1SPravin B Shelar 	struct ip_tunnel_info *info = skb_tunnel_info(skb);
441fc4099f1SPravin B Shelar 	struct rtable *rt;
442fc4099f1SPravin B Shelar 	struct flowi4 fl4;
443fc4099f1SPravin B Shelar 
444fc4099f1SPravin B Shelar 	if (ip_tunnel_info_af(info) != AF_INET)
445fc4099f1SPravin B Shelar 		return -EINVAL;
446fc4099f1SPravin B Shelar 
447fc4099f1SPravin B Shelar 	rt = gre_get_rt(skb, dev, &fl4, &info->key);
448fc4099f1SPravin B Shelar 	if (IS_ERR(rt))
449fc4099f1SPravin B Shelar 		return PTR_ERR(rt);
450fc4099f1SPravin B Shelar 
451fc4099f1SPravin B Shelar 	ip_rt_put(rt);
452fc4099f1SPravin B Shelar 	info->key.u.ipv4.src = fl4.saddr;
453fc4099f1SPravin B Shelar 	return 0;
454fc4099f1SPravin B Shelar }
455fc4099f1SPravin B Shelar 
456c5441932SPravin B Shelar static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
457c5441932SPravin B Shelar 			      struct net_device *dev)
458ee34c1ebSMichal Schmidt {
459c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
460c5441932SPravin B Shelar 	const struct iphdr *tnl_params;
461ee34c1ebSMichal Schmidt 
4622e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
4632090714eSJiri Benc 		gre_fb_xmit(skb, dev, skb->protocol);
4642e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
4652e15ea39SPravin B Shelar 	}
4662e15ea39SPravin B Shelar 
467c5441932SPravin B Shelar 	if (dev->header_ops) {
468c5441932SPravin B Shelar 		/* Need space for new headers */
469c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom -
4702bac7cb3SChen Gang 				      (tunnel->hlen + sizeof(struct iphdr))))
471c5441932SPravin B Shelar 			goto free_skb;
472ee34c1ebSMichal Schmidt 
473c5441932SPravin B Shelar 		tnl_params = (const struct iphdr *)skb->data;
474cbb1e85fSDavid S. Miller 
475c5441932SPravin B Shelar 		/* Pull skb since ip_tunnel_xmit() needs skb->data pointing
476c5441932SPravin B Shelar 		 * to gre header.
477c5441932SPravin B Shelar 		 */
478c5441932SPravin B Shelar 		skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
4798a0033a9STimo Teräs 		skb_reset_mac_header(skb);
480c5441932SPravin B Shelar 	} else {
481c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom))
482c5441932SPravin B Shelar 			goto free_skb;
483c5441932SPravin B Shelar 
484c5441932SPravin B Shelar 		tnl_params = &tunnel->parms.iph;
485ee34c1ebSMichal Schmidt 	}
486e1a80002SHerbert Xu 
487aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
488aed069dfSAlexander Duyck 		goto free_skb;
4898a0033a9STimo Teräs 
490c5441932SPravin B Shelar 	__gre_xmit(skb, dev, tnl_params, skb->protocol);
491c5441932SPravin B Shelar 	return NETDEV_TX_OK;
492c5441932SPravin B Shelar 
493c5441932SPravin B Shelar free_skb:
4943acfa1e7SEric Dumazet 	kfree_skb(skb);
495c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
496c5441932SPravin B Shelar 	return NETDEV_TX_OK;
497ee34c1ebSMichal Schmidt }
498ee34c1ebSMichal Schmidt 
499c5441932SPravin B Shelar static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
500c5441932SPravin B Shelar 				struct net_device *dev)
501c5441932SPravin B Shelar {
502c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
503ee34c1ebSMichal Schmidt 
5042e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
5052090714eSJiri Benc 		gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
5062e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
5072e15ea39SPravin B Shelar 	}
5082e15ea39SPravin B Shelar 
509aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
510aed069dfSAlexander Duyck 		goto free_skb;
511ee34c1ebSMichal Schmidt 
512c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom))
513c5441932SPravin B Shelar 		goto free_skb;
51442aa9162SHerbert Xu 
515c5441932SPravin B Shelar 	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
516c5441932SPravin B Shelar 	return NETDEV_TX_OK;
517c5441932SPravin B Shelar 
518c5441932SPravin B Shelar free_skb:
5193acfa1e7SEric Dumazet 	kfree_skb(skb);
520c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
521c5441932SPravin B Shelar 	return NETDEV_TX_OK;
52268c33163SPravin B Shelar }
523ee34c1ebSMichal Schmidt 
524c5441932SPravin B Shelar static int ipgre_tunnel_ioctl(struct net_device *dev,
525c5441932SPravin B Shelar 			      struct ifreq *ifr, int cmd)
5261da177e4SLinus Torvalds {
5274565e991STom Herbert 	int err;
5281da177e4SLinus Torvalds 	struct ip_tunnel_parm p;
5291da177e4SLinus Torvalds 
5301da177e4SLinus Torvalds 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
531c5441932SPravin B Shelar 		return -EFAULT;
5326c734fb8SCong Wang 	if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
5331da177e4SLinus Torvalds 		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
5341da177e4SLinus Torvalds 		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
5356c734fb8SCong Wang 		    ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
5361da177e4SLinus Torvalds 			return -EINVAL;
537c5441932SPravin B Shelar 	}
538c5441932SPravin B Shelar 	p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
539c5441932SPravin B Shelar 	p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
540c5441932SPravin B Shelar 
541c5441932SPravin B Shelar 	err = ip_tunnel_ioctl(dev, &p, cmd);
542c5441932SPravin B Shelar 	if (err)
543c5441932SPravin B Shelar 		return err;
544c5441932SPravin B Shelar 
54595f5c64cSTom Herbert 	p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
54695f5c64cSTom Herbert 	p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
547c5441932SPravin B Shelar 
548c5441932SPravin B Shelar 	if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
549c5441932SPravin B Shelar 		return -EFAULT;
5501da177e4SLinus Torvalds 	return 0;
5511da177e4SLinus Torvalds }
5521da177e4SLinus Torvalds 
5531da177e4SLinus Torvalds /* Nice toy. Unfortunately, useless in real life :-)
5541da177e4SLinus Torvalds    It allows to construct virtual multiprotocol broadcast "LAN"
5551da177e4SLinus Torvalds    over the Internet, provided multicast routing is tuned.
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds    I have no idea was this bicycle invented before me,
5591da177e4SLinus Torvalds    so that I had to set ARPHRD_IPGRE to a random value.
5601da177e4SLinus Torvalds    I have an impression, that Cisco could make something similar,
5611da177e4SLinus Torvalds    but this feature is apparently missing in IOS<=11.2(8).
5621da177e4SLinus Torvalds 
5631da177e4SLinus Torvalds    I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
5641da177e4SLinus Torvalds    with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds    ping -t 255 224.66.66.66
5671da177e4SLinus Torvalds 
5681da177e4SLinus Torvalds    If nobody answers, mbone does not work.
5691da177e4SLinus Torvalds 
5701da177e4SLinus Torvalds    ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
5711da177e4SLinus Torvalds    ip addr add 10.66.66.<somewhat>/24 dev Universe
5721da177e4SLinus Torvalds    ifconfig Universe up
5731da177e4SLinus Torvalds    ifconfig Universe add fe80::<Your_real_addr>/10
5741da177e4SLinus Torvalds    ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
5751da177e4SLinus Torvalds    ftp 10.66.66.66
5761da177e4SLinus Torvalds    ...
5771da177e4SLinus Torvalds    ftp fec0:6666:6666::193.233.7.65
5781da177e4SLinus Torvalds    ...
5791da177e4SLinus Torvalds  */
5803b04dddeSStephen Hemminger static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
5813b04dddeSStephen Hemminger 			unsigned short type,
5821507850bSEric Dumazet 			const void *daddr, const void *saddr, unsigned int len)
5831da177e4SLinus Torvalds {
5842941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
585c5441932SPravin B Shelar 	struct iphdr *iph;
586c5441932SPravin B Shelar 	struct gre_base_hdr *greh;
587c5441932SPravin B Shelar 
588c5441932SPravin B Shelar 	iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
589c5441932SPravin B Shelar 	greh = (struct gre_base_hdr *)(iph+1);
59095f5c64cSTom Herbert 	greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
591c5441932SPravin B Shelar 	greh->protocol = htons(type);
5921da177e4SLinus Torvalds 
5931da177e4SLinus Torvalds 	memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
5941da177e4SLinus Torvalds 
595c5441932SPravin B Shelar 	/* Set the source hardware address. */
5961da177e4SLinus Torvalds 	if (saddr)
5971da177e4SLinus Torvalds 		memcpy(&iph->saddr, saddr, 4);
5986d55cb91STimo Teräs 	if (daddr)
5991da177e4SLinus Torvalds 		memcpy(&iph->daddr, daddr, 4);
6006d55cb91STimo Teräs 	if (iph->daddr)
60177a482bdSTimo Teräs 		return t->hlen + sizeof(*iph);
6021da177e4SLinus Torvalds 
603c5441932SPravin B Shelar 	return -(t->hlen + sizeof(*iph));
6041da177e4SLinus Torvalds }
6051da177e4SLinus Torvalds 
6066a5f44d7STimo Teras static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
6076a5f44d7STimo Teras {
608b71d1d42SEric Dumazet 	const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
6096a5f44d7STimo Teras 	memcpy(haddr, &iph->saddr, 4);
6106a5f44d7STimo Teras 	return 4;
6116a5f44d7STimo Teras }
6126a5f44d7STimo Teras 
6133b04dddeSStephen Hemminger static const struct header_ops ipgre_header_ops = {
6143b04dddeSStephen Hemminger 	.create	= ipgre_header,
6156a5f44d7STimo Teras 	.parse	= ipgre_header_parse,
6163b04dddeSStephen Hemminger };
6173b04dddeSStephen Hemminger 
6186a5f44d7STimo Teras #ifdef CONFIG_NET_IPGRE_BROADCAST
6191da177e4SLinus Torvalds static int ipgre_open(struct net_device *dev)
6201da177e4SLinus Torvalds {
6212941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
6221da177e4SLinus Torvalds 
623f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr)) {
624cbb1e85fSDavid S. Miller 		struct flowi4 fl4;
625cbb1e85fSDavid S. Miller 		struct rtable *rt;
626cbb1e85fSDavid S. Miller 
627b57708adSNicolas Dichtel 		rt = ip_route_output_gre(t->net, &fl4,
62878fbfd8aSDavid S. Miller 					 t->parms.iph.daddr,
62978fbfd8aSDavid S. Miller 					 t->parms.iph.saddr,
63078fbfd8aSDavid S. Miller 					 t->parms.o_key,
63178fbfd8aSDavid S. Miller 					 RT_TOS(t->parms.iph.tos),
63278fbfd8aSDavid S. Miller 					 t->parms.link);
633b23dd4feSDavid S. Miller 		if (IS_ERR(rt))
6341da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
635d8d1f30bSChangli Gao 		dev = rt->dst.dev;
6361da177e4SLinus Torvalds 		ip_rt_put(rt);
63751456b29SIan Morris 		if (!__in_dev_get_rtnl(dev))
6381da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
6391da177e4SLinus Torvalds 		t->mlink = dev->ifindex;
640e5ed6399SHerbert Xu 		ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
6411da177e4SLinus Torvalds 	}
6421da177e4SLinus Torvalds 	return 0;
6431da177e4SLinus Torvalds }
6441da177e4SLinus Torvalds 
6451da177e4SLinus Torvalds static int ipgre_close(struct net_device *dev)
6461da177e4SLinus Torvalds {
6472941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
648b8c26a33SStephen Hemminger 
649f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
6507fee0ca2SDenis V. Lunev 		struct in_device *in_dev;
651b57708adSNicolas Dichtel 		in_dev = inetdev_by_index(t->net, t->mlink);
6528723e1b4SEric Dumazet 		if (in_dev)
6531da177e4SLinus Torvalds 			ip_mc_dec_group(in_dev, t->parms.iph.daddr);
6541da177e4SLinus Torvalds 	}
6551da177e4SLinus Torvalds 	return 0;
6561da177e4SLinus Torvalds }
6571da177e4SLinus Torvalds #endif
6581da177e4SLinus Torvalds 
659b8c26a33SStephen Hemminger static const struct net_device_ops ipgre_netdev_ops = {
660b8c26a33SStephen Hemminger 	.ndo_init		= ipgre_tunnel_init,
661c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
662b8c26a33SStephen Hemminger #ifdef CONFIG_NET_IPGRE_BROADCAST
663b8c26a33SStephen Hemminger 	.ndo_open		= ipgre_open,
664b8c26a33SStephen Hemminger 	.ndo_stop		= ipgre_close,
665b8c26a33SStephen Hemminger #endif
666c5441932SPravin B Shelar 	.ndo_start_xmit		= ipgre_xmit,
667b8c26a33SStephen Hemminger 	.ndo_do_ioctl		= ipgre_tunnel_ioctl,
668c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
669c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
6701e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
671b8c26a33SStephen Hemminger };
672b8c26a33SStephen Hemminger 
6736b78f16eSEric Dumazet #define GRE_FEATURES (NETIF_F_SG |		\
6746b78f16eSEric Dumazet 		      NETIF_F_FRAGLIST |	\
6756b78f16eSEric Dumazet 		      NETIF_F_HIGHDMA |		\
6766b78f16eSEric Dumazet 		      NETIF_F_HW_CSUM)
6776b78f16eSEric Dumazet 
6781da177e4SLinus Torvalds static void ipgre_tunnel_setup(struct net_device *dev)
6791da177e4SLinus Torvalds {
680b8c26a33SStephen Hemminger 	dev->netdev_ops		= &ipgre_netdev_ops;
6815a455275SNicolas Dichtel 	dev->type		= ARPHRD_IPGRE;
682c5441932SPravin B Shelar 	ip_tunnel_setup(dev, ipgre_net_id);
683c5441932SPravin B Shelar }
6841da177e4SLinus Torvalds 
685c5441932SPravin B Shelar static void __gre_tunnel_init(struct net_device *dev)
686c5441932SPravin B Shelar {
687c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
6884565e991STom Herbert 	int t_hlen;
689c5441932SPravin B Shelar 
690c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
69195f5c64cSTom Herbert 	tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
692c5441932SPravin B Shelar 	tunnel->parms.iph.protocol = IPPROTO_GRE;
693c5441932SPravin B Shelar 
6944565e991STom Herbert 	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
6954565e991STom Herbert 
6964565e991STom Herbert 	t_hlen = tunnel->hlen + sizeof(struct iphdr);
6974565e991STom Herbert 
6984565e991STom Herbert 	dev->needed_headroom	= LL_MAX_HEADER + t_hlen + 4;
6994565e991STom Herbert 	dev->mtu		= ETH_DATA_LEN - t_hlen - 4;
7006b78f16eSEric Dumazet 
701b57708adSNicolas Dichtel 	dev->features		|= GRE_FEATURES;
7026b78f16eSEric Dumazet 	dev->hw_features	|= GRE_FEATURES;
703c5441932SPravin B Shelar 
704c5441932SPravin B Shelar 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
705a0ca153fSAlexander Duyck 		/* TCP offload with GRE SEQ is not supported, nor
706a0ca153fSAlexander Duyck 		 * can we support 2 levels of outer headers requiring
707a0ca153fSAlexander Duyck 		 * an update.
708a0ca153fSAlexander Duyck 		 */
709a0ca153fSAlexander Duyck 		if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
710a0ca153fSAlexander Duyck 		    (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
711c5441932SPravin B Shelar 			dev->features    |= NETIF_F_GSO_SOFTWARE;
712c5441932SPravin B Shelar 			dev->hw_features |= NETIF_F_GSO_SOFTWARE;
713a0ca153fSAlexander Duyck 		}
714a0ca153fSAlexander Duyck 
715c5441932SPravin B Shelar 		/* Can use a lockless transmit, unless we generate
716c5441932SPravin B Shelar 		 * output sequences
717c5441932SPravin B Shelar 		 */
718c5441932SPravin B Shelar 		dev->features |= NETIF_F_LLTX;
719c5441932SPravin B Shelar 	}
7201da177e4SLinus Torvalds }
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev)
7231da177e4SLinus Torvalds {
724c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
725c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
7261da177e4SLinus Torvalds 
727c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
7281da177e4SLinus Torvalds 
729c5441932SPravin B Shelar 	memcpy(dev->dev_addr, &iph->saddr, 4);
730c5441932SPravin B Shelar 	memcpy(dev->broadcast, &iph->daddr, 4);
7311da177e4SLinus Torvalds 
732c5441932SPravin B Shelar 	dev->flags		= IFF_NOARP;
73302875878SEric Dumazet 	netif_keep_dst(dev);
734c5441932SPravin B Shelar 	dev->addr_len		= 4;
7351da177e4SLinus Torvalds 
736a64b04d8SJiri Benc 	if (iph->daddr && !tunnel->collect_md) {
7371da177e4SLinus Torvalds #ifdef CONFIG_NET_IPGRE_BROADCAST
738f97c1e0cSJoe Perches 		if (ipv4_is_multicast(iph->daddr)) {
7391da177e4SLinus Torvalds 			if (!iph->saddr)
7401da177e4SLinus Torvalds 				return -EINVAL;
7411da177e4SLinus Torvalds 			dev->flags = IFF_BROADCAST;
7423b04dddeSStephen Hemminger 			dev->header_ops = &ipgre_header_ops;
7431da177e4SLinus Torvalds 		}
7441da177e4SLinus Torvalds #endif
745a64b04d8SJiri Benc 	} else if (!tunnel->collect_md) {
7466a5f44d7STimo Teras 		dev->header_ops = &ipgre_header_ops;
747a64b04d8SJiri Benc 	}
7481da177e4SLinus Torvalds 
749c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
75060769a5dSEric Dumazet }
75160769a5dSEric Dumazet 
7529f57c67cSPravin B Shelar static const struct gre_protocol ipgre_protocol = {
7539f57c67cSPravin B Shelar 	.handler     = gre_rcv,
7549f57c67cSPravin B Shelar 	.err_handler = gre_err,
7551da177e4SLinus Torvalds };
7561da177e4SLinus Torvalds 
7572c8c1e72SAlexey Dobriyan static int __net_init ipgre_init_net(struct net *net)
75859a4c759SPavel Emelyanov {
759c5441932SPravin B Shelar 	return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
76059a4c759SPavel Emelyanov }
76159a4c759SPavel Emelyanov 
7622c8c1e72SAlexey Dobriyan static void __net_exit ipgre_exit_net(struct net *net)
76359a4c759SPavel Emelyanov {
764c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
7656c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_link_ops);
76659a4c759SPavel Emelyanov }
76759a4c759SPavel Emelyanov 
76859a4c759SPavel Emelyanov static struct pernet_operations ipgre_net_ops = {
76959a4c759SPavel Emelyanov 	.init = ipgre_init_net,
77059a4c759SPavel Emelyanov 	.exit = ipgre_exit_net,
771cfb8fbf2SEric W. Biederman 	.id   = &ipgre_net_id,
772c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
77359a4c759SPavel Emelyanov };
7741da177e4SLinus Torvalds 
775c19e654dSHerbert Xu static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
776c19e654dSHerbert Xu {
777c19e654dSHerbert Xu 	__be16 flags;
778c19e654dSHerbert Xu 
779c19e654dSHerbert Xu 	if (!data)
780c19e654dSHerbert Xu 		return 0;
781c19e654dSHerbert Xu 
782c19e654dSHerbert Xu 	flags = 0;
783c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
784c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
785c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
786c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
787c19e654dSHerbert Xu 	if (flags & (GRE_VERSION|GRE_ROUTING))
788c19e654dSHerbert Xu 		return -EINVAL;
789c19e654dSHerbert Xu 
790946b636fSJiri Benc 	if (data[IFLA_GRE_COLLECT_METADATA] &&
791946b636fSJiri Benc 	    data[IFLA_GRE_ENCAP_TYPE] &&
792946b636fSJiri Benc 	    nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
793946b636fSJiri Benc 		return -EINVAL;
794946b636fSJiri Benc 
795c19e654dSHerbert Xu 	return 0;
796c19e654dSHerbert Xu }
797c19e654dSHerbert Xu 
798e1a80002SHerbert Xu static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
799e1a80002SHerbert Xu {
800e1a80002SHerbert Xu 	__be32 daddr;
801e1a80002SHerbert Xu 
802e1a80002SHerbert Xu 	if (tb[IFLA_ADDRESS]) {
803e1a80002SHerbert Xu 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
804e1a80002SHerbert Xu 			return -EINVAL;
805e1a80002SHerbert Xu 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
806e1a80002SHerbert Xu 			return -EADDRNOTAVAIL;
807e1a80002SHerbert Xu 	}
808e1a80002SHerbert Xu 
809e1a80002SHerbert Xu 	if (!data)
810e1a80002SHerbert Xu 		goto out;
811e1a80002SHerbert Xu 
812e1a80002SHerbert Xu 	if (data[IFLA_GRE_REMOTE]) {
813e1a80002SHerbert Xu 		memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
814e1a80002SHerbert Xu 		if (!daddr)
815e1a80002SHerbert Xu 			return -EINVAL;
816e1a80002SHerbert Xu 	}
817e1a80002SHerbert Xu 
818e1a80002SHerbert Xu out:
819e1a80002SHerbert Xu 	return ipgre_tunnel_validate(tb, data);
820e1a80002SHerbert Xu }
821e1a80002SHerbert Xu 
8222e15ea39SPravin B Shelar static void ipgre_netlink_parms(struct net_device *dev,
8232e15ea39SPravin B Shelar 				struct nlattr *data[],
8242e15ea39SPravin B Shelar 				struct nlattr *tb[],
825c19e654dSHerbert Xu 				struct ip_tunnel_parm *parms)
826c19e654dSHerbert Xu {
8277bb82d92SHerbert Xu 	memset(parms, 0, sizeof(*parms));
828c19e654dSHerbert Xu 
829c19e654dSHerbert Xu 	parms->iph.protocol = IPPROTO_GRE;
830c19e654dSHerbert Xu 
831c19e654dSHerbert Xu 	if (!data)
832c19e654dSHerbert Xu 		return;
833c19e654dSHerbert Xu 
834c19e654dSHerbert Xu 	if (data[IFLA_GRE_LINK])
835c19e654dSHerbert Xu 		parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
836c19e654dSHerbert Xu 
837c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
838c5441932SPravin B Shelar 		parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
839c19e654dSHerbert Xu 
840c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
841c5441932SPravin B Shelar 		parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
842c19e654dSHerbert Xu 
843c19e654dSHerbert Xu 	if (data[IFLA_GRE_IKEY])
844c19e654dSHerbert Xu 		parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
845c19e654dSHerbert Xu 
846c19e654dSHerbert Xu 	if (data[IFLA_GRE_OKEY])
847c19e654dSHerbert Xu 		parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
848c19e654dSHerbert Xu 
849c19e654dSHerbert Xu 	if (data[IFLA_GRE_LOCAL])
85067b61f6cSJiri Benc 		parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
851c19e654dSHerbert Xu 
852c19e654dSHerbert Xu 	if (data[IFLA_GRE_REMOTE])
85367b61f6cSJiri Benc 		parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
854c19e654dSHerbert Xu 
855c19e654dSHerbert Xu 	if (data[IFLA_GRE_TTL])
856c19e654dSHerbert Xu 		parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
857c19e654dSHerbert Xu 
858c19e654dSHerbert Xu 	if (data[IFLA_GRE_TOS])
859c19e654dSHerbert Xu 		parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
860c19e654dSHerbert Xu 
861c19e654dSHerbert Xu 	if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC]))
862c19e654dSHerbert Xu 		parms->iph.frag_off = htons(IP_DF);
8632e15ea39SPravin B Shelar 
8642e15ea39SPravin B Shelar 	if (data[IFLA_GRE_COLLECT_METADATA]) {
8652e15ea39SPravin B Shelar 		struct ip_tunnel *t = netdev_priv(dev);
8662e15ea39SPravin B Shelar 
8672e15ea39SPravin B Shelar 		t->collect_md = true;
8682e15ea39SPravin B Shelar 	}
869c19e654dSHerbert Xu }
870c19e654dSHerbert Xu 
8714565e991STom Herbert /* This function returns true when ENCAP attributes are present in the nl msg */
8724565e991STom Herbert static bool ipgre_netlink_encap_parms(struct nlattr *data[],
8734565e991STom Herbert 				      struct ip_tunnel_encap *ipencap)
8744565e991STom Herbert {
8754565e991STom Herbert 	bool ret = false;
8764565e991STom Herbert 
8774565e991STom Herbert 	memset(ipencap, 0, sizeof(*ipencap));
8784565e991STom Herbert 
8794565e991STom Herbert 	if (!data)
8804565e991STom Herbert 		return ret;
8814565e991STom Herbert 
8824565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_TYPE]) {
8834565e991STom Herbert 		ret = true;
8844565e991STom Herbert 		ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
8854565e991STom Herbert 	}
8864565e991STom Herbert 
8874565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_FLAGS]) {
8884565e991STom Herbert 		ret = true;
8894565e991STom Herbert 		ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
8904565e991STom Herbert 	}
8914565e991STom Herbert 
8924565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_SPORT]) {
8934565e991STom Herbert 		ret = true;
8943e97fa70SSabrina Dubroca 		ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
8954565e991STom Herbert 	}
8964565e991STom Herbert 
8974565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_DPORT]) {
8984565e991STom Herbert 		ret = true;
8993e97fa70SSabrina Dubroca 		ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
9004565e991STom Herbert 	}
9014565e991STom Herbert 
9024565e991STom Herbert 	return ret;
9034565e991STom Herbert }
9044565e991STom Herbert 
905c5441932SPravin B Shelar static int gre_tap_init(struct net_device *dev)
906e1a80002SHerbert Xu {
907c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
908bec94d43Sstephen hemminger 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
909e1a80002SHerbert Xu 
910c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
911e1a80002SHerbert Xu }
912e1a80002SHerbert Xu 
913c5441932SPravin B Shelar static const struct net_device_ops gre_tap_netdev_ops = {
914c5441932SPravin B Shelar 	.ndo_init		= gre_tap_init,
915c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
916c5441932SPravin B Shelar 	.ndo_start_xmit		= gre_tap_xmit,
917b8c26a33SStephen Hemminger 	.ndo_set_mac_address 	= eth_mac_addr,
918b8c26a33SStephen Hemminger 	.ndo_validate_addr	= eth_validate_addr,
919c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
920c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
9211e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
922fc4099f1SPravin B Shelar 	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
923b8c26a33SStephen Hemminger };
924b8c26a33SStephen Hemminger 
925e1a80002SHerbert Xu static void ipgre_tap_setup(struct net_device *dev)
926e1a80002SHerbert Xu {
927e1a80002SHerbert Xu 	ether_setup(dev);
928c5441932SPravin B Shelar 	dev->netdev_ops	= &gre_tap_netdev_ops;
929d13b161cSJiri Benc 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
930f8c1b7ceSstephen hemminger 	dev->priv_flags	|= IFF_LIVE_ADDR_CHANGE;
931c5441932SPravin B Shelar 	ip_tunnel_setup(dev, gre_tap_net_id);
932e1a80002SHerbert Xu }
933e1a80002SHerbert Xu 
934c5441932SPravin B Shelar static int ipgre_newlink(struct net *src_net, struct net_device *dev,
935c5441932SPravin B Shelar 			 struct nlattr *tb[], struct nlattr *data[])
936c19e654dSHerbert Xu {
937c5441932SPravin B Shelar 	struct ip_tunnel_parm p;
9384565e991STom Herbert 	struct ip_tunnel_encap ipencap;
9394565e991STom Herbert 
9404565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
9414565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
9424565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
9434565e991STom Herbert 
9444565e991STom Herbert 		if (err < 0)
9454565e991STom Herbert 			return err;
9464565e991STom Herbert 	}
947c19e654dSHerbert Xu 
9482e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
949c5441932SPravin B Shelar 	return ip_tunnel_newlink(dev, tb, &p);
950c19e654dSHerbert Xu }
951c19e654dSHerbert Xu 
952c19e654dSHerbert Xu static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
953c19e654dSHerbert Xu 			    struct nlattr *data[])
954c19e654dSHerbert Xu {
955c19e654dSHerbert Xu 	struct ip_tunnel_parm p;
9564565e991STom Herbert 	struct ip_tunnel_encap ipencap;
9574565e991STom Herbert 
9584565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
9594565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
9604565e991STom Herbert 		int err = ip_tunnel_encap_setup(t, &ipencap);
9614565e991STom Herbert 
9624565e991STom Herbert 		if (err < 0)
9634565e991STom Herbert 			return err;
9644565e991STom Herbert 	}
965c19e654dSHerbert Xu 
9662e15ea39SPravin B Shelar 	ipgre_netlink_parms(dev, data, tb, &p);
967c5441932SPravin B Shelar 	return ip_tunnel_changelink(dev, tb, &p);
968c19e654dSHerbert Xu }
969c19e654dSHerbert Xu 
970c19e654dSHerbert Xu static size_t ipgre_get_size(const struct net_device *dev)
971c19e654dSHerbert Xu {
972c19e654dSHerbert Xu 	return
973c19e654dSHerbert Xu 		/* IFLA_GRE_LINK */
974c19e654dSHerbert Xu 		nla_total_size(4) +
975c19e654dSHerbert Xu 		/* IFLA_GRE_IFLAGS */
976c19e654dSHerbert Xu 		nla_total_size(2) +
977c19e654dSHerbert Xu 		/* IFLA_GRE_OFLAGS */
978c19e654dSHerbert Xu 		nla_total_size(2) +
979c19e654dSHerbert Xu 		/* IFLA_GRE_IKEY */
980c19e654dSHerbert Xu 		nla_total_size(4) +
981c19e654dSHerbert Xu 		/* IFLA_GRE_OKEY */
982c19e654dSHerbert Xu 		nla_total_size(4) +
983c19e654dSHerbert Xu 		/* IFLA_GRE_LOCAL */
984c19e654dSHerbert Xu 		nla_total_size(4) +
985c19e654dSHerbert Xu 		/* IFLA_GRE_REMOTE */
986c19e654dSHerbert Xu 		nla_total_size(4) +
987c19e654dSHerbert Xu 		/* IFLA_GRE_TTL */
988c19e654dSHerbert Xu 		nla_total_size(1) +
989c19e654dSHerbert Xu 		/* IFLA_GRE_TOS */
990c19e654dSHerbert Xu 		nla_total_size(1) +
991c19e654dSHerbert Xu 		/* IFLA_GRE_PMTUDISC */
992c19e654dSHerbert Xu 		nla_total_size(1) +
9934565e991STom Herbert 		/* IFLA_GRE_ENCAP_TYPE */
9944565e991STom Herbert 		nla_total_size(2) +
9954565e991STom Herbert 		/* IFLA_GRE_ENCAP_FLAGS */
9964565e991STom Herbert 		nla_total_size(2) +
9974565e991STom Herbert 		/* IFLA_GRE_ENCAP_SPORT */
9984565e991STom Herbert 		nla_total_size(2) +
9994565e991STom Herbert 		/* IFLA_GRE_ENCAP_DPORT */
10004565e991STom Herbert 		nla_total_size(2) +
10012e15ea39SPravin B Shelar 		/* IFLA_GRE_COLLECT_METADATA */
10022e15ea39SPravin B Shelar 		nla_total_size(0) +
1003c19e654dSHerbert Xu 		0;
1004c19e654dSHerbert Xu }
1005c19e654dSHerbert Xu 
1006c19e654dSHerbert Xu static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1007c19e654dSHerbert Xu {
1008c19e654dSHerbert Xu 	struct ip_tunnel *t = netdev_priv(dev);
1009c19e654dSHerbert Xu 	struct ip_tunnel_parm *p = &t->parms;
1010c19e654dSHerbert Xu 
1011f3756b79SDavid S. Miller 	if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
101295f5c64cSTom Herbert 	    nla_put_be16(skb, IFLA_GRE_IFLAGS,
101395f5c64cSTom Herbert 			 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
101495f5c64cSTom Herbert 	    nla_put_be16(skb, IFLA_GRE_OFLAGS,
101595f5c64cSTom Herbert 			 gre_tnl_flags_to_gre_flags(p->o_flags)) ||
1016f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1017f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1018930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1019930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
1020f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1021f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1022f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1023f3756b79SDavid S. Miller 		       !!(p->iph.frag_off & htons(IP_DF))))
1024f3756b79SDavid S. Miller 		goto nla_put_failure;
10254565e991STom Herbert 
10264565e991STom Herbert 	if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
10274565e991STom Herbert 			t->encap.type) ||
10283e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
10294565e991STom Herbert 			 t->encap.sport) ||
10303e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
10314565e991STom Herbert 			 t->encap.dport) ||
10324565e991STom Herbert 	    nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
1033e1b2cb65STom Herbert 			t->encap.flags))
10344565e991STom Herbert 		goto nla_put_failure;
10354565e991STom Herbert 
10362e15ea39SPravin B Shelar 	if (t->collect_md) {
10372e15ea39SPravin B Shelar 		if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
10382e15ea39SPravin B Shelar 			goto nla_put_failure;
10392e15ea39SPravin B Shelar 	}
10402e15ea39SPravin B Shelar 
1041c19e654dSHerbert Xu 	return 0;
1042c19e654dSHerbert Xu 
1043c19e654dSHerbert Xu nla_put_failure:
1044c19e654dSHerbert Xu 	return -EMSGSIZE;
1045c19e654dSHerbert Xu }
1046c19e654dSHerbert Xu 
1047c19e654dSHerbert Xu static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1048c19e654dSHerbert Xu 	[IFLA_GRE_LINK]		= { .type = NLA_U32 },
1049c19e654dSHerbert Xu 	[IFLA_GRE_IFLAGS]	= { .type = NLA_U16 },
1050c19e654dSHerbert Xu 	[IFLA_GRE_OFLAGS]	= { .type = NLA_U16 },
1051c19e654dSHerbert Xu 	[IFLA_GRE_IKEY]		= { .type = NLA_U32 },
1052c19e654dSHerbert Xu 	[IFLA_GRE_OKEY]		= { .type = NLA_U32 },
10534d74f8baSPatrick McHardy 	[IFLA_GRE_LOCAL]	= { .len = FIELD_SIZEOF(struct iphdr, saddr) },
10544d74f8baSPatrick McHardy 	[IFLA_GRE_REMOTE]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
1055c19e654dSHerbert Xu 	[IFLA_GRE_TTL]		= { .type = NLA_U8 },
1056c19e654dSHerbert Xu 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
1057c19e654dSHerbert Xu 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
10584565e991STom Herbert 	[IFLA_GRE_ENCAP_TYPE]	= { .type = NLA_U16 },
10594565e991STom Herbert 	[IFLA_GRE_ENCAP_FLAGS]	= { .type = NLA_U16 },
10604565e991STom Herbert 	[IFLA_GRE_ENCAP_SPORT]	= { .type = NLA_U16 },
10614565e991STom Herbert 	[IFLA_GRE_ENCAP_DPORT]	= { .type = NLA_U16 },
10622e15ea39SPravin B Shelar 	[IFLA_GRE_COLLECT_METADATA]	= { .type = NLA_FLAG },
1063c19e654dSHerbert Xu };
1064c19e654dSHerbert Xu 
1065c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1066c19e654dSHerbert Xu 	.kind		= "gre",
1067c19e654dSHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1068c19e654dSHerbert Xu 	.policy		= ipgre_policy,
1069c19e654dSHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1070c19e654dSHerbert Xu 	.setup		= ipgre_tunnel_setup,
1071c19e654dSHerbert Xu 	.validate	= ipgre_tunnel_validate,
1072c19e654dSHerbert Xu 	.newlink	= ipgre_newlink,
1073c19e654dSHerbert Xu 	.changelink	= ipgre_changelink,
1074c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1075c19e654dSHerbert Xu 	.get_size	= ipgre_get_size,
1076c19e654dSHerbert Xu 	.fill_info	= ipgre_fill_info,
10771728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1078c19e654dSHerbert Xu };
1079c19e654dSHerbert Xu 
1080e1a80002SHerbert Xu static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1081e1a80002SHerbert Xu 	.kind		= "gretap",
1082e1a80002SHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1083e1a80002SHerbert Xu 	.policy		= ipgre_policy,
1084e1a80002SHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1085e1a80002SHerbert Xu 	.setup		= ipgre_tap_setup,
1086e1a80002SHerbert Xu 	.validate	= ipgre_tap_validate,
1087e1a80002SHerbert Xu 	.newlink	= ipgre_newlink,
1088e1a80002SHerbert Xu 	.changelink	= ipgre_changelink,
1089c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1090e1a80002SHerbert Xu 	.get_size	= ipgre_get_size,
1091e1a80002SHerbert Xu 	.fill_info	= ipgre_fill_info,
10921728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1093e1a80002SHerbert Xu };
1094e1a80002SHerbert Xu 
1095b2acd1dcSPravin B Shelar struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1096b2acd1dcSPravin B Shelar 					u8 name_assign_type)
1097b2acd1dcSPravin B Shelar {
1098b2acd1dcSPravin B Shelar 	struct nlattr *tb[IFLA_MAX + 1];
1099b2acd1dcSPravin B Shelar 	struct net_device *dev;
1100b2acd1dcSPravin B Shelar 	struct ip_tunnel *t;
1101b2acd1dcSPravin B Shelar 	int err;
1102b2acd1dcSPravin B Shelar 
1103b2acd1dcSPravin B Shelar 	memset(&tb, 0, sizeof(tb));
1104b2acd1dcSPravin B Shelar 
1105b2acd1dcSPravin B Shelar 	dev = rtnl_create_link(net, name, name_assign_type,
1106b2acd1dcSPravin B Shelar 			       &ipgre_tap_ops, tb);
1107b2acd1dcSPravin B Shelar 	if (IS_ERR(dev))
1108b2acd1dcSPravin B Shelar 		return dev;
1109b2acd1dcSPravin B Shelar 
1110b2acd1dcSPravin B Shelar 	/* Configure flow based GRE device. */
1111b2acd1dcSPravin B Shelar 	t = netdev_priv(dev);
1112b2acd1dcSPravin B Shelar 	t->collect_md = true;
1113b2acd1dcSPravin B Shelar 
1114b2acd1dcSPravin B Shelar 	err = ipgre_newlink(net, dev, tb, NULL);
1115b2acd1dcSPravin B Shelar 	if (err < 0)
1116b2acd1dcSPravin B Shelar 		goto out;
11177e059158SDavid Wragg 
11187e059158SDavid Wragg 	/* openvswitch users expect packet sizes to be unrestricted,
11197e059158SDavid Wragg 	 * so set the largest MTU we can.
11207e059158SDavid Wragg 	 */
11217e059158SDavid Wragg 	err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
11227e059158SDavid Wragg 	if (err)
11237e059158SDavid Wragg 		goto out;
11247e059158SDavid Wragg 
1125b2acd1dcSPravin B Shelar 	return dev;
1126b2acd1dcSPravin B Shelar out:
1127b2acd1dcSPravin B Shelar 	free_netdev(dev);
1128b2acd1dcSPravin B Shelar 	return ERR_PTR(err);
1129b2acd1dcSPravin B Shelar }
1130b2acd1dcSPravin B Shelar EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1131b2acd1dcSPravin B Shelar 
1132c5441932SPravin B Shelar static int __net_init ipgre_tap_init_net(struct net *net)
1133c5441932SPravin B Shelar {
11342e15ea39SPravin B Shelar 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
1135c5441932SPravin B Shelar }
1136c5441932SPravin B Shelar 
1137c5441932SPravin B Shelar static void __net_exit ipgre_tap_exit_net(struct net *net)
1138c5441932SPravin B Shelar {
1139c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
11406c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_tap_ops);
1141c5441932SPravin B Shelar }
1142c5441932SPravin B Shelar 
1143c5441932SPravin B Shelar static struct pernet_operations ipgre_tap_net_ops = {
1144c5441932SPravin B Shelar 	.init = ipgre_tap_init_net,
1145c5441932SPravin B Shelar 	.exit = ipgre_tap_exit_net,
1146c5441932SPravin B Shelar 	.id   = &gre_tap_net_id,
1147c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
1148c5441932SPravin B Shelar };
11491da177e4SLinus Torvalds 
11501da177e4SLinus Torvalds static int __init ipgre_init(void)
11511da177e4SLinus Torvalds {
11521da177e4SLinus Torvalds 	int err;
11531da177e4SLinus Torvalds 
1154058bd4d2SJoe Perches 	pr_info("GRE over IPv4 tunneling driver\n");
11551da177e4SLinus Torvalds 
1156cfb8fbf2SEric W. Biederman 	err = register_pernet_device(&ipgre_net_ops);
115759a4c759SPavel Emelyanov 	if (err < 0)
1158c2892f02SAlexey Dobriyan 		return err;
1159c2892f02SAlexey Dobriyan 
1160c5441932SPravin B Shelar 	err = register_pernet_device(&ipgre_tap_net_ops);
1161c5441932SPravin B Shelar 	if (err < 0)
1162c5441932SPravin B Shelar 		goto pnet_tap_faied;
1163c5441932SPravin B Shelar 
11649f57c67cSPravin B Shelar 	err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
1165c2892f02SAlexey Dobriyan 	if (err < 0) {
1166058bd4d2SJoe Perches 		pr_info("%s: can't add protocol\n", __func__);
1167c2892f02SAlexey Dobriyan 		goto add_proto_failed;
1168c2892f02SAlexey Dobriyan 	}
11697daa0004SPavel Emelyanov 
1170c19e654dSHerbert Xu 	err = rtnl_link_register(&ipgre_link_ops);
1171c19e654dSHerbert Xu 	if (err < 0)
1172c19e654dSHerbert Xu 		goto rtnl_link_failed;
1173c19e654dSHerbert Xu 
1174e1a80002SHerbert Xu 	err = rtnl_link_register(&ipgre_tap_ops);
1175e1a80002SHerbert Xu 	if (err < 0)
1176e1a80002SHerbert Xu 		goto tap_ops_failed;
1177e1a80002SHerbert Xu 
1178c5441932SPravin B Shelar 	return 0;
1179c19e654dSHerbert Xu 
1180e1a80002SHerbert Xu tap_ops_failed:
1181e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
1182c19e654dSHerbert Xu rtnl_link_failed:
11839f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1184c2892f02SAlexey Dobriyan add_proto_failed:
1185c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1186c5441932SPravin B Shelar pnet_tap_faied:
1187c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
1188c5441932SPravin B Shelar 	return err;
11891da177e4SLinus Torvalds }
11901da177e4SLinus Torvalds 
1191db44575fSAlexey Kuznetsov static void __exit ipgre_fini(void)
11921da177e4SLinus Torvalds {
1193e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_tap_ops);
1194c19e654dSHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
11959f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1196c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1197c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
11981da177e4SLinus Torvalds }
11991da177e4SLinus Torvalds 
12001da177e4SLinus Torvalds module_init(ipgre_init);
12011da177e4SLinus Torvalds module_exit(ipgre_fini);
12021da177e4SLinus Torvalds MODULE_LICENSE("GPL");
12034d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gre");
12044d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gretap");
12058909c9adSVasiliy Kulikov MODULE_ALIAS_NETDEV("gre0");
1206c5441932SPravin B Shelar MODULE_ALIAS_NETDEV("gretap0");
1207