From ccb39bfd335454e873e0c5e2b46c3c1a81628b9d Mon Sep 17 00:00:00 2001 From: Kamlesh Parmar Date: Tue, 19 Jun 2018 14:50:21 -0700 Subject: [PATCH] Add evpn type-5 route related configuration for DM. No end user configuration is required. Change-Id: I4860f5aff822ad145f8b3426efdb3d7abf8da2dc Closes-Bug: #1774546 --- .../plugins/juniper/qfx/qfx_conf.py | 27 +++++++++++--- .../plugins/juniper/qfx/series10K/qfx_10k.py | 10 ++++-- .../device_schema/juniper/juniper_common.xsd | 10 ++++++ .../device-manager/test/test_dm_qfx_basic.py | 36 ++++++++++++++++++- 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/config/device-manager/device_manager/plugins/juniper/qfx/qfx_conf.py b/src/config/device-manager/device_manager/plugins/juniper/qfx/qfx_conf.py index d915a3b3270..6184edd9dea 100644 --- a/src/config/device-manager/device_manager/plugins/juniper/qfx/qfx_conf.py +++ b/src/config/device-manager/device_manager/plugins/juniper/qfx/qfx_conf.py @@ -233,6 +233,10 @@ def add_routing_instance(self, ri_conf): self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) + lr_uuid = None + if is_internal_vn: + lr_uuid = DMUtils.extract_lr_uuid_from_internal_vn_name(ri_name) + # add policies for export route targets if self.is_spine(): ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) @@ -279,14 +283,24 @@ def add_routing_instance(self, ri_conf): self.build_l2_evpn_interface_config(interfaces_config, interfaces, vn, vlan_conf) - if (not is_l2 and vni is not None and + if (not is_l2 and (vni is not None or (is_internal_vn and lr_uuid)) and \ self.is_family_configured(self.bgp_params, "e-vpn")): - ri.set_vtep_source_interface("lo0.0") - evpn = self.build_evpn_config() + evpn = self.build_evpn_config(int_vn = is_internal_vn) if evpn: ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) - #add vlans - self.add_ri_vlan_config(ri, vni) + if is_internal_vn and lr_uuid: + ip_prefix_support = IpPrefixSupport() + #ip_prefix_support.set_forwarding_mode("symmetric") + ip_prefix_support.set_encapsulation("vxlan") + ip_prefix_support.set_vni(str(vni)) + ip_prefix_support.set_advertise("direct-nexthop") + evpn.set_ip_prefix_support(ip_prefix_support) + else: + ri.set_vtep_source_interface("lo0.0") + if not is_internal_vn: + #add vlans + self.add_ri_vlan_config(ri, vni) + if (not is_l2 and not is_l2_l3 and gateways): interfaces_config = self.interfaces_config or \ @@ -918,6 +932,7 @@ def build_ri_config(self): ri_conf['network_id'] = vn_obj.vn_network_id self.add_routing_instance(ri_conf) + is_internal_vn = True if '_contrail_lr_internal_vn_' in vn_obj.name else False if vn_obj.get_forwarding_mode() in ['l3'] and self.is_l3_supported(vn_obj): interfaces = [] lo0_ips = vn_irb_ip_map['lo0'].get(vn_id, []) @@ -928,6 +943,8 @@ def build_ri_config(self): ri_conf['export_targets'] = export_set ri_conf['prefixes'] = vn_obj.get_prefixes() ri_conf['interfaces'] = interfaces + if is_internal_vn: + ri_conf['vni'] = vn_obj.get_vxlan_vni() ri_conf['gateways'] = lo0_ips ri_conf['network_id'] = vn_obj.vn_network_id self.add_routing_instance(ri_conf) diff --git a/src/config/device-manager/device_manager/plugins/juniper/qfx/series10K/qfx_10k.py b/src/config/device-manager/device_manager/plugins/juniper/qfx/series10K/qfx_10k.py index 104ec0c7abc..fa525a189af 100644 --- a/src/config/device-manager/device_manager/plugins/juniper/qfx/series10K/qfx_10k.py +++ b/src/config/device-manager/device_manager/plugins/juniper/qfx/series10K/qfx_10k.py @@ -29,9 +29,13 @@ def register(cls): return super(Qfx10kConf, cls).register(qconf) # end register - def build_evpn_config(self): - evpn = Evpn(encapsulation='vxlan') - if self.is_spine(): + def build_evpn_config(self, int_vn = False): + # for internal VN (intervxlan routing) do not set anything + if not int_vn: + evpn = Evpn(encapsulation='vxlan') + else: + evpn = Evpn() + if self.is_spine() and not int_vn: evpn.set_default_gateway("no-gateway-community") return evpn # end build_evpn_config diff --git a/src/config/device-manager/device_schema/juniper/juniper_common.xsd b/src/config/device-manager/device_schema/juniper/juniper_common.xsd index 534d18997c1..69e8799b822 100644 --- a/src/config/device-manager/device_schema/juniper/juniper_common.xsd +++ b/src/config/device-manager/device_schema/juniper/juniper_common.xsd @@ -495,6 +495,15 @@ targetNamespace="http://www.juniper.net/2016/device-config/0"> + + + + + + + + + @@ -504,6 +513,7 @@ targetNamespace="http://www.juniper.net/2016/device-config/0"> + diff --git a/src/config/device-manager/test/test_dm_qfx_basic.py b/src/config/device-manager/test/test_dm_qfx_basic.py index ac2f809ad78..876aa7890e8 100644 --- a/src/config/device-manager/test/test_dm_qfx_basic.py +++ b/src/config/device-manager/test/test_dm_qfx_basic.py @@ -305,6 +305,38 @@ def check_spine_bogus_lo0_ip(self, int_vn): raise Exception("Lo0 Interface unit not found") # end check_spine_bogus_lo0_ip + @retries(5, hook=retry_exc_handler) + def check_spine_evpn_type5_config(self, int_vn, lr_obj): + vrf_name = DMUtils.make_vrf_name(int_vn.fq_name[-1], + int_vn.virtual_network_network_id, "l3") + config = FakeDeviceConnect.get_xml_config() + ris = self.get_routing_instances(config, vrf_name) + if not ris: + raise Exception("No RI Config found for internal vn %s" %vrf_name) + ri = ris[0] + internal_vn_name = DMUtils.get_lr_internal_vn_name(lr_obj.uuid) + vn_fq = lr_obj.get_fq_name()[:-1] + [internal_vn_name] + vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq) + vn_obj_properties = vn_obj.get_virtual_network_properties() + # check ri has protocol evpn + if not ri.protocols: + raise Exception("protocol not present in internal vn %s" %vrf_name) + if not ri.protocols.evpn: + raise Exception("evpn not present in ri_protocols for internal vn \ + %s" %vrf_name) + # get ip_prefix config + ip_pfx_obj = ri.protocols.evpn.ip_prefix_support + vnc_vni = vn_obj_properties.vxlan_network_identifier + if ip_pfx_obj.encapsulation != "vxlan": + raise Exception("vxlan encaps not set in ip_prefix for int vn \ + %s" %vrf_name) + if (ip_pfx_obj.vni != '1111') or (vnc_vni != '1111'): + raise Exception("vni mismatch for int vn %s: \ + in vnc %s, confiugured %s" %(vrf_name, + vnc_vni, + ip_pfx_obj.vni)) + # end check_spine_evpn_type5_config + @retries(5, hook=retry_exc_handler) def check_spine_irb_config(self, int_vn, vn_obj): vrf_name = DMUtils.make_vrf_name(int_vn.fq_name[-1], @@ -900,7 +932,7 @@ def verify_dm_qfx_switch_options(self, product, role=None): self._vnc_lib.virtual_machine_interface_create(vmi1) fq_name = ['default-domain', 'default-project', 'lr1' + self.id() + "-" + product] - lr = LogicalRouter(fq_name=fq_name, parent_type = 'project') + lr = LogicalRouter(fq_name=fq_name, parent_type = 'project', vxlan_network_identifier='1111') lr.set_physical_router(pr) lr.add_virtual_machine_interface(vmi1) lr_uuid = self._vnc_lib.logical_router_create(lr) @@ -919,6 +951,8 @@ def verify_dm_qfx_switch_options(self, product, role=None): self.check_spine_irb_config(int_vn, vn1_obj) # check bogus lo0 config self.check_spine_bogus_lo0_ip(int_vn) + # check evpn type config + self.check_spine_evpn_type5_config(int_vn, lr) else: self.check_ri_config(vn1_obj, 'l2', False) self.check_ri_config(vn1_obj, 'l3', False)