11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Linux NET3: IP/IP protocol decoder. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Authors: 51da177e4SLinus Torvalds * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * Fixes: 81da177e4SLinus Torvalds * Alan Cox : Merged and made usable non modular (its so tiny its silly as 91da177e4SLinus Torvalds * a module taking up 2 pages). 101da177e4SLinus Torvalds * Alan Cox : Fixed bug with 1.3.18 and IPIP not working (now needs to set skb->h.iph) 111da177e4SLinus Torvalds * to keep ip_forward happy. 121da177e4SLinus Torvalds * Alan Cox : More fixes for 1.3.21, and firewall fix. Maybe this will work soon 8). 131da177e4SLinus Torvalds * Kai Schulte : Fixed #defines for IP_FIREWALL->FIREWALL 141da177e4SLinus Torvalds * David Woodhouse : Perform some basic ICMP handling. 151da177e4SLinus Torvalds * IPIP Routing without decapsulation. 161da177e4SLinus Torvalds * Carlos Picoto : GRE over IP support 171da177e4SLinus Torvalds * Alexey Kuznetsov: Reworked. Really, now it is truncated version of ipv4/ip_gre.c. 181da177e4SLinus Torvalds * I do not want to merge them together. 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 211da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 221da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 231da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 241da177e4SLinus Torvalds * 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds /* tunnel.c: an IP tunnel driver 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds The purpose of this driver is to provide an IP tunnel through 301da177e4SLinus Torvalds which you can tunnel network traffic transparently across subnets. 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds This was written by looking at Nick Holloway's dummy driver 331da177e4SLinus Torvalds Thanks for the great code! 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds -Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds Minor tweaks: 381da177e4SLinus Torvalds Cleaned up the code a little and added some pre-1.3.0 tweaks. 391da177e4SLinus Torvalds dev->hard_header/hard_header_len changed to use no headers. 401da177e4SLinus Torvalds Comments/bracketing tweaked. 411da177e4SLinus Torvalds Made the tunnels use dev->name not tunnel: when error reporting. 421da177e4SLinus Torvalds Added tx_dropped stat 431da177e4SLinus Torvalds 44113aa838SAlan Cox -Alan Cox (alan@lxorguk.ukuu.org.uk) 21 March 95 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds Reworked: 471da177e4SLinus Torvalds Changed to tunnel to destination gateway in addition to the 481da177e4SLinus Torvalds tunnel's pointopoint address 491da177e4SLinus Torvalds Almost completely rewritten 501da177e4SLinus Torvalds Note: There is currently no firewall or ICMP handling done. 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds -Sam Lantinga (slouken@cs.ucdavis.edu) 02/13/96 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds */ 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds /* Things I wish I had known when writing the tunnel driver: 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds When the tunnel_xmit() function is called, the skb contains the 591da177e4SLinus Torvalds packet to be sent (plus a great deal of extra info), and dev 601da177e4SLinus Torvalds contains the tunnel device that _we_ are. 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds When we are passed a packet, we are expected to fill in the 631da177e4SLinus Torvalds source address with our source IP address. 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds What is the proper way to allocate, copy and free a buffer? 661da177e4SLinus Torvalds After you allocate it, it is a "0 length" chunk of memory 671da177e4SLinus Torvalds starting at zero. If you want to add headers to the buffer 681da177e4SLinus Torvalds later, you'll have to call "skb_reserve(skb, amount)" with 691da177e4SLinus Torvalds the amount of memory you want reserved. Then, you call 701da177e4SLinus Torvalds "skb_put(skb, amount)" with the amount of space you want in 711da177e4SLinus Torvalds the buffer. skb_put() returns a pointer to the top (#0) of 721da177e4SLinus Torvalds that buffer. skb->len is set to the amount of space you have 731da177e4SLinus Torvalds "allocated" with skb_put(). You can then write up to skb->len 741da177e4SLinus Torvalds bytes to that buffer. If you need more, you can call skb_put() 751da177e4SLinus Torvalds again with the additional amount of space you need. You can 761da177e4SLinus Torvalds find out how much more space you can allocate by calling 771da177e4SLinus Torvalds "skb_tailroom(skb)". 781da177e4SLinus Torvalds Now, to add header space, call "skb_push(skb, header_len)". 791da177e4SLinus Torvalds This creates space at the beginning of the buffer and returns 801da177e4SLinus Torvalds a pointer to this new space. If later you need to strip a 811da177e4SLinus Torvalds header from a buffer, call "skb_pull(skb, header_len)". 821da177e4SLinus Torvalds skb_headroom() will return how much space is left at the top 831da177e4SLinus Torvalds of the buffer (before the main data). Remember, this headroom 841da177e4SLinus Torvalds space must be reserved before the skb_put() function is called. 851da177e4SLinus Torvalds */ 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds /* 881da177e4SLinus Torvalds This version of net/ipv4/ipip.c is cloned of net/ipv4/ip_gre.c 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds For comments look at net/ipv4/ip_gre.c --ANK 911da177e4SLinus Torvalds */ 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds 944fc268d2SRandy Dunlap #include <linux/capability.h> 951da177e4SLinus Torvalds #include <linux/module.h> 961da177e4SLinus Torvalds #include <linux/types.h> 971da177e4SLinus Torvalds #include <linux/kernel.h> 985a0e3ad6STejun Heo #include <linux/slab.h> 991da177e4SLinus Torvalds #include <asm/uaccess.h> 1001da177e4SLinus Torvalds #include <linux/skbuff.h> 1011da177e4SLinus Torvalds #include <linux/netdevice.h> 1021da177e4SLinus Torvalds #include <linux/in.h> 1031da177e4SLinus Torvalds #include <linux/tcp.h> 1041da177e4SLinus Torvalds #include <linux/udp.h> 1051da177e4SLinus Torvalds #include <linux/if_arp.h> 1061da177e4SLinus Torvalds #include <linux/mroute.h> 1071da177e4SLinus Torvalds #include <linux/init.h> 1081da177e4SLinus Torvalds #include <linux/netfilter_ipv4.h> 10946f25dffSKris Katterjohn #include <linux/if_ether.h> 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds #include <net/sock.h> 1121da177e4SLinus Torvalds #include <net/ip.h> 1131da177e4SLinus Torvalds #include <net/icmp.h> 114c5441932SPravin B Shelar #include <net/ip_tunnels.h> 1151da177e4SLinus Torvalds #include <net/inet_ecn.h> 1161da177e4SLinus Torvalds #include <net/xfrm.h> 11710dc4c7bSPavel Emelyanov #include <net/net_namespace.h> 11810dc4c7bSPavel Emelyanov #include <net/netns/generic.h> 1191da177e4SLinus Torvalds 120eccc1bb8Sstephen hemminger static bool log_ecn_error = true; 121eccc1bb8Sstephen hemminger module_param(log_ecn_error, bool, 0644); 122eccc1bb8Sstephen hemminger MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); 123eccc1bb8Sstephen hemminger 124f99189b1SEric Dumazet static int ipip_net_id __read_mostly; 12510dc4c7bSPavel Emelyanov 1263c97af99SEric Dumazet static int ipip_tunnel_init(struct net_device *dev); 1270974658dSNicolas Dichtel static struct rtnl_link_ops ipip_link_ops __read_mostly; 1281da177e4SLinus Torvalds 129d2acc347SHerbert Xu static int ipip_err(struct sk_buff *skb, u32 info) 1301da177e4SLinus Torvalds { 1311da177e4SLinus Torvalds 132071f92d0SRami Rosen /* All the routers (except for Linux) return only 1331da177e4SLinus Torvalds 8 bytes of packet payload. It means, that precise relaying of 1341da177e4SLinus Torvalds ICMP in the real Internet is absolutely infeasible. 1351da177e4SLinus Torvalds */ 136fd58156eSPravin B Shelar struct net *net = dev_net(skb->dev); 137fd58156eSPravin B Shelar struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 138b71d1d42SEric Dumazet const struct iphdr *iph = (const struct iphdr *)skb->data; 1391da177e4SLinus Torvalds struct ip_tunnel *t; 140d2acc347SHerbert Xu int err; 141fd58156eSPravin B Shelar const int type = icmp_hdr(skb)->type; 142fd58156eSPravin B Shelar const int code = icmp_hdr(skb)->code; 1431da177e4SLinus Torvalds 144d2acc347SHerbert Xu err = -ENOENT; 145fd58156eSPravin B Shelar t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 146fd58156eSPravin B Shelar iph->daddr, iph->saddr, 0); 14736393395SDavid S. Miller if (t == NULL) 14836393395SDavid S. Miller goto out; 14936393395SDavid S. Miller 15036393395SDavid S. Miller if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 15136393395SDavid S. Miller ipv4_update_pmtu(skb, dev_net(skb->dev), info, 15236393395SDavid S. Miller t->dev->ifindex, 0, IPPROTO_IPIP, 0); 15336393395SDavid S. Miller err = 0; 15436393395SDavid S. Miller goto out; 15536393395SDavid S. Miller } 15636393395SDavid S. Miller 15755be7a9cSDavid S. Miller if (type == ICMP_REDIRECT) { 15855be7a9cSDavid S. Miller ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0, 15955be7a9cSDavid S. Miller IPPROTO_IPIP, 0); 16055be7a9cSDavid S. Miller err = 0; 16155be7a9cSDavid S. Miller goto out; 16255be7a9cSDavid S. Miller } 16355be7a9cSDavid S. Miller 16436393395SDavid S. Miller if (t->parms.iph.daddr == 0) 1651da177e4SLinus Torvalds goto out; 166d2acc347SHerbert Xu 167d2acc347SHerbert Xu err = 0; 1681da177e4SLinus Torvalds if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 1691da177e4SLinus Torvalds goto out; 1701da177e4SLinus Torvalds 17126d94b46SWei Yongjun if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO)) 1721da177e4SLinus Torvalds t->err_count++; 1731da177e4SLinus Torvalds else 1741da177e4SLinus Torvalds t->err_count = 1; 1751da177e4SLinus Torvalds t->err_time = jiffies; 176b0558ef2Sstephen hemminger 177fd58156eSPravin B Shelar out: 178d2acc347SHerbert Xu return err; 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds 181fd58156eSPravin B Shelar static const struct tnl_ptk_info tpi = { 182fd58156eSPravin B Shelar /* no tunnel info required for ipip. */ 183fd58156eSPravin B Shelar .proto = htons(ETH_P_IP), 184fd58156eSPravin B Shelar }; 185fd58156eSPravin B Shelar 1861da177e4SLinus Torvalds static int ipip_rcv(struct sk_buff *skb) 1871da177e4SLinus Torvalds { 188fd58156eSPravin B Shelar struct net *net = dev_net(skb->dev); 189fd58156eSPravin B Shelar struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 1901da177e4SLinus Torvalds struct ip_tunnel *tunnel; 1913d7b46cdSPravin B Shelar const struct iphdr *iph; 1921da177e4SLinus Torvalds 1933d7b46cdSPravin B Shelar iph = ip_hdr(skb); 194fd58156eSPravin B Shelar tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 195fd58156eSPravin B Shelar iph->saddr, iph->daddr, 0); 196fd58156eSPravin B Shelar if (tunnel) { 197eccc1bb8Sstephen hemminger if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) 198eccc1bb8Sstephen hemminger goto drop; 199*737e828bSLi Hongjun if (iptunnel_pull_header(skb, 0, tpi.proto)) 200*737e828bSLi Hongjun goto drop; 201fd58156eSPravin B Shelar return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); 2021da177e4SLinus Torvalds } 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds return -1; 205eccc1bb8Sstephen hemminger 206eccc1bb8Sstephen hemminger drop: 207eccc1bb8Sstephen hemminger kfree_skb(skb); 208eccc1bb8Sstephen hemminger return 0; 2091da177e4SLinus Torvalds } 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds /* 2121da177e4SLinus Torvalds * This function assumes it is being called from dev_queue_xmit() 2131da177e4SLinus Torvalds * and that skb is filled properly by that function. 2141da177e4SLinus Torvalds */ 2156fef4c0cSStephen Hemminger static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 2161da177e4SLinus Torvalds { 2172941a486SPatrick McHardy struct ip_tunnel *tunnel = netdev_priv(dev); 218b71d1d42SEric Dumazet const struct iphdr *tiph = &tunnel->parms.iph; 2191da177e4SLinus Torvalds 220fd58156eSPravin B Shelar if (unlikely(skb->protocol != htons(ETH_P_IP))) 2211da177e4SLinus Torvalds goto tx_error; 222cef401deSEric Dumazet 223fd58156eSPravin B Shelar if (likely(!skb->encapsulation)) { 2244f3ed920SPravin B Shelar skb_reset_inner_headers(skb); 2254f3ed920SPravin B Shelar skb->encapsulation = 1; 2264f3ed920SPravin B Shelar } 2274f3ed920SPravin B Shelar 228bf3d6a8fSNicolas Dichtel ip_tunnel_xmit(skb, dev, tiph, tiph->protocol); 2296ed10654SPatrick McHardy return NETDEV_TX_OK; 2301da177e4SLinus Torvalds 2311da177e4SLinus Torvalds tx_error: 2323c97af99SEric Dumazet dev->stats.tx_errors++; 2331da177e4SLinus Torvalds dev_kfree_skb(skb); 2346ed10654SPatrick McHardy return NETDEV_TX_OK; 2351da177e4SLinus Torvalds } 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds static int 2381da177e4SLinus Torvalds ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 2391da177e4SLinus Torvalds { 2401da177e4SLinus Torvalds int err = 0; 2411da177e4SLinus Torvalds struct ip_tunnel_parm p; 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 244fd58156eSPravin B Shelar return -EFAULT; 2451da177e4SLinus Torvalds 2463b7b514fSCong Wang if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) { 2471da177e4SLinus Torvalds if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP || 2481da177e4SLinus Torvalds p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF))) 249fd58156eSPravin B Shelar return -EINVAL; 2503b7b514fSCong Wang } 2513b7b514fSCong Wang 2523b7b514fSCong Wang p.i_key = p.o_key = p.i_flags = p.o_flags = 0; 2531da177e4SLinus Torvalds if (p.iph.ttl) 2541da177e4SLinus Torvalds p.iph.frag_off |= htons(IP_DF); 2551da177e4SLinus Torvalds 256fd58156eSPravin B Shelar err = ip_tunnel_ioctl(dev, &p, cmd); 257fd58156eSPravin B Shelar if (err) 2581da177e4SLinus Torvalds return err; 2591da177e4SLinus Torvalds 260fd58156eSPravin B Shelar if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 261fd58156eSPravin B Shelar return -EFAULT; 262fd58156eSPravin B Shelar 2631da177e4SLinus Torvalds return 0; 2641da177e4SLinus Torvalds } 2651da177e4SLinus Torvalds 26623a12b14SStephen Hemminger static const struct net_device_ops ipip_netdev_ops = { 267fd58156eSPravin B Shelar .ndo_init = ipip_tunnel_init, 268fd58156eSPravin B Shelar .ndo_uninit = ip_tunnel_uninit, 26923a12b14SStephen Hemminger .ndo_start_xmit = ipip_tunnel_xmit, 27023a12b14SStephen Hemminger .ndo_do_ioctl = ipip_tunnel_ioctl, 271fd58156eSPravin B Shelar .ndo_change_mtu = ip_tunnel_change_mtu, 272fd58156eSPravin B Shelar .ndo_get_stats64 = ip_tunnel_get_stats64, 27323a12b14SStephen Hemminger }; 27423a12b14SStephen Hemminger 275c3b89fbbSEric Dumazet #define IPIP_FEATURES (NETIF_F_SG | \ 276c3b89fbbSEric Dumazet NETIF_F_FRAGLIST | \ 277c3b89fbbSEric Dumazet NETIF_F_HIGHDMA | \ 278c3b89fbbSEric Dumazet NETIF_F_HW_CSUM) 279c3b89fbbSEric Dumazet 2801da177e4SLinus Torvalds static void ipip_tunnel_setup(struct net_device *dev) 2811da177e4SLinus Torvalds { 28223a12b14SStephen Hemminger dev->netdev_ops = &ipip_netdev_ops; 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds dev->type = ARPHRD_TUNNEL; 2851da177e4SLinus Torvalds dev->flags = IFF_NOARP; 2861da177e4SLinus Torvalds dev->iflink = 0; 2871da177e4SLinus Torvalds dev->addr_len = 4; 2880a826406SPavel Emelyanov dev->features |= NETIF_F_NETNS_LOCAL; 289153f0943SEric Dumazet dev->features |= NETIF_F_LLTX; 29028e72216SEric Dumazet dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 291c3b89fbbSEric Dumazet 292c3b89fbbSEric Dumazet dev->features |= IPIP_FEATURES; 293c3b89fbbSEric Dumazet dev->hw_features |= IPIP_FEATURES; 294fd58156eSPravin B Shelar ip_tunnel_setup(dev, ipip_net_id); 2951da177e4SLinus Torvalds } 2961da177e4SLinus Torvalds 2973c97af99SEric Dumazet static int ipip_tunnel_init(struct net_device *dev) 2981da177e4SLinus Torvalds { 29923a12b14SStephen Hemminger struct ip_tunnel *tunnel = netdev_priv(dev); 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvalds memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); 3021da177e4SLinus Torvalds memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); 3031da177e4SLinus Torvalds 304fd58156eSPravin B Shelar tunnel->hlen = 0; 305fd58156eSPravin B Shelar tunnel->parms.iph.protocol = IPPROTO_IPIP; 306fd58156eSPravin B Shelar return ip_tunnel_init(dev); 3071da177e4SLinus Torvalds } 3081da177e4SLinus Torvalds 309be42da0eSNicolas Dichtel static void ipip_netlink_parms(struct nlattr *data[], 310be42da0eSNicolas Dichtel struct ip_tunnel_parm *parms) 311be42da0eSNicolas Dichtel { 312be42da0eSNicolas Dichtel memset(parms, 0, sizeof(*parms)); 313be42da0eSNicolas Dichtel 314be42da0eSNicolas Dichtel parms->iph.version = 4; 315be42da0eSNicolas Dichtel parms->iph.protocol = IPPROTO_IPIP; 316be42da0eSNicolas Dichtel parms->iph.ihl = 5; 317be42da0eSNicolas Dichtel 318be42da0eSNicolas Dichtel if (!data) 319be42da0eSNicolas Dichtel return; 320be42da0eSNicolas Dichtel 321be42da0eSNicolas Dichtel if (data[IFLA_IPTUN_LINK]) 322be42da0eSNicolas Dichtel parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]); 323be42da0eSNicolas Dichtel 324be42da0eSNicolas Dichtel if (data[IFLA_IPTUN_LOCAL]) 325fea379b2SNicolas Dichtel parms->iph.saddr = nla_get_be32(data[IFLA_IPTUN_LOCAL]); 326be42da0eSNicolas Dichtel 327be42da0eSNicolas Dichtel if (data[IFLA_IPTUN_REMOTE]) 328fea379b2SNicolas Dichtel parms->iph.daddr = nla_get_be32(data[IFLA_IPTUN_REMOTE]); 329be42da0eSNicolas Dichtel 330be42da0eSNicolas Dichtel if (data[IFLA_IPTUN_TTL]) { 331be42da0eSNicolas Dichtel parms->iph.ttl = nla_get_u8(data[IFLA_IPTUN_TTL]); 332be42da0eSNicolas Dichtel if (parms->iph.ttl) 333be42da0eSNicolas Dichtel parms->iph.frag_off = htons(IP_DF); 334be42da0eSNicolas Dichtel } 335be42da0eSNicolas Dichtel 336be42da0eSNicolas Dichtel if (data[IFLA_IPTUN_TOS]) 337be42da0eSNicolas Dichtel parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]); 338be42da0eSNicolas Dichtel 339be42da0eSNicolas Dichtel if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC])) 340be42da0eSNicolas Dichtel parms->iph.frag_off = htons(IP_DF); 341be42da0eSNicolas Dichtel } 342be42da0eSNicolas Dichtel 343be42da0eSNicolas Dichtel static int ipip_newlink(struct net *src_net, struct net_device *dev, 344be42da0eSNicolas Dichtel struct nlattr *tb[], struct nlattr *data[]) 345be42da0eSNicolas Dichtel { 346fd58156eSPravin B Shelar struct ip_tunnel_parm p; 347be42da0eSNicolas Dichtel 348fd58156eSPravin B Shelar ipip_netlink_parms(data, &p); 349fd58156eSPravin B Shelar return ip_tunnel_newlink(dev, tb, &p); 350be42da0eSNicolas Dichtel } 351be42da0eSNicolas Dichtel 352be42da0eSNicolas Dichtel static int ipip_changelink(struct net_device *dev, struct nlattr *tb[], 353be42da0eSNicolas Dichtel struct nlattr *data[]) 354be42da0eSNicolas Dichtel { 355be42da0eSNicolas Dichtel struct ip_tunnel_parm p; 356be42da0eSNicolas Dichtel 357be42da0eSNicolas Dichtel ipip_netlink_parms(data, &p); 358be42da0eSNicolas Dichtel 359be42da0eSNicolas Dichtel if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) || 360be42da0eSNicolas Dichtel (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr)) 361be42da0eSNicolas Dichtel return -EINVAL; 362be42da0eSNicolas Dichtel 363fd58156eSPravin B Shelar return ip_tunnel_changelink(dev, tb, &p); 364be42da0eSNicolas Dichtel } 365be42da0eSNicolas Dichtel 3660974658dSNicolas Dichtel static size_t ipip_get_size(const struct net_device *dev) 3670974658dSNicolas Dichtel { 3680974658dSNicolas Dichtel return 3690974658dSNicolas Dichtel /* IFLA_IPTUN_LINK */ 3700974658dSNicolas Dichtel nla_total_size(4) + 3710974658dSNicolas Dichtel /* IFLA_IPTUN_LOCAL */ 3720974658dSNicolas Dichtel nla_total_size(4) + 3730974658dSNicolas Dichtel /* IFLA_IPTUN_REMOTE */ 3740974658dSNicolas Dichtel nla_total_size(4) + 3750974658dSNicolas Dichtel /* IFLA_IPTUN_TTL */ 3760974658dSNicolas Dichtel nla_total_size(1) + 3770974658dSNicolas Dichtel /* IFLA_IPTUN_TOS */ 3780974658dSNicolas Dichtel nla_total_size(1) + 379befe2aa1SNicolas Dichtel /* IFLA_IPTUN_PMTUDISC */ 380befe2aa1SNicolas Dichtel nla_total_size(1) + 3810974658dSNicolas Dichtel 0; 3820974658dSNicolas Dichtel } 3830974658dSNicolas Dichtel 3840974658dSNicolas Dichtel static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev) 3850974658dSNicolas Dichtel { 3860974658dSNicolas Dichtel struct ip_tunnel *tunnel = netdev_priv(dev); 3870974658dSNicolas Dichtel struct ip_tunnel_parm *parm = &tunnel->parms; 3880974658dSNicolas Dichtel 3890974658dSNicolas Dichtel if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || 3900974658dSNicolas Dichtel nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || 3910974658dSNicolas Dichtel nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || 3920974658dSNicolas Dichtel nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || 393befe2aa1SNicolas Dichtel nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) || 394befe2aa1SNicolas Dichtel nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, 395befe2aa1SNicolas Dichtel !!(parm->iph.frag_off & htons(IP_DF)))) 3960974658dSNicolas Dichtel goto nla_put_failure; 3970974658dSNicolas Dichtel return 0; 3980974658dSNicolas Dichtel 3990974658dSNicolas Dichtel nla_put_failure: 4000974658dSNicolas Dichtel return -EMSGSIZE; 4010974658dSNicolas Dichtel } 4020974658dSNicolas Dichtel 403be42da0eSNicolas Dichtel static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = { 404be42da0eSNicolas Dichtel [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, 405be42da0eSNicolas Dichtel [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, 406be42da0eSNicolas Dichtel [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, 407be42da0eSNicolas Dichtel [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, 408be42da0eSNicolas Dichtel [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, 409be42da0eSNicolas Dichtel [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, 410be42da0eSNicolas Dichtel }; 411be42da0eSNicolas Dichtel 4120974658dSNicolas Dichtel static struct rtnl_link_ops ipip_link_ops __read_mostly = { 4130974658dSNicolas Dichtel .kind = "ipip", 4140974658dSNicolas Dichtel .maxtype = IFLA_IPTUN_MAX, 415be42da0eSNicolas Dichtel .policy = ipip_policy, 4160974658dSNicolas Dichtel .priv_size = sizeof(struct ip_tunnel), 417be42da0eSNicolas Dichtel .setup = ipip_tunnel_setup, 418be42da0eSNicolas Dichtel .newlink = ipip_newlink, 419be42da0eSNicolas Dichtel .changelink = ipip_changelink, 420fd58156eSPravin B Shelar .dellink = ip_tunnel_dellink, 4210974658dSNicolas Dichtel .get_size = ipip_get_size, 4220974658dSNicolas Dichtel .fill_info = ipip_fill_info, 4230974658dSNicolas Dichtel }; 4240974658dSNicolas Dichtel 4256dcd814bSEric Dumazet static struct xfrm_tunnel ipip_handler __read_mostly = { 4261da177e4SLinus Torvalds .handler = ipip_rcv, 4271da177e4SLinus Torvalds .err_handler = ipip_err, 428d2acc347SHerbert Xu .priority = 1, 4291da177e4SLinus Torvalds }; 4301da177e4SLinus Torvalds 4312c8c1e72SAlexey Dobriyan static int __net_init ipip_init_net(struct net *net) 43210dc4c7bSPavel Emelyanov { 433fd58156eSPravin B Shelar return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0"); 43410dc4c7bSPavel Emelyanov } 43510dc4c7bSPavel Emelyanov 4362c8c1e72SAlexey Dobriyan static void __net_exit ipip_exit_net(struct net *net) 43710dc4c7bSPavel Emelyanov { 438fd58156eSPravin B Shelar struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 439fd58156eSPravin B Shelar ip_tunnel_delete_net(itn); 44010dc4c7bSPavel Emelyanov } 44110dc4c7bSPavel Emelyanov 44210dc4c7bSPavel Emelyanov static struct pernet_operations ipip_net_ops = { 44310dc4c7bSPavel Emelyanov .init = ipip_init_net, 44410dc4c7bSPavel Emelyanov .exit = ipip_exit_net, 44586de8a63SEric W. Biederman .id = &ipip_net_id, 446fd58156eSPravin B Shelar .size = sizeof(struct ip_tunnel_net), 44710dc4c7bSPavel Emelyanov }; 44810dc4c7bSPavel Emelyanov 4491da177e4SLinus Torvalds static int __init ipip_init(void) 4501da177e4SLinus Torvalds { 4511da177e4SLinus Torvalds int err; 4521da177e4SLinus Torvalds 453fd58156eSPravin B Shelar pr_info("ipip: IPv4 over IPv4 tunneling driver\n"); 4541da177e4SLinus Torvalds 45586de8a63SEric W. Biederman err = register_pernet_device(&ipip_net_ops); 456d5aa407fSAlexey Dobriyan if (err < 0) 457d5aa407fSAlexey Dobriyan return err; 458d5aa407fSAlexey Dobriyan err = xfrm4_tunnel_register(&ipip_handler, AF_INET); 459d5aa407fSAlexey Dobriyan if (err < 0) { 460058bd4d2SJoe Perches pr_info("%s: can't register tunnel\n", __func__); 4610974658dSNicolas Dichtel goto xfrm_tunnel_failed; 462d5aa407fSAlexey Dobriyan } 4630974658dSNicolas Dichtel err = rtnl_link_register(&ipip_link_ops); 4640974658dSNicolas Dichtel if (err < 0) 4650974658dSNicolas Dichtel goto rtnl_link_failed; 4660974658dSNicolas Dichtel 4670974658dSNicolas Dichtel out: 468b9855c54SPavel Emelyanov return err; 4690974658dSNicolas Dichtel 4700974658dSNicolas Dichtel rtnl_link_failed: 4710974658dSNicolas Dichtel xfrm4_tunnel_deregister(&ipip_handler, AF_INET); 4720974658dSNicolas Dichtel xfrm_tunnel_failed: 4730974658dSNicolas Dichtel unregister_pernet_device(&ipip_net_ops); 4740974658dSNicolas Dichtel goto out; 4751da177e4SLinus Torvalds } 4761da177e4SLinus Torvalds 4771da177e4SLinus Torvalds static void __exit ipip_fini(void) 4781da177e4SLinus Torvalds { 4790974658dSNicolas Dichtel rtnl_link_unregister(&ipip_link_ops); 480c0d56408SKazunori MIYAZAWA if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) 481058bd4d2SJoe Perches pr_info("%s: can't deregister tunnel\n", __func__); 4821da177e4SLinus Torvalds 48386de8a63SEric W. Biederman unregister_pernet_device(&ipip_net_ops); 4841da177e4SLinus Torvalds } 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds module_init(ipip_init); 4871da177e4SLinus Torvalds module_exit(ipip_fini); 4881da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 4898909c9adSVasiliy Kulikov MODULE_ALIAS_NETDEV("tunl0"); 490