2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

netdev: Fully handle netdev lifecycle through refcounting.

This builds on earlier work that implemented netdev object refcounting.
However, rather than requiring explicit create and destroy calls,
these operations are now performed automatically based on the referenece
count.  This is important because in certain situations it is not
possible to know whether a netdev has already been created.  A
workaround existed (which looked fairly similar to this paradigm) but
introduced it's own issues.  This simplifies and unifies the API.
This commit is contained in:
Jesse Gross
2010-01-12 16:01:43 -05:00
parent b4182c7f2d
commit 149f577a25
12 changed files with 707 additions and 619 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Nicira Networks.
* Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -237,7 +237,7 @@ create_dp_netdev(const char *name, int dp_idx, struct dpif **dpifp)
error = do_add_port(dp, name, ODP_PORT_INTERNAL, ODPP_LOCAL);
if (error) {
dp_netdev_free(dp);
return error;
return ENODEV;
}
*dpifp = create_dpif_netdev(dp);
@@ -363,6 +363,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, uint16_t flags,
{
bool internal = (flags & ODP_PORT_INTERNAL) != 0;
struct dp_netdev_port *port;
struct netdev_options netdev_options;
struct netdev *netdev;
int mtu;
int error;
@@ -370,17 +371,17 @@ do_add_port(struct dp_netdev *dp, const char *devname, uint16_t flags,
/* XXX reject devices already in some dp_netdev. */
/* Open and validate network device. */
if (!internal) {
error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
memset(&netdev_options, 0, sizeof netdev_options);
netdev_options.name = devname;
netdev_options.ethertype = NETDEV_ETH_TYPE_ANY;
netdev_options.may_create = true;
if (internal) {
netdev_options.type = "tap";
} else {
error = netdev_create(devname, "tap", NULL);
if (!error) {
error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
if (error) {
netdev_destroy(devname);
}
}
netdev_options.may_open = true;
}
error = netdev_open(&netdev_options, &netdev);
if (error) {
return error;
}
@@ -487,9 +488,7 @@ do_del_port(struct dp_netdev *dp, uint16_t port_no)
name = xstrdup(netdev_get_name(port->netdev));
netdev_close(port->netdev);
if (port->internal) {
netdev_destroy(name);
}
free(name);
free(port);