2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-05 00:35:33 +00:00

netdev: Adopt four-step alloc/construct/destruct/dealloc lifecycle.

This is the same lifecycle used in the ofproto provider interface.
Compared to the previous netdev provider interface, it has the
advantage that the netdev top layer can control when any given
netdev becomes visible to the outside world.

Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff
2013-08-09 21:21:38 -07:00
parent 996e5ae9e9
commit 9dc63482bb
6 changed files with 439 additions and 334 deletions

View File

@@ -74,8 +74,6 @@ struct netdev_rx_bsd {
int fd;
};
static const struct netdev_rx_class netdev_rx_bsd_class;
struct netdev_bsd {
struct netdev up;
unsigned int cache_valid;
@@ -162,7 +160,7 @@ netdev_bsd_cast(const struct netdev *netdev)
static struct netdev_rx_bsd *
netdev_rx_bsd_cast(const struct netdev_rx *rx)
{
netdev_rx_assert_class(rx, &netdev_rx_bsd_class);
ovs_assert(is_netdev_bsd_class(netdev_get_class(rx->netdev)));
return CONTAINER_OF(rx, struct netdev_rx_bsd, up);
}
@@ -269,12 +267,17 @@ cache_notifier_unref(void)
return 0;
}
/* Allocate a netdev_bsd structure */
static int
netdev_bsd_create_system(const struct netdev_class *class, const char *name,
struct netdev **netdevp)
static struct netdev *
netdev_bsd_alloc(void)
{
struct netdev_bsd *netdev;
struct netdev_bsd *netdev = xzalloc(sizeof *netdev);
return &netdev->up;
}
static int
netdev_bsd_construct_system(struct netdev *netdev_)
{
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
enum netdev_flags flags;
int error;
@@ -283,34 +286,26 @@ netdev_bsd_create_system(const struct netdev_class *class, const char *name,
return error;
}
netdev = xzalloc(sizeof *netdev);
netdev->change_seq = 1;
netdev_init(&netdev->up, name, class);
netdev->tap_fd = -1;
netdev->kernel_name = xstrdup(name);
netdev->kernel_name = xstrdup(netdev_->name);
/* Verify that the netdev really exists by attempting to read its flags */
error = netdev_get_flags(&netdev->up, &flags);
error = netdev_get_flags(netdev_, &flags);
if (error == ENXIO) {
free(netdev->kernel_name);
netdev_uninit(&netdev->up, false);
free(netdev);
cache_notifier_unref();
return error;
}
*netdevp = &netdev->up;
return 0;
}
/*
* Allocate a netdev_bsd structure with 'tap' class.
*/
static int
netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
struct netdev **netdevp)
netdev_bsd_construct_tap(struct netdev *netdev_)
{
struct netdev_bsd *netdev = NULL;
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
const char *name = netdev_->name;
int error = 0;
struct ifreq ifr;
char *kernel_name = NULL;
@@ -320,9 +315,6 @@ netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
goto error;
}
/* allocate the device structure and set the internal flag */
netdev = xzalloc(sizeof *netdev);
memset(&ifr, 0, sizeof(ifr));
/* Create a tap device by opening /dev/tap. The TAPGIFNAME ioctl is used
@@ -376,24 +368,19 @@ netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
goto error_unref_notifier;
}
/* initialize the device structure and
* link the structure to its netdev */
netdev_init(&netdev->up, name, class);
netdev->kernel_name = kernel_name;
*netdevp = &netdev->up;
return 0;
error_unref_notifier:
cache_notifier_unref();
error:
free(netdev);
free(kernel_name);
return error;
}
static void
netdev_bsd_destroy(struct netdev *netdev_)
netdev_bsd_destruct(struct netdev *netdev_)
{
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
@@ -406,6 +393,13 @@ netdev_bsd_destroy(struct netdev *netdev_)
pcap_close(netdev->pcap);
}
free(netdev->kernel_name);
}
static void
netdev_bsd_dealloc(struct netdev *netdev_)
{
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
free(netdev);
}
@@ -478,21 +472,26 @@ error:
return error;
}
static int
netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
static struct netdev_rx *
netdev_bsd_rx_alloc(void)
{
struct netdev_rx_bsd *rx = xzalloc(sizeof *rx);
return &rx->up;
}
static int
netdev_bsd_rx_construct(struct netdev_rx *rx_)
{
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
struct netdev *netdev_ = rx->up.netdev;
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
struct netdev_rx_bsd *rx;
pcap_t *pcap;
int fd;
if (!strcmp(netdev_get_type(netdev_), "tap")) {
pcap = NULL;
fd = netdev->tap_fd;
rx->pcap_handle = NULL;
rx->fd = netdev->tap_fd;
} else {
int error = netdev_bsd_open_pcap(netdev_get_kernel_name(netdev_),
&pcap, &fd);
&rx->pcap_handle, &rx->fd);
if (error) {
return error;
}
@@ -500,23 +499,24 @@ netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
netdev_bsd_changed(netdev);
}
rx = xmalloc(sizeof *rx);
netdev_rx_init(&rx->up, netdev_, &netdev_rx_bsd_class);
rx->pcap_handle = pcap;
rx->fd = fd;
*rxp = &rx->up;
return 0;
}
static void
netdev_rx_bsd_destroy(struct netdev_rx *rx_)
netdev_bsd_rx_destruct(struct netdev_rx *rx_)
{
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
if (rx->pcap_handle) {
pcap_close(rx->pcap_handle);
}
}
static void
netdev_bsd_rx_dealloc(struct netdev_rx *rx_)
{
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
free(rx);
}
@@ -615,9 +615,8 @@ netdev_rx_bsd_recv_tap(struct netdev_rx_bsd *rx, void *data, size_t size)
}
}
static int
netdev_rx_bsd_recv(struct netdev_rx *rx_, void *data, size_t size)
netdev_bsd_rx_recv(struct netdev_rx *rx_, void *data, size_t size)
{
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
@@ -631,7 +630,7 @@ netdev_rx_bsd_recv(struct netdev_rx *rx_, void *data, size_t size)
* when a packet is ready to be received with netdev_rx_recv() on 'rx'.
*/
static void
netdev_rx_bsd_wait(struct netdev_rx *rx_)
netdev_bsd_rx_wait(struct netdev_rx *rx_)
{
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
@@ -640,7 +639,7 @@ netdev_rx_bsd_wait(struct netdev_rx *rx_)
/* Discards all packets waiting to be received from 'rx'. */
static int
netdev_rx_bsd_drain(struct netdev_rx *rx_)
netdev_bsd_rx_drain(struct netdev_rx *rx_)
{
struct ifreq ifr;
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
@@ -1379,14 +1378,14 @@ const struct netdev_class netdev_bsd_class = {
NULL, /* init */
netdev_bsd_run,
netdev_bsd_wait,
netdev_bsd_create_system,
netdev_bsd_destroy,
netdev_bsd_alloc,
netdev_bsd_construct_system,
netdev_bsd_destruct,
netdev_bsd_dealloc,
NULL, /* get_config */
NULL, /* set_config */
NULL, /* get_tunnel_config */
netdev_bsd_rx_open,
netdev_bsd_send,
netdev_bsd_send_wait,
@@ -1425,7 +1424,15 @@ const struct netdev_class netdev_bsd_class = {
netdev_bsd_update_flags,
netdev_bsd_change_seq
netdev_bsd_change_seq,
netdev_bsd_rx_alloc,
netdev_bsd_rx_construct,
netdev_bsd_rx_destruct,
netdev_bsd_rx_dealloc,
netdev_bsd_rx_recv,
netdev_bsd_rx_wait,
netdev_bsd_rx_drain,
};
const struct netdev_class netdev_tap_class = {
@@ -1434,14 +1441,14 @@ const struct netdev_class netdev_tap_class = {
NULL, /* init */
netdev_bsd_run,
netdev_bsd_wait,
netdev_bsd_create_tap,
netdev_bsd_destroy,
netdev_bsd_alloc,
netdev_bsd_construct_tap,
netdev_bsd_destruct,
netdev_bsd_dealloc,
NULL, /* get_config */
NULL, /* set_config */
NULL, /* get_tunnel_config */
netdev_bsd_rx_open,
netdev_bsd_send,
netdev_bsd_send_wait,
@@ -1480,14 +1487,15 @@ const struct netdev_class netdev_tap_class = {
netdev_bsd_update_flags,
netdev_bsd_change_seq
};
netdev_bsd_change_seq,
static const struct netdev_rx_class netdev_rx_bsd_class = {
netdev_rx_bsd_destroy,
netdev_rx_bsd_recv,
netdev_rx_bsd_wait,
netdev_rx_bsd_drain,
netdev_bsd_rx_alloc,
netdev_bsd_rx_construct,
netdev_bsd_rx_destruct,
netdev_bsd_rx_dealloc,
netdev_bsd_rx_recv,
netdev_bsd_rx_wait,
netdev_bsd_rx_drain,
};