blob: 5b1481be028212cfb61735a2d8ff8fbccbee203f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09002 * Linux NET3: GRE over IP protocol decoder.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Joe Perchesafd465032012-03-12 07:03:32 +000013#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
Randy Dunlap4fc268d2006-01-11 12:17:47 -080015#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/module.h>
17#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <asm/uaccess.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/in.h>
24#include <linux/tcp.h>
25#include <linux/udp.h>
26#include <linux/if_arp.h>
Pravin B Shelar2e15ea32015-08-07 23:51:42 -070027#include <linux/if_vlan.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/init.h>
29#include <linux/in6.h>
30#include <linux/inetdevice.h>
31#include <linux/igmp.h>
32#include <linux/netfilter_ipv4.h>
Herbert Xue1a80002008-10-09 12:00:17 -070033#include <linux/etherdevice.h>
Kris Katterjohn46f25df2006-01-05 16:35:42 -080034#include <linux/if_ether.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/sock.h>
37#include <net/ip.h>
38#include <net/icmp.h>
39#include <net/protocol.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000040#include <net/ip_tunnels.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <net/arp.h>
42#include <net/checksum.h>
43#include <net/dsfield.h>
44#include <net/inet_ecn.h>
45#include <net/xfrm.h>
Pavel Emelyanov59a4c752008-04-16 01:08:53 -070046#include <net/net_namespace.h>
47#include <net/netns/generic.h>
Herbert Xuc19e6542008-10-09 11:59:55 -070048#include <net/rtnetlink.h>
Dmitry Kozlov00959ad2010-08-21 23:05:39 -070049#include <net/gre.h>
Pravin B Shelar2e15ea32015-08-07 23:51:42 -070050#include <net/dst_metadata.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052/*
53 Problems & solutions
54 --------------------
55
56 1. The most important issue is detecting local dead loops.
57 They would cause complete host lockup in transmit, which
58 would be "resolved" by stack overflow or, if queueing is enabled,
59 with infinite looping in net_bh.
60
61 We cannot track such dead loops during route installation,
62 it is infeasible task. The most general solutions would be
63 to keep skb->encapsulation counter (sort of local ttl),
Eric Dumazet6d0722a2010-09-29 23:35:10 -070064 and silently drop packet when it expires. It is a good
stephen hemmingerbff52852012-02-24 08:08:20 +000065 solution, but it supposes maintaining new variable in ALL
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 skb, even if no tunneling is used.
67
Eric Dumazet6d0722a2010-09-29 23:35:10 -070068 Current solution: xmit_recursion breaks dead loops. This is a percpu
69 counter, since when we enter the first ndo_xmit(), cpu migration is
70 forbidden. We force an exit if this counter reaches RECURSION_LIMIT
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
72 2. Networking dead loops would not kill routers, but would really
73 kill network. IP hop limit plays role of "t->recursion" in this case,
74 if we copy it from packet being encapsulated to upper header.
75 It is very good solution, but it introduces two problems:
76
77 - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
78 do not work over tunnels.
79 - traceroute does not work. I planned to relay ICMP from tunnel,
80 so that this problem would be solved and traceroute output
81 would even more informative. This idea appeared to be wrong:
82 only Linux complies to rfc1812 now (yes, guys, Linux is the only
83 true router now :-)), all routers (at least, in neighbourhood of mine)
84 return only 8 bytes of payload. It is the end.
85
86 Hence, if we want that OSPF worked or traceroute said something reasonable,
87 we should search for another solution.
88
89 One of them is to parse packet trying to detect inner encapsulation
90 made by our node. It is difficult or even impossible, especially,
stephen hemmingerbff52852012-02-24 08:08:20 +000091 taking into account fragmentation. TO be short, ttl is not solution at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93 Current solution: The solution was UNEXPECTEDLY SIMPLE.
94 We force DF flag on tunnels with preconfigured hop limit,
95 that is ALL. :-) Well, it does not remove the problem completely,
96 but exponential growth of network traffic is changed to linear
97 (branches, that exceed pmtu are pruned) and tunnel mtu
stephen hemmingerbff52852012-02-24 08:08:20 +000098 rapidly degrades to value <68, where looping stops.
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 Yes, it is not good if there exists a router in the loop,
100 which does not force DF, even when encapsulating packets have DF set.
101 But it is not our problem! Nobody could accuse us, we made
102 all that we could make. Even if it is your gated who injected
103 fatal route to network, even if it were you who configured
104 fatal static route: you are innocent. :-)
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 Alexey Kuznetsov.
107 */
108
stephen hemmingereccc1bb2012-09-25 11:02:48 +0000109static bool log_ecn_error = true;
110module_param(log_ecn_error, bool, 0644);
111MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
112
Herbert Xuc19e6542008-10-09 11:59:55 -0700113static struct rtnl_link_ops ipgre_link_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114static int ipgre_tunnel_init(struct net_device *dev);
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700115
Eric Dumazetf99189b2009-11-17 10:42:49 +0000116static int ipgre_net_id __read_mostly;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000117static int gre_tap_net_id __read_mostly;
Pavel Emelyanoveb8ce742008-04-16 01:10:26 -0700118
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700119static void ipgre_err(struct sk_buff *skb, u32 info,
120 const struct tnl_ptk_info *tpi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Pravin B Shelarc5441932013-03-25 14:49:35 +0000123 /* All the routers (except for Linux) return only
124 8 bytes of packet payload. It means, that precise relaying of
125 ICMP in the real Internet is absolutely infeasible.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Pravin B Shelarc5441932013-03-25 14:49:35 +0000127 Moreover, Cisco "wise men" put GRE key to the third word
128 in GRE header. It makes impossible maintaining even soft
129 state for keyed GRE tunnels with enabled checksum. Tell
130 them "thank you".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Pravin B Shelarc5441932013-03-25 14:49:35 +0000132 Well, I wonder, rfc1812 was written by Cisco employee,
133 what the hell these idiots break standards established
134 by themselves???
135 */
136 struct net *net = dev_net(skb->dev);
137 struct ip_tunnel_net *itn;
Eric Dumazet96f5a842013-05-18 08:36:03 +0000138 const struct iphdr *iph;
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300139 const int type = icmp_hdr(skb)->type;
140 const int code = icmp_hdr(skb)->code;
Eric Dumazet20e19542016-06-18 21:52:06 -0700141 unsigned int data_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 struct ip_tunnel *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 switch (type) {
145 default:
146 case ICMP_PARAMETERPROB:
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700147 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
149 case ICMP_DEST_UNREACH:
150 switch (code) {
151 case ICMP_SR_FAILED:
152 case ICMP_PORT_UNREACH:
153 /* Impossible event. */
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700154 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 default:
156 /* All others are translated to HOST_UNREACH.
157 rfc2003 contains "deep thoughts" about NET_UNREACH,
158 I believe they are just ether pollution. --ANK
159 */
160 break;
161 }
162 break;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 case ICMP_TIME_EXCEEDED:
165 if (code != ICMP_EXC_TTL)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700166 return;
Eric Dumazet20e19542016-06-18 21:52:06 -0700167 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 break;
David S. Miller55be7a92012-07-11 21:27:49 -0700169
170 case ICMP_REDIRECT:
171 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 }
173
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700174 if (tpi->proto == htons(ETH_P_TEB))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000175 itn = net_generic(net, gre_tap_net_id);
176 else
177 itn = net_generic(net, ipgre_net_id);
178
Duan Jiongc0c0c502014-01-28 11:49:43 +0800179 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700180 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
181 iph->daddr, iph->saddr, tpi->key);
stephen hemmingerd2083282012-09-24 18:12:23 +0000182
Ian Morris51456b22015-04-03 09:17:26 +0100183 if (!t)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700184 return;
David S. Miller36393392012-06-14 22:21:46 -0700185
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700186#if IS_ENABLED(CONFIG_IPV6)
187 if (tpi->proto == htons(ETH_P_IPV6) &&
Eric Dumazet20e19542016-06-18 21:52:06 -0700188 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
189 type, data_len))
Eric Dumazet9b8c6d72016-06-18 21:52:05 -0700190 return;
191#endif
192
David S. Miller36393392012-06-14 22:21:46 -0700193 if (t->parms.iph.daddr == 0 ||
Joe Perchesf97c1e02007-12-16 13:45:43 -0800194 ipv4_is_multicast(t->parms.iph.daddr))
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700195 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700198 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Wei Yongjunda6185d82009-02-24 23:34:48 -0800200 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 t->err_count++;
202 else
203 t->err_count = 1;
204 t->err_time = jiffies;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700205}
206
207static void gre_err(struct sk_buff *skb, u32 info)
208{
209 /* All the routers (except for Linux) return only
210 * 8 bytes of packet payload. It means, that precise relaying of
211 * ICMP in the real Internet is absolutely infeasible.
212 *
213 * Moreover, Cisco "wise men" put GRE key to the third word
214 * in GRE header. It makes impossible maintaining even soft
215 * state for keyed
216 * GRE tunnels with enabled checksum. Tell them "thank you".
217 *
218 * Well, I wonder, rfc1812 was written by Cisco employee,
219 * what the hell these idiots break standards established
220 * by themselves???
221 */
222
Eric Dumazete5826152016-06-15 06:24:00 -0700223 const struct iphdr *iph = (struct iphdr *)skb->data;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700224 const int type = icmp_hdr(skb)->type;
225 const int code = icmp_hdr(skb)->code;
226 struct tnl_ptk_info tpi;
227 bool csum_err = false;
228
Eric Dumazete5826152016-06-15 06:24:00 -0700229 if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP),
230 iph->ihl * 4) < 0) {
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700231 if (!csum_err) /* ignore csum errors. */
232 return;
233 }
234
235 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
236 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
237 skb->dev->ifindex, 0, IPPROTO_GRE, 0);
238 return;
239 }
240 if (type == ICMP_REDIRECT) {
241 ipv4_redirect(skb, dev_net(skb->dev), skb->dev->ifindex, 0,
242 IPPROTO_GRE, 0);
243 return;
244 }
245
246 ipgre_err(skb, info, &tpi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247}
248
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700249static __be64 key_to_tunnel_id(__be32 key)
250{
251#ifdef __BIG_ENDIAN
252 return (__force __be64)((__force u32)key);
253#else
254 return (__force __be64)((__force u64)key << 32);
255#endif
256}
257
258/* Returns the least-significant 32 bits of a __be64. */
259static __be32 tunnel_id_to_key(__be64 x)
260{
261#ifdef __BIG_ENDIAN
262 return (__force __be32)x;
263#else
264 return (__force __be32)((__force u64)x >> 32);
265#endif
266}
267
Jiri Benc125372f2016-05-03 17:10:08 +0200268static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
269 struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700271 struct metadata_dst *tun_dst = NULL;
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000272 const struct iphdr *iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 struct ip_tunnel *tunnel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700275 iph = ip_hdr(skb);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700276 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
277 iph->saddr, iph->daddr, tpi->key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
stephen hemmingerd2083282012-09-24 18:12:23 +0000279 if (tunnel) {
Jiri Benc125372f2016-05-03 17:10:08 +0200280 if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
281 raw_proto, false) < 0)
Jiri Benc244a7972016-05-03 17:10:07 +0200282 goto drop;
283
Jiri Bence271c7b2016-05-11 15:53:57 +0200284 if (tunnel->dev->type != ARPHRD_NONE)
285 skb_pop_mac_header(skb);
286 else
287 skb_reset_mac_header(skb);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700288 if (tunnel->collect_md) {
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700289 __be16 flags;
290 __be64 tun_id;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700291
Pravin B Shelarc29a70d2015-08-26 23:46:50 -0700292 flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
293 tun_id = key_to_tunnel_id(tpi->key);
294 tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700295 if (!tun_dst)
296 return PACKET_REJECT;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700297 }
298
299 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
Pravin B Shelarbda7bb42013-06-17 17:49:38 -0700300 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 }
Jiri Benc125372f2016-05-03 17:10:08 +0200302 return PACKET_NEXT;
Jiri Benc244a7972016-05-03 17:10:07 +0200303
304drop:
305 kfree_skb(skb);
306 return PACKET_RCVD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}
308
Jiri Benc125372f2016-05-03 17:10:08 +0200309static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
310 int hdr_len)
311{
312 struct net *net = dev_net(skb->dev);
313 struct ip_tunnel_net *itn;
314 int res;
315
316 if (tpi->proto == htons(ETH_P_TEB))
317 itn = net_generic(net, gre_tap_net_id);
318 else
319 itn = net_generic(net, ipgre_net_id);
320
321 res = __ipgre_rcv(skb, tpi, itn, hdr_len, false);
322 if (res == PACKET_NEXT && tpi->proto == htons(ETH_P_TEB)) {
323 /* ipgre tunnels in collect metadata mode should receive
324 * also ETH_P_TEB traffic.
325 */
326 itn = net_generic(net, ipgre_net_id);
327 res = __ipgre_rcv(skb, tpi, itn, hdr_len, true);
328 }
329 return res;
330}
331
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700332static int gre_rcv(struct sk_buff *skb)
333{
334 struct tnl_ptk_info tpi;
335 bool csum_err = false;
Tom Herbert95f5c642016-04-29 17:12:16 -0700336 int hdr_len;
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700337
338#ifdef CONFIG_NET_IPGRE_BROADCAST
339 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
340 /* Looped back packet, drop it! */
341 if (rt_is_output_route(skb_rtable(skb)))
342 goto drop;
343 }
344#endif
345
Eric Dumazete5826152016-06-15 06:24:00 -0700346 hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0);
Jiri Bencf132ae72016-05-03 15:00:21 +0200347 if (hdr_len < 0)
Tom Herbert95f5c642016-04-29 17:12:16 -0700348 goto drop;
349
Jiri Benc244a7972016-05-03 17:10:07 +0200350 if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700351 return 0;
352
353 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
354drop:
355 kfree_skb(skb);
356 return 0;
357}
358
Pravin B Shelarc5441932013-03-25 14:49:35 +0000359static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
360 const struct iphdr *tnl_params,
361 __be16 proto)
362{
363 struct ip_tunnel *tunnel = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000364
Pravin B Shelarc5441932013-03-25 14:49:35 +0000365 if (tunnel->parms.o_flags & TUNNEL_SEQ)
366 tunnel->o_seqno++;
Eric Dumazetcef401d2013-01-25 20:34:37 +0000367
Pravin B Shelarc5441932013-03-25 14:49:35 +0000368 /* Push GRE header. */
Tom Herbert182a3522016-04-29 17:12:19 -0700369 gre_build_header(skb, tunnel->tun_hlen,
370 tunnel->parms.o_flags, proto, tunnel->parms.o_key,
371 htonl(tunnel->o_seqno));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700373 skb_set_inner_protocol(skb, proto);
Nicolas Dichtelbf3d6a82013-05-27 23:48:15 +0000374 ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375}
376
Alexander Duyckaed069d2016-04-14 15:33:37 -0400377static int gre_handle_offloads(struct sk_buff *skb, bool csum)
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700378{
Edward Cree6fa79662016-02-11 21:02:31 +0000379 return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -0700380}
381
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700382static struct rtable *gre_get_rt(struct sk_buff *skb,
383 struct net_device *dev,
384 struct flowi4 *fl,
385 const struct ip_tunnel_key *key)
386{
387 struct net *net = dev_net(dev);
388
389 memset(fl, 0, sizeof(*fl));
390 fl->daddr = key->u.ipv4.dst;
391 fl->saddr = key->u.ipv4.src;
392 fl->flowi4_tos = RT_TOS(key->tos);
393 fl->flowi4_mark = skb->mark;
394 fl->flowi4_proto = IPPROTO_GRE;
395
396 return ip_route_output_key(net, fl);
397}
398
Jiri Benc20907142016-04-27 11:29:07 +0200399static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
400 __be16 proto)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700401{
402 struct ip_tunnel_info *tun_info;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700403 const struct ip_tunnel_key *key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100404 struct rtable *rt = NULL;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700405 struct flowi4 fl;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700406 int min_headroom;
407 int tunnel_hlen;
408 __be16 df, flags;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100409 bool use_cache;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700410 int err;
411
Jiri Benc61adedf2015-08-20 13:56:25 +0200412 tun_info = skb_tunnel_info(skb);
Jiri Benc7f9562a2015-08-28 20:48:20 +0200413 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
414 ip_tunnel_info_af(tun_info) != AF_INET))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700415 goto err_free_skb;
416
417 key = &tun_info->key;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100418 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
419 if (use_cache)
420 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
Paolo Abeni3c1cb4d2016-02-12 15:43:59 +0100421 if (!rt) {
422 rt = gre_get_rt(skb, dev, &fl, key);
423 if (IS_ERR(rt))
424 goto err_free_skb;
Daniel Borkmanndb3c6132016-03-04 15:15:07 +0100425 if (use_cache)
Paolo Abeni3c1cb4d2016-02-12 15:43:59 +0100426 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
427 fl.saddr);
428 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700429
Tom Herbert95f5c642016-04-29 17:12:16 -0700430 tunnel_hlen = gre_calc_hlen(key->tun_flags);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700431
432 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
433 + tunnel_hlen + sizeof(struct iphdr);
434 if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
435 int head_delta = SKB_DATA_ALIGN(min_headroom -
436 skb_headroom(skb) +
437 16);
438 err = pskb_expand_head(skb, max_t(int, head_delta, 0),
439 0, GFP_ATOMIC);
440 if (unlikely(err))
441 goto err_free_rt;
442 }
443
444 /* Push Tunnel header. */
Alexander Duyckaed069d2016-04-14 15:33:37 -0400445 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700446 goto err_free_rt;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700447
448 flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
David S. Millercba653212016-05-04 00:52:29 -0400449 gre_build_header(skb, tunnel_hlen, flags, proto,
Tom Herbert182a3522016-04-29 17:12:19 -0700450 tunnel_id_to_key(tun_info->key.tun_id), 0);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700451
452 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
Pravin B Shelar039f5062015-12-24 14:34:54 -0800453
454 iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
455 key->tos, key->ttl, df, false);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700456 return;
457
458err_free_rt:
459 ip_rt_put(rt);
460err_free_skb:
461 kfree_skb(skb);
462 dev->stats.tx_dropped++;
463}
464
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700465static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
466{
467 struct ip_tunnel_info *info = skb_tunnel_info(skb);
468 struct rtable *rt;
469 struct flowi4 fl4;
470
471 if (ip_tunnel_info_af(info) != AF_INET)
472 return -EINVAL;
473
474 rt = gre_get_rt(skb, dev, &fl4, &info->key);
475 if (IS_ERR(rt))
476 return PTR_ERR(rt);
477
478 ip_rt_put(rt);
479 info->key.u.ipv4.src = fl4.saddr;
480 return 0;
481}
482
Pravin B Shelarc5441932013-03-25 14:49:35 +0000483static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
484 struct net_device *dev)
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800485{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000486 struct ip_tunnel *tunnel = netdev_priv(dev);
487 const struct iphdr *tnl_params;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800488
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700489 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200490 gre_fb_xmit(skb, dev, skb->protocol);
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700491 return NETDEV_TX_OK;
492 }
493
Pravin B Shelarc5441932013-03-25 14:49:35 +0000494 if (dev->header_ops) {
495 /* Need space for new headers */
496 if (skb_cow_head(skb, dev->needed_headroom -
Chen Gang2bac7cb2013-04-22 20:45:42 +0000497 (tunnel->hlen + sizeof(struct iphdr))))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000498 goto free_skb;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800499
Pravin B Shelarc5441932013-03-25 14:49:35 +0000500 tnl_params = (const struct iphdr *)skb->data;
Eric Dumazete985aad2010-09-27 03:57:11 +0000501
Pravin B Shelarc5441932013-03-25 14:49:35 +0000502 /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
503 * to gre header.
504 */
505 skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
Timo Teräs8a0033a2014-12-15 09:24:13 +0200506 skb_reset_mac_header(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000507 } else {
508 if (skb_cow_head(skb, dev->needed_headroom))
509 goto free_skb;
Herbert Xue1a80002008-10-09 12:00:17 -0700510
Pravin B Shelarc5441932013-03-25 14:49:35 +0000511 tnl_params = &tunnel->parms.iph;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800512 }
513
Alexander Duyckaed069d2016-04-14 15:33:37 -0400514 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
515 goto free_skb;
Timo Teräs8a0033a2014-12-15 09:24:13 +0200516
Pravin B Shelarc5441932013-03-25 14:49:35 +0000517 __gre_xmit(skb, dev, tnl_params, skb->protocol);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000518 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800519
Pravin B Shelarc5441932013-03-25 14:49:35 +0000520free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800521 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000522 dev->stats.tx_dropped++;
523 return NETDEV_TX_OK;
Michal Schmidtee34c1e2007-12-13 09:46:32 -0800524}
525
Pravin B Shelarc5441932013-03-25 14:49:35 +0000526static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
527 struct net_device *dev)
528{
529 struct ip_tunnel *tunnel = netdev_priv(dev);
530
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700531 if (tunnel->collect_md) {
Jiri Benc20907142016-04-27 11:29:07 +0200532 gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700533 return NETDEV_TX_OK;
534 }
535
Alexander Duyckaed069d2016-04-14 15:33:37 -0400536 if (gre_handle_offloads(skb, !!(tunnel->parms.o_flags & TUNNEL_CSUM)))
537 goto free_skb;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000538
539 if (skb_cow_head(skb, dev->needed_headroom))
540 goto free_skb;
541
542 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000543 return NETDEV_TX_OK;
544
545free_skb:
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800546 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000547 dev->stats.tx_dropped++;
548 return NETDEV_TX_OK;
549}
550
551static int ipgre_tunnel_ioctl(struct net_device *dev,
552 struct ifreq *ifr, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553{
Tom Herbert4565e992014-09-17 12:26:01 -0700554 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 struct ip_tunnel_parm p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
Pravin B Shelarc5441932013-03-25 14:49:35 +0000557 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
558 return -EFAULT;
Cong Wang6c734fb2013-06-29 12:02:59 +0800559 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
560 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
561 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
562 ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
563 return -EINVAL;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000564 }
565 p.i_flags = gre_flags_to_tnl_flags(p.i_flags);
566 p.o_flags = gre_flags_to_tnl_flags(p.o_flags);
567
568 err = ip_tunnel_ioctl(dev, &p, cmd);
569 if (err)
570 return err;
571
Tom Herbert95f5c642016-04-29 17:12:16 -0700572 p.i_flags = gre_tnl_flags_to_gre_flags(p.i_flags);
573 p.o_flags = gre_tnl_flags_to_gre_flags(p.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000574
575 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
576 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 return 0;
578}
579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580/* Nice toy. Unfortunately, useless in real life :-)
581 It allows to construct virtual multiprotocol broadcast "LAN"
582 over the Internet, provided multicast routing is tuned.
583
584
585 I have no idea was this bicycle invented before me,
586 so that I had to set ARPHRD_IPGRE to a random value.
587 I have an impression, that Cisco could make something similar,
588 but this feature is apparently missing in IOS<=11.2(8).
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
591 with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
592
593 ping -t 255 224.66.66.66
594
595 If nobody answers, mbone does not work.
596
597 ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
598 ip addr add 10.66.66.<somewhat>/24 dev Universe
599 ifconfig Universe up
600 ifconfig Universe add fe80::<Your_real_addr>/10
601 ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
602 ftp 10.66.66.66
603 ...
604 ftp fec0:6666:6666::193.233.7.65
605 ...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700607static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
608 unsigned short type,
Eric Dumazet15078502010-09-15 11:07:53 +0000609 const void *daddr, const void *saddr, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610{
Patrick McHardy2941a482006-01-08 22:05:26 -0800611 struct ip_tunnel *t = netdev_priv(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000612 struct iphdr *iph;
613 struct gre_base_hdr *greh;
614
615 iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
616 greh = (struct gre_base_hdr *)(iph+1);
Tom Herbert95f5c642016-04-29 17:12:16 -0700617 greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000618 greh->protocol = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
620 memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Pravin B Shelarc5441932013-03-25 14:49:35 +0000622 /* Set the source hardware address. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 if (saddr)
624 memcpy(&iph->saddr, saddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000625 if (daddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 memcpy(&iph->daddr, daddr, 4);
Timo Teräs6d55cb92010-03-03 04:01:13 +0000627 if (iph->daddr)
Timo Teräs77a482b2013-08-06 13:45:43 +0300628 return t->hlen + sizeof(*iph);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900629
Pravin B Shelarc5441932013-03-25 14:49:35 +0000630 return -(t->hlen + sizeof(*iph));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631}
632
Timo Teras6a5f44d2007-10-23 20:31:53 -0700633static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
634{
Eric Dumazetb71d1d42011-04-22 04:53:02 +0000635 const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb);
Timo Teras6a5f44d2007-10-23 20:31:53 -0700636 memcpy(haddr, &iph->saddr, 4);
637 return 4;
638}
639
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700640static const struct header_ops ipgre_header_ops = {
641 .create = ipgre_header,
Timo Teras6a5f44d2007-10-23 20:31:53 -0700642 .parse = ipgre_header_parse,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700643};
644
Timo Teras6a5f44d2007-10-23 20:31:53 -0700645#ifdef CONFIG_NET_IPGRE_BROADCAST
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646static int ipgre_open(struct net_device *dev)
647{
Patrick McHardy2941a482006-01-08 22:05:26 -0800648 struct ip_tunnel *t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
Joe Perchesf97c1e02007-12-16 13:45:43 -0800650 if (ipv4_is_multicast(t->parms.iph.daddr)) {
David S. Millercbb1e852011-05-04 12:33:34 -0700651 struct flowi4 fl4;
652 struct rtable *rt;
Eric Dumazete985aad2010-09-27 03:57:11 +0000653
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200654 rt = ip_route_output_gre(t->net, &fl4,
David S. Millercbb1e852011-05-04 12:33:34 -0700655 t->parms.iph.daddr,
656 t->parms.iph.saddr,
657 t->parms.o_key,
658 RT_TOS(t->parms.iph.tos),
659 t->parms.link);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800660 if (IS_ERR(rt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 return -EADDRNOTAVAIL;
Changli Gaod8d1f302010-06-10 23:31:35 -0700662 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 ip_rt_put(rt);
Ian Morris51456b22015-04-03 09:17:26 +0100664 if (!__in_dev_get_rtnl(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 return -EADDRNOTAVAIL;
666 t->mlink = dev->ifindex;
Herbert Xue5ed6392005-10-03 14:35:55 -0700667 ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 }
669 return 0;
670}
671
672static int ipgre_close(struct net_device *dev)
673{
Patrick McHardy2941a482006-01-08 22:05:26 -0800674 struct ip_tunnel *t = netdev_priv(dev);
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800675
Joe Perchesf97c1e02007-12-16 13:45:43 -0800676 if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
Denis V. Lunev7fee0ca2008-01-21 17:32:38 -0800677 struct in_device *in_dev;
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200678 in_dev = inetdev_by_index(t->net, t->mlink);
Eric Dumazet8723e1b2010-10-19 00:39:26 +0000679 if (in_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 ip_mc_dec_group(in_dev, t->parms.iph.daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 }
682 return 0;
683}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684#endif
685
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800686static const struct net_device_ops ipgre_netdev_ops = {
687 .ndo_init = ipgre_tunnel_init,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000688 .ndo_uninit = ip_tunnel_uninit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800689#ifdef CONFIG_NET_IPGRE_BROADCAST
690 .ndo_open = ipgre_open,
691 .ndo_stop = ipgre_close,
692#endif
Pravin B Shelarc5441932013-03-25 14:49:35 +0000693 .ndo_start_xmit = ipgre_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800694 .ndo_do_ioctl = ipgre_tunnel_ioctl,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000695 .ndo_change_mtu = ip_tunnel_change_mtu,
696 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200697 .ndo_get_iflink = ip_tunnel_get_iflink,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800698};
699
Eric Dumazet6b78f162012-09-13 21:25:33 +0000700#define GRE_FEATURES (NETIF_F_SG | \
701 NETIF_F_FRAGLIST | \
702 NETIF_F_HIGHDMA | \
703 NETIF_F_HW_CSUM)
704
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705static void ipgre_tunnel_setup(struct net_device *dev)
706{
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800707 dev->netdev_ops = &ipgre_netdev_ops;
Nicolas Dichtel5a455272014-04-11 15:51:18 +0200708 dev->type = ARPHRD_IPGRE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000709 ip_tunnel_setup(dev, ipgre_net_id);
710}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
Pravin B Shelarc5441932013-03-25 14:49:35 +0000712static void __gre_tunnel_init(struct net_device *dev)
713{
714 struct ip_tunnel *tunnel;
Tom Herbert4565e992014-09-17 12:26:01 -0700715 int t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000716
717 tunnel = netdev_priv(dev);
Tom Herbert95f5c642016-04-29 17:12:16 -0700718 tunnel->tun_hlen = gre_calc_hlen(tunnel->parms.o_flags);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000719 tunnel->parms.iph.protocol = IPPROTO_GRE;
720
Tom Herbert4565e992014-09-17 12:26:01 -0700721 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
722
723 t_hlen = tunnel->hlen + sizeof(struct iphdr);
724
725 dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
726 dev->mtu = ETH_DATA_LEN - t_hlen - 4;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000727
Nicolas Dichtelb57708a2014-04-22 10:15:23 +0200728 dev->features |= GRE_FEATURES;
Eric Dumazet6b78f162012-09-13 21:25:33 +0000729 dev->hw_features |= GRE_FEATURES;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000730
731 if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
Alexander Duycka0ca1532016-04-05 09:13:39 -0700732 /* TCP offload with GRE SEQ is not supported, nor
733 * can we support 2 levels of outer headers requiring
734 * an update.
735 */
736 if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
737 (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
738 dev->features |= NETIF_F_GSO_SOFTWARE;
739 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
740 }
741
Pravin B Shelarc5441932013-03-25 14:49:35 +0000742 /* Can use a lockless transmit, unless we generate
743 * output sequences
744 */
745 dev->features |= NETIF_F_LLTX;
746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747}
748
749static int ipgre_tunnel_init(struct net_device *dev)
750{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000751 struct ip_tunnel *tunnel = netdev_priv(dev);
752 struct iphdr *iph = &tunnel->parms.iph;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753
Pravin B Shelarc5441932013-03-25 14:49:35 +0000754 __gre_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755
Pravin B Shelarc5441932013-03-25 14:49:35 +0000756 memcpy(dev->dev_addr, &iph->saddr, 4);
757 memcpy(dev->broadcast, &iph->daddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
Pravin B Shelarc5441932013-03-25 14:49:35 +0000759 dev->flags = IFF_NOARP;
Eric Dumazet02875872014-10-05 18:38:35 -0700760 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000761 dev->addr_len = 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
Jiri Benca64b04d2016-04-27 11:29:06 +0200763 if (iph->daddr && !tunnel->collect_md) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764#ifdef CONFIG_NET_IPGRE_BROADCAST
Joe Perchesf97c1e02007-12-16 13:45:43 -0800765 if (ipv4_is_multicast(iph->daddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 if (!iph->saddr)
767 return -EINVAL;
768 dev->flags = IFF_BROADCAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700769 dev->header_ops = &ipgre_header_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 }
771#endif
Jiri Benca64b04d2016-04-27 11:29:06 +0200772 } else if (!tunnel->collect_md) {
Timo Teras6a5f44d2007-10-23 20:31:53 -0700773 dev->header_ops = &ipgre_header_ops;
Jiri Benca64b04d2016-04-27 11:29:06 +0200774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
Pravin B Shelarc5441932013-03-25 14:49:35 +0000776 return ip_tunnel_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777}
778
Pravin B Shelar9f57c672015-08-07 23:51:52 -0700779static const struct gre_protocol ipgre_protocol = {
780 .handler = gre_rcv,
781 .err_handler = gre_err,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782};
783
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000784static int __net_init ipgre_init_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700785{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000786 return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700787}
788
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000789static void __net_exit ipgre_exit_net(struct net *net)
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700790{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000791 struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200792 ip_tunnel_delete_net(itn, &ipgre_link_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700793}
794
795static struct pernet_operations ipgre_net_ops = {
796 .init = ipgre_init_net,
797 .exit = ipgre_exit_net,
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +0000798 .id = &ipgre_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000799 .size = sizeof(struct ip_tunnel_net),
Pavel Emelyanov59a4c752008-04-16 01:08:53 -0700800};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
Herbert Xuc19e6542008-10-09 11:59:55 -0700802static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
803{
804 __be16 flags;
805
806 if (!data)
807 return 0;
808
809 flags = 0;
810 if (data[IFLA_GRE_IFLAGS])
811 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
812 if (data[IFLA_GRE_OFLAGS])
813 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
814 if (flags & (GRE_VERSION|GRE_ROUTING))
815 return -EINVAL;
816
Jiri Benc946b6362016-04-27 14:08:01 +0200817 if (data[IFLA_GRE_COLLECT_METADATA] &&
818 data[IFLA_GRE_ENCAP_TYPE] &&
819 nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
820 return -EINVAL;
821
Herbert Xuc19e6542008-10-09 11:59:55 -0700822 return 0;
823}
824
Herbert Xue1a80002008-10-09 12:00:17 -0700825static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
826{
827 __be32 daddr;
828
829 if (tb[IFLA_ADDRESS]) {
830 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
831 return -EINVAL;
832 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
833 return -EADDRNOTAVAIL;
834 }
835
836 if (!data)
837 goto out;
838
839 if (data[IFLA_GRE_REMOTE]) {
840 memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
841 if (!daddr)
842 return -EINVAL;
843 }
844
845out:
846 return ipgre_tunnel_validate(tb, data);
847}
848
Philip Prindeville22a59be2016-06-14 15:53:02 -0600849static int ipgre_netlink_parms(struct net_device *dev,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700850 struct nlattr *data[],
851 struct nlattr *tb[],
852 struct ip_tunnel_parm *parms)
Herbert Xuc19e6542008-10-09 11:59:55 -0700853{
Philip Prindeville22a59be2016-06-14 15:53:02 -0600854 struct ip_tunnel *t = netdev_priv(dev);
855
Herbert Xu7bb82d92008-10-11 12:20:15 -0700856 memset(parms, 0, sizeof(*parms));
Herbert Xuc19e6542008-10-09 11:59:55 -0700857
858 parms->iph.protocol = IPPROTO_GRE;
859
860 if (!data)
Philip Prindeville22a59be2016-06-14 15:53:02 -0600861 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -0700862
863 if (data[IFLA_GRE_LINK])
864 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
865
866 if (data[IFLA_GRE_IFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +0000867 parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -0700868
869 if (data[IFLA_GRE_OFLAGS])
Pravin B Shelarc5441932013-03-25 14:49:35 +0000870 parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));
Herbert Xuc19e6542008-10-09 11:59:55 -0700871
872 if (data[IFLA_GRE_IKEY])
873 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
874
875 if (data[IFLA_GRE_OKEY])
876 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
877
878 if (data[IFLA_GRE_LOCAL])
Jiri Benc67b61f62015-03-29 16:59:26 +0200879 parms->iph.saddr = nla_get_in_addr(data[IFLA_GRE_LOCAL]);
Herbert Xuc19e6542008-10-09 11:59:55 -0700880
881 if (data[IFLA_GRE_REMOTE])
Jiri Benc67b61f62015-03-29 16:59:26 +0200882 parms->iph.daddr = nla_get_in_addr(data[IFLA_GRE_REMOTE]);
Herbert Xuc19e6542008-10-09 11:59:55 -0700883
884 if (data[IFLA_GRE_TTL])
885 parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
886
887 if (data[IFLA_GRE_TOS])
888 parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
889
Philip Prindeville22a59be2016-06-14 15:53:02 -0600890 if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) {
891 if (t->ignore_df)
892 return -EINVAL;
Herbert Xuc19e6542008-10-09 11:59:55 -0700893 parms->iph.frag_off = htons(IP_DF);
Philip Prindeville22a59be2016-06-14 15:53:02 -0600894 }
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700895
896 if (data[IFLA_GRE_COLLECT_METADATA]) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700897 t->collect_md = true;
Jiri Bence271c7b2016-05-11 15:53:57 +0200898 if (dev->type == ARPHRD_IPGRE)
899 dev->type = ARPHRD_NONE;
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700900 }
Philip Prindeville22a59be2016-06-14 15:53:02 -0600901
902 if (data[IFLA_GRE_IGNORE_DF]) {
903 if (nla_get_u8(data[IFLA_GRE_IGNORE_DF])
904 && (parms->iph.frag_off & htons(IP_DF)))
905 return -EINVAL;
906 t->ignore_df = !!nla_get_u8(data[IFLA_GRE_IGNORE_DF]);
907 }
908
909 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -0700910}
911
Tom Herbert4565e992014-09-17 12:26:01 -0700912/* This function returns true when ENCAP attributes are present in the nl msg */
913static bool ipgre_netlink_encap_parms(struct nlattr *data[],
914 struct ip_tunnel_encap *ipencap)
915{
916 bool ret = false;
917
918 memset(ipencap, 0, sizeof(*ipencap));
919
920 if (!data)
921 return ret;
922
923 if (data[IFLA_GRE_ENCAP_TYPE]) {
924 ret = true;
925 ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
926 }
927
928 if (data[IFLA_GRE_ENCAP_FLAGS]) {
929 ret = true;
930 ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
931 }
932
933 if (data[IFLA_GRE_ENCAP_SPORT]) {
934 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +0100935 ipencap->sport = nla_get_be16(data[IFLA_GRE_ENCAP_SPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -0700936 }
937
938 if (data[IFLA_GRE_ENCAP_DPORT]) {
939 ret = true;
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +0100940 ipencap->dport = nla_get_be16(data[IFLA_GRE_ENCAP_DPORT]);
Tom Herbert4565e992014-09-17 12:26:01 -0700941 }
942
943 return ret;
944}
945
Pravin B Shelarc5441932013-03-25 14:49:35 +0000946static int gre_tap_init(struct net_device *dev)
Herbert Xue1a80002008-10-09 12:00:17 -0700947{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000948 __gre_tunnel_init(dev);
stephen hemmingerbec94d42014-12-27 10:01:42 -0800949 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Herbert Xue1a80002008-10-09 12:00:17 -0700950
Pravin B Shelarc5441932013-03-25 14:49:35 +0000951 return ip_tunnel_init(dev);
Herbert Xue1a80002008-10-09 12:00:17 -0700952}
953
Pravin B Shelarc5441932013-03-25 14:49:35 +0000954static const struct net_device_ops gre_tap_netdev_ops = {
955 .ndo_init = gre_tap_init,
956 .ndo_uninit = ip_tunnel_uninit,
957 .ndo_start_xmit = gre_tap_xmit,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800958 .ndo_set_mac_address = eth_mac_addr,
959 .ndo_validate_addr = eth_validate_addr,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000960 .ndo_change_mtu = ip_tunnel_change_mtu,
961 .ndo_get_stats64 = ip_tunnel_get_stats64,
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200962 .ndo_get_iflink = ip_tunnel_get_iflink,
Pravin B Shelarfc4099f2015-10-22 18:17:16 -0700963 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
Stephen Hemmingerb8c26a32008-11-20 20:34:29 -0800964};
965
Herbert Xue1a80002008-10-09 12:00:17 -0700966static void ipgre_tap_setup(struct net_device *dev)
967{
Herbert Xue1a80002008-10-09 12:00:17 -0700968 ether_setup(dev);
Jiri Bencd13b1612016-02-17 15:32:53 +0100969 dev->netdev_ops = &gre_tap_netdev_ops;
970 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
971 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000972 ip_tunnel_setup(dev, gre_tap_net_id);
Herbert Xue1a80002008-10-09 12:00:17 -0700973}
974
Pravin B Shelarc5441932013-03-25 14:49:35 +0000975static int ipgre_newlink(struct net *src_net, struct net_device *dev,
976 struct nlattr *tb[], struct nlattr *data[])
Herbert Xuc19e6542008-10-09 11:59:55 -0700977{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000978 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -0700979 struct ip_tunnel_encap ipencap;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600980 int err;
Tom Herbert4565e992014-09-17 12:26:01 -0700981
982 if (ipgre_netlink_encap_parms(data, &ipencap)) {
983 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -0600984 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -0700985
986 if (err < 0)
987 return err;
988 }
Herbert Xuc19e6542008-10-09 11:59:55 -0700989
Philip Prindeville22a59be2016-06-14 15:53:02 -0600990 err = ipgre_netlink_parms(dev, data, tb, &p);
991 if (err < 0)
992 return err;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000993 return ip_tunnel_newlink(dev, tb, &p);
Herbert Xuc19e6542008-10-09 11:59:55 -0700994}
995
996static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
997 struct nlattr *data[])
998{
Herbert Xuc19e6542008-10-09 11:59:55 -0700999 struct ip_tunnel_parm p;
Tom Herbert4565e992014-09-17 12:26:01 -07001000 struct ip_tunnel_encap ipencap;
Philip Prindeville22a59be2016-06-14 15:53:02 -06001001 int err;
Tom Herbert4565e992014-09-17 12:26:01 -07001002
1003 if (ipgre_netlink_encap_parms(data, &ipencap)) {
1004 struct ip_tunnel *t = netdev_priv(dev);
Philip Prindeville22a59be2016-06-14 15:53:02 -06001005 err = ip_tunnel_encap_setup(t, &ipencap);
Tom Herbert4565e992014-09-17 12:26:01 -07001006
1007 if (err < 0)
1008 return err;
1009 }
Herbert Xuc19e6542008-10-09 11:59:55 -07001010
Philip Prindeville22a59be2016-06-14 15:53:02 -06001011 err = ipgre_netlink_parms(dev, data, tb, &p);
1012 if (err < 0)
1013 return err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001014 return ip_tunnel_changelink(dev, tb, &p);
Herbert Xuc19e6542008-10-09 11:59:55 -07001015}
1016
1017static size_t ipgre_get_size(const struct net_device *dev)
1018{
1019 return
1020 /* IFLA_GRE_LINK */
1021 nla_total_size(4) +
1022 /* IFLA_GRE_IFLAGS */
1023 nla_total_size(2) +
1024 /* IFLA_GRE_OFLAGS */
1025 nla_total_size(2) +
1026 /* IFLA_GRE_IKEY */
1027 nla_total_size(4) +
1028 /* IFLA_GRE_OKEY */
1029 nla_total_size(4) +
1030 /* IFLA_GRE_LOCAL */
1031 nla_total_size(4) +
1032 /* IFLA_GRE_REMOTE */
1033 nla_total_size(4) +
1034 /* IFLA_GRE_TTL */
1035 nla_total_size(1) +
1036 /* IFLA_GRE_TOS */
1037 nla_total_size(1) +
1038 /* IFLA_GRE_PMTUDISC */
1039 nla_total_size(1) +
Tom Herbert4565e992014-09-17 12:26:01 -07001040 /* IFLA_GRE_ENCAP_TYPE */
1041 nla_total_size(2) +
1042 /* IFLA_GRE_ENCAP_FLAGS */
1043 nla_total_size(2) +
1044 /* IFLA_GRE_ENCAP_SPORT */
1045 nla_total_size(2) +
1046 /* IFLA_GRE_ENCAP_DPORT */
1047 nla_total_size(2) +
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001048 /* IFLA_GRE_COLLECT_METADATA */
1049 nla_total_size(0) +
Philip Prindeville22a59be2016-06-14 15:53:02 -06001050 /* IFLA_GRE_IGNORE_DF */
1051 nla_total_size(1) +
Herbert Xuc19e6542008-10-09 11:59:55 -07001052 0;
1053}
1054
1055static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1056{
1057 struct ip_tunnel *t = netdev_priv(dev);
1058 struct ip_tunnel_parm *p = &t->parms;
1059
David S. Millerf3756b72012-04-01 20:39:02 -04001060 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
Tom Herbert95f5c642016-04-29 17:12:16 -07001061 nla_put_be16(skb, IFLA_GRE_IFLAGS,
1062 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
1063 nla_put_be16(skb, IFLA_GRE_OFLAGS,
1064 gre_tnl_flags_to_gre_flags(p->o_flags)) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001065 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1066 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
Jiri Benc930345e2015-03-29 16:59:25 +02001067 nla_put_in_addr(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
1068 nla_put_in_addr(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
David S. Millerf3756b72012-04-01 20:39:02 -04001069 nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
1070 nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
1071 nla_put_u8(skb, IFLA_GRE_PMTUDISC,
1072 !!(p->iph.frag_off & htons(IP_DF))))
1073 goto nla_put_failure;
Tom Herbert4565e992014-09-17 12:26:01 -07001074
1075 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
1076 t->encap.type) ||
Sabrina Dubroca3e97fa72015-02-06 17:22:22 +01001077 nla_put_be16(skb, IFLA_GRE_ENCAP_SPORT,
1078 t->encap.sport) ||
1079 nla_put_be16(skb, IFLA_GRE_ENCAP_DPORT,
1080 t->encap.dport) ||
Tom Herbert4565e992014-09-17 12:26:01 -07001081 nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
Tom Herberte1b2cb62014-11-05 16:49:38 -08001082 t->encap.flags))
Tom Herbert4565e992014-09-17 12:26:01 -07001083 goto nla_put_failure;
1084
Philip Prindeville22a59be2016-06-14 15:53:02 -06001085 if (nla_put_u8(skb, IFLA_GRE_IGNORE_DF, t->ignore_df))
1086 goto nla_put_failure;
1087
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001088 if (t->collect_md) {
1089 if (nla_put_flag(skb, IFLA_GRE_COLLECT_METADATA))
1090 goto nla_put_failure;
1091 }
1092
Herbert Xuc19e6542008-10-09 11:59:55 -07001093 return 0;
1094
1095nla_put_failure:
1096 return -EMSGSIZE;
1097}
1098
1099static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1100 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1101 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1102 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1103 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1104 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001105 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
1106 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
Herbert Xuc19e6542008-10-09 11:59:55 -07001107 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1108 [IFLA_GRE_TOS] = { .type = NLA_U8 },
1109 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
Tom Herbert4565e992014-09-17 12:26:01 -07001110 [IFLA_GRE_ENCAP_TYPE] = { .type = NLA_U16 },
1111 [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 },
1112 [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 },
1113 [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 },
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001114 [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG },
Philip Prindeville22a59be2016-06-14 15:53:02 -06001115 [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 },
Herbert Xuc19e6542008-10-09 11:59:55 -07001116};
1117
1118static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1119 .kind = "gre",
1120 .maxtype = IFLA_GRE_MAX,
1121 .policy = ipgre_policy,
1122 .priv_size = sizeof(struct ip_tunnel),
1123 .setup = ipgre_tunnel_setup,
1124 .validate = ipgre_tunnel_validate,
1125 .newlink = ipgre_newlink,
1126 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001127 .dellink = ip_tunnel_dellink,
Herbert Xuc19e6542008-10-09 11:59:55 -07001128 .get_size = ipgre_get_size,
1129 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001130 .get_link_net = ip_tunnel_get_link_net,
Herbert Xuc19e6542008-10-09 11:59:55 -07001131};
1132
Herbert Xue1a80002008-10-09 12:00:17 -07001133static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1134 .kind = "gretap",
1135 .maxtype = IFLA_GRE_MAX,
1136 .policy = ipgre_policy,
1137 .priv_size = sizeof(struct ip_tunnel),
1138 .setup = ipgre_tap_setup,
1139 .validate = ipgre_tap_validate,
1140 .newlink = ipgre_newlink,
1141 .changelink = ipgre_changelink,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001142 .dellink = ip_tunnel_dellink,
Herbert Xue1a80002008-10-09 12:00:17 -07001143 .get_size = ipgre_get_size,
1144 .fill_info = ipgre_fill_info,
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001145 .get_link_net = ip_tunnel_get_link_net,
Herbert Xue1a80002008-10-09 12:00:17 -07001146};
1147
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001148struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1149 u8 name_assign_type)
1150{
1151 struct nlattr *tb[IFLA_MAX + 1];
1152 struct net_device *dev;
Nicolas Dichtel106da662016-06-13 10:31:04 +02001153 LIST_HEAD(list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001154 struct ip_tunnel *t;
1155 int err;
1156
1157 memset(&tb, 0, sizeof(tb));
1158
1159 dev = rtnl_create_link(net, name, name_assign_type,
1160 &ipgre_tap_ops, tb);
1161 if (IS_ERR(dev))
1162 return dev;
1163
1164 /* Configure flow based GRE device. */
1165 t = netdev_priv(dev);
1166 t->collect_md = true;
1167
1168 err = ipgre_newlink(net, dev, tb, NULL);
Nicolas Dichtel106da662016-06-13 10:31:04 +02001169 if (err < 0) {
1170 free_netdev(dev);
1171 return ERR_PTR(err);
1172 }
David Wragg7e059152016-02-10 00:05:58 +00001173
1174 /* openvswitch users expect packet sizes to be unrestricted,
1175 * so set the largest MTU we can.
1176 */
1177 err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
1178 if (err)
1179 goto out;
1180
Nicolas Dichtelda6f1da2016-06-13 10:31:06 +02001181 err = rtnl_configure_link(dev, NULL);
1182 if (err < 0)
1183 goto out;
1184
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001185 return dev;
1186out:
Nicolas Dichtel106da662016-06-13 10:31:04 +02001187 ip_tunnel_dellink(dev, &list_kill);
1188 unregister_netdevice_many(&list_kill);
Pravin B Shelarb2acd1d2015-08-07 23:51:47 -07001189 return ERR_PTR(err);
1190}
1191EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
1192
Pravin B Shelarc5441932013-03-25 14:49:35 +00001193static int __net_init ipgre_tap_init_net(struct net *net)
1194{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001195 return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001196}
1197
1198static void __net_exit ipgre_tap_exit_net(struct net *net)
1199{
1200 struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001201 ip_tunnel_delete_net(itn, &ipgre_tap_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001202}
1203
1204static struct pernet_operations ipgre_tap_net_ops = {
1205 .init = ipgre_tap_init_net,
1206 .exit = ipgre_tap_exit_net,
1207 .id = &gre_tap_net_id,
1208 .size = sizeof(struct ip_tunnel_net),
1209};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211static int __init ipgre_init(void)
1212{
1213 int err;
1214
Joe Perches058bd4d2012-03-11 18:36:11 +00001215 pr_info("GRE over IPv4 tunneling driver\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Eric W. Biedermancfb8fbf2009-11-29 15:46:13 +00001217 err = register_pernet_device(&ipgre_net_ops);
Pavel Emelyanov59a4c752008-04-16 01:08:53 -07001218 if (err < 0)
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001219 return err;
1220
Pravin B Shelarc5441932013-03-25 14:49:35 +00001221 err = register_pernet_device(&ipgre_tap_net_ops);
1222 if (err < 0)
1223 goto pnet_tap_faied;
1224
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001225 err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001226 if (err < 0) {
Joe Perches058bd4d2012-03-11 18:36:11 +00001227 pr_info("%s: can't add protocol\n", __func__);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001228 goto add_proto_failed;
1229 }
Pavel Emelyanov7daa0002008-04-16 01:10:05 -07001230
Herbert Xuc19e6542008-10-09 11:59:55 -07001231 err = rtnl_link_register(&ipgre_link_ops);
1232 if (err < 0)
1233 goto rtnl_link_failed;
1234
Herbert Xue1a80002008-10-09 12:00:17 -07001235 err = rtnl_link_register(&ipgre_tap_ops);
1236 if (err < 0)
1237 goto tap_ops_failed;
1238
Pravin B Shelarc5441932013-03-25 14:49:35 +00001239 return 0;
Herbert Xuc19e6542008-10-09 11:59:55 -07001240
Herbert Xue1a80002008-10-09 12:00:17 -07001241tap_ops_failed:
1242 rtnl_link_unregister(&ipgre_link_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001243rtnl_link_failed:
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001244 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001245add_proto_failed:
Pravin B Shelarc5441932013-03-25 14:49:35 +00001246 unregister_pernet_device(&ipgre_tap_net_ops);
1247pnet_tap_faied:
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001248 unregister_pernet_device(&ipgre_net_ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001249 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250}
1251
Alexey Kuznetsovdb445752005-07-30 17:46:44 -07001252static void __exit ipgre_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253{
Herbert Xue1a80002008-10-09 12:00:17 -07001254 rtnl_link_unregister(&ipgre_tap_ops);
Herbert Xuc19e6542008-10-09 11:59:55 -07001255 rtnl_link_unregister(&ipgre_link_ops);
Pravin B Shelar9f57c672015-08-07 23:51:52 -07001256 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001257 unregister_pernet_device(&ipgre_tap_net_ops);
Alexey Dobriyanc2892f02010-02-16 07:57:44 +00001258 unregister_pernet_device(&ipgre_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259}
1260
1261module_init(ipgre_init);
1262module_exit(ipgre_fini);
1263MODULE_LICENSE("GPL");
Patrick McHardy4d74f8b2008-10-10 12:11:06 -07001264MODULE_ALIAS_RTNL_LINK("gre");
1265MODULE_ALIAS_RTNL_LINK("gretap");
Vasiliy Kulikov8909c9a2011-03-02 00:33:13 +03001266MODULE_ALIAS_NETDEV("gre0");
Pravin B Shelarc5441932013-03-25 14:49:35 +00001267MODULE_ALIAS_NETDEV("gretap0");