diff --git a/dockers/docker-router-advertiser/radvd.conf.j2 b/dockers/docker-router-advertiser/radvd.conf.j2 index 1d1e9e952f..3880ef9607 100644 --- a/dockers/docker-router-advertiser/radvd.conf.j2 +++ b/dockers/docker-router-advertiser/radvd.conf.j2 @@ -10,9 +10,21 @@ {# If our configuration has VLAN interfaces... #} {% if VLAN_INTERFACE %} -{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{# If this VLAN has an IPv6 address... #} +{% set vlan_list = dict() %} +{% for (name,prefix) in VLAN_INTERFACE|pfx_filter %} +{% if name is not in vlan_list and prefix | ipv6 %} +{% set prefix_list = [] %} +{% set _ = vlan_list.update({name: prefix_list}) %} +{% endif %} {% if prefix | ipv6 %} +{# If our configuration has VLAN interfaces... #} +{% set prefix_list = vlan_list.get(name) %} +{% set _ = prefix_list.append(prefix) %} +{% set _ = vlan_list.update({name: prefix_list}) %} +{% endif %} +{% endfor %} +{% endif %} +{% for name, prefixes in vlan_list.items() %} interface {{ name }} { IgnoreIfMissing on; @@ -23,6 +35,7 @@ interface {{ name }} AdvOtherConfigFlag off; AdvLinkMTU 9100; AdvHomeAgentFlag off; +{% for prefix in prefixes %} prefix {{ prefix | network }}/{{ prefix | prefixlen }} { AdvOnLink on; AdvAutonomous off; @@ -30,8 +43,7 @@ interface {{ name }} AdvValidLifetime infinity; AdvPreferredLifetime infinity; }; +{% endfor %} }; -{% endif %} {% endfor %} -{% endif %} diff --git a/src/sonic-config-engine/tests/radv-test-sample-graph.xml b/src/sonic-config-engine/tests/radv-test-sample-graph.xml new file mode 100644 index 0000000000..6945c8e175 --- /dev/null +++ b/src/sonic-config-engine/tests/radv-test-sample-graph.xml @@ -0,0 +1,579 @@ + + + + + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + + + false + switch-t0 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 180 + 60 + + + switch-t0 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 180 + 60 + + + switch-t0 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 180 + 60 + + + switch-t0 + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 180 + 60 + + + switch-t0 + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 180 + 60 + + + + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
+ + 65100 + switch-t0 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + LoopbackIP1 + Loopback1 + + 10.10.0.99/32 + + 10.10.0.99/32 + + + LoopbackIP2 + Loopback2 + + 10.21.0.64/32 + + 10.21.0.64/32 + + + LoopbackIP3 + Loopback3 + + 10.21.64.2/32 + + 10.21.64.2/32 + + + + + HostIP + eth0 + + 10.0.0.100/24 + + 10.0.0.100/24 + + + HostIP + eth0 + + 2603:10e2:0:2902::8/64 + + 2603:10e2:0:2902::8/64 + + + + + + + switch-t0 + + + PortChannel01 + fortyGigE0/112 + + + + PortChannel02 + fortyGigE0/116 + + + + PortChannel03 + fortyGigE0/120 + + + + PortChannel04 + fortyGigE0/124 + + + + + + Vlan1000 + fortyGigE0/4;fortyGigE0/8;fortyGigE0/12;fortyGigE0/16;fortyGigE0/20;fortyGigE0/24;fortyGigE0/28;fortyGigE0/32;fortyGigE0/36;fortyGigE0/40;fortyGigE0/44;fortyGigE0/48;fortyGigE0/52;fortyGigE0/56;fortyGigE0/60;fortyGigE0/64;fortyGigE0/68;fortyGigE0/72;fortyGigE0/76;fortyGigE0/80;fortyGigE0/84;fortyGigE0/88;fortyGigE0/92;fortyGigE0/96 + False + 0.0.0.0/0 + + + 192.0.0.1;192.0.0.2 + fc02:2000::1;fc02:2000::2 + 1000 + 1000 + 192.168.0.0/27 + + + + + Vlan2000 + fortyGigE0/112;fortyGigE0/116;fortyGigE0/120 + False + 0.0.0.0/0 + + + + 2000 + 2000 + 192.168.200.0/27 + + + + + Vlan99 + fortyGigE0/100 + False + 0.0.0.0/0 + + UserDefinedL2Vlan + 192.0.0.1;192.0.0.2 + 99 + 99 + + + + + + Vlan98 + fortyGigE0/100;PortChannel01;PortChannel03 + False + 0.0.0.0/0 + + UserDefinedL2Vlan + 192.0.0.1;192.0.0.2 + 98 + 98 + + + + + + + + + PortChannel01 + 10.0.0.56/31 + + + + PortChannel01 + FC00::71/126 + + + + PortChannel02 + 10.0.0.58/31 + + + + PortChannel02 + FC00::75/126 + + + + PortChannel03 + 10.0.0.60/31 + + + + PortChannel03 + FC00::79/126 + + + + PortChannel04 + 10.0.0.62/31 + + + + PortChannel04 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/27 + + + + Vlan1000 + fc02:1000::1/64 + + + + Vlan2000 + 192.168.200.1/27 + + + + Vlan1000 + fc02:2000::1/64 + + + + + + ERSPAN + everflow + Everflow + + + ERSPANv6 + everflowV6 + Everflow + + + EGRESS_ERSPAN + everflow_egress + Everflow + + + PortChannel01;PortChannel02;PortChannel03;PortChannel04 + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02;Vlan98 + DataAclEgress + DataPlane + + + SNMP + SNMP_ACL + SNMP + + + NTP + NTP_ACL + NTP + + + SSH + SSH_ACL + SSH + + + SSH + ROUTER-PROTECT + SSH + + + SNMP + ROUTER-PROTECT + SNMP + + + NTP + NTP_ACL + + + + + + + + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1/1 + switch-t0 + fortyGigE0/112 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1/1 + switch-t0 + fortyGigE0/116 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1/1 + switch-t0 + fortyGigE0/120 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1/1 + switch-t0 + fortyGigE0/124 + 100000 + + + DeviceInterfaceLink + 100000 + switch-t0 + fortyGigE0/4 + true + ARISTA05T1 + Ethernet1/33 + true + + + DeviceInterfaceLink + Servers0 + eth0 + switch-t0 + fortyGigE0/4 + + + DeviceInterfaceLink + Servers100 + eth0 + switch-t0 + fortyGigE0/100 + + + + + switch-t0 + Force10-S6000 + + + ARISTA01T1 + Arista + + + ARISTA02T1 + Arista + + + ARISTA03T1 + Arista + + + ARISTA04T1 + Arista + + + + + + + switch-t0 + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + + + + + + + AutoNegotiation + + True + + + FECDisabled + + True + + + ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + + + + + + AutoNegotiation + + False + + + FECDisabled + + True + + + ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8 + + + + + + + switch-t0 + + + DeploymentId + + 1 + + + + + + + switch-t0 + Force10-S6000 +
diff --git a/src/sonic-config-engine/tests/sample_output/py2/radvd.conf b/src/sonic-config-engine/tests/sample_output/py2/radvd.conf new file mode 100644 index 0000000000..9e716b7144 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/radvd.conf @@ -0,0 +1,35 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/radvd.conf.j2 using config DB data +# File: /etc/radvd.conf +# +# Config file for radvd, the router advertisement daemon +# See man page for radvd.conf for descriptions of all available options +# + +interface Vlan1000 +{ + IgnoreIfMissing on; + AdvSendAdvert on; + MinRtrAdvInterval 60; + MaxRtrAdvInterval 180; + AdvManagedFlag on; + AdvOtherConfigFlag off; + AdvLinkMTU 9100; + AdvHomeAgentFlag off; + prefix fc02:2000::/64 { + AdvOnLink on; + AdvAutonomous off; + AdvRouterAddr off; + AdvValidLifetime infinity; + AdvPreferredLifetime infinity; + }; + prefix fc02:1000::/64 { + AdvOnLink on; + AdvAutonomous off; + AdvRouterAddr off; + AdvValidLifetime infinity; + AdvPreferredLifetime infinity; + }; +}; + + diff --git a/src/sonic-config-engine/tests/sample_output/py3/radvd.conf b/src/sonic-config-engine/tests/sample_output/py3/radvd.conf new file mode 100644 index 0000000000..43de8b8477 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/radvd.conf @@ -0,0 +1,35 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/radvd.conf.j2 using config DB data +# File: /etc/radvd.conf +# +# Config file for radvd, the router advertisement daemon +# See man page for radvd.conf for descriptions of all available options +# + +interface Vlan1000 +{ + IgnoreIfMissing on; + AdvSendAdvert on; + MinRtrAdvInterval 60; + MaxRtrAdvInterval 180; + AdvManagedFlag on; + AdvOtherConfigFlag off; + AdvLinkMTU 9100; + AdvHomeAgentFlag off; + prefix fc02:1000::/64 { + AdvOnLink on; + AdvAutonomous off; + AdvRouterAddr off; + AdvValidLifetime infinity; + AdvPreferredLifetime infinity; + }; + prefix fc02:2000::/64 { + AdvOnLink on; + AdvAutonomous off; + AdvRouterAddr off; + AdvValidLifetime infinity; + AdvPreferredLifetime infinity; + }; +}; + + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index d9878c2d9c..851f45098f 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -25,6 +25,7 @@ class TestJ2Files(TestCase): self.arista7050_t0_minigraph = os.path.join(self.test_dir, 'sample-arista-7050-t0-minigraph.xml') self.multi_asic_minigraph = os.path.join(self.test_dir, 'multi_npu_data', 'sample-minigraph.xml') self.multi_asic_port_config = os.path.join(self.test_dir, 'multi_npu_data', 'sample_port_config-0.ini') + self.radv_test_minigraph = os.path.join(self.test_dir, 'radv-test-sample-graph.xml') self.output_file = os.path.join(self.test_dir, 'output') os.environ["CFGGEN_UNIT_TESTING"] = "2" @@ -67,7 +68,14 @@ class TestJ2Files(TestCase): template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'docker-dhcp-relay.supervisord.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file), self.output_file) + + def test_radv(self): + # Test generation of radvd.conf with multiple ipv6 prefixes + template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-router-advertiser', 'radvd.conf.j2') + argument = '-m ' + self.radv_test_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'radvd.conf'), self.output_file)) def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2')