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(a)massclouds.com>
---
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