From 7dc37d1bcdddd11bb1f1bec766f07f5657909528 Mon Sep 17 00:00:00 2001
From: Christian Poessinger <christian@poessinger.com>
Date: Sun, 7 Feb 2021 20:27:58 +0100
Subject: rip: T2547: migrate interface specific options to "protocols rip"

---
 data/templates/frr/rip.frr.tmpl | 35 +++++++++++++++++++++++++++++++++++
 src/conf_mode/protocols_rip.py  | 11 +++++++++++
 2 files changed, 46 insertions(+)

diff --git a/data/templates/frr/rip.frr.tmpl b/data/templates/frr/rip.frr.tmpl
index eeaee7199..c0d062fc6 100644
--- a/data/templates/frr/rip.frr.tmpl
+++ b/data/templates/frr/rip.frr.tmpl
@@ -1,4 +1,39 @@
 !
+{# RIP key-chain definition #}
+{% if interface is defined and interface is not none %}
+{%   for iface, iface_config in interface.items() %}
+{%     if iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+key chain {{ iface }}-rip
+{%       for key_id, key_options in iface_config.authentication.md5.items() %}
+ key {{ key_id }}
+{%         if key_options.password is defined and key_options.password is not none %}
+  key-string {{ key_options.password }}
+{%         endif %}
+{%       endfor %}
+{%     endif %}
+{%   endfor %}
+{% endif %}
+!
+{# Interface specific configuration #}
+{% if interface is defined and interface is not none %}
+{%   for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{%     if iface_config.authentication is defined and iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
+ ip rip authentication mode text
+ ip rip authentication string {{ iface_config.authentication.plaintext_password }}
+{%     elif iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+ ip rip authentication key-chain {{ iface }}-rip
+ ip rip authentication mode md5
+{%     endif %}
+{%     if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
+ no ip rip split-horizon
+{%     endif %}
+{%     if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
+ ip rip split-horizon poisoned-reverse
+{%     endif %}
+{%   endfor %}
+{% endif %}
+!
 router rip
 {% if default_information is defined and default_information.originate is defined %}
  default-information originate
diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py
index bb3790fb2..06d7c6d49 100755
--- a/src/conf_mode/protocols_rip.py
+++ b/src/conf_mode/protocols_rip.py
@@ -89,6 +89,16 @@ def verify(rip):
     if prefix_list_out and prefix_list_out.replace('-','_') not in (dict_search('policy.prefix_list', rip) or []):
         raise ConfigError(f'Outbound prefix-list "{prefix_list_out}" does not exist!')
 
+    if 'interface' in rip:
+        for interface, interface_options in rip['interface'].items():
+            if 'authentication' in interface_options:
+                if {'md5', 'plaintext_password'} <= set(interface_options['authentication']):
+                    raise ConfigError('Can not use both md5 and plaintext-password at the same time!')
+            if 'split_horizon' in interface_options:
+                if {'disable', 'poison_reverse'} <= set(interface_options['split_horizon']):
+                    raise ConfigError(f'You can not have "split-horizon poison-reverse" enabled ' \
+                                      f'with "split-horizon disable" for "{interface}"!')
+
     verify_route_maps(rip)
 
 def generate(rip):
@@ -106,6 +116,7 @@ def apply(rip):
     # Save original configuration prior to starting any commit actions
     frr_cfg = frr.FRRConfig()
     frr_cfg.load_configuration(frr_daemon)
+    frr_cfg.modify_section(r'key chain \S+', '')
     frr_cfg.modify_section(r'interface \S+', '')
     frr_cfg.modify_section('router rip', '')
     frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rip['new_frr_config'])
-- 
cgit v1.2.3