summaryrefslogtreecommitdiff
path: root/src/conf_mode/vpp.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/vpp.py')
-rwxr-xr-xsrc/conf_mode/vpp.py48
1 files changed, 33 insertions, 15 deletions
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index 54ea54852..25fe159f8 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -20,6 +20,7 @@ from re import search as re_search, MULTILINE as re_M
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configdict import node_changed
from vyos.ifconfig import Section
from vyos.ifconfig import EthernetIf
from vyos.ifconfig import interface
@@ -31,6 +32,7 @@ from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
from vyos.vpp import VPPControl
+from vyos.vpp import HostControl
airbag.enable()
@@ -53,7 +55,6 @@ def _get_pci_address_by_interface(iface) -> str:
# use VPP - maybe interface already attached to it
vpp_control = VPPControl()
pci_addr = vpp_control.get_pci_addr(iface)
- vpp_control.disconnect()
if pci_addr:
return pci_addr
# return empty string if address was not found
@@ -69,8 +70,20 @@ def get_config(config=None):
base = ['vpp']
base_ethernet = ['interfaces', 'ethernet']
+
+ # find interfaces removed from VPP
+ removed_ifaces = []
+ tmp = node_changed(conf, base + ['interface'])
+ if tmp:
+ for removed_iface in tmp:
+ pci_address: str = _get_pci_address_by_interface(removed_iface)
+ removed_ifaces.append({
+ 'iface_name': removed_iface,
+ 'iface_pci_addr': pci_address
+ })
+
if not conf.exists(base):
- return None
+ return {'removed_ifaces': removed_ifaces}
config = conf.get_config_dict(base,
get_first_key=True,
@@ -97,12 +110,15 @@ def get_config(config=None):
config['other_interfaces'] = conf.get_config_dict(base_ethernet, key_mangling=('-', '_'),
get_first_key=True, no_tag_node_value_mangle=True)
+ if removed_ifaces:
+ config['removed_ifaces'] = removed_ifaces
+
return config
def verify(config):
# bail out early - looks like removal from running config
- if not config:
+ if not config or (len(config) == 1 and 'removed_ifaces' in config):
return None
if 'interface' not in config:
@@ -114,7 +130,7 @@ def verify(config):
def generate(config):
- if not config:
+ if not config or (len(config) == 1 and 'removed_ifaces' in config):
# Remove old config and return
service_conf.unlink(missing_ok=True)
return None
@@ -126,22 +142,24 @@ def generate(config):
def apply(config):
- if not config:
- print(f'systemctl stop {service_name}.service')
+ if not config or (len(config) == 1 and 'removed_ifaces' in config):
call(f'systemctl stop {service_name}.service')
- return
else:
- print(f'systemctl restart {service_name}.service')
+ call('systemctl daemon-reload')
call(f'systemctl restart {service_name}.service')
- call('systemctl daemon-reload')
+ for iface in config.get('removed_ifaces', []):
+ HostControl().pci_rescan(iface['iface_pci_addr'])
- call('sudo sysctl -w vm.nr_hugepages=4096')
- vpp_control = VPPControl()
- for iface, _ in config['interface'].items():
- # Create lcp
- if iface not in Section.interfaces():
- vpp_control.lcp_pair_add(iface, iface)
+ if 'interface' in config:
+ # connect to VPP
+ # must be performed multiple attempts because API is not available
+ # immediately after the service restart
+ vpp_control = VPPControl(attempts=20, interval=500)
+ for iface, _ in config['interface'].items():
+ # Create lcp
+ if iface not in Section.interfaces():
+ vpp_control.lcp_pair_add(iface, iface)
# update interface config
#e = EthernetIf(iface)