The Route information of the Linux VM needs to be used
by administrators and users when debugging network problems
and troubleshooting.
Signed-off-by: Dehan Meng <demeng@redhat.com>
---
qga/commands-posix.c | 78 ++++++++++++++++++++++++++++++++++++++++++
qga/commands-win32.c | 6 ++++
qga/qapi-schema.json | 80 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 164 insertions(+)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 6169bbf7a0..894cc43fce 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2747,6 +2747,78 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp)
return head;
}
+char *hexToIPAddress(unsigned int hexValue);
remove this declaration and make the function static,
similar to dev_major_minor
+
+char *hexToIPAddress(unsigned int hexValue)
+{
+ unsigned int byte1 = (hexValue >> 24) & 0xFF;
+ unsigned int byte2 = (hexValue >> 16) & 0xFF;
+ unsigned int byte3 = (hexValue >> 8) & 0xFF;
+ unsigned int byte4 = hexValue & 0xFF;
+
+ return g_strdup_printf("%u.%u.%u.%u", byte4, byte3, byte2, byte1);
+}
+
+GuestNetworkRouteList *qmp_guest_network_get_route(Error **errp)
+{
+ GuestNetworkRouteList *head = NULL, **tail = &head;
+ const char *routeFile = "/proc/net/route";
+ FILE *fp;
+ size_t n;
+ char *line = NULL;
+ int firstLine = 1;
+
+ fp = fopen(routeFile, "r");
+ if (fp == NULL) {
+ error_setg_errno(errp, errno, "open(\"%s\")", routeFile);
+ free(line);
+ return NULL;
+ }
+
+ while (getline(&line, &n, fp) != -1) {
+ if (firstLine) {
+ firstLine = 0;
+ continue;
+ }
+ GuestNetworkRoute *route = NULL;
+ GuestNetworkRouteStat *networkroute;
+ int i;
+ char Iface[16];
Use a define IFNAMSIZ from kernel instead of a hardcode
+ unsigned int Destination, Gateway, Mask, Flags;
+ int RefCnt, Use, Metric, MTU, Window, IRTT;
+
+ /* Parse the line and extract the values */
+ i = (sscanf(line, "%s %X %X %x %d %d %d %X %d %d %d",
+ Iface, &Destination, &Gateway, &Flags, &RefCnt,
+ &Use, &Metric, &Mask, &MTU, &Window, &IRTT) == 11);
+ if (i == EOF) {
+ continue;
+ }
+
+ route = g_new0(GuestNetworkRoute, 1);
+ route->type = GUEST_NETWORK_ROUTE_TYPE_LINUX;
I think we don't need it while flags, refcnt, etc are optional.
Just set FALSE in Windows.
+
+ networkroute = &route->u.q_linux;
+ networkroute->iface = g_strdup(Iface);
+ networkroute->destination = hexToIPAddress(Destination);
+ networkroute->gateway = hexToIPAddress(Gateway);
+ networkroute->mask = hexToIPAddress(Mask);
+ networkroute->metric = Metric;
+ networkroute->flags = Flags;
+ networkroute->refcnt = RefCnt;
+ networkroute->use = Use;
+ networkroute->mtu = MTU;
+ networkroute->window = Window;
+ networkroute->irtt = IRTT;
set networkroute->has_irtt = true, etc
for each optional field.
+
+ QAPI_LIST_APPEND(tail, route);
+ }
+
+ free(line);
+ fclose(fp);
+ return head;
+}
+
#else /* defined(__linux__) */
void qmp_guest_suspend_disk(Error **errp)
@@ -3118,6 +3190,12 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp)
return NULL;
}
+GuestNetworkRouteList *qmp_guest_network_get_route(Error **errp)
+{
+ error_setg(errp, QERR_UNSUPPORTED);
+ return NULL;
+}
+
#endif /* CONFIG_FSFREEZE */
#if !defined(CONFIG_FSTRIM)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 697c65507c..e62c04800a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -2522,3 +2522,9 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp)
error_setg(errp, QERR_UNSUPPORTED);
return NULL;
}
+
+GuestNetworkRouteList *qmp_guest_network_get_route(Error **errp)
+{
+ error_setg(errp, QERR_UNSUPPORTED);
+ return NULL;
+}
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 876e2a8ea8..eed9539bb7 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1789,3 +1789,83 @@
{ 'command': 'guest-get-cpustats',
'returns': ['GuestCpuStats']
}
+
+##
+# @GuestNetworkRouteType:
+#
+# An enumeration of OS type
+#
+# Since: 8.2
+##
+{ 'enum': 'GuestNetworkRouteType',
+ 'data': [ 'linux' ] }
+
no need for this enum,
GuestNetworkRouteStat is a generic and can be used in windows/linux
+##
+# @GuestNetworkRouteStat:
+#
+# Route information, currently, only linux supported.
+#
+# @iface: The destination network or host's egress network interface in the routing table
+#
+# @destination: The IP address of the target network or host, The final destination of the packet
+#
+# @gateway: The IP address of the next hop router
+#
+# @mask: Subnet Mask
+#
+# @metric: Route metric
+#
+# @flags: Route flags (not for windows)
+#
+# @irtt: Initial round-trip delay (not for windows)
+#
+# @refcnt: The route's reference count (not for windows)
+#
+# @use: Route usage count (not for windows)
+#
+# @window: TCP window size, used for flow control (not for windows)
+#
+# @mtu: Data link layer maximum packet size (not for windows)
+#
+# Since: 8.2
+
+##
+{ 'struct': 'GuestNetworkRouteStat',
+ 'data': {'iface': 'str',
+ 'destination': 'str',
+ 'gateway': 'str',
+ 'metric': 'int',
+ 'mask': 'str',
+ '*irtt': 'int',
+ '*flags': 'uint64',
+ '*refcnt': 'int',
+ '*use': 'int',
+ '*window': 'int',
+ '*mtu': 'int'
+ }}
+
+##
+# @GuestNetworkRoute:
+#
+# Get route information of system.
+#
+# - @linux: Linux style network route
+#
+# Since: 8.2
+##
+{ 'union': 'GuestNetworkRoute',
+ 'base': { 'type': 'GuestNetworkRouteType' },
+ 'discriminator': 'type',
+ 'data': { 'linux': 'GuestNetworkRouteStat' } }
+
+##
+# @guest-network-get-route:
+#
+# Retrieve information about route of network.
+# Returns: List of route info of guest.
+#
+# Since: 8.2
+##
+{ 'command': 'guest-network-get-route',
+ 'returns': ['GuestNetworkRoute']
+}
--
2.35.1