On 11/17/20 1:48 AM, Shi Lei wrote:
When netlink is supported, use netlink to create veth device pair
rather than 'ip link' command.

Signed-off-by: Shi Lei <shi_...@massclouds.com>
---
  src/util/virnetdevveth.c | 39 ++++++++++++++++++++++++++++++---------
  1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
index b3eee1af..996bf5dd 100644
--- a/src/util/virnetdevveth.c
+++ b/src/util/virnetdevveth.c
@@ -27,6 +27,7 @@
  #include "virfile.h"
  #include "virstring.h"
  #include "virnetdev.h"
+#include "virnetlink.h"
#define VIR_FROM_THIS VIR_FROM_NONE @@ -116,7 +117,6 @@ int virNetDevVethCreate(char** veth1, char** veth2)
      for (i = 0; i < MAX_VETH_RETRIES; i++) {
          g_autofree char *veth1auto = NULL;
          g_autofree char *veth2auto = NULL;
-        g_autoptr(virCommand) cmd = NULL;
int status;
          if (!*veth1) {
@@ -136,15 +136,32 @@ int virNetDevVethCreate(char** veth1, char** veth2)
              vethNum = veth2num + 1;
          }
- cmd = virCommandNew("ip");
-        virCommandAddArgList(cmd, "link", "add",
-                             *veth1 ? *veth1 : veth1auto,
-                             "type", "veth", "peer", "name",
-                             *veth2 ? *veth2 : veth2auto,
-                             NULL);
+#if defined(WITH_LIBNL)
+        {
+            int error = 0;
+            virNetlinkNewLinkData data = {
+                .veth_peer = *veth2 ? *veth2 : veth2auto,
+            };
- if (virCommandRun(cmd, &status) < 0)
-            goto cleanup;
+            status = virNetlinkNewLink(*veth1 ? *veth1 : veth1auto,
+                                       "veth", &data, &error);
+            if (status < 0)
+                goto cleanup;
+        }
+#else
+        {
+            g_autoptr(virCommand) cmd = NULL;
+            cmd = virCommandNew("ip");
+            virCommandAddArgList(cmd, "link", "add",
+                                 *veth1 ? *veth1 : veth1auto,
+                                 "type", "veth", "peer", "name",
+                                 *veth2 ? *veth2 : veth2auto,
+                                 NULL);
+
+            if (virCommandRun(cmd, &status) < 0)
+                goto cleanup;
+        }
+#endif /* WITH_LIBNL */


Although it isn't a hard/fast rule, we generally prefer to have complete functions within an #ifdefs rather then putting #ifdefs in the middle of a function. Could you put these bits into smaller functions, patterned like below, and then call the vir*Internal() functions from the existing functions?

(other than that this looks fine, although I haven't actually tried *running* it yet :-))


#if defined(WITH_LIBNL)

int

virNetDevVethCreateInternal(char *veth1, char *veth2)

{

    int error;

    virNetlinkNewLinkData data = { .veth_peer = veth2 };


    return virNetlinkNewLink(veth1, "veth", &data, &error);

}



int

virNetDevVethDeleteInternal(char *veth)

{

    return virNetlinkDelLink(veth, NULL);

}



#else



int

virNetDevVethCreateInternal(char *veth1, char *veth2)

{

    g_autoptr(virCommand) cmd = virCommandNew("ip");


    virCommandAddArgList(cmd, "link", "add", veth1, veth2);

    return virCommandRun(cmd, NULL);

}



int

virNetDevVethDeleteInternal(char *veth)

{

    int status;
    g_autoptr(virCommand) cmd = virCommandNewArgList("ip", "link", "del", veth, NULL);

    if (virCommandRun(cmd, &status) < 0)
        return -1;

    if (status != 0) {
        if (!virNetDevExists(veth)) {
            VIR_DEBUG("Device %s already deleted (by kernel namespace cleanup)", veth);
            return 0;
        }
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to delete veth device %s"), veth);
        return -1;
    }

    return 0;
}


if (status == 0) {
              if (veth1auto) {
@@ -188,6 +205,9 @@ int virNetDevVethCreate(char** veth1, char** veth2)
   */
  int virNetDevVethDelete(const char *veth)
  {
+#if defined(WITH_LIBNL)
+    return virNetlinkDelLink(veth, NULL);
+#else
      int status;
      g_autoptr(virCommand) cmd = virCommandNewArgList("ip", "link",
                                                         "del", veth, NULL);
@@ -206,4 +226,5 @@ int virNetDevVethDelete(const char *veth)
      }
return 0;
+#endif /* WITH_LIBNL */
  }


(Aside from this, it looks like veth interface naming could benefit from the same simplifications that I did to tap and macvtap awhile back (basically changing the auto-generated names to never re-use a name - commit 95089f481 and commit d7f38beb2e). But that isn't something for this series, just another thing to add to the to-do list :-))

Reply via email to