IPv6 NS RS tests and fixes
[vpp.git] / test / vpp_pg_interface.py
index d3db8d2..b5929a4 100644 (file)
@@ -1,5 +1,6 @@
 import os
 import time
+import socket
 from traceback import format_exc
 from scapy.utils import wrpcap, rdpcap, PcapReader
 from vpp_interface import VppInterface
@@ -9,12 +10,14 @@ from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6ND_NA,\
     ICMPv6NDOptSrcLLAddr, ICMPv6NDOptDstLLAddr, ICMPv6ND_RA, RouterAlert, \
     IPv6ExtHdrHopByHop
 from util import ppp, ppc
-
+from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ismaddr
+from scapy.utils import inet_pton, inet_ntop
 
 def is_ipv6_misc(p):
     """ Is packet one of uninteresting IPv6 broadcasts? """
     if p.haslayer(ICMPv6ND_RA):
-        return True
+        if in6_ismaddr(p[IPv6].dst):
+            return True
     if p.haslayer(IPv6ExtHdrHopByHop):
         for o in p[IPv6ExtHdrHopByHop].options:
             if isinstance(o, RouterAlert):
@@ -91,8 +94,7 @@ class VppPGInterface(VppInterface):
         self._input_cli = "packet-generator new pcap %s source pg%u name %s" % (
             self.in_path, self.pg_index, self.cap_name)
 
-    def enable_capture(self):
-        """ Enable capture on this packet-generator interface"""
+    def rotate_out_file(self):
         try:
             if os.path.isfile(self.out_path):
                 os.rename(self.out_path,
@@ -104,6 +106,10 @@ class VppPGInterface(VppInterface):
                            self._out_file))
         except:
             pass
+
+    def enable_capture(self):
+        """ Enable capture on this packet-generator interface"""
+        self.rotate_out_file()
         # FIXME this should be an API, but no such exists atm
         self.test.vapi.cli(self.capture_cli)
         self._pcap_reader = None
@@ -145,7 +151,7 @@ class VppPGInterface(VppInterface):
         before = len(output.res)
         if filter_out_fn:
             output.res = [p for p in output.res if not filter_out_fn(p)]
-        removed = len(output.res) - before
+        removed = before - len(output.res)
         if removed:
             self.test.logger.debug(
                 "Filtered out %s packets from capture (returning %s)" %
@@ -301,8 +307,11 @@ class VppPGInterface(VppInterface):
 
     def create_ndp_req(self):
         """Create NDP - NS applicable for this interface"""
-        return (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.remote_mac) /
-                IPv6(src=self.remote_ip6, dst=self.local_ip6) /
+        nsma = in6_getnsma(inet_pton(socket.AF_INET6, self.local_ip6))
+        d = inet_ntop(socket.AF_INET6, nsma)
+
+        return (Ether(dst=in6_getnsmac(nsma)) /
+                IPv6(dst=d, src=self.remote_ip6) /
                 ICMPv6ND_NS(tgt=self.local_ip6) /
                 ICMPv6NDOptSrcLLAddr(lladdr=self.remote_mac))
 
@@ -328,6 +337,7 @@ class VppPGInterface(VppInterface):
             self.test.logger.info("No ARP received on port %s" %
                                   pg_interface.name)
             return
+        self.rotate_out_file()
         arp_reply = captured_packet.copy()  # keep original for exception
         # Make Dot1AD packet content recognizable to scapy
         if arp_reply.type == 0x88a8:
@@ -387,6 +397,7 @@ class VppPGInterface(VppInterface):
                 self._local_mac = opt.lladdr
                 self.test.logger.debug(self.test.vapi.cli("show trace"))
                 # we now have the MAC we've been after
+                self.rotate_out_file()
                 return
             except:
                 self.test.logger.info(
@@ -394,4 +405,5 @@ class VppPGInterface(VppInterface):
             now = time.time()
 
         self.test.logger.debug(self.test.vapi.cli("show trace"))
+        self.rotate_out_file()
         raise Exception("Timeout while waiting for NDP response")