util: netlink function to delete any network device

libvirt has always used the netlink RTM_DELLINK message to delete
macvtap/macvlan devices, but it can actually be used to delete other
types of network devices, such as bonds and bridges. This patch makes
virNetDevMacVLanDelete() available as a generic function so it can
intelligibly be called to delete these other types of interfaces.
This commit is contained in:
Laine Stump 2015-03-17 14:27:21 -04:00
parent df60346ca2
commit 0473b45cc1
3 changed files with 92 additions and 1 deletions

View File

@ -1816,6 +1816,7 @@ virNetDevVPortProfileOpTypeToString;
# util/virnetlink.h
virNetlinkCommand;
virNetlinkDelLink;
virNetlinkEventAddClient;
virNetlinkEventRemoveClient;
virNetlinkEventServiceIsRunning;

View File

@ -277,6 +277,87 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
}
/**
* virNetlinkDelLink:
*
* @ifname: Name of the link
*
* delete a network "link" (aka interface aka device) with the given
* name. This works for many different types of network devices,
* including macvtap and bridges.
*
* Returns 0 on success, -1 on fatal error.
*/
int
virNetlinkDelLink(const char *ifname)
{
int rc = -1;
struct nlmsghdr *resp = NULL;
struct nlmsgerr *err;
struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
unsigned int recvbuflen;
struct nl_msg *nl_msg;
nl_msg = nlmsg_alloc_simple(RTM_DELLINK,
NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
if (!nl_msg) {
virReportOOMError();
return -1;
}
if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
goto buffer_too_small;
if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
goto buffer_too_small;
if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
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 destroying network device %s"),
ifname);
goto cleanup;
}
break;
case NLMSG_DONE:
break;
default:
goto malformed_resp;
}
rc = 0;
cleanup:
nlmsg_free(nl_msg);
VIR_FREE(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;
}
int
virNetlinkGetErrorCode(struct nlmsghdr *resp, unsigned int recvbuflen)
{
@ -803,6 +884,14 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
return -1;
}
int
virNetlinkDelLink(const char *ifname ATTRIBUTE_UNSUPPORTED)
{
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1;
}
/**
* stopNetlinkEventServer: stop the monitor to receive netlink
* messages for libvirtd

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2013 Red Hat, Inc.
* Copyright (C) 2010-2013, 2015 Red Hat, Inc.
* Copyright (C) 2010-2012 IBM Corporation
*
* This library is free software; you can redistribute it and/or
@ -51,6 +51,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
struct nlmsghdr **resp, unsigned int *respbuflen,
uint32_t src_pid, uint32_t dst_pid,
unsigned int protocol, unsigned int groups);
int virNetlinkDelLink(const char *ifname);
int virNetlinkGetErrorCode(struct nlmsghdr *resp, unsigned int recvbuflen);