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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>

---
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;
 }

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]