From e75f5bfbe89e0ea4a98fb9b70fc4649fe861a21c Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Fri, 17 Mar 2017 20:57:18 -0400 Subject: [PATCH] util: new function virNetDevGetMaster() This function provides the bridge/bond device that the given network device is attached to. The return value is 0 or -1, and the master device is a char** argument to the function - this is needed in order to allow for a "success" return from a device that has no master. --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 49 ++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 3 +++ 3 files changed, 53 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 57acfdbb19..b3fd6077e3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1994,6 +1994,7 @@ virNetDevGetFeatures; virNetDevGetIndex; virNetDevGetLinkInfo; virNetDevGetMAC; +virNetDevGetMaster; virNetDevGetMTU; virNetDevGetName; virNetDevGetOnline; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 9e52a1f725..6805d324da 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -979,6 +979,55 @@ int virNetDevGetIndex(const char *ifname ATTRIBUTE_UNUSED, #endif /* ! SIOCGIFINDEX */ +#if defined(__linux__) && defined(HAVE_LIBNL) +/** + * virNetDevGetMaster: + * @ifname: name of interface we're interested in + * @master: used to return a string containing the name of @ifname's "master" + * (this is the bridge or bond device that this device is attached to) + * + * Returns 0 on success, -1 on failure (if @ifname has no master + * @master will be NULL, but return value will still be 0 (success)). + */ +int +virNetDevGetMaster(const char *ifname, char **master) +{ + int ret = -1; + void *nlData = NULL; + struct nlattr *tb[IFLA_MAX + 1] = {NULL, }; + + *master = NULL; + + if (virNetlinkDumpLink(ifname, -1, &nlData, tb, 0, 0) < 0) + goto cleanup; + + if (tb[IFLA_MASTER]) { + if (!(*master = virNetDevGetName(*(int *)RTA_DATA(tb[IFLA_MASTER])))) + goto cleanup; + } + + ret = 0; + cleanup: + VIR_FREE(nlData); + return ret; +} + + +#else + + +int +virNetDevGetMaster(const char *ifname, char **master) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get device master from netlink on this platform")); + return -1; +} + + +#endif /* defined(__linux__) && defined(HAVE_LIBNL) */ + + #if defined(SIOCGIFVLAN) && defined(HAVE_STRUCT_IFREQ) && HAVE_DECL_GET_VLAN_VID_CMD int virNetDevGetVLanID(const char *ifname, int *vlanid) { diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 01e9c5b954..2b1d0121de 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -165,6 +165,9 @@ int virNetDevGetIndex(const char *ifname, int *ifindex) int virNetDevGetVLanID(const char *ifname, int *vlanid) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMaster(const char *ifname, char **master) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + int virNetDevValidateConfig(const char *ifname, const virMacAddr *macaddr, int ifindex) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- GitLab