From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Move the ifaceMacvtapLinkDump and ifaceGetNthParent functions into virnetdevvportprofile.c since they are specific to that code. This avoids polluting the headers with the Linux specific netlink data types * src/util/interface.c, src/util/interface.h: Move ifaceMacvtapLinkDump and ifaceGetNthParent functions and delete remaining file * src/util/virnetdevvportprofile.c: Add ifaceMacvtapLinkDump and ifaceGetNthParent functions * src/network/bridge_driver.c, src/nwfilter/nwfilter_gentech_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/util/virnetdevmacvlan.c: Remove include of interface.h --- po/POTFILES.in | 1 - src/Makefile.am | 1 - src/libvirt_private.syms | 2 - src/network/bridge_driver.c | 1 - src/nwfilter/nwfilter_gentech_driver.c | 2 +- src/nwfilter/nwfilter_learnipaddr.c | 1 - src/util/interface.c | 296 -------------------------------- src/util/interface.h | 41 ----- src/util/virnetdevmacvlan.c | 1 - src/util/virnetdevvportprofile.c | 199 +++++++++++++++++++++- 10 files changed, 195 insertions(+), 350 deletions(-) delete mode 100644 src/util/interface.c delete mode 100644 src/util/interface.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 6797298..403d94b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -112,7 +112,6 @@ src/util/hash.c src/util/hooks.c src/util/hostusb.c src/util/iohelper.c -src/util/interface.c src/util/iptables.c src/util/json.c src/util/netlink.c diff --git a/src/Makefile.am b/src/Makefile.am index e44c53a..f82be78 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,7 +72,6 @@ UTIL_SOURCES = \ util/pci.c util/pci.h \ util/processinfo.c util/processinfo.h \ util/hostusb.c util/hostusb.h \ - util/interface.c util/interface.h \ util/qparams.c util/qparams.h \ util/sexpr.c util/sexpr.h \ util/stats_linux.c util/stats_linux.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0189875..131d856 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -578,14 +578,12 @@ virHookPresent; virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; -ifaceGetNthParent; virNetDevGetPhysicalFunction; virNetDevGetVirtualFunctionIndex; virNetDevGetVLanID; virNetDevIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; -ifaceMacvtapLinkDump; virNetDevReplaceMacAddress; virNetDevRestoreMacAddress; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index f19bf51..7bea465 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -55,7 +55,6 @@ #include "memory.h" #include "uuid.h" #include "iptables.h" -#include "interface.h" #include "logging.h" #include "dnsmasq.h" #include "configmake.h" diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 9dffdc5..c9c1415 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -28,13 +28,13 @@ #include "memory.h" #include "logging.h" -#include "interface.h" #include "domain_conf.h" #include "virterror_internal.h" #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_learnipaddr.h" #include "virnetdev.h" +#include "datatypes.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 03716ea..1843c98 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -45,7 +45,6 @@ #include "memory.h" #include "logging.h" #include "datatypes.h" -#include "interface.h" #include "virnetdev.h" #include "virterror_internal.h" #include "threads.h" diff --git a/src/util/interface.c b/src/util/interface.c deleted file mode 100644 index 00a873e..0000000 --- a/src/util/interface.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * interface.c: interface support functions - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corp. - * Copyright (C) 2010 Stefan Berger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * chgIfaceFlags originated from bridge.c - * - * Author: Stefan Berger <stefanb@xxxxxxxxxx> - */ - -#include <config.h> - -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <netinet/in.h> - -#ifdef __linux__ -# include <linux/if.h> -# include <linux/sockios.h> -# include <linux/if_vlan.h> -#endif - -#include "internal.h" - -#include "util.h" -#include "interface.h" -#include "virterror_internal.h" -#include "virfile.h" -#include "memory.h" -#include "netlink.h" -#include "logging.h" -#include "virnetdev.h" - -#define VIR_FROM_THIS VIR_FROM_NET - -#define ifaceError(code, ...) \ - virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) - - -#if defined(__linux__) && defined(IFLA_PORT_MAX) - -static struct nla_policy ifla_policy[IFLA_MAX + 1] = -{ - [IFLA_VF_PORTS] = { .type = NLA_NESTED }, -}; - -/** - * ifaceMacvtapLinkDump - * - * @nltarget_kernel: whether to send the message to the kernel or another - * process - * @ifname: The name of the interface; only use if ifindex < 0 - * @ifindex: The interface index; may be < 0 if ifname is given - * @nlattr: pointer to a pointer of netlink attributes that will contain - * the results - * @recvbuf: Pointer to the buffer holding the returned netlink response - * message; free it, once not needed anymore - * @getPidFunc: Pointer to a function that will be invoked if the kernel - * is not the target of the netlink message but it is to be - * sent to another process. - * - * Get information about an interface given its name or index. - * - * Returns 0 on success, -1 on fatal error. - */ -int -ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, - struct nlattr **tb, unsigned char **recvbuf, - uint32_t (*getPidFunc)(void)) -{ - int rc = 0; - struct nlmsghdr *resp; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex - }; - unsigned int recvbuflen; - uint32_t pid = 0; - struct nl_msg *nl_msg; - - *recvbuf = NULL; - - nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); - if (!nl_msg) { - virReportOOMError(); - return -1; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (ifindex < 0 && ifname) { - if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - } - - if (!nltarget_kernel) { - pid = getPidFunc(); - if (pid == 0) { - rc = -1; - goto cleanup; - } - } - - if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) { - rc = -1; - goto cleanup; - } - - if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) - goto malformed_resp; - - resp = (struct nlmsghdr *)*recvbuf; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - if (err->error) { - virReportSystemError(-err->error, - _("error dumping %s (%d) interface"), - ifname, ifindex); - rc = -1; - } - break; - - case GENL_ID_CTRL: - case NLMSG_DONE: - if (nlmsg_parse(resp, sizeof(struct ifinfomsg), - tb, IFLA_MAX, ifla_policy)) { - goto malformed_resp; - } - break; - - default: - goto malformed_resp; - } - - if (rc != 0) - VIR_FREE(*recvbuf); - -cleanup: - nlmsg_free(nl_msg); - - return rc; - -malformed_resp: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - VIR_FREE(*recvbuf); - return -1; - -buffer_too_small: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - return -1; -} - -#else - -int -ifaceMacvtapLinkDump(bool nltarget_kernel ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - int ifindex ATTRIBUTE_UNUSED, - struct nlattr **tb ATTRIBUTE_UNUSED, - unsigned char **recvbuf ATTRIBUTE_UNUSED, - uint32_t (*getPidFunc)(void) ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !defined(IFLA_PORT_MAX) - _("ifaceMacvtapLinkDump is not supported since the include " - "files were too old")); -# else - _("ifaceMacvtapLinkDump is not supported on non-linux " - "platforms")); -# endif - - return -1; -} - -#endif - - -/** - * ifaceGetNthParent - * - * @ifindex : the index of the interface or -1 if ifname is given - * @ifname : the name of the interface; ignored if ifindex is valid - * @nthParent : the nth parent interface to get - * @parent_ifindex : pointer to int - * @parent_ifname : pointer to buffer of size IFNAMSIZ - * @nth : the nth parent that is actually returned; if for example eth0.100 - * was given and the 100th parent is to be returned, then eth0 will - * most likely be returned with nth set to 1 since the chain does - * not have more interfaces - * - * Get the nth parent interface of the given interface. 0 is the interface - * itself. - * - * Return 0 on success, < 0 otherwise - */ -#if defined(__linux__) && WITH_MACVTAP -int -ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, - int *parent_ifindex, char *parent_ifname, - unsigned int *nth) -{ - int rc; - struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; - unsigned char *recvbuf = NULL; - bool end = false; - unsigned int i = 0; - - *nth = 0; - - if (ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) - return -1; - - while (!end && i <= nthParent) { - rc = ifaceMacvtapLinkDump(true, ifname, ifindex, tb, &recvbuf, NULL); - if (rc < 0) - break; - - if (tb[IFLA_IFNAME]) { - if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]), - IFNAMSIZ)) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("buffer for root interface name is too small")); - VIR_FREE(recvbuf); - return -1; - } - *parent_ifindex = ifindex; - } - - if (tb[IFLA_LINK]) { - ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]); - ifname = NULL; - } else - end = true; - - VIR_FREE(recvbuf); - - i++; - } - - *nth = i - 1; - - return rc; -} - -#else - -int -ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - unsigned int nthParent ATTRIBUTE_UNUSED, - int *parent_ifindex ATTRIBUTE_UNUSED, - char *parent_ifname ATTRIBUTE_UNUSED, - unsigned int *nth ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !WITH_MACVTAP - _("ifaceGetNthParent is not supported since the include files " - "were too old")); -# else - _("ifaceGetNthParent is not supported on non-linux platforms")); -# endif - return -1; -} - -#endif diff --git a/src/util/interface.h b/src/util/interface.h deleted file mode 100644 index 141d19c..0000000 --- a/src/util/interface.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * interface.h: interface helper APIs for libvirt - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corporation, Inc. - * - * See COPYING.LIB for the License of this software - * - * Stefan Berger <stefanb@xxxxxxxxxx> - */ -#ifndef __VIR_INTERFACE_H__ -# define __VIR_INTERFACE_H__ - -# include <stdint.h> - -# if __linux__ - -# include <sys/socket.h> -# include <linux/netlink.h> - -# else - -struct nlattr; - -# endif - -# include "datatypes.h" -# include "virsocketaddr.h" - - -int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, - struct nlattr **tb, unsigned char **recvbuf, - uint32_t (*getPidFunc)(void)); - -int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, - int *parent_ifindex, char *parent_ifname, - unsigned int *nth) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) - ATTRIBUTE_NONNULL(6); - -#endif /* __VIR_INTERFACE_H__ */ diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index e3f90dd..fe2f383 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -64,7 +64,6 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, # include "memory.h" # include "logging.h" -# include "interface.h" # include "uuid.h" # include "virfile.h" # include "netlink.h" diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 9315281..8f7e5b9 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -58,7 +58,6 @@ VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, # include "netlink.h" # include "virfile.h" # include "memory.h" -# include "interface.h" # include "logging.h" # include "virnetdev.h" @@ -127,6 +126,10 @@ static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = { [IFLA_PORT_RESPONSE] = { .type = NLA_U16 }, }; +static struct nla_policy ifla_policy[IFLA_MAX + 1] = +{ + [IFLA_VF_PORTS] = { .type = NLA_NESTED }, +}; static uint32_t @@ -163,6 +166,125 @@ virNetDevVPortProfileGetLldpadPid(void) { /** + * virNetDevVPortProfileLinkDump: + * + * @ifname: The name of the interface; only use if ifindex < 0 + * @ifindex: The interface index; may be < 0 if ifname is given + * @nltarget_kernel: whether to send the message to the kernel or another + * process + * @nlattr: pointer to a pointer of netlink attributes that will contain + * the results + * @recvbuf: Pointer to the buffer holding the returned netlink response + * message; free it, once not needed anymore + * @getPidFunc: Pointer to a function that will be invoked if the kernel + * is not the target of the netlink message but it is to be + * sent to another process. + * + * Get information about an interface given its name or index. + * + * Returns 0 on success, -1 on fatal error. + */ +static int +virNetDevVPortProfileLinkDump(const char *ifname, int ifindex, bool nltarget_kernel, + struct nlattr **tb, unsigned char **recvbuf, + uint32_t (*getPidFunc)(void)) +{ + int rc = 0; + struct nlmsghdr *resp; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex + }; + unsigned int recvbuflen; + uint32_t pid = 0; + struct nl_msg *nl_msg; + + *recvbuf = NULL; + + nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); + if (!nl_msg) { + virReportOOMError(); + return -1; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (ifindex < 0 && ifname) { + if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + } + + if (!nltarget_kernel) { + pid = getPidFunc(); + if (pid == 0) { + rc = -1; + goto cleanup; + } + } + + if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) { + rc = -1; + goto cleanup; + } + + if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) + goto malformed_resp; + + resp = (struct nlmsghdr *)*recvbuf; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + if (err->error) { + virReportSystemError(-err->error, + _("error dumping %s (%d) interface"), + ifname, ifindex); + rc = -1; + } + break; + + case GENL_ID_CTRL: + case NLMSG_DONE: + if (nlmsg_parse(resp, sizeof(struct ifinfomsg), + tb, IFLA_MAX, ifla_policy)) { + goto malformed_resp; + } + break; + + default: + goto malformed_resp; + } + + if (rc != 0) + VIR_FREE(*recvbuf); + +cleanup: + nlmsg_free(nl_msg); + + return rc; + +malformed_resp: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + VIR_FREE(*recvbuf); + return -1; + +buffer_too_small: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + return -1; +} + +/** * virNetDevVPortProfileGetStatus: * * tb: top level netlink response attributes + values @@ -450,6 +572,73 @@ buffer_too_small: } +/** + * virNetDevVPortProfileGetNthParent + * + * @ifname : the name of the interface; ignored if ifindex is valid + * @ifindex : the index of the interface or -1 if ifname is given + * @nthParent : the nth parent interface to get + * @parent_ifindex : pointer to int + * @parent_ifname : pointer to buffer of size IFNAMSIZ + * @nth : the nth parent that is actually returned; if for example eth0.100 + * was given and the 100th parent is to be returned, then eth0 will + * most likely be returned with nth set to 1 since the chain does + * not have more interfaces + * + * Get the nth parent interface of the given interface. 0 is the interface + * itself. + * + * Return 0 on success, < 0 otherwise + */ +static int +virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int nthParent, + int *parent_ifindex, char *parent_ifname, + unsigned int *nth) +{ + int rc; + struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; + unsigned char *recvbuf = NULL; + bool end = false; + unsigned int i = 0; + + *nth = 0; + + if (ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) + return -1; + + while (!end && i <= nthParent) { + rc = virNetDevVPortProfileLinkDump(ifname, ifindex, true, tb, &recvbuf, NULL); + if (rc < 0) + break; + + if (tb[IFLA_IFNAME]) { + if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]), + IFNAMSIZ)) { + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("buffer for root interface name is too small")); + VIR_FREE(recvbuf); + return -1; + } + *parent_ifindex = ifindex; + } + + if (tb[IFLA_LINK]) { + ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]); + ifname = NULL; + } else + end = true; + + VIR_FREE(recvbuf); + + i++; + } + + *nth = i - 1; + + return rc; +} + + /* Returns 0 on success, -1 on general failure, and -2 on timeout */ static int virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, @@ -487,8 +676,8 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, } while (--repeats >= 0) { - rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb, - &recvbuf, virNetDevVPortProfileGetLldpadPid); + rc = virNetDevVPortProfileLinkDump(NULL, ifindex, nltarget_kernel, tb, + &recvbuf, virNetDevVPortProfileGetLldpadPid); if (rc < 0) goto err_exit; @@ -538,8 +727,8 @@ virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, ch *vlanid = -1; while (1) { - if ((ret = ifaceGetNthParent(ifindex, ifname, 1, - root_ifindex, root_ifname, &nth)) < 0) + if ((ret = virNetDevVPortProfileGetNthParent(ifname, ifindex, 1, + root_ifindex, root_ifname, &nth)) < 0) return ret; if (nth == 0) break; -- 1.7.6.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list