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

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@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; }
participants (1)
-
Stefan Berger