diff options
Diffstat (limited to 'src/conf_mode/arp.py')
-rwxr-xr-x | src/conf_mode/arp.py | 114 |
1 files changed, 42 insertions, 72 deletions
diff --git a/src/conf_mode/arp.py b/src/conf_mode/arp.py index aac07bd80..1cd8f5451 100755 --- a/src/conf_mode/arp.py +++ b/src/conf_mode/arp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018 VyOS maintainers and contributors +# Copyright (C) 2018-2022 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -13,92 +13,62 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# -import sys -import os -import re -import syslog as sl +from sys import exit from vyos.config import Config +from vyos.configdict import node_changed from vyos.util import call from vyos import ConfigError - from vyos import airbag airbag.enable() -arp_cmd = '/usr/sbin/arp' - -def get_config(): - c = Config() - if not c.exists('protocols static arp'): - return None - - c.set_level('protocols static') - config_data = {} - - for ip_addr in c.list_nodes('arp'): - config_data.update( - { - ip_addr : c.return_value('arp ' + ip_addr + ' hwaddr') - } - ) +def get_config(config=None): + if config: + conf = config + else: + conf = Config() - return config_data + base = ['protocols', 'static', 'arp'] + arp = conf.get_config_dict(base, get_first_key=True) -def generate(c): - c_eff = Config() - c_eff.set_level('protocols static') - c_eff_cnf = {} - for ip_addr in c_eff.list_effective_nodes('arp'): - c_eff_cnf.update( - { - ip_addr : c_eff.return_effective_value('arp ' + ip_addr + ' hwaddr') - } - ) + if 'interface' in arp: + for interface in arp['interface']: + tmp = node_changed(conf, base + ['interface', interface, 'address'], recursive=True) + if tmp: arp['interface'][interface].update({'address_old' : tmp}) - config_data = { - 'remove' : [], - 'update' : {} - } - ### removal - if c == None: - for ip_addr in c_eff_cnf: - config_data['remove'].append(ip_addr) - else: - for ip_addr in c_eff_cnf: - if not ip_addr in c or c[ip_addr] == None: - config_data['remove'].append(ip_addr) + return arp - ### add/update - if c != None: - for ip_addr in c: - if not ip_addr in c_eff_cnf: - config_data['update'][ip_addr] = c[ip_addr] - if ip_addr in c_eff_cnf: - if c[ip_addr] != c_eff_cnf[ip_addr] and c[ip_addr] != None: - config_data['update'][ip_addr] = c[ip_addr] +def verify(arp): + pass - return config_data +def generate(arp): + pass -def apply(c): - for ip_addr in c['remove']: - sl.syslog(sl.LOG_NOTICE, "arp -d " + ip_addr) - call(f'{arp_cmd} -d {ip_addr} >/dev/null 2>&1') +def apply(arp): + if not arp: + return None - for ip_addr in c['update']: - sl.syslog(sl.LOG_NOTICE, "arp -s " + ip_addr + " " + c['update'][ip_addr]) - updated = c['update'][ip_addr] - call(f'{arp_cmd} -s {ip_addr} {updated}') + if 'interface' in arp: + for interface, interface_config in arp['interface'].items(): + # Delete old static ARP assignments first + if 'address_old' in interface_config: + for address in interface_config['address_old']: + call(f'ip neigh del {address} dev {interface}') + # Add new static ARP entries to interface + if 'address' not in interface_config: + continue + for address, address_config in interface_config['address'].items(): + mac = address_config['mac'] + call(f'ip neigh add {address} lladdr {mac} dev {interface}') if __name__ == '__main__': - try: - c = get_config() - ## syntax verification is done via cli - config = generate(c) - apply(config) - except ConfigError as e: - print(e) - sys.exit(1) + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) |