diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/host_name.py | 17 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-pseudo-ethernet.py | 30 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wirelessmodem.py | 12 | ||||
-rwxr-xr-x | src/conf_mode/service_console-server.py | 37 | ||||
-rwxr-xr-x | src/conf_mode/service_pppoe-server.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/system_lcd.py | 84 | ||||
-rw-r--r-- | src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper | 9 | ||||
-rw-r--r-- | src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup | 10 | ||||
-rw-r--r-- | src/etc/systemd/system/LCDd.service.d/override.conf | 8 | ||||
-rw-r--r-- | src/etc/systemd/system/hostapd@.service.d/override.conf | 7 | ||||
-rwxr-xr-x | src/op_mode/ping.py | 8 | ||||
-rw-r--r-- | src/systemd/lcdproc.service | 13 |
12 files changed, 186 insertions, 52 deletions
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index f2fa64233..9d66bd434 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -18,20 +18,16 @@ conf-mode script for 'system host-name' and 'system domain-name'. """ -import os import re import sys import copy -import glob -import argparse -import jinja2 import vyos.util import vyos.hostsd_client from vyos.config import Config from vyos import ConfigError -from vyos.util import cmd, call, run, process_named_running +from vyos.util import cmd, call, process_named_running from vyos import airbag airbag.enable() @@ -47,7 +43,9 @@ default_config_data = { hostsd_tag = 'system' -def get_config(conf): +def get_config(): + conf = Config() + hosts = copy.deepcopy(default_config_data) hosts['hostname'] = conf.return_value("system host-name") @@ -77,7 +75,7 @@ def get_config(conf): return hosts -def verify(conf, hosts): +def verify(hosts): if hosts is None: return None @@ -168,9 +166,8 @@ def apply(config): if __name__ == '__main__': try: - conf = Config() - c = get_config(conf) - verify(conf, c) + c = get_config() + verify(c) generate(c) apply(c) except ConfigError as e: diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 4afea2b3a..fe2d7b1be 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -28,6 +28,7 @@ from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_source_interface from vyos.configverify import verify_vlan_config from vyos.ifconfig import MACVLANIf +from vyos.validate import is_member from vyos import ConfigError from vyos import airbag @@ -35,8 +36,8 @@ airbag.enable() def get_config(): """ - Retrive CLI config as dictionary. Dictionary can never be empty, as at least the - interface name will be added or a deleted flag + Retrive CLI config as dictionary. Dictionary can never be empty, as at + least the interface name will be added or a deleted flag """ conf = Config() base = ['interfaces', 'pseudo-ethernet'] @@ -46,6 +47,17 @@ def get_config(): if mode: peth.update({'mode_old' : mode}) + # Check if source-interface is member of a bridge device + if 'source_interface' in peth: + bridge = is_member(conf, peth['source_interface'], 'bridge') + if bridge: + peth.update({'source_interface_is_bridge_member' : bridge}) + + # Check if we are a member of a bond device + bond = is_member(conf, peth['source_interface'], 'bonding') + if bond: + peth.update({'source_interface_is_bond_member' : bond}) + return peth def verify(peth): @@ -57,6 +69,16 @@ def verify(peth): verify_vrf(peth) verify_address(peth) + if 'source_interface_is_bridge_member' in peth: + raise ConfigError( + 'Source interface "{source_interface}" can not be used as it is already a ' + 'member of bridge "{source_interface_is_bridge_member}"!'.format(**peth)) + + if 'source_interface_is_bond_member' in peth: + raise ConfigError( + 'Source interface "{source_interface}" can not be used as it is already a ' + 'member of bond "{source_interface_is_bond_member}"!'.format(**peth)) + # use common function to verify VLAN configuration verify_vlan_config(peth) return None @@ -71,8 +93,8 @@ def apply(peth): return None # Check if MACVLAN interface already exists. Parameters like the underlaying - # source-interface device or mode can not be changed on the fly and the interface - # needs to be recreated from the bottom. + # source-interface device or mode can not be changed on the fly and the + # interface needs to be recreated from the bottom. if 'mode_old' in peth: MACVLANIf(peth['ifname']).remove() diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index 4081be3c9..6d168d918 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -16,7 +16,6 @@ import os -from fnmatch import fnmatch from sys import exit from vyos.config import Config @@ -25,22 +24,13 @@ from vyos.configverify import verify_vrf from vyos.template import render from vyos.util import call from vyos.util import check_kmod +from vyos.util import find_device_file from vyos import ConfigError from vyos import airbag airbag.enable() k_mod = ['option', 'usb_wwan', 'usbserial'] -def find_device_file(device): - """ Recurively search /dev for the given device file and return its full path. - If no device file was found 'None' is returned """ - for root, dirs, files in os.walk('/dev'): - for basename in files: - if fnmatch(basename, device): - return os.path.join(root, basename) - - return None - def get_config(): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py index ace6b8ca4..613ec6879 100755 --- a/src/conf_mode/service_console-server.py +++ b/src/conf_mode/service_console-server.py @@ -31,11 +31,9 @@ def get_config(): conf = Config() base = ['service', 'console-server'] - if not conf.exists(base): - return None - # Retrieve CLI representation as dictionary - proxy = conf.get_config_dict(base, key_mangling=('-', '_')) + proxy = conf.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True) # The retrieved dictionary will look something like this: # # {'device': {'usb0b2.4p1.0': {'speed': '9600'}, @@ -47,9 +45,10 @@ def get_config(): # We have gathered the dict representation of the CLI, but there are default # options which we need to update into the dictionary retrived. default_values = defaults(base + ['device']) - for device in proxy['device'].keys(): - tmp = dict_merge(default_values, proxy['device'][device]) - proxy['device'][device] = tmp + if 'device' in proxy: + for device in proxy['device']: + tmp = dict_merge(default_values, proxy['device'][device]) + proxy['device'][device] = tmp return proxy @@ -57,15 +56,14 @@ def verify(proxy): if not proxy: return None - for device in proxy['device']: - keys = proxy['device'][device].keys() - if 'speed' not in keys: - raise ConfigError(f'Serial port speed must be defined for "{tmp}"!') + if 'device' in proxy: + for device in proxy['device']: + if 'speed' not in proxy['device'][device]: + raise ConfigError(f'Serial port speed must be defined for "{device}"!') - if 'ssh' in keys: - ssh_keys = proxy['device'][device]['ssh'].keys() - if 'port' not in ssh_keys: - raise ConfigError(f'SSH port must be defined for "{tmp}"!') + if 'ssh' in proxy['device'][device]: + if 'port' not in proxy['device'][device]['ssh']: + raise ConfigError(f'SSH port must be defined for "{device}"!') return None @@ -86,10 +84,11 @@ def apply(proxy): call('systemctl restart conserver-server.service') - for device in proxy['device']: - if 'ssh' in proxy['device'][device].keys(): - port = proxy['device'][device]['ssh']['port'] - call(f'systemctl restart dropbear@{device}.service') + if 'device' in proxy: + for device in proxy['device']: + if 'ssh' in proxy['device'][device]: + port = proxy['device'][device]['ssh']['port'] + call(f'systemctl restart dropbear@{device}.service') return None diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index a8357f653..39d34a7e2 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -421,6 +421,9 @@ def verify(pppoe): if len(pppoe['dnsv6']) > 3: raise ConfigError('Not more then three IPv6 DNS name-servers can be configured') + if not pppoe['interfaces']: + raise ConfigError('At least one listen interface must be defined!') + # local ippool and gateway settings config checks if pppoe['client_ip_subnets'] or pppoe['client_ip_pool']: if not pppoe['ppp_gw']: diff --git a/src/conf_mode/system_lcd.py b/src/conf_mode/system_lcd.py new file mode 100755 index 000000000..0ad1318f0 --- /dev/null +++ b/src/conf_mode/system_lcd.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io> +# +# 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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 os + +from sys import exit + +from vyos.config import Config +from vyos.util import call +from vyos.util import find_device_file +from vyos.template import render +from vyos import ConfigError +from vyos import airbag +airbag.enable() + +lcdd_conf = '/run/LCDd/LCDd.conf' +lcdproc_conf = '/run/lcdproc/lcdproc.conf' + +def get_config(): + conf = Config() + base = ['system', 'lcd'] + lcd = conf.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True) + # Return (possibly empty) dictionary + return lcd + +def verify(lcd): + if not lcd: + return None + + if not {'device', 'model'} <= set(lcd): + raise ConfigError('Both device and driver must be set!') + + return None + +def generate(lcd): + if not lcd: + return None + + if 'device' in lcd: + lcd['device'] = find_device_file(lcd['device']) + + # Render config file for daemon LCDd + render(lcdd_conf, 'lcd/LCDd.conf.tmpl', lcd, trim_blocks=True) + # Render config file for client lcdproc + render(lcdproc_conf, 'lcd/lcdproc.conf.tmpl', lcd, trim_blocks=True) + + return None + +def apply(lcd): + if not lcd: + call('systemctl stop lcdproc.service LCDd.service') + + for file in [lcdd_conf, lcdproc_conf]: + if os.path.exists(file): + os.remove(file) + else: + # Restart server + call('systemctl restart LCDd.service lcdproc.service') + + return None + +if __name__ == '__main__': + try: + config_dict = get_config() + verify(config_dict) + generate(config_dict) + apply(config_dict) + except ConfigError as e: + print(e) + exit(1) diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper index f1167fcd2..d1161e704 100644 --- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper +++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper @@ -40,7 +40,14 @@ function iptovtysh () { elif [ "$7" == "dev" ]; then VTYSH_DEV=$8 fi - VTYSH_CMD="ip route $VTYSH_NETADDR $VTYSH_GATEWAY $VTYSH_DEV tag $VTYSH_TAG $VTYSH_DISTANCE" + + # Add route to VRF routing table + local VTYSH_VRF_NAME=$(basename /sys/class/net/$VTYSH_DEV/upper_* | sed -e 's/upper_//') + if [ -n $VTYSH_VRF_NAME ]; then + VTYSH_VRF="vrf $VTYSH_VRF_NAME" + fi + VTYSH_CMD="ip route $VTYSH_NETADDR $VTYSH_GATEWAY $VTYSH_DEV tag $VTYSH_TAG $VTYSH_DISTANCE $VTYSH_VRF" + # delete route if the command is "del" if [ "$3" == "del" ] ; then VTYSH_CMD="no $VTYSH_CMD" diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup index 01981ad04..b768e1ae5 100644 --- a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup +++ b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup @@ -15,8 +15,14 @@ if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then # try to delete default ip route for router in $old_routers; do - logmsg info "Deleting default route: via $router dev ${interface}" - ip -4 route del default via $router dev ${interface} + # check if we are bound to a VRF + local vrf_name=$(basename /sys/class/net/${interface}/upper_* | sed -e 's/upper_//') + if [ -n $vrf_name ]; then + vrf="vrf $vrf_name" + fi + + logmsg info "Deleting default route: via $router dev ${interface} ${vrf}" + ip -4 route del default via $router dev ${interface} ${vrf} done # delete rfc3442 routes diff --git a/src/etc/systemd/system/LCDd.service.d/override.conf b/src/etc/systemd/system/LCDd.service.d/override.conf new file mode 100644 index 000000000..5f3f0dc95 --- /dev/null +++ b/src/etc/systemd/system/LCDd.service.d/override.conf @@ -0,0 +1,8 @@ +[Unit] +After= +After=vyos-router.service + +[Service] +ExecStart= +ExecStart=/usr/sbin/LCDd -c /run/LCDd/LCDd.conf + diff --git a/src/etc/systemd/system/hostapd@.service.d/override.conf b/src/etc/systemd/system/hostapd@.service.d/override.conf index bb8e81d7a..b03dbc299 100644 --- a/src/etc/systemd/system/hostapd@.service.d/override.conf +++ b/src/etc/systemd/system/hostapd@.service.d/override.conf @@ -3,8 +3,7 @@ After= After=vyos-router.service [Service] -WorkingDirectory=/run/hostapd -EnvironmentFile= +WorkingDirectory=/run/LCDd ExecStart= -ExecStart=/usr/sbin/hostapd -B -P /run/hostapd/%i.pid /run/hostapd/%i.conf -PIDFile=/run/hostapd/%i.pid +ExecStart=/usr/sbin/LCDd -s 1 -f -c /run/LCDd/LCDd.conf + diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py index e56952c38..29b430d53 100755 --- a/src/op_mode/ping.py +++ b/src/op_mode/ping.py @@ -118,7 +118,8 @@ options = { 'vrf': { 'ping': 'sudo ip vrf exec {value} {command}', 'type': '<vrf>', - 'help': 'Use specified VRF table' + 'help': 'Use specified VRF table', + 'dflt': 'default', }, 'verbose': { 'ping': '{command} -v', @@ -207,6 +208,11 @@ if __name__ == '__main__': sys.stdout.write(options[matched[0]]['type']) sys.exit(0) + for name,option in options.items(): + if 'dflt' in option and name not in args: + args.append(name) + args.append(option['dflt']) + try: ip = socket.gethostbyname(host) except socket.gaierror: diff --git a/src/systemd/lcdproc.service b/src/systemd/lcdproc.service new file mode 100644 index 000000000..5aa99ec78 --- /dev/null +++ b/src/systemd/lcdproc.service @@ -0,0 +1,13 @@ +[Unit] +Description=LCDproc system status information viewer on %I +Documentation=man:lcdproc(8) http://www.lcdproc.org/ +After=vyos-router.service +After=LCDd.service + +[Service] +User=root +ExecStart=/usr/bin/lcdproc -f -c /run/lcdproc/lcdproc.conf +PIDFile=/run/lcdproc/lcdproc.pid + +[Install] +WantedBy=multi-user.target |