From ce361fe12c430c792361479e5b5b3228141fd36f Mon Sep 17 00:00:00 2001
From: Christian Poessinger <christian@poessinger.com>
Date: Wed, 7 Apr 2021 14:53:49 +0200
Subject: vrf: T3344: re-add virtual network identifier

Commit 548d9057e3e (vrf: T3344: move dynamic routing protocols under "vrf name
<name> protocols") temporary removed the possibility to specify the VNI for a
given VRF to to changing of the CLI configuration nodes.

As VNI is set inside zebra, we can re-use the now widely deployed frr python
library to configure and change the configuration without any interference to
other FRR daemons.
---
 src/conf_mode/vrf.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

(limited to 'src')

diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 414e514c5..a39da8991 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -23,14 +23,18 @@ from vyos.config import Config
 from vyos.configdict import node_changed
 from vyos.ifconfig import Interface
 from vyos.template import render
+from vyos.template import render_to_string
 from vyos.util import call
 from vyos.util import cmd
 from vyos.util import dict_search
 from vyos.util import get_interface_config
 from vyos import ConfigError
+from vyos import frr
 from vyos import airbag
 airbag.enable()
 
+frr_daemon = 'zebra'
+
 config_file = r'/etc/iproute2/rt_tables.d/vyos-vrf.conf'
 
 def list_rules():
@@ -123,6 +127,7 @@ def verify(vrf):
 
 def generate(vrf):
     render(config_file, 'vrf/vrf.conf.tmpl', vrf)
+    vrf['new_frr_config'] = render_to_string('frr/vrf.frr.tmpl', vrf)
     return None
 
 def apply(vrf):
@@ -210,6 +215,22 @@ def apply(vrf):
             if 1000 in [r.get('priority') for r in list_rules() if r.get('priority') == 1000]:
                 call(f'ip {af} rule del pref 1000')
 
+    # add configuration to FRR
+    frr_cfg = frr.FRRConfig()
+    frr_cfg.load_configuration(frr_daemon)
+    frr_cfg.modify_section(f'^vrf [a-zA-Z-]*$', '')
+    frr_cfg.add_before(r'(interface .*|line vty)', vrf['new_frr_config'])
+    frr_cfg.commit_configuration(frr_daemon)
+
+    # If FRR config is blank, rerun the blank commit x times due to frr-reload
+    # behavior/bug not properly clearing out on one commit.
+    if vrf['new_frr_config'] == '':
+        for a in range(5):
+            frr_cfg.commit_configuration(frr_daemon)
+
+    # Save configuration to /run/frr/config/frr.conf
+    frr.save_configuration()
+
     return None
 
 if __name__ == '__main__':
-- 
cgit v1.2.3