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