summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
be7cd27)
vport->init and exit() functions are defined by gre and netdev vport
only and both can be moved to first port create.
Following patch does same, it moves vport init to respective vport
create and gets rid of vport->init() and vport->exit() functions.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
static int gre_init(void)
{
int err;
static int gre_init(void)
{
int err;
+ gre_ports++;
+ if (gre_ports > 1)
err = inet_add_protocol(&gre_protocol_handlers, IPPROTO_GRE);
if (err)
pr_warn("cannot register gre protocol handler\n");
err = inet_add_protocol(&gre_protocol_handlers, IPPROTO_GRE);
if (err)
pr_warn("cannot register gre protocol handler\n");
static void gre_exit(void)
{
static void gre_exit(void)
{
+ gre_ports--;
+ if (gre_ports > 0)
inet_del_protocol(&gre_protocol_handlers, IPPROTO_GRE);
}
inet_del_protocol(&gre_protocol_handlers, IPPROTO_GRE);
}
struct net *net = ovs_dp_get_net(parms->dp);
struct ovs_net *ovs_net;
struct vport *vport;
struct net *net = ovs_dp_get_net(parms->dp);
struct ovs_net *ovs_net;
struct vport *vport;
+ int err;
+
+ err = gre_init();
+ if (err)
+ return ERR_PTR(err);
ovs_net = net_generic(net, ovs_net_id);
ovs_net = net_generic(net, ovs_net_id);
- if (ovsl_dereference(ovs_net->vport_net.gre_vport))
- return ERR_PTR(-EEXIST);
+ if (ovsl_dereference(ovs_net->vport_net.gre_vport)) {
+ vport = ERR_PTR(-EEXIST);
+ goto error;
+ }
vport = ovs_vport_alloc(IFNAMSIZ, &ovs_gre_vport_ops, parms);
if (IS_ERR(vport))
vport = ovs_vport_alloc(IFNAMSIZ, &ovs_gre_vport_ops, parms);
if (IS_ERR(vport))
strncpy(vport_priv(vport), parms->name, IFNAMSIZ);
rcu_assign_pointer(ovs_net->vport_net.gre_vport, vport);
return vport;
strncpy(vport_priv(vport), parms->name, IFNAMSIZ);
rcu_assign_pointer(ovs_net->vport_net.gre_vport, vport);
return vport;
+
+error:
+ gre_exit();
+ return vport;
}
static void gre_tnl_destroy(struct vport *vport)
}
static void gre_tnl_destroy(struct vport *vport)
rcu_assign_pointer(ovs_net->vport_net.gre_vport, NULL);
ovs_vport_deferred_free(vport);
rcu_assign_pointer(ovs_net->vport_net.gre_vport, NULL);
ovs_vport_deferred_free(vport);
}
static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
}
static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
const struct vport_ops ovs_gre_vport_ops = {
.type = OVS_VPORT_TYPE_GRE,
.flags = VPORT_F_TUN_ID,
const struct vport_ops ovs_gre_vport_ops = {
.type = OVS_VPORT_TYPE_GRE,
.flags = VPORT_F_TUN_ID,
- .init = gre_init,
- .exit = gre_exit,
.create = gre_create,
.destroy = gre_tnl_destroy,
.get_name = gre_get_name,
.create = gre_create,
.destroy = gre_tnl_destroy,
.get_name = gre_get_name,
struct net *net = ovs_dp_get_net(parms->dp);
struct ovs_net *ovs_net;
struct vport *vport;
struct net *net = ovs_dp_get_net(parms->dp);
struct ovs_net *ovs_net;
struct vport *vport;
+ int err;
+
+ err = gre_init();
+ if (err)
+ return ERR_PTR(err);
ovs_net = net_generic(net, ovs_net_id);
ovs_net = net_generic(net, ovs_net_id);
- if (ovsl_dereference(ovs_net->vport_net.gre64_vport))
- return ERR_PTR(-EEXIST);
+ if (ovsl_dereference(ovs_net->vport_net.gre64_vport)) {
+ vport = ERR_PTR(-EEXIST);
+ goto error;
+ }
vport = ovs_vport_alloc(IFNAMSIZ, &ovs_gre64_vport_ops, parms);
if (IS_ERR(vport))
vport = ovs_vport_alloc(IFNAMSIZ, &ovs_gre64_vport_ops, parms);
if (IS_ERR(vport))
strncpy(vport_priv(vport), parms->name, IFNAMSIZ);
rcu_assign_pointer(ovs_net->vport_net.gre64_vport, vport);
return vport;
strncpy(vport_priv(vport), parms->name, IFNAMSIZ);
rcu_assign_pointer(ovs_net->vport_net.gre64_vport, vport);
return vport;
+error:
+ gre_exit();
+ return vport;
}
static void gre64_tnl_destroy(struct vport *vport)
}
static void gre64_tnl_destroy(struct vport *vport)
rcu_assign_pointer(ovs_net->vport_net.gre64_vport, NULL);
ovs_vport_deferred_free(vport);
rcu_assign_pointer(ovs_net->vport_net.gre64_vport, NULL);
ovs_vport_deferred_free(vport);
}
static int gre64_tnl_send(struct vport *vport, struct sk_buff *skb)
}
static int gre64_tnl_send(struct vport *vport, struct sk_buff *skb)
const struct vport_ops ovs_gre64_vport_ops = {
.type = OVS_VPORT_TYPE_GRE64,
.flags = VPORT_F_TUN_ID,
const struct vport_ops ovs_gre64_vport_ops = {
.type = OVS_VPORT_TYPE_GRE64,
.flags = VPORT_F_TUN_ID,
- .init = gre_init,
- .exit = gre_exit,
.create = gre64_create,
.destroy = gre64_tnl_destroy,
.get_name = gre_get_name,
.create = gre64_create,
.destroy = gre64_tnl_destroy,
.get_name = gre_get_name,
const struct vport_ops ovs_internal_vport_ops = {
.type = OVS_VPORT_TYPE_INTERNAL,
const struct vport_ops ovs_internal_vport_ops = {
.type = OVS_VPORT_TYPE_INTERNAL,
- .flags = VPORT_F_REQUIRED,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
.get_name = ovs_netdev_get_name,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
.get_name = ovs_netdev_get_name,
static int netdev_init(void) { return 0; }
static void netdev_exit(void) { }
#else
static int netdev_init(void) { return 0; }
static void netdev_exit(void) { }
#else
-static int netdev_init(void)
+static int port_count;
+
+static void netdev_init(void)
+ port_count++;
+ if (port_count > 1)
+ return;
+
/* Hook into callback used by the bridge to intercept packets.
* Parasites we are. */
br_handle_frame_hook = netdev_frame_hook;
/* Hook into callback used by the bridge to intercept packets.
* Parasites we are. */
br_handle_frame_hook = netdev_frame_hook;
}
static void netdev_exit(void)
{
}
static void netdev_exit(void)
{
+ port_count--;
+ if (port_count > 0)
+ return;
+
br_handle_frame_hook = NULL;
}
#endif
br_handle_frame_hook = NULL;
}
#endif
netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
rtnl_unlock();
netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
rtnl_unlock();
return vport;
#ifndef HAVE_RHEL_OVS_HOOK
return vport;
#ifndef HAVE_RHEL_OVS_HOOK
{
struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
{
struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
rtnl_lock();
netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
netdev_rx_handler_unregister(netdev_vport->dev);
rtnl_lock();
netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
netdev_rx_handler_unregister(netdev_vport->dev);
const struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV,
const struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV,
- .flags = VPORT_F_REQUIRED,
- .init = netdev_init,
- .exit = netdev_exit,
.create = netdev_create,
.destroy = netdev_destroy,
.get_name = ovs_netdev_get_name,
.create = netdev_create,
.destroy = netdev_destroy,
.get_name = ovs_netdev_get_name,
/* List of statically compiled vport implementations. Don't forget to also
* add yours to the list at the bottom of vport.h. */
/* List of statically compiled vport implementations. Don't forget to also
* add yours to the list at the bottom of vport.h. */
-static const struct vport_ops *base_vport_ops_list[] = {
+static const struct vport_ops *vport_ops_list[] = {
&ovs_netdev_vport_ops,
&ovs_internal_vport_ops,
&ovs_gre_vport_ops,
&ovs_netdev_vport_ops,
&ovs_internal_vport_ops,
&ovs_gre_vport_ops,
-static const struct vport_ops **vport_ops_list;
-static int n_vport_types;
-
/* Protected by RCU read lock for reading, ovs_mutex for writing. */
static struct hlist_head *dev_table;
#define VPORT_HASH_BUCKETS 1024
/* Protected by RCU read lock for reading, ovs_mutex for writing. */
static struct hlist_head *dev_table;
#define VPORT_HASH_BUCKETS 1024
/**
* ovs_vport_init - initialize vport subsystem
*
/**
* ovs_vport_init - initialize vport subsystem
*
- * Called at module load time to initialize the vport subsystem and any
- * compiled in vport types.
+ * Called at module load time to initialize the vport subsystem.
*/
int ovs_vport_init(void)
{
*/
int ovs_vport_init(void)
{
dev_table = kzalloc(VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
GFP_KERNEL);
dev_table = kzalloc(VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
GFP_KERNEL);
- if (!dev_table) {
- err = -ENOMEM;
- goto error;
- }
-
- vport_ops_list = kmalloc(ARRAY_SIZE(base_vport_ops_list) *
- sizeof(struct vport_ops *), GFP_KERNEL);
- if (!vport_ops_list) {
- err = -ENOMEM;
- goto error_dev_table;
- }
-
- for (i = 0; i < ARRAY_SIZE(base_vport_ops_list); i++) {
- const struct vport_ops *new_ops = base_vport_ops_list[i];
-
- if (new_ops->init)
- err = new_ops->init();
- else
- err = 0;
-
- if (!err)
- vport_ops_list[n_vport_types++] = new_ops;
- else if (new_ops->flags & VPORT_F_REQUIRED) {
- ovs_vport_exit();
- goto error;
- }
- }
+ if (!dev_table)
+ return -ENOMEM;
-
-error_dev_table:
- kfree(dev_table);
-error:
- return err;
}
/**
* ovs_vport_exit - shutdown vport subsystem
*
}
/**
* ovs_vport_exit - shutdown vport subsystem
*
- * Called at module exit time to shutdown the vport subsystem and any
- * initialized vport types.
+ * Called at module exit time to shutdown the vport subsystem.
*/
void ovs_vport_exit(void)
{
*/
void ovs_vport_exit(void)
{
- int i;
-
- for (i = 0; i < n_vport_types; i++) {
- if (vport_ops_list[i]->exit)
- vport_ops_list[i]->exit();
- }
-
- kfree(vport_ops_list);
- for (i = 0; i < n_vport_types; i++) {
+ for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) {
if (vport_ops_list[i]->type == parms->type) {
struct hlist_head *bucket;
if (vport_ops_list[i]->type == parms->type) {
struct hlist_head *bucket;
struct ovs_vport_stats offset_stats;
};
struct ovs_vport_stats offset_stats;
};
-#define VPORT_F_REQUIRED (1 << 0) /* If init fails, module loading fails. */
-#define VPORT_F_TUN_ID (1 << 1) /* Sets OVS_CB(skb)->tun_id. */
+#define VPORT_F_TUN_ID (1 << 0) /* Sets OVS_CB(skb)->tun_id. */
/**
* struct vport_parms - parameters for creating a new vport
/**
* struct vport_parms - parameters for creating a new vport
* @type: %OVS_VPORT_TYPE_* value for this type of virtual port.
* @flags: Flags of type VPORT_F_* that influence how the generic vport layer
* handles this vport.
* @type: %OVS_VPORT_TYPE_* value for this type of virtual port.
* @flags: Flags of type VPORT_F_* that influence how the generic vport layer
* handles this vport.
- * @init: Called at module initialization. If VPORT_F_REQUIRED is set then the
- * failure of this function will cause the module to not load. If the flag is
- * not set and initialzation fails then no vports of this type can be created.
- * @exit: Called at module unload.
* @create: Create a new vport configured as specified. On success returns
* a new vport allocated with ovs_vport_alloc(), otherwise an ERR_PTR() value.
* @destroy: Destroys a vport. Must call vport_free() on the vport but not
* @create: Create a new vport configured as specified. On success returns
* a new vport allocated with ovs_vport_alloc(), otherwise an ERR_PTR() value.
* @destroy: Destroys a vport. Must call vport_free() on the vport but not
enum ovs_vport_type type;
u32 flags;
enum ovs_vport_type type;
u32 flags;
- /* Called at module init and exit respectively. */
- int (*init)(void);
- void (*exit)(void);
-
/* Called with ovs_mutex. */
struct vport *(*create)(const struct vport_parms *);
void (*destroy)(struct vport *);
/* Called with ovs_mutex. */
struct vport *(*create)(const struct vport_parms *);
void (*destroy)(struct vport *);