From e562a61a07398411c7aa6d92cbd8c64117b151f2 Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Thu, 22 Jan 2015 14:47:02 -0500 Subject: [PATCH] util: Functions for getting/setting device options This patch provides the utility functions needed to synchronize the rxfilter changes made to a guest domain with the corresponding macvtap devices on the host: * Get/set PROMISC flag * Get/set ALLMULTI, MULTICAST Signed-off-by: Tony Krowiak Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 8 +- src/util/virnetdev.c | 186 +++++++++++++++++++++++++++++++++------ src/util/virnetdev.h | 24 ++++- 3 files changed, 190 insertions(+), 28 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bd7870f6a9..db60813566 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1647,13 +1647,16 @@ virNetDevGetIPv4Address; virNetDevGetLinkInfo; virNetDevGetMAC; virNetDevGetMTU; +virNetDevGetOnline; virNetDevGetPhysicalFunction; +virNetDevGetPromiscuous; +virNetDevGetRcvAllMulti; +virNetDevGetRcvMulti; virNetDevGetRxFilter; virNetDevGetVirtualFunctionIndex; virNetDevGetVirtualFunctionInfo; virNetDevGetVirtualFunctions; virNetDevGetVLanID; -virNetDevIsOnline; virNetDevIsVirtualFunction; virNetDevLinkDump; virNetDevReplaceMacAddress; @@ -1671,6 +1674,9 @@ virNetDevSetMTUFromDevice; virNetDevSetName; virNetDevSetNamespace; virNetDevSetOnline; +virNetDevSetPromiscuous; +virNetDevSetRcvAllMulti; +virNetDevSetRcvMulti; virNetDevSetupControl; virNetDevValidateConfig; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index ef96b2ba4c..7a0a43df1b 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -610,17 +610,7 @@ int virNetDevSetName(const char* ifname, const char *newifname) #if defined(SIOCSIFFLAGS) && defined(HAVE_STRUCT_IFREQ) -/** - * virNetDevSetOnline: - * @ifname: the interface name - * @online: true for up, false for down - * - * Function to control if an interface is activated (up, true) or not (down, false) - * - * Returns 0 in case of success or -1 on error. - */ -int virNetDevSetOnline(const char *ifname, - bool online) +int virNetDevSetIFFlag(const char *ifname, int flag, bool val) { int fd = -1; int ret = -1; @@ -637,10 +627,10 @@ int virNetDevSetOnline(const char *ifname, goto cleanup; } - if (online) - ifflags = ifr.ifr_flags | IFF_UP; + if (val) + ifflags = ifr.ifr_flags | flag; else - ifflags = ifr.ifr_flags & ~IFF_UP; + ifflags = ifr.ifr_flags & ~flag; if (ifr.ifr_flags != ifflags) { ifr.ifr_flags = ifflags; @@ -659,8 +649,9 @@ int virNetDevSetOnline(const char *ifname, return ret; } #else -int virNetDevSetOnline(const char *ifname, - bool online ATTRIBUTE_UNUSED) +int virNetDevSetIFFlag(const char *ifname, + int flag ATTRIBUTE_UNUSED, + bool val ATTRIBUTE_UNUSED) { virReportSystemError(ENOSYS, _("Cannot set interface flags on '%s'"), @@ -670,18 +661,77 @@ int virNetDevSetOnline(const char *ifname, #endif -#if defined(SIOCGIFFLAGS) && defined(HAVE_STRUCT_IFREQ) + /** - * virNetDevIsOnline: + * virNetDevSetOnline: * @ifname: the interface name - * @online: where to store the status + * @online: true for up, false for down * - * Function to query if an interface is activated (true) or not (false) + * Function to control if an interface is activated (up, true) or not (down, false) * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on error. */ -int virNetDevIsOnline(const char *ifname, - bool *online) +int virNetDevSetOnline(const char *ifname, + bool online) +{ + + return virNetDevSetIFFlag(ifname, IFF_UP, online); +} + +/** + * virNetDevSetPromiscuous: + * @ifname: the interface name + * @promiscuous: true for receive all packets, false for do not receive + * all packets + * + * Function to control if an interface is to receive all + * packets (receive all, true) or not (do not receive all, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevSetPromiscuous(const char *ifname, + bool promiscuous) +{ + return virNetDevSetIFFlag(ifname, IFF_PROMISC, promiscuous); +} + +/** + * virNetDevSetRcvMulti: + * @ifname: the interface name + * @:receive true for receive multicast packets, false for do not receive + * multicast packets + * + * Function to control if an interface is to receive multicast + * packets in which it is interested (receive, true) + * or not (do not receive, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevSetRcvMulti(const char *ifname, + bool receive) +{ + return virNetDevSetIFFlag(ifname, IFF_MULTICAST, receive); +} + +/** + * virNetDevSetRcvAllMulti: + * @ifname: the interface name + * @:receive true for receive all packets, false for do not receive all packets + * + * Function to control if an interface is to receive all multicast + * packets (receive, true) or not (do not receive, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevSetRcvAllMulti(const char *ifname, + bool receive) +{ + return virNetDevSetIFFlag(ifname, IFF_ALLMULTI, receive); +} + + +#if defined(SIOCGIFFLAGS) && defined(HAVE_STRUCT_IFREQ) +int virNetDevGetIFFlag(const char *ifname, int flag, bool *val) { int fd = -1; int ret = -1; @@ -697,7 +747,7 @@ int virNetDevIsOnline(const char *ifname, goto cleanup; } - *online = (ifr.ifr_flags & IFF_UP) ? true : false; + *val = (ifr.ifr_flags & flag) ? true : false; ret = 0; cleanup: @@ -705,8 +755,9 @@ int virNetDevIsOnline(const char *ifname, return ret; } #else -int virNetDevIsOnline(const char *ifname, - bool *online ATTRIBUTE_UNUSED) +int virNetDevGetIFFlag(const char *ifname, + int flag ATTRIBUTE_UNUSED, + bool *val ATTRIBUTE_UNUSED) { virReportSystemError(ENOSYS, _("Cannot get interface flags on '%s'"), @@ -716,6 +767,70 @@ int virNetDevIsOnline(const char *ifname, #endif +/** + * virNetDevGetOnline: + * @ifname: the interface name + * @online: where to store the status + * + * Function to query if an interface is activated (true) or not (false) + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevGetOnline(const char *ifname, + bool *online) +{ + return virNetDevGetIFFlag(ifname, IFF_UP, online); +} + +/** + * virNetDevIsPromiscuous: + * @ifname: the interface name + * @promiscuous: where to store the status + * + * Function to query if an interface is receiving all packets (true) or + * not (false) + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevGetPromiscuous(const char *ifname, + bool *promiscuous) +{ + return virNetDevGetIFFlag(ifname, IFF_PROMISC, promiscuous); +} + +/** + * virNetDevIsRcvMulti: + * @ifname: the interface name + * @receive where to store the status + * + * Function to query whether an interface is receiving multicast packets (true) + * in which it is interested, or not (false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevGetRcvMulti(const char *ifname, + bool *receive) +{ + return virNetDevGetIFFlag(ifname, IFF_MULTICAST, receive); +} + +/** + * virNetDevIsRcvAllMulti: + * @ifname: the interface name + * @:receive where to store the status + * + * Function to query whether an interface is receiving all multicast + * packets (receiving, true) or not (is not receiving, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevGetRcvAllMulti(const char *ifname, + bool *receive) +{ + return virNetDevGetIFFlag(ifname, IFF_ALLMULTI, receive); +} + + /** * virNetDevGetIndex: * @ifname : Name of the interface whose index is to be found @@ -2549,6 +2664,7 @@ int virNetDevGetRxFilter(const char *ifname, virNetDevRxFilterPtr *filter) { int ret = -1; + bool receive; virNetDevRxFilterPtr fil = virNetDevRxFilterNew(); if (!fil) @@ -2560,6 +2676,24 @@ int virNetDevGetRxFilter(const char *ifname, if (virNetDevGetMulticastTable(ifname, fil)) goto cleanup; + if (virNetDevGetPromiscuous(ifname, &fil->promiscuous)) + goto cleanup; + + if (virNetDevGetRcvAllMulti(ifname, &receive)) + goto cleanup; + + if (receive) { + fil->multicast.mode = VIR_NETDEV_RX_FILTER_MODE_ALL; + } else { + if (virNetDevGetRcvMulti(ifname, &receive)) + goto cleanup; + + if (receive) + fil->multicast.mode = VIR_NETDEV_RX_FILTER_MODE_NORMAL; + else + fil->multicast.mode = VIR_NETDEV_RX_FILTER_MODE_NONE; + } + ret = 0; cleanup: if (ret < 0) { diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index fb7988f330..8d0345911f 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -83,7 +83,7 @@ int virNetDevExists(const char *brname) int virNetDevSetOnline(const char *ifname, bool online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevIsOnline(const char *ifname, +int virNetDevGetOnline(const char *ifname, bool *online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; @@ -200,4 +200,26 @@ int virNetDevDelMulti(const char *ifname, virMacAddrPtr macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetIFFlag(const char *ifname, int flag, bool val) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevGetIFFlag(const char *ifname, int flag, bool *val) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetPromiscuous(const char *ifname, bool promiscuous) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetPromiscuous(const char *ifname, bool *promiscuous) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetRcvMulti(const char *ifname, bool receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetRcvMulti(const char *ifname, bool *receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetRcvAllMulti(const char *ifname, bool receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetRcvAllMulti(const char *ifname, bool *receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; #endif /* __VIR_NETDEV_H__ */