From: Tony Krowiak <akrowiak(a)linux.vnet.ibm.com>
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 <akrowiak(a)linux.vnet.ibm.com>
---
Changes for v3:
* Fixed a syntax-check error in virNetDevGetRxFilter function
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 a2eec83..8d76f9b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1639,13 +1639,16 @@ virNetDevGetIPv4Address;
virNetDevGetLinkInfo;
virNetDevGetMAC;
virNetDevGetMTU;
+virNetDevGetOnline;
virNetDevGetPhysicalFunction;
+virNetDevGetPromiscuous;
+virNetDevGetRcvAllMulti;
+virNetDevGetRcvMulti;
virNetDevGetRxFilter;
virNetDevGetVirtualFunctionIndex;
virNetDevGetVirtualFunctionInfo;
virNetDevGetVirtualFunctions;
virNetDevGetVLanID;
-virNetDevIsOnline;
virNetDevIsVirtualFunction;
virNetDevLinkDump;
virNetDevReplaceMacAddress;
@@ -1663,6 +1666,9 @@ virNetDevSetMTUFromDevice;
virNetDevSetName;
virNetDevSetNamespace;
virNetDevSetOnline;
+virNetDevSetPromiscuous;
+virNetDevSetRcvAllMulti;
+virNetDevSetRcvMulti;
virNetDevSetupControl;
virNetDevValidateConfig;
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index ef96b2b..5d330ce 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'"),
@@ -717,6 +768,70 @@ int virNetDevIsOnline(const char *ifname,
/**
+ * 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
* @ifindex: Pointer to int where the index will be written into
@@ -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 fb7988f..8d03459 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__ */
--
1.7.1