blob: 9609ad71dd260a1162f6dd037010195c4f22f321 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09002 * Linux NET3: GRE over IP protocol decoder.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Joe Perchesafd465032012-03-12 07:03:32 +000013#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
Randy Dunlap4fc268d2006-01-11 12:17:47 -080015#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/module.h>
17#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <asm/uaccess.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/in.h>
24#include <linux/tcp.h>
25#include <linux/udp.h>
26#include <linux/if_arp.h>
Pravin B Shelar2e15ea32015-08-07 23:51:42 -070027#include <linux/if_vlan.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/init.h>
29#include <linux/in6.h>
30#include <linux/inetdevice.h>
31#include <linux/igmp.h>
32#include <linux/netfilter_ipv4.h>
Herbert Xue1a80002008-10-09 12:00:17 -070033#include <linux/etherdevice.h>
Kris Katterjohn46f25df2006-01-05 16:35:42 -080034#include <linux/if_ether.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/sock.h>
37#include <net/ip.h>
38#include <net/icmp.h>
39#include <net/protocol.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000040#include <net/ip_tunnels.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <net/arp.h>
42#include <net/checksum.h>
43#include <net/dsfield.h>
44#include <net/inet_ecn.h>
45#include <net/xfrm.h>
Pavel Emelyanov59a4c752008-04-16 01:08:53 -070046#include <net/net_namespace.h>
47#include <net/netns/generic.h>
Herbert Xuc19e6542008-10-09 11:59:55 -070048#include <net/rtnetlink.h>
Dmitry Kozlov00959ad2010-08-21 23:05:39 -070049#include <net/gre.h>
Pravin B Shelar2e15ea32015-08-07 23:51:42 -070050#include <net/dst_metadata.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052/*
53 Problems & solutions
54 --------------------
55
56 1. The most important issue is detecting local dead loops.
57 They would cause complete host lockup in transmit, which
58 would be "resolved" by stack overflow or, if queueing is enabled,
59 with infinite looping in net_bh.
60
61 We cannot track such dead loops during route installation,
62 it is infeasible task. The most general solutions would be
63 to keep skb->encapsulation counter (sort of local ttl),
Eric Dumazet6d0722a2010-09-29 23:35:10 -070064 and silently drop packet when it expires. It is a good
stephen hemmingerbff52852012-02-24 08:08:20 +000065 solution, but it supposes maintaining new variable in ALL
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 skb, even if no tunneling is used.
67
Eric Dumazet6d0722a2010-09-29 23:35:10 -070068 Current solution: xmit_recursion breaks dead loops. This is a percpu
69 counter, since when we enter the first ndo_xmit(), cpu migration is
70 forbidden. We force an exit if this counter reaches RECURSION_LIMIT
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
72 2. Networking dead loops would not kill routers, but would really
73 kill network. IP hop limit plays role of "t->recursion" in this case,
74 if we copy it from packet being encapsulated to upper header.
75 It is very good solution, but it introduces two problems:
76
77 - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
78 do not work over tunnels.
79 - traceroute does not work. I planned to relay ICMP from tunnel,
80 so that this problem would be solved and traceroute output
81 would even more informative. This idea appeared to be wrong:
82 only Linux complies to rfc1812 now (yes, guys, Linux is the only
83 true router now :-)), all routers (at least, in neighbourhood of mine)
84 return only 8 bytes of payload. It is the end.
85
86 Hence, if we want that OSPF worked or traceroute said something reasonable,
87 we should search for another solution.
88
89 One of them is to parse packet trying to detect inner encapsulation
90 made by our node. It is difficult or even impossible, especially,
stephen hemmingerbff52852012-02-24 08:08:20 +000091 taking into account fragmentation. TO be short, ttl is not solution at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93 Current solution: The solution was UNEXPECTEDLY SIMPLE.
94 We force DF flag on tunnels with preconfigured hop limit,
95 that is ALL. :-) Well, it does not remove the problem completely,
96 but exponential growth of network traffic is changed to linear
97 (branches, that exceed pmtu are pruned) and tunnel mtu
stephen hemmingerbff52852012-02-24 08:08:20 +000098 rapidly degrades to value <68, where looping stops.
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 Yes, it is not good if there exists a router in the loop,
100 which does not force DF, even when encapsulating packets have DF set.
101 But it is not our problem! Nobody could accuse us, we made
102 all that we could make. Even if it is your gated who injected
103 fatal route to network, even if it were you who configured
104 fatal static route: you are innocent. :-)
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 Alexey Kuznetsov.
107 */
108
stephen hemmingereccc1bb2012-09-25 11:02:48 +0000109static bool log_ecn_error = true;
110module_param(log_ecn_error, bool, 0644);
111MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
112
Herbert Xuc19e6542008-10-09 11:59:55 -0700113static struct rtnl_link_ops ipgre_link_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114static int ipgre_tunnel_init(struct net_device *dev);
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700115
Eric Dumazetf99189b2009-11-17 10:42:49 +0000116static int ipgre_net_id __read_mostly;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000117static int gre_tap_net_id __read_mostly;
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700118
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700119static void ipgre_err(struct sk_buff *skb, u32 info,
120 const struct tnl_ptk_info *tpi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Pravin B Shelarc5441932013-03-25 14:49:35 +0000123 /* All the routers (except for Linux) return only
124 8 bytes of packet payload. It means, that precise relaying of
125 ICMP in the real Internet is absolutely infeasible.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Pravin B Shelarc5441932013-03-25 14:49:35 +0000127 Moreover, Cisco "wise men" put GRE key to the third word
128 in GRE header. It makes impossible maintaining even soft
129 state for keyed GRE tunnels with enabled checksum. Tell
130 them "thank you".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Pravin B Shelarc5441932013-03-25 14:49:35 +0000132 Well, I wonder, rfc1812 was written by Cisco employee,
133 what the hell these idiots break standards established
134 by themselves???
135 */
136 struct net *net = dev_net(skb->dev);
137 struct ip_tunnel_net *itn;
Eric Dumazet96f5a842013-05-18 08:36:03 +0000138 const struct iphdr *iph;
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300139 const int type = icmp_hdr(skb)->type;
140 const int code = icmp_hdr(skb)->code;
Eric Dumazet20e19542016-06-18 21:52:06 -0700141 unsigned int data_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 struct ip_tunnel *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 switch (type) {
145 default:
146 case ICMP_PARAMETERPROB:
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700147 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
149 case ICMP_DEST_UNREACH:
150 switch (code) {
151 case ICMP_SR_FAILED:
152 case ICMP_PORT_UNREACH:
153 /* Impossible event. */
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700154 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 default:
156 /* All others are translated to HOST_UNREACH.
157 rfc2003 contains "deep thoughts" about NET_UNREACH,
158 I believe they are just ether pollution. --ANK
159 */
160 break;
161 }
162 break;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 case ICMP_TIME_EXCEEDED:
165 if (code != ICMP_EXC_TTL)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700166 return;
Eric Dumazet20e19542016-06-18 21:52:06 -0700167 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 break;
David S. Miller55be7a92012-07-11 21:27:49 -0700169
170 case ICMP_REDIRECT:
171 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 }
173
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700174 if (tpi->proto == htons(ETH_P_TEB))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000175 itn = net_generic(net, gre_tap_net_id);
176 else
177 itn = net_generic(net, ipgre_net_id);
178
Duan Jiongc0c0c502014-01-28 11:49:43 +0800179 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700180 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
181 iph->daddr, iph->saddr, tpi->key);
stephen hemmingerd2083282012-09-24 18:12:23 +0000182
Ian Morris51456b22015-04-03 09:17:26 +0100183 if (!t)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700184 return;
David S. Miller36393392012-06-14 22:21:46 -0700185
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700186#if IS_ENABLED(CONFIG_IPV6)
187 if (tpi->proto == htons(ETH_P_IPV6) &&
Eric Dumazet20e19542016-06-18 21:52:06 -0700188 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
189 type, data_len))
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700190 return;
191#endif
192
David S. Miller36393392012-06-14 22:21:46 -0700193 if (t->parms.iph.daddr == 0 ||
Joe Perchesf97c1e02007-12-16 13:45:43 -0800194 ipv4_is_multicast(t->parms.iph.daddr))
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700195 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700198 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Wei Yongjunda6185d82009-02-24 23:34:48 -0800200 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 t->err_count++;
202 else
203 t->err_count = 1;
204 t->err_time = jiffies;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700205}
206
207static void gre_err(struct sk_buff *skb, u32 info)
208{
209 /* All the routers (except for Linux) return only
210 * 8 bytes of packet payload. It means, that precise relaying of
211 * ICMP in the real Internet is absolutely infeasible.
212 *
213 * Moreover, Cisco "wise men" put GRE key to the third word
214 * in GRE header. It makes impossible maintaining even soft
215 * state for keyed
216 * GRE tunnels with enabled checksum. Tell them "thank you".
217 *
218 * Well, I wonder, rfc1812 was written by Cisco employee,
219 * what the hell these idiots break standards established
220 * by themselves???
221 */
222
Eric Dumazete5826152016-06-15 06:24:00 -0700223 const struct iphdr *iph = (struct iphdr *)skb->data;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700224 const int type = icmp_hdr(skb)->type;
225 const int code = icmp_hdr(skb)->code;
226 struct tnl_ptk_info tpi;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700227
Haishuang Yan53949762018-09-14 12:26:47 +0800228 if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IP),
229 iph->ihl * 4) < 0)
230 return;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700231
232 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
233 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
234 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
235 return;
236 }
237 if (type == ICMP_REDIRECT) {
238 ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
239 IPPROTO_GRE, 0);
240 return;
241 }
242
243 ipgre_err(skb, info, &tpi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244}
245
Jiri Benc125372f2016-05-03 17:10:08 +0200246static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
247 struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700249 struct metadata_dst *tun_dst = NULL;
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000250 const struct iphdr *iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 struct ip_tunnel *tunnel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700253 iph = ip_hdr(skb);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700254 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
255 iph->saddr, iph->daddr, tpi->key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
stephen hemmingerd2083282012-09-24 18:12:23 +0000257 if (tunnel) {
Jiri Benc125372f2016-05-03 17:10:08 +0200258 if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
259 raw_proto, false) < 0)
Jiri Benc244a7972016-05-03 17:10:07 +0200260 goto drop;
261
Jiri Bence271c7b2016-05-11 15:53:57 +0200262 if (tunnel->dev->type != ARPHRD_NONE)
263 skb_pop_mac_header(skb);
264 else
265 skb_reset_mac_header(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700266 if (tunnel->collect_md) {
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700267 __be16 flags;
268 __be64 tun_id;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700269
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700270 flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
Amir Vadaid817f432016-09-08 16:23:45 +0300271 tun_id = key32_to_tunnel_id(tpi->key);
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700272 tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700273 if (!tun_dst)
274 return PACKET_REJECT;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700275 }
276
277 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700278 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 }
Jiri Benc125372f2016-05-03 17:10:08 +0200280 return PACKET_NEXT;
Jiri Benc244a7972016-05-03 17:10:07 +0200281
282drop:
283 kfree_skb(skb);
284 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285}
286
Jiri Benc125372f2016-05-03 17:10:08 +0200287static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
288 int hdr_len)
289{
290 struct net *net = dev_net(skb->dev);
291 struct ip_tunnel_net *itn;
292 int res;
293
294 if (tpi->proto == htons(ETH_P_TEB))
295 itn = net_generic(net, gre_tap_net_id);
296 else
297 itn = net_generic(net, ipgre_net_id);
298
299 res = __ipgre_rcv(skb, tpi, itn, hdr_len, false);
300 if (res == PACKET_NEXT && tpi->proto == htons(ETH_P_TEB)) {
301 /* ipgre tunnels in collect metadata mode should receive
302 * also ETH_P_TEB traffic.
303 */
304 itn = net_generic(net, ipgre_net_id);
305 res = __ipgre_rcv(skb, tpi, itn, hdr_len, true);
306 }
307 return res;
308}
309
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700310static int gre_rcv(struct sk_buff *skb)
311{
312 struct tnl_ptk_info tpi;
313 bool csum_err = false;
Tom Herbert95f5c642016-04-29 17:12:16 -0700314 int hdr_len;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700315
316#ifdef CONFIG_NET_IPGRE_BROADCAST
317 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
318 /* Looped back packet, drop it! */
319 if (rt_is_output_route(skb_rtable(skb)))
320 goto drop;
321 }
322#endif
323
Eric Dumazete5826152016-06-15 06:24:00 -0700324 hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0);
Jiri Bencf132ae72016-05-03 15:00:21 +0200325 if (hdr_len < 0)
Tom Herbert95f5c642016-04-29 17:12:16 -0700326 goto drop;
327
Jiri Benc244a7972016-05-03 17:10:07 +0200328 if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700329 return 0;
330
331 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
332drop:
333 kfree_skb(skb);
334 return 0;
335}
336
Pravin B Shelarc5441932013-03-25 14:49:35 +0000337static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
338 const struct iphdr *tnl_params,
339 __be16 proto)
340{
341 struct ip_tunnel *tunnel = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000342
Pravin B Shelarc5441932013-03-25 14:49:35 +0000343 if (tunnel->parms.o_flags & TUNNEL_SEQ)
344 tunnel->o_seqno++;
Eric Dumazetcef401d2013-01-25 20:34:37 +0000345
Pravin B Shelarc5441932013-03-25 14:49:35 +0000346 /* Push GRE header. */
Tom Herbert182a3522016-04-29 17:12:19 -0700347 gre_build_header(skb, tunnel->tun_hlen,
348 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
349 htonl(tunnel->o_seqno));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
Nicolas Dichtelbf3d6a82013-05-27 23:48:15 +0000351 ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352}
353
Alexander Duyckaed069d2016-04-14 15:33:37 -0400354static int gre_handle_offloads(struct sk_buff *skb, bool csum)
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700355{
Edward Cree6fa79662016-02-11 21:02:31 +0000356 return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700357}
358
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700359static struct rtable *gre_get_rt(struct sk_buff *skb,
360 struct net_device *dev,
361 struct flowi4 *fl,
362 const struct ip_tunnel_key *key)
363{
364 struct net *net = dev_net(dev);
365
366 memset(fl, 0, sizeof(*fl));
367 fl->daddr = key->u.ipv4.dst;
368 fl->saddr = key->u.ipv4.src;
369 fl->flowi4_tos = RT_TOS(key->tos);
370 fl->flowi4_mark = skb->mark;
371 fl->flowi4_proto = IPPROTO_GRE;
372
373 return ip_route_output_key(net, fl);
374}
375
Jiri Benc20907142016-04-27 11:29:07 +0200376static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
377 __be16 proto)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700378{
379 struct ip_tunnel_info *tun_info;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700380 const struct ip_tunnel_key *key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100381 struct rtable *rt = NULL;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700382 struct flowi4 fl;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700383 int min_headroom;
384 int tunnel_hlen;
385 __be16 df, flags;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100386 bool use_cache;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700387 int err;
388
Jiri Benc61adedf2015-08-20 13:56:25 +0200389 tun_info = skb_tunnel_info(skb);
Jiri Benc7f9562a2015-08-28 20:48:20 +0200390 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
391 ip_tunnel_info_af(tun_info) != AF_INET))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700392 goto err_free_skb;
393
394 key = &tun_info->key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100395 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
396 if (use_cache)
397 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
Paolo Abeni3c1cb4d2016-02-12 15:43:59 +0100398 if (!rt) {
399 rt = gre_get_rt(skb, dev, &fl, key);
400 if (IS_ERR(rt))
401 goto err_free_skb;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100402 if (use_cache)
Paolo Abeni3c1cb4d2016-02-12 15:43:59 +0100403 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
404 fl.saddr);
405 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700406
Tom Herbert95f5c642016-04-29 17:12:16 -0700407 tunnel_hlen = gre_calc_hlen(key->tun_flags);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700408
409 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
410 + tunnel_hlen + sizeof(struct iphdr);
411 if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
412 int head_delta = SKB_DATA_ALIGN(min_headroom -
413 skb_headroom(skb) +
414 16);
415 err = pskb_expand_head(skb, max_t(int, head_delta, 0),
416 0, GFP_ATOMIC);
417 if (unlikely(err))
418 goto err_free_rt;
419 }
420
421 /* Push Tunnel header. */
Alexander Duyckaed069d2016-04-14 15:33:37 -0400422 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700423 goto err_free_rt;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700424
425 flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
David S. Millercba653212016-05-04 00:52:29 -0400426 gre_build_header(skb, tunnel_hlen, flags, proto,
Amir Vadaid817f432016-09-08 16:23:45 +0300427 tunnel_id_to_key32(tun_info->key.tun_id), 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700428
429 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
Pravin B Shelar039f5062015-12-24 14:34:54 -0800430
431 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
432 key->tos, key->ttl, df, false);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700433 return;
434
435err_free_rt:
436 ip_rt_put(rt);
437err_free_skb:
438 kfree_skb(skb);
439 dev->stats.tx_dropped++;
440}
441
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700442static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
443{
444 struct ip_tunnel_info *info = skb_tunnel_info(skb);
445 struct rtable *rt;
446 struct flowi4 fl4;
447
448 if (ip_tunnel_info_af(info) != AF_INET)
449 return -EINVAL;
450
451 rt = gre_get_rt(skb, dev, &fl4, &info->key);
452 if (IS_ERR(rt))
453 return PTR_ERR(rt);
454
455 ip_rt_put(rt);
456 info->key.u.ipv4.src = fl4.saddr;
457 return 0;
458}
459
Pravin B Shelarc5441932013-03-25 14:49:35 +0000460static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
461 struct net_device *dev)
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800462{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000463 struct ip_tunnel *tunnel = netdev_priv(dev);
464 const struct iphdr *tnl_params;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800465
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700466 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200467 gre_fb_xmit(skb, dev, skb->protocol);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700468 return NETDEV_TX_OK;
469 }
470
Pravin B Shelarc5441932013-03-25 14:49:35 +0000471 if (dev->header_ops) {
472 /* Need space for new headers */
473 if (skb_cow_head(skb, dev->needed_headroom -
Chen Gang2bac7cb2013-04-22 20:45:42 +0000474 (tunnel->hlen + sizeof(struct iphdr))))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000475 goto free_skb;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800476
Pravin B Shelarc5441932013-03-25 14:49:35 +0000477 tnl_params = (const struct iphdr *)skb->data;
Eric Dumazete985aad2010-09-27 03:57:11 +0000478
Pravin B Shelarc5441932013-03-25 14:49:35 +0000479 /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
480 * to gre header.
481 */
482 skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
Timo Teräs8a0033a2014-12-15 09:24:13 +0200483 skb_reset_mac_header(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000484 } else {
485 if (skb_cow_head(skb, dev->needed_headroom))
486 goto free_skb;
Herbert Xue1a80002008-10-09 12:00:17 -0700487
Pravin B Shelarc5441932013-03-25 14:49:35 +0000488 tnl_params = &tunnel->parms.iph;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800489 }
490
Alexander Duyckaed069d2016-04-14 15:33:37 -0400491 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
492 goto free_skb;
Timo Teräs8a0033a2014-12-15 09:24:13 +0200493
Pravin B Shelarc5441932013-03-25 14:49:35 +0000494 __gre_xmit(skb, dev, tnl_params, skb->protocol);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000495 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800496
Pravin B Shelarc5441932013-03-25 14:49:35 +0000497free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800498 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000499 dev->stats.tx_dropped++;
500 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800501}
502
Pravin B Shelarc5441932013-03-25 14:49:35 +0000503static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
504 struct net_device *dev)
505{
506 struct ip_tunnel *tunnel = netdev_priv(dev);
507
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700508 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200509 gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700510 return NETDEV_TX_OK;
511 }
512
Alexander Duyckaed069d2016-04-14 15:33:37 -0400513 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
514 goto free_skb;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000515
516 if (skb_cow_head(skb, dev->needed_headroom))
517 goto free_skb;
518
519 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000520 return NETDEV_TX_OK;
521
522free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800523 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000524 dev->stats.tx_dropped++;
525 return NETDEV_TX_OK;
526}
527
528static int ipgre_tunnel_ioctl(struct net_device *dev,
529 struct ifreq *ifr, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530{
Tom Herbert4565e992014-09-17 12:26:01 -0700531 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 struct ip_tunnel_parm p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
Pravin B Shelarc5441932013-03-25 14:49:35 +0000534 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
535 return -EFAULT;
Cong Wang6c734fb2013-06-29 12:02:59 +0800536 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
537 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
538 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
539 ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
540 return -EINVAL;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000541 }
542 p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
543 p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
544
545 err = ip_tunnel_ioctl(dev, &p, cmd);
546 if (err)
547 return err;
548
Tom Herbert95f5c642016-04-29 17:12:16 -0700549 p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
550 p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000551
552 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
553 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 return 0;
555}
556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557/* Nice toy. Unfortunately, useless in real life :-)
558 It allows to construct virtual multiprotocol broadcast "LAN"
559 over the Internet, provided multicast routing is tuned.
560
561
562 I have no idea was this bicycle invented before me,
563 so that I had to set ARPHRD_IPGRE to a random value.
564 I have an impression, that Cisco could make something similar,
565 but this feature is apparently missing in IOS<=11.2(8).
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
568 with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
569
570 ping -t 255 224.66.66.66
571
572 If nobody answers, mbone does not work.
573
574 ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
575 ip addr add 10.66.66.<somewhat>/24 dev Universe
576 ifconfig Universe up
577 ifconfig Universe add fe80::<Your_real_addr>/10
578 ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
579 ftp 10.66.66.66
580 ...
581 ftp fec0:6666:6666::193.233.7.65
582 ...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700584static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
585 unsigned short type,
Eric Dumazet15078502010-09-15 11:07:53 +0000586 const void *daddr, const void *saddr, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587{
Patrick McHardy2941a482006-01-08 22:05:26 -0800588 struct ip_tunnel *t = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000589 struct iphdr *iph;
590 struct gre_base_hdr *greh;
591
592 iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
593 greh = (struct gre_base_hdr *)(iph+1);
Tom Herbert95f5c642016-04-29 17:12:16 -0700594 greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000595 greh->protocol = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597 memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
Pravin B Shelarc5441932013-03-25 14:49:35 +0000599 /* Set the source hardware address. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 if (saddr)
601 memcpy(&iph->saddr, saddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000602 if (daddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 memcpy(&iph->daddr, daddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000604 if (iph->daddr)
Timo Teräs77a482b2013-08-06 13:45:43 +0300605 return t->hlen + sizeof(*iph);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900606
Pravin B Shelarc5441932013-03-25 14:49:35 +0000607 return -(t->hlen + sizeof(*iph));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608}
609
Timo Teras6a5f44d2007-10-23 20:31:53 -0700610static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
611{
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000612 const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
Timo Teras6a5f44d2007-10-23 20:31:53 -0700613 memcpy(haddr, &iph->saddr, 4);
614 return 4;
615}
616
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700617static const struct header_ops ipgre_header_ops = {
618 .create = ipgre_header,
Timo Teras6a5f44d2007-10-23 20:31:53 -0700619 .parse = ipgre_header_parse,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700620};
621
Timo Teras6a5f44d2007-10-23 20:31:53 -0700622#ifdef CONFIG_NET_IPGRE_BROADCAST
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623static int ipgre_open(struct net_device *dev)
624{
Patrick McHardy2941a482006-01-08 22:05:26 -0800625 struct ip_tunnel *t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
Joe Perchesf97c1e02007-12-16 13:45:43 -0800627 if (ipv4_is_multicast(t->parms.iph.daddr)) {
David S. Millercbb1e852011-05-04 12:33:34 -0700628 struct flowi4 fl4;
629 struct rtable *rt;
Eric Dumazete985aad2010-09-27 03:57:11 +0000630
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200631 rt = ip_route_output_gre(t->net, &fl4,
David S. Millercbb1e852011-05-04 12:33:34 -0700632 t->parms.iph.daddr,
633 t->parms.iph.saddr,
634 t->parms.o_key,
635 RT_TOS(t->parms.iph.tos),
636 t->parms.link);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800637 if (IS_ERR(rt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 return -EADDRNOTAVAIL;
Changli Gaod8d1f302010-06-10 23:31:35 -0700639 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 ip_rt_put(rt);
Ian Morris51456b22015-04-03 09:17:26 +0100641 if (!__in_dev_get_rtnl(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 return -EADDRNOTAVAIL;
643 t->mlink = dev->ifindex;
Herbert Xue5ed6392005-10-03 14:35:55 -0700644 ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 }
646 return 0;
647}
648
649static int ipgre_close(struct net_device *dev)
650{
Patrick McHardy2941a482006-01-08 22:05:26 -0800651 struct ip_tunnel *t = netdev_priv(dev);
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800652
Joe Perchesf97c1e02007-12-16 13:45:43 -0800653 if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
Denis V. Lunev7fee0ca2008-01-21 17:32:38 -0800654 struct in_device *in_dev;
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200655 in_dev = inetdev_by_index(t->net, t->mlink);
Eric Dumazet8723e1b2010-10-19 00:39:26 +0000656 if (in_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 ip_mc_dec_group(in_dev, t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 }
659 return 0;
660}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661#endif
662
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800663static const struct net_device_ops ipgre_netdev_ops = {
664 .ndo_init = ipgre_tunnel_init,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000665 .ndo_uninit = ip_tunnel_uninit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800666#ifdef CONFIG_NET_IPGRE_BROADCAST
667 .ndo_open = ipgre_open,
668 .ndo_stop = ipgre_close,
669#endif
Pravin B Shelarc5441932013-03-25 14:49:35 +0000670 .ndo_start_xmit = ipgre_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800671 .ndo_do_ioctl = ipgre_tunnel_ioctl,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000672 .ndo_change_mtu = ip_tunnel_change_mtu,
673 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200674 .ndo_get_iflink = ip_tunnel_get_iflink,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800675};
676
Eric Dumazet6b78f162012-09-13 21:25:33 +0000677#define GRE_FEATURES (NETIF_F_SG | \
678 NETIF_F_FRAGLIST | \
679 NETIF_F_HIGHDMA | \
680 NETIF_F_HW_CSUM)
681
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682static void ipgre_tunnel_setup(struct net_device *dev)
683{
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800684 dev->netdev_ops = &ipgre_netdev_ops;
Nicolas Dichtel5a455272014-04-11 15:51:18 +0200685 dev->type = ARPHRD_IPGRE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000686 ip_tunnel_setup(dev, ipgre_net_id);
687}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688
Pravin B Shelarc5441932013-03-25 14:49:35 +0000689static void __gre_tunnel_init(struct net_device *dev)
690{
691 struct ip_tunnel *tunnel;
Tom Herbert4565e992014-09-17 12:26:01 -0700692 int t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000693
694 tunnel = netdev_priv(dev);
Tom Herbert95f5c642016-04-29 17:12:16 -0700695 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000696 tunnel->parms.iph.protocol = IPPROTO_GRE;
697
Tom Herbert4565e992014-09-17 12:26:01 -0700698 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
699
700 t_hlen = tunnel->hlen + sizeof(struct iphdr);
701
702 dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
703 dev->mtu = ETH_DATA_LEN - t_hlen - 4;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000704
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200705 dev->features |= GRE_FEATURES;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000706 dev->hw_features |= GRE_FEATURES;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000707
708 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
Alexander Duycka0ca1532016-04-05 09:13:39 -0700709 /* TCP offload with GRE SEQ is not supported, nor
710 * can we support 2 levels of outer headers requiring
711 * an update.
712 */
713 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
714 (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
715 dev->features |= NETIF_F_GSO_SOFTWARE;
716 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
717 }
718
Pravin B Shelarc5441932013-03-25 14:49:35 +0000719 /* Can use a lockless transmit, unless we generate
720 * output sequences
721 */
722 dev->features |= NETIF_F_LLTX;
723 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724}
725
726static int ipgre_tunnel_init(struct net_device *dev)
727{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000728 struct ip_tunnel *tunnel = netdev_priv(dev);
729 struct iphdr *iph = &tunnel->parms.iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
Pravin B Shelarc5441932013-03-25 14:49:35 +0000731 __gre_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
Pravin B Shelarc5441932013-03-25 14:49:35 +0000733 memcpy(dev->dev_addr, &iph->saddr, 4);
734 memcpy(dev->broadcast, &iph->daddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
Pravin B Shelarc5441932013-03-25 14:49:35 +0000736 dev->flags = IFF_NOARP;
Eric Dumazet02875872014-10-05 18:38:35 -0700737 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000738 dev->addr_len = 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
Jiri Benca64b04d2016-04-27 11:29:06 +0200740 if (iph->daddr && !tunnel->collect_md) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741#ifdef CONFIG_NET_IPGRE_BROADCAST
Joe Perchesf97c1e02007-12-16 13:45:43 -0800742 if (ipv4_is_multicast(iph->daddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 if (!iph->saddr)
744 return -EINVAL;
745 dev->flags = IFF_BROADCAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700746 dev->header_ops = &ipgre_header_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 }
748#endif
Jiri Benca64b04d2016-04-27 11:29:06 +0200749 } else if (!tunnel->collect_md) {
Timo Teras6a5f44d2007-10-23 20:31:53 -0700750 dev->header_ops = &ipgre_header_ops;
Jiri Benca64b04d2016-04-27 11:29:06 +0200751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
Pravin B Shelarc5441932013-03-25 14:49:35 +0000753 return ip_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754}
755
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700756static const struct gre_protocol ipgre_protocol = {
757 .handler = gre_rcv,
758 .err_handler = gre_err,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759};
760
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000761static int __net_init ipgre_init_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700762{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000763 return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700764}
765
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000766static void __net_exit ipgre_exit_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700767{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000768 struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200769 ip_tunnel_delete_net(itn, &ipgre_link_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700770}
771
772static struct pernet_operations ipgre_net_ops = {
773 .init = ipgre_init_net,
774 .exit = ipgre_exit_net,
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +0000775 .id = &ipgre_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000776 .size = sizeof(struct ip_tunnel_net),
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700777};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
Herbert Xuc19e6542008-10-09 11:59:55 -0700779static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
780{
781 __be16 flags;
782
783 if (!data)
784 return 0;
785
786 flags = 0;
787 if (data[IFLA_GRE_IFLAGS])
788 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
789 if (data[IFLA_GRE_OFLAGS])
790 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
791 if (flags & (GRE_VERSION|GRE_ROUTING))
792 return -EINVAL;
793
Jiri Benc946b6362016-04-27 14:08:01 +0200794 if (data[IFLA_GRE_COLLECT_METADATA] &&
795 data[IFLA_GRE_ENCAP_TYPE] &&
796 nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
797 return -EINVAL;
798
Herbert Xuc19e6542008-10-09 11:59:55 -0700799 return 0;
800}
801
Herbert Xue1a80002008-10-09 12:00:17 -0700802static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
803{
804 __be32 daddr;
805
806 if (tb[IFLA_ADDRESS]) {
807 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
808 return -EINVAL;
809 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
810 return -EADDRNOTAVAIL;
811 }
812
813 if (!data)
814 goto out;
815
816 if (data[IFLA_GRE_REMOTE]) {
817 memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
818 if (!daddr)
819 return -EINVAL;
820 }
821
822out:
823 return ipgre_tunnel_validate(tb, data);
824}
825
Philip Prindeville22a59be2016-06-14 15:53:02 -0600826static int ipgre_netlink_parms(struct net_device *dev,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700827 struct nlattr *data[],
828 struct nlattr *tb[],
829 struct ip_tunnel_parm *parms)
Herbert Xuc19e6542008-10-09 11:59:55 -0700830{
Philip Prindeville22a59be2016-06-14 15:53:02 -0600831 struct ip_tunnel *t = netdev_priv(dev);
832
Herbert Xu7bb82d92008-10-11 12:20:15 -0700833 memset(parms, 0, sizeof(*parms));
Herbert Xuc19e6542008-10-09 11:59:55 -0700834
835 parms->iph.protocol = IPPROTO_GRE;
836
837 if (!data)
Philip Prindeville22a59be2016-06-14 15:53:02 -0600838 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -0700839
840 if (data[IFLA_GRE_LINK])
841 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
842
843 if (data[IFLA_GRE_IFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +0000844 parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -0700845
846 if (data[IFLA_GRE_OFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +0000847 parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -0700848
849 if (data[IFLA_GRE_IKEY])
850 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
851
852 if (data[IFLA_GRE_OKEY])
853 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
854
855 if (data[IFLA_GRE_LOCAL])
Jiri Benc67b61f62015-03-29 16:59:26 +0200856 parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
Herbert Xuc19e6542008-10-09 11:59:55 -0700857
858 if (data[IFLA_GRE_REMOTE])
Jiri Benc67b61f62015-03-29 16:59:26 +0200859 parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
Herbert Xuc19e6542008-10-09 11:59:55 -0700860
861 if (data[IFLA_GRE_TTL])
862 parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
863
864 if (data[IFLA_GRE_TOS])
865 parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
866
Philip Prindeville22a59be2016-06-14 15:53:02 -0600867 if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) {
868 if (t->ignore_df)
869 return -EINVAL;
Herbert Xuc19e6542008-10-09 11:59:55 -0700870 parms->iph.frag_off = htons(IP_DF);
Philip Prindeville22a59be2016-06-14 15:53:02 -0600871 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700872
873 if (data[IFLA_GRE_COLLECT_METADATA]) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700874 t->collect_md = true;
Jiri Bence271c7b2016-05-11 15:53:57 +0200875 if (dev->type == ARPHRD_IPGRE)
876 dev->type = ARPHRD_NONE;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700877 }
Philip Prindeville22a59be2016-06-14 15:53:02 -0600878
879 if (data[IFLA_GRE_IGNORE_DF]) {
880 if (nla_get_u8(data[IFLA_GRE_IGNORE_DF])
881 && (parms->iph.frag_off & htons(IP_DF)))
882 return -EINVAL;
883 t->ignore_df = !!nla_get_u8(data[IFLA_GRE_IGNORE_DF]);
884 }
885
886 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -0700887}
888
Tom Herbert4565e992014-09-17 12:26:01 -0700889/* This function returns true when ENCAP attributes are present in the nl msg */
890static bool ipgre_netlink_encap_parms(struct nlattr *data[],
891 struct ip_tunnel_encap *ipencap)
892{
893 bool ret = false;
894
895 memset(ipencap, 0, sizeof(*ipencap));
896
897 if (!data)
898 return ret;
899
900 if (data[IFLA_GRE_ENCAP_TYPE]) {
901 ret = true;
902 ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
903 }
904
905 if (data[IFLA_GRE_ENCAP_FLAGS]) {
906 ret = true;
907 ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
908 }
909
910 if (data[IFLA_GRE_ENCAP_SPORT]) {
911 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +0100912 ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -0700913 }
914
915 if (data[IFLA_GRE_ENCAP_DPORT]) {
916 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +0100917 ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -0700918 }
919
920 return ret;
921}
922
Pravin B Shelarc5441932013-03-25 14:49:35 +0000923static int gre_tap_init(struct net_device *dev)
Herbert Xue1a80002008-10-09 12:00:17 -0700924{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000925 __gre_tunnel_init(dev);
stephen hemmingerbec94d42014-12-27 10:01:42 -0800926 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Herbert Xue1a80002008-10-09 12:00:17 -0700927
Pravin B Shelarc5441932013-03-25 14:49:35 +0000928 return ip_tunnel_init(dev);
Herbert Xue1a80002008-10-09 12:00:17 -0700929}
930
Pravin B Shelarc5441932013-03-25 14:49:35 +0000931static const struct net_device_ops gre_tap_netdev_ops = {
932 .ndo_init = gre_tap_init,
933 .ndo_uninit = ip_tunnel_uninit,
934 .ndo_start_xmit = gre_tap_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800935 .ndo_set_mac_address = eth_mac_addr,
936 .ndo_validate_addr = eth_validate_addr,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000937 .ndo_change_mtu = ip_tunnel_change_mtu,
938 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200939 .ndo_get_iflink = ip_tunnel_get_iflink,
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700940 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800941};
942
Herbert Xue1a80002008-10-09 12:00:17 -0700943static void ipgre_tap_setup(struct net_device *dev)
944{
Herbert Xue1a80002008-10-09 12:00:17 -0700945 ether_setup(dev);
Jiri Bencd13b1612016-02-17 15:32:53 +0100946 dev->netdev_ops = &gre_tap_netdev_ops;
947 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
948 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000949 ip_tunnel_setup(dev, gre_tap_net_id);
Herbert Xue1a80002008-10-09 12:00:17 -0700950}
951
Pravin B Shelarc5441932013-03-25 14:49:35 +0000952static int ipgre_newlink(struct net *src_net, struct net_device *dev,
953 struct nlattr *tb[], struct nlattr *data[])
Herbert Xuc19e6542008-10-09 11:59:55 -0700954{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000955 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -0700956 struct ip_tunnel_encap ipencap;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600957 int err;
Tom Herbert4565e992014-09-17 12:26:01 -0700958
959 if (ipgre_netlink_encap_parms(data, &ipencap)) {
960 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -0600961 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -0700962
963 if (err < 0)
964 return err;
965 }
Herbert Xuc19e6542008-10-09 11:59:55 -0700966
Philip Prindeville22a59be2016-06-14 15:53:02 -0600967 err = ipgre_netlink_parms(dev, data, tb, &p);
968 if (err < 0)
969 return err;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000970 return ip_tunnel_newlink(dev, tb, &p);
Herbert Xuc19e6542008-10-09 11:59:55 -0700971}
972
973static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
974 struct nlattr *data[])
975{
Herbert Xuc19e6542008-10-09 11:59:55 -0700976 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -0700977 struct ip_tunnel_encap ipencap;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600978 int err;
Tom Herbert4565e992014-09-17 12:26:01 -0700979
980 if (ipgre_netlink_encap_parms(data, &ipencap)) {
981 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -0600982 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -0700983
984 if (err < 0)
985 return err;
986 }
Herbert Xuc19e6542008-10-09 11:59:55 -0700987
Philip Prindeville22a59be2016-06-14 15:53:02 -0600988 err = ipgre_netlink_parms(dev, data, tb, &p);
989 if (err < 0)
990 return err;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000991 return ip_tunnel_changelink(dev, tb, &p);
Herbert Xuc19e6542008-10-09 11:59:55 -0700992}
993
994static size_t ipgre_get_size(const struct net_device *dev)
995{
996 return
997 /* IFLA_GRE_LINK */
998 nla_total_size(4) +
999 /* IFLA_GRE_IFLAGS */
1000 nla_total_size(2) +
1001 /* IFLA_GRE_OFLAGS */
1002 nla_total_size(2) +
1003 /* IFLA_GRE_IKEY */
1004 nla_total_size(4) +
1005 /* IFLA_GRE_OKEY */
1006 nla_total_size(4) +
1007 /* IFLA_GRE_LOCAL */
1008 nla_total_size(4) +
1009 /* IFLA_GRE_REMOTE */
1010 nla_total_size(4) +
1011 /* IFLA_GRE_TTL */
1012 nla_total_size(1) +
1013 /* IFLA_GRE_TOS */
1014 nla_total_size(1) +
1015 /* IFLA_GRE_PMTUDISC */
1016 nla_total_size(1) +
Tom Herbert4565e992014-09-17 12:26:01 -07001017 /* IFLA_GRE_ENCAP_TYPE */
1018 nla_total_size(2) +
1019 /* IFLA_GRE_ENCAP_FLAGS */
1020 nla_total_size(2) +
1021 /* IFLA_GRE_ENCAP_SPORT */
1022 nla_total_size(2) +
1023 /* IFLA_GRE_ENCAP_DPORT */
1024 nla_total_size(2) +
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001025 /* IFLA_GRE_COLLECT_METADATA */
1026 nla_total_size(0) +
Philip Prindeville22a59be2016-06-14 15:53:02 -06001027 /* IFLA_GRE_IGNORE_DF */
1028 nla_total_size(1) +
Herbert Xuc19e6542008-10-09 11:59:55 -07001029 0;
1030}
1031
1032static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1033{
1034 struct ip_tunnel *t = netdev_priv(dev);
1035 struct ip_tunnel_parm *p = &t->parms;
1036
David S. Millerf3756b72012-04-01 20:39:02 -04001037 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
Tom Herbert95f5c642016-04-29 17:12:16 -07001038 nla_put_be16(skb, IFLA_GRE_IFLAGS,
1039 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
1040 nla_put_be16(skb, IFLA_GRE_OFLAGS,
1041 gre_tnl_flags_to_gre_flags(p->o_flags)) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001042 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1043 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
Jiri Benc930345e2015-03-29 16:59:25 +02001044 nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1045 nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001046 nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1047 nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1048 nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1049 !!(p->iph.frag_off & htons(IP_DF))))
1050 goto nla_put_failure;
Tom Herbert4565e992014-09-17 12:26:01 -07001051
1052 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
1053 t->encap.type) ||
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001054 nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
1055 t->encap.sport) ||
1056 nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
1057 t->encap.dport) ||
Tom Herbert4565e992014-09-17 12:26:01 -07001058 nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
Tom Herberte1b2cb62014-11-05 16:49:38 -08001059 t->encap.flags))
Tom Herbert4565e992014-09-17 12:26:01 -07001060 goto nla_put_failure;
1061
Philip Prindeville22a59be2016-06-14 15:53:02 -06001062 if (nla_put_u8(skb, IFLA_GRE_IGNORE_DF, t->ignore_df))
1063 goto nla_put_failure;
1064
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001065 if (t->collect_md) {
1066 if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
1067 goto nla_put_failure;
1068 }
1069
Herbert Xuc19e6542008-10-09 11:59:55 -07001070 return 0;
1071
1072nla_put_failure:
1073 return -EMSGSIZE;
1074}
1075
1076static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1077 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1078 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1079 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1080 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1081 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001082 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
1083 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
Herbert Xuc19e6542008-10-09 11:59:55 -07001084 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1085 [IFLA_GRE_TOS] = { .type = NLA_U8 },
1086 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
Tom Herbert4565e992014-09-17 12:26:01 -07001087 [IFLA_GRE_ENCAP_TYPE] = { .type = NLA_U16 },
1088 [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 },
1089 [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 },
1090 [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 },
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001091 [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG },
Philip Prindeville22a59be2016-06-14 15:53:02 -06001092 [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 },
Herbert Xuc19e6542008-10-09 11:59:55 -07001093};
1094
1095static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1096 .kind = "gre",
1097 .maxtype = IFLA_GRE_MAX,
1098 .policy = ipgre_policy,
1099 .priv_size = sizeof(struct ip_tunnel),
1100 .setup = ipgre_tunnel_setup,
1101 .validate = ipgre_tunnel_validate,
1102 .newlink = ipgre_newlink,
1103 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001104 .dellink = ip_tunnel_dellink,
Herbert Xuc19e6542008-10-09 11:59:55 -07001105 .get_size = ipgre_get_size,
1106 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001107 .get_link_net = ip_tunnel_get_link_net,
Herbert Xuc19e6542008-10-09 11:59:55 -07001108};
1109
Herbert Xue1a80002008-10-09 12:00:17 -07001110static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1111 .kind = "gretap",
1112 .maxtype = IFLA_GRE_MAX,
1113 .policy = ipgre_policy,
1114 .priv_size = sizeof(struct ip_tunnel),
1115 .setup = ipgre_tap_setup,
1116 .validate = ipgre_tap_validate,
1117 .newlink = ipgre_newlink,
1118 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001119 .dellink = ip_tunnel_dellink,
Herbert Xue1a80002008-10-09 12:00:17 -07001120 .get_size = ipgre_get_size,
1121 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001122 .get_link_net = ip_tunnel_get_link_net,
Herbert Xue1a80002008-10-09 12:00:17 -07001123};
1124
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001125struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1126 u8 name_assign_type)
1127{
1128 struct nlattr *tb[IFLA_MAX + 1];
1129 struct net_device *dev;
Nicolas Dichtel106da662016-06-13 10:31:04 +02001130 LIST_HEAD(list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001131 struct ip_tunnel *t;
1132 int err;
1133
1134 memset(&tb, 0, sizeof(tb));
1135
1136 dev = rtnl_create_link(net, name, name_assign_type,
1137 &ipgre_tap_ops, tb);
1138 if (IS_ERR(dev))
1139 return dev;
1140
1141 /* Configure flow based GRE device. */
1142 t = netdev_priv(dev);
1143 t->collect_md = true;
1144
1145 err = ipgre_newlink(net, dev, tb, NULL);
Nicolas Dichtel106da662016-06-13 10:31:04 +02001146 if (err < 0) {
1147 free_netdev(dev);
1148 return ERR_PTR(err);
1149 }
David Wragg7e059152016-02-10 00:05:58 +00001150
1151 /* openvswitch users expect packet sizes to be unrestricted,
1152 * so set the largest MTU we can.
1153 */
1154 err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
1155 if (err)
1156 goto out;
1157
Nicolas Dichtelda6f1da2016-06-13 10:31:06 +02001158 err = rtnl_configure_link(dev, NULL);
1159 if (err < 0)
1160 goto out;
1161
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001162 return dev;
1163out:
Nicolas Dichtel106da662016-06-13 10:31:04 +02001164 ip_tunnel_dellink(dev, &list_kill);
1165 unregister_netdevice_many(&list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001166 return ERR_PTR(err);
1167}
1168EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1169
Pravin B Shelarc5441932013-03-25 14:49:35 +00001170static int __net_init ipgre_tap_init_net(struct net *net)
1171{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001172 return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001173}
1174
1175static void __net_exit ipgre_tap_exit_net(struct net *net)
1176{
1177 struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001178 ip_tunnel_delete_net(itn, &ipgre_tap_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001179}
1180
1181static struct pernet_operations ipgre_tap_net_ops = {
1182 .init = ipgre_tap_init_net,
1183 .exit = ipgre_tap_exit_net,
1184 .id = &gre_tap_net_id,
1185 .size = sizeof(struct ip_tunnel_net),
1186};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
1188static int __init ipgre_init(void)
1189{
1190 int err;
1191
Joe Perches058bd4d2012-03-11 18:36:11 +00001192 pr_info("GRE over IPv4 tunneling driver\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001194 err = register_pernet_device(&ipgre_net_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001195 if (err < 0)
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001196 return err;
1197
Pravin B Shelarc5441932013-03-25 14:49:35 +00001198 err = register_pernet_device(&ipgre_tap_net_ops);
1199 if (err < 0)
1200 goto pnet_tap_faied;
1201
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001202 err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001203 if (err < 0) {
Joe Perches058bd4d2012-03-11 18:36:11 +00001204 pr_info("%s: can't add protocol\n", __func__);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001205 goto add_proto_failed;
1206 }
Pavel Emelyanov7daa0002008-04-16 01:10:05 -07001207
Herbert Xuc19e6542008-10-09 11:59:55 -07001208 err = rtnl_link_register(&ipgre_link_ops);
1209 if (err < 0)
1210 goto rtnl_link_failed;
1211
Herbert Xue1a80002008-10-09 12:00:17 -07001212 err = rtnl_link_register(&ipgre_tap_ops);
1213 if (err < 0)
1214 goto tap_ops_failed;
1215
Pravin B Shelarc5441932013-03-25 14:49:35 +00001216 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001217
Herbert Xue1a80002008-10-09 12:00:17 -07001218tap_ops_failed:
1219 rtnl_link_unregister(&ipgre_link_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001220rtnl_link_failed:
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001221 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001222add_proto_failed:
Pravin B Shelarc5441932013-03-25 14:49:35 +00001223 unregister_pernet_device(&ipgre_tap_net_ops);
1224pnet_tap_faied:
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001225 unregister_pernet_device(&ipgre_net_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001226 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227}
1228
Alexey Kuznetsovdb445752005-07-30 17:46:44 -07001229static void __exit ipgre_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230{
Herbert Xue1a80002008-10-09 12:00:17 -07001231 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001232 rtnl_link_unregister(&ipgre_link_ops);
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001233 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001234 unregister_pernet_device(&ipgre_tap_net_ops);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001235 unregister_pernet_device(&ipgre_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236}
1237
1238module_init(ipgre_init);
1239module_exit(ipgre_fini);
1240MODULE_LICENSE("GPL");
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001241MODULE_ALIAS_RTNL_LINK("gre");
1242MODULE_ALIAS_RTNL_LINK("gretap");
Vasiliy Kulikov8909c9a2011-03-02 00:33:13 +03001243MODULE_ALIAS_NETDEV("gre0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001244MODULE_ALIAS_NETDEV("gretap0");