diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 8815e1881958cf019f70286ca38c02b46c3a4309..e96838d72060d42194c61a677e15c103b3311031 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1353,23 +1353,25 @@ static struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { /** * virNetDevLinkDump: * - * @ifname: The name of the interface; only use if ifindex < 0 - * @ifindex: The interface index; may be < 0 if ifname is given - * @nlattr: pointer to a pointer of netlink attributes that will contain - * the results + * @ifname: The name of the interface; only use if ifindex <= 0 + * @ifindex: The interface index; may be <= 0 if ifname is given + * @data: Gets a pointer to the raw data from netlink. + MUST BE FREED BY CALLER! + * @nlattr: Pointer to a pointer of netlink attributes that will contain + * the results * @src_pid: pid used for nl_pid of the local end of the netlink message * (0 == "use getpid()") * @dst_pid: pid of destination nl_pid if the kernel * is not the target of the netlink message but it is to be * sent to another process (0 if sending to the kernel) * - * Get information about an interface given its name or index. + * Get information from netlink about an interface given its name or index. * * Returns 0 on success, -1 on fatal error. */ int virNetDevLinkDump(const char *ifname, int ifindex, - struct nlattr **tb, + void **nlData, struct nlattr **tb, uint32_t src_pid, uint32_t dst_pid) { int rc = -1; @@ -1451,7 +1453,9 @@ virNetDevLinkDump(const char *ifname, int ifindex, rc = 0; cleanup: nlmsg_free(nl_msg); - VIR_FREE(resp); + if (rc < 0) + VIR_FREE(resp); + *nlData = resp; return rc; malformed_resp: @@ -1647,15 +1651,18 @@ virNetDevGetVfConfig(const char *ifname, int vf, virMacAddrPtr mac, int *vlanid) { int rc = -1; + void *nlData = NULL; struct nlattr *tb[IFLA_MAX + 1] = {NULL, }; int ifindex = -1; - rc = virNetDevLinkDump(ifname, ifindex, tb, 0, 0); + rc = virNetDevLinkDump(ifname, ifindex, &nlData, tb, 0, 0); if (rc < 0) - return rc; + goto cleanup; rc = virNetDevParseVfConfig(tb, vf, mac, vlanid); + cleanup: + VIR_FREE(nlData); return rc; } @@ -1798,6 +1805,7 @@ virNetDevRestoreNetConfig(const char *linkdev, int vf, const char *stateDir) int virNetDevLinkDump(const char *ifname ATTRIBUTE_UNUSED, int ifindex ATTRIBUTE_UNUSED, + void **nlData ATTRIBUTE_UNUSED, struct nlattr **tb ATTRIBUTE_UNUSED, uint32_t src_pid ATTRIBUTE_UNUSED, uint32_t dst_pid ATTRIBUTE_UNUSED) diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 69e365e74184baee708dfd995bbccef109ef4646..f1e03c82b6ba65d141ad4de89ab079f0055ce0d9 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -130,7 +130,7 @@ int virNetDevGetVirtualFunctions(const char *pfname, ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK; int virNetDevLinkDump(const char *ifname, int ifindex, - struct nlattr **tb, + void **nlData, struct nlattr **tb, uint32_t src_pid, uint32_t dst_pid) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 75679b08186fd142769ec9b98ec922c570f312c5..6ee20d3bfa9c88c667d7a9095c1a0d81af037983 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -787,7 +787,8 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int int *parent_ifindex, char *parent_ifname, unsigned int *nth) { - int rc; + int rc = -1; + void *nlData = NULL; struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; bool end = false; size_t i = 0; @@ -798,7 +799,8 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int return -1; while (!end && i <= nthParent) { - rc = virNetDevLinkDump(ifname, ifindex, tb, 0, 0); + VIR_FREE(nlData); + rc = virNetDevLinkDump(ifname, ifindex, &nlData, tb, 0, 0); if (rc < 0) break; @@ -807,7 +809,8 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int IFNAMSIZ)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("buffer for root interface name is too small")); - return -1; + rc = -1; + goto cleanup; } *parent_ifindex = ifindex; } @@ -824,6 +827,8 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int *nth = i - 1; + cleanup: + VIR_FREE(nlData); return rc; } @@ -845,6 +850,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, int rc; int src_pid = 0; uint32_t dst_pid = 0; + void *nlData = NULL; struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; int repeats = STATUS_POLL_TIMEOUT_USEC / STATUS_POLL_INTERVL_USEC; uint16_t status = 0; @@ -877,7 +883,8 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, } while (--repeats >= 0) { - rc = virNetDevLinkDump(NULL, ifindex, tb, src_pid, dst_pid); + VIR_FREE(nlData); + rc = virNetDevLinkDump(NULL, ifindex, &nlData, tb, src_pid, dst_pid); if (rc < 0) goto cleanup; @@ -909,7 +916,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, } cleanup: - + VIR_FREE(nlData); return rc; }