From a45e7e316af1462815906e79cff504d73f8ec825 Mon Sep 17 00:00:00 2001 From: Sachin Bansal Date: Thu, 11 Jun 2015 11:17:40 -0700 Subject: [PATCH] Fix multiple issues with ibgp auto mesh 1. vendor name was not being initialized 2. router asn change and global asn change need to be handled differently 3. create peering among all routers with asn same as global Change-Id: I1589e10ece9575f935b9e78ca1d6f41192dc1463 Closes-Bug: 1463771 --- .../schema-transformer/test/test_service.py | 57 ++++++++++++++++++ src/config/schema-transformer/to_bgp.py | 58 +++++++++++-------- 2 files changed, 91 insertions(+), 24 deletions(-) diff --git a/src/config/schema-transformer/test/test_service.py b/src/config/schema-transformer/test/test_service.py index 5cb2cc6825f..7e0b8b59b10 100644 --- a/src/config/schema-transformer/test/test_service.py +++ b/src/config/schema-transformer/test/test_service.py @@ -680,4 +680,61 @@ def test_logical_router(self): self.check_vn_is_deleted(uuid=vn1_obj.uuid) self._vnc_lib.logical_router_delete(id=lr.uuid) + @retries(5, hook=retry_exc_handler) + def check_bgp_peering(self, router1, router2, length): + r1 = self._vnc_lib.bgp_router_read(fq_name=router1.get_fq_name()) + ref_names = [ref['to'] for ref in r1.get_bgp_router_refs() or []] + self.assertEqual(len(ref_names), length) + self.assertThat(ref_names, Contains(router2.get_fq_name())) + + def create_bgp_router(self, name, vendor, asn=None): + ip_fabric_ri = self._vnc_lib.routing_instance_read( + fq_name=['default-domain', 'default-project', 'ip-fabric', '__default__']) + router = BgpRouter(name, parent_obj=ip_fabric_ri) + params = BgpRouterParams() + params.vendor = 'contrail' + params.autonomous_system = asn + router.set_bgp_router_parameters(params) + self._vnc_lib.bgp_router_create(router) + return router + + def test_ibgp_auto_mesh(self): + + # create router1 + r1_name = self.id() + 'router1' + router1 = self.create_bgp_router(r1_name, 'contrail') + + # create router2 + r2_name = self.id() + 'router2' + router2 = self.create_bgp_router(r2_name, 'contrail') + + self.check_bgp_peering(router1, router2, 1) + + r3_name = self.id() + 'router3' + router3 = self.create_bgp_router(r3_name, 'juniper', 1) + + self.check_bgp_peering(router1, router2, 1) + + params = router3.get_bgp_router_parameters() + params.autonomous_system = 64512 + router3.set_bgp_router_parameters(params) + self._vnc_lib.bgp_router_update(router3) + + self.check_bgp_peering(router1, router3, 2) + + r4_name = self.id() + 'router4' + router4 = self.create_bgp_router(r4_name, 'juniper', 1) + + gsc = self._vnc_lib.global_system_config_read( + fq_name=['default-global-system-config']) + + gsc.set_autonomous_system(1) + self.check_bgp_peering(router1, router4, 3) + + self._vnc_lib.bgp_router_delete(id=router1.uuid) + self._vnc_lib.bgp_router_delete(id=router2.uuid) + self._vnc_lib.bgp_router_delete(id=router3.uuid) + self._vnc_lib.bgp_router_delete(id=router4.uuid) + gevent.sleep(1) + # end class TestRouteTable diff --git a/src/config/schema-transformer/to_bgp.py b/src/config/schema-transformer/to_bgp.py index fa143cfa860..f911cfee1d3 100644 --- a/src/config/schema-transformer/to_bgp.py +++ b/src/config/schema-transformer/to_bgp.py @@ -382,13 +382,13 @@ def update_autonomous_system(cls, new_asn): pass # end for vn + cls._autonomous_system = int(new_asn) for router in BgpRouterST.values(): - router.update_autonomous_system(new_asn) + router.update_global_asn(new_asn) # end for router for router in LogicalRouterST.values(): router.update_autonomous_system(new_asn) # end for router - cls._autonomous_system = int(new_asn) # end update_autonomous_system def add_policy(self, policy_name, attrib=None): @@ -2011,11 +2011,11 @@ def update_acl_entries(self, acl_entries): class BgpRouterST(DictST): _dict = {} _ibgp_auto_mesh = None - def __init__(self, name): + def __init__(self, name, params): self.name = name - self.vendor = None + self.vendor = (params.vendor or 'contrail').lower() self.asn = None - self.identifier = None + self.identifier = params.identifier if self._ibgp_auto_mesh is None: gsc = _vnc_lib.global_system_config_read( @@ -2023,7 +2023,6 @@ def __init__(self, name): self._ibgp_auto_mesh = gsc.get_ibgp_auto_mesh() if self._ibgp_auto_mesh is None: self._ibgp_auto_mesh = True - # end __init__ @classmethod @@ -2032,20 +2031,27 @@ def delete(cls, name): del cls._dict[name] # end delete - def update_autonomous_system(self, asn): - if self.vendor not in ["contrail", None]: - self.asn = asn - return - my_asn = int(VirtualNetworkST.get_autonomous_system()) - if asn == my_asn: - self.asn = asn - self.update_peering() + def set_params(self, params): + if self.vendor == 'contrail': + self.update_global_asn(VirtualNetworkST.get_autonomous_system()) + else: + self.update_autonomous_system(params.autonomous_system) + # end set_params + + def update_global_asn(self, asn): + if self.vendor != 'contrail' or self.asn == int(asn): return - bgp_router_obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) - params = bgp_router_obj.get_bgp_router_parameters() + router_obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) + params = router_obj.get_bgp_router_parameters() params.autonomous_system = int(asn) - bgp_router_obj.set_bgp_router_parameters(params) - _vnc_lib.bgp_router_update(bgp_router_obj) + router_obj.set_bgp_router_parameters(params) + _vnc_lib.bgp_router_update(router_obj) + self.update_autonomous_system(asn) + # end update_global_asn + + def update_autonomous_system(self, asn): + if self.asn == int(asn): + return self.asn = int(asn) self.update_peering() # end update_autonomous_system @@ -2064,8 +2070,8 @@ def update_ibgp_auto_mesh(cls, value): def update_peering(self): if not self._ibgp_auto_mesh: return - my_asn = int(VirtualNetworkST.get_autonomous_system()) - if self.asn != my_asn: + global_asn = int(VirtualNetworkST.get_autonomous_system()) + if self.asn != global_asn: return try: obj = _vnc_lib.bgp_router_read(fq_name_str=self.name) @@ -2074,14 +2080,14 @@ def update_peering(self): "%s: %s", self.name, str(e)) return + peerings = [ref['to'] for ref in (obj.get_bgp_router_refs() or [])] for router in self._dict.values(): if router.name == self.name: continue - if router.asn != my_asn: + if router.asn != global_asn: continue router_fq_name = router.name.split(':') - if (router_fq_name in - [ref['to'] for ref in (obj.get_bgp_router_refs() or [])]): + if router_fq_name in peerings: continue router_obj = BgpRouter() router_obj.fq_name = router_fq_name @@ -3123,7 +3129,11 @@ def delete_configured_route_target_list(self, idents, meta): def add_bgp_router_parameters(self, idents, meta): router_name = idents['bgp-router'] - router = BgpRouterST.locate(router_name) + params = BgpRouterParams() + params.build(meta) + router = BgpRouterST.locate(router_name, params) + if router: + router.set_params(params) # end add_bgp_router_parameters def delete_bgp_router_parameters(self, idents, meta):