[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