mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
datapath: Make adding and attaching a vport a single step.
For some time now, Open vSwitch datapaths have internally made a distinction between adding a vport and attaching it to a datapath. Adding a vport just means to create it, as an entity detached from any datapath. Attaching it gives it a port number and a datapath. Similarly, a vport could be detached and deleted separately. After some study, I think I understand why this distinction exists. It is because ovs-vswitchd tries to open all the datapath ports before it tries to create them. However, changing it to create them before it tries to open them is not difficult, so this commit does this. The bulk of this commit, however, changes the datapath interface to one that always creates a vport and attaches it to a datapath in a single step, and similarly detaches a vport and deletes it in a single step. Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
@@ -495,9 +495,9 @@ netdev_linux_cache_cb(const struct rtnetlink_change *change,
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates the netdev device of 'type' with 'name'. */
|
||||
/* Creates system and internal devices. */
|
||||
static int
|
||||
netdev_linux_create_system(const struct netdev_class *class OVS_UNUSED,
|
||||
netdev_linux_create(const struct netdev_class *class,
|
||||
const char *name, const struct shash *args,
|
||||
struct netdev_dev **netdev_devp)
|
||||
{
|
||||
@@ -505,7 +505,8 @@ netdev_linux_create_system(const struct netdev_class *class OVS_UNUSED,
|
||||
int error;
|
||||
|
||||
if (!shash_is_empty(args)) {
|
||||
VLOG_WARN("%s: arguments for system devices should be empty", name);
|
||||
VLOG_WARN("%s: arguments for %s devices should be empty",
|
||||
name, class->type);
|
||||
}
|
||||
|
||||
if (!cache_notifier_refcount) {
|
||||
@@ -518,7 +519,7 @@ netdev_linux_create_system(const struct netdev_class *class OVS_UNUSED,
|
||||
cache_notifier_refcount++;
|
||||
|
||||
netdev_dev = xzalloc(sizeof *netdev_dev);
|
||||
netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_linux_class);
|
||||
netdev_dev_init(&netdev_dev->netdev_dev, name, class);
|
||||
|
||||
*netdev_devp = &netdev_dev->netdev_dev;
|
||||
return 0;
|
||||
@@ -629,9 +630,19 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, int ethertype,
|
||||
netdev->fd = -1;
|
||||
netdev_init(&netdev->netdev, netdev_dev_);
|
||||
|
||||
error = netdev_get_flags(&netdev->netdev, &flags);
|
||||
if (error == ENODEV) {
|
||||
goto error;
|
||||
/* Verify that the device really exists, by attempting to read its flags.
|
||||
* (The flags might be cached, in which case this won't actually do an
|
||||
* ioctl.)
|
||||
*
|
||||
* Don't do this for "internal" netdevs, though, because those have to be
|
||||
* created as netdev objects before they exist in the kernel, because
|
||||
* creating them in the kernel happens by passing a netdev object to
|
||||
* dpif_port_add(). */
|
||||
if (netdev_dev_get_class(netdev_dev_) != &netdev_internal_class) {
|
||||
error = netdev_get_flags(&netdev->netdev, &flags);
|
||||
if (error == ENODEV) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(netdev_dev_get_type(netdev_dev_), "tap") &&
|
||||
@@ -2107,125 +2118,87 @@ netdev_linux_poll_remove(struct netdev_notifier *notifier_)
|
||||
}
|
||||
}
|
||||
|
||||
const struct netdev_class netdev_linux_class = {
|
||||
"system",
|
||||
#define NETDEV_LINUX_CLASS(NAME, CREATE, ENUMERATE, SET_STATS) \
|
||||
{ \
|
||||
NAME, \
|
||||
\
|
||||
netdev_linux_init, \
|
||||
netdev_linux_run, \
|
||||
netdev_linux_wait, \
|
||||
\
|
||||
CREATE, \
|
||||
netdev_linux_destroy, \
|
||||
NULL, /* reconfigure */ \
|
||||
\
|
||||
netdev_linux_open, \
|
||||
netdev_linux_close, \
|
||||
\
|
||||
ENUMERATE, \
|
||||
\
|
||||
netdev_linux_recv, \
|
||||
netdev_linux_recv_wait, \
|
||||
netdev_linux_drain, \
|
||||
\
|
||||
netdev_linux_send, \
|
||||
netdev_linux_send_wait, \
|
||||
\
|
||||
netdev_linux_set_etheraddr, \
|
||||
netdev_linux_get_etheraddr, \
|
||||
netdev_linux_get_mtu, \
|
||||
netdev_linux_get_ifindex, \
|
||||
netdev_linux_get_carrier, \
|
||||
netdev_linux_get_stats, \
|
||||
SET_STATS, \
|
||||
\
|
||||
netdev_linux_get_features, \
|
||||
netdev_linux_set_advertisements, \
|
||||
netdev_linux_get_vlan_vid, \
|
||||
\
|
||||
netdev_linux_set_policing, \
|
||||
netdev_linux_get_qos_types, \
|
||||
netdev_linux_get_qos_capabilities, \
|
||||
netdev_linux_get_qos, \
|
||||
netdev_linux_set_qos, \
|
||||
netdev_linux_get_queue, \
|
||||
netdev_linux_set_queue, \
|
||||
netdev_linux_delete_queue, \
|
||||
netdev_linux_get_queue_stats, \
|
||||
netdev_linux_dump_queues, \
|
||||
netdev_linux_dump_queue_stats, \
|
||||
\
|
||||
netdev_linux_get_in4, \
|
||||
netdev_linux_set_in4, \
|
||||
netdev_linux_get_in6, \
|
||||
netdev_linux_add_router, \
|
||||
netdev_linux_get_next_hop, \
|
||||
netdev_linux_arp_lookup, \
|
||||
\
|
||||
netdev_linux_update_flags, \
|
||||
\
|
||||
netdev_linux_poll_add, \
|
||||
netdev_linux_poll_remove \
|
||||
}
|
||||
|
||||
netdev_linux_init,
|
||||
netdev_linux_run,
|
||||
netdev_linux_wait,
|
||||
const struct netdev_class netdev_linux_class =
|
||||
NETDEV_LINUX_CLASS(
|
||||
"system",
|
||||
netdev_linux_create,
|
||||
netdev_linux_enumerate,
|
||||
netdev_vport_set_stats);
|
||||
|
||||
netdev_linux_create_system,
|
||||
netdev_linux_destroy,
|
||||
NULL, /* reconfigure */
|
||||
const struct netdev_class netdev_tap_class =
|
||||
NETDEV_LINUX_CLASS(
|
||||
"tap",
|
||||
netdev_linux_create_tap,
|
||||
NULL, /* enumerate */
|
||||
NULL); /* set_stats */
|
||||
|
||||
netdev_linux_open,
|
||||
netdev_linux_close,
|
||||
|
||||
netdev_linux_enumerate,
|
||||
|
||||
netdev_linux_recv,
|
||||
netdev_linux_recv_wait,
|
||||
netdev_linux_drain,
|
||||
|
||||
netdev_linux_send,
|
||||
netdev_linux_send_wait,
|
||||
|
||||
netdev_linux_set_etheraddr,
|
||||
netdev_linux_get_etheraddr,
|
||||
netdev_linux_get_mtu,
|
||||
netdev_linux_get_ifindex,
|
||||
netdev_linux_get_carrier,
|
||||
netdev_linux_get_stats,
|
||||
netdev_vport_set_stats,
|
||||
|
||||
netdev_linux_get_features,
|
||||
netdev_linux_set_advertisements,
|
||||
netdev_linux_get_vlan_vid,
|
||||
|
||||
netdev_linux_set_policing,
|
||||
netdev_linux_get_qos_types,
|
||||
netdev_linux_get_qos_capabilities,
|
||||
netdev_linux_get_qos,
|
||||
netdev_linux_set_qos,
|
||||
netdev_linux_get_queue,
|
||||
netdev_linux_set_queue,
|
||||
netdev_linux_delete_queue,
|
||||
netdev_linux_get_queue_stats,
|
||||
netdev_linux_dump_queues,
|
||||
netdev_linux_dump_queue_stats,
|
||||
|
||||
netdev_linux_get_in4,
|
||||
netdev_linux_set_in4,
|
||||
netdev_linux_get_in6,
|
||||
netdev_linux_add_router,
|
||||
netdev_linux_get_next_hop,
|
||||
netdev_linux_arp_lookup,
|
||||
|
||||
netdev_linux_update_flags,
|
||||
|
||||
netdev_linux_poll_add,
|
||||
netdev_linux_poll_remove,
|
||||
};
|
||||
|
||||
const struct netdev_class netdev_tap_class = {
|
||||
"tap",
|
||||
|
||||
netdev_linux_init,
|
||||
netdev_linux_run,
|
||||
netdev_linux_wait,
|
||||
|
||||
netdev_linux_create_tap,
|
||||
netdev_linux_destroy,
|
||||
NULL, /* reconfigure */
|
||||
|
||||
netdev_linux_open,
|
||||
netdev_linux_close,
|
||||
|
||||
NULL, /* enumerate */
|
||||
|
||||
netdev_linux_recv,
|
||||
netdev_linux_recv_wait,
|
||||
netdev_linux_drain,
|
||||
|
||||
netdev_linux_send,
|
||||
netdev_linux_send_wait,
|
||||
|
||||
netdev_linux_set_etheraddr,
|
||||
netdev_linux_get_etheraddr,
|
||||
netdev_linux_get_mtu,
|
||||
netdev_linux_get_ifindex,
|
||||
netdev_linux_get_carrier,
|
||||
netdev_linux_get_stats,
|
||||
NULL, /* set_stats */
|
||||
|
||||
netdev_linux_get_features,
|
||||
netdev_linux_set_advertisements,
|
||||
netdev_linux_get_vlan_vid,
|
||||
|
||||
netdev_linux_set_policing,
|
||||
netdev_linux_get_qos_types,
|
||||
netdev_linux_get_qos_capabilities,
|
||||
netdev_linux_get_qos,
|
||||
netdev_linux_set_qos,
|
||||
netdev_linux_get_queue,
|
||||
netdev_linux_set_queue,
|
||||
netdev_linux_delete_queue,
|
||||
netdev_linux_get_queue_stats,
|
||||
netdev_linux_dump_queues,
|
||||
netdev_linux_dump_queue_stats,
|
||||
|
||||
netdev_linux_get_in4,
|
||||
netdev_linux_set_in4,
|
||||
netdev_linux_get_in6,
|
||||
netdev_linux_add_router,
|
||||
netdev_linux_get_next_hop,
|
||||
netdev_linux_arp_lookup,
|
||||
|
||||
netdev_linux_update_flags,
|
||||
|
||||
netdev_linux_poll_add,
|
||||
netdev_linux_poll_remove,
|
||||
};
|
||||
const struct netdev_class netdev_internal_class =
|
||||
NETDEV_LINUX_CLASS(
|
||||
"internal",
|
||||
netdev_linux_create,
|
||||
NULL, /* enumerate */
|
||||
netdev_vport_set_stats);
|
||||
|
||||
/* HTB traffic control class. */
|
||||
|
||||
|
Reference in New Issue
Block a user