Page MenuHomeVyOS Platform

No OneTemporary

Size
20 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/frr/ospfv3.frr.tmpl b/data/templates/frr/ospfv3.frr.tmpl
index d08972a80..0026c0d2c 100644
--- a/data/templates/frr/ospfv3.frr.tmpl
+++ b/data/templates/frr/ospfv3.frr.tmpl
@@ -1,84 +1,89 @@
!
{% if interface is defined and interface is not none %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
{% if iface_config.cost is defined and iface_config.cost is not none %}
ipv6 ospf6 cost {{ iface_config.cost }}
{% endif %}
{% if iface_config.priority is defined and iface_config.priority is not none %}
ipv6 ospf6 priority {{ iface_config.priority }}
{% endif %}
{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
ipv6 ospf6 hello-interval {{ iface_config.hello_interval }}
{% endif %}
{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }}
{% endif %}
{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }}
{% endif %}
{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
ipv6 ospf6 dead-interval {{ iface_config.dead_interval }}
{% endif %}
{% if iface_config.bfd is defined %}
ipv6 ospf6 bfd
{% endif %}
{% if iface_config.mtu_ignore is defined %}
ipv6 ospf6 mtu-ignore
{% endif %}
{% if iface_config.ifmtu is defined and iface_config.ifmtu is not none %}
ipv6 ospf6 ifmtu {{ iface_config.ifmtu }}
{% endif %}
{% if iface_config.network is defined and iface_config.network is not none %}
ipv6 ospf6 network {{ iface_config.network }}
{% endif %}
{% if iface_config.instance_id is defined and iface_config.instance_id is not none %}
ipv6 ospf6 instance-id {{ iface_config.instance_id }}
{% endif %}
{% if iface_config.passive is defined %}
ipv6 ospf6 passive
{% endif %}
!
{% endfor %}
{% endif %}
!
router ospf6
{% if area is defined and area is not none %}
{% for area_id, area_config in area.items() %}
{% if area_config.interface is defined and area_config.interface is not none %}
{% for interface in area_config.interface %}
interface {{ interface }} area {{ area_id }}
{% endfor %}
{% endif %}
+{% if area_config.area_type is defined and area_config.area_type is not none %}
+{% for type, type_config in area_config.area_type.items() %}
+ area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
+{% endfor %}
+{% endif %}
{% if area_config.range is defined and area_config.range is not none %}
{% for prefix, prefix_config in area_config.range.items() %}
area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is defined }} {{ 'not-advertise' if prefix_config.not_advertise is defined }}
{% endfor %}
{% endif %}
{% if area_config.export_list is defined and area_config.export_list is not none %}
area {{ area_id }} export-list {{ area_config.export_list }}
{% endif %}
{% if area_config.import_list is defined and area_config.import_list is not none %}
area {{ area_id }} import-list {{ area_config.import_list }}
{% endif %}
{% endfor %}
{% endif %}
{% if distance is defined and distance is not none %}
{% if distance.global is defined and distance.global is not none %}
distance {{ distance.global }}
{% endif %}
{% if distance.ospfv3 is defined and distance.ospfv3 is not none %}
distance ospf6 {{ 'intra-area ' + distance.ospfv3.intra_area if distance.ospfv3.intra_area is defined }} {{ 'inter-area ' + distance.ospfv3.inter_area if distance.ospfv3.inter_area is defined }} {{ 'external ' + distance.ospfv3.external if distance.ospfv3.external is defined }}
{% endif %}
{% endif %}
{% if parameters is defined and parameters is not none %}
{% if parameters.router_id is defined and parameters.router_id is not none %}
ospf6 router-id {{ parameters.router_id }}
{% endif %}
{% endif %}
{% if redistribute is defined and redistribute is not none %}
{% for protocol, options in redistribute.items() %}
redistribute {{ protocol }} {{ 'route-map ' + options.route_map if options.route_map is defined }}
{% endfor %}
{% endif %}
!
diff --git a/interface-definitions/protocols-ospfv3.xml.in b/interface-definitions/protocols-ospfv3.xml.in
index 99e671b32..7b42c448d 100644
--- a/interface-definitions/protocols-ospfv3.xml.in
+++ b/interface-definitions/protocols-ospfv3.xml.in
@@ -1,229 +1,249 @@
<?xml version="1.0" encoding="utf-8"?>
<interfaceDefinition>
<node name="protocols">
<children>
<node name="ospfv3" owner="${vyos_conf_scripts_dir}/protocols_ospfv3.py">
<properties>
<help>Open Shortest Path First (OSPF) for IPv6</help>
<priority>620</priority>
</properties>
<children>
<tagNode name="area">
<properties>
<help>OSPFv3 Area</help>
<valueHelp>
<format>u32</format>
<description>Area ID as a decimal value</description>
</valueHelp>
<valueHelp>
<format>ipv4</format>
<description>Area ID in IP address forma</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
<validator name="ip-address"/>
</constraint>
</properties>
<children>
+ <node name="area-type">
+ <properties>
+ <help>OSPFv3 Area type</help>
+ </properties>
+ <children>
+ <node name="stub">
+ <properties>
+ <help>Stub OSPFv3 area</help>
+ </properties>
+ <children>
+ <leafNode name="no-summary">
+ <properties>
+ <help>Do not inject inter-area routes into the stub</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
<leafNode name="export-list">
<properties>
<help>Name of export-list</help>
<completionHelp>
<path>policy access-list6</path>
</completionHelp>
</properties>
</leafNode>
<leafNode name="import-list">
<properties>
<help>Name of import-list</help>
<completionHelp>
<path>policy access-list6</path>
</completionHelp>
</properties>
</leafNode>
<leafNode name="interface">
<properties>
<help>Enable routing on an IPv6 interface</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
<valueHelp>
<format>txt</format>
<description>Interface used for routing information exchange</description>
</valueHelp>
<constraint>
<validator name="interface-name"/>
</constraint>
<multi/>
</properties>
</leafNode>
<tagNode name="range">
<properties>
<help>Specify IPv6 prefix (border routers only)</help>
<valueHelp>
<format>ipv6net</format>
<description>Specify IPv6 prefix (border routers only)</description>
</valueHelp>
<constraint>
<validator name="ipv6-prefix"/>
</constraint>
</properties>
<children>
<leafNode name="advertise">
<properties>
<help>Advertise this range</help>
<valueless/>
</properties>
</leafNode>
<leafNode name="not-advertise">
<properties>
<help>Do not advertise this range</help>
<valueless/>
</properties>
</leafNode>
</children>
</tagNode>
</children>
</tagNode>
<node name="distance">
<properties>
<help>Administrative distance</help>
</properties>
<children>
#include <include/ospf/distance-global.xml.i>
<node name="ospfv3">
<properties>
<help>OSPFv3 administrative distance</help>
</properties>
<children>
#include <include/ospf/distance-per-protocol.xml.i>
</children>
</node>
</children>
</node>
<tagNode name="interface">
<properties>
<help>Enable routing on an IPv6 interface</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
<valueHelp>
<format>txt</format>
<description>Interface used for routing information exchange</description>
</valueHelp>
<constraint>
<validator name="interface-name"/>
</constraint>
</properties>
<children>
#include <include/ospf/intervals.xml.i>
#include <include/ospf/interface-common.xml.i>
<leafNode name="ifmtu">
<properties>
<help>Interface MTU</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Interface MTU</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
</constraint>
</properties>
</leafNode>
<leafNode name="instance-id">
<properties>
<help>Instance Id (default: 0)</help>
<valueHelp>
<format>u32:0-255</format>
<description>Instance Id</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-255"/>
</constraint>
</properties>
<defaultValue>0</defaultValue>
</leafNode>
<leafNode name="network">
<properties>
<help>Network type</help>
<completionHelp>
<list>broadcast point-to-point</list>
</completionHelp>
<valueHelp>
<format>broadcast</format>
<description>Broadcast network type</description>
</valueHelp>
<valueHelp>
<format>point-to-point</format>
<description>Point-to-point network type</description>
</valueHelp>
<constraint>
<regex>^(broadcast|point-to-point)$</regex>
</constraint>
<constraintErrorMessage>Must be broadcast or point-to-point</constraintErrorMessage>
</properties>
</leafNode>
#include <include/isis/passive.xml.i>
</children>
</tagNode>
<node name="parameters">
<properties>
<help>OSPFv3 specific parameters</help>
</properties>
<children>
#include <include/router-id.xml.i>
</children>
</node>
<node name="redistribute">
<properties>
<help>Redistribute information from another routing protocol</help>
</properties>
<children>
<node name="bgp">
<properties>
<help>Redistribute BGP routes</help>
</properties>
<children>
#include <include/route-map.xml.i>
</children>
</node>
<node name="connected">
<properties>
<help>Redistribute connected routes</help>
</properties>
<children>
#include <include/route-map.xml.i>
</children>
</node>
<node name="kernel">
<properties>
<help>Redistribute kernel routes</help>
</properties>
<children>
#include <include/route-map.xml.i>
</children>
</node>
<node name="ripng">
<properties>
<help>Redistribute RIPNG routes</help>
</properties>
<children>
#include <include/route-map.xml.i>
</children>
</node>
<node name="static">
<properties>
<help>Redistribute static routes</help>
</properties>
<children>
#include <include/route-map.xml.i>
</children>
</node>
</children>
</node>
#include <include/route-map.xml.i>
</children>
</node>
</children>
</node>
</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index 6bb551642..0b4b01993 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -1,154 +1,171 @@
#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSession
from vyos.ifconfig import Section
from vyos.util import process_named_running
PROCESS_NAME = 'ospf6d'
base_path = ['protocols', 'ospfv3']
router_id = '192.0.2.1'
default_area = '0'
class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(base_path)
self.cli_commit()
def test_ospfv3_01_basic(self):
seq = '10'
prefix = '2001:db8::/32'
acl_name = 'foo-acl-100'
self.cli_set(['policy', 'access-list6', acl_name, 'rule', seq, 'action', 'permit'])
self.cli_set(['policy', 'access-list6', acl_name, 'rule', seq, 'source', 'any'])
self.cli_set(base_path + ['parameters', 'router-id', router_id])
self.cli_set(base_path + ['area', default_area, 'range', prefix, 'advertise'])
self.cli_set(base_path + ['area', default_area, 'export-list', acl_name])
self.cli_set(base_path + ['area', default_area, 'import-list', acl_name])
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
self.cli_set(base_path + ['area', default_area, 'interface', interface])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf6')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {default_area} range {prefix}', frrconfig)
self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
self.assertIn(f' area {default_area} import-list {acl_name}', frrconfig)
self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig)
for interface in interfaces:
self.assertIn(f' interface {interface} area {default_area}', frrconfig)
self.cli_delete(['policy', 'access-list6', acl_name])
def test_ospfv3_02_distance(self):
dist_global = '200'
dist_external = '110'
dist_inter_area = '120'
dist_intra_area = '130'
self.cli_set(base_path + ['distance', 'global', dist_global])
self.cli_set(base_path + ['distance', 'ospfv3', 'external', dist_external])
self.cli_set(base_path + ['distance', 'ospfv3', 'inter-area', dist_inter_area])
self.cli_set(base_path + ['distance', 'ospfv3', 'intra-area', dist_intra_area])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf6')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' distance {dist_global}', frrconfig)
self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig)
def test_ospfv3_03_redistribute(self):
route_map = 'foo-bar'
route_map_seq = '10'
redistribute = ['bgp', 'connected', 'kernel', 'ripng', 'static']
self.cli_set(['policy', 'route-map', route_map, 'rule', route_map_seq, 'action', 'permit'])
for protocol in redistribute:
self.cli_set(base_path + ['redistribute', protocol, 'route-map', route_map])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf6')
self.assertIn(f'router ospf6', frrconfig)
for protocol in redistribute:
self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig)
def test_ospfv3_04_interfaces(self):
self.cli_set(base_path + ['parameters', 'router-id', router_id])
self.cli_set(base_path + ['area', default_area])
cost = '100'
priority = '10'
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
if_base = base_path + ['interface', interface]
self.cli_set(if_base + ['bfd'])
self.cli_set(if_base + ['cost', cost])
self.cli_set(if_base + ['instance-id', '0'])
self.cli_set(if_base + ['mtu-ignore'])
self.cli_set(if_base + ['network', 'point-to-point'])
self.cli_set(if_base + ['passive'])
self.cli_set(if_base + ['priority', priority])
cost = str(int(cost) + 10)
priority = str(int(priority) + 5)
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf6')
self.assertIn(f'router ospf6', frrconfig)
cost = '100'
priority = '10'
for interface in interfaces:
if_config = self.getFRRconfig(f'interface {interface}')
self.assertIn(f'interface {interface}', if_config)
self.assertIn(f' ipv6 ospf6 bfd', if_config)
self.assertIn(f' ipv6 ospf6 cost {cost}', if_config)
self.assertIn(f' ipv6 ospf6 mtu-ignore', if_config)
self.assertIn(f' ipv6 ospf6 network point-to-point', if_config)
self.assertIn(f' ipv6 ospf6 passive', if_config)
self.assertIn(f' ipv6 ospf6 priority {priority}', if_config)
cost = str(int(cost) + 10)
priority = str(int(priority) + 5)
+
+ def test_ospfv3_05_area_stub(self):
+ area_stub = '23'
+ area_stub_nosum = '26'
+
+ self.cli_set(base_path + ['area', area_stub, 'area-type', 'stub'])
+ self.cli_set(base_path + ['area', area_stub_nosum, 'area-type', 'stub', 'no-summary'])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6')
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' area {area_stub} stub', frrconfig)
+ self.assertIn(f' area {area_stub_nosum} stub no-summary', frrconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 26, 1:32 PM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4285287
Default Alt Text
(20 KB)

Event Timeline