blob: 5c36b6745dbce6a96a5aa6b9fa914faf65e4fc74 [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 Tua3222dc2017-11-30 11:51:27 -0800117 __be32 id, u32 index,
118 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
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700124static void 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 switch (type) {
150 default:
151 case ICMP_PARAMETERPROB:
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700152 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
154 case ICMP_DEST_UNREACH:
155 switch (code) {
156 case ICMP_SR_FAILED:
157 case ICMP_PORT_UNREACH:
158 /* Impossible event. */
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700159 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 default:
161 /* All others are translated to HOST_UNREACH.
162 rfc2003 contains "deep thoughts" about NET_UNREACH,
163 I believe they are just ether pollution. --ANK
164 */
165 break;
166 }
167 break;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 case ICMP_TIME_EXCEEDED:
170 if (code != ICMP_EXC_TTL)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700171 return;
Eric Dumazet20e19542016-06-18 21:52:06 -0700172 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 break;
David S. Miller55be7a92012-07-11 21:27:49 -0700174
175 case ICMP_REDIRECT:
176 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 }
178
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700179 if (tpi->proto == htons(ETH_P_TEB))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000180 itn = net_generic(net, gre_tap_net_id);
181 else
182 itn = net_generic(net, ipgre_net_id);
183
Duan Jiongc0c0c502014-01-28 11:49:43 +0800184 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700185 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
186 iph->daddr, iph->saddr, tpi->key);
stephen hemmingerd2083282012-09-24 18:12:23 +0000187
Ian Morris51456b22015-04-03 09:17:26 +0100188 if (!t)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700189 return;
David S. Miller36393392012-06-14 22:21:46 -0700190
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700191#if IS_ENABLED(CONFIG_IPV6)
192 if (tpi->proto == htons(ETH_P_IPV6) &&
Eric Dumazet20e19542016-06-18 21:52:06 -0700193 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
194 type, data_len))
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700195 return;
196#endif
197
David S. Miller36393392012-06-14 22:21:46 -0700198 if (t->parms.iph.daddr == 0 ||
Joe Perchesf97c1e02007-12-16 13:45:43 -0800199 ipv4_is_multicast(t->parms.iph.daddr))
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700200 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201
202 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700203 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
Wei Yongjunda6185d82009-02-24 23:34:48 -0800205 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 t->err_count++;
207 else
208 t->err_count = 1;
209 t->err_time = jiffies;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700210}
211
212static void gre_err(struct sk_buff *skb, u32 info)
213{
214 /* All the routers (except for Linux) return only
215 * 8 bytes of packet payload. It means, that precise relaying of
216 * ICMP in the real Internet is absolutely infeasible.
217 *
218 * Moreover, Cisco "wise men" put GRE key to the third word
219 * in GRE header. It makes impossible maintaining even soft
220 * state for keyed
221 * GRE tunnels with enabled checksum. Tell them "thank you".
222 *
223 * Well, I wonder, rfc1812 was written by Cisco employee,
224 * what the hell these idiots break standards established
225 * by themselves???
226 */
227
Eric Dumazete582615ad2016-06-15 06:24:00 -0700228 const struct iphdr *iph = (struct iphdr *)skb->data;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700229 const int type = icmp_hdr(skb)->type;
230 const int code = icmp_hdr(skb)->code;
231 struct tnl_ptk_info tpi;
232 bool csum_err = false;
233
Eric Dumazete582615ad2016-06-15 06:24:00 -0700234 if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP),
235 iph->ihl * 4) < 0) {
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700236 if (!csum_err) /* ignore csum errors. */
237 return;
238 }
239
240 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
241 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
242 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
243 return;
244 }
245 if (type == ICMP_REDIRECT) {
246 ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
247 IPPROTO_GRE, 0);
248 return;
249 }
250
251 ipgre_err(skb, info, &tpi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252}
253
William Tu84e54fe2017-08-22 09:40:28 -0700254static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
255 int gre_hdr_len)
256{
257 struct net *net = dev_net(skb->dev);
258 struct metadata_dst *tun_dst = NULL;
William Tu1d7e2ed2017-12-13 16:38:55 -0800259 struct erspan_base_hdr *ershdr;
260 struct erspan_metadata *pkt_md;
William Tu84e54fe2017-08-22 09:40:28 -0700261 struct ip_tunnel_net *itn;
262 struct ip_tunnel *tunnel;
William Tu84e54fe2017-08-22 09:40:28 -0700263 const struct iphdr *iph;
William Tu1d7e2ed2017-12-13 16:38:55 -0800264 int ver;
William Tu84e54fe2017-08-22 09:40:28 -0700265 int len;
266
267 itn = net_generic(net, erspan_net_id);
William Tu84e54fe2017-08-22 09:40:28 -0700268 len = gre_hdr_len + sizeof(*ershdr);
269
William Tu1d7e2ed2017-12-13 16:38:55 -0800270 /* Check based hdr len */
William Tu84e54fe2017-08-22 09:40:28 -0700271 if (unlikely(!pskb_may_pull(skb, len)))
Haishuang Yanc05fad52017-12-15 10:46:16 +0800272 return PACKET_REJECT;
William Tu84e54fe2017-08-22 09:40:28 -0700273
274 iph = ip_hdr(skb);
William Tu1d7e2ed2017-12-13 16:38:55 -0800275 ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
276 ver = (ntohs(ershdr->ver_vlan) & VER_MASK) >> VER_OFFSET;
William Tu84e54fe2017-08-22 09:40:28 -0700277
278 /* The original GRE header does not have key field,
279 * Use ERSPAN 10-bit session ID as key.
280 */
Xin Long935a9742017-10-01 22:00:53 +0800281 tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK);
William Tu84e54fe2017-08-22 09:40:28 -0700282 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
283 tpi->flags | TUNNEL_KEY,
284 iph->saddr, iph->daddr, tpi->key);
285
286 if (tunnel) {
William Tu1d7e2ed2017-12-13 16:38:55 -0800287 len = gre_hdr_len + erspan_hdr_len(ver);
288 if (unlikely(!pskb_may_pull(skb, len)))
William Tuae3e1332017-12-15 14:27:43 -0800289 return PACKET_REJECT;
William Tu1d7e2ed2017-12-13 16:38:55 -0800290
William Tud91e8db52017-12-15 14:27:44 -0800291 ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
292 pkt_md = (struct erspan_metadata *)(ershdr + 1);
293
William Tu84e54fe2017-08-22 09:40:28 -0700294 if (__iptunnel_pull_header(skb,
William Tu1d7e2ed2017-12-13 16:38:55 -0800295 len,
William Tu84e54fe2017-08-22 09:40:28 -0700296 htons(ETH_P_TEB),
297 false, false) < 0)
298 goto drop;
299
William Tu1a66a832017-08-25 09:21:28 -0700300 if (tunnel->collect_md) {
301 struct ip_tunnel_info *info;
302 struct erspan_metadata *md;
303 __be64 tun_id;
304 __be16 flags;
305
306 tpi->flags |= TUNNEL_KEY;
307 flags = tpi->flags;
308 tun_id = key32_to_tunnel_id(tpi->key);
309
310 tun_dst = ip_tun_rx_dst(skb, flags,
311 tun_id, sizeof(*md));
312 if (!tun_dst)
313 return PACKET_REJECT;
314
315 md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
316 if (!md)
317 return PACKET_REJECT;
318
William Tu1d7e2ed2017-12-13 16:38:55 -0800319 memcpy(md, pkt_md, sizeof(*md));
William Tuf551c912017-12-13 16:38:56 -0800320 md->version = ver;
321
William Tu1a66a832017-08-25 09:21:28 -0700322 info = &tun_dst->u.tun_info;
323 info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
324 info->options_len = sizeof(*md);
325 } else {
William Tuf551c912017-12-13 16:38:56 -0800326 tunnel->erspan_ver = ver;
327 if (ver == 1) {
328 tunnel->index = ntohl(pkt_md->u.index);
329 } else {
330 u16 md2_flags;
331 u16 dir, hwid;
332
333 md2_flags = ntohs(pkt_md->u.md2.flags);
334 dir = (md2_flags & DIR_MASK) >> DIR_OFFSET;
335 hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET;
336 tunnel->dir = dir;
337 tunnel->hwid = hwid;
338 }
339
William Tu1a66a832017-08-25 09:21:28 -0700340 }
341
William Tu84e54fe2017-08-22 09:40:28 -0700342 skb_reset_mac_header(skb);
343 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
344 return PACKET_RCVD;
345 }
346drop:
347 kfree_skb(skb);
348 return PACKET_RCVD;
349}
350
Jiri Benc125372f2016-05-03 17:10:08 +0200351static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
352 struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700354 struct metadata_dst *tun_dst = NULL;
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000355 const struct iphdr *iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 struct ip_tunnel *tunnel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700358 iph = ip_hdr(skb);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700359 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
360 iph->saddr, iph->daddr, tpi->key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
stephen hemmingerd2083282012-09-24 18:12:23 +0000362 if (tunnel) {
Jiri Benc125372f2016-05-03 17:10:08 +0200363 if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
364 raw_proto, false) < 0)
Jiri Benc244a7972016-05-03 17:10:07 +0200365 goto drop;
366
Jiri Bence271c7b2016-05-11 15:53:57 +0200367 if (tunnel->dev->type != ARPHRD_NONE)
368 skb_pop_mac_header(skb);
369 else
370 skb_reset_mac_header(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700371 if (tunnel->collect_md) {
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700372 __be16 flags;
373 __be64 tun_id;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700374
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700375 flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
Amir Vadaid817f432016-09-08 16:23:45 +0300376 tun_id = key32_to_tunnel_id(tpi->key);
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700377 tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700378 if (!tun_dst)
379 return PACKET_REJECT;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700380 }
381
382 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700383 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 }
Jiri Benc125372f2016-05-03 17:10:08 +0200385 return PACKET_NEXT;
Jiri Benc244a7972016-05-03 17:10:07 +0200386
387drop:
388 kfree_skb(skb);
389 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390}
391
Jiri Benc125372f2016-05-03 17:10:08 +0200392static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
393 int hdr_len)
394{
395 struct net *net = dev_net(skb->dev);
396 struct ip_tunnel_net *itn;
397 int res;
398
399 if (tpi->proto == htons(ETH_P_TEB))
400 itn = net_generic(net, gre_tap_net_id);
401 else
402 itn = net_generic(net, ipgre_net_id);
403
404 res = __ipgre_rcv(skb, tpi, itn, hdr_len, false);
405 if (res == PACKET_NEXT && tpi->proto == htons(ETH_P_TEB)) {
406 /* ipgre tunnels in collect metadata mode should receive
407 * also ETH_P_TEB traffic.
408 */
409 itn = net_generic(net, ipgre_net_id);
410 res = __ipgre_rcv(skb, tpi, itn, hdr_len, true);
411 }
412 return res;
413}
414
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700415static int gre_rcv(struct sk_buff *skb)
416{
417 struct tnl_ptk_info tpi;
418 bool csum_err = false;
Tom Herbert95f5c642016-04-29 17:12:16 -0700419 int hdr_len;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700420
421#ifdef CONFIG_NET_IPGRE_BROADCAST
422 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
423 /* Looped back packet, drop it! */
424 if (rt_is_output_route(skb_rtable(skb)))
425 goto drop;
426 }
427#endif
428
Eric Dumazete582615ad2016-06-15 06:24:00 -0700429 hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0);
Jiri Bencf132ae72016-05-03 15:00:21 +0200430 if (hdr_len < 0)
Tom Herbert95f5c642016-04-29 17:12:16 -0700431 goto drop;
432
William Tuf551c912017-12-13 16:38:56 -0800433 if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) ||
434 tpi.proto == htons(ETH_P_ERSPAN2))) {
William Tu84e54fe2017-08-22 09:40:28 -0700435 if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
436 return 0;
Haishuang Yandd8d5b82017-12-20 10:21:46 +0800437 goto out;
William Tu84e54fe2017-08-22 09:40:28 -0700438 }
439
Jiri Benc244a7972016-05-03 17:10:07 +0200440 if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700441 return 0;
442
Haishuang Yandd8d5b82017-12-20 10:21:46 +0800443out:
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700444 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
445drop:
446 kfree_skb(skb);
447 return 0;
448}
449
Pravin B Shelarc5441932013-03-25 14:49:35 +0000450static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
451 const struct iphdr *tnl_params,
452 __be16 proto)
453{
454 struct ip_tunnel *tunnel = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000455
Pravin B Shelarc5441932013-03-25 14:49:35 +0000456 if (tunnel->parms.o_flags & TUNNEL_SEQ)
457 tunnel->o_seqno++;
Eric Dumazetcef401d2013-01-25 20:34:37 +0000458
Pravin B Shelarc5441932013-03-25 14:49:35 +0000459 /* Push GRE header. */
Tom Herbert182a3522016-04-29 17:12:19 -0700460 gre_build_header(skb, tunnel->tun_hlen,
461 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
462 htonl(tunnel->o_seqno));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
Nicolas Dichtelbf3d6a82013-05-27 23:48:15 +0000464 ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465}
466
Alexander Duyckaed069d2016-04-14 15:33:37 -0400467static int gre_handle_offloads(struct sk_buff *skb, bool csum)
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700468{
Edward Cree6fa79662016-02-11 21:02:31 +0000469 return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700470}
471
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700472static struct rtable *gre_get_rt(struct sk_buff *skb,
473 struct net_device *dev,
474 struct flowi4 *fl,
475 const struct ip_tunnel_key *key)
476{
477 struct net *net = dev_net(dev);
478
479 memset(fl, 0, sizeof(*fl));
480 fl->daddr = key->u.ipv4.dst;
481 fl->saddr = key->u.ipv4.src;
482 fl->flowi4_tos = RT_TOS(key->tos);
483 fl->flowi4_mark = skb->mark;
484 fl->flowi4_proto = IPPROTO_GRE;
485
486 return ip_route_output_key(net, fl);
487}
488
William Tu862a03c2017-08-25 09:21:27 -0700489static struct rtable *prepare_fb_xmit(struct sk_buff *skb,
490 struct net_device *dev,
491 struct flowi4 *fl,
492 int tunnel_hlen)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700493{
494 struct ip_tunnel_info *tun_info;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700495 const struct ip_tunnel_key *key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100496 struct rtable *rt = NULL;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700497 int min_headroom;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100498 bool use_cache;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700499 int err;
500
Jiri Benc61adedf2015-08-20 13:56:25 +0200501 tun_info = skb_tunnel_info(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700502 key = &tun_info->key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100503 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
William Tu862a03c2017-08-25 09:21:27 -0700504
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100505 if (use_cache)
William Tu862a03c2017-08-25 09:21:27 -0700506 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl->saddr);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100507 if (!rt) {
William Tu862a03c2017-08-25 09:21:27 -0700508 rt = gre_get_rt(skb, dev, fl, key);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100509 if (IS_ERR(rt))
William Tu862a03c2017-08-25 09:21:27 -0700510 goto err_free_skb;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100511 if (use_cache)
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100512 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
William Tu862a03c2017-08-25 09:21:27 -0700513 fl->saddr);
Paolo Abeni3c1cb4d22016-02-12 15:43:59 +0100514 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700515
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700516 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
517 + tunnel_hlen + sizeof(struct iphdr);
518 if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
519 int head_delta = SKB_DATA_ALIGN(min_headroom -
520 skb_headroom(skb) +
521 16);
522 err = pskb_expand_head(skb, max_t(int, head_delta, 0),
523 0, GFP_ATOMIC);
524 if (unlikely(err))
525 goto err_free_rt;
526 }
William Tu862a03c2017-08-25 09:21:27 -0700527 return rt;
528
529err_free_rt:
530 ip_rt_put(rt);
531err_free_skb:
532 kfree_skb(skb);
533 dev->stats.tx_dropped++;
534 return NULL;
535}
536
537static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
538 __be16 proto)
539{
540 struct ip_tunnel_info *tun_info;
541 const struct ip_tunnel_key *key;
542 struct rtable *rt = NULL;
543 struct flowi4 fl;
544 int tunnel_hlen;
545 __be16 df, flags;
546
547 tun_info = skb_tunnel_info(skb);
548 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
549 ip_tunnel_info_af(tun_info) != AF_INET))
550 goto err_free_skb;
551
552 key = &tun_info->key;
553 tunnel_hlen = gre_calc_hlen(key->tun_flags);
554
555 rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen);
556 if (!rt)
557 return;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700558
559 /* Push Tunnel header. */
Alexander Duyckaed069d2016-04-14 15:33:37 -0400560 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700561 goto err_free_rt;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700562
563 flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
David S. Millercba653212016-05-04 00:52:29 -0400564 gre_build_header(skb, tunnel_hlen, flags, proto,
Amir Vadaid817f432016-09-08 16:23:45 +0300565 tunnel_id_to_key32(tun_info->key.tun_id), 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700566
567 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
Pravin B Shelar039f5062015-12-24 14:34:54 -0800568
569 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
570 key->tos, key->ttl, df, false);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700571 return;
572
573err_free_rt:
574 ip_rt_put(rt);
575err_free_skb:
576 kfree_skb(skb);
577 dev->stats.tx_dropped++;
578}
579
William Tu1a66a832017-08-25 09:21:28 -0700580static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
581 __be16 proto)
582{
583 struct ip_tunnel *tunnel = netdev_priv(dev);
584 struct ip_tunnel_info *tun_info;
585 const struct ip_tunnel_key *key;
586 struct erspan_metadata *md;
587 struct rtable *rt = NULL;
588 bool truncate = false;
589 struct flowi4 fl;
590 int tunnel_hlen;
William Tuf551c912017-12-13 16:38:56 -0800591 int version;
William Tu1a66a832017-08-25 09:21:28 -0700592 __be16 df;
593
594 tun_info = skb_tunnel_info(skb);
595 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
596 ip_tunnel_info_af(tun_info) != AF_INET))
597 goto err_free_skb;
598
599 key = &tun_info->key;
William Tuf551c912017-12-13 16:38:56 -0800600 md = ip_tunnel_info_opts(tun_info);
601 if (!md)
602 goto err_free_rt;
William Tu1a66a832017-08-25 09:21:28 -0700603
604 /* ERSPAN has fixed 8 byte GRE header */
William Tuf551c912017-12-13 16:38:56 -0800605 version = md->version;
606 tunnel_hlen = 8 + erspan_hdr_len(version);
William Tu1a66a832017-08-25 09:21:28 -0700607
608 rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen);
609 if (!rt)
610 return;
611
612 if (gre_handle_offloads(skb, false))
613 goto err_free_rt;
614
William Tuf1929702017-10-05 12:07:12 -0700615 if (skb->len > dev->mtu + dev->hard_header_len) {
616 pskb_trim(skb, dev->mtu + dev->hard_header_len);
William Tu1a66a832017-08-25 09:21:28 -0700617 truncate = true;
618 }
619
William Tuf551c912017-12-13 16:38:56 -0800620 if (version == 1) {
621 erspan_build_header(skb, tunnel_id_to_key32(key->tun_id),
622 ntohl(md->u.index), truncate, true);
623 } else if (version == 2) {
624 u16 md2_flags;
625 u8 direction;
626 u16 hwid;
William Tu1a66a832017-08-25 09:21:28 -0700627
William Tuf551c912017-12-13 16:38:56 -0800628 md2_flags = ntohs(md->u.md2.flags);
629 direction = (md2_flags & DIR_MASK) >> DIR_OFFSET;
630 hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET;
631
632 erspan_build_header_v2(skb, tunnel_id_to_key32(key->tun_id),
633 direction, hwid, truncate, true);
634 } else {
635 goto err_free_rt;
636 }
William Tu1a66a832017-08-25 09:21:28 -0700637
638 gre_build_header(skb, 8, TUNNEL_SEQ,
639 htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++));
640
641 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
642
643 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
644 key->tos, key->ttl, df, false);
645 return;
646
647err_free_rt:
648 ip_rt_put(rt);
649err_free_skb:
650 kfree_skb(skb);
651 dev->stats.tx_dropped++;
652}
653
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700654static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
655{
656 struct ip_tunnel_info *info = skb_tunnel_info(skb);
657 struct rtable *rt;
658 struct flowi4 fl4;
659
660 if (ip_tunnel_info_af(info) != AF_INET)
661 return -EINVAL;
662
663 rt = gre_get_rt(skb, dev, &fl4, &info->key);
664 if (IS_ERR(rt))
665 return PTR_ERR(rt);
666
667 ip_rt_put(rt);
668 info->key.u.ipv4.src = fl4.saddr;
669 return 0;
670}
671
Pravin B Shelarc5441932013-03-25 14:49:35 +0000672static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
673 struct net_device *dev)
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800674{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000675 struct ip_tunnel *tunnel = netdev_priv(dev);
676 const struct iphdr *tnl_params;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800677
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700678 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200679 gre_fb_xmit(skb, dev, skb->protocol);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700680 return NETDEV_TX_OK;
681 }
682
Pravin B Shelarc5441932013-03-25 14:49:35 +0000683 if (dev->header_ops) {
684 /* Need space for new headers */
685 if (skb_cow_head(skb, dev->needed_headroom -
Chen Gang2bac7cb2013-04-22 20:45:42 +0000686 (tunnel->hlen + sizeof(struct iphdr))))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000687 goto free_skb;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800688
Pravin B Shelarc5441932013-03-25 14:49:35 +0000689 tnl_params = (const struct iphdr *)skb->data;
Eric Dumazete985aad2010-09-27 03:57:11 +0000690
Pravin B Shelarc5441932013-03-25 14:49:35 +0000691 /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
692 * to gre header.
693 */
694 skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
Timo Teräs8a0033a2014-12-15 09:24:13 +0200695 skb_reset_mac_header(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000696 } else {
697 if (skb_cow_head(skb, dev->needed_headroom))
698 goto free_skb;
Herbert Xue1a80002008-10-09 12:00:17 -0700699
Pravin B Shelarc5441932013-03-25 14:49:35 +0000700 tnl_params = &tunnel->parms.iph;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800701 }
702
Alexander Duyckaed069d2016-04-14 15:33:37 -0400703 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
704 goto free_skb;
Timo Teräs8a0033a2014-12-15 09:24:13 +0200705
Pravin B Shelarc5441932013-03-25 14:49:35 +0000706 __gre_xmit(skb, dev, tnl_params, skb->protocol);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000707 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800708
Pravin B Shelarc5441932013-03-25 14:49:35 +0000709free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800710 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000711 dev->stats.tx_dropped++;
712 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800713}
714
William Tu84e54fe2017-08-22 09:40:28 -0700715static netdev_tx_t erspan_xmit(struct sk_buff *skb,
716 struct net_device *dev)
717{
718 struct ip_tunnel *tunnel = netdev_priv(dev);
719 bool truncate = false;
720
William Tu1a66a832017-08-25 09:21:28 -0700721 if (tunnel->collect_md) {
722 erspan_fb_xmit(skb, dev, skb->protocol);
723 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 */
William Tuf551c912017-12-13 16:38:56 -0800738 if (tunnel->erspan_ver == 1)
739 erspan_build_header(skb, tunnel->parms.o_key, tunnel->index,
740 truncate, true);
741 else
742 erspan_build_header_v2(skb, tunnel->parms.o_key,
743 tunnel->dir, tunnel->hwid,
744 truncate, true);
745
William Tu84e54fe2017-08-22 09:40:28 -0700746 tunnel->parms.o_flags &= ~TUNNEL_KEY;
747 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
748 return NETDEV_TX_OK;
749
750free_skb:
751 kfree_skb(skb);
752 dev->stats.tx_dropped++;
753 return NETDEV_TX_OK;
754}
755
Pravin B Shelarc5441932013-03-25 14:49:35 +0000756static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
757 struct net_device *dev)
758{
759 struct ip_tunnel *tunnel = netdev_priv(dev);
760
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700761 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200762 gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700763 return NETDEV_TX_OK;
764 }
765
Alexander Duyckaed069d2016-04-14 15:33:37 -0400766 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
767 goto free_skb;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000768
769 if (skb_cow_head(skb, dev->needed_headroom))
770 goto free_skb;
771
772 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000773 return NETDEV_TX_OK;
774
775free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800776 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000777 dev->stats.tx_dropped++;
778 return NETDEV_TX_OK;
779}
780
Xin Longdd9d5982017-11-07 16:33:08 +0800781static void ipgre_link_update(struct net_device *dev, bool set_mtu)
782{
783 struct ip_tunnel *tunnel = netdev_priv(dev);
784 int len;
785
786 len = tunnel->tun_hlen;
787 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
788 len = tunnel->tun_hlen - len;
789 tunnel->hlen = tunnel->hlen + len;
790
791 dev->needed_headroom = dev->needed_headroom + len;
792 if (set_mtu)
793 dev->mtu = max_t(int, dev->mtu - len, 68);
794
795 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
796 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
797 tunnel->encap.type == TUNNEL_ENCAP_NONE) {
798 dev->features |= NETIF_F_GSO_SOFTWARE;
799 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
800 }
801 dev->features |= NETIF_F_LLTX;
802 }
803}
804
Pravin B Shelarc5441932013-03-25 14:49:35 +0000805static int ipgre_tunnel_ioctl(struct net_device *dev,
806 struct ifreq *ifr, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 struct ip_tunnel_parm p;
Xin Longa0efab62017-11-07 16:33:09 +0800809 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
Pravin B Shelarc5441932013-03-25 14:49:35 +0000811 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
812 return -EFAULT;
Xin Longa0efab62017-11-07 16:33:09 +0800813
Cong Wang6c734fb2013-06-29 12:02:59 +0800814 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
815 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
Xin Longa0efab62017-11-07 16:33:09 +0800816 p.iph.ihl != 5 || (p.iph.frag_off & htons(~IP_DF)) ||
817 ((p.i_flags | p.o_flags) & (GRE_VERSION | GRE_ROUTING)))
Cong Wang6c734fb2013-06-29 12:02:59 +0800818 return -EINVAL;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000819 }
Xin Longa0efab62017-11-07 16:33:09 +0800820
Pravin B Shelarc5441932013-03-25 14:49:35 +0000821 p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
822 p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
823
824 err = ip_tunnel_ioctl(dev, &p, cmd);
825 if (err)
826 return err;
827
Xin Longa0efab62017-11-07 16:33:09 +0800828 if (cmd == SIOCCHGTUNNEL) {
829 struct ip_tunnel *t = netdev_priv(dev);
830
831 t->parms.i_flags = p.i_flags;
832 t->parms.o_flags = p.o_flags;
833
834 if (strcmp(dev->rtnl_link_ops->kind, "erspan"))
835 ipgre_link_update(dev, true);
836 }
837
Tom Herbert95f5c642016-04-29 17:12:16 -0700838 p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
839 p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000840
841 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
842 return -EFAULT;
Xin Longa0efab62017-11-07 16:33:09 +0800843
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 return 0;
845}
846
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847/* Nice toy. Unfortunately, useless in real life :-)
848 It allows to construct virtual multiprotocol broadcast "LAN"
849 over the Internet, provided multicast routing is tuned.
850
851
852 I have no idea was this bicycle invented before me,
853 so that I had to set ARPHRD_IPGRE to a random value.
854 I have an impression, that Cisco could make something similar,
855 but this feature is apparently missing in IOS<=11.2(8).
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
858 with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
859
860 ping -t 255 224.66.66.66
861
862 If nobody answers, mbone does not work.
863
864 ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
865 ip addr add 10.66.66.<somewhat>/24 dev Universe
866 ifconfig Universe up
867 ifconfig Universe add fe80::<Your_real_addr>/10
868 ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
869 ftp 10.66.66.66
870 ...
871 ftp fec0:6666:6666::193.233.7.65
872 ...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700874static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
875 unsigned short type,
Eric Dumazet15078502010-09-15 11:07:53 +0000876 const void *daddr, const void *saddr, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
Patrick McHardy2941a482006-01-08 22:05:26 -0800878 struct ip_tunnel *t = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000879 struct iphdr *iph;
880 struct gre_base_hdr *greh;
881
Johannes Bergd58ff352017-06-16 14:29:23 +0200882 iph = skb_push(skb, t->hlen + sizeof(*iph));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000883 greh = (struct gre_base_hdr *)(iph+1);
Tom Herbert95f5c642016-04-29 17:12:16 -0700884 greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000885 greh->protocol = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Pravin B Shelarc5441932013-03-25 14:49:35 +0000889 /* Set the source hardware address. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 if (saddr)
891 memcpy(&iph->saddr, saddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000892 if (daddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 memcpy(&iph->daddr, daddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000894 if (iph->daddr)
Timo Teräs77a482b2013-08-06 13:45:43 +0300895 return t->hlen + sizeof(*iph);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900896
Pravin B Shelarc5441932013-03-25 14:49:35 +0000897 return -(t->hlen + sizeof(*iph));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898}
899
Timo Teras6a5f44d2007-10-23 20:31:53 -0700900static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
901{
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000902 const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
Timo Teras6a5f44d2007-10-23 20:31:53 -0700903 memcpy(haddr, &iph->saddr, 4);
904 return 4;
905}
906
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700907static const struct header_ops ipgre_header_ops = {
908 .create = ipgre_header,
Timo Teras6a5f44d2007-10-23 20:31:53 -0700909 .parse = ipgre_header_parse,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700910};
911
Timo Teras6a5f44d2007-10-23 20:31:53 -0700912#ifdef CONFIG_NET_IPGRE_BROADCAST
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913static int ipgre_open(struct net_device *dev)
914{
Patrick McHardy2941a482006-01-08 22:05:26 -0800915 struct ip_tunnel *t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Joe Perchesf97c1e02007-12-16 13:45:43 -0800917 if (ipv4_is_multicast(t->parms.iph.daddr)) {
David S. Millercbb1e852011-05-04 12:33:34 -0700918 struct flowi4 fl4;
919 struct rtable *rt;
Eric Dumazete985aad2010-09-27 03:57:11 +0000920
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200921 rt = ip_route_output_gre(t->net, &fl4,
David S. Millercbb1e852011-05-04 12:33:34 -0700922 t->parms.iph.daddr,
923 t->parms.iph.saddr,
924 t->parms.o_key,
925 RT_TOS(t->parms.iph.tos),
926 t->parms.link);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800927 if (IS_ERR(rt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 return -EADDRNOTAVAIL;
Changli Gaod8d1f302010-06-10 23:31:35 -0700929 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 ip_rt_put(rt);
Ian Morris51456b22015-04-03 09:17:26 +0100931 if (!__in_dev_get_rtnl(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 return -EADDRNOTAVAIL;
933 t->mlink = dev->ifindex;
Herbert Xue5ed6392005-10-03 14:35:55 -0700934 ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 }
936 return 0;
937}
938
939static int ipgre_close(struct net_device *dev)
940{
Patrick McHardy2941a482006-01-08 22:05:26 -0800941 struct ip_tunnel *t = netdev_priv(dev);
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800942
Joe Perchesf97c1e02007-12-16 13:45:43 -0800943 if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
Denis V. Lunev7fee0ca2008-01-21 17:32:38 -0800944 struct in_device *in_dev;
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200945 in_dev = inetdev_by_index(t->net, t->mlink);
Eric Dumazet8723e1b2010-10-19 00:39:26 +0000946 if (in_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 ip_mc_dec_group(in_dev, t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 }
949 return 0;
950}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951#endif
952
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800953static const struct net_device_ops ipgre_netdev_ops = {
954 .ndo_init = ipgre_tunnel_init,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000955 .ndo_uninit = ip_tunnel_uninit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800956#ifdef CONFIG_NET_IPGRE_BROADCAST
957 .ndo_open = ipgre_open,
958 .ndo_stop = ipgre_close,
959#endif
Pravin B Shelarc5441932013-03-25 14:49:35 +0000960 .ndo_start_xmit = ipgre_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800961 .ndo_do_ioctl = ipgre_tunnel_ioctl,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000962 .ndo_change_mtu = ip_tunnel_change_mtu,
963 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200964 .ndo_get_iflink = ip_tunnel_get_iflink,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800965};
966
Eric Dumazet6b78f162012-09-13 21:25:33 +0000967#define GRE_FEATURES (NETIF_F_SG | \
968 NETIF_F_FRAGLIST | \
969 NETIF_F_HIGHDMA | \
970 NETIF_F_HW_CSUM)
971
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972static void ipgre_tunnel_setup(struct net_device *dev)
973{
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800974 dev->netdev_ops = &ipgre_netdev_ops;
Nicolas Dichtel5a455272014-04-11 15:51:18 +0200975 dev->type = ARPHRD_IPGRE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000976 ip_tunnel_setup(dev, ipgre_net_id);
977}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
Pravin B Shelarc5441932013-03-25 14:49:35 +0000979static void __gre_tunnel_init(struct net_device *dev)
980{
981 struct ip_tunnel *tunnel;
Tom Herbert4565e992014-09-17 12:26:01 -0700982 int t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000983
984 tunnel = netdev_priv(dev);
Tom Herbert95f5c642016-04-29 17:12:16 -0700985 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000986 tunnel->parms.iph.protocol = IPPROTO_GRE;
987
Tom Herbert4565e992014-09-17 12:26:01 -0700988 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
989
990 t_hlen = tunnel->hlen + sizeof(struct iphdr);
991
992 dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
993 dev->mtu = ETH_DATA_LEN - t_hlen - 4;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000994
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200995 dev->features |= GRE_FEATURES;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000996 dev->hw_features |= GRE_FEATURES;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000997
998 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
Alexander Duycka0ca1532016-04-05 09:13:39 -0700999 /* TCP offload with GRE SEQ is not supported, nor
1000 * can we support 2 levels of outer headers requiring
1001 * an update.
1002 */
1003 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
1004 (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
1005 dev->features |= NETIF_F_GSO_SOFTWARE;
1006 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
1007 }
1008
Pravin B Shelarc5441932013-03-25 14:49:35 +00001009 /* Can use a lockless transmit, unless we generate
1010 * output sequences
1011 */
1012 dev->features |= NETIF_F_LLTX;
1013 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014}
1015
1016static int ipgre_tunnel_init(struct net_device *dev)
1017{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001018 struct ip_tunnel *tunnel = netdev_priv(dev);
1019 struct iphdr *iph = &tunnel->parms.iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
Pravin B Shelarc5441932013-03-25 14:49:35 +00001021 __gre_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
Pravin B Shelarc5441932013-03-25 14:49:35 +00001023 memcpy(dev->dev_addr, &iph->saddr, 4);
1024 memcpy(dev->broadcast, &iph->daddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025
Pravin B Shelarc5441932013-03-25 14:49:35 +00001026 dev->flags = IFF_NOARP;
Eric Dumazet02875872014-10-05 18:38:35 -07001027 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001028 dev->addr_len = 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Jiri Benca64b04d2016-04-27 11:29:06 +02001030 if (iph->daddr && !tunnel->collect_md) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031#ifdef CONFIG_NET_IPGRE_BROADCAST
Joe Perchesf97c1e02007-12-16 13:45:43 -08001032 if (ipv4_is_multicast(iph->daddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 if (!iph->saddr)
1034 return -EINVAL;
1035 dev->flags = IFF_BROADCAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001036 dev->header_ops = &ipgre_header_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 }
1038#endif
Jiri Benca64b04d2016-04-27 11:29:06 +02001039 } else if (!tunnel->collect_md) {
Timo Teras6a5f44d2007-10-23 20:31:53 -07001040 dev->header_ops = &ipgre_header_ops;
Jiri Benca64b04d2016-04-27 11:29:06 +02001041 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Pravin B Shelarc5441932013-03-25 14:49:35 +00001043 return ip_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044}
1045
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001046static const struct gre_protocol ipgre_protocol = {
1047 .handler = gre_rcv,
1048 .err_handler = gre_err,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049};
1050
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00001051static int __net_init ipgre_init_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001052{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001053 return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001054}
1055
Eric Dumazet64bc1782017-09-19 16:27:09 -07001056static void __net_exit ipgre_exit_batch_net(struct list_head *list_net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001057{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001058 ip_tunnel_delete_nets(list_net, ipgre_net_id, &ipgre_link_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001059}
1060
1061static struct pernet_operations ipgre_net_ops = {
1062 .init = ipgre_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001063 .exit_batch = ipgre_exit_batch_net,
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001064 .id = &ipgre_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001065 .size = sizeof(struct ip_tunnel_net),
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001066};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001068static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
1069 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001070{
1071 __be16 flags;
1072
1073 if (!data)
1074 return 0;
1075
1076 flags = 0;
1077 if (data[IFLA_GRE_IFLAGS])
1078 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1079 if (data[IFLA_GRE_OFLAGS])
1080 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1081 if (flags & (GRE_VERSION|GRE_ROUTING))
1082 return -EINVAL;
1083
Jiri Benc946b6362016-04-27 14:08:01 +02001084 if (data[IFLA_GRE_COLLECT_METADATA] &&
1085 data[IFLA_GRE_ENCAP_TYPE] &&
1086 nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
1087 return -EINVAL;
1088
Herbert Xuc19e6542008-10-09 11:59:55 -07001089 return 0;
1090}
1091
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001092static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
1093 struct netlink_ext_ack *extack)
Herbert Xue1a80002008-10-09 12:00:17 -07001094{
1095 __be32 daddr;
1096
1097 if (tb[IFLA_ADDRESS]) {
1098 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
1099 return -EINVAL;
1100 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
1101 return -EADDRNOTAVAIL;
1102 }
1103
1104 if (!data)
1105 goto out;
1106
1107 if (data[IFLA_GRE_REMOTE]) {
1108 memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
1109 if (!daddr)
1110 return -EINVAL;
1111 }
1112
1113out:
Matthias Schiffera8b8a8892017-06-25 23:56:01 +02001114 return ipgre_tunnel_validate(tb, data, extack);
Herbert Xue1a80002008-10-09 12:00:17 -07001115}
1116
William Tu84e54fe2017-08-22 09:40:28 -07001117static int erspan_validate(struct nlattr *tb[], struct nlattr *data[],
1118 struct netlink_ext_ack *extack)
1119{
1120 __be16 flags = 0;
1121 int ret;
1122
1123 if (!data)
1124 return 0;
1125
1126 ret = ipgre_tap_validate(tb, data, extack);
1127 if (ret)
1128 return ret;
1129
1130 /* ERSPAN should only have GRE sequence and key flag */
William Tu1a66a832017-08-25 09:21:28 -07001131 if (data[IFLA_GRE_OFLAGS])
1132 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1133 if (data[IFLA_GRE_IFLAGS])
1134 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1135 if (!data[IFLA_GRE_COLLECT_METADATA] &&
1136 flags != (GRE_SEQ | GRE_KEY))
William Tu84e54fe2017-08-22 09:40:28 -07001137 return -EINVAL;
1138
1139 /* ERSPAN Session ID only has 10-bit. Since we reuse
1140 * 32-bit key field as ID, check it's range.
1141 */
1142 if (data[IFLA_GRE_IKEY] &&
1143 (ntohl(nla_get_be32(data[IFLA_GRE_IKEY])) & ~ID_MASK))
1144 return -EINVAL;
1145
1146 if (data[IFLA_GRE_OKEY] &&
1147 (ntohl(nla_get_be32(data[IFLA_GRE_OKEY])) & ~ID_MASK))
1148 return -EINVAL;
1149
1150 return 0;
1151}
1152
Philip Prindeville22a59be2016-06-14 15:53:02 -06001153static int ipgre_netlink_parms(struct net_device *dev,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001154 struct nlattr *data[],
1155 struct nlattr *tb[],
Craig Gallek9830ad42017-04-19 12:30:54 -04001156 struct ip_tunnel_parm *parms,
1157 __u32 *fwmark)
Herbert Xuc19e6542008-10-09 11:59:55 -07001158{
Philip Prindeville22a59be2016-06-14 15:53:02 -06001159 struct ip_tunnel *t = netdev_priv(dev);
1160
Herbert Xu7bb82d92008-10-11 12:20:15 -07001161 memset(parms, 0, sizeof(*parms));
Herbert Xuc19e6542008-10-09 11:59:55 -07001162
1163 parms->iph.protocol = IPPROTO_GRE;
1164
1165 if (!data)
Philip Prindeville22a59be2016-06-14 15:53:02 -06001166 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001167
1168 if (data[IFLA_GRE_LINK])
1169 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
1170
1171 if (data[IFLA_GRE_IFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +00001172 parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -07001173
1174 if (data[IFLA_GRE_OFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +00001175 parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -07001176
1177 if (data[IFLA_GRE_IKEY])
1178 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
1179
1180 if (data[IFLA_GRE_OKEY])
1181 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
1182
1183 if (data[IFLA_GRE_LOCAL])
Jiri Benc67b61f62015-03-29 16:59:26 +02001184 parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
Herbert Xuc19e6542008-10-09 11:59:55 -07001185
1186 if (data[IFLA_GRE_REMOTE])
Jiri Benc67b61f62015-03-29 16:59:26 +02001187 parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
Herbert Xuc19e6542008-10-09 11:59:55 -07001188
1189 if (data[IFLA_GRE_TTL])
1190 parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
1191
1192 if (data[IFLA_GRE_TOS])
1193 parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
1194
Philip Prindeville22a59be2016-06-14 15:53:02 -06001195 if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) {
1196 if (t->ignore_df)
1197 return -EINVAL;
Herbert Xuc19e6542008-10-09 11:59:55 -07001198 parms->iph.frag_off = htons(IP_DF);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001199 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001200
1201 if (data[IFLA_GRE_COLLECT_METADATA]) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001202 t->collect_md = true;
Jiri Bence271c7b2016-05-11 15:53:57 +02001203 if (dev->type == ARPHRD_IPGRE)
1204 dev->type = ARPHRD_NONE;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001205 }
Philip Prindeville22a59be2016-06-14 15:53:02 -06001206
1207 if (data[IFLA_GRE_IGNORE_DF]) {
1208 if (nla_get_u8(data[IFLA_GRE_IGNORE_DF])
1209 && (parms->iph.frag_off & htons(IP_DF)))
1210 return -EINVAL;
1211 t->ignore_df = !!nla_get_u8(data[IFLA_GRE_IGNORE_DF]);
1212 }
1213
Craig Gallek9830ad42017-04-19 12:30:54 -04001214 if (data[IFLA_GRE_FWMARK])
1215 *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]);
1216
William Tuf551c912017-12-13 16:38:56 -08001217 if (data[IFLA_GRE_ERSPAN_VER]) {
1218 t->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
William Tu84e54fe2017-08-22 09:40:28 -07001219
William Tuf551c912017-12-13 16:38:56 -08001220 if (t->erspan_ver != 1 && t->erspan_ver != 2)
William Tu84e54fe2017-08-22 09:40:28 -07001221 return -EINVAL;
1222 }
1223
William Tuf551c912017-12-13 16:38:56 -08001224 if (t->erspan_ver == 1) {
1225 if (data[IFLA_GRE_ERSPAN_INDEX]) {
1226 t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]);
1227 if (t->index & ~INDEX_MASK)
1228 return -EINVAL;
1229 }
1230 } else if (t->erspan_ver == 2) {
1231 if (data[IFLA_GRE_ERSPAN_DIR]) {
1232 t->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]);
1233 if (t->dir & ~(DIR_MASK >> DIR_OFFSET))
1234 return -EINVAL;
1235 }
1236 if (data[IFLA_GRE_ERSPAN_HWID]) {
1237 t->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]);
1238 if (t->hwid & ~(HWID_MASK >> HWID_OFFSET))
1239 return -EINVAL;
1240 }
1241 }
1242
Philip Prindeville22a59be2016-06-14 15:53:02 -06001243 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001244}
1245
Tom Herbert4565e992014-09-17 12:26:01 -07001246/* This function returns true when ENCAP attributes are present in the nl msg */
1247static bool ipgre_netlink_encap_parms(struct nlattr *data[],
1248 struct ip_tunnel_encap *ipencap)
1249{
1250 bool ret = false;
1251
1252 memset(ipencap, 0, sizeof(*ipencap));
1253
1254 if (!data)
1255 return ret;
1256
1257 if (data[IFLA_GRE_ENCAP_TYPE]) {
1258 ret = true;
1259 ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
1260 }
1261
1262 if (data[IFLA_GRE_ENCAP_FLAGS]) {
1263 ret = true;
1264 ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
1265 }
1266
1267 if (data[IFLA_GRE_ENCAP_SPORT]) {
1268 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001269 ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -07001270 }
1271
1272 if (data[IFLA_GRE_ENCAP_DPORT]) {
1273 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001274 ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -07001275 }
1276
1277 return ret;
1278}
1279
Pravin B Shelarc5441932013-03-25 14:49:35 +00001280static int gre_tap_init(struct net_device *dev)
Herbert Xue1a80002008-10-09 12:00:17 -07001281{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001282 __gre_tunnel_init(dev);
stephen hemmingerbec94d4302014-12-27 10:01:42 -08001283 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Xin Longd51711c2017-09-28 13:23:31 +08001284 netif_keep_dst(dev);
Herbert Xue1a80002008-10-09 12:00:17 -07001285
Pravin B Shelarc5441932013-03-25 14:49:35 +00001286 return ip_tunnel_init(dev);
Herbert Xue1a80002008-10-09 12:00:17 -07001287}
1288
Pravin B Shelarc5441932013-03-25 14:49:35 +00001289static const struct net_device_ops gre_tap_netdev_ops = {
1290 .ndo_init = gre_tap_init,
1291 .ndo_uninit = ip_tunnel_uninit,
1292 .ndo_start_xmit = gre_tap_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -08001293 .ndo_set_mac_address = eth_mac_addr,
1294 .ndo_validate_addr = eth_validate_addr,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001295 .ndo_change_mtu = ip_tunnel_change_mtu,
1296 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +02001297 .ndo_get_iflink = ip_tunnel_get_iflink,
Pravin B Shelarfc4099f2015-10-22 18:17:16 -07001298 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -08001299};
1300
William Tu84e54fe2017-08-22 09:40:28 -07001301static int erspan_tunnel_init(struct net_device *dev)
1302{
1303 struct ip_tunnel *tunnel = netdev_priv(dev);
1304 int t_hlen;
1305
1306 tunnel->tun_hlen = 8;
1307 tunnel->parms.iph.protocol = IPPROTO_GRE;
Xin Longc122fda2017-10-01 22:00:55 +08001308 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen +
William Tuf551c912017-12-13 16:38:56 -08001309 erspan_hdr_len(tunnel->erspan_ver);
Xin Longc122fda2017-10-01 22:00:55 +08001310 t_hlen = tunnel->hlen + sizeof(struct iphdr);
William Tu84e54fe2017-08-22 09:40:28 -07001311
1312 dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
1313 dev->mtu = ETH_DATA_LEN - t_hlen - 4;
1314 dev->features |= GRE_FEATURES;
1315 dev->hw_features |= GRE_FEATURES;
1316 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Xin Longc84bed42017-10-01 22:00:56 +08001317 netif_keep_dst(dev);
William Tu84e54fe2017-08-22 09:40:28 -07001318
1319 return ip_tunnel_init(dev);
1320}
1321
1322static const struct net_device_ops erspan_netdev_ops = {
1323 .ndo_init = erspan_tunnel_init,
1324 .ndo_uninit = ip_tunnel_uninit,
1325 .ndo_start_xmit = erspan_xmit,
1326 .ndo_set_mac_address = eth_mac_addr,
1327 .ndo_validate_addr = eth_validate_addr,
1328 .ndo_change_mtu = ip_tunnel_change_mtu,
1329 .ndo_get_stats64 = ip_tunnel_get_stats64,
1330 .ndo_get_iflink = ip_tunnel_get_iflink,
1331 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
1332};
1333
Herbert Xue1a80002008-10-09 12:00:17 -07001334static void ipgre_tap_setup(struct net_device *dev)
1335{
Herbert Xue1a80002008-10-09 12:00:17 -07001336 ether_setup(dev);
Jiri Bencd13b1612016-02-17 15:32:53 +01001337 dev->netdev_ops = &gre_tap_netdev_ops;
1338 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1339 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001340 ip_tunnel_setup(dev, gre_tap_net_id);
Herbert Xue1a80002008-10-09 12:00:17 -07001341}
1342
Pravin B Shelarc5441932013-03-25 14:49:35 +00001343static int ipgre_newlink(struct net *src_net, struct net_device *dev,
Matthias Schiffer7a3f4a12017-06-25 23:55:59 +02001344 struct nlattr *tb[], struct nlattr *data[],
1345 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001346{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001347 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -07001348 struct ip_tunnel_encap ipencap;
Craig Gallek9830ad42017-04-19 12:30:54 -04001349 __u32 fwmark = 0;
Philip Prindeville22a59be2016-06-14 15:53:02 -06001350 int err;
Tom Herbert4565e992014-09-17 12:26:01 -07001351
1352 if (ipgre_netlink_encap_parms(data, &ipencap)) {
1353 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001354 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -07001355
1356 if (err < 0)
1357 return err;
1358 }
Herbert Xuc19e6542008-10-09 11:59:55 -07001359
Craig Gallek9830ad42017-04-19 12:30:54 -04001360 err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001361 if (err < 0)
1362 return err;
Craig Gallek9830ad42017-04-19 12:30:54 -04001363 return ip_tunnel_newlink(dev, tb, &p, fwmark);
Herbert Xuc19e6542008-10-09 11:59:55 -07001364}
1365
1366static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
Matthias Schifferad744b22017-06-25 23:56:00 +02001367 struct nlattr *data[],
1368 struct netlink_ext_ack *extack)
Herbert Xuc19e6542008-10-09 11:59:55 -07001369{
Craig Gallek9830ad42017-04-19 12:30:54 -04001370 struct ip_tunnel *t = netdev_priv(dev);
Tom Herbert4565e992014-09-17 12:26:01 -07001371 struct ip_tunnel_encap ipencap;
Craig Gallek9830ad42017-04-19 12:30:54 -04001372 __u32 fwmark = t->fwmark;
Xin Longdd9d5982017-11-07 16:33:08 +08001373 struct ip_tunnel_parm p;
Philip Prindeville22a59be2016-06-14 15:53:02 -06001374 int err;
Tom Herbert4565e992014-09-17 12:26:01 -07001375
1376 if (ipgre_netlink_encap_parms(data, &ipencap)) {
Philip Prindeville22a59be2016-06-14 15:53:02 -06001377 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -07001378
1379 if (err < 0)
1380 return err;
1381 }
Herbert Xuc19e6542008-10-09 11:59:55 -07001382
Craig Gallek9830ad42017-04-19 12:30:54 -04001383 err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001384 if (err < 0)
1385 return err;
Xin Longdd9d5982017-11-07 16:33:08 +08001386
1387 err = ip_tunnel_changelink(dev, tb, &p, fwmark);
1388 if (err < 0)
1389 return err;
1390
1391 t->parms.i_flags = p.i_flags;
1392 t->parms.o_flags = p.o_flags;
1393
1394 if (strcmp(dev->rtnl_link_ops->kind, "erspan"))
1395 ipgre_link_update(dev, !tb[IFLA_MTU]);
1396
1397 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001398}
1399
1400static size_t ipgre_get_size(const struct net_device *dev)
1401{
1402 return
1403 /* IFLA_GRE_LINK */
1404 nla_total_size(4) +
1405 /* IFLA_GRE_IFLAGS */
1406 nla_total_size(2) +
1407 /* IFLA_GRE_OFLAGS */
1408 nla_total_size(2) +
1409 /* IFLA_GRE_IKEY */
1410 nla_total_size(4) +
1411 /* IFLA_GRE_OKEY */
1412 nla_total_size(4) +
1413 /* IFLA_GRE_LOCAL */
1414 nla_total_size(4) +
1415 /* IFLA_GRE_REMOTE */
1416 nla_total_size(4) +
1417 /* IFLA_GRE_TTL */
1418 nla_total_size(1) +
1419 /* IFLA_GRE_TOS */
1420 nla_total_size(1) +
1421 /* IFLA_GRE_PMTUDISC */
1422 nla_total_size(1) +
Tom Herbert4565e992014-09-17 12:26:01 -07001423 /* IFLA_GRE_ENCAP_TYPE */
1424 nla_total_size(2) +
1425 /* IFLA_GRE_ENCAP_FLAGS */
1426 nla_total_size(2) +
1427 /* IFLA_GRE_ENCAP_SPORT */
1428 nla_total_size(2) +
1429 /* IFLA_GRE_ENCAP_DPORT */
1430 nla_total_size(2) +
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001431 /* IFLA_GRE_COLLECT_METADATA */
1432 nla_total_size(0) +
Philip Prindeville22a59be2016-06-14 15:53:02 -06001433 /* IFLA_GRE_IGNORE_DF */
1434 nla_total_size(1) +
Craig Gallek9830ad42017-04-19 12:30:54 -04001435 /* IFLA_GRE_FWMARK */
1436 nla_total_size(4) +
William Tu84e54fe2017-08-22 09:40:28 -07001437 /* IFLA_GRE_ERSPAN_INDEX */
1438 nla_total_size(4) +
William Tuf551c912017-12-13 16:38:56 -08001439 /* IFLA_GRE_ERSPAN_VER */
1440 nla_total_size(1) +
1441 /* IFLA_GRE_ERSPAN_DIR */
1442 nla_total_size(1) +
1443 /* IFLA_GRE_ERSPAN_HWID */
1444 nla_total_size(2) +
Herbert Xuc19e6542008-10-09 11:59:55 -07001445 0;
1446}
1447
1448static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1449{
1450 struct ip_tunnel *t = netdev_priv(dev);
1451 struct ip_tunnel_parm *p = &t->parms;
1452
David S. Millerf3756b72012-04-01 20:39:02 -04001453 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
Tom Herbert95f5c642016-04-29 17:12:16 -07001454 nla_put_be16(skb, IFLA_GRE_IFLAGS,
1455 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
1456 nla_put_be16(skb, IFLA_GRE_OFLAGS,
1457 gre_tnl_flags_to_gre_flags(p->o_flags)) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001458 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1459 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
Jiri Benc930345e2015-03-29 16:59:25 +02001460 nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1461 nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001462 nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1463 nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1464 nla_put_u8(skb, IFLA_GRE_PMTUDISC,
Craig Gallek9830ad42017-04-19 12:30:54 -04001465 !!(p->iph.frag_off & htons(IP_DF))) ||
1466 nla_put_u32(skb, IFLA_GRE_FWMARK, t->fwmark))
David S. Millerf3756b72012-04-01 20:39:02 -04001467 goto nla_put_failure;
Tom Herbert4565e992014-09-17 12:26:01 -07001468
1469 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
1470 t->encap.type) ||
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001471 nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
1472 t->encap.sport) ||
1473 nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
1474 t->encap.dport) ||
Tom Herbert4565e992014-09-17 12:26:01 -07001475 nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
Tom Herberte1b2cb62014-11-05 16:49:38 -08001476 t->encap.flags))
Tom Herbert4565e992014-09-17 12:26:01 -07001477 goto nla_put_failure;
1478
Philip Prindeville22a59be2016-06-14 15:53:02 -06001479 if (nla_put_u8(skb, IFLA_GRE_IGNORE_DF, t->ignore_df))
1480 goto nla_put_failure;
1481
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001482 if (t->collect_md) {
1483 if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
1484 goto nla_put_failure;
1485 }
1486
William Tuf551c912017-12-13 16:38:56 -08001487 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
1488 goto nla_put_failure;
1489
1490 if (t->erspan_ver == 1) {
William Tu84e54fe2017-08-22 09:40:28 -07001491 if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
1492 goto nla_put_failure;
William Tuf551c912017-12-13 16:38:56 -08001493 } else if (t->erspan_ver == 2) {
1494 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
1495 goto nla_put_failure;
1496 if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
1497 goto nla_put_failure;
1498 }
William Tu84e54fe2017-08-22 09:40:28 -07001499
Herbert Xuc19e6542008-10-09 11:59:55 -07001500 return 0;
1501
1502nla_put_failure:
1503 return -EMSGSIZE;
1504}
1505
William Tu84e54fe2017-08-22 09:40:28 -07001506static void erspan_setup(struct net_device *dev)
1507{
1508 ether_setup(dev);
1509 dev->netdev_ops = &erspan_netdev_ops;
1510 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1511 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1512 ip_tunnel_setup(dev, erspan_net_id);
1513}
1514
Herbert Xuc19e6542008-10-09 11:59:55 -07001515static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1516 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1517 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1518 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1519 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1520 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001521 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
1522 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
Herbert Xuc19e6542008-10-09 11:59:55 -07001523 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1524 [IFLA_GRE_TOS] = { .type = NLA_U8 },
1525 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
Tom Herbert4565e992014-09-17 12:26:01 -07001526 [IFLA_GRE_ENCAP_TYPE] = { .type = NLA_U16 },
1527 [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 },
1528 [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 },
1529 [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 },
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001530 [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG },
Philip Prindeville22a59be2016-06-14 15:53:02 -06001531 [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 },
Craig Gallek9830ad42017-04-19 12:30:54 -04001532 [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
William Tu84e54fe2017-08-22 09:40:28 -07001533 [IFLA_GRE_ERSPAN_INDEX] = { .type = NLA_U32 },
William Tuf551c912017-12-13 16:38:56 -08001534 [IFLA_GRE_ERSPAN_VER] = { .type = NLA_U8 },
1535 [IFLA_GRE_ERSPAN_DIR] = { .type = NLA_U8 },
1536 [IFLA_GRE_ERSPAN_HWID] = { .type = NLA_U16 },
Herbert Xuc19e6542008-10-09 11:59:55 -07001537};
1538
1539static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1540 .kind = "gre",
1541 .maxtype = IFLA_GRE_MAX,
1542 .policy = ipgre_policy,
1543 .priv_size = sizeof(struct ip_tunnel),
1544 .setup = ipgre_tunnel_setup,
1545 .validate = ipgre_tunnel_validate,
1546 .newlink = ipgre_newlink,
1547 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001548 .dellink = ip_tunnel_dellink,
Herbert Xuc19e6542008-10-09 11:59:55 -07001549 .get_size = ipgre_get_size,
1550 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001551 .get_link_net = ip_tunnel_get_link_net,
Herbert Xuc19e6542008-10-09 11:59:55 -07001552};
1553
Herbert Xue1a80002008-10-09 12:00:17 -07001554static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1555 .kind = "gretap",
1556 .maxtype = IFLA_GRE_MAX,
1557 .policy = ipgre_policy,
1558 .priv_size = sizeof(struct ip_tunnel),
1559 .setup = ipgre_tap_setup,
1560 .validate = ipgre_tap_validate,
1561 .newlink = ipgre_newlink,
1562 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001563 .dellink = ip_tunnel_dellink,
Herbert Xue1a80002008-10-09 12:00:17 -07001564 .get_size = ipgre_get_size,
1565 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001566 .get_link_net = ip_tunnel_get_link_net,
Herbert Xue1a80002008-10-09 12:00:17 -07001567};
1568
William Tu84e54fe2017-08-22 09:40:28 -07001569static struct rtnl_link_ops erspan_link_ops __read_mostly = {
1570 .kind = "erspan",
1571 .maxtype = IFLA_GRE_MAX,
1572 .policy = ipgre_policy,
1573 .priv_size = sizeof(struct ip_tunnel),
1574 .setup = erspan_setup,
1575 .validate = erspan_validate,
1576 .newlink = ipgre_newlink,
1577 .changelink = ipgre_changelink,
1578 .dellink = ip_tunnel_dellink,
1579 .get_size = ipgre_get_size,
1580 .fill_info = ipgre_fill_info,
1581 .get_link_net = ip_tunnel_get_link_net,
1582};
1583
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001584struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1585 u8 name_assign_type)
1586{
1587 struct nlattr *tb[IFLA_MAX + 1];
1588 struct net_device *dev;
Nicolas Dichtel106da662016-06-13 10:31:04 +02001589 LIST_HEAD(list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001590 struct ip_tunnel *t;
1591 int err;
1592
1593 memset(&tb, 0, sizeof(tb));
1594
1595 dev = rtnl_create_link(net, name, name_assign_type,
1596 &ipgre_tap_ops, tb);
1597 if (IS_ERR(dev))
1598 return dev;
1599
1600 /* Configure flow based GRE device. */
1601 t = netdev_priv(dev);
1602 t->collect_md = true;
1603
Matthias Schiffer7a3f4a12017-06-25 23:55:59 +02001604 err = ipgre_newlink(net, dev, tb, NULL, NULL);
Nicolas Dichtel106da662016-06-13 10:31:04 +02001605 if (err < 0) {
1606 free_netdev(dev);
1607 return ERR_PTR(err);
1608 }
David Wragg7e059152016-02-10 00:05:58 +00001609
1610 /* openvswitch users expect packet sizes to be unrestricted,
1611 * so set the largest MTU we can.
1612 */
1613 err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
1614 if (err)
1615 goto out;
1616
Nicolas Dichtelda6f1da2016-06-13 10:31:06 +02001617 err = rtnl_configure_link(dev, NULL);
1618 if (err < 0)
1619 goto out;
1620
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001621 return dev;
1622out:
Nicolas Dichtel106da662016-06-13 10:31:04 +02001623 ip_tunnel_dellink(dev, &list_kill);
1624 unregister_netdevice_many(&list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001625 return ERR_PTR(err);
1626}
1627EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1628
Pravin B Shelarc5441932013-03-25 14:49:35 +00001629static int __net_init ipgre_tap_init_net(struct net *net)
1630{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001631 return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001632}
1633
Eric Dumazet64bc1782017-09-19 16:27:09 -07001634static void __net_exit ipgre_tap_exit_batch_net(struct list_head *list_net)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001635{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001636 ip_tunnel_delete_nets(list_net, gre_tap_net_id, &ipgre_tap_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001637}
1638
1639static struct pernet_operations ipgre_tap_net_ops = {
1640 .init = ipgre_tap_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001641 .exit_batch = ipgre_tap_exit_batch_net,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001642 .id = &gre_tap_net_id,
1643 .size = sizeof(struct ip_tunnel_net),
1644};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
William Tu84e54fe2017-08-22 09:40:28 -07001646static int __net_init erspan_init_net(struct net *net)
1647{
1648 return ip_tunnel_init_net(net, erspan_net_id,
1649 &erspan_link_ops, "erspan0");
1650}
1651
Eric Dumazet64bc1782017-09-19 16:27:09 -07001652static void __net_exit erspan_exit_batch_net(struct list_head *net_list)
William Tu84e54fe2017-08-22 09:40:28 -07001653{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001654 ip_tunnel_delete_nets(net_list, erspan_net_id, &erspan_link_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001655}
1656
1657static struct pernet_operations erspan_net_ops = {
1658 .init = erspan_init_net,
Eric Dumazet64bc1782017-09-19 16:27:09 -07001659 .exit_batch = erspan_exit_batch_net,
William Tu84e54fe2017-08-22 09:40:28 -07001660 .id = &erspan_net_id,
1661 .size = sizeof(struct ip_tunnel_net),
1662};
1663
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664static int __init ipgre_init(void)
1665{
1666 int err;
1667
Joe Perches058bd4d2012-03-11 18:36:11 +00001668 pr_info("GRE over IPv4 tunneling driver\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001670 err = register_pernet_device(&ipgre_net_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001671 if (err < 0)
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001672 return err;
1673
Pravin B Shelarc5441932013-03-25 14:49:35 +00001674 err = register_pernet_device(&ipgre_tap_net_ops);
1675 if (err < 0)
William Tue3d03282017-08-22 17:04:05 -07001676 goto pnet_tap_failed;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001677
William Tu84e54fe2017-08-22 09:40:28 -07001678 err = register_pernet_device(&erspan_net_ops);
1679 if (err < 0)
1680 goto pnet_erspan_failed;
1681
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001682 err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001683 if (err < 0) {
Joe Perches058bd4d2012-03-11 18:36:11 +00001684 pr_info("%s: can't add protocol\n", __func__);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001685 goto add_proto_failed;
1686 }
Pavel Emelyanov7daa0002008-04-16 01:10:05 -07001687
Herbert Xuc19e6542008-10-09 11:59:55 -07001688 err = rtnl_link_register(&ipgre_link_ops);
1689 if (err < 0)
1690 goto rtnl_link_failed;
1691
Herbert Xue1a80002008-10-09 12:00:17 -07001692 err = rtnl_link_register(&ipgre_tap_ops);
1693 if (err < 0)
1694 goto tap_ops_failed;
1695
William Tu84e54fe2017-08-22 09:40:28 -07001696 err = rtnl_link_register(&erspan_link_ops);
1697 if (err < 0)
1698 goto erspan_link_failed;
1699
Pravin B Shelarc5441932013-03-25 14:49:35 +00001700 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001701
William Tu84e54fe2017-08-22 09:40:28 -07001702erspan_link_failed:
1703 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xue1a80002008-10-09 12:00:17 -07001704tap_ops_failed:
1705 rtnl_link_unregister(&ipgre_link_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001706rtnl_link_failed:
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001707 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001708add_proto_failed:
William Tu84e54fe2017-08-22 09:40:28 -07001709 unregister_pernet_device(&erspan_net_ops);
1710pnet_erspan_failed:
Pravin B Shelarc5441932013-03-25 14:49:35 +00001711 unregister_pernet_device(&ipgre_tap_net_ops);
William Tue3d03282017-08-22 17:04:05 -07001712pnet_tap_failed:
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001713 unregister_pernet_device(&ipgre_net_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001714 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715}
1716
Alexey Kuznetsovdb445752005-07-30 17:46:44 -07001717static void __exit ipgre_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718{
Herbert Xue1a80002008-10-09 12:00:17 -07001719 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001720 rtnl_link_unregister(&ipgre_link_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001721 rtnl_link_unregister(&erspan_link_ops);
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001722 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001723 unregister_pernet_device(&ipgre_tap_net_ops);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001724 unregister_pernet_device(&ipgre_net_ops);
William Tu84e54fe2017-08-22 09:40:28 -07001725 unregister_pernet_device(&erspan_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726}
1727
1728module_init(ipgre_init);
1729module_exit(ipgre_fini);
1730MODULE_LICENSE("GPL");
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001731MODULE_ALIAS_RTNL_LINK("gre");
1732MODULE_ALIAS_RTNL_LINK("gretap");
William Tu84e54fe2017-08-22 09:40:28 -07001733MODULE_ALIAS_RTNL_LINK("erspan");
Vasiliy Kulikov8909c9a2011-03-02 00:33:13 +03001734MODULE_ALIAS_NETDEV("gre0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001735MODULE_ALIAS_NETDEV("gretap0");
William Tu84e54fe2017-08-22 09:40:28 -07001736MODULE_ALIAS_NETDEV("erspan0");