virNetDevLinkDump should have been in virnetlink.c, but that file didn't exist yet when the function was created. It didn't really matter until now - I found that having virnetlink.h included by virnetdev.h caused build problems when trying to #include virnetdev.h in a .c file in src/conf (due to missing directory in -I). Rather than fix that to further institutionalize the incorrect placement of this one function, this patch moves the function. --- src/libvirt_private.syms | 2 +- src/util/virnetdev.c | 134 +------------------------------------- src/util/virnetdev.h | 6 -- src/util/virnetdevvportprofile.c | 4 +- src/util/virnetlink.c | 135 +++++++++++++++++++++++++++++++++++++++ src/util/virnetlink.h | 5 ++ 6 files changed, 145 insertions(+), 141 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 501c23e..00fa673 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1872,7 +1872,6 @@ virNetDevGetVirtualFunctionInfo; virNetDevGetVirtualFunctions; virNetDevGetVLanID; virNetDevIsVirtualFunction; -virNetDevLinkDump; virNetDevReplaceMacAddress; virNetDevReplaceNetConfig; virNetDevRestoreMacAddress; @@ -1986,6 +1985,7 @@ virNetDevVPortProfileOpTypeToString; # util/virnetlink.h virNetlinkCommand; virNetlinkDelLink; +virNetlinkDumpLink; virNetlinkEventAddClient; virNetlinkEventRemoveClient; virNetlinkEventServiceIsRunning; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 5a4ccc6..4cd51cb 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -23,6 +23,7 @@ #include <config.h> #include "virnetdev.h" +#include "virnetlink.h" #include "virmacaddr.h" #include "virfile.h" #include "virerror.h" @@ -2086,124 +2087,6 @@ static struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { .maxlen = sizeof(struct ifla_vf_vlan) }, }; -/** - * virNetDevLinkDump: - * - * @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 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, - void **nlData, struct nlattr **tb, - uint32_t src_pid, uint32_t dst_pid) -{ - int rc = -1; - struct nlmsghdr *resp = NULL; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex - }; - unsigned int recvbuflen; - struct nl_msg *nl_msg; - - if (ifname && ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) - return -1; - - ifinfo.ifi_index = ifindex; - - nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); - if (!nl_msg) { - virReportOOMError(); - return -1; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (ifname) { - if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - } - -# ifdef RTEXT_FILTER_VF - /* if this filter exists in the kernel's netlink implementation, - * we need to set it, otherwise the response message will not - * contain the IFLA_VFINFO_LIST that we're looking for. - */ - { - uint32_t ifla_ext_mask = RTEXT_FILTER_VF; - - if (nla_put(nl_msg, IFLA_EXT_MASK, - sizeof(ifla_ext_mask), &ifla_ext_mask) < 0) { - goto buffer_too_small; - } - } -# endif - - if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, - src_pid, dst_pid, NETLINK_ROUTE, 0) < 0) - goto cleanup; - - if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL) - goto malformed_resp; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - if (err->error) { - virReportSystemError(-err->error, - _("error dumping %s (%d) interface"), - ifname, ifindex); - goto cleanup; - } - break; - - case GENL_ID_CTRL: - case NLMSG_DONE: - rc = nlmsg_parse(resp, sizeof(struct ifinfomsg), - tb, IFLA_MAX, NULL); - if (rc < 0) - goto malformed_resp; - break; - - default: - goto malformed_resp; - } - rc = 0; - cleanup: - nlmsg_free(nl_msg); - if (rc < 0) - VIR_FREE(resp); - *nlData = resp; - return rc; - - malformed_resp: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - goto cleanup; - - buffer_too_small: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - goto cleanup; -} static int virNetDevSetVfConfig(const char *ifname, int ifindex, int vf, @@ -2398,7 +2281,7 @@ virNetDevGetVfConfig(const char *ifname, int vf, virMacAddrPtr mac, struct nlattr *tb[IFLA_MAX + 1] = {NULL, }; int ifindex = -1; - rc = virNetDevLinkDump(ifname, ifindex, &nlData, tb, 0, 0); + rc = virNetlinkDumpLink(ifname, ifindex, &nlData, tb, 0, 0); if (rc < 0) goto cleanup; @@ -2640,19 +2523,6 @@ virNetDevRestoreNetConfig(const char *linkdev, int vf, const char *stateDir) #else /* defined(__linux__) && defined(HAVE_LIBNL) */ 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) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to dump link info on this platform")); - return -1; -} - -int virNetDevReplaceNetConfig(const char *linkdev ATTRIBUTE_UNUSED, int vf ATTRIBUTE_UNUSED, const virMacAddr *macaddress ATTRIBUTE_UNUSED, diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index cbe7938..522536f 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -27,7 +27,6 @@ # include "virbitmap.h" # include "virsocketaddr.h" -# include "virnetlink.h" # include "virmacaddr.h" # include "virpci.h" # include "virnetdevvlan.h" @@ -170,11 +169,6 @@ int virNetDevGetVirtualFunctions(const char *pfname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; -int virNetDevLinkDump(const char *ifname, int ifindex, - void **nlData, struct nlattr **tb, - uint32_t src_pid, uint32_t dst_pid) - ATTRIBUTE_RETURN_CHECK; - int virNetDevReplaceNetConfig(const char *linkdev, int vf, const virMacAddr *macaddress, virNetDevVlanPtr vlan, diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 8100656..db495a7 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -880,7 +880,7 @@ virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int while (!end && i <= nthParent) { VIR_FREE(nlData); - rc = virNetDevLinkDump(ifname, ifindex, &nlData, tb, 0, 0); + rc = virNetlinkDumpLink(ifname, ifindex, &nlData, tb, 0, 0); if (rc < 0) break; @@ -964,7 +964,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, while (--repeats >= 0) { VIR_FREE(nlData); - rc = virNetDevLinkDump(NULL, ifindex, &nlData, tb, src_pid, dst_pid); + rc = virNetlinkDumpLink(NULL, ifindex, &nlData, tb, src_pid, dst_pid); if (rc < 0) goto cleanup; diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c index 513f36e..a5d10fa 100644 --- a/src/util/virnetlink.c +++ b/src/util/virnetlink.c @@ -36,6 +36,7 @@ #include <sys/socket.h> #include "virnetlink.h" +#include "virnetdev.h" #include "virlog.h" #include "viralloc.h" #include "virthread.h" @@ -316,6 +317,126 @@ int virNetlinkCommand(struct nl_msg *nl_msg, /** + * virNetlinkDumpLink: + * + * @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 from netlink about an interface given its name or index. + * + * Returns 0 on success, -1 on fatal error. + */ +int +virNetlinkDumpLink(const char *ifname, int ifindex, + void **nlData, struct nlattr **tb, + uint32_t src_pid, uint32_t dst_pid) +{ + int rc = -1; + struct nlmsghdr *resp = NULL; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex + }; + unsigned int recvbuflen; + struct nl_msg *nl_msg; + + if (ifname && ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) + return -1; + + ifinfo.ifi_index = ifindex; + + nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); + if (!nl_msg) { + virReportOOMError(); + return -1; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (ifname) { + if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + } + +# ifdef RTEXT_FILTER_VF + /* if this filter exists in the kernel's netlink implementation, + * we need to set it, otherwise the response message will not + * contain the IFLA_VFINFO_LIST that we're looking for. + */ + { + uint32_t ifla_ext_mask = RTEXT_FILTER_VF; + + if (nla_put(nl_msg, IFLA_EXT_MASK, + sizeof(ifla_ext_mask), &ifla_ext_mask) < 0) { + goto buffer_too_small; + } + } +# endif + + if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, + src_pid, dst_pid, NETLINK_ROUTE, 0) < 0) + goto cleanup; + + if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL) + goto malformed_resp; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + if (err->error) { + virReportSystemError(-err->error, + _("error dumping %s (%d) interface"), + ifname, ifindex); + goto cleanup; + } + break; + + case GENL_ID_CTRL: + case NLMSG_DONE: + rc = nlmsg_parse(resp, sizeof(struct ifinfomsg), + tb, IFLA_MAX, NULL); + if (rc < 0) + goto malformed_resp; + break; + + default: + goto malformed_resp; + } + rc = 0; + cleanup: + nlmsg_free(nl_msg); + if (rc < 0) + VIR_FREE(resp); + *nlData = resp; + return rc; + + malformed_resp: + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + goto cleanup; + + buffer_too_small: + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + goto cleanup; +} + + +/** * virNetlinkDelLink: * * @ifname: Name of the link @@ -923,6 +1044,20 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED, int +virNetlinkDumpLink(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) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to dump link info on this platform")); + return -1; +} + + +int virNetlinkDelLink(const char *ifname ATTRIBUTE_UNUSED, virNetlinkDelLinkFallback fallback ATTRIBUTE_UNUSED) { diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h index 0664a7a..11e817c 100644 --- a/src/util/virnetlink.h +++ b/src/util/virnetlink.h @@ -58,6 +58,11 @@ int virNetlinkDelLink(const char *ifname, virNetlinkDelLinkFallback fallback); int virNetlinkGetErrorCode(struct nlmsghdr *resp, unsigned int recvbuflen); +int virNetlinkDumpLink(const char *ifname, int ifindex, + void **nlData, struct nlattr **tb, + uint32_t src_pid, uint32_t dst_pid) + ATTRIBUTE_RETURN_CHECK; + typedef void (*virNetlinkEventHandleCallback)(struct nlmsghdr *, unsigned int length, struct sockaddr_nl *peer, -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list