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

netdev: Fix netdev_open() to track and recreate classless interfaces

Due to commit 67ac844 an existing issue with OVS persisten ports
surfaced. If we revert the commit we no longer get the error, and
basic traffic will flow. However the wrong netdev class is used, hence
the wrong callbacks get called.

The main issue is with netdev_open() being called with type = NULL
before the interface is actually configured in the system. This patch
tracks these "auto" generated interfaces, and once netdev_open() gets
called with a valid type, re-configures (re-create) it.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Eelco Chaudron
2017-07-14 14:33:27 +02:00
committed by Ben Pfaff
parent f80485a1f5
commit 8c2c225e48
2 changed files with 29 additions and 5 deletions

View File

@@ -361,7 +361,7 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
OVS_EXCLUDED(netdev_mutex)
{
struct netdev *netdev;
int error;
int error = 0;
if (!name[0]) {
/* Reject empty names. This saves the providers having to do this. At
@@ -375,6 +375,29 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
ovs_mutex_lock(&netdev_mutex);
netdev = shash_find_data(&netdev_shash, name);
if (netdev &&
type && type[0] && strcmp(type, netdev->netdev_class->type)) {
if (netdev->auto_classified) {
/* If this device was first created without a classification type,
* for example due to routing or tunneling code, and they keep a
* reference, a "classified" call to open will fail. In this case
* we remove the classless device, and re-add it below. We remove
* the netdev from the shash, and change the sequence, so owners of
* the old classless device can release/cleanup. */
if (netdev->node) {
shash_delete(&netdev_shash, netdev->node);
netdev->node = NULL;
netdev_change_seq_changed(netdev);
}
netdev = NULL;
} else {
error = EEXIST;
}
}
if (!netdev) {
struct netdev_registered_class *rc;
@@ -384,6 +407,7 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
if (netdev) {
memset(netdev, 0, sizeof *netdev);
netdev->netdev_class = rc->class;
netdev->auto_classified = type && type[0] ? false : true;
netdev->name = xstrdup(name);
netdev->change_seq = 1;
netdev->reconfigure_seq = seq_create();
@@ -416,10 +440,6 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
name, type);
error = EAFNOSUPPORT;
}
} else if (type && type[0] && strcmp(type, netdev->netdev_class->type)) {
error = EEXIST;
} else {
error = 0;
}
if (!error) {