qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] net: Add "info neighbors" command


From: Patrick Venture
Subject: Re: [PATCH] net: Add "info neighbors" command
Date: Thu, 2 Sep 2021 15:08:43 -0700



On Thu, Sep 2, 2021 at 2:21 PM Doug Evans <dje@google.com> wrote:
This command dumps the ARP and NDP tables maintained within slirp.
One use-case for it is showing the guest's IPv6 address(es).

Signed-off-by: Doug Evans <dje@google.com>
Reviewed-by: Patrick Venture <venture@google.com
---
 hmp-commands-info.hx               | 15 +++++++
 include/net/slirp.h                |  1 +
 net/slirp.c                        | 15 +++++++
 tests/acceptance/info_neighbors.py | 69 ++++++++++++++++++++++++++++++
 4 files changed, 100 insertions(+)
 create mode 100644 tests/acceptance/info_neighbors.py

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 27206ac049..386f09f163 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -512,6 +512,21 @@ SRST
     Show user network stack connection states.
 ERST

+#if defined(CONFIG_SLIRP)
+    {
+        .name       = "neighbors",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show the ARP and NDP tables",
+        .cmd        = hmp_info_neighbors,
+    },
+#endif
+
+SRST
+  ``info neighbors``
+    Show the ARP and NDP tables.
+ERST
+
     {
         .name       = "migrate",
         .args_type  = "",
diff --git a/include/net/slirp.h b/include/net/slirp.h
index bad3e1e241..b9ccfda1e7 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -31,6 +31,7 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
 void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);

 void hmp_info_usernet(Monitor *mon, const QDict *qdict);
+void hmp_info_neighbors(Monitor *mon, const QDict *qdict);

 #endif

diff --git a/net/slirp.c b/net/slirp.c
index ad3a838e0b..29a4cd3fe1 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -1028,6 +1028,21 @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
     }
 }

+void hmp_info_neighbors(Monitor *mon, const QDict *qdict)
+{
+    SlirpState *s;
+
+    QTAILQ_FOREACH(s, &slirp_stacks, entry) {
+        int id;
+        bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
+        char *info = slirp_neighbor_info(s->slirp);
+        monitor_printf(mon, "Hub %d (%s):\n%s",
+                       got_hub_id ? id : -1,
+                       s->nc.name, info);
+        g_free(info);
+    }
+}
+
 static void
 net_init_slirp_configs(const StringList *fwd, int flags)
 {
diff --git a/tests/acceptance/info_neighbors.py b/tests/acceptance/info_neighbors.py
new file mode 100644
index 0000000000..ff79ec3ff3
--- /dev/null
+++ b/tests/acceptance/info_neighbors.py
@@ -0,0 +1,69 @@
+# Test for the hmp command "info neighbors"
+#
+# Copyright 2021 Google LLC
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+import re
+
+from avocado_qemu import LinuxTest
+from avocado_qemu import Test
+
+VNET_HUB_HEADER = 'Hub -1 (vnet):'
+NEIGHBOR_HEADER_REGEX = '^ *Table *MacAddr *IP Address$'
+
+def trim(text):
+    return " ".join(text.split())
+
+def hmc(test, cmd):
+    return test.vm.command('human-monitor-command', command_line=cmd)
+
+def get_neighbors(test):
+    output = hmc(test, 'info neighbors').splitlines()
+    if len(output) < 2:
+        test.fail("Insufficient output from 'info neighbors'")
+    test.assertEquals(output[0], VNET_HUB_HEADER)
+    test.assertTrue(re.fullmatch(NEIGHBOR_HEADER_REGEX, output[1]))
+    return output[2:]
+
+class InfoNeighborsNone(Test):
+
+    def test_no_neighbors(self):
+        self.vm.add_args('-nodefaults',
+                         '-netdev', 'user,id=vnet',
+                         '-device', 'virtio-net,netdev=vnet')
+        self.vm.launch()
+        neighbors = get_neighbors(self)
+        self.assertEquals(len(neighbors), 0)
+
+class InfoNeighbors(LinuxTest):
+
+    def test_neighbors(self):
+        """
+        :avocado: tags=arch:x86_64
+        :avocado: tags=machine:pc
+        :avocado: tags=accel:kvm
+        """
+        self.require_accelerator('kvm')
+        self.vm.add_args("-accel", "kvm")
+        self.vm.add_args('-nographic',
+                         '-m', '1024')
+        self.launch_and_wait()
+
+        # Ensure there's some packets to the guest and back.
+        self.ssh_command('pwd')
+
+        # We should now be aware of the guest as a neighbor.
+        expected_ipv4_neighbor = 'ARP 52:54:00:12:34:56 10.0.2.15'
+        # The default ipv6 net is fec0. Both fe80 and fec0 can appear.
+        expected_ipv6_neighbors = [
+            'NDP 52:54:00:12:34:56 fe80::5054:ff:fe12:3456',
+            'NDP 52:54:00:12:34:56 fec0::5054:ff:fe12:3456'
+        ]
+        neighbors = get_neighbors(self)
+        self.assertTrue(len(neighbors) >= 2 and len(neighbors) <= 3)
+        # IPv4 is output first.
+        self.assertEquals(trim(neighbors[0]), expected_ipv4_neighbor)
+        for neighbor in neighbors[1:]:
+            self.assertTrue(trim(neighbor) in expected_ipv6_neighbors)
--
2.33.0.153.gba50c8fa24-goog



reply via email to

[Prev in Thread] Current Thread [Next in Thread]