vpp_papi_provider: Remove more wrapper functions.
[vpp.git] / test / test_gbp.py
index ec72981..05a4b4d 100644 (file)
@@ -124,7 +124,7 @@ class VppGbpEndpoint(VppObject):
             self.itf.sw_if_index,
             [self.ip4.encode(), self.ip6.encode()],
             self.vmac.packed,
-            self.epg.epg,
+            self.epg.sclass,
             self.flags,
             self.tun_src.encode(),
             self.tun_dst.encode())
@@ -141,7 +141,7 @@ class VppGbpEndpoint(VppObject):
         return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
                                                 self.itf.sw_if_index,
                                                 self.ip4.address,
-                                                self.epg.epg)
+                                                self.epg.sclass)
 
     def query_vpp_config(self):
         return find_gbp_endpoint(self._test,
@@ -164,7 +164,7 @@ class VppGbpRecirc(VppObject):
         self._test.vapi.gbp_recirc_add_del(
             1,
             self.recirc.sw_if_index,
-            self.epg.epg,
+            self.epg.sclass,
             self.is_ext)
         self._test.registry.register(self, self._test.logger)
 
@@ -172,7 +172,7 @@ class VppGbpRecirc(VppObject):
         self._test.vapi.gbp_recirc_add_del(
             0,
             self.recirc.sw_if_index,
-            self.epg.epg,
+            self.epg.sclass,
             self.is_ext)
 
     def __str__(self):
@@ -249,7 +249,7 @@ class VppGbpSubnet(VppObject):
             self.prefix.encode(),
             self.type,
             sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
-            epg_id=self.epg if self.epg else 0xffff)
+            sclass=self.epg.sclass if self.epg else 0xffff)
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
@@ -275,48 +275,58 @@ class VppGbpSubnet(VppObject):
         return False
 
 
+class VppGbpEndpointRetention(object):
+    def __init__(self, remote_ep_timeout=0xffffffff):
+        self.remote_ep_timeout = remote_ep_timeout
+
+    def encode(self):
+        return {'remote_ep_timeout': self.remote_ep_timeout}
+
+
 class VppGbpEndpointGroup(VppObject):
     """
     GBP Endpoint Group
     """
 
-    def __init__(self, test, epg, sclass, rd, bd, uplink,
-                 bvi, bvi_ip4, bvi_ip6=None):
+    def __init__(self, test, vnid, sclass, rd, bd, uplink,
+                 bvi, bvi_ip4, bvi_ip6=None,
+                 retention=VppGbpEndpointRetention()):
         self._test = test
         self.uplink = uplink
         self.bvi = bvi
         self.bvi_ip4 = VppIpAddress(bvi_ip4)
         self.bvi_ip6 = VppIpAddress(bvi_ip6)
-        self.epg = epg
+        self.vnid = vnid
         self.bd = bd
         self.rd = rd
         self.sclass = sclass
         if 0 == self.sclass:
             self.sclass = 0xffff
+        self.retention = retention
 
     def add_vpp_config(self):
         self._test.vapi.gbp_endpoint_group_add(
-            self.epg,
+            self.vnid,
             self.sclass,
             self.bd.bd.bd_id,
             self.rd.rd_id,
-            self.uplink.sw_if_index if self.uplink else INDEX_INVALID)
+            self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
+            self.retention.encode())
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
-        self._test.vapi.gbp_endpoint_group_del(
-            self.epg)
+        self._test.vapi.gbp_endpoint_group_del(self.sclass)
 
     def __str__(self):
         return self.object_id()
 
     def object_id(self):
-        return "gbp-endpoint-group:[%d]" % (self.epg)
+        return "gbp-endpoint-group:[%d]" % (self.vnid)
 
     def query_vpp_config(self):
         epgs = self._test.vapi.gbp_endpoint_group_dump()
         for epg in epgs:
-            if epg.epg.epg_id == self.epg:
+            if epg.epg.vnid == self.vnid:
                 return True
         return False
 
@@ -458,8 +468,8 @@ class VppGbpContract(VppObject):
             rules.append(r.encode())
         self._test.vapi.gbp_contract_add_del(
             1,
-            self.src_epg,
-            self.dst_epg,
+            self.src_epg.sclass,
+            self.dst_epg.sclass,
             self.acl_index,
             rules,
             self.allowed_ethertypes)
@@ -468,8 +478,8 @@ class VppGbpContract(VppObject):
     def remove_vpp_config(self):
         self._test.vapi.gbp_contract_add_del(
             0,
-            self.src_epg,
-            self.dst_epg,
+            self.src_epg.sclass,
+            self.dst_epg.sclass,
             self.acl_index,
             [], [])
 
@@ -477,15 +487,15 @@ class VppGbpContract(VppObject):
         return self.object_id()
 
     def object_id(self):
-        return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
-                                            self.dst_epg,
+        return "gbp-contract:[%d:%s:%d]" % (self.src_epg.sclass,
+                                            self.dst_epg.sclass,
                                             self.acl_index)
 
     def query_vpp_config(self):
         cs = self._test.vapi.gbp_contract_dump()
         for c in cs:
-            if c.contract.src_epg == self.src_epg \
-               and c.contract.dst_epg == self.dst_epg:
+            if c.contract.sclass == self.src_epg.sclass \
+               and c.contract.dclass == self.dst_epg.sclass:
                 return True
         return False
 
@@ -495,18 +505,20 @@ class VppGbpVxlanTunnel(VppInterface):
     GBP VXLAN tunnel
     """
 
-    def __init__(self, test, vni, bd_rd_id, mode):
+    def __init__(self, test, vni, bd_rd_id, mode, src):
         super(VppGbpVxlanTunnel, self).__init__(test)
         self._test = test
         self.vni = vni
         self.bd_rd_id = bd_rd_id
         self.mode = mode
+        self.src = src
 
     def add_vpp_config(self):
         r = self._test.vapi.gbp_vxlan_tunnel_add(
             self.vni,
             self.bd_rd_id,
-            self.mode)
+            self.mode,
+            self.src)
         self.set_sw_if_index(r.sw_if_index)
         self._test.registry.register(self, self._test.logger)
 
@@ -517,7 +529,7 @@ class VppGbpVxlanTunnel(VppInterface):
         return self.object_id()
 
     def object_id(self):
-        return "gbp-vxlan:%d" % (self.vni)
+        return "gbp-vxlan:%d" % (self.sw_if_index)
 
     def query_vpp_config(self):
         return find_gbp_vxlan(self._test, self.vni)
@@ -533,8 +545,8 @@ class VppGbpAcl(VppObject):
         self.acl_index = 4294967295
 
     def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
-                    s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
-                    sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
+                    s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
+                    sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
                     dport_from=0, dport_to=65535):
         if proto == -1 or proto == 0:
             sport_to = 0
@@ -557,7 +569,7 @@ class VppGbpAcl(VppObject):
 
         reply = self._test.vapi.acl_add_replace(self.acl_index,
                                                 r=rules,
-                                                tag='GBPTest')
+                                                tag=b'GBPTest')
         self.acl_index = reply.acl_index
         return self.acl_index
 
@@ -736,36 +748,26 @@ class TestGBP(VppTestCase):
         # 3 EPGs, 2 of which share a BD.
         # 2 NAT EPGs, one for floating-IP subnets, the other for internet
         #
-        epgs = [VppGbpEndpointGroup(self, 220, 0, rd0, gbd1, self.pg4,
-                                    self.loop0,
-                                    "10.0.0.128",
-                                    "2001:10::128"),
-                VppGbpEndpointGroup(self, 221, 0, rd0, gbd1, self.pg5,
-                                    self.loop0,
-                                    "10.0.1.128",
-                                    "2001:10:1::128"),
-                VppGbpEndpointGroup(self, 222, 0, rd0, gbd2, self.pg6,
-                                    self.loop1,
-                                    "10.0.2.128",
-                                    "2001:10:2::128"),
-                VppGbpEndpointGroup(self, 333, 0, rd20, gbd20, self.pg7,
-                                    self.loop2,
-                                    "11.0.0.128",
-                                    "3001::128"),
-                VppGbpEndpointGroup(self, 444, 0, rd20, gbd20, self.pg8,
-                                    self.loop2,
-                                    "11.0.0.129",
-                                    "3001::129")]
-        recircs = [VppGbpRecirc(self, epgs[0],
-                                self.loop3),
-                   VppGbpRecirc(self, epgs[1],
-                                self.loop4),
-                   VppGbpRecirc(self, epgs[2],
-                                self.loop5),
-                   VppGbpRecirc(self, epgs[3],
-                                self.loop6, is_ext=True),
-                   VppGbpRecirc(self, epgs[4],
-                                self.loop7, is_ext=True)]
+        epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
+                                    self.pg4, self.loop0,
+                                    "10.0.0.128", "2001:10::128"),
+                VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
+                                    self.pg5, self.loop0,
+                                    "10.0.1.128", "2001:10:1::128"),
+                VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
+                                    self.pg6, self.loop1,
+                                    "10.0.2.128", "2001:10:2::128"),
+                VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
+                                    self.pg7, self.loop2,
+                                    "11.0.0.128", "3001::128"),
+                VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
+                                    self.pg8, self.loop2,
+                                    "11.0.0.129", "3001::129")]
+        recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
+                   VppGbpRecirc(self, epgs[1], self.loop4),
+                   VppGbpRecirc(self, epgs[2], self.loop5),
+                   VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
+                   VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
 
         epg_nat = epgs[3]
         recirc_nat = recircs[3]
@@ -1142,7 +1144,7 @@ class TestGBP(VppTestCase):
         rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
         acl_index = acl.add_vpp_config([rule, rule2])
         c1 = VppGbpContract(
-            self, 220, 221, acl_index,
+            self, epgs[0], epgs[1], acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1162,7 +1164,7 @@ class TestGBP(VppTestCase):
         # contract for the return direction
         #
         c2 = VppGbpContract(
-            self, 221, 220, acl_index,
+            self, epgs[1], epgs[0], acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1199,7 +1201,7 @@ class TestGBP(VppTestCase):
         # A uni-directional contract from EPG 220 -> 222 'L3 routed'
         #
         c3 = VppGbpContract(
-            self, 220, 222, acl_index,
+            self, epgs[0], epgs[2], acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1241,33 +1243,33 @@ class TestGBP(VppTestCase):
             self, rd0, "0.0.0.0", 0,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=recirc_nat.recirc.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         se2 = VppGbpSubnet(
             self, rd0, "11.0.0.0", 8,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=recirc_nat.recirc.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         se16 = VppGbpSubnet(
             self, rd0, "::", 0,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=recirc_nat.recirc.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         # in the NAT RD an external subnet via the NAT EPG's uplink
         se3 = VppGbpSubnet(
             self, rd20, "0.0.0.0", 0,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=epg_nat.uplink.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         se36 = VppGbpSubnet(
             self, rd20, "::", 0,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=epg_nat.uplink.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         se4 = VppGbpSubnet(
             self, rd20, "11.0.0.0", 8,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
             sw_if_index=epg_nat.uplink.sw_if_index,
-            epg=epg_nat.epg)
+            epg=epg_nat)
         se1.add_vpp_config()
         se2.add_vpp_config()
         se16.add_vpp_config()
@@ -1304,7 +1306,7 @@ class TestGBP(VppTestCase):
 
         acl_index2 = acl2.add_vpp_config([rule, rule2])
         c4 = VppGbpContract(
-            self, 220, 333, acl_index2,
+            self, epgs[0], epgs[3], acl_index2,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1345,7 +1347,7 @@ class TestGBP(VppTestCase):
                                         pkt_inter_epg_220_from_global * 65)
 
         c5 = VppGbpContract(
-            self, 333, 220, acl_index2,
+            self, epgs[3], epgs[0], acl_index2,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1458,12 +1460,6 @@ class TestGBP(VppTestCase):
                    'ip': '10.0.0.2',
                    'ip6': '2001:10::3'}]
 
-        #
-        # lower the inactive threshold so these tests pass in a
-        # reasonable amount of time
-        #
-        self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
-
         #
         # IP tables
         #
@@ -1518,12 +1514,14 @@ class TestGBP(VppTestCase):
         epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
                                       None, self.loop0,
                                       "10.0.0.128",
-                                      "2001:10::128")
+                                      "2001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_220.add_vpp_config()
         epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
                                       None, self.loop1,
                                       "10.0.1.128",
-                                      "2001:11::128")
+                                      "2001:11::128",
+                                      VppGbpEndpointRetention(2))
         epg_330.add_vpp_config()
 
         #
@@ -1532,7 +1530,8 @@ class TestGBP(VppTestCase):
         #
         vx_tun_l2_1 = VppGbpVxlanTunnel(
             self, 99, bd1.bd_id,
-            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
+            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
+            self.pg2.local_ip4)
         vx_tun_l2_1.add_vpp_config()
 
         #
@@ -1574,6 +1573,9 @@ class TestGBP(VppTestCase):
         # epg is not learnt, becasue the EPG is unknwon
         self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
 
+        #
+        # Learn new EPs from IP packets
+        #
         for ii, l in enumerate(learnt):
             # a packet with an sclass from a knwon EPG
             # arriving on an unknown TEP
@@ -1611,7 +1613,7 @@ class TestGBP(VppTestCase):
 
         self.logger.info(self.vapi.cli("show gbp endpoint"))
         self.logger.info(self.vapi.cli("show gbp vxlan"))
-        self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
+        self.logger.info(self.vapi.cli("show ip mfib"))
 
         #
         # If we sleep for the threshold time, the learnt endpoints should
@@ -1621,6 +1623,95 @@ class TestGBP(VppTestCase):
             self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
                                      mac=l['mac'])
 
+        #
+        # Learn new EPs from GARP packets received on the BD's mcast tunnel
+        #
+        for ii, l in enumerate(learnt):
+            # a packet with an sclass from a knwon EPG
+            # arriving on an unknown TEP
+            p = (Ether(src=self.pg2.remote_mac,
+                       dst=self.pg2.local_mac) /
+                 IP(src=self.pg2.remote_hosts[1].ip4,
+                    dst="239.1.1.1") /
+                 UDP(sport=1234, dport=48879) /
+                 VXLAN(vni=88, gpid=112, flags=0x88) /
+                 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
+                 ARP(op="who-has",
+                     psrc=l['ip'], pdst=l['ip'],
+                     hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
+
+            rx = self.send_and_expect(self.pg4, [p], self.pg0)
+
+            # the new TEP
+            tep1_sw_if_index = find_vxlan_gbp_tunnel(
+                self,
+                self.pg2.local_ip4,
+                self.pg2.remote_hosts[1].ip4,
+                99)
+            self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
+
+            #
+            # the EP is learnt via the learnt TEP
+            # both from its MAC and its IP
+            #
+            self.assertTrue(find_gbp_endpoint(self,
+                                              vx_tun_l2_1.sw_if_index,
+                                              mac=l['mac']))
+            self.assertTrue(find_gbp_endpoint(self,
+                                              vx_tun_l2_1.sw_if_index,
+                                              ip=l['ip']))
+
+        #
+        # wait for the learnt endpoints to age out
+        #
+        for l in learnt:
+            self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
+                                     mac=l['mac'])
+
+        #
+        # Learn new EPs from L2 packets
+        #
+        for ii, l in enumerate(learnt):
+            # a packet with an sclass from a knwon EPG
+            # arriving on an unknown TEP
+            p = (Ether(src=self.pg2.remote_mac,
+                       dst=self.pg2.local_mac) /
+                 IP(src=self.pg2.remote_hosts[1].ip4,
+                    dst=self.pg2.local_ip4) /
+                 UDP(sport=1234, dport=48879) /
+                 VXLAN(vni=99, gpid=112, flags=0x88) /
+                 Ether(src=l['mac'], dst=ep.mac) /
+                 Raw('\xa5' * 100))
+
+            rx = self.send_and_expect(self.pg2, [p], self.pg0)
+
+            # the new TEP
+            tep1_sw_if_index = find_vxlan_gbp_tunnel(
+                self,
+                self.pg2.local_ip4,
+                self.pg2.remote_hosts[1].ip4,
+                99)
+            self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
+
+            #
+            # the EP is learnt via the learnt TEP
+            # both from its MAC and its IP
+            #
+            self.assertTrue(find_gbp_endpoint(self,
+                                              vx_tun_l2_1.sw_if_index,
+                                              mac=l['mac']))
+
+        self.logger.info(self.vapi.cli("show gbp endpoint"))
+        self.logger.info(self.vapi.cli("show gbp vxlan"))
+        self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
+
+        #
+        # wait for the learnt endpoints to age out
+        #
+        for l in learnt:
+            self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
+                                     mac=l['mac'])
+
         #
         # repeat. the do not learn bit is set so the EPs are not learnt
         #
@@ -1759,7 +1850,7 @@ class TestGBP(VppTestCase):
         rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
         acl_index = acl.add_vpp_config([rule, rule2])
         c1 = VppGbpContract(
-            self, 220, 330, acl_index,
+            self, epg_220, epg_330, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -1860,12 +1951,6 @@ class TestGBP(VppTestCase):
                    'ip': '10.0.0.2',
                    'ip6': '2001:10::3'}]
 
-        #
-        # lower the inactive threshold so these tests pass in a
-        # reasonable amount of time
-        #
-        self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
-
         #
         # IP tables
         #
@@ -1892,9 +1977,9 @@ class TestGBP(VppTestCase):
         #
         vlan_11 = VppDot1QSubint(self, self.pg0, 11)
         vlan_11.admin_up()
-        self.vapi.l2_interface_vlan_tag_rewrite(vlan_11.sw_if_index,
-                                                L2_VTR_OP.L2_POP_1,
-                                                11)
+        self.vapi.l2_interface_vlan_tag_rewrite(
+            sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
+            push_dot1q=11)
 
         bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
                                       self.pg3.remote_ip4, 116)
@@ -1924,7 +2009,8 @@ class TestGBP(VppTestCase):
         epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
                                       None, self.loop0,
                                       "10.0.0.128",
-                                      "2001:10::128")
+                                      "2001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_220.add_vpp_config()
 
         #
@@ -1933,7 +2019,8 @@ class TestGBP(VppTestCase):
         #
         vx_tun_l2_1 = VppGbpVxlanTunnel(
             self, 99, bd1.bd_id,
-            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
+            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
+            self.pg2.local_ip4)
         vx_tun_l2_1.add_vpp_config()
 
         #
@@ -2033,12 +2120,6 @@ class TestGBP(VppTestCase):
                    'ip': '10.0.1.3',
                    'ip6': '2001:10::3'}]
 
-        #
-        # lower the inactive threshold so these tests pass in a
-        # reasonable amount of time
-        #
-        self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
-
         #
         # IP tables
         #
@@ -2104,7 +2185,8 @@ class TestGBP(VppTestCase):
         epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
                                       None, self.loop0,
                                       "10.0.0.128",
-                                      "2001:10::128")
+                                      "2001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_220.add_vpp_config()
 
         #
@@ -2113,7 +2195,8 @@ class TestGBP(VppTestCase):
         #
         vx_tun_l3 = VppGbpVxlanTunnel(
             self, 101, rd1.rd_id,
-            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
+            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
+            self.pg2.local_ip4)
         vx_tun_l3.add_vpp_config()
 
         #
@@ -2476,12 +2559,6 @@ class TestGBP(VppTestCase):
                    'ip': '10.0.1.3',
                    'ip6': '2001:10::3'}]
 
-        #
-        # lower the inactive threshold so these tests pass in a
-        # reasonable amount of time
-        #
-        self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
-
         #
         # IP tables
         #
@@ -2536,17 +2613,20 @@ class TestGBP(VppTestCase):
         epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
                                       None, gbd1.bvi,
                                       "10.0.0.128",
-                                      "2001:10::128")
+                                      "2001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_220.add_vpp_config()
         epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
                                       None, gbd2.bvi,
                                       "10.0.1.128",
-                                      "2001:11::128")
+                                      "2001:11::128",
+                                      VppGbpEndpointRetention(2))
         epg_221.add_vpp_config()
         epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
                                       None, gbd1.bvi,
                                       "10.0.2.128",
-                                      "2001:12::128")
+                                      "2001:12::128",
+                                      VppGbpEndpointRetention(2))
         epg_222.add_vpp_config()
 
         #
@@ -2574,12 +2654,14 @@ class TestGBP(VppTestCase):
         epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
                                       None, gbd1.bvi,
                                       "12.0.0.128",
-                                      "4001:10::128")
+                                      "4001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_320.add_vpp_config()
         epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
                                       None, gbd2.bvi,
                                       "12.0.1.128",
-                                      "4001:11::128")
+                                      "4001:11::128",
+                                      VppGbpEndpointRetention(2))
         epg_321.add_vpp_config()
 
         #
@@ -2663,7 +2745,7 @@ class TestGBP(VppTestCase):
         # test the src-ip hash mode
         #
         c1 = VppGbpContract(
-            self, 220, 222, acl_index,
+            self, epg_220, epg_222, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
@@ -2682,7 +2764,7 @@ class TestGBP(VppTestCase):
         c1.add_vpp_config()
 
         c2 = VppGbpContract(
-            self, 222, 220, acl_index,
+            self, epg_222, epg_220, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
@@ -2795,7 +2877,7 @@ class TestGBP(VppTestCase):
         # test the symmetric hash mode
         #
         c1 = VppGbpContract(
-            self, 220, 222, acl_index,
+            self, epg_220, epg_222, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
@@ -2814,7 +2896,7 @@ class TestGBP(VppTestCase):
         c1.add_vpp_config()
 
         c2 = VppGbpContract(
-            self, 222, 220, acl_index,
+            self, epg_222, epg_220, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
@@ -2879,7 +2961,7 @@ class TestGBP(VppTestCase):
                Raw('\xa5' * 100))]
 
         c3 = VppGbpContract(
-            self, 220, 221, acl_index,
+            self, epg_220, epg_221, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
@@ -2910,11 +2992,12 @@ class TestGBP(VppTestCase):
         #
         vx_tun_l3 = VppGbpVxlanTunnel(
             self, 444, rd1.rd_id,
-            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
+            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
+            self.pg2.local_ip4)
         vx_tun_l3.add_vpp_config()
 
         c4 = VppGbpContract(
-            self, 221, 220, acl_index,
+            self, epg_221, epg_220, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
                 []),
@@ -2992,7 +3075,7 @@ class TestGBP(VppTestCase):
         # test the dst-ip hash mode
         #
         c5 = VppGbpContract(
-            self, 220, 221, acl_index,
+            self, epg_220, epg_221, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
@@ -3088,7 +3171,8 @@ class TestGBP(VppTestCase):
         epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
                                       None, gbd1.bvi,
                                       "10.0.0.128",
-                                      "2001:10::128")
+                                      "2001:10::128",
+                                      VppGbpEndpointRetention(2))
         epg_220.add_vpp_config()
 
         # the BVIs have the subnets applied ...
@@ -3101,7 +3185,7 @@ class TestGBP(VppTestCase):
         l3o_1 = VppGbpSubnet(
             self, rd1, "10.0.0.0", 24,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
-            epg=220)
+            epg=epg_220)
         l3o_1.add_vpp_config()
 
         #
@@ -3118,11 +3202,12 @@ class TestGBP(VppTestCase):
         #
         vx_tun_l3 = VppGbpVxlanTunnel(
             self, 444, rd1.rd_id,
-            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
+            VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
+            self.pg2.local_ip4)
         vx_tun_l3.add_vpp_config()
 
         #
-        # packets destined to unkown addresses in the BVI's subnet
+        # packets destined to unknown addresses in the BVI's subnet
         # are ARP'd for
         #
         p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
@@ -3206,7 +3291,7 @@ class TestGBP(VppTestCase):
         l3o_220 = VppGbpSubnet(
             self, rd1, "10.220.0.0", 24,
             VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
-            epg=220)
+            epg=epg_220)
         l3o_220.add_vpp_config()
 
         p = (Ether(src=self.pg7.remote_mac,