util: move virNetDevLinkDump to virnetlink.c

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.
This commit is contained in:
Laine Stump 2016-06-13 07:59:12 -04:00
parent d0a9dbc323
commit 943a400c0d
6 changed files with 145 additions and 141 deletions

View File

@ -1878,7 +1878,6 @@ virNetDevGetVirtualFunctionInfo;
virNetDevGetVirtualFunctions;
virNetDevGetVLanID;
virNetDevIsVirtualFunction;
virNetDevLinkDump;
virNetDevReplaceMacAddress;
virNetDevReplaceNetConfig;
virNetDevRestoreMacAddress;
@ -1992,6 +1991,7 @@ virNetDevVPortProfileOpTypeToString;
# util/virnetlink.h
virNetlinkCommand;
virNetlinkDelLink;
virNetlinkDumpLink;
virNetlinkEventAddClient;
virNetlinkEventRemoveClient;
virNetlinkEventServiceIsRunning;

View File

@ -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;
@ -2639,19 +2522,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,

View File

@ -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,

View File

@ -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;

View File

@ -36,6 +36,7 @@
#include <sys/socket.h>
#include "virnetlink.h"
#include "virnetdev.h"
#include "virlog.h"
#include "viralloc.h"
#include "virthread.h"
@ -315,6 +316,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:
*
@ -922,6 +1043,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)

View File

@ -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,