summaryrefslogtreecommitdiff
path: root/src/conf_mode/protocols_pim6.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/protocols_pim6.py')
-rwxr-xr-xsrc/conf_mode/protocols_pim6.py57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/conf_mode/protocols_pim6.py b/src/conf_mode/protocols_pim6.py
index 6a1235ba5..2003a1014 100755
--- a/src/conf_mode/protocols_pim6.py
+++ b/src/conf_mode/protocols_pim6.py
@@ -15,18 +15,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipaddress import IPv6Address
+from ipaddress import IPv6Network
from sys import exit
-from typing import Optional
-from vyos import ConfigError, airbag, frr
-from vyos.config import Config, ConfigDict
+from vyos.config import Config
+from vyos.config import config_dict_merge
from vyos.configdict import node_changed
from vyos.configverify import verify_interface_exists
from vyos.template import render_to_string
-
+from vyos import ConfigError
+from vyos import frr
+from vyos import airbag
airbag.enable()
-
def get_config(config=None):
if config:
conf = config
@@ -44,11 +45,21 @@ def get_config(config=None):
if interfaces_removed:
pim6['interface_removed'] = list(interfaces_removed)
- return pim6
+ # Bail out early if configuration tree does no longer exist. this must
+ # be done after retrieving the list of interfaces to be removed.
+ if not conf.exists(base):
+ pim6.update({'deleted' : ''})
+ return pim6
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = conf.get_config_defaults(**pim6.kwargs, recursive=True)
+
+ pim6 = config_dict_merge(default_values, pim6)
+ return pim6
def verify(pim6):
- if pim6 is None:
+ if not pim6 or 'deleted' in pim6:
return
for interface, interface_config in pim6.get('interface', {}).items():
@@ -60,13 +71,34 @@ def verify(pim6):
if not IPv6Address(group).is_multicast:
raise ConfigError(f"{group} is not a multicast group")
+ if 'rp' in pim6:
+ if 'address' not in pim6['rp']:
+ raise ConfigError('PIM6 rendezvous point needs to be defined!')
+
+ # Check unique multicast groups
+ unique = []
+ pim_base_error = 'PIM6 rendezvous point group'
+
+ if {'address', 'prefix-list6'} <= set(pim6['rp']):
+ raise ConfigError(f'{pim_base_error} supports either address or a prefix-list!')
+
+ for address, address_config in pim6['rp']['address'].items():
+ if 'group' not in address_config:
+ raise ConfigError(f'{pim_base_error} should be defined for "{address}"!')
+
+ # Check if it is a multicast group
+ for gr_addr in address_config['group']:
+ if not IPv6Network(gr_addr).is_multicast:
+ raise ConfigError(f'{pim_base_error} "{gr_addr}" is not a multicast group!')
+ if gr_addr in unique:
+ raise ConfigError(f'{pim_base_error} must be unique!')
+ unique.append(gr_addr)
def generate(pim6):
- if pim6 is None:
+ if not pim6 or 'deleted' in pim6:
return
-
pim6['new_frr_config'] = render_to_string('frr/pim6d.frr.j2', pim6)
-
+ return None
def apply(pim6):
if pim6 is None:
@@ -83,13 +115,12 @@ def apply(pim6):
if key not in pim6:
continue
for interface in pim6[key]:
- frr_cfg.modify_section(
- f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True)
+ frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True)
if 'new_frr_config' in pim6:
frr_cfg.add_before(frr.default_add_before, pim6['new_frr_config'])
frr_cfg.commit_configuration(pim6_daemon)
-
+ return None
if __name__ == '__main__':
try: