blob: 3978f807fa8b7c8514f7727174facdb9812c9c59 [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 Torvalds7c0f6ba2016-12-24 11:46:01 -080020#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#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>
William Tu84e54fe2017-08-22 09:40:28 -070051#include <net/erspan.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Linus Torvalds1da177e2005-04-16 15:20:36 -070053/*
54 Problems & solutions
55 --------------------
56
57 1. The most important issue is detecting local dead loops.
58 They would cause complete host lockup in transmit, which
59 would be "resolved" by stack overflow or, if queueing is enabled,
60 with infinite looping in net_bh.
61
62 We cannot track such dead loops during route installation,
63 it is infeasible task. The most general solutions would be
64 to keep skb->encapsulation counter (sort of local ttl),
Eric Dumazet6d0722a2010-09-29 23:35:10 -070065 and silently drop packet when it expires. It is a good
stephen hemmingerbff52852012-02-24 08:08:20 +000066 solution, but it supposes maintaining new variable in ALL
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 skb, even if no tunneling is used.
68
Eric Dumazet6d0722a2010-09-29 23:35:10 -070069 Current solution: xmit_recursion breaks dead loops. This is a percpu
70 counter, since when we enter the first ndo_xmit(), cpu migration is
71 forbidden. We force an exit if this counter reaches RECURSION_LIMIT
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73 2. Networking dead loops would not kill routers, but would really
74 kill network. IP hop limit plays role of "t->recursion" in this case,
75 if we copy it from packet being encapsulated to upper header.
76 It is very good solution, but it introduces two problems:
77
78 - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
79 do not work over tunnels.
80 - traceroute does not work. I planned to relay ICMP from tunnel,
81 so that this problem would be solved and traceroute output
82 would even more informative. This idea appeared to be wrong:
83 only Linux complies to rfc1812 now (yes, guys, Linux is the only
84 true router now :-)), all routers (at least, in neighbourhood of mine)
85 return only 8 bytes of payload. It is the end.
86
87 Hence, if we want that OSPF worked or traceroute said something reasonable,
88 we should search for another solution.
89
90 One of them is to parse packet trying to detect inner encapsulation
91 made by our node. It is difficult or even impossible, especially,
stephen hemmingerbff52852012-02-24 08:08:20 +000092 taking into account fragmentation. TO be short, ttl is not solution at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94 Current solution: The solution was UNEXPECTEDLY SIMPLE.
95 We force DF flag on tunnels with preconfigured hop limit,
96 that is ALL. :-) Well, it does not remove the problem completely,
97 but exponential growth of network traffic is changed to linear
98 (branches, that exceed pmtu are pruned) and tunnel mtu
stephen hemmingerbff52852012-02-24 08:08:20 +000099 rapidly degrades to value <68, where looping stops.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 Yes, it is not good if there exists a router in the loop,
101 which does not force DF, even when encapsulating packets have DF set.
102 But it is not our problem! Nobody could accuse us, we made
103 all that we could make. Even if it is your gated who injected
104 fatal route to network, even if it were you who configured
105 fatal static route: you are innocent. :-)
106
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 Alexey Kuznetsov.
108 */
109
stephen hemmingereccc1bb2012-09-25 11:02:48 +0000110static bool log_ecn_error = true;
111module_param(log_ecn_error, bool, 0644);
112MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
113
Herbert Xuc19e6542008-10-09 11:59:55 -0700114static struct rtnl_link_ops ipgre_link_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115static int ipgre_tunnel_init(struct net_device *dev);
William Tu1a66a832017-08-25 09:21:28 -0700116static void erspan_build_header(struct sk_buff *skb,
William Tuc69de582018-01-25 13:20:09 -0800117 u32 id, u32 index,
William Tua3222dc2017-11-30 11:51:27 -0800118 bool truncate, bool is_ipv4);
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700119
Alexey Dobriyanc7d03a02016-11-17 04:58:21 +0300120static unsigned int ipgre_net_id __read_mostly;
121static unsigned int gre_tap_net_id __read_mostly;
William Tu84e54fe2017-08-22 09:40:28 -0700122static unsigned int erspan_net_id __read_mostly;
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700123
Stefano Brivio32bbd872018-11-08 12:19:21 +0100124static int ipgre_err(struct sk_buff *skb, u32 info,
125 const struct tnl_ptk_info *tpi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
Pravin B Shelarc5441932013-03-25 14:49:35 +0000128 /* All the routers (except for Linux) return only
129 8 bytes of packet payload. It means, that precise relaying of
130 ICMP in the real Internet is absolutely infeasible.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Pravin B Shelarc5441932013-03-25 14:49:35 +0000132 Moreover, Cisco "wise men" put GRE key to the third word
133 in GRE header. It makes impossible maintaining even soft
134 state for keyed GRE tunnels with enabled checksum. Tell
135 them "thank you".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136
Pravin B Shelarc5441932013-03-25 14:49:35 +0000137 Well, I wonder, rfc1812 was written by Cisco employee,
138 what the hell these idiots break standards established
139 by themselves???
140 */
141 struct net *net = dev_net(skb->dev);
142 struct ip_tunnel_net *itn;
Eric Dumazet96f5a842013-05-18 08:36:03 +0000143 const struct iphdr *iph;
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300144 const int type = icmp_hdr(skb)->type;
145 const int code = icmp_hdr(skb)->code;
Eric Dumazet20e19542016-06-18 21:52:06 -0700146 unsigned int data_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 struct ip_tunnel *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700149 if (tpi->proto == htons(ETH_P_TEB))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000150 itn = net_generic(net, gre_tap_net_id);
Haishuang Yan51dc63e2018-09-10 22:19:48 +0800151 else if (tpi->proto == htons(ETH_P_ERSPAN) ||
152 tpi->proto == htons(ETH_P_ERSPAN2))
153 itn = net_generic(net, erspan_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000154 else
155 itn = net_generic(net, ipgre_net_id);
156
Duan Jiongc0c0c502014-01-28 11:49:43 +0800157 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700158 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
159 iph->daddr, iph->saddr, tpi->key);
stephen hemmingerd2083282012-09-24 18:12:23 +0000160
Ian Morris51456b22015-04-03 09:17:26 +0100161 if (!t)
Stefano Brivio32bbd872018-11-08 12:19:21 +0100162 return -ENOENT;
163
164 switch (type) {
165 default:
166 case ICMP_PARAMETERPROB:
167 return 0;
168
169 case ICMP_DEST_UNREACH:
170 switch (code) {
171 case ICMP_SR_FAILED:
172 case ICMP_PORT_UNREACH:
173 /* Impossible event. */
174 return 0;
175 default:
176 /* All others are translated to HOST_UNREACH.
177 rfc2003 contains "deep thoughts" about NET_UNREACH,
178 I believe they are just ether pollution. --ANK
179 */
180 break;
181 }
182 break;
183
184 case ICMP_TIME_EXCEEDED:
185 if (code != ICMP_EXC_TTL)
186 return 0;
187 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
188 break;
189
190 case ICMP_REDIRECT:
191 break;
192 }
David S. Miller36393392012-06-14 22:21:46 -0700193
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700194#if IS_ENABLED(CONFIG_IPV6)
195 if (tpi->proto == htons(ETH_P_IPV6) &&
Eric Dumazet20e19542016-06-18 21:52:06 -0700196 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
197 type, data_len))
Stefano Brivio32bbd872018-11-08 12:19:21 +0100198 return 0;
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700199#endif
200
David S. Miller36393392012-06-14 22:21:46 -0700201 if (t->parms.iph.daddr == 0 ||
Joe Perchesf97c1e02007-12-16 13:45:43 -0800202 ipv4_is_multicast(t->parms.iph.daddr))
Stefano Brivio32bbd872018-11-08 12:19:21 +0100203 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
Stefano Brivio32bbd872018-11-08 12:19:21 +0100206 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
Wei Yongjunda6185d82009-02-24 23:34:48 -0800208 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 t->err_count++;
210 else
211 t->err_count = 1;
212 t->err_time = jiffies;
Stefano Brivio32bbd872018-11-08 12:19:21 +0100213
214 return 0;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700215}
216
217static void gre_err(struct sk_buff *skb, u32 info)
218{
219 /* All the routers (except for Linux) return only
220 * 8 bytes of packet payload. It means, that precise relaying of
221 * ICMP in the real Internet is absolutely infeasible.
222 *
223 * Moreover, Cisco "wise men" put GRE key to the third word
224 * in GRE header. It makes impossible maintaining even soft
225 * state for keyed
226 * GRE tunnels with enabled checksum. Tell them "thank you".
227 *
228 * Well, I wonder, rfc1812 was written by Cisco employee,
229 * what the hell these idiots break standards established
230 * by themselves???
231 */
232
Eric Dumazete582615ad2016-06-15 06:24:00 -0700233 const struct iphdr *iph = (struct iphdr *)skb->data;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700234 const int type = icmp_hdr(skb)->type;
235 const int code = icmp_hdr(skb)->code;
236 struct tnl_ptk_info tpi;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700237
Haishuang Yanb0350d52018-09-14 12:26:47 +0800238 if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IP),
239 iph->ihl * 4) < 0)
240 return;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700241
242 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
243 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
Maciej Żenczykowskid888f392018-09-25 20:56:26 -0700244 skb->dev->ifindex, IPPROTO_GRE);
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700245 return;
246 }
247 if (type == ICMP_REDIRECT) {
Maciej Żenczykowski1042caa2018-09-25 20:56:27 -0700248 ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex,
249 IPPROTO_GRE);
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700250 return;
251 }
252
253 ipgre_err(skb, info, &tpi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254}
255
William Tu84e54fe2017-08-22 09:40:28 -0700256static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
257 int gre_hdr_len)
258{
259 struct net *net = dev_net(skb->dev);
260 struct metadata_dst *tun_dst = NULL;
William Tu1d7e2ed2017-12-13 16:38:55 -0800261 struct erspan_base_hdr *ershdr;
262 struct erspan_metadata *pkt_md;
William Tu84e54fe2017-08-22 09:40:28 -0700263 struct ip_tunnel_net *itn;
264 struct ip_tunnel *tunnel;
William Tu84e54fe2017-08-22 09:40:28 -0700265 const struct iphdr *iph;
William Tu3df192832018-02-05 13:35:34 -0800266 struct erspan_md2 *md2;
William Tu1d7e2ed2017-12-13 16:38:55 -0800267 int ver;
William Tu84e54fe2017-08-22 09:40:28 -0700268 int len;
269
270 itn = net_generic(net, erspan_net_id);
William Tu84e54fe2017-08-22 09:40:28 -0700271
272 iph = ip_hdr(skb);
William Tu1d7e2ed2017-12-13 16:38:55 -0800273 ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
William Tuc69de582018-01-25 13:20:09 -0800274 ver = ershdr->ver;
William Tu84e54fe2017-08-22 09:40:28 -0700275
William Tu84e54fe2017-08-22 09:40:28 -0700276 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
277 tpi->flags | TUNNEL_KEY,
278 iph->saddr, iph->daddr, tpi->key);
279
280 if (tunnel) {
William Tu1d7e2ed2017-12-13 16:38:55 -0800281 len = gre_hdr_len + erspan_hdr_len(ver);
282 if (unlikely(!pskb_may_pull(skb, len)))
William Tuae3e1332017-12-15 14:27:43 -0800283 return PACKET_REJECT;
William Tu1d7e2ed2017-12-13 16:38:55 -0800284
William Tud91e8db52017-12-15 14:27:44 -0800285 ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
286 pkt_md = (struct erspan_metadata *)(ershdr + 1);
287
William Tu84e54fe2017-08-22 09:40:28 -0700288 if (__iptunnel_pull_header(skb,
William Tu1d7e2ed2017-12-13 16:38:55 -0800289 len,
William Tu84e54fe2017-08-22 09:40:28 -0700290 htons(ETH_P_TEB),
291 false, false) < 0)
292 goto drop;
293
William Tu1a66a832017-08-25 09:21:28 -0700294 if (tunnel->collect_md) {
295 struct ip_tunnel_info *info;
296 struct erspan_metadata *md;
297 __be64 tun_id;
298 __be16 flags;
299
300 tpi->flags |= TUNNEL_KEY;
301 flags = tpi->flags;
302 tun_id = key32_to_tunnel_id(tpi->key);
303
304 tun_dst = ip_tun_rx_dst(skb, flags,
305 tun_id, sizeof(*md));
306 if (!tun_dst)
307 return PACKET_REJECT;
308
309 md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
William Tuf551c912017-12-13 16:38:56 -0800310 md->version = ver;
William Tu3df192832018-02-05 13:35:34 -0800311 md2 = &md->u.md2;
312 memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
313 ERSPAN_V2_MDSIZE);
William Tuf551c912017-12-13 16:38:56 -0800314
William Tu1a66a832017-08-25 09:21:28 -0700315 info = &tun_dst->u.tun_info;
316 info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
317 info->options_len = sizeof(*md);
William Tu1a66a832017-08-25 09:21:28 -0700318 }
319
William Tu84e54fe2017-08-22 09:40:28 -0700320 skb_reset_mac_header(skb);
321 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
322 return PACKET_RCVD;
323 }
Haishuang Yan5a645062018-09-10 22:19:47 +0800324 return PACKET_REJECT;
325
William Tu84e54fe2017-08-22 09:40:28 -0700326drop:
327 kfree_skb(skb);
328 return PACKET_RCVD;
329}
330
Jiri Benc125372f2016-05-03 17:10:08 +0200331static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
332 struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700334 struct metadata_dst *tun_dst = NULL;
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000335 const struct iphdr *iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 struct ip_tunnel *tunnel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700338 iph = ip_hdr(skb);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700339 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
340 iph->saddr, iph->daddr, tpi->key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
stephen hemmingerd2083282012-09-24 18:12:23 +0000342 if (tunnel) {
Jiri Benc125372f2016-05-03 17:10:08 +0200343 if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
344 raw_proto, false) < 0)
Jiri Benc244a7972016-05-03 17:10:07 +0200345 goto drop;
346
Jiri Bence271c7b2016-05-11 15:53:57 +0200347 if (tunnel->dev->type != ARPHRD_NONE)
348 skb_pop_mac_header(skb);
349 else
350 skb_reset_mac_header(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700351 if (tunnel->collect_md) {
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700352 __be16 flags;
353 __be64 tun_id;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700354
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700355 flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
Amir Vadaid817f432016-09-08 16:23:45 +0300356 tun_id = key32_to_tunnel_id(tpi->key);
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700357 tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700358 if (!tun_dst)
359 return PACKET_REJECT;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700360 }
361
362 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700363 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 }
Jiri Benc125372f2016-05-03 17:10:08 +0200365 return PACKET_NEXT;
Jiri Benc244a7972016-05-03 17:10:07 +0200366
367drop:
368 kfree_skb(skb);
369 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370}
371
Jiri Benc125372f2016-05-03 17:10:08 +0200372static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
373 int hdr_len)
374{
375 struct net *net = dev_net(skb->dev);
376 struct ip_tunnel_net *itn;
377 int res;
378
379 if (tpi->proto == htons(ETH_P_TEB))
380 itn = net_generic(net, gre_tap_net_id);
381 else
382 itn = net_generic(net, ipgre_net_id);
383
384 res = __ipgre_rcv(skb, tpi, itn, hdr_len, false);
385 if (res == PACKET_NEXT && tpi->proto == htons(ETH_P_TEB)) {
386 /* ipgre tunnels in collect metadata mode should receive
387 * also ETH_P_TEB traffic.
388 */
389 itn = net_generic(net, ipgre_net_id);
390 res = __ipgre_rcv(skb, tpi, itn, hdr_len, true);
391 }
392 return res;
393}
394
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700395static int gre_rcv(struct sk_buff *skb)
396{
397 struct tnl_ptk_info tpi;
398 bool csum_err = false;
Tom Herbert95f5c642016-04-29 17:12:16 -0700399 int hdr_len;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700400
401#ifdef CONFIG_NET_IPGRE_BROADCAST
402 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
403 /* Looped back packet, drop it! */
404 if (rt_is_output_route(skb_rtable(skb)))
405 goto drop;
406 }
407#endif
408
Eric Dumazete582615ad2016-06-15 06:24:00 -0700409 hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0);
Jiri Bencf132ae72016-05-03 15:00:21 +0200410 if (hdr_len < 0)
Tom Herbert95f5c642016-04-29 17:12:16 -0700411 goto drop;
412
William Tuf551c912017-12-13 16:38:56 -0800413 if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) ||
414 tpi.proto == htons(ETH_P_ERSPAN2))) {
William Tu84e54fe2017-08-22 09:40:28 -0700415 if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
416 return 0;
Haishuang Yandd8d5b82017-12-20 10:21:46 +0800417 goto out;
William Tu84e54fe2017-08-22 09:40:28 -0700418 }
419
Jiri Benc244a7972016-05-03 17:10:07 +0200420 if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700421 return 0;
422
Haishuang Yandd8d5b82017-12-20 10:21:46 +0800423out:
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700424 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
425drop:
426 kfree_skb(skb);
427 return 0;
428}
429
Pravin B Shelarc5441932013-03-25 14:49:35 +0000430static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
431 const struct iphdr *tnl_params,
432 __be16 proto)
433{
434 struct ip_tunnel *tunnel = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000435
Pravin B Shelarc5441932013-03-25 14:49:35 +0000436 if (tunnel->parms.o_flags & TUNNEL_SEQ)
437 tunnel->o_seqno++;
Eric Dumazetcef401d2013-01-25 20:34:37 +0000438
Pravin B Shelarc5441932013-03-25 14:49:35 +0000439 /* Push GRE header. */
Tom Herbert182a3522016-04-29 17:12:19 -0700440 gre_build_header(skb, tunnel->tun_hlen,
441 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
442 htonl(tunnel->o_seqno));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
Nicolas Dichtelbf3d6a82013-05-27 23:48:15 +0000444 ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445}
446
Alexander Duyckaed069d2016-04-14 15:33:37 -0400447static int gre_handle_offloads(struct sk_buff *skb, bool csum)
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700448{
Edward Cree6fa79662016-02-11 21:02:31 +0000449 return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700450}
451
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700452static struct rtable *gre_get_rt(struct sk_buff *skb,
453 struct net_device *dev,
454 struct flowi4 *fl,
455 const struct ip_tunnel_key *key)
456{
457 struct net *net = dev_net(dev);
458
459 memset(fl, 0, sizeof(*fl));
460 fl->daddr = key->u.ipv4.dst;
461 fl->saddr = key->u.ipv4.src;
462 fl->flowi4_tos = RT_TOS(key->tos);
463 fl->flowi4_mark = skb->mark;
464 fl->flowi4_proto = IPPROTO_GRE;
465
466 return ip_route_output_key(net, fl);
467}
468
William Tu862a03c2017-08-25 09:21:27 -0700469static struct rtable *prepare_fb_xmit(struct sk_buff *skb,
470 struct net_device *dev,
471 struct flowi4 *fl,
472 int tunnel_hlen)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700473{
474 struct ip_tunnel_info *tun_info;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700475 const struct ip_tunnel_key *key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100476 struct rtable *rt = NULL;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700477 int min_headroom;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100478 bool use_cache;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700479 int err;
480
Jiri Benc61adedf2015-08-20 13:56:25 +0200481 tun_info = skb_tunnel_info(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700482 key = &tun_info->key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100483 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
William Tu862a03c2017-08-25 09:21:27 -0700484
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100485 if (use_cache)
William Tu862a03c2017-08-25 09:21:27 -0700486 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl->saddr);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100487 if (!rt) {
William Tu862a03c2017-08-25 09:21:27 -0700488 rt = gre_get_rt(skb, dev, fl, key);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100489 if (IS_ERR(rt))
William Tu862a03c2017-08-25 09:21:27 -0700490 goto err_free_skb;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100491 if (use_cache)
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100492 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
William Tu862a03c2017-08-25 09:21:27 -0700493 fl->saddr);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100494 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700495
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700496 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
497 + tunnel_hlen + sizeof(struct iphdr);
498 if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
499 int head_delta = SKB_DATA_ALIGN(min_headroom -
500 skb_headroom(skb) +
501 16);
502 err = pskb_expand_head(skb, max_t(int, head_delta, 0),
503 0, GFP_ATOMIC);
504 if (unlikely(err))
505 goto err_free_rt;
506 }
William Tu862a03c2017-08-25 09:21:27 -0700507 return rt;
508
509err_free_rt:
510 ip_rt_put(rt);
511err_free_skb:
512 kfree_skb(skb);
513 dev->stats.tx_dropped++;
514 return NULL;
515}
516
517static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
518 __be16 proto)
519{
William Tu77a51962018-03-01 13:49:57 -0800520 struct ip_tunnel *tunnel = netdev_priv(dev);
William Tu862a03c2017-08-25 09:21:27 -0700521 struct ip_tunnel_info *tun_info;
522 const struct ip_tunnel_key *key;
523 struct rtable *rt = NULL;
524 struct flowi4 fl;
525 int tunnel_hlen;
526 __be16 df, flags;
527
528 tun_info = skb_tunnel_info(skb);
529 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
530 ip_tunnel_info_af(tun_info) != AF_INET))
531 goto err_free_skb;
532
533 key = &tun_info->key;
534 tunnel_hlen = gre_calc_hlen(key->tun_flags);
535
536 rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen);
537 if (!rt)
538 return;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700539
540 /* Push Tunnel header. */
Alexander Duyckaed069d2016-04-14 15:33:37 -0400541 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700542 goto err_free_rt;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700543
William Tu77a51962018-03-01 13:49:57 -0800544 flags = tun_info->key.tun_flags &
545 (TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
David S. Millercba653212016-05-04 00:52:29 -0400546 gre_build_header(skb, tunnel_hlen, flags, proto,
William Tu77a51962018-03-01 13:49:57 -0800547 tunnel_id_to_key32(tun_info->key.tun_id),
Colin Ian King15746392018-03-21 19:34:58 +0000548 (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++) : 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700549
550 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
Pravin B Shelar039f5062015-12-24 14:34:54 -0800551
552 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
553 key->tos, key->ttl, df, false);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700554 return;
555
556err_free_rt:
557 ip_rt_put(rt);
558err_free_skb:
559 kfree_skb(skb);
560 dev->stats.tx_dropped++;
561}
562
Xin Long20704bd2019-01-14 18:10:06 +0800563static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
William Tu1a66a832017-08-25 09:21:28 -0700564{
565 struct ip_tunnel *tunnel = netdev_priv(dev);
566 struct ip_tunnel_info *tun_info;
567 const struct ip_tunnel_key *key;
568 struct erspan_metadata *md;
569 struct rtable *rt = NULL;
570 bool truncate = false;
Xin Long20704bd2019-01-14 18:10:06 +0800571 __be16 df, proto;
William Tu1a66a832017-08-25 09:21:28 -0700572 struct flowi4 fl;
573 int tunnel_hlen;
William Tuf551c912017-12-13 16:38:56 -0800574 int version;
William Tu1baf5eb2018-04-27 14:16:32 -0700575 int nhoff;
William Tud5db21a2018-05-11 05:49:47 -0700576 int thoff;
William Tu1a66a832017-08-25 09:21:28 -0700577
578 tun_info = skb_tunnel_info(skb);
579 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
580 ip_tunnel_info_af(tun_info) != AF_INET))
581 goto err_free_skb;
582
583 key = &tun_info->key;
Pieter Jansen van Vuuren256c87c2018-06-26 21:39:36 -0700584 if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
585 goto err_free_rt;
William Tuf551c912017-12-13 16:38:56 -0800586 md = ip_tunnel_info_opts(tun_info);
587 if (!md)
588 goto err_free_rt;
William Tu1a66a832017-08-25 09:21:28 -0700589
590 /* ERSPAN has fixed 8 byte GRE header */
William Tuf551c912017-12-13 16:38:56 -0800591 version = md->version;
592 tunnel_hlen = 8 + erspan_hdr_len(version);
William Tu1a66a832017-08-25 09:21:28 -0700593
594 rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen);
595 if (!rt)
596 return;
597
598 if (gre_handle_offloads(skb, false))
599 goto err_free_rt;
600
William Tuf1929702017-10-05 12:07:12 -0700601 if (skb->len > dev->mtu + dev->hard_header_len) {
602 pskb_trim(skb, dev->mtu + dev->hard_header_len);
William Tu1a66a832017-08-25 09:21:28 -0700603 truncate = true;
604 }
605
William Tu1baf5eb2018-04-27 14:16:32 -0700606 nhoff = skb_network_header(skb) - skb_mac_header(skb);
607 if (skb->protocol == htons(ETH_P_IP) &&
608 (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
609 truncate = true;
610
William Tud5db21a2018-05-11 05:49:47 -0700611 thoff = skb_transport_header(skb) - skb_mac_header(skb);
612 if (skb->protocol == htons(ETH_P_IPV6) &&
613 (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff))
614 truncate = true;
615
William Tuf551c912017-12-13 16:38:56 -0800616 if (version == 1) {
William Tuc69de582018-01-25 13:20:09 -0800617 erspan_build_header(skb, ntohl(tunnel_id_to_key32(key->tun_id)),
William Tuf551c912017-12-13 16:38:56 -0800618 ntohl(md->u.index), truncate, true);
Xin Long20704bd2019-01-14 18:10:06 +0800619 proto = htons(ETH_P_ERSPAN);
William Tuf551c912017-12-13 16:38:56 -0800620 } else if (version == 2) {
William Tuc69de582018-01-25 13:20:09 -0800621 erspan_build_header_v2(skb,
622 ntohl(tunnel_id_to_key32(key->tun_id)),
623 md->u.md2.dir,
624 get_hwid(&md->u.md2),
625 truncate, true);
Xin Long20704bd2019-01-14 18:10:06 +0800626 proto = htons(ETH_P_ERSPAN2);
William Tuf551c912017-12-13 16:38:56 -0800627 } else {
628 goto err_free_rt;
629 }
William Tu1a66a832017-08-25 09:21:28 -0700630
631 gre_build_header(skb, 8, TUNNEL_SEQ,
Xin Long20704bd2019-01-14 18:10:06 +0800632 proto, 0, htonl(tunnel->o_seqno++));
William Tu1a66a832017-08-25 09:21:28 -0700633
634 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
635
636 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
637 key->tos, key->ttl, df, false);
638 return;
639
640err_free_rt:
641 ip_rt_put(rt);
642err_free_skb:
643 kfree_skb(skb);
644 dev->stats.tx_dropped++;
645}
646
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700647static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
648{
649 struct ip_tunnel_info *info = skb_tunnel_info(skb);
650 struct rtable *rt;
651 struct flowi4 fl4;
652
653 if (ip_tunnel_info_af(info) != AF_INET)
654 return -EINVAL;
655
656 rt = gre_get_rt(skb, dev, &fl4, &info->key);
657 if (IS_ERR(rt))
658 return PTR_ERR(rt);
659
660 ip_rt_put(rt);
661 info->key.u.ipv4.src = fl4.saddr;
662 return 0;
663}
664
Pravin B Shelarc5441932013-03-25 14:49:35 +0000665static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
666 struct net_device *dev)
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800667{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000668 struct ip_tunnel *tunnel = netdev_priv(dev);
669 const struct iphdr *tnl_params;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800670
Willem de Bruijncb9f1b72018-12-30 17:24:36 -0500671 if (!pskb_inet_may_pull(skb))
672 goto free_skb;
673
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700674 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200675 gre_fb_xmit(skb, dev, skb->protocol);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700676 return NETDEV_TX_OK;
677 }
678
Pravin B Shelarc5441932013-03-25 14:49:35 +0000679 if (dev->header_ops) {
680 /* Need space for new headers */
681 if (skb_cow_head(skb, dev->needed_headroom -
Chen Gang2bac7cb2013-04-22 20:45:42 +0000682 (tunnel->hlen + sizeof(struct iphdr))))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000683 goto free_skb;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800684
Pravin B Shelarc5441932013-03-25 14:49:35 +0000685 tnl_params = (const struct iphdr *)skb->data;
Eric Dumazete985aad2010-09-27 03:57:11 +0000686
Pravin B Shelarc5441932013-03-25 14:49:35 +0000687 /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
688 * to gre header.
689 */
690 skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
Timo Teräs8a0033a2014-12-15 09:24:13 +0200691 skb_reset_mac_header(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000692 } else {
693 if (skb_cow_head(skb, dev->needed_headroom))
694 goto free_skb;
Herbert Xue1a80002008-10-09 12:00:17 -0700695
Pravin B Shelarc5441932013-03-25 14:49:35 +0000696 tnl_params = &tunnel->parms.iph;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800697 }
698
Alexander Duyckaed069d2016-04-14 15:33:37 -0400699 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
700 goto free_skb;
Timo Teräs8a0033a2014-12-15 09:24:13 +0200701
Pravin B Shelarc5441932013-03-25 14:49:35 +0000702 __gre_xmit(skb, dev, tnl_params, skb->protocol);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000703 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800704
Pravin B Shelarc5441932013-03-25 14:49:35 +0000705free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800706 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000707 dev->stats.tx_dropped++;
708 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800709}
710
William Tu84e54fe2017-08-22 09:40:28 -0700711static netdev_tx_t erspan_xmit(struct sk_buff *skb,
712 struct net_device *dev)
713{
714 struct ip_tunnel *tunnel = netdev_priv(dev);
715 bool truncate = false;
Xin Long20704bd2019-01-14 18:10:06 +0800716 __be16 proto;
William Tu84e54fe2017-08-22 09:40:28 -0700717
Willem de Bruijncb9f1b72018-12-30 17:24:36 -0500718 if (!pskb_inet_may_pull(skb))
719 goto free_skb;
720
William Tu1a66a832017-08-25 09:21:28 -0700721 if (tunnel->collect_md) {
Xin Long20704bd2019-01-14 18:10:06 +0800722 erspan_fb_xmit(skb, dev);
William Tu1a66a832017-08-25 09:21:28 -0700723 return NETDEV_TX_OK;
724 }
725
William Tu84e54fe2017-08-22 09:40:28 -0700726 if (gre_handle_offloads(skb, false))
727 goto free_skb;
728
729 if (skb_cow_head(skb, dev->needed_headroom))
730 goto free_skb;
731
William Tuf1929702017-10-05 12:07:12 -0700732 if (skb->len > dev->mtu + dev->hard_header_len) {
733 pskb_trim(skb, dev->mtu + dev->hard_header_len);
William Tu84e54fe2017-08-22 09:40:28 -0700734 truncate = true;
735 }
736
737 /* Push ERSPAN header */
Xin Long20704bd2019-01-14 18:10:06 +0800738 if (tunnel->erspan_ver == 1) {
William Tuc69de582018-01-25 13:20:09 -0800739 erspan_build_header(skb, ntohl(tunnel->parms.o_key),
740 tunnel->index,
William Tuf551c912017-12-13 16:38:56 -0800741 truncate, true);
Xin Long20704bd2019-01-14 18:10:06 +0800742 proto = htons(ETH_P_ERSPAN);
743 } else if (tunnel->erspan_ver == 2) {
William Tuc69de582018-01-25 13:20:09 -0800744 erspan_build_header_v2(skb, ntohl(tunnel->parms.o_key),
William Tuf551c912017-12-13 16:38:56 -0800745 tunnel->dir, tunnel->hwid,
746 truncate, true);
Xin Long20704bd2019-01-14 18:10:06 +0800747 proto = htons(ETH_P_ERSPAN2);
748 } else {
William Tu02f99df2018-05-16 17:24:32 -0700749 goto free_skb;
Xin Long20704bd2019-01-14 18:10:06 +0800750 }
William Tuf551c912017-12-13 16:38:56 -0800751
William Tu84e54fe2017-08-22 09:40:28 -0700752 tunnel->parms.o_flags &= ~TUNNEL_KEY;
Xin Long20704bd2019-01-14 18:10:06 +0800753 __gre_xmit(skb, dev, &tunnel->parms.iph, proto);
William Tu84e54fe2017-08-22 09:40:28 -0700754 return NETDEV_TX_OK;
755
756free_skb:
757 kfree_skb(skb);
758 dev->stats.tx_dropped++;
759 return NETDEV_TX_OK;
760}
761
Pravin B Shelarc5441932013-03-25 14:49:35 +0000762static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
763 struct net_device *dev)
764{
765 struct ip_tunnel *tunnel = netdev_priv(dev);
766
Willem de Bruijncb9f1b72018-12-30 17:24:36 -0500767 if (!pskb_inet_may_pull(skb))
768 goto free_skb;
769
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700770 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200771 gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700772 return NETDEV_TX_OK;
773 }
774
Alexander Duyckaed069d2016-04-14 15:33:37 -0400775 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
776 goto free_skb;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000777
778 if (skb_cow_head(skb, dev->needed_headroom))
779 goto free_skb;
780
781 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000782 return NETDEV_TX_OK;
783
784free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800785 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000786 dev->stats.tx_dropped++;
787 return NETDEV_TX_OK;
788}
789
Xin Longdd9d5982017-11-07 16:33:08 +0800790static void ipgre_link_update(struct net_device *dev, bool set_mtu)
791{
792 struct ip_tunnel *tunnel = netdev_priv(dev);
793 int len;
794
795 len = tunnel->tun_hlen;
796 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
797 len = tunnel->tun_hlen - len;
798 tunnel->hlen = tunnel->hlen + len;
799
800 dev->needed_headroom = dev->needed_headroom + len;
801 if (set_mtu)
802 dev->mtu = max_t(int, dev->mtu - len, 68);
803
804 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
805 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
806 tunnel->encap.type == TUNNEL_ENCAP_NONE) {
807 dev->features |= NETIF_F_GSO_SOFTWARE;
808 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
Sabrina Dubroca1cc59542018-04-10 12:57:18 +0200809 } else {
810 dev->features &= ~NETIF_F_GSO_SOFTWARE;
811 dev->hw_features &= ~NETIF_F_GSO_SOFTWARE;
Xin Longdd9d5982017-11-07 16:33:08 +0800812 }
813 dev->features |= NETIF_F_LLTX;
Sabrina Dubroca1cc59542018-04-10 12:57:18 +0200814 } else {
815 dev->hw_features &= ~NETIF_F_GSO_SOFTWARE;
816 dev->features &= ~(NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE);
Xin Longdd9d5982017-11-07 16:33:08 +0800817 }
818}
819
Pravin B Shelarc5441932013-03-25 14:49:35 +0000820static int ipgre_tunnel_ioctl(struct net_device *dev,
821 struct ifreq *ifr, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 struct ip_tunnel_parm p;
Xin Longa0efab62017-11-07 16:33:09 +0800824 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Pravin B Shelarc5441932013-03-25 14:49:35 +0000826 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
827 return -EFAULT;
Xin Longa0efab62017-11-07 16:33:09 +0800828
Cong Wang6c734fb2013-06-29 12:02:59 +0800829 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
830 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
Xin Longa0efab62017-11-07 16:33:09 +0800831 p.iph.ihl != 5 || (p.iph.frag_off & htons(~IP_DF)) ||
832 ((p.i_flags | p.o_flags) & (GRE_VERSION | GRE_ROUTING)))
Cong Wang6c734fb2013-06-29 12:02:59 +0800833 return -EINVAL;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000834 }
Xin Longa0efab62017-11-07 16:33:09 +0800835
Pravin B Shelarc5441932013-03-25 14:49:35 +0000836 p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
837 p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
838
839 err = ip_tunnel_ioctl(dev, &p, cmd);
840 if (err)
841 return err;
842
Xin Longa0efab62017-11-07 16:33:09 +0800843 if (cmd == SIOCCHGTUNNEL) {
844 struct ip_tunnel *t = netdev_priv(dev);
845
846 t->parms.i_flags = p.i_flags;
847 t->parms.o_flags = p.o_flags;
848
849 if (strcmp(dev->rtnl_link_ops->kind, "erspan"))
850 ipgre_link_update(dev, true);
851 }
852
Tom Herbert95f5c642016-04-29 17:12:16 -0700853 p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
854 p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000855
856 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
857 return -EFAULT;
Xin Longa0efab62017-11-07 16:33:09 +0800858
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 return 0;
860}
861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862/* Nice toy. Unfortunately, useless in real life :-)
863 It allows to construct virtual multiprotocol broadcast "LAN"
864 over the Internet, provided multicast routing is tuned.
865
866
867 I have no idea was this bicycle invented before me,
868 so that I had to set ARPHRD_IPGRE to a random value.
869 I have an impression, that Cisco could make something similar,
870 but this feature is apparently missing in IOS<=11.2(8).
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
873 with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
874
875 ping -t 255 224.66.66.66
876
877 If nobody answers, mbone does not work.
878
879 ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
880 ip addr add 10.66.66.<somewhat>/24 dev Universe
881 ifconfig Universe up
882 ifconfig Universe add fe80::<Your_real_addr>/10
883 ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
884 ftp 10.66.66.66
885 ...
886 ftp fec0:6666:6666::193.233.7.65
887 ...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700889static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
890 unsigned short type,
Eric Dumazet15078502010-09-15 11:07:53 +0000891 const void *daddr, const void *saddr, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892{
Patrick McHardy2941a482006-01-08 22:05:26 -0800893 struct ip_tunnel *t = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000894 struct iphdr *iph;
895 struct gre_base_hdr *greh;
896
Johannes Bergd58ff352017-06-16 14:29:23 +0200897 iph = skb_push(skb, t->hlen + sizeof(*iph));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000898 greh = (struct gre_base_hdr *)(iph+1);
Tom Herbert95f5c642016-04-29 17:12:16 -0700899 greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000900 greh->protocol = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902 memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
Pravin B Shelarc5441932013-03-25 14:49:35 +0000904 /* Set the source hardware address. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 if (saddr)
906 memcpy(&iph->saddr, saddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000907 if (daddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 memcpy(&iph->daddr, daddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000909 if (iph->daddr)
Timo Teräs77a482b2013-08-06 13:45:43 +0300910 return t->hlen + sizeof(*iph);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900911
Pravin B Shelarc5441932013-03-25 14:49:35 +0000912 return -(t->hlen + sizeof(*iph));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913}
914
Timo Teras6a5f44d2007-10-23 20:31:53 -0700915static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
916{
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000917 const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
Timo Teras6a5f44d2007-10-23 20:31:53 -0700918 memcpy(haddr, &iph->saddr, 4);
919 return 4;
920}
921
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700922static const struct header_ops ipgre_header_ops = {
923 .create = ipgre_header,
Timo Teras6a5f44d2007-10-23 20:31:53 -0700924 .parse = ipgre_header_parse,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700925};
926
Timo Teras6a5f44d2007-10-23 20:31:53 -0700927#ifdef CONFIG_NET_IPGRE_BROADCAST
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928static int ipgre_open(struct net_device *dev)
929{
Patrick McHardy2941a482006-01-08 22:05:26 -0800930 struct ip_tunnel *t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Joe Perchesf97c1e02007-12-16 13:45:43 -0800932 if (ipv4_is_multicast(t->parms.iph.daddr)) {
David S. Millercbb1e852011-05-04 12:33:34 -0700933 struct flowi4 fl4;
934 struct rtable *rt;
Eric Dumazete985aad2010-09-27 03:57:11 +0000935
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200936 rt = ip_route_output_gre(t->net, &fl4,
David S. Millercbb1e852011-05-04 12:33:34 -0700937 t->parms.iph.daddr,
938 t->parms.iph.saddr,
939 t->parms.o_key,
940 RT_TOS(t->parms.iph.tos),
941 t->parms.link);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800942 if (IS_ERR(rt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 return -EADDRNOTAVAIL;
Changli Gaod8d1f302010-06-10 23:31:35 -0700944 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 ip_rt_put(rt);
Ian Morris51456b22015-04-03 09:17:26 +0100946 if (!__in_dev_get_rtnl(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 return -EADDRNOTAVAIL;
948 t->mlink = dev->ifindex;
Herbert Xue5ed6392005-10-03 14:35:55 -0700949 ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 }
951 return 0;
952}
953
954static int ipgre_close(struct net_device *dev)
955{
Patrick McHardy2941a482006-01-08 22:05:26 -0800956 struct ip_tunnel *t = netdev_priv(dev);
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800957
Joe Perchesf97c1e02007-12-16 13:45:43 -0800958 if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
Denis V. Lunev7fee0ca2008-01-21 17:32:38 -0800959 struct in_device *in_dev;
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200960 in_dev = inetdev_by_index(t->net, t->mlink);
Eric Dumazet8723e1b2010-10-19 00:39:26 +0000961 if (in_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 ip_mc_dec_group(in_dev, t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 }
964 return 0;
965}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966#endif
967
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800968static const struct net_device_ops ipgre_netdev_ops = {
969 .ndo_init = ipgre_tunnel_init,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000970 .ndo_uninit = ip_tunnel_uninit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800971#ifdef CONFIG_NET_IPGRE_BROADCAST
972 .ndo_open = ipgre_open,
973 .ndo_stop = ipgre_close,
974#endif
Pravin B Shelarc5441932013-03-25 14:49:35 +0000975 .ndo_start_xmit = ipgre_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800976 .ndo_do_ioctl = ipgre_tunnel_ioctl,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000977 .ndo_change_mtu = ip_tunnel_change_mtu,
978 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200979 .ndo_get_iflink = ip_tunnel_get_iflink,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800980};
981
Eric Dumazet6b78f162012-09-13 21:25:33 +0000982#define GRE_FEATURES (NETIF_F_SG | \
983 NETIF_F_FRAGLIST | \
984 NETIF_F_HIGHDMA | \
985 NETIF_F_HW_CSUM)
986
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987static void ipgre_tunnel_setup(struct net_device *dev)
988{
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800989 dev->netdev_ops = &ipgre_netdev_ops;
Nicolas Dichtel5a455272014-04-11 15:51:18 +0200990 dev->type = ARPHRD_IPGRE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000991 ip_tunnel_setup(dev, ipgre_net_id);
992}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Pravin B Shelarc5441932013-03-25 14:49:35 +0000994static void __gre_tunnel_init(struct net_device *dev)
995{
996 struct ip_tunnel *tunnel;
997
998 tunnel = netdev_priv(dev);
Tom Herbert95f5c642016-04-29 17:12:16 -0700999 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001000 tunnel->parms.iph.protocol = IPPROTO_GRE;
1001
Tom Herbert4565e992014-09-17 12:26:01 -07001002 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
1003
Nicolas Dichtelb57708a2014-04-22 10:15:23 +02001004 dev->features |= GRE_FEATURES;
Eric Dumazet6b78f162012-09-13 21:25:33 +00001005 dev->hw_features |= GRE_FEATURES;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001006
1007 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
Alexander Duycka0ca1532016-04-05 09:13:39 -07001008 /* TCP offload with GRE SEQ is not supported, nor
1009 * can we support 2 levels of outer headers requiring
1010 * an update.
1011 */
1012 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
1013 (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
1014 dev->features |= NETIF_F_GSO_SOFTWARE;
1015 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
1016 }
1017
Pravin B Shelarc5441932013-03-25 14:49:35 +00001018 /* Can use a lockless transmit, unless we generate
1019 * output sequences
1020 */
1021 dev->features |= NETIF_F_LLTX;
1022 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023}
1024
1025static int ipgre_tunnel_init(struct net_device *dev)
1026{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001027 struct ip_tunnel *tunnel = netdev_priv(dev);
1028 struct iphdr *iph = &tunnel->parms.iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Pravin B Shelarc5441932013-03-25 14:49:35 +00001030 __gre_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
Pravin B Shelarc5441932013-03-25 14:49:35 +00001032 memcpy(dev->dev_addr, &iph->saddr, 4);
1033 memcpy(dev->broadcast, &iph->daddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034
Pravin B Shelarc5441932013-03-25 14:49:35 +00001035 dev->flags = IFF_NOARP;
Eric Dumazet02875872014-10-05 18:38:35 -07001036 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001037 dev->addr_len = 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
Jiri Benca64b04d2016-04-27 11:29:06 +02001039 if (iph->daddr && !tunnel->collect_md) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040#ifdef CONFIG_NET_IPGRE_BROADCAST
Joe Perchesf97c1e02007-12-16 13:45:43 -08001041 if (ipv4_is_multicast(iph->daddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 if (!iph->saddr)
1043 return -EINVAL;
1044 dev->flags = IFF_BROADCAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001045 dev->header_ops = &ipgre_header_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 }
1047#endif
Jiri Benca64b04d2016-04-27 11:29:06 +02001048 } else if (!tunnel->collect_md) {
Timo Teras6a5f44d2007-10-23 20:31:53 -07001049 dev->header_ops = &ipgre_header_ops;
Jiri Benca64b04d2016-04-27 11:29:06 +02001050 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
Pravin B Shelarc5441932013-03-25 14:49:35 +00001052 return ip_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053}
1054
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001055static const struct gre_protocol ipgre_protocol = {
1056 .handler = gre_rcv,
1057 .err_handler = gre_err,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058};
1059
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00001060static int __net_init ipgre_init_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001061{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001062 return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001063}
1064
Eric Dumazet64bc1782017-09-19 16:27:09 -07001065static void __net_exit ipgre_exit_batch_net(struct list_head *list_net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001066{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001067 ip_tunnel_delete_nets(list_net, ipgre_net_id, &ipgre_link_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001068}
1069
1070static struct pernet_operations ipgre_net_ops = {
1071 .init = ipgre_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001072 .exit_batch = ipgre_exit_batch_net,
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001073 .id = &ipgre_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001074 .size = sizeof(struct ip_tunnel_net),
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001075};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001077static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
1078 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001079{
1080 __be16 flags;
1081
1082 if (!data)
1083 return 0;
1084
1085 flags = 0;
1086 if (data[IFLA_GRE_IFLAGS])
1087 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1088 if (data[IFLA_GRE_OFLAGS])
1089 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1090 if (flags & (GRE_VERSION|GRE_ROUTING))
1091 return -EINVAL;
1092
Jiri Benc946b6362016-04-27 14:08:01 +02001093 if (data[IFLA_GRE_COLLECT_METADATA] &&
1094 data[IFLA_GRE_ENCAP_TYPE] &&
1095 nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
1096 return -EINVAL;
1097
Herbert Xuc19e6542008-10-09 11:59:55 -07001098 return 0;
1099}
1100
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001101static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
1102 struct netlink_ext_ack *extack)
Herbert Xue1a80002008-10-09 12:00:17 -07001103{
1104 __be32 daddr;
1105
1106 if (tb[IFLA_ADDRESS]) {
1107 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
1108 return -EINVAL;
1109 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
1110 return -EADDRNOTAVAIL;
1111 }
1112
1113 if (!data)
1114 goto out;
1115
1116 if (data[IFLA_GRE_REMOTE]) {
1117 memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
1118 if (!daddr)
1119 return -EINVAL;
1120 }
1121
1122out:
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001123 return ipgre_tunnel_validate(tb, data, extack);
Herbert Xue1a80002008-10-09 12:00:17 -07001124}
1125
William Tu84e54fe2017-08-22 09:40:28 -07001126static int erspan_validate(struct nlattr *tb[], struct nlattr *data[],
1127 struct netlink_ext_ack *extack)
1128{
1129 __be16 flags = 0;
1130 int ret;
1131
1132 if (!data)
1133 return 0;
1134
1135 ret = ipgre_tap_validate(tb, data, extack);
1136 if (ret)
1137 return ret;
1138
1139 /* ERSPAN should only have GRE sequence and key flag */
William Tu1a66a832017-08-25 09:21:28 -07001140 if (data[IFLA_GRE_OFLAGS])
1141 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1142 if (data[IFLA_GRE_IFLAGS])
1143 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1144 if (!data[IFLA_GRE_COLLECT_METADATA] &&
1145 flags != (GRE_SEQ | GRE_KEY))
William Tu84e54fe2017-08-22 09:40:28 -07001146 return -EINVAL;
1147
1148 /* ERSPAN Session ID only has 10-bit. Since we reuse
1149 * 32-bit key field as ID, check it's range.
1150 */
1151 if (data[IFLA_GRE_IKEY] &&
1152 (ntohl(nla_get_be32(data[IFLA_GRE_IKEY])) & ~ID_MASK))
1153 return -EINVAL;
1154
1155 if (data[IFLA_GRE_OKEY] &&
1156 (ntohl(nla_get_be32(data[IFLA_GRE_OKEY])) & ~ID_MASK))
1157 return -EINVAL;
1158
1159 return 0;
1160}
1161
Philip Prindeville22a59be2016-06-14 15:53:02 -06001162static int ipgre_netlink_parms(struct net_device *dev,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001163 struct nlattr *data[],
1164 struct nlattr *tb[],
Craig Gallek9830ad42017-04-19 12:30:54 -04001165 struct ip_tunnel_parm *parms,
1166 __u32 *fwmark)
Herbert Xuc19e6542008-10-09 11:59:55 -07001167{
Philip Prindeville22a59be2016-06-14 15:53:02 -06001168 struct ip_tunnel *t = netdev_priv(dev);
1169
Herbert Xu7bb82d92008-10-11 12:20:15 -07001170 memset(parms, 0, sizeof(*parms));
Herbert Xuc19e6542008-10-09 11:59:55 -07001171
1172 parms->iph.protocol = IPPROTO_GRE;
1173
1174 if (!data)
Philip Prindeville22a59be2016-06-14 15:53:02 -06001175 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001176
1177 if (data[IFLA_GRE_LINK])
1178 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
1179
1180 if (data[IFLA_GRE_IFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +00001181 parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -07001182
1183 if (data[IFLA_GRE_OFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +00001184 parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -07001185
1186 if (data[IFLA_GRE_IKEY])
1187 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
1188
1189 if (data[IFLA_GRE_OKEY])
1190 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
1191
1192 if (data[IFLA_GRE_LOCAL])
Jiri Benc67b61f62015-03-29 16:59:26 +02001193 parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
Herbert Xuc19e6542008-10-09 11:59:55 -07001194
1195 if (data[IFLA_GRE_REMOTE])
Jiri Benc67b61f62015-03-29 16:59:26 +02001196 parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
Herbert Xuc19e6542008-10-09 11:59:55 -07001197
1198 if (data[IFLA_GRE_TTL])
1199 parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
1200
1201 if (data[IFLA_GRE_TOS])
1202 parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
1203
Philip Prindeville22a59be2016-06-14 15:53:02 -06001204 if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) {
1205 if (t->ignore_df)
1206 return -EINVAL;
Herbert Xuc19e6542008-10-09 11:59:55 -07001207 parms->iph.frag_off = htons(IP_DF);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001208 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001209
1210 if (data[IFLA_GRE_COLLECT_METADATA]) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001211 t->collect_md = true;
Jiri Bence271c7b2016-05-11 15:53:57 +02001212 if (dev->type == ARPHRD_IPGRE)
1213 dev->type = ARPHRD_NONE;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001214 }
Philip Prindeville22a59be2016-06-14 15:53:02 -06001215
1216 if (data[IFLA_GRE_IGNORE_DF]) {
1217 if (nla_get_u8(data[IFLA_GRE_IGNORE_DF])
1218 && (parms->iph.frag_off & htons(IP_DF)))
1219 return -EINVAL;
1220 t->ignore_df = !!nla_get_u8(data[IFLA_GRE_IGNORE_DF]);
1221 }
1222
Craig Gallek9830ad42017-04-19 12:30:54 -04001223 if (data[IFLA_GRE_FWMARK])
1224 *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]);
1225
William Tuf551c912017-12-13 16:38:56 -08001226 if (data[IFLA_GRE_ERSPAN_VER]) {
1227 t->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
William Tu84e54fe2017-08-22 09:40:28 -07001228
William Tuf551c912017-12-13 16:38:56 -08001229 if (t->erspan_ver != 1 && t->erspan_ver != 2)
William Tu84e54fe2017-08-22 09:40:28 -07001230 return -EINVAL;
1231 }
1232
William Tuf551c912017-12-13 16:38:56 -08001233 if (t->erspan_ver == 1) {
1234 if (data[IFLA_GRE_ERSPAN_INDEX]) {
1235 t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]);
1236 if (t->index & ~INDEX_MASK)
1237 return -EINVAL;
1238 }
1239 } else if (t->erspan_ver == 2) {
1240 if (data[IFLA_GRE_ERSPAN_DIR]) {
1241 t->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]);
1242 if (t->dir & ~(DIR_MASK >> DIR_OFFSET))
1243 return -EINVAL;
1244 }
1245 if (data[IFLA_GRE_ERSPAN_HWID]) {
1246 t->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]);
1247 if (t->hwid & ~(HWID_MASK >> HWID_OFFSET))
1248 return -EINVAL;
1249 }
1250 }
1251
Philip Prindeville22a59be2016-06-14 15:53:02 -06001252 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001253}
1254
Tom Herbert4565e992014-09-17 12:26:01 -07001255/* This function returns true when ENCAP attributes are present in the nl msg */
1256static bool ipgre_netlink_encap_parms(struct nlattr *data[],
1257 struct ip_tunnel_encap *ipencap)
1258{
1259 bool ret = false;
1260
1261 memset(ipencap, 0, sizeof(*ipencap));
1262
1263 if (!data)
1264 return ret;
1265
1266 if (data[IFLA_GRE_ENCAP_TYPE]) {
1267 ret = true;
1268 ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
1269 }
1270
1271 if (data[IFLA_GRE_ENCAP_FLAGS]) {
1272 ret = true;
1273 ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
1274 }
1275
1276 if (data[IFLA_GRE_ENCAP_SPORT]) {
1277 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001278 ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -07001279 }
1280
1281 if (data[IFLA_GRE_ENCAP_DPORT]) {
1282 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001283 ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -07001284 }
1285
1286 return ret;
1287}
1288
Pravin B Shelarc5441932013-03-25 14:49:35 +00001289static int gre_tap_init(struct net_device *dev)
Herbert Xue1a80002008-10-09 12:00:17 -07001290{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001291 __gre_tunnel_init(dev);
stephen hemmingerbec94d4302014-12-27 10:01:42 -08001292 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Xin Longd51711c2017-09-28 13:23:31 +08001293 netif_keep_dst(dev);
Herbert Xue1a80002008-10-09 12:00:17 -07001294
Pravin B Shelarc5441932013-03-25 14:49:35 +00001295 return ip_tunnel_init(dev);
Herbert Xue1a80002008-10-09 12:00:17 -07001296}
1297
Pravin B Shelarc5441932013-03-25 14:49:35 +00001298static const struct net_device_ops gre_tap_netdev_ops = {
1299 .ndo_init = gre_tap_init,
1300 .ndo_uninit = ip_tunnel_uninit,
1301 .ndo_start_xmit = gre_tap_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -08001302 .ndo_set_mac_address = eth_mac_addr,
1303 .ndo_validate_addr = eth_validate_addr,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001304 .ndo_change_mtu = ip_tunnel_change_mtu,
1305 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +02001306 .ndo_get_iflink = ip_tunnel_get_iflink,
Pravin B Shelarfc4099f2015-10-22 18:17:16 -07001307 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -08001308};
1309
William Tu84e54fe2017-08-22 09:40:28 -07001310static int erspan_tunnel_init(struct net_device *dev)
1311{
1312 struct ip_tunnel *tunnel = netdev_priv(dev);
William Tu84e54fe2017-08-22 09:40:28 -07001313
1314 tunnel->tun_hlen = 8;
1315 tunnel->parms.iph.protocol = IPPROTO_GRE;
Xin Longc122fda2017-10-01 22:00:55 +08001316 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen +
William Tuf551c912017-12-13 16:38:56 -08001317 erspan_hdr_len(tunnel->erspan_ver);
William Tu84e54fe2017-08-22 09:40:28 -07001318
William Tu84e54fe2017-08-22 09:40:28 -07001319 dev->features |= GRE_FEATURES;
1320 dev->hw_features |= GRE_FEATURES;
1321 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Xin Longc84bed42017-10-01 22:00:56 +08001322 netif_keep_dst(dev);
William Tu84e54fe2017-08-22 09:40:28 -07001323
1324 return ip_tunnel_init(dev);
1325}
1326
1327static const struct net_device_ops erspan_netdev_ops = {
1328 .ndo_init = erspan_tunnel_init,
1329 .ndo_uninit = ip_tunnel_uninit,
1330 .ndo_start_xmit = erspan_xmit,
1331 .ndo_set_mac_address = eth_mac_addr,
1332 .ndo_validate_addr = eth_validate_addr,
1333 .ndo_change_mtu = ip_tunnel_change_mtu,
1334 .ndo_get_stats64 = ip_tunnel_get_stats64,
1335 .ndo_get_iflink = ip_tunnel_get_iflink,
1336 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
1337};
1338
Herbert Xue1a80002008-10-09 12:00:17 -07001339static void ipgre_tap_setup(struct net_device *dev)
1340{
Herbert Xue1a80002008-10-09 12:00:17 -07001341 ether_setup(dev);
Xin Longcfddd4c2017-12-18 14:24:35 +08001342 dev->max_mtu = 0;
Jiri Bencd13b1612016-02-17 15:32:53 +01001343 dev->netdev_ops = &gre_tap_netdev_ops;
1344 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1345 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001346 ip_tunnel_setup(dev, gre_tap_net_id);
Herbert Xue1a80002008-10-09 12:00:17 -07001347}
1348
Pravin B Shelarc5441932013-03-25 14:49:35 +00001349static int ipgre_newlink(struct net *src_net, struct net_device *dev,
Matthias Schiffer7a3f4a12017-06-25 23:55:59 +02001350 struct nlattr *tb[], struct nlattr *data[],
1351 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001352{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001353 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -07001354 struct ip_tunnel_encap ipencap;
Craig Gallek9830ad42017-04-19 12:30:54 -04001355 __u32 fwmark = 0;
Philip Prindeville22a59be2016-06-14 15:53:02 -06001356 int err;
Tom Herbert4565e992014-09-17 12:26:01 -07001357
1358 if (ipgre_netlink_encap_parms(data, &ipencap)) {
1359 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001360 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -07001361
1362 if (err < 0)
1363 return err;
1364 }
Herbert Xuc19e6542008-10-09 11:59:55 -07001365
Craig Gallek9830ad42017-04-19 12:30:54 -04001366 err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001367 if (err < 0)
1368 return err;
Craig Gallek9830ad42017-04-19 12:30:54 -04001369 return ip_tunnel_newlink(dev, tb, &p, fwmark);
Herbert Xuc19e6542008-10-09 11:59:55 -07001370}
1371
1372static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
Matthias Schifferad744b22017-06-25 23:56:00 +02001373 struct nlattr *data[],
1374 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001375{
Craig Gallek9830ad42017-04-19 12:30:54 -04001376 struct ip_tunnel *t = netdev_priv(dev);
Tom Herbert4565e992014-09-17 12:26:01 -07001377 struct ip_tunnel_encap ipencap;
Craig Gallek9830ad42017-04-19 12:30:54 -04001378 __u32 fwmark = t->fwmark;
Xin Longdd9d5982017-11-07 16:33:08 +08001379 struct ip_tunnel_parm p;
Philip Prindeville22a59be2016-06-14 15:53:02 -06001380 int err;
Tom Herbert4565e992014-09-17 12:26:01 -07001381
1382 if (ipgre_netlink_encap_parms(data, &ipencap)) {
Philip Prindeville22a59be2016-06-14 15:53:02 -06001383 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -07001384
1385 if (err < 0)
1386 return err;
1387 }
Herbert Xuc19e6542008-10-09 11:59:55 -07001388
Craig Gallek9830ad42017-04-19 12:30:54 -04001389 err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001390 if (err < 0)
1391 return err;
Xin Longdd9d5982017-11-07 16:33:08 +08001392
1393 err = ip_tunnel_changelink(dev, tb, &p, fwmark);
1394 if (err < 0)
1395 return err;
1396
1397 t->parms.i_flags = p.i_flags;
1398 t->parms.o_flags = p.o_flags;
1399
1400 if (strcmp(dev->rtnl_link_ops->kind, "erspan"))
1401 ipgre_link_update(dev, !tb[IFLA_MTU]);
1402
1403 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001404}
1405
1406static size_t ipgre_get_size(const struct net_device *dev)
1407{
1408 return
1409 /* IFLA_GRE_LINK */
1410 nla_total_size(4) +
1411 /* IFLA_GRE_IFLAGS */
1412 nla_total_size(2) +
1413 /* IFLA_GRE_OFLAGS */
1414 nla_total_size(2) +
1415 /* IFLA_GRE_IKEY */
1416 nla_total_size(4) +
1417 /* IFLA_GRE_OKEY */
1418 nla_total_size(4) +
1419 /* IFLA_GRE_LOCAL */
1420 nla_total_size(4) +
1421 /* IFLA_GRE_REMOTE */
1422 nla_total_size(4) +
1423 /* IFLA_GRE_TTL */
1424 nla_total_size(1) +
1425 /* IFLA_GRE_TOS */
1426 nla_total_size(1) +
1427 /* IFLA_GRE_PMTUDISC */
1428 nla_total_size(1) +
Tom Herbert4565e992014-09-17 12:26:01 -07001429 /* IFLA_GRE_ENCAP_TYPE */
1430 nla_total_size(2) +
1431 /* IFLA_GRE_ENCAP_FLAGS */
1432 nla_total_size(2) +
1433 /* IFLA_GRE_ENCAP_SPORT */
1434 nla_total_size(2) +
1435 /* IFLA_GRE_ENCAP_DPORT */
1436 nla_total_size(2) +
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001437 /* IFLA_GRE_COLLECT_METADATA */
1438 nla_total_size(0) +
Philip Prindeville22a59be2016-06-14 15:53:02 -06001439 /* IFLA_GRE_IGNORE_DF */
1440 nla_total_size(1) +
Craig Gallek9830ad42017-04-19 12:30:54 -04001441 /* IFLA_GRE_FWMARK */
1442 nla_total_size(4) +
William Tu84e54fe2017-08-22 09:40:28 -07001443 /* IFLA_GRE_ERSPAN_INDEX */
1444 nla_total_size(4) +
William Tuf551c912017-12-13 16:38:56 -08001445 /* IFLA_GRE_ERSPAN_VER */
1446 nla_total_size(1) +
1447 /* IFLA_GRE_ERSPAN_DIR */
1448 nla_total_size(1) +
1449 /* IFLA_GRE_ERSPAN_HWID */
1450 nla_total_size(2) +
Herbert Xuc19e6542008-10-09 11:59:55 -07001451 0;
1452}
1453
1454static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1455{
1456 struct ip_tunnel *t = netdev_priv(dev);
1457 struct ip_tunnel_parm *p = &t->parms;
Lorenzo Bianconifeaf5c72019-01-28 22:23:48 +01001458 __be16 o_flags = p->o_flags;
1459
1460 if ((t->erspan_ver == 1 || t->erspan_ver == 2) &&
1461 !t->collect_md)
1462 o_flags |= TUNNEL_KEY;
Herbert Xuc19e6542008-10-09 11:59:55 -07001463
David S. Millerf3756b72012-04-01 20:39:02 -04001464 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
Tom Herbert95f5c642016-04-29 17:12:16 -07001465 nla_put_be16(skb, IFLA_GRE_IFLAGS,
1466 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
1467 nla_put_be16(skb, IFLA_GRE_OFLAGS,
Lorenzo Bianconifeaf5c72019-01-28 22:23:48 +01001468 gre_tnl_flags_to_gre_flags(o_flags)) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001469 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1470 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
Jiri Benc930345e2015-03-29 16:59:25 +02001471 nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1472 nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001473 nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1474 nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1475 nla_put_u8(skb, IFLA_GRE_PMTUDISC,
Craig Gallek9830ad42017-04-19 12:30:54 -04001476 !!(p->iph.frag_off & htons(IP_DF))) ||
1477 nla_put_u32(skb, IFLA_GRE_FWMARK, t->fwmark))
David S. Millerf3756b72012-04-01 20:39:02 -04001478 goto nla_put_failure;
Tom Herbert4565e992014-09-17 12:26:01 -07001479
1480 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
1481 t->encap.type) ||
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001482 nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
1483 t->encap.sport) ||
1484 nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
1485 t->encap.dport) ||
Tom Herbert4565e992014-09-17 12:26:01 -07001486 nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
Tom Herberte1b2cb62014-11-05 16:49:38 -08001487 t->encap.flags))
Tom Herbert4565e992014-09-17 12:26:01 -07001488 goto nla_put_failure;
1489
Philip Prindeville22a59be2016-06-14 15:53:02 -06001490 if (nla_put_u8(skb, IFLA_GRE_IGNORE_DF, t->ignore_df))
1491 goto nla_put_failure;
1492
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001493 if (t->collect_md) {
1494 if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
1495 goto nla_put_failure;
1496 }
1497
William Tuf551c912017-12-13 16:38:56 -08001498 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
1499 goto nla_put_failure;
1500
1501 if (t->erspan_ver == 1) {
William Tu84e54fe2017-08-22 09:40:28 -07001502 if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
1503 goto nla_put_failure;
William Tuf551c912017-12-13 16:38:56 -08001504 } else if (t->erspan_ver == 2) {
1505 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
1506 goto nla_put_failure;
1507 if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
1508 goto nla_put_failure;
1509 }
William Tu84e54fe2017-08-22 09:40:28 -07001510
Herbert Xuc19e6542008-10-09 11:59:55 -07001511 return 0;
1512
1513nla_put_failure:
1514 return -EMSGSIZE;
1515}
1516
William Tu84e54fe2017-08-22 09:40:28 -07001517static void erspan_setup(struct net_device *dev)
1518{
Xin Long84581bd2018-08-27 18:41:32 +08001519 struct ip_tunnel *t = netdev_priv(dev);
1520
William Tu84e54fe2017-08-22 09:40:28 -07001521 ether_setup(dev);
1522 dev->netdev_ops = &erspan_netdev_ops;
1523 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1524 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1525 ip_tunnel_setup(dev, erspan_net_id);
Xin Long84581bd2018-08-27 18:41:32 +08001526 t->erspan_ver = 1;
William Tu84e54fe2017-08-22 09:40:28 -07001527}
1528
Herbert Xuc19e6542008-10-09 11:59:55 -07001529static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1530 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1531 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1532 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1533 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1534 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001535 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
1536 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
Herbert Xuc19e6542008-10-09 11:59:55 -07001537 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1538 [IFLA_GRE_TOS] = { .type = NLA_U8 },
1539 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
Tom Herbert4565e992014-09-17 12:26:01 -07001540 [IFLA_GRE_ENCAP_TYPE] = { .type = NLA_U16 },
1541 [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 },
1542 [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 },
1543 [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 },
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001544 [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG },
Philip Prindeville22a59be2016-06-14 15:53:02 -06001545 [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 },
Craig Gallek9830ad42017-04-19 12:30:54 -04001546 [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
William Tu84e54fe2017-08-22 09:40:28 -07001547 [IFLA_GRE_ERSPAN_INDEX] = { .type = NLA_U32 },
William Tuf551c912017-12-13 16:38:56 -08001548 [IFLA_GRE_ERSPAN_VER] = { .type = NLA_U8 },
1549 [IFLA_GRE_ERSPAN_DIR] = { .type = NLA_U8 },
1550 [IFLA_GRE_ERSPAN_HWID] = { .type = NLA_U16 },
Herbert Xuc19e6542008-10-09 11:59:55 -07001551};
1552
1553static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1554 .kind = "gre",
1555 .maxtype = IFLA_GRE_MAX,
1556 .policy = ipgre_policy,
1557 .priv_size = sizeof(struct ip_tunnel),
1558 .setup = ipgre_tunnel_setup,
1559 .validate = ipgre_tunnel_validate,
1560 .newlink = ipgre_newlink,
1561 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001562 .dellink = ip_tunnel_dellink,
Herbert Xuc19e6542008-10-09 11:59:55 -07001563 .get_size = ipgre_get_size,
1564 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001565 .get_link_net = ip_tunnel_get_link_net,
Herbert Xuc19e6542008-10-09 11:59:55 -07001566};
1567
Herbert Xue1a80002008-10-09 12:00:17 -07001568static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1569 .kind = "gretap",
1570 .maxtype = IFLA_GRE_MAX,
1571 .policy = ipgre_policy,
1572 .priv_size = sizeof(struct ip_tunnel),
1573 .setup = ipgre_tap_setup,
1574 .validate = ipgre_tap_validate,
1575 .newlink = ipgre_newlink,
1576 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001577 .dellink = ip_tunnel_dellink,
Herbert Xue1a80002008-10-09 12:00:17 -07001578 .get_size = ipgre_get_size,
1579 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001580 .get_link_net = ip_tunnel_get_link_net,
Herbert Xue1a80002008-10-09 12:00:17 -07001581};
1582
William Tu84e54fe2017-08-22 09:40:28 -07001583static struct rtnl_link_ops erspan_link_ops __read_mostly = {
1584 .kind = "erspan",
1585 .maxtype = IFLA_GRE_MAX,
1586 .policy = ipgre_policy,
1587 .priv_size = sizeof(struct ip_tunnel),
1588 .setup = erspan_setup,
1589 .validate = erspan_validate,
1590 .newlink = ipgre_newlink,
1591 .changelink = ipgre_changelink,
1592 .dellink = ip_tunnel_dellink,
1593 .get_size = ipgre_get_size,
1594 .fill_info = ipgre_fill_info,
1595 .get_link_net = ip_tunnel_get_link_net,
1596};
1597
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001598struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1599 u8 name_assign_type)
1600{
1601 struct nlattr *tb[IFLA_MAX + 1];
1602 struct net_device *dev;
Nicolas Dichtel106da662016-06-13 10:31:04 +02001603 LIST_HEAD(list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001604 struct ip_tunnel *t;
1605 int err;
1606
1607 memset(&tb, 0, sizeof(tb));
1608
1609 dev = rtnl_create_link(net, name, name_assign_type,
David Ahernd0522f12018-11-06 12:51:14 -08001610 &ipgre_tap_ops, tb, NULL);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001611 if (IS_ERR(dev))
1612 return dev;
1613
1614 /* Configure flow based GRE device. */
1615 t = netdev_priv(dev);
1616 t->collect_md = true;
1617
Matthias Schiffer7a3f4a12017-06-25 23:55:59 +02001618 err = ipgre_newlink(net, dev, tb, NULL, NULL);
Nicolas Dichtel106da662016-06-13 10:31:04 +02001619 if (err < 0) {
1620 free_netdev(dev);
1621 return ERR_PTR(err);
1622 }
David Wragg7e059152016-02-10 00:05:58 +00001623
1624 /* openvswitch users expect packet sizes to be unrestricted,
1625 * so set the largest MTU we can.
1626 */
1627 err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
1628 if (err)
1629 goto out;
1630
Nicolas Dichtelda6f1da2016-06-13 10:31:06 +02001631 err = rtnl_configure_link(dev, NULL);
1632 if (err < 0)
1633 goto out;
1634
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001635 return dev;
1636out:
Nicolas Dichtel106da662016-06-13 10:31:04 +02001637 ip_tunnel_dellink(dev, &list_kill);
1638 unregister_netdevice_many(&list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001639 return ERR_PTR(err);
1640}
1641EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1642
Pravin B Shelarc5441932013-03-25 14:49:35 +00001643static int __net_init ipgre_tap_init_net(struct net *net)
1644{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001645 return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001646}
1647
Eric Dumazet64bc1782017-09-19 16:27:09 -07001648static void __net_exit ipgre_tap_exit_batch_net(struct list_head *list_net)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001649{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001650 ip_tunnel_delete_nets(list_net, gre_tap_net_id, &ipgre_tap_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001651}
1652
1653static struct pernet_operations ipgre_tap_net_ops = {
1654 .init = ipgre_tap_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001655 .exit_batch = ipgre_tap_exit_batch_net,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001656 .id = &gre_tap_net_id,
1657 .size = sizeof(struct ip_tunnel_net),
1658};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
William Tu84e54fe2017-08-22 09:40:28 -07001660static int __net_init erspan_init_net(struct net *net)
1661{
1662 return ip_tunnel_init_net(net, erspan_net_id,
1663 &erspan_link_ops, "erspan0");
1664}
1665
Eric Dumazet64bc1782017-09-19 16:27:09 -07001666static void __net_exit erspan_exit_batch_net(struct list_head *net_list)
William Tu84e54fe2017-08-22 09:40:28 -07001667{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001668 ip_tunnel_delete_nets(net_list, erspan_net_id, &erspan_link_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001669}
1670
1671static struct pernet_operations erspan_net_ops = {
1672 .init = erspan_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001673 .exit_batch = erspan_exit_batch_net,
William Tu84e54fe2017-08-22 09:40:28 -07001674 .id = &erspan_net_id,
1675 .size = sizeof(struct ip_tunnel_net),
1676};
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678static int __init ipgre_init(void)
1679{
1680 int err;
1681
Joe Perches058bd4d2012-03-11 18:36:11 +00001682 pr_info("GRE over IPv4 tunneling driver\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001684 err = register_pernet_device(&ipgre_net_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001685 if (err < 0)
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001686 return err;
1687
Pravin B Shelarc5441932013-03-25 14:49:35 +00001688 err = register_pernet_device(&ipgre_tap_net_ops);
1689 if (err < 0)
William Tue3d03282017-08-22 17:04:05 -07001690 goto pnet_tap_failed;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001691
William Tu84e54fe2017-08-22 09:40:28 -07001692 err = register_pernet_device(&erspan_net_ops);
1693 if (err < 0)
1694 goto pnet_erspan_failed;
1695
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001696 err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001697 if (err < 0) {
Joe Perches058bd4d2012-03-11 18:36:11 +00001698 pr_info("%s: can't add protocol\n", __func__);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001699 goto add_proto_failed;
1700 }
Pavel Emelyanov7daa0002008-04-16 01:10:05 -07001701
Herbert Xuc19e6542008-10-09 11:59:55 -07001702 err = rtnl_link_register(&ipgre_link_ops);
1703 if (err < 0)
1704 goto rtnl_link_failed;
1705
Herbert Xue1a80002008-10-09 12:00:17 -07001706 err = rtnl_link_register(&ipgre_tap_ops);
1707 if (err < 0)
1708 goto tap_ops_failed;
1709
William Tu84e54fe2017-08-22 09:40:28 -07001710 err = rtnl_link_register(&erspan_link_ops);
1711 if (err < 0)
1712 goto erspan_link_failed;
1713
Pravin B Shelarc5441932013-03-25 14:49:35 +00001714 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001715
William Tu84e54fe2017-08-22 09:40:28 -07001716erspan_link_failed:
1717 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xue1a80002008-10-09 12:00:17 -07001718tap_ops_failed:
1719 rtnl_link_unregister(&ipgre_link_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001720rtnl_link_failed:
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001721 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001722add_proto_failed:
William Tu84e54fe2017-08-22 09:40:28 -07001723 unregister_pernet_device(&erspan_net_ops);
1724pnet_erspan_failed:
Pravin B Shelarc5441932013-03-25 14:49:35 +00001725 unregister_pernet_device(&ipgre_tap_net_ops);
William Tue3d03282017-08-22 17:04:05 -07001726pnet_tap_failed:
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001727 unregister_pernet_device(&ipgre_net_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001728 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729}
1730
Alexey Kuznetsovdb445752005-07-30 17:46:44 -07001731static void __exit ipgre_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732{
Herbert Xue1a80002008-10-09 12:00:17 -07001733 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001734 rtnl_link_unregister(&ipgre_link_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001735 rtnl_link_unregister(&erspan_link_ops);
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001736 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001737 unregister_pernet_device(&ipgre_tap_net_ops);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001738 unregister_pernet_device(&ipgre_net_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001739 unregister_pernet_device(&erspan_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
1742module_init(ipgre_init);
1743module_exit(ipgre_fini);
1744MODULE_LICENSE("GPL");
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001745MODULE_ALIAS_RTNL_LINK("gre");
1746MODULE_ALIAS_RTNL_LINK("gretap");
William Tu84e54fe2017-08-22 09:40:28 -07001747MODULE_ALIAS_RTNL_LINK("erspan");
Vasiliy Kulikov8909c9a2011-03-02 00:33:13 +03001748MODULE_ALIAS_NETDEV("gre0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001749MODULE_ALIAS_NETDEV("gretap0");
William Tu84e54fe2017-08-22 09:40:28 -07001750MODULE_ALIAS_NETDEV("erspan0");