[PATCH] macvtap: convert send / recv function to use libnl

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

 



In a second step I am converting the netlink send/receive function to use libnl.

I tested this with 802.1Qbg profiles and my test server and did not see a regression.


Caveat: The online documentation of libnl talks about nl_socket_alloc() but the header file provides nl_handle_alloc() -- this could be a hint to a possible problem between libnl versions...

http://www.infradead.org/~tgr/libnl/doc/group__socket.html

versus

http://libnl.sourcearchive.com/documentation/1.1/group__socket_gf903c9ea089735b1ba8e40dae801c47d.html


Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>

---
src/util/macvtap.c | 89 ++++++++++++++++++-----------------------------------
 1 file changed, 31 insertions(+), 58 deletions(-)

Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -82,22 +82,6 @@ enum virVirtualPortOp {
 };


-static int nlOpen(void)
-{
-    int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-    if (fd < 0)
-        virReportSystemError(errno,
-                             "%s",_("cannot open netlink socket"));
-    return fd;
-}
-
-
-static void nlClose(int fd)
-{
-    close(fd);
-}
-
-
 /**
  * nlComm:
  * @nlmsg: pointer to netlink message
@@ -111,8 +95,8 @@ static void nlClose(int fd)
  * buffer will be returned.
  */
 static
-int nlComm(struct nlmsghdr *nlmsg,
-           char **respbuf, unsigned int *respbuflen,
+int nlComm(struct nl_msg *nl_msg,
+           unsigned char **respbuf, unsigned int *respbuflen,
            int nl_pid)
 {
     int rc = 0;
@@ -121,24 +105,29 @@ int nlComm(struct nlmsghdr *nlmsg,
             .nl_pid    = nl_pid,
             .nl_groups = 0,
     };
-    int rcvChunkSize = 1024; // expecting less than that
-    int rcvoffset = 0;
     ssize_t nbytes;
     struct timeval tv = {
         .tv_sec = NETLINK_ACK_TIMEOUT_S,
     };
     fd_set readfds;
-    int fd = nlOpen();
+    int fd;
     int n;
+    struct nl_handle *nlhandle = nl_handle_alloc();
+    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);

-    if (fd < 0)
+    if (!nlhandle)
         return -1;

+    if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
+        rc = -1;
+        goto err_exit;
+    }
+
+    nlmsg_set_dst(nl_msg, &nladdr);
+
     nlmsg->nlmsg_pid = getpid();
-    nlmsg->nlmsg_flags |= NLM_F_ACK;

-    nbytes = sendto(fd, (void *)nlmsg, nlmsg->nlmsg_len, 0,
-                    (struct sockaddr *)&nladdr, sizeof(nladdr));
+    nbytes = nl_send_auto_complete(nlhandle, nl_msg);
     if (nbytes < 0) {
         virReportSystemError(errno,
                              "%s", _("cannot send to netlink socket"));
@@ -146,6 +135,8 @@ int nlComm(struct nlmsghdr *nlmsg,
         goto err_exit;
     }

+    fd = nl_socket_get_fd(nlhandle);
+
     FD_ZERO(&readfds);
     FD_SET(fd, &readfds);

@@ -161,28 +152,9 @@ int nlComm(struct nlmsghdr *nlmsg,
         goto err_exit;
     }

-    while (1) {
-        if (VIR_REALLOC_N(*respbuf, rcvoffset+rcvChunkSize) < 0) {
-            virReportOOMError();
-            rc = -1;
-            goto err_exit;
-        }
-
-        socklen_t addrlen = sizeof(nladdr);
-        nbytes = recvfrom(fd, &((*respbuf)[rcvoffset]), rcvChunkSize, 0,
-                          (struct sockaddr *)&nladdr, &addrlen);
-        if (nbytes < 0) {
-            if (errno == EAGAIN || errno == EINTR)
-                continue;
-            virReportSystemError(errno, "%s",
-                                 _("error receiving from netlink socket"));
-            rc = -1;
-            goto err_exit;
-        }
-        rcvoffset += nbytes;
-        break;
-    }
-    *respbuflen = rcvoffset;
+    *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
+    if (*respbuflen <= 0)
+        rc = -1;

 err_exit:
     if (rc == -1) {
@@ -191,7 +163,8 @@ err_exit:
         *respbuflen = 0;
     }

-    nlClose(fd);
+    nl_handle_destroy(nlhandle);
+
     return rc;
 }

@@ -211,7 +184,7 @@ link_add(const char *type,
     struct nlmsgerr *err;
     struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
     int ifindex;
-    char *recvbuf = NULL;
+    unsigned char *recvbuf = NULL;
     unsigned int recvbuflen;
     struct nl_msg *nl_msg;
     struct nlattr *linkinfo, *info_data;
@@ -260,7 +233,7 @@ link_add(const char *type,

     nla_nest_end(nl_msg, linkinfo);

-    if (nlComm(nlmsg_hdr(nl_msg), &recvbuf, &recvbuflen, 0) < 0) {
+    if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
         rc = -1;
         goto err_exit;
     }
@@ -332,7 +305,7 @@ link_del(const char *ifname)
     struct nlmsghdr *resp;
     struct nlmsgerr *err;
     struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
-    char *recvbuf = NULL;
+    unsigned char *recvbuf = NULL;
     unsigned int recvbuflen;
     struct nl_msg *nl_msg;

@@ -349,7 +322,7 @@ link_del(const char *ifname)
     if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
         goto buffer_too_small;

-    if (nlComm(nlmsg_hdr(nl_msg), &recvbuf, &recvbuflen, 0) < 0) {
+    if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
         rc = -1;
         goto err_exit;
     }
@@ -746,7 +719,7 @@ getLldpadPid(void) {

 static int
 link_dump(bool nltarget_kernel, const char *ifname, int ifindex,
-          struct nlattr **tb, char **recvbuf)
+          struct nlattr **tb, unsigned char **recvbuf)
 {
     int rc = 0;
     struct nlmsghdr *resp;
@@ -783,7 +756,7 @@ link_dump(bool nltarget_kernel, const ch
         }
     }

-    if (nlComm(nlmsg_hdr(nl_msg), recvbuf, &recvbuflen, pid) < 0) {
+    if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) {
         rc = -1;
         goto err_exit;
     }
@@ -869,7 +842,7 @@ ifaceGetNthParent(int ifindex, const cha
 {
     int rc;
     struct nlattr *tb[IFLA_MAX + 1] = { NULL, };
-    char *recvbuf = NULL;
+    unsigned char *recvbuf = NULL;
     bool end = false;
     unsigned int i = 0;

@@ -1029,7 +1002,7 @@ doPortProfileOpSetLink(bool nltarget_ker
         .ifi_family = AF_UNSPEC,
         .ifi_index  = ifindex,
     };
-    char *recvbuf = NULL;
+    unsigned char *recvbuf = NULL;
     unsigned int recvbuflen = 0;
     uint32_t pid = 0;
     struct nl_msg *nl_msg;
@@ -1140,7 +1113,7 @@ doPortProfileOpSetLink(bool nltarget_ker
         }
     }

-    if (nlComm(nlmsg_hdr(nl_msg), &recvbuf, &recvbuflen, pid) < 0) {
+    if (nlComm(nl_msg, &recvbuf, &recvbuflen, pid) < 0) {
         rc = -1;
         goto err_exit;
     }
@@ -1208,7 +1181,7 @@ doPortProfileOpCommon(bool nltarget_kern
                       uint8_t op)
 {
     int rc;
-    char *recvbuf = NULL;
+    unsigned char *recvbuf = NULL;
     struct nlattr *tb[IFLA_MAX + 1] = { NULL , };
     int repeats = STATUS_POLL_TIMEOUT_USEC / STATUS_POLL_INTERVL_USEC;
     uint16_t status = 0;

--
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]