[PATCHv2 2/4] Add wrapper macros around nla_nest*/nla_put* to make code more readable

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

 



This patch adds wrapper macros around nla_nest*/nla_put* which apply to
virNetlinkNewLink and virNetDevSetVfConfig and virNetDevVPortProfileOpSetLink.

Signed-off-by: Shi Lei <shi_lei@xxxxxxxxxxxxxx>
---
 src/util/virnetdev.c             |  54 ++++++--------
 src/util/virnetdevvportprofile.c | 117 ++++++++++---------------------
 src/util/virnetlink.c            |  74 +++++++------------
 src/util/virnetlink.h            |  52 ++++++++++++++
 4 files changed, 134 insertions(+), 163 deletions(-)

diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 8eac419..892a147 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1657,11 +1657,11 @@ virNetDevSetVfConfig(const char *ifname, int vf,
 {
     int rc = -1;
     char macstr[VIR_MAC_STRING_BUFLEN];
-    struct nlmsghdr *resp = NULL;
     struct nlmsgerr *err;
     unsigned int recvbuflen = 0;
-    struct nl_msg *nl_msg;
     struct nlattr *vfinfolist, *vfinfo;
+    VIR_AUTOPTR(virNetlinkMsg) nl_msg = NULL;
+    VIR_AUTOFREE(struct nlmsghdr *) resp = NULL;
     struct ifinfomsg ifinfo = {
         .ifi_family = AF_UNSPEC,
         .ifi_index  = -1,
@@ -1676,47 +1676,41 @@ virNetDevSetVfConfig(const char *ifname, int vf,
         return rc;
     }
 
-    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
-        goto buffer_too_small;
-
-    if (ifname &&
-        nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
-        goto buffer_too_small;
-
+    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nlmsg_append error"));
+        return rc;
+    }
 
-    if (!(vfinfolist = nla_nest_start(nl_msg, IFLA_VFINFO_LIST)))
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_IFNAME, ifname);
 
-    if (!(vfinfo = nla_nest_start(nl_msg, IFLA_VF_INFO)))
-        goto buffer_too_small;
+    NETLINK_MSG_NEST_START(nl_msg, vfinfolist, IFLA_VFINFO_LIST);
+    NETLINK_MSG_NEST_START(nl_msg, vfinfo, IFLA_VF_INFO);
 
     if (macaddr) {
         struct ifla_vf_mac ifla_vf_mac = {
-             .vf = vf,
-             .mac = { 0, },
+            .vf = vf,
+            .mac = { 0, },
         };
 
         virMacAddrGetRaw(macaddr, ifla_vf_mac.mac);
 
-        if (nla_put(nl_msg, IFLA_VF_MAC, sizeof(ifla_vf_mac),
-                    &ifla_vf_mac) < 0)
-            goto buffer_too_small;
+        NETLINK_MSG_PUT(nl_msg, IFLA_VF_MAC,
+                        sizeof(ifla_vf_mac), &ifla_vf_mac);
     }
 
     if (vlanid >= 0) {
         struct ifla_vf_vlan ifla_vf_vlan = {
-             .vf = vf,
-             .vlan = vlanid,
-             .qos = 0,
+            .vf = vf,
+            .vlan = vlanid,
+            .qos = 0,
         };
 
-        if (nla_put(nl_msg, IFLA_VF_VLAN, sizeof(ifla_vf_vlan),
-                    &ifla_vf_vlan) < 0)
-            goto buffer_too_small;
+        NETLINK_MSG_PUT(nl_msg, IFLA_VF_VLAN,
+                        sizeof(ifla_vf_vlan), &ifla_vf_vlan);
     }
 
-    nla_nest_end(nl_msg, vfinfo);
-    nla_nest_end(nl_msg, vfinfolist);
+    NETLINK_MSG_NEST_END(nl_msg, vfinfo);
+    NETLINK_MSG_NEST_END(nl_msg, vfinfolist);
 
     if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
                           NETLINK_ROUTE, 0) < 0)
@@ -1767,20 +1761,12 @@ virNetDevSetVfConfig(const char *ifname, int vf,
               ifname, vf,
               macaddr ? virMacAddrFormat(macaddr, macstr) : "(unchanged)",
               vlanid, rc < 0 ? "Fail" : "Success");
-
-    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;
 }
 
 static int
diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
index 3ebf757..8574571 100644
--- a/src/util/virnetdevvportprofile.c
+++ b/src/util/virnetdevvportprofile.c
@@ -641,8 +641,6 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
                                int32_t vf,
                                uint8_t op)
 {
-    int rc = -1;
-    struct nlmsghdr *resp = NULL;
     struct nlmsgerr *err;
     struct ifinfomsg ifinfo = {
         .ifi_family = AF_UNSPEC,
@@ -651,12 +649,14 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
     unsigned int recvbuflen = 0;
     int src_pid = 0;
     uint32_t dst_pid = 0;
-    struct nl_msg *nl_msg;
     struct nlattr *vfports = NULL, *vfport;
     char macStr[VIR_MAC_STRING_BUFLEN];
     char hostUUIDStr[VIR_UUID_STRING_BUFLEN];
     char instanceUUIDStr[VIR_UUID_STRING_BUFLEN];
     const char *opName;
+    int vfport_type = IFLA_PORT_SELF;
+    VIR_AUTOPTR(virNetlinkMsg) nl_msg = NULL;
+    VIR_AUTOFREE(struct nlmsghdr *) resp = NULL;
 
     switch (op) {
     case PORT_REQUEST_PREASSOCIATE:
@@ -691,24 +691,21 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
     nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST);
     if (!nl_msg) {
         virReportOOMError();
-        return rc;
+        return -1;
     }
 
-    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
-        goto buffer_too_small;
+    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nlmsg_append error"));
+        return -1;
+    }
 
-    if (ifname &&
-        nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_IFNAME, ifname);
 
     if (macaddr || vlanid >= 0) {
         struct nlattr *vfinfolist, *vfinfo;
 
-        if (!(vfinfolist = nla_nest_start(nl_msg, IFLA_VFINFO_LIST)))
-            goto buffer_too_small;
-
-        if (!(vfinfo = nla_nest_start(nl_msg, IFLA_VF_INFO)))
-            goto buffer_too_small;
+        NETLINK_MSG_NEST_START(nl_msg, vfinfolist, IFLA_VFINFO_LIST);
+        NETLINK_MSG_NEST_START(nl_msg, vfinfo, IFLA_VF_INFO);
 
         if (macaddr) {
             struct ifla_vf_mac ifla_vf_mac = {
@@ -718,9 +715,8 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
 
             virMacAddrGetRaw(macaddr, ifla_vf_mac.mac);
 
-            if (nla_put(nl_msg, IFLA_VF_MAC, sizeof(ifla_vf_mac),
-                        &ifla_vf_mac) < 0)
-                goto buffer_too_small;
+            NETLINK_MSG_PUT(nl_msg, IFLA_VF_MAC,
+                            sizeof(ifla_vf_mac), &ifla_vf_mac);
         }
 
         if (vlanid >= 0) {
@@ -730,77 +726,49 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
                 .qos = 0,
             };
 
-            if (nla_put(nl_msg, IFLA_VF_VLAN, sizeof(ifla_vf_vlan),
-                        &ifla_vf_vlan) < 0)
-                goto buffer_too_small;
+            NETLINK_MSG_PUT(nl_msg, IFLA_VF_VLAN,
+                            sizeof(ifla_vf_vlan), &ifla_vf_vlan);
         }
 
-        nla_nest_end(nl_msg, vfinfo);
-        nla_nest_end(nl_msg, vfinfolist);
-    }
-
-    if (vf == PORT_SELF_VF && nltarget_kernel) {
-        if (!(vfport = nla_nest_start(nl_msg, IFLA_PORT_SELF)))
-            goto buffer_too_small;
-    } else {
-        if (!(vfports = nla_nest_start(nl_msg, IFLA_VF_PORTS)))
-            goto buffer_too_small;
-
-        /* begin nesting vfports */
-        if (!(vfport = nla_nest_start(nl_msg, IFLA_VF_PORT)))
-            goto buffer_too_small;
-    }
-
-    if (profileId) {
-        if (nla_put(nl_msg, IFLA_PORT_PROFILE, strlen(profileId) + 1,
-                    profileId) < 0)
-            goto buffer_too_small;
-    }
-
-    if (portVsi) {
-        if (nla_put(nl_msg, IFLA_PORT_VSI_TYPE, sizeof(*portVsi),
-                    portVsi) < 0)
-            goto buffer_too_small;
+        NETLINK_MSG_NEST_END(nl_msg, vfinfo);
+        NETLINK_MSG_NEST_END(nl_msg, vfinfolist);
     }
 
-    if (instanceId) {
-        if (nla_put(nl_msg, IFLA_PORT_INSTANCE_UUID, VIR_UUID_BUFLEN,
-                    instanceId) < 0)
-            goto buffer_too_small;
+    if (vf != PORT_SELF_VF || !nltarget_kernel) {
+        NETLINK_MSG_NEST_START(nl_msg, vfports, IFLA_VF_PORTS);
+        /* begin nesting of vfports */
+        vfport_type = IFLA_VF_PORT;
     }
+    /* begin nesting of vfport */
+    NETLINK_MSG_NEST_START(nl_msg, vfport, vfport_type);
 
-    if (hostUUID) {
-        if (nla_put(nl_msg, IFLA_PORT_HOST_UUID, VIR_UUID_BUFLEN,
-                    hostUUID) < 0)
-            goto buffer_too_small;
-    }
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_PORT_PROFILE, profileId);
+    NETLINK_MSG_PUT(nl_msg, IFLA_PORT_VSI_TYPE, sizeof(*portVsi), portVsi);
+    NETLINK_MSG_PUT(nl_msg, IFLA_PORT_INSTANCE_UUID, VIR_UUID_BUFLEN, instanceId);
+    NETLINK_MSG_PUT(nl_msg, IFLA_PORT_HOST_UUID, VIR_UUID_BUFLEN, hostUUID);
 
-    if (vf != PORT_SELF_VF) {
-        if (nla_put(nl_msg, IFLA_PORT_VF, sizeof(vf), &vf) < 0)
-            goto buffer_too_small;
-    }
+    if (vf != PORT_SELF_VF)
+        NETLINK_MSG_PUT(nl_msg, IFLA_PORT_VF, sizeof(vf), &vf);
 
-    if (nla_put(nl_msg, IFLA_PORT_REQUEST, sizeof(op), &op) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT(nl_msg, IFLA_PORT_REQUEST, sizeof(op), &op);
 
     /* end nesting of vport */
-    nla_nest_end(nl_msg, vfport);
-
+    NETLINK_MSG_NEST_END(nl_msg, vfport);
     if (vfports) {
         /* end nesting of vfports */
-        nla_nest_end(nl_msg, vfports);
+        NETLINK_MSG_NEST_END(nl_msg, vfports);
     }
 
     if (!nltarget_kernel) {
         if ((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0)
-            goto cleanup;
+            return -1;
         if ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0)
-            goto cleanup;
+            return -1;
     }
 
     if (virNetlinkCommand(nl_msg, &resp, &recvbuflen,
                           src_pid, dst_pid, NETLINK_ROUTE, 0) < 0)
-        goto cleanup;
+        return -1;
 
     if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL)
         goto malformed_resp;
@@ -815,7 +783,7 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
             virReportSystemError(-err->error,
                 _("error during virtual port configuration of ifindex %d"),
                 ifindex);
-            goto cleanup;
+            return -1;
         }
         break;
 
@@ -826,21 +794,12 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
         goto malformed_resp;
     }
 
-    rc = 0;
- cleanup:
-    nlmsg_free(nl_msg);
-    VIR_FREE(resp);
-    return rc;
+    return 0;
 
  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;
+    return -1;
 }
 
 
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 32aa62d..4d19ac9 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -417,11 +417,12 @@ virNetlinkDumpLink(const char *ifname, int ifindex,
         return -1;
     }
 
-    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
-        goto buffer_too_small;
+    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nlmsg_append error"));
+        return -1;
+    }
 
-    if (ifname && nla_put_string(nl_msg, IFLA_IFNAME, ifname) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_IFNAME, ifname);
 
 # ifdef RTEXT_FILTER_VF
     /* if this filter exists in the kernel's netlink implementation,
@@ -430,11 +431,7 @@ virNetlinkDumpLink(const char *ifname, int ifindex,
      */
     {
         uint32_t ifla_ext_mask = RTEXT_FILTER_VF;
-
-        if (nla_put(nl_msg, IFLA_EXT_MASK,
-                    sizeof(ifla_ext_mask), &ifla_ext_mask) < 0) {
-            goto buffer_too_small;
-        }
+        NETLINK_MSG_PUT_U32PTR(nl_msg, IFLA_EXT_MASK, &ifla_ext_mask);
     }
 # endif
 
@@ -478,11 +475,6 @@ virNetlinkDumpLink(const char *ifname, int ifindex,
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("malformed netlink response message"));
     return rc;
-
- buffer_too_small:
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("allocated netlink buffer is too small"));
-    return rc;
 }
 
 
@@ -528,36 +520,27 @@ virNetlinkNewLink(const char *ifname,
         return -1;
     }
 
-    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
-        goto buffer_too_small;
-
-    if (ifindex && nla_put_u32(nl_msg, IFLA_LINK, *ifindex) < 0)
-        goto buffer_too_small;
+    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nlmsg_append error"));
+        return -1;
+    }
 
-    if (data->mac && nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, data->mac) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_U32PTR(nl_msg, IFLA_LINK, ifindex);
+    NETLINK_MSG_PUT(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, data->mac);
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_IFNAME, ifname);
 
-    if (ifname && nla_put_string(nl_msg, IFLA_IFNAME, ifname) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_NEST_START(nl_msg, linkinfo, IFLA_LINKINFO);
 
-    if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO)))
-        goto buffer_too_small;
-
-    if (type && nla_put_string(nl_msg, IFLA_INFO_KIND, type) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_INFO_KIND, type);
 
     if ((STREQ(type, "macvtap") || STREQ(type, "macvlan")) &&
         data->macvlan_mode && *data->macvlan_mode > 0) {
-        if (!(infodata = nla_nest_start(nl_msg, IFLA_INFO_DATA)))
-            goto buffer_too_small;
-
-        if (nla_put_u32(nl_msg, IFLA_MACVLAN_MODE, *data->macvlan_mode) < 0)
-            goto buffer_too_small;
-
-        nla_nest_end(nl_msg, infodata);
+        NETLINK_MSG_NEST_START(nl_msg, infodata, IFLA_INFO_DATA);
+        NETLINK_MSG_PUT_U32PTR(nl_msg, IFLA_MACVLAN_MODE, data->macvlan_mode);
+        NETLINK_MSG_NEST_END(nl_msg, infodata);
     }
 
-    nla_nest_end(nl_msg, linkinfo);
+    NETLINK_MSG_NEST_END(nl_msg, linkinfo);
 
     if (virNetlinkCommand(nl_msg, &resp, &buflen, 0, 0, NETLINK_ROUTE, 0) < 0)
         return -1;
@@ -590,11 +573,6 @@ virNetlinkNewLink(const char *ifname,
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("malformed netlink response message"));
     return -1;
-
- buffer_too_small:
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("allocated netlink buffer is too small"));
-    return -1;
 }
 
 
@@ -629,11 +607,12 @@ virNetlinkDelLink(const char *ifname, virNetlinkDelLinkFallback fallback)
         return -1;
     }
 
-    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
-        goto buffer_too_small;
+    if (nlmsg_append(nl_msg,  &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nlmsg_append error"));
+        return -1;
+    }
 
-    if (ifname && nla_put_string(nl_msg, IFLA_IFNAME, ifname) < 0)
-        goto buffer_too_small;
+    NETLINK_MSG_PUT_STRING(nl_msg, IFLA_IFNAME, ifname);
 
     if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
                           NETLINK_ROUTE, 0) < 0) {
@@ -673,11 +652,6 @@ virNetlinkDelLink(const char *ifname, virNetlinkDelLinkFallback fallback)
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("malformed netlink response message"));
     return -1;
-
- buffer_too_small:
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("allocated netlink buffer is too small"));
-    return -1;
 }
 
 /**
diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h
index 8163a81..2e64570 100644
--- a/src/util/virnetlink.h
+++ b/src/util/virnetlink.h
@@ -48,6 +48,58 @@ struct nlmsghdr;
 
 # endif /* __linux__ */
 
+
+# define NETLINK_MSG_NEST_START(msg, container, attrtype) \
+do { \
+    container = nla_nest_start(msg, attrtype); \
+    if (!container) { \
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
+                       _("nla_nest_start error [" #attrtype "]")); \
+        return -1; \
+    } \
+} while(0)
+
+# define NETLINK_MSG_NEST_END(msg, container) \
+do { nla_nest_end(msg, container); } while(0)
+
+/*
+ * When data is an rvalue, compiler will report error as below:
+ * "the address of [...] will always evaluate as 'true' [-Werror=address]"
+ * Add a dummy(as an lvalue) to solve it.
+ */
+# define NETLINK_MSG_PUT(msg, attrtype, datalen, data) \
+do { \
+    const void *dummy = data; \
+    if (dummy && nla_put(msg, attrtype, datalen, data) < 0) { \
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
+                       _("nla_put error [" #attrtype "]")); \
+        return -1; \
+    } \
+} while(0)
+
+# define NETLINK_MSG_PUT_STRING(msg, attrtype, str) \
+do { \
+    const void *dummy = str; \
+    if (dummy && nla_put_string(msg, attrtype, str) < 0) { \
+        virReportError(VIR_ERR_INTERNAL_ERROR, \
+                       _("nla_put_string error [" #attrtype "]: '%s'"), \
+                       str); \
+        return -1; \
+    } \
+} while(0)
+
+# define NETLINK_MSG_PUT_U32PTR(msg, attrtype, ptr) \
+do { \
+    const void *dummy = ptr; \
+    if (dummy && nla_put_u32(msg, attrtype, *ptr) < 0) { \
+        virReportError(VIR_ERR_INTERNAL_ERROR, \
+                       _("nla_put_u32 error [" #attrtype "]: '%u'"), \
+                       *ptr); \
+        return -1; \
+    } \
+} while(0)
+
+
 int virNetlinkStartup(void);
 void virNetlinkShutdown(void);
 
-- 
2.17.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]

  Powered by Linux