On 02/20/2013 02:56 PM, Doug Goldstein wrote: > Refactored the interface device type identification to make it more > clear about the operations. Add support for udev devtype to detect > VLANs on Linux 3.7 and newer. Move VLAN detection based on device > name to fallback case. > --- > src/interface/interface_backend_udev.c | 46 +++++++++++++++++++++++++--------- > 1 file changed, 34 insertions(+), 12 deletions(-) > > diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c > index e5ab1a7..db4e7d1 100644 > --- a/src/interface/interface_backend_udev.c > +++ b/src/interface/interface_backend_udev.c > @@ -684,9 +684,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; > @@ -707,6 +704,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) { > @@ -716,7 +714,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) { > @@ -753,18 +750,43 @@ 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 */ > - vlan_parent_dev = strrchr(name, '.'); > - if (vlan_parent_dev) { > + /* 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. */ > + if (ifacedef->type == VIR_INTERFACE_TYPE_ETHERNET) { > + /* 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) < 0) > 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); ACK. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list