summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py23
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py1
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py12
-rwxr-xr-xsrc/conf_mode/service_console-server.py23
-rwxr-xr-xsrc/conf_mode/vrrp.py6
-rwxr-xr-xsrc/migration-scripts/nat/4-to-56
-rwxr-xr-xsrc/services/vyos-configd22
-rwxr-xr-xsrc/system/on-dhcp-event.sh25
-rw-r--r--src/systemd/dropbear@.service5
-rw-r--r--src/tests/test_util.py4
-rwxr-xr-xsrc/validators/interface-name2
11 files changed, 96 insertions, 33 deletions
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index bf4650773..378f400b8 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -30,6 +30,7 @@ from vyos.configverify import verify_mtu
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
+from vyos.ethtool import Ethtool
from vyos.ifconfig import EthernetIf
from vyos.template import render
from vyos.util import call
@@ -82,11 +83,31 @@ def verify(ethernet):
driver = EthernetIf(ifname).get_driver_name()
# T3342 - Xen driver requires special treatment
- if driver == "vif":
+ if driver == 'vif':
if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None:
raise ConfigError('Xen netback drivers requires scatter-gatter offloading '\
'for MTU size larger then 1500 bytes')
+ ethtool = Ethtool(ifname)
+ if 'ring_buffer' in ethernet:
+ max_rx = ethtool.get_rx_buffer()
+ if not max_rx:
+ raise ConfigError('Driver does not support RX ring-buffer configuration!')
+
+ max_tx = ethtool.get_tx_buffer()
+ if not max_tx:
+ raise ConfigError('Driver does not support TX ring-buffer configuration!')
+
+ rx = dict_search('ring_buffer.rx', ethernet)
+ if rx and int(rx) > int(max_rx):
+ raise ConfigError(f'Driver only supports a maximum RX ring-buffer '\
+ f'size of "{max_rx}" bytes!')
+
+ tx = dict_search('ring_buffer.tx', ethernet)
+ if tx and int(tx) > int(max_tx):
+ raise ConfigError(f'Driver only supports a maximum TX ring-buffer '\
+ f'size of "{max_tx}" bytes!')
+
# XDP requires multiple TX queues
if 'xdp' in ethernet:
queues = glob(f'/sys/class/net/{ifname}/queues/tx-*')
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 034bd6dd1..87da214a8 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -140,7 +140,6 @@ def apply(tunnel):
'parameters.ip.ttl' : 'ttl',
'parameters.ip.tos' : 'tos',
'parameters.ip.key' : 'key',
- 'parameters.ipv6.encaplimit' : 'encaplimit'
}
# Add additional IPv6 options if tunnel is IPv6 aware
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index baf5c4159..1ce2d3e7c 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -23,6 +23,7 @@ from vyos.configdict import dict_merge
from vyos.template import render_to_string
from vyos.util import call
from vyos.util import dict_search
+from vyos.validate import is_addr_assigned
from vyos import ConfigError
from vyos import frr
from vyos import airbag
@@ -99,6 +100,13 @@ def verify(bgp):
raise ConfigError(f'Specified peer-group "{peer_group}" for '\
f'neighbor "{neighbor}" does not exist!')
+ # ttl-security and ebgp-multihop can't be used in the same configration
+ if 'ebgp_multihop' in peer_config and 'ttl_security' in peer_config:
+ raise ConfigError('You can\'t set both ebgp-multihop and ttl-security hops')
+
+ # Check spaces in the password
+ if 'password' in peer_config and ' ' in peer_config['password']:
+ raise ConfigError('You can\'t use spaces in the password')
# Some checks can/must only be done on a neighbor and not a peer-group
if neighbor == 'neighbor':
@@ -107,6 +115,10 @@ def verify(bgp):
if not verify_remote_as(peer_config, asn_config):
raise ConfigError(f'Neighbor "{peer}" remote-as must be set!')
+ # Check if neighbor address is assigned as system interface address
+ if is_addr_assigned(peer):
+ raise ConfigError(f'Can\'t configure local address as neighbor "{peer}"')
+
for afi in ['ipv4_unicast', 'ipv6_unicast', 'l2vpn_evpn']:
# Bail out early if address family is not configured
if 'address_family' not in peer_config or afi not in peer_config['address_family']:
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
index 0e5fc75b0..6e94a19ae 100755
--- a/src/conf_mode/service_console-server.py
+++ b/src/conf_mode/service_console-server.py
@@ -25,7 +25,8 @@ from vyos.util import call
from vyos.xml import defaults
from vyos import ConfigError
-config_file = r'/run/conserver/conserver.cf'
+config_file = '/run/conserver/conserver.cf'
+dropbear_systemd_file = '/etc/systemd/system/dropbear@{port}.service.d/override.conf'
def get_config(config=None):
if config:
@@ -75,9 +76,22 @@ def generate(proxy):
return None
render(config_file, 'conserver/conserver.conf.tmpl', proxy)
+ if 'device' in proxy:
+ for device in proxy['device']:
+ if 'ssh' not in proxy['device'][device]:
+ continue
+
+ tmp = {
+ 'device' : device,
+ 'port' : proxy['device'][device]['ssh']['port'],
+ }
+ render(dropbear_systemd_file.format(**tmp),
+ 'conserver/dropbear@.service.tmpl', tmp)
+
return None
def apply(proxy):
+ call('systemctl daemon-reload')
call('systemctl stop dropbear@*.service conserver-server.service')
if not proxy:
@@ -89,9 +103,10 @@ def apply(proxy):
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')
+ if 'ssh' not in proxy['device'][device]:
+ continue
+ port = proxy['device'][device]['ssh']['port']
+ call(f'systemctl restart dropbear@{port}.service')
return None
diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/vrrp.py
index 4510dd3e7..680a80859 100755
--- a/src/conf_mode/vrrp.py
+++ b/src/conf_mode/vrrp.py
@@ -75,6 +75,7 @@ def get_config(config=None):
group["backup_script"] = config.return_value("transition-script backup")
group["fault_script"] = config.return_value("transition-script fault")
group["stop_script"] = config.return_value("transition-script stop")
+ group["script_mode_force"] = config.exists("transition-script mode-force")
if config.exists("no-preempt"):
group["preempt"] = False
@@ -183,6 +184,11 @@ def verify(data):
if isinstance(pa, IPv4Address):
raise ConfigError("VRRP group {0} uses IPv6 but its peer-address is IPv4".format(group["name"]))
+ # Warn the user about the deprecated mode-force option
+ if group['script_mode_force']:
+ print("""Warning: "transition-script mode-force" VRRP option is deprecated and will be removed in VyOS 1.4.""")
+ print("""It's no longer necessary, so you can safely remove it from your config now.""")
+
# Disallow same VRID on multiple interfaces
_groups = sorted(vrrp_groups, key=(lambda x: x["interface"]))
count = len(_groups) - 1
diff --git a/src/migration-scripts/nat/4-to-5 b/src/migration-scripts/nat/4-to-5
index dda191719..b791996e2 100755
--- a/src/migration-scripts/nat/4-to-5
+++ b/src/migration-scripts/nat/4-to-5
@@ -36,9 +36,15 @@ if not config.exists(['nat']):
exit(0)
else:
for direction in ['source', 'destination']:
+ # If a node doesn't exist, we obviously have nothing to do.
if not config.exists(['nat', direction]):
continue
+ # However, we also need to handle the case when a 'source' or 'destination' sub-node does exist,
+ # but there are no rules under it.
+ if not config.list_nodes(['nat', direction]):
+ continue
+
for rule in config.list_nodes(['nat', direction, 'rule']):
base = ['nat', direction, 'rule', rule]
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index 3bd516463..1e60e53df 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -34,6 +34,8 @@ from vyos import ConfigError
CFG_GROUP = 'vyattacfg'
+script_stdout_log = '/tmp/vyos-configd-script-stdout'
+
debug = True
logger = logging.getLogger(__name__)
@@ -60,7 +62,8 @@ configd_env_unset_file = os.path.join(directories['data'], 'vyos-configd-env-uns
# sourced on entering config session
configd_env_file = '/etc/default/vyos-configd-env'
-session_tty = None
+session_out = None
+session_mode = None
def key_name_from_file_name(f):
return os.path.splitext(f)[0]
@@ -109,7 +112,7 @@ include_set = {key_name_from_file_name(f) for f in filenames if f in include}
def run_script(script, config) -> int:
config.set_level([])
try:
- with open(session_tty, 'w') as f, redirect_stdout(f):
+ with open(session_out, session_mode) as f, redirect_stdout(f):
with redirect_stderr(f):
c = script.get_config(config)
script.verify(c)
@@ -117,7 +120,7 @@ def run_script(script, config) -> int:
script.apply(c)
except ConfigError as e:
logger.critical(e)
- with open(session_tty, 'w') as f, redirect_stdout(f):
+ with open(session_out, session_mode) as f, redirect_stdout(f):
print(f"{e}\n")
return R_ERROR_COMMIT
except Exception as e:
@@ -127,7 +130,8 @@ def run_script(script, config) -> int:
return R_SUCCESS
def initialization(socket):
- global session_tty
+ global session_out
+ global session_mode
# Reset config strings:
active_string = ''
session_string = ''
@@ -155,9 +159,15 @@ def initialization(socket):
logger.debug(f"config session pid is {pid_string}")
try:
- session_tty = os.readlink(f"/proc/{pid_string}/fd/1")
+ session_out = os.readlink(f"/proc/{pid_string}/fd/1")
+ session_mode = 'w'
except FileNotFoundError:
- session_tty = None
+ session_out = None
+
+ # if not a 'live' session, for example on boot, write to file
+ if not session_out or '/dev/pts' not in session_out:
+ session_out = script_stdout_log
+ session_mode = 'a'
try:
configsource = ConfigSourceString(running_config_text=active_string,
diff --git a/src/system/on-dhcp-event.sh b/src/system/on-dhcp-event.sh
index a062dc810..49e53d7e1 100755
--- a/src/system/on-dhcp-event.sh
+++ b/src/system/on-dhcp-event.sh
@@ -21,21 +21,20 @@ client_mac=$4
domain=$5
hostsd_client="/usr/bin/vyos-hostsd-client"
-if [ -z "$client_name" ]; then
- logger -s -t on-dhcp-event "Client name was empty, using MAC \"$client_mac\" instead"
- client_name=$(echo "client-"$client_mac | tr : -)
-fi
-
-if [ "$domain" == "..YYZ!" ]; then
- client_fqdn_name=$client_name
- client_search_expr=$client_name
-else
- client_fqdn_name=$client_name.$domain
- client_search_expr="$client_name\\.$domain"
-fi
-
case "$action" in
commit) # add mapping for new lease
+ if [ -z "$client_name" ]; then
+ logger -s -t on-dhcp-event "Client name was empty, using MAC \"$client_mac\" instead"
+ client_name=$(echo "client-"$client_mac | tr : -)
+ fi
+
+ if [ "$domain" == "..YYZ!" ]; then
+ client_fqdn_name=$client_name
+ client_search_expr=$client_name
+ else
+ client_fqdn_name=$client_name.$domain
+ client_search_expr="$client_name\\.$domain"
+ fi
$hostsd_client --add-hosts "$client_fqdn_name,$client_ip" --tag "dhcp-server-$client_ip" --apply
exit 0
;;
diff --git a/src/systemd/dropbear@.service b/src/systemd/dropbear@.service
index a3fde5708..acf926af9 100644
--- a/src/systemd/dropbear@.service
+++ b/src/systemd/dropbear@.service
@@ -8,9 +8,8 @@ StartLimitIntervalSec=0
[Service]
Type=forking
-ExecStartPre=/usr/bin/bash -c '/usr/bin/systemctl set-environment PORT=$(cli-shell-api returnActiveValue service console-server device "%I" ssh port)'
-ExecStart=-/usr/sbin/dropbear -w -j -k -r /etc/dropbear/dropbear_rsa_host_key -c "/usr/bin/console %I" -P /run/conserver/dropbear.%I.pid -p ${PORT}
-PIDFile=/run/conserver/dropbear.%I.pid
+ExecStart=/usr/sbin/dropbear -w -j -k -r /etc/dropbear/dropbear_rsa_host_key -P /run/dropbear/dropbear.%I.pid -p %I
+PIDFile=/run/dropbear/dropbear.%I.pid
KillMode=process
Restart=always
RestartSec=10
diff --git a/src/tests/test_util.py b/src/tests/test_util.py
index f7405cbde..22bc085c5 100644
--- a/src/tests/test_util.py
+++ b/src/tests/test_util.py
@@ -17,11 +17,7 @@
from unittest import TestCase
from vyos.util import mangle_dict_keys
-
class TestVyOSUtil(TestCase):
- def setUp(self):
- pass
-
def test_key_mangline(self):
data = {"foo-bar": {"baz-quux": None}}
expected_data = {"foo_bar": {"baz_quux": None}}
diff --git a/src/validators/interface-name b/src/validators/interface-name
index 8e337b401..72e9fd54a 100755
--- a/src/validators/interface-name
+++ b/src/validators/interface-name
@@ -17,7 +17,7 @@
import re
import sys
-pattern = '^(bond|br|dum|en|ersp|eth|gnv|lan|l2tp|l2tpeth|macsec|peth|ppp|pppoe|pptp|sstp|tun|vti|vtun|vxlan|wg|wlan|wlm)[0-9]+|lo$'
+pattern = '^(bond|br|dum|en|ersp|eth|gnv|lan|l2tp|l2tpeth|macsec|peth|ppp|pppoe|pptp|sstp|tun|vti|vtun|vxlan|wg|wlan|wlm)[0-9]+(.\d+)?|lo$'
if __name__ == '__main__':
if len(sys.argv) != 2: