All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM test: Add support for ipv6 addresses
@ 2010-02-24  4:10 Lucas Meneghel Rodrigues
  2010-02-24  4:16 ` [Autotest] " Lucas Meneghel Rodrigues
  0 siblings, 1 reply; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-02-24  4:10 UTC (permalink / raw)
  To: autotest; +Cc: Yogananth Subramanian, kvm

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]


This patch enables ipv6 address support in kvm-autotest.
The patch adds a new dictionary called "address6_cache" for ip6 address.
Tcpdump is used to create this cache of link-local ipv6 address.

Link-local ipv6 address is used because it eliminates to need to create
complex configuration on both the host and the guest.

The ipv6 address for a guest can be obtained by using the new function
get_address6 in kvm_vm.py

Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
---
 client/tests/kvm/kvm_preprocessing.py |   29 ++++++++++++++++++-
 client/tests/kvm/kvm_utils.py         |   28 +++++++++++++++++++
 client/tests/kvm/kvm_vm.py            |   49 +++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 5 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-KVM-test-Add-support-for-ipv6-addresses.patch --]
[-- Type: text/x-patch; name="0001-KVM-test-Add-support-for-ipv6-addresses.patch", Size: 8891 bytes --]

diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py
index e91d1da..4ea13b2 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -51,7 +51,8 @@ def preprocess_vm(test, params, env, name):
         logging.debug("VM object found in environment")
     else:
         logging.debug("VM object does not exist; creating it")
-        vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache"))
+        vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache"),
+                       env.get("address6_cache"))
         kvm_utils.env_register_vm(env, name, vm)
 
     start_vm = False
@@ -199,6 +200,14 @@ def preprocess(test, params, env):
             command=command,
             output_func=_update_address_cache,
             output_params=(env["address_cache"],))
+
+        env["address6_cache"] = {}
+        command6 = "/usr/sbin/tcpdump -npv ip6 -i any 'dst net ff02::2'"
+        env["tcpdump6"] = kvm_subprocess.kvm_tail(
+            command=command6,
+            output_func=_update_address6_cache,
+            output_params=(env["address6_cache"],))
+
         if kvm_utils.wait_for(lambda: not env["tcpdump"].is_alive(),
                               0.1, 0.1, 1.0):
             logging.warn("Could not start tcpdump")
@@ -321,6 +330,8 @@ def postprocess(test, params, env):
     if not living_vms and env.has_key("tcpdump"):
         env["tcpdump"].close()
         del env["tcpdump"]
+        env["tcpdump6"].close()
+        del env["tcpdump6"]
 
 
 def postprocess_on_error(test, params, env):
@@ -343,7 +354,21 @@ def _update_address_cache(address_cache, line):
         matches = re.findall(r"\w*:\w*:\w*:\w*:\w*:\w*", line)
         if matches and address_cache.get("last_seen"):
             mac_address = matches[0].lower()
-            logging.debug("(address cache) Adding cache entry: %s ---> %s",
+            logging.debug("(address cache ipv4) Adding cache entry: %s ---> %s",
                           mac_address, address_cache.get("last_seen"))
             address_cache[mac_address] = address_cache.get("last_seen")
             del address_cache["last_seen"]
+
+def _update_address6_cache(address6_cache, line):
+    if re.search("ff02::2:", line, re.IGNORECASE):
+        matches = re.findall(r"(fe80.+) >", line)
+        if matches:
+            address6_cache["last_seen"] = matches[0]
+    if re.search("source link-address option", line, re.IGNORECASE):
+        matches = re.findall(r"\w*:\w*:\w*:\w*:\w*:\w*", line)
+        if matches and address6_cache.get("last_seen"):
+            mac_address = matches[0].lower()
+            logging.debug("(address cache ipv6) Adding cache entry: %s ---> %s",
+                          mac_address, address6_cache.get("last_seen"))
+            address6_cache[mac_address] = address6_cache.get("last_seen")
+            del address6_cache["last_seen"]
diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 4565dc1..a574520 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -208,6 +208,34 @@ def verify_ip_address_ownership(ip, macs, timeout=10.0):
     o = commands.getoutput("/sbin/arping -f -c 3 -I %s %s" % (dev, ip))
     return bool(regex.search(o))
 
+def verify_ip6_address_ownership(ip, macs, timeout=10.0):
+    """
+    Use ping6 and the ND cache to make sure a given IP address belongs to one
+    of the given MAC addresses.
+
+    @param ip: An IP6 address.
+    @param macs: A list or tuple of MAC addresses.
+    @return: True iff ip is assigned to a MAC address in macs.
+    """
+    # Compile a regex that matches the given IP6 address and any of the given
+    # MAC addresses
+    mac_regex = "|".join("(%s)" % mac for mac in macs)
+    regex = re.compile(r"\b%s\b.*\b(%s)\b" % (ip, mac_regex), re.IGNORECASE)
+
+    # Get the name of the bridge device for ping6
+    o = commands.getoutput("/sbin/ip route get ff02::1" )
+    dev = re.findall("dev\s+\S+", o, re.IGNORECASE)
+    if not dev:
+        return False
+    dev = dev[0].split()[-1]
+
+    if bool(commands.getstatusoutput("/bin/ping6 -c 11 -I %s %s"% (dev, ip)[0])):
+        return False
+
+    # Check the ND cache
+    o = commands.getoutput("/sbin/ip -6 neigh show")
+    if regex.search(o):
+        return True
 
 # Functions for working with the environment (a dict-like object)
 
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 921414d..76babd4 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -95,7 +95,7 @@ class VM:
     This class handles all basic VM operations.
     """
 
-    def __init__(self, name, params, root_dir, address_cache):
+    def __init__(self, name, params, root_dir, address_cache, address6_cache):
         """
         Initialize the object and set a few attributes.
 
@@ -104,6 +104,7 @@ class VM:
                 (see method make_qemu_command for a full description)
         @param root_dir: Base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
+        @param address_cache: A dict that maps MAC addresses to IP6 addresses
         """
         self.process = None
         self.redirs = {}
@@ -114,6 +115,7 @@ class VM:
         self.params = params
         self.root_dir = root_dir
         self.address_cache = address_cache
+        self.address6_cache = address6_cache
         self.pci_assignable = None
 
         # Find available monitor filename
@@ -127,7 +129,8 @@ class VM:
                 break
 
 
-    def clone(self, name=None, params=None, root_dir=None, address_cache=None):
+    def clone(self, name=None, params=None, root_dir=None, address_cache=None,
+              address6_cache=None):
         """
         Return a clone of the VM object with optionally modified parameters.
         The clone is initially not alive and needs to be started using create().
@@ -138,6 +141,7 @@ class VM:
         @param params: Optional new VM creation parameters
         @param root_dir: Optional new base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
+        @param address_cache: A dict that maps MAC addresses to IP6 addresses
         """
         if name is None:
             name = self.name
@@ -147,7 +151,9 @@ class VM:
             root_dir = self.root_dir
         if address_cache is None:
             address_cache = self.address_cache
-        return VM(name, params, root_dir, address_cache)
+        if address6_cache is None:
+            address6_cache = self.address6_cache
+        return VM(name, params, root_dir, address_cache, address6_cache)
 
 
     def make_qemu_command(self, name=None, params=None, root_dir=None):
@@ -720,6 +726,43 @@ class VM:
         else:
             return "localhost"
 
+    def get_address6(self, index=0):
+        """
+        Return the address of a NIC of the guest, in host space.
+
+        If port redirection is used, return 'localhost' (the NIC has no IP
+        address of its own).  Otherwise return the NIC's IP6 address.
+
+        @param index: Index of the NIC whose address is requested.
+        """
+        nics = kvm_utils.get_sub_dict_names(self.params, "nics")
+        nic_name = nics[index]
+        nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
+        if nic_params.get("nic_mode") == "tap":
+            mac, ip = kvm_utils.get_mac_ip_pair_from_dict(nic_params)
+            if not mac:
+                logging.debug("MAC address unavailable")
+                return None
+            if not ip or nic_params.get("always_use_tcpdump") == "yes":
+                # Get the IP6 address from the cache
+                ip = self.address6_cache.get(mac)
+                if not ip:
+                    logging.debug("Could not find IP address for MAC address: "
+                                  "%s" % mac)
+                    return None
+                # Make sure the IP6 address is assigned to this guest
+                nic_dicts = [kvm_utils.get_sub_dict(self.params, nic)
+                             for nic in nics]
+                macs = [kvm_utils.get_mac_ip_pair_from_dict(dict)[0]
+                        for dict in nic_dicts]
+                if not kvm_utils.verify_ip6_address_ownership(ip, macs):
+                    logging.debug("Could not verify MAC-IP address mapping: "
+                                  "%s ---> %s" % (mac, ip))
+                    return None
+            return ip
+        else:
+            return "localhost"
+
 
     def get_port(self, port, nic_index=0):
         """

[-- Attachment #3: Type: text/plain, Size: 152 bytes --]

_______________________________________________
Autotest mailing list
Autotest@test.kernel.org
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Autotest] [PATCH] KVM test: Add support for ipv6 addresses
  2010-02-24  4:10 [PATCH] KVM test: Add support for ipv6 addresses Lucas Meneghel Rodrigues
@ 2010-02-24  4:16 ` Lucas Meneghel Rodrigues
  2010-02-25 13:41   ` yogi
  0 siblings, 1 reply; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-02-24  4:16 UTC (permalink / raw)
  To: autotest; +Cc: Yogananth Subramanian, kvm

H i Yogi, I have read and rebased your patch against current trunk. I
have one doubt: I noticed that the tcpdump command you use to monitor
traffic is basically all traffic that goes to network routers

/usr/sbin/tcpdump -npv ip6 -i any 'dst net ff02::2'

However, the IPv4 implementation filters the traffic to the dhcp/bootp
port, 68. Therefore the ipv6 mapper captures more (non necessarily
useful) mappings than the ipv4 version. I made some brief research and
couldn't figure out how to do it. Do you think it's possible to refine
the tcpdump command to make it look only on the dhp request port (68)?

On Wed, Feb 24, 2010 at 1:10 AM, Lucas Meneghel Rodrigues
<lmr@redhat.com> wrote:
>
> This patch enables ipv6 address support in kvm-autotest.
> The patch adds a new dictionary called "address6_cache" for ip6 address.
> Tcpdump is used to create this cache of link-local ipv6 address.
>
> Link-local ipv6 address is used because it eliminates to need to create
> complex configuration on both the host and the guest.
>
> The ipv6 address for a guest can be obtained by using the new function
> get_address6 in kvm_vm.py
>
> Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
> ---
>  client/tests/kvm/kvm_preprocessing.py |   29 ++++++++++++++++++-
>  client/tests/kvm/kvm_utils.py         |   28 +++++++++++++++++++
>  client/tests/kvm/kvm_vm.py            |   49 +++++++++++++++++++++++++++++++--
>  3 files changed, 101 insertions(+), 5 deletions(-)
>
>
> _______________________________________________
> Autotest mailing list
> Autotest@test.kernel.org
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>
>



-- 
Lucas

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Autotest] [PATCH] KVM test: Add support for ipv6 addresses
  2010-02-24  4:16 ` [Autotest] " Lucas Meneghel Rodrigues
@ 2010-02-25 13:41   ` yogi
  2010-02-25 20:09     ` Lucas Meneghel Rodrigues
  0 siblings, 1 reply; 5+ messages in thread
From: yogi @ 2010-02-25 13:41 UTC (permalink / raw)
  To: Lucas Meneghel Rodrigues; +Cc: autotest, kvm, Yogananth Subramanian

On Wed, 2010-02-24 at 01:16 -0300, Lucas Meneghel Rodrigues wrote:
> H i Yogi, I have read and rebased your patch against current trunk. I
> have one doubt: I noticed that the tcpdump command you use to monitor
> traffic is basically all traffic that goes to network routers
> 
> /usr/sbin/tcpdump -npv ip6 -i any 'dst net ff02::2'
> 
> However, the IPv4 implementation filters the traffic to the dhcp/bootp
> port, 68. Therefore the ipv6 mapper captures more (non necessarily
> useful) mappings than the ipv4 version. I made some brief research and
> couldn't figure out how to do it. Do you think it's possible to refine
> the tcpdump command to make it look only on the dhp request port (68)?
> 

Hello Lucas, thanks for reviewing my patches for ipv6.
Following tcpdump command will capture only the icmp6 packets and not
all the ipv6 packets
tcpdump -npv -i any icmp6 and 'dst net ff02::2'

Since the patch uses ip6 link local address, we are looking for router
solicitation messages.
Thanks
Yogi
> On Wed, Feb 24, 2010 at 1:10 AM, Lucas Meneghel Rodrigues
> <lmr@redhat.com> wrote:
> >
> > This patch enables ipv6 address support in kvm-autotest.
> > The patch adds a new dictionary called "address6_cache" for ip6 address.
> > Tcpdump is used to create this cache of link-local ipv6 address.
> >
> > Link-local ipv6 address is used because it eliminates to need to create
> > complex configuration on both the host and the guest.
> >
> > The ipv6 address for a guest can be obtained by using the new function
> > get_address6 in kvm_vm.py
> >
> > Signed-off-by: Yogananth Subramanian <anantyog@in.ibm.com>
> > ---
> >  client/tests/kvm/kvm_preprocessing.py |   29 ++++++++++++++++++-
> >  client/tests/kvm/kvm_utils.py         |   28 +++++++++++++++++++
> >  client/tests/kvm/kvm_vm.py            |   49 +++++++++++++++++++++++++++++++--
> >  3 files changed, 101 insertions(+), 5 deletions(-)
> >
> >
> > _______________________________________________
> > Autotest mailing list
> > Autotest@test.kernel.org
> > http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
> >
> >
> 
> 
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Autotest] [PATCH] KVM test: Add support for ipv6 addresses
  2010-02-25 13:41   ` yogi
@ 2010-02-25 20:09     ` Lucas Meneghel Rodrigues
  2010-03-02 15:02       ` yogi
  0 siblings, 1 reply; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2010-02-25 20:09 UTC (permalink / raw)
  To: yogi; +Cc: autotest, kvm, Yogananth Subramanian

On Thu, 2010-02-25 at 19:11 +0530, yogi wrote:
> On Wed, 2010-02-24 at 01:16 -0300, Lucas Meneghel Rodrigues wrote:
> > H i Yogi, I have read and rebased your patch against current trunk. I
> > have one doubt: I noticed that the tcpdump command you use to monitor
> > traffic is basically all traffic that goes to network routers
> > 
> > /usr/sbin/tcpdump -npv ip6 -i any 'dst net ff02::2'
> > 
> > However, the IPv4 implementation filters the traffic to the dhcp/bootp
> > port, 68. Therefore the ipv6 mapper captures more (non necessarily
> > useful) mappings than the ipv4 version. I made some brief research and
> > couldn't figure out how to do it. Do you think it's possible to refine
> > the tcpdump command to make it look only on the dhp request port (68)?
> > 
> 
> Hello Lucas, thanks for reviewing my patches for ipv6.
> Following tcpdump command will capture only the icmp6 packets and not
> all the ipv6 packets
> tcpdump -npv -i any icmp6 and 'dst net ff02::2'
> 
> Since the patch uses ip6 link local address, we are looking for router
> solicitation messages.

Ok, so you think it'd be better to change the tcpdump command used in
the patch to be "tcpdump -npv -i any icmp6 and 'dst net ff02::2'"?

That said, I don't fully understand all gory ipv6 details, so please
bear with me on this question: how would we be benefit from having an
ipv6 address cache? I mean, it's not like we're going to use the
mappings for any of the communications...

This patch will stay in the queue so Michael can take a look at it and
give opinions.

Cheers,

Lucas


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Autotest] [PATCH] KVM test: Add support for ipv6 addresses
  2010-02-25 20:09     ` Lucas Meneghel Rodrigues
@ 2010-03-02 15:02       ` yogi
  0 siblings, 0 replies; 5+ messages in thread
From: yogi @ 2010-03-02 15:02 UTC (permalink / raw)
  To: Lucas Meneghel Rodrigues; +Cc: autotest, kvm, Yogananth Subramanian

On Thu, 2010-02-25 at 17:09 -0300, Lucas Meneghel Rodrigues wrote:
> On Thu, 2010-02-25 at 19:11 +0530, yogi wrote:
> > On Wed, 2010-02-24 at 01:16 -0300, Lucas Meneghel Rodrigues wrote:
> > > H i Yogi, I have read and rebased your patch against current trunk. I
> > > have one doubt: I noticed that the tcpdump command you use to monitor
> > > traffic is basically all traffic that goes to network routers
> > > 
> > > /usr/sbin/tcpdump -npv ip6 -i any 'dst net ff02::2'
> > > 
> > > However, the IPv4 implementation filters the traffic to the dhcp/bootp
> > > port, 68. Therefore the ipv6 mapper captures more (non necessarily
> > > useful) mappings than the ipv4 version. I made some brief research and
> > > couldn't figure out how to do it. Do you think it's possible to refine
> > > the tcpdump command to make it look only on the dhp request port (68)?
> > > 
> > 
> > Hello Lucas, thanks for reviewing my patches for ipv6.
> > Following tcpdump command will capture only the icmp6 packets and not
> > all the ipv6 packets
> > tcpdump -npv -i any icmp6 and 'dst net ff02::2'
> > 
> > Since the patch uses ip6 link local address, we are looking for router
> > solicitation messages.
> 
> Ok, so you think it'd be better to change the tcpdump command used in
> the patch to be "tcpdump -npv -i any icmp6 and 'dst net ff02::2'"?
> 
Yes, its better to change the tcdump in the patch, so that it captures
only the icmp6 packets.
> That said, I don't fully understand all gory ipv6 details, so please
> bear with me on this question: how would we be benefit from having an
> ipv6 address cache? I mean, it's not like we're going to use the
> mappings for any of the communications...
Ipv6 address cache would add support to  test the ipv6 stack in the
guest, while doing network tests.
> 
> This patch will stay in the queue so Michael can take a look at it and
> give opinions.
Sure no problem at all. I would be happy to resubmit the Ipv6 patch,
when there is support to do network tests in kvm-autotest becomes
available.
> 
> Cheers,
> 
> Lucas
> 
Thanks and Regards
Yogi


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-03-02 15:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-24  4:10 [PATCH] KVM test: Add support for ipv6 addresses Lucas Meneghel Rodrigues
2010-02-24  4:16 ` [Autotest] " Lucas Meneghel Rodrigues
2010-02-25 13:41   ` yogi
2010-02-25 20:09     ` Lucas Meneghel Rodrigues
2010-03-02 15:02       ` yogi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.