Skip to content

Commit

Permalink
ovs: Turn vports with dependencies into separate modules
Browse files Browse the repository at this point in the history
The internal and netdev vport remain part of openvswitch.ko. Encap
vports including vxlan, gre, and geneve can be built as separate
modules and are loaded on demand. Modules can be unloaded after use.
Datapath ports keep a reference to the vport module during their
lifetime.

Allows to remove the error prone maintenance of the global list
vport_ops_list.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Graf authored and David S. Miller committed Oct 28, 2014
1 parent cf7b200 commit 62b9c8d
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 68 deletions.
18 changes: 9 additions & 9 deletions net/openvswitch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ config OPENVSWITCH
If unsure, say N.

config OPENVSWITCH_GRE
bool "Open vSwitch GRE tunneling support"
tristate "Open vSwitch GRE tunneling support"
depends on INET
depends on OPENVSWITCH
depends on NET_IPGRE_DEMUX && !(OPENVSWITCH=y && NET_IPGRE_DEMUX=m)
default y
depends on NET_IPGRE_DEMUX
default OPENVSWITCH
---help---
If you say Y here, then the Open vSwitch will be able create GRE
vport.
Expand All @@ -43,11 +43,11 @@ config OPENVSWITCH_GRE
If unsure, say Y.

config OPENVSWITCH_VXLAN
bool "Open vSwitch VXLAN tunneling support"
tristate "Open vSwitch VXLAN tunneling support"
depends on INET
depends on OPENVSWITCH
depends on VXLAN && !(OPENVSWITCH=y && VXLAN=m)
default y
depends on VXLAN
default OPENVSWITCH
---help---
If you say Y here, then the Open vSwitch will be able create vxlan vport.

Expand All @@ -56,11 +56,11 @@ config OPENVSWITCH_VXLAN
If unsure, say Y.

config OPENVSWITCH_GENEVE
bool "Open vSwitch Geneve tunneling support"
tristate "Open vSwitch Geneve tunneling support"
depends on INET
depends on OPENVSWITCH
depends on GENEVE && !(OPENVSWITCH=y && GENEVE=m)
default y
depends on GENEVE
default OPENVSWITCH
---help---
If you say Y here, then the Open vSwitch will be able create geneve vport.

Expand Down
14 changes: 3 additions & 11 deletions net/openvswitch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ openvswitch-y := \
vport-internal_dev.o \
vport-netdev.o

ifneq ($(CONFIG_OPENVSWITCH_GENEVE),)
openvswitch-y += vport-geneve.o
endif

ifneq ($(CONFIG_OPENVSWITCH_VXLAN),)
openvswitch-y += vport-vxlan.o
endif

ifneq ($(CONFIG_OPENVSWITCH_GRE),)
openvswitch-y += vport-gre.o
endif
obj-$(CONFIG_OPENVSWITCH_GENEVE)+= vport-geneve.o
obj-$(CONFIG_OPENVSWITCH_VXLAN) += vport-vxlan.o
obj-$(CONFIG_OPENVSWITCH_GRE) += vport-gre.o
16 changes: 14 additions & 2 deletions net/openvswitch/datapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "vport-netdev.h"

int ovs_net_id __read_mostly;
EXPORT_SYMBOL(ovs_net_id);

static struct genl_family dp_packet_genl_family;
static struct genl_family dp_flow_genl_family;
Expand Down Expand Up @@ -1764,6 +1765,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;

ovs_lock();
restart:
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
err = -ENODEV;
if (!dp)
Expand Down Expand Up @@ -1795,8 +1797,11 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)

vport = new_vport(&parms);
err = PTR_ERR(vport);
if (IS_ERR(vport))
if (IS_ERR(vport)) {
if (err == -EAGAIN)
goto restart;
goto exit_unlock_free;
}

err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
info->snd_seq, 0, OVS_VPORT_CMD_NEW);
Expand Down Expand Up @@ -2112,12 +2117,18 @@ static int __init dp_init(void)
if (err)
goto error_netns_exit;

err = ovs_netdev_init();
if (err)
goto error_unreg_notifier;

err = dp_register_genl();
if (err < 0)
goto error_unreg_notifier;
goto error_unreg_netdev;

return 0;

error_unreg_netdev:
ovs_netdev_exit();
error_unreg_notifier:
unregister_netdevice_notifier(&ovs_dp_device_notifier);
error_netns_exit:
Expand All @@ -2137,6 +2148,7 @@ static int __init dp_init(void)
static void dp_cleanup(void)
{
dp_unregister_genl(ARRAY_SIZE(dp_genl_families));
ovs_netdev_exit();
unregister_netdevice_notifier(&ovs_dp_device_notifier);
unregister_pernet_device(&ovs_net_ops);
rcu_barrier();
Expand Down
23 changes: 22 additions & 1 deletion net/openvswitch/vport-geneve.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/rculist.h>
#include <linux/udp.h>
#include <linux/if_vlan.h>
#include <linux/module.h>

#include <net/geneve.h>
#include <net/icmp.h>
Expand All @@ -28,6 +29,8 @@
#include "datapath.h"
#include "vport.h"

static struct vport_ops ovs_geneve_vport_ops;

/**
* struct geneve_port - Keeps track of open UDP ports
* @gs: The socket created for this port number.
Expand Down Expand Up @@ -225,11 +228,29 @@ static const char *geneve_get_name(const struct vport *vport)
return geneve_port->name;
}

const struct vport_ops ovs_geneve_vport_ops = {
static struct vport_ops ovs_geneve_vport_ops = {
.type = OVS_VPORT_TYPE_GENEVE,
.create = geneve_tnl_create,
.destroy = geneve_tnl_destroy,
.get_name = geneve_get_name,
.get_options = geneve_get_options,
.send = geneve_tnl_send,
.owner = THIS_MODULE,
};

static int __init ovs_geneve_tnl_init(void)
{
return ovs_vport_ops_register(&ovs_geneve_vport_ops);
}

static void __exit ovs_geneve_tnl_exit(void)
{
ovs_vport_ops_unregister(&ovs_geneve_vport_ops);
}

module_init(ovs_geneve_tnl_init);
module_exit(ovs_geneve_tnl_exit);

MODULE_DESCRIPTION("OVS: Geneve swiching port");
MODULE_LICENSE("GPL");
MODULE_ALIAS("vport-type-5");
23 changes: 22 additions & 1 deletion net/openvswitch/vport-gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/jhash.h>
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/rculist.h>
#include <net/route.h>
Expand All @@ -45,6 +46,8 @@
#include "datapath.h"
#include "vport.h"

static struct vport_ops ovs_gre_vport_ops;

/* Returns the least-significant 32 bits of a __be64. */
static __be32 be64_get_low32(__be64 x)
{
Expand Down Expand Up @@ -281,10 +284,28 @@ static void gre_tnl_destroy(struct vport *vport)
gre_exit();
}

const struct vport_ops ovs_gre_vport_ops = {
static struct vport_ops ovs_gre_vport_ops = {
.type = OVS_VPORT_TYPE_GRE,
.create = gre_create,
.destroy = gre_tnl_destroy,
.get_name = gre_get_name,
.send = gre_tnl_send,
.owner = THIS_MODULE,
};

static int __init ovs_gre_tnl_init(void)
{
return ovs_vport_ops_register(&ovs_gre_vport_ops);
}

static void __exit ovs_gre_tnl_exit(void)
{
ovs_vport_ops_unregister(&ovs_gre_vport_ops);
}

module_init(ovs_gre_tnl_init);
module_exit(ovs_gre_tnl_exit);

MODULE_DESCRIPTION("OVS: GRE switching port");
MODULE_LICENSE("GPL");
MODULE_ALIAS("vport-type-3");
17 changes: 15 additions & 2 deletions net/openvswitch/vport-internal_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ struct internal_dev {
struct vport *vport;
};

static struct vport_ops ovs_internal_vport_ops;

static struct internal_dev *internal_dev_priv(struct net_device *netdev)
{
return netdev_priv(netdev);
Expand Down Expand Up @@ -238,7 +240,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
return len;
}

const struct vport_ops ovs_internal_vport_ops = {
static struct vport_ops ovs_internal_vport_ops = {
.type = OVS_VPORT_TYPE_INTERNAL,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
Expand All @@ -261,10 +263,21 @@ struct vport *ovs_internal_dev_get_vport(struct net_device *netdev)

int ovs_internal_dev_rtnl_link_register(void)
{
return rtnl_link_register(&internal_dev_link_ops);
int err;

err = rtnl_link_register(&internal_dev_link_ops);
if (err < 0)
return err;

err = ovs_vport_ops_register(&ovs_internal_vport_ops);
if (err < 0)
rtnl_link_unregister(&internal_dev_link_ops);

return err;
}

void ovs_internal_dev_rtnl_link_unregister(void)
{
ovs_vport_ops_unregister(&ovs_internal_vport_ops);
rtnl_link_unregister(&internal_dev_link_ops);
}
14 changes: 13 additions & 1 deletion net/openvswitch/vport-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "vport-internal_dev.h"
#include "vport-netdev.h"

static struct vport_ops ovs_netdev_vport_ops;

/* Must be called with rcu_read_lock. */
static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
{
Expand Down Expand Up @@ -224,10 +226,20 @@ struct vport *ovs_netdev_get_vport(struct net_device *dev)
return NULL;
}

const struct vport_ops ovs_netdev_vport_ops = {
static struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV,
.create = netdev_create,
.destroy = netdev_destroy,
.get_name = ovs_netdev_get_name,
.send = netdev_send,
};

int __init ovs_netdev_init(void)
{
return ovs_vport_ops_register(&ovs_netdev_vport_ops);
}

void ovs_netdev_exit(void)
{
ovs_vport_ops_unregister(&ovs_netdev_vport_ops);
}
3 changes: 3 additions & 0 deletions net/openvswitch/vport-netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ netdev_vport_priv(const struct vport *vport)
const char *ovs_netdev_get_name(const struct vport *);
void ovs_netdev_detach_dev(struct vport *);

int __init ovs_netdev_init(void);
void ovs_netdev_exit(void);

#endif /* vport_netdev.h */
23 changes: 22 additions & 1 deletion net/openvswitch/vport-vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/net.h>
#include <linux/rculist.h>
#include <linux/udp.h>
#include <linux/module.h>

#include <net/icmp.h>
#include <net/ip.h>
Expand All @@ -50,6 +51,8 @@ struct vxlan_port {
char name[IFNAMSIZ];
};

static struct vport_ops ovs_vxlan_vport_ops;

static inline struct vxlan_port *vxlan_vport(const struct vport *vport)
{
return vport_priv(vport);
Expand Down Expand Up @@ -192,11 +195,29 @@ static const char *vxlan_get_name(const struct vport *vport)
return vxlan_port->name;
}

const struct vport_ops ovs_vxlan_vport_ops = {
static struct vport_ops ovs_vxlan_vport_ops = {
.type = OVS_VPORT_TYPE_VXLAN,
.create = vxlan_tnl_create,
.destroy = vxlan_tnl_destroy,
.get_name = vxlan_get_name,
.get_options = vxlan_get_options,
.send = vxlan_tnl_send,
.owner = THIS_MODULE,
};

static int __init ovs_vxlan_tnl_init(void)
{
return ovs_vport_ops_register(&ovs_vxlan_vport_ops);
}

static void __exit ovs_vxlan_tnl_exit(void)
{
ovs_vport_ops_unregister(&ovs_vxlan_vport_ops);
}

module_init(ovs_vxlan_tnl_init);
module_exit(ovs_vxlan_tnl_exit);

MODULE_DESCRIPTION("OVS: VXLAN switching port");
MODULE_LICENSE("GPL");
MODULE_ALIAS("vport-type-4");
Loading

0 comments on commit 62b9c8d

Please sign in to comment.