From ef90ed08fbcde7535b4a789349b39dc25798c77d Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 13 Sep 2018 08:45:12 -0700 Subject: BIER API and load-balancing fixes Change-Id: Ibda19d786070c942c75016ab568c8361de2f24af Signed-off-by: Neale Ranns --- test/test_bier.py | 94 +++++++++++++++++++++++++++++++++++++++++++++++ test/vpp_bier.py | 77 ++++++++++++++++++++++++++++---------- test/vpp_ip_route.py | 3 ++ test/vpp_papi_provider.py | 6 ++- 4 files changed, 159 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/test_bier.py b/test/test_bier.py index 0276f95c4fc..9a1967cc459 100644 --- a/test/test_bier.py +++ b/test/test_bier.py @@ -202,6 +202,100 @@ class TestBier(VppTestCase): """BIER midpoint BSL:64""" self.bier_midpoint(BIERLength.BIER_LEN_64, 8, 64) + def test_bier_load_balance(self): + """BIER load-balance""" + + # + # Add a BIER table for sub-domain 0, set 0, and BSL 256 + # + bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_64) + bt = VppBierTable(self, bti, 77) + bt.add_vpp_config() + + # + # packets with varying entropy + # + pkts = [] + for ii in range(257): + pkts.append((Ether(dst=self.pg0.local_mac, + src=self.pg0.remote_mac) / + MPLS(label=77, ttl=255) / + BIER(length=BIERLength.BIER_LEN_64, + entropy=ii, + BitString=chr(255)*16) / + IPv6(src=self.pg0.remote_ip6, + dst=self.pg0.remote_ip6) / + UDP(sport=1234, dport=1234) / + Raw())) + + # + # 4 next hops + # + nhs = [{'ip': "10.0.0.1", 'label': 201}, + {'ip': "10.0.0.2", 'label': 202}, + {'ip': "10.0.0.3", 'label': 203}, + {'ip': "10.0.0.4", 'label': 204}] + + for nh in nhs: + ipr = VppIpRoute( + self, nh['ip'], 32, + [VppRoutePath(self.pg1.remote_ip4, + self.pg1.sw_if_index, + labels=[VppMplsLabel(nh['label'])])]) + ipr.add_vpp_config() + + bier_route = VppBierRoute( + self, bti, 1, + [VppRoutePath(nhs[0]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)]), + VppRoutePath(nhs[1]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)])]) + bier_route.add_vpp_config() + + rx = self.send_and_expect(self.pg0, pkts, self.pg1) + + # + # we should have recieved a packet from each neighbor + # + for nh in nhs[:2]: + self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx)) + + # + # add the other paths + # + bier_route.update_paths( + [VppRoutePath(nhs[0]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)]), + VppRoutePath(nhs[1]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)]), + VppRoutePath(nhs[2]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)]), + VppRoutePath(nhs[3]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)])]) + + rx = self.send_and_expect(self.pg0, pkts, self.pg1) + for nh in nhs: + self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx)) + + # + # remove first two paths + # + bier_route.remove_path(VppRoutePath(nhs[0]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)])) + bier_route.remove_path(VppRoutePath(nhs[1]['ip'], 0xffffffff, + labels=[VppMplsLabel(101)])) + + rx = self.send_and_expect(self.pg0, pkts, self.pg1) + for nh in nhs[2:]: + self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx)) + + # + # remove the last of the paths, deleteing the entry + # + bier_route.remove_all_paths() + + self.send_and_assert_no_replies(self.pg0, pkts) + def test_bier_head(self): """BIER head""" diff --git a/test/vpp_bier.py b/test/vpp_bier.py index 88dd79ce3b7..f389ca1b979 100644 --- a/test/vpp_bier.py +++ b/test/vpp_bier.py @@ -120,28 +120,31 @@ class VppBierRoute(VppObject): self.bp = bp self.paths = paths + def encode_path(self, p): + lstack = [] + for l in p.nh_labels: + if type(l) == VppMplsLabel: + lstack.append(l.encode()) + else: + lstack.append({'label': l, 'ttl': 255}) + n_labels = len(lstack) + while (len(lstack) < 16): + lstack.append({}) + return {'next_hop': p.nh_addr, + 'weight': 1, + 'afi': p.proto, + 'sw_if_index': 0xffffffff, + 'preference': 0, + 'table_id': p.nh_table_id, + 'next_hop_id': p.next_hop_id, + 'is_udp_encap': p.is_udp_encap, + 'n_labels': n_labels, + 'label_stack': lstack} + def encode_paths(self): br_paths = [] for p in self.paths: - lstack = [] - for l in p.nh_labels: - if type(l) == VppMplsLabel: - lstack.append(l.encode()) - else: - lstack.append({'label': l, 'ttl': 255}) - n_labels = len(lstack) - while (len(lstack) < 16): - lstack.append({}) - br_paths.append({'next_hop': p.nh_addr, - 'weight': 1, - 'afi': p.proto, - 'sw_if_index': 0xffffffff, - 'preference': 0, - 'table_id': p.nh_table_id, - 'next_hop_id': p.next_hop_id, - 'is_udp_encap': p.is_udp_encap, - 'n_labels': n_labels, - 'label_stack': lstack}) + br_paths.append(self.encode_path(p)) return br_paths def add_vpp_config(self): @@ -159,6 +162,42 @@ class VppBierRoute(VppObject): self.encode_paths(), is_add=0) + def update_paths(self, paths): + self.paths = paths + self._test.vapi.bier_route_add_del( + self.tbl_id, + self.bp, + self.encode_paths(), + is_replace=1) + + def add_path(self, path): + self._test.vapi.bier_route_add_del( + self.tbl_id, + self.bp, + [self.encode_path(path)], + is_add=1, + is_replace=0) + self.paths.append(path) + self._test.registry.register(self, self._test.logger) + + def remove_path(self, path): + self._test.vapi.bier_route_add_del( + self.tbl_id, + self.bp, + [self.encode_path(path)], + is_add=0, + is_replace=0) + self.paths.remove(path) + + def remove_all_paths(self): + self._test.vapi.bier_route_add_del( + self.tbl_id, + self.bp, + [], + is_add=0, + is_replace=1) + self.paths = [] + def __str__(self): return self.object_id() diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py index 9d6bfb77d93..18c27ffa942 100644 --- a/test/vpp_ip_route.py +++ b/test/vpp_ip_route.py @@ -192,6 +192,9 @@ class VppRoutePath(object): 'n_labels': len(self.nh_labels), 'label_stack': self.encode_labels()} + def __eq__(self, other): + return self.nh_addr == other.nh_addr + class VppMRoutePath(VppRoutePath): diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 61d80b21fb5..5ff7db990c0 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -3147,7 +3147,8 @@ class VppPapiProvider(object): bti, bp, paths, - is_add=1): + is_add=1, + is_replace=0): """ BIER Route add/del """ return self.api( self.papi.bier_route_add_del, @@ -3157,7 +3158,8 @@ class VppPapiProvider(object): 'br_bp': bp, 'br_n_paths': len(paths), 'br_paths': paths, - 'br_is_add': is_add}) + 'br_is_add': is_add, + 'br_is_replace': is_replace}) def bier_route_dump(self, bti): return self.api( -- cgit 1.2.3-korg