/*********************************************************
- * Copyright (C) 2002-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 2002-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#define CONFNAME_GUESTINFO_EXCLUDENICS "exclude-nics"
+/**
+ * Define a custom max IPv4 routes to gather.
+ *
+ * @note Illegal values result in a @c g_warning and fallback to the default
+ * NICINFO_MAX_ROUTES.
+ *
+ * @param int User-defined max routes with range [0, NICINFO_MAX_ROUTES].
+ * Set to 0 to disable gathering.
+ */
+#define CONFNAME_GUESTINFO_MAXIPV4ROUTES "max-ipv4-routes"
+
+/**
+ * Define a custom max IPv6 routes to gather.
+ *
+ * @note Illegal values result in a @c g_warning and fallback to the default
+ * NICINFO_MAX_ROUTES.
+ *
+ * @param int User-defined max routes with range [0, NICINFO_MAX_ROUTES].
+ * Set to 0 to disable gathering.
+ */
+#define CONFNAME_GUESTINFO_MAXIPV6ROUTES "max-ipv6-routes"
+
/**
* Lets user include reserved space in diskInfo space metrics on Linux.
*
/*********************************************************
- * Copyright (C) 2014-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
} NicInfoPriority;
Bool GuestInfo_GetFqdn(int outBufLen, char fqdn[]);
-Bool GuestInfo_GetNicInfo(NicInfoV3 **nicInfo);
+Bool GuestInfo_GetNicInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 **nicInfo);
void GuestInfo_FreeNicInfo(NicInfoV3 *nicInfo);
char *GuestInfo_GetPrimaryIP(void);
/*********************************************************
- * Copyright (C) 2009-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
EXTERN GHashTable *SlashProcNet_GetSnmp(void);
EXTERN GHashTable *SlashProcNet_GetSnmp6(void);
-EXTERN GPtrArray *SlashProcNet_GetRoute(void);
+EXTERN GPtrArray *SlashProcNet_GetRoute(unsigned int, unsigned short);
EXTERN void SlashProcNet_FreeRoute(GPtrArray *);
-EXTERN GPtrArray *SlashProcNet_GetRoute6(void);
+EXTERN GPtrArray *SlashProcNet_GetRoute6(unsigned int, unsigned int);
EXTERN void SlashProcNet_FreeRoute6(GPtrArray *);
#endif // ifndef _SLASHPROC_H_
/*********************************************************
- * Copyright (C) 2014-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
*
* @brief Returns guest networking configuration (and some runtime state).
*
- * @param[out] nicInfo Will point to a newly allocated NicInfo.
+ * @param[in] maxIPv4Routes Max IPv4 routes to gather.
+ * @param[in] maxIPv6Routes Max IPv6 routes to gather.
+ * @param[out] nicInfo Will point to a newly allocated NicInfo.
*
* @note
* Caller is responsible for freeing @a nicInfo with GuestInfo_FreeNicInfo.
*/
Bool
-GuestInfo_GetNicInfo(NicInfoV3 **nicInfo)
+GuestInfo_GetNicInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 **nicInfo)
{
Bool retval = FALSE;
*nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3));
- retval = GuestInfoGetNicInfo(*nicInfo);
+ retval = GuestInfoGetNicInfo(maxIPv4Routes, maxIPv6Routes, *nicInfo);
if (!retval) {
GuestInfo_FreeNicInfo(*nicInfo);
*nicInfo = NULL;
/*********************************************************
- * Copyright (C) 2014-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#endif
Bool GuestInfoGetFqdn(int outBufLen, char fqdn[]);
-Bool GuestInfoGetNicInfo(NicInfoV3 *nicInfo);
+Bool GuestInfoGetNicInfo(unsigned int maxIPv4Routes, // IN
+ unsigned int maxIPv6Routes, // IN
+ NicInfoV3 *nicInfo); // OUT
GuestNicV3 *GuestInfoAddNicEntry(NicInfoV3 *nicInfo, // IN/OUT
const char macAddress[NICINFO_MAC_LEN], // IN
/*********************************************************
- * Copyright (C) 2014-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
void *arg);
static int ReadInterfaceDetailsLowPriority(const struct intf_entry *entry,
void *arg);
-static Bool RecordRoutingInfo(NicInfoV3 *nicInfo);
+static Bool RecordRoutingInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 *nicInfo);
#if !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(USERWORLD)
typedef struct GuestInfoIpPriority {
#endif
-static Bool RecordRoutingInfo(NicInfoV3 *nicInfo);
+static Bool RecordRoutingInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 *nicInfo);
static char *ValidateConvertAddress(const struct sockaddr *addr);
******************************************************************************
* GuestInfoGetNicInfo -- */ /**
*
+ * @param[in] maxIPv4Routes Max IPv4 routes to gather.
+ * @param[in] maxIPv6Routes Max IPv6 routes to gather.
+ * @param[out] nicInfo NicInfoV3 container.
+ *
* @copydoc GuestInfo_GetNicInfo
*
******************************************************************************
*/
-Bool GuestInfoGetNicInfo(NicInfoV3 *nicInfo) // OUT
+Bool
+GuestInfoGetNicInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 *nicInfo)
{
#ifndef NO_DNET
intf_t *intf;
}
#endif
- if (!RecordRoutingInfo(nicInfo)) {
+ if ((maxIPv4Routes > 0 || maxIPv6Routes > 0) &&
+ !RecordRoutingInfo(maxIPv4Routes, maxIPv6Routes, nicInfo)) {
return FALSE;
}
}
#endif
- if (!RecordRoutingInfo(nicInfo)) {
+ if ((maxIPv4Routes > 0 || maxIPv6Routes > 0) &&
+ !RecordRoutingInfo(maxIPv4Routes, maxIPv6Routes, nicInfo)) {
return FALSE;
}
return TRUE;
#else
- RecordRoutingInfo(nicInfo);
+ (void)maxIPv4Routes;
+ (void)maxIPv6Routes;
+ (void)nicInfo;
return FALSE;
#endif
* @brief Query the IPv4 routing subsystem and pack up contents
* (struct rtentry) into InetCidrRouteEntries.
*
- * @param[out] nicInfo NicInfoV3 container.
+ * @param[in] maxRoutes Max routes to gather.
+ * @param[out] nicInfo NicInfoV3 container.
*
* @note Do not call this routine without first populating @a nicInfo 's NIC
* list.
*/
static Bool
-RecordRoutingInfoIPv4(NicInfoV3 *nicInfo)
+RecordRoutingInfoIPv4(unsigned int maxRoutes,
+ NicInfoV3 *nicInfo)
{
GPtrArray *routes = NULL;
guint i;
Bool ret = FALSE;
- if ((routes = SlashProcNet_GetRoute()) == NULL) {
+ ASSERT(maxRoutes > 0);
+
+ if ((routes = SlashProcNet_GetRoute(maxRoutes, RTF_UP)) == NULL) {
return FALSE;
}
rtentry = g_ptr_array_index(routes, i);
- if ((rtentry->rt_flags & RTF_UP) == 0 ||
- !GuestInfoGetNicInfoIfIndex(nicInfo,
+ if (!GuestInfoGetNicInfoIfIndex(nicInfo,
if_nametoindex(rtentry->rt_dev),
&ifIndex)) {
continue;
* @brief Query the IPv6 routing subsystem and pack up contents
* (struct in6_rtmsg) into InetCidrRouteEntries.
*
- * @param[out] nicInfo NicInfoV3 container.
+ * @param[in] maxRoutes Max routes to gather.
+ * @param[out] nicInfo NicInfoV3 container.
*
* @note Do not call this routine without first populating @a nicInfo 's NIC
* list.
*/
static Bool
-RecordRoutingInfoIPv6(NicInfoV3 *nicInfo)
+RecordRoutingInfoIPv6(unsigned int maxRoutes,
+ NicInfoV3 *nicInfo)
{
GPtrArray *routes = NULL;
guint i;
Bool ret = FALSE;
- if ((routes = SlashProcNet_GetRoute6()) == NULL) {
+ ASSERT(maxRoutes > 0);
+
+ /*
+ * Reading large number of ipv6 routes in pathToNetRoute6 could
+ * result in performance issue because:
+ * 1. IPv6 route table is not efficient natively compared to ipv4
+ * because of its implementation.
+ * 2. The glib I/O channel can aggravate the performace.
+ * Considering bug 605821/2064541, we try to read the first maxRoutes
+ * lines of pathToNetRoute6 with route flag RTF_UP set.
+ */
+ if ((routes = SlashProcNet_GetRoute6(maxRoutes, RTF_UP)) == NULL) {
return FALSE;
}
in6_rtmsg = g_ptr_array_index(routes, i);
- if ((in6_rtmsg->rtmsg_flags & RTF_UP) == 0 ||
- !GuestInfoGetNicInfoIfIndex(nicInfo, in6_rtmsg->rtmsg_ifindex,
+ if (!GuestInfoGetNicInfoIfIndex(nicInfo, in6_rtmsg->rtmsg_ifindex,
&ifIndex)) {
continue;
}
* @brief Query the routing subsystem and pack up contents into
* InetCidrRouteEntries when either of IPv4 or IPV6 is configured.
*
- * @param[out] nicInfo NicInfoV3 container.
+ * @param[in] maxIPv4Routes Max IPv4 routes to gather.
+ Set 0 to disable gathering.
+ * @param[in] maxIPv6Routes Max IPv6 routes to gather.
+ Set 0 to disable gathering.
+ * @param[out] nicInfo NicInfoV3 container.
*
* @note Do not call this routine without first populating @a nicInfo 's NIC
* list.
*/
static Bool
-RecordRoutingInfo(NicInfoV3 *nicInfo)
+RecordRoutingInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 *nicInfo)
{
- Bool retIPv4 = TRUE;
- Bool retIPv6 = TRUE;
+ Bool retIPv4 = FALSE;
+ Bool retIPv6 = FALSE;
+
+ ASSERT(maxIPv4Routes > 0 || maxIPv6Routes > 0);
- if (File_Exists("/proc/net/route") && !RecordRoutingInfoIPv4(nicInfo)) {
- g_warning("%s: Unable to collect IPv4 routing table.\n", __func__);
- retIPv4 = FALSE;
+ /*
+ * We gather IPv4 routes first, then IPv6. This means IPv4 routes are more
+ * prioritized than IPv6. When there's more than NICINFO_MAX_ROUTES IPv4
+ * routes in system, the IPv6 routes will be ignored. A more equitable
+ * design might be getting max IPv4 and IPv6 routes first, and then pick
+ * out the head NICINFO_MAX_ROUTES/2 of each route list.
+ */
+ if (maxIPv4Routes > 0) {
+ if (RecordRoutingInfoIPv4(maxIPv4Routes, nicInfo)) {
+ retIPv4 = TRUE;
+ } else {
+ g_warning("%s: Unable to collect IPv4 routing table.\n", __func__);
+ }
}
- if (File_Exists("/proc/net/ipv6_route") && !RecordRoutingInfoIPv6(nicInfo)) {
- g_warning("%s: Unable to collect IPv6 routing table.\n", __func__);
- retIPv6 = FALSE;
+ if (maxIPv6Routes > 0 && nicInfo->routes.routes_len < NICINFO_MAX_ROUTES) {
+ if (RecordRoutingInfoIPv6(maxIPv6Routes, nicInfo)) {
+ retIPv6 = TRUE;
+ } else {
+ g_warning("%s: Unable to collect IPv6 routing table.\n", __func__);
+ }
}
return (retIPv4 || retIPv6);
#else // ifdef USE_SLASH_PROC
static Bool
-RecordRoutingInfo(NicInfoV3 *nicInfo)
+RecordRoutingInfo(unsigned int maxIPv4Routes,
+ unsigned int maxIPv6Routes,
+ NicInfoV3 *nicInfo)
{
return TRUE;
}
/*********************************************************
- * Copyright (C) 2009-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
******************************************************************************
* SlashProcNet_GetRoute -- */ /**
*
- * @brief Reads @ref pathToNetRoute and returns a @c GPtrArray of
- * <tt>struct rtentry</tt>s.
+ * @brief Reads the first @c maxRoutes lines of @ref pathToNetRoute and
+ * returns a @c GPtrArray of <tt>struct rtentry</tt>s.
*
* Example usage:
* @code
* GPtrArray *rtArray;
* guint i;
- * rtArray = SlashProcNet_GetRoute();
+ * rtArray = SlashProcNet_GetRoute(NICINFO_MAX_ROUTES, RTF_UP);
* for (i = 0; i < rtArray->len; i++) {
* struct rtentry *myRoute = g_ptr_array_index(rtArray, i);
* // Do something with myRoute->rt_dst.
* SlashProcNet_FreeRoute.
* @note This routine creates persistent GLib GRegexs.
*
+ * @param[in] maxRoutes Max routes to gather.
+ * @param[in] rtFilterFlags Route flags used to filter out what we want.
+ * Set ~0 if want everything.
+ *
* @return On failure, NULL. On success, a valid @c GPtrArray.
* @todo Consider init/cleanup routines to not "leak" GRegexs.
* @todo Consider rewriting, integrating with libdnet.
*/
GPtrArray *
-SlashProcNet_GetRoute(void)
+SlashProcNet_GetRoute(unsigned int maxRoutes,
+ unsigned short rtFilterFlags)
{
GIOChannel *myChannel = NULL;
GIOStatus myIoStatus;
GPtrArray *myArray = NULL;
gchar *myLine = NULL;
int fd = -1;
+ unsigned int lineCount = 0;
static GRegex *myFieldsRE = NULL;
static GRegex *myValuesRE = NULL;
+ ASSERT(maxRoutes > 0);
+
if (myFieldsRE == NULL) {
myFieldsRE = g_regex_new("^Iface\\s+Destination\\s+Gateway\\s+Flags\\s+"
"RefCnt\\s+Use\\s+Metric\\s+Mask\\s+MTU\\s+"
* 3. For each line...
*/
- while ((myIoStatus = g_io_channel_read_line(myChannel, &myLine, NULL, NULL,
- NULL)) == G_IO_STATUS_NORMAL) {
+ while (lineCount < maxRoutes &&
+ (myIoStatus = g_io_channel_read_line(myChannel,
+ &myLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) {
GMatchInfo *myMatchInfo = NULL;
struct rtentry *myEntry = NULL;
struct sockaddr_in *sin = NULL;
*/
if (!g_regex_match(myValuesRE, myLine, 0, &myMatchInfo)) {
parseError = TRUE;
- goto badIteration;
+ goto iterationCleanup;
}
/*
* code path.
*/
myEntry = g_new0(struct rtentry, 1);
- g_ptr_array_add(myArray, myEntry);
/*
* 3c. Copy contents to new struct rtentry.
myEntry->rt_mtu = MatchToGuint64(myMatchInfo, 7, 10);
myEntry->rt_irtt = MatchToGuint64(myMatchInfo, 8, 10);
-badIteration:
+ if (rtFilterFlags == (unsigned short)~0 ||
+ (myEntry->rt_flags & rtFilterFlags) != 0) {
+ g_ptr_array_add(myArray, myEntry);
+ lineCount++;
+ } else {
+ g_free(myEntry->rt_dev);
+ g_free(myEntry);
+ }
+
+iterationCleanup:
g_free(myLine);
myLine = NULL;
myMatchInfo = NULL;
if (parseError) {
+ /* Return NULL to signal parsing error */
+ if (myArray) {
+ SlashProcNet_FreeRoute(myArray);
+ myArray = NULL;
+ }
break;
}
}
- if (myArray && myIoStatus != G_IO_STATUS_EOF) {
- SlashProcNet_FreeRoute(myArray);
- myArray = NULL;
- }
-
out:
g_free(myLine);
close(fd);
******************************************************************************
* SlashProcNet_GetRoute6 -- */ /**
*
- * @brief Reads @ref pathToNetRoute6 and returns a @c GPtrArray of
- * <tt>struct in6_rtmsg</tt>s.
+ * @brief Reads the first @c maxRoutes lines of @ref pathToNetRoute6 and
+ * returns a @c GPtrArray of <tt>struct in6_rtmsg</tt>s.
*
* Example usage:
* @code
* GPtrArray *rtArray;
* guint i;
- * rtArray = SlashProcNet_GetRoute6();
+ * rtArray = SlashProcNet_GetRoute6(NICINFO_MAX_ROUTES, RTF_UP);
* for (i = 0; i < rtArray->len; i++) {
* struct in6_rtmsg *myRoute = g_ptr_array_index(rtArray, i);
* // Do something with myRoute->rtmsg_dst.
* }
- * SlashProcNet_FreeRoute6(rtArray, TRUE);
+ * SlashProcNet_FreeRoute6(rtArray);
* @endcode
*
* @note Caller is responsible for freeing the @c GPtrArray with
* SlashProcNet_FreeRoute6.
* @note This routine creates persistent GLib GRegexs.
*
+ * @param[in] maxRoutes Max routes to gather.
+ * @param[in] rtFilterFlags Route flags used to filter out what we want.
+ * Set ~0 if want everything.
+ *
* @return On failure, NULL. On success, a valid @c GPtrArray.
* @todo Consider init/cleanup routines to not "leak" GRegexs.
* @todo Consider rewriting, integrating with libdnet.
*/
GPtrArray *
-SlashProcNet_GetRoute6(void)
+SlashProcNet_GetRoute6(unsigned int maxRoutes,
+ unsigned int rtFilterFlags)
{
GIOChannel *myChannel = NULL;
GIOStatus myIoStatus;
gchar *myLine = NULL;
Bool parseError = FALSE;
int fd = -1;
+ unsigned int lineCount = 0;
static GRegex *myValuesRE = NULL;
+ ASSERT(maxRoutes > 0);
+
if (myValuesRE == NULL) {
myValuesRE = g_regex_new("^([[:xdigit:]]{32}) ([[:xdigit:]]{2}) "
"([[:xdigit:]]{32}) ([[:xdigit:]]{2}) "
*/
if ((fd = g_open(pathToNetRoute6, O_RDONLY)) == -1) {
- Warning("%s: open(%s): %s\n", __func__, pathToNetRoute,
+ Warning("%s: open(%s): %s\n", __func__, pathToNetRoute6,
g_strerror(errno));
return NULL;
}
myArray = g_ptr_array_new();
- while ((myIoStatus = g_io_channel_read_line(myChannel, &myLine, NULL, NULL,
- NULL)) == G_IO_STATUS_NORMAL) {
+ while (lineCount < maxRoutes &&
+ (myIoStatus = g_io_channel_read_line(myChannel,
+ &myLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) {
struct in6_rtmsg *myEntry = NULL;
GMatchInfo *myMatchInfo = NULL;
if (!g_regex_match(myValuesRE, myLine, 0, &myMatchInfo)) {
parseError = TRUE;
- goto badIteration;
+ goto iterationCleanup;
}
myEntry = g_new0(struct in6_rtmsg, 1);
- g_ptr_array_add(myArray, myEntry);
MATCHEXPR(myMatchInfo, 1, Ip6StringToIn6Addr(MATCH, &myEntry->rtmsg_dst));
MATCHEXPR(myMatchInfo, 3, Ip6StringToIn6Addr(MATCH, &myEntry->rtmsg_src));
MATCHEXPR(myMatchInfo, 8, myEntry->rtmsg_ifindex = if_nametoindex(MATCH));
-badIteration:
+ if (rtFilterFlags == (uint)~0 ||
+ (myEntry->rtmsg_flags & rtFilterFlags) != 0) {
+ g_ptr_array_add(myArray, myEntry);
+ lineCount++;
+ } else {
+ g_free(myEntry);
+ }
+
+iterationCleanup:
g_free(myLine);
myLine = NULL;
myMatchInfo = NULL;
if (parseError) {
+ /* Return NULL to signal parsing error */
+ if (myArray) {
+ SlashProcNet_FreeRoute6(myArray);
+ myArray = NULL;
+ }
break;
}
}
- if (myArray && myIoStatus != G_IO_STATUS_EOF) {
- SlashProcNet_FreeRoute6(myArray);
- myArray = NULL;
- }
-
g_free(myLine);
myLine = NULL;
ToolsAppCtx *ctx = data;
Bool primaryChanged;
Bool lowPriorityChanged;
+ int maxIPv4RoutesToGather;
+ int maxIPv6RoutesToGather;
g_debug("Entered guest info gather.\n");
lowPriorityChanged = GuestInfoResetNicLowPriorityList(ctx);
GuestInfoResetNicExcludeList(ctx);
- if (!GuestInfo_GetNicInfo(&nicInfo)) {
+ /*
+ * Check the config registry for max IPv4/6 routes to gather
+ */
+ maxIPv4RoutesToGather =
+ VMTools_ConfigGetInteger(ctx->config,
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV4ROUTES,
+ NICINFO_MAX_ROUTES);
+ if (maxIPv4RoutesToGather < 0 ||
+ maxIPv4RoutesToGather > NICINFO_MAX_ROUTES) {
+ g_warning("Invalid %s.%s value: %d. Using default %u.\n",
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV4ROUTES,
+ maxIPv4RoutesToGather,
+ NICINFO_MAX_ROUTES);
+ maxIPv4RoutesToGather = NICINFO_MAX_ROUTES;
+ }
+
+ maxIPv6RoutesToGather =
+ VMTools_ConfigGetInteger(ctx->config,
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV6ROUTES,
+ NICINFO_MAX_ROUTES);
+ if (maxIPv6RoutesToGather < 0 ||
+ maxIPv6RoutesToGather > NICINFO_MAX_ROUTES) {
+ g_warning("Invalid %s.%s value: %d. Using default %u.\n",
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV6ROUTES,
+ maxIPv6RoutesToGather,
+ NICINFO_MAX_ROUTES);
+ maxIPv6RoutesToGather = NICINFO_MAX_ROUTES;
+ }
+
+ if (!GuestInfo_GetNicInfo(maxIPv4RoutesToGather,
+ maxIPv6RoutesToGather,
+ &nicInfo)) {
g_warning("Failed to get nic info.\n");
/*
* Return an empty nic info.
/*********************************************************
- * Copyright (C) 2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2015-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
GuestNicProto msg = { 0 };
GuestInfoType type = INFO_IPADDRESS_V3;
+ GKeyFile *confDict = NULL;
+ int maxIPv4RoutesToGather = NICINFO_MAX_ROUTES;
+ int maxIPv6RoutesToGather = NICINFO_MAX_ROUTES;
+
#ifdef _WIN32
DWORD dwRet = NetUtil_LoadIpHlpApiDll();
if (dwRet != ERROR_SUCCESS) {
- g_warning("NetUtil_LoadIpHlpApiDll() failed\n");
+ g_warning("NetUtil_LoadIpHlpApiDll() failed.\n");
return EXIT_FAILURE;
}
#endif
- if (!GuestInfo_GetNicInfo(&info)) {
- g_warning("Failed to get nic info\n");
+ // Get the config options of max IPv4/IPv6 routes to gather
+ VMTools_LoadConfig(NULL, G_KEY_FILE_NONE, &confDict, NULL);
+
+ if (confDict != NULL) {
+ maxIPv4RoutesToGather =
+ VMTools_ConfigGetInteger(confDict,
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV4ROUTES,
+ NICINFO_MAX_ROUTES);
+ if (maxIPv4RoutesToGather < 0 ||
+ maxIPv4RoutesToGather > NICINFO_MAX_ROUTES) {
+ g_warning("Invalid %s.%s value: %d. Using default %u.\n",
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV4ROUTES,
+ maxIPv4RoutesToGather,
+ NICINFO_MAX_ROUTES);
+ maxIPv4RoutesToGather = NICINFO_MAX_ROUTES;
+ }
+
+ maxIPv6RoutesToGather =
+ VMTools_ConfigGetInteger(confDict,
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV6ROUTES,
+ NICINFO_MAX_ROUTES);
+ if (maxIPv6RoutesToGather < 0 ||
+ maxIPv6RoutesToGather > NICINFO_MAX_ROUTES) {
+ g_warning("Invalid %s.%s value: %d. Using default %u.\n",
+ CONFGROUPNAME_GUESTINFO,
+ CONFNAME_GUESTINFO_MAXIPV6ROUTES,
+ maxIPv6RoutesToGather,
+ NICINFO_MAX_ROUTES);
+ maxIPv6RoutesToGather = NICINFO_MAX_ROUTES;
+ }
+ g_key_file_free(confDict);
+ }
+
+ if (!GuestInfo_GetNicInfo(maxIPv4RoutesToGather,
+ maxIPv6RoutesToGather,
+ &info)) {
+ g_warning("Failed to get nic info.\n");
ret = EXIT_FAILURE;
goto done;
}