]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: netlink function to delete any network device
authorLaine Stump <laine@laine.org>
Tue, 17 Mar 2015 18:27:21 +0000 (14:27 -0400)
committerLaine Stump <laine@laine.org>
Thu, 26 Mar 2015 19:29:42 +0000 (15:29 -0400)
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.

src/libvirt_private.syms
src/util/virnetlink.c
src/util/virnetlink.h

index 839702b874afdcebc5d15d873ee90c6180057417..5716ece1d15e3f42f59773371e0977efb9fc1ff2 100644 (file)
@@ -1816,6 +1816,7 @@ virNetDevVPortProfileOpTypeToString;
 
 # util/virnetlink.h
 virNetlinkCommand;
+virNetlinkDelLink;
 virNetlinkEventAddClient;
 virNetlinkEventRemoveClient;
 virNetlinkEventServiceIsRunning;
index d52f66acf595fc7fc216024123ae86081bc3d1f9..86c9c9cac2d6beb4984fbd266c3ac5dc85b69a57 100644 (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
index 1a3e06d913251ceb3499379777ccfb0b006c9d46..06c3cd089f0891df38e53a0d49cac512140f89be 100644 (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);