summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/pppoe/ip-down.script.tmpl18
-rw-r--r--data/templates/pppoe/ip-up.script.tmpl36
-rw-r--r--data/templates/wwan/ip-up.script.tmpl11
-rw-r--r--interface-definitions/interfaces-wireless.xml.in2
-rw-r--r--python/vyos/ifconfig/control.py30
-rw-r--r--python/vyos/ifconfig/ethernet.py27
-rw-r--r--python/vyos/util.py38
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py9
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py4
-rwxr-xr-xsrc/op_mode/show_openvpn.py4
10 files changed, 124 insertions, 55 deletions
diff --git a/data/templates/pppoe/ip-down.script.tmpl b/data/templates/pppoe/ip-down.script.tmpl
index f90da02bc..e76875f12 100644
--- a/data/templates/pppoe/ip-down.script.tmpl
+++ b/data/templates/pppoe/ip-down.script.tmpl
@@ -2,7 +2,6 @@
# As PPPoE is an "on demand" interface we need to re-configure it when it
# becomes up
-
if [ "$6" != "{{ intf }}" ]; then
exit
fi
@@ -11,6 +10,17 @@ fi
DIALER_PID=$(cat /var/run/{{ intf }}.pid)
logger -t pppd[$DIALER_PID] "executing $0"
-# Debian PPP version has no support for replacing an existing default route
-# thus we emulate this ba an ip-up script https://phabricator.vyos.net/T2220.
-vtysh -c "conf t" -c "no ip route 0.0.0.0/0 {{ intf }}"
+# Determine if we are enslaved to a VRF, this is needed to properly insert
+# the default route
+VRF_NAME=""
+if [ -d /sys/class/net/{{ intf }}/upper_* ]; then
+ # Determine upper (VRF) interface
+ VRF=$(basename $(ls -d /sys/class/net/{{ intf }}/upper_*))
+ # Remove upper_ prefix from result string
+ VRF=${VRF#"upper_"}
+ # Populate variable to run in VR context
+ VRF_NAME="vrf ${VRF_NAME}"
+fi
+
+# Always delete default route when interface goes down
+vtysh -c "conf t" ${VRF_NAME} -c "no ip route 0.0.0.0/0 {{ intf }} ${VRF_NAME}"
diff --git a/data/templates/pppoe/ip-up.script.tmpl b/data/templates/pppoe/ip-up.script.tmpl
index c6aa02e9e..4cc779914 100644
--- a/data/templates/pppoe/ip-up.script.tmpl
+++ b/data/templates/pppoe/ip-up.script.tmpl
@@ -6,28 +6,42 @@ if [ "$6" != "{{ intf }}" ]; then
exit
fi
+set -x
+
# add some info to syslog
DIALER_PID=$(cat /var/run/{{ intf }}.pid)
logger -t pppd[$DIALER_PID] "executing $0"
+SED_OPT="ip route"
+VRF_NAME=""
+if [ -d /sys/class/net/{{ intf }}/upper_* ]; then
+ # Determine upper (VRF) interface
+ VRF=$(basename $(ls -d /sys/class/net/{{ intf }}/upper_*))
+ # Remove upper_ prefix from result string
+ VRF=${VRF#"upper_"}
+ # generate new SED command
+ SED_OPT="vrf ${VRF}"
+ # generate vtysh option
+ VRF_NAME="vrf ${VRF}"
+fi
+
# Debian PPP version has no support for replacing an existing default route
# thus we emulate this ba an ip-up script https://phabricator.vyos.net/T2220.
-
{% if 'auto' in default_route -%}
-
# only insert a new default route if there is no default route configured
-routes=$(vtysh -c "show running-config" | sed -n "/ip route/,/!/p" | grep 0.0.0.0/0 | wc -l)
-if [ "$routes" -eq 0 ]; then
- # No VRF, use default routing table
- vtysh -c "conf t" -c "ip route 0.0.0.0/0 {{ intf }}"
+routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | wc -l)
+if [ "$routes" -ne 0 ]; then
+ exit 1
fi
{% elif 'force' in default_route -%}
-
# Retrieve current static default routes and remove it from the routing table
-vtysh -c "show running-config" | sed -n "/ip route/,/!/p" | grep 0.0.0.0/0 | while read route ; do
- vtysh -c "conf t" -c "no ${route}"
+vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | while read route ; do
+ vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}"
done
-# No VRF, use default routing table
-vtysh -c "conf t" -c "ip route 0.0.0.0/0 {{ intf }}"
{% endif %}
+
+# Add default route to default or VRF routing table
+vtysh -c "conf t" ${VTY_OPT} -c "ip route 0.0.0.0/0 {{ intf }} ${VRF_NAME}"
+logger -t pppd[$DIALER_PID] "added default route via {{ intf }} ${VRF_NAME}"
+
diff --git a/data/templates/wwan/ip-up.script.tmpl b/data/templates/wwan/ip-up.script.tmpl
index 7382309ac..89e42a23a 100644
--- a/data/templates/wwan/ip-up.script.tmpl
+++ b/data/templates/wwan/ip-up.script.tmpl
@@ -7,6 +7,8 @@ if [ -z "$(echo $tty | egrep "tty(USB|ACM)")" ]; then
exit 0
fi
+DIALER_PID=$(cat /var/run/{{ intf }}.pid)
+
# Determine if we are enslaved to a VRF, this is needed to properly insert
# the default route
VRF_NAME=""
@@ -15,12 +17,9 @@ if [ -d /sys/class/net/{{ intf }}/upper_* ]; then
VRF=$(basename $(ls -d /sys/class/net/{{ intf }}/upper_*))
# Remove upper_ prefix from result string
VRF=${VRF#"upper_"}
- # Populate variable to run in VR context
- VRF_NAME=" -c vrf ${VRF_NAME} "
+ VRF_NAME="vrf ${VRF}"
fi
# Apply default route to either default or VRF routing table
-vtysh -c "conf t" ${VRF_NAME} -c "ip route 0.0.0.0/0 {{ intf }} {{ metric }}"
-
-DIALER_PID=$(cat /var/run/{{ intf }}.pid)
-logger -t pppd[$DIALER_PID] "added default route via {{ intf }} metric {{ metric }}"
+vtysh -c "conf t" -c "ip route 0.0.0.0/0 {{ intf }} ${VRF_NAME} {{ metric }}"
+logger -t pppd[$DIALER_PID] "added default route via {{ intf }} metric {{ metric }} ${VRF_NAME}"
diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in
index 12736510b..490e63a42 100644
--- a/interface-definitions/interfaces-wireless.xml.in
+++ b/interface-definitions/interfaces-wireless.xml.in
@@ -320,7 +320,7 @@
<properties>
<help>VHT link adaptation capabilities</help>
<completionHelp>
- <list>single-user-beamformer single-user-beamformee multi-user-beamformer multi-user-beamformee</list>
+ <list>unsolicited both</list>
</completionHelp>
<valueHelp>
<format>unsolicited</format>
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py
index c1a073aef..c7a2fa2d6 100644
--- a/python/vyos/ifconfig/control.py
+++ b/python/vyos/ifconfig/control.py
@@ -15,8 +15,9 @@
import os
-from subprocess import Popen, PIPE, STDOUT
+from vyos.util import debug, debug_msg
+from vyos.util import popen, cmd
from vyos.ifconfig.register import Register
@@ -32,27 +33,18 @@ class Control(Register):
# to prevent this, debugging can be explicitely disabled
# if debug is not explicitely disabled the the config, enable it
- self.debug = kargs.get('debug', True)
+ self.debug = ''
+ if kargs.get('debug', True):
+ self.debug = debug('ifconfig')
- def _debug_msg(self, msg):
- if os.path.isfile('/tmp/vyos.ifconfig.debug') and self.debug:
- print('DEBUG/{:<6} {}'.format(self.config['ifname'], msg))
+ def _debug_msg (self, message):
+ return debug_msg(message, self.debug)
def _popen(self, command):
- p = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True)
- tmp = p.communicate()[0].strip()
- self._debug_msg(f"cmd '{command}'")
- decoded = tmp.decode()
- if decoded:
- self._debug_msg(f"returned:\n{decoded}")
- return decoded, p.returncode
+ return popen(command, self.debug)
def _cmd(self, command):
- decoded, code = self._popen(command)
- if code != 0:
- # error code can be recovered with .errno
- raise OSError(code, f'{command}\nreturned: {decoded}')
- return decoded
+ return cmd(command, self.debug)
def _get_command(self, config, name):
"""
@@ -79,6 +71,10 @@ class Control(Register):
if convert:
value = convert(value)
+ possible = self._command_set[name].get('possible', None)
+ if possible and not possible(config['ifname'], value):
+ return False
+
config = {**config, **{'value': value}}
cmd = self._command_set[name]['shellcmd'].format(**config)
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 50552dc71..c18d2e72f 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -18,7 +18,7 @@ import re
from vyos.ifconfig.interface import Interface
from vyos.ifconfig.vlan import VLAN
-
+from vyos.util import popen
from vyos.validate import *
@@ -43,27 +43,36 @@ class EthernetIf(Interface):
}
}
+ @staticmethod
+ def feature(ifname, option, value):
+ out, code = popen(f'/sbin/ethtool -K {ifname} {option} {value}','ifconfig')
+ return False
_command_set = {**Interface._command_set, **{
'gro': {
'validate': lambda v: assert_list(v, ['on', 'off']),
- 'shellcmd': '/sbin/ethtool -K {ifname} gro {value}',
+ 'possible': lambda i, v: EthernetIf.feature(i, 'gro', v),
+ # 'shellcmd': '/sbin/ethtool -K {ifname} gro {value}',
},
'gso': {
'validate': lambda v: assert_list(v, ['on', 'off']),
- 'shellcmd': '/sbin/ethtool -K {ifname} gso {value}',
+ 'possible': lambda i, v: EthernetIf.feature(i, 'gso', v),
+ # 'shellcmd': '/sbin/ethtool -K {ifname} gso {value}',
},
'sg': {
'validate': lambda v: assert_list(v, ['on', 'off']),
- 'shellcmd': '/sbin/ethtool -K {ifname} sg {value}',
+ 'possible': lambda i, v: EthernetIf.feature(i, 'sg', v),
+ # 'shellcmd': '/sbin/ethtool -K {ifname} sg {value}',
},
'tso': {
'validate': lambda v: assert_list(v, ['on', 'off']),
- 'shellcmd': '/sbin/ethtool -K {ifname} tso {value}',
+ 'possible': lambda i, v: EthernetIf.feature(i, 'tso', v),
+ # 'shellcmd': '/sbin/ethtool -K {ifname} tso {value}',
},
'ufo': {
'validate': lambda v: assert_list(v, ['on', 'off']),
- 'shellcmd': '/sbin/ethtool -K {ifname} ufo {value}',
+ 'possible': lambda i, v: EthernetIf.feature(i, 'ufo', v),
+ # 'shellcmd': '/sbin/ethtool -K {ifname} ufo {value}',
},
}}
@@ -245,8 +254,4 @@ class EthernetIf(Interface):
>>> i = EthernetIf('eth0')
>>> i.set_udp_offload('on')
"""
- if state not in ['on', 'off']:
- raise ValueError('state must be "on" or "off"')
-
- cmd = '/sbin/ethtool -K {} ufo {}'.format(self.config['ifname'], state)
- return self._cmd(cmd)
+ return self.set_interface('ufo', state)
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 5807c837d..781fd9a2c 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -16,6 +16,44 @@
import os
import re
import sys
+from subprocess import Popen, PIPE, STDOUT
+
+
+# debugging
+
+
+def debug(flag):
+ return flag if os.path.isfile(f'/tmp/vyos.{flag}.debug') else ''
+
+
+def debug_msg(message, section=''):
+ if section:
+ print(f'DEBUG/{section:<6} {message}')
+
+
+# commands
+
+
+def popen(command, section=''):
+ p = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True)
+ tmp = p.communicate()[0].strip()
+ debug_msg(f"cmd '{command}'", section)
+ decoded = tmp.decode()
+ if decoded:
+ debug_msg(f"returned:\n{decoded}", section)
+ return decoded, p.returncode
+
+
+def cmd(command, section=''):
+ decoded, code = popen(command, section)
+ if code != 0:
+ # error code can be recovered with .errno
+ raise OSError(code, f'{command}\nreturned: {decoded}')
+ return decoded
+
+
+# file manipulation
+
def subprocess_cmd(command):
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index fb2d6e6d9..9bac4d759 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -66,6 +66,10 @@ proto {% if 'tcp-active' in protocol -%}tcp-client{% elif 'tcp-passive' in proto
local {{ local_host }}
{% endif %}
+{%- if mode == 'server' and protocol == 'udp' and not local_host %}
+multihome
+{% endif %}
+
{%- if local_port %}
lport {{ local_port }}
{% endif %}
@@ -308,7 +312,7 @@ default_config_data = {
'ncp_ciphers': '',
'options': [],
'persistent_tunnel': False,
- 'protocol': '',
+ 'protocol': 'udp',
'redirect_gateway': '',
'remote_address': '',
'remote_host': [],
@@ -512,8 +516,7 @@ def get_config():
# OpenVPN operation mode
if conf.exists('mode'):
- mode = conf.return_value('mode')
- openvpn['mode'] = mode
+ openvpn['mode'] = conf.return_value('mode')
# Additional OpenVPN options
if conf.exists('openvpn-option'):
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index f7ecb098e..3c20c3025 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -799,7 +799,7 @@ default_config_data = {
'cap_vht_center_freq_2' : '',
'cap_vht_chan_set_width' : '',
'cap_vht_ldpc' : False,
- 'cap_vht_link_adaptation' : False,
+ 'cap_vht_link_adaptation' : '',
'cap_vht_max_mpdu_exp' : '',
'cap_vht_max_mpdu' : '',
'cap_vht_short_gi' : [],
@@ -1043,7 +1043,7 @@ def get_config():
# VHT link adaptation capabilities
if conf.exists('capabilities vht link-adaptation'):
wifi['cap_vht'] = True
- wifi['cap_vht_link_adaptation'] = True
+ wifi['cap_vht_link_adaptation'] = conf.return_value('capabilities vht link-adaptation')
# Set the maximum length of A-MPDU pre-EOF padding that the station can receive
if conf.exists('capabilities vht max-mpdu-exp'):
diff --git a/src/op_mode/show_openvpn.py b/src/op_mode/show_openvpn.py
index 06b90296f..32918ddce 100755
--- a/src/op_mode/show_openvpn.py
+++ b/src/op_mode/show_openvpn.py
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+import os
import jinja2
import argparse
@@ -63,6 +64,9 @@ def get_status(mode, interface):
'clients': [],
}
+ if not os.path.exists(status_file):
+ return data
+
with open(status_file, 'r') as f:
lines = f.readlines()
for line_no, line in enumerate(lines):