xref: /linux/net/ipv4/ip_gre.c (revision 20e1954fe238dbe5f8d3a979e593fe352bd703cf)
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;
147*20e1954fSEric Dumazet 	unsigned int data_len = 0;
1481da177e4SLinus Torvalds 	struct ip_tunnel *t;
149d2083287Sstephen hemminger 
1501da177e4SLinus Torvalds 	switch (type) {
1511da177e4SLinus Torvalds 	default:
1521da177e4SLinus Torvalds 	case ICMP_PARAMETERPROB:
1539f57c67cSPravin B Shelar 		return;
1541da177e4SLinus Torvalds 
1551da177e4SLinus Torvalds 	case ICMP_DEST_UNREACH:
1561da177e4SLinus Torvalds 		switch (code) {
1571da177e4SLinus Torvalds 		case ICMP_SR_FAILED:
1581da177e4SLinus Torvalds 		case ICMP_PORT_UNREACH:
1591da177e4SLinus Torvalds 			/* Impossible event. */
1609f57c67cSPravin B Shelar 			return;
1611da177e4SLinus Torvalds 		default:
1621da177e4SLinus Torvalds 			/* All others are translated to HOST_UNREACH.
1631da177e4SLinus Torvalds 			   rfc2003 contains "deep thoughts" about NET_UNREACH,
1641da177e4SLinus Torvalds 			   I believe they are just ether pollution. --ANK
1651da177e4SLinus Torvalds 			 */
1661da177e4SLinus Torvalds 			break;
1671da177e4SLinus Torvalds 		}
1681da177e4SLinus Torvalds 		break;
1699f57c67cSPravin B Shelar 
1701da177e4SLinus Torvalds 	case ICMP_TIME_EXCEEDED:
1711da177e4SLinus Torvalds 		if (code != ICMP_EXC_TTL)
1729f57c67cSPravin B Shelar 			return;
173*20e1954fSEric Dumazet 		data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
1741da177e4SLinus Torvalds 		break;
17555be7a9cSDavid S. Miller 
17655be7a9cSDavid S. Miller 	case ICMP_REDIRECT:
17755be7a9cSDavid S. Miller 		break;
1781da177e4SLinus Torvalds 	}
1791da177e4SLinus Torvalds 
180bda7bb46SPravin B Shelar 	if (tpi->proto == htons(ETH_P_TEB))
181c5441932SPravin B Shelar 		itn = net_generic(net, gre_tap_net_id);
182c5441932SPravin B Shelar 	else
183c5441932SPravin B Shelar 		itn = net_generic(net, ipgre_net_id);
184c5441932SPravin B Shelar 
185c0c0c50fSDuan Jiong 	iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
186bda7bb46SPravin B Shelar 	t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
187bda7bb46SPravin B Shelar 			     iph->daddr, iph->saddr, tpi->key);
188d2083287Sstephen hemminger 
18951456b29SIan Morris 	if (!t)
1909f57c67cSPravin B Shelar 		return;
19136393395SDavid S. Miller 
1929b8c6d7bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6)
1939b8c6d7bSEric Dumazet        if (tpi->proto == htons(ETH_P_IPV6) &&
194*20e1954fSEric Dumazet            !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
195*20e1954fSEric Dumazet 				       type, data_len))
1969b8c6d7bSEric Dumazet                return;
1979b8c6d7bSEric Dumazet #endif
1989b8c6d7bSEric Dumazet 
19936393395SDavid S. Miller 	if (t->parms.iph.daddr == 0 ||
200f97c1e0cSJoe Perches 	    ipv4_is_multicast(t->parms.iph.daddr))
2019f57c67cSPravin B Shelar 		return;
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds 	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
2049f57c67cSPravin B Shelar 		return;
2051da177e4SLinus Torvalds 
206da6185d8SWei Yongjun 	if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
2071da177e4SLinus Torvalds 		t->err_count++;
2081da177e4SLinus Torvalds 	else
2091da177e4SLinus Torvalds 		t->err_count = 1;
2101da177e4SLinus Torvalds 	t->err_time = jiffies;
2119f57c67cSPravin B Shelar }
2129f57c67cSPravin B Shelar 
2139f57c67cSPravin B Shelar static void gre_err(struct sk_buff *skb, u32 info)
2149f57c67cSPravin B Shelar {
2159f57c67cSPravin B Shelar 	/* All the routers (except for Linux) return only
2169f57c67cSPravin B Shelar 	 * 8 bytes of packet payload. It means, that precise relaying of
2179f57c67cSPravin B Shelar 	 * ICMP in the real Internet is absolutely infeasible.
2189f57c67cSPravin B Shelar 	 *
2199f57c67cSPravin B Shelar 	 * Moreover, Cisco "wise men" put GRE key to the third word
2209f57c67cSPravin B Shelar 	 * in GRE header. It makes impossible maintaining even soft
2219f57c67cSPravin B Shelar 	 * state for keyed
2229f57c67cSPravin B Shelar 	 * GRE tunnels with enabled checksum. Tell them "thank you".
2239f57c67cSPravin B Shelar 	 *
2249f57c67cSPravin B Shelar 	 * Well, I wonder, rfc1812 was written by Cisco employee,
2259f57c67cSPravin B Shelar 	 * what the hell these idiots break standards established
2269f57c67cSPravin B Shelar 	 * by themselves???
2279f57c67cSPravin B Shelar 	 */
2289f57c67cSPravin B Shelar 
2299f57c67cSPravin B Shelar 	const int type = icmp_hdr(skb)->type;
2309f57c67cSPravin B Shelar 	const int code = icmp_hdr(skb)->code;
2319f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
2329f57c67cSPravin B Shelar 	bool csum_err = false;
2339f57c67cSPravin B Shelar 
234da73b4e9SHaishuang Yan 	if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP)) < 0) {
2359f57c67cSPravin B Shelar 		if (!csum_err)		/* ignore csum errors. */
2369f57c67cSPravin B Shelar 			return;
2379f57c67cSPravin B Shelar 	}
2389f57c67cSPravin B Shelar 
2399f57c67cSPravin B Shelar 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
2409f57c67cSPravin B Shelar 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
2419f57c67cSPravin B Shelar 				 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
2429f57c67cSPravin B Shelar 		return;
2439f57c67cSPravin B Shelar 	}
2449f57c67cSPravin B Shelar 	if (type == ICMP_REDIRECT) {
2459f57c67cSPravin B Shelar 		ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
2469f57c67cSPravin B Shelar 			      IPPROTO_GRE, 0);
2479f57c67cSPravin B Shelar 		return;
2489f57c67cSPravin B Shelar 	}
2499f57c67cSPravin B Shelar 
2509f57c67cSPravin B Shelar 	ipgre_err(skb, info, &tpi);
2511da177e4SLinus Torvalds }
2521da177e4SLinus Torvalds 
2532e15ea39SPravin B Shelar static __be64 key_to_tunnel_id(__be32 key)
2542e15ea39SPravin B Shelar {
2552e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
2562e15ea39SPravin B Shelar 	return (__force __be64)((__force u32)key);
2572e15ea39SPravin B Shelar #else
2582e15ea39SPravin B Shelar 	return (__force __be64)((__force u64)key << 32);
2592e15ea39SPravin B Shelar #endif
2602e15ea39SPravin B Shelar }
2612e15ea39SPravin B Shelar 
2622e15ea39SPravin B Shelar /* Returns the least-significant 32 bits of a __be64. */
2632e15ea39SPravin B Shelar static __be32 tunnel_id_to_key(__be64 x)
2642e15ea39SPravin B Shelar {
2652e15ea39SPravin B Shelar #ifdef __BIG_ENDIAN
2662e15ea39SPravin B Shelar 	return (__force __be32)x;
2672e15ea39SPravin B Shelar #else
2682e15ea39SPravin B Shelar 	return (__force __be32)((__force u64)x >> 32);
2692e15ea39SPravin B Shelar #endif
2702e15ea39SPravin B Shelar }
2712e15ea39SPravin B Shelar 
272125372faSJiri Benc static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
273125372faSJiri Benc 		       struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
2741da177e4SLinus Torvalds {
2752e15ea39SPravin B Shelar 	struct metadata_dst *tun_dst = NULL;
276b71d1d42SEric Dumazet 	const struct iphdr *iph;
2771da177e4SLinus Torvalds 	struct ip_tunnel *tunnel;
2781da177e4SLinus Torvalds 
279eddc9ec5SArnaldo Carvalho de Melo 	iph = ip_hdr(skb);
280bda7bb46SPravin B Shelar 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
281bda7bb46SPravin B Shelar 				  iph->saddr, iph->daddr, tpi->key);
2821da177e4SLinus Torvalds 
283d2083287Sstephen hemminger 	if (tunnel) {
284125372faSJiri Benc 		if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
285125372faSJiri Benc 					   raw_proto, false) < 0)
286244a797bSJiri Benc 			goto drop;
287244a797bSJiri Benc 
288e271c7b4SJiri Benc 		if (tunnel->dev->type != ARPHRD_NONE)
2890e3da5bbSTimo Teräs 			skb_pop_mac_header(skb);
290e271c7b4SJiri Benc 		else
291e271c7b4SJiri Benc 			skb_reset_mac_header(skb);
2922e15ea39SPravin B Shelar 		if (tunnel->collect_md) {
293c29a70d2SPravin B Shelar 			__be16 flags;
294c29a70d2SPravin B Shelar 			__be64 tun_id;
2952e15ea39SPravin B Shelar 
296c29a70d2SPravin B Shelar 			flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
297c29a70d2SPravin B Shelar 			tun_id = key_to_tunnel_id(tpi->key);
298c29a70d2SPravin B Shelar 			tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
2992e15ea39SPravin B Shelar 			if (!tun_dst)
3002e15ea39SPravin B Shelar 				return PACKET_REJECT;
3012e15ea39SPravin B Shelar 		}
3022e15ea39SPravin B Shelar 
3032e15ea39SPravin B Shelar 		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
304bda7bb46SPravin B Shelar 		return PACKET_RCVD;
3051da177e4SLinus Torvalds 	}
306125372faSJiri Benc 	return PACKET_NEXT;
307244a797bSJiri Benc 
308244a797bSJiri Benc drop:
309244a797bSJiri Benc 	kfree_skb(skb);
310244a797bSJiri Benc 	return PACKET_RCVD;
3111da177e4SLinus Torvalds }
3121da177e4SLinus Torvalds 
313125372faSJiri Benc static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
314125372faSJiri Benc 		     int hdr_len)
315125372faSJiri Benc {
316125372faSJiri Benc 	struct net *net = dev_net(skb->dev);
317125372faSJiri Benc 	struct ip_tunnel_net *itn;
318125372faSJiri Benc 	int res;
319125372faSJiri Benc 
320125372faSJiri Benc 	if (tpi->proto == htons(ETH_P_TEB))
321125372faSJiri Benc 		itn = net_generic(net, gre_tap_net_id);
322125372faSJiri Benc 	else
323125372faSJiri Benc 		itn = net_generic(net, ipgre_net_id);
324125372faSJiri Benc 
325125372faSJiri Benc 	res = __ipgre_rcv(skb, tpi, itn, hdr_len, false);
326125372faSJiri Benc 	if (res == PACKET_NEXT && tpi->proto == htons(ETH_P_TEB)) {
327125372faSJiri Benc 		/* ipgre tunnels in collect metadata mode should receive
328125372faSJiri Benc 		 * also ETH_P_TEB traffic.
329125372faSJiri Benc 		 */
330125372faSJiri Benc 		itn = net_generic(net, ipgre_net_id);
331125372faSJiri Benc 		res = __ipgre_rcv(skb, tpi, itn, hdr_len, true);
332125372faSJiri Benc 	}
333125372faSJiri Benc 	return res;
334125372faSJiri Benc }
335125372faSJiri Benc 
3369f57c67cSPravin B Shelar static int gre_rcv(struct sk_buff *skb)
3379f57c67cSPravin B Shelar {
3389f57c67cSPravin B Shelar 	struct tnl_ptk_info tpi;
3399f57c67cSPravin B Shelar 	bool csum_err = false;
34095f5c64cSTom Herbert 	int hdr_len;
3419f57c67cSPravin B Shelar 
3429f57c67cSPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
3439f57c67cSPravin B Shelar 	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
3449f57c67cSPravin B Shelar 		/* Looped back packet, drop it! */
3459f57c67cSPravin B Shelar 		if (rt_is_output_route(skb_rtable(skb)))
3469f57c67cSPravin B Shelar 			goto drop;
3479f57c67cSPravin B Shelar 	}
3489f57c67cSPravin B Shelar #endif
3499f57c67cSPravin B Shelar 
350da73b4e9SHaishuang Yan 	hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP));
351f132ae7cSJiri Benc 	if (hdr_len < 0)
35295f5c64cSTom Herbert 		goto drop;
35395f5c64cSTom Herbert 
354244a797bSJiri Benc 	if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
3559f57c67cSPravin B Shelar 		return 0;
3569f57c67cSPravin B Shelar 
3579f57c67cSPravin B Shelar 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
3589f57c67cSPravin B Shelar drop:
3599f57c67cSPravin B Shelar 	kfree_skb(skb);
3609f57c67cSPravin B Shelar 	return 0;
3619f57c67cSPravin B Shelar }
3629f57c67cSPravin B Shelar 
363c5441932SPravin B Shelar static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
364c5441932SPravin B Shelar 		       const struct iphdr *tnl_params,
365c5441932SPravin B Shelar 		       __be16 proto)
366c5441932SPravin B Shelar {
367c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
368c5441932SPravin B Shelar 
369c5441932SPravin B Shelar 	if (tunnel->parms.o_flags & TUNNEL_SEQ)
370c5441932SPravin B Shelar 		tunnel->o_seqno++;
371cef401deSEric Dumazet 
372c5441932SPravin B Shelar 	/* Push GRE header. */
373182a352dSTom Herbert 	gre_build_header(skb, tunnel->tun_hlen,
374182a352dSTom Herbert 			 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
375182a352dSTom Herbert 			 htonl(tunnel->o_seqno));
3761da177e4SLinus Torvalds 
3772e15ea39SPravin B Shelar 	skb_set_inner_protocol(skb, proto);
378bf3d6a8fSNicolas Dichtel 	ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
3791da177e4SLinus Torvalds }
3801da177e4SLinus Torvalds 
381aed069dfSAlexander Duyck static int gre_handle_offloads(struct sk_buff *skb, bool csum)
382b2acd1dcSPravin B Shelar {
3836fa79666SEdward Cree 	return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
384b2acd1dcSPravin B Shelar }
385b2acd1dcSPravin B Shelar 
386fc4099f1SPravin B Shelar static struct rtable *gre_get_rt(struct sk_buff *skb,
387fc4099f1SPravin B Shelar 				 struct net_device *dev,
388fc4099f1SPravin B Shelar 				 struct flowi4 *fl,
389fc4099f1SPravin B Shelar 				 const struct ip_tunnel_key *key)
390fc4099f1SPravin B Shelar {
391fc4099f1SPravin B Shelar 	struct net *net = dev_net(dev);
392fc4099f1SPravin B Shelar 
393fc4099f1SPravin B Shelar 	memset(fl, 0, sizeof(*fl));
394fc4099f1SPravin B Shelar 	fl->daddr = key->u.ipv4.dst;
395fc4099f1SPravin B Shelar 	fl->saddr = key->u.ipv4.src;
396fc4099f1SPravin B Shelar 	fl->flowi4_tos = RT_TOS(key->tos);
397fc4099f1SPravin B Shelar 	fl->flowi4_mark = skb->mark;
398fc4099f1SPravin B Shelar 	fl->flowi4_proto = IPPROTO_GRE;
399fc4099f1SPravin B Shelar 
400fc4099f1SPravin B Shelar 	return ip_route_output_key(net, fl);
401fc4099f1SPravin B Shelar }
402fc4099f1SPravin B Shelar 
4032090714eSJiri Benc static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
4042090714eSJiri Benc 			__be16 proto)
4052e15ea39SPravin B Shelar {
4062e15ea39SPravin B Shelar 	struct ip_tunnel_info *tun_info;
4072e15ea39SPravin B Shelar 	const struct ip_tunnel_key *key;
408db3c6139SDaniel Borkmann 	struct rtable *rt = NULL;
4092e15ea39SPravin B Shelar 	struct flowi4 fl;
4102e15ea39SPravin B Shelar 	int min_headroom;
4112e15ea39SPravin B Shelar 	int tunnel_hlen;
4122e15ea39SPravin B Shelar 	__be16 df, flags;
413db3c6139SDaniel Borkmann 	bool use_cache;
4142e15ea39SPravin B Shelar 	int err;
4152e15ea39SPravin B Shelar 
41661adedf3SJiri Benc 	tun_info = skb_tunnel_info(skb);
4177f9562a1SJiri Benc 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
4187f9562a1SJiri Benc 		     ip_tunnel_info_af(tun_info) != AF_INET))
4192e15ea39SPravin B Shelar 		goto err_free_skb;
4202e15ea39SPravin B Shelar 
4212e15ea39SPravin B Shelar 	key = &tun_info->key;
422db3c6139SDaniel Borkmann 	use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
423db3c6139SDaniel Borkmann 	if (use_cache)
424db3c6139SDaniel Borkmann 		rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
4253c1cb4d2SPaolo Abeni 	if (!rt) {
426fc4099f1SPravin B Shelar 		rt = gre_get_rt(skb, dev, &fl, key);
4272e15ea39SPravin B Shelar 		if (IS_ERR(rt))
4282e15ea39SPravin B Shelar 				goto err_free_skb;
429db3c6139SDaniel Borkmann 		if (use_cache)
4303c1cb4d2SPaolo Abeni 			dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
4313c1cb4d2SPaolo Abeni 					  fl.saddr);
4323c1cb4d2SPaolo Abeni 	}
4332e15ea39SPravin B Shelar 
43495f5c64cSTom Herbert 	tunnel_hlen = gre_calc_hlen(key->tun_flags);
4352e15ea39SPravin B Shelar 
4362e15ea39SPravin B Shelar 	min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
4372e15ea39SPravin B Shelar 			+ tunnel_hlen + sizeof(struct iphdr);
4382e15ea39SPravin B Shelar 	if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
4392e15ea39SPravin B Shelar 		int head_delta = SKB_DATA_ALIGN(min_headroom -
4402e15ea39SPravin B Shelar 						skb_headroom(skb) +
4412e15ea39SPravin B Shelar 						16);
4422e15ea39SPravin B Shelar 		err = pskb_expand_head(skb, max_t(int, head_delta, 0),
4432e15ea39SPravin B Shelar 				       0, GFP_ATOMIC);
4442e15ea39SPravin B Shelar 		if (unlikely(err))
4452e15ea39SPravin B Shelar 			goto err_free_rt;
4462e15ea39SPravin B Shelar 	}
4472e15ea39SPravin B Shelar 
4482e15ea39SPravin B Shelar 	/* Push Tunnel header. */
449aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
4502e15ea39SPravin B Shelar 		goto err_free_rt;
4512e15ea39SPravin B Shelar 
4522e15ea39SPravin B Shelar 	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
453cba65321SDavid S. Miller 	gre_build_header(skb, tunnel_hlen, flags, proto,
4542e15ea39SPravin B Shelar 			 tunnel_id_to_key(tun_info->key.tun_id), 0);
4552e15ea39SPravin B Shelar 
4562e15ea39SPravin B Shelar 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
457039f5062SPravin B Shelar 
458039f5062SPravin B Shelar 	iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
4597c383fb2SJiri Benc 		      key->tos, key->ttl, df, false);
4602e15ea39SPravin B Shelar 	return;
4612e15ea39SPravin B Shelar 
4622e15ea39SPravin B Shelar err_free_rt:
4632e15ea39SPravin B Shelar 	ip_rt_put(rt);
4642e15ea39SPravin B Shelar err_free_skb:
4652e15ea39SPravin B Shelar 	kfree_skb(skb);
4662e15ea39SPravin B Shelar 	dev->stats.tx_dropped++;
4672e15ea39SPravin B Shelar }
4682e15ea39SPravin B Shelar 
469fc4099f1SPravin B Shelar static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
470fc4099f1SPravin B Shelar {
471fc4099f1SPravin B Shelar 	struct ip_tunnel_info *info = skb_tunnel_info(skb);
472fc4099f1SPravin B Shelar 	struct rtable *rt;
473fc4099f1SPravin B Shelar 	struct flowi4 fl4;
474fc4099f1SPravin B Shelar 
475fc4099f1SPravin B Shelar 	if (ip_tunnel_info_af(info) != AF_INET)
476fc4099f1SPravin B Shelar 		return -EINVAL;
477fc4099f1SPravin B Shelar 
478fc4099f1SPravin B Shelar 	rt = gre_get_rt(skb, dev, &fl4, &info->key);
479fc4099f1SPravin B Shelar 	if (IS_ERR(rt))
480fc4099f1SPravin B Shelar 		return PTR_ERR(rt);
481fc4099f1SPravin B Shelar 
482fc4099f1SPravin B Shelar 	ip_rt_put(rt);
483fc4099f1SPravin B Shelar 	info->key.u.ipv4.src = fl4.saddr;
484fc4099f1SPravin B Shelar 	return 0;
485fc4099f1SPravin B Shelar }
486fc4099f1SPravin B Shelar 
487c5441932SPravin B Shelar static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
488c5441932SPravin B Shelar 			      struct net_device *dev)
489ee34c1ebSMichal Schmidt {
490c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
491c5441932SPravin B Shelar 	const struct iphdr *tnl_params;
492ee34c1ebSMichal Schmidt 
4932e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
4942090714eSJiri Benc 		gre_fb_xmit(skb, dev, skb->protocol);
4952e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
4962e15ea39SPravin B Shelar 	}
4972e15ea39SPravin B Shelar 
498c5441932SPravin B Shelar 	if (dev->header_ops) {
499c5441932SPravin B Shelar 		/* Need space for new headers */
500c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom -
5012bac7cb3SChen Gang 				      (tunnel->hlen + sizeof(struct iphdr))))
502c5441932SPravin B Shelar 			goto free_skb;
503ee34c1ebSMichal Schmidt 
504c5441932SPravin B Shelar 		tnl_params = (const struct iphdr *)skb->data;
505cbb1e85fSDavid S. Miller 
506c5441932SPravin B Shelar 		/* Pull skb since ip_tunnel_xmit() needs skb->data pointing
507c5441932SPravin B Shelar 		 * to gre header.
508c5441932SPravin B Shelar 		 */
509c5441932SPravin B Shelar 		skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
5108a0033a9STimo Teräs 		skb_reset_mac_header(skb);
511c5441932SPravin B Shelar 	} else {
512c5441932SPravin B Shelar 		if (skb_cow_head(skb, dev->needed_headroom))
513c5441932SPravin B Shelar 			goto free_skb;
514c5441932SPravin B Shelar 
515c5441932SPravin B Shelar 		tnl_params = &tunnel->parms.iph;
516ee34c1ebSMichal Schmidt 	}
517e1a80002SHerbert Xu 
518aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
519aed069dfSAlexander Duyck 		goto free_skb;
5208a0033a9STimo Teräs 
521c5441932SPravin B Shelar 	__gre_xmit(skb, dev, tnl_params, skb->protocol);
522c5441932SPravin B Shelar 	return NETDEV_TX_OK;
523c5441932SPravin B Shelar 
524c5441932SPravin B Shelar free_skb:
5253acfa1e7SEric Dumazet 	kfree_skb(skb);
526c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
527c5441932SPravin B Shelar 	return NETDEV_TX_OK;
528ee34c1ebSMichal Schmidt }
529ee34c1ebSMichal Schmidt 
530c5441932SPravin B Shelar static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
531c5441932SPravin B Shelar 				struct net_device *dev)
532c5441932SPravin B Shelar {
533c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
534ee34c1ebSMichal Schmidt 
5352e15ea39SPravin B Shelar 	if (tunnel->collect_md) {
5362090714eSJiri Benc 		gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
5372e15ea39SPravin B Shelar 		return NETDEV_TX_OK;
5382e15ea39SPravin B Shelar 	}
5392e15ea39SPravin B Shelar 
540aed069dfSAlexander Duyck 	if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
541aed069dfSAlexander Duyck 		goto free_skb;
542ee34c1ebSMichal Schmidt 
543c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom))
544c5441932SPravin B Shelar 		goto free_skb;
54542aa9162SHerbert Xu 
546c5441932SPravin B Shelar 	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
547c5441932SPravin B Shelar 	return NETDEV_TX_OK;
548c5441932SPravin B Shelar 
549c5441932SPravin B Shelar free_skb:
5503acfa1e7SEric Dumazet 	kfree_skb(skb);
551c5441932SPravin B Shelar 	dev->stats.tx_dropped++;
552c5441932SPravin B Shelar 	return NETDEV_TX_OK;
55368c33163SPravin B Shelar }
554ee34c1ebSMichal Schmidt 
555c5441932SPravin B Shelar static int ipgre_tunnel_ioctl(struct net_device *dev,
556c5441932SPravin B Shelar 			      struct ifreq *ifr, int cmd)
5571da177e4SLinus Torvalds {
5584565e991STom Herbert 	int err;
5591da177e4SLinus Torvalds 	struct ip_tunnel_parm p;
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
562c5441932SPravin B Shelar 		return -EFAULT;
5636c734fb8SCong Wang 	if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
5641da177e4SLinus Torvalds 		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
5651da177e4SLinus Torvalds 		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
5666c734fb8SCong Wang 		    ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
5671da177e4SLinus Torvalds 			return -EINVAL;
568c5441932SPravin B Shelar 	}
569c5441932SPravin B Shelar 	p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
570c5441932SPravin B Shelar 	p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
571c5441932SPravin B Shelar 
572c5441932SPravin B Shelar 	err = ip_tunnel_ioctl(dev, &p, cmd);
573c5441932SPravin B Shelar 	if (err)
574c5441932SPravin B Shelar 		return err;
575c5441932SPravin B Shelar 
57695f5c64cSTom Herbert 	p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
57795f5c64cSTom Herbert 	p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
578c5441932SPravin B Shelar 
579c5441932SPravin B Shelar 	if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
580c5441932SPravin B Shelar 		return -EFAULT;
5811da177e4SLinus Torvalds 	return 0;
5821da177e4SLinus Torvalds }
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds /* Nice toy. Unfortunately, useless in real life :-)
5851da177e4SLinus Torvalds    It allows to construct virtual multiprotocol broadcast "LAN"
5861da177e4SLinus Torvalds    over the Internet, provided multicast routing is tuned.
5871da177e4SLinus Torvalds 
5881da177e4SLinus Torvalds 
5891da177e4SLinus Torvalds    I have no idea was this bicycle invented before me,
5901da177e4SLinus Torvalds    so that I had to set ARPHRD_IPGRE to a random value.
5911da177e4SLinus Torvalds    I have an impression, that Cisco could make something similar,
5921da177e4SLinus Torvalds    but this feature is apparently missing in IOS<=11.2(8).
5931da177e4SLinus Torvalds 
5941da177e4SLinus Torvalds    I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
5951da177e4SLinus Torvalds    with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds    ping -t 255 224.66.66.66
5981da177e4SLinus Torvalds 
5991da177e4SLinus Torvalds    If nobody answers, mbone does not work.
6001da177e4SLinus Torvalds 
6011da177e4SLinus Torvalds    ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
6021da177e4SLinus Torvalds    ip addr add 10.66.66.<somewhat>/24 dev Universe
6031da177e4SLinus Torvalds    ifconfig Universe up
6041da177e4SLinus Torvalds    ifconfig Universe add fe80::<Your_real_addr>/10
6051da177e4SLinus Torvalds    ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
6061da177e4SLinus Torvalds    ftp 10.66.66.66
6071da177e4SLinus Torvalds    ...
6081da177e4SLinus Torvalds    ftp fec0:6666:6666::193.233.7.65
6091da177e4SLinus Torvalds    ...
6101da177e4SLinus Torvalds  */
6113b04dddeSStephen Hemminger static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
6123b04dddeSStephen Hemminger 			unsigned short type,
6131507850bSEric Dumazet 			const void *daddr, const void *saddr, unsigned int len)
6141da177e4SLinus Torvalds {
6152941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
616c5441932SPravin B Shelar 	struct iphdr *iph;
617c5441932SPravin B Shelar 	struct gre_base_hdr *greh;
618c5441932SPravin B Shelar 
619c5441932SPravin B Shelar 	iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
620c5441932SPravin B Shelar 	greh = (struct gre_base_hdr *)(iph+1);
62195f5c64cSTom Herbert 	greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
622c5441932SPravin B Shelar 	greh->protocol = htons(type);
6231da177e4SLinus Torvalds 
6241da177e4SLinus Torvalds 	memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
6251da177e4SLinus Torvalds 
626c5441932SPravin B Shelar 	/* Set the source hardware address. */
6271da177e4SLinus Torvalds 	if (saddr)
6281da177e4SLinus Torvalds 		memcpy(&iph->saddr, saddr, 4);
6296d55cb91STimo Teräs 	if (daddr)
6301da177e4SLinus Torvalds 		memcpy(&iph->daddr, daddr, 4);
6316d55cb91STimo Teräs 	if (iph->daddr)
63277a482bdSTimo Teräs 		return t->hlen + sizeof(*iph);
6331da177e4SLinus Torvalds 
634c5441932SPravin B Shelar 	return -(t->hlen + sizeof(*iph));
6351da177e4SLinus Torvalds }
6361da177e4SLinus Torvalds 
6376a5f44d7STimo Teras static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
6386a5f44d7STimo Teras {
639b71d1d42SEric Dumazet 	const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
6406a5f44d7STimo Teras 	memcpy(haddr, &iph->saddr, 4);
6416a5f44d7STimo Teras 	return 4;
6426a5f44d7STimo Teras }
6436a5f44d7STimo Teras 
6443b04dddeSStephen Hemminger static const struct header_ops ipgre_header_ops = {
6453b04dddeSStephen Hemminger 	.create	= ipgre_header,
6466a5f44d7STimo Teras 	.parse	= ipgre_header_parse,
6473b04dddeSStephen Hemminger };
6483b04dddeSStephen Hemminger 
6496a5f44d7STimo Teras #ifdef CONFIG_NET_IPGRE_BROADCAST
6501da177e4SLinus Torvalds static int ipgre_open(struct net_device *dev)
6511da177e4SLinus Torvalds {
6522941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
6531da177e4SLinus Torvalds 
654f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr)) {
655cbb1e85fSDavid S. Miller 		struct flowi4 fl4;
656cbb1e85fSDavid S. Miller 		struct rtable *rt;
657cbb1e85fSDavid S. Miller 
658b57708adSNicolas Dichtel 		rt = ip_route_output_gre(t->net, &fl4,
65978fbfd8aSDavid S. Miller 					 t->parms.iph.daddr,
66078fbfd8aSDavid S. Miller 					 t->parms.iph.saddr,
66178fbfd8aSDavid S. Miller 					 t->parms.o_key,
66278fbfd8aSDavid S. Miller 					 RT_TOS(t->parms.iph.tos),
66378fbfd8aSDavid S. Miller 					 t->parms.link);
664b23dd4feSDavid S. Miller 		if (IS_ERR(rt))
6651da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
666d8d1f30bSChangli Gao 		dev = rt->dst.dev;
6671da177e4SLinus Torvalds 		ip_rt_put(rt);
66851456b29SIan Morris 		if (!__in_dev_get_rtnl(dev))
6691da177e4SLinus Torvalds 			return -EADDRNOTAVAIL;
6701da177e4SLinus Torvalds 		t->mlink = dev->ifindex;
671e5ed6399SHerbert Xu 		ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
6721da177e4SLinus Torvalds 	}
6731da177e4SLinus Torvalds 	return 0;
6741da177e4SLinus Torvalds }
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds static int ipgre_close(struct net_device *dev)
6771da177e4SLinus Torvalds {
6782941a486SPatrick McHardy 	struct ip_tunnel *t = netdev_priv(dev);
679b8c26a33SStephen Hemminger 
680f97c1e0cSJoe Perches 	if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
6817fee0ca2SDenis V. Lunev 		struct in_device *in_dev;
682b57708adSNicolas Dichtel 		in_dev = inetdev_by_index(t->net, t->mlink);
6838723e1b4SEric Dumazet 		if (in_dev)
6841da177e4SLinus Torvalds 			ip_mc_dec_group(in_dev, t->parms.iph.daddr);
6851da177e4SLinus Torvalds 	}
6861da177e4SLinus Torvalds 	return 0;
6871da177e4SLinus Torvalds }
6881da177e4SLinus Torvalds #endif
6891da177e4SLinus Torvalds 
690b8c26a33SStephen Hemminger static const struct net_device_ops ipgre_netdev_ops = {
691b8c26a33SStephen Hemminger 	.ndo_init		= ipgre_tunnel_init,
692c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
693b8c26a33SStephen Hemminger #ifdef CONFIG_NET_IPGRE_BROADCAST
694b8c26a33SStephen Hemminger 	.ndo_open		= ipgre_open,
695b8c26a33SStephen Hemminger 	.ndo_stop		= ipgre_close,
696b8c26a33SStephen Hemminger #endif
697c5441932SPravin B Shelar 	.ndo_start_xmit		= ipgre_xmit,
698b8c26a33SStephen Hemminger 	.ndo_do_ioctl		= ipgre_tunnel_ioctl,
699c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
700c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
7011e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
702b8c26a33SStephen Hemminger };
703b8c26a33SStephen Hemminger 
7046b78f16eSEric Dumazet #define GRE_FEATURES (NETIF_F_SG |		\
7056b78f16eSEric Dumazet 		      NETIF_F_FRAGLIST |	\
7066b78f16eSEric Dumazet 		      NETIF_F_HIGHDMA |		\
7076b78f16eSEric Dumazet 		      NETIF_F_HW_CSUM)
7086b78f16eSEric Dumazet 
7091da177e4SLinus Torvalds static void ipgre_tunnel_setup(struct net_device *dev)
7101da177e4SLinus Torvalds {
711b8c26a33SStephen Hemminger 	dev->netdev_ops		= &ipgre_netdev_ops;
7125a455275SNicolas Dichtel 	dev->type		= ARPHRD_IPGRE;
713c5441932SPravin B Shelar 	ip_tunnel_setup(dev, ipgre_net_id);
714c5441932SPravin B Shelar }
7151da177e4SLinus Torvalds 
716c5441932SPravin B Shelar static void __gre_tunnel_init(struct net_device *dev)
717c5441932SPravin B Shelar {
718c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
7194565e991STom Herbert 	int t_hlen;
720c5441932SPravin B Shelar 
721c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
72295f5c64cSTom Herbert 	tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
723c5441932SPravin B Shelar 	tunnel->parms.iph.protocol = IPPROTO_GRE;
724c5441932SPravin B Shelar 
7254565e991STom Herbert 	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
7264565e991STom Herbert 
7274565e991STom Herbert 	t_hlen = tunnel->hlen + sizeof(struct iphdr);
7284565e991STom Herbert 
7294565e991STom Herbert 	dev->needed_headroom	= LL_MAX_HEADER + t_hlen + 4;
7304565e991STom Herbert 	dev->mtu		= ETH_DATA_LEN - t_hlen - 4;
7316b78f16eSEric Dumazet 
732b57708adSNicolas Dichtel 	dev->features		|= GRE_FEATURES;
7336b78f16eSEric Dumazet 	dev->hw_features	|= GRE_FEATURES;
734c5441932SPravin B Shelar 
735c5441932SPravin B Shelar 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
736a0ca153fSAlexander Duyck 		/* TCP offload with GRE SEQ is not supported, nor
737a0ca153fSAlexander Duyck 		 * can we support 2 levels of outer headers requiring
738a0ca153fSAlexander Duyck 		 * an update.
739a0ca153fSAlexander Duyck 		 */
740a0ca153fSAlexander Duyck 		if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
741a0ca153fSAlexander Duyck 		    (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
742c5441932SPravin B Shelar 			dev->features    |= NETIF_F_GSO_SOFTWARE;
743c5441932SPravin B Shelar 			dev->hw_features |= NETIF_F_GSO_SOFTWARE;
744a0ca153fSAlexander Duyck 		}
745a0ca153fSAlexander Duyck 
746c5441932SPravin B Shelar 		/* Can use a lockless transmit, unless we generate
747c5441932SPravin B Shelar 		 * output sequences
748c5441932SPravin B Shelar 		 */
749c5441932SPravin B Shelar 		dev->features |= NETIF_F_LLTX;
750c5441932SPravin B Shelar 	}
7511da177e4SLinus Torvalds }
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds static int ipgre_tunnel_init(struct net_device *dev)
7541da177e4SLinus Torvalds {
755c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
756c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
7571da177e4SLinus Torvalds 
758c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
7591da177e4SLinus Torvalds 
760c5441932SPravin B Shelar 	memcpy(dev->dev_addr, &iph->saddr, 4);
761c5441932SPravin B Shelar 	memcpy(dev->broadcast, &iph->daddr, 4);
7621da177e4SLinus Torvalds 
763c5441932SPravin B Shelar 	dev->flags		= IFF_NOARP;
76402875878SEric Dumazet 	netif_keep_dst(dev);
765c5441932SPravin B Shelar 	dev->addr_len		= 4;
7661da177e4SLinus Torvalds 
767a64b04d8SJiri Benc 	if (iph->daddr && !tunnel->collect_md) {
7681da177e4SLinus Torvalds #ifdef CONFIG_NET_IPGRE_BROADCAST
769f97c1e0cSJoe Perches 		if (ipv4_is_multicast(iph->daddr)) {
7701da177e4SLinus Torvalds 			if (!iph->saddr)
7711da177e4SLinus Torvalds 				return -EINVAL;
7721da177e4SLinus Torvalds 			dev->flags = IFF_BROADCAST;
7733b04dddeSStephen Hemminger 			dev->header_ops = &ipgre_header_ops;
7741da177e4SLinus Torvalds 		}
7751da177e4SLinus Torvalds #endif
776a64b04d8SJiri Benc 	} else if (!tunnel->collect_md) {
7776a5f44d7STimo Teras 		dev->header_ops = &ipgre_header_ops;
778a64b04d8SJiri Benc 	}
7791da177e4SLinus Torvalds 
780c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
78160769a5dSEric Dumazet }
78260769a5dSEric Dumazet 
7839f57c67cSPravin B Shelar static const struct gre_protocol ipgre_protocol = {
7849f57c67cSPravin B Shelar 	.handler     = gre_rcv,
7859f57c67cSPravin B Shelar 	.err_handler = gre_err,
7861da177e4SLinus Torvalds };
7871da177e4SLinus Torvalds 
7882c8c1e72SAlexey Dobriyan static int __net_init ipgre_init_net(struct net *net)
78959a4c759SPavel Emelyanov {
790c5441932SPravin B Shelar 	return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
79159a4c759SPavel Emelyanov }
79259a4c759SPavel Emelyanov 
7932c8c1e72SAlexey Dobriyan static void __net_exit ipgre_exit_net(struct net *net)
79459a4c759SPavel Emelyanov {
795c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
7966c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_link_ops);
79759a4c759SPavel Emelyanov }
79859a4c759SPavel Emelyanov 
79959a4c759SPavel Emelyanov static struct pernet_operations ipgre_net_ops = {
80059a4c759SPavel Emelyanov 	.init = ipgre_init_net,
80159a4c759SPavel Emelyanov 	.exit = ipgre_exit_net,
802cfb8fbf2SEric W. Biederman 	.id   = &ipgre_net_id,
803c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
80459a4c759SPavel Emelyanov };
8051da177e4SLinus Torvalds 
806c19e654dSHerbert Xu static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
807c19e654dSHerbert Xu {
808c19e654dSHerbert Xu 	__be16 flags;
809c19e654dSHerbert Xu 
810c19e654dSHerbert Xu 	if (!data)
811c19e654dSHerbert Xu 		return 0;
812c19e654dSHerbert Xu 
813c19e654dSHerbert Xu 	flags = 0;
814c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
815c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
816c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
817c19e654dSHerbert Xu 		flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
818c19e654dSHerbert Xu 	if (flags & (GRE_VERSION|GRE_ROUTING))
819c19e654dSHerbert Xu 		return -EINVAL;
820c19e654dSHerbert Xu 
821946b636fSJiri Benc 	if (data[IFLA_GRE_COLLECT_METADATA] &&
822946b636fSJiri Benc 	    data[IFLA_GRE_ENCAP_TYPE] &&
823946b636fSJiri Benc 	    nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
824946b636fSJiri Benc 		return -EINVAL;
825946b636fSJiri Benc 
826c19e654dSHerbert Xu 	return 0;
827c19e654dSHerbert Xu }
828c19e654dSHerbert Xu 
829e1a80002SHerbert Xu static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
830e1a80002SHerbert Xu {
831e1a80002SHerbert Xu 	__be32 daddr;
832e1a80002SHerbert Xu 
833e1a80002SHerbert Xu 	if (tb[IFLA_ADDRESS]) {
834e1a80002SHerbert Xu 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
835e1a80002SHerbert Xu 			return -EINVAL;
836e1a80002SHerbert Xu 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
837e1a80002SHerbert Xu 			return -EADDRNOTAVAIL;
838e1a80002SHerbert Xu 	}
839e1a80002SHerbert Xu 
840e1a80002SHerbert Xu 	if (!data)
841e1a80002SHerbert Xu 		goto out;
842e1a80002SHerbert Xu 
843e1a80002SHerbert Xu 	if (data[IFLA_GRE_REMOTE]) {
844e1a80002SHerbert Xu 		memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
845e1a80002SHerbert Xu 		if (!daddr)
846e1a80002SHerbert Xu 			return -EINVAL;
847e1a80002SHerbert Xu 	}
848e1a80002SHerbert Xu 
849e1a80002SHerbert Xu out:
850e1a80002SHerbert Xu 	return ipgre_tunnel_validate(tb, data);
851e1a80002SHerbert Xu }
852e1a80002SHerbert Xu 
85322a59be8SPhilip Prindeville static int ipgre_netlink_parms(struct net_device *dev,
8542e15ea39SPravin B Shelar 				struct nlattr *data[],
8552e15ea39SPravin B Shelar 				struct nlattr *tb[],
856c19e654dSHerbert Xu 				struct ip_tunnel_parm *parms)
857c19e654dSHerbert Xu {
85822a59be8SPhilip Prindeville 	struct ip_tunnel *t = netdev_priv(dev);
85922a59be8SPhilip Prindeville 
8607bb82d92SHerbert Xu 	memset(parms, 0, sizeof(*parms));
861c19e654dSHerbert Xu 
862c19e654dSHerbert Xu 	parms->iph.protocol = IPPROTO_GRE;
863c19e654dSHerbert Xu 
864c19e654dSHerbert Xu 	if (!data)
86522a59be8SPhilip Prindeville 		return 0;
866c19e654dSHerbert Xu 
867c19e654dSHerbert Xu 	if (data[IFLA_GRE_LINK])
868c19e654dSHerbert Xu 		parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
869c19e654dSHerbert Xu 
870c19e654dSHerbert Xu 	if (data[IFLA_GRE_IFLAGS])
871c5441932SPravin B Shelar 		parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
872c19e654dSHerbert Xu 
873c19e654dSHerbert Xu 	if (data[IFLA_GRE_OFLAGS])
874c5441932SPravin B Shelar 		parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
875c19e654dSHerbert Xu 
876c19e654dSHerbert Xu 	if (data[IFLA_GRE_IKEY])
877c19e654dSHerbert Xu 		parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
878c19e654dSHerbert Xu 
879c19e654dSHerbert Xu 	if (data[IFLA_GRE_OKEY])
880c19e654dSHerbert Xu 		parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
881c19e654dSHerbert Xu 
882c19e654dSHerbert Xu 	if (data[IFLA_GRE_LOCAL])
88367b61f6cSJiri Benc 		parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
884c19e654dSHerbert Xu 
885c19e654dSHerbert Xu 	if (data[IFLA_GRE_REMOTE])
88667b61f6cSJiri Benc 		parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
887c19e654dSHerbert Xu 
888c19e654dSHerbert Xu 	if (data[IFLA_GRE_TTL])
889c19e654dSHerbert Xu 		parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
890c19e654dSHerbert Xu 
891c19e654dSHerbert Xu 	if (data[IFLA_GRE_TOS])
892c19e654dSHerbert Xu 		parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
893c19e654dSHerbert Xu 
89422a59be8SPhilip Prindeville 	if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) {
89522a59be8SPhilip Prindeville 		if (t->ignore_df)
89622a59be8SPhilip Prindeville 			return -EINVAL;
897c19e654dSHerbert Xu 		parms->iph.frag_off = htons(IP_DF);
89822a59be8SPhilip Prindeville 	}
8992e15ea39SPravin B Shelar 
9002e15ea39SPravin B Shelar 	if (data[IFLA_GRE_COLLECT_METADATA]) {
9012e15ea39SPravin B Shelar 		t->collect_md = true;
902e271c7b4SJiri Benc 		if (dev->type == ARPHRD_IPGRE)
903e271c7b4SJiri Benc 			dev->type = ARPHRD_NONE;
9042e15ea39SPravin B Shelar 	}
90522a59be8SPhilip Prindeville 
90622a59be8SPhilip Prindeville 	if (data[IFLA_GRE_IGNORE_DF]) {
90722a59be8SPhilip Prindeville 		if (nla_get_u8(data[IFLA_GRE_IGNORE_DF])
90822a59be8SPhilip Prindeville 		  && (parms->iph.frag_off & htons(IP_DF)))
90922a59be8SPhilip Prindeville 			return -EINVAL;
91022a59be8SPhilip Prindeville 		t->ignore_df = !!nla_get_u8(data[IFLA_GRE_IGNORE_DF]);
91122a59be8SPhilip Prindeville 	}
91222a59be8SPhilip Prindeville 
91322a59be8SPhilip Prindeville 	return 0;
914c19e654dSHerbert Xu }
915c19e654dSHerbert Xu 
9164565e991STom Herbert /* This function returns true when ENCAP attributes are present in the nl msg */
9174565e991STom Herbert static bool ipgre_netlink_encap_parms(struct nlattr *data[],
9184565e991STom Herbert 				      struct ip_tunnel_encap *ipencap)
9194565e991STom Herbert {
9204565e991STom Herbert 	bool ret = false;
9214565e991STom Herbert 
9224565e991STom Herbert 	memset(ipencap, 0, sizeof(*ipencap));
9234565e991STom Herbert 
9244565e991STom Herbert 	if (!data)
9254565e991STom Herbert 		return ret;
9264565e991STom Herbert 
9274565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_TYPE]) {
9284565e991STom Herbert 		ret = true;
9294565e991STom Herbert 		ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
9304565e991STom Herbert 	}
9314565e991STom Herbert 
9324565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_FLAGS]) {
9334565e991STom Herbert 		ret = true;
9344565e991STom Herbert 		ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
9354565e991STom Herbert 	}
9364565e991STom Herbert 
9374565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_SPORT]) {
9384565e991STom Herbert 		ret = true;
9393e97fa70SSabrina Dubroca 		ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
9404565e991STom Herbert 	}
9414565e991STom Herbert 
9424565e991STom Herbert 	if (data[IFLA_GRE_ENCAP_DPORT]) {
9434565e991STom Herbert 		ret = true;
9443e97fa70SSabrina Dubroca 		ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
9454565e991STom Herbert 	}
9464565e991STom Herbert 
9474565e991STom Herbert 	return ret;
9484565e991STom Herbert }
9494565e991STom Herbert 
950c5441932SPravin B Shelar static int gre_tap_init(struct net_device *dev)
951e1a80002SHerbert Xu {
952c5441932SPravin B Shelar 	__gre_tunnel_init(dev);
953bec94d43Sstephen hemminger 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
954e1a80002SHerbert Xu 
955c5441932SPravin B Shelar 	return ip_tunnel_init(dev);
956e1a80002SHerbert Xu }
957e1a80002SHerbert Xu 
958c5441932SPravin B Shelar static const struct net_device_ops gre_tap_netdev_ops = {
959c5441932SPravin B Shelar 	.ndo_init		= gre_tap_init,
960c5441932SPravin B Shelar 	.ndo_uninit		= ip_tunnel_uninit,
961c5441932SPravin B Shelar 	.ndo_start_xmit		= gre_tap_xmit,
962b8c26a33SStephen Hemminger 	.ndo_set_mac_address 	= eth_mac_addr,
963b8c26a33SStephen Hemminger 	.ndo_validate_addr	= eth_validate_addr,
964c5441932SPravin B Shelar 	.ndo_change_mtu		= ip_tunnel_change_mtu,
965c5441932SPravin B Shelar 	.ndo_get_stats64	= ip_tunnel_get_stats64,
9661e99584bSNicolas Dichtel 	.ndo_get_iflink		= ip_tunnel_get_iflink,
967fc4099f1SPravin B Shelar 	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
968b8c26a33SStephen Hemminger };
969b8c26a33SStephen Hemminger 
970e1a80002SHerbert Xu static void ipgre_tap_setup(struct net_device *dev)
971e1a80002SHerbert Xu {
972e1a80002SHerbert Xu 	ether_setup(dev);
973c5441932SPravin B Shelar 	dev->netdev_ops	= &gre_tap_netdev_ops;
974d13b161cSJiri Benc 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
975f8c1b7ceSstephen hemminger 	dev->priv_flags	|= IFF_LIVE_ADDR_CHANGE;
976c5441932SPravin B Shelar 	ip_tunnel_setup(dev, gre_tap_net_id);
977e1a80002SHerbert Xu }
978e1a80002SHerbert Xu 
979c5441932SPravin B Shelar static int ipgre_newlink(struct net *src_net, struct net_device *dev,
980c5441932SPravin B Shelar 			 struct nlattr *tb[], struct nlattr *data[])
981c19e654dSHerbert Xu {
982c5441932SPravin B Shelar 	struct ip_tunnel_parm p;
9834565e991STom Herbert 	struct ip_tunnel_encap ipencap;
98422a59be8SPhilip Prindeville 	int err;
9854565e991STom Herbert 
9864565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
9874565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
98822a59be8SPhilip Prindeville 		err = ip_tunnel_encap_setup(t, &ipencap);
9894565e991STom Herbert 
9904565e991STom Herbert 		if (err < 0)
9914565e991STom Herbert 			return err;
9924565e991STom Herbert 	}
993c19e654dSHerbert Xu 
99422a59be8SPhilip Prindeville 	err = ipgre_netlink_parms(dev, data, tb, &p);
99522a59be8SPhilip Prindeville 	if (err < 0)
99622a59be8SPhilip Prindeville 		return err;
997c5441932SPravin B Shelar 	return ip_tunnel_newlink(dev, tb, &p);
998c19e654dSHerbert Xu }
999c19e654dSHerbert Xu 
1000c19e654dSHerbert Xu static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
1001c19e654dSHerbert Xu 			    struct nlattr *data[])
1002c19e654dSHerbert Xu {
1003c19e654dSHerbert Xu 	struct ip_tunnel_parm p;
10044565e991STom Herbert 	struct ip_tunnel_encap ipencap;
100522a59be8SPhilip Prindeville 	int err;
10064565e991STom Herbert 
10074565e991STom Herbert 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
10084565e991STom Herbert 		struct ip_tunnel *t = netdev_priv(dev);
100922a59be8SPhilip Prindeville 		err = ip_tunnel_encap_setup(t, &ipencap);
10104565e991STom Herbert 
10114565e991STom Herbert 		if (err < 0)
10124565e991STom Herbert 			return err;
10134565e991STom Herbert 	}
1014c19e654dSHerbert Xu 
101522a59be8SPhilip Prindeville 	err = ipgre_netlink_parms(dev, data, tb, &p);
101622a59be8SPhilip Prindeville 	if (err < 0)
101722a59be8SPhilip Prindeville 		return err;
1018c5441932SPravin B Shelar 	return ip_tunnel_changelink(dev, tb, &p);
1019c19e654dSHerbert Xu }
1020c19e654dSHerbert Xu 
1021c19e654dSHerbert Xu static size_t ipgre_get_size(const struct net_device *dev)
1022c19e654dSHerbert Xu {
1023c19e654dSHerbert Xu 	return
1024c19e654dSHerbert Xu 		/* IFLA_GRE_LINK */
1025c19e654dSHerbert Xu 		nla_total_size(4) +
1026c19e654dSHerbert Xu 		/* IFLA_GRE_IFLAGS */
1027c19e654dSHerbert Xu 		nla_total_size(2) +
1028c19e654dSHerbert Xu 		/* IFLA_GRE_OFLAGS */
1029c19e654dSHerbert Xu 		nla_total_size(2) +
1030c19e654dSHerbert Xu 		/* IFLA_GRE_IKEY */
1031c19e654dSHerbert Xu 		nla_total_size(4) +
1032c19e654dSHerbert Xu 		/* IFLA_GRE_OKEY */
1033c19e654dSHerbert Xu 		nla_total_size(4) +
1034c19e654dSHerbert Xu 		/* IFLA_GRE_LOCAL */
1035c19e654dSHerbert Xu 		nla_total_size(4) +
1036c19e654dSHerbert Xu 		/* IFLA_GRE_REMOTE */
1037c19e654dSHerbert Xu 		nla_total_size(4) +
1038c19e654dSHerbert Xu 		/* IFLA_GRE_TTL */
1039c19e654dSHerbert Xu 		nla_total_size(1) +
1040c19e654dSHerbert Xu 		/* IFLA_GRE_TOS */
1041c19e654dSHerbert Xu 		nla_total_size(1) +
1042c19e654dSHerbert Xu 		/* IFLA_GRE_PMTUDISC */
1043c19e654dSHerbert Xu 		nla_total_size(1) +
10444565e991STom Herbert 		/* IFLA_GRE_ENCAP_TYPE */
10454565e991STom Herbert 		nla_total_size(2) +
10464565e991STom Herbert 		/* IFLA_GRE_ENCAP_FLAGS */
10474565e991STom Herbert 		nla_total_size(2) +
10484565e991STom Herbert 		/* IFLA_GRE_ENCAP_SPORT */
10494565e991STom Herbert 		nla_total_size(2) +
10504565e991STom Herbert 		/* IFLA_GRE_ENCAP_DPORT */
10514565e991STom Herbert 		nla_total_size(2) +
10522e15ea39SPravin B Shelar 		/* IFLA_GRE_COLLECT_METADATA */
10532e15ea39SPravin B Shelar 		nla_total_size(0) +
105422a59be8SPhilip Prindeville 		/* IFLA_GRE_IGNORE_DF */
105522a59be8SPhilip Prindeville 		nla_total_size(1) +
1056c19e654dSHerbert Xu 		0;
1057c19e654dSHerbert Xu }
1058c19e654dSHerbert Xu 
1059c19e654dSHerbert Xu static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1060c19e654dSHerbert Xu {
1061c19e654dSHerbert Xu 	struct ip_tunnel *t = netdev_priv(dev);
1062c19e654dSHerbert Xu 	struct ip_tunnel_parm *p = &t->parms;
1063c19e654dSHerbert Xu 
1064f3756b79SDavid S. Miller 	if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
106595f5c64cSTom Herbert 	    nla_put_be16(skb, IFLA_GRE_IFLAGS,
106695f5c64cSTom Herbert 			 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
106795f5c64cSTom Herbert 	    nla_put_be16(skb, IFLA_GRE_OFLAGS,
106895f5c64cSTom Herbert 			 gre_tnl_flags_to_gre_flags(p->o_flags)) ||
1069f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1070f3756b79SDavid S. Miller 	    nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1071930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1072930345eaSJiri Benc 	    nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
1073f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1074f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1075f3756b79SDavid S. Miller 	    nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1076f3756b79SDavid S. Miller 		       !!(p->iph.frag_off & htons(IP_DF))))
1077f3756b79SDavid S. Miller 		goto nla_put_failure;
10784565e991STom Herbert 
10794565e991STom Herbert 	if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
10804565e991STom Herbert 			t->encap.type) ||
10813e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
10824565e991STom Herbert 			 t->encap.sport) ||
10833e97fa70SSabrina Dubroca 	    nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
10844565e991STom Herbert 			 t->encap.dport) ||
10854565e991STom Herbert 	    nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
1086e1b2cb65STom Herbert 			t->encap.flags))
10874565e991STom Herbert 		goto nla_put_failure;
10884565e991STom Herbert 
108922a59be8SPhilip Prindeville 	if (nla_put_u8(skb, IFLA_GRE_IGNORE_DF, t->ignore_df))
109022a59be8SPhilip Prindeville 		goto nla_put_failure;
109122a59be8SPhilip Prindeville 
10922e15ea39SPravin B Shelar 	if (t->collect_md) {
10932e15ea39SPravin B Shelar 		if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
10942e15ea39SPravin B Shelar 			goto nla_put_failure;
10952e15ea39SPravin B Shelar 	}
10962e15ea39SPravin B Shelar 
1097c19e654dSHerbert Xu 	return 0;
1098c19e654dSHerbert Xu 
1099c19e654dSHerbert Xu nla_put_failure:
1100c19e654dSHerbert Xu 	return -EMSGSIZE;
1101c19e654dSHerbert Xu }
1102c19e654dSHerbert Xu 
1103c19e654dSHerbert Xu static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1104c19e654dSHerbert Xu 	[IFLA_GRE_LINK]		= { .type = NLA_U32 },
1105c19e654dSHerbert Xu 	[IFLA_GRE_IFLAGS]	= { .type = NLA_U16 },
1106c19e654dSHerbert Xu 	[IFLA_GRE_OFLAGS]	= { .type = NLA_U16 },
1107c19e654dSHerbert Xu 	[IFLA_GRE_IKEY]		= { .type = NLA_U32 },
1108c19e654dSHerbert Xu 	[IFLA_GRE_OKEY]		= { .type = NLA_U32 },
11094d74f8baSPatrick McHardy 	[IFLA_GRE_LOCAL]	= { .len = FIELD_SIZEOF(struct iphdr, saddr) },
11104d74f8baSPatrick McHardy 	[IFLA_GRE_REMOTE]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
1111c19e654dSHerbert Xu 	[IFLA_GRE_TTL]		= { .type = NLA_U8 },
1112c19e654dSHerbert Xu 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
1113c19e654dSHerbert Xu 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
11144565e991STom Herbert 	[IFLA_GRE_ENCAP_TYPE]	= { .type = NLA_U16 },
11154565e991STom Herbert 	[IFLA_GRE_ENCAP_FLAGS]	= { .type = NLA_U16 },
11164565e991STom Herbert 	[IFLA_GRE_ENCAP_SPORT]	= { .type = NLA_U16 },
11174565e991STom Herbert 	[IFLA_GRE_ENCAP_DPORT]	= { .type = NLA_U16 },
11182e15ea39SPravin B Shelar 	[IFLA_GRE_COLLECT_METADATA]	= { .type = NLA_FLAG },
111922a59be8SPhilip Prindeville 	[IFLA_GRE_IGNORE_DF]	= { .type = NLA_U8 },
1120c19e654dSHerbert Xu };
1121c19e654dSHerbert Xu 
1122c19e654dSHerbert Xu static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1123c19e654dSHerbert Xu 	.kind		= "gre",
1124c19e654dSHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1125c19e654dSHerbert Xu 	.policy		= ipgre_policy,
1126c19e654dSHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1127c19e654dSHerbert Xu 	.setup		= ipgre_tunnel_setup,
1128c19e654dSHerbert Xu 	.validate	= ipgre_tunnel_validate,
1129c19e654dSHerbert Xu 	.newlink	= ipgre_newlink,
1130c19e654dSHerbert Xu 	.changelink	= ipgre_changelink,
1131c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1132c19e654dSHerbert Xu 	.get_size	= ipgre_get_size,
1133c19e654dSHerbert Xu 	.fill_info	= ipgre_fill_info,
11341728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1135c19e654dSHerbert Xu };
1136c19e654dSHerbert Xu 
1137e1a80002SHerbert Xu static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1138e1a80002SHerbert Xu 	.kind		= "gretap",
1139e1a80002SHerbert Xu 	.maxtype	= IFLA_GRE_MAX,
1140e1a80002SHerbert Xu 	.policy		= ipgre_policy,
1141e1a80002SHerbert Xu 	.priv_size	= sizeof(struct ip_tunnel),
1142e1a80002SHerbert Xu 	.setup		= ipgre_tap_setup,
1143e1a80002SHerbert Xu 	.validate	= ipgre_tap_validate,
1144e1a80002SHerbert Xu 	.newlink	= ipgre_newlink,
1145e1a80002SHerbert Xu 	.changelink	= ipgre_changelink,
1146c5441932SPravin B Shelar 	.dellink	= ip_tunnel_dellink,
1147e1a80002SHerbert Xu 	.get_size	= ipgre_get_size,
1148e1a80002SHerbert Xu 	.fill_info	= ipgre_fill_info,
11491728d4faSNicolas Dichtel 	.get_link_net	= ip_tunnel_get_link_net,
1150e1a80002SHerbert Xu };
1151e1a80002SHerbert Xu 
1152b2acd1dcSPravin B Shelar struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1153b2acd1dcSPravin B Shelar 					u8 name_assign_type)
1154b2acd1dcSPravin B Shelar {
1155b2acd1dcSPravin B Shelar 	struct nlattr *tb[IFLA_MAX + 1];
1156b2acd1dcSPravin B Shelar 	struct net_device *dev;
1157b2acd1dcSPravin B Shelar 	struct ip_tunnel *t;
1158b2acd1dcSPravin B Shelar 	int err;
1159b2acd1dcSPravin B Shelar 
1160b2acd1dcSPravin B Shelar 	memset(&tb, 0, sizeof(tb));
1161b2acd1dcSPravin B Shelar 
1162b2acd1dcSPravin B Shelar 	dev = rtnl_create_link(net, name, name_assign_type,
1163b2acd1dcSPravin B Shelar 			       &ipgre_tap_ops, tb);
1164b2acd1dcSPravin B Shelar 	if (IS_ERR(dev))
1165b2acd1dcSPravin B Shelar 		return dev;
1166b2acd1dcSPravin B Shelar 
1167b2acd1dcSPravin B Shelar 	/* Configure flow based GRE device. */
1168b2acd1dcSPravin B Shelar 	t = netdev_priv(dev);
1169b2acd1dcSPravin B Shelar 	t->collect_md = true;
1170b2acd1dcSPravin B Shelar 
1171b2acd1dcSPravin B Shelar 	err = ipgre_newlink(net, dev, tb, NULL);
1172b2acd1dcSPravin B Shelar 	if (err < 0)
1173b2acd1dcSPravin B Shelar 		goto out;
11747e059158SDavid Wragg 
11757e059158SDavid Wragg 	/* openvswitch users expect packet sizes to be unrestricted,
11767e059158SDavid Wragg 	 * so set the largest MTU we can.
11777e059158SDavid Wragg 	 */
11787e059158SDavid Wragg 	err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
11797e059158SDavid Wragg 	if (err)
11807e059158SDavid Wragg 		goto out;
11817e059158SDavid Wragg 
1182b2acd1dcSPravin B Shelar 	return dev;
1183b2acd1dcSPravin B Shelar out:
1184b2acd1dcSPravin B Shelar 	free_netdev(dev);
1185b2acd1dcSPravin B Shelar 	return ERR_PTR(err);
1186b2acd1dcSPravin B Shelar }
1187b2acd1dcSPravin B Shelar EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1188b2acd1dcSPravin B Shelar 
1189c5441932SPravin B Shelar static int __net_init ipgre_tap_init_net(struct net *net)
1190c5441932SPravin B Shelar {
11912e15ea39SPravin B Shelar 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
1192c5441932SPravin B Shelar }
1193c5441932SPravin B Shelar 
1194c5441932SPravin B Shelar static void __net_exit ipgre_tap_exit_net(struct net *net)
1195c5441932SPravin B Shelar {
1196c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
11976c742e71SNicolas Dichtel 	ip_tunnel_delete_net(itn, &ipgre_tap_ops);
1198c5441932SPravin B Shelar }
1199c5441932SPravin B Shelar 
1200c5441932SPravin B Shelar static struct pernet_operations ipgre_tap_net_ops = {
1201c5441932SPravin B Shelar 	.init = ipgre_tap_init_net,
1202c5441932SPravin B Shelar 	.exit = ipgre_tap_exit_net,
1203c5441932SPravin B Shelar 	.id   = &gre_tap_net_id,
1204c5441932SPravin B Shelar 	.size = sizeof(struct ip_tunnel_net),
1205c5441932SPravin B Shelar };
12061da177e4SLinus Torvalds 
12071da177e4SLinus Torvalds static int __init ipgre_init(void)
12081da177e4SLinus Torvalds {
12091da177e4SLinus Torvalds 	int err;
12101da177e4SLinus Torvalds 
1211058bd4d2SJoe Perches 	pr_info("GRE over IPv4 tunneling driver\n");
12121da177e4SLinus Torvalds 
1213cfb8fbf2SEric W. Biederman 	err = register_pernet_device(&ipgre_net_ops);
121459a4c759SPavel Emelyanov 	if (err < 0)
1215c2892f02SAlexey Dobriyan 		return err;
1216c2892f02SAlexey Dobriyan 
1217c5441932SPravin B Shelar 	err = register_pernet_device(&ipgre_tap_net_ops);
1218c5441932SPravin B Shelar 	if (err < 0)
1219c5441932SPravin B Shelar 		goto pnet_tap_faied;
1220c5441932SPravin B Shelar 
12219f57c67cSPravin B Shelar 	err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
1222c2892f02SAlexey Dobriyan 	if (err < 0) {
1223058bd4d2SJoe Perches 		pr_info("%s: can't add protocol\n", __func__);
1224c2892f02SAlexey Dobriyan 		goto add_proto_failed;
1225c2892f02SAlexey Dobriyan 	}
12267daa0004SPavel Emelyanov 
1227c19e654dSHerbert Xu 	err = rtnl_link_register(&ipgre_link_ops);
1228c19e654dSHerbert Xu 	if (err < 0)
1229c19e654dSHerbert Xu 		goto rtnl_link_failed;
1230c19e654dSHerbert Xu 
1231e1a80002SHerbert Xu 	err = rtnl_link_register(&ipgre_tap_ops);
1232e1a80002SHerbert Xu 	if (err < 0)
1233e1a80002SHerbert Xu 		goto tap_ops_failed;
1234e1a80002SHerbert Xu 
1235c5441932SPravin B Shelar 	return 0;
1236c19e654dSHerbert Xu 
1237e1a80002SHerbert Xu tap_ops_failed:
1238e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
1239c19e654dSHerbert Xu rtnl_link_failed:
12409f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1241c2892f02SAlexey Dobriyan add_proto_failed:
1242c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1243c5441932SPravin B Shelar pnet_tap_faied:
1244c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
1245c5441932SPravin B Shelar 	return err;
12461da177e4SLinus Torvalds }
12471da177e4SLinus Torvalds 
1248db44575fSAlexey Kuznetsov static void __exit ipgre_fini(void)
12491da177e4SLinus Torvalds {
1250e1a80002SHerbert Xu 	rtnl_link_unregister(&ipgre_tap_ops);
1251c19e654dSHerbert Xu 	rtnl_link_unregister(&ipgre_link_ops);
12529f57c67cSPravin B Shelar 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
1253c5441932SPravin B Shelar 	unregister_pernet_device(&ipgre_tap_net_ops);
1254c2892f02SAlexey Dobriyan 	unregister_pernet_device(&ipgre_net_ops);
12551da177e4SLinus Torvalds }
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds module_init(ipgre_init);
12581da177e4SLinus Torvalds module_exit(ipgre_fini);
12591da177e4SLinus Torvalds MODULE_LICENSE("GPL");
12604d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gre");
12614d74f8baSPatrick McHardy MODULE_ALIAS_RTNL_LINK("gretap");
12628909c9adSVasiliy Kulikov MODULE_ALIAS_NETDEV("gre0");
1263c5441932SPravin B Shelar MODULE_ALIAS_NETDEV("gretap0");
1264