diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 3a60cf7c4380a63119e0b3f14b1e31d13404dd34..818afdcd75604c2f090997c4b01d642e2c67535d 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1354,23 +1354,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; @@ -1452,7 +1454,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: @@ -1648,15 +1652,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; } @@ -1799,6 +1806,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 00c82e0d5fc6513b3ce393e340f63138dba60f96..99d6388ff8b948725ad83000847995b80292c19e 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -129,7 +129,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 897727520f6a40639e8359d05f8c12a560ac210e..f55c3d5af1d55333f4eb16ac1e7e925e9024e34b 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; } @@ -823,6 +826,8 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int *nth = i - 1; + cleanup: + VIR_FREE(nlData); return rc; } @@ -844,6 +849,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; @@ -876,7 +882,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; @@ -908,7 +915,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, } cleanup: - + VIR_FREE(nlData); return rc; }