[libvirt] [PATCH] macvtap: convert nl msg construction to use libnl

Stefan Berger stefanb at linux.vnet.ibm.com
Wed Nov 3 19:36:40 UTC 2010


In a first step I am converting the netlink message construction in 
macvtap code to use libnl. It's pretty much a 1:1 conversion except that 
now the message needs to be allocated and deallocated.

Signed-off-by: Stefan Berger <stefanb at us.ibm.com>

---
  src/util/macvtap.c |  145 
+++++++++++++++++------------------------------------
  1 file changed, 49 insertions(+), 96 deletions(-)

Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -196,51 +196,6 @@ err_exit:
  }


-static struct rtattr *
-rtattrCreate(char *buffer, int bufsize, int type,
-             const void *data, int datalen)
-{
-    struct rtattr *r = (struct rtattr *)buffer;
-    r->rta_type = type;
-    r->rta_len  = RTA_LENGTH(datalen);
-    if (r->rta_len > bufsize)
-        return NULL;
-    memcpy(RTA_DATA(r), data, datalen);
-    return r;
-}
-
-
-static void
-nlInit(struct nlmsghdr *nlm, int flags, int type)
-{
-    nlm->nlmsg_len = NLMSG_LENGTH(0);
-    nlm->nlmsg_flags = flags;
-    nlm->nlmsg_type = type;
-}
-
-
-static void
-nlAlign(struct nlmsghdr *nlm)
-{
-    nlm->nlmsg_len = NLMSG_ALIGN(nlm->nlmsg_len);
-}
-
-
-static void *
-nlAppend(struct nlmsghdr *nlm, int totlen, const void *data, int datalen)
-{
-    char *pos;
-    nlAlign(nlm);
-    if (nlm->nlmsg_len + NLMSG_ALIGN(datalen) > totlen)
-        return NULL;
-    pos = (char *)nlm + nlm->nlmsg_len;
-    memcpy(pos, data, datalen);
-    nlm->nlmsg_len += datalen;
-    nlAlign(nlm);
-    return pos;
-}
-
-
  # if WITH_MACVTAP

  static int
@@ -252,73 +207,60 @@ link_add(const char *type,
           int *retry)
  {
      int rc = 0;
-    char nlmsgbuf[NLMSGBUF_SIZE];
-    struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+    struct nlmsghdr *resp;
      struct nlmsgerr *err;
-    char rtattbuf[RATTBUF_SIZE];
-    struct rtattr *rta, *rta1, *li;
      struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
      int ifindex;
      char *recvbuf = NULL;
      unsigned int recvbuflen;
+    struct nl_msg *nl_msg;
+    struct nlattr *linkinfo, *info_data;

      if (ifaceGetIndex(true, srcdev, &ifindex) != 0)
          return -1;

-    *retry = 0;
-
-    memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
+    nl_msg = nlmsg_alloc_simple(RTM_NEWLINK,
+                                NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
+    if (!nl_msg) {
+        virReportOOMError();
+        return -1;
+    }

-    nlInit(nlm, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL, RTM_NEWLINK);
+    *retry = 0;

-    if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
+    if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
          goto buffer_too_small;

-    rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_LINK,
- &ifindex, sizeof(ifindex));
-    if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+    if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0)
          goto buffer_too_small;

-    rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_ADDRESS,
-                       macaddress, macaddrsize);
-    if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+    if (nla_put(nl_msg, IFLA_ADDRESS, macaddrsize, macaddress) < 0)
          goto buffer_too_small;

-    if (ifname) {
-        rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
-                           ifname, strlen(ifname) + 1);
-        if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, 
rta->rta_len))
-            goto buffer_too_small;
-    }
+    if (ifname &&
+        nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
+        goto buffer_too_small;

-    rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_LINKINFO, NULL, 0);
-    if (!rta ||
-        !(li = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
+    if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO)))
          goto buffer_too_small;

-    rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_INFO_KIND,
-                       type, strlen(type));
-    if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+    if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0)
          goto buffer_too_small;

      if (macvlan_mode > 0) {
-        rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_INFO_DATA,
-                           NULL, 0);
-        if (!rta ||
-            !(rta1 = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, 
rta->rta_len)))
+        if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA)))
              goto buffer_too_small;

-        rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_MACVLAN_MODE,
- &macvlan_mode, sizeof(macvlan_mode));
-        if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, 
rta->rta_len))
+        if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode),
+ &macvlan_mode) < 0)
              goto buffer_too_small;

-        rta1->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)rta1;
+        nla_nest_end(nl_msg, info_data);
      }

-    li->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)li;
+    nla_nest_end(nl_msg, linkinfo);

-    if (nlComm(nlm, &recvbuf, &recvbuflen, 0) < 0)
+    if (nlComm(nlmsg_hdr(nl_msg), &recvbuf, &recvbuflen, 0) < 0)
          return -1;

      if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
@@ -359,17 +301,23 @@ link_add(const char *type,

      VIR_FREE(recvbuf);

+    nlmsg_free(nl_msg);
+
      return rc;

  malformed_resp:
+    nlmsg_free(nl_msg);
+
      macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("malformed netlink response message"));
      VIR_FREE(recvbuf);
      return -1;

  buffer_too_small:
+    nlmsg_free(nl_msg);
+
      macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
-                 _("internal buffer is too small"));
+                 _("allocated netlink buffer is too small"));
      return -1;
  }

@@ -378,28 +326,27 @@ static int
  link_del(const char *name)
  {
      int rc = 0;
-    char nlmsgbuf[NLMSGBUF_SIZE];
-    struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+    struct nlmsghdr *resp;
      struct nlmsgerr *err;
-    char rtattbuf[RATTBUF_SIZE];
-    struct rtattr *rta;
      struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
      char *recvbuf = NULL;
      unsigned int recvbuflen;
+    struct nl_msg *nl_msg;

-    memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
-
-    nlInit(nlm, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL, RTM_DELLINK);
+    nl_msg = nlmsg_alloc_simple(RTM_DELLINK,
+                                NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
+    if (!nl_msg) {
+        virReportOOMError();
+        return -1;
+    }

-    if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
+    if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
          goto buffer_too_small;

-    rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
-                       name, strlen(name)+1);
-    if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+    if (nla_put(nl_msg, IFLA_IFNAME, strlen(name)+1, name) < 0)
          goto buffer_too_small;

-    if (nlComm(nlm, &recvbuf, &recvbuflen, 0) < 0)
+    if (nlComm(nlmsg_hdr(nl_msg), &recvbuf, &recvbuflen, 0) < 0)
          return -1;

      if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
@@ -430,17 +377,23 @@ link_del(const char *name)

      VIR_FREE(recvbuf);

+    nlmsg_free(nl_msg);
+
      return rc;

  malformed_resp:
+    nlmsg_free(nl_msg);
+
      macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("malformed netlink response message"));
      VIR_FREE(recvbuf);
      return -1;

  buffer_too_small:
+    nlmsg_free(nl_msg);
+
      macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
-                 _("internal buffer is too small"));
+                 _("allocated netlink buffer is too small"));
      return -1;
  }




More information about the libvir-list mailing list