misc: fix coverity warning in ila plugin
[vpp.git] / test / test_neighbor.py
index 7c13f9f..e893085 100644 (file)
@@ -4,10 +4,11 @@ import unittest
 import os
 from socket import AF_INET, AF_INET6, inet_pton
 
+from framework import tag_fixme_vpp_workers
 from framework import VppTestCase, VppTestRunner
 from vpp_neighbor import VppNeighbor, find_nbr
 from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, \
-    VppIpTable, DpoProto, FibPathType
+    VppIpTable, DpoProto, FibPathType, VppIpInterfaceAddress
 from vpp_papi import VppEnum
 from vpp_ip import VppIpPuntRedirect
 
@@ -82,6 +83,7 @@ class ARPTestCase(VppTestCase):
         ether = rx[Ether]
         self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
         self.assertEqual(ether.src, smac)
+        self.assertEqual(ether.type, 0x0806)
 
         arp = rx[ARP]
         self.assertEqual(arp.hwtype, 1)
@@ -98,6 +100,7 @@ class ARPTestCase(VppTestCase):
         ether = rx[Ether]
         self.assertEqual(ether.dst, dmac)
         self.assertEqual(ether.src, smac)
+        self.assertEqual(ether.type, 0x0806)
 
         arp = rx[ARP]
         self.assertEqual(arp.hwtype, 1)
@@ -132,6 +135,7 @@ class ARPTestCase(VppTestCase):
         ether = rx[Ether]
         self.assertEqual(ether.dst, dmac)
         self.assertEqual(ether.src, smac)
+        self.assertEqual(ether.type, 0x0800)
 
         ip = rx[IP]
         self.assertEqual(ip.src, sip)
@@ -141,6 +145,7 @@ class ARPTestCase(VppTestCase):
         ether = rx[Ether]
         self.assertEqual(ether.dst, dmac)
         self.assertEqual(ether.src, smac)
+        self.assertEqual(ether.type, 0x8847)
 
         mpls = rx[MPLS]
         self.assertTrue(mpls.label, label)
@@ -1367,7 +1372,7 @@ class ARPTestCase(VppTestCase):
 
     def test_arp_incomplete(self):
         """ ARP Incomplete"""
-        self.pg1.generate_remote_hosts(3)
+        self.pg1.generate_remote_hosts(4)
 
         p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
               IP(src=self.pg0.remote_ip4,
@@ -1379,6 +1384,11 @@ class ARPTestCase(VppTestCase):
                  dst=self.pg1.remote_hosts[2].ip4) /
               UDP(sport=1234, dport=1234) /
               Raw())
+        p2 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
+              IP(src=self.pg0.remote_ip4,
+                 dst="1.1.1.1") /
+              UDP(sport=1234, dport=1234) /
+              Raw())
 
         #
         # a packet to an unresolved destination generates an ARP request
@@ -1399,6 +1409,18 @@ class ARPTestCase(VppTestCase):
                                  is_static=1)
         static_arp.add_vpp_config()
 
+        #
+        # add a route through remote host 3 hence we get an incomplete
+        #
+        VppIpRoute(self, "1.1.1.1", 32,
+                   [VppRoutePath(self.pg1.remote_hosts[3].ip4,
+                                 self.pg1.sw_if_index)]).add_vpp_config()
+        rx = self.send_and_expect(self.pg0, [p2], self.pg1)
+        self.verify_arp_req(rx[0],
+                            self.pg1.local_mac,
+                            self.pg1.local_ip4,
+                            self.pg1._remote_hosts[3].ip4)
+
         #
         # change the interface's MAC
         #
@@ -1413,6 +1435,11 @@ class ARPTestCase(VppTestCase):
                             "00:00:00:33:33:33",
                             self.pg1.local_ip4,
                             self.pg1._remote_hosts[2].ip4)
+        rx = self.send_and_expect(self.pg0, [p2], self.pg1)
+        self.verify_arp_req(rx[0],
+                            "00:00:00:33:33:33",
+                            self.pg1.local_ip4,
+                            self.pg1._remote_hosts[3].ip4)
 
         #
         # packets to the resolved host also have the new source mac
@@ -1721,7 +1748,110 @@ class ARPTestCase(VppTestCase):
         self.pg1.unconfig_ip4()
         self.pg1.set_table_ip4(0)
 
+    def test_glean_src_select(self):
+        """ Multi Connecteds """
+
+        #
+        # configure multiple connected subnets on an interface
+        # and ensure that ARP requests for hosts on those subnets
+        # pick up the correct source address
+        #
+        conn1 = VppIpInterfaceAddress(self, self.pg1,
+                                      "10.0.0.1", 24).add_vpp_config()
+        conn2 = VppIpInterfaceAddress(self, self.pg1,
+                                      "10.0.1.1", 24).add_vpp_config()
+
+        p1 = (Ether(src=self.pg0.remote_mac,
+                    dst=self.pg0.local_mac) /
+              IP(src=self.pg1.remote_ip4,
+                 dst="10.0.0.128") /
+              Raw(b'0x5' * 100))
+
+        rxs = self.send_and_expect(self.pg0, [p1], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.0.1",
+                                "10.0.0.128")
+
+        p2 = (Ether(src=self.pg0.remote_mac,
+                    dst=self.pg0.local_mac) /
+              IP(src=self.pg1.remote_ip4,
+                 dst="10.0.1.128") /
+              Raw(b'0x5' * 100))
+
+        rxs = self.send_and_expect(self.pg0, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.1",
+                                "10.0.1.128")
+
+        #
+        # add a local address in the same subnet
+        #  the source addresses are equivalent. VPP happens to
+        #  choose the last one that was added
+        conn3 = VppIpInterfaceAddress(self, self.pg1,
+                                      "10.0.1.2", 24).add_vpp_config()
+
+        rxs = self.send_and_expect(self.pg0, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.2",
+                                "10.0.1.128")
+
+        #
+        # remove
+        #
+        conn3.remove_vpp_config()
+        rxs = self.send_and_expect(self.pg0, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.1",
+                                "10.0.1.128")
+
+        #
+        # add back, this time remove the first one
+        #
+        conn3 = VppIpInterfaceAddress(self, self.pg1,
+                                      "10.0.1.2", 24).add_vpp_config()
+
+        rxs = self.send_and_expect(self.pg0, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.2",
+                                "10.0.1.128")
+
+        conn1.remove_vpp_config()
+        rxs = self.send_and_expect(self.pg0, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.2",
+                                "10.0.1.128")
+
+        # apply a connected prefix to an interface in a different table
+        VppIpRoute(self, "10.0.1.0", 24,
+                   [VppRoutePath("0.0.0.0",
+                                 self.pg1.sw_if_index)],
+                   table_id=1).add_vpp_config()
+
+        rxs = self.send_and_expect(self.pg3, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.2",
+                                "10.0.1.128")
+
+        # cleanup
+        conn3.remove_vpp_config()
+        conn2.remove_vpp_config()
+
 
+@tag_fixme_vpp_workers
 class NeighborStatsTestCase(VppTestCase):
     """ ARP/ND Counters """