xref: /openbmc/linux/net/openvswitch/vport-gre.c (revision f3a63cce)
1c9422999SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2aa310701SPravin B Shelar /*
38c8b1b83SPravin B Shelar  * Copyright (c) 2007-2014 Nicira, Inc.
4aa310701SPravin B Shelar  */
5aa310701SPravin B Shelar 
6aa310701SPravin B Shelar #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7aa310701SPravin B Shelar 
8aa310701SPravin B Shelar #include <linux/if.h>
9aa310701SPravin B Shelar #include <linux/skbuff.h>
10aa310701SPravin B Shelar #include <linux/ip.h>
11aa310701SPravin B Shelar #include <linux/if_tunnel.h>
12aa310701SPravin B Shelar #include <linux/if_vlan.h>
13aa310701SPravin B Shelar #include <linux/in.h>
14aa310701SPravin B Shelar #include <linux/in_route.h>
15aa310701SPravin B Shelar #include <linux/inetdevice.h>
16aa310701SPravin B Shelar #include <linux/jhash.h>
17aa310701SPravin B Shelar #include <linux/list.h>
18aa310701SPravin B Shelar #include <linux/kernel.h>
1962b9c8d0SThomas Graf #include <linux/module.h>
20aa310701SPravin B Shelar #include <linux/workqueue.h>
21aa310701SPravin B Shelar #include <linux/rculist.h>
22aa310701SPravin B Shelar #include <net/route.h>
23aa310701SPravin B Shelar #include <net/xfrm.h>
24aa310701SPravin B Shelar 
25aa310701SPravin B Shelar #include <net/icmp.h>
26aa310701SPravin B Shelar #include <net/ip.h>
27aa310701SPravin B Shelar #include <net/ip_tunnels.h>
28aa310701SPravin B Shelar #include <net/gre.h>
29aa310701SPravin B Shelar #include <net/net_namespace.h>
30aa310701SPravin B Shelar #include <net/netns/generic.h>
31aa310701SPravin B Shelar #include <net/protocol.h>
32aa310701SPravin B Shelar 
33aa310701SPravin B Shelar #include "datapath.h"
34aa310701SPravin B Shelar #include "vport.h"
35b2acd1dcSPravin B Shelar #include "vport-netdev.h"
36aa310701SPravin B Shelar 
3762b9c8d0SThomas Graf static struct vport_ops ovs_gre_vport_ops;
3862b9c8d0SThomas Graf 
gre_tnl_create(const struct vport_parms * parms)39b2acd1dcSPravin B Shelar static struct vport *gre_tnl_create(const struct vport_parms *parms)
40aa310701SPravin B Shelar {
41b2acd1dcSPravin B Shelar 	struct net *net = ovs_dp_get_net(parms->dp);
42b2acd1dcSPravin B Shelar 	struct net_device *dev;
43e0bb8c44SWei Zhang 	struct vport *vport;
444b5b9ba5SMartynas Pumputis 	int err;
45e0bb8c44SWei Zhang 
46b2acd1dcSPravin B Shelar 	vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms);
47b2acd1dcSPravin B Shelar 	if (IS_ERR(vport))
48b2acd1dcSPravin B Shelar 		return vport;
49e0bb8c44SWei Zhang 
50b2acd1dcSPravin B Shelar 	rtnl_lock();
51b2acd1dcSPravin B Shelar 	dev = gretap_fb_dev_create(net, parms->name, NET_NAME_USER);
52b2acd1dcSPravin B Shelar 	if (IS_ERR(dev)) {
53b2acd1dcSPravin B Shelar 		rtnl_unlock();
54b2acd1dcSPravin B Shelar 		ovs_vport_free(vport);
55b2acd1dcSPravin B Shelar 		return ERR_CAST(dev);
56e0bb8c44SWei Zhang 	}
57e0bb8c44SWei Zhang 
58567c5e13SPetr Machata 	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
594b5b9ba5SMartynas Pumputis 	if (err < 0) {
60*f3a63cceSHangbin Liu 		rtnl_delete_link(dev, 0, NULL);
61b2acd1dcSPravin B Shelar 		rtnl_unlock();
624b5b9ba5SMartynas Pumputis 		ovs_vport_free(vport);
634b5b9ba5SMartynas Pumputis 		return ERR_PTR(err);
644b5b9ba5SMartynas Pumputis 	}
65aa310701SPravin B Shelar 
664b5b9ba5SMartynas Pumputis 	rtnl_unlock();
67b2acd1dcSPravin B Shelar 	return vport;
68aa310701SPravin B Shelar }
69aa310701SPravin B Shelar 
gre_create(const struct vport_parms * parms)70aa310701SPravin B Shelar static struct vport *gre_create(const struct vport_parms *parms)
71aa310701SPravin B Shelar {
72aa310701SPravin B Shelar 	struct vport *vport;
73aa310701SPravin B Shelar 
74b2acd1dcSPravin B Shelar 	vport = gre_tnl_create(parms);
75aa310701SPravin B Shelar 	if (IS_ERR(vport))
76aa310701SPravin B Shelar 		return vport;
77aa310701SPravin B Shelar 
78b2acd1dcSPravin B Shelar 	return ovs_netdev_link(vport, parms->name);
79aa310701SPravin B Shelar }
80aa310701SPravin B Shelar 
8162b9c8d0SThomas Graf static struct vport_ops ovs_gre_vport_ops = {
82aa310701SPravin B Shelar 	.type		= OVS_VPORT_TYPE_GRE,
83aa310701SPravin B Shelar 	.create		= gre_create,
84aec15924SPravin B Shelar 	.send		= dev_queue_xmit,
85b2acd1dcSPravin B Shelar 	.destroy	= ovs_netdev_tunnel_destroy,
86aa310701SPravin B Shelar };
8762b9c8d0SThomas Graf 
ovs_gre_tnl_init(void)8862b9c8d0SThomas Graf static int __init ovs_gre_tnl_init(void)
8962b9c8d0SThomas Graf {
9062b9c8d0SThomas Graf 	return ovs_vport_ops_register(&ovs_gre_vport_ops);
9162b9c8d0SThomas Graf }
9262b9c8d0SThomas Graf 
ovs_gre_tnl_exit(void)9362b9c8d0SThomas Graf static void __exit ovs_gre_tnl_exit(void)
9462b9c8d0SThomas Graf {
9562b9c8d0SThomas Graf 	ovs_vport_ops_unregister(&ovs_gre_vport_ops);
9662b9c8d0SThomas Graf }
9762b9c8d0SThomas Graf 
9862b9c8d0SThomas Graf module_init(ovs_gre_tnl_init);
9962b9c8d0SThomas Graf module_exit(ovs_gre_tnl_exit);
10062b9c8d0SThomas Graf 
10162b9c8d0SThomas Graf MODULE_DESCRIPTION("OVS: GRE switching port");
10262b9c8d0SThomas Graf MODULE_LICENSE("GPL");
10362b9c8d0SThomas Graf MODULE_ALIAS("vport-type-3");
104