From 72372b7631ccea0b809fa7eac7a906910867096d Mon Sep 17 00:00:00 2001
From: Christian Poessinger <christian@poessinger.com>
Date: Sun, 31 May 2020 18:17:00 +0200
Subject: openvpn: T2532: add VRF support

---
 interface-definitions/interfaces-openvpn.xml.in |  1 +
 src/conf_mode/interfaces-openvpn.py             | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in
index b5da8cf76..bdf5aeddb 100644
--- a/interface-definitions/interfaces-openvpn.xml.in
+++ b/interface-definitions/interfaces-openvpn.xml.in
@@ -800,6 +800,7 @@
               <valueless/>
             </properties>
           </leafNode>
+          #include <include/interface-vrf.xml.i>
         </children>
       </tagNode>
     </children>
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index bd8a0b6b0..5afcbe7da 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -112,6 +112,7 @@ default_config_data = {
     'type': 'tun',
     'uid': user,
     'gid': group,
+    'vrf': ''
 }
 
 
@@ -633,6 +634,10 @@ def get_config():
         if openvpn['redirect_gateway']:
             openvpn['redirect_gateway'] += ' ipv6'
 
+    # retrieve VRF instance
+    if conf.exists('vrf'):
+        openvpn['vrf'] = conf.return_value('vrf')
+
     return openvpn
 
 def verify(openvpn):
@@ -944,6 +949,16 @@ def verify(openvpn):
         if not openvpn['auth_pass']:
             raise ConfigError('Password for authentication is missing')
 
+    if openvpn['vrf']:
+        if openvpn['vrf'] not in interfaces():
+            raise ConfigError(f'VRF "{openvpn["vrf"]}" does not exist')
+
+        if openvpn['is_bridge_member']:
+            raise ConfigError((
+                f'Interface "{openvpn["intf"]}" cannot be member of VRF '
+                f'"{openvpn["vrf"]}" and bridge "{openvpn["is_bridge_member"]}" '
+                f'at the same time!'))
+
     return None
 
 def generate(openvpn):
@@ -1073,6 +1088,11 @@ def apply(openvpn):
             for addr in openvpn['ipv6_eui64_prefix']:
                 o.add_ipv6_eui64_address(addr)
 
+        # assign/remove VRF (ONLY when not a member of a bridge,
+        # otherwise 'nomaster' removes it from it)
+        if not openvpn['is_bridge_member']:
+            o.set_vrf(openvpn['vrf'])
+
     except:
         pass
 
-- 
cgit v1.2.3