1c5441932SPravin B Shelar /* 2c5441932SPravin B Shelar * Copyright (c) 2013 Nicira, Inc. 3c5441932SPravin B Shelar * 4c5441932SPravin B Shelar * This program is free software; you can redistribute it and/or 5c5441932SPravin B Shelar * modify it under the terms of version 2 of the GNU General Public 6c5441932SPravin B Shelar * License as published by the Free Software Foundation. 7c5441932SPravin B Shelar * 8c5441932SPravin B Shelar * This program is distributed in the hope that it will be useful, but 9c5441932SPravin B Shelar * WITHOUT ANY WARRANTY; without even the implied warranty of 10c5441932SPravin B Shelar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11c5441932SPravin B Shelar * General Public License for more details. 12c5441932SPravin B Shelar * 13c5441932SPravin B Shelar * You should have received a copy of the GNU General Public License 14c5441932SPravin B Shelar * along with this program; if not, write to the Free Software 15c5441932SPravin B Shelar * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16c5441932SPravin B Shelar * 02110-1301, USA 17c5441932SPravin B Shelar */ 18c5441932SPravin B Shelar 19c5441932SPravin B Shelar #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20c5441932SPravin B Shelar 21c5441932SPravin B Shelar #include <linux/capability.h> 22c5441932SPravin B Shelar #include <linux/module.h> 23c5441932SPravin B Shelar #include <linux/types.h> 24c5441932SPravin B Shelar #include <linux/kernel.h> 25c5441932SPravin B Shelar #include <linux/slab.h> 26c5441932SPravin B Shelar #include <linux/uaccess.h> 27c5441932SPravin B Shelar #include <linux/skbuff.h> 28c5441932SPravin B Shelar #include <linux/netdevice.h> 29c5441932SPravin B Shelar #include <linux/in.h> 30c5441932SPravin B Shelar #include <linux/tcp.h> 31c5441932SPravin B Shelar #include <linux/udp.h> 32c5441932SPravin B Shelar #include <linux/if_arp.h> 33c5441932SPravin B Shelar #include <linux/init.h> 34c5441932SPravin B Shelar #include <linux/in6.h> 35c5441932SPravin B Shelar #include <linux/inetdevice.h> 36c5441932SPravin B Shelar #include <linux/igmp.h> 37c5441932SPravin B Shelar #include <linux/netfilter_ipv4.h> 38c5441932SPravin B Shelar #include <linux/etherdevice.h> 39c5441932SPravin B Shelar #include <linux/if_ether.h> 40c5441932SPravin B Shelar #include <linux/if_vlan.h> 41c5441932SPravin B Shelar #include <linux/rculist.h> 4227d79f3bSSachin Kamat #include <linux/err.h> 43c5441932SPravin B Shelar 44c5441932SPravin B Shelar #include <net/sock.h> 45c5441932SPravin B Shelar #include <net/ip.h> 46c5441932SPravin B Shelar #include <net/icmp.h> 47c5441932SPravin B Shelar #include <net/protocol.h> 48c5441932SPravin B Shelar #include <net/ip_tunnels.h> 49c5441932SPravin B Shelar #include <net/arp.h> 50c5441932SPravin B Shelar #include <net/checksum.h> 51c5441932SPravin B Shelar #include <net/dsfield.h> 52c5441932SPravin B Shelar #include <net/inet_ecn.h> 53c5441932SPravin B Shelar #include <net/xfrm.h> 54c5441932SPravin B Shelar #include <net/net_namespace.h> 55c5441932SPravin B Shelar #include <net/netns/generic.h> 56c5441932SPravin B Shelar #include <net/rtnetlink.h> 5756328486STom Herbert #include <net/udp.h> 58cfc7381bSAlexei Starovoitov #include <net/dst_metadata.h> 5963487babSTom Herbert 60c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6) 61c5441932SPravin B Shelar #include <net/ipv6.h> 62c5441932SPravin B Shelar #include <net/ip6_fib.h> 63c5441932SPravin B Shelar #include <net/ip6_route.h> 64c5441932SPravin B Shelar #endif 65c5441932SPravin B Shelar 66967680e0SDuan Jiong static unsigned int ip_tunnel_hash(__be32 key, __be32 remote) 67c5441932SPravin B Shelar { 68c5441932SPravin B Shelar return hash_32((__force u32)key ^ (__force u32)remote, 69c5441932SPravin B Shelar IP_TNL_HASH_BITS); 70c5441932SPravin B Shelar } 71c5441932SPravin B Shelar 72c5441932SPravin B Shelar static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, 73c5441932SPravin B Shelar __be16 flags, __be32 key) 74c5441932SPravin B Shelar { 75c5441932SPravin B Shelar if (p->i_flags & TUNNEL_KEY) { 76c5441932SPravin B Shelar if (flags & TUNNEL_KEY) 77c5441932SPravin B Shelar return key == p->i_key; 78c5441932SPravin B Shelar else 79c5441932SPravin B Shelar /* key expected, none present */ 80c5441932SPravin B Shelar return false; 81c5441932SPravin B Shelar } else 82c5441932SPravin B Shelar return !(flags & TUNNEL_KEY); 83c5441932SPravin B Shelar } 84c5441932SPravin B Shelar 85c5441932SPravin B Shelar /* Fallback tunnel: no source, no destination, no key, no options 86c5441932SPravin B Shelar 87c5441932SPravin B Shelar Tunnel hash table: 88c5441932SPravin B Shelar We require exact key match i.e. if a key is present in packet 89c5441932SPravin B Shelar it will match only tunnel with the same key; if it is not present, 90c5441932SPravin B Shelar it will match only keyless tunnel. 91c5441932SPravin B Shelar 92c5441932SPravin B Shelar All keysless packets, if not matched configured keyless tunnels 93c5441932SPravin B Shelar will match fallback tunnel. 94c5441932SPravin B Shelar Given src, dst and key, find appropriate for input tunnel. 95c5441932SPravin B Shelar */ 96c5441932SPravin B Shelar struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, 97c5441932SPravin B Shelar int link, __be16 flags, 98c5441932SPravin B Shelar __be32 remote, __be32 local, 99c5441932SPravin B Shelar __be32 key) 100c5441932SPravin B Shelar { 101c5441932SPravin B Shelar unsigned int hash; 102c5441932SPravin B Shelar struct ip_tunnel *t, *cand = NULL; 103c5441932SPravin B Shelar struct hlist_head *head; 104c5441932SPravin B Shelar 105967680e0SDuan Jiong hash = ip_tunnel_hash(key, remote); 106c5441932SPravin B Shelar head = &itn->tunnels[hash]; 107c5441932SPravin B Shelar 108c5441932SPravin B Shelar hlist_for_each_entry_rcu(t, head, hash_node) { 109c5441932SPravin B Shelar if (local != t->parms.iph.saddr || 110c5441932SPravin B Shelar remote != t->parms.iph.daddr || 111c5441932SPravin B Shelar !(t->dev->flags & IFF_UP)) 112c5441932SPravin B Shelar continue; 113c5441932SPravin B Shelar 114c5441932SPravin B Shelar if (!ip_tunnel_key_match(&t->parms, flags, key)) 115c5441932SPravin B Shelar continue; 116c5441932SPravin B Shelar 117c5441932SPravin B Shelar if (t->parms.link == link) 118c5441932SPravin B Shelar return t; 119c5441932SPravin B Shelar else 120c5441932SPravin B Shelar cand = t; 121c5441932SPravin B Shelar } 122c5441932SPravin B Shelar 123c5441932SPravin B Shelar hlist_for_each_entry_rcu(t, head, hash_node) { 124c5441932SPravin B Shelar if (remote != t->parms.iph.daddr || 125e0056593SDmitry Popov t->parms.iph.saddr != 0 || 126c5441932SPravin B Shelar !(t->dev->flags & IFF_UP)) 127c5441932SPravin B Shelar continue; 128c5441932SPravin B Shelar 129c5441932SPravin B Shelar if (!ip_tunnel_key_match(&t->parms, flags, key)) 130c5441932SPravin B Shelar continue; 131c5441932SPravin B Shelar 132c5441932SPravin B Shelar if (t->parms.link == link) 133c5441932SPravin B Shelar return t; 134c5441932SPravin B Shelar else if (!cand) 135c5441932SPravin B Shelar cand = t; 136c5441932SPravin B Shelar } 137c5441932SPravin B Shelar 138967680e0SDuan Jiong hash = ip_tunnel_hash(key, 0); 139c5441932SPravin B Shelar head = &itn->tunnels[hash]; 140c5441932SPravin B Shelar 141c5441932SPravin B Shelar hlist_for_each_entry_rcu(t, head, hash_node) { 142e0056593SDmitry Popov if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) && 143e0056593SDmitry Popov (local != t->parms.iph.daddr || !ipv4_is_multicast(local))) 144e0056593SDmitry Popov continue; 145e0056593SDmitry Popov 146e0056593SDmitry Popov if (!(t->dev->flags & IFF_UP)) 147c5441932SPravin B Shelar continue; 148c5441932SPravin B Shelar 149c5441932SPravin B Shelar if (!ip_tunnel_key_match(&t->parms, flags, key)) 150c5441932SPravin B Shelar continue; 151c5441932SPravin B Shelar 152c5441932SPravin B Shelar if (t->parms.link == link) 153c5441932SPravin B Shelar return t; 154c5441932SPravin B Shelar else if (!cand) 155c5441932SPravin B Shelar cand = t; 156c5441932SPravin B Shelar } 157c5441932SPravin B Shelar 158c5441932SPravin B Shelar if (flags & TUNNEL_NO_KEY) 159c5441932SPravin B Shelar goto skip_key_lookup; 160c5441932SPravin B Shelar 161c5441932SPravin B Shelar hlist_for_each_entry_rcu(t, head, hash_node) { 162c5441932SPravin B Shelar if (t->parms.i_key != key || 163e0056593SDmitry Popov t->parms.iph.saddr != 0 || 164e0056593SDmitry Popov t->parms.iph.daddr != 0 || 165c5441932SPravin B Shelar !(t->dev->flags & IFF_UP)) 166c5441932SPravin B Shelar continue; 167c5441932SPravin B Shelar 168c5441932SPravin B Shelar if (t->parms.link == link) 169c5441932SPravin B Shelar return t; 170c5441932SPravin B Shelar else if (!cand) 171c5441932SPravin B Shelar cand = t; 172c5441932SPravin B Shelar } 173c5441932SPravin B Shelar 174c5441932SPravin B Shelar skip_key_lookup: 175c5441932SPravin B Shelar if (cand) 176c5441932SPravin B Shelar return cand; 177c5441932SPravin B Shelar 1782e15ea39SPravin B Shelar t = rcu_dereference(itn->collect_md_tun); 179833a8b40SHaishuang Yan if (t && t->dev->flags & IFF_UP) 1802e15ea39SPravin B Shelar return t; 1812e15ea39SPravin B Shelar 182c5441932SPravin B Shelar if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP) 183c5441932SPravin B Shelar return netdev_priv(itn->fb_tunnel_dev); 184c5441932SPravin B Shelar 185c5441932SPravin B Shelar return NULL; 186c5441932SPravin B Shelar } 187c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_lookup); 188c5441932SPravin B Shelar 189c5441932SPravin B Shelar static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn, 190c5441932SPravin B Shelar struct ip_tunnel_parm *parms) 191c5441932SPravin B Shelar { 192c5441932SPravin B Shelar unsigned int h; 193c5441932SPravin B Shelar __be32 remote; 1946d608f06SSteffen Klassert __be32 i_key = parms->i_key; 195c5441932SPravin B Shelar 196c5441932SPravin B Shelar if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr)) 197c5441932SPravin B Shelar remote = parms->iph.daddr; 198c5441932SPravin B Shelar else 199c5441932SPravin B Shelar remote = 0; 200c5441932SPravin B Shelar 2016d608f06SSteffen Klassert if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI)) 2026d608f06SSteffen Klassert i_key = 0; 2036d608f06SSteffen Klassert 2046d608f06SSteffen Klassert h = ip_tunnel_hash(i_key, remote); 205c5441932SPravin B Shelar return &itn->tunnels[h]; 206c5441932SPravin B Shelar } 207c5441932SPravin B Shelar 208c5441932SPravin B Shelar static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t) 209c5441932SPravin B Shelar { 210c5441932SPravin B Shelar struct hlist_head *head = ip_bucket(itn, &t->parms); 211c5441932SPravin B Shelar 2122e15ea39SPravin B Shelar if (t->collect_md) 2132e15ea39SPravin B Shelar rcu_assign_pointer(itn->collect_md_tun, t); 214c5441932SPravin B Shelar hlist_add_head_rcu(&t->hash_node, head); 215c5441932SPravin B Shelar } 216c5441932SPravin B Shelar 2172e15ea39SPravin B Shelar static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t) 218c5441932SPravin B Shelar { 2192e15ea39SPravin B Shelar if (t->collect_md) 2202e15ea39SPravin B Shelar rcu_assign_pointer(itn->collect_md_tun, NULL); 221c5441932SPravin B Shelar hlist_del_init_rcu(&t->hash_node); 222c5441932SPravin B Shelar } 223c5441932SPravin B Shelar 224c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn, 225c5441932SPravin B Shelar struct ip_tunnel_parm *parms, 226c5441932SPravin B Shelar int type) 227c5441932SPravin B Shelar { 228c5441932SPravin B Shelar __be32 remote = parms->iph.daddr; 229c5441932SPravin B Shelar __be32 local = parms->iph.saddr; 230c5441932SPravin B Shelar __be32 key = parms->i_key; 2315ce54af1SDmitry Popov __be16 flags = parms->i_flags; 232c5441932SPravin B Shelar int link = parms->link; 233c5441932SPravin B Shelar struct ip_tunnel *t = NULL; 234c5441932SPravin B Shelar struct hlist_head *head = ip_bucket(itn, parms); 235c5441932SPravin B Shelar 236c5441932SPravin B Shelar hlist_for_each_entry_rcu(t, head, hash_node) { 237c5441932SPravin B Shelar if (local == t->parms.iph.saddr && 238c5441932SPravin B Shelar remote == t->parms.iph.daddr && 239c5441932SPravin B Shelar link == t->parms.link && 2405ce54af1SDmitry Popov type == t->dev->type && 2415ce54af1SDmitry Popov ip_tunnel_key_match(&t->parms, flags, key)) 242c5441932SPravin B Shelar break; 243c5441932SPravin B Shelar } 244c5441932SPravin B Shelar return t; 245c5441932SPravin B Shelar } 246c5441932SPravin B Shelar 247c5441932SPravin B Shelar static struct net_device *__ip_tunnel_create(struct net *net, 248c5441932SPravin B Shelar const struct rtnl_link_ops *ops, 249c5441932SPravin B Shelar struct ip_tunnel_parm *parms) 250c5441932SPravin B Shelar { 251c5441932SPravin B Shelar int err; 252c5441932SPravin B Shelar struct ip_tunnel *tunnel; 253c5441932SPravin B Shelar struct net_device *dev; 254c5441932SPravin B Shelar char name[IFNAMSIZ]; 255c5441932SPravin B Shelar 256c5441932SPravin B Shelar if (parms->name[0]) 257c5441932SPravin B Shelar strlcpy(name, parms->name, IFNAMSIZ); 258c5441932SPravin B Shelar else { 25954a5d382SPravin B Shelar if (strlen(ops->kind) > (IFNAMSIZ - 3)) { 260c5441932SPravin B Shelar err = -E2BIG; 261c5441932SPravin B Shelar goto failed; 262c5441932SPravin B Shelar } 263c5441932SPravin B Shelar strlcpy(name, ops->kind, IFNAMSIZ); 264c5441932SPravin B Shelar strncat(name, "%d", 2); 265c5441932SPravin B Shelar } 266c5441932SPravin B Shelar 267c5441932SPravin B Shelar ASSERT_RTNL(); 268c835a677STom Gundersen dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup); 269c5441932SPravin B Shelar if (!dev) { 270c5441932SPravin B Shelar err = -ENOMEM; 271c5441932SPravin B Shelar goto failed; 272c5441932SPravin B Shelar } 273c5441932SPravin B Shelar dev_net_set(dev, net); 274c5441932SPravin B Shelar 275c5441932SPravin B Shelar dev->rtnl_link_ops = ops; 276c5441932SPravin B Shelar 277c5441932SPravin B Shelar tunnel = netdev_priv(dev); 278c5441932SPravin B Shelar tunnel->parms = *parms; 2795e6700b3SNicolas Dichtel tunnel->net = net; 280c5441932SPravin B Shelar 281c5441932SPravin B Shelar err = register_netdevice(dev); 282c5441932SPravin B Shelar if (err) 283c5441932SPravin B Shelar goto failed_free; 284c5441932SPravin B Shelar 285c5441932SPravin B Shelar return dev; 286c5441932SPravin B Shelar 287c5441932SPravin B Shelar failed_free: 288c5441932SPravin B Shelar free_netdev(dev); 289c5441932SPravin B Shelar failed: 290c5441932SPravin B Shelar return ERR_PTR(err); 291c5441932SPravin B Shelar } 292c5441932SPravin B Shelar 2937d442fabSTom Herbert static inline void init_tunnel_flow(struct flowi4 *fl4, 294c5441932SPravin B Shelar int proto, 295c5441932SPravin B Shelar __be32 daddr, __be32 saddr, 2969830ad4cSCraig Gallek __be32 key, __u8 tos, int oif, 2979830ad4cSCraig Gallek __u32 mark) 298c5441932SPravin B Shelar { 299c5441932SPravin B Shelar memset(fl4, 0, sizeof(*fl4)); 300c5441932SPravin B Shelar fl4->flowi4_oif = oif; 301c5441932SPravin B Shelar fl4->daddr = daddr; 302c5441932SPravin B Shelar fl4->saddr = saddr; 303c5441932SPravin B Shelar fl4->flowi4_tos = tos; 304c5441932SPravin B Shelar fl4->flowi4_proto = proto; 305c5441932SPravin B Shelar fl4->fl4_gre_key = key; 3069830ad4cSCraig Gallek fl4->flowi4_mark = mark; 307c5441932SPravin B Shelar } 308c5441932SPravin B Shelar 309c5441932SPravin B Shelar static int ip_tunnel_bind_dev(struct net_device *dev) 310c5441932SPravin B Shelar { 311c5441932SPravin B Shelar struct net_device *tdev = NULL; 312c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 313c5441932SPravin B Shelar const struct iphdr *iph; 314c5441932SPravin B Shelar int hlen = LL_MAX_HEADER; 315c5441932SPravin B Shelar int mtu = ETH_DATA_LEN; 316c5441932SPravin B Shelar int t_hlen = tunnel->hlen + sizeof(struct iphdr); 317c5441932SPravin B Shelar 318c5441932SPravin B Shelar iph = &tunnel->parms.iph; 319c5441932SPravin B Shelar 320c5441932SPravin B Shelar /* Guess output device to choose reasonable mtu and needed_headroom */ 321c5441932SPravin B Shelar if (iph->daddr) { 322c5441932SPravin B Shelar struct flowi4 fl4; 323c5441932SPravin B Shelar struct rtable *rt; 324c5441932SPravin B Shelar 3257d442fabSTom Herbert init_tunnel_flow(&fl4, iph->protocol, iph->daddr, 3267d442fabSTom Herbert iph->saddr, tunnel->parms.o_key, 3279830ad4cSCraig Gallek RT_TOS(iph->tos), tunnel->parms.link, 3289830ad4cSCraig Gallek tunnel->fwmark); 3297d442fabSTom Herbert rt = ip_route_output_key(tunnel->net, &fl4); 3307d442fabSTom Herbert 331c5441932SPravin B Shelar if (!IS_ERR(rt)) { 332c5441932SPravin B Shelar tdev = rt->dst.dev; 333c5441932SPravin B Shelar ip_rt_put(rt); 334c5441932SPravin B Shelar } 335c5441932SPravin B Shelar if (dev->type != ARPHRD_ETHER) 336c5441932SPravin B Shelar dev->flags |= IFF_POINTOPOINT; 337f27337e1SPaolo Abeni 338f27337e1SPaolo Abeni dst_cache_reset(&tunnel->dst_cache); 339c5441932SPravin B Shelar } 340c5441932SPravin B Shelar 341c5441932SPravin B Shelar if (!tdev && tunnel->parms.link) 3426c742e71SNicolas Dichtel tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); 343c5441932SPravin B Shelar 344c5441932SPravin B Shelar if (tdev) { 345c5441932SPravin B Shelar hlen = tdev->hard_header_len + tdev->needed_headroom; 346c5441932SPravin B Shelar mtu = tdev->mtu; 347c5441932SPravin B Shelar } 348c5441932SPravin B Shelar 349c5441932SPravin B Shelar dev->needed_headroom = t_hlen + hlen; 350c5441932SPravin B Shelar mtu -= (dev->hard_header_len + t_hlen); 351c5441932SPravin B Shelar 352b5476022SEric Dumazet if (mtu < IPV4_MIN_MTU) 353b5476022SEric Dumazet mtu = IPV4_MIN_MTU; 354c5441932SPravin B Shelar 355c5441932SPravin B Shelar return mtu; 356c5441932SPravin B Shelar } 357c5441932SPravin B Shelar 358c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_create(struct net *net, 359c5441932SPravin B Shelar struct ip_tunnel_net *itn, 360c5441932SPravin B Shelar struct ip_tunnel_parm *parms) 361c5441932SPravin B Shelar { 3624929fd8cSJulia Lawall struct ip_tunnel *nt; 363c5441932SPravin B Shelar struct net_device *dev; 364b96f9afeSJarod Wilson int t_hlen; 365*f6cc9c05SPetr Machata int mtu; 366*f6cc9c05SPetr Machata int err; 367c5441932SPravin B Shelar 368c5441932SPravin B Shelar BUG_ON(!itn->fb_tunnel_dev); 369c5441932SPravin B Shelar dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms); 370c5441932SPravin B Shelar if (IS_ERR(dev)) 3716dd3c9ecSFlorian Westphal return ERR_CAST(dev); 372c5441932SPravin B Shelar 373*f6cc9c05SPetr Machata mtu = ip_tunnel_bind_dev(dev); 374*f6cc9c05SPetr Machata err = dev_set_mtu(dev, mtu); 375*f6cc9c05SPetr Machata if (err) 376*f6cc9c05SPetr Machata goto err_dev_set_mtu; 377c5441932SPravin B Shelar 378c5441932SPravin B Shelar nt = netdev_priv(dev); 379b96f9afeSJarod Wilson t_hlen = nt->hlen + sizeof(struct iphdr); 380b96f9afeSJarod Wilson dev->min_mtu = ETH_MIN_MTU; 381b96f9afeSJarod Wilson dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen; 382c5441932SPravin B Shelar ip_tunnel_add(itn, nt); 383c5441932SPravin B Shelar return nt; 384*f6cc9c05SPetr Machata 385*f6cc9c05SPetr Machata err_dev_set_mtu: 386*f6cc9c05SPetr Machata unregister_netdevice(dev); 387*f6cc9c05SPetr Machata return ERR_PTR(err); 388c5441932SPravin B Shelar } 389c5441932SPravin B Shelar 390c5441932SPravin B Shelar int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, 3912e15ea39SPravin B Shelar const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst, 3922e15ea39SPravin B Shelar bool log_ecn_error) 393c5441932SPravin B Shelar { 3948f84985fSLi RongQing struct pcpu_sw_netstats *tstats; 395c5441932SPravin B Shelar const struct iphdr *iph = ip_hdr(skb); 396c5441932SPravin B Shelar int err; 397c5441932SPravin B Shelar 398c5441932SPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST 399c5441932SPravin B Shelar if (ipv4_is_multicast(iph->daddr)) { 400c5441932SPravin B Shelar tunnel->dev->stats.multicast++; 401c5441932SPravin B Shelar skb->pkt_type = PACKET_BROADCAST; 402c5441932SPravin B Shelar } 403c5441932SPravin B Shelar #endif 404c5441932SPravin B Shelar 405c5441932SPravin B Shelar if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) || 406c5441932SPravin B Shelar ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) { 407c5441932SPravin B Shelar tunnel->dev->stats.rx_crc_errors++; 408c5441932SPravin B Shelar tunnel->dev->stats.rx_errors++; 409c5441932SPravin B Shelar goto drop; 410c5441932SPravin B Shelar } 411c5441932SPravin B Shelar 412c5441932SPravin B Shelar if (tunnel->parms.i_flags&TUNNEL_SEQ) { 413c5441932SPravin B Shelar if (!(tpi->flags&TUNNEL_SEQ) || 414c5441932SPravin B Shelar (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) { 415c5441932SPravin B Shelar tunnel->dev->stats.rx_fifo_errors++; 416c5441932SPravin B Shelar tunnel->dev->stats.rx_errors++; 417c5441932SPravin B Shelar goto drop; 418c5441932SPravin B Shelar } 419c5441932SPravin B Shelar tunnel->i_seqno = ntohl(tpi->seq) + 1; 420c5441932SPravin B Shelar } 421c5441932SPravin B Shelar 422e96f2e7cSYing Cai skb_reset_network_header(skb); 423e96f2e7cSYing Cai 424c5441932SPravin B Shelar err = IP_ECN_decapsulate(iph, skb); 425c5441932SPravin B Shelar if (unlikely(err)) { 426c5441932SPravin B Shelar if (log_ecn_error) 427c5441932SPravin B Shelar net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n", 428c5441932SPravin B Shelar &iph->saddr, iph->tos); 429c5441932SPravin B Shelar if (err > 1) { 430c5441932SPravin B Shelar ++tunnel->dev->stats.rx_frame_errors; 431c5441932SPravin B Shelar ++tunnel->dev->stats.rx_errors; 432c5441932SPravin B Shelar goto drop; 433c5441932SPravin B Shelar } 434c5441932SPravin B Shelar } 435c5441932SPravin B Shelar 436c5441932SPravin B Shelar tstats = this_cpu_ptr(tunnel->dev->tstats); 437c5441932SPravin B Shelar u64_stats_update_begin(&tstats->syncp); 438c5441932SPravin B Shelar tstats->rx_packets++; 439c5441932SPravin B Shelar tstats->rx_bytes += skb->len; 440c5441932SPravin B Shelar u64_stats_update_end(&tstats->syncp); 441c5441932SPravin B Shelar 44281b9eab5SAlexei Starovoitov skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev))); 44381b9eab5SAlexei Starovoitov 4443d7b46cdSPravin B Shelar if (tunnel->dev->type == ARPHRD_ETHER) { 4453d7b46cdSPravin B Shelar skb->protocol = eth_type_trans(skb, tunnel->dev); 4463d7b46cdSPravin B Shelar skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); 4473d7b46cdSPravin B Shelar } else { 4483d7b46cdSPravin B Shelar skb->dev = tunnel->dev; 4493d7b46cdSPravin B Shelar } 45064261f23SNicolas Dichtel 4512e15ea39SPravin B Shelar if (tun_dst) 4522e15ea39SPravin B Shelar skb_dst_set(skb, (struct dst_entry *)tun_dst); 4532e15ea39SPravin B Shelar 454c5441932SPravin B Shelar gro_cells_receive(&tunnel->gro_cells, skb); 455c5441932SPravin B Shelar return 0; 456c5441932SPravin B Shelar 457c5441932SPravin B Shelar drop: 458469f87e1SHaishuang Yan if (tun_dst) 459469f87e1SHaishuang Yan dst_release((struct dst_entry *)tun_dst); 460c5441932SPravin B Shelar kfree_skb(skb); 461c5441932SPravin B Shelar return 0; 462c5441932SPravin B Shelar } 463c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_rcv); 464c5441932SPravin B Shelar 465a8c5f90fSTom Herbert int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops, 466a8c5f90fSTom Herbert unsigned int num) 467a8c5f90fSTom Herbert { 468bb1553c8SThomas Graf if (num >= MAX_IPTUN_ENCAP_OPS) 469bb1553c8SThomas Graf return -ERANGE; 470bb1553c8SThomas Graf 471a8c5f90fSTom Herbert return !cmpxchg((const struct ip_tunnel_encap_ops **) 472a8c5f90fSTom Herbert &iptun_encaps[num], 473a8c5f90fSTom Herbert NULL, ops) ? 0 : -1; 47456328486STom Herbert } 475a8c5f90fSTom Herbert EXPORT_SYMBOL(ip_tunnel_encap_add_ops); 476a8c5f90fSTom Herbert 477a8c5f90fSTom Herbert int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops, 478a8c5f90fSTom Herbert unsigned int num) 479a8c5f90fSTom Herbert { 480a8c5f90fSTom Herbert int ret; 481a8c5f90fSTom Herbert 482bb1553c8SThomas Graf if (num >= MAX_IPTUN_ENCAP_OPS) 483bb1553c8SThomas Graf return -ERANGE; 484bb1553c8SThomas Graf 485a8c5f90fSTom Herbert ret = (cmpxchg((const struct ip_tunnel_encap_ops **) 486a8c5f90fSTom Herbert &iptun_encaps[num], 487a8c5f90fSTom Herbert ops, NULL) == ops) ? 0 : -1; 488a8c5f90fSTom Herbert 489a8c5f90fSTom Herbert synchronize_net(); 490a8c5f90fSTom Herbert 491a8c5f90fSTom Herbert return ret; 492a8c5f90fSTom Herbert } 493a8c5f90fSTom Herbert EXPORT_SYMBOL(ip_tunnel_encap_del_ops); 49456328486STom Herbert 49556328486STom Herbert int ip_tunnel_encap_setup(struct ip_tunnel *t, 49656328486STom Herbert struct ip_tunnel_encap *ipencap) 49756328486STom Herbert { 49856328486STom Herbert int hlen; 49956328486STom Herbert 50056328486STom Herbert memset(&t->encap, 0, sizeof(t->encap)); 50156328486STom Herbert 50256328486STom Herbert hlen = ip_encap_hlen(ipencap); 50356328486STom Herbert if (hlen < 0) 50456328486STom Herbert return hlen; 50556328486STom Herbert 50656328486STom Herbert t->encap.type = ipencap->type; 50756328486STom Herbert t->encap.sport = ipencap->sport; 50856328486STom Herbert t->encap.dport = ipencap->dport; 50956328486STom Herbert t->encap.flags = ipencap->flags; 51056328486STom Herbert 51156328486STom Herbert t->encap_hlen = hlen; 51256328486STom Herbert t->hlen = t->encap_hlen + t->tun_hlen; 51356328486STom Herbert 51456328486STom Herbert return 0; 51556328486STom Herbert } 51656328486STom Herbert EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup); 51756328486STom Herbert 51823a3647bSPravin B Shelar static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, 519fc24f2b2STimo Teräs struct rtable *rt, __be16 df, 520fc24f2b2STimo Teräs const struct iphdr *inner_iph) 52123a3647bSPravin B Shelar { 52223a3647bSPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 5238c91e162SAlexander Duyck int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len; 52423a3647bSPravin B Shelar int mtu; 52523a3647bSPravin B Shelar 52623a3647bSPravin B Shelar if (df) 52723a3647bSPravin B Shelar mtu = dst_mtu(&rt->dst) - dev->hard_header_len 52823a3647bSPravin B Shelar - sizeof(struct iphdr) - tunnel->hlen; 52923a3647bSPravin B Shelar else 53023a3647bSPravin B Shelar mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; 53123a3647bSPravin B Shelar 532f15ca723SNicolas Dichtel skb_dst_update_pmtu(skb, mtu); 53323a3647bSPravin B Shelar 53423a3647bSPravin B Shelar if (skb->protocol == htons(ETH_P_IP)) { 53523a3647bSPravin B Shelar if (!skb_is_gso(skb) && 536fc24f2b2STimo Teräs (inner_iph->frag_off & htons(IP_DF)) && 537fc24f2b2STimo Teräs mtu < pkt_size) { 53823a3647bSPravin B Shelar memset(IPCB(skb), 0, sizeof(*IPCB(skb))); 53923a3647bSPravin B Shelar icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 54023a3647bSPravin B Shelar return -E2BIG; 54123a3647bSPravin B Shelar } 54223a3647bSPravin B Shelar } 54323a3647bSPravin B Shelar #if IS_ENABLED(CONFIG_IPV6) 54423a3647bSPravin B Shelar else if (skb->protocol == htons(ETH_P_IPV6)) { 54523a3647bSPravin B Shelar struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); 54623a3647bSPravin B Shelar 54723a3647bSPravin B Shelar if (rt6 && mtu < dst_mtu(skb_dst(skb)) && 54823a3647bSPravin B Shelar mtu >= IPV6_MIN_MTU) { 54923a3647bSPravin B Shelar if ((tunnel->parms.iph.daddr && 55023a3647bSPravin B Shelar !ipv4_is_multicast(tunnel->parms.iph.daddr)) || 55123a3647bSPravin B Shelar rt6->rt6i_dst.plen == 128) { 55223a3647bSPravin B Shelar rt6->rt6i_flags |= RTF_MODIFIED; 55323a3647bSPravin B Shelar dst_metric_set(skb_dst(skb), RTAX_MTU, mtu); 55423a3647bSPravin B Shelar } 55523a3647bSPravin B Shelar } 55623a3647bSPravin B Shelar 55723a3647bSPravin B Shelar if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU && 55823a3647bSPravin B Shelar mtu < pkt_size) { 55923a3647bSPravin B Shelar icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 56023a3647bSPravin B Shelar return -E2BIG; 56123a3647bSPravin B Shelar } 56223a3647bSPravin B Shelar } 56323a3647bSPravin B Shelar #endif 56423a3647bSPravin B Shelar return 0; 56523a3647bSPravin B Shelar } 56623a3647bSPravin B Shelar 567cfc7381bSAlexei Starovoitov void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto) 568cfc7381bSAlexei Starovoitov { 569cfc7381bSAlexei Starovoitov struct ip_tunnel *tunnel = netdev_priv(dev); 570cfc7381bSAlexei Starovoitov u32 headroom = sizeof(struct iphdr); 571cfc7381bSAlexei Starovoitov struct ip_tunnel_info *tun_info; 572cfc7381bSAlexei Starovoitov const struct ip_tunnel_key *key; 573cfc7381bSAlexei Starovoitov const struct iphdr *inner_iph; 574cfc7381bSAlexei Starovoitov struct rtable *rt; 575cfc7381bSAlexei Starovoitov struct flowi4 fl4; 576cfc7381bSAlexei Starovoitov __be16 df = 0; 577cfc7381bSAlexei Starovoitov u8 tos, ttl; 578cfc7381bSAlexei Starovoitov 579cfc7381bSAlexei Starovoitov tun_info = skb_tunnel_info(skb); 580cfc7381bSAlexei Starovoitov if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || 581cfc7381bSAlexei Starovoitov ip_tunnel_info_af(tun_info) != AF_INET)) 582cfc7381bSAlexei Starovoitov goto tx_error; 583cfc7381bSAlexei Starovoitov key = &tun_info->key; 584cfc7381bSAlexei Starovoitov memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 585cfc7381bSAlexei Starovoitov inner_iph = (const struct iphdr *)skb_inner_network_header(skb); 586cfc7381bSAlexei Starovoitov tos = key->tos; 587cfc7381bSAlexei Starovoitov if (tos == 1) { 588cfc7381bSAlexei Starovoitov if (skb->protocol == htons(ETH_P_IP)) 589cfc7381bSAlexei Starovoitov tos = inner_iph->tos; 590cfc7381bSAlexei Starovoitov else if (skb->protocol == htons(ETH_P_IPV6)) 591cfc7381bSAlexei Starovoitov tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph); 592cfc7381bSAlexei Starovoitov } 593cfc7381bSAlexei Starovoitov init_tunnel_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, 0, 5949830ad4cSCraig Gallek RT_TOS(tos), tunnel->parms.link, tunnel->fwmark); 595cfc7381bSAlexei Starovoitov if (tunnel->encap.type != TUNNEL_ENCAP_NONE) 596cfc7381bSAlexei Starovoitov goto tx_error; 597cfc7381bSAlexei Starovoitov rt = ip_route_output_key(tunnel->net, &fl4); 598cfc7381bSAlexei Starovoitov if (IS_ERR(rt)) { 599cfc7381bSAlexei Starovoitov dev->stats.tx_carrier_errors++; 600cfc7381bSAlexei Starovoitov goto tx_error; 601cfc7381bSAlexei Starovoitov } 602cfc7381bSAlexei Starovoitov if (rt->dst.dev == dev) { 603cfc7381bSAlexei Starovoitov ip_rt_put(rt); 604cfc7381bSAlexei Starovoitov dev->stats.collisions++; 605cfc7381bSAlexei Starovoitov goto tx_error; 606cfc7381bSAlexei Starovoitov } 607cfc7381bSAlexei Starovoitov tos = ip_tunnel_ecn_encap(tos, inner_iph, skb); 608cfc7381bSAlexei Starovoitov ttl = key->ttl; 609cfc7381bSAlexei Starovoitov if (ttl == 0) { 610cfc7381bSAlexei Starovoitov if (skb->protocol == htons(ETH_P_IP)) 611cfc7381bSAlexei Starovoitov ttl = inner_iph->ttl; 612cfc7381bSAlexei Starovoitov else if (skb->protocol == htons(ETH_P_IPV6)) 613cfc7381bSAlexei Starovoitov ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit; 614cfc7381bSAlexei Starovoitov else 615cfc7381bSAlexei Starovoitov ttl = ip4_dst_hoplimit(&rt->dst); 616cfc7381bSAlexei Starovoitov } 617cfc7381bSAlexei Starovoitov if (key->tun_flags & TUNNEL_DONT_FRAGMENT) 618cfc7381bSAlexei Starovoitov df = htons(IP_DF); 619cfc7381bSAlexei Starovoitov else if (skb->protocol == htons(ETH_P_IP)) 620cfc7381bSAlexei Starovoitov df = inner_iph->frag_off & htons(IP_DF); 621cfc7381bSAlexei Starovoitov headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; 622cfc7381bSAlexei Starovoitov if (headroom > dev->needed_headroom) 623cfc7381bSAlexei Starovoitov dev->needed_headroom = headroom; 624cfc7381bSAlexei Starovoitov 625cfc7381bSAlexei Starovoitov if (skb_cow_head(skb, dev->needed_headroom)) { 626cfc7381bSAlexei Starovoitov ip_rt_put(rt); 627cfc7381bSAlexei Starovoitov goto tx_dropped; 628cfc7381bSAlexei Starovoitov } 6290f693f19SHaishuang Yan iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl, 6300f693f19SHaishuang Yan df, !net_eq(tunnel->net, dev_net(dev))); 631cfc7381bSAlexei Starovoitov return; 632cfc7381bSAlexei Starovoitov tx_error: 633cfc7381bSAlexei Starovoitov dev->stats.tx_errors++; 634cfc7381bSAlexei Starovoitov goto kfree; 635cfc7381bSAlexei Starovoitov tx_dropped: 636cfc7381bSAlexei Starovoitov dev->stats.tx_dropped++; 637cfc7381bSAlexei Starovoitov kfree: 638cfc7381bSAlexei Starovoitov kfree_skb(skb); 639cfc7381bSAlexei Starovoitov } 640cfc7381bSAlexei Starovoitov EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit); 641cfc7381bSAlexei Starovoitov 642c5441932SPravin B Shelar void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, 64356328486STom Herbert const struct iphdr *tnl_params, u8 protocol) 644c5441932SPravin B Shelar { 645c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 646c5441932SPravin B Shelar const struct iphdr *inner_iph; 647c5441932SPravin B Shelar struct flowi4 fl4; 648c5441932SPravin B Shelar u8 tos, ttl; 649c5441932SPravin B Shelar __be16 df; 650b045d37bSEric Dumazet struct rtable *rt; /* Route to the other host */ 651c5441932SPravin B Shelar unsigned int max_headroom; /* The extra header space needed */ 652c5441932SPravin B Shelar __be32 dst; 65322fb22eaSTimo Teräs bool connected; 654c5441932SPravin B Shelar 655c5441932SPravin B Shelar inner_iph = (const struct iphdr *)skb_inner_network_header(skb); 65622fb22eaSTimo Teräs connected = (tunnel->parms.iph.daddr != 0); 657c5441932SPravin B Shelar 6585146d1f1SBernie Harris memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 6595146d1f1SBernie Harris 660c5441932SPravin B Shelar dst = tnl_params->daddr; 661c5441932SPravin B Shelar if (dst == 0) { 662c5441932SPravin B Shelar /* NBMA tunnel */ 663c5441932SPravin B Shelar 66451456b29SIan Morris if (!skb_dst(skb)) { 665c5441932SPravin B Shelar dev->stats.tx_fifo_errors++; 666c5441932SPravin B Shelar goto tx_error; 667c5441932SPravin B Shelar } 668c5441932SPravin B Shelar 669c5441932SPravin B Shelar if (skb->protocol == htons(ETH_P_IP)) { 670c5441932SPravin B Shelar rt = skb_rtable(skb); 671c5441932SPravin B Shelar dst = rt_nexthop(rt, inner_iph->daddr); 672c5441932SPravin B Shelar } 673c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6) 674c5441932SPravin B Shelar else if (skb->protocol == htons(ETH_P_IPV6)) { 675c5441932SPravin B Shelar const struct in6_addr *addr6; 676c5441932SPravin B Shelar struct neighbour *neigh; 677c5441932SPravin B Shelar bool do_tx_error_icmp; 678c5441932SPravin B Shelar int addr_type; 679c5441932SPravin B Shelar 680c5441932SPravin B Shelar neigh = dst_neigh_lookup(skb_dst(skb), 681c5441932SPravin B Shelar &ipv6_hdr(skb)->daddr); 68251456b29SIan Morris if (!neigh) 683c5441932SPravin B Shelar goto tx_error; 684c5441932SPravin B Shelar 685c5441932SPravin B Shelar addr6 = (const struct in6_addr *)&neigh->primary_key; 686c5441932SPravin B Shelar addr_type = ipv6_addr_type(addr6); 687c5441932SPravin B Shelar 688c5441932SPravin B Shelar if (addr_type == IPV6_ADDR_ANY) { 689c5441932SPravin B Shelar addr6 = &ipv6_hdr(skb)->daddr; 690c5441932SPravin B Shelar addr_type = ipv6_addr_type(addr6); 691c5441932SPravin B Shelar } 692c5441932SPravin B Shelar 693c5441932SPravin B Shelar if ((addr_type & IPV6_ADDR_COMPATv4) == 0) 694c5441932SPravin B Shelar do_tx_error_icmp = true; 695c5441932SPravin B Shelar else { 696c5441932SPravin B Shelar do_tx_error_icmp = false; 697c5441932SPravin B Shelar dst = addr6->s6_addr32[3]; 698c5441932SPravin B Shelar } 699c5441932SPravin B Shelar neigh_release(neigh); 700c5441932SPravin B Shelar if (do_tx_error_icmp) 701c5441932SPravin B Shelar goto tx_error_icmp; 702c5441932SPravin B Shelar } 703c5441932SPravin B Shelar #endif 704c5441932SPravin B Shelar else 705c5441932SPravin B Shelar goto tx_error; 7067d442fabSTom Herbert 7077d442fabSTom Herbert connected = false; 708c5441932SPravin B Shelar } 709c5441932SPravin B Shelar 710c5441932SPravin B Shelar tos = tnl_params->tos; 711c5441932SPravin B Shelar if (tos & 0x1) { 712c5441932SPravin B Shelar tos &= ~0x1; 7137d442fabSTom Herbert if (skb->protocol == htons(ETH_P_IP)) { 714c5441932SPravin B Shelar tos = inner_iph->tos; 7157d442fabSTom Herbert connected = false; 7167d442fabSTom Herbert } else if (skb->protocol == htons(ETH_P_IPV6)) { 717c5441932SPravin B Shelar tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph); 7187d442fabSTom Herbert connected = false; 7197d442fabSTom Herbert } 720c5441932SPravin B Shelar } 721c5441932SPravin B Shelar 7227d442fabSTom Herbert init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, 7239830ad4cSCraig Gallek tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, 7249830ad4cSCraig Gallek tunnel->fwmark); 7257d442fabSTom Herbert 72656328486STom Herbert if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) 72756328486STom Herbert goto tx_error; 72856328486STom Herbert 729e09acddfSPaolo Abeni rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) : 730e09acddfSPaolo Abeni NULL; 7317d442fabSTom Herbert 7327d442fabSTom Herbert if (!rt) { 7337d442fabSTom Herbert rt = ip_route_output_key(tunnel->net, &fl4); 7347d442fabSTom Herbert 735c5441932SPravin B Shelar if (IS_ERR(rt)) { 736c5441932SPravin B Shelar dev->stats.tx_carrier_errors++; 737c5441932SPravin B Shelar goto tx_error; 738c5441932SPravin B Shelar } 7397d442fabSTom Herbert if (connected) 740e09acddfSPaolo Abeni dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, 741e09acddfSPaolo Abeni fl4.saddr); 7427d442fabSTom Herbert } 7437d442fabSTom Herbert 7440e6fbc5bSPravin B Shelar if (rt->dst.dev == dev) { 745c5441932SPravin B Shelar ip_rt_put(rt); 746c5441932SPravin B Shelar dev->stats.collisions++; 747c5441932SPravin B Shelar goto tx_error; 748c5441932SPravin B Shelar } 749c5441932SPravin B Shelar 750fc24f2b2STimo Teräs if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) { 751c5441932SPravin B Shelar ip_rt_put(rt); 752c5441932SPravin B Shelar goto tx_error; 753c5441932SPravin B Shelar } 754c5441932SPravin B Shelar 755c5441932SPravin B Shelar if (tunnel->err_count > 0) { 756c5441932SPravin B Shelar if (time_before(jiffies, 757c5441932SPravin B Shelar tunnel->err_time + IPTUNNEL_ERR_TIMEO)) { 758c5441932SPravin B Shelar tunnel->err_count--; 759c5441932SPravin B Shelar 760c5441932SPravin B Shelar dst_link_failure(skb); 761c5441932SPravin B Shelar } else 762c5441932SPravin B Shelar tunnel->err_count = 0; 763c5441932SPravin B Shelar } 764c5441932SPravin B Shelar 765d4a71b15SPravin B Shelar tos = ip_tunnel_ecn_encap(tos, inner_iph, skb); 766c5441932SPravin B Shelar ttl = tnl_params->ttl; 767c5441932SPravin B Shelar if (ttl == 0) { 768c5441932SPravin B Shelar if (skb->protocol == htons(ETH_P_IP)) 769c5441932SPravin B Shelar ttl = inner_iph->ttl; 770c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6) 771c5441932SPravin B Shelar else if (skb->protocol == htons(ETH_P_IPV6)) 772c5441932SPravin B Shelar ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit; 773c5441932SPravin B Shelar #endif 774c5441932SPravin B Shelar else 775c5441932SPravin B Shelar ttl = ip4_dst_hoplimit(&rt->dst); 776c5441932SPravin B Shelar } 777c5441932SPravin B Shelar 77823a3647bSPravin B Shelar df = tnl_params->frag_off; 77922a59be8SPhilip Prindeville if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) 78023a3647bSPravin B Shelar df |= (inner_iph->frag_off&htons(IP_DF)); 78123a3647bSPravin B Shelar 7820e6fbc5bSPravin B Shelar max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) 7837371e022STom Herbert + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); 7843e08f4a7SSteffen Klassert if (max_headroom > dev->needed_headroom) 785c5441932SPravin B Shelar dev->needed_headroom = max_headroom; 7863e08f4a7SSteffen Klassert 787c5441932SPravin B Shelar if (skb_cow_head(skb, dev->needed_headroom)) { 788586d5fc8SDmitry Popov ip_rt_put(rt); 789c5441932SPravin B Shelar dev->stats.tx_dropped++; 7903acfa1e7SEric Dumazet kfree_skb(skb); 791c5441932SPravin B Shelar return; 792c5441932SPravin B Shelar } 793c5441932SPravin B Shelar 794039f5062SPravin B Shelar iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, 795039f5062SPravin B Shelar df, !net_eq(tunnel->net, dev_net(dev))); 796c5441932SPravin B Shelar return; 797c5441932SPravin B Shelar 798c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6) 799c5441932SPravin B Shelar tx_error_icmp: 800c5441932SPravin B Shelar dst_link_failure(skb); 801c5441932SPravin B Shelar #endif 802c5441932SPravin B Shelar tx_error: 803c5441932SPravin B Shelar dev->stats.tx_errors++; 8043acfa1e7SEric Dumazet kfree_skb(skb); 805c5441932SPravin B Shelar } 806c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_xmit); 807c5441932SPravin B Shelar 808c5441932SPravin B Shelar static void ip_tunnel_update(struct ip_tunnel_net *itn, 809c5441932SPravin B Shelar struct ip_tunnel *t, 810c5441932SPravin B Shelar struct net_device *dev, 811c5441932SPravin B Shelar struct ip_tunnel_parm *p, 8129830ad4cSCraig Gallek bool set_mtu, 8139830ad4cSCraig Gallek __u32 fwmark) 814c5441932SPravin B Shelar { 8152e15ea39SPravin B Shelar ip_tunnel_del(itn, t); 816c5441932SPravin B Shelar t->parms.iph.saddr = p->iph.saddr; 817c5441932SPravin B Shelar t->parms.iph.daddr = p->iph.daddr; 818c5441932SPravin B Shelar t->parms.i_key = p->i_key; 819c5441932SPravin B Shelar t->parms.o_key = p->o_key; 820c5441932SPravin B Shelar if (dev->type != ARPHRD_ETHER) { 821c5441932SPravin B Shelar memcpy(dev->dev_addr, &p->iph.saddr, 4); 822c5441932SPravin B Shelar memcpy(dev->broadcast, &p->iph.daddr, 4); 823c5441932SPravin B Shelar } 824c5441932SPravin B Shelar ip_tunnel_add(itn, t); 825c5441932SPravin B Shelar 826c5441932SPravin B Shelar t->parms.iph.ttl = p->iph.ttl; 827c5441932SPravin B Shelar t->parms.iph.tos = p->iph.tos; 828c5441932SPravin B Shelar t->parms.iph.frag_off = p->iph.frag_off; 829c5441932SPravin B Shelar 8309830ad4cSCraig Gallek if (t->parms.link != p->link || t->fwmark != fwmark) { 831c5441932SPravin B Shelar int mtu; 832c5441932SPravin B Shelar 833c5441932SPravin B Shelar t->parms.link = p->link; 8349830ad4cSCraig Gallek t->fwmark = fwmark; 835c5441932SPravin B Shelar mtu = ip_tunnel_bind_dev(dev); 836c5441932SPravin B Shelar if (set_mtu) 837c5441932SPravin B Shelar dev->mtu = mtu; 838c5441932SPravin B Shelar } 839e09acddfSPaolo Abeni dst_cache_reset(&t->dst_cache); 840c5441932SPravin B Shelar netdev_state_change(dev); 841c5441932SPravin B Shelar } 842c5441932SPravin B Shelar 843c5441932SPravin B Shelar int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) 844c5441932SPravin B Shelar { 845c5441932SPravin B Shelar int err = 0; 8468c923ce2SNicolas Dichtel struct ip_tunnel *t = netdev_priv(dev); 8478c923ce2SNicolas Dichtel struct net *net = t->net; 8488c923ce2SNicolas Dichtel struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id); 849c5441932SPravin B Shelar 850c5441932SPravin B Shelar BUG_ON(!itn->fb_tunnel_dev); 851c5441932SPravin B Shelar switch (cmd) { 852c5441932SPravin B Shelar case SIOCGETTUNNEL: 8538c923ce2SNicolas Dichtel if (dev == itn->fb_tunnel_dev) { 854c5441932SPravin B Shelar t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 85551456b29SIan Morris if (!t) 856c5441932SPravin B Shelar t = netdev_priv(dev); 8578c923ce2SNicolas Dichtel } 858c5441932SPravin B Shelar memcpy(p, &t->parms, sizeof(*p)); 859c5441932SPravin B Shelar break; 860c5441932SPravin B Shelar 861c5441932SPravin B Shelar case SIOCADDTUNNEL: 862c5441932SPravin B Shelar case SIOCCHGTUNNEL: 863c5441932SPravin B Shelar err = -EPERM; 864c5441932SPravin B Shelar if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 865c5441932SPravin B Shelar goto done; 866c5441932SPravin B Shelar if (p->iph.ttl) 867c5441932SPravin B Shelar p->iph.frag_off |= htons(IP_DF); 8687c8e6b9cSDmitry Popov if (!(p->i_flags & VTI_ISVTI)) { 869c5441932SPravin B Shelar if (!(p->i_flags & TUNNEL_KEY)) 870c5441932SPravin B Shelar p->i_key = 0; 871c5441932SPravin B Shelar if (!(p->o_flags & TUNNEL_KEY)) 872c5441932SPravin B Shelar p->o_key = 0; 8737c8e6b9cSDmitry Popov } 874c5441932SPravin B Shelar 875c5441932SPravin B Shelar t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 876c5441932SPravin B Shelar 877d61746b2SSteffen Klassert if (cmd == SIOCADDTUNNEL) { 878d61746b2SSteffen Klassert if (!t) { 879c5441932SPravin B Shelar t = ip_tunnel_create(net, itn, p); 880ee30ef4dSDuan Jiong err = PTR_ERR_OR_ZERO(t); 8816dd3c9ecSFlorian Westphal break; 8826dd3c9ecSFlorian Westphal } 883d61746b2SSteffen Klassert 884d61746b2SSteffen Klassert err = -EEXIST; 885d61746b2SSteffen Klassert break; 886d61746b2SSteffen Klassert } 887c5441932SPravin B Shelar if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { 88800db4124SIan Morris if (t) { 889c5441932SPravin B Shelar if (t->dev != dev) { 890c5441932SPravin B Shelar err = -EEXIST; 891c5441932SPravin B Shelar break; 892c5441932SPravin B Shelar } 893c5441932SPravin B Shelar } else { 894c5441932SPravin B Shelar unsigned int nflags = 0; 895c5441932SPravin B Shelar 896c5441932SPravin B Shelar if (ipv4_is_multicast(p->iph.daddr)) 897c5441932SPravin B Shelar nflags = IFF_BROADCAST; 898c5441932SPravin B Shelar else if (p->iph.daddr) 899c5441932SPravin B Shelar nflags = IFF_POINTOPOINT; 900c5441932SPravin B Shelar 901c5441932SPravin B Shelar if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) { 902c5441932SPravin B Shelar err = -EINVAL; 903c5441932SPravin B Shelar break; 904c5441932SPravin B Shelar } 905c5441932SPravin B Shelar 906c5441932SPravin B Shelar t = netdev_priv(dev); 907c5441932SPravin B Shelar } 908c5441932SPravin B Shelar } 909c5441932SPravin B Shelar 910c5441932SPravin B Shelar if (t) { 911c5441932SPravin B Shelar err = 0; 9129830ad4cSCraig Gallek ip_tunnel_update(itn, t, dev, p, true, 0); 9136dd3c9ecSFlorian Westphal } else { 9146dd3c9ecSFlorian Westphal err = -ENOENT; 9156dd3c9ecSFlorian Westphal } 916c5441932SPravin B Shelar break; 917c5441932SPravin B Shelar 918c5441932SPravin B Shelar case SIOCDELTUNNEL: 919c5441932SPravin B Shelar err = -EPERM; 920c5441932SPravin B Shelar if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 921c5441932SPravin B Shelar goto done; 922c5441932SPravin B Shelar 923c5441932SPravin B Shelar if (dev == itn->fb_tunnel_dev) { 924c5441932SPravin B Shelar err = -ENOENT; 925c5441932SPravin B Shelar t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 92651456b29SIan Morris if (!t) 927c5441932SPravin B Shelar goto done; 928c5441932SPravin B Shelar err = -EPERM; 929c5441932SPravin B Shelar if (t == netdev_priv(itn->fb_tunnel_dev)) 930c5441932SPravin B Shelar goto done; 931c5441932SPravin B Shelar dev = t->dev; 932c5441932SPravin B Shelar } 933c5441932SPravin B Shelar unregister_netdevice(dev); 934c5441932SPravin B Shelar err = 0; 935c5441932SPravin B Shelar break; 936c5441932SPravin B Shelar 937c5441932SPravin B Shelar default: 938c5441932SPravin B Shelar err = -EINVAL; 939c5441932SPravin B Shelar } 940c5441932SPravin B Shelar 941c5441932SPravin B Shelar done: 942c5441932SPravin B Shelar return err; 943c5441932SPravin B Shelar } 944c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_ioctl); 945c5441932SPravin B Shelar 9467e059158SDavid Wragg int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict) 947c5441932SPravin B Shelar { 948c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 949c5441932SPravin B Shelar int t_hlen = tunnel->hlen + sizeof(struct iphdr); 9507e059158SDavid Wragg int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen; 951c5441932SPravin B Shelar 952b96f9afeSJarod Wilson if (new_mtu < ETH_MIN_MTU) 953c5441932SPravin B Shelar return -EINVAL; 9547e059158SDavid Wragg 9557e059158SDavid Wragg if (new_mtu > max_mtu) { 9567e059158SDavid Wragg if (strict) 9577e059158SDavid Wragg return -EINVAL; 9587e059158SDavid Wragg 9597e059158SDavid Wragg new_mtu = max_mtu; 9607e059158SDavid Wragg } 9617e059158SDavid Wragg 962c5441932SPravin B Shelar dev->mtu = new_mtu; 963c5441932SPravin B Shelar return 0; 964c5441932SPravin B Shelar } 9657e059158SDavid Wragg EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu); 9667e059158SDavid Wragg 9677e059158SDavid Wragg int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu) 9687e059158SDavid Wragg { 9697e059158SDavid Wragg return __ip_tunnel_change_mtu(dev, new_mtu, true); 9707e059158SDavid Wragg } 971c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu); 972c5441932SPravin B Shelar 973c5441932SPravin B Shelar static void ip_tunnel_dev_free(struct net_device *dev) 974c5441932SPravin B Shelar { 975c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 976c5441932SPravin B Shelar 977c5441932SPravin B Shelar gro_cells_destroy(&tunnel->gro_cells); 978e09acddfSPaolo Abeni dst_cache_destroy(&tunnel->dst_cache); 979c5441932SPravin B Shelar free_percpu(dev->tstats); 980c5441932SPravin B Shelar } 981c5441932SPravin B Shelar 982c5441932SPravin B Shelar void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) 983c5441932SPravin B Shelar { 984c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 985c5441932SPravin B Shelar struct ip_tunnel_net *itn; 986c5441932SPravin B Shelar 9876c742e71SNicolas Dichtel itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id); 988c5441932SPravin B Shelar 989c5441932SPravin B Shelar if (itn->fb_tunnel_dev != dev) { 9902e15ea39SPravin B Shelar ip_tunnel_del(itn, netdev_priv(dev)); 991c5441932SPravin B Shelar unregister_netdevice_queue(dev, head); 992c5441932SPravin B Shelar } 993c5441932SPravin B Shelar } 994c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_dellink); 995c5441932SPravin B Shelar 9961728d4faSNicolas Dichtel struct net *ip_tunnel_get_link_net(const struct net_device *dev) 9971728d4faSNicolas Dichtel { 9981728d4faSNicolas Dichtel struct ip_tunnel *tunnel = netdev_priv(dev); 9991728d4faSNicolas Dichtel 10001728d4faSNicolas Dichtel return tunnel->net; 10011728d4faSNicolas Dichtel } 10021728d4faSNicolas Dichtel EXPORT_SYMBOL(ip_tunnel_get_link_net); 10031728d4faSNicolas Dichtel 10041e99584bSNicolas Dichtel int ip_tunnel_get_iflink(const struct net_device *dev) 10051e99584bSNicolas Dichtel { 10061e99584bSNicolas Dichtel struct ip_tunnel *tunnel = netdev_priv(dev); 10071e99584bSNicolas Dichtel 10081e99584bSNicolas Dichtel return tunnel->parms.link; 10091e99584bSNicolas Dichtel } 10101e99584bSNicolas Dichtel EXPORT_SYMBOL(ip_tunnel_get_iflink); 10111e99584bSNicolas Dichtel 1012c7d03a00SAlexey Dobriyan int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id, 1013c5441932SPravin B Shelar struct rtnl_link_ops *ops, char *devname) 1014c5441932SPravin B Shelar { 1015c5441932SPravin B Shelar struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id); 1016c5441932SPravin B Shelar struct ip_tunnel_parm parms; 10176261d983Sstephen hemminger unsigned int i; 1018c5441932SPravin B Shelar 10196261d983Sstephen hemminger for (i = 0; i < IP_TNL_HASH_SIZE; i++) 10206261d983Sstephen hemminger INIT_HLIST_HEAD(&itn->tunnels[i]); 1021c5441932SPravin B Shelar 1022c5441932SPravin B Shelar if (!ops) { 1023c5441932SPravin B Shelar itn->fb_tunnel_dev = NULL; 1024c5441932SPravin B Shelar return 0; 1025c5441932SPravin B Shelar } 10266261d983Sstephen hemminger 1027c5441932SPravin B Shelar memset(&parms, 0, sizeof(parms)); 1028c5441932SPravin B Shelar if (devname) 1029c5441932SPravin B Shelar strlcpy(parms.name, devname, IFNAMSIZ); 1030c5441932SPravin B Shelar 1031c5441932SPravin B Shelar rtnl_lock(); 1032c5441932SPravin B Shelar itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms); 1033ea857f28SDan Carpenter /* FB netdevice is special: we have one, and only one per netns. 1034ea857f28SDan Carpenter * Allowing to move it to another netns is clearly unsafe. 1035ea857f28SDan Carpenter */ 103667013282SSteffen Klassert if (!IS_ERR(itn->fb_tunnel_dev)) { 1037ea857f28SDan Carpenter itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; 103878ff4be4SSteffen Klassert itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev); 103967013282SSteffen Klassert ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev)); 104067013282SSteffen Klassert } 1041b4de77adSDan Carpenter rtnl_unlock(); 1042c5441932SPravin B Shelar 104327d79f3bSSachin Kamat return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev); 1044c5441932SPravin B Shelar } 1045c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init_net); 1046c5441932SPravin B Shelar 10476c742e71SNicolas Dichtel static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head, 10486c742e71SNicolas Dichtel struct rtnl_link_ops *ops) 1049c5441932SPravin B Shelar { 10506c742e71SNicolas Dichtel struct net *net = dev_net(itn->fb_tunnel_dev); 10516c742e71SNicolas Dichtel struct net_device *dev, *aux; 1052c5441932SPravin B Shelar int h; 1053c5441932SPravin B Shelar 10546c742e71SNicolas Dichtel for_each_netdev_safe(net, dev, aux) 10556c742e71SNicolas Dichtel if (dev->rtnl_link_ops == ops) 10566c742e71SNicolas Dichtel unregister_netdevice_queue(dev, head); 10576c742e71SNicolas Dichtel 1058c5441932SPravin B Shelar for (h = 0; h < IP_TNL_HASH_SIZE; h++) { 1059c5441932SPravin B Shelar struct ip_tunnel *t; 1060c5441932SPravin B Shelar struct hlist_node *n; 1061c5441932SPravin B Shelar struct hlist_head *thead = &itn->tunnels[h]; 1062c5441932SPravin B Shelar 1063c5441932SPravin B Shelar hlist_for_each_entry_safe(t, n, thead, hash_node) 10646c742e71SNicolas Dichtel /* If dev is in the same netns, it has already 10656c742e71SNicolas Dichtel * been added to the list by the previous loop. 10666c742e71SNicolas Dichtel */ 10676c742e71SNicolas Dichtel if (!net_eq(dev_net(t->dev), net)) 1068c5441932SPravin B Shelar unregister_netdevice_queue(t->dev, head); 1069c5441932SPravin B Shelar } 1070c5441932SPravin B Shelar } 1071c5441932SPravin B Shelar 107264bc1781SEric Dumazet void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id, 107364bc1781SEric Dumazet struct rtnl_link_ops *ops) 1074c5441932SPravin B Shelar { 107564bc1781SEric Dumazet struct ip_tunnel_net *itn; 107664bc1781SEric Dumazet struct net *net; 1077c5441932SPravin B Shelar LIST_HEAD(list); 1078c5441932SPravin B Shelar 1079c5441932SPravin B Shelar rtnl_lock(); 108064bc1781SEric Dumazet list_for_each_entry(net, net_list, exit_list) { 108164bc1781SEric Dumazet itn = net_generic(net, id); 10826c742e71SNicolas Dichtel ip_tunnel_destroy(itn, &list, ops); 108364bc1781SEric Dumazet } 1084c5441932SPravin B Shelar unregister_netdevice_many(&list); 1085c5441932SPravin B Shelar rtnl_unlock(); 1086c5441932SPravin B Shelar } 108764bc1781SEric Dumazet EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets); 1088c5441932SPravin B Shelar 1089c5441932SPravin B Shelar int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], 10909830ad4cSCraig Gallek struct ip_tunnel_parm *p, __u32 fwmark) 1091c5441932SPravin B Shelar { 1092c5441932SPravin B Shelar struct ip_tunnel *nt; 1093c5441932SPravin B Shelar struct net *net = dev_net(dev); 1094c5441932SPravin B Shelar struct ip_tunnel_net *itn; 1095c5441932SPravin B Shelar int mtu; 1096c5441932SPravin B Shelar int err; 1097c5441932SPravin B Shelar 1098c5441932SPravin B Shelar nt = netdev_priv(dev); 1099c5441932SPravin B Shelar itn = net_generic(net, nt->ip_tnl_net_id); 1100c5441932SPravin B Shelar 11012e15ea39SPravin B Shelar if (nt->collect_md) { 11022e15ea39SPravin B Shelar if (rtnl_dereference(itn->collect_md_tun)) 11032e15ea39SPravin B Shelar return -EEXIST; 11042e15ea39SPravin B Shelar } else { 1105c5441932SPravin B Shelar if (ip_tunnel_find(itn, p, dev->type)) 1106c5441932SPravin B Shelar return -EEXIST; 11072e15ea39SPravin B Shelar } 1108c5441932SPravin B Shelar 11095e6700b3SNicolas Dichtel nt->net = net; 1110c5441932SPravin B Shelar nt->parms = *p; 11119830ad4cSCraig Gallek nt->fwmark = fwmark; 1112c5441932SPravin B Shelar err = register_netdevice(dev); 1113c5441932SPravin B Shelar if (err) 1114*f6cc9c05SPetr Machata goto err_register_netdevice; 1115c5441932SPravin B Shelar 1116c5441932SPravin B Shelar if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS]) 1117c5441932SPravin B Shelar eth_hw_addr_random(dev); 1118c5441932SPravin B Shelar 1119c5441932SPravin B Shelar mtu = ip_tunnel_bind_dev(dev); 1120*f6cc9c05SPetr Machata if (!tb[IFLA_MTU]) { 1121*f6cc9c05SPetr Machata err = dev_set_mtu(dev, mtu); 1122*f6cc9c05SPetr Machata if (err) 1123*f6cc9c05SPetr Machata goto err_dev_set_mtu; 1124*f6cc9c05SPetr Machata } 1125c5441932SPravin B Shelar 1126c5441932SPravin B Shelar ip_tunnel_add(itn, nt); 1127*f6cc9c05SPetr Machata return 0; 1128*f6cc9c05SPetr Machata 1129*f6cc9c05SPetr Machata err_dev_set_mtu: 1130*f6cc9c05SPetr Machata unregister_netdevice(dev); 1131*f6cc9c05SPetr Machata err_register_netdevice: 1132c5441932SPravin B Shelar return err; 1133c5441932SPravin B Shelar } 1134c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_newlink); 1135c5441932SPravin B Shelar 1136c5441932SPravin B Shelar int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[], 11379830ad4cSCraig Gallek struct ip_tunnel_parm *p, __u32 fwmark) 1138c5441932SPravin B Shelar { 11396c742e71SNicolas Dichtel struct ip_tunnel *t; 1140c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 11416c742e71SNicolas Dichtel struct net *net = tunnel->net; 1142c5441932SPravin B Shelar struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id); 1143c5441932SPravin B Shelar 1144c5441932SPravin B Shelar if (dev == itn->fb_tunnel_dev) 1145c5441932SPravin B Shelar return -EINVAL; 1146c5441932SPravin B Shelar 1147c5441932SPravin B Shelar t = ip_tunnel_find(itn, p, dev->type); 1148c5441932SPravin B Shelar 1149c5441932SPravin B Shelar if (t) { 1150c5441932SPravin B Shelar if (t->dev != dev) 1151c5441932SPravin B Shelar return -EEXIST; 1152c5441932SPravin B Shelar } else { 11536c742e71SNicolas Dichtel t = tunnel; 1154c5441932SPravin B Shelar 1155c5441932SPravin B Shelar if (dev->type != ARPHRD_ETHER) { 1156c5441932SPravin B Shelar unsigned int nflags = 0; 1157c5441932SPravin B Shelar 1158c5441932SPravin B Shelar if (ipv4_is_multicast(p->iph.daddr)) 1159c5441932SPravin B Shelar nflags = IFF_BROADCAST; 1160c5441932SPravin B Shelar else if (p->iph.daddr) 1161c5441932SPravin B Shelar nflags = IFF_POINTOPOINT; 1162c5441932SPravin B Shelar 1163c5441932SPravin B Shelar if ((dev->flags ^ nflags) & 1164c5441932SPravin B Shelar (IFF_POINTOPOINT | IFF_BROADCAST)) 1165c5441932SPravin B Shelar return -EINVAL; 1166c5441932SPravin B Shelar } 1167c5441932SPravin B Shelar } 1168c5441932SPravin B Shelar 11699830ad4cSCraig Gallek ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU], fwmark); 1170c5441932SPravin B Shelar return 0; 1171c5441932SPravin B Shelar } 1172c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_changelink); 1173c5441932SPravin B Shelar 1174c5441932SPravin B Shelar int ip_tunnel_init(struct net_device *dev) 1175c5441932SPravin B Shelar { 1176c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 1177c5441932SPravin B Shelar struct iphdr *iph = &tunnel->parms.iph; 11781c213bd2SWANG Cong int err; 1179c5441932SPravin B Shelar 1180cf124db5SDavid S. Miller dev->needs_free_netdev = true; 1181cf124db5SDavid S. Miller dev->priv_destructor = ip_tunnel_dev_free; 11821c213bd2SWANG Cong dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 1183c5441932SPravin B Shelar if (!dev->tstats) 1184c5441932SPravin B Shelar return -ENOMEM; 1185c5441932SPravin B Shelar 1186e09acddfSPaolo Abeni err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL); 1187e09acddfSPaolo Abeni if (err) { 11889a4aa9afSTom Herbert free_percpu(dev->tstats); 1189e09acddfSPaolo Abeni return err; 11909a4aa9afSTom Herbert } 11919a4aa9afSTom Herbert 1192c5441932SPravin B Shelar err = gro_cells_init(&tunnel->gro_cells, dev); 1193c5441932SPravin B Shelar if (err) { 1194e09acddfSPaolo Abeni dst_cache_destroy(&tunnel->dst_cache); 1195c5441932SPravin B Shelar free_percpu(dev->tstats); 1196c5441932SPravin B Shelar return err; 1197c5441932SPravin B Shelar } 1198c5441932SPravin B Shelar 1199c5441932SPravin B Shelar tunnel->dev = dev; 12006c742e71SNicolas Dichtel tunnel->net = dev_net(dev); 1201c5441932SPravin B Shelar strcpy(tunnel->parms.name, dev->name); 1202c5441932SPravin B Shelar iph->version = 4; 1203c5441932SPravin B Shelar iph->ihl = 5; 1204c5441932SPravin B Shelar 12052e15ea39SPravin B Shelar if (tunnel->collect_md) { 12062e15ea39SPravin B Shelar dev->features |= NETIF_F_NETNS_LOCAL; 12072e15ea39SPravin B Shelar netif_keep_dst(dev); 12082e15ea39SPravin B Shelar } 1209c5441932SPravin B Shelar return 0; 1210c5441932SPravin B Shelar } 1211c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init); 1212c5441932SPravin B Shelar 1213c5441932SPravin B Shelar void ip_tunnel_uninit(struct net_device *dev) 1214c5441932SPravin B Shelar { 1215c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 12166c742e71SNicolas Dichtel struct net *net = tunnel->net; 1217c5441932SPravin B Shelar struct ip_tunnel_net *itn; 1218c5441932SPravin B Shelar 1219c5441932SPravin B Shelar itn = net_generic(net, tunnel->ip_tnl_net_id); 1220c5441932SPravin B Shelar /* fb_tunnel_dev will be unregisted in net-exit call. */ 1221c5441932SPravin B Shelar if (itn->fb_tunnel_dev != dev) 12222e15ea39SPravin B Shelar ip_tunnel_del(itn, netdev_priv(dev)); 12237d442fabSTom Herbert 1224e09acddfSPaolo Abeni dst_cache_reset(&tunnel->dst_cache); 1225c5441932SPravin B Shelar } 1226c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_uninit); 1227c5441932SPravin B Shelar 1228c5441932SPravin B Shelar /* Do least required initialization, rest of init is done in tunnel_init call */ 1229c7d03a00SAlexey Dobriyan void ip_tunnel_setup(struct net_device *dev, unsigned int net_id) 1230c5441932SPravin B Shelar { 1231c5441932SPravin B Shelar struct ip_tunnel *tunnel = netdev_priv(dev); 1232c5441932SPravin B Shelar tunnel->ip_tnl_net_id = net_id; 1233c5441932SPravin B Shelar } 1234c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_setup); 1235c5441932SPravin B Shelar 1236c5441932SPravin B Shelar MODULE_LICENSE("GPL"); 1237