From 8903fcc7ff6a61cca14fb5bd01215db9a16b700a Mon Sep 17 00:00:00 2001 From: Sebastian Lohff Date: Fri, 8 Nov 2024 17:39:58 +0100 Subject: [PATCH] IPv6 support for vrf address-family v6 We now support setting route-targets and export maps on the v6 address-family. --- asr1k_neutron_l3/models/netconf_yang/vrf.py | 29 ++++++++++++------- asr1k_neutron_l3/models/neutron/l3/vrf.py | 12 ++++---- .../unit/models/netconf_yang/test_parsing.py | 2 +- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/asr1k_neutron_l3/models/netconf_yang/vrf.py b/asr1k_neutron_l3/models/netconf_yang/vrf.py index 92625840..b1391b33 100644 --- a/asr1k_neutron_l3/models/netconf_yang/vrf.py +++ b/asr1k_neutron_l3/models/netconf_yang/vrf.py @@ -130,20 +130,21 @@ def __parameters__(cls): {'key': 'address_family_ipv4', "yang-key": "ipv4", "yang-path": "address-family", 'type': IpV4AddressFamily, "default": {}}, {'key': 'address_family_ipv6', "yang-key": "ipv6", "yang-path": "address-family", - 'yang-type': YANG_TYPE.EMPTY}, + 'type': IpV6AddressFamily, "default": {}}, {'key': 'rd'} ] def __init__(self, **kwargs): super(VrfDefinition, self).__init__(**kwargs) - self.enable_bgp = kwargs.get('enable_bgp', False) - if kwargs.get('map', None) is not None or kwargs.get('rt_import', None) is not None or \ - kwargs.get('rt_export', None) is not None: + if kwargs.get('map') is not None or kwargs.get('rt_import') is not None or \ + kwargs.get('rt_export') is not None: self.address_family_ipv4 = IpV4AddressFamily(**kwargs) if kwargs.get('enable_ipv6'): - self.address_family_ipv6 = True + # we need to pass map_v6 as map key to the AF + kwargs['map'] = kwargs.get('map_v6') + self.address_family_ipv6 = IpV6AddressFamily(**kwargs) self.asn = None if self.rd: @@ -167,10 +168,10 @@ def to_dict(self, context): if self.address_family_ipv4 or self.address_family_ipv6: af = definition[VrfConstants.ADDRESS_FAMILY] = {} - if self.address_family_ipv4 is not None: + if self.address_family_ipv4: af[VrfConstants.IPV4] = self.address_family_ipv4.to_dict(context) if self.address_family_ipv6: - af[VrfConstants.IPV6] = "" + af[VrfConstants.IPV6] = self.address_family_ipv6.to_dict(context) result = OrderedDict() result[VrfConstants.DEFINITION] = definition @@ -294,9 +295,9 @@ def init_config(self): return cli_snippets.VRF_CLI_INIT.format(name=self.name, description=self.description, rd=self.rd) -class IpV4AddressFamily(NyBase): +class IpAddressFamilyBase(NyBase): LIST_KEY = VrfConstants.ADDRESS_FAMILY - ITEM_KEY = VrfConstants.IPV4 + ITEM_KEY = None @classmethod def __parameters__(cls): @@ -312,7 +313,7 @@ def __parameters__(cls): ] def to_dict(self, context): - address_family = OrderedDict() + address_family = {} if self.map is not None: address_family[VrfConstants.EXPORT] = {"map": self.map} @@ -338,6 +339,14 @@ def to_dict(self, context): return dict(address_family) +class IpV4AddressFamily(IpAddressFamilyBase): + ITEM_KEY = VrfConstants.IPV4 + + +class IpV6AddressFamily(IpAddressFamilyBase): + ITEM_KEY = VrfConstants.IPV6 + + class RouteTarget(NyBase): # matches 65001.4:1234 SHORT_4B_RE = re.compile(r"^(?P\d+)\.(?P\d+):(?P\d+)$") diff --git a/asr1k_neutron_l3/models/neutron/l3/vrf.py b/asr1k_neutron_l3/models/neutron/l3/vrf.py index dec8b091..d28aa3fc 100644 --- a/asr1k_neutron_l3/models/neutron/l3/vrf.py +++ b/asr1k_neutron_l3/models/neutron/l3/vrf.py @@ -34,19 +34,21 @@ def __init__(self, name, description=None, asn=None, rd=None, routable_interface self.asn = asn self.rd = utils.to_rd(self.asn, rd) - self.enable_bgp = False - self.map = "exp-{}".format(self.name) if self.routable_interface: - self.enable_bgp = True - self.map = "{}{:02d}".format(cfg.CONF.asr1k_l3.dapnet_rm_prefix, global_vrf_id) + self.map = f"{cfg.CONF.asr1k_l3.dapnet_rm_prefix}{global_vrf_id:02d}" + else: + self.map = f"exp-{self.name}" self.rt_import = [{'asn_ip': asn_ip} for asn_ip in rt_import] if rt_import else None self.rt_export = [{'asn_ip': asn_ip} for asn_ip in rt_export] if rt_export else None + self.map_v6 = None self.enable_ipv6 = enable_ipv6 + if enable_ipv6: + self.map_v6 = f"exp-v6-{self.name}" self._rest_definition = vrf.VrfDefinition(name=self.name, description=self.description, - rd=self.rd, enable_bgp=self.enable_bgp, map=self.map, + rd=self.rd, map=self.map, map_v6=self.map_v6, rt_import=self.rt_import, rt_export=self.rt_export, enable_ipv6=enable_ipv6) diff --git a/asr1k_neutron_l3/tests/unit/models/netconf_yang/test_parsing.py b/asr1k_neutron_l3/tests/unit/models/netconf_yang/test_parsing.py index 13aa9658..293fb3b3 100644 --- a/asr1k_neutron_l3/tests/unit/models/netconf_yang/test_parsing.py +++ b/asr1k_neutron_l3/tests/unit/models/netconf_yang/test_parsing.py @@ -1030,4 +1030,4 @@ def test_vrf_ipv6_af_parsing(self): # back to xml vrf_dict = vrf.to_dict(context) - self.assertEqual('', vrf_dict['definition']['address-family']['ipv6']) + self.assertEqual({"route-target": {}}, vrf_dict['definition']['address-family']['ipv6'])