tests: python3 use byte strings in raw()
[vpp.git] / src / plugins / gbp / test / test_gbp.py
index cb42649..315e166 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from socket import AF_INET, AF_INET6
 import unittest
@@ -652,6 +652,9 @@ class TestGBP(VppTestCase):
         for i in self.pg_interfaces:
             i.admin_down()
         super(TestGBP, self).tearDown()
+        for i in self.lo_interfaces:
+            i.remove_vpp_config()
+        self.lo_interfaces = []
         self.vlan_102.remove_vpp_config()
         self.vlan_101.remove_vpp_config()
         self.vlan_100.remove_vpp_config()
@@ -1039,7 +1042,7 @@ class TestGBP(VppTestCase):
                            src=self.pg0.remote_mac) /
                      IP(src=eps[0].ip4.address, dst="232.1.1.1") /
                      UDP(sport=1234, dport=1234) /
-                     Raw('\xa5' * 100))
+                     Raw(b'\xa5' * 100))
 
         self.vapi.cli("clear trace")
         self.pg0.add_stream(pkt_bcast)
@@ -1060,13 +1063,13 @@ class TestGBP(VppTestCase):
                                  IP(src=eps[0].ip4.address,
                                     dst="10.0.0.99") /
                                  UDP(sport=1234, dport=1234) /
-                                 Raw('\xa5' * 100))
+                                 Raw(b'\xa5' * 100))
         pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
                                        dst=str(self.router_mac)) /
                                  IP(src=eps[0].ip4.address,
                                     dst="10.0.1.99") /
                                  UDP(sport=1234, dport=1234) /
-                                 Raw('\xa5' * 100))
+                                 Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(self.pg0,
                                         pkt_intra_epg_220_ip4 * NUM_PKTS)
@@ -1076,7 +1079,7 @@ class TestGBP(VppTestCase):
                                  IPv6(src=eps[0].ip6.address,
                                       dst="2001:10::99") /
                                  UDP(sport=1234, dport=1234) /
-                                 Raw('\xa5' * 100))
+                                 Raw(b'\xa5' * 100))
         self.send_and_assert_no_replies(self.pg0,
                                         pkt_inter_epg_222_ip6 * NUM_PKTS)
 
@@ -1137,7 +1140,7 @@ class TestGBP(VppTestCase):
                                        IP(src=eps[0].ip4.address,
                                           dst="10.0.0.99") /
                                        UDP(sport=1234, dport=1234) /
-                                       Raw('\xa5' * 100))
+                                       Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged(eps[0].itf,
                                      pkt_intra_epg_220_to_uplink * NUM_PKTS,
@@ -1151,7 +1154,7 @@ class TestGBP(VppTestCase):
                                        IP(src=eps[0].ip4.address,
                                           dst="10.0.0.99") /
                                        UDP(sport=1234, dport=1234) /
-                                       Raw('\xa5' * 100))
+                                       Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged(eps[2].itf,
                                      pkt_intra_epg_221_to_uplink * NUM_PKTS,
@@ -1165,7 +1168,7 @@ class TestGBP(VppTestCase):
                                          IP(src=eps[0].ip4.address,
                                             dst="10.0.0.99") /
                                          UDP(sport=1234, dport=1234) /
-                                         Raw('\xa5' * 100))
+                                         Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged(self.pg4,
                                      pkt_intra_epg_220_from_uplink * NUM_PKTS,
@@ -1180,7 +1183,7 @@ class TestGBP(VppTestCase):
                          IP(src=eps[0].ip4.address,
                             dst=eps[1].ip4.address) /
                          UDP(sport=1234, dport=1234) /
-                         Raw('\xa5' * 100))
+                         Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged(self.pg0,
                                      pkt_intra_epg * NUM_PKTS,
@@ -1195,19 +1198,19 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[2].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
                                           dst=self.pg0.remote_mac) /
                                     IP(src=eps[2].ip4.address,
                                        dst=eps[0].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
                                           dst=str(self.router_mac)) /
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[3].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(eps[0].itf,
                                         pkt_inter_epg_220_to_221 * NUM_PKTS)
@@ -1380,7 +1383,7 @@ class TestGBP(VppTestCase):
                                        IP(src=eps[0].ip4.address,
                                           dst="1.1.1.1") /
                                        UDP(sport=1234, dport=1234) /
-                                       Raw('\xa5' * 100))
+                                       Raw(b'\xa5' * 100))
 
         # no policy yet
         self.send_and_assert_no_replies(eps[0].itf,
@@ -1417,7 +1420,7 @@ class TestGBP(VppTestCase):
                                        IPv6(src=eps[0].ip6.address,
                                             dst="6001::1") /
                                        UDP(sport=1234, dport=1234) /
-                                       Raw('\xa5' * 100))
+                                       Raw(b'\xa5' * 100))
 
         self.send_and_expect_natted6(self.pg0,
                                      pkt_inter_epg_220_to_global * NUM_PKTS,
@@ -1432,7 +1435,7 @@ class TestGBP(VppTestCase):
                                          IP(dst=eps[0].fip4.address,
                                             src="1.1.1.1") /
                                          UDP(sport=1234, dport=1234) /
-                                         Raw('\xa5' * 100))
+                                         Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(
             self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS)
@@ -1460,7 +1463,7 @@ class TestGBP(VppTestCase):
                                          IPv6(dst=eps[0].fip6.address,
                                               src="6001::1") /
                                          UDP(sport=1234, dport=1234) /
-                                         Raw('\xa5' * 100))
+                                         Raw(b'\xa5' * 100))
 
         self.send_and_expect_unnatted6(
             self.pg7,
@@ -1477,7 +1480,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[1].fip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_expect_double_natted(eps[0].itf,
                                            pkt_intra_epg_220_global * NUM_PKTS,
@@ -1490,7 +1493,7 @@ class TestGBP(VppTestCase):
                                     IPv6(src=eps[0].ip6.address,
                                          dst=eps[1].fip6.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_expect_double_natted6(
             eps[0].itf,
@@ -1660,7 +1663,7 @@ class TestGBP(VppTestCase):
              Ether(src=learnt[0]["mac"], dst=ep.mac) /
              IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(self.pg2, p)
 
@@ -1697,7 +1700,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -1795,7 +1798,7 @@ class TestGBP(VppTestCase):
                  UDP(sport=1234, dport=48879) /
                  VXLAN(vni=99, gpid=112, flags=0x88) /
                  Ether(src=l['mac'], dst=ep.mac) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -1840,7 +1843,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
 
@@ -1865,7 +1868,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
 
@@ -1881,7 +1884,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=l['mac']) /
                  IP(dst=l['ip'], src=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
 
@@ -1917,7 +1920,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
 
@@ -1932,7 +1935,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=l['mac']) /
              IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(self.pg0, [p])
 
@@ -1950,7 +1953,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
 
@@ -1982,7 +1985,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=l['mac']) /
                  IP(dst=l['ip'], src=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             self.send_and_expect(self.pg0, [p], self.pg2)
 
@@ -1994,7 +1997,7 @@ class TestGBP(VppTestCase):
         p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
                 IP(dst="10.0.0.133", src=ep.ip4.address) /
                 UDP(sport=1234, dport=1234) /
-                Raw('\xa5' * 100))
+                Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
 
         self.logger.info(self.vapi.cli("sh bridge 1 detail"))
@@ -2002,7 +2005,7 @@ class TestGBP(VppTestCase):
         p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
                 IP(dst="10.0.0.133", src=ep.ip4.address) /
                 UDP(sport=1234, dport=1234) /
-                Raw('\xa5' * 100))
+                Raw(b'\xa5' * 100))
         rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
 
         for rx in rxs:
@@ -2051,7 +2054,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IPv6(src=l['ip6'], dst=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
@@ -2083,7 +2086,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IPv6(src=l['ip6'], dst=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
@@ -2103,7 +2106,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=l['mac']) /
                  IPv6(dst=l['ip6'], src=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
 
@@ -2134,7 +2137,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IPv6(src=l['ip6'], dst=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
             rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
@@ -2157,7 +2160,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=l['mac']) /
                  IPv6(dst=l['ip6'], src=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
 
@@ -2293,7 +2296,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[1].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged(self.pg0,
                                      pkt_intra_epg_220_to_220 * 65,
@@ -2304,7 +2307,7 @@ class TestGBP(VppTestCase):
                                     IPv6(src=eps[0].ip6.address,
                                          dst=eps[1].ip6.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_expect_bridged6(self.pg0,
                                       pkt_intra_epg_220_to_220 * 65,
@@ -2318,7 +2321,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[2].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221)
 
@@ -2356,7 +2359,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[0].ip4.address,
                                        dst=eps[3].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         self.send_and_assert_no_replies(eps[0].itf,
                                         pkt_inter_epg_220_to_222 * 65)
 
@@ -2403,7 +2406,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[2].ip4.address,
                                        dst=eps[0].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         self.send_and_expect_bridged(eps[2].itf,
                                      pkt_inter_epg_221_to_220 * 65,
                                      eps[0].itf)
@@ -2412,7 +2415,7 @@ class TestGBP(VppTestCase):
                                     IP(src=eps[2].ip4.address,
                                        dst=eps[0].ip4.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         self.send_and_expect_routed(eps[2].itf,
                                     pkt_inter_epg_221_to_220 * 65,
                                     eps[0].itf,
@@ -2422,7 +2425,7 @@ class TestGBP(VppTestCase):
                                     IPv6(src=eps[2].ip6.address,
                                          dst=eps[0].ip6.address) /
                                     UDP(sport=1234, dport=1234) /
-                                    Raw('\xa5' * 100))
+                                    Raw(b'\xa5' * 100))
         self.send_and_expect_routed6(eps[2].itf,
                                      pkt_inter_epg_221_to_220 * 65,
                                      eps[0].itf,
@@ -2510,13 +2513,13 @@ class TestGBP(VppTestCase):
         p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
                 IP(dst="10.0.0.133", src=ep.ip4.address) /
                 UDP(sport=1234, dport=1234) /
-                Raw('\xa5' * 100))
+                Raw(b'\xa5' * 100))
         self.send_and_assert_no_replies(ep.itf, [p_uu])
 
         p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
                 IP(dst="10.0.0.133", src=ep.ip4.address) /
                 UDP(sport=1234, dport=1234) /
-                Raw('\xa5' * 100))
+                Raw(b'\xa5' * 100))
         self.send_and_assert_no_replies(ep.itf, [p_bm])
 
         self.pg3.unconfig_ip4()
@@ -2706,7 +2709,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst=ep.mac) /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -2741,7 +2744,7 @@ class TestGBP(VppTestCase):
                  Dot1Q(vlan=11) /
                  IP(dst=l['ip'], src=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
 
@@ -2879,7 +2882,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst="00:00:00:11:11:11") /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -2903,7 +2906,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
                  IP(dst=l['ip'], src=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * 1, self.pg2)
 
@@ -2946,7 +2949,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst="00:00:00:11:11:11") /
                  IPv6(src=l['ip6'], dst=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -2976,7 +2979,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
                  IPv6(dst=l['ip6'], src=ep.ip6.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
 
@@ -3009,7 +3012,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(dst="10.0.0.99", src=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         self.send_and_assert_no_replies(self.pg0, [p])
 
@@ -3027,14 +3030,14 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(dst=epg_220.bvi_ip4.address, src=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
 
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IPv6(dst=epg_220.bvi_ip6.address, src=ep.ip6.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
 
@@ -3044,7 +3047,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(dst="10.0.0.99", src=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, [p], self.pg4)
         for rx in rxs:
@@ -3075,7 +3078,7 @@ class TestGBP(VppTestCase):
                  Ether(src=l['mac'], dst="00:00:00:11:11:11") /
                  IP(src=l['ip'], dst=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -3136,7 +3139,7 @@ class TestGBP(VppTestCase):
             p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
                  IP(dst=ip, src=ep.ip4.address) /
                  UDP(sport=1234, dport=1234) /
-                 Raw('\xa5' * 100))
+                 Raw(b'\xa5' * 100))
 
             rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
 
@@ -3171,7 +3174,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(self.pg0, [p], self.pg2)
 
         self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
@@ -3179,7 +3182,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(self.pg0, [p], self.pg4)
 
         #
@@ -3213,7 +3216,7 @@ class TestGBP(VppTestCase):
              Ether(src=l['mac'], dst="00:00:00:11:11:11") /
              IP(src="10.0.1.4", dst=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
 
         self.assertTrue(find_gbp_endpoint(self,
@@ -3225,7 +3228,7 @@ class TestGBP(VppTestCase):
         p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
              IP(dst="10.0.1.4", src=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
 
         # host 2 is the DP learned TEP
@@ -3256,7 +3259,7 @@ class TestGBP(VppTestCase):
              Ether(src=l['mac'], dst="00:00:00:11:11:11") /
              IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rx = self.send_and_expect(self.pg2, [p], self.pg0)
 
@@ -3446,19 +3449,19 @@ class TestGBP(VppTestCase):
         p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
                IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100)),
+               Raw(b'\xa5' * 100)),
               (Ether(src=ep3.mac, dst=ep1.mac) /
                IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
         p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
                IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100)),
+               Raw(b'\xa5' * 100)),
               (Ether(src=ep3.mac, dst=ep1.mac) /
                IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
                UDP(sport=1234, dport=1230) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
 
         # should be dropped since no contract yet
         self.send_and_assert_no_replies(self.pg0, [p4[0]])
@@ -3678,19 +3681,19 @@ class TestGBP(VppTestCase):
         p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
                IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100)),
+               Raw(b'\xa5' * 100)),
               (Ether(src=ep2.mac, dst=str(self.router_mac)) /
                IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
         p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
                IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100)),
+               Raw(b'\xa5' * 100)),
               (Ether(src=ep2.mac, dst=str(self.router_mac)) /
                IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
 
         c3 = VppGbpContract(
             self, 402, epg_220.sclass, epg_221.sclass, acl_index,
@@ -3757,7 +3760,7 @@ class TestGBP(VppTestCase):
              Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
              IP(src="10.0.0.88", dst=ep1.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         # unknown remote EP to local EP redirected
         rxs = self.send_and_expect(self.pg7, [p], sep1.itf)
@@ -3782,7 +3785,7 @@ class TestGBP(VppTestCase):
              Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
              IPv6(src="2001:10::88", dst=ep1.ip6.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         # unknown remote EP to local EP redirected (ipv6)
         rxs = self.send_and_expect(self.pg7, [p], sep3.itf)
@@ -3804,11 +3807,11 @@ class TestGBP(VppTestCase):
         p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
                IP(src=ep1.ip4.address, dst="10.0.0.88") /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
         p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
                IPv6(src=ep1.ip6.address, dst="2001:10::88") /
                UDP(sport=1234, dport=1234) /
-               Raw('\xa5' * 100))]
+               Raw(b'\xa5' * 100))]
 
         rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
 
@@ -3971,12 +3974,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=100) /
               IP(src="10.220.0.17", dst="10.221.0.65") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (Ether(src=eep1.mac, dst=self.router_mac) /
               Dot1Q(vlan=100) /
               IPv6(src="10:220::17", dst="10:221::65") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         # packets should be dropped in absence of contract
         self.send_and_assert_no_replies(self.pg0, p)
@@ -4101,11 +4104,11 @@ class TestGBP(VppTestCase):
         p = [(base /
               IP(src="10.0.1.100", dst=ep3.ip4.address) /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (base /
               IPv6(src="2001:10::100", dst=ep3.ip6.address) /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         # unknown remote EP to local EP redirected to known remote SEP
         rxs = self.send_and_expect(self.pg7, p, self.pg7)
@@ -4167,6 +4170,463 @@ class TestGBP(VppTestCase):
         #
         self.pg7.unconfig_ip4()
 
+    def test_gbp_redirect_extended(self):
+        """ GBP Endpoint Redirect Extended """
+
+        self.vapi.cli("set logging class gbp level debug")
+
+        ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
+        routed_dst_mac = "00:0c:0c:0c:0c:0c"
+        routed_src_mac = "00:22:bd:f8:19:ff"
+
+        learnt = [{'mac': '00:00:11:11:11:02',
+                   'ip': '10.0.1.2',
+                   'ip6': '2001:10::2'},
+                  {'mac': '00:00:11:11:11:03',
+                   'ip': '10.0.1.3',
+                   'ip6': '2001:10::3'}]
+
+        #
+        # IP tables
+        #
+        t4 = VppIpTable(self, 1)
+        t4.add_vpp_config()
+        t6 = VppIpTable(self, 1, True)
+        t6.add_vpp_config()
+
+        # create IPv4 and IPv6 RD UU VxLAN-GBP TEP and bind them to the right
+        # VRF
+        rd_uu4 = VppVxlanGbpTunnel(
+            self,
+            self.pg7.local_ip4,
+            self.pg7.remote_ip4,
+            114,
+            mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
+                  VXLAN_GBP_API_TUNNEL_MODE_L3))
+        rd_uu4.add_vpp_config()
+        VppIpInterfaceBind(self, rd_uu4, t4).add_vpp_config()
+
+        rd_uu6 = VppVxlanGbpTunnel(
+            self,
+            self.pg7.local_ip4,
+            self.pg7.remote_ip4,
+            115,
+            mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
+                  VXLAN_GBP_API_TUNNEL_MODE_L3))
+        rd_uu6.add_vpp_config()
+        VppIpInterfaceBind(self, rd_uu6, t4).add_vpp_config()
+
+        rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6, rd_uu4, rd_uu6)
+        rd1.add_vpp_config()
+
+        self.loop0.set_mac(self.router_mac)
+        self.loop1.set_mac(self.router_mac)
+        self.loop2.set_mac(self.router_mac)
+
+        #
+        # Bind the BVI to the RD
+        #
+        VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
+        VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
+        VppIpInterfaceBind(self, self.loop1, t4).add_vpp_config()
+        VppIpInterfaceBind(self, self.loop1, t6).add_vpp_config()
+        VppIpInterfaceBind(self, self.loop2, t4).add_vpp_config()
+        VppIpInterfaceBind(self, self.loop2, t6).add_vpp_config()
+
+        #
+        # Pg7 hosts a BD's UU-fwd
+        #
+        self.pg7.config_ip4()
+        self.pg7.resolve_arp()
+
+        #
+        # a GBP bridge domains for the EPs
+        #
+        bd1 = VppBridgeDomain(self, 1)
+        bd1.add_vpp_config()
+        gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0)
+        gbd1.add_vpp_config()
+
+        bd2 = VppBridgeDomain(self, 2)
+        bd2.add_vpp_config()
+        gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1)
+        gbd2.add_vpp_config()
+
+        # ... and has a /32 and /128 applied
+        ip4_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
+        ip4_addr1.add_vpp_config()
+        ip6_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
+        ip6_addr1.add_vpp_config()
+        ip4_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
+        ip4_addr2.add_vpp_config()
+        ip6_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
+        ip6_addr2.add_vpp_config()
+
+        #
+        # The Endpoint-groups
+        #
+        epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
+                                      None, gbd1.bvi,
+                                      "10.0.0.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",
+                                      VppGbpEndpointRetention(2))
+        epg_221.add_vpp_config()
+
+        #
+        # a GBP bridge domains for the SEPs
+        #
+        bd_uu3 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
+                                   self.pg7.remote_ip4, 116)
+        bd_uu3.add_vpp_config()
+
+        bd3 = VppBridgeDomain(self, 3)
+        bd3.add_vpp_config()
+        gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2,
+                                  bd_uu3, learn=False)
+        gbd3.add_vpp_config()
+
+        ip4_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, "12.0.0.128", 32)
+        ip4_addr3.add_vpp_config()
+        ip6_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, "4001:10::128", 128)
+        ip6_addr3.add_vpp_config()
+
+        #
+        # self.logger.info(self.vapi.cli("show gbp bridge"))
+        # self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
+        # self.logger.info(self.vapi.cli("show gbp vxlan"))
+        # self.logger.info(self.vapi.cli("show int addr"))
+        #
+
+        #
+        # EPGs in which the service endpoints exist
+        #
+        epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
+                                      None, gbd3.bvi,
+                                      "12.0.0.128",
+                                      "4001:10::128",
+                                      VppGbpEndpointRetention(2))
+        epg_320.add_vpp_config()
+
+        #
+        # endpoints
+        #
+        ep1 = VppGbpEndpoint(self, self.pg0,
+                             epg_220, None,
+                             "10.0.0.1", "11.0.0.1",
+                             "2001:10::1", "3001:10::1")
+        ep1.add_vpp_config()
+        ep2 = VppGbpEndpoint(self, self.pg1,
+                             epg_221, None,
+                             "10.0.1.1", "11.0.1.1",
+                             "2001:11::1", "3001:11::1")
+        ep2.add_vpp_config()
+
+        #
+        # service endpoints
+        #
+        sep1 = VppGbpEndpoint(self, self.pg3,
+                              epg_320, None,
+                              "12.0.0.1", "13.0.0.1",
+                              "4001:10::1", "5001:10::1")
+        sep2 = VppGbpEndpoint(self, self.pg4,
+                              epg_320, None,
+                              "12.0.0.2", "13.0.0.2",
+                              "4001:10::2", "5001:10::2")
+
+        # sep1 and sep2 are not added to config yet
+        # they are unknown for now
+
+        #
+        # add routes to EPG subnets
+        #
+        VppGbpSubnet(self, rd1, "10.0.0.0", 24,
+                     VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT
+                     ).add_vpp_config()
+        VppGbpSubnet(self, rd1, "10.0.1.0", 24,
+                     VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT
+                     ).add_vpp_config()
+
+        #
+        # Local host to known local host in different BD
+        # with SFC contract (source and destination are in
+        # one node and service endpoint in another node)
+        #
+        p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
+               IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
+               UDP(sport=1234, dport=1234) /
+               Raw(b'\xa5' * 100)),
+              (Ether(src=ep2.mac, dst=str(self.router_mac)) /
+               IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
+               UDP(sport=1234, dport=1234) /
+               Raw(b'\xa5' * 100))]
+        p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
+               IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
+               UDP(sport=1234, dport=1234) /
+               Raw(b'\xa5' * 100)),
+              (Ether(src=ep2.mac, dst=str(self.router_mac)) /
+               IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
+               UDP(sport=1234, dport=1230) /
+               Raw(b'\xa5' * 100))]
+
+        # should be dropped since no contract yet
+        self.send_and_assert_no_replies(self.pg0, [p4[0]])
+        self.send_and_assert_no_replies(self.pg0, [p6[0]])
+
+        #
+        # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
+        # one of the next-hops is via an EP that is not known
+        #
+        acl = VppGbpAcl(self)
+        rule4 = acl.create_rule(permit_deny=1, proto=17)
+        rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
+        acl_index = acl.add_vpp_config([rule4, rule6])
+
+        #
+        # test the src-ip hash mode
+        #
+        c1 = VppGbpContract(
+            self, 402, epg_220.sclass, epg_221.sclass, 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,
+                [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
+                                       sep1.ip4, sep1.epg.rd)]),
+             VppGbpContractRule(
+                VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
+                VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
+                [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
+                                       sep1.ip6, sep1.epg.rd)])],
+            [ETH_P_IP, ETH_P_IPV6])
+        c1.add_vpp_config()
+
+        c2 = VppGbpContract(
+            self, 402, epg_221.sclass, epg_220.sclass, 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,
+                [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
+                                       sep1.ip4, sep1.epg.rd)]),
+             VppGbpContractRule(
+                VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
+                VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
+                [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
+                                       sep1.ip6, sep1.epg.rd)])],
+            [ETH_P_IP, ETH_P_IPV6])
+        c2.add_vpp_config()
+
+        # ep1 <--> ep2 redirected through sep1
+        # sep1 is unknown
+        # packet is redirected to sep bd and then go through sep bd UU
+
+        rxs = self.send_and_expect(self.pg0, p4[0] * 17, self.pg7)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, self.pg7.local_mac)
+            self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
+            self.assertEqual(rx[IP].src, self.pg7.local_ip4)
+            self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
+            self.assertEqual(rx[VXLAN].vni, 116)
+            self.assertTrue(rx[VXLAN].flags.G)
+            self.assertTrue(rx[VXLAN].flags.Instance)
+            # redirect policy has been applied
+            self.assertTrue(rx[VXLAN].gpflags.A)
+            self.assertFalse(rx[VXLAN].gpflags.D)
+
+            inner = rx[VXLAN].payload
+
+            self.assertEqual(inner[Ether].src, routed_src_mac)
+            self.assertEqual(inner[Ether].dst, sep1.mac)
+            self.assertEqual(inner[IP].src, ep1.ip4.address)
+            self.assertEqual(inner[IP].dst, ep2.ip4.address)
+
+        rxs = self.send_and_expect(self.pg1, p4[1] * 17, self.pg7)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, self.pg7.local_mac)
+            self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
+            self.assertEqual(rx[IP].src, self.pg7.local_ip4)
+            self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
+            self.assertEqual(rx[VXLAN].vni, 116)
+            self.assertTrue(rx[VXLAN].flags.G)
+            self.assertTrue(rx[VXLAN].flags.Instance)
+            # redirect policy has been applied
+            self.assertTrue(rx[VXLAN].gpflags.A)
+            self.assertFalse(rx[VXLAN].gpflags.D)
+
+            inner = rx[VXLAN].payload
+
+            self.assertEqual(inner[Ether].src, routed_src_mac)
+            self.assertEqual(inner[Ether].dst, sep1.mac)
+            self.assertEqual(inner[IP].src, ep2.ip4.address)
+            self.assertEqual(inner[IP].dst, ep1.ip4.address)
+
+        rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, self.pg7.local_mac)
+            self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
+            self.assertEqual(rx[IP].src, self.pg7.local_ip4)
+            self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
+            self.assertEqual(rx[VXLAN].vni, 116)
+            self.assertTrue(rx[VXLAN].flags.G)
+            self.assertTrue(rx[VXLAN].flags.Instance)
+            # redirect policy has been applied
+            inner = rx[VXLAN].payload
+
+            self.assertEqual(inner[Ether].src, routed_src_mac)
+            self.assertEqual(inner[Ether].dst, sep1.mac)
+            self.assertEqual(inner[IPv6].src, ep1.ip6.address)
+            self.assertEqual(inner[IPv6].dst, ep2.ip6.address)
+
+        rxs = self.send_and_expect(self.pg1, p6[1] * 17, self.pg7)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, self.pg7.local_mac)
+            self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
+            self.assertEqual(rx[IP].src, self.pg7.local_ip4)
+            self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
+            self.assertEqual(rx[VXLAN].vni, 116)
+            self.assertTrue(rx[VXLAN].flags.G)
+            self.assertTrue(rx[VXLAN].flags.Instance)
+            # redirect policy has been applied
+            self.assertTrue(rx[VXLAN].gpflags.A)
+            self.assertFalse(rx[VXLAN].gpflags.D)
+
+            inner = rx[VXLAN].payload
+
+            self.assertEqual(inner[Ether].src, routed_src_mac)
+            self.assertEqual(inner[Ether].dst, sep1.mac)
+            self.assertEqual(inner[IPv6].src, ep2.ip6.address)
+            self.assertEqual(inner[IPv6].dst, ep1.ip6.address)
+
+        # configure sep1: it is now local
+        # packets between ep1 and ep2 are redirected locally
+        sep1.add_vpp_config()
+
+        rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, routed_src_mac)
+            self.assertEqual(rx[Ether].dst, sep1.mac)
+            self.assertEqual(rx[IP].src, ep1.ip4.address)
+            self.assertEqual(rx[IP].dst, ep2.ip4.address)
+
+        rxs = self.send_and_expect(self.pg1, p6[1] * 17, sep1.itf)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, routed_src_mac)
+            self.assertEqual(rx[Ether].dst, sep1.mac)
+            self.assertEqual(rx[IPv6].src, ep2.ip6.address)
+            self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
+
+        # packet coming from the l2 spine-proxy to sep1
+        p = (Ether(src=self.pg7.remote_mac,
+                   dst=self.pg7.local_mac) /
+             IP(src=self.pg7.remote_ip4,
+                dst=self.pg7.local_ip4) /
+             UDP(sport=1234, dport=48879) /
+             VXLAN(vni=116, gpid=440, gpflags=0x08, flags=0x88) /
+             Ether(src=str(self.router_mac), dst=sep1.mac) /
+             IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
+             UDP(sport=1234, dport=1234) /
+             Raw(b'\xa5' * 100))
+
+        rxs = self.send_and_expect(self.pg7, [p] * 17, sep1.itf)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, str(self.router_mac))
+            self.assertEqual(rx[Ether].dst, sep1.mac)
+            self.assertEqual(rx[IP].src, ep1.ip4.address)
+            self.assertEqual(rx[IP].dst, ep2.ip4.address)
+
+        # contract for SEP to communicate with dst EP
+        c3 = VppGbpContract(
+            self, 402, epg_320.sclass, epg_221.sclass, acl_index,
+            [VppGbpContractRule(
+                VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
+                VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC),
+             VppGbpContractRule(
+                VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
+                VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC)],
+            [ETH_P_IP, ETH_P_IPV6])
+        c3.add_vpp_config()
+
+        # temporarily remove ep2, so that ep2 is remote & unknown
+        ep2.remove_vpp_config()
+
+        # packet going back from sep1 to its original dest (ep2)
+        # as ep2 is now unknown (see above), it must go through
+        # the rd UU (packet is routed)
+
+        p1 = (Ether(src=sep1.mac, dst=self.router_mac) /
+              IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
+              UDP(sport=1234, dport=1234) /
+              Raw(b'\xa5' * 100))
+
+        rxs = self.send_and_expect(self.pg3, [p1] * 17, self.pg7)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, self.pg7.local_mac)
+            self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
+            self.assertEqual(rx[IP].src, self.pg7.local_ip4)
+            self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
+            self.assertEqual(rx[VXLAN].vni, 114)
+            self.assertTrue(rx[VXLAN].flags.G)
+            self.assertTrue(rx[VXLAN].flags.Instance)
+            # redirect policy has been applied
+            inner = rx[VXLAN].payload
+            self.assertEqual(inner[Ether].src, routed_src_mac)
+            self.assertEqual(inner[Ether].dst, routed_dst_mac)
+            self.assertEqual(inner[IP].src, ep1.ip4.address)
+            self.assertEqual(inner[IP].dst, ep2.ip4.address)
+
+        self.logger.info(self.vapi.cli("show bridge 3 detail"))
+        sep1.remove_vpp_config()
+
+        self.logger.info(self.vapi.cli("show bridge 1 detail"))
+        self.logger.info(self.vapi.cli("show bridge 2 detail"))
+
+        # re-add ep2: it is local again :)
+        ep2.add_vpp_config()
+
+        # packet coming back from the remote sep through rd UU
+        p2 = (Ether(src=self.pg7.remote_mac,
+                    dst=self.pg7.local_mac) /
+              IP(src=self.pg7.remote_ip4,
+                 dst=self.pg7.local_ip4) /
+              UDP(sport=1234, dport=48879) /
+              VXLAN(vni=114, gpid=441, gpflags=0x09, flags=0x88) /
+              Ether(src=str(self.router_mac), dst=self.router_mac) /
+              IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
+              UDP(sport=1234, dport=1234) /
+              Raw(b'\xa5' * 100))
+
+        rxs = self.send_and_expect(self.pg7, [p2], self.pg1)
+
+        for rx in rxs:
+            self.assertEqual(rx[Ether].src, str(self.router_mac))
+            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
+            self.assertEqual(rx[IP].src, ep1.ip4.address)
+            self.assertEqual(rx[IP].dst, ep2.ip4.address)
+
+        #
+        # bd_uu2.add_vpp_config()
+        #
+
+        #
+        # cleanup
+        #
+        c1.remove_vpp_config()
+        c2.remove_vpp_config()
+        c3.remove_vpp_config()
+        self.pg7.unconfig_ip4()
+
     def test_gbp_l3_out(self):
         """ GBP L3 Out """
 
@@ -4333,12 +4793,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=100) /
               IP(src="10.0.0.1", dst="10.0.0.88") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100))
+              Raw(b'\xa5' * 100))
         p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
               Dot1Q(vlan=100) /
               IPv6(src="2001:10::1", dst="2001:10::88") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100))
+              Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
 
@@ -4371,7 +4831,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.0.0.101", dst="10.0.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
 
@@ -4490,10 +4950,12 @@ class TestGBP(VppTestCase):
             self, 44, 4220, 4221, acl_index,
             [VppGbpContractRule(
                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
+                VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
                 []),
-                VppGbpContractRule(
-                    VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
-                    [])],
+             VppGbpContractRule(
+                 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
+                 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
+                 [])],
             [ETH_P_IP, ETH_P_IPV6])
         c_44.add_vpp_config()
         self.send_and_assert_no_replies(self.pg0, p * 1)
@@ -4546,7 +5008,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.221.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
 
@@ -4571,7 +5033,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.0.0.101", dst="10.220.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
 
@@ -4582,7 +5044,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst=rep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
 
@@ -4653,7 +5115,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.222.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
 
@@ -4680,7 +5142,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.222.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
 
@@ -4734,12 +5196,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=100) /
               IP(src="10.220.0.1", dst="10.222.0.1") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (Ether(src=eep1.mac, dst=str(self.router_mac)) /
               Dot1Q(vlan=100) /
               IP(src="10.220.0.1", dst="10.222.0.1") /
               UDP(sport=1222, dport=1235) /
-             Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         rxs = self.send_and_expect(self.pg0, p, self.pg7)
 
@@ -4778,12 +5240,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=100) /
               IPv6(src="10:220::1", dst="10:222::1") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (Ether(src=eep1.mac, dst=str(self.router_mac)) /
               Dot1Q(vlan=100) /
               IPv6(src="10:220::1", dst="10:222::1") /
               UDP(sport=7777, dport=8881) /
-             Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1"))
         rxs = self.send_and_expect(self.pg0, p, self.pg7)
@@ -4802,7 +5264,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.222.0.1", dst="10.220.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
         self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
@@ -4818,7 +5280,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.222.0.1", dst="10.222.0.2") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
 
@@ -4829,7 +5291,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IPv6(src="10:222::1", dst="10:222::2") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
 
@@ -4849,7 +5311,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=144) /
              IP(src=lep1.ip4.address, dst="10.220.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
 
@@ -4865,7 +5327,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=144) /
              IPv6(src=lep1.ip6.address, dst="10:220::1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
 
@@ -4913,12 +5375,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=144) /
               IPv6(src=lep1.ip6.address, dst="10:20::1") /
               UDP(sport=1234, dport=1234) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (Ether(src=lep1.mac, dst=str(self.router_mac)) /
               Dot1Q(vlan=144) /
               IPv6(src=lep1.ip6.address, dst="10:20::1") /
               UDP(sport=124, dport=1230) /
-              Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
 
@@ -4930,12 +5392,12 @@ class TestGBP(VppTestCase):
               Dot1Q(vlan=144) /
               IP(src=lep1.ip4.address, dst="10.20.0.1") /
               UDP(sport=1235, dport=1235) /
-              Raw('\xa5' * 100)),
+              Raw(b'\xa5' * 100)),
              (Ether(src=lep1.mac, dst=str(self.router_mac)) /
               Dot1Q(vlan=144) /
               IP(src=lep1.ip4.address, dst="10.20.0.1") /
               UDP(sport=124, dport=1230) /
-              Raw('\xa5' * 100))]
+              Raw(b'\xa5' * 100))]
 
         rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
 
@@ -5089,7 +5551,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src=str(rep.ip4), dst="10.0.0.100") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
         rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
 
         #
@@ -5220,7 +5682,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.221.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
 
@@ -5245,7 +5707,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src=rep.ip4.address, dst="10.220.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
 
@@ -5256,7 +5718,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst=rep.ip4.address) /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
 
@@ -5328,7 +5790,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.222.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
 
@@ -5355,7 +5817,7 @@ class TestGBP(VppTestCase):
              Dot1Q(vlan=100) /
              IP(src="10.220.0.1", dst="10.222.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
 
@@ -5389,7 +5851,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.222.0.1", dst="10.220.0.1") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
         self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
@@ -5405,7 +5867,7 @@ class TestGBP(VppTestCase):
              Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
              IP(src="10.222.0.1", dst="10.222.0.2") /
              UDP(sport=1234, dport=1234) /
-             Raw('\xa5' * 100))
+             Raw(b'\xa5' * 100))
 
         rxs = self.send_and_assert_no_replies(self.pg7, p * 3)