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:
committed by
Ben Pfaff
parent
f80485a1f5
commit
8c2c225e48
30
lib/netdev.c
30
lib/netdev.c
@@ -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) {
|
||||
|
Reference in New Issue
Block a user