diff options
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-x | src/conf_mode/interfaces-pppoe.py | 82 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 9 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wirelessmodem.py | 88 |
3 files changed, 107 insertions, 72 deletions
diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index f318614db..9c045534c 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -20,12 +20,10 @@ from sys import exit from copy import deepcopy from jinja2 import Template from subprocess import Popen, PIPE -from pwd import getpwnam -from grp import getgrnam -from stat import S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IXGRP, S_IROTH, S_IXOTH from vyos.config import Config from vyos.ifconfig import Interface +from vyos.util import chown_file, chmod_x_file from vyos import ConfigError from netifaces import interfaces @@ -112,15 +110,11 @@ if [ "$6" != "{{ intf }}" ]; then exit fi +{% if ipv6_autoconf -%} # add some info to syslog DIALER_PID=$(cat /var/run/{{ intf }}.pid) logger -t pppd[$DIALER_PID] "executing $0" -logger -t pppd[$DIALER_PID] "configuring dialer interface $6 via $2" - -echo "{{ description }}" > /sys/class/net/{{ intf }}/ifalias - -{% if ipv6_autoconf -%} - +logger -t pppd[$DIALER_PID] "configuring interface {{ intf }} via $2" # Configure interface-specific Host/Router behaviour. # Note: It is recommended to have the same setting on all interfaces; mixed @@ -150,12 +144,12 @@ echo 1 > /proc/sys/net/ipv6/conf/{{ intf }}/autoconfigure {% endif %} """ -config_pppoe_ip_pre_up_tmpl = """#!/bin/sh +config_pppoe_ip_up_tmpl = """#!/bin/sh # As PPPoE is an "on demand" interface we need to re-configure it when it # becomes up -if [ "$6" != "pppoe0" ]; then +if [ "$6" != "{{ intf }}" ]; then exit fi @@ -163,6 +157,8 @@ fi DIALER_PID=$(cat /var/run/{{ intf }}.pid) logger -t pppd[$DIALER_PID] "executing $0" +echo "{{ description }}" > /sys/class/net/{{ intf }}/ifalias + {% if vrf -%} logger -t pppd[$DIALER_PID] "configuring dialer interface $6 for VRF {{ vrf }}" ip link set dev {{ intf }} master {{ vrf }} @@ -305,61 +301,49 @@ def verify(pppoe): return None def generate(pppoe): - config_file_pppoe = f"/etc/ppp/peers/{pppoe['intf']}" - ip_pre_up_script_file = f"/etc/ppp/ip-pre-up.d/9999-vyos-vrf-{pppoe['intf']}" - ipv6_if_up_script_file = f"/etc/ppp/ipv6-up.d/50-vyos-{pppoe['intf']}-autoconf" + intf = pppoe['intf'] + config_file_pppoe = f'/etc/ppp/peers/{intf}' + ip_up_script_file = f'/etc/ppp/ip-up.d/9990-vyos-vrf-{intf}' + ipv6_if_up_script_file = f'/etc/ppp/ipv6-up.d/9990-vyos-autoconf-{intf}' + + config_files = [config_file_pppoe, ip_up_script_file, ipv6_if_up_script_file] + + # Ensure directories for config files exist - otherwise create them on demand + for file in config_files: + dirname = os.path.dirname(file) + if not os.path.isdir(dirname): + os.mkdir(dirname) # Always hang-up PPPoE connection prior generating new configuration file - cmd = f"systemctl stop ppp@{pppoe['intf']}.service" + cmd = f'systemctl stop ppp@{intf}.service' subprocess_cmd(cmd) if pppoe['deleted']: # Delete PPP configuration files - if os.path.exists(config_file_pppoe): - os.unlink(config_file_pppoe) - - if os.path.exists(ipv6_if_up_script_file): - os.unlink(ipv6_if_up_script_file) - - if os.path.exists(ip_pre_up_script_file): - os.unlink(ip_pre_up_script_file) + for file in config_files: + if os.path.exists(file): + os.unlink(file) else: - # PPP peers directory - dirname = os.path.dirname(config_file_pppoe) - if not os.path.isdir(dirname): - os.mkdir(dirname) - # Create PPP configuration files tmpl = Template(config_pppoe_tmpl) config_text = tmpl.render(pppoe) with open(config_file_pppoe, 'w') as f: f.write(config_text) - # PPP ip-pre-up.d scripting directory - dirname = os.path.dirname(ip_pre_up_script_file) - if not os.path.isdir(dirname): - os.mkdir(dirname) - - tmpl = Template(config_pppoe_ip_pre_up_tmpl) + tmpl = Template(config_pppoe_ip_up_tmpl) config_text = tmpl.render(pppoe) - with open(ip_pre_up_script_file, 'w') as f: + with open(ip_up_script_file, 'w') as f: f.write(config_text) - # PPP ipv6-up.d scripting directory - dirname = os.path.dirname(ipv6_if_up_script_file) - if not os.path.isdir(dirname): - os.mkdir(dirname) - tmpl = Template(config_pppoe_ipv6_up_tmpl) config_text = tmpl.render(pppoe) with open(ipv6_if_up_script_file, 'w') as f: f.write(config_text) - bitmask = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | \ - S_IROTH | S_IXOTH - os.chmod(ip_pre_up_script_file, bitmask) - os.chmod(ipv6_if_up_script_file, bitmask) + # make generated script file executable + chmod_x_file(ip_up_script_file) + chmod_x_file(ipv6_if_up_script_file) return None @@ -369,15 +353,13 @@ def apply(pppoe): return None if not pppoe['disable']: - # dial PPPoE connection - cmd = f"systemctl start ppp@{pppoe['intf']}.service" + # "dial" PPPoE connection + intf = pppoe['intf'] + cmd = f'systemctl start ppp@{intf}.service' subprocess_cmd(cmd) # make logfile owned by root / vyattacfg - if os.path.isfile(pppoe['logfile']): - uid = getpwnam('root').pw_uid - gid = getgrnam('vyattacfg').gr_gid - os.chown(pppoe['logfile'], uid, gid) + chown_file(pppoe['logfile'], 'root', 'vyattacfg') return None diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 4cbb51f4a..646e61c53 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -138,6 +138,9 @@ default_config_data = { 'ip': False, 'ipv6': False, 'nhrp': [], + 'ipv6_autoconf': 0, + 'ipv6_forwarding': 1, + 'ipv6_dad_transmits': 1, # internal 'tunnel': {}, # the following names are exactly matching the name @@ -183,6 +186,9 @@ mapping = { 'link_detect': ('disable-link-detect', False, 2), 'vrf': ('vrf', False, None), 'addresses-add': ('address', True, None), + 'ipv6_autoconf': ('ipv6 address autoconf', False, 1), + 'ipv6_forwarding': ('ipv6 disable-forwarding', False, 0), + 'ipv6_dad_transmits:': ('ipv6 dup-addr-detect-transmits', False, None) } def get_class (options): @@ -468,7 +474,8 @@ def apply(conf): tunnel.set_interface(option, options[option]) # set other interface properties - for option in ('alias', 'mtu', 'link_detect', 'multicast', 'allmulticast', 'vrf'): + for option in ('alias', 'mtu', 'link_detect', 'multicast', 'allmulticast', + 'vrf', 'ipv6_autoconf', 'ipv6_forwarding', 'ipv6_dad_transmits'): tunnel.set_interface(option, options[option]) # Configure interface address(es) diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index 9efad3b8d..7aee5c9bd 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -20,10 +20,10 @@ from sys import exit from copy import deepcopy from jinja2 import Template from subprocess import Popen, PIPE -from pwd import getpwnam -from grp import getgrnam +from netifaces import interfaces from vyos.config import Config +from vyos.util import chown_file, chmod_x_file from vyos import ConfigError # Please be careful if you edit the template. @@ -70,6 +70,32 @@ CONNECT '' """ +config_wwan_ip_up_tmpl = """#!/bin/sh +# As WWAN is an "on demand" interface we need to re-configure it when it +# becomes 'up' + +ipparam=$6 + +# device name and metric are received using ipparam +device=`echo "$ipparam"|awk '{ print $1 }'` + +if [ "$device" != "{{ intf }}" ]; then + exit +fi + +# add some info to syslog +DIALER_PID=$(cat /var/run/{{ intf }}.pid) +logger -t pppd[$DIALER_PID] "executing $0" + +echo "{{ description }}" > /sys/class/net/{{ intf }}/ifalias + +{% if vrf -%} +logger -t pppd[$DIALER_PID] "configuring interface {{ intf }} for VRF {{ vrf }}" +ip link set dev {{ intf }} master {{ vrf }} +{% endif %} + +""" + default_config_data = { 'address': [], 'apn': '', @@ -84,7 +110,8 @@ default_config_data = { 'metric': '10', 'mtu': '1500', 'name_server': True, - 'intf': '' + 'intf': '', + 'vrf': '' } def subprocess_cmd(command): @@ -154,6 +181,10 @@ def get_config(): if conf.exists(['ondemand']): wwan['on_demand'] = True + # retrieve VRF instance + if conf.exists('vrf'): + wwan['vrf'] = conf.return_value(['vrf']) + return wwan def verify(wwan): @@ -168,41 +199,58 @@ def verify(wwan): if not os.path.exists(f"/dev/{wwan['device']}"): raise ConfigError(f"Device {wwan['device']} does not exist") + vrf_name = wwan['vrf'] + if vrf_name and vrf_name not in interfaces(): + raise ConfigError(f'VRF {vrf_name} does not exist') + return None def generate(wwan): - config_file_wwan = f"/etc/ppp/peers/{wwan['intf']}" + intf = wwan['intf'] + config_file_wwan = f'/etc/ppp/peers/{intf}' + config_file_wwan_chat = wwan['chat_script'] + ip_up_script_file = f'/etc/ppp/ip-up.d/9991-vyos-vrf-{intf}' + + config_files = [config_file_wwan, config_file_wwan_chat, ip_up_script_file] + + # Ensure directories for config files exist - otherwise create them on demand + for file in config_files: + dirname = os.path.dirname(file) + if not os.path.isdir(dirname): + os.mkdir(dirname) # Always hang-up WWAN connection prior generating new configuration file - cmd = f"systemctl stop ppp@{wwan['intf']}.service" + cmd = f'systemctl stop ppp@{intf}.service' subprocess_cmd(cmd) if wwan['deleted']: # Delete PPP configuration files - if os.path.exists(config_file_wwan): - os.unlink(config_file_wwan) - if os.path.exists(wwan['chat_script']): - os.unlink(wwan['chat_script']) + for file in config_files: + if os.path.exists(file): + os.unlink(file) else: - # PPP peers directory - dirname = os.path.dirname(config_file_wwan) - if not os.path.isdir(dirname): - os.mkdir(dirname) - # Create PPP configuration files tmpl = Template(config_wwan_tmpl) config_text = tmpl.render(wwan) with open(config_file_wwan, 'w') as f: f.write(config_text) - # Create PPP chat script tmpl = Template(chat_wwan_tmpl) config_text = tmpl.render(wwan) with open(wwan['chat_script'], 'w') as f: f.write(config_text) + # Create ip-pre-up script + tmpl = Template(config_wwan_ip_up_tmpl) + config_text = tmpl.render(wwan) + with open(ip_up_script_file, 'w') as f: + f.write(config_text) + + # make generated script file executable + chmod_x_file(ip_up_script_file) + return None def apply(wwan): @@ -211,15 +259,13 @@ def apply(wwan): return None if not wwan['disable']: - # dial WWAN connection - cmd = f"systemctl start ppp@{wwan['intf']}.service" + # "dial" WWAN connection + intf = wwan['intf'] + cmd = f'systemctl start ppp@{intf}.service' subprocess_cmd(cmd) # make logfile owned by root / vyattacfg - if os.path.isfile(wwan['logfile']): - uid = getpwnam('root').pw_uid - gid = getgrnam('vyattacfg').gr_gid - os.chown(wwan['logfile'], uid, gid) + chown_file(wwan['logfile'], 'root', 'vyattacfg') return None |