mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
util: support functions for mac/portprofile associations on hostdev
This patch adds the following: - functions to set and get vf configs - Functions to replace and store vf configs (Only mac address is handled today. But the functions can be easily extended for vlans and other vf configs) - function to dump link dev info (This is moved from virnetdevvportprofile.c) Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
This commit is contained in:
parent
b8b702734c
commit
5095bf06f1
@ -1213,11 +1213,15 @@ virNetDevGetMTU;
|
|||||||
virNetDevGetPhysicalFunction;
|
virNetDevGetPhysicalFunction;
|
||||||
virNetDevGetVLanID;
|
virNetDevGetVLanID;
|
||||||
virNetDevGetVirtualFunctionIndex;
|
virNetDevGetVirtualFunctionIndex;
|
||||||
|
virNetDevGetVirtualFunctionInfo;
|
||||||
virNetDevGetVirtualFunctions;
|
virNetDevGetVirtualFunctions;
|
||||||
virNetDevIsOnline;
|
virNetDevIsOnline;
|
||||||
virNetDevIsVirtualFunction;
|
virNetDevIsVirtualFunction;
|
||||||
|
virNetDevLinkDump;
|
||||||
virNetDevReplaceMacAddress;
|
virNetDevReplaceMacAddress;
|
||||||
|
virNetDevReplaceNetConfig;
|
||||||
virNetDevRestoreMacAddress;
|
virNetDevRestoreMacAddress;
|
||||||
|
virNetDevRestoreNetConfig;
|
||||||
virNetDevSetIPv4Address;
|
virNetDevSetIPv4Address;
|
||||||
virNetDevSetMAC;
|
virNetDevSetMAC;
|
||||||
virNetDevSetMTU;
|
virNetDevSetMTU;
|
||||||
|
@ -1127,8 +1127,47 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else /* !__linux__ */
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetDevGetVirtualFunctionInfo:
|
||||||
|
* @vfname: name of the virtual function interface
|
||||||
|
* @pfname: name of the physical function
|
||||||
|
* @vf: vf index
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -errno on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNetDevGetVirtualFunctionInfo(const char *vfname, char **pfname,
|
||||||
|
int *vf)
|
||||||
|
{
|
||||||
|
char *pf_sysfs_path = NULL, *vf_sysfs_path = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
*pfname = NULL;
|
||||||
|
|
||||||
|
if (virNetDevGetPhysicalFunction(vfname, pfname) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (virNetDevSysfsFile(&pf_sysfs_path, *pfname, "device") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virNetDevSysfsFile(&vf_sysfs_path, vfname, "device") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = pciGetVirtualFunctionIndex(pf_sysfs_path, vf_sysfs_path, vf);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ret < 0)
|
||||||
|
VIR_FREE(*pfname);
|
||||||
|
|
||||||
|
VIR_FREE(vf_sysfs_path);
|
||||||
|
VIR_FREE(pf_sysfs_path);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !__linux__ */
|
||||||
int
|
int
|
||||||
virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
|
virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
|
||||||
char ***vfname ATTRIBUTE_UNUSED,
|
char ***vfname ATTRIBUTE_UNUSED,
|
||||||
@ -1165,4 +1204,509 @@ virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED,
|
|||||||
_("Unable to get physical function status on this platform"));
|
_("Unable to get physical function status on this platform"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevGetVirtualFunctionInfo(const char *vfname ATTRIBUTE_UNUSED,
|
||||||
|
char **pfname ATTRIBUTE_UNUSED,
|
||||||
|
int *vf ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Unable to get virtual function info on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif /* !__linux__ */
|
#endif /* !__linux__ */
|
||||||
|
#if defined(__linux__) && defined(HAVE_LIBNL)
|
||||||
|
|
||||||
|
static struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
|
||||||
|
[IFLA_VF_MAC] = { .type = NLA_UNSPEC,
|
||||||
|
.maxlen = sizeof(struct ifla_vf_mac) },
|
||||||
|
[IFLA_VF_VLAN] = { .type = NLA_UNSPEC,
|
||||||
|
.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
|
||||||
|
* @nltarget_kernel: whether to send the message to the kernel or another
|
||||||
|
* process
|
||||||
|
* @nlattr: pointer to a pointer of netlink attributes that will contain
|
||||||
|
* the results
|
||||||
|
* @recvbuf: Pointer to the buffer holding the returned netlink response
|
||||||
|
* message; free it, once not needed anymore
|
||||||
|
* @getPidFunc: Pointer to a function that will be invoked if the kernel
|
||||||
|
* is not the target of the netlink message but it is to be
|
||||||
|
* sent to another process.
|
||||||
|
*
|
||||||
|
* Get information about an interface given its name or index.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on fatal error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNetDevLinkDump(const char *ifname, int ifindex,
|
||||||
|
bool nltarget_kernel, struct nlattr **tb,
|
||||||
|
unsigned char **recvbuf,
|
||||||
|
uint32_t (*getPidFunc)(void))
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct nlmsghdr *resp;
|
||||||
|
struct nlmsgerr *err;
|
||||||
|
struct ifinfomsg ifinfo = {
|
||||||
|
.ifi_family = AF_UNSPEC,
|
||||||
|
.ifi_index = ifindex
|
||||||
|
};
|
||||||
|
unsigned int recvbuflen;
|
||||||
|
uint32_t pid = 0;
|
||||||
|
struct nl_msg *nl_msg;
|
||||||
|
|
||||||
|
*recvbuf = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nltarget_kernel) {
|
||||||
|
pid = getPidFunc();
|
||||||
|
if (pid == 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetlinkCommand(nl_msg, recvbuf, &recvbuflen, pid) < 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
|
||||||
|
goto malformed_resp;
|
||||||
|
|
||||||
|
resp = (struct nlmsghdr *)*recvbuf;
|
||||||
|
|
||||||
|
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);
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
VIR_FREE(*recvbuf);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
malformed_resp:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("malformed netlink response message"));
|
||||||
|
VIR_FREE(*recvbuf);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buffer_too_small:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("allocated netlink buffer is too small"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDevSetVfConfig(const char *ifname, int ifindex, int vf,
|
||||||
|
bool nltarget_kernel, const unsigned char *macaddr,
|
||||||
|
int vlanid, uint32_t (*getPidFunc)(void))
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
struct nlmsghdr *resp;
|
||||||
|
struct nlmsgerr *err;
|
||||||
|
unsigned char *recvbuf = NULL;
|
||||||
|
unsigned int recvbuflen = 0;
|
||||||
|
uint32_t pid = 0;
|
||||||
|
struct nl_msg *nl_msg;
|
||||||
|
struct nlattr *vfinfolist, *vfinfo;
|
||||||
|
struct ifinfomsg ifinfo = {
|
||||||
|
.ifi_family = AF_UNSPEC,
|
||||||
|
.ifi_index = ifindex
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!macaddr && vlanid < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST);
|
||||||
|
if (!nl_msg) {
|
||||||
|
virReportOOMError();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
|
||||||
|
goto buffer_too_small;
|
||||||
|
|
||||||
|
if (ifname &&
|
||||||
|
nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
|
||||||
|
goto buffer_too_small;
|
||||||
|
|
||||||
|
|
||||||
|
if (!(vfinfolist = nla_nest_start(nl_msg, IFLA_VFINFO_LIST)))
|
||||||
|
goto buffer_too_small;
|
||||||
|
|
||||||
|
if (!(vfinfo = nla_nest_start(nl_msg, IFLA_VF_INFO)))
|
||||||
|
goto buffer_too_small;
|
||||||
|
|
||||||
|
if (macaddr) {
|
||||||
|
struct ifla_vf_mac ifla_vf_mac = {
|
||||||
|
.vf = vf,
|
||||||
|
.mac = { 0, },
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(ifla_vf_mac.mac, macaddr, VIR_MAC_BUFLEN);
|
||||||
|
|
||||||
|
if (nla_put(nl_msg, IFLA_VF_MAC, sizeof(ifla_vf_mac),
|
||||||
|
&ifla_vf_mac) < 0)
|
||||||
|
goto buffer_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vlanid >= 0) {
|
||||||
|
struct ifla_vf_vlan ifla_vf_vlan = {
|
||||||
|
.vf = vf,
|
||||||
|
.vlan = vlanid,
|
||||||
|
.qos = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nla_put(nl_msg, IFLA_VF_VLAN, sizeof(ifla_vf_vlan),
|
||||||
|
&ifla_vf_vlan) < 0)
|
||||||
|
goto buffer_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(nl_msg, vfinfo);
|
||||||
|
nla_nest_end(nl_msg, vfinfolist);
|
||||||
|
|
||||||
|
if (!nltarget_kernel) {
|
||||||
|
pid = getPidFunc();
|
||||||
|
if (pid == 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, pid) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
|
||||||
|
goto malformed_resp;
|
||||||
|
|
||||||
|
resp = (struct nlmsghdr *)recvbuf;
|
||||||
|
|
||||||
|
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 during set %s of ifindex %d"),
|
||||||
|
(macaddr ? (vlanid >= 0 ? "mac/vlan" : "mac") : "vlanid"),
|
||||||
|
ifindex);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NLMSG_DONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto malformed_resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
VIR_FREE(recvbuf);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
malformed_resp:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("malformed netlink response message"));
|
||||||
|
VIR_FREE(recvbuf);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
buffer_too_small:
|
||||||
|
nlmsg_free(nl_msg);
|
||||||
|
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("allocated netlink buffer is too small"));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDevParseVfConfig(struct nlattr **tb, int32_t vf, unsigned char *mac,
|
||||||
|
int *vlanid)
|
||||||
|
{
|
||||||
|
const char *msg = NULL;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
if (tb[IFLA_VFINFO_LIST]) {
|
||||||
|
struct ifla_vf_mac *vf_mac;
|
||||||
|
struct ifla_vf_vlan *vf_vlan;
|
||||||
|
struct nlattr *tb_vf_info = {NULL, };
|
||||||
|
struct nlattr *tb_vf[IFLA_VF_MAX+1];
|
||||||
|
int found = 0;
|
||||||
|
int rem;
|
||||||
|
|
||||||
|
nla_for_each_nested(tb_vf_info, tb[IFLA_VFINFO_LIST], rem) {
|
||||||
|
if (nla_type(tb_vf_info) != IFLA_VF_INFO)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nla_parse_nested(tb_vf, IFLA_VF_MAX, tb_vf_info,
|
||||||
|
ifla_vf_policy)) {
|
||||||
|
msg = _("error parsing IFLA_VF_INFO");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[IFLA_VF_MAC]) {
|
||||||
|
vf_mac = RTA_DATA(tb_vf[IFLA_VF_MAC]);
|
||||||
|
if (vf_mac && vf_mac->vf == vf) {
|
||||||
|
memcpy(mac, vf_mac->mac, VIR_MAC_BUFLEN);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[IFLA_VF_VLAN]) {
|
||||||
|
vf_vlan = RTA_DATA(tb_vf[IFLA_VF_VLAN]);
|
||||||
|
if (vf_vlan && vf_vlan->vf == vf) {
|
||||||
|
*vlanid = vf_vlan->vlan;
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (msg)
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", msg);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDevGetVfConfig(const char *ifname, int vf, unsigned char *mac,
|
||||||
|
int *vlanid)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
unsigned char *recvbuf = NULL;
|
||||||
|
struct nlattr *tb[IFLA_MAX + 1] = {NULL, };
|
||||||
|
int ifindex = -1;
|
||||||
|
|
||||||
|
rc = virNetDevLinkDump(ifname, ifindex, true, tb, &recvbuf, NULL);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = virNetDevParseVfConfig(tb, vf, mac, vlanid);
|
||||||
|
|
||||||
|
VIR_FREE(recvbuf);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDevReplaceVfConfig(const char *pflinkdev, int vf,
|
||||||
|
const unsigned char *macaddress,
|
||||||
|
int vlanid,
|
||||||
|
const char *stateDir)
|
||||||
|
{
|
||||||
|
unsigned char oldmac[6];
|
||||||
|
int oldvlanid = -1;
|
||||||
|
char *path = NULL;
|
||||||
|
char macstr[VIR_MAC_STRING_BUFLEN];
|
||||||
|
int ifindex = -1;
|
||||||
|
|
||||||
|
if (virNetDevGetVfConfig(pflinkdev, vf, oldmac, &oldvlanid) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&path, "%s/%s_vf%d",
|
||||||
|
stateDir, pflinkdev, vf) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virMacAddrFormat(oldmac, macstr);
|
||||||
|
if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) {
|
||||||
|
virReportSystemError(errno, _("Unable to preserve mac for pf = %s,"
|
||||||
|
" vf = %d"), pflinkdev, vf);
|
||||||
|
VIR_FREE(path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(path);
|
||||||
|
|
||||||
|
return virNetDevSetVfConfig(pflinkdev, ifindex, vf, true,
|
||||||
|
macaddress, vlanid, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDevRestoreVfConfig(const char *pflinkdev, int vf,
|
||||||
|
const char *stateDir)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
char *macstr = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
unsigned char oldmac[6];
|
||||||
|
int vlanid = -1;
|
||||||
|
int ifindex = -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&path, "%s/%s_vf%d",
|
||||||
|
stateDir, pflinkdev, vf) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virMacAddrParse(macstr, &oldmac[0]) != 0) {
|
||||||
|
virNetDevError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Cannot parse MAC address from '%s'"),
|
||||||
|
macstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*reset mac and remove file-ignore results*/
|
||||||
|
rc = virNetDevSetVfConfig(pflinkdev, ifindex, vf, true,
|
||||||
|
oldmac, vlanid, NULL);
|
||||||
|
ignore_value(unlink(path));
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(path);
|
||||||
|
VIR_FREE(macstr);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetDevReplaceNetConfig:
|
||||||
|
* @linkdev: name of the interface
|
||||||
|
* @vf: vf index if linkdev is a pf
|
||||||
|
* @macaddress: new MAC address for interface
|
||||||
|
* @vlanid: new vlanid
|
||||||
|
* @stateDir: directory to store old net config
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNetDevReplaceNetConfig(char *linkdev, int vf,
|
||||||
|
const unsigned char *macaddress, int vlanid,
|
||||||
|
char *stateDir)
|
||||||
|
{
|
||||||
|
if (vf == -1)
|
||||||
|
return virNetDevReplaceMacAddress(linkdev, macaddress, stateDir);
|
||||||
|
else
|
||||||
|
return virNetDevReplaceVfConfig(linkdev, vf, macaddress, vlanid,
|
||||||
|
stateDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetDevRestoreNetConfig:
|
||||||
|
* @linkdev: name of the interface
|
||||||
|
* @vf: vf index if linkdev is a pf
|
||||||
|
* @stateDir: directory containing old net config
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -errno on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNetDevRestoreNetConfig(char *linkdev, int vf, char *stateDir)
|
||||||
|
{
|
||||||
|
if (vf == -1)
|
||||||
|
return virNetDevRestoreMacAddress(linkdev, stateDir);
|
||||||
|
else
|
||||||
|
return virNetDevRestoreVfConfig(linkdev, vf, stateDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* defined(__linux__) && defined(HAVE_LIBNL) */
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevLinkDump(const char *ifname ATTRIBUTE_UNUSED,
|
||||||
|
int ifindex ATTRIBUTE_UNUSED,
|
||||||
|
bool nltarget_kernel ATTRIBUTE_UNUSED,
|
||||||
|
struct nlattr **tb ATTRIBUTE_UNUSED,
|
||||||
|
unsigned char **recvbuf ATTRIBUTE_UNUSED,
|
||||||
|
uint32_t (*getPidFunc)(void) ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Unable to dump link info on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevReplaceNetConfig(char *linkdev ATTRIBUTE_UNUSED,
|
||||||
|
int vf ATTRIBUTE_UNUSED,
|
||||||
|
const unsigned char *macaddress ATTRIBUTE_UNUSED,
|
||||||
|
int vlanid ATTRIBUTE_UNUSED,
|
||||||
|
char *stateDir ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Unable to replace net config on this platform"));
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevRestoreNetConfig(char *linkdev ATTRIBUTE_UNUSED,
|
||||||
|
int vf ATTRIBUTE_UNUSED,
|
||||||
|
char *stateDir ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Unable to restore net config on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__linux__) && defined(HAVE_LIBNL) */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
# define __VIR_NETDEV_H__
|
# define __VIR_NETDEV_H__
|
||||||
|
|
||||||
# include "virsocketaddr.h"
|
# include "virsocketaddr.h"
|
||||||
|
# include "virnetlink.h"
|
||||||
|
|
||||||
int virNetDevExists(const char *brname)
|
int virNetDevExists(const char *brname)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
||||||
@ -105,4 +106,22 @@ int virNetDevGetVirtualFunctions(const char *pfname,
|
|||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
|
||||||
ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
int virNetDevLinkDump(const char *ifname, int ifindex,
|
||||||
|
bool nltarget_kernel, struct nlattr **tb,
|
||||||
|
unsigned char **recvbuf,
|
||||||
|
uint32_t (*getPidFunc)(void))
|
||||||
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
int virNetDevReplaceNetConfig(char *linkdev, int vf,
|
||||||
|
const unsigned char *macaddress, int vlanid,
|
||||||
|
char *stateDir)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5);
|
||||||
|
|
||||||
|
int virNetDevRestoreNetConfig(char *linkdev, int vf, char *stateDir)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
|
||||||
|
|
||||||
|
int virNetDevGetVirtualFunctionInfo(const char *vfname, char **pfname,
|
||||||
|
int *vf)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
#endif /* __VIR_NETDEV_H__ */
|
#endif /* __VIR_NETDEV_H__ */
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
struct nl_msg;
|
struct nl_msg;
|
||||||
struct sockaddr_nl;
|
struct sockaddr_nl;
|
||||||
|
struct nlattr;
|
||||||
|
|
||||||
# endif /* __linux__ */
|
# endif /* __linux__ */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user