From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:52 +0000 (-0700) Subject: GuestInfo: Add option to exclude network interfaces X-Git-Tag: stable-10.2.0~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad4f5db55d031ce7d1b75ddc64c3f046c24469de;p=thirdparty%2Fopen-vm-tools.git GuestInfo: Add option to exclude network interfaces VMs running docker can have hundred of virtual network interfaces. Also, docker creates one virtual network interface 'docker0' with an IPv4 address. This address is useless outside the VM, and should not be propagated via GuestInfo, or even as the primary network address. This change adds on option for tools.conf to exclude specific network interface names using patterns with wildcards. This makes it easy to exclude virtual docker interface names with the option exclude-nics=docker*,veth* For convenience, the option is set to docker*,veth* by default, except for Windows, where it is "vEthernet*". To send information of all interfaces, including docker* and veth*, the option needs to be set to an empty value: exclude-nics= --- diff --git a/open-vm-tools/lib/include/conf.h b/open-vm-tools/lib/include/conf.h index 5813c956b..d6da7e339 100644 --- a/open-vm-tools/lib/include/conf.h +++ b/open-vm-tools/lib/include/conf.h @@ -103,6 +103,16 @@ */ #define CONFNAME_GUESTINFO_ENABLESTATLOGGING "enable-stat-logging" +/** + * Set a comma separated list of network interface names that shall be ignored. + * + * @note interface names can use wildcards like '*' and '?' + * + * @param string comma separated list of interface name patterns. + */ + +#define CONFNAME_GUESTINFO_EXCLUDENICS "exclude-nics" + /* * END GuestInfo goodies. ****************************************************************************** diff --git a/open-vm-tools/lib/include/nicInfo.h b/open-vm-tools/lib/include/nicInfo.h index 6d116e519..506d15461 100644 --- a/open-vm-tools/lib/include/nicInfo.h +++ b/open-vm-tools/lib/include/nicInfo.h @@ -74,4 +74,8 @@ Bool GuestInfo_IsEqual_WinsConfigInfo(const WinsConfigInfo *a, const WinsConfigInfo *b); +void GuestInfo_SetIfaceExcludeList(char **list); + +Bool GuestInfo_IfaceIsExcluded(const char *name); + #endif diff --git a/open-vm-tools/lib/nicInfo/nicInfo.c b/open-vm-tools/lib/nicInfo/nicInfo.c index 9975dec60..88aab30dd 100644 --- a/open-vm-tools/lib/nicInfo/nicInfo.c +++ b/open-vm-tools/lib/nicInfo/nicInfo.c @@ -38,6 +38,7 @@ #include "netutil.h" #include "wiper.h" +GPtrArray *gIfaceExcludePatterns = NULL; /** * Helper to initialize an opaque struct member. @@ -57,6 +58,72 @@ static void * Util_DupeThis(const void *source, size_t sourceSize); * Global functions. */ +/* + ****************************************************************************** + * + * GuestInfo_SetIfaceExcludeList -- + * + * @brief Set list of network interfaces to be ignored. + * + * @param[in] NULL terminated array of pointers to strings with patterns + * + * @sa gIfaceExcludePatterns will be set + * + ****************************************************************************** + */ + +void +GuestInfo_SetIfaceExcludeList(char **list) +{ + guint i; + + if (gIfaceExcludePatterns != NULL) { + g_ptr_array_free(gIfaceExcludePatterns, TRUE); + gIfaceExcludePatterns = NULL; + } + + if (list != NULL) { + gIfaceExcludePatterns = + g_ptr_array_new_with_free_func((GDestroyNotify) &g_pattern_spec_free); + for (i = 0; list[i] != NULL; i++) { + if (list[i][0] != '\0') { + g_ptr_array_add(gIfaceExcludePatterns, g_pattern_spec_new(list[i])); + } + } + } +} + +/* + ****************************************************************************** + * + * GuestInfo_IfaceIsExcluded -- + * + * @brief Determine if a specific interface name shall be excluded. + * + * @param[in] The interface name. + * + * @retval TRUE if interface name shall be excluded. + * + ****************************************************************************** +*/ + +Bool +GuestInfo_IfaceIsExcluded(const char *name) +{ + int i; + + if (gIfaceExcludePatterns != NULL && name != NULL) { + for(i = 0; i < gIfaceExcludePatterns->len; i++) { + if (g_pattern_match_string(g_ptr_array_index(gIfaceExcludePatterns, i), + name)) { + g_debug("%s: excluding interface %s because it matched pattern %d", + __FUNCTION__, name, i); + return TRUE; + } + } + } + return FALSE; +} /* ****************************************************************************** diff --git a/open-vm-tools/lib/nicInfo/nicInfoPosix.c b/open-vm-tools/lib/nicInfo/nicInfoPosix.c index bc862f2e5..f00083226 100644 --- a/open-vm-tools/lib/nicInfo/nicInfoPosix.c +++ b/open-vm-tools/lib/nicInfo/nicInfoPosix.c @@ -273,6 +273,11 @@ GuestInfoGetNicInfo(NicInfoV3 *nicInfo) // OUT GuestNicV3 *nic; struct ifaddrs *ip; struct sockaddr_ll *sll = (struct sockaddr_ll *)pkt->ifa_addr; + + if (GuestInfo_IfaceIsExcluded(pkt->ifa_name)) { + continue; + } + if (sll != NULL && sll->sll_family == AF_PACKET) { char macAddress[NICINFO_MAC_LEN]; Str_Sprintf(macAddress, sizeof macAddress, @@ -383,6 +388,8 @@ GuestInfoGetPrimaryIP(void) if (!(curr->ifa_flags & IFF_UP) || curr->ifa_flags & IFF_LOOPBACK) { continue; + } else if (GuestInfo_IfaceIsExcluded(curr->ifa_name)) { + continue; } else if (currFamily == AF_INET || currFamily == AF_INET6) { ipstr = ValidateConvertAddress(curr->ifa_addr); } else { @@ -504,6 +511,11 @@ ReadInterfaceDetails(const struct intf_entry *entry, // IN: current interface e if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH) { Str_Sprintf(macAddress, sizeof macAddress, "%s", addr_ntoa(&entry->intf_link_addr)); + + if (GuestInfo_IfaceIsExcluded(entry->intf_name)) { + return 0; + } + nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL); if (NULL == nic) { /* @@ -977,6 +989,10 @@ GuestInfoGetIntf(const struct intf_entry *entry, // IN: struct sockaddr_storage ss; struct sockaddr *saddr = (struct sockaddr *)&ss; + if (GuestInfo_IfaceIsExcluded(entry->intf_name)) { + return 0; + } + memset(&ss, 0, sizeof ss); addr_ntos(&entry->intf_addr, saddr); *ipstr = ValidateConvertAddress(saddr); diff --git a/open-vm-tools/libvmtools/vmtoolsConfig.c b/open-vm-tools/libvmtools/vmtoolsConfig.c index 36bcff7cc..874580703 100644 --- a/open-vm-tools/libvmtools/vmtoolsConfig.c +++ b/open-vm-tools/libvmtools/vmtoolsConfig.c @@ -621,7 +621,9 @@ VMTools_ConfigGetInteger(GKeyFile *config, * @param[in] section Section to look for in the config file. * @param[in] defValue Default value if the key is not found or error. * - * @return value of the key if value was read successfully, else defValue. + * @return value of the key if value was read successfully, else a copy + * of defValue unless defValue is NULL, in which case it's NULL. + * The returned string should be freed with g_free() when no longer needed. */ gchar * @@ -646,7 +648,7 @@ VMTools_ConfigGetString(GKeyFile *config, } g_debug("%s: Returning default value for '[%s] %s'=%s.\n", __FUNCTION__, section, key, defValue ? defValue : "(null)"); - value = defValue; + value = g_strdup(defValue); g_clear_error(&err); } return value; diff --git a/open-vm-tools/services/plugins/guestInfo/guestInfoServer.c b/open-vm-tools/services/plugins/guestInfo/guestInfoServer.c index e0f128a2e..4c473e65d 100644 --- a/open-vm-tools/services/plugins/guestInfo/guestInfoServer.c +++ b/open-vm-tools/services/plugins/guestInfo/guestInfoServer.c @@ -85,6 +85,15 @@ VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #define GUESTINFO_DEFAULT_DELIMITER ' ' +/** + * The default setting for exclude-nics + */ +#if defined(_WIN32) +#define GUESTINFO_DEFAULT_IFACE_EXCLUDES "vEthernet*" +#else +#define GUESTINFO_DEFAULT_IFACE_EXCLUDES "docker*,veth*" +#endif + /* * Define what guest info types and nic info versions could be sent * to update nic info at VMX. The order defines a sequence of fallback @@ -309,6 +318,40 @@ GuestInfoCheckIfRunningSlow(ToolsAppCtx *ctx) } +/* + ****************************************************************************** + * GuestInfoSetNicExcludeList -- */ /** + * + * Gets exclude-nics setting from the config, and sets the list of exclude + * patterns. + * + * @param[in] ctx The application context. + * + ****************************************************************************** + */ + +static void +GuestInfoSetNicExcludeList(ToolsAppCtx *ctx) +{ + static gchar *ifaceExcludeStringCached = NULL; + gchar *ifaceExcludeString; + + /* Check if we want to exclude interfaces based on the name. */ + ifaceExcludeString = VMTools_ConfigGetString(ctx->config, CONFGROUPNAME_GUESTINFO, + CONFNAME_GUESTINFO_EXCLUDENICS, + GUESTINFO_DEFAULT_IFACE_EXCLUDES); + if (g_strcmp0(ifaceExcludeString, ifaceExcludeStringCached) != 0) { + gchar **list = NULL; + if (ifaceExcludeString != NULL && ifaceExcludeString[0] != '\0') { + list = g_strsplit(ifaceExcludeString, ",", 0); + } + g_free(ifaceExcludeStringCached); + ifaceExcludeStringCached = ifaceExcludeString; + GuestInfo_SetIfaceExcludeList(list); + g_strfreev(list); + } +} + /* ****************************************************************************** * GuestInfoGather -- */ /** @@ -396,6 +439,9 @@ GuestInfoGather(gpointer data) } /* Get NIC information. */ + + GuestInfoSetNicExcludeList(ctx); + if (!GuestInfo_GetNicInfo(&nicInfo)) { g_warning("Failed to get nic info.\n"); /* @@ -1529,6 +1575,8 @@ GuestInfoServerShutdown(gpointer src, { GuestInfoClearCache(); + GuestInfo_SetIfaceExcludeList(NULL); + if (gatherInfoTimeoutSource != NULL) { g_source_destroy(gatherInfoTimeoutSource); gatherInfoTimeoutSource = NULL;