xref: /openbmc/linux/net/openvswitch/vport-gre.c (revision aec15924)
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,
97aec15924SPravin B Shelar 	.send		= dev_queue_xmit,
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