1aa310701SPravin B Shelar /* 28c8b1b83SPravin B Shelar * Copyright (c) 2007-2014 Nicira, Inc. 3aa310701SPravin B Shelar * 4aa310701SPravin B Shelar * This program is free software; you can redistribute it and/or 5aa310701SPravin B Shelar * modify it under the terms of version 2 of the GNU General Public 6aa310701SPravin B Shelar * License as published by the Free Software Foundation. 7aa310701SPravin B Shelar * 8aa310701SPravin B Shelar * This program is distributed in the hope that it will be useful, but 9aa310701SPravin B Shelar * WITHOUT ANY WARRANTY; without even the implied warranty of 10aa310701SPravin B Shelar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11aa310701SPravin B Shelar * General Public License for more details. 12aa310701SPravin B Shelar * 13aa310701SPravin B Shelar * You should have received a copy of the GNU General Public License 14aa310701SPravin B Shelar * along with this program; if not, write to the Free Software 15aa310701SPravin B Shelar * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16aa310701SPravin B Shelar * 02110-1301, USA 17aa310701SPravin B Shelar */ 18aa310701SPravin B Shelar 19aa310701SPravin B Shelar #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20aa310701SPravin B Shelar 21aa310701SPravin B Shelar #include <linux/if.h> 22aa310701SPravin B Shelar #include <linux/skbuff.h> 23aa310701SPravin B Shelar #include <linux/ip.h> 24aa310701SPravin B Shelar #include <linux/if_tunnel.h> 25aa310701SPravin B Shelar #include <linux/if_vlan.h> 26aa310701SPravin B Shelar #include <linux/in.h> 27aa310701SPravin B Shelar #include <linux/in_route.h> 28aa310701SPravin B Shelar #include <linux/inetdevice.h> 29aa310701SPravin B Shelar #include <linux/jhash.h> 30aa310701SPravin B Shelar #include <linux/list.h> 31aa310701SPravin B Shelar #include <linux/kernel.h> 3262b9c8d0SThomas Graf #include <linux/module.h> 33aa310701SPravin B Shelar #include <linux/workqueue.h> 34aa310701SPravin B Shelar #include <linux/rculist.h> 35aa310701SPravin B Shelar #include <net/route.h> 36aa310701SPravin B Shelar #include <net/xfrm.h> 37aa310701SPravin B Shelar 38aa310701SPravin B Shelar #include <net/icmp.h> 39aa310701SPravin B Shelar #include <net/ip.h> 40aa310701SPravin B Shelar #include <net/ip_tunnels.h> 41aa310701SPravin B Shelar #include <net/gre.h> 42aa310701SPravin B Shelar #include <net/net_namespace.h> 43aa310701SPravin B Shelar #include <net/netns/generic.h> 44aa310701SPravin B Shelar #include <net/protocol.h> 45aa310701SPravin B Shelar 46aa310701SPravin B Shelar #include "datapath.h" 47aa310701SPravin B Shelar #include "vport.h" 48b2acd1dcSPravin B Shelar #include "vport-netdev.h" 49aa310701SPravin B Shelar 5062b9c8d0SThomas Graf static struct vport_ops ovs_gre_vport_ops; 5162b9c8d0SThomas Graf 52b2acd1dcSPravin B Shelar static struct vport *gre_tnl_create(const struct vport_parms *parms) 53aa310701SPravin B Shelar { 54b2acd1dcSPravin B Shelar struct net *net = ovs_dp_get_net(parms->dp); 55b2acd1dcSPravin B Shelar struct net_device *dev; 56e0bb8c44SWei Zhang struct vport *vport; 57e0bb8c44SWei Zhang 58b2acd1dcSPravin B Shelar vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms); 59b2acd1dcSPravin B Shelar if (IS_ERR(vport)) 60b2acd1dcSPravin B Shelar return vport; 61e0bb8c44SWei Zhang 62b2acd1dcSPravin B Shelar rtnl_lock(); 63b2acd1dcSPravin B Shelar dev = gretap_fb_dev_create(net, parms->name, NET_NAME_USER); 64b2acd1dcSPravin B Shelar if (IS_ERR(dev)) { 65b2acd1dcSPravin B Shelar rtnl_unlock(); 66b2acd1dcSPravin B Shelar ovs_vport_free(vport); 67b2acd1dcSPravin B Shelar return ERR_CAST(dev); 68e0bb8c44SWei Zhang } 69e0bb8c44SWei Zhang 70b2acd1dcSPravin B Shelar dev_change_flags(dev, dev->flags | IFF_UP); 71b2acd1dcSPravin B Shelar rtnl_unlock(); 72aa310701SPravin B Shelar 73b2acd1dcSPravin B Shelar return vport; 74aa310701SPravin B Shelar } 75aa310701SPravin B Shelar 76aa310701SPravin B Shelar static struct vport *gre_create(const struct vport_parms *parms) 77aa310701SPravin B Shelar { 78aa310701SPravin B Shelar struct vport *vport; 79aa310701SPravin B Shelar 80b2acd1dcSPravin B Shelar vport = gre_tnl_create(parms); 81aa310701SPravin B Shelar if (IS_ERR(vport)) 82aa310701SPravin B Shelar return vport; 83aa310701SPravin B Shelar 84b2acd1dcSPravin B Shelar return ovs_netdev_link(vport, parms->name); 85aa310701SPravin B Shelar } 86aa310701SPravin B Shelar 878f0aad6fSWenyu Zhang static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, 884c222798SPravin B Shelar struct dp_upcall_info *upcall) 898f0aad6fSWenyu Zhang { 904c222798SPravin B Shelar return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp), 913eedb41fSPravin B Shelar skb, IPPROTO_GRE, 0, 0); 928f0aad6fSWenyu Zhang } 938f0aad6fSWenyu Zhang 9462b9c8d0SThomas Graf static struct vport_ops ovs_gre_vport_ops = { 95aa310701SPravin B Shelar .type = OVS_VPORT_TYPE_GRE, 96aa310701SPravin B Shelar .create = gre_create, 97b2acd1dcSPravin B Shelar .send = ovs_netdev_send, 988f0aad6fSWenyu Zhang .get_egress_tun_info = gre_get_egress_tun_info, 99b2acd1dcSPravin B Shelar .destroy = ovs_netdev_tunnel_destroy, 10062b9c8d0SThomas Graf .owner = THIS_MODULE, 101aa310701SPravin B Shelar }; 10262b9c8d0SThomas Graf 10362b9c8d0SThomas Graf static int __init ovs_gre_tnl_init(void) 10462b9c8d0SThomas Graf { 10562b9c8d0SThomas Graf return ovs_vport_ops_register(&ovs_gre_vport_ops); 10662b9c8d0SThomas Graf } 10762b9c8d0SThomas Graf 10862b9c8d0SThomas Graf static void __exit ovs_gre_tnl_exit(void) 10962b9c8d0SThomas Graf { 11062b9c8d0SThomas Graf ovs_vport_ops_unregister(&ovs_gre_vport_ops); 11162b9c8d0SThomas Graf } 11262b9c8d0SThomas Graf 11362b9c8d0SThomas Graf module_init(ovs_gre_tnl_init); 11462b9c8d0SThomas Graf module_exit(ovs_gre_tnl_exit); 11562b9c8d0SThomas Graf 11662b9c8d0SThomas Graf MODULE_DESCRIPTION("OVS: GRE switching port"); 11762b9c8d0SThomas Graf MODULE_LICENSE("GPL"); 11862b9c8d0SThomas Graf MODULE_ALIAS("vport-type-3"); 119