mirror of
https://github.com/openvswitch/ovs
synced 2025-09-04 08:15:25 +00:00
netdev-dummy: Use netdev_get_devices() instead of a local shash.
When an upcoming commit introduces thread safety into the netdev API, this allows netdev-dummy to avoid adding more internal locking by taking advantage of netdev_get_devices() refcounting. Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -60,6 +60,8 @@ struct netdev_dummy {
|
|||||||
struct list rxes; /* List of child "netdev_rx_dummy"s. */
|
struct list rxes; /* List of child "netdev_rx_dummy"s. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct netdev_class dummy_class;
|
||||||
|
|
||||||
/* Max 'recv_queue_len' in struct netdev_dummy. */
|
/* Max 'recv_queue_len' in struct netdev_dummy. */
|
||||||
#define NETDEV_DUMMY_MAX_QUEUE 100
|
#define NETDEV_DUMMY_MAX_QUEUE 100
|
||||||
|
|
||||||
@@ -71,8 +73,6 @@ struct netdev_rx_dummy {
|
|||||||
bool listening;
|
bool listening;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct shash dummy_netdevs = SHASH_INITIALIZER(&dummy_netdevs);
|
|
||||||
|
|
||||||
static const struct netdev_rx_class netdev_rx_dummy_class;
|
static const struct netdev_rx_class netdev_rx_dummy_class;
|
||||||
|
|
||||||
static unixctl_cb_func netdev_dummy_set_admin_state;
|
static unixctl_cb_func netdev_dummy_set_admin_state;
|
||||||
@@ -106,8 +106,11 @@ netdev_rx_dummy_cast(const struct netdev_rx *rx)
|
|||||||
static void
|
static void
|
||||||
netdev_dummy_run(void)
|
netdev_dummy_run(void)
|
||||||
{
|
{
|
||||||
|
struct shash dummy_netdevs;
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
|
|
||||||
|
shash_init(&dummy_netdevs);
|
||||||
|
netdev_get_devices(&dummy_class, &dummy_netdevs);
|
||||||
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
||||||
struct netdev_dummy *dev = node->data;
|
struct netdev_dummy *dev = node->data;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -202,7 +205,10 @@ netdev_dummy_run(void)
|
|||||||
dev->streams[i] = dev->streams[--dev->n_streams];
|
dev->streams[i] = dev->streams[--dev->n_streams];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netdev_close(&dev->up);
|
||||||
}
|
}
|
||||||
|
shash_destroy(&dummy_netdevs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -216,8 +222,11 @@ dummy_stream_close(struct dummy_stream *s)
|
|||||||
static void
|
static void
|
||||||
netdev_dummy_wait(void)
|
netdev_dummy_wait(void)
|
||||||
{
|
{
|
||||||
|
struct shash dummy_netdevs;
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
|
|
||||||
|
shash_init(&dummy_netdevs);
|
||||||
|
netdev_get_devices(&dummy_class, &dummy_netdevs);
|
||||||
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
||||||
struct netdev_dummy *dev = node->data;
|
struct netdev_dummy *dev = node->data;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -234,7 +243,9 @@ netdev_dummy_wait(void)
|
|||||||
}
|
}
|
||||||
stream_recv_wait(s->stream);
|
stream_recv_wait(s->stream);
|
||||||
}
|
}
|
||||||
|
netdev_close(&dev->up);
|
||||||
}
|
}
|
||||||
|
shash_destroy(&dummy_netdevs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -265,8 +276,6 @@ netdev_dummy_create(const struct netdev_class *class, const char *name,
|
|||||||
|
|
||||||
list_init(&netdev->rxes);
|
list_init(&netdev->rxes);
|
||||||
|
|
||||||
shash_add(&dummy_netdevs, name, netdev);
|
|
||||||
|
|
||||||
*netdevp = &netdev->up;
|
*netdevp = &netdev->up;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -278,8 +287,6 @@ netdev_dummy_destroy(struct netdev *netdev_)
|
|||||||
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
|
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
shash_find_and_delete(&dummy_netdevs,
|
|
||||||
netdev_get_name(netdev_));
|
|
||||||
pstream_close(netdev->pstream);
|
pstream_close(netdev->pstream);
|
||||||
for (i = 0; i < netdev->n_streams; i++) {
|
for (i = 0; i < netdev->n_streams; i++) {
|
||||||
dummy_stream_close(&netdev->streams[i]);
|
dummy_stream_close(&netdev->streams[i]);
|
||||||
@@ -677,13 +684,15 @@ netdev_dummy_receive(struct unixctl_conn *conn,
|
|||||||
int argc, const char *argv[], void *aux OVS_UNUSED)
|
int argc, const char *argv[], void *aux OVS_UNUSED)
|
||||||
{
|
{
|
||||||
struct netdev_dummy *dummy_dev;
|
struct netdev_dummy *dummy_dev;
|
||||||
|
struct netdev *netdev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dummy_dev = shash_find_data(&dummy_netdevs, argv[1]);
|
netdev = netdev_from_name(argv[1]);
|
||||||
if (!dummy_dev) {
|
if (!netdev || !is_dummy_class(netdev->netdev_class)) {
|
||||||
unixctl_command_reply_error(conn, "no such dummy netdev");
|
unixctl_command_reply_error(conn, "no such dummy netdev");
|
||||||
return;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
dummy_dev = netdev_dummy_cast(netdev);
|
||||||
|
|
||||||
for (i = 2; i < argc; i++) {
|
for (i = 2; i < argc; i++) {
|
||||||
struct ofpbuf *packet;
|
struct ofpbuf *packet;
|
||||||
@@ -691,7 +700,7 @@ netdev_dummy_receive(struct unixctl_conn *conn,
|
|||||||
packet = eth_from_packet_or_flow(argv[i]);
|
packet = eth_from_packet_or_flow(argv[i]);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
unixctl_command_reply_error(conn, "bad packet syntax");
|
unixctl_command_reply_error(conn, "bad packet syntax");
|
||||||
return;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
dummy_dev->stats.rx_packets++;
|
dummy_dev->stats.rx_packets++;
|
||||||
@@ -701,6 +710,9 @@ netdev_dummy_receive(struct unixctl_conn *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unixctl_command_reply(conn, NULL);
|
unixctl_command_reply(conn, NULL);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
netdev_close(netdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -731,21 +743,29 @@ netdev_dummy_set_admin_state(struct unixctl_conn *conn, int argc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
struct netdev_dummy *dummy_dev;
|
struct netdev *netdev = netdev_from_name(argv[1]);
|
||||||
|
if (netdev && is_dummy_class(netdev->netdev_class)) {
|
||||||
|
struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev);
|
||||||
|
|
||||||
dummy_dev = shash_find_data(&dummy_netdevs, argv[1]);
|
|
||||||
if (dummy_dev) {
|
|
||||||
netdev_dummy_set_admin_state__(dummy_dev, up);
|
netdev_dummy_set_admin_state__(dummy_dev, up);
|
||||||
|
netdev_close(netdev);
|
||||||
} else {
|
} else {
|
||||||
unixctl_command_reply_error(conn, "Unknown Dummy Interface");
|
unixctl_command_reply_error(conn, "Unknown Dummy Interface");
|
||||||
|
netdev_close(netdev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
struct shash dummy_netdevs;
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
|
|
||||||
|
shash_init(&dummy_netdevs);
|
||||||
|
netdev_get_devices(&dummy_class, &dummy_netdevs);
|
||||||
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
SHASH_FOR_EACH (node, &dummy_netdevs) {
|
||||||
netdev_dummy_set_admin_state__(node->data, up);
|
struct netdev *netdev = node->data;
|
||||||
|
netdev_dummy_set_admin_state__(netdev_dummy_cast(netdev), up);
|
||||||
|
netdev_close(netdev);
|
||||||
}
|
}
|
||||||
|
shash_destroy(&dummy_netdevs);
|
||||||
}
|
}
|
||||||
unixctl_command_reply(conn, "OK");
|
unixctl_command_reply(conn, "OK");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user