From 961eab48de35d1574e5efbbc43b3b57bfa09c93e Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Thu, 21 Nov 2024 21:54:40 +0100
Subject: [PATCH 01/18] pki: T3642: Minimize `node_changed` code
---
src/conf_mode/pki.py | 32 ++++++--------------------------
1 file changed, 6 insertions(+), 26 deletions(-)
diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py
index 45e0129a33..4ff15d56e1 100755
--- a/src/conf_mode/pki.py
+++ b/src/conf_mode/pki.py
@@ -149,35 +149,15 @@ def get_config(config=None):
if len(argv) > 1 and argv[1] == 'certbot_renew':
pki['certbot_renew'] = {}
- tmp = node_changed(conf, base + ['ca'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'ca' : tmp})
-
- tmp = node_changed(conf, base + ['certificate'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'certificate' : tmp})
-
- tmp = node_changed(conf, base + ['dh'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'dh' : tmp})
+ changed_keys = ['ca', 'certificate', 'dh', 'key-pair', 'openssh', 'openvpn']
- tmp = node_changed(conf, base + ['key-pair'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'key_pair' : tmp})
+ for key in changed_keys:
+ tmp = node_changed(conf, base + [key], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- tmp = node_changed(conf, base + ['openssh'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'openssh' : tmp})
+ if 'changed' not in pki:
+ pki.update({'changed':{}})
- tmp = node_changed(conf, base + ['openvpn', 'shared-secret'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
- if tmp:
- if 'changed' not in pki: pki.update({'changed':{}})
- pki['changed'].update({'openvpn' : tmp})
+ pki['changed'].update({key.replace('-', '_') : tmp})
# We only merge on the defaults of there is a configuration at all
if conf.exists(base):
From 0358f6c660e6130b94ca8c53ec7b34d796605dd8 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Thu, 21 Nov 2024 22:05:49 +0100
Subject: [PATCH 02/18] pki: T6809: Support system install of CA certificates
---
interface-definitions/pki.xml.in | 6 ++++++
python/vyos/defaults.py | 3 ++-
src/conf_mode/pki.py | 29 +++++++++++++++++++++++++++++
src/init/vyos-router | 6 ++++++
4 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/interface-definitions/pki.xml.in b/interface-definitions/pki.xml.in
index b922771c17..c69886a4b5 100644
--- a/interface-definitions/pki.xml.in
+++ b/interface-definitions/pki.xml.in
@@ -35,6 +35,12 @@
+
+
+ Install into CA certificate store on router
+
+
+
#include
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index dec619d3eb..4259909676 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -36,7 +36,8 @@
'isc_dhclient_dir' : '/run/dhclient',
'dhcp6_client_dir' : '/run/dhcp6c',
'vyos_configdir' : '/opt/vyatta/config',
- 'completion_dir' : f'{base_dir}/completion'
+ 'completion_dir' : f'{base_dir}/completion',
+ 'ca_certificates' : '/usr/local/share/ca-certificates/vyos'
}
config_status = '/tmp/vyos-config-status'
diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py
index 4ff15d56e1..acea2c9be1 100755
--- a/src/conf_mode/pki.py
+++ b/src/conf_mode/pki.py
@@ -50,6 +50,7 @@
airbag.enable()
vyos_certbot_dir = directories['certbot']
+vyos_ca_certificates_dir = directories['ca_certificates']
# keys to recursively search for under specified path
sync_search = [
@@ -397,10 +398,33 @@ def verify(pki):
return None
+def cleanup_system_ca():
+ if not os.path.exists(vyos_ca_certificates_dir):
+ os.mkdir(vyos_ca_certificates_dir)
+ else:
+ for filename in os.listdir(vyos_ca_certificates_dir):
+ full_path = os.path.join(vyos_ca_certificates_dir, filename)
+ if os.path.isfile(full_path):
+ os.unlink(full_path)
+
def generate(pki):
if not pki:
+ cleanup_system_ca()
return None
+ # Create or cleanup CA install directory
+ if 'changed' in pki and 'ca' in pki['changed']:
+ cleanup_system_ca()
+
+ if 'ca' in pki:
+ for ca, ca_conf in pki['ca'].items():
+ if 'system_install' in ca_conf:
+ ca_obj = load_certificate(ca_conf['certificate'])
+ ca_path = os.path.join(vyos_ca_certificates_dir, f'{ca}.crt')
+
+ with open(ca_path, 'w') as f:
+ f.write(encode_certificate(ca_obj))
+
# Certbot renewal only needs to re-trigger the services to load up the
# new PEM file
if 'certbot_renew' in pki:
@@ -467,6 +491,7 @@ def apply(pki):
systemd_certbot_name = 'certbot.timer'
if not pki:
call(f'systemctl stop {systemd_certbot_name}')
+ call('update-ca-certificates')
return None
has_certbot = False
@@ -484,6 +509,10 @@ def apply(pki):
if 'changed' in pki:
call_dependents()
+ # Rebuild ca-certificates bundle
+ if 'ca' in pki['changed']:
+ call('update-ca-certificates')
+
return None
if __name__ == '__main__':
diff --git a/src/init/vyos-router b/src/init/vyos-router
index 8825cc16aa..f8cc875078 100755
--- a/src/init/vyos-router
+++ b/src/init/vyos-router
@@ -471,6 +471,12 @@ start ()
touch /tmp/vyos.smoketest.debug
fi
+ # Cleanup PKI CAs
+ if [ -d /usr/local/share/ca-certificates/vyos ]; then
+ rm -f /usr/local/share/ca-certificates/vyos/*.crt
+ update-ca-certificates >/dev/null 2>&1
+ fi
+
log_action_begin_msg "Mounting VyOS Config"
# ensure the vyatta_configdir supports a large number of inodes since
# the config hierarchy is often inode-bound (instead of size).
From 67f51b67416c84c23086f997954be1d51502637d Mon Sep 17 00:00:00 2001
From: Lucas Christian
Date: Mon, 25 Nov 2024 22:01:34 -0800
Subject: [PATCH 03/18] T6630: ntp: fix timestamp nested under ptp
---
data/templates/chrony/chrony.conf.j2 | 4 +-
interface-definitions/service_ntp.xml.in | 96 +++++++++++------------
smoketest/scripts/cli/test_service_ntp.py | 2 +-
3 files changed, 51 insertions(+), 51 deletions(-)
diff --git a/data/templates/chrony/chrony.conf.j2 b/data/templates/chrony/chrony.conf.j2
index 2838f55242..cc80e4d643 100644
--- a/data/templates/chrony/chrony.conf.j2
+++ b/data/templates/chrony/chrony.conf.j2
@@ -67,9 +67,9 @@ binddevice {{ interface }}
{% endif %}
{% endif %}
-{% if ptp.timestamp.interface is vyos_defined %}
+{% if timestamp.interface is vyos_defined %}
# Enable hardware timestamping on the specified interfaces
-{% for iface, iface_config in ptp.timestamp.interface.items() %}
+{% for iface, iface_config in timestamp.interface.items() %}
{% if iface == "all" %}
{% set iface = "*" %}
{% endif %}
diff --git a/interface-definitions/service_ntp.xml.in b/interface-definitions/service_ntp.xml.in
index 5dc0cd2951..c31b572bd9 100644
--- a/interface-definitions/service_ntp.xml.in
+++ b/interface-definitions/service_ntp.xml.in
@@ -13,72 +13,72 @@
#include
#include
#include
-
+
- Enable Precision Time Protocol (PTP) transport
+ Enable timestamping of packets in the NIC hardware
- #include
-
- 319
-
-
+
- Enable timestamping of packets in the NIC hardware
+ Interface to enable timestamping on
+
+
+ all
+
+
+ all
+ Select all interfaces
+
+
+ txt
+ Interface name
+
+
+ #include
+ all
+
-
+
- Interface to enable timestamping on
+ Selects which inbound packets are timestamped by the NIC
-
- all
+ all ntp ptp none
all
- Select all interfaces
+ All packets are timestamped
- txt
- Interface name
+ ntp
+ Only NTP packets are timestamped
+
+
+ ptp
+ Only PTP or NTP packets using the PTP transport are timestamped
+
+
+ none
+ No packet is timestamped
- #include
- all
+ (all|ntp|ptp|none)
-
-
-
- Selects which inbound packets are timestamped by the NIC
-
- all ntp ptp none
-
-
- all
- All packets are timestamped
-
-
- ntp
- Only NTP packets are timestamped
-
-
- ptp
- Only PTP or NTP packets using the PTP transport are timestamped
-
-
- none
- No packet is timestamped
-
-
- (all|ntp|ptp|none)
-
-
-
-
-
+
-
+
+
+
+
+
+ Enable Precision Time Protocol (PTP) transport
+
+
+ #include
+
+ 319
+
diff --git a/smoketest/scripts/cli/test_service_ntp.py b/smoketest/scripts/cli/test_service_ntp.py
index 07af4f5eba..469d44eaab 100755
--- a/smoketest/scripts/cli/test_service_ntp.py
+++ b/smoketest/scripts/cli/test_service_ntp.py
@@ -203,7 +203,7 @@ def test_offload_timestamp_default(self):
self.cli_set(base_path + ['server', server, 'ptp'])
self.cli_set(base_path + ['ptp', 'port', ptp_port])
- self.cli_set(base_path + ['ptp', 'timestamp', 'interface', 'all'])
+ self.cli_set(base_path + ['timestamp', 'interface', 'all'])
# commit changes
self.cli_commit()
From 51c6930e5e498dd2aef2fcba0287884b17683390 Mon Sep 17 00:00:00 2001
From: Nataliia Solomko
Date: Fri, 22 Nov 2024 15:20:13 +0200
Subject: [PATCH 04/18] op_mode: T6909: Move "show monitoring" and "show zebra"
to "show monitoring frr"
---
op-mode-definitions/show-monitoring.xml.in | 62 ++++++++++++++++++++--
op-mode-definitions/show-zebra.xml.in | 54 -------------------
2 files changed, 59 insertions(+), 57 deletions(-)
delete mode 100644 op-mode-definitions/show-zebra.xml.in
diff --git a/op-mode-definitions/show-monitoring.xml.in b/op-mode-definitions/show-monitoring.xml.in
index 2651b34387..9fd60e45ad 100644
--- a/op-mode-definitions/show-monitoring.xml.in
+++ b/op-mode-definitions/show-monitoring.xml.in
@@ -2,12 +2,68 @@
-
+
Show currently monitored services
- vtysh -c "show debugging"
-
+
+
+
+ Show currently monitored FRR services
+
+ vtysh -c "show debugging"
+
+
+
+ Show Zebra routing information
+
+ ${vyos_op_scripts_dir}/vtysh_wrapper.sh "show ${@:4}"
+
+
+
+ Client information
+
+
+
+
+ Brief summary
+
+ ${vyos_op_scripts_dir}/vtysh_wrapper.sh "show ${@:4}"
+
+
+
+
+
+ Zebra dataplane information
+
+ ${vyos_op_scripts_dir}/vtysh_wrapper.sh "show ${@:4}"
+
+
+
+ Zebra router information
+
+
+
+
+ Zebra routing table information
+
+
+
+
+ Summary information
+
+ ${vyos_op_scripts_dir}/vtysh_wrapper.sh "show ${@:4}"
+
+
+
+
+
+
+
+
+
+
+
diff --git a/op-mode-definitions/show-zebra.xml.in b/op-mode-definitions/show-zebra.xml.in
deleted file mode 100644
index 69991a1d57..0000000000
--- a/op-mode-definitions/show-zebra.xml.in
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
- Show Zebra routing information
-
- ${vyos_op_scripts_dir}/vtysh_wrapper.sh $@
-
-
-
- Client information
-
-
-
-
- Brief Summary
-
- ${vyos_op_scripts_dir}/vtysh_wrapper.sh $@
-
-
-
-
-
- Zebra dataplane information
-
- ${vyos_op_scripts_dir}/vtysh_wrapper.sh $@
-
-
-
- Zebra Router Information
-
-
-
-
- Table Information about this Zebra Router
-
-
-
-
- Summary Information
-
- ${vyos_op_scripts_dir}/vtysh_wrapper.sh $@
-
-
-
-
-
-
-
-
-
-
From 8fd29dfdcbe0f8ba7f7fb9915e96ffd704695a74 Mon Sep 17 00:00:00 2001
From: Nataliia Solomko
Date: Wed, 27 Nov 2024 13:02:35 +0200
Subject: [PATCH 05/18] op_mode: T6770: Fix op command "show bridge vni"
---
op-mode-definitions/show-bridge.xml.in | 2 +-
src/op_mode/bridge.py | 47 ++++++++++++++++++--------
2 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/op-mode-definitions/show-bridge.xml.in b/op-mode-definitions/show-bridge.xml.in
index 5d8cc38475..1212ab1f93 100644
--- a/op-mode-definitions/show-bridge.xml.in
+++ b/op-mode-definitions/show-bridge.xml.in
@@ -66,7 +66,7 @@
Display bridge interface nexthop-group
- ${vyos_op_scripts_dir}/bridge.py show_detail --nexthop_group --interface=$3
+ ${vyos_op_scripts_dir}/bridge.py show_detail --nexthop-group --interface=$3
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py
index e80b1c21d6..c4293a77c3 100755
--- a/src/op_mode/bridge.py
+++ b/src/op_mode/bridge.py
@@ -23,10 +23,11 @@
from vyos.utils.process import cmd
from vyos.utils.process import rc_cmd
-from vyos.utils.process import call
+from vyos.utils.process import call
import vyos.opmode
+
def _get_json_data():
"""
Get bridge data format JSON
@@ -43,7 +44,7 @@ def _get_raw_data_summary():
return data_dict
-def _get_raw_data_vlan(tunnel:bool=False):
+def _get_raw_data_vlan(tunnel: bool = False):
"""
:returns dict
"""
@@ -54,14 +55,18 @@ def _get_raw_data_vlan(tunnel:bool=False):
data_dict = json.loads(json_data)
return data_dict
+
def _get_raw_data_vni() -> dict:
"""
:returns dict
"""
- json_data = cmd(f'bridge --json vni show')
+ code, json_data = rc_cmd(f'bridge --json vni show')
+ if code != 0:
+ raise vyos.opmode.UnconfiguredObject('VNI is not configured')
data_dict = json.loads(json_data)
return data_dict
+
def _get_raw_data_fdb(bridge):
"""Get MAC-address for the bridge brX
:returns list
@@ -70,7 +75,9 @@ def _get_raw_data_fdb(bridge):
# From iproute2 fdb.c, fdb_show() will only exit(-1) in case of
# non-existent bridge device; raise error.
if code == 255:
- raise vyos.opmode.UnconfiguredObject(f"bridge {bridge} does not exist in the system")
+ raise vyos.opmode.UnconfiguredObject(
+ f'bridge {bridge} does not exist in the system'
+ )
data_dict = json.loads(json_data)
return data_dict
@@ -116,8 +123,8 @@ def _get_formatted_output_summary(data):
flags = ','.join(option.get('flags')).lower()
prio = option.get('priority')
member_entries.append([interface, state, mtu, flags, prio])
- member_headers = ["Member", "State", "MTU", "Flags", "Prio"]
- output_members = tabulate(member_entries, member_headers, numalign="left")
+ member_headers = ['Member', 'State', 'MTU', 'Flags', 'Prio']
+ output_members = tabulate(member_entries, member_headers, numalign='left')
output_bridge = f"""Bridge interface {bridge}:
{output_members}
@@ -138,13 +145,14 @@ def _get_formatted_output_vlan(data):
vlan_end = vlan_entry.get('vlanEnd')
vlan = f'{vlan}-{vlan_end}'
flags_raw = vlan_entry.get('flags')
- flags = ', '.join(flags_raw if isinstance(flags_raw,list) else "").lower()
+ flags = ', '.join(flags_raw if isinstance(flags_raw, list) else '').lower()
data_entries.append([interface, vlan, flags])
- headers = ["Interface", "VLAN", "Flags"]
+ headers = ['Interface', 'VLAN', 'Flags']
output = tabulate(data_entries, headers)
return output
+
def _get_formatted_output_vlan_tunnel(data):
data_entries = []
for entry in data:
@@ -166,10 +174,11 @@ def _get_formatted_output_vlan_tunnel(data):
# 200 200
data_entries.append(['', vlan, vni])
- headers = ["Interface", "VLAN", "VNI"]
+ headers = ['Interface', 'VLAN', 'VNI']
output = tabulate(data_entries, headers)
return output
+
def _get_formatted_output_vni(data):
data_entries = []
for entry in data:
@@ -182,10 +191,11 @@ def _get_formatted_output_vni(data):
vlan = f'{vlan}-{vlan_end}'
data_entries.append([interface, vlan])
- headers = ["Interface", "VNI"]
+ headers = ['Interface', 'VNI']
output = tabulate(data_entries, headers)
return output
+
def _get_formatted_output_fdb(data):
data_entries = []
for entry in data:
@@ -195,8 +205,8 @@ def _get_formatted_output_fdb(data):
flags = ','.join(entry['flags'])
data_entries.append([interface, mac, state, flags])
- headers = ["Interface", "Mac address", "State", "Flags"]
- output = tabulate(data_entries, headers, numalign="left")
+ headers = ['Interface', 'Mac address', 'State', 'Flags']
+ output = tabulate(data_entries, headers, numalign='left')
return output
@@ -209,28 +219,33 @@ def _get_formatted_output_mdb(data):
state = mdb_entry.get('state')
flags = ','.join(mdb_entry.get('flags'))
data_entries.append([interface, group, state, flags])
- headers = ["Interface", "Group", "State", "Flags"]
+ headers = ['Interface', 'Group', 'State', 'Flags']
output = tabulate(data_entries, headers)
return output
+
def _get_bridge_detail(iface):
"""Get interface detail statistics"""
return call(f'vtysh -c "show interface {iface}"')
+
def _get_bridge_detail_nexthop_group(iface):
"""Get interface detail nexthop_group statistics"""
return call(f'vtysh -c "show interface {iface} nexthop-group"')
+
def _get_bridge_detail_nexthop_group_raw(iface):
out = cmd(f'vtysh -c "show interface {iface} nexthop-group"')
return out
+
def _get_bridge_detail_raw(iface):
"""Get interface detail json statistics"""
- data = cmd(f'vtysh -c "show interface {iface} json"')
+ data = cmd(f'vtysh -c "show interface {iface} json"')
data_dict = json.loads(data)
return data_dict
+
def show(raw: bool):
bridge_data = _get_raw_data_summary()
if raw:
@@ -249,6 +264,7 @@ def show_vlan(raw: bool, tunnel: typing.Optional[bool]):
else:
return _get_formatted_output_vlan(bridge_vlan)
+
def show_vni(raw: bool):
bridge_vni = _get_raw_data_vni()
if raw:
@@ -256,6 +272,7 @@ def show_vni(raw: bool):
else:
return _get_formatted_output_vni(bridge_vni)
+
def show_fdb(raw: bool, interface: str):
fdb_data = _get_raw_data_fdb(interface)
if raw:
@@ -271,6 +288,7 @@ def show_mdb(raw: bool, interface: str):
else:
return _get_formatted_output_mdb(mdb_data)
+
def show_detail(raw: bool, nexthop_group: typing.Optional[bool], interface: str):
if raw:
if nexthop_group:
@@ -283,6 +301,7 @@ def show_detail(raw: bool, nexthop_group: typing.Optional[bool], interface: str)
else:
return _get_bridge_detail(interface)
+
if __name__ == '__main__':
try:
res = vyos.opmode.run(sys.modules[__name__])
From 37859ee69da3e78a85d741de5c20edf227c548bb Mon Sep 17 00:00:00 2001
From: Viacheslav Hletenko
Date: Thu, 28 Nov 2024 13:44:46 +0200
Subject: [PATCH 06/18] T6906: IPoE-server add start-session option (#4206)
Add the abbility to start IPoE session by unclassified-packet.
It allows the cases when subscriber configures the address manually
(static) and accel-ppp can start session on any packet.
By default start session on DHCPv4 Discover packet.
set service ipoe-server interface eth1 start-session unclassified-packet
---
data/templates/accel-ppp/ipoe.config.j2 | 4 +++-
.../service_ipoe-server.xml.in | 24 +++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/data/templates/accel-ppp/ipoe.config.j2 b/data/templates/accel-ppp/ipoe.config.j2
index a10dcf2c16..34dfa529a2 100644
--- a/data/templates/accel-ppp/ipoe.config.j2
+++ b/data/templates/accel-ppp/ipoe.config.j2
@@ -59,7 +59,9 @@ lua-file={{ lua_file }}
{% set relay = ',' ~ 'relay=' ~ iface_config.external_dhcp.dhcp_relay if iface_config.external_dhcp.dhcp_relay is vyos_defined else '' %}
{% set giaddr = ',' ~ 'giaddr=' ~ iface_config.external_dhcp.giaddr if iface_config.external_dhcp.giaddr is vyos_defined else '' %}
{% set username = ',' ~ 'username=lua:' ~ iface_config.lua_username if iface_config.lua_username is vyos_defined else '' %}
-{{ tmp }},{{ shared }}mode={{ iface_config.mode | upper }},ifcfg=1,{{ range }}start=dhcpv4,ipv6=1{{ relay }}{{ giaddr }}{{ username }}
+{% set start_map = {'dhcp': 'dhcpv4', 'unclassified-packet': 'up', 'auto': 'auto'} %}
+{% set start = start_map[iface_config.start_session] %}
+{{ tmp }},{{ shared }}mode={{ iface_config.mode | upper }},ifcfg=1,{{ range }}start={{ start }},ipv6=1{{ relay }}{{ giaddr }}{{ username }}
{% if iface_config.vlan_mon is vyos_defined %}
vlan-mon={{ iface }},{{ iface_config.vlan | join(',') }}
{% endif %}
diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in
index 27a654f926..39cfb78893 100644
--- a/interface-definitions/service_ipoe-server.xml.in
+++ b/interface-definitions/service_ipoe-server.xml.in
@@ -131,6 +131,30 @@
shared
+
+
+ Start session options
+
+ auto dhcp unclassified-packet
+
+
+ auto
+ Start session with username as the interface name
+
+
+ dhcp
+ Start session on DHCPv4 Discover
+
+
+ unclassified-packet
+ Start session on unclassified-packet
+
+
+ (auto|dhcp|unclassified-packet)
+
+
+ dhcp
+
Client address pool
From 56fb46f392187434a7ccf7504d2e1d1bf46c8377 Mon Sep 17 00:00:00 2001
From: "Nataliia S." <81954790+natali-rs1985@users.noreply.github.com>
Date: Thu, 28 Nov 2024 19:43:26 +0200
Subject: [PATCH 07/18] multicast: T6920: static multicast routing throws
TypeError (#4210)
---
src/conf_mode/protocols_static_multicast.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index d323ceb4f9..c8894fd417 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -86,10 +86,10 @@ def verify(mroute):
if mroute is None:
return None
- for route in mroute['mroute']:
- route = route.split('/')
+ for mcast_route in mroute['mroute']:
+ route = mcast_route.split('/')
if IPv4Address(route[0]) < IPv4Address('224.0.0.0'):
- raise ConfigError(route + " not a multicast network")
+ raise ConfigError(f'{mcast_route} not a multicast network')
def generate(mroute):
From 24b1d246373a0def45a6e6ba1b0ecabe19fe1d58 Mon Sep 17 00:00:00 2001
From: Christian Breunig
Date: Sun, 1 Dec 2024 12:44:10 +0100
Subject: [PATCH 08/18] sudo: T6926: remove spam messages to syslog
Right now every command that's executed via op-mode/conf-mode is logged with a
session entry/exit and command execution into syslog.
sudo[1082396]: vyos : TTY=pts/1 ; PWD=/home/vyos ; USER=root ; COMMAND=/usr/bin/mv /tmp/config.boot.1082388 /opt/vyatta/etc/config/archive/config.boot
sudo[1082396]: pam_unix(sudo:session): session opened for user root(uid=0) by vyos(uid=1002)
sudo[1082396]: pam_unix(sudo:session): session closed for user root
sudo[1082399]: vyos : TTY=pts/1 ; PWD=/home/vyos ; USER=root ; COMMAND=/usr/sbin/logrotate -f -s /opt/vyatta/etc/config/archive/lr.state /opt/vyatta/etc/config/archive/lr.conf
sudo[1082399]: pam_unix(sudo:session): session opened for user root(uid=0) by vyos(uid=1002)
sudo[1082399]: pam_unix(sudo:session): session closed for user root
This heavily bloats remote logging services - remove the log entries
---
src/etc/sudoers.d/vyos | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/etc/sudoers.d/vyos b/src/etc/sudoers.d/vyos
index 67d7babc44..198b9b9aab 100644
--- a/src/etc/sudoers.d/vyos
+++ b/src/etc/sudoers.d/vyos
@@ -1,7 +1,8 @@
#
# VyOS modifications to sudo configuration
#
-Defaults syslog_goodpri=info
+Defaults !syslog
+Defaults !pam_session
Defaults env_keep+=VYATTA_*
#
From 29cc3d790fa690356016a7df21ec75b12b84cb3c Mon Sep 17 00:00:00 2001
From: John Estabrook
Date: Mon, 2 Dec 2024 03:04:40 -0600
Subject: [PATCH 09/18] config-mgmt: T6925: return from verify function on
config object None (#4213)
---
src/conf_mode/system_config-management.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/conf_mode/system_config-management.py b/src/conf_mode/system_config-management.py
index 8de4e53429..a3ce665120 100755
--- a/src/conf_mode/system_config-management.py
+++ b/src/conf_mode/system_config-management.py
@@ -39,6 +39,9 @@ def get_config(config=None):
def verify(mgmt):
+ if mgmt is None:
+ return
+
d = mgmt.config_dict
confirm = d.get('commit_confirm', {})
if confirm.get('action', '') == 'reload' and 'commit_revisions' not in d:
From b4c276fcb8536cf53f414343694f202c75b6eae4 Mon Sep 17 00:00:00 2001
From: Viacheslav Hletenko
Date: Mon, 2 Dec 2024 15:32:56 +0000
Subject: [PATCH 10/18] T6917: fix RPS ethernet settings for CPUs with more
than 32 cores
The maximun value theat could be written for the 'rpc_cpu'
is 4294967295 or 0xffffffff in the chunk splitted by commas
---
python/vyos/ifconfig/ethernet.py | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 61da7b74b9..50dd0f3961 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -310,13 +310,15 @@ def set_rps(self, state):
rps_cpus = 0
queues = len(glob(f'/sys/class/net/{self.ifname}/queues/rx-*'))
if state:
+ cpu_count = os.cpu_count()
+
# Enable RPS on all available CPUs except CPU0 which we will not
# utilize so the system has one spare core when it's under high
# preasure to server other means. Linux sysfs excepts a bitmask
# representation of the CPUs which should participate on RPS, we
# can enable more CPUs that are physically present on the system,
# Linux will clip that internally!
- rps_cpus = (1 << os.cpu_count()) -1
+ rps_cpus = (1 << cpu_count) - 1
# XXX: we should probably reserve one core when the system is under
# high preasure so we can still have a core left for housekeeping.
@@ -324,8 +326,19 @@ def set_rps(self, state):
# receive packet steering.
rps_cpus &= ~1
- for i in range(0, queues):
- self._write_sysfs(f'/sys/class/net/{self.ifname}/queues/rx-{i}/rps_cpus', f'{rps_cpus:x}')
+ # Convert the bitmask to hexadecimal chunks of 32 bits
+ # Split the bitmask into chunks of up to 32 bits each
+ hex_chunks = []
+ for i in range(0, cpu_count, 32):
+ # Extract the next 32-bit chunk
+ chunk = (rps_cpus >> i) & 0xFFFFFFFF
+ hex_chunks.append(f"{chunk:08x}")
+
+ # Join the chunks with commas
+ rps_cpus = ",".join(hex_chunks)
+
+ for i in range(queues):
+ self._write_sysfs(f'/sys/class/net/{self.ifname}/queues/rx-{i}/rps_cpus', rps_cpus)
# send bitmask representation as hex string without leading '0x'
return True
From 01eb2accf8fbfc4848ed3306ec8a37bba2bed39e Mon Sep 17 00:00:00 2001
From: Viacheslav Hletenko
Date: Wed, 4 Dec 2024 10:35:56 +0000
Subject: [PATCH 11/18] T6923: Add debian-security-mirror for
package-smoketests
---
.github/workflows/package-smoketest.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/package-smoketest.yml b/.github/workflows/package-smoketest.yml
index 91c968c822..d352bd3cb2 100644
--- a/.github/workflows/package-smoketest.yml
+++ b/.github/workflows/package-smoketest.yml
@@ -17,6 +17,7 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed for PR comments
BUILD_BY: autobuild@vyos.net
DEBIAN_MIRROR: http://deb.debian.org/debian/
+ DEBIAN_SECURITY_MIRROR: http://deb.debian.org/debian-security
VYOS_MIRROR: https://packages.vyos.net/repositories/current/
jobs:
@@ -56,6 +57,7 @@ jobs:
--build-type release \
--custom-package vyos-1x-smoketest \
--debian-mirror $DEBIAN_MIRROR \
+ --debian-security-mirror $DEBIAN_SECURITY_MIRROR \
--version ${{ steps.version.outputs.build_version }} \
--vyos-mirror $VYOS_MIRROR \
generic
From 62edabd26292181f2ea09759681387a34cf3ad95 Mon Sep 17 00:00:00 2001
From: John Estabrook
Date: Thu, 5 Dec 2024 15:31:39 -0600
Subject: [PATCH 12/18] vyconf: T6718: add keyword default for change in
libvyosconfig binding
Adjust signature of reference_tree_to_json for change in the ctypes
binding.
---
python/vyos/configtree.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index 3e02fbba61..fb79e84598 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -469,15 +469,15 @@ def mask_inclusive(left, right, libpath=LIBPATH):
return tree
-def reference_tree_to_json(from_dir, to_file, libpath=LIBPATH):
+def reference_tree_to_json(from_dir, to_file, internal_cache="", libpath=LIBPATH):
try:
__lib = cdll.LoadLibrary(libpath)
__reference_tree_to_json = __lib.reference_tree_to_json
- __reference_tree_to_json.argtypes = [c_char_p, c_char_p]
+ __reference_tree_to_json.argtypes = [c_char_p, c_char_p, c_char_p]
__get_error = __lib.get_error
__get_error.argtypes = []
__get_error.restype = c_char_p
- res = __reference_tree_to_json(from_dir.encode(), to_file.encode())
+ res = __reference_tree_to_json(internal_cache.encode(), from_dir.encode(), to_file.encode())
except Exception as e:
raise ConfigTreeError(e)
if res == 1:
From 6733ebcf129193a373eca870ebe5f2d6d65b9476 Mon Sep 17 00:00:00 2001
From: Vijayakumar A <36878324+kumvijaya@users.noreply.github.com>
Date: Sun, 8 Dec 2024 14:04:39 +0530
Subject: [PATCH 13/18] T6940: updated codeowners with user list to support
sync (#4228)
* T6940: updated codeowners with user list to support sync
* T6940: updated codeowners with user list to support sync
---------
Co-authored-by: kumvijaya
---
CODEOWNERS | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/CODEOWNERS b/CODEOWNERS
index 1913942985..4891a03252 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1 +1,2 @@
-* @vyos/reviewers
\ No newline at end of file
+# Users from reviewers github team
+* @dmbaturin @sarthurdev @jestabro @sever-sever @c-po @fett0 @nicolas-fort @zdc
From f9ddf3f68f42080efc471e934d6bdaa1fec17459 Mon Sep 17 00:00:00 2001
From: Nicolas Vollmar
Date: Sun, 1 Dec 2024 16:25:05 +0100
Subject: [PATCH 14/18] T6927: adds option to set container name server
---
interface-definitions/container.xml.in | 1 +
smoketest/scripts/cli/test_container.py | 12 ++++++++++++
src/conf_mode/container.py | 7 ++++++-
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in
index bd2ff820da..ad18156047 100644
--- a/interface-definitions/container.xml.in
+++ b/interface-definitions/container.xml.in
@@ -275,6 +275,7 @@
64
+ #include
Attach user defined network to container
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py
index 0541384da9..db67add318 100755
--- a/smoketest/scripts/cli/test_container.py
+++ b/smoketest/scripts/cli/test_container.py
@@ -96,6 +96,18 @@ def test_basic(self):
tmp = cmd(f'sudo podman exec -it {cont_name} sysctl kernel.msgmax')
self.assertEqual(tmp, 'kernel.msgmax = 4096')
+ def test_name_server(self):
+ cont_name = 'dns-test'
+ name_server = '192.168.0.1'
+ self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])
+ self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
+ self.cli_set(base_path + ['name', cont_name, 'name-server', name_server])
+
+ self.cli_commit()
+
+ n = cmd_to_json(f'sudo podman inspect {cont_name}')
+ self.assertEqual(n['HostConfig']['Dns'][0], name_server)
+
def test_cpu_limit(self):
cont_name = 'c2'
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index a7dc33d9d4..4d39620296 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -363,9 +363,14 @@ def generate_run_arguments(name, container_config):
if 'allow_host_pid' in container_config:
host_pid = '--pid host'
+ name_server = ''
+ if 'name_server' in container_config:
+ for ns in container_config['name_server']:
+ name_server += f'--dns {ns}'
+
container_base_cmd = f'--detach --interactive --tty --replace {capabilities} --cpus {cpu_quota} {sysctl_opt} ' \
f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \
- f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid} {host_pid}'
+ f'--name {name} {hostname} {device} {port} {name_server} {volume} {env_opt} {label} {uid} {host_pid}'
entrypoint = ''
if 'entrypoint' in container_config:
From 1db8a48a8b9d1b7b125d9ca29cc4c48534640375 Mon Sep 17 00:00:00 2001
From: Nicolas Vollmar
Date: Mon, 9 Dec 2024 07:18:05 +0100
Subject: [PATCH 15/18] T6927: adds option to set container name server -add
container check
---
smoketest/scripts/cli/test_container.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py
index db67add318..5d574ab7d9 100755
--- a/smoketest/scripts/cli/test_container.py
+++ b/smoketest/scripts/cli/test_container.py
@@ -108,6 +108,9 @@ def test_name_server(self):
n = cmd_to_json(f'sudo podman inspect {cont_name}')
self.assertEqual(n['HostConfig']['Dns'][0], name_server)
+ tmp = cmd(f'sudo podman exec -it {cont_name} cat /etc/resolv.conf')
+ self.assertIn(name_server, tmp)
+
def test_cpu_limit(self):
cont_name = 'c2'
From 609069f4005aa05b29c1ea07a3be9bc81752b277 Mon Sep 17 00:00:00 2001
From: Nataliia Solomko
Date: Tue, 10 Dec 2024 15:18:56 +0200
Subject: [PATCH 16/18] pki: T6368: Add ability for acme to listen on IPv6
addresses
---
interface-definitions/pki.xml.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/interface-definitions/pki.xml.in b/interface-definitions/pki.xml.in
index c69886a4b5..5c0b735ef6 100644
--- a/interface-definitions/pki.xml.in
+++ b/interface-definitions/pki.xml.in
@@ -80,7 +80,7 @@
- #include
+ #include
Size of the RSA key
From 2de9fc6c1c0ee4fb814bb48cfe8b260453f80436 Mon Sep 17 00:00:00 2001
From: Nicolas Vollmar
Date: Tue, 10 Dec 2024 06:13:32 +0100
Subject: [PATCH 17/18] T6927: add name server validation
---
smoketest/scripts/cli/test_container.py | 12 +++++++++++-
src/conf_mode/container.py | 3 +++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py
index 5d574ab7d9..51559a7c67 100755
--- a/smoketest/scripts/cli/test_container.py
+++ b/smoketest/scripts/cli/test_container.py
@@ -98,11 +98,21 @@ def test_basic(self):
def test_name_server(self):
cont_name = 'dns-test'
+ net_name = 'net-test'
name_server = '192.168.0.1'
- self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])
+ prefix = '192.0.2.0/24'
+
+ self.cli_set(base_path + ['network', net_name, 'prefix', prefix])
+
self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
self.cli_set(base_path + ['name', cont_name, 'name-server', name_server])
+ self.cli_set(base_path + ['name', cont_name, 'network', net_name, 'address', str(ip_interface(prefix).ip + 2)])
+ # verify() - name server has no effect when container network has dns enabled
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(base_path + ['network', net_name, 'no-name-server'])
self.cli_commit()
n = cmd_to_json(f'sudo podman inspect {cont_name}')
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index 4d39620296..594de3eb0b 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -148,6 +148,9 @@ def verify(container):
if network_name not in container.get('network', {}):
raise ConfigError(f'Container network "{network_name}" does not exist!')
+ if 'name_server' in container_config and 'no_name_server' not in container['network'][network_name]:
+ raise ConfigError(f'Setting name server has no effect when attached container network has DNS enabled!')
+
if 'address' in container_config['network'][network_name]:
cnt_ipv4 = 0
cnt_ipv6 = 0
From 678c6cd00412cad5d788da210c6dfeae6e77907c Mon Sep 17 00:00:00 2001
From: Roman Khramshin
Date: Fri, 13 Dec 2024 03:14:17 +0800
Subject: [PATCH 18/18] T6863: Fix default distance for PPPoE (#4229)
set `default-route-distance` to 1
---
.../include/interface/default-route-distance.xml.i | 2 +-
interface-definitions/interfaces_pppoe.xml.in | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/interface-definitions/include/interface/default-route-distance.xml.i b/interface-definitions/include/interface/default-route-distance.xml.i
index 6eda52c919..7a226a538b 100644
--- a/interface-definitions/include/interface/default-route-distance.xml.i
+++ b/interface-definitions/include/interface/default-route-distance.xml.i
@@ -4,7 +4,7 @@
Distance for installed default route
u32:1-255
- Distance for the default route from DHCP server
+ Distance for the default route received from the server
diff --git a/interface-definitions/interfaces_pppoe.xml.in b/interface-definitions/interfaces_pppoe.xml.in
index 56660bc154..f24bc41d8c 100644
--- a/interface-definitions/interfaces_pppoe.xml.in
+++ b/interface-definitions/interfaces_pppoe.xml.in
@@ -21,6 +21,9 @@
#include
#include
#include
+
+ 1
+
#include
#include
#include