Refactored the interface device type identification to make it more clear about the operations. --- src/interface/interface_backend_udev.c | 43 ++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c index c144978..73494a6 100644 --- a/src/interface/interface_backend_udev.c +++ b/src/interface/interface_backend_udev.c @@ -561,9 +561,6 @@ udevIfaceGetIfaceDefBridge(struct udev *udev, int stp; int i; - /* Set our type to Bridge */ - ifacedef->type = VIR_INTERFACE_TYPE_BRIDGE; - /* Bridge specifics */ ifacedef->data.bridge.delay = strdup(udev_device_get_sysattr_value(dev, "bridge/forward_delay")); @@ -665,9 +662,6 @@ udevIfaceGetIfaceDefVlan(struct udev *udev ATTRIBUTE_UNUSED, vid[0] = '\0'; vid++; - /* Set our type to VLAN */ - ifacedef->type = VIR_INTERFACE_TYPE_VLAN; - /* Set the VLAN specifics */ ifacedef->data.vlan.tag = vid; ifacedef->data.vlan.devname = vlan_parent_dev; @@ -688,6 +682,7 @@ udevIfaceGetIfaceDef(struct udev *udev, const char *name) unsigned int mtu; const char *mtu_str; char *vlan_parent_dev = NULL; + const char *devtype; /* Allocate our interface definition structure */ if (VIR_ALLOC(ifacedef) < 0) { @@ -697,7 +692,6 @@ udevIfaceGetIfaceDef(struct udev *udev, const char *name) /* Clear our structure and set safe defaults */ ifacedef->startmode = VIR_INTERFACE_START_UNSPECIFIED; - ifacedef->type = VIR_INTERFACE_TYPE_ETHERNET; ifacedef->name = strdup(name); if (!ifacedef->name) { @@ -734,18 +728,41 @@ udevIfaceGetIfaceDef(struct udev *udev, const char *name) ifacedef->nprotos = 0; ifacedef->protos = NULL; - /* Check if its a VLAN since we can have a VLAN of any of the - * other devices */ + /* Check the type of device we are working with based on the devtype */ + devtype = udev_device_get_devtype(dev); + + /* Set our type to ethernet as the default case */ + ifacedef->type = VIR_INTERFACE_TYPE_ETHERNET; + + if (STREQ_NULLABLE(devtype, "vlan")) { + /* This only works on modern kernels (3.7 and newer) + * e949b09b71d975a82f13ac88ce4ad338fed213da + */ + ifacedef->type = VIR_INTERFACE_TYPE_VLAN; + } else if (STREQ_NULLABLE(devtype, "bridge")) { + ifacedef->type = VIR_INTERFACE_TYPE_BRIDGE; + } + + /* Fallback checks if the devtype check didn't work, first + * check if its a VLAN based on the name containing a dot, + * to prevent false positives + */ vlan_parent_dev = strrchr(name, '.'); if (vlan_parent_dev) { + ifacedef->type = VIR_INTERFACE_TYPE_VLAN; + } + + switch (ifacedef->type) { + case VIR_INTERFACE_TYPE_VLAN: if (udevIfaceGetIfaceDefVlan(udev, dev, name, ifacedef)) goto cleanup; - } else if (STREQ_NULLABLE(udev_device_get_devtype(dev), "bridge")) { + break; + case VIR_INTERFACE_TYPE_BRIDGE: if (udevIfaceGetIfaceDefBridge(udev, dev, name, ifacedef)) goto cleanup; - } else { - /* Set our type to ethernet */ - ifacedef->type = VIR_INTERFACE_TYPE_ETHERNET; + break; + case VIR_INTERFACE_TYPE_ETHERNET: + break; } udev_device_unref(dev); -- 1.7.12.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list