summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/check-open-prs-conflict.yml17
-rw-r--r--.github/workflows/cla-check.yml19
-rw-r--r--.github/workflows/cleanup-mirror-pr-branch.yml16
-rw-r--r--.github/workflows/darker-ruff-lint.yml (renamed from .github/workflows/lint-with-ruff.yml)6
-rw-r--r--.github/workflows/mirror-pr-and-sync.yml21
-rw-r--r--.github/workflows/package-smoketest.yml2
-rw-r--r--.github/workflows/pr-mirror-repo-sync.yml28
-rw-r--r--.github/workflows/trigger-pr-mirror-repo-sync.yml13
-rw-r--r--.gitignore3
-rw-r--r--Makefile13
-rw-r--r--data/config-mode-dependencies/vyos-1x.json4
-rw-r--r--data/config.boot.default3
-rw-r--r--data/templates/aws/override_aws_gwlbtun.conf.j24
-rw-r--r--data/templates/conntrack/sysctl.conf.j23
-rw-r--r--data/templates/conntrack/vyos_nf_conntrack.conf.j22
-rw-r--r--data/templates/container/containers.conf.j24
-rw-r--r--data/templates/dhcp-client/ipv6.override.conf.j23
-rw-r--r--data/templates/dhcp-server/kea-ctrl-agent.conf.j214
-rw-r--r--data/templates/dhcp-server/kea-dhcp-ddns.conf.j230
-rw-r--r--data/templates/dhcp-server/kea-dhcp4.conf.j237
-rw-r--r--data/templates/firewall/nftables-defines.j211
-rw-r--r--data/templates/firewall/nftables-geoip-update.j233
-rw-r--r--data/templates/firewall/nftables-policy.j217
-rw-r--r--data/templates/firewall/nftables-zone.j236
-rwxr-xr-xdata/templates/firewall/nftables.j246
-rw-r--r--data/templates/frr/bgpd.frr.j25
-rw-r--r--data/templates/frr/daemons.frr.tmpl1
-rw-r--r--data/templates/frr/ospfd.frr.j22
-rw-r--r--data/templates/frr/rpki.frr.j228
-rw-r--r--data/templates/frr/zebra.route-map.frr.j26
-rw-r--r--data/templates/https/nginx.default.j22
-rw-r--r--data/templates/ids/fastnetmon.j2121
-rw-r--r--data/templates/ids/fastnetmon_excluded_networks_list.j25
-rw-r--r--data/templates/ids/fastnetmon_networks_list.j25
-rw-r--r--data/templates/ipsec/swanctl/peer.j215
-rw-r--r--data/templates/load-balancing/haproxy.cfg.j224
-rw-r--r--data/templates/load-balancing/nftables-wlb.j22
-rw-r--r--data/templates/login/authorized_keys.j21
-rw-r--r--data/templates/login/authorized_principals.j24
-rw-r--r--data/templates/prometheus/node_exporter.service.j211
-rw-r--r--data/templates/router-advert/radvd.conf.j215
-rw-r--r--data/templates/ssh/sshd_config.j216
-rw-r--r--debian/control7
-rw-r--r--debian/copyright6
-rw-r--r--debian/vyos-1x.install1
-rw-r--r--debian/vyos-1x.links3
-rw-r--r--debian/vyos-1x.postinst6
-rw-r--r--interface-definitions/container.xml.in30
-rw-r--r--interface-definitions/include/accel-ppp/radius-additions.xml.i11
-rw-r--r--interface-definitions/include/accel-ppp/thread-count.xml.i27
-rw-r--r--interface-definitions/include/bgp/protocol-common-config.xml.i6
-rw-r--r--interface-definitions/include/dhcp/ddns-dns-server.xml.i19
-rw-r--r--interface-definitions/include/dhcp/ddns-settings.xml.i172
-rw-r--r--interface-definitions/include/dhcp/ping-check.xml.i8
-rw-r--r--interface-definitions/include/firewall/common-rule-ipv6.xml.i4
-rw-r--r--interface-definitions/include/firewall/geoip.xml.i2
-rw-r--r--interface-definitions/include/firewall/global-options.xml.i57
-rw-r--r--interface-definitions/include/haproxy/logging.xml.i132
-rw-r--r--interface-definitions/include/haproxy/rule-backend.xml.i8
-rw-r--r--interface-definitions/include/haproxy/rule-frontend.xml.i14
-rw-r--r--interface-definitions/include/interface/ipv6-address-interface-identifier.xml.i15
-rw-r--r--interface-definitions/include/interface/ipv6-address.xml.i12
-rw-r--r--interface-definitions/include/interface/ipv6-options-with-nd.xml.i9
-rw-r--r--interface-definitions/include/interface/ipv6-options.xml.i11
-rw-r--r--interface-definitions/include/interface/vif-s.xml.i2
-rw-r--r--interface-definitions/include/interface/vif.xml.i1
-rw-r--r--interface-definitions/include/rpki/protocol-common-config.xml.i87
-rw-r--r--interface-definitions/include/version/conntrack-version.xml.i2
-rw-r--r--interface-definitions/include/version/container-version.xml.i2
-rw-r--r--interface-definitions/include/version/firewall-version.xml.i2
-rw-r--r--interface-definitions/include/version/ids-version.xml.i2
-rw-r--r--interface-definitions/include/version/reverseproxy-version.xml.i2
-rw-r--r--interface-definitions/interfaces_bonding.xml.in3
-rw-r--r--interface-definitions/interfaces_bridge.xml.in13
-rw-r--r--interface-definitions/interfaces_ethernet.xml.in1
-rw-r--r--interface-definitions/interfaces_geneve.xml.in1
-rw-r--r--interface-definitions/interfaces_l2tpv3.xml.in1
-rw-r--r--interface-definitions/interfaces_macsec.xml.in1
-rw-r--r--interface-definitions/interfaces_openvpn.xml.in1
-rw-r--r--interface-definitions/interfaces_pppoe.xml.in1
-rw-r--r--interface-definitions/interfaces_pseudo-ethernet.xml.in1
-rw-r--r--interface-definitions/interfaces_vxlan.xml.in1
-rw-r--r--interface-definitions/interfaces_wireless.xml.in1
-rw-r--r--interface-definitions/interfaces_wwan.xml.in1
-rw-r--r--interface-definitions/load-balancing_haproxy.xml.in6
-rw-r--r--interface-definitions/load-balancing_wan.xml.in2
-rw-r--r--interface-definitions/nat66.xml.in1
-rw-r--r--interface-definitions/policy.xml.in2
-rw-r--r--interface-definitions/policy_route.xml.in4
-rw-r--r--interface-definitions/protocols_rpki.xml.in86
-rw-r--r--interface-definitions/qos.xml.in19
-rw-r--r--interface-definitions/service_dhcp-server.xml.in123
-rw-r--r--interface-definitions/service_ids_ddos-protection.xml.in167
-rw-r--r--interface-definitions/service_ipoe-server.xml.in1
-rw-r--r--interface-definitions/service_pppoe-server.xml.in1
-rw-r--r--interface-definitions/service_router-advert.xml.in13
-rw-r--r--interface-definitions/service_snmp.xml.in2
-rw-r--r--interface-definitions/service_ssh.xml.in16
-rw-r--r--interface-definitions/system_conntrack.xml.in6
-rw-r--r--interface-definitions/system_ip.xml.in16
-rw-r--r--interface-definitions/system_login.xml.in9
-rw-r--r--interface-definitions/system_option.xml.in165
-rw-r--r--interface-definitions/vpn_ipsec.xml.in57
-rw-r--r--interface-definitions/vpn_l2tp.xml.in1
-rw-r--r--interface-definitions/vpn_pptp.xml.in1
-rw-r--r--interface-definitions/vpn_sstp.xml.in1
-rw-r--r--interface-definitions/vrf.xml.in9
m---------libvyosconfig0
-rw-r--r--op-mode-definitions/clear-interfaces.xml.in842
-rw-r--r--op-mode-definitions/clear-ip.xml.in14
-rw-r--r--op-mode-definitions/clear-ipv6.xml.in14
-rw-r--r--op-mode-definitions/clear-log.xml.in2
-rw-r--r--op-mode-definitions/connect.xml.in2
-rw-r--r--op-mode-definitions/conntrack-sync.xml.in22
-rw-r--r--op-mode-definitions/container.xml.in33
-rw-r--r--op-mode-definitions/crypt.xml.in6
-rw-r--r--op-mode-definitions/date.xml.in2
-rw-r--r--op-mode-definitions/dhcp.xml.in18
-rw-r--r--op-mode-definitions/disconnect.xml.in2
-rw-r--r--op-mode-definitions/disks.xml.in4
-rw-r--r--op-mode-definitions/dns-dynamic.xml.in8
-rw-r--r--op-mode-definitions/dns-forwarding.xml.in8
-rw-r--r--op-mode-definitions/execute-port-scan.xml.in4
-rw-r--r--op-mode-definitions/execute-shell.xml.in4
-rw-r--r--op-mode-definitions/file.xml.in10
-rwxr-xr-xop-mode-definitions/firewall.xml.in193
-rw-r--r--op-mode-definitions/flow-accounting-op.xml.in2
-rw-r--r--op-mode-definitions/force-arp.xml.in10
-rw-r--r--op-mode-definitions/force-root-partition-auto-resize.xml.in2
-rw-r--r--op-mode-definitions/generate-ipsec-debug-archive.xml.in2
-rw-r--r--op-mode-definitions/generate-ipsec-profile.xml.in10
-rw-r--r--op-mode-definitions/generate-openconnect-user-key.xml.in10
-rw-r--r--op-mode-definitions/generate-openvpn-config-client.xml.in4
-rw-r--r--op-mode-definitions/generate-ssh-server-key.xml.in2
-rw-r--r--op-mode-definitions/generate-system-login-user.xml.in14
-rw-r--r--op-mode-definitions/generate-wireguard.xml.in6
-rw-r--r--op-mode-definitions/generate_tech-support_archive.xml.in23
-rw-r--r--op-mode-definitions/geoip.xml.in2
-rw-r--r--op-mode-definitions/igmp-proxy.xml.in2
-rw-r--r--op-mode-definitions/include/bgp/advertised-routes.xml.i12
-rw-r--r--op-mode-definitions/include/bgp/afi-common.xml.i24
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i99
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i24
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i4
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn.xml.i24
-rw-r--r--op-mode-definitions/include/bgp/dampened-routes.xml.i8
-rw-r--r--op-mode-definitions/include/bgp/filtered-routes.xml.i8
-rw-r--r--op-mode-definitions/include/bgp/flap-statistics.xml.i8
-rw-r--r--op-mode-definitions/include/bgp/next-hop.xml.i24
-rw-r--r--op-mode-definitions/include/bgp/prefix-counts.xml.i8
-rw-r--r--op-mode-definitions/include/bgp/received-routes.xml.i12
-rw-r--r--op-mode-definitions/include/bgp/received.xml.i16
-rw-r--r--op-mode-definitions/include/bgp/routes.xml.i8
-rw-r--r--op-mode-definitions/include/bgp/show-bgp-common.xml.i97
-rw-r--r--op-mode-definitions/include/bgp/show-ip-bgp-common.xml.i66
-rw-r--r--op-mode-definitions/include/isis-common.xml.i54
-rw-r--r--op-mode-definitions/include/ospf/common.xml.i538
-rw-r--r--op-mode-definitions/include/ospfv3/border-routers.xml.i18
-rw-r--r--op-mode-definitions/include/ospfv3/database.xml.i54
-rw-r--r--op-mode-definitions/include/ospfv3/interface.xml.i90
-rw-r--r--op-mode-definitions/include/ospfv3/linkstate-id-node-tag.xml.i4
-rw-r--r--op-mode-definitions/include/ospfv3/linkstate.xml.i4
-rw-r--r--op-mode-definitions/include/ospfv3/route.xml.i52
-rw-r--r--op-mode-definitions/include/rpki/vrf.xml.i11
-rw-r--r--op-mode-definitions/include/show-route-table.xml.i7
-rw-r--r--op-mode-definitions/include/show-route-tag.xml.i7
-rw-r--r--op-mode-definitions/include/vtysh-generic-detail-wide.xml.i11
-rw-r--r--op-mode-definitions/include/vtysh-generic-interface-virtualTagNode.xml11
-rw-r--r--op-mode-definitions/install-mok.xml.in2
-rw-r--r--op-mode-definitions/ipv4-route.xml.in18
-rw-r--r--op-mode-definitions/ipv6-route.xml.in16
-rw-r--r--op-mode-definitions/load-balancing_haproxy.xml.in4
-rw-r--r--op-mode-definitions/load-balancing_wan.xml.in4
-rw-r--r--op-mode-definitions/mdns-reflector.xml.in2
-rw-r--r--op-mode-definitions/monitor-bridge.xml.in8
-rw-r--r--op-mode-definitions/monitor-command.xml.in29
-rw-r--r--op-mode-definitions/monitor-log.xml.in27
-rw-r--r--op-mode-definitions/monitor-ndp.xml.in8
-rw-r--r--op-mode-definitions/monitor-protocol.xml.in20
-rw-r--r--op-mode-definitions/mtr.xml.in8
-rw-r--r--op-mode-definitions/nat.xml.in22
-rw-r--r--op-mode-definitions/nat66.xml.in16
-rw-r--r--op-mode-definitions/ntp.xml.in12
-rw-r--r--op-mode-definitions/openconnect.xml.in2
-rw-r--r--op-mode-definitions/openvpn.xml.in131
-rw-r--r--op-mode-definitions/ping.xml.in4
-rw-r--r--op-mode-definitions/pki.xml.in96
-rw-r--r--op-mode-definitions/policy-route.xml.in28
-rw-r--r--op-mode-definitions/poweroff.xml.in12
-rw-r--r--op-mode-definitions/raid.xml.in8
-rw-r--r--op-mode-definitions/reboot.xml.in12
-rw-r--r--op-mode-definitions/reset-bgp.xml.in172
-rw-r--r--op-mode-definitions/reset-connection.xml.in18
-rw-r--r--op-mode-definitions/reset-conntrack.xml.in2
-rw-r--r--op-mode-definitions/reset-ip-bgp.xml.in46
-rw-r--r--op-mode-definitions/reset-session.xml.in (renamed from op-mode-definitions/clear-session.xml.in)4
-rw-r--r--op-mode-definitions/reset-vpn.xml.in18
-rw-r--r--op-mode-definitions/reset-wireguard.xml.in4
-rw-r--r--op-mode-definitions/restart-frr.xml.in28
-rw-r--r--op-mode-definitions/restart-ntp.xml.in2
-rw-r--r--op-mode-definitions/restart-router-advert.xml.in2
-rw-r--r--op-mode-definitions/restart-serial.xml.in4
-rw-r--r--op-mode-definitions/restart-snmp.xml.in2
-rw-r--r--op-mode-definitions/restart-ssh.xml.in2
-rw-r--r--op-mode-definitions/rpki.xml.in57
-rw-r--r--op-mode-definitions/sflow.xml.in3
-rw-r--r--op-mode-definitions/show-acceleration.xml.in10
-rw-r--r--op-mode-definitions/show-babel.xml.in10
-rw-r--r--op-mode-definitions/show-bfd.xml.in5
-rw-r--r--op-mode-definitions/show-bgp.xml.in10
-rw-r--r--op-mode-definitions/show-bridge.xml.in105
-rw-r--r--op-mode-definitions/show-conntrack.xml.in6
-rw-r--r--op-mode-definitions/show-environment.xml.in2
-rw-r--r--op-mode-definitions/show-evpn.xml.in71
-rw-r--r--op-mode-definitions/show-hardware.xml.in6
-rw-r--r--op-mode-definitions/show-history.xml.in21
-rw-r--r--op-mode-definitions/show-interfaces-bonding.xml.in117
-rw-r--r--op-mode-definitions/show-interfaces-bridge.xml.in40
-rw-r--r--op-mode-definitions/show-interfaces-dummy.xml.in40
-rw-r--r--op-mode-definitions/show-interfaces-ethernet.xml.in131
-rw-r--r--op-mode-definitions/show-interfaces-geneve.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-input.xml.in34
-rw-r--r--op-mode-definitions/show-interfaces-l2tpv3.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-loopback.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-macsec.xml.in26
-rw-r--r--op-mode-definitions/show-interfaces-pppoe.xml.in56
-rw-r--r--op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in40
-rw-r--r--op-mode-definitions/show-interfaces-sstpc.xml.in56
-rw-r--r--op-mode-definitions/show-interfaces-tunnel.xml.in40
-rw-r--r--op-mode-definitions/show-interfaces-virtual-ethernet.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-vti.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-vxlan.xml.in38
-rw-r--r--op-mode-definitions/show-interfaces-wireguard.xml.in84
-rw-r--r--op-mode-definitions/show-interfaces-wireless.xml.in90
-rw-r--r--op-mode-definitions/show-interfaces-wwan.xml.in160
-rw-r--r--op-mode-definitions/show-interfaces.xml.in42
-rw-r--r--op-mode-definitions/show-ip-access-paths-prefix-community-lists.xml.in72
-rw-r--r--op-mode-definitions/show-ip-bgp.xml.in10
-rw-r--r--op-mode-definitions/show-ip-ports.xml.in2
-rw-r--r--op-mode-definitions/show-ip-route.xml.in56
-rw-r--r--op-mode-definitions/show-ipv6-ospfv3.xml.in34
-rw-r--r--op-mode-definitions/show-ipv6-prefix-list.xml.in106
-rw-r--r--op-mode-definitions/show-ipv6-route.xml.in56
-rw-r--r--op-mode-definitions/show-ipv6.xml.in10
-rw-r--r--op-mode-definitions/show-kernel-modules.xml.in2
-rwxr-xr-xop-mode-definitions/show-log.xml.in100
-rw-r--r--op-mode-definitions/show-login.xml.in6
-rw-r--r--op-mode-definitions/show-mpls.xml.in80
-rw-r--r--op-mode-definitions/show-openfabric.xml.in2
-rw-r--r--op-mode-definitions/show-qos.xml.in14
-rw-r--r--op-mode-definitions/show-raid.xml.in2
-rw-r--r--op-mode-definitions/show-route-map.xml.in10
-rw-r--r--op-mode-definitions/show-ssh.xml.in2
-rw-r--r--op-mode-definitions/show-system.xml.in14
-rw-r--r--op-mode-definitions/show-techsupport_report.xml.in2
-rw-r--r--op-mode-definitions/show-users.xml.in10
-rw-r--r--op-mode-definitions/show-version.xml.in4
-rw-r--r--op-mode-definitions/show-vrf.xml.in46
-rw-r--r--op-mode-definitions/suricata.xml.in4
-rw-r--r--op-mode-definitions/system-image.xml.in52
-rw-r--r--op-mode-definitions/terminal.xml.in12
-rw-r--r--op-mode-definitions/traceroute.xml.in4
-rw-r--r--op-mode-definitions/traffic-dump.xml.in4
-rw-r--r--op-mode-definitions/vpn-ipsec.xml.in56
-rw-r--r--op-mode-definitions/vrrp.xml.in46
-rw-r--r--op-mode-definitions/wake-on-lan.xml.in2
-rw-r--r--op-mode-definitions/webproxy.xml.in12
-rw-r--r--pyproject.toml2
-rw-r--r--python/vyos/accel_ppp.py2
-rw-r--r--python/vyos/accel_ppp_util.py6
-rw-r--r--python/vyos/airbag.py2
-rw-r--r--python/vyos/base.py21
-rw-r--r--python/vyos/component_version.py65
-rw-r--r--python/vyos/compose_config.py2
-rw-r--r--python/vyos/config.py12
-rw-r--r--python/vyos/config_mgmt.py27
-rw-r--r--python/vyos/configdep.py2
-rw-r--r--python/vyos/configdict.py54
-rw-r--r--python/vyos/configdiff.py2
-rw-r--r--python/vyos/configquery.py2
-rw-r--r--python/vyos/configsession.py147
-rw-r--r--python/vyos/configsource.py112
-rw-r--r--python/vyos/configtree.py27
-rw-r--r--python/vyos/configverify.py27
-rw-r--r--python/vyos/debug.py2
-rw-r--r--python/vyos/defaults.py30
-rw-r--r--python/vyos/ethtool.py2
-rwxr-xr-xpython/vyos/firewall.py94
-rw-r--r--python/vyos/frrender.py24
-rw-r--r--python/vyos/ifconfig/__init__.py2
-rw-r--r--python/vyos/ifconfig/afi.py2
-rw-r--r--python/vyos/ifconfig/bond.py2
-rw-r--r--python/vyos/ifconfig/bridge.py26
-rw-r--r--python/vyos/ifconfig/control.py2
-rw-r--r--python/vyos/ifconfig/dummy.py2
-rw-r--r--python/vyos/ifconfig/ethernet.py2
-rw-r--r--python/vyos/ifconfig/geneve.py2
-rw-r--r--python/vyos/ifconfig/input.py2
-rw-r--r--python/vyos/ifconfig/interface.py164
-rw-r--r--python/vyos/ifconfig/l2tpv3.py2
-rw-r--r--python/vyos/ifconfig/loopback.py2
-rw-r--r--python/vyos/ifconfig/macsec.py2
-rw-r--r--python/vyos/ifconfig/macvlan.py2
-rw-r--r--python/vyos/ifconfig/operational.py2
-rw-r--r--python/vyos/ifconfig/pppoe.py2
-rw-r--r--python/vyos/ifconfig/section.py2
-rw-r--r--python/vyos/ifconfig/sstpc.py2
-rw-r--r--python/vyos/ifconfig/tunnel.py2
-rw-r--r--python/vyos/ifconfig/veth.py2
-rw-r--r--python/vyos/ifconfig/vrrp.py2
-rw-r--r--python/vyos/ifconfig/vti.py2
-rw-r--r--python/vyos/ifconfig/vtun.py2
-rw-r--r--python/vyos/ifconfig/vxlan.py2
-rw-r--r--python/vyos/ifconfig/wireguard.py164
-rw-r--r--python/vyos/ifconfig/wireless.py2
-rw-r--r--python/vyos/ifconfig/wwan.py2
-rw-r--r--python/vyos/iflag.py2
-rw-r--r--python/vyos/include/__init__.py2
-rw-r--r--python/vyos/include/uapi/__init__.py2
-rw-r--r--python/vyos/include/uapi/linux/__init__.py2
-rw-r--r--python/vyos/include/uapi/linux/fib_rules.py2
-rw-r--r--python/vyos/include/uapi/linux/icmpv6.py2
-rw-r--r--python/vyos/include/uapi/linux/if_arp.py2
-rw-r--r--python/vyos/include/uapi/linux/lwtunnel.py2
-rw-r--r--python/vyos/include/uapi/linux/neighbour.py2
-rw-r--r--python/vyos/include/uapi/linux/rtnetlink.py2
-rw-r--r--python/vyos/initialsetup.py2
-rw-r--r--python/vyos/ioctl.py2
-rw-r--r--python/vyos/ipsec.py2
-rw-r--r--python/vyos/kea.py67
-rw-r--r--python/vyos/limericks.py2
-rw-r--r--python/vyos/load_config.py2
-rw-r--r--python/vyos/logger.py2
-rw-r--r--python/vyos/migrate.py2
-rw-r--r--python/vyos/nat.py2
-rw-r--r--python/vyos/opmode.py2
-rw-r--r--python/vyos/pki.py2
-rw-r--r--python/vyos/priority.py2
-rw-r--r--python/vyos/progressbar.py2
-rwxr-xr-xpython/vyos/proto/generate_dataclass.py2
-rw-r--r--python/vyos/proto/vycall_pb2.py29
-rw-r--r--python/vyos/proto/vyconf_client.py6
-rw-r--r--python/vyos/proto/vyconf_pb2.py93
-rw-r--r--python/vyos/proto/vyconf_proto.py379
-rw-r--r--python/vyos/qos/__init__.py2
-rw-r--r--python/vyos/qos/base.py2
-rw-r--r--python/vyos/qos/cake.py11
-rw-r--r--python/vyos/qos/droptail.py2
-rw-r--r--python/vyos/qos/fairqueue.py2
-rw-r--r--python/vyos/qos/fqcodel.py2
-rw-r--r--python/vyos/qos/limiter.py2
-rw-r--r--python/vyos/qos/netem.py2
-rw-r--r--python/vyos/qos/priority.py2
-rw-r--r--python/vyos/qos/randomdetect.py2
-rw-r--r--python/vyos/qos/ratelimiter.py2
-rw-r--r--python/vyos/qos/roundrobin.py2
-rw-r--r--python/vyos/qos/trafficshaper.py2
-rw-r--r--python/vyos/raid.py2
-rw-r--r--python/vyos/remote.py46
-rw-r--r--python/vyos/snmpv3_hashgen.py2
-rw-r--r--python/vyos/system/__init__.py2
-rw-r--r--python/vyos/system/compat.py2
-rw-r--r--python/vyos/system/disk.py2
-rw-r--r--python/vyos/system/grub.py2
-rw-r--r--python/vyos/system/grub_util.py7
-rw-r--r--python/vyos/system/image.py2
-rw-r--r--python/vyos/system/raid.py2
-rwxr-xr-xpython/vyos/template.py193
-rw-r--r--python/vyos/tpm.py2
-rw-r--r--python/vyos/utils/__init__.py2
-rw-r--r--python/vyos/utils/assertion.py2
-rw-r--r--python/vyos/utils/auth.py2
-rw-r--r--python/vyos/utils/backend.py94
-rw-r--r--python/vyos/utils/boot.py2
-rw-r--r--python/vyos/utils/commit.py80
-rw-r--r--python/vyos/utils/config.py2
-rw-r--r--python/vyos/utils/configfs.py2
-rw-r--r--python/vyos/utils/convert.py2
-rw-r--r--python/vyos/utils/cpu.py8
-rw-r--r--python/vyos/utils/dict.py2
-rw-r--r--python/vyos/utils/disk.py2
-rw-r--r--python/vyos/utils/error.py2
-rw-r--r--python/vyos/utils/file.py23
-rw-r--r--python/vyos/utils/io.py2
-rw-r--r--python/vyos/utils/kernel.py2
-rw-r--r--python/vyos/utils/list.py2
-rw-r--r--python/vyos/utils/locking.py2
-rw-r--r--python/vyos/utils/misc.py2
-rw-r--r--python/vyos/utils/network.py93
-rw-r--r--python/vyos/utils/permission.py2
-rw-r--r--python/vyos/utils/process.py50
-rw-r--r--python/vyos/utils/serial.py2
-rw-r--r--[-rwxr-xr-x]python/vyos/utils/session.py (renamed from src/helpers/vyos-sudo.py)28
-rw-r--r--python/vyos/utils/strip_config.py2
-rw-r--r--python/vyos/utils/system.py2
-rw-r--r--python/vyos/utils/vti_updown_db.py2
-rw-r--r--python/vyos/version.py2
-rw-r--r--python/vyos/vyconf_session.py236
-rw-r--r--python/vyos/wanloadbalance.py2
-rw-r--r--python/vyos/xml_ref/__init__.py30
-rw-r--r--python/vyos/xml_ref/definition.py2
-rwxr-xr-xpython/vyos/xml_ref/generate_cache.py2
-rwxr-xr-xpython/vyos/xml_ref/generate_op_cache.py193
-rw-r--r--python/vyos/xml_ref/op_definition.py248
-rwxr-xr-xpython/vyos/xml_ref/update_cache.py2
-rw-r--r--schema/interface_definition.rnc2
-rw-r--r--schema/interface_definition.rng10
-rw-r--r--schema/op-mode-definition.rnc35
-rw-r--r--schema/op-mode-definition.rng97
-rwxr-xr-xscripts/build-command-op-templates62
-rwxr-xr-xscripts/build-command-templates2
-rwxr-xr-xscripts/generate-configd-include-json.py2
-rwxr-xr-xscripts/override-default2
-rwxr-xr-xscripts/transclude-template2
-rwxr-xr-xsmoketest/bin/vyos-configtest2
-rwxr-xr-xsmoketest/bin/vyos-configtest-pki2
-rwxr-xr-xsmoketest/bin/vyos-smoketest2
-rw-r--r--smoketest/config-tests/basic-haproxy46
-rw-r--r--smoketest/config-tests/basic-vyos17
-rw-r--r--smoketest/config-tests/conntrack-basic35
-rw-r--r--smoketest/config-tests/firewall-bridged-global-options21
-rw-r--r--smoketest/configs/basic-haproxy153
-rw-r--r--smoketest/configs/basic-vyos60
-rw-r--r--smoketest/configs/conntrack-basic92
-rw-r--r--smoketest/configs/firewall-bridged-global-options60
-rw-r--r--smoketest/scripts/cli/base_accel_ppp_test.py2
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py14
-rw-r--r--smoketest/scripts/cli/base_vyostest_shim.py8
-rwxr-xr-xsmoketest/scripts/cli/test_backslash_escape.py2
-rwxr-xr-xsmoketest/scripts/cli/test_cgnat.py2
-rwxr-xr-xsmoketest/scripts/cli/test_config_dependency.py2
-rwxr-xr-xsmoketest/scripts/cli/test_configd_init.py2
-rwxr-xr-xsmoketest/scripts/cli/test_container.py156
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py103
-rwxr-xr-xsmoketest/scripts/cli/test_high-availability_virtual-server.py2
-rwxr-xr-xsmoketest/scripts/cli/test_high-availability_vrrp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bonding.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py27
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_dummy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_geneve.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_input.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_l2tpv3.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_loopback.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_macsec.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_openvpn.py7
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pppoe.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pseudo-ethernet.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_tunnel.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_virtual-ethernet.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vti.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vxlan.py16
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireguard.py29
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py2
-rwxr-xr-xsmoketest/scripts/cli/test_load-balancing_haproxy.py144
-rwxr-xr-xsmoketest/scripts/cli/test_load-balancing_wan.py6
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py2
-rwxr-xr-xsmoketest/scripts/cli/test_nat64.py2
-rwxr-xr-xsmoketest/scripts/cli/test_nat66.py31
-rwxr-xr-xsmoketest/scripts/cli/test_netns.py2
-rwxr-xr-xsmoketest/scripts/cli/test_op-mode_show.py2
-rwxr-xr-xsmoketest/scripts/cli/test_pki.py2
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py2
-rw-r--r--smoketest/scripts/cli/test_policy_local-route.py2
-rwxr-xr-xsmoketest/scripts/cli/test_policy_route.py36
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_babel.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bfd.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py4
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_igmp-proxy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_mpls.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_nhrp.py2
-rw-r--r--smoketest/scripts/cli/test_protocols_openfabric.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py20
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_pim.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_pim6.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rip.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ripng.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rpki.py189
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_segment-routing.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static_arp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_qos.py31
-rwxr-xr-xsmoketest/scripts/cli/test_service_broadcast-relay.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-relay.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-server.py189
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcpv6-relay.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcpv6-server.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_dns_dynamic.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_dns_forwarding.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_https.py26
-rwxr-xr-xsmoketest/scripts/cli/test_service_ids_ddos-protection.py116
-rwxr-xr-xsmoketest/scripts/cli/test_service_ipoe-server.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_lldp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_mdns_repeater.py2
-rw-r--r--smoketest/scripts/cli/test_service_monitoring_network_event.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_monitoring_prometheus.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_monitoring_telegraf.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_monitoring_zabbix-agent.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_ndp-proxy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_ntp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_pppoe-server.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_router-advert.py114
-rwxr-xr-xsmoketest/scripts/cli/test_service_salt-minion.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_snmp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_ssh.py201
-rwxr-xr-xsmoketest/scripts/cli/test_service_stunnel.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_tftp-server.py2
-rwxr-xr-xsmoketest/scripts/cli/test_service_webproxy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_acceleration_qat.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_conntrack.py29
-rwxr-xr-xsmoketest/scripts/cli/test_system_flow-accounting.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_frr.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_ip.py23
-rwxr-xr-xsmoketest/scripts/cli/test_system_ipv6.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_login.py31
-rwxr-xr-xsmoketest/scripts/cli/test_system_logs.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_option.py62
-rwxr-xr-xsmoketest/scripts/cli/test_system_resolvconf.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_sflow.py2
-rwxr-xr-xsmoketest/scripts/cli/test_system_syslog.py8
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_ipsec.py90
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_l2tp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_openconnect.py2
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_pptp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_sstp.py2
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py2
-rwxr-xr-xsmoketest/scripts/system/test_config_mount.py2
-rwxr-xr-xsmoketest/scripts/system/test_iproute2.py2
-rwxr-xr-xsmoketest/scripts/system/test_kernel_options.py29
-rwxr-xr-xsmoketest/scripts/system/test_module_load.py2
-rwxr-xr-xsrc/activation-scripts/20-ethernet_offload.py2
-rwxr-xr-xsrc/completion/list_bgp_neighbors.sh2
-rwxr-xr-xsrc/completion/list_container_sysctl_parameters.sh2
-rwxr-xr-xsrc/completion/list_ddclient_protocols.sh2
-rwxr-xr-xsrc/completion/list_disks.py2
-rwxr-xr-xsrc/completion/list_esi.sh2
-rwxr-xr-xsrc/completion/list_images.py2
-rwxr-xr-xsrc/completion/list_ipoe.py2
-rw-r--r--src/completion/list_ipsec_profile_tunnels.py2
-rw-r--r--src/completion/list_login_ttys.py2
-rwxr-xr-xsrc/completion/list_openconnect_users.py2
-rwxr-xr-xsrc/completion/list_openvpn_clients.py2
-rwxr-xr-xsrc/completion/list_openvpn_users.py2
-rwxr-xr-xsrc/completion/list_sysctl_parameters.sh2
-rwxr-xr-xsrc/completion/list_vni.sh2
-rw-r--r--src/completion/qos/list_traffic_match_group.py2
-rwxr-xr-xsrc/conf_mode/container.py14
-rwxr-xr-xsrc/conf_mode/firewall.py39
-rwxr-xr-xsrc/conf_mode/high-availability.py2
-rwxr-xr-xsrc/conf_mode/interfaces_bonding.py2
-rwxr-xr-xsrc/conf_mode/interfaces_bridge.py15
-rwxr-xr-xsrc/conf_mode/interfaces_dummy.py2
-rwxr-xr-xsrc/conf_mode/interfaces_ethernet.py36
-rwxr-xr-xsrc/conf_mode/interfaces_geneve.py2
-rwxr-xr-xsrc/conf_mode/interfaces_input.py2
-rwxr-xr-xsrc/conf_mode/interfaces_l2tpv3.py2
-rwxr-xr-xsrc/conf_mode/interfaces_loopback.py2
-rwxr-xr-xsrc/conf_mode/interfaces_macsec.py2
-rwxr-xr-xsrc/conf_mode/interfaces_openvpn.py2
-rwxr-xr-xsrc/conf_mode/interfaces_pppoe.py2
-rwxr-xr-xsrc/conf_mode/interfaces_pseudo-ethernet.py4
-rwxr-xr-xsrc/conf_mode/interfaces_sstpc.py2
-rwxr-xr-xsrc/conf_mode/interfaces_tunnel.py2
-rwxr-xr-xsrc/conf_mode/interfaces_virtual-ethernet.py4
-rwxr-xr-xsrc/conf_mode/interfaces_vti.py4
-rwxr-xr-xsrc/conf_mode/interfaces_vxlan.py2
-rwxr-xr-xsrc/conf_mode/interfaces_wireguard.py32
-rwxr-xr-xsrc/conf_mode/interfaces_wireless.py2
-rwxr-xr-xsrc/conf_mode/interfaces_wwan.py9
-rw-r--r--src/conf_mode/load-balancing_haproxy.py37
-rwxr-xr-xsrc/conf_mode/load-balancing_wan.py2
-rwxr-xr-xsrc/conf_mode/nat.py16
-rwxr-xr-xsrc/conf_mode/nat64.py2
-rwxr-xr-xsrc/conf_mode/nat66.py6
-rwxr-xr-xsrc/conf_mode/nat_cgnat.py2
-rwxr-xr-xsrc/conf_mode/netns.py2
-rwxr-xr-xsrc/conf_mode/pki.py101
-rwxr-xr-xsrc/conf_mode/policy.py18
-rwxr-xr-xsrc/conf_mode/policy_local-route.py2
-rwxr-xr-xsrc/conf_mode/policy_route.py49
-rwxr-xr-xsrc/conf_mode/protocols_babel.py2
-rwxr-xr-xsrc/conf_mode/protocols_bfd.py2
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py21
-rwxr-xr-xsrc/conf_mode/protocols_eigrp.py2
-rwxr-xr-xsrc/conf_mode/protocols_failover.py2
-rwxr-xr-xsrc/conf_mode/protocols_igmp-proxy.py2
-rwxr-xr-xsrc/conf_mode/protocols_isis.py2
-rwxr-xr-xsrc/conf_mode/protocols_mpls.py2
-rwxr-xr-xsrc/conf_mode/protocols_nhrp.py2
-rw-r--r--src/conf_mode/protocols_openfabric.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py13
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py2
-rwxr-xr-xsrc/conf_mode/protocols_pim.py2
-rwxr-xr-xsrc/conf_mode/protocols_pim6.py2
-rwxr-xr-xsrc/conf_mode/protocols_rip.py2
-rwxr-xr-xsrc/conf_mode/protocols_ripng.py2
-rwxr-xr-xsrc/conf_mode/protocols_rpki.py19
-rwxr-xr-xsrc/conf_mode/protocols_segment-routing.py2
-rwxr-xr-xsrc/conf_mode/protocols_static.py2
-rwxr-xr-xsrc/conf_mode/protocols_static_arp.py2
-rwxr-xr-xsrc/conf_mode/protocols_static_neighbor-proxy.py2
-rwxr-xr-xsrc/conf_mode/qos.py10
-rwxr-xr-xsrc/conf_mode/service_aws_glb.py2
-rwxr-xr-xsrc/conf_mode/service_broadcast-relay.py2
-rwxr-xr-xsrc/conf_mode/service_config-sync.py2
-rwxr-xr-xsrc/conf_mode/service_conntrack-sync.py2
-rwxr-xr-xsrc/conf_mode/service_console-server.py2
-rwxr-xr-xsrc/conf_mode/service_dhcp-relay.py2
-rwxr-xr-xsrc/conf_mode/service_dhcp-server.py49
-rwxr-xr-xsrc/conf_mode/service_dhcpv6-relay.py2
-rwxr-xr-xsrc/conf_mode/service_dhcpv6-server.py2
-rwxr-xr-xsrc/conf_mode/service_dns_dynamic.py2
-rwxr-xr-xsrc/conf_mode/service_dns_forwarding.py2
-rwxr-xr-xsrc/conf_mode/service_event-handler.py2
-rwxr-xr-xsrc/conf_mode/service_https.py16
-rwxr-xr-xsrc/conf_mode/service_ids_ddos-protection.py104
-rwxr-xr-xsrc/conf_mode/service_ipoe-server.py8
-rwxr-xr-xsrc/conf_mode/service_lldp.py2
-rwxr-xr-xsrc/conf_mode/service_mdns_repeater.py2
-rw-r--r--src/conf_mode/service_monitoring_network_event.py2
-rwxr-xr-xsrc/conf_mode/service_monitoring_prometheus.py30
-rwxr-xr-xsrc/conf_mode/service_monitoring_telegraf.py2
-rwxr-xr-xsrc/conf_mode/service_monitoring_zabbix-agent.py2
-rwxr-xr-xsrc/conf_mode/service_ndp-proxy.py2
-rwxr-xr-xsrc/conf_mode/service_ntp.py2
-rwxr-xr-xsrc/conf_mode/service_pppoe-server.py6
-rwxr-xr-xsrc/conf_mode/service_router-advert.py2
-rwxr-xr-xsrc/conf_mode/service_salt-minion.py2
-rwxr-xr-xsrc/conf_mode/service_sla.py2
-rwxr-xr-xsrc/conf_mode/service_snmp.py2
-rwxr-xr-xsrc/conf_mode/service_ssh.py78
-rw-r--r--src/conf_mode/service_stunnel.py2
-rwxr-xr-xsrc/conf_mode/service_suricata.py2
-rwxr-xr-xsrc/conf_mode/service_tftp-server.py2
-rwxr-xr-xsrc/conf_mode/service_webproxy.py2
-rwxr-xr-xsrc/conf_mode/system_acceleration.py2
-rwxr-xr-xsrc/conf_mode/system_config-management.py2
-rwxr-xr-xsrc/conf_mode/system_conntrack.py4
-rwxr-xr-xsrc/conf_mode/system_console.py2
-rwxr-xr-xsrc/conf_mode/system_flow-accounting.py2
-rwxr-xr-xsrc/conf_mode/system_frr.py2
-rwxr-xr-xsrc/conf_mode/system_host-name.py4
-rwxr-xr-xsrc/conf_mode/system_ip.py7
-rwxr-xr-xsrc/conf_mode/system_ipv6.py2
-rwxr-xr-xsrc/conf_mode/system_lcd.py2
-rwxr-xr-xsrc/conf_mode/system_login.py42
-rwxr-xr-xsrc/conf_mode/system_login_banner.py2
-rwxr-xr-xsrc/conf_mode/system_logs.py2
-rwxr-xr-xsrc/conf_mode/system_option.py56
-rwxr-xr-xsrc/conf_mode/system_proxy.py2
-rwxr-xr-xsrc/conf_mode/system_sflow.py2
-rwxr-xr-xsrc/conf_mode/system_sysctl.py2
-rwxr-xr-xsrc/conf_mode/system_syslog.py4
-rwxr-xr-xsrc/conf_mode/system_task-scheduler.py2
-rwxr-xr-xsrc/conf_mode/system_timezone.py2
-rwxr-xr-xsrc/conf_mode/system_update-check.py2
-rw-r--r--src/conf_mode/system_wireless.py2
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py4
-rwxr-xr-xsrc/conf_mode/vpn_l2tp.py2
-rwxr-xr-xsrc/conf_mode/vpn_openconnect.py329
-rwxr-xr-xsrc/conf_mode/vpn_pptp.py2
-rwxr-xr-xsrc/conf_mode/vpn_sstp.py2
-rwxr-xr-xsrc/conf_mode/vrf.py13
-rw-r--r--src/etc/default/vyatta1
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/06-vyos-nodefaultroute20
-rwxr-xr-xsrc/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook2
-rwxr-xr-xsrc/etc/ipsec.d/vti-up-down2
-rwxr-xr-xsrc/etc/netplug/netplug2
-rwxr-xr-xsrc/etc/netplug/vyos-netplug-dhcp-client41
-rwxr-xr-xsrc/etc/opennhrp/opennhrp-script.py371
-rwxr-xr-xsrc/etc/ppp/ip-up.d/96-vyos-sstpc-callback2
-rwxr-xr-xsrc/etc/ppp/ip-up.d/99-vyos-pppoe-callback2
-rwxr-xr-xsrc/etc/ppp/ip-up.d/99-vyos-pppoe-wlb2
-rw-r--r--src/etc/sysctl.d/30-vyos-router.conf10
-rw-r--r--src/etc/systemd/system/certbot.service.d/10-override.conf7
-rw-r--r--src/etc/systemd/system/fastnetmon.service.d/override.conf12
-rw-r--r--src/etc/systemd/system/frr.service.d/override.conf6
-rw-r--r--src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf10
-rw-r--r--src/etc/systemd/system/kea-dhcp-ddns-server.service.d/override.conf7
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/vyos_services_input_filter.py2
-rwxr-xr-xsrc/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py2
-rwxr-xr-xsrc/helpers/add-system-version.py2
-rwxr-xr-xsrc/helpers/config_dependency.py2
-rwxr-xr-xsrc/helpers/geoip-update.py19
-rwxr-xr-xsrc/helpers/priority.py2
-rwxr-xr-xsrc/helpers/read-saved-value.py2
-rwxr-xr-xsrc/helpers/reset_section.py124
-rwxr-xr-xsrc/helpers/run-config-activation.py2
-rwxr-xr-xsrc/helpers/run-config-migration.py9
-rwxr-xr-xsrc/helpers/set_vyconf_backend.py43
-rwxr-xr-xsrc/helpers/show_commit_data.py2
-rwxr-xr-xsrc/helpers/strip-private.py2
-rwxr-xr-xsrc/helpers/teardown-config-session.py27
-rwxr-xr-xsrc/helpers/test_commit.py2
-rwxr-xr-xsrc/helpers/vyconf_cli.py47
-rwxr-xr-xsrc/helpers/vyos-boot-config-loader.py2
-rwxr-xr-xsrc/helpers/vyos-check-wwan.py2
-rwxr-xr-xsrc/helpers/vyos-config-encrypt.py2
-rwxr-xr-xsrc/helpers/vyos-failover.py2
-rwxr-xr-xsrc/helpers/vyos-interface-rescan.py2
-rwxr-xr-xsrc/helpers/vyos-load-balancer.py8
-rwxr-xr-xsrc/helpers/vyos-load-config.py101
-rwxr-xr-xsrc/helpers/vyos-merge-config.py143
-rwxr-xr-xsrc/helpers/vyos-save-config.py2
-rwxr-xr-xsrc/helpers/vyos_config_sync.py2
-rwxr-xr-xsrc/helpers/vyos_net_name2
-rwxr-xr-xsrc/init/vyos-router132
-rw-r--r--src/migration-scripts/bgp/0-to-12
-rw-r--r--src/migration-scripts/bgp/1-to-22
-rw-r--r--src/migration-scripts/bgp/2-to-32
-rw-r--r--src/migration-scripts/bgp/3-to-42
-rw-r--r--src/migration-scripts/bgp/4-to-52
-rw-r--r--src/migration-scripts/bgp/5-to-62
-rw-r--r--src/migration-scripts/cluster/1-to-22
-rw-r--r--src/migration-scripts/config-management/0-to-12
-rw-r--r--src/migration-scripts/conntrack-sync/1-to-22
-rw-r--r--src/migration-scripts/conntrack/1-to-22
-rw-r--r--src/migration-scripts/conntrack/2-to-32
-rw-r--r--src/migration-scripts/conntrack/3-to-42
-rw-r--r--src/migration-scripts/conntrack/4-to-52
-rw-r--r--src/migration-scripts/conntrack/5-to-630
-rw-r--r--src/migration-scripts/container/0-to-12
-rw-r--r--src/migration-scripts/container/1-to-22
-rw-r--r--src/migration-scripts/container/2-to-331
-rw-r--r--src/migration-scripts/dhcp-relay/1-to-22
-rw-r--r--src/migration-scripts/dhcp-server/10-to-112
-rw-r--r--src/migration-scripts/dhcp-server/4-to-52
-rw-r--r--src/migration-scripts/dhcp-server/5-to-62
-rw-r--r--src/migration-scripts/dhcp-server/6-to-72
-rw-r--r--src/migration-scripts/dhcp-server/7-to-88
-rw-r--r--src/migration-scripts/dhcp-server/8-to-92
-rw-r--r--src/migration-scripts/dhcp-server/9-to-102
-rw-r--r--src/migration-scripts/dhcpv6-server/0-to-12
-rw-r--r--src/migration-scripts/dhcpv6-server/1-to-22
-rw-r--r--src/migration-scripts/dhcpv6-server/2-to-32
-rw-r--r--src/migration-scripts/dhcpv6-server/3-to-42
-rw-r--r--src/migration-scripts/dhcpv6-server/4-to-52
-rw-r--r--src/migration-scripts/dhcpv6-server/5-to-62
-rw-r--r--src/migration-scripts/dns-dynamic/0-to-12
-rw-r--r--src/migration-scripts/dns-dynamic/1-to-22
-rw-r--r--src/migration-scripts/dns-dynamic/2-to-32
-rw-r--r--src/migration-scripts/dns-dynamic/3-to-42
-rw-r--r--src/migration-scripts/dns-forwarding/0-to-12
-rw-r--r--src/migration-scripts/dns-forwarding/1-to-22
-rw-r--r--src/migration-scripts/dns-forwarding/2-to-32
-rw-r--r--src/migration-scripts/dns-forwarding/3-to-42
-rw-r--r--src/migration-scripts/firewall/10-to-112
-rw-r--r--src/migration-scripts/firewall/11-to-122
-rw-r--r--src/migration-scripts/firewall/12-to-132
-rw-r--r--src/migration-scripts/firewall/13-to-142
-rw-r--r--src/migration-scripts/firewall/14-to-152
-rw-r--r--src/migration-scripts/firewall/15-to-162
-rw-r--r--src/migration-scripts/firewall/16-to-172
-rwxr-xr-xsrc/migration-scripts/firewall/17-to-182
-rw-r--r--src/migration-scripts/firewall/18-to-1935
-rw-r--r--src/migration-scripts/firewall/5-to-62
-rw-r--r--src/migration-scripts/firewall/6-to-72
-rw-r--r--src/migration-scripts/firewall/7-to-82
-rw-r--r--src/migration-scripts/firewall/8-to-92
-rw-r--r--src/migration-scripts/firewall/9-to-102
-rw-r--r--src/migration-scripts/flow-accounting/0-to-12
-rw-r--r--src/migration-scripts/flow-accounting/1-to-22
-rw-r--r--src/migration-scripts/https/0-to-12
-rw-r--r--src/migration-scripts/https/1-to-22
-rw-r--r--src/migration-scripts/https/2-to-32
-rw-r--r--src/migration-scripts/https/3-to-42
-rw-r--r--src/migration-scripts/https/4-to-52
-rw-r--r--src/migration-scripts/https/5-to-62
-rw-r--r--src/migration-scripts/https/6-to-72
-rw-r--r--src/migration-scripts/ids/0-to-12
-rw-r--r--src/migration-scripts/ids/1-to-230
-rw-r--r--src/migration-scripts/interfaces/0-to-12
-rw-r--r--src/migration-scripts/interfaces/1-to-22
-rw-r--r--src/migration-scripts/interfaces/10-to-112
-rw-r--r--src/migration-scripts/interfaces/11-to-122
-rw-r--r--src/migration-scripts/interfaces/12-to-132
-rw-r--r--src/migration-scripts/interfaces/13-to-142
-rw-r--r--src/migration-scripts/interfaces/14-to-152
-rw-r--r--src/migration-scripts/interfaces/15-to-162
-rw-r--r--src/migration-scripts/interfaces/16-to-172
-rw-r--r--src/migration-scripts/interfaces/17-to-182
-rw-r--r--src/migration-scripts/interfaces/18-to-192
-rw-r--r--src/migration-scripts/interfaces/19-to-202
-rw-r--r--src/migration-scripts/interfaces/2-to-32
-rw-r--r--src/migration-scripts/interfaces/20-to-212
-rw-r--r--src/migration-scripts/interfaces/21-to-222
-rw-r--r--src/migration-scripts/interfaces/22-to-232
-rw-r--r--src/migration-scripts/interfaces/23-to-242
-rw-r--r--src/migration-scripts/interfaces/24-to-252
-rw-r--r--src/migration-scripts/interfaces/25-to-262
-rw-r--r--src/migration-scripts/interfaces/26-to-272
-rw-r--r--src/migration-scripts/interfaces/27-to-282
-rw-r--r--src/migration-scripts/interfaces/28-to-292
-rw-r--r--src/migration-scripts/interfaces/29-to-302
-rw-r--r--src/migration-scripts/interfaces/3-to-42
-rw-r--r--src/migration-scripts/interfaces/30-to-312
-rw-r--r--src/migration-scripts/interfaces/31-to-322
-rw-r--r--src/migration-scripts/interfaces/32-to-332
-rw-r--r--src/migration-scripts/interfaces/4-to-52
-rw-r--r--src/migration-scripts/interfaces/5-to-62
-rw-r--r--src/migration-scripts/interfaces/6-to-72
-rw-r--r--src/migration-scripts/interfaces/7-to-82
-rw-r--r--src/migration-scripts/interfaces/8-to-92
-rw-r--r--src/migration-scripts/interfaces/9-to-102
-rw-r--r--src/migration-scripts/ipoe-server/1-to-22
-rw-r--r--src/migration-scripts/ipoe-server/2-to-32
-rw-r--r--src/migration-scripts/ipoe-server/3-to-42
-rw-r--r--src/migration-scripts/ipsec/10-to-112
-rw-r--r--src/migration-scripts/ipsec/11-to-122
-rw-r--r--src/migration-scripts/ipsec/12-to-132
-rw-r--r--src/migration-scripts/ipsec/4-to-52
-rw-r--r--src/migration-scripts/ipsec/5-to-62
-rw-r--r--src/migration-scripts/ipsec/6-to-72
-rw-r--r--src/migration-scripts/ipsec/7-to-82
-rw-r--r--src/migration-scripts/ipsec/8-to-92
-rw-r--r--src/migration-scripts/ipsec/9-to-102
-rw-r--r--src/migration-scripts/isis/0-to-12
-rw-r--r--src/migration-scripts/isis/1-to-22
-rw-r--r--src/migration-scripts/isis/2-to-32
-rw-r--r--src/migration-scripts/l2tp/0-to-12
-rw-r--r--src/migration-scripts/l2tp/1-to-22
-rw-r--r--src/migration-scripts/l2tp/2-to-32
-rw-r--r--src/migration-scripts/l2tp/3-to-42
-rw-r--r--src/migration-scripts/l2tp/4-to-52
-rw-r--r--src/migration-scripts/l2tp/5-to-62
-rw-r--r--src/migration-scripts/l2tp/6-to-72
-rw-r--r--src/migration-scripts/l2tp/7-to-82
-rw-r--r--src/migration-scripts/l2tp/8-to-92
-rw-r--r--src/migration-scripts/lldp/0-to-12
-rw-r--r--src/migration-scripts/lldp/1-to-22
-rw-r--r--src/migration-scripts/lldp/2-to-32
-rw-r--r--src/migration-scripts/monitoring/0-to-14
-rw-r--r--src/migration-scripts/monitoring/1-to-22
-rw-r--r--src/migration-scripts/nat/4-to-52
-rw-r--r--src/migration-scripts/nat/5-to-62
-rw-r--r--src/migration-scripts/nat/6-to-72
-rw-r--r--src/migration-scripts/nat/7-to-82
-rw-r--r--src/migration-scripts/nat66/0-to-12
-rw-r--r--src/migration-scripts/nat66/1-to-24
-rw-r--r--src/migration-scripts/nat66/2-to-32
-rw-r--r--src/migration-scripts/nhrp/0-to-12
-rw-r--r--src/migration-scripts/ntp/0-to-12
-rw-r--r--src/migration-scripts/ntp/1-to-22
-rw-r--r--src/migration-scripts/ntp/2-to-32
-rw-r--r--src/migration-scripts/openconnect/0-to-12
-rw-r--r--src/migration-scripts/openconnect/1-to-22
-rw-r--r--src/migration-scripts/openconnect/2-to-32
-rw-r--r--src/migration-scripts/openvpn/0-to-12
-rw-r--r--src/migration-scripts/openvpn/1-to-22
-rw-r--r--src/migration-scripts/openvpn/2-to-32
-rw-r--r--src/migration-scripts/openvpn/3-to-42
-rw-r--r--src/migration-scripts/ospf/0-to-12
-rw-r--r--src/migration-scripts/ospf/1-to-22
-rw-r--r--src/migration-scripts/pim/0-to-12
-rw-r--r--src/migration-scripts/policy/0-to-12
-rw-r--r--src/migration-scripts/policy/1-to-22
-rw-r--r--src/migration-scripts/policy/2-to-32
-rw-r--r--src/migration-scripts/policy/3-to-42
-rw-r--r--src/migration-scripts/policy/4-to-52
-rw-r--r--src/migration-scripts/policy/5-to-62
-rw-r--r--src/migration-scripts/policy/6-to-72
-rw-r--r--src/migration-scripts/policy/7-to-82
-rw-r--r--src/migration-scripts/policy/8-to-92
-rw-r--r--src/migration-scripts/pppoe-server/0-to-12
-rw-r--r--src/migration-scripts/pppoe-server/1-to-22
-rw-r--r--src/migration-scripts/pppoe-server/10-to-112
-rw-r--r--src/migration-scripts/pppoe-server/2-to-32
-rw-r--r--src/migration-scripts/pppoe-server/3-to-42
-rw-r--r--src/migration-scripts/pppoe-server/4-to-52
-rw-r--r--src/migration-scripts/pppoe-server/5-to-62
-rw-r--r--src/migration-scripts/pppoe-server/6-to-72
-rw-r--r--src/migration-scripts/pppoe-server/7-to-82
-rw-r--r--src/migration-scripts/pppoe-server/8-to-92
-rw-r--r--src/migration-scripts/pppoe-server/9-to-102
-rw-r--r--src/migration-scripts/pptp/0-to-12
-rw-r--r--src/migration-scripts/pptp/1-to-22
-rw-r--r--src/migration-scripts/pptp/2-to-32
-rw-r--r--src/migration-scripts/pptp/3-to-42
-rw-r--r--src/migration-scripts/pptp/4-to-52
-rw-r--r--src/migration-scripts/qos/1-to-22
-rw-r--r--src/migration-scripts/qos/2-to-32
-rw-r--r--src/migration-scripts/quagga/10-to-112
-rw-r--r--src/migration-scripts/quagga/11-to-122
-rw-r--r--src/migration-scripts/quagga/2-to-32
-rw-r--r--src/migration-scripts/quagga/3-to-42
-rw-r--r--src/migration-scripts/quagga/4-to-52
-rw-r--r--src/migration-scripts/quagga/5-to-62
-rw-r--r--src/migration-scripts/quagga/6-to-72
-rw-r--r--src/migration-scripts/quagga/7-to-82
-rw-r--r--src/migration-scripts/quagga/8-to-920
-rw-r--r--src/migration-scripts/quagga/9-to-102
-rw-r--r--src/migration-scripts/reverse-proxy/0-to-12
-rwxr-xr-xsrc/migration-scripts/reverse-proxy/1-to-22
-rwxr-xr-xsrc/migration-scripts/reverse-proxy/2-to-366
-rw-r--r--src/migration-scripts/rip/0-to-12
-rw-r--r--src/migration-scripts/rpki/0-to-12
-rw-r--r--src/migration-scripts/rpki/1-to-22
-rw-r--r--src/migration-scripts/salt/0-to-12
-rw-r--r--src/migration-scripts/snmp/0-to-12
-rw-r--r--src/migration-scripts/snmp/1-to-22
-rw-r--r--src/migration-scripts/snmp/2-to-32
-rw-r--r--src/migration-scripts/ssh/0-to-12
-rw-r--r--src/migration-scripts/ssh/1-to-22
-rw-r--r--src/migration-scripts/sstp/0-to-12
-rw-r--r--src/migration-scripts/sstp/1-to-22
-rw-r--r--src/migration-scripts/sstp/2-to-32
-rw-r--r--src/migration-scripts/sstp/3-to-42
-rw-r--r--src/migration-scripts/sstp/4-to-52
-rw-r--r--src/migration-scripts/sstp/5-to-62
-rw-r--r--src/migration-scripts/system/10-to-112
-rw-r--r--src/migration-scripts/system/11-to-122
-rw-r--r--src/migration-scripts/system/12-to-132
-rw-r--r--src/migration-scripts/system/13-to-142
-rw-r--r--src/migration-scripts/system/14-to-152
-rw-r--r--src/migration-scripts/system/15-to-162
-rw-r--r--src/migration-scripts/system/16-to-172
-rw-r--r--src/migration-scripts/system/17-to-182
-rw-r--r--src/migration-scripts/system/18-to-192
-rw-r--r--src/migration-scripts/system/19-to-202
-rw-r--r--src/migration-scripts/system/20-to-212
-rw-r--r--src/migration-scripts/system/21-to-222
-rw-r--r--src/migration-scripts/system/22-to-232
-rw-r--r--src/migration-scripts/system/23-to-242
-rw-r--r--src/migration-scripts/system/24-to-252
-rw-r--r--src/migration-scripts/system/25-to-262
-rw-r--r--src/migration-scripts/system/26-to-272
-rw-r--r--src/migration-scripts/system/27-to-282
-rw-r--r--src/migration-scripts/system/28-to-292
-rw-r--r--src/migration-scripts/system/6-to-72
-rw-r--r--src/migration-scripts/system/7-to-82
-rw-r--r--src/migration-scripts/system/8-to-92
-rw-r--r--src/migration-scripts/vrf/0-to-12
-rw-r--r--src/migration-scripts/vrf/1-to-27
-rw-r--r--src/migration-scripts/vrf/2-to-35
-rw-r--r--src/migration-scripts/vrrp/1-to-22
-rw-r--r--src/migration-scripts/vrrp/2-to-32
-rw-r--r--src/migration-scripts/vrrp/3-to-42
-rw-r--r--src/migration-scripts/wanloadbalance/3-to-42
-rw-r--r--src/migration-scripts/webproxy/1-to-22
-rwxr-xr-xsrc/op_mode/accelppp.py2
-rwxr-xr-xsrc/op_mode/bgp.py2
-rwxr-xr-xsrc/op_mode/bonding.py2
-rwxr-xr-xsrc/op_mode/bridge.py2
-rwxr-xr-xsrc/op_mode/cgnat.py2
-rwxr-xr-xsrc/op_mode/clear_conntrack.py2
-rwxr-xr-xsrc/op_mode/config_mgmt.py2
-rwxr-xr-xsrc/op_mode/connect_disconnect.py2
-rwxr-xr-xsrc/op_mode/conntrack.py2
-rwxr-xr-xsrc/op_mode/conntrack_sync.py2
-rwxr-xr-xsrc/op_mode/container.py44
-rwxr-xr-xsrc/op_mode/cpu.py2
-rwxr-xr-xsrc/op_mode/dhcp.py2
-rwxr-xr-xsrc/op_mode/dns.py2
-rw-r--r--src/op_mode/evpn.py2
-rwxr-xr-xsrc/op_mode/execute_bandwidth_test.sh2
-rw-r--r--src/op_mode/execute_port-scan.py2
-rwxr-xr-xsrc/op_mode/file.py2
-rwxr-xr-xsrc/op_mode/firewall.py26
-rwxr-xr-xsrc/op_mode/flow_accounting_op.py2
-rwxr-xr-xsrc/op_mode/force_mtu_host.sh2
-rwxr-xr-xsrc/op_mode/force_root-partition-auto-resize.sh2
-rwxr-xr-xsrc/op_mode/format_disk.py2
-rwxr-xr-xsrc/op_mode/generate_interfaces_debug_archive.py2
-rwxr-xr-xsrc/op_mode/generate_ipsec_debug_archive.py2
-rwxr-xr-xsrc/op_mode/generate_openconnect_otp_key.py2
-rwxr-xr-xsrc/op_mode/generate_ovpn_client_file.py2
-rw-r--r--src/op_mode/generate_psk.py2
-rwxr-xr-xsrc/op_mode/generate_public_key_command.py2
-rwxr-xr-xsrc/op_mode/generate_service_rule-resequence.py2
-rwxr-xr-xsrc/op_mode/generate_ssh_server_key.py2
-rwxr-xr-xsrc/op_mode/generate_system_login_user.py2
-rwxr-xr-xsrc/op_mode/generate_tech-support_archive.py2
-rwxr-xr-xsrc/op_mode/igmp-proxy.py2
-rwxr-xr-xsrc/op_mode/ikev2_profile_generator.py2
-rwxr-xr-xsrc/op_mode/image_info.py10
-rwxr-xr-xsrc/op_mode/image_installer.py95
-rwxr-xr-xsrc/op_mode/image_manager.py2
-rwxr-xr-xsrc/op_mode/install_mok.sh7
-rwxr-xr-xsrc/op_mode/interfaces.py140
-rw-r--r--src/op_mode/interfaces_wireguard.py2
-rwxr-xr-xsrc/op_mode/interfaces_wireless.py2
-rwxr-xr-xsrc/op_mode/ipoe-control.py2
-rwxr-xr-xsrc/op_mode/ipsec.py2
-rwxr-xr-xsrc/op_mode/kernel_modules.py2
-rwxr-xr-xsrc/op_mode/lldp.py2
-rwxr-xr-xsrc/op_mode/load-balancing_haproxy.py2
-rwxr-xr-xsrc/op_mode/load-balancing_wan.py6
-rwxr-xr-xsrc/op_mode/log.py2
-rwxr-xr-xsrc/op_mode/maya_date.py2
-rwxr-xr-xsrc/op_mode/memory.py2
-rw-r--r--src/op_mode/mtr.py2
-rw-r--r--src/op_mode/mtr_execute.py2
-rwxr-xr-xsrc/op_mode/multicast.py2
-rwxr-xr-xsrc/op_mode/nat.py2
-rwxr-xr-xsrc/op_mode/neighbor.py2
-rw-r--r--src/op_mode/ntp.py2
-rwxr-xr-xsrc/op_mode/openconnect-control.py2
-rwxr-xr-xsrc/op_mode/openconnect.py2
-rwxr-xr-xsrc/op_mode/openvpn.py2
-rwxr-xr-xsrc/op_mode/otp.py4
-rwxr-xr-xsrc/op_mode/ping.py2
-rwxr-xr-xsrc/op_mode/pki.py17
-rwxr-xr-xsrc/op_mode/policy_route.py2
-rwxr-xr-xsrc/op_mode/powerctrl.py2
-rwxr-xr-xsrc/op_mode/ppp-server-ctrl.py2
-rwxr-xr-xsrc/op_mode/qos.py2
-rwxr-xr-xsrc/op_mode/raid.py2
-rwxr-xr-xsrc/op_mode/reset_openvpn.py2
-rwxr-xr-xsrc/op_mode/reset_vpn.py2
-rwxr-xr-xsrc/op_mode/reset_wireguard.py2
-rwxr-xr-xsrc/op_mode/restart.py2
-rwxr-xr-xsrc/op_mode/restart_dhcp_relay.py2
-rwxr-xr-xsrc/op_mode/restart_frr.py2
-rwxr-xr-xsrc/op_mode/route.py2
-rwxr-xr-xsrc/op_mode/secure_boot.py2
-rw-r--r--src/op_mode/serial.py2
-rwxr-xr-xsrc/op_mode/sflow.py2
-rwxr-xr-xsrc/op_mode/show-bond.py2
-rwxr-xr-xsrc/op_mode/show_acceleration.py2
-rwxr-xr-xsrc/op_mode/show_bonding_detail.sh7
-rwxr-xr-xsrc/op_mode/show_configuration_json.py2
-rwxr-xr-xsrc/op_mode/show_openconnect_otp.py2
-rwxr-xr-xsrc/op_mode/show_openvpn.py2
-rwxr-xr-xsrc/op_mode/show_openvpn_mfa.py2
-rwxr-xr-xsrc/op_mode/show_ppp_stats.sh5
-rwxr-xr-xsrc/op_mode/show_sensors.py2
-rw-r--r--src/op_mode/show_techsupport_report.py2
-rwxr-xr-xsrc/op_mode/show_usb_serial.py2
-rwxr-xr-xsrc/op_mode/show_users.py2
-rwxr-xr-xsrc/op_mode/show_virtual_server.py2
-rwxr-xr-xsrc/op_mode/show_wwan.py2
-rwxr-xr-xsrc/op_mode/snmp.py2
-rwxr-xr-xsrc/op_mode/snmp_ifmib.py2
-rwxr-xr-xsrc/op_mode/snmp_v3.py2
-rwxr-xr-xsrc/op_mode/ssh.py2
-rwxr-xr-xsrc/op_mode/storage.py2
-rwxr-xr-xsrc/op_mode/stp.py2
-rwxr-xr-xsrc/op_mode/system.py2
-rw-r--r--src/op_mode/tcpdump.py2
-rw-r--r--src/op_mode/tech_support.py10
-rwxr-xr-xsrc/op_mode/toggle_help_binding.sh2
-rwxr-xr-xsrc/op_mode/traceroute.py2
-rwxr-xr-xsrc/op_mode/update_suricata.sh8
-rwxr-xr-xsrc/op_mode/uptime.py2
-rwxr-xr-xsrc/op_mode/version.py2
-rwxr-xr-xsrc/op_mode/vpn_ike_sa.py2
-rwxr-xr-xsrc/op_mode/vpn_ipsec.py9
-rwxr-xr-xsrc/op_mode/vrf.py2
-rwxr-xr-xsrc/op_mode/vrrp.py2
-rwxr-xr-xsrc/op_mode/webproxy_update_blacklist.sh2
-rwxr-xr-xsrc/op_mode/wireguard_client.py2
-rw-r--r--src/op_mode/zone.py2
-rw-r--r--src/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run17
-rw-r--r--src/services/api/graphql/bindings.py2
-rwxr-xr-xsrc/services/api/graphql/generate/generate_schema.py2
-rwxr-xr-xsrc/services/api/graphql/generate/schema_from_composite.py2
-rwxr-xr-xsrc/services/api/graphql/generate/schema_from_config_session.py2
-rwxr-xr-xsrc/services/api/graphql/generate/schema_from_op_mode.py2
-rw-r--r--src/services/api/graphql/graphql/auth_token_mutation.py2
-rw-r--r--src/services/api/graphql/graphql/directives.py2
-rw-r--r--src/services/api/graphql/graphql/mutations.py2
-rw-r--r--src/services/api/graphql/graphql/queries.py2
-rw-r--r--src/services/api/graphql/libs/key_auth.py2
-rw-r--r--src/services/api/graphql/libs/op_mode.py2
-rw-r--r--src/services/api/graphql/libs/token_auth.py2
-rw-r--r--src/services/api/graphql/routers.py2
-rwxr-xr-xsrc/services/api/graphql/session/composite/system_status.py2
-rw-r--r--src/services/api/graphql/session/override/remove_firewall_address_group_members.py2
-rw-r--r--src/services/api/graphql/session/session.py2
-rw-r--r--src/services/api/rest/models.py29
-rw-r--r--src/services/api/rest/routers.py168
-rw-r--r--src/services/api/session.py2
-rwxr-xr-xsrc/services/vyos-commitd6
-rwxr-xr-xsrc/services/vyos-configd16
-rwxr-xr-xsrc/services/vyos-conntrack-logger2
-rwxr-xr-xsrc/services/vyos-domain-resolver31
-rwxr-xr-xsrc/services/vyos-hostsd2
-rwxr-xr-xsrc/services/vyos-http-api-server2
-rw-r--r--src/services/vyos-network-event-logger2
-rw-r--r--src/shim/vyshim.c43
-rw-r--r--src/system/grub_update.py2
-rwxr-xr-xsrc/system/keepalived-fifo.py2
-rwxr-xr-xsrc/system/normalize-ip2
-rwxr-xr-xsrc/system/on-dhcp-event.sh2
-rwxr-xr-xsrc/system/on-dhcpv6-event.sh2
-rwxr-xr-xsrc/system/sync-dhcp-lease-to-hosts.py2
-rwxr-xr-xsrc/system/uacctd_stop.py2
-rwxr-xr-xsrc/system/vyos-config-cloud-init.py2
-rwxr-xr-xsrc/system/vyos-event-handler.py2
-rwxr-xr-xsrc/system/vyos-system-update-check.py2
-rw-r--r--src/systemd/netplug.service9
-rw-r--r--src/systemd/opennhrp.service13
-rw-r--r--src/systemd/vyconfd.service2
-rw-r--r--src/systemd/vyos.target2
-rw-r--r--src/tests/helper.py2
-rw-r--r--src/tests/test_config_diff.py2
-rw-r--r--src/tests/test_config_merge.py50
-rw-r--r--src/tests/test_config_parser.py2
-rw-r--r--src/tests/test_configd_inspect.py2
-rw-r--r--src/tests/test_configverify.py2
-rw-r--r--src/tests/test_dependency_graph.py2
-rw-r--r--src/tests/test_dict_search.py2
-rw-r--r--src/tests/test_find_device_file.py2
-rw-r--r--src/tests/test_initial_setup.py2
-rw-r--r--src/tests/test_op_mode.py2
-rw-r--r--src/tests/test_task_scheduler.py2
-rw-r--r--src/tests/test_template.py20
-rw-r--r--src/tests/test_utils.py2
-rw-r--r--src/tests/test_utils_network.py11
-rwxr-xr-xsrc/utils/vyos-commands-to-config2
-rwxr-xr-xsrc/utils/vyos-config-file-query2
-rwxr-xr-xsrc/utils/vyos-hostsd-client2
-rwxr-xr-xsrc/utils/vyos-show-config2
-rwxr-xr-xsrc/validators/as-number-list2
-rwxr-xr-xsrc/validators/base642
-rwxr-xr-xsrc/validators/bgp-extended-community2
-rwxr-xr-xsrc/validators/bgp-large-community2
-rwxr-xr-xsrc/validators/bgp-large-community-list21
-rwxr-xr-xsrc/validators/bgp-rd-rt2
-rwxr-xr-xsrc/validators/bgp-regular-community2
-rwxr-xr-xsrc/validators/cpu43
-rwxr-xr-xsrc/validators/ddclient-protocol2
-rw-r--r--src/validators/ether-type2
-rwxr-xr-xsrc/validators/ip-protocol2
-rw-r--r--src/validators/psk-secret2
-rwxr-xr-xsrc/validators/script2
-rwxr-xr-xsrc/validators/sysctl2
-rwxr-xr-xsrc/validators/timezone2
-rwxr-xr-xsrc/validators/vrf-name2
-rwxr-xr-xsrc/validators/wireless-phy2
1132 files changed, 11654 insertions, 6258 deletions
diff --git a/.github/workflows/check-open-prs-conflict.yml b/.github/workflows/check-open-prs-conflict.yml
new file mode 100644
index 000000000..52b11938e
--- /dev/null
+++ b/.github/workflows/check-open-prs-conflict.yml
@@ -0,0 +1,17 @@
+name: "Open PRs Conflicts checker"
+on:
+ push:
+ branches:
+ - current
+ - sagitta
+ - circinus
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ check-pr-conflict-call:
+ uses: vyos/.github/.github/workflows/check-open-prs-conflict.yml@current
+ secrets: inherit
diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml
new file mode 100644
index 000000000..3c1aeee67
--- /dev/null
+++ b/.github/workflows/cla-check.yml
@@ -0,0 +1,19 @@
+name: "CLA Check"
+
+permissions:
+ actions: write
+ contents: read
+ pull-requests: write
+ statuses: write
+
+on:
+ pull_request:
+ types: [opened, synchronize, closed]
+ issue_comment:
+ types: [created]
+
+jobs:
+ call-cla-assistant:
+ uses: vyos/vyos-cla-signatures/.github/workflows/cla-reusable.yml@current
+ secrets:
+ CLA_PAT: ${{ secrets.CLA_PAT }}
diff --git a/.github/workflows/cleanup-mirror-pr-branch.yml b/.github/workflows/cleanup-mirror-pr-branch.yml
deleted file mode 100644
index a62e44b24..000000000
--- a/.github/workflows/cleanup-mirror-pr-branch.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Cleanup pr mirror branch
-
-on:
- pull_request:
- types: [closed]
- branches:
- - current
-
-permissions:
- contents: write
-
-jobs:
- call-delete-branch:
- if: github.repository_owner != 'vyos'
- uses: vyos/.github/.github/workflows/cleanup-mirror-pr-branch.yml@current
- secrets: inherit
diff --git a/.github/workflows/lint-with-ruff.yml b/.github/workflows/darker-ruff-lint.yml
index 00cc9ca1b..0307d14d4 100644
--- a/.github/workflows/lint-with-ruff.yml
+++ b/.github/workflows/darker-ruff-lint.yml
@@ -1,4 +1,4 @@
-name: Lint py code with ruff
+name: Python Lint (Darker + Ruff)
on:
pull_request_target:
branches:
@@ -9,6 +9,6 @@ permissions:
contents: read
jobs:
- ruff-lint:
- uses: vyos/.github/.github/workflows/lint-with-ruff.yml@current
+ darker-ruff-lint:
+ uses: vyos/.github/.github/workflows/lint-with-darker-ruff.yml@current
secrets: inherit
diff --git a/.github/workflows/mirror-pr-and-sync.yml b/.github/workflows/mirror-pr-and-sync.yml
deleted file mode 100644
index 120e116d4..000000000
--- a/.github/workflows/mirror-pr-and-sync.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Create Mirror PR and Repo Sync
-on:
- workflow_dispatch:
- inputs:
- sync_branch:
- description: 'branch to sync'
- required: true
- type: string
-
-permissions:
- pull-requests: write
- contents: write
-
-jobs:
- call-mirror-pr-and-sync:
- if: github.repository_owner != 'vyos'
- uses: VyOS-Networks/vyos-reusable-workflows/.github/workflows/mirror-pr-and-sync.yml@main
- with:
- sync_branch: ${{ inputs.sync_branch }}
- secrets:
- PAT: ${{ secrets.PAT }}
diff --git a/.github/workflows/package-smoketest.yml b/.github/workflows/package-smoketest.yml
index 5ed764217..8bdcc598d 100644
--- a/.github/workflows/package-smoketest.yml
+++ b/.github/workflows/package-smoketest.yml
@@ -49,7 +49,7 @@ jobs:
- name: Generate ISO version string
id: version
run: |
- echo "build_version=1.5-integration-$(date -u +%Y%m%d%H%M)" >> $GITHUB_OUTPUT
+ echo "build_version=$(date -u +%Y.%m.%d-%H%M-integration)" >> $GITHUB_OUTPUT
- name: Build custom ISO image
shell: bash
run: |
diff --git a/.github/workflows/pr-mirror-repo-sync.yml b/.github/workflows/pr-mirror-repo-sync.yml
new file mode 100644
index 000000000..7f0012d18
--- /dev/null
+++ b/.github/workflows/pr-mirror-repo-sync.yml
@@ -0,0 +1,28 @@
+name: PR Mirror and Repo Sync
+on:
+ pull_request_target:
+ types:
+ - closed
+ branches:
+ - current
+ workflow_dispatch:
+ inputs:
+ sync_branch:
+ description: 'branch to sync'
+ required: false
+ type: string
+ default: 'current'
+permissions:
+ pull-requests: write
+ contents: write
+ issues: write
+jobs:
+ call-trigger-mirror-pr-repo-sync:
+ if: github.repository_owner == 'vyos' && github.event.pull_request.merged == true
+ uses: vyos/.github/.github/workflows/pr-mirror-repo-sync.yml@current
+ with:
+ sync_branch: ${{ inputs.sync_branch }}
+ secrets:
+ PAT: ${{ secrets.PAT }}
+ REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }}
+ REMOTE_REPO: ${{ secrets.REMOTE_REPO }}
diff --git a/.github/workflows/trigger-pr-mirror-repo-sync.yml b/.github/workflows/trigger-pr-mirror-repo-sync.yml
deleted file mode 100644
index f74895987..000000000
--- a/.github/workflows/trigger-pr-mirror-repo-sync.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Trigger Mirror PR and Repo Sync
-on:
- pull_request_target:
- types:
- - closed
- branches:
- - current
-
-jobs:
- call-trigger-mirror-pr-repo-sync:
- if: github.repository_owner == 'vyos' && github.event.pull_request.merged == true
- uses: vyos/.github/.github/workflows/trigger-pr-mirror-repo-sync.yml@current
- secrets: inherit
diff --git a/.gitignore b/.gitignore
index 839d2afff..abdc5eb7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -146,15 +146,14 @@ data/component-versions.json
python/vyos/xml_ref/cache.py
python/vyos/xml_ref/pkg_cache/*_cache.py
python/vyos/xml_ref/op_cache.py
+python/vyos/xml_ref/op_cache.json
python/vyos/xml_ref/pkg_cache/*_op_cache.py
data/reftree.cache
# autogenerated vyos-configd JSON definition
data/configd-include.json
# autogenerated vyos-commitd protobuf files
-python/vyos/proto/*pb2.py
python/vyos/proto/*.desc
-python/vyos/proto/vyconf_proto.py
# We do not use pip
Pipfile
diff --git a/Makefile b/Makefile
index 14fefe208..218fc4ae1 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ op_mode_definitions: $(op_xml_obj)
find $(BUILD_DIR)/op-mode-definitions/ -type f -name "*.xml" | xargs -I {} $(CURDIR)/scripts/build-command-op-templates {} $(CURDIR)/schema/op-mode-definition.rng $(OP_TMPL_DIR) || exit 1
- $(CURDIR)/python/vyos/xml_ref/generate_op_cache.py --xml-dir $(BUILD_DIR)/op-mode-definitions || exit 1
+ $(CURDIR)/python/vyos/xml_ref/generate_op_cache.py --check-path-ambiguity --xml-dir $(BUILD_DIR)/op-mode-definitions || exit 1
# XXX: tcpdump, ping, traceroute and mtr must be able to recursivly call themselves as the
# options are provided from the scripts themselves
@@ -89,7 +89,14 @@ vyshim:
$(MAKE) -C $(SHIM_DIR)
.PHONY: all
-all: clean libvyosconfig interface_definitions op_mode_definitions test j2lint vyshim generate-configd-include-json
+all: clean copyright libvyosconfig interface_definitions op_mode_definitions test j2lint vyshim generate-configd-include-json
+
+.PHONY: copyright
+copyright:
+ @if git grep -q -E "Copyright( \(C\))? (19|20)[0-9]{2}(-[0-9]{4})? VyOS maintainers"; then \
+ echo "Error: Legacy copyright notice found."; \
+ exit 1; \
+ fi
.PHONY: clean
clean:
@@ -100,7 +107,7 @@ clean:
.PHONY: test
test: generate-configd-include-json
- set -e; python3 -m compileall -q -x '/vmware-tools/scripts/, /ppp/' .
+ set -e; python3 -m compileall -q -x '/vmware-tools/scripts/' .
PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
.PHONY: check_migration_scripts_executable
diff --git a/data/config-mode-dependencies/vyos-1x.json b/data/config-mode-dependencies/vyos-1x.json
index 7506a0908..ccfc022f4 100644
--- a/data/config-mode-dependencies/vyos-1x.json
+++ b/data/config-mode-dependencies/vyos-1x.json
@@ -34,6 +34,7 @@
"ipsec": ["vpn_ipsec"],
"openconnect": ["vpn_openconnect"],
"rpki": ["protocols_rpki"],
+ "ssh": ["service_ssh"],
"sstp": ["vpn_sstp"],
"sstpc": ["interfaces_sstpc"],
"stunnel": ["service_stunnel"]
@@ -73,6 +74,9 @@
"system_ipv6": {
"sysctl": ["system_sysctl"]
},
+ "system_login": {
+ "ssh": ["service_ssh"]
+ },
"system_option": {
"ip_ipv6": ["system_ip", "system_ipv6"],
"sysctl": ["system_sysctl"]
diff --git a/data/config.boot.default b/data/config.boot.default
index db5d11ea1..02f56da8f 100644
--- a/data/config.boot.default
+++ b/data/config.boot.default
@@ -40,6 +40,9 @@ system {
}
}
}
+ option {
+ reboot-on-upgrade-failure 5
+ }
syslog {
local {
facility all {
diff --git a/data/templates/aws/override_aws_gwlbtun.conf.j2 b/data/templates/aws/override_aws_gwlbtun.conf.j2
index 4c566d852..e7e60dc95 100644
--- a/data/templates/aws/override_aws_gwlbtun.conf.j2
+++ b/data/templates/aws/override_aws_gwlbtun.conf.j2
@@ -30,7 +30,7 @@ After=vyos-router.service
[Service]
EnvironmentFile=
-ExecStart=/usr/bin/gwlbtun {{ args | join(' ') }}
-CapabilityBoundingSet=CAP_NET_ADMIN
+ExecStart=/usr/sbin/gwlbtun {{ args | join(' ') }}
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
Restart=always
RestartSec=10
diff --git a/data/templates/conntrack/sysctl.conf.j2 b/data/templates/conntrack/sysctl.conf.j2
index cd6c34ede..8d934db9c 100644
--- a/data/templates/conntrack/sysctl.conf.j2
+++ b/data/templates/conntrack/sysctl.conf.j2
@@ -1,10 +1,11 @@
# Autogenerated by system_conntrack.py
{# all values have defaults - thus no checking required #}
+net.netfilter.nf_conntrack_buckets = {{ hash_size }}
net.netfilter.nf_conntrack_expect_max = {{ expect_table_size }}
net.netfilter.nf_conntrack_max = {{ table_size }}
net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }}
net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }}
net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }}
net.netfilter.nf_conntrack_acct = {{ '1' if flow_accounting is vyos_defined else '0' }}
-net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }} \ No newline at end of file
+net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }}
diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.j2 b/data/templates/conntrack/vyos_nf_conntrack.conf.j2
deleted file mode 100644
index 1b12fec5f..000000000
--- a/data/templates/conntrack/vyos_nf_conntrack.conf.j2
+++ /dev/null
@@ -1,2 +0,0 @@
-# Autogenerated by system_conntrack.py
-options nf_conntrack hashsize={{ hash_size }}
diff --git a/data/templates/container/containers.conf.j2 b/data/templates/container/containers.conf.j2
index c8b54dfbb..414c3e849 100644
--- a/data/templates/container/containers.conf.j2
+++ b/data/templates/container/containers.conf.j2
@@ -170,10 +170,6 @@ default_sysctls = [
#
#label = true
-# Logging driver for the container. Available options: k8s-file and journald.
-#
-#log_driver = "k8s-file"
-
# Maximum size allowed for the container log file. Negative numbers indicate
# that no size limit is imposed. If positive, it must be >= 8192 to match or
# exceed conmon's read buffer. The file is truncated and re-opened so the
diff --git a/data/templates/dhcp-client/ipv6.override.conf.j2 b/data/templates/dhcp-client/ipv6.override.conf.j2
index b0c0e0544..d270a55fc 100644
--- a/data/templates/dhcp-client/ipv6.override.conf.j2
+++ b/data/templates/dhcp-client/ipv6.override.conf.j2
@@ -4,6 +4,9 @@
[Unit]
ConditionPathExists={{ dhcp6_client_dir }}/dhcp6c.%i.conf
+{% if ifname.startswith('pppoe') %}
+After=ppp@{{ ifname }}.service
+{% endif %}
[Service]
ExecStart=
diff --git a/data/templates/dhcp-server/kea-ctrl-agent.conf.j2 b/data/templates/dhcp-server/kea-ctrl-agent.conf.j2
deleted file mode 100644
index b37cf4798..000000000
--- a/data/templates/dhcp-server/kea-ctrl-agent.conf.j2
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "Control-agent": {
-{% if high_availability is vyos_defined %}
- "http-host": "{{ high_availability.source_address }}",
- "http-port": 647,
- "control-sockets": {
- "dhcp4": {
- "socket-type": "unix",
- "socket-name": "/run/kea/dhcp4-ctrl-socket"
- }
- }
-{% endif %}
- }
-}
diff --git a/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2 b/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2
new file mode 100644
index 000000000..7b0394a88
--- /dev/null
+++ b/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2
@@ -0,0 +1,30 @@
+{
+ "DhcpDdns": {
+ "ip-address": "127.0.0.1",
+ "port": 53001,
+ "control-socket": {
+ "socket-type": "unix",
+ "socket-name": "/run/kea/kea-ddns-ctrl-socket"
+ },
+ "tsig-keys": {{ dynamic_dns_update | kea_dynamic_dns_update_tsig_key_json }},
+ "forward-ddns" : {
+ "ddns-domains": {{ dynamic_dns_update | kea_dynamic_dns_update_domains('forward_domain') }}
+ },
+ "reverse-ddns" : {
+ "ddns-domains": {{ dynamic_dns_update | kea_dynamic_dns_update_domains('reverse_domain') }}
+ },
+ "loggers": [
+ {
+ "name": "kea-dhcp-ddns",
+ "output_options": [
+ {
+ "output": "stdout",
+ "pattern": "%-5p %m\n"
+ }
+ ],
+ "severity": "INFO",
+ "debuglevel": 0
+ }
+ ]
+ }
+}
diff --git a/data/templates/dhcp-server/kea-dhcp4.conf.j2 b/data/templates/dhcp-server/kea-dhcp4.conf.j2
index 2e10d58e0..d08ca0eaa 100644
--- a/data/templates/dhcp-server/kea-dhcp4.conf.j2
+++ b/data/templates/dhcp-server/kea-dhcp4.conf.j2
@@ -25,20 +25,6 @@
},
"option-def": [
{
- "name": "rfc3442-static-route",
- "code": 121,
- "type": "record",
- "array": true,
- "record-types": "uint8,uint8,uint8,uint8,uint8,uint8,uint8"
- },
- {
- "name": "windows-static-route",
- "code": 249,
- "type": "record",
- "array": true,
- "record-types": "uint8,uint8,uint8,uint8,uint8,uint8,uint8"
- },
- {
"name": "wpad-url",
"code": 252,
"type": "string"
@@ -50,6 +36,19 @@
"space": "ubnt"
}
],
+{% if dynamic_dns_update is vyos_defined %}
+ "dhcp-ddns": {
+ "enable-updates": true,
+ "server-ip": "127.0.0.1",
+ "server-port": 53001,
+ "sender-ip": "",
+ "sender-port": 0,
+ "max-queue-size": 1024,
+ "ncr-protocol": "UDP",
+ "ncr-format": "JSON"
+ },
+ {{ dynamic_dns_update | kea_dynamic_dns_update_main_json }}
+{% endif %}
"hooks-libraries": [
{% if high_availability is vyos_defined %}
{
@@ -69,6 +68,16 @@
},
{% endif %}
{
+ "library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_ping_check.so",
+ "parameters": {
+ "enable-ping-check" : false,
+ "min-ping-requests" : 1,
+ "reply-timeout" : 100,
+ "ping-cltt-secs" : 60,
+ "ping-channel-threads" : 0
+ }
+ },
+ {
"library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_lease_cmds.so",
"parameters": {}
}
diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2
index 3147b4c37..c4b6b7eba 100644
--- a/data/templates/firewall/nftables-defines.j2
+++ b/data/templates/firewall/nftables-defines.j2
@@ -44,6 +44,15 @@
}
{% endfor %}
{% endif %}
+{% if group.remote_group is vyos_defined and is_l3 and is_ipv6 %}
+{% for name, name_config in group.remote_group.items() %}
+ set R6_{{ name }} {
+ type {{ ip_type }}
+ flags interval
+ auto-merge
+ }
+{% endfor %}
+{% endif %}
{% if group.mac_group is vyos_defined %}
{% for group_name, group_conf in group.mac_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
@@ -102,7 +111,7 @@
flags interval
auto-merge
{% if group_conf.interface is vyos_defined or includes %}
- elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | join(",") }} }
+ elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | quoted_join(",") }} }
{% endif %}
}
{% endfor %}
diff --git a/data/templates/firewall/nftables-geoip-update.j2 b/data/templates/firewall/nftables-geoip-update.j2
index 832ccc3e9..d8f80d1f5 100644
--- a/data/templates/firewall/nftables-geoip-update.j2
+++ b/data/templates/firewall/nftables-geoip-update.j2
@@ -31,3 +31,36 @@ table ip6 vyos_filter {
{% endfor %}
}
{% endif %}
+
+
+{% if ipv4_sets_policy is vyos_defined %}
+{% for setname, ip_list in ipv4_sets_policy.items() %}
+flush set ip vyos_mangle {{ setname }}
+{% endfor %}
+
+table ip vyos_mangle {
+{% for setname, ip_list in ipv4_sets_policy.items() %}
+ set {{ setname }} {
+ type ipv4_addr
+ flags interval
+ elements = { {{ ','.join(ip_list) }} }
+ }
+{% endfor %}
+}
+{% endif %}
+
+{% if ipv6_sets_policy is vyos_defined %}
+{% for setname, ip_list in ipv6_sets_policy.items() %}
+flush set ip6 vyos_mangle {{ setname }}
+{% endfor %}
+
+table ip6 vyos_mangle {
+{% for setname, ip_list in ipv6_sets_policy.items() %}
+ set {{ setname }} {
+ type ipv6_addr
+ flags interval
+ elements = { {{ ','.join(ip_list) }} }
+ }
+{% endfor %}
+}
+{% endif %}
diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2
index 9e28899b0..00d0e8a62 100644
--- a/data/templates/firewall/nftables-policy.j2
+++ b/data/templates/firewall/nftables-policy.j2
@@ -33,6 +33,15 @@ table ip vyos_mangle {
{% endif %}
}
{% endfor %}
+
+{% if geoip_updated.name is vyos_defined %}
+{% for setname in geoip_updated.name %}
+ set {{ setname }} {
+ type ipv4_addr
+ flags interval
+ }
+{% endfor %}
+{% endif %}
{% endif %}
{{ group_tmpl.groups(firewall_group, False, True) }}
@@ -65,6 +74,14 @@ table ip6 vyos_mangle {
{% endif %}
}
{% endfor %}
+{% if geoip_updated.ipv6_name is vyos_defined %}
+{% for setname in geoip_updated.ipv6_name %}
+ set {{ setname }} {
+ type ipv6_addr
+ flags interval
+ }
+{% endfor %}
+{% endif %}
{% endif %}
{{ group_tmpl.groups(firewall_group, True, True) }}
diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2
index 645a38706..66f7e0b1c 100644
--- a/data/templates/firewall/nftables-zone.j2
+++ b/data/templates/firewall/nftables-zone.j2
@@ -9,11 +9,11 @@
{% for zone_name, zone_conf in zone.items() %}
{% if 'local_zone' not in zone_conf %}
{% if 'interface' in zone_conf.member %}
- oifname { {{ zone_conf.member.interface | join(',') }} } counter jump VZONE_{{ zone_name }}
+ oifname { {{ zone_conf.member.interface | quoted_join(',') }} } counter jump VZONE_{{ zone_name }}
{% endif %}
{% if 'vrf' in zone_conf.member %}
{% for vrf_name in zone_conf.member.vrf %}
- oifname { {{ zone_conf['vrf_interfaces'][vrf_name] }} } counter jump VZONE_{{ zone_name }}
+ oifname { "{{ zone_conf['vrf_interfaces'][vrf_name] }}" } counter jump VZONE_{{ zone_name }}
{% endfor %}
{% endif %}
{% endif %}
@@ -49,12 +49,12 @@
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %}
{% if 'interface' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
{% endif %}
{% if 'vrf' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
+ iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
{% endif %}
{% endfor %}
{% endif %}
@@ -65,13 +65,13 @@
{% if zone_conf.from_local is vyos_defined %}
{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall[fw_name] is vyos_defined %}
{% if 'interface' in zone[from_zone].member %}
- oifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- oifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
{% endif %}
{% if 'vrf' in zone[from_zone].member %}
{% for vrf_name in zone[from_zone].member.vrf %}
- oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] }} } counter return
+ oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter return
{% endfor %}
{% endif %}
{% endfor %}
@@ -81,29 +81,29 @@
{% else %}
chain VZONE_{{ zone_name }} {
{% if 'interface' in zone_conf.member %}
- iifname { {{ zone_conf.member.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
+ iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
{% endif %}
{% if 'vrf' in zone_conf.member %}
- iifname { {{ zone_conf.member.vrf | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
+ iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
{% endif %}
{% if zone_conf.intra_zone_filtering is vyos_defined %}
{% if 'interface' in zone_conf.member %}
- iifname { {{ zone_conf.member.interface | join(",") }} } counter return
+ iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter return
{% endif %}
{% if 'vrf' in zone_conf.member %}
- iifname { {{ zone_conf.member.vrf | join(",") }} } counter return
+ iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter return
{% endif %}
{% endif %}
{% if zone_conf.from is vyos_defined %}
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %}
{% if zone[from_zone].local_zone is not defined %}
{% if 'interface' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
{% endif %}
{% if 'vrf' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
+ iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
+ iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
{% endif %}
{% endif %}
{% endfor %}
diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2
index 67473da8e..39ef72059 100755
--- a/data/templates/firewall/nftables.j2
+++ b/data/templates/firewall/nftables.j2
@@ -47,7 +47,7 @@ table ip vyos_filter {
chain VYOS_FORWARD_{{ prior }} {
type filter hook forward priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
- jump VYOS_STATE_POLICY
+ jump VYOS_STATE_POLICY_FORWARD
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
@@ -180,6 +180,22 @@ table ip vyos_filter {
{% endif %}
return
}
+
+ chain VYOS_STATE_POLICY_FORWARD {
+{% if global_options.state_policy.offload is vyos_defined %}
+ counter flow add @VYOS_FLOWTABLE_{{ global_options.state_policy.offload.offload_target }}
+{% endif %}
+{% if global_options.state_policy.established is vyos_defined %}
+ {{ global_options.state_policy.established | nft_state_policy('established') }}
+{% endif %}
+{% if global_options.state_policy.invalid is vyos_defined %}
+ {{ global_options.state_policy.invalid | nft_state_policy('invalid') }}
+{% endif %}
+{% if global_options.state_policy.related is vyos_defined %}
+ {{ global_options.state_policy.related | nft_state_policy('related') }}
+{% endif %}
+ return
+ }
{% endif %}
}
@@ -200,7 +216,7 @@ table ip6 vyos_filter {
chain VYOS_IPV6_FORWARD_{{ prior }} {
type filter hook forward priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
- jump VYOS_STATE_POLICY6
+ jump VYOS_STATE_POLICY6_FORWARD
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
@@ -331,6 +347,22 @@ table ip6 vyos_filter {
{% endif %}
return
}
+
+ chain VYOS_STATE_POLICY6_FORWARD {
+{% if global_options.state_policy.offload is vyos_defined %}
+ counter flow add @VYOS_FLOWTABLE_{{ global_options.state_policy.offload.offload_target }}
+{% endif %}
+{% if global_options.state_policy.established is vyos_defined %}
+ {{ global_options.state_policy.established | nft_state_policy('established') }}
+{% endif %}
+{% if global_options.state_policy.invalid is vyos_defined %}
+ {{ global_options.state_policy.invalid | nft_state_policy('invalid') }}
+{% endif %}
+{% if global_options.state_policy.related is vyos_defined %}
+ {{ global_options.state_policy.related | nft_state_policy('related') }}
+{% endif %}
+ return
+ }
{% endif %}
}
@@ -378,11 +410,11 @@ table bridge vyos_filter {
{% for prior, conf in bridge.output.items() %}
chain VYOS_OUTPUT_{{ prior }} {
type filter hook output priority {{ prior }}; policy accept;
-{% if global_options.apply_to_bridged_traffic is vyos_defined %}
-{% if 'invalid_connections' in global_options.apply_to_bridged_traffic %}
- ct state invalid udp sport 67 udp dport 68 counter accept
- ct state invalid ether type arp counter accept
- ct state invalid ether type 0x8864 counter accept
+{% if global_options.apply_to_bridged_traffic.accept_invalid is vyos_defined %}
+{% if 'ethernet_type' in global_options.apply_to_bridged_traffic.accept_invalid %}
+{% for ether_type in global_options.apply_to_bridged_traffic.accept_invalid.ethernet_type %}
+ {{ ether_type | nft_accept_invalid() }}
+{% endfor %}
{% endif %}
{% endif %}
{% if global_options.state_policy is vyos_defined %}
diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2
index b89f15be1..e5a75090f 100644
--- a/data/templates/frr/bgpd.frr.j2
+++ b/data/templates/frr/bgpd.frr.j2
@@ -98,6 +98,8 @@
{% endif %}
{% if config.enforce_first_as is vyos_defined %}
neighbor {{ neighbor }} enforce-first-as
+{% else %}
+ no neighbor {{ neighbor }} enforce-first-as
{% endif %}
{% if config.strict_capability_match is vyos_defined %}
neighbor {{ neighbor }} strict-capability-match
@@ -636,6 +638,9 @@ bgp route-reflector allow-outbound-policy
{% if parameters.no_fast_external_failover is vyos_defined %}
no bgp fast-external-failover
{% endif %}
+{% if parameters.no_ipv6_auto_ra is vyos_defined %}
+ no bgp ipv6-auto-ra
+{% endif %}
{% if parameters.no_suppress_duplicates is vyos_defined %}
no bgp suppress-duplicates
{% endif %}
diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl
index 835dc382b..afd888122 100644
--- a/data/templates/frr/daemons.frr.tmpl
+++ b/data/templates/frr/daemons.frr.tmpl
@@ -4,7 +4,6 @@
# Note: The following FRR-services must be kept disabled because they are replaced by other packages in VyOS:
#
# pimd Replaced by package igmpproxy.
-# nhrpd Replaced by package opennhrp.
# pbrd Replaced by PBR in nftables.
# vrrpd Replaced by package keepalived.
#
diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2
index bc2c74b10..79824fb64 100644
--- a/data/templates/frr/ospfd.frr.j2
+++ b/data/templates/frr/ospfd.frr.j2
@@ -82,7 +82,7 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
{% for area_id, area_config in area.items() %}
{% if area_config.area_type is vyos_defined %}
{% for type, type_config in area_config.area_type.items() if type != 'normal' %}
- area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
+ area {{ area_id }} {{ type }} {{ 'translate-' + type_config.translate if type_config.translate is vyos_defined }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
{% if type_config.default_cost is vyos_defined %}
area {{ area_id }} default-cost {{ type_config.default_cost }}
{% endif %}
diff --git a/data/templates/frr/rpki.frr.j2 b/data/templates/frr/rpki.frr.j2
index edf0ccaa2..e35f99766 100644
--- a/data/templates/frr/rpki.frr.j2
+++ b/data/templates/frr/rpki.frr.j2
@@ -1,8 +1,8 @@
-!
+{% macro rpki_config(rpki) %}
{# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #}
rpki
-{% if cache is vyos_defined %}
-{% for peer, peer_config in cache.items() %}
+{% if rpki.cache is vyos_defined %}
+{% for peer, peer_config in rpki.cache.items() %}
{# port is mandatory and preference uses a default value #}
{% if peer_config.ssh.username is vyos_defined %}
rpki cache ssh {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }}{{ ' source ' ~ peer_config.source_address if peer_config.source_address is vyos_defined }} preference {{ peer_config.preference }}
@@ -11,14 +11,24 @@ rpki
{% endif %}
{% endfor %}
{% endif %}
-{% if expire_interval is vyos_defined %}
- rpki expire_interval {{ expire_interval }}
+{% if rpki.expire_interval is vyos_defined %}
+ rpki expire_interval {{ rpki.expire_interval }}
{% endif %}
-{% if polling_period is vyos_defined %}
- rpki polling_period {{ polling_period }}
+{% if rpki.polling_period is vyos_defined %}
+ rpki polling_period {{ rpki.polling_period }}
{% endif %}
-{% if retry_interval is vyos_defined %}
- rpki retry_interval {{ retry_interval }}
+{% if rpki.retry_interval is vyos_defined %}
+ rpki retry_interval {{ rpki.retry_interval }}
{% endif %}
exit
+{# j2lint: disable=jinja-statements-delimeter #}
+{%- endmacro -%}
+!
+{% if rpki.vrf is vyos_defined %}
+vrf {{ rpki.vrf }}
+ {{ rpki_config(rpki) | indent(width=1) }}
+exit-vrf
+{% else %}
+{{ rpki_config(rpki) }}
+{% endif %}
!
diff --git a/data/templates/frr/zebra.route-map.frr.j2 b/data/templates/frr/zebra.route-map.frr.j2
index 70a810f43..0d6d01930 100644
--- a/data/templates/frr/zebra.route-map.frr.j2
+++ b/data/templates/frr/zebra.route-map.frr.j2
@@ -1,6 +1,12 @@
!
{{ 'no ' if disable_forwarding is vyos_defined }}{{ afi }} forwarding
!
+{% if import_table is vyos_defined %}
+{% for table_num, table_config in import_table.items() %}
+ip import-table {{ table_num }} {{ 'distance ' ~ table_config.distance if table_config.distance is vyos_defined }} {{ 'route-map ' ~ table_config.route_map if table_config.route_map is vyos_defined }}
+{% endfor %}
+{% endif %}
+!
{% if nht.no_resolve_via_default is vyos_defined %}
no {{ afi }} nht resolve-via-default
{% endif %}
diff --git a/data/templates/https/nginx.default.j2 b/data/templates/https/nginx.default.j2
index 692ccbff7..47280c9f0 100644
--- a/data/templates/https/nginx.default.j2
+++ b/data/templates/https/nginx.default.j2
@@ -48,7 +48,7 @@ server {
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
# proxy settings for HTTP API, if enabled; 503, if not
- location ~ ^/(retrieve|configure|config-file|image|import-pki|container-image|generate|show|reboot|reset|poweroff|traceroute|info|docs|openapi.json|redoc|graphql) {
+ location ~ ^/(retrieve|configure|config-file|image|import-pki|container-image|generate|show|reboot|reset|poweroff|traceroute|info|docs|openapi.json|redoc|graphql|renew) {
{% if api is vyos_defined %}
proxy_pass http://unix:/run/api.sock;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
diff --git a/data/templates/ids/fastnetmon.j2 b/data/templates/ids/fastnetmon.j2
deleted file mode 100644
index f6f03d0db..000000000
--- a/data/templates/ids/fastnetmon.j2
+++ /dev/null
@@ -1,121 +0,0 @@
-# enable this option if you want to send logs to local syslog facility
-logging:logging_level = debug
-logging:local_syslog_logging = on
-
-# list of all your networks in CIDR format
-networks_list_path = /run/fastnetmon/networks_list
-
-# list networks in CIDR format which will be not monitored for attacks
-white_list_path = /run/fastnetmon/excluded_networks_list
-
-# Enable/Disable any actions in case of attack
-enable_ban = on
-enable_ban_ipv6 = on
-
-## How many packets will be collected from attack traffic
-ban_details_records_count = 500
-
-## How long (in seconds) we should keep an IP in blocked state
-## If you set 0 here it completely disables unban capability
-{% if ban_time is vyos_defined %}
-ban_time = {{ ban_time }}
-{% endif %}
-
-# Check if the attack is still active, before triggering an unban callback with this option
-# If the attack is still active, check each run of the unban watchdog
-unban_only_if_attack_finished = on
-
-# enable per subnet speed meters
-# For each subnet, list track speed in bps and pps for both directions
-enable_subnet_counters = off
-
-{% if mode is vyos_defined('mirror') %}
-mirror_afpacket = on
-{% elif mode is vyos_defined('sflow') %}
-sflow = on
-{% if sflow.port is vyos_defined %}
-sflow_port = {{ sflow.port }}
-{% endif %}
-{% if sflow.listen_address is vyos_defined %}
-sflow_host = {{ sflow.listen_address }}
-{% endif %}
-{% endif %}
-
-
-process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in direction else 'off' }}
-process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }}
-
-{% if threshold is vyos_defined %}
-{% if threshold.general is vyos_defined %}
-# General threshold
-{% for thr, thr_value in threshold.general.items() %}
-{% if thr is vyos_defined('fps') %}
-ban_for_flows = on
-threshold_flows = {{ thr_value }}
-{% elif thr is vyos_defined('mbps') %}
-ban_for_bandwidth = on
-threshold_mbps = {{ thr_value }}
-{% elif thr is vyos_defined('pps') %}
-ban_for_pps = on
-threshold_pps = {{ thr_value }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if threshold.tcp is vyos_defined %}
-# TCP threshold
-{% for thr, thr_value in threshold.tcp.items() %}
-{% if thr is vyos_defined('fps') %}
-ban_for_tcp_flows = on
-threshold_tcp_flows = {{ thr_value }}
-{% elif thr is vyos_defined('mbps') %}
-ban_for_tcp_bandwidth = on
-threshold_tcp_mbps = {{ thr_value }}
-{% elif thr is vyos_defined('pps') %}
-ban_for_tcp_pps = on
-threshold_tcp_pps = {{ thr_value }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if threshold.udp is vyos_defined %}
-# UDP threshold
-{% for thr, thr_value in threshold.udp.items() %}
-{% if thr is vyos_defined('fps') %}
-ban_for_udp_flows = on
-threshold_udp_flows = {{ thr_value }}
-{% elif thr is vyos_defined('mbps') %}
-ban_for_udp_bandwidth = on
-threshold_udp_mbps = {{ thr_value }}
-{% elif thr is vyos_defined('pps') %}
-ban_for_udp_pps = on
-threshold_udp_pps = {{ thr_value }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if threshold.icmp is vyos_defined %}
-# ICMP threshold
-{% for thr, thr_value in threshold.icmp.items() %}
-{% if thr is vyos_defined('fps') %}
-ban_for_icmp_flows = on
-threshold_icmp_flows = {{ thr_value }}
-{% elif thr is vyos_defined('mbps') %}
-ban_for_icmp_bandwidth = on
-threshold_icmp_mbps = {{ thr_value }}
-{% elif thr is vyos_defined('pps') %}
-ban_for_icmp_pps = on
-threshold_icmp_pps = {{ thr_value }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% endif %}
-
-{% if listen_interface is vyos_defined %}
-interfaces = {{ listen_interface | join(',') }}
-{% endif %}
-
-{% if alert_script is vyos_defined %}
-notify_script_path = {{ alert_script }}
-{% endif %}
diff --git a/data/templates/ids/fastnetmon_excluded_networks_list.j2 b/data/templates/ids/fastnetmon_excluded_networks_list.j2
deleted file mode 100644
index c88a1c527..000000000
--- a/data/templates/ids/fastnetmon_excluded_networks_list.j2
+++ /dev/null
@@ -1,5 +0,0 @@
-{% if excluded_network is vyos_defined %}
-{% for net in excluded_network %}
-{{ net }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/ids/fastnetmon_networks_list.j2 b/data/templates/ids/fastnetmon_networks_list.j2
deleted file mode 100644
index 0a0576d2a..000000000
--- a/data/templates/ids/fastnetmon_networks_list.j2
+++ /dev/null
@@ -1,5 +0,0 @@
-{% if network is vyos_defined %}
-{% for net in network %}
-{{ net }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2
index 3a9af2c94..cf0865c88 100644
--- a/data/templates/ipsec/swanctl/peer.j2
+++ b/data/templates/ipsec/swanctl/peer.j2
@@ -68,8 +68,19 @@
rekey_packets = 0
rekey_time = 0s
{% endif %}
- local_ts = 0.0.0.0/0,::/0
- remote_ts = 0.0.0.0/0,::/0
+{# set default traffic-selectors #}
+{% set local_ts = '0.0.0.0/0,::/0' %}
+{% set remote_ts = '0.0.0.0/0,::/0' %}
+{% if peer_conf.vti.traffic_selector is vyos_defined %}
+{% if peer_conf.vti.traffic_selector.local is vyos_defined and peer_conf.vti.traffic_selector.local.prefix is vyos_defined %}
+{% set local_ts = peer_conf.vti.traffic_selector.local.prefix | join(',') %}
+{% endif %}
+{% if peer_conf.vti.traffic_selector.remote is vyos_defined and peer_conf.vti.traffic_selector.remote.prefix is vyos_defined %}
+{% set remote_ts = peer_conf.vti.traffic_selector.remote.prefix | join(',') %}
+{% endif %}
+{% endif %}
+ local_ts = {{ local_ts }}
+ remote_ts = {{ remote_ts }}
updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}"
{# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #}
{# Thus we simply shift the key by one to also support a vti0 interface #}
diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2
index 70ea5d2b0..62934c612 100644
--- a/data/templates/load-balancing/haproxy.cfg.j2
+++ b/data/templates/load-balancing/haproxy.cfg.j2
@@ -50,9 +50,29 @@ defaults
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
+# Default ACME backend
+backend buildin_acme_certbot
+ server localhost 127.0.0.1:{{ get_default_port('certbot_haproxy') }}
+
# Frontend
{% if service is vyos_defined %}
{% for front, front_config in service.items() %}
+{% if front_config.redirect_http_to_https is vyos_defined %}
+{% set certbot_backend_name = 'certbot_' ~ front ~ '_backend' %}
+frontend {{ front }}-http
+ mode http
+{% if front_config.listen_address is vyos_defined %}
+{% for address in front_config.listen_address %}
+ bind {{ address | bracketize_ipv6 }}:80
+{% endfor %}
+{% else %}
+ bind [::]:80 v4v6
+{% endif %}
+ acl acme_acl path_beg /.well-known/acme-challenge/
+ use_backend buildin_acme_certbot if acme_acl
+ redirect scheme https code 301 if !acme_acl
+{% endif %}
+
frontend {{ front }}
{% set ssl_front = [] %}
{% if front_config.ssl.certificate is vyos_defined and front_config.ssl.certificate is iterable %}
@@ -68,9 +88,6 @@ frontend {{ front }}
{% else %}
bind [::]:{{ front_config.port }} v4v6 {{ ssl_directive }} {{ ssl_front | join(' ') }}
{% endif %}
-{% if front_config.redirect_http_to_https is vyos_defined %}
- http-request redirect scheme https unless { ssl_fc }
-{% endif %}
{% if front_config.logging is vyos_defined %}
{% for facility, facility_config in front_config.logging.facility.items() %}
log /dev/log {{ facility }} {{ facility_config.level }}
@@ -237,6 +254,5 @@ backend {{ back }}
{% if back_config.timeout.server is vyos_defined %}
timeout server {{ back_config.timeout.server }}s
{% endif %}
-
{% endfor %}
{% endif %}
diff --git a/data/templates/load-balancing/nftables-wlb.j2 b/data/templates/load-balancing/nftables-wlb.j2
index b3d7c3376..8afd0c162 100644
--- a/data/templates/load-balancing/nftables-wlb.j2
+++ b/data/templates/load-balancing/nftables-wlb.j2
@@ -9,7 +9,7 @@ table ip vyos_wanloadbalance {
{% for ifname, health_conf in interface_health.items() if health_state[ifname].if_addr %}
{% if disable_source_nat is not vyos_defined %}
{% set state = health_state[ifname] %}
- ct mark {{ state.mark }} counter snat to {{ state.if_addr }}
+ ct mark {{ state.mark }} oifname {{ ifname }} counter snat to {{ state.if_addr }}
{% endif %}
{% endfor %}
}
diff --git a/data/templates/login/authorized_keys.j2 b/data/templates/login/authorized_keys.j2
index 695b66abe..5b15f066a 100644
--- a/data/templates/login/authorized_keys.j2
+++ b/data/templates/login/authorized_keys.j2
@@ -1,5 +1,4 @@
### Automatically generated by system_login.py ###
-
{% if authentication.public_keys is vyos_defined %}
{% for key, key_options in authentication.public_keys.items() %}
{# The whitespace after options is wisely chosen #}
diff --git a/data/templates/login/authorized_principals.j2 b/data/templates/login/authorized_principals.j2
new file mode 100644
index 000000000..16525e808
--- /dev/null
+++ b/data/templates/login/authorized_principals.j2
@@ -0,0 +1,4 @@
+### Automatically generated by system_login.py ###
+{% if authentication.principal is vyos_defined %}
+{{ '\n'.join(authentication.principal) }}
+{% endif %}
diff --git a/data/templates/prometheus/node_exporter.service.j2 b/data/templates/prometheus/node_exporter.service.j2
index 135439bd6..9a943cd75 100644
--- a/data/templates/prometheus/node_exporter.service.j2
+++ b/data/templates/prometheus/node_exporter.service.j2
@@ -9,6 +9,11 @@ After=network.target
User=node_exporter
{% endif %}
ExecStart={{ vrf_command }}/usr/sbin/node_exporter \
+{% if collectors is vyos_defined %}
+{% if collectors.textfile is vyos_defined %}
+ --collector.textfile.directory=/run/node_exporter/collector \
+{% endif %}
+{% endif %}
{% if listen_address is vyos_defined %}
{% for address in listen_address %}
--web.listen-address={{ address }}:{{ port }}
@@ -16,10 +21,6 @@ ExecStart={{ vrf_command }}/usr/sbin/node_exporter \
{% else %}
--web.listen-address=:{{ port }}
{% endif %}
-{% if collectors is vyos_defined %}
-{% if collectors.textfile is vyos_defined %}
- --collector.textfile.directory=/run/node_exporter/collector
-{% endif %}
-{% endif %}
+
[Install]
WantedBy=multi-user.target
diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2
index a83bd03ac..34f8e1f6d 100644
--- a/data/templates/router-advert/radvd.conf.j2
+++ b/data/templates/router-advert/radvd.conf.j2
@@ -57,6 +57,21 @@ interface {{ iface }} {
};
{% endfor %}
{% endif %}
+{% if iface_config.prefix is vyos_defined and "::/64" in iface_config.prefix %}
+{% if iface_config.auto_ignore is vyos_defined or iface_config.prefix | count > 1 %}
+ autoignoreprefixes {
+{% if iface_config.auto_ignore is vyos_defined %}
+{% for auto_ignore_prefix in (iface_config.auto_ignore + iface_config.prefix | list) | reject("eq", "::/64") | unique %}
+ {{ auto_ignore_prefix }};
+{% endfor %}
+{% else %}
+{% for auto_ignore_prefix in iface_config.prefix | reject("eq", "::/64") %}
+ {{ auto_ignore_prefix }};
+{% endfor %}
+{% endif %}
+ };
+{% endif %}
+{% endif %}
{% if iface_config.prefix is vyos_defined %}
{% for prefix, prefix_options in iface_config.prefix.items() %}
prefix {{ prefix }} {
diff --git a/data/templates/ssh/sshd_config.j2 b/data/templates/ssh/sshd_config.j2
index 7e44efae8..1315bf2cb 100644
--- a/data/templates/ssh/sshd_config.j2
+++ b/data/templates/ssh/sshd_config.j2
@@ -111,6 +111,18 @@ ClientAliveInterval {{ client_keepalive_interval }}
RekeyLimit {{ rekey.data }}M {{ rekey.time + 'M' if rekey.time is vyos_defined }}
{% endif %}
-{% if trusted_user_ca_key is vyos_defined %}
-TrustedUserCAKeys /etc/ssh/trusted_user_ca_key
+{% if trusted_user_ca is vyos_defined %}
+# Specifies a file containing public keys of certificate authorities that are
+# trusted to sign user certificates for authentication
+TrustedUserCAKeys {{ get_default_config_file('sshd_user_ca') }}
+
+# The default is "none", i.e. not to use a principals file - in this case, the
+# username of the user must appear in a certificate's principals list for it
+# to be accepted. ".ssh/authorized_principals" means a per-user configuration,
+# relative to $HOME.
+{% set filename = 'none' %}
+{% if has_principals is vyos_defined %}
+{% set filename = '.ssh/authorized_principals' %}
+{% endif %}
+AuthorizedPrincipalsFile {{ filename }}
{% endif %}
diff --git a/debian/control b/debian/control
index c40b0fb04..e58822e9f 100644
--- a/debian/control
+++ b/debian/control
@@ -120,7 +120,7 @@ Depends:
dosfstools,
grub-efi-amd64-signed [amd64],
grub-efi-arm64-bin [arm64],
- mokutil [amd64],
+ mokutil,
shim-signed [amd64],
sbsigntool [amd64],
# Image signature verification tool
@@ -196,7 +196,6 @@ Depends:
ddclient (>= 3.11.1),
# End "service dns dynamic"
# # For "service ids"
- fastnetmon [amd64],
suricata,
suricata-update,
# End "service ids"
@@ -204,7 +203,7 @@ Depends:
ndppd,
# End "service ndp-proxy"
# For "service router-advert"
- radvd,
+ radvd (>= 2.20),
# End "service route-advert"
# For "load-balancing haproxy"
haproxy,
@@ -386,7 +385,7 @@ Description: VyOS configuration scripts and data
VyOS configuration scripts, interface definitions, and everything
Package: vyos-1x-vmware
-Architecture: amd64
+Architecture: all
Depends:
vyos-1x,
open-vm-tools
diff --git a/debian/copyright b/debian/copyright
index 20704c47c..b3b55b1d1 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -3,13 +3,13 @@ Thu, 17 Aug 2017 20:17:04 -0400
It's original content from the GIT repository <http://github.com/vyos/vyos-1x>
-Upstream Author:
+Upstream Author:
<maintainers@vyos.net>
-Copyright:
+Copyright:
- Copyright (C) 2017 VyOS maintainers and contributors
+ Copyright VyOS maintainers and contributors <maintainers@vyos.io>
All Rights Reserved.
License:
diff --git a/debian/vyos-1x.install b/debian/vyos-1x.install
index 4e312a648..0fd5e3395 100644
--- a/debian/vyos-1x.install
+++ b/debian/vyos-1x.install
@@ -6,7 +6,6 @@ etc/dhcp
etc/ipsec.d
etc/logrotate.d
etc/netplug
-etc/opennhrp
etc/modprobe.d
etc/ppp
etc/securetty
diff --git a/debian/vyos-1x.links b/debian/vyos-1x.links
index 7e21f294c..aef22555c 100644
--- a/debian/vyos-1x.links
+++ b/debian/vyos-1x.links
@@ -1,3 +1,4 @@
/etc/netplug/linkup.d/vyos-python-helper /etc/netplug/linkdown.d/vyos-python-helper
/usr/libexec/vyos/system/standalone_root_pw_reset /opt/vyatta/sbin/standalone_root_pw_reset
-/lib/systemd/system/rsyslog.service /etc/systemd/system/syslog.service
+/usr/libexec/vyos/vyconf_cli.py /usr/libexec/vyos/vyconf/bin/vy_commit
+/usr/libexec/vyos/vyconf_cli.py /usr/libexec/vyos/vyconf/bin/vy_in_session
diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst
index fde58651a..9dd06d5e2 100644
--- a/debian/vyos-1x.postinst
+++ b/debian/vyos-1x.postinst
@@ -50,6 +50,10 @@ if [[ -e /usr/share/pam-configs/tacplus ]]; then
rm /usr/share/pam-configs/tacplus
fi
+# Disable pam_nologin.so behavior for regular users
+sed -i '/^auth[[:space:]]\+requisite[[:space:]]\+pam_nologin\.so$/s/^/#/' /etc/pam.d/login
+sed -i '/^account[[:space:]]\+required[[:space:]]\+pam_nologin\.so$/s/^/#/' /etc/pam.d/sshd
+
# Add TACACS system users required for TACACS based system authentication
if ! grep -q '^tacacs' /etc/passwd; then
# Add the tacacs group and all 16 possible tacacs privilege-level users to
@@ -221,11 +225,9 @@ fi
# Remove unwanted daemon files from /etc
# conntackd
# pmacct
-# fastnetmon
# ntp
DELETE="/etc/logrotate.d/conntrackd.distrib /etc/init.d/conntrackd /etc/default/conntrackd
/etc/default/pmacctd /etc/pmacct
- /etc/networks_list /etc/networks_whitelist /etc/fastnetmon.conf
/etc/ntp.conf /etc/default/ssh /etc/avahi/avahi-daemon.conf /etc/avahi/hosts
/etc/powerdns /etc/default/pdns-recursor
/etc/ppp/ip-up.d/0000usepeerdns /etc/ppp/ip-down.d/0000usepeerdns"
diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in
index 3a5cfbaa6..f20fd7690 100644
--- a/interface-definitions/container.xml.in
+++ b/interface-definitions/container.xml.in
@@ -75,6 +75,12 @@
<multi/>
</properties>
</leafNode>
+ <leafNode name="privileged">
+ <properties>
+ <help>Grant root capabilities to the container</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<node name="sysctl">
<properties>
<help>Configure namespaced kernel parameters of the container</help>
@@ -526,6 +532,30 @@
</leafNode>
</children>
</tagNode>
+ <leafNode name="log-driver">
+ <properties>
+ <help>Configure container log driver</help>
+ <completionHelp>
+ <list>k8s-file journald none</list>
+ </completionHelp>
+ <valueHelp>
+ <format>k8s-file</format>
+ <description>Logs to plain-text file</description>
+ </valueHelp>
+ <valueHelp>
+ <format>journald</format>
+ <description>Logs to systemd's journal</description>
+ </valueHelp>
+ <valueHelp>
+ <format>none</format>
+ <description>Disable logging for the container</description>
+ </valueHelp>
+ <constraint>
+ <regex>(k8s-file|journald|none)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>journald</defaultValue>
+ </leafNode>
</children>
</tagNode>
<tagNode name="network">
diff --git a/interface-definitions/include/accel-ppp/radius-additions.xml.i b/interface-definitions/include/accel-ppp/radius-additions.xml.i
index 5222ba864..b6c88c6e8 100644
--- a/interface-definitions/include/accel-ppp/radius-additions.xml.i
+++ b/interface-definitions/include/accel-ppp/radius-additions.xml.i
@@ -133,17 +133,8 @@
</valueHelp>
</properties>
</leafNode>
+ #include <include/port-number.xml.i>
<leafNode name="port">
- <properties>
- <help>Port for Dynamic Authorization Extension server (DM/CoA)</help>
- <valueHelp>
- <format>u32:1-65535</format>
- <description>TCP port</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-65535"/>
- </constraint>
- </properties>
<defaultValue>1700</defaultValue>
</leafNode>
<leafNode name="key">
diff --git a/interface-definitions/include/accel-ppp/thread-count.xml.i b/interface-definitions/include/accel-ppp/thread-count.xml.i
new file mode 100644
index 000000000..84d9224d0
--- /dev/null
+++ b/interface-definitions/include/accel-ppp/thread-count.xml.i
@@ -0,0 +1,27 @@
+<!-- include start from accel-ppp/thread-count.xml.i -->
+<leafNode name="thread-count">
+ <properties>
+ <help>Number of working threads</help>
+ <completionHelp>
+ <list>all half</list>
+ </completionHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>Use all available CPU cores</description>
+ </valueHelp>
+ <valueHelp>
+ <format>half</format>
+ <description>Use half of available CPU cores</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-512</format>
+ <description>Thread count</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-512"/>
+ <regex>(all|half)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>all</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i
index 31c8cafea..ab016884e 100644
--- a/interface-definitions/include/bgp/protocol-common-config.xml.i
+++ b/interface-definitions/include/bgp/protocol-common-config.xml.i
@@ -1596,6 +1596,12 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="no-ipv6-auto-ra">
+ <properties>
+ <help>Disable IPv6 automatic router advertisement</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<leafNode name="no-suppress-duplicates">
<properties>
<help>Disable suppress duplicate updates if the route actually not changed</help>
diff --git a/interface-definitions/include/dhcp/ddns-dns-server.xml.i b/interface-definitions/include/dhcp/ddns-dns-server.xml.i
new file mode 100644
index 000000000..ba9f186d0
--- /dev/null
+++ b/interface-definitions/include/dhcp/ddns-dns-server.xml.i
@@ -0,0 +1,19 @@
+<!-- include start from dhcp/ddns-dns-server.xml.i -->
+<tagNode name="dns-server">
+ <properties>
+ <help>DNS server specification</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number for this DNS server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>DNS server number must be between 1 and 999999</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/address-ipv4-ipv6-single.xml.i>
+ #include <include/port-number.xml.i>
+ </children>
+</tagNode>
+<!-- include end -->
diff --git a/interface-definitions/include/dhcp/ddns-settings.xml.i b/interface-definitions/include/dhcp/ddns-settings.xml.i
new file mode 100644
index 000000000..3e202685e
--- /dev/null
+++ b/interface-definitions/include/dhcp/ddns-settings.xml.i
@@ -0,0 +1,172 @@
+<!-- include start from dhcp/ddns-settings.xml.i -->
+<leafNode name="send-updates">
+ <properties>
+ <help>Enable or disable updates for this scope</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable updates for this scope</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable updates for this scope</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ <constraintErrorMessage>Set it to either enable or disable</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="override-client-update">
+ <properties>
+ <help>Always update both forward and reverse DNS data, regardless of the client's request</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Force update both forward and reverse DNS records</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Respect client request settings</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ <constraintErrorMessage>Set it to either enable or disable</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="override-no-update">
+ <properties>
+ <help>Perform a DDNS update, even if the client instructs the server not to</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Force DDNS updates regardless of client request</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Respect client request settings</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ <constraintErrorMessage>Set it to either enable or disable</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="replace-client-name">
+ <properties>
+ <help>Replace client name mode</help>
+ <completionHelp>
+ <list>never always when-present when-not-present</list>
+ </completionHelp>
+ <valueHelp>
+ <format>never</format>
+ <description>Use the name the client sent. If the client sent no name, do not generate
+ one</description>
+ </valueHelp>
+ <valueHelp>
+ <format>always</format>
+ <description>Replace the name the client sent. If the client sent no name, generate one
+ for the client</description>
+ </valueHelp>
+ <valueHelp>
+ <format>when-present</format>
+ <description>Replace the name the client sent. If the client sent no name, do not
+ generate one</description>
+ </valueHelp>
+ <valueHelp>
+ <format>when-not-present</format>
+ <description>Use the name the client sent. If the client sent no name, generate one for
+ the client</description>
+ </valueHelp>
+ <constraint>
+ <regex>(never|always|when-present|when-not-present)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid replace client name mode</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="generated-prefix">
+ <properties>
+ <help>The prefix used in the generation of an FQDN</help>
+ <constraint>
+ <validator name="fqdn" />
+ </constraint>
+ <constraintErrorMessage>Invalid generated prefix</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="qualifying-suffix">
+ <properties>
+ <help>The suffix used when generating an FQDN, or when qualifying a partial name</help>
+ <constraint>
+ <validator name="fqdn" />
+ </constraint>
+ <constraintErrorMessage>Invalid qualifying suffix</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="update-on-renew">
+ <properties>
+ <help>Update DNS record on lease renew</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Update DNS record on lease renew</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Do not update DNS record on lease renew</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ <constraintErrorMessage>Set it to either enable or disable</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="conflict-resolution">
+ <properties>
+ <help>DNS conflict resolution behavior</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable DNS conflict resolution</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable DNS conflict resolution</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ <constraintErrorMessage>Set it to either enable or disable</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="ttl-percent">
+ <properties>
+ <help>Calculate TTL of the DNS record as a percentage of the lease lifetime</help>
+ <constraint>
+ <validator name="numeric" argument="--range 1-100" />
+ </constraint>
+ <constraintErrorMessage>Invalid qualifying suffix</constraintErrorMessage>
+ </properties>
+</leafNode>
+<leafNode name="hostname-char-set">
+ <properties>
+ <help>A regular expression describing the invalid character set in the host name</help>
+ </properties>
+</leafNode>
+<leafNode name="hostname-char-replacement">
+ <properties>
+ <help>A string of zero or more characters with which to replace each invalid character in
+ the host name</help>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/dhcp/ping-check.xml.i b/interface-definitions/include/dhcp/ping-check.xml.i
new file mode 100644
index 000000000..a506f68e4
--- /dev/null
+++ b/interface-definitions/include/dhcp/ping-check.xml.i
@@ -0,0 +1,8 @@
+<!-- include start from dhcp/ping-check.xml.i -->
+<leafNode name="ping-check">
+ <properties>
+ <help>Sends ICMP Echo request to the address being assigned</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/common-rule-ipv6.xml.i b/interface-definitions/include/firewall/common-rule-ipv6.xml.i
index bb176fe71..65ec415fb 100644
--- a/interface-definitions/include/firewall/common-rule-ipv6.xml.i
+++ b/interface-definitions/include/firewall/common-rule-ipv6.xml.i
@@ -16,6 +16,7 @@
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/source-destination-dynamic-group-ipv6.xml.i>
+ #include <include/firewall/source-destination-remote-group.xml.i>
</children>
</node>
<leafNode name="jump-target">
@@ -39,6 +40,7 @@
#include <include/firewall/port.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/source-destination-dynamic-group-ipv6.xml.i>
+ #include <include/firewall/source-destination-remote-group.xml.i>
</children>
</node>
-<!-- include end --> \ No newline at end of file
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/geoip.xml.i b/interface-definitions/include/firewall/geoip.xml.i
index 9fb37a574..b8f2cbc45 100644
--- a/interface-definitions/include/firewall/geoip.xml.i
+++ b/interface-definitions/include/firewall/geoip.xml.i
@@ -12,7 +12,7 @@
<description>Country code (2 characters)</description>
</valueHelp>
<constraint>
- <regex>^(ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)$</regex>
+ <regex>(ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)</regex>
</constraint>
<multi />
</properties>
diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i
index 355b41fde..e19f3a7c5 100644
--- a/interface-definitions/include/firewall/global-options.xml.i
+++ b/interface-definitions/include/firewall/global-options.xml.i
@@ -49,12 +49,53 @@
<help>Apply configured firewall rules to traffic switched by bridges</help>
</properties>
<children>
- <leafNode name="invalid-connections">
+ <node name="accept-invalid">
<properties>
- <help>Accept ARP, DHCP and PPPoE despite they are marked as invalid connection</help>
- <valueless/>
+ <help>Accept connections despite they are marked as invalid</help>
</properties>
- </leafNode>
+ <children>
+ <leafNode name="ethernet-type">
+ <properties>
+ <help>Ethernet type</help>
+ <completionHelp>
+ <list>arp dhcp pppoe 802.1q 802.1ad pppoe-discovery wol</list>
+ </completionHelp>
+ <valueHelp>
+ <format>arp</format>
+ <description>Adress Resolution Protocol (ARP)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>dhcp</format>
+ <description>Dynamic Host Configuration Protocol (DHCP)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>pppoe</format>
+ <description>Point to Point over Ethernet (PPPoE) Session</description>
+ </valueHelp>
+ <valueHelp>
+ <format>pppoe-discovery</format>
+ <description>PPPoE Discovery</description>
+ </valueHelp>
+ <valueHelp>
+ <format>802.1q</format>
+ <description>Customer VLAN tag type (802.1Q)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>802.1ad</format>
+ <description>Service VLAN tag type (802.1ad)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>wol</format>
+ <description>Wake-on-LAN magic packet</description>
+ </valueHelp>
+ <constraint>
+ <regex>(arp|dhcp|pppoe|pppoe-discovery|802.1q|802.1ad|wol)</regex>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="ipv4">
<properties>
<help>Apply configured IPv4 firewall rules</help>
@@ -217,6 +258,14 @@
<help>Global firewall state-policy</help>
</properties>
<children>
+ <node name="offload">
+ <properties>
+ <help>All stateful forward traffic is offloaded to a flowtable</help>
+ </properties>
+ <children>
+ #include <include/firewall/offload-target.xml.i>
+ </children>
+ </node>
<node name="established">
<properties>
<help>Global firewall policy for packets part of an established connection</help>
diff --git a/interface-definitions/include/haproxy/logging.xml.i b/interface-definitions/include/haproxy/logging.xml.i
index e0af54fa4..315c959bf 100644
--- a/interface-definitions/include/haproxy/logging.xml.i
+++ b/interface-definitions/include/haproxy/logging.xml.i
@@ -4,7 +4,137 @@
<help>Logging parameters</help>
</properties>
<children>
- #include <include/syslog-facility.xml.i>
+ <tagNode name="facility">
+ <properties>
+ <help>Facility for logging</help>
+ <completionHelp>
+ <list>auth cron daemon kern lpr mail news syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7</list>
+ </completionHelp>
+ <constraint>
+ <regex>(auth|cron|daemon|kern|lpr|mail|news|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid facility type</constraintErrorMessage>
+ <valueHelp>
+ <format>auth</format>
+ <description>Authentication and authorization</description>
+ </valueHelp>
+ <valueHelp>
+ <format>cron</format>
+ <description>Cron daemon</description>
+ </valueHelp>
+ <valueHelp>
+ <format>daemon</format>
+ <description>System daemons</description>
+ </valueHelp>
+ <valueHelp>
+ <format>kern</format>
+ <description>Kernel</description>
+ </valueHelp>
+ <valueHelp>
+ <format>lpr</format>
+ <description>Line printer spooler</description>
+ </valueHelp>
+ <valueHelp>
+ <format>mail</format>
+ <description>Mail subsystem</description>
+ </valueHelp>
+ <valueHelp>
+ <format>news</format>
+ <description>USENET subsystem</description>
+ </valueHelp>
+ <valueHelp>
+ <format>syslog</format>
+ <description>Authentication and authorization</description>
+ </valueHelp>
+ <valueHelp>
+ <format>user</format>
+ <description>Application processes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>uucp</format>
+ <description>UUCP subsystem</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local0</format>
+ <description>Local facility 0</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local1</format>
+ <description>Local facility 1</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local2</format>
+ <description>Local facility 2</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local3</format>
+ <description>Local facility 3</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local4</format>
+ <description>Local facility 4</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local5</format>
+ <description>Local facility 5</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local6</format>
+ <description>Local facility 6</description>
+ </valueHelp>
+ <valueHelp>
+ <format>local7</format>
+ <description>Local facility 7</description>
+ </valueHelp>
+ </properties>
+ <children>
+ <leafNode name="level">
+ <properties>
+ <help>Logging level</help>
+ <completionHelp>
+ <list>emerg alert crit err warning notice info debug</list>
+ </completionHelp>
+ <valueHelp>
+ <format>emerg</format>
+ <description>Emergency messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>alert</format>
+ <description>Urgent messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>crit</format>
+ <description>Critical messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>err</format>
+ <description>Error messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>warning</format>
+ <description>Warning messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>notice</format>
+ <description>Messages for further investigation</description>
+ </valueHelp>
+ <valueHelp>
+ <format>info</format>
+ <description>Informational messages</description>
+ </valueHelp>
+ <valueHelp>
+ <format>debug</format>
+ <description>Debug messages</description>
+ </valueHelp>
+ <constraint>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
+ </properties>
+ <defaultValue>err</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/haproxy/rule-backend.xml.i b/interface-definitions/include/haproxy/rule-backend.xml.i
index 1df9d5dcf..5faf09a96 100644
--- a/interface-definitions/include/haproxy/rule-backend.xml.i
+++ b/interface-definitions/include/haproxy/rule-backend.xml.i
@@ -38,7 +38,7 @@
<description>Set URL location</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
</properties>
@@ -90,7 +90,7 @@
<description>Begin URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
@@ -104,7 +104,7 @@
<description>End URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
@@ -118,7 +118,7 @@
<description>Exactly URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]*$</regex>
+ <regex>\/[\w\-.\/]*</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
diff --git a/interface-definitions/include/haproxy/rule-frontend.xml.i b/interface-definitions/include/haproxy/rule-frontend.xml.i
index eabdd8632..d2e7a38c3 100644
--- a/interface-definitions/include/haproxy/rule-frontend.xml.i
+++ b/interface-definitions/include/haproxy/rule-frontend.xml.i
@@ -32,15 +32,15 @@
<children>
<leafNode name="redirect-location">
<properties>
- <help>Set URL location</help>
+ <help>Set path location</help>
<valueHelp>
<format>url</format>
- <description>Set URL location</description>
+ <description>Set path location</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
- <constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
+ <constraintErrorMessage>Incorrect path format</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="backend">
@@ -93,7 +93,7 @@
<description>Begin URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
@@ -107,7 +107,7 @@
<description>End URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
@@ -121,7 +121,7 @@
<description>Exactly URL</description>
</valueHelp>
<constraint>
- <regex>^\/[\w\-.\/]+$</regex>
+ <regex>\/[\w\-.\/]+</regex>
</constraint>
<constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
<multi/>
diff --git a/interface-definitions/include/interface/ipv6-address-interface-identifier.xml.i b/interface-definitions/include/interface/ipv6-address-interface-identifier.xml.i
new file mode 100644
index 000000000..d173dfdb8
--- /dev/null
+++ b/interface-definitions/include/interface/ipv6-address-interface-identifier.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from interface/ipv6-address-interface-identifier.xml.i -->
+<leafNode name="interface-identifier">
+ <properties>
+ <help>SLAAC interface identifier</help>
+ <valueHelp>
+ <format>::h:h:h:h</format>
+ <description>Interface identifier</description>
+ </valueHelp>
+ <constraint>
+ <regex>::([0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){0,3})</regex>
+ </constraint>
+ <constraintErrorMessage>Interface identifier format must start with :: and may contain up four hextets (::h:h:h:h)</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/ipv6-address.xml.i b/interface-definitions/include/interface/ipv6-address.xml.i
deleted file mode 100644
index e1bdf02fd..000000000
--- a/interface-definitions/include/interface/ipv6-address.xml.i
+++ /dev/null
@@ -1,12 +0,0 @@
-<!-- include start from interface/ipv6-address.xml.i -->
-<node name="address">
- <properties>
- <help>IPv6 address configuration modes</help>
- </properties>
- <children>
- #include <include/interface/ipv6-address-autoconf.xml.i>
- #include <include/interface/ipv6-address-eui64.xml.i>
- #include <include/interface/ipv6-address-no-default-link-local.xml.i>
- </children>
-</node>
-<!-- include end -->
diff --git a/interface-definitions/include/interface/ipv6-options-with-nd.xml.i b/interface-definitions/include/interface/ipv6-options-with-nd.xml.i
new file mode 100644
index 000000000..5894104b3
--- /dev/null
+++ b/interface-definitions/include/interface/ipv6-options-with-nd.xml.i
@@ -0,0 +1,9 @@
+ <node name="ipv6">
+ <children>
+ <node name="address">
+ <children>
+ #include <include/interface/ipv6-address-interface-identifier.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
diff --git a/interface-definitions/include/interface/ipv6-options.xml.i b/interface-definitions/include/interface/ipv6-options.xml.i
index ec6ec64ee..f84a9f2cd 100644
--- a/interface-definitions/include/interface/ipv6-options.xml.i
+++ b/interface-definitions/include/interface/ipv6-options.xml.i
@@ -8,9 +8,18 @@
#include <include/interface/base-reachable-time.xml.i>
#include <include/interface/disable-forwarding.xml.i>
#include <include/interface/ipv6-accept-dad.xml.i>
- #include <include/interface/ipv6-address.xml.i>
#include <include/interface/ipv6-dup-addr-detect-transmits.xml.i>
#include <include/interface/source-validation.xml.i>
+ <node name="address">
+ <properties>
+ <help>IPv6 address configuration modes</help>
+ </properties>
+ <children>
+ #include <include/interface/ipv6-address-autoconf.xml.i>
+ #include <include/interface/ipv6-address-eui64.xml.i>
+ #include <include/interface/ipv6-address-no-default-link-local.xml.i>
+ </children>
+ </node>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i
index 02e7ab057..65ca10207 100644
--- a/interface-definitions/include/interface/vif-s.xml.i
+++ b/interface-definitions/include/interface/vif-s.xml.i
@@ -21,6 +21,7 @@
#include <include/interface/vlan-protocol.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
@@ -41,6 +42,7 @@
#include <include/interface/disable.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
diff --git a/interface-definitions/include/interface/vif.xml.i b/interface-definitions/include/interface/vif.xml.i
index ec3921bf6..87f91c5ce 100644
--- a/interface-definitions/include/interface/vif.xml.i
+++ b/interface-definitions/include/interface/vif.xml.i
@@ -46,6 +46,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
diff --git a/interface-definitions/include/rpki/protocol-common-config.xml.i b/interface-definitions/include/rpki/protocol-common-config.xml.i
new file mode 100644
index 000000000..0b3356604
--- /dev/null
+++ b/interface-definitions/include/rpki/protocol-common-config.xml.i
@@ -0,0 +1,87 @@
+<!-- include start from rpki/protocol-common-config.xml.i -->
+<tagNode name="cache">
+ <properties>
+ <help>RPKI cache server address</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IP address of RPKI server</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address of RPKI server</description>
+ </valueHelp>
+ <valueHelp>
+ <format>hostname</format>
+ <description>Fully qualified domain name of RPKI server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-address"/>
+ <validator name="fqdn"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/port-number.xml.i>
+ <leafNode name="preference">
+ <properties>
+ <help>Preference of the cache server</help>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>Preference of the cache server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/source-address-ipv4.xml.i>
+ <node name="ssh">
+ <properties>
+ <help>RPKI SSH connection settings</help>
+ </properties>
+ <children>
+ #include <include/pki/openssh-key.xml.i>
+ #include <include/generic-username.xml.i>
+ </children>
+ </node>
+ </children>
+</tagNode>
+<leafNode name="expire-interval">
+ <properties>
+ <help>Interval to wait before expiring the cache</help>
+ <valueHelp>
+ <format>u32:600-172800</format>
+ <description>Interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 600-172800"/>
+ </constraint>
+ </properties>
+ <defaultValue>7200</defaultValue>
+</leafNode>
+<leafNode name="polling-period">
+ <properties>
+ <help>Cache polling interval</help>
+ <valueHelp>
+ <format>u32:1-86400</format>
+ <description>Interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-86400"/>
+ </constraint>
+ </properties>
+ <defaultValue>300</defaultValue>
+</leafNode>
+<leafNode name="retry-interval">
+ <properties>
+ <help>Retry interval to connect to the cache server</help>
+ <valueHelp>
+ <format>u32:1-7200</format>
+ <description>Interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-7200"/>
+ </constraint>
+ </properties>
+ <defaultValue>600</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/version/conntrack-version.xml.i b/interface-definitions/include/version/conntrack-version.xml.i
index 6995ce119..517424034 100644
--- a/interface-definitions/include/version/conntrack-version.xml.i
+++ b/interface-definitions/include/version/conntrack-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/conntrack-version.xml.i -->
-<syntaxVersion component='conntrack' version='5'></syntaxVersion>
+<syntaxVersion component='conntrack' version='6'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/include/version/container-version.xml.i b/interface-definitions/include/version/container-version.xml.i
index ed6e942cd..046bacfdc 100644
--- a/interface-definitions/include/version/container-version.xml.i
+++ b/interface-definitions/include/version/container-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/container-version.xml.i -->
-<syntaxVersion component='container' version='2'></syntaxVersion>
+<syntaxVersion component='container' version='3'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i
index 1a8098297..1f3b779d5 100644
--- a/interface-definitions/include/version/firewall-version.xml.i
+++ b/interface-definitions/include/version/firewall-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/firewall-version.xml.i -->
-<syntaxVersion component='firewall' version='18'></syntaxVersion>
+<syntaxVersion component='firewall' version='19'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/include/version/ids-version.xml.i b/interface-definitions/include/version/ids-version.xml.i
index 9133be02b..6d4e92c21 100644
--- a/interface-definitions/include/version/ids-version.xml.i
+++ b/interface-definitions/include/version/ids-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/ids-version.xml.i -->
-<syntaxVersion component='ids' version='1'></syntaxVersion>
+<syntaxVersion component='ids' version='2'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/include/version/reverseproxy-version.xml.i b/interface-definitions/include/version/reverseproxy-version.xml.i
index 4f09f2848..71f7def1a 100644
--- a/interface-definitions/include/version/reverseproxy-version.xml.i
+++ b/interface-definitions/include/version/reverseproxy-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/reverseproxy-version.xml.i -->
-<syntaxVersion component='reverse-proxy' version='2'></syntaxVersion>
+<syntaxVersion component='reverse-proxy' version='3'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/interfaces_bonding.xml.in b/interface-definitions/interfaces_bonding.xml.in
index b17cad478..9945fc15d 100644
--- a/interface-definitions/interfaces_bonding.xml.in
+++ b/interface-definitions/interfaces_bonding.xml.in
@@ -141,6 +141,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
<leafNode name="mii-mon-interval">
<properties>
@@ -239,7 +240,7 @@
<description>Distribute based on MAC address</description>
</valueHelp>
<constraint>
- <regex>(802.3ad|active-backup|broadcast|round-robin|transmit-load-balance|adaptive-load-balance|xor-hash)</regex>
+ <regex>(802\.3ad|active-backup|broadcast|round-robin|transmit-load-balance|adaptive-load-balance|xor-hash)</regex>
</constraint>
<constraintErrorMessage>mode must be 802.3ad, active-backup, broadcast, round-robin, transmit-load-balance, adaptive-load-balance, or xor</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/interfaces_bridge.xml.in b/interface-definitions/interfaces_bridge.xml.in
index 29dd61df5..b360f34f1 100644
--- a/interface-definitions/interfaces_bridge.xml.in
+++ b/interface-definitions/interfaces_bridge.xml.in
@@ -93,6 +93,7 @@
</node>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mirror.xml.i>
<leafNode name="enable-vlan">
@@ -200,6 +201,18 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="bpdu-guard">
+ <properties>
+ <help>Enable BPDU Guard</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="root-guard">
+ <properties>
+ <help>Enable Root Guard</help>
+ <valueless/>
+ </properties>
+ </leafNode>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces_ethernet.xml.in b/interface-definitions/interfaces_ethernet.xml.in
index b3559a626..819ceb2cb 100644
--- a/interface-definitions/interfaces_ethernet.xml.in
+++ b/interface-definitions/interfaces_ethernet.xml.in
@@ -74,6 +74,7 @@
#include <include/interface/hw-id.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/mirror.xml.i>
diff --git a/interface-definitions/interfaces_geneve.xml.in b/interface-definitions/interfaces_geneve.xml.in
index c1e6c33d5..b85bd3b9e 100644
--- a/interface-definitions/interfaces_geneve.xml.in
+++ b/interface-definitions/interfaces_geneve.xml.in
@@ -21,6 +21,7 @@
#include <include/interface/disable.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-1200-16000.xml.i>
#include <include/port-number.xml.i>
diff --git a/interface-definitions/interfaces_l2tpv3.xml.in b/interface-definitions/interfaces_l2tpv3.xml.in
index 5f816c956..381e86bd0 100644
--- a/interface-definitions/interfaces_l2tpv3.xml.in
+++ b/interface-definitions/interfaces_l2tpv3.xml.in
@@ -55,6 +55,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/source-address-ipv4-ipv6.xml.i>
#include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
diff --git a/interface-definitions/interfaces_macsec.xml.in b/interface-definitions/interfaces_macsec.xml.in
index d825f8262..5279a9495 100644
--- a/interface-definitions/interfaces_macsec.xml.in
+++ b/interface-definitions/interfaces_macsec.xml.in
@@ -21,6 +21,7 @@
#include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mirror.xml.i>
<node name="security">
<properties>
diff --git a/interface-definitions/interfaces_openvpn.xml.in b/interface-definitions/interfaces_openvpn.xml.in
index 3c844107e..6510ed733 100644
--- a/interface-definitions/interfaces_openvpn.xml.in
+++ b/interface-definitions/interfaces_openvpn.xml.in
@@ -135,6 +135,7 @@
</node>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mirror.xml.i>
<leafNode name="hash">
<properties>
diff --git a/interface-definitions/interfaces_pppoe.xml.in b/interface-definitions/interfaces_pppoe.xml.in
index f24bc41d8..66a774e21 100644
--- a/interface-definitions/interfaces_pppoe.xml.in
+++ b/interface-definitions/interfaces_pppoe.xml.in
@@ -88,6 +88,7 @@
</properties>
<children>
#include <include/interface/ipv6-address-autoconf.xml.i>
+ #include <include/interface/ipv6-address-interface-identifier.xml.i>
</children>
</node>
#include <include/interface/adjust-mss.xml.i>
diff --git a/interface-definitions/interfaces_pseudo-ethernet.xml.in b/interface-definitions/interfaces_pseudo-ethernet.xml.in
index 031af3563..f13144bed 100644
--- a/interface-definitions/interfaces_pseudo-ethernet.xml.in
+++ b/interface-definitions/interfaces_pseudo-ethernet.xml.in
@@ -25,6 +25,7 @@
#include <include/interface/vrf.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/source-interface-ethernet.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mirror.xml.i>
diff --git a/interface-definitions/interfaces_vxlan.xml.in b/interface-definitions/interfaces_vxlan.xml.in
index 937acb123..f4cd4fcd2 100644
--- a/interface-definitions/interfaces_vxlan.xml.in
+++ b/interface-definitions/interfaces_vxlan.xml.in
@@ -45,6 +45,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-1200-16000.xml.i>
#include <include/interface/mirror.xml.i>
diff --git a/interface-definitions/interfaces_wireless.xml.in b/interface-definitions/interfaces_wireless.xml.in
index 474953500..1b5356caa 100644
--- a/interface-definitions/interfaces_wireless.xml.in
+++ b/interface-definitions/interfaces_wireless.xml.in
@@ -626,6 +626,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/hw-id.xml.i>
<leafNode name="isolate-stations">
<properties>
diff --git a/interface-definitions/interfaces_wwan.xml.in b/interface-definitions/interfaces_wwan.xml.in
index 1580c3bcb..552806d4e 100644
--- a/interface-definitions/interfaces_wwan.xml.in
+++ b/interface-definitions/interfaces_wwan.xml.in
@@ -38,6 +38,7 @@
</leafNode>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/ipv6-options-with-nd.xml.i>
#include <include/interface/dial-on-demand.xml.i>
#include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
diff --git a/interface-definitions/load-balancing_haproxy.xml.in b/interface-definitions/load-balancing_haproxy.xml.in
index b95e02337..61ff8bc81 100644
--- a/interface-definitions/load-balancing_haproxy.xml.in
+++ b/interface-definitions/load-balancing_haproxy.xml.in
@@ -4,7 +4,7 @@
<children>
<node name="haproxy" owner="${vyos_conf_scripts_dir}/load-balancing_haproxy.py">
<properties>
- <help>Configure haproxy</help>
+ <help>HAProxy TCP/HTTP Load Balancer</help>
<priority>900</priority>
</properties>
<children>
@@ -26,7 +26,7 @@
<constraintErrorMessage>Backend name must be alphanumeric and can contain hyphen and underscores</constraintErrorMessage>
<valueHelp>
<format>txt</format>
- <description>Name of haproxy backend system</description>
+ <description>HAProxy backend system name</description>
</valueHelp>
<completionHelp>
<path>load-balancing haproxy backend</path>
@@ -159,7 +159,7 @@
<properties>
<help>URI used for HTTP health check (Example: '/' or '/health')</help>
<constraint>
- <regex>^\/([^?#\s]*)(\?[^#\s]*)?$</regex>
+ <regex>\/([^?#\s]*)(\?[^#\s]*)?</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/load-balancing_wan.xml.in b/interface-definitions/load-balancing_wan.xml.in
index 310aa0343..f80440411 100644
--- a/interface-definitions/load-balancing_wan.xml.in
+++ b/interface-definitions/load-balancing_wan.xml.in
@@ -7,7 +7,7 @@
<children>
<node name="wan" owner="${vyos_conf_scripts_dir}/load-balancing_wan.py">
<properties>
- <help>Configure Wide Area Network (WAN) load-balancing</help>
+ <help>Wide Area Network (WAN) load-balancing</help>
<priority>900</priority>
</properties>
<children>
diff --git a/interface-definitions/nat66.xml.in b/interface-definitions/nat66.xml.in
index c59725c53..2c1babd5a 100644
--- a/interface-definitions/nat66.xml.in
+++ b/interface-definitions/nat66.xml.in
@@ -53,6 +53,7 @@
</properties>
</leafNode>
#include <include/nat-port.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
</children>
</node>
<node name="source">
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 25dbf5581..31e01c68c 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -1519,7 +1519,7 @@
<constraint>
<validator name="numeric" argument="--relative --"/>
<validator name="numeric" argument="--range 0-4294967295"/>
- <regex>^[+|-]?rtt$</regex>
+ <regex>[+|-]?rtt</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/policy_route.xml.in b/interface-definitions/policy_route.xml.in
index 9cc22540b..48f728923 100644
--- a/interface-definitions/policy_route.xml.in
+++ b/interface-definitions/policy_route.xml.in
@@ -35,6 +35,7 @@
#include <include/firewall/address-ipv6.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/port.xml.i>
+ #include <include/firewall/geoip.xml.i>
</children>
</node>
<node name="source">
@@ -45,6 +46,7 @@
#include <include/firewall/address-ipv6.xml.i>
#include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/port.xml.i>
+ #include <include/firewall/geoip.xml.i>
</children>
</node>
#include <include/policy/route-common.xml.i>
@@ -90,6 +92,7 @@
#include <include/firewall/address.xml.i>
#include <include/firewall/source-destination-group.xml.i>
#include <include/firewall/port.xml.i>
+ #include <include/firewall/geoip.xml.i>
</children>
</node>
<node name="source">
@@ -100,6 +103,7 @@
#include <include/firewall/address.xml.i>
#include <include/firewall/source-destination-group.xml.i>
#include <include/firewall/port.xml.i>
+ #include <include/firewall/geoip.xml.i>
</children>
</node>
#include <include/policy/route-common.xml.i>
diff --git a/interface-definitions/protocols_rpki.xml.in b/interface-definitions/protocols_rpki.xml.in
index 9e2e84717..a298cdbfd 100644
--- a/interface-definitions/protocols_rpki.xml.in
+++ b/interface-definitions/protocols_rpki.xml.in
@@ -8,91 +8,7 @@
<priority>819</priority>
</properties>
<children>
- <tagNode name="cache">
- <properties>
- <help>RPKI cache server address</help>
- <valueHelp>
- <format>ipv4</format>
- <description>IP address of RPKI server</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>IPv6 address of RPKI server</description>
- </valueHelp>
- <valueHelp>
- <format>hostname</format>
- <description>Fully qualified domain name of RPKI server</description>
- </valueHelp>
- <constraint>
- <validator name="ip-address"/>
- <validator name="fqdn"/>
- </constraint>
- </properties>
- <children>
- #include <include/port-number.xml.i>
- <leafNode name="preference">
- <properties>
- <help>Preference of the cache server</help>
- <valueHelp>
- <format>u32:1-255</format>
- <description>Preference of the cache server</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-255"/>
- </constraint>
- </properties>
- </leafNode>
- #include <include/source-address-ipv4.xml.i>
- <node name="ssh">
- <properties>
- <help>RPKI SSH connection settings</help>
- </properties>
- <children>
- #include <include/pki/openssh-key.xml.i>
- #include <include/generic-username.xml.i>
- </children>
- </node>
- </children>
- </tagNode>
- <leafNode name="expire-interval">
- <properties>
- <help>Interval to wait before expiring the cache</help>
- <valueHelp>
- <format>u32:600-172800</format>
- <description>Interval in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 600-172800"/>
- </constraint>
- </properties>
- <defaultValue>7200</defaultValue>
- </leafNode>
- <leafNode name="polling-period">
- <properties>
- <help>Cache polling interval</help>
- <valueHelp>
- <format>u32:1-86400</format>
- <description>Interval in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-86400"/>
- </constraint>
- </properties>
- <defaultValue>300</defaultValue>
- </leafNode>
- <leafNode name="retry-interval">
- <properties>
- <help>Retry interval to connect to the cache server</help>
- <valueHelp>
- <format>u32:1-7200</format>
- <description>Interval in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-7200"/>
- </constraint>
- </properties>
- <defaultValue>600</defaultValue>
- </leafNode>
+ #include <include/rpki/protocol-common-config.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/qos.xml.in b/interface-definitions/qos.xml.in
index c6ecb742e..aad1de629 100644
--- a/interface-definitions/qos.xml.in
+++ b/interface-definitions/qos.xml.in
@@ -135,6 +135,25 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="no-split-gso">
+ <properties>
+ <help>Do not split GSO super-packets into on-the-wire components</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <node name="ack-filter">
+ <properties>
+ <help>Identify and filter out TCP ACK packets that do not convey significant new information</help>
+ </properties>
+ <children>
+ <leafNode name="aggressive">
+ <properties>
+ <help>Enable aggressive mode which will result in more ACK packets being compresses/filtered</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="rtt">
<properties>
<help>Round-Trip-Time for Active Queue Management (AQM)</help>
diff --git a/interface-definitions/service_dhcp-server.xml.in b/interface-definitions/service_dhcp-server.xml.in
index 9a194de4f..78f1cea4e 100644
--- a/interface-definitions/service_dhcp-server.xml.in
+++ b/interface-definitions/service_dhcp-server.xml.in
@@ -10,12 +10,111 @@
</properties>
<children>
#include <include/generic-disable-node.xml.i>
- <leafNode name="dynamic-dns-update">
+ <node name="dynamic-dns-update">
<properties>
<help>Dynamically update Domain Name System (RFC4702)</help>
- <valueless/>
</properties>
- </leafNode>
+ <children>
+ #include <include/dhcp/ddns-settings.xml.i>
+ <tagNode name="tsig-key">
+ <properties>
+ <help>TSIG key definition for DNS updates</help>
+ <constraint>
+ #include <include/constraint/alpha-numeric-hyphen-underscore.xml.i>
+ </constraint>
+ <constraintErrorMessage>Invalid TSIG key name. May only contain letters, numbers, hyphen and underscore</constraintErrorMessage>
+ </properties>
+ <children>
+ <leafNode name="algorithm">
+ <properties>
+ <help>TSIG key algorithm</help>
+ <completionHelp>
+ <list>md5 sha1 sha224 sha256 sha384 sha512</list>
+ </completionHelp>
+ <valueHelp>
+ <format>md5</format>
+ <description>MD5 HMAC algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha1</format>
+ <description>SHA1 HMAC algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha224</format>
+ <description>SHA224 HMAC algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha256</format>
+ <description>SHA256 HMAC algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha384</format>
+ <description>SHA384 HMAC algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha512</format>
+ <description>SHA512 HMAC algorithm</description>
+ </valueHelp>
+ <constraint>
+ <regex>(md5|sha1|sha224|sha256|sha384|sha512)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid TSIG key algorithm</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="secret">
+ <properties>
+ <help>TSIG key secret (base64-encoded)</help>
+ <constraint>
+ <validator name="base64"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ <tagNode name="forward-domain">
+ <properties>
+ <help>Forward DNS domain name</help>
+ <constraint>
+ <validator name="fqdn"/>
+ </constraint>
+ <constraintErrorMessage>Invalid forward DNS domain name</constraintErrorMessage>
+ </properties>
+ <children>
+ <leafNode name="key-name">
+ <properties>
+ <help>TSIG key name for forward DNS updates</help>
+ <constraint>
+ #include <include/constraint/alpha-numeric-hyphen-underscore.xml.i>
+ </constraint>
+ <constraintErrorMessage>Invalid TSIG key name. May only contain letters, numbers, numbers, hyphen and underscore</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/dhcp/ddns-dns-server.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="reverse-domain">
+ <properties>
+ <help>Reverse DNS domain name</help>
+ <constraint>
+ <validator name="fqdn"/>
+ </constraint>
+ <constraintErrorMessage>Invalid reverse DNS domain name</constraintErrorMessage>
+ </properties>
+ <children>
+ <leafNode name="key-name">
+ <properties>
+ <help>TSIG key name for reverse DNS updates</help>
+ <constraint>
+ #include <include/constraint/alpha-numeric-hyphen-underscore.xml.i>
+ </constraint>
+ <constraintErrorMessage>Invalid TSIG key name. May only contain letters, numbers, numbers, hyphen and underscore</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/dhcp/ddns-dns-server.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
<node name="high-availability">
<properties>
<help>DHCP high availability configuration</help>
@@ -105,6 +204,14 @@
<constraintErrorMessage>Invalid shared network name. May only contain letters, numbers and .-_</constraintErrorMessage>
</properties>
<children>
+ <node name="dynamic-dns-update">
+ <properties>
+ <help>Dynamically update Domain Name System (RFC4702)</help>
+ </properties>
+ <children>
+ #include <include/dhcp/ddns-settings.xml.i>
+ </children>
+ </node>
<leafNode name="authoritative">
<properties>
<help>Option to make DHCP server authoritative for this physical network</help>
@@ -112,6 +219,7 @@
</properties>
</leafNode>
#include <include/dhcp/option-v4.xml.i>
+ #include <include/dhcp/ping-check.xml.i>
#include <include/generic-description.xml.i>
#include <include/generic-disable-node.xml.i>
<tagNode name="subnet">
@@ -128,8 +236,17 @@
</properties>
<children>
#include <include/dhcp/option-v4.xml.i>
+ #include <include/dhcp/ping-check.xml.i>
#include <include/generic-description.xml.i>
#include <include/generic-disable-node.xml.i>
+ <node name="dynamic-dns-update">
+ <properties>
+ <help>Dynamically update Domain Name System (RFC4702)</help>
+ </properties>
+ <children>
+ #include <include/dhcp/ddns-settings.xml.i>
+ </children>
+ </node>
<leafNode name="exclude">
<properties>
<help>IP address to exclude from DHCP lease range</help>
diff --git a/interface-definitions/service_ids_ddos-protection.xml.in b/interface-definitions/service_ids_ddos-protection.xml.in
deleted file mode 100644
index 3ef2640b3..000000000
--- a/interface-definitions/service_ids_ddos-protection.xml.in
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0"?>
-<interfaceDefinition>
- <node name="service">
- <children>
- <node name="ids">
- <properties>
- <help>Intrusion Detection System</help>
- </properties>
- <children>
- <node name="ddos-protection" owner="${vyos_conf_scripts_dir}/service_ids_ddos-protection.py">
- <properties>
- <help>FastNetMon detection and protection parameters</help>
- <priority>731</priority>
- </properties>
- <children>
- <leafNode name="alert-script">
- <properties>
- <help>Path to fastnetmon alert script</help>
- </properties>
- </leafNode>
- <leafNode name="ban-time">
- <properties>
- <help>How long we should keep an IP in blocked state</help>
- <valueHelp>
- <format>u32:1-4294967294</format>
- <description>Time in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4294967294"/>
- </constraint>
- </properties>
- <defaultValue>1900</defaultValue>
- </leafNode>
- <leafNode name="direction">
- <properties>
- <help>Direction for processing traffic</help>
- <completionHelp>
- <list>in out</list>
- </completionHelp>
- <constraint>
- <regex>(in|out)</regex>
- </constraint>
- <multi/>
- </properties>
- </leafNode>
- <leafNode name="excluded-network">
- <properties>
- <help>Specify IPv4 and IPv6 networks which are going to be excluded from protection</help>
- <valueHelp>
- <format>ipv4net</format>
- <description>IPv4 prefix(es) to exclude</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6net</format>
- <description>IPv6 prefix(es) to exclude</description>
- </valueHelp>
- <constraint>
- <validator name="ipv4-prefix"/>
- <validator name="ipv6-prefix"/>
- </constraint>
- <multi/>
- </properties>
- </leafNode>
- <leafNode name="listen-interface">
- <properties>
- <help>Listen interface for mirroring traffic</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces</script>
- </completionHelp>
- <multi/>
- </properties>
- </leafNode>
- <leafNode name="mode">
- <properties>
- <help>Traffic capture mode</help>
- <completionHelp>
- <list>mirror sflow</list>
- </completionHelp>
- <valueHelp>
- <format>mirror</format>
- <description>Listen to mirrored traffic</description>
- </valueHelp>
- <valueHelp>
- <format>sflow</format>
- <description>Capture sFlow flows</description>
- </valueHelp>
- <constraint>
- <regex>(mirror|sflow)</regex>
- </constraint>
- </properties>
- </leafNode>
- <node name="sflow">
- <properties>
- <help>Sflow settings</help>
- </properties>
- <children>
- #include <include/listen-address-ipv4-single.xml.i>
- #include <include/port-number.xml.i>
- <leafNode name="port">
- <defaultValue>6343</defaultValue>
- </leafNode>
- </children>
- </node>
- <leafNode name="network">
- <properties>
- <help>Specify IPv4 and IPv6 networks which belong to you</help>
- <valueHelp>
- <format>ipv4net</format>
- <description>Your IPv4 prefix(es)</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6net</format>
- <description>Your IPv6 prefix(es)</description>
- </valueHelp>
- <constraint>
- <validator name="ipv4-prefix"/>
- <validator name="ipv6-prefix"/>
- </constraint>
- <multi/>
- </properties>
- </leafNode>
- <node name="threshold">
- <properties>
- <help>Attack limits thresholds</help>
- </properties>
- <children>
- <node name="general">
- <properties>
- <help>General threshold</help>
- </properties>
- <children>
- #include <include/ids/threshold.xml.i>
- </children>
- </node>
- <node name="tcp">
- <properties>
- <help>TCP threshold</help>
- </properties>
- <children>
- #include <include/ids/threshold.xml.i>
- </children>
- </node>
- <node name="udp">
- <properties>
- <help>UDP threshold</help>
- </properties>
- <children>
- #include <include/ids/threshold.xml.i>
- </children>
- </node>
- <node name="icmp">
- <properties>
- <help>ICMP threshold</help>
- </properties>
- <children>
- #include <include/ids/threshold.xml.i>
- </children>
- </node>
- </children>
- </node>
- </children>
- </node>
- </children>
- </node>
- </children>
- </node>
-</interfaceDefinition>
diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in
index fe9d32bbd..3093151ea 100644
--- a/interface-definitions/service_ipoe-server.xml.in
+++ b/interface-definitions/service_ipoe-server.xml.in
@@ -237,6 +237,7 @@
#include <include/accel-ppp/max-concurrent-sessions.xml.i>
#include <include/accel-ppp/shaper.xml.i>
#include <include/accel-ppp/snmp.xml.i>
+ #include <include/accel-ppp/thread-count.xml.i>
#include <include/generic-description.xml.i>
#include <include/name-server-ipv4-ipv6.xml.i>
#include <include/accel-ppp/log.xml.i>
diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in
index 32215e9d2..81a4a95e3 100644
--- a/interface-definitions/service_pppoe-server.xml.in
+++ b/interface-definitions/service_pppoe-server.xml.in
@@ -175,6 +175,7 @@
</node>
#include <include/accel-ppp/shaper.xml.i>
#include <include/accel-ppp/snmp.xml.i>
+ #include <include/accel-ppp/thread-count.xml.i>
#include <include/accel-ppp/wins-server.xml.i>
#include <include/generic-description.xml.i>
#include <include/name-server-ipv4-ipv6.xml.i>
diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in
index 3fd33540a..7f96cdb19 100644
--- a/interface-definitions/service_router-advert.xml.in
+++ b/interface-definitions/service_router-advert.xml.in
@@ -255,6 +255,19 @@
</leafNode>
</children>
</tagNode>
+ <leafNode name="auto-ignore">
+ <properties>
+ <help>IPv6 prefix to be excluded in Router Advertisements (RAs) - use in conjunction with the ::/64 wildcard prefix</help>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 prefix to be excluded</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
<tagNode name="prefix">
<properties>
<help>IPv6 prefix to be advertised in Router Advertisements (RAs)</help>
diff --git a/interface-definitions/service_snmp.xml.in b/interface-definitions/service_snmp.xml.in
index cc21f5b8b..bdc9f88fe 100644
--- a/interface-definitions/service_snmp.xml.in
+++ b/interface-definitions/service_snmp.xml.in
@@ -13,7 +13,7 @@
<properties>
<help>Community name</help>
<constraint>
- <regex>[[:alnum:]-_!@*#]{1,100}</regex>
+ <regex>[[:alnum:]\-_!@*#]{1,100}</regex>
</constraint>
<constraintErrorMessage>Community string is limited to alphanumerical characters, -, _, !, @, *, and # with a total lenght of 100</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/service_ssh.xml.in b/interface-definitions/service_ssh.xml.in
index 14d358c78..c659a7db7 100644
--- a/interface-definitions/service_ssh.xml.in
+++ b/interface-definitions/service_ssh.xml.in
@@ -275,14 +275,18 @@
</constraint>
</properties>
</leafNode>
- <node name="trusted-user-ca-key">
+ <leafNode name="trusted-user-ca">
<properties>
- <help>Trusted user CA key</help>
+ <help>OpenSSH trusted user CA</help>
+ <completionHelp>
+ <path>pki openssh</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>OpenSSH certificate name from PKI subsystem</description>
+ </valueHelp>
</properties>
- <children>
- #include <include/pki/ca-certificate.xml.i>
- </children>
- </node>
+ </leafNode>
#include <include/vrf-multi.xml.i>
</children>
</node>
diff --git a/interface-definitions/system_conntrack.xml.in b/interface-definitions/system_conntrack.xml.in
index 54610b625..92c4d24cf 100644
--- a/interface-definitions/system_conntrack.xml.in
+++ b/interface-definitions/system_conntrack.xml.in
@@ -32,14 +32,14 @@
<properties>
<help>Hash size for connection tracking table</help>
<valueHelp>
- <format>u32:1-50000000</format>
+ <format>u32:1024-50000000</format>
<description>Size of hash to use for connection tracking table</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-50000000"/>
+ <validator name="numeric" argument="--range 1024-50000000"/>
</constraint>
</properties>
- <defaultValue>32768</defaultValue>
+ <defaultValue>65536</defaultValue>
</leafNode>
<node name="ignore">
<properties>
diff --git a/interface-definitions/system_ip.xml.in b/interface-definitions/system_ip.xml.in
index b4b5092fe..f2bb5bd8a 100644
--- a/interface-definitions/system_ip.xml.in
+++ b/interface-definitions/system_ip.xml.in
@@ -17,6 +17,22 @@
#include <include/arp-ndp-table-size.xml.i>
</children>
</node>
+ <tagNode name="import-table">
+ <properties>
+ <help>Routing table for import</help>
+ <valueHelp>
+ <format>u32:1-252</format>
+ <description>Table number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-252"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/static/static-route-distance.xml.i>
+ #include <include/route-map.xml.i>
+ </children>
+ </tagNode>
<leafNode name="disable-forwarding">
<properties>
<help>Disable IPv4 forwarding on all interfaces</help>
diff --git a/interface-definitions/system_login.xml.in b/interface-definitions/system_login.xml.in
index 9865e3d32..a13ba10ea 100644
--- a/interface-definitions/system_login.xml.in
+++ b/interface-definitions/system_login.xml.in
@@ -103,6 +103,15 @@
<help>Plaintext password used for encryption</help>
</properties>
</leafNode>
+ <leafNode name="principal">
+ <properties>
+ <help>Accepted principal names for certificate authentication</help>
+ <constraint>
+ #include <include/constraint/login-username.xml.i>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
<tagNode name="public-keys">
<properties>
<help>Remote access public keys</help>
diff --git a/interface-definitions/system_option.xml.in b/interface-definitions/system_option.xml.in
index 638ac1a3d..5d385e3d0 100644
--- a/interface-definitions/system_option.xml.in
+++ b/interface-definitions/system_option.xml.in
@@ -37,7 +37,145 @@
<help>Kernel boot parameters</help>
</properties>
<children>
- <leafNode name="disable-mitigations">
+ <node name="cpu">
+ <properties>
+ <help>CPU settings</help>
+ </properties>
+ <children>
+ <leafNode name="disable-nmi-watchdog">
+ <properties>
+ <help>Disable the NMI watchdog for detecting hard CPU lockups</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="isolate-cpus">
+ <properties>
+ <help>Isolate specified CPUs from the scheduler</help>
+ <valueHelp>
+ <format>u32:0-511</format>
+ <description>CPU core</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;start-end&gt;</format>
+ <description>CPU core range (examples: "1", "4-7", "1,2-5,7")</description>
+ </valueHelp>
+ <constraint>
+ <validator name="cpu"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="nohz-full">
+ <properties>
+ <help>Enable full tickless mode for specified CPUs</help>
+ <valueHelp>
+ <format>u32:0-511</format>
+ <description>CPU core</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;start-end&gt;</format>
+ <description>CPU core range (examples: "1", "4-7", "1,2-5,7")</description>
+ </valueHelp>
+ <constraint>
+ <validator name="cpu"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="rcu-no-cbs">
+ <properties>
+ <help>Offload Read-Copy-Update (RCU) callback processing to specified CPUs</help>
+ <valueHelp>
+ <format>u32:0-511</format>
+ <description>CPU core</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;start-end&gt;</format>
+ <description>CPU core range (examples: "1", "4-7", "1,2-5,7")</description>
+ </valueHelp>
+ <constraint>
+ <validator name="cpu"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="memory">
+ <properties>
+ <help>Memory settings</help>
+ </properties>
+ <children>
+ <leafNode name="disable-numa-balancing">
+ <properties>
+ <help>Disable automatic NUMA memory balancing</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="default-hugepage-size">
+ <properties>
+ <help>Set default hugepage size (e.g., 2M, 1G)</help>
+ <completionHelp>
+ <list>2M 1G</list>
+ </completionHelp>
+ <valueHelp>
+ <format>2M</format>
+ <description>2 megabytes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>1G</format>
+ <description>1 gigabyte</description>
+ </valueHelp>
+ <constraint>
+ <regex>(2M|1G)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <tagNode name="hugepage-size">
+ <properties>
+ <help>Set hugepage size for allocation (e.g., 2M, 1G)</help>
+ <completionHelp>
+ <list>2M 1G</list>
+ </completionHelp>
+ <valueHelp>
+ <format>2M</format>
+ <description>2 megabytes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>1G</format>
+ <description>1 gigabyte</description>
+ </valueHelp>
+ <constraint>
+ <regex>(2M|1G)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="hugepage-count">
+ <properties>
+ <help>Allocate number of hugepages for system use</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>Number of hugepages</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-100000"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ <leafNode name="disable-hpet">
+ <properties>
+ <help>Disable High Precision Event Timer (HPET)</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="disable-mce">
+ <properties>
+ <help>Disable Machine Check Exceptions (MCE) reporting and handling</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="disable-mitigations">
<properties>
<help>Disable all optional CPU mitigations</help>
<valueless/>
@@ -69,6 +207,18 @@
</valueHelp>
</properties>
</leafNode>
+ <leafNode name="disable-softlockup">
+ <properties>
+ <help>Disable soft lockup detector for kernel threads</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="quiet">
+ <properties>
+ <help>Disable most log messages</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<node name="debug">
<properties>
<help>Dynamic debugging for kernel module</help>
@@ -192,6 +342,19 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="reboot-on-upgrade-failure">
+ <properties>
+ <help>Automatic reboot into previous running image on upgrade failure</help>
+ <valueHelp>
+ <format>u32:1-30</format>
+ <description>Timeout before automatic reboot (minutes)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-30"/>
+ </constraint>
+ <constraintErrorMessage>Timeout out of range, must be 5 to 30 minutes</constraintErrorMessage>
+ </properties>
+ </leafNode>
<node name="ssh-client">
<properties>
<help>Global options used for SSH client</help>
diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in
index 0cf526fad..873a4f882 100644
--- a/interface-definitions/vpn_ipsec.xml.in
+++ b/interface-definitions/vpn_ipsec.xml.in
@@ -1244,6 +1244,63 @@
<children>
#include <include/ipsec/bind.xml.i>
#include <include/ipsec/esp-group.xml.i>
+ <node name="traffic-selector">
+ <properties>
+ <help>Traffic-selectors parameters</help>
+ </properties>
+ <children>
+ <node name="local">
+ <properties>
+ <help>Local parameters for interesting traffic</help>
+ </properties>
+ <children>
+ <leafNode name="prefix">
+ <properties>
+ <help>Local IPv4 or IPv6 prefix</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>Local IPv4 prefix</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>Local IPv6 prefix</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-prefix"/>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="remote">
+ <properties>
+ <help>Remote parameters for interesting traffic</help>
+ </properties>
+ <children>
+ <leafNode name="prefix">
+ <properties>
+ <help>Remote IPv4 or IPv6 prefix</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>Remote IPv4 prefix</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>Remote IPv6 prefix</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-prefix"/>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in
index c00e82534..d28f86653 100644
--- a/interface-definitions/vpn_l2tp.xml.in
+++ b/interface-definitions/vpn_l2tp.xml.in
@@ -137,6 +137,7 @@
#include <include/accel-ppp/ppp-options.xml.i>
#include <include/accel-ppp/shaper.xml.i>
#include <include/accel-ppp/snmp.xml.i>
+ #include <include/accel-ppp/thread-count.xml.i>
#include <include/accel-ppp/wins-server.xml.i>
#include <include/generic-description.xml.i>
#include <include/name-server-ipv4-ipv6.xml.i>
diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in
index 8aec0cb1c..3e985486d 100644
--- a/interface-definitions/vpn_pptp.xml.in
+++ b/interface-definitions/vpn_pptp.xml.in
@@ -53,6 +53,7 @@
#include <include/accel-ppp/ppp-options.xml.i>
#include <include/accel-ppp/shaper.xml.i>
#include <include/accel-ppp/snmp.xml.i>
+ #include <include/accel-ppp/thread-count.xml.i>
#include <include/accel-ppp/wins-server.xml.i>
#include <include/generic-description.xml.i>
#include <include/name-server-ipv4-ipv6.xml.i>
diff --git a/interface-definitions/vpn_sstp.xml.in b/interface-definitions/vpn_sstp.xml.in
index 5fd5c95ca..851a202dc 100644
--- a/interface-definitions/vpn_sstp.xml.in
+++ b/interface-definitions/vpn_sstp.xml.in
@@ -50,6 +50,7 @@
#include <include/accel-ppp/ppp-options.xml.i>
#include <include/accel-ppp/shaper.xml.i>
#include <include/accel-ppp/snmp.xml.i>
+ #include <include/accel-ppp/thread-count.xml.i>
#include <include/accel-ppp/wins-server.xml.i>
#include <include/generic-description.xml.i>
#include <include/name-server-ipv4-ipv6.xml.i>
diff --git a/interface-definitions/vrf.xml.in b/interface-definitions/vrf.xml.in
index a20be995a..03128cb99 100644
--- a/interface-definitions/vrf.xml.in
+++ b/interface-definitions/vrf.xml.in
@@ -95,6 +95,15 @@
#include <include/ospfv3/protocol-common-config.xml.i>
</children>
</node>
+ <node name="rpki" owner="${vyos_conf_scripts_dir}/protocols_rpki.py $VAR(../../@)">
+ <properties>
+ <help>Resource Public Key Infrastructure (RPKI)</help>
+ <priority>820</priority>
+ </properties>
+ <children>
+ #include <include/rpki/protocol-common-config.xml.i>
+ </children>
+ </node>
<node name="static" owner="${vyos_conf_scripts_dir}/protocols_static.py $VAR(../../@)">
<properties>
<help>Static Routing</help>
diff --git a/libvyosconfig b/libvyosconfig
-Subproject 58dbb42e827e3d326c6e0e9470334d4d5c7c396
+Subproject 73600f99aa11f01e3f8148da2212abf51a76663
diff --git a/op-mode-definitions/clear-interfaces.xml.in b/op-mode-definitions/clear-interfaces.xml.in
index de2c3443e..4b4362add 100644
--- a/op-mode-definitions/clear-interfaces.xml.in
+++ b/op-mode-definitions/clear-interfaces.xml.in
@@ -12,601 +12,267 @@
<children>
<node name="counters">
<properties>
- <help>Clear interface counters for all interfaces</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters</command>
- </node>
- <tagNode name="connection">
- <properties>
- <help>Bring connection-oriented network interface down and up</help>
- <completionHelp>
- <path>interfaces pppoe</path>
- <path>interfaces sstpc</path>
- <path>interfaces wwan</path>
- </completionHelp>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/connect_disconnect.py --connect --disconnect --interface "$3"</command>
- </tagNode>
- <node name="bonding">
- <properties>
- <help>Clear Bonding interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all bonding interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="bonding">
- <properties>
- <help>Clear interface information for a given bonding interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type bonding</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given bonding interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="bridge">
- <properties>
- <help>Clear Bridge interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all bridge interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="bridge">
- <properties>
- <help>Clear interface information for a given bridge interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type bridge</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given bridge interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="dummy">
- <properties>
- <help>Clear Dummy interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all dummy interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="dummy">
- <properties>
- <help>Clear interface information for a given dummy interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type dummy</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given dummy interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="ethernet">
- <properties>
- <help>Clear Ethernet interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all ethernet interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="ethernet">
- <properties>
- <help>Clear interface information for a given ethernet interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type ethernet</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given ethernet interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="geneve">
- <properties>
- <help>Clear GENEVE interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all GENEVE interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="geneve">
- <properties>
- <help>Clear interface information for a given GENEVE interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type geneve</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given GENEVE interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="input">
- <properties>
- <help>Clear Input (ifb) interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all Input interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="input">
- <properties>
- <help>Clear interface information for a given Input interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type input</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given Input interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="l2tpv3">
- <properties>
- <help>Clear L2TPv3 interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all L2TPv3 interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="l2tpv3">
- <properties>
- <help>Clear interface information for a given L2TPv3 interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type l2tpeth</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given L2TPv3 interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="loopback">
- <properties>
- <help>Clear Loopback interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all loopback interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="loopback">
- <properties>
- <help>Clear interface information for a given loopback interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type loopback</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given loopback interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="macsec">
- <properties>
- <help>Clear MACsec interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all MACsec interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="macsec">
- <properties>
- <help>Clear interface information for a given MACsec interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type macsec</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given MACsec interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="openvpn">
- <properties>
- <help>Clear OpenVPN interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all OpenVPN interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="openvpn">
- <properties>
- <help>Clear interface information for a given OpenVPN interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type openvpn</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given OpenVPN interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="pppoe">
- <properties>
- <help>Clear PPPoE interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all PPPoE interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="pppoe">
- <properties>
- <help>Clear interface information for a given PPPoE interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type pppoe</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given PPPoE interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="pseudo-ethernet">
- <properties>
- <help>Clear Pseudo-Ethernet/MACvlan interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all Pseudo-Ethernet interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="pseudo-ethernet">
- <properties>
- <help>Clear interface information for a given Pseudo-Ethernet interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type pseudo-ethernet</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given Pseudo-Ethernet interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="sstp">
- <properties>
- <help>Clear SSTP interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all SSTP interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
+ <help>Clear interface counters</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters</command>
+ <children>
+ <tagNode name="bonding">
+ <properties>
+ <help>Clear counters for a given bonding interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type bonding</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear bonding interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type bonding</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="bridge">
+ <properties>
+ <help>Clear counters for a given bridge interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type bridge</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear bridge interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type bridge</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="dummy">
+ <properties>
+ <help>Clear counters for a given dummy interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type dummy</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear dummy interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type dummy</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="ethernet">
+ <properties>
+ <help>Clear counters for a given ethernet interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type ethernet</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear ethernet interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type ethernet</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="geneve">
+ <properties>
+ <help>Clear counters for a given GENEVE interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type geneve</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear GENEVE interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type geneve</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="input">
+ <properties>
+ <help>Clear counters for a given Input interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type input</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear input interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type input</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="l2tpv3">
+ <properties>
+ <help>Clear counters for a given L2TPv3 interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type l2tpeth</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear L2TPv3 interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type l2tpeth</command>
+ </standalone>
+ </tagNode>
+ <!-- There's only one loopback in Linux and it's unlikely to change,
+ so we don't need a tag node here. -->
+ <node name="loopback">
+ <properties>
+ <help>Clear loopback interface counters</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name lo</command>
</node>
- </children>
- </node>
- <tagNode name="sstp">
- <properties>
- <help>Clear interface information for a given SSTP interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type sstp</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given SSTP interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="tunnel">
- <properties>
- <help>Clear Tunnel interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all tunnel interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="tunnel">
- <properties>
- <help>Clear interface information for a given tunnel interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type tunnel</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given tunnel interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="virtual-ethernet">
- <properties>
- <help>Clear virtual-ethernet interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all virtual-ethernet interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="virtual-ethernet">
- <properties>
- <help>Clear interface information for a given virtual-ethernet interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type virtual-ethernet</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given virtual-ethernet interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="vti">
- <properties>
- <help>Clear VTI interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all VTI interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="vti">
- <properties>
- <help>Clear interface information for a given VTI interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type vti</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given VTI interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="vxlan">
- <properties>
- <help>Clear VXLAN interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all VXLAN interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="vxlan">
- <properties>
- <help>Clear interface information for a given VXLAN interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type vxlan</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given VXLAN interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="wireguard">
- <properties>
- <help>Clear Wireguard interface information</help>
- </properties>
- <children>
- <node name="counters">
- <properties>
- <help>Clear all Wireguard interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </node>
- </children>
- </node>
- <tagNode name="wireguard">
- <properties>
- <help>Clear interface information for a given Wireguard interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type wireguard</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear interface counters for a given Wireguard interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="wireless">
- <properties>
- <help>Clear Wireless (WLAN) interface information</help>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear all wireless interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </leafNode>
- </children>
- </node>
- <tagNode name="wireless">
- <properties>
- <help>Clear interface information for a given wireless interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type wireless</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
+ <tagNode name="macsec">
+ <properties>
+ <help>Clear counters for a given MACsec interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type macsec</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear MACsec interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type macsec</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="openvpn">
+ <properties>
+ <help>Clear counters for a given OpenVPN interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type openvpn</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear OpenVPN interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type openvpn</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="pppoe">
+ <properties>
+ <help>Clear counters for a given PPPoE interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type pppoe</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear PPPoE interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type pppoe</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="pseudo-ethernet">
+ <properties>
+ <help>Clear counters for a given pseudo-ethernet interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type pseudo-ethernet</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear pseudo-ethernet interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type pseudo-ethernet</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="sstp">
+ <properties>
+ <help>Clear counters for a given SSTP interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type sstp</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear SSTP interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type sstp</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="tunnel">
+ <properties>
+ <help>Clear counters for a given tunnel interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type tunnel</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear tunnel interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type tunnel</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="virtual-ethernet">
+ <properties>
+ <help>Clear counters for a given virtual-ethernet interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type virtual-ethernet</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear virtual-ethernet interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type virtual-ethernet</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="vti">
+ <properties>
+ <help>Clear counters for a given VTI interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type vti</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear VTI interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type vti</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="vxlan">
+ <properties>
+ <help>Clear counters for a given VXLAN interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type vxlan</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear VXLAN interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type vxlan</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="wireguard">
+ <properties>
+ <help>Clear counters for a given WireGuard interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type wireguard</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear WireGuard interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type wireguard</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="wireless">
<properties>
<help>Clear counters for a given wireless interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
- </children>
- </tagNode>
- <node name="wwan">
- <properties>
- <help>Clear Wireless Modem (WWAN) interface information</help>
- </properties>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Clear all WWAN interface counters</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
- </leafNode>
- </children>
- </node>
- <tagNode name="wwan">
- <properties>
- <help>Clear interface information for a given WWAN interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type wwan</script>
- </completionHelp>
- </properties>
- <children>
- <leafNode name="counters">
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type wireless</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear wireless interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type wireless</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="wwan">
<properties>
<help>Clear counters for a given WWAN interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type wwan</script>
+ </completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$5"</command>
+ <standalone>
+ <help>Clear wireless wide area network interface counters</help>
+ <command>${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type wwan</command>
+ </standalone>
+ </tagNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/clear-ip.xml.in b/op-mode-definitions/clear-ip.xml.in
index 3c75ed11b..cbbd462d1 100644
--- a/op-mode-definitions/clear-ip.xml.in
+++ b/op-mode-definitions/clear-ip.xml.in
@@ -7,12 +7,6 @@
<help>Clear Internet Protocol (IP) statistics or status</help>
</properties>
<children>
- <node name="prefix-list">
- <properties>
- <help>Clear prefix-list statistics or status</help>
- </properties>
- <command>vtysh -c "$*"</command>
- </node>
<tagNode name="prefix-list">
<properties>
<help>Clear prefix-list statistics or status for specified word</help>
@@ -20,9 +14,13 @@
<list>&lt;WORD&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Clear prefix-list statistics or status</help>
+ <command>vtysh -c "$*"</command>
+ </standalone>
<command>vtysh -c "$*"</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Clear prefix-list statistics or status for given word|network</help>
<completionHelp>
@@ -30,7 +28,7 @@
</completionHelp>
</properties>
<command>vtysh -c "$*"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
diff --git a/op-mode-definitions/clear-ipv6.xml.in b/op-mode-definitions/clear-ipv6.xml.in
index c062102fc..bdfc9eab7 100644
--- a/op-mode-definitions/clear-ipv6.xml.in
+++ b/op-mode-definitions/clear-ipv6.xml.in
@@ -7,12 +7,6 @@
<help>Clear Internet Protocol (IPv6) statistics or status</help>
</properties>
<children>
- <node name="prefix-list">
- <properties>
- <help>Clear prefix-list statistics or status</help>
- </properties>
- <command>vtysh -c "$*"</command>
- </node>
<tagNode name="prefix-list">
<properties>
<help>Clear prefix-list statistics or status for specified word</help>
@@ -20,9 +14,13 @@
<list>WORD</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Clear prefix-list statistics or status</help>
+ <command>vtysh -c "$*"</command>
+ </standalone>
<command>vtysh -c "$*"</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Clear prefix-list statistics or status for given word|network</help>
<completionHelp>
@@ -30,7 +28,7 @@
</completionHelp>
</properties>
<command>vtysh -c "$*"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
diff --git a/op-mode-definitions/clear-log.xml.in b/op-mode-definitions/clear-log.xml.in
index 1f4a1aacd..5457ce7d6 100644
--- a/op-mode-definitions/clear-log.xml.in
+++ b/op-mode-definitions/clear-log.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Clear contents of current master log file</help>
</properties>
- <command>sudo journalctl --rotate --vacuum-time=1s</command>
+ <command>journalctl --rotate --vacuum-time=1s</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/connect.xml.in b/op-mode-definitions/connect.xml.in
index 9027056a6..73bfb598a 100644
--- a/op-mode-definitions/connect.xml.in
+++ b/op-mode-definitions/connect.xml.in
@@ -24,7 +24,7 @@
<path>interfaces wwan</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/connect_disconnect.py --connect --interface "$3"</command>
+ <command>${vyos_op_scripts_dir}/connect_disconnect.py --connect --interface "$3"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/conntrack-sync.xml.in b/op-mode-definitions/conntrack-sync.xml.in
index a66331f27..d52939bed 100644
--- a/op-mode-definitions/conntrack-sync.xml.in
+++ b/op-mode-definitions/conntrack-sync.xml.in
@@ -11,13 +11,13 @@
<properties>
<help>Reset external cache and request resync with other systems</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py reset_external_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py reset_external_cache</command>
</leafNode>
<leafNode name="internal-cache">
<properties>
<help>Reset internal cache and request resync with other systems</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py reset_internal_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py reset_internal_cache</command>
</leafNode>
</children>
</node>
@@ -29,7 +29,7 @@
<properties>
<help>Restart the connection tracking synchronization service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py restart</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py restart</command>
</leafNode>
</children>
</node>
@@ -49,19 +49,19 @@
<properties>
<help>Show external connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_external_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_external_cache</command>
<children>
<leafNode name="main">
<properties>
<help>Show external main connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_external_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_external_cache</command>
</leafNode>
<leafNode name="expect">
<properties>
<help>Show external expect connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_external_expect</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_external_expect</command>
</leafNode>
</children>
</node>
@@ -69,19 +69,19 @@
<properties>
<help>Show internal connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_internal_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_internal_cache</command>
<children>
<leafNode name="main">
<properties>
<help>Show internal main connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_internal_cache</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_internal_cache</command>
</leafNode>
<leafNode name="expect">
<properties>
<help>Show internal expect connection tracking cache entries</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_internal_expect</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_internal_expect</command>
</leafNode>
</children>
</node>
@@ -91,13 +91,13 @@
<properties>
<help>Show connection syncing statistics</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_statistics</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_statistics</command>
</leafNode>
<leafNode name="status">
<properties>
<help>Show conntrack-sync status</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py show_status</command>
+ <command>${vyos_op_scripts_dir}/conntrack_sync.py show_status</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/container.xml.in b/op-mode-definitions/container.xml.in
index bb6f97b02..70ab4b6e5 100644
--- a/op-mode-definitions/container.xml.in
+++ b/op-mode-definitions/container.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Pull a new image for container</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/container.py add_image --name "${4}"</command>
+ <command>${vyos_op_scripts_dir}/container.py add_image --name "${4}"</command>
</tagNode>
</children>
</node>
@@ -26,7 +26,7 @@
<path>container name</path>
</completionHelp>
</properties>
- <command>sudo podman exec --interactive --tty "$3" /bin/sh</command>
+ <command>podman exec --interactive --tty "$3" /bin/sh</command>
</tagNode>
</children>
</node>
@@ -42,10 +42,10 @@
<help>Delete container image</help>
<completionHelp>
<list>all</list>
- <script>sudo podman image ls -q</script>
+ <script>podman image ls -q</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/container.py delete_image --name "${4}"</command>
+ <command>${vyos_op_scripts_dir}/container.py delete_image --name "${4}"</command>
</tagNode>
</children>
</node>
@@ -70,7 +70,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo podman build --net host --layers --force-rm --tag "$4" $6</command>
+ <command>podman build --net host --layers --force-rm --tag "$4" $6</command>
</tagNode>
</children>
</tagNode>
@@ -89,7 +89,7 @@
<path>container name</path>
</completionHelp>
</properties>
- <command>sudo podman logs --follow --names "$4"</command>
+ <command>${vyos_op_scripts_dir}/container.py show_log --follow --name "$4"</command>
</tagNode>
</children>
</node>
@@ -101,27 +101,27 @@
<properties>
<help>Show containers</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/container.py show_container</command>
+ <command>${vyos_op_scripts_dir}/container.py show_container</command>
<children>
<node name="json">
<properties>
<help>Show containers in JSON format</help>
</properties>
<!-- no admin check -->
- <command>sudo ${vyos_op_scripts_dir}/container.py show_container --raw</command>
+ <command>${vyos_op_scripts_dir}/container.py show_container --raw</command>
</node>
<node name="image">
<properties>
<help>Show container image</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/container.py show_image</command>
+ <command>${vyos_op_scripts_dir}/container.py show_image</command>
<children>
<node name="json">
<properties>
<help>Show container image in JSON format</help>
</properties>
<!-- no admin check -->
- <command>sudo ${vyos_op_scripts_dir}/container.py show_image --raw</command>
+ <command>${vyos_op_scripts_dir}/container.py show_image --raw</command>
</node>
</children>
</node>
@@ -132,22 +132,21 @@
<path>container name</path>
</completionHelp>
</properties>
- <!-- no admin check -->
- <command>sudo podman logs --names "$4"</command>
+ <command>${vyos_op_scripts_dir}/container.py show_log --name "$4"</command>
</tagNode>
<node name="network">
<properties>
<help>Show available container networks</help>
</properties>
<!-- no admin check -->
- <command>sudo ${vyos_op_scripts_dir}/container.py show_network</command>
+ <command>${vyos_op_scripts_dir}/container.py show_network</command>
<children>
<node name="json">
<properties>
<help>Show available container networks in JSON format</help>
</properties>
<!-- no admin check -->
- <command>sudo ${vyos_op_scripts_dir}/container.py show_network --raw</command>
+ <command>${vyos_op_scripts_dir}/container.py show_network --raw</command>
</node>
</children>
</node>
@@ -162,7 +161,7 @@
<path>container name</path>
</completionHelp>
</properties>
- <command>sudo podman logs --names "$4"</command>
+ <command>${vyos_op_scripts_dir}/container.py show_log --name "$4"</command>
</tagNode>
</children>
</node>
@@ -177,7 +176,7 @@
<path>container name</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/container.py restart --name="$3"</command>
+ <command>${vyos_op_scripts_dir}/container.py restart --name="$3"</command>
</tagNode>
</children>
</node>
@@ -198,7 +197,7 @@
<path>container name</path>
</completionHelp>
</properties>
- <command>if cli-shell-api existsActive container name "$4"; then sudo podman pull $(cli-shell-api returnActiveValue container name "$4" image); else echo "Container $4 does not exist"; fi</command>
+ <command>if cli-shell-api existsActive container name "$4"; then podman pull $(cli-shell-api returnActiveValue container name "$4" image); else echo "Container $4 does not exist"; fi</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/crypt.xml.in b/op-mode-definitions/crypt.xml.in
index 105592a1a..5a17cca12 100644
--- a/op-mode-definitions/crypt.xml.in
+++ b/op-mode-definitions/crypt.xml.in
@@ -9,19 +9,19 @@
<properties>
<help>Disable config encryption using TPM or recovery key</help>
</properties>
- <command>sudo ${vyos_libexec_dir}/vyos-config-encrypt.py --disable</command>
+ <command>${vyos_libexec_dir}/vyos-config-encrypt.py --disable</command>
</node>
<node name="enable">
<properties>
<help>Enable config encryption using TPM</help>
</properties>
- <command>sudo ${vyos_libexec_dir}/vyos-config-encrypt.py --enable</command>
+ <command>${vyos_libexec_dir}/vyos-config-encrypt.py --enable</command>
</node>
<node name="load">
<properties>
<help>Load encrypted config volume using TPM or recovery key</help>
</properties>
- <command>sudo ${vyos_libexec_dir}/vyos-config-encrypt.py --load</command>
+ <command>${vyos_libexec_dir}/vyos-config-encrypt.py --load</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/date.xml.in b/op-mode-definitions/date.xml.in
index 4e62a8335..90bddd7f3 100644
--- a/op-mode-definitions/date.xml.in
+++ b/op-mode-definitions/date.xml.in
@@ -35,7 +35,7 @@
<list>&lt;MMDDhhmm&gt; &lt;MMDDhhmmYY&gt; &lt;MMDDhhmmCCYY&gt; &lt;MMDDhhmmCCYY.ss&gt;</list>
</completionHelp>
</properties>
- <command>sudo bash -c "/bin/date '$3' &amp;&amp; hwclock --systohc --localtime"</command>
+ <command>bash -c "/bin/date '$3' &amp;&amp; hwclock --systohc --localtime"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/dhcp.xml.in b/op-mode-definitions/dhcp.xml.in
index 4ee66a90c..2da3bb5dc 100644
--- a/op-mode-definitions/dhcp.xml.in
+++ b/op-mode-definitions/dhcp.xml.in
@@ -171,7 +171,7 @@
<properties>
<help>Show DHCPv6 server leases</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dhcp.py show_server_leases --family inet6</command>
+ <command>${vyos_op_scripts_dir}/dhcp.py show_server_leases --family inet6</command>
<children>
<tagNode name="pool">
<properties>
@@ -262,13 +262,13 @@
<properties>
<help>Restart DHCP server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name dhcp</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name dhcp</command>
</node>
<node name="relay-agent">
<properties>
<help>Restart DHCP relay-agent</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_dhcp_relay.py --ipv4</command>
+ <command>${vyos_op_scripts_dir}/restart_dhcp_relay.py --ipv4</command>
</node>
</children>
</node>
@@ -281,13 +281,13 @@
<properties>
<help>Restart DHCPv6 server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name dhcpv6</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name dhcpv6</command>
</node>
<node name="relay-agent">
<properties>
<help>Restart DHCPv6 relay-agent</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_dhcp_relay.py --ipv6</command>
+ <command>${vyos_op_scripts_dir}/restart_dhcp_relay.py --ipv6</command>
</node>
</children>
</node>
@@ -310,7 +310,7 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dhcp.py renew_client_lease --family inet --interface "$4"</command>
+ <command>${vyos_op_scripts_dir}/dhcp.py renew_client_lease --family inet --interface "$4"</command>
</tagNode>
</children>
</node>
@@ -326,7 +326,7 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dhcp.py renew_client_lease --family inet6 --interface "$4"</command>
+ <command>${vyos_op_scripts_dir}/dhcp.py renew_client_lease --family inet6 --interface "$4"</command>
</tagNode>
</children>
</node>
@@ -349,7 +349,7 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet --interface "$4"</command>
+ <command>${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet --interface "$4"</command>
</tagNode>
</children>
</node>
@@ -365,7 +365,7 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet6 --interface "$4"</command>
+ <command>${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet6 --interface "$4"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/disconnect.xml.in b/op-mode-definitions/disconnect.xml.in
index f0523d9b9..7891a6488 100644
--- a/op-mode-definitions/disconnect.xml.in
+++ b/op-mode-definitions/disconnect.xml.in
@@ -14,7 +14,7 @@
<path>interfaces wwan</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/connect_disconnect.py --disconnect --interface "$3"</command>
+ <command>${vyos_op_scripts_dir}/connect_disconnect.py --disconnect --interface "$3"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/disks.xml.in b/op-mode-definitions/disks.xml.in
index 8a1e2c86f..e3ffe8da9 100644
--- a/op-mode-definitions/disks.xml.in
+++ b/op-mode-definitions/disks.xml.in
@@ -19,7 +19,7 @@
<properties>
<help>Format this disk the same as another disk</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/format_disk.py --by-id --target $4 --proto $6</command>
+ <command>${vyos_op_scripts_dir}/format_disk.py --by-id --target $4 --proto $6</command>
</tagNode>
</children>
</tagNode>
@@ -40,7 +40,7 @@
<script>${vyos_completion_dir}/list_disks.py --exclude ${COMP_WORDS[2]}</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/format_disk.py --target $3 --proto $5</command>
+ <command>${vyos_op_scripts_dir}/format_disk.py --target $3 --proto $5</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/dns-dynamic.xml.in b/op-mode-definitions/dns-dynamic.xml.in
index ef0f03988..1a1176835 100644
--- a/op-mode-definitions/dns-dynamic.xml.in
+++ b/op-mode-definitions/dns-dynamic.xml.in
@@ -16,7 +16,7 @@
<properties>
<help>Clear Dynamic DNS information cache (ddclient)</help>
</properties>
- <command>sudo rm -f /run/ddclient/ddclient.cache</command>
+ <command>rm -f /run/ddclient/ddclient.cache</command>
</leafNode>
</children>
</node>
@@ -78,7 +78,7 @@
<properties>
<help>Show Dynamic DNS status</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dns.py show_dynamic_status</command>
+ <command>${vyos_op_scripts_dir}/dns.py show_dynamic_status</command>
</leafNode>
</children>
</node>
@@ -97,7 +97,7 @@
<properties>
<help>Restart Dynamic DNS service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name dns_dynamic</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name dns_dynamic</command>
</node>
</children>
</node>
@@ -114,7 +114,7 @@
<properties>
<help>Reset Dynamic DNS information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dns.py reset_dynamic</command>
+ <command>${vyos_op_scripts_dir}/dns.py reset_dynamic</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/dns-forwarding.xml.in b/op-mode-definitions/dns-forwarding.xml.in
index fac3fc345..d25be6009 100644
--- a/op-mode-definitions/dns-forwarding.xml.in
+++ b/op-mode-definitions/dns-forwarding.xml.in
@@ -54,7 +54,7 @@
<properties>
<help>Show DNS Forwarding statistics</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/dns.py show_forwarding_statistics</command>
+ <command>${vyos_op_scripts_dir}/dns.py show_forwarding_statistics</command>
</leafNode>
</children>
</node>
@@ -73,7 +73,7 @@
<properties>
<help>Restart DNS Forwarding service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name dns_forwarding</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name dns_forwarding</command>
</leafNode>
</children>
</node>
@@ -92,13 +92,13 @@
</properties>
<children>
<tagNode name="domain">
- <command>sudo ${vyos_op_scripts_dir}/dns.py reset_forwarding --domain $5</command>
+ <command>${vyos_op_scripts_dir}/dns.py reset_forwarding --domain $5</command>
<properties>
<help>Reset DNS Forwarding cache for a domain</help>
</properties>
</tagNode>
<leafNode name="all">
- <command>sudo ${vyos_op_scripts_dir}/dns.py reset_forwarding --all</command>
+ <command>${vyos_op_scripts_dir}/dns.py reset_forwarding --all</command>
<properties>
<help>Reset DNS Forwarding cache for all domains</help>
</properties>
diff --git a/op-mode-definitions/execute-port-scan.xml.in b/op-mode-definitions/execute-port-scan.xml.in
index 52cdab5f0..45221cb4c 100644
--- a/op-mode-definitions/execute-port-scan.xml.in
+++ b/op-mode-definitions/execute-port-scan.xml.in
@@ -16,7 +16,7 @@
</properties>
<command>nmap -p- -T4 --max-retries=1 --host-timeout=30s "$4"</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Port scan options</help>
<completionHelp>
@@ -24,7 +24,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/execute_port-scan.py "${@:4}"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
diff --git a/op-mode-definitions/execute-shell.xml.in b/op-mode-definitions/execute-shell.xml.in
index dfdc1e371..241935607 100644
--- a/op-mode-definitions/execute-shell.xml.in
+++ b/op-mode-definitions/execute-shell.xml.in
@@ -14,7 +14,7 @@
<path>netns name</path>
</completionHelp>
</properties>
- <command>sudo ip netns exec $4 su - $(whoami)</command>
+ <command>ip netns exec $4 su - $(whoami)</command>
</tagNode>
<tagNode name="vrf">
<properties>
@@ -23,7 +23,7 @@
<path>vrf name</path>
</completionHelp>
</properties>
- <command>sudo ip vrf exec $4 su - $(whoami)</command>
+ <command>ip vrf exec $4 su - $(whoami)</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/file.xml.in b/op-mode-definitions/file.xml.in
index 549b9ad92..23c92f2b3 100644
--- a/op-mode-definitions/file.xml.in
+++ b/op-mode-definitions/file.xml.in
@@ -7,7 +7,7 @@
<help>Show the contents of a file, a directory or an image</help>
<completionHelp><imagePath/></completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/file.py --show $3</command>
+ <command>${vyos_op_scripts_dir}/file.py --show $3</command>
</tagNode>
</children>
</node>
@@ -27,7 +27,7 @@
<help>Destination path</help>
<completionHelp><imagePath/></completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/file.py --copy $3 $5
+ <command>${vyos_op_scripts_dir}/file.py --copy $3 $5
</command>
</tagNode>
</children>
@@ -44,7 +44,7 @@
<help>Delete a local file, possibly from an image</help>
<completionHelp><imagePath/></completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/file.py --delete $3</command>
+ <command>${vyos_op_scripts_dir}/file.py --delete $3</command>
</tagNode>
</children>
</node>
@@ -65,7 +65,7 @@
<script>${vyos_completion_dir}/list_images.py --no-running</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/file.py --clone $4</command>
+ <command>${vyos_op_scripts_dir}/file.py --clone $4</command>
<children>
<tagNode name="from">
<properties>
@@ -75,7 +75,7 @@
<script>${vyos_completion_dir}/list_images.py</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/file.py --clone-from $6 $4</command>
+ <command>${vyos_op_scripts_dir}/file.py --clone-from $6 $4</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in
index 82e6c8668..549935de9 100755
--- a/op-mode-definitions/firewall.xml.in
+++ b/op-mode-definitions/firewall.xml.in
@@ -7,36 +7,43 @@
<help>Show firewall information</help>
</properties>
<children>
- <tagNode name="group">
+ <node name="group">
<properties>
<help>Show firewall group</help>
- <completionHelp>
- <path>firewall group address-group</path>
- <path>firewall group network-group</path>
- <path>firewall group port-group</path>
- <path>firewall group interface-group</path>
- <path>firewall group ipv6-address-group</path>
- <path>firewall group ipv6-network-group</path>
- </completionHelp>
</properties>
<children>
- <leafNode name="detail">
+ <virtualTagNode>
<properties>
- <help>Show list view of firewall groups</help>
+ <help>Show firewall group</help>
<completionHelp>
- <path>firewall group detail</path>
+ <path>firewall group address-group</path>
+ <path>firewall group network-group</path>
+ <path>firewall group port-group</path>
+ <path>firewall group domain-group</path>
+ <path>firewall group dynamic-group address-group</path>
+ <path>firewall group dynamic-group ipv6-address-group</path>
+ <path>firewall group interface-group</path>
+ <path>firewall group ipv6-address-group</path>
+ <path>firewall group ipv6-network-group</path>
+ <path>firewall group mac-group</path>
+ <path>firewall group network-group</path>
+ <path>firewall group port-group</path>
+ <path>firewall group remote-group</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group --name $4 --detail $5</command>
- </leafNode>
- </children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group --name $4</command>
- </tagNode>
- <node name="group">
- <properties>
- <help>Show firewall group</help>
- </properties>
- <children>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show list view of firewall groups</help>
+ <completionHelp>
+ <path>firewall group detail</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_group --name $4 --detail $5</command>
+ </leafNode>
+ </children>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_group --name $4</command>
+ </virtualTagNode>
<leafNode name="detail">
<properties>
<help>Show list view of firewall group</help>
@@ -44,10 +51,10 @@
<path>firewall group detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group --detail $4</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_group --detail $4</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_group</command>
</node>
<node name="bridge">
<properties>
@@ -71,7 +78,7 @@
<path>firewall bridge forward filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -88,13 +95,13 @@
<path>firewall bridge forward filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -115,7 +122,7 @@
<path>firewall bridge input filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -132,13 +139,13 @@
<path>firewall bridge input filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -159,7 +166,7 @@
<path>firewall bridge output filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -176,13 +183,13 @@
<path>firewall bridge output filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -203,7 +210,7 @@
<path>firewall bridge prerouting filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -220,13 +227,13 @@
<path>firewall bridge prerouting filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -245,7 +252,7 @@
<path>firewall bridge name detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -262,16 +269,16 @@
<path>firewall bridge name ${COMP_WORDS[4]} rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
</node>
<node name="ipv6">
<properties>
@@ -295,7 +302,7 @@
<path>firewall ipv6 forward filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -312,13 +319,13 @@
<path>firewall ipv6 forward filter rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -339,7 +346,7 @@
<path>firewall ipv6 input filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -356,13 +363,13 @@
<path>firewall ipv6 input filter rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -383,7 +390,7 @@
<path>firewall ipv6 output filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -400,13 +407,13 @@
<path>firewall ipv6 output filter rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -427,7 +434,7 @@
<path>firewall ipv6 prerouting raw detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -444,13 +451,13 @@
<path>firewall ipv6 prerouting raw rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -469,7 +476,7 @@
<path>firewall ipv6 name detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -486,16 +493,16 @@
<path>firewall ipv6 name ${COMP_WORDS[4]} rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
</node>
<node name="ipv4">
<properties>
@@ -519,7 +526,7 @@
<path>firewall ipv4 forward filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -536,13 +543,13 @@
<path>firewall ipv4 forward filter rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -563,7 +570,7 @@
<path>firewall ipv4 input filter detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -580,13 +587,13 @@
<path>firewall ipv4 input filter rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -607,7 +614,7 @@
<path>firewall ipv4 input output detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -624,13 +631,13 @@
<path>firewall ipv4 input output rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -651,7 +658,7 @@
<path>firewall ipv4 prerouting raw detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -668,13 +675,13 @@
<path>firewall ipv4 prerouting raw rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</node>
</children>
</node>
@@ -693,7 +700,7 @@
<path>firewall ipv4 name detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --detail $6</command>
</leafNode>
<tagNode name="rule">
<properties>
@@ -710,16 +717,16 @@
<path>firewall ipv4 name ${COMP_WORDS[4]} rule detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7 --detail $8</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5 --rule $7</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show --family $3 --hook $4 --priority $5</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_family --family $3</command>
</node>
<node name="statistics">
<properties>
@@ -733,16 +740,16 @@
<path>firewall statistics detail</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_statistics --detail $4</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_statistics --detail $4</command>
</leafNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_statistics</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_statistics</command>
</node>
<leafNode name="summary">
<properties>
<help>Show summary of firewall application</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_summary</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_summary</command>
</leafNode>
<node name="zone-policy">
<properties>
@@ -756,13 +763,13 @@
<path>firewall zone</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/zone.py show --zone $5</command>
+ <command>${vyos_op_scripts_dir}/zone.py show --zone $5</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/zone.py show</command>
+ <command>${vyos_op_scripts_dir}/zone.py show</command>
</node>
</children>
- <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_all</command>
+ <command>${vyos_op_scripts_dir}/firewall.py --action show_all</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/flow-accounting-op.xml.in b/op-mode-definitions/flow-accounting-op.xml.in
index 46dc77d05..01686f0aa 100644
--- a/op-mode-definitions/flow-accounting-op.xml.in
+++ b/op-mode-definitions/flow-accounting-op.xml.in
@@ -57,7 +57,7 @@
<properties>
<help>Restart (net)flow accounting process</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/flow_accounting_op.py --action restart</command>
+ <command>${vyos_op_scripts_dir}/flow_accounting_op.py --action restart</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/force-arp.xml.in b/op-mode-definitions/force-arp.xml.in
index 05aa04e6b..368a08ac4 100644
--- a/op-mode-definitions/force-arp.xml.in
+++ b/op-mode-definitions/force-arp.xml.in
@@ -27,13 +27,13 @@
<properties>
<help>Send gratuitous ARP reply for specified address</help>
</properties>
- <command>sudo /usr/bin/arping -I $5 -c 1 -A $7</command>
+ <command>/usr/bin/arping -I $5 -c 1 -A $7</command>
<children>
<tagNode name="count">
<properties>
<help>Send specified number of ARP replies</help>
</properties>
- <command>sudo /usr/bin/arping -I $5 -c $9 -A $7</command>
+ <command>/usr/bin/arping -I $5 -c $9 -A $7</command>
</tagNode>
</children>
</tagNode>
@@ -58,13 +58,13 @@
<properties>
<help>Send gratuitous ARP request for specified address</help>
</properties>
- <command>sudo /usr/bin/arping -I $5 -c 1 -U $7</command>
+ <command>/usr/bin/arping -I $5 -c 1 -U $7</command>
<children>
<tagNode name="count">
<properties>
<help>Send specified number of ARP requests</help>
</properties>
- <command>sudo /usr/bin/arping -I $5 -c $9 -U $7</command>
+ <command>/usr/bin/arping -I $5 -c $9 -U $7</command>
</tagNode>
</children>
</tagNode>
@@ -89,7 +89,7 @@
<properties>
<help>Send ARP for DAD detection for specified address</help>
</properties>
- <command>sudo /usr/bin/arping -I $5 -c 1 -D $7</command>
+ <command>/usr/bin/arping -I $5 -c 1 -D $7</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/force-root-partition-auto-resize.xml.in b/op-mode-definitions/force-root-partition-auto-resize.xml.in
index f84c073b8..dc58a331d 100644
--- a/op-mode-definitions/force-root-partition-auto-resize.xml.in
+++ b/op-mode-definitions/force-root-partition-auto-resize.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Resize the VyOS partition</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/force_root-partition-auto-resize.sh</command>
+ <command>${vyos_op_scripts_dir}/force_root-partition-auto-resize.sh</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/generate-ipsec-debug-archive.xml.in b/op-mode-definitions/generate-ipsec-debug-archive.xml.in
index a9ce113d1..dcbed0c42 100644
--- a/op-mode-definitions/generate-ipsec-debug-archive.xml.in
+++ b/op-mode-definitions/generate-ipsec-debug-archive.xml.in
@@ -8,7 +8,7 @@
<properties>
<help>Generate IPSec debug-archive</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_ipsec_debug_archive.py</command>
+ <command>${vyos_op_scripts_dir}/generate_ipsec_debug_archive.py</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/generate-ipsec-profile.xml.in b/op-mode-definitions/generate-ipsec-profile.xml.in
index afa299da2..b7203d7d1 100644
--- a/op-mode-definitions/generate-ipsec-profile.xml.in
+++ b/op-mode-definitions/generate-ipsec-profile.xml.in
@@ -28,7 +28,7 @@
<script>${vyos_completion_dir}/list_local_ips.sh --both</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7"</command>
+ <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7"</command>
<children>
<tagNode name="name">
<properties>
@@ -37,7 +37,7 @@
<list>&lt;name&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9"</command>
+ <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9"</command>
<children>
<tagNode name="profile">
<properties>
@@ -46,7 +46,7 @@
<list>&lt;name&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9" --profile "${11}"</command>
+ <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9" --profile "${11}"</command>
</tagNode>
</children>
</tagNode>
@@ -57,7 +57,7 @@
<list>&lt;name&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9"</command>
+ <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9"</command>
<children>
<tagNode name="name">
<properties>
@@ -66,7 +66,7 @@
<list>&lt;name&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9" --name "${11}"</command>
+ <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9" --name "${11}"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate-openconnect-user-key.xml.in b/op-mode-definitions/generate-openconnect-user-key.xml.in
index 80cdfb3d7..8a75b09dc 100644
--- a/op-mode-definitions/generate-openconnect-user-key.xml.in
+++ b/op-mode-definitions/generate-openconnect-user-key.xml.in
@@ -24,19 +24,19 @@
<properties>
<help>HOTP time-based token</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits 6</command>
+ <command>${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits 6</command>
<children>
<tagNode name="interval">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits 6</command>
+ <command>${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits 6</command>
<children>
<tagNode name="digits">
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits "${10}"</command>
+ <command>${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits "${10}"</command>
</tagNode>
</children>
</tagNode>
@@ -44,13 +44,13 @@
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits "$8"</command>
+ <command>${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits "$8"</command>
<children>
<tagNode name="interval">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "${10}" --digits $8</command>
+ <command>${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "${10}" --digits $8</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate-openvpn-config-client.xml.in b/op-mode-definitions/generate-openvpn-config-client.xml.in
index fc8bfa346..351742f1e 100644
--- a/op-mode-definitions/generate-openvpn-config-client.xml.in
+++ b/op-mode-definitions/generate-openvpn-config-client.xml.in
@@ -40,10 +40,10 @@
<properties>
<help>Certificate key used by client</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9" --key "${11}"</command>
+ <command>${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9" --key "${11}"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9"</command>
+ <command>${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate-ssh-server-key.xml.in b/op-mode-definitions/generate-ssh-server-key.xml.in
index ecea3e5d1..86bb1b1bd 100644
--- a/op-mode-definitions/generate-ssh-server-key.xml.in
+++ b/op-mode-definitions/generate-ssh-server-key.xml.in
@@ -14,7 +14,7 @@
<properties>
<help>Re-generate SSH host keys and restart SSH server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_ssh_server_key.py</command>
+ <command>${vyos_op_scripts_dir}/generate_ssh_server_key.py</command>
</node>
<tagNode name="client-key">
<properties>
diff --git a/op-mode-definitions/generate-system-login-user.xml.in b/op-mode-definitions/generate-system-login-user.xml.in
index 6f65c12b3..b93cb8beb 100644
--- a/op-mode-definitions/generate-system-login-user.xml.in
+++ b/op-mode-definitions/generate-system-login-user.xml.in
@@ -29,25 +29,25 @@
<properties>
<help>HOTP time-based token</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5"</command>
<children>
<tagNode name="rate-limit">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9"</command>
<children>
<tagNode name="rate-time">
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" </command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" </command>
<children>
<tagNode name="window-size">
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" --window_size "${13}"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" --window_size "${13}"</command>
</tagNode>
</children>
</tagNode>
@@ -57,19 +57,19 @@
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --window_size "${9}"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --window_size "${9}"</command>
<children>
<tagNode name="rate-limit">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --window_size "${9}"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --window_size "${9}"</command>
<children>
<tagNode name="rate-time">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --rate_time "${13}" --window_size "${9}"</command>
+ <command>${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --rate_time "${13}" --window_size "${9}"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate-wireguard.xml.in b/op-mode-definitions/generate-wireguard.xml.in
index 5f2463d1a..0375e6324 100644
--- a/op-mode-definitions/generate-wireguard.xml.in
+++ b/op-mode-definitions/generate-wireguard.xml.in
@@ -31,7 +31,7 @@
<list>&lt;hostname&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8"</command>
+ <command>${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8"</command>
<children>
<tagNode name="address">
<properties>
@@ -40,7 +40,7 @@
<list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8" --address "${10}"</command>
+ <command>${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8" --address "${10}"</command>
<children>
<tagNode name="address">
<properties>
@@ -49,7 +49,7 @@
<list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8" --address "${10}" --address "${12}"</command>
+ <command>${vyos_op_scripts_dir}/wireguard_client.py --name "$4" --interface "$6" --server "$8" --address "${10}" --address "${12}"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate_tech-support_archive.xml.in b/op-mode-definitions/generate_tech-support_archive.xml.in
index fc664eb90..939b3dec4 100644
--- a/op-mode-definitions/generate_tech-support_archive.xml.in
+++ b/op-mode-definitions/generate_tech-support_archive.xml.in
@@ -7,20 +7,31 @@
<help>Generate tech support info</help>
</properties>
<children>
- <node name="archive">
+ <tagNode name="archive">
<properties>
- <help>Generate tech support archive</help>
+ <help>Generate tech support archive to defined location</help>
+ <completionHelp>
+ <list> &lt;file&gt; &lt;scp://user:passwd@host&gt; &lt;ftp://user:passwd@host&gt;</list>
+ </completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/tech_support.py show --raw | gzip> $4.json.gz</command>
- </node>
- <tagNode name="archive">
+ <command>${vyos_op_scripts_dir}/generate_tech-support_archive.py $4</command>
+ <standalone>
+ <help>Generate tech support archive</help>
+ <command>${vyos_op_scripts_dir}/generate_tech-support_archive.py</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="machine-readable-archive">
<properties>
<help>Generate tech support archive to defined location</help>
<completionHelp>
<list> &lt;file&gt; </list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/tech_support.py show --raw | gzip > $4.json.gz</command>
+ <command>${vyos_op_scripts_dir}/tech_support.py show --raw | gzip > $4.json.gz</command>
+ <standalone>
+ <help>Generate a machine-readable tech support archive</help>
+ <command>${vyos_op_scripts_dir}/tech_support.py show --raw | gzip> $4.json.gz</command>
+ </standalone>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/geoip.xml.in b/op-mode-definitions/geoip.xml.in
index c1b6e87b9..66ebfccca 100644
--- a/op-mode-definitions/geoip.xml.in
+++ b/op-mode-definitions/geoip.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Update GeoIP database and firewall sets</help>
</properties>
- <command>sudo ${vyos_libexec_dir}/geoip-update.py --force</command>
+ <command>${vyos_libexec_dir}/geoip-update.py --force</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/igmp-proxy.xml.in b/op-mode-definitions/igmp-proxy.xml.in
index d6ad7ed7e..699d94b3b 100644
--- a/op-mode-definitions/igmp-proxy.xml.in
+++ b/op-mode-definitions/igmp-proxy.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart the IGMP proxy process</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name igmp_proxy</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name igmp_proxy</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/include/bgp/advertised-routes.xml.i b/op-mode-definitions/include/bgp/advertised-routes.xml.i
new file mode 100644
index 000000000..cc3f1f9b5
--- /dev/null
+++ b/op-mode-definitions/include/bgp/advertised-routes.xml.i
@@ -0,0 +1,12 @@
+<!-- included start from bgp/advertised-routes.xml.i -->
+<node name="advertised-routes">
+ <properties>
+ <help>Show routes advertised to a BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/vtysh-generic-detail-wide.xml.i>
+ #include <include/vtysh-generic-wide.xml.i>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/afi-common.xml.i b/op-mode-definitions/include/bgp/afi-common.xml.i
index acf20d950..e5a72f3b1 100644
--- a/op-mode-definitions/include/bgp/afi-common.xml.i
+++ b/op-mode-definitions/include/bgp/afi-common.xml.i
@@ -1,28 +1,4 @@
<!-- included start from bgp/afi-common.xml.i -->
-<tagNode name="community">
- <properties>
- <help>Community number where AA and NN are (0-65535)</help>
- <completionHelp>
- <list>AA:NN</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/bgp/exact-match.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
-<tagNode name="large-community">
- <properties>
- <help>Display routes matching the large-communities</help>
- <completionHelp>
- <list>AA:BB:CC</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/exact-match.xml.i>
- </children>
-</tagNode>
<tagNode name="large-community-list">
<properties>
<help>Display routes matching the large-community-list</help>
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
index 820d507fd..86cd27517 100644
--- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
@@ -4,6 +4,18 @@
<help>Display routes matching the community</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Community number where AA and NN are (0-65535)</help>
+ <completionHelp>
+ <list>AA:NN</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/exact-match.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
<leafNode name="accept-own">
<properties>
<help>Should accept local VPN route if exported and imported into different VRF (well-known community)</help>
@@ -142,13 +154,21 @@
<help>Show BGP routes matching the specified large-communities</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <help>Display routes matching the large-communities</help>
+ <completionHelp>
+ <list>AA:BB:CC</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/exact-match.xml.i>
+ </children>
+ </virtualTagNode>
+ </children>
</node>
-<leafNode name="neighbors">
- <properties>
- <help>Detailed information on TCP and BGP neighbor connections</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</leafNode>
<tagNode name="neighbors">
<properties>
<help>Show BGP information for specified neighbor</help>
@@ -156,63 +176,20 @@
<script>vtysh -c "$(IFS=$' '; echo "${COMP_WORDS[@]:0:${#COMP_WORDS[@]}-2} summary")" | awk '/^[0-9a-f]/ {print $1}'</script>
</completionHelp>
</properties>
+ <standalone>
+ <help>Detailed information on TCP and BGP neighbor connections</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <leafNode name="advertised-routes">
- <properties>
- <help>Show routes advertised to a BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="dampened-routes">
- <properties>
- <help>Show dampened routes received from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="flap-statistics">
- <properties>
- <help>Show flap statistics of the routes learned from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="prefix-counts">
- <properties>
- <help>Show detailed prefix count information for BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <node name="received">
- <properties>
- <help>Show information received from BGP neighbor</help>
- </properties>
- <children>
- <leafNode name="prefix-filter">
- <properties>
- <help>Show prefixlist filter</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- </children>
- </node>
- <leafNode name="filtered-routes">
- <properties>
- <help>Show filtered routes from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="received-routes">
- <properties>
- <help>Show received routes from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="routes">
- <properties>
- <help>Show routes learned from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
+ #include <include/bgp/advertised-routes.xml.i>
+ #include <include/bgp/dampened-routes.xml.i>
+ #include <include/bgp/filtered-routes.xml.i>
+ #include <include/bgp/flap-statistics.xml.i>
+ #include <include/bgp/prefix-counts.xml.i>
+ #include <include/bgp/received.xml.i>
+ #include <include/bgp/received-routes.xml.i>
+ #include <include/bgp/routes.xml.i>
</children>
</tagNode>
<tagNode name="prefix-list">
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i
index 34228fdd1..996e2bd3d 100644
--- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i
@@ -1,16 +1,4 @@
<!-- included start from bgp/afi-ipv4-ipv6-flowspec.xml.i -->
-<tagNode name="flowspec">
- <properties>
- <help>Network in the BGP routing table to display</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/bgp/prefix-bestpath-multipath.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="flowspec">
<properties>
<help>Flowspec Address Family modifier</help>
@@ -19,6 +7,18 @@
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
#include <include/vtysh-generic-detail.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/prefix-bestpath-multipath.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i
index bb95ce3f5..493207f5e 100644
--- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i
@@ -8,7 +8,7 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="">
+ <virtualTagNode>
<properties>
<help>Show IP routes of specified prefix</help>
<completionHelp>
@@ -16,7 +16,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
+ </virtualTagNode>
</children>
</tagNode>
<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn.xml.i
index a9fb6e255..f106b8725 100644
--- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn.xml.i
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-vpn.xml.i
@@ -1,16 +1,4 @@
<!-- included start from bgp/afi-ipv4-ipv6-vpn.xml.i -->
-<tagNode name="vpn">
- <properties>
- <help>Network in the BGP routing table to display</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/bgp/prefix-bestpath-multipath.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="vpn">
<properties>
<help>VPN Address Family modifier</help>
@@ -19,6 +7,18 @@
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-vpn-rd.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/prefix-bestpath-multipath.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
diff --git a/op-mode-definitions/include/bgp/dampened-routes.xml.i b/op-mode-definitions/include/bgp/dampened-routes.xml.i
new file mode 100644
index 000000000..073ca3325
--- /dev/null
+++ b/op-mode-definitions/include/bgp/dampened-routes.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from bgp/dampened-routes.xml.i -->
+<leafNode name="dampened-routes">
+ <properties>
+ <help>Show dampened routes received from BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/filtered-routes.xml.i b/op-mode-definitions/include/bgp/filtered-routes.xml.i
new file mode 100644
index 000000000..a33e8f28f
--- /dev/null
+++ b/op-mode-definitions/include/bgp/filtered-routes.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from bgp/filtered-routes.xml.i -->
+<leafNode name="filtered-routes">
+ <properties>
+ <help>Show filtered routes from BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/flap-statistics.xml.i b/op-mode-definitions/include/bgp/flap-statistics.xml.i
new file mode 100644
index 000000000..93ac110e0
--- /dev/null
+++ b/op-mode-definitions/include/bgp/flap-statistics.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from bgp/flap-statistics.xml.i -->
+<leafNode name="flap-statistics">
+ <properties>
+ <help>Show flap statistics of the routes learned from BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/next-hop.xml.i b/op-mode-definitions/include/bgp/next-hop.xml.i
index 517a44888..23f07e135 100644
--- a/op-mode-definitions/include/bgp/next-hop.xml.i
+++ b/op-mode-definitions/include/bgp/next-hop.xml.i
@@ -5,19 +5,19 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>IPv4/IPv6 nexthop address</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/vtysh-generic-detail.xml.i>
+ </children>
+ </virtualTagNode>
#include <include/vtysh-generic-detail.xml.i>
</children>
</node>
-<tagNode name="nexthop">
- <properties>
- <help>IPv4/IPv6 nexthop address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/vtysh-generic-detail.xml.i>
- </children>
-</tagNode>
<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/prefix-counts.xml.i b/op-mode-definitions/include/bgp/prefix-counts.xml.i
new file mode 100644
index 000000000..a7131ebeb
--- /dev/null
+++ b/op-mode-definitions/include/bgp/prefix-counts.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from bgp/prefix-counts.xml.i -->
+<leafNode name="prefix-counts">
+ <properties>
+ <help>Show detailed prefix count information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/received-routes.xml.i b/op-mode-definitions/include/bgp/received-routes.xml.i
new file mode 100644
index 000000000..55bed7c77
--- /dev/null
+++ b/op-mode-definitions/include/bgp/received-routes.xml.i
@@ -0,0 +1,12 @@
+<!-- included start from bgp/received-routes.xml.i -->
+<node name="received-routes">
+ <properties>
+ <help>Show received routes from a BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/vtysh-generic-detail-wide.xml.i>
+ #include <include/vtysh-generic-wide.xml.i>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/received.xml.i b/op-mode-definitions/include/bgp/received.xml.i
new file mode 100644
index 000000000..bb8dc6981
--- /dev/null
+++ b/op-mode-definitions/include/bgp/received.xml.i
@@ -0,0 +1,16 @@
+<!-- included start from bgp/received.xml.i -->
+<node name="received">
+ <properties>
+ <help>Show information received from BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <leafNode name="prefix-filter">
+ <properties>
+ <help>Show prefixlist filter</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/routes.xml.i b/op-mode-definitions/include/bgp/routes.xml.i
new file mode 100644
index 000000000..248e8fc5c
--- /dev/null
+++ b/op-mode-definitions/include/bgp/routes.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from bgp/routes.xml.i -->
+<leafNode name="routes">
+ <properties>
+ <help>Show routes learned from BGP neighbor</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/show-bgp-common.xml.i b/op-mode-definitions/include/bgp/show-bgp-common.xml.i
index d888bc3b0..0e488d65f 100644
--- a/op-mode-definitions/include/bgp/show-bgp-common.xml.i
+++ b/op-mode-definitions/include/bgp/show-bgp-common.xml.i
@@ -1,23 +1,23 @@
<!-- included start from bgp/show-bgp-common.xml.i -->
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
-<tagNode name="ipv4">
- <properties>
- <help>Network in the BGP routing table to display</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/bgp/prefix-bestpath-multipath.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="ipv4">
<properties>
<help>IPv4 Address Family</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/prefix-bestpath-multipath.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-flowspec.xml.i>
@@ -25,23 +25,23 @@
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
-<tagNode name="ipv6">
- <properties>
- <help>Network in the BGP routing table to display</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/bgp/prefix-bestpath-multipath.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="ipv6">
<properties>
<help>IPv6 Address Family</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/prefix-bestpath-multipath.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-vpn.xml.i>
@@ -53,21 +53,21 @@
<help>Layer 2 Virtual Private Network</help>
</properties>
<children>
- <tagNode name="evpn">
- <properties>
- <help>Network in the BGP routing table to display</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
<node name="evpn">
<properties>
<help>Ethernet Virtual Private Network</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/bgp/afi-common.xml.i>
<node name="all">
<properties>
@@ -128,18 +128,8 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <leafNode name="advertised-routes">
- <properties>
- <help>Show routes advertised to a BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="routes">
- <properties>
- <help>Show routes learned from BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
+ #include <include/bgp/advertised-routes.xml.i>
+ #include <include/bgp/routes.xml.i>
</children>
</tagNode>
<leafNode name="next-hops">
@@ -198,13 +188,20 @@
#include <include/vni-tagnode-all.xml.i>
</children>
</node>
- #include <include/vni-tagnode.xml.i>
- <leafNode name="vni">
+ <tagNode name="vni">
<properties>
- <help>VXLAN network identifier (VNI)</help>
+ <help>VXLAN network identifier (VNI) number</help>
+ <completionHelp>
+ <list>&lt;1-16777215&gt;</list>
+ <script>${vyos_completion_dir}/list_vni.sh</script>
+ </completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
+ <standalone>
+ <help>VXLAN network identifier (VNI)</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
+ <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
+ </tagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/include/bgp/show-ip-bgp-common.xml.i b/op-mode-definitions/include/bgp/show-ip-bgp-common.xml.i
index db9021f3e..bb62fd1bb 100644
--- a/op-mode-definitions/include/bgp/show-ip-bgp-common.xml.i
+++ b/op-mode-definitions/include/bgp/show-ip-bgp-common.xml.i
@@ -37,18 +37,21 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <leafNode name="cidr-only">
+ <virtualTagNode>
<properties>
- <help>Display only routes with non-natural netmasks</help>
+ <help>Show BGP information for specified IP address or prefix</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
+ </completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <node name="community">
+ </virtualTagNode>
+ <leafNode name="cidr-only">
<properties>
- <help>Show BGP routes matching the communities</help>
+ <help>Display only routes with non-natural netmasks</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
+ </leafNode>
<tagNode name="community">
<properties>
<help>Display routes matching the specified communities</help>
@@ -56,6 +59,10 @@
<list>&lt;AA:NN&gt; local-AS no-advertise no-export</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show BGP routes matching the communities</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
<tagNode name="community-list">
@@ -81,36 +88,14 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <leafNode name="advertised-routes">
- <properties>
- <help>Show routes advertised to a BGP neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="prefix-counts">
- <properties>
- <help>Show detailed prefix count information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="filtered-routes">
- <properties>
- <help>Show the filtered routes from neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="received-routes">
- <properties>
- <help>Show the received routes from neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- <leafNode name="routes">
- <properties>
- <help>Show routes learned from neighbor</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
+ #include <include/bgp/advertised-routes.xml.i>
+ #include <include/bgp/dampened-routes.xml.i>
+ #include <include/bgp/filtered-routes.xml.i>
+ #include <include/bgp/flap-statistics.xml.i>
+ #include <include/bgp/prefix-counts.xml.i>
+ #include <include/bgp/received.xml.i>
+ #include <include/bgp/received-routes.xml.i>
+ #include <include/bgp/routes.xml.i>
</children>
</tagNode>
<leafNode name="paths">
@@ -145,15 +130,6 @@
</leafNode>
</children>
</node>
- <tagNode name="unicast">
- <properties>
- <help>Show BGP information for specified IP address or prefix</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
</children>
</node>
<leafNode name="large-community-info">
diff --git a/op-mode-definitions/include/isis-common.xml.i b/op-mode-definitions/include/isis-common.xml.i
index 493a56633..cda46736d 100644
--- a/op-mode-definitions/include/isis-common.xml.i
+++ b/op-mode-definitions/include/isis-common.xml.i
@@ -4,19 +4,19 @@
<help>Show IS-IS link state database</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show IS-IS link state database PDU</help>
+ <completionHelp>
+ <list>lsp-id detail</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/vtysh-generic-detail.xml.i>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
-<tagNode name="database">
- <properties>
- <help>Show IS-IS link state database PDU</help>
- <completionHelp>
- <list>lsp-id detail</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="fast-reroute">
<properties>
<help>Show IS-IS fast reroute/loop free alternate (lfa) information</help>
@@ -59,10 +59,10 @@
</properties>
<children>
#include <include/vtysh-generic-detail.xml.i>
+ #include <include/vtysh-generic-interface-virtualTagNode.xml.i>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
-#include <include/vtysh-generic-interface-tagNode.xml.i>
<node name="mpls">
<properties>
<help>Show MPLS information</help>
@@ -82,13 +82,19 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</leafNode>
- <leafNode name="interface">
+ <tagNode name="interface">
<properties>
- <help>Show interface information</help>
+ <help>Show information about specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces</script>
+ </completionHelp>
</properties>
+ <standalone>
+ <help>Show interface information</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- #include <include/vtysh-generic-interface-tagNode.xml.i>
+ </tagNode>
</children>
</node>
<node name="neighbor">
@@ -96,19 +102,19 @@
<help>Show IS-IS neighbor adjacencies</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show specific IS-IS neighbor adjacency </help>
+ <completionHelp>
+ <list>system-id</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/vtysh-generic-detail.xml.i>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
-<tagNode name="neighbor">
- <properties>
- <help>Show specific IS-IS neighbor adjacency </help>
- <completionHelp>
- <list>system-id</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="route">
<properties>
<help>Show IS-IS routing table</help>
@@ -180,4 +186,4 @@
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
-<!-- included end --> \ No newline at end of file
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospf/common.xml.i b/op-mode-definitions/include/ospf/common.xml.i
index 684073cc5..1ffe246e4 100644
--- a/op-mode-definitions/include/ospf/common.xml.i
+++ b/op-mode-definitions/include/ospf/common.xml.i
@@ -17,106 +17,86 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF ASBR summary database for given address of advertised router</help>
+ <help>Show IPv4 OSPF ASBR summary database information of given address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF ASBR summary database for given address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="asbr-summary">
- <properties>
- <help>Show IPv4 OSPF ASBR summary database information of given address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF ASBR summary database of given address for given advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show summary of self-originate IPv4 OSPF ASBR database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF ASBR summary database of given address for given advertised router</help>
+ <help>Show IPv4 OSPF ASBR summary database for given address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show summary of self-originate IPv4 OSPF ASBR database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="external">
<properties>
<help>Show IPv4 OSPF external database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF external database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF external database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF external database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="external">
- <properties>
- <help>Show IPv4 OSPF external database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF external database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF external database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF external database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF external database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF external database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<leafNode name="max-age">
<properties>
<help>Show IPv4 OSPF max-age database</help>
@@ -129,318 +109,258 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF network database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF network database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF network database for given address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="network">
- <properties>
- <help>Show IPv4 OSPF network database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF network database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF network database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF network database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF network database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF network database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="nssa-external">
<properties>
<help>Show IPv4 OSPF NSSA external database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF NSSA external database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF NSSA external database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF NSSA external database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="nssa-external">
- <properties>
- <help>Show IPv4 OSPF NSSA external database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF NSSA external database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF NSSA external database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF NSSA external database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF NSSA external database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF NSSA external database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="opaque-area">
<properties>
<help>Show IPv4 OSPF opaque-area database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF opaque-area database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF opaque-area database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF opaque-area database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="opaque-area">
- <properties>
- <help>Show IPv4 OSPF opaque-area database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF opaque-area database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF opaque-area database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF opaque-area database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF opaque-area database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF opaque-area database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="opaque-as">
<properties>
<help>Show IPv4 OSPF opaque-as database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF opaque-as database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF opaque-as database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF opaque-as database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="opaque-as">
- <properties>
- <help>Show IPv4 OSPF opaque-as database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF opaque-as database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF opaque-as database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF opaque-as database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF opaque-as database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF opaque-as database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="opaque-link">
<properties>
<help>Show IPv4 OSPF opaque-link database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF opaque-link database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF opaque-link database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF opaque-link database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="opaque-link">
- <properties>
- <help>Show IPv4 OSPF opaque-link database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF opaque-link database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF opaque-link database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF opaque-link database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF opaque-link database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF opaque-link database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<node name="router">
<properties>
<help>Show IPv4 OSPF router database</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF router database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF router database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF router database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="router">
- <properties>
- <help>Show IPv4 OSPF router database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF router database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF router database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF router database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF router database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF router database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
<leafNode name="self-originate">
<properties>
<help>Show IPv4 OSPF self-originate database</help>
@@ -453,63 +373,59 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="adv-router">
+ <virtualTagNode>
<properties>
- <help>Show IPv4 OSPF summary database for specified IP address of advertised router</help>
+ <help>Show IPv4 OSPF summary database information of specified IP address</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="adv-router">
- <properties>
- <help>Show IPv4 OSPF summary database for specified IP address of advertised router</help>
- </properties>
- </node>
- </children>
- </node>
- <tagNode name="summary">
- <properties>
- <help>Show IPv4 OSPF summary database information of specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="adv-router">
- <properties>
- <help>Show advertising router link states</help>
- </properties>
- </node>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Show IPv4 OSPF summary database of specified IP address for specified advertised router</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ <leafNode name="self-originate">
+ <properties>
+ <help>Show self-originate IPv4 OSPF summary database</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<tagNode name="adv-router">
<properties>
- <help>Show IPv4 OSPF summary database of specified IP address for specified advertised router</help>
+ <help>Show IPv4 OSPF summary database for specified IP address of advertised router</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
- <leafNode name="self-originate">
- <properties>
- <help>Show self-originate IPv4 OSPF summary database</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
#include <include/ospf/graceful-restart.xml.i>
-<node name="interface">
+<tagNode name="interface">
<properties>
- <help>Show IPv4 OSPF interface information</help>
+ <help>Show information about specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces</script>
+ </completionHelp>
</properties>
+ <standalone>
+ <help>Show IPv4 OSPF interface information</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</node>
-#include <include/vtysh-generic-interface-tagNode.xml.i>
+</tagNode>
<node name="mpls">
<properties>
<help>Show MPLS information</help>
@@ -524,19 +440,19 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show IPv4 OSPF neighbor information for specified IP address or interface</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ <script>${vyos_completion_dir}/list_interfaces</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/frr-detail.xml.i>
</children>
</node>
-<tagNode name="neighbor">
- <properties>
- <help>Show IPv4 OSPF neighbor information for specified IP address or interface</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- <script>${vyos_completion_dir}/list_interfaces</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<node name="route">
<properties>
<help>Show IPv4 OSPF route information</help>
diff --git a/op-mode-definitions/include/ospfv3/border-routers.xml.i b/op-mode-definitions/include/ospfv3/border-routers.xml.i
index e8827a2c4..4abd89e6b 100644
--- a/op-mode-definitions/include/ospfv3/border-routers.xml.i
+++ b/op-mode-definitions/include/ospfv3/border-routers.xml.i
@@ -5,16 +5,16 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Border router ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </virtualTagNode>
#include <include/frr-detail.xml.i>
</children>
</node>
-<tagNode name="border-routers">
- <properties>
- <help>Border router ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
-</tagNode>
<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/database.xml.i b/op-mode-definitions/include/ospfv3/database.xml.i
index fdc45f184..d4e7ab695 100644
--- a/op-mode-definitions/include/ospfv3/database.xml.i
+++ b/op-mode-definitions/include/ospfv3/database.xml.i
@@ -21,7 +21,7 @@
<help>Search by Any Link state Type</help>
</properties>
<children>
- <tagNode name="any">
+ <virtualTagNode>
<properties>
<help>Search by Link state ID</help>
<completionHelp>
@@ -32,31 +32,32 @@
#include <include/frr-detail.xml.i>
#include <include/ospfv3/dump.xml.i>
#include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/adv-router-id-node-tag.xml.i>
</children>
- </tagNode>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="any">
- <properties>
- <help>Search by Link state ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ipv6 ospf6 database * $6"</command>
- <children>
- #include <include/frr-detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/adv-router-id-node-tag.xml.i>
- </children>
- </tagNode>
<node name="as-external">
<properties>
<help>Show AS-External LSAs</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Search by Advertising Router IDs</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/frr-detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ #include <include/ospfv3/adv-router-id-node-tag.xml.i>
+ </children>
+ </virtualTagNode>
#include <include/ospfv3/adv-router.xml.i>
<tagNode name="any">
<properties>
@@ -79,21 +80,6 @@
#include <include/ospfv3/self-originated.xml.i>
</children>
</node>
- <tagNode name="as-external">
- <properties>
- <help>Search by Advertising Router IDs</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/frr-detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- #include <include/ospfv3/adv-router-id-node-tag.xml.i>
- </children>
- </tagNode>
#include <include/frr-detail.xml.i>
#include <include/ospfv3/internal.xml.i>
#include <include/ospfv3/linkstate-id.xml.i>
@@ -188,7 +174,7 @@
#include <include/ospfv3/self-originated.xml.i>
</children>
</node>
- <node name="node.tag">
+ <virtualTagNode>
<properties>
<help>Show LSAs</help>
</properties>
@@ -202,7 +188,7 @@
#include <include/ospfv3/linkstate-id-node-tag.xml.i>
#include <include/ospfv3/self-originated.xml.i>
</children>
- </node>
+ </virtualTagNode>
<node name="router">
<properties>
<help>Show router LSAs</help>
diff --git a/op-mode-definitions/include/ospfv3/interface.xml.i b/op-mode-definitions/include/ospfv3/interface.xml.i
index 45d5dbd45..a918651cf 100644
--- a/op-mode-definitions/include/ospfv3/interface.xml.i
+++ b/op-mode-definitions/include/ospfv3/interface.xml.i
@@ -5,71 +5,71 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <node name="prefix">
+ <virtualTagNode>
<properties>
- <help>Show connected prefixes to advertise</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/frr-detail.xml.i>
- </children>
- </node>
- <tagNode name="prefix">
- <properties>
- <help>Show interface prefix route specific information</help>
+ <help>Specific insterface to examine</help>
<completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ <script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- #include <include/frr-detail.xml.i>
- <node name="match">
+ <node name="prefix">
<properties>
- <help>Matched interface prefix information</help>
+ <help>Show connected prefixes to advertise</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <help>Show interface prefix route specific information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/frr-detail.xml.i>
+ <node name="match">
+ <properties>
+ <help>Matched interface prefix information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </virtualTagNode>
+ #include <include/frr-detail.xml.i>
+ </children>
</node>
</children>
- </tagNode>
- </children>
-</node>
-<tagNode name="interface">
- <properties>
- <help>Specific insterface to examine</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
+ </virtualTagNode>
<node name="prefix">
<properties>
<help>Show connected prefixes to advertise</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- #include <include/frr-detail.xml.i>
- </children>
- </node>
- <tagNode name="prefix">
- <properties>
- <help>Show interface prefix route specific information</help>
- <completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/frr-detail.xml.i>
- <node name="match">
+ <virtualTagNode>
<properties>
- <help>Matched interface prefix information</help>
+ <help>Show interface prefix route specific information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
+ <children>
+ #include <include/frr-detail.xml.i>
+ <node name="match">
+ <properties>
+ <help>Matched interface prefix information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </virtualTagNode>
+ #include <include/frr-detail.xml.i>
</children>
- </tagNode>
+ </node>
</children>
-</tagNode>
+</node>
<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/linkstate-id-node-tag.xml.i b/op-mode-definitions/include/ospfv3/linkstate-id-node-tag.xml.i
index 66674e754..b5aed4c0a 100644
--- a/op-mode-definitions/include/ospfv3/linkstate-id-node-tag.xml.i
+++ b/op-mode-definitions/include/ospfv3/linkstate-id-node-tag.xml.i
@@ -1,5 +1,5 @@
<!-- included start from ospfv3/linkstate-id-node-tag.xml.i -->
-<node name="node.tag">
+<virtualTagNode>
<properties>
<help>Search by Link state ID</help>
<completionHelp>
@@ -13,5 +13,5 @@
#include <include/ospfv3/internal.xml.i>
#include <include/ospfv3/self-originated.xml.i>
</children>
-</node>
+</virtualTagNode>
<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/linkstate.xml.i b/op-mode-definitions/include/ospfv3/linkstate.xml.i
index 030dc7923..3a08d748f 100644
--- a/op-mode-definitions/include/ospfv3/linkstate.xml.i
+++ b/op-mode-definitions/include/ospfv3/linkstate.xml.i
@@ -13,7 +13,7 @@
</completionHelp>
</properties>
<children>
- <node name="node.tag">
+ <virtualTagNode>
<properties>
<help>Specify Link state ID as IPv4 address notation</help>
<completionHelp>
@@ -21,7 +21,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
+ </virtualTagNode>
</children>
</tagNode>
<tagNode name="router">
diff --git a/op-mode-definitions/include/ospfv3/route.xml.i b/op-mode-definitions/include/ospfv3/route.xml.i
index a5b97cd05..0128bac1b 100644
--- a/op-mode-definitions/include/ospfv3/route.xml.i
+++ b/op-mode-definitions/include/ospfv3/route.xml.i
@@ -5,6 +5,32 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified route/prefix information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="longer">
+ <properties>
+ <help>Show routes longer than specified prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ <node name="match">
+ <properties>
+ <help>Show routes matching specified prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/frr-detail.xml.i>
+ </children>
+ </node>
+ </children>
+ </virtualTagNode>
<node name="external-1">
<properties>
<help>Show Type-1 External route information</help>
@@ -50,30 +76,4 @@
</node>
</children>
</node>
-<tagNode name="route">
- <properties>
- <help>Show specified route/prefix information</help>
- <completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="longer">
- <properties>
- <help>Show routes longer than specified prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- <node name="match">
- <properties>
- <help>Show routes matching specified prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/frr-detail.xml.i>
- </children>
- </node>
- </children>
-</tagNode>
<!-- included end -->
diff --git a/op-mode-definitions/include/rpki/vrf.xml.i b/op-mode-definitions/include/rpki/vrf.xml.i
new file mode 100644
index 000000000..5b6518fee
--- /dev/null
+++ b/op-mode-definitions/include/rpki/vrf.xml.i
@@ -0,0 +1,11 @@
+<!-- include start from rpki/vrf.xml.i -->
+<tagNode name="vrf">
+ <properties>
+ <help>Virtual Routing and Forwarding (VRF)</help>
+ <completionHelp>
+ <path>vrf name</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<!-- include end -->
diff --git a/op-mode-definitions/include/show-route-table.xml.i b/op-mode-definitions/include/show-route-table.xml.i
index c3cf82a86..7c0f574c8 100644
--- a/op-mode-definitions/include/show-route-table.xml.i
+++ b/op-mode-definitions/include/show-route-table.xml.i
@@ -1,12 +1,7 @@
<!-- included start from show-route-table.xml.i -->
-<node name="table">
- <properties>
- <help>Table to display</help>
- </properties>
-</node>
<tagNode name="table">
<properties>
- <help>The table number to display</help>
+ <help>Show routes in specific routing table</help>
<completionHelp>
<list>all</list>
<path>protocols static table</path>
diff --git a/op-mode-definitions/include/show-route-tag.xml.i b/op-mode-definitions/include/show-route-tag.xml.i
index 8bfa0ae4e..c7279e82e 100644
--- a/op-mode-definitions/include/show-route-tag.xml.i
+++ b/op-mode-definitions/include/show-route-tag.xml.i
@@ -1,12 +1,7 @@
<!-- included start from show-route-tag.xml.i -->
-<node name="tag">
- <properties>
- <help>Show only routes with tag</help>
- </properties>
-</node>
<tagNode name="tag">
<properties>
- <help>Tag value</help>
+ <help>Show route with given tag</help>
<completionHelp>
<list>&lt;1-4294967295&gt;</list>
</completionHelp>
diff --git a/op-mode-definitions/include/vtysh-generic-detail-wide.xml.i b/op-mode-definitions/include/vtysh-generic-detail-wide.xml.i
new file mode 100644
index 000000000..98ce09948
--- /dev/null
+++ b/op-mode-definitions/include/vtysh-generic-detail-wide.xml.i
@@ -0,0 +1,11 @@
+<!-- included start from vtysh-generic-detail-wide.xml.i -->
+<node name="detail">
+ <properties>
+ <help>Detailed information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/vtysh-generic-wide.xml.i>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/vtysh-generic-interface-virtualTagNode.xml b/op-mode-definitions/include/vtysh-generic-interface-virtualTagNode.xml
new file mode 100644
index 000000000..1dfcfc75e
--- /dev/null
+++ b/op-mode-definitions/include/vtysh-generic-interface-virtualTagNode.xml
@@ -0,0 +1,11 @@
+<!-- included start from vtysh-generic-interface-virtualTagNode.xml.i -->
+<virtualTagNode>
+ <properties>
+ <help>Show information about specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</virtualTagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/install-mok.xml.in b/op-mode-definitions/install-mok.xml.in
index c7e62349a..ab8e5d3db 100644
--- a/op-mode-definitions/install-mok.xml.in
+++ b/op-mode-definitions/install-mok.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Install Secure Boot MOK (Machine Owner Key)</help>
</properties>
- <command>if test -f /var/lib/shim-signed/mok/vyos-dev-2025-shim.der; then sudo mokutil --ignore-keyring --import /var/lib/shim-signed/mok/vyos-dev-2025-shim.der; else echo "Secure Boot Machine Owner Key not found"; fi</command>
+ <command>${vyos_op_scripts_dir}/install_mok.sh</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/ipv4-route.xml.in b/op-mode-definitions/ipv4-route.xml.in
index 17a0a4ad9..41a4b62ba 100644
--- a/op-mode-definitions/ipv4-route.xml.in
+++ b/op-mode-definitions/ipv4-route.xml.in
@@ -39,7 +39,7 @@
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/neighbor.py reset --family inet --address "$5"</command>
+ <command>${vyos_op_scripts_dir}/neighbor.py reset --family inet --address "$5"</command>
</tagNode>
<tagNode name="interface">
<properties>
@@ -48,13 +48,13 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/neighbor.py reset --family inet --interface "$5"</command>
+ <command>${vyos_op_scripts_dir}/neighbor.py reset --family inet --interface "$5"</command>
</tagNode>
<node name="table">
<properties>
<help>Flush the ARP cache completely</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/neighbor.py reset --family inet</command>
+ <command>${vyos_op_scripts_dir}/neighbor.py reset --family inet</command>
</node>
</children>
</node>
@@ -63,12 +63,6 @@
<help>Reset IP route</help>
</properties>
<children>
- <leafNode name= "cache">
- <properties>
- <help>Flush the kernel route cache</help>
- </properties>
- <command>sudo ip route flush cache</command>
- </leafNode>
<tagNode name="cache">
<properties>
<help>Flush the kernel route cache for a given route</help>
@@ -76,7 +70,11 @@
<list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ip route flush cache "$5"</command>
+ <standalone>
+ <help>Flush the kernel route cache</help>
+ <command>ip route flush cache</command>
+ </standalone>
+ <command>ip route flush cache "$5"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/ipv6-route.xml.in b/op-mode-definitions/ipv6-route.xml.in
index 5ed0b9dba..7ea5a13f6 100644
--- a/op-mode-definitions/ipv6-route.xml.in
+++ b/op-mode-definitions/ipv6-route.xml.in
@@ -65,7 +65,7 @@
<list>&lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ip -f inet6 neigh flush to "$5"</command>
+ <command>ip -f inet6 neigh flush to "$5"</command>
</tagNode>
<tagNode name="interface">
<properties>
@@ -74,7 +74,7 @@
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
- <command>sudo ip -f inet6 neigh flush dev "$5"</command>
+ <command>ip -f inet6 neigh flush dev "$5"</command>
</tagNode>
</children>
</node>
@@ -83,12 +83,6 @@
<help>Reset IPv6 route</help>
</properties>
<children>
- <leafNode name= "cache">
- <properties>
- <help>Flush the kernel IPv6 route cache</help>
- </properties>
- <command>sudo ip -f inet6 route flush cache</command>
- </leafNode>
<tagNode name="cache">
<properties>
<help>Flush the kernel IPv6 route cache for a given route</help>
@@ -96,7 +90,11 @@
<list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ip -f inet6 route flush cache "$5"</command>
+ <standalone>
+ <help>Flush the kernel IPv6 route cache</help>
+ <command>ip -f inet6 route flush cache</command>
+ </standalone>
+ <command>ip -f inet6 route flush cache "$5"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/load-balancing_haproxy.xml.in b/op-mode-definitions/load-balancing_haproxy.xml.in
index 8de7ae97f..8692a7367 100644
--- a/op-mode-definitions/load-balancing_haproxy.xml.in
+++ b/op-mode-definitions/load-balancing_haproxy.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart haproxy service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name haproxy</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name haproxy</command>
</node>
</children>
</node>
@@ -16,7 +16,7 @@
<properties>
<help>Show load-balancing haproxy</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/load-balancing_haproxy.py show</command>
+ <command>${vyos_op_scripts_dir}/load-balancing_haproxy.py show</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/load-balancing_wan.xml.in b/op-mode-definitions/load-balancing_wan.xml.in
index 91c57c1f4..652b01eda 100644
--- a/op-mode-definitions/load-balancing_wan.xml.in
+++ b/op-mode-definitions/load-balancing_wan.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart Wide Area Network (WAN) load-balancing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name load-balancing_wan</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name load-balancing_wan</command>
</node>
</children>
</node>
@@ -34,4 +34,4 @@
</node>
</children>
</node>
-</interfaceDefinition> \ No newline at end of file
+</interfaceDefinition>
diff --git a/op-mode-definitions/mdns-reflector.xml.in b/op-mode-definitions/mdns-reflector.xml.in
index 115b2858c..6fe412334 100644
--- a/op-mode-definitions/mdns-reflector.xml.in
+++ b/op-mode-definitions/mdns-reflector.xml.in
@@ -53,7 +53,7 @@
<properties>
<help>Restart mDNS repeater service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name mdns_repeater</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name mdns_repeater</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/monitor-bridge.xml.in b/op-mode-definitions/monitor-bridge.xml.in
index a43fa6dd9..ae98ec3ea 100644
--- a/op-mode-definitions/monitor-bridge.xml.in
+++ b/op-mode-definitions/monitor-bridge.xml.in
@@ -6,22 +6,22 @@
<properties>
<help>Monitor bridge database changes</help>
</properties>
- <command>sudo bridge monitor all</command>
+ <command>bridge monitor all</command>
<children>
<node name="link">
- <command>sudo bridge monitor link</command>
+ <command>bridge monitor link</command>
<properties>
<help>Monitor bridge database generated connection interface changes</help>
</properties>
</node>
<node name="fdb">
- <command>sudo bridge monitor fdb</command>
+ <command>bridge monitor fdb</command>
<properties>
<help>Monitor the forwarding database changes generated by the bridge database</help>
</properties>
</node>
<node name="mdb">
- <command>sudo bridge monitor mdb</command>
+ <command>bridge monitor mdb</command>
<properties>
<help>Monitor the multicast database changes generated by the bridge database</help>
</properties>
diff --git a/op-mode-definitions/monitor-command.xml.in b/op-mode-definitions/monitor-command.xml.in
index 31c68f029..ba242386e 100644
--- a/op-mode-definitions/monitor-command.xml.in
+++ b/op-mode-definitions/monitor-command.xml.in
@@ -2,26 +2,31 @@
<interfaceDefinition>
<node name="monitor">
<children>
- <tagNode name="command">
+ <node name="command">
<properties>
- <help>Monitor operational mode command (refreshes every 2 seconds)</help>
+ <help>Monitor operational mode command output</help>
</properties>
- <command>watch --no-title ${vyos_op_scripts_dir}/vyos-op-cmd-wrapper.sh ${@:3}</command>
- </tagNode>
- <node name="command">
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Monitor operational mode command (refreshes every 2 seconds)</help>
+ </properties>
+ <command>watch --no-title ${vyos_op_scripts_dir}/vyos-op-cmd-wrapper.sh ${@:3}</command>
+ </virtualTagNode>
<node name="diff">
<properties>
<help>Show differences during each run</help>
</properties>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <help>Monitor operational mode command (refreshes every 2 seconds)</help>
+ </properties>
+ <command>watch --no-title --differences ${vyos_op_scripts_dir}/vyos-op-cmd-wrapper.sh ${@:4}</command>
+ </virtualTagNode>
+ </children>
</node>
- <tagNode name="diff">
- <properties>
- <help>Monitor operational mode command (refreshes every 2 seconds)</help>
- </properties>
- <command>watch --no-title --differences ${vyos_op_scripts_dir}/vyos-op-cmd-wrapper.sh ${@:4}</command>
- </tagNode>
- </children>
+ </children>
</node>
</children>
</node>
diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in
index b9ef8f48e..721460be5 100644
--- a/op-mode-definitions/monitor-log.xml.in
+++ b/op-mode-definitions/monitor-log.xml.in
@@ -17,24 +17,11 @@
</properties>
<command>SYSTEMD_COLORS=false grc journalctl --no-hostname --follow --boot</command>
</node>
- <node name="ids">
- <properties>
- <help>Monitor Intrusion Detection System log</help>
- </properties>
- <children>
- <leafNode name="ddos-protection">
- <properties>
- <help>Monitor last lines of DDOS protection</help>
- </properties>
- <command>journalctl --no-hostname --follow --boot --unit fastnetmon.service</command>
- </leafNode>
- </children>
- </node>
<leafNode name="certbot">
<properties>
<help>Monitor last lines of certbot log</help>
</properties>
- <command>if sudo test -f /var/log/letsencrypt/letsencrypt.log; then sudo tail --follow=name /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
+ <command>if test -f /var/log/letsencrypt/letsencrypt.log; then tail --follow=name /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
</leafNode>
<leafNode name="conntrack-sync">
<properties>
@@ -120,6 +107,12 @@
</properties>
<command>journalctl --no-hostname --boot --follow --unit frr.service</command>
</leafNode>
+ <leafNode name="haproxy">
+ <properties>
+ <help>Monitor last lines of HAProxy log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit haproxy.service</command>
+ </leafNode>
<leafNode name="ipoe-server">
<properties>
<help>Monitor last lines of IP over Ethernet server log</help>
@@ -138,12 +131,6 @@
</properties>
<command>journalctl --no-hostname --boot --follow --unit ndppd.service</command>
</leafNode>
- <leafNode name="nhrp">
- <properties>
- <help>Monitor last lines of Next Hop Resolution Protocol log</help>
- </properties>
- <command>journalctl --no-hostname --boot --follow --unit opennhrp.service</command>
- </leafNode>
<leafNode name="ntp">
<properties>
<help>Monitor last lines of Network Time Protocol log</help>
diff --git a/op-mode-definitions/monitor-ndp.xml.in b/op-mode-definitions/monitor-ndp.xml.in
index 3b08f3d73..a40c4f25c 100644
--- a/op-mode-definitions/monitor-ndp.xml.in
+++ b/op-mode-definitions/monitor-ndp.xml.in
@@ -6,10 +6,10 @@
<properties>
<help>Monitor Neighbor Discovery Protocol (NDP) information</help>
</properties>
- <command>sudo ndptool monitor</command>
+ <command>ndptool monitor</command>
<children>
<tagNode name="interface">
- <command>sudo ndptool monitor --ifname=$4</command>
+ <command>ndptool monitor --ifname=$4</command>
<properties>
<help>Monitor Neighbor Discovery Protocol on specified interface</help>
<completionHelp>
@@ -18,7 +18,7 @@
</properties>
<children>
<tagNode name="type">
- <command>sudo ndptool monitor --ifname=$4 --msg-type=$6</command>
+ <command>ndptool monitor --ifname=$4 --msg-type=$6</command>
<properties>
<help>Monitor specific Neighbor Discovery Protocol type</help>
<completionHelp>
@@ -29,7 +29,7 @@
</children>
</tagNode>
<tagNode name="type">
- <command>sudo ndptool monitor --msg-type=$4</command>
+ <command>ndptool monitor --msg-type=$4</command>
<properties>
<help>Monitor specific Neighbor Discovery Protocol type</help>
<completionHelp>
diff --git a/op-mode-definitions/monitor-protocol.xml.in b/op-mode-definitions/monitor-protocol.xml.in
index f05a1945f..fec30c8a5 100644
--- a/op-mode-definitions/monitor-protocol.xml.in
+++ b/op-mode-definitions/monitor-protocol.xml.in
@@ -35,12 +35,6 @@
</properties>
<command>vtysh -c "no debug bgp ${@:5}"</command>
</node>
- <node name="bestpath">
- <properties>
- <help>Disable BGP allow best path debugging</help>
- </properties>
- <command>vtysh -c "no debug bgp ${@:5}"</command>
- </node>
<tagNode name="bestpath">
<properties>
<help>Disable BGP bestpath IPv4 IPv6</help>
@@ -48,6 +42,10 @@
<list>&lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h/h&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Disable BGP allow best path debugging</help>
+ <command>vtysh -c "no debug bgp ${@:5}"</command>
+ </standalone>
<command>vtysh -c "no debug bgp ${@:5}"</command>
</tagNode>
<node name="flowspec">
@@ -155,12 +153,6 @@
</properties>
<command>vtysh -c "debug bgp ${@:5}"</command>
</node>
- <node name="bestpath">
- <properties>
- <help>Enable BGP allow best path debugging</help>
- </properties>
- <command>vtysh -c "debug bgp ${@:5}"</command>
- </node>
<tagNode name="bestpath">
<properties>
<help>Debug bestpath IPv4 IPv6</help>
@@ -168,6 +160,10 @@
<list>&lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h/h&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Enable BGP allow best path debugging</help>
+ <command>vtysh -c "debug bgp ${@:5}"</command>
+ </standalone>
<command>vtysh -c "debug bgp ${@:5}"</command>
</tagNode>
<node name="flowspec">
diff --git a/op-mode-definitions/mtr.xml.in b/op-mode-definitions/mtr.xml.in
index 66729e2bc..ac146d520 100644
--- a/op-mode-definitions/mtr.xml.in
+++ b/op-mode-definitions/mtr.xml.in
@@ -11,7 +11,7 @@
</properties>
<command>${vyos_op_scripts_dir}/mtr.py ${@:3}</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Traceroute options</help>
<completionHelp>
@@ -19,7 +19,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/mtr.py ${@:3}</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
@@ -33,7 +33,7 @@
</properties>
<command>${vyos_op_scripts_dir}/mtr.py ${@:2}</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>mtr options</help>
<completionHelp>
@@ -41,7 +41,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/mtr.py ${@:2}</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</interfaceDefinition>
diff --git a/op-mode-definitions/nat.xml.in b/op-mode-definitions/nat.xml.in
index 13e7fd81d..bdf6324b2 100644
--- a/op-mode-definitions/nat.xml.in
+++ b/op-mode-definitions/nat.xml.in
@@ -24,7 +24,7 @@
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/cgnat.py show_allocation --external-address "$6"</command>
+ <command>${vyos_op_scripts_dir}/cgnat.py show_allocation --external-address "$6"</command>
</tagNode>
<tagNode name="internal-address">
<properties>
@@ -33,10 +33,10 @@
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/cgnat.py show_allocation --internal-address "$6"</command>
+ <command>${vyos_op_scripts_dir}/cgnat.py show_allocation --internal-address "$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/cgnat.py show_allocation</command>
+ <command>${vyos_op_scripts_dir}/cgnat.py show_allocation</command>
</node>
</children>
</node>
@@ -49,13 +49,13 @@
<properties>
<help>Show configured source NAT rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_rules --direction source --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_rules --direction source --family inet</command>
</node>
<node name="statistics">
<properties>
<help>Show statistics for configured source NAT rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_statistics --direction source --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_statistics --direction source --family inet</command>
</node>
<node name="translations">
<properties>
@@ -69,10 +69,10 @@
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet --address "$6"</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet --address "$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet</command>
</node>
</children>
</node>
@@ -85,13 +85,13 @@
<properties>
<help>Show configured destination NAT rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_rules --direction destination --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_rules --direction destination --family inet</command>
</node>
<node name="statistics">
<properties>
<help>Show statistics for configured destination NAT rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_statistics --direction destination --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_statistics --direction destination --family inet</command>
</node>
<node name="translations">
<properties>
@@ -105,10 +105,10 @@
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet --address "$6"</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet --address "$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/nat66.xml.in b/op-mode-definitions/nat66.xml.in
index 4df20d847..435e041a3 100644
--- a/op-mode-definitions/nat66.xml.in
+++ b/op-mode-definitions/nat66.xml.in
@@ -16,13 +16,13 @@
<properties>
<help>Show configured source NAT66 rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_rules --direction source --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_rules --direction source --family inet6</command>
</node>
<node name="statistics">
<properties>
<help>Show statistics for configured source NAT66 rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_statistics --direction source --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_statistics --direction source --family inet6</command>
</node>
<node name="translations">
<properties>
@@ -36,10 +36,10 @@
<list>&lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet6 --address "$6"</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet6 --address "$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction source --family inet6</command>
</node>
</children>
</node>
@@ -52,13 +52,13 @@
<properties>
<help>Show configured destination NAT66 rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_rules --direction destination --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_rules --direction destination --family inet6</command>
</node>
<node name="statistics">
<properties>
<help>Show statistics for configured destination NAT66 rules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_statistics --direction destination --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_statistics --direction destination --family inet6</command>
</node>
<node name="translations">
<properties>
@@ -72,10 +72,10 @@
<list>&lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet6 --address "$6"</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet6 --address "$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet6</command>
+ <command>${vyos_op_scripts_dir}/nat.py show_translations --direction destination --family inet6</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/ntp.xml.in b/op-mode-definitions/ntp.xml.in
index 565a5edb5..208df8259 100644
--- a/op-mode-definitions/ntp.xml.in
+++ b/op-mode-definitions/ntp.xml.in
@@ -6,25 +6,25 @@
<properties>
<help>Show peer status of NTP daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ntp.py show_sourcestats</command>
+ <command>${vyos_op_scripts_dir}/ntp.py show_sourcestats</command>
<children>
<node name="activity">
<properties>
<help>Report the number of servers and peers that are online and offline</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ntp.py show_activity</command>
+ <command>${vyos_op_scripts_dir}/ntp.py show_activity</command>
</node>
<node name="sources">
<properties>
<help>Show information about the current time sources being accessed</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ntp.py show_sources</command>
+ <command>${vyos_op_scripts_dir}/ntp.py show_sources</command>
</node>
<node name="system">
<properties>
<help>Show parameters about the system clock performance</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ntp.py show_tracking</command>
+ <command>${vyos_op_scripts_dir}/ntp.py show_tracking</command>
</node>
</children>
</node>
@@ -49,10 +49,10 @@
<path>vrf name</path>
</completionHelp>
</properties>
- <command>sudo ip vrf exec $5 chronyc makestep</command>
+ <command>ip vrf exec $5 chronyc makestep</command>
</tagNode>
</children>
- <command>sudo chronyc makestep</command>
+ <command>chronyc makestep</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/openconnect.xml.in b/op-mode-definitions/openconnect.xml.in
index 88e1f9f15..e2c94bacb 100644
--- a/op-mode-definitions/openconnect.xml.in
+++ b/op-mode-definitions/openconnect.xml.in
@@ -17,7 +17,7 @@
<properties>
<help>Show OpenConnect configured user settings</help>
<completionHelp>
- <script>sudo ${vyos_completion_dir}/list_openconnect_users.py</script>
+ <script>${vyos_completion_dir}/list_openconnect_users.py</script>
</completionHelp>
</properties>
<children>
diff --git a/op-mode-definitions/openvpn.xml.in b/op-mode-definitions/openvpn.xml.in
index f205b0026..692eef836 100644
--- a/op-mode-definitions/openvpn.xml.in
+++ b/op-mode-definitions/openvpn.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Reset specified OpenVPN client</help>
<completionHelp>
- <script>sudo ${vyos_completion_dir}/list_openvpn_clients.py --all</script>
+ <script>${vyos_completion_dir}/list_openvpn_clients.py --all</script>
</completionHelp>
</properties>
<command>echo kill $4 | socat - UNIX-CONNECT:/run/openvpn/openvpn-mgmt-intf &gt; /dev/null</command>
@@ -20,10 +20,10 @@
<properties>
<help>Reset OpenVPN process on interface</help>
<completionHelp>
- <script>sudo ${vyos_completion_dir}/list_interfaces --type openvpn</script>
+ <script>${vyos_completion_dir}/list_interfaces --type openvpn</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/openvpn.py reset --interface $4</command>
+ <command>${vyos_op_scripts_dir}/openvpn.py reset --interface $4</command>
</tagNode>
</children>
</node>
@@ -39,91 +39,84 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=openvpn</command>
<children>
+ <leafNode name="client">
+ <properties>
+ <help>Show tunnel status for OpenVPN client interfaces</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/openvpn.py show --mode client</command>
+ </leafNode>
+ <leafNode name="server">
+ <properties>
+ <help>Show tunnel status for OpenVPN server interfaces</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/openvpn.py show --mode server</command>
+ </leafNode>
+ <leafNode name="site-to-site">
+ <properties>
+ <help>Show tunnel status for OpenVPN site-to-site interfaces</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/openvpn.py show --mode site_to_site</command>
+ </leafNode>
<leafNode name="detail">
<properties>
<help>Show detailed OpenVPN interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=openvpn</command>
</leafNode>
- </children>
- </node>
- <tagNode name="openvpn">
- <properties>
- <help>Show OpenVPN interface information</help>
- <completionHelp>
- <script>sudo ${vyos_completion_dir}/list_interfaces --type openvpn</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name=$4</command>
- <children>
- <tagNode name="user">
+ <virtualTagNode>
<properties>
- <help>Show OpenVPN interface users</help>
+ <help>Show OpenVPN interface information</help>
<completionHelp>
- <script>sudo ${vyos_completion_dir}/list_openvpn_users.py --interface ${COMP_WORDS[3]}</script>
+ <script>${vyos_completion_dir}/list_interfaces --type openvpn</script>
</completionHelp>
</properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name=$4</command>
<children>
- <node name="mfa">
+ <tagNode name="user">
<properties>
- <help>Show multi-factor authentication information</help>
+ <help>Show OpenVPN interface users</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_openvpn_users.py --interface ${COMP_WORDS[3]}</script>
+ </completionHelp>
</properties>
<children>
- <leafNode name="secret">
- <properties>
- <help>Show multi-factor authentication secret</help>
- </properties>
- <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=secret</command>
- </leafNode>
- <leafNode name="uri">
- <properties>
- <help>Show multi-factor authentication otpauth uri</help>
- </properties>
- <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=uri</command>
- </leafNode>
- <leafNode name="qrcode">
+ <node name="mfa">
<properties>
- <help>Show multi-factor authentication QR code</help>
+ <help>Show multi-factor authentication information</help>
</properties>
- <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=qrcode</command>
- </leafNode>
+ <children>
+ <leafNode name="secret">
+ <properties>
+ <help>Show multi-factor authentication secret</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=secret</command>
+ </leafNode>
+ <leafNode name="uri">
+ <properties>
+ <help>Show multi-factor authentication otpauth uri</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=uri</command>
+ </leafNode>
+ <leafNode name="qrcode">
+ <properties>
+ <help>Show multi-factor authentication QR code</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_openvpn_mfa.py --user="$6" --intf="$4" --action=qrcode</command>
+ </leafNode>
+ </children>
+ </node>
</children>
- </node>
+ </tagNode>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of specified OpenVPN interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4"</command>
+ </leafNode>
</children>
- </tagNode>
- <leafNode name="brief">
- <properties>
- <help>Show summary of specified OpenVPN interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4"</command>
- </leafNode>
+ </virtualTagNode>
</children>
- </tagNode>
- </children>
- </node>
- <node name="openvpn">
- <properties>
- <help>Show OpenVPN information</help>
- </properties>
- <children>
- <leafNode name="client">
- <properties>
- <help>Show tunnel status for OpenVPN client interfaces</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/openvpn.py show --mode client</command>
- </leafNode>
- <leafNode name="server">
- <properties>
- <help>Show tunnel status for OpenVPN server interfaces</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/openvpn.py show --mode server</command>
- </leafNode>
- <leafNode name="site-to-site">
- <properties>
- <help>Show tunnel status for OpenVPN site-to-site interfaces</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/openvpn.py show --mode site_to_site</command>
- </leafNode>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/ping.xml.in b/op-mode-definitions/ping.xml.in
index 4c25a59ab..fd50398ba 100644
--- a/op-mode-definitions/ping.xml.in
+++ b/op-mode-definitions/ping.xml.in
@@ -9,7 +9,7 @@
</properties>
<command>${vyos_op_scripts_dir}/ping.py ${@:2}</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Ping options</help>
<completionHelp>
@@ -17,7 +17,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/ping.py ${@:2}</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</interfaceDefinition>
diff --git a/op-mode-definitions/pki.xml.in b/op-mode-definitions/pki.xml.in
index 866f482bf..29b08dacb 100644
--- a/op-mode-definitions/pki.xml.in
+++ b/op-mode-definitions/pki.xml.in
@@ -27,7 +27,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ca --name "$7" --sign "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ca --name "$7" --sign "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -48,7 +48,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ca --name "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ca --name "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -79,7 +79,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$6" --self-sign --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$6" --self-sign --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -108,7 +108,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$7" --sign "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$7" --sign "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -129,7 +129,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type certificate --name "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -158,7 +158,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type crl --name "$4" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type crl --name "$4" --file</command>
</tagNode>
<leafNode name="install">
<properties>
@@ -181,7 +181,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type dh --name "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type dh --name "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -207,7 +207,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type key-pair --name "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type key-pair --name "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -238,7 +238,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type openvpn --name "$6" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type openvpn --name "$6" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -266,7 +266,7 @@
<list>&lt;filename&gt;</list>
</completionHelp>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ssh --name "$5" --file</command>
+ <command>${vyos_op_scripts_dir}/pki.py generate_pki --pki-type ssh --name "$5" --file</command>
</tagNode>
<tagNode name="install">
<properties>
@@ -371,13 +371,13 @@
<properties>
<help>Path to CA certificate file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type ca --name "$4" --filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type ca --name "$4" --filename "$6"</command>
</tagNode>
<tagNode name="key-file">
<properties>
<help>Path to private key file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type ca --name "$4" --key-filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type ca --name "$4" --key-filename "$6"</command>
</tagNode>
</children>
</tagNode>
@@ -393,13 +393,13 @@
<properties>
<help>Path to certificate file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type certificate --name "$4" --filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type certificate --name "$4" --filename "$6"</command>
</tagNode>
<tagNode name="key-file">
<properties>
<help>Path to private key file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type certificate --name "$4" --key-filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type certificate --name "$4" --key-filename "$6"</command>
</tagNode>
</children>
</tagNode>
@@ -415,7 +415,7 @@
<properties>
<help>Path to CRL file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type crl --name "$4" --filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type crl --name "$4" --filename "$6"</command>
</tagNode>
</children>
</tagNode>
@@ -431,7 +431,7 @@
<properties>
<help>Path to DH parameters file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type dh --name "$4" --filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type dh --name "$4" --filename "$6"</command>
</tagNode>
</children>
</tagNode>
@@ -447,13 +447,13 @@
<properties>
<help>Path to public key file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type key-pair --name "$4" --filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type key-pair --name "$4" --filename "$6"</command>
</tagNode>
<tagNode name="private-file">
<properties>
<help>Path to private key file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type key-pair --name "$4" --key-filename "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type key-pair --name "$4" --key-filename "$6"</command>
</tagNode>
</children>
</tagNode>
@@ -474,7 +474,7 @@
<properties>
<help>Path to shared secret key file</help>
</properties>
- <command>sudo -E ${vyos_op_scripts_dir}/pki.py import_pki --pki-type openvpn --name "$5" --filename "$7"</command>
+ <command>${vyos_op_scripts_dir}/pki.py import_pki --pki-type openvpn --name "$5" --filename "$7"</command>
</tagNode>
</children>
</tagNode>
@@ -490,14 +490,8 @@
<properties>
<help>Show PKI x509 certificates</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_all</command>
+ <command>${vyos_op_scripts_dir}/pki.py show_all</command>
<children>
- <leafNode name="ca">
- <properties>
- <help>Show x509 CA certificates</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate_authority</command>
- </leafNode>
<tagNode name="ca">
<properties>
<help>Show x509 CA certificate by name</help>
@@ -505,22 +499,20 @@
<path>pki ca</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate_authority --name "$4"</command>
+ <standalone>
+ <help>Show x509 CA certificates</help>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate_authority</command>
+ </standalone>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate_authority --name "$4"</command>
<children>
<leafNode name="pem">
<properties>
<help>Show x509 CA certificate in PEM format</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate_authority --name "$4" --pem</command>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate_authority --name "$4" --pem</command>
</leafNode>
</children>
</tagNode>
- <leafNode name="certificate">
- <properties>
- <help>Show x509 certificates</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate</command>
- </leafNode>
<tagNode name="certificate">
<properties>
<help>Show x509 certificate by name</help>
@@ -528,13 +520,17 @@
<path>pki certificate</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate --name "$4"</command>
+ <standalone>
+ <help>Show x509 certificates</help>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate</command>
+ </standalone>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate --name "$4"</command>
<children>
<leafNode name="pem">
<properties>
<help>Show x509 certificate in PEM format</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate --name "$4" --pem</command>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate --name "$4" --pem</command>
</leafNode>
<tagNode name="fingerprint">
<properties>
@@ -543,16 +539,10 @@
<list>sha256 sha384 sha512</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/pki.py show_certificate --name "$4" --fingerprint "$6"</command>
+ <command>${vyos_op_scripts_dir}/pki.py show_certificate --name "$4" --fingerprint "$6"</command>
</tagNode>
</children>
</tagNode>
- <leafNode name="crl">
- <properties>
- <help>Show x509 certificate revocation lists</help>
- </properties>
- <command>${vyos_op_scripts_dir}/pki.py show_crl</command>
- </leafNode>
<tagNode name="crl">
<properties>
<help>Show x509 certificate revocation lists by CA name</help>
@@ -560,6 +550,10 @@
<path>pki ca</path>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show x509 certificate revocation lists</help>
+ <command>${vyos_op_scripts_dir}/pki.py show_crl</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/pki.py show_crl --name "$4"</command>
<children>
<leafNode name="pem">
@@ -576,12 +570,20 @@
</node>
<node name="renew">
<children>
- <leafNode name="certbot">
+ <node name="certbot">
<properties>
- <help>Start manual certbot renewal</help>
+ <help>Manual certbot renewal</help>
</properties>
- <command>sudo systemctl start certbot.service</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/pki.py renew_certbot</command>
+ <children>
+ <leafNode name="force">
+ <properties>
+ <help>Force manual certbot renewal</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/pki.py renew_certbot --force</command>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/policy-route.xml.in b/op-mode-definitions/policy-route.xml.in
index bd4a61dc9..e733d976c 100644
--- a/op-mode-definitions/policy-route.xml.in
+++ b/op-mode-definitions/policy-route.xml.in
@@ -84,12 +84,6 @@
<help>Show policy information</help>
</properties>
<children>
- <node name="route6">
- <properties>
- <help>Show IPv6 policy chain</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all --ipv6</command>
- </node>
<tagNode name="route6">
<properties>
<help>Show IPv6 policy chains</help>
@@ -97,6 +91,10 @@
<path>policy route6</path>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show IPv6 policy chain</help>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show_all --ipv6</command>
+ </standalone>
<children>
<tagNode name="rule">
<properties>
@@ -105,17 +103,11 @@
<path>policy route6 ${COMP_WORDS[4]} rule</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6 --ipv6</command>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6 --ipv6</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --ipv6</command>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --ipv6</command>
</tagNode>
- <node name="route">
- <properties>
- <help>Show IPv4 policy chain</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all</command>
- </node>
<tagNode name="route">
<properties>
<help>Show IPv4 policy chains</help>
@@ -123,6 +115,10 @@
<path>policy route</path>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show IPv4 policy chains</help>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show_all</command>
+ </standalone>
<children>
<tagNode name="rule">
<properties>
@@ -131,10 +127,10 @@
<path>policy route ${COMP_WORDS[4]} rule</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6</command>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4</command>
+ <command>${vyos_op_scripts_dir}/policy_route.py --action show --name $4</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/poweroff.xml.in b/op-mode-definitions/poweroff.xml.in
index b4163bcb9..e023e80be 100644
--- a/op-mode-definitions/poweroff.xml.in
+++ b/op-mode-definitions/poweroff.xml.in
@@ -4,19 +4,19 @@
<properties>
<help>Poweroff the system</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --poweroff</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --poweroff</command>
<children>
<leafNode name="now">
<properties>
<help>Poweroff the system without confirmation</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff</command>
</leafNode>
<leafNode name="cancel">
<properties>
<help>Cancel a pending poweroff</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --cancel</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --cancel</command>
</leafNode>
<tagNode name="in">
<properties>
@@ -25,7 +25,7 @@
<list>&lt;Minutes&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $4</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $4</command>
</tagNode>
<tagNode name="at">
<properties>
@@ -34,7 +34,7 @@
<list>&lt;HH:MM&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3</command>
<children>
<tagNode name="date">
<properties>
@@ -43,7 +43,7 @@
<list>&lt;DDMMYYYY&gt; &lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $5</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $5</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/raid.xml.in b/op-mode-definitions/raid.xml.in
index 85fbf4566..0733b637d 100644
--- a/op-mode-definitions/raid.xml.in
+++ b/op-mode-definitions/raid.xml.in
@@ -19,7 +19,7 @@
<properties>
<help>Add a member to a RAID set</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/raid.py add --raid-set-name $3 --by-id --member $6</command>
+ <command>${vyos_op_scripts_dir}/raid.py add --raid-set-name $3 --by-id --member $6</command>
</tagNode>
</children>
</node>
@@ -27,7 +27,7 @@
<properties>
<help>Add a member to a RAID set</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/raid.py add --raid-set-name $3 --member $5</command>
+ <command>${vyos_op_scripts_dir}/raid.py add --raid-set-name $3 --member $5</command>
</tagNode>
</children>
</tagNode>
@@ -52,7 +52,7 @@
<properties>
<help>Delete a member from a RAID set</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/raid.py delete --raid-set-name $3 --by-id --member $6</command>
+ <command>${vyos_op_scripts_dir}/raid.py delete --raid-set-name $3 --by-id --member $6</command>
</tagNode>
</children>
</node>
@@ -60,7 +60,7 @@
<properties>
<help>Delete a member from a RAID set</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/raid.py delete --raid-set-name $3 --member $5</command>
+ <command>${vyos_op_scripts_dir}/raid.py delete --raid-set-name $3 --member $5</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/reboot.xml.in b/op-mode-definitions/reboot.xml.in
index d5a71f561..1fa79da7e 100644
--- a/op-mode-definitions/reboot.xml.in
+++ b/op-mode-definitions/reboot.xml.in
@@ -4,19 +4,19 @@
<properties>
<help>Reboot the system</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --reboot</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --reboot</command>
<children>
<leafNode name="now">
<properties>
<help>Reboot the system without confirmation</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --reboot</command>
</leafNode>
<leafNode name="cancel">
<properties>
<help>Cancel a pending reboot</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --cancel</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --cancel</command>
</leafNode>
<tagNode name="in">
<properties>
@@ -25,7 +25,7 @@
<list>&lt;Minutes&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot-in $3 $4</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --reboot-in $3 $4</command>
</tagNode>
<tagNode name="at">
<properties>
@@ -34,7 +34,7 @@
<list>&lt;HH:MM&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3</command>
<children>
<tagNode name="date">
<properties>
@@ -43,7 +43,7 @@
<list>&lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $5</command>
+ <command>${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $5</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/reset-bgp.xml.in b/op-mode-definitions/reset-bgp.xml.in
index a1d42d4a3..3d73fd417 100644
--- a/op-mode-definitions/reset-bgp.xml.in
+++ b/op-mode-definitions/reset-bgp.xml.in
@@ -7,6 +7,18 @@
<help>Border Gateway Protocol (BGP) information</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>BGP IPv4/IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
<leafNode name="all">
<properties>
<help>Clear all peers</help>
@@ -37,20 +49,20 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>IPv4 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="ipv4">
- <properties>
- <help>IPv4 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
<node name="ipv6">
<properties>
<help>IPv6 Address Family</help>
@@ -64,20 +76,20 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv6</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="ipv6">
- <properties>
- <help>IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv6</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
<node name="l2vpn">
<properties>
<help>Layer 2 Virtual Private Network Address Family</help>
@@ -96,20 +108,20 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>BGP IPv4/IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="evpn">
- <properties>
- <help>BGP IPv4/IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
</children>
</node>
<tagNode name="vrf">
@@ -120,7 +132,7 @@
</completionHelp>
</properties>
<children>
- <node name="node.tag">
+ <virtualTagNode>
<properties>
<help>IPv4/IPv6 neighbor to clear</help>
<completionHelp>
@@ -131,7 +143,7 @@
<children>
#include <include/bgp/reset-bgp-neighbor-options.xml.i>
</children>
- </node>
+ </virtualTagNode>
<leafNode name="all">
<properties>
<help>Clear all peers</help>
@@ -162,20 +174,20 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group-vrf.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>IPv4 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4 --vrf ${COMP_WORDS[3]}</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="ipv4">
- <properties>
- <help>IPv4 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4 --vrf ${COMP_WORDS[3]}</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
<node name="ipv6">
<properties>
<help>IPv6 Address Family</help>
@@ -189,20 +201,20 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group-vrf.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv6 --vrf ${COMP_WORDS[3]}</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="ipv6">
- <properties>
- <help>IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv6 --vrf ${COMP_WORDS[3]}</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
<node name="l2vpn">
<properties>
<help>Layer 2 Virtual Private Network Address Family</help>
@@ -221,38 +233,26 @@
</leafNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
#include <include/bgp/reset-bgp-peer-group-vrf.xml.i>
+ <virtualTagNode>
+ <properties>
+ <help>BGP IPv4/IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both --vrf ${COMP_WORDS[3]}</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="evpn">
- <properties>
- <help>BGP IPv4/IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both --vrf ${COMP_WORDS[3]}</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
</children>
</node>
</children>
</tagNode>
</children>
</node>
- <tagNode name="bgp">
- <properties>
- <help>BGP IPv4/IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --both</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/reset-connection.xml.in b/op-mode-definitions/reset-connection.xml.in
new file mode 100644
index 000000000..e41d8ed20
--- /dev/null
+++ b/op-mode-definitions/reset-connection.xml.in
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="reset">
+ <children>
+ <tagNode name="connection">
+ <properties>
+ <help>Bring connection-oriented network interface down and up</help>
+ <completionHelp>
+ <path>interfaces pppoe</path>
+ <path>interfaces sstpc</path>
+ <path>interfaces wwan</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/connect_disconnect.py --connect --disconnect --interface "$3"</command>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/reset-conntrack.xml.in b/op-mode-definitions/reset-conntrack.xml.in
index 9c8265f77..e180b47a8 100644
--- a/op-mode-definitions/reset-conntrack.xml.in
+++ b/op-mode-definitions/reset-conntrack.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Reset all currently tracked connections</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/clear_conntrack.py</command>
+ <command>${vyos_op_scripts_dir}/clear_conntrack.py</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/reset-ip-bgp.xml.in b/op-mode-definitions/reset-ip-bgp.xml.in
index 34a4503d9..9201865dc 100644
--- a/op-mode-definitions/reset-ip-bgp.xml.in
+++ b/op-mode-definitions/reset-ip-bgp.xml.in
@@ -9,28 +9,38 @@
<help>Border Gateway Protocol (BGP) information</help>
</properties>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>BGP IPv4/IPv6 neighbor to clear</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/bgp/reset-bgp-neighbor-options.xml.i>
+ </children>
+ </virtualTagNode>
<leafNode name="all">
<properties>
<help>Clear all BGP peering sessions</help>
</properties>
<command>vtysh -c "clear bgp ipv4 *"</command>
</leafNode>
- <node name="dampening">
- <properties>
- <help>Clear BGP route flap dampening information</help>
- </properties>
- <command>vtysh -c "clear ip bgp dampening"</command>
- </node>
<tagNode name="dampening">
<properties>
- <help>Clear BGP route flap dampening information for given host|network address</help>
+ <help>Clear BGP route flap dampening information for given host ornetwork address</help>
<completionHelp>
<list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Clear BGP route flap dampening information</help>
+ <command>vtysh -c "clear ip bgp dampening"</command>
+ </standalone>
<command>vtysh -c "clear ip bgp dampening $5"</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Clear BGP route flap dampening information for given network address</help>
<completionHelp>
@@ -38,7 +48,7 @@
</completionHelp>
</properties>
<command>vtysh -c "clear ip bgp dampening $5 $6"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
#include <include/bgp/reset-bgp-afi-common.xml.i>
@@ -57,7 +67,7 @@
</properties>
<command>vtysh -c "clear bgp vrf $5 *"</command>
</leafNode>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Clear BGP neighbor IP address</help>
<completionHelp>
@@ -65,24 +75,12 @@
</completionHelp>
</properties>
<command>vtysh -c "clear bgp vrf $5 $6"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
</node>
- <tagNode name="bgp">
- <properties>
- <help>BGP IPv4/IPv6 neighbor to clear</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_bgp_neighbors.sh --ipv4</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/bgp/reset-bgp-neighbor-options.xml.i>
- </children>
- </tagNode>
- </children>
+ </children>
</node>
</children>
</node>
diff --git a/op-mode-definitions/clear-session.xml.in b/op-mode-definitions/reset-session.xml.in
index bfafe6312..a1e8739c5 100644
--- a/op-mode-definitions/clear-session.xml.in
+++ b/op-mode-definitions/reset-session.xml.in
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<interfaceDefinition>
- <node name="clear">
+ <node name="reset">
<children>
<tagNode name="session">
<properties>
@@ -9,7 +9,7 @@
<script>who | awk '{print $2}'</script>
</completionHelp>
</properties>
- <command>sudo pkill -9 -t $3</command>
+ <command>pkill -9 -t $3</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/reset-vpn.xml.in b/op-mode-definitions/reset-vpn.xml.in
index 8de95d1cc..336fb1e02 100644
--- a/op-mode-definitions/reset-vpn.xml.in
+++ b/op-mode-definitions/reset-vpn.xml.in
@@ -16,19 +16,19 @@
<properties>
<help>Reset all L2TP server VPN sessions</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp"</command>
</node>
<tagNode name="interface">
<properties>
<help>Reset specified interface on L2TP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp" --interface="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp" --interface="$5"</command>
</tagNode>
<tagNode name="user">
<properties>
<help>Reset specified user on L2TP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp" --username="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="l2tp" --username="$5"</command>
</tagNode>
</children>
</node>
@@ -41,19 +41,19 @@
<properties>
<help>Reset all PPTP server VPN sessions</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp"</command>
</node>
<tagNode name="interface">
<properties>
<help>Reset specified interface on PPTP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp" --interface="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp" --interface="$5"</command>
</tagNode>
<tagNode name="user">
<properties>
<help>Reset specified user on PPTP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp" --username="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="pptp" --username="$5"</command>
</tagNode>
</children>
</node>
@@ -66,19 +66,19 @@
<properties>
<help>Reset all SSTP server VPN sessions</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp"</command>
</node>
<tagNode name="interface">
<properties>
<help>Reset specified interface on SSTP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp" --interface="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp" --interface="$5"</command>
</tagNode>
<tagNode name="user">
<properties>
<help>Reset specified user on SSTP VPN server</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp" --username="$5"</command>
+ <command>${vyos_op_scripts_dir}/reset_vpn.py reset_conn --protocol="sstp" --username="$5"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/reset-wireguard.xml.in b/op-mode-definitions/reset-wireguard.xml.in
index c2243f519..cb575c8c6 100644
--- a/op-mode-definitions/reset-wireguard.xml.in
+++ b/op-mode-definitions/reset-wireguard.xml.in
@@ -14,7 +14,7 @@
<path>interfaces wireguard</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_wireguard.py reset_peer --interface="$4"</command>
+ <command>${vyos_op_scripts_dir}/reset_wireguard.py reset_peer --interface="$4"</command>
<children>
<tagNode name="peer">
<properties>
@@ -23,7 +23,7 @@
<path>interfaces wireguard ${COMP_WORDS[3]} peer</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/reset_wireguard.py reset_peer --interface="$4" --peer="$6"</command>
+ <command>${vyos_op_scripts_dir}/reset_wireguard.py reset_peer --interface="$4" --peer="$6"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/restart-frr.xml.in b/op-mode-definitions/restart-frr.xml.in
index 4772e8dd2..950007a50 100644
--- a/op-mode-definitions/restart-frr.xml.in
+++ b/op-mode-definitions/restart-frr.xml.in
@@ -6,85 +6,85 @@
<properties>
<help>Restart all routing daemons</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart</command>
</leafNode>
<leafNode name="zebra">
<properties>
<help>Restart Routing Information Base (RIB) IP manager daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon zebra</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon zebra</command>
</leafNode>
<leafNode name="static">
<properties>
<help>Restart static routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon staticd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon staticd</command>
</leafNode>
<leafNode name="bgp">
<properties>
<help>Restart Border Gateway Protocol (BGP) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bgpd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bgpd</command>
</leafNode>
<leafNode name="ospf">
<properties>
<help>Restart Open Shortest Path First (OSPF) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospfd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospfd</command>
</leafNode>
<leafNode name="ospfv3">
<properties>
<help>Restart IPv6 Open Shortest Path First (OSPFv3) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospf6d</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospf6d</command>
</leafNode>
<leafNode name="rip">
<properties>
<help>Restart Routing Information Protocol (RIP) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripd</command>
</leafNode>
<leafNode name="ripng">
<properties>
<help>Restart IPv6 Routing Information Protocol (RIPng) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripngd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripngd</command>
</leafNode>
<leafNode name="isis">
<properties>
<help>Restart Intermediate System to Intermediate System (IS-IS) routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command>
</leafNode>
<leafNode name="openfabric">
<properties>
<help>Restart OpenFabric routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon fabricd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon fabricd</command>
</leafNode>
<leafNode name="pim6">
<properties>
<help>Restart IPv6 Protocol Independent Multicast (PIM) daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon pim6d</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon pim6d</command>
</leafNode>
<leafNode name="ldp">
<properties>
<help>Restart Label Distribution Protocol (LDP) daemon used by MPLS</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ldpd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ldpd</command>
</leafNode>
<leafNode name="babel">
<properties>
<help>Restart Babel routing daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon babeld</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon babeld</command>
</leafNode>
<leafNode name="bfd">
<properties>
<help>Restart Bidirectional Forwarding Detection (BFD) daemon</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bfdd</command>
+ <command>${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bfdd</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/restart-ntp.xml.in b/op-mode-definitions/restart-ntp.xml.in
index 961fae252..8713dd147 100644
--- a/op-mode-definitions/restart-ntp.xml.in
+++ b/op-mode-definitions/restart-ntp.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart NTP service</help>
</properties>
- <command>if cli-shell-api existsActive service ntp; then sudo systemctl restart chrony.service; else echo "Service NTP not configured"; fi</command>
+ <command>if cli-shell-api existsActive service ntp; then systemctl restart chrony.service; else echo "Service NTP not configured"; fi</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/restart-router-advert.xml.in b/op-mode-definitions/restart-router-advert.xml.in
index 9eea3dfc4..82cde9892 100644
--- a/op-mode-definitions/restart-router-advert.xml.in
+++ b/op-mode-definitions/restart-router-advert.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart IPv6 Router Advertisement service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name router_advert</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name router_advert</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/restart-serial.xml.in b/op-mode-definitions/restart-serial.xml.in
index 4d8a03633..27618b2f4 100644
--- a/op-mode-definitions/restart-serial.xml.in
+++ b/op-mode-definitions/restart-serial.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Restart serial console service for login TTYs</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/serial.py restart_console</command>
+ <command>${vyos_op_scripts_dir}/serial.py restart_console</command>
<children>
<tagNode name="device">
<properties>
@@ -20,7 +20,7 @@
<script>${vyos_completion_dir}/list_login_ttys.py</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/serial.py restart_console --device-name "$5"</command>
+ <command>${vyos_op_scripts_dir}/serial.py restart_console --device-name "$5"</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/restart-snmp.xml.in b/op-mode-definitions/restart-snmp.xml.in
index e9c43de01..0c1f1a2b7 100644
--- a/op-mode-definitions/restart-snmp.xml.in
+++ b/op-mode-definitions/restart-snmp.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart SNMP service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name snmp</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name snmp</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/restart-ssh.xml.in b/op-mode-definitions/restart-ssh.xml.in
index 914586df8..daa046dd7 100644
--- a/op-mode-definitions/restart-ssh.xml.in
+++ b/op-mode-definitions/restart-ssh.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Restart SSH service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name ssh --vrf "*"</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name ssh --vrf "*"</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/rpki.xml.in b/op-mode-definitions/rpki.xml.in
index 9e0f83e20..4753cfb93 100644
--- a/op-mode-definitions/rpki.xml.in
+++ b/op-mode-definitions/rpki.xml.in
@@ -15,19 +15,28 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/rpki/vrf.xml.i>
+ </children>
</tagNode>
- <leafNode name="cache-connection">
+ <node name="cache-connection">
<properties>
<help>Show RPKI cache connections</help>
</properties>
- <command>vtysh -c "show rpki cache-connection"</command>
- </leafNode>
- <leafNode name="cache-server">
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/rpki/vrf.xml.i>
+ </children>
+ </node>
+ <node name="cache-server">
<properties>
<help>Show RPKI cache servers information</help>
</properties>
- <command>vtysh -c "show rpki cache-server"</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/rpki/vrf.xml.i>
+ </children>
+ </node>
<tagNode name="prefix">
<properties>
<help>Lookup IP prefix and optionally ASN in prefix table</help>
@@ -45,27 +54,53 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $(echo $@ | sed -e "s/as-number //g")</command>
+ <children>
+ <tagNode name="vrf">
+ <properties>
+ <help>Virtual Routing and Forwarding (VRF)</help>
+ <completionHelp>
+ <path>vrf name</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $(echo $@ | sed -e "s/as-number //g")</command>
+ </tagNode>
+ </children>
</tagNode>
+ #include <include/rpki/vrf.xml.i>
</children>
</tagNode>
- <leafNode name="prefix-table">
+ <node name="prefix-table">
<properties>
<help>Show RPKI-validated prefixes</help>
</properties>
- <command>vtysh -c "show rpki prefix-table"</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/rpki/vrf.xml.i>
+ </children>
+ </node>
</children>
</node>
</children>
</node>
<node name="reset">
<children>
- <leafNode name="rpki">
+ <node name="rpki">
<properties>
<help>Reset RPKI</help>
</properties>
<command>vtysh -c "rpki reset"</command>
- </leafNode>
+ <children>
+ <tagNode name="vrf">
+ <properties>
+ <help>Reset RPKI in VRF</help>
+ <completionHelp>
+ <path>vrf name</path>
+ </completionHelp>
+ </properties>
+ <command>vtysh -c "rpki reset vrf $4"</command>
+ </tagNode>
+ </children>
+ </node>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/sflow.xml.in b/op-mode-definitions/sflow.xml.in
index 9f02dacda..003550304 100644
--- a/op-mode-definitions/sflow.xml.in
+++ b/op-mode-definitions/sflow.xml.in
@@ -7,8 +7,7 @@
<properties>
<help>Show sFlow statistics</help>
</properties>
- <!-- requires sudo, do not remove it -->
- <command>sudo ${vyos_op_scripts_dir}/sflow.py show</command>
+ <command>${vyos_op_scripts_dir}/sflow.py show</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-acceleration.xml.in b/op-mode-definitions/show-acceleration.xml.in
index fccfba5e3..3f47bb1cd 100644
--- a/op-mode-definitions/show-acceleration.xml.in
+++ b/op-mode-definitions/show-acceleration.xml.in
@@ -29,13 +29,13 @@
<properties>
<help>Intel QAT flows</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/show_acceleration.py --flow --dev $6</command>
+ <command>${vyos_op_scripts_dir}/show_acceleration.py --flow --dev $6</command>
</node>
<node name="config">
<properties>
<help>Intel QAT configuration</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/show_acceleration.py --conf --dev $6</command>
+ <command>${vyos_op_scripts_dir}/show_acceleration.py --conf --dev $6</command>
</node>
</children>
</tagNode>
@@ -43,16 +43,16 @@
<properties>
<help>Intel QAT status</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/show_acceleration.py --status</command>
+ <command>${vyos_op_scripts_dir}/show_acceleration.py --status</command>
</node>
<node name="interrupts">
<properties>
<help>Intel QAT interrupts</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/show_acceleration.py --interrupts</command>
+ <command>${vyos_op_scripts_dir}/show_acceleration.py --interrupts</command>
</node>
</children>
- <command>sudo ${vyos_op_scripts_dir}/show_acceleration.py --hw</command>
+ <command>${vyos_op_scripts_dir}/show_acceleration.py --hw</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-babel.xml.in b/op-mode-definitions/show-babel.xml.in
index 0a1f1b262..8b841eeac 100644
--- a/op-mode-definitions/show-babel.xml.in
+++ b/op-mode-definitions/show-babel.xml.in
@@ -13,12 +13,6 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</leafNode>
- <leafNode name="neighbor">
- <properties>
- <help>Show Babel neighbor information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
<tagNode name="neighbor">
<properties>
<help>Show Babel neighbor information for specified interface</help>
@@ -27,6 +21,10 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <standalone>
+ <help>Show Babel neighbor information</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
</tagNode>
<leafNode name="route">
<properties>
diff --git a/op-mode-definitions/show-bfd.xml.in b/op-mode-definitions/show-bfd.xml.in
index 87d672e04..02863975b 100644
--- a/op-mode-definitions/show-bfd.xml.in
+++ b/op-mode-definitions/show-bfd.xml.in
@@ -7,11 +7,6 @@
<help>Show Bidirectional Forwarding Detection (BFD)</help>
</properties>
<children>
- <node name="peer">
- <properties>
- <help>Show all Bidirectional Forwarding Detection (BFD) peer status</help>
- </properties>
- </node>
<tagNode name="peer">
<properties>
<help>Show Bidirectional Forwarding Detection (BFD) peer status</help>
diff --git a/op-mode-definitions/show-bgp.xml.in b/op-mode-definitions/show-bgp.xml.in
index 8b1992432..ee232fa04 100644
--- a/op-mode-definitions/show-bgp.xml.in
+++ b/op-mode-definitions/show-bgp.xml.in
@@ -78,12 +78,6 @@
</node>
</children>
</tagNode>
- <leafNode name="vrf">
- <properties>
- <help>Show BGP VRF information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
<tagNode name="vrf">
<properties>
<help>Show BGP VRF related information</help>
@@ -93,6 +87,10 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <standalone>
+ <help>Show BGP VRF information</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<children>
#include <include/bgp/show-bgp-common.xml.i>
#include <include/bgp/martian-next-hop.xml.i>
diff --git a/op-mode-definitions/show-bridge.xml.in b/op-mode-definitions/show-bridge.xml.in
index 40fadac8b..c9558c315 100644
--- a/op-mode-definitions/show-bridge.xml.in
+++ b/op-mode-definitions/show-bridge.xml.in
@@ -6,7 +6,57 @@
<properties>
<help>Show bridging information</help>
</properties>
+ <command>${vyos_op_scripts_dir}/bridge.py show</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show bridge information for a given bridge interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type bridge</script>
+ </completionHelp>
+ </properties>
+ <command>bridge -c link show | grep "master $3"</command>
+ <children>
+ <node name="spanning-tree">
+ <properties>
+ <help>View Spanning Tree info for specified bridges</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/stp.py show_stp --ifname=$3</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed Spanning Tree info for specified bridge</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/stp.py show_stp --ifname=$3 --detail</command>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="mdb">
+ <properties>
+ <help>Displays the multicast group database for the bridge</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bridge.py show_mdb --interface=$3</command>
+ </leafNode>
+ <leafNode name="fdb">
+ <properties>
+ <help>Show the forwarding database of the bridge</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bridge.py show_fdb --interface=$3</command>
+ </leafNode>
+ <leafNode name="detail">
+ <properties>
+ <help>Display bridge interface details</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bridge.py show_detail --interface=$3</command>
+ </leafNode>
+ <leafNode name="nexthop-group">
+ <properties>
+ <help>Display bridge interface nexthop-group</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bridge.py show_detail --nexthop-group --interface=$3</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<node name="spanning-tree">
<properties>
<help>View Spanning Tree info for all bridges</help>
@@ -43,61 +93,6 @@
</leafNode>
</children>
</node>
- <leafNode name="bridge">
- <properties>
- <help>Show bridging information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/bridge.py show</command>
- </leafNode>
- <tagNode name="bridge">
- <properties>
- <help>Show bridge information for a given bridge interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type bridge</script>
- </completionHelp>
- </properties>
- <command>bridge -c link show | grep "master $3"</command>
- <children>
- <node name="spanning-tree">
- <properties>
- <help>View Spanning Tree info for specified bridges</help>
- </properties>
- <command>${vyos_op_scripts_dir}/stp.py show_stp --ifname=$3</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed Spanning Tree info for specified bridge</help>
- </properties>
- <command>${vyos_op_scripts_dir}/stp.py show_stp --ifname=$3 --detail</command>
- </leafNode>
- </children>
- </node>
- <leafNode name="mdb">
- <properties>
- <help>Displays the multicast group database for the bridge</help>
- </properties>
- <command>${vyos_op_scripts_dir}/bridge.py show_mdb --interface=$3</command>
- </leafNode>
- <leafNode name="fdb">
- <properties>
- <help>Show the forwarding database of the bridge</help>
- </properties>
- <command>${vyos_op_scripts_dir}/bridge.py show_fdb --interface=$3</command>
- </leafNode>
- <leafNode name="detail">
- <properties>
- <help>Display bridge interface details</help>
- </properties>
- <command>${vyos_op_scripts_dir}/bridge.py show_detail --interface=$3</command>
- </leafNode>
- <leafNode name="nexthop-group">
- <properties>
- <help>Display bridge interface nexthop-group</help>
- </properties>
- <command>${vyos_op_scripts_dir}/bridge.py show_detail --nexthop-group --interface=$3</command>
- </leafNode>
- </children>
- </tagNode>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/show-conntrack.xml.in b/op-mode-definitions/show-conntrack.xml.in
index 4cdcffcdb..6212af4eb 100644
--- a/op-mode-definitions/show-conntrack.xml.in
+++ b/op-mode-definitions/show-conntrack.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Show conntrack statistics</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack.py show_statistics</command>
+ <command>${vyos_op_scripts_dir}/conntrack.py show_statistics</command>
</node>
<node name="table">
<properties>
@@ -22,13 +22,13 @@
<properties>
<help>Show conntrack entries for IPv4 protocol</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack.py show --family inet</command>
+ <command>${vyos_op_scripts_dir}/conntrack.py show --family inet</command>
</node>
<node name="ipv6">
<properties>
<help>Show conntrack entries for IPv6 protocol</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/conntrack.py show --family inet6</command>
+ <command>${vyos_op_scripts_dir}/conntrack.py show --family inet6</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-environment.xml.in b/op-mode-definitions/show-environment.xml.in
index 95b658785..7cc9fe822 100644
--- a/op-mode-definitions/show-environment.xml.in
+++ b/op-mode-definitions/show-environment.xml.in
@@ -12,7 +12,7 @@
<help>Show hardware monitoring results</help>
</properties>
<!-- Linux always adds "hypervisor" to CPU flags -->
- <command>if ! grep -q hypervisor /proc/cpuinfo; then ${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_sensors.py; else echo "VyOS running under hypervisor, no sensors available"; fi</command>
+ <command>if ! grep -q hypervisor /proc/cpuinfo; then ${vyos_op_scripts_dir}/show_sensors.py; else echo "VyOS running under hypervisor, no sensors available"; fi</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-evpn.xml.in b/op-mode-definitions/show-evpn.xml.in
index 3c1e5c7d6..885e0e615 100644
--- a/op-mode-definitions/show-evpn.xml.in
+++ b/op-mode-definitions/show-evpn.xml.in
@@ -11,30 +11,30 @@
<properties>
<help>Access VLANs</help>
</properties>
- <children>
- #include <include/frr-detail.xml.i>
- </children>
- <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
- </node>
- <tagNode name="access-vlan">
- <properties>
- <help>Access VLANs interface name</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --bridgeable --no-vlan-subinterfaces</script>
- </completionHelp>
- </properties>
- <children>
- <node name="node.tag">
+ <children>
+ <virtualTagNode>
<properties>
- <help>VLAN ID</help>
+ <help>Access VLANs interface name</help>
<completionHelp>
- <list>&lt;1-4094&gt;</list>
+ <script>${vyos_completion_dir}/list_interfaces --bridgeable --no-vlan-subinterfaces</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
- </node>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <help>VLAN ID</help>
+ <completionHelp>
+ <list>&lt;1-4094&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
+ </virtualTagNode>
+ </children>
+ </virtualTagNode>
+ #include <include/frr-detail.xml.i>
</children>
- </tagNode>
+ <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
+ </node>
<node name="arp-cache">
<properties>
<help>ARP and ND cache</help>
@@ -43,22 +43,22 @@
#include <include/vni-tagnode-all.xml.i>
</children>
</node>
- <tagNode name="es">
- <properties>
- <help>Show ESI information for specified ESI</help>
- <completionHelp>
- <list>&lt;esi&gt;</list>
- <script>${vyos_completion_dir}/list_esi.sh</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
- </tagNode>
<node name="es">
<properties>
<help>Show ESI information</help>
</properties>
<command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show ESI information for specified ESI</help>
+ <completionHelp>
+ <list>&lt;esi&gt;</list>
+ <script>${vyos_completion_dir}/list_esi.sh</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
+ </virtualTagNode>
<leafNode name="detail">
<properties>
<help>Show ESI details</help>
@@ -106,13 +106,22 @@
#include <include/vni-tagnode-all.xml.i>
</children>
</node>
- #include <include/vni-tagnode.xml.i>
<node name="vni">
<properties>
<help>Show VNI information</help>
</properties>
<command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
- <children>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <help>VXLAN network identifier (VNI) number</help>
+ <completionHelp>
+ <list>&lt;1-16777215&gt;</list>
+ <script>${vyos_completion_dir}/list_vni.sh</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command>
+ </virtualTagNode>
<leafNode name="detail">
<properties>
<help>Show VNI details</help>
diff --git a/op-mode-definitions/show-hardware.xml.in b/op-mode-definitions/show-hardware.xml.in
index 21079765a..84e46a22b 100644
--- a/op-mode-definitions/show-hardware.xml.in
+++ b/op-mode-definitions/show-hardware.xml.in
@@ -31,7 +31,7 @@
<properties>
<help>Show system DMI details</help>
</properties>
- <command>sudo dmidecode</command>
+ <command>dmidecode</command>
</node>
<node name="mem">
<properties>
@@ -62,7 +62,7 @@
<properties>
<help>Show NVMe device information</help>
</properties>
- <command>sudo nvme list</command>
+ <command>nvme list</command>
</leafNode>
<node name="scsi">
<properties>
@@ -85,7 +85,7 @@
<script>ls /dev | egrep '([hsv]d[a-z]|nvme[0-9]+n[0-9])$'</script>
</completionHelp>
</properties>
- <command>sudo smartctl -a "/dev/$5" | sed 1,3d</command>
+ <command>smartctl -a "/dev/$5" | sed 1,3d</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/show-history.xml.in b/op-mode-definitions/show-history.xml.in
index 7fb286264..1781fa267 100644
--- a/op-mode-definitions/show-history.xml.in
+++ b/op-mode-definitions/show-history.xml.in
@@ -14,18 +14,17 @@
</properties>
<command>HISTTIMEFORMAT='%FT%T%z ' HISTFILE="$HOME/.bash_history" \set -o history; history 20</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show last N commands in history</help>
+ <completionHelp>
+ <list>&lt;NUMBER&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>HISTTIMEFORMAT='%FT%T%z ' HISTFILE="$HOME/.bash_history" \set -o history; history $3</command>
+ </virtualTagNode>
</children>
</node>
-
- <tagNode name="history">
- <properties>
- <help>Show last N commands in history</help>
- <completionHelp>
- <list>&lt;NUMBER&gt;</list>
- </completionHelp>
- </properties>
- <command>HISTTIMEFORMAT='%FT%T%z ' HISTFILE="$HOME/.bash_history" \set -o history; history $3</command>
- </tagNode>
- </children>
+ </children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/show-interfaces-bonding.xml.in b/op-mode-definitions/show-interfaces-bonding.xml.in
index 0abb7cd5a..58f754ad6 100644
--- a/op-mode-definitions/show-interfaces-bonding.xml.in
+++ b/op-mode-definitions/show-interfaces-bonding.xml.in
@@ -4,26 +4,17 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="bonding">
+ <node name="bonding">
<properties>
- <help>Show specified Bonding interface information</help>
- <completionHelp>
- <path>interfaces bonding</path>
- </completionHelp>
+ <help>Show specified bonding interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bonding</command>
<children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified bonding interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bonding</command>
- </leafNode>
<leafNode name="detail">
<properties>
- <help>Show detailed interface information</help>
+ <help>Show detailed bonding interface information</help>
</properties>
- <command>if [ -f "/proc/net/bonding/$4" ]; then sudo cat "/proc/net/bonding/$4"; else echo "Interface $4 does not exist!"; fi</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=bonding</command>
</leafNode>
<node name="lacp">
<properties>
@@ -34,13 +25,7 @@
<properties>
<help>Show LACP details</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/bonding.py show_lacp_detail --interface="$4" </command>
- </leafNode>
- <leafNode name="neighbors">
- <properties>
- <help>Show LACP Neighbors</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/bonding.py show_lacp_neighbors --interface="$4"</command>
+ <command>${vyos_op_scripts_dir}/bonding.py show_lacp_detail</command>
</leafNode>
</children>
</node>
@@ -48,59 +33,73 @@
<properties>
<help>Show specified bonding interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/show-bond.py --interface "$4"</command>
+ <command>${vyos_op_scripts_dir}/show-bond.py --slaves</command>
</leafNode>
- <tagNode name="vif">
+ <virtualTagNode>
<properties>
- <help>Show specified virtual network interface (vif) information</help>
<completionHelp>
- <path>interfaces bonding ${COMP_WORDS[3]} vif</path>
+ <path>interfaces bonding</path>
</completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=bonding</command>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bonding</command>
<children>
<leafNode name="brief">
<properties>
- <help>Show summary of specified virtual network interface (vif) information</help>
+ <help>Show summary of the specified bonding interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bonding</command>
</leafNode>
- </children>
- </tagNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="bonding">
- <properties>
- <help>Show Bonding interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=bonding</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed bonding interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=bonding</command>
- </leafNode>
- <node name="lacp">
- <properties>
- <help>Show LACP related info</help>
- </properties>
- <children>
<leafNode name="detail">
<properties>
- <help>Show LACP details</help>
+ <help>Show detailed interface information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/bonding.py show_lacp_detail</command>
+ <command>${vyos_op_scripts_dir}/show_bonding_detail.sh "$4"</command>
</leafNode>
+ <node name="lacp">
+ <properties>
+ <help>Show LACP related info</help>
+ </properties>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show LACP details</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bonding.py show_lacp_detail --interface="$4" </command>
+ </leafNode>
+ <leafNode name="neighbors">
+ <properties>
+ <help>Show LACP Neighbors</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/bonding.py show_lacp_neighbors --interface="$4"</command>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="slaves">
+ <properties>
+ <help>Show specified bonding interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show-bond.py --interface "$4"</command>
+ </leafNode>
+ <tagNode name="vif">
+ <properties>
+ <help>Show specified virtual network interface (vif) information</help>
+ <completionHelp>
+ <path>interfaces bonding ${COMP_WORDS[3]} vif</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=bonding</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of specified virtual network interface (vif) information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=bonding</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/show-interface-type-event-log.xml.i>
</children>
- </node>
- <leafNode name="slaves">
- <properties>
- <help>Show specified bonding interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/show-bond.py --slaves</command>
- </leafNode>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-bridge.xml.in b/op-mode-definitions/show-interfaces-bridge.xml.in
index 998dacd38..f79b7bd7f 100644
--- a/op-mode-definitions/show-interfaces-bridge.xml.in
+++ b/op-mode-definitions/show-interfaces-bridge.xml.in
@@ -4,27 +4,9 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="bridge">
+ <node name="bridge">
<properties>
- <help>Show specified Bridge interface information</help>
- <completionHelp>
- <path>interfaces bridge</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bridge</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified bridge interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bridge</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="bridge">
- <properties>
- <help>Show Bridge interface information</help>
+ <help>Show bridge interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=bridge</command>
<children>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=bridge</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified bridge interface information</help>
+ <completionHelp>
+ <path>interfaces bridge</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bridge</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified bridge interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bridge</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-dummy.xml.in b/op-mode-definitions/show-interfaces-dummy.xml.in
index 18f21e97e..fdffeb96b 100644
--- a/op-mode-definitions/show-interfaces-dummy.xml.in
+++ b/op-mode-definitions/show-interfaces-dummy.xml.in
@@ -4,27 +4,9 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="dummy">
+ <node name="dummy">
<properties>
- <help>Show specified Dummy interface information</help>
- <completionHelp>
- <path>interfaces dummy</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=dummy</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified dummy interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=dummy</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="dummy">
- <properties>
- <help>Show Dummy interface information</help>
+ <help>Show dummy interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=dummy</command>
<children>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=dummy</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified dummy interface information</help>
+ <completionHelp>
+ <path>interfaces dummy</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=dummy</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified dummy interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=dummy</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-ethernet.xml.in b/op-mode-definitions/show-interfaces-ethernet.xml.in
index 8a23455bf..c6e9a2ec2 100644
--- a/op-mode-definitions/show-interfaces-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-ethernet.xml.in
@@ -4,85 +4,84 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="ethernet">
+ <node name="ethernet">
<properties>
<help>Show specified Ethernet interface information</help>
- <completionHelp>
- <path>interfaces ethernet</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=ethernet</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified ethernet interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=ethernet</command>
- </leafNode>
- <leafNode name="identify">
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=ethernet</command>
+ <children>
+ <leafNode name="detail">
<properties>
- <help>Visually identify specified ethernet interface</help>
+ <help>Show detailed ethernet interface information</help>
</properties>
- <command>echo "Blinking interface $4 for 30 seconds."; ethtool --identify "$4" 30</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=ethernet</command>
</leafNode>
- <node name="physical">
- <properties>
- <help>Show physical device information for specified ethernet interface</help>
- </properties>
- <command>ethtool "$4"; ethtool --show-ring "$4"; ethtool --driver "$4"</command>
+ <virtualTagNode>
+ <properties>
+ <completionHelp>
+ <path>interfaces ethernet</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=ethernet</command>
<children>
- <leafNode name="offload">
+ <leafNode name="brief">
<properties>
- <help>Show physical device offloading capabilities</help>
+ <help>Show summary of the specified ethernet interface information</help>
</properties>
- <command>ethtool --show-features "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' '</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=ethernet</command>
</leafNode>
- </children>
- </node>
- <leafNode name="statistics">
- <properties>
- <help>Show physical device statistics for specified ethernet interface</help>
- </properties>
- <command>ethtool --statistics "$4"</command>
- </leafNode>
- <leafNode name="transceiver">
- <properties>
- <help>Show transceiver information from modules (e.g SFP+, QSFP)</help>
- </properties>
- <command>ethtool --module-info "$4"</command>
- </leafNode>
- <tagNode name="vif">
- <properties>
- <help>Show specified virtual network interface (vif) information</help>
- <completionHelp>
- <path>interfaces ethernet ${COMP_WORDS[3]} vif</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=ethernet</command>
- <children>
- <leafNode name="brief">
+ <leafNode name="identify">
<properties>
- <help>Show summary of specified virtual network interface (vif) information</help>
+ <help>Visually identify specified ethernet interface</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=ethernet</command>
+ <command>echo "Blinking interface $4 for 30 seconds."; ethtool --identify "$4" 30</command>
</leafNode>
+ <node name="physical">
+ <properties>
+ <help>Show physical device information for specified ethernet interface</help>
+ </properties>
+ <command>ethtool "$4"; ethtool --show-ring "$4"; ethtool --driver "$4"</command>
+ <children>
+ <leafNode name="offload">
+ <properties>
+ <help>Show physical device offloading capabilities</help>
+ </properties>
+ <command>ethtool --show-features "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' '</command>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show physical device statistics for specified ethernet interface</help>
+ </properties>
+ <command>ethtool --statistics "$4"</command>
+ </leafNode>
+ <leafNode name="transceiver">
+ <properties>
+ <help>Show transceiver information from modules (e.g SFP+, QSFP)</help>
+ </properties>
+ <command>ethtool --module-info "$4"</command>
+ </leafNode>
+ <tagNode name="vif">
+ <properties>
+ <help>Show specified virtual network interface (vif) information</help>
+ <completionHelp>
+ <path>interfaces ethernet ${COMP_WORDS[3]} vif</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=ethernet</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of specified virtual network interface (vif) information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=ethernet</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/show-interface-type-event-log.xml.i>
</children>
- </tagNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="ethernet">
- <properties>
- <help>Show Ethernet interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=ethernet</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed ethernet interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=ethernet</command>
- </leafNode>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-geneve.xml.in b/op-mode-definitions/show-interfaces-geneve.xml.in
index b5fe84ca7..aaaa34757 100644
--- a/op-mode-definitions/show-interfaces-geneve.xml.in
+++ b/op-mode-definitions/show-interfaces-geneve.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="geneve">
- <properties>
- <help>Show specified GENEVE interface information</help>
- <completionHelp>
- <path>interfaces geneve</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=geneve</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified GENEVE interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=geneve</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="geneve">
+ <node name="geneve">
<properties>
<help>Show GENEVE interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=geneve</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified GENEVE interface information</help>
+ <completionHelp>
+ <path>interfaces geneve</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=geneve</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified GENEVE interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=geneve</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-input.xml.in b/op-mode-definitions/show-interfaces-input.xml.in
index c9856f77f..705b94a1a 100644
--- a/op-mode-definitions/show-interfaces-input.xml.in
+++ b/op-mode-definitions/show-interfaces-input.xml.in
@@ -4,9 +4,23 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="input">
+ <node name="input">
+ <properties>
+ <help>Show input (ifb) interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=input</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed input interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=input</command>
+ </leafNode>
+ </children>
+ </node>
+ <virtualTagNode>
<properties>
- <help>Show specified Input interface information</help>
+ <help>Show specified input interface information</help>
<completionHelp>
<path>interfaces input</path>
</completionHelp>
@@ -21,21 +35,7 @@
</leafNode>
#include <include/show-interface-type-event-log.xml.i>
</children>
- </tagNode>
- <node name="input">
- <properties>
- <help>Show Input (ifb) interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=input</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed input interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=input</command>
- </leafNode>
- </children>
- </node>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-l2tpv3.xml.in b/op-mode-definitions/show-interfaces-l2tpv3.xml.in
index 88b73d7d7..3d0345001 100644
--- a/op-mode-definitions/show-interfaces-l2tpv3.xml.in
+++ b/op-mode-definitions/show-interfaces-l2tpv3.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="l2tpv3">
- <properties>
- <help>Show specified L2TPv3 interface information</help>
- <completionHelp>
- <path>interfaces l2tpv3</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=l2tpv3</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified L2TPv3 interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=l2tpv3</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="l2tpv3">
+ <node name="l2tpv3">
<properties>
<help>Show L2TPv3 interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=l2tpv3</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified L2TPv3 interface information</help>
+ <completionHelp>
+ <path>interfaces l2tpv3</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=l2tpv3</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified L2TPv3 interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=l2tpv3</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-loopback.xml.in b/op-mode-definitions/show-interfaces-loopback.xml.in
index 467e1a13d..028d1c079 100644
--- a/op-mode-definitions/show-interfaces-loopback.xml.in
+++ b/op-mode-definitions/show-interfaces-loopback.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="loopback">
- <properties>
- <help>Show specified Loopback interface information</help>
- <completionHelp>
- <path>interfaces loopback</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=loopback</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified Loopback interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=loopback</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="loopback">
+ <node name="loopback">
<properties>
<help>Show Loopback interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=loopback</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified Loopback interface information</help>
+ <completionHelp>
+ <path>interfaces loopback</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=loopback</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified Loopback interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=loopback</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-macsec.xml.in b/op-mode-definitions/show-interfaces-macsec.xml.in
index 640031b77..027c05c63 100644
--- a/op-mode-definitions/show-interfaces-macsec.xml.in
+++ b/op-mode-definitions/show-interfaces-macsec.xml.in
@@ -19,21 +19,21 @@
</properties>
<command>ip -s macsec show</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified MACsec interface information</help>
+ <completionHelp>
+ <path>interfaces macsec</path>
+ </completionHelp>
+ </properties>
+ <command>ip macsec show $4</command>
+ <children>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
- <tagNode name="macsec">
- <properties>
- <help>Show specified MACsec interface information</help>
- <completionHelp>
- <path>interfaces macsec</path>
- </completionHelp>
- </properties>
- <command>ip macsec show $4</command>
- <children>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- </children>
+ </children>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-pppoe.xml.in b/op-mode-definitions/show-interfaces-pppoe.xml.in
index c1f502cb3..0e13ecdb8 100644
--- a/op-mode-definitions/show-interfaces-pppoe.xml.in
+++ b/op-mode-definitions/show-interfaces-pppoe.xml.in
@@ -4,34 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="pppoe">
- <properties>
- <help>Show specified PPPoE interface information</help>
- <completionHelp>
- <path>interfaces pppoe</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pppoe</command>
- <children>
- <leafNode name="log">
- <properties>
- <help>Show specified PPPoE interface log</help>
- </properties>
- <command>journalctl --no-hostname --boot --follow --unit "ppp@$4".service</command>
- </leafNode>
- <leafNode name="statistics">
- <properties>
- <help>Show specified PPPoE interface statistics</help>
- <completionHelp>
- <path>interfaces pppoe</path>
- </completionHelp>
- </properties>
- <command>if [ -d "/sys/class/net/$4" ]; then /usr/sbin/pppstats "$4"; fi</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="pppoe">
+ <node name="pppoe">
<properties>
<help>Show PPPoE interface information</help>
</properties>
@@ -43,6 +16,33 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=pppoe</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified PPPoE interface information</help>
+ <completionHelp>
+ <path>interfaces pppoe</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pppoe</command>
+ <children>
+ <leafNode name="log">
+ <properties>
+ <help>Show specified PPPoE interface log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit "ppp@$4".service</command>
+ </leafNode>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show specified PPPoE interface statistics</help>
+ <completionHelp>
+ <path>interfaces pppoe</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_ppp_stats.sh "$4"</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
index a9e4257ce..140e7150d 100644
--- a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
@@ -4,27 +4,9 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="pseudo-ethernet">
+ <node name="pseudo-ethernet">
<properties>
- <help>Show specified Pseudo-Ethernet/MACvlan interface information</help>
- <completionHelp>
- <path>interfaces pseudo-ethernet</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pseudo-ethernet</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified pseudo-ethernet/MACvlan interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=pseudo-ethernet</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="pseudo-ethernet">
- <properties>
- <help>Show Pseudo-Ethernet/MACvlan interface information</help>
+ <help>Show pseudo-ethernet/MACvlan interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=pseudo-ethernet</command>
<children>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=pseudo-ethernet</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified pseudo-ethernet/MACvlan interface information</help>
+ <completionHelp>
+ <path>interfaces pseudo-ethernet</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pseudo-ethernet</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified pseudo-ethernet/MACvlan interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=pseudo-ethernet</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-sstpc.xml.in b/op-mode-definitions/show-interfaces-sstpc.xml.in
index 3bd7a8247..e0a53d9f4 100644
--- a/op-mode-definitions/show-interfaces-sstpc.xml.in
+++ b/op-mode-definitions/show-interfaces-sstpc.xml.in
@@ -4,34 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="sstpc">
- <properties>
- <help>Show specified SSTP client interface information</help>
- <completionHelp>
- <path>interfaces sstpc</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=sstpc</command>
- <children>
- <leafNode name="log">
- <properties>
- <help>Show specified SSTP client interface log</help>
- </properties>
- <command>journalctl --no-hostname --boot --follow --unit "ppp@$4".service</command>
- </leafNode>
- <leafNode name="statistics">
- <properties>
- <help>Show specified SSTP client interface statistics</help>
- <completionHelp>
- <path>interfaces sstpc</path>
- </completionHelp>
- </properties>
- <command>if [ -d "/sys/class/net/$4" ]; then /usr/sbin/pppstats "$4"; fi</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="sstpc">
+ <node name="sstpc">
<properties>
<help>Show SSTP client interface information</help>
</properties>
@@ -43,6 +16,33 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=sstpc</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified SSTP client interface information</help>
+ <completionHelp>
+ <path>interfaces sstpc</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=sstpc</command>
+ <children>
+ <leafNode name="log">
+ <properties>
+ <help>Show specified SSTP client interface log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit "ppp@$4".service</command>
+ </leafNode>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show specified SSTP client interface statistics</help>
+ <completionHelp>
+ <path>interfaces sstpc</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_ppp_stats.sh "$4"</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-tunnel.xml.in b/op-mode-definitions/show-interfaces-tunnel.xml.in
index 579b173cb..0707fe763 100644
--- a/op-mode-definitions/show-interfaces-tunnel.xml.in
+++ b/op-mode-definitions/show-interfaces-tunnel.xml.in
@@ -4,27 +4,9 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="tunnel">
+ <node name="tunnel">
<properties>
- <help>Show specified Tunnel interface information</help>
- <completionHelp>
- <path>interfaces tunnel</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=tunnel</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified tunnel interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=tunnel</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="tunnel">
- <properties>
- <help>Show Tunnel interface information</help>
+ <help>Show tunnel interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=tunnel</command>
<children>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=tunnel</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified tunnel interface information</help>
+ <completionHelp>
+ <path>interfaces tunnel</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=tunnel</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified tunnel interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=tunnel</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in b/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
index 4112a17af..20e1754e7 100644
--- a/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="virtual-ethernet">
- <properties>
- <help>Show specified virtual-ethernet interface information</help>
- <completionHelp>
- <path>interfaces virtual-ethernet</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=virtual-ethernet</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified virtual-ethernet interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=virtual-ethernet</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="virtual-ethernet">
+ <node name="virtual-ethernet">
<properties>
<help>Show virtual-ethernet interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=virtual-ethernet</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified virtual-ethernet interface information</help>
+ <completionHelp>
+ <path>interfaces virtual-ethernet</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=virtual-ethernet</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified virtual-ethernet interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=virtual-ethernet</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-vti.xml.in b/op-mode-definitions/show-interfaces-vti.xml.in
index d13b3e7cc..460481bde 100644
--- a/op-mode-definitions/show-interfaces-vti.xml.in
+++ b/op-mode-definitions/show-interfaces-vti.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="vti">
- <properties>
- <help>Show specified VTI interface information</help>
- <completionHelp>
- <path>interfaces vti</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vti</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified vti interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vti</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="vti">
+ <node name="vti">
<properties>
<help>Show VTI interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=vti</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified VTI interface information</help>
+ <completionHelp>
+ <path>interfaces vti</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vti</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified vti interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vti</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-vxlan.xml.in b/op-mode-definitions/show-interfaces-vxlan.xml.in
index 89c8d075b..4623e9371 100644
--- a/op-mode-definitions/show-interfaces-vxlan.xml.in
+++ b/op-mode-definitions/show-interfaces-vxlan.xml.in
@@ -4,25 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="vxlan">
- <properties>
- <help>Show specified VXLAN interface information</help>
- <completionHelp>
- <path>interfaces vxlan</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vxlan</command>
- <children>
- <leafNode name="brief">
- <properties>
- <help>Show summary of the specified VXLAN interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vxlan</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="vxlan">
+ <node name="vxlan">
<properties>
<help>Show VXLAN interface information</help>
</properties>
@@ -34,6 +16,24 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=vxlan</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified VXLAN interface information</help>
+ <completionHelp>
+ <path>interfaces vxlan</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vxlan</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified VXLAN interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vxlan</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-wireguard.xml.in b/op-mode-definitions/show-interfaces-wireguard.xml.in
index d86152a21..9457953ef 100644
--- a/op-mode-definitions/show-interfaces-wireguard.xml.in
+++ b/op-mode-definitions/show-interfaces-wireguard.xml.in
@@ -4,48 +4,6 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="wireguard">
- <properties>
- <help>Show specified WireGuard interface information</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type wireguard</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireguard</command>
- <children>
- <leafNode name="allowed-ips">
- <properties>
- <help>Show all IP addresses allowed for the specified interface</help>
- </properties>
- <command>sudo wg show "$4" allowed-ips</command>
- </leafNode>
- <leafNode name="endpoints">
- <properties>
- <help>Show all endpoints for the specified interface</help>
- </properties>
- <command>sudo wg show "$4" endpoints</command>
- </leafNode>
- <leafNode name="peers">
- <properties>
- <help>Show all peer IDs for the specified interface</help>
- </properties>
- <command>sudo wg show "$4" peers</command>
- </leafNode>
- <leafNode name="public-key">
- <properties>
- <help>Show interface public-key</help>
- </properties>
- <command>sudo wg show "$4" public-key</command>
- </leafNode>
- <leafNode name="summary">
- <properties>
- <help>Shows current configuration and device information</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces_wireguard.py show_summary --intf-name="$4"</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
<node name="wireguard">
<properties>
<help>Show WireGuard interface information</help>
@@ -58,6 +16,48 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=wireguard</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified WireGuard interface information</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type wireguard</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireguard</command>
+ <children>
+ <leafNode name="allowed-ips">
+ <properties>
+ <help>Show all IP addresses allowed for the specified interface</help>
+ </properties>
+ <command>wg show "$4" allowed-ips</command>
+ </leafNode>
+ <leafNode name="endpoints">
+ <properties>
+ <help>Show all endpoints for the specified interface</help>
+ </properties>
+ <command>wg show "$4" endpoints</command>
+ </leafNode>
+ <leafNode name="peers">
+ <properties>
+ <help>Show all peer IDs for the specified interface</help>
+ </properties>
+ <command>wg show "$4" peers</command>
+ </leafNode>
+ <leafNode name="public-key">
+ <properties>
+ <help>Show interface public-key</help>
+ </properties>
+ <command>wg show "$4" public-key</command>
+ </leafNode>
+ <leafNode name="summary">
+ <properties>
+ <help>Shows current configuration and device information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces_wireguard.py show_summary --intf-name="$4"</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-wireless.xml.in b/op-mode-definitions/show-interfaces-wireless.xml.in
index b0a1502de..55e23adf5 100644
--- a/op-mode-definitions/show-interfaces-wireless.xml.in
+++ b/op-mode-definitions/show-interfaces-wireless.xml.in
@@ -6,7 +6,7 @@
<children>
<node name="wireless">
<properties>
- <help>Show Wireless (WLAN) interface information</help>
+ <help>Show wireless (WLAN) interface information</help>
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=wireless</command>
<children>
@@ -22,61 +22,61 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces_wireless.py show_info</command>
</leafNode>
- </children>
- </node>
- <tagNode name="wireless">
- <properties>
- <help>Show specified wireless interface information</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces --type wireless</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireless</command>
- <children>
- <leafNode name="brief">
+ <virtualTagNode>
<properties>
- <help>Show brief summary of the specified wireless interface</help>
+ <help>Show specified wireless interface information</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces --type wireless</script>
+ </completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=wireless</command>
- </leafNode>
- <node name="scan">
- <properties>
- <help>Scan for networks via specified wireless interface</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces_wireless.py show_scan --intf-name="$4"</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireless</command>
<children>
- <leafNode name="detail">
+ <leafNode name="brief">
<properties>
- <help>Show detailed scan results</help>
+ <help>Show brief summary of the specified wireless interface</help>
</properties>
- <command>sudo /sbin/iw dev "$4" scan ap-force</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=wireless</command>
</leafNode>
- </children>
- </node>
- <leafNode name="stations">
- <properties>
- <help>Show specified Wireless interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces_wireless.py show_stations --intf-name="$4"</command>
- </leafNode>
- <tagNode name="vif">
- <properties>
- <help>Show specified virtual network interface (vif) information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=wireless</command>
- <children>
- <leafNode name="brief">
+ <node name="scan">
<properties>
- <help>Show summary of specified virtual network interface (vif) information</help>
+ <help>Scan for networks via specified wireless interface</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces_wireless.py show_scan --intf-name="$4"</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed scan results</help>
+ </properties>
+ <command>/sbin/iw dev "$4" scan ap-force</command>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="stations">
+ <properties>
+ <help>Show specified wireless interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces_wireless.py show_stations --intf-name="$4"</command>
</leafNode>
+ <tagNode name="vif">
+ <properties>
+ <help>Show specified virtual network interface (vif) information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=wireless</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of specified virtual network interface (vif) information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=wireless</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/show-interface-type-event-log.xml.i>
</children>
- </tagNode>
- #include <include/show-interface-type-event-log.xml.i>
+ </virtualTagNode>
</children>
- </tagNode>
- </children>
+ </node>
+ </children>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-wwan.xml.in b/op-mode-definitions/show-interfaces-wwan.xml.in
index 2301b32d0..6616de9dc 100644
--- a/op-mode-definitions/show-interfaces-wwan.xml.in
+++ b/op-mode-definitions/show-interfaces-wwan.xml.in
@@ -4,86 +4,7 @@
<children>
<node name="interfaces">
<children>
- <tagNode name="wwan">
- <properties>
- <help>Show specified Wireless Wire Area Network (WWAN) interface information</help>
- <completionHelp>
- <path>interfaces wwan</path>
- <script>cd /sys/class/net; ls -d wwan*</script>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wirelessmodem</command>
- <children>
- <leafNode name="capabilities">
- <properties>
- <help>Show WWAN module capabilities</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --capabilities</command>
- </leafNode>
- <leafNode name="firmware">
- <properties>
- <help>Show WWAN module firmware</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --firmware</command>
- </leafNode>
- <leafNode name="imei">
- <properties>
- <help>Show WWAN module IMEI/ESN/MEID</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --imei</command>
- </leafNode>
- <leafNode name="imsi">
- <properties>
- <help>Show WWAN module IMSI</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --imsi</command>
- </leafNode>
- <leafNode name="model">
- <properties>
- <help>Show WWAN module manufacturer</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --model</command>
- </leafNode>
- <leafNode name="msisdn">
- <properties>
- <help>Show WWAN module MSISDN</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --msisdn</command>
- </leafNode>
- <leafNode name="revision">
- <properties>
- <help>Show WWAN module revision</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --revision</command>
- </leafNode>
- <leafNode name="signal">
- <properties>
- <help>Show WWAN module RF signal info</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --signal</command>
- </leafNode>
- <leafNode name="sim">
- <properties>
- <help>Show WWAN module connected SIM card information</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --sim</command>
- </leafNode>
- <leafNode name="detail">
- <properties>
- <help>Show WWAN module detailed information summary</help>
- </properties>
- <command>if cli-shell-api existsActive interfaces wwan $4; then mmcli --modem ${4#wwan}; else echo "Interface \"$4\" unconfigured!"; fi</command>
- </leafNode>
- <leafNode name="log">
- <properties>
- <help>Show interface log for specified interface</help>
- </properties>
- <command>echo not implemented</command>
- </leafNode>
- #include <include/show-interface-type-event-log.xml.i>
- </children>
- </tagNode>
- <node name="wwan">
+ <node name="wwan">
<properties>
<help>Show Wireless Modem (WWAN) interface information</help>
</properties>
@@ -95,6 +16,85 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=wwan</command>
</leafNode>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified Wireless Wire Area Network (WWAN) interface information</help>
+ <completionHelp>
+ <path>interfaces wwan</path>
+ <script>cd /sys/class/net; ls -d wwan*</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wirelessmodem</command>
+ <children>
+ <leafNode name="capabilities">
+ <properties>
+ <help>Show WWAN module capabilities</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --capabilities</command>
+ </leafNode>
+ <leafNode name="firmware">
+ <properties>
+ <help>Show WWAN module firmware</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --firmware</command>
+ </leafNode>
+ <leafNode name="imei">
+ <properties>
+ <help>Show WWAN module IMEI/ESN/MEID</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --imei</command>
+ </leafNode>
+ <leafNode name="imsi">
+ <properties>
+ <help>Show WWAN module IMSI</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --imsi</command>
+ </leafNode>
+ <leafNode name="model">
+ <properties>
+ <help>Show WWAN module manufacturer</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --model</command>
+ </leafNode>
+ <leafNode name="msisdn">
+ <properties>
+ <help>Show WWAN module MSISDN</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --msisdn</command>
+ </leafNode>
+ <leafNode name="revision">
+ <properties>
+ <help>Show WWAN module revision</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --revision</command>
+ </leafNode>
+ <leafNode name="signal">
+ <properties>
+ <help>Show WWAN module RF signal info</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --signal</command>
+ </leafNode>
+ <leafNode name="sim">
+ <properties>
+ <help>Show WWAN module connected SIM card information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --sim</command>
+ </leafNode>
+ <leafNode name="detail">
+ <properties>
+ <help>Show WWAN module detailed information summary</help>
+ </properties>
+ <command>if cli-shell-api existsActive interfaces wwan $4; then mmcli --modem ${4#wwan}; else echo "Interface \"$4\" unconfigured!"; fi</command>
+ </leafNode>
+ <leafNode name="log">
+ <properties>
+ <help>Show interface log for specified interface</help>
+ </properties>
+ <command>echo not implemented</command>
+ </leafNode>
+ #include <include/show-interface-type-event-log.xml.i>
+ </children>
+ </virtualTagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces.xml.in b/op-mode-definitions/show-interfaces.xml.in
index 09466647d..e2d7d3dd3 100644
--- a/op-mode-definitions/show-interfaces.xml.in
+++ b/op-mode-definitions/show-interfaces.xml.in
@@ -26,6 +26,48 @@
</properties>
<command>${vyos_op_scripts_dir}/interfaces.py show_summary</command>
</leafNode>
+ <node name="kernel">
+ <properties>
+ <help>Show all interfaces on this system</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel</command>
+ <children>
+ <virtualTagNode>
+ <properties>
+ <completionHelp>
+ <script>ip -j link show | jq -r '.[].ifname'</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel --intf-name=$4</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show system interface in JSON format</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel --intf-name=$4 --detail</command>
+ </leafNode>
+ <leafNode name="json">
+ <properties>
+ <help>Show system interface in JSON format</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel --intf-name=$4 --raw</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
+ <leafNode name="detail">
+ <properties>
+ <help>Show system interface in JSON format</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel --detail</command>
+ </leafNode>
+ <leafNode name="json">
+ <properties>
+ <help>Show all interfaces in JSON format</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_kernel --raw</command>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-ip-access-paths-prefix-community-lists.xml.in b/op-mode-definitions/show-ip-access-paths-prefix-community-lists.xml.in
index d7222516a..7a466d8c1 100644
--- a/op-mode-definitions/show-ip-access-paths-prefix-community-lists.xml.in
+++ b/op-mode-definitions/show-ip-access-paths-prefix-community-lists.xml.in
@@ -7,65 +7,57 @@
<help>Show IPv4 routing information</help>
</properties>
<children>
- <leafNode name="access-list">
- <properties>
- <help>Show all IP access-lists</help>
- </properties>
- <command>vtysh -c "show ip access-list"</command>
- </leafNode>
<tagNode name="access-list">
<properties>
- <help>Show all IP access-lists</help>
+ <help>Show IP access-list</help>
<completionHelp>
<path>policy access-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show ip access-list $4"</command>
+ <standalone>
+ <help>Show all IP access lists</help>
+ <command>vtysh -c "show ip access-list"</command>
+ </standalone>
</tagNode>
- <leafNode name="as-path-access-list">
- <properties>
- <help>Show all as-path-access-lists</help>
- </properties>
- <command>vtysh -c "show ip as-path-access-list"</command>
- </leafNode>
<tagNode name="as-path-access-list">
<properties>
- <help>Show all as-path-access-lists</help>
+ <help>Show as-path-access-list</help>
<completionHelp>
<path>policy as-path-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show ip as-path-access-list $4"</command>
+ <standalone>
+ <help>Show all AS path access lists</help>
+ <command>vtysh -c "show ip as-path-access-list"</command>
+ </standalone>
</tagNode>
- <leafNode name="community-list">
- <properties>
- <help>Show IP community-lists</help>
- </properties>
- <command>vtysh -c "show bgp community-list"</command>
- </leafNode>
<tagNode name="community-list">
<properties>
- <help>Show IP community-lists</help>
+ <help>Show BGP community-list</help>
<completionHelp>
<path>policy community-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show bgp community-list $4 detail"</command>
+ <standalone>
+ <help>Show all BGP community lists</help>
+ <command>vtysh -c "show bgp community-list"</command>
+ </standalone>
</tagNode>
- <leafNode name="extcommunity-list">
- <properties>
- <help>Show extended IP community-lists</help>
- </properties>
- <command>vtysh -c "show bgp extcommunity-list"</command>
- </leafNode>
<tagNode name="extcommunity-list">
<properties>
- <help>Show extended IP community-lists</help>
+ <help>Show extended BGP community list</help>
<completionHelp>
<path>policy extcommunity-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show bgp extcommunity-list $4 detail"</command>
+ <standalone>
+ <help>Show all extended BGP community lists</help>
+ <command>vtysh -c "show bgp extcommunity-list"</command>
+ </standalone>
</tagNode>
<leafNode name="forwarding">
<properties>
@@ -73,35 +65,31 @@
</properties>
<command>vtysh -c "show ip forwarding"</command>
</leafNode>
- <leafNode name="large-community-list">
- <properties>
- <help>Show IP large-community-lists</help>
- </properties>
- <command>vtysh -c "show bgp large-community-list"</command>
- </leafNode>
<tagNode name="large-community-list">
<properties>
- <help>Show IP large-community-lists</help>
+ <help>Show BGP large-community-list</help>
<completionHelp>
<path>policy large-community-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show bgp large-community-list $4 detail"</command>
+ <standalone>
+ <help>Show all BGP large community lists</help>
+ <command>vtysh -c "show bgp large-community-list"</command>
+ </standalone>
</tagNode>
- <leafNode name="prefix-list">
- <properties>
- <help>Show all IP prefix-lists</help>
- </properties>
- <command>vtysh -c "show ip prefix-list"</command>
- </leafNode>
<tagNode name="prefix-list">
<properties>
- <help>Show all IP prefix-lists</help>
+ <help>Show IP prefix-list</help>
<completionHelp>
<path>policy prefix-list</path>
</completionHelp>
</properties>
<command>vtysh -c "show ip prefix-list $4"</command>
+ <standalone>
+ <help>Show all IP prefix lists</help>
+ <command>vtysh -c "show ip prefix-list"</command>
+ </standalone>
</tagNode>
<leafNode name="protocol">
<properties>
diff --git a/op-mode-definitions/show-ip-bgp.xml.in b/op-mode-definitions/show-ip-bgp.xml.in
index ecef320bf..f2b98582e 100644
--- a/op-mode-definitions/show-ip-bgp.xml.in
+++ b/op-mode-definitions/show-ip-bgp.xml.in
@@ -11,12 +11,6 @@
<command>vtysh -c "show ip bgp"</command>
<children>
#include <include/bgp/show-ip-bgp-common.xml.i>
- <leafNode name="vrf">
- <properties>
- <help>Show BGP VRF information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
<tagNode name="vrf">
<properties>
<help>Show BGP VRF related information</help>
@@ -25,6 +19,10 @@
<list>all</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show BGP VRF information</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
#include <include/bgp/show-ip-bgp-common.xml.i>
diff --git a/op-mode-definitions/show-ip-ports.xml.in b/op-mode-definitions/show-ip-ports.xml.in
index a74b68ffc..0d4eec351 100644
--- a/op-mode-definitions/show-ip-ports.xml.in
+++ b/op-mode-definitions/show-ip-ports.xml.in
@@ -8,7 +8,7 @@
<properties>
<help>Show IP ports in use by various system services</help>
</properties>
- <command>sudo /usr/bin/netstat -tulnp</command>
+ <command>/usr/bin/netstat -tulnp</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-ip-route.xml.in b/op-mode-definitions/show-ip-route.xml.in
index 37279d3d2..bbac433c7 100644
--- a/op-mode-definitions/show-ip-route.xml.in
+++ b/op-mode-definitions/show-ip-route.xml.in
@@ -13,13 +13,24 @@
</properties>
<command>vtysh -c "show ip route"</command>
<children>
- #include <include/show-route-bgp.xml.i>
- <node name="cache">
+ <virtualTagNode>
<properties>
- <help>Show kernel route cache</help>
+ <help>Show IP routes of specified IP address or prefix</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
+ </completionHelp>
</properties>
- <command>ip -s route list cache</command>
- </node>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <leafNode name="longer-prefixes">
+ <properties>
+ <help>Show longer prefixes of routes for specified prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
+ #include <include/show-route-bgp.xml.i>
<tagNode name="cache">
<properties>
<help>Show kernel route cache for a given route</help>
@@ -27,15 +38,13 @@
<list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show kernel route cache</help>
+ <command>ip -s route list cache</command>
+ </standalone>
<command>ip -s route list cache $5</command>
</tagNode>
#include <include/show-route-connected.xml.i>
- <node name="forward">
- <properties>
- <help>Show kernel route table</help>
- </properties>
- <command>ip route list</command>
- </node>
<tagNode name="forward">
<properties>
<help>Show kernel route table for a given route</help>
@@ -43,6 +52,10 @@
<list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show kernel route table</help>
+ <command>ip route list</command>
+ </standalone>
<command>ip -s route list $5</command>
</tagNode>
#include <include/show-route-isis.xml.i>
@@ -93,7 +106,7 @@
#include <include/show-route-static.xml.i>
#include <include/show-route-supernets-only.xml.i>
#include <include/show-route-tag.xml.i>
- <node name="node.tag">
+ <virtualTagNode>
<properties>
<help>Show IP routes of specified IP address or prefix</help>
<completionHelp>
@@ -109,28 +122,11 @@
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</leafNode>
</children>
- </node>
+ </virtualTagNode>
</children>
</tagNode>
</children>
</node>
- <tagNode name="route">
- <properties>
- <help>Show IP routes of specified IP address or prefix</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <leafNode name="longer-prefixes">
- <properties>
- <help>Show longer prefixes of routes for specified prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
- </children>
- </tagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-ipv6-ospfv3.xml.in b/op-mode-definitions/show-ipv6-ospfv3.xml.in
index e1fcf470f..b4a1c6c8a 100644
--- a/op-mode-definitions/show-ipv6-ospfv3.xml.in
+++ b/op-mode-definitions/show-ipv6-ospfv3.xml.in
@@ -13,12 +13,6 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <node name="area">
- <properties>
- <help>Show Shortest Path First tree information</help>
- </properties>
- <command>vtysh -c "show ipv6 ospf6 spf tree"</command>
- </node>
<tagNode name="area">
<properties>
<help>Area ID (as an IPv4 notation)</help>
@@ -27,6 +21,10 @@
</completionHelp>
</properties>
<command>vtysh -c "show ipv6 ospf6 area $5 spf tree"</command>
+ <standalone>
+ <help>Show Shortest Path First tree information</help>
+ <command>vtysh -c "show ipv6 ospf6 spf tree"</command>
+ </standalone>
<children>
<tagNode name="router">
<properties>
@@ -47,16 +45,6 @@
#include <include/ospfv3/neighbor.xml.i>
#include <include/ospfv3/redistribute.xml.i>
#include <include/ospfv3/route.xml.i>
- <node name="vrf">
- <properties>
- <help>Specify the VRF</help>
- <completionHelp>
- <list>all</list>
- <path>vrf name</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
<tagNode name="vrf">
<properties>
<help>VRF name</help>
@@ -66,13 +54,11 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <standalone>
+ <help>Show OSPFv3 information in given VRF</help>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </standalone>
<children>
- <node name="area">
- <properties>
- <help>Show Shortest Path First tree information</help>
- </properties>
- <command>vtysh -c "show ipv6 ospf6 vrf $5 spf tree"</command>
- </node>
<tagNode name="area">
<properties>
<help>Area ID (as an IPv4 notation)</help>
@@ -81,6 +67,10 @@
</completionHelp>
</properties>
<command>vtysh -c "show ipv6 ospf6 vrf $5 area $7 spf tree"</command>
+ <standalone>
+ <help>Show Shortest Path First tree information</help>
+ <command>vtysh -c "show ipv6 ospf6 vrf $5 spf tree"</command>
+ </standalone>
<children>
<tagNode name="router">
<properties>
diff --git a/op-mode-definitions/show-ipv6-prefix-list.xml.in b/op-mode-definitions/show-ipv6-prefix-list.xml.in
index e003ad110..db1a2754e 100644
--- a/op-mode-definitions/show-ipv6-prefix-list.xml.in
+++ b/op-mode-definitions/show-ipv6-prefix-list.xml.in
@@ -13,78 +13,72 @@
</properties>
<command>vtysh -c "show ipv6 prefix-list"</command>
<children>
- <node name="detail">
+ <virtualTagNode>
<properties>
- <help>Show detail of IPv6 prefix-lists</help>
- </properties>
- <command>vtysh -c "show ipv6 prefix-list detail"</command>
- </node>
- <tagNode name="detail">
- <properties>
- <help>Show detail of specified IPv6 prefix-list</help>
- </properties>
- <command>vtysh -c "show ipv6 prefix-list detail $5"</command>
- </tagNode>
- <node name="summary">
- <properties>
- <help>Show summary of IPv6 prefix-lists</help>
- </properties>
- <command>vtysh -c "show ipv6 prefix-list summary"</command>
- </node>
- <tagNode name="summary">
- <properties>
- <help>Show summary of specified IPv6 prefix-list</help>
- </properties>
- <command>vtysh -c "show ipv6 prefix-list summary $5"</command>
- </tagNode>
- </children>
- </node>
- <tagNode name="prefix-list">
- <properties>
- <help>Show specified IPv6 prefix-list</help>
- <completionHelp>
- <list>WORD</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ipv6 prefix-list $4"</command>
- <children>
- <node name="node.tag">
- <properties>
- <help>Show select prefix of specified IPv6 prefix-list</help>
+ <help>Show specified IPv6 prefix-list</help>
<completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ <list>WORD</list>
</completionHelp>
</properties>
- <command>vtysh -c "show ipv6 prefix-list $4 $5"</command>
+ <command>vtysh -c "show ipv6 prefix-list $4"</command>
<children>
- <node name="first-match">
+ <virtualTagNode>
<properties>
- <help>Show first-match from select prefix of named IPv6 prefix-list</help>
+ <help>Show select prefix of specified IPv6 prefix-list</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
</properties>
- <command>vtysh -c "show ipv6 prefix-list $4 $5 first-match"</command>
- </node>
- <node name="longer">
+ <command>vtysh -c "show ipv6 prefix-list $4 $5"</command>
+ <children>
+ <node name="first-match">
+ <properties>
+ <help>Show first-match from select prefix of named IPv6 prefix-list</help>
+ </properties>
+ <command>vtysh -c "show ipv6 prefix-list $4 $5 first-match"</command>
+ </node>
+ <node name="longer">
+ <properties>
+ <help>Show longer match of select prefix from named IPv6 prefix-list</help>
+ </properties>
+ <command>vtysh -c "show ipv6 prefix-list $4 $5 longer"</command>
+ </node>
+ </children>
+ </virtualTagNode>
+ <tagNode name="seq">
<properties>
- <help>Show longer match of select prefix from named IPv6 prefix-list</help>
+ <help>Show specified sequence from specified IPv6 prefix-list</help>
</properties>
- <command>vtysh -c "show ipv6 prefix-list $4 $5 longer"</command>
- </node>
+ <standalone>
+ <help>Show specified sequence from specified IPv6 prefix-list</help>
+ <command>vtysh -c "show ipv6 prefix-list $4 seq"</command>
+ </standalone>
+ <command>vtysh -c "show ipv6 prefix-list $4 seq $6"</command>
+ </tagNode>
</children>
- </node>
- <node name="seq">
+ </virtualTagNode>
+ <tagNode name="detail">
<properties>
- <help>Show specified sequence from specified IPv6 prefix-list</help>
+ <help>Show detail of specified IPv6 prefix-list</help>
</properties>
- <command>vtysh -c "show ipv6 prefix-list $4 seq"</command>
- </node>
- <tagNode name="seq">
+ <command>vtysh -c "show ipv6 prefix-list detail $5"</command>
+ <standalone>
+ <help>Show details of IPv6 prefix lists</help>
+ <command>vtysh -c "show ipv6 prefix-list detail"</command>
+ </standalone>
+ </tagNode>
+ <tagNode name="summary">
<properties>
- <help>Show specified sequence from specified IPv6 prefix-list</help>
+ <help>Show summary of specified IPv6 prefix-list</help>
</properties>
- <command>vtysh -c "show ipv6 prefix-list $4 seq $6"</command>
+ <command>vtysh -c "show ipv6 prefix-list summary $5"</command>
+ <standalone>
+ <help>Show summary of IPv6 prefix lists</help>
+ <command>vtysh -c "show ipv6 prefix-list summary"</command>
+ </standalone>
</tagNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-ipv6-route.xml.in b/op-mode-definitions/show-ipv6-route.xml.in
index f68a94971..8690ed710 100644
--- a/op-mode-definitions/show-ipv6-route.xml.in
+++ b/op-mode-definitions/show-ipv6-route.xml.in
@@ -13,13 +13,24 @@
</properties>
<command>vtysh -c "show ipv6 route"</command>
<children>
- #include <include/show-route-bgp.xml.i>
- <node name="cache">
+ <virtualTagNode>
<properties>
- <help>Show kernel IPv6 route cache</help>
+ <help>Show IPv6 routes of given address or prefix</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
</properties>
- <command>ip -s -f inet6 route list cache</command>
- </node>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="longer-prefixes">
+ <properties>
+ <help>Show longer prefixes of routes for given prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </virtualTagNode>
+ #include <include/show-route-bgp.xml.i>
<tagNode name="cache">
<properties>
<help>Show kernel IPv6 route cache for a given route</help>
@@ -27,15 +38,13 @@
<list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show kernel IPv6 route cache</help>
+ <command>ip -s -f inet6 route list cache</command>
+ </standalone>
<command>ip -s -f inet6 route list cache $5</command>
</tagNode>
#include <include/show-route-connected.xml.i>
- <node name="forward">
- <properties>
- <help>Show kernel IPv6 route table</help>
- </properties>
- <command>ip -f inet6 route list</command>
- </node>
<tagNode name="forward">
<properties>
<help>Show kernel IPv6 route table for a given route</help>
@@ -43,6 +52,10 @@
<list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show kernel IPv6 route table</help>
+ <command>ip -f inet6 route list</command>
+ </standalone>
<command>ip -s -f inet6 route list $5</command>
</tagNode>
#include <include/show-route-isis.xml.i>
@@ -83,7 +96,7 @@
</properties>
<command>${vyos_op_scripts_dir}/route.py show_summary --family inet6 --vrf $5</command>
</node>
- <node name="node.tag">
+ <virtualTagNode>
<properties>
<help>Show IPv6 routes of given address or prefix</help>
<completionHelp>
@@ -99,7 +112,7 @@
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
</children>
- </node>
+ </virtualTagNode>
#include <include/show-route-bgp.xml.i>
#include <include/show-route-connected.xml.i>
#include <include/show-route-isis.xml.i>
@@ -114,23 +127,6 @@
</tagNode>
</children>
</node>
- <tagNode name="route">
- <properties>
- <help>Show IPv6 routes of given address or prefix</help>
- <completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="longer-prefixes">
- <properties>
- <help>Show longer prefixes of routes for given prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- </children>
- </tagNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-ipv6.xml.in b/op-mode-definitions/show-ipv6.xml.in
index e10379ac2..314a686fe 100644
--- a/op-mode-definitions/show-ipv6.xml.in
+++ b/op-mode-definitions/show-ipv6.xml.in
@@ -7,12 +7,6 @@
<help>Show IPv6 networking information</help>
</properties>
<children>
- <node name="access-list">
- <properties>
- <help>Show all IPv6 access-lists</help>
- </properties>
- <command>vtysh -c "show ipv6 access-list"</command>
- </node>
<tagNode name="access-list">
<properties>
<help>Show specified IPv6 access-list</help>
@@ -21,6 +15,10 @@
</completionHelp>
</properties>
<command>vtysh -c "show ipv6 access-list $4"</command>
+ <standalone>
+ <help>Show all IPv6 access-lists</help>
+ <command>vtysh -c "show ipv6 access-list"</command>
+ </standalone>
</tagNode>
<node name="forwarding">
<properties>
diff --git a/op-mode-definitions/show-kernel-modules.xml.in b/op-mode-definitions/show-kernel-modules.xml.in
index 28eb28212..67a0130fb 100644
--- a/op-mode-definitions/show-kernel-modules.xml.in
+++ b/op-mode-definitions/show-kernel-modules.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Show kernel modules</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/kernel_modules.py show</command>
+ <command>${vyos_op_scripts_dir}/kernel_modules.py show</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in
index 5ee7c973f..499e7f84b 100755
--- a/op-mode-definitions/show-log.xml.in
+++ b/op-mode-definitions/show-log.xml.in
@@ -5,21 +5,21 @@
<help>Show system information</help>
</properties>
<children>
- <tagNode name="log">
- <properties>
- <help>Show last number of messages in master logging buffer</help>
- <completionHelp>
- <list>&lt;1-9999&gt;</list>
- </completionHelp>
- </properties>
- <command>if ${vyos_validators_dir}/numeric --range 1-9999 "$3"; then journalctl --no-hostname --boot --lines "$3"; fi</command>
- </tagNode>
- <node name="log">
+ <node name="log">
<properties>
<help>Show contents of current master logging buffer</help>
</properties>
<command>journalctl --no-hostname --boot</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show last number of messages in master logging buffer</help>
+ <completionHelp>
+ <list>&lt;1-9999&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>if ${vyos_validators_dir}/numeric --range 1-9999 "$3"; then journalctl --no-hostname --boot --lines "$3"; fi</command>
+ </virtualTagNode>
<leafNode name="audit">
<properties>
<help>Show audit logs</help>
@@ -30,7 +30,7 @@
<properties>
<help>Show contents of all master log files</help>
</properties>
- <command>sudo bash -c 'eval $(lesspipe); less $_vyatta_less_options --prompt=".logm, file %i of %m., page %dt of %D" -- `printf "%s\n" /var/log/messages* | sort -nr`'</command>
+ <command>bash -c 'eval $(lesspipe); less $_vyatta_less_options --prompt=".logm, file %i of %m., page %dt of %D" -- `printf "%s\n" /var/log/messages* | sort -nr`'</command>
</leafNode>
<leafNode name="authorization">
<properties>
@@ -42,7 +42,7 @@
<properties>
<help>Show log for certbot</help>
</properties>
- <command>if sudo test -f /var/log/letsencrypt/letsencrypt.log; then sudo cat /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
+ <command>if test -f /var/log/letsencrypt/letsencrypt.log; then cat /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
</leafNode>
<leafNode name="cluster">
<properties>
@@ -50,6 +50,39 @@
</properties>
<command>cat $(printf "%s\n" /var/log/messages* | sort -nr) | grep -e heartbeat -e cl_status -e mach_down -e ha_log</command>
</leafNode>
+ <node name="conntrack">
+ <properties>
+ <help>Show log for conntrack events</help>
+ </properties>
+ <command>journalctl --no-hostname --boot -t vyos-conntrack-logger --grep='\[(NEW|UPDATE|DESTROY)\]'</command>
+ <children>
+ <node name="event">
+ <properties>
+ <help>Show log for conntrack events</help>
+ </properties>
+ <children>
+ <leafNode name="new">
+ <properties>
+ <help>Show log for conntrack events</help>
+ </properties>
+ <command>journalctl --no-hostname --boot -t vyos-conntrack-logger --grep='\[(NEW)\]'</command>
+ </leafNode>
+ <leafNode name="update">
+ <properties>
+ <help>Show log for conntrack events</help>
+ </properties>
+ <command>journalctl --no-hostname --boot -t vyos-conntrack-logger --grep='\[(UPDATE)\]'</command>
+ </leafNode>
+ <leafNode name="destroy">
+ <properties>
+ <help>Show log for Conntrack Events</help>
+ </properties>
+ <command>journalctl --no-hostname --boot -t vyos-conntrack-logger --grep='\[(DESTROY)\]'</command>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
<leafNode name="conntrack-sync">
<properties>
<help>Show log for Conntrack-sync</help>
@@ -62,19 +95,6 @@
</properties>
<command>journalctl --no-hostname --boot --unit conserver-server.service</command>
</leafNode>
- <node name="ids">
- <properties>
- <help>Show log for for Intrusion Detection System</help>
- </properties>
- <children>
- <leafNode name="ddos-protection">
- <properties>
- <help>Show log for DDOS protection</help>
- </properties>
- <command>journalctl --no-hostname --boot --unit fastnetmon.service</command>
- </leafNode>
- </children>
- </node>
<node name="dhcp">
<properties>
<help>Show log for Dynamic Host Control Protocol (DHCP)</help>
@@ -139,7 +159,7 @@
<properties>
<help>Show log for Firewall</help>
</properties>
- <command>journalctl --no-hostname --boot -k | egrep "(ipv[46]|bri)-(FWD|INP|OUT|NAM)"</command>
+ <command>journalctl --no-hostname --boot -k --grep='(ipv[46]|bri)-(FWD|INP|OUT|NAM)|STATE-POLICY'</command>
<children>
<node name="bridge">
<properties>
@@ -539,6 +559,12 @@
</properties>
<command>journalctl --no-hostname --boot --unit frr.service</command>
</leafNode>
+ <leafNode name="haproxy">
+ <properties>
+ <help>Show log for HAProxy</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit haproxy.service</command>
+ </leafNode>
<leafNode name="https">
<properties>
<help>Show log for HTTPs</help>
@@ -651,12 +677,6 @@
</properties>
<command>journalctl --no-hostname --boot --unit ndppd.service</command>
</leafNode>
- <leafNode name="nhrp">
- <properties>
- <help>Show log for Next Hop Resolution Protocol (NHRP)</help>
- </properties>
- <command>journalctl --no-hostname --boot --unit opennhrp.service</command>
- </leafNode>
<leafNode name="ntp">
<properties>
<help>Show log for Network Time Protocol (NTP)</help>
@@ -811,6 +831,12 @@
</properties>
<command>journalctl --no-hostname --boot --unit snmpd.service</command>
</leafNode>
+ <leafNode name="spanning-tree">
+ <properties>
+ <help>Show log for Spanning Tree Protocol (STP)</help>
+ </properties>
+ <command>journalctl --dmesg --no-hostname --boot --grep='br[0-9].*(stp|bpdu|blocking|disabled|forwarding|listening|root port)'</command>
+ </leafNode>
<node name="ssh">
<properties>
<help>Show log for Secure Shell (SSH)</help>
@@ -832,14 +858,12 @@
<list>&lt;NUMBER&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Show last 10 lines of /var/log/messages file</help>
+ <command>tail -n 10 /var/log/messages</command>
+ </standalone>
<command>tail -n "$4" /var/log/messages | ${VYATTA_PAGER:-cat}</command>
</tagNode>
- <node name="tail">
- <properties>
- <help>Show last 10 lines of /var/log/messages file</help>
- </properties>
- <command>tail -n 10 /var/log/messages</command>
- </node>
<leafNode name="vpn">
<properties>
<help>Show log for ALL Virtual Private Network services</help>
diff --git a/op-mode-definitions/show-login.xml.in b/op-mode-definitions/show-login.xml.in
index 6d8c782c4..664677bc6 100644
--- a/op-mode-definitions/show-login.xml.in
+++ b/op-mode-definitions/show-login.xml.in
@@ -14,12 +14,6 @@
</properties>
<command>/usr/bin/id -Gn</command>
</leafNode>
- <leafNode name="level">
- <properties>
- <help>Show current login level</help>
- </properties>
- <command>if [ -n "$VYATTA_USER_LEVEL_DIR" ]; then basename $VYATTA_USER_LEVEL_DIR; fi</command>
- </leafNode>
<leafNode name="user">
<properties>
<help>Show current login user id</help>
diff --git a/op-mode-definitions/show-mpls.xml.in b/op-mode-definitions/show-mpls.xml.in
index 86f6f1bcc..43fa26b64 100644
--- a/op-mode-definitions/show-mpls.xml.in
+++ b/op-mode-definitions/show-mpls.xml.in
@@ -18,6 +18,23 @@
</properties>
<command>vtysh -c "show mpls ldp binding"</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>LDP forwarding equivalence class</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h/h&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>vtysh -c "show mpls ldp binding $5"</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed information</help>
+ </properties>
+ <command>vtysh -c "show mpls ldp binding $5 detail"</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
<node name="detail">
<properties>
<help>Show detailed information</help>
@@ -116,23 +133,6 @@
</tagNode>
</children>
</node>
- <tagNode name="binding">
- <properties>
- <help>LDP forwarding equivalence class</help>
- <completionHelp>
- <list>&lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h/h&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show mpls ldp binding $5"</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed information</help>
- </properties>
- <command>vtysh -c "show mpls ldp binding $5 detail"</command>
- </leafNode>
- </children>
- </tagNode>
<node name="discovery">
<properties>
<help>Discovery hello information</help>
@@ -171,32 +171,32 @@
</properties>
<command>vtysh -c "show mpls ldp neighbor capabilities"</command>
</leafNode>
- </children>
- </node>
- <tagNode name="neighbor">
- <properties>
- <help>LDP neighbor</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- <script>vtysh -c "show mpls ldp neighbor" | awk '{print $2}' | egrep -v "ID"</script>
- </completionHelp>
- </properties>
- <command>vtysh -c "show mpls ldp neighbor $5"</command>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed information</help>
- </properties>
- <command>vtysh -c "show mpls ldp neighbor $5 detail"</command>
- </leafNode>
- <leafNode name="capabilities">
+ <virtualTagNode>
<properties>
- <help>Show neighbor capability information</help>
+ <help>LDP neighbor</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
+ <script>vtysh -c "show mpls ldp neighbor" | awk '{print $2}' | egrep -v "ID"</script>
+ </completionHelp>
</properties>
- <command>vtysh -c "show mpls ldp neighbor $5 capabilities"</command>
- </leafNode>
+ <command>vtysh -c "show mpls ldp neighbor $5"</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed information</help>
+ </properties>
+ <command>vtysh -c "show mpls ldp neighbor $5 detail"</command>
+ </leafNode>
+ <leafNode name="capabilities">
+ <properties>
+ <help>Show neighbor capability information</help>
+ </properties>
+ <command>vtysh -c "show mpls ldp neighbor $5 capabilities"</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
<node name="pseudowire">
diff --git a/op-mode-definitions/show-openfabric.xml.in b/op-mode-definitions/show-openfabric.xml.in
index 2f489866e..124b9616e 100644
--- a/op-mode-definitions/show-openfabric.xml.in
+++ b/op-mode-definitions/show-openfabric.xml.in
@@ -24,11 +24,11 @@
</completionHelp>
</properties>
<children>
+ #include <include/vtysh-generic-interface-virtualTagNode.xml.i>
#include <include/vtysh-generic-detail.xml.i>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</node>
- #include <include/vtysh-generic-interface-tagNode.xml.i>
<node name="neighbor">
<properties>
<help>Show OpenFabric neighbor adjacencies</help>
diff --git a/op-mode-definitions/show-qos.xml.in b/op-mode-definitions/show-qos.xml.in
index 8974e9541..12b215d8d 100644
--- a/op-mode-definitions/show-qos.xml.in
+++ b/op-mode-definitions/show-qos.xml.in
@@ -20,7 +20,7 @@
<list>&lt;interface&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_cake --ifname $5</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_cake --ifname $5</command>
</tagNode>
</children>
</node>
@@ -28,13 +28,13 @@
<properties>
<help>Show QoS shaping information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper</command>
<children>
<leafNode name="detail">
<properties>
<help>Show QoS detailed information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper --detail</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper --detail</command>
</leafNode>
<tagNode name="interface">
<properties>
@@ -44,7 +44,7 @@
<list>&lt;interface&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5</command>
<children>
<tagNode name="class">
<properties>
@@ -53,13 +53,13 @@
<list>&lt;class&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --classn $7</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --classn $7</command>
<children>
<leafNode name="detail">
<properties>
<help>Show QoS detailed information for given class</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --classn $7 --detail</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --classn $7 --detail</command>
</leafNode>
</children>
</tagNode>
@@ -67,7 +67,7 @@
<properties>
<help>Show QoS detailed information for given interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --detail</command>
+ <command>${vyos_op_scripts_dir}/qos.py show_shaper --ifname $5 --detail</command>
</leafNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/show-raid.xml.in b/op-mode-definitions/show-raid.xml.in
index 2ae3fad6a..8bf394552 100644
--- a/op-mode-definitions/show-raid.xml.in
+++ b/op-mode-definitions/show-raid.xml.in
@@ -9,7 +9,7 @@
<script>${vyos_completion_dir}/list_raidset.sh</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/show_raid.sh $3</command>
+ <command>${vyos_op_scripts_dir}/show_raid.sh $3</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/show-route-map.xml.in b/op-mode-definitions/show-route-map.xml.in
index 633b2a4cb..a34ae0200 100644
--- a/op-mode-definitions/show-route-map.xml.in
+++ b/op-mode-definitions/show-route-map.xml.in
@@ -2,12 +2,6 @@
<interfaceDefinition>
<node name="show">
<children>
- <node name="route-map">
- <properties>
- <help>Show route-map information</help>
- </properties>
- <command>vtysh -c "show route-map"</command>
- </node>
<tagNode name="route-map">
<properties>
<help>Show specified route-map information</help>
@@ -16,6 +10,10 @@
</completionHelp>
</properties>
<command>vtysh -c "show route-map $3"</command>
+ <standalone>
+ <help>Show route map information</help>
+ <command>vtysh -c "show route-map"</command>
+ </standalone>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/show-ssh.xml.in b/op-mode-definitions/show-ssh.xml.in
index ca8e669b3..88faecada 100644
--- a/op-mode-definitions/show-ssh.xml.in
+++ b/op-mode-definitions/show-ssh.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Show SSH server dynamic-protection blocked attackers</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ssh.py show_dynamic_protection</command>
+ <command>${vyos_op_scripts_dir}/ssh.py show_dynamic_protection</command>
</node>
<node name="fingerprints">
<properties>
diff --git a/op-mode-definitions/show-system.xml.in b/op-mode-definitions/show-system.xml.in
index 6873b816b..c7b57893f 100644
--- a/op-mode-definitions/show-system.xml.in
+++ b/op-mode-definitions/show-system.xml.in
@@ -95,7 +95,7 @@
<properties>
<help>Show messages in kernel ring buffer</help>
</properties>
- <command>sudo dmesg</command>
+ <command>dmesg</command>
</leafNode>
<node name="login">
<properties>
@@ -155,31 +155,31 @@
<properties>
<help>Show user account information</help>
</properties>
- <command>${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_users.py</command>
+ <command>${vyos_op_scripts_dir}/show_users.py</command>
<children>
<leafNode name="all">
<properties>
<help>Show information about all accounts</help>
</properties>
- <command>${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_users.py all</command>
+ <command>${vyos_op_scripts_dir}/show_users.py all</command>
</leafNode>
<leafNode name="locked">
<properties>
<help>Show information about locked accounts</help>
</properties>
- <command>${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_users.py locked</command>
+ <command>${vyos_op_scripts_dir}/show_users.py locked</command>
</leafNode>
<leafNode name="other">
<properties>
<help>Show information about non VyOS user accounts</help>
</properties>
- <command>${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_users.py other</command>
+ <command>${vyos_op_scripts_dir}/show_users.py other</command>
</leafNode>
<leafNode name="vyos">
<properties>
<help>Show information about VyOS user accounts</help>
</properties>
- <command>${vyos_libexec_dir}/vyos-sudo.py ${vyos_op_scripts_dir}/show_users.py vyos</command>
+ <command>${vyos_op_scripts_dir}/show_users.py vyos</command>
</leafNode>
</children>
</node>
@@ -195,7 +195,7 @@
<properties>
<help>Show kernel cache information</help>
</properties>
- <command>sudo slabtop -o</command>
+ <command>slabtop -o</command>
</leafNode>
<leafNode name="detail">
<properties>
diff --git a/op-mode-definitions/show-techsupport_report.xml.in b/op-mode-definitions/show-techsupport_report.xml.in
index 4fd6e5d1e..c07cb3c7d 100644
--- a/op-mode-definitions/show-techsupport_report.xml.in
+++ b/op-mode-definitions/show-techsupport_report.xml.in
@@ -17,7 +17,7 @@
<properties>
<help>Show consolidated tech-support report in JSON</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/tech_support.py show --raw</command>
+ <command>${vyos_op_scripts_dir}/tech_support.py show --raw</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/show-users.xml.in b/op-mode-definitions/show-users.xml.in
index a026e47e7..a9cde3138 100644
--- a/op-mode-definitions/show-users.xml.in
+++ b/op-mode-definitions/show-users.xml.in
@@ -8,12 +8,6 @@
</properties>
<command>who -H</command>
<children>
- <node name="recent">
- <properties>
- <help>Show 10 recently logged in users</help>
- </properties>
- <command>last -aF -n 10 | sed -e 's/^wtmp begins/Displaying logins since/'</command>
- </node>
<tagNode name="recent">
<properties>
<help>Show specified number of recently logged in users</help>
@@ -22,6 +16,10 @@
</completionHelp>
</properties>
<command>last -aF -n $4 | sed -e 's/^wtmp begins/Displaying logins since/'</command>
+ <standalone>
+ <help>Show 10 recently logged in users</help>
+ <command>last -aF -n 10 | sed -e 's/^wtmp begins/Displaying logins since/'</command>
+ </standalone>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/show-version.xml.in b/op-mode-definitions/show-version.xml.in
index 36e68ff79..dc158673d 100644
--- a/op-mode-definitions/show-version.xml.in
+++ b/op-mode-definitions/show-version.xml.in
@@ -6,13 +6,13 @@
<properties>
<help>Show system version information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/version.py show</command>
+ <command>${vyos_op_scripts_dir}/version.py show</command>
<children>
<leafNode name="funny">
<properties>
<help>Show system version and some fun stuff</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/version.py show --funny</command>
+ <command>${vyos_op_scripts_dir}/version.py show --funny</command>
</leafNode>
<leafNode name="all">
<properties>
diff --git a/op-mode-definitions/show-vrf.xml.in b/op-mode-definitions/show-vrf.xml.in
index c18649844..574e92bfe 100644
--- a/op-mode-definitions/show-vrf.xml.in
+++ b/op-mode-definitions/show-vrf.xml.in
@@ -14,31 +14,31 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</leafNode>
- </children>
- </node>
- <tagNode name="vrf">
- <properties>
- <help>Show information on specific VRF instance</help>
- <completionHelp>
- <path>vrf name</path>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vrf.py show --name="$3"</command>
- <children>
- <leafNode name="processes">
- <properties>
- <help>Shows all process ids associated with VRF</help>
- </properties>
- <command>ip vrf pids "$3"</command>
- </leafNode>
- <leafNode name="vni">
+ <virtualTagNode>
<properties>
- <help>Show VXLAN VNI association</help>
+ <help>Show information on specific VRF instance</help>
+ <completionHelp>
+ <path>vrf name</path>
+ </completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/vrf.py show --name="$3"</command>
+ <children>
+ <leafNode name="processes">
+ <properties>
+ <help>Shows all process ids associated with VRF</help>
+ </properties>
+ <command>ip vrf pids "$3"</command>
+ </leafNode>
+ <leafNode name="vni">
+ <properties>
+ <help>Show VXLAN VNI association</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ </virtualTagNode>
</children>
- </tagNode>
- </children>
+ </node>
+ </children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/suricata.xml.in b/op-mode-definitions/suricata.xml.in
index ff1f84706..74e54fb9c 100644
--- a/op-mode-definitions/suricata.xml.in
+++ b/op-mode-definitions/suricata.xml.in
@@ -6,7 +6,7 @@
<properties>
<help>Update Suricata</help>
</properties>
- <command>if test -f /run/suricata/suricata.yaml; then sudo suricata-update --suricata-conf /run/suricata/suricata.yaml; sudo systemctl restart suricata; else echo "Service Suricata not configured"; fi </command>
+ <command>${vyos_op_scripts_dir}/update_suricata.sh</command>
</node>
</children>
</node>
@@ -16,7 +16,7 @@
<properties>
<help>Restart Suricata service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name suricata</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name suricata</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/system-image.xml.in b/op-mode-definitions/system-image.xml.in
index 44b055be6..a6634fc65 100644
--- a/op-mode-definitions/system-image.xml.in
+++ b/op-mode-definitions/system-image.xml.in
@@ -17,7 +17,7 @@
<list>/path/to/vyos-image.iso "http://example.com/vyos-image.iso" latest</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}"</command>
+ <command>${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}"</command>
<children>
<tagNode name="vrf">
<properties>
@@ -26,7 +26,7 @@
<path>vrf name</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --vrf "${6}"</command>
+ <command>${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --vrf "${6}"</command>
<children>
<tagNode name="username">
<properties>
@@ -37,7 +37,7 @@
<properties>
<help>Password to use with authentication</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --vrf "${6}" --username "${8}" --password "${10}"</command>
+ <command>${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --vrf "${6}" --username "${8}" --password "${10}"</command>
</tagNode>
</children>
</tagNode>
@@ -52,7 +52,7 @@
<properties>
<help>Password to use with authentication</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --username "${6}" --password "${8}"</command>
+ <command>${vyos_op_scripts_dir}/image_installer.py --action add --image-path "${4}" --username "${6}" --password "${8}"</command>
</tagNode>
</children>
</tagNode>
@@ -76,30 +76,28 @@
<properties>
<help>Set system console type at boot</help>
<completionHelp>
- <script>sudo ${vyos_op_scripts_dir}/image_manager.py --action list_console_types</script>
+ <script>${vyos_op_scripts_dir}/image_manager.py --action list_console_types</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action set_console_type --console-type "${4}"</command>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action set_console_type --console-type "${4}"</command>
</tagNode>
<node name="image">
<properties>
<help>Set system image parameters</help>
</properties>
<children>
- <node name="default-boot">
- <properties>
- <help>Set default image to boot.</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action set</command>
- </node>
<tagNode name="default-boot">
<properties>
- <help>Set default image to boot.</help>
+ <help>Set default image to boot</help>
<completionHelp>
- <script>sudo ${vyos_op_scripts_dir}/image_manager.py --action list</script>
+ <script>${vyos_op_scripts_dir}/image_manager.py --action list</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action set --image-name "${5}"</command>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action set --image-name "${5}"</command>
+ <standalone>
+ <help>Set default image to boot</help>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action set</command>
+ </standalone>
</tagNode>
</children>
</node>
@@ -116,7 +114,7 @@
<properties>
<help>Install new system image to hard drive</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_installer.py --action install</command>
+ <command>${vyos_op_scripts_dir}/image_installer.py --action install</command>
</node>
</children>
</node>
@@ -130,20 +128,18 @@
<help>Delete system objects</help>
</properties>
<children>
- <node name="image">
- <properties>
- <help>Remove an installed image from the system</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action delete</command>
- </node>
<tagNode name="image">
<properties>
<help>Remove an installed image from the system</help>
<completionHelp>
- <script>sudo ${vyos_op_scripts_dir}/image_manager.py --action list</script>
+ <script>${vyos_op_scripts_dir}/image_manager.py --action list</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action delete --image-name "${4}"</command>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action delete --image-name "${4}"</command>
+ <standalone>
+ <help>Remove an installed image from the system</help>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action delete</command>
+ </standalone>
</tagNode>
</children>
</node>
@@ -163,7 +159,7 @@
<properties>
<help>System image to rename</help>
<completionHelp>
- <script>sudo ${vyos_op_scripts_dir}/image_manager.py --action list</script>
+ <script>${vyos_op_scripts_dir}/image_manager.py --action list</script>
</completionHelp>
</properties>
<children>
@@ -171,7 +167,7 @@
<properties>
<help>A new name for an image</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_manager.py --action rename --image-name "${4}" --image-new-name "${6}"</command>
+ <command>${vyos_op_scripts_dir}/image_manager.py --action rename --image-name "${4}" --image-new-name "${6}"</command>
</tagNode>
</children>
</tagNode>
@@ -193,13 +189,13 @@
<properties>
<help>Show installed VyOS images</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_info.py show_images_summary</command>
+ <command>${vyos_op_scripts_dir}/image_info.py show_images_summary</command>
<children>
<node name="details">
<properties>
<help>Show details about installed VyOS images</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/image_info.py show_images_details</command>
+ <command>${vyos_op_scripts_dir}/image_info.py show_images_details</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/terminal.xml.in b/op-mode-definitions/terminal.xml.in
index 2a76de146..163159846 100644
--- a/op-mode-definitions/terminal.xml.in
+++ b/op-mode-definitions/terminal.xml.in
@@ -49,7 +49,7 @@
<properties>
<help>Reconfigure console keyboard layout</help>
</properties>
- <command>sudo dpkg-reconfigure -f dialog keyboard-configuration &amp;&amp; sudo systemctl restart keyboard-setup</command>
+ <command>dpkg-reconfigure -f dialog keyboard-configuration &amp;&amp; systemctl restart keyboard-setup</command>
</leafNode>
</children>
</node>
@@ -74,12 +74,6 @@
</tagNode>
</children>
</node>
- <node name="pager">
- <properties>
- <help>Set terminal pager to default (less)</help>
- </properties>
- <command>VYATTA_PAGER=${_vyatta_default_pager}</command>
- </node>
<tagNode name="pager">
<properties>
<help>Set terminal pager</help>
@@ -87,6 +81,10 @@
<list>&lt;PROGRAM&gt;</list>
</completionHelp>
</properties>
+ <standalone>
+ <help>Set terminal pager to default (less)</help>
+ <command>VYATTA_PAGER=${_vyatta_default_pager}</command>
+ </standalone>
<command>VYATTA_PAGER=$4</command>
</tagNode>
<tagNode name="length">
diff --git a/op-mode-definitions/traceroute.xml.in b/op-mode-definitions/traceroute.xml.in
index aba0f45e3..9976bdd97 100644
--- a/op-mode-definitions/traceroute.xml.in
+++ b/op-mode-definitions/traceroute.xml.in
@@ -9,7 +9,7 @@
</properties>
<command>${vyos_op_scripts_dir}/traceroute.py ${@:2}</command>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Traceroute options</help>
<completionHelp>
@@ -17,7 +17,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/traceroute.py ${@:2}</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</interfaceDefinition>
diff --git a/op-mode-definitions/traffic-dump.xml.in b/op-mode-definitions/traffic-dump.xml.in
index e86e69736..a145742e9 100644
--- a/op-mode-definitions/traffic-dump.xml.in
+++ b/op-mode-definitions/traffic-dump.xml.in
@@ -16,7 +16,7 @@
</completionHelp>
</properties>
<children>
- <leafNode name="node.tag">
+ <virtualTagNode>
<properties>
<help>Traffic capture options</help>
<completionHelp>
@@ -24,7 +24,7 @@
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/tcpdump.py "${@:4}"</command>
- </leafNode>
+ </virtualTagNode>
</children>
</tagNode>
</children>
diff --git a/op-mode-definitions/vpn-ipsec.xml.in b/op-mode-definitions/vpn-ipsec.xml.in
index 0a8671aeb..af7f12ba8 100644
--- a/op-mode-definitions/vpn-ipsec.xml.in
+++ b/op-mode-definitions/vpn-ipsec.xml.in
@@ -24,7 +24,7 @@
<properties>
<help>Reset a specific tunnel for given DMVPN profile</help>
<completionHelp>
- <script>sudo ${vyos_completion_dir}/list_ipsec_profile_tunnels.py --profile ${COMP_WORDS[4]}</script>
+ <script>${vyos_completion_dir}/list_ipsec_profile_tunnels.py --profile ${COMP_WORDS[4]}</script>
</completionHelp>
</properties>
<children>
@@ -35,10 +35,10 @@
<list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_profile_dst --profile="$5" --tunnel="$7" --nbma-dst="$9"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_profile_dst --profile="$5" --tunnel="$7" --nbma-dst="$9"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_profile_all --profile="$5" --tunnel="$7"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_profile_all --profile="$5" --tunnel="$7"</command>
</tagNode>
</children>
</tagNode>
@@ -51,13 +51,13 @@
<properties>
<help>Reset all users current remote access IPSec VPN sessions</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_ra</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_ra</command>
</node>
<tagNode name="user">
<properties>
<help>Reset specified user current remote access IPsec VPN session(s)</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_ra --user="$6"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_ra --user="$6"</command>
</tagNode>
</children>
</node>
@@ -70,7 +70,7 @@
<properties>
<help>Reset all site-to-site IPSec VPN sessions</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_all_peers</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_all_peers</command>
</node>
<tagNode name="peer">
<properties>
@@ -87,16 +87,16 @@
<path>vpn ipsec site-to-site peer ${COMP_WORDS[5]} tunnel</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6" --tunnel="$8"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6" --tunnel="$8"</command>
</tagNode>
<node name="vti">
<properties>
<help>Reset the VTI tunnel for given peer</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6" --tunnel="vti"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6" --tunnel="vti"</command>
</node>
</children>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6"</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py reset_peer --peer="$6"</command>
</tagNode>
</children>
</node>
@@ -112,7 +112,7 @@
<properties>
<help>Restart the IPsec VPN process</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name ipsec</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name ipsec</command>
</node>
</children>
</node>
@@ -140,13 +140,13 @@
<properties>
<help>Show debug information for peer tunnel</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="$5" --tunnel="$7"</command>
+ <command>${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="$5" --tunnel="$7"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="$5" --tunnel="all"</command>
+ <command>${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="$5" --tunnel="all"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="all"</command>
+ <command>${vyos_op_scripts_dir}/vpn_ipsec.py --action="vpn-debug" --name="all"</command>
</node>
<node name="ike">
<properties>
@@ -162,16 +162,16 @@
<properties>
<help>Show all currently active IKE Security Associations (SA) that are using NAT Traversal</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ike_sa.py --nat="yes"</command>
+ <command>${vyos_op_scripts_dir}/vpn_ike_sa.py --nat="yes"</command>
</node>
<tagNode name="peer">
<properties>
<help>Show all currently active IKE Security Associations (SA) for a peer</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ike_sa.py --peer="$6"</command>
+ <command>${vyos_op_scripts_dir}/vpn_ike_sa.py --peer="$6"</command>
</tagNode>
</children>
- <command>sudo ${vyos_op_scripts_dir}/vpn_ike_sa.py</command>
+ <command>${vyos_op_scripts_dir}/vpn_ike_sa.py</command>
</node>
<node name="secrets">
<properties>
@@ -183,7 +183,7 @@
<properties>
<help>Show summary of IKE process information</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then systemctl status strongswan ; else echo "Process is not running" ; fi</command>
+ <command>systemctl status strongswan</command>
</node>
</children>
</node>
@@ -196,13 +196,13 @@
<properties>
<help>Show VPN connections</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py show_connections</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_connections</command>
</node>
<node name="policy">
<properties>
<help>Show the in-kernel crypto policies</help>
</properties>
- <command>sudo ip xfrm policy list</command>
+ <command>ip xfrm policy list</command>
</node>
<node name="remote-access">
<properties>
@@ -213,25 +213,25 @@
<properties>
<help>Show detail active IKEv2 RA sessions</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_detail; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_ra_detail</command>
</node>
<tagNode name="connection-id">
<properties>
<help>Show detail active IKEv2 RA sessions by connection-id</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_detail --conn-id="$6"; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_ra_detail --conn-id="$6"</command>
</tagNode>
<node name="summary">
<properties>
<help>Show active IKEv2 RA sessions summary</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_summary; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_ra_summary; else echo "IPsec process not running"</command>
</node>
<tagNode name="username">
<properties>
<help>Show detail active IKEv2 RA sessions by username</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_detail --username="$6"; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_ra_detail --username="$6"</command>
</tagNode>
</children>
</node>
@@ -268,24 +268,24 @@
-->
<node name="detail">
<properties>
- <help>Show Verbose Detail on all active IPsec Security Associations (SA)</help>
+ <help>Show verbose details on all active IPsec security associations (SA)</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_sa_detail ; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_sa_detail</command>
</node>
</children>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_sa ; else echo "IPsec process not running" ; fi</command>
+ <command>${vyos_op_scripts_dir}/ipsec.py show_sa</command>
</node>
<node name="state">
<properties>
<help>Show the in-kernel crypto state</help>
</properties>
- <command>sudo ip xfrm state list</command>
+ <command>ip xfrm state list</command>
</node>
<node name="status">
<properties>
<help>Show status of IPsec process</help>
</properties>
- <command>if systemctl is-active --quiet strongswan >/dev/null ; then echo -e "IPsec Process Running: $(pgrep charon)\n$(sudo /usr/sbin/ipsec status)" ; else echo "IPsec process not running" ; fi</command>
+ <command>/usr/sbin/ipsec status</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/vrrp.xml.in b/op-mode-definitions/vrrp.xml.in
index fb777b2e4..b2b2886c0 100644
--- a/op-mode-definitions/vrrp.xml.in
+++ b/op-mode-definitions/vrrp.xml.in
@@ -2,42 +2,42 @@
<interfaceDefinition>
<node name="show">
<children>
- <tagNode name="vrrp">
- <properties>
- <help>Show specified VRRP (Virtual Router Redundancy Protocol) group information</help>
- </properties>
- <children>
- <node name="statistics">
- <properties>
- <help>Show VRRP statistics</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/vrrp.py show_statistics --group-name="$3"</command>
- </node>
- <node name="detail">
- <properties>
- <help>Show detailed VRRP state information</help>
- </properties>
- <command>sudo ${vyos_op_scripts_dir}/vrrp.py show_detail --group-name="$3"</command>
- </node>
- </children>
- </tagNode>
<node name="vrrp">
<properties>
<help>Show VRRP (Virtual Router Redundancy Protocol) information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vrrp.py show_summary</command>
+ <command>${vyos_op_scripts_dir}/vrrp.py show_summary</command>
<children>
+ <virtualTagNode>
+ <properties>
+ <help>Show specified VRRP (Virtual Router Redundancy Protocol) group information</help>
+ </properties>
+ <children>
+ <node name="statistics">
+ <properties>
+ <help>Show VRRP statistics</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vrrp.py show_statistics --group-name="$3"</command>
+ </node>
+ <node name="detail">
+ <properties>
+ <help>Show detailed VRRP state information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vrrp.py show_detail --group-name="$3"</command>
+ </node>
+ </children>
+ </virtualTagNode>
<node name="statistics">
<properties>
<help>Show VRRP statistics</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vrrp.py show_statistics</command>
+ <command>${vyos_op_scripts_dir}/vrrp.py show_statistics</command>
</node>
<node name="detail">
<properties>
<help>Show detailed VRRP state information</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/vrrp.py show_detail</command>
+ <command>${vyos_op_scripts_dir}/vrrp.py show_detail</command>
</node>
</children>
</node>
@@ -49,7 +49,7 @@
<properties>
<help>Restart VRRP (Virtual Router Redundancy Protocol) process</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name vrrp</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name vrrp</command>
</node>
</children>
</node>
diff --git a/op-mode-definitions/wake-on-lan.xml.in b/op-mode-definitions/wake-on-lan.xml.in
index d4589c868..bec12dae6 100644
--- a/op-mode-definitions/wake-on-lan.xml.in
+++ b/op-mode-definitions/wake-on-lan.xml.in
@@ -19,7 +19,7 @@
<properties>
<help>Station (MAC) address to wake up</help>
</properties>
- <command>sudo /usr/sbin/etherwake -i "$4" "$6"</command>
+ <command>/usr/sbin/etherwake -i "$4" "$6"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/webproxy.xml.in b/op-mode-definitions/webproxy.xml.in
index ba13907b8..76c348f9d 100644
--- a/op-mode-definitions/webproxy.xml.in
+++ b/op-mode-definitions/webproxy.xml.in
@@ -14,13 +14,13 @@
<properties>
<help>Monitor the last lines of the Webproxy access log</help>
</properties>
- <command>if [ -f /var/log/squid/access.log ]; then sudo tail --follow=name /var/log/squid/access.log; else echo "WebProxy access-log does not exist"; fi</command>
+ <command>if [ -f /var/log/squid/access.log ]; then tail --follow=name /var/log/squid/access.log; else echo "WebProxy access-log does not exist"; fi</command>
</leafNode>
<leafNode name="cache-log">
<properties>
<help>Monitor the last lines of the Webproxy cache log</help>
</properties>
- <command>if [ -f /var/log/squid/cache.log ]; then sudo tail --follow=name /var/log/squid/cache.log; else echo "WebProxy cache-log does not exist"; fi</command>
+ <command>if [ -f /var/log/squid/cache.log ]; then tail --follow=name /var/log/squid/cache.log; else echo "WebProxy cache-log does not exist"; fi</command>
</leafNode>
</children>
</node>
@@ -34,7 +34,7 @@
<properties>
<help>Restart WebProxy service</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/restart.py restart_service --name webproxy</command>
+ <command>${vyos_op_scripts_dir}/restart.py restart_service --name webproxy</command>
</node>
</children>
</node>
@@ -63,7 +63,7 @@
<properties>
<help>Show contents of WebProxy access log</help>
</properties>
- <command>if [ -e /var/log/squid/access.log ]; then sudo less $_vyatta_less_options --prompt="file %i of %m, page %dt of %D" -- `printf "%s\n" /var/log/squid/access.log* | sort -nr`; else echo "No WebProxy log"; fi</command>
+ <command>if [ -e /var/log/squid/access.log ]; then less $_vyatta_less_options --prompt="file %i of %m, page %dt of %D" -- `printf "%s\n" /var/log/squid/access.log* | sort -nr`; else echo "No WebProxy log"; fi</command>
</node>
<node name="update-log">
<properties>
@@ -86,7 +86,7 @@
<properties>
<help>Update the webproxy blacklist database</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/webproxy_update_blacklist.sh --update-blacklist</command>
+ <command>${vyos_op_scripts_dir}/webproxy_update_blacklist.sh --update-blacklist</command>
<children>
<tagNode name="vrf">
<properties>
@@ -95,7 +95,7 @@
<path>vrf name</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/webproxy_update_blacklist.sh --update-blacklist --vrf "${5}" </command>
+ <command>${vyos_op_scripts_dir}/webproxy_update_blacklist.sh --update-blacklist --vrf "${5}" </command>
</tagNode>
</children>
</node>
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 000000000..76597715e
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,2 @@
+[tool.black]
+skip-string-normalization = true \ No newline at end of file
diff --git a/python/vyos/accel_ppp.py b/python/vyos/accel_ppp.py
index bae695fc3..b1160dc76 100644
--- a/python/vyos/accel_ppp.py
+++ b/python/vyos/accel_ppp.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/accel_ppp_util.py b/python/vyos/accel_ppp_util.py
index ae75e6654..85e8a964c 100644
--- a/python/vyos/accel_ppp_util.py
+++ b/python/vyos/accel_ppp_util.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -221,10 +221,12 @@ def verify_accel_ppp_ip_pool(vpn_config):
for interface, interface_config in vpn_config['interface'].items():
if dict_search('client_subnet', interface_config):
break
+ if dict_search('external_dhcp.dhcp_relay', interface_config):
+ break
else:
raise ConfigError(
'Local auth and noauth mode requires local client-ip-pool \
- or client-ipv6-pool or client-subnet to be configured!')
+ or client-ipv6-pool or client-subnet or dhcp-relay to be configured!')
else:
raise ConfigError(
"Local auth mode requires local client-ip-pool \
diff --git a/python/vyos/airbag.py b/python/vyos/airbag.py
index 3c7a144b7..a869daae8 100644
--- a/python/vyos/airbag.py
+++ b/python/vyos/airbag.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2020 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/base.py b/python/vyos/base.py
index ca96d96ce..67f92564e 100644
--- a/python/vyos/base.py
+++ b/python/vyos/base.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,7 @@
from textwrap import fill
-
-class BaseWarning:
+class UserMessage:
def __init__(self, header, message, **kwargs):
self.message = message
self.kwargs = kwargs
@@ -33,7 +32,6 @@ class BaseWarning:
messages = self.message.split('\n')
isfirstmessage = True
initial_indent = self.textinitindent
- print('')
for mes in messages:
mes = fill(mes, initial_indent=initial_indent,
subsequent_indent=self.standardindent, **self.kwargs)
@@ -44,17 +42,24 @@ class BaseWarning:
print('', flush=True)
+class Message():
+ def __init__(self, message, **kwargs):
+ self.Message = UserMessage('', message, **kwargs)
+ self.Message.print()
+
class Warning():
def __init__(self, message, **kwargs):
- self.BaseWarn = BaseWarning('WARNING: ', message, **kwargs)
- self.BaseWarn.print()
+ print('')
+ self.UserMessage = UserMessage('WARNING: ', message, **kwargs)
+ self.UserMessage.print()
class DeprecationWarning():
def __init__(self, message, **kwargs):
# Reformat the message and trim it to 72 characters in length
- self.BaseWarn = BaseWarning('DEPRECATION WARNING: ', message, **kwargs)
- self.BaseWarn.print()
+ print('')
+ self.UserMessage = UserMessage('DEPRECATION WARNING: ', message, **kwargs)
+ self.UserMessage.print()
class ConfigError(Exception):
diff --git a/python/vyos/component_version.py b/python/vyos/component_version.py
index 94215531d..136bd36e8 100644
--- a/python/vyos/component_version.py
+++ b/python/vyos/component_version.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -49,7 +49,9 @@ DEFAULT_CONFIG_PATH = os.path.join(directories['config'], 'config.boot')
REGEX_WARN_VYOS = r'(// Warning: Do not remove the following line.)'
REGEX_WARN_VYATTA = r'(/\* Warning: Do not remove the following line. \*/)'
REGEX_COMPONENT_VERSION_VYOS = r'// vyos-config-version:\s+"([\w@:-]+)"\s*'
-REGEX_COMPONENT_VERSION_VYATTA = r'/\* === vyatta-config-version:\s+"([\w@:-]+)"\s+=== \*/'
+REGEX_COMPONENT_VERSION_VYATTA = (
+ r'/\* === vyatta-config-version:\s+"([\w@:-]+)"\s+=== \*/'
+)
REGEX_RELEASE_VERSION_VYOS = r'// Release version:\s+(\S*)\s*'
REGEX_RELEASE_VERSION_VYATTA = r'/\* Release version:\s+(\S*)\s*\*/'
@@ -62,16 +64,31 @@ CONFIG_FILE_VERSION = """\
warn_filter_vyos = re.compile(REGEX_WARN_VYOS)
warn_filter_vyatta = re.compile(REGEX_WARN_VYATTA)
-regex_filter = { 'vyos': dict(zip(['component', 'release'],
- [re.compile(REGEX_COMPONENT_VERSION_VYOS),
- re.compile(REGEX_RELEASE_VERSION_VYOS)])),
- 'vyatta': dict(zip(['component', 'release'],
- [re.compile(REGEX_COMPONENT_VERSION_VYATTA),
- re.compile(REGEX_RELEASE_VERSION_VYATTA)])) }
+regex_filter = {
+ 'vyos': dict(
+ zip(
+ ['component', 'release'],
+ [
+ re.compile(REGEX_COMPONENT_VERSION_VYOS),
+ re.compile(REGEX_RELEASE_VERSION_VYOS),
+ ],
+ )
+ ),
+ 'vyatta': dict(
+ zip(
+ ['component', 'release'],
+ [
+ re.compile(REGEX_COMPONENT_VERSION_VYATTA),
+ re.compile(REGEX_RELEASE_VERSION_VYATTA),
+ ],
+ )
+ ),
+}
+
@dataclass
class VersionInfo:
- component: Optional[dict[str,int]] = None
+ component: Optional[dict[str, int]] = None
release: str = get_version()
vintage: str = 'vyos'
config_body: Optional[str] = None
@@ -84,8 +101,9 @@ class VersionInfo:
return bool(self.config_body is None)
def update_footer(self):
- f = CONFIG_FILE_VERSION.format(component_to_string(self.component),
- self.release)
+ f = CONFIG_FILE_VERSION.format(
+ component_to_string(self.component), self.release
+ )
self.footer_lines = f.splitlines()
def update_syntax(self):
@@ -121,13 +139,16 @@ class VersionInfo:
except Exception as e:
raise ValueError(e) from e
+
def component_to_string(component: dict) -> str:
- l = [f'{k}@{v}' for k, v in sorted(component.items(), key=lambda x: x[0])]
+ l = [f'{k}@{v}' for k, v in sorted(component.items(), key=lambda x: x[0])] # noqa: E741
return ':'.join(l)
+
def component_from_string(string: str) -> dict:
return {k: int(v) for k, v in re.findall(r'([\w,-]+)@(\d+)', string)}
+
def version_info_from_file(config_file) -> VersionInfo:
"""Return config file component and release version info."""
version_info = VersionInfo()
@@ -166,27 +187,27 @@ def version_info_from_file(config_file) -> VersionInfo:
return version_info
+
def version_info_from_system() -> VersionInfo:
"""Return system component and release version info."""
d = component_version()
sort_d = dict(sorted(d.items(), key=lambda x: x[0]))
- version_info = VersionInfo(
- component = sort_d,
- release = get_version(),
- vintage = 'vyos'
- )
+ version_info = VersionInfo(component=sort_d, release=get_version(), vintage='vyos')
return version_info
+
def version_info_copy(v: VersionInfo) -> VersionInfo:
"""Make a copy of dataclass."""
return replace(v)
+
def version_info_prune_component(x: VersionInfo, y: VersionInfo) -> VersionInfo:
"""In place pruning of component keys of x not in y."""
if x.component is None or y.component is None:
return
- x.component = { k: v for k,v in x.component.items() if k in y.component }
+ x.component = {k: v for k, v in x.component.items() if k in y.component}
+
def add_system_version(config_str: str = None, out_file: str = None):
"""Wrap config string with system version and write to out_file.
@@ -202,3 +223,11 @@ def add_system_version(config_str: str = None, out_file: str = None):
version_info.write(out_file)
else:
sys.stdout.write(version_info.write_string())
+
+
+def append_system_version(file: str):
+ """Append system version data to existing file"""
+ version_info = version_info_from_system()
+ version_info.update_footer()
+ with open(file, 'a') as f:
+ f.write(version_info.write_string())
diff --git a/python/vyos/compose_config.py b/python/vyos/compose_config.py
index 79a8718c5..1e7837858 100644
--- a/python/vyos/compose_config.py
+++ b/python/vyos/compose_config.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/config.py b/python/vyos/config.py
index 546eeceab..6f7c76ca7 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -1,4 +1,4 @@
-# Copyright 2017-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -73,8 +73,11 @@ from vyos.xml_ref import ext_dict_merge
from vyos.xml_ref import relative_defaults
from vyos.utils.dict import get_sub_dict
from vyos.utils.dict import mangle_dict_keys
+from vyos.utils.boot import boot_configuration_complete
+from vyos.utils.backend import vyconf_backend
from vyos.configsource import ConfigSource
from vyos.configsource import ConfigSourceSession
+from vyos.configsource import ConfigSourceVyconfSession
class ConfigDict(dict):
_from_defaults = {}
@@ -131,8 +134,13 @@ class Config(object):
subtrees.
"""
def __init__(self, session_env=None, config_source=None):
+ self.vyconf_session = None
if config_source is None:
- self._config_source = ConfigSourceSession(session_env)
+ if vyconf_backend() and boot_configuration_complete():
+ self._config_source = ConfigSourceVyconfSession(session_env)
+ self.vyconf_session = self._config_source._vyconf_session
+ else:
+ self._config_source = ConfigSourceSession(session_env)
else:
if not isinstance(config_source, ConfigSource):
raise TypeError("config_source not of type ConfigSource")
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index dd8910afb..51c6f2241 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -25,10 +25,12 @@ from filecmp import cmp
from datetime import datetime
from textwrap import dedent
from pathlib import Path
-from tabulate import tabulate
from shutil import copy, chown
+from subprocess import Popen
+from subprocess import DEVNULL
from urllib.parse import urlsplit
from urllib.parse import urlunsplit
+from tabulate import tabulate
from vyos.config import Config
from vyos.configtree import ConfigTree
@@ -44,6 +46,7 @@ from vyos.utils.io import ask_yes_no
from vyos.utils.boot import boot_configuration_complete
from vyos.utils.process import is_systemd_service_active
from vyos.utils.process import rc_cmd
+from vyos.defaults import DEFAULT_COMMIT_CONFIRM_MINUTES
SAVE_CONFIG = '/usr/libexec/vyos/vyos-save-config.py'
config_json = '/run/vyatta/config/config.json'
@@ -56,7 +59,6 @@ commit_hooks = {
'commit_archive': '02vyos-commit-archive',
}
-DEFAULT_TIME_MINUTES = 10
timer_name = 'commit-confirm'
config_file = os.path.join(directories['config'], 'config.boot')
@@ -144,14 +146,16 @@ class ConfigMgmt:
['system', 'config-management'],
key_mangling=('-', '_'),
get_first_key=True,
- with_defaults=True,
+ with_recursive_defaults=True,
)
self.max_revisions = int(d.get('commit_revisions', 0))
self.num_revisions = 0
self.locations = d.get('commit_archive', {}).get('location', [])
self.source_address = d.get('commit_archive', {}).get('source_address', '')
- self.reboot_unconfirmed = bool(d.get('commit_confirm') == 'reboot')
+ self.reboot_unconfirmed = bool(
+ d.get('commit_confirm', {}).get('action') == 'reboot'
+ )
self.config_dict = d
if config.exists(['system', 'host-name']):
@@ -181,7 +185,7 @@ class ConfigMgmt:
# Console script functions
#
def commit_confirm(
- self, minutes: int = DEFAULT_TIME_MINUTES, no_prompt: bool = False
+ self, minutes: int = DEFAULT_COMMIT_CONFIRM_MINUTES, no_prompt: bool = False
) -> Tuple[str, int]:
"""Commit with reload/reboot to saved config in 'minutes' minutes if
'confirm' call is not issued.
@@ -229,7 +233,14 @@ Proceed ?"""
else:
cmd = f'sudo -b /usr/libexec/vyos/commit-confirm-notify.py {minutes}'
- os.system(cmd)
+ Popen(
+ cmd.split(),
+ stdout=DEVNULL,
+ stderr=DEVNULL,
+ stdin=DEVNULL,
+ close_fds=True,
+ preexec_fn=os.setsid,
+ )
if self.reboot_unconfirmed:
msg = f'Initialized commit-confirm; {minutes} minutes to confirm before reboot'
@@ -805,7 +816,7 @@ def run():
'-t',
dest='minutes',
type=int,
- default=DEFAULT_TIME_MINUTES,
+ default=DEFAULT_COMMIT_CONFIRM_MINUTES,
help="Minutes until reboot, unless 'confirm'",
)
commit_confirm.add_argument(
diff --git a/python/vyos/configdep.py b/python/vyos/configdep.py
index 747af8dbe..04de66493 100644
--- a/python/vyos/configdep.py
+++ b/python/vyos/configdep.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index 78b98a3eb..d91d88d88 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -517,6 +517,14 @@ def get_interface_dict(config, base, ifname='', recursive_defaults=True, with_pk
else:
dict['ipv6']['address'].update({'eui64_old': eui64})
+ interface_identifier = leaf_node_changed(config, base + [ifname, 'ipv6', 'address', 'interface-identifier'])
+ if interface_identifier:
+ tmp = dict_search('ipv6.address', dict)
+ if not tmp:
+ dict.update({'ipv6': {'address': {'interface_identifier_old': interface_identifier}}})
+ else:
+ dict['ipv6']['address'].update({'interface_identifier_old': interface_identifier})
+
for vif, vif_config in dict.get('vif', {}).items():
# Add subinterface name to dictionary
dict['vif'][vif].update({'ifname' : f'{ifname}.{vif}'})
@@ -626,6 +634,23 @@ def get_vlan_ids(interface):
return vlan_ids
+def get_vlans_ids_and_range(interface):
+ vlan_ids = set()
+
+ vlan_filter_status = json.loads(cmd(f'bridge -j -d vlan show dev {interface}'))
+
+ if vlan_filter_status is not None:
+ for interface_status in vlan_filter_status:
+ for vlan_entry in interface_status.get("vlans", []):
+ start = vlan_entry["vlan"]
+ end = vlan_entry.get("vlanEnd")
+ if end:
+ vlan_ids.add(f"{start}-{end}")
+ else:
+ vlan_ids.add(str(start))
+
+ return vlan_ids
+
def get_accel_dict(config, base, chap_secrets, with_pki=False):
"""
Common utility function to retrieve and mangle the Accel-PPP configuration
@@ -636,6 +661,7 @@ def get_accel_dict(config, base, chap_secrets, with_pki=False):
Return a dictionary with the necessary interface config keys.
"""
from vyos.utils.cpu import get_core_count
+ from vyos.utils.cpu import get_half_cpus
from vyos.template import is_ipv4
dict = config.get_config_dict(base, key_mangling=('-', '_'),
@@ -645,7 +671,16 @@ def get_accel_dict(config, base, chap_secrets, with_pki=False):
with_pki=with_pki)
# set CPUs cores to process requests
- dict.update({'thread_count' : get_core_count()})
+ match dict.get('thread_count'):
+ case 'all':
+ dict['thread_count'] = get_core_count()
+ case 'half':
+ dict['thread_count'] = get_half_cpus()
+ case str(x) if x.isdigit():
+ dict['thread_count'] = int(x)
+ case _:
+ dict['thread_count'] = get_core_count()
+
# we need to store the path to the secrets file
dict.update({'chap_secrets_file' : chap_secrets})
@@ -668,3 +703,18 @@ def get_accel_dict(config, base, chap_secrets, with_pki=False):
dict['authentication']['radius']['server'][server]['acct_port'] = '0'
return dict
+
+def get_flowtable_interfaces(config):
+ """
+ Return all interfaces used in flowtables
+ """
+ ft_base = ['firewall', 'flowtable']
+
+ if not config.exists(ft_base):
+ return []
+
+ ifaces = []
+ for ft_name in config.list_nodes(ft_base):
+ ifaces += config.return_values(ft_base + [ft_name, 'interface'])
+
+ return ifaces
diff --git a/python/vyos/configdiff.py b/python/vyos/configdiff.py
index b6d4a5558..5e21a16e5 100644
--- a/python/vyos/configdiff.py
+++ b/python/vyos/configdiff.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/configquery.py b/python/vyos/configquery.py
index 4c4ead0a3..e8a3c0f99 100644
--- a/python/vyos/configquery.py
+++ b/python/vyos/configquery.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/configsession.py b/python/vyos/configsession.py
index 90b96b88c..50f93f890 100644
--- a/python/vyos/configsession.py
+++ b/python/vyos/configsession.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software Foundation;
@@ -21,16 +21,25 @@ import subprocess
from vyos.defaults import directories
from vyos.utils.process import is_systemd_service_running
from vyos.utils.dict import dict_to_paths
+from vyos.utils.boot import boot_configuration_complete
+from vyos.utils.backend import vyconf_backend
+from vyos.vyconf_session import VyconfSession
+from vyos.base import Warning as Warn
+from vyos.defaults import DEFAULT_COMMIT_CONFIRM_MINUTES
+
CLI_SHELL_API = '/bin/cli-shell-api'
SET = '/opt/vyatta/sbin/my_set'
DELETE = '/opt/vyatta/sbin/my_delete'
COMMENT = '/opt/vyatta/sbin/my_comment'
COMMIT = '/opt/vyatta/sbin/my_commit'
+COMMIT_CONFIRM = ['/usr/bin/config-mgmt', 'commit_confirm', '-y']
+CONFIRM = ['/usr/bin/config-mgmt', 'confirm']
DISCARD = '/opt/vyatta/sbin/my_discard'
SHOW_CONFIG = ['/bin/cli-shell-api', 'showConfig']
LOAD_CONFIG = ['/bin/cli-shell-api', 'loadFile']
MIGRATE_LOAD_CONFIG = ['/usr/libexec/vyos/vyos-load-config.py']
+MERGE_CONFIG = ['/usr/libexec/vyos/vyos-merge-config.py']
SAVE_CONFIG = ['/usr/libexec/vyos/vyos-save-config.py']
INSTALL_IMAGE = [
'/usr/libexec/vyos/op_mode/image_installer.py',
@@ -63,6 +72,7 @@ GENERATE = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'generate']
SHOW = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'show']
RESET = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'reset']
REBOOT = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'reboot']
+RENEW = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'renew']
POWEROFF = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'poweroff']
OP_CMD_ADD = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'add']
OP_CMD_DELETE = ['/opt/vyatta/bin/vyatta-op-cmd-wrapper', 'delete']
@@ -116,6 +126,10 @@ def inject_vyos_env(env):
env['vyos_sbin_dir'] = '/usr/sbin'
env['vyos_validators_dir'] = '/usr/libexec/vyos/validators'
+ # with the retirement of the Cstore backend, this will remain as the
+ # sole indication of legacy CLI config mode, as checked by VyconfSession
+ env['_OFR_CONFIGURE'] = 'ok'
+
# if running the vyos-configd daemon, inject the vyshim env var
if is_systemd_service_running('vyos-configd.service'):
env['vyshim'] = '/usr/sbin/vyshim'
@@ -132,7 +146,7 @@ class ConfigSession(object):
The write API of VyOS.
"""
- def __init__(self, session_id, app=APP):
+ def __init__(self, session_id, app=APP, shared=False):
"""
Creates a new config session.
@@ -160,32 +174,52 @@ class ConfigSession(object):
for k, v in env_list:
session_env[k] = v
+ session_env['CONFIGSESSION_PID'] = str(session_id)
+
self.__session_env = session_env
self.__session_env['COMMIT_VIA'] = app
self.__run_command([CLI_SHELL_API, 'setupSession'])
+ if vyconf_backend() and boot_configuration_complete():
+ self._vyconf_session = VyconfSession(
+ pid=session_id, on_error=ConfigSessionError
+ )
+ else:
+ self._vyconf_session = None
+
+ self.shared = shared
+
def __del__(self):
- try:
- output = (
- subprocess.check_output(
- [CLI_SHELL_API, 'teardownSession'], env=self.__session_env
+ if self.shared:
+ return
+ if self._vyconf_session is None:
+ try:
+ output = (
+ subprocess.check_output(
+ [CLI_SHELL_API, 'teardownSession'], env=self.__session_env
+ )
+ .decode()
+ .strip()
)
- .decode()
- .strip()
- )
- if output:
+ if output:
+ print(
+ 'cli-shell-api teardownSession output for sesion {0}: {1}'.format(
+ self.__session_id, output
+ ),
+ file=sys.stderr,
+ )
+ except Exception as e:
print(
- 'cli-shell-api teardownSession output for sesion {0}: {1}'.format(
- self.__session_id, output
- ),
+ 'Could not tear down session {0}: {1}'.format(self.__session_id, e),
file=sys.stderr,
)
- except Exception as e:
- print(
- 'Could not tear down session {0}: {1}'.format(self.__session_id, e),
- file=sys.stderr,
- )
+ else:
+ if self._vyconf_session.session_changed():
+ Warn('Exiting with uncommitted changes')
+ self._vyconf_session.discard()
+ self._vyconf_session.exit_config_mode()
+ self._vyconf_session.teardown()
def __run_command(self, cmd_list):
p = subprocess.Popen(
@@ -209,7 +243,10 @@ class ConfigSession(object):
value = []
else:
value = [value]
- self.__run_command([SET] + path + value)
+ if self._vyconf_session is None:
+ self.__run_command([SET] + path + value)
+ else:
+ self._vyconf_session.set(path + value)
def set_section(self, path: list, d: dict):
try:
@@ -223,7 +260,10 @@ class ConfigSession(object):
value = []
else:
value = [value]
- self.__run_command([DELETE] + path + value)
+ if self._vyconf_session is None:
+ self.__run_command([DELETE] + path + value)
+ else:
+ self._vyconf_session.delete(path + value)
def load_section(self, path: list, d: dict):
try:
@@ -261,20 +301,50 @@ class ConfigSession(object):
self.__run_command([COMMENT] + path + value)
def commit(self):
- out = self.__run_command([COMMIT])
+ if self._vyconf_session is None:
+ out = self.__run_command([COMMIT])
+ else:
+ out, _ = self._vyconf_session.commit()
+
+ return out
+
+ def commit_confirm(self, minutes: int = DEFAULT_COMMIT_CONFIRM_MINUTES):
+ if self._vyconf_session is None:
+ out = self.__run_command(COMMIT_CONFIRM + [f'-t {minutes}'])
+ else:
+ out = 'unimplemented'
+
+ return out
+
+ def confirm(self):
+ if self._vyconf_session is None:
+ out = self.__run_command(CONFIRM)
+ else:
+ out = 'unimplemented'
+
return out
def discard(self):
- self.__run_command([DISCARD])
+ if self._vyconf_session is None:
+ self.__run_command([DISCARD])
+ else:
+ out, _ = self._vyconf_session.discard()
def show_config(self, path, format='raw'):
- config_data = self.__run_command(SHOW_CONFIG + path)
+ if self._vyconf_session is None:
+ config_data = self.__run_command(SHOW_CONFIG + path)
+ else:
+ config_data, _ = self._vyconf_session.show_config(path)
if format == 'raw':
return config_data
def load_config(self, file_path):
- out = self.__run_command(LOAD_CONFIG + [file_path])
+ if self._vyconf_session is None:
+ out = self.__run_command(LOAD_CONFIG + [file_path])
+ else:
+ out, _ = self._vyconf_session.load_config(file_name=file_path)
+
return out
def load_explicit(self, file_path):
@@ -287,11 +357,32 @@ class ConfigSession(object):
raise ConfigSessionError(e) from e
def migrate_and_load_config(self, file_path):
- out = self.__run_command(MIGRATE_LOAD_CONFIG + [file_path])
+ if self._vyconf_session is None:
+ out = self.__run_command(MIGRATE_LOAD_CONFIG + [file_path])
+ else:
+ out, _ = self._vyconf_session.load_config(file_name=file_path, migrate=True)
+
+ return out
+
+ def merge_config(self, file_path, destructive=False):
+ if self._vyconf_session is None:
+ destr = ['--destructive'] if destructive else []
+ out = self.__run_command(MERGE_CONFIG + [file_path] + destr)
+ else:
+ out, _ = self._vyconf_session.merge_config(
+ file_name=file_path, destructive=destructive
+ )
+
return out
def save_config(self, file_path):
- out = self.__run_command(SAVE_CONFIG + [file_path])
+ if self._vyconf_session is None:
+ out = self.__run_command(SAVE_CONFIG + [file_path])
+ else:
+ out, _ = self._vyconf_session.save_config(
+ file=file_path, append_version=True
+ )
+
return out
def install_image(self, url):
@@ -330,6 +421,10 @@ class ConfigSession(object):
out = self.__run_command(RESET + path)
return out
+ def renew(self, path):
+ out = self.__run_command(RENEW + path)
+ return out
+
def poweroff(self, path):
out = self.__run_command(POWEROFF + path)
return out
diff --git a/python/vyos/configsource.py b/python/vyos/configsource.py
index 65cef5333..949216722 100644
--- a/python/vyos/configsource.py
+++ b/python/vyos/configsource.py
@@ -1,5 +1,5 @@
-# Copyright 2020-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -17,9 +17,16 @@
import os
import re
import subprocess
+from typing import Union
from vyos.configtree import ConfigTree
from vyos.utils.boot import boot_configuration_complete
+from vyos.vyconf_session import VyconfSession
+from vyos.vyconf_session import VyconfSessionError
+from vyos.defaults import directories
+from vyos.xml_ref import is_tag
+from vyos.xml_ref import is_leaf
+from vyos.xml_ref import is_multi
class VyOSError(Exception):
"""
@@ -310,6 +317,109 @@ class ConfigSourceSession(ConfigSource):
except VyOSError:
return False
+class ConfigSourceVyconfSession(ConfigSource):
+ def __init__(self, session_env=None):
+ super().__init__()
+
+ if session_env:
+ self.__session_env = session_env
+ else:
+ self.__session_env = None
+
+ if session_env and 'CONFIGSESSION_PID' in session_env:
+ self.pid = int(session_env['CONFIGSESSION_PID'])
+ else:
+ self.pid = os.getppid()
+
+ self._vyconf_session = VyconfSession(pid=self.pid)
+ try:
+ out = self._vyconf_session.get_config()
+ except VyconfSessionError as e:
+ raise ConfigSourceError(f'Init error in {type(self)}: {e}')
+
+ session_dir = directories['vyconf_session_dir']
+
+ self.running_cache_path = os.path.join(session_dir, f'running_cache_{out}')
+ self.session_cache_path = os.path.join(session_dir, f'session_cache_{out}')
+
+ self._running_config = ConfigTree(internal=self.running_cache_path)
+ self._session_config = ConfigTree(internal=self.session_cache_path)
+
+ if os.path.isfile(self.running_cache_path):
+ os.remove(self.running_cache_path)
+ if os.path.isfile(self.session_cache_path):
+ os.remove(self.session_cache_path)
+
+ # N.B. level not yet implemented pending integration with legacy CLI
+ # cf. T7374
+ self._level = []
+
+ def get_level(self):
+ return self._level
+
+ def set_level(self):
+ pass
+
+ def session_changed(self):
+ """
+ Returns:
+ True if the config session has uncommited changes, False otherwise.
+ """
+ try:
+ return self._vyconf_session.session_changed()
+ except VyconfSessionError:
+ # no actionable session info on error
+ return False
+
+ def in_session(self):
+ """
+ Returns:
+ True if called from a configuration session, False otherwise.
+ """
+ return self._vyconf_session.in_session()
+
+ def show_config(self, path: Union[str,list] = None, default: str = None,
+ effective: bool = False):
+ """
+ Args:
+ path (str|list): Configuration tree path, or empty
+ default (str): Default value to return
+
+ Returns:
+ str: working configuration
+ """
+
+ if path is None:
+ path = []
+ if isinstance(path, str):
+ path = path.split()
+
+ ct = self._running_config if effective else self._session_config
+ with_node = True if self.is_tag(path) else False
+ ct_at_path = ct.get_subtree(path, with_node=with_node) if path else ct
+
+ res = ct_at_path.to_string().strip()
+
+ return res if res else default
+
+ def is_tag(self, path):
+ try:
+ return is_tag(path)
+ except ValueError:
+ return False
+
+ def is_leaf(self, path):
+ try:
+ return is_leaf(path)
+ except ValueError:
+ return False
+
+ def is_multi(self, path):
+ try:
+ return is_multi(path)
+ except ValueError:
+ return False
+
class ConfigSourceString(ConfigSource):
def __init__(self, running_config_text=None, session_config_text=None):
super().__init__()
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index ff40fbad0..ba3f1e368 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -1,5 +1,5 @@
# configtree -- a standalone VyOS config file manipulation library (Python bindings)
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software Foundation;
@@ -194,6 +194,7 @@ class ConfigTree(object):
raise ValueError('Failed to read internal rep: {0}'.format(msg))
else:
self.__config = config
+ self.__version = ''
elif config_string is not None:
config_section, version_section = extract_version(config_string)
config_section = escape_backslash(config_section)
@@ -232,7 +233,7 @@ class ConfigTree(object):
return self.__version
def write_cache(self, file_name):
- self.__write_internal(self._get_config(), file_name)
+ self.__write_internal(self._get_config(), file_name.encode())
def to_string(self, ordered_values=False, no_version=False):
config_string = self.__to_string(self.__config, ordered_values).decode()
@@ -498,6 +499,28 @@ def union(left, right, libpath=LIBPATH):
return tree
+def merge(left, right, destructive=False, libpath=LIBPATH):
+ if left is None:
+ left = ConfigTree(config_string='\n')
+ if right is None:
+ right = ConfigTree(config_string='\n')
+ if not (isinstance(left, ConfigTree) and isinstance(right, ConfigTree)):
+ raise TypeError('Arguments must be instances of ConfigTree')
+
+ __lib = cdll.LoadLibrary(libpath)
+ __tree_merge = __lib.tree_merge
+ __tree_merge.argtypes = [c_bool, c_void_p, c_void_p]
+ __tree_merge.restype = c_void_p
+ __get_error = __lib.get_error
+ __get_error.argtypes = []
+ __get_error.restype = c_char_p
+
+ res = __tree_merge(destructive, left._get_config(), right._get_config())
+ tree = ConfigTree(address=res)
+
+ return tree
+
+
def mask_inclusive(left, right, libpath=LIBPATH):
if not (isinstance(left, ConfigTree) and isinstance(right, ConfigTree)):
raise TypeError('Arguments must be instances of ConfigTree')
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 4084425b1..cc4419913 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -92,6 +92,9 @@ def verify_mtu_ipv6(config):
tmp = dict_search('ipv6.address.eui64', config)
if tmp != None: raise ConfigError(error_msg)
+ tmp = dict_search('ipv6.address.interface_identifier', config)
+ if tmp != None: raise ConfigError(error_msg)
+
def verify_vrf(config):
"""
Common helper function used by interface implementations to perform
@@ -356,6 +359,7 @@ def verify_vlan_config(config):
verify_vrf(vlan)
verify_mirror_redirect(vlan)
verify_mtu_parent(vlan, config)
+ verify_mtu_ipv6(vlan)
# 802.1ad (Q-in-Q) VLANs
for s_vlan_id in config.get('vif_s', {}):
@@ -367,6 +371,7 @@ def verify_vlan_config(config):
verify_vrf(s_vlan)
verify_mirror_redirect(s_vlan)
verify_mtu_parent(s_vlan, config)
+ verify_mtu_ipv6(s_vlan)
for c_vlan_id in s_vlan.get('vif_c', {}):
c_vlan = s_vlan['vif_c'][c_vlan_id]
@@ -378,6 +383,7 @@ def verify_vlan_config(config):
verify_mirror_redirect(c_vlan)
verify_mtu_parent(c_vlan, config)
verify_mtu_parent(c_vlan, s_vlan)
+ verify_mtu_ipv6(c_vlan)
def verify_diffie_hellman_length(file, min_keysize):
@@ -521,6 +527,25 @@ def verify_pki_dh_parameters(config: dict, dh_name: str, min_key_size: int=0):
if dh_bits < min_key_size:
raise ConfigError(f'Minimum DH key-size is {min_key_size} bits!')
+def verify_pki_openssh_key(config: dict, key_name: str):
+ """
+ Common helper function user by PKI consumers to perform recurring
+ validation functions on OpenSSH keys
+ """
+ if 'pki' not in config:
+ raise ConfigError('PKI is not configured!')
+
+ if 'openssh' not in config['pki']:
+ raise ConfigError('PKI does not contain any OpenSSH keys!')
+
+ if key_name not in config['pki']['openssh']:
+ raise ConfigError(f'OpenSSH key "{key_name}" not found in configuration!')
+
+ if 'public' in config['pki']['openssh'][key_name]:
+ if not {'key', 'type'} <= set(config['pki']['openssh'][key_name]['public']):
+ raise ConfigError('Both public key and type must be defined for '\
+ f'OpenSSH public key "{key_name}"!')
+
def verify_eapol(config: dict):
"""
Common helper function used by interface implementations to perform
diff --git a/python/vyos/debug.py b/python/vyos/debug.py
index 6ce42b173..5b6e8172e 100644
--- a/python/vyos/debug.py
+++ b/python/vyos/debug.py
@@ -1,4 +1,4 @@
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 2b08ff68e..fbb5a0393 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -15,10 +15,10 @@
import os
-base_dir = '/usr/libexec/vyos/'
+base_dir = '/usr/libexec/vyos'
directories = {
- 'base' : base_dir,
+ 'base' : f'{base_dir}',
'data' : '/usr/share/vyos/',
'conf_mode' : f'{base_dir}/conf_mode',
'op_mode' : f'{base_dir}/op_mode',
@@ -39,14 +39,24 @@ directories = {
'completion_dir' : f'{base_dir}/completion',
'ca_certificates' : '/usr/local/share/ca-certificates/vyos',
'ppp_nexthop_dir' : '/run/ppp_nexthop',
- 'proto_path' : '/usr/share/vyos/vyconf'
+ 'proto_path' : '/usr/share/vyos/vyconf',
+ 'vyconf_session_dir' : f'{base_dir}/vyconf/session'
}
systemd_services = {
- 'rsyslog' : 'rsyslog.service',
+ 'haproxy' : 'haproxy.service',
+ 'syslog' : 'syslog.service',
'snmpd' : 'snmpd.service',
}
+internal_ports = {
+ 'certbot_haproxy' : 65080, # Certbot running behing haproxy
+}
+
+config_files = {
+ 'sshd_user_ca' : '/run/sshd/trusted_user_ca',
+}
+
config_status = '/tmp/vyos-config-status'
api_config_state = '/run/http-api-state'
frr_debug_enable = '/tmp/vyos.frr.debug'
@@ -63,8 +73,8 @@ config_default = os.path.join(directories['data'], 'config.boot.default')
rt_symbolic_names = {
# Standard routing tables for Linux & reserved IDs for VyOS
- 'default': 253, # Confusingly, a final fallthru, not the default.
- 'main': 254, # The actual global table used by iproute2 unless told otherwise.
+ 'default': 253, # Confusingly, a final fallthru, not the default.
+ 'main': 254, # The actual global table used by iproute2 unless told otherwise.
'local': 255, # Special kernel loopback table.
}
@@ -72,3 +82,9 @@ rt_global_vrf = rt_symbolic_names['main']
rt_global_table = rt_symbolic_names['main']
vyconfd_conf = '/etc/vyos/vyconfd.conf'
+
+DEFAULT_COMMIT_CONFIRM_MINUTES = 10
+
+commit_hooks = {'pre': '/etc/commit/pre-hooks.d',
+ 'post': '/etc/commit/post-hooks.d'
+ }
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index 4710a5d40..6c362163c 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 9f01f8be1..b136b6fca 100755
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -233,6 +233,9 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
hook_name = 'prerouting'
if hook == 'NAM':
hook_name = f'name'
+ # for policy
+ if hook == 'route' or hook == 'route6':
+ hook_name = hook
output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC{def_suffix}_{hook_name}_{fw_name}_{rule_id}')
if 'mac_address' in side_conf:
@@ -316,7 +319,10 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
if group_name[0] == '!':
operator = '!='
group_name = group_name[1:]
- output.append(f'{ip_name} {prefix}addr {operator} @R_{group_name}')
+ if ip_name == 'ip':
+ output.append(f'{ip_name} {prefix}addr {operator} @R_{group_name}')
+ elif ip_name == 'ip6':
+ output.append(f'{ip_name} {prefix}addr {operator} @R6_{group_name}')
if 'mac_group' in group:
group_name = group['mac_group']
operator = ''
@@ -355,7 +361,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
if iiface[0] == '!':
operator = '!='
iiface = iiface[1:]
- output.append(f'iifname {operator} {{{iiface}}}')
+ output.append(f'iifname {operator} {{"{iiface}"}}')
elif 'group' in rule_conf['inbound_interface']:
iiface = rule_conf['inbound_interface']['group']
if iiface[0] == '!':
@@ -370,7 +376,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
if oiface[0] == '!':
operator = '!='
oiface = oiface[1:]
- output.append(f'oifname {operator} {{{oiface}}}')
+ output.append(f'oifname {operator} {{"{oiface}"}}')
elif 'group' in rule_conf['outbound_interface']:
oiface = rule_conf['outbound_interface']['group']
if oiface[0] == '!':
@@ -468,14 +474,14 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
output.append('gre version 1')
if gre_key:
- # The offset of the key within the packet shifts depending on the C-flag.
- # nftables cannot handle complex enough expressions to match multiple
+ # The offset of the key within the packet shifts depending on the C-flag.
+ # nftables cannot handle complex enough expressions to match multiple
# offsets based on bitfields elsewhere.
- # We enforce a specific match for the checksum flag in validation, so the
- # gre_flags dict will always have a 'checksum' key when gre_key is populated.
- if not gre_flags['checksum']:
+ # We enforce a specific match for the checksum flag in validation, so the
+ # gre_flags dict will always have a 'checksum' key when gre_key is populated.
+ if not gre_flags['checksum']:
# No "unset" child node means C is set, we offset key lookup +32 bits
- output.append(f'@th,64,32 == {gre_key}')
+ output.append(f'@th,64,32 == {gre_key}')
else:
output.append(f'@th,32,32 == {gre_key}')
@@ -634,7 +640,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
return " ".join(output)
def parse_gre_flags(flags, force_keyed=False):
- flag_map = { # nft does not have symbolic names for these.
+ flag_map = { # nft does not have symbolic names for these.
'checksum': 1<<0,
'routing': 1<<1,
'key': 1<<2,
@@ -645,7 +651,7 @@ def parse_gre_flags(flags, force_keyed=False):
include = 0
exclude = 0
for fl_name, fl_state in flags.items():
- if not fl_state:
+ if not fl_state:
include |= flag_map[fl_name]
else: # 'unset' child tag
exclude |= flag_map[fl_name]
@@ -738,14 +744,14 @@ class GeoIPLock(object):
def __exit__(self, exc_type, exc_value, tb):
os.unlink(self.file)
-def geoip_update(firewall, force=False):
+def geoip_update(firewall=None, policy=None, force=False):
with GeoIPLock(geoip_lock_file) as lock:
if not lock:
print("Script is already running")
return False
- if not firewall:
- print("Firewall is not configured")
+ if not firewall and not policy:
+ print("Firewall and policy are not configured")
return True
if not os.path.exists(geoip_database):
@@ -760,23 +766,41 @@ def geoip_update(firewall, force=False):
ipv4_sets = {}
ipv6_sets = {}
+ ipv4_codes_policy = {}
+ ipv6_codes_policy = {}
+
+ ipv4_sets_policy = {}
+ ipv6_sets_policy = {}
+
# Map country codes to set names
- for codes, path in dict_search_recursive(firewall, 'country_code'):
- set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}'
- if ( path[0] == 'ipv4'):
- for code in codes:
- ipv4_codes.setdefault(code, []).append(set_name)
- elif ( path[0] == 'ipv6' ):
- set_name = f'GEOIP_CC6_{path[1]}_{path[2]}_{path[4]}'
- for code in codes:
- ipv6_codes.setdefault(code, []).append(set_name)
-
- if not ipv4_codes and not ipv6_codes:
+ if firewall:
+ for codes, path in dict_search_recursive(firewall, 'country_code'):
+ set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}'
+ if ( path[0] == 'ipv4'):
+ for code in codes:
+ ipv4_codes.setdefault(code, []).append(set_name)
+ elif ( path[0] == 'ipv6' ):
+ set_name = f'GEOIP_CC6_{path[1]}_{path[2]}_{path[4]}'
+ for code in codes:
+ ipv6_codes.setdefault(code, []).append(set_name)
+
+ if policy:
+ for codes, path in dict_search_recursive(policy, 'country_code'):
+ set_name = f'GEOIP_CC_{path[0]}_{path[1]}_{path[3]}'
+ if ( path[0] == 'route'):
+ for code in codes:
+ ipv4_codes_policy.setdefault(code, []).append(set_name)
+ elif ( path[0] == 'route6' ):
+ set_name = f'GEOIP_CC6_{path[0]}_{path[1]}_{path[3]}'
+ for code in codes:
+ ipv6_codes_policy.setdefault(code, []).append(set_name)
+
+ if not ipv4_codes and not ipv6_codes and not ipv4_codes_policy and not ipv6_codes_policy:
if force:
- print("GeoIP not in use by firewall")
+ print("GeoIP not in use by firewall and policy")
return True
- geoip_data = geoip_load_data([*ipv4_codes, *ipv6_codes])
+ geoip_data = geoip_load_data([*ipv4_codes, *ipv6_codes, *ipv4_codes_policy, *ipv6_codes_policy])
# Iterate IP blocks to assign to sets
for start, end, code in geoip_data:
@@ -785,19 +809,29 @@ def geoip_update(firewall, force=False):
ip_range = f'{start}-{end}' if start != end else start
for setname in ipv4_codes[code]:
ipv4_sets.setdefault(setname, []).append(ip_range)
+ if code in ipv4_codes_policy and ipv4:
+ ip_range = f'{start}-{end}' if start != end else start
+ for setname in ipv4_codes_policy[code]:
+ ipv4_sets_policy.setdefault(setname, []).append(ip_range)
if code in ipv6_codes and not ipv4:
ip_range = f'{start}-{end}' if start != end else start
for setname in ipv6_codes[code]:
ipv6_sets.setdefault(setname, []).append(ip_range)
+ if code in ipv6_codes_policy and not ipv4:
+ ip_range = f'{start}-{end}' if start != end else start
+ for setname in ipv6_codes_policy[code]:
+ ipv6_sets_policy.setdefault(setname, []).append(ip_range)
render(nftables_geoip_conf, 'firewall/nftables-geoip-update.j2', {
'ipv4_sets': ipv4_sets,
- 'ipv6_sets': ipv6_sets
+ 'ipv6_sets': ipv6_sets,
+ 'ipv4_sets_policy': ipv4_sets_policy,
+ 'ipv6_sets_policy': ipv6_sets_policy,
})
result = run(f'nft --file {nftables_geoip_conf}')
if result != 0:
- print('Error: GeoIP failed to update firewall')
+ print('Error: GeoIP failed to update firewall/policy')
return False
return True
diff --git a/python/vyos/frrender.py b/python/vyos/frrender.py
index 8d469e3e2..f4ed69205 100644
--- a/python/vyos/frrender.py
+++ b/python/vyos/frrender.py
@@ -1,4 +1,4 @@
-# Copyright 2024-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -92,7 +92,7 @@ def get_frrender_dict(conf, argv=None) -> dict:
if dict_search(f'area.{area_num}.area_type.nssa', ospf) is None:
del default_values['area'][area_num]['area_type']['nssa']
- for protocol in ['babel', 'bgp', 'connected', 'isis', 'kernel', 'rip', 'static']:
+ for protocol in ['babel', 'bgp', 'connected', 'isis', 'kernel', 'nhrp', 'rip', 'static']:
if dict_search(f'redistribute.{protocol}', ospf) is None:
del default_values['redistribute'][protocol]
if not bool(default_values['redistribute']):
@@ -543,6 +543,21 @@ def get_frrender_dict(conf, argv=None) -> dict:
elif conf.exists_effective(ospfv3_vrf_path):
vrf['name'][vrf_name]['protocols'].update({'ospfv3' : {'deleted' : ''}})
+ # We need to check the CLI if the RPKI node is present and thus load in all the default
+ # values present on the CLI - that's why we have if conf.exists()
+ rpki_vrf_path = ['vrf', 'name', vrf_name, 'protocols', 'rpki']
+ if 'rpki' in vrf_config.get('protocols', []):
+ rpki = conf.get_config_dict(rpki_vrf_path, key_mangling=('-', '_'), get_first_key=True,
+ with_pki=True, with_recursive_defaults=True)
+ rpki_ssh_key_base = '/run/frr/id_rpki'
+ for cache, cache_config in rpki.get('cache',{}).items():
+ if 'ssh' in cache_config:
+ cache_config['ssh']['public_key_file'] = f'{rpki_ssh_key_base}_{cache}.pub'
+ cache_config['ssh']['private_key_file'] = f'{rpki_ssh_key_base}_{cache}'
+ vrf['name'][vrf_name]['protocols'].update({'rpki' : rpki})
+ elif conf.exists_effective(rpki_vrf_path):
+ vrf['name'][vrf_name]['protocols'].update({'rpki' : {'deleted' : ''}})
+
# We need to check the CLI if the static node is present and thus load in all the default
# values present on the CLI - that's why we have if conf.exists()
static_vrf_path = ['vrf', 'name', vrf_name, 'protocols', 'static']
@@ -675,7 +690,7 @@ class FRRender:
output += render_to_string('frr/ripngd.frr.j2', config_dict['ripng'])
output += '\n'
if 'rpki' in config_dict and 'deleted' not in config_dict['rpki']:
- output += render_to_string('frr/rpki.frr.j2', config_dict['rpki'])
+ output += render_to_string('frr/rpki.frr.j2', {'rpki': config_dict['rpki']})
output += '\n'
if 'segment_routing' in config_dict and 'deleted' not in config_dict['segment_routing']:
output += render_to_string('frr/zebra.segment_routing.frr.j2', config_dict['segment_routing'])
@@ -697,6 +712,9 @@ class FRRender:
debug('FRR: START CONFIGURATION RENDERING')
# we can not reload an empty file, thus we always embed the marker
output = '!\n'
+ # Enable FRR logging
+ output += 'log syslog\n'
+ output += 'log facility local7\n'
# Enable SNMP agentx support
# SNMP AgentX support cannot be disabled once enabled
if 'snmp' in config_dict:
diff --git a/python/vyos/ifconfig/__init__.py b/python/vyos/ifconfig/__init__.py
index 206b2bba1..7838fa9a2 100644
--- a/python/vyos/ifconfig/__init__.py
+++ b/python/vyos/ifconfig/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/afi.py b/python/vyos/ifconfig/afi.py
index fd263d220..a391cb8a0 100644
--- a/python/vyos/ifconfig/afi.py
+++ b/python/vyos/ifconfig/afi.py
@@ -1,4 +1,4 @@
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py
index a659b9bd2..8a97243c5 100644
--- a/python/vyos/ifconfig/bond.py
+++ b/python/vyos/ifconfig/bond.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index d534dade7..ba06e3757 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@ from vyos.utils.assertion import assert_list
from vyos.utils.assertion import assert_positive
from vyos.utils.dict import dict_search
from vyos.utils.network import interface_exists
-from vyos.configdict import get_vlan_ids
+from vyos.configdict import get_vlans_ids_and_range
from vyos.configdict import list_diff
@Interface.register
@@ -376,11 +376,21 @@ class BridgeIf(Interface):
if 'priority' in interface_config:
lower.set_path_priority(interface_config['priority'])
+ # set BPDU guard
+ tmp = dict_search('bpdu_guard', interface_config)
+ value = '1' if (tmp != None) else '0'
+ lower.set_bpdu_guard(value)
+
+ # set root guard
+ tmp = dict_search('root_guard', interface_config)
+ value = '1' if (tmp != None) else '0'
+ lower.set_root_guard(value)
+
if 'enable_vlan' in config:
add_vlan = []
native_vlan_id = None
allowed_vlan_ids= []
- cur_vlan_ids = get_vlan_ids(interface)
+ cur_vlan_ids = get_vlans_ids_and_range(interface)
if 'native_vlan' in interface_config:
vlan_id = interface_config['native_vlan']
@@ -389,14 +399,8 @@ class BridgeIf(Interface):
if 'allowed_vlan' in interface_config:
for vlan in interface_config['allowed_vlan']:
- vlan_range = vlan.split('-')
- if len(vlan_range) == 2:
- for vlan_add in range(int(vlan_range[0]),int(vlan_range[1]) + 1):
- add_vlan.append(str(vlan_add))
- allowed_vlan_ids.append(str(vlan_add))
- else:
- add_vlan.append(vlan)
- allowed_vlan_ids.append(vlan)
+ add_vlan.append(vlan)
+ allowed_vlan_ids.append(vlan)
# Remove redundant VLANs from the system
for vlan in list_diff(cur_vlan_ids, add_vlan):
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py
index a886c1b9e..e5672ed50 100644
--- a/python/vyos/ifconfig/control.py
+++ b/python/vyos/ifconfig/control.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/dummy.py b/python/vyos/ifconfig/dummy.py
index 29a1965a3..93066c965 100644
--- a/python/vyos/ifconfig/dummy.py
+++ b/python/vyos/ifconfig/dummy.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 93727bdf6..864a9d0bc 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/geneve.py b/python/vyos/ifconfig/geneve.py
index f53ef4166..7c5b7c0fb 100644
--- a/python/vyos/ifconfig/geneve.py
+++ b/python/vyos/ifconfig/geneve.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/input.py b/python/vyos/ifconfig/input.py
index 201d3cacb..6cb1eb64c 100644
--- a/python/vyos/ifconfig/input.py
+++ b/python/vyos/ifconfig/input.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 979b62578..787364483 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@ from copy import deepcopy
from glob import glob
from ipaddress import IPv4Network
+from ipaddress import IPv6Interface
from netifaces import ifaddresses
# this is not the same as socket.AF_INET/INET6
from netifaces import AF_INET
@@ -216,6 +217,16 @@ class Interface(Control):
'location': '/sys/class/net/{ifname}/brport/priority',
'errormsg': '{ifname} is not a bridge port member'
},
+ 'bpdu_guard': {
+ 'validate': assert_boolean,
+ 'location': '/sys/class/net/{ifname}/brport/bpdu_guard',
+ 'errormsg': '{ifname} is not a bridge port member'
+ },
+ 'root_guard': {
+ 'validate': assert_boolean,
+ 'location': '/sys/class/net/{ifname}/brport/root_block',
+ 'errormsg': '{ifname} is not a bridge port member'
+ },
'proxy_arp': {
'validate': assert_boolean,
'location': '/proc/sys/net/ipv4/conf/{ifname}/proxy_arp',
@@ -412,11 +423,11 @@ class Interface(Control):
self._cmd(f'nft {nft_command}')
def _del_interface_from_ct_iface_map(self):
- nft_command = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}'
+ nft_command = f'delete element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' }}'
self._nft_check_and_run(nft_command)
def _add_interface_to_ct_iface_map(self, vrf_table_id: int):
- nft_command = f'add element inet vrf_zones ct_iface_map {{ "{self.ifname}" : {vrf_table_id} }}'
+ nft_command = f'add element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' : {vrf_table_id} }}'
self._nft_check_and_run(nft_command)
def get_ifindex(self):
@@ -909,7 +920,11 @@ class Interface(Control):
tmp = self.get_interface('ipv6_autoconf')
if tmp == autoconf:
return None
- return self.set_interface('ipv6_autoconf', autoconf)
+ rc = self.set_interface('ipv6_autoconf', autoconf)
+ if autoconf == '0':
+ flushed = self.flush_ipv6_slaac_addrs()
+ self.flush_ipv6_slaac_routes(ra_addrs=flushed)
+ return rc
def add_ipv6_eui64_address(self, prefix):
"""
@@ -937,6 +952,20 @@ class Interface(Control):
prefixlen = prefix.split('/')[1]
self.del_addr(f'{eui64}/{prefixlen}')
+ def set_ipv6_interface_identifier(self, identifier):
+ """
+ Set the interface identifier for IPv6 autoconf.
+ """
+ cmd = f'ip token set {identifier} dev {self.ifname}'
+ self._cmd(cmd)
+
+ def del_ipv6_interface_identifier(self):
+ """
+ Delete the interface identifier for IPv6 autoconf.
+ """
+ cmd = f'ip token delete dev {self.ifname}'
+ self._cmd(cmd)
+
def set_ipv6_forwarding(self, forwarding):
"""
Configure IPv6 interface-specific Host/Router behaviour.
@@ -1087,6 +1116,28 @@ class Interface(Control):
"""
self.set_interface('path_priority', priority)
+ def set_bpdu_guard(self, state):
+ """
+ Set BPDU guard state for a bridge port. When enabled, the port will be
+ disabled if it receives a BPDU packet.
+
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> Interface('eth0').set_bpdu_guard(1)
+ """
+ self.set_interface('bpdu_guard', state)
+
+ def set_root_guard(self, state):
+ """
+ Set root guard state for a bridge port. When enabled, the port will be
+ disabled if it receives a superior BPDU that would make it a root port.
+
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> Interface('eth0').set_root_guard(1)
+ """
+ self.set_interface('root_guard', state)
+
def set_port_isolation(self, on_or_off):
"""
Controls whether a given port will be isolated, which means it will be
@@ -1310,6 +1361,71 @@ class Interface(Control):
# flush all addresses
self._cmd(cmd)
+ def flush_ipv6_slaac_addrs(self) -> list:
+ """
+ Flush all IPv6 addresses installed in response to router advertisement
+ messages from this interface.
+
+ Will raise an exception on error.
+ Will return a list of flushed IPv6 addresses.
+ """
+ netns = get_interface_namespace(self.ifname)
+ netns_cmd = f'ip netns exec {netns}' if netns else ''
+ tmp = get_interface_address(self.ifname)
+ if not tmp or 'addr_info' not in tmp:
+ return
+
+ # Parse interface IP addresses. Example data:
+ # {'family': 'inet6', 'local': '2001:db8:1111:0:250:56ff:feb3:38c5',
+ # 'prefixlen': 64, 'scope': 'global', 'dynamic': True,
+ # 'mngtmpaddr': True, 'protocol': 'kernel_ra',
+ # 'valid_life_time': 2591987, 'preferred_life_time': 14387}
+ flushed = []
+ for addr_info in tmp['addr_info']:
+ if 'protocol' not in addr_info:
+ continue
+ if (addr_info['protocol'] == 'kernel_ra' and
+ addr_info['scope'] == 'global'):
+ # Flush IPv6 addresses installed by router advertisement
+ ra_addr = f"{addr_info['local']}/{addr_info['prefixlen']}"
+ flushed.append(ra_addr)
+ cmd = f'{netns_cmd} ip -6 addr del dev {self.ifname} {ra_addr}'
+ self._cmd(cmd)
+ return flushed
+
+ def flush_ipv6_slaac_routes(self, ra_addrs: list=[]) -> None:
+ """
+ Flush IPv6 default routes installed in response to router advertisement
+ messages from this interface.
+
+ Will raise an exception on error.
+ """
+ # Find IPv6 connected prefixes for flushed SLAAC addresses
+ connected = []
+ for addr in ra_addrs if isinstance(ra_addrs, list) else []:
+ connected.append(str(IPv6Interface(addr).network))
+
+ netns = get_interface_namespace(self.ifname)
+ netns_cmd = f'ip netns exec {netns}' if netns else ''
+
+ tmp = self._cmd(f'{netns_cmd} ip -j -6 route show dev {self.ifname}')
+ tmp = json.loads(tmp)
+ # Parse interface routes. Example data:
+ # {'dst': 'default', 'gateway': 'fe80::250:56ff:feb3:cdba',
+ # 'protocol': 'ra', 'metric': 1024, 'flags': [], 'expires': 1398,
+ # 'metrics': [{'hoplimit': 64}], 'pref': 'medium'}
+ for route in tmp:
+ # If it's a default route received from RA, delete it
+ if (dict_search('dst', route) == 'default' and
+ dict_search('protocol', route) == 'ra'):
+ self._cmd(f'{netns_cmd} ip -6 route del default via {route["gateway"]} dev {self.ifname}')
+ # Remove connected prefixes received from RA
+ if dict_search('dst', route) in connected:
+ # If it's a connected prefix, delete it
+ self._cmd(f'{netns_cmd} ip -6 route del {route["dst"]} dev {self.ifname}')
+
+ return None
+
def add_to_bridge(self, bridge_dict):
"""
Adds the interface to the bridge with the passed port config.
@@ -1320,8 +1436,6 @@ class Interface(Control):
# drop all interface addresses first
self.flush_addrs()
- ifname = self.ifname
-
for bridge, bridge_config in bridge_dict.items():
# add interface to bridge - use Section.klass to get BridgeIf class
Section.klass(bridge)(bridge, create=True).add_port(self.ifname)
@@ -1337,7 +1451,7 @@ class Interface(Control):
bridge_vlan_filter = Section.klass(bridge)(bridge, create=True).get_vlan_filter()
if int(bridge_vlan_filter):
- cur_vlan_ids = get_vlan_ids(ifname)
+ cur_vlan_ids = get_vlan_ids(self.ifname)
add_vlan = []
native_vlan_id = None
allowed_vlan_ids= []
@@ -1360,15 +1474,15 @@ class Interface(Control):
# Remove redundant VLANs from the system
for vlan in list_diff(cur_vlan_ids, add_vlan):
- cmd = f'bridge vlan del dev {ifname} vid {vlan} master'
+ cmd = f'bridge vlan del dev {self.ifname} vid {vlan} master'
self._cmd(cmd)
for vlan in allowed_vlan_ids:
- cmd = f'bridge vlan add dev {ifname} vid {vlan} master'
+ cmd = f'bridge vlan add dev {self.ifname} vid {vlan} master'
self._cmd(cmd)
# Setting native VLAN to system
if native_vlan_id:
- cmd = f'bridge vlan add dev {ifname} vid {native_vlan_id} pvid untagged master'
+ cmd = f'bridge vlan add dev {self.ifname} vid {native_vlan_id} pvid untagged master'
self._cmd(cmd)
def set_dhcp(self, enable: bool, vrf_changed: bool=False):
@@ -1447,12 +1561,11 @@ class Interface(Control):
if enable not in [True, False]:
raise ValueError()
- ifname = self.ifname
config_base = directories['dhcp6_client_dir']
- config_file = f'{config_base}/dhcp6c.{ifname}.conf'
- script_file = f'/etc/wide-dhcpv6/dhcp6c.{ifname}.script' # can not live under /run b/c of noexec mount option
- systemd_override_file = f'/run/systemd/system/dhcp6c@{ifname}.service.d/10-override.conf'
- systemd_service = f'dhcp6c@{ifname}.service'
+ config_file = f'{config_base}/dhcp6c.{self.ifname}.conf'
+ script_file = f'/etc/wide-dhcpv6/dhcp6c.{self.ifname}.script' # can not live under /run b/c of noexec mount option
+ systemd_override_file = f'/run/systemd/system/dhcp6c@{self.ifname}.service.d/10-override.conf'
+ systemd_service = f'dhcp6c@{self.ifname}.service'
# Rendered client configuration files require additional settings
config = deepcopy(self.config)
@@ -1792,11 +1905,26 @@ class Interface(Control):
value = '0' if (tmp != None) else '1'
self.set_ipv6_forwarding(value)
+ # Delete old interface identifier
+ # This should be before setting the accept_ra value
+ old = dict_search('ipv6.address.interface_identifier_old', config)
+ now = dict_search('ipv6.address.interface_identifier', config)
+ if old and not now:
+ # accept_ra of ra is required to delete the interface identifier
+ self.set_ipv6_accept_ra('2')
+ self.del_ipv6_interface_identifier()
+
+ # Set IPv6 Interface identifier
+ # This should be before setting the accept_ra value
+ tmp = dict_search('ipv6.address.interface_identifier', config)
+ if tmp:
+ # accept_ra is required to set the interface identifier
+ self.set_ipv6_accept_ra('2')
+ self.set_ipv6_interface_identifier(tmp)
+
# IPv6 router advertisements
tmp = dict_search('ipv6.address.autoconf', config)
- value = '2' if (tmp != None) else '1'
- if 'dhcpv6' in new_addr:
- value = '2'
+ value = '2' if (tmp != None) else '0'
self.set_ipv6_accept_ra(value)
# IPv6 address autoconfiguration
diff --git a/python/vyos/ifconfig/l2tpv3.py b/python/vyos/ifconfig/l2tpv3.py
index dfaa006aa..ea9294e99 100644
--- a/python/vyos/ifconfig/l2tpv3.py
+++ b/python/vyos/ifconfig/l2tpv3.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/loopback.py b/python/vyos/ifconfig/loopback.py
index 13e8a2c50..f4fc2c906 100644
--- a/python/vyos/ifconfig/loopback.py
+++ b/python/vyos/ifconfig/loopback.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/macsec.py b/python/vyos/ifconfig/macsec.py
index 3b4dc223f..4d76a1d46 100644
--- a/python/vyos/ifconfig/macsec.py
+++ b/python/vyos/ifconfig/macsec.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/macvlan.py b/python/vyos/ifconfig/macvlan.py
index fe948b920..7a26f9ef5 100644
--- a/python/vyos/ifconfig/macvlan.py
+++ b/python/vyos/ifconfig/macvlan.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/operational.py b/python/vyos/ifconfig/operational.py
index dc2742123..e60518948 100644
--- a/python/vyos/ifconfig/operational.py
+++ b/python/vyos/ifconfig/operational.py
@@ -1,4 +1,4 @@
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/pppoe.py b/python/vyos/ifconfig/pppoe.py
index 85ca3877e..4ca66cf4d 100644
--- a/python/vyos/ifconfig/pppoe.py
+++ b/python/vyos/ifconfig/pppoe.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py
index 50273cf67..4ea606495 100644
--- a/python/vyos/ifconfig/section.py
+++ b/python/vyos/ifconfig/section.py
@@ -1,4 +1,4 @@
-# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/sstpc.py b/python/vyos/ifconfig/sstpc.py
index d92ef23dc..e43a2f177 100644
--- a/python/vyos/ifconfig/sstpc.py
+++ b/python/vyos/ifconfig/sstpc.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py
index df904f7d5..f96364161 100644
--- a/python/vyos/ifconfig/tunnel.py
+++ b/python/vyos/ifconfig/tunnel.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/veth.py b/python/vyos/ifconfig/veth.py
index 2c8709d20..f4075fa02 100644
--- a/python/vyos/ifconfig/veth.py
+++ b/python/vyos/ifconfig/veth.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/vrrp.py b/python/vyos/ifconfig/vrrp.py
index 3ee22706c..4949fe571 100644
--- a/python/vyos/ifconfig/vrrp.py
+++ b/python/vyos/ifconfig/vrrp.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/vti.py b/python/vyos/ifconfig/vti.py
index 78f5895f8..030aa1ed7 100644
--- a/python/vyos/ifconfig/vti.py
+++ b/python/vyos/ifconfig/vti.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/vtun.py b/python/vyos/ifconfig/vtun.py
index ee790f275..e6963ce5d 100644
--- a/python/vyos/ifconfig/vtun.py
+++ b/python/vyos/ifconfig/vtun.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py
index 58844885b..0f55acf10 100644
--- a/python/vyos/ifconfig/vxlan.py
+++ b/python/vyos/ifconfig/vxlan.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py
index f5217aecb..c4e70056c 100644
--- a/python/vyos/ifconfig/wireguard.py
+++ b/python/vyos/ifconfig/wireguard.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,13 @@ from tempfile import NamedTemporaryFile
from hurry.filesize import size
from hurry.filesize import alternative
+from vyos.base import Warning
from vyos.configquery import ConfigTreeQuery
from vyos.ifconfig import Interface
from vyos.ifconfig import Operational
from vyos.template import is_ipv6
from vyos.template import is_ipv4
-
+from vyos.utils.network import get_wireguard_peers
class WireGuardOperational(Operational):
def _dump(self):
"""Dump wireguard data in a python friendly way."""
@@ -51,7 +52,7 @@ class WireGuardOperational(Operational):
'private_key': None if private_key == '(none)' else private_key,
'public_key': None if public_key == '(none)' else public_key,
'listen_port': int(listen_port),
- 'fw_mark': None if fw_mark == 'off' else int(fw_mark),
+ 'fw_mark': None if fw_mark == 'off' else int(fw_mark, 16),
'peers': {},
}
else:
@@ -251,92 +252,131 @@ class WireGuardIf(Interface):
"""Get a synthetic MAC address."""
return self.get_mac_synthetic()
+ def get_peer_public_keys(self, config, disabled=False):
+ """Get list of configured peer public keys"""
+ if 'peer' not in config:
+ return []
+
+ public_keys = []
+
+ for _, peer_config in config['peer'].items():
+ if disabled == ('disable' in peer_config):
+ public_keys.append(peer_config['public_key'])
+
+ return public_keys
+
def update(self, config):
"""General helper function which works on a dictionary retrived by
get_config_dict(). It's main intention is to consolidate the scattered
interface setup code and provide a single point of entry when workin
on any interface."""
- tmp_file = NamedTemporaryFile('w')
- tmp_file.write(config['private_key'])
- tmp_file.flush()
# Wireguard base command is identical for every peer
base_cmd = f'wg set {self.ifname}'
+
interface_cmd = base_cmd
if 'port' in config:
interface_cmd += ' listen-port {port}'
if 'fwmark' in config:
interface_cmd += ' fwmark {fwmark}'
- interface_cmd += f' private-key {tmp_file.name}'
- interface_cmd = interface_cmd.format(**config)
- # T6490: execute command to ensure interface configured
- self._cmd(interface_cmd)
+ with NamedTemporaryFile('w') as tmp_file:
+ tmp_file.write(config['private_key'])
+ tmp_file.flush()
- # If no PSK is given remove it by using /dev/null - passing keys via
- # the shell (usually bash) is considered insecure, thus we use a file
- no_psk_file = '/dev/null'
+ interface_cmd += f' private-key {tmp_file.name}'
+ interface_cmd = interface_cmd.format(**config)
+ # T6490: execute command to ensure interface configured
+ self._cmd(interface_cmd)
+
+ current_peer_public_keys = get_wireguard_peers(self.ifname)
+
+ if 'rebuild_required' in config:
+ # Remove all existing peers that no longer exist in config
+ current_public_keys = self.get_peer_public_keys(config)
+ cmd_remove_peers = [f' peer {public_key} remove'
+ for public_key in current_peer_public_keys
+ if public_key not in current_public_keys]
+ if cmd_remove_peers:
+ self._cmd(base_cmd + ''.join(cmd_remove_peers))
if 'peer' in config:
+ # Group removal of disabled peers in one command
+ current_disabled_peers = self.get_peer_public_keys(config, disabled=True)
+ cmd_disabled_peers = [f' peer {public_key} remove'
+ for public_key in current_disabled_peers]
+ if cmd_disabled_peers:
+ self._cmd(base_cmd + ''.join(cmd_disabled_peers))
+
+ peer_cmds = []
+ peer_domain_cmds = []
+ peer_psk_files = []
+
for peer, peer_config in config['peer'].items():
# T4702: No need to configure this peer when it was explicitly
# marked as disabled - also active sessions are terminated as
# the public key was already removed when entering this method!
if 'disable' in peer_config:
- # remove peer if disabled, no error report even if peer not exists
- cmd = base_cmd + ' peer {public_key} remove'
- self._cmd(cmd.format(**peer_config))
continue
- psk_file = no_psk_file
-
# start of with a fresh 'wg' command
- peer_cmd = base_cmd + ' peer {public_key}'
+ peer_cmd = ' peer {public_key}'
- try:
- cmd = peer_cmd
-
- if 'preshared_key' in peer_config:
- psk_file = '/tmp/tmp.wireguard.psk'
- with open(psk_file, 'w') as f:
- f.write(peer_config['preshared_key'])
- cmd += f' preshared-key {psk_file}'
-
- # Persistent keepalive is optional
- if 'persistent_keepalive' in peer_config:
- cmd += ' persistent-keepalive {persistent_keepalive}'
-
- # Multiple allowed-ip ranges can be defined - ensure we are always
- # dealing with a list
- if isinstance(peer_config['allowed_ips'], str):
- peer_config['allowed_ips'] = [peer_config['allowed_ips']]
- cmd += ' allowed-ips ' + ','.join(peer_config['allowed_ips'])
-
- self._cmd(cmd.format(**peer_config))
-
- cmd = peer_cmd
-
- # Ensure peer is created even if dns not working
- if {'address', 'port'} <= set(peer_config):
- if is_ipv6(peer_config['address']):
- cmd += ' endpoint [{address}]:{port}'
- elif is_ipv4(peer_config['address']):
- cmd += ' endpoint {address}:{port}'
- else:
- # don't set endpoint if address uses domain name
- continue
- elif {'host_name', 'port'} <= set(peer_config):
- cmd += ' endpoint {host_name}:{port}'
-
- self._cmd(cmd.format(**peer_config), env={
+ cmd = peer_cmd
+
+ if 'preshared_key' in peer_config:
+ with NamedTemporaryFile(mode='w', delete=False) as tmp_file:
+ tmp_file.write(peer_config['preshared_key'])
+ tmp_file.flush()
+ cmd += f' preshared-key {tmp_file.name}'
+ peer_psk_files.append(tmp_file.name)
+ else:
+ # If no PSK is given remove it by using /dev/null - passing keys via
+ # the shell (usually bash) is considered insecure, thus we use a file
+ cmd += f' preshared-key /dev/null'
+
+ # Persistent keepalive is optional
+ if 'persistent_keepalive' in peer_config:
+ cmd += ' persistent-keepalive {persistent_keepalive}'
+
+ # Multiple allowed-ip ranges can be defined - ensure we are always
+ # dealing with a list
+ if isinstance(peer_config['allowed_ips'], str):
+ peer_config['allowed_ips'] = [peer_config['allowed_ips']]
+ cmd += ' allowed-ips ' + ','.join(peer_config['allowed_ips'])
+
+ peer_cmds.append(cmd.format(**peer_config))
+
+ cmd = peer_cmd
+
+ # Ensure peer is created even if dns not working
+ if {'address', 'port'} <= set(peer_config):
+ if is_ipv6(peer_config['address']):
+ cmd += ' endpoint [{address}]:{port}'
+ elif is_ipv4(peer_config['address']):
+ cmd += ' endpoint {address}:{port}'
+ else:
+ # don't set endpoint if address uses domain name
+ continue
+ elif {'host_name', 'port'} <= set(peer_config):
+ cmd += ' endpoint {host_name}:{port}'
+ else:
+ continue
+
+ peer_domain_cmds.append(cmd.format(**peer_config))
+
+ try:
+ if peer_cmds:
+ self._cmd(base_cmd + ''.join(peer_cmds))
+
+ if peer_domain_cmds:
+ self._cmd(base_cmd + ''.join(peer_domain_cmds), env={
'WG_ENDPOINT_RESOLUTION_RETRIES': config['max_dns_retry']})
- except:
- # todo: logging
- pass
- finally:
- # PSK key file is not required to be stored persistently as its backed by CLI
- if psk_file != no_psk_file and os.path.exists(psk_file):
- os.remove(psk_file)
+ except Exception as e:
+ Warning(f'Failed to apply Wireguard peers on {self.ifname}: {e}')
+ finally:
+ for tmp in peer_psk_files:
+ os.unlink(tmp)
# call base class
super().update(config)
diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py
index 121f56bd5..69fd87347 100644
--- a/python/vyos/ifconfig/wireless.py
+++ b/python/vyos/ifconfig/wireless.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ifconfig/wwan.py b/python/vyos/ifconfig/wwan.py
index 004a64b39..2b5714b85 100644
--- a/python/vyos/ifconfig/wwan.py
+++ b/python/vyos/ifconfig/wwan.py
@@ -1,4 +1,4 @@
-# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/iflag.py b/python/vyos/iflag.py
index 3ce73c1bf..179f33497 100644
--- a/python/vyos/iflag.py
+++ b/python/vyos/iflag.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/include/__init__.py b/python/vyos/include/__init__.py
index 22e836531..ba196ffed 100644
--- a/python/vyos/include/__init__.py
+++ b/python/vyos/include/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/include/uapi/__init__.py b/python/vyos/include/uapi/__init__.py
index 22e836531..ba196ffed 100644
--- a/python/vyos/include/uapi/__init__.py
+++ b/python/vyos/include/uapi/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/include/uapi/linux/__init__.py b/python/vyos/include/uapi/linux/__init__.py
index 22e836531..ba196ffed 100644
--- a/python/vyos/include/uapi/linux/__init__.py
+++ b/python/vyos/include/uapi/linux/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/include/uapi/linux/fib_rules.py b/python/vyos/include/uapi/linux/fib_rules.py
index 72f0b18cb..83544f69b 100644
--- a/python/vyos/include/uapi/linux/fib_rules.py
+++ b/python/vyos/include/uapi/linux/fib_rules.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/include/uapi/linux/icmpv6.py b/python/vyos/include/uapi/linux/icmpv6.py
index 47e0c723c..cc30b76fd 100644
--- a/python/vyos/include/uapi/linux/icmpv6.py
+++ b/python/vyos/include/uapi/linux/icmpv6.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/include/uapi/linux/if_arp.py b/python/vyos/include/uapi/linux/if_arp.py
index 90cb66ebd..80c16a83d 100644
--- a/python/vyos/include/uapi/linux/if_arp.py
+++ b/python/vyos/include/uapi/linux/if_arp.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/include/uapi/linux/lwtunnel.py b/python/vyos/include/uapi/linux/lwtunnel.py
index 6797a762b..c598513a5 100644
--- a/python/vyos/include/uapi/linux/lwtunnel.py
+++ b/python/vyos/include/uapi/linux/lwtunnel.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/include/uapi/linux/neighbour.py b/python/vyos/include/uapi/linux/neighbour.py
index d5caf44b9..8878353e3 100644
--- a/python/vyos/include/uapi/linux/neighbour.py
+++ b/python/vyos/include/uapi/linux/neighbour.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/include/uapi/linux/rtnetlink.py b/python/vyos/include/uapi/linux/rtnetlink.py
index e31272460..f3778fa65 100644
--- a/python/vyos/include/uapi/linux/rtnetlink.py
+++ b/python/vyos/include/uapi/linux/rtnetlink.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/initialsetup.py b/python/vyos/initialsetup.py
index cb6b9e459..bff3adf20 100644
--- a/python/vyos/initialsetup.py
+++ b/python/vyos/initialsetup.py
@@ -1,7 +1,7 @@
# initialsetup -- functions for setting common values in config file,
# for use in installation and first boot scripts
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software Foundation;
diff --git a/python/vyos/ioctl.py b/python/vyos/ioctl.py
index 51574c1db..7f9ad226a 100644
--- a/python/vyos/ioctl.py
+++ b/python/vyos/ioctl.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/ipsec.py b/python/vyos/ipsec.py
index 28f77565a..81f3d0812 100644
--- a/python/vyos/ipsec.py
+++ b/python/vyos/ipsec.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/kea.py b/python/vyos/kea.py
index de397d8f9..15c8564b0 100644
--- a/python/vyos/kea.py
+++ b/python/vyos/kea.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,8 @@ import socket
from datetime import datetime
from datetime import timezone
+from vyos import ConfigError
from vyos.template import is_ipv6
-from vyos.template import isc_static_route
from vyos.template import netmask_from_cidr
from vyos.utils.dict import dict_search_args
from vyos.utils.file import file_permissions
@@ -113,22 +113,21 @@ def kea_parse_options(config):
default_route = ''
if 'default_router' in config:
- default_route = isc_static_route('0.0.0.0/0', config['default_router'])
+ default_route = f'0.0.0.0/0 - {config["default_router"]}'
routes = [
- isc_static_route(route, route_options['next_hop'])
+ f'{route} - {route_options["next_hop"]}'
for route, route_options in config['static_route'].items()
]
options.append(
{
- 'name': 'rfc3442-static-route',
+ 'name': 'classless-static-route',
'data': ', '.join(
routes if not default_route else routes + [default_route]
),
}
)
- options.append({'name': 'windows-static-route', 'data': ', '.join(routes)})
if 'time_zone' in config:
with open('/usr/share/zoneinfo/' + config['time_zone'], 'rb') as f:
@@ -149,7 +148,7 @@ def kea_parse_options(config):
def kea_parse_subnet(subnet, config):
- out = {'subnet': subnet, 'id': int(config['subnet_id'])}
+ out = {'subnet': subnet, 'id': int(config['subnet_id']), 'user-context': {}}
if 'option' in config:
out['option-data'] = kea_parse_options(config['option'])
@@ -167,6 +166,9 @@ def kea_parse_subnet(subnet, config):
out['valid-lifetime'] = int(config['lease'])
out['max-valid-lifetime'] = int(config['lease'])
+ if 'ping_check' in config:
+ out['user-context']['enable-ping-check'] = True
+
if 'range' in config:
pools = []
for num, range_config in config['range'].items():
@@ -220,6 +222,9 @@ def kea_parse_subnet(subnet, config):
reservations.append(reservation)
out['reservations'] = reservations
+ if 'dynamic_dns_update' in config:
+ out.update(kea_parse_ddns_settings(config['dynamic_dns_update']))
+
return out
@@ -349,6 +354,54 @@ def kea6_parse_subnet(subnet, config):
return out
+def kea_parse_tsig_algo(algo_spec):
+ translate = {
+ 'md5': 'HMAC-MD5',
+ 'sha1': 'HMAC-SHA1',
+ 'sha224': 'HMAC-SHA224',
+ 'sha256': 'HMAC-SHA256',
+ 'sha384': 'HMAC-SHA384',
+ 'sha512': 'HMAC-SHA512'
+ }
+ if algo_spec not in translate:
+ raise ConfigError(f'Unsupported TSIG algorithm: {algo_spec}')
+ return translate[algo_spec]
+
+def kea_parse_enable_disable(value):
+ return True if value == 'enable' else False
+
+def kea_parse_ddns_settings(config):
+ data = {}
+
+ if send_updates := config.get('send_updates'):
+ data['ddns-send-updates'] = kea_parse_enable_disable(send_updates)
+
+ if override_client_update := config.get('override_client_update'):
+ data['ddns-override-client-update'] = kea_parse_enable_disable(override_client_update)
+
+ if override_no_update := config.get('override_no_update'):
+ data['ddns-override-no-update'] = kea_parse_enable_disable(override_no_update)
+
+ if update_on_renew := config.get('update_on_renew'):
+ data['ddns-update-on-renew'] = kea_parse_enable_disable(update_on_renew)
+
+ if conflict_resolution := config.get('conflict_resolution'):
+ data['ddns-use-conflict-resolution'] = kea_parse_enable_disable(conflict_resolution)
+
+ if 'replace_client_name' in config:
+ data['ddns-replace-client-name'] = config['replace_client_name']
+ if 'generated_prefix' in config:
+ data['ddns-generated-prefix'] = config['generated_prefix']
+ if 'qualifying_suffix' in config:
+ data['ddns-qualifying-suffix'] = config['qualifying_suffix']
+ if 'ttl_percent' in config:
+ data['ddns-ttl-percent'] = int(config['ttl_percent']) / 100
+ if 'hostname_char_set' in config:
+ data['hostname-char-set'] = config['hostname_char_set']
+ if 'hostname_char_replacement' in config:
+ data['hostname-char-replacement'] = config['hostname_char_replacement']
+
+ return data
def _ctrl_socket_command(inet, command, args=None):
path = kea_ctrl_socket.format(inet=inet)
diff --git a/python/vyos/limericks.py b/python/vyos/limericks.py
index 3c6744816..0c02d5292 100644
--- a/python/vyos/limericks.py
+++ b/python/vyos/limericks.py
@@ -1,4 +1,4 @@
-# Copyright 2015, 2018 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/load_config.py b/python/vyos/load_config.py
index b910a2f92..f65e887f0 100644
--- a/python/vyos/load_config.py
+++ b/python/vyos/load_config.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/logger.py b/python/vyos/logger.py
index f7cc964d5..207f95c1b 100644
--- a/python/vyos/logger.py
+++ b/python/vyos/logger.py
@@ -1,4 +1,4 @@
-# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/migrate.py b/python/vyos/migrate.py
index 9d1613676..c06f6a76c 100644
--- a/python/vyos/migrate.py
+++ b/python/vyos/migrate.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/nat.py b/python/vyos/nat.py
index 29f8e961b..7be957a0c 100644
--- a/python/vyos/nat.py
+++ b/python/vyos/nat.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/opmode.py b/python/vyos/opmode.py
index 7b11d36dd..7f1fc6b4f 100644
--- a/python/vyos/opmode.py
+++ b/python/vyos/opmode.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/pki.py b/python/vyos/pki.py
index 55dc02631..4598c5daa 100644
--- a/python/vyos/pki.py
+++ b/python/vyos/pki.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/priority.py b/python/vyos/priority.py
index ab4e6d411..e61281d3c 100644
--- a/python/vyos/priority.py
+++ b/python/vyos/priority.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/progressbar.py b/python/vyos/progressbar.py
index 8d1042672..eb8ed474a 100644
--- a/python/vyos/progressbar.py
+++ b/python/vyos/progressbar.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/proto/generate_dataclass.py b/python/vyos/proto/generate_dataclass.py
index c6296c568..64485cd10 100755
--- a/python/vyos/proto/generate_dataclass.py
+++ b/python/vyos/proto/generate_dataclass.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/proto/vycall_pb2.py b/python/vyos/proto/vycall_pb2.py
new file mode 100644
index 000000000..95214d2a6
--- /dev/null
+++ b/python/vyos/proto/vycall_pb2.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: vycall.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cvycall.proto\"&\n\x06Status\x12\x0f\n\x07success\x18\x01 \x02(\x08\x12\x0b\n\x03out\x18\x02 \x02(\t\"Y\n\x04\x43\x61ll\x12\x13\n\x0bscript_name\x18\x01 \x02(\t\x12\x11\n\ttag_value\x18\x02 \x01(\t\x12\x11\n\targ_value\x18\x03 \x01(\t\x12\x16\n\x05reply\x18\x04 \x01(\x0b\x32\x07.Status\"~\n\x06\x43ommit\x12\x12\n\nsession_id\x18\x01 \x02(\t\x12\x0f\n\x07\x64ry_run\x18\x04 \x02(\x08\x12\x0e\n\x06\x61tomic\x18\x05 \x02(\x08\x12\x12\n\nbackground\x18\x06 \x02(\x08\x12\x15\n\x04init\x18\x07 \x01(\x0b\x32\x07.Status\x12\x14\n\x05\x63\x61lls\x18\x08 \x03(\x0b\x32\x05.Call')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vycall_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+ DESCRIPTOR._options = None
+ _STATUS._serialized_start=16
+ _STATUS._serialized_end=54
+ _CALL._serialized_start=56
+ _CALL._serialized_end=145
+ _COMMIT._serialized_start=147
+ _COMMIT._serialized_end=273
+# @@protoc_insertion_point(module_scope)
diff --git a/python/vyos/proto/vyconf_client.py b/python/vyos/proto/vyconf_client.py
index f34549309..a3ba9864c 100644
--- a/python/vyos/proto/vyconf_client.py
+++ b/python/vyos/proto/vyconf_client.py
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -52,7 +52,9 @@ def request_to_msg(req: vyconf_proto.RequestEnvelope) -> vyconf_pb2.RequestEnvel
def msg_to_response(msg: vyconf_pb2.Response) -> vyconf_proto.Response:
# pylint: disable=no-member
- d = MessageToDict(msg, preserving_proto_field_name=True)
+ d = MessageToDict(
+ msg, preserving_proto_field_name=True, use_integers_for_enums=True
+ )
response = vyconf_proto.Response(**d)
return response
diff --git a/python/vyos/proto/vyconf_pb2.py b/python/vyos/proto/vyconf_pb2.py
new file mode 100644
index 000000000..4bf0eb2e0
--- /dev/null
+++ b/python/vyos/proto/vyconf_pb2.py
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: vyconf.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cvyconf.proto\"\xae\x15\n\x07Request\x12!\n\x06prompt\x18\x01 \x01(\x0b\x32\x0f.Request.PromptH\x00\x12.\n\rsetup_session\x18\x02 \x01(\x0b\x32\x15.Request.SetupSessionH\x00\x12\x1b\n\x03set\x18\x03 \x01(\x0b\x32\x0c.Request.SetH\x00\x12!\n\x06\x64\x65lete\x18\x04 \x01(\x0b\x32\x0f.Request.DeleteH\x00\x12!\n\x06rename\x18\x05 \x01(\x0b\x32\x0f.Request.RenameH\x00\x12\x1d\n\x04\x63opy\x18\x06 \x01(\x0b\x32\r.Request.CopyH\x00\x12#\n\x07\x63omment\x18\x07 \x01(\x0b\x32\x10.Request.CommentH\x00\x12!\n\x06\x63ommit\x18\x08 \x01(\x0b\x32\x0f.Request.CommitH\x00\x12%\n\x08rollback\x18\t \x01(\x0b\x32\x11.Request.RollbackH\x00\x12\x1f\n\x05merge\x18\n \x01(\x0b\x32\x0e.Request.MergeH\x00\x12\x1d\n\x04save\x18\x0b \x01(\x0b\x32\r.Request.SaveH\x00\x12*\n\x0bshow_config\x18\x0c \x01(\x0b\x32\x13.Request.ShowConfigH\x00\x12!\n\x06\x65xists\x18\r \x01(\x0b\x32\x0f.Request.ExistsH\x00\x12&\n\tget_value\x18\x0e \x01(\x0b\x32\x11.Request.GetValueH\x00\x12(\n\nget_values\x18\x0f \x01(\x0b\x32\x12.Request.GetValuesH\x00\x12.\n\rlist_children\x18\x10 \x01(\x0b\x32\x15.Request.ListChildrenH\x00\x12)\n\x0brun_op_mode\x18\x11 \x01(\x0b\x32\x12.Request.RunOpModeH\x00\x12#\n\x07\x63onfirm\x18\x12 \x01(\x0b\x32\x10.Request.ConfirmH\x00\x12\x43\n\x18\x65nter_configuration_mode\x18\x13 \x01(\x0b\x32\x1f.Request.EnterConfigurationModeH\x00\x12\x41\n\x17\x65xit_configuration_mode\x18\x14 \x01(\x0b\x32\x1e.Request.ExitConfigurationModeH\x00\x12%\n\x08validate\x18\x15 \x01(\x0b\x32\x11.Request.ValidateH\x00\x12%\n\x08teardown\x18\x16 \x01(\x0b\x32\x11.Request.TeardownH\x00\x12\x30\n\x0ereload_reftree\x18\x17 \x01(\x0b\x32\x16.Request.ReloadReftreeH\x00\x12\x1d\n\x04load\x18\x18 \x01(\x0b\x32\r.Request.LoadH\x00\x12#\n\x07\x64iscard\x18\x19 \x01(\x0b\x32\x10.Request.DiscardH\x00\x12\x32\n\x0fsession_changed\x18\x1a \x01(\x0b\x32\x17.Request.SessionChangedH\x00\x12/\n\x0esession_of_pid\x18\x1b \x01(\x0b\x32\x15.Request.SessionOfPidH\x00\x12\x37\n\x12session_update_pid\x18\x1c \x01(\x0b\x32\x19.Request.SessionUpdatePidH\x00\x12(\n\nget_config\x18\x1d \x01(\x0b\x32\x12.Request.GetConfigH\x00\x1a\x08\n\x06Prompt\x1aP\n\x0cSetupSession\x12\x11\n\tClientPid\x18\x01 \x02(\x05\x12\x19\n\x11\x43lientApplication\x18\x02 \x01(\t\x12\x12\n\nOnBehalfOf\x18\x03 \x01(\x05\x1a!\n\x0cSessionOfPid\x12\x11\n\tClientPid\x18\x01 \x02(\x05\x1a%\n\x10SessionUpdatePid\x12\x11\n\tClientPid\x18\x01 \x02(\x05\x1a\x1a\n\tGetConfig\x12\r\n\x05\x64ummy\x18\x01 \x01(\x05\x1a\x1e\n\x08Teardown\x12\x12\n\nOnBehalfOf\x18\x01 \x01(\x05\x1a\x46\n\x08Validate\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12,\n\routput_format\x18\x02 \x01(\x0e\x32\x15.Request.OutputFormat\x1a\x13\n\x03Set\x12\x0c\n\x04Path\x18\x01 \x03(\t\x1a\x16\n\x06\x44\x65lete\x12\x0c\n\x04Path\x18\x01 \x03(\t\x1a\x18\n\x07\x44iscard\x12\r\n\x05\x64ummy\x18\x01 \x01(\x05\x1a\x1f\n\x0eSessionChanged\x12\r\n\x05\x64ummy\x18\x01 \x01(\x05\x1a\x35\n\x06Rename\x12\x11\n\tEditLevel\x18\x01 \x03(\t\x12\x0c\n\x04\x46rom\x18\x02 \x02(\t\x12\n\n\x02To\x18\x03 \x02(\t\x1a\x33\n\x04\x43opy\x12\x11\n\tEditLevel\x18\x01 \x03(\t\x12\x0c\n\x04\x46rom\x18\x02 \x02(\t\x12\n\n\x02To\x18\x03 \x02(\t\x1a(\n\x07\x43omment\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12\x0f\n\x07\x43omment\x18\x02 \x02(\t\x1aR\n\x06\x43ommit\x12\x0f\n\x07\x43onfirm\x18\x01 \x01(\x08\x12\x16\n\x0e\x43onfirmTimeout\x18\x02 \x01(\x05\x12\x0f\n\x07\x43omment\x18\x03 \x01(\t\x12\x0e\n\x06\x44ryRun\x18\x04 \x01(\x08\x1a\x1c\n\x08Rollback\x12\x10\n\x08Revision\x18\x01 \x02(\x05\x1aO\n\x04Load\x12\x10\n\x08Location\x18\x01 \x02(\t\x12\x0e\n\x06\x63\x61\x63hed\x18\x02 \x02(\x08\x12%\n\x06\x66ormat\x18\x03 \x01(\x0e\x32\x15.Request.ConfigFormat\x1aU\n\x05Merge\x12\x10\n\x08Location\x18\x01 \x02(\t\x12\x13\n\x0b\x64\x65structive\x18\x02 \x02(\x08\x12%\n\x06\x66ormat\x18\x03 \x01(\x0e\x32\x15.Request.ConfigFormat\x1a?\n\x04Save\x12\x10\n\x08Location\x18\x01 \x02(\t\x12%\n\x06\x66ormat\x18\x02 \x01(\x0e\x32\x15.Request.ConfigFormat\x1a\x41\n\nShowConfig\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12%\n\x06\x66ormat\x18\x02 \x01(\x0e\x32\x15.Request.ConfigFormat\x1a\x16\n\x06\x45xists\x12\x0c\n\x04Path\x18\x01 \x03(\t\x1a\x46\n\x08GetValue\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12,\n\routput_format\x18\x02 \x01(\x0e\x32\x15.Request.OutputFormat\x1aG\n\tGetValues\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12,\n\routput_format\x18\x02 \x01(\x0e\x32\x15.Request.OutputFormat\x1aJ\n\x0cListChildren\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12,\n\routput_format\x18\x02 \x01(\x0e\x32\x15.Request.OutputFormat\x1aG\n\tRunOpMode\x12\x0c\n\x04Path\x18\x01 \x03(\t\x12,\n\routput_format\x18\x02 \x01(\x0e\x32\x15.Request.OutputFormat\x1a\t\n\x07\x43onfirm\x1a\x46\n\x16\x45nterConfigurationMode\x12\x11\n\tExclusive\x18\x01 \x02(\x08\x12\x19\n\x11OverrideExclusive\x18\x02 \x02(\x08\x1a\x17\n\x15\x45xitConfigurationMode\x1a#\n\rReloadReftree\x12\x12\n\nOnBehalfOf\x18\x01 \x01(\x05\"#\n\x0c\x43onfigFormat\x12\t\n\x05\x43URLY\x10\x00\x12\x08\n\x04JSON\x10\x01\")\n\x0cOutputFormat\x12\x0c\n\x08OutPlain\x10\x00\x12\x0b\n\x07OutJSON\x10\x01\x42\x05\n\x03msg\";\n\x0fRequestEnvelope\x12\r\n\x05token\x18\x01 \x01(\t\x12\x19\n\x07request\x18\x02 \x02(\x0b\x32\x08.Request\"S\n\x08Response\x12\x17\n\x06status\x18\x01 \x02(\x0e\x32\x07.Errnum\x12\x0e\n\x06output\x18\x02 \x01(\t\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x0f\n\x07warning\x18\x04 \x01(\t*\xd2\x01\n\x06\x45rrnum\x12\x0b\n\x07SUCCESS\x10\x00\x12\x08\n\x04\x46\x41IL\x10\x01\x12\x10\n\x0cINVALID_PATH\x10\x02\x12\x11\n\rINVALID_VALUE\x10\x03\x12\x16\n\x12\x43OMMIT_IN_PROGRESS\x10\x04\x12\x18\n\x14\x43ONFIGURATION_LOCKED\x10\x05\x12\x12\n\x0eINTERNAL_ERROR\x10\x06\x12\x15\n\x11PERMISSION_DENIED\x10\x07\x12\x17\n\x13PATH_ALREADY_EXISTS\x10\x08\x12\x16\n\x12UNCOMMITED_CHANGES\x10\t')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vyconf_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+ DESCRIPTOR._options = None
+ _ERRNUM._serialized_start=2900
+ _ERRNUM._serialized_end=3110
+ _REQUEST._serialized_start=17
+ _REQUEST._serialized_end=2751
+ _REQUEST_PROMPT._serialized_start=1237
+ _REQUEST_PROMPT._serialized_end=1245
+ _REQUEST_SETUPSESSION._serialized_start=1247
+ _REQUEST_SETUPSESSION._serialized_end=1327
+ _REQUEST_SESSIONOFPID._serialized_start=1329
+ _REQUEST_SESSIONOFPID._serialized_end=1362
+ _REQUEST_SESSIONUPDATEPID._serialized_start=1364
+ _REQUEST_SESSIONUPDATEPID._serialized_end=1401
+ _REQUEST_GETCONFIG._serialized_start=1403
+ _REQUEST_GETCONFIG._serialized_end=1429
+ _REQUEST_TEARDOWN._serialized_start=1431
+ _REQUEST_TEARDOWN._serialized_end=1461
+ _REQUEST_VALIDATE._serialized_start=1463
+ _REQUEST_VALIDATE._serialized_end=1533
+ _REQUEST_SET._serialized_start=1535
+ _REQUEST_SET._serialized_end=1554
+ _REQUEST_DELETE._serialized_start=1556
+ _REQUEST_DELETE._serialized_end=1578
+ _REQUEST_DISCARD._serialized_start=1580
+ _REQUEST_DISCARD._serialized_end=1604
+ _REQUEST_SESSIONCHANGED._serialized_start=1606
+ _REQUEST_SESSIONCHANGED._serialized_end=1637
+ _REQUEST_RENAME._serialized_start=1639
+ _REQUEST_RENAME._serialized_end=1692
+ _REQUEST_COPY._serialized_start=1694
+ _REQUEST_COPY._serialized_end=1745
+ _REQUEST_COMMENT._serialized_start=1747
+ _REQUEST_COMMENT._serialized_end=1787
+ _REQUEST_COMMIT._serialized_start=1789
+ _REQUEST_COMMIT._serialized_end=1871
+ _REQUEST_ROLLBACK._serialized_start=1873
+ _REQUEST_ROLLBACK._serialized_end=1901
+ _REQUEST_LOAD._serialized_start=1903
+ _REQUEST_LOAD._serialized_end=1982
+ _REQUEST_MERGE._serialized_start=1984
+ _REQUEST_MERGE._serialized_end=2069
+ _REQUEST_SAVE._serialized_start=2071
+ _REQUEST_SAVE._serialized_end=2134
+ _REQUEST_SHOWCONFIG._serialized_start=2136
+ _REQUEST_SHOWCONFIG._serialized_end=2201
+ _REQUEST_EXISTS._serialized_start=2203
+ _REQUEST_EXISTS._serialized_end=2225
+ _REQUEST_GETVALUE._serialized_start=2227
+ _REQUEST_GETVALUE._serialized_end=2297
+ _REQUEST_GETVALUES._serialized_start=2299
+ _REQUEST_GETVALUES._serialized_end=2370
+ _REQUEST_LISTCHILDREN._serialized_start=2372
+ _REQUEST_LISTCHILDREN._serialized_end=2446
+ _REQUEST_RUNOPMODE._serialized_start=2448
+ _REQUEST_RUNOPMODE._serialized_end=2519
+ _REQUEST_CONFIRM._serialized_start=1799
+ _REQUEST_CONFIRM._serialized_end=1808
+ _REQUEST_ENTERCONFIGURATIONMODE._serialized_start=2532
+ _REQUEST_ENTERCONFIGURATIONMODE._serialized_end=2602
+ _REQUEST_EXITCONFIGURATIONMODE._serialized_start=2604
+ _REQUEST_EXITCONFIGURATIONMODE._serialized_end=2627
+ _REQUEST_RELOADREFTREE._serialized_start=2629
+ _REQUEST_RELOADREFTREE._serialized_end=2664
+ _REQUEST_CONFIGFORMAT._serialized_start=2666
+ _REQUEST_CONFIGFORMAT._serialized_end=2701
+ _REQUEST_OUTPUTFORMAT._serialized_start=2703
+ _REQUEST_OUTPUTFORMAT._serialized_end=2744
+ _REQUESTENVELOPE._serialized_start=2753
+ _REQUESTENVELOPE._serialized_end=2812
+ _RESPONSE._serialized_start=2814
+ _RESPONSE._serialized_end=2897
+# @@protoc_insertion_point(module_scope)
diff --git a/python/vyos/proto/vyconf_proto.py b/python/vyos/proto/vyconf_proto.py
new file mode 100644
index 000000000..ec62a6e35
--- /dev/null
+++ b/python/vyos/proto/vyconf_proto.py
@@ -0,0 +1,379 @@
+from enum import IntEnum
+from dataclasses import dataclass
+from dataclasses import field
+
+class Errnum(IntEnum):
+ SUCCESS = 0
+ FAIL = 1
+ INVALID_PATH = 2
+ INVALID_VALUE = 3
+ COMMIT_IN_PROGRESS = 4
+ CONFIGURATION_LOCKED = 5
+ INTERNAL_ERROR = 6
+ PERMISSION_DENIED = 7
+ PATH_ALREADY_EXISTS = 8
+ UNCOMMITED_CHANGES = 9
+
+class ConfigFormat(IntEnum):
+ CURLY = 0
+ JSON = 1
+
+class OutputFormat(IntEnum):
+ OutPlain = 0
+ OutJSON = 1
+
+@dataclass
+class Prompt:
+ pass
+
+@dataclass
+class SetupSession:
+ ClientPid: int = 0
+ ClientApplication: str = None
+ OnBehalfOf: int = None
+
+@dataclass
+class SessionOfPid:
+ ClientPid: int = 0
+
+@dataclass
+class SessionUpdatePid:
+ ClientPid: int = 0
+
+@dataclass
+class GetConfig:
+ dummy: int = None
+
+@dataclass
+class Teardown:
+ OnBehalfOf: int = None
+
+@dataclass
+class Validate:
+ Path: list[str] = field(default_factory=list)
+ output_format: OutputFormat = None
+
+@dataclass
+class Set:
+ Path: list[str] = field(default_factory=list)
+
+@dataclass
+class Delete:
+ Path: list[str] = field(default_factory=list)
+
+@dataclass
+class Discard:
+ dummy: int = None
+
+@dataclass
+class SessionChanged:
+ dummy: int = None
+
+@dataclass
+class Rename:
+ EditLevel: list[str] = field(default_factory=list)
+ From: str = ""
+ To: str = ""
+
+@dataclass
+class Copy:
+ EditLevel: list[str] = field(default_factory=list)
+ From: str = ""
+ To: str = ""
+
+@dataclass
+class Comment:
+ Path: list[str] = field(default_factory=list)
+ Comment: str = ""
+
+@dataclass
+class Commit:
+ Confirm: bool = None
+ ConfirmTimeout: int = None
+ Comment: str = None
+ DryRun: bool = None
+
+@dataclass
+class Rollback:
+ Revision: int = 0
+
+@dataclass
+class Load:
+ Location: str = ""
+ cached: bool = False
+ format: ConfigFormat = None
+
+@dataclass
+class Merge:
+ Location: str = ""
+ destructive: bool = False
+ format: ConfigFormat = None
+
+@dataclass
+class Save:
+ Location: str = ""
+ format: ConfigFormat = None
+
+@dataclass
+class ShowConfig:
+ Path: list[str] = field(default_factory=list)
+ format: ConfigFormat = None
+
+@dataclass
+class Exists:
+ Path: list[str] = field(default_factory=list)
+
+@dataclass
+class GetValue:
+ Path: list[str] = field(default_factory=list)
+ output_format: OutputFormat = None
+
+@dataclass
+class GetValues:
+ Path: list[str] = field(default_factory=list)
+ output_format: OutputFormat = None
+
+@dataclass
+class ListChildren:
+ Path: list[str] = field(default_factory=list)
+ output_format: OutputFormat = None
+
+@dataclass
+class RunOpMode:
+ Path: list[str] = field(default_factory=list)
+ output_format: OutputFormat = None
+
+@dataclass
+class Confirm:
+ pass
+
+@dataclass
+class EnterConfigurationMode:
+ Exclusive: bool = False
+ OverrideExclusive: bool = False
+
+@dataclass
+class ExitConfigurationMode:
+ pass
+
+@dataclass
+class ReloadReftree:
+ OnBehalfOf: int = None
+
+@dataclass
+class Request:
+ prompt: Prompt = None
+ setup_session: SetupSession = None
+ set: Set = None
+ delete: Delete = None
+ rename: Rename = None
+ copy: Copy = None
+ comment: Comment = None
+ commit: Commit = None
+ rollback: Rollback = None
+ merge: Merge = None
+ save: Save = None
+ show_config: ShowConfig = None
+ exists: Exists = None
+ get_value: GetValue = None
+ get_values: GetValues = None
+ list_children: ListChildren = None
+ run_op_mode: RunOpMode = None
+ confirm: Confirm = None
+ enter_configuration_mode: EnterConfigurationMode = None
+ exit_configuration_mode: ExitConfigurationMode = None
+ validate: Validate = None
+ teardown: Teardown = None
+ reload_reftree: ReloadReftree = None
+ load: Load = None
+ discard: Discard = None
+ session_changed: SessionChanged = None
+ session_of_pid: SessionOfPid = None
+ session_update_pid: SessionUpdatePid = None
+ get_config: GetConfig = None
+
+@dataclass
+class RequestEnvelope:
+ token: str = None
+ request: Request = None
+
+@dataclass
+class Response:
+ status: Errnum = None
+ output: str = None
+ error: str = None
+ warning: str = None
+
+def set_request_prompt(token: str = None):
+ reqi = Prompt ()
+ req = Request(prompt=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_setup_session(token: str = None, client_pid: int = 0, client_application: str = None, on_behalf_of: int = None):
+ reqi = SetupSession (client_pid, client_application, on_behalf_of)
+ req = Request(setup_session=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_session_of_pid(token: str = None, client_pid: int = 0):
+ reqi = SessionOfPid (client_pid)
+ req = Request(session_of_pid=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_session_update_pid(token: str = None, client_pid: int = 0):
+ reqi = SessionUpdatePid (client_pid)
+ req = Request(session_update_pid=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_get_config(token: str = None, dummy: int = None):
+ reqi = GetConfig (dummy)
+ req = Request(get_config=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_teardown(token: str = None, on_behalf_of: int = None):
+ reqi = Teardown (on_behalf_of)
+ req = Request(teardown=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_validate(token: str = None, path: list[str] = [], output_format: OutputFormat = None):
+ reqi = Validate (path, output_format)
+ req = Request(validate=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_set(token: str = None, path: list[str] = []):
+ reqi = Set (path)
+ req = Request(set=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_delete(token: str = None, path: list[str] = []):
+ reqi = Delete (path)
+ req = Request(delete=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_discard(token: str = None, dummy: int = None):
+ reqi = Discard (dummy)
+ req = Request(discard=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_session_changed(token: str = None, dummy: int = None):
+ reqi = SessionChanged (dummy)
+ req = Request(session_changed=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_rename(token: str = None, edit_level: list[str] = [], from_: str = "", to: str = ""):
+ reqi = Rename (edit_level, from_, to)
+ req = Request(rename=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_copy(token: str = None, edit_level: list[str] = [], from_: str = "", to: str = ""):
+ reqi = Copy (edit_level, from_, to)
+ req = Request(copy=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_comment(token: str = None, path: list[str] = [], comment: str = ""):
+ reqi = Comment (path, comment)
+ req = Request(comment=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_commit(token: str = None, confirm: bool = None, confirm_timeout: int = None, comment: str = None, dry_run: bool = None):
+ reqi = Commit (confirm, confirm_timeout, comment, dry_run)
+ req = Request(commit=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_rollback(token: str = None, revision: int = 0):
+ reqi = Rollback (revision)
+ req = Request(rollback=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_load(token: str = None, location: str = "", cached: bool = False, format: ConfigFormat = None):
+ reqi = Load (location, cached, format)
+ req = Request(load=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_merge(token: str = None, location: str = "", destructive: bool = False, format: ConfigFormat = None):
+ reqi = Merge (location, destructive, format)
+ req = Request(merge=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_save(token: str = None, location: str = "", format: ConfigFormat = None):
+ reqi = Save (location, format)
+ req = Request(save=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_show_config(token: str = None, path: list[str] = [], format: ConfigFormat = None):
+ reqi = ShowConfig (path, format)
+ req = Request(show_config=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_exists(token: str = None, path: list[str] = []):
+ reqi = Exists (path)
+ req = Request(exists=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_get_value(token: str = None, path: list[str] = [], output_format: OutputFormat = None):
+ reqi = GetValue (path, output_format)
+ req = Request(get_value=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_get_values(token: str = None, path: list[str] = [], output_format: OutputFormat = None):
+ reqi = GetValues (path, output_format)
+ req = Request(get_values=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_list_children(token: str = None, path: list[str] = [], output_format: OutputFormat = None):
+ reqi = ListChildren (path, output_format)
+ req = Request(list_children=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_run_op_mode(token: str = None, path: list[str] = [], output_format: OutputFormat = None):
+ reqi = RunOpMode (path, output_format)
+ req = Request(run_op_mode=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_confirm(token: str = None):
+ reqi = Confirm ()
+ req = Request(confirm=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_enter_configuration_mode(token: str = None, exclusive: bool = False, override_exclusive: bool = False):
+ reqi = EnterConfigurationMode (exclusive, override_exclusive)
+ req = Request(enter_configuration_mode=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_exit_configuration_mode(token: str = None):
+ reqi = ExitConfigurationMode ()
+ req = Request(exit_configuration_mode=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
+
+def set_request_reload_reftree(token: str = None, on_behalf_of: int = None):
+ reqi = ReloadReftree (on_behalf_of)
+ req = Request(reload_reftree=reqi)
+ req_env = RequestEnvelope(token, req)
+ return req_env
diff --git a/python/vyos/qos/__init__.py b/python/vyos/qos/__init__.py
index a2980ccde..4bffda2d2 100644
--- a/python/vyos/qos/__init__.py
+++ b/python/vyos/qos/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/base.py b/python/vyos/qos/base.py
index b477b5b5e..487249714 100644
--- a/python/vyos/qos/base.py
+++ b/python/vyos/qos/base.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/cake.py b/python/vyos/qos/cake.py
index ca5a26917..05a737649 100644
--- a/python/vyos/qos/cake.py
+++ b/python/vyos/qos/cake.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -54,7 +54,16 @@ class CAKE(QoSBase):
f'Invalid flow isolation parameter: {config["flow_isolation"]}'
)
+ if 'ack_filter' in config:
+ if 'aggressive' in config['ack_filter']:
+ tmp += ' ack-filter-aggressive'
+ else:
+ tmp += ' ack-filter'
+ else:
+ tmp += ' no-ack-filter'
+
tmp += ' nat' if 'flow_isolation_nat' in config else ' nonat'
+ tmp += ' no-split-gso' if 'no_split_gso' in config else ' split-gso'
self._cmd(tmp)
diff --git a/python/vyos/qos/droptail.py b/python/vyos/qos/droptail.py
index 427d43d19..223ab1e64 100644
--- a/python/vyos/qos/droptail.py
+++ b/python/vyos/qos/droptail.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/fairqueue.py b/python/vyos/qos/fairqueue.py
index f41d098fb..8f4fe2d47 100644
--- a/python/vyos/qos/fairqueue.py
+++ b/python/vyos/qos/fairqueue.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/fqcodel.py b/python/vyos/qos/fqcodel.py
index cd2340aa2..d574226ef 100644
--- a/python/vyos/qos/fqcodel.py
+++ b/python/vyos/qos/fqcodel.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/limiter.py b/python/vyos/qos/limiter.py
index 3f5c11112..dce376d3e 100644
--- a/python/vyos/qos/limiter.py
+++ b/python/vyos/qos/limiter.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/netem.py b/python/vyos/qos/netem.py
index 8bdef300b..8fdd75387 100644
--- a/python/vyos/qos/netem.py
+++ b/python/vyos/qos/netem.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/priority.py b/python/vyos/qos/priority.py
index 66d27a639..5f373f696 100644
--- a/python/vyos/qos/priority.py
+++ b/python/vyos/qos/priority.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/randomdetect.py b/python/vyos/qos/randomdetect.py
index a3a39da36..63445bb62 100644
--- a/python/vyos/qos/randomdetect.py
+++ b/python/vyos/qos/randomdetect.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/ratelimiter.py b/python/vyos/qos/ratelimiter.py
index a4f80a1be..b0d7b3072 100644
--- a/python/vyos/qos/ratelimiter.py
+++ b/python/vyos/qos/ratelimiter.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/roundrobin.py b/python/vyos/qos/roundrobin.py
index 509c4069f..d07dc0f52 100644
--- a/python/vyos/qos/roundrobin.py
+++ b/python/vyos/qos/roundrobin.py
@@ -1,4 +1,4 @@
-# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/qos/trafficshaper.py b/python/vyos/qos/trafficshaper.py
index 9f92ccd8b..3840e7d0e 100644
--- a/python/vyos/qos/trafficshaper.py
+++ b/python/vyos/qos/trafficshaper.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/raid.py b/python/vyos/raid.py
index 7fb794817..4ae63a100 100644
--- a/python/vyos/raid.py
+++ b/python/vyos/raid.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/remote.py b/python/vyos/remote.py
index c54fb6031..b73f486c0 100644
--- a/python/vyos/remote.py
+++ b/python/vyos/remote.py
@@ -1,4 +1,4 @@
-# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@ import stat
import sys
import tempfile
import urllib.parse
+import gzip
from contextlib import contextmanager
from pathlib import Path
@@ -44,6 +45,7 @@ from vyos.utils.misc import begin
from vyos.utils.process import cmd, rc_cmd
from vyos.version import get_version
from vyos.base import Warning
+from vyos.defaults import directories
CHUNK_SIZE = 8192
@@ -478,3 +480,45 @@ def get_remote_config(urlstring, source_host='', source_port=0):
return f.read()
finally:
os.remove(temp)
+
+
+def get_config_file(file_in: str, file_out: str, source_host='', source_port=0):
+ protocols = ['scp', 'sftp', 'http', 'https', 'ftp', 'tftp']
+ config_dir = directories['config']
+
+ with tempfile.NamedTemporaryFile() as tmp_file:
+ if any(file_in.startswith(f'{x}://') for x in protocols):
+ try:
+ download(
+ tmp_file.name,
+ file_in,
+ check_space=True,
+ source_host='',
+ source_port=0,
+ raise_error=True,
+ )
+ except Exception as e:
+ return e
+ file_name = tmp_file.name
+ else:
+ full_path = os.path.realpath(file_in)
+ if os.path.isfile(full_path):
+ file_in = full_path
+ else:
+ file_in = os.path.join(config_dir, file_in)
+ if not os.path.isfile(file_in):
+ return ValueError(f'No such file {file_in}')
+
+ file_name = file_in
+
+ if file_in.endswith('.gz'):
+ try:
+ with gzip.open(file_name, 'rb') as f_in:
+ with open(file_out, 'wb') as f_out:
+ shutil.copyfileobj(f_in, f_out)
+ except Exception as e:
+ return e
+ else:
+ shutil.copyfile(file_name, file_out)
+
+ return None
diff --git a/python/vyos/snmpv3_hashgen.py b/python/vyos/snmpv3_hashgen.py
index 324c3274d..57dba07a0 100644
--- a/python/vyos/snmpv3_hashgen.py
+++ b/python/vyos/snmpv3_hashgen.py
@@ -1,4 +1,4 @@
-# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/__init__.py b/python/vyos/system/__init__.py
index 0c91330ba..42af8e3e8 100644
--- a/python/vyos/system/__init__.py
+++ b/python/vyos/system/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/compat.py b/python/vyos/system/compat.py
index d35bddea2..23a34d38a 100644
--- a/python/vyos/system/compat.py
+++ b/python/vyos/system/compat.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/disk.py b/python/vyos/system/disk.py
index c8908cd5c..268a3b195 100644
--- a/python/vyos/system/disk.py
+++ b/python/vyos/system/disk.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/grub.py b/python/vyos/system/grub.py
index de8303ee2..0f04fa5e9 100644
--- a/python/vyos/system/grub.py
+++ b/python/vyos/system/grub.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/grub_util.py b/python/vyos/system/grub_util.py
index 4a3d8795e..e534334e6 100644
--- a/python/vyos/system/grub_util.py
+++ b/python/vyos/system/grub_util.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -56,13 +56,12 @@ def set_kernel_cmdline_options(cmdline_options: str, version: str = '',
@image.if_not_live_boot
def update_kernel_cmdline_options(cmdline_options: str,
- root_dir: str = '') -> None:
+ root_dir: str = '',
+ version = image.get_running_image()) -> None:
"""Update Kernel custom cmdline options"""
if not root_dir:
root_dir = disk.find_persistence()
- version = image.get_running_image()
-
boot_opts_current = grub.get_boot_opts(version, root_dir)
boot_opts_proposed = grub.BOOT_OPTS_STEM + f'{version} {cmdline_options}'
diff --git a/python/vyos/system/image.py b/python/vyos/system/image.py
index aae52e770..ed8a96fbb 100644
--- a/python/vyos/system/image.py
+++ b/python/vyos/system/image.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/system/raid.py b/python/vyos/system/raid.py
index 5b33d34da..c03764ad1 100644
--- a/python/vyos/system/raid.py
+++ b/python/vyos/system/raid.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/template.py b/python/vyos/template.py
index e75db1a8d..824d42136 100755
--- a/python/vyos/template.py
+++ b/python/vyos/template.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -36,6 +36,7 @@ DEFAULT_TEMPLATE_DIR = directories["templates"]
# Holds template filters registered via register_filter()
_FILTERS = {}
_TESTS = {}
+_CLEVER_FUNCTIONS = {}
# reuse Environments with identical settings to improve performance
@functools.lru_cache(maxsize=2)
@@ -58,6 +59,7 @@ def _get_environment(location=None):
)
env.filters.update(_FILTERS)
env.tests.update(_TESTS)
+ env.globals.update(_CLEVER_FUNCTIONS)
return env
@@ -77,7 +79,7 @@ def register_filter(name, func=None):
"Filters can only be registered before rendering the first template"
)
if name in _FILTERS:
- raise ValueError(f"A filter with name {name!r} was registered already")
+ raise ValueError(f"A filter with name {name!r} was already registered")
_FILTERS[name] = func
return func
@@ -97,10 +99,30 @@ def register_test(name, func=None):
"Tests can only be registered before rendering the first template"
)
if name in _TESTS:
- raise ValueError(f"A test with name {name!r} was registered already")
+ raise ValueError(f"A test with name {name!r} was already registered")
_TESTS[name] = func
return func
+def register_clever_function(name, func=None):
+ """Register a function to be available as test in templates under given name.
+
+ It can also be used as a decorator, see below in this module for examples.
+
+ :raise RuntimeError:
+ when trying to register a test after a template has been rendered already
+ :raise ValueError: when trying to register a name which was taken already
+ """
+ if func is None:
+ return functools.partial(register_clever_function, name)
+ if _get_environment.cache_info().currsize:
+ raise RuntimeError(
+ "Clever functions can only be registered before rendering the" \
+ "first template")
+ if name in _CLEVER_FUNCTIONS:
+ raise ValueError(f"A clever function with name {name!r} was already "\
+ "registered")
+ _CLEVER_FUNCTIONS[name] = func
+ return func
def render_to_string(template, content, formater=None, location=None):
"""Render a template from the template directory, raise on any errors.
@@ -150,6 +172,8 @@ def render(
# As we are opening the file with 'w', we are performing the rendering before
# calling open() to not accidentally erase the file if rendering fails
rendered = render_to_string(template, content, formater, location)
+ # Remove any trailing character and always add a new line at the end
+ rendered = rendered.rstrip() + "\n"
# Write to file
with open(destination, "w") as file:
@@ -390,28 +414,6 @@ def compare_netmask(netmask1, netmask2):
except:
return False
-@register_filter('isc_static_route')
-def isc_static_route(subnet, router):
- # https://ercpe.de/blog/pushing-static-routes-with-isc-dhcp-server
- # Option format is:
- # <netmask>, <network-byte1>, <network-byte2>, <network-byte3>, <router-byte1>, <router-byte2>, <router-byte3>
- # where bytes with the value 0 are omitted.
- from ipaddress import ip_network
- net = ip_network(subnet)
- # add netmask
- string = str(net.prefixlen) + ','
- # add network bytes
- if net.prefixlen:
- width = net.prefixlen // 8
- if net.prefixlen % 8:
- width += 1
- string += ','.join(map(str,tuple(net.network_address.packed)[:width])) + ','
-
- # add router bytes
- string += ','.join(router.split('.'))
-
- return string
-
@register_filter('is_file')
def is_file(filename):
if os.path.exists(filename):
@@ -580,6 +582,10 @@ def snmp_auth_oid(type):
}
return OIDs[type]
+@register_filter('quoted_join')
+def quoted_join(input_list, join_str, quote='"'):
+ return str(join_str).join(f'{quote}{elem}{quote}' for elem in input_list)
+
@register_filter('nft_action')
def nft_action(vyos_action):
if vyos_action == 'accept':
@@ -672,6 +678,29 @@ def nft_nested_group(out_list, includes, groups, key):
add_includes(name)
return out_list
+@register_filter('nft_accept_invalid')
+def nft_accept_invalid(ether_type):
+ ether_type_mapping = {
+ 'dhcp': 'udp sport 67 udp dport 68',
+ 'arp': 'arp',
+ 'pppoe-discovery': '0x8863',
+ 'pppoe': '0x8864',
+ '802.1q': '8021q',
+ '802.1ad': '8021ad',
+ 'wol': '0x0842',
+ }
+ if ether_type not in ether_type_mapping:
+ raise RuntimeError(f'Ethernet type "{ether_type}" not found in ' \
+ 'available ethernet types!')
+ out = 'ct state invalid '
+
+ if ether_type != 'dhcp':
+ out += 'ether type '
+
+ out += f'{ether_type_mapping[ether_type]} counter accept'
+
+ return out
+
@register_filter('nat_rule')
def nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
from vyos.nat import parse_nat_rule
@@ -726,7 +755,7 @@ def conntrack_rule(rule_conf, rule_id, action, ipv6=False):
if port[0] == '!':
operator = '!='
port = port[1:]
- output.append(f'th {prefix}port {operator} {port}')
+ output.append(f'th {prefix}port {operator} {{ {port} }}')
if 'group' in side_conf:
group = side_conf['group']
@@ -881,10 +910,77 @@ def kea_high_availability_json(config):
return dumps(data)
+@register_filter('kea_dynamic_dns_update_main_json')
+def kea_dynamic_dns_update_main_json(config):
+ from vyos.kea import kea_parse_ddns_settings
+ from json import dumps
+
+ data = kea_parse_ddns_settings(config)
+
+ if len(data) == 0:
+ return ''
+
+ return dumps(data, indent=8)[1:-1] + ','
+
+@register_filter('kea_dynamic_dns_update_tsig_key_json')
+def kea_dynamic_dns_update_tsig_key_json(config):
+ from vyos.kea import kea_parse_tsig_algo
+ from json import dumps
+ out = []
+
+ if 'tsig_key' not in config:
+ return dumps(out)
+
+ tsig_keys = config['tsig_key']
+
+ for tsig_key_name, tsig_key_config in tsig_keys.items():
+ tsig_key = {
+ 'name': tsig_key_name,
+ 'algorithm': kea_parse_tsig_algo(tsig_key_config['algorithm']),
+ 'secret': tsig_key_config['secret']
+ }
+ out.append(tsig_key)
+
+ return dumps(out, indent=12)
+
+@register_filter('kea_dynamic_dns_update_domains')
+def kea_dynamic_dns_update_domains(config, type_key):
+ from json import dumps
+ out = []
+
+ if type_key not in config:
+ return dumps(out)
+
+ domains = config[type_key]
+
+ for domain_name, domain_config in domains.items():
+ domain = {
+ 'name': domain_name,
+
+ }
+ if 'key_name' in domain_config:
+ domain['key-name'] = domain_config['key_name']
+
+ if 'dns_server' in domain_config:
+ dns_servers = []
+ for dns_server_config in domain_config['dns_server'].values():
+ dns_server = {
+ 'ip-address': dns_server_config['address']
+ }
+ if 'port' in dns_server_config:
+ dns_server['port'] = int(dns_server_config['port'])
+ dns_servers.append(dns_server)
+ domain['dns-servers'] = dns_servers
+
+ out.append(domain)
+
+ return dumps(out, indent=12)
+
@register_filter('kea_shared_network_json')
def kea_shared_network_json(shared_networks):
from vyos.kea import kea_parse_options
from vyos.kea import kea_parse_subnet
+ from vyos.kea import kea_parse_ddns_settings
from json import dumps
out = []
@@ -895,9 +991,13 @@ def kea_shared_network_json(shared_networks):
network = {
'name': name,
'authoritative': ('authoritative' in config),
- 'subnet4': []
+ 'subnet4': [],
+ 'user-context': {}
}
+ if 'dynamic_dns_update' in config:
+ network.update(kea_parse_ddns_settings(config['dynamic_dns_update']))
+
if 'option' in config:
network['option-data'] = kea_parse_options(config['option'])
@@ -907,6 +1007,9 @@ def kea_shared_network_json(shared_networks):
if 'bootfile_server' in config['option']:
network['next-server'] = config['option']['bootfile_server']
+ if 'ping_check' in config:
+ network['user-context']['enable-ping-check'] = True
+
if 'subnet' in config:
for subnet, subnet_config in config['subnet'].items():
if 'disable' in subnet_config:
@@ -998,3 +1101,39 @@ def vyos_defined(value, test_value=None, var_type=None):
else:
# Valid value and is matching optional argument if provided - return true
return True
+
+@register_clever_function('get_default_port')
+def get_default_port(service):
+ """
+ Jinja2 plugin to retrieve common service port number from vyos.defaults
+ class from a Jinja2 template. This removes the need to hardcode, or pass in
+ the data using the general dictionary.
+
+ Added to remove code complexity and make it easier to read.
+
+ Example:
+ {{ get_default_port('certbot_haproxy') }}
+ """
+ from vyos.defaults import internal_ports
+ if service not in internal_ports:
+ raise RuntimeError(f'Service "{service}" not found in internal ' \
+ 'vyos.defaults.internal_ports dict!')
+ return internal_ports[service]
+
+@register_clever_function('get_default_config_file')
+def get_default_config_file(filename):
+ """
+ Jinja2 plugin to retrieve a common configuration file path from
+ vyos.defaults class from a Jinja2 template. This removes the need to
+ hardcode, or pass in the data using the general dictionary.
+
+ Added to remove code complexity and make it easier to read.
+
+ Example:
+ {{ get_default_config_file('certbot_haproxy') }}
+ """
+ from vyos.defaults import config_files
+ if filename not in config_files:
+ raise RuntimeError(f'Configuration file "{filename}" not found in '\
+ 'internal vyos.defaults.config_files dict!')
+ return config_files[filename]
diff --git a/python/vyos/tpm.py b/python/vyos/tpm.py
index a24f149fd..663490dec 100644
--- a/python/vyos/tpm.py
+++ b/python/vyos/tpm.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/utils/__init__.py b/python/vyos/utils/__init__.py
index 3759b2125..280cde17f 100644
--- a/python/vyos/utils/__init__.py
+++ b/python/vyos/utils/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/assertion.py b/python/vyos/utils/assertion.py
index c7fa220c3..aa0614743 100644
--- a/python/vyos/utils/assertion.py
+++ b/python/vyos/utils/assertion.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/auth.py b/python/vyos/utils/auth.py
index 5d0e3464a..6e816af71 100644
--- a/python/vyos/utils/auth.py
+++ b/python/vyos/utils/auth.py
@@ -1,6 +1,6 @@
# authutils -- miscelanneous functions for handling passwords and publis keys
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software Foundation;
diff --git a/python/vyos/utils/backend.py b/python/vyos/utils/backend.py
new file mode 100644
index 000000000..d302a2efd
--- /dev/null
+++ b/python/vyos/utils/backend.py
@@ -0,0 +1,94 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# N.B. the following is a temporary addition for running smoketests under
+# vyconf and is not to be called explicitly, at the risk of catastophe.
+
+# pylint: disable=wrong-import-position
+
+from pathlib import Path
+
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import call
+from vyos.utils.process import is_systemd_service_active
+
+VYCONF_SENTINEL = '/run/vyconf_backend'
+
+MSG_ENABLE_VYCONF = 'This will enable the vyconf backend for testing. Proceed?'
+MSG_DISABLE_VYCONF = (
+ 'This will restore the legacy backend; it requires a reboot. Proceed?'
+)
+
+# read/set immutable file attribute without popen:
+# https://www.geeklab.info/2021/04/chattr-and-lsattr-in-python/
+import fcntl # pylint: disable=C0411 # noqa: E402
+from array import array # pylint: disable=C0411 # noqa: E402
+
+# FS constants - see /uapi/linux/fs.h in kernel source
+# or <elixir.free-electrons.com/linux/latest/source/include/uapi/linux/fs.h>
+FS_IOC_GETFLAGS = 0x80086601
+FS_IOC_SETFLAGS = 0x40086602
+FS_IMMUTABLE_FL = 0x010
+
+
+def chattri(filename: str, value: bool):
+ with open(filename, 'r') as f:
+ arg = array('L', [0])
+ fcntl.ioctl(f.fileno(), FS_IOC_GETFLAGS, arg, True)
+ if value:
+ arg[0] = arg[0] | FS_IMMUTABLE_FL
+ else:
+ arg[0] = arg[0] & ~FS_IMMUTABLE_FL
+ fcntl.ioctl(f.fileno(), FS_IOC_SETFLAGS, arg, True)
+
+
+def lsattri(filename: str) -> bool:
+ with open(filename, 'r') as f:
+ arg = array('L', [0])
+ fcntl.ioctl(f.fileno(), FS_IOC_GETFLAGS, arg, True)
+ return bool(arg[0] & FS_IMMUTABLE_FL)
+
+
+# End: read/set immutable file attribute without popen
+
+
+def vyconf_backend() -> bool:
+ return Path(VYCONF_SENTINEL).exists() and lsattri(VYCONF_SENTINEL)
+
+
+def set_vyconf_backend(value: bool, no_prompt: bool = False):
+ vyconfd_service = 'vyconfd.service'
+ commitd_service = 'vyos-commitd.service'
+ http_api_service = 'vyos-http-api.service'
+ match value:
+ case True:
+ if vyconf_backend():
+ return
+ if not no_prompt and not ask_yes_no(MSG_ENABLE_VYCONF):
+ return
+ Path(VYCONF_SENTINEL).touch()
+ chattri(VYCONF_SENTINEL, True)
+ call(f'systemctl restart {vyconfd_service}')
+ call(f'systemctl restart {commitd_service}')
+ if is_systemd_service_active(http_api_service):
+ call(f'systemctl restart {http_api_service}')
+ case False:
+ if not vyconf_backend():
+ return
+ if not no_prompt and not ask_yes_no(MSG_DISABLE_VYCONF):
+ return
+ chattri(VYCONF_SENTINEL, False)
+ Path(VYCONF_SENTINEL).unlink()
+ call('/sbin/shutdown -r now')
diff --git a/python/vyos/utils/boot.py b/python/vyos/utils/boot.py
index 708bef14d..f804cd94e 100644
--- a/python/vyos/utils/boot.py
+++ b/python/vyos/utils/boot.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/commit.py b/python/vyos/utils/commit.py
index 105aed8c2..4147c7fba 100644
--- a/python/vyos/utils/commit.py
+++ b/python/vyos/utils/commit.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,8 +13,13 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+# pylint: disable=import-outside-toplevel
+
+from typing import IO
+
+
def commit_in_progress():
- """ Not to be used in normal op mode scripts! """
+ """Not to be used in normal op mode scripts!"""
# The CStore backend locks the config by opening a file
# The file is not removed after commit, so just checking
@@ -36,7 +41,9 @@ def commit_in_progress():
from vyos.defaults import commit_lock
if getuser() != 'root':
- raise OSError('This functions needs to be run as root to return correct results!')
+ raise OSError(
+ 'This functions needs to be run as root to return correct results!'
+ )
for proc in process_iter():
try:
@@ -45,7 +52,7 @@ def commit_in_progress():
for f in files:
if f.path == commit_lock:
return True
- except NoSuchProcess as err:
+ except NoSuchProcess:
# Process died before we could examine it
pass
# Default case
@@ -53,8 +60,71 @@ def commit_in_progress():
def wait_for_commit_lock():
- """ Not to be used in normal op mode scripts! """
+ """Not to be used in normal op mode scripts!"""
from time import sleep
+
# Very synchronous approach to multiprocessing
while commit_in_progress():
sleep(1)
+
+
+# For transitional compatibility with the legacy commit locking mechanism,
+# we require a lockf/fcntl (POSIX-type) lock, hence the following in place
+# of vyos.utils.locking
+
+
+def acquire_commit_lock_file() -> tuple[IO, str]:
+ import fcntl
+ from pathlib import Path
+ from vyos.defaults import commit_lock
+
+ try:
+ # pylint: disable=consider-using-with
+ lock_fd = Path(commit_lock).open('w')
+ except IOError as e:
+ out = f'Critical error opening commit lock file {e}'
+ return None, out
+
+ try:
+ fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ return lock_fd, ''
+ except IOError:
+ out = 'Configuration system locked by another commit in progress'
+ lock_fd.close()
+ return None, out
+
+
+def release_commit_lock_file(file_descr):
+ import fcntl
+
+ if file_descr is None:
+ return
+ fcntl.lockf(file_descr, fcntl.LOCK_UN)
+ file_descr.close()
+
+
+def call_commit_hooks(which: str):
+ import re
+ import os
+ from pathlib import Path
+ from vyos.defaults import commit_hooks
+ from vyos.utils.process import rc_cmd
+
+ if which not in list(commit_hooks):
+ raise ValueError(f'no entry {which} in commit_hooks')
+
+ hook_dir = commit_hooks[which]
+ file_list = list(Path(hook_dir).glob('*'))
+ regex = re.compile('^[a-zA-Z0-9._-]+$')
+ hook_list = sorted([str(f) for f in file_list if regex.match(f.name)])
+ err = False
+ out = ''
+ for runf in hook_list:
+ try:
+ e, o = rc_cmd(runf)
+ except FileNotFoundError:
+ continue
+ err = err | bool(e)
+ out = out + o
+
+ return out, int(err)
diff --git a/python/vyos/utils/config.py b/python/vyos/utils/config.py
index deda13c13..1f067e91e 100644
--- a/python/vyos/utils/config.py
+++ b/python/vyos/utils/config.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/configfs.py b/python/vyos/utils/configfs.py
index 8617f0129..307e1446c 100644
--- a/python/vyos/utils/configfs.py
+++ b/python/vyos/utils/configfs.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/convert.py b/python/vyos/utils/convert.py
index 2f587405d..ea07f9514 100644
--- a/python/vyos/utils/convert.py
+++ b/python/vyos/utils/convert.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/cpu.py b/python/vyos/utils/cpu.py
index 8ace77d15..0f47123a4 100644
--- a/python/vyos/utils/cpu.py
+++ b/python/vyos/utils/cpu.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@ It has special cases for x86_64 and MAY work correctly on other architectures,
but nothing is certain.
"""
+import os
import re
def _read_cpuinfo():
@@ -114,3 +115,8 @@ def get_available_cpus():
out = json.loads(cmd('lscpu --extended -b --json'))
return out['cpus']
+
+
+def get_half_cpus():
+ """ return 1/2 of the numbers of available CPUs """
+ return max(1, os.cpu_count() // 2)
diff --git a/python/vyos/utils/dict.py b/python/vyos/utils/dict.py
index 1a7a6b96f..e6ef943c6 100644
--- a/python/vyos/utils/dict.py
+++ b/python/vyos/utils/dict.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/disk.py b/python/vyos/utils/disk.py
index d4271ebe1..b822badde 100644
--- a/python/vyos/utils/disk.py
+++ b/python/vyos/utils/disk.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/error.py b/python/vyos/utils/error.py
index 8d4709bff..75ad813f3 100644
--- a/python/vyos/utils/error.py
+++ b/python/vyos/utils/error.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/file.py b/python/vyos/utils/file.py
index eaebb57a3..31c2361df 100644
--- a/python/vyos/utils/file.py
+++ b/python/vyos/utils/file.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -28,22 +28,28 @@ def file_is_persistent(path):
absolute = os.path.abspath(os.path.dirname(path))
return re.match(location,absolute)
-def read_file(fname, defaultonfailure=None):
+def read_file(fname, defaultonfailure=None, sudo=False):
"""
read the content of a file, stripping any end characters (space, newlines)
should defaultonfailure be not None, it is returned on failure to read
"""
try:
- """ Read a file to string """
- with open(fname, 'r') as f:
- data = f.read().strip()
- return data
+ # Some files can only be read by root - emulate sudo cat call
+ if sudo:
+ from vyos.utils.process import cmd
+ data = cmd(['sudo', 'cat', fname])
+ else:
+ # If not sudo, just read the file
+ with open(fname, 'r') as f:
+ data = f.read()
+ return data.strip()
except Exception as e:
if defaultonfailure is not None:
return defaultonfailure
raise e
-def write_file(fname, data, defaultonfailure=None, user=None, group=None, mode=None, append=False):
+def write_file(fname, data, defaultonfailure=None, user=None, group=None,
+ mode=None, append=False, trailing_newline=False):
"""
Write content of data to given fname, should defaultonfailure be not None,
it is returned on failure to read.
@@ -60,6 +66,9 @@ def write_file(fname, data, defaultonfailure=None, user=None, group=None, mode=N
bytes = 0
with open(fname, 'w' if not append else 'a') as f:
bytes = f.write(data)
+ if trailing_newline and not data.endswith('\n'):
+ f.write('\n')
+ bytes += 1
chown(fname, user, group)
chmod(fname, mode)
return bytes
diff --git a/python/vyos/utils/io.py b/python/vyos/utils/io.py
index 205210b66..0883376d1 100644
--- a/python/vyos/utils/io.py
+++ b/python/vyos/utils/io.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/kernel.py b/python/vyos/utils/kernel.py
index 05eac8a6a..4d8544670 100644
--- a/python/vyos/utils/kernel.py
+++ b/python/vyos/utils/kernel.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/list.py b/python/vyos/utils/list.py
index 63ef720ab..931084e7c 100644
--- a/python/vyos/utils/list.py
+++ b/python/vyos/utils/list.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/locking.py b/python/vyos/utils/locking.py
index 63cb1a816..f4cd6fd41 100644
--- a/python/vyos/utils/locking.py
+++ b/python/vyos/utils/locking.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/misc.py b/python/vyos/utils/misc.py
index d82655914..0ffd82696 100644
--- a/python/vyos/utils/misc.py
+++ b/python/vyos/utils/misc.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py
index 2f666f0ee..2182642dd 100644
--- a/python/vyos/utils/network.py
+++ b/python/vyos/utils/network.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -256,40 +256,60 @@ def mac2eui64(mac, prefix=None):
except: # pylint: disable=bare-except
return
-def check_port_availability(ipaddress, port, protocol):
+def check_port_availability(address: str=None, port: int=0, protocol: str='tcp') -> bool:
"""
- Check if port is available and not used by any service
- Return False if a port is busy or IP address does not exists
+ Check if given port is available and not used by any service.
+
Should be used carefully for services that can start listening
dynamically, because IP address may be dynamic too
+
+ Args:
+ address: IPv4 or IPv6 address - if None, checks on all interfaces
+ port: TCP/UDP port number.
+
+
+ Returns:
+ False if a port is busy or IP address does not exists
+ True if a port is free and IP address exists
"""
- from socketserver import TCPServer, UDPServer
+ import socket
from ipaddress import ip_address
+ # treat None as "any address"
+ address = address or '::'
+
# verify arguments
try:
- ipaddress = ip_address(ipaddress).compressed
- except:
- raise ValueError(f'The {ipaddress} is not a valid IPv4 or IPv6 address')
+ address = ip_address(address).compressed
+ except ValueError:
+ raise ValueError(f'{address} is not a valid IPv4 or IPv6 address')
if port not in range(1, 65536):
- raise ValueError(f'The port number {port} is not in the 1-65535 range')
+ raise ValueError(f'Port {port} is not in range 1-65535')
if protocol not in ['tcp', 'udp']:
- raise ValueError(f'The protocol {protocol} is not supported. Only tcp and udp are allowed')
+ raise ValueError(f'{protocol} is not supported - only tcp and udp are allowed')
- # check port availability
+ protocol = socket.SOCK_STREAM if protocol == 'tcp' else socket.SOCK_DGRAM
try:
- if protocol == 'tcp':
- server = TCPServer((ipaddress, port), None, bind_and_activate=True)
- if protocol == 'udp':
- server = UDPServer((ipaddress, port), None, bind_and_activate=True)
- server.server_close()
- except Exception as e:
- # errno.h:
- #define EADDRINUSE 98 /* Address already in use */
- if e.errno == 98:
+ addr_info = socket.getaddrinfo(address, port, socket.AF_UNSPEC, protocol)
+ except socket.gaierror as e:
+ print(f'Invalid address: {address}')
+ return False
+
+ for family, socktype, proto, canonname, sockaddr in addr_info:
+ try:
+ with socket.socket(family, socktype, proto) as s:
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ s.bind(sockaddr)
+ # port is free to use
+ return True
+ except OSError:
+ # port is already in use
return False
- return True
+ # if we reach this point, no socket was tested and we assume the port is
+ # already in use - better safe then sorry
+ return False
+
def is_listen_port_bind_service(port: int, service: str) -> bool:
"""Check if listen port bound to expected program name
@@ -396,6 +416,21 @@ def is_wireguard_key_pair(private_key: str, public_key:str) -> bool:
else:
return False
+def get_wireguard_peers(ifname: str) -> list:
+ """
+ Return list of configured Wireguard peers for interface
+ :param ifname: Interface name
+ :type ifname: str
+ :return: list of public keys
+ :rtype: list
+ """
+ if not interface_exists(ifname):
+ return []
+
+ from vyos.utils.process import cmd
+ peers = cmd(f'wg show {ifname} peers')
+ return peers.splitlines()
+
def is_subnet_connected(subnet, primary=False):
"""
Verify is the given IPv4/IPv6 subnet is connected to any interface on this
@@ -615,3 +650,19 @@ def is_valid_ipv4_address_or_range(addr: str) -> bool:
return ip_network(addr).version == 4
except:
return False
+
+def is_valid_ipv6_address_or_range(addr: str) -> bool:
+ """
+ Validates if the provided address is a valid IPv4, CIDR or IPv4 range
+ :param addr: address to test
+ :return: bool: True if provided address is valid
+ """
+ from ipaddress import ip_network
+ try:
+ if '-' in addr: # If we are checking a range, validate both address's individually
+ split = addr.split('-')
+ return is_valid_ipv6_address_or_range(split[0]) and is_valid_ipv6_address_or_range(split[1])
+ else:
+ return ip_network(addr).version == 6
+ except:
+ return False
diff --git a/python/vyos/utils/permission.py b/python/vyos/utils/permission.py
index d938b494f..efd44bfeb 100644
--- a/python/vyos/utils/permission.py
+++ b/python/vyos/utils/permission.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/process.py b/python/vyos/utils/process.py
index 121b6e240..86a2747af 100644
--- a/python/vyos/utils/process.py
+++ b/python/vyos/utils/process.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,6 +14,7 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
import os
+import shlex
from subprocess import Popen
from subprocess import PIPE
@@ -21,20 +22,17 @@ from subprocess import STDOUT
from subprocess import DEVNULL
-def get_wrapper(vrf, netns, auth):
- wrapper = ''
+def get_wrapper(vrf, netns):
+ wrapper = None
if vrf:
- wrapper = f'ip vrf exec {vrf} '
+ wrapper = ['ip', 'vrf', 'exec', vrf]
elif netns:
- wrapper = f'ip netns exec {netns} '
- if auth:
- wrapper = f'{auth} {wrapper}'
+ wrapper = ['ip', 'netns', 'exec', netns]
return wrapper
def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=PIPE, stderr=PIPE, decode='utf-8', auth='', vrf=None,
- netns=None):
+ stdout=PIPE, stderr=PIPE, decode='utf-8', vrf=None, netns=None):
"""
popen is a wrapper helper around subprocess.Popen
with it default setting it will return a tuple (out, err)
@@ -75,28 +73,33 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
if not debug.enabled(flag):
flag = 'command'
+ use_shell = shell
+ stdin = None
+ if shell is None:
+ use_shell = False
+ if ' ' in command:
+ use_shell = True
+ if env:
+ use_shell = True
+
# Must be run as root to execute command in VRF or network namespace
+ wrapper = get_wrapper(vrf, netns)
if vrf or netns:
if os.getuid() != 0:
raise OSError(
'Permission denied: cannot execute commands in VRF and netns contexts as an unprivileged user'
)
- wrapper = get_wrapper(vrf, netns, auth)
- command = f'{wrapper} {command}' if wrapper else command
+ if use_shell:
+ command = f'{shlex.join(wrapper)} {command}'
+ else:
+ if type(command) is not list:
+ command = [command]
+ command = wrapper + command
- cmd_msg = f"cmd '{command}'"
+ cmd_msg = f"cmd '{command}'" if use_shell else f"cmd '{shlex.join(command)}'"
debug.message(cmd_msg, flag)
- use_shell = shell
- stdin = None
- if shell is None:
- use_shell = False
- if ' ' in command:
- use_shell = True
- if env:
- use_shell = True
-
if input:
stdin = PIPE
input = input.encode() if type(input) is str else input
@@ -155,7 +158,7 @@ def run(command, flag='', shell=None, input=None, timeout=None, env=None,
def cmd(command, flag='', shell=None, input=None, timeout=None, env=None,
stdout=PIPE, stderr=PIPE, decode='utf-8', raising=None, message='',
- expect=[0], auth='', vrf=None, netns=None):
+ expect=[0], vrf=None, netns=None):
"""
A wrapper around popen, which returns the stdout and
will raise the error code of a command
@@ -171,12 +174,11 @@ def cmd(command, flag='', shell=None, input=None, timeout=None, env=None,
input=input, timeout=timeout,
env=env, shell=shell,
decode=decode,
- auth=auth,
vrf=vrf,
netns=netns,
)
if code not in expect:
- wrapper = get_wrapper(vrf, netns, auth='')
+ wrapper = get_wrapper(vrf, netns)
command = f'{wrapper} {command}'
feedback = message + '\n' if message else ''
feedback += f'failed to run command: {command}\n'
diff --git a/python/vyos/utils/serial.py b/python/vyos/utils/serial.py
index b646f881e..68aad676e 100644
--- a/python/vyos/utils/serial.py
+++ b/python/vyos/utils/serial.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/helpers/vyos-sudo.py b/python/vyos/utils/session.py
index 75dd7f29d..bc5240fc7 100755..100644
--- a/src/helpers/vyos-sudo.py
+++ b/python/vyos/utils/session.py
@@ -1,6 +1,4 @@
-#!/usr/bin/env python3
-
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -12,22 +10,16 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-import sys
-
-from vyos.utils.permission import is_admin
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+# pylint: disable=import-outside-toplevel
-if __name__ == '__main__':
- if len(sys.argv) < 2:
- print('Missing command argument')
- sys.exit(1)
- if not is_admin():
- print('This account is not authorized to run this command')
- sys.exit(1)
+def in_config_session():
+ """Vyatta bash completion uses the following environment variable for
+ indication of the config mode environment, independent of legacy backend
+ initialization of Cstore"""
+ from os import environ
- os.execvp('sudo', ['sudo'] + sys.argv[1:])
+ return '_OFR_CONFIGURE' in environ
diff --git a/python/vyos/utils/strip_config.py b/python/vyos/utils/strip_config.py
index 7a9c78c9f..17f6867cb 100644
--- a/python/vyos/utils/strip_config.py
+++ b/python/vyos/utils/strip_config.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
#
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/system.py b/python/vyos/utils/system.py
index 6c112334b..e2197daf2 100644
--- a/python/vyos/utils/system.py
+++ b/python/vyos/utils/system.py
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/utils/vti_updown_db.py b/python/vyos/utils/vti_updown_db.py
index b491fc6f2..f4dd24007 100644
--- a/python/vyos/utils/vti_updown_db.py
+++ b/python/vyos/utils/vti_updown_db.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/version.py b/python/vyos/version.py
index 86e96d0ec..01986e4da 100644
--- a/python/vyos/version.py
+++ b/python/vyos/version.py
@@ -1,4 +1,4 @@
-# Copyright 2017-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/vyconf_session.py b/python/vyos/vyconf_session.py
new file mode 100644
index 000000000..3cf5fb4e3
--- /dev/null
+++ b/python/vyos/vyconf_session.py
@@ -0,0 +1,236 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+
+import os
+import tempfile
+from functools import wraps
+from typing import Type
+
+from vyos.proto import vyconf_client
+from vyos.migrate import ConfigMigrate
+from vyos.migrate import ConfigMigrateError
+from vyos.component_version import append_system_version
+from vyos.utils.session import in_config_session
+from vyos.proto.vyconf_proto import Errnum
+from vyos.utils.commit import acquire_commit_lock_file
+from vyos.utils.commit import release_commit_lock_file
+from vyos.utils.commit import call_commit_hooks
+from vyos.remote import get_config_file
+
+
+class VyconfSessionError(Exception):
+ pass
+
+
+class VyconfSession:
+ def __init__(
+ self, token: str = None, pid: int = None, on_error: Type[Exception] = None
+ ):
+ self.pid = os.getpid() if pid is None else pid
+ if token is None:
+ # CLI applications with arg pid=getppid() allow coordination
+ # with the ambient session; other uses (such as ConfigSession)
+ # may default to self pid
+ out = vyconf_client.send_request('session_of_pid', client_pid=self.pid)
+ if out.output is None:
+ out = vyconf_client.send_request('setup_session', client_pid=self.pid)
+ self.__token = out.output
+ else:
+ out = vyconf_client.send_request(
+ 'session_update_pid', token=token, client_pid=self.pid
+ )
+ if out.status:
+ raise ValueError(f'No existing session for token: {token}')
+ self.__token = token
+
+ self.in_config_session = in_config_session()
+ if self.in_config_session:
+ out = vyconf_client.send_request(
+ 'enter_configuration_mode', token=self.__token
+ )
+ if out.status:
+ raise VyconfSessionError(self.output(out))
+
+ self.on_error = on_error
+
+ def __del__(self):
+ if not self.in_config_session:
+ self.teardown()
+
+ def teardown(self):
+ vyconf_client.send_request('teardown', token=self.__token)
+
+ def exit_config_mode(self):
+ if self.session_changed():
+ return 'Uncommited changes', Errnum.UNCOMMITED_CHANGES
+ out = vyconf_client.send_request('exit_configuration_mode', token=self.__token)
+ return self.output(out), out.status
+
+ def in_session(self) -> bool:
+ return self.in_config_session
+
+ def session_changed(self) -> bool:
+ out = vyconf_client.send_request('session_changed', token=self.__token)
+ return not bool(out.status)
+
+ def get_config(self):
+ out = vyconf_client.send_request('get_config', token=self.__token)
+ if out.status:
+ raise VyconfSessionError(self.output(out))
+ return out.output
+
+ @staticmethod
+ def config_mode(f):
+ @wraps(f)
+ def wrapped(self, *args, **kwargs):
+ msg = 'operation not available outside of config mode'
+ if not self.in_config_session:
+ if self.on_error is None:
+ raise VyconfSessionError(msg)
+ raise self.on_error(msg)
+ return f(self, *args, **kwargs)
+
+ return wrapped
+
+ @staticmethod
+ def raise_exception(f):
+ @wraps(f)
+ def wrapped(self, *args, **kwargs):
+ if self.on_error is None:
+ return f(self, *args, **kwargs)
+ o, e = f(self, *args, **kwargs)
+ if e:
+ raise self.on_error(o)
+ return o, e
+
+ return wrapped
+
+ @staticmethod
+ def output(o):
+ out = ''
+ for res in (o.output, o.error, o.warning):
+ if res is not None:
+ out = out + res
+ return out
+
+ @raise_exception
+ @config_mode
+ def set(self, path: list[str]) -> tuple[str, int]:
+ out = vyconf_client.send_request('set', token=self.__token, path=path)
+ return self.output(out), out.status
+
+ @raise_exception
+ @config_mode
+ def delete(self, path: list[str]) -> tuple[str, int]:
+ out = vyconf_client.send_request('delete', token=self.__token, path=path)
+ return self.output(out), out.status
+
+ @raise_exception
+ @config_mode
+ def commit(self) -> tuple[str, int]:
+ if not self.session_changed():
+ out = 'No changes to commit'
+ return out, 0
+
+ lock_fd, out = acquire_commit_lock_file()
+ if lock_fd is None:
+ return out, Errnum.COMMIT_IN_PROGRESS
+
+ pre_out, _ = call_commit_hooks('pre')
+ out = vyconf_client.send_request('commit', token=self.__token)
+ os.environ['COMMIT_STATUS'] = 'FAILURE' if out.status else 'SUCCESS'
+ post_out, _ = call_commit_hooks('post')
+
+ release_commit_lock_file(lock_fd)
+
+ return pre_out + self.output(out) + post_out, out.status
+
+ @raise_exception
+ @config_mode
+ def discard(self) -> tuple[str, int]:
+ out = vyconf_client.send_request('discard', token=self.__token)
+ return self.output(out), out.status
+
+ @raise_exception
+ @config_mode
+ def load_config(
+ self, file_name: str, migrate: bool = False, cached: bool = False
+ ) -> tuple[str, int]:
+ # pylint: disable=consider-using-with
+ file_path = tempfile.NamedTemporaryFile(delete=False).name
+ err = get_config_file(file_name, file_path)
+ if err:
+ os.remove(file_path)
+ return str(err), Errnum.INVALID_VALUE
+ if not cached:
+ if migrate:
+ config_migrate = ConfigMigrate(file_path)
+ try:
+ config_migrate.run()
+ except ConfigMigrateError as e:
+ os.remove(file_path)
+ return repr(e), 1
+
+ out = vyconf_client.send_request(
+ 'load', token=self.__token, location=file_path, cached=cached
+ )
+
+ if not cached:
+ os.remove(file_path)
+
+ return self.output(out), out.status
+
+ @raise_exception
+ @config_mode
+ def merge_config(
+ self, file_name: str, migrate: bool = False, destructive: bool = False
+ ) -> tuple[str, int]:
+ # pylint: disable=consider-using-with
+ file_path = tempfile.NamedTemporaryFile(delete=False).name
+ err = get_config_file(file_name, file_path)
+ if err:
+ os.remove(file_path)
+ return str(err), Errnum.INVALID_VALUE
+ if migrate:
+ config_migrate = ConfigMigrate(file_path)
+ try:
+ config_migrate.run()
+ except ConfigMigrateError as e:
+ os.remove(file_path)
+ return repr(e), 1
+
+ out = vyconf_client.send_request(
+ 'merge', token=self.__token, location=file_path, destructive=destructive
+ )
+
+ os.remove(file_path)
+
+ return self.output(out), out.status
+
+ @raise_exception
+ def save_config(self, file: str, append_version: bool = False) -> tuple[str, int]:
+ out = vyconf_client.send_request('save', token=self.__token, location=file)
+ if append_version:
+ append_system_version(file)
+ return self.output(out), out.status
+
+ @raise_exception
+ def show_config(self, path: list[str] = None) -> tuple[str, int]:
+ if path is None:
+ path = []
+ out = vyconf_client.send_request('show_config', token=self.__token, path=path)
+ return self.output(out), out.status
diff --git a/python/vyos/wanloadbalance.py b/python/vyos/wanloadbalance.py
index 62e109f21..2381f7d1c 100644
--- a/python/vyos/wanloadbalance.py
+++ b/python/vyos/wanloadbalance.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/xml_ref/__init__.py b/python/vyos/xml_ref/__init__.py
index 99d8432d2..41a25049e 100644
--- a/python/vyos/xml_ref/__init__.py
+++ b/python/vyos/xml_ref/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,6 +14,8 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, Union, TYPE_CHECKING
+from typing import Callable
+from typing import Any
from vyos.xml_ref import definition
from vyos.xml_ref import op_definition
@@ -89,6 +91,7 @@ def from_source(d: dict, path: list) -> bool:
def ext_dict_merge(source: dict, destination: Union[dict, 'ConfigDict']):
return definition.ext_dict_merge(source, destination)
+
def load_op_reference(op_cache=[]):
if op_cache:
return op_cache[0]
@@ -108,5 +111,26 @@ def load_op_reference(op_cache=[]):
return op_xml
-def get_op_ref_path(path: list) -> list[op_definition.PathData]:
- return load_op_reference()._get_op_ref_path(path)
+
+def walk_op_data(func: Callable[[tuple, dict], Any]):
+ return load_op_reference().walk(func)
+
+
+def walk_op_node_data():
+ return load_op_reference().walk_node_data()
+
+
+def lookup_op_data(
+ path: list, tag_values: bool = False, last_node_type: str = ''
+) -> (dict, list[str]):
+ return load_op_reference().lookup(
+ path, tag_values=tag_values, last_node_type=last_node_type
+ )
+
+
+def lookup_op_node_data(
+ path: list, tag_values: bool = False, last_node_type: str = ''
+) -> list[op_definition.NodeData]:
+ return load_op_reference().lookup_node_data(
+ path, tag_values=tag_values, last_node_type=last_node_type
+ )
diff --git a/python/vyos/xml_ref/definition.py b/python/vyos/xml_ref/definition.py
index 4e755ab72..015e7ee6e 100644
--- a/python/vyos/xml_ref/definition.py
+++ b/python/vyos/xml_ref/definition.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/python/vyos/xml_ref/generate_cache.py b/python/vyos/xml_ref/generate_cache.py
index 093697993..f0a3ec35b 100755
--- a/python/vyos/xml_ref/generate_cache.py
+++ b/python/vyos/xml_ref/generate_cache.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/python/vyos/xml_ref/generate_op_cache.py b/python/vyos/xml_ref/generate_op_cache.py
index 95779d066..266c81cd0 100755
--- a/python/vyos/xml_ref/generate_op_cache.py
+++ b/python/vyos/xml_ref/generate_op_cache.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -14,10 +14,13 @@
# 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
+import io
import re
import sys
-import json
import glob
+import json
+import atexit
from argparse import ArgumentParser
from os.path import join
@@ -25,23 +28,44 @@ from os.path import abspath
from os.path import dirname
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import Element
+from functools import cmp_to_key
from typing import TypeAlias
from typing import Optional
+from op_definition import NodeData
+from op_definition import OpKey # pylint: disable=unused-import # noqa: F401
+from op_definition import OpData # pylint: disable=unused-import # noqa: F401
+from op_definition import key_name
+from op_definition import key_type
+from op_definition import node_data_difference
+from op_definition import get_node_data
+from op_definition import collapse
+
_here = dirname(__file__)
sys.path.append(join(_here, '..'))
-from defaults import directories
-
-from op_definition import PathData
+# pylint: disable=wrong-import-position,wrong-import-order
+from defaults import directories # noqa: E402
-xml_op_cache_json = 'xml_op_cache.json'
-xml_op_tmp = join('/tmp', xml_op_cache_json)
op_ref_cache = abspath(join(_here, 'op_cache.py'))
+op_ref_json = abspath(join(_here, 'op_cache.json'))
OptElement: TypeAlias = Optional[Element]
-DEBUG = False
+
+
+# It is expected that the node_data help txt contained in top-level nodes,
+# shared across files, e.g.'show', will reveal inconsistencies; to list
+# differences, use --check-xml-consistency
+CHECK_XML_CONSISTENCY = False
+err_buf = io.StringIO()
+
+
+def write_err_buf():
+ err_buf.seek(0)
+ out = err_buf.read()
+ print(out)
+ err_buf.close()
def translate_exec(s: str) -> str:
@@ -74,14 +98,58 @@ def translate_op_script(s: str) -> str:
return s
-def insert_node(n: Element, l: list[PathData], path=None) -> None:
- # pylint: disable=too-many-locals,too-many-branches
+def compare_keys(a, b):
+ # pylint: disable=too-many-return-statements
+ match key_type(a), key_type(b):
+ case None, None:
+ if key_name(a) == key_name(b):
+ return 0
+ return -1 if key_name(a) < key_name(b) else 1
+ case None, _:
+ return -1
+ case _, None:
+ return 1
+ case _, _:
+ if key_name(a) == key_name(b):
+ if key_type(a) == key_type(b):
+ return 0
+ return -1 if key_type(a) < key_type(b) else 1
+ return -1 if key_name(a) < key_name(b) else 1
+
+
+def sort_func(obj: dict, key_func):
+ if not obj or not isinstance(obj, dict):
+ return obj
+ k_list = list(obj.keys())
+ if not isinstance(k_list[0], tuple):
+ return obj
+ k_list = sorted(k_list, key=key_func)
+ v_list = map(lambda t: sort_func(obj[t], key_func), k_list)
+ return dict(zip(k_list, v_list))
+
+
+def sort_op_data(obj):
+ key_func = cmp_to_key(compare_keys)
+ return sort_func(obj, key_func)
+
+
+def insert_node(
+ n: Element, d: dict, path: list[str] = None, parent: NodeData = None, file: str = ''
+) -> None:
+ # pylint: disable=too-many-locals,too-many-branches,too-many-statements
prop: OptElement = n.find('properties')
children: OptElement = n.find('children')
command: OptElement = n.find('command')
- # name is not None as required by schema
- name: str = n.get('name', 'schema_error')
+ standalone: OptElement = n.find('standalone')
node_type: str = n.tag
+
+ if node_type == 'virtualTagNode':
+ name = '__virtual_tag'
+ else:
+ name = n.get('name')
+ if not name:
+ raise ValueError("Node name is required for all node types except <virtualTagNode>")
+
if path is None:
path = []
@@ -95,6 +163,16 @@ def insert_node(n: Element, l: list[PathData], path=None) -> None:
if command_text is not None:
command_text = translate_command(command_text, path)
+ try:
+ standalone_command = translate_command(standalone.find('command').text, path)
+ except AttributeError:
+ standalone_command = None
+
+ try:
+ standalone_help_text = translate_command(standalone.find('help').text, path)
+ except AttributeError:
+ standalone_help_text = None
+
comp_help = {}
if prop is not None:
che = prop.findall('completionHelp')
@@ -124,31 +202,49 @@ def insert_node(n: Element, l: list[PathData], path=None) -> None:
if comp_scripts:
comp_help['script'] = comp_scripts
- cur_node_dict = {}
- cur_node_dict['name'] = name
- cur_node_dict['type'] = node_type
- cur_node_dict['comp_help'] = comp_help
- cur_node_dict['help'] = help_text
- cur_node_dict['command'] = command_text
- cur_node_dict['path'] = path
- cur_node_dict['children'] = []
- l.append(cur_node_dict)
+ cur_node_data = NodeData()
+ cur_node_data.name = name
+ cur_node_data.node_type = node_type
+ cur_node_data.comp_help = comp_help
+ cur_node_data.help_text = help_text
+ cur_node_data.command = command_text
+ cur_node_data.standalone_help_text = standalone_help_text
+ cur_node_data.standalone_command = standalone_command
+ cur_node_data.path = path
+ cur_node_data.file = file
+
+ value = {('__node_data', None): cur_node_data}
+ key = (name, node_type)
+
+ cur_value = d.setdefault(key, value)
+
+ if parent and key not in parent.children:
+ parent.children.append(key)
+
+ if CHECK_XML_CONSISTENCY:
+ out = node_data_difference(get_node_data(cur_value), get_node_data(value))
+ if out:
+ err_buf.write(out)
if children is not None:
inner_nodes = children.iterfind('*')
for inner_n in inner_nodes:
inner_path = path[:]
- insert_node(inner_n, cur_node_dict['children'], inner_path)
+ insert_node(inner_n, d[key], inner_path, cur_node_data, file)
-def parse_file(file_path, l):
+def parse_file(file_path, d):
tree = ET.parse(file_path)
root = tree.getroot()
+ file = os.path.basename(file_path)
for n in root.iterfind('*'):
- insert_node(n, l)
+ insert_node(n, d, file=file)
def main():
+ # pylint: disable=global-statement
+ global CHECK_XML_CONSISTENCY
+
parser = ArgumentParser(description='generate dict from xml defintions')
parser.add_argument(
'--xml-dir',
@@ -156,21 +252,58 @@ def main():
required=True,
help='transcluded xml op-mode-definition file',
)
+ parser.add_argument(
+ '--check-xml-consistency',
+ action='store_true',
+ help='check consistency of node data across files',
+ )
+ parser.add_argument(
+ '--check-path-ambiguity',
+ action='store_true',
+ help='attempt to reduce to unique paths, reporting if error',
+ )
+ parser.add_argument(
+ '--select',
+ type=str,
+ help='limit cache to a subset of XML files: "power_ctl | multicast-group | ..."',
+ )
args = vars(parser.parse_args())
+ if args['check_xml_consistency']:
+ CHECK_XML_CONSISTENCY = True
+ atexit.register(write_err_buf)
+
xml_dir = abspath(args['xml_dir'])
- l = []
+ d = {}
+
+ select = args['select']
+ if select:
+ select = [item.strip() for item in select.split('|')]
+
+ for fname in sorted(glob.glob(f'{xml_dir}/*.xml')):
+ file = os.path.basename(fname)
+ if not select or os.path.splitext(file)[0] in select:
+ parse_file(fname, d)
- for fname in glob.glob(f'{xml_dir}/*.xml'):
- parse_file(fname, l)
+ d = sort_op_data(d)
- with open(xml_op_tmp, 'w') as f:
- json.dump(l, f, indent=2)
+ if args['check_path_ambiguity']:
+ # when the following passes without error, return value will be the
+ # full dictionary indexed by str, not tuple
+ res, out, err = collapse(d)
+ if not err:
+ with open(op_ref_json, 'w') as f:
+ json.dump(res, f, indent=2)
+ else:
+ print('Found the following duplicate paths:\n')
+ print(out)
+ sys.exit(1)
with open(op_ref_cache, 'w') as f:
- f.write(f'op_reference = {str(l)}')
+ f.write('from vyos.xml_ref.op_definition import NodeData\n')
+ f.write(f'op_reference = {str(d)}')
if __name__ == '__main__':
diff --git a/python/vyos/xml_ref/op_definition.py b/python/vyos/xml_ref/op_definition.py
index 914f3a105..7b0a45a5b 100644
--- a/python/vyos/xml_ref/op_definition.py
+++ b/python/vyos/xml_ref/op_definition.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,37 +13,243 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
-from typing import TypedDict
from typing import TypeAlias
-from typing import Optional
from typing import Union
+from typing import Optional
+from typing import Iterator
+from dataclasses import dataclass
+from dataclasses import field
+from dataclasses import fields
+from dataclasses import asdict
+from itertools import filterfalse
+
+
+@dataclass
+class NodeData:
+ # pylint: disable=too-many-instance-attributes
+ name: str = ''
+ node_type: str = 'node'
+ help_text: str = ''
+ comp_help: dict[str, list] = field(default_factory=dict)
+ command: str = ''
+ standalone_help_text: Optional[str] = None
+ standalone_command: Optional[str] = None
+ path: list[str] = field(default_factory=list)
+ file: str = ''
+ children: list[tuple] = field(default_factory=list)
+
+
+OpKey: TypeAlias = tuple[str, str]
+OpData: TypeAlias = dict[OpKey, Union[NodeData, 'OpData']]
+
+
+def key_name(k: OpKey):
+ return k[0]
+
+
+def key_type(k: OpKey):
+ return k[1]
+
+
+def key_names(l: list): # noqa: E741
+ return list(map(lambda t: t[0], l))
+
+
+def keys_of_name(s: str, l: list): # noqa: E741
+ filter(lambda t: t[0] == s, l)
+
+
+def is_tag_node(t: tuple):
+ return t[1] == 'tagNode'
+
+
+def subdict_of_name(s: str, d: dict) -> dict:
+ res = {}
+ for t, v in d.items():
+ if not isinstance(t, tuple):
+ break
+ if key_name(t) == s:
+ res[t] = v
+
+ return res
+
+
+def next_keys(d: dict) -> list:
+ key_set = set()
+ for k in list(d.keys()):
+ if isinstance(d[k], dict):
+ key_set |= set(d[k].keys())
+ return list(key_set)
+
+
+def tuple_paths(d: dict) -> Iterator[list[tuple]]:
+ def func(d, path):
+ if isinstance(d, dict):
+ if not d:
+ yield path
+ for k, v in d.items():
+ if isinstance(k, tuple) and key_name(k) != '__node_data':
+ for r in func(v, path + [k]):
+ yield r
+ else:
+ yield path
+ else:
+ yield path
+ for r in func(d, []):
+ yield r
-class NodeData(TypedDict):
- node_type: Optional[str]
- help_text: Optional[str]
- comp_help: Optional[dict[str, list]]
- command: Optional[str]
- path: Optional[list[str]]
+def match_tuple_paths(
+ path: list[str], paths: list[list[tuple[str, str]]]
+) -> list[list[tuple[str, str]]]:
+ return list(filter(lambda p: key_names(p) == path, paths))
-PathData: TypeAlias = dict[str, Union[NodeData|list['PathData']]]
+
+def get_node_data(d: dict) -> NodeData:
+ return d.get(('__node_data', None), {})
+
+
+def get_node_data_at_path(d: dict, tpath):
+ if not tpath:
+ return {}
+ # operates on actual paths, not names:
+ if not isinstance(tpath[0], tuple):
+ raise ValueError('must be path of tuples')
+ while tpath and d:
+ d = d.get(tpath[0], {})
+ tpath = tpath[1:]
+
+ return get_node_data(d)
+
+
+def node_data_difference(a: NodeData, b: NodeData):
+ out = ''
+ for fld in fields(NodeData):
+ if fld.name in ('children', 'file'):
+ continue
+ a_fld = getattr(a, fld.name)
+ b_fld = getattr(b, fld.name)
+ if a_fld != b_fld:
+ out += f'prev: {a.file} {a.path} {fld.name}: {a_fld}\n'
+ out += f'new: {b.file} {b.path} {fld.name}: {b_fld}\n'
+ out += '\n'
+
+ return out
+
+
+def collapse(d: OpData, acc: dict = None) -> tuple[dict, str, bool]:
+ err = False
+ inner_err = False
+ out = ''
+ inner_out = ''
+ if acc is None:
+ acc = {}
+ if not isinstance(d, dict):
+ return d
+ for k, v in d.items():
+ if isinstance(k, tuple):
+ name = key_name(k)
+ if name != '__node_data':
+ new_data = get_node_data(v)
+ if name in list(acc.keys()):
+ err = True
+ prev_data = acc[name].get('__node_data', {})
+ if prev_data:
+ out += f'prev: {prev_data["file"]} {prev_data["path"]}\n'
+ else:
+ out += '\n'
+ out += f'new: {new_data.file} {new_data.path}\n\n'
+ else:
+ acc[name] = {}
+ acc[name]['__node_data'] = asdict(new_data)
+ inner, o, e = collapse(v)
+ inner_err |= e
+ inner_out += o
+ acc[name].update(inner)
+ else:
+ name = k
+ acc[name] = v
+
+ err |= inner_err
+ out += inner_out
+
+ return acc, out, err
class OpXml:
def __init__(self):
self.op_ref = {}
- def define(self, op_ref: list[PathData]) -> None:
+ def define(self, op_ref: dict) -> None:
self.op_ref = op_ref
- def _get_op_ref_path(self, path: list[str]) -> list[PathData]:
- def _get_path_list(path: list[str], l: list[PathData]) -> list[PathData]:
- if not path:
- return l
- for d in l:
- if path[0] in list(d):
- return _get_path_list(path[1:], d[path[0]])
- return []
- l = self.op_ref
- return _get_path_list(path, l)
+ def walk(self, func):
+ def walk_op_data(obj, func):
+ if isinstance(obj, dict):
+ for k, v in obj.items():
+ if isinstance(k, tuple):
+ res = func(k, v)
+ yield res
+ yield from walk_op_data(v, func)
+
+ return walk_op_data(self.op_ref, func)
+
+ @staticmethod
+ def get_node_data_func(k, v):
+ if key_name(k) == '__node_data':
+ return v
+ return None
+
+ def walk_node_data(self):
+ return filterfalse(lambda x: x is None, self.walk(self.get_node_data_func))
+
+ def lookup(
+ self, path: list[str], tag_values: bool = False, last_node_type: str = ''
+ ) -> (OpData, list[str]):
+ path = path[:]
+
+ ref_path = []
+
+ def prune_tree(d: dict, p: list[str]):
+ p = p[:]
+ if not d or not isinstance(d, dict) or not p:
+ return d
+ op_data: dict = subdict_of_name(p[0], d)
+ op_keys = list(op_data.keys())
+ ref_path.append(p[0])
+ if len(p) < 2:
+ # check last node_type
+ if last_node_type:
+ keys = list(filter(lambda t: t[1] == last_node_type, op_keys))
+ values = list(map(lambda t: op_data[t], keys))
+ return dict(zip(keys, values))
+ return op_data
+
+ if p[1] not in key_names(next_keys(op_data)):
+ # check if tag_values
+ if tag_values:
+ p = p[2:]
+ keys = list(filter(is_tag_node, op_keys))
+ values = list(map(lambda t: prune_tree(op_data[t], p), keys))
+ return dict(zip(keys, values))
+ return {}
+
+ p = p[1:]
+ op_data = list(map(lambda t: prune_tree(op_data[t], p), op_keys))
+
+ return dict(zip(op_keys, op_data))
+
+ return prune_tree(self.op_ref, path), ref_path
+
+ def lookup_node_data(
+ self, path: list[str], tag_values: bool = False, last_node_type: str = ''
+ ) -> list[NodeData]:
+ res = []
+ d, ref_path = self.lookup(path, tag_values, last_node_type)
+ paths = list(tuple_paths(d))
+ paths = match_tuple_paths(ref_path, paths)
+ for p in paths:
+ res.append(get_node_data_at_path(d, p))
+
+ return res
diff --git a/python/vyos/xml_ref/update_cache.py b/python/vyos/xml_ref/update_cache.py
index 0842bcbe9..6643f9dc4 100755
--- a/python/vyos/xml_ref/update_cache.py
+++ b/python/vyos/xml_ref/update_cache.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/schema/interface_definition.rnc b/schema/interface_definition.rnc
index 9434f5d18..a338b875f 100644
--- a/schema/interface_definition.rnc
+++ b/schema/interface_definition.rnc
@@ -1,6 +1,6 @@
# interface_definition.rnc: VyConf reference tree XML grammar
#
-# Copyright (C) 2014. 2017 VyOS maintainers and contributors <maintainers@vyos.net>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/schema/interface_definition.rng b/schema/interface_definition.rng
index e3d582452..d653d1b01 100644
--- a/schema/interface_definition.rng
+++ b/schema/interface_definition.rng
@@ -2,19 +2,19 @@
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<!--
interface_definition.rnc: VyConf reference tree XML grammar
-
- Copyright (C) 2014. 2017 VyOS maintainers and contributors <maintainers@vyos.net>
-
+
+ Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
-
+
This library 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
Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
diff --git a/schema/op-mode-definition.rnc b/schema/op-mode-definition.rnc
index ad41700b9..c10cf0431 100644
--- a/schema/op-mode-definition.rnc
+++ b/schema/op-mode-definition.rnc
@@ -1,6 +1,6 @@
# interface_definition.rnc: VyConf reference tree XML grammar
#
-# Copyright (C) 2014. 2017 VyOS maintainers and contributors <maintainers@vyos.net>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -37,12 +37,35 @@ node = element node
}
# Tag nodes are containers for nodes without predefined names, like network interfaces
-# or user names (e.g. "interfaces ethernet eth0" or "user jrandomhacker")
-# Tag nodes may contain node and leafNode elements, and also nameConstraint tags
-# They must not contain other tag nodes
+# or user names (e.g. "show interfaces ethernet ethX").
+# Operational mode tag nodes can be parents to other tag nodes,
+# like in "ping <host> count <packets>".
+#
+# Some commands can be called either with or without arguments,
+# like "show interfaces ethernet eth0" (show info for eth0 only)
+# or "show interfaces ethernet" (show info about all ethernet interfaces).
+# That case is handled using the <standalone> element
tagNode = element tagNode
{
nodeNameAttr,
+ (properties? & standalone? & children? & command?)
+}
+
+# The <standalone> element is only used inside tag nodes
+# to define their behavior when they are called without arguments
+# It can provide a help string and a command.
+# Everything else is handled in the <tagNode> itself.
+standalone = element standalone
+{
+ help & command
+}
+
+# Virtual tag nodes provide a way to add a variable argument
+# to a command that also needs fixed arguments,
+# like "show ip route" that can take "show ip route bgp"
+# or a network and arguments after it, like "show ip route 10.0.0.0/8 longer-prefixes"
+virtualTagNode = element virtualTagNode
+{
(properties? & children? & command?)
}
@@ -55,9 +78,11 @@ leafNode = element leafNode
(command & properties)
}
-# Normal and tag nodes may have children
+# Normal and tag nodes may have children: nodes, leaf nodes, or tag nodes.
+# There can only be one virtual tag node child, though.
children = element children
{
+ (virtualTagNode? & (node | tagNode | leafNode)*) |
(node | tagNode | leafNode)+
}
diff --git a/schema/op-mode-definition.rng b/schema/op-mode-definition.rng
index a255aeb73..692584fb4 100644
--- a/schema/op-mode-definition.rng
+++ b/schema/op-mode-definition.rng
@@ -2,19 +2,19 @@
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<!--
interface_definition.rnc: VyConf reference tree XML grammar
-
- Copyright (C) 2014. 2017 VyOS maintainers and contributors <maintainers@vyos.net>
-
+
+ Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
-
+
This library 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
Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
@@ -59,9 +59,14 @@
</define>
<!--
Tag nodes are containers for nodes without predefined names, like network interfaces
- or user names (e.g. "interfaces ethernet eth0" or "user jrandomhacker")
- Tag nodes may contain node and leafNode elements, and also nameConstraint tags
- They must not contain other tag nodes
+ or user names (e.g. "show interfaces ethernet ethX").
+ Operational mode tag nodes can be parents to other tag nodes,
+ like in "ping <host> count <packets>".
+
+ Some commands can be called either with or without arguments,
+ like "show interfaces ethernet eth0" (show info for eth0 only)
+ or "show interfaces ethernet" (show info about all ethernet interfaces).
+ That case is handled using the <standalone> element
-->
<define name="tagNode">
<element name="tagNode">
@@ -71,6 +76,44 @@
<ref name="properties"/>
</optional>
<optional>
+ <ref name="standalone"/>
+ </optional>
+ <optional>
+ <ref name="children"/>
+ </optional>
+ <optional>
+ <ref name="command"/>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+ <!--
+ The <standalone> element is only used inside tag nodes
+ to define their behavior when they are called without arguments
+ It can provide a help string and a command.
+ Everything else is handled in the <tagNode> itself.
+ -->
+ <define name="standalone">
+ <element name="standalone">
+ <interleave>
+ <ref name="help"/>
+ <ref name="command"/>
+ </interleave>
+ </element>
+ </define>
+ <!--
+ Virtual tag nodes provide a way to add a variable argument
+ to a command that also needs fixed arguments,
+ like "show ip route" that can take "show ip route bgp"
+ or a network and arguments after it, like "show ip route 10.0.0.0/8 longer-prefixes"
+ -->
+ <define name="virtualTagNode">
+ <element name="virtualTagNode">
+ <interleave>
+ <optional>
+ <ref name="properties"/>
+ </optional>
+ <optional>
<ref name="children"/>
</optional>
<optional>
@@ -92,16 +135,33 @@
</interleave>
</element>
</define>
- <!-- Normal and tag nodes may have children -->
+ <!--
+ Normal and tag nodes may have children: nodes, leaf nodes, or tag nodes.
+ There can only be one virtual tag node child, though.
+ -->
<define name="children">
<element name="children">
- <oneOrMore>
- <choice>
- <ref name="node"/>
- <ref name="tagNode"/>
- <ref name="leafNode"/>
- </choice>
- </oneOrMore>
+ <choice>
+ <interleave>
+ <optional>
+ <ref name="virtualTagNode"/>
+ </optional>
+ <zeroOrMore>
+ <choice>
+ <ref name="node"/>
+ <ref name="tagNode"/>
+ <ref name="leafNode"/>
+ </choice>
+ </zeroOrMore>
+ </interleave>
+ <oneOrMore>
+ <choice>
+ <ref name="node"/>
+ <ref name="tagNode"/>
+ <ref name="leafNode"/>
+ </choice>
+ </oneOrMore>
+ </choice>
</element>
</define>
<!--
@@ -139,10 +199,11 @@
<!--
completionHelp tags contain information about allowed values of a node that is used for generating
tab completion in the CLI frontend and drop-down lists in GUI frontends
- It is only meaninful for leaf nodes
+ It is only meaningful for leaf nodes
Allowed values can be given as a fixed list of values (e.g. <list>foo bar baz</list>),
as a configuration path (e.g. <path>interfaces ethernet</path>),
- or as a path to a script file that generates the list (e.g. <script>/usr/lib/foo/list-things</script>
+ as a path to a script file that generates the list (e.g. <script>/usr/lib/foo/list-things</script>,
+ or to enable built-in image path completion (<imagePath/>).
-->
<define name="completionHelp">
<element name="completionHelp">
diff --git a/scripts/build-command-op-templates b/scripts/build-command-op-templates
index d203fdcef..94bbd1d07 100755
--- a/scripts/build-command-op-templates
+++ b/scripts/build-command-op-templates
@@ -3,7 +3,7 @@
# build-command-template: converts new style command definitions in XML
# to the old style (bunch of dirs and node.def's) command templates
#
-# Copyright (C) 2017-2024 VyOS maintainers <maintainers@vyos.net>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,8 @@ import functools
from lxml import etree as ET
from textwrap import fill
+debug = True
+
# Defaults
validator_dir = "/opt/vyatta/libexec/validators"
default_constraint_err_msg = "Invalid value"
@@ -116,7 +118,7 @@ def get_properties(p):
if comptype is not None:
props["comp_type"] = "imagefiles"
comp_exprs.append("echo -n \"<imagefiles>\"")
- comp_help = " && ".join(comp_exprs)
+ comp_help = " ; ".join(comp_exprs)
props["comp_help"] = comp_help
except:
@@ -124,6 +126,26 @@ def get_properties(p):
return props
+def get_standalone(s):
+ standalone = {}
+
+ if s is None:
+ return {}
+
+ # Get the help string
+ try:
+ standalone["help"] = s.find("help").text
+ except:
+ standalone["help"] = "No help available"
+
+ # Get the command -- it's required by the schema
+ try:
+ standalone["command"] = s.find("command")
+ except:
+ raise AssertionError("Found a <standalone> node without <command>")
+
+ return standalone
+
def make_node_def(props, command):
# XXX: replace with a template processor if it grows
@@ -150,19 +172,27 @@ def process_node(n, tmpl_dir):
my_tmpl_dir = copy.copy(tmpl_dir)
props_elem = n.find("properties")
+ standalone_elem = n.find("standalone")
children = n.find("children")
command = n.find("command")
name = n.get("name")
node_type = n.tag
- my_tmpl_dir.append(name)
+ if name:
+ my_tmpl_dir.append(name)
+ else:
+ # Virtual tag nodes have no names,
+ # that's a normal situation.
+ # In that case we create subdirs at the current level.
+ pass
if debug:
print(f"Name of the node: {name};\n Created directory: ", end="")
os.makedirs(make_path(my_tmpl_dir), exist_ok=True)
props = get_properties(props_elem)
+ standalone = get_standalone(standalone_elem)
nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def")
if node_type == "node":
@@ -189,7 +219,10 @@ def process_node(n, tmpl_dir):
# does not exist at all.
if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0:
with open(nodedef_path, "w") as f:
- f.write('help: {0}\n'.format(props['help']))
+ if standalone:
+ f.write(make_node_def(standalone, standalone["command"]))
+ else:
+ f.write('help: {0}\n'.format(props['help']))
# Create the inner node.tag part
my_tmpl_dir.append("node.tag")
@@ -209,6 +242,27 @@ def process_node(n, tmpl_dir):
inner_nodes = children.iterfind("*")
for inner_n in inner_nodes:
process_node(inner_n, my_tmpl_dir)
+ elif node_type == "virtualTagNode":
+ # The outer structure is already created
+
+ # Create the inner node.tag part
+ my_tmpl_dir.append("node.tag")
+ os.makedirs(make_path(my_tmpl_dir), exist_ok=True)
+ if debug:
+ print("Created path for the virtualTagNode: {}".format(make_path(my_tmpl_dir)), end="")
+
+ # Not sure if we want partially defined tag nodes, write the file unconditionally
+ nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def")
+ # Only create the "node.def" file if it exists but is empty, or if it
+ # does not exist at all.
+ if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0:
+ with open(nodedef_path, "w") as f:
+ f.write(make_node_def(props, command))
+
+ if children is not None:
+ inner_nodes = children.iterfind("*")
+ for inner_n in inner_nodes:
+ process_node(inner_n, my_tmpl_dir)
elif node_type == "leafNode":
# This is a leaf node
if debug:
diff --git a/scripts/build-command-templates b/scripts/build-command-templates
index 36929abb2..5d4d27e8c 100755
--- a/scripts/build-command-templates
+++ b/scripts/build-command-templates
@@ -3,7 +3,7 @@
# build-command-template: converts new style command definitions in XML
# to the old style (bunch of dirs and node.def's) command templates
#
-# Copyright (C) 2017 VyOS maintainers <maintainers@vyos.net>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/scripts/generate-configd-include-json.py b/scripts/generate-configd-include-json.py
index b4b627fce..8d0accaf1 100755
--- a/scripts/generate-configd-include-json.py
+++ b/scripts/generate-configd-include-json.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/scripts/override-default b/scripts/override-default
index 5058e79b3..fe5b07bde 100755
--- a/scripts/override-default
+++ b/scripts/override-default
@@ -5,7 +5,7 @@
# directive. Must be called before build-command-templates, as the schema
# disallows redundancy.
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/scripts/transclude-template b/scripts/transclude-template
index 767583acd..932f91351 100755
--- a/scripts/transclude-template
+++ b/scripts/transclude-template
@@ -4,7 +4,7 @@
# interpret #include statements to include nested XML fragments and
# snippets in documents.
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/bin/vyos-configtest b/smoketest/bin/vyos-configtest
index fbf4055ad..23cbd4e54 100755
--- a/smoketest/bin/vyos-configtest
+++ b/smoketest/bin/vyos-configtest
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/bin/vyos-configtest-pki b/smoketest/bin/vyos-configtest-pki
index 0f9ecdd41..ac6272cc4 100755
--- a/smoketest/bin/vyos-configtest-pki
+++ b/smoketest/bin/vyos-configtest-pki
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024, VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/bin/vyos-smoketest b/smoketest/bin/vyos-smoketest
index 135388afe..d197499a7 100755
--- a/smoketest/bin/vyos-smoketest
+++ b/smoketest/bin/vyos-smoketest
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/config-tests/basic-haproxy b/smoketest/config-tests/basic-haproxy
new file mode 100644
index 000000000..7755fc4ea
--- /dev/null
+++ b/smoketest/config-tests/basic-haproxy
@@ -0,0 +1,46 @@
+set interfaces dummy dum0 address '172.18.254.203/32'
+set interfaces ethernet eth0 duplex 'auto'
+set interfaces ethernet eth0 speed 'auto'
+set interfaces ethernet eth0 vif 203 address '172.18.203.10/24'
+set interfaces ethernet eth1 duplex 'auto'
+set interfaces ethernet eth1 speed 'auto'
+set interfaces ethernet eth2 duplex 'auto'
+set interfaces ethernet eth2 speed 'auto'
+set load-balancing haproxy backend webserver logging facility daemon
+set load-balancing haproxy backend webserver logging facility user level 'info'
+set load-balancing haproxy backend webserver server web01 address '192.0.2.1'
+set load-balancing haproxy backend webserver server web01 port '443'
+set load-balancing haproxy backend webserver ssl no-verify
+set load-balancing haproxy global-parameters logging facility daemon
+set load-balancing haproxy global-parameters logging facility user level 'info'
+set load-balancing haproxy service frontend backend 'webserver'
+set load-balancing haproxy service frontend logging facility daemon
+set load-balancing haproxy service frontend logging facility user level 'info'
+set load-balancing haproxy service frontend port '443'
+set load-balancing haproxy service frontend ssl certificate 'dummy'
+set pki certificate dummy certificate 'MIIDsTCCApmgAwIBAgIUegVgO1wIN2v44trXZ+Kb1t48uL0wDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yNTA1MDUxODIzMTdaFw0yNjA1MDUxODIzMTdaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBSr4OYIWkb8UGuQnEFnjSbmvR+4vDAfBgNVHSMEGDAWgBSr4OYIWkb8UGuQnEFnjSbmvR+4vDANBgkqhkiG9w0BAQsFAAOCAQEAUmRWRPGXsvfuRT+53id3EufH1IJAdowrt6yBZsHobvqCXO2+YhG7oG6/UqUYiv5bHN5xEMQyWd7nyrLOUeFo2bpcMIOlpl6AoUIY65Gm2BqQ7FuPxLLO25RdpZ5WkMGX5kJsKY0/PcpamRKNz1khgFcRyxf9WGhCAIjDCWIWs8lkvPN3m75SFCW7MTuzzQOrzvI6nqqcHO4k8hRBznp26WLUW1rQKpNN09nZGOkeNYK5QbzKN/RUmtEHQZhlgLAIr09jUaA4RDLI1SdD6LR5nvpa9RJBTyS/kISF8BXKMgvUbDHN2nP+VUUrut2ZwoU+pxV4RVT2pS760HuYj4+sYQ=='
+set pki certificate dummy private key 'MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAECgf9plqCMg2pKEWRFl183bqWAm7lnLnsUOfABFNPYa3U+uKQUKZpboTBfzDfZqNak3XNQV0mTAR8pFfoMhQjQU9hUxH7ivjw1RUCHjixCF0vLBkTB34gL7FUbiEIFhR1NW3pCJY73OXOkIZG1Obh6Syb8KubDeu4bTmb90/TnDDAs6OYXJ5yo7ZDZLvLu5a3Dli+H4K5Qb5VJ74o/vtodBo3wmKBgy2Ey6JqF+y7/3HeE66rVhYNft5pURgemWnNYqh3oDTJASqpA/8n90o8ceYPVJugQ7029UiyTp0xgBRXFszgiYPkBlsNWB+9+ospopOmYU0owBykH+RtD/bQ0mwECgYEA4gxPdYbHg/GLihHrkv0t5V0pSEhBeBeTBdWG+P/6K90vXofpp7qISdOeYMGkh8mY+PfZNHksdu67d2ks5on5/dNf5YXWCm+LMMRiSsfOo11NISNdNHS6afqs18Wq1aKawv/rwotfxrakM4Gar692+jgz/l/X+FdOQwmE6uEus8ECgYEA3oW4eGtzGq28TiqyhTHduTkas0ckPWX8ulasyPnLxBKDNNohbXXpFIJIcrnl24QFJw3MJbo+R+OxZHgzPK8r64gIGVa7vLCR2fiU/RFoUa1Jo1pPOqXXWqf/Mvdokm2p0atrjRUX9VhjoFsDLcqTgAmfSCsVSqGucX6ER7Gy60UCgYAvmhoNjNFtFquk6rsqHAjTOTgdUaH/0S8T1nBy9SzQmeaEyKhKuvxCV78NbxnfwnNlUoQ6CZ50eTefINXkwn+TlTSnl/SIBA9SuLheOQ9p1ZcNeG4DQuWStcg6NBUSoghnMg+Ky2Di7slLU2qovpGWhcllMve/A1umwFVuRPdZwQKBgHS7mYYyd/Oq6HnpFDWjbzlXp5Yc3/oFooruJT5ZLHfzbjkvpRGTJW7I2dC1jMuXekx+hHXWOg3keI7IL7jJ/DRW7Ei+o0XdKuY57Y7ErwEJ8vNq0N1nWo4IS2wlNgp61PdVAdrFEgh3EexxUj2XY8FrSs/FKio4nxaS1Dn4EnAxAoGBAKqLvuPpmCMVwlIu57WGxL5d9i7EjIGY65l6HTKQYoHCzE51rkowH1La2fuUYz0IpExq2lcrLbOUtSyhXH7Zlktiz//Gu/P90SUfR/ZGcLeZi+EDyK2OctpnWBjs2Dmfg4D6vxk39yV8AB97pYG073GcJ/P54qRUuEitbpJwH+fB'
+set service ntp allow-client address '0.0.0.0/0'
+set service ntp allow-client address '::/0'
+set service ntp server 172.16.100.10
+set service ntp server 172.16.100.20
+set service ntp server 172.16.110.30
+set service ssh disable-host-validation
+set service ssh port '22'
+set system config-management commit-revisions '200'
+set system conntrack modules ftp
+set system conntrack modules h323
+set system conntrack modules nfs
+set system conntrack modules pptp
+set system conntrack modules sip
+set system conntrack modules sqlnet
+set system conntrack modules tftp
+set system console device ttyS0 speed '115200'
+set system host-name 'vyos'
+set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0'
+set system login user vyos authentication plaintext-password ''
+set system name-server '172.16.254.30'
+set system option kernel disable-mitigations
+set system syslog local facility all level 'info'
+set system syslog local facility local7 level 'debug'
+set system time-zone 'Europe/Berlin'
diff --git a/smoketest/config-tests/basic-vyos b/smoketest/config-tests/basic-vyos
index 4793e069e..aaf450e80 100644
--- a/smoketest/config-tests/basic-vyos
+++ b/smoketest/config-tests/basic-vyos
@@ -28,7 +28,21 @@ set protocols static arp interface eth2.200.201 address 100.64.201.20 mac '00:50
set protocols static arp interface eth2.200.202 address 100.64.202.30 mac '00:50:00:00:00:30'
set protocols static arp interface eth2.200.202 address 100.64.202.40 mac '00:50:00:00:00:40'
set protocols static route 0.0.0.0/0 next-hop 100.64.0.1
+set service dhcp-server dynamic-dns-update send-updates 'enable'
+set service dhcp-server dynamic-dns-update conflict-resolution 'enable'
+set service dhcp-server dynamic-dns-update tsig-key domain-lan-updates algorithm 'sha256'
+set service dhcp-server dynamic-dns-update tsig-key domain-lan-updates secret 'SXQncyBXZWRuZXNkYXkgbWFoIGR1ZGVzIQ=='
+set service dhcp-server dynamic-dns-update tsig-key reverse-0-168-192 algorithm 'sha256'
+set service dhcp-server dynamic-dns-update tsig-key reverse-0-168-192 secret 'VGhhbmsgR29kIGl0J3MgRnJpZGF5IQ=='
+set service dhcp-server dynamic-dns-update forward-domain domain.lan dns-server 1 address '192.168.0.1'
+set service dhcp-server dynamic-dns-update forward-domain domain.lan dns-server 2 address '100.100.0.1'
+set service dhcp-server dynamic-dns-update forward-domain domain.lan key-name 'domain-lan-updates'
+set service dhcp-server dynamic-dns-update reverse-domain 0.168.192.in-addr.arpa dns-server 1 address '192.168.0.1'
+set service dhcp-server dynamic-dns-update reverse-domain 0.168.192.in-addr.arpa dns-server 2 address '100.100.0.1'
+set service dhcp-server dynamic-dns-update reverse-domain 0.168.192.in-addr.arpa key-name 'reverse-0-168-192'
set service dhcp-server shared-network-name LAN authoritative
+set service dhcp-server shared-network-name LAN dynamic-dns-update send-updates 'enable'
+set service dhcp-server shared-network-name LAN dynamic-dns-update ttl-percent '75'
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 option default-router '192.168.0.1'
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 option domain-name 'vyos.net'
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 option domain-search 'vyos.net'
@@ -46,6 +60,9 @@ set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-map
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping TEST2-2 ip-address '192.168.0.21'
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping TEST2-2 mac '00:01:02:03:04:22'
set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 subnet-id '1'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 dynamic-dns-update send-updates 'enable'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 dynamic-dns-update generated-prefix 'myhost'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 dynamic-dns-update qualifying-suffix 'lan1.domain.lan'
set service dhcpv6-server shared-network-name LAN6 subnet fe88::/56 interface 'eth0'
set service dhcpv6-server shared-network-name LAN6 subnet fe88::/56 option domain-search 'vyos.net'
set service dhcpv6-server shared-network-name LAN6 subnet fe88::/56 option name-server 'fe88::1'
diff --git a/smoketest/config-tests/conntrack-basic b/smoketest/config-tests/conntrack-basic
new file mode 100644
index 000000000..8c375d244
--- /dev/null
+++ b/smoketest/config-tests/conntrack-basic
@@ -0,0 +1,35 @@
+set firewall global-options timeout icmp '30'
+set firewall global-options timeout other '600'
+set firewall global-options timeout udp other '300'
+set firewall global-options timeout udp stream '300'
+set interfaces ethernet eth0 vif 5 address '192.0.2.1/24'
+set interfaces ethernet eth1 vif 7 description 'FTTH-PPPoE'
+set nat source rule 100 log
+set nat source rule 100 outbound-interface name 'pppoe0'
+set nat source rule 100 source address '192.0.2.0/24'
+set nat source rule 100 translation address 'masquerade'
+set service ntp allow-client address '172.16.0.0/12'
+set service ntp server 0.pool.ntp.org
+set service ntp server 1.pool.ntp.org
+set service ntp server 2.pool.ntp.org
+set system config-management commit-revisions '200'
+set system conntrack expect-table-size '2048'
+set system conntrack hash-size '1024'
+set system conntrack modules ftp
+set system conntrack modules h323
+set system conntrack modules nfs
+set system conntrack modules pptp
+set system conntrack modules sip
+set system conntrack modules sqlnet
+set system conntrack modules tftp
+set system conntrack table-size '262144'
+set system conntrack timeout
+set system console device ttyS0 speed '115200'
+set system domain-name 'vyos.net'
+set system host-name 'vyos'
+set system login user vyos authentication encrypted-password '$6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/'
+set system login user vyos authentication plaintext-password ''
+set system name-server '172.16.254.30'
+set system syslog local facility all level 'debug'
+set system syslog local facility local7 level 'debug'
+set system syslog remote 172.16.100.1 facility all level 'warning'
diff --git a/smoketest/config-tests/firewall-bridged-global-options b/smoketest/config-tests/firewall-bridged-global-options
new file mode 100644
index 000000000..1d960d6c1
--- /dev/null
+++ b/smoketest/config-tests/firewall-bridged-global-options
@@ -0,0 +1,21 @@
+set firewall bridge prerouting filter rule 10 action 'accept'
+set firewall bridge prerouting filter rule 10 ethernet-type 'arp'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'dhcp'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'arp'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'pppoe-discovery'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'pppoe'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type '802.1q'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type '802.1ad'
+set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type 'wol'
+set firewall global-options state-policy established action 'accept'
+set firewall global-options state-policy invalid action 'drop'
+set firewall global-options state-policy related action 'accept'
+set interfaces ethernet eth0 duplex 'auto'
+set interfaces ethernet eth0 speed 'auto'
+set interfaces ethernet eth1 duplex 'auto'
+set interfaces ethernet eth1 speed 'auto'
+set system console device ttyS0 speed '115200'
+set system domain-name 'vyos-ci-test.net'
+set system host-name 'vyos'
+set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0'
+set system login user vyos authentication plaintext-password ''
diff --git a/smoketest/configs/basic-haproxy b/smoketest/configs/basic-haproxy
new file mode 100644
index 000000000..83fffbac6
--- /dev/null
+++ b/smoketest/configs/basic-haproxy
@@ -0,0 +1,153 @@
+interfaces {
+ dummy dum0 {
+ address "172.18.254.203/32"
+ }
+ ethernet eth0 {
+ duplex "auto"
+ speed "auto"
+ vif 203 {
+ address "172.18.203.10/24"
+ }
+ }
+ ethernet eth1 {
+ duplex "auto"
+ speed "auto"
+ }
+ ethernet eth2 {
+ duplex "auto"
+ speed "auto"
+ }
+}
+load-balancing {
+ reverse-proxy {
+ backend webserver {
+ logging {
+ facility all {
+ level "all"
+ }
+ facility daemon {
+ level "all"
+ }
+ facility user {
+ level "info"
+ }
+ }
+ server web01 {
+ address "192.0.2.1"
+ port "443"
+ }
+ ssl {
+ no-verify
+ }
+ }
+ global-parameters {
+ logging {
+ facility all {
+ level "all"
+ }
+ facility daemon {
+ level "all"
+ }
+ facility user {
+ level "info"
+ }
+ }
+ }
+ service frontend {
+ backend "webserver"
+ logging {
+ facility all {
+ level "all"
+ }
+ facility daemon {
+ level "all"
+ }
+ facility user {
+ level "info"
+ }
+ }
+ port "443"
+ ssl {
+ certificate "dummy"
+ }
+ }
+ }
+}
+pki {
+ certificate dummy {
+ certificate "MIIDsTCCApmgAwIBAgIUegVgO1wIN2v44trXZ+Kb1t48uL0wDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yNTA1MDUxODIzMTdaFw0yNjA1MDUxODIzMTdaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBSr4OYIWkb8UGuQnEFnjSbmvR+4vDAfBgNVHSMEGDAWgBSr4OYIWkb8UGuQnEFnjSbmvR+4vDANBgkqhkiG9w0BAQsFAAOCAQEAUmRWRPGXsvfuRT+53id3EufH1IJAdowrt6yBZsHobvqCXO2+YhG7oG6/UqUYiv5bHN5xEMQyWd7nyrLOUeFo2bpcMIOlpl6AoUIY65Gm2BqQ7FuPxLLO25RdpZ5WkMGX5kJsKY0/PcpamRKNz1khgFcRyxf9WGhCAIjDCWIWs8lkvPN3m75SFCW7MTuzzQOrzvI6nqqcHO4k8hRBznp26WLUW1rQKpNN09nZGOkeNYK5QbzKN/RUmtEHQZhlgLAIr09jUaA4RDLI1SdD6LR5nvpa9RJBTyS/kISF8BXKMgvUbDHN2nP+VUUrut2ZwoU+pxV4RVT2pS760HuYj4+sYQ=="
+ private {
+ key "MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDEfMAwYLKKVhGlUXr9gkVC7uBi+0O9yyEgd5QzPByePXYw0FrSLWmLRfQuByFDPIVANcEa3FgIXIAeKmxItw7IhFRsG5soSOXXgBxdAH/qzEbWhwzgafnxZKJkmrQr8YA3IFtkFPr2+5s26WdjtwEM0tzIFkq6hmWSX1axUgvYlF2uCxjututMZ6I5JCa0uR3gBRuNONuGPH3Ko9zUEATffv53j9DbYVEM0lfVNewefPoVJmWz+oT0wP/kNx6tREf+aUAF4m+eBsqnggITftW2fyeFnoBPCcPp3HUgSwZhesunqz+YeW6Pk+WWb5vl+2QbMKKtz5qK6dI3q0z9yp4FAgMBAAECgf9plqCMg2pKEWRFl183bqWAm7lnLnsUOfABFNPYa3U+uKQUKZpboTBfzDfZqNak3XNQV0mTAR8pFfoMhQjQU9hUxH7ivjw1RUCHjixCF0vLBkTB34gL7FUbiEIFhR1NW3pCJY73OXOkIZG1Obh6Syb8KubDeu4bTmb90/TnDDAs6OYXJ5yo7ZDZLvLu5a3Dli+H4K5Qb5VJ74o/vtodBo3wmKBgy2Ey6JqF+y7/3HeE66rVhYNft5pURgemWnNYqh3oDTJASqpA/8n90o8ceYPVJugQ7029UiyTp0xgBRXFszgiYPkBlsNWB+9+ospopOmYU0owBykH+RtD/bQ0mwECgYEA4gxPdYbHg/GLihHrkv0t5V0pSEhBeBeTBdWG+P/6K90vXofpp7qISdOeYMGkh8mY+PfZNHksdu67d2ks5on5/dNf5YXWCm+LMMRiSsfOo11NISNdNHS6afqs18Wq1aKawv/rwotfxrakM4Gar692+jgz/l/X+FdOQwmE6uEus8ECgYEA3oW4eGtzGq28TiqyhTHduTkas0ckPWX8ulasyPnLxBKDNNohbXXpFIJIcrnl24QFJw3MJbo+R+OxZHgzPK8r64gIGVa7vLCR2fiU/RFoUa1Jo1pPOqXXWqf/Mvdokm2p0atrjRUX9VhjoFsDLcqTgAmfSCsVSqGucX6ER7Gy60UCgYAvmhoNjNFtFquk6rsqHAjTOTgdUaH/0S8T1nBy9SzQmeaEyKhKuvxCV78NbxnfwnNlUoQ6CZ50eTefINXkwn+TlTSnl/SIBA9SuLheOQ9p1ZcNeG4DQuWStcg6NBUSoghnMg+Ky2Di7slLU2qovpGWhcllMve/A1umwFVuRPdZwQKBgHS7mYYyd/Oq6HnpFDWjbzlXp5Yc3/oFooruJT5ZLHfzbjkvpRGTJW7I2dC1jMuXekx+hHXWOg3keI7IL7jJ/DRW7Ei+o0XdKuY57Y7ErwEJ8vNq0N1nWo4IS2wlNgp61PdVAdrFEgh3EexxUj2XY8FrSs/FKio4nxaS1Dn4EnAxAoGBAKqLvuPpmCMVwlIu57WGxL5d9i7EjIGY65l6HTKQYoHCzE51rkowH1La2fuUYz0IpExq2lcrLbOUtSyhXH7Zlktiz//Gu/P90SUfR/ZGcLeZi+EDyK2OctpnWBjs2Dmfg4D6vxk39yV8AB97pYG073GcJ/P54qRUuEitbpJwH+fB"
+ }
+ }
+}
+service {
+ ntp {
+ allow-client {
+ address "0.0.0.0/0"
+ address "::/0"
+ }
+ server 172.16.100.10 {
+ }
+ server 172.16.100.20 {
+ }
+ server 172.16.110.30 {
+ }
+ }
+ ssh {
+ disable-host-validation
+ port "22"
+ }
+}
+system {
+ config-management {
+ commit-revisions "200"
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ conntrack {
+ modules {
+ ftp
+ h323
+ nfs
+ pptp
+ sip
+ sqlnet
+ tftp
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ name-server "172.16.254.30"
+ option {
+ kernel {
+ disable-mitigations
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level "info"
+ }
+ facility local7 {
+ level "debug"
+ }
+ }
+ }
+ time-zone "Europe/Berlin"
+}
+
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "bgp@5:broadcast-relay@1:cluster@2:config-management@1:conntrack@5:conntrack-sync@2:container@2:dhcp-relay@2:dhcp-server@8:dhcpv6-server@1:dns-dynamic@4:dns-forwarding@4:firewall@15:flow-accounting@1:https@6:ids@1:interfaces@32:ipoe-server@3:ipsec@13:isis@3:l2tp@9:lldp@2:mdns@1:monitoring@1:nat@8:nat66@3:ntp@3:openconnect@3:ospf@2:pim@1:policy@8:pppoe-server@10:pptp@5:qos@2:quagga@11:reverse-proxy@1:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@27:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2"
+// Release version: 1.4.1
diff --git a/smoketest/configs/basic-vyos b/smoketest/configs/basic-vyos
index a6cd3b6e1..5f7a71237 100644
--- a/smoketest/configs/basic-vyos
+++ b/smoketest/configs/basic-vyos
@@ -99,33 +99,77 @@ protocols {
}
service {
dhcp-server {
+ dynamic-dns-update {
+ send-updates enable
+ forward-domain domain.lan {
+ dns-server 1 {
+ address 192.168.0.1
+ }
+ dns-server 2 {
+ address 100.100.0.1
+ }
+ key-name domain-lan-updates
+ }
+ reverse-domain 0.168.192.in-addr.arpa {
+ dns-server 1 {
+ address 192.168.0.1
+ }
+ dns-server 2 {
+ address 100.100.0.1
+ }
+ key-name reverse-0-168-192
+ }
+ tsig-key domain-lan-updates {
+ algorithm sha256
+ secret SXQncyBXZWRuZXNkYXkgbWFoIGR1ZGVzIQ==
+ }
+ tsig-key reverse-0-168-192 {
+ algorithm sha256
+ secret VGhhbmsgR29kIGl0J3MgRnJpZGF5IQ==
+ }
+ conflict-resolution enable
+ }
shared-network-name LAN {
authoritative
+ dynamic-dns-update {
+ send-updates enable
+ ttl-percent 75
+ }
subnet 192.168.0.0/24 {
- default-router 192.168.0.1
- dns-server 192.168.0.1
- domain-name vyos.net
- domain-search vyos.net
+ dynamic-dns-update {
+ send-updates enable
+ generated-prefix myhost
+ qualifying-suffix lan1.domain.lan
+ }
+ option {
+ default-router 192.168.0.1
+ domain-name vyos.net
+ domain-search vyos.net
+ name-server 192.168.0.1
+ }
range LANDynamic {
start 192.168.0.30
stop 192.168.0.240
}
static-mapping TEST1-1 {
ip-address 192.168.0.11
- mac-address 00:01:02:03:04:05
+ mac 00:01:02:03:04:05
}
static-mapping TEST1-2 {
+ disable
ip-address 192.168.0.12
- mac-address 00:01:02:03:04:05
+ mac 00:01:02:03:04:05
}
static-mapping TEST2-1 {
ip-address 192.168.0.21
- mac-address 00:01:02:03:04:21
+ mac 00:01:02:03:04:21
}
static-mapping TEST2-2 {
+ disable
ip-address 192.168.0.21
- mac-address 00:01:02:03:04:22
+ mac 00:01:02:03:04:22
}
+ subnet-id 1
}
}
}
diff --git a/smoketest/configs/conntrack-basic b/smoketest/configs/conntrack-basic
new file mode 100644
index 000000000..8ecb78aeb
--- /dev/null
+++ b/smoketest/configs/conntrack-basic
@@ -0,0 +1,92 @@
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ speed auto
+ vif 5 {
+ address 192.0.2.1/24
+ }
+ }
+ ethernet eth1 {
+ vif 7 {
+ description FTTH-PPPoE
+ }
+ }
+}
+nat {
+ source {
+ rule 100 {
+ log
+ outbound-interface pppoe0
+ source {
+ address 192.0.2.0/24
+ }
+ translation {
+ address masquerade
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ conntrack {
+ expect-table-size 2048
+ hash-size 1023
+ table-size 262144
+ timeout {
+ icmp 30
+ other 600
+ udp {
+ other 300
+ stream 300
+ }
+ }
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ }
+ }
+ name-server 172.16.254.30
+ ntp {
+ allow-clients {
+ address 172.16.0.0/12
+ }
+ server 0.pool.ntp.org {
+ }
+ server 1.pool.ntp.org {
+ }
+ server 2.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level debug
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ host 172.16.100.1 {
+ facility all {
+ level warning
+ }
+ }
+ }
+}
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@6:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3-beta-202101091250
diff --git a/smoketest/configs/firewall-bridged-global-options b/smoketest/configs/firewall-bridged-global-options
new file mode 100644
index 000000000..a7e1428d8
--- /dev/null
+++ b/smoketest/configs/firewall-bridged-global-options
@@ -0,0 +1,60 @@
+firewall {
+ bridge {
+ prerouting {
+ filter {
+ rule 10 {
+ action "accept"
+ ethernet-type "arp"
+ }
+ }
+ }
+ }
+ global-options {
+ apply-to-bridged-traffic {
+ invalid-connections {
+ }
+ }
+ state-policy {
+ established {
+ action "accept"
+ }
+ invalid {
+ action "drop"
+ }
+ related {
+ action "accept"
+ }
+ }
+ }
+}
+interfaces {
+ ethernet eth0 {
+ duplex "auto"
+ speed "auto"
+ }
+ ethernet eth1 {
+ duplex auto
+ speed auto
+ }
+}
+system {
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos-ci-test.net
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+}
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "bgp@6:broadcast-relay@1:cluster@2:config-management@1:conntrack@6:conntrack-sync@2:container@2:dhcp-relay@2:dhcp-server@11:dhcpv6-server@6:dns-dynamic@4:dns-forwarding@4:firewall@18:flow-accounting@2:https@7:ids@2:interfaces@33:ipoe-server@4:ipsec@13:isis@3:l2tp@9:lldp@3:mdns@1:monitoring@2:nat@8:nat66@3:nhrp@1:ntp@3:openconnect@3:openvpn@4:ospf@2:pim@1:policy@9:pppoe-server@11:pptp@5:qos@3:quagga@12:reverse-proxy@3:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@29:vpp@1:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@4:webproxy@2"
+// Release version: 2025.06.17-0020-rolling
diff --git a/smoketest/scripts/cli/base_accel_ppp_test.py b/smoketest/scripts/cli/base_accel_ppp_test.py
index 750702e98..ddaed80ad 100644
--- a/smoketest/scripts/cli/base_accel_ppp_test.py
+++ b/smoketest/scripts/cli/base_accel_ppp_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 3e2653a2f..54547e62d 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -14,6 +14,7 @@
import re
+from json import loads
from netifaces import AF_INET
from netifaces import AF_INET6
from netifaces import ifaddresses
@@ -1067,6 +1068,7 @@ class BasicInterfaceTest:
dad_transmits = '10'
accept_dad = '0'
source_validation = 'strict'
+ interface_identifier = '::fffe'
for interface in self._interfaces:
path = self._base_path + [interface]
@@ -1089,6 +1091,9 @@ class BasicInterfaceTest:
if cli_defined(self._base_path + ['ipv6'], 'source-validation'):
self.cli_set(path + ['ipv6', 'source-validation', source_validation])
+ if cli_defined(self._base_path + ['ipv6', 'address'], 'interface-identifier'):
+ self.cli_set(path + ['ipv6', 'address', 'interface-identifier', interface_identifier])
+
self.cli_commit()
for interface in self._interfaces:
@@ -1120,6 +1125,13 @@ class BasicInterfaceTest:
self.assertIn('fib saddr . iif oif 0', line)
self.assertIn('drop', line)
+ if cli_defined(self._base_path + ['ipv6', 'address'], 'interface-identifier'):
+ tmp = cmd(f'ip -j token show dev {interface}')
+ tmp = loads(tmp)[0]
+ self.assertEqual(tmp['token'], interface_identifier)
+ self.assertEqual(tmp['ifname'], interface)
+
+
def test_dhcpv6_client_options(self):
if not self._test_ipv6_dhcpc6:
self.skipTest(MSG_TESTCASE_UNSUPPORTED)
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index f0674f187..526b24c46 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -152,12 +152,14 @@ class VyOSUnitTestSHIM:
return out
@staticmethod
- def ssh_send_cmd(command, username, password, hostname='localhost'):
+ def ssh_send_cmd(command, username, password, key_filename=None,
+ hostname='localhost'):
""" SSH command execution helper """
# Try to login via SSH
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- ssh_client.connect(hostname=hostname, username=username, password=password)
+ ssh_client.connect(hostname=hostname, username=username,
+ password=password, key_filename=key_filename)
_, stdout, stderr = ssh_client.exec_command(command)
output = stdout.read().decode().strip()
error = stderr.read().decode().strip()
diff --git a/smoketest/scripts/cli/test_backslash_escape.py b/smoketest/scripts/cli/test_backslash_escape.py
index e94e9ab0a..0fe71cdef 100755
--- a/smoketest/scripts/cli/test_backslash_escape.py
+++ b/smoketest/scripts/cli/test_backslash_escape.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_cgnat.py b/smoketest/scripts/cli/test_cgnat.py
index 02dad3de5..2cec401ae 100755
--- a/smoketest/scripts/cli/test_cgnat.py
+++ b/smoketest/scripts/cli/test_cgnat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_config_dependency.py b/smoketest/scripts/cli/test_config_dependency.py
index 99e807ac5..5cc62fbd1 100755
--- a/smoketest/scripts/cli/test_config_dependency.py
+++ b/smoketest/scripts/cli/test_config_dependency.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/smoketest/scripts/cli/test_configd_init.py b/smoketest/scripts/cli/test_configd_init.py
index 245c03824..aa6d18d39 100755
--- a/smoketest/scripts/cli/test_configd_init.py
+++ b/smoketest/scripts/cli/test_configd_init.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py
index 36622cad1..7590ed1cd 100755
--- a/smoketest/scripts/cli/test_container.py
+++ b/smoketest/scripts/cli/test_container.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -33,11 +33,13 @@ PROCESS_PIDFILE = '/run/vyos-container-{0}.service.pid'
busybox_image = 'busybox:stable'
busybox_image_path = '/usr/share/vyos/busybox-stable.tar'
+
def cmd_to_json(command):
c = cmd(command + ' --format=json')
data = json.loads(c)[0]
return data
+
class TestContainer(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
@@ -73,14 +75,27 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
cont_name = 'c1'
self.cli_set(['interfaces', 'ethernet', 'eth0', 'address', '10.0.2.15/24'])
- self.cli_set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop', '10.0.2.2'])
+ self.cli_set(
+ ['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop', '10.0.2.2']
+ )
self.cli_set(['system', 'name-server', '1.1.1.1'])
self.cli_set(['system', 'name-server', '8.8.8.8'])
self.cli_set(base_path + ['name', cont_name, 'image', busybox_image])
self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])
- self.cli_set(base_path + ['name', cont_name, 'sysctl', 'parameter', 'kernel.msgmax', 'value', '4096'])
-
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ cont_name,
+ 'sysctl',
+ 'parameter',
+ 'kernel.msgmax',
+ 'value',
+ '4096',
+ ]
+ )
+ self.cli_set(base_path + ['name', cont_name, 'log-driver', 'journald'])
# commit changes
self.cli_commit()
@@ -95,6 +110,10 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
tmp = cmd(f'sudo podman exec -it {cont_name} sysctl kernel.msgmax')
self.assertEqual(tmp, 'kernel.msgmax = 4096')
+ l = cmd_to_json(f'sudo podman container inspect {cont_name}')
+ self.assertEqual(l['HostConfig']['LogConfig']['Type'], 'journald')
+
+
def test_name_server(self):
cont_name = 'dns-test'
net_name = 'net-test'
@@ -105,7 +124,17 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['name', cont_name, 'image', busybox_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)])
+ 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):
@@ -146,7 +175,17 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(1, 6):
name = f'{base_name}-{ii}'
self.cli_set(base_path + ['name', name, 'image', busybox_image])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix).ip + ii)])
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix).ip + ii),
+ ]
+ )
# verify() - first IP address of a prefix can not be used by a container
with self.assertRaises(ConfigSessionError):
@@ -163,8 +202,14 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(2, 6):
name = f'{base_name}-{ii}'
c = cmd_to_json(f'sudo podman container inspect {name}')
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['Gateway'] , str(ip_interface(prefix).ip + 1))
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['IPAddress'], str(ip_interface(prefix).ip + ii))
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['Gateway'],
+ str(ip_interface(prefix).ip + 1),
+ )
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['IPAddress'],
+ str(ip_interface(prefix).ip + ii),
+ )
def test_ipv6_network(self):
prefix = '2001:db8::/64'
@@ -176,7 +221,17 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(1, 6):
name = f'{base_name}-{ii}'
self.cli_set(base_path + ['name', name, 'image', busybox_image])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix).ip + ii)])
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix).ip + ii),
+ ]
+ )
# verify() - first IP address of a prefix can not be used by a container
with self.assertRaises(ConfigSessionError):
@@ -193,8 +248,14 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(2, 6):
name = f'{base_name}-{ii}'
c = cmd_to_json(f'sudo podman container inspect {name}')
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['IPv6Gateway'] , str(ip_interface(prefix).ip + 1))
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['GlobalIPv6Address'], str(ip_interface(prefix).ip + ii))
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['IPv6Gateway'],
+ str(ip_interface(prefix).ip + 1),
+ )
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['GlobalIPv6Address'],
+ str(ip_interface(prefix).ip + ii),
+ )
def test_dual_stack_network(self):
prefix4 = '192.0.2.0/24'
@@ -208,8 +269,28 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(1, 6):
name = f'{base_name}-{ii}'
self.cli_set(base_path + ['name', name, 'image', busybox_image])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix4).ip + ii)])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix6).ip + ii)])
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix4).ip + ii),
+ ]
+ )
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix6).ip + ii),
+ ]
+ )
# verify() - first IP address of a prefix can not be used by a container
with self.assertRaises(ConfigSessionError):
@@ -227,10 +308,22 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
for ii in range(2, 6):
name = f'{base_name}-{ii}'
c = cmd_to_json(f'sudo podman container inspect {name}')
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['IPv6Gateway'] , str(ip_interface(prefix6).ip + 1))
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['GlobalIPv6Address'], str(ip_interface(prefix6).ip + ii))
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['Gateway'] , str(ip_interface(prefix4).ip + 1))
- self.assertEqual(c['NetworkSettings']['Networks'][net_name]['IPAddress'] , str(ip_interface(prefix4).ip + ii))
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['IPv6Gateway'],
+ str(ip_interface(prefix6).ip + 1),
+ )
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['GlobalIPv6Address'],
+ str(ip_interface(prefix6).ip + ii),
+ )
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['Gateway'],
+ str(ip_interface(prefix4).ip + 1),
+ )
+ self.assertEqual(
+ c['NetworkSettings']['Networks'][net_name]['IPAddress'],
+ str(ip_interface(prefix4).ip + ii),
+ )
def test_no_name_server(self):
prefix = '192.0.2.0/24'
@@ -242,7 +335,17 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
name = f'{base_name}-2'
self.cli_set(base_path + ['name', name, 'image', busybox_image])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix).ip + 2)])
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix).ip + 2),
+ ]
+ )
self.cli_commit()
n = cmd_to_json(f'sudo podman network inspect {net_name}')
@@ -258,7 +361,17 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
name = f'{base_name}-2'
self.cli_set(base_path + ['name', name, 'image', busybox_image])
- self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix).ip + 2)])
+ self.cli_set(
+ base_path
+ + [
+ 'name',
+ name,
+ 'network',
+ net_name,
+ 'address',
+ str(ip_interface(prefix).ip + 2),
+ ]
+ )
self.cli_commit()
n = cmd_to_json(f'sudo podman network inspect {net_name}')
@@ -298,11 +411,14 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Query API about running containers
- tmp = cmd("sudo curl --unix-socket /run/podman/podman.sock -H 'content-type: application/json' -sf http://localhost/containers/json")
+ tmp = cmd(
+ "sudo curl --unix-socket /run/podman/podman.sock -H 'content-type: application/json' -sf http://localhost/containers/json"
+ )
tmp = json.loads(tmp)
# We expect the same amount of containers from the API that we started above
self.assertEqual(len(container_list), len(tmp))
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 2829edbfb..24d30f89e 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -642,6 +642,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip6 vyos_filter')
def test_ipv4_global_state(self):
+ self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0'])
+ self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'software'])
+
+ self.cli_set(['firewall', 'global-options', 'state-policy', 'offload', 'offload-target', 'smoketest'])
self.cli_set(['firewall', 'global-options', 'state-policy', 'established', 'action', 'accept'])
self.cli_set(['firewall', 'global-options', 'state-policy', 'related', 'action', 'accept'])
self.cli_set(['firewall', 'global-options', 'state-policy', 'invalid', 'action', 'drop'])
@@ -651,6 +655,9 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['jump VYOS_STATE_POLICY'],
['chain VYOS_STATE_POLICY'],
+ ['jump VYOS_STATE_POLICY_FORWARD'],
+ ['chain VYOS_STATE_POLICY_FORWARD'],
+ ['flow add @VYOS_FLOWTABLE_smoketest'],
['ct state established', 'accept'],
['ct state invalid', 'drop'],
['ct state related', 'accept']
@@ -721,7 +728,13 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'group', 'ipv6-address-group', 'AGV6', 'address', '2001:db1::1'])
self.cli_set(['firewall', 'global-options', 'state-policy', 'established', 'action', 'accept'])
self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'ipv4'])
- self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'invalid-connections'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'dhcp'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'arp'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'pppoe'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'pppoe-discovery'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', '802.1q'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', '802.1ad'])
+ self.cli_set(['firewall', 'global-options', 'apply-to-bridged-traffic', 'accept-invalid', 'ethernet-type', 'wol'])
self.cli_set(['firewall', 'bridge', 'name', name, 'default-action', 'accept'])
self.cli_set(['firewall', 'bridge', 'name', name, 'default-log'])
@@ -776,7 +789,11 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['type filter hook output priority filter; policy accept;'],
['ct state invalid', 'udp sport 67', 'udp dport 68', 'accept'],
['ct state invalid', 'ether type arp', 'accept'],
+ ['ct state invalid', 'ether type 8021q', 'accept'],
+ ['ct state invalid', 'ether type 8021ad', 'accept'],
+ ['ct state invalid', 'ether type 0x8863', 'accept'],
['ct state invalid', 'ether type 0x8864', 'accept'],
+ ['ct state invalid', 'ether type 0x0842', 'accept'],
['chain VYOS_PREROUTING_filter'],
['type filter hook prerouting priority filter; policy accept;'],
['ip6 daddr @A6_AGV6', 'notrack'],
@@ -1106,6 +1123,12 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables_chain([['accept']], 'ip vyos_conntrack', 'FW_CONNTRACK')
self.verify_nftables_chain([['accept']], 'ip6 vyos_conntrack', 'FW_CONNTRACK')
+ # Test interface deletion
+ self.cli_delete(['interfaces', 'ethernet', 'eth0', 'vif', '10'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
def test_zone_flow_offload(self):
self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0'])
self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'hardware'])
@@ -1288,7 +1311,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['R_group01'],
['type ipv4_addr'],
['flags interval'],
- ['meta l4proto', 'daddr @R_group01', "ipv4-INP-filter-10"]
+ ['meta l4proto', 'daddr @R_group01', 'ipv4-INP-filter-10']
]
self.verify_nftables(nftables_search, 'ip vyos_filter')
@@ -1307,5 +1330,79 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_discard()
+ def test_ipv6_remote_group(self):
+ # Setup base config for test
+ self.cli_set(['firewall', 'group', 'remote-group', 'group01', 'url', 'http://127.0.0.1:80/list.txt'])
+ self.cli_set(['firewall', 'group', 'remote-group', 'group01', 'description', 'Example Group 01'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'destination', 'group', 'remote-group', 'group01'])
+
+ self.cli_commit()
+
+ # Test remote-group had been loaded correctly in nft
+ nftables_search = [
+ ['R6_group01'],
+ ['type ipv6_addr'],
+ ['flags interval'],
+ ['meta l4proto', 'daddr @R6_group01', 'ipv6-INP-filter-10']
+ ]
+ self.verify_nftables(nftables_search, 'ip6 vyos_filter')
+
+ # Test remote-group cannot be configured without a URL
+ self.cli_delete(['firewall', 'group', 'remote-group', 'group01', 'url'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_discard()
+
+ # Test remote-group cannot be set alongside address in rules
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'destination', 'address', '2001:db8::1'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_discard()
+
+
+ def test_remote_group(self):
+ # Setup base config for test adding remote group to both ipv4 and ipv6 rules
+ self.cli_set(['firewall', 'group', 'remote-group', 'group01', 'url', 'http://127.0.0.1:80/list.txt'])
+ self.cli_set(['firewall', 'group', 'remote-group', 'group01', 'description', 'Example Group 01'])
+ self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '10', 'destination', 'group', 'remote-group', 'group01'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'source', 'group', 'remote-group', 'group01'])
+ self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '10', 'destination', 'group', 'remote-group', 'group01'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '10', 'source', 'group', 'remote-group', 'group01'])
+
+ self.cli_commit()
+
+ # Test remote-group had been loaded correctly in nft ip table
+ nftables_v4_search = [
+ ['R_group01'],
+ ['type ipv4_addr'],
+ ['flags interval'],
+ ['meta l4proto', 'daddr @R_group01', 'ipv4-OUT-filter-10'],
+ ['meta l4proto', 'saddr @R_group01', 'ipv4-INP-filter-10'],
+ ]
+ self.verify_nftables(nftables_v4_search, 'ip vyos_filter')
+
+ # Test remote-group had been loaded correctly in nft ip6 table
+ nftables_v6_search = [
+ ['R6_group01'],
+ ['type ipv6_addr'],
+ ['flags interval'],
+ ['meta l4proto', 'daddr @R6_group01', 'ipv6-OUT-filter-10'],
+ ['meta l4proto', 'saddr @R6_group01', 'ipv6-INP-filter-10'],
+ ]
+ self.verify_nftables(nftables_v6_search, 'ip6 vyos_filter')
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_high-availability_virtual-server.py b/smoketest/scripts/cli/test_high-availability_virtual-server.py
index 2dbf4a5f2..70c400555 100755
--- a/smoketest/scripts/cli/test_high-availability_virtual-server.py
+++ b/smoketest/scripts/cli/test_high-availability_virtual-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_high-availability_vrrp.py b/smoketest/scripts/cli/test_high-availability_vrrp.py
index aa9fa432e..e76fe69f7 100755
--- a/smoketest/scripts/cli/test_high-availability_vrrp.py
+++ b/smoketest/scripts/cli/test_high-availability_vrrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index f99fd0363..2473bc732 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 4041b3ef3..8502e6b2d 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -508,6 +508,31 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_delete(['interfaces', 'vxlan', vxlan_if])
self.cli_delete(['interfaces', 'ethernet', 'eth0', 'address', eth0_addr])
+ def test_bridge_root_bpdu_guard(self):
+ # Test if both bpdu_guard and root_guard configured
+ self.cli_set(['interfaces', 'bridge', 'br0', 'stp'])
+ self.cli_set(['interfaces', 'bridge', 'br0', 'member', 'interface', 'eth0', 'bpdu-guard'])
+ self.cli_set(['interfaces', 'bridge', 'br0', 'member', 'interface', 'eth0', 'root-guard'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_discard()
+
+ # Test if bpdu_guard configured
+ self.cli_set(['interfaces', 'bridge', 'br0', 'stp'])
+ self.cli_set(['interfaces', 'bridge', 'br0', 'member', 'interface', 'eth0', 'bpdu-guard'])
+ self.cli_commit()
+
+ tmp = read_file(f'/sys/class/net/eth0/brport/bpdu_guard')
+ self.assertEqual(tmp, '1')
+
+ # Test if root_guard configured
+ self.cli_delete(['interfaces', 'bridge', 'br0'])
+ self.cli_set(['interfaces', 'bridge', 'br0', 'stp'])
+ self.cli_set(['interfaces', 'bridge', 'br0', 'member', 'interface', 'eth0', 'root-guard'])
+ self.cli_commit()
+
+ tmp = read_file(f'/sys/class/net/eth0/brport/root_block')
+ self.assertEqual(tmp, '1')
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_dummy.py b/smoketest/scripts/cli/test_interfaces_dummy.py
index d96ec2c5d..c9cc6124f 100755
--- a/smoketest/scripts/cli/test_interfaces_dummy.py
+++ b/smoketest/scripts/cli/test_interfaces_dummy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 2b421e942..780399159 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_geneve.py b/smoketest/scripts/cli/test_interfaces_geneve.py
index 5f8fae91e..bb3d7c00d 100755
--- a/smoketest/scripts/cli/test_interfaces_geneve.py
+++ b/smoketest/scripts/cli/test_interfaces_geneve.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_input.py b/smoketest/scripts/cli/test_interfaces_input.py
index 3ddf86000..611d2985b 100755
--- a/smoketest/scripts/cli/test_interfaces_input.py
+++ b/smoketest/scripts/cli/test_interfaces_input.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_l2tpv3.py b/smoketest/scripts/cli/test_interfaces_l2tpv3.py
index 28165736b..510be8938 100755
--- a/smoketest/scripts/cli/test_interfaces_l2tpv3.py
+++ b/smoketest/scripts/cli/test_interfaces_l2tpv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_loopback.py b/smoketest/scripts/cli/test_interfaces_loopback.py
index f4b6038c5..290cda64b 100755
--- a/smoketest/scripts/cli/test_interfaces_loopback.py
+++ b/smoketest/scripts/cli/test_interfaces_loopback.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py
index d73895b7f..6465f234c 100755
--- a/smoketest/scripts/cli/test_interfaces_macsec.py
+++ b/smoketest/scripts/cli/test_interfaces_macsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py
index e087b8735..ec17d71bf 100755
--- a/smoketest/scripts/cli/test_interfaces_openvpn.py
+++ b/smoketest/scripts/cli/test_interfaces_openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -826,7 +826,6 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
gw_subnet = "192.168.0.1"
self.cli_set(['interfaces', 'bridge', br_if, 'member', 'interface', vtun_if])
- self.cli_set(path + ['device-type', 'tap'])
self.cli_set(path + ['encryption', 'data-ciphers', 'aes192'])
self.cli_set(path + ['hash', auth_hash])
self.cli_set(path + ['mode', 'server'])
@@ -840,6 +839,10 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['tls', 'certificate', 'ovpn_test'])
self.cli_set(path + ['tls', 'dh-params', 'ovpn_test'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(path + ['device-type', 'tap'])
self.cli_commit()
config_file = f'/run/openvpn/{vtun_if}.conf'
diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py
index 2683a3122..dbc70ebd4 100755
--- a/smoketest/scripts/cli/test_interfaces_pppoe.py
+++ b/smoketest/scripts/cli/test_interfaces_pppoe.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_pseudo-ethernet.py b/smoketest/scripts/cli/test_interfaces_pseudo-ethernet.py
index 0d6f5bc1f..749c90420 100755
--- a/smoketest/scripts/cli/test_interfaces_pseudo-ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_pseudo-ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py
index dd9f1d2d1..43c98532a 100755
--- a/smoketest/scripts/cli/test_interfaces_tunnel.py
+++ b/smoketest/scripts/cli/test_interfaces_tunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_virtual-ethernet.py b/smoketest/scripts/cli/test_interfaces_virtual-ethernet.py
index b2af86139..82155dfa7 100755
--- a/smoketest/scripts/cli/test_interfaces_virtual-ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_virtual-ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_vti.py b/smoketest/scripts/cli/test_interfaces_vti.py
index 8d90ca5ad..067c1fb34 100755
--- a/smoketest/scripts/cli/test_interfaces_vti.py
+++ b/smoketest/scripts/cli/test_interfaces_vti.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py
index 694c24e4d..e7cbf6c0e 100755
--- a/smoketest/scripts/cli/test_interfaces_vxlan.py
+++ b/smoketest/scripts/cli/test_interfaces_vxlan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -125,19 +125,17 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
'source-interface eth0',
'vni 60'
]
- params = []
for option in options:
opts = option.split()
- params.append(opts[0])
- self.cli_set(self._base_path + [ intf ] + opts)
+ self.cli_set(self._base_path + [intf] + opts)
- with self.assertRaises(ConfigSessionError) as cm:
+ # verify() - Both group and remote cannot be specified
+ with self.assertRaises(ConfigSessionError):
self.cli_commit()
- exception = cm.exception
- self.assertIn('Both group and remote cannot be specified', str(exception))
- for param in params:
- self.cli_delete(self._base_path + [intf, param])
+ # Remove blocking CLI option
+ self.cli_delete(self._base_path + [intf, 'group'])
+ self.cli_commit()
def test_vxlan_external(self):
diff --git a/smoketest/scripts/cli/test_interfaces_wireguard.py b/smoketest/scripts/cli/test_interfaces_wireguard.py
index f8cd18cf2..55e3added 100755
--- a/smoketest/scripts/cli/test_interfaces_wireguard.py
+++ b/smoketest/scripts/cli/test_interfaces_wireguard.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -154,13 +154,15 @@ class WireGuardInterfaceTest(BasicInterfaceTest.TestCase):
tmp = read_file(f'/sys/class/net/{intf}/threaded')
self.assertTrue(tmp, "1")
- def test_wireguard_peer_pubkey_change(self):
+ def test_wireguard_peer_change(self):
# T5707 changing WireGuard CLI public key of a peer - it's not removed
+ # Also check if allowed-ips update
- def get_peers(interface) -> list:
+ def get_peers(interface) -> list[tuple]:
tmp = cmd(f'sudo wg show {interface} dump')
first_line = True
peers = []
+ allowed_ips = []
for line in tmp.split('\n'):
if not line:
continue # Skip empty lines and last line
@@ -170,24 +172,27 @@ class WireGuardInterfaceTest(BasicInterfaceTest.TestCase):
first_line = False
else:
peers.append(items[0])
- return peers
+ allowed_ips.append(items[3])
+ return peers, allowed_ips
interface = 'wg1337'
port = '1337'
privkey = 'iJi4lb2HhkLx2KSAGOjji2alKkYsJjSPkHkrcpxgEVU='
pubkey_1 = 'srQ8VF6z/LDjKCzpxBzFpmaNUOeuHYzIfc2dcmoc/h4='
pubkey_2 = '8pbMHiQ7NECVP7F65Mb2W8+4ldGG2oaGvDSpSEsOBn8='
+ allowed_ips_1 = '10.205.212.10/32'
+ allowed_ips_2 = '10.205.212.11/32'
self.cli_set(base_path + [interface, 'address', '172.16.0.1/24'])
self.cli_set(base_path + [interface, 'port', port])
self.cli_set(base_path + [interface, 'private-key', privkey])
self.cli_set(base_path + [interface, 'peer', 'VyOS', 'public-key', pubkey_1])
- self.cli_set(base_path + [interface, 'peer', 'VyOS', 'allowed-ips', '10.205.212.10/32'])
+ self.cli_set(base_path + [interface, 'peer', 'VyOS', 'allowed-ips', allowed_ips_1])
self.cli_commit()
- peers = get_peers(interface)
+ peers, _ = get_peers(interface)
self.assertIn(pubkey_1, peers)
self.assertNotIn(pubkey_2, peers)
@@ -196,10 +201,20 @@ class WireGuardInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
# Verify config
- peers = get_peers(interface)
+ peers, _ = get_peers(interface)
self.assertNotIn(pubkey_1, peers)
self.assertIn(pubkey_2, peers)
+ # Update allowed-ips
+ self.cli_delete(base_path + [interface, 'peer', 'VyOS', 'allowed-ips', allowed_ips_1])
+ self.cli_set(base_path + [interface, 'peer', 'VyOS', 'allowed-ips', allowed_ips_2])
+ self.cli_commit()
+
+ # Verify config
+ _, allowed_ips = get_peers(interface)
+ self.assertNotIn(allowed_ips_1, allowed_ips)
+ self.assertIn(allowed_ips_2, allowed_ips)
+
def test_wireguard_hostname(self):
# T4930: Test dynamic endpoint support
interface = 'wg1234'
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index 1c69c1be5..e00d96e35 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_load-balancing_haproxy.py b/smoketest/scripts/cli/test_load-balancing_haproxy.py
index 077f1974f..a63a3e7f1 100755
--- a/smoketest/scripts/cli/test_load-balancing_haproxy.py
+++ b/smoketest/scripts/cli/test_load-balancing_haproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
@@ -14,11 +14,14 @@
# 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 re
+import textwrap
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
+from vyos.template import get_default_port
from vyos.utils.process import process_named_running
from vyos.utils.file import read_file
@@ -131,7 +134,25 @@ ZXLrtgVJR9W020qTurO2f91qfU8646n11hR9ObBB1IYbagOU0Pw1Nrq/FRp/u2tx
7i7xFz2WEiQeSCPaKYOiqM3t
"""
+haproxy_service_name = 'https_front'
+haproxy_backend_name = 'bk-01'
+def parse_haproxy_config() -> dict:
+ config_str = read_file(HAPROXY_CONF)
+ section_pattern = re.compile(r'^(global|defaults|frontend\s+\S+|backend\s+\S+)', re.MULTILINE)
+ sections = {}
+
+ matches = list(section_pattern.finditer(config_str))
+
+ for i, match in enumerate(matches):
+ section_name = match.group(1).strip()
+ start = match.end()
+ end = matches[i + 1].start() if i + 1 < len(matches) else len(config_str)
+ section_body = config_str[start:end]
+ dedented_body = textwrap.dedent(section_body).strip()
+ sections[section_name] = dedented_body
+
+ return sections
class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
# Check for running process
@@ -146,14 +167,14 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertFalse(process_named_running(PROCESS_NAME))
def base_config(self):
- self.cli_set(base_path + ['service', 'https_front', 'mode', 'http'])
- self.cli_set(base_path + ['service', 'https_front', 'port', '4433'])
- self.cli_set(base_path + ['service', 'https_front', 'backend', 'bk-01'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'mode', 'http'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'port', '4433'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'backend', haproxy_backend_name])
- self.cli_set(base_path + ['backend', 'bk-01', 'mode', 'http'])
- self.cli_set(base_path + ['backend', 'bk-01', 'server', 'bk-01', 'address', '192.0.2.11'])
- self.cli_set(base_path + ['backend', 'bk-01', 'server', 'bk-01', 'port', '9090'])
- self.cli_set(base_path + ['backend', 'bk-01', 'server', 'bk-01', 'send-proxy'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'mode', 'http'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'server', haproxy_backend_name, 'address', '192.0.2.11'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'server', haproxy_backend_name, 'port', '9090'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'server', haproxy_backend_name, 'send-proxy'])
self.cli_set(base_path + ['global-parameters', 'max-connections', '1000'])
@@ -167,15 +188,15 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.cli_set(['pki', 'certificate', 'smoketest', 'certificate', valid_cert.replace('\n','')])
self.cli_set(['pki', 'certificate', 'smoketest', 'private', 'key', valid_cert_private_key.replace('\n','')])
- def test_01_lb_reverse_proxy_domain(self):
+ def test_reverse_proxy_domain(self):
domains_bk_first = ['n1.example.com', 'n2.example.com', 'n3.example.com']
domain_bk_second = 'n5.example.com'
- frontend = 'https_front'
+ frontend = 'vyos_smoketest'
front_port = '4433'
bk_server_first = '192.0.2.11'
bk_server_second = '192.0.2.12'
- bk_first_name = 'bk-01'
- bk_second_name = 'bk-02'
+ bk_first_name = 'vyosbk-01'
+ bk_second_name = 'vyosbk-02'
bk_server_port = '9090'
mode = 'http'
rule_ten = '10'
@@ -241,9 +262,9 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'server {bk_second_name} {bk_server_second}:{bk_server_port}', config)
self.assertIn(f'server {bk_second_name} {bk_server_second}:{bk_server_port} backup', config)
- def test_02_lb_reverse_proxy_cert_not_exists(self):
+ def test_reverse_proxy_cert_not_exists(self):
self.base_config()
- self.cli_set(base_path + ['service', 'https_front', 'ssl', 'certificate', 'cert'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'ssl', 'certificate', 'cert'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
@@ -253,19 +274,19 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.configure_pki()
self.base_config()
- self.cli_set(base_path + ['service', 'https_front', 'ssl', 'certificate', 'cert'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'ssl', 'certificate', 'cert'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
# self.assertIn('\nCertificate "cert" does not exist\n', str(e.exception))
- self.cli_delete(base_path + ['service', 'https_front', 'ssl', 'certificate', 'cert'])
- self.cli_set(base_path + ['service', 'https_front', 'ssl', 'certificate', 'smoketest'])
+ self.cli_delete(base_path + ['service', haproxy_service_name, 'ssl', 'certificate', 'cert'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'ssl', 'certificate', 'smoketest'])
self.cli_commit()
- def test_03_lb_reverse_proxy_ca_not_exists(self):
+ def test_reverse_proxy_ca_not_exists(self):
self.base_config()
- self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'ca-test'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'ssl', 'ca-certificate', 'ca-test'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
@@ -275,40 +296,40 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.configure_pki()
self.base_config()
- self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'ca-test'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'ssl', 'ca-certificate', 'ca-test'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
# self.assertIn('\nCA certificate "ca-test" does not exist\n', str(e.exception))
- self.cli_delete(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'ca-test'])
- self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'smoketest'])
+ self.cli_delete(base_path + ['backend', haproxy_backend_name, 'ssl', 'ca-certificate', 'ca-test'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'ssl', 'ca-certificate', 'smoketest'])
self.cli_commit()
- def test_04_lb_reverse_proxy_backend_ssl_no_verify(self):
+ def test_reverse_proxy_backend_ssl_no_verify(self):
# Setup base
self.configure_pki()
self.base_config()
# Set no-verify option
- self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'no-verify'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'ssl', 'no-verify'])
self.cli_commit()
# Test no-verify option
config = read_file(HAPROXY_CONF)
- self.assertIn('server bk-01 192.0.2.11:9090 send-proxy ssl verify none', config)
+ self.assertIn(f'server {haproxy_backend_name} 192.0.2.11:9090 send-proxy ssl verify none', config)
# Test setting ca-certificate alongside no-verify option fails, to test config validation
- self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'smoketest'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'ssl', 'ca-certificate', 'smoketest'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
- def test_05_lb_reverse_proxy_backend_http_check(self):
+ def test_reverse_proxy_backend_http_check(self):
# Setup base
self.base_config()
# Set http-check
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'method', 'get'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'http-check', 'method', 'get'])
self.cli_commit()
# Test http-check
@@ -317,8 +338,8 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('http-check send meth GET', config)
# Set http-check with uri and status
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'uri', '/health'])
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'http-check', 'uri', '/health'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'http-check', 'expect', 'status', '200'])
self.cli_commit()
# Test http-check with uri and status
@@ -328,8 +349,8 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('http-check expect status 200', config)
# Set http-check with string
- self.cli_delete(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'string', 'success'])
+ self.cli_delete(base_path + ['backend', haproxy_backend_name, 'http-check', 'expect', 'status', '200'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'http-check', 'expect', 'string', 'success'])
self.cli_commit()
# Test http-check with string
@@ -339,11 +360,11 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('http-check expect string success', config)
# Test configuring both http-check & health-check fails validation script
- self.cli_set(base_path + ['backend', 'bk-01', 'health-check', 'ldap'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'health-check', 'ldap'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
- def test_06_lb_reverse_proxy_tcp_mode(self):
+ def test_reverse_proxy_tcp_mode(self):
frontend = 'tcp_8443'
mode = 'tcp'
front_port = '8433'
@@ -390,27 +411,27 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'mode {mode}', config)
self.assertIn(f'server {bk_name} {bk_server}:{bk_server_port}', config)
- def test_07_lb_reverse_proxy_http_response_headers(self):
+ def test_reverse_proxy_http_response_headers(self):
# Setup base
self.configure_pki()
self.base_config()
# Set example headers in both frontend and backend
- self.cli_set(base_path + ['service', 'https_front', 'http-response-headers', 'Cache-Control', 'value', 'max-age=604800'])
- self.cli_set(base_path + ['backend', 'bk-01', 'http-response-headers', 'Proxy-Backend-ID', 'value', 'bk-01'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'http-response-headers', 'Cache-Control', 'value', 'max-age=604800'])
+ self.cli_set(base_path + ['backend', haproxy_backend_name, 'http-response-headers', 'Proxy-Backend-ID', 'value', haproxy_backend_name])
self.cli_commit()
# Test headers are present in generated configuration file
config = read_file(HAPROXY_CONF)
self.assertIn('http-response set-header Cache-Control \'max-age=604800\'', config)
- self.assertIn('http-response set-header Proxy-Backend-ID \'bk-01\'', config)
+ self.assertIn(f'http-response set-header Proxy-Backend-ID \'{haproxy_backend_name}\'', config)
# Test setting alongside modes other than http is blocked by validation conditions
- self.cli_set(base_path + ['service', 'https_front', 'mode', 'tcp'])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'mode', 'tcp'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
- def test_08_lb_reverse_proxy_tcp_health_checks(self):
+ def test_reverse_proxy_tcp_health_checks(self):
# Setup PKI
self.configure_pki()
@@ -458,7 +479,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
config = read_file(HAPROXY_CONF)
self.assertIn(f'option smtpchk', config)
- def test_09_lb_reverse_proxy_logging(self):
+ def test_reverse_proxy_logging(self):
# Setup base
self.base_config()
self.cli_commit()
@@ -477,7 +498,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('log /dev/log local2 warning', config)
# Test backend logging options
- backend_path = base_path + ['backend', 'bk-01']
+ backend_path = base_path + ['backend', haproxy_backend_name]
self.cli_set(backend_path + ['logging', 'facility', 'local3', 'level', 'debug'])
self.cli_set(backend_path + ['logging', 'facility', 'local4', 'level', 'info'])
self.cli_commit()
@@ -488,7 +509,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('log /dev/log local4 info', config)
# Test service logging options
- service_path = base_path + ['service', 'https_front']
+ service_path = base_path + ['service', haproxy_service_name]
self.cli_set(service_path + ['logging', 'facility', 'local5', 'level', 'notice'])
self.cli_set(service_path + ['logging', 'facility', 'local6', 'level', 'crit'])
self.cli_commit()
@@ -498,16 +519,17 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('log /dev/log local5 notice', config)
self.assertIn('log /dev/log local6 crit', config)
- def test_10_lb_reverse_proxy_http_compression(self):
+ def test_reverse_proxy_http_compression(self):
# Setup base
self.configure_pki()
self.base_config()
# Configure compression in frontend
- self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'algorithm', 'gzip'])
- self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/html'])
- self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/javascript'])
- self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/plain'])
+ http_comp_path = base_path + ['service', haproxy_service_name, 'http-compression']
+ self.cli_set(http_comp_path + ['algorithm', 'gzip'])
+ self.cli_set(http_comp_path + ['mime-type', 'text/html'])
+ self.cli_set(http_comp_path + ['mime-type', 'text/javascript'])
+ self.cli_set(http_comp_path + ['mime-type', 'text/plain'])
self.cli_commit()
# Test compression is present in generated configuration file
@@ -517,11 +539,11 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn('compression type text/html text/javascript text/plain', config)
# Test setting compression without specifying any mime-types fails verification
- self.cli_delete(base_path + ['service', 'https_front', 'http-compression', 'mime-type'])
+ self.cli_delete(base_path + ['service', haproxy_service_name, 'http-compression', 'mime-type'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()
- def test_11_lb_haproxy_timeout(self):
+ def test_reverse_proxy_timeout(self):
t_default_check = '5'
t_default_client = '50'
t_default_connect = '10'
@@ -551,7 +573,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['timeout', 'client', t_client])
self.cli_set(base_path + ['timeout', 'connect', t_connect])
self.cli_set(base_path + ['timeout', 'server', t_server])
- self.cli_set(base_path + ['service', 'https_front', 'timeout', 'client', t_front_client])
+ self.cli_set(base_path + ['service', haproxy_service_name, 'timeout', 'client', t_front_client])
self.cli_commit()
@@ -569,5 +591,25 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
for config_entry in config_entries:
self.assertIn(config_entry, config)
+ def test_reverse_proxy_http_redirect(self):
+ self.base_config()
+ self.cli_set(base_path + ['service', haproxy_service_name, 'redirect-http-to-https'])
+
+ self.cli_commit()
+
+ config = parse_haproxy_config()
+ frontend_name = f'frontend {haproxy_service_name}-http'
+ self.assertIn(frontend_name, config.keys())
+ self.assertIn('mode http', config[frontend_name])
+ self.assertIn('bind [::]:80 v4v6', config[frontend_name])
+ self.assertIn('acl acme_acl path_beg /.well-known/acme-challenge/', config[frontend_name])
+ self.assertIn('use_backend buildin_acme_certbot if acme_acl', config[frontend_name])
+ self.assertIn('redirect scheme https code 301 if !acme_acl', config[frontend_name])
+
+ backend_name = 'backend buildin_acme_certbot'
+ self.assertIn(backend_name, config.keys())
+ port = get_default_port('certbot_haproxy')
+ self.assertIn(f'server localhost 127.0.0.1:{port}', config[backend_name])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_load-balancing_wan.py b/smoketest/scripts/cli/test_load-balancing_wan.py
index 32e5f6915..88a6f0ad7 100755
--- a/smoketest/scripts/cli/test_load-balancing_wan.py
+++ b/smoketest/scripts/cli/test_load-balancing_wan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -171,8 +171,8 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase):
nat_wanloadbalance = """table ip vyos_wanloadbalance {
chain wlb_nat_postrouting {
type nat hook postrouting priority srcnat - 1; policy accept;
- ct mark 0x000000c9 counter snat to 203.0.113.10
- ct mark 0x000000ca counter snat to 192.0.2.10
+ ct mark 0x000000c9 oifname "veth1" counter snat to 203.0.113.10
+ ct mark 0x000000ca oifname "veth2" counter snat to 192.0.2.10
}
}"""
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index b33ef2617..a370f4779 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_nat64.py b/smoketest/scripts/cli/test_nat64.py
index 5c907f6cb..1c5f62874 100755
--- a/smoketest/scripts/cli/test_nat64.py
+++ b/smoketest/scripts/cli/test_nat64.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_nat66.py b/smoketest/scripts/cli/test_nat66.py
index 52ad8e3ef..bec023ca9 100755
--- a/smoketest/scripts/cli/test_nat66.py
+++ b/smoketest/scripts/cli/test_nat66.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -227,6 +227,35 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip6 vyos_nat')
+ def test_source_nat66_network_group(self):
+ address_group = 'smoketest_addr'
+ address_group_member = 'fc00::1'
+ network_group = 'smoketest_net'
+ network_group_member = 'fc00::/64'
+ translation_prefix = 'fc01::/64'
+
+ self.cli_set(['firewall', 'group', 'ipv6-address-group', address_group, 'address', address_group_member])
+ self.cli_set(['firewall', 'group', 'ipv6-network-group', network_group, 'network', network_group_member])
+
+ self.cli_set(src_path + ['rule', '1', 'destination', 'group', 'address-group', address_group])
+ self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_prefix])
+
+ self.cli_set(src_path + ['rule', '2', 'destination', 'group', 'network-group', network_group])
+ self.cli_set(src_path + ['rule', '2', 'translation', 'address', translation_prefix])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'set A6_{address_group}'],
+ [f'elements = {{ {address_group_member} }}'],
+ [f'set N6_{network_group}'],
+ [f'elements = {{ {network_group_member} }}'],
+ ['ip6 daddr', f'@A6_{address_group}', 'snat prefix to fc01::/64'],
+ ['ip6 daddr', f'@N6_{network_group}', 'snat prefix to fc01::/64']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip6 vyos_nat')
+
def test_nat66_no_rules(self):
# T3206: deleting all rules but keep the direction 'destination' or
# 'source' resulteds in KeyError: 'rule'.
diff --git a/smoketest/scripts/cli/test_netns.py b/smoketest/scripts/cli/test_netns.py
index 2ac603a69..9ed85ef7a 100755
--- a/smoketest/scripts/cli/test_netns.py
+++ b/smoketest/scripts/cli/test_netns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_op-mode_show.py b/smoketest/scripts/cli/test_op-mode_show.py
index 62f8e88da..10dbe0330 100755
--- a/smoketest/scripts/cli/test_op-mode_show.py
+++ b/smoketest/scripts/cli/test_op-mode_show.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_pki.py b/smoketest/scripts/cli/test_pki.py
index 02beafb26..a43d92b08 100755
--- a/smoketest/scripts/cli/test_pki.py
+++ b/smoketest/scripts/cli/test_pki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 985097726..8849ee182 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_policy_local-route.py b/smoketest/scripts/cli/test_policy_local-route.py
index a4239b8a1..5b3f84cc1 100644
--- a/smoketest/scripts/cli/test_policy_local-route.py
+++ b/smoketest/scripts/cli/test_policy_local-route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py
index 53761b7d6..5a0eb7f7c 100755
--- a/smoketest/scripts/cli/test_policy_route.py
+++ b/smoketest/scripts/cli/test_policy_route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -307,5 +307,39 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables6_search, 'ip6 vyos_mangle')
+ def test_geoip(self):
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'action', 'drop'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'se'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'gb'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'action', 'accept'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'de'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'fr'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'source', 'geoip', 'inverse-match'])
+
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'action', 'drop'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'source', 'geoip', 'country-code', 'se'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'source', 'geoip', 'country-code', 'gb'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'action', 'accept'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'source', 'geoip', 'country-code', 'de'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'source', 'geoip', 'country-code', 'fr'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'source', 'geoip', 'inverse-match'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['ip saddr @GEOIP_CC_route_smoketest_1', 'drop'],
+ ['ip saddr != @GEOIP_CC_route_smoketest_2', 'accept'],
+ ]
+
+ # -t prevents 1000+ GeoIP elements being returned
+ self.verify_nftables(nftables_search, 'ip vyos_mangle', args='-t')
+
+ nftables_search = [
+ ['ip6 saddr @GEOIP_CC6_route6_smoketest6_1', 'drop'],
+ ['ip6 saddr != @GEOIP_CC6_route6_smoketest6_2', 'accept'],
+ ]
+
+ self.verify_nftables(nftables_search, 'ip6 vyos_mangle', args='-t')
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_babel.py b/smoketest/scripts/cli/test_protocols_babel.py
index 3a9ee2d62..0032a5688 100755
--- a/smoketest/scripts/cli/test_protocols_babel.py
+++ b/smoketest/scripts/cli/test_protocols_babel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py
index 2205cd9de..59b0abfac 100755
--- a/smoketest/scripts/cli/test_protocols_bfd.py
+++ b/smoketest/scripts/cli/test_protocols_bfd.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 8403dcc37..be48e6aaa 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -358,6 +358,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['parameters', 'no-suppress-duplicates'])
self.cli_set(base_path + ['parameters', 'reject-as-sets'])
self.cli_set(base_path + ['parameters', 'route-reflector-allow-outbound-policy'])
+ self.cli_set(base_path + ['parameters', 'no-ipv6-auto-ra'])
self.cli_set(base_path + ['parameters', 'shutdown'])
self.cli_set(base_path + ['parameters', 'suppress-fib-pending'])
self.cli_set(base_path + ['parameters', 'tcp-keepalive', 'idle', tcp_keepalive_idle])
@@ -396,6 +397,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig)
self.assertIn(f' bgp reject-as-sets', frrconfig)
self.assertIn(f' bgp route-reflector allow-outbound-policy', frrconfig)
+ self.assertIn(f' no bgp ipv6-auto-ra', frrconfig)
self.assertIn(f' bgp shutdown', frrconfig)
self.assertIn(f' bgp suppress-fib-pending', frrconfig)
self.assertIn(f' bgp tcp-keepalive {tcp_keepalive_idle} {tcp_keepalive_interval} {tcp_keepalive_probes}', frrconfig)
diff --git a/smoketest/scripts/cli/test_protocols_igmp-proxy.py b/smoketest/scripts/cli/test_protocols_igmp-proxy.py
index df10442ea..c705132bb 100755
--- a/smoketest/scripts/cli/test_protocols_igmp-proxy.py
+++ b/smoketest/scripts/cli/test_protocols_igmp-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
index 14e833fd9..18f475fa9 100755
--- a/smoketest/scripts/cli/test_protocols_isis.py
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_mpls.py b/smoketest/scripts/cli/test_protocols_mpls.py
index 3840c24f4..a83a41df7 100755
--- a/smoketest/scripts/cli/test_protocols_mpls.py
+++ b/smoketest/scripts/cli/test_protocols_mpls.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_nhrp.py b/smoketest/scripts/cli/test_protocols_nhrp.py
index 73a760945..5f99cd92f 100755
--- a/smoketest/scripts/cli/test_protocols_nhrp.py
+++ b/smoketest/scripts/cli/test_protocols_nhrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_openfabric.py b/smoketest/scripts/cli/test_protocols_openfabric.py
index 323b6cd74..e44711993 100644
--- a/smoketest/scripts/cli/test_protocols_openfabric.py
+++ b/smoketest/scripts/cli/test_protocols_openfabric.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index ea55fa031..7a0f087e1 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -574,5 +574,23 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' network {network} area {area1}', frrconfig)
+ def test_ospf_18_area_translate_no_summary(self):
+ area = '11'
+ area_type = 'nssa'
+ network = '100.64.0.0/10'
+
+ self.cli_set(base_path + ['area', area, 'area-type', area_type, 'no-summary'])
+ self.cli_set(base_path + ['area', area, 'area-type', area_type, 'translate', 'never'])
+ self.cli_set(base_path + ['area', area, 'network', network])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' area {area} {area_type} translate-never no-summary', frrconfig)
+ self.assertIn(f' network {network} area {area}', frrconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index 5da4c7c98..484bd2acc 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_pim.py b/smoketest/scripts/cli/test_protocols_pim.py
index cc62769b3..f1c6053e7 100755
--- a/smoketest/scripts/cli/test_protocols_pim.py
+++ b/smoketest/scripts/cli/test_protocols_pim.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_pim6.py b/smoketest/scripts/cli/test_protocols_pim6.py
index 4ed8fcf7a..d10a3efc2 100755
--- a/smoketest/scripts/cli/test_protocols_pim6.py
+++ b/smoketest/scripts/cli/test_protocols_pim6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_rip.py b/smoketest/scripts/cli/test_protocols_rip.py
index 27b543803..67da2382c 100755
--- a/smoketest/scripts/cli/test_protocols_rip.py
+++ b/smoketest/scripts/cli/test_protocols_rip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py
index d2066b825..830c8bb3a 100755
--- a/smoketest/scripts/cli/test_protocols_ripng.py
+++ b/smoketest/scripts/cli/test_protocols_ripng.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
index 0addf7fee..50a157fd0 100755
--- a/smoketest/scripts/cli/test_protocols_rpki.py
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -25,6 +25,11 @@ from vyos.utils.file import read_file
from vyos.utils.process import process_named_running
base_path = ['protocols', 'rpki']
+base_frr_config_args = {'string': 'rpki', 'endsection': '^exit'}
+vrf = 'blue'
+vrf_path = ['vrf', 'name', vrf]
+vrf_frr_config_args = {'string': f'vrf {vrf}', 'endsection':'^exit-vrf',
+ 'substring': ' rpki', 'endsubsection': '^ exit'}
rpki_key_name = 'rpki-smoketest'
rpki_key_type = 'ssh-rsa'
@@ -112,14 +117,19 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
+ cls.cli_delete(cls, vrf_path)
# Enable CSTORE guard time required by FRR related tests
cls._commit_guard_time = CSTORE_GUARD_TIME
def tearDown(self):
self.cli_delete(base_path)
+ self.cli_delete(vrf_path)
self.cli_commit()
- frrconfig = self.getFRRconfig('rpki', endsection='^exit')
+ frrconfig = self.getFRRconfig(**base_frr_config_args)
+ self.assertNotIn(f'rpki', frrconfig)
+
+ frrconfig = self.getFRRconfig(**vrf_frr_config_args)
self.assertNotIn(f'rpki', frrconfig)
# check process health and continuity
@@ -144,27 +154,33 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
},
}
- self.cli_set(base_path + ['expire-interval', expire_interval])
- self.cli_set(base_path + ['polling-period', polling_period])
- self.cli_set(base_path + ['retry-interval', retry_interval])
+ for test_set in [ {'path': base_path, 'frrargs': base_frr_config_args},
+ {'path': vrf_path + base_path, 'frrargs': vrf_frr_config_args} ]:
- for peer, peer_config in cache.items():
- self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
- self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
+ if 'vrf' in test_set['path']:
+ self.cli_set(vrf_path + ['table', '1000'])
- # commit changes
- self.cli_commit()
+ self.cli_set(test_set['path'] + ['expire-interval', expire_interval])
+ self.cli_set(test_set['path'] + ['polling-period', polling_period])
+ self.cli_set(test_set['path'] + ['retry-interval', retry_interval])
+
+ for peer, peer_config in cache.items():
+ self.cli_set(test_set['path'] + ['cache', peer, 'port', peer_config['port']])
+ self.cli_set(test_set['path'] + ['cache', peer, 'preference', peer_config['preference']])
+
+ # commit changes
+ self.cli_commit()
- # Verify FRR configuration
- frrconfig = self.getFRRconfig('rpki', endsection='^exit')
- self.assertIn(f'rpki expire_interval {expire_interval}', frrconfig)
- self.assertIn(f'rpki polling_period {polling_period}', frrconfig)
- self.assertIn(f'rpki retry_interval {retry_interval}', frrconfig)
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(**test_set['frrargs'])
+ self.assertIn(f'rpki expire_interval {expire_interval}', frrconfig)
+ self.assertIn(f'rpki polling_period {polling_period}', frrconfig)
+ self.assertIn(f'rpki retry_interval {retry_interval}', frrconfig)
- for peer, peer_config in cache.items():
- port = peer_config['port']
- preference = peer_config['preference']
- self.assertIn(f'rpki cache tcp {peer} {port} preference {preference}', frrconfig)
+ for peer, peer_config in cache.items():
+ port = peer_config['port']
+ preference = peer_config['preference']
+ self.assertIn(f'rpki cache tcp {peer} {port} preference {preference}', frrconfig)
def test_rpki_ssh(self):
polling = '7200'
@@ -185,28 +201,34 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'key', rpki_ssh_pub.replace('\n','')])
self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'type', rpki_key_type])
- for cache_name, cache_config in cache.items():
- self.cli_set(base_path + ['cache', cache_name, 'port', cache_config['port']])
- self.cli_set(base_path + ['cache', cache_name, 'preference', cache_config['preference']])
- self.cli_set(base_path + ['cache', cache_name, 'ssh', 'username', cache_config['username']])
- self.cli_set(base_path + ['cache', cache_name, 'ssh', 'key', rpki_key_name])
+ for test_set in [ {'path': base_path, 'frrargs': base_frr_config_args},
+ {'path': vrf_path + base_path, 'frrargs': vrf_frr_config_args} ]:
- # commit changes
- self.cli_commit()
+ if 'vrf' in test_set['path']:
+ self.cli_set(vrf_path + ['table', '1000'])
+
+ for cache_name, cache_config in cache.items():
+ self.cli_set(test_set['path'] + ['cache', cache_name, 'port', cache_config['port']])
+ self.cli_set(test_set['path'] + ['cache', cache_name, 'preference', cache_config['preference']])
+ self.cli_set(test_set['path'] + ['cache', cache_name, 'ssh', 'username', cache_config['username']])
+ self.cli_set(test_set['path'] + ['cache', cache_name, 'ssh', 'key', rpki_key_name])
+
+ # commit changes
+ self.cli_commit()
- # Verify FRR configuration
- frrconfig = self.getFRRconfig('rpki', endsection='^exit')
- for cache_name, cache_config in cache.items():
- port = cache_config['port']
- preference = cache_config['preference']
- username = cache_config['username']
- self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(**test_set['frrargs'])
+ for cache_name, cache_config in cache.items():
+ port = cache_config['port']
+ preference = cache_config['preference']
+ username = cache_config['username']
+ self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
- # Verify content of SSH keys
- tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
- self.assertIn(rpki_ssh_key.replace('\n',''), tmp)
- tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
- self.assertIn(rpki_ssh_pub.replace('\n',''), tmp)
+ # Verify content of SSH keys
+ tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
+ self.assertIn(rpki_ssh_key.replace('\n',''), tmp)
+ tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
+ self.assertIn(rpki_ssh_pub.replace('\n',''), tmp)
# Change OpenSSH key and verify it was properly written to filesystem
self.cli_set(['pki', 'openssh', rpki_key_name, 'private', 'key', rpki_ssh_key_replacement.replace('\n','')])
@@ -214,17 +236,21 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
# commit changes
self.cli_commit()
- for cache_name, cache_config in cache.items():
- port = cache_config['port']
- preference = cache_config['preference']
- username = cache_config['username']
- self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
+ for test_set in [ {'path': base_path, 'frrargs': base_frr_config_args},
+ {'path': vrf_path + base_path, 'frrargs': vrf_frr_config_args} ]:
- # Verify content of SSH keys
- tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
- self.assertIn(rpki_ssh_key_replacement.replace('\n',''), tmp)
- tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
- self.assertIn(rpki_ssh_pub_replacement.replace('\n',''), tmp)
+ frrconfig = self.getFRRconfig(**test_set['frrargs'])
+ for cache_name, cache_config in cache.items():
+ port = cache_config['port']
+ preference = cache_config['preference']
+ username = cache_config['username']
+ self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
+
+ # Verify content of SSH keys
+ tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
+ self.assertIn(rpki_ssh_key_replacement.replace('\n',''), tmp)
+ tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
+ self.assertIn(rpki_ssh_pub_replacement.replace('\n',''), tmp)
self.cli_delete(['pki', 'openssh'])
@@ -240,13 +266,19 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
},
}
- for peer, peer_config in cache.items():
- self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
- self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
+ for test_set in [ {'path': base_path, 'frrargs': base_frr_config_args},
+ {'path': vrf_path + base_path, 'frrargs': vrf_frr_config_args} ]:
- # check validate() - preferences must be unique
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
+ if 'vrf' in test_set['path']:
+ self.cli_set(vrf_path + ['table', '1000'])
+
+ for peer, peer_config in cache.items():
+ self.cli_set(test_set['path'] + ['cache', peer, 'port', peer_config['port']])
+ self.cli_set(test_set['path'] + ['cache', peer, 'preference', peer_config['preference']])
+
+ # check validate() - preferences must be unique
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
def test_rpki_source_address(self):
peer = '192.0.2.1'
@@ -257,31 +289,38 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
self.cli_set(['interfaces', 'ethernet', 'eth0', 'address', f'{source_address}/24'])
- # Configure a TCP cache server
- self.cli_set(base_path + ['cache', peer, 'port', port])
- self.cli_set(base_path + ['cache', peer, 'preference', preference])
- self.cli_set(base_path + ['cache', peer, 'source-address', source_address])
- self.cli_commit()
- # Verify FRR configuration
- frrconfig = self.getFRRconfig('rpki')
- self.assertIn(f'rpki cache tcp {peer} {port} source {source_address} preference {preference}', frrconfig)
+ for test_set in [ {'path': base_path, 'frrargs': base_frr_config_args},
+ {'path': vrf_path + base_path, 'frrargs': vrf_frr_config_args} ]:
- self.cli_set(['pki', 'openssh', rpki_key_name, 'private', 'key', rpki_ssh_key.replace('\n', '')])
- self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'key', rpki_ssh_pub.replace('\n', '')])
- self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'type', rpki_key_type])
+ if 'vrf' in test_set['path']:
+ self.cli_set(vrf_path + ['table', '1000'])
- # Configure a SSH cache server
- self.cli_set(base_path + ['cache', peer, 'ssh', 'username', username])
- self.cli_set(base_path + ['cache', peer, 'ssh', 'key', rpki_key_name])
- self.cli_commit()
+ # Configure a TCP cache server
+ self.cli_set(test_set['path'] + ['cache', peer, 'port', port])
+ self.cli_set(test_set['path'] + ['cache', peer, 'preference', preference])
+ self.cli_set(test_set['path'] + ['cache', peer, 'source-address', source_address])
+ self.cli_commit()
+
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(**test_set['frrargs'])
+ self.assertIn(f'rpki cache tcp {peer} {port} source {source_address} preference {preference}', frrconfig)
+
+ self.cli_set(['pki', 'openssh', rpki_key_name, 'private', 'key', rpki_ssh_key.replace('\n', '')])
+ self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'key', rpki_ssh_pub.replace('\n', '')])
+ self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'type', rpki_key_type])
+
+ # Configure a SSH cache server
+ self.cli_set(test_set['path'] + ['cache', peer, 'ssh', 'username', username])
+ self.cli_set(test_set['path'] + ['cache', peer, 'ssh', 'key', rpki_key_name])
+ self.cli_commit()
- # Verify FRR configuration
- frrconfig = self.getFRRconfig('rpki')
- self.assertIn(
- f'rpki cache ssh {peer} {port} {username} /run/frr/id_rpki_{peer} /run/frr/id_rpki_{peer}.pub source {source_address} preference {preference}',
- frrconfig,
- )
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(**test_set['frrargs'])
+ self.assertIn(
+ f'rpki cache ssh {peer} {port} {username} /run/frr/id_rpki_{peer} /run/frr/id_rpki_{peer}.pub source {source_address} preference {preference}',
+ frrconfig,
+ )
if __name__ == '__main__':
diff --git a/smoketest/scripts/cli/test_protocols_segment-routing.py b/smoketest/scripts/cli/test_protocols_segment-routing.py
index 94c808733..94e769bb1 100755
--- a/smoketest/scripts/cli/test_protocols_segment-routing.py
+++ b/smoketest/scripts/cli/test_protocols_segment-routing.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py
index 79d6b3af4..66fb880c5 100755
--- a/smoketest/scripts/cli/test_protocols_static.py
+++ b/smoketest/scripts/cli/test_protocols_static.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_protocols_static_arp.py b/smoketest/scripts/cli/test_protocols_static_arp.py
index 7f8047249..c0d62ecb5 100755
--- a/smoketest/scripts/cli/test_protocols_static_arp.py
+++ b/smoketest/scripts/cli/test_protocols_static_arp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_qos.py b/smoketest/scripts/cli/test_qos.py
index 231743344..03160ec7e 100755
--- a/smoketest/scripts/cli/test_qos.py
+++ b/smoketest/scripts/cli/test_qos.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
@@ -355,10 +355,10 @@ class TestQoS(VyOSUnitTestSHIM.TestCase):
tc_details = get_tc_filter_details(interface, 'ingress')
self.assertTrue('filter parent ffff: protocol all pref 20 u32 chain 0' in tc_details)
- self.assertTrue('rate 1Gbit burst 15125b mtu 2Kb action drop overhead 0b linklayer ethernet' in tc_details)
+ self.assertTrue('rate 1Gbit burst 15Kb mtu 2Kb action drop overhead 0b linklayer ethernet' in tc_details)
self.assertTrue('filter parent ffff: protocol all pref 15 u32 chain 0' in tc_details)
- self.assertTrue('rate 3Gbit burst 102000b mtu 1600b action pipe/continue overhead 0b linklayer ethernet' in tc_details)
- self.assertTrue('rate 500Mbit burst 204687b mtu 3000b action drop overhead 0b linklayer ethernet' in tc_details)
+ self.assertTrue('rate 3Gbit burst 100Kb mtu 1600b action pipe/continue overhead 0b linklayer ethernet' in tc_details)
+ self.assertTrue('rate 500Mbit burst 200Kb mtu 3000b action drop overhead 0b linklayer ethernet' in tc_details)
self.assertTrue('filter parent ffff: protocol all pref 255 basic chain 0' in tc_details)
def test_06_network_emulator(self):
@@ -773,7 +773,7 @@ class TestQoS(VyOSUnitTestSHIM.TestCase):
tc_filters = cmd(f'tc filter show dev {self._interfaces[0]} ingress')
# class 100
self.assertIn('filter parent ffff: protocol all pref 20 fw chain 0', tc_filters)
- self.assertIn('action order 1: police 0x1 rate 20Gbit burst 3847500b mtu 2Kb action drop overhead 0b', tc_filters)
+ self.assertIn('action order 1: police 0x1 rate 20Gbit burst 3760Kb mtu 2Kb action drop overhead 0b', tc_filters)
# default
self.assertIn('filter parent ffff: protocol all pref 255 basic chain 0', tc_filters)
self.assertIn('action order 1: police 0x2 rate 1Gbit burst 125000000b mtu 2Kb action drop overhead 0b', tc_filters)
@@ -884,6 +884,8 @@ class TestQoS(VyOSUnitTestSHIM.TestCase):
base_path + ['policy', 'cake', policy_name, 'bandwidth', str(bandwidth)]
)
self.cli_set(base_path + ['policy', 'cake', policy_name, 'rtt', str(rtt)])
+ self.cli_set(base_path + ['policy', 'cake', policy_name, 'no-split-gso'])
+ self.cli_set(base_path + ['policy', 'cake', policy_name, 'ack-filter', 'aggressive'])
# commit changes
self.cli_commit()
@@ -899,6 +901,23 @@ class TestQoS(VyOSUnitTestSHIM.TestCase):
self.assertFalse(tmp['options']['ingress'])
self.assertFalse(tmp['options']['nat'])
self.assertTrue(tmp['options']['raw'])
+ self.assertFalse(tmp['options']['split_gso'])
+ self.assertEqual(tmp['options']['ack-filter'], 'aggressive')
+
+ self.cli_delete(base_path + ['policy', 'cake', policy_name, 'ack-filter', 'aggressive'])
+ self.cli_commit()
+ tmp = get_tc_qdisc_json(interface)
+ self.assertEqual(tmp['options']['ack-filter'], 'enabled')
+
+ self.cli_delete(base_path + ['policy', 'cake', policy_name, 'ack-filter'])
+ self.cli_commit()
+ tmp = get_tc_qdisc_json(interface)
+ self.assertEqual(tmp['options']['ack-filter'], 'disabled')
+
+ self.cli_delete(base_path + ['policy', 'cake', policy_name, 'no-split-gso'])
+ self.cli_commit()
+ tmp = get_tc_qdisc_json(interface)
+ self.assertTrue(tmp['options']['split_gso'])
nat = True
for flow_isolation in [
@@ -1232,7 +1251,7 @@ class TestQoS(VyOSUnitTestSHIM.TestCase):
# class 100
self.assertIn('filter parent ffff: protocol all pref 20 basic chain 0', tc_filters)
self.assertIn(f'meta(rt_iif eq {iif})', tc_filters)
- self.assertIn('action order 1: police 0x1 rate 20Gbit burst 3847500b mtu 2Kb action drop overhead 0b', tc_filters)
+ self.assertIn('action order 1: police 0x1 rate 20Gbit burst 3760Kb mtu 2Kb action drop overhead 0b', tc_filters)
# default
self.assertIn('filter parent ffff: protocol all pref 255 basic chain 0', tc_filters)
self.assertIn('action order 1: police 0x2 rate 1Gbit burst 125000000b mtu 2Kb action drop overhead 0b', tc_filters)
diff --git a/smoketest/scripts/cli/test_service_broadcast-relay.py b/smoketest/scripts/cli/test_service_broadcast-relay.py
index 87901869e..7f877869a 100755
--- a/smoketest/scripts/cli/test_service_broadcast-relay.py
+++ b/smoketest/scripts/cli/test_service_broadcast-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_dhcp-relay.py b/smoketest/scripts/cli/test_service_dhcp-relay.py
index 59c4b59a9..6d4e79817 100755
--- a/smoketest/scripts/cli/test_service_dhcp-relay.py
+++ b/smoketest/scripts/cli/test_service_dhcp-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py
index 7bb850b22..dcd6a5720 100755
--- a/smoketest/scripts/cli/test_service_dhcp-server.py
+++ b/smoketest/scripts/cli/test_service_dhcp-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -32,8 +32,10 @@ from vyos.template import inc_ip
from vyos.template import dec_ip
PROCESS_NAME = 'kea-dhcp4'
+D2_PROCESS_NAME = 'kea-dhcp-ddns'
CTRL_PROCESS_NAME = 'kea-ctrl-agent'
KEA4_CONF = '/run/kea/kea-dhcp4.conf'
+KEA4_D2_CONF = '/run/kea/kea-dhcp-ddns.conf'
KEA4_CTRL = '/run/kea/dhcp4-ctrl-socket'
HOSTSD_CLIENT = '/usr/bin/vyos-hostsd-client'
base_path = ['service', 'dhcp-server']
@@ -96,6 +98,10 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
self.assertTrue(key in base_obj)
self.assertEqual(base_obj[key], value)
+ def verify_service_running(self):
+ tmp = cmd('tail -n 100 /var/log/messages | grep kea')
+ self.assertTrue(process_named_running(PROCESS_NAME), msg=f'Service not running, log: {tmp}')
+
def test_dhcp_single_pool_range(self):
shared_net_name = 'SMOKE-1'
@@ -106,9 +112,12 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['listen-interface', interface])
+ self.cli_set(base_path + ['shared-network-name', shared_net_name, 'ping-check'])
+
pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
self.cli_set(pool + ['subnet-id', '1'])
self.cli_set(pool + ['ignore-client-id'])
+ self.cli_set(pool + ['ping-check'])
# we use the first subnet IP address as default gateway
self.cli_set(pool + ['option', 'default-router', router])
self.cli_set(pool + ['option', 'name-server', dns_1])
@@ -151,6 +160,21 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'max-valid-lifetime', 86400
)
+ # Verify ping-check
+ self.verify_config_value(
+ obj,
+ ['Dhcp4', 'shared-networks', 0, 'user-context'],
+ 'enable-ping-check',
+ True
+ )
+
+ self.verify_config_value(
+ obj,
+ ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'user-context'],
+ 'enable-ping-check',
+ True
+ )
+
# Verify options
self.verify_config_object(
obj,
@@ -181,7 +205,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_single_pool_options(self):
shared_net_name = 'SMOKE-0815'
@@ -221,8 +245,11 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
pool + ['option', 'capwap-controller', capwap_access_controller]
)
+ static_route = '10.0.0.0/24'
+ static_route_nexthop = '192.0.2.1'
+
self.cli_set(
- pool + ['option', 'static-route', '10.0.0.0/24', 'next-hop', '192.0.2.1']
+ pool + ['option', 'static-route', static_route, 'next-hop', static_route_nexthop]
)
self.cli_set(pool + ['option', 'ipv6-only-preferred', ipv6_only_preferred])
self.cli_set(pool + ['option', 'time-zone', 'Europe/London'])
@@ -321,18 +348,13 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
obj,
['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'option-data'],
{
- 'name': 'rfc3442-static-route',
- 'data': '24,10,0,0,192,0,2,1, 0,192,0,2,1',
+ 'name': 'classless-static-route',
+ 'data': f'{static_route} - {static_route_nexthop}, 0.0.0.0/0 - {router}',
},
)
self.verify_config_object(
obj,
['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'option-data'],
- {'name': 'windows-static-route', 'data': '24,10,0,0,192,0,2,1'},
- )
- self.verify_config_object(
- obj,
- ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'option-data'],
{'name': 'v6-only-preferred', 'data': ipv6_only_preferred},
)
self.verify_config_object(
@@ -361,7 +383,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_single_pool_options_scoped(self):
shared_net_name = 'SMOKE-2'
@@ -447,7 +469,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_single_pool_static_mapping(self):
shared_net_name = 'SMOKE-2'
@@ -593,7 +615,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
client_base += 1
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_multiple_pools(self):
lease_time = '14400'
@@ -735,7 +757,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
client_base += 1
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_exclude_not_in_range(self):
# T3180: verify else path when slicing DHCP ranges and exclude address
@@ -782,7 +804,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_exclude_in_range(self):
# T3180: verify else path when slicing DHCP ranges and exclude address
@@ -845,7 +867,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_relay_server(self):
# Listen on specific address and return DHCP leases from a non
@@ -893,7 +915,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_high_availability(self):
shared_net_name = 'FAILOVER'
@@ -996,8 +1018,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
- self.assertTrue(process_named_running(CTRL_PROCESS_NAME))
+ self.verify_service_running()
def test_dhcp_high_availability_standby(self):
shared_net_name = 'FAILOVER'
@@ -1096,8 +1117,134 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
+ self.verify_service_running()
+
+ def test_dhcp_dynamic_dns_update(self):
+ shared_net_name = 'SMOKE-1DDNS'
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+
+ self.cli_set(base_path + ['listen-interface', interface])
+
+ ddns = base_path + ['dynamic-dns-update']
+
+ self.cli_set(ddns + ['send-updates', 'enable'])
+ self.cli_set(ddns + ['conflict-resolution', 'enable'])
+ self.cli_set(ddns + ['override-no-update', 'enable'])
+ self.cli_set(ddns + ['override-client-update', 'enable'])
+ self.cli_set(ddns + ['replace-client-name', 'always'])
+ self.cli_set(ddns + ['update-on-renew', 'enable'])
+
+ self.cli_set(ddns + ['tsig-key', 'domain-lan-updates', 'algorithm', 'sha256'])
+ self.cli_set(ddns + ['tsig-key', 'domain-lan-updates', 'secret', 'SXQncyBXZWRuZXNkYXkgbWFoIGR1ZGVzIQ=='])
+ self.cli_set(ddns + ['tsig-key', 'reverse-0-168-192', 'algorithm', 'sha256'])
+ self.cli_set(ddns + ['tsig-key', 'reverse-0-168-192', 'secret', 'VGhhbmsgR29kIGl0J3MgRnJpZGF5IQ=='])
+ self.cli_set(ddns + ['forward-domain', 'domain.lan', 'dns-server', '1', 'address', '192.168.0.1'])
+ self.cli_set(ddns + ['forward-domain', 'domain.lan', 'dns-server', '2', 'address', '100.100.0.1'])
+ self.cli_set(ddns + ['forward-domain', 'domain.lan', 'key-name', 'domain-lan-updates'])
+ self.cli_set(ddns + ['reverse-domain', '0.168.192.in-addr.arpa', 'dns-server', '1', 'address', '192.168.0.1'])
+ self.cli_set(ddns + ['reverse-domain', '0.168.192.in-addr.arpa', 'dns-server', '1', 'port', '1053'])
+ self.cli_set(ddns + ['reverse-domain', '0.168.192.in-addr.arpa', 'dns-server', '2', 'address', '100.100.0.1'])
+ self.cli_set(ddns + ['reverse-domain', '0.168.192.in-addr.arpa', 'dns-server', '2', 'port', '1153'])
+ self.cli_set(ddns + ['reverse-domain', '0.168.192.in-addr.arpa', 'key-name', 'reverse-0-168-192'])
+
+ shared = base_path + ['shared-network-name', shared_net_name]
+
+ self.cli_set(shared + ['dynamic-dns-update', 'send-updates', 'enable'])
+ self.cli_set(shared + ['dynamic-dns-update', 'conflict-resolution', 'enable'])
+ self.cli_set(shared + ['dynamic-dns-update', 'ttl-percent', '75'])
+
+ pool = shared + [ 'subnet', subnet]
+
+ self.cli_set(pool + ['subnet-id', '1'])
+
+ self.cli_set(pool + ['range', '0', 'start', range_0_start])
+ self.cli_set(pool + ['range', '0', 'stop', range_0_stop])
+
+ self.cli_set(pool + ['dynamic-dns-update', 'send-updates', 'enable'])
+ self.cli_set(pool + ['dynamic-dns-update', 'generated-prefix', 'myfunnyprefix'])
+ self.cli_set(pool + ['dynamic-dns-update', 'qualifying-suffix', 'suffix.lan'])
+ self.cli_set(pool + ['dynamic-dns-update', 'hostname-char-set', 'xXyYzZ'])
+ self.cli_set(pool + ['dynamic-dns-update', 'hostname-char-replacement', '_xXx_'])
+
+ self.cli_commit()
+
+ config = read_file(KEA4_CONF)
+ d2_config = read_file(KEA4_D2_CONF)
+
+ obj = loads(config)
+ d2_obj = loads(d2_config)
+
+ # Verify global DDNS parameters in the main config file
+ self.verify_config_value(
+ obj,
+ ['Dhcp4'], 'dhcp-ddns',
+ {'enable-updates': True, 'server-ip': '127.0.0.1', 'server-port': 53001, 'sender-ip': '', 'sender-port': 0,
+ 'max-queue-size': 1024, 'ncr-protocol': 'UDP', 'ncr-format': 'JSON'})
+
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-send-updates', True)
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-use-conflict-resolution', True)
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-override-no-update', True)
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-override-client-update', True)
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-replace-client-name', 'always')
+ self.verify_config_value(obj, ['Dhcp4'], 'ddns-update-on-renew', True)
+
+ # Verify scoped DDNS parameters in the main config file
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'name', shared_net_name)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'ddns-send-updates', True)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'ddns-use-conflict-resolution', True)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'ddns-ttl-percent', 0.75)
+
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'subnet', subnet)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'id', 1)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'ddns-send-updates', True)
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'ddns-generated-prefix', 'myfunnyprefix')
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'ddns-qualifying-suffix', 'suffix.lan')
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'hostname-char-set', 'xXyYzZ')
+ self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'hostname-char-replacement', '_xXx_')
+
+ # Verify keys and domains configuration in the D2 config
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'tsig-keys'],
+ {'name': 'domain-lan-updates', 'algorithm': 'HMAC-SHA256', 'secret': 'SXQncyBXZWRuZXNkYXkgbWFoIGR1ZGVzIQ=='}
+ )
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'tsig-keys'],
+ {'name': 'reverse-0-168-192', 'algorithm': 'HMAC-SHA256', 'secret': 'VGhhbmsgR29kIGl0J3MgRnJpZGF5IQ=='}
+ )
+
+ self.verify_config_value(d2_obj, ['DhcpDdns', 'forward-ddns', 'ddns-domains', 0], 'name', 'domain.lan')
+ self.verify_config_value(d2_obj, ['DhcpDdns', 'forward-ddns', 'ddns-domains', 0], 'key-name', 'domain-lan-updates')
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'forward-ddns', 'ddns-domains', 0, 'dns-servers'],
+ {'ip-address': '192.168.0.1'}
+ )
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'forward-ddns', 'ddns-domains', 0, 'dns-servers'],
+ {'ip-address': '100.100.0.1'}
+ )
+
+ self.verify_config_value(d2_obj, ['DhcpDdns', 'reverse-ddns', 'ddns-domains', 0], 'name', '0.168.192.in-addr.arpa')
+ self.verify_config_value(d2_obj, ['DhcpDdns', 'reverse-ddns', 'ddns-domains', 0], 'key-name', 'reverse-0-168-192')
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'reverse-ddns', 'ddns-domains', 0, 'dns-servers'],
+ {'ip-address': '192.168.0.1', 'port': 1053}
+ )
+ self.verify_config_object(
+ d2_obj,
+ ['DhcpDdns', 'reverse-ddns', 'ddns-domains', 0, 'dns-servers'],
+ {'ip-address': '100.100.0.1', 'port': 1153}
+ )
+
+ # Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
- self.assertTrue(process_named_running(CTRL_PROCESS_NAME))
+ self.assertTrue(process_named_running(D2_PROCESS_NAME))
def test_dhcp_on_interface_with_vrf(self):
self.cli_set(['interfaces', 'ethernet', 'eth1', 'address', '10.1.1.1/30'])
@@ -1259,7 +1406,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
)
# Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.verify_service_running()
# All up and running, now test vyos-hostsd store
diff --git a/smoketest/scripts/cli/test_service_dhcpv6-relay.py b/smoketest/scripts/cli/test_service_dhcpv6-relay.py
index e634a011f..da826615d 100755
--- a/smoketest/scripts/cli/test_service_dhcpv6-relay.py
+++ b/smoketest/scripts/cli/test_service_dhcpv6-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_dhcpv6-server.py b/smoketest/scripts/cli/test_service_dhcpv6-server.py
index 6535ca72d..ab4604165 100755
--- a/smoketest/scripts/cli/test_service_dhcpv6-server.py
+++ b/smoketest/scripts/cli/test_service_dhcpv6-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_dns_dynamic.py b/smoketest/scripts/cli/test_service_dns_dynamic.py
index 522102e67..61141762d 100755
--- a/smoketest/scripts/cli/test_service_dns_dynamic.py
+++ b/smoketest/scripts/cli/test_service_dns_dynamic.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_dns_forwarding.py b/smoketest/scripts/cli/test_service_dns_forwarding.py
index 9a3f4933e..995f5cb25 100755
--- a/smoketest/scripts/cli/test_service_dns_forwarding.py
+++ b/smoketest/scripts/cli/test_service_dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_https.py b/smoketest/scripts/cli/test_service_https.py
index 04c4a2e51..df7657685 100755
--- a/smoketest/scripts/cli/test_service_https.py
+++ b/smoketest/scripts/cli/test_service_https.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -16,6 +16,7 @@
import unittest
import json
+import psutil
from requests import request
from urllib3.exceptions import InsecureRequestWarning
@@ -113,6 +114,29 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
# Check for stopped process
self.assertFalse(process_named_running(PROCESS_NAME))
+ def test_listen_address(self):
+ test_prefix = ['192.0.2.1/26', '2001:db8:1::ffff/64']
+ test_addr = [ i.split('/')[0] for i in test_prefix ]
+ for i, addr in enumerate(test_prefix):
+ self.cli_set(['interfaces', 'dummy', f'dum{i}', 'address', addr])
+
+ key = 'MySuperSecretVyOS'
+ self.cli_set(base_path + ['api', 'keys', 'id', 'key-01', 'key', key])
+ # commit base config first, for testing update of listen-address
+ self.cli_commit()
+
+ for addr in test_addr:
+ self.cli_set(base_path + ['listen-address', addr])
+ self.cli_commit()
+
+ res = set()
+ t = psutil.net_connections(kind="tcp")
+ for c in t:
+ if c.laddr.port == 443:
+ res.add(c.laddr.ip)
+
+ self.assertEqual(res, set(test_addr))
+
def test_certificate(self):
cert_name = 'test_https'
dh_name = 'dh-test'
diff --git a/smoketest/scripts/cli/test_service_ids_ddos-protection.py b/smoketest/scripts/cli/test_service_ids_ddos-protection.py
deleted file mode 100755
index 91b056eea..000000000
--- a/smoketest/scripts/cli/test_service_ids_ddos-protection.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2022 VyOS maintainers and contributors
-#
-# 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
-import unittest
-
-from base_vyostest_shim import VyOSUnitTestSHIM
-
-from vyos.configsession import ConfigSessionError
-from vyos.utils.process import process_named_running
-from vyos.utils.file import read_file
-
-PROCESS_NAME = 'fastnetmon'
-FASTNETMON_CONF = '/run/fastnetmon/fastnetmon.conf'
-NETWORKS_CONF = '/run/fastnetmon/networks_list'
-EXCLUDED_NETWORKS_CONF = '/run/fastnetmon/excluded_networks_list'
-base_path = ['service', 'ids', 'ddos-protection']
-
-class TestServiceIDS(VyOSUnitTestSHIM.TestCase):
- @classmethod
- def setUpClass(cls):
- super(TestServiceIDS, cls).setUpClass()
-
- # ensure we can also run this test on a live system - so lets clean
- # out the current configuration :)
- cls.cli_delete(cls, base_path)
-
- def tearDown(self):
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
- # delete test config
- self.cli_delete(base_path)
- self.cli_commit()
-
- self.assertFalse(os.path.exists(FASTNETMON_CONF))
- self.assertFalse(process_named_running(PROCESS_NAME))
-
- def test_fastnetmon(self):
- networks = ['10.0.0.0/24', '10.5.5.0/24', '2001:db8:10::/64', '2001:db8:20::/64']
- excluded_networks = ['10.0.0.1/32', '2001:db8:10::1/128']
- interfaces = ['eth0', 'eth1']
- fps = '3500'
- mbps = '300'
- pps = '60000'
-
- self.cli_set(base_path + ['mode', 'mirror'])
- # Required network!
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- for tmp in networks:
- self.cli_set(base_path + ['network', tmp])
-
- # optional excluded-network!
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- for tmp in excluded_networks:
- self.cli_set(base_path + ['excluded-network', tmp])
-
- # Required interface(s)!
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- for tmp in interfaces:
- self.cli_set(base_path + ['listen-interface', tmp])
-
- self.cli_set(base_path + ['direction', 'in'])
- self.cli_set(base_path + ['threshold', 'general', 'fps', fps])
- self.cli_set(base_path + ['threshold', 'general', 'pps', pps])
- self.cli_set(base_path + ['threshold', 'general', 'mbps', mbps])
-
- # commit changes
- self.cli_commit()
-
- # Check configured port
- config = read_file(FASTNETMON_CONF)
- self.assertIn(f'mirror_afpacket = on', config)
- self.assertIn(f'process_incoming_traffic = on', config)
- self.assertIn(f'process_outgoing_traffic = off', config)
- self.assertIn(f'ban_for_flows = on', config)
- self.assertIn(f'threshold_flows = {fps}', config)
- self.assertIn(f'ban_for_bandwidth = on', config)
- self.assertIn(f'threshold_mbps = {mbps}', config)
- self.assertIn(f'ban_for_pps = on', config)
- self.assertIn(f'threshold_pps = {pps}', config)
- # default
- self.assertIn(f'enable_ban = on', config)
- self.assertIn(f'enable_ban_ipv6 = on', config)
- self.assertIn(f'ban_time = 1900', config)
-
- tmp = ','.join(interfaces)
- self.assertIn(f'interfaces = {tmp}', config)
-
-
- network_config = read_file(NETWORKS_CONF)
- for tmp in networks:
- self.assertIn(f'{tmp}', network_config)
-
- excluded_network_config = read_file(EXCLUDED_NETWORKS_CONF)
- for tmp in excluded_networks:
- self.assertIn(f'{tmp}', excluded_network_config)
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_ipoe-server.py b/smoketest/scripts/cli/test_service_ipoe-server.py
index 3b3c205cd..3943d686a 100755
--- a/smoketest/scripts/cli/test_service_ipoe-server.py
+++ b/smoketest/scripts/cli/test_service_ipoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_lldp.py b/smoketest/scripts/cli/test_service_lldp.py
index c73707e0d..6566bdb39 100755
--- a/smoketest/scripts/cli/test_service_lldp.py
+++ b/smoketest/scripts/cli/test_service_lldp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_mdns_repeater.py b/smoketest/scripts/cli/test_service_mdns_repeater.py
index 30e48683f..47b8e4dc5 100755
--- a/smoketest/scripts/cli/test_service_mdns_repeater.py
+++ b/smoketest/scripts/cli/test_service_mdns_repeater.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_monitoring_network_event.py b/smoketest/scripts/cli/test_service_monitoring_network_event.py
index 3c9b4bf7f..0bd4b93a6 100644
--- a/smoketest/scripts/cli/test_service_monitoring_network_event.py
+++ b/smoketest/scripts/cli/test_service_monitoring_network_event.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_monitoring_prometheus.py b/smoketest/scripts/cli/test_service_monitoring_prometheus.py
index 6e7f8c808..328c8d6b2 100755
--- a/smoketest/scripts/cli/test_service_monitoring_prometheus.py
+++ b/smoketest/scripts/cli/test_service_monitoring_prometheus.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_monitoring_telegraf.py b/smoketest/scripts/cli/test_service_monitoring_telegraf.py
index 886b88683..05a2103b2 100755
--- a/smoketest/scripts/cli/test_service_monitoring_telegraf.py
+++ b/smoketest/scripts/cli/test_service_monitoring_telegraf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_monitoring_zabbix-agent.py b/smoketest/scripts/cli/test_service_monitoring_zabbix-agent.py
index 522f9df0f..1b2d37f1f 100755
--- a/smoketest/scripts/cli/test_service_monitoring_zabbix-agent.py
+++ b/smoketest/scripts/cli/test_service_monitoring_zabbix-agent.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_ndp-proxy.py b/smoketest/scripts/cli/test_service_ndp-proxy.py
index dfdb3f6aa..1e66fc331 100755
--- a/smoketest/scripts/cli/test_service_ndp-proxy.py
+++ b/smoketest/scripts/cli/test_service_ndp-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_ntp.py b/smoketest/scripts/cli/test_service_ntp.py
index 469d44eaa..a84b9cec8 100755
--- a/smoketest/scripts/cli/test_service_ntp.py
+++ b/smoketest/scripts/cli/test_service_ntp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_pppoe-server.py b/smoketest/scripts/cli/test_service_pppoe-server.py
index 8cd87e0f2..7a43acfca 100755
--- a/smoketest/scripts/cli/test_service_pppoe-server.py
+++ b/smoketest/scripts/cli/test_service_pppoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_router-advert.py b/smoketest/scripts/cli/test_service_router-advert.py
index 6dbb6add4..56e05c317 100755
--- a/smoketest/scripts/cli/test_service_router-advert.py
+++ b/smoketest/scripts/cli/test_service_router-advert.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright 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
@@ -252,6 +252,118 @@ class TestServiceRADVD(VyOSUnitTestSHIM.TestCase):
tmp = get_config_value('AdvIntervalOpt')
self.assertEqual(tmp, 'off')
+ def test_auto_ignore(self):
+ isp_prefix = '2001:db8::/64'
+ ula_prefixes = ['fd00::/64', 'fd01::/64']
+
+ # configure wildcard prefix
+ self.cli_set(base_path + ['prefix', '::/64'])
+
+ # test auto-ignore CLI behaviors with no prefix overrides
+ # set auto-ignore for all three prefixes
+ self.cli_set(base_path + ['auto-ignore', isp_prefix])
+
+ for ula_prefix in ula_prefixes:
+ self.cli_set(base_path + ['auto-ignore', ula_prefix])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # ensure autoignoreprefixes block is generated in config file
+ tmp = f'autoignoreprefixes' + ' {'
+ self.assertIn(tmp, config)
+
+ # ensure all three prefixes are contained in the block
+ self.assertIn(f' {isp_prefix};', config)
+ for ula_prefix in ula_prefixes:
+ self.assertIn(f' {ula_prefix};', config)
+
+ # remove a prefix and verify it's gone
+ self.cli_delete(base_path + ['auto-ignore', ula_prefixes[1]])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ self.assertNotIn(f' {ula_prefixes[1]};', config)
+
+ # ensure remaining two prefixes are still present
+ self.assertIn(f' {ula_prefixes[0]};', config)
+ self.assertIn(f' {isp_prefix};', config)
+
+ # remove the remaining two prefixes and verify the config block is gone
+ self.cli_delete(base_path + ['auto-ignore', ula_prefixes[0]])
+ self.cli_delete(base_path + ['auto-ignore', isp_prefix])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ tmp = f'autoignoreprefixes' + ' {'
+ self.assertNotIn(tmp, config)
+
+ # test wildcard prefix overrides, with and without auto-ignore CLI configuration
+ newline = '\n'
+ left_curly = '{'
+ right_curly = '}'
+
+ # override ULA prefixes
+ for ula_prefix in ula_prefixes:
+ self.cli_set(base_path + ['prefix', ula_prefix])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # ensure autoignoreprefixes block is generated in config file with both prefixes
+ tmp = f'autoignoreprefixes' + f' {left_curly}{newline} {ula_prefixes[0]};{newline} {ula_prefixes[1]};{newline} {right_curly};'
+ self.assertIn(tmp, config)
+
+ # remove a ULA prefix and ensure there is only one prefix in the config block
+ self.cli_delete(base_path + ['prefix', ula_prefixes[0]])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # ensure autoignoreprefixes block is generated in config file with only one prefix
+ tmp = f'autoignoreprefixes' + f' {left_curly}{newline} {ula_prefixes[1]};{newline} {right_curly};'
+ self.assertIn(tmp, config)
+
+ # exclude a prefix with auto-ignore CLI syntax
+ self.cli_set(base_path + ['auto-ignore', ula_prefixes[0]])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # verify that both prefixes appear in config block once again
+ tmp = f'autoignoreprefixes' + f' {left_curly}{newline} {ula_prefixes[0]};{newline} {ula_prefixes[1]};{newline} {right_curly};'
+ self.assertIn(tmp, config)
+
+ # override first ULA prefix again
+ # first ULA is auto-ignored in CLI, it must appear only once in config
+ self.cli_set(base_path + ['prefix', ula_prefixes[0]])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # verify that both prefixes appear uniquely
+ tmp = f'autoignoreprefixes' + f' {left_curly}{newline} {ula_prefixes[0]};{newline} {ula_prefixes[1]};{newline} {right_curly};'
+ self.assertIn(tmp, config)
+
+ # remove wildcard prefix and verify config block is gone
+ self.cli_delete(base_path + ['prefix', '::/64'])
+
+ # commit and reload config
+ self.cli_commit()
+ config = read_file(RADVD_CONF)
+
+ # verify config block is gone
+ tmp = f'autoignoreprefixes' + ' {'
+ self.assertNotIn(tmp, config)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_salt-minion.py b/smoketest/scripts/cli/test_service_salt-minion.py
index 48a588b72..1ad1333f0 100755
--- a/smoketest/scripts/cli/test_service_salt-minion.py
+++ b/smoketest/scripts/cli/test_service_salt-minion.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_snmp.py b/smoketest/scripts/cli/test_service_snmp.py
index 7d5eaa440..d2221908c 100755
--- a/smoketest/scripts/cli/test_service_snmp.py
+++ b/smoketest/scripts/cli/test_service_snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py
index fa08a5b32..32bc3cc89 100755
--- a/smoketest/scripts/cli/test_service_ssh.py
+++ b/smoketest/scripts/cli/test_service_ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -24,10 +24,12 @@ from pwd import getpwall
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
+from vyos.defaults import config_files
from vyos.utils.process import cmd
from vyos.utils.process import is_systemd_service_running
from vyos.utils.process import process_named_running
from vyos.utils.file import read_file
+from vyos.utils.file import write_file
from vyos.xml_ref import default_value
PROCESS_NAME = 'sshd'
@@ -38,26 +40,101 @@ pki_path = ['pki']
key_rsa = '/etc/ssh/ssh_host_rsa_key'
key_dsa = '/etc/ssh/ssh_host_dsa_key'
key_ed25519 = '/etc/ssh/ssh_host_ed25519_key'
-trusted_user_ca_key = '/etc/ssh/trusted_user_ca_key'
-
+trusted_user_ca = config_files['sshd_user_ca']
+test_command = 'uname -a'
def get_config_value(key):
tmp = read_file(SSHD_CONF)
tmp = re.findall(f'\n?{key}\s+(.*)', tmp)
return tmp
+trusted_user_ca_path = base_path + ['trusted-user-ca']
+# CA and signed user key generated using:
+# ssh-keygen -f vyos-ssh-ca.key
+# ssh-keygen -f vyos_testca -C "vyos_tesca@vyos.net"
+# ssh-keygen -s vyos-ssh-ca.key -I vyos_testca@vyos.net -n vyos,vyos_testca -V +520w vyos_testca.pub
+ca_cert_data = """
+AAAAB3NzaC1yc2EAAAADAQABAAABgQCTBa7+TTefsMLTHuuLPUmmm7SGAuoK03oZEIi2/O
+sww1uhCdKrm7bFvSUFpWvq3gX8TSS+yO5kNKz3BTMBu7oq01/Ewjyw0jR+fUog76x7mCzd
+2iI4QmPj4lNHSUFquaELt2aBwY4f7LtjxRCCgtWgirq/Qk+P27uJKErvndyYc95v9no15z
+lQFSdUid6tF8IjYljK8pXP0JshFp3XnFV2Rg80j7O66mRtVFC4tt2vluyIFeIID+5fL03v
+LXbT/2zNdoH6QiI9NGWkxhS7zFYziVd/rzG5xlEB1ezs2Sz4zjMPgV3GiMINb6tjEWNJhM
+KtDWIt+3UDpx+2T9PrhDBDFMlneiHCD6MxRv2sLbicevSj0PV7/fRnwoHs6hDKCU5eS2Mc
+CTxXr4jaboLZ6q3sbGHCHZo/PuA8Sl9iZCM4GCxx5bgvRRmGpgZv4PfFzA2b/wTHkKnf6E
+kuthoAJufmNxPaZQRQKF34SdmTKgSJTCY1gqwCH2iNg0PVKU+vN8c=
+"""
-ca_root_cert_data = """
-MIIBcTCCARagAwIBAgIUDcAf1oIQV+6WRaW7NPcSnECQ/lUwCgYIKoZIzj0EAwIw
-HjEcMBoGA1UEAwwTVnlPUyBzZXJ2ZXIgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjBa
-Fw0zMjAyMTUxOTQxMjBaMB4xHDAaBgNVBAMME1Z5T1Mgc2VydmVyIHJvb3QgQ0Ew
-WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ0y24GzKQf4aM2Ir12tI9yITOIzAUj
-ZXyJeCmYI6uAnyAMqc4Q4NKyfq3nBi4XP87cs1jlC1P2BZ8MsjL5MdGWozIwMDAP
-BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRwC/YaieMEnjhYa7K3Flw/o0SFuzAK
-BggqhkjOPQQDAgNJADBGAiEAh3qEj8vScsjAdBy5shXzXDVVOKWCPTdGrPKnu8UW
-a2cCIQDlDgkzWmn5ujc5ATKz1fj+Se/aeqwh4QyoWCVTFLIxhQ==
+cert_user_key = """-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
+NhAAAAAwEAAQAAAYEArnIlFpMwSQax7+qH3+/gbv65mem6Ur+gepNYC8TYaE91xJxMoE5M
+Pyh1s8Kr/WYNF6aN43qdDnjvGy38oFng4lEfxG475AqpTIGmP4GvEOlnNLhjCcOHrOFuzg
+uRtDDvn0/TPhdqLTlbvgZ326WO7xQkCX11qmdGUUtC9Byd7p+EmnTe0oP8N6MeyYY78qa4
+HnzMd6EPb3vyWdASpPZjQE0OJCeAx6Mne2kOnKxUcW1UlczOa1PPIQMU+Rp1PWDtkdiYAd
+nbTbIdxDN8Bn3mC3JXD642EcwXSJ1+kov/8u8bBuYNt3t3nf/krSebx4Ge7ObYnURj31j0
+8L8Vv3fgv+T7pY8iyMh8dYfrZPAWQGN1pe8ZkDaM1QGKJncF+8N0UB4EVFBHNLt7W8+oHt
+LPMqYw13djZHg5Q1NxSxc1srOmEBZrWCBZgDGGiqtKo+lF+oVvqvBh/hncOBlDX5RFM8qw
+Qt4mem9TEZZrIvC9q1dcVpQUrt8BvBOSnGnBb7yTAAAFkEdBIUlHQSFJAAAAB3NzaC1yc2
+EAAAGBAK5yJRaTMEkGse/qh9/v4G7+uZnpulK/oHqTWAvE2GhPdcScTKBOTD8odbPCq/1m
+DRemjeN6nQ547xst/KBZ4OJRH8RuO+QKqUyBpj+BrxDpZzS4YwnDh6zhbs4LkbQw759P0z
+4Xai05W74Gd9ulju8UJAl9dapnRlFLQvQcne6fhJp03tKD/DejHsmGO/KmuB58zHehD297
+8lnQEqT2Y0BNDiQngMejJ3tpDpysVHFtVJXMzmtTzyEDFPkadT1g7ZHYmAHZ202yHcQzfA
+Z95gtyVw+uNhHMF0idfpKL//LvGwbmDbd7d53/5K0nm8eBnuzm2J1EY99Y9PC/Fb934L/k
++6WPIsjIfHWH62TwFkBjdaXvGZA2jNUBiiZ3BfvDdFAeBFRQRzS7e1vPqB7SzzKmMNd3Y2
+R4OUNTcUsXNbKzphAWa1ggWYAxhoqrSqPpRfqFb6rwYf4Z3DgZQ1+URTPKsELeJnpvUxGW
+ayLwvatXXFaUFK7fAbwTkpxpwW+8kwAAAAMBAAEAAAGAEeZQe+0vyoPPWkjRwbQBbszgX9
+9QaRE/TD82N5mZLbWJkK+2WnSY9O9tNGbIncBiSNz5ji/p/FmDCgzr8SAyfRvJ4K6sTTfy
+1eYvwtscYDsy2ywDAuDMrnvrPLqJ1tghSP2N4BR9ppT4yZosTkjB+TIzMxjBLB0GEBgNj1
+19rxswe2YmlFSgBVgi3pbRgT0uLfgBmvzXHUoLPL/8ScT7u4Csmh/GN7Xmuo5gcMnArcAu
+1Q17g3PJZcpv1Ser2VfKnVAwrURCLW8dlji5xat/3E/PLsrLvszVS6U0hFf3MaOixprxsz
+wc0n2Y4lAgkgkCZQ0Ty9TSXI/8TQWL8cPFej1TK15NWXlfElZxI+lhwcsnWmNy3mXD746/
+YZLH+OCs9isvewZWryQEkdVCU42MM/7L4Hoeqh2diGDV9wtKDW5FjHq/VRNOMVt59eCFlv
+eujh89/KY6wPxHoDoY3+olhggiKDGw1wUUpEXKNQhhTjx1g0xn7AFYz+Bp2svM9EdhAAAA
+wQDBq+zeOhsS/VrrVRkmOYYXnBSe0WcckjcYOly/8FLTPkq19aVY5eOmo6teegqvkWscGP
+Wisl7DW+kFNolIvwc6shf/8+PXC1KlADd9S1uoXvSmVoe3wSsIKRCsUuLZiiJkv4nqQ/BK
+T6ijvNG2Wu3YGsP8Tj+OcTebqk1vDItaickhKtFxCx6PBcV+RrDeK1TT6uAHd1AsGikTva
+V/BDMmtoDz7qFQbj9Vj2np88MakxYfm7u4DzKu082GHDBC44sAAADBAN8ATvmmfxqk5GFg
++2rbIW+qMJ2GwWXiTFLjH7u4HEhsmHbHYsQ0v+cGu2dKfBUVWoq/N2ltDQ0QYTgkmsxKvm
+I8AjVhLHhFB1DtPBMHibsF/rtBRgsItR+PveUtRYOmeY1PzJ3ygVNJpPJ87st0T4JVNQiE
++bFEhnJ/RcTHxzAAt8+gTn0PTen3+hn9Jk2YFHWFb51YDw2h00LL9XT9Enz4xkc6gTPL3M
+0IKULJWnyYGOLueSsQxJiaAUcsZg8W2QAAAMEAyEJ45HtbUqZ5xd2K5ZfY8cd1dC9uAx6a
+cSdENUvMW4yE3QEJ4xdonDUn9OQYR7GpseQWuXBrTO2PSsse7P6eHUsRhaUkFOvLzHSVzO
+bI9HDJAq6+KCPhm2eixfBiMs2meEle8MvNiiONwaY3JnPnGdsTpEjcm6oulyC52xRvHhvc
+nCuoRTqX7xcIka4jCXInYBS7GhlF5iAmIAAVkvfWjjNwZ3S0mnGUUOYgknidBhK+x0zCWt
+IXOeoIfjb/C4NLAAAAE3Z5b3NfdGVzY2FAdnlvcy5uZXQBAgMEBQYH
+-----END OPENSSH PRIVATE KEY-----
"""
+cert_user_signed = """
+ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb2
+0AAAAglE+kjRPqsck/y2ywO+owv1FTeU6QFNPywFqD8aoEcA8AAAADAQABAAABgQCuciUWk
+zBJBrHv6off7+Bu/rmZ6bpSv6B6k1gLxNhoT3XEnEygTkw/KHWzwqv9Zg0Xpo3jep0OeO8b
+LfygWeDiUR/EbjvkCqlMgaY/ga8Q6Wc0uGMJw4es4W7OC5G0MO+fT9M+F2otOVu+BnfbpY7
+vFCQJfXWqZ0ZRS0L0HJ3un4SadN7Sg/w3ox7JhjvyprgefMx3oQ9ve/JZ0BKk9mNATQ4kJ4
+DHoyd7aQ6crFRxbVSVzM5rU88hAxT5GnU9YO2R2JgB2dtNsh3EM3wGfeYLclcPrjYRzBdIn
+X6Si//y7xsG5g23e3ed/+StJ5vHgZ7s5tidRGPfWPTwvxW/d+C/5PuljyLIyHx1h+tk8BZA
+Y3Wl7xmQNozVAYomdwX7w3RQHgRUUEc0u3tbz6ge0s8ypjDXd2NkeDlDU3FLFzWys6YQFmt
+YIFmAMYaKq0qj6UX6hW+q8GH+Gdw4GUNflEUzyrBC3iZ6b1MRlmsi8L2rV1xWlBSu3wG8E5
+KcacFvvJMAAAAAAAAAAAAAAAEAAAAUdnlvc190ZXN0Y2FAdnlvcy5uZXQAAAAXAAAABHZ5b
+3MAAAALdnlvc190ZXN0Y2EAAAAAaDg66AAAAAB69w9WAAAAAAAAAIIAAAAVcGVybWl0LVgx
+MS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGV
+ybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LX
+VzZXItcmMAAAAAAAAAAAAAAZcAAAAHc3NoLXJzYQAAAAMBAAEAAAGBAJMFrv5NN5+wwtMe6
+4s9SaabtIYC6grTehkQiLb86zDDW6EJ0qubtsW9JQWla+reBfxNJL7I7mQ0rPcFMwG7uirT
+X8TCPLDSNH59SiDvrHuYLN3aIjhCY+PiU0dJQWq5oQu3ZoHBjh/su2PFEIKC1aCKur9CT4/
+bu4koSu+d3Jhz3m/2ejXnOVAVJ1SJ3q0XwiNiWMrylc/QmyEWndecVXZGDzSPs7rqZG1UUL
+i23a+W7IgV4ggP7l8vTe8tdtP/bM12gfpCIj00ZaTGFLvMVjOJV3+vMbnGUQHV7OzZLPjOM
+w+BXcaIwg1vq2MRY0mEwq0NYi37dQOnH7ZP0+uEMEMUyWd6IcIPozFG/awtuJx69KPQ9Xv9
+9GfCgezqEMoJTl5LYxwJPFeviNpugtnqrexsYcIdmj8+4DxKX2JkIzgYLHHluC9FGYamBm/
+g98XMDZv/BMeQqd/oSS62GgAm5+Y3E9plBFAoXfhJ2ZMqBIlMJjWCrAIfaI2DQ9UpT683xw
+AAAZQAAAAMcnNhLXNoYTItNTEyAAABgINZAr9M9ZYWDhhf5uWNkUBKq12OlJ3ImvHg5161P
+BAAL6crGS3WzyAs9LerxFcdMJ0gzMgUixR59MgGMAzfN+DjoSmgcLVT0eVoI5GMBkdiq8T5
+h3qjeXTc5BfLJiACbu7tOPhuIsIDreDnCVYmGr2z+rAPaqMETJa4L0submx4DqnahSY0ZSH
+WjTrjWCSPIdySh9HUXbpq3tYdNlqmpSY5YzvDmMC46kGMF10G5ycc58asWfUMwLMGsTEt2t
+R5DKRDw/iJch3r+L0xLMCSmEXnu6/Gl7Yq1XJdWm9cA1SvDyxEuB4yKIDkunXrPiuPn3zyv
+z1a/bY0hvuF+fyL+tRCbmrfOLreHuYh9aFg6e22MoKhrez5wP8Eoy1T+rlQrmlgCRDShBgj
+wMMhc+2fdrzTR07Ctnmv339p/SY5wBruzNM9R1mzyEuuJDE6OkKBTI8kuQu6ypGv+bLqSSt
+wujcNqOI4Vz61HiOsRSTUa7tA5q4hBwFqq7FB8+N0Ylfa5A== vyos_tesca@vyos.net
+"""
class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
@classmethod
@@ -207,23 +284,12 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
# run natively.
#
# We also try to login as an invalid user - this is not allowed to work.
-
test_user = 'ssh_test'
test_pass = 'v2i57DZs8idUwMN3VC92'
- test_command = 'uname -a'
self.cli_set(base_path)
- self.cli_set(
- [
- 'system',
- 'login',
- 'user',
- test_user,
- 'authentication',
- 'plaintext-password',
- test_pass,
- ]
- )
+ self.cli_set(['system', 'login', 'user', test_user, 'authentication',
+ 'plaintext-password', test_pass])
# commit changes
self.cli_commit()
@@ -236,9 +302,8 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
# Login with invalid credentials
with self.assertRaises(paramiko.ssh_exception.AuthenticationException):
- output, error = self.ssh_send_cmd(
- test_command, 'invalid_user', 'invalid_password'
- )
+ output, error = self.ssh_send_cmd(test_command, 'invalid_user',
+ 'invalid_password')
self.cli_delete(['system', 'login', 'user', test_user])
self.cli_commit()
@@ -359,40 +424,74 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
tmp_sshd_conf = read_file(SSHD_CONF)
self.assertIn(expected, tmp_sshd_conf)
- def test_ssh_trusted_user_ca_key(self):
+ def test_ssh_trusted_user_ca(self):
ca_cert_name = 'test_ca'
+ public_key_type = 'ssh-rsa'
+ public_key_data = ca_cert_data.replace('\n', '')
+ test_user = 'vyos_testca'
+ principal = 'vyos'
+ user_auth_base = ['system', 'login', 'user', test_user]
+
+ # create user account
+ self.cli_set(user_auth_base)
+ self.cli_set(pki_path + ['openssh', ca_cert_name, 'public',
+ 'key', public_key_data])
+ self.cli_set(pki_path + ['openssh', ca_cert_name, 'public',
+ 'type', public_key_type])
+ self.cli_set(trusted_user_ca_path, value=ca_cert_name)
+ self.cli_commit()
+
+ trusted_user_ca_config = get_config_value('TrustedUserCAKeys')
+ self.assertIn(trusted_user_ca, trusted_user_ca_config)
+
+ authorize_principals_file_config = get_config_value('AuthorizedPrincipalsFile')
+ self.assertIn('none', authorize_principals_file_config)
+
+ ca_key_contents = read_file(trusted_user_ca).lstrip().rstrip()
+ self.assertIn(f'{public_key_type} {public_key_data}', ca_key_contents)
- # set pki ca <ca_cert_name> certificate <ca_key_data>
- # set service ssh trusted-user-ca-key ca-certificate <ca_cert_name>
- self.cli_set(
- pki_path
- + [
- 'ca',
- ca_cert_name,
- 'certificate',
- ca_root_cert_data.replace('\n', ''),
- ]
- )
- self.cli_set(
- base_path + ['trusted-user-ca-key', 'ca-certificate', ca_cert_name]
- )
+ # Verify functionality by logging into the system using signed user key
+ key_filename = f'/tmp/{test_user}'
+ write_file(key_filename, cert_user_key, mode=0o600)
+ write_file(f'{key_filename}-cert.pub', cert_user_signed.replace('\n', ''))
+
+ # Login with proper credentials
+ output, error = self.ssh_send_cmd(test_command, test_user, password=None,
+ key_filename=key_filename)
+ # Verify login
+ self.assertFalse(error)
+ self.assertEqual(output, cmd(test_command))
+
+ # Enable user principal name - logins only allowed if certificate contains
+ # said principal name
+ self.cli_set(user_auth_base + ['authentication', 'principal', principal])
self.cli_commit()
- trusted_user_ca_key_config = get_config_value('TrustedUserCAKeys')
- self.assertIn(trusted_user_ca_key, trusted_user_ca_key_config)
+ # Verify generated SSH principals
+ authorized_principals_file = f'/home/{test_user}/.ssh/authorized_principals'
+ authorized_principals = read_file(authorized_principals_file, sudo=True)
+ self.assertIn(principal, authorized_principals)
- with open(trusted_user_ca_key, 'r') as file:
- ca_key_contents = file.read()
- self.assertIn(ca_root_cert_data, ca_key_contents)
+ # Login with proper credentials
+ output, error = self.ssh_send_cmd(test_command, test_user, password=None,
+ key_filename=key_filename)
+ # Verify login
+ self.assertFalse(error)
+ self.assertEqual(output, cmd(test_command))
- self.cli_delete(base_path + ['trusted-user-ca-key'])
+ self.cli_delete(trusted_user_ca_path)
+ self.cli_delete(user_auth_base)
self.cli_delete(['pki', 'ca', ca_cert_name])
self.cli_commit()
# Verify the CA key is removed
- trusted_user_ca_key_config = get_config_value('TrustedUserCAKeys')
- self.assertNotIn(trusted_user_ca_key, trusted_user_ca_key_config)
+ trusted_user_ca_config = get_config_value('TrustedUserCAKeys')
+ self.assertNotIn(trusted_user_ca, trusted_user_ca_config)
+ self.assertFalse(os.path.exists(trusted_user_ca))
+ authorize_principals_file_config = get_config_value('AuthorizedPrincipalsFile')
+ self.assertNotIn('none', authorize_principals_file_config)
+ self.assertFalse(os.path.exists(f'/home/{test_user}/.ssh/authorized_principals'))
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_stunnel.py b/smoketest/scripts/cli/test_service_stunnel.py
index 3aeffd09e..4bae79865 100755
--- a/smoketest/scripts/cli/test_service_stunnel.py
+++ b/smoketest/scripts/cli/test_service_stunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_tftp-server.py b/smoketest/scripts/cli/test_service_tftp-server.py
index d60794980..e3f1e25e4 100755
--- a/smoketest/scripts/cli/test_service_tftp-server.py
+++ b/smoketest/scripts/cli/test_service_tftp-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_service_webproxy.py b/smoketest/scripts/cli/test_service_webproxy.py
index ab4707a61..431f1c885 100755
--- a/smoketest/scripts/cli/test_service_webproxy.py
+++ b/smoketest/scripts/cli/test_service_webproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_acceleration_qat.py b/smoketest/scripts/cli/test_system_acceleration_qat.py
index 9e60bb211..9b8ecef7f 100755
--- a/smoketest/scripts/cli/test_system_acceleration_qat.py
+++ b/smoketest/scripts/cli/test_system_acceleration_qat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py
index 72deb7525..75fabdf7a 100755
--- a/smoketest/scripts/cli/test_system_conntrack.py
+++ b/smoketest/scripts/cli/test_system_conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -20,7 +20,10 @@ import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.firewall import find_nftables_rule
-from vyos.utils.file import read_file, read_json
+from vyos.utils.file import read_file
+from vyos.utils.file import read_json
+from vyos.utils.system import sysctl_read
+from vyos.xml_ref import default_value
base_path = ['system', 'conntrack']
@@ -168,8 +171,8 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
self.assertTrue(find_nftables_rule('ip vyos_conntrack', 'VYOS_CT_HELPER', [rule]) == None)
def test_conntrack_hash_size(self):
- hash_size = '65536'
- hash_size_default = '32768'
+ hash_size = '8192'
+ hash_size_default = default_value(base_path + ['hash-size'])
self.cli_set(base_path + ['hash-size', hash_size])
@@ -178,7 +181,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
# verify new configuration - only effective after reboot, but
# a valid config file is sufficient
- tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf')
+ tmp = sysctl_read('net.netfilter.nf_conntrack_buckets')
self.assertIn(hash_size, tmp)
# Test default value by deleting the configuration
@@ -189,12 +192,14 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
# verify new configuration - only effective after reboot, but
# a valid config file is sufficient
- tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf')
+ tmp = sysctl_read('net.netfilter.nf_conntrack_buckets')
self.assertIn(hash_size_default, tmp)
def test_conntrack_ignore(self):
address_group = 'conntracktest'
address_group_member = '192.168.0.1'
+ port_single = '53'
+ ports_multi = '500,4500'
ipv6_address_group = 'conntracktest6'
ipv6_address_group_member = 'dead:beef::1'
@@ -211,6 +216,14 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'destination', 'group', 'address-group', address_group])
self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'protocol', 'all'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '3', 'source', 'address', '192.0.2.1'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '3', 'destination', 'port', ports_multi])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '3', 'protocol', 'udp'])
+
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '4', 'source', 'address', '192.0.2.1'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '4', 'destination', 'port', port_single])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '4', 'protocol', 'udp'])
+
self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'source', 'address', 'fe80::1'])
self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'address', 'fe80::2'])
self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'port', '22'])
@@ -226,7 +239,9 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['ip saddr 192.0.2.1', 'ip daddr 192.0.2.2', 'tcp dport 22', 'tcp flags & syn == syn', 'notrack'],
- ['ip saddr 192.0.2.1', 'ip daddr @A_conntracktest', 'notrack']
+ ['ip saddr 192.0.2.1', 'ip daddr @A_conntracktest', 'notrack'],
+ ['ip saddr 192.0.2.1', 'udp dport { 500, 4500 }', 'notrack'],
+ ['ip saddr 192.0.2.1', 'udp dport 53', 'notrack']
]
nftables6_search = [
diff --git a/smoketest/scripts/cli/test_system_flow-accounting.py b/smoketest/scripts/cli/test_system_flow-accounting.py
index 9d7942789..7778c393f 100755
--- a/smoketest/scripts/cli/test_system_flow-accounting.py
+++ b/smoketest/scripts/cli/test_system_flow-accounting.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_frr.py b/smoketest/scripts/cli/test_system_frr.py
index a2ce58bf6..98baca1d3 100755
--- a/smoketest/scripts/cli/test_system_frr.py
+++ b/smoketest/scripts/cli/test_system_frr.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_ip.py b/smoketest/scripts/cli/test_system_ip.py
index 5b6ef2046..764cd9192 100755
--- a/smoketest/scripts/cli/test_system_ip.py
+++ b/smoketest/scripts/cli/test_system_ip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -128,5 +128,26 @@ class TestSystemIP(VyOSUnitTestSHIM.TestCase):
frrconfig = self.getFRRconfig('', end='')
self.assertNotIn(f'no ip nht resolve-via-default', frrconfig)
+ def test_system_ip_import_table(self):
+ table_num = '100'
+ distance = '200'
+ route_map_in = 'foo-map-in'
+ self.cli_set(['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit'])
+ self.cli_set(base_path + ['import-table', table_num, 'distance', distance])
+ self.cli_set(base_path + ['import-table', table_num, 'route-map', route_map_in])
+
+ self.cli_commit()
+ # Verify CLI config applied to FRR
+ frrconfig = self.getFRRconfig('', end='')
+ self.assertIn(f'ip import-table {table_num} distance {distance} route-map {route_map_in}', frrconfig)
+
+ self.cli_delete(['policy', 'route-map', route_map_in])
+
+ self.cli_delete(base_path + ['import-table'])
+ self.cli_commit()
+ # Verify CLI config removed to FRR
+ frrconfig = self.getFRRconfig('', end='')
+ self.assertNotIn(f'ip import-table {table_num} distance {distance}', frrconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_ipv6.py b/smoketest/scripts/cli/test_system_ipv6.py
index 26f281bb4..2b4a86a4d 100755
--- a/smoketest/scripts/cli/test_system_ipv6.py
+++ b/smoketest/scripts/cli/test_system_ipv6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py
index 71dec68d8..9a07505d0 100755
--- a/smoketest/scripts/cli/test_system_login.py
+++ b/smoketest/scripts/cli/test_system_login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -548,5 +548,34 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
self.cli_discard()
+ def test_pam_nologin(self):
+ # Testcase for T7443, test if we can login with a non-privileged user
+ # when there are only 5 minutes left until the system reboots
+ username = users[0]
+ password = f'{username}-pSWd-t3st'
+
+ self.cli_set(base_path + ['user', username, 'authentication', 'plaintext-password', password])
+ self.cli_commit()
+
+ # Login with proper credentials
+ out, err = self.ssh_send_cmd(ssh_test_command, username, password)
+ # verify login
+ self.assertFalse(err)
+ self.assertEqual(out, self.ssh_test_command_result)
+
+ # Request system reboot in 5 minutes - this will activate pam_nologin.so
+ # and prevent any login - but we have this disabled, so we must be able
+ # to login to the router
+ self.op_mode(['reboot', 'in', '4'])
+
+ # verify login
+ # Login with proper credentials - after reboot is pending
+ out, err = self.ssh_send_cmd(ssh_test_command, username, password)
+ self.assertFalse(err)
+ self.assertEqual(out, self.ssh_test_command_result)
+
+ # Cancel pending reboot - we do wan't to preceed with the remaining tests
+ self.op_mode(['reboot', 'cancel'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_logs.py b/smoketest/scripts/cli/test_system_logs.py
index 17cce5ca1..d951ce43d 100755
--- a/smoketest/scripts/cli/test_system_logs.py
+++ b/smoketest/scripts/cli/test_system_logs.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_option.py b/smoketest/scripts/cli/test_system_option.py
index f3112cf0b..69f053a7f 100755
--- a/smoketest/scripts/cli/test_system_option.py
+++ b/smoketest/scripts/cli/test_system_option.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
@@ -16,14 +16,18 @@
import os
import unittest
+
from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSessionError
+from vyos.utils.cpu import get_cpus
from vyos.utils.file import read_file
from vyos.utils.process import is_systemd_service_active
from vyos.utils.system import sysctl_read
+from vyos.system import image
base_path = ['system', 'option']
-
class TestSystemOption(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
self.cli_delete(base_path)
@@ -96,6 +100,60 @@ class TestSystemOption(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
self.assertFalse(os.path.exists(ssh_client_opt_file))
+ def test_kernel_options(self):
+ amd_pstate_mode = 'active'
+ isolate_cpus = '1,2,3'
+ nohz_full = '2'
+ rcu_no_cbs = '1,2,4-5'
+ default_hp_size = '2M'
+ hp_size_1g = '1G'
+ hp_size_2m = '2M'
+ hp_count_1g = '2'
+ hp_count_2m = '512'
+
+ self.cli_set(['system', 'option', 'kernel', 'cpu', 'disable-nmi-watchdog'])
+ self.cli_set(['system', 'option', 'kernel', 'cpu', 'isolate-cpus', isolate_cpus])
+ self.cli_set(['system', 'option', 'kernel', 'cpu', 'nohz-full', nohz_full])
+ self.cli_set(['system', 'option', 'kernel', 'cpu', 'rcu-no-cbs', rcu_no_cbs])
+ self.cli_set(['system', 'option', 'kernel', 'disable-hpet'])
+ self.cli_set(['system', 'option', 'kernel', 'disable-mce'])
+ self.cli_set(['system', 'option', 'kernel', 'disable-mitigations'])
+ self.cli_set(['system', 'option', 'kernel', 'disable-power-saving'])
+ self.cli_set(['system', 'option', 'kernel', 'disable-softlockup'])
+ self.cli_set(['system', 'option', 'kernel', 'memory', 'disable-numa-balancing'])
+ self.cli_set(['system', 'option', 'kernel', 'memory', 'default-hugepage-size', default_hp_size])
+ self.cli_set(['system', 'option', 'kernel', 'memory', 'hugepage-size', hp_size_1g, 'hugepage-count', hp_count_1g])
+ self.cli_set(['system', 'option', 'kernel', 'memory', 'hugepage-size', hp_size_2m, 'hugepage-count', hp_count_2m])
+ self.cli_set(['system', 'option', 'kernel', 'quiet'])
+
+ self.cli_set(['system', 'option', 'kernel', 'amd-pstate-driver', amd_pstate_mode])
+ cpu_vendor = get_cpus()[0]['vendor_id']
+ if cpu_vendor != 'AuthenticAMD':
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(['system', 'option', 'kernel', 'amd-pstate-driver'])
+
+ self.cli_commit()
+
+ # Read GRUB config file for current running image
+ tmp = read_file(f'{image.grub.GRUB_DIR_VYOS_VERS}/{image.get_running_image()}.cfg')
+ self.assertIn(' mitigations=off', tmp)
+ self.assertIn(' intel_idle.max_cstate=0 processor.max_cstate=1', tmp)
+ self.assertIn(' quiet', tmp)
+ self.assertIn(' nmi_watchdog=0', tmp)
+ self.assertIn(' hpet=disable', tmp)
+ self.assertIn(' mce=off', tmp)
+ self.assertIn(' nosoftlockup', tmp)
+ self.assertIn(f' isolcpus={isolate_cpus}', tmp)
+ self.assertIn(f' nohz_full={nohz_full}', tmp)
+ self.assertIn(f' rcu_nocbs={rcu_no_cbs}', tmp)
+ self.assertIn(f' default_hugepagesz={default_hp_size}', tmp)
+ self.assertIn(f' hugepagesz={hp_size_1g} hugepages={hp_count_1g}', tmp)
+ self.assertIn(f' hugepagesz={hp_size_2m} hugepages={hp_count_2m}', tmp)
+ self.assertIn(' numa_balancing=disable', tmp)
+
+ if cpu_vendor == 'AuthenticAMD':
+ self.assertIn(f' initcall_blacklist=acpi_cpufreq_init amd_pstate={amd_pstate_mode}', tmp)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_resolvconf.py b/smoketest/scripts/cli/test_system_resolvconf.py
index d8726a301..d91e29230 100755
--- a/smoketest/scripts/cli/test_system_resolvconf.py
+++ b/smoketest/scripts/cli/test_system_resolvconf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_sflow.py b/smoketest/scripts/cli/test_system_sflow.py
index 700253e2b..69b35d1f0 100755
--- a/smoketest/scripts/cli/test_system_sflow.py
+++ b/smoketest/scripts/cli/test_system_sflow.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_system_syslog.py b/smoketest/scripts/cli/test_system_syslog.py
index 6eae3f19d..c4e043a7c 100755
--- a/smoketest/scripts/cli/test_system_syslog.py
+++ b/smoketest/scripts/cli/test_system_syslog.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -14,6 +14,7 @@
# 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
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
@@ -59,6 +60,11 @@ class TestRSYSLOGService(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base_path)
self.cli_commit()
+ # The default syslog implementation should make syslog.service a
+ # symlink to itself
+ self.assertEqual(os.readlink('/etc/systemd/system/syslog.service'),
+ '/lib/systemd/system/rsyslog.service')
+
# Check for running process
self.assertFalse(process_named_running(PROCESS_NAME))
diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py
index 91a76e6f6..a0bf30953 100755
--- a/smoketest/scripts/cli/test_vpn_ipsec.py
+++ b/smoketest/scripts/cli/test_vpn_ipsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -352,6 +352,94 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.tearDownPKI()
+ def test_site_to_site_vti_ts_afi(self):
+ local_address = '192.0.2.10'
+ vti = 'vti10'
+ # IKE
+ self.cli_set(base_path + ['ike-group', ike_group, 'key-exchange', 'ikev2'])
+ self.cli_set(base_path + ['ike-group', ike_group, 'disable-mobike'])
+ # ESP
+ self.cli_set(base_path + ['esp-group', esp_group, 'compression'])
+ # VTI interface
+ self.cli_set(vti_path + [vti, 'address', '10.1.1.1/24'])
+
+ # vpn ipsec auth psk <tag> id <x.x.x.x>
+ self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', local_id])
+ self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', remote_id])
+ self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', peer_ip])
+ self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret', secret])
+
+ # Site to site
+ peer_base_path = base_path + ['site-to-site', 'peer', connection_name]
+ self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret'])
+ self.cli_set(peer_base_path + ['connection-type', 'none'])
+ self.cli_set(peer_base_path + ['force-udp-encapsulation'])
+ self.cli_set(peer_base_path + ['ike-group', ike_group])
+ self.cli_set(peer_base_path + ['default-esp-group', esp_group])
+ self.cli_set(peer_base_path + ['local-address', local_address])
+ self.cli_set(peer_base_path + ['remote-address', peer_ip])
+ self.cli_set(peer_base_path + ['vti', 'bind', vti])
+ self.cli_set(peer_base_path + ['vti', 'esp-group', esp_group])
+ self.cli_set(peer_base_path + ['vti', 'traffic-selector', 'local', 'prefix', '0.0.0.0/0'])
+ self.cli_set(peer_base_path + ['vti', 'traffic-selector', 'remote', 'prefix', '192.0.2.1/32'])
+ self.cli_set(peer_base_path + ['vti', 'traffic-selector', 'remote', 'prefix', '192.0.2.3/32'])
+
+ self.cli_commit()
+
+ swanctl_conf = read_file(swanctl_file)
+ if_id = vti.lstrip('vti')
+ # The key defaults to 0 and will match any policies which similarly do
+ # not have a lookup key configuration - thus we shift the key by one
+ # to also support a vti0 interface
+ if_id = str(int(if_id) +1)
+ swanctl_conf_lines = [
+ f'version = 2',
+ f'auth = psk',
+ f'proposals = aes128-sha1-modp1024',
+ f'esp_proposals = aes128-sha1-modp1024',
+ f'local_addrs = {local_address} # dhcp:no',
+ f'mobike = no',
+ f'remote_addrs = {peer_ip}',
+ f'mode = tunnel',
+ f'local_ts = 0.0.0.0/0',
+ f'remote_ts = 192.0.2.1/32,192.0.2.3/32',
+ f'ipcomp = yes',
+ f'start_action = none',
+ f'replay_window = 32',
+ f'if_id_in = {if_id}', # will be 11 for vti10 - shifted by one
+ f'if_id_out = {if_id}',
+ f'updown = "/etc/ipsec.d/vti-up-down {vti}"'
+ ]
+ for line in swanctl_conf_lines:
+ self.assertIn(line, swanctl_conf)
+
+ # Check IPv6 TS
+ self.cli_delete(peer_base_path + ['vti', 'traffic-selector'])
+ self.cli_set(peer_base_path + ['vti', 'traffic-selector', 'local', 'prefix', '::/0'])
+ self.cli_set(peer_base_path + ['vti', 'traffic-selector', 'remote', 'prefix', '::/0'])
+ self.cli_commit()
+ swanctl_conf = read_file(swanctl_file)
+ swanctl_conf_lines = [
+ f'local_ts = ::/0',
+ f'remote_ts = ::/0',
+ f'updown = "/etc/ipsec.d/vti-up-down {vti}"'
+ ]
+ for line in swanctl_conf_lines:
+ self.assertIn(line, swanctl_conf)
+
+ # Check both TS (IPv4 + IPv6)
+ self.cli_delete(peer_base_path + ['vti', 'traffic-selector'])
+ self.cli_commit()
+ swanctl_conf = read_file(swanctl_file)
+ swanctl_conf_lines = [
+ f'local_ts = 0.0.0.0/0,::/0',
+ f'remote_ts = 0.0.0.0/0,::/0',
+ f'updown = "/etc/ipsec.d/vti-up-down {vti}"'
+ ]
+ for line in swanctl_conf_lines:
+ self.assertIn(line, swanctl_conf)
+
+
def test_dmvpn(self):
ike_lifetime = '3600'
esp_lifetime = '1800'
diff --git a/smoketest/scripts/cli/test_vpn_l2tp.py b/smoketest/scripts/cli/test_vpn_l2tp.py
index 07a7e2906..581ebd35d 100755
--- a/smoketest/scripts/cli/test_vpn_l2tp.py
+++ b/smoketest/scripts/cli/test_vpn_l2tp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_vpn_openconnect.py b/smoketest/scripts/cli/test_vpn_openconnect.py
index dcce229e2..77f37b74d 100755
--- a/smoketest/scripts/cli/test_vpn_openconnect.py
+++ b/smoketest/scripts/cli/test_vpn_openconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_vpn_pptp.py b/smoketest/scripts/cli/test_vpn_pptp.py
index 25d9a4760..f2e9d9868 100755
--- a/smoketest/scripts/cli/test_vpn_pptp.py
+++ b/smoketest/scripts/cli/test_vpn_pptp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_vpn_sstp.py b/smoketest/scripts/cli/test_vpn_sstp.py
index 1a3e1df6e..d1e197246 100755
--- a/smoketest/scripts/cli/test_vpn_sstp.py
+++ b/smoketest/scripts/cli/test_vpn_sstp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 30980f9ec..42c95dd71 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/system/test_config_mount.py b/smoketest/scripts/system/test_config_mount.py
index 657158c39..09a6327e5 100755
--- a/smoketest/scripts/system/test_config_mount.py
+++ b/smoketest/scripts/system/test_config_mount.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/system/test_iproute2.py b/smoketest/scripts/system/test_iproute2.py
index f4fa0f3ba..c720b78b1 100755
--- a/smoketest/scripts/system/test_iproute2.py
+++ b/smoketest/scripts/system/test_iproute2.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/smoketest/scripts/system/test_kernel_options.py b/smoketest/scripts/system/test_kernel_options.py
index b51b0be1d..b418ae172 100755
--- a/smoketest/scripts/system/test_kernel_options.py
+++ b/smoketest/scripts/system/test_kernel_options.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -134,5 +134,32 @@ class TestKernelModules(unittest.TestCase):
tmp = re.findall(f'{option}=y', self._config_data)
self.assertTrue(tmp)
+ def test_amd_pstate(self):
+ # AMD pstate driver required as we have "set system option kernel amd-pstate-driver"
+ for option in ['CONFIG_X86_AMD_PSTATE']:
+ tmp = re.findall(f'{option}=y', self._config_data)
+ self.assertTrue(tmp)
+ for option in ['CONFIG_X86_AMD_PSTATE_DEFAULT_MODE']:
+ tmp = re.findall(f'{option}=3', self._config_data)
+ self.assertTrue(tmp)
+
+ def test_inotify_stackfs(self):
+ for option in ['CONFIG_INOTIFY_USER', 'CONFIG_INOTIFY_STACKFS']:
+ tmp = re.findall(f'{option}=y', self._config_data)
+ self.assertTrue(tmp)
+
+ def test_wwan(self):
+ for option in ['CONFIG_USB_NET_DRIVERS', 'CONFIG_USB_USBNET',
+ 'CONFIG_USB_NET_CDCETHER', 'CONFIG_USB_NET_HUAWEI_CDC_NCM',
+ 'CONFIG_USB_NET_CDC_MBIM', 'CONFIG_USB_NET_QMI_WWAN',
+ 'CONFIG_USB_SIERRA_NET', 'CONFIG_WWAN',
+ 'CONFIG_USB_SERIAL', 'CONFIG_USB_SERIAL_WWAN']:
+ tmp = re.findall(f'{option}=y', self._config_data)
+ self.assertTrue(tmp)
+
+ for option in ['CONFIG_WWAN_HWSIM', 'CONFIG_IOSM', 'CONFIG_MTK_T7XX']:
+ tmp = re.findall(f'{option}=m', self._config_data)
+ self.assertTrue(tmp)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/system/test_module_load.py b/smoketest/scripts/system/test_module_load.py
index fc60c7220..29fbb407d 100755
--- a/smoketest/scripts/system/test_module_load.py
+++ b/smoketest/scripts/system/test_module_load.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/activation-scripts/20-ethernet_offload.py b/src/activation-scripts/20-ethernet_offload.py
index ca7213512..bc1e9f202 100755
--- a/src/activation-scripts/20-ethernet_offload.py
+++ b/src/activation-scripts/20-ethernet_offload.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/completion/list_bgp_neighbors.sh b/src/completion/list_bgp_neighbors.sh
index 869a7ab0a..72c4fcbcb 100755
--- a/src/completion/list_bgp_neighbors.sh
+++ b/src/completion/list_bgp_neighbors.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_container_sysctl_parameters.sh b/src/completion/list_container_sysctl_parameters.sh
index cf8d006e5..6b1402d69 100755
--- a/src/completion/list_container_sysctl_parameters.sh
+++ b/src/completion/list_container_sysctl_parameters.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_ddclient_protocols.sh b/src/completion/list_ddclient_protocols.sh
index 634981660..0c8c2712d 100755
--- a/src/completion/list_ddclient_protocols.sh
+++ b/src/completion/list_ddclient_protocols.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_disks.py b/src/completion/list_disks.py
index 0aa872abb..034f7344c 100755
--- a/src/completion/list_disks.py
+++ b/src/completion/list_disks.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_esi.sh b/src/completion/list_esi.sh
index b8373fa57..e57013672 100755
--- a/src/completion/list_esi.sh
+++ b/src/completion/list_esi.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_images.py b/src/completion/list_images.py
index eae29c084..c545fb882 100755
--- a/src/completion/list_images.py
+++ b/src/completion/list_images.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_ipoe.py b/src/completion/list_ipoe.py
index 5a8f4b0c5..d328816c9 100755
--- a/src/completion/list_ipoe.py
+++ b/src/completion/list_ipoe.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright 2020-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/completion/list_ipsec_profile_tunnels.py b/src/completion/list_ipsec_profile_tunnels.py
index 95a4ca3ce..1f7241699 100644
--- a/src/completion/list_ipsec_profile_tunnels.py
+++ b/src/completion/list_ipsec_profile_tunnels.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_login_ttys.py b/src/completion/list_login_ttys.py
index 4d77a1b8b..dae217aec 100644
--- a/src/completion/list_login_ttys.py
+++ b/src/completion/list_login_ttys.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_openconnect_users.py b/src/completion/list_openconnect_users.py
index db2f4b4da..81952c613 100755
--- a/src/completion/list_openconnect_users.py
+++ b/src/completion/list_openconnect_users.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_openvpn_clients.py b/src/completion/list_openvpn_clients.py
index c1d8eaeb3..24b73f13b 100755
--- a/src/completion/list_openvpn_clients.py
+++ b/src/completion/list_openvpn_clients.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_openvpn_users.py b/src/completion/list_openvpn_users.py
index f2c648476..992926793 100755
--- a/src/completion/list_openvpn_users.py
+++ b/src/completion/list_openvpn_users.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_sysctl_parameters.sh b/src/completion/list_sysctl_parameters.sh
index c111716bb..edabeac6d 100755
--- a/src/completion/list_sysctl_parameters.sh
+++ b/src/completion/list_sysctl_parameters.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/list_vni.sh b/src/completion/list_vni.sh
index f8bd4a993..487313538 100755
--- a/src/completion/list_vni.sh
+++ b/src/completion/list_vni.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/completion/qos/list_traffic_match_group.py b/src/completion/qos/list_traffic_match_group.py
index 015d7ada9..0d0eef77b 100644
--- a/src/completion/qos/list_traffic_match_group.py
+++ b/src/completion/qos/list_traffic_match_group.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index 18d660a4e..4ec9b8849 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -310,12 +310,13 @@ def generate_run_arguments(name, container_config):
memory = container_config['memory']
shared_memory = container_config['shared_memory']
restart = container_config['restart']
+ log_driver = container_config['log_driver']
# Add sysctl options
sysctl_opt = ''
if 'sysctl' in container_config and 'parameter' in container_config['sysctl']:
for k, v in container_config['sysctl']['parameter'].items():
- sysctl_opt += f" --sysctl {k}={v['value']}"
+ sysctl_opt += f" --sysctl \"{k}={v['value']}\""
# Add capability options. Should be in uppercase
capabilities = ''
@@ -324,6 +325,11 @@ def generate_run_arguments(name, container_config):
cap = cap.upper().replace('-', '_')
capabilities += f' --cap-add={cap}'
+ # Grant root capabilities to the container
+ privileged = ''
+ if 'privileged' in container_config:
+ privileged = '--privileged'
+
# Add a host device to the container /dev/x:/dev/x
device = ''
if 'device' in container_config:
@@ -402,8 +408,8 @@ def generate_run_arguments(name, 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} ' \
+ container_base_cmd = f'--detach --interactive --tty --replace {capabilities} {privileged} --cpus {cpu_quota} {sysctl_opt} ' \
+ f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} --log-driver={log_driver} ' \
f'--name {name} {hostname} {device} {port} {name_server} {volume} {tmpfs} {env_opt} {label} {uid} {host_pid}'
entrypoint = ''
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index cebe57092..90fdded99 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -17,6 +17,8 @@
import os
import re
+from glob import glob
+
from sys import exit
from vyos.base import Warning
from vyos.config import Config
@@ -30,6 +32,7 @@ from vyos.firewall import geoip_update
from vyos.template import render
from vyos.utils.dict import dict_search_args
from vyos.utils.dict import dict_search_recursive
+from vyos.utils.file import write_file
from vyos.utils.process import call
from vyos.utils.process import cmd
from vyos.utils.process import rc_cmd
@@ -37,7 +40,6 @@ from vyos.utils.network import get_vrf_members
from vyos.utils.network import get_interface_vrf
from vyos import ConfigError
from vyos import airbag
-from pathlib import Path
from subprocess import run as subp_run
airbag.enable()
@@ -205,7 +207,7 @@ def verify_rule(firewall, family, hook, priority, rule_id, rule_conf):
if 'jump' not in rule_conf['action']:
raise ConfigError('jump-target defined, but action jump needed and it is not defined')
target = rule_conf['jump_target']
- if hook != 'name': # This is a bit clumsy, but consolidates a chunk of code.
+ if hook != 'name': # This is a bit clumsy, but consolidates a chunk of code.
verify_jump_target(firewall, hook, target, family, recursive=True)
else:
verify_jump_target(firewall, hook, target, family, recursive=False)
@@ -268,12 +270,12 @@ def verify_rule(firewall, family, hook, priority, rule_id, rule_conf):
if dict_search_args(rule_conf, 'gre', 'flags', 'checksum') is None:
# There is no builtin match in nftables for the GRE key, so we need to do a raw lookup.
- # The offset of the key within the packet shifts depending on the C-flag.
- # 99% of the time, nobody will have checksums enabled - it's usually a manual config option.
- # We can either assume it is unset unless otherwise directed
+ # The offset of the key within the packet shifts depending on the C-flag.
+ # 99% of the time, nobody will have checksums enabled - it's usually a manual config option.
+ # We can either assume it is unset unless otherwise directed
# (confusing, requires doco to explain why it doesn't work sometimes)
- # or, demand an explicit selection to be made for this specific match rule.
- # This check enforces the latter. The user is free to create rules for both cases.
+ # or, demand an explicit selection to be made for this specific match rule.
+ # This check enforces the latter. The user is free to create rules for both cases.
raise ConfigError('Matching GRE tunnel key requires an explicit checksum flag match. For most cases, use "gre flags checksum unset"')
if dict_search_args(rule_conf, 'gre', 'flags', 'key', 'unset') is not None:
@@ -286,7 +288,7 @@ def verify_rule(firewall, family, hook, priority, rule_id, rule_conf):
if gre_inner_value < 0 or gre_inner_value > 65535:
raise ConfigError('inner-proto outside valid ethertype range 0-65535')
except ValueError:
- pass # Symbolic constant, pre-validated before reaching here.
+ pass # Symbolic constant, pre-validated before reaching here.
tcp_flags = dict_search_args(rule_conf, 'tcp', 'flags')
if tcp_flags:
@@ -437,6 +439,16 @@ def verify(firewall):
for ifname in interfaces:
verify_hardware_offload(ifname)
+ if 'offload' in firewall.get('global_options', {}).get('state_policy', {}):
+ offload_path = firewall['global_options']['state_policy']['offload']
+ if 'offload_target' not in offload_path:
+ raise ConfigError('offload-target must be specified')
+
+ offload_target = offload_path['offload_target']
+
+ if not dict_search_args(firewall, 'flowtable', offload_target):
+ raise ConfigError(f'Invalid offload-target. Flowtable "{offload_target}" does not exist on the system')
+
if 'group' in firewall:
for group_type in nested_group_types:
if group_type in firewall['group']:
@@ -616,10 +628,11 @@ def apply(firewall):
domain_action = 'restart'
if dict_search_args(firewall, 'group', 'remote_group') or dict_search_args(firewall, 'group', 'domain_group') or firewall['ip_fqdn'].items() or firewall['ip6_fqdn'].items():
text = f'# Automatically generated by firewall.py\nThis file indicates that vyos-domain-resolver service is used by the firewall.\n'
- Path(domain_resolver_usage).write_text(text)
+ write_file(domain_resolver_usage, text)
else:
- Path(domain_resolver_usage).unlink(missing_ok=True)
- if not Path('/run').glob('use-vyos-domain-resolver*'):
+ if os.path.exists(domain_resolver_usage):
+ os.unlink(domain_resolver_usage)
+ if not glob('/run/use-vyos-domain-resolver*'):
domain_action = 'stop'
call(f'systemctl {domain_action} vyos-domain-resolver.service')
@@ -627,7 +640,7 @@ def apply(firewall):
# Call helper script to Update set contents
if 'name' in firewall['geoip_updated'] or 'ipv6_name' in firewall['geoip_updated']:
print('Updating GeoIP. Please wait...')
- geoip_update(firewall)
+ geoip_update(firewall=firewall)
return None
diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py
index c726db8b2..005bb6cce 100755
--- a/src/conf_mode/high-availability.py
+++ b/src/conf_mode/high-availability.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_bonding.py b/src/conf_mode/interfaces_bonding.py
index 84316c16e..4a2317f85 100755
--- a/src/conf_mode/interfaces_bonding.py
+++ b/src/conf_mode/interfaces_bonding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_bridge.py b/src/conf_mode/interfaces_bridge.py
index aff93af2a..8cb0c515a 100755
--- a/src/conf_mode/interfaces_bridge.py
+++ b/src/conf_mode/interfaces_bridge.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -25,6 +25,7 @@ from vyos.configdict import has_vlan_subinterface_configured
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_mtu_ipv6
from vyos.ifconfig import BridgeIf
from vyos.configdict import has_address_configured
from vyos.configdict import has_vrf_configured
@@ -110,6 +111,11 @@ def get_config(config=None):
elif interface.startswith('wlan') and interface_exists(interface):
set_dependents('wlan', conf, interface)
+ if interface.startswith('vtun'):
+ _, tmp_config = get_interface_dict(conf, ['interfaces', 'openvpn'], interface)
+ tmp = tmp_config.get('device_type') == 'tap'
+ bridge['member']['interface'][interface].update({'valid_ovpn' : tmp})
+
# delete empty dictionary keys - no need to run code paths if nothing is there to do
if 'member' in bridge:
if 'interface' in bridge['member'] and len(bridge['member']['interface']) == 0:
@@ -136,6 +142,7 @@ def verify(bridge):
verify_dhcpv6(bridge)
verify_vrf(bridge)
+ verify_mtu_ipv6(bridge)
verify_mirror_redirect(bridge)
ifname = bridge['ifname']
@@ -165,6 +172,9 @@ def verify(bridge):
if 'has_vrf' in interface_config:
raise ConfigError(error_msg + 'it has a VRF assigned!')
+ if 'bpdu_guard' in interface_config and 'root_guard' in interface_config:
+ raise ConfigError(error_msg + 'bpdu-guard and root-guard cannot be configured at the same time!')
+
if 'enable_vlan' in bridge:
if 'has_vlan' in interface_config:
raise ConfigError(error_msg + 'it has VLAN subinterface(s) assigned!')
@@ -173,6 +183,9 @@ def verify(bridge):
if option in interface_config:
raise ConfigError('Can not use VLAN options on non VLAN aware bridge')
+ if interface.startswith('vtun') and not interface_config['valid_ovpn']:
+ raise ConfigError(error_msg + 'OpenVPN device-type must be set to "tap"')
+
if 'enable_vlan' in bridge:
if dict_search('vif.1', bridge):
raise ConfigError(f'VLAN 1 sub interface cannot be set for VLAN aware bridge {ifname}, and VLAN 1 is always the parent interface')
diff --git a/src/conf_mode/interfaces_dummy.py b/src/conf_mode/interfaces_dummy.py
index db768b94d..0a83eb23b 100755
--- a/src/conf_mode/interfaces_dummy.py
+++ b/src/conf_mode/interfaces_dummy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_ethernet.py b/src/conf_mode/interfaces_ethernet.py
index 41c89fdf8..b112b244e 100755
--- a/src/conf_mode/interfaces_ethernet.py
+++ b/src/conf_mode/interfaces_ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -22,6 +22,7 @@ from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import is_node_changed
+from vyos.configdict import get_flowtable_interfaces
from vyos.configverify import verify_address
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_interface_exists
@@ -168,6 +169,8 @@ def get_config(config=None):
tmp = is_node_changed(conf, base + [ifname, 'evpn'])
if tmp: ethernet.update({'frr_dict' : get_frrender_dict(conf)})
+ ethernet['flowtable_interfaces'] = get_flowtable_interfaces(conf)
+
return ethernet
def verify_speed_duplex(ethernet: dict, ethtool: Ethtool):
@@ -269,7 +272,38 @@ def verify_allowedbond_changes(ethernet: dict):
f' on interface "{ethernet["ifname"]}".' \
f' Interface is a bond member')
+def verify_flowtable(ethernet: dict):
+ ifname = ethernet['ifname']
+
+ if 'deleted' in ethernet and ifname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{ifname}", still referenced on a flowtable')
+
+ if 'vif_remove' in ethernet:
+ for vif in ethernet['vif_remove']:
+ vifname = f'{ifname}.{vif}'
+
+ if vifname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifname}", still referenced on a flowtable')
+
+ if 'vif_s_remove' in ethernet:
+ for vifs in ethernet['vif_s_remove']:
+ vifsname = f'{ifname}.{vifs}'
+
+ if vifsname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifsname}", still referenced on a flowtable')
+
+ if 'vif_s' in ethernet:
+ for vifs, vifs_conf in ethernet['vif_s'].items():
+ if 'vif_c_delete' in vifs_conf:
+ for vifc in vifs_conf['vif_c_delete']:
+ vifcname = f'{ifname}.{vifs}.{vifc}'
+
+ if vifcname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifcname}", still referenced on a flowtable')
+
def verify(ethernet):
+ verify_flowtable(ethernet)
+
if 'deleted' in ethernet:
return None
if 'is_bond_member' in ethernet:
diff --git a/src/conf_mode/interfaces_geneve.py b/src/conf_mode/interfaces_geneve.py
index 1c5b4d0e7..11b349002 100755
--- a/src/conf_mode/interfaces_geneve.py
+++ b/src/conf_mode/interfaces_geneve.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_input.py b/src/conf_mode/interfaces_input.py
index ad248843d..6ed0bd2cf 100755
--- a/src/conf_mode/interfaces_input.py
+++ b/src/conf_mode/interfaces_input.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_l2tpv3.py b/src/conf_mode/interfaces_l2tpv3.py
index f0a70436e..8eca1cedc 100755
--- a/src/conf_mode/interfaces_l2tpv3.py
+++ b/src/conf_mode/interfaces_l2tpv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_loopback.py b/src/conf_mode/interfaces_loopback.py
index a784e9ec2..bac36b7f0 100755
--- a/src/conf_mode/interfaces_loopback.py
+++ b/src/conf_mode/interfaces_loopback.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_macsec.py b/src/conf_mode/interfaces_macsec.py
index 3ede4377a..683e12ec3 100755
--- a/src/conf_mode/interfaces_macsec.py
+++ b/src/conf_mode/interfaces_macsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_openvpn.py b/src/conf_mode/interfaces_openvpn.py
index a9b4e570d..5cc09da89 100755
--- a/src/conf_mode/interfaces_openvpn.py
+++ b/src/conf_mode/interfaces_openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_pppoe.py b/src/conf_mode/interfaces_pppoe.py
index 412676c7d..976702aba 100755
--- a/src/conf_mode/interfaces_pppoe.py
+++ b/src/conf_mode/interfaces_pppoe.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_pseudo-ethernet.py b/src/conf_mode/interfaces_pseudo-ethernet.py
index 446beffd3..6edd3f248 100755
--- a/src/conf_mode/interfaces_pseudo-ethernet.py
+++ b/src/conf_mode/interfaces_pseudo-ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -27,6 +27,7 @@ from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_mtu_parent
+from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import MACVLANIf
from vyos.utils.network import interface_exists
@@ -71,6 +72,7 @@ def verify(peth):
verify_vrf(peth)
verify_address(peth)
verify_mtu_parent(peth, peth['parent'])
+ verify_mtu_ipv6(peth)
verify_mirror_redirect(peth)
# use common function to verify VLAN configuration
verify_vlan_config(peth)
diff --git a/src/conf_mode/interfaces_sstpc.py b/src/conf_mode/interfaces_sstpc.py
index b9d7a74fb..276fab4f9 100755
--- a/src/conf_mode/interfaces_sstpc.py
+++ b/src/conf_mode/interfaces_sstpc.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_tunnel.py b/src/conf_mode/interfaces_tunnel.py
index ee1436e49..4cf5ef115 100755
--- a/src/conf_mode/interfaces_tunnel.py
+++ b/src/conf_mode/interfaces_tunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_virtual-ethernet.py b/src/conf_mode/interfaces_virtual-ethernet.py
index cb6104f59..f85c3d1de 100755
--- a/src/conf_mode/interfaces_virtual-ethernet.py
+++ b/src/conf_mode/interfaces_virtual-ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -23,6 +23,7 @@ from vyos.configdict import get_interface_dict
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_mtu_ipv6
from vyos.ifconfig import VethIf
from vyos.utils.network import interface_exists
airbag.enable()
@@ -62,6 +63,7 @@ def verify(veth):
return None
verify_vrf(veth)
+ verify_mtu_ipv6(veth)
verify_address(veth)
if 'peer_name' not in veth:
diff --git a/src/conf_mode/interfaces_vti.py b/src/conf_mode/interfaces_vti.py
index 20629c6c1..0461c4f68 100755
--- a/src/conf_mode/interfaces_vti.py
+++ b/src/conf_mode/interfaces_vti.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -20,6 +20,7 @@ from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_mtu_ipv6
from vyos.ifconfig import VTIIf
from vyos import ConfigError
from vyos import airbag
@@ -40,6 +41,7 @@ def get_config(config=None):
def verify(vti):
verify_vrf(vti)
+ verify_mtu_ipv6(vti)
verify_mirror_redirect(vti)
return None
diff --git a/src/conf_mode/interfaces_vxlan.py b/src/conf_mode/interfaces_vxlan.py
index 256b65708..34eb3ef5c 100755
--- a/src/conf_mode/interfaces_vxlan.py
+++ b/src/conf_mode/interfaces_vxlan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_wireguard.py b/src/conf_mode/interfaces_wireguard.py
index 192937dba..33d782ec6 100755
--- a/src/conf_mode/interfaces_wireguard.py
+++ b/src/conf_mode/interfaces_wireguard.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -14,6 +14,9 @@
# 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 glob import glob
from sys import exit
from vyos.config import Config
@@ -35,7 +38,6 @@ from vyos.utils.network import is_wireguard_key_pair
from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
-from pathlib import Path
airbag.enable()
@@ -97,7 +99,7 @@ def verify(wireguard):
if 'port' in wireguard and 'port_changed' in wireguard:
listen_port = int(wireguard['port'])
- if check_port_availability('0.0.0.0', listen_port, 'udp') is not True:
+ if check_port_availability(None, listen_port, protocol='udp') is not True:
raise ConfigError(f'UDP port {listen_port} is busy or unavailable and '
'cannot be used for the interface!')
@@ -145,19 +147,11 @@ def generate(wireguard):
def apply(wireguard):
check_kmod('wireguard')
- if 'rebuild_required' in wireguard or 'deleted' in wireguard:
- wg = WireGuardIf(**wireguard)
- # WireGuard only supports peer removal based on the configured public-key,
- # by deleting the entire interface this is the shortcut instead of parsing
- # out all peers and removing them one by one.
- #
- # Peer reconfiguration will always come with a short downtime while the
- # WireGuard interface is recreated (see below)
- wg.remove()
+ wg = WireGuardIf(**wireguard)
- # Create the new interface if required
- if 'deleted' not in wireguard:
- wg = WireGuardIf(**wireguard)
+ if 'deleted' in wireguard:
+ wg.remove()
+ else:
wg.update(wireguard)
domain_resolver_usage = '/run/use-vyos-domain-resolver-interfaces-wireguard-' + wireguard['ifname']
@@ -168,12 +162,12 @@ def apply(wireguard):
from vyos.utils.file import write_file
text = f'# Automatically generated by interfaces_wireguard.py\nThis file indicates that vyos-domain-resolver service is used by the interfaces_wireguard.\n'
- text += "intefaces:\n" + "".join([f" - {peer}\n" for peer in wireguard['peers_need_resolve']])
- Path(domain_resolver_usage).write_text(text)
+ text += "interfaces:\n" + "".join([f" - {peer}\n" for peer in wireguard['peers_need_resolve']])
write_file(domain_resolver_usage, text)
else:
- Path(domain_resolver_usage).unlink(missing_ok=True)
- if not Path('/run').glob('use-vyos-domain-resolver*'):
+ if os.path.exists(domain_resolver_usage):
+ os.unlink(domain_resolver_usage)
+ if not glob('/run/use-vyos-domain-resolver*'):
domain_action = 'stop'
call(f'systemctl {domain_action} vyos-domain-resolver.service')
diff --git a/src/conf_mode/interfaces_wireless.py b/src/conf_mode/interfaces_wireless.py
index d24675ee6..b3b909046 100755
--- a/src/conf_mode/interfaces_wireless.py
+++ b/src/conf_mode/interfaces_wireless.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/interfaces_wwan.py b/src/conf_mode/interfaces_wwan.py
index 230eb14d6..ddddbe5e8 100755
--- a/src/conf_mode/interfaces_wwan.py
+++ b/src/conf_mode/interfaces_wwan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright 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
@@ -26,8 +26,10 @@ from vyos.configverify import verify_authentication
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_mtu_ipv6
from vyos.ifconfig import WWANIf
from vyos.utils.dict import dict_search
+from vyos.utils.network import is_wwan_connected
from vyos.utils.process import cmd
from vyos.utils.process import call
from vyos.utils.process import DEVNULL
@@ -98,6 +100,7 @@ def verify(wwan):
verify_interface_exists(wwan, ifname)
verify_authentication(wwan)
verify_vrf(wwan)
+ verify_mtu_ipv6(wwan)
verify_mirror_redirect(wwan)
return None
@@ -135,7 +138,7 @@ def apply(wwan):
break
sleep(0.250)
- if 'shutdown_required' in wwan:
+ if 'shutdown_required' in wwan or (not is_wwan_connected(wwan['ifname'])):
# we only need the modem number. wwan0 -> 0, wwan1 -> 1
modem = wwan['ifname'].lstrip('wwan')
base_cmd = f'mmcli --modem {modem}'
@@ -157,7 +160,7 @@ def apply(wwan):
return None
- if 'shutdown_required' in wwan:
+ if 'shutdown_required' in wwan or (not is_wwan_connected(wwan['ifname'])):
ip_type = 'ipv4'
slaac = dict_search('ipv6.address.autoconf', wwan) != None
if 'address' in wwan:
diff --git a/src/conf_mode/load-balancing_haproxy.py b/src/conf_mode/load-balancing_haproxy.py
index 5fd1beec9..4c26ed0b4 100644
--- a/src/conf_mode/load-balancing_haproxy.py
+++ b/src/conf_mode/load-balancing_haproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -19,6 +19,7 @@ import os
from sys import exit
from shutil import rmtree
+from vyos.defaults import systemd_services
from vyos.config import Config
from vyos.configverify import verify_pki_certificate
from vyos.configverify import verify_pki_ca_certificate
@@ -39,7 +40,6 @@ airbag.enable()
load_balancing_dir = '/run/haproxy'
load_balancing_conf_file = f'{load_balancing_dir}/haproxy.cfg'
-systemd_service = 'haproxy.service'
systemd_override = '/run/systemd/system/haproxy.service.d/10-override.conf'
def get_config(config=None):
@@ -65,18 +65,18 @@ def verify(lb):
return None
if 'backend' not in lb or 'service' not in lb:
- raise ConfigError(f'"service" and "backend" must be configured!')
+ raise ConfigError('Both "service" and "backend" must be configured!')
for front, front_config in lb['service'].items():
if 'port' not in front_config:
raise ConfigError(f'"{front} service port" must be configured!')
# Check if bind address:port are used by another service
- tmp_address = front_config.get('address', '0.0.0.0')
+ tmp_address = front_config.get('address', None)
tmp_port = front_config['port']
if check_port_availability(tmp_address, int(tmp_port), 'tcp') is not True and \
not is_listen_port_bind_service(int(tmp_port), 'haproxy'):
- raise ConfigError(f'"TCP" port "{tmp_port}" is used by another service')
+ raise ConfigError(f'TCP port "{tmp_port}" is used by another service')
if 'http_compression' in front_config:
if front_config['mode'] != 'http':
@@ -85,16 +85,19 @@ def verify(lb):
raise ConfigError(f'service {front} must have at least one mime-type configured to use'
f'http_compression!')
+ for cert in dict_search('ssl.certificate', front_config) or []:
+ verify_pki_certificate(lb, cert)
+
for back, back_config in lb['backend'].items():
if 'http_check' in back_config:
http_check = back_config['http_check']
if 'expect' in http_check and 'status' in http_check['expect'] and 'string' in http_check['expect']:
- raise ConfigError(f'"expect status" and "expect string" can not be configured together!')
+ raise ConfigError('"expect status" and "expect string" can not be configured together!')
if 'health_check' in back_config:
if back_config['mode'] != 'tcp':
raise ConfigError(f'backend "{back}" can only be configured with {back_config["health_check"]} ' +
- f'health-check whilst in TCP mode!')
+ 'health-check whilst in TCP mode!')
if 'http_check' in back_config:
raise ConfigError(f'backend "{back}" cannot be configured with both http-check and health-check!')
@@ -112,20 +115,15 @@ def verify(lb):
if {'no_verify', 'ca_certificate'} <= set(back_config['ssl']):
raise ConfigError(f'backend {back} cannot have both ssl options no-verify and ca-certificate set!')
+ tmp = dict_search('ssl.ca_certificate', back_config)
+ if tmp: verify_pki_ca_certificate(lb, tmp)
+
# Check if http-response-headers are configured in any frontend/backend where mode != http
for group in ['service', 'backend']:
for config_name, config in lb[group].items():
if 'http_response_headers' in config and config['mode'] != 'http':
raise ConfigError(f'{group} {config_name} must be set to http mode to use http_response_headers!')
- for front, front_config in lb['service'].items():
- for cert in dict_search('ssl.certificate', front_config) or []:
- verify_pki_certificate(lb, cert)
-
- for back, back_config in lb['backend'].items():
- tmp = dict_search('ssl.ca_certificate', back_config)
- if tmp: verify_pki_ca_certificate(lb, tmp)
-
def generate(lb):
if not lb:
@@ -193,12 +191,11 @@ def generate(lb):
return None
def apply(lb):
+ action = 'stop'
+ if lb:
+ action = 'reload-or-restart'
call('systemctl daemon-reload')
- if not lb:
- call(f'systemctl stop {systemd_service}')
- else:
- call(f'systemctl reload-or-restart {systemd_service}')
-
+ call(f'systemctl {action} {systemd_services["haproxy"]}')
return None
diff --git a/src/conf_mode/load-balancing_wan.py b/src/conf_mode/load-balancing_wan.py
index 92d9acfba..dc7f1c838 100755
--- a/src/conf_mode/load-balancing_wan.py
+++ b/src/conf_mode/load-balancing_wan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 504b3e82a..8763da886 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -16,14 +16,13 @@
import os
+from glob import glob
from sys import exit
-from pathlib import Path
from vyos.base import Warning
from vyos.config import Config
from vyos.configdep import set_dependents, call_dependents
from vyos.template import render
-from vyos.template import is_ip_network
from vyos.utils.kernel import check_kmod
from vyos.utils.dict import dict_search
from vyos.utils.dict import dict_search_args
@@ -31,7 +30,6 @@ from vyos.utils.file import write_file
from vyos.utils.process import cmd
from vyos.utils.process import run
from vyos.utils.process import call
-from vyos.utils.network import is_addr_assigned
from vyos.utils.network import interface_exists
from vyos.firewall import fqdn_config_parse
from vyos import ConfigError
@@ -176,12 +174,6 @@ def verify(nat):
if 'exclude' not in config and 'backend' not in config['load_balance']:
raise ConfigError(f'{err_msg} translation requires address and/or port')
- addr = dict_search('translation.address', config)
- if addr != None and addr != 'masquerade' and not is_ip_network(addr):
- for ip in addr.split('-'):
- if not is_addr_assigned(ip):
- Warning(f'IP address {ip} does not exist on the system!')
-
# common rule verification
verify_rule(config, err_msg, nat['firewall_group'])
@@ -265,9 +257,9 @@ def apply(nat):
text = f'# Automatically generated by nat.py\nThis file indicates that vyos-domain-resolver service is used by nat.\n'
write_file(domain_resolver_usage, text)
elif os.path.exists(domain_resolver_usage):
- Path(domain_resolver_usage).unlink(missing_ok=True)
+ os.unlink(domain_resolver_usage)
- if not Path('/run').glob('use-vyos-domain-resolver*'):
+ if not glob('/run/use-vyos-domain-resolver*'):
domain_action = 'stop'
call(f'systemctl {domain_action} vyos-domain-resolver.service')
diff --git a/src/conf_mode/nat64.py b/src/conf_mode/nat64.py
index df501ce7f..4f8853661 100755
--- a/src/conf_mode/nat64.py
+++ b/src/conf_mode/nat64.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index 95dfae3a5..aea187d18 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -92,6 +92,10 @@ def verify(nat):
if prefix != None:
if not is_ipv6(prefix):
raise ConfigError(f'{err_msg} source-prefix not specified')
+
+ if 'destination' in config and 'group' in config['destination']:
+ if len({'address_group', 'network_group', 'domain_group'} & set(config['destination']['group'])) > 1:
+ raise ConfigError('Only one address-group, network-group or domain-group can be specified')
if dict_search('destination.rule', nat):
for rule, config in dict_search('destination.rule', nat).items():
diff --git a/src/conf_mode/nat_cgnat.py b/src/conf_mode/nat_cgnat.py
index 3484e5873..312688b53 100755
--- a/src/conf_mode/nat_cgnat.py
+++ b/src/conf_mode/nat_cgnat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/netns.py b/src/conf_mode/netns.py
index b57e46a0d..5a3c4e7fa 100755
--- a/src/conf_mode/netns.py
+++ b/src/conf_mode/netns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py
index 724f97555..fa6958130 100755
--- a/src/conf_mode/pki.py
+++ b/src/conf_mode/pki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -19,6 +19,7 @@ import os
from sys import argv
from sys import exit
+from vyos.base import Message
from vyos.config import Config
from vyos.config import config_dict_merge
from vyos.configdep import set_dependents
@@ -27,6 +28,8 @@ from vyos.configdict import node_changed
from vyos.configdiff import Diff
from vyos.configdiff import get_config_diff
from vyos.defaults import directories
+from vyos.defaults import internal_ports
+from vyos.defaults import systemd_services
from vyos.pki import encode_certificate
from vyos.pki import is_ca_certificate
from vyos.pki import load_certificate
@@ -42,9 +45,11 @@ from vyos.utils.dict import dict_search
from vyos.utils.dict import dict_search_args
from vyos.utils.dict import dict_search_recursive
from vyos.utils.file import read_file
+from vyos.utils.network import check_port_availability
from vyos.utils.process import call
from vyos.utils.process import cmd
from vyos.utils.process import is_systemd_service_active
+from vyos.utils.process import is_systemd_service_running
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -59,6 +64,10 @@ sync_search = [
'path': ['service', 'https'],
},
{
+ 'keys': ['key'],
+ 'path': ['service', 'ssh'],
+ },
+ {
'keys': ['certificate', 'ca_certificate'],
'path': ['interfaces', 'ethernet'],
},
@@ -128,8 +137,20 @@ def certbot_request(name: str, config: dict, dry_run: bool=True):
f'--standalone --agree-tos --no-eff-email --expand --server {config["url"]} '\
f'--email {config["email"]} --key-type rsa --rsa-key-size {config["rsa_key_size"]} '\
f'{domains}'
+
+ listen_address = None
if 'listen_address' in config:
- tmp += f' --http-01-address {config["listen_address"]}'
+ listen_address = config['listen_address']
+
+ # When ACME is used behind a reverse proxy, we always bind to localhost
+ # whatever the CLI listen-address is configured for.
+ if ('used_by' in config and 'haproxy' in config['used_by'] and
+ is_systemd_service_running(systemd_services['haproxy']) and
+ not check_port_availability(listen_address, 80)):
+ tmp += f' --http-01-address 127.0.0.1 --http-01-port {internal_ports["certbot_haproxy"]}'
+ elif listen_address:
+ tmp += f' --http-01-address {listen_address}'
+
# verify() does not need to actually request a cert but only test for plausability
if dry_run:
tmp += ' --dry-run'
@@ -150,14 +171,18 @@ def get_config(config=None):
if len(argv) > 1 and argv[1] == 'certbot_renew':
pki['certbot_renew'] = {}
- changed_keys = ['ca', 'certificate', 'dh', 'key-pair', 'openssh', 'openvpn']
+ # Walk through the list of sync_translate mapping and build a list
+ # which is later used to check if the node was changed in the CLI config
+ changed_keys = []
+ for value in sync_translate.values():
+ if value not in changed_keys:
+ changed_keys.append(value)
+ # Check for changes to said given keys in the CLI config
for key in changed_keys:
tmp = node_changed(conf, base + [key], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD)
-
if 'changed' not in pki:
pki.update({'changed':{}})
-
pki['changed'].update({key.replace('-', '_') : tmp})
# We only merge on the defaults of there is a configuration at all
@@ -219,8 +244,8 @@ def get_config(config=None):
continue
path = search['path']
- path_str = ' '.join(path + found_path)
- #print(f'PKI: Updating config: {path_str} {item_name}')
+ path_str = ' '.join(path + found_path).replace('_','-')
+ Message(f'Updating configuration: "{path_str} {item_name}"')
if path[0] == 'interfaces':
ifname = found_path[0]
@@ -230,6 +255,24 @@ def get_config(config=None):
if not D.node_changed_presence(path):
set_dependents(path[1], conf)
+ # Check PKI certificates if they are auto-generated by ACME. If they are,
+ # traverse the current configuration and determine the service where the
+ # certificate is used by.
+ # Required to check if we might need to run certbot behing a reverse proxy.
+ if 'certificate' in pki:
+ for name, cert_config in pki['certificate'].items():
+ if 'acme' not in cert_config:
+ continue
+ if not dict_search('system.load_balancing.haproxy', pki):
+ continue
+ used_by = []
+ for cert_list, _ in dict_search_recursive(
+ pki['system']['load_balancing']['haproxy'], 'certificate'):
+ if name in cert_list:
+ used_by.append('haproxy')
+ if used_by:
+ pki['certificate'][name]['acme'].update({'used_by': used_by})
+
return pki
def is_valid_certificate(raw_data):
@@ -321,6 +364,15 @@ def verify(pki):
raise ConfigError(f'An email address is required to request '\
f'certificate for "{name}" via ACME!')
+ listen_address = None
+ if 'listen_address' in cert_conf['acme']:
+ listen_address = cert_conf['acme']['listen_address']
+
+ if 'used_by' not in cert_conf['acme']:
+ if not check_port_availability(listen_address, 80):
+ raise ConfigError('Port 80 is already in use and not available '\
+ f'to provide ACME challenge for "{name}"!')
+
if 'certbot_renew' not in pki:
# Only run the ACME command if something on this entity changed,
# as this is time intensive
@@ -366,7 +418,8 @@ def verify(pki):
if 'country' in default_values:
country = default_values['country']
if len(country) != 2 or not country.isalpha():
- raise ConfigError(f'Invalid default country value. Value must be 2 alpha characters.')
+ raise ConfigError('Invalid default country value. '\
+ 'Value must be 2 alpha characters.')
if 'changed' in pki:
# if the list is getting longer, we can move to a dict() and also embed the
@@ -374,27 +427,35 @@ def verify(pki):
for search in sync_search:
for key in search['keys']:
changed_key = sync_translate[key]
-
if changed_key not in pki['changed']:
continue
-
for item_name in pki['changed'][changed_key]:
node_present = False
if changed_key == 'openvpn':
node_present = dict_search_args(pki, 'openvpn', 'shared_secret', item_name)
else:
node_present = dict_search_args(pki, changed_key, item_name)
+ # If the node is still present, we can skip the check
+ # as we are not deleting it
+ if node_present:
+ continue
- if not node_present:
- search_dict = dict_search_args(pki['system'], *search['path'])
-
- if not search_dict:
- continue
+ search_dict = dict_search_args(pki['system'], *search['path'])
+ if not search_dict:
+ continue
- for found_name, found_path in dict_search_recursive(search_dict, key):
- if found_name == item_name:
- path_str = " ".join(search['path'] + found_path)
- raise ConfigError(f'PKI object "{item_name}" still in use by "{path_str}"')
+ for found_name, found_path in dict_search_recursive(search_dict, key):
+ # Check if the name matches either by string compare, or beeing
+ # part of a list
+ if ((isinstance(found_name, str) and found_name == item_name) or
+ (isinstance(found_name, list) and item_name in found_name)):
+ # We do not support _ in CLI paths - this is only a convenience
+ # as we mangle all - to _, now it's time to reverse this!
+ path_str = ' '.join(search['path'] + found_path).replace('_','-')
+ object = changed_key.replace('_','-')
+ tmp = f'Embedded PKI {object} with name "{item_name}" is still '\
+ f'in use by CLI path "{path_str}"'
+ raise ConfigError(tmp)
return None
@@ -490,7 +551,7 @@ def generate(pki):
if not ca_cert_present:
tmp = dict_search_args(pki, 'ca', f'{autochain_prefix}{cert}', 'certificate')
if not bool(tmp) or tmp != cert_chain_base64:
- print(f'Adding/replacing automatically imported CA certificate for "{cert}" ...')
+ Message(f'Add/replace automatically imported CA certificate for "{cert}" ...')
add_cli_node(['pki', 'ca', f'{autochain_prefix}{cert}', 'certificate'], value=cert_chain_base64)
return None
diff --git a/src/conf_mode/policy.py b/src/conf_mode/policy.py
index a90e33e81..84962c807 100755
--- a/src/conf_mode/policy.py
+++ b/src/conf_mode/policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -14,6 +14,7 @@
# 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 re
from sys import exit
from vyos.config import Config
@@ -24,9 +25,20 @@ from vyos.frrender import get_frrender_dict
from vyos.utils.dict import dict_search
from vyos.utils.process import is_systemd_service_running
from vyos import ConfigError
+from vyos.base import Warning
from vyos import airbag
airbag.enable()
+# Sanity checks for large-community-list regex:
+# * Require complete 3-tuples, no blank members. Catch missed & doubled colons.
+# * Permit appropriate community separators (whitespace, underscore)
+# * Permit common regex between tuples while requiring at least one separator
+# (eg, "1:1:1_.*_4:4:4", matching "1:1:1 4:4:4" and "1:1:1 2:2:2 4:4:4",
+# but not "1:1:13 24:4:4")
+# Best practice: stick with basic patterns, mind your wildcards and whitespace.
+# Regex that doesn't match this pattern will be allowed with a warning.
+large_community_regex_pattern = r'([^: _]+):([^: _]+):([^: _]+)([ _]([^:]+):([^: _]+):([^: _]+))*'
+
def community_action_compatibility(actions: dict) -> bool:
"""
Check compatibility of values in community and large community sections
@@ -147,6 +159,10 @@ def verify(config_dict):
if 'regex' not in rule_config:
raise ConfigError(f'A regex {mandatory_error}')
+ if policy_type == 'large_community_list':
+ if not re.fullmatch(large_community_regex_pattern, rule_config['regex']):
+ Warning(f'"policy large-community-list {instance} rule {rule} regex" does not follow expected form and may not match as expected.')
+
if policy_type in ['prefix_list', 'prefix_list6']:
if 'prefix' not in rule_config:
raise ConfigError(f'A prefix {mandatory_error}')
diff --git a/src/conf_mode/policy_local-route.py b/src/conf_mode/policy_local-route.py
index 9be2bc227..77b39e59f 100755
--- a/src/conf_mode/policy_local-route.py
+++ b/src/conf_mode/policy_local-route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/policy_route.py b/src/conf_mode/policy_route.py
index 223175b8a..15d735f75 100755
--- a/src/conf_mode/policy_route.py
+++ b/src/conf_mode/policy_route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -21,13 +21,16 @@ from sys import exit
from vyos.base import Warning
from vyos.config import Config
+from vyos.configdiff import get_config_diff, Diff
from vyos.template import render
from vyos.utils.dict import dict_search_args
+from vyos.utils.dict import dict_search_recursive
from vyos.utils.process import cmd
from vyos.utils.process import run
from vyos.utils.network import get_vrf_tableid
from vyos.defaults import rt_global_table
from vyos.defaults import rt_global_vrf
+from vyos.firewall import geoip_update
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -43,6 +46,43 @@ valid_groups = [
'interface_group'
]
+def geoip_updated(conf, policy):
+ diff = get_config_diff(conf)
+ node_diff = diff.get_child_nodes_diff(['policy'], expand_nodes=Diff.DELETE, recursive=True)
+
+ out = {
+ 'name': [],
+ 'ipv6_name': [],
+ 'deleted_name': [],
+ 'deleted_ipv6_name': []
+ }
+ updated = False
+
+ for key, path in dict_search_recursive(policy, 'geoip'):
+ set_name = f'GEOIP_CC_{path[0]}_{path[1]}_{path[3]}'
+ if (path[0] == 'route'):
+ out['name'].append(set_name)
+ elif (path[0] == 'route6'):
+ set_name = f'GEOIP_CC6_{path[0]}_{path[1]}_{path[3]}'
+ out['ipv6_name'].append(set_name)
+
+ updated = True
+
+ if 'delete' in node_diff:
+ for key, path in dict_search_recursive(node_diff['delete'], 'geoip'):
+ set_name = f'GEOIP_CC_{path[0]}_{path[1]}_{path[3]}'
+ if (path[0] == 'route'):
+ out['deleted_name'].append(set_name)
+ elif (path[0] == 'route6'):
+ set_name = f'GEOIP_CC6_{path[0]}_{path[1]}_{path[3]}'
+ out['deleted_ipv6_name'].append(set_name)
+ updated = True
+
+ if updated:
+ return out
+
+ return False
+
def get_config(config=None):
if config:
conf = config
@@ -60,6 +100,7 @@ def get_config(config=None):
if 'dynamic_group' in policy['firewall_group']:
del policy['firewall_group']['dynamic_group']
+ policy['geoip_updated'] = geoip_updated(conf, policy)
return policy
def verify_rule(policy, name, rule_conf, ipv6, rule_id):
@@ -203,6 +244,12 @@ def apply(policy):
apply_table_marks(policy)
+ if policy['geoip_updated']:
+ # Call helper script to Update set contents
+ if 'name' in policy['geoip_updated'] or 'ipv6_name' in policy['geoip_updated']:
+ print('Updating GeoIP. Please wait...')
+ geoip_update(policy=policy)
+
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_babel.py b/src/conf_mode/protocols_babel.py
index 80a847af8..a683031bd 100755
--- a/src/conf_mode/protocols_babel.py
+++ b/src/conf_mode/protocols_babel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_bfd.py b/src/conf_mode/protocols_bfd.py
index d3bc3e961..953611f24 100755
--- a/src/conf_mode/protocols_bfd.py
+++ b/src/conf_mode/protocols_bfd.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 53e83c3b4..bc7925d28 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -413,15 +413,19 @@ def verify(config_dict):
verify_route_map(afi_config['route_map'][tmp], bgp)
if 'route_reflector_client' in afi_config:
- peer_group_as = peer_config.get('remote_as')
+ peer_as = peer_config.get('remote_as')
- if peer_group_as is None or (peer_group_as != 'internal' and peer_group_as != bgp['system_as']):
+ if peer_as is not None and (peer_as != 'internal' and peer_as != bgp['system_as']):
raise ConfigError('route-reflector-client only supported for iBGP peers')
else:
+ # Check into the peer group for the remote as, if we are in a peer group, check in peer itself
if 'peer_group' in peer_config:
peer_group_as = dict_search(f'peer_group.{peer_group}.remote_as', bgp)
- if peer_group_as is None or (peer_group_as != 'internal' and peer_group_as != bgp['system_as']):
- raise ConfigError('route-reflector-client only supported for iBGP peers')
+ elif neighbor == 'peer_group':
+ peer_group_as = peer_config.get('remote_as')
+
+ if peer_group_as is None or (peer_group_as != 'internal' and peer_group_as != bgp['system_as']):
+ raise ConfigError('route-reflector-client only supported for iBGP peers')
# T5833 not all AFIs are supported for VRF
if 'vrf' in bgp and 'address_family' in peer_config:
@@ -523,11 +527,15 @@ def verify(config_dict):
raise ConfigError(
'Please unconfigure import vrf commands before using vpn commands in dependent VRFs!')
+ # Verify if the route-map exists
+ if dict_search('route_map.vrf.import', afi_config) is not None:
+ verify_route_map(afi_config['route_map']['vrf']['import'], bgp)
+
if (dict_search('route_map.vrf.import', afi_config) is not None
or dict_search('import.vrf', afi_config) is not None):
# FRR error: please unconfigure vpn to vrf commands before
# using import vrf commands
- if ('vpn' in afi_config['import']
+ if (dict_search('import.vpn', afi_config) is not None
or dict_search('export.vpn', afi_config) is not None):
raise ConfigError('Please unconfigure VPN to VRF commands before '\
'using "import vrf" commands!')
@@ -537,7 +545,6 @@ def verify(config_dict):
raise ConfigError('Please unconfigure route-map VPN to VRF commands before '\
'using "import vrf" commands!')
-
# Verify that the export/import route-maps do exist
for export_import in ['export', 'import']:
tmp = dict_search(f'route_map.vpn.{export_import}', afi_config)
diff --git a/src/conf_mode/protocols_eigrp.py b/src/conf_mode/protocols_eigrp.py
index 324ff883f..e127a3a07 100755
--- a/src/conf_mode/protocols_eigrp.py
+++ b/src/conf_mode/protocols_eigrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_failover.py b/src/conf_mode/protocols_failover.py
index e7e44db84..9b50cc1ed 100755
--- a/src/conf_mode/protocols_failover.py
+++ b/src/conf_mode/protocols_failover.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_igmp-proxy.py b/src/conf_mode/protocols_igmp-proxy.py
index 9a07adf05..c2d2fea5b 100755
--- a/src/conf_mode/protocols_igmp-proxy.py
+++ b/src/conf_mode/protocols_igmp-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index 1c994492e..8b1408f57 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py
index 33d9a6dae..d534ad2e3 100755
--- a/src/conf_mode/protocols_mpls.py
+++ b/src/conf_mode/protocols_mpls.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py
index ac92c9d99..be08080b1 100755
--- a/src/conf_mode/protocols_nhrp.py
+++ b/src/conf_mode/protocols_nhrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_openfabric.py b/src/conf_mode/protocols_openfabric.py
index 7df11fb20..f490d28bf 100644
--- a/src/conf_mode/protocols_openfabric.py
+++ b/src/conf_mode/protocols_openfabric.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index c06c0aafc..9421765a1 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -17,6 +17,7 @@
from sys import exit
from sys import argv
+from vyos.base import Warning
from vyos.config import Config
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_route_map
@@ -62,6 +63,16 @@ def verify(config_dict):
if 'area' in ospf:
networks = []
for area, area_config in ospf['area'].items():
+ # Implemented as warning to not break existing configurations
+ if area == '0' and dict_search('area_type.nssa', area_config) != None:
+ Warning('You cannot configure NSSA to backbone!')
+ # Implemented as warning to not break existing configurations
+ if area == '0' and dict_search('area_type.stub', area_config) != None:
+ Warning('You cannot configure STUB to backbone!')
+ # Implemented as warning to not break existing configurations
+ if len(area_config['area_type']) > 1:
+ Warning(f'Only one area-type is supported for area "{area}"!')
+
if 'import_list' in area_config:
acl_import = area_config['import_list']
if acl_import: verify_access_list(acl_import, ospf)
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index 2563eb7d5..1d2eceb8f 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_pim.py b/src/conf_mode/protocols_pim.py
index 632099964..bb55aada0 100755
--- a/src/conf_mode/protocols_pim.py
+++ b/src/conf_mode/protocols_pim.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_pim6.py b/src/conf_mode/protocols_pim6.py
index 03a79139a..f7803246a 100755
--- a/src/conf_mode/protocols_pim6.py
+++ b/src/conf_mode/protocols_pim6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py
index ec9dfbb8b..c6adcde5b 100755
--- a/src/conf_mode/protocols_rip.py
+++ b/src/conf_mode/protocols_rip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_ripng.py b/src/conf_mode/protocols_ripng.py
index 9a9ac8ec8..e5babf2e8 100755
--- a/src/conf_mode/protocols_ripng.py
+++ b/src/conf_mode/protocols_ripng.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_rpki.py b/src/conf_mode/protocols_rpki.py
index ef0250e3d..5ba23c141 100755
--- a/src/conf_mode/protocols_rpki.py
+++ b/src/conf_mode/protocols_rpki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -18,6 +18,7 @@ import os
from glob import glob
from sys import exit
+from sys import argv
from vyos.config import Config
from vyos.configverify import has_frr_protocol_in_dict
@@ -39,13 +40,18 @@ def get_config(config=None):
conf = config
else:
conf = Config()
- return get_frrender_dict(conf)
+ return get_frrender_dict(conf, argv)
def verify(config_dict):
if not has_frr_protocol_in_dict(config_dict, 'rpki'):
return None
- rpki = config_dict['rpki']
+ vrf = None
+ if 'vrf_context' in config_dict:
+ vrf = config_dict['vrf_context']
+
+ # eqivalent of the C foo ? 'a' : 'b' statement
+ rpki = vrf and config_dict['vrf']['name'][vrf]['protocols']['rpki'] or config_dict['rpki']
if 'cache' in rpki:
preferences = []
@@ -79,7 +85,12 @@ def generate(config_dict):
if not has_frr_protocol_in_dict(config_dict, 'rpki'):
return None
- rpki = config_dict['rpki']
+ vrf = None
+ if 'vrf_context' in config_dict:
+ vrf = config_dict['vrf_context']
+
+ # eqivalent of the C foo ? 'a' : 'b' statement
+ rpki = vrf and config_dict['vrf']['name'][vrf]['protocols']['rpki'] or config_dict['rpki']
if 'cache' in rpki:
for cache, cache_config in rpki['cache'].items():
diff --git a/src/conf_mode/protocols_segment-routing.py b/src/conf_mode/protocols_segment-routing.py
index f2bd42a79..4020a0917 100755
--- a/src/conf_mode/protocols_segment-routing.py
+++ b/src/conf_mode/protocols_segment-routing.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py
index 1b9e51167..7c730ca81 100755
--- a/src/conf_mode/protocols_static.py
+++ b/src/conf_mode/protocols_static.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_static_arp.py b/src/conf_mode/protocols_static_arp.py
index b141f1141..87dc5229e 100755
--- a/src/conf_mode/protocols_static_arp.py
+++ b/src/conf_mode/protocols_static_arp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/protocols_static_neighbor-proxy.py b/src/conf_mode/protocols_static_neighbor-proxy.py
index 8a1ea1df9..bda737e75 100755
--- a/src/conf_mode/protocols_static_neighbor-proxy.py
+++ b/src/conf_mode/protocols_static_neighbor-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py
index 59e307a39..326d617a2 100755
--- a/src/conf_mode/qos.py
+++ b/src/conf_mode/qos.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -85,7 +85,13 @@ def _clean_conf_dict(conf):
}
"""
if isinstance(conf, dict):
- return {node: _clean_conf_dict(val) for node, val in conf.items() if val != {} and _clean_conf_dict(val) != {}}
+ preserve_empty_nodes = {'syn', 'ack'}
+
+ return {
+ node: _clean_conf_dict(val)
+ for node, val in conf.items()
+ if (val != {} and _clean_conf_dict(val) != {}) or node in preserve_empty_nodes
+ }
else:
return conf
diff --git a/src/conf_mode/service_aws_glb.py b/src/conf_mode/service_aws_glb.py
index d1ed5a07b..aa5ec5ebe 100755
--- a/src/conf_mode/service_aws_glb.py
+++ b/src/conf_mode/service_aws_glb.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_broadcast-relay.py b/src/conf_mode/service_broadcast-relay.py
index d35954718..f7f2875f5 100755
--- a/src/conf_mode/service_broadcast-relay.py
+++ b/src/conf_mode/service_broadcast-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_config-sync.py b/src/conf_mode/service_config-sync.py
index 4b8a7f6ee..32001ce57 100755
--- a/src/conf_mode/service_config-sync.py
+++ b/src/conf_mode/service_config-sync.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_conntrack-sync.py b/src/conf_mode/service_conntrack-sync.py
index 3a233a172..5eb4ca0e5 100755
--- a/src/conf_mode/service_conntrack-sync.py
+++ b/src/conf_mode/service_conntrack-sync.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
index b83c6dfb1..82386babf 100755
--- a/src/conf_mode/service_console-server.py
+++ b/src/conf_mode/service_console-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_dhcp-relay.py b/src/conf_mode/service_dhcp-relay.py
index 37d708847..ebdf5e8ee 100755
--- a/src/conf_mode/service_dhcp-relay.py
+++ b/src/conf_mode/service_dhcp-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_dhcp-server.py b/src/conf_mode/service_dhcp-server.py
index 5a729af74..6bbe72e90 100755
--- a/src/conf_mode/service_dhcp-server.py
+++ b/src/conf_mode/service_dhcp-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -41,9 +41,9 @@ from vyos import airbag
airbag.enable()
-ctrl_config_file = '/run/kea/kea-ctrl-agent.conf'
ctrl_socket = '/run/kea/dhcp4-ctrl-socket'
config_file = '/run/kea/kea-dhcp4.conf'
+config_file_d2 = '/run/kea/kea-dhcp-ddns.conf'
lease_file = '/config/dhcp/dhcp4-leases.csv'
lease_file_glob = '/config/dhcp/dhcp4-leases*'
user_group = '_kea'
@@ -171,6 +171,15 @@ def get_config(config=None):
return dhcp
+def verify_ddns_domain_servers(domain_type, domain):
+ if 'dns_server' in domain:
+ invalid_servers = []
+ for server_no, server_config in domain['dns_server'].items():
+ if 'address' not in server_config:
+ invalid_servers.append(server_no)
+ if len(invalid_servers) > 0:
+ raise ConfigError(f'{domain_type} DNS servers {", ".join(invalid_servers)} in DDNS configuration need to have an IP address')
+ return None
def verify(dhcp):
# bail out early - looks like removal from running config
@@ -423,6 +432,22 @@ def verify(dhcp):
if not interface_exists(interface):
raise ConfigError(f'listen-interface "{interface}" does not exist')
+ if 'dynamic_dns_update' in dhcp:
+ ddns = dhcp['dynamic_dns_update']
+ if 'tsig_key' in ddns:
+ invalid_keys = []
+ for tsig_key_name, tsig_key_config in ddns['tsig_key'].items():
+ if not ('algorithm' in tsig_key_config and 'secret' in tsig_key_config):
+ invalid_keys.append(tsig_key_name)
+ if len(invalid_keys) > 0:
+ raise ConfigError(f'Both algorithm and secret need to be set for TSIG keys: {", ".join(invalid_keys)}')
+
+ if 'forward_domain' in ddns:
+ verify_ddns_domain_servers('Forward', ddns['forward_domain'])
+
+ if 'reverse_domain' in ddns:
+ verify_ddns_domain_servers('Reverse', ddns['reverse_domain'])
+
return None
@@ -480,25 +505,26 @@ def generate(dhcp):
dhcp['high_availability']['ca_cert_file'] = ca_cert_file
render(
- ctrl_config_file,
- 'dhcp-server/kea-ctrl-agent.conf.j2',
- dhcp,
- user=user_group,
- group=user_group,
- )
- render(
config_file,
'dhcp-server/kea-dhcp4.conf.j2',
dhcp,
user=user_group,
group=user_group,
)
+ if 'dynamic_dns_update' in dhcp:
+ render(
+ config_file_d2,
+ 'dhcp-server/kea-dhcp-ddns.conf.j2',
+ dhcp,
+ user=user_group,
+ group=user_group
+ )
return None
def apply(dhcp):
- services = ['kea-ctrl-agent', 'kea-dhcp4-server', 'kea-dhcp-ddns-server']
+ services = ['kea-dhcp4-server', 'kea-dhcp-ddns-server']
if not dhcp or 'disable' in dhcp:
for service in services:
@@ -515,9 +541,6 @@ def apply(dhcp):
if service == 'kea-dhcp-ddns-server' and 'dynamic_dns_update' not in dhcp:
action = 'stop'
- if service == 'kea-ctrl-agent' and 'high_availability' not in dhcp:
- action = 'stop'
-
call(f'systemctl {action} {service}.service')
return None
diff --git a/src/conf_mode/service_dhcpv6-relay.py b/src/conf_mode/service_dhcpv6-relay.py
index 6537ca3c2..4547b608c 100755
--- a/src/conf_mode/service_dhcpv6-relay.py
+++ b/src/conf_mode/service_dhcpv6-relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_dhcpv6-server.py b/src/conf_mode/service_dhcpv6-server.py
index 7af88007c..07dd08337 100755
--- a/src/conf_mode/service_dhcpv6-server.py
+++ b/src/conf_mode/service_dhcpv6-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_dns_dynamic.py b/src/conf_mode/service_dns_dynamic.py
index 5f5303856..b321d5f51 100755
--- a/src/conf_mode/service_dns_dynamic.py
+++ b/src/conf_mode/service_dns_dynamic.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_dns_forwarding.py b/src/conf_mode/service_dns_forwarding.py
index 5636d6f83..cd0c6a38a 100755
--- a/src/conf_mode/service_dns_forwarding.py
+++ b/src/conf_mode/service_dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_event-handler.py b/src/conf_mode/service_event-handler.py
index 5028ef52f..1b9e7ff53 100755
--- a/src/conf_mode/service_event-handler.py
+++ b/src/conf_mode/service_event-handler.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_https.py b/src/conf_mode/service_https.py
index 9e58b4c72..38bb485e7 100755
--- a/src/conf_mode/service_https.py
+++ b/src/conf_mode/service_https.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -28,6 +28,7 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_pki_certificate
from vyos.configverify import verify_pki_ca_certificate
from vyos.configverify import verify_pki_dh_parameters
+from vyos.configdiff import get_config_diff
from vyos.defaults import api_config_state
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
@@ -79,6 +80,14 @@ def get_config(config=None):
# merge CLI and default dictionary
https = config_dict_merge(default_values, https)
+
+ # some settings affecting nginx will require a restart:
+ # for example, a reload will not suffice when binding the listen address
+ # after nginx has started and dropped privileges; add flag here
+ diff = get_config_diff(conf)
+ children_changed = diff.node_changed_children(base)
+ https['nginx_restart_required'] = bool(set(children_changed) != set(['api']))
+
return https
def verify(https):
@@ -208,7 +217,10 @@ def apply(https):
elif is_systemd_service_active(http_api_service_name):
call(f'systemctl stop {http_api_service_name}')
- call(f'systemctl reload-or-restart {https_service_name}')
+ if https['nginx_restart_required']:
+ call(f'systemctl restart {https_service_name}')
+ else:
+ call(f'systemctl reload-or-restart {https_service_name}')
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/service_ids_ddos-protection.py b/src/conf_mode/service_ids_ddos-protection.py
deleted file mode 100755
index 276a71fcb..000000000
--- a/src/conf_mode/service_ids_ddos-protection.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
-#
-# 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.template import render
-from vyos.utils.process import call
-from vyos import ConfigError
-from vyos import airbag
-airbag.enable()
-
-config_file = r'/run/fastnetmon/fastnetmon.conf'
-networks_list = r'/run/fastnetmon/networks_list'
-excluded_networks_list = r'/run/fastnetmon/excluded_networks_list'
-attack_dir = '/var/log/fastnetmon_attacks'
-
-def get_config(config=None):
- if config:
- conf = config
- else:
- conf = Config()
- base = ['service', 'ids', 'ddos-protection']
- if not conf.exists(base):
- return None
-
- fastnetmon = conf.get_config_dict(base, key_mangling=('-', '_'),
- get_first_key=True,
- with_recursive_defaults=True)
-
- return fastnetmon
-
-def verify(fastnetmon):
- if not fastnetmon:
- return None
-
- if 'mode' not in fastnetmon:
- raise ConfigError('Specify operating mode!')
-
- if fastnetmon.get('mode') == 'mirror' and 'listen_interface' not in fastnetmon:
- raise ConfigError("Incorrect settings for 'mode mirror': must specify interface(s) for traffic mirroring")
-
- if fastnetmon.get('mode') == 'sflow' and 'listen_address' not in fastnetmon.get('sflow', {}):
- raise ConfigError("Incorrect settings for 'mode sflow': must specify sFlow 'listen-address'")
-
- if 'alert_script' in fastnetmon:
- if os.path.isfile(fastnetmon['alert_script']):
- # Check script permissions
- if not os.access(fastnetmon['alert_script'], os.X_OK):
- raise ConfigError('Script "{alert_script}" is not executable!'.format(fastnetmon['alert_script']))
- else:
- raise ConfigError('File "{alert_script}" does not exists!'.format(fastnetmon))
-
-def generate(fastnetmon):
- if not fastnetmon:
- for file in [config_file, networks_list]:
- if os.path.isfile(file):
- os.unlink(file)
-
- return None
-
- # Create dir for log attack details
- if not os.path.exists(attack_dir):
- os.mkdir(attack_dir)
-
- render(config_file, 'ids/fastnetmon.j2', fastnetmon)
- render(networks_list, 'ids/fastnetmon_networks_list.j2', fastnetmon)
- render(excluded_networks_list, 'ids/fastnetmon_excluded_networks_list.j2', fastnetmon)
- return None
-
-def apply(fastnetmon):
- systemd_service = 'fastnetmon.service'
- if not fastnetmon:
- # Stop fastnetmon service if removed
- call(f'systemctl stop {systemd_service}')
- else:
- call(f'systemctl reload-or-restart {systemd_service}')
-
- return None
-
-if __name__ == '__main__':
- try:
- c = get_config()
- verify(c)
- generate(c)
- apply(c)
- except ConfigError as e:
- print(e)
- exit(1)
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index a14d4b5b6..50628947e 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -88,6 +88,12 @@ def verify(ipoe):
'Can configure username with Lua script only for RADIUS authentication'
)
+ if dict_search('external_dhcp.dhcp_relay', iface_config):
+ if not dict_search('external_dhcp.giaddr', iface_config):
+ raise ConfigError(
+ f'"external-dhcp dhcp-relay" requires "giaddr" to be set for interface {interface}'
+ )
+
verify_accel_ppp_authentication(ipoe, local_users=False)
verify_accel_ppp_ip_pool(ipoe)
verify_accel_ppp_name_servers(ipoe)
diff --git a/src/conf_mode/service_lldp.py b/src/conf_mode/service_lldp.py
index 04b1db880..50e9a49e6 100755
--- a/src/conf_mode/service_lldp.py
+++ b/src/conf_mode/service_lldp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_mdns_repeater.py b/src/conf_mode/service_mdns_repeater.py
index b0ece031c..360b94588 100755
--- a/src/conf_mode/service_mdns_repeater.py
+++ b/src/conf_mode/service_mdns_repeater.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_monitoring_network_event.py b/src/conf_mode/service_monitoring_network_event.py
index 104e6ce23..f43ea23ca 100644
--- a/src/conf_mode/service_monitoring_network_event.py
+++ b/src/conf_mode/service_monitoring_network_event.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_monitoring_prometheus.py b/src/conf_mode/service_monitoring_prometheus.py
index 9a07d8593..b02f9f154 100755
--- a/src/conf_mode/service_monitoring_prometheus.py
+++ b/src/conf_mode/service_monitoring_prometheus.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
@@ -23,6 +23,7 @@ from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.template import render
from vyos.utils.process import call
+from vyos.utils.process import is_systemd_service_active
from vyos import ConfigError
from vyos import airbag
@@ -48,9 +49,21 @@ def get_config(config=None):
if not conf.exists(base):
return None
- monitoring = conf.get_config_dict(
- base, key_mangling=('-', '_'), get_first_key=True, with_recursive_defaults=True
- )
+ monitoring = {}
+ exporters = {
+ 'node_exporter': base + ['node-exporter'],
+ 'frr_exporter': base + ['frr-exporter'],
+ 'blackbox_exporter': base + ['blackbox-exporter'],
+ }
+
+ for exporter_name, exporter_base in exporters.items():
+ if conf.exists(exporter_base):
+ monitoring[exporter_name] = conf.get_config_dict(
+ exporter_base,
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ with_recursive_defaults=True,
+ )
tmp = is_node_changed(conf, base + ['node-exporter', 'vrf'])
if tmp:
@@ -161,11 +174,14 @@ def apply(monitoring):
# Reload systemd manager configuration
call('systemctl daemon-reload')
if not monitoring or 'node_exporter' not in monitoring:
- call(f'systemctl stop {node_exporter_systemd_service}')
+ if is_systemd_service_active(node_exporter_systemd_service):
+ call(f'systemctl stop {node_exporter_systemd_service}')
if not monitoring or 'frr_exporter' not in monitoring:
- call(f'systemctl stop {frr_exporter_systemd_service}')
+ if is_systemd_service_active(frr_exporter_systemd_service):
+ call(f'systemctl stop {frr_exporter_systemd_service}')
if not monitoring or 'blackbox_exporter' not in monitoring:
- call(f'systemctl stop {blackbox_exporter_systemd_service}')
+ if is_systemd_service_active(blackbox_exporter_systemd_service):
+ call(f'systemctl stop {blackbox_exporter_systemd_service}')
if not monitoring:
return
diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py
index db870aae5..de8097e11 100755
--- a/src/conf_mode/service_monitoring_telegraf.py
+++ b/src/conf_mode/service_monitoring_telegraf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_monitoring_zabbix-agent.py b/src/conf_mode/service_monitoring_zabbix-agent.py
index f17146a8d..5f3a8d4b5 100755
--- a/src/conf_mode/service_monitoring_zabbix-agent.py
+++ b/src/conf_mode/service_monitoring_zabbix-agent.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_ndp-proxy.py b/src/conf_mode/service_ndp-proxy.py
index 024ad79f2..f42ee9be8 100755
--- a/src/conf_mode/service_ndp-proxy.py
+++ b/src/conf_mode/service_ndp-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_ntp.py b/src/conf_mode/service_ntp.py
index 32563aa0e..fbdcd6b58 100755
--- a/src/conf_mode/service_ntp.py
+++ b/src/conf_mode/service_ntp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py
index ac697c509..d910e770d 100755
--- a/src/conf_mode/service_pppoe-server.py
+++ b/src/conf_mode/service_pppoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -73,7 +73,9 @@ def get_config(config=None):
# https://phabricator.accel-ppp.org/T3
conditions = [is_node_changed(conf, base + ['client-ip-pool']),
is_node_changed(conf, base + ['client-ipv6-pool']),
- is_node_changed(conf, base + ['interface'])]
+ is_node_changed(conf, base + ['interface']),
+ is_node_changed(conf, base + ['authentication','radius','dynamic-author']),
+ is_node_changed(conf, base + ['authentication','mode'])]
if any(conditions):
pppoe.update({'restart_required': {}})
pppoe['server_type'] = 'pppoe'
diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py
index 88d767bb8..4345bea1d 100755
--- a/src/conf_mode/service_router-advert.py
+++ b/src/conf_mode/service_router-advert.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_salt-minion.py b/src/conf_mode/service_salt-minion.py
index edf74b0c0..9e9940175 100755
--- a/src/conf_mode/service_salt-minion.py
+++ b/src/conf_mode/service_salt-minion.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_sla.py b/src/conf_mode/service_sla.py
index ba5e645f0..0a7b81073 100755
--- a/src/conf_mode/service_sla.py
+++ b/src/conf_mode/service_sla.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_snmp.py b/src/conf_mode/service_snmp.py
index c64c59af7..c6059c260 100755
--- a/src/conf_mode/service_snmp.py
+++ b/src/conf_mode/service_snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_ssh.py b/src/conf_mode/service_ssh.py
index 759f87bb2..bf8afe8b7 100755
--- a/src/conf_mode/service_ssh.py
+++ b/src/conf_mode/service_ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -23,14 +23,15 @@ from syslog import LOG_INFO
from vyos.config import Config
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
-from vyos.configverify import verify_pki_ca_certificate
+from vyos.configverify import verify_pki_openssh_key
+from vyos.defaults import config_files
from vyos.utils.process import call
from vyos.template import render
from vyos import ConfigError
from vyos import airbag
-from vyos.pki import find_chain
-from vyos.pki import encode_certificate
-from vyos.pki import load_certificate
+from vyos.pki import encode_public_key
+from vyos.pki import load_openssh_public_key
+from vyos.utils.dict import dict_search_recursive
from vyos.utils.file import write_file
airbag.enable()
@@ -44,8 +45,7 @@ key_rsa = '/etc/ssh/ssh_host_rsa_key'
key_dsa = '/etc/ssh/ssh_host_dsa_key'
key_ed25519 = '/etc/ssh/ssh_host_ed25519_key'
-trusted_user_ca_key = '/etc/ssh/trusted_user_ca_key'
-
+trusted_user_ca = config_files['sshd_user_ca']
def get_config(config=None):
if config:
@@ -55,10 +55,8 @@ def get_config(config=None):
base = ['service', 'ssh']
if not conf.exists(base):
return None
-
- ssh = conf.get_config_dict(
- base, key_mangling=('-', '_'), get_first_key=True, with_pki=True
- )
+ ssh = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True, with_pki=True)
tmp = is_node_changed(conf, base + ['vrf'])
if tmp:
@@ -68,14 +66,27 @@ def get_config(config=None):
# options which we need to update into the dictionary retrived.
ssh = conf.merge_defaults(ssh, recursive=True)
- # pass config file path - used in override template
- ssh['config_file'] = config_file
-
# Ignore default XML values if config doesn't exists
# Delete key from dict
if not conf.exists(base + ['dynamic-protection']):
del ssh['dynamic_protection']
+ # See if any user has specified a list of principal names that are accepted
+ # for certificate authentication.
+ tmp = conf.get_config_dict(['system', 'login', 'user'],
+ key_mangling=('-', '_'),
+ no_tag_node_value_mangle=True,
+ get_first_key=True)
+
+ for value, _ in dict_search_recursive(tmp, 'principal'):
+ # Only enable principal handling if SSH trusted-user-ca is set
+ if 'trusted_user_ca' in ssh:
+ ssh['has_principals'] = {}
+ # We do only need to execute this code path once as we need to know
+ # if any one of the local users has a principal set or not - this
+ # accounts for the entire system.
+ break
+
return ssh
@@ -86,15 +97,8 @@ def verify(ssh):
if 'rekey' in ssh and 'data' not in ssh['rekey']:
raise ConfigError('Rekey data is required!')
- if 'trusted_user_ca_key' in ssh:
- if 'ca_certificate' not in ssh['trusted_user_ca_key']:
- raise ConfigError('CA certificate is required for TrustedUserCAKey')
-
- ca_key_name = ssh['trusted_user_ca_key']['ca_certificate']
- verify_pki_ca_certificate(ssh, ca_key_name)
- pki_ca_cert = ssh['pki']['ca'][ca_key_name]
- if 'certificate' not in pki_ca_cert or not pki_ca_cert['certificate']:
- raise ConfigError(f"CA certificate '{ca_key_name}' is not valid or missing")
+ if 'trusted_user_ca' in ssh:
+ verify_pki_openssh_key(ssh, ssh['trusted_user_ca'])
verify_vrf(ssh)
return None
@@ -119,23 +123,17 @@ def generate(ssh):
syslog(LOG_INFO, 'SSH ed25519 host key not found, generating new key!')
call(f'ssh-keygen -q -N "" -t ed25519 -f {key_ed25519}')
- if 'trusted_user_ca_key' in ssh:
- ca_key_name = ssh['trusted_user_ca_key']['ca_certificate']
- pki_ca_cert = ssh['pki']['ca'][ca_key_name]
-
- loaded_ca_cert = load_certificate(pki_ca_cert['certificate'])
- loaded_ca_certs = {
- load_certificate(c['certificate'])
- for c in ssh['pki']['ca'].values()
- if 'certificate' in c
- }
-
- ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs)
- write_file(
- trusted_user_ca_key, '\n'.join(encode_certificate(c) for c in ca_full_chain)
- )
- elif os.path.exists(trusted_user_ca_key):
- os.unlink(trusted_user_ca_key)
+ if 'trusted_user_ca' in ssh:
+ key_name = ssh['trusted_user_ca']
+ openssh_cert = ssh['pki']['openssh'][key_name]
+ loaded_ca_cert = load_openssh_public_key(openssh_cert['public']['key'],
+ openssh_cert['public']['type'])
+ tmp = encode_public_key(loaded_ca_cert, encoding='OpenSSH',
+ key_format='OpenSSH')
+ write_file(trusted_user_ca, tmp, trailing_newline=True)
+ else:
+ if os.path.exists(trusted_user_ca):
+ os.unlink(trusted_user_ca)
render(config_file, 'ssh/sshd_config.j2', ssh)
diff --git a/src/conf_mode/service_stunnel.py b/src/conf_mode/service_stunnel.py
index 8ec762548..eb1d4dea2 100644
--- a/src/conf_mode/service_stunnel.py
+++ b/src/conf_mode/service_stunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_suricata.py b/src/conf_mode/service_suricata.py
index 1ce170145..728c5607e 100755
--- a/src/conf_mode/service_suricata.py
+++ b/src/conf_mode/service_suricata.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_tftp-server.py b/src/conf_mode/service_tftp-server.py
index 5b7303c40..dc5ec5674 100755
--- a/src/conf_mode/service_tftp-server.py
+++ b/src/conf_mode/service_tftp-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/service_webproxy.py b/src/conf_mode/service_webproxy.py
index 12ae4135e..7a4954de2 100755
--- a/src/conf_mode/service_webproxy.py
+++ b/src/conf_mode/service_webproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_acceleration.py b/src/conf_mode/system_acceleration.py
index d2cf44ff0..954bf8bba 100755
--- a/src/conf_mode/system_acceleration.py
+++ b/src/conf_mode/system_acceleration.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_config-management.py b/src/conf_mode/system_config-management.py
index a3ce66512..c1d83af34 100755
--- a/src/conf_mode/system_config-management.py
+++ b/src/conf_mode/system_config-management.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py
index f25ed8d10..eed1a4458 100755
--- a/src/conf_mode/system_conntrack.py
+++ b/src/conf_mode/system_conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -32,7 +32,6 @@ from vyos import ConfigError
from vyos import airbag
airbag.enable()
-conntrack_config = r'/etc/modprobe.d/vyatta_nf_conntrack.conf'
sysctl_file = r'/run/sysctl/10-vyos-conntrack.conf'
nftables_ct_file = r'/run/nftables-ct.conf'
vyos_conntrack_logger_config = r'/run/vyos-conntrack-logger.conf'
@@ -204,7 +203,6 @@ def generate(conntrack):
elif path[0] == 'ipv6':
conntrack['ipv6_firewall_action'] = 'accept'
- render(conntrack_config, 'conntrack/vyos_nf_conntrack.conf.j2', conntrack)
render(sysctl_file, 'conntrack/sysctl.conf.j2', conntrack)
render(nftables_ct_file, 'conntrack/nftables-ct.j2', conntrack)
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index b380e0521..90648e2b8 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_flow-accounting.py b/src/conf_mode/system_flow-accounting.py
index 925c4a562..618227fc0 100755
--- a/src/conf_mode/system_flow-accounting.py
+++ b/src/conf_mode/system_flow-accounting.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py
index d9ac543d0..06af37ad8 100755
--- a/src/conf_mode/system_frr.py
+++ b/src/conf_mode/system_frr.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_host-name.py b/src/conf_mode/system_host-name.py
index fef034d1c..2a5592484 100755
--- a/src/conf_mode/system_host-name.py
+++ b/src/conf_mode/system_host-name.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -175,7 +175,7 @@ def apply(config):
# Restart services that use the hostname
if hostname_new != hostname_old:
- tmp = systemd_services['rsyslog']
+ tmp = systemd_services['syslog']
call(f'systemctl restart {tmp}')
# If SNMP is running, restart it too
diff --git a/src/conf_mode/system_ip.py b/src/conf_mode/system_ip.py
index 7f3796168..13471eb3b 100755
--- a/src/conf_mode/system_ip.py
+++ b/src/conf_mode/system_ip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -53,6 +53,11 @@ def verify(config_dict):
for protocol, protocol_options in opt['protocol'].items():
if 'route_map' in protocol_options:
verify_route_map(protocol_options['route_map'], opt)
+
+ if dict_search('import_table', opt):
+ for table_num, import_config in opt['import_table'].items():
+ if dict_search('route_map', import_config):
+ verify_route_map(import_config['route_map'], opt)
return
def generate(config_dict):
diff --git a/src/conf_mode/system_ipv6.py b/src/conf_mode/system_ipv6.py
index 309869b2f..35f343d82 100755
--- a/src/conf_mode/system_ipv6.py
+++ b/src/conf_mode/system_ipv6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_lcd.py b/src/conf_mode/system_lcd.py
index eb88224d1..1e97414dc 100755
--- a/src/conf_mode/system_lcd.py
+++ b/src/conf_mode/system_lcd.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 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
diff --git a/src/conf_mode/system_login.py b/src/conf_mode/system_login.py
index 4febb6494..00cacccd1 100755
--- a/src/conf_mode/system_login.py
+++ b/src/conf_mode/system_login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -26,6 +26,8 @@ from time import sleep
from vyos.base import Warning
from vyos.config import Config
+from vyos.configdep import set_dependents
+from vyos.configdep import call_dependents
from vyos.configverify import verify_vrf
from vyos.template import render
from vyos.template import is_ipv4
@@ -129,6 +131,7 @@ def get_config(config=None):
max_uid=MIN_TACACS_UID) + cli_users
login['tacacs_min_uid'] = MIN_TACACS_UID
+ set_dependents('ssh', conf)
return login
def verify(login):
@@ -345,6 +348,17 @@ def apply(login):
user_config, permission=0o600,
formater=lambda _: _.replace("&quot;", '"'),
user=user, group='users')
+
+ principals_file = f'{home_dir}/.ssh/authorized_principals'
+ if dict_search('authentication.principal', user_config):
+ render(principals_file, 'login/authorized_principals.j2',
+ user_config, permission=0o600,
+ formater=lambda _: _.replace("&quot;", '"'),
+ user=user, group='users')
+ else:
+ if os.path.exists(principals_file):
+ os.unlink(principals_file)
+
except Exception as e:
raise ConfigError(f'Adding user "{user}" raised exception: "{e}"')
@@ -361,14 +375,15 @@ def apply(login):
chown(home_dir, user=user, recursive=True)
# Generate 2FA/MFA One-Time-Pad configuration
+ google_auth_file = f'{home_dir}/.google_authenticator'
if dict_search('authentication.otp.key', user_config):
enable_otp = True
- render(f'{home_dir}/.google_authenticator', 'login/pam_otp_ga.conf.j2',
+ render(google_auth_file, 'login/pam_otp_ga.conf.j2',
user_config, permission=0o400, user=user, group='users')
else:
# delete configuration as it's not enabled for the user
- if os.path.exists(f'{home_dir}/.google_authenticator'):
- os.remove(f'{home_dir}/.google_authenticator')
+ if os.path.exists(google_auth_file):
+ os.unlink(google_auth_file)
# Lock/Unlock local user account
lock_unlock = '--unlock'
@@ -382,6 +397,22 @@ def apply(login):
# Disable user to prevent re-login
call(f'usermod -s /sbin/nologin {user}')
+ home_dir = getpwnam(user).pw_dir
+ # Remove SSH authorized keys file
+ authorized_keys_file = f'{home_dir}/.ssh/authorized_keys'
+ if os.path.exists(authorized_keys_file):
+ os.unlink(authorized_keys_file)
+
+ # Remove SSH authorized principals file
+ principals_file = f'{home_dir}/.ssh/authorized_principals'
+ if os.path.exists(principals_file):
+ os.unlink(principals_file)
+
+ # Remove Google Authenticator file
+ google_auth_file = f'{home_dir}/.google_authenticator'
+ if os.path.exists(google_auth_file):
+ os.unlink(google_auth_file)
+
# Logout user if he is still logged in
if user in list(set([tmp[0] for tmp in users()])):
print(f'{user} is logged in, forcing logout!')
@@ -420,8 +451,9 @@ def apply(login):
# Enable/disable Google authenticator
cmd('pam-auth-update --disable mfa-google-authenticator')
if enable_otp:
- cmd(f'pam-auth-update --enable mfa-google-authenticator')
+ cmd('pam-auth-update --enable mfa-google-authenticator')
+ call_dependents()
return None
diff --git a/src/conf_mode/system_login_banner.py b/src/conf_mode/system_login_banner.py
index cdd066649..9d5fba65f 100755
--- a/src/conf_mode/system_login_banner.py
+++ b/src/conf_mode/system_login_banner.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_logs.py b/src/conf_mode/system_logs.py
index 8ad4875d4..f0e742d1b 100755
--- a/src/conf_mode/system_logs.py
+++ b/src/conf_mode/system_logs.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_option.py b/src/conf_mode/system_option.py
index 064a1aa91..fbe7231df 100755
--- a/src/conf_mode/system_option.py
+++ b/src/conf_mode/system_option.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -122,7 +122,14 @@ def generate(options):
render(ssh_config, 'system/ssh_config.j2', options)
render(usb_autosuspend, 'system/40_usb_autosuspend.j2', options)
+ # XXX: This code path and if statements must be kept in sync with the Kernel
+ # option handling in image_installer.py:get_cli_kernel_options(). This
+ # occurance is used for having the appropriate options passed to GRUB
+ # when re-configuring options on the CLI.
cmdline_options = []
+ kernel_opts = options.get('kernel', {})
+ k_cpu_opts = kernel_opts.get('cpu', {})
+ k_memory_opts = kernel_opts.get('memory', {})
if 'kernel' in options:
if 'disable_mitigations' in options['kernel']:
cmdline_options.append('mitigations=off')
@@ -131,8 +138,51 @@ def generate(options):
if 'amd_pstate_driver' in options['kernel']:
mode = options['kernel']['amd_pstate_driver']
cmdline_options.append(
- f'initcall_blacklist=acpi_cpufreq_init amd_pstate={mode}'
- )
+ f'initcall_blacklist=acpi_cpufreq_init amd_pstate={mode}')
+ if 'quiet' in options['kernel']:
+ cmdline_options.append('quiet')
+
+ if 'disable_hpet' in kernel_opts:
+ cmdline_options.append('hpet=disable')
+
+ if 'disable_mce' in kernel_opts:
+ cmdline_options.append('mce=off')
+
+ if 'disable_softlockup' in kernel_opts:
+ cmdline_options.append('nosoftlockup')
+
+ # CPU options
+ isol_cpus = k_cpu_opts.get('isolate_cpus')
+ if isol_cpus:
+ cmdline_options.append(f'isolcpus={isol_cpus}')
+
+ nohz_full = k_cpu_opts.get('nohz_full')
+ if nohz_full:
+ cmdline_options.append(f'nohz_full={nohz_full}')
+
+ rcu_nocbs = k_cpu_opts.get('rcu_no_cbs')
+ if rcu_nocbs:
+ cmdline_options.append(f'rcu_nocbs={rcu_nocbs}')
+
+ if 'disable_nmi_watchdog' in k_cpu_opts:
+ cmdline_options.append('nmi_watchdog=0')
+
+ # Memory options
+ if 'disable_numa_balancing' in k_memory_opts:
+ cmdline_options.append('numa_balancing=disable')
+
+ default_hp_size = k_memory_opts.get('default_hugepage_size')
+ if default_hp_size:
+ cmdline_options.append(f'default_hugepagesz={default_hp_size}')
+
+ hp_sizes = k_memory_opts.get('hugepage_size')
+ if hp_sizes:
+ for size, settings in hp_sizes.items():
+ cmdline_options.append(f'hugepagesz={size}')
+ count = settings.get('hugepage_count')
+ if count:
+ cmdline_options.append(f'hugepages={count}')
+
grub_util.update_kernel_cmdline_options(' '.join(cmdline_options))
return None
diff --git a/src/conf_mode/system_proxy.py b/src/conf_mode/system_proxy.py
index 079c43e7e..3843ad527 100755
--- a/src/conf_mode/system_proxy.py
+++ b/src/conf_mode/system_proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_sflow.py b/src/conf_mode/system_sflow.py
index a22dac36f..86a344ff7 100755
--- a/src/conf_mode/system_sflow.py
+++ b/src/conf_mode/system_sflow.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_sysctl.py b/src/conf_mode/system_sysctl.py
index f6b02023d..8e018ec0b 100755
--- a/src/conf_mode/system_sysctl.py
+++ b/src/conf_mode/system_sysctl.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_syslog.py b/src/conf_mode/system_syslog.py
index 414bd4b6b..c1a8baa1d 100755
--- a/src/conf_mode/system_syslog.py
+++ b/src/conf_mode/system_syslog.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -35,7 +35,7 @@ rsyslog_conf = '/run/rsyslog/rsyslog.conf'
logrotate_conf = '/etc/logrotate.d/vyos-rsyslog'
systemd_socket = 'syslog.socket'
-systemd_service = systemd_services['rsyslog']
+systemd_service = systemd_services['syslog']
def get_config(config=None):
if config:
diff --git a/src/conf_mode/system_task-scheduler.py b/src/conf_mode/system_task-scheduler.py
index 129be5d3c..c0253006a 100755
--- a/src/conf_mode/system_task-scheduler.py
+++ b/src/conf_mode/system_task-scheduler.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_timezone.py b/src/conf_mode/system_timezone.py
index 39770fdb4..54ffb88ee 100755
--- a/src/conf_mode/system_timezone.py
+++ b/src/conf_mode/system_timezone.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_update-check.py b/src/conf_mode/system_update-check.py
index 71ac13e51..7ed736eac 100755
--- a/src/conf_mode/system_update-check.py
+++ b/src/conf_mode/system_update-check.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/system_wireless.py b/src/conf_mode/system_wireless.py
index e0ca0ab8e..2d377c50a 100644
--- a/src/conf_mode/system_wireless.py
+++ b/src/conf_mode/system_wireless.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index 2754314f7..1871956b2 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
@@ -727,7 +727,7 @@ def generate(ipsec):
for remote_prefix in remote_prefixes:
local_net = ipaddress.ip_network(local_prefix)
remote_net = ipaddress.ip_network(remote_prefix)
- if local_net.overlaps(remote_net):
+ if local_net.subnet_of(remote_net):
if passthrough is None:
passthrough = []
passthrough.append(local_prefix)
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index 04ccbcec3..d6f5e4c28 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py
index 42785134f..78cdaa179 100755
--- a/src/conf_mode/vpn_openconnect.py
+++ b/src/conf_mode/vpn_openconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -37,19 +37,22 @@ from passlib.hash import sha512_crypt
from time import sleep
from vyos import airbag
+
airbag.enable()
-cfg_dir = '/run/ocserv'
-ocserv_conf = cfg_dir + '/ocserv.conf'
-ocserv_passwd = cfg_dir + '/ocpasswd'
+cfg_dir = '/run/ocserv'
+ocserv_conf = cfg_dir + '/ocserv.conf'
+ocserv_passwd = cfg_dir + '/ocpasswd'
ocserv_otp_usr = cfg_dir + '/users.oath'
-radius_cfg = cfg_dir + '/radiusclient.conf'
+radius_cfg = cfg_dir + '/radiusclient.conf'
radius_servers = cfg_dir + '/radius_servers'
+
# Generate hash from user cleartext password
def get_hash(password):
return sha512_crypt.hash(password)
+
def get_config(config=None):
if config:
conf = config
@@ -59,78 +62,133 @@ def get_config(config=None):
if not conf.exists(base):
return None
- ocserv = conf.get_config_dict(base, key_mangling=('-', '_'),
- get_first_key=True,
- with_recursive_defaults=True,
- with_pki=True)
+ ocserv = conf.get_config_dict(
+ base,
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ with_recursive_defaults=True,
+ with_pki=True,
+ )
return ocserv
+
def verify(ocserv):
if ocserv is None:
return None
# Check if listen-ports not binded other services
# It can be only listen by 'ocserv-main'
for proto, port in ocserv.get('listen_ports').items():
- if check_port_availability(ocserv['listen_address'], int(port), proto) is not True and \
- not is_listen_port_bind_service(int(port), 'ocserv-main'):
+ if check_port_availability(
+ ocserv['listen_address'], int(port), proto
+ ) is not True and not is_listen_port_bind_service(int(port), 'ocserv-main'):
raise ConfigError(f'"{proto}" port "{port}" is used by another service')
# Check accounting
- if "accounting" in ocserv:
- if "mode" in ocserv["accounting"] and "radius" in ocserv["accounting"]["mode"]:
- if not origin["accounting"]['radius']['server']:
- raise ConfigError('OpenConnect accounting mode radius requires at least one RADIUS server')
- if "authentication" not in ocserv or "mode" not in ocserv["authentication"]:
- raise ConfigError('Accounting depends on OpenConnect authentication configuration')
- elif "radius" not in ocserv["authentication"]["mode"]:
- raise ConfigError('RADIUS accounting must be used with RADIUS authentication')
+ if 'accounting' in ocserv:
+ if 'mode' in ocserv['accounting'] and 'radius' in ocserv['accounting']['mode']:
+ if not ocserv['accounting']['radius']['server']:
+ raise ConfigError(
+ 'OpenConnect accounting mode radius requires at least one RADIUS server'
+ )
+ if 'authentication' not in ocserv or 'mode' not in ocserv['authentication']:
+ raise ConfigError(
+ 'Accounting depends on OpenConnect authentication configuration'
+ )
+ elif 'radius' not in ocserv['authentication']['mode']:
+ raise ConfigError(
+ 'RADIUS accounting must be used with RADIUS authentication'
+ )
# Check authentication
- if "authentication" in ocserv:
- if "mode" in ocserv["authentication"]:
- if ("local" in ocserv["authentication"]["mode"] and
- "radius" in ocserv["authentication"]["mode"]):
- raise ConfigError('OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration')
- if "radius" in ocserv["authentication"]["mode"]:
- if not ocserv["authentication"]['radius']['server']:
- raise ConfigError('OpenConnect authentication mode radius requires at least one RADIUS server')
- if "local" in ocserv["authentication"]["mode"]:
- if not ocserv.get("authentication", {}).get("local_users"):
- raise ConfigError('OpenConnect mode local required at least one user')
- if not ocserv["authentication"]["local_users"]["username"]:
- raise ConfigError('OpenConnect mode local required at least one user')
+ if 'authentication' in ocserv:
+ if 'mode' in ocserv['authentication']:
+ if (
+ 'local' in ocserv['authentication']['mode']
+ and 'radius' in ocserv['authentication']['mode']
+ ):
+ raise ConfigError(
+ 'OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration'
+ )
+ if 'radius' in ocserv['authentication']['mode']:
+ if 'server' not in ocserv['authentication']['radius']:
+ raise ConfigError(
+ 'OpenConnect authentication mode radius requires at least one RADIUS server'
+ )
+ if 'local' in ocserv['authentication']['mode']:
+ if not ocserv.get('authentication', {}).get('local_users'):
+ raise ConfigError(
+ 'OpenConnect mode local required at least one user'
+ )
+ if not ocserv['authentication']['local_users']['username']:
+ raise ConfigError(
+ 'OpenConnect mode local required at least one user'
+ )
else:
# For OTP mode: verify that each local user has an OTP key
- if "otp" in ocserv["authentication"]["mode"]["local"]:
+ if 'otp' in ocserv['authentication']['mode']['local']:
users_wo_key = []
- for user, user_config in ocserv["authentication"]["local_users"]["username"].items():
+ for user, user_config in ocserv['authentication'][
+ 'local_users'
+ ]['username'].items():
# User has no OTP key defined
- if dict_search('otp.key', user_config) == None:
+ if dict_search('otp.key', user_config) is None:
users_wo_key.append(user)
if users_wo_key:
- raise ConfigError(f'OTP enabled, but no OTP key is configured for these users:\n{users_wo_key}')
+ raise ConfigError(
+ f'OTP enabled, but no OTP key is configured for these users:\n{users_wo_key}'
+ )
# For password (and default) mode: verify that each local user has password
- if "password" in ocserv["authentication"]["mode"]["local"] or "otp" not in ocserv["authentication"]["mode"]["local"]:
+ if (
+ 'password' in ocserv['authentication']['mode']['local']
+ or 'otp' not in ocserv['authentication']['mode']['local']
+ ):
users_wo_pswd = []
- for user in ocserv["authentication"]["local_users"]["username"]:
- if not "password" in ocserv["authentication"]["local_users"]["username"][user]:
+ for user in ocserv['authentication']['local_users']['username']:
+ if (
+ 'password'
+ not in ocserv['authentication']['local_users'][
+ 'username'
+ ][user]
+ ):
users_wo_pswd.append(user)
if users_wo_pswd:
- raise ConfigError(f'password required for users:\n{users_wo_pswd}')
+ raise ConfigError(
+ f'password required for users:\n{users_wo_pswd}'
+ )
# Validate that if identity-based-config is configured all child config nodes are set
- if 'identity_based_config' in ocserv["authentication"]:
- if 'disabled' not in ocserv["authentication"]["identity_based_config"]:
- Warning("Identity based configuration files is a 3rd party addition. Use at your own risk, this might break the ocserv daemon!")
- if 'mode' not in ocserv["authentication"]["identity_based_config"]:
- raise ConfigError('OpenConnect radius identity-based-config enabled but mode not selected')
- elif 'group' in ocserv["authentication"]["identity_based_config"]["mode"] and "radius" not in ocserv["authentication"]["mode"]:
- raise ConfigError('OpenConnect config-per-group must be used with radius authentication')
- if 'directory' not in ocserv["authentication"]["identity_based_config"]:
- raise ConfigError('OpenConnect identity-based-config enabled but directory not set')
- if 'default_config' not in ocserv["authentication"]["identity_based_config"]:
- raise ConfigError('OpenConnect identity-based-config enabled but default-config not set')
+ if 'identity_based_config' in ocserv['authentication']:
+ if 'disabled' not in ocserv['authentication']['identity_based_config']:
+ Warning(
+ 'Identity based configuration files is a 3rd party addition. Use at your own risk, this might break the ocserv daemon!'
+ )
+ if 'mode' not in ocserv['authentication']['identity_based_config']:
+ raise ConfigError(
+ 'OpenConnect radius identity-based-config enabled but mode not selected'
+ )
+ elif (
+ 'group'
+ in ocserv['authentication']['identity_based_config']['mode']
+ and 'radius' not in ocserv['authentication']['mode']
+ ):
+ raise ConfigError(
+ 'OpenConnect config-per-group must be used with radius authentication'
+ )
+ if (
+ 'directory'
+ not in ocserv['authentication']['identity_based_config']
+ ):
+ raise ConfigError(
+ 'OpenConnect identity-based-config enabled but directory not set'
+ )
+ if (
+ 'default_config'
+ not in ocserv['authentication']['identity_based_config']
+ ):
+ raise ConfigError(
+ 'OpenConnect identity-based-config enabled but default-config not set'
+ )
else:
raise ConfigError('OpenConnect authentication mode required')
else:
@@ -149,94 +207,162 @@ def verify(ocserv):
verify_pki_ca_certificate(ocserv, ca_cert)
# Check network settings
- if "network_settings" in ocserv:
- if "push_route" in ocserv["network_settings"]:
+ if 'network_settings' in ocserv:
+ if 'push_route' in ocserv['network_settings']:
# Replace default route
- if "0.0.0.0/0" in ocserv["network_settings"]["push_route"]:
- ocserv["network_settings"]["push_route"].remove("0.0.0.0/0")
- ocserv["network_settings"]["push_route"].append("default")
+ if '0.0.0.0/0' in ocserv['network_settings']['push_route']:
+ ocserv['network_settings']['push_route'].remove('0.0.0.0/0')
+ ocserv['network_settings']['push_route'].append('default')
else:
- ocserv["network_settings"]["push_route"] = ["default"]
+ ocserv['network_settings']['push_route'] = ['default']
else:
raise ConfigError('OpenConnect network settings required!')
+
def generate(ocserv):
if not ocserv:
return None
- if "radius" in ocserv["authentication"]["mode"]:
+ if 'radius' in ocserv['authentication']['mode']:
if dict_search(ocserv, 'accounting.mode.radius'):
# Render radius client configuration
render(radius_cfg, 'ocserv/radius_conf.j2', ocserv)
- merged_servers = ocserv["accounting"]["radius"]["server"] | ocserv["authentication"]["radius"]["server"]
+ merged_servers = (
+ ocserv['accounting']['radius']['server']
+ | ocserv['authentication']['radius']['server']
+ )
# Render radius servers
# Merge the accounting and authentication servers into a single dictionary
- render(radius_servers, 'ocserv/radius_servers.j2', {'server': merged_servers})
+ render(
+ radius_servers, 'ocserv/radius_servers.j2', {'server': merged_servers}
+ )
else:
# Render radius client configuration
render(radius_cfg, 'ocserv/radius_conf.j2', ocserv)
# Render radius servers
- render(radius_servers, 'ocserv/radius_servers.j2', ocserv["authentication"]["radius"])
- elif "local" in ocserv["authentication"]["mode"]:
+ render(
+ radius_servers,
+ 'ocserv/radius_servers.j2',
+ ocserv['authentication']['radius'],
+ )
+ elif 'local' in ocserv['authentication']['mode']:
# if mode "OTP", generate OTP users file parameters
- if "otp" in ocserv["authentication"]["mode"]["local"]:
- if "local_users" in ocserv["authentication"]:
- for user in ocserv["authentication"]["local_users"]["username"]:
+ if 'otp' in ocserv['authentication']['mode']['local']:
+ if 'local_users' in ocserv['authentication']:
+ for user in ocserv['authentication']['local_users']['username']:
# OTP token type from CLI parameters:
- otp_interval = str(ocserv["authentication"]["local_users"]["username"][user]["otp"].get("interval"))
- token_type = ocserv["authentication"]["local_users"]["username"][user]["otp"].get("token_type")
- otp_length = str(ocserv["authentication"]["local_users"]["username"][user]["otp"].get("otp_length"))
- if token_type == "hotp-time":
- otp_type = "HOTP/T" + otp_interval
- elif token_type == "hotp-event":
- otp_type = "HOTP/E"
+ otp_interval = str(
+ ocserv['authentication']['local_users']['username'][user][
+ 'otp'
+ ].get('interval')
+ )
+ token_type = ocserv['authentication']['local_users']['username'][
+ user
+ ]['otp'].get('token_type')
+ otp_length = str(
+ ocserv['authentication']['local_users']['username'][user][
+ 'otp'
+ ].get('otp_length')
+ )
+ if token_type == 'hotp-time':
+ otp_type = 'HOTP/T' + otp_interval
+ elif token_type == 'hotp-event':
+ otp_type = 'HOTP/E'
else:
- otp_type = "HOTP/T" + otp_interval
- ocserv["authentication"]["local_users"]["username"][user]["otp"]["token_tmpl"] = otp_type + "/" + otp_length
+ otp_type = 'HOTP/T' + otp_interval
+ ocserv['authentication']['local_users']['username'][user]['otp'][
+ 'token_tmpl'
+ ] = otp_type + '/' + otp_length
# if there is a password, generate hash
- if "password" in ocserv["authentication"]["mode"]["local"] or not "otp" in ocserv["authentication"]["mode"]["local"]:
- if "local_users" in ocserv["authentication"]:
- for user in ocserv["authentication"]["local_users"]["username"]:
- ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"])
-
- if "password-otp" in ocserv["authentication"]["mode"]["local"]:
+ if (
+ 'password' in ocserv['authentication']['mode']['local']
+ or 'otp' not in ocserv['authentication']['mode']['local']
+ ):
+ if 'local_users' in ocserv['authentication']:
+ for user in ocserv['authentication']['local_users']['username']:
+ ocserv['authentication']['local_users']['username'][user][
+ 'hash'
+ ] = get_hash(
+ ocserv['authentication']['local_users']['username'][user][
+ 'password'
+ ]
+ )
+
+ if 'password-otp' in ocserv['authentication']['mode']['local']:
# Render local users ocpasswd
- render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
+ render(
+ ocserv_passwd,
+ 'ocserv/ocserv_passwd.j2',
+ ocserv['authentication']['local_users'],
+ )
# Render local users OTP keys
- render(ocserv_otp_usr, 'ocserv/ocserv_otp_usr.j2', ocserv["authentication"]["local_users"])
- elif "password" in ocserv["authentication"]["mode"]["local"]:
+ render(
+ ocserv_otp_usr,
+ 'ocserv/ocserv_otp_usr.j2',
+ ocserv['authentication']['local_users'],
+ )
+ elif 'password' in ocserv['authentication']['mode']['local']:
# Render local users ocpasswd
- render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
- elif "otp" in ocserv["authentication"]["mode"]["local"]:
+ render(
+ ocserv_passwd,
+ 'ocserv/ocserv_passwd.j2',
+ ocserv['authentication']['local_users'],
+ )
+ elif 'otp' in ocserv['authentication']['mode']['local']:
# Render local users OTP keys
- render(ocserv_otp_usr, 'ocserv/ocserv_otp_usr.j2', ocserv["authentication"]["local_users"])
+ render(
+ ocserv_otp_usr,
+ 'ocserv/ocserv_otp_usr.j2',
+ ocserv['authentication']['local_users'],
+ )
else:
# Render local users ocpasswd
- render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
+ render(
+ ocserv_passwd,
+ 'ocserv/ocserv_passwd.j2',
+ ocserv['authentication']['local_users'],
+ )
else:
- if "local_users" in ocserv["authentication"]:
- for user in ocserv["authentication"]["local_users"]["username"]:
- ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"])
+ if 'local_users' in ocserv['authentication']:
+ for user in ocserv['authentication']['local_users']['username']:
+ ocserv['authentication']['local_users']['username'][user]['hash'] = (
+ get_hash(
+ ocserv['authentication']['local_users']['username'][user][
+ 'password'
+ ]
+ )
+ )
# Render local users
- render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
+ render(
+ ocserv_passwd,
+ 'ocserv/ocserv_passwd.j2',
+ ocserv['authentication']['local_users'],
+ )
- if "ssl" in ocserv:
+ if 'ssl' in ocserv:
cert_file_path = os.path.join(cfg_dir, 'cert.pem')
cert_key_path = os.path.join(cfg_dir, 'cert.key')
-
if 'certificate' in ocserv['ssl']:
cert_name = ocserv['ssl']['certificate']
pki_cert = ocserv['pki']['certificate'][cert_name]
loaded_pki_cert = load_certificate(pki_cert['certificate'])
- loaded_ca_certs = {load_certificate(c['certificate'])
- for c in ocserv['pki']['ca'].values()} if 'ca' in ocserv['pki'] else {}
+ loaded_ca_certs = (
+ {
+ load_certificate(c['certificate'])
+ for c in ocserv['pki']['ca'].values()
+ }
+ if 'ca' in ocserv['pki']
+ else {}
+ )
cert_full_chain = find_chain(loaded_pki_cert, loaded_ca_certs)
- write_file(cert_file_path,
- '\n'.join(encode_certificate(c) for c in cert_full_chain))
+ write_file(
+ cert_file_path,
+ '\n'.join(encode_certificate(c) for c in cert_full_chain),
+ )
if 'private' in pki_cert and 'key' in pki_cert['private']:
write_file(cert_key_path, wrap_private_key(pki_cert['private']['key']))
@@ -250,7 +376,8 @@ def generate(ocserv):
loaded_ca_cert = load_certificate(pki_ca_cert['certificate'])
ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs)
ca_chains.append(
- '\n'.join(encode_certificate(c) for c in ca_full_chain))
+ '\n'.join(encode_certificate(c) for c in ca_full_chain)
+ )
write_file(ca_cert_file_path, '\n'.join(ca_chains))
@@ -269,11 +396,13 @@ def apply(ocserv):
counter = 0
while True:
# exit early when service runs
- if is_systemd_service_running("ocserv.service"):
+ if is_systemd_service_running('ocserv.service'):
break
sleep(0.250)
if counter > 5:
- raise ConfigError('OpenConnect failed to start, check the logs for details')
+ raise ConfigError(
+ 'OpenConnect failed to start, check the logs for details'
+ )
break
counter += 1
diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py
index c0d8330bd..c11619779 100755
--- a/src/conf_mode/vpn_pptp.py
+++ b/src/conf_mode/vpn_pptp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 7490fd0e0..5382fc711 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 8baf55857..1eacba112 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -18,6 +18,8 @@ from sys import exit
from jmespath import search
from json import loads
+import vyos.defaults
+
from vyos.config import Config
from vyos.configdict import node_changed
from vyos.configverify import verify_route_map
@@ -163,6 +165,11 @@ def verify(vrf):
if 'table' not in vrf_config:
raise ConfigError(f'VRF "{name}" table id is mandatory!')
+ if int(vrf_config['table']) == vyos.defaults.rt_global_vrf:
+ raise ConfigError(
+ f'VRF "{name}" table id {vrf_config["table"]} cannot be used!'
+ )
+
# routing table id can't be changed - OS restriction
if interface_exists(name):
tmp = get_vrf_tableid(name)
@@ -233,7 +240,7 @@ def apply(vrf):
vrf_iface.set_dhcpv6(False)
# Remove nftables conntrack zone map item
- nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}'
+ nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ \'"{tmp}"\' }}'
# Check if deleting is possible first to avoid raising errors
_, err = popen(f'nft --check {nft_del_element}')
if not err:
@@ -313,7 +320,7 @@ def apply(vrf):
state = 'down' if 'disable' in config else 'up'
vrf_if.set_admin_state(state)
# Add nftables conntrack zone map item
- nft_add_element = f'add element inet vrf_zones ct_iface_map {{ "{name}" : {table} }}'
+ nft_add_element = f'add element inet vrf_zones ct_iface_map {{ \'"{name}"\' : {table} }}'
cmd(f'nft {nft_add_element}')
# Only call into nftables as long as there is nothing setup to avoid wasting
diff --git a/src/etc/default/vyatta b/src/etc/default/vyatta
index e5fa3bb30..0a5129e8b 100644
--- a/src/etc/default/vyatta
+++ b/src/etc/default/vyatta
@@ -173,6 +173,7 @@ unset _vyatta_extglob
declare -x -r vyos_bin_dir=/usr/bin
declare -x -r vyos_sbin_dir=/usr/sbin
declare -x -r vyos_share_dir=/usr/share
+ declare -x -r vyconf_bin_dir=/usr/libexec/vyos/vyconf/bin
if test -z "$vyos_conf_scripts_dir" ; then
declare -x -r vyos_conf_scripts_dir=$vyos_libexec_dir/conf_mode
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/06-vyos-nodefaultroute b/src/etc/dhcp/dhclient-enter-hooks.d/06-vyos-nodefaultroute
new file mode 100644
index 000000000..38f674276
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/06-vyos-nodefaultroute
@@ -0,0 +1,20 @@
+# Don't add default route if no-default-route is configured for interface
+
+# As configuration is not available to cli-shell-api at the first boot, we must use vyos.config, which contains a workaround for this
+function get_no_default_route {
+python3 - <<PYEND
+from vyos.config import Config
+import os
+
+config = Config()
+if config.exists('interfaces'):
+ iface_types = config.list_nodes('interfaces')
+ for iface_type in iface_types:
+ if config.exists("interfaces {} {} dhcp-options no-default-route".format(iface_type, os.environ['interface'])):
+ print("True")
+PYEND
+}
+
+if [[ "$(get_no_default_route)" == 'True' ]]; then
+ new_routers=""
+fi
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
index 57f803055..f10ee7f43 100755
--- a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down
index e1765ae85..49acd27d2 100755
--- a/src/etc/ipsec.d/vti-up-down
+++ b/src/etc/ipsec.d/vti-up-down
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/netplug/netplug b/src/etc/netplug/netplug
index 60b65e8c9..9f6ab74cc 100755
--- a/src/etc/netplug/netplug
+++ b/src/etc/netplug/netplug
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/etc/netplug/vyos-netplug-dhcp-client b/src/etc/netplug/vyos-netplug-dhcp-client
index 7fe6cda75..31a0cc6a7 100755
--- a/src/etc/netplug/vyos-netplug-dhcp-client
+++ b/src/etc/netplug/vyos-netplug-dhcp-client
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2023-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -20,10 +20,10 @@ import sys
from time import sleep
from vyos.config import Config
-from vyos.configdict import get_interface_dict
-from vyos.ifconfig import Interface
from vyos.ifconfig import Section
from vyos.utils.boot import boot_configuration_complete
+from vyos.utils.process import cmd
+from vyos.utils.process import is_systemd_service_active
from vyos.utils.commit import commit_in_progress
from vyos import airbag
@@ -38,21 +38,34 @@ if not boot_configuration_complete():
sys.exit(1)
interface = sys.argv[1]
-# helper scripts should only work on physical interfaces not on individual
-# sub-interfaces. Moving e.g. a VLAN interface in/out a VRF will also trigger
-# this script which should be prohibited - bail out early
-if '.' in interface:
- sys.exit(0)
while commit_in_progress():
- sleep(1)
+ sleep(0.250)
in_out = sys.argv[2]
config = Config()
interface_path = ['interfaces'] + Section.get_config_path(interface).split()
-_, interface_config = get_interface_dict(
- config, interface_path[:-1], ifname=interface, with_pki=True
-)
-if 'deleted' not in interface_config:
- Interface(interface).update(interface_config)
+
+systemdV4_service = f'dhclient@{interface}.service'
+systemdV6_service = f'dhcp6c@{interface}.service'
+if in_out == 'out':
+ # Interface moved state to down
+ if is_systemd_service_active(systemdV4_service):
+ cmd(f'systemctl stop {systemdV4_service}')
+ if is_systemd_service_active(systemdV6_service):
+ cmd(f'systemctl stop {systemdV6_service}')
+elif in_out == 'in':
+ if config.exists_effective(interface_path + ['address']):
+ tmp = config.return_effective_values(interface_path + ['address'])
+ # Always (re-)start the DHCP(v6) client service. If the DHCP(v6) client
+ # is already running - which could happen if the interface is re-
+ # configured in operational down state, it will have a backoff
+ # time increasing while not receiving a DHCP(v6) reply.
+ #
+ # To make the interface instantly available, and as for a DHCP(v6) lease
+ # we will re-start the service and thus cancel the backoff time.
+ if 'dhcp' in tmp:
+ cmd(f'systemctl restart {systemdV4_service}')
+ if 'dhcpv6' in tmp:
+ cmd(f'systemctl restart {systemdV6_service}')
diff --git a/src/etc/opennhrp/opennhrp-script.py b/src/etc/opennhrp/opennhrp-script.py
deleted file mode 100755
index f6f6d075c..000000000
--- a/src/etc/opennhrp/opennhrp-script.py
+++ /dev/null
@@ -1,371 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
-#
-# 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
-import re
-import sys
-import vyos.ipsec
-
-from json import loads
-from pathlib import Path
-
-from vyos.logger import getLogger
-from vyos.utils.process import cmd
-from vyos.utils.process import process_named_running
-
-NHRP_CONFIG: str = '/run/opennhrp/opennhrp.conf'
-
-
-def vici_get_ipsec_uniqueid(conn: str, src_nbma: str,
- dst_nbma: str) -> list[str]:
- """ Find and return IKE SAs by src nbma and dst nbma
-
- Args:
- conn (str): a connection name
- src_nbma (str): an IP address of NBMA source
- dst_nbma (str): an IP address of NBMA destination
-
- Returns:
- list: a list of IKE connections that match a criteria
- """
- if not conn or not src_nbma or not dst_nbma:
- logger.error(
- f'Incomplete input data for resolving IKE unique ids: '
- f'conn: {conn}, src_nbma: {src_nbma}, dst_nbma: {dst_nbma}')
- return []
-
- try:
- logger.info(
- f'Resolving IKE unique ids for: conn: {conn}, '
- f'src_nbma: {src_nbma}, dst_nbma: {dst_nbma}')
- list_ikeid: list[str] = []
- list_sa: list = vyos.ipsec.get_vici_sas_by_name(conn, None)
- for sa in list_sa:
- if sa[conn]['local-host'].decode('ascii') == src_nbma \
- and sa[conn]['remote-host'].decode('ascii') == dst_nbma:
- list_ikeid.append(sa[conn]['uniqueid'].decode('ascii'))
- return list_ikeid
- except Exception as err:
- logger.error(f'Unable to find unique ids for IKE: {err}')
- return []
-
-
-def vici_ike_terminate(list_ikeid: list[str]) -> bool:
- """Terminating IKE SAs by list of IKE IDs
-
- Args:
- list_ikeid (list[str]): a list of IKE ids to terminate
-
- Returns:
- bool: result of termination action
- """
- if not list:
- logger.warning('An empty list for termination was provided')
- return False
-
- try:
- vyos.ipsec.terminate_vici_ikeid_list(list_ikeid)
- return True
- except Exception as err:
- logger.error(f'Failed to terminate SA for IKE ids {list_ikeid}: {err}')
- return False
-
-
-def parse_type_ipsec(interface: str) -> tuple[str, str]:
- """Get DMVPN Type and NHRP Profile from the configuration
-
- Args:
- interface (str): a name of interface
-
- Returns:
- tuple[str, str]: `peer_type` and `profile_name`
- """
- if not interface:
- logger.error('Cannot find peer type - no input provided')
- return '', ''
-
- config_file: str = Path(NHRP_CONFIG).read_text()
- regex: str = rf'^interface {interface} #(?P<peer_type>hub|spoke) ?(?P<profile_name>[^\n]*)$'
- match = re.search(regex, config_file, re.M)
- if match:
- return match.groupdict()['peer_type'], match.groupdict()[
- 'profile_name']
- return '', ''
-
-
-def add_peer_route(nbma_src: str, nbma_dst: str, mtu: str) -> None:
- """Add a route to a NBMA peer
-
- Args:
- nbma_src (str): a local IP address
- nbma_dst (str): a remote IP address
- mtu (str): a MTU for a route
- """
- logger.info(f'Adding route from {nbma_src} to {nbma_dst} with MTU {mtu}')
- # Find routes to a peer
- route_get_cmd: str = f'sudo ip --json route get {nbma_dst} from {nbma_src}'
- try:
- route_info_data = loads(cmd(route_get_cmd))
- except Exception as err:
- logger.error(f'Unable to find a route to {nbma_dst}: {err}')
- return
-
- # Check if an output has an expected format
- if not isinstance(route_info_data, list):
- logger.error(
- f'Garbage returned from the "{route_get_cmd}" '
- f'command: {route_info_data}')
- return
-
- # Add static routes to a peer
- for route_item in route_info_data:
- route_dev = route_item.get('dev')
- route_dst = route_item.get('dst')
- route_gateway = route_item.get('gateway')
- # Prepare a command to add a route
- route_add_cmd = 'sudo ip route add'
- if route_dst:
- route_add_cmd = f'{route_add_cmd} {route_dst}'
- if route_gateway:
- route_add_cmd = f'{route_add_cmd} via {route_gateway}'
- if route_dev:
- route_add_cmd = f'{route_add_cmd} dev {route_dev}'
- route_add_cmd = f'{route_add_cmd} proto 42 mtu {mtu}'
- # Add a route
- try:
- cmd(route_add_cmd)
- except Exception as err:
- logger.error(
- f'Unable to add a route using command "{route_add_cmd}": '
- f'{err}')
-
-
-def vici_initiate(conn: str, child_sa: str, src_addr: str,
- dest_addr: str) -> bool:
- """Initiate IKE SA connection with specific peer
-
- Args:
- conn (str): an IKE connection name
- child_sa (str): a child SA profile name
- src_addr (str): NBMA local address
- dest_addr (str): NBMA address of a peer
-
- Returns:
- bool: a result of initiation command
- """
- logger.info(
- f'Trying to initiate connection. Name: {conn}, child sa: {child_sa}, '
- f'src_addr: {src_addr}, dst_addr: {dest_addr}')
- try:
- vyos.ipsec.vici_initiate(conn, child_sa, src_addr, dest_addr)
- return True
- except Exception as err:
- logger.error(f'Unable to initiate connection {err}')
- return False
-
-
-def vici_terminate(conn: str, src_addr: str, dest_addr: str) -> None:
- """Find and terminate IKE SAs by local NBMA and remote NBMA addresses
-
- Args:
- conn (str): IKE connection name
- src_addr (str): NBMA local address
- dest_addr (str): NBMA address of a peer
- """
- logger.info(
- f'Terminating IKE connection {conn} between {src_addr} '
- f'and {dest_addr}')
-
- ikeid_list: list[str] = vici_get_ipsec_uniqueid(conn, src_addr, dest_addr)
-
- if not ikeid_list:
- logger.warning(
- f'No active sessions found for IKE profile {conn}, '
- f'local NBMA {src_addr}, remote NBMA {dest_addr}')
- else:
- try:
- vyos.ipsec.terminate_vici_ikeid_list(ikeid_list)
- except Exception as err:
- logger.error(
- f'Failed to terminate SA for IKE ids {ikeid_list}: {err}')
-
-def iface_up(interface: str) -> None:
- """Proceed tunnel interface UP event
-
- Args:
- interface (str): an interface name
- """
- if not interface:
- logger.warning('No interface name provided for UP event')
-
- logger.info(f'Turning up interface {interface}')
- try:
- cmd(f'sudo ip route flush proto 42 dev {interface}')
- cmd(f'sudo ip neigh flush dev {interface}')
- except Exception as err:
- logger.error(
- f'Unable to flush route on interface "{interface}": {err}')
-
-
-def peer_up(dmvpn_type: str, conn: str) -> None:
- """Proceed NHRP peer UP event
-
- Args:
- dmvpn_type (str): a type of peer
- conn (str): an IKE profile name
- """
- logger.info(f'Peer UP event for {dmvpn_type} using IKE profile {conn}')
- src_nbma = os.getenv('NHRP_SRCNBMA')
- dest_nbma = os.getenv('NHRP_DESTNBMA')
- dest_mtu = os.getenv('NHRP_DESTMTU')
-
- if not src_nbma or not dest_nbma:
- logger.error(
- f'Can not get NHRP NBMA addresses: local {src_nbma}, '
- f'remote {dest_nbma}')
- return
-
- logger.info(f'NBMA addresses: local {src_nbma}, remote {dest_nbma}')
- if dest_mtu:
- add_peer_route(src_nbma, dest_nbma, dest_mtu)
- if conn and dmvpn_type == 'spoke' and process_named_running('charon'):
- vici_terminate(conn, src_nbma, dest_nbma)
- vici_initiate(conn, 'dmvpn', src_nbma, dest_nbma)
-
-
-def peer_down(dmvpn_type: str, conn: str) -> None:
- """Proceed NHRP peer DOWN event
-
- Args:
- dmvpn_type (str): a type of peer
- conn (str): an IKE profile name
- """
- logger.info(f'Peer DOWN event for {dmvpn_type} using IKE profile {conn}')
-
- src_nbma = os.getenv('NHRP_SRCNBMA')
- dest_nbma = os.getenv('NHRP_DESTNBMA')
-
- if not src_nbma or not dest_nbma:
- logger.error(
- f'Can not get NHRP NBMA addresses: local {src_nbma}, '
- f'remote {dest_nbma}')
- return
-
- logger.info(f'NBMA addresses: local {src_nbma}, remote {dest_nbma}')
- if conn and dmvpn_type == 'spoke' and process_named_running('charon'):
- vici_terminate(conn, src_nbma, dest_nbma)
- try:
- cmd(f'sudo ip route del {dest_nbma} src {src_nbma} proto 42')
- except Exception as err:
- logger.error(
- f'Unable to del route from {src_nbma} to {dest_nbma}: {err}')
-
-
-def route_up(interface: str) -> None:
- """Proceed NHRP route UP event
-
- Args:
- interface (str): an interface name
- """
- logger.info(f'Route UP event for interface {interface}')
-
- dest_addr = os.getenv('NHRP_DESTADDR')
- dest_prefix = os.getenv('NHRP_DESTPREFIX')
- next_hop = os.getenv('NHRP_NEXTHOP')
-
- if not dest_addr or not dest_prefix or not next_hop:
- logger.error(
- f'Can not get route details: dest_addr {dest_addr}, '
- f'dest_prefix {dest_prefix}, next_hop {next_hop}')
- return
-
- logger.info(
- f'Route details: dest_addr {dest_addr}, dest_prefix {dest_prefix}, '
- f'next_hop {next_hop}')
-
- try:
- cmd(f'sudo ip route replace {dest_addr}/{dest_prefix} proto 42 \
- via {next_hop} dev {interface}')
- cmd('sudo ip route flush cache')
- except Exception as err:
- logger.error(
- f'Unable replace or flush route to {dest_addr}/{dest_prefix} '
- f'via {next_hop} dev {interface}: {err}')
-
-
-def route_down(interface: str) -> None:
- """Proceed NHRP route DOWN event
-
- Args:
- interface (str): an interface name
- """
- logger.info(f'Route DOWN event for interface {interface}')
-
- dest_addr = os.getenv('NHRP_DESTADDR')
- dest_prefix = os.getenv('NHRP_DESTPREFIX')
-
- if not dest_addr or not dest_prefix:
- logger.error(
- f'Can not get route details: dest_addr {dest_addr}, '
- f'dest_prefix {dest_prefix}')
- return
-
- logger.info(
- f'Route details: dest_addr {dest_addr}, dest_prefix {dest_prefix}')
- try:
- cmd(f'sudo ip route del {dest_addr}/{dest_prefix} proto 42')
- cmd('sudo ip route flush cache')
- except Exception as err:
- logger.error(
- f'Unable delete or flush route to {dest_addr}/{dest_prefix}: '
- f'{err}')
-
-
-if __name__ == '__main__':
- logger = getLogger('opennhrp-script', syslog=True)
- logger.debug(
- f'Running script with arguments: {sys.argv}, '
- f'environment: {os.environ}')
-
- action = sys.argv[1]
- interface = os.getenv('NHRP_INTERFACE')
-
- if not interface:
- logger.error('Can not get NHRP interface name')
- sys.exit(1)
-
- dmvpn_type, profile_name = parse_type_ipsec(interface)
- if not dmvpn_type:
- logger.info(f'Interface {interface} is not NHRP tunnel')
- sys.exit()
-
- dmvpn_conn: str = ''
- if profile_name:
- dmvpn_conn: str = f'dmvpn-{profile_name}-{interface}'
- if action == 'interface-up':
- iface_up(interface)
- elif action == 'peer-register':
- pass
- elif action == 'peer-up':
- peer_up(dmvpn_type, dmvpn_conn)
- elif action == 'peer-down':
- peer_down(dmvpn_type, dmvpn_conn)
- elif action == 'route-up':
- route_up(interface)
- elif action == 'route-down':
- route_down(interface)
-
- sys.exit()
diff --git a/src/etc/ppp/ip-up.d/96-vyos-sstpc-callback b/src/etc/ppp/ip-up.d/96-vyos-sstpc-callback
index 4e8804f29..e8d396887 100755
--- a/src/etc/ppp/ip-up.d/96-vyos-sstpc-callback
+++ b/src/etc/ppp/ip-up.d/96-vyos-sstpc-callback
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback b/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
index fa1917ab1..79c7a27bf 100755
--- a/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
+++ b/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb b/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb
index fff258afa..9b708b88f 100755
--- a/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb
+++ b/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/sysctl.d/30-vyos-router.conf b/src/etc/sysctl.d/30-vyos-router.conf
index 76be41ddc..ef81cebac 100644
--- a/src/etc/sysctl.d/30-vyos-router.conf
+++ b/src/etc/sysctl.d/30-vyos-router.conf
@@ -83,6 +83,16 @@ net.ipv4.conf.default.ignore_routes_with_linkdown=1
net.ipv6.conf.all.ignore_routes_with_linkdown=1
net.ipv6.conf.default.ignore_routes_with_linkdown=1
+# Disable IPv6 interface autoconfigurationnable packet forwarding for IPv6
+net.ipv6.conf.all.autoconf=0
+net.ipv6.conf.default.autoconf=0
+net.ipv6.conf.*.autoconf=0
+
+# Disable IPv6 router advertisements
+net.ipv6.conf.all.accept_ra=0
+net.ipv6.conf.default.accept_ra=0
+net.ipv6.conf.*.accept_ra=0
+
# Enable packet forwarding for IPv6
net.ipv6.conf.all.forwarding=1
diff --git a/src/etc/systemd/system/certbot.service.d/10-override.conf b/src/etc/systemd/system/certbot.service.d/10-override.conf
deleted file mode 100644
index 542f77eb2..000000000
--- a/src/etc/systemd/system/certbot.service.d/10-override.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[Unit]
-After=
-After=vyos-router.service
-
-[Service]
-ExecStart=
-ExecStart=/usr/bin/certbot renew --config-dir /config/auth/letsencrypt --no-random-sleep-on-renew --post-hook "/usr/libexec/vyos/vyos-certbot-renew-pki.sh"
diff --git a/src/etc/systemd/system/fastnetmon.service.d/override.conf b/src/etc/systemd/system/fastnetmon.service.d/override.conf
deleted file mode 100644
index 841666070..000000000
--- a/src/etc/systemd/system/fastnetmon.service.d/override.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-RequiresMountsFor=/run
-ConditionPathExists=/run/fastnetmon/fastnetmon.conf
-After=
-After=vyos-router.service
-
-[Service]
-Type=simple
-WorkingDirectory=/run/fastnetmon
-PIDFile=/run/fastnetmon.pid
-ExecStart=
-ExecStart=/usr/sbin/fastnetmon --configuration_file /run/fastnetmon/fastnetmon.conf
diff --git a/src/etc/systemd/system/frr.service.d/override.conf b/src/etc/systemd/system/frr.service.d/override.conf
index 614b4f7ed..a4a73ecd9 100644
--- a/src/etc/systemd/system/frr.service.d/override.conf
+++ b/src/etc/systemd/system/frr.service.d/override.conf
@@ -3,9 +3,11 @@ After=vyos-router.service
[Service]
LimitNOFILE=4096
-ExecStartPre=/bin/bash -c 'mkdir -p /run/frr/config; \
+ExecStartPre=/bin/bash -c 'if [ ! -f /run/frr/config/frr.conf ]; then \
+ mkdir -p /run/frr/config; \
echo "log syslog" > /run/frr/config/frr.conf; \
echo "log facility local7" >> /run/frr/config/frr.conf; \
chown frr:frr /run/frr/config/frr.conf; \
chmod 664 /run/frr/config/frr.conf; \
- mount --bind /run/frr/config/frr.conf /etc/frr/frr.conf'
+ mount --bind /run/frr/config/frr.conf /etc/frr/frr.conf; \
+fi;'
diff --git a/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf b/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf
deleted file mode 100644
index c74fafb42..000000000
--- a/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-After=
-After=vyos-router.service
-ConditionFileNotEmpty=
-
-[Service]
-ExecStart=
-ExecStart=/usr/sbin/kea-ctrl-agent -c /run/kea/kea-ctrl-agent.conf
-AmbientCapabilities=CAP_NET_BIND_SERVICE
-CapabilityBoundingSet=CAP_NET_BIND_SERVICE
diff --git a/src/etc/systemd/system/kea-dhcp-ddns-server.service.d/override.conf b/src/etc/systemd/system/kea-dhcp-ddns-server.service.d/override.conf
new file mode 100644
index 000000000..cdfdea8eb
--- /dev/null
+++ b/src/etc/systemd/system/kea-dhcp-ddns-server.service.d/override.conf
@@ -0,0 +1,7 @@
+[Unit]
+After=
+After=vyos-router.service
+
+[Service]
+ExecStart=
+ExecStart=/usr/sbin/kea-dhcp-ddns -c /run/kea/kea-dhcp-ddns.conf
diff --git a/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
index 00f2f184c..78c5249fb 100755
--- a/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
+++ b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
index 7da57bca8..cfe774edd 100755
--- a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
+++ b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/add-system-version.py b/src/helpers/add-system-version.py
index 5270ee7d3..70bbd2202 100755
--- a/src/helpers/add-system-version.py
+++ b/src/helpers/add-system-version.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/helpers/config_dependency.py b/src/helpers/config_dependency.py
index 817bcc65a..d6358bef8 100755
--- a/src/helpers/config_dependency.py
+++ b/src/helpers/config_dependency.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/geoip-update.py b/src/helpers/geoip-update.py
index 34accf2cc..22d26e538 100755
--- a/src/helpers/geoip-update.py
+++ b/src/helpers/geoip-update.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
@@ -25,20 +25,19 @@ def get_config(config=None):
conf = config
else:
conf = ConfigTreeQuery()
- base = ['firewall']
- if not conf.exists(base):
- return None
-
- return conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True,
- no_tag_node_value_mangle=True)
+ return (
+ conf.get_config_dict(['firewall'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True) if conf.exists(['firewall']) else None,
+ conf.get_config_dict(['policy'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True) if conf.exists(['policy']) else None,
+ )
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--force", help="Force update", action="store_true")
args = parser.parse_args()
- firewall = get_config()
-
- if not geoip_update(firewall, force=args.force):
+ firewall, policy = get_config()
+ if not geoip_update(firewall=firewall, policy=policy, force=args.force):
sys.exit(1)
diff --git a/src/helpers/priority.py b/src/helpers/priority.py
index 04186104c..6630889af 100755
--- a/src/helpers/priority.py
+++ b/src/helpers/priority.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/read-saved-value.py b/src/helpers/read-saved-value.py
index 1463e9ffe..f4048f373 100755
--- a/src/helpers/read-saved-value.py
+++ b/src/helpers/read-saved-value.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/reset_section.py b/src/helpers/reset_section.py
new file mode 100755
index 000000000..7e464afd5
--- /dev/null
+++ b/src/helpers/reset_section.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+#
+# Copyright 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 argparse
+import sys
+import os
+import grp
+
+from vyos.configsession import ConfigSession
+from vyos.config import Config
+from vyos.configdiff import get_config_diff
+from vyos.xml_ref import is_leaf
+
+
+CFG_GROUP = 'vyattacfg'
+DEBUG = False
+
+
+def type_str_to_list(value):
+ if isinstance(value, str):
+ return value.split()
+ raise argparse.ArgumentTypeError('path must be a whitespace separated string')
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('path', type=type_str_to_list, help='section to reload/rollback')
+parser.add_argument('--pid', help='pid of config session')
+
+group = parser.add_mutually_exclusive_group()
+group.add_argument('--reload', action='store_true', help='retry proposed commit')
+group.add_argument(
+ '--rollback', action='store_true', default=True, help='rollback to stable commit'
+)
+
+args = parser.parse_args()
+
+path = args.path
+reload = args.reload
+rollback = args.rollback
+pid = args.pid
+
+try:
+ if is_leaf(path):
+ sys.exit('path is leaf node: neither allowed nor useful')
+except ValueError:
+ if DEBUG:
+ sys.exit('nonexistent path: neither allowed nor useful')
+ else:
+ sys.exit()
+
+test = Config()
+in_session = test.in_session()
+
+if in_session:
+ if reload:
+ sys.exit('reset_section reload not available inside of a config session')
+
+ diff = get_config_diff(test)
+ if not diff.is_node_changed(path):
+ # No discrepancies at path after commit, hence no error to revert.
+ sys.exit()
+
+ del diff
+else:
+ if not reload:
+ sys.exit('reset_section rollback not available outside of a config session')
+
+del test
+
+
+session_id = int(pid) if pid else os.getppid()
+
+if in_session:
+ # check hint left by vyshim when ConfigError is from apply stage
+ hint_name = f'/tmp/apply_{session_id}'
+ if not os.path.exists(hint_name):
+ # no apply error; exit
+ sys.exit()
+ else:
+ # cleanup hint and continue with reset
+ os.unlink(hint_name)
+
+cfg_group = grp.getgrnam(CFG_GROUP)
+os.setgid(cfg_group.gr_gid)
+os.umask(0o002)
+
+shared = not bool(reload)
+
+session = ConfigSession(session_id, shared=shared)
+
+session_env = session.get_session_env()
+config = Config(session_env)
+
+d = config.get_config_dict(path, effective=True, get_first_key=True)
+
+if in_session:
+ session.discard()
+
+session.delete(path)
+session.commit()
+
+if not d:
+ # nothing more to do in either case of reload/rollback
+ sys.exit()
+
+session.set_section(path, d)
+out = session.commit()
+print(out)
diff --git a/src/helpers/run-config-activation.py b/src/helpers/run-config-activation.py
index 58293702a..f20adff1e 100755
--- a/src/helpers/run-config-activation.py
+++ b/src/helpers/run-config-activation.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/run-config-migration.py b/src/helpers/run-config-migration.py
index e6ce97363..6a3533644 100755
--- a/src/helpers/run-config-migration.py
+++ b/src/helpers/run-config-migration.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -19,6 +19,7 @@ import sys
import time
from argparse import ArgumentParser
from shutil import copyfile
+from vyos.utils.file import read_file
from vyos.migrate import ConfigMigrate
from vyos.migrate import ConfigMigrateError
@@ -76,3 +77,9 @@ except ConfigMigrateError as e:
if backup is not None and not config_migrate.config_modified:
os.unlink(backup)
+
+# T1771: add knob on Kernel command-line to simulate failed config migrator run
+# used to test if the automatic image reboot works.
+kernel_cmdline = read_file('/proc/cmdline')
+if 'vyos-fail-migration' in kernel_cmdline.split():
+ sys.exit(1)
diff --git a/src/helpers/set_vyconf_backend.py b/src/helpers/set_vyconf_backend.py
new file mode 100755
index 000000000..dddbe12f6
--- /dev/null
+++ b/src/helpers/set_vyconf_backend.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+#
+# Copyright 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/>.
+#
+#
+
+# N.B. only for use within testing framework; explicit invocation will leave
+# system in inconsistent state.
+
+import os
+import sys
+from argparse import ArgumentParser
+
+from vyos.utils.backend import set_vyconf_backend
+
+if os.getuid() != 0:
+ sys.exit('Requires root privileges')
+
+parser = ArgumentParser()
+parser.add_argument('--disable', action='store_true',
+ help='enable/disable vyconf backend')
+parser.add_argument('--no-prompt', action='store_true',
+ help='confirm without prompt')
+
+args = parser.parse_args()
+
+match args.disable:
+ case False:
+ set_vyconf_backend(True, no_prompt=args.no_prompt)
+ case True:
+ set_vyconf_backend(False, no_prompt=args.no_prompt)
diff --git a/src/helpers/show_commit_data.py b/src/helpers/show_commit_data.py
index d507ed9a4..85ee64cb1 100755
--- a/src/helpers/show_commit_data.py
+++ b/src/helpers/show_commit_data.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/strip-private.py b/src/helpers/strip-private.py
index cb29069cf..71b7c079a 100755
--- a/src/helpers/strip-private.py
+++ b/src/helpers/strip-private.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2021-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/helpers/teardown-config-session.py b/src/helpers/teardown-config-session.py
new file mode 100755
index 000000000..c30303c99
--- /dev/null
+++ b/src/helpers/teardown-config-session.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+#
+# Copyright 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 sys
+
+from vyos.vyconf_session import VyconfSession
+
+if len(sys.argv) < 2:
+ sys.exit('session pid is required')
+
+pid = sys.argv[1]
+
+vc = VyconfSession(pid=pid)
+vc.teardown()
diff --git a/src/helpers/test_commit.py b/src/helpers/test_commit.py
index 00a413687..cfff85b9d 100755
--- a/src/helpers/test_commit.py
+++ b/src/helpers/test_commit.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyconf_cli.py b/src/helpers/vyconf_cli.py
new file mode 100755
index 000000000..53542dd63
--- /dev/null
+++ b/src/helpers/vyconf_cli.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+#
+# Copyright 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
+import sys
+
+from vyos.vyconf_session import VyconfSession
+
+
+pid = os.getppid()
+
+vs = VyconfSession(pid=pid)
+
+script_path = sys.argv[0]
+script_name = os.path.basename(script_path)
+# drop prefix 'vy_' if present
+if script_name.startswith('vy_'):
+ func_name = script_name[3:]
+else:
+ func_name = script_name
+
+if hasattr(vs, func_name):
+ func = getattr(vs, func_name)
+else:
+ sys.exit(f'Call unimplemented: {func_name}')
+
+out = func()
+if isinstance(out, bool):
+ # for use in shell scripts
+ sys.exit(int(not out))
+
+print(out)
diff --git a/src/helpers/vyos-boot-config-loader.py b/src/helpers/vyos-boot-config-loader.py
index 42de696ce..e20b8415f 100755
--- a/src/helpers/vyos-boot-config-loader.py
+++ b/src/helpers/vyos-boot-config-loader.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos-check-wwan.py b/src/helpers/vyos-check-wwan.py
index 334f08dd3..4768ddf3f 100755
--- a/src/helpers/vyos-check-wwan.py
+++ b/src/helpers/vyos-check-wwan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos-config-encrypt.py b/src/helpers/vyos-config-encrypt.py
index 84860bd6a..5f49ca119 100755
--- a/src/helpers/vyos-config-encrypt.py
+++ b/src/helpers/vyos-config-encrypt.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos-failover.py b/src/helpers/vyos-failover.py
index 348974364..96db947e1 100755
--- a/src/helpers/vyos-failover.py
+++ b/src/helpers/vyos-failover.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos-interface-rescan.py b/src/helpers/vyos-interface-rescan.py
index 012357259..fea9bca1c 100755
--- a/src/helpers/vyos-interface-rescan.py
+++ b/src/helpers/vyos-interface-rescan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos-load-balancer.py b/src/helpers/vyos-load-balancer.py
index 30329fd5c..850c5142e 100755
--- a/src/helpers/vyos-load-balancer.py
+++ b/src/helpers/vyos-load-balancer.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2024-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -246,6 +246,7 @@ if __name__ == '__main__':
# Main loop
+ init = True;
try:
while True:
ip_change = False
@@ -273,6 +274,11 @@ if __name__ == '__main__':
if state_changed and state['failure_count'] >= int(health_conf['failure_count']):
state['state'] = False
state['state_changed'] = True
+
+ #Force state changed to trigger the first write
+ if init == True:
+ state['state_changed'] = True
+ init = False
if state['state_changed']:
state['if_addr'] = get_ipv4_address(ifname)
diff --git a/src/helpers/vyos-load-config.py b/src/helpers/vyos-load-config.py
index 16083fd41..01a6a88dc 100755
--- a/src/helpers/vyos-load-config.py
+++ b/src/helpers/vyos-load-config.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -16,84 +16,57 @@
#
#
-"""Load config file from within config session.
-Config file specified by URI or path (without scheme prefix).
-Example: load https://somewhere.net/some.config
- or
- load /tmp/some.config
-"""
-
import os
import sys
-import gzip
+import argparse
import tempfile
-import vyos.defaults
-import vyos.remote
-from vyos.configsource import ConfigSourceSession, VyOSError
+
+from vyos.remote import get_config_file
+from vyos.config import Config
from vyos.migrate import ConfigMigrate
from vyos.migrate import ConfigMigrateError
+from vyos.load_config import load as load_config
-class LoadConfig(ConfigSourceSession):
- """A subclass for calling 'loadFile'.
- This does not belong in configsource.py, and only has a single caller.
- """
- def load_config(self, path):
- return self._run(['/bin/cli-shell-api','loadFile',path])
-
-file_name = sys.argv[1] if len(sys.argv) > 1 else 'config.boot'
-configdir = vyos.defaults.directories['config']
-protocols = ['scp', 'sftp', 'http', 'https', 'ftp', 'tftp']
-def get_local_config(filename):
- if os.path.isfile(filename):
- fname = filename
- elif os.path.isfile(os.path.join(configdir, filename)):
- fname = os.path.join(configdir, filename)
- else:
- sys.exit(f"No such file '{filename}'")
+parser = argparse.ArgumentParser()
+parser.add_argument('config_file', help='config file to load')
+parser.add_argument(
+ '--migrate', action='store_true', help='migrate config file before merge'
+)
- if fname.endswith('.gz'):
- with gzip.open(fname, 'rb') as f:
- try:
- config_str = f.read().decode()
- except OSError as e:
- sys.exit(e)
- else:
- with open(fname, 'r') as f:
- try:
- config_str = f.read()
- except OSError as e:
- sys.exit(e)
+args = parser.parse_args()
- return config_str
-
-if any(file_name.startswith(f'{x}://') for x in protocols):
- config_string = vyos.remote.get_remote_config(file_name)
- if not config_string:
- sys.exit(f"No such config file at '{file_name}'")
-else:
- config_string = get_local_config(file_name)
+file_name = args.config_file
-config = LoadConfig()
+# pylint: disable=consider-using-with
+file_path = tempfile.NamedTemporaryFile(delete=False).name
+err = get_config_file(file_name, file_path)
+if err:
+ os.remove(file_path)
+ sys.exit(err)
-print(f"Loading configuration from '{file_name}'")
+if args.migrate:
+ migrate = ConfigMigrate(file_path)
+ try:
+ migrate.run()
+ except ConfigMigrateError as e:
+ os.remove(file_path)
+ sys.exit(e)
-with tempfile.NamedTemporaryFile() as fp:
- with open(fp.name, 'w') as fd:
- fd.write(config_string)
+config = Config()
- config_migrate = ConfigMigrate(fp.name)
- try:
- config_migrate.run()
- except ConfigMigrateError as err:
- sys.exit(err)
+if config.vyconf_session is not None:
+ out, err = config.vyconf_session.load_config(file_path)
+ if err:
+ os.remove(file_path)
+ sys.exit(out)
+ print(out)
+else:
+ load_config(file_path)
- try:
- config.load_config(fp.name)
- except VyOSError as err:
- sys.exit(err)
+os.remove(file_path)
if config.session_changed():
print("Load complete. Use 'commit' to make changes effective.")
else:
- print("No configuration changes to commit.")
+ print('No configuration changes to commit.')
diff --git a/src/helpers/vyos-merge-config.py b/src/helpers/vyos-merge-config.py
index 5ef845ac2..e8a696eb5 100755
--- a/src/helpers/vyos-merge-config.py
+++ b/src/helpers/vyos-merge-config.py
@@ -1,108 +1,101 @@
#!/usr/bin/python3
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
+# 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 library is distributed in the hope that it will be useful,
+# 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
-# Lesser General Public License for more details.
+# 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/>.
+#
#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+import os
import sys
+import shlex
+import argparse
import tempfile
-import vyos.defaults
-import vyos.remote
+from vyos.remote import get_config_file
from vyos.config import Config
from vyos.configtree import ConfigTree
+from vyos.configtree import mask_inclusive
+from vyos.configtree import merge
from vyos.migrate import ConfigMigrate
from vyos.migrate import ConfigMigrateError
-from vyos.utils.process import cmd
-from vyos.utils.process import DEVNULL
+from vyos.load_config import load_explicit
-if (len(sys.argv) < 2):
- print("Need config file name to merge.")
- print("Usage: merge <config file> [config path]")
- sys.exit(0)
-file_name = sys.argv[1]
+parser = argparse.ArgumentParser()
+parser.add_argument('config_file', help='config file to merge from')
+parser.add_argument(
+ '--destructive', action='store_true', help='replace values with those of merge file'
+)
+parser.add_argument('--paths', nargs='+', help='only merge from listed paths')
+parser.add_argument(
+ '--migrate', action='store_true', help='migrate config file before merge'
+)
-configdir = vyos.defaults.directories['config']
+args = parser.parse_args()
-protocols = ['scp', 'sftp', 'http', 'https', 'ftp', 'tftp']
+file_name = args.config_file
+paths = [shlex.split(s) for s in args.paths] if args.paths else []
-if any(x in file_name for x in protocols):
- config_file = vyos.remote.get_remote_config(file_name)
- if not config_file:
- sys.exit("No config file by that name.")
-else:
- canonical_path = "{0}/{1}".format(configdir, file_name)
- first_err = None
- try:
- with open(canonical_path, 'r') as f:
- config_file = f.read()
- except Exception as err:
- first_err = err
- try:
- with open(file_name, 'r') as f:
- config_file = f.read()
- except Exception as err:
- print(first_err)
- print(err)
- sys.exit(1)
-
-with tempfile.NamedTemporaryFile() as file_to_migrate:
- with open(file_to_migrate.name, 'w') as fd:
- fd.write(config_file)
-
- config_migrate = ConfigMigrate(file_to_migrate.name)
+# pylint: disable=consider-using-with
+file_path = tempfile.NamedTemporaryFile(delete=False).name
+err = get_config_file(file_name, file_path)
+if err:
+ os.remove(file_path)
+ sys.exit(err)
+
+if args.migrate:
+ migrate = ConfigMigrate(file_path)
try:
- config_migrate.run()
+ migrate.run()
except ConfigMigrateError as e:
+ os.remove(file_path)
sys.exit(e)
-merge_config_tree = ConfigTree(config_file)
+with open(file_path) as f:
+ merge_str = f.read()
+
+merge_ct = ConfigTree(merge_str)
-effective_config = Config()
-effective_config_tree = effective_config._running_config
+if paths:
+ mask = ConfigTree('')
+ for p in paths:
+ mask.set(p)
-effective_cmds = effective_config_tree.to_commands()
-merge_cmds = merge_config_tree.to_commands()
+ merge_ct = mask_inclusive(merge_ct, mask)
-effective_cmd_list = effective_cmds.splitlines()
-merge_cmd_list = merge_cmds.splitlines()
+with open(file_path, 'w') as f:
+ f.write(merge_ct.to_string())
-effective_cmd_set = set(effective_cmd_list)
-add_cmds = [ cmd for cmd in merge_cmd_list if cmd not in effective_cmd_set ]
+config = Config()
-path = None
-if (len(sys.argv) > 2):
- path = sys.argv[2:]
- if (not effective_config_tree.exists(path) and not
- merge_config_tree.exists(path)):
- print("path {} does not exist in either effective or merge"
- " config; will use root.".format(path))
- path = None
- else:
- path = " ".join(path)
+if config.vyconf_session is not None:
+ out, err = config.vyconf_session.merge_config(
+ file_path, destructive=args.destructive
+ )
+ if err:
+ os.remove(file_path)
+ sys.exit(out)
+ print(out)
+else:
+ session_ct = config.get_config_tree()
+ merge_res = merge(session_ct, merge_ct, destructive=args.destructive)
-if path:
- add_cmds = [ cmd for cmd in add_cmds if path in cmd ]
+ load_explicit(merge_res)
-for add in add_cmds:
- try:
- cmd(f'/opt/vyatta/sbin/my_{add}', shell=True, stderr=DEVNULL)
- except OSError as err:
- print(err)
+os.remove(file_path)
-if effective_config.session_changed():
+if config.session_changed():
print("Merge complete. Use 'commit' to make changes effective.")
else:
- print("No configuration changes to commit.")
+ print('No configuration changes to commit.')
diff --git a/src/helpers/vyos-save-config.py b/src/helpers/vyos-save-config.py
index fa2ea0ce4..adf62b71d 100755
--- a/src/helpers/vyos-save-config.py
+++ b/src/helpers/vyos-save-config.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos_config_sync.py b/src/helpers/vyos_config_sync.py
index 9d9aec376..80bfb6d17 100755
--- a/src/helpers/vyos_config_sync.py
+++ b/src/helpers/vyos_config_sync.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/helpers/vyos_net_name b/src/helpers/vyos_net_name
index f5de182c6..6ad7af2d6 100755
--- a/src/helpers/vyos_net_name
+++ b/src/helpers/vyos_net_name
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/init/vyos-router b/src/init/vyos-router
index 565b778e6..563f12755 100755
--- a/src/init/vyos-router
+++ b/src/init/vyos-router
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -67,37 +67,50 @@ disabled () {
grep -q -w no-vyos-$1 /proc/cmdline
}
+motd_helper() {
+ MOTD_DIR="/run/motd.d"
+ MOTD_FILE="${MOTD_DIR}/99-vyos-update-failed"
+
+ if [[ ! -d ${MOTD_DIR} ]]; then
+ mkdir -p ${MOTD_DIR}
+ fi
+
+ echo "" > ${MOTD_FILE}
+ echo "WARNING: Image update to \"$1\" failed." >> ${MOTD_FILE}
+ echo "Please check the logs:" >> ${MOTD_FILE}
+ echo "/usr/lib/live/mount/persistence/boot/$1/rw/var/log" >> ${MOTD_FILE}
+ echo "Message is cleared on next reboot!" >> ${MOTD_FILE}
+ echo "" >> ${MOTD_FILE}
+}
+
# Load encrypted config volume
mount_encrypted_config() {
persist_path=$(/opt/vyatta/sbin/vyos-persistpath)
if [ $? == 0 ]; then
if [ -e $persist_path/boot ]; then
image_name=$(cat /proc/cmdline | sed -e s+^.*vyos-union=/boot/++ | sed -e 's/ .*$//')
-
if [ -z "$image_name" ]; then
- return
+ return 0
fi
if [ ! -f $persist_path/luks/$image_name ]; then
- return
+ return 0
fi
vyos_tpm_key=$(python3 -c 'from vyos.tpm import read_tpm_key; print(read_tpm_key().decode())' 2>/dev/null)
-
if [ $? -ne 0 ]; then
echo "ERROR: Failed to fetch encryption key from TPM. Encrypted config volume has not been mounted"
echo "Use 'encryption load' to load volume with recovery key"
echo "or 'encryption disable' to decrypt volume with recovery key"
- return
+ return 1
fi
echo $vyos_tpm_key | tr -d '\r\n' | cryptsetup open $persist_path/luks/$image_name vyos_config --key-file=-
-
if [ $? -ne 0 ]; then
echo "ERROR: Failed to decrypt config volume. Encrypted config volume has not been mounted"
echo "Use 'encryption load' to load volume with recovery key"
echo "or 'encryption disable' to decrypt volume with recovery key"
- return
+ return 1
fi
mount /dev/mapper/vyos_config /config
@@ -106,6 +119,7 @@ mount_encrypted_config() {
echo "Mounted encrypted config volume"
fi
fi
+ return 0
}
unmount_encrypted_config() {
@@ -160,11 +174,16 @@ migrate_bootfile ()
if [ -x $vyos_libexec_dir/run-config-migration.py ]; then
log_progress_msg migrate
sg ${GROUP} -c "$vyos_libexec_dir/run-config-migration.py $BOOTFILE"
+ STATUS=$?
+ if [[ "$STATUS" != "0" ]]; then
+ return 1
+ fi
# update vyconf copy after migration
if [ -d $VYCONF_CONFIG_DIR ] ; then
cp -f $BOOTFILE $VYCONF_CONFIG_DIR/config.boot
fi
fi
+ return 0
}
# configure system-specific settings
@@ -187,8 +206,13 @@ load_bootfile ()
fi
if [ -x $vyos_libexec_dir/vyos-boot-config-loader.py ]; then
sg ${GROUP} -c "$vyos_libexec_dir/vyos-boot-config-loader.py $BOOTFILE"
+ STATUS=$?
+ if [[ "$STATUS" != "0" ]]; then
+ return 1
+ fi
fi
)
+ return 0
}
# restore if missing pre-config script
@@ -289,10 +313,10 @@ clear_or_override_config_files ()
keepalived/keepalived.conf cron.d/vyos-crontab \
ipvsadm.rules default/ipvsadm resolv.conf
do
- if [ -s /etc/$conf ] ; then
- empty /etc/$conf
- chmod 0644 /etc/$conf
- fi
+ if [ -s /etc/$conf ] ; then
+ empty /etc/$conf
+ chmod 0644 /etc/$conf
+ fi
done
}
@@ -396,7 +420,10 @@ gen_duid ()
UUID=$(cat ${UUID_FILE} | tr -d -)
fi
if [ -z ${UUID} ]; then
- UUID=$(uuidgen --sha1 --namespace @dns --name $(cat ${UUID_FILE_ALT}) | tr -d -)
+ file_alt="$(cat ${UUID_FILE_ALT})"
+ if [ -n "${file_alt}" ]; then
+ UUID=$(uuidgen --sha1 --namespace @dns --name ${file_alt} | tr -d -)
+ fi
fi
# Add DUID type4 (UUID) information
DUID_TYPE="0004"
@@ -417,7 +444,8 @@ gen_duid ()
start ()
{
- echo -e "Initializing VyOS router\033[0m"
+ log_success_msg "Starting VyOS router"
+
# reset and clean config files
security_reset || log_failure_msg "security reset failed"
@@ -460,6 +488,14 @@ start ()
nfct helper add tns inet6 tcp
nft --file /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules"
+ # Ensure rsyslog is the default syslog daemon
+ SYSTEMD_SYSLOG="/etc/systemd/system/syslog.service"
+ SYSTEMD_RSYSLOG="/lib/systemd/system/rsyslog.service"
+ if [ ! -L ${SYSTEMD_SYSLOG} ] || [ "$(readlink -f ${SYSTEMD_SYSLOG})" != "${SYSTEMD_RSYSLOG}" ]; then
+ ln -sf ${SYSTEMD_RSYSLOG} ${SYSTEMD_SYSLOG}
+ systemctl daemon-reload
+ fi
+
# As VyOS does not execute commands that are not present in the CLI we call
# the script by hand to have a single source for the login banner and MOTD
${vyos_conf_scripts_dir}/system_syslog.py || log_failure_msg "could not reset syslog"
@@ -475,7 +511,7 @@ start ()
# enable some debugging before loading the configuration
if grep -q vyos-debug /proc/cmdline; then
- log_action_begin_msg "Enable runtime debugging options"
+ log_success_msg "Enable runtime debugging options"
FRR_DEBUG=$(python3 -c "from vyos.defaults import frr_debug_enable; print(frr_debug_enable)")
touch $FRR_DEBUG
touch /tmp/vyos.container.debug
@@ -502,7 +538,7 @@ start ()
&& chgrp ${GROUP} ${vyatta_configdir}
log_action_end_msg $?
- mount_encrypted_config
+ mount_encrypted_config || overall_status=1
# T5239: early read of system hostname as this value is read-only once during
# FRR initialisation
@@ -518,7 +554,7 @@ start ()
cleanup_post_commit_hooks
- disabled migrate || migrate_bootfile
+ disabled migrate || migrate_bootfile || overall_status=1
restore_if_missing_preconfig_script
@@ -526,27 +562,66 @@ start ()
run_postupgrade_script
- update_interface_config
+ update_interface_config || overall_status=1
- disabled system_config || system_config
+ disabled system_config || system_config || overall_status=1
systemctl start vyconfd.service
for s in ${subinit[@]} ; do
- if ! disabled $s; then
- log_progress_msg $s
- if ! ${vyatta_sbindir}/${s}.init start
- then log_failure_msg
- exit 1
+ if ! disabled $s; then
+ log_progress_msg $s
+ if ! ${vyatta_sbindir}/${s}.init start
+ then log_failure_msg
+ exit 1
+ fi
fi
- fi
done
bind_mount_boot
- disabled configure || load_bootfile
+ disabled configure || load_bootfile || overall_status=1
log_end_msg $?
+ FIRST_BOOT_FILE="/config/first_boot"
+ UPDATE_FAILED_BOOT_FILE="/config/update_failed"
+ AUTOMATIC_REBOOT_TMO=$(${vyos_libexec_dir}/read-saved-value.py --path "system option reboot-on-upgrade-failure")
+ # Image upgrade failed - get previous image name, re-set it as default image
+ # and perform an automatic reboot. Automatic reboot timeout can be set via CLI
+ if [[ -n $AUTOMATIC_REBOOT_TMO ]] && [[ -f ${FIRST_BOOT_FILE} ]] && [[ ${overall_status} -ne 0 ]]; then
+ previous_image=$(jq -r '.previous_image' ${FIRST_BOOT_FILE})
+
+ # If the image update failed, we need to inform the image we will revert
+ # to about this
+ running_image=$(${vyos_op_scripts_dir}/image_info.py show_images_current --raw | jq -r '.image_running')
+ echo "{\"failed_image_update\": \"${running_image}\"}" \
+ > /usr/lib/live/mount/persistence/boot/${previous_image}/rw/${UPDATE_FAILED_BOOT_FILE}
+
+ ${vyos_op_scripts_dir}/image_manager.py --action set --image-name "${previous_image}" >/dev/null 2>&1
+ motd_helper "${running_image}"
+
+ log_daemon_msg "Booting failed, reverting to previous image"
+ log_progress_msg ${previous_image}
+ log_end_msg 0
+ log_daemon_msg "Automatic reboot in ${AUTOMATIC_REBOOT_TMO} minutes"
+ sync ; shutdown --reboot --no-wall ${AUTOMATIC_REBOOT_TMO} >/dev/null 2>&1
+ log_progress_msg "Use \"reboot cancel\" to cancel"
+ log_end_msg 0
+ fi
+ # After image upgrade failure and once booted into the previous working
+ # image, inform the user via MOTD about the failure
+ if [[ -n $AUTOMATIC_REBOOT_TMO ]] && [[ -f ${UPDATE_FAILED_BOOT_FILE} ]] ; then
+ failed_image_update=$(jq -r '.failed_image_update' ${UPDATE_FAILED_BOOT_FILE})
+ motd_helper "${failed_image_update}"
+ fi
+ # Clear marker files used by automatic reboot on image upgrade mechanism
+ if [[ -f ${FIRST_BOOT_FILE} ]]; then
+ rm -f ${FIRST_BOOT_FILE}
+ fi
+ if [[ -f ${UPDATE_FAILED_BOOT_FILE} ]] ; then
+ rm -f ${UPDATE_FAILED_BOOT_FILE}
+ fi
+
telinit q
chmod g-w,o-w /
@@ -557,6 +632,9 @@ start ()
if [[ ! -z "$tmp" ]]; then
vtysh -c "rpki start"
fi
+
+ # Start netplug daemon
+ systemctl start netplug.service
}
stop()
@@ -574,8 +652,8 @@ stop()
umount ${vyatta_configdir}
log_action_end_msg $?
+ systemctl stop netplug.service
systemctl stop vyconfd.service
-
systemctl stop frr.service
unmount_encrypted_config
diff --git a/src/migration-scripts/bgp/0-to-1 b/src/migration-scripts/bgp/0-to-1
index a2f3343d8..a072286ea 100644
--- a/src/migration-scripts/bgp/0-to-1
+++ b/src/migration-scripts/bgp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/bgp/1-to-2 b/src/migration-scripts/bgp/1-to-2
index c0fc3b05a..64732ac72 100644
--- a/src/migration-scripts/bgp/1-to-2
+++ b/src/migration-scripts/bgp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/bgp/2-to-3 b/src/migration-scripts/bgp/2-to-3
index d8bc34db6..9d3ab3ecf 100644
--- a/src/migration-scripts/bgp/2-to-3
+++ b/src/migration-scripts/bgp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/bgp/3-to-4 b/src/migration-scripts/bgp/3-to-4
index 842aef0ce..9e45bd4d6 100644
--- a/src/migration-scripts/bgp/3-to-4
+++ b/src/migration-scripts/bgp/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/bgp/4-to-5 b/src/migration-scripts/bgp/4-to-5
index d779eb11e..42b2fd0b6 100644
--- a/src/migration-scripts/bgp/4-to-5
+++ b/src/migration-scripts/bgp/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/bgp/5-to-6 b/src/migration-scripts/bgp/5-to-6
index e6fea6574..5e5090587 100644
--- a/src/migration-scripts/bgp/5-to-6
+++ b/src/migration-scripts/bgp/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/cluster/1-to-2 b/src/migration-scripts/cluster/1-to-2
index 5ca4531ea..5e5136a64 100644
--- a/src/migration-scripts/cluster/1-to-2
+++ b/src/migration-scripts/cluster/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/config-management/0-to-1 b/src/migration-scripts/config-management/0-to-1
index 44c685630..9c1b96a4b 100644
--- a/src/migration-scripts/config-management/0-to-1
+++ b/src/migration-scripts/config-management/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack-sync/1-to-2 b/src/migration-scripts/conntrack-sync/1-to-2
index 3e10e98c3..793bf01d8 100644
--- a/src/migration-scripts/conntrack-sync/1-to-2
+++ b/src/migration-scripts/conntrack-sync/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack/1-to-2 b/src/migration-scripts/conntrack/1-to-2
index 0a4fb3de9..5b126c8ab 100644
--- a/src/migration-scripts/conntrack/1-to-2
+++ b/src/migration-scripts/conntrack/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack/2-to-3 b/src/migration-scripts/conntrack/2-to-3
index 5ad4e6350..e74fe3105 100644
--- a/src/migration-scripts/conntrack/2-to-3
+++ b/src/migration-scripts/conntrack/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack/3-to-4 b/src/migration-scripts/conntrack/3-to-4
index 679a260d5..709f97310 100644
--- a/src/migration-scripts/conntrack/3-to-4
+++ b/src/migration-scripts/conntrack/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack/4-to-5 b/src/migration-scripts/conntrack/4-to-5
index 775fe7480..b5d2a79bc 100644
--- a/src/migration-scripts/conntrack/4-to-5
+++ b/src/migration-scripts/conntrack/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/conntrack/5-to-6 b/src/migration-scripts/conntrack/5-to-6
new file mode 100644
index 000000000..330849243
--- /dev/null
+++ b/src/migration-scripts/conntrack/5-to-6
@@ -0,0 +1,30 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# T7202: fix lower limit of supported conntrack hash-size to match Kernel
+# lower limit.
+
+from vyos.configtree import ConfigTree
+
+base = ['system', 'conntrack']
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
+ if config.exists(base + ['hash-size']):
+ tmp = config.return_value(base + ['hash-size'])
+ if int(tmp) < 1024:
+ config.set(base + ['hash-size'], value=1024)
diff --git a/src/migration-scripts/container/0-to-1 b/src/migration-scripts/container/0-to-1
index 99102a5e6..db0b6de2b 100644
--- a/src/migration-scripts/container/0-to-1
+++ b/src/migration-scripts/container/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/container/1-to-2 b/src/migration-scripts/container/1-to-2
index c12dd8ebb..8664cfac9 100644
--- a/src/migration-scripts/container/1-to-2
+++ b/src/migration-scripts/container/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/container/2-to-3 b/src/migration-scripts/container/2-to-3
new file mode 100644
index 000000000..0b43ecdb2
--- /dev/null
+++ b/src/migration-scripts/container/2-to-3
@@ -0,0 +1,31 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# T7473: container: allow log-driver to be set per container
+
+from vyos.configtree import ConfigTree
+
+def migrate(config: ConfigTree) -> None:
+ log_base = ['container', 'log-driver']
+ container_base = ['container', 'name']
+
+ if not config.exists(log_base):
+ return
+ else:
+ log_driver = config.return_value(log_base)
+ for container in config.list_nodes(container_base):
+ # Set the log-driver for each container
+ config.set(container_base + [container, 'log-driver'], value=log_driver)
+ config.delete(log_base)
diff --git a/src/migration-scripts/dhcp-relay/1-to-2 b/src/migration-scripts/dhcp-relay/1-to-2
index 54cd8d6c0..50ac29df1 100644
--- a/src/migration-scripts/dhcp-relay/1-to-2
+++ b/src/migration-scripts/dhcp-relay/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/10-to-11 b/src/migration-scripts/dhcp-server/10-to-11
index f54a4c7b7..82f303868 100644
--- a/src/migration-scripts/dhcp-server/10-to-11
+++ b/src/migration-scripts/dhcp-server/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/4-to-5 b/src/migration-scripts/dhcp-server/4-to-5
index a655515dc..9b121d23f 100644
--- a/src/migration-scripts/dhcp-server/4-to-5
+++ b/src/migration-scripts/dhcp-server/4-to-5
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/5-to-6 b/src/migration-scripts/dhcp-server/5-to-6
index 9404cd038..fd2ed9e34 100644
--- a/src/migration-scripts/dhcp-server/5-to-6
+++ b/src/migration-scripts/dhcp-server/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/6-to-7 b/src/migration-scripts/dhcp-server/6-to-7
index 4e6583a31..fbb8c06f9 100644
--- a/src/migration-scripts/dhcp-server/6-to-7
+++ b/src/migration-scripts/dhcp-server/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/7-to-8 b/src/migration-scripts/dhcp-server/7-to-8
index 7fcb62e86..fb939e020 100644
--- a/src/migration-scripts/dhcp-server/7-to-8
+++ b/src/migration-scripts/dhcp-server/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -41,9 +41,6 @@ def migrate(config: ConfigTree) -> None:
for network in config.list_nodes(base + ['shared-network-name']):
base_network = base + ['shared-network-name', network]
- if config.exists(base_network + ['ping-check']):
- config.delete(base_network + ['ping-check'])
-
if config.exists(base_network + ['shared-network-parameters']):
config.delete(base_network +['shared-network-parameters'])
@@ -57,9 +54,6 @@ def migrate(config: ConfigTree) -> None:
if config.exists(base_subnet + ['enable-failover']):
config.delete(base_subnet + ['enable-failover'])
- if config.exists(base_subnet + ['ping-check']):
- config.delete(base_subnet + ['ping-check'])
-
if config.exists(base_subnet + ['subnet-parameters']):
config.delete(base_subnet + ['subnet-parameters'])
diff --git a/src/migration-scripts/dhcp-server/8-to-9 b/src/migration-scripts/dhcp-server/8-to-9
index 5843e9fda..34c80cb22 100644
--- a/src/migration-scripts/dhcp-server/8-to-9
+++ b/src/migration-scripts/dhcp-server/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcp-server/9-to-10 b/src/migration-scripts/dhcp-server/9-to-10
index eda97550d..0d3d53d5e 100644
--- a/src/migration-scripts/dhcp-server/9-to-10
+++ b/src/migration-scripts/dhcp-server/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/0-to-1 b/src/migration-scripts/dhcpv6-server/0-to-1
index fd9b2d739..e46063a26 100644
--- a/src/migration-scripts/dhcpv6-server/0-to-1
+++ b/src/migration-scripts/dhcpv6-server/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 202-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/1-to-2 b/src/migration-scripts/dhcpv6-server/1-to-2
index ad307495c..cd7b06673 100644
--- a/src/migration-scripts/dhcpv6-server/1-to-2
+++ b/src/migration-scripts/dhcpv6-server/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/2-to-3 b/src/migration-scripts/dhcpv6-server/2-to-3
index b44798d18..728720ecb 100644
--- a/src/migration-scripts/dhcpv6-server/2-to-3
+++ b/src/migration-scripts/dhcpv6-server/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/3-to-4 b/src/migration-scripts/dhcpv6-server/3-to-4
index e38e36505..db10fcb6c 100644
--- a/src/migration-scripts/dhcpv6-server/3-to-4
+++ b/src/migration-scripts/dhcpv6-server/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/4-to-5 b/src/migration-scripts/dhcpv6-server/4-to-5
index ad18e1a84..fd8c63644 100644
--- a/src/migration-scripts/dhcpv6-server/4-to-5
+++ b/src/migration-scripts/dhcpv6-server/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dhcpv6-server/5-to-6 b/src/migration-scripts/dhcpv6-server/5-to-6
index cad0a3538..e12020597 100644
--- a/src/migration-scripts/dhcpv6-server/5-to-6
+++ b/src/migration-scripts/dhcpv6-server/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-dynamic/0-to-1 b/src/migration-scripts/dns-dynamic/0-to-1
index 6a91b36af..a75fedcad 100644
--- a/src/migration-scripts/dns-dynamic/0-to-1
+++ b/src/migration-scripts/dns-dynamic/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-dynamic/1-to-2 b/src/migration-scripts/dns-dynamic/1-to-2
index 7f4938147..6398b902f 100644
--- a/src/migration-scripts/dns-dynamic/1-to-2
+++ b/src/migration-scripts/dns-dynamic/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-dynamic/2-to-3 b/src/migration-scripts/dns-dynamic/2-to-3
index 9aafc41a4..bd6ed7c00 100644
--- a/src/migration-scripts/dns-dynamic/2-to-3
+++ b/src/migration-scripts/dns-dynamic/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-dynamic/3-to-4 b/src/migration-scripts/dns-dynamic/3-to-4
index c8e1ffeee..ff640f7ef 100644
--- a/src/migration-scripts/dns-dynamic/3-to-4
+++ b/src/migration-scripts/dns-dynamic/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-forwarding/0-to-1 b/src/migration-scripts/dns-forwarding/0-to-1
index 264ffb40d..fe1669e84 100644
--- a/src/migration-scripts/dns-forwarding/0-to-1
+++ b/src/migration-scripts/dns-forwarding/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-forwarding/1-to-2 b/src/migration-scripts/dns-forwarding/1-to-2
index 15ed1e136..2d90078ec 100644
--- a/src/migration-scripts/dns-forwarding/1-to-2
+++ b/src/migration-scripts/dns-forwarding/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-forwarding/2-to-3 b/src/migration-scripts/dns-forwarding/2-to-3
index 729c1f00a..0fdfd8447 100644
--- a/src/migration-scripts/dns-forwarding/2-to-3
+++ b/src/migration-scripts/dns-forwarding/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/dns-forwarding/3-to-4 b/src/migration-scripts/dns-forwarding/3-to-4
index b02c0b7ca..f22cfea81 100644
--- a/src/migration-scripts/dns-forwarding/3-to-4
+++ b/src/migration-scripts/dns-forwarding/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11
index 70a170940..50d3eb89b 100644
--- a/src/migration-scripts/firewall/10-to-11
+++ b/src/migration-scripts/firewall/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/11-to-12 b/src/migration-scripts/firewall/11-to-12
index 80a74cca9..ff4f71614 100644
--- a/src/migration-scripts/firewall/11-to-12
+++ b/src/migration-scripts/firewall/11-to-12
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/12-to-13 b/src/migration-scripts/firewall/12-to-13
index d7b801cd3..58c4e864a 100644
--- a/src/migration-scripts/firewall/12-to-13
+++ b/src/migration-scripts/firewall/12-to-13
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/13-to-14 b/src/migration-scripts/firewall/13-to-14
index 723b0aea2..dbd585584 100644
--- a/src/migration-scripts/firewall/13-to-14
+++ b/src/migration-scripts/firewall/13-to-14
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/14-to-15 b/src/migration-scripts/firewall/14-to-15
index e4a2aaee4..e3f5bd554 100644
--- a/src/migration-scripts/firewall/14-to-15
+++ b/src/migration-scripts/firewall/14-to-15
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/15-to-16 b/src/migration-scripts/firewall/15-to-16
index 8e28bba6f..1eac943ba 100644
--- a/src/migration-scripts/firewall/15-to-16
+++ b/src/migration-scripts/firewall/15-to-16
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/migration-scripts/firewall/16-to-17 b/src/migration-scripts/firewall/16-to-17
index ad0706f04..e0582aeab 100644
--- a/src/migration-scripts/firewall/16-to-17
+++ b/src/migration-scripts/firewall/16-to-17
@@ -1,4 +1,4 @@
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/migration-scripts/firewall/17-to-18 b/src/migration-scripts/firewall/17-to-18
index 34ce6aa07..6cde20870 100755
--- a/src/migration-scripts/firewall/17-to-18
+++ b/src/migration-scripts/firewall/17-to-18
@@ -1,4 +1,4 @@
-# Copyright (C) 2024-2025 VyOS maintainers and contributors
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/18-to-19 b/src/migration-scripts/firewall/18-to-19
new file mode 100644
index 000000000..bcc4a482b
--- /dev/null
+++ b/src/migration-scripts/firewall/18-to-19
@@ -0,0 +1,35 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# From
+# set firewall global-options apply-to-bridged-traffic invalid-connections
+# To
+# set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type <ethertype>
+
+from vyos.configtree import ConfigTree
+
+base = ['firewall', 'global-options', 'apply-to-bridged-traffic']
+
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base + ['invalid-connections']):
+ # Nothing to do
+ return
+
+ ether_types = ['dhcp', 'arp', 'pppoe-discovery', 'pppoe', '802.1q', '802.1ad', 'wol']
+
+ for ether_type in ether_types:
+ config.set(base + ['accept-invalid', 'ethernet-type'], value=ether_type, replace=False)
+
+ config.delete(base + ['invalid-connections'])
diff --git a/src/migration-scripts/firewall/5-to-6 b/src/migration-scripts/firewall/5-to-6
index d01684787..49348a620 100644
--- a/src/migration-scripts/firewall/5-to-6
+++ b/src/migration-scripts/firewall/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/6-to-7 b/src/migration-scripts/firewall/6-to-7
index 1afbc780b..2626d76ee 100644
--- a/src/migration-scripts/firewall/6-to-7
+++ b/src/migration-scripts/firewall/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/7-to-8 b/src/migration-scripts/firewall/7-to-8
index b8bcc52cc..80303849e 100644
--- a/src/migration-scripts/firewall/7-to-8
+++ b/src/migration-scripts/firewall/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/8-to-9 b/src/migration-scripts/firewall/8-to-9
index 3c9e84662..916000387 100644
--- a/src/migration-scripts/firewall/8-to-9
+++ b/src/migration-scripts/firewall/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/firewall/9-to-10 b/src/migration-scripts/firewall/9-to-10
index 306a53a86..57970e8ab 100644
--- a/src/migration-scripts/firewall/9-to-10
+++ b/src/migration-scripts/firewall/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/flow-accounting/0-to-1 b/src/migration-scripts/flow-accounting/0-to-1
index 77670e3ef..af4c6cbe6 100644
--- a/src/migration-scripts/flow-accounting/0-to-1
+++ b/src/migration-scripts/flow-accounting/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/flow-accounting/1-to-2 b/src/migration-scripts/flow-accounting/1-to-2
index 5ffb1eec8..c1a48274e 100644
--- a/src/migration-scripts/flow-accounting/1-to-2
+++ b/src/migration-scripts/flow-accounting/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/0-to-1 b/src/migration-scripts/https/0-to-1
index 52fe3f2ad..c39f5d15b 100644
--- a/src/migration-scripts/https/0-to-1
+++ b/src/migration-scripts/https/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 202-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/1-to-2 b/src/migration-scripts/https/1-to-2
index dad7ac1f0..708b7c919 100644
--- a/src/migration-scripts/https/1-to-2
+++ b/src/migration-scripts/https/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/2-to-3 b/src/migration-scripts/https/2-to-3
index 1125caebf..9efaf840a 100644
--- a/src/migration-scripts/https/2-to-3
+++ b/src/migration-scripts/https/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/3-to-4 b/src/migration-scripts/https/3-to-4
index c01236cc6..be9bb17ff 100644
--- a/src/migration-scripts/https/3-to-4
+++ b/src/migration-scripts/https/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/4-to-5 b/src/migration-scripts/https/4-to-5
index 0f1c7901f..a99e8d8a5 100644
--- a/src/migration-scripts/https/4-to-5
+++ b/src/migration-scripts/https/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/5-to-6 b/src/migration-scripts/https/5-to-6
index 6ef6976b6..f51b35972 100644
--- a/src/migration-scripts/https/5-to-6
+++ b/src/migration-scripts/https/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/https/6-to-7 b/src/migration-scripts/https/6-to-7
index 571f3b6ae..36ac3d1d9 100644
--- a/src/migration-scripts/https/6-to-7
+++ b/src/migration-scripts/https/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ids/0-to-1 b/src/migration-scripts/ids/0-to-1
index 1b963e839..108f68399 100644
--- a/src/migration-scripts/ids/0-to-1
+++ b/src/migration-scripts/ids/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ids/1-to-2 b/src/migration-scripts/ids/1-to-2
new file mode 100644
index 000000000..6f93f8b45
--- /dev/null
+++ b/src/migration-scripts/ids/1-to-2
@@ -0,0 +1,30 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# T: Migrate threshold and add new threshold types
+
+from vyos.configtree import ConfigTree
+
+# The old 'service ids' path was only used for FastNetMon
+# Suricata is in 'service suricata',
+# so this isn't an overreach
+base = ['service', 'ids']
+
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+ else:
+ config.delete(base)
diff --git a/src/migration-scripts/interfaces/0-to-1 b/src/migration-scripts/interfaces/0-to-1
index 7c135e76e..6ed5f118f 100644
--- a/src/migration-scripts/interfaces/0-to-1
+++ b/src/migration-scripts/interfaces/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/1-to-2 b/src/migration-scripts/interfaces/1-to-2
index ebf02b028..65da60f24 100644
--- a/src/migration-scripts/interfaces/1-to-2
+++ b/src/migration-scripts/interfaces/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/10-to-11 b/src/migration-scripts/interfaces/10-to-11
index 8a562f2d0..2e8d2d099 100644
--- a/src/migration-scripts/interfaces/10-to-11
+++ b/src/migration-scripts/interfaces/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/11-to-12 b/src/migration-scripts/interfaces/11-to-12
index 132cecbb7..e1bd496c9 100644
--- a/src/migration-scripts/interfaces/11-to-12
+++ b/src/migration-scripts/interfaces/11-to-12
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/12-to-13 b/src/migration-scripts/interfaces/12-to-13
index 585deb898..abd01ceb8 100644
--- a/src/migration-scripts/interfaces/12-to-13
+++ b/src/migration-scripts/interfaces/12-to-13
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/13-to-14 b/src/migration-scripts/interfaces/13-to-14
index 45d8e3b5f..c8b686ee9 100644
--- a/src/migration-scripts/interfaces/13-to-14
+++ b/src/migration-scripts/interfaces/13-to-14
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/14-to-15 b/src/migration-scripts/interfaces/14-to-15
index d45d59bba..e48371539 100644
--- a/src/migration-scripts/interfaces/14-to-15
+++ b/src/migration-scripts/interfaces/14-to-15
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/15-to-16 b/src/migration-scripts/interfaces/15-to-16
index c9abdb5f8..44768356c 100644
--- a/src/migration-scripts/interfaces/15-to-16
+++ b/src/migration-scripts/interfaces/15-to-16
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/16-to-17 b/src/migration-scripts/interfaces/16-to-17
index 7d241ac68..e3161f178 100644
--- a/src/migration-scripts/interfaces/16-to-17
+++ b/src/migration-scripts/interfaces/16-to-17
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/17-to-18 b/src/migration-scripts/interfaces/17-to-18
index f45695a88..a9bf8174c 100644
--- a/src/migration-scripts/interfaces/17-to-18
+++ b/src/migration-scripts/interfaces/17-to-18
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/18-to-19 b/src/migration-scripts/interfaces/18-to-19
index ae1a07adb..2b54d5cdc 100644
--- a/src/migration-scripts/interfaces/18-to-19
+++ b/src/migration-scripts/interfaces/18-to-19
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/19-to-20 b/src/migration-scripts/interfaces/19-to-20
index 7ee6302e2..7262bdad8 100644
--- a/src/migration-scripts/interfaces/19-to-20
+++ b/src/migration-scripts/interfaces/19-to-20
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/2-to-3 b/src/migration-scripts/interfaces/2-to-3
index 695dcbf7a..bb59eb3ce 100644
--- a/src/migration-scripts/interfaces/2-to-3
+++ b/src/migration-scripts/interfaces/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21
index 0b6895177..73c98957c 100644
--- a/src/migration-scripts/interfaces/20-to-21
+++ b/src/migration-scripts/interfaces/20-to-21
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/21-to-22 b/src/migration-scripts/interfaces/21-to-22
index 046eb10c6..a5feffce3 100644
--- a/src/migration-scripts/interfaces/21-to-22
+++ b/src/migration-scripts/interfaces/21-to-22
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/22-to-23 b/src/migration-scripts/interfaces/22-to-23
index 31f7fa2ff..401d5db0e 100644
--- a/src/migration-scripts/interfaces/22-to-23
+++ b/src/migration-scripts/interfaces/22-to-23
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/23-to-24 b/src/migration-scripts/interfaces/23-to-24
index b72ceee49..c534628ce 100644
--- a/src/migration-scripts/interfaces/23-to-24
+++ b/src/migration-scripts/interfaces/23-to-24
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/24-to-25 b/src/migration-scripts/interfaces/24-to-25
index 9f8cc80ec..7386507f9 100644
--- a/src/migration-scripts/interfaces/24-to-25
+++ b/src/migration-scripts/interfaces/24-to-25
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/25-to-26 b/src/migration-scripts/interfaces/25-to-26
index 7a4032d10..88b630691 100644
--- a/src/migration-scripts/interfaces/25-to-26
+++ b/src/migration-scripts/interfaces/25-to-26
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/26-to-27 b/src/migration-scripts/interfaces/26-to-27
index 3f58de02c..c04655da0 100644
--- a/src/migration-scripts/interfaces/26-to-27
+++ b/src/migration-scripts/interfaces/26-to-27
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/27-to-28 b/src/migration-scripts/interfaces/27-to-28
index eb9363e39..fb156a899 100644
--- a/src/migration-scripts/interfaces/27-to-28
+++ b/src/migration-scripts/interfaces/27-to-28
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/28-to-29 b/src/migration-scripts/interfaces/28-to-29
index 886d49e2c..9a2ba5757 100644
--- a/src/migration-scripts/interfaces/28-to-29
+++ b/src/migration-scripts/interfaces/28-to-29
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/29-to-30 b/src/migration-scripts/interfaces/29-to-30
index 7b32d871e..c9664e83a 100644
--- a/src/migration-scripts/interfaces/29-to-30
+++ b/src/migration-scripts/interfaces/29-to-30
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/3-to-4 b/src/migration-scripts/interfaces/3-to-4
index 4e56200e1..ed27a917b 100644
--- a/src/migration-scripts/interfaces/3-to-4
+++ b/src/migration-scripts/interfaces/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/30-to-31 b/src/migration-scripts/interfaces/30-to-31
index 7e509dd86..48ca063e2 100644
--- a/src/migration-scripts/interfaces/30-to-31
+++ b/src/migration-scripts/interfaces/30-to-31
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/31-to-32 b/src/migration-scripts/interfaces/31-to-32
index 24077ed24..1c5147e6a 100644
--- a/src/migration-scripts/interfaces/31-to-32
+++ b/src/migration-scripts/interfaces/31-to-32
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/32-to-33 b/src/migration-scripts/interfaces/32-to-33
index c7b1c5b36..ccda04d0c 100644
--- a/src/migration-scripts/interfaces/32-to-33
+++ b/src/migration-scripts/interfaces/32-to-33
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/migration-scripts/interfaces/4-to-5 b/src/migration-scripts/interfaces/4-to-5
index 93fa7c393..839e23d77 100644
--- a/src/migration-scripts/interfaces/4-to-5
+++ b/src/migration-scripts/interfaces/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/5-to-6 b/src/migration-scripts/interfaces/5-to-6
index 44c32ba63..45a6daef7 100644
--- a/src/migration-scripts/interfaces/5-to-6
+++ b/src/migration-scripts/interfaces/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 202-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/6-to-7 b/src/migration-scripts/interfaces/6-to-7
index e60121eec..0131b419c 100644
--- a/src/migration-scripts/interfaces/6-to-7
+++ b/src/migration-scripts/interfaces/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/7-to-8 b/src/migration-scripts/interfaces/7-to-8
index 43ae320ab..a2e875b82 100644
--- a/src/migration-scripts/interfaces/7-to-8
+++ b/src/migration-scripts/interfaces/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/8-to-9 b/src/migration-scripts/interfaces/8-to-9
index bae1b34fa..8e1881911 100644
--- a/src/migration-scripts/interfaces/8-to-9
+++ b/src/migration-scripts/interfaces/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/interfaces/9-to-10 b/src/migration-scripts/interfaces/9-to-10
index cdfd7d432..06429ba98 100644
--- a/src/migration-scripts/interfaces/9-to-10
+++ b/src/migration-scripts/interfaces/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipoe-server/1-to-2 b/src/migration-scripts/ipoe-server/1-to-2
index 034eacb10..cf1cb5ca6 100644
--- a/src/migration-scripts/ipoe-server/1-to-2
+++ b/src/migration-scripts/ipoe-server/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipoe-server/2-to-3 b/src/migration-scripts/ipoe-server/2-to-3
index dcd15e595..fb4262e1d 100644
--- a/src/migration-scripts/ipoe-server/2-to-3
+++ b/src/migration-scripts/ipoe-server/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipoe-server/3-to-4 b/src/migration-scripts/ipoe-server/3-to-4
index 3bad9756d..cce1927f3 100644
--- a/src/migration-scripts/ipoe-server/3-to-4
+++ b/src/migration-scripts/ipoe-server/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/10-to-11 b/src/migration-scripts/ipsec/10-to-11
index 6c4ccb553..f88250ac1 100644
--- a/src/migration-scripts/ipsec/10-to-11
+++ b/src/migration-scripts/ipsec/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/11-to-12 b/src/migration-scripts/ipsec/11-to-12
index fc65f1825..f6f34bd59 100644
--- a/src/migration-scripts/ipsec/11-to-12
+++ b/src/migration-scripts/ipsec/11-to-12
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/12-to-13 b/src/migration-scripts/ipsec/12-to-13
index ffe766eb2..184ba0274 100644
--- a/src/migration-scripts/ipsec/12-to-13
+++ b/src/migration-scripts/ipsec/12-to-13
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/4-to-5 b/src/migration-scripts/ipsec/4-to-5
index a88a543d3..62653f32d 100644
--- a/src/migration-scripts/ipsec/4-to-5
+++ b/src/migration-scripts/ipsec/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/5-to-6 b/src/migration-scripts/ipsec/5-to-6
index 373428d61..6c1d9c0d4 100644
--- a/src/migration-scripts/ipsec/5-to-6
+++ b/src/migration-scripts/ipsec/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/6-to-7 b/src/migration-scripts/ipsec/6-to-7
index 5679477c0..35d2ad6c6 100644
--- a/src/migration-scripts/ipsec/6-to-7
+++ b/src/migration-scripts/ipsec/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/7-to-8 b/src/migration-scripts/ipsec/7-to-8
index 481f00d29..b10230431 100644
--- a/src/migration-scripts/ipsec/7-to-8
+++ b/src/migration-scripts/ipsec/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/8-to-9 b/src/migration-scripts/ipsec/8-to-9
index 7f325139f..3a97c01c0 100644
--- a/src/migration-scripts/ipsec/8-to-9
+++ b/src/migration-scripts/ipsec/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ipsec/9-to-10 b/src/migration-scripts/ipsec/9-to-10
index 321a75973..ccb1a5e02 100644
--- a/src/migration-scripts/ipsec/9-to-10
+++ b/src/migration-scripts/ipsec/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/isis/0-to-1 b/src/migration-scripts/isis/0-to-1
index e24288558..052dbc8a8 100644
--- a/src/migration-scripts/isis/0-to-1
+++ b/src/migration-scripts/isis/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/isis/1-to-2 b/src/migration-scripts/isis/1-to-2
index 0fc92a6de..e87d91516 100644
--- a/src/migration-scripts/isis/1-to-2
+++ b/src/migration-scripts/isis/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/isis/2-to-3 b/src/migration-scripts/isis/2-to-3
index afb9f2340..9cdc84ac3 100644
--- a/src/migration-scripts/isis/2-to-3
+++ b/src/migration-scripts/isis/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/0-to-1 b/src/migration-scripts/l2tp/0-to-1
index f0cb6af96..03fb7e236 100644
--- a/src/migration-scripts/l2tp/0-to-1
+++ b/src/migration-scripts/l2tp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/1-to-2 b/src/migration-scripts/l2tp/1-to-2
index 468d564ac..dd38edfbc 100644
--- a/src/migration-scripts/l2tp/1-to-2
+++ b/src/migration-scripts/l2tp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/2-to-3 b/src/migration-scripts/l2tp/2-to-3
index 00fabb6b6..748d9544e 100644
--- a/src/migration-scripts/l2tp/2-to-3
+++ b/src/migration-scripts/l2tp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/3-to-4 b/src/migration-scripts/l2tp/3-to-4
index 01c3fa844..434b3a72e 100644
--- a/src/migration-scripts/l2tp/3-to-4
+++ b/src/migration-scripts/l2tp/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/4-to-5 b/src/migration-scripts/l2tp/4-to-5
index 56d451b8d..c3cc8451e 100644
--- a/src/migration-scripts/l2tp/4-to-5
+++ b/src/migration-scripts/l2tp/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/5-to-6 b/src/migration-scripts/l2tp/5-to-6
index cc9f948a6..c1f13a8c7 100644
--- a/src/migration-scripts/l2tp/5-to-6
+++ b/src/migration-scripts/l2tp/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/6-to-7 b/src/migration-scripts/l2tp/6-to-7
index 4dba5974e..f4e561382 100644
--- a/src/migration-scripts/l2tp/6-to-7
+++ b/src/migration-scripts/l2tp/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/7-to-8 b/src/migration-scripts/l2tp/7-to-8
index 527906fc8..b11a28af0 100644
--- a/src/migration-scripts/l2tp/7-to-8
+++ b/src/migration-scripts/l2tp/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/l2tp/8-to-9 b/src/migration-scripts/l2tp/8-to-9
index e6b689e80..e5577da3e 100644
--- a/src/migration-scripts/l2tp/8-to-9
+++ b/src/migration-scripts/l2tp/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/lldp/0-to-1 b/src/migration-scripts/lldp/0-to-1
index c16e7e84b..052fe65c2 100644
--- a/src/migration-scripts/lldp/0-to-1
+++ b/src/migration-scripts/lldp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/lldp/1-to-2 b/src/migration-scripts/lldp/1-to-2
index 7f233a725..e2d936a9e 100644
--- a/src/migration-scripts/lldp/1-to-2
+++ b/src/migration-scripts/lldp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/lldp/2-to-3 b/src/migration-scripts/lldp/2-to-3
index 93090756c..653029550 100644
--- a/src/migration-scripts/lldp/2-to-3
+++ b/src/migration-scripts/lldp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/monitoring/0-to-1 b/src/migration-scripts/monitoring/0-to-1
index 92f824325..7f7d9df60 100644
--- a/src/migration-scripts/monitoring/0-to-1
+++ b/src/migration-scripts/monitoring/0-to-1
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/monitoring/1-to-2 b/src/migration-scripts/monitoring/1-to-2
index 8bdaebae9..013e8ff3a 100644
--- a/src/migration-scripts/monitoring/1-to-2
+++ b/src/migration-scripts/monitoring/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat/4-to-5 b/src/migration-scripts/nat/4-to-5
index e1919da50..f4a48bbf3 100644
--- a/src/migration-scripts/nat/4-to-5
+++ b/src/migration-scripts/nat/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat/5-to-6 b/src/migration-scripts/nat/5-to-6
index a583d4eb6..e40ccebb0 100644
--- a/src/migration-scripts/nat/5-to-6
+++ b/src/migration-scripts/nat/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat/6-to-7 b/src/migration-scripts/nat/6-to-7
index e9b90fc98..651179f4e 100644
--- a/src/migration-scripts/nat/6-to-7
+++ b/src/migration-scripts/nat/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat/7-to-8 b/src/migration-scripts/nat/7-to-8
index 9ae389ef1..4af8c935c 100644
--- a/src/migration-scripts/nat/7-to-8
+++ b/src/migration-scripts/nat/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat66/0-to-1 b/src/migration-scripts/nat66/0-to-1
index b3c6bf4cc..08348379f 100644
--- a/src/migration-scripts/nat66/0-to-1
+++ b/src/migration-scripts/nat66/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat66/1-to-2 b/src/migration-scripts/nat66/1-to-2
index f49940ae0..b506f891b 100644
--- a/src/migration-scripts/nat66/1-to-2
+++ b/src/migration-scripts/nat66/1-to-2
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nat66/2-to-3 b/src/migration-scripts/nat66/2-to-3
index 55d5f4b2b..1e76819d4 100644
--- a/src/migration-scripts/nat66/2-to-3
+++ b/src/migration-scripts/nat66/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/nhrp/0-to-1 b/src/migration-scripts/nhrp/0-to-1
index badd88e04..daed73993 100644
--- a/src/migration-scripts/nhrp/0-to-1
+++ b/src/migration-scripts/nhrp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ntp/0-to-1 b/src/migration-scripts/ntp/0-to-1
index 01f5a460a..895308b75 100644
--- a/src/migration-scripts/ntp/0-to-1
+++ b/src/migration-scripts/ntp/0-to-1
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ntp/1-to-2 b/src/migration-scripts/ntp/1-to-2
index d5f800922..d3039041c 100644
--- a/src/migration-scripts/ntp/1-to-2
+++ b/src/migration-scripts/ntp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ntp/2-to-3 b/src/migration-scripts/ntp/2-to-3
index bbda90351..701cffdfb 100644
--- a/src/migration-scripts/ntp/2-to-3
+++ b/src/migration-scripts/ntp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/openconnect/0-to-1 b/src/migration-scripts/openconnect/0-to-1
index aa5a97eee..90f7ee64a 100644
--- a/src/migration-scripts/openconnect/0-to-1
+++ b/src/migration-scripts/openconnect/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/openconnect/1-to-2 b/src/migration-scripts/openconnect/1-to-2
index 4f74b44df..07b1903b8 100644
--- a/src/migration-scripts/openconnect/1-to-2
+++ b/src/migration-scripts/openconnect/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/openconnect/2-to-3 b/src/migration-scripts/openconnect/2-to-3
index 00e13ecb0..74cb6f2d8 100644
--- a/src/migration-scripts/openconnect/2-to-3
+++ b/src/migration-scripts/openconnect/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/openvpn/0-to-1 b/src/migration-scripts/openvpn/0-to-1
index e5db731ed..582cd9a46 100644
--- a/src/migration-scripts/openvpn/0-to-1
+++ b/src/migration-scripts/openvpn/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/openvpn/1-to-2 b/src/migration-scripts/openvpn/1-to-2
index 2baa7302c..83d6219d6 100644
--- a/src/migration-scripts/openvpn/1-to-2
+++ b/src/migration-scripts/openvpn/1-to-2
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/migration-scripts/openvpn/2-to-3 b/src/migration-scripts/openvpn/2-to-3
index 4e6b3c8b7..f2a7d1d69 100644
--- a/src/migration-scripts/openvpn/2-to-3
+++ b/src/migration-scripts/openvpn/2-to-3
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/migration-scripts/openvpn/3-to-4 b/src/migration-scripts/openvpn/3-to-4
index 0529491c1..86b287102 100644
--- a/src/migration-scripts/openvpn/3-to-4
+++ b/src/migration-scripts/openvpn/3-to-4
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ospf/0-to-1 b/src/migration-scripts/ospf/0-to-1
index a1f810960..2f20184b4 100644
--- a/src/migration-scripts/ospf/0-to-1
+++ b/src/migration-scripts/ospf/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ospf/1-to-2 b/src/migration-scripts/ospf/1-to-2
index 5368d8dd7..5b7862ee7 100644
--- a/src/migration-scripts/ospf/1-to-2
+++ b/src/migration-scripts/ospf/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pim/0-to-1 b/src/migration-scripts/pim/0-to-1
index ce24b23ba..c0b48ae67 100644
--- a/src/migration-scripts/pim/0-to-1
+++ b/src/migration-scripts/pim/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/0-to-1 b/src/migration-scripts/policy/0-to-1
index 837946c37..aea43560b 100644
--- a/src/migration-scripts/policy/0-to-1
+++ b/src/migration-scripts/policy/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/1-to-2 b/src/migration-scripts/policy/1-to-2
index ba3e48db0..5990c4a8e 100644
--- a/src/migration-scripts/policy/1-to-2
+++ b/src/migration-scripts/policy/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/2-to-3 b/src/migration-scripts/policy/2-to-3
index 399a55387..74c15885e 100644
--- a/src/migration-scripts/policy/2-to-3
+++ b/src/migration-scripts/policy/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/3-to-4 b/src/migration-scripts/policy/3-to-4
index 5d4959def..4e213eec1 100644
--- a/src/migration-scripts/policy/3-to-4
+++ b/src/migration-scripts/policy/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/4-to-5 b/src/migration-scripts/policy/4-to-5
index 0ecfdfd5e..01f019d39 100644
--- a/src/migration-scripts/policy/4-to-5
+++ b/src/migration-scripts/policy/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/5-to-6 b/src/migration-scripts/policy/5-to-6
index acba0b4be..d1c818827 100644
--- a/src/migration-scripts/policy/5-to-6
+++ b/src/migration-scripts/policy/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/6-to-7 b/src/migration-scripts/policy/6-to-7
index 69aa703c5..b4e7ebcea 100644
--- a/src/migration-scripts/policy/6-to-7
+++ b/src/migration-scripts/policy/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/7-to-8 b/src/migration-scripts/policy/7-to-8
index a887f37fe..4fa45b879 100644
--- a/src/migration-scripts/policy/7-to-8
+++ b/src/migration-scripts/policy/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/policy/8-to-9 b/src/migration-scripts/policy/8-to-9
index 355e48e00..b8cc1f471 100644
--- a/src/migration-scripts/policy/8-to-9
+++ b/src/migration-scripts/policy/8-to-9
@@ -1,4 +1,4 @@
-# Copyright (C) 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/0-to-1 b/src/migration-scripts/pppoe-server/0-to-1
index 8c9a24fbe..c2b25c45f 100644
--- a/src/migration-scripts/pppoe-server/0-to-1
+++ b/src/migration-scripts/pppoe-server/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/1-to-2 b/src/migration-scripts/pppoe-server/1-to-2
index c9c968bff..31132565e 100644
--- a/src/migration-scripts/pppoe-server/1-to-2
+++ b/src/migration-scripts/pppoe-server/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/10-to-11 b/src/migration-scripts/pppoe-server/10-to-11
index 6bc138b5c..9d0477172 100644
--- a/src/migration-scripts/pppoe-server/10-to-11
+++ b/src/migration-scripts/pppoe-server/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/2-to-3 b/src/migration-scripts/pppoe-server/2-to-3
index 160cffdf8..56dc032aa 100644
--- a/src/migration-scripts/pppoe-server/2-to-3
+++ b/src/migration-scripts/pppoe-server/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/3-to-4 b/src/migration-scripts/pppoe-server/3-to-4
index 29dd62201..b0eb6f2b9 100644
--- a/src/migration-scripts/pppoe-server/3-to-4
+++ b/src/migration-scripts/pppoe-server/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/4-to-5 b/src/migration-scripts/pppoe-server/4-to-5
index 03fbfb247..bb75b7e1f 100644
--- a/src/migration-scripts/pppoe-server/4-to-5
+++ b/src/migration-scripts/pppoe-server/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/5-to-6 b/src/migration-scripts/pppoe-server/5-to-6
index 13de8f8d2..4616f6021 100644
--- a/src/migration-scripts/pppoe-server/5-to-6
+++ b/src/migration-scripts/pppoe-server/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/6-to-7 b/src/migration-scripts/pppoe-server/6-to-7
index 79745a0c6..e764284da 100644
--- a/src/migration-scripts/pppoe-server/6-to-7
+++ b/src/migration-scripts/pppoe-server/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/7-to-8 b/src/migration-scripts/pppoe-server/7-to-8
index 90e4fa053..9a26da9e6 100644
--- a/src/migration-scripts/pppoe-server/7-to-8
+++ b/src/migration-scripts/pppoe-server/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/8-to-9 b/src/migration-scripts/pppoe-server/8-to-9
index e7e0aaa2c..0f10dafec 100644
--- a/src/migration-scripts/pppoe-server/8-to-9
+++ b/src/migration-scripts/pppoe-server/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pppoe-server/9-to-10 b/src/migration-scripts/pppoe-server/9-to-10
index d3475e8ff..0a1931d81 100644
--- a/src/migration-scripts/pppoe-server/9-to-10
+++ b/src/migration-scripts/pppoe-server/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pptp/0-to-1 b/src/migration-scripts/pptp/0-to-1
index dd0b6f57e..b0e4c3b65 100644
--- a/src/migration-scripts/pptp/0-to-1
+++ b/src/migration-scripts/pptp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pptp/1-to-2 b/src/migration-scripts/pptp/1-to-2
index 1e7601193..afeb6e3bb 100644
--- a/src/migration-scripts/pptp/1-to-2
+++ b/src/migration-scripts/pptp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pptp/2-to-3 b/src/migration-scripts/pptp/2-to-3
index 8b0d6d865..9f06aa1a7 100644
--- a/src/migration-scripts/pptp/2-to-3
+++ b/src/migration-scripts/pptp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pptp/3-to-4 b/src/migration-scripts/pptp/3-to-4
index 2dabd8475..3fe579aa9 100644
--- a/src/migration-scripts/pptp/3-to-4
+++ b/src/migration-scripts/pptp/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/pptp/4-to-5 b/src/migration-scripts/pptp/4-to-5
index c906f58c4..d8390cc66 100644
--- a/src/migration-scripts/pptp/4-to-5
+++ b/src/migration-scripts/pptp/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/qos/1-to-2 b/src/migration-scripts/qos/1-to-2
index c43d8fa47..dea1a77eb 100644
--- a/src/migration-scripts/qos/1-to-2
+++ b/src/migration-scripts/qos/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/qos/2-to-3 b/src/migration-scripts/qos/2-to-3
index 284fe828e..40fc7637f 100644
--- a/src/migration-scripts/qos/2-to-3
+++ b/src/migration-scripts/qos/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/10-to-11 b/src/migration-scripts/quagga/10-to-11
index 15dbbb193..08ea1a00e 100644
--- a/src/migration-scripts/quagga/10-to-11
+++ b/src/migration-scripts/quagga/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/11-to-12 b/src/migration-scripts/quagga/11-to-12
index 8ae2023a1..83fd1d0d3 100644
--- a/src/migration-scripts/quagga/11-to-12
+++ b/src/migration-scripts/quagga/11-to-12
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/2-to-3 b/src/migration-scripts/quagga/2-to-3
index d62c387ba..b619d1edc 100644
--- a/src/migration-scripts/quagga/2-to-3
+++ b/src/migration-scripts/quagga/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/3-to-4 b/src/migration-scripts/quagga/3-to-4
index 81cf139f6..f801dcff1 100644
--- a/src/migration-scripts/quagga/3-to-4
+++ b/src/migration-scripts/quagga/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/4-to-5 b/src/migration-scripts/quagga/4-to-5
index 27b995431..a7bb23d14 100644
--- a/src/migration-scripts/quagga/4-to-5
+++ b/src/migration-scripts/quagga/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/5-to-6 b/src/migration-scripts/quagga/5-to-6
index 08fd070de..5dcfa3cfb 100644
--- a/src/migration-scripts/quagga/5-to-6
+++ b/src/migration-scripts/quagga/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/6-to-7 b/src/migration-scripts/quagga/6-to-7
index 095baac03..4a28a47e7 100644
--- a/src/migration-scripts/quagga/6-to-7
+++ b/src/migration-scripts/quagga/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/7-to-8 b/src/migration-scripts/quagga/7-to-8
index d9de26d15..60afb87cf 100644
--- a/src/migration-scripts/quagga/7-to-8
+++ b/src/migration-scripts/quagga/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/quagga/8-to-9 b/src/migration-scripts/quagga/8-to-9
index eece6c15d..4c7089c52 100644
--- a/src/migration-scripts/quagga/8-to-9
+++ b/src/migration-scripts/quagga/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,7 @@
# - T2450: drop interface-route and interface-route6 from "protocols static"
from vyos.configtree import ConfigTree
+from vyos.template import is_ip
def migrate_interface_route(config, base, path, route_route6):
""" Generic migration function which can be called on every instance of
@@ -31,11 +32,18 @@ def migrate_interface_route(config, base, path, route_route6):
tmp = base + path + [route, 'next-hop-interface']
for interface in config.list_nodes(tmp):
- new_base = base + [route_route6, route, 'interface']
- config.set(new_base)
- config.set_tag(base + [route_route6])
- config.set_tag(new_base)
- config.copy(tmp + [interface], new_base + [interface])
+ if is_ip(interface): # not prohibited in 1.3.x, hence allowed
+ new_base = base + [route_route6, route, 'next-hop']
+ config.set(new_base)
+ config.set_tag(base + [route_route6])
+ config.set_tag(new_base)
+ config.copy(tmp + [interface], new_base + [interface])
+ else:
+ new_base = base + [route_route6, route, 'interface']
+ config.set(new_base)
+ config.set_tag(base + [route_route6])
+ config.set_tag(new_base)
+ config.copy(tmp + [interface], new_base + [interface])
config.delete(base + path)
diff --git a/src/migration-scripts/quagga/9-to-10 b/src/migration-scripts/quagga/9-to-10
index 4ac1f0b7d..a2002bf88 100644
--- a/src/migration-scripts/quagga/9-to-10
+++ b/src/migration-scripts/quagga/9-to-10
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/reverse-proxy/0-to-1 b/src/migration-scripts/reverse-proxy/0-to-1
index b495474a6..b8c98ae99 100644
--- a/src/migration-scripts/reverse-proxy/0-to-1
+++ b/src/migration-scripts/reverse-proxy/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/reverse-proxy/1-to-2 b/src/migration-scripts/reverse-proxy/1-to-2
index 61612bc36..4b72107b1 100755
--- a/src/migration-scripts/reverse-proxy/1-to-2
+++ b/src/migration-scripts/reverse-proxy/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/reverse-proxy/2-to-3 b/src/migration-scripts/reverse-proxy/2-to-3
new file mode 100755
index 000000000..bf3403d11
--- /dev/null
+++ b/src/migration-scripts/reverse-proxy/2-to-3
@@ -0,0 +1,66 @@
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# T7429: logging facility "all" unavailable in code
+
+from vyos.configtree import ConfigTree
+
+base = ['load-balancing', 'haproxy']
+unsupported_facilities = ['all', 'authpriv', 'mark']
+
+def config_migrator(config, config_path: list) -> None:
+ if not config.exists(config_path):
+ return
+ # Remove unsupported backend HAProxy syslog facilities form CLI
+ # Works for both backend and service CLI nodes
+ for service_backend in config.list_nodes(config_path):
+ log_path = config_path + [service_backend, 'logging', 'facility']
+ if not config.exists(log_path):
+ continue
+ # Remove unsupported syslog facilities form CLI
+ for facility in config.list_nodes(log_path):
+ if facility in unsupported_facilities:
+ config.delete(log_path + [facility])
+ continue
+ # Remove unsupported facility log level form CLI. VyOS will fallback
+ # to default log level if not set
+ if config.exists(log_path + [facility, 'level']):
+ tmp = config.return_value(log_path + [facility, 'level'])
+ if tmp == 'all':
+ config.delete(log_path + [facility, 'level'])
+
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
+ # Remove unsupported syslog facilities form CLI
+ global_path = base + ['global-parameters', 'logging', 'facility']
+ if config.exists(global_path):
+ for facility in config.list_nodes(global_path):
+ if facility in unsupported_facilities:
+ config.delete(global_path + [facility])
+ continue
+ # Remove unsupported facility log level form CLI. VyOS will fallback
+ # to default log level if not set
+ if config.exists(global_path + [facility, 'level']):
+ tmp = config.return_value(global_path + [facility, 'level'])
+ if tmp == 'all':
+ config.delete(global_path + [facility, 'level'])
+
+ # Remove unsupported backend HAProxy syslog facilities from CLI
+ config_migrator(config, base + ['backend'])
+ # Remove unsupported service HAProxy syslog facilities from CLI
+ config_migrator(config, base + ['service'])
diff --git a/src/migration-scripts/rip/0-to-1 b/src/migration-scripts/rip/0-to-1
index 6d41bcf58..4fbd88cfe 100644
--- a/src/migration-scripts/rip/0-to-1
+++ b/src/migration-scripts/rip/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/rpki/0-to-1 b/src/migration-scripts/rpki/0-to-1
index b6e781fa9..2263489a0 100644
--- a/src/migration-scripts/rpki/0-to-1
+++ b/src/migration-scripts/rpki/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/rpki/1-to-2 b/src/migration-scripts/rpki/1-to-2
index 855236d6c..42447de66 100644
--- a/src/migration-scripts/rpki/1-to-2
+++ b/src/migration-scripts/rpki/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/salt/0-to-1 b/src/migration-scripts/salt/0-to-1
index 3990a88dc..05f6476ce 100644
--- a/src/migration-scripts/salt/0-to-1
+++ b/src/migration-scripts/salt/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/snmp/0-to-1 b/src/migration-scripts/snmp/0-to-1
index 03b190cb7..ee334cdc7 100644
--- a/src/migration-scripts/snmp/0-to-1
+++ b/src/migration-scripts/snmp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/snmp/1-to-2 b/src/migration-scripts/snmp/1-to-2
index 0120f8acb..d2b8457ce 100644
--- a/src/migration-scripts/snmp/1-to-2
+++ b/src/migration-scripts/snmp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/snmp/2-to-3 b/src/migration-scripts/snmp/2-to-3
index 6d828b619..b0020a7a5 100644
--- a/src/migration-scripts/snmp/2-to-3
+++ b/src/migration-scripts/snmp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ssh/0-to-1 b/src/migration-scripts/ssh/0-to-1
index 65b68f509..4acdd4ec3 100644
--- a/src/migration-scripts/ssh/0-to-1
+++ b/src/migration-scripts/ssh/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/ssh/1-to-2 b/src/migration-scripts/ssh/1-to-2
index b601db3b4..7dec65e58 100644
--- a/src/migration-scripts/ssh/1-to-2
+++ b/src/migration-scripts/ssh/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/0-to-1 b/src/migration-scripts/sstp/0-to-1
index 1bd7d6c6b..5cc091965 100644
--- a/src/migration-scripts/sstp/0-to-1
+++ b/src/migration-scripts/sstp/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/1-to-2 b/src/migration-scripts/sstp/1-to-2
index 2349e3c9f..7c127cc93 100644
--- a/src/migration-scripts/sstp/1-to-2
+++ b/src/migration-scripts/sstp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/2-to-3 b/src/migration-scripts/sstp/2-to-3
index 4255a896e..db752ad32 100644
--- a/src/migration-scripts/sstp/2-to-3
+++ b/src/migration-scripts/sstp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/3-to-4 b/src/migration-scripts/sstp/3-to-4
index fd10985de..dede5e87a 100644
--- a/src/migration-scripts/sstp/3-to-4
+++ b/src/migration-scripts/sstp/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/4-to-5 b/src/migration-scripts/sstp/4-to-5
index 254e828af..74410006b 100644
--- a/src/migration-scripts/sstp/4-to-5
+++ b/src/migration-scripts/sstp/4-to-5
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/sstp/5-to-6 b/src/migration-scripts/sstp/5-to-6
index fc3cc29b2..9e3ad609d 100644
--- a/src/migration-scripts/sstp/5-to-6
+++ b/src/migration-scripts/sstp/5-to-6
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/10-to-11 b/src/migration-scripts/system/10-to-11
index 76d7f23cb..68ff6869c 100644
--- a/src/migration-scripts/system/10-to-11
+++ b/src/migration-scripts/system/10-to-11
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/11-to-12 b/src/migration-scripts/system/11-to-12
index 71c359b7e..c71d6eb7e 100644
--- a/src/migration-scripts/system/11-to-12
+++ b/src/migration-scripts/system/11-to-12
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/12-to-13 b/src/migration-scripts/system/12-to-13
index 014edba91..b0c1fd8ea 100644
--- a/src/migration-scripts/system/12-to-13
+++ b/src/migration-scripts/system/12-to-13
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/13-to-14 b/src/migration-scripts/system/13-to-14
index fbbecbcd3..0c2480bdb 100644
--- a/src/migration-scripts/system/13-to-14
+++ b/src/migration-scripts/system/13-to-14
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/14-to-15 b/src/migration-scripts/system/14-to-15
index 281809460..ea1370365 100644
--- a/src/migration-scripts/system/14-to-15
+++ b/src/migration-scripts/system/14-to-15
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/15-to-16 b/src/migration-scripts/system/15-to-16
index 7db042930..55642d5d1 100644
--- a/src/migration-scripts/system/15-to-16
+++ b/src/migration-scripts/system/15-to-16
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/16-to-17 b/src/migration-scripts/system/16-to-17
index 9fb86af88..5b0c195a1 100644
--- a/src/migration-scripts/system/16-to-17
+++ b/src/migration-scripts/system/16-to-17
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/17-to-18 b/src/migration-scripts/system/17-to-18
index 323ef4e65..e0dae4b3b 100644
--- a/src/migration-scripts/system/17-to-18
+++ b/src/migration-scripts/system/17-to-18
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/18-to-19 b/src/migration-scripts/system/18-to-19
index 5d9788d70..121706fe5 100644
--- a/src/migration-scripts/system/18-to-19
+++ b/src/migration-scripts/system/18-to-19
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/19-to-20 b/src/migration-scripts/system/19-to-20
index cb84e11fc..dd0d2cad1 100644
--- a/src/migration-scripts/system/19-to-20
+++ b/src/migration-scripts/system/19-to-20
@@ -1,4 +1,4 @@
-# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/20-to-21 b/src/migration-scripts/system/20-to-21
index 71c283da6..96863290a 100644
--- a/src/migration-scripts/system/20-to-21
+++ b/src/migration-scripts/system/20-to-21
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/21-to-22 b/src/migration-scripts/system/21-to-22
index 0e68a6856..fc414c70b 100644
--- a/src/migration-scripts/system/21-to-22
+++ b/src/migration-scripts/system/21-to-22
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/22-to-23 b/src/migration-scripts/system/22-to-23
index e49094e4a..92695668f 100644
--- a/src/migration-scripts/system/22-to-23
+++ b/src/migration-scripts/system/22-to-23
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/23-to-24 b/src/migration-scripts/system/23-to-24
index feb62bc32..ad88a4a2b 100644
--- a/src/migration-scripts/system/23-to-24
+++ b/src/migration-scripts/system/23-to-24
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/24-to-25 b/src/migration-scripts/system/24-to-25
index bdb89902e..d0386f0a7 100644
--- a/src/migration-scripts/system/24-to-25
+++ b/src/migration-scripts/system/24-to-25
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/25-to-26 b/src/migration-scripts/system/25-to-26
index 8832f48e5..ae70b174c 100644
--- a/src/migration-scripts/system/25-to-26
+++ b/src/migration-scripts/system/25-to-26
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/26-to-27 b/src/migration-scripts/system/26-to-27
index 499e16e08..dc2bcd55e 100644
--- a/src/migration-scripts/system/26-to-27
+++ b/src/migration-scripts/system/26-to-27
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/27-to-28 b/src/migration-scripts/system/27-to-28
index 0a5be48ab..896165af4 100644
--- a/src/migration-scripts/system/27-to-28
+++ b/src/migration-scripts/system/27-to-28
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/28-to-29 b/src/migration-scripts/system/28-to-29
index ccf7056c4..310feaa2f 100644
--- a/src/migration-scripts/system/28-to-29
+++ b/src/migration-scripts/system/28-to-29
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/6-to-7 b/src/migration-scripts/system/6-to-7
index e91ccc4e9..01d214986 100644
--- a/src/migration-scripts/system/6-to-7
+++ b/src/migration-scripts/system/6-to-7
@@ -1,4 +1,4 @@
-# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/7-to-8 b/src/migration-scripts/system/7-to-8
index 64dd4dc93..4e7f8c0e6 100644
--- a/src/migration-scripts/system/7-to-8
+++ b/src/migration-scripts/system/7-to-8
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/system/8-to-9 b/src/migration-scripts/system/8-to-9
index ea5f7af81..f1be35126 100644
--- a/src/migration-scripts/system/8-to-9
+++ b/src/migration-scripts/system/8-to-9
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/vrf/0-to-1 b/src/migration-scripts/vrf/0-to-1
index 70abae2a8..3a9567ab9 100644
--- a/src/migration-scripts/vrf/0-to-1
+++ b/src/migration-scripts/vrf/0-to-1
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/vrf/1-to-2 b/src/migration-scripts/vrf/1-to-2
index 557a9ec58..2b7dd556c 100644
--- a/src/migration-scripts/vrf/1-to-2
+++ b/src/migration-scripts/vrf/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -37,7 +37,10 @@ def migrate(config: ConfigTree) -> None:
new_static_base = vrf_base + [vrf, 'protocols']
config.set(new_static_base)
config.copy(static_base, new_static_base + ['static'])
- config.set_tag(new_static_base + ['static', 'route'])
+ if config.exists(new_static_base + ['static', 'route']):
+ config.set_tag(new_static_base + ['static', 'route'])
+ if config.exists(new_static_base + ['static', 'route6']):
+ config.set_tag(new_static_base + ['static', 'route6'])
# Now delete the old configuration
config.delete(base)
diff --git a/src/migration-scripts/vrf/2-to-3 b/src/migration-scripts/vrf/2-to-3
index acacffb41..b43067031 100644
--- a/src/migration-scripts/vrf/2-to-3
+++ b/src/migration-scripts/vrf/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -76,7 +76,8 @@ def migrate(config: ConfigTree) -> None:
# Get a list of all currently used VRFs and tables
vrfs_current = {}
for vrf in config.list_nodes(base):
- vrfs_current[vrf] = int(config.return_value(base + [vrf, 'table']))
+ if config.exists(base + [vrf, 'table']):
+ vrfs_current[vrf] = int(config.return_value(base + [vrf, 'table']))
# Check VRF names and table numbers
name_regex = re.compile(r'^\d.*$')
diff --git a/src/migration-scripts/vrrp/1-to-2 b/src/migration-scripts/vrrp/1-to-2
index 8639a7553..a717df29c 100644
--- a/src/migration-scripts/vrrp/1-to-2
+++ b/src/migration-scripts/vrrp/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/vrrp/2-to-3 b/src/migration-scripts/vrrp/2-to-3
index 468918f91..f9158de1d 100644
--- a/src/migration-scripts/vrrp/2-to-3
+++ b/src/migration-scripts/vrrp/2-to-3
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/vrrp/3-to-4 b/src/migration-scripts/vrrp/3-to-4
index 9f05cf7a1..bb20979c9 100644
--- a/src/migration-scripts/vrrp/3-to-4
+++ b/src/migration-scripts/vrrp/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/wanloadbalance/3-to-4 b/src/migration-scripts/wanloadbalance/3-to-4
index e49f46a5b..fb3975385 100644
--- a/src/migration-scripts/wanloadbalance/3-to-4
+++ b/src/migration-scripts/wanloadbalance/3-to-4
@@ -1,4 +1,4 @@
-# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/migration-scripts/webproxy/1-to-2 b/src/migration-scripts/webproxy/1-to-2
index 5a4847474..70b54b1cd 100644
--- a/src/migration-scripts/webproxy/1-to-2
+++ b/src/migration-scripts/webproxy/1-to-2
@@ -1,4 +1,4 @@
-# Copyright 2018-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/accelppp.py b/src/op_mode/accelppp.py
index 67ce786d0..6f6fd4858 100755
--- a/src/op_mode/accelppp.py
+++ b/src/op_mode/accelppp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/bgp.py b/src/op_mode/bgp.py
index 096113cb4..011f39c1b 100755
--- a/src/op_mode/bgp.py
+++ b/src/op_mode/bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/bonding.py b/src/op_mode/bonding.py
index 07bccbd4b..0ceb65cff 100755
--- a/src/op_mode/bonding.py
+++ b/src/op_mode/bonding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2016-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py
index c4293a77c..2db462db8 100755
--- a/src/op_mode/bridge.py
+++ b/src/op_mode/bridge.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/cgnat.py b/src/op_mode/cgnat.py
index 9ad8f92f9..d53f6158b 100755
--- a/src/op_mode/cgnat.py
+++ b/src/op_mode/cgnat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/clear_conntrack.py b/src/op_mode/clear_conntrack.py
index fec7cf144..2a4f19607 100755
--- a/src/op_mode/clear_conntrack.py
+++ b/src/op_mode/clear_conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/config_mgmt.py b/src/op_mode/config_mgmt.py
index 66de26d1f..fa2abec0e 100755
--- a/src/op_mode/config_mgmt.py
+++ b/src/op_mode/config_mgmt.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/connect_disconnect.py b/src/op_mode/connect_disconnect.py
index 8903f916a..9035ce072 100755
--- a/src/op_mode/connect_disconnect.py
+++ b/src/op_mode/connect_disconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/conntrack.py b/src/op_mode/conntrack.py
index c379c3e60..ee1ae6174 100755
--- a/src/op_mode/conntrack.py
+++ b/src/op_mode/conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/conntrack_sync.py b/src/op_mode/conntrack_sync.py
index f3b09b452..0da5b3b0b 100755
--- a/src/op_mode/conntrack_sync.py
+++ b/src/op_mode/conntrack_sync.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/container.py b/src/op_mode/container.py
index 05f65df1f..089d02dd2 100755
--- a/src/op_mode/container.py
+++ b/src/op_mode/container.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -16,6 +16,7 @@
import json
import sys
+import subprocess
from vyos.utils.process import cmd
from vyos.utils.process import rc_cmd
@@ -109,6 +110,47 @@ def restart(name: str):
print(f'Container "{name}" restarted!')
return output
+def show_log(name: str, follow: bool = False, raw: bool = False):
+ """
+ Show or monitor logs for a specific container.
+ Use --follow to continuously stream logs.
+ """
+ from vyos.configquery import ConfigTreeQuery
+ conf = ConfigTreeQuery()
+ container = conf.get_config_dict(['container', 'name', name], get_first_key=True, with_recursive_defaults=True)
+ log_type = container.get('log-driver')
+ if log_type == 'k8s-file':
+ if follow:
+ log_command_list = ['sudo', 'podman', 'logs', '--follow', '--names', name]
+ else:
+ log_command_list = ['sudo', 'podman', 'logs', '--names', name]
+ elif log_type == 'journald':
+ if follow:
+ log_command_list = ['journalctl', '--follow', '--unit', f'vyos-container-{name}.service']
+ else:
+ log_command_list = ['journalctl', '-e', '--no-pager', '--unit', f'vyos-container-{name}.service']
+ elif log_type == 'none':
+ print(f'Container "{name}" has disabled logs.')
+ return None
+ else:
+ raise vyos.opmode.InternalError(f'Unknown log type "{log_type}" for container "{name}".')
+
+ process = None
+ try:
+ process = subprocess.Popen(log_command_list,
+ stdout=sys.stdout,
+ stderr=sys.stderr)
+ process.wait()
+ except KeyboardInterrupt:
+ if process:
+ process.terminate()
+ process.wait()
+ return None
+ except Exception as e:
+ raise vyos.opmode.InternalError(f"Error starting logging command: {e} ")
+ return None
+
+
if __name__ == '__main__':
try:
res = vyos.opmode.run(sys.modules[__name__])
diff --git a/src/op_mode/cpu.py b/src/op_mode/cpu.py
index 1a0f7392f..a8db16dfc 100755
--- a/src/op_mode/cpu.py
+++ b/src/op_mode/cpu.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2016-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py
index 725bfc75b..f5b01a323 100755
--- a/src/op_mode/dhcp.py
+++ b/src/op_mode/dhcp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/dns.py b/src/op_mode/dns.py
index 16c462f23..7c9f769f1 100755
--- a/src/op_mode/dns.py
+++ b/src/op_mode/dns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/evpn.py b/src/op_mode/evpn.py
index cae4ab9f5..a6dee0b34 100644
--- a/src/op_mode/evpn.py
+++ b/src/op_mode/evpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2016-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/execute_bandwidth_test.sh b/src/op_mode/execute_bandwidth_test.sh
index a6ad0b42c..a7c7484d2 100755
--- a/src/op_mode/execute_bandwidth_test.sh
+++ b/src/op_mode/execute_bandwidth_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/execute_port-scan.py b/src/op_mode/execute_port-scan.py
index bf17d0379..47cd2f7c4 100644
--- a/src/op_mode/execute_port-scan.py
+++ b/src/op_mode/execute_port-scan.py
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/file.py b/src/op_mode/file.py
index bf13bed6f..a0efdb5cb 100755
--- a/src/op_mode/file.py
+++ b/src/op_mode/file.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 086536e4e..6e9f8a01b 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -18,6 +18,7 @@ import argparse
import ipaddress
import json
import re
+from signal import signal, SIGPIPE, SIG_DFL
import tabulate
import textwrap
@@ -25,6 +26,9 @@ from vyos.config import Config
from vyos.utils.process import cmd
from vyos.utils.dict import dict_search_args
+signal(SIGPIPE, SIG_DFL)
+
+
def get_config_node(conf, node=None, family=None, hook=None, priority=None):
if node == 'nat':
if family == 'ipv6':
@@ -598,6 +602,9 @@ def show_firewall_group(name=None):
prefix = 'DA_' if dynamic_type == 'address_group' else 'DA6_'
if dynamic_type in firewall['group']['dynamic_group']:
for dynamic_name, dynamic_conf in firewall['group']['dynamic_group'][dynamic_type].items():
+ if name and name != dynamic_name:
+ continue
+
references = find_references(dynamic_type, dynamic_name)
row = [dynamic_name, textwrap.fill(dynamic_conf.get('description') or '', 50), dynamic_type + '(dynamic)', '\n'.join(references) or 'N/D']
@@ -645,12 +652,14 @@ def show_firewall_group(name=None):
references = find_references(group_type, remote_name)
row = [remote_name, textwrap.fill(remote_conf.get('description') or '', 50), group_type, '\n'.join(references) or 'N/D']
members = get_nftables_remote_group_members("ipv4", 'vyos_filter', f'R_{remote_name}')
+ members6 = get_nftables_remote_group_members("ipv6", 'vyos_filter', f'R6_{remote_name}')
if 'url' in remote_conf:
# display only the url if no members are found for both views
- if not members:
+ if not members and not members6:
if args.detail:
- header_tail = ['Remote URL']
+ header_tail = ['IPv6 Members', 'Remote URL']
+ row.append('N/D')
row.append('N/D')
row.append(remote_conf['url'])
else:
@@ -659,8 +668,15 @@ def show_firewall_group(name=None):
else:
# display all table elements in detail view
if args.detail:
- header_tail = ['Remote URL']
- row += [' '.join(members)]
+ header_tail = ['IPv6 Members', 'Remote URL']
+ if members:
+ row.append(' '.join(members))
+ else:
+ row.append('N/D')
+ if members6:
+ row.append(' '.join(members6))
+ else:
+ row.append('N/D')
row.append(remote_conf['url'])
rows.append(row)
else:
diff --git a/src/op_mode/flow_accounting_op.py b/src/op_mode/flow_accounting_op.py
index 497ccafdf..f8aabc1ee 100755
--- a/src/op_mode/flow_accounting_op.py
+++ b/src/op_mode/flow_accounting_op.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/force_mtu_host.sh b/src/op_mode/force_mtu_host.sh
index c72fc243f..e3e24b57b 100755
--- a/src/op_mode/force_mtu_host.sh
+++ b/src/op_mode/force_mtu_host.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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 as
diff --git a/src/op_mode/force_root-partition-auto-resize.sh b/src/op_mode/force_root-partition-auto-resize.sh
index b39e87560..e17f63a88 100755
--- a/src/op_mode/force_root-partition-auto-resize.sh
+++ b/src/op_mode/force_root-partition-auto-resize.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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 as
diff --git a/src/op_mode/format_disk.py b/src/op_mode/format_disk.py
index dc3c96322..052c89105 100755
--- a/src/op_mode/format_disk.py
+++ b/src/op_mode/format_disk.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_interfaces_debug_archive.py b/src/op_mode/generate_interfaces_debug_archive.py
index 3059aad23..60b3ed691 100755
--- a/src/op_mode/generate_interfaces_debug_archive.py
+++ b/src/op_mode/generate_interfaces_debug_archive.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_ipsec_debug_archive.py b/src/op_mode/generate_ipsec_debug_archive.py
index ca2eeb511..de0f25bfd 100755
--- a/src/op_mode/generate_ipsec_debug_archive.py
+++ b/src/op_mode/generate_ipsec_debug_archive.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_openconnect_otp_key.py b/src/op_mode/generate_openconnect_otp_key.py
index 99b67d261..5cb1c6edf 100755
--- a/src/op_mode/generate_openconnect_otp_key.py
+++ b/src/op_mode/generate_openconnect_otp_key.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_ovpn_client_file.py b/src/op_mode/generate_ovpn_client_file.py
index 1d2f1067a..86d94b191 100755
--- a/src/op_mode/generate_ovpn_client_file.py
+++ b/src/op_mode/generate_ovpn_client_file.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_psk.py b/src/op_mode/generate_psk.py
index d51293712..816150dbf 100644
--- a/src/op_mode/generate_psk.py
+++ b/src/op_mode/generate_psk.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_public_key_command.py b/src/op_mode/generate_public_key_command.py
index 8ba55c901..1c1246742 100755
--- a/src/op_mode/generate_public_key_command.py
+++ b/src/op_mode/generate_public_key_command.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_service_rule-resequence.py b/src/op_mode/generate_service_rule-resequence.py
index 9333d6353..fd6354110 100755
--- a/src/op_mode/generate_service_rule-resequence.py
+++ b/src/op_mode/generate_service_rule-resequence.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_ssh_server_key.py b/src/op_mode/generate_ssh_server_key.py
index d6063c43c..386112c10 100755
--- a/src/op_mode/generate_ssh_server_key.py
+++ b/src/op_mode/generate_ssh_server_key.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_system_login_user.py b/src/op_mode/generate_system_login_user.py
index 1b328eae0..c0cb69708 100755
--- a/src/op_mode/generate_system_login_user.py
+++ b/src/op_mode/generate_system_login_user.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/generate_tech-support_archive.py b/src/op_mode/generate_tech-support_archive.py
index 41b53cd15..1d3f26d39 100755
--- a/src/op_mode/generate_tech-support_archive.py
+++ b/src/op_mode/generate_tech-support_archive.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/igmp-proxy.py b/src/op_mode/igmp-proxy.py
index 709e25915..d197e11f6 100755
--- a/src/op_mode/igmp-proxy.py
+++ b/src/op_mode/igmp-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ikev2_profile_generator.py b/src/op_mode/ikev2_profile_generator.py
index cf2bc6d5c..0db9ef545 100755
--- a/src/op_mode/ikev2_profile_generator.py
+++ b/src/op_mode/ikev2_profile_generator.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/image_info.py b/src/op_mode/image_info.py
index 56aefcd6e..119960a6f 100755
--- a/src/op_mode/image_info.py
+++ b/src/op_mode/image_info.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This file is part of VyOS.
#
@@ -72,6 +72,14 @@ def _format_show_images_details(
return tabulated
+def show_images_current(raw: bool) -> Union[image.BootDetails, str]:
+
+ images_summary = show_images_summary(raw=True)
+ if raw:
+ return {'image_running' : images_summary['image_running']}
+ else:
+ return images_summary['image_running']
+
def show_images_summary(raw: bool) -> Union[image.BootDetails, str]:
images_available: list[str] = grub.version_list()
diff --git a/src/op_mode/image_installer.py b/src/op_mode/image_installer.py
index 179913f15..756afb4fb 100755
--- a/src/op_mode/image_installer.py
+++ b/src/op_mode/image_installer.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2023-2025 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This file is part of VyOS.
#
@@ -19,12 +19,15 @@
from argparse import ArgumentParser, Namespace
from pathlib import Path
-from shutil import copy, chown, rmtree, copytree
+from shutil import copy, chown, rmtree, copytree, disk_usage
from glob import glob
from sys import exit
from os import environ
from os import readlink
-from os import getpid, getppid
+from os import getpid
+from os import getppid
+from json import loads
+from json import dumps
from typing import Union
from urllib.parse import urlparse
from passlib.hosts import linux_context
@@ -35,21 +38,31 @@ from psutil import disk_partitions
from vyos.base import Warning
from vyos.configtree import ConfigTree
from vyos.remote import download
-from vyos.system import disk, grub, image, compat, raid, SYSTEM_CFG_VER
+from vyos.system import disk
+from vyos.system import grub
+from vyos.system import image
+from vyos.system import compat
+from vyos.system import raid
+from vyos.system import SYSTEM_CFG_VER
+from vyos.system import grub_util
from vyos.template import render
from vyos.utils.auth import (
DEFAULT_PASSWORD,
EPasswdStrength,
evaluate_strength
)
+from vyos.utils.dict import dict_search
from vyos.utils.io import ask_input, ask_yes_no, select_entry
from vyos.utils.file import chmod_2775
+from vyos.utils.file import read_file
+from vyos.utils.file import write_file
from vyos.utils.process import cmd, run, rc_cmd
from vyos.version import get_version_data
# define text messages
MSG_ERR_NOT_LIVE: str = 'The system is already installed. Please use "add system image" instead.'
MSG_ERR_LIVE: str = 'The system is in live-boot mode. Please use "install image" instead.'
+MSG_ERR_NOT_ENOUGH_SPACE: str = 'Image upgrade requires at least 2GB of free drive space.'
MSG_ERR_NO_DISK: str = 'No suitable disk was found. There must be at least one disk of 2GB or greater size.'
MSG_ERR_IMPROPER_IMAGE: str = 'Missing sha256sum.txt.\nEither this image is corrupted, or of era 1.2.x (md5sum) and would downgrade image tools;\ndisallowed in either case.'
MSG_ERR_INCOMPATIBLE_IMAGE: str = 'Image compatibility check failed, aborting installation.'
@@ -477,6 +490,29 @@ def setup_grub(root_dir: str) -> None:
render(grub_cfg_menu, grub.TMPL_GRUB_MENU, {})
render(grub_cfg_options, grub.TMPL_GRUB_OPTS, {})
+def get_cli_kernel_options(config_file: str) -> list:
+ config = ConfigTree(read_file(config_file))
+ config_dict = loads(config.to_json())
+ kernel_options = dict_search('system.option.kernel', config_dict)
+ if kernel_options is None:
+ kernel_options = {}
+ cmdline_options = []
+
+ # XXX: This code path and if statements must be kept in sync with the Kernel
+ # option handling in system_options.py:generate(). This occurance is used
+ # for having the appropriate options passed to GRUB after an image upgrade!
+ if 'disable-mitigations' in kernel_options:
+ cmdline_options.append('mitigations=off')
+ if 'disable-power-saving' in kernel_options:
+ cmdline_options.append('intel_idle.max_cstate=0 processor.max_cstate=1')
+ if 'amd-pstate-driver' in kernel_options:
+ mode = kernel_options['amd-pstate-driver']
+ cmdline_options.append(
+ f'initcall_blacklist=acpi_cpufreq_init amd_pstate={mode}')
+ if 'quiet' in kernel_options:
+ cmdline_options.append('quiet')
+
+ return cmdline_options
def configure_authentication(config_file: str, password: str) -> None:
"""Write encrypted password to config file
@@ -491,10 +527,7 @@ def configure_authentication(config_file: str, password: str) -> None:
plaintext exposed
"""
encrypted_password = linux_context.hash(password)
-
- with open(config_file) as f:
- config_string = f.read()
-
+ config_string = read_file(config_file)
config = ConfigTree(config_string)
config.set([
'system', 'login', 'user', 'vyos', 'authentication',
@@ -535,21 +568,18 @@ def validate_signature(file_path: str, sign_type: str) -> None:
print('Signature is valid')
def download_file(local_file: str, remote_path: str, vrf: str,
- username: str, password: str,
progressbar: bool = False, check_space: bool = False):
- environ['REMOTE_USERNAME'] = username
- environ['REMOTE_PASSWORD'] = password
+ # Server credentials are implicitly passed in environment variables
+ # that are set by add_image
if vrf is None:
download(local_file, remote_path, progressbar=progressbar,
check_space=check_space, raise_error=True)
else:
- remote_auth = f'REMOTE_USERNAME={username} REMOTE_PASSWORD={password}'
vrf_cmd = f'ip vrf exec {vrf} {external_download_script} \
--local-file {local_file} --remote-path {remote_path}'
- cmd(vrf_cmd, auth=remote_auth)
+ cmd(vrf_cmd, env=environ)
def image_fetch(image_path: str, vrf: str = None,
- username: str = '', password: str = '',
no_prompt: bool = False) -> Path:
"""Fetch an ISO image
@@ -568,9 +598,8 @@ def image_fetch(image_path: str, vrf: str = None,
if image_path == 'latest':
command = external_latest_image_url_script
if vrf:
- command = f'REMOTE_USERNAME={username} REMOTE_PASSWORD={password} \
- ip vrf exec {vrf} ' + command
- code, output = rc_cmd(command)
+ command = f'ip vrf exec {vrf} {command}'
+ code, output = rc_cmd(command, env=environ)
if code:
print(output)
exit(MSG_INFO_INSTALL_EXIT)
@@ -582,7 +611,6 @@ def image_fetch(image_path: str, vrf: str = None,
# Download the image file
ISO_DOWNLOAD_PATH = os.path.join(os.path.expanduser("~"), '{0}.iso'.format(uuid4()))
download_file(ISO_DOWNLOAD_PATH, image_path, vrf,
- username, password,
progressbar=True, check_space=True)
# Download the image signature
@@ -593,8 +621,7 @@ def image_fetch(image_path: str, vrf: str = None,
for sign_type in ['minisig']:
try:
download_file(f'{ISO_DOWNLOAD_PATH}.{sign_type}',
- f'{image_path}.{sign_type}', vrf,
- username, password)
+ f'{image_path}.{sign_type}', vrf)
sign_file = (True, sign_type)
break
except Exception:
@@ -898,8 +925,7 @@ def install_image() -> None:
for disk_target in l:
disk.partition_mount(disk_target.partition['efi'], f'{DIR_DST_ROOT}/boot/efi')
grub.install(disk_target.name, f'{DIR_DST_ROOT}/boot/',
- f'{DIR_DST_ROOT}/boot/efi',
- id=f'VyOS (RAID disk {l.index(disk_target) + 1})')
+ f'{DIR_DST_ROOT}/boot/efi')
disk.partition_umount(disk_target.partition['efi'])
else:
print('Installing GRUB to the drive')
@@ -951,8 +977,19 @@ def add_image(image_path: str, vrf: str = None, username: str = '',
if image.is_live_boot():
exit(MSG_ERR_LIVE)
+ # Trying to upgrade with insufficient space can break the system.
+ # It's better to be on the safe side:
+ # our images are a bit below 1G,
+ # so one gigabyte to download the image plus one more to install it
+ # sounds like a sensible estimate.
+ if disk_usage('/').free < (2 * 1024**3):
+ exit(MSG_ERR_NOT_ENOUGH_SPACE)
+
+ environ['REMOTE_USERNAME'] = username
+ environ['REMOTE_PASSWORD'] = password
+
# fetch an image
- iso_path: Path = image_fetch(image_path, vrf, username, password, no_prompt)
+ iso_path: Path = image_fetch(image_path, vrf, no_prompt)
try:
# mount an ISO
Path(DIR_ISO_MOUNT).mkdir(mode=0o755, parents=True)
@@ -1014,6 +1051,12 @@ def add_image(image_path: str, vrf: str = None, username: str = '',
chmod_2775(target_config_dir)
copytree('/opt/vyatta/etc/config/', target_config_dir, symlinks=True,
copy_function=copy_preserve_owner, dirs_exist_ok=True)
+
+ # Record information from which image we upgraded to the new one.
+ # This can be used for a future automatic rollback into the old image.
+ tmp = {'previous_image' : image.get_running_image()}
+ write_file(f'{target_config_dir}/first_boot', dumps(tmp))
+
else:
Path(target_config_dir).mkdir(parents=True)
chown(target_config_dir, group='vyattacfg')
@@ -1045,6 +1088,12 @@ def add_image(image_path: str, vrf: str = None, username: str = '',
if set_as_default:
grub.set_default(image_name, root_dir)
+ cmdline_options = get_cli_kernel_options(
+ f'{target_config_dir}/config.boot')
+ grub_util.update_kernel_cmdline_options(' '.join(cmdline_options),
+ root_dir=root_dir,
+ version=image_name)
+
except OSError as e:
# if no space error, remove image dir and cleanup
if e.errno == ENOSPC:
diff --git a/src/op_mode/image_manager.py b/src/op_mode/image_manager.py
index fb4286dbc..40668793e 100755
--- a/src/op_mode/image_manager.py
+++ b/src/op_mode/image_manager.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This file is part of VyOS.
#
diff --git a/src/op_mode/install_mok.sh b/src/op_mode/install_mok.sh
new file mode 100755
index 000000000..29f78cd1f
--- /dev/null
+++ b/src/op_mode/install_mok.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if test -f /var/lib/shim-signed/mok/vyos-dev-2025-shim.der; then
+ mokutil --ignore-keyring --import /var/lib/shim-signed/mok/vyos-dev-2025-shim.der;
+else
+ echo "Secure Boot Machine Owner Key not found";
+fi
diff --git a/src/op_mode/interfaces.py b/src/op_mode/interfaces.py
index e7afc4caa..43546bb82 100755
--- a/src/op_mode/interfaces.py
+++ b/src/op_mode/interfaces.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
@@ -29,6 +29,7 @@ from vyos.ifconfig import Section
from vyos.ifconfig import Interface
from vyos.ifconfig import VRRP
from vyos.utils.process import cmd
+from vyos.utils.network import interface_exists
from vyos.utils.process import rc_cmd
from vyos.utils.process import call
@@ -84,6 +85,14 @@ def filtered_interfaces(ifnames: typing.Union[str, list],
yield interface
+def detailed_output(dataset, headers):
+ for data in dataset:
+ adjusted_rule = data + [""] * (len(headers) - len(data)) # account for different header length, like default-action
+ transformed_rule = [[header, adjusted_rule[i]] for i, header in enumerate(headers) if i < len(adjusted_rule)] # create key-pair list from headers and rules lists; wrap at 100 char
+
+ print(tabulate(transformed_rule, tablefmt="presto"))
+ print()
+
def _split_text(text, used=0):
"""
take a string and attempt to split it to fit with the width of the screen
@@ -296,6 +305,114 @@ def _get_counter_data(ifname: typing.Optional[str],
return ret
+def _get_kernel_data(raw, ifname = None, detail = False):
+ if ifname:
+ # Check if the interface exists
+ if not interface_exists(ifname):
+ raise vyos.opmode.IncorrectValue(f"{ifname} does not exist!")
+ int_name = f'dev {ifname}'
+ else:
+ int_name = ''
+
+ kernel_interface = json.loads(cmd(f'ip -j -d -s address show {int_name}'))
+
+ # Return early if raw
+ if raw:
+ return kernel_interface, None
+
+ # Format the kernel data
+ kernel_interface_out = _format_kernel_data(kernel_interface, detail)
+
+ return kernel_interface, kernel_interface_out
+
+def _format_kernel_data(data, detail):
+ output_list = []
+ tmpInfo = {}
+
+ # Sort interfaces by name
+ for interface in sorted(data, key=lambda x: x.get('ifname', '')):
+ if interface.get('linkinfo', {}).get('info_kind') == 'vrf':
+ continue
+
+ # Get the device model; ex. Intel Corporation Ethernet Controller I225-V
+ dev_model = interface.get('parentdev', '')
+ if 'parentdev' in interface:
+ parentdev = interface['parentdev']
+ if re.match(r'^[0-9a-fA-F]{4}:', parentdev):
+ dev_model = cmd(f'lspci -nn -s {parentdev}').split(']:')[1].strip()
+
+ # Get the IP addresses on interface
+ ip_list = []
+ has_global = False
+
+ for ip in interface['addr_info']:
+ if ip.get('scope') in ('global', 'host'):
+ has_global = True
+ local = ip.get('local', '-')
+ prefixlen = ip.get('prefixlen', '')
+ ip_list.append(f"{local}/{prefixlen}")
+
+
+ # If no global IP address, add '-'; indicates no IP address on interface
+ if not has_global:
+ ip_list.append('-')
+
+ sl_status = ('A' if not 'UP' in interface['flags'] else 'u') + '/' + ('D' if interface['operstate'] == 'DOWN' else 'u')
+
+ # Generate temporary dict to hold data
+ tmpInfo['ifname'] = interface.get('ifname', '')
+ tmpInfo['ip'] = ip_list
+ tmpInfo['mac'] = interface.get('address', '')
+ tmpInfo['mtu'] = interface.get('mtu', '')
+ tmpInfo['vrf'] = interface.get('master', 'default')
+ tmpInfo['status'] = sl_status
+ tmpInfo['description'] = interface.get('ifalias', '')
+ tmpInfo['device'] = dev_model
+ tmpInfo['alternate_names'] = interface.get('altnames', '')
+ tmpInfo['minimum_mtu'] = interface.get('min_mtu', '')
+ tmpInfo['maximum_mtu'] = interface.get('max_mtu', '')
+ rx_stats = interface.get('stats64', {}).get('rx')
+ tx_stats = interface.get('stats64', {}).get('tx')
+ tmpInfo['rx_packets'] = rx_stats.get('packets', "")
+ tmpInfo['rx_bytes'] = rx_stats.get('bytes', "")
+ tmpInfo['rx_errors'] = rx_stats.get('errors', "")
+ tmpInfo['rx_dropped'] = rx_stats.get('dropped', "")
+ tmpInfo['rx_over_errors'] = rx_stats.get('over_errors', '')
+ tmpInfo['multicast'] = rx_stats.get('multicast', "")
+ tmpInfo['tx_packets'] = tx_stats.get('packets', "")
+ tmpInfo['tx_bytes'] = tx_stats.get('bytes', "")
+ tmpInfo['tx_errors'] = tx_stats.get('errors', "")
+ tmpInfo['tx_dropped'] = tx_stats.get('dropped', "")
+ tmpInfo['tx_carrier_errors'] = tx_stats.get('carrier_errors', "")
+ tmpInfo['tx_collisions'] = tx_stats.get('collisions', "")
+
+ # Generate output list; detail adds more fields
+ output_list.append([tmpInfo['ifname'],
+ '\n'.join(tmpInfo['ip']),
+ tmpInfo['mac'],
+ tmpInfo['vrf'],
+ tmpInfo['mtu'],
+ tmpInfo['status'],
+ tmpInfo['description'],
+ *([tmpInfo['device']] if detail else []),
+ *(['\n'.join(tmpInfo['alternate_names'])] if detail else []),
+ *([tmpInfo['minimum_mtu']] if detail else []),
+ *([tmpInfo['maximum_mtu']] if detail else []),
+ *([tmpInfo['rx_packets']] if detail else []),
+ *([tmpInfo['rx_bytes']] if detail else []),
+ *([tmpInfo['rx_errors']] if detail else []),
+ *([tmpInfo['rx_dropped']] if detail else []),
+ *([tmpInfo['rx_over_errors']] if detail else []),
+ *([tmpInfo['multicast']] if detail else []),
+ *([tmpInfo['tx_packets']] if detail else []),
+ *([tmpInfo['tx_bytes']] if detail else []),
+ *([tmpInfo['tx_errors']] if detail else []),
+ *([tmpInfo['tx_dropped']] if detail else []),
+ *([tmpInfo['tx_carrier_errors']] if detail else []),
+ *([tmpInfo['tx_collisions']] if detail else [])])
+
+ return output_list
+
@catch_broken_pipe
def _format_show_data(data: list):
unhandled = []
@@ -445,6 +562,27 @@ def _format_show_counters(data: list):
print (output)
return output
+def show_kernel(raw: bool, intf_name: typing.Optional[str], detail: bool):
+ raw_data, data = _get_kernel_data(raw, intf_name, detail)
+
+ # Return early if raw
+ if raw:
+ return raw_data
+
+ # Normal headers; show interfaces kernel
+ headers = ['Interface', 'IP Address', 'MAC', 'VRF', 'MTU', 'S/L', 'Description']
+
+ # Detail headers; show interfaces kernel detail
+ detail_header = ['Interface', 'IP Address', 'MAC', 'VRF', 'MTU', 'S/L', 'Description',
+ 'Device', 'Alternate Names','Minimum MTU', 'Maximum MTU', 'RX_Packets',
+ 'RX_Bytes', 'RX_Errors', 'RX_Dropped', 'Receive Overrun Errors', 'Received Multicast',
+ 'TX_Packets', 'TX_Bytes', 'TX_Errors', 'TX_Dropped', 'Transmit Carrier Errors',
+ 'Transmit Collisions']
+
+ if detail:
+ detailed_output(data, detail_header)
+ else:
+ print(tabulate(data, headers))
def _show_raw(data: list, intf_name: str):
if intf_name is not None and len(data) <= 1:
diff --git a/src/op_mode/interfaces_wireguard.py b/src/op_mode/interfaces_wireguard.py
index 627af0579..3c63d83ff 100644
--- a/src/op_mode/interfaces_wireguard.py
+++ b/src/op_mode/interfaces_wireguard.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/interfaces_wireless.py b/src/op_mode/interfaces_wireless.py
index bf6e462f3..5a708ad27 100755
--- a/src/op_mode/interfaces_wireless.py
+++ b/src/op_mode/interfaces_wireless.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ipoe-control.py b/src/op_mode/ipoe-control.py
index b7d6a0c43..f2934458e 100755
--- a/src/op_mode/ipoe-control.py
+++ b/src/op_mode/ipoe-control.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py
index 1ab50b105..649e4d095 100755
--- a/src/op_mode/ipsec.py
+++ b/src/op_mode/ipsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/kernel_modules.py b/src/op_mode/kernel_modules.py
index e381a1df7..5475158aa 100755
--- a/src/op_mode/kernel_modules.py
+++ b/src/op_mode/kernel_modules.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/lldp.py b/src/op_mode/lldp.py
index fac622b81..6d77db5bc 100755
--- a/src/op_mode/lldp.py
+++ b/src/op_mode/lldp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/load-balancing_haproxy.py b/src/op_mode/load-balancing_haproxy.py
index ae6734e16..3ea016677 100755
--- a/src/op_mode/load-balancing_haproxy.py
+++ b/src/op_mode/load-balancing_haproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/load-balancing_wan.py b/src/op_mode/load-balancing_wan.py
index 9fa473802..6f1d00dcd 100755
--- a/src/op_mode/load-balancing_wan.py
+++ b/src/op_mode/load-balancing_wan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
@@ -56,13 +56,15 @@ def _get_raw_data():
return data
def _get_formatted_output(raw_data):
+ from time import time
+
for ifname, if_data in raw_data.items():
latest_change = if_data['last_success'] if if_data['last_success'] > if_data['last_failure'] else if_data['last_failure']
change_dt = datetime.fromtimestamp(latest_change) if latest_change > 0 else None
success_dt = datetime.fromtimestamp(if_data['last_success']) if if_data['last_success'] > 0 else None
failure_dt = datetime.fromtimestamp(if_data['last_failure']) if if_data['last_failure'] > 0 else None
- now = datetime.utcnow()
+ now = datetime.fromtimestamp(time())
fmt_data = {
'ifname': ifname,
diff --git a/src/op_mode/log.py b/src/op_mode/log.py
index 797ba5a88..0bf44cf6a 100755
--- a/src/op_mode/log.py
+++ b/src/op_mode/log.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/maya_date.py b/src/op_mode/maya_date.py
index 847b543e0..06f2f22b1 100755
--- a/src/op_mode/maya_date.py
+++ b/src/op_mode/maya_date.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (c) 2013, 2018 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/memory.py b/src/op_mode/memory.py
index eb530035b..20d937243 100755
--- a/src/op_mode/memory.py
+++ b/src/op_mode/memory.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/mtr.py b/src/op_mode/mtr.py
index 522cbe008..646d95e7b 100644
--- a/src/op_mode/mtr.py
+++ b/src/op_mode/mtr.py
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/mtr_execute.py b/src/op_mode/mtr_execute.py
index 2585a7ee4..b97e46a1f 100644
--- a/src/op_mode/mtr_execute.py
+++ b/src/op_mode/mtr_execute.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/multicast.py b/src/op_mode/multicast.py
index 0666f8af3..096d01665 100755
--- a/src/op_mode/multicast.py
+++ b/src/op_mode/multicast.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/nat.py b/src/op_mode/nat.py
index c6cf4770a..a65bcfd59 100755
--- a/src/op_mode/nat.py
+++ b/src/op_mode/nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/neighbor.py b/src/op_mode/neighbor.py
index 8b3c45c7c..50fcf87c5 100755
--- a/src/op_mode/neighbor.py
+++ b/src/op_mode/neighbor.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ntp.py b/src/op_mode/ntp.py
index 6ec0fedcb..42d0c1b00 100644
--- a/src/op_mode/ntp.py
+++ b/src/op_mode/ntp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/openconnect-control.py b/src/op_mode/openconnect-control.py
index b70d4fa16..dec5b9482 100755
--- a/src/op_mode/openconnect-control.py
+++ b/src/op_mode/openconnect-control.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/openconnect.py b/src/op_mode/openconnect.py
index 62c683ebb..35df25856 100755
--- a/src/op_mode/openconnect.py
+++ b/src/op_mode/openconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/openvpn.py b/src/op_mode/openvpn.py
index 092873909..7347ac757 100755
--- a/src/op_mode/openvpn.py
+++ b/src/op_mode/openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/otp.py b/src/op_mode/otp.py
index a4ab9b22b..aceb75660 100755
--- a/src/op_mode/otp.py
+++ b/src/op_mode/otp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-
-# Copyright 2017, 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py
index 583d8792c..e9487e03b 100755
--- a/src/op_mode/ping.py
+++ b/src/op_mode/ping.py
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py
index 49a461e9e..2ee57a458 100755
--- a/src/op_mode/pki.py
+++ b/src/op_mode/pki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -1373,6 +1373,21 @@ def show_all(raw: bool):
print('\n')
show_crl(raw)
+def renew_certbot(raw: bool, force: typing.Optional[bool] = False):
+ from vyos.defaults import directories
+
+ certbot_config = directories['certbot']
+ hook_dir = directories['base']
+
+ tmp = f'/usr/bin/certbot renew --no-random-sleep-on-renew ' \
+ f'--config-dir "{certbot_config}" ' \
+ f'--post-hook "{hook_dir}/vyos-certbot-renew-pki.sh"'
+ if force:
+ tmp += ' --force-renewal'
+
+ out = cmd(tmp)
+ if not raw:
+ print(out)
if __name__ == '__main__':
try:
diff --git a/src/op_mode/policy_route.py b/src/op_mode/policy_route.py
index d12465008..966dc80f9 100755
--- a/src/op_mode/policy_route.py
+++ b/src/op_mode/policy_route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py
index c32a2be7d..a60c33dc6 100755
--- a/src/op_mode/powerctrl.py
+++ b/src/op_mode/powerctrl.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ppp-server-ctrl.py b/src/op_mode/ppp-server-ctrl.py
index 2bae5b32a..96b497549 100755
--- a/src/op_mode/ppp-server-ctrl.py
+++ b/src/op_mode/ppp-server-ctrl.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/qos.py b/src/op_mode/qos.py
index 464b552ee..47a7a3d59 100755
--- a/src/op_mode/qos.py
+++ b/src/op_mode/qos.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/raid.py b/src/op_mode/raid.py
index fed8ae2c3..985ef730f 100755
--- a/src/op_mode/raid.py
+++ b/src/op_mode/raid.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/reset_openvpn.py b/src/op_mode/reset_openvpn.py
index cef5299da..e3345435a 100755
--- a/src/op_mode/reset_openvpn.py
+++ b/src/op_mode/reset_openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/reset_vpn.py b/src/op_mode/reset_vpn.py
index 61d7c8c81..4ff1740d2 100755
--- a/src/op_mode/reset_vpn.py
+++ b/src/op_mode/reset_vpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/reset_wireguard.py b/src/op_mode/reset_wireguard.py
index 1fcfb31b5..60aeef52d 100755
--- a/src/op_mode/reset_wireguard.py
+++ b/src/op_mode/reset_wireguard.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/restart.py b/src/op_mode/restart.py
index efa835485..7f50ba621 100755
--- a/src/op_mode/restart.py
+++ b/src/op_mode/restart.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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 as
diff --git a/src/op_mode/restart_dhcp_relay.py b/src/op_mode/restart_dhcp_relay.py
index 42626cac4..99c2c20b6 100755
--- a/src/op_mode/restart_dhcp_relay.py
+++ b/src/op_mode/restart_dhcp_relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index 83146f5ec..188d99037 100755
--- a/src/op_mode/restart_frr.py
+++ b/src/op_mode/restart_frr.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/route.py b/src/op_mode/route.py
index 4aa57dbf4..b11b0ccc2 100755
--- a/src/op_mode/route.py
+++ b/src/op_mode/route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/secure_boot.py b/src/op_mode/secure_boot.py
index 5f6390a15..a2d4c9e72 100755
--- a/src/op_mode/secure_boot.py
+++ b/src/op_mode/secure_boot.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/serial.py b/src/op_mode/serial.py
index a5864872b..e9f9fc121 100644
--- a/src/op_mode/serial.py
+++ b/src/op_mode/serial.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/sflow.py b/src/op_mode/sflow.py
index 0f3feb35a..668d0b7b3 100755
--- a/src/op_mode/sflow.py
+++ b/src/op_mode/sflow.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show-bond.py b/src/op_mode/show-bond.py
index f676e0841..0be3ae215 100755
--- a/src/op_mode/show-bond.py
+++ b/src/op_mode/show-bond.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_acceleration.py b/src/op_mode/show_acceleration.py
index 1c4831f1d..6d1d842fa 100755
--- a/src/op_mode/show_acceleration.py
+++ b/src/op_mode/show_acceleration.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_bonding_detail.sh b/src/op_mode/show_bonding_detail.sh
new file mode 100755
index 000000000..62265daa2
--- /dev/null
+++ b/src/op_mode/show_bonding_detail.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ -f "/proc/net/bonding/$1" ]; then
+ cat "/proc/net/bonding/$1";
+else
+ echo "Interface $1 does not exist!";
+fi
diff --git a/src/op_mode/show_configuration_json.py b/src/op_mode/show_configuration_json.py
index fdece533b..4e4b4d386 100755
--- a/src/op_mode/show_configuration_json.py
+++ b/src/op_mode/show_configuration_json.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_openconnect_otp.py b/src/op_mode/show_openconnect_otp.py
index 3771fb385..36aa7bf11 100755
--- a/src/op_mode/show_openconnect_otp.py
+++ b/src/op_mode/show_openconnect_otp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/show_openvpn.py b/src/op_mode/show_openvpn.py
index 6abafc8b6..9f2708b69 100755
--- a/src/op_mode/show_openvpn.py
+++ b/src/op_mode/show_openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_openvpn_mfa.py b/src/op_mode/show_openvpn_mfa.py
index 100c42154..a08fd33ae 100755
--- a/src/op_mode/show_openvpn_mfa.py
+++ b/src/op_mode/show_openvpn_mfa.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/show_ppp_stats.sh b/src/op_mode/show_ppp_stats.sh
new file mode 100755
index 000000000..d9c17f966
--- /dev/null
+++ b/src/op_mode/show_ppp_stats.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if [ -d "/sys/class/net/$1" ]; then
+ /usr/sbin/pppstats "$1";
+fi
diff --git a/src/op_mode/show_sensors.py b/src/op_mode/show_sensors.py
index 5e3084fe9..1efcc9aec 100755
--- a/src/op_mode/show_sensors.py
+++ b/src/op_mode/show_sensors.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/show_techsupport_report.py b/src/op_mode/show_techsupport_report.py
index 32cf67778..d75911d50 100644
--- a/src/op_mode/show_techsupport_report.py
+++ b/src/op_mode/show_techsupport_report.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_usb_serial.py b/src/op_mode/show_usb_serial.py
index 973bf19c8..7c1d2a07f 100755
--- a/src/op_mode/show_usb_serial.py
+++ b/src/op_mode/show_usb_serial.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_users.py b/src/op_mode/show_users.py
index 82bd585c9..bccfaf991 100755
--- a/src/op_mode/show_users.py
+++ b/src/op_mode/show_users.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_virtual_server.py b/src/op_mode/show_virtual_server.py
index 7880edc97..5c6ba4f4e 100755
--- a/src/op_mode/show_virtual_server.py
+++ b/src/op_mode/show_virtual_server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/show_wwan.py b/src/op_mode/show_wwan.py
index bd97bb0e5..05e7d0e75 100755
--- a/src/op_mode/show_wwan.py
+++ b/src/op_mode/show_wwan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/snmp.py b/src/op_mode/snmp.py
index 3d6cd220a..ea952aaaa 100755
--- a/src/op_mode/snmp.py
+++ b/src/op_mode/snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/snmp_ifmib.py b/src/op_mode/snmp_ifmib.py
index c71febac9..020865c9d 100755
--- a/src/op_mode/snmp_ifmib.py
+++ b/src/op_mode/snmp_ifmib.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/snmp_v3.py b/src/op_mode/snmp_v3.py
index abeb524dd..94c6691b0 100755
--- a/src/op_mode/snmp_v3.py
+++ b/src/op_mode/snmp_v3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/ssh.py b/src/op_mode/ssh.py
index 0c51576b0..a4442c301 100755
--- a/src/op_mode/ssh.py
+++ b/src/op_mode/ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/op_mode/storage.py b/src/op_mode/storage.py
index 8fd2ffea1..7e869e9d9 100755
--- a/src/op_mode/storage.py
+++ b/src/op_mode/storage.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/stp.py b/src/op_mode/stp.py
index fb57bd7ee..ae0954604 100755
--- a/src/op_mode/stp.py
+++ b/src/op_mode/stp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/system.py b/src/op_mode/system.py
index 854b4b699..6d0815a4a 100755
--- a/src/op_mode/system.py
+++ b/src/op_mode/system.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/tcpdump.py b/src/op_mode/tcpdump.py
index 607b59603..fcdb23a81 100644
--- a/src/op_mode/tcpdump.py
+++ b/src/op_mode/tcpdump.py
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/tech_support.py b/src/op_mode/tech_support.py
index 24ac0af1b..6055cbf15 100644
--- a/src/op_mode/tech_support.py
+++ b/src/op_mode/tech_support.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
@@ -20,6 +20,7 @@ import json
import vyos.opmode
from vyos.utils.process import cmd
+from vyos.base import Warning
def _get_version_data():
from vyos.version import get_version_data
@@ -51,7 +52,12 @@ def _get_storage():
def _get_devices():
devices = {}
devices["pci"] = cmd("lspci")
- devices["usb"] = cmd("lsusb")
+
+ try:
+ devices["usb"] = cmd("lsusb")
+ except OSError:
+ Warning("Could not retrieve information about USB devices")
+ devices["usb"] = {}
return devices
diff --git a/src/op_mode/toggle_help_binding.sh b/src/op_mode/toggle_help_binding.sh
index a8708f3da..7c8bc05ce 100755
--- a/src/op_mode/toggle_help_binding.sh
+++ b/src/op_mode/toggle_help_binding.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/traceroute.py b/src/op_mode/traceroute.py
index d2bac3f7c..cc19464e2 100755
--- a/src/op_mode/traceroute.py
+++ b/src/op_mode/traceroute.py
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/update_suricata.sh b/src/op_mode/update_suricata.sh
new file mode 100755
index 000000000..6e4e605f4
--- /dev/null
+++ b/src/op_mode/update_suricata.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if test -f /run/suricata/suricata.yaml; then
+ suricata-update --suricata-conf /run/suricata/suricata.yaml;
+ systemctl restart suricata;
+else
+ echo "Service Suricata not configured";
+fi
diff --git a/src/op_mode/uptime.py b/src/op_mode/uptime.py
index 1c1a149ec..90475cb50 100755
--- a/src/op_mode/uptime.py
+++ b/src/op_mode/uptime.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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 as
diff --git a/src/op_mode/version.py b/src/op_mode/version.py
index 71a40dd50..b93e3081b 100755
--- a/src/op_mode/version.py
+++ b/src/op_mode/version.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2016-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/vpn_ike_sa.py b/src/op_mode/vpn_ike_sa.py
index 9385bcd0c..0cd192174 100755
--- a/src/op_mode/vpn_ike_sa.py
+++ b/src/op_mode/vpn_ike_sa.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/vpn_ipsec.py b/src/op_mode/vpn_ipsec.py
index ef89e605f..3d7049a14 100755
--- a/src/op_mode/vpn_ipsec.py
+++ b/src/op_mode/vpn_ipsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright 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
@@ -23,13 +23,13 @@ SWANCTL_CONF = '/etc/swanctl/swanctl.conf'
def get_peer_connections(peer, tunnel, return_all = False):
- search = rf'^[\s]*(peer_{peer}_(tunnel_[\d]+|vti)).*'
+ search = rf'^[\s]*({peer}-(tunnel-[\d]+|vti))[\s]*{{'
matches = []
with open(SWANCTL_CONF, 'r') as f:
for line in f.readlines():
result = re.match(search, line)
if result:
- suffix = f'tunnel_{tunnel}' if tunnel.isnumeric() else tunnel
+ suffix = f'tunnel-{tunnel}' if tunnel.isnumeric() else tunnel
if return_all or (result[2] == suffix):
matches.append(result[1])
return matches
@@ -66,7 +66,8 @@ def debug_peer(peer, tunnel):
return
for conn in conns:
- call(f'/usr/sbin/ipsec statusall | grep {conn}')
+ command = f'/usr/sbin/ipsec statusall | grep {conn}'
+ call(command)
if __name__ == '__main__':
diff --git a/src/op_mode/vrf.py b/src/op_mode/vrf.py
index 51032a4b5..a13b48866 100755
--- a/src/op_mode/vrf.py
+++ b/src/op_mode/vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py
index ef1338e23..c8414b03e 100755
--- a/src/op_mode/vrrp.py
+++ b/src/op_mode/vrrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/webproxy_update_blacklist.sh b/src/op_mode/webproxy_update_blacklist.sh
index 05ea86f9e..90594daf6 100755
--- a/src/op_mode/webproxy_update_blacklist.sh
+++ b/src/op_mode/webproxy_update_blacklist.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/wireguard_client.py b/src/op_mode/wireguard_client.py
index 04d8ce28c..7638d24a0 100755
--- a/src/op_mode/wireguard_client.py
+++ b/src/op_mode/wireguard_client.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/op_mode/zone.py b/src/op_mode/zone.py
index df39549d2..8bdf373a8 100644
--- a/src/op_mode/zone.py
+++ b/src/op_mode/zone.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run b/src/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run
index f0479ae88..6bc77b61d 100644
--- a/src/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run
+++ b/src/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run
@@ -222,10 +222,21 @@ _vyatta_op_run ()
local cmd_regex="^(LESSOPEN=|less|pager|tail|(sudo )?$file_cmd).*"
if [ -n "$run_cmd" ]; then
eval $restore_shopts
- if [[ -t 1 && "${args[1]}" == "show" && ! $run_cmd =~ $cmd_regex ]] ; then
- eval "($run_cmd) | ${VYATTA_PAGER:-cat}"
- else
+ if [[ "${args[1]}" == "configure" ]]; then
+ # The "configure" command modifies the shell environment
+ # and must run in the current shell.
+ eval "$run_cmd"
+ elif [[ "${args[1]} ${args[2]}" =~ ^set[[:space:]]+(builtin|terminal) ]]; then
+ # Some commands like "set terminal width"
+ # only affect the user shell
+ # (so they don't need special privileges)
+ # and must be executed directly in the current shell
+ # to be able to do their job.
eval "$run_cmd"
+ elif [[ -t 1 && "${args[1]}" == "show" && ! $run_cmd =~ $cmd_regex ]] ; then
+ eval "(sudo $run_cmd) | ${VYATTA_PAGER:-cat}"
+ else
+ eval "sudo $run_cmd"
fi
else
echo -ne "\n Incomplete command: ${args[@]}\n\n" >&2
diff --git a/src/services/api/graphql/bindings.py b/src/services/api/graphql/bindings.py
index ebf745f32..7380dbb5f 100644
--- a/src/services/api/graphql/bindings.py
+++ b/src/services/api/graphql/bindings.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/generate/generate_schema.py b/src/services/api/graphql/generate/generate_schema.py
index dd5e7ea56..bb36a4c04 100755
--- a/src/services/api/graphql/generate/generate_schema.py
+++ b/src/services/api/graphql/generate/generate_schema.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/api/graphql/generate/schema_from_composite.py b/src/services/api/graphql/generate/schema_from_composite.py
index 06e74032d..e370961dc 100755
--- a/src/services/api/graphql/generate/schema_from_composite.py
+++ b/src/services/api/graphql/generate/schema_from_composite.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/api/graphql/generate/schema_from_config_session.py b/src/services/api/graphql/generate/schema_from_config_session.py
index 1d5ff1e53..61ac9bd39 100755
--- a/src/services/api/graphql/generate/schema_from_config_session.py
+++ b/src/services/api/graphql/generate/schema_from_config_session.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/api/graphql/generate/schema_from_op_mode.py b/src/services/api/graphql/generate/schema_from_op_mode.py
index ab7cb691f..8cfd60769 100755
--- a/src/services/api/graphql/generate/schema_from_op_mode.py
+++ b/src/services/api/graphql/generate/schema_from_op_mode.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/api/graphql/graphql/auth_token_mutation.py b/src/services/api/graphql/graphql/auth_token_mutation.py
index c74364603..a8020d149 100644
--- a/src/services/api/graphql/graphql/auth_token_mutation.py
+++ b/src/services/api/graphql/graphql/auth_token_mutation.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/graphql/directives.py b/src/services/api/graphql/graphql/directives.py
index 3927aee58..037f09204 100644
--- a/src/services/api/graphql/graphql/directives.py
+++ b/src/services/api/graphql/graphql/directives.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/graphql/mutations.py b/src/services/api/graphql/graphql/mutations.py
index 0b391c070..c979d06e8 100644
--- a/src/services/api/graphql/graphql/mutations.py
+++ b/src/services/api/graphql/graphql/mutations.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/graphql/queries.py b/src/services/api/graphql/graphql/queries.py
index 9303fe909..3a8d12344 100644
--- a/src/services/api/graphql/graphql/queries.py
+++ b/src/services/api/graphql/graphql/queries.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/libs/key_auth.py b/src/services/api/graphql/libs/key_auth.py
index ffd7f32b2..dc3322fea 100644
--- a/src/services/api/graphql/libs/key_auth.py
+++ b/src/services/api/graphql/libs/key_auth.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/libs/op_mode.py b/src/services/api/graphql/libs/op_mode.py
index 86e38eae6..fa726264c 100644
--- a/src/services/api/graphql/libs/op_mode.py
+++ b/src/services/api/graphql/libs/op_mode.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/libs/token_auth.py b/src/services/api/graphql/libs/token_auth.py
index 4f743a096..73c52bdf0 100644
--- a/src/services/api/graphql/libs/token_auth.py
+++ b/src/services/api/graphql/libs/token_auth.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/routers.py b/src/services/api/graphql/routers.py
index ed3ee1e8c..5526918d9 100644
--- a/src/services/api/graphql/routers.py
+++ b/src/services/api/graphql/routers.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/session/composite/system_status.py b/src/services/api/graphql/session/composite/system_status.py
index 516a4eff6..1674b2c2b 100755
--- a/src/services/api/graphql/session/composite/system_status.py
+++ b/src/services/api/graphql/session/composite/system_status.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/api/graphql/session/override/remove_firewall_address_group_members.py b/src/services/api/graphql/session/override/remove_firewall_address_group_members.py
index b91932e14..9f39465a1 100644
--- a/src/services/api/graphql/session/override/remove_firewall_address_group_members.py
+++ b/src/services/api/graphql/session/override/remove_firewall_address_group_members.py
@@ -1,4 +1,4 @@
-# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/graphql/session/session.py b/src/services/api/graphql/session/session.py
index 619534f43..e4725e752 100644
--- a/src/services/api/graphql/session/session.py
+++ b/src/services/api/graphql/session/session.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/api/rest/models.py b/src/services/api/rest/models.py
index dda50010f..70fab03ec 100644
--- a/src/services/api/rest/models.py
+++ b/src/services/api/rest/models.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@ from typing import Self
from pydantic import BaseModel
from pydantic import StrictStr
+from pydantic import StrictInt
from pydantic import field_validator
from pydantic import model_validator
from fastapi.responses import HTMLResponse
@@ -71,6 +72,8 @@ class BaseConfigureModel(BasePathModel):
class ConfigureModel(ApiModel, BaseConfigureModel):
+ confirm_time: StrictInt = 0
+
class Config:
json_schema_extra = {
'example': {
@@ -81,8 +84,12 @@ class ConfigureModel(ApiModel, BaseConfigureModel):
}
+class ConfirmModel(ApiModel):
+ op: StrictStr
+
class ConfigureListModel(ApiModel):
commands: List[BaseConfigureModel]
+ confirm_time: StrictInt = 0
class Config:
json_schema_extra = {
@@ -134,13 +141,17 @@ class RetrieveModel(ApiModel):
class ConfigFileModel(ApiModel):
op: StrictStr
file: StrictStr = None
+ string: StrictStr = None
+ confirm_time: StrictInt = 0
+ destructive: bool = False
class Config:
json_schema_extra = {
'example': {
'key': 'id_key',
- 'op': 'save | load',
+ 'op': 'save | load | merge | confirm',
'file': 'filename',
+ 'string': 'config_string'
}
}
@@ -251,6 +262,20 @@ class RebootModel(ApiModel):
}
+class RenewModel(ApiModel):
+ op: StrictStr
+ path: List[StrictStr]
+
+ class Config:
+ json_schema_extra = {
+ 'example': {
+ 'key': 'id_key',
+ 'op': 'renew',
+ 'path': ['op', 'mode', 'path'],
+ }
+ }
+
+
class ResetModel(ApiModel):
op: StrictStr
path: List[StrictStr]
diff --git a/src/services/api/rest/routers.py b/src/services/api/rest/routers.py
index e52c77fda..329d6e51f 100644
--- a/src/services/api/rest/routers.py
+++ b/src/services/api/rest/routers.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,7 @@ from fastapi import HTTPException
from fastapi import APIRouter
from fastapi import BackgroundTasks
from fastapi.routing import APIRoute
+from fastapi.concurrency import run_in_threadpool
from starlette.datastructures import FormData
from starlette.formparsers import FormParser
from starlette.formparsers import MultiPartParser
@@ -51,6 +52,7 @@ from .models import error
from .models import responses
from .models import ApiModel
from .models import ConfigureModel
+from .models import ConfirmModel
from .models import ConfigureListModel
from .models import ConfigSectionModel
from .models import ConfigSectionListModel
@@ -66,6 +68,7 @@ from .models import GenerateModel
from .models import ShowModel
from .models import RebootModel
from .models import ResetModel
+from .models import RenewModel
from .models import ImportPkiModel
from .models import PoweroffModel
from .models import TracerouteModel
@@ -301,8 +304,47 @@ def call_commit(s: SessionState):
LOG.warning(f'ConfigSessionError: {e}')
-def _configure_op(
+def call_commit_confirm(s: SessionState):
+ env = s.session.get_session_env()
+ env['IN_COMMIT_CONFIRM'] = 't'
+ try:
+ s.session.commit()
+ s.session.commit_confirm(minutes=s.confirm_time)
+ except ConfigSessionError as e:
+ s.session.discard()
+ if s.debug:
+ LOG.warning(f'ConfigSessionError:\n {traceback.format_exc()}')
+ else:
+ LOG.warning(f'ConfigSessionError: {e}')
+ finally:
+ del env['IN_COMMIT_CONFIRM']
+
+
+def run_commit(s: SessionState):
+ try:
+ out = s.session.commit()
+ return out, None
+ except Exception as e:
+ return None, e
+
+
+def run_commit_confirm(s: SessionState):
+ env = s.session.get_session_env()
+ env['IN_COMMIT_CONFIRM'] = 't'
+ try:
+ out_c = s.session.commit()
+ out_cc = s.session.commit_confirm(minutes=s.confirm_time)
+ out = out_c + '\n' + out_cc
+ return out, None
+ except Exception as e:
+ return None, e
+ finally:
+ del env['IN_COMMIT_CONFIRM']
+
+
+async def _configure_op(
data: Union[
+ ConfirmModel,
ConfigureModel,
ConfigureListModel,
ConfigSectionModel,
@@ -319,6 +361,11 @@ def _configure_op(
session = state.session
env = session.get_session_env()
+ # A non-zero confirm_time will start commit-confirm timer on commit
+ confirm_time = 0
+ if isinstance(data, (ConfigureModel, ConfigureListModel, ConfigFileModel)):
+ confirm_time = data.confirm_time
+
# Allow users to pass just one command
if not isinstance(data, (ConfigureListModel, ConfigSectionListModel)):
data = [data]
@@ -338,10 +385,16 @@ def _configure_op(
try:
for c in data:
op = c.op
- if not isinstance(c, BaseConfigSectionTreeModel):
+ if not isinstance(c, (ConfirmModel, BaseConfigSectionTreeModel)):
path = c.path
- if isinstance(c, BaseConfigureModel):
+ if isinstance(c, ConfirmModel):
+ if op == 'confirm':
+ msg = session.confirm()
+ else:
+ raise ConfigSessionError(f"'{op}' is not a valid operation")
+
+ elif isinstance(c, BaseConfigureModel):
if c.value:
value = c.value
else:
@@ -387,16 +440,30 @@ def _configure_op(
else:
raise ConfigSessionError(f"'{op}' is not a valid operation")
# end for
+
config = Config(session_env=env)
d = get_config_diff(config)
- if d.is_node_changed(['service', 'https']):
- background_tasks.add_task(call_commit, state)
- msg = self_ref_msg
+ state.confirm_time = confirm_time if confirm_time else 0
+
+ if not d.is_node_changed(['service', 'https']):
+ if confirm_time:
+ out, err = await run_in_threadpool(run_commit_confirm, state)
+ if err:
+ raise err
+ msg = msg + out if msg else out
+ else:
+ out, err = await run_in_threadpool(run_commit, state)
+ if err:
+ raise err
+ msg = msg + out if msg else out
else:
- # capture non-fatal warnings
- out = session.commit()
- msg = out if out else msg
+ if confirm_time:
+ background_tasks.add_task(call_commit_confirm, state)
+ else:
+ background_tasks.add_task(call_commit, state)
+ out = self_ref_msg
+ msg = msg + out if msg else out
LOG.info(f"Configuration modified via HTTP API using key '{state.id}'")
except ConfigSessionError as e:
@@ -413,6 +480,8 @@ def _configure_op(
# Don't give the details away to the outer world
error_msg = 'An internal error occured. Check the logs for details.'
finally:
+ if 'IN_COMMIT_CONFIRM' in env:
+ del env['IN_COMMIT_CONFIRM']
lock.release()
if status != 200:
@@ -431,12 +500,14 @@ def create_path_import_pki_no_prompt(path):
@router.post('/configure')
-def configure_op(
- data: Union[ConfigureModel, ConfigureListModel],
+async def configure_op(
+ data: Union[ConfigureModel, ConfigureListModel, ConfirmModel],
request: Request,
background_tasks: BackgroundTasks,
):
- return _configure_op(data, request, background_tasks)
+ out = await _configure_op(data, request, background_tasks)
+
+ return out
@router.post('/configure-section')
@@ -493,13 +564,18 @@ async def retrieve_op(data: RetrieveModel):
@router.post('/config-file')
-def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):
+async def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):
state = SessionState()
session = state.session
env = session.get_session_env()
op = data.op
msg = None
+ # A non-zero confirm_time will start commit-confirm timer on commit
+ confirm_time = data.confirm_time
+
+ lock.acquire()
+
try:
if op == 'save':
if data.file:
@@ -507,22 +583,48 @@ def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):
else:
path = '/config/config.boot'
msg = session.save_config(path)
- elif op == 'load':
+ elif op in ('load', 'merge'):
if data.file:
path = data.file
+ elif data.string:
+ path = '/tmp/config.file'
+ with open(path, 'w') as f:
+ f.write(data.string)
else:
- return error(400, 'Missing required field "file"')
+ return error(400, 'Missing required field "file | string"')
- session.migrate_and_load_config(path)
+ match op:
+ case 'load':
+ session.migrate_and_load_config(path)
+ case 'merge':
+ session.merge_config(path, destructive=data.destructive)
config = Config(session_env=env)
d = get_config_diff(config)
- if d.is_node_changed(['service', 'https']):
- background_tasks.add_task(call_commit, state)
- msg = self_ref_msg
+ state.confirm_time = confirm_time if confirm_time else 0
+
+ if not d.is_node_changed(['service', 'https']):
+ if confirm_time:
+ out, err = await run_in_threadpool(run_commit_confirm, state)
+ if err:
+ raise err
+ msg = msg + out if msg else out
+ else:
+ out, err = await run_in_threadpool(run_commit, state)
+ if err:
+ raise err
+ msg = msg + out if msg else out
else:
- session.commit()
+ if confirm_time:
+ background_tasks.add_task(call_commit_confirm, state)
+ else:
+ background_tasks.add_task(call_commit, state)
+ out = self_ref_msg
+ msg = msg + out if msg else out
+
+ elif op == 'confirm':
+ msg = session.confirm()
else:
return error(400, f"'{op}' is not a valid operation")
except ConfigSessionError as e:
@@ -530,6 +632,10 @@ def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):
except Exception:
LOG.critical(traceback.format_exc())
return error(500, 'An internal error occured. Check the logs for details.')
+ finally:
+ if 'IN_COMMIT_CONFIRM' in env:
+ del env['IN_COMMIT_CONFIRM']
+ lock.release()
return success(msg)
@@ -657,6 +763,26 @@ def reboot_op(data: RebootModel):
return success(res)
+@router.post('/renew')
+def renew_op(data: RenewModel):
+ state = SessionState()
+ session = state.session
+
+ op = data.op
+ path = data.path
+
+ try:
+ if op == 'renew':
+ res = session.renew(path)
+ else:
+ return error(400, f"'{op}' is not a valid operation")
+ except ConfigSessionError as e:
+ return error(400, str(e))
+ except Exception:
+ LOG.critical(traceback.format_exc())
+ return error(500, 'An internal error occured. Check the logs for details.')
+
+ return success(res)
@router.post('/reset')
def reset_op(data: ResetModel):
diff --git a/src/services/api/session.py b/src/services/api/session.py
index ad3ef660c..c25a444e9 100644
--- a/src/services/api/session.py
+++ b/src/services/api/session.py
@@ -1,4 +1,4 @@
-# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/services/vyos-commitd b/src/services/vyos-commitd
index e7f2d82c7..620d7eb6e 100755
--- a/src/services/vyos-commitd
+++ b/src/services/vyos-commitd
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
@@ -42,6 +42,7 @@ from vyos.defaults import directories
from vyos.utils.boot import boot_configuration_complete
from vyos.configsource import ConfigSourceCache
from vyos.configsource import ConfigSourceError
+from vyos.configdiff import get_commit_scripts
from vyos.config import Config
from vyos.frrender import FRRender
from vyos.frrender import get_frrender_dict
@@ -230,6 +231,9 @@ def initialization(session: Session) -> Session:
dependent_func: dict[str, list[typing.Callable]] = {}
setattr(config, 'dependent_func', dependent_func)
+ commit_scripts = get_commit_scripts(config)
+ logger.debug(f'commit_scripts: {commit_scripts}')
+
scripts_called = []
setattr(config, 'scripts_called', scripts_called)
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index 28acccd2c..22eb48102 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -68,6 +68,7 @@ class Response(Enum):
ERROR_COMMIT = 2
ERROR_DAEMON = 4
PASS = 8
+ ERROR_COMMIT_APPLY = 16
vyos_conf_scripts_dir = directories['conf_mode']
@@ -142,8 +143,6 @@ def run_script(script_name, config, args) -> tuple[Response, str]:
try:
c = script.get_config(config)
script.verify(c)
- script.generate(c)
- script.apply(c)
except ConfigError as e:
logger.error(e)
return Response.ERROR_COMMIT, str(e)
@@ -152,6 +151,17 @@ def run_script(script_name, config, args) -> tuple[Response, str]:
logger.error(tb)
return Response.ERROR_COMMIT, tb
+ try:
+ script.generate(c)
+ script.apply(c)
+ except ConfigError as e:
+ logger.error(e)
+ return Response.ERROR_COMMIT_APPLY, str(e)
+ except Exception:
+ tb = traceback.format_exc()
+ logger.error(tb)
+ return Response.ERROR_COMMIT_APPLY, tb
+
return Response.SUCCESS, ''
diff --git a/src/services/vyos-conntrack-logger b/src/services/vyos-conntrack-logger
index ec0e1f717..6e0733291 100755
--- a/src/services/vyos-conntrack-logger
+++ b/src/services/vyos-conntrack-logger
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/vyos-domain-resolver b/src/services/vyos-domain-resolver
index 4419fc4a7..17dae38e0 100755
--- a/src/services/vyos-domain-resolver
+++ b/src/services/vyos-domain-resolver
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -28,7 +28,7 @@ from vyos.utils.commit import commit_in_progress
from vyos.utils.dict import dict_search_args
from vyos.utils.kernel import WIREGUARD_REKEY_AFTER_TIME
from vyos.utils.file import makedir, chmod_775, write_file, read_file
-from vyos.utils.network import is_valid_ipv4_address_or_range
+from vyos.utils.network import is_valid_ipv4_address_or_range, is_valid_ipv6_address_or_range
from vyos.utils.process import cmd
from vyos.utils.process import run
from vyos.xml_ref import get_defaults
@@ -143,10 +143,11 @@ def update_remote_group(config):
for set_name, remote_config in remote_groups.items():
if 'url' not in remote_config:
continue
- nft_set_name = f'R_{set_name}'
+ nft_ip_set_name = f'R_{set_name}'
+ nft_ip6_set_name = f'R6_{set_name}'
# Create list file if necessary
- list_file = os.path.join(firewall_config_dir, f"{nft_set_name}.txt")
+ list_file = os.path.join(firewall_config_dir, f"{nft_ip_set_name}.txt")
if not os.path.exists(list_file):
write_file(list_file, '', user="root", group="vyattacfg", mode=0o644)
@@ -159,16 +160,32 @@ def update_remote_group(config):
# Read list file
ip_list = []
+ ip6_list = []
+ invalid_list = []
for line in read_file(list_file).splitlines():
line_first_word = line.strip().partition(' ')[0]
if is_valid_ipv4_address_or_range(line_first_word):
ip_list.append(line_first_word)
+ elif is_valid_ipv6_address_or_range(line_first_word):
+ ip6_list.append(line_first_word)
+ else:
+ if line_first_word[0].isalnum():
+ invalid_list.append(line_first_word)
- # Load tables
+ # Load ip tables
for table in ipv4_tables:
- if (table, nft_set_name) in valid_sets:
- conf_lines += nft_output(table, nft_set_name, ip_list)
+ if (table, nft_ip_set_name) in valid_sets:
+ conf_lines += nft_output(table, nft_ip_set_name, ip_list)
+
+ # Load ip6 tables
+ for table in ipv6_tables:
+ if (table, nft_ip6_set_name) in valid_sets:
+ conf_lines += nft_output(table, nft_ip6_set_name, ip6_list)
+
+ invalid_str = ", ".join(invalid_list)
+ if invalid_str:
+ logger.info(f'Invalid address for set {set_name}: {invalid_str}')
count += 1
diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd
index 44f03586c..89742b431 100755
--- a/src/services/vyos-hostsd
+++ b/src/services/vyos-hostsd
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server
index be3dd5051..c9d5f3a1b 100755
--- a/src/services/vyos-http-api-server
+++ b/src/services/vyos-http-api-server
@@ -1,6 +1,6 @@
#!/usr/share/vyos-http-api-tools/bin/python3
#
-# Copyright (C) 2019-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/services/vyos-network-event-logger b/src/services/vyos-network-event-logger
index 840ff3cda..135cc8ec5 100644
--- a/src/services/vyos-network-event-logger
+++ b/src/services/vyos-network-event-logger
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/shim/vyshim.c b/src/shim/vyshim.c
index 1eb653cbf..7b516cd46 100644
--- a/src/shim/vyshim.c
+++ b/src/shim/vyshim.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020-2024 VyOS maintainers and contributors
+ * Copyright 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
@@ -18,8 +18,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <fcntl.h>
#include <unistd.h>
#include <string.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
@@ -55,15 +57,17 @@ enum {
SUCCESS = 1 << 0,
ERROR_COMMIT = 1 << 1,
ERROR_DAEMON = 1 << 2,
- PASS = 1 << 3
+ PASS = 1 << 3,
+ ERROR_COMMIT_APPLY = 1 << 4
};
volatile int init_alarm = 0;
volatile int timeout = 0;
-int initialization(void *);
+int initialization(void *, char *);
int pass_through(char **, int);
void timer_handler(int);
+void leave_hint(char *);
double get_posix_clock_time(void);
@@ -94,8 +98,17 @@ int main(int argc, char* argv[])
char *test = strstr(string_node_data, "VYOS_TAGNODE_VALUE");
ex_index = test ? 2 : 1;
+ char *env_tmp = getenv("VYATTA_CONFIG_TMP");
+ if (env_tmp == NULL) {
+ fprintf(stderr, "Error: Environment variable VYATTA_CONFIG_TMP is not set.\n");
+ exit(EXIT_FAILURE);
+ }
+ char *pid_str = strdup(env_tmp);
+ strsep(&pid_str, "_");
+ debug_print("config session pid: %s\n", pid_str);
+
if (access(COMMIT_MARKER, F_OK) != -1) {
- init_timeout = initialization(requester);
+ init_timeout = initialization(requester, pid_str);
if (!init_timeout) remove(COMMIT_MARKER);
}
@@ -151,13 +164,19 @@ int main(int argc, char* argv[])
ret = -1;
}
+ if (err & ERROR_COMMIT_APPLY) {
+ debug_print("Received ERROR_COMMIT_APPLY\n");
+ leave_hint(pid_str);
+ ret = -1;
+ }
+
zmq_close(requester);
zmq_ctx_destroy(context);
return ret;
}
-int initialization(void* Requester)
+int initialization(void* Requester, char* pid_val)
{
char *active_str = NULL;
size_t active_len = 0;
@@ -185,10 +204,6 @@ int initialization(void* Requester)
double prev_time_value, time_value;
double time_diff;
- char *pid_val = getenv("VYATTA_CONFIG_TMP");
- strsep(&pid_val, "_");
- debug_print("config session pid: %s\n", pid_val);
-
char *sudo_user = getenv("SUDO_USER");
if (!sudo_user) {
char nobody[] = "nobody";
@@ -338,6 +353,16 @@ void timer_handler(int signum)
return;
}
+void leave_hint(char *pid_val)
+{
+ char tmp_str[16];
+ mode_t omask = umask(0);
+ snprintf(tmp_str, sizeof(tmp_str), "/tmp/apply_%s", pid_val);
+ open(tmp_str, O_CREAT|O_RDWR|O_TRUNC, 0666);
+ chown(tmp_str, 1002, 102);
+ umask(omask);
+}
+
#ifdef _POSIX_MONOTONIC_CLOCK
double get_posix_clock_time(void)
{
diff --git a/src/system/grub_update.py b/src/system/grub_update.py
index 5a0534195..a5bf0bdeb 100644
--- a/src/system/grub_update.py
+++ b/src/system/grub_update.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This file is part of VyOS.
#
diff --git a/src/system/keepalived-fifo.py b/src/system/keepalived-fifo.py
index 24733803a..21c261099 100755
--- a/src/system/keepalived-fifo.py
+++ b/src/system/keepalived-fifo.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/normalize-ip b/src/system/normalize-ip
index 08f922a8e..9ef57e28a 100755
--- a/src/system/normalize-ip
+++ b/src/system/normalize-ip
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/on-dhcp-event.sh b/src/system/on-dhcp-event.sh
index 47c276270..77ac30c3a 100755
--- a/src/system/on-dhcp-event.sh
+++ b/src/system/on-dhcp-event.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/on-dhcpv6-event.sh b/src/system/on-dhcpv6-event.sh
index cbb370999..93fd3ce81 100755
--- a/src/system/on-dhcpv6-event.sh
+++ b/src/system/on-dhcpv6-event.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/sync-dhcp-lease-to-hosts.py b/src/system/sync-dhcp-lease-to-hosts.py
index 5c8b18faf..fbce4c9ea 100755
--- a/src/system/sync-dhcp-lease-to-hosts.py
+++ b/src/system/sync-dhcp-lease-to-hosts.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/uacctd_stop.py b/src/system/uacctd_stop.py
index a1b57335b..2f0a4bb74 100755
--- a/src/system/uacctd_stop.py
+++ b/src/system/uacctd_stop.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/vyos-config-cloud-init.py b/src/system/vyos-config-cloud-init.py
index 0a6c1f9bc..1fdfb00db 100755
--- a/src/system/vyos-config-cloud-init.py
+++ b/src/system/vyos-config-cloud-init.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/vyos-event-handler.py b/src/system/vyos-event-handler.py
index dd2793046..7fc21bae4 100755
--- a/src/system/vyos-event-handler.py
+++ b/src/system/vyos-event-handler.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/system/vyos-system-update-check.py b/src/system/vyos-system-update-check.py
index c874f1e2c..66a8b0d02 100755
--- a/src/system/vyos-system-update-check.py
+++ b/src/system/vyos-system-update-check.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/systemd/netplug.service b/src/systemd/netplug.service
new file mode 100644
index 000000000..928c553e8
--- /dev/null
+++ b/src/systemd/netplug.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Network cable hotplug management daemon
+Documentation=man:netplugd(8)
+After=vyos-router.service
+
+[Service]
+Type=forking
+PIDFile=/run/netplugd.pid
+ExecStart=/sbin/netplugd -c /etc/netplug/netplugd.conf -p /run/netplugd.pid
diff --git a/src/systemd/opennhrp.service b/src/systemd/opennhrp.service
deleted file mode 100644
index c9a44de29..000000000
--- a/src/systemd/opennhrp.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=OpenNHRP
-After=vyos-router.service
-ConditionPathExists=/run/opennhrp/opennhrp.conf
-StartLimitIntervalSec=0
-
-[Service]
-Type=forking
-ExecStart=/usr/sbin/opennhrp -d -v -a /run/opennhrp.socket -c /run/opennhrp/opennhrp.conf -s /etc/opennhrp/opennhrp-script.py -p /run/opennhrp/opennhrp.pid
-ExecReload=/usr/bin/kill -HUP $MAINPID
-PIDFile=/run/opennhrp/opennhrp.pid
-Restart=on-failure
-RestartSec=20
diff --git a/src/systemd/vyconfd.service b/src/systemd/vyconfd.service
index ab2280263..d23ca2202 100644
--- a/src/systemd/vyconfd.service
+++ b/src/systemd/vyconfd.service
@@ -8,7 +8,7 @@ DefaultDependencies=no
After=systemd-remount-fs.service
[Service]
-ExecStart=/usr/libexec/vyos/vyconf/vyconfd --log-file /var/run/log/vyconfd.log
+ExecStart=/usr/libexec/vyos/vyconf/vyconfd --log-file /var/run/log/vyconfd.log --legacy-config-path
Type=exec
SyslogIdentifier=vyconfd
SyslogFacility=daemon
diff --git a/src/systemd/vyos.target b/src/systemd/vyos.target
index 47c91c1cc..ea1593fe9 100644
--- a/src/systemd/vyos.target
+++ b/src/systemd/vyos.target
@@ -1,3 +1,3 @@
[Unit]
Description=VyOS target
-After=multi-user.target
+After=multi-user.target vyos-grub-update.service systemd-sysctl.service
diff --git a/src/tests/helper.py b/src/tests/helper.py
index cc0710494..2c4421d0a 100644
--- a/src/tests/helper.py
+++ b/src/tests/helper.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_config_diff.py b/src/tests/test_config_diff.py
index 4017fff4d..edbc0804e 100644
--- a/src/tests/test_config_diff.py
+++ b/src/tests/test_config_diff.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_config_merge.py b/src/tests/test_config_merge.py
new file mode 100644
index 000000000..c9b4ad5c8
--- /dev/null
+++ b/src/tests/test_config_merge.py
@@ -0,0 +1,50 @@
+# Copyright 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 vyos.configtree
+
+from unittest import TestCase
+
+class TestConfigDiff(TestCase):
+ def setUp(self):
+ with open('tests/data/config.left', 'r') as f:
+ config_string = f.read()
+ self.config_left = vyos.configtree.ConfigTree(config_string)
+
+ with open('tests/data/config.right', 'r') as f:
+ config_string = f.read()
+ self.config_right = vyos.configtree.ConfigTree(config_string)
+
+ def test_merge_destructive(self):
+ res = vyos.configtree.merge(self.config_left, self.config_right,
+ destructive=True)
+ right_value = self.config_right.return_value(['node1', 'tag_node', 'foo', 'single'])
+ merge_value = res.return_value(['node1', 'tag_node', 'foo', 'single'])
+
+ # Check includes new value
+ self.assertEqual(right_value, merge_value)
+
+ # Check preserves non-confliciting paths
+ self.assertTrue(res.exists(['node3']))
+
+ def test_merge_non_destructive(self):
+ res = vyos.configtree.merge(self.config_left, self.config_right)
+ left_value = self.config_left.return_value(['node1', 'tag_node', 'foo', 'single'])
+ merge_value = res.return_value(['node1', 'tag_node', 'foo', 'single'])
+
+ # Check includes original value
+ self.assertEqual(left_value, merge_value)
+
+ # Check preserves non-confliciting paths
+ self.assertTrue(res.exists(['node3']))
diff --git a/src/tests/test_config_parser.py b/src/tests/test_config_parser.py
index 1b4a57311..823d5a7c1 100644
--- a/src/tests/test_config_parser.py
+++ b/src/tests/test_config_parser.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_configd_inspect.py b/src/tests/test_configd_inspect.py
index a0470221d..3363ab653 100644
--- a/src/tests/test_configd_inspect.py
+++ b/src/tests/test_configd_inspect.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_configverify.py b/src/tests/test_configverify.py
index f1ec65cd2..8f80365d7 100644
--- a/src/tests/test_configverify.py
+++ b/src/tests/test_configverify.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_dependency_graph.py b/src/tests/test_dependency_graph.py
index f3f1db376..12f50a1c4 100644
--- a/src/tests/test_dependency_graph.py
+++ b/src/tests/test_dependency_graph.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_dict_search.py b/src/tests/test_dict_search.py
index 6b4bc933a..ed147ec01 100644
--- a/src/tests/test_dict_search.py
+++ b/src/tests/test_dict_search.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_find_device_file.py b/src/tests/test_find_device_file.py
index 5b90f2034..02a33c224 100644
--- a/src/tests/test_find_device_file.py
+++ b/src/tests/test_find_device_file.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_initial_setup.py b/src/tests/test_initial_setup.py
index 7737f9df5..09feea7ba 100644
--- a/src/tests/test_initial_setup.py
+++ b/src/tests/test_initial_setup.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_op_mode.py b/src/tests/test_op_mode.py
index 23f709653..848a9666d 100644
--- a/src/tests/test_op_mode.py
+++ b/src/tests/test_op_mode.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_task_scheduler.py b/src/tests/test_task_scheduler.py
index 795ffeb9d..0d0319495 100644
--- a/src/tests/test_task_scheduler.py
+++ b/src/tests/test_task_scheduler.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_template.py b/src/tests/test_template.py
index 6377f6da5..e2548602d 100644
--- a/src/tests/test_template.py
+++ b/src/tests/test_template.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -190,3 +190,21 @@ class TestVyOSTemplate(TestCase):
for group_name, group_config in data['ike_group'].items():
ciphers = vyos.template.get_esp_ike_cipher(group_config)
self.assertIn(IKEv2_DEFAULT, ','.join(ciphers))
+
+ def test_get_default_port(self):
+ from vyos.defaults import config_files
+ from vyos.defaults import internal_ports
+
+ with self.assertRaises(RuntimeError):
+ vyos.template.get_default_config_file('UNKNOWN')
+ with self.assertRaises(RuntimeError):
+ vyos.template.get_default_port('UNKNOWN')
+ with self.assertRaises(RuntimeError):
+ vyos.template.nft_accept_invalid('UNKNOWN')
+
+ self.assertEqual(vyos.template.get_default_config_file('sshd_user_ca'),
+ config_files['sshd_user_ca'])
+ self.assertEqual(vyos.template.get_default_port('certbot_haproxy'),
+ internal_ports['certbot_haproxy'])
+ self.assertEqual(vyos.template.nft_accept_invalid('arp'),
+ 'ct state invalid ether type arp counter accept')
diff --git a/src/tests/test_utils.py b/src/tests/test_utils.py
index 7bfd2618e..5d642f4ea 100644
--- a/src/tests/test_utils.py
+++ b/src/tests/test_utils.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/tests/test_utils_network.py b/src/tests/test_utils_network.py
index d68dec16f..6d9a358c1 100644
--- a/src/tests/test_utils_network.py
+++ b/src/tests/test_utils_network.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright 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
@@ -43,3 +43,12 @@ class TestVyOSUtilsNetwork(TestCase):
self.assertFalse(vyos.utils.network.is_loopback_addr('::2'))
self.assertFalse(vyos.utils.network.is_loopback_addr('192.0.2.1'))
+
+ def test_check_port_availability(self):
+ self.assertTrue(vyos.utils.network.check_port_availability('::1', 8080))
+ self.assertTrue(vyos.utils.network.check_port_availability('127.0.0.1', 8080))
+ self.assertTrue(vyos.utils.network.check_port_availability(None, 8080, protocol='udp'))
+ # We do not have 192.0.2.1 configured on this system
+ self.assertFalse(vyos.utils.network.check_port_availability('192.0.2.1', 443))
+ # We do not have 2001:db8::1 configured on this system
+ self.assertFalse(vyos.utils.network.check_port_availability('2001:db8::1', 80, protocol='udp'))
diff --git a/src/utils/vyos-commands-to-config b/src/utils/vyos-commands-to-config
index 927d9bd70..54dd4e9fa 100755
--- a/src/utils/vyos-commands-to-config
+++ b/src/utils/vyos-commands-to-config
@@ -1,6 +1,6 @@
#! /usr/bin/python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/utils/vyos-config-file-query b/src/utils/vyos-config-file-query
index a10c7e9b3..2673fc487 100755
--- a/src/utils/vyos-config-file-query
+++ b/src/utils/vyos-config-file-query
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/utils/vyos-hostsd-client b/src/utils/vyos-hostsd-client
index a0515951a..937e657ff 100755
--- a/src/utils/vyos-hostsd-client
+++ b/src/utils/vyos-hostsd-client
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/utils/vyos-show-config b/src/utils/vyos-show-config
index 152322fc1..703b0ac9a 100755
--- a/src/utils/vyos-show-config
+++ b/src/utils/vyos-show-config
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/as-number-list b/src/validators/as-number-list
index 432d44180..1df40cc3a 100755
--- a/src/validators/as-number-list
+++ b/src/validators/as-number-list
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/base64 b/src/validators/base64
index a54168ef7..97d7a0398 100755
--- a/src/validators/base64
+++ b/src/validators/base64
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2025 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/bgp-extended-community b/src/validators/bgp-extended-community
index d66665519..561d41bca 100755
--- a/src/validators/bgp-extended-community
+++ b/src/validators/bgp-extended-community
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2019-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/validators/bgp-large-community b/src/validators/bgp-large-community
index 386398308..e322c653c 100755
--- a/src/validators/bgp-large-community
+++ b/src/validators/bgp-large-community
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/validators/bgp-large-community-list b/src/validators/bgp-large-community-list
index 9ba5b27eb..8e4326a9c 100755
--- a/src/validators/bgp-large-community-list
+++ b/src/validators/bgp-large-community-list
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright 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
@@ -17,18 +17,27 @@
import re
import sys
-pattern = '(.*):(.*):(.*)'
-allowedChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '*', '?', '^', '$', '(', ')', '[', ']', '{', '}', '|', '\\', ':', '-' }
+allowedChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '*', '?', '^', '$', '(', ')', '[', ']', '{', '}', '|', '\\', ':', '-', '_', ' ' }
if __name__ == '__main__':
if len(sys.argv) != 2:
sys.exit(1)
- value = sys.argv[1].split(':')
- if not len(value) == 3:
+ value = sys.argv[1]
+
+ # Require at least one well-formed large-community tuple in the pattern.
+ tmp = value.split(':')
+ if len(tmp) < 3:
+ sys.exit(1)
+
+ # Simple guard against invalid community & 1003.2 pattern chars
+ if not set(value).issubset(allowedChars):
sys.exit(1)
- if not (re.match(pattern, sys.argv[1]) and set(sys.argv[1]).issubset(allowedChars)):
+ # Don't feed FRR badly formed regex
+ try:
+ re.compile(value)
+ except re.error:
sys.exit(1)
sys.exit(0)
diff --git a/src/validators/bgp-rd-rt b/src/validators/bgp-rd-rt
index b2b69c9be..233f09696 100755
--- a/src/validators/bgp-rd-rt
+++ b/src/validators/bgp-rd-rt
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/bgp-regular-community b/src/validators/bgp-regular-community
index d43a71eae..0cc7f8fc3 100755
--- a/src/validators/bgp-regular-community
+++ b/src/validators/bgp-regular-community
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/src/validators/cpu b/src/validators/cpu
new file mode 100755
index 000000000..959a49248
--- /dev/null
+++ b/src/validators/cpu
@@ -0,0 +1,43 @@
+#!/usr/bin/python3
+
+import re
+import sys
+
+MAX_CPU = 511
+
+
+def validate_isolcpus(value):
+ pattern = re.compile(r'^(\d{1,3}(-\d{1,3})?)(,(\d{1,3}(-\d{1,3})?))*$')
+ if not pattern.fullmatch(value):
+ return False
+
+ flat_list = []
+ for part in value.split(','):
+ if '-' in part:
+ start, end = map(int, part.split('-'))
+ if start > end or start < 0 or end > MAX_CPU:
+ return False
+ flat_list.extend(range(start, end + 1))
+ else:
+ num = int(part)
+ if num < 0 or num > MAX_CPU:
+ return False
+ flat_list.append(num)
+
+ for i in range(1, len(flat_list)):
+ if flat_list[i] <= flat_list[i - 1]:
+ return False
+
+ return True
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ print("Usage: python3 cpu.py <cpu_list>")
+ sys.exit(1)
+
+ input_value = sys.argv[1]
+ if validate_isolcpus(input_value):
+ sys.exit(0)
+ else:
+ sys.exit(1)
diff --git a/src/validators/ddclient-protocol b/src/validators/ddclient-protocol
index ce5efbd52..0d28039d3 100755
--- a/src/validators/ddclient-protocol
+++ b/src/validators/ddclient-protocol
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/ether-type b/src/validators/ether-type
index 926db26d3..b3dc23b58 100644
--- a/src/validators/ether-type
+++ b/src/validators/ether-type
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/ip-protocol b/src/validators/ip-protocol
index c4c882502..b7467a7a0 100755
--- a/src/validators/ip-protocol
+++ b/src/validators/ip-protocol
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/psk-secret b/src/validators/psk-secret
index c91aa95a8..69d8b75c4 100644
--- a/src/validators/psk-secret
+++ b/src/validators/psk-secret
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/script b/src/validators/script
index eb176d23b..c3d39b347 100755
--- a/src/validators/script
+++ b/src/validators/script
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/sysctl b/src/validators/sysctl
index 9b5bba3e1..cc21186f5 100755
--- a/src/validators/sysctl
+++ b/src/validators/sysctl
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/timezone b/src/validators/timezone
index e55af8d2a..dd3e0654d 100755
--- a/src/validators/timezone
+++ b/src/validators/timezone
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2023 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/vrf-name b/src/validators/vrf-name
index 29167c635..cc4be2510 100755
--- a/src/validators/vrf-name
+++ b/src/validators/vrf-name
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright 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
diff --git a/src/validators/wireless-phy b/src/validators/wireless-phy
index 513a902de..3d0abbb54 100755
--- a/src/validators/wireless-phy
+++ b/src/validators/wireless-phy
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright 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