summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-05-02 17:25:47 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-05-06 16:18:03 +0300
commitfa54a080fac977157454beb0853daf0ac0e6af66 (patch)
tree82b112cde06437b80515450d63eb793bee198ec6
parent746195618941d8be8ed132f4b0be539763ec352d (diff)
downloadvyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.tar.gz
vyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.zip
feat(swap): import .md files and webp transition from myst/current
Selective import from origin/myst/current (cf9c9b34): - Add/update 255 .md files (full MyST conversion plus webp ref updates) - Delete 175 PNG/JPG from docs/_static/images (webp twins already present) - Delete 5 autotest topology.png (webp twins already present) Preserved on swap (untouched): - All .rst files (incremental swap pattern) - conf.py, _ext/, _include/*.txt, .gitignore - 115 canary md-*.md files - 7 superpowers/specs/*.md design docs - Logos vyos-logo.png / vyos-logo-icon.png (referenced by conf.py) 🤖 Generated by [robots](https://vyos.io)
-rw-r--r--docs/404.md13
-rw-r--r--docs/_static/images/1u_vyos_back.jpgbin586620 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front.jpgbin363840 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_10ge_open_1.jpgbin1853769 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_10ge_open_2.jpgbin2294504 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_10ge_open_3.jpgbin2067314 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_10ge_open_4.jpgbin2447196 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_open_1.jpgbin956435 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_open_2.jpgbin1225208 -> 0 bytes
-rw-r--r--docs/_static/images/1u_vyos_front_open_3.jpgbin1337822 -> 0 bytes
-rw-r--r--docs/_static/images/480px-Acrosser_ANDJ190N1_Back.jpgbin11340 -> 0 bytes
-rw-r--r--docs/_static/images/480px-Acrosser_ANDJ190N1_Front.jpgbin11138 -> 0 bytes
-rw-r--r--docs/_static/images/600px-Partaker-i5.jpgbin31015 -> 0 bytes
-rw-r--r--docs/_static/images/ESP_AH.pngbin35607 -> 0 bytes
-rw-r--r--docs/_static/images/IPSec_close_action_settings.pngbin22371 -> 0 bytes
-rw-r--r--docs/_static/images/L3VPN_hub_and_spoke.pngbin134458 -> 0 bytes
-rw-r--r--docs/_static/images/PA-ESP-group.pngbin27516 -> 0 bytes
-rw-r--r--docs/_static/images/PA-IKE-GW-1.pngbin31121 -> 0 bytes
-rw-r--r--docs/_static/images/PA-IKE-GW-2.pngbin19848 -> 0 bytes
-rw-r--r--docs/_static/images/PA-IKE-group.pngbin26998 -> 0 bytes
-rw-r--r--docs/_static/images/PA-IPsec-tunnel.pngbin33519 -> 0 bytes
-rw-r--r--docs/_static/images/PA-tunnel-1.pngbin16308 -> 0 bytes
-rw-r--r--docs/_static/images/PA-tunnel-2.pngbin18290 -> 0 bytes
-rw-r--r--docs/_static/images/PA-tunnel-3.pngbin15779 -> 0 bytes
-rw-r--r--docs/_static/images/VyOS_Dual-Hub_DMVPN.pngbin67747 -> 0 bytes
-rw-r--r--docs/_static/images/Wan_load_balancing1.pngbin373848 -> 0 bytes
-rw-r--r--docs/_static/images/Wan_load_balancing_exclude1.pngbin382563 -> 0 bytes
-rw-r--r--docs/_static/images/ansible.pngbin204124 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_desk_1.jpgbin816206 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_desk_2.jpgbin288989 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_desk_3.jpgbin831843 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_desk_4.jpgbin804070 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_1.jpgbin305789 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_2.jpgbin623490 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_3.jpgbin1113842 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_4.jpgbin1676612 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_5.jpgbin1584027 -> 0 bytes
-rw-r--r--docs/_static/images/apu4_rack_vyos_print.jpgbin569311 -> 0 bytes
-rw-r--r--docs/_static/images/aws.pngbin150759 -> 0 bytes
-rw-r--r--docs/_static/images/blueprint-dmvpn.pngbin29626 -> 0 bytes
-rw-r--r--docs/_static/images/boot-options.pngbin30582 -> 0 bytes
-rw-r--r--docs/_static/images/cisco-vpn-ipsec.pngbin38659 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-01.pngbin54783 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-02.pngbin88657 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-03.pngbin48191 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-04.pngbin131948 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-05.pngbin103661 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-06.pngbin111207 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-07.pngbin72764 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-aws-08.pngbin20893 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-01.pngbin90521 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-02.pngbin56507 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-03.pngbin47364 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-04.pngbin87475 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-05.pngbin77301 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-azure-06.pngbin57830 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-gcp-01.pngbin5526 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-gcp-02.pngbin46685 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-gcp-03.pngbin106217 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-gcp-04.pngbin19727 -> 0 bytes
-rw-r--r--docs/_static/images/cloud-gcp-05.pngbin26049 -> 0 bytes
-rw-r--r--docs/_static/images/dhcp-relay-through-gre-bridge.pngbin31261 -> 0 bytes
-rw-r--r--docs/_static/images/dual-hub-DMVPN.pngbin88497 -> 0 bytes
-rw-r--r--docs/_static/images/eve-ng-vyos.pngbin4228 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-and-vrf-blueprints.pngbin84270 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-bridge-forward.pngbin26359 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-bridge-input.pngbin39158 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-bridge-output.pngbin34496 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-flowtable-packet-flow.pngbin47883 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-fwd-packet-flow.pngbin30593 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-gral-packet-flow.pngbin49632 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-input-packet-flow.pngbin43944 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-netfilter.pngbin73608 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-traditional.pngbin53437 -> 0 bytes
-rw-r--r--docs/_static/images/firewall-zonebased.pngbin55621 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-01.pngbin28912 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-02.pngbin179730 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-03.pngbin22829 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-04.pngbin35150 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-05.pngbin31728 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-06.pngbin29168 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-07.pngbin31199 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-08.pngbin29636 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-09.pngbin21881 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-10.pngbin30788 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-11.pngbin168937 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-12.pngbin58597 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-13.pngbin56994 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-14.pngbin28821 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-15.pngbin45453 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-16.pngbin54790 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-17.pngbin169380 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-20.pngbin55168 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-21.pngbin25663 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-215.pngbin44485 -> 0 bytes
-rw-r--r--docs/_static/images/gns3-22.pngbin54674 -> 0 bytes
-rw-r--r--docs/_static/images/gowin-01.pngbin355723 -> 0 bytes
-rw-r--r--docs/_static/images/gowin-02.pngbin2613833 -> 0 bytes
-rw-r--r--docs/_static/images/gowin-03.pngbin2268530 -> 0 bytes
-rw-r--r--docs/_static/images/gowin-04.pngbin2165023 -> 0 bytes
-rw-r--r--docs/_static/images/inter-vrf-routing-vrf-lite.pngbin104622 -> 0 bytes
-rw-r--r--docs/_static/images/ipsec-vyos-pa.pngbin61250 -> 0 bytes
-rw-r--r--docs/_static/images/json.pngbin26585 -> 0 bytes
-rw-r--r--docs/_static/images/key.pngbin165894 -> 0 bytes
-rw-r--r--docs/_static/images/keypairs.pngbin49718 -> 0 bytes
-rw-r--r--docs/_static/images/lac-lns-diagram.jpgbin35665 -> 0 bytes
-rw-r--r--docs/_static/images/lac-lns-winclient.jpgbin90842 -> 0 bytes
-rw-r--r--docs/_static/images/ldapone.pngbin88753 -> 0 bytes
-rw-r--r--docs/_static/images/ldaptwo.pngbin58322 -> 0 bytes
-rw-r--r--docs/_static/images/mainschema.pngbin78790 -> 0 bytes
-rw-r--r--docs/_static/images/multicast-basic.pngbin43708 -> 0 bytes
-rw-r--r--docs/_static/images/nat_before_vpn_topology.pngbin19015 -> 0 bytes
-rw-r--r--docs/_static/images/nmp1.pngbin128546 -> 0 bytes
-rw-r--r--docs/_static/images/nmp2.pngbin52507 -> 0 bytes
-rw-r--r--docs/_static/images/nmp3.pngbin107595 -> 0 bytes
-rw-r--r--docs/_static/images/nmp4.pngbin72678 -> 0 bytes
-rw-r--r--docs/_static/images/nmp5.pngbin115299 -> 0 bytes
-rw-r--r--docs/_static/images/nmp6.pngbin130524 -> 0 bytes
-rw-r--r--docs/_static/images/nmp7.pngbin100135 -> 0 bytes
-rw-r--r--docs/_static/images/openvpn_site2site_diagram.jpgbin24179 -> 0 bytes
-rw-r--r--docs/_static/images/pbr_example_1.pngbin39170 -> 0 bytes
-rw-r--r--docs/_static/images/policy-based-ipsec-and-firewall.pngbin42987 -> 0 bytes
-rw-r--r--docs/_static/images/pppoe-ipv6-pd-diagram.jpgbin19993 -> 0 bytes
-rw-r--r--docs/_static/images/project.pngbin18173 -> 0 bytes
-rw-r--r--docs/_static/images/qos1.pngbin135527 -> 0 bytes
-rw-r--r--docs/_static/images/qos10.pngbin119669 -> 0 bytes
-rw-r--r--docs/_static/images/qos2.pngbin140834 -> 0 bytes
-rw-r--r--docs/_static/images/qos3.pngbin16699 -> 0 bytes
-rw-r--r--docs/_static/images/qos4.pngbin17273 -> 0 bytes
-rw-r--r--docs/_static/images/qos5.pngbin15868 -> 0 bytes
-rw-r--r--docs/_static/images/qos6.pngbin139244 -> 0 bytes
-rw-r--r--docs/_static/images/qos7.pngbin17775 -> 0 bytes
-rw-r--r--docs/_static/images/qos8.pngbin17368 -> 0 bytes
-rw-r--r--docs/_static/images/qos9.pngbin17065 -> 0 bytes
-rw-r--r--docs/_static/images/reset-password-step-1.jpgbin37351 -> 0 bytes
-rw-r--r--docs/_static/images/reset-password-step-2.jpgbin42278 -> 0 bytes
-rw-r--r--docs/_static/images/reset-password-step-3.jpgbin36932 -> 0 bytes
-rw-r--r--docs/_static/images/reset-password-step-4.jpgbin31564 -> 0 bytes
-rw-r--r--docs/_static/images/reset-password-step-5.jpgbin100973 -> 0 bytes
-rw-r--r--docs/_static/images/service.pngbin195145 -> 0 bytes
-rw-r--r--docs/_static/images/service_conntrack_sync-schema.pngbin56954 -> 0 bytes
-rw-r--r--docs/_static/images/service_dhcp-relay01.pngbin153617 -> 0 bytes
-rw-r--r--docs/_static/images/service_dhcpv6-relay01.pngbin150157 -> 0 bytes
-rw-r--r--docs/_static/images/service_snmp_communication_principles_diagram.pngbin56582 -> 0 bytes
-rw-r--r--docs/_static/images/sg.pngbin31817 -> 0 bytes
-rw-r--r--docs/_static/images/sticky-connections.jpgbin22252 -> 0 bytes
-rw-r--r--docs/_static/images/traffic.pngbin36786 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_01.pngbin60527 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_02.pngbin14091 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_03.pngbin14760 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_04.pngbin7349 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_05.pngbin6636 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_06.pngbin7102 -> 0 bytes
-rw-r--r--docs/_static/images/uefi_secureboot_07.pngbin12622 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-01.pngbin33227 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-02.pngbin30981 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-03.pngbin24547 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-04.pngbin28896 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-05.pngbin38080 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-06.pngbin28784 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-qc-01.pngbin33468 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-qc-02.pngbin26749 -> 0 bytes
-rw-r--r--docs/_static/images/virt-libvirt-qc-03.pngbin28278 -> 0 bytes
-rw-r--r--docs/_static/images/vpn_dmvpn_topology01.pngbin94382 -> 0 bytes
-rw-r--r--docs/_static/images/vpn_s2s_ikev2.pngbin66279 -> 0 bytes
-rw-r--r--docs/_static/images/vpn_s2s_ikev2_c.pngbin69496 -> 0 bytes
-rw-r--r--docs/_static/images/vrf-example-topology-01.pngbin32567 -> 0 bytes
-rw-r--r--docs/_static/images/vyos-downloads.pngbin65202 -> 0 bytes
-rw-r--r--docs/_static/images/vyos-sr-isis.pngbin45339 -> 0 bytes
-rw-r--r--docs/_static/images/vyos_1_4_nat66_simple.pngbin21021 -> 0 bytes
-rw-r--r--docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.pngbin349078 -> 0 bytes
-rw-r--r--docs/_static/images/vyos_arista_bond_lacp.pngbin40622 -> 0 bytes
-rw-r--r--docs/_static/images/vyosnew-downloads.pngbin64419 -> 0 bytes
-rw-r--r--docs/_static/images/wireguard_qrcode.jpgbin133939 -> 0 bytes
-rw-r--r--docs/_static/images/wireguard_site2site_diagram.jpgbin19987 -> 0 bytes
-rw-r--r--docs/_static/images/zone-policy-diagram.pngbin113618 -> 0 bytes
-rw-r--r--docs/automation/cloud-init.md380
-rw-r--r--docs/automation/command-scripting.md225
-rw-r--r--docs/automation/index.md16
-rw-r--r--docs/automation/terraform/index.md29
-rw-r--r--docs/automation/terraform/terraformAWS.md551
-rw-r--r--docs/automation/terraform/terraformAZ.md500
-rw-r--r--docs/automation/terraform/terraformGoogle.md703
-rw-r--r--docs/automation/terraform/terraformvSphere.md389
-rw-r--r--docs/automation/terraform/terraformvyos.md44
-rw-r--r--docs/automation/vyos-ansible.md101
-rw-r--r--docs/automation/vyos-api.md587
-rw-r--r--docs/automation/vyos-govyos.md199
-rw-r--r--docs/automation/vyos-napalm.md154
-rw-r--r--docs/automation/vyos-netmiko.md76
-rw-r--r--docs/automation/vyos-pyvyos.md151
-rw-r--r--docs/automation/vyos-salt.md211
-rw-r--r--docs/cli.md868
-rw-r--r--docs/configexamples/ansible.md212
-rw-r--r--docs/configexamples/autotest/DHCPRelay_through_GRE/DHCPRelay_through_GRE.md89
-rw-r--r--docs/configexamples/autotest/DHCPRelay_through_GRE/_include/topology.pngbin57080 -> 0 bytes
-rw-r--r--docs/configexamples/autotest/L3VPN_EVPN/L3VPN_EVPN.md246
-rw-r--r--docs/configexamples/autotest/L3VPN_EVPN/_include/topology.pngbin102832 -> 0 bytes
-rw-r--r--docs/configexamples/autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP.md287
-rw-r--r--docs/configexamples/autotest/OpenVPN_with_LDAP/_include/topology.pngbin40891 -> 0 bytes
-rw-r--r--docs/configexamples/autotest/Wireguard/Wireguard.md108
-rw-r--r--docs/configexamples/autotest/Wireguard/_include/topology.pngbin158227 -> 0 bytes
-rw-r--r--docs/configexamples/autotest/tunnelbroker/_include/topology.pngbin34614 -> 0 bytes
-rw-r--r--docs/configexamples/autotest/tunnelbroker/tunnelbroker.md206
-rw-r--r--docs/configexamples/azure-vpn-bgp.md134
-rw-r--r--docs/configexamples/azure-vpn-dual-bgp.md160
-rw-r--r--docs/configexamples/bgp-ipv6-unnumbered.md174
-rw-r--r--docs/configexamples/dmvpn-dualhub-dualcloud.md552
-rw-r--r--docs/configexamples/firewall.md16
-rw-r--r--docs/configexamples/fwall-and-bridge.md490
-rw-r--r--docs/configexamples/fwall-and-vrf.md121
-rw-r--r--docs/configexamples/ha.md556
-rw-r--r--docs/configexamples/index.md60
-rw-r--r--docs/configexamples/inter-vrf-routing-vrf-lite.md797
-rw-r--r--docs/configexamples/ipsec-cisco-policy-based.md363
-rw-r--r--docs/configexamples/ipsec-cisco-route-based.md406
-rw-r--r--docs/configexamples/ipsec-pa-route-based.md412
-rw-r--r--docs/configexamples/l3vpn-hub-and-spoke.md1091
-rw-r--r--docs/configexamples/lac-lns.md177
-rw-r--r--docs/configexamples/nmp.md72
-rw-r--r--docs/configexamples/ospf-unnumbered.md118
-rw-r--r--docs/configexamples/policy-based-ipsec-and-firewall.md269
-rw-r--r--docs/configexamples/pppoe-ipv6-basic.md114
-rw-r--r--docs/configexamples/qos.md201
-rw-r--r--docs/configexamples/segment-routing-isis.md277
-rw-r--r--docs/configexamples/site-2-site-cisco.md170
-rw-r--r--docs/configexamples/wan-load-balancing.md179
-rw-r--r--docs/configexamples/zone-policy.md416
-rw-r--r--docs/configuration/container/index.md479
-rw-r--r--docs/configuration/firewall/bridge.md685
-rw-r--r--docs/configuration/firewall/flowtables.md176
-rw-r--r--docs/configuration/firewall/global-options.md186
-rw-r--r--docs/configuration/firewall/groups.md477
-rw-r--r--docs/configuration/firewall/index.md278
-rw-r--r--docs/configuration/firewall/ipv4.md1544
-rw-r--r--docs/configuration/firewall/ipv6.md1567
-rw-r--r--docs/configuration/firewall/zone.md201
-rw-r--r--docs/configuration/highavailability/index.md561
-rw-r--r--docs/configuration/index.md23
-rw-r--r--docs/configuration/interfaces/bonding.md764
-rw-r--r--docs/configuration/interfaces/bridge.md431
-rw-r--r--docs/configuration/interfaces/dummy.md87
-rw-r--r--docs/configuration/interfaces/ethernet.md515
-rw-r--r--docs/configuration/interfaces/geneve.md105
-rw-r--r--docs/configuration/interfaces/index.md26
-rw-r--r--docs/configuration/interfaces/l2tpv3.md170
-rw-r--r--docs/configuration/interfaces/loopback.md67
-rw-r--r--docs/configuration/interfaces/macsec.md319
-rw-r--r--docs/configuration/interfaces/openvpn-examples.md769
-rw-r--r--docs/configuration/interfaces/openvpn.md614
-rw-r--r--docs/configuration/interfaces/pppoe.md419
-rw-r--r--docs/configuration/interfaces/pseudo-ethernet.md52
-rw-r--r--docs/configuration/interfaces/sstp-client.md170
-rw-r--r--docs/configuration/interfaces/tunnel.md309
-rw-r--r--docs/configuration/interfaces/virtual-ethernet.md119
-rw-r--r--docs/configuration/interfaces/vti.md121
-rw-r--r--docs/configuration/interfaces/vxlan.md373
-rw-r--r--docs/configuration/interfaces/wireguard.md434
-rw-r--r--docs/configuration/interfaces/wireless.md923
-rw-r--r--docs/configuration/interfaces/wwan.md355
-rw-r--r--docs/configuration/loadbalancing/haproxy.md510
-rw-r--r--docs/configuration/loadbalancing/index.md15
-rw-r--r--docs/configuration/loadbalancing/wan.md306
-rw-r--r--docs/configuration/nat/cgnat.md200
-rw-r--r--docs/configuration/nat/index.md13
-rw-r--r--docs/configuration/nat/nat44.md788
-rw-r--r--docs/configuration/nat/nat64.md73
-rw-r--r--docs/configuration/nat/nat66.md243
-rw-r--r--docs/configuration/pki/index.md583
-rw-r--r--docs/configuration/policy/access-list.md70
-rw-r--r--docs/configuration/policy/as-path-list.md29
-rw-r--r--docs/configuration/policy/community-list.md29
-rw-r--r--docs/configuration/policy/examples.md205
-rw-r--r--docs/configuration/policy/extcommunity-list.md33
-rw-r--r--docs/configuration/policy/index.md53
-rw-r--r--docs/configuration/policy/large-community-list.md29
-rw-r--r--docs/configuration/policy/local-route.md100
-rw-r--r--docs/configuration/policy/prefix-list.md152
-rw-r--r--docs/configuration/policy/route-map.md439
-rw-r--r--docs/configuration/policy/route.md424
-rw-r--r--docs/configuration/protocols/arp.md72
-rw-r--r--docs/configuration/protocols/babel.md296
-rw-r--r--docs/configuration/protocols/bfd.md205
-rw-r--r--docs/configuration/protocols/bgp.md1414
-rw-r--r--docs/configuration/protocols/failover.md237
-rw-r--r--docs/configuration/protocols/igmp-proxy.md79
-rw-r--r--docs/configuration/protocols/index.md25
-rw-r--r--docs/configuration/protocols/isis.md746
-rw-r--r--docs/configuration/protocols/mpls.md285
-rw-r--r--docs/configuration/protocols/multicast.md31
-rw-r--r--docs/configuration/protocols/openfabric.md242
-rw-r--r--docs/configuration/protocols/ospf.md1504
-rw-r--r--docs/configuration/protocols/pim.md282
-rw-r--r--docs/configuration/protocols/pim6.md100
-rw-r--r--docs/configuration/protocols/rip.md294
-rw-r--r--docs/configuration/protocols/rpki.md210
-rw-r--r--docs/configuration/protocols/segment-routing.md359
-rw-r--r--docs/configuration/protocols/static.md298
-rw-r--r--docs/configuration/protocols/traffic-engineering.md54
-rw-r--r--docs/configuration/service/broadcast-relay.md70
-rw-r--r--docs/configuration/service/config-sync.md164
-rw-r--r--docs/configuration/service/conntrack-sync.md321
-rw-r--r--docs/configuration/service/console-server.md139
-rw-r--r--docs/configuration/service/dhcp-relay.md205
-rw-r--r--docs/configuration/service/dhcp-server.md1178
-rw-r--r--docs/configuration/service/dns.md582
-rw-r--r--docs/configuration/service/eventhandler.md130
-rw-r--r--docs/configuration/service/https.md138
-rw-r--r--docs/configuration/service/index.md29
-rw-r--r--docs/configuration/service/ipoe-server.md512
-rw-r--r--docs/configuration/service/lldp.md154
-rw-r--r--docs/configuration/service/mdns.md131
-rw-r--r--docs/configuration/service/monitoring.md334
-rw-r--r--docs/configuration/service/ntp.md202
-rw-r--r--docs/configuration/service/pppoe-server.md753
-rw-r--r--docs/configuration/service/router-advert.md121
-rw-r--r--docs/configuration/service/salt-minion.md51
-rw-r--r--docs/configuration/service/snmp.md258
-rw-r--r--docs/configuration/service/ssh.md366
-rw-r--r--docs/configuration/service/suricata.md93
-rw-r--r--docs/configuration/service/tftp-server.md78
-rw-r--r--docs/configuration/service/webproxy.md459
-rw-r--r--docs/configuration/system/acceleration.md158
-rw-r--r--docs/configuration/system/conntrack.md218
-rw-r--r--docs/configuration/system/console.md59
-rw-r--r--docs/configuration/system/default-route.md40
-rw-r--r--docs/configuration/system/flow-accounting.md209
-rw-r--r--docs/configuration/system/frr.md45
-rw-r--r--docs/configuration/system/host-name.md70
-rw-r--r--docs/configuration/system/index.md34
-rw-r--r--docs/configuration/system/ip.md126
-rw-r--r--docs/configuration/system/ipv6.md193
-rw-r--r--docs/configuration/system/lcd.md41
-rw-r--r--docs/configuration/system/login.md604
-rw-r--r--docs/configuration/system/name-server.md65
-rw-r--r--docs/configuration/system/option.md190
-rw-r--r--docs/configuration/system/proxy.md27
-rw-r--r--docs/configuration/system/sflow.md66
-rw-r--r--docs/configuration/system/sysctl.md16
-rw-r--r--docs/configuration/system/syslog.md450
-rw-r--r--docs/configuration/system/task-scheduler.md45
-rw-r--r--docs/configuration/system/time-zone.md17
-rw-r--r--docs/configuration/system/updates.md36
-rw-r--r--docs/configuration/system/watchdog.md212
-rw-r--r--docs/configuration/trafficpolicy/index.md1299
-rw-r--r--docs/configuration/vpn/dmvpn.md431
-rw-r--r--docs/configuration/vpn/index.md14
-rw-r--r--docs/configuration/vpn/ipsec/index.md11
-rw-r--r--docs/configuration/vpn/ipsec/ipsec_general.md407
-rw-r--r--docs/configuration/vpn/ipsec/remoteaccess_ipsec.md186
-rw-r--r--docs/configuration/vpn/ipsec/site2site_ipsec.md780
-rw-r--r--docs/configuration/vpn/ipsec/troubleshooting_ipsec.md313
-rw-r--r--docs/configuration/vpn/l2tp.md624
-rw-r--r--docs/configuration/vpn/openconnect.md330
-rw-r--r--docs/configuration/vpn/pptp.md594
-rw-r--r--docs/configuration/vpn/rsa-keys.md114
-rw-r--r--docs/configuration/vpn/sstp.md698
-rw-r--r--docs/configuration/vrf/index.md646
-rw-r--r--docs/contributing/build-vyos.md730
-rw-r--r--docs/contributing/cla.md45
-rw-r--r--docs/contributing/debugging.md204
-rw-r--r--docs/contributing/development.md549
-rw-r--r--docs/contributing/index.md13
-rw-r--r--docs/contributing/issues-features.md122
-rw-r--r--docs/contributing/testing.md207
-rw-r--r--docs/contributing/upstream-packages.md147
-rw-r--r--docs/coverage.md59
-rw-r--r--docs/documentation.md442
-rw-r--r--docs/index.md113
-rw-r--r--docs/installation/bare-metal.md626
-rw-r--r--docs/installation/cloud/aws.md188
-rw-r--r--docs/installation/cloud/azure.md98
-rw-r--r--docs/installation/cloud/gcp.md61
-rw-r--r--docs/installation/cloud/index.md10
-rw-r--r--docs/installation/cloud/oracle.md17
-rw-r--r--docs/installation/image.md113
-rw-r--r--docs/installation/index.md30
-rw-r--r--docs/installation/install.md466
-rw-r--r--docs/installation/secure-boot.md194
-rw-r--r--docs/installation/update.md105
-rw-r--r--docs/installation/virtual/docker.md72
-rw-r--r--docs/installation/virtual/eve-ng.md14
-rw-r--r--docs/installation/virtual/gns3.md191
-rw-r--r--docs/installation/virtual/index.md16
-rw-r--r--docs/installation/virtual/libvirt.md186
-rw-r--r--docs/installation/virtual/proxmox.md80
-rw-r--r--docs/installation/virtual/vmware.md38
-rw-r--r--docs/introducing/about.md21
-rw-r--r--docs/introducing/history.md171
-rw-r--r--docs/operation/boot-options.md55
-rw-r--r--docs/operation/index.md12
-rw-r--r--docs/operation/information.md106
-rw-r--r--docs/operation/password-recovery.md46
-rw-r--r--docs/operation/raid.md236
-rw-r--r--docs/operation/upgrade-recovery.md70
-rw-r--r--docs/quick-start.md381
-rw-r--r--docs/troubleshooting/connectivity.md147
-rw-r--r--docs/troubleshooting/index.md17
-rw-r--r--docs/troubleshooting/interfaces.md36
-rw-r--r--docs/troubleshooting/monitoring.md152
-rw-r--r--docs/troubleshooting/system.md48
-rw-r--r--docs/troubleshooting/terminal.md39
-rw-r--r--docs/vpp/configuration/acl.md582
-rw-r--r--docs/vpp/configuration/dataplane/buffers.md102
-rw-r--r--docs/vpp/configuration/dataplane/cpu.md71
-rw-r--r--docs/vpp/configuration/dataplane/index.md36
-rw-r--r--docs/vpp/configuration/dataplane/interface.md104
-rw-r--r--docs/vpp/configuration/dataplane/ipsec.md74
-rw-r--r--docs/vpp/configuration/dataplane/ipv6.md46
-rw-r--r--docs/vpp/configuration/dataplane/l2learn.md35
-rw-r--r--docs/vpp/configuration/dataplane/lcp.md46
-rw-r--r--docs/vpp/configuration/dataplane/logging.md59
-rw-r--r--docs/vpp/configuration/dataplane/memory.md142
-rw-r--r--docs/vpp/configuration/dataplane/system.md212
-rw-r--r--docs/vpp/configuration/dataplane/unix.md57
-rw-r--r--docs/vpp/configuration/index.md47
-rw-r--r--docs/vpp/configuration/interfaces/bonding.md255
-rw-r--r--docs/vpp/configuration/interfaces/bridge.md194
-rw-r--r--docs/vpp/configuration/interfaces/gre.md168
-rw-r--r--docs/vpp/configuration/interfaces/index.md49
-rw-r--r--docs/vpp/configuration/interfaces/ipip.md119
-rw-r--r--docs/vpp/configuration/interfaces/loopback.md148
-rw-r--r--docs/vpp/configuration/interfaces/vxlan.md157
-rw-r--r--docs/vpp/configuration/interfaces/xconnect.md108
-rw-r--r--docs/vpp/configuration/ipfix.md50
-rw-r--r--docs/vpp/configuration/ipsec.md188
-rw-r--r--docs/vpp/configuration/nat/cgnat.md249
-rw-r--r--docs/vpp/configuration/nat/index.md42
-rw-r--r--docs/vpp/configuration/nat/nat44.md755
-rw-r--r--docs/vpp/configuration/sflow.md45
-rw-r--r--docs/vpp/description.md87
-rw-r--r--docs/vpp/index.md25
-rw-r--r--docs/vpp/limitations.md42
-rw-r--r--docs/vpp/requirements.md131
-rw-r--r--docs/vpp/troubleshooting.md474
435 files changed, 65424 insertions, 0 deletions
diff --git a/docs/404.md b/docs/404.md
new file mode 100644
index 00000000..f5530747
--- /dev/null
+++ b/docs/404.md
@@ -0,0 +1,13 @@
+---
+orphan: true
+---
+
+# Page Not Found
+
+Sorry, we could not find a page.
+Try using the search box or go to the release homepage:
+
+- [1.2.x (crux)](https://docs.vyos.io/en/crux/)
+- [1.3.x (equuleus)](https://docs.vyos.io/en/equuleus/)
+- [1.4.x (sagitta)](https://docs.vyos.io/en/sagitta/)
+- [rolling release (circinus)](https://docs.vyos.io/en/latest/)
diff --git a/docs/_static/images/1u_vyos_back.jpg b/docs/_static/images/1u_vyos_back.jpg
deleted file mode 100644
index cd00c11c..00000000
--- a/docs/_static/images/1u_vyos_back.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front.jpg b/docs/_static/images/1u_vyos_front.jpg
deleted file mode 100644
index 3d135d56..00000000
--- a/docs/_static/images/1u_vyos_front.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_10ge_open_1.jpg b/docs/_static/images/1u_vyos_front_10ge_open_1.jpg
deleted file mode 100644
index edfba5a3..00000000
--- a/docs/_static/images/1u_vyos_front_10ge_open_1.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_10ge_open_2.jpg b/docs/_static/images/1u_vyos_front_10ge_open_2.jpg
deleted file mode 100644
index 4f48a116..00000000
--- a/docs/_static/images/1u_vyos_front_10ge_open_2.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_10ge_open_3.jpg b/docs/_static/images/1u_vyos_front_10ge_open_3.jpg
deleted file mode 100644
index c102b903..00000000
--- a/docs/_static/images/1u_vyos_front_10ge_open_3.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_10ge_open_4.jpg b/docs/_static/images/1u_vyos_front_10ge_open_4.jpg
deleted file mode 100644
index 2f270b7e..00000000
--- a/docs/_static/images/1u_vyos_front_10ge_open_4.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_open_1.jpg b/docs/_static/images/1u_vyos_front_open_1.jpg
deleted file mode 100644
index d90d565e..00000000
--- a/docs/_static/images/1u_vyos_front_open_1.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_open_2.jpg b/docs/_static/images/1u_vyos_front_open_2.jpg
deleted file mode 100644
index 6d112463..00000000
--- a/docs/_static/images/1u_vyos_front_open_2.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/1u_vyos_front_open_3.jpg b/docs/_static/images/1u_vyos_front_open_3.jpg
deleted file mode 100644
index 198ba3ce..00000000
--- a/docs/_static/images/1u_vyos_front_open_3.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/480px-Acrosser_ANDJ190N1_Back.jpg b/docs/_static/images/480px-Acrosser_ANDJ190N1_Back.jpg
deleted file mode 100644
index 6441c54a..00000000
--- a/docs/_static/images/480px-Acrosser_ANDJ190N1_Back.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/480px-Acrosser_ANDJ190N1_Front.jpg b/docs/_static/images/480px-Acrosser_ANDJ190N1_Front.jpg
deleted file mode 100644
index 5f216aa1..00000000
--- a/docs/_static/images/480px-Acrosser_ANDJ190N1_Front.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/600px-Partaker-i5.jpg b/docs/_static/images/600px-Partaker-i5.jpg
deleted file mode 100644
index 68196d41..00000000
--- a/docs/_static/images/600px-Partaker-i5.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/ESP_AH.png b/docs/_static/images/ESP_AH.png
deleted file mode 100644
index 6075c3f4..00000000
--- a/docs/_static/images/ESP_AH.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/IPSec_close_action_settings.png b/docs/_static/images/IPSec_close_action_settings.png
deleted file mode 100644
index 531643f7..00000000
--- a/docs/_static/images/IPSec_close_action_settings.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/L3VPN_hub_and_spoke.png b/docs/_static/images/L3VPN_hub_and_spoke.png
deleted file mode 100644
index d442cc1a..00000000
--- a/docs/_static/images/L3VPN_hub_and_spoke.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-ESP-group.png b/docs/_static/images/PA-ESP-group.png
deleted file mode 100644
index c6411b66..00000000
--- a/docs/_static/images/PA-ESP-group.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-IKE-GW-1.png b/docs/_static/images/PA-IKE-GW-1.png
deleted file mode 100644
index 863eeb3a..00000000
--- a/docs/_static/images/PA-IKE-GW-1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-IKE-GW-2.png b/docs/_static/images/PA-IKE-GW-2.png
deleted file mode 100644
index 21a16055..00000000
--- a/docs/_static/images/PA-IKE-GW-2.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-IKE-group.png b/docs/_static/images/PA-IKE-group.png
deleted file mode 100644
index 06fd535d..00000000
--- a/docs/_static/images/PA-IKE-group.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-IPsec-tunnel.png b/docs/_static/images/PA-IPsec-tunnel.png
deleted file mode 100644
index 2f8f4cb8..00000000
--- a/docs/_static/images/PA-IPsec-tunnel.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-tunnel-1.png b/docs/_static/images/PA-tunnel-1.png
deleted file mode 100644
index 3c99c6c7..00000000
--- a/docs/_static/images/PA-tunnel-1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-tunnel-2.png b/docs/_static/images/PA-tunnel-2.png
deleted file mode 100644
index 6f073513..00000000
--- a/docs/_static/images/PA-tunnel-2.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/PA-tunnel-3.png b/docs/_static/images/PA-tunnel-3.png
deleted file mode 100644
index ca5a94e9..00000000
--- a/docs/_static/images/PA-tunnel-3.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/VyOS_Dual-Hub_DMVPN.png b/docs/_static/images/VyOS_Dual-Hub_DMVPN.png
deleted file mode 100644
index 9c25a308..00000000
--- a/docs/_static/images/VyOS_Dual-Hub_DMVPN.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/Wan_load_balancing1.png b/docs/_static/images/Wan_load_balancing1.png
deleted file mode 100644
index bde1edb6..00000000
--- a/docs/_static/images/Wan_load_balancing1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/Wan_load_balancing_exclude1.png b/docs/_static/images/Wan_load_balancing_exclude1.png
deleted file mode 100644
index 1111535d..00000000
--- a/docs/_static/images/Wan_load_balancing_exclude1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/ansible.png b/docs/_static/images/ansible.png
deleted file mode 100644
index 1d80b3f4..00000000
--- a/docs/_static/images/ansible.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_desk_1.jpg b/docs/_static/images/apu4_desk_1.jpg
deleted file mode 100644
index b7a3d08e..00000000
--- a/docs/_static/images/apu4_desk_1.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_desk_2.jpg b/docs/_static/images/apu4_desk_2.jpg
deleted file mode 100644
index fe356e1f..00000000
--- a/docs/_static/images/apu4_desk_2.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_desk_3.jpg b/docs/_static/images/apu4_desk_3.jpg
deleted file mode 100644
index af7dc406..00000000
--- a/docs/_static/images/apu4_desk_3.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_desk_4.jpg b/docs/_static/images/apu4_desk_4.jpg
deleted file mode 100644
index 37251af2..00000000
--- a/docs/_static/images/apu4_desk_4.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_1.jpg b/docs/_static/images/apu4_rack_1.jpg
deleted file mode 100644
index 3793cd39..00000000
--- a/docs/_static/images/apu4_rack_1.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_2.jpg b/docs/_static/images/apu4_rack_2.jpg
deleted file mode 100644
index b8caf976..00000000
--- a/docs/_static/images/apu4_rack_2.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_3.jpg b/docs/_static/images/apu4_rack_3.jpg
deleted file mode 100644
index 08ff633e..00000000
--- a/docs/_static/images/apu4_rack_3.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_4.jpg b/docs/_static/images/apu4_rack_4.jpg
deleted file mode 100644
index a88d62fe..00000000
--- a/docs/_static/images/apu4_rack_4.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_5.jpg b/docs/_static/images/apu4_rack_5.jpg
deleted file mode 100644
index 644b8e0a..00000000
--- a/docs/_static/images/apu4_rack_5.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/apu4_rack_vyos_print.jpg b/docs/_static/images/apu4_rack_vyos_print.jpg
deleted file mode 100644
index a0bbaab2..00000000
--- a/docs/_static/images/apu4_rack_vyos_print.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/aws.png b/docs/_static/images/aws.png
deleted file mode 100644
index c1c111bb..00000000
--- a/docs/_static/images/aws.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/blueprint-dmvpn.png b/docs/_static/images/blueprint-dmvpn.png
deleted file mode 100644
index 85f189c1..00000000
--- a/docs/_static/images/blueprint-dmvpn.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/boot-options.png b/docs/_static/images/boot-options.png
deleted file mode 100644
index b00350bc..00000000
--- a/docs/_static/images/boot-options.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cisco-vpn-ipsec.png b/docs/_static/images/cisco-vpn-ipsec.png
deleted file mode 100644
index bc19e8bc..00000000
--- a/docs/_static/images/cisco-vpn-ipsec.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-01.png b/docs/_static/images/cloud-aws-01.png
deleted file mode 100644
index cda6542f..00000000
--- a/docs/_static/images/cloud-aws-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-02.png b/docs/_static/images/cloud-aws-02.png
deleted file mode 100644
index 639d42fa..00000000
--- a/docs/_static/images/cloud-aws-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-03.png b/docs/_static/images/cloud-aws-03.png
deleted file mode 100644
index 92d3e63b..00000000
--- a/docs/_static/images/cloud-aws-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-04.png b/docs/_static/images/cloud-aws-04.png
deleted file mode 100644
index 3ae4fb2a..00000000
--- a/docs/_static/images/cloud-aws-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-05.png b/docs/_static/images/cloud-aws-05.png
deleted file mode 100644
index fa3521a6..00000000
--- a/docs/_static/images/cloud-aws-05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-06.png b/docs/_static/images/cloud-aws-06.png
deleted file mode 100644
index c8f88ded..00000000
--- a/docs/_static/images/cloud-aws-06.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-07.png b/docs/_static/images/cloud-aws-07.png
deleted file mode 100644
index d9f934ac..00000000
--- a/docs/_static/images/cloud-aws-07.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-aws-08.png b/docs/_static/images/cloud-aws-08.png
deleted file mode 100644
index db3030a0..00000000
--- a/docs/_static/images/cloud-aws-08.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-01.png b/docs/_static/images/cloud-azure-01.png
deleted file mode 100644
index 2c7b1adb..00000000
--- a/docs/_static/images/cloud-azure-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-02.png b/docs/_static/images/cloud-azure-02.png
deleted file mode 100644
index 286b8689..00000000
--- a/docs/_static/images/cloud-azure-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-03.png b/docs/_static/images/cloud-azure-03.png
deleted file mode 100644
index 4661a1fb..00000000
--- a/docs/_static/images/cloud-azure-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-04.png b/docs/_static/images/cloud-azure-04.png
deleted file mode 100644
index af12d337..00000000
--- a/docs/_static/images/cloud-azure-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-05.png b/docs/_static/images/cloud-azure-05.png
deleted file mode 100644
index c5a32d2e..00000000
--- a/docs/_static/images/cloud-azure-05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-azure-06.png b/docs/_static/images/cloud-azure-06.png
deleted file mode 100644
index 1cc7cbf1..00000000
--- a/docs/_static/images/cloud-azure-06.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-gcp-01.png b/docs/_static/images/cloud-gcp-01.png
deleted file mode 100644
index f7681d6e..00000000
--- a/docs/_static/images/cloud-gcp-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-gcp-02.png b/docs/_static/images/cloud-gcp-02.png
deleted file mode 100644
index 5a17efb4..00000000
--- a/docs/_static/images/cloud-gcp-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-gcp-03.png b/docs/_static/images/cloud-gcp-03.png
deleted file mode 100644
index 9881a5a3..00000000
--- a/docs/_static/images/cloud-gcp-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-gcp-04.png b/docs/_static/images/cloud-gcp-04.png
deleted file mode 100644
index 61ee2d5e..00000000
--- a/docs/_static/images/cloud-gcp-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/cloud-gcp-05.png b/docs/_static/images/cloud-gcp-05.png
deleted file mode 100644
index acaafc59..00000000
--- a/docs/_static/images/cloud-gcp-05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/dhcp-relay-through-gre-bridge.png b/docs/_static/images/dhcp-relay-through-gre-bridge.png
deleted file mode 100644
index 1f3e7744..00000000
--- a/docs/_static/images/dhcp-relay-through-gre-bridge.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/dual-hub-DMVPN.png b/docs/_static/images/dual-hub-DMVPN.png
deleted file mode 100644
index 51ba9c14..00000000
--- a/docs/_static/images/dual-hub-DMVPN.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/eve-ng-vyos.png b/docs/_static/images/eve-ng-vyos.png
deleted file mode 100644
index fdd196a7..00000000
--- a/docs/_static/images/eve-ng-vyos.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-and-vrf-blueprints.png b/docs/_static/images/firewall-and-vrf-blueprints.png
deleted file mode 100644
index 8c3bf9f2..00000000
--- a/docs/_static/images/firewall-and-vrf-blueprints.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-bridge-forward.png b/docs/_static/images/firewall-bridge-forward.png
deleted file mode 100644
index 1294349b..00000000
--- a/docs/_static/images/firewall-bridge-forward.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-bridge-input.png b/docs/_static/images/firewall-bridge-input.png
deleted file mode 100644
index 20a46b2e..00000000
--- a/docs/_static/images/firewall-bridge-input.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-bridge-output.png b/docs/_static/images/firewall-bridge-output.png
deleted file mode 100644
index ab2fd3d7..00000000
--- a/docs/_static/images/firewall-bridge-output.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-flowtable-packet-flow.png b/docs/_static/images/firewall-flowtable-packet-flow.png
deleted file mode 100644
index fca7e13a..00000000
--- a/docs/_static/images/firewall-flowtable-packet-flow.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-fwd-packet-flow.png b/docs/_static/images/firewall-fwd-packet-flow.png
deleted file mode 100644
index 1ca213e8..00000000
--- a/docs/_static/images/firewall-fwd-packet-flow.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-gral-packet-flow.png b/docs/_static/images/firewall-gral-packet-flow.png
deleted file mode 100644
index 4fb5d516..00000000
--- a/docs/_static/images/firewall-gral-packet-flow.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-input-packet-flow.png b/docs/_static/images/firewall-input-packet-flow.png
deleted file mode 100644
index 20d356bd..00000000
--- a/docs/_static/images/firewall-input-packet-flow.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-netfilter.png b/docs/_static/images/firewall-netfilter.png
deleted file mode 100644
index dde3766b..00000000
--- a/docs/_static/images/firewall-netfilter.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-traditional.png b/docs/_static/images/firewall-traditional.png
deleted file mode 100644
index 7eb2b49d..00000000
--- a/docs/_static/images/firewall-traditional.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/firewall-zonebased.png b/docs/_static/images/firewall-zonebased.png
deleted file mode 100644
index 46b2f623..00000000
--- a/docs/_static/images/firewall-zonebased.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-01.png b/docs/_static/images/gns3-01.png
deleted file mode 100644
index a655d6aa..00000000
--- a/docs/_static/images/gns3-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-02.png b/docs/_static/images/gns3-02.png
deleted file mode 100644
index 3dffdd2b..00000000
--- a/docs/_static/images/gns3-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-03.png b/docs/_static/images/gns3-03.png
deleted file mode 100644
index fcab6c5d..00000000
--- a/docs/_static/images/gns3-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-04.png b/docs/_static/images/gns3-04.png
deleted file mode 100644
index afc30131..00000000
--- a/docs/_static/images/gns3-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-05.png b/docs/_static/images/gns3-05.png
deleted file mode 100644
index fee0dc65..00000000
--- a/docs/_static/images/gns3-05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-06.png b/docs/_static/images/gns3-06.png
deleted file mode 100644
index c03cd89f..00000000
--- a/docs/_static/images/gns3-06.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-07.png b/docs/_static/images/gns3-07.png
deleted file mode 100644
index 89d0a565..00000000
--- a/docs/_static/images/gns3-07.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-08.png b/docs/_static/images/gns3-08.png
deleted file mode 100644
index aca0ff8a..00000000
--- a/docs/_static/images/gns3-08.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-09.png b/docs/_static/images/gns3-09.png
deleted file mode 100644
index 7ae38c30..00000000
--- a/docs/_static/images/gns3-09.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-10.png b/docs/_static/images/gns3-10.png
deleted file mode 100644
index 1ee70d58..00000000
--- a/docs/_static/images/gns3-10.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-11.png b/docs/_static/images/gns3-11.png
deleted file mode 100644
index 7990c73a..00000000
--- a/docs/_static/images/gns3-11.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-12.png b/docs/_static/images/gns3-12.png
deleted file mode 100644
index 9ad51f70..00000000
--- a/docs/_static/images/gns3-12.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-13.png b/docs/_static/images/gns3-13.png
deleted file mode 100644
index 5f9dd783..00000000
--- a/docs/_static/images/gns3-13.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-14.png b/docs/_static/images/gns3-14.png
deleted file mode 100644
index 447fcafe..00000000
--- a/docs/_static/images/gns3-14.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-15.png b/docs/_static/images/gns3-15.png
deleted file mode 100644
index 956b9edb..00000000
--- a/docs/_static/images/gns3-15.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-16.png b/docs/_static/images/gns3-16.png
deleted file mode 100644
index 4f75ffab..00000000
--- a/docs/_static/images/gns3-16.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-17.png b/docs/_static/images/gns3-17.png
deleted file mode 100644
index 64eff002..00000000
--- a/docs/_static/images/gns3-17.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-20.png b/docs/_static/images/gns3-20.png
deleted file mode 100644
index 17d92dea..00000000
--- a/docs/_static/images/gns3-20.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-21.png b/docs/_static/images/gns3-21.png
deleted file mode 100644
index e461016a..00000000
--- a/docs/_static/images/gns3-21.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-215.png b/docs/_static/images/gns3-215.png
deleted file mode 100644
index fde268ba..00000000
--- a/docs/_static/images/gns3-215.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gns3-22.png b/docs/_static/images/gns3-22.png
deleted file mode 100644
index 6ed52c1d..00000000
--- a/docs/_static/images/gns3-22.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gowin-01.png b/docs/_static/images/gowin-01.png
deleted file mode 100644
index 403ce52a..00000000
--- a/docs/_static/images/gowin-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gowin-02.png b/docs/_static/images/gowin-02.png
deleted file mode 100644
index 413f2948..00000000
--- a/docs/_static/images/gowin-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gowin-03.png b/docs/_static/images/gowin-03.png
deleted file mode 100644
index fbdbb142..00000000
--- a/docs/_static/images/gowin-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/gowin-04.png b/docs/_static/images/gowin-04.png
deleted file mode 100644
index c68b8731..00000000
--- a/docs/_static/images/gowin-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/inter-vrf-routing-vrf-lite.png b/docs/_static/images/inter-vrf-routing-vrf-lite.png
deleted file mode 100644
index 3acefee6..00000000
--- a/docs/_static/images/inter-vrf-routing-vrf-lite.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/ipsec-vyos-pa.png b/docs/_static/images/ipsec-vyos-pa.png
deleted file mode 100644
index 0929bcc7..00000000
--- a/docs/_static/images/ipsec-vyos-pa.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/json.png b/docs/_static/images/json.png
deleted file mode 100644
index 6c884e8e..00000000
--- a/docs/_static/images/json.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/key.png b/docs/_static/images/key.png
deleted file mode 100644
index 7d9366f4..00000000
--- a/docs/_static/images/key.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/keypairs.png b/docs/_static/images/keypairs.png
deleted file mode 100644
index 7e772ae9..00000000
--- a/docs/_static/images/keypairs.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/lac-lns-diagram.jpg b/docs/_static/images/lac-lns-diagram.jpg
deleted file mode 100644
index 4463a3c3..00000000
--- a/docs/_static/images/lac-lns-diagram.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/lac-lns-winclient.jpg b/docs/_static/images/lac-lns-winclient.jpg
deleted file mode 100644
index 9fa99152..00000000
--- a/docs/_static/images/lac-lns-winclient.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/ldapone.png b/docs/_static/images/ldapone.png
deleted file mode 100644
index 33ecf628..00000000
--- a/docs/_static/images/ldapone.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/ldaptwo.png b/docs/_static/images/ldaptwo.png
deleted file mode 100644
index 7cb9e0cb..00000000
--- a/docs/_static/images/ldaptwo.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/mainschema.png b/docs/_static/images/mainschema.png
deleted file mode 100644
index c39e5da2..00000000
--- a/docs/_static/images/mainschema.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/multicast-basic.png b/docs/_static/images/multicast-basic.png
deleted file mode 100644
index 3d4a3de3..00000000
--- a/docs/_static/images/multicast-basic.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nat_before_vpn_topology.png b/docs/_static/images/nat_before_vpn_topology.png
deleted file mode 100644
index ae23c92d..00000000
--- a/docs/_static/images/nat_before_vpn_topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp1.png b/docs/_static/images/nmp1.png
deleted file mode 100644
index 0b761a76..00000000
--- a/docs/_static/images/nmp1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp2.png b/docs/_static/images/nmp2.png
deleted file mode 100644
index 3190a099..00000000
--- a/docs/_static/images/nmp2.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp3.png b/docs/_static/images/nmp3.png
deleted file mode 100644
index 0585b80e..00000000
--- a/docs/_static/images/nmp3.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp4.png b/docs/_static/images/nmp4.png
deleted file mode 100644
index e0aa893e..00000000
--- a/docs/_static/images/nmp4.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp5.png b/docs/_static/images/nmp5.png
deleted file mode 100644
index d3149034..00000000
--- a/docs/_static/images/nmp5.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp6.png b/docs/_static/images/nmp6.png
deleted file mode 100644
index c4645e33..00000000
--- a/docs/_static/images/nmp6.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/nmp7.png b/docs/_static/images/nmp7.png
deleted file mode 100644
index 3e518e7e..00000000
--- a/docs/_static/images/nmp7.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/openvpn_site2site_diagram.jpg b/docs/_static/images/openvpn_site2site_diagram.jpg
deleted file mode 100644
index 05881e7d..00000000
--- a/docs/_static/images/openvpn_site2site_diagram.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/pbr_example_1.png b/docs/_static/images/pbr_example_1.png
deleted file mode 100644
index 3dff6db6..00000000
--- a/docs/_static/images/pbr_example_1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/policy-based-ipsec-and-firewall.png b/docs/_static/images/policy-based-ipsec-and-firewall.png
deleted file mode 100644
index 6e9d43ac..00000000
--- a/docs/_static/images/policy-based-ipsec-and-firewall.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/pppoe-ipv6-pd-diagram.jpg b/docs/_static/images/pppoe-ipv6-pd-diagram.jpg
deleted file mode 100644
index 430848c8..00000000
--- a/docs/_static/images/pppoe-ipv6-pd-diagram.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/project.png b/docs/_static/images/project.png
deleted file mode 100644
index 6f844c23..00000000
--- a/docs/_static/images/project.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos1.png b/docs/_static/images/qos1.png
deleted file mode 100644
index 9c16e6a3..00000000
--- a/docs/_static/images/qos1.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos10.png b/docs/_static/images/qos10.png
deleted file mode 100644
index 2f90ffe7..00000000
--- a/docs/_static/images/qos10.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos2.png b/docs/_static/images/qos2.png
deleted file mode 100644
index 4d351344..00000000
--- a/docs/_static/images/qos2.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos3.png b/docs/_static/images/qos3.png
deleted file mode 100644
index 97efaeb7..00000000
--- a/docs/_static/images/qos3.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos4.png b/docs/_static/images/qos4.png
deleted file mode 100644
index b87b256e..00000000
--- a/docs/_static/images/qos4.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos5.png b/docs/_static/images/qos5.png
deleted file mode 100644
index 4a615755..00000000
--- a/docs/_static/images/qos5.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos6.png b/docs/_static/images/qos6.png
deleted file mode 100644
index 907d6104..00000000
--- a/docs/_static/images/qos6.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos7.png b/docs/_static/images/qos7.png
deleted file mode 100644
index 03ec5cd1..00000000
--- a/docs/_static/images/qos7.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos8.png b/docs/_static/images/qos8.png
deleted file mode 100644
index 3566ac00..00000000
--- a/docs/_static/images/qos8.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/qos9.png b/docs/_static/images/qos9.png
deleted file mode 100644
index 67d8afd2..00000000
--- a/docs/_static/images/qos9.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/reset-password-step-1.jpg b/docs/_static/images/reset-password-step-1.jpg
deleted file mode 100644
index 3b6f7703..00000000
--- a/docs/_static/images/reset-password-step-1.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/reset-password-step-2.jpg b/docs/_static/images/reset-password-step-2.jpg
deleted file mode 100644
index 265bc73b..00000000
--- a/docs/_static/images/reset-password-step-2.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/reset-password-step-3.jpg b/docs/_static/images/reset-password-step-3.jpg
deleted file mode 100644
index 98795757..00000000
--- a/docs/_static/images/reset-password-step-3.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/reset-password-step-4.jpg b/docs/_static/images/reset-password-step-4.jpg
deleted file mode 100644
index 6f70ea24..00000000
--- a/docs/_static/images/reset-password-step-4.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/reset-password-step-5.jpg b/docs/_static/images/reset-password-step-5.jpg
deleted file mode 100644
index 70c586e2..00000000
--- a/docs/_static/images/reset-password-step-5.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/service.png b/docs/_static/images/service.png
deleted file mode 100644
index e2a9bbbc..00000000
--- a/docs/_static/images/service.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/service_conntrack_sync-schema.png b/docs/_static/images/service_conntrack_sync-schema.png
deleted file mode 100644
index 1b5fe8fb..00000000
--- a/docs/_static/images/service_conntrack_sync-schema.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/service_dhcp-relay01.png b/docs/_static/images/service_dhcp-relay01.png
deleted file mode 100644
index cd7f30cf..00000000
--- a/docs/_static/images/service_dhcp-relay01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/service_dhcpv6-relay01.png b/docs/_static/images/service_dhcpv6-relay01.png
deleted file mode 100644
index 9a10a10f..00000000
--- a/docs/_static/images/service_dhcpv6-relay01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/service_snmp_communication_principles_diagram.png b/docs/_static/images/service_snmp_communication_principles_diagram.png
deleted file mode 100644
index eff2ce45..00000000
--- a/docs/_static/images/service_snmp_communication_principles_diagram.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/sg.png b/docs/_static/images/sg.png
deleted file mode 100644
index 8be51e1f..00000000
--- a/docs/_static/images/sg.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/sticky-connections.jpg b/docs/_static/images/sticky-connections.jpg
deleted file mode 100644
index 25fd72a9..00000000
--- a/docs/_static/images/sticky-connections.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/traffic.png b/docs/_static/images/traffic.png
deleted file mode 100644
index 74002b16..00000000
--- a/docs/_static/images/traffic.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_01.png b/docs/_static/images/uefi_secureboot_01.png
deleted file mode 100644
index 02ec56b0..00000000
--- a/docs/_static/images/uefi_secureboot_01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_02.png b/docs/_static/images/uefi_secureboot_02.png
deleted file mode 100644
index 336d654d..00000000
--- a/docs/_static/images/uefi_secureboot_02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_03.png b/docs/_static/images/uefi_secureboot_03.png
deleted file mode 100644
index ff126842..00000000
--- a/docs/_static/images/uefi_secureboot_03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_04.png b/docs/_static/images/uefi_secureboot_04.png
deleted file mode 100644
index 90242299..00000000
--- a/docs/_static/images/uefi_secureboot_04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_05.png b/docs/_static/images/uefi_secureboot_05.png
deleted file mode 100644
index b08cb946..00000000
--- a/docs/_static/images/uefi_secureboot_05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_06.png b/docs/_static/images/uefi_secureboot_06.png
deleted file mode 100644
index 784f0eed..00000000
--- a/docs/_static/images/uefi_secureboot_06.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/uefi_secureboot_07.png b/docs/_static/images/uefi_secureboot_07.png
deleted file mode 100644
index 6ff450b4..00000000
--- a/docs/_static/images/uefi_secureboot_07.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-01.png b/docs/_static/images/virt-libvirt-01.png
deleted file mode 100644
index 06baea8e..00000000
--- a/docs/_static/images/virt-libvirt-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-02.png b/docs/_static/images/virt-libvirt-02.png
deleted file mode 100644
index b6c4b379..00000000
--- a/docs/_static/images/virt-libvirt-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-03.png b/docs/_static/images/virt-libvirt-03.png
deleted file mode 100644
index ac3891f0..00000000
--- a/docs/_static/images/virt-libvirt-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-04.png b/docs/_static/images/virt-libvirt-04.png
deleted file mode 100644
index b1218597..00000000
--- a/docs/_static/images/virt-libvirt-04.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-05.png b/docs/_static/images/virt-libvirt-05.png
deleted file mode 100644
index 5579c281..00000000
--- a/docs/_static/images/virt-libvirt-05.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-06.png b/docs/_static/images/virt-libvirt-06.png
deleted file mode 100644
index e0983d23..00000000
--- a/docs/_static/images/virt-libvirt-06.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-qc-01.png b/docs/_static/images/virt-libvirt-qc-01.png
deleted file mode 100644
index 49867bd0..00000000
--- a/docs/_static/images/virt-libvirt-qc-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-qc-02.png b/docs/_static/images/virt-libvirt-qc-02.png
deleted file mode 100644
index a71b8f64..00000000
--- a/docs/_static/images/virt-libvirt-qc-02.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/virt-libvirt-qc-03.png b/docs/_static/images/virt-libvirt-qc-03.png
deleted file mode 100644
index 4eefaa58..00000000
--- a/docs/_static/images/virt-libvirt-qc-03.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vpn_dmvpn_topology01.png b/docs/_static/images/vpn_dmvpn_topology01.png
deleted file mode 100644
index 17433be6..00000000
--- a/docs/_static/images/vpn_dmvpn_topology01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vpn_s2s_ikev2.png b/docs/_static/images/vpn_s2s_ikev2.png
deleted file mode 100644
index f8050e3a..00000000
--- a/docs/_static/images/vpn_s2s_ikev2.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vpn_s2s_ikev2_c.png b/docs/_static/images/vpn_s2s_ikev2_c.png
deleted file mode 100644
index 2d9e21b5..00000000
--- a/docs/_static/images/vpn_s2s_ikev2_c.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vrf-example-topology-01.png b/docs/_static/images/vrf-example-topology-01.png
deleted file mode 100644
index 57357509..00000000
--- a/docs/_static/images/vrf-example-topology-01.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyos-downloads.png b/docs/_static/images/vyos-downloads.png
deleted file mode 100644
index 6bad2b19..00000000
--- a/docs/_static/images/vyos-downloads.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyos-sr-isis.png b/docs/_static/images/vyos-sr-isis.png
deleted file mode 100644
index 62430919..00000000
--- a/docs/_static/images/vyos-sr-isis.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyos_1_4_nat66_simple.png b/docs/_static/images/vyos_1_4_nat66_simple.png
deleted file mode 100644
index d7c54115..00000000
--- a/docs/_static/images/vyos_1_4_nat66_simple.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png b/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png
deleted file mode 100644
index 297fdd11..00000000
--- a/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyos_arista_bond_lacp.png b/docs/_static/images/vyos_arista_bond_lacp.png
deleted file mode 100644
index 6c9ef8ec..00000000
--- a/docs/_static/images/vyos_arista_bond_lacp.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/vyosnew-downloads.png b/docs/_static/images/vyosnew-downloads.png
deleted file mode 100644
index 294a4589..00000000
--- a/docs/_static/images/vyosnew-downloads.png
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/wireguard_qrcode.jpg b/docs/_static/images/wireguard_qrcode.jpg
deleted file mode 100644
index 0a9a98c0..00000000
--- a/docs/_static/images/wireguard_qrcode.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/wireguard_site2site_diagram.jpg b/docs/_static/images/wireguard_site2site_diagram.jpg
deleted file mode 100644
index 4a7a95e4..00000000
--- a/docs/_static/images/wireguard_site2site_diagram.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/_static/images/zone-policy-diagram.png b/docs/_static/images/zone-policy-diagram.png
deleted file mode 100644
index cfde4af6..00000000
--- a/docs/_static/images/zone-policy-diagram.png
+++ /dev/null
Binary files differ
diff --git a/docs/automation/cloud-init.md b/docs/automation/cloud-init.md
new file mode 100644
index 00000000..01ad360d
--- /dev/null
+++ b/docs/automation/cloud-init.md
@@ -0,0 +1,380 @@
+---
+lastproofread: '2026-04-13'
+---
+
+(cloud-init)=
+
+# VyOS cloud-init
+
+VyOS instances in cloud and virtualized environments are initialized using the
+industry-standard `cloud-init`. Through `cloud-init`, VyOS injects SSH
+keys, configures network settings, and applies custom configurations during the
+initial instance boot.
+
+## Configuration sources
+
+VyOS `cloud-init` obtains configuration data from the following sources:
+
+- `meta-data`: Instance-specific details provided by the cloud platform or
+ hypervisor. In some cloud environments, this data is available via an HTTP
+ endpoint at `http://169.254.169.254`.
+- `network configuration`: Network settings such as IP addresses, routes, and
+ DNS (only available on certain cloud and virtualization platforms).
+- `user-data`: User-supplied CLI configuration commands.
+
+## User-data
+
+Major cloud providers support injecting `user-data` as plain text or base64
+encoding text during initial instance boot. As `user-data` has a strict size
+limit of \~16384 bytes, long configuration command lists can be compressed using
+`gzip`.
+
+The recommended method for configuring VyOS instances via `user-data` is to
+use the `cloud-config` syntax described below.
+
+## Cloud-config modules
+
+By default, VyOS enables only two `cloud-config` modules:
+
+- `write_files`: Inserts user-provided files such as encryption keys,
+ certificates, or `config.boot` into the filesystem during the initial
+ instance boot. See [Cloud-init-write_files] for file syntax and file format
+ requirements.
+- `vyos_userdata`: Executes user-provided CLI configuration commands during
+ the initial instance boot.
+
+The files to insert and the CLI commands to execute must be provided in a
+`cloud-config` YAML file.
+
+## Cloud-config file format
+
+`cloud-config` files are written in YAML and must begin with the
+`#cloud-config` line. Only `vyos_config_commands` and `write_files` are
+supported as top-level keys. The use of these keys is described in the
+following two sections.
+
+## Vyos_config_commands key
+
+Use the `vyos_config_commands` key to define configuration commands for
+initializing your VyOS instance. Commands must follow the set-style syntax
+and can include both `set` and `delete` statements.
+
+Syntax requirements:
+
+- Place one command per line.
+- Enclose values in single quotes.
+- Avoid single quotes within commands or values.
+
+Applying commands from `cloud-config` overrides both settings configured via
+`meta-data` and default VyOS settings. After commands are applied,
+`cloud-init` automatically performs `commit` and `save`.
+
+The following is an example of a `cloud-config` file:
+
+```yaml
+#cloud-config
+vyos_config_commands:
+ - set system host-name 'vyos-prod-ashburn'
+ - set service ntp server 1.pool.ntp.org
+ - set service ntp server 2.pool.ntp.org
+ - delete interfaces ethernet eth1 address 'dhcp'
+ - set interfaces ethernet eth1 address '192.0.2.247/24'
+ - set protocols static route 198.51.100.0/24 next-hop '192.0.2.1'
+```
+
+
+### Instance defaults/fallbacks
+
+If no external configuration data is provided, VyOS applies the following
+defaults:
+
+- **SSH:** port 22.
+- **Credentials:** `vyos`/`vyos`.
+- **Networking:** DHCP is enabled on the first Ethernet interface.
+
+All defaults can be overridden via `user-data` configurations.
+
+## Write_files key
+
+VyOS allows you to run custom scripts during the initial instance boot to
+execute operational, configuration, and standard Linux commands.
+
+Use the `write_files` key to insert these scripts into the
+`/opt/vyatta/etc/config/scripts/` directory.
+
+Depending on when your commands need to run, use one of the following paths:
+
+- `/opt/vyatta/etc/config/scripts/vyos-preconfig-bootup.script`: Commands
+ defined here are executed before the system configuration is applied.
+- `/opt/vyatta/etc/config/scripts/vyos-postconfig-bootup.script`: Commands
+ defined here are executed after the system configuration is applied.
+
+In both cases, commands are executed with `root` privileges.
+
+:::{note}
+Use the `/opt/vyatta/etc/config/` path instead of `/config/scripts/` as
+referenced in the {ref}`command-scripting` section. The `/config/scripts/`
+directory is not mounted when the `write_files` module runs.
+:::
+
+The following example shows how to use `write_files` to execute an
+operational command **after** the initial configuration is complete:
+
+```yaml
+#cloud-config
+write_files:
+ - path: /opt/vyatta/etc/config/scripts/vyos-postconfig-bootup.script
+ owner: root:vyattacfg
+ permissions: '0775'
+ content: |
+ #!/bin/vbash
+ source /opt/vyatta/etc/functions/script-template
+ filename=/tmp/bgp_status_`date +"%Y_%m_%d_%I_%M_%p"`.log
+ run show ip bgp summary >> $filename
+```
+
+You can combine standard Linux commands to fetch data and VyOS configuration
+commands (like `set` and `commit`) in the same script.
+
+The following example sets the `hostname` based on the instance identifier
+obtained from the EC2 Instance Metadata Service (IMDS).
+
+```yaml
+#cloud-config
+write_files:
+ - path: /opt/vyatta/etc/config/scripts/vyos-postconfig-bootup.script
+ owner: root:vyattacfg
+ permissions: '0775'
+ content: |
+ #!/bin/vbash
+ source /opt/vyatta/etc/functions/script-template
+ hostname=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
+ configure
+ set system host-name $hostname
+ commit
+ exit
+```
+
+
+## NoCloud
+
+Injecting configuration data is not limited to cloud platforms. The NoCloud
+data source allows you to inject `user-data` and `meta-data` on
+virtualization platforms such as VMware, Hyper-V, and KVM.
+
+The simplest way to use the NoCloud data source is to create a `seed.iso`
+file and attach it to the virtual machine as a CD drive. The volume must be
+formatted as a VFAT or ISO 9660 file system with the label `cidata` or
+`CIDATA`.
+
+Create text files named `user-data` and `meta-data`. On Linux-based
+systems, use the `mkisofs` utility to create the `seed.iso` file. The
+following syntax adds these files to the ISO 9660 file system:
+
+```none
+mkisofs -joliet -rock -volid "cidata" -output seed.iso meta-data user-data
+```
+
+Once generated, attach the `seed.iso` file to your virtual machine. The
+following example shows how to attach the file as a CD drive using KVM:
+
+```none
+$ virt-install -n vyos_r1 \
+ --ram 4096 \
+ --vcpus 2 \
+ --cdrom seed.iso \
+ --os-type linux \
+ --os-variant debian10 \
+ --network network=default \
+ --graphics vnc \
+ --hvm \
+ --virt-type kvm \
+ --disk path=/var/lib/libvirt/images/vyos_kvm.qcow2,bus=virtio \
+ --import \
+ --noautoconsole
+```
+
+For more information on the NoCloud data source, visit the [NoCloud] page in
+the `cloud-init` documentation.
+
+## Troubleshooting
+
+If your configuration does not apply as expected, follow these troubleshooting
+steps:
+
+1. **Validate your YAML**: Ensure your `cloud-config` file follows proper
+ YAML syntax. Online resources such as [YAML Lint](https://www.yamllint.com/)
+ provide simple validation tools.
+2. **Check the logs**: `cloud-init` writes logs to `/var/log/cloud-init.log`.
+ Filter for VyOS-specific entries using:
+
+```none
+sudo grep vyos /var/log/cloud-init.log
+```
+
+
+## Cloud-init on Proxmox
+
+Before you begin, review the `cloud-init` [network-config-docs] to
+understand how to import user and network configuration data.
+
+Key considerations:
+
+- Define VyOS configuration commands in the `user-data` file.
+- Avoid including network configuration data in the `user-data` file.
+- If no network configuration data is provided, the DHCP client is enabled on
+ the first interface. This happens at the OS level and is not reflected in the
+ VyOS CLI.
+
+The following example shows how to disable the DHCP client on `eth0` to
+address this behavior.
+
+In this example:
+
+- **Proxmox IP address**: `192.168.0.253/24`.
+- **Storage**: The `local` volume is mounted at `/var/lib/vz` and contains
+ all content types, including snippets.
+
+The goal is to remove the default DHCP client from the first interface and
+apply a custom configuration during the initial instance boot using
+`cloud-init`.
+
+### Generate .qcow2 image
+
+First, generate a VyOS `.qcow2` image with `cloud-init` support from the
+[vyos-vm-images] repository:
+
+1. Clone the `vyos-vm-images` repository and comment out the `download-iso`
+ role in `qemu.yml`.
+2. Download your preferred VyOS `.iso` file and save it as `/tmp/vyos.iso`.
+3. Generate the `.qcow2` image (using a 10G disk size for this example):
+
+```sh
+sudo ansible-playbook qemu.yml -e disk_size=10 \
+ -e iso_local=/tmp/vyos.iso -e grub_console=serial -e vyos_version=1.5.0 \
+ -e cloud_init=true -e cloud_init_ds=NoCloud
+```
+
+This generates your new image at `/tmp/vyos-1.5.0-cloud-init-10G-qemu.qcow2`.
+
+4. Copy the resulting image to the Proxmox server:
+
+```sh
+sudo scp /tmp/vyos-1.5.0-cloud-init-10G-qemu.qcow2 root@192.168.0.253:/tmp/
+```
+
+
+### Prepare cloud-init files
+
+Create the following files on your Proxmox server to proceed with this setup:
+
+- `user-data`: Contains VyOS configuration commands.
+- `network-config`: Disables the DHCP client on the first interface.
+- `meta-data`: An empty file (required by `cloud-init`).
+
+All files must be placed in the `/tmp/` directory.
+
+Follow these steps to create the required files:
+
+1. Navigate to the `/tmp/` directory:
+
+ ```sh
+ cd /tmp/
+ ```
+
+2. Create the `user-data` file. Begin the file with `#cloud-config` and
+ include VyOS configuration commands.
+
+ ```none
+ #cloud-config
+ vyos_config_commands:
+ - set system host-name 'vyos-BRAS'
+ - set service ntp server '1.pool.ntp.org'
+ - set service ntp server '2.pool.ntp.org'
+ - delete interfaces ethernet eth0 address 'dhcp'
+ - set interfaces ethernet eth0 address '198.51.100.2/30'
+ - set interfaces ethernet eth0 description 'WAN - ISP01'
+ - set interfaces ethernet eth1 address '192.168.25.1/24'
+ - set interfaces ethernet eth1 description 'Coming through VLAN 25'
+ - set interfaces ethernet eth2 address '192.168.26.1/24'
+ - set interfaces ethernet eth2 description 'Coming through VLAN 26'
+ - set protocols static route 0.0.0.0/0 next-hop '198.51.100.1'
+ ```
+
+3. Create the `network-config` file. Include the following:
+
+ ```none
+ version: 2
+ ethernets:
+ eth0:
+ dhcp4: false
+ dhcp6: false
+ ```
+
+4. Create the required empty `meta-data` file.
+
+### Create seed.iso
+
+Once you have created the necessary files, generate the `seed.iso` image and
+mount it as a CD drive to the new VM.
+
+```sh
+mkisofs -joliet -rock -volid "cidata" -output seed.iso meta-data \
+user-data network-config
+```
+
+:::{note}
+Be careful while copying and pasting the above commands. Double quotes may need
+to be corrected.
+:::
+
+### Create the VM
+
+Note that the following settings apply to this particular example and may
+require adjustment for other setups:
+
+- **VM ID**: `555`.
+- **VM and .iso file storage**: The local volume (`directory` type,
+ mounted at `/var/lib/vz`).
+- **VM resources**: Can be modified as needed.
+
+The `seed.iso` file was previously created in the `/tmp/` directory. Move
+it to `/var/lib/vz/template/iso`:
+
+```sh
+mv /tmp/seed.iso /var/lib/vz/template/iso/
+```
+
+On the Proxmox server:
+
+```none
+## Create VM, import disk and define boot order
+qm create 555 --name vyos-1.5.0-cloudinit --memory 1024 --net0 virtio,bridge=vmbr0
+qm importdisk 555 vyos-1.5.0-cloud-init-10G-qemu.qcow2 local
+qm set 555 --virtio0 local:555/vm-555-disk-0.raw
+qm set 555 --boot order=virtio0
+
+## Import seed.iso for cloud init
+qm set 555 --ide2 media=cdrom,file=local:iso/seed.iso
+
+## Since this server has 1 nic, lets add network intefaces (vlan 25 and 26)
+qm set 555 --net1 virtio,bridge=vmbr0,firewall=1,tag=25
+qm set 555 --net2 virtio,bridge=vmbr0,firewall=1,tag=26
+```
+
+
+### Power on and verify the VM
+
+Power on the VM using the CLI or GUI. After it boots, verify the configuration.
+
+### References
+
+- Cloud-init [network-config-docs].
+- Proxmox [Cloud-init-Support].
+
+[cloud-init-docs]: https://docs.vyos.io/en/equuleus/automation/cloud-init.html?highlight=cloud-init#vyos-cloud-init
+[cloud-init-support]: <https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_cloud_init>
+[cloud-init-write_files]: https://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing-out-arbitrary-files
+[network-config-docs]: https://cloudinit.readthedocs.io/en/latest/topics/network-config.html
+[nocloud]: https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html
+[vyos-vm-images]: https://github.com/vyos/vyos-vm-images
diff --git a/docs/automation/command-scripting.md b/docs/automation/command-scripting.md
new file mode 100644
index 00000000..7e736152
--- /dev/null
+++ b/docs/automation/command-scripting.md
@@ -0,0 +1,225 @@
+---
+lastproofread: '2026-03-16'
+---
+
+(command-scripting)=
+
+# Command scripting
+
+VyOS supports executing configuration and operational commands non-interactively
+from shell scripts.
+
+To include VyOS-specific functions and aliases, source the
+`/opt/vyatta/etc/functions/script-template` file at the beginning of your
+script.
+
+```none
+#!/bin/vbash
+source /opt/vyatta/etc/functions/script-template
+exit
+```
+
+
+## Script execute permissions
+
+Simply placing script files in `/config/scripts/` does not mean the system
+can execute them.
+
+To make your scripts executable, grant them **execute permissions**. Use the
+following command:
+
+```none
+chmod +x /config/scripts/script-name.sh
+```
+
+
+## Run configuration commands
+
+In scripts, present configuration commands as in a standard configuration
+session.
+
+For example, to disable a BGP peer during a VRRP transition to the backup
+state, use the following syntax:
+
+```none
+#!/bin/vbash
+source /opt/vyatta/etc/functions/script-template
+configure
+set protocols bgp system-as 65536
+set protocols bgp neighbor 192.168.2.1 shutdown
+commit
+exit
+```
+
+
+## Run operational commands
+
+In scripts, **always** prefix operational commands with `run`.
+
+```none
+#!/bin/vbash
+source /opt/vyatta/etc/functions/script-template
+run show interfaces
+exit
+```
+
+
+## Run commands remotely
+
+You can execute multiple **operational commands** on a remote VyOS system by
+passing a script block over SSH.
+
+```none
+ssh 192.0.2.1 'vbash -s' <<EOF
+source /opt/vyatta/etc/functions/script-template
+run show interfaces
+exit
+EOF
+```
+
+Example output:
+
+```none
+Welcome to VyOS
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 192.0.2.1/24 u/u
+lo 127.0.0.1/8 u/u
+ ::1/128
+```
+
+
+## Other script languages
+
+If you use a scripting language other than bash, configure your script to
+output the relevant commands, and then source that output into a bash script.
+
+The following example demonstrates this two-step process:
+
+```python
+#!/usr/bin/env python3
+print("delete firewall group address-group somehosts")
+print("set firewall group address-group somehosts address '192.0.2.3'")
+print("set firewall group address-group somehosts address '203.0.113.55'")
+```
+
+```none
+#!/bin/vbash
+source /opt/vyatta/etc/functions/script-template
+configure
+source <(/config/scripts/setfirewallgroup.py)
+commit
+```
+
+
+## Execute configuration scripts
+
+In Linux, it is common practice to prefix system commands with `sudo`.
+
+In VyOS, if you prefix a script that modifies the configuration with `sudo`
+(see the code snippet below), subsequent manual configuration changes fail with
+the `Set failed` error. Recovery requires a system reboot.
+
+```none
+sudo ./myscript.sh # Modifies config
+configure
+set ... # Any configuration parameter
+```
+
+To avoid this issue, run scripts under the `vyattacfg` group using the `sg`
+command:
+
+```none
+sg vyattacfg -c ./myscript.sh
+```
+
+To ensure the script is executed under the `vyattacfg` group, safeguard it as
+follows:
+
+```none
+if [ "$(id -g -n)" != 'vyattacfg' ] ; then
+ exec sg vyattacfg -c "/bin/vbash $(readlink -f $0) $@"
+fi
+```
+
+
+## Executing pre-hooks/post-hooks scripts
+
+VyOS allows you to run custom scripts **before** and **after** each commit.
+
+Place your custom scripts in the following default directories:
+
+```none
+/config/scripts/commit/pre-hooks.d - Directory with scripts that run before
+ each commit.
+
+/config/scripts/commit/post-hooks.d - Directory with scripts that run after
+ each commit.
+```
+
+Scripts run in alphabetical order. Filenames must consist only of ASCII letters
+(upper and lowercase), digits (0-9), underscores (\_), and hyphens (-). No other
+characters are allowed.
+
+:::{note}
+Custom scripts are executed **without** root privileges. Prefix
+specific commands with `sudo` in your script when required.
+:::
+
+The following example shows the output after executing a post-hook script
+that runs the `show interfaces` command:
+
+```none
+vyos@vyos# set interfaces ethernet eth1 address 192.0.2.3/24
+vyos@vyos# commit
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 198.51.100.10/24 u/u
+eth1 192.0.2.3/24 u/u
+eth2 - u/u
+eth3 - u/u
+lo 203.0.113.5/24 u/u
+```
+
+
+## Preconfig script on boot
+
+VyOS runs `/config/scripts/vyos-preconfig-bootup.script` at boot, **before**
+the system configuration is applied.
+
+Use this script to apply **pre-configuration** workarounds for unresolved bugs
+or enhancements not yet available in VyOS.
+
+The default script contains the following:
+
+```none
+#!/bin/sh
+# This script is executed at boot time before VyOS configuration is applied.
+# Any modifications required to work around unfixed bugs or use
+# services not available through the VyOS CLI system can be placed here.
+```
+
+
+## Postconfig script on boot
+
+VyOS runs `/config/scripts/vyos-postconfig-bootup.script` at boot, **after**
+the system configuration is applied.
+
+Use this script to apply **post-configuration** workarounds for unresolved bugs
+or enhancements not yet available in VyOS.
+
+The default script contains the following:
+
+```none
+#!/bin/sh
+# This script is executed at boot time after VyOS configuration is fully
+# applied. Any modifications required to work around unfixed bugs or use
+# services not available through the VyOS CLI system can be placed here.
+```
+
+:::{warning}
+For configuration or upgrade management issues, modify this script
+only as a last resort. Always try CLI-based solutions first.
+:::
diff --git a/docs/automation/index.md b/docs/automation/index.md
new file mode 100644
index 00000000..62e60f84
--- /dev/null
+++ b/docs/automation/index.md
@@ -0,0 +1,16 @@
+# VyOS Automation
+
+```{toctree}
+:maxdepth: 2
+
+vyos-api
+vyos-ansible
+terraform/index
+vyos-napalm
+vyos-netmiko
+vyos-salt
+command-scripting
+cloud-init
+vyos-pyvyos
+vyos-govyos
+```
diff --git a/docs/automation/terraform/index.md b/docs/automation/terraform/index.md
new file mode 100644
index 00000000..dc787db1
--- /dev/null
+++ b/docs/automation/terraform/index.md
@@ -0,0 +1,29 @@
+---
+lastproofread: '2026-03-23'
+---
+
+# VyOS Terraform
+
+VyOS supports development infrastructure via Terraform and provisioning
+via Ansible.
+Terraform allows you to automate the deployment of instances on a number of
+cloud and virtual platforms. This section shows how to deploy VyOS on
+multiple platforms: AWS, Microsoft Azure, Google Cloud Platform (GCP),
+and VMware vSphere.
+For more information, see the
+official documentation for [Terraform] and [Ansible].
+
+```{toctree}
+:caption: Guides
+:maxdepth: 1
+
+terraformvyos
+terraformAWS
+terraformAZ
+terraformGoogle
+terraformvSphere
+```
+
+[ansible]: https://docs.ansible.com
+[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
+[terraform]: https://developer.hashicorp.com/terraform/intro
diff --git a/docs/automation/terraform/terraformAWS.md b/docs/automation/terraform/terraformAWS.md
new file mode 100644
index 00000000..b0c06bb1
--- /dev/null
+++ b/docs/automation/terraform/terraformAWS.md
@@ -0,0 +1,551 @@
+---
+lastproofread: '2026-03-16'
+---
+
+(terraformaws)=
+
+# Deploy VyOS on AWS with Terraform and Ansible
+
+You can use Terraform to quickly deploy VyOS-based infrastructure
+on AWS and remove infrastructure when it's no longer needed.
+Additionally, you can use Ansible for provisioning.
+
+```{eval-rst}
+.. image:: /_static/images/aws.webp
+ :width: 50%
+ :align: center
+ :alt: Network Topology Diagram
+```
+
+On this page you'll learn how to:
+- Create the necessary files for Terraform and Ansible.
+- Use Terraform to create a single instance on AWS and use Ansible for
+ provisioning.
+
+## Prepare to deploy VyOS with Terraform on AWS
+
+To create a single instance and install your configuration using
+Terraform, Ansible, and AWS, follow these steps:
+
+### AWS
+
+1. Create an account with AWS and get your `access_key` and `secret_key`.
+2. Create a key [pair] and download your `.pem` key.
+
+```{eval-rst}
+.. image:: /_static/images/keypairs.webp
+ :width: 50%
+ :align: center
+ :alt: Network Topology Diagram
+```
+
+3. Create a security [group] for the new VyOS instance and open all traffic.
+
+```{eval-rst}
+.. image:: /_static/images/sg.webp
+ :width: 50%
+ :align: center
+ :alt: Network Topology Diagram
+```
+
+```{eval-rst}
+.. image:: /_static/images/traffic.webp
+ :width: 50%
+ :align: center
+ :alt: Network Topology Diagram
+```
+
+
+### Terraform
+
+```{eval-rst}
+1. Create an UNIX or Windows instance.
+
+2. Download and install
+ `Terraform <https://developer.hashicorp.com/terraform/install>`__.
+
+3. Create a folder, for example ``/root/awsterraform``:
+
+ .. code-block:: none
+
+ mkdir /root/awsterraform
+
+.. stop_vyoslinter
+
+4. Copy all files into your Terraform project
+ (``vyos.tf``, ``var.tf``, ``terraform.tfvars``, ``version.tf``).
+ See `Structure of files in Terraform for AWS <#structure-of-files-in-terraform-for-aws>`__ for more details.
+
+.. start_vyoslinter
+
+5. Run the following commands:
+
+.. code-block:: none
+
+ cd /<your folder>
+ terraform init
+```
+
+### Ansible
+
+```{eval-rst}
+1. Create a UNIX instance whenever you need.
+
+2. Download and install Ansible
+
+3. Create a folder, for example ``/root/aws/``.
+
+.. stop_vyoslinter
+
+4. Copy all files into your Ansible project
+ (``ansible.cfg``, ``instance.yml``,
+ ``mykey.pem``, and ``all``).
+ See `Structure of files in Ansible for AWS <#structure-of-files-in-ansible-for-aws>`__ for more details.
+ You can obtain ``mykey.pem`` by creating a key `pair <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html>`__ in AWS and
+ downloading your ``.pem`` key.
+```
+
+### Deploy with Terraform
+
+Run the following commands on your Terraform instance:
+
+```none
+cd /<your folder>
+terraform plan
+terraform apply
+yes
+```
+
+## Create an AWS instance and check its configuration
+
+```none
+root@localhost:~/awsterraform# terraform apply
+
+Terraform used the selected providers to generate the following execution plan.
+Resource actions are indicated with the following symbols:
+ + create
+
+Terraform will perform the following actions:
+
+ # aws_instance.myVyOSec2 will be created
+ + resource "aws_instance" "myVyOSec2" {
+ + ami = "ami-************62c2d"
+ + arn = (known after apply)
+ + associate_public_ip_address = (known after apply)
+ + availability_zone = (known after apply)
+ + cpu_core_count = (known after apply)
+ + cpu_threads_per_core = (known after apply)
+ + disable_api_stop = (known after apply)
+ + disable_api_termination = (known after apply)
+ + ebs_optimized = (known after apply)
+ + get_password_data = false
+ + host_id = (known after apply)
+ + host_resource_group_arn = (known after apply)
+ + iam_instance_profile = (known after apply)
+ + id = (known after apply)
+ + instance_initiated_shutdown_behavior = (known after apply)
+ + instance_lifecycle = (known after apply)
+ + instance_state = (known after apply)
+ + instance_type = "t2.micro"
+ + ipv6_address_count = (known after apply)
+ + ipv6_addresses = (known after apply)
+ + key_name = "awsterraform"
+ + monitoring = (known after apply)
+ + outpost_arn = (known after apply)
+ + password_data = (known after apply)
+ + placement_group = (known after apply)
+ + placement_partition_number = (known after apply)
+ + primary_network_interface_id = (known after apply)
+ + private_dns = (known after apply)
+ + private_ip = (known after apply)
+ + public_dns = (known after apply)
+ + public_ip = (known after apply)
+ + secondary_private_ips = (known after apply)
+ + security_groups = [
+ + "awsterraformsg",
+ ]
+ + source_dest_check = true
+ + spot_instance_request_id = (known after apply)
+ + subnet_id = (known after apply)
+ + tags = {
+ + "name" = "VyOS System"
+ }
+ + tags_all = {
+ + "name" = "VyOS System"
+ }
+ + tenancy = (known after apply)
+ + user_data = (known after apply)
+ + user_data_base64 = (known after apply)
+ + user_data_replace_on_change = false
+ + vpc_security_group_ids = (known after apply)
+ }
+
+ # local_file.ip will be created
+ + resource "local_file" "ip" {
+ + content = (known after apply)
+ + content_base64sha256 = (known after apply)
+ + content_base64sha512 = (known after apply)
+ + content_md5 = (known after apply)
+ + content_sha1 = (known after apply)
+ + content_sha256 = (known after apply)
+ + content_sha512 = (known after apply)
+ + directory_permission = "0777"
+ + file_permission = "0777"
+ + filename = "ip.txt"
+ + id = (known after apply)
+ }
+
+ # null_resource.SSHconnection1 will be created
+ + resource "null_resource" "SSHconnection1" {
+ + id = (known after apply)
+ }
+
+ # null_resource.SSHconnection2 will be created
+ + resource "null_resource" "SSHconnection2" {
+ + id = (known after apply)
+ }
+
+Plan: 4 to add, 0 to change, 0 to destroy.
+
+Changes to Outputs:
+ + my_IP = (known after apply)
+
+Do you want to perform these actions?
+ Terraform will perform the actions described above.
+ Only 'yes' will be accepted to approve.
+
+ Enter a value: yes
+
+aws_instance.myVyOSec2: Creating...
+aws_instance.myVyOSec2: Still creating... [10s elapsed]
+aws_instance.myVyOSec2: Still creating... [20s elapsed]
+aws_instance.myVyOSec2: Still creating... [30s elapsed]
+aws_instance.myVyOSec2: Still creating... [40s elapsed]
+aws_instance.myVyOSec2: Creation complete after 44s [id=i-09edfca15aac2fe0a]
+null_resource.SSHconnection1: Creating...
+null_resource.SSHconnection2: Creating...
+null_resource.SSHconnection1: Provisioning with 'file'...
+null_resource.SSHconnection2: Provisioning with 'remote-exec'...
+null_resource.SSHconnection2 (remote-exec): Connecting to remote host via SSH...
+null_resource.SSHconnection2 (remote-exec): Host: 10.217.80.104
+null_resource.SSHconnection2 (remote-exec): User: root
+null_resource.SSHconnection2 (remote-exec): Password: true
+null_resource.SSHconnection2 (remote-exec): Private key: false
+null_resource.SSHconnection2 (remote-exec): Certificate: false
+null_resource.SSHconnection2 (remote-exec): SSH Agent: false
+null_resource.SSHconnection2 (remote-exec): Checking Host Key: false
+null_resource.SSHconnection2 (remote-exec): Target Platform: unix
+local_file.ip: Creating...
+local_file.ip: Creation complete after 0s [id=e8e91f2e24579cd28b92e2d152c0c24c3bf4b52c]
+null_resource.SSHconnection2 (remote-exec): Connected!
+null_resource.SSHconnection1: Creation complete after 0s [id=7070868940858935600]
+
+null_resource.SSHconnection2 (remote-exec): PLAY [integration of terraform and ansible] ************************************
+
+null_resource.SSHconnection2 (remote-exec): TASK [Wait 300 seconds, but only start checking after 60 seconds] **************
+null_resource.SSHconnection2: Still creating... [10s elapsed]
+null_resource.SSHconnection2: Still creating... [20s elapsed]
+null_resource.SSHconnection2: Still creating... [30s elapsed]
+null_resource.SSHconnection2: Still creating... [40s elapsed]
+null_resource.SSHconnection2: Still creating... [50s elapsed]
+null_resource.SSHconnection2: Still creating... [1m0s elapsed]
+null_resource.SSHconnection2 (remote-exec): ok: [54.xxx.xxx.xxx]
+
+null_resource.SSHconnection2 (remote-exec): TASK [Configure general settings for the vyos hosts group] *********************
+null_resource.SSHconnection2: Still creating... [1m10s elapsed]
+null_resource.SSHconnection2 (remote-exec): changed: [54.xxx.xxx.xxx]
+
+null_resource.SSHconnection2 (remote-exec): PLAY RECAP *********************************************************************
+null_resource.SSHconnection2 (remote-exec): 54.xxx.xxx.xxx : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+
+null_resource.SSHconnection2: Creation complete after 1m16s [id=4902256962410024771]
+
+Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
+
+Outputs:
+
+my_IP = "54.xxx.xxx.xxx"
+```
+
+After running all the commands, your VyOS instance is deployed on
+AWS with your specified configuration.
+To delete the instance, type the following command:
+
+```none
+terraform destroy
+```
+
+## Troubleshooting
+
+1. If Ansible doesn't connect via SSH to your AWS instance, verify that
+ your SSH key is in the path `/root/aws/`. You might need to
+ increase the timeout in `instance.yml` from 300 seconds to 500
+ seconds or more, depending on your location. Make sure that the
+ security group allows access to the instance.
+2. If Terraform doesn't connect via SSH to your Ansible instance,
+ verify the correct login and password in the `VyOS.tf` file.
+
+```{eval-rst}
+ .. code-block:: none
+
+ connection {
+ type = "ssh"
+ user = "root" # open root access using login and password on your Ansible
+ password = var.password # check password in the file terraform.tfvars isn't empty
+ host = var.host # check the correct IP address of your Ansible host
+ }
+```
+
+Make sure Ansible can ping from Terraform.
+
+## Structure of files in Terraform for AWS
+
+```none
+.
+├── vyos.tf # The main script
+├── var.tf # The file of all variables in "vyos.tf"
+├── versions.tf # File for the changing version of Terraform.
+└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on)
+```
+
+## File contents of Terraform for AWS
+
+`vyos.tf`
+
+```none
+##############################################################################
+# Build a VyOS VM from the Marketplace.
+# Find the necessary AMI image_ in AWS.
+#
+# The vyos.tf script uses default values (you can change them as
+# needed)
+# AWS Region = "us-east-1"
+# AMI = "standard AMI of VyOS from AWS Marketplace"
+# Size of VM = "t2.micro"
+# AWS Region = "us-east-1"
+# After deploying the AWS instance and getting an IP address, the IP address is copied into the file
+#"ip.txt" and copied to the Ansible node for provisioning.
+##############################################################################
+
+provider "aws" {
+ access_key = var.access
+ secret_key = var.secret
+ region = var.region
+}
+
+variable "region" {
+ default = "us-east-1"
+ description = "AWS Region"
+}
+
+variable "ami" {
+ default = "ami-**************3b3" # ami image please enter your details
+ description = "Amazon Machine Image ID for VyOS"
+}
+
+variable "type" {
+ default = "t2.micro"
+ description = "Size of VM"
+}
+
+# my resource for VyOS
+
+resource "aws_instance" "myVyOSec2" {
+ ami = var.ami
+ key_name = "awsterraform" # Please enter your details from 1.2 of Preparation steps for deploying VyOS on AWS
+ security_groups = ["awsterraformsg"] # Please enter your details from 1.3 of Preparation steps for deploying VyOS on AWS
+ instance_type = var.type
+ tags = {
+ name = "VyOS System"
+ }
+}
+
+##############################################################################
+# Specific variable (to getting type "terraform plan"):
+# aws_instance.myVyOSec2.public_ip - the information about public IP address
+# of our instance, needs for provisioning and SSH connection from Ansible
+##############################################################################
+
+output "my_IP"{
+value = aws_instance.myVyOSec2.public_ip
+}
+
+##############################################################################
+# The IP address of the AWS instance is copied to the ip.txt file
+# on the local Terraform system. The ip.txt file contains the public
+# IP address in the format: xxx.xxx.xxx.xxx
+##############################################################################
+
+resource "local_file" "ip" {
+ content = aws_instance.myVyOSec2.public_ip
+ filename = "ip.txt"
+}
+
+#connecting to the Ansible control node using SSH connection
+
+##############################################################################
+# The "SSHconnection1" and "SSHconnection2" steps retrieve ip.txt
+# from the Terraform node and run the Ansible playbook remotely.
+##############################################################################
+
+resource "null_resource" "SSHconnection1" {
+depends_on = [aws_instance.myVyOSec2]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+
+# Copy the ip.txt file to the Ansible control node from the local
+# system
+ provisioner "file" {
+ source = "ip.txt"
+ destination = "/root/aws/ip.txt" # The folder of your Ansible project
+ }
+}
+
+resource "null_resource" "SSHconnection2" {
+depends_on = [aws_instance.myVyOSec2]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+# Run Ansible playbook on remote Linux OS
+provisioner "remote-exec" {
+ inline = [
+ "cd /root/aws/",
+ "ansible-playbook instance.yml" # more detailed in "File contents of Ansible for AWS"
+]
+}
+}
+```
+
+`var.tf`
+
+```none
+variable "password" {
+ description = "pass for Ansible"
+ type = string
+ sensitive = true
+}
+variable "host"{
+ description = "The IP of my Ansible"
+ type = string
+}
+variable "access" {
+ description = "my access_key for AWS"
+ type = string
+ sensitive = true
+}
+variable "secret" {
+ description = "my secret_key for AWS"
+ type = string
+ sensitive = true
+}
+```
+
+`versions.tf`
+
+```none
+ terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ }
+}
+```
+
+`terraform.tfvars`
+
+```none
+password = "" # password for Ansible SSH
+host = "" # IP of my Ansible
+access = "" # access_key for AWS
+secret = "" # secret_key for AWS
+```
+
+## Structure of files in Ansible for AWS
+
+```none
+.
+├── group_vars
+ └── all
+├── ansible.cfg
+├── mykey.pem
+└── instance.yml
+```
+
+## File contents of Ansible for AWS
+
+`ansible.cfg`
+
+```none
+[defaults]
+inventory = /root/aws/ip.txt
+host_key_checking= False
+private_key_file = /root/aws/awsterraform.pem # check the name
+remote_user=vyos
+```
+
+`mykey.pem`
+
+```none
+Copy your key.pem from AWS
+```
+
+`instance.yml`
+
+```none
+##############################################################################
+# About tasks:
+# "Wait 300 seconds, but only start checking after 60 seconds" -
+# attempts SSH connection every 60 seconds until 300 seconds
+# "Configure general settings for the VyOS hosts group" -
+# provisions the AWS VyOS node
+# Add all necessary VyOS commands under the "lines:" block
+##############################################################################
+
+- name: integration of terraform and ansible
+ hosts: all
+ gather_facts: 'no'
+
+ tasks:
+
+ - name: "Wait 300 seconds, but only start checking after 60 seconds"
+ wait_for_connection:
+ delay: 60
+ timeout: 300
+
+ - name: "Configure general settings for the VyOS hosts group"
+ vyos_config:
+ lines:
+ - set system name-server xxx.xxx.xxx.xxx
+ save:
+ true
+```
+
+`group_vars/all`
+
+```none
+ansible_connection: ansible.netcommon.network_cli
+ansible_network_os: vyos.vyos.vyos
+ansible_user: vyos
+```
+
+
+## Source files on GitHub
+
+All files related to deploying VyOS on AWS with Terraform and Ansible
+can be found in the [vyos-automation] repository.
+
+[group]: https://docs.aws.amazon.com/cli/latest/userguide/cli-services-ec2-sg.html
+[image]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html
+[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
+[link]: https://developer.hashicorp.com/terraform/intro
+[pair]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html
+[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/AWS_terraform_ansible_single_vyos_instance-main>
diff --git a/docs/automation/terraform/terraformAZ.md b/docs/automation/terraform/terraformAZ.md
new file mode 100644
index 00000000..05856824
--- /dev/null
+++ b/docs/automation/terraform/terraformAZ.md
@@ -0,0 +1,500 @@
+---
+lastproofread: '2026-03-19'
+---
+
+(terraformaz)=
+
+# Deploy VyOS on Microsoft Azure with Terraform and Ansible
+
+You can use Terraform to quickly deploy VyOS-based infrastructure
+on Microsoft Azure (hereafter referred to as *Azure*) and remove
+infrastructure when it's no longer needed.
+Additionally, you can use Ansible for provisioning.
+
+On this page you'll learn how to:
+
+- Create the necessary files for Terraform and Ansible.
+- Use Terraform to create a single instance on Azure and use Ansible for
+ provisioning.
+
+## Prepare to deploy VyOS with Terraform on Azure
+
+To create a single instance and install your configuration using
+Terraform, Ansible, and Azure, follow these steps:
+
+### Azure
+
+- Create an [Azure account](https://azure.microsoft.com/).
+
+### Terraform
+
+```{eval-rst}
+1. Create an UNIX or Windows instance.
+
+2. Download and install
+ `Terraform <https://developer.hashicorp.com/terraform/install>`__.
+
+3. Create the folder for example ``/root/azvyos/``.
+
+.. code-block:: none
+
+ mkdir /root/azvyos
+
+.. stop_vyoslinter
+
+4. Copy all files into your Terraform project "/root/azvyos"
+ (``vyos.tf``, ``var.tf``, ``terraform.tfvars``). For more details, see
+ `Structure of files in Terraform for Azure <#structure-of-files-in-terraform-for-azure>`_.
+
+.. start_vyoslinter
+
+5. Log in to Azure using the command:
+
+ .. code-block:: none
+
+ az login
+
+6. Run the following commands to initialize Terraform:
+
+ .. code-block:: none
+
+ cd /<your folder>
+ terraform init
+```
+
+
+### Ansible
+
+1. Create an UNIX instance either locally or in the cloud.
+
+2. Download and install Ansible
+
+3. Create a folder, for example `/root/az/`.
+
+4. Copy all files into your Ansible project `/root/az/` (`ansible.cfg`,
+ `instance.yml`, `all`). For more details, see
+ [Structure of files in Ansible for Azure](#structure-of-files-in-ansible-for-azure)
+
+### Deploy with Terraform
+
+Run the following commands on your Terraform instance:
+
+```none
+cd /<your folder>
+terraform plan
+terraform apply
+yes
+```
+
+After executing all the commands, your VyOS instance is deployed to
+Azure with your configuration.
+If you need to delete the instance, run the following command:
+
+```none
+terraform destroy
+```
+
+
+## Structure of files in Terraform for Azure
+
+```none
+.
+├── vyos.tf # The main script
+├── var.tf # File for the Terraform version.
+└── terraform.tfvars # Values for all variables (passwords,
+ # login, IP addresses, etc.)
+```
+
+
+## File contents of Terraform for Azure
+
+`vyos.tf`
+
+```none
+##############################################################################
+# HashiCorp Guide to Using Terraform on Azure
+# This Terraform configuration will create the following:
+# Resource group with a virtual network and subnet
+# A VyOS server without SSH key (only login+password)
+##############################################################################
+
+# Choose a provider
+
+provider "azurerm" {
+ features {}
+}
+
+# Create a resource group. In Azure, every resource belongs to a
+# resource group.
+
+resource "azurerm_resource_group" "azure_vyos" {
+ name = "${var.resource_group}"
+ location = "${var.location}"
+}
+
+# The next resource is a Virtual Network.
+
+resource "azurerm_virtual_network" "vnet" {
+ name = "${var.virtual_network_name}"
+ location = "${var.location}"
+ address_space = ["${var.address_space}"]
+ resource_group_name = "${var.resource_group}"
+}
+
+# Build a subnet to run your VMs.
+
+resource "azurerm_subnet" "subnet" {
+ name = "${var.prefix}subnet"
+ virtual_network_name = "${azurerm_virtual_network.vnet.name}"
+ resource_group_name = "${var.resource_group}"
+ address_prefixes = ["${var.subnet_prefix}"]
+}
+
+##############################################################################
+# Build a VyOS VM from the Marketplace.
+# To find the necessary image, use the command:
+#
+# az vm image list --offer vyos --all
+#
+# Now that you have a network, you can deploy a VyOS server.
+# An Azure Virtual Machine has several components. In this example,
+# you build a security group, a network interface, a public IP
+# address, a storage account, and finally the VM itself. Terraform
+# handles all the dependencies automatically, and each resource is
+# named with user-defined variables.
+##############################################################################
+
+
+# Security group to allow inbound access on port 22 (SSH)
+
+resource "azurerm_network_security_group" "vyos-sg" {
+ name = "${var.prefix}-sg"
+ location = "${var.location}"
+ resource_group_name = "${var.resource_group}"
+
+ security_rule {
+ name = "SSH"
+ priority = 100
+ direction = "Inbound"
+ access = "Allow"
+ protocol = "Tcp"
+ source_port_range = "*"
+ destination_port_range = "22"
+ source_address_prefix = "${var.source_network}"
+ destination_address_prefix = "*"
+ }
+}
+
+# A network interface.
+
+resource "azurerm_network_interface" "vyos-nic" {
+ name = "${var.prefix}vyos-nic"
+ location = "${var.location}"
+ resource_group_name = "${var.resource_group}"
+
+ ip_configuration {
+ name = "${var.prefix}ipconfig"
+ subnet_id = "${azurerm_subnet.subnet.id}"
+ private_ip_address_allocation = "Dynamic"
+ public_ip_address_id = "${azurerm_public_ip.vyos-pip.id}"
+ }
+}
+
+# Add a public IP address.
+
+resource "azurerm_public_ip" "vyos-pip" {
+ name = "${var.prefix}-ip"
+ location = "${var.location}"
+ resource_group_name = "${var.resource_group}"
+ allocation_method = "Dynamic"
+}
+
+# Build a virtual machine. This is a standard VyOS instance from
+# Marketplace.
+
+resource "azurerm_virtual_machine" "vyos" {
+ name = "${var.hostname}-vyos"
+ location = "${var.location}"
+ resource_group_name = "${var.resource_group}"
+ vm_size = "${var.vm_size}"
+
+ network_interface_ids = ["${azurerm_network_interface.vyos-nic.id}"]
+ delete_os_disk_on_termination = "true"
+
+# To find information about the plan, use the command:
+# az vm image list --offer vyos --all
+
+ plan {
+ publisher = "sentriumsl"
+ name = "vyos-1-3"
+ product = "vyos-1-2-lts-on-azure"
+ }
+
+ storage_image_reference {
+ publisher = "${var.image_publisher}"
+ offer = "${var.image_offer}"
+ sku = "${var.image_sku}"
+ version = "${var.image_version}"
+ }
+
+ storage_os_disk {
+ name = "${var.hostname}-osdisk"
+ managed_disk_type = "Standard_LRS"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ }
+
+ os_profile {
+ computer_name = "${var.hostname}"
+ admin_username = "${var.admin_username}"
+ admin_password = "${var.admin_password}"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+}
+
+data "azurerm_public_ip" "example" {
+ depends_on = ["azurerm_virtual_machine.vyos"]
+ name = "vyos-ip"
+ resource_group_name = "${var.resource_group}"
+}
+output "public_ip_address" {
+ value = data.azurerm_public_ip.example.ip_address
+}
+
+# IP of AZ instance copied to a file ip.txt in the local system.
+
+resource "local_file" "ip" {
+ content = data.azurerm_public_ip.example.ip_address
+ filename = "ip.txt"
+}
+
+# Connect to the Ansible control node via SSH
+
+resource "null_resource" "nullremote1" {
+depends_on = ["azurerm_virtual_machine.vyos"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+
+# Copy the ip.txt file to the Ansible control node from the local
+# system
+
+ provisioner "file" {
+ source = "ip.txt"
+ destination = "/root/az/ip.txt"
+ }
+}
+
+resource "null_resource" "nullremote2" {
+depends_on = ["azurerm_virtual_machine.vyos"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+
+# Run the Ansible playbook on the remote Linux OS
+
+provisioner "remote-exec" {
+
+ inline = [
+ "cd /root/az/",
+ "ansible-playbook instance.yml"
+]
+}
+}
+```
+
+`var.tf`
+
+```none
+##############################################################################
+# Variables File
+#
+# Default values for all variables used in Terraform code.
+##############################################################################
+
+variable "resource_group" {
+ description = "The name of your Azure Resource Group."
+ default = "my_resource_group"
+}
+
+variable "prefix" {
+ description = "This prefix will be included in the name of some resources."
+ default = "vyos"
+}
+
+variable "hostname" {
+ description = "Virtual machine hostname. Used for local hostname, DNS, and storage-related names."
+ default = "vyos_terraform"
+}
+
+variable "location" {
+ description = "The region where the virtual network is created."
+ default = "centralus"
+}
+
+variable "virtual_network_name" {
+ description = "The name for your virtual network."
+ default = "vnet"
+}
+
+variable "address_space" {
+ description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created."
+ default = "10.0.0.0/16"
+}
+
+variable "subnet_prefix" {
+ description = "The address prefix to use for the subnet."
+ default = "10.0.10.0/24"
+}
+
+variable "storage_account_tier" {
+ description = "Defines the storage tier. Valid options are Standard and Premium."
+ default = "Standard"
+}
+
+variable "storage_replication_type" {
+ description = "Defines the replication type to use for this storage account. Valid options include LRS, GRS etc."
+ default = "LRS"
+}
+
+# The most cost-effective size
+
+variable "vm_size" {
+ description = "Specifies the size of the virtual machine."
+ default = "Standard_B1s"
+}
+
+variable "image_publisher" {
+ description = "Name of the publisher of the image (az vm image list)"
+ default = "sentriumsl"
+}
+
+variable "image_offer" {
+ description = "Name of the offer (az vm image list)"
+ default = "vyos-1-2-lts-on-azure"
+}
+
+variable "image_sku" {
+ description = "Image SKU to apply (az vm image list)"
+ default = "vyos-1-3"
+}
+
+variable "image_version" {
+ description = "Version of the image to apply (az vm image list)"
+ default = "1.3.3"
+}
+
+variable "admin_username" {
+ description = "Administrator user name"
+ default = "vyos"
+}
+
+variable "admin_password" {
+ description = "Administrator password"
+ default = "Vyos0!"
+}
+
+variable "source_network" {
+ description = "Allow access from this network prefix. Defaults to '*'."
+ default = "*"
+}
+
+variable "password" {
+ description = "pass for Ansible"
+ type = string
+ sensitive = true
+}
+variable "host"{
+ description = "IP of my Ansible"
+}
+```
+
+`terraform.tfvars`
+
+```none
+password = "" # password for Ansible SSH
+host = "" # IP of my Ansible
+```
+
+
+## Structure of files in Ansible for Azure
+
+```none
+.
+├── group_vars
+ └── all
+├── ansible.cfg
+└── instance.yml
+```
+
+
+## File contents of Ansible for Azure
+
+`ansible.cfg`
+
+```none
+[defaults]
+inventory = /root/az/ip.txt
+host_key_checking= False
+remote_user=vyos
+```
+
+`instance.yml`
+
+```none
+##############################################################################
+# About tasks:
+# "Wait 300 seconds, but only start checking after 60 seconds" - Tries
+# to make SSH connection every 60 seconds until 300 seconds.
+# "Configure general settings for the VyOS hosts group" - Provision
+# the Azure VyOS node.
+# Add all necessary commands for VyOS under the block "lines:"
+##############################################################################
+
+
+- name: integration of terraform and ansible
+ hosts: all
+ gather_facts: 'no'
+
+ tasks:
+
+ - name: "Wait 300 seconds, but only start checking after 60 seconds"
+ wait_for_connection:
+ delay: 60
+ timeout: 300
+
+ - name: "Configure general settings for the VyOS hosts group"
+ vyos_config:
+ lines:
+ - set system name-server xxx.xxx.xxx.xxx
+ save:
+ true
+```
+
+`group_vars/all`
+
+```none
+ansible_connection: ansible.netcommon.network_cli
+ansible_network_os: vyos.vyos.vyos
+
+# user and password gets from terraform variables "admin_username" and "admin_password" in the file /root/azvyos/var.tf
+ansible_user: vyos
+ansible_ssh_pass: Vyos0!
+```
+
+
+## Source files on GitHub
+
+All files related to deploying VyOS on Azure with Terraform and Ansible
+can be found in the [vyos-automation] repository.
+
+[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Azure_terraform_ansible_single_vyos_instance-main>
diff --git a/docs/automation/terraform/terraformGoogle.md b/docs/automation/terraform/terraformGoogle.md
new file mode 100644
index 00000000..7236b045
--- /dev/null
+++ b/docs/automation/terraform/terraformGoogle.md
@@ -0,0 +1,703 @@
+---
+lastproofread: '2026-03-23'
+---
+
+(terraformgoogle)=
+
+# Deploy VyOS on Google Cloud with Terraform and Ansible
+
+Using Terraform, you can quickly deploy VyOS-based infrastructure on
+Google Cloud Platform (GCP) and remove the
+infrastructure when it's no longer needed.
+Additionally, you can use Ansible for provisioning.
+
+On this page you'll learn how to:
+
+- Create the necessary files for Terraform and Ansible.
+- Use Terraform to create a single instance on GCP and use Ansible for
+ provisioning.
+
+## Prepare to deploy VyOS with Terraform on GCP
+
+To create a single instance and install your configuration using
+Terraform, Ansible, and GCP, follow these steps:
+
+### GCP
+
+1. Create an account with GCP and a new project.
+
+```{image} /_static/images/project.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 50%
+```
+
+2. Create a service account and download your key (a JSON file).
+
+```{image} /_static/images/service.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 50%
+```
+
+```{image} /_static/images/key.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 50%
+```
+
+The .JSON file downloads automatically after you create it and looks
+like the following:
+
+```{image} /_static/images/json.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 50%
+```
+
+### Terraform
+
+1. Create an UNIX or Windows instance.
+
+2. Download and install
+ [Terraform](https://developer.hashicorp.com/terraform/install).
+
+3. Create the folder. For example, `/root/google`.
+
+```none
+mkdir /root/google
+```
+
+4. Copy all files into your Terraform project `/root/google`
+ (`vyos.tf`, `var.tf`, `terraform.tfvars`, `mykey.json`).
+ For more details,
+ see [Structure of files Terraform for Google Cloud](#structure-of-files-in-terraform-for-google-cloud)
+
+<!-- -->
+
+5. Run the following commands:
+
+```none
+cd /<your folder>
+terraform init
+```
+
+### Ansible
+
+1. Create an UNIX instance either locally or in the cloud.
+
+2. Download and install Ansible
+
+3. Create the folder for example /root/google/
+
+4. Copy all files into your Ansible project `/root/google/`
+ (`ansible.cfg`, `instance.yml`, `mykey.json`, and `all`). For more
+ details, see [Structure of files in Ansible for Google Cloud](#structure-of-files-in-ansible-for-google-cloud)
+
+You obtain `mykey.json` when you create a service account in GCP
+and download the key (a JSON file).
+
+### Deploy with Terraform
+
+Run the following commands on your Terraform instance:
+
+```none
+cd /<your folder>
+terraform plan
+terraform apply
+yes
+```
+
+## Create a GCP instance and check its configuration
+
+```none
+# terraform apply
+
+Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ + create
+
+Terraform will perform the following actions:
+
+ # google_compute_firewall.tcp_22[0] will be created
+ + resource "google_compute_firewall" "tcp_22" {
+ + creation_timestamp = (known after apply)
+ + destination_ranges = (known after apply)
+ + direction = (known after apply)
+ + enable_logging = (known after apply)
+ + id = (known after apply)
+ + name = "vyos-tcp-22"
+ + network = "default"
+ + priority = 1000
+ + project = "vyosproject"
+ + self_link = (known after apply)
+ + source_ranges = [
+ + "0.0.0.0/0",
+ ]
+ + target_tags = [
+ + "vyos-deployment",
+ ]
+
+ + allow {
+ + ports = [
+ + "22",
+ ]
+ + protocol = "tcp"
+ }
+ }
+
+ # google_compute_firewall.udp_500_4500[0] will be created
+ + resource "google_compute_firewall" "udp_500_4500" {
+ + creation_timestamp = (known after apply)
+ + destination_ranges = (known after apply)
+ + direction = (known after apply)
+ + enable_logging = (known after apply)
+ + id = (known after apply)
+ + name = "vyos-udp-500-4500"
+ + network = "default"
+ + priority = 1000
+ + project = "vyosproject"
+ + self_link = (known after apply)
+ + source_ranges = [
+ + "0.0.0.0/0",
+ ]
+ + target_tags = [
+ + "vyos-deployment",
+ ]
+
+ + allow {
+ + ports = [
+ + "500",
+ + "4500",
+ ]
+ + protocol = "udp"
+ }
+ }
+
+ # google_compute_instance.default will be created
+ + resource "google_compute_instance" "default" {
+ + can_ip_forward = true
+ + cpu_platform = (known after apply)
+ + current_status = (known after apply)
+ + deletion_protection = false
+ + effective_labels = (known after apply)
+ + guest_accelerator = (known after apply)
+ + id = (known after apply)
+ + instance_id = (known after apply)
+ + label_fingerprint = (known after apply)
+ + machine_type = "n2-highcpu-4"
+ + metadata = {
+ + "enable-oslogin" = "FALSE"
+ + "serial-port-enable" = "TRUE"
+ + "user-data" = ""
+ }
+ + metadata_fingerprint = (known after apply)
+ + min_cpu_platform = (known after apply)
+ + name = "vyos"
+ + project = "vyosproject"
+ + self_link = (known after apply)
+ + tags_fingerprint = (known after apply)
+ + terraform_labels = (known after apply)
+ + zone = "us-west1-a"
+
+ + boot_disk {
+ + auto_delete = true
+ + device_name = (known after apply)
+ + disk_encryption_key_sha256 = (known after apply)
+ + kms_key_self_link = (known after apply)
+ + mode = "READ_WRITE"
+ + source = (known after apply)
+
+ + initialize_params {
+ + image = "projects/sentrium-public/global/images/vyos-1-3-5-20231222143039"
+ + labels = (known after apply)
+ + provisioned_iops = (known after apply)
+ + provisioned_throughput = (known after apply)
+ + size = (known after apply)
+ + type = (known after apply)
+ }
+ }
+
+ + network_interface {
+ + internal_ipv6_prefix_length = (known after apply)
+ + ipv6_access_type = (known after apply)
+ + ipv6_address = (known after apply)
+ + name = (known after apply)
+ + network = "default"
+ + network_ip = (known after apply)
+ + nic_type = "GVNIC"
+ + stack_type = (known after apply)
+ + subnetwork = "default"
+ + subnetwork_project = (known after apply)
+
+ + access_config {
+ + nat_ip = (known after apply)
+ + network_tier = (known after apply)
+ }
+ }
+ }
+
+ # local_file.ip will be created
+ + resource "local_file" "ip" {
+ + content = (known after apply)
+ + content_base64sha256 = (known after apply)
+ + content_base64sha512 = (known after apply)
+ + content_md5 = (known after apply)
+ + content_sha1 = (known after apply)
+ + content_sha256 = (known after apply)
+ + content_sha512 = (known after apply)
+ + directory_permission = "0777"
+ + file_permission = "0777"
+ + filename = "ip.txt"
+ + id = (known after apply)
+ }
+
+ # null_resource.SSHconnection1 will be created
+ + resource "null_resource" "SSHconnection1" {
+ + id = (known after apply)
+ }
+
+ # null_resource.SSHconnection2 will be created
+ + resource "null_resource" "SSHconnection2" {
+ + id = (known after apply)
+ }
+
+Plan: 6 to add, 0 to change, 0 to destroy.
+
+Changes to Outputs:
+ + public_ip_address = (known after apply)
+╷
+│ Warning: Quoted references are deprecated
+│
+│ on vyos.tf line 126, in resource "null_resource" "SSHconnection1":
+│ 126: depends_on = ["google_compute_instance.default"]
+│
+│ In this context, references are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted references are now deprecated and will be removed in a
+│ future version of Terraform. Remove the quotes surrounding this reference to silence this warning.
+│
+│ (and one more similar warning elsewhere)
+╵
+
+Do you want to perform these actions?
+ Terraform will perform the actions described above.
+ Only 'yes' will be accepted to approve.
+
+ Enter a value: yes
+
+google_compute_firewall.udp_500_4500[0]: Creating...
+google_compute_firewall.tcp_22[0]: Creating...
+google_compute_instance.default: Creating...
+google_compute_firewall.udp_500_4500[0]: Still creating... [10s elapsed]
+google_compute_firewall.tcp_22[0]: Still creating... [10s elapsed]
+google_compute_instance.default: Still creating... [10s elapsed]
+google_compute_firewall.tcp_22[0]: Creation complete after 16s [id=projects/vyosproject/global/firewalls/vyos-tcp-22]
+google_compute_firewall.udp_500_4500[0]: Creation complete after 16s [id=projects/vyosproject/global/firewalls/vyos-udp-500-4500]
+google_compute_instance.default: Creation complete after 20s [id=projects/vyosproject/zones/us-west1-a/instances/vyos]
+null_resource.SSHconnection1: Creating...
+null_resource.SSHconnection2: Creating...
+null_resource.SSHconnection1: Provisioning with 'file'...
+null_resource.SSHconnection2: Provisioning with 'remote-exec'...
+null_resource.SSHconnection2 (remote-exec): Connecting to remote host via SSH...
+null_resource.SSHconnection2 (remote-exec): Host: 10.***.***.104
+null_resource.SSHconnection2 (remote-exec): User: root
+null_resource.SSHconnection2 (remote-exec): Password: true
+null_resource.SSHconnection2 (remote-exec): Private key: false
+null_resource.SSHconnection2 (remote-exec): Certificate: false
+null_resource.SSHconnection2 (remote-exec): SSH Agent: false
+null_resource.SSHconnection2 (remote-exec): Checking Host Key: false
+null_resource.SSHconnection2 (remote-exec): Target Platform: unix
+local_file.ip: Creating...
+local_file.ip: Creation complete after 0s [id=7d568c3b994a018c942a3cdb952ccbf3c729d0ca]
+null_resource.SSHconnection2 (remote-exec): Connected!
+null_resource.SSHconnection1: Creation complete after 4s [id=5175298735911137161]
+
+null_resource.SSHconnection2 (remote-exec): PLAY [integration of terraform and ansible] ************************************
+
+null_resource.SSHconnection2 (remote-exec): TASK [Wait 300 seconds, but only start checking after 60 seconds] **************
+null_resource.SSHconnection2: Still creating... [10s elapsed]
+null_resource.SSHconnection2: Still creating... [20s elapsed]
+null_resource.SSHconnection2: Still creating... [30s elapsed]
+null_resource.SSHconnection2: Still creating... [40s elapsed]
+null_resource.SSHconnection2: Still creating... [50s elapsed]
+null_resource.SSHconnection2: Still creating... [1m0s elapsed]
+null_resource.SSHconnection2: Still creating... [1m10s elapsed]
+null_resource.SSHconnection2 (remote-exec): ok: [104.***.***.158]
+
+null_resource.SSHconnection2 (remote-exec): TASK [Configure general settings for the vyos hosts group] *********************
+null_resource.SSHconnection2: Still creating... [1m20s elapsed]
+null_resource.SSHconnection2 (remote-exec): changed: [104.***.***.158]
+
+null_resource.SSHconnection2 (remote-exec): PLAY RECAP *********************************************************************
+null_resource.SSHconnection2 (remote-exec): 104.***.***.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+
+null_resource.SSHconnection2: Creation complete after 1m22s [id=3355727070503709742]
+
+Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
+
+Outputs:
+
+public_ip_address = "104.***.***.158"
+```
+
+After running all the commands, your VyOS instance is deployed on
+GCP with your specified configuration.
+To delete the instance, type the following command:
+
+```none
+terraform destroy
+```
+
+## Troubleshooting
+
+- Increase the timeout value in `instance.yml` from 300 seconds to
+ 500 seconds or more (depends on your location). Ensure that the
+ security group allows access to the instance.
+- If Terraform doesn't connect via SSH to your Ansible instance:
+ Check the correct login and password in the `VyOS.tf` file.
+
+```none
+connection {
+ type = "ssh"
+ user = "root" # open root access using login and password on your Ansible
+ password = var.password # check password in the file terraform.tfvars isn't empty
+ host = var.host # check the correct IP address of your Ansible host
+}
+```
+
+Verify that Ansible can ping from Terraform.
+
+## Structure of files in Terraform for Google Cloud
+
+```none
+.
+├── vyos.tf # The main script
+├── ***.JSON # The credential file from GCP
+├── var.tf # The file of all variables in "vyos.tf"
+└── terraform.tfvars # The value of all variables (passwords, login, IP addresses and so on)
+```
+
+## File contents of Terraform for Google Cloud
+
+`vyos.tf`
+
+```none
+##############################################################################
+# Build a VyOS VM from the Marketplace
+#
+# After deploying the GCP instance and getting an IP address, the IP address is copied into the file
+#"ip.txt" and copied to the Ansible node for provisioning.
+##############################################################################
+
+terraform {
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ }
+ }
+}
+
+provider "google" {
+ project = var.project_id
+ request_timeout = "60s"
+ credentials = file(var.gcp_auth_file)
+}
+
+locals {
+ network_interfaces = [for i, n in var.networks : {
+ network = n,
+ subnetwork = length(var.sub_networks) > i ? element(var.sub_networks, i) : null
+ external_ip = length(var.external_ips) > i ? element(var.external_ips, i) : "NONE"
+ }
+ ]
+}
+
+resource "google_compute_instance" "default" {
+ name = var.goog_cm_deployment_name
+ machine_type = var.machine_type
+ zone = var.zone
+
+ metadata = {
+ enable-oslogin = "FALSE"
+ serial-port-enable = "TRUE"
+ user-data = var.vyos_user_data
+ }
+ boot_disk {
+ initialize_params {
+ image = var.image
+ }
+ }
+
+ can_ip_forward = true
+
+ dynamic "network_interface" {
+ for_each = local.network_interfaces
+ content {
+ network = network_interface.value.network
+ subnetwork = network_interface.value.subnetwork
+ nic_type = "GVNIC"
+ dynamic "access_config" {
+ for_each = network_interface.value.external_ip == "NONE" ? [] : [1]
+ content {
+ nat_ip = network_interface.value.external_ip == "EPHEMERAL" ? null : network_interface.value.external_ip
+ }
+ }
+ }
+ }
+}
+
+resource "google_compute_firewall" "tcp_22" {
+ count = var.enable_tcp_22 ? 1 : 0
+
+ name = "${var.goog_cm_deployment_name}-tcp-22"
+ network = element(var.networks, 0)
+
+ allow {
+ ports = ["22"]
+ protocol = "tcp"
+ }
+
+ source_ranges = ["0.0.0.0/0"]
+
+ target_tags = ["${var.goog_cm_deployment_name}-deployment"]
+}
+
+resource "google_compute_firewall" "udp_500_4500" {
+ count = var.enable_udp_500_4500 ? 1 : 0
+
+ name = "${var.goog_cm_deployment_name}-udp-500-4500"
+ network = element(var.networks, 0)
+
+allow {
+ ports = ["500", "4500"]
+ protocol = "udp"
+}
+
+source_ranges = ["0.0.0.0/0"]
+
+ target_tags = ["${var.goog_cm_deployment_name}-deployment"]
+}
+
+output "public_ip_address" {
+ value = google_compute_instance.default.network_interface[0].access_config[0].nat_ip
+}
+
+##############################################################################
+#
+# IP of google instance copied to a file ip.txt in local system Terraform
+# ip.txt looks like:
+# cat ./ip.txt
+# ххх.ххх.ххх.ххх
+##############################################################################
+
+resource "local_file" "ip" {
+ content = google_compute_instance.default.network_interface[0].access_config[0].nat_ip
+ filename = "ip.txt"
+}
+
+#connecting to the Ansible control node using SSH connection
+
+##############################################################################
+# Steps "SSHconnection1" and "SSHconnection2" need to get file ip.txt from the terraform node and start remotely the playbook of Ansible.
+##############################################################################
+
+resource "null_resource" "SSHconnection1" {
+depends_on = ["google_compute_instance.default"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+
+#copying the ip.txt file to the Ansible control node from local system
+
+ provisioner "file" {
+ source = "ip.txt"
+ destination = "/root/google/ip.txt" # The folder of your Ansible project
+ }
+}
+
+resource "null_resource" "SSHconnection2" {
+depends_on = ["google_compute_instance.default"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.password
+ host = var.host
+}
+
+#command to run Ansible playbook on remote Linux OS
+
+provisioner "remote-exec" {
+ inline = [
+ "cd /root/google/",
+ "ansible-playbook instance.yml" # more detailed in "File contents of Ansible for Google Cloud"
+]
+}
+}
+```
+
+`var.tf`
+
+```none
+variable "image" {
+ type = string
+ default = "projects/sentrium-public/global/images/vyos-1-3-5-20231222143039"
+}
+
+variable "project_id" {
+ type = string
+}
+
+variable "zone" {
+ type = string
+}
+
+##############################################################################
+# You can choose a lower cost machine type than n2-highcpu-4
+##############################################################################
+
+variable "machine_type" {
+ type = string
+ default = "n2-highcpu-4"
+}
+
+variable "networks" {
+ description = "The network name to attach the VM instance."
+ type = list(string)
+ default = ["default"]
+}
+
+variable "sub_networks" {
+ description = "The sub network name to attach the VM instance."
+ type = list(string)
+ default = ["default"]
+}
+
+variable "external_ips" {
+ description = "The external IPs assigned to the VM for public access."
+ type = list(string)
+ default = ["EPHEMERAL"]
+}
+
+variable "enable_tcp_22" {
+ description = "Allow SSH traffic from the Internet"
+ type = bool
+ default = true
+}
+
+variable "enable_udp_500_4500" {
+ description = "Allow IKE/IPSec traffic from the Internet"
+ type = bool
+ default = true
+}
+
+variable "vyos_user_data" {
+ type = string
+ default = ""
+}
+
+// Marketplace requires this variable name to be declared
+variable "goog_cm_deployment_name" {
+ description = "VyOS Universal Router Deployment"
+ type = string
+ default = "vyos"
+}
+
+# GCP authentication file
+variable "gcp_auth_file" {
+ type = string
+ description = "GCP authentication file"
+}
+
+variable "password" {
+ description = "pass for Ansible"
+ type = string
+ sensitive = true
+}
+variable "host"{
+ description = "The IP of my Ansible"
+ type = string
+}
+```
+
+`terraform.tfvars`
+
+```none
+##############################################################################
+# Must be filled in
+##############################################################################
+
+zone = "us-west1-a"
+gcp_auth_file = "/root/***/***.json" # path of your .json file
+project_id = "" # the google project
+password = "" # password for Ansible SSH
+host = "" # IP of my Ansible
+```
+
+## Structure of files in Ansible for Google Cloud
+
+```none
+.
+├── group_vars
+ └── all
+├── ansible.cfg
+└── instance.yml
+```
+
+## File contents of Ansible for Google Cloud
+
+`ansible.cfg`
+
+```none
+[defaults]
+inventory = /root/google/ip.txt
+host_key_checking= False
+remote_user=vyos
+```
+
+`instance.yml`
+
+```none
+##############################################################################
+# About tasks:
+# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds
+# "Configure general settings for the VyOS hosts group" - make provisioning into Google Cloud VyOS node
+# Add all necessary VyOS commands under the "lines:" block
+##############################################################################
+
+
+- name: integration of terraform and ansible
+ hosts: all
+ gather_facts: 'no'
+
+ tasks:
+
+ - name: "Wait 300 seconds, but only start checking after 60 seconds"
+ wait_for_connection:
+ delay: 60
+ timeout: 300
+
+ - name: "Configure general settings for the VyOS hosts group"
+ vyos_config:
+ lines:
+ - set system name-server xxx.xxx.xxx.xxx
+ save:
+ true
+```
+
+`group_vars/all`
+
+```none
+ansible_connection: ansible.netcommon.network_cli
+ansible_network_os: vyos.vyos.vyos
+ansible_user: vyos
+ansible_ssh_pass: vyos
+```
+
+
+## Source files on GitHub
+
+All files related to deploying VyOS on Google Cloud Platform with
+Terraform and Ansible can be found in the [vyos-automation] repository.
+
+[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Google_terraform_ansible_single_vyos_instance-main>
diff --git a/docs/automation/terraform/terraformvSphere.md b/docs/automation/terraform/terraformvSphere.md
new file mode 100644
index 00000000..8bbb91e9
--- /dev/null
+++ b/docs/automation/terraform/terraformvSphere.md
@@ -0,0 +1,389 @@
+---
+lastproofread: '2026-03-23'
+---
+
+(terraformvSphere)=
+
+# Deploy VyOS on VMware vSphere with Terraform and Ansible
+
+You can use Terraform to quickly deploy VyOS-based infrastructure
+on VMware vSphere (hereafter referred to as *vSphere*) and remove
+infrastructure when it's no longer needed.
+Additionally, you can use Ansible for provisioning.
+
+On this page you'll learn how to:
+
+- Create the necessary files for Terraform and Ansible.
+- Use Terraform to create a single instance on vSphere and use Ansible for
+ provisioning.
+
+## Prepare to deploy VyOS with Terraform on vSphere
+
+To create a single instance and install your configuration using
+Terraform, Ansible, and vSphere, follow these steps:
+
+### vSphere
+
+- Add all necessary data to the `terraform.tfvars`
+ [file](<https://github.com/vyos/vyos-automation/blob/main/TerraformCloud/Vsphere_terraform_ansible_single_vyos_instance-main/terraform.tfvars>)
+ and create resources.
+
+### Terraform
+
+- Create an UNIX or Windows instance.
+- Download and install
+ [Terraform](https://developer.hashicorp.com/terraform/install).
+- Create the folder for example `/root/vsphereterraform`.
+
+```none
+mkdir /root/vsphereterraform
+```
+
+- Copy all files into your Terraform project `/root/vsphereterraform`
+ (`vyos.tf`, `var.tf`, `terraform.tfvars`, `version.tf`).
+ For more details,
+ see [Structure of files in Terraform for vSphere](#structure-of-files-in-terraform-for-vsphere)
+- Run the following commands:
+
+```none
+cd /<your folder>
+terraform init
+```
+
+
+### Ansible
+
+- Create an UNIX instance either locally or in the cloud.
+- Download and install Ansible.
+- Create the folder. For example, `/root/vsphereterraform/`.
+- Copy all files into your Ansible project `/root/vsphereterraform/`
+ (`ansible.cfg`, `instance.yml`, `all`). For more details, see
+ [Structure of files in Ansible for vSphere](#structure-of-files-in-ansible-for-vsphere)
+
+### Deploy with Terraform
+
+Run the following commands on your Terraform instance:
+
+```none
+cd /<your folder>
+terraform plan
+terraform apply
+yes
+```
+
+After executing these commands, your VyOS instance is deployed to
+vSphere with your configuration.
+If you need to delete the instance, run the following command:
+
+```none
+terraform destroy
+```
+
+## Structure of files in Terraform for vSphere
+
+```none
+.
+├── vyos.tf # The main script.
+├── versions.tf # File for Terraform version.
+├── var.tf # File for Terraform version.
+└── terraform.tfvars # Values for all variables (passwords,
+ # login, IP addresses, etc.).
+```
+
+## File contents of Terraform for vSphere
+
+`vyos.tf`
+
+```none
+provider "vsphere" {
+ user = var.vsphere_user
+ password = var.vsphere_password
+ vsphere_server = var.vsphere_server
+ allow_unverified_ssl = true
+}
+
+data "vsphere_datacenter" "datacenter" {
+ name = var.datacenter
+}
+
+data "vsphere_datastore" "datastore" {
+ name = var.datastore
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+}
+
+data "vsphere_compute_cluster" "cluster" {
+ name = var.cluster
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+}
+
+data "vsphere_resource_pool" "default" {
+ name = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources/terraform") # set as you need
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+}
+
+data "vsphere_host" "host" {
+ name = var.host
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+}
+
+data "vsphere_network" "network" {
+ name = var.network_name
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+}
+
+# Deployment of VM from Remote OVF
+resource "vsphere_virtual_machine" "vmFromRemoteOvf" {
+ name = var.remotename
+ datacenter_id = data.vsphere_datacenter.datacenter.id
+ datastore_id = data.vsphere_datastore.datastore.id
+ host_system_id = data.vsphere_host.host.id
+ resource_pool_id = data.vsphere_resource_pool.default.id
+ network_interface {
+ network_id = data.vsphere_network.network.id
+ }
+ wait_for_guest_net_timeout = 2
+ wait_for_guest_ip_timeout = 2
+
+ ovf_deploy {
+ allow_unverified_ssl_cert = true
+ remote_ovf_url = var.url_ova
+ disk_provisioning = "thin"
+ ip_protocol = "IPv4"
+ ip_allocation_policy = "dhcpPolicy"
+ ovf_network_map = {
+ "Network 1" = data.vsphere_network.network.id
+ "Network 2" = data.vsphere_network.network.id
+ }
+ }
+ vapp {
+ properties = {
+ "password" = "12345678",
+ "local-hostname" = "terraform_vyos"
+ }
+ }
+}
+
+output "ip" {
+ description = "default ip address of the deployed VM"
+ value = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address
+}
+
+# IP of vSphere instance copied to a file ip.txt in local system
+
+resource "local_file" "ip" {
+ content = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address
+ filename = "ip.txt"
+}
+
+#Connecting to the Ansible control node using SSH connection
+
+resource "null_resource" "nullremote1" {
+depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.ansiblepassword
+ host = var.ansiblehost
+
+}
+
+# Copying the ip.txt file to the Ansible control node from local system
+
+ provisioner "file" {
+ source = "ip.txt"
+ destination = "/root/vsphere/ip.txt"
+ }
+}
+
+resource "null_resource" "nullremote2" {
+depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"]
+connection {
+ type = "ssh"
+ user = "root"
+ password = var.ansiblepassword
+ host = var.ansiblehost
+}
+
+# Command to run ansible playbook on remote Linux OS
+
+provisioner "remote-exec" {
+
+ inline = [
+ "cd /root/vsphere/",
+ "ansible-playbook instance.yml"
+]
+}
+}
+```
+
+`versions.tf`
+
+```none
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+terraform {
+ required_providers {
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "2.4.0"
+ }
+ }
+}
+```
+
+`var.tf`
+
+```none
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+variable "vsphere_server" {
+ description = "vSphere server"
+ type = string
+}
+
+variable "vsphere_user" {
+ description = "vSphere username"
+ type = string
+}
+
+variable "vsphere_password" {
+ description = "vSphere password"
+ type = string
+ sensitive = true
+}
+
+variable "datacenter" {
+ description = "vSphere data center"
+ type = string
+}
+
+variable "cluster" {
+ description = "vSphere cluster"
+ type = string
+}
+
+variable "datastore" {
+ description = "vSphere datastore"
+ type = string
+}
+
+variable "network_name" {
+ description = "vSphere network name"
+ type = string
+}
+
+variable "host" {
+ description = "Name of your host"
+ type = string
+}
+
+variable "remotename" {
+ description = "The name of your VM"
+ type = string
+}
+
+variable "url_ova" {
+ description = "The URL to the .OVA file or cloud storage"
+ type = string
+}
+
+variable "ansiblepassword" {
+ description = "Ansible password"
+ type = string
+}
+
+variable "ansiblehost" {
+ description = "Ansible host name or IP"
+ type = string
+}
+```
+
+`terraform.tfvars`
+
+```none
+vsphere_user = ""
+vsphere_password = ""
+vsphere_server = ""
+datacenter = ""
+datastore = ""
+cluster = ""
+network_name = ""
+host = ""
+url_ova = ""
+ansiblepassword = ""
+ansiblehost = ""
+remotename = ""
+```
+
+## Structure of files in Ansible for vSphere
+
+```none
+.
+├── group_vars
+ └── all
+├── ansible.cfg
+└── instance.yml
+```
+
+## File contents of Ansible for vSphere
+
+`ansible.cfg`
+
+```none
+[defaults]
+inventory = /root/vsphere/ip.txt
+host_key_checking= False
+remote_user=vyos
+```
+
+`instance.yml`
+
+```none
+##############################################################################
+# About tasks:
+# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds
+# "Configure general settings for the VyOS hosts group" - make provisioning into vSphere VyOS node
+# You have to add all necessary cammans of VyOS under the block "lines:"
+##############################################################################
+
+
+- name: integration of terraform and ansible
+ hosts: all
+ gather_facts: 'no'
+
+ tasks:
+
+ - name: "Wait 300 seconds, but only start checking after 60 seconds"
+ wait_for_connection:
+ delay: 60
+ timeout: 300
+ - name: "Configure general settings for the VyOS hosts group"
+ vyos_config:
+ lines:
+ - set system name-server 192.0.2.1
+ - set system name-server 192.0.2.1
+ save:
+ true
+```
+
+`group_vars/all`
+
+```none
+ansible_connection: ansible.netcommon.network_cli
+ansible_network_os: vyos.vyos.vyos
+
+# user and password gets from terraform variables "admin_username" and "admin_password"
+ansible_user: vyos
+# get from vyos.tf "vapp"
+ansible_ssh_pass: 12345678
+```
+
+
+## Source files on GitHub
+
+All files related to deploying VyOS on vSphere with Terraform and Ansible
+can be found in the [vyos-automation] repository.
+
+[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Vsphere_terraform_ansible_single_vyos_instance-main>
diff --git a/docs/automation/terraform/terraformvyos.md b/docs/automation/terraform/terraformvyos.md
new file mode 100644
index 00000000..bfe1b6d1
--- /dev/null
+++ b/docs/automation/terraform/terraformvyos.md
@@ -0,0 +1,44 @@
+---
+lastproofread: '2024-03-03'
+---
+
+(terraformvyos)=
+
+# Terraform for VyOS
+
+VyOS supports development infrastructure via Terraform and
+provisioning via Ansible. Terraform allows you to automate the
+process of deploying instances on many cloud and virtual
+platforms. In this article, we will look at using Terraform to
+deploy VyOS on platforms - AWS, Azure, and vSphere. For more
+details about Terraform please have a look at [link].
+
+You will need to [install] Terraform before proceeding.
+
+Structure of files in the standard Terraform project:
+
+```none
+.
+├── main.tf # The main script
+├── version.tf # File for the changing version of Terraform.
+├── variables.tf # The file of all variables in "main.tf"
+└── terraform.tfvars # The value of all variables (passwords, login, IP addresses and so on)
+```
+
+General commands that we will use for running Terraform scripts
+
+```none
+cd /<your folder> # go to the Terraform project
+terraform init # install all add-ons and providers (AWS, Azure, and so on)
+terraform plan # show what is changing
+terraform apply # run script
+yes # apply running
+```
+
+% stop_vyoslinter
+
+% start_vyoslinter
+
+[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
+[link]: https://developer.hashicorp.com/terraform/intro
+
diff --git a/docs/automation/vyos-ansible.md b/docs/automation/vyos-ansible.md
new file mode 100644
index 00000000..8e94b251
--- /dev/null
+++ b/docs/automation/vyos-ansible.md
@@ -0,0 +1,101 @@
+---
+lastproofread: '2026-04-13'
+---
+
+(vyos-ansible)=
+
+# Ansible
+
+VyOS can be configured using Ansible. To use it, install the `ansible`
+package and the `python3-paramiko` module.
+
+## Directory structure
+
+Arrange your Ansible project directory as follows:
+
+```none
+.
+├── ansible.cfg
+├── files
+│ └── id_rsa_docker.pub
+├── hosts
+└── main.yml
+```
+
+
+## File contents
+
+- `ansible.cfg`
+
+```none
+[defaults]
+host_key_checking = no
+retry_files_enabled = False
+ANSIBLE_INVENTORY_UNPARSED_FAILED = true
+```
+
+- `id_rsa_docker.pub`
+
+Contains only the SSH public key.
+
+```none
+AAAAB3NzaC1yc2EAAAADAQABAAABAQCoDgfhQJuJRFWJijHn7ZinZ3NWp4hWVrt7HFcvn0kgtP/5PeCtMt
+```
+
+- `hosts`
+
+Defines the target VyOS devices and the connection parameters required to reach
+them.
+
+```none
+[vyos_hosts]
+r11 ansible_ssh_host=192.0.2.11
+
+[vyos_hosts:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=vyos
+ansible_ssh_pass=vyos
+ansible_network_os=vyos
+ansible_connection=network_cli
+```
+
+- `main.yml`
+
+Defines the configuration tasks to be applied to the target VyOS devices.
+
+```none
+---
+
+- hosts: r11
+
+ connection: network_cli
+ gather_facts: 'no'
+
+ tasks:
+ - name: Configure remote r11
+ vyos_config:
+ lines:
+ - set system host-name r11
+ - set system name-server 203.0.113.254
+ - set service ssh disable-host-validation
+ - set system login user vyos authentication public-keys docker@work type ssh-rsa
+ - set system login user vyos authentication public-keys docker@work key "{{ lookup('file', 'id_rsa_docker.pub') }}"
+ - set system time-zone America/Los_Angeles
+ - set interfaces ethernet eth0 description WAN
+```
+
+
+## Run Ansible
+
+To apply the configuration, use the following command:
+
+```none
+$ ansible-playbook -i hosts main.yml
+
+PLAY [r11] **************************************************************************************************
+
+TASK [Configure remote r11] *********************************************************************************
+
+PLAY RECAP **************************************************************************************************
+r11 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+```
diff --git a/docs/automation/vyos-api.md b/docs/automation/vyos-api.md
new file mode 100644
index 00000000..fd753838
--- /dev/null
+++ b/docs/automation/vyos-api.md
@@ -0,0 +1,587 @@
+---
+lastproofread: '2026-04-13'
+---
+
+(vyosapi)=
+
+# VyOS API
+
+For instructions on configuring and enabling the API, see {ref}`http-api`.
+
+## Authentication
+
+All endpoints, except one, accept HTTP POST requests. The API key must be
+provided as the `key` field in the form data. The only public endpoint
+accepts HTTP GET requests and supports optional query parameters.
+
+Below are examples of API requests in cURL and Python. All other code examples
+in this documentation use cURL.
+
+```none
+curl --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "showConfig", "path": []}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+```
+
+```python
+import requests
+url = "https://vyos/retrieve"
+payload={'data': '{"op": "showConfig", "path": []}',
+ 'key': 'MY-HTTPS-API-PLAINTEXT-KEY'
+ }
+headers = {}
+response = requests.request("POST", url, headers=headers, data=payload)
+print(response.text)
+```
+
+
+## API endpoints
+
+### /info
+
+This is the only API endpoint that does not require authentication and can be
+accessed by anonymous users. The info endpoint returns general system
+information, including the VyOS version, system hostname, and a welcome banner.
+
+This endpoint accepts **only** HTTP GET requests.
+
+```none
+curl --location --request GET 'https://vyos/info'
+
+response
+{
+ "success": true,
+ "data": {
+ "version": "1.5-rolling",
+ "hostname": "vyos",
+ "banner": "Welcome to VyOS"
+ },
+ "error": null
+}
+```
+
+**Query parameters**
+
+This endpoint accepts two optional query parameters, version and hostname. Each
+parameter accepts values convertible to Boolean (e.g., `yes/no`, `1/0`, or
+`true/false`) to control the inclusion of related fields in the response.
+
+If no query parameters are provided, both parameters default to `true`.
+
+```none
+curl --location --request GET 'https://vyos/info?version=1&hostname=1'
+
+response {
+ "success": true,
+ "data": {
+ "version": "1.5-rolling",
+ "hostname": "vyos",
+ "banner": "Welcome to VyOS"
+ },
+ "error": null
+}
+```
+
+If either parameter is set to a value corresponding to false, its field is
+returned as an empty string in the response:
+
+```none
+curl --location --request GET 'https://vyos/info?version=0&hostname=1'
+
+response {
+ "success": true,
+ "data": {
+ "version": "",
+ "hostname": "vyos",
+ "banner": "Welcome to VyOS"
+ },
+ "error": null
+}
+```
+
+You do not need to specify both parameters if you want to hide only one. Any
+missing query parameter defaults to true.
+
+```none
+curl --location --request GET 'https://vyos/info?hostname=no'
+
+response {
+ "success": true,
+ "data": {
+ "version": "1.5-rolling",
+ "hostname": "",
+ "banner": "Welcome to VyOS"
+ },
+ "error": null
+}
+```
+
+Note that while you can disable output for both `hostname` and `version`,
+the `banner` is always included in the response.
+
+:::{Important}
+The endpoint accepts **ONLY** `hostname` and `version` query
+parameters. Including any other parameters results in an HTTP 400 Bad Request.
+:::
+
+```none
+curl --location --request GET \
+ 'https://192.168.56.119/info?hostname=1&url=https://evilsite.com'
+
+response {
+ "success": false,
+ "error": "{'type': 'extra_forbidden', 'loc': ('query', 'url'), 'msg': 'Extra inputs are not permitted', 'input': 'https://evilsite.com'}",
+ "data": null
+}
+```
+
+Values passed to the query string are validated to ensure they are strictly
+Boolean. Other data types are not accepted.
+
+```none
+curl --location --request GET 'https://vyos/info?hostname=1; eval"sudo rm -rf /"'
+
+response
+{
+ "success": false,
+ "error": "{'type': 'bool_parsing', 'loc': ('query', 'hostname'), 'msg': 'Input should be a valid boolean, unable to interpret input', 'input': '1; eval \"sudo rm -rf /\"'}",
+ "data": null
+}
+```
+
+
+### /retrieve
+
+The `/retrieve` endpoint returns either specific parts or the entire
+configuration.
+
+To retrieve the entire configuration, pass an empty list to the `path` field.
+
+```none
+curl --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "showConfig", "path": []}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+
+response (shortened)
+{
+ "success": true,
+ "data": {
+ "interfaces": {
+ "ethernet": {
+ "eth0": {
+ "address": "dhcp",
+ "duplex": "auto",
+ "hw-id": "50:00:00:01:00:00",
+ "speed": "auto"
+ },
+ "eth1": {
+ "duplex": "auto",
+ "hw-id": "50:00:00:01:00:01",
+ "speed": "auto"
+ ...
+ },
+ "error": null
+}
+```
+
+To retrieve a specific configuration part, such as `system syslog`, specify
+the desired path.
+
+```none
+curl -k --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "showConfig", "path": ["system", "syslog"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+
+response:
+{
+ "success": true,
+ "data": {
+ "global": {
+ "facility": {
+ "all": {
+ "level": "info"
+ },
+ "protocols": {
+ "level": "debug"
+ }
+ }
+ }
+ },
+ "error": null
+}
+```
+
+If you only need the value of a multi-valued node, use the `returnValues`
+operation.
+
+For example, to get the addresses of a `dum0` interface:
+
+```none
+curl -k --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "returnValues", "path": ["interfaces","dummy","dum0","address"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": [
+ "10.10.10.10/24",
+ "10.10.10.11/24",
+ "10.10.10.12/24"
+ ],
+ "error": null
+}
+```
+
+To check whether a configuration path exists, use the `exists` operation. It
+returns `true` for an existing path:
+
+```none
+curl -k --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "exists", "path": ["service","https","api"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": true,
+ "error": null
+}
+```
+
+It returns `false` for a non-existing path:
+
+```none
+curl -k --location --request POST 'https://vyos/retrieve' \
+--form data='{"op": "exists", "path": ["service","non","existent","path"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": false,
+ "error": null
+}
+```
+
+
+### /reset
+
+The `/reset` endpoint runs the `reset` command.
+
+```none
+curl --location --request POST 'https://vyos/reset' \
+--form data='{"op": "reset", "path": ["ip", "bgp", "192.0.2.11"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "",
+ "error": null
+}
+```
+
+
+### /reboot
+
+To initiate a reboot, use the `/reboot` endpoint.
+
+```none
+curl --location --request POST 'https://vyos/reboot' \
+--form data='{"op": "reboot", "path": ["now"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "",
+ "error": null
+}
+```
+
+
+### /poweroff
+
+To power off the system, use the `/poweroff` endpoint.
+
+```none
+curl --location --request POST 'https://vyos/poweroff' \
+--form data='{"op": "poweroff", "path": ["now"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "",
+ "error": null
+}
+```
+
+
+### /image
+
+To add or delete an image, use the `/image` endpoint.
+
+To add an image:
+
+```none
+curl -k --location --request POST 'https://vyos/image' \
+--form data='{"op": "add", "url": "https://downloads.vyos.io/rolling/current/amd64/vyos-rolling-latest.iso"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response (shortened):
+{
+ "success": true,
+ "data": "Trying to fetch ISO file from https://downloads.vyos.io/rolling-latest.iso\n
+ ...
+ Setting up grub configuration...\nDone.\n",
+ "error": null
+}
+```
+
+To delete an image, for example `1.3-rolling-202006070117`:
+
+```none
+curl -k --location --request POST 'https://vyos/image' \
+--form data='{"op": "delete", "name": "1.3-rolling-202006070117"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "Deleting the \"1.3-rolling-202006070117\" image...\nDone\n",
+ "error": null
+}
+```
+
+
+### /show
+
+The `/show` endpoint runs operational mode commands and returns the resulting
+output.
+
+For example, to show the installed images:
+
+```none
+curl -k --location --request POST 'https://vyos/show' \
+--form data='{"op": "show", "path": ["system", "image"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "The system currently has the following image(s) installed:\n\n
+ 1: 1.4-rolling-202102280559 (default boot)\n
+ 2: 1.4-rolling-202102230218\n
+ 3: 1.3-beta-202102210443\n\n",
+ "error": null
+}
+```
+
+
+### /generate
+
+The `/generate` endpoint runs a `generate` command.
+
+```none
+curl -k --location --request POST 'https://vyos/generate' \
+--form data='{"op": "generate", "path": ["pki", "wireguard", "key-pair"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "Private key: CFZR2eyhoVZwk4n3JFPMJx3E145f1EYgDM+ubytXYVY=\n
+ Public key: jjtpPT8ycI1Q0bNtrWuxAkO4k88Xwzg5VHV9xGZ58lU=\n\n",
+ "error": null
+}
+```
+
+
+### /configure
+
+The `/configure` endpoint accepts `set`, `delete`, and `comment` commands.
+
+To apply a `set` command:
+
+```none
+curl -k --location --request POST 'https://vyos/configure' \
+--form data='{"op": "set", "path": ["interfaces", "dummy", "dum1", "address", "10.11.0.1/32"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+To apply a `delete` command:
+
+```none
+curl -k --location --request POST 'https://vyos/configure' \
+--form data='{"op": "delete", "path": ["interfaces", "dummy", "dum1", "address", "10.11.0.1/32"]}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+The API processes each request in a session and commits it. For components such
+as DHCP and PPPoE servers, IPsec, VXLAN, and other tunnels, VyOS requires the
+entire configuration block for a commit.
+
+The endpoint can process multiple commands if you pass them as a list to
+the `data` field.
+
+```none
+curl -k --location --request POST 'https://vyos/configure' \
+--form data='[{"op": "set","path":["interfaces","vxlan","vxlan1","remote","203.0.113.99"]}, {"op": "set","path":["interfaces","vxlan","vxlan1","vni","1"]}]' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+
+### /config-file
+
+The `/config-file` endpoint allows you to save, load, or merge a
+configuration.
+
+If you do not specify a file during the `save` operation, the configuration
+is automatically saved to `/config/config.boot`.
+
+```none
+curl -k --location --request POST 'https://vyos/config-file' \
+--form data='{"op": "save"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "Saving configuration to '/config/config.boot'...\nDone\n",
+ "error": null
+}
+```
+
+To save a running configuration to a file:
+
+```none
+curl -k --location --request POST 'https://vyos/config-file' \
+--form data='{"op": "save", "file": "/config/test.config"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": "Saving configuration to '/config/test.config'...\nDone\n",
+ "error": null
+}
+```
+
+To load a configuration file:
+
+```none
+curl -k --location --request POST 'https://vyos/config-file' \
+--form data='{"op": "load", "file": "/config/test.config"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+To merge a configuration file:
+
+```none
+curl -k --location --request POST 'https://vyos/config-file' \
+--form data='{"op": "merge", "file": "/config/test.config"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+For both `load` and `merge` operations, you can pass a string in the
+request body. For example:
+
+```none
+curl -k --location --request POST 'https://vyos/config-file' \
+--form data='{"op": "merge", "string": "interfaces {\nethernet eth1 {\naddress "192.168.2.137/24"\ndescription "test"\n}\n}\n"}' \
+--form key='MY-HTTPS-API-PLAINTEXT-KEY'
+
+response:
+{
+ "success": true,
+ "data": null,
+ "error": null
+}
+```
+
+
+## Commit-confirm
+
+For the previous two endpoints, a `commit` command is executed automatically
+after a successful request operation (`set`, `delete`, `load`, `merge`,
+or a list of `set` and `delete` operations).
+
+Alternatively, you can initiate a `commit-confirm`. Include the
+`confirm_time` field in your request and set it to an integer greater than
+`0`.
+
+The following example uses the JSON format for brevity, though the standard
+form data format is equally valid:
+
+```none
+curl -k -X POST -d '{"key": "MY-HTTPS-API-PLAINTEXT-KEY", "op": "merge", "string": "interfaces {\nethernet eth1 {\naddress '192.168.137.1/24'\ndescription 'internal'\n}\n}\n", "confirm_time": 1}' https://vyos/config-file
+
+response:
+{
+ "success": true,
+ "data": "Initialized commit-confirm; 1 minutes to confirm before reload\n",
+ "error": null
+}
+```
+
+If not confirmed within the specified time, the committed changes will be
+reverted. To confirm and keep the changes:
+
+```none
+curl -k -X POST -d '{"key": "MY-HTTPS-API-PLAINTEXT-KEY", "op": "confirm"}' https://vyos/config-file
+
+response:
+{
+ "success": true,
+ "data": "Reload timer stopped\n",
+ "error": null
+}
+```
+
+If the commit is not confirmed, the revert behavior is controlled by:
+
+```none
+vyos@vyos# set system config-management commit-confirm action
+Possible completions:
+ reload Reload previous configuration if not confirmed
+ reboot Reboot to saved configuration if not confirmed (default)
+```
diff --git a/docs/automation/vyos-govyos.md b/docs/automation/vyos-govyos.md
new file mode 100644
index 00000000..e5a444f1
--- /dev/null
+++ b/docs/automation/vyos-govyos.md
@@ -0,0 +1,199 @@
+---
+lastproofread: '2026-04-14'
+---
+
+(vyos-govyos)=
+
+# Go-VyOS
+
+Go-VyOS is a Go library for configuring and managing VyOS devices through
+their API.
+
+- [GitHub repository](https://github.com/ganawaj/go-vyos): Hosts the source
+ code.
+- [Documentation](https://pkg.go.dev/github.com/ganawaj/go-vyos@v0.1.0/vyos):
+ Provides the complete API reference, including available types, functions, and
+ methods.
+
+## Installation
+
+To install Go-VyOS, run:
+
+```bash
+go install "github.com/ganawaj/go-vyos/vyos"
+```
+
+
+## Getting started
+
+### Import and disable TLS verification
+
+```none
+import "github.com/ganawaj/go-vyos/vyos"
+client := vyos.NewClient(nil).WithToken("AUTH_KEY").WithURL("https://192.168.0.1").Insecure()
+```
+
+
+### Initialize a VyDevice object
+
+```none
+import (
+ "github.com/ganawaj/go-vyos/vyos"
+ "os"
+)
+
+hostname := os.Getenv("VYDEVICE_HOSTNAME")
+port := os.Getenv("VYDEVICE_PORT")
+url := fmt.Sprintf("https://%s:%s", hostname, port)
+
+apikey := os.Getenv("VYDEVICE_APIKEY")
+verify_ssl := os.Getenv("VYDEVICE_VERIFY_SSL")
+
+client := vyos.NewClient(nil).WithToken(apikey).WithURL(url)
+
+if verify_ssl == "false" {
+ client = client.Insecure()
+}
+```
+
+
+## Use Go-VyOS
+
+### Configure, then set
+
+```none
+out, resp, err := c.Conf.Set(ctx, "interfaces ethernet eth0 address 192.168.1.1/24")
+if err != nil {
+ panic(fmt.Sprintf("Error: %v", err))
+}
+
+fmt.Println(out.Success)
+```
+
+
+### Show a single object value
+
+```none
+out, resp, err := c.Show.Do(ctx, "interfaces dummy dum1 address")
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+fmt.Printf("Data: %v\n", out.Data)
+```
+
+
+### Configure, then show object
+
+```none
+out, resp, err := c.Conf.Get(ctx, "interfaces dummy dum1", nil)
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+fmt.Printf("Data: %v\n", out.Data)
+```
+
+
+### Configure, then show multivalue object
+
+```none
+options := RetrieveOptions{
+ Multivalue: true,
+}
+
+out, resp, err := c.Conf.Get(ctx, "interfaces dummy dum1", options)
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+```
+
+
+### Configure, then delete object
+
+```none
+out, resp, err := c.Conf.Delete(ctx, "interfaces dummy dum1")
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+```
+
+
+### Configure, then save
+
+```none
+out, resp, err := c.Conf.Save(ctx, "")
+
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+```
+
+
+### Configure, then save file
+
+```none
+out, resp, err := c.Conf.Save(ctx, "/config/test300.config")
+
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+```
+
+
+### Show object
+
+```none
+out, resp, err := c.Show.Do(ctx, "system image")
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+fmt.Printf("Data: %v\n", out.Data)
+```
+
+
+### Generate object
+
+```none
+out, resp, err := c.Generate.Do(ctx, "pki wireguard key-pair")
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+fmt.Printf("Data: %v\n", out.Data)
+```
+
+
+### Reset object
+
+```none
+out, resp, err := c.Reset.Do(ctx, "ip bgp 192.0.2.11")
+if err != nil {
+ panic("Error: %v", err)
+}
+
+fmt.Println(out.Success)
+fmt.Printf("Data: %v\n", out.Data)
+```
+
+
+### Configure, then load file
+
+```none
+out, resp, err := c.ConfigFile.Load(ctx, "/config/test300.config")
+```
+
+[go-vyos]: https://github.com/ganawaj/go-vyos
diff --git a/docs/automation/vyos-napalm.md b/docs/automation/vyos-napalm.md
new file mode 100644
index 00000000..27e3c16c
--- /dev/null
+++ b/docs/automation/vyos-napalm.md
@@ -0,0 +1,154 @@
+---
+lastproofread: '2026-04-13'
+---
+
+(vyos-napalm)=
+
+# NAPALM VyOS driver
+
+VyOS can be configured using the [NAPALM VyOS driver], which enables you to
+retrieve device data and apply configurations via SSH.
+
+:::{note}
+The `napalm-vyos` module is currently in testing.
+:::
+
+To use the NAPALM VyOS driver, install the following packages:
+
+```none
+apt install python3-pip
+pip3 install napalm
+pip3 install napalm-vyos
+```
+
+
+## Retrieve device data
+
+The following script connects to a VyOS device, retrieves device facts and
+the ARP table, and prints the output in JSON format.
+
+```none
+#!/usr/bin/env python3
+
+import json
+from napalm import get_network_driver
+
+driver = get_network_driver('vyos')
+
+vyos_router = driver(
+ hostname="192.0.2.1",
+ username="vyos",
+ password="vyospass",
+ optional_args={"port": 22},
+)
+
+vyos_router.open()
+output = vyos_router.get_facts()
+print(json.dumps(output, indent=4))
+
+output = vyos_router.get_arp_table()
+print(json.dumps(output, indent=4))
+
+vyos_router.close()
+```
+
+Output:
+
+```none
+$ ./vyos-napalm.py
+{
+ "uptime": 7185,
+ "vendor": "VyOS",
+ "os_version": "1.3.0-rc5",
+ "serial_number": "",
+ "model": "Standard PC (Q35 + ICH9, 2009)",
+ "hostname": "r4-1.3",
+ "fqdn": "vyos.local",
+ "interface_list": [
+ "eth0",
+ "eth1",
+ "eth2",
+ "lo",
+ "vtun10"
+ ]
+}
+[
+ {
+ "interface": "eth1",
+ "mac": "52:54:00:b2:38:2c",
+ "ip": "192.0.2.2",
+ "age": 0.0
+ },
+ {
+ "interface": "eth0",
+ "mac": "52:54:00:a2:b9:5b",
+ "ip": "203.0.113.11",
+ "age": 0.0
+ }
+]
+```
+
+
+## Apply a configuration
+
+To apply a configuration using NAPALM VyOS driver, you will need a file with
+configuration commands (`commands.conf`) and a script that executes and
+commits them (`vyos-napalm.py`).
+
+- `commands.conf`
+
+```none
+set service ssh disable-host-validation
+set service ssh port '2222'
+set system name-server '192.0.2.8'
+set system name-server '203.0.113.8'
+set interfaces ethernet eth1 description 'FOO'
+```
+
+- `vyos-napalm.py`
+
+```none
+#!/usr/bin/env python3
+
+from napalm import get_network_driver
+
+driver = get_network_driver('vyos')
+
+vyos_router = driver(
+ hostname="192.0.2.1",
+ username="vyos",
+ password="vyospass",
+ optional_args={"port": 22},
+)
+
+vyos_router.open()
+vyos_router.load_merge_candidate(filename='commands.conf')
+diffs = vyos_router.compare_config()
+
+if bool(diffs) == True:
+ print(diffs)
+ vyos_router.commit_config()
+else:
+ print('No configuration changes to commit')
+ vyos_router.discard_config()
+
+vyos_router.close()
+```
+
+Output:
+
+```none
+$./vyos-napalm.py
+[edit interfaces ethernet eth1]
++description FOO
+[edit service ssh]
++disable-host-validation
++port 2222
+[edit system]
++name-server 192.0.2.8
++name-server 203.0.113.8
+[edit]
+```
+
+[napalm]: https://napalm.readthedocs.io/en/latest/base.html
+[NAPALM VyOS driver]: https://github.com/napalm-automation-community/napalm-vyos
diff --git a/docs/automation/vyos-netmiko.md b/docs/automation/vyos-netmiko.md
new file mode 100644
index 00000000..2e947b6a
--- /dev/null
+++ b/docs/automation/vyos-netmiko.md
@@ -0,0 +1,76 @@
+---
+lastproofread: '2026-04-13'
+---
+
+(vyos-netmiko)=
+
+# Netmiko
+
+VyOS can be configured using [Netmiko]. To use Netmiko, install the
+`python3-netmiko` module.
+
+## Example
+
+The following script connects to a VyOS device, applies configuration changes,
+commits them, and runs an operational mode command to verify the updated
+configuration.
+
+```none
+#!/usr/bin/env python3
+
+from netmiko import ConnectHandler
+
+vyos_router = {
+ "device_type": "vyos",
+ "host": "192.0.2.1",
+ "username": "vyos",
+ "password": "vyospass",
+ "port": 22,
+ }
+
+net_connect = ConnectHandler(**vyos_router)
+
+config_commands = [
+ 'set interfaces ethernet eth0 description WAN',
+ 'set interfaces ethernet eth1 description LAN',
+ ]
+
+# set configuration
+output = net_connect.send_config_set(config_commands, exit_config_mode=False)
+print(output)
+
+# commit configuration
+output = net_connect.commit()
+print(output)
+
+# operational mode commands
+output = net_connect.send_command("run show interfaces")
+print(output)
+```
+
+Output
+
+```none
+$ ./vyos-netmiko.py
+configure
+set interfaces ethernet eth0 description WAN
+[edit]
+vyos@r4-1.5# set interfaces ethernet eth1 description LAN
+[edit]
+vyos@r4-1.5#
+commit
+[edit]
+vyos@r4-1.5#
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 203.0.113.1/24 u/u WAN
+eth1 192.0.2.1/30 u/u LAN
+eth2 - u/u
+lo 127.0.0.1/8 u/u
+ ::1/128
+vtun10 10.10.0.1/24 u/u
+[edit]
+```
+
+[netmiko]: https://github.com/ktbyers/netmiko
diff --git a/docs/automation/vyos-pyvyos.md b/docs/automation/vyos-pyvyos.md
new file mode 100644
index 00000000..c9dcbc81
--- /dev/null
+++ b/docs/automation/vyos-pyvyos.md
@@ -0,0 +1,151 @@
+---
+lastproofread: '2026-04-14'
+---
+
+(vyos-pyvyos)=
+
+# PyVyOS
+
+PyVyOS is a Python library for configuring and managing VyOS devices through
+their API.
+
+**Key resources:**
+
+- [Documentation](https://pyvyos.readthedocs.io/en/latest/): Provides
+ installation, configuration, and usage instructions.
+- [GitHub repository](https://github.com/robertoberto/pyvyos): Hosts the
+ source code.
+- [PyPI](https://pypi.org/project/pyvyos/): Hosts distribution packages for
+ installation via the Python package installer (`pip`).
+
+## Installation
+
+To install PyVyOS via `pip`, run:
+
+```bash
+pip install pyvyos
+```
+
+
+## Getting started
+
+### Import and disable warnings for verify=false
+
+```none
+import urllib3
+urllib3.disable_warnings()
+```
+
+
+### Use API response class
+
+```none
+@dataclass
+class ApiResponse:
+ status: int
+ request: dict
+ result: dict
+ error: str
+```
+
+
+### Initialize a VyDevice object
+
+```none
+from dotenv import load_dotenv
+load_dotenv()
+
+hostname = os.getenv('VYDEVICE_HOSTNAME')
+apikey = os.getenv('VYDEVICE_APIKEY')
+port = os.getenv('VYDEVICE_PORT')
+protocol = os.getenv('VYDEVICE_PROTOCOL')
+verify_ssl = os.getenv('VYDEVICE_VERIFY_SSL')
+
+verify = verify_ssl.lower() == "true" if verify_ssl else True
+
+device = VyDevice(hostname=hostname, apikey=apikey, port=port, protocol=protocol, verify=verify)
+```
+
+
+## Use PyVyOS
+
+### Configure, then set
+
+```none
+response = device.configure_set(path=["interfaces", "ethernet", "eth0", "address", "192.168.1.1/24"])
+if not response.error:
+ print(response.result)
+```
+
+
+### Configure, then show a single object value
+
+```none
+response = device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"])
+print(response.result)
+```
+
+
+### Configure, then show object
+
+```none
+response = device.retrieve_show_config(path=[])
+if not response.error:
+ print(response.result)
+```
+
+
+### Configure, then delete object
+
+```none
+response = device.configure_delete(path=["interfaces", "dummy", "dum1"])
+```
+
+
+### Configure, then save
+
+```none
+response = device.config_file_save()
+```
+
+
+### Configure, then save file
+
+```none
+response = device.config_file_save(file="/config/test300.config")
+```
+
+
+### Show object
+
+```none
+response = device.show(path=["system", "image"])
+print(response.result)
+```
+
+
+### Generate object
+
+```none
+randstring = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20))
+keyrand = f'/tmp/key_{randstring}'
+response = device.generate(path=["ssh", "client-key", keyrand])
+```
+
+
+### Reset object
+
+```none
+response = device.reset(path=["conntrack-sync", "internal-cache"])
+if not response.error:
+ print(response.result)
+```
+
+
+### Configure, then load file
+
+```none
+response = device.config_file_load(file="/config/test300.config")
+```
+
+[pyvyos]: https://github.com/robertoberto/pyvyos
diff --git a/docs/automation/vyos-salt.md b/docs/automation/vyos-salt.md
new file mode 100644
index 00000000..7b306cb8
--- /dev/null
+++ b/docs/automation/vyos-salt.md
@@ -0,0 +1,211 @@
+---
+lastproofread: '2023-01-16'
+---
+
+(vyos-salt)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# Salt
+
+VyOS supports op-mode and configuration via [salt].
+
+Without proxy it requires VyOS minion configuration
+and supports op-mode data:
+
+```none
+set service salt-minion id 'r14'
+set service salt-minion master '192.0.2.250'
+```
+
+Check salt-keys on the salt master
+
+```none
+/ # salt-key --list-all
+Accepted Keys:
+r11
+Denied Keys:
+Unaccepted Keys:
+r14
+Rejected Keys:
+```
+
+Accept minion key
+
+```none
+/ # salt-key --accept r14
+The following keys are going to be accepted:
+Unaccepted Keys:
+r14
+Proceed? [n/Y] y
+Key for minion r14 accepted.
+```
+
+Check that salt master can communicate with minions
+
+```none
+/ # salt '*' test.ping
+r14:
+ True
+r11:
+ True
+```
+
+At this step we can get some op-mode information from VyOS nodes:
+
+```none
+/ # salt '*' network.interface eth0
+r11:
+ |_
+ ----------
+ address:
+ 192.0.2.11
+ broadcast:
+ 192.0.2.255
+ label:
+ eth0
+ netmask:
+ 255.255.255.0
+r14:
+ |_
+ ----------
+ address:
+ 192.0.2.14
+ broadcast:
+ 192.0.2.255
+ label:
+ eth0
+ netmask:
+ 255.255.255.0
+
+
+/ # salt r14 network.arp
+r14:
+ ----------
+ aa:bb:cc:dd:f3:db:
+ 192.0.2.1
+ aa:bb:cc:dd:2e:80:
+ 203.0.113.1
+```
+
+## Netmiko-proxy
+
+It is possible to configure VyOS via [netmiko] proxy module.
+It requires a minion with installed packet `python3-netmiko` module
+who has a connection to VyOS nodes. Salt-minion have to communicate
+with salt master
+
+### Configuration
+
+Salt master configuration:
+
+```none
+/ # cat /etc/salt/master
+file_roots:
+ base:
+ - /srv/salt/states
+
+pillar_roots:
+ base:
+ - /srv/salt/pillars
+```
+
+Structure of /srv/salt:
+
+```none
+/ # tree /srv/salt/
+/srv/salt/
+|___ pillars
+| |__ r11-proxy.sls
+| |__ top.sls
+|___ states
+ |__ commands.txt
+```
+
+top.sls
+
+```none
+/ # cat /srv/salt/pillars/top.sls
+base:
+ r11-proxy:
+ - r11-proxy
+```
+
+r11-proxy.sls Includes parameters for connecting to salt-proxy minion
+
+```none
+/ # cat /srv/salt/pillars/r11-proxy.sls
+proxy:
+ proxytype: netmiko # how to connect to proxy minion, change it
+ device_type: vyos #
+ host: 192.0.2.250
+ username: user
+ password: secret_passwd
+```
+
+commands.txt
+
+```none
+/ # cat /srv/salt/states/commands.txt
+set interfaces ethernet eth0 description 'WAN'
+set interfaces ethernet eth1 description 'LAN'
+```
+
+Check that proxy minion is alive:
+
+```none
+/ # salt r11-proxy test.ping
+r11-proxy:
+ True
+/ #
+```
+
+### Examples
+
+Example of op-mode:
+
+```none
+/ # salt r11-proxy netmiko.send_command 'show interfaces ethernet eth0 brief' host=192.0.2.14 device_type=vyos username=vyos password=vyos
+r11-proxy:
+ Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+ Interface IP Address S/L Description
+ --------- ---------- --- -----------
+ eth0 192.0.2.14/24 u/u Upstream
+/ #
+```
+
+Example of configuration:
+
+```none
+/ # salt r11-proxy netmiko.send_config config_commands=['set interfaces ethernet eth0 description Link_to_WAN'] commit=True host=192.0.2.14 device_type=vyos username=vyos password=vyos
+r11-proxy:
+ configure
+ set interfaces ethernet eth0 description Link_to_WAN
+ [edit]
+ vyos@r14# commit
+ [edit]
+ vyos@r14#
+/ #
+```
+
+Example of configuration commands from the file
+"/srv/salt/states/commands.txt"
+
+```none
+/ # salt r11-proxy netmiko.send_config config_file=salt://commands.txt commit=True host=192.0.2.11 device_type=vyos username=vyos password=vyos
+r11-proxy:
+ configure
+ set interfaces ethernet eth0 description 'WAN'
+ [edit]
+ vyos@r1# set interfaces ethernet eth1 description 'LAN'
+ [edit]
+ vyos@r1# commit
+ [edit]
+ vyos@r1#
+/ #
+```
+
+[netmiko]: <https://docs.saltproject.io/en/latest/ref/modules/all/salt.modules.netmiko_mod.html#module-salt.modules.netmiko_mod>
+[salt]: https://docs.saltproject.io/en/latest/contents.html
diff --git a/docs/cli.md b/docs/cli.md
new file mode 100644
index 00000000..3d37510e
--- /dev/null
+++ b/docs/cli.md
@@ -0,0 +1,868 @@
+(cli)=
+
+# Command Line Interface
+
+The VyOS {abbr}`CLI (Command-Line Interface)` comprises an operational and a configuration mode.
+
+## Operational Mode
+
+Operational mode allows for commands to perform operational system tasks and view system and service status, while configuration mode allows for the modification of system configuration.
+
+The CLI provides a built-in help system. In the CLI the `?` key may be used to display available commands. The `TAB` key can be used to auto-complete commands and will present the help system upon a conflict or unknown value.
+
+For example typing `sh` followed by the `TAB` key will complete to `show`. Pressing `TAB` a second time will display the possible sub-commands of the `show` command.
+
+``` none
+vyos@vyos:~$ s[tab]
+set show
+```
+
+Example showing possible show commands:
+
+``` none
+vyos@vyos:~$ show [tab]
+Possible completions:
+ arp Show Address Resolution Protocol (ARP) information
+ bridge Show bridging information
+ cluster Show clustering information
+ configuration Show running configuration
+ conntrack Show conntrack entries in the conntrack table
+ conntrack-sync
+ Show connection syncing information
+ date Show system date and time
+ dhcp Show Dynamic Host Configuration Protocol (DHCP) information
+ dhcpv6 Show status related to DHCPv6
+ disk Show status of disk device
+ dns Show Domain Name Server (DNS) information
+ file Show files for a particular image
+ firewall Show firewall information
+ flow-accounting
+ Show flow accounting statistics
+ hardware Show system hardware details
+ history show command history
+ host Show host information
+ incoming Show ethernet input-policy information
+: q
+```
+
+You can scroll up with the keys `[Shift]+[PageUp]` and scroll down with `[Shift]+[PageDown]`.
+
+When the output of a command results in more lines than can be displayed on the terminal screen the output is paginated as indicated by a `:` prompt.
+
+When viewing in page mode the following commands are available:
+: - `q` key can be used to cancel output
+ - `space` will scroll down one page
+ - `b` will scroll back one page
+ - `return` will scroll down one line
+ - `up-arrow` and `down-arrow` will scroll up or down one line at a time
+ respectively
+ - `left-arrow` and `right-arrow` can be used to scroll left or right in
+ the event that the output has lines which exceed the terminal size.
+
+### Operational mode command families
+
+Many operational mode commands in VyOS are placed in families such as `show`, `clear`, or `reset`. Every such family has a specific meaning to allow the user to guess how the command is going to behave --- in particular, whether it will be disruptive to the system or not.
+
+Note that this convention was not always followed with perfect consistency and some commands may still be in wrong families, so you should always check the command help and documentation if you are not sure what exactly it does.
+
+#### clear
+
+\"Clear\" commands are completely non-disruptive to any system operations. Generally, they can be used freely without hesitation.
+
+Most often their purpose is to remove or reset various debug and diagnostic information such as system logs and packet counters.
+
+Examples:
+- `clear console` --- clears the screen.
+- `clear interfaces ethernet eth0 counters` --- zeroes packet counters on `eth0`.
+- `clear log` --- deletes all system log entries.
+
+#### reset
+
+\"Reset\" commands can be locally-disruptive. They may, for example, terminate a single user session or a session with a dynamic routing protocol peer.
+
+They should be used with caution since they may have a significant impact on a particular users in the network.
+- `reset pppoe-server username jsmith` --- terminate all PPPoE sessions from user `jsmith`.
+- `reset bgp 192.0.2.54` --- terminates the BGP session with neighbor 192.0.2.54.
+- `reset vpn ipsec site-to-site peer vpn.example.com` --- terminates IPsec tunnels to `vpn.example.com`.
+- `reset session tty1` --- terminates the TTY user session `tty1`
+
+#### restart
+
+\"Restart\" operations may disrupt an entire subsystem. Most often they initiate a restart of a server process, which causes it to be unavailable for a brief period and resets all the process state.
+
+They should be used with extreme caution.
+- `restart dhcp server` --- restarts the IPv4 DHCP server process (DHCP requests are not served while it is restarting).
+- `restart ipsec` --- restarts the IPsec process (which forces all sessions and all IPsec process state to reset).
+
+#### force
+
+\"Force\" commands force the system to perform an action that it might perform by itself at a later point.
+
+Examples:
+- `force arp request interface eth1 address 10.3.0.2` --- send a gratuitious ARP request.
+- `force root-partition-auto-resize` --- grow the root filesystem to the size of the system partition (this is also done on startup, but this command can do it without a reboot).
+
+#### execute
+
+\"Execute\" commands are for executing various diagnostic and auxilliary actions that the system would never perform by itself.
+
+Examples:
+- `execute wake-on-lan interface <intf> host <MAC>` --- send a Wake-On-LAN packet to a host.
+
+#### show
+
+\"Show\" commands display various system information. They may occasionally use a pager for long outputs, that you can quit by pressing the Q button. Their output is always finite, however.
+
+Examples:
+- `show system login` --- displays current system users.
+- `show ip route` --- displays the IPv4 routing table.
+
+#### monitor
+
+\"Monitor\" commands initiate various monitoring operations that may output information continuously, until terminated with `Ctrl-C` or disabled.
+
+Examples:
+- `monitor log` --- continuously outputs latest system logs.
+
+## Configuration Mode
+
+To enter configuration mode use the `configure` command:
+
+``` none
+vyos@vyos:~$ configure
+[edit]
+vyos@vyos:~#
+```
+
+::::{note}
+Prompt changes from `$` to `#`. To exit configuration mode, type `exit`.
+::::
+
+``` none
+vyos@vyos:~# exit
+exit
+vyos@vyos:~$
+```
+
+See the configuration section of this document for more information on configuration mode.
+
+(configuration-overview)=
+
+# Configuration Overview
+
+VyOS makes use of a unified configuration file for the entire system\'s configuration: `/config/config.boot`. This allows easy template creation, backup, and replication of system configuration. A system can thus also be easily cloned by simply copying the required configuration files.
+
+## Terminology
+
+A VyOS system has three major types of configurations:
+- **Active** or **running configuration** is the system configuration that is loaded and currently active (used by VyOS). Any change in the configuration will have to be committed to belong to the active/running configuration.
+- **Working configuration** is the one that is currently being modified in configuration mode. Changes made to the working configuration do not go into effect until the changes are committed with the {cfgcmd}`commit` command. At which time the working configuration will become the active or running configuration.
+- **Saved configuration** is the one saved to a file using the {cfgcmd}`save` command. It allows you to keep safe a configuration for future uses. There can be multiple configuration files. The default or \"boot\" configuration is saved and loaded from the file `/config/config.boot`.
+
+## Seeing and navigating the configuration
+
+```{opcmd} show configuration
+
+View the current active configuration, also known as the running configuration, from the operational mode.
+
+:::{code-block} none
+vyos@vyos:~$ show configuration
+interfaces {
+ ethernet eth0 {
+ address dhcp
+ hw-id 00:53:00:00:aa:01
+ }
+ loopback lo {
+ }
+}
+service {
+ ssh {
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 20
+ }
+ console {
+ device ttyS0 {
+ speed 9600
+ }
+ }
+ login {
+ user vyos {
+ authentication {
+ encrypted-password ****************
+ }
+ level admin
+ }
+ }
+ ntp {
+ server 0.pool.ntp.org {
+ }
+ server 1.pool.ntp.org {
+ }
+ server 2.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level notice
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+:::
+```
+
+By default, the configuration is displayed in a hierarchy like the above example, this is only one of the possible ways to display the configuration. When the configuration is generated and the device is configured, changes are added through a collection of {cfgcmd}`set` and {cfgcmd}`delete` commands.
+
+```{opcmd} show configuration commands
+
+Get a collection of all the set commands required which led to the running configuration.
+
+:::{code-block} none
+vyos@vyos:~$ show configuration commands
+set interfaces ethernet eth0 address 'dhcp'
+set interfaces ethernet eth0 hw-id '00:53:dd:44:3b:0f'
+set interfaces loopback 'lo'
+set service ssh port '22'
+set system config-management commit-revisions '20'
+set system console device ttyS0 speed '9600'
+set system login user vyos authentication encrypted-password '$6$Vt68...QzF0'
+set system login user vyos level 'admin'
+set system ntp server '0.pool.ntp.org'
+set system ntp server '1.pool.ntp.org'
+set system ntp server '2.pool.ntp.org'
+set system syslog global facility all level 'notice'
+set system syslog global facility protocols level 'debug'
+:::
+```
+
+Both these `show` commands should be executed when in operational mode, they do not work directly in configuration mode. There is a special way on how to {ref}`run_opmode_from_config_mode`.
+
+::::{hint}
+
+Use the `show configuration commands | strip-private` command when you want to hide private data. You may want to do so if you want to share your configuration on the [forum](https://forum.vyos.io).
+::::
+
+```{opcmd} show configuration json
+
+View the current active configuration in JSON format.
+
+:::{code-block} none
+{"interfaces": {"ethernet": {"eth0": {"address": ["192.0.2.11/24", "192.0.2.35/24"], "hw-id": "52:54:00:48:a0:c6"}, "eth1": {"address": ["203.0.113.1/24"], "hw-id": "52:54:00:fc:50:0b"}}, "loopback": {"lo": {}}}, "protocols": {"static": {"route": {"0.0.0.0/0": {"next-hop": {"192.0.2.254": {}}}}}}, "service": {"ssh": {"disable-host-validation": {}}}, "system": {"config-management": {"commit-revisions": "100"}, "console": {"device": {"ttyS0": {"speed": "115200"}}}, "host-name": "r11-vyos", "login": {"user": {"vyos": {"authentication": {"encrypted-password": "$6$Vt68...F0", "plaintext-password": "", "public-keys": {"vyos@vyos": {"key": "AAAAxxx=", "type": "ssh-rsa"}}}}}}, "name-server": ["203.0.113.254"], "ntp": {"server": {"time1.vyos.net": {}, "time2.vyos.net": {}, "time3.vyos.net": {}}}, "syslog": {"global": {"facility": {"all": {"level": "info"}, "protocols": {"level": "debug"}}}}, "time-zone": "America/New_York"}}
+:::
+```
+
+```{opcmd} show configuration json pretty
+
+View the current active configuration in readable JSON format.
+
+:::{code-block} none
+{
+ "interfaces": {
+ "ethernet": {
+ "eth0": {
+ "address": [
+ "192.0.2.11/24",
+ "192.0.2.35/24"
+ ],
+ "hw-id": "52:54:00:48:a0:c6"
+ },
+ "eth1": {
+ "address": [
+ "203.0.113.1/24"
+ ],
+ "hw-id": "52:54:00:fc:50:0b"
+ }
+ },
+ "loopback": {
+ "lo": {}
+ }
+ },
+ "protocols": {
+ "static": {
+ "route": {
+ "0.0.0.0/0": {
+ "next-hop": {
+ "192.0.2.254": {}
+ }
+ }
+ }
+ }
+ },
+ "service": {
+ "ssh": {
+ "disable-host-validation": {}
+ }
+ },
+ "system": {
+ "config-management": {
+ "commit-revisions": "100"
+ },
+ "console": {
+ "device": {
+ "ttyS0": {
+ "speed": "115200"
+ }
+ }
+ },
+ "host-name": "r11-vyos",
+ "login": {
+ "user": {
+ "vyos": {
+ "authentication": {
+ "encrypted-password": "$6$Vt68...F0",
+ "plaintext-password": "",
+ "public-keys": {
+ "vyos@vyos": {
+ "key": "AAAAxxx=",
+ "type": "ssh-rsa"
+ }
+ }
+ }
+ }
+ }
+ },
+ "name-server": [
+ "203.0.113.254"
+ ],
+ "ntp": {
+ "server": {
+ "time1.vyos.net": {},
+ "time2.vyos.net": {},
+ "time3.vyos.net": {}
+ }
+ },
+ "syslog": {
+ "global": {
+ "facility": {
+ "all": {
+ "level": "info"
+ },
+ "protocols": {
+ "level": "debug"
+ }
+ }
+ }
+ },
+ "time-zone": "America/New_York"
+ }
+}
+:::
+```
+
+
+### The config mode
+
+When entering the configuration mode you are navigating inside a tree structure, to enter configuration mode enter the command {opcmd}`configure` when in operational mode.
+
+``` none
+vyos@vyos$ configure
+[edit]
+vyos@vyos#
+```
+
+::::{note}
+When going into configuration mode, prompt changes from `$` to `#`.
+::::
+
+All commands executed here are relative to the configuration level you have entered. You can do everything from the top level, but commands will be quite lengthy when manually typing them.
+
+The current hierarchy level can be changed by the {cfgcmd}`edit` command.
+
+``` none
+[edit]
+vyos@vyos# edit interfaces ethernet eth0
+
+[edit interfaces ethernet eth0]
+vyos@vyos#
+```
+
+You are now in a sublevel relative to `interfaces ethernet eth0`, all commands executed from this point on are relative to this sublevel. Use either the {cfgcmd}`top` or {cfgcmd}`exit` command to go back to the top of the hierarchy. You can also use the {cfgcmd}`up` command to move only one level up at a time.
+
+```{cfgcmd} show
+```
+
+The {cfgcmd}`show` command within configuration mode will show the working configuration indicating line changes with `+` for additions, `>` for replacements and `-` for deletions.
+**Example:**
+
+``` none
+vyos@vyos:~$ configure
+[edit]
+vyos@vyos# show interfaces
+ ethernet eth0 {
+ description MY_OLD_DESCRIPTION
+ disable
+ hw-id 00:53:dd:44:3b:03
+ }
+ loopback lo {
+ }
+[edit]
+vyos@vyos# set interfaces ethernet eth0 address dhcp
+[edit]
+vyos@vyos# set interfaces ethernet eth0 description MY_NEW_DESCRIPTION
+[edit]
+vyos@vyos# delete interfaces ethernet eth0 disable
+[edit]
+vyos@vyos# show interfaces
+ ethernet eth0 {
++ address dhcp
+> description MY_NEW_DESCRIPTION
+- disable
+ hw-id 00:53:dd:44:3b:03
+ }
+ loopback lo {
+ }
+```
+
+It is also possible to display all {cfgcmd}`set` commands within configuration mode using {cfgcmd}`show | commands`
+
+``` none
+vyos@vyos# show interfaces ethernet eth0 | commands
+set address dhcp
+set hw-id 00:53:ad:44:3b:03
+```
+
+These commands are also relative to the level you are inside and only relevant configuration blocks will be displayed when entering a sub-level.
+
+``` none
+[edit interfaces ethernet eth0]
+vyos@vyos# show
+ address dhcp
+ hw-id 00:53:ad:44:3b:03
+```
+
+Exiting from the configuration mode is done via the {cfgcmd}`exit` command from the top level, executing {cfgcmd}`exit` from within a sub-level takes you back to the top level.
+
+``` none
+[edit interfaces ethernet eth0]
+vyos@vyos# exit
+[edit]
+vyos@vyos# exit
+Warning: configuration changes have not been saved.
+```
+
+## Editing the configuration
+
+The configuration can be edited by the use of {cfgcmd}`set` and {cfgcmd}`delete` commands from within configuration mode.
+
+```{cfgcmd} set
+
+Use this command to set the value of a parameter or to create a new element.
+```
+
+Configuration commands are flattened from the tree into \'one-liner\' commands shown in {opcmd}`show configuration commands` from operation mode. Commands are relative to the level where they are executed and all redundant information from the current level is removed from the command entered.
+
+``` none
+[edit]
+vyos@vyos# set interface ethernet eth0 address 192.0.2.100/24
+```
+
+``` none
+[edit interfaces ethernet eth0]
+vyos@vyos# set address 203.0.113.6/24
+```
+
+These two commands above are essentially the same, just executed from different levels in the hierarchy.
+
+```{cfgcmd} delete
+
+To delete a configuration entry use the {cfgcmd}`delete` command, this also deletes all sub-levels under the current level you\'ve specified in the {cfgcmd}`delete` command. Deleting an entry will also result in the element reverting back to its default value if one exists.
+
+:::{code-block} none
+[edit interfaces ethernet eth0]
+vyos@vyos# delete address 192.0.2.100/24
+:::
+```
+
+```{cfgcmd} commit
+
+Any change you do on the configuration, will not take effect until committed using the {cfgcmd}`commit` command in configuration mode.
+
+:::{code-block} none
+vyos@vyos# commit
+[edit]
+vyos@vyos# exit
+Warning: configuration changes have not been saved.
+vyos@vyos:~$
+:::
+```
+::::{hint}
+
+You can specify a commit message with {cfgcmd}`commit comment <message>`.
+::::
+
+(save)=
+
+```{cfgcmd} save
+
+Use this command to preserve configuration changes upon reboot. By default it is stored at */config/config.boot*. In the case you want to store the configuration file somewhere else, you can add a local path, a SCP address, a FTP address or a TFTP address.
+```
+
+``` none
+vyos@vyos# save
+Saving configuration to '/config/config.boot'...
+Done
+```
+
+``` none
+vyos@vyos# save [tab]
+Possible completions:
+ <Enter> Save to system config file
+ <file> Save to file on local machine
+ scp://<user>:<passwd>@<host>:/<file> Save to file on remote machine
+ ftp://<user>:<passwd>@<host>/<file> Save to file on remote machine
+ tftp://<host>/<file> Save to file on remote machine
+vyos@vyos# save tftp://192.168.0.100/vyos-test.config.boot
+Saving configuration to 'tftp://192.168.0.100/vyos-test.config.boot'...
+
+Done
+```
+:::
+::::
+```{cfgcmd} exit \[discard\]
+
+Configuration mode can not be exited while uncommitted changes exist. To exit configuration mode without applying changes, the {cfgcmd}`exit discard` command must be used.
+
+All changes in the working config will thus be lost.
+
+:::{code-block} none
+vyos@vyos# exit
+Cannot exit: configuration modified.
+
+Use 'exit discard' to discard the changes and exit.
+[edit]
+vyos@vyos# exit discard
+:::
+```
+
+```{cfgcmd} commit-confirm \<minutes\>
+
+Use this command to temporarily commit your changes and set the number of minutes available for confirmation. `confirm` must be entered within those minutes, otherwise the system will revert into a previous configuration. The default value is 10 minutes.
+
+The definition of \'revert\' and \'a previous configuration\' depends on the setting:
+
+:::{code-block} none
+vyos@vyos# set system config-management commit-confirm action
+Possible completions:
+reload Reload previous configuration if not confirmed
+reboot Reboot to saved configuration if not confirmed (default)
+:::
+
+Note that \'reload\' loads the most recent completed configuration and does not require a reboot.
+
+What if you are doing something dangerous? Suppose you want to setup a firewall, and you are not sure there are no mistakes that will lock you out of your system. You can use confirmed commit. If you issue the `commit-confirm` command, your changes will be committed, and if you don\'t issue the `confirm` command in 10 minutes, your system will reboot into previous config revision.
+
+:::{code-block} none
+vyos@router# set firewall interface eth0 local name FromWorld
+vyos@router# commit-confirm
+commit confirm will be automatically reboot in 10 minutes unless confirmed
+Proceed? [confirm]y
+[edit]
+vyos@router# confirm
+[edit]
+:::
+```
+
+```{cfgcmd} copy
+
+Copy a configuration element.
+
+You can copy and remove configuration subtrees. Suppose you set up a firewall ruleset `FromWorld` with one rule that allows traffic from specific subnet. Now you want to setup a similar rule, but for different subnet. Change your edit level to `firewall name FromWorld` and use `copy rule 10 to rule 20`, then modify rule 20.
+
+:::{code-block} none
+vyos@router# show firewall name FromWorld
+ default-action drop
+ rule 10 {
+ action accept
+ source {
+ address 203.0.113.0/24
+ }
+ }
+[edit]
+vyos@router# edit firewall name FromWorld
+[edit firewall name FromWorld]
+vyos@router# copy rule 10 to rule 20
+[edit firewall name FromWorld]
+vyos@router# set rule 20 source address 198.51.100.0/24
+[edit firewall name FromWorld]
+vyos@router# commit
+[edit firewall name FromWorld]
+:::
+```
+
+```{cfgcmd} rename
+
+Rename a configuration element.
+
+You can also rename config subtrees:
+
+:::{code-block} none
+vyos@router# rename rule 10 to rule 5
+[edit firewall name FromWorld]
+vyos@router# commit
+[edit firewall name FromWorld]
+:::
+Note that `show` command respects your edit level and from this level you can view the modified firewall ruleset with just `show` with no parameters.
+
+:::{code-block} none
+vyos@router# show
+ default-action drop
+ rule 5 {
+ action accept
+ source {
+ address 203.0.113.0/24
+ }
+ }
+ rule 20 {
+ action accept
+ source {
+ address 198.51.100.0/24
+ }
+ }
+:::
+```
+
+```{cfgcmd} comment \<config node\> "comment text"
+
+Add comment as an annotation to a configuration node.
+
+The `comment` command allows you to insert a comment above the `<config node>` configuration section. When shown, comments are enclosed with `/*` and `*/` as open/close delimiters. Comments need to be committed, just like other config changes.
+
+To remove an existing comment from your current configuration, specify an empty string enclosed in double quote marks (`""`) as the comment text.
+
+Example:
+
+:::{code-block} none
+vyos@vyos# comment firewall all-ping "Yes I know this VyOS is cool"
+vyos@vyos# commit
+vyos@vyos# show
+ firewall {
+ /* Yes I know this VyOS is cool */
+ all-ping enable
+ broadcast-ping disable
+ ...
+ }
+:::
+:::{note}
+An important thing to note is that since the comment is added on top of the section, it will not appear if the `show <section>` command is used. With the above example, the ``show firewall`` command would return starting after the `firewall {` line, hiding the comment.
+:::
+```
+
+(run_opmode_from_config_mode)=
+
+## Access opmode from config mode
+
+When inside configuration mode you are not directly able to execute operational commands.
+
+```{cfgcmd} run
+
+Access to these commands are possible through the use of the `run [command]` command. From this command you will have access to everything accessible from operational mode.
+
+Command completion and syntax help with `?` and `[tab]` will also work.
+
+:::{code-block} none
+[edit]
+vyos@vyos# run show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 0.0.0.0/0 u/u
+:::
+```
+
+## Managing configurations
+
+VyOS comes with an integrated versioning system for the system configuration. It automatically maintains a backup of every previous configuration which has been committed to the system. The configurations are versioned locally for rollback but they can also be stored on a remote host for archiving/backup reasons.
+
+### Local Archive
+
+Revisions are stored on disk. You can view, compare and rollback them to any previous revisions if something goes wrong.
+
+```{opcmd} show system commit
+
+View all existing revisions on the local system.
+
+:::{code-block} none
+vyos@vyos:~$ show system commit
+0 2015-03-30 08:53:03 by vyos via cli
+1 2015-03-30 08:52:20 by vyos via cli
+2 2015-03-26 21:26:01 by root via boot-config-loader
+3 2015-03-26 20:43:18 by root via boot-config-loader
+4 2015-03-25 11:06:14 by root via boot-config-loader
+5 2015-03-25 01:04:28 by root via boot-config-loader
+6 2015-03-25 00:16:47 by vyos via cli
+7 2015-03-24 23:43:45 by root via boot-config-loader
+:::
+```
+
+```{cfgcmd} set system config-management commit-revisions \<N\>
+
+You can specify the number of revisions stored on disk. N can be in the range of 0 - 65535. When the number of revisions exceeds the configured value, the oldest revision is removed. The default setting for this value is to store 100 revisions locally.
+```
+
+### Compare configurations
+
+VyOS lets you compare different configurations.
+
+```{cfgcmd} compare \<saved \| N\> \<M\>
+
+Use this command to spot what the differences are between different configurations.
+
+:::{code-block} none
+vyos@vyos# compare [tab]
+Possible completions:
+<Enter> Compare working & active configurations
+saved Compare working & saved configurations
+<N> Compare working with revision N
+<N> <M> Compare revision N with M
+Revisions:
+ 0 2013-12-17 20:01:37 root by boot-config-loader
+ 1 2013-12-13 15:59:31 root by boot-config-loader
+ 2 2013-12-12 21:56:22 vyos by cli
+ 3 2013-12-12 21:55:11 vyos by cli
+ 4 2013-12-12 21:27:54 vyos by cli
+ 5 2013-12-12 21:23:29 vyos by cli
+ 6 2013-12-12 21:13:59 root by boot-config-loader
+ 7 2013-12-12 16:25:19 vyos by cli
+ 8 2013-12-12 15:44:36 vyos by cli
+ 9 2013-12-12 15:42:07 root by boot-config-loader
+ 10 2013-12-12 15:42:06 root by init
+:::
+The command {cfgcmd}`compare` allows you to compare different type of configurations. It also lets you compare different revisions through the {cfgcmd}`compare N M` command, where N and M are revision numbers. The output will describe how the configuration N is when compared to M indicating with a plus sign (`+`) the additional parts N has when compared to M, and indicating with a minus sign (`-`) the lacking parts N misses when compared to M.
+
+:::{code-block} none
+vyos@vyos# compare 0 6
+[edit interfaces]
++dummy dum1 {
++ address 10.189.0.1/31
++}
+[edit interfaces ethernet eth0]
++vif 99 {
++ address 10.199.0.1/31
++}
+-vif 900 {
+- address 192.0.2.4/24
+-}
+:::
+```
+
+```{opcmd} show system commit diff \<number\>
+
+Show commit revision difference.
+```
+
+The command above also lets you see the difference between two commits. By default the difference with the running config is shown.
+
+``` none
+vyos@router# run show system commit diff 4
+[edit system]
++ipv6 {
++ disable-forwarding
++}
+```
+
+This means four commits ago we did `set system ipv6 disable-forwarding`.
+
+### Rollback Changes
+
+You can rollback configuration changes using the rollback command. This will apply the selected revision and trigger a system reboot.
+
+```{cfgcmd} rollback \<N\>
+
+Rollback to revision N (currently requires reboot)
+
+:::{code-block} none
+vyos@vyos# compare 1
+[edit system]
+>host-name vyos-1
+[edit]
+vyos@vyos# rollback 1
+Proceed with reboot? [confirm][y]
+Broadcast message from root@vyos-1 (pts/0) (Tue Dec 17 21:07:45 2013):
+
+The system is going down for reboot NOW!
+:::
+```
+
+### Remote Archive
+
+VyOS can upload the configuration to a remote location after each call to {cfgcmd}`commit`. You will have to set the commit-archive location. TFTP, FTP, SCP and SFTP servers are supported. Every time a {cfgcmd}`commit` is successful the `config.boot` file will be copied to the defined destination(s). The filename used on the remote host will be `config.boot-hostname.YYYYMMDD_HHMMSS`.
+
+```{cfgcmd} set system config-management commit-archive location \<URI\>
+
+Specify remote location of commit archive as any of the below {abbr}`URI (Uniform Resource Identifier)`
+- `http://<user>:<passwd>@<host>:/<dir>`
+- `https://<user>:<passwd>@<host>:/<dir>`
+- `ftp://<user>:<passwd>@<host>/<dir>`
+- `sftp://<user>:<passwd>@<host>/<dir>`
+- `scp://<user>:<passwd>@<host>:/<dir>`
+- `tftp://<host>/<dir>`
+- `git+https://<user>:<passwd>@<host>/<path>`
+
+Since username and password are part of the URI, they need to be properly url encoded if containing special characters.
+
+:::{note}
+The number of revisions don\'t affect the commit-archive.
+
+When using Git as destination for the commit archive the `source-address` CLI option has no effect.
+
+You may find VyOS not allowing the secure connection because it cannot verify the legitimacy of the remote server. You can use the workaround below to quickly add the remote host\'s SSH fingerprint to your `~/.ssh/known_hosts` file:
+:::
+:::{code-block} none
+vyos@vyos# ssh-keyscan <host> >> ~/.ssh/known_hosts
+:::
+```
+
+```{cfgcmd} set system config-management commit-archive vrf \<name\>
+
+Specify name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance used to upload the configuration to the remote system.
+```
+
+### Saving and loading manually
+
+You can use the `save` and `load` commands if you want to manually manage specific configuration files.
+
+When using the [save](#save) command, you can add a specific location where to store your configuration file. And, when needed it, you will be able to load it with the `load` command:
+
+```{cfgcmd} load \<URI\>
+
+Use this command to load a configuration which will replace the running configuration. Define the location of the configuration file to be loaded. You can use a path to a local file, an SCP address, an SFTP address, an FTP address, an HTTP address, an HTTPS address or a TFTP address.
+
+:::{code-block} none
+vyos@vyos# load
+Possible completions:
+<Enter> Load from system config file
+<file> Load from file on local machine
+scp://<user>:<passwd>@<host>:/<file> Load from file on remote machine
+sftp://<user>:<passwd>@<host>/<file> Load from file on remote machine
+ftp://<user>:<passwd>@<host>/<file> Load from file on remote machine
+http://<host>/<file> Load from file on remote machine
+https://<host>/<file> Load from file on remote machine
+tftp://<host>/<file> Load from file on remote machine
+:::
+
+If you are remotely connected, you will lose your connection. You may want to copy first the config, edit it to ensure connectivity, and load the edited config.
+```
+
+### Restore Default
+
+In the case you want to completely delete your configuration and restore the default one, you can enter the following command in configuration mode:
+
+``` none
+load /opt/vyatta/etc/config.boot.default
+```
+
+You will be asked if you want to continue. If you accept, you will have to use {cfgcmd}`commit` if you want to make the changes active.
+
+Then you may want to {cfgcmd}`save` in order to delete the saved configuration too.
+
+::::{note}
+Prompt changes from `$` to `#`. To exit configuration mode, type `exit`.
+::::
diff --git a/docs/configexamples/ansible.md b/docs/configexamples/ansible.md
new file mode 100644
index 00000000..8bbd9306
--- /dev/null
+++ b/docs/configexamples/ansible.md
@@ -0,0 +1,212 @@
+---
+lastproofread: '2024-04-09'
+---
+
+(examples-ansible)=
+
+# Ansible example
+
+## Setting up Ansible on a server running the Debian operating system.
+
+In this example, we will set up a simple use of Ansible to configure
+multiple VyOS routers.
+We have four pre-configured routers with this configuration:
+
+Using the general schema for example:
+
+```{image} /_static/images/ansible.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+We have four pre-configured routers with this configuration:
+
+```none
+set interfaces ethernet eth0 address dhcp
+set service ssh
+commit
+save
+```
+
+- vyos7 - 192.0.2.105
+- vyos8 - 192.0.2.106
+- vyos9 - 192.0.2.107
+- vyos10 - 192.0.2.108
+
+## Install Ansible:
+
+```none
+# apt-get install ansible
+Do you want to continue? [Y/n] y
+```
+
+
+## Install Paramiko:
+
+```none
+#apt-get install -y python3-paramiko
+```
+
+
+## Check the version:
+
+```none
+# ansible --version
+ansible 2.10.8
+config file = None
+configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
+ansible python module location = /usr/lib/python3/dist-packages/ansible
+executable location = /usr/bin/ansible
+python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
+```
+
+
+## Basic configuration of ansible.cfg:
+
+```none
+# nano /root/ansible.cfg
+[defaults]
+host_key_checking = no
+```
+
+
+## Add all the VyOS hosts:
+
+```none
+# nano /root/hosts
+[vyos_hosts]
+vyos7 ansible_ssh_host=192.0.2.105
+vyos8 ansible_ssh_host=192.0.2.106
+vyos9 ansible_ssh_host=192.0.2.107
+vyos10 ansible_ssh_host=192.0.2.108
+```
+
+
+## Add general variables:
+
+```none
+# mkdir /root/group_vars/
+# nano /root/group_vars/vyos_hosts
+ansible_python_interpreter: /usr/bin/python3
+ansible_network_os: vyos
+ansible_connection: network_cli
+ansible_user: vyos
+ansible_ssh_pass: vyos
+```
+
+
+## Add a simple playbook with the tasks for each router:
+
+```none
+# nano /root/main.yml
+
+---
+- hosts: vyos_hosts
+ gather_facts: 'no'
+ tasks:
+ - name: Configure general settings for the vyos hosts group
+ vyos_config:
+ lines:
+ - set system name-server 192.0.2.1
+ - set interfaces ethernet eth0 description '#WAN#'
+ - set interfaces ethernet eth1 description '#LAN#'
+ - set interfaces ethernet eth2 disable
+ - set interfaces ethernet eth3 disable
+ - set system host-name {{ inventory_hostname }}
+ save: true
+```
+
+
+## Start the playbook:
+
+```none
+ansible-playbook -i hosts main.yml
+PLAY [vyos_hosts] **************************************************************
+
+TASK [Configure general settings for the vyos hosts group] *********************
+ok: [vyos9]
+ok: [vyos10]
+ok: [vyos7]
+ok: [vyos8]
+
+PLAY RECAP *********************************************************************
+vyos10 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos7 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos8 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos9 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+```
+
+
+## Check the result on the vyos10 router:
+
+```none
+vyos@vyos10:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 192.0.2.108/24 u/u WAN
+eth1 - u/u LAN
+eth2 - A/D
+eth3 - A/D
+lo 127.0.0.1/8 u/u
+ ::1/128
+
+vyos@vyos10:~$ sh configuration commands | grep 192.0.2.1
+set system name-server '192.0.2.1'
+```
+
+
+## The simple way without configuration of the hostname (one task for all routers):
+
+```none
+# nano /root/hosts_v2
+[vyos_hosts_group]
+vyos7 ansible_ssh_host=192.0.2.105
+vyos8 ansible_ssh_host=192.0.2.106
+vyos9 ansible_ssh_host=192.0.2.107
+vyos10 ansible_ssh_host=192.0.2.108
+[vyos_hosts_group:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=vyos
+ansible_ssh_pass=vyos
+ansible_network_os=vyos
+ansible_connection=network_cli
+
+# nano /root/main_v2.yml
+---
+- hosts: vyos_hosts_group
+ connection: network_cli
+ gather_facts: 'no'
+ tasks:
+ - name: Configure remote vyos_hosts_group
+ vyos_config:
+ lines:
+ - set system name-server 192.0.2.1
+ - set interfaces ethernet eth0 description WAN
+ - set interfaces ethernet eth1 description LAN
+ - set interfaces ethernet eth2 disable
+ - set interfaces ethernet eth3 disable
+ save: true
+```
+
+```none
+# ansible-playbook -i hosts_v2 main_v2.yml
+
+PLAY [vyos_hosts_group] ********************************************************
+
+TASK [Configure remote vyos_hosts_group] ***************************************
+ok: [vyos8]
+ok: [vyos7]
+ok: [vyos9]
+ok: [vyos10]
+
+PLAY RECAP *********************************************************************
+vyos10 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos7 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos8 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+vyos9 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
+```
+
+In the next chapter of the example, we'll use Ansible with jinja2
+templates and variables.
diff --git a/docs/configexamples/autotest/DHCPRelay_through_GRE/DHCPRelay_through_GRE.md b/docs/configexamples/autotest/DHCPRelay_through_GRE/DHCPRelay_through_GRE.md
new file mode 100644
index 00000000..114e1d2e
--- /dev/null
+++ b/docs/configexamples/autotest/DHCPRelay_through_GRE/DHCPRelay_through_GRE.md
@@ -0,0 +1,89 @@
+# DHCP Relay trough GRE-Bridge
+
+```{eval-rst}
+| Testdate: 2023-05-11
+| Version: 1.4-rolling-202305100734
+```
+
+This simple structure shows how to configure a DHCP Relay over a GRE Bridge
+interface.
+
+## Topology
+
+The topology has 3 VyOS routers and one client. Between the DHCP Server and
+the DHCP Relay is a GRE tunnel. The `transport` VyOS represent a large
+Network.
+
+```{image} _include/topology.webp
+:alt: Ansible Example topology image
+```
+
+
+## Configuration
+
+First, we configure the transport network and the Tunnel interface.
+
+Transport:
+
+```{literalinclude} _include/transport.conf
+:language: none
+```
+
+DHCP-Server
+
+```{literalinclude} _include/dhcp-server.conf
+:language: none
+:lines: 1-8
+```
+
+DHCP-Relay
+
+```{literalinclude} _include/dhcp-relay.conf
+:language: none
+:lines: 1-8
+```
+
+After this, we need the DHCP-Server and Relay configuration.
+To get a testable result, we just have one IP in the DHCP range.
+Expand it as you need it.
+
+DHCP-Server
+
+```{literalinclude} _include/dhcp-server.conf
+:language: none
+:lines: 9-13
+```
+
+DHCP-Relay
+
+```{literalinclude} _include/dhcp-relay.conf
+:language: none
+:lines: 9-10
+```
+
+
+## Test the result
+
+Ping the Client from the DHCP Server.
+
+```none
+vyos@dhcp-server:~$ ping 192.168.0.30 count 4
+PING 192.168.0.30 (192.168.0.30) 56(84) bytes of data.
+64 bytes from 192.168.0.30: icmp_seq=1 ttl=63 time=1.02 ms
+64 bytes from 192.168.0.30: icmp_seq=2 ttl=63 time=1.06 ms
+64 bytes from 192.168.0.30: icmp_seq=3 ttl=63 time=1.21 ms
+64 bytes from 192.168.0.30: icmp_seq=4 ttl=63 time=1.16 ms
+
+--- 192.168.0.30 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3004ms
+rtt min/avg/max/mdev = 1.016/1.112/1.214/0.077 ms
+```
+
+And show all DHCP Leases
+
+```none
+vyos@dhcp-server:~$ show dhcp server leases
+IP Address MAC address State Lease start Lease expiration Remaining Pool Hostname
+------------ ----------------- ------- ------------------- ------------------- ----------- ---------- ----------
+192.168.0.30 00:50:79:66:68:05 active 2023/05/11 13:08:50 2023/05/12 13:08:50 23:59:16 DHCPTun100 VPCS
+```
diff --git a/docs/configexamples/autotest/DHCPRelay_through_GRE/_include/topology.png b/docs/configexamples/autotest/DHCPRelay_through_GRE/_include/topology.png
deleted file mode 100644
index 952b664b..00000000
--- a/docs/configexamples/autotest/DHCPRelay_through_GRE/_include/topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/configexamples/autotest/L3VPN_EVPN/L3VPN_EVPN.md b/docs/configexamples/autotest/L3VPN_EVPN/L3VPN_EVPN.md
new file mode 100644
index 00000000..b74452e1
--- /dev/null
+++ b/docs/configexamples/autotest/L3VPN_EVPN/L3VPN_EVPN.md
@@ -0,0 +1,246 @@
+# L3VPN EVPN with VyOS
+
+```{eval-rst}
+| Testdate: 2023-05-11
+| Version: 1.4-rolling-202305100734
+```
+
+I spun up a new lab in EVE-NG, which represents this as the
+"Foo Bar - Service Provider Inc." that has 3 points of presence (PoP) in random
+datacenters/sites named PE1, PE2, and PE3. Each PoP aggregates at least two
+customers.
+
+I named the customers blue, red and green which is common practice in
+VRF (Virtual Routing and Forwarding) documentation scenarios.
+
+- PE1 is located in an industrial area that holds multiple office buildings.
+ All customers have a site in this area.
+- PE2 is located in a smaller area where by coincidence two customers
+ (blue and red) share an office building.
+- PE3 is located in a smaller area where by coincidence two customers
+ (blue and green) are located.
+
+## Management VRF
+
+A brief excursion into VRFs: This has been one of the longest-standing feature
+requests of VyOS (dating back to 2016) which can be described as
+"a VLAN for layer 2 is what a VRF is for layer 3".
+With VRFs, a router/system can hold multiple, isolated routing tables on the
+same system. If you wonder what's the difference between multiple tables that
+people used for policy-based routing since forever, it's that a VRF also
+isolates connected routes rather than just static and dynamically learned
+routes, so it allows NICs in different VRFs to use conflicting network
+ranges without issues.
+
+VyOS 1.3 added initial support for VRFs (including IPv4/IPv6 static routing)
+and VyOS 1.4 now enables full dynamic routing protocol support for
+OSPF, IS-IS, and BGP for individual VRFs.
+
+The lab I built is using a VRF (called **mgmt**) to provide out-of-band
+SSH access to the PE (Provider Edge) routers.
+
+```{literalinclude} _include/PE1.conf
+:language: none
+:lines: 1-6
+```
+
+
+## Topology
+
+We use the following network topology in this example:
+
+```{image} _include/topology.webp
+:alt: L3VPN EVPN with VyOS topology image
+```
+
+
+## Core network
+
+I chose to run OSPF as the IGP (Interior Gateway Protocol).
+All required BGP sessions are established via a dummy interfaces
+(similar to the loopback, but in Linux you can have only one loopback,
+while there can be many dummy interfaces) on the PE routers. In case of a link
+failure, traffic is diverted in the other direction in this triangle setup and
+BGP sessions will not go down. One could even enable
+BFD (Bidirectional Forwarding Detection) on the links for a faster
+failover and resilience in the network.
+
+Regular VyOS users will notice that the BGP syntax has changed in VyOS 1.4 from
+even the prior post about this subject. This is due to T1711, where it was
+finally decided to get rid of the redundant BGP ASN (Autonomous System Number)
+specification on the CLI and move it to a single leaf node
+(set protocols bgp local-as).
+
+It's important to note that all your existing configurations will be migrated
+automatically on image upgrade. Nothing to do on your side.
+
+PE1
+
+```{literalinclude} _include/PE1.conf
+:language: none
+:lines: 8-38
+```
+
+PE2
+
+```{literalinclude} _include/PE2.conf
+:language: none
+:lines: 8-38
+```
+
+PE3
+
+```{literalinclude} _include/PE3.conf
+:language: none
+:lines: 8-38
+```
+
+
+## Tenant networks (VRFs)
+
+Once all routers can be safely remotely managed and the core network is
+operational, we can now setup the tenant networks.
+
+Every tenant is assigned an individual VRF that would support overlapping
+address ranges for customers blue, red and green. In our example,
+we do not use overlapping ranges to make it easier when showing debug commands.
+
+Thus you can easily match it to one of the devices/networks below.
+
+Every router that provides access to a customer network needs to have the
+customer network (VRF + VNI) configured. To make our own lives easier,
+we utilize the same VRF table id (local routing table number) and
+VNI (Virtual Network Identifier) per tenant on all our routers.
+
+- blue uses local routing table id and VNI 2000
+- red uses local routing table id and VNI 3000
+- green uses local routing table id and VNI 4000
+
+PE1
+
+```{literalinclude} _include/PE1.conf
+:language: none
+:lines: 40-96
+```
+
+PE2
+
+```{literalinclude} _include/PE2.conf
+:language: none
+:lines: 40-89
+```
+
+PE3
+
+```{literalinclude} _include/PE3.conf
+:language: none
+:lines: 40-89
+```
+
+
+## Testing and debugging
+
+You managed to come this far, now we want to see the network and routing
+tables in action.
+
+Show routes for all VRFs
+
+```none
+vyos@PE1:~$ show ip route vrf all
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+VRF blue:
+C>* 10.1.1.0/24 is directly connected, br2000, 00:01:13
+B>* 10.1.2.0/24 [200/0] via 172.29.255.2, br2000 onlink, weight 1, 00:00:49
+B>* 10.1.3.0/24 [200/0] via 172.29.255.3, br2000 onlink, weight 1, 00:00:49
+
+VRF default:
+O 172.29.0.2/31 [110/1] is directly connected, eth1, weight 1, 00:01:09
+C>* 172.29.0.2/31 is directly connected, eth1, 00:01:12
+O>* 172.29.0.4/31 [110/2] via 172.29.0.3, eth1, weight 1, 00:00:46
+ * via 172.29.0.7, eth3, weight 1, 00:00:46
+O 172.29.0.6/31 [110/1] is directly connected, eth3, weight 1, 00:01:09
+C>* 172.29.0.6/31 is directly connected, eth3, 00:01:12
+C>* 172.29.255.1/32 is directly connected, dum0, 00:01:14
+O>* 172.29.255.2/32 [110/20] via 172.29.0.3, eth1, weight 1, 00:00:50
+O>* 172.29.255.3/32 [110/20] via 172.29.0.7, eth3, weight 1, 00:00:45
+
+VRF green:
+C>* 10.3.1.0/24 is directly connected, br4000, 00:01:13
+B>* 10.3.3.0/24 [200/0] via 172.29.255.3, br4000 onlink, weight 1, 00:00:49
+
+VRF mgmt:
+S>* 0.0.0.0/0 [210/0] via 10.100.0.1, eth0, weight 1, 00:01:45
+C>* 10.100.0.0/24 is directly connected, eth0, 00:01:45
+
+VRF red:
+C>* 10.2.1.0/24 is directly connected, br3000, 00:01:13
+B>* 10.2.2.0/24 [200/0] via 172.29.255.2, br3000 onlink, weight 1, 00:00:49
+```
+
+Information about Ethernet Virtual Private Networks
+
+```none
+vyos@PE1:~$ show bgp l2vpn evpn
+BGP table version is 1, local router ID is 172.29.255.1
+Status codes: s suppressed, d damped, h history, * valid, > best, i - internal
+Origin codes: i - IGP, e - EGP, ? - incomplete
+EVPN type-1 prefix: [1]:[EthTag]:[ESI]:[IPlen]:[VTEP-IP]:[Frag-id]
+EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]
+EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]
+EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]
+EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]
+
+ Network Next Hop Metric LocPrf Weight Path
+Route Distinguisher: 10.1.1.1:5
+*> [5]:[0]:[24]:[10.1.1.0]
+ 172.29.255.1 0 32768 ?
+ ET:8 RT:100:2000 Rmac:4e:bb:3c:ba:bd:a6
+Route Distinguisher: 10.1.2.1:4
+*>i[5]:[0]:[24]:[10.1.2.0]
+ 172.29.255.2 0 100 0 ?
+ RT:100:2000 ET:8 Rmac:26:07:da:eb:fc:ea
+Route Distinguisher: 10.1.3.1:4
+*>i[5]:[0]:[24]:[10.1.3.0]
+ 172.29.255.3 0 100 0 ?
+ RT:100:2000 ET:8 Rmac:26:98:28:24:6e:54
+Route Distinguisher: 10.2.1.1:6
+*> [5]:[0]:[24]:[10.2.1.0]
+ 172.29.255.1 0 32768 ?
+ ET:8 RT:100:3000 Rmac:50:00:00:01:00:05
+Route Distinguisher: 10.2.2.1:5
+*>i[5]:[0]:[24]:[10.2.2.0]
+ 172.29.255.2 0 100 0 ?
+ RT:100:3000 ET:8 Rmac:50:00:00:02:00:05
+Route Distinguisher: 10.3.1.1:7
+*> [5]:[0]:[24]:[10.3.1.0]
+ 172.29.255.1 0 32768 ?
+ ET:8 RT:100:4000 Rmac:50:00:00:01:00:06
+Route Distinguisher: 10.3.3.1:6
+*>i[5]:[0]:[24]:[10.3.3.0]
+ 172.29.255.3 0 100 0 ?
+ RT:100:4000 ET:8 Rmac:06:32:9d:22:55:8a
+
+Displayed 7 out of 7 total prefixes
+```
+
+If we need to retrieve information about a specific host/network inside
+the EVPN network we need to run
+
+```none
+vyos@PE2:~$ show bgp l2vpn evpn 10.3.1.10
+BGP routing table entry for 10.3.1.1:7:[5]:[0]:[24]:[10.3.1.0]
+Paths: (1 available, best #1)
+ Not advertised to any peer
+ Route [5]:[0]:[24]:[10.3.1.0] VNI 4000
+ Local
+ 172.29.255.1 (metric 20) from 172.29.255.1 (172.29.255.1)
+ Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
+ Extended Community: RT:100:4000 ET:8 Rmac:50:00:00:01:00:06
+ Last update: Thu May 11 13:31:13 2023
+```
diff --git a/docs/configexamples/autotest/L3VPN_EVPN/_include/topology.png b/docs/configexamples/autotest/L3VPN_EVPN/_include/topology.png
deleted file mode 100644
index 18ecaabb..00000000
--- a/docs/configexamples/autotest/L3VPN_EVPN/_include/topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/configexamples/autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP.md b/docs/configexamples/autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP.md
new file mode 100644
index 00000000..d58c8bf7
--- /dev/null
+++ b/docs/configexamples/autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP.md
@@ -0,0 +1,287 @@
+(examples-openvpn-with-ldap)=
+
+# OpenVPN with LDAP
+
+```{eval-rst}
+| Testdate: 2023-05-11
+| Version: 1.4-rolling-202305100734
+```
+
+This LAB shows how to use OpenVPN with a Active Directory authentication method.
+
+Topology consists of:
+: - Windows Server 2019 with a running Active Directory
+ - VyOS as a OpenVPN Server
+ - VyOS as Client
+
+```{image} _include/topology.webp
+:alt: OpenVPN with LDAP topology image
+```
+
+
+## Active Directory on Windows server
+
+The lab assumes a full running Active Directory on the Windows Server.
+Here are some PowerShell commands to quickly add a Test Active Directory.
+
+```powershell
+# install the Active Directory Server role
+Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
+
+# install the Active Directory Server role
+Install-ADDSForest -DomainName "vyos.local" -DomainNetBiosName "VYOS" -InstallDns:$true -NoRebootCompletion:$true
+
+# create test user01 and binduser
+New-ADUser binduser -AccountPassword(Read-Host -AsSecureString "Input Password") -Enabled $true
+New-ADUser user01 -AccountPassword(Read-Host -AsSecureString "Input Password") -Enabled $true
+```
+
+
+## Configure VyOS as OpenVPN Server
+
+In this example OpenVPN will be setup with a client certificate and username / password authentication.
+
+First a CA, a signed server and client ceftificate and a Diffie-Hellman parameter musst be generated and installed.
+Please look {ref}`here <configuration/pki/index:pki>` for more information.
+
+```{eval-rst}
+| Add the LDAP plugin configuration file `/config/auth/ldap-auth.config`
+```
+
+```{eval-rst}
+| Check all possible settings `here <https://github.com/threerings/openvpn-auth-ldap/blob/master/auth-ldap.conf>`_.
+```
+
+```{literalinclude} _include/ldap-auth.config
+:language: none
+```
+
+Now generate all required certificates on the ovpn-server:
+
+First the CA
+
+```none
+vyos@ovpn-server# run generate pki ca install OVPN-CA
+```
+
+after this create a signed server and a client certificate
+
+```none
+vyos@ovpn-server# run generate pki certificate sign OVPN-CA install SRV
+vyos@ovpn-server# run generate pki certificate sign OVPN-CA install CLIENT
+```
+
+and last the DH Key
+
+```none
+vyos@ovpn-server# run generate pki dh install DH
+```
+
+after all these steps the config look like this:
+
+```none
+set pki ca OVPN-CA certificate 'MIIFnTCCA4WgAwIBAgIUIPFIXvCxYdavCnSPFNjr6lUtlsswDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA1MTExMjM4MjJaFw0zMzA1MDgxMjM4MjJaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDg45vAzS6xNqU+Pa7wk1Imt1/az1C22Sbp3wPJLfgOmy0K3TA5qVsx/c/8gatsatMkCsekGnK5BPzCDd5eCCLo//B25HFO6fBYRNvHvVyCUx7QEXw4FHFNG88zCIizx114AGtVwZfGGG9xCc53xjLPUpH6iqTXme41cCFFQlqXwZ7fuySieSdoV8SAsJTTOsGCEUEcDEnNPn6tX3KWTzNuyFPECy8WCmNgWNyG2nmH+U7WRTX0ehZ5dZyU5au7TxpRN4a+JtE0gNqcWJ+nh1A543q2pcRoQpPAzHFclgj8wG/EyauQMY/LC4tLc6moPaNlTwA9HJv8s6xUqpzNptDoUHKOqKuw2JRFnno5SCQ788KkKNgVWBy2o3BGoewfHFhAdR61CXeLpmuneuhi96GcM031gW8ptXbd4DkCF7H6KRtqeIvwiyG79ttC8kZf01Sn1fM5fTjGxaE38dAk/RchtHRC6rtFavHJjB2cUcCkhhQofUE6IR2dYJZ1cw0Wy5CI3bXHf43BpvDGmuxIlNGirTq8wf5RCWzDJJgmkQpYhUYe8x4faF4gTo00uH4ZvAYjQu3JNZGkb50p4kM9Mu5rQAiZJUeMAz/QD+EIV9xXgOk14+BbnHKWbZ7Ou5emewFuE/bjl79oNJklpXdc4soRkCPCTEGK3zDBdmUtCYk1DwIDAQABo2EwXzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwHQYDVR0OBBYEFP5NDac/yC+mQmaTpZDUv9GZMGMBMA0GCSqGSIb3DQEBCwUAA4ICAQDEqpF2ibwYFxsF1XDIPS5/Gs0sZTZBuByNm5d2+jTyO7d5alZUdbvobbwhxZOhWasmFNyPLr4TYmZm5zF+efFsiOxjyRuEoVU+Fe8rZmpRIF/+6+nYX5r9vMI4QxGjeeyP20OHJ85Kvz182CTsITrM15Vw/kVVjAVzFI5Gm/QolalAoFQza9rAL4kDqaUszjHjPbysvDpGF+NLPjiYDHXcty/BC48bnuzAeEM60SGZ7EXvf8l0X8YsO7z39w6780A/3rbZvFhCYMKp/+p5xBRDjnX91dM6DJw73RwYQ1KHbHk9wWUwnL1giL71jzp/y4Oj6SSK2PQv+OnO80J6Zg06WIQx9xYcxr108Xh9FotUrlG7GYPI3Udf95t6SjuydDhULAVD0lMBxlDe9DHW1k1q1pOXaHZg926tY66xx/lda6dcuwJjA2Dx5JI6L0u9ureQmQAtxvnoTCtf+hR1iX/IkskZCKs34SjNiCnBuw/DNfdOpfaABm7y+tWiXBwnu5l/K8poXcQYQByyZj6YMmpgsbVPr5KNsLWOgRA81M6IPof8qxvnFrkazhiQWh1YHSjnaHtA3z5/BdgwHVICuFyrIOlbkKyJOjKcKBsDdMwIV0tsnpnyli2xEPZKu1tAQFAavXrK/RGYYhOZ3e0aRSV8hlP8i/mf7p0I45cJiBCqPg=='
+set pki ca OVPN-CA private key 'MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDg45vAzS6xNqU+Pa7wk1Imt1/az1C22Sbp3wPJLfgOmy0K3TA5qVsx/c/8gatsatMkCsekGnK5BPzCDd5eCCLo//B25HFO6fBYRNvHvVyCUx7QEXw4FHFNG88zCIizx114AGtVwZfGGG9xCc53xjLPUpH6iqTXme41cCFFQlqXwZ7fuySieSdoV8SAsJTTOsGCEUEcDEnNPn6tX3KWTzNuyFPECy8WCmNgWNyG2nmH+U7WRTX0ehZ5dZyU5au7TxpRN4a+JtE0gNqcWJ+nh1A543q2pcRoQpPAzHFclgj8wG/EyauQMY/LC4tLc6moPaNlTwA9HJv8s6xUqpzNptDoUHKOqKuw2JRFnno5SCQ788KkKNgVWBy2o3BGoewfHFhAdR61CXeLpmuneuhi96GcM031gW8ptXbd4DkCF7H6KRtqeIvwiyG79ttC8kZf01Sn1fM5fTjGxaE38dAk/RchtHRC6rtFavHJjB2cUcCkhhQofUE6IR2dYJZ1cw0Wy5CI3bXHf43BpvDGmuxIlNGirTq8wf5RCWzDJJgmkQpYhUYe8x4faF4gTo00uH4ZvAYjQu3JNZGkb50p4kM9Mu5rQAiZJUeMAz/QD+EIV9xXgOk14+BbnHKWbZ7Ou5emewFuE/bjl79oNJklpXdc4soRkCPCTEGK3zDBdmUtCYk1DwIDAQABAoICACVsewzYmD6RU2pKJYSPX4pl1aO6ADqNZHZi0GR4K+FyXUqDiHTwA+cLz8K7aWV/WWeUC6j5ZcH4XH+Gg0yumfCgNsnyNhDlyUNHIjPZBT4Cywvg/QTwEfK8//wEHYudT6aam0IIF1O12UW8VgmEiAwMN5Kz476lNQjbgg3efujmJaQhpnULKE2q3V51BC8qhe05JdafDOEE11vOmGj/ARYcbCQhoFJQpDzyTLB8RuEj0cTCe7oVXwwTUF1O4wcmoMCHNvsJxqKwFrER5m+giu83NcKTT13yRlg9LVg094XoGDFtRgmW1dD6ONHzi3Yd28UOIoII8sRYugLU6YcnjXfrgxvKJHJywEEJobfS2o/2/mHh6kjv7pvppWdDhjkf+dWZ0frx2YyF5/dUgGG6e94hzOwRunEu4JVKl0Qr+Vfsqt/STVDA3vbhaMdMuIR2Ir0OkoYiqGBdiEGVx82lf4uDy2TXveqKUADXU5SchjP0JZpBANO4RVoxFpY2r1tEh/sRBu9wY+Fjk4FqdjjOmsbmFwhyG/j2VvKkVsq5itsxG/Rg1nTThE2LN+R6LUquujtn94rIaz6lukEr7Yq9qy14Prj5A7tYnuHbcN36b0A3xN7bxxeX6w12naVp0KZPmey6W4HNeNOOfTLh8BpG+TMPZLJq6U+fryHD2nIhk1mxAoIBAQD88A7vo3LIzas83bYaCa1BgjtJ6WUsqsriuG55pt8olzF/X0THkcDiozCy1IJchL4+GxxA0dp+NBispflvbFWZFAHMnbJx4cc7qMR9k8DDSHNQVgfV6nBa4xBvjBp+sanOOOLV4p+fQZW+n6VMzCcKC74awjbIKgPY0LhUQxIVjtzFyor+MLLoqeavxWzBVVBslwR2oyjbTtTMkeNuTyC4kQAJcfWDN/s2bl6P8Mldpik2WhW0GdxHyK3sgZWXIrnkTlQg3EMPb2sPhFZm6pQKpxXwl8gGgFzEx4mEpHxHm/igZPVRTnYfGwkPmHu3caF59IWHq4jsUAxRQperRgStAoIBAQDjnJ4dZgcnI4PxiDKDKXeb5ZgjnIL0eyxMZoLtaVYnO2lLG0uMlACUEuRwGz4acQcjRoW4FOh3NSberobSHOVBO9Y3qgEcTtgJvzkso5IXD76/vmpiYFdPo9aGaVR/fr+yPZ0h4S9wFShRBtDZapjAlds68ROQsvF/fdU4kqtfyIAst1lwtqMPeTmiZJxVubE0h2YEXOpwIEFcu3+MUvqtCd8X/T+VyF4ZQqn64NvYvkoWpfIiKmOGsCBc4agYuPs4Cy1QvN6oLXp+0b8mSzp+ot35n1lBGTSY2l4/9k6sIzWY7x23GS2g3AUJ2kYUTpQIq2pow8Sc8ptxLwZSQZwrAoIBABqhW7E3UDp8DO9XmHidVDR1dbCOdiyBvuKn8Fm2jABGCtwSN7ebTOePruzlGuSKxUzcpdjdP1fSPFbRErX8ffaj+JyGbec3kjZhym4+RClLU3i91g1bpYCsL2rPIWr9YZdovdkvBwdJbG6peEnhpKqWGenPUN06LzWApCea+Ch05iGc9Y1Vq0B7wuH2s0CXruP/8mRbQU31usnfAkb25ccI3SwhZ2vtVPGiJSqae1j0yZoDWg2gO2UDZ+xiqFFFQrUa2hirmBPj8y2rDT3ArN2CQfkWweSNVzcQmxXwC3Wuojqg5oMs85rKyeVudHgX6pxgdj6WfNAEjYdwr29E6/ECggEBAIHl7i7k/YwOrsx3aCyGy+ZC39LjDbGtYhiwIGSRy0NUmsDscO9nv/TB23FHeufoPaSaKNJnzEvMH8TSYcskBop2NclK0ptvO8hEQ8MADu3uZHRVna1LQkkHPfUzw6+HjKuSkky1kTcsO/gSJbsPJOI0JAu9becU2NJj4/4HZpqheNUMRpUXBnRcQNI3DSm3cjSCWWyAAqO/JM5hi2dwK/P5QEMWmuVGlr1f2FZ/YbiO0QWf61IoUuiZN78KYb7KQ0U2y8PaJlBgtBoQZkDaiiWfmYNOt8d5NRVO+p8SWM/QwFPpk1Hdora9GnsHARuxxLY17eKgZ2MS6jdsGPV00EUCggEBAPuNZ3peHYhIo2EMb6wpnAFV2fAUajymwenr+Bmv5BlAnW7bE2bSNuK0P342H047On8pSEHD4tk9C/GedKiUyxP2UnaFS24mWpe44X3UlC+KJLqJG+zVGXryC7bvhS3N1KlI6H2pRY1fPAhlfUk2KAe+ZP5C7iWwtR6FlPpjB3JoS77qFVhnYdlfnQEuJ7woEKD1TXQH0Sb2OGfPQW1UjIYoEp+9p2F5scB8rV6WaOIpwLY1H0ODvo1JYdTruWGHMKqhuLs5L2MeOluUOyHW7HkJLdLuyDIR9nA4+vNB1RNF3rz83L4Xs/NA1CW3iFWIyG57oFMX1td3i3xJwhjd40M='
+set pki certificate SRV certificate 'MIIFtTCCA52gAwIBAgIUeZnSAMPohIvKL/1Fy/pW2cV73HkwDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA1MTExMjM4MzFaFw0zMzA1MDgxMjM4MzFaMFsxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxFDASBgNVBAMMC292cG4tc2VydmVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApDWzTcB5LFM/tacaRHvpchBKLigJ5FlqNNfJ2vnP87KfCmTA5tkWF7MtuY990tHZtl1vQ3Pim4d6XBOngiQmaw7tZeWAIrv1L2/VBjORUrLrQhkkg9nSpcYFxoyUQzukTY75PcwhYLkS6ZO/vPPSBuh97f3XR645Aauf7ZIk2NsUidP2uGZz/Sr5VC7ovH2l3zz1kIHPCinfvpPEVb5oTt7qEffk4vnKjy9RY+H1hZowvcAp1zfLaOt/dXaK6vfNutbmwDHbYAlIals0EcjtTr+63ymxmupn7RBjgWtK7MgocGZnt6HKJ4J6teP3WgiSd+I9pdFG4wHZOSVL3axf3rBx7q09DMn/Snvfbly+SlhXw9Ebk368J6j6rhNUkxo/M9fbfgxS0JnNjHInRNAvRQW5CgQfT9KyUdxR63BeSnngk2XYX+bDinb0ig+VDpZcr6PgOBR8aNFsCPbXRwDy0bmuFnFYMzs/7ZmFQhzE6rQykHvVvAsyv7FYrlW0E02H4+Xe6bEVpE1fLcH8OCGY2cfuTfq1Ax6R4r+tdHYW1kzFLjwdh3uqTLF11zcbkAwd78E/ItrfEadvgxrYR9gfhX79AkK0VHmZ/hzrLFeGznnVcqoTKgq21dfMfQG2P13QvqS7tCE5swM9N09ASVrifyVDuoL6jaW96wgeqR6eHMECAwEAAaN1MHMwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFE1U3Zamfuv6ocYiF9q7H//U8h+AMB8GA1UdIwQYMBaAFP5NDac/yC+mQmaTpZDUv9GZMGMBMA0GCSqGSIb3DQEBCwUAA4ICAQBZwHvGj/jziNFwXS2W1Q11I12YANmVhISP39AA7DNhXR+E1hXFs+U52ehurZoLTi5YTjd8PD0KcE58mw8CLsFQB/+pni9EwJuAhpMb6XsmYEp0PeOH7C/q5eOc4TB/NBsvEa5IdTmUoewmjubKeJ8OHdRBMI77Me53lSC6iskc9DGyixSLqQogQW4aiTposFJOW/YugBy7kiuygmFNJv4luDbyRBb9131zH0qSSishLT4Bp5lXQNYWI4AU0JeyQcYaSHWCr0h6H9GN3QOf/emc3/2Tee40FcEMsszJBRnQ3IISzU5xVLlfU02SJMpjvFT2MGfHAs7obrNbwiFeoLZ6fQeGLe53aOQ5M9XeW5bdIeR2ZrLoO1hW33x5jYI8nLnU0FnqpMMY14r7LZE/mjwfdrTsGChFzsLasB0Tj++mGMOXw3DSusppub17AE2bO2uO6J9XMlbkOC8EmDCF1Hetija4D3aunhtu6jRBOcR8DHVBqNae2YgUk1ALqGrNUGFH4bEioTjDDx2GieOtp9rUwJMlkAyUEe0k/wzcBLjZaO8KBCtrmTdr1wMXizPT+XcjAlzRNXvHiZFq0NG5Rnim+LH9tp90EHzO7EeVXV+LegnIKQqboIrY3KOw5Qx8ska+t1WrWHpyzpwsA0WjA6sDTyWthgNYSxb1ikNGO8STCA=='
+set pki certificate SRV private key 'MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCkNbNNwHksUz+1pxpEe+lyEEouKAnkWWo018na+c/zsp8KZMDm2RYXsy25j33S0dm2XW9Dc+Kbh3pcE6eCJCZrDu1l5YAiu/Uvb9UGM5FSsutCGSSD2dKlxgXGjJRDO6RNjvk9zCFguRLpk7+889IG6H3t/ddHrjkBq5/tkiTY2xSJ0/a4ZnP9KvlULui8faXfPPWQgc8KKd++k8RVvmhO3uoR9+Ti+cqPL1Fj4fWFmjC9wCnXN8to6391dorq98261ubAMdtgCUhqWzQRyO1Ov7rfKbGa6mftEGOBa0rsyChwZme3ocongnq14/daCJJ34j2l0UbjAdk5JUvdrF/esHHurT0Myf9Ke99uXL5KWFfD0RuTfrwnqPquE1STGj8z19t+DFLQmc2McidE0C9FBbkKBB9P0rJR3FHrcF5KeeCTZdhf5sOKdvSKD5UOllyvo+A4FHxo0WwI9tdHAPLRua4WcVgzOz/tmYVCHMTqtDKQe9W8CzK/sViuVbQTTYfj5d7psRWkTV8twfw4IZjZx+5N+rUDHpHiv610dhbWTMUuPB2He6pMsXXXNxuQDB3vwT8i2t8Rp2+DGthH2B+Ffv0CQrRUeZn+HOssV4bOedVyqhMqCrbV18x9AbY/XdC+pLu0ITmzAz03T0BJWuJ/JUO6gvqNpb3rCB6pHp4cwQIDAQABAoICAQCgNLAZhFX0E8hNbplnBUltek0VGQUFnuLKaVlLZXwn8zXNCx1UW6l9N9e9eSw1uXzhueiqc247dQLAwIAlrSU6P9cHGdBYku4T+NRpd3gpqdtyolsItEQabccGvfKMYazb6khqrTRHTGkSL47aRzq6eKsbvRMCoQyG/61JN9LxK1SvX3gO0g4Jipq0MgvokeF5mdyuvqaC8PWU1k+vo9PaVwsguqy5cSDZbz3F6BcE4Lj693cavRmb5F52+E9yDI/P4IhCLKIt4QCgmxiC3XgA43fq75+SV21LUTjzc/0mY+VoO9CmzJcQ0vDrclzJnyFfCwBAPZweL5iBc0zAGcNxTA5/k86ejHdLlASH0dRf55F8ALeO22um21F7cEqOSYBtl009LDvpHte9wKWp9MpHABeDCigYMc05/IgVPQemtd6NtQ0ZVWHWUiWWqh5cY4v8d0CHWAv4HJZI5JuGWdWUc1QufMfu9UbTuNJe0RGQ/N9OJZzzwX+Vpuflrg9K0CT47Yo3NGFbYOuxn12JQBEYDNl5VHWZGAe1x/ljD0OjWmw3xkLNyRqwZnSTTJ4salCSW6qLrsqHWEeNyx+J4t2gBY0TNoylQ8hECxozFu/CYNIlY7+dJjFFe29r+FNBK+WOuUcSoyrABbqCkQH3iXOC97SQSyxdXMNvkkl9X8gvQQKCAQEA2VKt5k7HqvUTC26DNswNQGfd89GcQSeWaipzOBe0Oq12QA0G4ZfPTR00F6CqYnEOSuu2Qa++KEkTBsgl9mE0tdWCAXTTWuqmnsvX2FYQ8rD8FMce+Hs8nn3qNtxAkqPjIY0uEe5AJDzeB0ct7A5w5K5f6MUE/2rWhCeBGVqJKQ+qRjgk0KeVTcnTGzyujaHN1akUA1CRKEqtrCCspZjollWhxDygevMbXs/0QlDkUxaflPOzit6B5vDJqLGJUgvPI3Hc+9eDZXeCyCCdXOVGY8FUxMQ84RnDO8sVOthgahHsdbxjdUb0KcgaV5xNuMyuYsA++QG7fnsHCHnKT0c4eQKCAQEAwW8ppE0K/EmTp2OXKq+cuZHRZWaBtm3zDwfOz3FLVBXi3JGX9M6Hv6q/2cgLDudYiE3LCNagNkI7rRRO8Gfqd2i9KVRQHWCTl4mpTOwwmKWONNgS34aTPjD5UptNUzTvIItGGSMfg/DNrYg6G9HA666aIqpvodSfUv1ryJViml/3NtvmlRmRKEYe03txKhAN1Reuq30BoOGs4Tu5Hy8ijws9hOSCdZbOyte4EhDRSNyZB45YXooJOHEWTLjrZZqgGH3B/uUAUmyHbutPF/Wkep7M1LVeU8KS4HeVmwMRgPL10nxoHPE/UGBuqL09p4a1muXQ+TMHvnI59Shkn9cEiQKCAQEA10v/l/BoAse0TFj5iSnx3uKHkmsQX8P2UcsoRmPFW3RJd/7v2EJrTrwlxVqYMdpLDJIkB0MyIfry7H8QjNuUOqgAmazBToq08xCDD4GEXMpVkcgKuKRuU53ukNb26c+Ozshs4bqktMHQPGmZ5wgPc54EyjeVUezoBBiW3yVASPuJ9vLcFhJP6baOe6dMTmgD4S4V84q3o7EICUR9hbjMg1LmZeCiI+wAK5fdJm25JU9+XTRppKP3EXFudr8bibrFRRoikSTauYUCfX1CKKvDZkQ71IuMvHynW+8/YwLF0Y9cMO+noKHgdhwVbMIehXvRL2fBezLqKs17FDyD3rJyEQKCAQAdwFtHShJGe4qaVFcL2bbhU+xBDGMnDAI2bZ0BiwtrA3LBOiOFI779W+XmOT56LFsRm+V+loRN1CIZnOYHU/RcKV/u22j3G8OXqzS/ABT5ZX1Z42IDv08mYaH3cquSALJG7yT4+M4AHSmFZ06IuNpTZaePbWd+HJXkzdWmJFPmKpx7c5cjl6sb5q0XGgVt0spN3Dahabi2Zf+RJP50LWvDVJdBuWPXcjqcOFG3dZ669jMTVnGBGPoSFFK5ujd6iS3WloEgE1jZVJgAF3Ey3jVOJt6aWMsJVwQAQmRgUzh9/OCSX1AkI3b5hdt/WJwDCFUmXfKmYZLvV+JSMsRHUWsBAoIBAC2ZuZ3hYmSFMq+rZme72lIl3PUiOWPO9VVbs+PsRk58/ceCWnGCO647+KGb4jFw0vKPwP5RKmPny9a6ZSpYB2jsgWItKewdah+VPEOSLZQT/aPB5f61eiazCnuUuWrrycQVyLlELD0pj29mMxAJ0Nr1CIVboYp+YYA7dWNVSUT6T+EV6ASEC6jflb//UUUmCjOfxILGMkqvNJ2T7WguaPLOw21wLx0eDvQA/N8ZTiyKmE+GVRkDwGzC/yLeelgzyBgmyr15hfo7Q41VtAso6rzzExc4GasmgQe8z4Y0Gm7t3RDL3GXxBmonZtxNZt0vwvVyS/kAJedmPgcfxJunPnM='
+set pki certificate CLIENT certificate 'MIIFsDCCA5igAwIBAgIUSzQgwzGsfJFecGxCwLXVsGCLMkAwDQYJKoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA1MTExMjM4MzlaFw0zMzA1MDgxMjM4MzlaMFYxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxDzANBgNVBAMMBmNsaWVudDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANHNJOSwcDbRqziL1gXYnHIq7P7vEUFvS8d/XLYJ1xIpcYTRXTut2CTGRar7fZZicu7x0yoK4TzrHvGVf1o4NC4NSGV5RX6kwRdrfWBmvpIkjSLGtCREFyhb+PHDpnsIS7cfN9udC0vocqVlx/xM/sfcP6Vja/uFp+9TQcneJIxYw34zkF+TtOVbE3pP5VxU7ZAj8F5/q1ONhTMdzG4Ol4/0nBqZfdYA3LVDeSSNIJNF5jlaKXXFHz1EJRemTYDx+f5bfCVcK2Qs8fU9jCFBlATjMu9O5rgk6nMLRwEnJZuZ1gj2tWQvz4e9yo5yUqf1PUhOrn3c81MRliUNHKr+CkxgQJal6P3Ar3q4iftJih3K+/j4o194mQ/Dt/Et+/Qn/DUFk2FB0rTMcQwJLTEAzxtTdmBJeJpipIPDR0u7UMZLNh/raQ8s3FsbY4uYORt2f5YQlCVHbth4dRa9xa+oRbm7eomNACIbWfkLh5Bzud1+qIfdBMZKaZbnf0HEeuH0J5LBJeova8EPxWbYMJPrRHzu5gowkIKl+uIxcy8IiNTA9YEoJVonCjmlr8NEtYShrIVbicdMNSI3pOQR60MFhkHwBjSU2l/z+4wwLxtzq/c2xKw9yrOZ46ZVLwGDFq8rPwp7/P9r6mDKsbn6jIvGOeH71dMZvoc4lCaClw+hKIzLAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0GA1UdDgQWBBS6j30FmL6kZW7rDH8QjRMoWoA/njAfBgNVHSMEGDAWgBT+TQ2nP8gvpkJmk6WQ1L/RmTBjATANBgkqhkiG9w0BAQsFAAOCAgEANW2Y4bgaB9oexEjj6rkGvePtQmXRkF/adVQREY9iZDGTe72ePybVzrfMkZHjse3o7JvXWRIVVztWSzEpv5noIOX7lAioGG3wsFTHotTFR0zrYJHXHBcV2Neq4Kx2Ta/TZwD8QnZHAAxEQ1pYb4fxwN/A60VElAZoz9zYsbrJyVrfuHDL9queQxPFzqis+7W1BiVIcv4rn0DMQ560jTGh4t4rImOSu5gUsUrQaih85XDdOBPxViSNwfVdZJIgbvamudpfEaKsIun/uCjcxpNnzIp0rhyYmDeqVat4GnTV7Sy48e/Uvcq71ZWbBYJF4+yW4pylIU2Sh/Uy2sAz4C2M71FlFB7qsmcnPRsFFHf+r1NyD1lkVI9k2371fTG/Kub9V0rOz4pvKz4Em5b4MUPdDbZOqJ8hQ+atGE3ovFJIovA3NFb0OtnyC4l+kG7dfjqFudOnmDa+Qsya+2YOxBZBIRfuhlXhb6Y6Smsk9R6x0jBmcQTPS5ZmvKaTxQCFc53xMdQNAswjiI2L9rw4BcqQfVmf/vpoN+VusD/XEv2V0Ixm10YybA7BI/tixh9vwj3fdQXVLy3jSYjVBd5WOFPizbQZeD10ElvlLqZZyWrP/Wre7Nmi/gEOnhBXXmo034fFF/vXf0JRpQsd2oDs24+4XwZYb8mbM31j7Nx8YvhR+64='
+set pki certificate CLIENT private key 'MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDRzSTksHA20as4i9YF2JxyKuz+7xFBb0vHf1y2CdcSKXGE0V07rdgkxkWq+32WYnLu8dMqCuE86x7xlX9aODQuDUhleUV+pMEXa31gZr6SJI0ixrQkRBcoW/jxw6Z7CEu3HzfbnQtL6HKlZcf8TP7H3D+lY2v7hafvU0HJ3iSMWMN+M5Bfk7TlWxN6T+VcVO2QI/Bef6tTjYUzHcxuDpeP9JwamX3WANy1Q3kkjSCTReY5Wil1xR89RCUXpk2A8fn+W3wlXCtkLPH1PYwhQZQE4zLvTua4JOpzC0cBJyWbmdYI9rVkL8+HvcqOclKn9T1ITq593PNTEZYlDRyq/gpMYECWpej9wK96uIn7SYodyvv4+KNfeJkPw7fxLfv0J/w1BZNhQdK0zHEMCS0xAM8bU3ZgSXiaYqSDw0dLu1DGSzYf62kPLNxbG2OLmDkbdn+WEJQlR27YeHUWvcWvqEW5u3qJjQAiG1n5C4eQc7ndfqiH3QTGSmmW539BxHrh9CeSwSXqL2vBD8Vm2DCT60R87uYKMJCCpfriMXMvCIjUwPWBKCVaJwo5pa/DRLWEoayFW4nHTDUiN6TkEetDBYZB8AY0lNpf8/uMMC8bc6v3NsSsPcqzmeOmVS8BgxavKz8Ke/z/a+pgyrG5+oyLxjnh+9XTGb6HOJQmgpcPoSiMywIDAQABAoICACNXi396uWyCpXVBGSyi8LfKw2GupBmBxiI1Mkj4H2LP2G+nVS1Ye7C2NcY311AeBX56/jd23bqFYRERPgLUtPWNB0UQyMQsvNpVISm8JR45Sg0xq+bwEXabB7SyYLkZDKgsehxkuCJxZd625pl53vGMCKyzst0MBt4qCEsZQM7jpQr9ZLS1DSQV05InI1wKcnp1k2hX2WSZ0nZp7qYbjyyQ6DsS4D/MpWFjnGSr4XDttXqz1YghTMHlWNpDCYtPN+3BO4iPnj+h0qCdXZ28jlLEczAc+oDKtzPqEmv/TDaKE6Qu6x+VbkBPmG+mkoX4qfokRwCs19CGheR38PxdDx7AgySv7K8hM8gFC0XEqNdjt86KG+N1Ps5Sru4QMrf8j9XXNPUvt0M8wsPVeWa5ubkV7/h0HIEROOFpEFbzWnhBChPVvFObuuEjl5Jnj3KUEnckQFU07mPP/BpysHo3v/p+VTVoo2UkfVvjamnwQOUt3cVlPVC4FzVgkswJa4f75nGmDv8dafyPrCYciOh0qyhD5Pw/EBJkKtDBYHaoxtAw9Ann4A5rvZAveLNTPESOMo90pJwJbQcZyq9H+UGVnde39I4m5vHB5izZJI24Yd3fjRRkRf+/68VYKrkI5B7oH73Z/cl/xgEdI1hag4MLv1gon8wna4yCX/321YPTrDABAoIBAQDpHtvnvpOaoSjkJHUx4EGJkrp5R/mPfEbzzU2Ov5pNIcufv++2lsoUVCTDwgp4+7GngqYO5vVyW/AS4pSrDx7kdWpFaUtJUUCcCHk/5hYcvvourYtW1NR+XPiI28IqRp1P0L1+P0mUaRgpEcw6nEnc37XEujvTB1M/yF2y6xc+kZGjrZTmJeu0V5kkaGcXlAqUv2k0Lj3tEPQR/qj+kMX5hidROGuybNBESgA5ELY6QVnpcOyNDyniWq+RIUyBOuXp7DpUbmUANFEEP8lwjZX+HqwTpSjTSFdcPrsmorc9FpTXA9ktt1Z0ZxBzUvdcWbUeVsFqL0yICiShE7UxlOPBAoIBAQDmZGQ5roSKKY+VnmjIq2+gx8zsMYeliQm0hnKrFw9MM8U+/XOpXlpNHx2ehrGWp/BbmlmrnQaRcbLPJaRtWSEywbWnG77g+zj0w+4BdsYyTtGGFj4tXVZhPPo/DID3FPLn9cSv8MIVWjzg1G/BZcxtCDBDRBhwhZHCPOfd0K/S7rvRBq7IsNNHMTGswWGRMaF+M/trZw7TsQ0BX+5zZUyO8VNBi/NgTV3yoQ8ynBefRt1dmNa2CKXPT+5R19cBtecFEyhc3yo8ryTtM22JzndzA8agQmNPnWmYGivvcNHNikTQ2qUvvcd7Siny6j0+CmFdT9bl64VPyRJrFCw3jaOLAoIBAQCQ/1OyShRO+myPsql+U0kQQ8Zeh0kPWTJclFboMf7MePfJLj3waMvaZxfS9s9CvvKaCSY2YKtL7Sle5bWozCff27Q05jAgszwnkRGxj/AzAwpjnCft40UkL7majm2vk+pm6aPjcYPXnqKbcOmBjxJWIoNRkLCDKqw6IOs+zQDRNwPKNb5GhFGeA1pKjfGJddg6+u95uEVmPcRBqQ79/5hUAoBUAW7jNNE5mHmZBO8DPwCotUc82bCojNVkxLxsKPE2VWtWdq+1t9SoevBVZItl2zgWpATHndhQlOgdONoWUgRT1J3x1HYewrg1suYOd/GypC17WV4Vw5FS6wopg71BAoIBAQC63vDgTGpauk0pOVyab1tSmNzhM2dn4BhMIcU+eqzAzTkO13sKBGrQJQ3cODoxDbSKSE61QN9D92nmVQziWKnxxmb1zS5sw7g15/nTnCg0Q/P0g3QZTZyzsEb1/slYH9jKRnErl+eEdDXu0sB2qIBAa6Th2ojMM7q/RrF3HD6Qo20ZpQb951bnZsJ48j2WDCCGAdnLCsNe9zuqQsphNOf9BUbXYpGcKgSquPJfxXXvjgYdVcvJyIfc+GNAZQaS750bY6eYdLaIlDMqZk1RunLuikCAWni86dvtMEU0qFi0E5Ovp7jWWWNE4CnYSyAzgy3oBssyoG74AQp8addXk/3zAoIBAQC8/7DglQGMcKnk4zX+7jCuc0p+qMcd5RdnfBKlRhcWYNRPup9jyDefdkXCBTumCHXrIil/rJzP6b1IZZdC4xkheQpLXNUcceAidRWIrTypaXKkmhR0D74uckGiLXB4S84HYmIdw89ZiF0gB0yyZH5mZnqVMojwnGmWqcM2sr2N44bNQMfhD+nCSgQmReYKKfMQCdvYMxRLQfseU0pFEOGnh9jAmpn8qWMWxNDmFR/rVl26BXtRPiNPimfwWKrYNYhESN7A5/hWcrNUhE4PI+Pjd74npimqs5TDSst2Jc6DiahdaZ6JNNzp2PMUXNbfsMCVgZx+qtVNnVxVMiEngPRl'
+set pki dh DH parameters 'MIIBCAKCAQEAzPOQWrWaIX2qt4sbV6bRbUnFx4jmeE+WXC8GIvulnC4pIr1nt2Gc/7uNfEPjDZ4X6csD3X6zAWxtSuWeNuml9Yuy+tS8gI7d0FlbQRAFO/9GIlRuVdMcbCtEhg8ja7Y0g3fQjOSQJ9mqFo7sRoXyYQALD+MDEJOxhnV7neCrgDi1pqnN4xZLoR9DLARp0ad30VIvnv0ay55wxFWAKh2iwNRwyeXIEOtUDBkfcLGSNNfK0kQsos/J8Q+7YXmk4cN9tiVX4xR92edVO4z/vhMkjsGKLSDm/E6EMusX+N0UhQ3dv7qDgeSS8vDsqBm8XJonumNZLvFbYt2ARGRZYL6DUwIBAg=='
+```
+
+Once all the required certificates and keys are installed, the remaining
+OpenVPN Server configuration can be carried out.
+
+```{literalinclude} _include/ovpn-server.conf
+:language: none
+```
+
+
+## Client configuration
+
+One advantage of having the client certificate stored is the ability to create the client configuration.
+
+```none
+vyos@ovpn-server:~$ generate openvpn client-config interface vtun10 ca OVPN-CA certificate CLIENT
+```
+
+save the output to a file and import it in nearly all openvpn clients.
+
+```none
+client
+nobind
+remote 198.51.100.254 1194
+remote-cert-tls server
+proto udp
+dev tun
+dev-type tun
+persist-key
+persist-tun
+verb 3
+
+# Encryption options
+
+keysize 256
+comp-lzo no
+
+<ca>
+-----BEGIN CERTIFICATE-----
+MIIFnTCCA4WgAwIBAgIUIPFIXvCxYdavCnSPFNjr6lUtlsswDQYJKoZIhvcNAQEL
+BQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcM
+CVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0y
+MzA1MTExMjM4MjJaFw0zMzA1MDgxMjM4MjJaMFcxCzAJBgNVBAYTAkdCMRMwEQYD
+VQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5
+T1MxEDAOBgNVBAMMB3Z5b3MuaW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQDg45vAzS6xNqU+Pa7wk1Imt1/az1C22Sbp3wPJLfgOmy0K3TA5qVsx/c/8
+gatsatMkCsekGnK5BPzCDd5eCCLo//B25HFO6fBYRNvHvVyCUx7QEXw4FHFNG88z
+CIizx114AGtVwZfGGG9xCc53xjLPUpH6iqTXme41cCFFQlqXwZ7fuySieSdoV8SA
+sJTTOsGCEUEcDEnNPn6tX3KWTzNuyFPECy8WCmNgWNyG2nmH+U7WRTX0ehZ5dZyU
+5au7TxpRN4a+JtE0gNqcWJ+nh1A543q2pcRoQpPAzHFclgj8wG/EyauQMY/LC4tL
+c6moPaNlTwA9HJv8s6xUqpzNptDoUHKOqKuw2JRFnno5SCQ788KkKNgVWBy2o3BG
+oewfHFhAdR61CXeLpmuneuhi96GcM031gW8ptXbd4DkCF7H6KRtqeIvwiyG79ttC
+8kZf01Sn1fM5fTjGxaE38dAk/RchtHRC6rtFavHJjB2cUcCkhhQofUE6IR2dYJZ1
+cw0Wy5CI3bXHf43BpvDGmuxIlNGirTq8wf5RCWzDJJgmkQpYhUYe8x4faF4gTo00
+uH4ZvAYjQu3JNZGkb50p4kM9Mu5rQAiZJUeMAz/QD+EIV9xXgOk14+BbnHKWbZ7O
+u5emewFuE/bjl79oNJklpXdc4soRkCPCTEGK3zDBdmUtCYk1DwIDAQABo2EwXzAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEF
+BQcDAgYIKwYBBQUHAwEwHQYDVR0OBBYEFP5NDac/yC+mQmaTpZDUv9GZMGMBMA0G
+CSqGSIb3DQEBCwUAA4ICAQDEqpF2ibwYFxsF1XDIPS5/Gs0sZTZBuByNm5d2+jTy
+O7d5alZUdbvobbwhxZOhWasmFNyPLr4TYmZm5zF+efFsiOxjyRuEoVU+Fe8rZmpR
+IF/+6+nYX5r9vMI4QxGjeeyP20OHJ85Kvz182CTsITrM15Vw/kVVjAVzFI5Gm/Qo
+lalAoFQza9rAL4kDqaUszjHjPbysvDpGF+NLPjiYDHXcty/BC48bnuzAeEM60SGZ
+7EXvf8l0X8YsO7z39w6780A/3rbZvFhCYMKp/+p5xBRDjnX91dM6DJw73RwYQ1KH
+bHk9wWUwnL1giL71jzp/y4Oj6SSK2PQv+OnO80J6Zg06WIQx9xYcxr108Xh9FotU
+rlG7GYPI3Udf95t6SjuydDhULAVD0lMBxlDe9DHW1k1q1pOXaHZg926tY66xx/ld
+a6dcuwJjA2Dx5JI6L0u9ureQmQAtxvnoTCtf+hR1iX/IkskZCKs34SjNiCnBuw/D
+NfdOpfaABm7y+tWiXBwnu5l/K8poXcQYQByyZj6YMmpgsbVPr5KNsLWOgRA81M6I
+Pof8qxvnFrkazhiQWh1YHSjnaHtA3z5/BdgwHVICuFyrIOlbkKyJOjKcKBsDdMwI
+V0tsnpnyli2xEPZKu1tAQFAavXrK/RGYYhOZ3e0aRSV8hlP8i/mf7p0I45cJiBCq
+Pg==
+-----END CERTIFICATE-----
+
+</ca>
+
+<cert>
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIUSzQgwzGsfJFecGxCwLXVsGCLMkAwDQYJKoZIhvcNAQEL
+BQAwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcM
+CVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0y
+MzA1MTExMjM4MzlaFw0zMzA1MDgxMjM4MzlaMFYxCzAJBgNVBAYTAkdCMRMwEQYD
+VQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5
+T1MxDzANBgNVBAMMBmNsaWVudDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBANHNJOSwcDbRqziL1gXYnHIq7P7vEUFvS8d/XLYJ1xIpcYTRXTut2CTGRar7
+fZZicu7x0yoK4TzrHvGVf1o4NC4NSGV5RX6kwRdrfWBmvpIkjSLGtCREFyhb+PHD
+pnsIS7cfN9udC0vocqVlx/xM/sfcP6Vja/uFp+9TQcneJIxYw34zkF+TtOVbE3pP
+5VxU7ZAj8F5/q1ONhTMdzG4Ol4/0nBqZfdYA3LVDeSSNIJNF5jlaKXXFHz1EJRem
+TYDx+f5bfCVcK2Qs8fU9jCFBlATjMu9O5rgk6nMLRwEnJZuZ1gj2tWQvz4e9yo5y
+Uqf1PUhOrn3c81MRliUNHKr+CkxgQJal6P3Ar3q4iftJih3K+/j4o194mQ/Dt/Et
++/Qn/DUFk2FB0rTMcQwJLTEAzxtTdmBJeJpipIPDR0u7UMZLNh/raQ8s3FsbY4uY
+ORt2f5YQlCVHbth4dRa9xa+oRbm7eomNACIbWfkLh5Bzud1+qIfdBMZKaZbnf0HE
+euH0J5LBJeova8EPxWbYMJPrRHzu5gowkIKl+uIxcy8IiNTA9YEoJVonCjmlr8NE
+tYShrIVbicdMNSI3pOQR60MFhkHwBjSU2l/z+4wwLxtzq/c2xKw9yrOZ46ZVLwGD
+Fq8rPwp7/P9r6mDKsbn6jIvGOeH71dMZvoc4lCaClw+hKIzLAgMBAAGjdTBzMAwG
+A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMC
+MB0GA1UdDgQWBBS6j30FmL6kZW7rDH8QjRMoWoA/njAfBgNVHSMEGDAWgBT+TQ2n
+P8gvpkJmk6WQ1L/RmTBjATANBgkqhkiG9w0BAQsFAAOCAgEANW2Y4bgaB9oexEjj
+6rkGvePtQmXRkF/adVQREY9iZDGTe72ePybVzrfMkZHjse3o7JvXWRIVVztWSzEp
+v5noIOX7lAioGG3wsFTHotTFR0zrYJHXHBcV2Neq4Kx2Ta/TZwD8QnZHAAxEQ1pY
+b4fxwN/A60VElAZoz9zYsbrJyVrfuHDL9queQxPFzqis+7W1BiVIcv4rn0DMQ560
+jTGh4t4rImOSu5gUsUrQaih85XDdOBPxViSNwfVdZJIgbvamudpfEaKsIun/uCjc
+xpNnzIp0rhyYmDeqVat4GnTV7Sy48e/Uvcq71ZWbBYJF4+yW4pylIU2Sh/Uy2sAz
+4C2M71FlFB7qsmcnPRsFFHf+r1NyD1lkVI9k2371fTG/Kub9V0rOz4pvKz4Em5b4
+MUPdDbZOqJ8hQ+atGE3ovFJIovA3NFb0OtnyC4l+kG7dfjqFudOnmDa+Qsya+2YO
+xBZBIRfuhlXhb6Y6Smsk9R6x0jBmcQTPS5ZmvKaTxQCFc53xMdQNAswjiI2L9rw4
+BcqQfVmf/vpoN+VusD/XEv2V0Ixm10YybA7BI/tixh9vwj3fdQXVLy3jSYjVBd5W
+OFPizbQZeD10ElvlLqZZyWrP/Wre7Nmi/gEOnhBXXmo034fFF/vXf0JRpQsd2oDs
+24+4XwZYb8mbM31j7Nx8YvhR+64=
+-----END CERTIFICATE-----
+
+</cert>
+
+<key>
+-----BEGIN PRIVATE KEY-----
+MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDRzSTksHA20as4
+i9YF2JxyKuz+7xFBb0vHf1y2CdcSKXGE0V07rdgkxkWq+32WYnLu8dMqCuE86x7x
+lX9aODQuDUhleUV+pMEXa31gZr6SJI0ixrQkRBcoW/jxw6Z7CEu3HzfbnQtL6HKl
+Zcf8TP7H3D+lY2v7hafvU0HJ3iSMWMN+M5Bfk7TlWxN6T+VcVO2QI/Bef6tTjYUz
+HcxuDpeP9JwamX3WANy1Q3kkjSCTReY5Wil1xR89RCUXpk2A8fn+W3wlXCtkLPH1
+PYwhQZQE4zLvTua4JOpzC0cBJyWbmdYI9rVkL8+HvcqOclKn9T1ITq593PNTEZYl
+DRyq/gpMYECWpej9wK96uIn7SYodyvv4+KNfeJkPw7fxLfv0J/w1BZNhQdK0zHEM
+CS0xAM8bU3ZgSXiaYqSDw0dLu1DGSzYf62kPLNxbG2OLmDkbdn+WEJQlR27YeHUW
+vcWvqEW5u3qJjQAiG1n5C4eQc7ndfqiH3QTGSmmW539BxHrh9CeSwSXqL2vBD8Vm
+2DCT60R87uYKMJCCpfriMXMvCIjUwPWBKCVaJwo5pa/DRLWEoayFW4nHTDUiN6Tk
+EetDBYZB8AY0lNpf8/uMMC8bc6v3NsSsPcqzmeOmVS8BgxavKz8Ke/z/a+pgyrG5
++oyLxjnh+9XTGb6HOJQmgpcPoSiMywIDAQABAoICACNXi396uWyCpXVBGSyi8LfK
+w2GupBmBxiI1Mkj4H2LP2G+nVS1Ye7C2NcY311AeBX56/jd23bqFYRERPgLUtPWN
+B0UQyMQsvNpVISm8JR45Sg0xq+bwEXabB7SyYLkZDKgsehxkuCJxZd625pl53vGM
+CKyzst0MBt4qCEsZQM7jpQr9ZLS1DSQV05InI1wKcnp1k2hX2WSZ0nZp7qYbjyyQ
+6DsS4D/MpWFjnGSr4XDttXqz1YghTMHlWNpDCYtPN+3BO4iPnj+h0qCdXZ28jlLE
+czAc+oDKtzPqEmv/TDaKE6Qu6x+VbkBPmG+mkoX4qfokRwCs19CGheR38PxdDx7A
+gySv7K8hM8gFC0XEqNdjt86KG+N1Ps5Sru4QMrf8j9XXNPUvt0M8wsPVeWa5ubkV
+7/h0HIEROOFpEFbzWnhBChPVvFObuuEjl5Jnj3KUEnckQFU07mPP/BpysHo3v/p+
+VTVoo2UkfVvjamnwQOUt3cVlPVC4FzVgkswJa4f75nGmDv8dafyPrCYciOh0qyhD
+5Pw/EBJkKtDBYHaoxtAw9Ann4A5rvZAveLNTPESOMo90pJwJbQcZyq9H+UGVnde3
+9I4m5vHB5izZJI24Yd3fjRRkRf+/68VYKrkI5B7oH73Z/cl/xgEdI1hag4MLv1go
+n8wna4yCX/321YPTrDABAoIBAQDpHtvnvpOaoSjkJHUx4EGJkrp5R/mPfEbzzU2O
+v5pNIcufv++2lsoUVCTDwgp4+7GngqYO5vVyW/AS4pSrDx7kdWpFaUtJUUCcCHk/
+5hYcvvourYtW1NR+XPiI28IqRp1P0L1+P0mUaRgpEcw6nEnc37XEujvTB1M/yF2y
+6xc+kZGjrZTmJeu0V5kkaGcXlAqUv2k0Lj3tEPQR/qj+kMX5hidROGuybNBESgA5
+ELY6QVnpcOyNDyniWq+RIUyBOuXp7DpUbmUANFEEP8lwjZX+HqwTpSjTSFdcPrsm
+orc9FpTXA9ktt1Z0ZxBzUvdcWbUeVsFqL0yICiShE7UxlOPBAoIBAQDmZGQ5roSK
+KY+VnmjIq2+gx8zsMYeliQm0hnKrFw9MM8U+/XOpXlpNHx2ehrGWp/BbmlmrnQaR
+cbLPJaRtWSEywbWnG77g+zj0w+4BdsYyTtGGFj4tXVZhPPo/DID3FPLn9cSv8MIV
+Wjzg1G/BZcxtCDBDRBhwhZHCPOfd0K/S7rvRBq7IsNNHMTGswWGRMaF+M/trZw7T
+sQ0BX+5zZUyO8VNBi/NgTV3yoQ8ynBefRt1dmNa2CKXPT+5R19cBtecFEyhc3yo8
+ryTtM22JzndzA8agQmNPnWmYGivvcNHNikTQ2qUvvcd7Siny6j0+CmFdT9bl64VP
+yRJrFCw3jaOLAoIBAQCQ/1OyShRO+myPsql+U0kQQ8Zeh0kPWTJclFboMf7MePfJ
+Lj3waMvaZxfS9s9CvvKaCSY2YKtL7Sle5bWozCff27Q05jAgszwnkRGxj/AzAwpj
+nCft40UkL7majm2vk+pm6aPjcYPXnqKbcOmBjxJWIoNRkLCDKqw6IOs+zQDRNwPK
+Nb5GhFGeA1pKjfGJddg6+u95uEVmPcRBqQ79/5hUAoBUAW7jNNE5mHmZBO8DPwCo
+tUc82bCojNVkxLxsKPE2VWtWdq+1t9SoevBVZItl2zgWpATHndhQlOgdONoWUgRT
+1J3x1HYewrg1suYOd/GypC17WV4Vw5FS6wopg71BAoIBAQC63vDgTGpauk0pOVya
+b1tSmNzhM2dn4BhMIcU+eqzAzTkO13sKBGrQJQ3cODoxDbSKSE61QN9D92nmVQzi
+WKnxxmb1zS5sw7g15/nTnCg0Q/P0g3QZTZyzsEb1/slYH9jKRnErl+eEdDXu0sB2
+qIBAa6Th2ojMM7q/RrF3HD6Qo20ZpQb951bnZsJ48j2WDCCGAdnLCsNe9zuqQsph
+NOf9BUbXYpGcKgSquPJfxXXvjgYdVcvJyIfc+GNAZQaS750bY6eYdLaIlDMqZk1R
+unLuikCAWni86dvtMEU0qFi0E5Ovp7jWWWNE4CnYSyAzgy3oBssyoG74AQp8addX
+k/3zAoIBAQC8/7DglQGMcKnk4zX+7jCuc0p+qMcd5RdnfBKlRhcWYNRPup9jyDef
+dkXCBTumCHXrIil/rJzP6b1IZZdC4xkheQpLXNUcceAidRWIrTypaXKkmhR0D74u
+ckGiLXB4S84HYmIdw89ZiF0gB0yyZH5mZnqVMojwnGmWqcM2sr2N44bNQMfhD+nC
+SgQmReYKKfMQCdvYMxRLQfseU0pFEOGnh9jAmpn8qWMWxNDmFR/rVl26BXtRPiNP
+imfwWKrYNYhESN7A5/hWcrNUhE4PI+Pjd74npimqs5TDSst2Jc6DiahdaZ6JNNzp
+2PMUXNbfsMCVgZx+qtVNnVxVMiEngPRl
+-----END PRIVATE KEY-----
+
+</key>
+```
+
+
+### Configure VyOS as client
+
+```none
+set interfaces openvpn vtun10 authentication username 'user01'
+set interfaces openvpn vtun10 authentication password '$ecret'
+set interfaces openvpn vtun10 encryption cipher 'aes256'
+set interfaces openvpn vtun10 hash 'sha512'
+set interfaces openvpn vtun10 mode 'client'
+set interfaces openvpn vtun10 persistent-tunnel
+set interfaces openvpn vtun10 protocol 'udp'
+set interfaces openvpn vtun10 remote-host '198.51.100.254'
+set interfaces openvpn vtun10 remote-port '1194'
+set interfaces openvpn vtun10 tls ca-certificate 'OVPN-CA'
+set interfaces openvpn vtun10 tls certificate 'CLIENT'
+```
+
+
+## Monitoring
+
+If the client is connected successfully you can check the status
+
+```none
+vyos@ovpn-server:~$ show openvpn server
+OpenVPN status on vtun10
+
+Client CN Remote Host Tunnel IP Local Host TX bytes RX bytes Connected Since
+----------- ------------------ ----------- ------------------- ---------- ---------- -------------------
+client 198.51.100.1:55150 10.23.1.6 198.51.100.254:1194 4.7 KB 4.7 KB 2023-05-11 12:47:11
+```
diff --git a/docs/configexamples/autotest/OpenVPN_with_LDAP/_include/topology.png b/docs/configexamples/autotest/OpenVPN_with_LDAP/_include/topology.png
deleted file mode 100644
index 382e44f6..00000000
--- a/docs/configexamples/autotest/OpenVPN_with_LDAP/_include/topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/configexamples/autotest/Wireguard/Wireguard.md b/docs/configexamples/autotest/Wireguard/Wireguard.md
new file mode 100644
index 00000000..7bbf4c55
--- /dev/null
+++ b/docs/configexamples/autotest/Wireguard/Wireguard.md
@@ -0,0 +1,108 @@
+# Wireguard
+
+```{eval-rst}
+| Testdate: 2024-01-13
+| Version: 1.5-rolling-202401121239
+```
+
+This simple structure show how to connect two offices. One remote branch and the
+central office.
+
+## Topology
+
+The topology have a central and a branch VyOS router and one client, to
+test, in each site.
+
+```{image} _include/topology.webp
+:alt: Ansible Example topology image
+```
+
+
+## Configuration
+
+Set the local subnet on eth2 and the public ip address eth1 on each site.
+
+Central
+
+```{literalinclude} _include/central.conf
+:language: none
+:lines: 1-2
+```
+
+Branch
+
+```{literalinclude} _include/branch.conf
+:language: none
+:lines: 1-2
+```
+
+Next thing to do, is to create a wireguard keypair on each side.
+After this, the public key can be displayed, to save for later.
+
+```none
+vyos@central:~$ generate pki wireguard
+Private key: wHQS+ib3eMIp2DxRiAeXfFVaSCMMP1YHBaKfSR1xfV8=
+Public key: RCMy6BAER0uEcPvspUb3K38MHyHJpK5kiV5IOX943HI=
+```
+
+After you have each public key. The wireguard interfaces can be setup.
+
+Central
+
+```{literalinclude} _include/central.conf
+:language: none
+:lines: 4-12
+```
+
+Branch
+
+```{literalinclude} _include/branch.conf
+:language: none
+:lines: 4-12
+```
+
+To reach the network, a route must be set on each VyOS host.
+In this structure, a static interface route will fit the requirements.
+
+Central
+
+```{literalinclude} _include/central.conf
+:language: none
+:lines: 14
+```
+
+Branch
+
+```{literalinclude} _include/branch.conf
+:language: none
+:lines: 14
+```
+
+
+## Testing and debugging
+
+After all is done and commit, let's take a look if the Wireguard interface is
+up and running.
+
+```none
+vyos@central:~$ show interfaces wireguard
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+wg01 192.168.0.1/24 u/u VPN-to-Branch
+```
+
+And ping the Branch PC from your central router to check the response.
+
+```none
+vyos@central:~$ ping 10.0.2.100 count 4
+PING 10.0.2.100 (10.0.2.100) 56(84) bytes of data.
+64 bytes from 10.0.2.100: icmp_seq=1 ttl=63 time=0.894 ms
+64 bytes from 10.0.2.100: icmp_seq=2 ttl=63 time=0.869 ms
+64 bytes from 10.0.2.100: icmp_seq=3 ttl=63 time=0.966 ms
+64 bytes from 10.0.2.100: icmp_seq=4 ttl=63 time=0.998 ms
+
+--- 10.0.2.100 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3004ms
+rtt min/avg/max/mdev = 0.869/0.931/0.998/0.052 ms
+```
diff --git a/docs/configexamples/autotest/Wireguard/_include/topology.png b/docs/configexamples/autotest/Wireguard/_include/topology.png
deleted file mode 100644
index 43c0018e..00000000
--- a/docs/configexamples/autotest/Wireguard/_include/topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/configexamples/autotest/tunnelbroker/_include/topology.png b/docs/configexamples/autotest/tunnelbroker/_include/topology.png
deleted file mode 100644
index e70d55bc..00000000
--- a/docs/configexamples/autotest/tunnelbroker/_include/topology.png
+++ /dev/null
Binary files differ
diff --git a/docs/configexamples/autotest/tunnelbroker/tunnelbroker.md b/docs/configexamples/autotest/tunnelbroker/tunnelbroker.md
new file mode 100644
index 00000000..8600f8d7
--- /dev/null
+++ b/docs/configexamples/autotest/tunnelbroker/tunnelbroker.md
@@ -0,0 +1,206 @@
+(examples-tunnelbroker-ipv6)=
+
+# Tunnelbroker.net (IPv6)
+
+```{eval-rst}
+| Testdate: 2024-01-13
+| Version: 1.5-rolling-202401121239
+```
+
+This guide walks through the setup of <https://www.tunnelbroker.net/> for an
+IPv6 Tunnel.
+
+## Prerequisites
+
+- A public, routable IPv4 address. This does not necessarily need to be static,
+ but you will need to update the tunnel endpoint when/if your IP address
+ changes, which can be done with a script and a scheduled task.
+- Account at <https://www.tunnelbroker.net/>
+- Requested a "Regular Tunnel". You want to choose a location that is closest
+ to your physical location for the best response time.
+
+### Topology
+
+The example topology has 2 VyOS routers. One as the WAN router and one as a
+client, to test a single LAN setup
+
+```{image} _include/topology.webp
+:alt: Tunnelbroker topology image
+```
+
+
+### Configuration
+
+First, we configure the `vyos-wan` interface to get a DHCP address.
+
+```{literalinclude} _include/vyos-wan.conf
+:language: none
+```
+
+Now we are able to setup the tunnel interface.
+
+```{literalinclude} _include/vyos-wan_tun0.conf
+:language: none
+:lines: 1-5
+```
+
+:::{note}
+The `source-address` is the Tunnelbroker client IPv4
+address or if there is NAT the current WAN interface address.
+
+If `source-address` is dynamic, the tunnel will cease working once
+the address changes. To avoid having to manually update
+`source-address` each time the dynamic IP changes, an address of
+'0.0.0.0' can be specified.
+:::
+
+Setup the IPv6 default route to the tunnel interface
+
+```{literalinclude} _include/vyos-wan_tun0.conf
+:language: none
+:lines: 7
+```
+
+Now you should be able to ping a public IPv6 Address
+
+```none
+vyos@vyos-wan:~$ ping 2001:470:20::2 count 4
+PING 2001:470:20::2(2001:470:20::2) 56 data bytes
+64 bytes from 2001:470:20::2: icmp_seq=1 ttl=64 time=33.8 ms
+64 bytes from 2001:470:20::2: icmp_seq=2 ttl=64 time=43.9 ms
+64 bytes from 2001:470:20::2: icmp_seq=3 ttl=64 time=43.4 ms
+64 bytes from 2001:470:20::2: icmp_seq=4 ttl=64 time=42.5 ms
+
+--- 2001:470:20::2 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 2999ms
+rtt min/avg/max/mdev = 33.802/40.920/43.924/4.139 ms
+```
+
+Assuming the pings are successful, you need to add some DNS servers.
+Some options:
+
+```{literalinclude} _include/vyos-wan_tun0.conf
+:language: none
+:lines: 13
+```
+
+You should now be able to ping something by IPv6 DNS name:
+
+```none
+vyos@vyos-wan:~$ ping tunnelbroker.net count 4
+PING tunnelbroker.net(tunnelbroker.net (2001:470:0:63::2)) 56 data bytes
+64 bytes from tunnelbroker.net (2001:470:0:63::2): icmp_seq=1 ttl=48 time=285 ms
+64 bytes from tunnelbroker.net (2001:470:0:63::2): icmp_seq=2 ttl=48 time=186 ms
+64 bytes from tunnelbroker.net (2001:470:0:63::2): icmp_seq=3 ttl=48 time=178 ms
+64 bytes from tunnelbroker.net (2001:470:0:63::2): icmp_seq=4 ttl=48 time=177 ms
+
+--- tunnelbroker.net ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3002ms
+rtt min/avg/max/mdev = 176.707/206.638/285.128/45.457 ms
+```
+
+
+### LAN Configuration
+
+At this point, your VyOS install should have full IPv6, but now your LAN devices
+need access.
+
+With Tunnelbroker.net, you have two options:
+
+- Routed /64. This is the default assignment. In IPv6-land, it's good for a
+ single "LAN", and is somewhat equivalent to a /24.
+- Routed /48. This is something you can request by clicking the "Assign /48"
+ link in the Tunnelbroker.net tunnel config. It allows you to have up to 65k
+
+Unlike IPv4, IPv6 is really not designed to be broken up smaller than /64. So
+if you ever want to have multiple LANs, VLANs, DMZ, etc, you'll want to ignore
+the assigned /64, and request the /48 and use that.
+
+## Single LAN Setup
+
+Single LAN setup where eth2 is your LAN interface. Use the Tunnelbroker
+Routed /64 prefix:
+
+```{literalinclude} _include/vyos-wan_tun0.conf
+:language: none
+:lines: 9-11
+```
+
+Please note, 'autonomous-flag' and 'on-link-flag' are enabled by default,
+'valid-lifetime' and 'preferred-lifetime' are set to default values of
+30 days and 4 hours respectively.
+
+And the `client` to receive an IPv6 address with stateless autoconfig.
+
+```{literalinclude} _include/client.conf
+:language: none
+```
+
+This accomplishes a few things:
+- Sets your LAN interface's IP address
+- Enables router advertisements. This is an IPv6 alternative for DHCP (though
+ DHCPv6 can still be used). With RAs, Your devices will automatically find the
+ information they need for routing and DNS.
+
+Now the Client is able to ping a public IPv6 address
+
+```none
+vyos@client:~$ ping 2001:470:20::2 count 4
+PING 2001:470:20::2(2001:470:20::2) 56 data bytes
+64 bytes from 2001:470:20::2: icmp_seq=1 ttl=63 time=32.1 ms
+64 bytes from 2001:470:20::2: icmp_seq=2 ttl=63 time=41.8 ms
+64 bytes from 2001:470:20::2: icmp_seq=3 ttl=63 time=41.7 ms
+64 bytes from 2001:470:20::2: icmp_seq=4 ttl=63 time=47.1 ms
+
+--- 2001:470:20::2 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3005ms
+rtt min/avg/max/mdev = 32.128/40.688/47.107/5.403 ms
+```
+
+
+## Multiple LAN/DMZ Setup
+
+That's how you can expand the example above.
+Use the `Routed /48` information. This allows you to assign a
+different /64 to every interface, LAN, or even device. Or you could break your
+network into smaller chunks like /56 or /60.
+
+The format of these addresses:
+- `2001:470:xxxx::/48`: The whole subnet. xxxx should come from Tunnelbroker.
+- `2001:470:xxxx:1::/64`: A subnet suitable for a LAN
+- `2001:470:xxxx:2::/64`: Another subnet
+- `2001:470:xxxx:ffff:/64`: The last usable /64 subnet.
+
+In the above examples, 1,2,ffff are all chosen by you. You can use 1-ffff
+(1-65535).
+
+So, when your LAN is eth1, your DMZ is eth2, your cameras are on eth3, etc:
+
+```none
+set interfaces ethernet eth1 address '2001:470:xxxx:1::1/64'
+set service router-advert interface eth1 name-server '2001:470:20::2'
+set service router-advert interface eth1 prefix 2001:470:xxxx:1::/64
+
+set interfaces ethernet eth2 address '2001:470:xxxx:2::1/64'
+set service router-advert interface eth2 name-server '2001:470:20::2'
+set service router-advert interface eth2 prefix 2001:470:xxxx:2::/64
+
+set interfaces ethernet eth3 address '2001:470:xxxx:3::1/64'
+set service router-advert interface eth3 name-server '2001:470:20::2'
+set service router-advert interface eth3 prefix 2001:470:xxxx:3::/64
+```
+
+Please note, 'autonomous-flag' and 'on-link-flag' are enabled by default,
+'valid-lifetime' and 'preferred-lifetime' are set to default values of
+30 days and 4 hours respectively.
+
+## Firewall
+
+Finally, don't forget the
+{ref}`Firewall <configuration/firewall/index:Firewall>`. The usage is
+identical, except instead of `set firewall ipv4 name NAME`, you would
+use `set firewall ipv6 name NAME`.
+
+Similarly, to attach the firewall, you would use
+`set firewall ipv6 name NAME rule N inbound-interface name eth0` or
+`set firewall zone LOCAL from WAN firewall ipv6-name`.
diff --git a/docs/configexamples/azure-vpn-bgp.md b/docs/configexamples/azure-vpn-bgp.md
new file mode 100644
index 00000000..180992a7
--- /dev/null
+++ b/docs/configexamples/azure-vpn-bgp.md
@@ -0,0 +1,134 @@
+---
+lastproofread: '2021-06-28'
+---
+
+(examples-azure-vpn-bgp)=
+
+# Route-Based Site-to-Site VPN to Azure (BGP over IKEv2/IPsec)
+
+This guide shows an example of a route-based IKEv2 site-to-site VPN to
+Azure using VTI and BGP for dynamic routing updates.
+
+For redundant / active-active configurations see
+{ref}`examples-azure-vpn-dual-bgp`
+
+## Prerequisites
+
+- A pair of Azure VNet Gateways deployed in active-passive
+ configuration with BGP enabled.
+- A local network gateway deployed in Azure representing
+ the Vyos device, matching the below Vyos settings except for
+ address space, which only requires the Vyos private IP, in
+ this example 10.10.0.5/32
+- A connection resource deployed in Azure linking the
+ Azure VNet gateway and the local network gateway representing
+ the Vyos device.
+
+## Example
+
+```{eval-rst}
++---------------------------------------+---------------------+
+| WAN Interface | eth0 |
++---------------------------------------+---------------------+
+| On-premises address space | 10.10.0.0/16 |
++---------------------------------------+---------------------+
+| Azure address space | 10.0.0.0/16 |
++---------------------------------------+---------------------+
+| Vyos public IP | 198.51.100.3 |
++---------------------------------------+---------------------+
+| Vyos private IP | 10.10.0.5 |
++---------------------------------------+---------------------+
+| Azure VNet Gateway public IP | 203.0.113.2 |
++---------------------------------------+---------------------+
+| Azure VNet Gateway BGP IP | 10.0.0.4 |
++---------------------------------------+---------------------+
+| Pre-shared key | ch00s3-4-s3cur3-psk |
++---------------------------------------+---------------------+
+| Vyos ASN | 64499 |
++---------------------------------------+---------------------+
+| Azure ASN | 65540 |
++---------------------------------------+---------------------+
+```
+
+## Vyos configuration
+
+- Configure the IKE and ESP settings to match a subset
+ of those supported by Azure:
+
+```none
+set vpn ipsec esp-group AZURE lifetime '3600'
+set vpn ipsec esp-group AZURE mode 'tunnel'
+set vpn ipsec esp-group AZURE pfs 'dh-group2'
+set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256'
+set vpn ipsec esp-group AZURE proposal 1 hash 'sha1'
+
+set vpn ipsec ike-group AZURE dead-peer-detection action 'restart'
+set vpn ipsec ike-group AZURE dead-peer-detection interval '15'
+set vpn ipsec ike-group AZURE dead-peer-detection timeout '30'
+set vpn ipsec ike-group AZURE ikev2-reauth
+set vpn ipsec ike-group AZURE key-exchange 'ikev2'
+set vpn ipsec ike-group AZURE lifetime '28800'
+set vpn ipsec ike-group AZURE proposal 1 dh-group '2'
+set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256'
+set vpn ipsec ike-group AZURE proposal 1 hash 'sha1'
+```
+
+- Enable IPsec on eth0
+
+```none
+set vpn ipsec interface 'eth0'
+```
+
+- Configure a VTI with a dummy IP address
+
+```none
+set interfaces vti vti1 address '10.10.1.5/32'
+set interfaces vti vti1 description 'Azure Tunnel'
+```
+
+- Clamp the VTI's MSS to 1350 to avoid PMTU blackholes.
+
+```none
+set interfaces vti vti1 ip adjust-mss 1350
+```
+
+- Configure the VPN tunnel
+
+```none
+set vpn ipsec authentication psk azure id '198.51.100.3'
+set vpn ipsec authentication psk azure id '203.0.113.2'
+set vpn ipsec authentication psk azure secret 'ch00s3-4-s3cur3-psk'
+set vpn ipsec site-to-site peer azure authentication local-id '198.51.100.3'
+set vpn ipsec site-to-site peer 203.0.113.2 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer 203.0.113.2 authentication remote-id '203.0.113.2'
+set vpn ipsec site-to-site peer 203.0.113.2 connection-type 'initiate'
+set vpn ipsec site-to-site peer 203.0.113.2 description 'AZURE PRIMARY TUNNEL'
+set vpn ipsec site-to-site peer 203.0.113.2 ike-group 'AZURE'
+set vpn ipsec site-to-site peer 203.0.113.2 ikev2-reauth 'inherit'
+set vpn ipsec site-to-site peer 203.0.113.2 local-address '10.10.0.5'
+set vpn ipsec site-to-site peer azure remote-address '203.0.113.2'
+set vpn ipsec site-to-site peer 203.0.113.2 vti bind 'vti1'
+set vpn ipsec site-to-site peer 203.0.113.2 vti esp-group 'AZURE'
+```
+
+- **Important**: Add an interface route to reach Azure's BGP listener
+
+```none
+set protocols static route 10.0.0.4/32 interface vti1
+```
+
+- Configure your BGP settings
+
+```none
+set protocols bgp system-as 64499
+set protocols bgp neighbor 10.0.0.4 remote-as '65540'
+set protocols bgp neighbor 10.0.0.4 address-family ipv4-unicast soft-reconfiguration 'inbound'
+set protocols bgp neighbor 10.0.0.4 timers holdtime '30'
+set protocols bgp neighbor 10.0.0.4 timers keepalive '10'
+```
+
+- **Important**: Disable connected check
+
+```none
+set protocols bgp neighbor 10.0.0.4 disable-connected-check
+```
diff --git a/docs/configexamples/azure-vpn-dual-bgp.md b/docs/configexamples/azure-vpn-dual-bgp.md
new file mode 100644
index 00000000..967debd4
--- /dev/null
+++ b/docs/configexamples/azure-vpn-dual-bgp.md
@@ -0,0 +1,160 @@
+---
+lastproofread: '2021-06-28'
+---
+
+(examples-azure-vpn-dual-bgp)=
+
+# Route-Based Redundant Site-to-Site VPN to Azure (BGP over IKEv2/IPsec)
+
+This guide shows an example of a redundant (active-active) route-based IKEv2
+site-to-site VPN to Azure using VTI
+and BGP for dynamic routing updates.
+
+## Prerequisites
+
+- A pair of Azure VNet Gateways deployed in active-active
+ configuration with BGP enabled.
+- A local network gateway deployed in Azure representing
+ the Vyos device, matching the below Vyos settings except for
+ address space, which only requires the Vyos private IP, in
+ this example 10.10.0.5/32
+- A connection resource deployed in Azure linking the
+ Azure VNet gateway and the local network gateway representing
+ the Vyos device.
+
+## Example
+
+```{eval-rst}
++---------------------------------------+---------------------+
+| WAN Interface | eth0 |
++---------------------------------------+---------------------+
+| On-premises address space | 10.10.0.0/16 |
++---------------------------------------+---------------------+
+| Azure address space | 10.0.0.0/16 |
++---------------------------------------+---------------------+
+| Vyos public IP | 198.51.100.3 |
++---------------------------------------+---------------------+
+| Vyos private IP | 10.10.0.5 |
++---------------------------------------+---------------------+
+| Azure VNet Gateway 1 public IP | 203.0.113.2 |
++---------------------------------------+---------------------+
+| Azure VNet Gateway 2 public IP | 203.0.113.3 |
++---------------------------------------+---------------------+
+| Azure VNet Gateway BGP IP | 10.0.0.4,10.0.0.5 |
++---------------------------------------+---------------------+
+| Pre-shared key | ch00s3-4-s3cur3-psk |
++---------------------------------------+---------------------+
+| Vyos ASN | 64499 |
++---------------------------------------+---------------------+
+| Azure ASN | 65540 |
++---------------------------------------+---------------------+
+```
+
+## Vyos configuration
+
+- Configure the IKE and ESP settings to match a subset
+ of those supported by Azure:
+
+```none
+set vpn ipsec esp-group AZURE lifetime '3600'
+set vpn ipsec esp-group AZURE mode 'tunnel'
+set vpn ipsec esp-group AZURE pfs 'dh-group2'
+set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256'
+set vpn ipsec esp-group AZURE proposal 1 hash 'sha1'
+
+set vpn ipsec ike-group AZURE dead-peer-detection action 'restart'
+set vpn ipsec ike-group AZURE dead-peer-detection interval '15'
+set vpn ipsec ike-group AZURE dead-peer-detection timeout '30'
+set vpn ipsec ike-group AZURE ikev2-reauth
+set vpn ipsec ike-group AZURE key-exchange 'ikev2'
+set vpn ipsec ike-group AZURE lifetime '28800'
+set vpn ipsec ike-group AZURE proposal 1 dh-group '2'
+set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256'
+set vpn ipsec ike-group AZURE proposal 1 hash 'sha1'
+```
+
+- Enable IPsec on eth0
+
+```none
+set vpn ipsec interface 'eth0'
+```
+
+- Configure two VTIs with a dummy IP address each
+
+```none
+set interfaces vti vti1 address '10.10.1.5/32'
+set interfaces vti vti1 description 'Azure Primary Tunnel'
+
+set interfaces vti vti2 address '10.10.1.6/32'
+set interfaces vti vti2 description 'Azure Secondary Tunnel'
+```
+
+- Clamp the VTI's MSS to 1350 to avoid PMTU blackholes.
+
+```none
+set interfaces vti vti1 ip adjust-mss 1350
+set interfaces vti vti2 ip adjust-mss 1350
+```
+
+- Configure the VPN tunnels
+
+```none
+set vpn ipsec authentication psk azure id '198.51.100.3'
+set vpn ipsec authentication psk azure id '203.0.113.2'
+set vpn ipsec authentication psk azure id '203.0.113.3'
+set vpn ipsec authentication psk azure secret 'ch00s3-4-s3cur3-psk'
+
+set vpn ipsec site-to-site peer azure-primary authentication local-id '198.51.100.3'
+set vpn ipsec site-to-site peer azure-primary authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer azure-primary authentication remote-id '203.0.113.2'
+set vpn ipsec site-to-site peer azure-primary connection-type 'initiate'
+set vpn ipsec site-to-site peer azure-primary description 'AZURE PRIMARY TUNNEL'
+set vpn ipsec site-to-site peer azure-primary ike-group 'AZURE'
+set vpn ipsec site-to-site peer azure-primary ikev2-reauth 'inherit'
+set vpn ipsec site-to-site peer azure-primary local-address '10.10.0.5'
+set vpn ipsec site-to-site peer azure-primary remote-address '203.0.113.2'
+set vpn ipsec site-to-site peer azure-primary vti bind 'vti1'
+set vpn ipsec site-to-site peer azure-primary vti esp-group 'AZURE'
+
+set vpn ipsec site-to-site peer azure-secondary authentication local-id '198.51.100.3'
+set vpn ipsec site-to-site peer azure-secondary authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer azure-secondary authentication remote-id '203.0.113.3'
+set vpn ipsec site-to-site peer azure-secondary connection-type 'initiate'
+set vpn ipsec site-to-site peer azure-secondary description 'AZURE secondary TUNNEL'
+set vpn ipsec site-to-site peer azure-secondary ike-group 'AZURE'
+set vpn ipsec site-to-site peer azure-secondary ikev2-reauth 'inherit'
+set vpn ipsec site-to-site peer azure-secondary local-address '10.10.0.5'
+set vpn ipsec site-to-site peer azure-secondary remote-address '203.0.113.3'
+set vpn ipsec site-to-site peer azure-secondary vti bind 'vti2'
+set vpn ipsec site-to-site peer azure-secondary vti esp-group 'AZURE'
+```
+
+- **Important**: Add an interface route to reach both Azure's BGP listeners
+
+```none
+set protocols static route 10.0.0.4/32 interface vti1
+set protocols static route 10.0.0.5/32 interface vti2
+```
+
+- Configure your BGP settings
+
+```none
+set protocols bgp system-as 64499
+set protocols bgp neighbor 10.0.0.4 remote-as '65540'
+set protocols bgp neighbor 10.0.0.4 address-family ipv4-unicast soft-reconfiguration 'inbound'
+set protocols bgp neighbor 10.0.0.4 timers holdtime '30'
+set protocols bgp neighbor 10.0.0.4 timers keepalive '10'
+
+set protocols bgp neighbor 10.0.0.5 remote-as '65540'
+set protocols bgp neighbor 10.0.0.5 address-family ipv4-unicast soft-reconfiguration 'inbound'
+set protocols bgp neighbor 10.0.0.5 timers holdtime '30'
+set protocols bgp neighbor 10.0.0.5 timers keepalive '10'
+```
+
+- **Important**: Disable connected check, otherwise the routes learned
+ from Azure will not be imported into the routing table.
+
+```none
+set protocols bgp neighbor 10.0.0.4 disable-connected-check
+set protocols bgp neighbor 10.0.0.5 disable-connected-check
+```
diff --git a/docs/configexamples/bgp-ipv6-unnumbered.md b/docs/configexamples/bgp-ipv6-unnumbered.md
new file mode 100644
index 00000000..274551f1
--- /dev/null
+++ b/docs/configexamples/bgp-ipv6-unnumbered.md
@@ -0,0 +1,174 @@
+---
+lastproofread: '2021-06-28'
+---
+
+(examples-bgp-ipv6-unnumbered)=
+
+# BGP IPv6 unnumbered with extended nexthop
+
+General information can be found in the {ref}`routing-bgp` chapter.
+
+## Configuration
+
+- Router A:
+
+```none
+set protocols bgp system-as 64496
+set protocols bgp address-family ipv4-unicast redistribute connected
+set protocols bgp address-family ipv6-unicast redistribute connected
+set protocols bgp neighbor eth1 interface v6only
+set protocols bgp neighbor eth1 interface v6only peer-group 'fabric'
+set protocols bgp neighbor eth2 interface v6only
+set protocols bgp neighbor eth2 interface v6only peer-group 'fabric'
+set protocols bgp parameters bestpath as-path multipath-relax
+set protocols bgp parameters bestpath compare-routerid
+set protocols bgp parameters default no-ipv4-unicast
+set protocols bgp parameters router-id '192.168.0.1'
+set protocols bgp peer-group fabric address-family ipv4-unicast
+set protocols bgp peer-group fabric address-family ipv6-unicast
+set protocols bgp peer-group fabric capability extended-nexthop
+set protocols bgp peer-group fabric remote-as 'external'
+```
+
+- Router B:
+
+```none
+set protocols bgp system-as 64499
+set protocols bgp address-family ipv4-unicast redistribute connected
+set protocols bgp address-family ipv6-unicast redistribute connected
+set protocols bgp neighbor eth1 interface v6only
+set protocols bgp neighbor eth1 interface v6only peer-group 'fabric'
+set protocols bgp neighbor eth2 interface v6only
+set protocols bgp neighbor eth2 interface v6only peer-group 'fabric'
+set protocols bgp parameters bestpath as-path multipath-relax
+set protocols bgp parameters bestpath compare-routerid
+set protocols bgp parameters default no-ipv4-unicast
+set protocols bgp parameters router-id '192.168.0.2'
+set protocols bgp peer-group fabric address-family ipv4-unicast
+set protocols bgp peer-group fabric address-family ipv6-unicast
+set protocols bgp peer-group fabric capability extended-nexthop
+set protocols bgp peer-group fabric remote-as 'external'
+```
+
+
+## Results
+
+- Router A:
+
+```none
+vyos@vyos:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 198.51.100.34/24 u/u
+eth1 - u/u
+eth2 - u/u
+lo 127.0.0.1/8 u/u
+ 192.168.0.1/32
+ ::1/128
+```
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route
+
+S>* 0.0.0.0/0 [210/0] via 198.51.100.34, eth0, 03:21:53
+C>* 198.51.100.0/24 is directly connected, eth0, 03:21:53
+C>* 192.168.0.1/32 is directly connected, lo, 03:21:56
+B>* 192.168.0.2/32 [20/0] via fe80::a00:27ff:fe3b:7ed2, eth2, 00:05:07
+ * via fe80::a00:27ff:fe7b:4000, eth1, 00:05:07
+```
+
+```none
+vyos@vyos:~$ ping 192.168.0.2
+PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
+64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.575 ms
+64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.628 ms
+64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.581 ms
+64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.682 ms
+64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=0.597 ms
+
+--- 192.168.0.2 ping statistics ---
+5 packets transmitted, 5 received, 0% packet loss, time 4086ms
+rtt min/avg/max/mdev = 0.575/0.612/0.682/0.047 ms
+```
+
+```none
+vyos@vyos:~$ show ip bgp summary
+
+IPv4 Unicast Summary:
+BGP router identifier 192.168.0.1, local AS number 65020 vrf-id 0
+BGP table version 4
+RIB entries 5, using 800 bytes of memory
+Peers 2, using 41 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
+eth1 4 64499 13 13 0 0 0 00:05:33 2
+eth2 4 64499 13 14 0 0 0 00:05:29 2
+
+Total number of neighbors 2
+```
+
+- Router B:
+
+```none
+vyos@vyos:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 198.51.100.33/24 u/u
+eth1 - u/u
+eth2 - u/u
+lo 127.0.0.1/8 u/u
+ 192.168.0.2/32
+ ::1/128
+```
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route
+
+S>* 0.0.0.0/0 [210/0] via 198.51.100.33, eth0, 00:44:08
+C>* 198.51.100.0/24 is directly connected, eth0, 00:44:09
+B>* 192.168.0.1/32 [20/0] via fe80::a00:27ff:fe2d:205d, eth1, 00:06:18
+ * via fe80::a00:27ff:fe93:e142, eth2, 00:06:18
+C>* 192.168.0.2/32 is directly connected, lo, 00:44:11
+```
+
+```none
+vyos@vyos:~$ ping 192.168.0.1
+PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
+64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.427 ms
+64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=0.471 ms
+64 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=0.782 ms
+64 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=0.715 ms
+
+--- 192.168.0.1 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3051ms
+rtt min/avg/max/mdev = 0.427/0.598/0.782/0.155 ms
+```
+
+```none
+vyos@vyos:~$ show ip bgp summary
+IPv4 Unicast Summary:
+BGP router identifier 192.168.0.2, local AS number 65021 vrf-id 0
+BGP table version 4
+RIB entries 5, using 800 bytes of memory
+Peers 2, using 41 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
+eth1 4 64496 14 14 0 0 0 00:06:40 2
+eth2 4 64496 14 14 0 0 0 00:06:37 2
+
+Total number of neighbors 2
+```
diff --git a/docs/configexamples/dmvpn-dualhub-dualcloud.md b/docs/configexamples/dmvpn-dualhub-dualcloud.md
new file mode 100644
index 00000000..7bccf127
--- /dev/null
+++ b/docs/configexamples/dmvpn-dualhub-dualcloud.md
@@ -0,0 +1,552 @@
+---
+lastproofread: '2024-02-21'
+---
+
+(examples-dmvpn-dualhub-dualcloud)=
+
+# DMVPN Dual HUB Dual Cloud
+
+This document is to describe a basic setup to build DVMPN network with two Hubs and two clouds using DMVPN Phase3.
+OSPF is used as routing protocol inside DMVPN.
+
+In this example we use VyOS 1.5 as HUBs and Spokes (HUB-1, HUB-2, SPOKE-2, SPOKE-3) and Cisco IOSv 15.5(3)M (SPOKE-1)
+as a Spoke.
+
+## Network Topology
+
+```{image} /_static/images/dual-hub-DMVPN.webp
+:align: center
+:alt: DMVPN Network Topology
+:width: 80%
+```
+
+
+## Configurations
+
+### Underlay configuration
+
+Networks 192.168.X.0/24 are used as LANs for every spoke.
+
+HUB-1
+
+```none
+set interfaces ethernet eth0 address '10.0.0.2/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.0.1
+```
+
+HUB-2
+
+```none
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+```
+
+Spoke-1
+
+```none
+interface GigabitEthernet0/0
+ ip address 10.0.11.2 255.255.255.252
+ duplex auto
+ speed auto
+ media-type rj45
+!
+interface GigabitEthernet0/1
+ ip address 192.168.11.1 255.255.255.0
+ ip ospf 1 area 0
+ duplex auto
+ speed auto
+ media-type rj45
+!
+ip route 0.0.0.0 0.0.0.0 10.0.11.1
+```
+
+Spoke-2
+
+```none
+set interfaces ethernet eth0 address '10.0.12.2/30'
+set interfaces ethernet eth1 address '192.168.12.1/24'
+set protocols static route 0.0.0.0/0 next-hop 10.0.12.1
+```
+
+Spoke-3
+
+```none
+set interfaces ethernet eth0 address '10.0.13.2/30'
+set interfaces ethernet eth1 address '192.168.13.1/24'
+set protocols static route 0.0.0.0/0 next-hop 10.0.13.1
+```
+
+
+### NHRP configuration
+
+The next step is to configure the NHRP protocol. In a Dual cloud network, every HUB has to be configured with one GRE
+multipoint tunnel interface and every spoke has to be configured with two tunnel interfaces, one tunnel to each hub.
+In this example tunnel networks are 10.100.100.0/24 for the first cloud and 10.100.101.0/24 for the second cloud.
+But VyOS uses FRR for NHRP, that is why the tunnel address mask must be /32.
+
+HUB-1
+
+```none
+set interfaces tunnel tun100 address '10.100.100.1/32'
+set interfaces tunnel tun100 enable-multicast
+set interfaces tunnel tun100 encapsulation 'gre'
+set interfaces tunnel tun100 ip adjust-mss '1360'
+set interfaces tunnel tun100 mtu '1436'
+set interfaces tunnel tun100 parameters ip key '42'
+set interfaces tunnel tun100 source-interface 'eth0'
+set protocols nhrp tunnel tun100 authentication 'vyos'
+set protocols nhrp tunnel tun100 holdtime '300'
+set protocols nhrp tunnel tun100 multicast 'dynamic'
+set protocols nhrp tunnel tun100 network-id '1'
+set protocols nhrp tunnel tun100 redirect
+set protocols nhrp tunnel tun100 registration-no-unique
+```
+
+HUB-2
+
+```none
+set interfaces tunnel tun101 address '10.100.101.1/32'
+set interfaces tunnel tun101 enable-multicast
+set interfaces tunnel tun101 encapsulation 'gre'
+set interfaces tunnel tun101 ip adjust-mss '1360'
+set interfaces tunnel tun101 mtu '1436'
+set interfaces tunnel tun101 parameters ip key '43'
+set interfaces tunnel tun101 source-interface 'eth0'
+set protocols nhrp tunnel tun101 authentication 'vyos'
+set protocols nhrp tunnel tun101 holdtime '300'
+set protocols nhrp tunnel tun101 multicast 'dynamic'
+set protocols nhrp tunnel tun101 network-id '2'
+set protocols nhrp tunnel tun101 redirect
+set protocols nhrp tunnel tun101 registration-no-unique
+```
+
+Spoke-1
+
+```none
+interface Tunnel100
+ ip address 10.100.100.11 255.255.255.0
+ no ip redirects
+ ip mtu 1436
+ ip nhrp authentication vyos
+ ip nhrp map multicast 10.0.0.2
+ ip nhrp network-id 1
+ ip nhrp holdtime 300
+ ip nhrp nhs 10.100.100.1 nbma 10.0.0.2
+ ip nhrp shortcut
+ ip tcp adjust-mss 1360
+ tunnel source GigabitEthernet0/0
+ tunnel mode gre multipoint
+ tunnel key 42
+!
+interface Tunnel101
+ ip address 10.100.101.11 255.255.255.0
+ no ip redirects
+ ip mtu 1436
+ ip nhrp authentication vyos
+ ip nhrp map multicast 10.0.1.2
+ ip nhrp network-id 2
+ ip nhrp holdtime 300
+ ip nhrp nhs 10.100.101.1 nbma 10.0.1.2
+ ip nhrp shortcut
+ ip tcp adjust-mss 1360
+ tunnel source GigabitEthernet0/0
+ tunnel mode gre multipoint
+ tunnel key 43
+```
+
+Spoke-2
+
+```none
+set interfaces tunnel tun100 address '10.100.100.12/32'
+set interfaces tunnel tun100 enable-multicast
+set interfaces tunnel tun100 encapsulation 'gre'
+set interfaces tunnel tun100 ip adjust-mss '1360'
+set interfaces tunnel tun100 mtu '1436'
+set interfaces tunnel tun100 parameters ip key '42'
+set interfaces tunnel tun100 source-interface 'eth0'
+set interfaces tunnel tun101 address '10.100.101.12/32'
+set interfaces tunnel tun101 enable-multicast
+set interfaces tunnel tun101 encapsulation 'gre'
+set interfaces tunnel tun101 ip adjust-mss '1360'
+set interfaces tunnel tun101 mtu '1436'
+set interfaces tunnel tun101 parameters ip key '43'
+set interfaces tunnel tun101 source-interface 'eth0'
+set protocols nhrp tunnel tun100 authentication 'vyos'
+set protocols nhrp tunnel tun100 holdtime '300'
+set protocols nhrp tunnel tun100 multicast '10.0.0.2'
+set protocols nhrp tunnel tun100 network-id '1'
+set protocols nhrp tunnel tun100 nhs tunnel-ip dynamic nbma '10.0.0.2'
+set protocols nhrp tunnel tun100 registration-no-unique
+set protocols nhrp tunnel tun100 shortcut
+set protocols nhrp tunnel tun101 authentication 'vyos'
+set protocols nhrp tunnel tun101 holdtime '300'
+set protocols nhrp tunnel tun101 multicast '10.0.1.2'
+set protocols nhrp tunnel tun101 network-id '2'
+set protocols nhrp tunnel tun101 nhs tunnel-ip dynamic nbma '10.0.1.2'
+set protocols nhrp tunnel tun101 registration-no-unique
+set protocols nhrp tunnel tun101 shortcut
+```
+
+Spoke-3
+
+```none
+set protocols nhrp tunnel tun100 authentication 'vyos'
+set protocols nhrp tunnel tun100 holdtime '300'
+set protocols nhrp tunnel tun100 multicast '10.0.0.2'
+set protocols nhrp tunnel tun100 network-id '1'
+set protocols nhrp tunnel tun100 nhs tunnel-ip dynamic nbma '10.0.0.2'
+set protocols nhrp tunnel tun100 registration-no-unique
+set protocols nhrp tunnel tun100 shortcut
+set protocols nhrp tunnel tun101 authentication 'vyos'
+set protocols nhrp tunnel tun101 holdtime '300'
+set protocols nhrp tunnel tun101 multicast '10.0.1.2'
+set protocols nhrp tunnel tun101 network-id '2'
+set protocols nhrp tunnel tun101 nhs tunnel-ip dynamic nbma '10.0.1.2'
+set protocols nhrp tunnel tun101 registration-no-unique
+set protocols nhrp tunnel tun101 shortcut
+```
+
+
+### Overlay configuration
+
+The last step is to configure the routing protocol. In this scenario, OSPF was chosen as the dynamic routing protocol.
+But you can use iBGP or eBGP. To form fast convergence it is possible to use BFD protocol.
+
+HUB-1
+
+```none
+set protocols ospf interface tun100 area '0'
+set protocols ospf interface tun100 network 'point-to-multipoint'
+set protocols ospf interface tun100 passive disable
+set protocols ospf passive-interface 'default'
+```
+
+HUB-2
+
+```none
+set protocols ospf interface tun101 area '0'
+set protocols ospf interface tun101 network 'point-to-multipoint'
+set protocols ospf interface tun101 passive disable
+set protocols ospf passive-interface 'default'
+```
+
+Spoke-1
+
+```none
+interface Tunnel100
+ ip ospf network point-to-multipoint
+ ip ospf dead-interval 40
+ ip ospf hello-interval 10
+ ip ospf 1 area 0
+!
+interface Tunnel101
+ ip ospf network point-to-multipoint
+ ip ospf dead-interval 40
+ ip ospf hello-interval 10
+ ip ospf 1 area 0
+!
+router ospf 1
+ passive-interface default
+ no passive-interface Tunnel100
+ no passive-interface Tunnel101
+```
+
+Spoke-2
+
+```none
+set protocols ospf interface eth1 area '0'
+set protocols ospf interface tun100 area '0'
+set protocols ospf interface tun100 network 'point-to-multipoint'
+set protocols ospf interface tun100 passive disable
+set protocols ospf interface tun101 area '0'
+set protocols ospf interface tun101 network 'point-to-multipoint'
+set protocols ospf interface tun101 passive disable
+set protocols ospf passive-interface 'default'
+```
+
+Spoke-3
+
+```none
+set protocols ospf interface eth1 area '0'
+set protocols ospf interface tun100 area '0'
+set protocols ospf interface tun100 network 'point-to-multipoint'
+set protocols ospf interface tun100 passive disable
+set protocols ospf interface tun101 area '0'
+set protocols ospf interface tun101 network 'point-to-multipoint'
+set protocols ospf interface tun101 passive disable
+set protocols ospf passive-interface 'default'
+```
+
+
+### Security configuration
+
+Tunnels can be encrypted by IPSEC for security.
+
+HUB-1
+
+```{eval-rst}
+ .. code-block:: none
+
+ set vpn ipsec esp-group ESP-HUB lifetime '1800'
+ set vpn ipsec esp-group ESP-HUB mode 'transport'
+ set vpn ipsec esp-group ESP-HUB pfs 'disable'
+ set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
+ set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
+ set vpn ipsec ike-group IKE-HUB lifetime '3600'
+ set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
+ set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
+ set vpn ipsec interface 'eth0'
+ set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
+ set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
+ set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
+ set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
+ set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
+```
+
+HUB-2
+
+```{eval-rst}
+ .. code-block:: none
+
+ set vpn ipsec esp-group ESP-HUB lifetime '1800'
+ set vpn ipsec esp-group ESP-HUB mode 'transport'
+ set vpn ipsec esp-group ESP-HUB pfs 'disable'
+ set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
+ set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
+ set vpn ipsec ike-group IKE-HUB lifetime '3600'
+ set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
+ set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
+ set vpn ipsec interface 'eth0'
+ set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
+ set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
+ set vpn ipsec profile NHRPVPN bind tunnel 'tun101'
+ set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
+ set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
+```
+
+VyOS Spokes have the same configuration
+
+```{eval-rst}
+ .. code-block:: none
+
+ set vpn ipsec esp-group ESP-HUB lifetime '1800'
+ set vpn ipsec esp-group ESP-HUB mode 'transport'
+ set vpn ipsec esp-group ESP-HUB pfs 'disable'
+ set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
+ set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
+ set vpn ipsec ike-group IKE-HUB lifetime '3600'
+ set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
+ set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
+ set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
+ set vpn ipsec interface 'eth0'
+ set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
+ set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
+ set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
+ set vpn ipsec profile NHRPVPN bind tunnel 'tun101'
+ set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
+ set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
+```
+
+SPOKE-1
+
+```{eval-rst}
+ .. code-block:: none
+
+ crypto isakmp policy 1
+ encr aes 256
+ authentication pre-share
+ group 2
+ lifetime 3600
+ crypto isakmp key secret address 0.0.0.0
+ !
+ !
+ crypto ipsec transform-set ESP_TRANSFORMSET esp-aes 256 esp-sha-hmac
+ mode transport
+ !
+ !
+ crypto ipsec profile gre_protection
+ set security-association lifetime seconds 1800
+ set transform-set ESP_TRANSFORMSET
+ !
+ interface Tunnel100
+ tunnel protection ipsec profile gre_protection shared
+ !
+ interface Tunnel101
+ tunnel protection ipsec profile gre_protection shared
+```
+
+
+## Monitoring
+
+All spokes created IPSec tunnels to Hubs, are registered on Hubs using NHRP protocol and formed adjacency in OSPF.
+
+```none
+vyos@HUB-1:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------------------- ------- -------- -------------- ---------------- ---------------- ----------- ------------------------
+dmvpn-NHRPVPN-tun100-child up 6m1s 4K/5K 51/56 10.0.13.2 10.0.13.2 AES_CBC_256/HMAC_SHA1_96
+dmvpn-NHRPVPN-tun100-child up 6m36s 4K/6K 56/65 10.0.12.2 10.0.12.2 AES_CBC_256/HMAC_SHA1_96
+dmvpn-NHRPVPN-tun100-child up 8m49s 6K/6K 73/77 10.0.11.2 10.0.11.2 AES_CBC_256/HMAC_SHA1_96
+
+vyos@HUB-1:~$ show ip nhrp cache
+Iface Type Protocol NBMA Claimed NBMA Flags Identity
+tun100 dynamic 10.100.100.12 10.0.12.2 10.0.12.2 T 10.0.12.2
+tun100 dynamic 10.100.100.13 10.0.13.2 10.0.13.2 T 10.0.13.2
+tun100 dynamic 10.100.100.11 10.0.11.2 10.0.11.2 T 10.0.11.2
+tun100 local 10.100.100.1 10.0.0.2 10.0.0.2 -
+
+vyos@HUB-1:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
+192.168.11.1 1 Full/DROther 17m01s 36.201s 10.100.100.11 tun100:10.100.100.1 0 0 0
+192.168.12.1 1 Full/DROther 9m42s 37.443s 10.100.100.12 tun100:10.100.100.1 0 0 0
+192.168.13.1 1 Full/DROther 9m15s 35.053s 10.100.100.13 tun100:10.100.100.1 0 0 0
+```
+
+First, we see that LANs are accessible through hubs using OSPF routes.
+
+```none
+SPOKE-1#show ip route
+Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
+ D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
+ N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
+ E1 - OSPF external type 1, E2 - OSPF external type 2
+ i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
+ ia - IS-IS inter area, * - candidate default, U - per-user static route
+ o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
+ a - application route
+ + - replicated route, % - next hop override, p - overrides from PfR
+
+Gateway of last resort is 10.0.11.1 to network 0.0.0.0
+.....
+ 192.168.11.0/24 is variably subnetted, 2 subnets, 2 masks
+C 192.168.11.0/24 is directly connected, GigabitEthernet0/1
+L 192.168.11.1/32 is directly connected, GigabitEthernet0/1
+O 192.168.12.0/24 [110/1002] via 10.100.101.1, 00:14:36, Tunnel101
+ [110/1002] via 10.100.100.1, 00:16:13, Tunnel100
+O 192.168.13.0/24 [110/1002] via 10.100.101.1, 00:14:36, Tunnel101
+ [110/1002] via 10.100.100.1, 00:15:45, Tunnel100
+
+
+vyos@SPOKE-2:~$ show ip route
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+......
+O>* 192.168.11.0/24 [110/3] via 10.100.100.1, tun100 onlink, weight 1, 00:12:36
+ * via 10.100.101.1, tun101 onlink, weight 1, 00:12:36
+O 192.168.12.0/24 [110/1] is directly connected, eth1, weight 1, 01:24:40
+C>* 192.168.12.0/24 is directly connected, eth1, weight 1, 01:24:43
+L>* 192.168.12.1/32 is directly connected, eth1, weight 1, 01:24:43
+O>* 192.168.13.0/24 [110/3] via 10.100.100.1, tun100 onlink, weight 1, 00:12:36
+ * via 10.100.101.1, tun101 onlink, weight 1, 00:12:36
+```
+
+After initiating traffic between SPOKES sites, Phase 3 of DMVPN will work.
+For instance, traceroute was generated from PC-SPOKE-2 to PC-SPOKE-1
+
+```none
+PC-SPOKE-2 : 192.168.12.2 255.255.255.0 gateway 192.168.12.1
+
+PC-SPOKE-2> trace 192.168.11.2
+trace to 192.168.11.2, 8 hops max, press Ctrl+C to stop
+ 1 192.168.12.1 0.558 ms 0.378 ms 0.561 ms
+ 2 10.100.101.1 1.768 ms 1.158 ms 1.744 ms
+ 3 10.100.101.11 7.196 ms 4.971 ms 4.793 ms
+ 4 *192.168.11.2 7.747 ms (ICMP type:3, code:3, Destination port unreachable)
+
+PC-SPOKE-2> trace 192.168.11.2
+trace to 192.168.11.2, 8 hops max, press Ctrl+C to stop
+ 1 192.168.12.1 0.562 ms 0.396 ms 0.364 ms
+ 2 10.100.100.11 4.401 ms 4.399 ms 4.174 ms
+ 3 *192.168.11.2 3.241 ms (ICMP type:3, code:3, Destination port unreachable)
+```
+
+First trace goes via HUB but the second goes directly from SPOKE-1 to SPOKE-2.
+Now routing tables are changed. LAN networks 192.168.12.0/24 and 192.168.11.0/24 available directly via SPOKES.
+
+```none
+vyos@SPOKE-2:~$ show ip route
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+N>* 192.168.11.0/24 [10/0] via 10.100.100.11, tun100 onlink, weight 1, 00:00:14
+O 192.168.11.0/24 [110/3] via 10.100.100.1, tun100 onlink, weight 1, 00:00:54
+ via 10.100.101.1, tun101 onlink, weight 1, 00:00:54
+
+
+SPOKE-1# show ip route next-hop-override
+Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
+ D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
+ N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
+ E1 - OSPF external type 1, E2 - OSPF external type 2
+ i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
+ ia - IS-IS inter area, * - candidate default, U - per-user static route
+ o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
+ a - application route
+ + - replicated route, % - next hop override, p - overrides from PfR
+
+Gateway of last resort is 10.0.11.1 to network 0.0.0.0
+
+O % 192.168.12.0/24 [110/1002] via 10.100.101.1, 00:24:09, Tunnel101
+ [110/1002] via 10.100.100.1, 00:25:46, Tunnel100
+ [NHO][110/1] via 10.100.100.12, 00:00:03, Tunnel100
+```
+
+NHRP shows shortcuts on Spokes
+
+```none
+vyos@SPOKE-2:~$ show ip nhrp shortcut
+Type Prefix Via Identity
+dynamic 192.168.11.0/24 10.100.100.11 10.0.11.2
+
+SPOKE-1# show ip nhrp shortcut
+10.100.100.12/32 via 10.100.100.12
+ Tunnel100 created 00:09:59, expire 00:02:21
+ Type: dynamic, Flags: router nhop rib nho
+ NBMA address: 10.0.12.2
+192.168.12.0/24 via 10.100.100.12
+ Tunnel100 created 00:02:38, expire 00:02:21
+ Type: dynamic, Flags: router rib nho
+ NBMA address: 10.0.12.2
+```
+
+A new Spoke to Spoke IPSec tunnel is created
+
+```none
+SPOKE-1#show crypto isakmp sa
+IPv4 Crypto ISAKMP SA
+dst src state conn-id status
+10.0.0.2 10.0.11.2 QM_IDLE 1002 ACTIVE
+10.0.12.2 10.0.11.2 QM_IDLE 1004 ACTIVE
+10.0.1.2 10.0.11.2 QM_IDLE 1003 ACTIVE
+
+vyos@SPOKE-2:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------------------- ------- -------- -------------- ---------------- ---------------- ----------- ------------------------
+dmvpn-NHRPVPN-tun100-child up 7m26s 4K/4K 57/53 10.0.0.2 10.0.0.2 AES_CBC_256/HMAC_SHA1_96
+dmvpn-NHRPVPN-tun100-child up 11m48s 316B/1K 3/15 10.0.11.2 10.0.11.2 AES_CBC_256/HMAC_SHA1_96
+dmvpn-NHRPVPN-tun101-child up 5m58s 5K/4K 62/51 10.0.1.2 10.0.1.2 AES_CBC_256/HMAC_SHA1_96
+```
+
+
+## Summary
+
+If one of the Hubs loses connectivity to the Internet, the other Hub will be available and take the main role.
+This is a simple example where only one internet connection is used. But in the real world, there can be two
+connections to the Internet. In this case, there is a recommendation to build each tunnel via each Internet connection,
+choose the main cloud, and manipulate traffic via a routing protocol. It allows the creation failover on link-level
+connections too.
diff --git a/docs/configexamples/firewall.md b/docs/configexamples/firewall.md
new file mode 100644
index 00000000..5d170511
--- /dev/null
+++ b/docs/configexamples/firewall.md
@@ -0,0 +1,16 @@
+---
+lastproofread: '2024-09-11'
+---
+
+# Firewall Examples
+
+This section contains examples of firewall configurations for various
+deployments.
+
+```{toctree}
+:maxdepth: 2
+
+fwall-and-vrf
+fwall-and-bridge
+zone-policy
+```
diff --git a/docs/configexamples/fwall-and-bridge.md b/docs/configexamples/fwall-and-bridge.md
new file mode 100644
index 00000000..f8b1ca42
--- /dev/null
+++ b/docs/configexamples/fwall-and-bridge.md
@@ -0,0 +1,490 @@
+---
+lastproofread: '2024-09-11'
+---
+
+# Bridge and firewall example
+
+## Scenario and requirements
+
+This example shows how to configure a VyOS router with bridge interfaces and
+firewall rules.
+
+Three non VLAN-aware bridges are going to be configured, and each one has its
+own requirements.
+
+- Bridge br0:
+ : - Isolated layer 2 bridge.
+ - Accept only IPv6 communication whithin the bridge.
+- Bridge br1:
+ : - Drop all DHCP discover packets.
+ - Accept all ARP packets.
+ - Within the bridge, accept only new IPv4 connections from host 10.1.1.102
+ - Drop all other IPv4 connections.
+ - Drop all IPv6 connections.
+ - Accept access to router itself.
+ - Allow connections to internet
+ - Drop connections to other LANs.
+- Bridge br2:
+ : - Accept all DHCP discover packets.
+ - Accept only DHCP offers from valid server and|or trusted bridge port.
+ - Accept all ARP packets.
+ - Accept all IPv4 connections.
+ - Drop all IPv6 connections.
+ - Deny access to the router.
+ - Allow connections to internet.
+ - Allow connections to bridge br1.
+
+## Configuration
+
+### Bridges and interfaces configuration
+
+First, we need to configure the interfaces and bridges:
+
+```none
+# Brige br0
+set interfaces bridge br0 description 'Isolated L2 bridge'
+set interfaces bridge br0 member interface eth1
+set interfaces bridge br0 member interface eth2
+set interfaces ethernet eth1 description 'br0'
+set interfaces ethernet eth2 description 'br0'
+
+# Bridge br1:
+set interfaces bridge br1 address '10.1.1.1/24'
+set interfaces bridge br1 description 'L3 bridge br1'
+set interfaces bridge br1 member interface eth3
+set interfaces bridge br1 member interface eth4
+set interfaces ethernet eth3 description 'br1'
+set interfaces ethernet eth4 description 'br1'
+
+# Bridge br2:
+set interfaces bridge br2 address '10.2.2.1/24'
+set interfaces bridge br2 description 'L3 bridge br2'
+set interfaces bridge br2 member interface eth5
+set interfaces bridge br2 member interface eth6
+set interfaces bridge br2 member interface eth7
+set interfaces ethernet eth5 description 'br2 - Host'
+set interfaces ethernet eth6 description 'br2 - Trusted DHCP Server'
+set interfaces ethernet eth7 description 'br2'
+```
+
+
+### Bridge firewall configuration
+
+In this section, we are going to configure the firewall rules that will be used
+in bridge firewall, and will control the traffic within each bridge.
+
+We are going to use custom firewall rulesets, one for each bridge that will
+be used in `prerouting`, and one for each bridge that will be used in the
+`forward` chain.
+
+Also, we are going to use firewall interface groups in order to simplify the
+firewall configuration.
+
+So first, let's create the required firewall interface groups:
+
+```none
+# Bridge br0 interface-group:
+set firewall group interface-group br0-ifaces interface 'br0'
+set firewall group interface-group br0-ifaces interface 'eth1'
+set firewall group interface-group br0-ifaces interface 'eth2'
+
+# Bridge br1 interface-group:
+set firewall group interface-group br1-ifaces interface 'br1'
+set firewall group interface-group br1-ifaces interface 'eth3'
+set firewall group interface-group br1-ifaces interface 'eth4'
+
+# Bridge br2 interface-group:
+set firewall group interface-group br2-ifaces interface 'br2'
+set firewall group interface-group br2-ifaces interface 'eth5'
+set firewall group interface-group br2-ifaces interface 'eth6'
+set firewall group interface-group br2-ifaces interface 'eth7'
+```
+
+As said before, we are going to create custom firewall rulesets for each
+bridge, that will be used in the `prerouting` chain, in order to drop as much
+unwanted traffic as early as possible. So, custom rulesets used in
+`prerouting` chain are going to be `br0-pre`, `br1-pre`, and `br2-pre`:
+
+```none
+# Prerouting - Catch all traffic for br0
+set firewall bridge prerouting filter rule 10 action 'jump'
+set firewall bridge prerouting filter rule 10 description 'br0 traffic'
+set firewall bridge prerouting filter rule 10 inbound-interface group 'br0-ifaces'
+set firewall bridge prerouting filter rule 10 jump-target 'br0-pre'
+
+# Prerouting - Catch all traffic for br1
+set firewall bridge prerouting filter rule 20 action 'jump'
+set firewall bridge prerouting filter rule 20 description 'br1 traffic'
+set firewall bridge prerouting filter rule 20 inbound-interface group 'br1-ifaces'
+set firewall bridge prerouting filter rule 20 jump-target 'br1-pre'
+
+# Prerouting - Catch all traffic for br2
+set firewall bridge prerouting filter rule 30 action 'jump'
+set firewall bridge prerouting filter rule 30 description 'br2 traffic'
+set firewall bridge prerouting filter rule 30 inbound-interface group 'br2-ifaces'
+set firewall bridge prerouting filter rule 30 jump-target 'br2-pre'
+```
+
+And then create the custom rulesets:
+
+```none
+### br0 - br0-pre
+ # Requirements: accept only IPv6 communication within the bridge
+set firewall bridge name br0-pre rule 10 description 'Accept IPv6 traffic'
+set firewall bridge name br0-pre rule 10 action 'accept'
+set firewall bridge name br0-pre rule 10 ethernet-type 'ipv6'
+ # And drop everything else
+set firewall bridge name br0-pre default-action 'drop'
+
+### br1 - br1-pre
+ # Requirements: drop all DHCP discover packets
+set firewall bridge name br1-pre rule 10 description 'Drop DHCP discover'
+set firewall bridge name br1-pre rule 10 action 'drop'
+set firewall bridge name br1-pre rule 10 protocol 'udp'
+set firewall bridge name br1-pre rule 10 source port '68'
+set firewall bridge name br1-pre rule 10 destination port '67'
+set firewall bridge name br1-pre rule 10 destination mac-address 'ff:ff:ff:ff:ff:ff'
+set firewall bridge name br1-pre rule 10 log
+ # Requirement: drop all IPv6 connections
+set firewall bridge name br1-pre rule 20 description 'Drop IPv6 traffic'
+set firewall bridge name br1-pre rule 20 action 'drop'
+set firewall bridge name br1-pre rule 20 ethernet-type 'ipv6'
+ # Accept everything else so it can be parsed later
+set firewall bridge name br1-pre default-action 'accept'
+
+### br2 - br2-pre
+ # Requirements: drop all IPv6 connections
+set firewall bridge name br2-pre rule 10 description 'Drop IPv6 traffic'
+set firewall bridge name br2-pre rule 10 action 'drop'
+set firewall bridge name br2-pre rule 10 ethernet-type 'ipv6'
+ # Accept everything else so it can be parsed later
+set firewall bridge name br2-pre default-action 'accept'
+```
+
+Now, in the `forward` chain, we are going to define state policies, and
+custom rulesets for each bridge that would be used in the `forward` chain.
+These rulesets are `br0-fwd`, `br1-fwd`, and `br2-fwd`:
+
+```none
+# Forward - State policies if not defined globally
+set firewall bridge forward filter rule 5 action 'accept'
+set firewall bridge forward filter rule 5 state 'established'
+set firewall bridge forward filter rule 5 state 'related'
+set firewall bridge forward filter rule 10 action 'drop'
+set firewall bridge forward filter rule 10 state 'invalid'
+
+# Forward - Catch all traffic for br0
+set firewall bridge forward filter rule 110 description 'br0 traffic'
+set firewall bridge forward filter rule 110 action 'jump'
+set firewall bridge forward filter rule 110 inbound-interface group 'br0-ifaces'
+set firewall bridge forward filter rule 110 jump-target 'br0-fwd'
+
+# Forward - Catch all traffic for br1
+set firewall bridge forward filter rule 120 description 'br1 traffic'
+set firewall bridge forward filter rule 120 action 'jump'
+set firewall bridge forward filter rule 120 inbound-interface group 'br1-ifaces'
+set firewall bridge forward filter rule 120 jump-target 'br1-fwd'
+
+# Forward - Catch all traffic for br2
+set firewall bridge forward filter rule 130 description 'br2 traffic'
+set firewall bridge forward filter rule 130 action 'jump'
+set firewall bridge forward filter rule 130 inbound-interface group 'br2-ifaces'
+set firewall bridge forward filter rule 130 jump-target 'br2-fwd'
+
+# Forward - Default action drop:
+set firewall bridge forward filter default-action 'drop'
+```
+
+And the content of the custom rulesets:
+
+```none
+### br0 - br0-fwd
+ # Accept everything that wasn't dropped in prerouting
+set firewall bridge name br0-fwd default-action 'accept'
+
+### br1 - br1-fwd
+ # Requirement: Accept all ARP packets
+set firewall bridge name br1-fwd rule 10 description 'Accept ARP'
+set firewall bridge name br1-fwd rule 10 action 'accept'
+set firewall bridge name br1-fwd rule 10 ethernet-type 'arp'
+ # Requirement: Accept only new IPv4 connections from host 10.1.1.102
+set firewall bridge name br1-fwd rule 20 description 'Accept ipv4 from host'
+set firewall bridge name br1-fwd rule 20 action 'accept'
+set firewall bridge name br1-fwd rule 20 source address '10.1.1.102'
+set firewall bridge name br1-fwd rule 20 state 'new'
+ # Drop everythin else within the bridge:
+set firewall bridge name br1-fwd default-action 'drop'
+
+### br2 - br2-fwd
+ # Requirement: Accept all DHCP discover packets
+set firewall bridge name br2-fwd rule 10 description 'Accept DHCP discover'
+set firewall bridge name br2-fwd rule 10 action 'accept'
+set firewall bridge name br2-fwd rule 10 protocol 'udp'
+set firewall bridge name br2-fwd rule 10 source port '68'
+set firewall bridge name br2-fwd rule 10 destination port '67'
+set firewall bridge name br2-fwd rule 10 destination mac-address 'ff:ff:ff:ff:ff:ff'
+ # Requirement: Accept only DHCP offers from valid server on port eth6
+set firewall bridge name br2-fwd rule 20 description 'Accept DHCP offers from trusted interface'
+set firewall bridge name br2-fwd rule 20 action 'accept'
+set firewall bridge name br2-fwd rule 20 protocol 'udp'
+set firewall bridge name br2-fwd rule 20 source port '67'
+set firewall bridge name br2-fwd rule 20 destination port '68'
+set firewall bridge name br2-fwd rule 20 inbound-interface name 'eth6'
+set firewall bridge name br2-fwd rule 22 description 'Drop all other DHCP offers'
+set firewall bridge name br2-fwd rule 22 action 'drop'
+set firewall bridge name br2-fwd rule 22 protocol 'udp'
+set firewall bridge name br2-fwd rule 22 source port '67'
+set firewall bridge name br2-fwd rule 22 destination port '68'
+set firewall bridge name br2-fwd rule 22 log
+
+ # Accept all ARP packets
+set firewall bridge name br2-fwd rule 30 description 'Accept ARP'
+set firewall bridge name br2-fwd rule 30 action 'accept'
+set firewall bridge name br2-fwd rule 30 ethernet-type 'arp'
+ # Accept all IPv4 connections
+set firewall bridge name br2-fwd rule 40 description 'Accept ipv4'
+set firewall bridge name br2-fwd rule 40 action 'accept'
+set firewall bridge name br2-fwd rule 40 ethernet-type 'ipv4'
+ # Drop everything else
+set firewall bridge name br2-fwd default-action 'drop'
+```
+
+
+### IP firewall configuration
+
+Since some of the requirements listed above exceed the capabilities of the
+bridge firewall, we need to use the IP firewall to implement them.
+For bridge br1 and br2, we need to control the traffic that is going to the
+router itself, to other local networks, and to the Internet.
+
+As a reminder, here's a link to the {doc}`firewall documentation
+</configuration/firewall/index>`, where you can find more information about
+the packet flow for traffic that comes from bridge layer and should be analized
+by the IP firewall.
+
+Access to the router itself is controlled by the base chain `input`, and
+rules to accomplish all the requirements are:
+
+```none
+# First of all, if not using global state policies, we need to define them:
+set firewall ipv4 input filter rule 10 state 'established'
+set firewall ipv4 input filter rule 10 state 'related'
+set firewall ipv4 input filter rule 10 action 'accept'
+set firewall ipv4 input filter rule 20 state 'invalid'
+set firewall ipv4 input filter rule 20 action 'drop'
+
+# Input - br1 - Accept access to router itself
+set firewall ipv4 input filter rule 110 description "Accept access from br1"
+set firewall ipv4 input filter rule 110 action 'accept'
+set firewall ipv4 input filter rule 110 inbound-interface group 'br1-ifaces'
+
+# Input - br2 - Deny access to the router
+set firewall ipv4 input filter rule 120 description "Deny access from br2"
+set firewall ipv4 input filter rule 120 action 'drop'
+set firewall ipv4 input filter rule 120 inbound-interface group 'br2-ifaces'
+```
+
+And for traffic that is going to other local networks, and to he Internet, we
+need to use the base chain `forward`. As in the bridge firewall, we are
+going to use custom rulesets for each bridge, that would be used in the
+`forward` chain. Those rulesets are `ip-br1-fwd` and `ip-br2-fwd`:
+
+```none
+# First of all, if not using global state policies, we need to define them:
+set firewall ipv4 forward filter rule 5 action 'accept'
+set firewall ipv4 forward filter rule 5 state 'established'
+set firewall ipv4 forward filter rule 5 state 'related'
+set firewall ipv4 forward filter rule 10 action 'drop'
+set firewall ipv4 forward filter rule 10 state 'invalid'
+
+# Forward - Catch all traffic for br1
+set firewall ipv4 forward filter rule 110 description 'br1 traffic'
+set firewall ipv4 forward filter rule 110 action 'jump'
+set firewall ipv4 forward filter rule 110 inbound-interface group 'br1-ifaces'
+set firewall ipv4 forward filter rule 110 jump-target 'ip-br1-fwd'
+
+# Forward - Catch all traffic for br2
+set firewall ipv4 forward filter rule 120 description 'br2 traffic'
+set firewall ipv4 forward filter rule 120 action 'jump'
+set firewall ipv4 forward filter rule 120 inbound-interface group 'br2-ifaces'
+set firewall ipv4 forward filter rule 120 jump-target 'ip-br2-fwd'
+
+# Forward - Default action drop:
+set firewall ipv4 forward filter default-action 'drop'
+```
+
+And the content of the custom rulesets:
+
+```none
+### br1 - ip-br1-fwd
+ # Requirement: Allow connections to internet
+set firewall ipv4 name ip-br1-fwd rule 10 description 'br1 - allow internet access'
+set firewall ipv4 name ip-br1-fwd rule 10 action 'accept'
+set firewall ipv4 name ip-br1-fwd rule 10 outbound-interface name 'eth0'
+ # Requirement: Drop all other connections
+set firewall ipv4 name ip-br1-fwd default-action 'drop'
+
+### br2 - ip-br2-fwd
+ # Requirement: Allow connections to internet
+set firewall ipv4 name ip-br2-fwd rule 10 description 'br2 - allow internet access'
+set firewall ipv4 name ip-br2-fwd rule 10 action 'accept'
+set firewall ipv4 name ip-br2-fwd rule 10 outbound-interface name 'eth0'
+ # Requirement: Allow connections to br1
+set firewall ipv4 name ip-br2-fwd rule 20 description 'br2 - allow access to br1'
+set firewall ipv4 name ip-br2-fwd rule 20 action 'accept'
+set firewall ipv4 name ip-br2-fwd rule 20 outbound-interface group 'br1-ifaces'
+ # Requirement: Drop all other connections
+set firewall ipv4 name ip-br2-fwd default-action 'drop'
+```
+
+
+## Validation
+
+While testing the configuration, we can check logs in order to ensure that
+we are accepting and/or blocking the correct traffic.
+
+For example, while a host tries to get an IP address from a DHCP server in
+br1 all DHCP discover are dropped, and in br2, we can see that DHCP offers from
+untrusted servers are dropped:
+
+```none
+vyos@bridge:~$ show log firewall bridge
+Sep 17 14:22:35 kernel: [bri-NAM-br2-fwd-22-D]IN=eth7 OUT=eth5 MAC=50:00:00:09:00:00:50:00:00:04:00:00:08:00 SRC=10.2.2.199 DST=10.2.2.92 LEN=322 TOS=0x10 PREC=0x00 TTL=128 ID=0 DF PROTO=UDP SPT=67 DPT=68 LEN=302
+Sep 17 14:28:18 kernel: [bri-NAM-br1-pre-10-D]IN=eth3 OUT= MAC=ff:ff:ff:ff:ff:ff:00:50:79:66:68:0c:08:00 SRC=0.0.0.0 DST=255.255.255.255 LEN=392 TOS=0x10 PREC=0x00 TTL=16 ID=0 PROTO=UDP SPT=68 DPT=67 LEN=372
+Sep 17 14:28:19 kernel: [bri-NAM-br1-pre-10-D]IN=eth3 OUT= MAC=ff:ff:ff:ff:ff:ff:00:50:79:66:68:0c:08:00 SRC=0.0.0.0 DST=255.255.255.255 LEN=392 TOS=0x10 PREC=0x00 TTL=16 ID=0 PROTO=UDP SPT=68 DPT=67 LEN=372
+```
+
+And with operational mode commands, we can check rules matchers, actions, and
+counters.
+
+Bridge firewall rulset:
+
+```none
+vyos@bri:~$ show firewall bridge
+Rulesets bridge Information
+
+---------------------------------
+bridge Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------------------
+5 accept all 19 1916 ct state { established, related } accept
+10 drop all 0 0 ct state invalid
+110 jump all 2 208 iifname @I_br0-ifaces jump NAME_br0-fwd
+120 jump all 10 670 iifname @I_br1-ifaces jump NAME_br1-fwd
+130 jump all 12 3086 iifname @I_br2-ifaces jump NAME_br2-fwd
+default drop all 0 0
+
+---------------------------------
+bridge Firewall "name br0-fwd"
+
+Rule Action Protocol Packets Bytes
+------- -------- ---------- --------- -------
+default accept all 2 208
+
+---------------------------------
+bridge Firewall "name br0-pre"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------
+10 accept all 18 1872 ether type ip6 accept
+default drop all 9 1476
+
+---------------------------------
+bridge Firewall "name br1-fwd"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------
+10 accept all 5 250 ether type arp accept
+20 accept all 3 252 ct state new ip saddr 10.1.1.102 accept
+default drop all 2 168
+
+---------------------------------
+bridge Firewall "name br1-pre"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------------------------------------------------------
+10 drop udp 3 1176 ether daddr ff:ff:ff:ff:ff:ff udp sport 68 udp dport 67 prefix "[bri-NAM-br1-pre-10-D]"
+20 drop all 0 0 ether type ip6
+default accept all 58 4430
+
+---------------------------------
+bridge Firewall "name br2-fwd"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ---------------------------------------------------------------
+10 accept udp 4 1312 ether daddr ff:ff:ff:ff:ff:ff udp sport 68 udp dport 67 accept
+20 accept udp 2 656 udp sport 67 udp dport 68 iifname "eth6" accept
+22 drop udp 1 322 udp sport 67 udp dport 68 prefix "[bri-NAM-br2-fwd-22-D]"
+30 accept all 2 92 ether type arp accept
+40 accept all 3 704 ether type ip accept
+default drop all 0 0
+
+---------------------------------
+bridge Firewall "name br2-pre"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- --------------
+10 drop all 7 728 ether type ip6
+default accept all 77 7548
+
+---------------------------------
+bridge Firewall "prerouting filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------
+10 jump all 27 3348 iifname @I_br0-ifaces jump NAME_br0-pre
+20 jump all 61 5606 iifname @I_br1-ifaces jump NAME_br1-pre
+30 jump all 84 8276 iifname @I_br2-ifaces jump NAME_br2-pre
+default drop all 0 0
+
+vyos@bridge:~$
+```
+
+IPv4 firewall rulset:
+
+```none
+vyos@bridge:~$ show firewall ipv4
+Rulesets ipv4 Information
+
+---------------------------------
+ipv4 Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -------------------------------------------
+5 accept all 76 6384 ct state { established, related } accept
+10 drop all 0 0 ct state invalid
+110 jump all 13 1092 iifname @I_br1-ifaces jump NAME_ip-br1-fwd
+120 jump all 3 252 iifname @I_br2-ifaces jump NAME_ip-br2-fwd
+default drop all 0 0
+
+---------------------------------
+ipv4 Firewall "input filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------------------
+10 accept all 0 0 ct state { established, related } accept
+20 drop all 0 0 ct state invalid
+110 accept all 10 720 iifname @I_br1-ifaces accept
+120 drop all 26 2672 iifname @I_br2-ifaces
+default accept all 3037 991621
+
+---------------------------------
+ipv4 Firewall "name ip-br1-fwd"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------
+10 accept all 5 420 oifname "eth0" accept
+default drop all 8 672
+
+---------------------------------
+ipv4 Firewall "name ip-br2-fwd"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------
+10 accept all 1 84 oifname "eth0" accept
+20 accept all 2 168 oifname @I_br1-ifaces accept
+default drop all 0 0
+
+vyos@bridge:~$
+```
diff --git a/docs/configexamples/fwall-and-vrf.md b/docs/configexamples/fwall-and-vrf.md
new file mode 100644
index 00000000..da9949db
--- /dev/null
+++ b/docs/configexamples/fwall-and-vrf.md
@@ -0,0 +1,121 @@
+# VRF and firewall example
+
+## Scenario and requirements
+
+This example shows how to configure a VyOS router with VRFs and firewall rules.
+
+Diagram used in this example:
+
+```{image} /_static/images/firewall-and-vrf-blueprints.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+As exposed in the diagram, there are four VRFs. These VRFs are `MGMT`,
+`WAN`, `LAN` and `PROD`, and their requirements are:
+
+```{eval-rst}
+* VRF MGMT:
+ * Allow connections to LAN and PROD.
+ * Deny connections to internet(WAN).
+ * Allow connections to the router.
+* VRF LAN:
+ * Allow connections to PROD.
+ * Allow connections to internet(WAN).
+* VRF PROD:
+ * Only accepts connections.
+* VRF WAN:
+ * Allow connection to PROD.
+```
+
+## Configuration
+
+First, we need to configure the interfaces and VRFs:
+
+```none
+set interfaces ethernet eth1 address '10.100.100.1/24'
+set interfaces ethernet eth1 vrf 'MGMT'
+set interfaces ethernet eth2 vif 150 address '10.150.150.1/24'
+set interfaces ethernet eth2 vif 150 vrf 'LAN'
+set interfaces ethernet eth2 vif 160 address '10.160.160.1/24'
+set interfaces ethernet eth2 vif 160 vrf 'LAN'
+set interfaces ethernet eth2 vif 3500 address '172.16.20.1/24'
+set interfaces ethernet eth2 vif 3500 vrf 'PROD'
+set interfaces loopback lo
+set interfaces pppoe pppoe0 authentication password 'p4ssw0rd'
+set interfaces pppoe pppoe0 authentication username 'vyos'
+set interfaces pppoe pppoe0 source-interface 'eth0'
+set interfaces pppoe pppoe0 vrf 'WAN'
+set vrf bind-to-all
+set vrf name LAN protocols static route 0.0.0.0/0 interface pppoe0 vrf 'WAN'
+set vrf name LAN protocols static route 10.100.100.0/24 interface eth1 vrf 'MGMT'
+set vrf name LAN protocols static route 172.16.20.0/24 interface eth2.3500 vrf 'PROD'
+set vrf name LAN table '103'
+set vrf name MGMT protocols static route 10.150.150.0/24 interface eth2.150 vrf 'LAN'
+set vrf name MGMT protocols static route 10.160.160.0/24 interface eth2.160 vrf 'LAN'
+set vrf name MGMT protocols static route 172.16.20.0/24 interface eth2.3500 vrf 'PROD'
+set vrf name MGMT table '102'
+set vrf name PROD protocols static route 0.0.0.0/0 interface pppoe0 vrf 'WAN'
+set vrf name PROD protocols static route 10.100.100.0/24 interface eth1 vrf 'MGMT'
+set vrf name PROD protocols static route 10.150.150.0/24 interface eth2.150 vrf 'LAN'
+set vrf name PROD protocols static route 10.160.160.0/24 interface eth2.160 vrf 'LAN'
+set vrf name PROD table '104'
+set vrf name WAN protocols static route 10.150.150.0/24 interface eth2.150 vrf 'LAN'
+set vrf name WAN protocols static route 10.160.160.0/24 interface eth2.160 vrf 'LAN'
+set vrf name WAN protocols static route 172.16.20.0/24 interface eth2.3500 vrf 'PROD'
+set vrf name WAN table '101'
+```
+
+And before firewall rules are shown, we need to pay attention how to configure
+and match interfaces and VRFs. In case where an interface is assigned to a
+non-default VRF, if we want to use inbound-interface or outbound-interface in
+firewall rules, we need to:
+
+- For **inbound-interface**: use the interface name with the VRF name, like
+ `MGMT` or `LAN`.
+- For **outbound-interface**: use the interface name, like `eth0`, `vtun0`,
+ `eth2*` or similar.
+
+Next, we need to configure the firewall rules. First we will define all rules
+for transit traffic between VRFs.
+
+```none
+set firewall ipv4 forward filter default-action 'drop'
+set firewall ipv4 forward filter default-log
+set firewall ipv4 forward filter rule 10 action 'accept'
+set firewall ipv4 forward filter rule 10 description 'MGMT - Allow to LAN and PROD'
+set firewall ipv4 forward filter rule 10 inbound-interface name 'MGMT'
+set firewall ipv4 forward filter rule 10 outbound-interface name 'eth2*'
+set firewall ipv4 forward filter rule 99 action 'drop'
+set firewall ipv4 forward filter rule 99 description 'MGMT - Drop all going to mgmt'
+set firewall ipv4 forward filter rule 99 outbound-interface name 'eth1'
+set firewall ipv4 forward filter rule 120 action 'accept'
+set firewall ipv4 forward filter rule 120 description 'LAN - Allow to PROD'
+set firewall ipv4 forward filter rule 120 inbound-interface name 'LAN'
+set firewall ipv4 forward filter rule 120 outbound-interface name 'eth2.3500'
+set firewall ipv4 forward filter rule 130 action 'accept'
+set firewall ipv4 forward filter rule 130 description 'LAN - Allow internet'
+set firewall ipv4 forward filter rule 130 inbound-interface name 'LAN'
+set firewall ipv4 forward filter rule 130 outbound-interface name 'pppoe0'
+```
+
+Also, we are adding global state policies, in order to allow established and
+related traffic, in order not to drop valid responses:
+
+```none
+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'
+```
+
+And finally, we need to allow input connections to the router itself only from
+vrf MGMT:
+
+```none
+set firewall ipv4 input filter default-action 'drop'
+set firewall ipv4 input filter default-log
+set firewall ipv4 input filter rule 10 action 'accept'
+set firewall ipv4 input filter rule 10 description 'MGMT - Allow input'
+set firewall ipv4 input filter rule 10 inbound-interface name 'MGMT'
+```
diff --git a/docs/configexamples/ha.md b/docs/configexamples/ha.md
new file mode 100644
index 00000000..b272f38e
--- /dev/null
+++ b/docs/configexamples/ha.md
@@ -0,0 +1,556 @@
+---
+lastproofread: '2021-06-28'
+---
+
+(example-high-availability)=
+
+# High Availability Walkthrough
+
+This document walks you through a complete HA setup of two VyOS machines. This
+design is based on a VM as the primary router and a physical machine as a
+backup, using VRRP, BGP, OSPF, and conntrack sharing.
+
+This document aims to walk you through setting everything up, so
+at a point where you can reboot any machine and not lose more than a few
+seconds worth of connectivity.
+
+## Design
+
+This is based on a real-life production design. One of the complex issues
+is ensuring you have redundant data INTO your network. We do this with a pair
+of Cisco Nexus switches and using Virtual PortChannels that are spanned across
+them. As a bonus, this also allows for complete switch failure without
+an outage. How you achieve this yourself is left as an exercise to the reader.
+But our setup is documented here.
+
+### Walkthrough suggestion
+
+The `commit` command is implied after every section. If you make an error,
+`commit` will warn you and you can fix it before getting too far into things.
+Please ensure you commit early and commit often.
+
+If you are following through this document, it is strongly suggested you
+complete the entire document, ONLY doing the virtual router1 steps, and then
+come back and walk through it AGAIN on the backup hardware router.
+
+This ensures you don't go too fast or miss a step. However, it will make your
+life easier to configure the fixed IP address and default route now on the
+hardware router.
+
+### Example Network
+
+In this document, we have been allocated 203.0.113.0/24 by our upstream
+provider, which we are publishing on VLAN100.
+
+They want us to establish a BGP session to their routers on 192.0.2.11 and
+192.0.2.12 from our routers 192.0.2.21 and 192.0.2.22. They are AS 65550 and
+we are AS 65551.
+
+Our routers are going to have a floating IP address of 203.0.113.1, and use
+.2 and .3 as their fixed IPs.
+
+We are going to use 10.200.201.0/24 for an 'internal' network on VLAN201.
+
+When traffic is originated from the 10.200.201.0/24 network, it will be
+masqueraded to 203.0.113.1
+
+For connection between sites, we are running a WireGuard link to two REMOTE
+routers and using OSPF over those links to distribute routes. That remote
+site is expected to send traffic from anything in 10.201.0.0/16
+
+### VLANs
+
+These are the vlans we will be using:
+
+- 50: Upstream, using the 192.0.2.0/24 network allocated by them.
+- 100: 'Public' network, using our 203.0.113.0/24 network.
+- 201: 'Internal' network, using 10.200.201.0/24
+
+### Hardware
+
+- switch1 (Nexus 10gb Switch)
+- switch2 (Nexus 10gb Switch)
+- compute1 (VMware ESXi 6.5)
+- compute2 (VMware ESXi 6.5)
+- compute3 (VMware ESXi 6.5)
+- router2 (Random 1RU machine with 4 NICs)
+
+Note that router1 is a VM that runs on one of the compute nodes.
+
+### Network Cabling
+
+- From Datacenter - This connects into port 1 on both switches, and is tagged
+ as VLAN 50
+- Cisco VPC Crossconnect - Ports 39 and 40 bonded between each switch
+- Hardware Router - Port 8 of each switch
+- compute1 - Port 9 of each switch
+- compute2 - Port 10 of each switch
+- compute3 - Port 11 of each switch
+
+This is ignoring the extra Out-of-band management networking, which should be
+on totally different switches, and a different feed into the rack, and is out
+of scope of this.
+
+:::{note}
+Our implementation uses VMware's Distributed Port Groups, which allows
+VMware to use LACP. This is a part of the ENTERPRISE licence, and is not
+available on a free licence. If you are implementing this and do not have
+access to DPGs, you should not use VMware, and use some other virtualization
+platform instead.
+:::
+
+## Basic Setup (via console)
+
+Create your router1 VM. So it can withstand a VM Host failing or a
+network link failing. Using VMware, this is achieved by enabling vSphere DRS,
+vSphere Availability, and creating a Distributed Port Group that uses LACP.
+
+Many other Hypervisors do this, and I'm hoping that this document will be
+expanded to document how to do this for others.
+
+Create an 'All VLANs' network group, that passes all trunked traffic through
+to the VM. Attach this network group to router1 as eth0.
+
+:::{note}
+VMware: You must DISABLE SECURITY on this Port group. Make sure that
+`Promiscuous Mode`, `MAC address changes` and `Forged transmits` are
+enabled. All of these will be done as part of failover.
+:::
+
+### Bonding on Hardware Router
+
+Create a LACP bond on the hardware router. We are assuming that eth0 and eth1
+are connected to port 8 on both switches, and that those ports are configured
+as a Port-Channel.
+
+```none
+set interfaces bonding bond0 description 'Switch Port-Channel'
+set interfaces bonding bond0 hash-policy 'layer2'
+set interfaces bonding bond0 member interface 'eth0'
+set interfaces bonding bond0 member interface 'eth1'
+set interfaces bonding bond0 mode '802.3ad'
+```
+
+
+### Assign external IP addresses
+
+VLAN 100 and 201 will have floating IP addresses, but VLAN50 does not, as this
+is talking directly to upstream. Create our IP address on vlan50.
+
+For the hardware router, replace `eth0` with `bond0`. As (almost) every
+command is identical, this will not be specified unless different things need
+to be performed on different hosts.
+
+```none
+set interfaces ethernet eth0 vif 50 address '192.0.2.21/24'
+```
+
+In this case, the hardware router has a different IP, so it would be
+
+```none
+set interfaces ethernet bond0 vif 50 address '192.0.2.22/24'
+```
+
+
+### Add (temporary) default route
+
+It is assumed that the routers provided by upstream are capable of acting as a
+default router, add that as a static route.
+
+```none
+set protocols static route 0.0.0.0/0 next-hop 192.0.2.11
+commit
+save
+```
+
+
+### Enable SSH
+
+Enable SSH so you can now SSH into the routers, rather than using the console.
+
+```none
+set service ssh
+commit
+save
+```
+
+At this point, you should be able to SSH into both of them, and will no longer
+need access to the console (unless you break something!)
+
+## VRRP Configuration
+
+We are setting up VRRP so that it does NOT fail back when a machine returns into
+service, and it prioritizes router1 over router2.
+
+### Internal Network
+
+This has a floating IP address of 10.200.201.1/24, using virtual router ID 201.
+The difference between them is the interface name, hello-source-address, and
+peer-address.
+
+**router1**
+
+```none
+set interfaces ethernet eth0 vif 201 address 10.200.201.2/24
+set high-availability vrrp group int hello-source-address '10.200.201.2'
+set high-availability vrrp group int interface 'eth0.201'
+set high-availability vrrp group int peer-address '10.200.201.3'
+set high-availability vrrp group int no-preempt
+set high-availability vrrp group int priority '200'
+set high-availability vrrp group int address '10.200.201.1/24'
+set high-availability vrrp group int vrid '201'
+```
+
+**router2**
+
+```none
+set interfaces ethernet bond0 vif 201 address 10.200.201.3/24
+set high-availability vrrp group int hello-source-address '10.200.201.3'
+set high-availability vrrp group int interface 'bond0.201'
+set high-availability vrrp group int peer-address '10.200.201.2'
+set high-availability vrrp group int no-preempt
+set high-availability vrrp group int priority '100'
+set high-availability vrrp group int address '10.200.201.1/24'
+set high-availability vrrp group int vrid '201'
+```
+
+
+### Public Network
+
+This has a floating IP address of 203.0.113.1/24, using virtual router ID 113.
+The virtual router ID is just a random number between 1 and 254, and can be set
+to whatever you want. Best practices suggest you try to keep them unique
+enterprise-wide.
+
+**router1**
+
+```none
+set interfaces ethernet eth0 vif 100 address 203.0.113.2/24
+set high-availability vrrp group public hello-source-address '203.0.113.2'
+set high-availability vrrp group public interface 'eth0.100'
+set high-availability vrrp group public peer-address '203.0.113.3'
+set high-availability vrrp group public no-preempt
+set high-availability vrrp group public priority '200'
+set high-availability vrrp group public address '203.0.113.1/24'
+set high-availability vrrp group public vrid '113'
+```
+
+**router2**
+
+```none
+set interfaces ethernet bond0 vif 100 address 203.0.113.3/24
+set high-availability vrrp group public hello-source-address '203.0.113.3'
+set high-availability vrrp group public interface 'bond0.100'
+set high-availability vrrp group public peer-address '203.0.113.2'
+set high-availability vrrp group public no-preempt
+set high-availability vrrp group public priority '100'
+set high-availability vrrp group public address '203.0.113.1/24'
+set high-availability vrrp group public vrid '113'
+```
+
+
+### Create VRRP sync-group
+
+The sync group is used to replicate connection tracking. It needs to be assigned
+to a random VRRP group, and we are creating a sync group called `sync` using
+the vrrp group `int`.
+
+```none
+set high-availability vrrp sync-group sync member 'int'
+```
+
+
+### Testing
+
+At this point, you should be able to see both IP addresses when you run
+`show interfaces`, and `show vrrp` should show both interfaces in MASTER
+state (and SLAVE state on router2).
+
+```none
+vyos@router1:~$ show vrrp
+Name Interface VRID State Last Transition
+-------- ----------- ------ ------- -----------------
+int eth0.201 201 MASTER 100s
+public eth0.100 113 MASTER 200s
+vyos@router1:~$
+```
+
+You should be able to ping to and from all the IPs you have allocated.
+
+## NAT and conntrack-sync
+
+Masquerade Traffic originating from 10.200.201.0/24 that is heading out the
+public interface.
+
+:::{note}
+We explicitly exclude the primary upstream network so that BGP or
+OSPF traffic doesn't accidentally get NAT'ed.
+:::
+
+```none
+set nat source rule 10 destination address '!192.0.2.0/24'
+set nat source rule 10 outbound-interface name 'eth0.50'
+set nat source rule 10 source address '10.200.201.0/24'
+set nat source rule 10 translation address '203.0.113.1'
+```
+
+
+### Configure conntrack-sync and enable helpers
+
+Conntrack helper modules are enabled by default, but they tend to cause more
+problems than they're worth in complex networks. You can disable all of them
+at one go.
+
+```none
+delete system conntrack modules
+```
+
+Now enable replication between nodes. Replace eth0.201 with bond0.201 on the
+hardware router.
+
+```none
+set service conntrack-sync accept-protocol 'tcp,udp,icmp'
+set service conntrack-sync event-listen-queue-size '8'
+set service conntrack-sync failover-mechanism vrrp sync-group 'sync'
+set service conntrack-sync interface eth0.201
+set service conntrack-sync mcast-group '224.0.0.50'
+set service conntrack-sync sync-queue-size '8'
+```
+
+(ha-contracktesting)=
+
+### Testing
+
+The simplest way to test is to look at the connection tracking stats on the
+standby hardware router with the command `show conntrack-sync statistics`.
+The numbers should be very close to the numbers on the primary router.
+
+When you have both routers up, you should be able to establish a connection
+from a NAT'ed machine out to the internet, reboot the active machine, and that
+connection should be preserved, and will not drop out.
+
+## OSPF Over WireGuard
+
+Wireguard doesn't have the concept of an up or down link, due to its design.
+This complicates AND simplifies using it for network transport, as for reliable
+state detection you need to use SOMETHING to detect when the link is down.
+
+If you use a routing protocol itself, you solve two problems at once. This is
+only a basic example, and is provided as a starting point.
+
+### Configure Wireguard
+
+There is plenty of instructions and documentation on setting up Wireguard. The
+only important thing you need to remember is to only use one WireGuard
+interface per OSPF connection.
+
+We use small /30's from 10.254.60/24 for the point-to-point links.
+
+**router1**
+
+Replace the 203.0.113.3 with whatever the other router's IP address is.
+
+```none
+set interfaces wireguard wg01 address '10.254.60.1/30'
+set interfaces wireguard wg01 description 'router1-to-offsite1'
+set interfaces wireguard wg01 peer OFFSITE1 allowed-ips '0.0.0.0/0'
+set interfaces wireguard wg01 peer OFFSITE1 endpoint '203.0.113.3:50001'
+set interfaces wireguard wg01 peer OFFSITE1 persistent-keepalive '15'
+set interfaces wireguard wg01 peer OFFSITE1 pubkey 'GEFMOWzAyau42/HwdwfXnrfHdIISQF8YHj35rOgSZ0o='
+set interfaces wireguard wg01 port '50001'
+set protocols ospf interface wg01 authentication md5 key-id 1 md5-key 'i360KoCwUGZvPq7e'
+set protocols ospf interface wg01 cost '11'
+set protocols ospf interface wg01 dead-interval '5'
+set protocols ospf interface wg01 hello-interval '1'
+set protocols ospf interface wg01 network 'point-to-point'
+set protocols ospf interface wg01 priority '1'
+set protocols ospf interface wg01 retransmit-interval '5'
+set protocols ospf interface wg01 transmit-delay '1'
+```
+
+**offsite1**
+
+This is connecting back to the STATIC IP of router1, not the floating.
+
+```none
+set interfaces wireguard wg01 address '10.254.60.2/30'
+set interfaces wireguard wg01 description 'offsite1-to-router1'
+set interfaces wireguard wg01 peer ROUTER1 allowed-ips '0.0.0.0/0'
+set interfaces wireguard wg01 peer ROUTER1 endpoint '192.0.2.21:50001'
+set interfaces wireguard wg01 peer ROUTER1 persistent-keepalive '15'
+set interfaces wireguard wg01 peer ROUTER1 pubkey 'CKwMV3ZaLntMule2Kd3G7UyVBR7zE8/qoZgLb82EE2Q='
+set interfaces wireguard wg01 port '50001'
+set protocols ospf interface wg01 authentication md5 key-id 1 md5-key 'i360KoCwUGZvPq7e'
+set protocols ospf interface wg01 cost '11'
+set protocols ospf interface wg01 dead-interval '5'
+set protocols ospf interface wg01 hello-interval '1'
+set protocols ospf interface wg01 network 'point-to-point'
+set protocols ospf interface wg01 priority '1'
+set protocols ospf interface wg01 retransmit-interval '5'
+set protocols ospf interface wg01 transmit-delay '1'
+```
+
+
+### Test WireGuard
+
+Make sure you can ping 10.254.60.1 and .2 from both routers.
+
+### Create Export Filter
+
+We only want to export the networks we know. Always do a whitelist on your route
+filters, both importing and exporting. A good rule of thumb is
+**'If you are not the default router for a network, don't advertise
+it'**. This means we explicitly do not want to advertise the 192.0.2.0/24
+network (but do want to advertise 10.200.201.0 and 203.0.113.0, which we ARE
+the default route for). This filter is applied to `redistribute connected`.
+If we WERE to advertise it, the remote machines would see 192.0.2.21 available
+via their default route, establish the connection, and then OSPF would say
+'192.0.2.0/24 is available via this tunnel', at which point the tunnel would
+break, OSPF would drop the routes, and then 192.0.2.0/24 would be reachable via
+default again. This is called 'flapping'.
+
+```none
+set policy access-list 150 description 'Outbound OSPF Redistribution'
+set policy access-list 150 rule 10 action 'permit'
+set policy access-list 150 rule 10 destination any
+set policy access-list 150 rule 10 source inverse-mask '0.0.0.255'
+set policy access-list 150 rule 10 source network '10.200.201.0'
+set policy access-list 150 rule 20 action 'permit'
+set policy access-list 150 rule 20 destination any
+set policy access-list 150 rule 20 source inverse-mask '0.0.0.255'
+set policy access-list 150 rule 20 source network '203.0.113.0'
+set policy access-list 150 rule 100 action 'deny'
+set policy access-list 150 rule 100 destination any
+set policy access-list 150 rule 100 source any
+```
+
+
+### Create Import Filter
+
+We only want to import networks we know. Our OSPF peer should only be
+advertising networks in the 10.201.0.0/16 range. Note that this is an INVERSE
+MATCH. You deny in access-list 100 to accept the route.
+
+```none
+set policy access-list 100 description 'Inbound OSPF Routes from Peers'
+set policy access-list 100 rule 10 action 'deny'
+set policy access-list 100 rule 10 destination any
+set policy access-list 100 rule 10 source inverse-mask '0.0.255.255'
+set policy access-list 100 rule 10 source network '10.201.0.0'
+set policy access-list 100 rule 100 action 'permit'
+set policy access-list 100 rule 100 destination any
+set policy access-list 100 rule 100 source any
+set policy route-map PUBOSPF rule 100 action 'deny'
+set policy route-map PUBOSPF rule 100 match ip address access-list '100'
+set policy route-map PUBOSPF rule 500 action 'permit'
+```
+
+
+### Enable OSPF
+
+Every router **must** have a unique router-id.
+The 'reference-bandwidth' is used because when OSPF was originally designed,
+the idea of a link faster than 1gbit was unheard of, and it does not scale
+correctly.
+
+```none
+set protocols ospf area 0.0.0.0 authentication 'md5'
+set protocols ospf area 0.0.0.0 network '10.254.60.0/24'
+set protocols ospf auto-cost reference-bandwidth '10000'
+set protocols ospf log-adjacency-changes
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.254.60.2'
+set system ip protocol ospf route-map PUBOSPF
+```
+
+
+### Test OSPF
+
+When you have enabled OSPF on both routers, you should be able to see each
+other with the command `show ip ospf neighbour`. The state must be 'Full'
+or '2-Way'. If it is not, then there is a network connectivity issue between the
+hosts. This is often caused by NAT or MTU issues. You should not see any new
+routes (unless this is the second pass) in the output of `show ip route`
+
+## Advertise connected routes
+
+As a reminder, only advertise routes that you are the default router for. This
+is why we are NOT announcing the 192.0.2.0/24 network, because if that was
+announced into OSPF, the other routers would try to connect to that network
+over a tunnel that connects to that network!
+
+```none
+set protocols ospf access-list 150 export 'connected'
+set protocols ospf redistribute connected
+```
+
+You should now be able to see the advertised network on the other host.
+
+### Duplicate configuration
+
+At this point, you now need to create the X link between all four routers.
+Use amdifferent /30 for each link.
+
+### Priorities
+
+Set the cost on the secondary links to be 200. This means that they will not
+be used unless the primary links are down.
+
+```none
+set protocols ospf interface wg01 cost '10'
+set protocols ospf interface wg01 cost '200'
+```
+
+This will be visible in 'show ip route'.
+
+## BGP
+
+BGP is an extremely complex network protocol. An example is provided here.
+
+:::{note}
+Router id's must be unique.
+:::
+
+**router1**
+
+The `redistribute ospf` command is there purely as an example of how this can
+be expanded. In this walkthrough, it will be filtered by BGPOUT rule 10000, as
+it is not 203.0.113.0/24.
+
+```none
+set policy prefix-list BGPOUT description 'BGP Export List'
+set policy prefix-list BGPOUT rule 10 action 'deny'
+set policy prefix-list BGPOUT rule 10 description 'Do not advertise short masks'
+set policy prefix-list BGPOUT rule 10 ge '25'
+set policy prefix-list BGPOUT rule 10 prefix '0.0.0.0/0'
+set policy prefix-list BGPOUT rule 100 action 'permit'
+set policy prefix-list BGPOUT rule 100 description 'Our network'
+set policy prefix-list BGPOUT rule 100 prefix '203.0.113.0/24'
+set policy prefix-list BGPOUT rule 10000 action 'deny'
+set policy prefix-list BGPOUT rule 10000 prefix '0.0.0.0/0'
+
+set policy route-map BGPOUT description 'BGP Export Filter'
+set policy route-map BGPOUT rule 10 action 'permit'
+set policy route-map BGPOUT rule 10 match ip address prefix-list 'BGPOUT'
+set policy route-map BGPOUT rule 10000 action 'deny'
+set policy route-map BGPPREPENDOUT description 'BGP Export Filter'
+set policy route-map BGPPREPENDOUT rule 10 action 'permit'
+set policy route-map BGPPREPENDOUT rule 10 set as-path prepend '65551 65551 65551'
+set policy route-map BGPPREPENDOUT rule 10 match ip address prefix-list 'BGPOUT'
+set policy route-map BGPPREPENDOUT rule 10000 action 'deny'
+
+set protocols bgp system-as 65551
+set protocols bgp address-family ipv4-unicast network 192.0.2.0/24
+set protocols bgp address-family ipv4-unicast redistribute connected metric '50'
+set protocols bgp address-family ipv4-unicast redistribute ospf metric '50'
+set protocols bgp neighbor 192.0.2.11 address-family ipv4-unicast route-map export 'BGPOUT'
+set protocols bgp neighbor 192.0.2.11 address-family ipv4-unicast soft-reconfiguration inbound
+set protocols bgp neighbor 192.0.2.11 remote-as '65550'
+set protocols bgp neighbor 192.0.2.11 update-source '192.0.2.21'
+set protocols bgp parameters router-id '192.0.2.21'
+```
+
+**router2**
+
+This is identical, but you use the BGPPREPENDOUT route-map to advertise the
+route with a longer path.
diff --git a/docs/configexamples/index.md b/docs/configexamples/index.md
new file mode 100644
index 00000000..e5a81305
--- /dev/null
+++ b/docs/configexamples/index.md
@@ -0,0 +1,60 @@
+(examples)=
+
+# Configuration Blueprints
+
+This chapter contains various configuration examples:
+
+```{toctree}
+:maxdepth: 2
+
+firewall
+bgp-ipv6-unnumbered
+ospf-unnumbered
+azure-vpn-bgp
+azure-vpn-dual-bgp
+ha
+wan-load-balancing
+pppoe-ipv6-basic
+l3vpn-hub-and-spoke
+lac-lns
+inter-vrf-routing-vrf-lite
+dmvpn-dualhub-dualcloud
+qos
+segment-routing-isis
+nmp
+ansible
+ipsec-cisco-policy-based
+ipsec-cisco-route-based
+ipsec-pa-route-based
+policy-based-ipsec-and-firewall
+site-2-site-cisco
+```
+
+
+## Configuration Blueprints (autotest)
+
+The next pages contain fully automated configuration examples.
+
+Each lab will build and test from an external script.
+The page content is generated, so changes will not take effect.
+
+A host `vyos-oobm` will be used as an SSH proxy. This host is just
+necessary for the lab tests.
+
+The process will do the following steps:
+1. create the lab on a eve-ng server
+2. configure each host in the lab
+3. do some defined tests
+4. optional do an upgrade to a higher version and do step 3 again.
+5. generate the documentation and include files
+6. shutdown and destroy the lab, if there is no error
+
+```{toctree}
+:maxdepth: 1
+
+autotest/DHCPRelay_through_GRE/DHCPRelay_through_GRE
+autotest/tunnelbroker/tunnelbroker
+autotest/L3VPN_EVPN/L3VPN_EVPN
+autotest/Wireguard/Wireguard
+autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP
+```
diff --git a/docs/configexamples/inter-vrf-routing-vrf-lite.md b/docs/configexamples/inter-vrf-routing-vrf-lite.md
new file mode 100644
index 00000000..881f482b
--- /dev/null
+++ b/docs/configexamples/inter-vrf-routing-vrf-lite.md
@@ -0,0 +1,797 @@
+# Inter-VRF Routing over VRF Lite
+
+**Virtual Routing and Forwarding** is a technology that allow multiple instance
+of a routing table to exist within a single device. One of the key aspect of
+**VRFs** is that do not share the same routes or interfaces, therefore packets
+are forwarded between interfaces that belong to the same VRF only.
+
+Any information related to a VRF is not exchanged between devices -or in the
+same device- by default, this is a technique called **VRF-Lite**.
+
+Keep networks isolated is -in general- a good principle, but there are cases
+where you might need that some network can access other in a different VRF.
+
+The scope of this document is to cover such cases in a dynamic way without the
+use of MPLS-LDP.
+
+General information about L3VPNs can be found in the {ref}`configuration/vrf/index:L3VPN VRFs` chapter.
+
+## Overview
+
+Let’s say we have a requirement to have multiple networks.
+
+- LAN 1
+- LAN 2
+- Management
+- Internet
+
+Both LANs have to be able to route between each other, both will have managed
+devices through a dedicated management network and both will need Internet
+access yet the LAN2 will need access to some set of outside networks, not all.
+The management network will need access to both LANs but cannot have access
+to/from the outside.
+
+This scenario could be a nightmare applying regular routing and might need
+filtering in multiple interfaces.
+
+A simple solution could be using different routing tables, or VRFs
+for all the networks so we can keep the routing restrictions.
+But for us to route between the different VRFs we would need a cable or a
+logical connection between each other:
+
+- One cable/logical connection between LAN1 and LAN2
+- One cable/logical connection between LAN1 and Internet
+- One cable/logical connection between LAN2 and Internet
+- One cable/logical connection between LAN1 and Management
+- One cable/logical connection between LAN2 and Management
+
+As we can see this is unpractical.
+
+To address this scenario we will use to our advantage an extension of the BGP
+routing protocol that will help us in the “Export” between VRFs without the
+need for MPLS.
+
+MP-BGP or MultiProtocol BGP introduces two main concepts to solve this
+limitation:
+\- Route Distinguisher (RD): Is used to distinguish between different VRFs
+–called VPNs- inside the BGP Process. The RD is appended to each IPv4 Network
+that is advertised into BGP for that VPN making it a unique VPNv4 route.
+\- Route Target (RT): This is an extended BGP community append to the VPNv4 route
+in the Import/Export process. When a route passes from the VRF routing table
+into the BGP process it will add the configured export extended community(ies)
+for that VPN. When that route needs to go from BGP into the VRF routing table
+will only pass if that given VPN import policy matches any of the appended
+community(ies) into that prefix.
+
+## Topology
+
+```{image} /_static/images/inter-vrf-routing-vrf-lite.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 70%
+```
+
+
+### IP Schema
+
+```{eval-rst}
++----------+------------+----------------+------------------+
+| Device-A | Device-B | IPv4 Network | IPv6 Network |
++----------+------------+----------------+------------------+
+| Core | LAN1 | 10.1.1.0/30 | 2001:db8::/127 |
++----------+------------+----------------+------------------+
+| Core | LAN2 | 172.16.2.0/30 | 2001:db8::2/127 |
++----------+------------+----------------+------------------+
+| Core | Management | 192.168.3.0/30 | 2001:db8::4/127 |
++----------+------------+----------------+------------------+
+| Core | ISP | 10.2.2.0/30 | 2001:db8::6/127 |
++----------+------------+----------------+------------------+
+```
+
+### RD & RT Schema
+
+```{eval-rst}
++------------+-----------+-----------+
+| VRF | RD | RT |
++------------+-----------+-----------+
+| LAN1 | 64496:1 | 64496:1 |
++------------+-----------+-----------+
+| LAN2 | 64496:2 | 64496:2 |
++------------+-----------+-----------+
+| Management | 64496:50 | 64496:50 |
++------------+-----------+-----------+
+| Internet | 64496:100 | 64496:100 |
++------------+-----------+-----------+
+```
+
+## Configurations
+
+:::{note}
+We use a static route configuration in between the Core and each
+LAN and Management router, and BGP between the Core router and the ISP router
+but any dynamic routing protocol can be used.
+:::
+
+### Remote Networks
+
+The following template configuration can be used in each remote router based
+in our topology.
+
+```none
+# Interface Configuration
+set interface eth eth<N> address <IP ADDRESS/CIDR>
+
+# Static default route back to Core
+set procotols static route 0.0.0.0/0 next-hop <CORE IP ADDRESS>
+```
+
+
+### Core Router
+
+#### Step 1: VRF and Configurations to remote networks
+
+- Configuration
+
+Set the VRF name and Table ID, set interface address and bind it to the VRF.
+Last add the static route to the remote network.
+
+```none
+# VRF name and table ID (MANDATORY)
+set vrf name <VRF> table <ID>
+
+# Interface Configuration
+set interface eth eth<N> address <IP ADDRESS/CIDR>
+
+# Assign interface to VRF
+set interface eth eth<N> vrf <VRF>
+
+# Static route to remote Network
+set vrf name <VRF> protocols static route <NETWORK/CIDR> next-hop <REMOTE IP ADDRESS>
+```
+
+- Verification
+
+Checking the routing table of the VRF should reveal both static and connected
+entries active. A PING test between the Core and remote router is a way to
+validate connectivity within the VRF.
+
+```none
+# show ip route vrf <VRF>
+# show ipv6 route vrf <VRF>
+
+vyos@Core:~$ show ip route vrf LAN1
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+VRF LAN1:
+S>* 10.0.0.0/24 [1/0] via 10.1.1.2, eth0, weight 1, 00:05:41
+C>* 10.1.1.0/30 is directly connected, eth0, 00:05:44
+
+vyos@Core:~$ show ipv6 route vrf LAN1
+Codes: K - kernel route, C - connected, S - static, R - RIPng,
+ O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
+ v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+VRF LAN1:
+C>* 2001:db8::/127 is directly connected, eth0, 00:18:43
+S>* 2001:db8:0:1::/64 [1/0] via 2001:db8::1, eth0, weight 1, 00:16:03
+C>* fe80::/64 is directly connected, eth0, 00:18:43
+
+# ping <DESTINATION> vrf <VRF>
+
+vyos@Core:~$ ping 10.1.1.2 vrf LAN1
+PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
+64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=1.52 ms
+64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.830 ms
+^C
+--- 10.1.1.2 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 0.830/1.174/1.518/0.344 ms
+vyos@Core:~$ ping 10.0.0.1 vrf LAN1
+PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
+64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.785 ms
+64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.948 ms
+^C
+--- 10.0.0.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 0.785/0.866/0.948/0.081 ms
+
+vyos@Core:~$ ping 2001:db8:0:1::1 vrf LAN1
+PING 2001:db8:0:1::1(2001:db8:0:1::1) 56 data bytes
+64 bytes from 2001:db8:0:1::1: icmp_seq=1 ttl=64 time=3.04 ms
+64 bytes from 2001:db8:0:1::1: icmp_seq=2 ttl=64 time=1.04 ms
+64 bytes from 2001:db8:0:1::1: icmp_seq=3 ttl=64 time=0.925 ms
+^C
+--- 2001:db8:0:1::1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 0.925/1.665/3.035/0.969 ms
+```
+
+
+#### Step 2: BGP Configuration for VRF-Lite
+
+- Configuration
+
+Setting BGP global local-as as well inside the VRF. Redistribute static
+routes to inject configured networks into the BGP process but still inside
+the VRF.
+
+```none
+# set BGP global local-as
+set protocols bgp system-as <ASN>
+
+# set BGP VRF local-as and redistribution
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> redistribute static
+```
+
+- Verification
+
+Check the BGP VRF table and verify if the static routes are injected showing
+the correct next-hop information.
+
+```none
+# show ip bgp vrf <VRF>
+# show bgp vrf <VRF> ipv6
+
+vyos@Core:~$ show ip bgp vrf LAN1
+BGP table version is 3, local router ID is 10.1.1.1, vrf id 8
+Default local pref 100, local AS 64496
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+RPKI validation codes: V valid, I invalid, N Not found
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 10.0.0.0/24 10.1.1.2 0 32768 ?
+
+vyos@Core# run show bgp vrf LAN1 ipv6
+BGP table version is 13, local router ID is 10.1.1.1, vrf id 8
+Default local pref 100, local AS 64496
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+RPKI validation codes: V valid, I invalid, N Not found
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 2001:db8:0:1::/64
+ 2001:db8::1 0 32768 ?
+```
+
+
+#### Step 3: VPN Configuration
+
+- Configuration
+
+Within the VRF we set the Route-Distinguisher (RD) and Route-Targets (RT),
+then we enable the export/import VPN.
+
+```none
+# set Route-distinguisher
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> rd vpn export '<RD>'
+
+# set route-target for import/export
+# Note: RT are a list that can be more than one community between apostrophe
+# and separated by blank space. Ex: '<RT:1> <RT:2> <RT:3>'
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> route-target vpn export '<RT:Export>'
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> route-target vpn import '<RT:Import>'
+
+# Enable VPN export/import under this VRF
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> export vpn
+set vrf name <VRF> protocols bgp address-family <AF IPv4/IPv6> import vpn
+```
+
+A key point to understand is that if we need two VRFs to communicate between
+each other EXPORT rt from VRF1 has to be in the IMPORT rt list from VRF2. But
+this is only in ONE direction, to complete the communication the EXPORT rt from
+VRF2 has to be in the IMPORT rt list from VRF1.
+
+There are some cases where this is not needed -for example, in some
+DDoS appliance- but most inter-vrf routing designs use the above configurations.
+
+- Verification
+
+After configured all the VRFs involved in this topology we take a deeper look
+at both BGP and Routing table for the VRF LAN1
+
+```none
+# show ip bgp vrf <VRF>
+# show bgp vrf <VRF> ipv6
+
+vyos@Core# run show ip bgp vrf LAN1
+BGP table version is 53, local router ID is 10.1.1.1, vrf id 8
+Default local pref 100, local AS 64496
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+RPKI validation codes: V valid, I invalid, N Not found
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 0.0.0.0/0 10.2.2.2@7< 0 64497 i
+*> 10.0.0.0/24 10.1.1.2 0 32768 ?
+*> 10.2.2.0/30 10.2.2.2@7< 0 0 64497 ?
+*> 192.0.2.0/24 10.2.2.2@7< 0 0 64497 ?
+*> 192.168.0.0/24 192.168.3.2@11< 0 32768 ?
+*> 198.51.100.0/24 10.2.2.2@7< 0 0 64497 ?
+*> 203.0.113.0/24 10.2.2.2@7< 0 0 64497 ?
+
+vyos@Core# run show bgp vrf LAN1 ipv6
+BGP table version is 13, local router ID is 10.1.1.1, vrf id 8
+Default local pref 100, local AS 64496
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+RPKI validation codes: V valid, I invalid, N Not found
+
+Network Next Hop Metric LocPrf Weight Path
+*> ::/0 fe80::5200:ff:fe02:3@7<
+ 0 64497 i
+*> 2001:db8::6/127 fe80::5200:ff:fe02:3@7<
+ 0 0 64497 ?
+*> 2001:db8:0:1::/64
+ 2001:db8::1 0 32768 ?
+*> 2001:db8:0:3::/64
+ 2001:db8::5@11< 0 32768 ?
+*> 2001:db8:1::/48 fe80::5200:ff:fe02:3@7<
+ 0 0 64497 ?
+*> 2001:db8:2::/48 fe80::5200:ff:fe02:3@7<
+ 0 0 64497 ?
+*> 2001:db8:3::/48 fe80::5200:ff:fe02:3@7<
+ 0 0 64497 ?
+
+# show ip route vrf <VRF>
+# show ipv6 route vrf <VRF>
+
+vyos@Core:~$ show ip route vrf LAN1
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+VRF LAN1:
+B>* 0.0.0.0/0 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:00:38
+S>* 10.0.0.0/24 [1/0] via 10.1.1.2, eth0, weight 1, 00:29:57
+C>* 10.1.1.0/30 is directly connected, eth0, 00:29:59
+B 10.2.2.0/30 [20/0] via 10.2.2.2 (vrf Internet) inactive, weight 1, 00:00:38
+B>* 172.16.0.0/24 [20/0] via 172.16.2.2, eth1 (vrf LAN2), weight 1, 00:00:38
+B>* 192.0.2.0/24 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:00:38
+B>* 198.51.100.0/24 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:00:38
+B>* 203.0.113.0/24 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:00:38
+
+vyos@Core# run show ipv6 route vrf LAN1
+Codes: K - kernel route, C - connected, S - static, R - RIPng,
+ O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
+ v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+VRF LAN1:
+B>* ::/0 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:07:50
+C>* 2001:db8::/127 is directly connected, eth0, 05:33:43
+B>* 2001:db8::6/127 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:07:50
+S>* 2001:db8:0:1::/64 [1/0] via 2001:db8::1, eth0, weight 1, 05:31:03
+B>* 2001:db8:0:3::/64 [20/0] via 2001:db8::5, eth2 (vrf Management), weight 1, 00:07:50
+B>* 2001:db8:1::/48 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:07:50
+B>* 2001:db8:2::/48 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:07:50
+B>* 2001:db8:3::/48 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:07:50
+C>* fe80::/64 is directly connected, eth0, 05:33:43
+```
+
+As we can see in the BGP table any imported route has been injected with a "@"
+followed by the VPN id; In the routing table of the VRF, if the route was
+installed, we can see -between round brackets- the exported VRF table.
+
+#### Step 4: End to End verification
+
+Now we perform some end-to-end testing
+- From Management to LAN1/LAN2
+
+```none
+vyos@Management:~$ ping 10.0.0.1 source-address 192.168.0.1
+PING 10.0.0.1 (10.0.0.1) from 192.168.0.1 : 56(84) bytes of data.
+64 bytes from 10.0.0.1: icmp_seq=1 ttl=63 time=1.93 ms
+64 bytes from 10.0.0.1: icmp_seq=2 ttl=63 time=2.12 ms
+64 bytes from 10.0.0.1: icmp_seq=3 ttl=63 time=2.12 ms
+^C
+--- 10.0.0.1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2005ms
+rtt min/avg/max/mdev = 1.931/2.056/2.123/0.088 ms
+vyos@Management:~$ ping 172.16.0.1 source-address 192.168.0.1
+PING 172.16.0.1 (172.16.0.1) from 192.168.0.1 : 56(84) bytes of data.
+64 bytes from 172.16.0.1: icmp_seq=1 ttl=63 time=1.62 ms
+64 bytes from 172.16.0.1: icmp_seq=2 ttl=63 time=1.75 ms
+^C
+--- 172.16.0.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1001ms
+rtt min/avg/max/mdev = 1.621/1.686/1.752/0.065 ms
+vyos@Management:~$ ping 2001:db8:0:1::1 source-address 2001:db8:0:3::1
+PING 2001:db8:0:1::1(2001:db8:0:1::1) from 2001:db8:0:3::1 : 56 data bytes
+64 bytes from 2001:db8:0:1::1: icmp_seq=1 ttl=63 time=2.44 ms
+64 bytes from 2001:db8:0:1::1: icmp_seq=2 ttl=63 time=2.40 ms
+64 bytes from 2001:db8:0:1::1: icmp_seq=3 ttl=63 time=2.41 ms
+^C
+--- 2001:db8:0:1::1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2003ms
+rtt min/avg/max/mdev = 2.399/2.418/2.442/0.017 ms
+vyos@Management:~$ ping 2001:db8:0:2::1 source-address 2001:db8:0:3::1
+PING 2001:db8:0:2::1(2001:db8:0:2::1) from 2001:db8:0:3::1 : 56 data bytes
+64 bytes from 2001:db8:0:2::1: icmp_seq=1 ttl=63 time=1.66 ms
+64 bytes from 2001:db8:0:2::1: icmp_seq=2 ttl=63 time=1.99 ms
+64 bytes from 2001:db8:0:2::1: icmp_seq=3 ttl=63 time=1.88 ms
+64 bytes from 2001:db8:0:2::1: icmp_seq=4 ttl=63 time=2.32 ms
+^C
+--- 2001:db8:0:2::1 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3005ms
+rtt min/avg/max/mdev = 1.660/1.960/2.315/0.236 ms
+```
+
+- From Management to Outside (fails as intended)
+
+```none
+vyos@Management:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+S>* 0.0.0.0/0 [1/0] via 192.168.3.1, eth2, weight 1, 00:01:58
+C>* 192.168.0.0/24 is directly connected, dum0, 00:02:05
+C>* 192.168.3.0/30 is directly connected, eth2, 00:02:03
+vyos@Management:~$ ping 192.0.2.1
+PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
+From 192.168.3.1 icmp_seq=1 Destination Net Unreachable
+From 192.168.3.1 icmp_seq=2 Destination Net Unreachable
+^C
+--- 192.0.2.1 ping statistics ---
+2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1002ms
+
+vyos@Management:~$ ping 195.51.100.1
+PING 195.51.100.1 (195.51.100.1) 56(84) bytes of data.
+From 192.168.3.1 icmp_seq=1 Destination Net Unreachable
+From 192.168.3.1 icmp_seq=2 Destination Net Unreachable
+From 192.168.3.1 icmp_seq=3 Destination Net Unreachable
+^C
+--- 195.51.100.1 ping statistics ---
+3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2003ms
+
+vyos@Management:~$ ping 2001:db8:1::1
+PING 2001:db8:1::1(2001:db8:1::1) 56 data bytes
+From 2001:db8::4 icmp_seq=1 Destination unreachable: No route
+From 2001:db8::4 icmp_seq=2 Destination unreachable: No route
+^C
+--- 2001:db8:1::1 ping statistics ---
+2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1002ms
+
+vyos@Management:~$ ping 2001:db8:2::1
+PING 2001:db8:2::1(2001:db8:2::1) 56 data bytes
+From 2001:db8::4 icmp_seq=1 Destination unreachable: No route
+From 2001:db8::4 icmp_seq=2 Destination unreachable: No route
+^C
+--- 2001:db8:2::1 ping statistics ---
+2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1002ms
+```
+
+- LAN1 to Outside
+
+```none
+vyos@LAN1:~$ ping 192.0.2.1 source-address 10.0.0.1
+PING 192.0.2.1 (192.0.2.1) from 10.0.0.1 : 56(84) bytes of data.
+64 bytes from 192.0.2.1: icmp_seq=1 ttl=63 time=1.47 ms
+64 bytes from 192.0.2.1: icmp_seq=2 ttl=63 time=1.41 ms
+64 bytes from 192.0.2.1: icmp_seq=3 ttl=63 time=1.80 ms
+^C
+--- 192.0.2.1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 1.414/1.563/1.803/0.171 ms
+vyos@LAN1:~$ ping 198.51.100.1 source-address 10.0.0.1
+PING 198.51.100.1 (198.51.100.1) from 10.0.0.1 : 56(84) bytes of data.
+64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=1.71 ms
+64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=1.83 ms
+^C
+--- 198.51.100.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 1.705/1.766/1.828/0.061 ms
+vyos@LAN1:~$ ping 203.0.113.1 source-address 10.0.0.1
+PING 203.0.113.1 (203.0.113.1) from 10.0.0.1 : 56(84) bytes of data.
+64 bytes from 203.0.113.1: icmp_seq=1 ttl=63 time=1.25 ms
+64 bytes from 203.0.113.1: icmp_seq=2 ttl=63 time=1.88 ms
+^C
+--- 203.0.113.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1003ms
+rtt min/avg/max/mdev = 1.249/1.566/1.884/0.317 ms
+vyos@LAN1:~$ ping 2001:db8:1::1 source-address 2001:db8:0:1::1
+PING 2001:db8:1::1(2001:db8:1::1) from 2001:db8:0:1::1 : 56 data bytes
+64 bytes from 2001:db8:1::1: icmp_seq=1 ttl=63 time=2.35 ms
+64 bytes from 2001:db8:1::1: icmp_seq=2 ttl=63 time=2.29 ms
+64 bytes from 2001:db8:1::1: icmp_seq=3 ttl=63 time=2.22 ms
+^C
+--- 2001:db8:1::1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 2.215/2.285/2.352/0.055 ms
+vyos@LAN1:~$ ping 2001:db8:2::1 source-address 2001:db8:0:1::1
+PING 2001:db8:2::1(2001:db8:2::1) from 2001:db8:0:1::1 : 56 data bytes
+64 bytes from 2001:db8:2::1: icmp_seq=1 ttl=63 time=1.37 ms
+64 bytes from 2001:db8:2::1: icmp_seq=2 ttl=63 time=2.68 ms
+64 bytes from 2001:db8:2::1: icmp_seq=3 ttl=63 time=2.00 ms
+^C
+--- 2001:db8:2::1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2003ms
+rtt min/avg/max/mdev = 1.367/2.015/2.679/0.535 ms
+```
+
+:::{note}
+we are using "source-address" option cause we are not redistributing
+connected interfaces into BGP on the Core router hence there is no comeback
+route and ping will fail.
+:::
+
+- LAN1 to LAN2
+
+```none
+vyos@LAN1:~$ ping 172.16.0.1 source-address 10.0.0.1
+PING 172.16.0.1 (172.16.0.1) from 10.0.0.1 : 56(84) bytes of data.
+64 bytes from 172.16.0.1: icmp_seq=1 ttl=63 time=3.00 ms
+64 bytes from 172.16.0.1: icmp_seq=2 ttl=63 time=2.20 ms
+^C
+--- 172.16.0.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 2.199/2.600/3.001/0.401 ms
+vyos@LAN1:~$ ping 2001:db8:0:2::1 source 2001:db8:0:1::1
+PING 2001:db8:0:2::1(2001:db8:0:2::1) from 2001:db8:0:1::1 : 56 data bytes
+64 bytes from 2001:db8:0:2::1: icmp_seq=1 ttl=63 time=4.82 ms
+64 bytes from 2001:db8:0:2::1: icmp_seq=2 ttl=63 time=1.95 ms
+64 bytes from 2001:db8:0:2::1: icmp_seq=3 ttl=63 time=1.98 ms
+^C
+--- 2001:db8:0:2::1 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2003ms
+rtt min/avg/max/mdev = 1.949/2.915/4.815/1.343 ms
+```
+
+
+## Conclusions
+
+Inter-VRF routing is a well-known solution to address complex routing scenarios
+that enable -in a dynamic way- to leak routes between VRFs. Is recommended to
+take special consideration while designing route-targets and its application as
+it can minimize future interventions while creating a new VRF will automatically
+take the desired effect in its propagation.
+
+## Appendix-A
+
+### Full configuration from all devices
+
+- Core
+
+```none
+set interfaces ethernet eth0 address '10.1.1.1/30'
+set interfaces ethernet eth0 address '2001:db8::/127'
+set interfaces ethernet eth0 vrf 'LAN1'
+set interfaces ethernet eth1 address '172.16.2.1/30'
+set interfaces ethernet eth1 address '2001:db8::2/127'
+set interfaces ethernet eth1 vrf 'LAN2'
+set interfaces ethernet eth2 address '192.168.3.1/30'
+set interfaces ethernet eth2 address '2001:db8::4/127'
+set interfaces ethernet eth2 vrf 'Management'
+set interfaces ethernet eth3 address '10.2.2.1/30'
+set interfaces ethernet eth3 address '2001:db8::6/127'
+set interfaces ethernet eth3 vrf 'Internet'
+set protocols bgp address-family ipv4-unicast
+set protocols bgp system-as '64496'
+set vrf name Internet protocols bgp address-family ipv4-unicast export vpn
+set vrf name Internet protocols bgp address-family ipv4-unicast import vpn
+set vrf name Internet protocols bgp address-family ipv4-unicast rd vpn export '64496:100'
+set vrf name Internet protocols bgp address-family ipv4-unicast route-target vpn export '64496:100'
+set vrf name Internet protocols bgp address-family ipv4-unicast route-target vpn import '64496:1 64496:2'
+set vrf name Internet protocols bgp address-family ipv6-unicast export vpn
+set vrf name Internet protocols bgp address-family ipv6-unicast import vpn
+set vrf name Internet protocols bgp address-family ipv6-unicast rd vpn export '64496:100'
+set vrf name Internet protocols bgp address-family ipv6-unicast route-target vpn export '64496:100'
+set vrf name Internet protocols bgp address-family ipv6-unicast route-target vpn import '64496:1 64496:2'
+set vrf name Internet protocols bgp neighbor 10.2.2.2 address-family ipv4-unicast
+set vrf name Internet protocols bgp neighbor 10.2.2.2 remote-as '64497'
+set vrf name Internet protocols bgp neighbor 2001:db8::7 address-family ipv6-unicast
+set vrf name Internet protocols bgp neighbor 2001:db8::7 remote-as '64497'
+set vrf name Internet table '104'
+set vrf name LAN1 protocols bgp address-family ipv4-unicast export vpn
+set vrf name LAN1 protocols bgp address-family ipv4-unicast import vpn
+set vrf name LAN1 protocols bgp address-family ipv4-unicast rd vpn export '64496:1'
+set vrf name LAN1 protocols bgp address-family ipv4-unicast redistribute static
+set vrf name LAN1 protocols bgp address-family ipv4-unicast route-target vpn export '64496:1'
+set vrf name LAN1 protocols bgp address-family ipv4-unicast route-target vpn import '64496:100 64496:50 64496:2'
+set vrf name LAN1 protocols bgp address-family ipv6-unicast export vpn
+set vrf name LAN1 protocols bgp address-family ipv6-unicast import vpn
+set vrf name LAN1 protocols bgp address-family ipv6-unicast rd vpn export '64496:1'
+set vrf name LAN1 protocols bgp address-family ipv6-unicast redistribute static
+set vrf name LAN1 protocols bgp address-family ipv6-unicast route-target vpn export '64496:1'
+set vrf name LAN1 protocols bgp address-family ipv6-unicast route-target vpn import '64496:100 64496:50 64496:2'
+set vrf name LAN1 protocols static route 10.0.0.0/24 next-hop 10.1.1.2
+set vrf name LAN1 protocols static route6 2001:db8:0:1::/64 next-hop 2001:db8::1
+set vrf name LAN1 table '101'
+set vrf name LAN2 protocols bgp address-family ipv4-unicast export vpn
+set vrf name LAN2 protocols bgp address-family ipv4-unicast import vpn
+set vrf name LAN2 protocols bgp address-family ipv4-unicast rd vpn export '64496:2'
+set vrf name LAN2 protocols bgp address-family ipv4-unicast redistribute static
+set vrf name LAN2 protocols bgp address-family ipv4-unicast route-target vpn export '64496:2'
+set vrf name LAN2 protocols bgp address-family ipv4-unicast route-target vpn import '64496:100 64496:50 64496:1'
+set vrf name LAN2 protocols bgp address-family ipv6-unicast export vpn
+set vrf name LAN2 protocols bgp address-family ipv6-unicast import vpn
+set vrf name LAN2 protocols bgp address-family ipv6-unicast rd vpn export '64496:2'
+set vrf name LAN2 protocols bgp address-family ipv6-unicast redistribute static
+set vrf name LAN2 protocols bgp address-family ipv6-unicast route-target vpn export '64496:2'
+set vrf name LAN2 protocols bgp address-family ipv6-unicast route-target vpn import '64496:100 64496:50 64496:1'
+set vrf name LAN2 protocols static route 172.16.0.0/24 next-hop 172.16.2.2
+set vrf name LAN2 protocols static route6 2001:db8:0:2::/64 next-hop 2001:db8::3
+set vrf name LAN2 table '102'
+set vrf name Management protocols bgp address-family ipv4-unicast export vpn
+set vrf name Management protocols bgp address-family ipv4-unicast import vpn
+set vrf name Management protocols bgp address-family ipv4-unicast rd vpn export '64496:50'
+set vrf name Management protocols bgp address-family ipv4-unicast redistribute static
+set vrf name Management protocols bgp address-family ipv4-unicast route-target vpn export '64496:50'
+set vrf name Management protocols bgp address-family ipv4-unicast route-target vpn import '64496:1 64496:2'
+set vrf name Management protocols bgp address-family ipv6-unicast export vpn
+set vrf name Management protocols bgp address-family ipv6-unicast import vpn
+set vrf name Management protocols bgp address-family ipv6-unicast rd vpn export '64496:50'
+set vrf name Management protocols bgp address-family ipv6-unicast redistribute static
+set vrf name Management protocols bgp address-family ipv6-unicast route-target vpn export '64496:50'
+set vrf name Management protocols bgp address-family ipv6-unicast route-target vpn import '64496:1 64496:2'
+set vrf name Management protocols static route 192.168.0.0/24 next-hop 192.168.3.2
+set vrf name Management protocols static route6 2001:db8:0:3::/64 next-hop 2001:db8::5
+set vrf name Management table '103'
+```
+
+- LAN1
+
+```none
+set interfaces dummy dum0 address '10.0.0.1/24'
+set interfaces dummy dum0 address '2001:db8:0:1::1/64'
+set interfaces ethernet eth0 address '10.1.1.2/30'
+set interfaces ethernet eth0 address '2001:db8::1/127'
+set protocols static route 0.0.0.0/0 next-hop 10.1.1.1
+set protocols static route6 ::/0 next-hop 2001:db8::*
+```
+
+- LAN2
+
+```none
+set interfaces dummy dum0 address '172.16.0.1/24'
+set interfaces dummy dum0 address '2001:db8:0:2::1/64'
+set interfaces ethernet eth0 hw-id '50:00:00:03:00:00'
+set interfaces ethernet eth1 address '172.16.2.2/30'
+set interfaces ethernet eth1 address '2001:db8::3/127'
+set protocols static route 0.0.0.0/0 next-hop 172.16.2.1
+set protocols static route6 ::/0 next-hop 2001:db8::2
+```
+
+- Management
+
+```none
+set interfaces dummy dum0 address '192.168.0.1/24'
+set interfaces dummy dum0 address '2001:db8:0:3::1/64'
+set interfaces ethernet eth2 address '192.168.3.2/30'
+set interfaces ethernet eth2 address '2001:db8::5/127'
+set protocols static route 0.0.0.0/0 next-hop 192.168.3.1
+set protocols static route6 ::/0 next-hop 2001:db8::4
+```
+
+- ISP
+
+```none
+set interfaces dummy dum0 address '192.0.2.1/24'
+set interfaces dummy dum0 address '2001:db8:1::1/48'
+set interfaces dummy dum1 address '198.51.100.1/24'
+set interfaces dummy dum1 address '2001:db8:2::1/48'
+set interfaces dummy dum2 address '203.0.113.1/24'
+set interfaces dummy dum2 address '2001:db8:3::1/48'
+set interfaces ethernet eth3 address '10.2.2.2/30'
+set interfaces ethernet eth3 address '2001:db8::7/127'
+set protocols bgp address-family ipv4-unicast redistribute connected
+set protocols bgp address-family ipv6-unicast redistribute connected
+set protocols bgp system-as '64497'
+set protocols bgp neighbor 10.2.2.1 address-family ipv4-unicast default-originate
+set protocols bgp neighbor 10.2.2.1 remote-as '64496'
+set protocols bgp neighbor 2001:db8::6 address-family ipv6-unicast default-originate
+set protocols bgp neighbor 2001:db8::6 remote-as '64496'
+set protocols static route 0.0.0.0/0 next-hop 10.2.2.1
+set protocols static route6 ::/0 next-hop 2001:db8::6
+```
+
+
+## Appendix-B
+
+### Route-Filtering
+
+When importing routes using MP-BGP it is possible to filter a subset of them
+before are injected in the BGP table. One of the most common case is to use a
+route-map with an prefix-list.
+- Configuration
+
+We create a prefix-list first and add all the routes we need to.
+
+```none
+# set both ipv4 and ipv6 policies
+
+set policy prefix-list LAN2-Internet rule 1 action 'permit'
+set policy prefix-list LAN2-Internet rule 1 le '24'
+set policy prefix-list LAN2-Internet rule 1 prefix '198.51.0.0/16'
+set policy prefix-list LAN2-Internet rule 2 action 'permit'
+set policy prefix-list LAN2-Internet rule 2 prefix '192.0.2.0/24'
+set policy prefix-list LAN2-Internet rule 3 action 'permit'
+set policy prefix-list LAN2-Internet rule 3 prefix '192.168.0.0/24'
+set policy prefix-list LAN2-Internet rule 4 action 'permit'
+set policy prefix-list LAN2-Internet rule 4 prefix '10.0.0.0/24'
+
+set policy prefix-list6 LAN2-Internet-v6 rule 1 action 'permit'
+set policy prefix-list6 LAN2-Internet-v6 rule 1 prefix '2001:db8:1::/48'
+set policy prefix-list6 LAN2-Internet-v6 rule 2 action 'permit'
+set policy prefix-list6 LAN2-Internet-v6 rule 2 prefix '2001:db8:2::/48'
+set policy prefix-list6 LAN2-Internet-v6 rule 3 action 'permit'
+set policy prefix-list6 LAN2-Internet-v6 rule 3 prefix '2001:db8:0:3::/64'
+set policy prefix-list6 LAN2-Internet-v6 rule 4 action 'permit'
+set policy prefix-list6 LAN2-Internet-v6 rule 4 prefix '2001:db8:0:1::/64'
+```
+
+Then add a route-map and reference to above prefix. Consider that the actions
+taken inside the prefix will MATCH the routes that will be affected by the
+actions inside the rules of the route-map.
+
+```none
+set policy route-map LAN2-Internet rule 1 action 'permit'
+set policy route-map LAN2-Internet rule 1 match ip address prefix-list 'LAN2-Internet'
+
+set policy route-map LAN2-Internet-v6 rule 1 action 'permit'
+set policy route-map LAN2-Internet-v6 rule 1 match ipv6 address prefix-list 'LAN2-Internet-v6'
+```
+
+We are using a "white list" approach by allowing only what is necessary. In case
+that need to implement a "black list" approach then you will need to change the
+action in the route-map for a deny BUT you need to add a rule that permits the
+rest due to the implicit deny in the route-map.
+
+Then we need to attach the policy to the BGP process. This needs to be under
+the import statement in the vrf we need to filter.
+
+```none
+set vrf name LAN2 protocols bgp address-family ipv4-unicast route-map vpn import 'LAN2-Internet'
+set vrf name LAN2 protocols bgp address-family ipv6-unicast route-map vpn import 'LAN2-Internet-v6'
+```
+
+- Verification
+
+```none
+# show ip route vrf LAN2
+
+B>* 10.0.0.0/24 [20/0] via 10.1.1.2, eth0 (vrf LAN1), weight 1, 00:45:28
+S>* 172.16.0.0/24 [1/0] via 172.16.2.2, eth1, weight 1, 00:45:32
+C>* 172.16.2.0/30 is directly connected, eth1, 00:45:39
+B>* 192.0.2.0/24 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:45:24
+B>* 192.168.0.0/24 [20/0] via 192.168.3.2, eth2 (vrf Managment), weight 1, 00:45:27
+B>* 198.51.100.0/24 [20/0] via 10.2.2.2, eth3 (vrf Internet), weight 1, 00:45:24
+
+# show ipv6 route vrf LAN2
+
+C>* 2001:db8::2/127 is directly connected, eth1, 00:46:26
+B>* 2001:db8:0:1::/64 [20/0] via 2001:db8::1, eth0 (vrf LAN1), weight 1, 00:46:17
+S>* 2001:db8:0:2::/64 [1/0] via 2001:db8::3, eth1, weight 1, 00:46:21
+B>* 2001:db8:0:3::/64 [20/0] via 2001:db8::5, eth2 (vrf Managment), weight 1, 00:46:16
+B>* 2001:db8:1::/48 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:46:13
+B>* 2001:db8:2::/48 [20/0] via fe80::5200:ff:fe02:3, eth3 (vrf Internet), weight 1, 00:46:13
+C>* fe80::/64 is directly connected, eth1, 00:46:27
+```
+
+As we can see even if both VRF LAN1 and LAN2 has the same import RTs we are able
+to select which routes are effectively imported and installed.
diff --git a/docs/configexamples/ipsec-cisco-policy-based.md b/docs/configexamples/ipsec-cisco-policy-based.md
new file mode 100644
index 00000000..7a31601d
--- /dev/null
+++ b/docs/configexamples/ipsec-cisco-policy-based.md
@@ -0,0 +1,363 @@
+---
+lastproofread: '2025-06-26'
+---
+
+(examples-ipsec-cisco-policy-based)=
+
+# Policy-based Site-to-Site VPN IPsec between VyOS and Cisco
+
+This document is to describe a basic setup using policy-based
+site-to-site VPN IPsec. In this example we use VyOS 1.5 and
+Cisco IOS. Cisco initiates IPsec connection only if interesting
+traffic present. For stable work we recommend configuring an
+initiator role on VyOS side.
+
+## Network Topology
+
+```{image} /_static/images/cisco-vpn-ipsec.webp
+:align: center
+:alt: Network Topology Diagram
+```
+
+
+## Prerequirements
+
+**VyOS:**
+
+```{eval-rst}
++---------+----------------+
+| WAN IP | 10.0.1.2/30 |
++---------+----------------+
+| LAN1 IP | 192.168.0.1/24 |
++---------+----------------+
+| LAN2 IP | 192.168.1.1/24 |
++---------+----------------+
+```
+
+**Cisco:**
+
+```{eval-rst}
++---------+-----------------+
+| WAN IP | 10.0.2.2/30 |
++---------+-----------------+
+| LAN1 IP | 192.168.10.1/24 |
++---------+-----------------+
+| LAN2 IP | 192.168.11.1/24 |
++---------+-----------------+
+```
+
+**IKE parameters:**
+
+```{eval-rst}
++-------------------+---------+
+| Encryption | AES-256 |
++-------------------+---------+
+| HASH | SHA-1 |
++-------------------+---------+
+| Diff-Helman Group | 14 |
++-------------------+---------+
+| Life-Time | 28800 |
++-------------------+---------+
+| IKE Version | 2 |
++-------------------+---------+
+```
+
+**IPsec parameters:**
+
+```{eval-rst}
++------------+---------+
+| Encryption | AES-256 |
++------------+---------+
+| HASH | SHA-256 |
++------------+---------+
+| Life-Time | 3600 |
++------------+---------+
+| PFS | disable |
++------------+---------+
+```
+
+```{eval-rst}
+**Traffic Selectors**
+ 192.168.0.0/24 <==> 192.168.10.0/24
+
+ 192.168.1.0/24 <==> 192.168.11.0/24
+```
+
+**Hosts configuration**
+
+```{eval-rst}
++--------+--------------+
+| PC1 IP | 192.168.0.2 |
++--------+--------------+
+| PC2 IP | 192.168.1.2 |
++--------+--------------+
+| PC3 IP | 192.168.10.2 |
++--------+--------------+
+| PC4 IP | 192.168.11.2 |
++--------+--------------+
+```
+
+## Configuration
+
+:::{note}
+Pfs is disabled in Cisco by default.
+:::
+
+### VyOS
+
+```none
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set interfaces ethernet eth1 address '192.168.0.1/24'
+set interfaces ethernet eth2 address '192.168.1.1/24'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'dGVzdA=='
+set vpn ipsec authentication psk AUTH-PSK secret-type 'base64'
+set vpn ipsec esp-group ESP-GROUP lifetime '3600'
+set vpn ipsec esp-group ESP-GROUP pfs 'disable'
+set vpn ipsec esp-group ESP-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GROUP proposal 10 hash 'sha256'
+set vpn ipsec ike-group IKE-GROUP close-action 'start'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '10'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec site-to-site peer CISCO authentication local-id '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer CISCO authentication remote-id '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO connection-type 'initiate'
+set vpn ipsec site-to-site peer CISCO default-esp-group 'ESP-GROUP'
+set vpn ipsec site-to-site peer CISCO ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer CISCO local-address '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO remote-address '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO tunnel 1 local prefix '192.168.0.0/24'
+set vpn ipsec site-to-site peer CISCO tunnel 1 remote prefix '192.168.10.0/24'
+set vpn ipsec site-to-site peer CISCO tunnel 2 local prefix '192.168.1.0/24'
+set vpn ipsec site-to-site peer CISCO tunnel 2 remote prefix '192.168.11.0/24'
+```
+
+
+### Cisco
+
+```none
+crypto ikev2 proposal aes-cbc-256-proposal
+ encryption aes-cbc-256
+ integrity sha1
+ group 14
+!
+crypto ikev2 policy policy1
+ match address local 10.0.2.2
+ proposal aes-cbc-256-proposal
+!
+crypto ikev2 keyring keys
+ peer VyOS
+ address 10.0.1.2
+ pre-shared-key local test
+ pre-shared-key remote test
+!
+crypto ikev2 profile IKEv2-profile
+ match identity remote address 10.0.1.2 255.255.255.255
+ authentication remote pre-share
+ authentication local pre-share
+ keyring local keys
+ lifetime 28800
+!
+crypto ipsec transform-set TS esp-aes 256 esp-sha256-hmac
+ mode tunnel
+!
+crypto map IPSEC-map 10 ipsec-isakmp
+ set peer 10.0.1.2
+ set security-association lifetime seconds 3600
+ set transform-set TS
+ set ikev2-profile IKEv2-profile
+ match address cryptoacl
+!
+interface GigabitEthernet0/0
+ ip address 10.0.2.2 255.255.255.252
+ crypto map IPSEC-map
+!
+interface GigabitEthernet0/1
+ ip address 192.168.10.1 255.255.255.0
+!
+interface GigabitEthernet0/2
+ ip address 192.168.11.1 255.255.255.0
+!
+ip route 0.0.0.0 0.0.0.0 10.0.2.1
+!
+ip access-list extended cryptoacl
+ permit ip 192.168.10.0 0.0.0.255 192.168.0.0 0.0.0.255
+ permit ip 192.168.11.0 0.0.0.255 192.168.1.0 0.0.0.255
+```
+
+
+## Monitoring
+
+### Monitoring on VyOS side
+
+IKE SAs:
+
+```none
+vyos@vyos:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+10.0.2.2 10.0.2.2 10.0.1.2 10.0.1.2
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv2 AES_CBC_256 HMAC_SHA1_96 MODP_2048 no 304 26528
+```
+
+IPsec SAs:
+
+```none
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------- ------- -------- -------------- ---------------- ---------------- ----------- -----------------------------
+CISCO-tunnel-1 up 6m6s 0B/0B 0/0 10.0.2.2 10.0.2.2 AES_CBC_256/HMAC_SHA2_256_128
+CISCO-tunnel-2 up 6m6s 0B/0B 0/0 10.0.2.2 10.0.2.2 AES_CBC_256/HMAC_SHA2_256_128
+```
+
+
+### Monitoring on Cisco side
+
+IKE SAs:
+
+```none
+Cisco#show crypto ikev2 sa
+ IPv4 Crypto IKEv2 SA
+
+Tunnel-id Local Remote fvrf/ivrf Status
+1 10.0.2.2/4500 10.0.1.2/4500 none/none READY
+ Encr: AES-CBC, keysize: 256, PRF: SHA1, Hash: SHA96, DH Grp:14, Auth sign: PSK, Auth verify: PSK
+ Life/Active Time: 28800/471 sec
+
+ IPv6 Crypto IKEv2 SA
+```
+
+IPsec SAs:
+
+```none
+ Cisco#show crypto ipsec sa
+
+interface: GigabitEthernet0/0
+ Crypto map tag: IPSEC-map, local addr 10.0.2.2
+
+ protected vrf: (none)
+ local ident (addr/mask/prot/port): (192.168.11.0/255.255.255.0/0/0)
+ remote ident (addr/mask/prot/port): (192.168.1.0/255.255.255.0/0/0)
+ current_peer 10.0.1.2 port 4500
+ PERMIT, flags={origin_is_acl,}
+ #pkts encaps: 0, #pkts encrypt: 0, #pkts digest: 0
+ #pkts decaps: 0, #pkts decrypt: 0, #pkts verify: 0
+ #pkts compressed: 0, #pkts decompressed: 0
+ #pkts not compressed: 0, #pkts compr. failed: 0
+ #pkts not decompressed: 0, #pkts decompress failed: 0
+ #send errors 0, #recv errors 0
+
+ local crypto endpt.: 10.0.2.2, remote crypto endpt.: 10.0.1.2
+ plaintext mtu 1438, path mtu 1500, ip mtu 1500, ip mtu idb GigabitEthernet0/0
+ current outbound spi: 0xC81F83DA(3357508570)
+ PFS (Y/N): N, DH group: none
+
+ inbound esp sas:
+ spi: 0x8C63C51E(2355348766)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 23, flow_id: SW:23, sibling_flags 80000040, crypto map: IPSEC-map
+ sa timing: remaining key lifetime (k/sec): (4231729/3585)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ inbound ah sas:
+
+ inbound pcp sas:
+
+ outbound esp sas:
+ spi: 0xC81F83DA(3357508570)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 24, flow_id: SW:24, sibling_flags 80000040, crypto map: IPSEC-map
+ sa timing: remaining key lifetime (k/sec): (4231729/3585)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ outbound ah sas:
+
+ outbound pcp sas:
+
+ protected vrf: (none)
+ local ident (addr/mask/prot/port): (192.168.10.0/255.255.255.0/0/0)
+ remote ident (addr/mask/prot/port): (192.168.0.0/255.255.255.0/0/0)
+ current_peer 10.0.1.2 port 4500
+ PERMIT, flags={origin_is_acl,}
+ #pkts encaps: 0, #pkts encrypt: 0, #pkts digest: 0
+ #pkts decaps: 0, #pkts decrypt: 0, #pkts verify: 0
+ #pkts compressed: 0, #pkts decompressed: 0
+ #pkts not compressed: 0, #pkts compr. failed: 0
+ #pkts not decompressed: 0, #pkts decompress failed: 0
+ #send errors 0, #recv errors 0
+
+ local crypto endpt.: 10.0.2.2, remote crypto endpt.: 10.0.1.2
+ plaintext mtu 1438, path mtu 1500, ip mtu 1500, ip mtu idb GigabitEthernet0/0
+ current outbound spi: 0xC40C7A20(3289152032)
+ PFS (Y/N): N, DH group: none
+
+ inbound esp sas:
+ spi: 0x2948B6CB(692631243)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 21, flow_id: SW:21, sibling_flags 80000040, crypto map: IPSEC-map
+ sa timing: remaining key lifetime (k/sec): (4194891/3581)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ inbound ah sas:
+
+ inbound pcp sas:
+
+ outbound esp sas:
+ spi: 0xC40C7A20(3289152032)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 22, flow_id: SW:22, sibling_flags 80000040, crypto map: IPSEC-map
+ sa timing: remaining key lifetime (k/sec): (4194891/3581)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ outbound ah sas:
+
+ outbound pcp sas:
+```
+
+
+### Checking Connectivity
+
+ICMP packets from PC1 to PC3.
+
+```none
+PC1> ping 192.168.10.2
+
+84 bytes from 192.168.10.2 icmp_seq=1 ttl=62 time=8.479 ms
+84 bytes from 192.168.10.2 icmp_seq=2 ttl=62 time=3.344 ms
+84 bytes from 192.168.10.2 icmp_seq=3 ttl=62 time=3.139 ms
+84 bytes from 192.168.10.2 icmp_seq=4 ttl=62 time=3.176 ms
+84 bytes from 192.168.10.2 icmp_seq=5 ttl=62 time=3.978 ms
+```
+
+ICMP packets from PC2 to PC4.
+
+```none
+PC2> ping 192.168.11.2
+
+84 bytes from 192.168.11.2 icmp_seq=1 ttl=62 time=9.687 ms
+84 bytes from 192.168.11.2 icmp_seq=2 ttl=62 time=3.286 ms
+84 bytes from 192.168.11.2 icmp_seq=3 ttl=62 time=2.972 ms
+```
diff --git a/docs/configexamples/ipsec-cisco-route-based.md b/docs/configexamples/ipsec-cisco-route-based.md
new file mode 100644
index 00000000..40a3985b
--- /dev/null
+++ b/docs/configexamples/ipsec-cisco-route-based.md
@@ -0,0 +1,406 @@
+---
+lastproofread: '2025-06-26'
+---
+
+(examples-ipsec-cisco-route-based)=
+
+# Route-based Site-to-Site VPN IPsec between VyOS and Cisco
+
+This document is to describe a basic setup using route-based
+site-to-site VPN IPsec. In this example we use VyOS 1.5 and
+Cisco IOS. Cisco initiates IPsec connection only if interesting
+traffic present. For stable work we recommend configuring an
+initiator role on VyOS side. OSPF is selected as routing protocol
+inside the tunnel.
+
+## Network Topology
+
+```{eval-rst}
+.. image:: /_static/images/cisco-vpn-ipsec.webp
+ :align: center
+ :alt: Network Topology Diagram
+```
+
+
+## Prerequirements
+
+**VyOS:**
+
+```{eval-rst}
++---------+----------------+
+| WAN IP | 10.0.1.2/30 |
++---------+----------------+
+| LAN1 IP | 192.168.0.1/24 |
++---------+----------------+
+| LAN2 IP | 192.168.1.1/24 |
++---------+----------------+
+```
+
+**Cisco:**
+
+```{eval-rst}
++---------+-----------------+
+| WAN IP | 10.0.2.2/30 |
++---------+-----------------+
+| LAN1 IP | 192.168.10.1/24 |
++---------+-----------------+
+| LAN2 IP | 192.168.11.1/24 |
++---------+-----------------+
+```
+
+**IKE parameters:**
+
+```{eval-rst}
++-------------------+---------+
+| Encryption | AES-128 |
++-------------------+---------+
+| HASH | SHA-1 |
++-------------------+---------+
+| Diff-Helman Group | 14 |
++-------------------+---------+
+| Life-Time | 28800 |
++-------------------+---------+
+| IKE Version | 1 |
++-------------------+---------+
+```
+
+**IPsec parameters:**
+
+```{eval-rst}
++------------+---------+
+| Encryption | AES-256 |
++------------+---------+
+| HASH | SHA-256 |
++------------+---------+
+| Life-Time | 3600 |
++------------+---------+
+| PFS | disable |
++------------+---------+
+```
+
+**Hosts configuration**
+
+```{eval-rst}
++--------+--------------+
+| PC1 IP | 192.168.0.2 |
++--------+--------------+
+| PC2 IP | 192.168.1.2 |
++--------+--------------+
+| PC3 IP | 192.168.10.2 |
++--------+--------------+
+| PC4 IP | 192.168.11.2 |
++--------+--------------+
+```
+
+## Configuration
+
+:::{note}
+Pfs is disabled in Cisco by default.
+:::
+
+### VyOS
+
+```none
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set interfaces ethernet eth1 address '192.168.0.1/24'
+set interfaces ethernet eth2 address '192.168.1.1/24'
+set interfaces vti vti1 address '10.100.100.1/30'
+set interfaces vti vti1 mtu '1438'
+set protocols ospf area 0 network '10.100.100.0/30'
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '192.168.1.0/24'
+set protocols ospf interface eth1 passive
+set protocols ospf interface eth2 passive
+set protocols ospf interface vti1 network 'point-to-point'
+set protocols ospf parameters router-id '2.2.2.2'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'dGVzdA=='
+set vpn ipsec authentication psk AUTH-PSK secret-type 'base64'
+set vpn ipsec esp-group ESP-GROUP lifetime '3600'
+set vpn ipsec esp-group ESP-GROUP pfs 'disable'
+set vpn ipsec esp-group ESP-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GROUP proposal 10 hash 'sha256'
+set vpn ipsec ike-group IKE-GROUP close-action 'start'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '10'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection timeout '30'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes128'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec options disable-route-autoinstall
+set vpn ipsec site-to-site peer CISCO authentication local-id '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer CISCO authentication remote-id '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO connection-type 'initiate'
+set vpn ipsec site-to-site peer CISCO default-esp-group 'ESP-GROUP'
+set vpn ipsec site-to-site peer CISCO ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer CISCO local-address '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO remote-address '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO vti bind 'vti1'
+```
+
+
+### Cisco
+
+```none
+crypto isakmp policy 10
+ encr aes
+ authentication pre-share
+ group 14
+ lifetime 28800
+crypto isakmp key test address 10.0.1.2
+!
+!
+crypto ipsec transform-set TS esp-aes 256 esp-sha256-hmac
+ mode transport
+!
+crypto ipsec profile IPsec-profile
+ set transform-set TS
+!
+!
+!
+!
+!
+!
+!
+interface Loopback0
+ ip address 1.1.1.1 255.255.255.255
+!
+interface Tunnel10
+ ip address 10.100.100.2 255.255.255.252
+ ip ospf network point-to-point
+ tunnel source GigabitEthernet0/0
+ tunnel mode ipsec ipv4
+ tunnel destination 10.0.1.2
+ tunnel protection ipsec profile IPsec-profile
+!
+interface GigabitEthernet0/0
+ ip address 10.0.2.2 255.255.255.252
+ duplex auto
+ speed auto
+ media-type rj45
+!
+interface GigabitEthernet0/1
+ ip address 192.168.10.1 255.255.255.0
+ duplex auto
+ speed auto
+ media-type rj45
+!
+interface GigabitEthernet0/2
+ ip address 192.168.11.1 255.255.255.0
+ duplex auto
+ speed auto
+ media-type rj45
+!
+router ospf 1
+ router-id 1.1.1.1
+ passive-interface GigabitEthernet0/1
+ passive-interface GigabitEthernet0/2
+ network 10.100.100.0 0.0.0.3 area 0
+ network 192.168.10.0 0.0.0.255 area 0
+ network 192.168.11.0 0.0.0.255 area 0
+!
+ip route 0.0.0.0 0.0.0.0 10.0.2.1
+```
+
+
+## Monitoring
+
+### Monitoring on VyOS side
+
+IKE SAs:
+
+```none
+vyos@vyos:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+10.0.2.2 10.0.2.2 10.0.1.2 10.0.1.2
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv1 AES_CBC_128 HMAC_SHA1_96 MODP_2048 no 8175 18439
+```
+
+IPsec SAs:
+
+```none
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------ ------- -------- -------------- ---------------- ---------------- ----------- -----------------------------
+CISCO-vti up 34m59s 17K/14K 224/213 10.0.2.2 10.0.2.2 AES_CBC_256/HMAC_SHA2_256_128
+```
+
+OSPF Neighbor Status:
+
+```none
+vyos@vyos:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
+1.1.1.1 1 Full/- 1h29m37s 39.317s 10.100.100.2 vti1:10.100.100.1 0 0 0
+```
+
+Routing Table:
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+S>* 0.0.0.0/0 [1/0] via 10.0.1.1, eth0, weight 1, 00:07:54
+C>* 10.0.1.0/30 is directly connected, eth0, weight 1, 00:07:59
+L>* 10.0.1.2/32 is directly connected, eth0, weight 1, 00:07:59
+O 10.100.100.0/30 [110/1] is directly connected, vti1, weight 1, 00:07:50
+C>* 10.100.100.0/30 is directly connected, vti1, weight 1, 00:07:50
+L>* 10.100.100.1/32 is directly connected, vti1, weight 1, 00:07:50
+O 192.168.0.0/24 [110/1] is directly connected, eth1, weight 1, 00:07:54
+C>* 192.168.0.0/24 is directly connected, eth1, weight 1, 00:07:59
+L>* 192.168.0.1/32 is directly connected, eth1, weight 1, 00:07:59
+O 192.168.1.0/24 [110/1] is directly connected, eth2, weight 1, 00:07:54
+C>* 192.168.1.0/24 is directly connected, eth2, weight 1, 00:07:59
+L>* 192.168.1.1/32 is directly connected, eth2, weight 1, 00:07:59
+O>* 192.168.10.0/24 [110/2] via 10.100.100.2, vti1, weight 1, 00:07:34
+O>* 192.168.11.0/24 [110/2] via 10.100.100.2, vti1, weight 1, 00:07:34
+```
+
+
+### Monitoring on Cisco side
+
+IKE SAs:
+
+```none
+Cisco#show crypto isakmp sa
+IPv4 Crypto ISAKMP SA
+dst src state conn-id status
+10.0.1.2 10.0.2.2 QM_IDLE 1002 ACTIVE
+
+IPv6 Crypto ISAKMP SA
+```
+
+IPsec SAs:
+
+```none
+Cisco#show crypto ipsec sa
+
+interface: Tunnel10
+ Crypto map tag: Tunnel10-head-0, local addr 10.0.2.2
+
+ protected vrf: (none)
+ local ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
+ remote ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
+ current_peer 10.0.1.2 port 500
+ PERMIT, flags={origin_is_acl,}
+ #pkts encaps: 1295, #pkts encrypt: 1295, #pkts digest: 1295
+ #pkts decaps: 1238, #pkts decrypt: 1238, #pkts verify: 1238
+ #pkts compressed: 0, #pkts decompressed: 0
+ #pkts not compressed: 0, #pkts compr. failed: 0
+ #pkts not decompressed: 0, #pkts decompress failed: 0
+ #send errors 0, #recv errors 0
+
+ local crypto endpt.: 10.0.2.2, remote crypto endpt.: 10.0.1.2
+ plaintext mtu 1438, path mtu 1500, ip mtu 1500, ip mtu idb GigabitEthernet0/0
+ current outbound spi: 0xC3E9B307(3286872839)
+ PFS (Y/N): N, DH group: none
+
+ inbound esp sas:
+ spi: 0x2740C328(658555688)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 7, flow_id: SW:7, sibling_flags 80000040, crypto map: Tunnel10-head-0
+ sa timing: remaining key lifetime (k/sec): (4173824/1401)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ inbound ah sas:
+
+ inbound pcp sas:
+
+ outbound esp sas:
+ spi: 0xC3E9B307(3286872839)
+ transform: esp-256-aes esp-sha256-hmac ,
+ in use settings ={Tunnel, }
+ conn id: 8, flow_id: SW:8, sibling_flags 80000040, crypto map: Tunnel10-head-0
+ sa timing: remaining key lifetime (k/sec): (4173819/1401)
+ IV size: 16 bytes
+ replay detection support: Y
+ Status: ACTIVE(ACTIVE)
+
+ outbound ah sas:
+
+ outbound pcp sas:
+```
+
+OSPF Neighbor Status:
+
+```none
+Cisco# show ip ospf neighbor
+
+Neighbor ID Pri State Dead Time Address Interface
+2.2.2.2 0 FULL/ - 00:00:35 10.100.100.1 Tunnel10
+```
+
+Routing Table:
+
+```none
+Cisco#show ip route
+Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
+ D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
+ N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
+ E1 - OSPF external type 1, E2 - OSPF external type 2
+ i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
+ ia - IS-IS inter area, * - candidate default, U - per-user static route
+ o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
+ a - application route
+ + - replicated route, % - next hop override, p - overrides from PfR
+
+Gateway of last resort is 10.0.2.1 to network 0.0.0.0
+
+S* 0.0.0.0/0 [1/0] via 10.0.2.1
+ 1.0.0.0/32 is subnetted, 1 subnets
+C 1.1.1.1 is directly connected, Loopback0
+ 10.0.0.0/8 is variably subnetted, 4 subnets, 2 masks
+C 10.0.2.0/30 is directly connected, GigabitEthernet0/0
+L 10.0.2.2/32 is directly connected, GigabitEthernet0/0
+C 10.100.100.0/30 is directly connected, Tunnel10
+L 10.100.100.2/32 is directly connected, Tunnel10
+O 192.168.0.0/24 [110/1001] via 10.100.100.1, 00:09:36, Tunnel10
+O 192.168.1.0/24 [110/1001] via 10.100.100.1, 00:09:36, Tunnel10
+ 192.168.10.0/24 is variably subnetted, 2 subnets, 2 masks
+C 192.168.10.0/24 is directly connected, GigabitEthernet0/1
+L 192.168.10.1/32 is directly connected, GigabitEthernet0/1
+ 192.168.11.0/24 is variably subnetted, 2 subnets, 2 masks
+C 192.168.11.0/24 is directly connected, GigabitEthernet0/2
+L 192.168.11.1/32 is directly connected, GigabitEthernet0/2
+```
+
+
+### Checking Connectivity
+
+ICMP packets from PC1 to PC3.
+
+```none
+PC1> ping 192.168.10.2
+
+84 bytes from 192.168.10.2 icmp_seq=1 ttl=62 time=8.479 ms
+84 bytes from 192.168.10.2 icmp_seq=2 ttl=62 time=3.344 ms
+84 bytes from 192.168.10.2 icmp_seq=3 ttl=62 time=3.139 ms
+84 bytes from 192.168.10.2 icmp_seq=4 ttl=62 time=3.176 ms
+84 bytes from 192.168.10.2 icmp_seq=5 ttl=62 time=3.978 ms
+```
+
+ICMP packets from PC2 to PC4.
+
+```none
+PC2> ping 192.168.11.2
+
+84 bytes from 192.168.11.2 icmp_seq=1 ttl=62 time=9.687 ms
+84 bytes from 192.168.11.2 icmp_seq=2 ttl=62 time=3.286 ms
+84 bytes from 192.168.11.2 icmp_seq=3 ttl=62 time=2.972 ms
+```
diff --git a/docs/configexamples/ipsec-pa-route-based.md b/docs/configexamples/ipsec-pa-route-based.md
new file mode 100644
index 00000000..628f2f48
--- /dev/null
+++ b/docs/configexamples/ipsec-pa-route-based.md
@@ -0,0 +1,412 @@
+---
+lastproofread: '2025-06-26'
+---
+
+(examples-ipsec-pa-route-based)=
+
+# Route-based Site-to-Site VPN IPsec between VyOS and Palo Alto
+
+This document is to describe a basic setup using route-based
+site-to-site VPN IPsec. In this example we use VyOS 1.5 and
+PA 11.0.0. OSPF is selected as routing protocol inside the
+tunnel.
+
+Since this example focuses on IPsec configuration it does not
+include firewall configuration.
+
+## Network Topology
+
+```{image} /_static/images/ipsec-vyos-pa.webp
+:align: center
+:alt: Network Topology Diagram
+```
+
+
+## Prerequirements
+
+**VyOS:**
+
+```{eval-rst}
++---------+----------------+
+| WAN IP | 10.0.1.2/30 |
++---------+----------------+
+| LAN1 IP | 192.168.0.1/24 |
++---------+----------------+
+| LAN2 IP | 192.168.1.1/24 |
++---------+----------------+
+```
+
+**Cisco:**
+
+```{eval-rst}
++---------+-----------------+
+| WAN IP | 10.0.2.2/30 |
++---------+-----------------+
+| LAN1 IP | 192.168.10.1/24 |
++---------+-----------------+
+| LAN2 IP | 192.168.11.1/24 |
++---------+-----------------+
+```
+
+**IKE parameters:**
+
+```{eval-rst}
++-------------------+---------+
+| Encryption | AES-128 |
++-------------------+---------+
+| HASH | SHA-1 |
++-------------------+---------+
+| Diff-Helman Group | 14 |
++-------------------+---------+
+| Life-Time | 28800 |
++-------------------+---------+
+| IKE Version | 1 |
++-------------------+---------+
+```
+
+**IPsec parameters:**
+
+```{eval-rst}
++------------+---------+
+| Encryption | AES-256 |
++------------+---------+
+| HASH | SHA-256 |
++------------+---------+
+| Life-Time | 3600 |
++------------+---------+
+| PFS | disable |
++------------+---------+
+```
+
+**Hosts configuration**
+
+```{eval-rst}
++--------+--------------+
+| PC1 IP | 192.168.0.2 |
++--------+--------------+
+| PC2 IP | 192.168.1.2 |
++--------+--------------+
+| PC3 IP | 192.168.10.2 |
++--------+--------------+
+| PC4 IP | 192.168.11.2 |
++--------+--------------+
+```
+
+## Configuration
+
+### VyOS
+
+```none
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set interfaces ethernet eth1 address '192.168.0.1/24'
+set interfaces ethernet eth2 address '192.168.1.1/24'
+set interfaces vti vti1 address '10.100.100.1/30'
+set interfaces vti vti1 mtu '1438'
+set protocols ospf area 0 network '10.100.100.0/30'
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '192.168.1.0/24'
+set protocols ospf interface eth1 passive
+set protocols ospf interface eth2 passive
+set protocols ospf interface vti1 network 'point-to-point'
+set protocols ospf parameters router-id '2.2.2.2'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'dGVzdA=='
+set vpn ipsec authentication psk AUTH-PSK secret-type 'base64'
+set vpn ipsec esp-group ESP-GROUP lifetime '3600'
+set vpn ipsec esp-group ESP-GROUP pfs 'disable'
+set vpn ipsec esp-group ESP-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GROUP proposal 10 hash 'sha256'
+set vpn ipsec ike-group IKE-GROUP close-action 'start'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '10'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection timeout '30'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes128'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec options disable-route-autoinstall
+set vpn ipsec site-to-site peer CISCO authentication local-id '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer CISCO authentication remote-id '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO connection-type 'initiate'
+set vpn ipsec site-to-site peer CISCO default-esp-group 'ESP-GROUP'
+set vpn ipsec site-to-site peer CISCO ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer CISCO local-address '10.0.1.2'
+set vpn ipsec site-to-site peer CISCO remote-address '10.0.2.2'
+set vpn ipsec site-to-site peer CISCO vti bind 'vti1'
+```
+
+
+### Palo Alto
+
+```{eval-rst}
+GUI Configuration:
+ Network -> Network Profiles -> IKE Crypto
+
+ .. image:: /_static/images/PA-IKE-group.webp
+ :align: center
+
+ Network -> Network Profiles -> IKE Gateways
+
+ .. image:: /_static/images/PA-IKE-GW-1.webp
+ :align: center
+
+ .. image:: /_static/images/PA-IKE-GW-2.webp
+ :align: center
+
+ Network -> Network Profiles -> IPSec Crypto
+
+ .. image:: /_static/images/PA-ESP-group.webp
+ :align: center
+
+ Network -> Interfaces
+
+ .. image:: /_static/images/PA-tunnel-1.webp
+ :align: center
+
+ .. image:: /_static/images/PA-tunnel-2.webp
+ :align: center
+
+ .. image:: /_static/images/PA-tunnel-3.webp
+ :align: center
+
+ Network -> IPSec Tunnels
+
+ .. image:: /_static/images/PA-IPsec-tunnel.webp
+ :align: center
+```
+CLI configuration with OSPF:
+```none
+set network interface ethernet ethernet1/1 layer3 ip 10.0.2.2/30
+set network interface ethernet ethernet1/1 layer3 interface-management-profile Allow
+set network interface ethernet ethernet1/2 layer3 ip 192.168.10.1/24
+set network interface ethernet ethernet1/1 layer3 interface-management-profile Allow
+set network interface ethernet ethernet1/3 layer3 ip 192.168.11.1/24
+set network interface ethernet ethernet1/1 layer3 interface-management-profile Allow
+set network interface tunnel units tunnel.1 ip 10.100.100.2/30
+set network interface tunnel units tunnel.1 interface-management-profile Allow
+set network interface tunnel units tunnel.1 mtu 1438
+set network profiles interface-management-profile Allow ping yes
+set network ike crypto-profiles ike-crypto-profiles IKE-GROUP hash sha1
+set network ike crypto-profiles ike-crypto-profiles IKE-GROUP dh-group group14
+set network ike crypto-profiles ike-crypto-profiles IKE-GROUP encryption aes-128-cbc
+set network ike crypto-profiles ike-crypto-profiles IKE-GROUP lifetime seconds 28800
+set network ike crypto-profiles ipsec-crypto-profiles ESP-GROUP esp authentication sha256
+set network ike crypto-profiles ipsec-crypto-profiles ESP-GROUP esp encryption aes-256-cbc
+set network ike crypto-profiles ipsec-crypto-profiles ESP-GROUP lifetime seconds 3600
+set network ike crypto-profiles ipsec-crypto-profiles ESP-GROUP dh-group no-pfs
+set network ike gateway VyOS authentication pre-shared-key key test
+set network ike gateway VyOS protocol ikev1 dpd enable yes
+set network ike gateway VyOS protocol ikev1 exchange-mode main
+set network ike gateway VyOS protocol ikev1 ike-crypto-profile IKE-GROUP
+set network ike gateway VyOS protocol ikev2 dpd enable yes
+set network ike gateway VyOS protocol version ikev1
+set network ike gateway VyOS protocol-common nat-traversal enable yes
+set network ike gateway VyOS protocol-common fragmentation enable no
+set network ike gateway VyOS protocol-common passive-mode yes
+set network ike gateway VyOS local-address interface ethernet1/1
+set network ike gateway VyOS peer-address ip 10.0.1.2
+set network ike gateway VyOS local-id id 10.0.2.2
+set network ike gateway VyOS local-id type ipaddr
+set network ike gateway VyOS peer-id id 10.0.1.2
+set network ike gateway VyOS peer-id type ipaddr
+set network tunnel ipsec VyOS-tunnel auto-key ike-gateway VyOS
+set network tunnel ipsec VyOS-tunnel auto-key ipsec-crypto-profile ESP-GROUP
+set network tunnel ipsec VyOS-tunnel tunnel-monitor enable no
+set network tunnel ipsec VyOS-tunnel tunnel-interface tunnel.1
+set network tunnel ipsec VyOS-tunnel anti-replay no
+set network virtual-router default protocol ospf enable yes
+set network virtual-router default protocol ospf area 0.0.0.0 type normal
+set network virtual-router default protocol ospf area 0.0.0.0 interface tunnel.1 enable yes
+set network virtual-router default protocol ospf area 0.0.0.0 interface tunnel.1 passive no
+set network virtual-router default protocol ospf area 0.0.0.0 interface tunnel.1 link-type p2p
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/2 enable yes
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/2 passive yes
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/2 link-type broadcast
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/3 enable yes
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/3 passive yes
+set network virtual-router default protocol ospf area 0.0.0.0 interface ethernet1/3 link-type broadcast
+set network virtual-router default protocol ospf router-id 1.1.1.1
+set network virtual-router default interface [ ethernet1/1 ethernet1/2 ethernet1/3 tunnel.1 ]
+```
+
+## Monitoring
+### Monitoring on VyOS side
+
+IKE SAs:
+
+```none
+vyos@vyos:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+10.0.2.2 10.0.2.2 10.0.1.2 10.0.1.2
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv1 AES_CBC_128 HMAC_SHA1_96 MODP_2048 no 1372 25802
+```
+
+IPsec SAs:
+
+```none
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------ ------- -------- -------------- ---------------- ---------------- ----------- -----------------------------
+PA-vti up 23m27s 9K/10K 149/151 10.0.2.2 10.0.2.2 AES_CBC_256/HMAC_SHA2_256_128
+```
+
+OSPF Neighbor Status:
+
+```none
+vyos@vyos:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
+1.1.1.1 1 Full/- 23m56s 37.948s 10.100.100.2 vti1:10.100.100.1 0 0 0
+```
+
+Routing Table:
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+S>* 0.0.0.0/0 [1/0] via 10.0.1.1, eth0, weight 1, 00:27:30
+C>* 10.0.1.0/30 is directly connected, eth0, weight 1, 00:27:34
+L>* 10.0.1.2/32 is directly connected, eth0, weight 1, 00:27:34
+O 10.100.100.0/30 [110/1] is directly connected, vti1, weight 1, 00:24:34
+C>* 10.100.100.0/30 is directly connected, vti1, weight 1, 00:24:34
+L>* 10.100.100.1/32 is directly connected, vti1, weight 1, 00:24:34
+O 192.168.0.0/24 [110/1] is directly connected, eth1, weight 1, 00:27:29
+C>* 192.168.0.0/24 is directly connected, eth1, weight 1, 00:27:34
+L>* 192.168.0.1/32 is directly connected, eth1, weight 1, 00:27:34
+O 192.168.1.0/24 [110/1] is directly connected, eth2, weight 1, 00:27:29
+C>* 192.168.1.0/24 is directly connected, eth2, weight 1, 00:27:34
+L>* 192.168.1.1/32 is directly connected, eth2, weight 1, 00:27:34
+O>* 192.168.10.0/24 [110/11] via 10.100.100.2, vti1, weight 1, 00:24:19
+O>* 192.168.11.0/24 [110/11] via 10.100.100.2, vti1, weight 1, 00:24:19
+```
+
+### Monitoring on Cisco side
+
+IKE SAs:
+
+```none
+admin@PA-VM> show vpn ike-sa
+
+IKEv1 phase-1 SAs
+GwID/client IP Peer-Address Gateway Name Role Mode Algorithm Established Expiration V ST Xt Phase2
+-------------- ------------ ------------ ---- ---- --------- ----------- ---------- - -- -- ------
+1 10.0.1.2 VyOS Resp Main PSK/DH14/A128/SHA1 Jul.31 01:35:00 Jul.31 09:35:00 v1 13 1 1
+
+Show IKEv1 IKE SA: Total 1 gateways found. 1 ike sa found.
+
+
+IKEv1 phase-2 SAs
+Gateway Name TnID Tunnel GwID/IP Role Algorithm SPI(in) SPI(out) MsgID ST Xt
+------------ ---- ------ ------- ---- --------- ------- -------- ----- -- --
+VyOS 1 VyOS-tunnel 1 Resp ESP/ /tunl/SHA2 8827A3D9 C204F4FA BD202829 9 1
+
+Show IKEv1 phase2 SA: Total 1 gateways found. 1 ike sa found.
+
+
+There is no IKEv2 SA found.
+```
+
+IPsec SAs:
+
+```none
+admin@PA-VM> show vpn ipsec-sa
+
+GwID/client IP TnID Peer-Address Tunnel(Gateway) Algorithm SPI(in) SPI(out) life(Sec/KB) remain-time(Sec)
+-------------- ---- ------------ --------------- --------- ------- -------- ------------ ----------------
+1 1 10.0.1.2 VyOS-tunnel(VyOS) ESP/A256/SHA256 8827A3D9 C204F4FA 3600/Unlimited 2733
+
+Show IPSec SA: Total 1 tunnels found. 1 ipsec sa found.
+```
+
+OSPF Neighbor Status:
+
+```none
+admin@PA-VM> show routing protocol ospf neighbor
+
+ Options: 0x80:reserved, O:Opaq-LSA capability, DC:demand circuits, EA:Ext-Attr LSA capability,
+ N/P:NSSA option, MC:multicase, E:AS external LSA capability, T:TOS capability
+ ==========
+ virtual router: default
+ neighbor address: 10.100.100.1
+ local address binding: 0.0.0.0
+ type: dynamic
+ status: full
+ neighbor router ID: 2.2.2.2
+ area id: 0.0.0.0
+ neighbor priority: 1
+ lifetime remain: 32
+ messages pending: 0
+ LSA request pending: 0
+ options: 0x02: E
+ hello suppressed: no
+ restart helper status: not helping
+ restart helper time remaining: 0
+ restart helper exit reason: none
+```
+
+Routing Table:
+
+```none
+admin@PA-VM> show routing route
+
+flags: A:active, ?:loose, C:connect, H:host, S:static, ~:internal, R:rip, O:ospf, B:bgp,
+ Oi:ospf intra-area, Oo:ospf inter-area, O1:ospf ext-type-1, O2:ospf ext-type-2, E:ecmp, M:multicast
+
+
+VIRTUAL ROUTER: default (id 1)
+ ==========
+destination nexthop metric flags age interface next-AS
+0.0.0.0/0 10.0.2.1 10 A S ethernet1/1
+10.0.2.0/30 10.0.2.2 0 A C ethernet1/1
+10.0.2.2/32 0.0.0.0 0 A H
+10.100.100.0/30 0.0.0.0 10 Oi 1273 tunnel.1
+10.100.100.0/30 10.100.100.2 0 A C tunnel.1
+10.100.100.2/32 0.0.0.0 0 A H
+192.168.0.0/24 10.100.100.1 11 A Oi 1253 tunnel.1
+192.168.1.0/24 10.100.100.1 11 A Oi 1253 tunnel.1
+192.168.10.0/24 0.0.0.0 10 Oi 1273 ethernet1/2
+192.168.10.0/24 192.168.10.1 0 A C ethernet1/2
+192.168.10.1/32 0.0.0.0 0 A H
+192.168.11.0/24 0.0.0.0 10 Oi 1273 ethernet1/3
+192.168.11.0/24 192.168.11.1 0 A C ethernet1/3
+192.168.11.1/32 0.0.0.0 0 A H
+total routes shown: 14
+```
+
+### Checking Connectivity
+
+ICMP packets from PC1 to PC3.
+
+```none
+PC1> ping 192.168.10.2
+
+84 bytes from 192.168.10.2 icmp_seq=1 ttl=62 time=8.479 ms
+84 bytes from 192.168.10.2 icmp_seq=2 ttl=62 time=3.344 ms
+84 bytes from 192.168.10.2 icmp_seq=3 ttl=62 time=3.139 ms
+84 bytes from 192.168.10.2 icmp_seq=4 ttl=62 time=3.176 ms
+84 bytes from 192.168.10.2 icmp_seq=5 ttl=62 time=3.978 ms
+```
+
+ICMP packets from PC2 to PC4.
+
+```none
+PC2> ping 192.168.11.2
+
+84 bytes from 192.168.11.2 icmp_seq=1 ttl=62 time=9.687 ms
+84 bytes from 192.168.11.2 icmp_seq=2 ttl=62 time=3.286 ms
+84 bytes from 192.168.11.2 icmp_seq=3 ttl=62 time=2.972 ms
+```
diff --git a/docs/configexamples/l3vpn-hub-and-spoke.md b/docs/configexamples/l3vpn-hub-and-spoke.md
new file mode 100644
index 00000000..858edeea
--- /dev/null
+++ b/docs/configexamples/l3vpn-hub-and-spoke.md
@@ -0,0 +1,1091 @@
+# L3VPN for Hub-and-Spoke connectivity with VyOS
+
+IP/MPLS technology is widely used by various service providers and large
+enterprises in order to achieve better network scalability, manageability
+and flexibility. It also provides the possibility to deliver different
+services for the customers in a seamless manner.
+Layer 3 VPN (L3VPN) is a type of VPN mode that is built and delivered
+through OSI layer 3 networking technologies. Often the border gateway
+protocol (BGP) is used to send and receive VPN-related data that is
+responsible for the control plane. L3VPN utilizes virtual routing and
+forwarding (VRF) techniques to receive and deliver user data as well as
+separate data planes of the end-users. It is built using a combination of
+IP- and MPLS-based information. Generally, L3VPNs are used to send data
+on back-end VPN infrastructures, such as for VPN connections between data
+centres, HQs and branches.
+
+An L3VPN consists of multiple access links, multiple VPN routing and
+forwarding (VRF) tables, and multiple MPLS paths or multiple P2MP LSPs.
+An L3VPN can be configured to connect two or more customer sites.
+In hub-and-spoke MPLS L3VPN environments, the spoke routers need to have
+unique Route Distinguishers (RDs). In order to use the hub site as a
+transit point for connectivity in such an environment, the spoke sites
+export their routes to the hub. Spokes can talk to hubs, but never have
+direct paths to other spokes. All traffic between spokes is controlled
+and delivered over the hub site.
+
+To deploy a Layer3 VPN with MPLS on VyOS, we should meet a couple
+requirements in order to properly implement the solution.
+We'll use the following nodes in our LAB environment:
+
+- 2 x Route reflectors (VyOS-RRx)
+- 4 x Provider routers (VyOS-Px)
+- 3 x Provider Edge (VyOs-PEx)
+- 3 x Customer Edge (VyOS-CEx)
+
+The following software was used in the creation of this document:
+
+- Operating system: VyOS
+- Version: 1.4-rolling-202110310317
+- Image name: vyos-1.4-rolling-202110310317-amd64.iso
+
+**NOTE:** VyOS Router (tested with VyOS 1.4-rolling-202110310317)
+– The configurations below are specifically for VyOS 1.4.x.
+
+General information can be found in the
+{ref}`configuration/vrf/index:L3VPN VRFs` chapter.
+
+## Topology
+
+```{image} /_static/images/L3VPN_hub_and_spoke.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+
+## How does it work?
+
+As we know the main assumption of L3VPN “Hub and Spoke” is, that the
+traffic between spokes have to pass via hub, in our scenario VyOS-PE2
+is the Hub PE
+and the VyOS-CE1-HUB is the central customer office device that is responsible
+for controlling access between all spokes and announcing its network prefixes
+(10.0.0.100/32). VyOS-PE2 has the main VRF (its name is BLUE_HUB), its
+own Route-Distinguisher(RD) and route-target import/export lists.
+Multiprotocol-BGP(MP-BGP) delivers L3VPN related control-plane information to
+the nodes across network where PEs Spokes import the route-target 60535:1030
+(this is export route-target of vrf BLUE_HUB) and export its own route-target
+60535:1011(this is vrf BLUE_SPOKE export route-target). Therefore, the
+Customer edge nodes can only learn the network prefixes of the HUB site
+[10.0.0.100/32]. For this example VyOS-CE1 has network prefixes
+[10.0.0.80/32] / VyOS-CE2 has network prefixes [10.0.0.90/32].
+Route-Reflector devices VyOS-RR1 and VyOS-RR2 are used to simplify network
+routes exchange and minimize iBGP peerings between devices.
+
+L3VPN configuration parameters table:
+
+```{eval-rst}
++----------+-------+------------+-----------------+-------------+-------------+
+| Node | Role | VRF | RD | RT import | RT export |
++----------+-------+------------+-----------------+-------------+-------------+
+| VyOS-PE2 | Hub | BLUE_HUB | 10.80.80.1:1011 | 65035:1011 | 65035:1030 |
+| | | | | 65035:1030 | |
++----------+-------+------------+-----------------+-------------+-------------+
+| VyOS-PE1 | Spoke | BLUE_SPOKE | 10.50.50.1:1011 | 65035:1030 | 65035:1011 |
++----------+-------+------------+-----------------+-------------+-------------+
+| VyOS-PE3 | Spoke | BLUE_SPOKE | 10.60.60.1:1011 | 65035:1030 | 65035:1011 |
++----------+-------+------------+-----------------+-------------+-------------+
+```
+
+## Configuration
+
+### Step-1: Configuring IGP and enabling MPLS LDP
+
+At the first step we need to configure the IP/MPLS backbone network using OSPF
+as IGP protocol and LDP as label-switching protocol for the base connectivity
+between **P** (rovider), **P** (rovider) **E** (dge) and **R** (oute) **R**
+(eflector) nodes:
+- VyOS-P1:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.3/32'
+set interfaces ethernet eth0 address '172.16.30.1/24'
+set interfaces ethernet eth1 address '172.16.40.1/24'
+set interfaces ethernet eth2 address '172.16.90.1/24'
+set interfaces ethernet eth3 address '172.16.10.1/24'
+set interfaces ethernet eth5 address '172.16.100.1/24'
+
+# protocols ospf+ldp
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth2'
+set protocols mpls interface 'eth3'
+set protocols mpls interface 'eth5'
+set protocols mpls interface 'eth0'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.3'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth2'
+set protocols mpls ldp interface 'eth3'
+set protocols mpls ldp interface 'eth5'
+set protocols mpls ldp router-id '10.0.0.3'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.3
+```
+
+- VyOS-P2:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.4/32'
+set interfaces ethernet eth0 address '172.16.30.2/24'
+set interfaces ethernet eth1 address '172.16.20.1/24'
+set interfaces ethernet eth2 address '172.16.120.1/24'
+set interfaces ethernet eth3 address '172.16.60.1/24'
+
+# protocols ospf+ldp
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth2'
+set protocols mpls interface 'eth3'
+set protocols mpls interface 'eth0'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.4'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth2'
+set protocols mpls ldp interface 'eth3'
+set protocols mpls ldp router-id '10.0.0.4'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.4'
+```
+
+- VyOS-P3:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.5/32'
+set interfaces ethernet eth0 address '172.16.110.1/24'
+set interfaces ethernet eth1 address '172.16.40.2/24'
+set interfaces ethernet eth2 address '172.16.50.1/24'
+set interfaces ethernet eth3 address '172.16.70.1/24'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth2'
+set protocols mpls interface 'eth3'
+set protocols mpls interface 'eth0'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.5'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth2'
+set protocols mpls ldp interface 'eth3'
+set protocols mpls ldp router-id '10.0.0.5'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.5'
+```
+
+- VyOS-P4:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.6/32'
+set interfaces ethernet eth0 address '172.16.80.2/24'
+set interfaces ethernet eth1 address '172.16.130.1/24'
+set interfaces ethernet eth2 address '172.16.50.2/24'
+set interfaces ethernet eth3 address '172.16.60.2/24'
+set interfaces ethernet eth5 address '172.16.140.1/24'
+
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth2'
+set protocols mpls interface 'eth3'
+set protocols mpls interface 'eth0'
+set protocols mpls interface 'eth5'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.6'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth2'
+set protocols mpls ldp interface 'eth3'
+set protocols mpls ldp interface 'eth5'
+set protocols mpls ldp router-id '10.0.0.6'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.6'
+```
+
+- VyOS-PE1:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.7/32'
+set interfaces ethernet eth0 address '172.16.90.2/24'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth0'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.7'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp router-id '10.0.0.7'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.7'
+```
+
+- VyOS-PE2:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.8/32'
+set interfaces ethernet eth0 address '172.16.110.2/24'
+set interfaces ethernet eth1 address '172.16.100.2/24'
+set interfaces ethernet eth2 address '172.16.80.1/24'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth0'
+set protocols mpls interface 'eth1'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.8'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp router-id '10.0.0.8'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.8'
+```
+
+- VyOS-PE3:
+
+```none
+# interfaces
+set interfaces dummy dum10 address '10.0.0.10/32'
+set interfaces ethernet eth0 address '172.16.140.2/24'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth0'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.10'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp router-id '10.0.0.10'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.10'
+```
+
+- VyOS-RR1:
+
+```none
+# interfaces
+set interfaces ethernet eth1 address '172.16.20.2/24'
+set interfaces ethernet eth2 address '172.16.10.2/24'
+set interfaces dummy dum10 address '10.0.0.1/32'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth2'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.1'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth2'
+set protocols mpls ldp router-id '10.0.0.1'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.1'
+```
+
+- VyOS-RR2:
+
+```none
+# interfaces
+set interfaces ethernet eth0 address '172.16.80.1/24'
+set interfaces ethernet eth1 address '172.16.70.2/24'
+set interfaces dummy dum10 address '10.0.0.2/32'
+
+# protocols ospf + ldp
+set protocols mpls interface 'eth0'
+set protocols mpls interface 'eth1'
+set protocols mpls ldp discovery transport-ipv4-address '10.0.0.2'
+set protocols mpls ldp interface 'eth1'
+set protocols mpls ldp interface 'eth0'
+set protocols mpls ldp router-id '10.0.0.2'
+set protocols ospf area 0 network '0.0.0.0/0'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters router-id '10.0.0.2'
+```
+
+
+### Step-2: Configuring iBGP for L3VPN control-plane
+
+At this step we are going to enable iBGP protocol on MPLS nodes and
+Route Reflectors (two routers for redundancy) that will deliver IPv4
+VPN (L3VPN) routes between them:
+- VyOS-RR1:
+
+```none
+set protocols bgp system-as '65001'
+set protocols bgp neighbor 10.0.0.7 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.7 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.8 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.8 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.10 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.10 peer-group 'RR_VPNv4'
+set protocols bgp parameters cluster-id '10.0.0.1'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.0.0.1'
+set protocols bgp peer-group RR_VPNv4 remote-as '65001'
+set protocols bgp peer-group RR_VPNv4 update-source 'dum10'
+```
+
+- VyOS-RR2:
+
+```none
+set protocols bgp system-as '65001'
+set protocols bgp neighbor 10.0.0.7 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.7 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.8 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.8 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.10 address-family ipv4-vpn route-reflector-client
+set protocols bgp neighbor 10.0.0.10 peer-group 'RR_VPNv4'
+set protocols bgp parameters cluster-id '10.0.0.1'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.0.0.2'
+set protocols bgp peer-group RR_VPNv4 remote-as '65001'
+set protocols bgp peer-group RR_VPNv4 update-source 'dum10'
+```
+
+- VyOS-PE1:
+
+```none
+set protocols bgp system-as '65001'
+set protocols bgp neighbor 10.0.0.1 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.1 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.2 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.2 peer-group 'RR_VPNv4'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.0.0.7'
+set protocols bgp peer-group RR_VPNv4 remote-as '65001'
+set protocols bgp peer-group RR_VPNv4 update-source 'dum10'
+```
+
+- VyOS-PE2:
+
+```none
+set protocols bgp system-as '65001'
+set protocols bgp neighbor 10.0.0.1 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.1 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.2 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.2 peer-group 'RR_VPNv4'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.0.0.8'
+set protocols bgp peer-group RR_VPNv4 remote-as '65001'
+set protocols bgp peer-group RR_VPNv4 update-source 'dum10'
+```
+
+- VyOS-PE3:
+
+```none
+set protocols bgp system-as '65001'
+set protocols bgp neighbor 10.0.0.1 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.1 peer-group 'RR_VPNv4'
+set protocols bgp neighbor 10.0.0.2 address-family ipv4-vpn nexthop-self
+set protocols bgp neighbor 10.0.0.2 peer-group 'RR_VPNv4'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.0.0.10'
+set protocols bgp peer-group RR_VPNv4 remote-as '65001'
+set protocols bgp peer-group RR_VPNv4 update-source 'dum10'
+```
+
+
+### Step-3: Configuring L3VPN VRFs on PE nodes
+
+This section provides configuration steps for setting up VRFs on our
+PE nodes including CE facing interfaces, BGP, rd and route-target
+import/export based on the pre-defined parameters.
+- VyOS-PE1:
+
+```none
+# VRF settings
+set vrf name BLUE_SPOKE table '200'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast export vpn
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast import vpn
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast label vpn export 'auto'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast network 10.50.50.0/24
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast rd vpn export '10.50.50.1:1011'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast redistribute connected
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast route-target vpn export '65035:1011'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast route-target vpn import '65035:1030'
+set vrf name BLUE_SPOKE protocols bgp neighbor 10.50.50.2 address-family ipv4-unicast as-override
+set vrf name BLUE_SPOKE protocols bgp neighbor 10.50.50.2 remote-as '65035'
+
+# interfaces
+set interfaces ethernet eth3 address '10.50.50.1/24'
+set interfaces ethernet eth3 vrf 'BLUE_SPOKE'
+```
+
+- VyOS-PE2:
+
+```none
+# VRF settings
+set vrf name BLUE_HUB table '400'
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast export vpn
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast import vpn
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast label vpn export 'auto'
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast network 10.80.80.0/24
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast rd vpn export '10.80.80.1:1011'
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast redistribute connected
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast route-target vpn export '65035:1030'
+set vrf name BLUE_HUB protocols bgp address-family ipv4-unicast route-target vpn import '65035:1011 65050:2011 65035:1030'
+set vrf name BLUE_HUB protocols bgp neighbor 10.80.80.2 address-family ipv4-unicast as-override
+set vrf name BLUE_HUB protocols bgp neighbor 10.80.80.2 remote-as '65035'
+
+# interfaces
+set interfaces ethernet eth3 address '10.80.80.1/24'
+set interfaces ethernet eth3 vrf 'BLUE_HUB'
+```
+
+- VyOS-PE3:
+
+```none
+# VRF settings
+set vrf name BLUE_SPOKE table '200'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast export vpn
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast import vpn
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast label vpn export 'auto'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast network 10.60.60.0/24
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast rd vpn export '10.60.60.1:1011'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast redistribute connected
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast route-target vpn export '65035:1011'
+set vrf name BLUE_SPOKE protocols bgp address-family ipv4-unicast route-target vpn import '65035:1030'
+set vrf name BLUE_SPOKE protocols bgp neighbor 10.60.60.2 address-family ipv4-unicast as-override
+set vrf name BLUE_SPOKE protocols bgp neighbor 10.60.60.2 remote-as '65035'
+
+# interfaces
+set interfaces ethernet eth3 address '10.60.60.1/24'
+set interfaces ethernet eth3 vrf 'BLUE_SPOKE'
+```
+
+
+### Step-4: Configuring CE nodes
+
+Dynamic routing used between CE and PE nodes and eBGP peering
+established for the route exchanging between them. All routes
+received by PEs are then exported to L3VPN and delivered from
+Spoke sites to Hub and vise-versa based on previously
+configured L3VPN parameters.
+- VyOS-CE1-SPOKE:
+
+```none
+# interfaces
+set interfaces dummy dum20 address '10.0.0.80/32'
+set interfaces ethernet eth0 address '10.50.50.2/24'
+
+# BGP for peering with PE
+set protocols bgp system-as 65035
+set protocols bgp address-family ipv4-unicast network 10.0.0.80/32
+set protocols bgp neighbor 10.50.50.1 ebgp-multihop '2'
+set protocols bgp neighbor 10.50.50.1 remote-as '65001'
+set protocols bgp neighbor 10.50.50.1 update-source 'eth0'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.50.50.2'
+```
+
+- VyOS-CE1-HUB:
+
+```none
+# interfaces
+set interfaces dummy dum20 address '10.0.0.100/32'
+set interfaces ethernet eth0 address '10.80.80.2/24'
+
+# BGP for peering with PE
+set protocols bgp system-as 65035
+set protocols bgp address-family ipv4-unicast network 10.0.0.100/32
+set protocols bgp address-family ipv4-unicast redistribute connected
+set protocols bgp neighbor 10.80.80.1 ebgp-multihop '2'
+set protocols bgp neighbor 10.80.80.1 remote-as '65001'
+set protocols bgp neighbor 10.80.80.1 update-source 'eth0'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.80.80.2'
+```
+
+- VyOS-CE2-SPOKE:
+
+```none
+# interfaces
+set interfaces dummy dum20 address '10.0.0.90/32'
+set interfaces ethernet eth0 address '10.60.60.2/24'
+
+# BGP for peering with PE
+set protocols bgp system-as 65035
+set protocols bgp address-family ipv4-unicast network 10.0.0.90/32
+set protocols bgp neighbor 10.60.60.1 ebgp-multihop '2'
+set protocols bgp neighbor 10.60.60.1 remote-as '65001'
+set protocols bgp neighbor 10.60.60.1 update-source 'eth0'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.60.60.2'
+```
+
+
+### Step-5: Verification
+
+This section describes verification commands for MPLS/BGP/LDP
+protocols and L3VPN related routes as well as diagnosis and
+reachability checks between CE nodes.
+
+Let’s check IPv4 routing and MPLS information on provider nodes
+(same procedure for all P nodes):
+- “show ip ospf neighbor” for checking ospf relationship
+
+```none
+vyos@VyOS-P1:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL
+10.0.0.4 1 Full/Backup 34.718s 172.16.30.2 eth0:172.16.30.1 0 0 0
+10.0.0.5 1 Full/Backup 35.132s 172.16.40.2 eth1:172.16.40.1 0 0 0
+10.0.0.7 1 Full/Backup 34.764s 172.16.90.2 eth2:172.16.90.1 0 0 0
+10.0.0.1 1 Full/Backup 35.642s 172.16.10.2 eth3:172.16.10.1 0 0 0
+10.0.0.8 1 Full/Backup 35.484s 172.16.100.2 eth5:172.16.100.1 0 0 0
+```
+
+- “show mpls ldp neighbor “ for checking ldp neighbors
+
+```none
+vyos@VyOS-P1:~$ show mpls ldp neighbor
+AF ID State Remote Address Uptime
+ipv4 10.0.0.1 OPERATIONAL 10.0.0.1 07w5d06h
+ipv4 10.0.0.4 OPERATIONAL 10.0.0.4 09w3d00h
+ipv4 10.0.0.5 OPERATIONAL 10.0.0.5 09w2d23h
+ipv4 10.0.0.7 OPERATIONAL 10.0.0.7 03w0d01h
+ipv4 10.0.0.8 OPERATIONAL 10.0.0.8 01w3d02h
+```
+
+- “show mpls ldp binding” for checking mpls label assignment
+
+```none
+vyos@VyOS-P1:~$ show mpls ldp discovery
+AF Destination Nexthop Local Label Remote Label In Use
+ipv4 10.0.0.1/32 10.0.0.1 23 imp-null yes
+ipv4 10.0.0.1/32 10.0.0.4 23 20 no
+ipv4 10.0.0.1/32 10.0.0.5 23 17 no
+ipv4 10.0.0.1/32 10.0.0.7 23 16 no
+ipv4 10.0.0.1/32 10.0.0.8 23 16 no
+ipv4 10.0.0.2/32 10.0.0.1 20 16 no
+ipv4 10.0.0.2/32 10.0.0.4 20 22 no
+ipv4 10.0.0.2/32 10.0.0.5 20 24 yes
+ipv4 10.0.0.2/32 10.0.0.7 20 17 no
+ipv4 10.0.0.2/32 10.0.0.8 20 17 no
+ipv4 10.0.0.3/32 10.0.0.1 imp-null 17 no
+ipv4 10.0.0.3/32 10.0.0.4 imp-null 16 no
+ipv4 10.0.0.3/32 10.0.0.5 imp-null 18 no
+ipv4 10.0.0.3/32 10.0.0.7 imp-null 18 no
+ipv4 10.0.0.3/32 10.0.0.8 imp-null 18 no
+ipv4 10.0.0.4/32 10.0.0.1 16 18 no
+ipv4 10.0.0.4/32 10.0.0.4 16 imp-null yes
+ipv4 10.0.0.4/32 10.0.0.5 16 19 no
+ipv4 10.0.0.4/32 10.0.0.7 16 19 no
+ipv4 10.0.0.4/32 10.0.0.8 16 19 no
+ipv4 10.0.0.5/32 10.0.0.1 21 19 no
+ipv4 10.0.0.5/32 10.0.0.4 21 17 no
+ipv4 10.0.0.5/32 10.0.0.5 21 imp-null yes
+ipv4 10.0.0.5/32 10.0.0.7 21 20 no
+ipv4 10.0.0.5/32 10.0.0.8 21 20 no
+ipv4 10.0.0.6/32 10.0.0.1 17 20 no
+ipv4 10.0.0.6/32 10.0.0.4 17 23 yes
+ipv4 10.0.0.6/32 10.0.0.5 17 21 yes
+ipv4 10.0.0.6/32 10.0.0.7 17 21 no
+ipv4 10.0.0.6/32 10.0.0.8 17 21 no
+ipv4 10.0.0.7/32 10.0.0.1 22 21 no
+ipv4 10.0.0.7/32 10.0.0.4 22 18 no
+ipv4 10.0.0.7/32 10.0.0.5 22 20 no
+ipv4 10.0.0.7/32 10.0.0.7 22 imp-null yes
+ipv4 10.0.0.7/32 10.0.0.8 22 22 no
+ipv4 10.0.0.8/32 10.0.0.1 24 22 no
+ipv4 10.0.0.8/32 10.0.0.4 24 19 no
+ipv4 10.0.0.8/32 10.0.0.5 24 16 no
+ipv4 10.0.0.8/32 10.0.0.7 24 22 no
+ipv4 10.0.0.8/32 10.0.0.8 24 imp-null yes
+ipv4 10.0.0.9/32 10.0.0.1 18 23 no
+ipv4 10.0.0.9/32 10.0.0.4 18 21 yes
+ipv4 10.0.0.9/32 10.0.0.5 18 22 no
+ipv4 10.0.0.9/32 10.0.0.7 18 23 no
+ipv4 10.0.0.9/32 10.0.0.8 18 23 no
+ipv4 10.0.0.10/32 10.0.0.1 19 24 no
+ipv4 10.0.0.10/32 10.0.0.4 19 24 yes
+ipv4 10.0.0.10/32 10.0.0.5 19 23 yes
+ipv4 10.0.0.10/32 10.0.0.7 19 24 no
+ipv4 10.0.0.10/32 10.0.0.8 19 24 no
+```
+
+Now we’re checking iBGP status and routes from route-reflector
+nodes to other devices:
+- “show bgp ipv4 vpn summary” for checking BGP VPNv4 neighbors:
+
+```none
+vyos@VyOS-RR1:~$ show bgp ipv4 vpn summary
+BGP router identifier 10.0.0.1, local AS number 65001 vrf-id 0
+BGP table version 0
+RIB entries 9, using 1728 bytes of memory
+Peers 4, using 85 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.0.0.7 4 65001 7719 7733 0 0 0 5d07h56m 2 10
+10.0.0.8 4 65001 7715 7724 0 0 0 5d08h28m 4 10
+10.0.0.9 4 65001 7713 7724 0 0 0 5d08h28m 2 10
+10.0.0.10 4 65001 7713 7724 0 0 0 5d08h28m 2 10
+
+Total number of neighbors 4
+```
+
+- “show bgp ipv4 vpn” for checking all VPNv4 prefixes information:
+
+```none
+vyos@VyOS-RR1:~$ show bgp ipv4 vpn
+BGP table version is 2, local router ID is 10.0.0.1, vrf id 0
+Default local pref 100, local AS 65001
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+Route Distinguisher: 10.50.50.1:1011
+*>i10.50.50.0/24 10.0.0.7 0 100 0 i
+ UN=10.0.0.7 EC{65035:1011} label=80 type=bgp, subtype=0
+*>i80.80.80.80/32 10.0.0.7 0 100 0 65035 i
+ UN=10.0.0.7 EC{65035:1011} label=80 type=bgp, subtype=0
+Route Distinguisher: 10.60.60.1:1011
+*>i10.60.60.0/24 10.0.0.10 0 100 0 i
+ UN=10.0.0.10 EC{65035:1011} label=80 type=bgp, subtype=0
+*>i90.90.90.90/32 10.0.0.10 0 100 0 65035 i
+ UN=10.0.0.10 EC{65035:1011} label=80 type=bgp, subtype=0
+Route Distinguisher: 10.80.80.1:1011
+*>i10.80.80.0/24 10.0.0.8 0 100 0 i
+ UN=10.0.0.8 EC{65035:1030} label=80 type=bgp, subtype=0
+*>i100.100.100.100/32
+ 10.0.0.8 0 100 0 65035 i
+ UN=10.0.0.8 EC{65035:1030} label=80 type=bgp, subtype=0
+Route Distinguisher: 172.16.80.1:2011
+*>i10.110.110.0/24 10.0.0.8 0 100 0 65050 i
+ UN=10.0.0.8 EC{65050:2011} label=81 type=bgp, subtype=0
+*>i172.16.80.0/24 10.0.0.8 0 100 0 i
+ UN=10.0.0.8 EC{65050:2011} label=81 type=bgp, subtype=0
+Route Distinguisher: 172.16.100.1:2011
+*>i10.210.210.0/24 10.0.0.9 0 100 0 65050 i
+ UN=10.0.0.9 EC{65050:2011} label=80 type=bgp, subtype=0
+*>i172.16.100.0/24 10.0.0.9 0 100 0 i
+ UN=10.0.0.9 EC{65050:2011} label=80 type=bgp, subtype=0
+```
+
+- “show bgp ipv4 vpn x.x.x.x/x” for checking best path selected
+ for specific VPNv4 destination
+
+```none
+vyos@VyOS-RR1:~$ show bgp ipv4 vpn 10.0.0.100/32
+BGP routing table entry for 10.80.80.1:1011:10.0.0.100/32
+not allocated
+Paths: (1 available, best #1)
+ Advertised to non peer-group peers:
+ 10.0.0.7 10.0.0.8 10.0.0.9 10.0.0.10
+ 65035, (Received from a RR-client)
+ 10.0.0.8 from 10.0.0.8 (10.0.0.8)
+ Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
+ Extended Community: RT:65035:1030
+ Remote label: 80
+ Last update: Tue Oct 19 13:45:32 202
+```
+
+Also we can verify how PE devices receives VPNv4 networks from the RRs
+and installing them to the specific customer VRFs:
+- “show bgp ipv4 vpn summary” for checking iBGP neighbors against
+ route-reflector devices:
+
+```none
+vyos@VyOS-PE1:~$ show bgp ipv4 vpn summary
+BGP router identifier 10.0.0.7, local AS number 65001 vrf-id 0
+BGP table version 0
+RIB entries 9, using 1728 bytes of memory
+Peers 2, using 43 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.0.0.1 4 65001 8812 8794 0 0 0 01:18:42 8 2
+10.0.0.2 4 65001 8800 8792 0 0 0 6d02h27m 8 2
+```
+
+- “show bgp vrf all” for checking all the prefix learning on BGP
+ : within VRFs:
+
+```none
+vyos@VyOS-PE1:~$ show bgp vrf all
+
+Instance default:
+No BGP prefixes displayed, 0 exist
+
+Instance BLUE_SPOKE:
+BGP table version is 8, local router ID is 10.50.50.1, vrf id 6
+Default local pref 100, local AS 65001
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+* 10.50.50.0/24 0.0.0.0 0 32768 ?
+*> 0.0.0.0 0 32768 i
+*> 10.80.80.0/24 10.0.0.8@0< 0 100 0 i
+* 10.0.0.8@0< 0 100 0 i
+*> 10.0.0.80/32 10.50.50.2 0 0 65035 i
+*> 10.0.0.100/32
+ 10.0.0.8@0< 0 100 0 65035 ?
+* 10.0.0.8@0< 0 100 0 65035 ?
+```
+
+- “show bgp vrf BLUE_SPOKE summary” for checking EBGP neighbor
+ : information between PE and CE:
+
+```none
+vyos@VyOS-PE1:~$ show bgp vrf BLUE_SPOKE summary
+
+IPv4 Unicast Summary:
+BGP router identifier 10.50.50.1, local AS number 65001 vrf-id 6
+BGP table version 8
+RIB entries 7, using 1344 bytes of memory
+Peers 1, using 21 KiB of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.50.50.2 4 65035 9019 9023 0 0 0 6d06h12m 1 4
+
+Total number of neighbors 1
+```
+
+- “show ip route vrf BLUE_SPOKE” for viewing the RIB in our Spoke PE.
+ : Using this command we are also able to check the transport and
+ customer label (inner/outer) for Hub network prefix (10.0.0.100/32):
+
+```none
+vyos@VyOS-PE1:~$ show ip route vrf BLUE_SPOKE
+
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+VRF BLUE_SPOKE:
+K>* 0.0.0.0/0 [255/8192] unreachable (ICMP unreachable), 03w0d23h
+C>* 10.50.50.0/24 is directly connected, eth3, 03w0d23h
+B> 10.80.80.0/24 [200/0] via 10.0.0.8 (vrf default) (recursive), label 80, weight 1, 04:22:00
+ * via 172.16.90.1, eth0 (vrf default), label 24/80, weight 1, 04:22:00
+B>* 10.0.0.80/32 [20/0] via 10.50.50.2, eth3, weight 1, 6d05h30m
+B> 10.0.0.100/32 [200/0] via 10.0.0.8 (vrf default) (recursive), label 80, weight 1, 04:22:00
+ * via 172.16.90.1, eth0 (vrf default), label 24/80, weight 1, 04:22:00
+```
+
+- “show bgp ipv4 vpn x.x.x.x/32” for checking the best-path to the
+ : specific VPNv4 destination including extended community and
+ remotelabel information. This procedure is the same on all Spoke nodes:
+
+```none
+vyos@VyOS-PE1:~$ show bgp ipv4 vpn 10.0.0.100/32
+BGP routing table entry for 10.80.80.1:1011:10.0.0.100/32
+not allocated
+Paths: (2 available, best #1)
+ Not advertised to any peer
+ 65035
+ 10.0.0.8 from 10.0.0.1 (10.0.0.8)
+ Origin incomplete, metric 0, localpref 100, valid, internal, best (Neighbor IP)
+ Extended Community: RT:65035:1030
+ Originator: 10.0.0.8, Cluster list: 10.0.0.1
+ Remote label: 80
+ Last update: Tue Oct 19 13:45:26 2021
+ 65035
+ 10.0.0.8 from 10.0.0.2 (10.0.0.8)
+ Origin incomplete, metric 0, localpref 100, valid, internal
+ Extended Community: RT:65035:1030
+ Originator: 10.0.0.8, Cluster list: 10.0.0.1
+ Remote label: 80
+ Last update: Wed Oct 13 12:39:34 202
+```
+
+Now, let’s check routing information on out Hub PE:
+- “show bgp ipv4 vpn summary” for checking iBGP neighbors again
+ : VyOS-RR1/RR2
+
+```none
+vyos@VyOS-PE2:~$ show bgp ipv4 vpn summary
+BGP router identifier 10.0.0.8, local AS number 65001 vrf-id 0
+BGP table version 0
+RIB entries 9, using 1728 bytes of memory
+Peers 2, using 43 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.0.0.1 4 65001 15982 15949 0 0 0 05:41:28 6 4
+10.0.0.2 4 65001 9060 9054 0 0 0 6d06h47m 6 4
+
+Total number of neighbors
+```
+
+- “show bgp vrf all” for checking all the prefixes learning on BGP
+
+```none
+vyos@VyOS-PE2:~$ show bgp vrf all
+
+Instance default:
+No BGP prefixes displayed, 0 exist
+
+Instance BLUE_HUB:
+BGP table version is 50, local router ID is 10.80.80.1, vrf id 8
+Default local pref 100, local AS 65001
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 10.50.50.0/24 10.0.0.7@0< 0 100 0 i
+* 10.0.0.7@0< 0 100 0 i
+*> 10.60.60.0/24 10.0.0.10@0< 0 100 0 i
+* 10.0.0.10@0< 0 100 0 i
+* 10.80.80.0/24 10.80.80.2 0 0 65035 ?
+* 0.0.0.0 0 32768 i
+*> 0.0.0.0 0 32768 ?
+*> 10.110.110.0/24 172.16.80.2@9< 0 0 65050 i
+*> 10.210.210.0/24 10.0.0.9@0< 0 100 0 65050 i
+* 10.0.0.9@0< 0 100 0 65050 i
+*> 10.0.0.80/32 10.0.0.7@0< 0 100 0 65035 i
+* 10.0.0.7@0< 0 100 0 65035 i
+*> 10.0.0.90/32 10.0.0.10@0< 0 100 0 65035 i
+* 10.0.0.10@0< 0 100 0 65035 i
+*> 10.0.0.100/32
+ 10.80.80.2 0 0 65035 ?
+*> 172.16.80.0/24 0.0.0.0@9< 0 32768 ?
+ 0.0.0.0@9< 0 32768 i
+*> 172.16.100.0/24 10.0.0.9@0< 0 100 0 i
+* 10.0.0.9@0< 0 100 0 i
+```
+
+- “show bgp vrf BLUE_HUB summary” for checking EBGP neighbor
+ : CE Hub device
+
+```none
+vyos@VyOS-PE2:~$ show bgp vrf BLUE_HUB summary
+
+IPv4 Unicast Summary:
+BGP router identifier 10.80.80.1, local AS number 65001 vrf-id 8
+BGP table version 50
+RIB entries 19, using 3648 bytes of memory
+Peers 1, using 21 KiB of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.80.80.2 4 65035 15954 15972 0 0 0 01w4d01h 2 10
+```
+
+- “show ip route vrf BLUE_HUB” to view the RIB in our Hub PE.
+ : With this command we are able to check the transport and
+ customer label (inner/outer) for network spokes prefixes
+ 10.0.0.80/32 - 10.0.0.90/32
+
+```none
+vyos@VyOS-PE2:~$ show ip route vrf BLUE_HUB
+
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+VRF BLUE_HUB:
+K>* 0.0.0.0/0 [255/8192] unreachable (ICMP unreachable), 01w4d01h
+B> 10.50.50.0/24 [200/0] via 10.0.0.7 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.100.1, eth1 (vrf default), label 22/144, weight 1, 05:53:15
+B> 10.60.60.0/24 [200/0] via 10.0.0.10 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.110.1, eth0 (vrf default), label 23/144, weight 1, 05:53:15
+C>* 10.80.80.0/24 is directly connected, eth3, 01w4d01h
+B>* 10.110.110.0/24 [200/0] via 172.16.80.2, eth2 (vrf GREEN), weight 1, 01w4d01h
+B> 10.210.210.0/24 [200/0] via 10.0.0.9 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.100.1, eth1 (vrf default), label 18/144, weight 1, 05:53:15
+ * via 172.16.110.1, eth0 (vrf default), label 22/144, weight 1, 05:53:15
+B> 10.0.0.80/32 [200/0] via 10.0.0.7 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.100.1, eth1 (vrf default), label 22/144, weight 1, 05:53:15
+B> 10.0.0.90/32 [200/0] via 10.0.0.10 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.110.1, eth0 (vrf default), label 23/144, weight 1, 05:53:15
+B>* 10.0.0.100/32 [20/0] via 10.80.80.2, eth3, weight 1, 01w4d01h
+B>* 172.16.80.0/24 [200/0] is directly connected, eth2 (vrf GREEN), weight 1, 01w4d01h
+B> 172.16.100.0/24 [200/0] via 10.0.0.9 (vrf default) (recursive), label 144, weight 1, 05:53:15
+ * via 172.16.100.1, eth1 (vrf default), label 18/144, weight 1, 05:53:15
+ * via 172.16.110.1, eth0 (vrf default), label 22/144, weight 1, 05:53:15
+```
+
+- “show bgp ipv4 vpn x.x.x.x/32” for checking best-path,
+ : extended community and remote label of specific destination
+
+```none
+vyos@VyOS-PE2:~$ show bgp ipv4 vpn 10.0.0.80/32
+BGP routing table entry for 10.50.50.1:1011:10.0.0.80/32
+not allocated
+Paths: (2 available, best #1)
+ Not advertised to any peer
+ 65035
+ 10.0.0.7 from 10.0.0.1 (10.0.0.7)
+ Origin IGP, metric 0, localpref 100, valid, internal, best (Neighbor IP)
+ Extended Community: RT:65035:1011
+ Originator: 10.0.0.7, Cluster list: 10.0.0.1
+ Remote label: 144
+ Last update: Tue Oct 19 13:45:30 2021
+ 65035
+ 10.0.0.7 from 10.0.0.2 (10.0.0.7)
+ Origin IGP, metric 0, localpref 100, valid, internal
+ Extended Community: RT:65035:1011
+ Originator: 10.0.0.7, Cluster list: 10.0.0.1
+ Remote label: 144
+ Last update: Wed Oct 13 12:39:37 2021
+
+vyos@VyOS-PE2:~$ show bgp ipv4 vpn 10.0.0.90/32
+BGP routing table entry for 10.60.60.1:1011:10.0.0.90/32
+not allocated
+Paths: (2 available, best #1)
+ Not advertised to any peer
+ 65035
+ 10.0.0.10 from 10.0.0.1 (10.0.0.10)
+ Origin IGP, metric 0, localpref 100, valid, internal, best (Neighbor IP)
+ Extended Community: RT:65035:1011
+ Originator: 10.0.0.10, Cluster list: 10.0.0.1
+ Remote label: 144
+ Last update: Tue Oct 19 13:45:30 2021
+ 65035
+ 10.0.0.10 from 10.0.0.2 (10.0.0.10)
+ Origin IGP, metric 0, localpref 100, valid, internal
+ Extended Community: RT:65035:1011
+ Originator: 10.0.0.10, Cluster list: 10.0.0.1
+ Remote label: 144
+ Last update: Wed Oct 13 12:45:44 2021
+```
+
+Finally, let’s check the reachability between CEs:
+- VyOS-CE1-SPOKE -----> VyOS-CE-HUB
+
+```none
+# check rib
+vyos@VyOS-CE1-SPOKE:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+B 10.50.50.0/24 [20/0] via 10.50.50.1 inactive, weight 1, 6d07h53m
+C>* 10.50.50.0/24 is directly connected, eth0, 09w0d00h
+B>* 10.80.80.0/24 [20/0] via 10.50.50.1, eth0, weight 1, 6d07h53m
+C>* 10.0.0.80/32 is directly connected, dum20, 09w0d00h
+B>* 10.0.0.100/32 [20/0] via 10.50.50.1, eth0, weight 1, 6d07h53m
+
+# check icmp
+vyos@VyOS-CE1-SPOKE:~$ ping 10.0.0.100 interface 10.0.0.80
+PING 10.0.0.100 (10.0.0.100) from 10.0.0.80 : 56(84) bytes of data.
+64 bytes from 10.0.0.100: icmp_seq=1 ttl=62 time=6.52 ms
+64 bytes from 10.0.0.100: icmp_seq=2 ttl=62 time=4.13 ms
+64 bytes from 10.0.0.100: icmp_seq=3 ttl=62 time=4.04 ms
+64 bytes from 10.0.0.100: icmp_seq=4 ttl=62 time=4.03 ms
+^C
+--- 10.0.0.100 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 8ms
+rtt min/avg/max/mdev = 4.030/4.680/6.518/1.064 ms
+
+# check network path
+vyos@VyOS-CE1-SPOKE:~$ traceroute 10.0.0.100
+traceroute to 10.0.0.100 (10.0.0.100), 30 hops max, 60 byte packets
+ 1 10.50.50.1 (10.50.50.1) 1.041 ms 1.252 ms 1.835 ms
+ 2 * * *
+ 3 10.0.0.100 (10.0.0.100) 9.225 ms 9.159 ms 9.121 m
+```
+
+- VyOS-CE-HUB -------> VyOS-CE1-SPOKE
+- VyOS-CE-HUB -------> VyOS-CE2-SPOKE
+
+```none
+# check rib
+vyos@VyOS-CE-HUB:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+B>* 10.50.50.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h04m
+B>* 10.60.60.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h35m
+C>* 10.80.80.0/24 is directly connected, eth0, 01w6d07h
+B>* 10.110.110.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 01w4d02h
+B>* 10.210.210.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h35m
+B>* 10.0.0.80/32 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h04m
+B>* 10.0.0.90/32 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h35m
+C>* 10.0.0.100/32 is directly connected, dum20, 01w6d07h
+B>* 172.16.80.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 01w4d02h
+B>* 172.16.100.0/24 [20/0] via 10.80.80.1, eth0, weight 1, 6d08h35m
+
+# check icmp
+vyos@VyOS-CE-HUB:~$ ping 10.0.0.80 interface 10.0.0.100 c 4
+PING 10.0.0.80 (10.0.0.80) from 10.0.0.100 : 56(84) bytes of data.
+64 bytes from 10.0.0.80: icmp_seq=1 ttl=62 time=3.31 ms
+64 bytes from 10.0.0.80: icmp_seq=2 ttl=62 time=4.23 ms
+64 bytes from 10.0.0.80: icmp_seq=3 ttl=62 time=3.89 ms
+64 bytes from 10.0.0.80: icmp_seq=4 ttl=62 time=3.22 ms
+
+--- 10.0.0.80 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 9ms
+rtt min/avg/max/mdev = 3.218/3.661/4.226/0.421 ms
+
+vyos@VyOS-CE-HUB:~$ ping 10.0.0.90 interface 10.0.0.100 c 4
+PING 10.0.0.90 (10.0.0.90) from 10.0.0.100 : 56(84) bytes of data.
+64 bytes from 10.0.0.90: icmp_seq=1 ttl=62 time=7.46 ms
+64 bytes from 10.0.0.90: icmp_seq=2 ttl=62 time=4.43 ms
+64 bytes from 10.0.0.90: icmp_seq=3 ttl=62 time=4.60 ms
+^C
+--- 10.0.0.90 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 6ms
+rtt min/avg/max/mdev = 4.430/5.498/7.463/1.391 ms
+
+# check network path
+vyos@VyOS-CE-HUB:~$ traceroute 10.0.0.80
+traceroute to 10.0.0.80 (10.0.0.80), 30 hops max, 60 byte packets
+ 1 10.80.80.1 (10.80.80.1) 1.563 ms 1.341 ms 1.075 ms
+ 2 * * *
+ 3 10.0.0.80 (10.0.0.80) 8.125 ms 8.019 ms 7.781 ms
+
+vyos@VyOS-CE-HUB:~$ traceroute 10.0.0.90
+traceroute to 10.0.0.90 (10.0.0.90), 30 hops max, 60 byte packets
+ 1 10.80.80.1 (10.80.80.1) 1.305 ms 1.137 ms 1.097 ms
+ 2 * * *
+ 3 * * *
+ 4 10.0.0.90 (10.0.0.90) 9.358 ms 9.325 ms 9.292 ms
+```
+
+- VyOS-CE2-SPOKE -------> VyOS-CE-HUB
+
+```none
+# check rib
+vyos@rt-ce2-SPOKE:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+B 10.60.60.0/24 [20/0] via 10.60.60.1 inactive, weight 1, 02w6d00h
+C>* 10.60.60.0/24 is directly connected, eth0, 02w6d00h
+B>* 10.80.80.0/24 [20/0] via 10.60.60.1, eth0, weight 1, 6d08h46m
+C>* 10.0.0.90/32 is directly connected, dum20, 02w6d00h
+B>* 10.0.0.100/32 [20/0] via 10.60.60.1, eth0, weight 1, 6d08h46m
+
+# check icmp
+vyos@rt-ce2-SPOKE:~$ ping 10.0.0.100 interface 10.0.0.90 c 4
+PING 10.0.0.100 (10.0.0.100) from 10.0.0.90 : 56(84) bytes of data.
+64 bytes from 10.0.0.100: icmp_seq=1 ttl=62 time=4.97 ms
+64 bytes from 10.0.0.100: icmp_seq=2 ttl=62 time=4.45 ms
+64 bytes from 10.0.0.100: icmp_seq=3 ttl=62 time=4.20 ms
+64 bytes from 10.0.0.100: icmp_seq=4 ttl=62 time=4.29 ms
+
+--- 10.0.0.100 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 9ms
+rtt min/avg/max/mdev = 4.201/4.476/4.971/0.309 ms
+
+# check network path
+vyos@rt-ce2-SPOKE:~$ traceroute 10.0.0.100
+traceroute to 10.0.0.100 (10.0.0.100), 30 hops max, 60 byte packets
+ 1 10.60.60.1 (10.60.60.1) 1.343 ms 1.190 ms 1.152 ms
+ 2 * * *
+ 3 * * *
+ 4 10.0.0.100 (10.0.0.100) 7.504 ms 7.480 ms 7.488 ms
+```
+
+**Note:** At the moment, trace mpls doesn’t show labels/paths. So we’ll
+see `* * *` for the transit routers of the mpls backbone.
diff --git a/docs/configexamples/lac-lns.md b/docs/configexamples/lac-lns.md
new file mode 100644
index 00000000..315abe1c
--- /dev/null
+++ b/docs/configexamples/lac-lns.md
@@ -0,0 +1,177 @@
+---
+lastproofread: '2024-02-21'
+---
+
+(examples-lac-lns)=
+
+# PPPoE over L2TP
+
+This document is to describe a basic setup using PPPoE over L2TP.
+LAC and LNS are components of the broadband topology.
+LAC - L2TP access concentrator
+LNS - L2TP Network Server
+LAC and LNS forms L2TP tunnel. LAC receives packets from PPPoE clients and
+forward them to LNS. LNS is the termination point that comes from PPP packets
+from the remote client.
+
+In this example we use VyOS 1.5 as LNS and Cisco IOS as LAC.
+All users with domain **vyos.io** will be tunneled to LNS via L2TP.
+
+## Network Topology
+
+```{image} /_static/images/lac-lns-diagram.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 60%
+```
+
+
+## Configurations
+
+### LAC
+
+```none
+aaa new-model
+!
+aaa authentication ppp default local
+!
+vpdn enable
+vpdn aaa attribute nas-ip-address vpdn-nas
+!
+vpdn-group LAC
+ request-dialin
+ protocol l2tp
+ domain vyos.io
+ initiate-to ip 192.168.139.100
+ source-ip 192.168.139.101
+ local name LAC
+ l2tp tunnel password 0 test123
+!
+bba-group pppoe MAIN-BBA
+ virtual-template 1
+!
+interface GigabitEthernet0/0
+ description To LNS
+ ip address 192.168.139.101 255.255.255.0
+ duplex auto
+ speed auto
+ media-type rj45
+!
+interface GigabitEthernet0/1
+ description To PPPoE clients
+ no ip address
+ duplex auto
+ speed auto
+ media-type rj45
+ pppoe enable group MAIN-BBA
+!
+interface Virtual-Template1
+ description pppoe MAIN-BBA
+ no ip address
+ no peer default ip address
+ ppp mtu adaptive
+ ppp authentication chap
+!
+```
+
+
+### LNS
+
+```none
+set interfaces ethernet eth0 address '192.168.139.100/24'
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 source address '10.0.0.0/24'
+set nat source rule 100 translation address 'masquerade'
+set protocols static route 0.0.0.0/0 next-hop 192.168.139.2
+set vpn l2tp remote-access authentication mode 'radius'
+set vpn l2tp remote-access authentication radius server 192.168.139.110 key 'radiustest'
+set vpn l2tp remote-access client-ip-pool TEST-POOL range '10.0.0.2-10.0.0.100'
+set vpn l2tp remote-access default-pool 'TEST-POOL'
+set vpn l2tp remote-access gateway-address '10.0.0.1'
+set vpn l2tp remote-access lns host-name 'LAC'
+set vpn l2tp remote-access lns shared-secret 'test123'
+set vpn l2tp remote-access name-server '8.8.8.8'
+set vpn l2tp remote-access ppp-options disable-ccp
+```
+
+:::{note}
+This setup requires the Compression Control Protocol (CCP)
+being disabled, the command `set vpn l2tp remote-access ppp-options disable-ccp`
+accomplishes that.
+:::
+
+### Client
+
+In this lab we use Windows PPPoE client.
+
+```{image} /_static/images/lac-lns-winclient.webp
+:align: center
+:alt: Window PPPoE Client Configuration
+:width: 100%
+```
+
+
+### Monitoring
+
+Monitoring on LNS side
+
+```none
+vyos@vyos:~$ show l2tp-server sessions
+ ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+--------+--------------+----------+-----+--------+-----------------+------------+--------+----------+-----------+----------
+ l2tp0 | test@vyos.io | 10.0.0.2 | | | 192.168.139.101 | | active | 00:00:35 | 188.4 KiB | 9.3 MiB
+```
+
+Monitoring on LAC side
+
+```none
+Router#show pppoe session
+ 1 session in FORWARDED (FWDED) State
+ 1 session total
+Uniq ID PPPoE RemMAC Port VT VA State
+ SID LocMAC VA-st Type
+ 1 1 000c.290b.20a6 Gi0/1 1 N/A FWDED
+ 0c58.88ac.0001
+
+Router#show l2tp
+L2TP Tunnel and Session Information Total tunnels 1 sessions 1
+
+LocTunID RemTunID Remote Name State Remote Address Sessn L2TP Class/
+ Count VPDN Group
+23238 2640 LAC est 192.168.139.100 1 LAC
+
+LocID RemID TunID Username, Intf/ State Last Chg Uniq ID
+ Vcid, Circuit
+25641 25822 23238 test@vyos.io, Gi0/1 est 00:05:36 1
+```
+
+Monitoring on RADIUS Server side
+
+```none
+root@Radius:~# cat /var/log/freeradius/radacct/192.168.139.100/detail-20240221
+Wed Feb 21 13:37:17 2024
+ User-Name = "test@vyos.io"
+ NAS-Port = 0
+ NAS-Port-Id = "l2tp0"
+ NAS-Port-Type = Virtual
+ Service-Type = Framed-User
+ Framed-Protocol = PPP
+ Calling-Station-Id = "192.168.139.101"
+ Called-Station-Id = "192.168.139.100"
+ Acct-Status-Type = Start
+ Acct-Authentic = RADIUS
+ Acct-Session-Id = "45c731e169d9a4f1"
+ Acct-Session-Time = 0
+ Acct-Input-Octets = 0
+ Acct-Output-Octets = 0
+ Acct-Input-Packets = 0
+ Acct-Output-Packets = 0
+ Acct-Input-Gigawords = 0
+ Acct-Output-Gigawords = 0
+ Framed-IP-Address = 10.0.0.2
+ NAS-IP-Address = 192.168.139.100
+ Event-Timestamp = "Feb 21 2024 13:37:17 UTC"
+ Tmp-String-9 = "ai:"
+ Acct-Unique-Session-Id = "ea6a1089816f19c0d0f1819bc61c3318"
+ Timestamp = 1708522637
+```
diff --git a/docs/configexamples/nmp.md b/docs/configexamples/nmp.md
new file mode 100644
index 00000000..9aa73540
--- /dev/null
+++ b/docs/configexamples/nmp.md
@@ -0,0 +1,72 @@
+---
+lastproofread: '2023-03-26'
+---
+
+(examples-nmp)=
+
+# NMP example
+
+Consider how to quickly set up NMP and VyOS for monitoring.
+NMP is multi-vendor network monitoring from 'SolarWinds' built to
+scale and expand with the needs of your network.
+
+## Configuration 'VyOS'
+
+First prepare our VyOS router for connection to NMP. We have to set
+up the SNMP protocol and connectivity between the router and NMP.
+
+```none
+set interfaces ethernet eth0 address 'dhcp'
+set system name-server '8.8.8.8'
+set service snmp community router authorization 'test'
+set service snmp community router network '0.0.0.0/0'
+```
+
+
+## Configuration 'NMP'
+
+Next, you just should follow the pictures:
+
+```{image} /_static/images/nmp1.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp2.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp3.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp4.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp5.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp6.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp7.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+In the end, you'll get a powerful instrument for monitoring the VyOS systems.
diff --git a/docs/configexamples/ospf-unnumbered.md b/docs/configexamples/ospf-unnumbered.md
new file mode 100644
index 00000000..9174d1b4
--- /dev/null
+++ b/docs/configexamples/ospf-unnumbered.md
@@ -0,0 +1,118 @@
+---
+lastproofread: '2021-06-29'
+---
+
+(examples-ospf-unnumbered)=
+
+# OSPF unnumbered with ECMP
+
+General information can be found in the {ref}`routing-ospf` chapter.
+
+## Configuration
+
+- Router A:
+
+```none
+set interfaces ethernet eth0 address '10.0.0.1/24'
+set interfaces ethernet eth1 address '192.168.0.1/32'
+set interfaces ethernet eth1 ip ospf authentication md5 key-id 1 md5-key 'yourpassword'
+set interfaces ethernet eth1 ip ospf network 'point-to-point'
+set interfaces ethernet eth2 address '192.168.0.1/32'
+set interfaces ethernet eth2 ip ospf authentication md5 key-id 1 md5-key 'yourpassword'
+set interfaces ethernet eth2 ip ospf network 'point-to-point'
+set interfaces loopback lo address '192.168.0.1/32'
+set protocols ospf area 0.0.0.0 authentication 'md5'
+set protocols ospf area 0.0.0.0 network '192.168.0.1/32'
+set protocols ospf parameters router-id '192.168.0.1'
+set protocols ospf redistribute connected
+```
+
+- Router B:
+
+```none
+set interfaces ethernet eth0 address '10.0.0.2/24'
+set interfaces ethernet eth1 address '192.168.0.2/32'
+set interfaces ethernet eth1 ip ospf authentication md5 key-id 1 md5-key 'yourpassword'
+set interfaces ethernet eth1 ip ospf network 'point-to-point'
+set interfaces ethernet eth2 address '192.168.0.2/32'
+set interfaces ethernet eth2 ip ospf authentication md5 key-id 1 md5-key 'yourpassword'
+set interfaces ethernet eth2 ip ospf network 'point-to-point'
+set interfaces loopback lo address '192.168.0.2/32'
+set protocols ospf area 0.0.0.0 authentication 'md5'
+set protocols ospf area 0.0.0.0 network '192.168.0.2/32'
+set protocols ospf parameters router-id '192.168.0.2'
+set protocols ospf redistribute connected
+```
+
+
+## Results
+
+- Router A:
+
+```none
+vyos@vyos:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 10.0.0.1/24 u/u
+eth1 192.168.0.1/32 u/u
+eth2 192.168.0.1/32 u/u
+lo 127.0.0.1/8 u/u
+ 192.168.0.1/32
+ ::1/128
+```
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+S>* 0.0.0.0/0 [210/0] via 10.0.0.254, eth0, 00:57:34
+O 10.0.0.0/24 [110/20] via 192.168.0.2, eth1 onlink, 00:13:21
+ via 192.168.0.2, eth2 onlink, 00:13:21
+C>* 10.0.0.0/24 is directly connected, eth0, 00:57:35
+O 192.168.0.1/32 [110/0] is directly connected, lo, 00:48:53
+C * 192.168.0.1/32 is directly connected, eth2, 00:56:31
+C * 192.168.0.1/32 is directly connected, eth1, 00:56:31
+C>* 192.168.0.1/32 is directly connected, lo, 00:57:36
+O>* 192.168.0.2/32 [110/1] via 192.168.0.2, eth1 onlink, 00:29:03
+ * via 192.168.0.2, eth2 onlink, 00:29:03
+```
+
+- Router B:
+
+```none
+vyos@vyos:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 10.0.0.2/24 u/u
+eth1 192.168.0.2/32 u/u
+eth2 192.168.0.2/32 u/u
+lo 127.0.0.1/8 u/u
+ 192.168.0.2/32
+ ::1/128
+```
+
+```none
+vyos@vyos:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+S>* 0.0.0.0/0 [210/0] via 10.0.0.254, eth0, 00:57:34
+O 10.0.0.0/24 [110/20] via 192.168.0.1, eth1 onlink, 00:13:21
+ via 192.168.0.1, eth2 onlink, 00:13:21
+C>* 10.0.0.0/24 is directly connected, eth0, 00:57:35
+O 192.168.0.2/32 [110/0] is directly connected, lo, 00:48:53
+C * 192.168.0.2/32 is directly connected, eth2, 00:56:31
+C * 192.168.0.2/32 is directly connected, eth1, 00:56:31
+C>* 192.168.0.2/32 is directly connected, lo, 00:57:36
+O>* 192.168.0.1/32 [110/1] via 192.168.0.1, eth1 onlink, 00:29:03
+ * via 192.168.0.1, eth2 onlink, 00:29:03
+```
diff --git a/docs/configexamples/policy-based-ipsec-and-firewall.md b/docs/configexamples/policy-based-ipsec-and-firewall.md
new file mode 100644
index 00000000..be3534dc
--- /dev/null
+++ b/docs/configexamples/policy-based-ipsec-and-firewall.md
@@ -0,0 +1,269 @@
+(examples-policy-based-ipsec-and-firewall)=
+
+# Policy-Based Site-to-Site VPN and Firewall Configuration
+
+This guide shows an example policy-based IKEv2 site-to-site VPN between two
+VyOS routers, and firewall configuration.
+
+For simplicity, configuration and tests are done only using IPv4, and firewall
+configuration is done only on one router.
+
+## Network Topology and requirements
+
+This configuration example and the requirements consists of:
+
+- Two VyOS routers with public IP address.
+
+- 2 private subnets on each site.
+
+- Local subnets should be able to reach internet using source NAT.
+
+- Communication between private subnets should be done through IPSec tunnel
+ without NAT.
+
+- Configuration of basic firewall in one site, in order to:
+
+ > - Protect the router on 'WAN' interface, allowing only IPSec connections
+ > and SSH access from trusted IPs.
+ > - Allow access to the router only from trusted networks.
+ > - Allow DNS requests only only for local networks.
+ > - Allow ICMP on all interfaces.
+ > - Allow all new connections from local subnets.
+ > - Allow connections from LANs to LANs through the tunnel.
+
+```{image} /_static/images/policy-based-ipsec-and-firewall.webp
+```
+
+
+## Configuration
+
+Interface and routing configuration:
+
+```none
+# LEFT router:
+set interfaces ethernet eth0 address '198.51.100.14/30'
+set interfaces ethernet eth1 vif 111 address '10.1.11.1/24'
+set interfaces ethernet eth2 vif 112 address '10.1.12.1/24'
+set protocols static route 0.0.0.0/0 next-hop 198.51.100.13
+
+# RIGHT router:
+set interfaces ethernet eth0 address '192.0.2.130/30'
+set interfaces ethernet eth1 vif 221 address '10.2.21.1/24'
+set interfaces ethernet eth2 vif 222 address '10.2.22.1/24'
+```
+
+IPSec configuration:
+
+```none
+# LEFT router:
+set vpn ipsec authentication psk RIGHT id '198.51.100.14'
+set vpn ipsec authentication psk RIGHT id '192.0.2.130'
+set vpn ipsec authentication psk RIGHT secret 'p4ssw0rd'
+set vpn ipsec esp-group ESP-GROUP mode 'tunnel'
+set vpn ipsec esp-group ESP-GROUP proposal 1 encryption 'aes256'
+set vpn ipsec esp-group ESP-GROUP proposal 1 hash 'sha256'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-GROUP proposal 1 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 1 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 1 hash 'sha256'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer RIGHT authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer RIGHT connection-type 'initiate'
+set vpn ipsec site-to-site peer RIGHT default-esp-group 'ESP-GROUP'
+set vpn ipsec site-to-site peer RIGHT ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer RIGHT local-address '198.51.100.14'
+set vpn ipsec site-to-site peer RIGHT remote-address '192.0.2.130'
+set vpn ipsec site-to-site peer RIGHT tunnel 0 local prefix '10.1.11.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 0 remote prefix '10.2.21.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 1 local prefix '10.1.11.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 1 remote prefix '10.2.22.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 2 local prefix '10.1.12.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 2 remote prefix '10.2.21.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 3 local prefix '10.1.12.0/24'
+set vpn ipsec site-to-site peer RIGHT tunnel 3 remote prefix '10.2.22.0/24'
+
+# RIGHT router:
+set vpn ipsec authentication psk LEFT id '192.0.2.130'
+set vpn ipsec authentication psk LEFT id '198.51.100.14'
+set vpn ipsec authentication psk LEFT secret 'p4ssw0rd'
+set vpn ipsec esp-group ESP-GROUP mode 'tunnel'
+set vpn ipsec esp-group ESP-GROUP proposal 1 encryption 'aes256'
+set vpn ipsec esp-group ESP-GROUP proposal 1 hash 'sha256'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-GROUP proposal 1 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 1 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 1 hash 'sha256'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer LEFT authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer LEFT connection-type 'none'
+set vpn ipsec site-to-site peer LEFT default-esp-group 'ESP-GROUP'
+set vpn ipsec site-to-site peer LEFT ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer LEFT local-address '192.0.2.130'
+set vpn ipsec site-to-site peer LEFT remote-address '198.51.100.14'
+set vpn ipsec site-to-site peer LEFT tunnel 0 local prefix '10.2.21.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 0 remote prefix '10.1.11.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 1 local prefix '10.2.22.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 1 remote prefix '10.1.11.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 2 local prefix '10.2.21.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 2 remote prefix '10.1.12.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 3 local prefix '10.2.22.0/24'
+set vpn ipsec site-to-site peer LEFT tunnel 3 remote prefix '10.1.12.0/24'
+```
+
+Firewall Configuration:
+
+```none
+# Firewall Groups:
+set firewall group network-group LOCAL-NETS network '10.1.11.0/24'
+set firewall group network-group LOCAL-NETS network '10.1.12.0/24'
+set firewall group network-group REMOTE-NETS network '10.2.21.0/24'
+set firewall group network-group REMOTE-NETS network '10.2.22.0/24'
+set firewall group network-group TRUSTED network '198.51.100.125/32'
+set firewall group network-group TRUSTED network '203.0.113.0/24'
+set firewall group network-group TRUSTED network '10.1.11.0/24'
+set firewall group network-group TRUSTED network '192.168.70.0/24'
+
+# Forward traffic: default drop and only allow what is needed
+set firewall ipv4 forward filter default-action 'drop'
+
+# Forward traffic: global state policies
+set firewall ipv4 forward filter rule 1 action 'accept'
+set firewall ipv4 forward filter rule 1 state established 'enable'
+set firewall ipv4 forward filter rule 1 state related 'enable'
+set firewall ipv4 forward filter rule 2 action 'drop'
+set firewall ipv4 forward filter rule 2 state invalid 'enable'
+
+# Forward traffic: Accept all connections from local networks
+set firewall ipv4 forward filter rule 10 action 'accept'
+set firewall ipv4 forward filter rule 10 source group network-group 'LOCAL-NETS'
+
+# Forward traffic: accept connections from remote LANs to local LANs
+set firewall ipv4 forward filter rule 20 action 'accept'
+set firewall ipv4 forward filter rule 20 destination group network-group 'LOCAL-NETS'
+set firewall ipv4 forward filter rule 20 source group network-group 'REMOTE-NETS'
+
+# Input traffic: default drop and only allow what is needed
+set firewall ipv4 input filter default-action 'drop'
+
+# Input traffic: global state policies
+set firewall ipv4 input filter rule 1 action 'accept'
+set firewall ipv4 input filter rule 1 state established 'enable'
+set firewall ipv4 input filter rule 1 state related 'enable'
+set firewall ipv4 input filter rule 2 action 'drop'
+set firewall ipv4 input filter rule 2 state invalid 'enable'
+
+# Input traffic: add rules needed for ipsec connection
+set firewall ipv4 input filter rule 10 action 'accept'
+set firewall ipv4 input filter rule 10 destination port '500,4500'
+set firewall ipv4 input filter rule 10 inbound-interface name 'eth0'
+set firewall ipv4 input filter rule 10 protocol 'udp'
+set firewall ipv4 input filter rule 15 action 'accept'
+set firewall ipv4 input filter rule 15 inbound-interface name 'eth0'
+set firewall ipv4 input filter rule 15 protocol 'esp'
+
+# Input traffic: accept ssh connection from trusted ips
+set firewall ipv4 input filter rule 20 action 'accept'
+set firewall ipv4 input filter rule 20 destination port '22'
+set firewall ipv4 input filter rule 20 protocol 'tcp'
+set firewall ipv4 input filter rule 20 source group network-group 'TRUSTED'
+
+# Input traffic: accepd dns requests only from local networks.
+set firewall ipv4 input filter rule 25 action 'accept'
+set firewall ipv4 input filter rule 25 destination port '53'
+set firewall ipv4 input filter rule 25 protocol 'udp'
+set firewall ipv4 input filter rule 25 source group network-group 'LOCAL-NETS'
+
+# Input traffic: allow icmp
+set firewall ipv4 input filter rule 30 action 'accept'
+set firewall ipv4 input filter rule 30 protocol 'icmp'
+```
+
+And NAT Configuration:
+
+```none
+set nat source rule 10 destination group network-group 'REMOTE-NETS'
+set nat source rule 10 exclude
+set nat source rule 10 outbound-interface name 'eth0'
+set nat source rule 10 source group network-group 'LOCAL-NETS'
+set nat source rule 20 outbound-interface name 'eth0'
+set nat source rule 20 source group network-group 'LOCAL-NETS'
+set nat source rule 20 translation address 'masquerade'
+```
+
+## Checking through op-mode commands
+
+After some testing, we can check IPSec status, and counter on every tunnel:
+
+```none
+vyos@LEFT:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------- ------- -------- -------------- ---------------- ---------------- ----------- ---------------------------------------
+RIGHT-tunnel-0 up 36m24s 840B/840B 10/10 192.0.2.130 192.0.2.130 AES_CBC_256/HMAC_SHA2_256_128/MODP_2048
+RIGHT-tunnel-1 up 36m33s 588B/588B 7/7 192.0.2.130 192.0.2.130 AES_CBC_256/HMAC_SHA2_256_128/MODP_2048
+RIGHT-tunnel-2 up 35m50s 1K/1K 15/15 192.0.2.130 192.0.2.130 AES_CBC_256/HMAC_SHA2_256_128/MODP_2048
+RIGHT-tunnel-3 up 36m54s 2K/2K 32/32 192.0.2.130 192.0.2.130 AES_CBC_256/HMAC_SHA2_256_128/MODP_2048
+vyos@LEFT:~$
+```
+
+Also, we can check firewall counters:
+
+```none
+vyos@LEFT:~$ show firewall
+Rulesets Information
+
+---------------------------------
+IPv4 Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ------------------------------------------------------
+1 accept all 681 96545 ct state { established, related } accept
+2 drop all 0 0 ct state invalid
+10 accept all 360 27205 ip saddr @N_LOCAL-NETS accept
+20 accept all 8 648 ip daddr @N_LOCAL-NETS ip saddr @N_REMOTE-NETS accept
+default drop all
+
+---------------------------------
+IPv4 Firewall "input filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------------
+1 accept all 901 123709 ct state { established, related } accept
+2 drop all 0 0 ct state invalid
+10 accept udp 0 0 udp dport { 500, 4500 } iifname "eth0" accept
+15 accept esp 0 0 meta l4proto esp iifname "eth0" accept
+20 accept tcp 1 60 tcp dport 22 ip saddr @N_TRUSTED accept
+25 accept udp 0 0 udp dport 53 ip saddr @N_LOCAL-NETS accept
+30 accept icmp 0 0 meta l4proto icmp accept
+default drop all
+
+vyos@LEFT:~$
+vyos@LEFT:~$ show firewall statistics
+Rulesets Statistics
+
+---------------------------------
+IPv4 Firewall "forward filter"
+
+Rule Packets Bytes Action Source Destination Inbound-Interface Outbound-interface
+------- --------- ------- -------- ----------- ------------- ------------------- --------------------
+1 681 96545 accept any any any any
+2 0 0 drop any any any any
+10 360 27205 accept LOCAL-NETS any any any
+20 8 648 accept REMOTE-NETS LOCAL-NETS any any
+default N/A N/A drop any any any any
+
+---------------------------------
+IPv4 Firewall "input filter"
+
+Rule Packets Bytes Action Source Destination Inbound-Interface Outbound-interface
+------- --------- ------- -------- ---------- ------------- ------------------- --------------------
+1 905 124213 accept any any any any
+2 0 0 drop any any any any
+10 0 0 accept any any eth0 any
+15 0 0 accept any any eth0 any
+20 1 60 accept TRUSTED any any any
+25 0 0 accept LOCAL-NETS any any any
+30 0 0 accept any any any any
+default N/A N/A drop any any any any
+
+vyos@LEFT:~$
+```
diff --git a/docs/configexamples/pppoe-ipv6-basic.md b/docs/configexamples/pppoe-ipv6-basic.md
new file mode 100644
index 00000000..516a4b28
--- /dev/null
+++ b/docs/configexamples/pppoe-ipv6-basic.md
@@ -0,0 +1,114 @@
+---
+lastproofread: '2021-06-29'
+---
+
+(examples-pppoe-ipv6-basic)=
+
+# PPPoE IPv6 Basic Setup for Home Network
+
+This document is to describe a basic setup using PPPoE with DHCPv6-PD +
+SLAAC to construct a typical home network. The user can follow the steps
+described here to quickly setup a working network and use this as a starting
+point to further configure or fine-tune other settings.
+
+To achieve this, your ISP is required to support DHCPv6-PD. If you're not sure,
+please contact your ISP for more information.
+
+## Network Topology
+
+```{image} /_static/images/pppoe-ipv6-pd-diagram.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 60%
+```
+
+
+## Configurations
+
+### PPPoE Setup
+
+```none
+set interfaces pppoe pppoe0 authentication password <YOUR PASSWORD>
+set interfaces pppoe pppoe0 authentication user <YOUR USERNAME>
+set interfaces pppoe pppoe0 service-name <YOUR SERVICENAME>
+set interfaces pppoe pppoe0 source-interface 'eth0'
+```
+
+- Fill `password` and `user` with the credential provided by your ISP.
+- `service-name` can be an arbitrary string.
+
+### DHCPv6-PD Setup
+
+During address configuration, in addition to assigning an address to the WAN
+interface, ISP also provides a prefix to allow the router to configure addresses
+of LAN interface and other nodes connecting to LAN, which is called prefix
+delegation (PD).
+
+```none
+set interfaces pppoe pppoe0 ipv6 address autoconf
+set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1 address '100'
+```
+
+- Here we use the prefix to configure the address of eth1 (LAN) to form
+ `<prefix>::64`, where `64` is hexadecimal of address 100.
+
+<!-- list break -->
+
+- For home network users, most of time ISP only provides /64 prefix, hence
+ there is no need to set SLA ID and prefix length. See {ref}`pppoe-interface`
+ for more information.
+
+### Router Advertisement
+
+We need to enable router advertisement for LAN network so that PC can receive
+the prefix and use SLAAC to configure the address automatically.
+
+```none
+set service router-advert interface eth1 link-mtu '1492'
+set service router-advert interface eth1 name-server <NAME SERVER>
+set service router-advert interface eth1 prefix ::/64 valid-lifetime '172800'
+```
+
+- Set MTU in advertisement to 1492 because of PPPoE header overhead.
+- Set DNS server address in the advertisement so that clients can obtain it by
+ using RDNSS option. Most operating systems (Windows, Linux, Mac) should
+ already support it.
+- Here we set the prefix to `::/64` to indicate advertising any /64 prefix
+ the LAN interface is assigned.
+- Since some ISPs disconnects continuous connection for every 2~3 days, we set
+ `valid-lifetime` to 2 days to allow PC for phasing out old address.
+
+### Basic Firewall
+
+To have basic protection while keeping IPv6 network functional, we need to:
+- Allow all established and related traffic for router and LAN
+- Allow all icmpv6 packets for router and LAN
+- Allow DHCPv6 packets for router
+
+```none
+set firewall ipv6 name WAN_IN default-action 'drop'
+set firewall ipv6 name WAN_IN rule 10 action 'accept'
+set firewall ipv6 name WAN_IN rule 10 state established 'enable'
+set firewall ipv6 name WAN_IN rule 10 state related 'enable'
+set firewall ipv6 name WAN_IN rule 20 action 'accept'
+set firewall ipv6 name WAN_IN rule 20 protocol 'icmpv6'
+set firewall ipv6 name WAN_LOCAL default-action 'drop'
+set firewall ipv6 name WAN_LOCAL rule 10 action 'accept'
+set firewall ipv6 name WAN_LOCAL rule 10 state established 'enable'
+set firewall ipv6 name WAN_LOCAL rule 10 state related 'enable'
+set firewall ipv6 name WAN_LOCAL rule 20 action 'accept'
+set firewall ipv6 name WAN_LOCAL rule 20 protocol 'icmpv6'
+set firewall ipv6 name WAN_LOCAL rule 30 action 'accept'
+set firewall ipv6 name WAN_LOCAL rule 30 destination port '546'
+set firewall ipv6 name WAN_LOCAL rule 30 protocol 'udp'
+set firewall ipv6 name WAN_LOCAL rule 30 source port '547'
+set firewall ipv6 forward filter rule 10 action jump
+set firewall ipv6 forward filter rule 10 jump-target 'WAN_IN'
+set firewall ipv6 forward filter rule 10 inbound-interface name 'pppoe0'
+set firewall ipv6 input filter rule 10 action jump
+set firewall ipv6 input filter rule 10 jump-target 'WAN_LOCAL'
+set firewall ipv6 input filter rule 10 inbound-interface name 'pppoe0'
+```
+
+Note to allow the router to receive DHCPv6 response from ISP. We need to allow
+packets with source port 547 (server) and destination port 546 (client).
diff --git a/docs/configexamples/qos.md b/docs/configexamples/qos.md
new file mode 100644
index 00000000..bb6c4b45
--- /dev/null
+++ b/docs/configexamples/qos.md
@@ -0,0 +1,201 @@
+---
+lastproofread: '2023-02-18'
+---
+
+(examples-qos)=
+
+# QoS example
+
+## Configuration 'dcsp' and shaper using QoS
+
+In this case, we'll try to make a simple lab using QoS and the
+general ability of the VyOS system.
+We recommend you to go through the main article about
+[QoS](https://docs.vyos.io/en/latest/configuration/trafficpolicy/index.html)
+first.
+
+Using the general schema for example:
+
+```{image} /_static/images/qos1.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+We have four hosts on the local network 172.17.1.0/24. All hosts are
+labeled CS0 by default. We need to replace labels on all hosts except
+vpc8.
+We will replace the labels on the nearest router “VyOS3” using the IP
+addresses of the sources.
+
+- 172.17.1.2 CS0 -> CS4
+- 172.17.1.3 CS0 -> CS5
+- 172.17.1.4 CS0 -> CS6
+- 172.17.1.40 CS0 by default
+
+Next, we will replace only all CS4 labels on the “VyOS2” router.
+
+- CS4 -> CS5
+
+In the end, we will configure the traffic shaper using QoS mechanisms
+on the “VYOS2” router.
+
+## Configuration:
+
+Set IP addresses on all VPCs and a default gateway 172.17.1.1. We'll
+use in this case only static routes.
+On the VyOS3 router, we need to change the 'dscp' labels for the
+VPCs. To do this, we use this configuration.
+
+```none
+set interfaces ethernet eth0 address '10.1.1.100/24'
+set interfaces ethernet eth1 address '172.17.1.1/24'
+set protocols static route 0.0.0.0/0 next-hop 10.1.1.1
+set qos policy shaper vyos3 class 10 match ADDRESS10 ip source address '172.17.1.2/32'
+set qos policy shaper vyos3 class 10 set-dscp 'CS4'
+set qos policy shaper vyos3 class 20 match ADDRESS20 ip source address '172.17.1.3/32'
+set qos policy shaper vyos3 class 20 set-dscp 'CS5'
+set qos policy shaper vyos3 class 30 match ADDRESS20 ip source address '172.17.1.4/32'
+set qos policy shaper vyos3 class 30 set-dscp 'CS6'
+set qos policy shaper vyos3 default bandwidth '10%'
+set qos policy shaper vyos3 default ceiling '100%'
+set qos policy shaper vyos3 default priority '7'
+set qos policy shaper vyos3 default queue-type 'fair-queue'
+set qos interface eth0 egress 'vyos3'
+```
+
+Main rules:
+
+- ADDRESS10 change CS0 -> CS4 source 172.17.1.2/32
+- ADDRESS20 change CS0 -> CS5 source 172.17.1.3/32
+- ADDRESS30 change CS0 -> CS6 source 172.17.1.4/32
+
+Check the result
+
+```{image} /_static/images/qos2.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+Before the interface eth0 on router VyOS3
+
+```{image} /_static/images/qos3.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+After the interface eth0 on router VyOS3
+
+```{image} /_static/images/qos4.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+On the router, VyOS4 set all traffic as CS4. We have to configure the
+default class and class for changing all labels from CS0 to CS4
+
+```none
+set interfaces ethernet eth0 address '10.2.1.100/24'
+set protocols static route 0.0.0.0/0 next-hop 10.2.1.1
+set qos policy shaper vyos4 class 10 bandwidth '100%'
+set qos policy shaper vyos4 class 10 burst '15k'
+set qos policy shaper vyos4 class 10 match ALL ether protocol 'all'
+set qos policy shaper vyos4 class 10 queue-type 'fair-queue'
+set qos policy shaper vyos4 class 10 set-dscp 'CS4'
+set qos policy shaper vyos4 default bandwidth '10%'
+set qos policy shaper vyos4 default burst '15k'
+set qos policy shaper vyos4 default ceiling '100%'
+set qos policy shaper vyos4 default priority '7'
+set qos policy shaper vyos4 default queue-type 'fair-queue'
+ set qos interface eth0 egress 'vyos4'
+```
+
+Next on the router VyOS2 we will change labels on all incoming
+traffic only from CS4-> CS6
+
+```{image} /_static/images/qos5.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```none
+set interfaces ethernet eth0 address '10.1.1.1/24'
+set interfaces ethernet eth1 address '10.2.1.1/24'
+set interfaces ethernet eth2 address '10.9.9.1/24'
+set protocols static route 172.17.1.0/24 next-hop 10.1.1.100
+set qos policy shaper vyos2 class 10 bandwidth '100%'
+set qos policy shaper vyos2 class 10 burst '15k'
+set qos policy shaper vyos2 class 10 match VYOS2 ip dscp 'CS4'
+set qos policy shaper vyos2 class 10 queue-type 'fair-queue'
+set qos policy shaper vyos2 class 10 set-dscp 'CS5'
+set qos policy shaper vyos2 default bandwidth '100%'
+set qos policy shaper vyos2 default burst '15k'
+set qos policy shaper vyos2 default ceiling '100%'
+set qos policy shaper vyos2 default priority '7'
+set qos policy shaper vyos2 default queue-type 'fair-queue'
+ set qos interface eth2 egress 'vyos2'
+```
+
+```{image} /_static/images/qos6.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+- 172.17.1.2/24 CS0
+
+```{image} /_static/images/qos7.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+- 172.17.1.2/24 CS0 - > CS4
+
+```{image} /_static/images/qos8.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+- 172.17.1.2/24 CS4 - > CS5
+
+```{image} /_static/images/qos9.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+In the end, on the router “VyOS2” we will set outgoing bandwidth
+limits between the “VyOS3” and “VyOS1” routers. Let's set a limit for
+IP 10.1.1.100 = 5 Mbps(Tx). We will check the result of the work
+with the help of the “iPerf” utility.
+
+Set up bandwidth limits on the eth2 interface of the router “VyOS2”.
+
+```none
+vyos@vyos2# show qos policy shaper vyos2 class 20
+bandwidth 5mbit
+description "for VyOS3 eth0"
+match VyOS3 {
+ ip {
+ source {
+ address 10.1.1.100/32
+ }
+ }
+}
+```
+
+Check the result.
+
+```{image} /_static/images/qos10.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+As we see shaper is working and the traffic will not work over 5 Mbit/s.
diff --git a/docs/configexamples/segment-routing-isis.md b/docs/configexamples/segment-routing-isis.md
new file mode 100644
index 00000000..41ba2389
--- /dev/null
+++ b/docs/configexamples/segment-routing-isis.md
@@ -0,0 +1,277 @@
+---
+lastproofread: '2023-04-10'
+---
+
+(examples-segment-routing-isis)=
+
+# Segment-routing IS-IS example
+
+When utilizing VyOS in an environment with Cisco IOS-XR gear you can use this
+blue print as an initial setup to get MPLS ISIS-SR working between those two
+devices.The lab was build using {abbr}`EVE-NG (Emulated Virtual
+Environment NG)`.
+
+:::{figure} /_static/images/vyos-sr-isis.webp
+:alt: ISIS-SR network
+
+ISIS-SR example network
+:::
+
+The below configuration is used as example where we keep focus on
+VyOS-P1/VyOS-P2/XRv-P3 which we share the settings.
+
+## Configuration
+
+- VyOS-P1:
+
+```none
+set interfaces dummy dum0 address '192.0.2.1/32'
+set interfaces ethernet eth1 address '192.0.2.5/30'
+set interfaces ethernet eth1 mtu '8000'
+set interfaces ethernet eth3 address '192.0.2.21/30'
+set interfaces ethernet eth3 mtu '8000'
+set protocols isis interface dum0 passive
+set protocols isis interface eth1 network point-to-point
+set protocols isis interface eth3 network point-to-point
+set protocols isis level 'level-2'
+set protocols isis log-adjacency-changes
+set protocols isis metric-style 'wide'
+set protocols isis net '49.0000.0000.0000.0001.00'
+set protocols isis segment-routing maximum-label-depth '8'
+set protocols isis segment-routing prefix 192.0.2.1/32 index value '1'
+set protocols mpls interface 'eth1'
+set protocols mpls interface 'eth3'
+set system host-name 'P1-VyOS'
+```
+
+- XRv-P3:
+
+```none
+hostname P3-VyOS
+interface Loopback0
+ ipv4 address 192.0.2.3 255.255.255.255
+!
+interface GigabitEthernet0/0/0/1
+ mtu 8014
+ ipv4 address 192.0.2.6 255.255.255.252
+!
+interface GigabitEthernet0/0/0/2
+ mtu 8014
+ ipv4 address 192.0.2.18 255.255.255.252
+!
+router isis VyOS
+ is-type level-2-only
+ net 49.0000.0000.0000.0003.00
+ log adjacency changes
+ address-family ipv4 unicast
+ metric-style wide
+ segment-routing mpls
+ !
+ interface Loopback0
+ passive
+ address-family ipv4 unicast
+ prefix-sid index 3
+ !
+ !
+ interface GigabitEthernet0/0/0/1
+ point-to-point
+ address-family ipv4 unicast
+ !
+ !
+ interface GigabitEthernet0/0/0/2
+ point-to-point
+ address-family ipv4 unicast
+ !
+ !
+!
+```
+
+- VyOS-P2:
+
+```none
+set interfaces dummy dum0 address '192.0.2.2/32'
+set interfaces ethernet eth2 address '192.0.2.17/30'
+set interfaces ethernet eth2 mtu '8000'
+set interfaces ethernet eth3 address '192.0.2.26/30'
+set interfaces ethernet eth3 mtu '8000'
+set protocols isis interface dum0 passive
+set protocols isis interface eth2 network point-to-point
+set protocols isis interface eth3 network point-to-point
+set protocols isis level 'level-2'
+set protocols isis log-adjacency-changes
+set protocols isis metric-style 'wide'
+set protocols isis net '49.0000.0000.0000.0002.00'
+set protocols isis segment-routing maximum-label-depth '8'
+set protocols isis segment-routing prefix 192.0.2.2/32 index value '2'
+set protocols mpls interface 'eth2'
+set protocols mpls interface 'eth3'
+set system host-name 'P2-VyOS'
+```
+
+This gives us MPLS segment routing enabled and labels forwarding :
+
+```none
+vyos@P1-VyOS:~$ show mpls table
+Inbound Label Type Nexthop Outbound Label
+-----------------------------------------------------------------
+15000 SR (IS-IS) 192.0.2.6 implicit-null
+15001 SR (IS-IS) 192.0.2.22 implicit-null
+15002 SR (IS-IS) fe80::5200:ff:fe04:3 implicit-null
+16002 SR (IS-IS) 192.0.2.6 16002
+16003 SR (IS-IS) 192.0.2.6 implicit-null
+16011 SR (IS-IS) 192.0.2.22 implicit-null
+
+vyos@P2-VyOS:~$ show mpls table
+Inbound Label Type Nexthop Outbound Label
+-------------------------------------------------------
+15000 SR (IS-IS) 192.0.2.18 implicit-null
+16001 SR (IS-IS) 192.0.2.18 16001
+16003 SR (IS-IS) 192.0.2.18 implicit-null
+16011 SR (IS-IS) 192.0.2.18 16011
+
+RP/0/0/CPU0:P3-VyOS#show mpls forwarding
+Tue Mar 28 17:47:18.928 UTC
+Local Outgoing Prefix Outgoing Next Hop Bytes
+Label Label or ID Interface Switched
+------ ----------- ------------------ ------------ --------------- ------------
+16001 Pop SR Pfx (idx 1) Gi0/0/0/1 192.0.2.5 0
+16002 Pop SR Pfx (idx 2) Gi0/0/0/2 192.0.2.17 0
+16011 16011 SR Pfx (idx 11) Gi0/0/0/1 192.0.2.5 0
+24000 Pop SR Adj (idx 1) Gi0/0/0/1 192.0.2.5 0
+24001 Pop SR Adj (idx 3) Gi0/0/0/1 192.0.2.5 0
+24002 Pop SR Adj (idx 1) Gi0/0/0/2 192.0.2.17 0
+24003 Pop SR Adj (idx 3) Gi0/0/0/2 192.0.2.17 0
+```
+
+VyOS is able to check MSD per devices:
+
+```none
+vyos@P1-VyOS:~$ show isis segment-routing node
+Area VyOS:
+IS-IS L1 SR-Nodes:
+
+IS-IS L2 SR-Nodes:
+
+System ID SRGB SRLB Algorithm MSD
+---------------------------------------------------------------
+0000.0000.0001 16000 - 23999 15000 - 15999 SPF 8
+0000.0000.0002 16000 - 23999 15000 - 15999 SPF 8
+0000.0000.0003 16000 - 23999 0 - 4294967295 SPF 10
+0000.0000.0011 16000 - 23999 15000 - 15999 SPF 8
+
+vyos@P2-VyOS:~$ show isis segment-routing node
+Area VyOS:
+ IS-IS L1 SR-Nodes:
+
+ IS-IS L2 SR-Nodes:
+
+ System ID SRGB SRLB Algorithm MSD
+ ---------------------------------------------------------------
+ 0000.0000.0001 16000 - 23999 15000 - 15999 SPF 8
+ 0000.0000.0002 16000 - 23999 15000 - 15999 SPF 8
+ 0000.0000.0003 16000 - 23999 0 - 4294967295 SPF 10
+ 0000.0000.0011 16000 - 23999 15000 - 15999 SPF 8
+```
+
+Here is the routing tables showing the MPLS segment routing label operations:
+
+```none
+vyos@P1-VyOS:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I>* 192.0.2.2/32 [115/30] via 192.0.2.6, eth1, label 16002, weight 1, 1d03h18m
+I>* 192.0.2.3/32 [115/10] via 192.0.2.6, eth1, label implicit-null, weight 1, 1d03h18m
+I 192.0.2.4/30 [115/20] via 192.0.2.6, eth1 inactive, weight 1, 1d03h18m
+I>* 192.0.2.11/32 [115/20] via 192.0.2.22, eth3, label implicit-null, weight 1, 1d02h47m
+I>* 192.0.2.16/30 [115/20] via 192.0.2.6, eth1, weight 1, 1d03h18m
+I 192.0.2.20/30 [115/20] via 192.0.2.22, eth3 inactive, weight 1, 1d02h48m
+I>* 192.0.2.24/30 [115/30] via 192.0.2.6, eth1, weight 1, 1d03h18m
+
+
+vyos@P2-VyOS:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I>* 192.0.2.1/32 [115/30] via 192.0.2.18, eth2, label 16001, weight 1, 1d03h17m
+I>* 192.0.2.3/32 [115/10] via 192.0.2.18, eth2, label implicit-null, weight 1, 1d03h17m
+I>* 192.0.2.4/30 [115/20] via 192.0.2.18, eth2, weight 1, 1d03h17m
+I>* 192.0.2.11/32 [115/40] via 192.0.2.18, eth2, label 16011, weight 1, 1d02h47m
+I 192.0.2.16/30 [115/20] via 192.0.2.18, eth2 inactive, weight 1, 1d03h17m
+I>* 192.0.2.20/30 [115/30] via 192.0.2.18, eth2, weight 1, 1d03h17m
+
+RP/0/0/CPU0:P3-VyOS#show route isis
+Tue Mar 28 18:19:16.417 UTC
+
+i L2 192.0.2.1/32 [115/20] via 192.0.2.5, 1d03h, GigabitEthernet0/0/0/1
+i L2 192.0.2.2/32 [115/20] via 192.0.2.17, 1d03h, GigabitEthernet0/0/0/2
+i L2 192.0.2.11/32 [115/30] via 192.0.2.5, 1d02h, GigabitEthernet0/0/0/1
+i L2 192.0.2.20/30 [115/20] via 192.0.2.5, 1d03h, GigabitEthernet0/0/0/1
+i L2 192.0.2.24/30 [115/20] via 192.0.2.17, 1d03h, GigabitEthernet0/0/0/2
+```
+
+Information about prefix-sid and label-operation from VyOS
+
+```none
+vyos@P1-VyOS:~$ show isis route prefix-sid
+Area VyOS:
+IS-IS L2 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop SID Label Op.
+ ----------------------------------------------------------------------
+ 192.0.2.1/32 0 - - - -
+ 192.0.2.2/32 30 eth1 192.0.2.6 2 Swap(16002, 16002)
+ 192.0.2.3/32 10 eth1 192.0.2.6 3 Pop(16003)
+ 192.0.2.4/30 20 eth1 192.0.2.6 - -
+ 192.0.2.16/30 20 eth1 192.0.2.6 - -
+ 192.0.2.20/30 0 - - - -
+ 192.0.2.24/30 30 eth1 192.0.2.6 - -
+
+ vyos@P2-VyOS:~$ show isis route prefix-sid
+ Area VyOS:
+ IS-IS L2 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop SID Label Op.
+ -----------------------------------------------------------------------
+ 192.0.2.1/32 30 eth2 192.0.2.18 1 Swap(16001, 16001)
+ 192.0.2.2/32 0 - - - -
+ 192.0.2.3/32 10 eth2 192.0.2.18 3 Pop(16003)
+ 192.0.2.4/30 20 eth2 192.0.2.18 - -
+ 192.0.2.16/30 20 eth2 192.0.2.18 - -
+ 192.0.2.20/30 30 eth2 192.0.2.18 - -
+ 192.0.2.24/30 0 - - - -
+```
+
+Ping between VyOS-P1 / VyOS-P2 to confirm reachability:
+
+```none
+vyos@P1-VyOS:~$ ping 192.0.2.2 source-address 192.0.2.1
+PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
+64 bytes from 192.0.2.2: icmp_seq=1 ttl=63 time=3.47 ms
+64 bytes from 192.0.2.2: icmp_seq=2 ttl=63 time=2.06 ms
+64 bytes from 192.0.2.2: icmp_seq=3 ttl=63 time=3.90 ms
+64 bytes from 192.0.2.2: icmp_seq=4 ttl=63 time=3.87 ms
+^C
+--- 192.0.2.2 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3004ms
+rtt min/avg/max/mdev = 2.064/3.326/3.903/0.748 ms
+
+vyos@P2-VyOS:~$ ping 192.0.2.1 source-address 192.0.2.2
+PING 192.0.2.1 (192.0.2.1) from 192.0.2.2 : 56(84) bytes of data.
+64 bytes from 192.0.2.1: icmp_seq=1 ttl=63 time=2.91 ms
+64 bytes from 192.0.2.1: icmp_seq=2 ttl=63 time=3.23 ms
+64 bytes from 192.0.2.1: icmp_seq=3 ttl=63 time=2.91 ms
+64 bytes from 192.0.2.1: icmp_seq=4 ttl=63 time=2.85 ms
+^C
+--- 192.0.2.1 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3005ms
+rtt min/avg/max/mdev = 2.846/2.972/3.231/0.151 ms
+```
diff --git a/docs/configexamples/site-2-site-cisco.md b/docs/configexamples/site-2-site-cisco.md
new file mode 100644
index 00000000..2a2fb7a1
--- /dev/null
+++ b/docs/configexamples/site-2-site-cisco.md
@@ -0,0 +1,170 @@
+(examples-site-2-site-cisco)=
+
+# Site-to-Site IPSec VPN to Cisco using FlexVPN
+
+This guide shows a sample configuration for FlexVPN site-to-site Internet
+Protocol Security (IPsec)/Generic Routing Encapsulation (GRE) tunnel.
+
+FlexVPN is a newer "solution" for deployment of VPNs and it utilizes IKEv2 as
+the key exchange protocol. The result is a flexible and scalable VPN solution
+that can be easily adapted to fit various network needs. It can also support a
+variety of encryption methods, including AES and 3DES.
+
+The lab was built using EVE-NG.
+
+## Configuration
+
+### VyOS
+
+- GRE:
+
+```none
+set interfaces tunnel tun1 encapsulation 'gre'
+set interfaces tunnel tun1 ip adjust-mss '1336'
+set interfaces tunnel tun1 mtu '1376'
+set interfaces tunnel tun1 remote '10.1.1.6'
+set interfaces tunnel tun1 source-address '198.51.100.1'
+```
+
+- IPsec:
+
+```none
+set vpn ipsec authentication psk vyos_cisco_l id 'vyos.net’
+set vpn ipsec authentication psk vyos_cisco_l id 'cisco.hub.net'
+set vpn ipsec authentication psk vyos_cisco_l secret 'secret'
+set vpn ipsec esp-group e1 lifetime '3600'
+set vpn ipsec esp-group e1 mode 'tunnel'
+set vpn ipsec esp-group e1 pfs 'disable'
+set vpn ipsec esp-group e1 proposal 1 encryption 'aes128'
+set vpn ipsec esp-group e1 proposal 1 hash 'sha256'
+set vpn ipsec ike-group i1 key-exchange 'ikev2'
+set vpn ipsec ike-group i1 lifetime '28800'
+set vpn ipsec ike-group i1 proposal 1 dh-group '5'
+set vpn ipsec ike-group i1 proposal 1 encryption 'aes256'
+set vpn ipsec ike-group i1 proposal 1 hash 'sha256'
+set vpn ipsec interface 'eth2'
+set vpn ipsec options disable-route-autoinstall
+set vpn ipsec options flexvpn
+set vpn ipsec options interface 'tun1'
+set vpn ipsec options virtual-ip
+set vpn ipsec site-to-site peer cisco_hub authentication local-id 'vyos.net'
+set vpn ipsec site-to-site peer cisco_hub authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer cisco_hub authentication remote-id 'cisco.hub.net'
+set vpn ipsec site-to-site peer cisco_hub connection-type 'initiate'
+set vpn ipsec site-to-site peer cisco_hub default-esp-group 'e1'
+set vpn ipsec site-to-site peer cisco_hub ike-group 'i1'
+set vpn ipsec site-to-site peer cisco_hub local-address '198.51.100.1'
+set vpn ipsec site-to-site peer cisco_hub remote-address '10.1.1.6'
+set vpn ipsec site-to-site peer cisco_hub tunnel 1 local prefix '198.51.100.1/32'
+set vpn ipsec site-to-site peer cisco_hub tunnel 1 protocol 'gre'
+set vpn ipsec site-to-site peer cisco_hub tunnel 1 remote prefix '10.1.1.6/32'
+set vpn ipsec site-to-site peer cisco_hub virtual-address '0.0.0.0'
+```
+
+
+### Cisco
+
+```none
+aaa new-model
+!
+!
+aaa authorization network default local
+!
+crypto ikev2 name-mangler GET_DOMAIN
+ fqdn all
+ email all
+!
+!
+crypto ikev2 authorization policy vyos
+ pool mypool
+ aaa attribute list mylist
+ route set interface
+ route accept any tag 100 distance 5
+!
+crypto ikev2 keyring mykeys
+ peer peer1
+ identity fqdn vyos.net
+ pre-shared-key local secret
+ pre-shared-key remote secret
+crypto ikev2 profile my_profile
+ match identity remote fqdn vyos.net
+ identity local fqdn cisco.hub.net
+ authentication remote pre-share
+ authentication local pre-share
+ keyring local mykeys
+ dpd 10 3 periodic
+ aaa authorization group psk list local name-mangler GET_DOMAIN
+ aaa authorization user psk cached
+ virtual-template 1
+!
+!
+!
+crypto ipsec transform-set TSET esp-aes esp-sha256-hmac
+ mode tunnel
+!
+!
+crypto ipsec profile my-ipsec-profile
+ set transform-set TSET
+ set ikev2-profile my_profile
+!
+interface Virtual-Template1 type tunnel
+ no ip address
+ ip mtu 1376
+ ip nhrp network-id 1
+ ip nhrp shortcut virtual-template 1
+ ip tcp adjust-mss 1336
+ tunnel path-mtu-discovery
+ tunnel protection ipsec profile my-ipsec-profile
+ !
+ ip local pool my_pool 172.16.122.1 172.16.122.254
+```
+
+Since the tunnel is a point-to-point GRE tunnel, it behaves like any other
+point-to-point interface (for example: serial, dialer), and it is possible to
+run any Interior Gateway Protocol (IGP)/Exterior Gateway Protocol (EGP) over
+the link in order to exchange routing information
+
+## Verification
+
+```none
+vyos@vyos$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 - u/u
+eth1 - u/u
+eth2 198.51.100.1/24 u/u
+eth3 172.16.1.2/24 u/u
+lo 127.0.0.1/8 u/u
+ ::1/128
+tun1 172.16.122.2/32 u/u
+
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------------ ------- -------- -------------- ---------------- ---------------- --------------------- -----------------------------
+cisco_hub-tunnel-1 up 44m17s 35K/31K 382/367 10.1.1.6 cisco.hub.net AES_CBC_128/HMAC_SHA2_256_128
+
+
+Hub#sh crypto ikev2 sa detailed
+ IPv4 Crypto IKEv2 SA
+
+Tunnel-id Local Remote fvrf/ivrf Status
+5 10.1.1.6/4500 198.51.100.1/4500 none/none READY
+ Encr: AES-CBC, keysize: 256, PRF: SHA256, Hash: SHA256, DH Grp:5, Auth sign: PSK, Auth verify: PSK
+ Life/Active Time: 86400/2694 sec
+ CE id: 0, Session-id: 2
+ Status Description: Negotiation done
+ Local spi: C94EE2DC92A60C47 Remote spi: 9AF0EF151BECF14C
+ Local id: cisco.hub.net
+ Remote id: vyos.net
+ Local req msg id: 269 Remote req msg id: 0
+ Local next msg id: 269 Remote next msg id: 0
+ Local req queued: 269 Remote req queued: 0
+ Local window: 5 Remote window: 1
+ DPD configured for 10 seconds, retry 3
+ Fragmentation not configured.
+ Extended Authentication not configured.
+ NAT-T is not detected
+ Cisco Trust Security SGT is disabled
+ Assigned host addr: 172.16.122.2
+```
diff --git a/docs/configexamples/wan-load-balancing.md b/docs/configexamples/wan-load-balancing.md
new file mode 100644
index 00000000..5671c515
--- /dev/null
+++ b/docs/configexamples/wan-load-balancing.md
@@ -0,0 +1,179 @@
+---
+lastproofread: '2021-06-29'
+---
+
+(wan-load-balancing)=
+
+
+# WAN Load Balancer examples
+
+## Example 1: Distributing load evenly
+
+The setup used in this example is shown in the following diagram:
+
+```{image} /_static/images/Wan_load_balancing1.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+
+### Overview
+
+> - All traffic coming in through eth2 is balanced between eth0 and eth1
+> on the router.
+> - Pings will be sent to four targets for health testing (33.44.55.66,
+> 44.55.66.77, 55.66.77.88 and 66.77.88.99).
+> - All outgoing packets are assigned the source address of the assigned
+> interface (SNAT).
+> - eth0 is set to be removed from the load balancer's interface pool
+> after 5 ping failures, eth1 will be removed after 4 ping failures.
+
+### Create static routes to ping targets
+
+Create static routes through the two ISPs towards the ping targets and
+commit the changes:
+
+```none
+set protocols static route 33.44.55.66/32 next-hop 11.22.33.1
+set protocols static route 44.55.66.77/32 next-hop 11.22.33.1
+set protocols static route 55.66.77.88/32 next-hop 22.33.44.1
+set protocols static route 66.77.88.99/32 next-hop 22.33.44.1
+```
+
+
+### Configure the load balancer
+
+Configure the WAN load balancer with the parameters described above:
+
+```none
+set load-balancing wan interface-health eth0 failure-count 5
+set load-balancing wan interface-health eth0 nexthop 11.22.33.1
+set load-balancing wan interface-health eth0 test 10 type ping
+set load-balancing wan interface-health eth0 test 10 target 33.44.55.66
+set load-balancing wan interface-health eth0 test 20 type ping
+set load-balancing wan interface-health eth0 test 20 target 44.55.66.77
+set load-balancing wan interface-health eth1 failure-count 4
+set load-balancing wan interface-health eth1 nexthop 22.33.44.1
+set load-balancing wan interface-health eth1 test 10 type ping
+set load-balancing wan interface-health eth1 test 10 target 55.66.77.88
+set load-balancing wan interface-health eth1 test 20 type ping
+set load-balancing wan interface-health eth1 test 20 target 66.77.88.99
+set load-balancing wan rule 10 inbound-interface eth2
+set load-balancing wan rule 10 interface eth0
+set load-balancing wan rule 10 interface eth1
+```
+
+
+## Example 2: Failover based on interface weights
+
+This example uses the failover mode.
+(wan-example2-overview)=
+
+### Overview
+
+In this example, eth0 is the primary interface and eth1 is the secondary
+interface. To provide simple failover functionality. If eth0 fails, eth1
+takes over.
+
+### Create interface weight based configuration
+
+The configuration steps are the same as in the previous example, except
+rule 10. So we keep the configuration, remove rule 10 and add a new rule
+for the failover mode:
+
+```none
+delete load-balancing wan rule 10
+set load-balancing wan rule 10 failover
+set load-balancing wan rule 10 inbound-interface eth2
+set load-balancing wan rule 10 interface eth0 weight 10
+set load-balancing wan rule 10 interface eth1 weight 1
+```
+
+
+## Example 3: Failover based on rule order
+
+The previous example used the failover command to send traffic through
+eth1 if eth0 fails. In this example, failover functionality is provided
+by rule order.
+(wan-example3-overview)=
+
+### Overview
+
+Two rules will be created, the first rule directs traffic coming in
+from eth2 to eth0 and the second rule directs the traffic to eth1. If
+eth0 fails the first rule is bypassed and the second rule matches,
+directing traffic to eth1.
+
+### Create rule order based configuration
+
+We keep the configuration from the previous example, delete rule 10
+and create the two new rules as described:
+
+```none
+delete load-balancing wan rule 10
+set load-balancing wan rule 10 inbound-interface eth2
+set load-balancing wan rule 10 interface eth0
+set load-balancing wan rule 20 inbound-interface eth2
+set load-balancing wan rule 20 interface eth1
+```
+
+
+## Example 4: Failover based on rule order - priority traffic
+
+A rule order for prioritizing traffic is useful in scenarios where the
+secondary link has a lower speed and should only carry high priority
+traffic. It is assumed for this example that eth1 is connected to a
+slower connection than eth0 and should prioritize VoIP traffic.
+(wan-example4-overview)=
+
+### Overview
+
+A rule order for prioritizing traffic is useful in scenarios where the
+secondary link has a lower speed and should only carry high priority
+traffic. It is assumed for this example that eth1 is connected to a
+slower connection than eth0 and should prioritize VoIP traffic.
+
+### Create rule order based configuration with low speed secondary link
+
+We keep the configuration from the previous example, delete rule 20 and
+create a new rule as described:
+
+```none
+delete load-balancing wan rule 20
+set load-balancing wan rule 20 inbound-interface eth2
+set load-balancing wan rule 20 interface eth1
+set load-balancing wan rule 20 destination port sip
+set load-balancing wan rule 20 protocol tcp
+set protocols static route 0.0.0.0/0 next-hop 11.22.33.1
+```
+
+
+## Example 5: Exclude traffic from load balancing
+
+In this example two LAN interfaces exist in different subnets instead
+of one like in the previous examples:
+
+```{image} /_static/images/Wan_load_balancing_exclude1.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+
+### Adding a rule for the second interface
+
+Based on the previous example, another rule for traffic from the second
+interface eth3 can be added to the load balancer. However, traffic meant
+to flow between the LAN subnets will be sent to eth0 and eth1 as well.
+To prevent this, another rule is required. This rule excludes traffic
+between the local subnets from the load balancer. It also excludes
+locally-sources packets (required for web caching with load balancing).
+eth+ is used as an alias that refers to all ethernet interfaces:
+
+```none
+set load-balancing wan rule 5 exclude
+set load-balancing wan rule 5 inbound-interface eth+
+set load-balancing wan rule 5 destination address 10.0.0.0/8
+```
+
diff --git a/docs/configexamples/zone-policy.md b/docs/configexamples/zone-policy.md
new file mode 100644
index 00000000..74654a71
--- /dev/null
+++ b/docs/configexamples/zone-policy.md
@@ -0,0 +1,416 @@
+---
+lastproofread: '2024-06-14'
+---
+
+(examples-zone-policy)=
+
+# Zone-Policy example
+
+:::{note}
+In {vytask}`T2199` the syntax of the zone configuration was changed.
+The zone configuration moved from `zone-policy zone <name>` to `firewall
+zone <name>`.
+:::
+
+## Native IPv4 and IPv6
+
+We have three networks.
+
+```none
+WAN - 172.16.10.0/24, 2001:0DB8:0:9999::0/64
+LAN - 192.168.100.0/24, 2001:0DB8:0:AAAA::0/64
+DMZ - 192.168.200.0/24, 2001:0DB8:0:BBBB::0/64
+```
+
+**This specific example is for a router on a stick, but is very easily
+adapted for however many NICs you have**:
+
+- Internet - 192.168.200.100 - TCP/80
+- Internet - 192.168.200.100 - TCP/443
+- Internet - 192.168.200.100 - TCP/25
+- Internet - 192.168.200.100 - TCP/53
+- VyOS acts as DHCP, DNS forwarder, NAT, router and firewall.
+- 192.168.200.200/2001:0DB8:0:BBBB::200 is an internal/external DNS, web
+ and mail (SMTP/IMAP) server.
+- 192.168.100.10/2001:0DB8:0:AAAA::10 is the administrator's console. It
+ can SSH to VyOS.
+- LAN and DMZ hosts have basic outbound access: Web, FTP, SSH.
+- LAN can access DMZ resources.
+- DMZ cannot access LAN resources.
+- Inbound WAN connect to DMZ host.
+
+```{image} /_static/images/zone-policy-diagram.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+The VyOS interface is assigned the .1/:1 address of their respective
+networks. WAN is on VLAN 10, LAN on VLAN 20, and DMZ on VLAN 30.
+
+It will look something like this:
+
+```none
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ hw-id 00:53:ed:6e:2a:92
+ smp_affinity auto
+ speed auto
+ vif 10 {
+ address 172.16.10.1/24
+ address 2001:db8:0:9999::1/64
+ }
+ vif 20 {
+ address 192.168.100.1/24
+ address 2001:db8:0:AAAA::1/64
+ }
+ vif 30 {
+ address 192.168.200.1/24
+ address 2001:db8:0:BBBB::1/64
+ }
+ }
+ loopback lo {
+ }
+}
+```
+
+
+## Zones Basics
+
+Each interface is assigned to a zone. The interface can be physical or
+virtual such as tunnels (VPN, PPTP, GRE, etc) and are treated exactly
+the same.
+
+Traffic flows from zone A to zone B. That flow is what I refer to as a
+zone-pair-direction. eg. A->B and B->A are two zone-pair-destinations.
+
+Ruleset are created per zone-pair-direction.
+
+I name rule sets to indicate which zone-pair-direction they represent.
+eg. ZoneA-ZoneB or ZoneB-ZoneA. LAN-DMZ, DMZ-LAN.
+
+In VyOS, you have to have unique Ruleset names. In the event of overlap,
+I add a "-6" to the end of v6 rulesets. eg. LAN-DMZ, LAN-DMZ-6. This
+allows for each auto-completion and uniqueness.
+
+In this example we have 4 zones. LAN, WAN, DMZ, Local. The local zone is
+the firewall itself.
+
+If your computer is on the LAN and you need to SSH into your VyOS box,
+you would need a rule to allow it in the LAN-Local ruleset. If you want
+to access a webpage from your VyOS box, you need a rule to allow it in
+the Local-LAN ruleset.
+
+In rules, it is good to keep them named consistently. As the number of
+rules you have grows, the more consistency you have, the easier your
+life will be.
+
+```none
+Rule 1 - State Established, Related
+Rule 2 - State Invalid
+Rule 100 - ICMP
+Rule 200 - Web
+Rule 300 - FTP
+Rule 400 - NTP
+Rule 500 - SMTP
+Rule 600 - DNS
+Rule 700 - DHCP
+Rule 800 - SSH
+Rule 900 - IMAPS
+```
+
+The first two rules are to deal with the idiosyncrasies of VyOS and
+iptables.
+
+Zones and Rulesets both have a default action statement. When using
+Zone-Policies, the default action is set by the zone-policy statement
+and is represented by rule 10000.
+
+It is good practice to log both accepted and denied traffic. It can save
+you significant headaches when trying to troubleshoot a connectivity
+issue.
+
+To add logging to the default rule, do:
+
+```none
+set firewall name <ruleSet> default-log
+```
+
+By default, iptables does not allow traffic for established sessions to
+return, so you must explicitly allow this. I do this by adding two rules
+to every ruleset. 1 allows established and related state packets through
+and rule 2 drops and logs invalid state packets. We place the
+established/related rule at the top because the vast majority of traffic
+on a network is established and the invalid rule to prevent invalid
+state packets from mistakenly being matched against other rules. Having
+the most matched rule listed first reduces CPU load in high volume
+environments. Note: I have filed a bug to have this added as a default
+action as well.
+
+''It is important to note, that you do not want to add logging to the
+established state rule as you will be logging both the inbound and
+outbound packets for each session instead of just the initiation of the
+session. Your logs will be massive in a very short period of time.''
+
+In VyOS you must have the interfaces created before you can apply it to
+the zone and the rulesets must be created prior to applying it to a
+zone-policy.
+
+I create/configure the interfaces first. Build out the rulesets for each
+zone-pair-direction which includes at least the three state rules. Then
+I setup the zone-policies.
+
+Zones do not allow for a default action of accept; either drop or
+reject. It is important to remember this because if you apply an
+interface to a zone and commit, any active connections will be dropped.
+Specifically, if you are SSH’d into VyOS and add local or the interface
+you are connecting through to a zone and do not have rulesets in place
+to allow SSH and established sessions, you will not be able to connect.
+
+The following are the rules that were created for this example (may not
+be complete), both in IPv4 and IPv6. If there is no IP specified, then
+the source/destination address is not explicit.
+
+```none
+WAN - DMZ:192.168.200.200 - tcp/80
+WAN - DMZ:192.168.200.200 - tcp/443
+WAN - DMZ:192.168.200.200 - tcp/25
+WAN - DMZ:192.168.200.200 - tcp/53
+WAN - DMZ:2001:0DB8:0:BBBB::200 - tcp/80
+WAN - DMZ:2001:0DB8:0:BBBB::200 - tcp/443
+WAN - DMZ:2001:0DB8:0:BBBB::200 - tcp/25
+WAN - DMZ:2001:0DB8:0:BBBB::200 - tcp/53
+
+DMZ - Local - tcp/53
+DMZ - Local - tcp/123
+DMZ - Local - tcp/67,68
+
+LAN - Local - tcp/53
+LAN - Local - tcp/123
+LAN - Local - tcp/67,68
+LAN:192.168.100.10 - Local - tcp/22
+LAN:2001:0DB8:0:AAAA::10 - Local - tcp/22
+
+LAN - WAN - tcp/80
+LAN - WAN - tcp/443
+LAN - WAN - tcp/22
+LAN - WAN - tcp/20,21
+
+DMZ - WAN - tcp/80
+DMZ - WAN - tcp/443
+DMZ - WAN - tcp/22
+DMZ - WAN - tcp/20,21
+DMZ - WAN - tcp/53
+DMZ - WAN - udp/53
+
+Local - WAN - tcp/80
+Local - WAN - tcp/443
+Local - WAN - tcp/20,21
+
+Local - DMZ - tcp/25
+Local - DMZ - tcp/67,68
+Local - DMZ - tcp/53
+Local - DMZ - udp/53
+
+Local - LAN - tcp/67,68
+
+LAN - DMZ - tcp/80
+LAN - DMZ - tcp/443
+LAN - DMZ - tcp/993
+LAN:2001:0DB8:0:AAAA::10 - DMZ:2001:0DB8:0:BBBB::200 - tcp/22
+LAN:192.168.100.10 - DMZ:192.168.200.200 - tcp/22
+```
+
+Since we have 4 zones, we need to setup the following rulesets.
+
+```none
+Lan-wan
+Lan-local
+Lan-dmz
+Wan-lan
+Wan-local
+Wan-dmz
+Local-lan
+Local-wan
+Local-dmz
+Dmz-lan
+Dmz-wan
+Dmz-local
+```
+
+Even if the two zones will never communicate, it is a good idea to
+create the zone-pair-direction rulesets and set default-log. This
+will allow you to log attempts to access the networks. Without it, you
+will never see the connection attempts.
+
+This is an example of the three base rules.
+
+```none
+name wan-lan {
+ default-action drop
+ default-log
+ rule 1 {
+ action accept
+ state {
+ established enable
+ related enable
+ }
+ }
+ rule 2 {
+ action drop
+ log enable
+ state {
+ invalid enable
+ }
+ }
+}
+```
+
+Here is an example of an IPv6 DMZ-WAN ruleset.
+
+```none
+ipv6-name dmz-wan-6 {
+ default-action drop
+ default-log
+ rule 1 {
+ action accept
+ state {
+ established enable
+ related enable
+ }
+ }
+ rule 2 {
+ action drop
+ log enable
+ state {
+ invalid enable
+ }
+ rule 100 {
+ action accept
+ log enable
+ protocol ipv6-icmp
+ }
+ rule 200 {
+ action accept
+ destination {
+ port 80,443
+ }
+ log enable
+ protocol tcp
+ }
+ rule 300 {
+ action accept
+ destination {
+ port 20,21
+ }
+ log enable
+ protocol tcp
+ }
+ rule 500 {
+ action accept
+ destination {
+ port 25
+ }
+ log enable
+ protocol tcp
+ source {
+ address 2001:db8:0:BBBB::200
+ }
+ }
+ rule 600 {
+ action accept
+ destination {
+ port 53
+ }
+ log enable
+ protocol tcp_udp
+ source {
+ address 2001:db8:0:BBBB::200
+ }
+ }
+ rule 800 {
+ action accept
+ destination {
+ port 22
+ }
+ log enable
+ protocol tcp
+ }
+}
+```
+
+Once you have all of your rulesets built, then you need to create your
+zone-policy.
+
+Start by setting the interface and default action for each zone.
+
+```none
+set firewall zone dmz default-action drop
+set firewall zone dmz interface eth0.30
+```
+
+In this case, we are setting the v6 ruleset that represents traffic
+sourced from the LAN, destined for the DMZ. Because the zone-policy
+firewall syntax is a little awkward, I keep it straight by thinking of
+it backwards.
+
+```none
+set firewall zone dmz from lan firewall ipv6-name lan-dmz-6
+```
+
+DMZ-LAN policy is LAN-DMZ. You can get a rhythm to it when you build out
+a bunch at one time.
+
+In the end, you will end up with something like this config. I took out
+everything but the Firewall, Interfaces, and zone-policy sections. It is
+long enough as is.
+
+## IPv6 Tunnel
+
+If you are using a IPv6 tunnel from HE.net or someone else, the basis is
+the same except you have two WAN interfaces. One for v4 and one for v6.
+
+You would have 5 zones instead of just 4 and you would configure your v6
+ruleset between your tunnel interface and your LAN/DMZ zones instead of
+to the WAN.
+
+LAN, WAN, DMZ, local and TUN (tunnel)
+
+v6 pairs would be:
+
+```none
+lan-tun
+lan-local
+lan-dmz
+tun-lan
+tun-local
+tun-dmz
+local-lan
+local-tun
+local-dmz
+dmz-lan
+dmz-tun
+dmz-local
+```
+
+Notice, none go to WAN since WAN wouldn't have a v6 address on it.
+
+You would have to add a couple of rules on your wan-local ruleset to
+allow protocol 41 in.
+
+Something like:
+
+```none
+rule 400 {
+ action accept
+ destination {
+ address 172.16.10.1
+ }
+ log enable
+ protocol 41
+ source {
+ address ip.of.tunnel.broker
+ }
+}
+```
diff --git a/docs/configuration/container/index.md b/docs/configuration/container/index.md
new file mode 100644
index 00000000..6cb64225
--- /dev/null
+++ b/docs/configuration/container/index.md
@@ -0,0 +1,479 @@
+---
+lastproofread: '2024-07-03'
+---
+
+# Container
+
+The VyOS container implementation is based on [Podman](https://podman.io/) as
+a deamonless container engine.
+
+## Configuration
+
+```{cfgcmd} set container name \<name\> image
+
+Sets the image name in the hub registry
+
+:::{code-block} none
+set container name mysql-server image mysql:8.0
+:::
+
+If a registry is not specified, Docker.io will be used as the container
+registry unless an alternative registry is specified using
+`set container registry <name>` or the registry is included
+in the image name
+
+:::{code-block} none
+set container name mysql-server image quay.io/mysql:8.0
+:::
+```
+
+
+```{cfgcmd} set container name \<name\> entrypoint \<entrypoint\>
+
+Override the default entrypoint from the image for a container.
+```
+
+
+```{cfgcmd} set container name \<name\> command \<command\>
+
+Override the default command from the image for a container.
+```
+
+
+```{cfgcmd} set container name \<name\> arguments \<arguments\>
+
+Set the command arguments for a container.
+```
+
+
+```{cfgcmd} set container name \<name\> host-name \<hostname\>
+
+Set the host name for a container.
+```
+
+
+```{cfgcmd} set container name \<name\> allow-host-pid
+
+The container and the host share the same process namespace.
+This means that processes running on the host are visible inside the
+container, and processes inside the container are visible on the host.
+
+The command translates to "--pid host" when the container is created.
+```
+
+
+```{cfgcmd} set container name \<name\> allow-host-networks
+
+Allow host networking in a container. The network stack of the container is
+not isolated from the host and will use the host IP.
+
+The command translates to "--net host" when the container is created.
+
+:::{note}
+**allow-host-networks** cannot be used with **network**
+:::
+```
+
+
+```{cfgcmd} set container name \<name\> network \<networkname\>
+
+Attaches user-defined network to a container.
+Only one network must be specified and must already exist.
+```
+
+
+```{cfgcmd} set container name \<name\> network \<networkname\> address \<address\>
+
+Optionally set a specific static IPv4 or IPv6 address for the container.
+This address must be within the named network prefix.
+
+:::{note}
+The first IP in the container network is reserved by the
+engine and cannot be used
+:::
+```
+
+
+```{cfgcmd} set container name \<name\> name-server \<address\>
+
+Optionally set a custom name server.
+If a container network is used with DNS enabled,
+this setting will not have any effect.
+```
+
+
+```{cfgcmd} set container name \<name\> description \<text\>
+
+Set a container description
+```
+
+
+```{cfgcmd} set container name \<name\> environment \<key\> value \<value\>
+
+Add custom environment variables.
+Multiple environment variables are allowed.
+The following commands translate to "-e key=value" when the container
+is created.
+
+:::{code-block} none
+set container name mysql-server environment MYSQL_DATABASE value 'zabbix'
+set container name mysql-server environment MYSQL_USER value 'zabbix'
+set container name mysql-server environment MYSQL_PASSWORD value 'zabbix_pwd'
+set container name mysql-server environment MYSQL_ROOT_PASSWORD value 'root_pwd'
+:::
+```
+
+
+```{cfgcmd} set container name \<name\> port \<portname\> source \<portnumber\>
+
+```
+```{cfgcmd} set container name \<name\> port \<portname\> destination \<portnumber\>
+```
+
+```{cfgcmd} set container name \<name\> port \<portname\> protocol \<tcp | udp\>
+
+Publish a port for the container.
+
+:::{code-block} none
+set container name zabbix-web-nginx-mysql port http source 80
+set container name zabbix-web-nginx-mysql port http destination 8080
+set container name zabbix-web-nginx-mysql port http protocol tcp
+:::
+```
+:::{note}
+Port publishing cannot be used with **network**. For this purpose, a workaround
+using destination NAT and static IP assignment for the container is available.
+:::
+```{cfgcmd} set container name \<name\> volume \<volumename\> source \<path\>
+```
+
+```{cfgcmd} set container name \<name\> volume \<volumename\> destination \<path\>
+
+Mount a volume into the container
+
+:::{code-block} none
+set container name coredns volume 'corefile' source /config/coredns/Corefile
+set container name coredns volume 'corefile' destination /etc/Corefile
+:::
+```
+
+```{cfgcmd} set container name \<name\> volume \<volumename\> mode \<ro | rw\>
+
+Volume is either mounted as rw (read-write - default) or ro (read-only)
+```
+
+```{cfgcmd} set container name \<name\> tmpfs \<tmpfsname\> destination \<path\>
+
+Mount a tmpfs *(ramdisk)* filesystem to the given path within the container.
+```
+
+```{cfgcmd} set container name \<name\> tmpfs \<tmpfsname\> size \<MB\>
+
+Size in MB for tmpfs filesystem, maximum size is 64GB or 50% of the
+systems total available memory.
+```
+
+```{cfgcmd} set container name \<name\> uid \<number\>
+```
+
+```{cfgcmd} set container name \<name\> gid \<number\>
+
+Set the User ID or Group ID of the container
+```
+
+```{cfgcmd} set container name \<name\> restart [no | on-failure | always]
+
+Set the restart behavior of the container.
+
+- **no**: Do not restart containers on exit
+- **on-failure**: Restart containers when they exit with a non-zero
+exit code, retrying indefinitely (default)
+- **always**: Restart containers when they exit, regardless of status,
+retrying indefinitely
+```
+
+```{cfgcmd} set container name \<name\> cpu-quota \<num\>
+
+This specifies the number of CPU resources the container can use.
+
+Default is 0 for unlimited.
+For example, 1.25 limits the container to use up to 1.25 cores
+worth of CPU time.
+This can be a decimal number with up to three decimal places.
+
+The command translates to "--cpus=\<num\>" when the container is created.
+```
+
+```{cfgcmd} set container name \<name\> memory \<MB\>
+
+Constrain the memory available to the container.
+
+Default is 512 MB. Use 0 MB for unlimited memory.
+```
+
+```{cfgcmd} set container name \<name\> device \<devicename\> source \<path\>
+```
+
+```{cfgcmd} set container name \<name\> device \<devicename\> destination \<path\>
+
+Add a host device to the container.
+```
+
+```{cfgcmd} set container name \<name\> capability \<text\>
+
+Set container capabilities or permissions.
+
+- **net-admin**: Network operations (interface, firewall, routing tables)
+- **net-bind-service**: Bind a socket to privileged ports
+(port numbers less than 1024)
+- **net-raw**: Permission to create raw network sockets
+- **setpcap**: Capability sets (from bounded or inherited set)
+- **sys-admin**: Administration operations (quotactl, mount, sethostname,
+setdomainame)
+- **sys-time**: Permission to set system clock
+```
+
+```{cfgcmd} set container name \<name\> sysctl parameter \<parameter\> value \<value\>
+
+Set container sysctl values.
+
+The subset of possible parameters are:
+
+- Kernel Parameters: kernel.msgmax, kernel.msgmnb, kernel.msgmni, kernel.sem,
+kernel.shmall, kernel.shmmax, kernel.shmmni, kernel.shm_rmid_forced
+- Parameters beginning with fs.mqueue.*
+- Parameters beginning with net.* (only if user-defined network is used)
+```
+
+```{cfgcmd} set container name \<name\> label \<label\> value \<value\>
+
+Add metadata label for this container.
+```
+
+```{cfgcmd} set container name \<name\> disable
+
+Disable a container.
+```
+
+### Container Health checks
+
+
+By default, no health checks are run, even when defined by the image.
+
+```{cfgcmd} set container name \<name\> health-check
+
+Default health check is run for the container if defined by the image.
+```
+
+```{cfgcmd} set container name \<name\> health-check command \<command\>
+
+Override the default health check command from the image for a container.
+```
+
+```{cfgcmd} set container name \<name\> health check interval \<interval\>
+
+Override the default health-check interval. For example: `60`
+```
+
+```{cfgcmd} set container name \<name\> health check timeout \<timeout\>
+
+Override the default health-check timeout. For example: `10`
+```
+
+```{cfgcmd} set container name \<name\> health check retries \<retries\>
+
+Number of health check retries before container is considered unhealthy. For example: `1`
+```
+
+### Container Networks
+
+```{cfgcmd} set container network \<name\>
+
+Creates a named container network
+```
+
+```{cfgcmd} set container network \<name\> description
+
+A brief description what this network is all about.
+```
+
+```{cfgcmd} set container network \<name\> prefix \<ipv4|ipv6\>
+
+Define IPv4 and/or IPv6 prefix for a given network name.
+Both IPv4 and IPv6 can be used in parallel.
+```
+
+```{cfgcmd} set container network \<name\> mtu \<number\>
+
+Configure {abbr}`MTU (Maximum Transmission Unit)` for a given network. It
+is the size (in bytes) of the largest ethernet frame sent on this link.
+```
+
+```{cfgcmd} set container network \<name\> no-name-server
+
+Disable Domain Name System (DNS) plugin for this network.
+```
+
+```{cfgcmd} set container network \<name\> vrf \<nme\>
+
+Bind container network to a given VRF instance.
+```
+
+### Container Registry
+
+```{cfgcmd} set container registry \<name\>
+
+Adds registry to list of unqualified-search-registries. By default, for any
+image that does not include the registry in the image name, VyOS will use
+docker.io and quay.io as the container registry.
+```
+
+```{cfgcmd} set container registry \<name\> disable
+
+Disable a given container registry
+```
+
+```{cfgcmd} set container registry \<name\> authentication username
+```
+
+```{cfgcmd} set container registry \<name\> authentication password
+
+Some container registries require credentials to be used.
+
+Credentials can be defined here and will only be used when adding a
+container image to the system.
+```
+
+```{cfgcmd} set container registry \<name\> insecure
+
+Allow registry access over unencrypted HTTP or TLS connections with
+untrusted certificates.
+```
+
+```{cfgcmd} set container registry \<name\> mirror address \<address\>
+```
+
+```{cfgcmd} set container registry \<name\> mirror host-name \<host-name\>
+```
+
+```{cfgcmd} set container registry \<name\> mirror port \<port\>
+```
+
+```{cfgcmd} set container registry \<name\> mirror path \<path\>
+
+Registry mirror, use ``(host-name|address)[:port][/path]``.
+
+If you have mirror http://192.168.1.1:8080 for docker.io, you can use ``docker.io/some/repo`` or run ``podman pull docker.io/some/repo``
+
+:::{code-block} none
+set container registry docker.io mirror address 192.168.1.1
+set container registry docker.io mirror port 8080
+set container registry docker.io insecure
+:::
+If http://192.168.1.1:8080 is your own registry, you can use ``192.168.1.1:8080/some/repo`` or run ``podman pull 192.168.1.1:8080/some/repo``
+
+:::{code-block} none
+set container registry 192.168.1.1:8080 insecure
+:::
+```
+
+### Log Configuration
+
+```{cfgcmd} set container name \<name\> log-driver [k8s-file | journald | none]
+
+Set the default log driver for containers.
+
+- **k8s-file**: Log to a plain text file in Kubernetes-style format.
+- **journald**: Log to the system journal
+- **none**: Disable logging for the container
+
+Current default is journald.
+
+```
+
+## Operation Commands
+
+```{opcmd} add container image \<containername\>
+
+Pull a new image for container
+```
+```{opcmd} show container
+
+Show the list of all active containers.
+```
+```{opcmd} show container image
+
+Show the local container images.
+```
+```{opcmd} show container log \<containername\>
+
+Show logs from a given container
+```
+```{opcmd} show container network
+
+Show a list available container networks
+```
+```{opcmd} restart container \<containername\>
+
+Restart a given container
+```
+```{opcmd} update container image \<containername\>
+
+Update container image
+```
+```{opcmd} delete container image \<image id|all\> [force]
+
+Delete a particular container image based on it's image ID.
+You can also delete all container images at once.
+
+You can not delete a container image if it has more then one tag
+assigned, this is why there is a `force` option to pass down to
+the container image to also remove those images.
+```
+
+## Example Configuration
+
+For the sake of demonstration, [example #1 in the official documentation](https://www.zabbix.com/documentation/current/manual/installation/containers)
+to the declarative VyOS CLI syntax.
+
+```none
+set container network zabbix prefix 172.20.0.0/16
+set container network zabbix description 'Network for Zabbix component containers'
+
+set container name mysql-server image mysql:8.0
+set container name mysql-server network zabbix
+
+set container name mysql-server environment 'MYSQL_DATABASE' value 'zabbix'
+set container name mysql-server environment 'MYSQL_USER' value 'zabbix'
+set container name mysql-server environment 'MYSQL_PASSWORD' value 'zabbix_pwd'
+set container name mysql-server environment 'MYSQL_ROOT_PASSWORD' value 'root_pwd'
+
+set container name zabbix-java-gateway image zabbix/zabbix-java-gateway:alpine-5.2-latest
+set container name zabbix-java-gateway network zabbix
+
+set container name zabbix-server-mysql image zabbix/zabbix-server-mysql:alpine-5.2-latest
+set container name zabbix-server-mysql network zabbix
+
+set container name zabbix-server-mysql environment 'DB_SERVER_HOST' value 'mysql-server'
+set container name zabbix-server-mysql environment 'MYSQL_DATABASE' value 'zabbix'
+set container name zabbix-server-mysql environment 'MYSQL_USER' value 'zabbix'
+set container name zabbix-server-mysql environment 'MYSQL_PASSWORD' value 'zabbix_pwd'
+set container name zabbix-server-mysql environment 'MYSQL_ROOT_PASSWORD' value 'root_pwd'
+set container name zabbix-server-mysql environment 'ZBX_JAVAGATEWAY' value 'zabbix-java-gateway'
+
+set container name zabbix-server-mysql port zabbix source 10051
+set container name zabbix-server-mysql port zabbix destination 10051
+
+set container name zabbix-web-nginx-mysql image zabbix/zabbix-web-nginx-mysql:alpine-5.2-latest
+set container name zabbix-web-nginx-mysql network zabbix
+
+set container name zabbix-web-nginx-mysql environment 'MYSQL_DATABASE' value 'zabbix'
+set container name zabbix-web-nginx-mysql environment 'ZBX_SERVER_HOST' value 'zabbix-server-mysql'
+set container name zabbix-web-nginx-mysql environment 'DB_SERVER_HOST' value 'mysql-server'
+set container name zabbix-web-nginx-mysql environment 'MYSQL_USER' value 'zabbix'
+set container name zabbix-web-nginx-mysql environment 'MYSQL_PASSWORD' value 'zabbix_pwd'
+set container name zabbix-web-nginx-mysql environment 'MYSQL_ROOT_PASSWORD' value 'root_pwd'
+
+set container name zabbix-web-nginx-mysql port http source 80
+set container name zabbix-web-nginx-mysql port http destination 8080
+```
diff --git a/docs/configuration/firewall/bridge.md b/docs/configuration/firewall/bridge.md
new file mode 100644
index 00000000..58acd531
--- /dev/null
+++ b/docs/configuration/firewall/bridge.md
@@ -0,0 +1,685 @@
+---
+lastproofread: '2026-03-28'
+---
+
+(firewall-configuration)=
+
+# Bridge Firewall Configuration
+
+## Overview
+
+Learn more about bridge firewall configuration
+and related op-mode commands.
+
+The following commands are covered in this section:
+
+```{cfgcmd} set firewall bridge \<options\>
+```
+
+From the main structure defined in
+{doc}`Firewall Overview</configuration/firewall/index>`
+in this section you can find detailed information only for the next part
+of the general structure:
+
+```none
+- set firewall
+ * bridge
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ - prerouting
+ + filter
+ - name
+ + custom_name
+```
+
+Traffic that is received by the router on an interface that is a member of a
+bridge is processed on the **Bridge Layer**. Before the bridge decision is
+made, all packets are analyzed at **Prerouting**. First filters can be applied
+here, and also rules for ignoring connection tracking system can be configured.
+The relevant configuration that acts in **prerouting** is:
+
+
+- `set firewall bridge prerouting filter ...`.
+
+
+For traffic that needs to be switched internally by the bridge, the base
+chain is **forward**, and its base command for filtering is `set firewall
+bridge forward filter ...`, which happens in stage 4, highlighted with red
+color.
+
+
+:::{figure} /_static/images/firewall-bridge-forward.webp
+:::
+
+
+For traffic destined to the router itself or that needs to be routed
+(assuming a layer3 bridge is configured), the base chain is **input**, and the
+base command is `set firewall bridge input filter ...` and the path is:
+
+
+:::{figure} /_static/images/firewall-bridge-input.webp
+:::
+
+
+If it's not dropped, then the packet is sent to **IP Layer**, and will be
+processed by the **IP Layer** firewall: IPv4 or IPv6 ruleset. Check once again
+the {doc}`general packet flow diagram</configuration/firewall/index>` if
+needed.
+
+
+For traffic that originates from the bridge itself, the base chain is
+**output**, and the base command is `set firewall bridge output filter
+...`, and the path is:
+
+
+:::{figure} /_static/images/firewall-bridge-output.webp
+:::
+
+
+Custom bridge firewall chains can be created with the command `set firewall
+bridge name <name> ...`. To use such a custom chain, a rule with action jump
+and the appropriate target must be defined in a base chain.
+
+
+## Bridge Rules
+
+
+For firewall filtering, firewall rules need to be created. Each rule is
+numbered, has an action to apply if the rule is matched, and the ability
+to specify multiple matching criteria. Data packets go through the rules
+from 1 - 999999, so order is crucial. At the first match the action of the
+rule will be executed.
+
+
+### Actions
+
+
+If a rule is defined, an action must also be defined for it. This tells the
+firewall what to do if all matching criteria in the rule are met.
+
+
+In firewall bridge rules, the action can be:
+
+
+- `accept`: accept the packet.
+- `continue`: continue parsing next rule.
+- `drop`: drop the packet.
+- `jump`: jump to another custom chain.
+- `return`: Return from the current chain and continue at the next rule
+ of the last chain.
+- `queue`: Enqueue packet to userspace.
+- `notrack`: ignore connection tracking system. This action is only
+ available in prerouting chain.
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> action [accept | continue | drop | jump | queue | return]
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> action [accept | continue | drop | jump | queue | return]
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> action [accept | continue | drop | jump | queue | return]
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> action [accept | continue | drop | jump | notrack | queue | return]
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> action [accept | continue | drop | jump | queue | return]
+
+This required setting defines the action of the current rule. If action is
+set to jump, then jump-target is also needed.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> jump-target \<text\>
+
+If action is set to ``queue``, use next command to specify the queue
+target. Range is also supported:
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> queue \<0-65535\>
+
+Also, if action is set to ``queue``, use next command to specify the queue
+options. Possible options are ``bypass`` and ``fanout``:
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> queue-options fanout
+```
+
+Also, **default-action** is an action that takes place whenever a packet does
+not match any rule in its chain. For base chains, possible options for
+**default-action** are **accept** or **drop**.
+
+```{cfgcmd} set firewall bridge forward filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall bridge input filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall bridge output filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall bridge prerouting filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall bridge name \<name\> default-action [accept | continue | drop | jump | reject | return]
+
+This sets the default action of the rule-set if a packet does not match
+any of the rules in that chain. If default-action is set to ``jump``, then
+``default-jump-target`` is also needed. Note that for base chains, default
+action can only be set to ``accept`` or ``drop``, while on custom chains
+more actions are available.
+```
+
+```{cfgcmd} set firewall bridge name \<name\> default-jump-target \<text\>
+
+To be used only when ``default-action`` is set to ``jump``. Use this
+command to specify jump target for default rule.
+```
+:::{note}
+**Important note about default-actions:**
+If the default action for any base chain is not defined, then the default
+action is set to **accept** for that chain. For custom chains, if the
+default action is not defined, then the default-action is set to **drop**.
+:::
+
+
+### Firewall Logs
+
+
+You can enable logging for every firewall rule. If enabled, other log options
+can be configured.
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> log
+
+Enable logging for the matched packet. If this configuration command is not
+present, then the log is not enabled.
+```
+
+```{cfgcmd} set firewall bridge forward filter default-log
+```
+
+```{cfgcmd} set firewall bridge input filter default-log
+```
+
+```{cfgcmd} set firewall bridge output filter default-log
+```
+
+```{cfgcmd} set firewall bridge prerouting filter default-log
+```
+
+```{cfgcmd} set firewall bridge name \<name\> default-log
+
+Use this command to enable the logging of the default action on
+the specified chain.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Define log-level. Only applicable if rule log is enabled.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> log-options group \<0-65535\>
+
+Define the log group to send messages to. Only applicable if rule log is
+enabled.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> log-options snapshot-length \<0-9000\>
+
+Define length of packet payload to include in netlink message. Only
+applicable if rule log is enabled and the log group is defined.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> log-options queue-threshold \<0-65535\>
+
+Define the number of packets to queue inside the kernel before sending them
+to userspace. Only applicable if rule log is enabled and the log group is
+defined.
+```
+
+### Firewall Description
+
+
+You can define a description for reference for every custom chain.
+
+```{cfgcmd} set firewall bridge name \<name\> description \<text\>
+
+Provide a rule-set description to a custom firewall chain.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> description \<text\>
+
+Provide a description for each rule.
+```
+
+### Rule Status
+
+
+By default, when you define a rule, it is enabled. In some cases, it is
+useful to disable the rule instead of removing it.
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> disable
+
+Command for disabling a rule but keep it in the configuration.
+```
+
+### Matching criteria
+
+
+There are many matching criteria against which a packet can be tested. Refer
+to {doc}`IPv4</configuration/firewall/ipv4>` and
+{doc}`IPv6</configuration/firewall/ipv6>` matching criteria for more details.
+
+
+Since bridges operate at layer 2, both matchers for IPv4 and IPv6 are
+supported in bridge firewall configuration. Same applies to firewall groups.
+
+
+Same specific matching criteria that can be used in bridge firewall are
+described in this section:
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+
+Match based on the Ethernet type of the packet.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> vlan ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> vlan ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> vlan ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> vlan ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> vlan ethernet-type [802.1q | 802.1ad | arp | ipv4 | ipv6]
+
+Match based on the Ethernet type of the packet when it is VLAN tagged.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> vlan id \<0-4096\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> vlan id \<0-4096\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> vlan id \<0-4096\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> vlan id \<0-4096\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> vlan id \<0-4096\>
+
+Match based on VLAN identifier. Range is also supported.
+```
+
+```{cfgcmd} set firewall bridge forward filter rule \<1-999999\> vlan priority \<0-7\>
+```
+
+```{cfgcmd} set firewall bridge input filter rule \<1-999999\> vlan priority \<0-7\>
+```
+
+```{cfgcmd} set firewall bridge output filter rule \<1-999999\> vlan priority \<0-7\>
+```
+
+```{cfgcmd} set firewall bridge prerouting filter rule \<1-999999\> vlan priority \<0-7\>
+```
+
+```{cfgcmd} set firewall bridge name \<name\> rule \<1-999999\> vlan priority \<0-7\>
+
+Match based on VLAN priority (Priority Code Point - PCP). Range is also
+supported.
+```
+
+### Packet Modifications
+
+
+Starting from **VyOS-1.5-rolling-202410060007**, the firewall can modify
+packets before they are sent out. This feaure provides more flexibility in
+packet handling.
+
+```{cfgcmd} set firewall bridge [prerouting | forward | output] filter rule \<1-999999\> set dscp \<0-63\>
+
+Set a specific value of Differentiated Services Codepoint (DSCP).
+```
+
+```{cfgcmd} set firewall bridge [prerouting | forward | output] filter rule \<1-999999\> set mark \<1-2147483647\>
+
+Set a specific packet mark value.
+```
+
+```{cfgcmd} set firewall bridge [prerouting | forward | output] filter rule \<1-999999\> set tcp-mss \<500-1460\>
+
+Set the TCP-MSS (TCP maximum segment size) for the connection.
+```
+
+```{cfgcmd} set firewall bridge [prerouting | forward | output] filter rule \<1-999999\> set ttl \<0-255\>
+
+Set the TTL (Time to Live) value.
+```
+
+```{cfgcmd} set firewall bridge [prerouting | forward | output] filter rule \<1-999999\> set hop-limit \<0-255\>
+
+Set hop limit value.
+```
+
+```{cfgcmd} set firewall bridge [forward | output] filter rule \<1-999999\> set connection-mark \<0-2147483647\>
+
+Set connection mark value.
+```
+
+### Use IP firewall
+
+By default, for switched traffic, only the rules defined under `set firewall
+bridge` are applied. There are two global-options that can be configured in
+order to force deeper analysis of the packet on the IP layer. These options
+are:
+
+```{cfgcmd} set firewall global-options apply-to-bridged-traffic ipv4
+
+This command enables the IPv4 firewall for bridged traffic. If this option
+is used, packets are also parsed by rules defined in ``set firewall ipv4
+...``
+```
+
+```{cfgcmd} set firewall global-options apply-to-bridged-traffic ipv6
+
+This command enables the IPv6 firewall for bridged traffic. If this option
+is used, packets are also parsed by rules defined in ``set firewall ipv6
+...``
+```
+
+## Operation-mode Firewall
+### Rule-set overview
+
+In this section you can find all useful firewall op-mode commands.
+General commands for firewall configuration, counter and statistics:
+
+```{opcmd} show firewall
+```
+
+```{opcmd} show firewall summary
+```
+
+```{opcmd} show firewall statistics
+```
+
+And, to print only bridge firewall information:
+
+```{opcmd} show firewall bridge
+```
+
+```{opcmd} show firewall bridge forward filter
+```
+
+```{opcmd} show firewall bridge forward filter rule \<rule\>
+```
+
+```{opcmd} show firewall bridge name \<name\>
+```
+
+```{opcmd} show firewall bridge name \<name\> rule \<rule\>
+```
+
+### Show Firewall log
+
+```{opcmd} show log firewall
+```
+
+```{opcmd} show log firewall bridge
+```
+
+```{opcmd} show log firewall bridge forward
+```
+
+```{opcmd} show log firewall bridge forward filter
+```
+
+```{opcmd} show log firewall bridge name \<name\>
+```
+
+```{opcmd} show log firewall bridge forward filter rule \<rule\>
+```
+
+```{opcmd} show log firewall bridge name \<name\> rule \<rule\>
+
+Show the logs of all firewall; show all bridge firewall logs; show all logs
+for forward hook; show all logs for forward hook and priority filter; show
+all logs for particular custom chain; show logs for specific Rule-Set.
+```
+
+### Example
+
+Configuration example:
+
+```none
+set firewall bridge forward filter default-action 'drop'
+set firewall bridge forward filter default-log
+set firewall bridge forward filter rule 10 action 'continue'
+set firewall bridge forward filter rule 10 inbound-interface name 'eth2'
+set firewall bridge forward filter rule 10 vlan id '22'
+set firewall bridge forward filter rule 20 action 'drop'
+set firewall bridge forward filter rule 20 inbound-interface group 'TRUNK-RIGHT'
+set firewall bridge forward filter rule 20 vlan id '60'
+set firewall bridge forward filter rule 30 action 'jump'
+set firewall bridge forward filter rule 30 jump-target 'TEST'
+set firewall bridge forward filter rule 30 outbound-interface name '!eth1'
+set firewall bridge forward filter rule 35 action 'accept'
+set firewall bridge forward filter rule 35 vlan id '11'
+set firewall bridge forward filter rule 40 action 'continue'
+set firewall bridge forward filter rule 40 destination mac-address '66:55:44:33:22:11'
+set firewall bridge forward filter rule 40 source mac-address '11:22:33:44:55:66'
+set firewall bridge name TEST default-action 'accept'
+set firewall bridge name TEST default-log
+set firewall bridge name TEST rule 10 action 'continue'
+set firewall bridge name TEST rule 10 log
+set firewall bridge name TEST rule 10 vlan priority '0'
+```
+
+And op-mode commands:
+
+```none
+vyos@BRI:~$ show firewall bridge
+Rulesets bridge Information
+
+---------------------------------
+bridge Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ---------------------------------------------------------------------
+10 continue all 0 0 iifname "eth2" vlan id 22 continue
+20 drop all 0 0 iifname @I_TRUNK-RIGHT vlan id 60
+30 jump all 2130 170688 oifname != "eth1" jump NAME_TEST
+35 accept all 2080 168616 vlan id 11 accept
+40 continue all 0 0 ether daddr 66:55:44:33:22:11 ether saddr 11:22:33:44:55:66 continue
+default drop all 0 0
+
+---------------------------------
+bridge Firewall "name TEST"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- --------------------------------------------------
+10 continue all 2130 170688 vlan pcp 0 prefix "[bri-NAM-TEST-10-C]" continue
+default accept all 2130 170688
+
+vyos@BRI:~$
+vyos@BRI:~$ show firewall bridge name TEST
+Ruleset Information
+
+---------------------------------
+bridge Firewall "name TEST"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- --------------------------------------------------
+10 continue all 2130 170688 vlan pcp 0 prefix "[bri-NAM-TEST-10-C]" continue
+default accept all 2130 170688
+
+vyos@BRI:~$
+```
+
+Inspect logs:
+
+```none
+vyos@BRI:~$ show log firewall bridge
+Dec 05 14:37:47 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
+Dec 05 14:37:48 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
+Dec 05 14:37:49 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
+...
+vyos@BRI:~$ show log firewall bridge forward filter
+Dec 05 14:42:22 kernel: [bri-FWD-filter-default-D]IN=eth2 OUT=eth1 MAC=33:33:00:00:00:16:50:00:00:06:00:00:86:dd SRC=0000:0000:0000:0000:0000:0000:0000:0000 DST=ff02:0000:0000:0000:0000:0000:0000:0016 LEN=96 TC=0 HOPLIMIT=1 FLOWLBL=0 PROTO=ICMPv6 TYPE=143 CODE=0
+Dec 05 14:42:22 kernel: [bri-FWD-filter-default-D]IN=eth2 OUT=eth1 MAC=33:33:00:00:00:16:50:00:00:06:00:00:86:dd SRC=0000:0000:0000:0000:0000:0000:0000:0000 DST=ff02:0000:0000:0000:0000:0000:0000:0016 LEN=96 TC=0 HOPLIMIT=1 FLOWLBL=0 PROTO=ICMPv6 TYPE=143 CODE=0
+```
diff --git a/docs/configuration/firewall/flowtables.md b/docs/configuration/firewall/flowtables.md
new file mode 100644
index 00000000..24d0675e
--- /dev/null
+++ b/docs/configuration/firewall/flowtables.md
@@ -0,0 +1,176 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(firewall-flowtables-configuration)=
+
+# Flowtables Firewall Configuration
+
+```{include} /_include/need_improvement.txt
+```
+
+
+## Overview
+
+This section provides information on firewall configuration for flowtables.
+
+```{cfgcmd} set firewall flowtable ...
+```
+
+To learn about the general traffic flow in VyOS firewalls,
+see {doc}`Firewall </configuration/firewall/index>`.
+
+```none
+- set firewall
+ * flowtable
+ - custom_flow_table
+ + ...
+```
+
+Flowtables let you define a fastpath through the flowtable datapath.
+Flowtables support layer 3 (IPv4 and IPv6) and layer 4 (TCP and UDP)
+protocols.
+
+:::{figure} /_static/images/firewall-flowtable-packet-flow.webp
+:::
+
+After the first packet successfully traverses the IP forwarding path (black
+circles path), you can offload subsequent packets to the flowtable through your
+ruleset. You specify when to add a flow to the flowtable during forward
+filtering (red circle number 6).
+
+When a packet finds a matching entry in the flowtable (flowtable hit), the
+system transmits it to the output netdevice. This means packets bypass the
+classic IP forwarding path and use the **Fast Path** (orange circles path).
+As a result, you do not see these packets from any Netfilter hooks after
+ingress. If no matching entry exists in the flowtable (flowtable miss), the
+packet traverses the classic IP forwarding path.
+
+:::{note}
+**Flowtable Reference:**
+<https://docs.kernel.org/networking/nf_flowtable.html>
+:::
+
+## Flowtable Configuration
+
+To use flowtables, you need to configure the following:
+> - Create a flowtable that includes the interfaces
+> that are going to be used by the flowtable.
+> - Create a firewall rule. Set the action to
+> `offload` and use your desired flowtable for `offload-target`.
+
+Creating a flow table:
+
+```{cfgcmd} set firewall flowtable \<flow_table_name\> interface \<iface\>
+
+Specify interfaces to use in the flowtable.
+```
+
+```{cfgcmd} set firewall flowtable \<flow_table_name\> description \<text\>
+```
+
+Provide a description for the flow table.
+
+```{cfgcmd} set firewall flowtable \<flow_table_name\> offload \<hardware | software\>
+
+Specify the offload type the flowtable uses: ``hardware`` or
+``software``. The default is ``software`` offload.
+```
+:::{note}
+**Hardware offload**: Make sure your network interface controller
+(NIC) supports hardware offloading and that you have the necessary drivers
+> installed before enabling this option.
+:::
+
+Creating rules for using flow tables:
+
+```{cfgcmd} set firewall [ipv4 | ipv6] forward filter rule \<1-999999\> action offload
+
+Create a firewall rule in the forward chain with the action set to
+``offload``.
+```
+
+```{cfgcmd} set firewall [ipv4 | ipv6] forward filter rule \<1-999999\> offload-target \<flowtable\>
+
+Create a firewall rule in the forward chain and specify which flowtable
+to use. Only applicable if the action is ``offload``.
+```
+
+## Configuration Example
+
+Consider the following in this setup:
+> - This example uses two interfaces in the flowtables: `eth0` and `eth1`.
+> - The example provides a minimal firewall ruleset with filtering rules
+> and rules for using flowtable offload capabilities.
+
+The first packet is evaluated by the firewall path, so a
+desired connection should be explicitly accepted.
+The same should occur for traffic in reverse order.
+In most cases, state policies are
+used to accept a connection in the reverse path.
+
+In the following example only traffic coming from interface `eth0`,
+TCP protocol, and destination port 1122 is accepted.
+All other traffic to the router is dropped.
+
+### Commands
+
+```none
+set firewall flowtable FT01 interface 'eth0'
+set firewall flowtable FT01 interface 'eth1'
+set firewall ipv4 forward filter default-action 'drop'
+set firewall ipv4 forward filter rule 10 action 'offload'
+set firewall ipv4 forward filter rule 10 offload-target 'FT01'
+set firewall ipv4 forward filter rule 10 state 'established'
+set firewall ipv4 forward filter rule 10 state 'related'
+set firewall ipv4 forward filter rule 20 action 'accept'
+set firewall ipv4 forward filter rule 20 state 'established'
+set firewall ipv4 forward filter rule 20 state 'related'
+set firewall ipv4 forward filter rule 110 action 'accept'
+set firewall ipv4 forward filter rule 110 destination address '192.0.2.100'
+set firewall ipv4 forward filter rule 110 destination port '1122'
+set firewall ipv4 forward filter rule 110 inbound-interface name 'eth0'
+set firewall ipv4 forward filter rule 110 protocol 'tcp'
+```
+
+### Explanation
+
+Here's what happens for a desired connection:
+> 1. A packet arrives on `eth0` with destination address `192.0.2.100`, TCP
+> protocol, and destination port 1122. Assume this address is reachable
+> through interface `eth1`.
+> 2. For this first packet, the connection state is **new**. Neither rule 10
+> nor rule 20 applies.
+> 3. Rule 110 matches, so the connection is accepted.
+> 4. When the server 192.0.2.100 replies, the connection state becomes
+> **established**, and rule 20 accepts the reply.
+> 5. The router receives the second packet for this connection. Because the
+> connection state is **established**, rule 10 matches and adds a new
+> entry in the flowtable FT01 for this connection.
+> 6. Subsequent packets skip the traditional path and use the **Fast Path**
+> for offloading.
+
+### Checks
+
+Check the conntrack table to verify that the system accepted and properly
+offloaded connections.
+
+```none
+vyos@FlowTables:~$ show firewall ipv4 forward filter
+Ruleset Information
+
+---------------------------------
+ipv4 Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------------------------------
+10 offload all 8 468 ct state { established, related } flow add @VYOS_FLOWTABLE_FT01
+20 accept all 8 468 ct state { established, related } accept
+110 accept tcp 2 120 ip daddr 192.0.2.100 tcp dport 1122 iifname "eth0" accept
+default drop all 7 420
+
+vyos@FlowTables:~$ sudo conntrack -L | grep tcp
+conntrack v1.4.6 (conntrack-tools): 5 flow entries have been shown.
+tcp 6 src=198.51.100.100 dst=192.0.2.100 sport=41676 dport=1122 src=192.0.2.100 dst=198.51.100.100 sport=1122 dport=41676 [OFFLOAD] mark=0 use=2
+vyos@FlowTables:~$
+```
diff --git a/docs/configuration/firewall/global-options.md b/docs/configuration/firewall/global-options.md
new file mode 100644
index 00000000..0f6d91ac
--- /dev/null
+++ b/docs/configuration/firewall/global-options.md
@@ -0,0 +1,186 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(firewall-global-options-configuration)=
+
+# Global Options Firewall Configuration
+
+## Overview
+
+Some firewall settings are global and affect the entire system. This section
+provides information about these global options that you can configure using
+the VyOS CLI.
+
+Configuration commands covered in this section:
+
+```{cfgcmd} set firewall global-options ...
+```
+
+## Configuration
+
+```{cfgcmd} set firewall global-options all-ping [enable | disable]
+
+By default, when VyOS receives an ICMP echo request packet destined for
+itself, it answers with an ICMP echo reply, unless your firewall prevents
+it.
+
+You can set firewall rules to accept, drop, or reject ICMP in, out, or
+local traffic. You can also use the **firewall global-options all-ping**
+command. This command affects only LOCAL traffic (packets destined for your
+VyOS system), not IN or OUT traffic.
+
+:::{note}
+**firewall global-options all-ping** affects only LOCAL traffic
+and always behaves in the most restrictive way
+:::
+:::{code-block} none
+set firewall global-options all-ping enable
+:::
+When you set this command, VyOS answers every ICMP echo request addressed
+to itself, but that response occurs only if no other rule drops or rejects
+local echo requests. In case of conflict, VyOS does not answer ICMP echo
+requests.
+
+:::{code-block} none
+set firewall global-options all-ping disable
+:::
+When you set this command, VyOS answers no ICMP echo requests addressed to
+itself, regardless of where they come from or what specific rules accept
+them.
+```
+
+```{cfgcmd} set firewall global-options apply-to-bridged-traffic [ipv4 | ipv6]
+
+Apply IPv4 or IPv6 firewall rules to bridged traffic.
+```
+
+```{cfgcmd} set firewall global-options broadcast-ping [enable | disable]
+
+Enable or disable the response to ICMP broadcast messages. The system
+alters the following parameter:
+* ``net.ipv4.icmp_echo_ignore_broadcasts``
+```
+
+```{cfgcmd} set firewall global-options ip-src-route [enable | disable]
+```
+
+```{cfgcmd} set firewall global-options ipv6-src-route [enable | disable]
+
+Set whether VyOS accepts packets with a source route option.
+The following sysctl parameters will be changed:
+* ``net.ipv4.conf.all.accept_source_route``
+* ``net.ipv6.conf.all.accept_source_route``
+```
+
+```{cfgcmd} set firewall global-options receive-redirects [enable | disable]
+```
+
+```{cfgcmd} set firewall global-options ipv6-receive-redirects [enable | disable]
+
+Allow VyOS to accept ICMPv4 and ICMPv6 redirect messages.
+The following sysctl parameters will be changed:
+* ``net.ipv4.conf.all.accept_redirects``
+* ``net.ipv6.conf.all.accept_redirects``
+```
+
+```{cfgcmd} set firewall global-options send-redirects [enable | disable]
+
+Allow VyOS to send ICMPv4 redirect messages.
+The following sysctl parameter will be changed:
+* ``net.ipv4.conf.all.send_redirects``
+```
+
+```{cfgcmd} set firewall global-options log-martians [enable | disable]
+
+Allow VyOS to log martian IPv4 packets.
+The following sysctl parameter will be changed:
+* ``net.ipv4.conf.all.log_martians``
+```
+
+```{cfgcmd} set firewall global-options source-validation [strict | loose | disable]
+
+Set the IPv4 source validation mode.
+The following sysctl parameter will be changed:
+* ``net.ipv4.conf.all.rp_filter``
+```
+
+```{cfgcmd} set firewall global-options syn-cookies [enable | disable]
+
+Allow VyOS to use IPv4 TCP SYN Cookies.
+The following sysctl parameter will be changed:
+* ``net.ipv4.tcp_syncookies``
+```
+
+```{cfgcmd} set firewall global-options twa-hazards-protection [enable | disable]
+
+Enable or disable VyOS {rfc}`1337` conformance.
+The following sysctl parameter will be changed:
+* ``net.ipv4.tcp_rfc1337``
+```
+
+```{cfgcmd} set firewall global-options state-policy established action [accept | drop | reject]
+```
+
+```{cfgcmd} set firewall global-options state-policy established log
+```
+
+```{cfgcmd} set firewall global-options state-policy established log-level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Set the global setting for an established connection.
+```
+
+```{cfgcmd} set firewall global-options state-policy invalid action [accept | drop | reject]
+```
+
+```{cfgcmd} set firewall global-options state-policy invalid log
+```
+
+```{cfgcmd} set firewall global-options state-policy invalid log-level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Set the global setting for invalid packets.
+```
+
+```{cfgcmd} set firewall global-options state-policy related action [accept | drop | reject]
+```
+
+```{cfgcmd} set firewall global-options state-policy related log
+```
+
+```{cfgcmd} set firewall global-options state-policy related log-level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Set the global setting for related connections.
+```
+
+VyOS supports setting timeouts for connections by connection type. You can
+set timeout values for generic connections, ICMP connections, UDP
+connections, or TCP connections in various states.
+
+```{eval-rst}
+.. cfgcmd:: set firewall global-options timeout icmp <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout other <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp close <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp close-wait <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp established <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp fin-wait <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp last-ack <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp syn-recv <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp syn-sent <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout tcp time-wait <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout udp other <1-21474836>
+ :defaultvalue:
+.. cfgcmd:: set firewall global-options timeout udp stream <1-21474836>
+ :defaultvalue:
+
+ Set the timeout in seconds for a protocol or state.
+``` \ No newline at end of file
diff --git a/docs/configuration/firewall/groups.md b/docs/configuration/firewall/groups.md
new file mode 100644
index 00000000..817f610e
--- /dev/null
+++ b/docs/configuration/firewall/groups.md
@@ -0,0 +1,477 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(firewall-groups-configuration)=
+
+# Firewall groups
+
+## Configuration
+
+Firewall groups represent collections of IP addresses, networks, ports,
+MAC addresses, domains, or interfaces. You can reference a group in firewall,
+NAT, and policy route rules as either a source or destination matcher, and/or
+as inbound or outbound in the case of interface groups.
+
+### Address Groups
+
+An **address group** contains a single IP address or IP address range.
+
+```{cfgcmd} set firewall group address-group \<name\> address [address | address range]
+
+```
+```{cfgcmd} set firewall group ipv6-address-group \<name\> address \<address\>
+
+Define an IPv4 or IPv6 address group.
+
+:::{code-block} none
+set firewall group address-group ADR-INSIDE-v4 address 192.168.0.1
+set firewall group address-group ADR-INSIDE-v4 address 10.0.0.1-10.0.0.8
+set firewall group ipv6-address-group ADR-INSIDE-v6 address 2001:db8::1
+:::
+```
+
+```{cfgcmd} set firewall group address-group \<name\> description \<text\>
+```
+
+```{cfgcmd} set firewall group ipv6-address-group \<name\> description \<text\>
+
+Provide an IPv4 or IPv6 address group description.
+```
+
+### Remote Groups
+
+A **remote-group** uses a URL that hosts a newline-delimited list of IPv4
+and/or IPv6 addresses, CIDRs, and ranges. VyOS pulls this list periodically
+according to the frequency you define in the firewall **resolver-interval**
+and loads matching entries into the group for use in rules. The list is cached
+in persistent storage, so rules continue to function if updates fail.
+
+```{cfgcmd} set firewall group remote-group \<name\> url \<http(s) url\>
+
+Specify a remote list of IPv4 and/or IPv6 addresses, ranges, and CIDRs
+to fetch.
+```
+
+```{cfgcmd} set firewall group remote-group \<name\> description \<text\>
+
+Set a description for a remote group.
+```
+
+The remote list format is flexible. VyOS attempts to parse the first word of
+each line as an entry and skips lines it cannot match. Lines that begin with
+an alphanumeric character but do not match valid IPv4 or IPv6 addresses,
+ranges, or CIDRs are logged to the system log. The following examples show
+acceptable formats that VyOS parses correctly:
+
+```none
+127.0.0.1
+127.0.0.0/24
+127.0.0.1-127.0.0.254
+2001:db8::1
+2001:db8:cafe::/48
+2001:db8:cafe::1-2001:db8:cafe::ffff
+```
+
+### Network Groups
+
+**Network groups** accept IP networks in CIDR notation. You can add specific
+IP addresses as a 32-bit prefix. If you need to add a mix of addresses and
+networks, use a network group.
+
+```{cfgcmd} set firewall group network-group \<name\> network \<CIDR\>
+```
+
+```{cfgcmd} set firewall group ipv6-network-group \<name\> network \<CIDR\>
+
+Define an IPv4 or IPv6 network group.
+
+:::{code-block} none
+set firewall group network-group NET-INSIDE-v4 network 192.168.0.0/24
+set firewall group network-group NET-INSIDE-v4 network 192.168.1.0/24
+set firewall group ipv6-network-group NET-INSIDE-v6 network 2001:db8::/64
+:::
+```
+
+```{cfgcmd} set firewall group network-group \<name\> description \<text\>
+```
+
+```{cfgcmd} set firewall group ipv6-network-group \<name\> description \<text\>
+
+Provide an IPv4 or IPv6 network group description.
+```
+
+### Interface Groups
+
+An **interface group** represents a collection of interfaces.
+
+```{cfgcmd} set firewall group interface-group \<name\> interface \<text\>
+
+Define an interface group.
+Wildcard ``*`` is supported. For example: ``eth3*``.
+Prepend the character ``!`` to invert the criteria. For example: ``!eth2``.
+```
+
+```none
+set firewall group interface-group LAN interface bond1001
+set firewall group interface-group LAN interface eth3*
+```
+
+```{cfgcmd} set firewall group interface-group \<name\> description \<text\>
+
+Provide an interface group description.
+```
+
+### Port Groups
+
+A **port group** represents only port numbers, not the protocol. You can
+reference port groups for either TCP or UDP. Create TCP and UDP groups
+separately to avoid accidentally filtering unnecessary ports. Specify port
+ranges by using `-`.
+
+```{cfgcmd} set firewall group port-group \<name\> port [portname | portnumber | startport-endport]
+
+Define a port group. A port name can be any name defined in
+/etc/services. For example, ``http``.
+
+:::{code-block} none
+set firewall group port-group PORT-TCP-SERVER1 port http
+set firewall group port-group PORT-TCP-SERVER1 port 443
+set firewall group port-group PORT-TCP-SERVER1 port 5000-5010
+:::
+```
+
+```{cfgcmd} set firewall group port-group \<name\> description \<text\>
+
+Provide a port group description.
+```
+
+### MAC Groups
+
+A **mac group** represents a collection of mac addresses.
+
+```{cfgcmd} set firewall group mac-group \<name\> mac-address \<mac-address\>
+
+Define a mac group.
+```
+
+```none
+set firewall group mac-group MAC-G01 mac-address 88:a4:c2:15:b6:4f
+set firewall group mac-group MAC-G01 mac-address 4c:d5:77:c0:19:81
+```
+
+```{cfgcmd} set firewall group mac-group \<name\> description \<text\>
+
+Provide a MAC group description.
+```
+
+### Domain Groups
+
+A **domain group** represents a collection of domains.
+
+```{cfgcmd} set firewall group domain-group \<name\> address \<domain\>
+
+Define a domain group.
+```
+
+```none
+set firewall group domain-group DOM address example.com
+```
+
+```{cfgcmd} set firewall group domain-group \<name\> description \<text\>
+
+Provide a domain group description.
+```
+
+### Dynamic Groups
+
+Firewall dynamic groups differ from other groups because you can use them as
+source/destination in firewall rules, and members are not defined statically
+in VyOS configuration. Instead, firewall rules dynamically add members to
+these groups.
+
+#### Defining Dynamic Address Groups
+
+Dynamic address groups support both IPv4 and IPv6 families. Use these
+commands to define dynamic IPv4 and IPv6 address groups:
+
+```{cfgcmd} set firewall group dynamic-group address-group \<name\>
+```
+
+```{cfgcmd} set firewall group dynamic-group ipv6-address-group \<name\>
+```
+
+Add description to firewall groups:
+
+```{cfgcmd} set firewall group dynamic-group address-group \<name\> description \<text\>
+```
+
+```{cfgcmd} set firewall group dynamic-group ipv6-address-group \<name\> description \<text\>
+```
+
+#### Adding elements to Dynamic Firewall Groups
+
+After you define dynamic firewall groups, use them in firewall rules to
+dynamically add elements to them.
+
+Commands used for this task are:
+- Add destination IP address of the connection to a dynamic address group:
+
+```{cfgcmd} set firewall ipv4 [forward | input | output] filter rule \<1-999999\> add-address-to-group destination-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> add-address-to-group destination-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv6 [forward | input | output] filter rule \<1-999999\> add-address-to-group destination-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> add-address-to-group destination-address address-group \<name\>
+```
+
+- Add source IP address of the connection to a dynamic address group:
+
+```{cfgcmd} set firewall ipv4 [forward | input | output] filter rule \<1-999999\> add-address-to-group source-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> add-address-to-group source-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv6 [forward | input | output] filter rule \<1-999999\> add-address-to-group source-address address-group \<name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> add-address-to-group source-address address-group \<name\>
+```
+
+You can define specific timeouts per rule. When a rule matches, the source or
+destination address is added to the group, and the element remains in the group
+until the timeout expires. If you do not define a timeout, the element remains
+in the group until the next reboot or until you commit firewall configuration
+changes.
+
+```{cfgcmd} set firewall ipv4 [forward | input | output] filter rule \<1-999999\> add-address-to-group [destination-address | source-address] timeout \<timeout\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> add-address-to-group [destination-address | source-address] timeout \<timeout\>
+```
+
+```{cfgcmd} set firewall ipv6 [forward | input | output] filter rule \<1-999999\> add-address-to-group [destination-address | source-address] timeout \<timeout\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> add-address-to-group [destination-address | source-address] timeout \<timeout\>
+```
+
+Timeout can be defined using seconds, minutes, hours or days:
+
+```none
+set firewall ipv6 name FOO rule 10 add-address-to-group source-address timeout
+Possible completions:
+<number>s Timeout value in seconds
+<number>m Timeout value in minutes
+<number>h Timeout value in hours
+<number>d Timeout value in days
+```
+
+#### Using Dynamic Firewall Groups
+
+Like other firewall groups, you can use dynamic firewall groups in firewall
+rules as matching options. For example:
+
+```none
+set firewall ipv4 input filter rule 10 source group dynamic-address-group FOO
+set firewall ipv4 input filter rule 10 destination group dynamic-address-group BAR
+```
+
+## Examples
+
+### General example
+
+After you create firewall groups, you can reference them in firewall, NAT,
+NAT66, and/or policy-route rules. The following example creates multiple
+groups:
+
+```{eval-rst}
+ .. code-block:: none
+
+ set firewall group address-group SERVERS address 198.51.100.101
+ set firewall group address-group SERVERS address 198.51.100.102
+ set firewall group network-group TRUSTEDv4 network 192.0.2.0/30
+ set firewall group network-group TRUSTEDv4 network 203.0.113.128/25
+ set firewall group ipv6-network-group TRUSTEDv6 network 2001:db8::/64
+ set firewall group interface-group LAN interface eth2.2001
+ set firewall group interface-group LAN interface bon0
+ set firewall group port-group PORT-SERVERS port http
+ set firewall group port-group PORT-SERVERS port 443
+ set firewall group port-group PORT-SERVERS port 5000-5010
+```
+
+And next, some configuration example where groups are used:
+
+```{eval-rst}
+ .. code-block:: none
+
+ set firewall ipv4 output filter rule 10 action accept
+ set firewall ipv4 output filter rule 10 outbound-interface group !LAN
+ set firewall ipv4 forward filter rule 20 action accept
+ set firewall ipv4 forward filter rule 20 source group network-group TRUSTEDv4
+ set firewall ipv6 input filter rule 10 action accept
+ set firewall ipv6 input filter rule 10 source group network-group TRUSTEDv6
+ set nat destination rule 101 inbound-interface group LAN
+ set nat destination rule 101 destination group address-group SERVERS
+ set nat destination rule 101 protocol tcp
+ set nat destination rule 101 destination group port-group PORT-SERVERS
+ set nat destination rule 101 translation address 203.0.113.250
+ set policy route PBR rule 201 destination group port-group PORT-SERVERS
+ set policy route PBR rule 201 protocol tcp
+ set policy route PBR rule 201 set table 15
+```
+
+### Port knocking example
+
+You can use dynamic firewall groups with port knocking to secure access to
+the router or any other device. The following example shows a 4-step port
+knocking configuration:
+
+```{eval-rst}
+ .. code-block:: none
+
+ 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 firewall group dynamic-group address-group ALLOWED
+ set firewall group dynamic-group address-group PN_01
+ set firewall group dynamic-group address-group PN_02
+ set firewall ipv4 input filter default-action 'drop'
+ set firewall ipv4 input filter rule 5 action 'accept'
+ set firewall ipv4 input filter rule 5 protocol 'icmp'
+ set firewall ipv4 input filter rule 10 action 'drop'
+ set firewall ipv4 input filter rule 10 add-address-to-group source-address address-group 'PN_01'
+ set firewall ipv4 input filter rule 10 add-address-to-group source-address timeout '2m'
+ set firewall ipv4 input filter rule 10 description 'Port_nock 01'
+ set firewall ipv4 input filter rule 10 destination port '9990'
+ set firewall ipv4 input filter rule 10 protocol 'tcp'
+ set firewall ipv4 input filter rule 20 action 'drop'
+ set firewall ipv4 input filter rule 20 add-address-to-group source-address address-group 'PN_02'
+ set firewall ipv4 input filter rule 20 add-address-to-group source-address timeout '3m'
+ set firewall ipv4 input filter rule 20 description 'Port_nock 02'
+ set firewall ipv4 input filter rule 20 destination port '9991'
+ set firewall ipv4 input filter rule 20 protocol 'tcp'
+ set firewall ipv4 input filter rule 20 source group dynamic-address-group 'PN_01'
+ set firewall ipv4 input filter rule 30 action 'drop'
+ set firewall ipv4 input filter rule 30 add-address-to-group source-address address-group 'ALLOWED'
+ set firewall ipv4 input filter rule 30 add-address-to-group source-address timeout '2h'
+ set firewall ipv4 input filter rule 30 description 'Port_nock 03'
+ set firewall ipv4 input filter rule 30 destination port '9992'
+ set firewall ipv4 input filter rule 30 protocol 'tcp'
+ set firewall ipv4 input filter rule 30 source group dynamic-address-group 'PN_02'
+ set firewall ipv4 input filter rule 99 action 'accept'
+ set firewall ipv4 input filter rule 99 description 'Port_nock 04 - Allow ssh'
+ set firewall ipv4 input filter rule 99 destination port '22'
+ set firewall ipv4 input filter rule 99 protocol 'tcp'
+ set firewall ipv4 input filter rule 99 source group dynamic-address-group 'ALLOWED'
+```
+
+Before testing, we can check the members of firewall groups:
+
+```none
+vyos@vyos# run show firewall group
+Firewall Groups
+
+Name Type References Members Timeout Expires
+------- ---------------------- -------------------- ------------- --------- ---------
+ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
+PN_01 address_group(dynamic) ipv4-input-filter-10 N/D N/D N/D
+PN_02 address_group(dynamic) ipv4-input-filter-20 N/D N/D N/D
+[edit]
+vyos@vyos#
+```
+
+With this configuration, to gain SSH access to the router, the user must:
+
+1. Create a new TCP connection to destination port 9990. A new entry is added
+ to dynamic firewall group `PN_01`.
+
+ ```none
+ vyos@vyos# run show firewall group
+ Firewall Groups
+
+ Name Type References Members Timeout Expires
+ ------- ---------------------- -------------------- ------------- --------- ---------
+ ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
+ PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 119
+ PN_02 address_group(dynamic) ipv4-input-filter-20 N/D N/D N/D
+ [edit]
+ vyos@vyos#
+ ```
+
+2. Create a new TCP connection to destination port 9991. A new entry is added
+ to dynamic firewall group `PN_02`.
+
+ ```none
+ vyos@vyos# run show firewall group
+ Firewall Groups
+
+ Name Type References Members Timeout Expires
+ ------- ---------------------- -------------------- ------------- --------- ---------
+ ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
+ PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 106
+ PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.89.31 180 179
+ [edit]
+ vyos@vyos#
+ ```
+
+3. Create a new TCP connection to destination port 9992. A new entry is added
+ to dynamic firewall group `ALLOWED`.
+
+ ```none
+ vyos@vyos# run show firewall group
+ Firewall Groups
+
+ Name Type References Members Timeout Expires
+ ------- ---------------------- -------------------- ------------- --------- ---------
+ ALLOWED address_group(dynamic) ipv4-input-filter-30 192.168.89.31 7200 7199
+ PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 89
+ PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.89.31 180 170
+ [edit]
+ vyos@vyos#
+ ```
+
+4. Now you can connect via SSH to the router (assuming SSH is
+ configured).
+
+## Operation-mode
+
+```{opcmd} show firewall group
+```
+
+```{opcmd} show firewall group \<name\>
+
+Display an overview of defined groups, including the firewall group name,
+type, references (where the group is used), members, timeout, and
+expiration (the last two only apply to dynamic firewall groups).
+```
+
+Here is an example of such command:
+
+```none
+vyos@vyos:~$ show firewall group
+Firewall Groups
+
+Name Type References Members Timeout Expires
+------------ ---------------------- ---------------------- ---------------- --------- ---------
+SERVERS address_group nat-destination-101 198.51.100.101
+ 198.51.100.102
+ALLOWED address_group(dynamic) ipv4-input-filter-30 192.168.77.39 7200 7174
+PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.0.245 120 112
+ 192.168.77.39 120 85
+PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.77.39 180 151
+LAN interface_group ipv4-output-filter-10 bon0
+ nat-destination-101 eth2.2001
+TRUSTEDv6 ipv6_network_group ipv6-input-filter-10 2001:db8::/64
+TRUSTEDv4 network_group ipv4-forward-filter-20 192.0.2.0/30
+ 203.0.113.128/25
+PORT-SERVERS port_group route-PBR-201 443
+ route-PBR-201 5000-5010
+ nat-destination-101 http
+vyos@vyos:~$
+```
diff --git a/docs/configuration/firewall/index.md b/docs/configuration/firewall/index.md
new file mode 100644
index 00000000..81699154
--- /dev/null
+++ b/docs/configuration/firewall/index.md
@@ -0,0 +1,278 @@
+---
+lastproofread: '2026-03-30'
+---
+
+# Firewall
+
+:::{warning}
+Due to a boot-time race condition, all interfaces initialize
+before the firewall. This temporarily leaves the system open to all traffic
+and poses a security risk.
+:::
+
+VyOS uses Netfilter. The Netfilter
+project developed `iptables` and its successor `nftables` for the Linux
+kernel to process packet data flows directly. This extends the concept of
+zone-based security to let you manipulate data at multiple stages after the
+network interface and driver accept it, and before sending it to its
+destination (for example, a web server or another device).
+
+The following is a simplified traffic flow diagram based on Netfilter
+packet flow.
+This diagram provides an overview of how packets are processed and the
+possible paths traffic can take.
+
+:::{figure} /_static/images/firewall-gral-packet-flow.webp
+:::
+
+The main points regarding packet flow and terminology in VyOS firewall
+are:
+
+- **Bridge Port?**: Choose the appropriate path based on whether the
+ interface where the packet was received is part of a bridge.
+
+If the interface where the packet was received is not part of a bridge, the
+packet is processed at the **IP Layer**:
+
+```{eval-rst}
+ * **Prerouting**: The router processes all packets in this stage,
+ regardless of the destination. You can perform several actions in
+ this stage, and these actions are also defined in different parts of the
+ VyOS configuration. Order is important. The relevant configuration that
+ applies in this stage includes:
+
+ * **Firewall prerouting**: Rules you define under ``set firewall
+ [ipv4 | ipv6] prerouting raw...``. The system processes all rules in
+ this section before the connection tracking subsystem.
+
+ * **Conntrack Ignore**: Rules you define under ``set system conntrack
+ ignore [ipv4 | ipv6] ...``. You can configure this section with
+ ``firewall [ipv4 | ipv6] prerouting ...``. For compatibility reasons,
+ this feature is supported, but will be deprecated in the future.
+
+ * **Policy Route**: Rules you define under ``set policy [route |
+ route6] ...``.
+
+ * **Destination NAT**: Rules you define under ``set [nat | nat66]
+ destination...``.
+
+ * **Destination is the router?**: Choose the appropriate path based on the
+ destination IP address. Transit traffic continues to **forward**, while
+ traffic destined for the router continues to **input**.
+
+ * **Input**: The stage where you filter and control traffic destined for
+ the router itself. This is where you enforce all rules for securing the
+ router. This includes IPv4 and IPv6 filtering rules, defined in:
+
+ * ``set firewall ipv4 input filter ...``.
+
+ * ``set firewall ipv6 input filter ...``.
+
+ * **Forward**: The stage where you filter and control transit traffic.
+ This includes IPv4 and IPv6 filtering rules, defined in:
+
+ * ``set firewall ipv4 forward filter ...``.
+
+ * ``set firewall ipv6 forward filter ...``.
+
+ * **Output**: The stage where you filter and control traffic that the
+ router originates. Note that this traffic comes from either a new
+ connection that an internal process on the VyOS router (such as NTP)
+ originates or a response to traffic the router receives externally through
+ **input** (for example, a response to an SSH login attempt). This includes
+ IPv4 and IPv6 rules, and two different sections apply:
+
+ * **Output Prerouting**: ``set firewall [ipv4 | ipv6] output
+ filter ...``. As described in **Prerouting**, the system processes
+ rules in this section before the connection tracking subsystem.
+
+ * **Output Filter**: ``set firewall [ipv4 | ipv6] output filter ...``.
+
+ * **Postrouting**: As in **Prerouting**, you can perform several actions
+ defined in different parts of VyOS configuration in this stage. This
+ includes:
+
+ * **Source NAT**: Rules you define under ``set [nat | nat66]
+ destination...``.
+```
+
+If the interface where the packet was received is part of a bridge, the
+packet is processed at the **Bridge Layer**:
+
+```{eval-rst}
+ * **Prerouting (Bridge)**: The bridge processes all packets it receives in
+ this stage, regardless of the destination. First, you can apply filters
+ here, or you can configure rules that ignore the connection tracking
+ system. The relevant configuration that applies:
+
+ * ``set firewall bridge prerouting filter ...``.
+
+ * **Forward (Bridge)**: The stage where you filter and control traffic
+ that passes through the bridge:
+
+ * ``set firewall bridge forward filter ...``.
+
+ * **Input (Bridge)**: The stage where you filter and control traffic
+ destined for the bridge itself:
+
+ * ``set firewall bridge input filter ...``.
+
+ * **Output (Bridge)**: The stage where you filter and control traffic that
+ the bridge originates:
+
+ * ``set firewall bridge output filter ...``.
+```
+
+The following is the overall structure of the VyOS firewall CLI:
+
+```none
+- set firewall
+ * bridge
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ - prerouting
+ + filter
+ - name
+ + custom_name
+ * flowtable
+ - custom_flow_table
+ + ...
+ * global-options
+ + all-ping
+ + broadcast-ping
+ + ...
+ * group
+ - address-group
+ - ipv6-address-group
+ - network-group
+ - ipv6-network-group
+ - interface-group
+ - mac-group
+ - port-group
+ - domain-group
+ * ipv4
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ + raw
+ - prerouting
+ + raw
+ - name
+ + custom_name
+ * ipv6
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ + raw
+ - prerouting
+ + raw
+ - ipv6-name
+ + custom_name
+ * zone
+ - custom_zone_name
+ + ...
+```
+
+Here is a list of VyOS firewall CLI subcommands and their
+corresponding pages in the documentation:
+
+```{cfgcmd} set firewall bridge ...
+
+Configure bridge firewall rules for traffic at the bridge layer.
+See the Bridge Firewall Configuration page for detailed information.
+```
+
+```{cfgcmd} set firewall flowtable ...
+
+Configure firewall flowtables for stateful connection tracking and rules.
+See the Flowtables Firewall Configuration page for detailed information.
+```
+
+```{cfgcmd} set firewall global-options ...
+
+Configure global firewall options such as ``all-ping``, ``broadcast-ping``,
+``syn-cookies``, and other system-wide firewall settings.
+See the Global Firewall Options page for detailed information.
+```
+
+```{cfgcmd} set firewall group ...
+
+Organize firewall rules by creating reusable address, network, interface,
+MAC, port, and domain groups. Use groups in multiple rules to simplify
+configuration and maintenance.
+See the Firewall Groups page for detailed information.
+```
+
+```{cfgcmd} set firewall ipv4 ...
+
+Configure IPv4-specific firewall rules.
+See the IPv4 Firewall Configuration page for detailed information.
+```
+
+```{cfgcmd} set firewall ipv6 ...
+
+Configure IPv6-specific firewall rules.
+See the IPv6 Firewall Configuration page for detailed information.
+```
+
+```{cfgcmd} set firewall zone ...
+
+Configure zone-based firewall policies for controlling traffic between
+different network zones.
+See the Zone-Based Firewall Configuration page for detailed information.
+```
+
+For more information on firewall configuration, see the following pages:
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+global-options
+groups
+bridge
+ipv4
+ipv6
+flowtables
+```
+
+:::{note}
+For more information on Netfilter hooks and Linux networking packet flows,
+see the [Netfilter-Hooks](<https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks>)
+documentation.
+:::
+
+## Zone-Based firewall
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+zone
+```
+
+With zone-based firewalls, a new concept applies. In addition to the standard
+in and out traffic flows, a local flow enables traffic originating from and
+destined to the router itself. This means you must configure additional rules to
+secure the firewall from the network, in addition to the existing inbound and
+outbound rules.
+
+To configure VyOS with zone-based firewall, see
+{doc}`Zone-Based Firewall Configuration </configuration/firewall/zone>`.
+
+As the following example image shows, you must configure rules to allow or block
+traffic to or from the services running on the device that have open
+connections on that interface.
+
+:::{figure} /_static/images/firewall-zonebased.webp
+:::
diff --git a/docs/configuration/firewall/ipv4.md b/docs/configuration/firewall/ipv4.md
new file mode 100644
index 00000000..04c4fc70
--- /dev/null
+++ b/docs/configuration/firewall/ipv4.md
@@ -0,0 +1,1544 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(firewall-ipv4-configuration)=
+
+# IPv4 Firewall Configuration
+
+## Overview
+
+This section provides information on IPv4 firewall configuration and
+appropriate operation-mode commands. This section covers the following
+configuration commands:
+
+```{cfgcmd} set firewall ipv4 ...
+```
+
+To learn about the general traffic flow in VyOS firewalls, see {doc}`Firewall </configuration/firewall/index>`.
+
+```none
+- set firewall
+ * ipv4
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ + raw
+ - prerouting
+ + raw
+ - name
+ + custom_name
+```
+
+First, the router receives all traffic and processes it in the **prerouting**
+stage.
+
+This stage includes:
+
+- **Firewall Prerouting**: commands found under `set firewall ipv4
+ prerouting raw ...`
+- {doc}`Conntrack Ignore</configuration/system/conntrack>`: `set system
+ conntrack ignore ipv4...`
+- {doc}`Policy Route</configuration/policy/route>`: commands found under
+ `set policy route ...`
+- {doc}`Destination NAT</configuration/nat/nat44>`: commands found under
+ `set nat destination ...`
+
+For transit traffic, which is received by the router and forwarded, the base
+chain is **forward**. The following is a simplified packet flow diagram for
+transit traffic:
+
+:::{figure} /_static/images/firewall-fwd-packet-flow.webp
+:::
+
+The base firewall chain for configuring filtering rules for transit traffic is
+`set firewall ipv4 forward filter ...`, which occurs in stage 5, highlighted
+in red.
+
+For traffic to the router itself, the base chain is **input**. For traffic
+the router originates, the base chain is **output**. A simplified packet flow
+diagram is shown next, which shows the path for traffic destined to the router
+itself and traffic the router generates (starting from circle number 6):
+
+:::{figure} /_static/images/firewall-input-packet-flow.webp
+:::
+
+The base chain for traffic towards the router is
+`set firewall ipv4 input filter ...`
+
+The base chain for traffic the router generates is `set firewall ipv4
+output ...`, where two sub-chains are available: **filter** and **raw**:
+
+- **Output Prerouting**: `set firewall ipv4 output raw ...`. As described
+ in **Prerouting**, the system processes rules in this section before the
+ connection tracking subsystem.
+- **Output Filter**: `set firewall ipv4 output filter ...`. The system
+ processes rules in this section after the connection tracking subsystem.
+
+:::{note}
+**Important note about default-actions:**
+If you do not define a default action for a base chain, the system sets
+the default action to **accept** for that chain. For custom chains, if you
+do not define a default action, the system sets the default-action to
+**drop**.
+:::
+
+You can create custom firewall chains using the following commands:
+`set firewall ipv4 name <name> ...`. To use a custom chain, you must define
+a rule with the **action jump** and the appropriate **target** in a base
+chain.
+
+## Firewall - IPv4 Rules
+
+Each firewall rule has a
+number, an action to apply if the rule matches, and the ability to specify
+multiple matching criteria. Packets traverse rules numbered 1-999999, so order
+is crucial. The system executes the rule action at the first match.
+
+### Actions
+
+If you define a rule, you must define an action for it. The action tells the
+firewall what to do if all the criteria you define for that rule are met.
+
+The action can be:
+
+- `accept`: Accept the packet.
+- `continue`: Continue parsing the next rule.
+- `drop`: Drop the packet.
+- `reject`: Reject the packet.
+- `jump`: Jump to another custom chain.
+- `return`: Return from the current chain and continue at the next rule
+ of the last chain.
+- `queue`: Enqueue packet to userspace.
+- `synproxy`: Synproxy the packet.
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return | synproxy]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return | synproxy]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return]
+
+This required setting defines the action of the current rule. If you set
+the action to jump, you must also specify a jump-target.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> jump-target \<text\>
+
+Use this command only when the action is set to ``jump``. Specify the
+jump target.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> queue \<0-65535\>
+
+Use this command only when the action is set to ``queue``. Specify the
+queue target to use. Queue range is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> queue-options bypass
+
+Use this command only when the action is set to ``queue``. Allow the packet
+to pass through the firewall when no userspace software is connected to the
+queue.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> queue-options fanout
+
+Use this command only when the action is set to ``queue``. Distribute
+packets between several queues.
+```
+
+Also, **default-action** is an action that applies when a packet does not
+match any rule in its chain. For base chains, possible options for
+**default-action** are **accept** or **drop**.
+
+```{cfgcmd} set firewall ipv4 forward filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv4 input filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv4 output filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> default-action [accept | drop | jump | queue | reject | return]
+
+This command sets the default action of the rule-set if a packet does not
+match the criteria of any rule. If you set the default-action to ``jump``,
+you must also specify ``default-jump-target``. Note that for base chains,
+you can set the default action only to ``accept`` or ``drop``, while on
+custom chains, more actions are available.
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> default-jump-target \<text\>
+
+Use this command only when you set ``default-action`` to ``jump``. Specify
+the jump target for the default rule.
+```
+:::{note}
+**Important note about default-actions:**
+If you do not define a default action for a base chain, the system sets
+the default action to **accept** for that chain. For custom chains, if you
+do not define a default action, the system sets the default-action to
+**drop**.
+:::
+
+### Firewall Logs
+
+You can enable logging for every single firewall rule. If you enable logging,
+you can define other log options.
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> log
+
+Enable logging for the matched packet. If this command is not present, then
+logging is not enabled.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter default-log
+```
+
+```{cfgcmd} set firewall ipv4 input filter default-log
+```
+
+```{cfgcmd} set firewall ipv4 output filter default-log
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> default-log
+
+Use this command to enable logging of the default action on the specified
+chain.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Define the log level. Only applicable if you enable rule logging.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> log-options group \<0-65535\>
+
+Define the log group to send messages to. Only applicable if you enable rule
+logging.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> log-options snapshot-length \<0-9000\>
+
+Define the length of packet payload to include in a netlink message. Only
+applicable if you enable rule logging and define the log group.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> log-options queue-threshold \<0-65535\>
+
+Define the number of packets to queue inside the kernel before sending them
+to userspace. Only applicable if you enable rule logging and define the log
+group.
+```
+
+### Firewall Description
+
+You can add a description for reference for every single rule and for every
+defined custom chain.
+
+```{cfgcmd} set firewall ipv4 name \<name\> description \<text\>
+
+Provide a rule-set description for a custom firewall chain.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> description \<text\>
+
+Provide a description for each rule.
+```
+
+### Rule Status
+
+When you define a rule, it is enabled by default. In some cases, it is useful
+to disable the rule rather than removing it.
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> disable
+
+Command for disabling a rule but keeping it in the configuration.
+```
+
+### Matching criteria
+
+There are a lot of matching criteria against which the packet can be tested.
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> connection-status nat [destination | source]
+
+Match based on nat connection status.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> connection-mark \<1-2147483647\>
+
+Match based on connection mark.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> conntrack-helper \<module\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> conntrack-helper \<module\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> conntrack-helper \<module\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> conntrack-helper \<module\>
+
+Match based on connection tracking protocol helper module to secure use of
+that helper module. See below for possible completions \<module\>.
+
+:::{code-block} none
+Possible completions:
+ftp Related traffic from FTP helper
+h323 Related traffic from H.323 helper
+pptp Related traffic from PPTP helper
+nfs Related traffic from NFS helper
+sip Related traffic from SIP helper
+tftp Related traffic from TFTP helper
+sqlnet Related traffic from SQLNet helper
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination address [address | addressrange | CIDR]
+
+Match criteria based on source and/or destination address. This is similar
+to the network groups part, but here you are able to negate the matching
+addresses.
+
+:::{code-block} none
+set firewall ipv4 name FOO rule 50 source address 192.0.2.10-192.0.2.11
+# with a '!' the rule match everything except the specified subnet
+set firewall ipv4 input filter FOO rule 51 source address !203.0.113.0/24
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination address-mask [address]
+
+An arbitrary netmask can be applied to mask addresses to only match against
+a specific portion.
+
+This functions for both individual addresses and address groups.
+
+:::{code-block} none
+# Match any IPv4 address with `11` as the 2nd octet and `13` as the forth octet
+set firewall ipv4 name FOO rule 100 destination address 0.11.0.13
+set firewall ipv4 name FOO rule 100 destination address-mask 0.255.0.255
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination fqdn \<fqdn\>
+
+Specify a Fully Qualified Domain Name as source/destination to match. Ensure
+that the router is able to resolve this dns query.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination geoip inverse-match
+
+Match IP addresses based on its geolocation. More info: geoip matching.
+Use inverse-match to match anything except the given country-codes.
+```
+
+Data is provided by DB-IP.com under CC-BY-4.0 license. Attribution required,
+permits redistribution so we can include a database in images(~3MB
+compressed). Includes cron script (manually callable by op-mode update
+geoip) to keep database and rules updated.
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source mac-address \<mac-address\>
+
+You can only specify a source mac-address to match.
+
+:::{code-block} none
+set firewall ipv4 input filter rule 100 source mac-address 00:53:00:11:22:33
+set firewall ipv4 input filter rule 101 source mac-address !00:53:00:aa:12:34
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination port [1-65535 | portname | start-end]
+
+A port can be set by number or name as defined in ``/etc/services``.
+
+:::{code-block} none
+set firewall ipv4 forward filter rule 10 source port '22'
+set firewall ipv4 forward filter rule 11 source port '!http'
+set firewall ipv4 forward filter rule 12 source port 'https'
+:::
+Multiple source ports can be specified as a comma-separated list.
+The whole list can also be "negated" using ``!``. For example:
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group address-group \<name | !name\>
+
+Use a specific address-group. Prepending the character ``!`` to invert the
+criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+
+Use a specific dynamic-address-group. Prepending the character ``!`` to
+invert the criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group network-group \<name | !name\>
+
+Use a specific network-group. Prepending the character ``!`` to invert the
+criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group port-group \<name | !name\>
+
+Use a specific port-group. Prepending the character ``!`` to invert the
+criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group domain-group \<name | !name\>
+
+Use a specific domain-group. Prepending the character ``!`` to invert the
+criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> destination group mac-group \<name | !name\>
+
+Use a specific mac-group. Prepending the character ``!`` to invert the
+criteria to match is also supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> dscp-exclude [0-63 | start-end]
+
+Match based on dscp value.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> fragment [match-frag | match-non-frag]
+
+Match based on fragmentation.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> icmp [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> icmp [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> icmp [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> icmp [code | type] \<0-255\>
+
+Match based on icmp code and type.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> icmp type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> icmp type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> icmp type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> icmp type-name \<text\>
+
+Match based on icmp type-name. Use tab for information
+about what **type-name** criteria are supported.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> inbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> inbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> inbound-interface name \<iface\>
+
+Match based on inbound interface. Wildcard ``*`` is supported. For example:
+``eth2*``. Prepend the character ``!`` to invert the criteria. For example:
+``!eth2``
+```
+:::{note}
+If an interface is attached to a non-default vrf, when using
+**inbound-interface**, the vrf name must be used. For example `set firewall
+ipv4 forward filter rule 10 inbound-interface name MGMT`
+:::
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> inbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> inbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> inbound-interface group \<iface_group\>
+
+Match based on the inbound interface group. Prepend the character ``!`` to
+invert the criteria. For example, ``!IFACE_GROUP``
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> outbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> outbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> outbound-interface name \<iface\>
+
+Match based on outbound interface. Wildcard ``*`` is supported. For example:
+``eth2*``. Prepend the character ``!`` to invert the criteria. For example:
+``!eth2``
+```
+:::{note}
+If an interface is attached to a non-default vrf, when using
+**outbound-interface**, the real interface name must be used. For example
+`set firewall ipv4 forward filter rule 10 outbound-interface name eth0`
+:::
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> outbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> outbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> outbound-interface group \<iface_group\>
+
+Match based on outbound interface group. Prepend the character ``!`` to
+invert the criteria. For example: ``!IFACE_GROUP``
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> ipsec [match-ipsec-in | match-ipsec-out | match-none-in | match-none-out]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> ipsec [match-ipsec-in | match-none-in]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> ipsec [match-ipsec-out | match-none-out]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> ipsec [match-ipsec-in | match-ipsec-out | match-none-in | match-none-out]
+
+Match based on ipsec.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> limit burst \<0-4294967295\>
+
+Match based on the maximum number of packets to allow in excess of rate.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> limit rate \<text\>
+
+Specify the maximum average rate as **integer/unit**. For example:
+**5/minutes**
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> packet-length-exclude \<text\>
+
+Match based on packet length. Specify multiple values from 1 to 65535 and
+ranges.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+
+Match based on the packet type.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+
+Match based on protocol number or name as defined in ``/etc/protocols``.
+Special names are ``all`` for all protocols and ``tcp_udp`` for TCP and UDP
+based packets. The ``!`` character negates the selected protocol.
+
+:::{code-block} none
+set firewall ipv4 forward filter rule 10 protocol tcp_udp
+set firewall ipv4 forward filter rule 11 protocol !tcp_udp
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> recent time [second | minute | hour]
+
+Match based on recently seen sources.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> tcp flags [not] \<text\>
+
+Specify TCP flags. Allowed values are ``ack``, ``cwr``, ``ecn``, ``fin``,
+``psh``, ``rst``, ``syn``, and ``urg``. Specify multiple values, and use
+``not`` for inverted selection, as shown in the example.
+
+:::{code-block} none
+set firewall ipv4 input filter rule 10 tcp flags 'ack'
+set firewall ipv4 input filter rule 12 tcp flags 'syn'
+set firewall ipv4 input filter rule 13 tcp flags not 'fin'
+:::
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> state [established | invalid | new | related]
+
+Match against the state of a packet.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> time weekdays \<text\>
+
+Time to match the defined rule.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> ttl \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> ttl \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> ttl \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> ttl \<eq | gt | lt\> \<0-255\>
+
+Match the time to live parameter, where 'eq' means 'equal', 'gt' means
+'greater than', and 'lt' means 'less than'.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv4 input filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv4 output filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv4 name \<name\> rule \<1-999999\> recent time \<second | minute | hour\>
+
+Match when 'count' amount of connections appear within 'time'. Use these
+matching criteria to block brute-force attempts.
+```
+
+### Packet Modifications
+
+Starting from **VyOS-1.5-rolling-202410060007**, the firewall can modify
+packets before sending them out. This feature provides more flexibility in
+packet handling.
+
+```{cfgcmd} set firewall ipv4 prerouting raw rule \<1-999999\> set dscp \<0-63\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> set dscp \<0-63\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set dscp \<0-63\>
+
+Set a specific value of Differentiated Services Codepoint (DSCP).
+```
+
+```{cfgcmd} set firewall ipv4 prerouting raw rule \<1-999999\> set mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> set mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set mark \<1-2147483647\>
+
+Set a specific packet mark value.
+```
+
+```{cfgcmd} set firewall ipv4 prerouting raw rule \<1-999999\> set tcp-mss \<500-1460\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> set tcp-mss \<500-1460\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set tcp-mss \<500-1460\>
+
+Set the TCP-MSS (TCP maximum segment size) for the connection.
+```
+
+```{cfgcmd} set firewall ipv4 prerouting raw rule \<1-999999\> set ttl \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> set ttl \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set ttl \<0-255\>
+
+Set the TTL (Time to Live) value.
+```
+
+```{cfgcmd} set firewall ipv4 forward filter rule \<1-999999\> set connection-mark \<0-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set connection-mark \<0-2147483647\>
+
+Set connection mark value.
+```
+
+## Synproxy
+
+Synproxy connections
+
+```{cfgcmd} set firewall ipv4 [input | forward] filter rule \<1-999999\> action synproxy
+```
+
+```{cfgcmd} set firewall ipv4 [input | forward] filter rule \<1-999999\> protocol tcp
+```
+
+```{cfgcmd} set firewall ipv4 [input | forward] filter rule \<1-999999\> synproxy tcp mss \<501-65535\>
+
+ Set the TCP-MSS (maximum segment size) for the connection
+```
+
+```{cfgcmd} set firewall ipv4 [input | forward] filter rule \<1-999999\> synproxy tcp window-scale \<1-14\>
+
+ Set the window scale factor for TCP window scaling
+```
+
+### Example synproxy
+
+Requirements to enable synproxy:
+
+- Traffic must be symmetric.
+- Synproxy relies on syncookies and TCP timestamps, ensure these are enabled.
+- Disable conntrack loose track option.
+
+```none
+set system sysctl parameter net.ipv4.tcp_timestamps value '1'
+
+set system conntrack tcp loose disable
+
+set system conntrack ignore ipv4 rule 10 destination port '8080'
+
+set system conntrack ignore ipv4 rule 10 protocol 'tcp'
+
+set system conntrack ignore ipv4 rule 10 tcp flags syn
+
+set firewall global-options syn-cookies 'enable'
+
+set firewall ipv4 input filter rule 10 action 'synproxy'
+
+set firewall ipv4 input filter rule 10 destination port '8080'
+
+set firewall ipv4 input filter rule 10 inbound-interface name 'eth1'
+
+set firewall ipv4 input filter rule 10 protocol 'tcp'
+
+set firewall ipv4 input filter rule 10 synproxy tcp mss '1460'
+
+set firewall ipv4 input filter rule 10 synproxy tcp window-scale '7'
+
+set firewall ipv4 input filter rule 1000 action 'drop'
+
+set firewall ipv4 input filter rule 1000 state invalid
+
+```
+
+## Operation-mode Firewall
+
+### Rule-set overview
+
+```{opcmd} show firewall
+
+This will show you a basic firewall overview, for all rule-sets, not
+only for IPv4.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall
+Rulesets Information
+
+---------------------------------
+ipv4 Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------
+20 accept all 0 0 ip saddr @N_TRUSTEDv4 accept
+21 jump all 0 0 jump NAME_AUX
+default accept all 0 0
+
+---------------------------------
+ipv4 Firewall "input filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -------------------------
+10 accept all 156 14377 iifname != @I_LAN accept
+default accept all 0 0
+
+---------------------------------
+ipv4 Firewall "name AUX"
+
+Rule Action Protocol Packets Bytes Conditions
+------ -------- ---------- --------- ------- --------------------------------------------
+10 accept icmp 0 0 meta l4proto icmp accept
+20 accept udp 0 0 meta l4proto udp ip saddr @A_SERVERS accept
+30 drop all 0 0 ip saddr != @A_SERVERS iifname "eth2"
+
+---------------------------------
+ipv4 Firewall "output filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------
+10 reject all 0 0 oifname @I_LAN
+20 accept icmp 2 168 meta l4proto icmp oifname "eth0" accept
+default accept all 72 9258
+
+---------------------------------
+ipv6 Firewall "input filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -------------------------------
+10 accept all 0 0 ip6 saddr @N6_TRUSTEDv6 accept
+default accept all 2 112
+
+vyos@vyos:~$
+:::
+```
+
+```{opcmd} show firewall summary
+
+This shows you a summary of rule-sets and groups.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall summary
+Ruleset Summary
+
+IPv6 Ruleset:
+
+Ruleset Hook Ruleset Priority Description
+-------------- -------------------- -------------------------
+forward filter
+input filter
+ipv6_name IPV6-VyOS_MANAGEMENT
+ipv6_name IPV6-WAN_IN PUBLIC_INTERNET
+
+IPv4 Ruleset:
+
+Ruleset Hook Ruleset Priority Description
+-------------- ------------------ -------------------------
+forward filter
+input filter
+name VyOS_MANAGEMENT
+name WAN_IN PUBLIC_INTERNET
+
+Firewall Groups
+
+Name Type References Members
+----------------------- ------------------ ----------------------- ----------------
+PBX address_group WAN_IN-100 198.51.100.77
+SERVERS address_group WAN_IN-110 192.0.2.10
+WAN_IN-111 192.0.2.11
+WAN_IN-112 192.0.2.12
+WAN_IN-120
+WAN_IN-121
+WAN_IN-122
+SUPPORT address_group VyOS_MANAGEMENT-20 192.168.1.2
+WAN_IN-20
+PHONE_VPN_SERVERS address_group WAN_IN-160 10.6.32.2
+PINGABLE_ADRESSES address_group WAN_IN-170 192.168.5.2
+WAN_IN-171
+PBX ipv6_address_group IPV6-WAN_IN-100 2001:db8::1
+SERVERS ipv6_address_group IPV6-WAN_IN-110 2001:db8::2
+IPV6-WAN_IN-111 2001:db8::3
+IPV6-WAN_IN-112 2001:db8::4
+IPV6-WAN_IN-120
+IPV6-WAN_IN-121
+IPV6-WAN_IN-122
+SUPPORT ipv6_address_group IPV6-VyOS_MANAGEMENT-20 2001:db8::5
+IPV6-WAN_IN-20
+:::
+```
+
+```{opcmd} show firewall ipv4 [forward | input | output] filter
+```
+
+```{opcmd} show firewall ipv4 name \<name\>
+
+This command will give an overview of a single rule-set.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall ipv4 input filter
+Ruleset Information
+---------------------------------
+IPv4 Firewall "input filter"
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------------------
+5 jump all 0 0 iifname "eth2" jump NAME_VyOS_MANAGEMENT
+default accept all
+:::
+```
+
+```{opcmd} show firewall ipv4 [forward | input | output] filter rule \<1-999999\>
+```
+
+```{opcmd} show firewall ipv4 name \<name\> rule \<1-999999\>
+
+This command gives an overview of a rule in a single rule-set, plus
+information for default action.
+```
+```none
+vyos@vyos:~$show firewall ipv4 output filter rule 20
+Rule Information
+
+---------------------------------
+ipv4 Firewall "output filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ----------------------------------------
+20 accept icmp 2 168 meta l4proto icmp oifname "eth0" accept
+default accept all 286 47614
+
+vyos@vyos:~$
+```
+
+```{opcmd} show firewall statistics
+
+This will show you statistics of all rule-sets since the last boot.
+```
+
+### Show Firewall log
+
+```{opcmd} show log firewall
+
+```
+```{opcmd} show log firewall ipv4
+```
+
+```{opcmd} show log firewall ipv4 [forward | input | output | name]
+```
+
+```{opcmd} show log firewall ipv4 [forward | input | output] filter
+```
+
+```{opcmd} show log firewall ipv4 name \<name\>
+```
+
+```{opcmd} show log firewall ipv4 [forward | input | output] filter rule \<rule\>
+```
+
+```{opcmd} show log firewall ipv4 name \<name\> rule \<rule\>
+
+Show the logs of all firewall; show all IPv4 firewall logs; show all logs
+for particular hook; show all logs for particular hook and priority;
+show all logs for particular custom chain; show logs for specific rule-set.
+```
+
+### Example Partial Config
+
+```none
+firewall {
+ group {
+ network-group BAD-NETWORKS {
+ network 198.51.100.0/24
+ network 203.0.113.0/24
+ }
+ network-group GOOD-NETWORKS {
+ network 192.0.2.0/24
+ }
+ port-group BAD-PORTS {
+ port 65535
+ }
+ }
+ ipv4 {
+ forward {
+ filter {
+ default-action accept
+ rule 5 {
+ action accept
+ source {
+ group {
+ network-group GOOD-NETWORKS
+ }
+ }
+ }
+ rule 10 {
+ action drop
+ description "Bad Networks"
+ protocol all
+ source {
+ group {
+ network-group BAD-NETWORKS
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+### Update geoip database
+
+```{opcmd} update geoip
+
+Command to update GeoIP database and firewall sets.
+``` \ No newline at end of file
diff --git a/docs/configuration/firewall/ipv6.md b/docs/configuration/firewall/ipv6.md
new file mode 100644
index 00000000..0ba30110
--- /dev/null
+++ b/docs/configuration/firewall/ipv6.md
@@ -0,0 +1,1567 @@
+---
+lastproofread: '2026-04-01'
+---
+
+(firewall-ipv6-configuration)=
+
+# IPv6 Firewall Configuration
+
+## Overview
+
+This section covers useful information about IPv6 firewall configuration and
+appropriate operation-mode commands.
+
+This section describes the following configuration commands:
+
+```{cfgcmd} set firewall ipv6 ...
+```
+
+To learn about the general traffic flow in VyOS firewalls, see {doc}`Firewall </configuration/firewall/index>`.
+
+```none
+- set firewall
+ * ipv6
+ - forward
+ + filter
+ - input
+ + filter
+ - output
+ + filter
+ + raw
+ - prerouting
+ + raw
+ - name
+ + custom_name
+```
+
+The router first receives all traffic and processes it in the **prerouting**
+section.
+
+
+This stage includes:
+
+
+- **Firewall Prerouting**: commands found under `set firewall ipv6
+ prerouting raw ...`
+- {doc}`Conntrack Ignore</configuration/system/conntrack>`: `set system
+ conntrack ignore ipv6...`
+- {doc}`Policy Route</configuration/policy/route>`: commands found under
+ `set policy route6 ...`
+- {doc}`Destination NAT</configuration/nat/nat44>`: commands found under
+ `set nat66 destination ...`
+
+
+For transit traffic that the router receives and forwards, the base chain is
+**forward**. The following diagram shows a simplified packet flow for transit
+traffic:
+
+
+:::{figure} /_static/images/firewall-fwd-packet-flow.webp
+:::
+
+
+Use `set firewall ipv6 forward filter ...` to configure filtering rules for
+transit traffic. This command corresponds to stage 5 and is highlighted in red
+in the diagram.
+
+
+For traffic destined to the router, use the **input** chain. For traffic the
+router generates, use the **output** chain. The following diagram shows the
+packet flow for traffic destined to the router and traffic generated by the
+router (starting from circle number 6):
+
+
+:::{figure} /_static/images/firewall-input-packet-flow.webp
+:::
+
+
+Use `set firewall ipv6 input filter ...` to configure traffic destined to
+the router.
+
+
+Use `set firewall ipv6 output ...` to configure traffic the router generates.
+Two sub-chains are available: **filter** and **raw**:
+
+
+- **Output Prerouting**: `set firewall ipv6 output raw ...`.
+ As described in **Prerouting**, the firewall processes rules in this
+ section before the connection tracking subsystem.
+- **Output Filter**: `set firewall ipv6 output filter ...`. The firewall
+ processes rules in this section after the connection tracking subsystem.
+
+
+:::{note}
+**Important note about default-actions:**
+If you do not define a default action for a base chain, the system sets
+the default action to **accept** for that chain. For custom chains, if you
+do not define a default action, the system sets the default-action to
+**drop**
+:::
+
+
+Create custom firewall chains using the commands
+`set firewall ipv6 name <name> ...`. To use the custom chain, define a
+rule with **action jump** and the appropriate **target** in a base chain.
+
+
+## Firewall - IPv6 Rules
+
+
+Create firewall rules for firewall filtering. Each rule is numbered and has
+an action to apply when the rule is matched. You can specify multiple matching
+criteria. Packets go through rules from 1 - 999999, so order is crucial. The
+firewall executes the action of the first matching rule.
+
+
+### Actions
+
+
+If you define a rule, you must define an action for it. The action tells the
+firewall what to do when all criteria for that rule are met.
+
+
+The action can be :
+
+
+- `accept`: accept the packet.
+- `continue`: continue parsing next rule.
+- `drop`: drop the packet.
+- `reject`: reject the packet.
+- `jump`: jump to another custom chain.
+- `return`: Return from the current chain and continue at the next rule
+ of the last chain.
+- `queue`: Enqueue packet to userspace.
+- `synproxy`: synproxy the packet.
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return | synproxy]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return | synproxy]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> action [accept | continue | drop | jump | queue | reject | return]
+
+This required setting defines the action of the current rule. If you set
+the action to jump, you must also define a jump-target.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> jump-target \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> jump-target \<text\>
+
+Use this command only when action is set to ``jump``. Specify the jump
+target.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> queue \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> queue \<0-65535\>
+
+Use this command only when action is set to ``queue``. Specify the queue
+target. Queue ranges are also supported.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> queue-options bypass
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> queue-options bypass
+
+Use this command only when action is set to ``queue``. This command allows
+the packet to go through the firewall when no userspace software is connected
+to the queue.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> queue-options fanout
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> queue-options fanout
+
+Use this command only when action is set to ``queue``. This command
+distributes packets among multiple queues.
+```
+
+Also, **default-action** is an action that takes place whenever a packet does
+not match any rule in its chain. For base chains, possible options for
+**default-action** are **accept** or **drop**.
+
+```{cfgcmd} set firewall ipv6 forward filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv6 input filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv6 output filter default-action [accept | drop]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> default-action [accept | drop | jump | queue | reject | return]
+
+Set the default action of the rule-set if a packet does not match any rule
+criteria. If you set default-action to ``jump``, you must also define
+``default-jump-target``. For base chains, you can only set the default
+action to ``accept`` or ``drop``. For custom chains, more actions are
+available.
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> default-jump-target \<text\>
+
+To be used only when ``default-action`` is set to ``jump``. Use this
+command to specify the jump target for the default rule.
+```
+:::{note}
+**Important note about default-actions:**
+If you do not define the default action for a base chain, the system sets
+the default action to **accept** for that chain. For custom chains, if you
+do not define a default action, the system sets the default-action to
+**drop**.
+:::
+
+
+### Firewall Logs
+
+
+You can enable logging for each firewall rule. When enabled, you can also
+define other log options.
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> log
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> log
+
+Enable logging for matched packets. If this configuration command is not
+present, logging is disabled.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter default-log
+```
+
+```{cfgcmd} set firewall ipv6 input filter default-log
+```
+
+```{cfgcmd} set firewall ipv6 output filter default-log
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> default-log
+
+Use this command to enable the logging of the default action on
+the specified chain.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> log-options level [emerg | alert | crit | err | warn | notice | info | debug]
+
+Define log-level. Only applicable if rule log is enabled.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> log-options group \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> log-options group \<0-65535\>
+
+Define the log group to send messages to. Only applicable if rule log is
+enabled.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> log-options snapshot-length \<0-9000\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> log-options snapshot-length \<0-9000\>
+
+Define the length of packet payload to include in a netlink message. Only
+applicable when rule logging is enabled and log group is defined.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> log-options queue-threshold \<0-65535\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> log-options queue-threshold \<0-65535\>
+
+Define the number of packets to queue inside the kernel before sending them
+to userspace. Only applicable when rule logging is enabled and log group is
+defined.
+```
+
+### Firewall Description
+
+
+For reference, you can define descriptions on every rule and custom chain.
+
+```{cfgcmd} set firewall ipv6 name \<name\> description \<text\>
+
+Provide a rule-set description to a custom firewall chain.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> description \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> description \<text\>
+
+Provide a description for each rule.
+```
+
+### Rule Status
+
+
+New rules are enabled by default. In some cases, you may want to disable a
+rule rather than remove it.
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> disable
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> disable
+
+Command for disabling a rule but keep it in the configuration.
+```
+
+### Matching criteria
+
+
+There are a lot of matching criteria against which the packet can be tested.
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> connection-status nat [destination | source]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> connection-status nat [destination | source]
+
+Match packets based on NAT connection status.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> connection-mark \<1-2147483647\>
+
+Match packets based on connection mark.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination address [address | addressrange | CIDR]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination address [address | addressrange | CIDR]
+
+Match based on source or destination address. This is similar to network
+groups, but you can negate the matching addresses here.
+
+:::{code-block} none
+set firewall ipv6 name FOO rule 100 source address 2001:db8::202
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination address-mask [address]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination address-mask [address]
+
+Apply an arbitrary netmask to mask addresses and match only a specific
+portion. This is useful for IPv6 because rules remain valid when the IPv6
+prefix changes if the host portion of the system's IPv6 address is static.
+Examples include SLAAC and tokenised IPv6 addresses
+
+This function works for both individual addresses and address groups.
+
+
+:::{code-block} none
+# Match any IPv6 address with the suffix ::0000:0000:0000:beef
+set firewall ipv6 forward filter rule 100 destination address ::beef
+set firewall ipv6 forward filter rule 100 destination address-mask ::ffff:ffff:ffff:ffff
+# Address groups
+set firewall group ipv6-address-group WEBSERVERS address ::1000
+set firewall group ipv6-address-group WEBSERVERS address ::2000
+set firewall ipv6 forward filter rule 200 source group address-group WEBSERVERS
+set firewall ipv6 forward filter rule 200 source address-mask ::ffff:ffff:ffff:ffff
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination fqdn \<fqdn\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination fqdn \<fqdn\>
+
+Specify a Fully Qualified Domain Name as source or destination to match.
+Ensure that the router can resolve the DNS query.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination geoip country-code \<country\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination geoip inverse-match
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination geoip inverse-match
+
+Match IP addresses based on their geolocation. For more information, see
+GeoIP matching.
+Use inverse-match to match anything except the specified country codes.
+```
+
+DB-IP.com provides data under CC-BY-4.0 license. Attribution is required and
+redistribution is permitted, allowing VyOS to include a database in images
+(approximately 3 MB compressed). The package includes a cron script that you
+can manually call through op-mode update geoip to keep the database and rules
+updated.
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source mac-address \<mac-address\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source mac-address \<mac-address\>
+
+You can specify only a source MAC address to match.
+
+:::{code-block} none
+set firewall ipv6 input filter rule 100 source mac-address 00:53:00:11:22:33
+set firewall ipv6 input filter rule 101 source mac-address !00:53:00:aa:12:34
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination port [1-65535 | portname | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination port [1-65535 | portname | start-end]
+
+Specify a port by number or by name as defined in ``/etc/services``.
+
+:::{code-block} none
+set firewall ipv6 forward filter rule 10 source port '22'
+set firewall ipv6 forward filter rule 11 source port '!http'
+set firewall ipv6 forward filter rule 12 source port 'https'
+:::
+Multiple source ports can be specified as a comma-separated list.
+The whole list can also be "negated" using ``!``. For example:
+
+:::{code-block} none
+set firewall ipv6 forward filter rule 10 source port '!22,https,3333-3338'
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group address-group \<name | !name\>
+
+Specify an address group. You can prepend the character ``!`` to invert the
+matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group dynamic-address-group \<name | !name\>
+
+Specify a dynamic address group. You can prepend the character ``!`` to
+invert the matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group network-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group network-group \<name | !name\>
+
+Specify a network group. You can prepend the character ``!`` to invert the
+matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group port-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group port-group \<name | !name\>
+
+Specify a port group. You can prepend the character ``!`` to invert the
+matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group domain-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group domain-group \<name | !name\>
+
+Specify a domain group. You can prepend the character ``!`` to invert the
+matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> source group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> destination group mac-group \<name | !name\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> destination group mac-group \<name | !name\>
+
+Specify a MAC group. You can prepend the character ``!`` to invert the
+matching criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> dscp [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> dscp-exclude [0-63 | start-end]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> dscp-exclude [0-63 | start-end]
+
+Match based on dscp value.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> fragment [match-frag | match-non-frag]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> fragment [match-frag | match-non-frag]
+
+Match packets based on fragmentation.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> icmpv6 [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> icmpv6 [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> icmpv6 [code | type] \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> icmpv6 [code | type] \<0-255\>
+
+Match packets based on ICMP or ICMPv6 code and type.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> icmpv6 type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> icmpv6 type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> icmpv6 type-name \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> icmpv6 type-name \<text\>
+
+Match based on ICMPv6 type-name. Press **Tab** for information about
+supported **type-name** criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> inbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> inbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> inbound-interface name \<iface\>
+
+Match based on inbound interface. You can use the wildcard ``*``. For
+example: ``eth2*``. You can prepend the character ``!`` to invert the
+matching criteria. For example ``!eth2``
+```
+:::{note}
+If an interface is attached to a non-default VRF, when using
+**inbound-interface**, use the VRF name. For example:
+`set firewall ipv6 forward filter rule 10 inbound-interface name MGMT`
+:::
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> inbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> inbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> inbound-interface group \<iface_group\>
+
+Match based on the inbound interface group. You can prepend the character
+``!`` to invert the matching criteria. For example ``!IFACE_GROUP``
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> outbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> outbound-interface name \<iface\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> outbound-interface name \<iface\>
+
+Match based on outbound interface. You can use the wildcard ``*``. For
+example: ``eth2*``. You can prepend the character ``!`` to invert the
+matching criteria. For example ``!eth2``
+```
+:::{note}
+If an interface is attached to a non-default VRF, when using
+**outbound-interface**, use the physical interface name. For example:
+`set firewall ipv6 forward filter rule 10 outbound-interface name eth0`
+:::
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> outbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> outbound-interface group \<iface_group\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> outbound-interface group \<iface_group\>
+
+Match based on outbound interface group. You can prepend the character ``!``
+to invert the matching criteria. For example ``!IFACE_GROUP``
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> ipsec [match-ipsec-in | match-ipsec-out | match-none-in | match-none-out]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> ipsec [match-ipsec-in | match-none-in]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> ipsec [match-ipsec-out | match-none-out]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> ipsec [match-ipsec-in | match-ipsec-out | match-none-in | match-none-out]
+
+Match packets based on IPsec.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> limit burst \<0-4294967295\>
+
+Match based on the maximum number of packets allowed to exceed the rate
+limit.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> limit rate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> limit rate \<text\>
+
+Match based on the maximum average rate, specified as ``integer/unit``.
+For example, specify ``5/minutes``.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> packet-length \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> packet-length-exclude \<text\>
+
+Match based on packet length. You can specify multiple values from 1 to
+65535 and ranges.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> packet-type [broadcast | host | multicast | other]
+
+Match based on packet type.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> protocol [\<text\> | \<0-255\> | all | tcp_udp]
+
+Match based on protocol number or name as defined in ``/etc/protocols``.
+Specify ``all`` for all protocols and ``tcp_udp`` for TCP and UDP packets.
+Prepend ``!`` to negate the protocol selection.
+
+:::{code-block} none
+set firewall ipv6 input filter rule 10 protocol tcp
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> recent time [second | minute | hour]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> recent time [second | minute | hour]
+
+Match packets based on recently seen sources.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> tcp flags [not] \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> tcp flags [not] \<text\>
+
+Allowed values for TCP flags: ``ack``, ``cwr``, ``ecn``, ``fin``, ``psh``,
+``rst``, ``syn``, and ``urg``. You can specify multiple values. To invert
+the selection, use ``not``, as shown in the following example.
+
+:::{code-block} none
+set firewall ipv6 input filter rule 10 tcp flags 'ack'
+set firewall ipv6 input filter rule 12 tcp flags 'syn'
+set firewall ipv6 input filter rule 13 tcp flags not 'fin'
+:::
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> state [established | invalid | new | related]
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> state [established | invalid | new | related]
+
+Match based on packet state.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> time startdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> time starttime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> time stopdate \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> time stoptime \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> time weekdays \<text\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> time weekdays \<text\>
+
+Match packets based on time criteria.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> hop-limit \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> hop-limit \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> hop-limit \<eq | gt | lt\> \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> hop-limit \<eq | gt | lt\> \<0-255\>
+
+Match the hop-limit parameter. Use ``eq`` for equal, ``gt`` for greater than,
+and ``lt`` for less than.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> recent count \<1-255\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv6 input filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv6 output filter rule \<1-999999\> recent time \<second | minute | hour\>
+```
+
+```{cfgcmd} set firewall ipv6 name \<name\> rule \<1-999999\> recent time \<second | minute | hour\>
+
+Match when the specified number of connections occur within the specified
+time period. Use these criteria to block brute-force attempts.
+```
+
+### Packet Modifications
+
+
+The firewall can modify packets before sending them.
+This feature provides more flexibility for packet handling.
+
+```{cfgcmd} set firewall ipv6 prerouting raw rule \<1-999999\> set dscp \<0-63\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> set dscp \<0-63\>
+```
+
+```{cfgcmd} set firewall ipv6 output [filter | raw] rule \<1-999999\> set dscp \<0-63\>
+
+Set a specific value of Differentiated Services Codepoint (DSCP).
+```
+
+```{cfgcmd} set firewall ipv6 prerouting raw rule \<1-999999\> set mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> set mark \<1-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv6 output [filter | raw] rule \<1-999999\> set mark \<1-2147483647\>
+
+Set a specific packet mark value.
+```
+
+```{cfgcmd} set firewall ipv6 prerouting raw rule \<1-999999\> set tcp-mss \<500-1460\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> set tcp-mss \<500-1460\>
+```
+
+```{cfgcmd} set firewall ipv6 output [filter | raw] rule \<1-999999\> set tcp-mss \<500-1460\>
+
+Set the TCP-MSS (TCP maximum segment size) for the connection.
+```
+
+```{cfgcmd} set firewall ipv6 prerouting raw rule \<1-999999\> set hop-limit \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> set hop-limit \<0-255\>
+```
+
+```{cfgcmd} set firewall ipv6 output [filter | raw] rule \<1-999999\> set hop-limit \<0-255\>
+
+Set hop limit value.
+```
+
+```{cfgcmd} set firewall ipv6 forward filter rule \<1-999999\> set connection-mark \<0-2147483647\>
+```
+
+```{cfgcmd} set firewall ipv4 output [filter | raw] rule \<1-999999\> set connection-mark \<0-2147483647\>
+
+Set connection mark value.
+```
+
+## Synproxy
+
+
+Synproxy connections
+
+```{cfgcmd} set firewall ipv6 [input | forward] filter rule \<1-999999\> action synproxy
+```
+
+```{cfgcmd} set firewall ipv6 [input | forward] filter rule \<1-999999\> protocol tcp
+```
+
+```{cfgcmd} set firewall ipv6 [input | forward] filter rule \<1-999999\> synproxy tcp mss \<501-65535\>
+
+ Set the TCP MSS (maximum segment size) for the connection.
+```
+
+```{cfgcmd} set firewall ipv6 [input | forward] filter rule \<1-999999\> synproxy tcp window-scale \<1-14\>
+
+ Set the window scale factor for TCP window scaling.
+```
+
+### Example synproxy
+
+
+Requirements to enable synproxy:
+
+
+- Traffic must be symmetric
+- Synproxy relies on syncookies and TCP timestamps, ensure these are enabled
+- Disable conntrack loose track option
+
+```none
+set system sysctl parameter net.ipv4.tcp_timestamps value '1'
+
+
+set system conntrack tcp loose disable
+
+set system conntrack ignore ipv6 rule 10 destination port '8080'
+
+set system conntrack ignore ipv6 rule 10 protocol 'tcp'
+
+set system conntrack ignore ipv6 rule 10 tcp flags syn
+
+
+set firewall global-options syn-cookies 'enable'
+
+set firewall ipv6 input filter rule 10 action 'synproxy'
+
+set firewall ipv6 input filter rule 10 destination port '8080'
+
+set firewall ipv6 input filter rule 10 inbound-interface name 'eth1'
+
+set firewall ipv6 input filter rule 10 protocol 'tcp'
+
+set firewall ipv6 input filter rule 10 synproxy tcp mss '1460'
+
+set firewall ipv6 input filter rule 10 synproxy tcp window-scale '7'
+
+set firewall ipv6 input filter rule 1000 action 'drop'
+
+set firewall ipv6 input filter rule 1000 state invalid
+
+```
+
+## Operation-mode Firewall
+
+
+### Rule-set overview
+
+```{opcmd} show firewall
+
+Show a basic firewall overview for all rule-sets, not only for IPv6:
+
+:::{code-block} none
+vyos@vyos:~$ show firewall
+Rulesets Information
+
+---------------------------------
+IPv4 Firewall "forward filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- -----------------------------------------
+5 jump all 0 0 iifname "eth1" jump NAME_VyOS_MANAGEMENT
+10 jump all 0 0 oifname "eth1" jump NAME_WAN_IN
+15 jump all 0 0 iifname "eth3" jump NAME_WAN_IN
+default accept all
+
+---------------------------------
+IPv4 Firewall "name VyOS_MANAGEMENT"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- --------------------------------
+5 accept all 0 0 ct state established accept
+10 drop all 0 0 ct state invalid
+20 accept all 0 0 ip saddr @A_GOOD_GUYS accept
+30 accept all 0 0 ip saddr @N_ENTIRE_RANGE accept
+40 accept all 0 0 ip saddr @A_VyOS_SERVERS accept
+50 accept icmp 0 0 meta l4proto icmp accept
+default drop all 0 0
+
+---------------------------------
+IPv6 Firewall "forward filter"
+
+Rule Action Protocol
+------- -------- ----------
+5 jump all
+10 jump all
+15 jump all
+default accept all
+
+---------------------------------
+IPv6 Firewall "input filter"
+
+Rule Action Protocol
+------- -------- ----------
+5 jump all
+default accept all
+
+---------------------------------
+IPv6 Firewall "ipv6_name IPV6-VyOS_MANAGEMENT"
+
+Rule Action Protocol
+------- -------- ----------
+5 accept all
+10 drop all
+20 accept all
+30 accept all
+40 accept all
+50 accept ipv6-icmp
+default drop all
+:::
+```
+
+```{opcmd} show firewall summary
+
+This will show you a summary of rule-sets and groups
+
+:::{code-block} none
+vyos@vyos:~$ show firewall summary
+Ruleset Summary
+
+IPv6 Ruleset:
+
+Ruleset Hook Ruleset Priority Description
+-------------- -------------------- -------------------------
+forward filter
+input filter
+ipv6_name IPV6-VyOS_MANAGEMENT
+ipv6_name IPV6-WAN_IN PUBLIC_INTERNET
+
+IPv4 Ruleset:
+
+Ruleset Hook Ruleset Priority Description
+-------------- ------------------ -------------------------
+forward filter
+input filter
+name VyOS_MANAGEMENT
+name WAN_IN PUBLIC_INTERNET
+
+Firewall Groups
+
+Name Type References Members
+----------------------- ------------------ ----------------------- ----------------
+PBX address_group WAN_IN-100 198.51.100.77
+SERVERS address_group WAN_IN-110 192.0.2.10
+WAN_IN-111 192.0.2.11
+WAN_IN-112 192.0.2.12
+WAN_IN-120
+WAN_IN-121
+WAN_IN-122
+SUPPORT address_group VyOS_MANAGEMENT-20 192.168.1.2
+WAN_IN-20
+PHONE_VPN_SERVERS address_group WAN_IN-160 10.6.32.2
+PINGABLE_ADRESSES address_group WAN_IN-170 192.168.5.2
+WAN_IN-171
+PBX ipv6_address_group IPV6-WAN_IN-100 2001:db8::1
+SERVERS ipv6_address_group IPV6-WAN_IN-110 2001:db8::2
+IPV6-WAN_IN-111 2001:db8::3
+IPV6-WAN_IN-112 2001:db8::4
+IPV6-WAN_IN-120
+IPV6-WAN_IN-121
+IPV6-WAN_IN-122
+SUPPORT ipv6_address_group IPV6-VyOS_MANAGEMENT-20 2001:db8::5
+IPV6-WAN_IN-20
+:::
+```
+
+```{opcmd} show firewall ipv6 [forward | input | output] filter
+```
+
+```{opcmd} show firewall ipv6 ipv6-name \<name\>
+
+This command will give an overview of a single rule-set.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall ipv6 input filter
+Ruleset Information
+
+---------------------------------
+ipv6 Firewall "input filter"
+
+Rule Action Protocol Packets Bytes Conditions
+------- -------- ---------- --------- ------- ------------------------------------------------------------------------------
+10 jump all 13 1456 iifname "eth1" jump NAME6_INP-ETH1
+20 accept ipv6-icmp 10 1112 meta l4proto ipv6-icmp iifname "eth0" prefix "[ipv6-INP-filter-20-A]" accept
+default accept all 14 1584
+
+vyos@vyos:~$
+:::
+```
+
+```{opcmd} show firewall ipv6 [forward | input | output] filter rule \<1-999999\>
+```
+
+```{opcmd} show firewall ipv6 name \<name\> rule \<1-999999\>
+```
+
+```{opcmd} show firewall ipv6 ipv6-name \<name\> rule \<1-999999\>
+
+This command will give an overview of a rule in a single rule-set
+```
+
+```{opcmd} show firewall group \<name\>
+
+Show an overview of defined groups, including the type, members, and where
+the group is used.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall group LAN
+Firewall Groups
+
+Name Type References Members
+------------ ------------------ ----------------------- ----------------
+LAN ipv6_network_group IPV6-VyOS_MANAGEMENT-30 2001:db8::0/64
+IPV6-WAN_IN-30
+LAN network_group VyOS_MANAGEMENT-30 192.168.200.0/24
+WAN_IN-30
+:::
+```
+
+```{opcmd} show firewall statistics
+
+Show statistics of all rule-sets since the last boot.
+```
+
+### Show Firewall log
+
+```{opcmd} show log firewall
+```
+
+```{opcmd} show log firewall ipv6
+```
+
+```{opcmd} show log firewall ipv6 [forward | input | output | name]
+```
+
+```{opcmd} show log firewall ipv6 [forward | input | output] filter
+```
+
+```{opcmd} show log firewall ipv6 name \<name\>
+```
+
+```{opcmd} show log firewall ipv6 [forward | input | output] filter rule \<rule\>
+```
+
+```{opcmd} show log firewall ipv6 name \<name\> rule \<rule\>
+
+Show firewall logs for all firewalls, all IPv6 firewalls, specific hooks,
+specific priorities, specific custom chains, or specific rule-sets.
+```
+
+### Example Partial Config
+
+```none
+firewall {
+ ipv6 {
+ input {
+ filter {
+ rule 10 {
+ action jump
+ inbound-interface {
+ name eth1
+ }
+ jump-target INP-ETH1
+ }
+ rule 20 {
+ action accept
+ inbound-interface {
+ name eth0
+ }
+ log
+ protocol ipv6-icmp
+ }
+ }
+ }
+ name INP-ETH1 {
+ default-action drop
+ default-log
+ rule 10 {
+ action accept
+ protocol tcp_udp
+ }
+ }
+ }
+}
+```
+
+### Update geoip database
+
+```{opcmd} update geoip
+
+Command used to update GeoIP database and firewall sets.
+``` \ No newline at end of file
diff --git a/docs/configuration/firewall/zone.md b/docs/configuration/firewall/zone.md
new file mode 100644
index 00000000..bbb93993
--- /dev/null
+++ b/docs/configuration/firewall/zone.md
@@ -0,0 +1,201 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(firewall-zone)=
+
+# Zone-Based Firewall
+
+## Overview
+
+:::{note}
+All VyOS versions built after 2023-10-22 (VyOS 1.4 and 1.5) support
+this feature.
+:::
+
+This section provides information on firewall configuration for the
+zone-based firewall. This section covers the following configuration
+commands:
+
+```{cfgcmd} set firewall zone ...
+```
+
+To learn about the general traffic flow in VyOS firewalls,
+see {doc}`Firewall </configuration/firewall/index>`.
+
+```none
+- set firewall
+ * zone
+ - custom_zone_name
+ + ...
+```
+
+In zone-based policy, you assign interfaces to zones and apply inspection
+policy to traffic moving between zones. The firewall acts on traffic
+according to rules. A zone is a group of interfaces that have similar
+functions or features. It establishes the security borders of a network.
+A zone defines a boundary where the system subjects traffic to policy
+restrictions as it crosses to another region of a network.
+
+Key Points:
+- A zone must be configured before you assign an interface to it, and you
+ can assign an interface to only a single zone.
+- All traffic to and from an interface within a zone flows freely.
+- Existing policies affect all traffic between zones.
+- Traffic cannot flow between a zone member interface and any interface that
+ is not a zone member.
+- You must define 2 separate firewalls to define traffic: one for each
+ direction.
+
+:::{note}
+In {vytask}`T2199` the syntax of the zone configuration was changed.
+The zone configuration moved from ``zone-policy zone <name>`` to
+``firewall zone <name>``.
+:::
+
+## Configuration
+
+As an alternative to applying policy to an interface directly, you can
+create a zone-based firewall to simplify configuration when multiple
+interfaces belong to the same security zone. Instead of applying rule-sets
+to interfaces, you apply them to source-destination zone pairs.
+
+You can find a basic introduction to zone-based firewalls in the
+[VyOS Knowledge Base](https://support.vyos.io/en/kb/articles/a-primer-to-zone-based-firewall),
+and an example at {ref}`examples-zone-policy`.
+
+The following steps are required to create a zone-based firewall:
+1. Define both the source and destination zones
+2. Define the rule-set
+3. Apply the rule-set to the zones
+
+### Define a Zone
+
+To define a zone, set up either one with interfaces or as the local zone.
+
+```{cfgcmd} set firewall zone \<name\> interface \<interface\>
+
+Assign interfaces as a member of a zone.
+
+:::{note}
+* An interface can only be a member of one zone.
+* You can have multiple interfaces in a zone. Traffic between
+interfaces in the same zone follows the intra-zone-filtering
+policy (allowed by default).
+:::
+```
+
+```{cfgcmd} set firewall zone \<name\> local-zone
+
+Define the zone as the local zone for traffic that originates from or is
+destined to the router itself.
+
+:::{note}
+* A local zone cannot have any member interfaces
+* You cannot have multiple local zones
+:::
+```
+
+```{cfgcmd} set firewall zone \<name\> default-action [drop | reject]
+
+Modify the zone default-action, which applies to traffic destined to this
+zone that does not match any of the source zone rulesets applied.
+```
+
+```{cfgcmd} set firewall zone \<name\> default-log
+
+Enable logging of packets that match this zone's default-action (disabled
+by default).
+```
+
+```{cfgcmd} set firewall zone \<name\> description
+
+Add a meaningful description.
+```
+
+### Defining a Rule-Set
+
+Zone-based firewall rule-sets define traffic from a *Source Zone* to a
+*Destination Zone*.
+
+You create rule-sets as a custom firewall chain using the commands below
+(refer to the firewall IPv4/IPv6 sections for the full syntax):
+- For {ref}`IPv4<configuration/firewall/ipv4:Firewall - IPv4 Rules>`:
+ `set firewall ipv4 name <name> ...`
+- For {ref}`IPv6<configuration/firewall/ipv6:Firewall - IPv6 Rules>`:
+ `set firewall ipv6 name <name> ...`
+
+It is helpful to name the rule-sets in the format
+`<Source Zone>-<Destination Zone>-<v4 | v6>` to make them easily
+identifiable.
+
+### Applying a Rule-Set to a Zone
+
+After you define a rule-set, apply it to the source and destination zones.
+The configuration syntax anchors to the destination zone, with each of the
+source zone rule-sets listed against the destination.
+
+```{cfgcmd} set firewall zone \<Destination Zone\> from \<Source Zone\> firewall name \<ipv4-rule-set-name\>
+```
+
+```{cfgcmd} set firewall zone \<Destination Zone\> from \<Source Zone\> firewall ipv6-name \<ipv6-rule-set-name\>
+```
+
+You should create two rule-sets for each source-destination zone
+pair.
+
+```none
+set firewall zone DMZ from LAN firewall name LAN-DMZ-v4
+set firewall zone LAN from DMZ firewall name DMZ-LAN-v4
+```
+
+### Applying a Default Rule-Set to a Zone
+
+When a destination zone shares a common rule-set for multiple source zones,
+or when you require a complex set of default policies, you can apply an
+optional default rule-set. The default rule-set applies to all zones that do
+not have a rule-set configured as defined in
+{ref}`IPv4<configuration/firewall/zone:Applying a Rule-Set to a Zone>`
+
+```{cfgcmd} set firewall zone \<Destination Zone\> default-firewall name \<ipv4-rule-set-name\>
+```
+
+```{cfgcmd} set firewall zone \<Destination Zone\> default-firewall ipv6-name \<ipv6-rule-set-name\>
+```
+
+## Operation-mode
+
+```{opcmd} show firewall zone-policy
+
+Display a basic summary of the zone configuration.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall zone-policy
+Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
+------ ------------ ----------- --------------- ---------------
+LAN eth1 WAN WAN-LAN-v4
+eth2
+LOCAL LOCAL LAN LAN-LOCAL-v4
+WAN WAN-LOCAL-v4 WAN-LOCAL-v6
+WAN eth3 LAN LAN-WAN-v4
+eth0 LOCAL LOCAL-WAN-v4
+:::
+```
+
+```{opcmd} show firewall zone-policy zone \<zone\>
+
+Display a basic summary of a particular zone.
+
+:::{code-block} none
+vyos@vyos:~$ show firewall zone-policy zone WAN
+Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
+------ ------------ ----------- --------------- ---------------
+WAN eth3 LAN LAN-WAN-v4
+eth0 LOCAL LOCAL-WAN-v4
+vyos@vyos:~$ show firewall zone-policy zone LOCAL
+Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
+------ ------------ ----------- --------------- ---------------
+LOCAL LOCAL LAN LAN-LOCAL-v4
+WAN WAN-LOCAL-v4 WAN-LOCAL-v6
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/highavailability/index.md b/docs/configuration/highavailability/index.md
new file mode 100644
index 00000000..e26f5791
--- /dev/null
+++ b/docs/configuration/highavailability/index.md
@@ -0,0 +1,561 @@
+---
+lastproofread: '2021-06-30'
+---
+
+(high-availability)=
+
+# High availability
+
+VRRP (Virtual Router Redundancy Protocol) provides active/backup redundancy for
+routers. Every VRRP router has a physical IP/IPv6 address, and a virtual
+address. On startup, routers elect the master, and the router with the highest
+priority becomes the master and assigns the virtual address to its interface.
+All routers with lower priorities become backup routers. The master then starts
+sending keepalive packets to notify other routers that it's available. If the
+master fails and stops sending keepalive packets, the router with the next
+highest priority becomes the new master and takes over the virtual address.
+
+VRRP keepalive packets use multicast, and VRRP setups are limited to a single
+datalink layer segment. You can setup multiple VRRP groups
+(also called virtual routers). Virtual routers are identified by a
+VRID (Virtual Router IDentifier). If you setup multiple groups on the same
+interface, their VRIDs must be unique if they use the same address family,
+but it's possible (even if not recommended for readability reasons) to use
+duplicate VRIDs on different interfaces.
+
+## Basic setup
+
+VRRP groups are created with the
+`set high-availability vrrp group $GROUP_NAME` commands. The required
+parameters are interface, vrid, and address.
+
+minimal config
+
+```none
+set high-availability vrrp group Foo vrid 10
+set high-availability vrrp group Foo interface eth0
+set high-availability vrrp group Foo address 192.0.2.1/24
+```
+
+You can verify your VRRP group status with the operational mode
+`run show vrrp` command:
+
+```none
+vyos@vyos# run show vrrp
+Name Interface VRID State Last Transition
+---------- ----------- ------ ------- -----------------
+Foo eth1 10 MASTER 2s
+```
+
+## IPv6 support
+
+The `address` parameter can be either an IPv4 or IPv6 address, but you can
+not mix IPv4 and IPv6 in the same group, and will need to create groups with
+different VRIDs specially for IPv4 and IPv6.
+If you want to use IPv4 + IPv6 address you can use option `excluded-address`
+
+## Address
+
+The `address` can be configured either on the VRRP interface or on not VRRP
+interface.
+
+```none
+set high-availability vrrp group Foo address 192.0.2.1/24
+set high-availability vrrp group Foo address 203.0.113.22/24 interface eth2
+set high-availability vrrp group Foo address 198.51.100.33/24 interface eth3
+```
+
+## Disabling a VRRP group
+
+You can disable a VRRP group with `disable` option:
+
+```none
+set high-availability vrrp group Foo disable
+```
+
+A disabled group will be removed from the VRRP process and your router will not
+participate in VRRP for that VRID. It will disappear from operational mode
+commands output, rather than enter the backup state.
+
+## Exclude address
+
+Exclude IP addresses from `VRRP packets`. This option `excluded-address` is
+used when you want to set IPv4 + IPv6 addresses on the same virtual interface
+or when used more than 20 IP addresses.
+
+```none
+set high-availability vrrp group Foo excluded-address '203.0.113.254/24'
+set high-availability vrrp group Foo excluded-address '2001:db8:aa::1/64'
+set high-availability vrrp group Foo excluded-address '2001:db8:22::1/64'
+```
+
+## Setting VRRP group priority
+
+VRRP priority can be set with `priority` option:
+
+```none
+set high-availability vrrp group Foo priority 200
+```
+
+The priority must be an integer number from 1 to 255. Higher priority value
+increases router's precedence in the master elections.
+
+## Sync groups
+
+A sync group allows VRRP groups to transition together.
+
+```none
+edit high-availability vrrp
+set sync-group MAIN member VLAN9
+set sync-group MAIN member VLAN20
+```
+
+In the following example, when VLAN9 transitions, VLAN20 will also transition:
+
+```none
+vrrp {
+ group VLAN9 {
+ interface eth0.9
+ address 10.9.1.1/24
+ priority 200
+ vrid 9
+ }
+ group VLAN20 {
+ interface eth0.20
+ priority 200
+ address 10.20.20.1/24
+ vrid 20
+ }
+ sync-group MAIN {
+ member VLAN20
+ member VLAN9
+ }
+}
+```
+
+:::{warning}
+All items in a sync group should be similarly configured.
+If one VRRP group is set to a different preemption delay or priority,
+it would result in an endless transition loop.
+:::
+
+## Preemption
+
+VRRP can use two modes: preemptive and non-preemptive. In the preemptive mode,
+if a router with a higher priority fails and then comes back, routers with lower
+priority will give up their master status. In non-preemptive mode, the newly
+elected master will keep the master status and the virtual address indefinitely.
+
+By default VRRP uses preemption. You can disable it with the "no-preempt"
+option:
+
+```none
+set high-availability vrrp group Foo no-preempt
+```
+
+You can also configure the time interval for preemption with the "preempt-delay"
+option. For example, to set the higher priority router to take over in 180
+seconds, use:
+
+```none
+set high-availability vrrp group Foo preempt-delay 180
+```
+
+## Track
+
+Track option to track non VRRP interface states. VRRP changes status to
+`FAULT` if one of the track interfaces in state `down`.
+
+```none
+set high-availability vrrp group Foo track interface eth0
+set high-availability vrrp group Foo track interface eth1
+```
+
+Ignore VRRP main interface faults
+
+```none
+set high-availability vrrp group Foo track exclude-vrrp-interface
+```
+
+## Unicast VRRP
+
+By default VRRP uses multicast packets. If your network does not support
+multicast for whatever reason, you can make VRRP use unicast communication
+instead.
+
+```none
+set high-availability vrrp group Foo peer-address 192.0.2.10
+set high-availability vrrp group Foo hello-source-address 192.0.2.15
+```
+
+## rfc3768-compatibility
+
+RFC 3768 defines a virtual MAC address to each VRRP virtual router.
+This virtual router MAC address will be used as the source in all periodic VRRP
+messages sent by the active node. When the rfc3768-compatibility option is set,
+a new VRRP interface is created, to which the MAC address and the virtual IP
+address is automatically assigned.
+
+```none
+set high-availability vrrp group Foo rfc3768-compatibility
+```
+
+Verification
+
+```none
+$show interfaces ethernet eth0v10
+eth0v10@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
+state UP group default qlen 1000
+link/ether 00:00:5e:00:01:0a brd ff:ff:ff:ff:ff:ff
+inet 172.25.0.247/16 scope global eth0v10
+valid_lft forever preferred_lft forever
+```
+
+:::{warning}
+RFC 3768 creates a virtual interface. If you want to apply
+the destination NAT rule to the traffic sent to the virtual MAC, set
+the created virtual interface as `inbound-interface`.
+:::
+
+## Global options
+
+On most scenarios, there's no need to change specific parameters, and using
+default configuration is enough. But there are cases were extra configuration
+is needed.
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters startup_delay <1-600>
+
+ This option specifies a delay in seconds before vrrp instances start up
+ after keepalived starts.
+```
+
+## Gratuitous ARP
+
+These configuration is not mandatory and in most cases there's no
+need to configure it. But if necessary, Gratuitous ARP can be configured in
+`global-parameters` and/or in `group` section.
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters garp interval
+ <0.000-1000>
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp group <name> garp interval <0.000-1000>
+
+ Set delay between gratuitous ARP messages sent on an interface.
+
+ 0 if not defined.
+```
+
+% stop_vyoslinter
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters garp master-delay <1-255>
+```
+
+% start_vyoslinter
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp group <name> garp master-delay <1-255>
+
+ Set delay for second set of gratuitous ARPs after transition to MASTER.
+
+ 5 if not defined.
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters garp master-refresh
+ <1-600>
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp group <name> garp master-refresh
+ <1-600>
+
+ Set minimum time interval for refreshing gratuitous ARPs while MASTER.
+
+ 0 if not defined, which means no refreshing.
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters garp
+ master-refresh-repeat <1-600>
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp group <name> garp
+ master-refresh-repeat <1-600>
+
+ Set number of gratuitous ARP messages to send at a time while MASTER.
+
+ 1 if not defined.
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters garp master-repeat
+ <1-600>
+```
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp group <name> garp master-repeat
+ <1-600>
+
+ Set number of gratuitous ARP messages to send at a time after transition to
+ MASTER.
+
+ 5 if not defined.
+```
+
+## Version
+
+```{eval-rst}
+.. cfgcmd:: set high-availability vrrp global-parameters version 2|3
+
+ Set the default VRRP version to use. This defaults to 2, but IPv6 instances
+ will always use version 3.
+```
+
+## Scripting
+
+VRRP functionality can be extended with scripts. VyOS supports two kinds of
+scripts: health check scripts and transition scripts. Health check scripts
+execute custom checks in addition to the master router reachability. Transition
+scripts are executed when VRRP state changes from master to backup or fault and
+vice versa and can be used to enable or disable certain services, for example.
+
+:::{note}
+Simply placing script files in `/config/scripts/` does not mean the
+system can execute them. To make custom scripts executable, grant them
+**execute permissions**. Use the following command:
+
+```none
+chmod +x /config/scripts/script-name.sh
+```
+:::
+
+:::{warning}
+It is not recommended to change VRRP configuration
+inside health-check and transition scripts.
+:::
+
+### Health check scripts
+
+There is the ability to run an arbitrary script at regular intervals
+according to health-check parameters. If a script returns 0, it
+indicates success. If a script returns anything else, it will indicate
+that the VRRP instance should enter the FAULT state.
+
+This setup will make the VRRP process execute the
+`/config/scripts/vrrp-check.sh script` every 60 seconds, and transition the
+group to the fault state if it fails (i.e. exits with non-zero status) three
+times:
+
+% stop_vyoslinter
+
+```none
+set high-availability vrrp group Foo health-check script /config/scripts/vrrp-check.sh
+set high-availability vrrp group Foo health-check interval 60
+set high-availability vrrp group Foo health-check failure-count 3
+```
+
+% start_vyoslinter
+
+An optional `timeout` can be set to define the maximum number of seconds the
+script is allowed to run. This is useful for scripts that may hang or take
+longer than expected — setting the timeout higher than the interval allows
+longer-running scripts to complete before being considered failed.
+
+% stop_vyoslinter
+
+```none
+set high-availability vrrp group Foo health-check script /config/scripts/vrrp-check.sh
+set high-availability vrrp group Foo health-check interval 20
+set high-availability vrrp group Foo health-check failure-count 3
+set high-availability vrrp group Foo health-check timeout 40
+```
+
+% start_vyoslinter
+
+When the vrrp group is a member of the sync group will use only
+the sync group health check script.
+This example shows how to configure it for the sync group:
+
+% stop_vyoslinter
+
+```none
+set high-availability vrrp sync-group Bar health-check script /config/scripts/vrrp-check.sh
+set high-availability vrrp sync-group Bar health-check interval 60
+set high-availability vrrp sync-group Bar health-check failure-count 3
+```
+
+% start_vyoslinter
+
+### Transition scripts
+
+Transition scripts can help you implement various fixups, such as starting and
+stopping services, or even modifying the VyOS config on VRRP transition.
+This setup will make the VRRP process execute the
+`/config/scripts/vrrp-fail.sh` with argument `Foo` when VRRP fails,
+and the `/config/scripts/vrrp-master.sh` when the router becomes the master:
+
+% stop_vyoslinter
+
+```none
+set high-availability vrrp group Foo transition-script backup "/config/scripts/vrrp-fail.sh Foo"
+set high-availability vrrp group Foo transition-script fault "/config/scripts/vrrp-fail.sh Foo"
+set high-availability vrrp group Foo transition-script master "/config/scripts/vrrp-master.sh Foo"
+```
+
+% start_vyoslinter
+
+To know more about scripting, check the {ref}`command-scripting` section.
+
+## Virtual-server
+
+```{eval-rst}
+.. include:: /_include/need_improvement.txt
+```
+
+Virtual Server allows to Load-balance traffic destination virtual-address:port
+between several real servers.
+
+### Algorithm
+
+Load-balancing schedule algorithm:
+
+- round-robin
+- weighted-round-robin
+- least-connection
+- weighted-least-connection
+- source-hashing
+- destination-hashing
+- locality-based-least-connection
+
+```none
+set high-availability virtual-server 203.0.113.1 algorithm 'least-connection'
+```
+
+### Forward method
+
+- NAT
+- direct
+- tunnel
+
+```none
+set high-availability virtual-server 203.0.113.1 forward-method 'nat'
+```
+
+### Health-check
+
+Custom health-check script allows checking real-server availability
+
+% stop_vyoslinter
+
+```none
+set high-availability virtual-server 203.0.113.1 real-server 192.0.2.11 health-check script <path-to-script>
+```
+
+% start_vyoslinter
+
+### Fwmark
+
+Firewall mark. It possible to loadbalancing traffic based on `fwmark` value
+
+```none
+set high-availability virtual-server 203.0.113.1 fwmark '111'
+```
+
+### Real server
+
+Real server IP address and port
+
+% stop_vyoslinter
+
+```none
+set high-availability virtual-server 203.0.113.1 real-server 192.0.2.11 port '80'
+```
+
+% start_vyoslinter
+
+### Example
+
+Virtual-server can be configured with VRRP virtual address or without VRRP.
+
+In the next example all traffic destined to `203.0.113.1` and port `8280`
+protocol TCP is balanced between 2 real servers `192.0.2.11` and
+`192.0.2.12` to port `80`
+
+Real server is auto-excluded if port check with this server fail.
+
+% stop_vyoslinter
+
+```none
+set interfaces ethernet eth0 address '203.0.113.11/24'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+set high-availability vrrp group FOO interface 'eth0'
+set high-availability vrrp group FOO no-preempt
+set high-availability vrrp group FOO priority '150'
+set high-availability vrrp group FOO address '203.0.113.1/24'
+set high-availability vrrp group FOO vrid '10'
+
+set high-availability virtual-server 203.0.113.1 algorithm 'source-hashing'
+set high-availability virtual-server 203.0.113.1 delay-loop '10'
+set high-availability virtual-server 203.0.113.1 forward-method 'nat'
+set high-availability virtual-server 203.0.113.1 persistence-timeout '180'
+set high-availability virtual-server 203.0.113.1 port '8280'
+set high-availability virtual-server 203.0.113.1 protocol 'tcp'
+set high-availability virtual-server 203.0.113.1 real-server 192.0.2.11 port '80'
+set high-availability virtual-server 203.0.113.1 real-server 192.0.2.12 port '80'
+```
+
+% start_vyoslinter
+
+A firewall mark `fwmark` allows using multiple ports for high-availability
+virtual-server.
+It uses fwmark value.
+
+In this example all traffic destined to ports "80, 2222, 8888" protocol TCP
+marks to fwmark "111" and balanced between 2 real servers.
+Port "0" is required if multiple ports are used.
+
+% stop_vyoslinter
+
+```none
+set interfaces ethernet eth0 address 'dhcp'
+set interfaces ethernet eth0 description 'WAN'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+set interfaces ethernet eth1 description 'LAN'
+
+set policy route PR interface 'eth0'
+set policy route PR rule 10 destination port '80,2222,8888'
+set policy route PR rule 10 protocol 'tcp'
+set policy route PR rule 10 set mark '111'
+
+set high-availability virtual-server vyos fwmark '111'
+set high-availability virtual-server vyos protocol 'tcp'
+set high-availability virtual-server vyos real-server 192.0.2.11 health-check script '/config/scripts/check-real-server-first.sh'
+set high-availability virtual-server vyos real-server 192.0.2.11 port '0'
+set high-availability virtual-server vyos real-server 192.0.2.12 health-check script '/config/scripts/check-real-server-second.sh'
+set high-availability virtual-server vyos real-server 192.0.2.12 port '0'
+
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 source address '192.0.2.0/24'
+set nat source rule 100 translation address 'masquerade'
+```
+
+% start_vyoslinter
+
+Op-mode check virtual-server status
+
+```none
+vyos@r14:~$ run show virtual-server
+IP Virtual Server version 1.2.1 (size=4096)
+Prot LocalAddress:Port Scheduler Flags
+ -> RemoteAddress:Port Forward Weight ActiveConn InActConn
+FWM 111 lc persistent 300
+ -> 192.0.2.11:0 Masq 1 0 0
+ -> 192.0.2.12:0 Masq 1 1 0
+```
+
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
new file mode 100644
index 00000000..3e215502
--- /dev/null
+++ b/docs/configuration/index.md
@@ -0,0 +1,23 @@
+# Configuration Guide
+
+The following structure represents the CLI structure.
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+container/index
+firewall/index
+highavailability/index
+interfaces/index
+loadbalancing/index
+nat/index
+policy/index
+pki/index
+protocols/index
+service/index
+system/index
+trafficpolicy/index
+vpn/index
+vrf/index
+```
diff --git a/docs/configuration/interfaces/bonding.md b/docs/configuration/interfaces/bonding.md
new file mode 100644
index 00000000..7a07a27c
--- /dev/null
+++ b/docs/configuration/interfaces/bonding.md
@@ -0,0 +1,764 @@
+---
+lastproofread: '2025-12-09'
+---
+
+(bond-interface)=
+
+# Bond / link aggregation
+
+A **bonding interface** aggregates multiple network interfaces into a single
+logical interface (referred to as a bond, {abbr}`LAG (Link Aggregation Group)`,
+EtherChannel, or port-channel).
+
+The behavior of a bonding interface depends on the selected mode. Modes provide
+either fault tolerance or a combination of load balancing and fault tolerance.
+Additionally, the bonding interface can be configured for link integrity
+monitoring.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: bonding
+:var1: bond0
+```
+
+### Member interfaces
+
+```{cfgcmd} set interfaces bonding \<interface\> member interface \<member\>
+
+**Add an interface to the bonding group.**
+
+**Example:**
+
+To configure eth0 and eth1 as members of the bonding interface bond0, execute
+the following commands:
+```
+
+```none
+set interfaces bonding bond0 member interface eth0
+set interfaces bonding bond0 member interface eth1
+```
+
+### Bond modes
+
+````{cfgcmd} set interfaces bonding \<interface\> mode \<802.3ad | active-backup | broadcast | round-robin | transmit-load-balance | adaptive-load-balance | xor-hash\>
+
+```{eval-rst}
+**Configure the bonding mode on the interface. The default mode is**
+``802.3ad``.
+
+The available modes are:
+
+* ``802.3ad``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - IEEE 802.3ad Dynamic Link Aggregation. Groups only member
+ interfaces with the same speed (e.g., 1 Gbps) and duplex
+ settings. Member interfaces with different speed and duplex
+ settings are not included in the active bond.
+
+ Provides load balancing and fault tolerance. Uses the
+ :abbr:`LACP (Link Aggregation Control Protocol)` to
+ negotiate the bond with the switch.
+ * - **Traffic distribution:**
+ - Traffic is distributed according to the **transmit hash
+ policy** (default: XOR).
+
+ The bonding driver applies an XOR operation to specific
+ packet header fields, generating a hash value that maps to
+ a particular member interface. This ensures the same network
+ flow is consistently transmitted over the same member
+ interface.
+
+ The transmit hash policy is configured via the ``hash-policy`` option.
+ * - **Failover:**
+ - If a member interface fails, the hash is recalculated to distribute
+ traffic among the remaining active member interfaces.
+
+.. note:: Not all transmit hash policies comply with 802.3ad, particularly
+ section 43.2.4. Using a non-compliant policy may result in out-of-order
+ packet delivery.
+
+* ``active-backup``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - Provides fault tolerance. Only one member interface is active
+ at a time. Other member interfaces remain in a standby mode.
+ * - **Traffic distribution:**
+ - All traffic (incoming and outgoing) is routed via one active
+ member interface.
+ * - **Failover:**
+ - If the designated member interface fails, all traffic is
+ routed to another member interface. The bonding driver sends
+ a Gratuitous ARP to update the peer's MAC address table,
+ linking the bond's MAC address to another physical port.
+
+* ``broadcast``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - Provides maximum fault tolerance by duplicating traffic.
+ * - **Traffic distribution:**
+ - Every packet is duplicated and transmitted on **all** member
+ interfaces.
+ * - **Failover:**
+ - Traffic flow is not interrupted as long as at least one
+ member interface remains active.
+
+* ``round-robin``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - Provides load balancing and fault tolerance.
+ * - **Traffic distribution:**
+ - Packets are transmitted in sequential order across the member
+ interfaces (e.g., packet 1 > interface A, packet 2 >
+ interface B, etc.).
+ * - **Failover:**
+ - If a member interface fails, the sequence skips the failed
+ interface and continues with the remaining active members.
+
+* ``transmit-load-balance``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - Provides adaptive transmit load balancing and fault tolerance.
+ * - **Traffic distribution:**
+ - **Outgoing:** Distributed across all active member interfaces
+ based on the current load.
+
+ **Incoming:** Received by a designated member interface
+ (active receiver).
+ * - **Failover:**
+ - If the active receiver fails, another member interface takes
+ over as the new active receiver.
+
+* ``adaptive-load-balance``
+
+.. list-table::
+ :widths: 20 80
+
+ * - **Description:**
+ - Provides adaptive transmit load balancing identical to
+ ``transmit-load-balance``, receive load balancing for IPv4
+ traffic, and fault tolerance for both incoming and outgoing
+ traffic.
+ * - **Traffic distribution:**
+ - **Outgoing:** Identical to ``transmit-load-balance``.
+
+ **Incoming:** Distributed based on ARP manipulation. For
+ both local and remote connections, the bonding driver
+ intercepts ARP traffic and changes the source MAC address
+ to the MAC address of the least loaded member interface.
+
+ All traffic from that peer is then routed to the chosen
+ member interface.
+ * - **Failover:**
+ - If a member interface's state changes (fails, recovers, is
+ added, or excluded), the traffic is redistributed among all
+ active member interfaces.
+
+* ``xor-hash``: Provides load balancing and fault tolerance
+ based on a hash formula. Distributes traffic and handles
+ failover identically to ``802.3ad``, but operates without
+ the :abbr:`LACP (Link Aggregation Control Protocol)`.
+```
+
+````
+
+```{cfgcmd} set interfaces bonding \<interface\> min-links \<0-16\>
+
+**Configure how many member interfaces must be active (in the
+link-up state) to mark the bonding interface UP (carrier
+asserted).**
+
+This command applies only when the bonding interface is configured
+in 802.3ad mode and functions like the Cisco EtherChannel min-links
+feature. It ensures that a bonding interface is marked UP (carrier
+asserted) only when a specified number of member interfaces are
+active (in the link-up state). This helps guarantee a minimum level
+of bandwidth for higher-level services (such as clustering) relying
+on the bonding interface.
+
+The default value is 0. This marks the bonding interface UP
+(carrier asserted) whenever an active LACP aggregator exists,
+regardless of the number of member interfaces in that aggregator.
+
+:::{note}
+In 802.3ad mode, a bond cannot be active without at least one active
+member interface. Therefore, setting min-links to 0 or 1 has the same result:
+the bonding interface is marked UP (carrier asserted).
+:::
+```
+
+```{cfgcmd} set interfaces bonding \<interface\> lacp-rate \<slow|fast\>
+
+**Configure the rate at which the bonding interface requests its link
+partner to send** {abbr}`LACPDUs (Link Aggregation Control Protocol Data
+Units)` **in 802.3ad mode.**
+
+This command applies only when the bonding interface is configured in
+802.3ad mode.
+
+The following options are available:
+
+* **slow (default):** Requests the link partner to transmit LACPDUs every 30 seconds.
+
+* **fast:** Requests the link partner to transmit LACPDUs every 1 second.
+```
+```{cfgcmd} set interfaces bonding \<interface\> system-mac \<mac address\>
+
+**Configure a specific MAC address for the bonding interface.**
+
+This sets the 802.3ad system MAC address, which is used for {abbr}`LACPDU (Link
+Aggregation Control Protocol Data Unit)` exchanges with the link partner.
+You can assign a fixed MAC address or generate a random one for these
+{abbr}`LACPDU (Link Aggregation Control Protocol Data Unit)` exchanges.
+```
+```{cfgcmd} set interfaces bonding \<interface\> hash-policy \<policy\>
+
+**Configure which transmit hash policy to use for distributing traffic across
+member interfaces.**
+
+The following policies are available:
+
+* ``layer2``
+
+**Description:** Routes all traffic destined for a specific network peer through
+the same member interface. The policy is 802.3ad-compliant.
+
+**Hash inputs:** Source MAC address, destination MAC address, and Ethernet packet
+type ID.
+
+**Formula:**
+
+:::{code-block} none
+hash = source MAC address XOR destination MAC address XOR packet type ID
+member interface number = hash modulo member interface count
+:::
+
+* ``layer2+3``
+
+**Description:** Similar to ``layer2``, routes all traffic destined for a specific
+network peer through the same member interface and is IEEE 802.3ad-compliant. Uses
+both Layer 2 and Layer 3 information to provide a more balanced traffic distribution.
+
+**Hash inputs:**
+* Source MAC address, destination MAC address, and Ethernet packet type ID.
+* Source IP address, destination IP address. IPv6 addresses are first hashed
+ using ``IPv6_addr_hash``.
+
+**Formula:**
+
+:::{code-block} none
+hash = source MAC address XOR destination MAC address XOR packet type ID
+hash = hash XOR source IP address XOR destination IP address
+hash = hash XOR (hash RSHIFT 16)
+hash = hash XOR (hash RSHIFT 8)
+member interface number = hash modulo member interface count
+:::
+
+For non-IP traffic, the formula is the same as for ``layer2``.
+
+* ``layer3+4``
+
+**Description:** Routes different connections (flows) destined for a specific
+network peer through multiple member interfaces, but ensures each individual
+flow is routed through only one member interface.
+
+:::{note}
+This policy is not fully 802.3ad-compliant. When a single TCP or UDP flow
+contains both fragmented and unfragmented packets, the algorithm may distribute
+them across different member interfaces. This may result in out-of-order packet
+delivery, violating the 802.3ad standard.
+:::
+
+**Hash inputs:**
+* Source port, destination port (if available).
+* Source IP address, destination IP address. IPv6 addresses are first hashed
+ using ``IPv6_addr_hash``.
+
+**Formula:**
+
+:::{code-block} none
+hash = source port, destination port (as in the header)
+hash = hash XOR source IP address XOR destination IP address
+hash = hash XOR (hash RSHIFT 16)
+hash = hash XOR (hash RSHIFT 8)
+member interface number = hash modulo member interface count
+:::
+
+For fragmented TCP or UDP packets and all other IPv4 and IPv6 traffic, the
+source and destination port information is omitted.
+
+For non-IP traffic, the formula is the same as for ``layer2``.
+```
+
+
+```{cfgcmd} set interfaces bonding \<interface\> primary \<interface\>
+
+**Configure the primary member interface in the bond.**
+
+The primary member interface remains active as long as it is operational;
+alternative member interfaces are used only if it fails.
+
+Use this configuration when a specific member interface is preferred,
+such as one with higher throughput.
+
+This command applies only to ``active-backup``, ``transmit-load-balance``, and
+``adaptive-load-balance`` modes.
+```
+
+
+```{cfgcmd} set interfaces bonding \<interface\> arp-monitor interval \<time\>
+
+**Configure the ARP monitoring interval, in seconds, for the bonding interface.**
+
+ARP monitoring periodically assesses the health of each member interface by
+checking whether it has recently sent or received traffic (this criterion
+varies depending on the bonding mode and the member interface’s state). ARP
+probes are sent to the IP addresses specified with the arp-monitor target option.
+
+When ARP monitoring is used with EtherChannel-compatible modes (such as
+``round-robin`` or ``xor-hash``), the switch should be configured to distribute
+traffic across all member interfaces. If the switch distributes traffic using
+an XOR-based policy, all ARP replies will be received on one member interface,
+causing other member interfaces to be incorrectly marked as failed.
+
+Setting this value to 0 disables ARP monitoring.
+
+The default value is 0.
+```
+
+
+```{cfgcmd} set interfaces bonding \<interface\> arp-monitor target \<address\>
+
+**Configure the IP addresses for ARP monitoring requests.**
+
+The bonding driver sends ARP requests to these IP addresses to check the
+state of member interfaces.
+
+To enable ARP monitoring, configure at least one IP address (up to 16 per
+bonding interface).
+
+By default, no IP addresses are configured.
+```
+
+### {abbr}`VLAN (Virtual Local Area Network)`
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: bonding
+:var1: bond0
+```
+
+### SPAN port mirroring
+
+```{cmdincludemd} ../../_include/interface-mirror.txt
+:var0: bonding
+:var1: bond1
+:var2: eth3
+```
+
+#### EVPN multihoming
+
+
+EVPN multihoming (EVPN-MH) is a standards-based solution (RFC 7432, RFC 8365)
+that enables Customer Edge (CE) devices, such as servers, to connect to two
+or more Provider Edge (PE) devices for redundancy and load balancing.
+
+
+EVPN-MH is often used as a modern, standards-based alternative to
+{abbr}`MLAG (Multi-Chassis Link Aggregation)` and {abbr}`VTEPs (Virtual
+Tunnel Endpoints)`.
+
+
+**Ethernet Segment (ES) and Ethernet Segment Identifier (ESI)**
+
+
+Physical links that connect a CE device to PE devices are bundled using link
+aggregation. This logical bundle is called an Ethernet Segment (ES) and is
+uniquely identified by an Ethernet Segment Identifier (ESI) within the
+EVPN domain.
+
+
+To enable EVPN-MH, configure the same ESI on the bonding interfaces of all
+PE devices connected to a single CE device.
+
+
+An ESI is configured by specifying either a system MAC address and a local
+discriminator, or an Ethernet Segment Identifier Name (ESINAME).
+
+
+The following two commands generate a 10-byte Type-3 ESI by combining the
+system MAC and local discriminator:
+
+```{cfgcmd} set interfaces bonding \<interface\> evpn es-id \<1-16777215|10-byte ID\>
+
+```
+```{cfgcmd} set interfaces bonding \<interface\> evpn es-sys-mac \<xx:xx:xx:xx:xx:xx\>
+
+Alternatively, assign an ESINAME directly as a 10-byte Type-0 ESI using the
+following format: 00:AA:BB:CC:DD:EE:FF:GG:HH:II.
+
+**BGP-EVPN route usage**
+
+EVPN-MH uses BGP-EVPN route types 1 and 2 for ES discovery and MAC-IP
+synchronization:
+
+* **Type 1 (EAD-per-ES and EAD-per-EVI)** routes advertise the locally
+attached ESs and discover remote ESs in the network.
+* **Type 2 (MAC-IP advertisement)** routes are advertised with a
+destination ESI, enabling MAC-IP synchronization between ES peers.
+```
+
+```{cfgcmd} set interfaces bonding \<interface\> evpn es-df-pref \<1-65535\>
+
+**Configure the** {abbr}`DF (Designated Forwarder)` **preference (1-65535) for
+the interface. A higher value indicates a higher preference to become the**
+{abbr}`DF (Designated Forwarder)`. **The** {abbr}`DF (Designated Forwarder)`
+**preference is configured per-ES.**
+
+The DF election process determines which interface in a specific ES forwards
+{abbr}`BUM (Broadcast, Unknown Unicast, and Multicast)` traffic from the EVPN
+overlay to the connected CE device. EVPN Type-4 (Ethernet Segment) routes are
+used to elect the DF, implementing the preference-based election method defined
+in RFC 9785.
+
+Interfaces not elected as the DF drop any BUM traffic from the EVPN overlay
+using non-DF filters. Similarly, traffic received from ES peers via the EVPN
+overlay is blocked from forwarding to the CE device to maintain split-horizon
+filtering with local bias.
+```
+
+```{cmdincludemd} /_include/interface-evpn-uplink.txt
+:var0: bonding
+:var1: bond0
+```
+
+## Example
+
+
+The following configuration example applies to all listed third-party vendors.
+It creates a bonding interface with two member interfaces, defines VLANs 10
+and 100 on the bonding interface, and assigns an IPv4 address to each VLAN
+subinterface.
+
+```none
+# Create the bonding interface bond0 with 802.3ad LACP
+set interfaces bonding bond0 hash-policy 'layer2'
+set interfaces bonding bond0 mode '802.3ad'
+
+# Add the required VLANs and IPv4 addresses on them
+set interfaces bonding bond0 vif 10 address 192.168.0.1/24
+set interfaces bonding bond0 vif 100 address 10.10.10.1/24
+
+# Add the member interfaces to the bonding interface
+set interfaces bonding bond0 member interface eth1
+set interfaces bonding bond0 member interface eth2
+```
+:::{note}
+If you are running this configuration in a virtual environment like
+EVE-NG, ensure the e1000 driver is chosen for your VyOS NIC. The default
+drivers, such as ``virtio-net-pci`` or ``vmxnet3``, are incompatible with
+this configuration. Specifically, ICMP messages will not be processed
+correctly.
+
+To check your NIC driver, use the following command:
+``show interfaces ethernet eth0 physical | grep -i driver``
+:::
+
+
+### Cisco Catalyst configuration
+
+
+Configure a Cisco Catalyst switch to integrate with a two-member VyOS bonding
+interface.
+
+
+Assign member interfaces to PortChannel:
+
+```none
+interface GigabitEthernet1/0/23
+ description VyOS eth1
+ channel-group 1 mode active
+!
+interface GigabitEthernet1/0/24
+ description VyOS eth2
+ channel-group 1 mode active
+!
+```
+
+A new interface, `Port-channel1`, becomes available; all configuration,
+such as allowed VLAN interfaces and STP, is applied here.
+
+```none
+interface Port-channel1
+ description LACP Channel for VyOS
+ switchport trunk encapsulation dot1q
+ switchport trunk allowed vlan 10,100
+ switchport mode trunk
+ spanning-tree portfast trunk
+!
+```
+
+### Juniper EX Switch configuration
+
+
+Configure a Juniper EX Series switch to integrate with a two-member VyOS bonding
+interface.
+
+```none
+# Create aggregated ethernet device with 802.3ad LACP and port speeds of 10gbit/s
+set interfaces ae0 aggregated-ether-options link-speed 10g
+set interfaces ae0 aggregated-ether-options lacp active
+
+# Create layer 2 on the aggregated ethernet device with trunking for our VLANs
+set interfaces ae0 unit 0 family ethernet-switching port-mode trunk
+
+# Add the required vlans to the device
+set interfaces ae0 unit 0 family ethernet-switching vlan members 10
+set interfaces ae0 unit 0 family ethernet-switching vlan members 100
+
+# Add the two interfaces to the aggregated ethernet device, in this setup both
+# ports are on the same switch (switch 0, module 1, port 0 and 1)
+set interfaces xe-0/1/0 ether-options 802.3ad ae0
+set interfaces xe-0/1/1 ether-options 802.3ad ae0
+
+# But this can also be done with multiple switches in a stack, a virtual
+# chassis on Juniper (switch 0 and switch 1, module 1, port 0 on both switches)
+set interfaces xe-0/1/0 ether-options 802.3ad ae0
+set interfaces xe-1/1/0 ether-options 802.3ad ae0
+```
+
+### Aruba/HP configuration
+
+
+Configure an Aruba/HP 2510G switch to integrate with a two-member VyOS bonding
+interface.
+
+```none
+# Create trunk with 2 member interfaces (interface 1 and 2) and LACP
+trunk 1-2 Trk1 LACP
+
+# Add the required VLANs to the trunk
+vlan 10 tagged Trk1
+vlan 100 tagged Trk1
+```
+
+### Arista EOS configuration
+
+
+When deploying VyOS in environments with Arista switches, use the following
+blueprint as an initial setup to configure an operational LACP port-channel
+between the two devices.
+
+
+Let's assume the following topology:
+
+
+```{eval-rst}
+.. figure:: /_static/images/vyos_arista_bond_lacp.webp
+ :alt: VyOS Arista EOS setup
+```
+
+
+**R1**
+
+```none
+interfaces {
+ bonding bond10 {
+ hash-policy layer3+4
+ member {
+ interface eth1
+ interface eth2
+ }
+ mode 802.3ad
+ vif 100 {
+ address 192.0.2.1/30
+ address 2001:db8::1/64
+ }
+ }
+```
+**R2**
+
+
+
+```none
+interfaces {
+ bonding bond10 {
+ hash-policy layer3+4
+ member {
+ interface eth1
+ interface eth2
+ }
+ mode 802.3ad
+ vif 100 {
+ address 192.0.2.2/30
+ address 2001:db8::2/64
+ }
+ }
+```
+**SW1**
+
+```none
+!
+vlan 100
+ name FOO
+!
+interface Port-Channel10
+ switchport trunk allowed vlan 100
+ switchport mode trunk
+ spanning-tree portfast
+!
+interface Port-Channel20
+ switchport mode trunk
+ no spanning-tree portfast auto
+ spanning-tree portfast network
+!
+interface Ethernet1
+ channel-group 10 mode active
+!
+interface Ethernet2
+ channel-group 10 mode active
+!
+interface Ethernet3
+ channel-group 20 mode active
+!
+interface Ethernet4
+ channel-group 20 mode active
+!
+```
+**SW2**
+
+
+
+```none
+!
+vlan 100
+ name FOO
+!
+interface Port-Channel10
+ switchport trunk allowed vlan 100
+ switchport mode trunk
+ spanning-tree portfast
+!
+interface Port-Channel20
+ switchport mode trunk
+ no spanning-tree portfast auto
+ spanning-tree portfast network
+!
+interface Ethernet1
+ channel-group 10 mode active
+!
+interface Ethernet2
+ channel-group 10 mode active
+!
+interface Ethernet3
+ channel-group 20 mode active
+!
+interface Ethernet4
+ channel-group 20 mode active
+!
+```
+:::{note}
+When testing this environment in EVE-NG, ensure the e1000 driver
+is chosen for your VyOS network interfaces. If the default virtio driver
+is used, VyOS will not transmit LACP PDUs, preventing the port-channel
+from ever becoming active.
+:::
+
+
+(operation)=
+
+## Operation
+
+```{opcmd} show interfaces bonding
+
+Show brief interface information.
+
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces bonding
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+bond0 - u/u my-sw1 int 23 and 24
+bond0.10 192.168.0.1/24 u/u office-net
+bond0.100 10.10.10.1/24 u/u management-net
+:::
+```
+```{opcmd} show interfaces bonding \<interface\>
+
+Show detailed interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces bonding bond5
+bond5: <NO-CARRIER,BROADCAST,MULTICAST,MASTER,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
+ link/ether 00:50:56:bf:ef:aa brd ff:ff:ff:ff:ff:ff
+ inet6 fe80::e862:26ff:fe72:2dac/64 scope link tentative
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 0 0 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 0 0 0 0 0 0
+:::
+```
+```{opcmd} show interfaces bonding \<interface\> detail
+
+Show detailed information about the underlying physical links on the given
+bonding interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces bonding bond5 detail
+Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
+Bonding Mode: IEEE 802.3ad Dynamic link aggregation
+Transmit Hash Policy: layer2 (0)
+MII Status: down
+MII Polling Interval (ms): 100
+Up Delay (ms): 0
+Down Delay (ms): 0
+802.3ad info
+LACP rate: slow
+Min links: 0
+Aggregator selection policy (ad_select): stable
+Slave Interface: eth1
+MII Status: down
+Speed: Unknown
+Duplex: Unknown
+Link Failure Count: 0
+Permanent HW addr: 00:50:56:bf:ef:aa
+Slave queue ID: 0
+Aggregator ID: 1
+Actor Churn State: churned
+Partner Churn State: churned
+Actor Churned Count: 1
+Partner Churned Count: 1
+Slave Interface: eth2
+MII Status: down
+Speed: Unknown
+Duplex: Unknown
+Link Failure Count: 0
+Permanent HW addr: 00:50:56:bf:19:26
+Slave queue ID: 0
+Aggregator ID: 2
+Actor Churn State: churned
+Partner Churn State: churned
+Actor Churned Count: 1
+Partner Churned Count: 1
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/bridge.md b/docs/configuration/interfaces/bridge.md
new file mode 100644
index 00000000..77775767
--- /dev/null
+++ b/docs/configuration/interfaces/bridge.md
@@ -0,0 +1,431 @@
+---
+lastproofread: '2025-12-22'
+---
+
+(bridge-interface)=
+
+# Bridge
+
+VyOS bridges connect Ethernet segments by grouping multiple interfaces into a
+single bridge interface, which acts as a virtual software switch. Unlike
+routers, which forward traffic based on Layer 3 IP addresses, bridges operate
+at Layer 2 and forward traffic based on MAC addresses. Operating at Layer 2,
+bridges are protocol-agnostic and transparently forward all Ethernet-
+encapsulated traffic, whether it is IPv4, IPv6, or specialized industrial
+protocols.
+
+This implementation utilizes the Linux bridge subsystem to support a subset of
+the ANSI/IEEE 802.1d standard for transparent bridging and MAC address learning.
+
+:::{note}
+{abbr}`STP (Spanning Tree Protocol)` is disabled by default in VyOS
+and must be explicitly enabled if required. See {ref}`stp` for details.
+:::
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: bridge
+:var1: br0
+```
+
+
+### Member interfaces
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\>
+
+**Configure an interface as a bridge member.**
+
+Valid interface types are: {ref}`ethernet-interface`, {ref}`bond-interface`,
+{ref}`l2tpv3-interface`, {ref}`openvpn`, {ref}`vxlan-interface`,
+{ref}`wireless-interface`, {ref}`tunnel-interface`, and
+{ref}`geneve-interface`.
+
+Use tab completion to list interfaces that can be bridged.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\> priority \<priority\>
+
+**Configure the** {abbr}`STP (Spanning Tree Protocol)` **port priority
+for a specific member interface within a bridge.**
+
+Within the {abbr}`STP (Spanning Tree Protocol)` topology, each member interface
+in a bridge operates as a port with an assigned **priority** and **path cost**.
+{abbr}`STP (Spanning Tree Protocol)` uses these values to determine the
+**lowest-cost path** to the root bridge, maintaining a loop-free topology.
+Traffic flows through the path with the lowest path cost, while alternate
+paths remain in standby.
+
+A **lower** priority value means **higher** precedence in path selection.
+
+{abbr}`STP (Spanning Tree Protocol)` considers the port priority only if
+multiple member interfaces have the same path costs.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\> cost \<cost\>
+
+**Configure the** {abbr}`STP (Spanning Tree Protocol)` **path cost for a
+specific member interface within the bridge.**
+
+Path cost is the primary metric {abbr}`STP (Spanning Tree Protocol)` uses to
+determine the path to the root bridge. This value is based on interface
+bandwidth; faster interfaces receive lower costs.
+
+By assigning a lower cost, you give the interface higher precedence during
+path selection.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\> disable-learning
+
+**Disable MAC address learning for a specific member interface
+within a bridge.**
+
+When learning is disabled, the bridge will not add source MAC addresses
+observed on this port to its forwarding database (FDB). Frames destined
+to MACs not present in the FDB are then flooded to all bridge ports
+rather than unicast-forwarded.
+```
+
+
+### Bridge options
+
+Configure how bridge interfaces maintain their {abbr}`FDB (Forwarding Database)`
+, react to topology changes, and optimize multicast data streams.
+
+```{cfgcmd} set interfaces bridge \<interface\> aging \<time\>
+
+**Configure the MAC address aging time for the bridge.**
+
+The duration in seconds that a MAC address remains in the bridge’s {abbr}`FDB
+(Forwarding Database)` before removal if no traffic is received from that
+address.
+
+The default value is 300 seconds.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> max-age \<time\>
+
+**Configure the** {abbr}`STP (Spanning Tree Protocol)` **max age timer for
+the bridge.**
+
+The duration in seconds that the bridge waits for a {abbr}`BPDU (Bridge
+Protocol Data Unit)` from the root bridge.
+
+If the bridge does not receive a {abbr}`BPDU (Bridge Protocol Data Unit)`
+within this period, it recalculates the path to the root bridge or initiates
+a new root bridge election.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> igmp querier
+
+**Configure the bridge interface to act as the** {abbr}`IGMP (Internet Group
+Management Protocol)`/{abbr}`MLD (Multicast Listener Discovery)` **Querier.**
+
+**When configured:** The bridge interface sends {abbr}`IGMP (Internet Group
+Management Protocol)` (IPv4) and {abbr}`MLD (Multicast Listener Discovery)`
+(IPv6) general queries to all connected hosts to identify active multicast
+listeners.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> igmp snooping
+
+**Configure the bridge interface to perform** {abbr}`IGMP (Internet Group
+Management Protocol)`/{abbr}`MLD (Multicast Listener Discovery)`
+**snooping.**
+
+**When configured:** The bridge interface monitors {abbr}`IGMP (Internet Group
+Management Protocol)` (IPv4) and {abbr}`MLD (Multicast Listener Discovery)`
+(IPv6) join requests and restricts multicast traffic forwarding to only active
+listeners. This prevents network flooding.
+```
+
+(stp)=
+
+#### STP configuration
+
+{abbr}`STP (Spanning Tree Protocol)` is a Layer 2 protocol that prevents loops
+in Ethernet networks by ensuring only one logical path exists between any two
+bridges. This creates a loop-free topology and prevents broadcast storms that
+can crash the network.
+
+By default, {abbr}`STP (Spanning Tree Protocol)` is disabled on bridge interfaces.
+To activate loop prevention, you must explicitly enable the protocol and
+configure its parameters.
+
+```{cfgcmd} set interfaces bridge \<interface\> stp
+
+Enable {abbr}`STP (Spanning Tree Protocol)` on the bridge interface.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> forwarding-delay \<delay\>
+
+**Configure the** {abbr}`STP (Spanning Tree Protocol)` **delay, in seconds,
+for the bridge interface.**
+
+This parameter defines how long the bridge interface remains in the listening
+and learning states before forwarding traffic. The delay ensures that the
+bridge has sufficient time to detect loops (in the listening state) and learn
+the MAC addresses of connected devices (in the learning state).
+
+The default value is 15 seconds. The total time before forwarding begins is
+twice this value.
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> hello-time \<interval\>
+
+**Configure the** {abbr}`STP (Spanning Tree Protocol)` **Hello advertisement
+interval, in seconds.**
+
+This parameter sets the frequency at which the bridge interface transmits
+Hello packets ({abbr}`BPDUs (Bridge Protocol Data Units)`). These packets
+originate from the root bridge and are propagated by designated bridges. If
+neighbors stop receiving Hello packets, they assume a connection failure and
+trigger a topology recalculation.
+
+The default value is 2 seconds.
+```
+
+
+### VLAN
+
+#### VLAN-aware bridges
+
+```{cfgcmd} set interfaces bridge \<interface\> enable-vlan
+
+**Enable VLAN filtering (also known as VLAN awareness) on the bridge interface.**
+
+When enabled, the bridge strictly segregates traffic among VLANs configured
+on its member interfaces.
+
+:::{note}
+Do not configure **vif 1** on a VLAN-aware bridge. The main bridge
+interface acts as VLAN 1 (the default native VLAN) and automatically
+handles all untagged traffic.
+:::
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> protocol \<802.1ad | 802.1q\>
+
+**Configure the VLAN protocol (EtherType) for the bridge interface.**
+
+The following options are available:
+* ``802.1q`` (default): Sets the EtherType to ``0x8100``. Used for standard
+enterprise VLANs.
+* ``802.1ad``: Sets the EtherType to ``0x88a8``. Used for QinQ (provider bridging).
+```
+
+
+#### VLAN configuration
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: bridge
+:var1: br0
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\> native-vlan \<vlan-id\>
+
+**Configure the native VLAN ID for a specific member interface within a
+VLAN-aware bridge.**
+
+This assigns the specified ``<vlan-id>`` to untagged traffic entering the member
+interface. The bridge strips the VLAN tag from outgoing traffic matching this
+ID.
+
+**Example:**
+
+Set the native VLAN ID to 2 for the member interface ``eth0``:
+
+:::{code-block} none
+set interfaces bridge br1 member interface eth0 native-vlan 2
+:::
+```
+
+```{cfgcmd} set interfaces bridge \<interface\> member interface \<member\> allowed-vlan \<vlan-id\>
+
+**Configure allowed VLAN IDs for a specific member interface within a
+VLAN-aware bridge.**
+
+Enter a single VLAN ID or a range of VLAN IDs separated by a hyphen.
+
+**Example:**
+
+To allow VLAN ID 4 on member interface ``eth0``:
+
+:::{code-block} none
+set interfaces bridge br1 member interface eth0 allowed-vlan 4
+:::
+**Example:**
+
+To allow VLAN IDs 6 through 8 on member interface ``eth0``:
+
+:::{code-block} none
+set interfaces bridge br1 member interface eth0 allowed-vlan 6-8
+:::
+```
+
+
+### SPAN port mirroring
+
+```{cmdincludemd} ../../_include/interface-mirror.txt
+:var0: bridge
+:var1: br1
+:var2: eth3
+```
+
+
+## Examples
+
+### Configure a standard bridge
+
+The following example creates a bridge named br100 with {abbr}`STP (Spanning
+Tree Protocol)` enabled.
+
+Configuration requirements:
+- **Bridge name:** `br100`
+- **Member interfaces:** Physical interface `eth1` and VLAN interface `eth2.10`.
+- **STP:** Enabled.
+- **Bridge IP addresses:** `192.0.2.1/24` (IPv4) and `2001:db8::ffff/64` (IPv6).
+
+```none
+set interfaces bridge br100 address 192.0.2.1/24
+set interfaces bridge br100 address 2001:db8::ffff/64
+set interfaces bridge br100 member interface eth1
+set interfaces bridge br100 member interface eth2.10
+set interfaces bridge br100 stp
+```
+
+Verify the configuration:
+
+```none
+vyos@vyos# show interfaces bridge br100
+ address 192.0.2.1/24
+ address 2001:db8::ffff/64
+ member {
+ interface eth1 {
+ }
+ interface eth2.10 {
+ }
+ }
+ stp
+```
+
+
+### Configure a VLAN-aware bridge
+
+The following example creates a VLAN-aware bridge named br100. In this setup,
+one member interface is configured as a trunk port, and the other as an access
+port. The VLAN interface is configured with IP addresses.
+
+**Configuration requirements:**
+- **Bridge name:** `br100`.
+- **Trunk port** (`eth1`): Handles **tagged** traffic for VLAN 10.
+- **Access port** (`eth2`): Handles **untagged** traffic (assigned to native
+ VLAN 10).
+- **STP:** Enabled.
+- **VLAN IP addresses** (`vif 10`): `192.0.2.1/24` (IPv4) and
+ `2001:db8::ffff/64` (IPv6).
+
+```none
+set interfaces bridge br100 enable-vlan
+set interfaces bridge br100 member interface eth1 allowed-vlan 10
+set interfaces bridge br100 member interface eth2 native-vlan 10
+set interfaces bridge br100 vif 10 address 192.0.2.1/24
+set interfaces bridge br100 vif 10 address 2001:db8::ffff/64
+set interfaces bridge br100 stp
+```
+
+Verify the configuration:
+
+```none
+vyos@vyos# show interfaces bridge br100
+ enable-vlan
+ member {
+ interface eth1 {
+ allowed-vlan 10
+ }
+ interface eth2 {
+ native-vlan 10
+ }
+ }
+ stp
+ vif 10 {
+ address 192.0.2.1/24
+ address 2001:db8::ffff/64
+ }
+```
+
+
+### Operation
+
+```{opcmd} show bridge
+
+Show the status of member interfaces for all configured bridges.
+
+:::{code-block} none
+vyos@vyos:~$ show bridge
+3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
+priority 32 cost 100
+4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
+priority 32 cost 100
+:::
+```
+
+```{opcmd} show bridge \<name\> fdb
+
+Show the {abbr}`FDB (Forwarding Database)` for the specified bridge.
+
+:::{code-block} none
+vyos@vyos:~$ show bridge br0 fdb
+50:00:00:08:00:01 dev eth1 vlan 20 master br0 permanent
+50:00:00:08:00:01 dev eth1 vlan 10 master br0 permanent
+50:00:00:08:00:01 dev eth1 master br0 permanent
+33:33:00:00:00:01 dev eth1 self permanent
+33:33:00:00:00:02 dev eth1 self permanent
+01:00:5e:00:00:01 dev eth1 self permanent
+50:00:00:08:00:02 dev eth2 vlan 20 master br0 permanent
+50:00:00:08:00:02 dev eth2 vlan 10 master br0 permanent
+50:00:00:08:00:02 dev eth2 master br0 permanent
+33:33:00:00:00:01 dev eth2 self permanent
+33:33:00:00:00:02 dev eth2 self permanent
+01:00:5e:00:00:01 dev eth2 self permanent
+33:33:00:00:00:01 dev br0 self permanent
+33:33:00:00:00:02 dev br0 self permanent
+33:33:ff:08:00:01 dev br0 self permanent
+01:00:5e:00:00:6a dev br0 self permanent
+33:33:00:00:00:6a dev br0 self permanent
+01:00:5e:00:00:01 dev br0 self permanent
+33:33:ff:00:00:00 dev br0 self permanent
+:::
+```
+
+```{opcmd} show bridge \<name\> mdb
+
+Show the {abbr}`MDB (Multicast group Database)` for the specified bridge.
+
+The {abbr}`MDB (Multicast group Database)` is populated by {abbr}`IGMP
+(Internet Group Management Protocol)`/{abbr}`MLD (Multicast Listener
+Discovery)` snooping and lists the multicast groups currently active on the
+bridge.
+
+:::{code-block} none
+vyos@vyos:~$ show bridge br0 mdb
+dev br0 port br0 grp ff02::1:ff00:0 temp vid 1
+dev br0 port br0 grp ff02::2 temp vid 1
+dev br0 port br0 grp ff02::1:ff08:1 temp vid 1
+dev br0 port br0 grp ff02::6a temp vid 1
+:::
+```
+
+```{opcmd} show bridge \<name\> macs
+
+Show the learned {abbr}`MAC (Media Access Control)` address table for the
+specified bridge.
+
+:::{code-block} none
+vyos@vyos:~$ show bridge br100 macs
+port no mac addr is local? ageing timer
+ 1 00:53:29:44:3b:19 yes 0.00
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/dummy.md b/docs/configuration/interfaces/dummy.md
new file mode 100644
index 00000000..d2d27c5d
--- /dev/null
+++ b/docs/configuration/interfaces/dummy.md
@@ -0,0 +1,87 @@
+---
+lastproofread: '2026-01-23'
+---
+
+(dummy-interface)=
+
+# Dummy
+
+A dummy interface is a virtual network interface that operates like the
+loopback interface, accepting traffic and routing it back to the local host.
+Unlike the loopback interface, which is limited to one per system and reserved
+for internal system use, multiple dummy interfaces can be created, removed, and
+managed without impacting core operations.
+
+As a software-based interface, the dummy interface does not depend on physical
+link state and remains active as long as the operating system is running.
+
+Dummy interfaces are commonly used in environments with multiple redundant
+uplinks (e.g., a server connected to two different switches), where assigning a
+management IP address to a specific physical interface is risky. If that
+interface fails, the management IP address becomes unreachable.
+
+Assigning the management IP address to a dummy interface and advertising it
+over all available physical links ensures the address remains reachable as long
+as at least one physical path is active.
+
+Dummy interfaces are also used for testing and simulation purposes.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address.txt
+:var0: dummy
+:var1: dum0
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: dummy
+:var1: dum0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: dummy
+:var1: dum0
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: dummy
+:var1: dum0
+```
+
+
+## Operation
+
+```{opcmd} show interfaces dummy
+
+Show brief interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces dummy
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+dum0 172.18.254.201/32 u/u
+:::
+```
+
+```{opcmd} show interfaces dummy \<interface\>
+
+Show detailed interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces dummy dum0
+dum0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/ether 26:7c:8e:bc:fc:f5 brd ff:ff:ff:ff:ff:ff
+ inet 172.18.254.201/32 scope global dum0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::247c:8eff:febc:fcf5/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 0 0 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 1369707 4267 0 0 0 0
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/ethernet.md b/docs/configuration/interfaces/ethernet.md
new file mode 100644
index 00000000..eac0b443
--- /dev/null
+++ b/docs/configuration/interfaces/ethernet.md
@@ -0,0 +1,515 @@
+---
+lastproofread: '2026-01-19'
+---
+
+(ethernet-interface)=
+
+# Ethernet
+
+Ethernet interfaces (e.g., `eth0`, `eth1`) represent the host's physical
+or virtual network ports.
+
+They are the most common interface type, serving as the base layer upon which
+IP addresses, VLANs, and tunnels are configured to carry traffic across both
+LANs and WANs.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: ethernet
+:var1: eth0
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> switchdev
+
+**Enable** ``switchdev`` **mode for the interface.**
+
+In ``switchdev`` mode, the interface offloads traffic switching between ports
+to the hardware, bypassing the host CPU. This increases the interface’s
+traffic-handling capacity and reduces its forwarding delay.
+```
+
+:::{note}
+`switchdev` mode is available only on certain physical network
+interfaces and requires a switchdev-compatible driver.
+:::
+
+### Ethernet options
+
+```{cfgcmd} set interfaces ethernet \<interface\> duplex \<auto | full | half\>
+
+**Configure duplex mode for the interface.**
+
+The following duplex modes are available:
+
+* ``auto``: The interface negotiates the duplex mode with the connected device.
+* ``full``: The interface sends and receives data simultaneously. The
+ connected device must also be set to full-duplex to avoid a duplex mismatch.
+* ``half``: The interface either sends or receives data, but not both at the
+ same time.
+
+The default duplex mode is ``auto``.
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> speed \<auto | 10 | 100 | 1000 | 2500 | 5000 | 10000 | 25000 | 40000 | 50000 | 100000\>
+
+**Configure the interface's speed, in Mbit/s.**
+
+The following options are available:
+
+* ``auto``: The interface negotiates the speed with the connected device.
+* ``10, 100, 1000 ...``: The interface operates at the selected speed. The
+ connected device must be set to the same speed to establish a connection.
+
+The default option is ``auto``.
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> ring-buffer rx \<value\>
+
+**Configure the receive (RX) ring buffer size for the interface.**
+
+The RX ring buffer size defines the number of incoming packets the interface
+can queue in hardware before the CPU processes them.
+
+Higher values reduce the risk of drops when the NIC receives network traffic
+faster than the CPU can process it, though latency may increase. Lower values
+reduce latency but increase the risk of packet drops during incoming traffic
+bursts.
+
+To view supported values for a specific interface, use:
+```
+
+```none
+ethtool -g <interface>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> ring-buffer tx \<value\>
+
+**Configure the transmit (TX) ring buffer size.**
+
+The TX ring buffer size defines the number of outgoing packets the interface
+can queue in hardware before they are transmitted onto the network.
+
+Higher values reduce the risk of drops when the CPU generates traffic faster
+than the NIC can handle, though latency may increase. Lower values reduce
+latency but increase the risk of packet drops during outgoing traffic bursts.
+
+To view supported values for a specific interface, use:
+```
+
+```none
+ethtool -g <interface>
+```
+
+
+#### Interrupt Coalescing
+
+Interrupt coalescing is a mechanism that reduces CPU interrupt load by bundling
+multiple packets into a single interrupt event instead of interrupting
+the CPU for every packet arrival or transmission.
+
+:::{note}
+Not all network drivers or virtual interfaces support all
+coalescing parameters. Use `ethtool --show-coalesce <interface>`
+to verify which settings are supported by your hardware and driver.
+:::
+
+**Basic adaptive coalescing**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing adaptive-rx
+
+```
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing adaptive-tx
+
+Enable adaptive interrupt coalescing. The NIC automatically tunes RX/TX
+interrupt pacing based on traffic patterns to reduce CPU utilization
+during high throughput while preserving latency at low packet rates.
+```
+
+**Basic interrupt delay**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-usecs \<0-16384\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-usecs \<0-16384\>
+
+Set the delay in microseconds before generating an RX/TX interrupt after
+receiving or transmitting a packet. Lower values reduce latency; higher
+values reduce CPU load.
+```
+
+**Interrupt frame thresholds**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-frames \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-frames \<number\>
+
+Generate an RX/TX interrupt only after the specified number of packets
+have been received or transmitted.
+```
+
+**IRQ-specific coalescing**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-usecs-irq \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-frames-irq \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-usecs-irq \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-frames-irq \<number\>
+
+Control interrupt coalescing parameters while the driver is already
+servicing an interrupt (IRQ context). These settings allow finer tuning
+of interrupt behavior under sustained load.
+```
+
+**Adaptive rate thresholds**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing pkt-rate-low \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing pkt-rate-high \<number\>
+
+Define packet-rate thresholds (packets per second) used by adaptive
+coalescing to switch between low-rate and high-rate interrupt coalescing
+profiles.
+```
+
+**Low-rate adaptive parameters**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-usecs-low \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-frame-low \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-usecs-low \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-frame-low \<number\>
+
+Interrupt coalescing parameters applied when the packet rate is below
+``pkt-rate-low``. Typically optimized for lower latency.
+```
+
+**High-rate adaptive parameters**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-usecs-high \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing rx-frame-high \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-usecs-high \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-frame-high \<number\>
+
+Interrupt coalescing parameters applied when the packet rate exceeds
+``pkt-rate-high``. Typically optimized for maximum throughput and
+reduced CPU utilization.
+```
+
+**Statistics and sampling**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing stats-block-usecs \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing sample-interval \<number\>
+
+Control how frequently coalescing statistics are updated and how often
+the NIC samples traffic rates for adaptive coalescing decisions.
+```
+
+**Completion queue (CQE) mode**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing cqe-mode-rx
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing cqe-mode-tx
+
+Enable RX/TX Completion Queue Entry (CQE) mode, if supported by the
+driver. CQE mode can improve performance on high-speed NICs by
+optimizing completion handling.
+```
+
+**Transmit aggregation**
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-aggr-max-bytes \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-aggr-max-frames \<number\>
+```
+
+```{cfgcmd} set interfaces ethernet \<interface\> interrupt-coalescing tx-aggr-time-usecs \<number\>
+
+Control transmit packet aggregation. Packets may be buffered and sent
+together until one of the configured limits (bytes, frames, or time)
+is reached, reducing interrupt and DMA overhead.
+```
+
+#### Offloading
+
+```{cfgcmd} set interfaces ethernet \<interface\> offload \<lro | tso | gso | gro | rps | sg\>
+
+**Configure the offloading features for the interface.**
+
+The interface offloading features define whether specific packet-processing tasks
+are performed by hardware (the NIC) or by software (the kernel). You can enable
+multiple offloading features for a single interface.
+
+ * ``lro`` **(Large Receive Offload):** Instructs the NIC to merge multiple
+ incoming packets into one larger packet before sending it to the CPU.
+
+ :::{note}
+ {abbr}`LRO (Large Receive Offload)` hardware support is often limited
+ to TCP/IPv4 packets. For details on LRO limitations, see
+ https://lwn.net/Articles/358910/
+ :::
+ :::{warning}
+ {abbr}`LRO (Large Receive Offload)` irreversibly alters packet
+ headers during merging. This prevents the merged packet from being correctly
+ split back into the original packets, causing packet drops and forwarding
+ failures on routers and bridges. Use {abbr}`LRO (Large Receive Offload)` only
+ for end-hosts that do not forward traffic.
+ :::
+ * ``tso`` **(TCP Segmentation Offload):** Instructs the NIC to split large TCP
+ packets into smaller ones before transmitting them to the network.
+
+ **Important:** {abbr}`SG (Scatter-Gather/Scatter-Gather DMA)` must be enabled
+ for {abbr}`TSO (TCP Segmentation Offload)` to work. Additionally, {abbr}`GSO
+ (Generic Segmentation Offload)` should be enabled as a safety fallback; it
+ ensures that if traffic is rerouted to hardware without {abbr}`TSO (TCP
+ Segmentation Offload)` support, the kernel can still segment the packets,
+ preventing transmission failures.
+
+ * ``gso`` **(Generic Segmentation Offload):** Instructs the kernel to split
+ large packets into smaller ones before sending them to the NIC.
+
+ {abbr}`GSO (Generic Segmentation Offload)` serves as a software fallback for
+ hardware that does not support {abbr}`TSO (TCP Segmentation Offload)` or for
+ protocols (like UDP) that hardware cannot offload.
+
+ **Important:** {abbr}`SG (Scatter-Gather/Scatter-Gather DMA)` must be enabled
+ for {abbr}`GSO (Generic Segmentation Offload)` to work.
+
+ * ``gro`` **(Generic Receive Offload):** Instructs the kernel to merge multiple
+ incoming packets into one larger packet before passing it to upper protocol
+ layers.
+
+ Unlike LRO, GRO preserves the necessary packet metadata so the merged packet
+ can be correctly split back into the original packets. This makes GRO safe for
+ use on routers and bridges.
+
+ :::{note}
+The exception is for IPv4 IDs. If the "Don't Fragment" (DF) bit is
+set and IDs are not sequential, {abbr}`GSO (Generic Segmentation Offload)`
+alters them to maintain a consistent sequence for {abbr}`GSO (Generic
+Segmentation Offload)` compatibility.
+ :::
+ * ``rps`` **(Receive Packet Steering):** Instructs the kernel to distribute
+ the processing of incoming packets across multiple CPU cores.
+
+ The kernel calculates a hash from packet headers (IP addresses and ports) to
+ ensure packets from the same flow are processed by the same CPU core.
+
+ :::{note}
+{abbr}`RPS (Receive Packet Steering)` is a software version of
+{abbr}`RSS (Receive Side Scaling)` and is useful for NICs without hardware
+multi-queue support.
+ :::
+ * ``sg`` **(Scatter-Gather/Scatter-Gather DMA):** Instructs the NIC to fetch
+ data fragments from various RAM locations and transmit them as a single packet
+ to the network, eliminating the need for the kernel to copy them into a
+ contiguous block first.
+```
+
+#### 802.1X (EAPOL) authentication
+
+```{cmdincludemd} /_include/interface-eapol.txt
+:var0: ethernet
+:var1: eth0
+```
+
+#### EVPN Multihoming
+
+Uplink/core tracking.
+
+```{cmdincludemd} /_include/interface-evpn-uplink.txt
+:var0: ethernet
+:var1: eth0
+```
+
+### VLAN
+#### Regular VLANs (802.1q)
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: ethernet
+:var1: eth0
+```
+
+#### 802.1ad (QinQ)
+
+```{cmdincludemd} /_include/interface-vlan-8021ad.txt
+:var0: ethernet
+:var1: eth0
+```
+
+### SPAN port mirroring
+
+```{cmdincludemd} ../../_include/interface-mirror.txt
+:var0: ethernet
+:var1: eth1
+:var2: eth3
+```
+
+## Operation
+
+```{opcmd} show interfaces ethernet
+
+Show brief interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces ethernet
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 172.18.201.10/24 u/u LAN
+eth1 172.18.202.11/24 u/u WAN
+eth2 - u/D
+:::
+```
+
+```{opcmd} show interfaces ethernet \<interface\>
+
+Show detailed interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces ethernet eth0
+eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
+ link/ether 00:50:44:00:f5:c9 brd ff:ff:ff:ff:ff:ff
+ inet6 fe80::250:44ff:fe00:f5c9/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 56735451 179841 0 0 0 142380
+ TX: bytes packets errors dropped carrier collisions
+ 5601460 62595 0 0 0 0
+:::
+```
+
+```{opcmd} show interfaces ethernet \<interface\> physical
+
+Show interface hardware-level and driver details.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces ethernet eth0 physical
+Settings for eth0:
+ Supported ports: [ TP ]
+ Supported link modes: 1000baseT/Full
+ 10000baseT/Full
+ Supported pause frame use: No
+ Supports auto-negotiation: No
+ Supported FEC modes: Not reported
+ Advertised link modes: Not reported
+ Advertised pause frame use: No
+ Advertised auto-negotiation: No
+ Advertised FEC modes: Not reported
+ Speed: 10000Mb/s
+ Duplex: Full
+ Port: Twisted Pair
+ PHYAD: 0
+ Transceiver: internal
+ Auto-negotiation: off
+ MDI-X: Unknown
+ Supports Wake-on: uag
+ Wake-on: d
+ Link detected: yes
+driver: vmxnet3
+version: 1.4.16.0-k-NAPI
+firmware-version:
+expansion-rom-version:
+bus-info: 0000:0b:00.0
+supports-statistics: yes
+supports-test: no
+supports-eeprom-access: no
+supports-register-dump: yes
+supports-priv-flags: no
+:::
+```
+
+```{opcmd} show interfaces ethernet \<interface\> physical offload
+
+Show the status of the interface offloading features.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces ethernet eth0 physical offload
+rx-checksumming on
+tx-checksumming on
+tx-checksum-ip-generic on
+scatter-gather off
+tx-scatter-gather off
+tcp-segmentation-offload off
+tx-tcp-segmentation off
+tx-tcp-mangleid-segmentation off
+tx-tcp6-segmentation off
+udp-fragmentation-offload off
+generic-segmentation-offload off
+generic-receive-offload off
+large-receive-offload off
+rx-vlan-offload on
+tx-vlan-offload on
+ntuple-filters off
+receive-hashing on
+tx-gre-segmentation on
+tx-gre-csum-segmentation on
+tx-udp_tnl-segmentation on
+tx-udp_tnl-csum-segmentation on
+tx-gso-partial on
+tx-nocache-copy off
+rx-all off
+:::
+```
+
+```{opcmd} show interfaces ethernet \<interface\> transceiver
+
+Show information about the transceiver module plugged into the interface
+(e.g., SFP+, QSFP).
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces ethernet eth5 transceiver
+ Identifier : 0x03 (SFP)
+ Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID)
+ Connector : 0x07 (LC)
+ Transceiver codes : 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00
+ Transceiver type : Ethernet: 1000BASE-SX
+ Encoding : 0x01 (8B/10B)
+ BR, Nominal : 1300MBd
+ Rate identifier : 0x00 (unspecified)
+ Length (SMF,km) : 0km
+ Length (SMF) : 0m
+ Length (50um) : 550m
+ Length (62.5um) : 270m
+ Length (Copper) : 0m
+ Length (OM3) : 0m
+ Laser wavelength : 850nm
+ Vendor name : CISCO-FINISAR
+ Vendor OUI : 00:90:65
+ Vendor PN : FTRJ-8519-7D-CS4
+ Vendor rev : A
+ Option values : 0x00 0x1a
+ Option : RX_LOS implemented
+ Option : TX_FAULT implemented
+ Option : TX_DISABLE implemented
+ BR margin, max : 0%
+ BR margin, min : 0%
+ Vendor SN : FNS092xxxxx
+ Date code : 0506xx
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/geneve.md b/docs/configuration/interfaces/geneve.md
new file mode 100644
index 00000000..1fce1119
--- /dev/null
+++ b/docs/configuration/interfaces/geneve.md
@@ -0,0 +1,105 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(geneve-interface)=
+
+# Geneve
+
+{abbr}`Geneve (Generic Network Virtualization Encapsulation)` interfaces
+operate as virtual network ports. Administrators can apply standard network
+configurations on them, such as IP addressing, bridging, or firewall rules,
+just as they would on physical Ethernet ports.
+
+The Geneve protocol encapsulates Layer 2 Ethernet frames originating from
+endpoints such as virtual machines, containers, or physical servers inside UDP
+packets. It unifies the features of earlier encapsulation protocols, including
+VXLAN, NVGRE, and STT, and addresses their limitations, such as fixed header
+structures and a lack of metadata support. Because of its extensibility, Geneve
+may eventually replace those older protocols.
+
+Geneve tunnels are used to connect virtual switches residing within
+hypervisors, physical switches, middleboxes, and other network appliances.
+
+Geneve tunnels operate over any standard IP network. In larger deployments,
+the underlying network (underlay) is often built using a **Clos** topology,
+also known as a *leaf-and-spine* or *fat-tree* topology.
+
+Geneve header:
+
+```none
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|Ver| Opt Len |O|C| Rsvd. | Protocol Type |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Virtual Network Identifier (VNI) | Reserved |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Variable Length Options |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+```
+
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-mac.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-mtu.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-ip.txt
+:var0: geneve
+:var1: gnv0
+```
+
+```{cmdincludemd} /_include/interface-ipv6.txt
+:var0: geneve
+:var1: gnv0
+```
+
+
+### Geneve options
+
+```{cfgcmd} set interfaces geneve gnv0 remote \<address\>
+
+Configure the remote endpoint IP address for the Geneve tunnel.
+```
+
+```{cfgcmd} set interfaces geneve gnv0 vni \<vni\>
+
+**Configure** {abbr}`VNI (Virtual Network Identifier)` **for the Geneve
+interface.**
+
+The VNI is a virtual network identifier. It allows multiple virtual networks to
+share the same physical infrastructure and remain isolated.
+
+The VNI is also used to distribute traffic after it leaves the tunnel, for
+example, to map packets with overlapping IP addresses to specific routing
+tables.
+```
+
+```{cfgcmd} set interfaces gnv0 \<interface\> port \<port\>
+
+**Configure the destination UDP port for the remote Geneve tunnel endpoint.**
+Ensure the remote peer is configured to listen on this specific port.
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/index.md b/docs/configuration/interfaces/index.md
new file mode 100644
index 00000000..9082cd80
--- /dev/null
+++ b/docs/configuration/interfaces/index.md
@@ -0,0 +1,26 @@
+# Interfaces
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+bonding
+bridge
+dummy
+ethernet
+geneve
+l2tpv3
+loopback
+macsec
+openvpn
+wireguard
+pppoe
+pseudo-ethernet
+sstp-client
+tunnel
+virtual-ethernet
+vti
+vxlan
+wireless
+wwan
+```
diff --git a/docs/configuration/interfaces/l2tpv3.md b/docs/configuration/interfaces/l2tpv3.md
new file mode 100644
index 00000000..324840fa
--- /dev/null
+++ b/docs/configuration/interfaces/l2tpv3.md
@@ -0,0 +1,170 @@
+---
+lastproofread: '2026-02-05'
+---
+
+(l2tpv3-interface)=
+
+# L2TPv3
+
+{abbr}`L2TPv3 (Layer 2 Tunneling Protocol version 3)` interfaces let you
+establish L2TPv3 tunnels to transport Layer 2 traffic over IP networks.
+
+The L2TPv3 protocol (defined in RFC 3931) wraps Layer 2 frames (e.g., Ethernet,
+Frame Relay, HDLC) within IP packets, allowing them to traverse the underlying
+IP infrastructure.
+
+Unlike L2TPv2, which strictly requires UDP encapsulation, the L2TPv3 protocol
+is more flexible and supports two encapsulation types:
+
+> - **Direct IP:** Tunnel data is encapsulated directly inside IP packets
+> (Protocol 115) for lower overhead.
+> - **UDP:** Tunnel data is encapsulated inside a UDP datagram. This allows the
+> tunnel to traverse NAT more easily.
+
+L2TPv3 tunnels connect geographically separated sites, serving as a simpler
+alternative to {ref}`mpls` by operating over basic IP connectivity rather than
+requiring a full MPLS infrastructure.
+
+L2TPv3 tunnels can be established over both IPv4 and IPv6 underlying networks.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-without-dhcp.txt
+:var0: l2tpv3
+:var1: l2tpeth0
+```
+
+
+### L2TPv3 options
+
+Use the following commands to configure the L2TPv3 tunnel's specific parameters.
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> encapsulation \<udp | ip\>
+
+**Configure the encapsulation type for the L2TPv3 tunnel.**
+
+Valid values are ``udp`` and ``ip``.
+
+The default encapsulation type is ``udp``.
+```
+
+:::{note}
+The encapsulation type must match on both the local and remote peers
+for the tunnel to establish.
+:::
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> source-address \<address\>
+
+**Configure the L2TPv3 tunnel source IP address.**
+
+The specified address must be a local interface IP address and can be either
+IPv4 or IPv6.
+```
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> remote \<address\>
+
+**Configure the L2TPv3 tunnel destination IP address.**
+
+The specified address must be a remote peer’s interface IP address and can be
+either IPv4 or IPv6.
+```
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> session-id \<id\>
+
+**Configure the local session ID within the L2TPv3 tunnel.**
+
+The ``session-id`` is a 32-bit value that identifies an incoming tunnel session
+on the local peer.
+
+The ``peer-session-id`` that identifies this session on the remote peer must be
+set to the same value.
+```
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> peer-session-id \<id\>
+
+**Configure the peer session ID within the L2TPv3 tunnel.**
+
+The ``peer-session-id`` is a 32-bit value that identifies an outgoing tunnel
+session from the local peer.
+
+The ``peer-session-id`` must match the ``session-id`` configured for this
+session on the remote peer.
+```
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> tunnel-id \<id\>
+
+**Configure the local identifier for the L2TPv3 tunnel.**
+
+The ``tunnel-id`` is a 32-bit value that identifies the L2TPv3 tunnel on the
+local peer.
+
+The ``peer-tunnel-id`` that identifies this tunnel on the remote peer must be
+set to the same value.
+```
+
+```{cfgcmd} set interfaces l2tpv3 \<interface\> peer-tunnel-id \<id\>
+
+**Configure the peer identifier for the L2TPv3 tunnel.**
+
+The ``peer-tunnel-id`` is a 32-bit value that identifies the L2TPv3 tunnel on
+the remote peer and must correspond to the ``tunnel-id`` configured for that
+tunnel on that peer.
+
+The ``peer-tunnel-id`` must match the ``tunnel-id`` that identifies this tunnel
+on the remote peer.
+```
+
+
+## Example
+
+### L2TPv3 tunnel with IP encapsulation
+
+The following example shows the configuration of an L2TPv3 tunnel using direct
+IP encapsulation:
+
+```none
+# show interfaces l2tpv3
+l2tpv3 l2tpeth10 {
+ address 192.168.37.1/27
+ encapsulation ip
+ source-address 192.0.2.1
+ peer-session-id 100
+ peer-tunnel-id 200
+ remote 203.0.113.24
+ session-id 100
+ tunnel-id 200
+}
+```
+
+The inverse configuration must be applied to the remote peer.
+
+### L2TPv3 tunnel with UDP encapsulation
+
+The following example shows the configuration of an L2TPv3 tunnel using UDP
+encapsulation.
+
+This setup is recommended when the tunnel traverses NAT devices.
+
+Configuration notes:
+- Use a local LAN IP address as the `source-address`.
+- Configure a forwarding rule to allow tunnel traffic on the specified UDP port
+ on the upstream NAT device.
+- Use a distinct UDP port for each individual tunnel.
+
+```none
+# show interfaces l2tpv3
+l2tpv3 l2tpeth10 {
+ address 192.168.37.1/27
+ destination-port 9001
+ encapsulation udp
+ source-address 192.0.2.1
+ peer-session-id 100
+ peer-tunnel-id 200
+ remote 203.0.113.24
+ session-id 100
+ source-port 9000
+ tunnel-id 200
+}
+```
diff --git a/docs/configuration/interfaces/loopback.md b/docs/configuration/interfaces/loopback.md
new file mode 100644
index 00000000..72f14c16
--- /dev/null
+++ b/docs/configuration/interfaces/loopback.md
@@ -0,0 +1,67 @@
+---
+lastproofread: '2026-01-23'
+---
+
+(loopback-interface)=
+
+# Loopback
+
+The loopback interface is a virtual, software-based network interface. All
+traffic sent to it loops back and only targets services on the local host.
+
+:::{note}
+Only one loopback `lo` interface is allowed per operating system.
+If you require multiple virtual interfaces, use the {ref}`dummy-interface`
+interface type.
+:::
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address.txt
+:var0: loopback
+:var1: lo
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: loopback
+:var1: lo
+```
+
+
+## Operation
+
+```{opcmd} show interfaces loopback
+
+Show brief interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces loopback
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+lo 127.0.0.1/8 u/u
+ ::1/128
+:::
+```
+
+```{opcmd} show interfaces loopback lo
+
+Show detailed interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces loopback lo
+lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 300 6 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 300 6 0 0 0 0
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/macsec.md b/docs/configuration/interfaces/macsec.md
new file mode 100644
index 00000000..b3c70362
--- /dev/null
+++ b/docs/configuration/interfaces/macsec.md
@@ -0,0 +1,319 @@
+---
+lastproofread: '2026-02-13'
+---
+
+(macsec-interface)=
+
+# MACsec
+
+MACsec is an IEEE standard (IEEE 802.1AE) for MAC security, introduced in
+2006\. It enables protocol-independent connectivity between two hosts, providing
+data confidentiality, authenticity, and integrity using GCM-AES ciphers. MACsec
+operates at the Ethernet layer as a Layer 2 protocol and secures traffic within
+Layer 2 networks, including DHCP and ARP requests. It does not compete with
+other security solutions, such as IPsec (Layer 3) or TLS (Layer 4), as each
+addresses distinct use cases.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: macsec
+:var1: macsec0
+```
+
+
+### MACsec options
+
+```{cfgcmd} set interfaces macsec \<interface\> security cipher \<gcm-aes-128|gcm-aes-256\>
+
+**Configure the cipher suite for the MACsec interface.**
+
+This configuration parameter is mandatory.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security encrypt
+
+**Enable encryption on the MACsec interface.**
+
+By default, MACsec interfaces only provide authentication; encryption is
+optional.
+When enabled, outgoing packets are encrypted using the configured cipher suite.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> source-interface \<physical-source\>
+
+**Configure a physical source interface for the MACsec interface.**
+
+Traffic transmitted through this interface is authenticated and, if configured,
+encrypted.
+```
+
+
+#### MACsec key management
+
+**Static** {abbr}`SAK (Secure Authentication Key)` **mode**
+
+In static SAK mode, administrators must manually configure and update SAKs on
+each MACsec peer. {abbr}`MKA (MACsec Key Agreement protocol)` cannot be used in
+this mode.
+
+```{cfgcmd} set interfaces macsec \<interface\> security static key \<key\>
+
+**Configure the Transmit (TX) SAK for the MACsec interface.**
+
+The key must be a 16-byte (GCM-AES-128) or 64-byte (GCM-AES-256) hexadecimal
+string.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security static peer \<peer\> mac \<mac address\>
+
+**Configure the MAC address associated with the MACsec peer.**
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security static peer \<peer\> key \<key\>
+
+**Configure the RX SAK for traffic from the MACsec peer.**
+
+The key must be a 16-byte (GCM-AES-128) or 64-byte (GCM-AES-256) hexadecimal
+string.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security static peer \<peer\> disable
+```
+
+**Dynamic** {abbr}`MKA (MACsec Key Agreement protocol)` **mode**
+
+In this mode, the {abbr}`MKA (MACsec Key Agreement protocol)` protocol is used
+to generate, distribute, and update {abbr}`CAKs (MACsec Connectivity
+Association Keys)`, and to authenticate MACsec peers.
+
+```{cfgcmd} set interfaces macsec \<interface\> security mka cak \<key\>
+
+**Configure the** {abbr}`CAK (MACsec Connectivity Association Key)` **for the
+MACsec interface.**
+
+The {abbr}`CAK (MACsec Connectivity Association Key)` and its {abbr}`CKN
+(MACsec Connectivity Association Key Name)` form the pre-shared master key pair
+used to authenticate MACsec peers.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security mka ckn \<key\>
+
+Configure the {abbr}`CKN (MACsec Connectivity Association Key Name)` for the
+MACsec interface.
+```
+
+```{cfgcmd} set interfaces macsec \<interface\> security mka priority \<priority\>
+
+Configure the MKA key server priority for the MACsec interface.
+The peer with the lowest priority is elected as the key server.
+```
+
+#### Replay protection
+
+```{cfgcmd} set interfaces macsec \<interface\> security replay-window \<window\>
+
+The replay protection window defines how many out-of-order frames can be
+received before they are dropped as a potential replay attack.
+The following values are valid:
+- ``0``: Any out-of-order frame is immediately dropped.
+- ``1-4294967295``: Allows the specified number of out-of-order frames.
+```
+
+## Operation
+
+```{opcmd} run generate macsec mka cak \<gcm-aes-128|gcm-aes-256\>
+
+Generate a 128-bit (GCM-AES-128) or 256-bit (GCM-AES-256) {abbr}`MKA (MACsec
+Key Agreement protocol)` {abbr}`CAK (MACsec Connectivity Association Key)`.
+
+:::{code-block} none
+vyos@vyos:~$ generate macsec mka cak gcm-aes-128
+20693b6e08bfa482703a563898c9e3ad
+:::
+```
+
+```{opcmd} run generate macsec mka ckn
+
+Generate an {abbr}`MKA (MACsec Key Agreement protocol)` {abbr}`CAK (MACsec
+Connectivity Association Key)`.
+
+:::{code-block} none
+vyos@vyos:~$ generate macsec mka ckn
+88737efef314ee319b2cbf30210a5f164957d884672c143aefdc0f5f6bc49eb2
+:::
+```
+
+```{opcmd} show interfaces macsec
+
+Show all MACsec interfaces.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces macsec
+17: macsec1: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off
+cipher suite: GCM-AES-128, using ICV length 16
+TXSC: 005056bfefaa0001 on SA 0
+20: macsec0: protect on validate strict sc off sa off encrypt off send_sci on end_station off scb off replay off
+cipher suite: GCM-AES-128, using ICV length 16
+TXSC: 005056bfefaa0001 on SA 0
+:::
+```
+
+```{opcmd} show interfaces macsec \<interface\>
+
+Show information for a specific MACsec interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces macsec macsec1
+17: macsec1: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off
+cipher suite: GCM-AES-128, using ICV length 16
+TXSC: 005056bfefaa0001 on SA 0
+:::
+```
+
+## Examples
+
+**Site-to-site MACsec with dynamic MKA over an untrusted network**
+
+In the following example, two routers (R1 and R2) are connected via an
+untrusted switch, using their `eth1` interfaces as the underlay. The MACsec
+interface (`macsec1`) with dynamic MKA encrypts traffic between them.
+
+Topology details:
+- R1 IP addresses: `192.0.2.1/24` and `2001:db8::1/64`.
+- R2 IP addresses: `192.0.2.2/24` and `2001:db8::2/64`.
+
+**R1**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.1/24'
+set interfaces macsec macsec1 address '2001:db8::1/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security mka cak '232e44b7fda6f8e2d88a07bf78a7aff4'
+set interfaces macsec macsec1 security mka ckn '40916f4b23e3d548ad27eedd2d10c6f98c2d21684699647d63d41b500dfe8836'
+set interfaces macsec macsec1 source-interface 'eth1'
+```
+
+**R2**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.2/24'
+set interfaces macsec macsec1 address '2001:db8::2/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security mka cak '232e44b7fda6f8e2d88a07bf78a7aff4'
+set interfaces macsec macsec1 security mka ckn '40916f4b23e3d548ad27eedd2d10c6f98c2d21684699647d63d41b500dfe8836'
+set interfaces macsec macsec1 source-interface 'eth1'
+```
+
+Pinging (IPv6) the other host and intercepting traffic on `eth1` confirm that
+the content is encrypted.
+
+```none
+17:35:44.586668 00:50:56:bf:ef:aa > 00:50:56:b3:ad:d6, ethertype Unknown (0x88e5), length 150:
+ 0x0000: 2c00 0000 000a 0050 56bf efaa 0001 d9fb ,......PV.......
+ 0x0010: 920a 8b8d 68ed 9609 29dd e767 25a4 4466 ....h...)..g%.Df
+ 0x0020: 5293 487b 9990 8517 3b15 22c7 ea5c ac83 R.H{....;."..\..
+ 0x0030: 4c6e 13cf 0743 f917 2c4e 694e 87d1 0f09 Ln...C..,NiN....
+ 0x0040: 0f77 5d53 ed75 cfe1 54df 0e5a c766 93cb .w]S.u..T..Z.f..
+ 0x0050: c4f2 6e23 f200 6dfe 3216 c858 dcaa a73b ..n#..m.2..X...;
+ 0x0060: 4dd1 9358 d9e4 ed0e 072f 1acc 31c4 f669 M..X...../..1..i
+ 0x0070: e93a 9f38 8a62 17c6 2857 6ac5 ec11 8b0e .:.8.b..(Wj.....
+ 0x0080: 6b30 92a5 7ccc 720b k0..|.r.
+```
+
+Disabling encryption on the MACsec interface by removing the `security
+encrypt` option shows the unencrypted but authenticated content.
+
+```none
+17:37:00.746155 00:50:56:bf:ef:aa > 00:50:56:b3:ad:d6, ethertype Unknown (0x88e5), length 150:
+ 0x0000: 2000 0000 0009 0050 56bf efaa 0001 86dd .......PV.......
+ 0x0010: 6009 86f3 0040 3a40 2001 0db8 0000 0000 `....@:@........
+ 0x0020: 0000 0000 0000 0001 2001 0db8 0000 0000 ................
+ 0x0030: 0000 0000 0000 0002 8100 d977 0f30 0003 ...........w.0..
+ 0x0040: 1ca0 c65e 0000 0000 8d93 0b00 0000 0000 ...^............
+ 0x0050: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f ................
+ 0x0060: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f .!"#$%&'()*+,-./
+ 0x0070: 3031 3233 3435 3637 87d5 eed3 3a39 d52b 01234567....:9.+
+ 0x0080: a282 c842 5254 ef28 ...BRT.(
+```
+
+**Site-to-site MACsec with static SAK over an untrusted network**
+
+This example uses the same topology as above, but applies static SAK mode to
+the MACsec interface configuration.
+
+**R1**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.1/24'
+set interfaces macsec macsec1 address '2001:db8::1/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security static key 'ddd6f4a7be4d8bbaf88b26f10e1c05f7'
+set interfaces macsec macsec1 security static peer R2 mac 00:11:22:33:44:02
+set interfaces macsec macsec1 security static peer R2 key 'eadcc0aa9cf203f3ce651b332bd6e6c7'
+set interfaces macsec macsec1 source-interface 'eth1'
+```
+
+**R2**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.2/24'
+set interfaces macsec macsec1 address '2001:db8::2/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security static key 'eadcc0aa9cf203f3ce651b332bd6e6c7'
+set interfaces macsec macsec1 security static peer R1 mac 00:11:22:33:44:01
+set interfaces macsec macsec1 security static peer R1 key 'ddd6f4a7be4d8bbaf88b26f10e1c05f7'
+set interfaces macsec macsec1 source-interface 'eth1'
+```
+
+## MACsec over WAN
+
+MACsec offers an alternative to traditional tunneling solutions by securing
+Layer 2 with integrity, origin authentication, and optional encryption.
+
+While typically deployed between hosts and access switches, MACsec can also
+secure traffic over a WAN. In the following example, we combine VXLAN (for
+transport) and MACsec (for security) to create a secure tunnel between two
+sites.
+
+**R1 MACsec01**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.1/24'
+set interfaces macsec macsec1 address '2001:db8::1/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security static key 'ddd6f4a7be4d8bbaf88b26f10e1c05f7'
+set interfaces macsec macsec1 security static peer SEC02 key 'eadcc0aa9cf203f3ce651b332bd6e6c7'
+set interfaces macsec macsec1 security static peer SEC02 mac '00:11:22:33:44:02'
+set interfaces macsec macsec1 source-interface 'vxlan1'
+set interfaces vxlan vxlan1 mac '00:11:22:33:44:01'
+set interfaces vxlan vxlan1 remote '10.1.3.3'
+set interfaces vxlan vxlan1 source-address '172.16.100.1'
+set interfaces vxlan vxlan1 vni '10'
+set protocols static route 10.1.3.3/32 next-hop 172.16.100.2
+```
+
+**R2 MACsec02**
+
+```none
+set interfaces macsec macsec1 address '192.0.2.2/24'
+set interfaces macsec macsec1 address '2001:db8::2/64'
+set interfaces macsec macsec1 security cipher 'gcm-aes-128'
+set interfaces macsec macsec1 security encrypt
+set interfaces macsec macsec1 security static key 'eadcc0aa9cf203f3ce651b332bd6e6c7'
+set interfaces macsec macsec1 security static peer SEC01 key 'ddd6f4a7be4d8bbaf88b26f10e1c05f7'
+set interfaces macsec macsec1 security static peer SEC01 mac '00:11:22:33:44:01'
+set interfaces macsec macsec1 source-interface 'vxlan1'
+set interfaces vxlan vxlan1 mac '00:11:22:33:44:02'
+set interfaces vxlan vxlan1 remote '10.1.2.2'
+set interfaces vxlan vxlan1 source-address '172.16.100.2'
+set interfaces vxlan vxlan1 vni '10'
+set protocols static route 10.1.2.2/32 next-hop 172.16.100.1
+```
diff --git a/docs/configuration/interfaces/openvpn-examples.md b/docs/configuration/interfaces/openvpn-examples.md
new file mode 100644
index 00000000..817e6868
--- /dev/null
+++ b/docs/configuration/interfaces/openvpn-examples.md
@@ -0,0 +1,769 @@
+# Site-to-site
+
+:::{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd directives for command coverage tracking.
+:::
+
+OpenVPN is popular for client-server setups, but its site-to-site mode is less common and often not supported by router appliances. Despite limited support, it is effective for quickly establishing tunnels between routers.
+
+As of VyOS 1.4, OpenVPN site-to-site mode can use either pre-shared keys or x.509 certificates.
+
+Pre-shared key mode is now deprecated and will be removed from future OpenVPN versions. VyOS will also discontinue support for this option because pre-shared keys are significantly less secure than TLS.
+
+We will configure OpenVPN with self-signed certificates, and then discuss the legacy pre-shared key mode.
+
+In both cases, we will use the following settings:
+
+- The public IP address of the local VPN endpoint is 198.51.100.10.
+- The public IP address of the remote VPN endpoint is 203.0.113.11.
+- The tunnel uses 10.255.1.1 for the local IP address and 10.255.1.2 for the remote IP address.
+- The local site has a subnet of 10.0.0.0/16.
+- The remote site has a subnet of 10.1.0.0/16.
+- The official OpenVPN port 1194 is reserved for client VPN. For site-to-site VPN, port 1195 is used.
+- The `persistent-tunnel` directive allows us to configure tunnel-related attributes, such as firewall policy, as we would on any standard network interface.
+- If known, the remote router\'s IP address can be configured using the `remote-host` directive. If unknown, it can be omitted. We assume the remote router has a dynamic IP address.
+
+![](/_static/images/openvpn_site2site_diagram.webp)
+
+## Set up site-to-site certificates
+
+Deploying a complete Public Key Infrastructure (PKI) with a Certificate Authority (CA) would overcomplicate site-to-site OpenVPN setups, which are primarily designed for simplicity. To keep their configuration simple without compromising security, VyOS 1.4 and later lets you verify self-signed certificates using certificate fingerprints.
+
+Generate a self-signed certificate on each router, preferably using the Elliptic Curve (EC) type. In configuration mode, run the following command: `run generate pki certificate self-signed install <name>`. This adds the certificate to the configuration session\'s `pki` subtree. Review and commit the changes.
+
+``` none
+vyos@vyos# run generate pki certificate self-signed install openvpn-local
+Enter private key type: [rsa, dsa, ec] (Default: rsa) ec
+Enter private key bits: (Default: 256)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io)
+Do you want to configure Subject Alternative Names? [y/N]
+Enter how many days certificate will be valid: (Default: 365)
+Enter certificate type: (client, server) (Default: server)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N]
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+
+vyos@vyos# compare
+[pki]
++ certificate openvpn-local {
++ certificate "MIICJTCCAcugAwIBAgIUMXLfRNJ5iOjk/uAZqUe4phW8MdgwCgYIKoZIzj0EAwIwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA5MDcyMTQzMTNaFw0yNDA5MDYyMTQzMTNaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMWo3UwczAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUBrAxRdFppdG/UBRdo7qNyHutaTQwHwYDVR0jBBgwFoAUBrAxRdFppdG/UBRdo7qNyHutaTQwCgYIKoZIzj0EAwIDSAAwRQIhAI2+8C92z9wTcTWkQ/goRxs10EBC+h78O+vgo9k97z5iAiBSeqfaVr5taQTS31+McGTAK3cYWNTg0DlOBI8aKO2oRg=="
++ private {
++ key "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgtOeEb0dMb5P/2Exi09WWvk6Cvz0oOBoDuP68ZimS2LShRANCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMW"
++ }
++ }
+
+[edit]
+
+vyos@vyos# commit
+```
+
+You do **not** need to copy the certificate to the other router. Instead, retrieve its SHA-256 fingerprint. Since OpenVPN currently supports only SHA-256 fingerprints, use the following command:
+
+``` none
+vyos@vyos# run show pki certificate openvpn-local fingerprint sha256
+5C:B8:09:64:8B:59:51:DC:F4:DF:2C:12:5C:B7:03:D1:68:94:D7:5B:62:C2:E1:83:79:F1:F0:68:B2:81:26:79
+```
+
+::::{note}
+Certificate names are arbitrary. While `openvpn-local` and `openvpn-remote` are used here, you may choose any names.
+::::
+
+Repeat the procedure on the other router.
+
+## Set up site-to-site OpenVPN
+
+Local configuration:
+
+``` none
+Configure the tunnel:
+
+set interfaces openvpn vtun1 mode site-to-site
+set interfaces openvpn vtun1 protocol udp
+set interfaces openvpn vtun1 persistent-tunnel
+set interfaces openvpn vtun1 remote-host '203.0.113.11' # Public IP of the other side
+set interfaces openvpn vtun1 local-port '1195'
+set interfaces openvpn vtun1 remote-port '1195'
+set interfaces openvpn vtun1 local-address '10.255.1.1' # Local IP of vtun interface
+set interfaces openvpn vtun1 remote-address '10.255.1.2' # Remote IP of vtun interface
+set interfaces openvpn vtun1 tls certificate 'openvpn-local' # The self-signed certificate
+set interfaces openvpn vtun1 tls peer-fingerprint <remote cert fingerprint> # The output of 'run show pki certificate <name> fingerprint sha256' on the remote router
+set interfaces openvpn vtun1 tls role active
+```
+
+Remote configuration:
+
+``` none
+set interfaces openvpn vtun1 mode site-to-site
+set interfaces openvpn vtun1 protocol udp
+set interfaces openvpn vtun1 persistent-tunnel
+set interfaces openvpn vtun1 remote-host '198.51.100.10' # Pub IP of other site
+set interfaces openvpn vtun1 local-port '1195'
+set interfaces openvpn vtun1 remote-port '1195'
+set interfaces openvpn vtun1 local-address '10.255.1.2' # Local IP of vtun interface
+set interfaces openvpn vtun1 remote-address '10.255.1.1' # Remote IP of vtun interface
+set interfaces openvpn vtun1 tls certificate 'openvpn-remote' # The self-signed certificate
+set interfaces openvpn vtun1 tls peer-fingerprint <local cert fingerprint> # The output of 'run show pki certificate <name> fingerprint sha256 on the local router
+set interfaces openvpn vtun1 tls role passive
+```
+
+
+## Set up pre-shared keys
+
+Before VyOS 1.4, site-to-site OpenVPN without PKI required pre-shared keys. This option is still available but is deprecated and will be removed in future releases. If you need to set up a tunnel to an older VyOS version or a system with older OpenVPN, you still need to use pre-shared keys.
+
+First, generate a key by running `run generate pki openvpn shared-secret install <name>` in configuration mode. You can use any name; in this example, we use `s2s`.
+
+``` none
+vyos@local# run generate pki openvpn shared-secret install s2s
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+vyos@local# compare
+[pki openvpn shared-secret]
++ s2s {
++ key "7c73046a9da91e874d31c7ad894a32688cda054bde157c64270f28eceebc0bb2f44dbb70335fad45148b0456aaa78cb34a34c0958eeed4f75e75fd99ff519ef940f7029a316c436d2366a2b0fb8ea1d1c792a65f67d10a461af83ef4530adc25d1c872de6d9c7d5f338223d1f3b66dc3311bbbddc0e05228c47b91c817c721aadc7ed18f0662df52ad14f898904372679e3d9697d062b0869d12de47ceb2e626fa12e1926a3119be37dd29c9b0ad81997230f4038926900d5edb78522d2940cfe207f8e2b948e0d459fa137ebb18064ac5982b28dd1899020b4f2b082a20d5d4eb65710fbb1e62b5e061df39620267eab429d3eedd9a1ae85957457c8e4655f3"
++ version "1"
++ }
+
+[edit]
+
+vyos@local# commit
+[edit]
+```
+
+Next, install the key on the remote router:
+
+``` none
+vyos@remote# set pki openvpn shared-secret s2s key <generated key string>
+```
+
+Finally, configure the key in your OpenVPN interface settings:
+
+``` none
+set interfaces openvpn vtun1 shared-secret-key s2s
+```
+
+
+## Set up firewall exceptions
+
+To allow OpenVPN traffic to pass through the WAN interface, create a firewall exception:
+
+``` none
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 action 'accept'
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 description 'Allow established/related'
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 state 'established'
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 state 'related'
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 action 'accept'
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 description 'OpenVPN_IN'
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 destination port '1195'
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 log
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 protocol 'udp'
+```
+
+Apply the OUTSIDE_LOCAL firewall group to the WAN interface and to the input filter for traffic destined for the router itself:
+
+``` none
+set firewall ipv4 input filter rule 10 action 'jump'
+set firewall ipv4 input filter rule 10 inbound-interface name eth0
+set firewall ipv4 input filter rule 10 jump-target OUTSIDE_LOCAL
+```
+
+Static routing:
+
+Configure static routes by referencing the tunnel interface. For example, if the local router\'s network is `10.0.0.0/16` and the remote router\'s network is `10.1.0.0/16`, define the routes as follows:
+
+Local configuration:
+
+``` none
+set protocols static route 10.1.0.0/16 interface vtun1
+```
+
+Remote configuration:
+
+``` none
+set protocols static route 10.0.0.0/16 interface vtun1
+```
+
+As with standard Ethernet interfaces, you can apply firewall policies to the tunnel interface for input, output, and forward directions.
+
+If you use multiple tunnels, OpenVPN must distinguish between them beyond just the pre-shared key. To achieve this, assign either unique IP addresses or unique ports to each tunnel.
+
+Verify OpenVPN status using the show openvpn operational commands.
+
+``` none
+vyos@vyos:~$ show openvpn site-to-site
+
+OpenVPN status on vtun1
+
+Client CN Remote Host Tunnel IP Local Host TX bytes RX bytes Connected Since
+----------- ----------------- ----------- ------------ ---------- ---------- -----------------
+N/A 10.110.12.54:1195 N/A N/A 504.0 B 656.0 B N/A
+```
+
+
+### Server-client
+
+In OpenVPN's server-client mode, the server acts as a central hub, allowing multiple clients to connect and securely route their traffic or access a private network. Multi-client server is the most popular OpenVPN mode for routers.
+
+## Set up server-client certificates
+
+Server-client mode always uses x.509 authentication and therefore requires a PKI setup. The PKI utility now simplifies the creation of Certificate Authorities (CAs), server and client certificates, and Diffie-Hellman keys directly in VyOS using configuration or operational mode commands.
+
+On the server, generate all certificates by running the following commands in configuration mode. The certificates will be added to the configuration session\'s PKI subtree.
+
+Certificate Authority (CA):
+
+``` none
+vyos@vyos# run generate pki ca install ca-1
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io) ca-1
+Enter how many days certificate will be valid: (Default: 1825)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N]
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+vyos@vyos# compare
+[pki]
++ ca ca-1 {
++ certificate "MIIDlzCCAn+gAwIBAgIUQW7AtPu0Qzp7VzT0TyYx83/ME8swDQYJKoZIhvcNAQELBQAwVDELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzENMAsGA1UEAwwEY2EtMTAeFw0yNTA2MTExMTIyMjJaFw0zMDA2MTAxMTIyMjJaMFQxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxDTALBgNVBAMMBGNhLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDi+v6i241T9ABxq1ngjWxDQITkqjV0nq2Jb3HSSuQpXRCu7DWdQZlbvnMHnkV/WTL0RNgkhS4iV/WYhE+bLihwiZ0GTeQnUd1QJSkusFROX46w6kKXYUR5IQtcBC+vdky8PESynPd+DXsJn5X9JTWqDeviUAQz/ZjDzWk+71MBCqa+Zps1zpIjK0ywn7pR/HnDrxJOQXlBMNgvbv8U3IAZ2jJp0jTB8TnuDtWSA+XZejMm/EN/AWUQyliX6OJFSCIhBL2BZ9lmVms4/HkRpbd50k3vvCoz+lAOEE6VsH0fEdLC3lZ+CtXZ7kjp2wdWWuSs5ggIJYZZkixsCisbtEmbAgMBAAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAdBgNVHQ4EFgQUAG9lvr7AzJ/y4vY/XlWxXru+6m0wDQYJKoZIhvcNAQELBQADggEBAKsu4eZa8Fha9aKfuKqlGQHPpEFfVDaVJmebw0uMw+b5Y8EpBxzZrgbqbk3Mty8pBjNa9jkZzph04gHN4pR6kg3iQlUKGxZUfsB9ZUjKhkgNdUI9zq1323MKEvuIuYdt61DCfBHwY6Xax5Ge+BahR2bXdPaQH452/+xMTqkukkpLbioTeIDg6FCU2HYPY5emDF5DDZAZWXtTqi0zdT3Y6FqiTvs5VuWwXCcp+HM+Lwe1/VVJhwi4CHTq0CKWnQIH5blYjmyxzRBlrlZm4ntWlL5Mtepa1A3DJirY4kw/SqMAAh/Q9lh41JzBc8epf+OdnOzK55YmtmctGO2o+NBCFi0="
++ private {
++ key "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDi+v6i241T9ABxq1ngjWxDQITkqjV0nq2Jb3HSSuQpXRCu7DWdQZlbvnMHnkV/WTL0RNgkhS4iV/WYhE+bLihwiZ0GTeQnUd1QJSkusFROX46w6kKXYUR5IQtcBC+vdky8PESynPd+DXsJn5X9JTWqDeviUAQz/ZjDzWk+71MBCqa+Zps1zpIjK0ywn7pR/HnDrxJOQXlBMNgvbv8U3IAZ2jJp0jTB8TnuDtWSA+XZejMm/EN/AWUQyliX6OJFSCIhBL2BZ9lmVms4/HkRpbd50k3vvCoz+lAOEE6VsH0fEdLC3lZ+CtXZ7kjp2wdWWuSs5ggIJYZZkixsCisbtEmbAgMBAAECggEAZdykF6wV8Z4n8NsoG4j8E/ZJbWEhWjO3x1y3JNutJw735LhmmysMSsreToXtxGfgYRTgNwt5l7oHoqmGHCsLxO1NBb5A7JBllIkIwUYqn31syOJofg0NsJpuwZ2zVLfvWe5mGg4tV2lvVPNEWXWwbp+Ow2KLcFWXkA+H8tFuW6F2mH3ntYlIi/WiCNjsEotNx8Kk7OVwt43DbkN/rbF5lxquuLedaSspOHuhIAOfZB5ZySfqohQalSAaguVD66rGPMrerZ2Vc7B1iJ6Mn/KZrSaQeHwyWrwDDHdzVwG9waydevtGTVO0dvH4etWnRypDx8p1FPJJKD4XVcsl3rR6oQKBgQD497Ep2RJcbNnKVj+kNXGriSGmyRSp6CL61KotepzgucK0RtGMeFJge56/otMHMAxIOcDMX6vRn2MB2pqVqwqUBQy6JfLrSemdpIjMN9xlX6Dw3BWP39SdewZ896/Eo0Q1ythMj1ORp+u3PqOlSa14Cy9aPwDWmNy2deD68YDnsQKBgQDpZE/T84BMQ0FzL6NRijZRzR6Dc775hRfmmSTYI0KqpG0gXNSc5UgrWSLN5H7fnx36mT01P7UkgXCInV0AlJOfkt4a8QTqM1Fh/rZbLLWpQE55S6Fs28GDiFYl2kvZT/TtxhA/E0POf/YXl/8KITS7ZVAZxE8rxBe1hVUfDbnlCwKBgQDeWUguGaGeTdCMNk8MNnbYPdaCAB+mRp3G6ls51sF4qi5Lltva2jKn3H/AoohZaP3vGzUm0WLACdsAct2QQXtnCsN9FBtJK2+qzKEn0dPR7X/s3IGdRse6BX+b6BFgSnfGmuxmI7L86L1JoHXCTnTQOx0FOjNjdI3ZnplZRIpdYQKBgFJacASU9l9yl+SiGZnLEDG7FBpEPE3lVbKrtSGDB6IY1NzHhMo76URKdop6Jv6XMcfcTIm+ihdwiRnblRaAVrrG4xJUm2xcYUoXy5bOZudq5oXMVxCHVngoImXG6l6q5P0Fl3P6Q0HZSye2HWsgnm/FZwdAisMhtU/61TdY65BTAoGBAM4jKeImiXta5lz1RgNiW/TPhft3UbOLj3TbzchNCNAamqCv4Tmh9YKB2d/mz2hNxbnAGe2cYn4iRYKcjJLMZ0UfBL2WxlrgQYQPPGzSD0fH1pLIXPohpBZpsGqNR3Nc8Jd+Uw3IiIJ2oxPCOPTOJsklNB0Xf1AlUUagB16bhhZZ"
++ }
++ }
+
+[edit]
+vyos@vyos# commit
+```
+
+Server certificate:
+
+``` none
+vyos@vyos# run generate pki certificate sign ca-1 install srv-1
+Do you already have a certificate request? [y/N] N
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io) srv-1
+Do you want to configure Subject Alternative Names? [y/N]
+Enter how many days certificate will be valid: (Default: 365)
+Enter certificate type: (client, server) (Default: server) server
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N]
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+vyos@vyos# compare
+[pki certificate]
++ srv-1 {
++ certificate "MIIDrDCCApSgAwIBAgIULpu+qZjfG01kUI58XNmqXbQC3qQwDQYJKoZIhvcNAQELBQAwVDELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzENMAsGA1UEAwwEY2EtMTAeFw0yNTA2MTExMTMxMDJaFw0yNjA2MTExMTMxMDJaMFUxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxDjAMBgNVBAMMBXNydi0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAysTrMfVH63aVidJT7bIf+zLwkLse07nGsv4aliGEbufr239RBHV4Jn8LbQ+nB/8mhYGjNY4OnZ7NYz3FU/iglo8qFtaZ26mWtPWpv2xW1F8JAEK7l5BAg42cBucxiIZFeRm+jkE6VN1bcNU0utnn3sbCwZMyH6pS9k08G1qrrFLA7ZFhv5AmgJcODmO8sigSAu7rRS/6O3eO6ICnVjvIfHLb+9DKKUEffHzFV8RrkqVCGmgisz9fF+j1Rvg9s+ylNc2lZJTbb1XnzixvSRro4t9I3uIWdpJ0iOu09YiTXGQgH9ER6V3rFiX00RdSiSXf+MJCV64hC1msg+8V3Nrw9QIDAQABo3UwczAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUzH0h4vBxma89HF9rUQ+DW052c5swHwYDVR0jBBgwFoAUAG9lvr7AzJ/y4vY/XlWxXru+6m0wDQYJKoZIhvcNAQELBQADggEBAI/Cyd0y7AJ7wY3yRssCud2iJAl9/ZjgxzXOUo6ibawYIYOnSf9tS3eD4CIH4BgppDXoJZ/qEA4WvIsLx3yvnyOxiqyk3TQmKIZ27VJH+yQkgzPeiKrHn1pCXBKEb1/jlT8Ozu4Lmn/oFwDH6nk8toxI8DM+qsTxqUFlTA3ea9yaRtxeNPMWJdaxZSUYGVSZL0wVKw5ZuQ1Gn7vGVApWlYDKYbMozCuZUG1q8wMzFBRa7x0anvh5hM4bksLz+Y1ujCS8f8b4Xtb8KIdFrZtTvtl97crv62bN05VueAcbwtYbIBNWNoT/CvmqV7k3uPg95GYSNddFqEMbQHoyd8hdDCo="
++ private {
++ key "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKxOsx9UfrdpWJ0lPtsh/7MvCQux7Tucay/hqWIYRu5+vbf1EEdXgmfwttD6cH/yaFgaM1jg6dns1jPcVT+KCWjyoW1pnbqZa09am/bFbUXwkAQruXkECDjZwG5zGIhkV5Gb6OQTpU3Vtw1TS62efexsLBkzIfqlL2TTwbWqusUsDtkWG/kCaAlw4OY7yyKBIC7utFL/o7d47ogKdWO8h8ctv70MopQR98fMVXxGuSpUIaaCKzP18X6PVG+D2z7KU1zaVklNtvVefOLG9JGuji30je4hZ2knSI67T1iJNcZCAf0RHpXesWJfTRF1KJJd/4wkJXriELWayD7xXc2vD1AgMBAAECggEACsUk3PVzSX11+ekTDigM7NHK11UpEQPoGu/GR70mBKIK9BCyI/N9W0YaPEO9kn4p9KNrINgXzKV3sVLBnXEyTmzyRl5Fs9YxLBF0X7eIcSVPHBVvU2CVHKez5uX2ypKfNAx7A6FRUNqlFbwtXdNfLoUOKSwBWI86ctytWaKaRb/TTSGQkaP/z/cwIsXOLfG9m6iFkw98ShUzalrUWNo/4fJKlO1+DvXVYE9sv9rjD8J7DtAbr5KykQ5n0AAlZTCWQ7jwMybSnjjY9ypZUms0l17raJrfhrdbWayc6xMDvtrmNIDebkF+J7cHU06aEV+yQXV/7yjyZgUSM2ANcHMdzQKBgQDmTi5tUeaj1JUSl9lAP/XUzcElw2tcU1B8qpX69J4ofjTNgj5okLWQZVIy1UyAfLOI3LJbHTBUtSvedhH0VaMulq99NXs5qnbPGG3//RBAc0wKhJknB5Qv0D3FxMI14kMO6jzPly+aIGEk4dTtHvZuHbbVHbKSZ5MMouLyT+SS7wKBgQDhZETARZ0MazeWRaPJwdkjlfNcqqcsnDicdcppCkcDCjeLxkVPZc8ej37rshOvw2Pf1D0PddGyOhJoWCWA8QE2LQoDHLaDnQ0L6aQ3yjN5Gxx9RCDFi3Zuat/mPcv3tFO7uUmeYvRC5fGYrghq29NADmUefOopAc06Izd4A3iqWwKBgQC1uPrpR7a1jwgRo7/I8q8HO1MseQY903+u3ut5GYuyZ+NCRYL4/zZEua4ibivvNnZzh7E0M9PvAwWag4+nO+uG11+hbJHO7rLQtnYVh5lLQa6+neI66cAD+kzDwH1+BwriufFB3Amzk9kTQR7B+6x3NvsNLmG5JADj96Mbj+7MAQKBgFIevEXplyzdK6WevexWqoyip8aNjtdcG+w1pofa7MCYymAs3zfseihCVBYADdguModsxsqJPNvY+Lf31cJDDRP2GP3FSmJtqEE84U5KZ7KqRBkH54DSLVZRrj4vKc+YbiGpgr8ogqKVMQ9V6U81xKREGmefT5mdRG74Qc+CREadAoGAFtdsH5js1yFEeGFad4BZJ69grEavD3pNCfIe9oIPtXvvFdzxd+QbKgqFf3JMJp/HYi8A0iv/i4mzf00KXzF4JU7bIJYrUVlk/w8x77gzDRIphsPqpMBJkTI0jisQHZKWNEe7IbmM/dWW2S4jvCkrhB7F5Szf72Q+j/lPbfx2g/8="
++ }
++ }
+
+[edit]
+vyos@vyos# commit
+```
+
+Diffie-Hellman key:
+
+``` none
+vyos@vyos# run generate pki dh install dh-1
+Enter DH parameters key size: (Default: 2048)
+Generating parameters...
+1 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+vyos@vyos# compare
+[pki]
++ dh dh-1 {
++ parameters "MIIBCAKCAQEAp25kxwZeLZ7wcbRii5E5RD4uWCUOBxarzKEE0msa84omh5nZ9dv/4bfJw4gIXlA2+sGc2lLV/jajZminMryiSwJdisyVuUdOB7sJWZwrzHBAY0qFbNyaRMVJBar2xVm+XcKd3A2eNTEgn10G7rPPvf6CJ5isUKFaKT8ymUv+mI0upLneYdGs8/yS3sAojzeulCf49fa5SiaGCcZZkdOI3Nby1u/ZG4okqJ2wE2c2hRVLs1k5qrrono0OF4Dh0B91ihnywRfp1xPYeqpiln+OPh+PPgTuBxkz4VxwRDoQ+NhVr/LOCb3vbhnyFisxI0w4r3109cA3QiDmo1L14aKl1wIBAg=="
++ }
+
+[edit]
+vyos@vyos# commit
+```
+
+Client certificate:
+
+``` none
+vyos@vyos:~$ generate pki certificate sign ca-1 install client1
+Do you already have a certificate request? [y/N] N
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io) client1
+Do you want to configure Subject Alternative Names? [y/N]
+Enter how many days certificate will be valid: (Default: 365)
+Enter certificate type: (client, server) (Default: server) client
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N]
+You are not in configure mode, commands to install manually from configure mode:
+set pki certificate client1 certificate 'MIIDrjCCApagAwIBAgIUPvtffeYTdoOiHxu++wdrjHwwVX4wDQYJKoZIhvcNAQELBQAwVDELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzENMAsGA1UEAwwEY2EtMTAeFw0yNTA2MTExMTQxMDlaFw0yNjA2MTExMTQxMDlaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB2NsaWVudDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9H6E6gm0PfXO1n/WoA9xlg89/bnScLmfztVDn1uyNn8epE6zAi2GWBhtj4ixLllIwLdkJ7L2mF3yUZtA1Q0oYbGIqTbnaZ37JydCygVGnlLT7UX9zfRfS3KebCIvIte7OyCmnUfVfFzdIsp+4LI3S2wX/9Vyn4UBAR8QQNbezRB3XPMk9gzULnuLhmEDP6GVcPq7RzGXoXUMqsCxfEOJBjej0y4ANKH07HGVVrfVRiY+zlGkM4TFjVuZKnEA0BO6dhOA0E+7gsIXsC06UzzatkjsyWHpb2/DOECIifBoYej9DITu8VxyyZmgaINHEn2gGb0LRHO7rvQapc+XZ2z9DAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0GA1UdDgQWBBQnUyqEzG+AqZzsdSud5MDqsOxiXTAfBgNVHSMEGDAWgBQAb2W+vsDMn/Li9j9eVbFeu77qbTANBgkqhkiG9w0BAQsFAAOCAQEAplItvZpoX/joG3QREu9tHVKwDTmXB2lwUM5G8iKPgd6D6oOILZMe2KuvWt12dcdEzUCGfJwJJ8M8R2WD0OmcLdFqvM/8UM1hYzUP2BCnFCLtElVD+b4wMlQNpdHqNbdckw8J4MLQlhUgu9rZAZ0XjWCprr+U50bX++vYRw7Un3Ds6ETEvjflm5WAPb2e0V1hhISPl8K+VXO7RAwxy0DHcDuR+YaD+hnNgMsJV3/QwA17Iy8x86RpOgqmesbt0U7e9Rmo81aVgiy/V4OCV7u6bPX03fmZNS8UwwJuRUlxkjO+epHNYB2cnOcjSkUxaIJ9Hv3tMWHQEtbVZsNYSOZozw=='
+set pki certificate client1 private key 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9H6E6gm0PfXO1n/WoA9xlg89/bnScLmfztVDn1uyNn8epE6zAi2GWBhtj4ixLllIwLdkJ7L2mF3yUZtA1Q0oYbGIqTbnaZ37JydCygVGnlLT7UX9zfRfS3KebCIvIte7OyCmnUfVfFzdIsp+4LI3S2wX/9Vyn4UBAR8QQNbezRB3XPMk9gzULnuLhmEDP6GVcPq7RzGXoXUMqsCxfEOJBjej0y4ANKH07HGVVrfVRiY+zlGkM4TFjVuZKnEA0BO6dhOA0E+7gsIXsC06UzzatkjsyWHpb2/DOECIifBoYej9DITu8VxyyZmgaINHEn2gGb0LRHO7rvQapc+XZ2z9DAgMBAAECggEAPS/Fhtt5k2BgFivZW3FcVc+OS0keGwV8hkFsGoXTZIKEIzSFWIn/mX0CUY90C0Rn9MRwiqB4PwssOAsHY6QQjdRK8irRbVK8l2ZeydHC7DfVUdXtKR0YnxTaePML3nTV/TqPF14Rx6EINtHrkLeBbu2DhGsKfhoHIoTVbvUiKLHa2TkGJOkhvjsyMSPKzUXa1AzLmu+UBIhRYpEPHj0SQUUJJnKgIb7mTR2fhJScHcKwsrPq6S8OpChvsYZ6zatgrTFz9tuhD4IjL7NBiYP45BwGaLIaQjph8yAJwwHWoOP+TTj5WYflkW6Uu8F9gC0ve6dPGPNEi2TUdirvAe4LYQKBgQD0UfAPm6tQg8pdkvfMBvYc21fk8zqmgcA4OtvDi60aXuv5jI5+faISvOG2JLuFhKIDOb5ZerzGvkN+LvWgzr9H7YdGZNNtwKgpS/MGqcuuHncTxWBAwYgKhf26a/tqFZRNurJ6GowxDiAcQEc1mWnmdngRa+dvvCwNbXvGVqfVEQKBgQDGKi447TqD76QfvRPn/fRSjM+QE1duk+XorEJ0HHIha5HV9kCrZdV/olGRjDLwPJO6JW7iE2FUsS9SsIrccFE/9P2ZUqfYP2wL5vNO5kAmoLLUl0gwqg1WnBTPJfXeKReTj2uGmOdEuuMPXpL/49hDuPViiE2Q4MGe2Z+oEYN/EwKBgHfQMuTEl2e9qaDn8OM6SrluC5V4fjunh6dLnfgwaCx1fk1702lOnQuJWzsiml9o4raoO6PP4AGqzphz2PsKSJ2ya1NnIJRDFXRjDYQoAn2Z7RViBsja36chfINObxXgDUFtHBdrK3LnFXIlR4aOfHOLh2grvWx7IDNZjIiAeH+xAoGAJlmFZnjqiRv4bDgAQTZRcSRVCvHjSsAOj0++8I+MutEBgSHN9B2aCsBT/tHeDcX7ZNvXsKLFhElh+iO2S+DkqHb2GRT47I2hkFAaqBtBMPiKgz/ftaNDP46nLEuRYHQdXu4zhfHTV+a/CHtqAWGLuddyjaYJNM96SQ6eqjzxcMcCgYAzdxOF2e27hIgo2ttjsROMGqW0/0r/HsKGKPnao7xHQNCAswTnBT+QGugPCe0NXjuxbySP7V1GeWMWF+WV5khtteWerT1/ELAC48NSDpaMxVa4GP8Q/0w6+ZyJty3UGbCYQzZZue81dU+42LUIaVJ4NAc2tYj3jD780udasawS6w=='
+```
+
+Manually copy the CA, client certificate, and Diffie-Hellman key to the client device, then commit them before configuring the OpenVPN interface.
+
+For more options, refer to {ref}`configuration/pki/index:pki`.
+
+## Set up server-client OpenVPN
+
+The following example demonstrates the most complicated scenario: each client acts as a router with its own subnet (e.g., an HQ and multiple branch offices). Simpler setups are subsets of it.
+
+In this scenario, the 10.23.1.0/24 network is used for client tunnel endpoints, and all client subnets belong to 10.23.0.0/20. Each client needs access to the 192.168.0.0/16 network.
+
+Server configuration:
+
+``` none
+set interfaces openvpn vtun10 encryption data-ciphers 'aes256'
+set interfaces openvpn vtun10 hash 'sha512'
+set interfaces openvpn vtun10 local-host '172.18.201.10'
+set interfaces openvpn vtun10 local-port '1194'
+set interfaces openvpn vtun10 mode 'server'
+set interfaces openvpn vtun10 persistent-tunnel
+set interfaces openvpn vtun10 protocol 'udp'
+set interfaces openvpn vtun10 server client client1 ip '10.23.1.10'
+set interfaces openvpn vtun10 server client client1 subnet '10.23.2.0/25'
+set interfaces openvpn vtun10 server domain-name 'vyos.net'
+set interfaces openvpn vtun10 server max-connections '250'
+set interfaces openvpn vtun10 server name-server '172.16.254.30'
+set interfaces openvpn vtun10 server subnet '10.23.1.0/24'
+set interfaces openvpn vtun10 server topology 'subnet'
+set interfaces openvpn vtun10 tls ca-certificate ca-1
+set interfaces openvpn vtun10 tls certificate srv-1
+set interfaces openvpn vtun10 tls dh-params dh-1
+```
+
+The configuration above uses the default 1194/UDP port, 256-bit AES encryption, SHA-512 for HMAC authentication, and the persistent-tunnel option. Persistent-tunnel is recommended as it keeps the TUN/TAP device active during connection resets or daemon reloads. Clients are identified by the CN attribute in their SSL certificates.
+
+To grant clients access to a specific network behind the router, use the push-route option to automatically install the appropriate route on each client.
+
+``` none
+set interfaces openvpn vtun10 server push-route 192.168.0.0/16
+```
+
+OpenVPN does not automatically create kernel routes for client subnets when clients connect; it only uses client-subnet association internally. Therefore, you must manually create a route to the 10.23.0.0/20 network:
+
+``` none
+set protocols static route 10.23.0.0/20 interface vtun10
+```
+
+
+## Set up OpenVPN client
+
+VyOS can operate not only as an OpenVPN site-to-site peer or a server for multiple clients, but also as an OpenVPN client. Any VyOS OpenVPN interface can be configured to connect to another VyOS or third-party OpenVPN server.
+
+Client configuration:
+
+``` none
+set interfaces openvpn vtun10 encryption data-ciphers 'aes256'
+set interfaces openvpn vtun10 hash 'sha512'
+set interfaces openvpn vtun10 mode 'client'
+set interfaces openvpn vtun10 persistent-tunnel
+set interfaces openvpn vtun10 protocol 'udp'
+set interfaces openvpn vtun10 remote-host '172.18.201.10'
+set interfaces openvpn vtun10 remote-port '1194'
+set interfaces openvpn vtun10 tls ca-certificate ca-1
+set interfaces openvpn vtun10 tls certificate client1
+```
+
+
+## Verification
+
+Check the tunnel status:
+
+``` none
+vyos@vyos:~$ show openvpn server
+
+OpenVPN status on vtun10
+
+Client CN Remote Host Tunnel IP Local Host TX bytes RX bytes Connected Since
+----------- ------------------ ----------- ---------------- ---------- ---------- -------------------
+client1 172.16.12.54:33166 10.23.1.10 172.18.201.10:1194 3.4 KB 3.4 KB 2024-06-11 12:07:25
+```
+
+
+### Server bridge
+
+In Ethernet bridging configurations, an OpenVPN interface operating in server mode with the device type set to TAP can be added to a bridge. By encapsulating entire Ethernet frames (up to 1514 bytes) rather than just IP packets (up to 1500 bytes), this setup enables clients to transmit Layer 2 frames through the OpenVPN tunnel.
+
+The following is a basic configuration example:
+
+Server side:
+
+``` none
+set interfaces bridge br10 member interface eth1.10
+set interfaces bridge br10 member interface vtun10
+set interfaces openvpn vtun10 device-type 'tap'
+set interfaces openvpn vtun10 encryption data-ciphers 'aes192'
+set interfaces openvpn vtun10 hash 'sha256'
+set interfaces openvpn vtun10 local-host '172.18.201.10'
+set interfaces openvpn vtun10 local-port '1194'
+set interfaces openvpn vtun10 mode 'server'
+set interfaces openvpn vtun10 server bridge gateway '10.10.0.1'
+set interfaces openvpn vtun10 server bridge start '10.10.0.100'
+set interfaces openvpn vtun10 server bridge stop '10.10.0.200'
+set interfaces openvpn vtun10 server bridge subnet-mask '255.255.255.0'
+set interfaces openvpn vtun10 server topology 'subnet'
+set interfaces openvpn vtun10 tls ca-certificate 'ca-1'
+set interfaces openvpn vtun10 tls certificate 'srv-1'
+set interfaces openvpn vtun10 tls dh-params 'dh-1'
+```
+
+Client side:
+
+``` none
+set interfaces openvpn vtun10 device-type 'tap'
+set interfaces openvpn vtun10 encryption data-ciphers 'aes192'
+set interfaces openvpn vtun10 hash 'sha256'
+set interfaces openvpn vtun10 mode 'client'
+set interfaces openvpn vtun10 protocol 'udp'
+set interfaces openvpn vtun10 remote-host '172.18.201.10'
+set interfaces openvpn vtun10 remote-port '1194'
+set interfaces openvpn vtun10 tls ca-certificate 'ca-1'
+set interfaces openvpn vtun10 tls certificate 'client-1'
+```
+
+
+### Server LDAP authentication
+
+## LDAP
+
+Enterprise installations usually include a directory service to centralize employee password management. VyOS and OpenVPN support using LDAP and Active Directory as a single user backend.
+
+Authentication is performed by the `openvpn-auth-ldap.so` plugin, included with every VyOS installation. To use it, you must create a dedicated configuration file.
+**Best practice:** Store the configuration file in the `/config` directory to ensure it is preserved after image updates.
+
+``` none
+set interfaces openvpn vtun0 openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-ldap.so /config/auth/ldap-auth.config"
+```
+
+A sample configuration file is shown below:
+
+``` none
+<LDAP>
+# LDAP server URL
+URL ldap://ldap.example.com
+# Bind DN (If your LDAP server doesn't support anonymous binds)
+BindDN cn=LDAPUser,dc=example,dc=com
+# Bind Password password
+Password S3cr3t
+# Network timeout (in seconds)
+Timeout 15
+</LDAP>
+
+<Authorization>
+# Base DN
+BaseDN "ou=people,dc=example,dc=com"
+# User Search Filter
+SearchFilter "(&(uid=%u)(objectClass=shadowAccount))"
+# Require Group Membership - allow all users
+RequireGroup false
+</Authorization>
+```
+
+
+### Active Directory
+
+A sample configuration file is shown below:
+
+``` none
+<LDAP>
+ # LDAP server URL
+ URL ldap://dc01.example.com
+ # Bind DN (If your LDAP server doesn’t support anonymous binds)
+ BindDN CN=LDAPUser,DC=example,DC=com
+ # Bind Password
+ Password mysecretpassword
+ # Network timeout (in seconds)
+ Timeout 15
+ # Enable Start TLS
+ TLSEnable no
+ # Follow LDAP Referrals (anonymously)
+ FollowReferrals no
+</LDAP>
+
+<Authorization>
+ # Base DN
+ BaseDN "DC=example,DC=com"
+ # User Search Filter, user must be a member of the VPN AD group
+ SearchFilter "(&(sAMAccountName=%u)(memberOf=CN=VPN,OU=Groups,DC=example,DC=com))"
+ # Require Group Membership
+ RequireGroup false # already handled by SearchFilter
+ <Group>
+ BaseDN "OU=Groups,DC=example,DC=com"
+ SearchFilter "(|(cn=VPN))"
+ MemberAttribute memberOf
+ </Group>
+</Authorization>
+```
+
+If you only want to check that the user account is enabled and can authenticate (against the primary group), the following snippet is sufficient:
+
+``` none
+<LDAP>
+ URL ldap://dc01.example.com
+ BindDN CN=SA_OPENVPN,OU=ServiceAccounts,DC=example,DC=com
+ Password ThisIsTopSecret
+ Timeout 15
+ TLSEnable no
+ FollowReferrals no
+</LDAP>
+
+<Authorization>
+ BaseDN "DC=example,DC=com"
+ SearchFilter "sAMAccountName=%u"
+ RequireGroup false
+</Authorization>
+```
+
+A complete example of an LDAP authentication configuration for OpenVPN is shown below:
+
+``` none
+vyos@vyos# show interfaces openvpn
+ openvpn vtun0 {
+ mode server
+ openvpn-option "--tun-mtu 1500 --fragment 1300 --mssfix"
+ openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-ldap.so /config/auth/ldap-auth.config"
+ openvpn-option "--push redirect-gateway"
+ openvpn-option --duplicate-cn
+ openvpn-option "--verify-client-cert none"
+ openvpn-option --comp-lzo
+ openvpn-option --persist-key
+ openvpn-option --persist-tun
+ server {
+ domain-name example.com
+ max-connections 5
+ name-server 203.0.113.0.10
+ name-server 198.51.100.3
+ subnet 172.18.100.128/29
+ }
+ tls {
+ ca-certificate ca.crt
+ certificate server.crt
+ dh-params dh1024.pem
+ }
+ }
+```
+
+For a detailed example, refer to {doc}`OpenVPN with LDAP</configexamples/autotest/OpenVPN_with_LDAP/OpenVPN_with_LDAP>`.
+
+### Multi-factor authentication
+
+VyOS supports multi-factor authentication (MFA) or two-factor authentication using Time-based One-Time Passwords (TOTP). It is compatible with Google Authenticator and other software tokens.
+
+## Server side
+
+``` none
+set interfaces openvpn vtun20 encryption cipher 'aes256'
+set interfaces openvpn vtun20 hash 'sha512'
+set interfaces openvpn vtun20 mode 'server'
+set interfaces openvpn vtun20 persistent-tunnel
+set interfaces openvpn vtun20 server client user1
+set interfaces openvpn vtun20 server mfa totp challenge 'disable'
+set interfaces openvpn vtun20 server subnet '10.10.2.0/24'
+set interfaces openvpn vtun20 server topology 'subnet'
+set interfaces openvpn vtun20 tls ca-certificate 'openvpn_vtun20'
+set interfaces openvpn vtun20 tls certificate 'openvpn_vtun20'
+set interfaces openvpn vtun20 tls dh-params 'dh-pem'
+```
+
+A TOTP secret is created for each client in the OpenVPN server configuration. To display authentication information, use the following command: `show interfaces openvpn vtun20 user user1 mfa qrcode`.
+
+Example:
+
+``` none
+vyos@vyos:~$ sh interfaces openvpn vtun20 user user1 mfa qrcode
+█████████████████████████████████████
+█████████████████████████████████████
+████ ▄▄▄▄▄ █▀▄▀ ▀▀▄▀ ▀▀▄ █ ▄▄▄▄▄ ████
+████ █ █ █▀▀▄ █▀▀▀█▀██ █ █ █ ████
+████ █▄▄▄█ █▀█ ▄ █▀▀ █▄▄▄█ █▄▄▄█ ████
+████▄▄▄▄▄▄▄█▄█ █ █ ▀ █▄▀▄█▄▄▄▄▄▄▄████
+████▄▄ ▄ █▄▄ ▄▀▄█▄ ▄▀▄█ ▄▄▀ ▀▄█ ▀████
+████ ▀██▄▄▄█▄ ██ █▄▄▄▄ █▄▀█ █ █▀█████
+████ ▄█▀▀▄▄ ▄█▀ ▀▄ ▄▄▀▄█▀▀▀ ▄▄▀████
+████▄█ ▀▄▄▄▀ ▀ ▄█ ▄ █▄█▀ █▀ █▀█████
+████▀█▀ ▀ ▄█▀▄▀▀█▄██▄█▀▀ ▀ ▀ ▄█▀████
+████ ██▄▄▀▄▄█ ██ ▀█ ▄█ ▀▄█ █▀██▀████
+████▄███▄█▄█ ▀█▄ ██▄▄▄█▀ ▄▄▄ █ ▀ ████
+████ ▄▄▄▄▄ █▄█▀▄ ▀▄ ▀█▀ █▄█ ██▀█████
+████ █ █ █ ▄█▀█▀▀▄ ▄▀▀▄▄▄▄▄▄ ████
+████ █▄▄▄█ █ ▄ ▀ █▄▄▄██▄▀█▄▀▄█▄ █████
+████▄▄▄▄▄▄▄█▄██▄█▄▄▄▄▄█▄█▄█▄██▄██████
+█████████████████████████████████████
+█████████████████████████████████████
+```
+
+Scan the QR code to add the user account to Google Authenticator. On the client side, use the generated OTP as the password.
+
+### Authentication with username/password
+
+An OpenVPN server can securely obtain a username and password from a connecting client and use this information for authentication.
+
+First, configure the server to use an authentication plugin or script. The server calls this plugin every time a client tries to connect, passing it the client\'s credentials.
+
+In the following example, the `--auth-user-pass-verify` directive is used with the via-env method and a specified script path to validate the client\'s username and password.
+
+## Server configuration
+
+``` none
+set interfaces openvpn vtun10 local-port '1194'
+set interfaces openvpn vtun10 mode 'server'
+set interfaces openvpn vtun10 openvpn-option '--auth-user-pass-verify /config/auth/check_user.sh via-env'
+set interfaces openvpn vtun10 openvpn-option '--script-security 3'
+set interfaces openvpn vtun10 persistent-tunnel
+set interfaces openvpn vtun10 protocol 'udp'
+set interfaces openvpn vtun10 server client client-1 ip '10.10.10.55'
+set interfaces openvpn vtun10 server push-route 192.0.2.0/24
+set interfaces openvpn vtun10 server subnet '10.10.10.0/24'
+set interfaces openvpn vtun10 server topology 'subnet'
+set interfaces openvpn vtun10 tls ca-certificate 'ca-1'
+set interfaces openvpn vtun10 tls certificate 'srv-1'
+set interfaces openvpn vtun10 tls dh-params 'dh-1'
+```
+
+The /config/auth/check_user.sh example includes two test users:
+
+``` none
+#!/bin/bash
+USERNAME="$username"
+PASSWORD="$password"
+
+# Replace this with real user checking logic or use getent
+if [[ "$USERNAME" == "client1" && "$PASSWORD" == "pass123" ]]; then
+ exit 0
+elif [[ "$USERNAME" == "peter" && "$PASSWORD" == "qwerty" ]]; then
+ exit 0
+else
+ exit 1
+fi
+```
+
+
+## Client configuration
+
+Storing the client certificate locally lets you generate the OpenVPN client configuration file. Use the following command:
+
+``` none
+vyos@vyos:~$ generate openvpn client-config interface vtun10 ca ca-1 certificate client1
+```
+
+Copy the output and save it as a .ovpn file. Add the `auth-user-pass` directive to the file. This instructs the OpenVPN client to prompt the user for a username and password, which are then sent to the server over the TLS channel. You can now import this file into any OpenVPN client application.
+
+``` none
+client
+dev tun
+proto udp
+remote 192.168.77.10 1194
+
+remote-cert-tls server
+proto udp
+dev tun
+dev-type tun
+persist-key
+persist-tun
+verb 3
+auth-user-pass
+
+
+<ca>
+-----BEGIN CERTIFICATE-----
+MIIDlzCCAn+gAwIBAgIUQW7AtPu0Qzp7VzT0TyYx83/ME8swDQYJKoZIhvcNAQEL
+BQAwVDELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcM
+CVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzENMAsGA1UEAwwEY2EtMTAeFw0yNTA2
+MTExMTIyMjJaFw0zMDA2MTAxMTIyMjJaMFQxCzAJBgNVBAYTAkdCMRMwEQYDVQQI
+DApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1Mx
+DTALBgNVBAMMBGNhLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDi
++v6i241T9ABxq1ngjWxDQITkqjV0nq2Jb3HSSuQpXRCu7DWdQZlbvnMHnkV/WTL0
+RNgkhS4iV/WYhE+bLihwiZ0GTeQnUd1QJSkusFROX46w6kKXYUR5IQtcBC+vdky8
+PESynPd+DXsJn5X9JTWqDeviUAQz/ZjDzWk+71MBCqa+Zps1zpIjK0ywn7pR/HnD
+rxJOQXlBMNgvbv8U3IAZ2jJp0jTB8TnuDtWSA+XZejMm/EN/AWUQyliX6OJFSCIh
+BL2BZ9lmVms4/HkRpbd50k3vvCoz+lAOEE6VsH0fEdLC3lZ+CtXZ7kjp2wdWWuSs
+5ggIJYZZkixsCisbtEmbAgMBAAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAdBgNVHQ4E
+FgQUAG9lvr7AzJ/y4vY/XlWxXru+6m0wDQYJKoZIhvcNAQELBQADggEBAKsu4eZa
+8Fha9aKfuKqlGQHPpEFfVDaVJmebw0uMw+b5Y8EpBxzZrgbqbk3Mty8pBjNa9jkZ
+zph04gHN4pR6kg3iQlUKGxZUfsB9ZUjKhkgNdUI9zq1323MKEvuIuYdt61DCfBHw
+Y6Xax5Ge+BahR2bXdPaQH452/+xMTqkukkpLbioTeIDg6FCU2HYPY5emDF5DDZAZ
+WXtTqi0zdT3Y6FqiTvs5VuWwXCcp+HM+Lwe1/VVJhwi4CHTq0CKWnQIH5blYjmyx
+zRBlrlZm4ntWlL5Mtepa1A3DJirY4kw/SqMAAh/Q9lh41JzBc8epf+OdnOzK55Ym
+tmctGO2o+NBCFi0=
+-----END CERTIFICATE-----
+
+</ca>
+
+<cert>
+-----BEGIN CERTIFICATE-----
+MIIDrjCCApagAwIBAgIUN6vPxDEW89cfbEFPa0tZlnsW1GkwDQYJKoZIhvcNAQEL
+BQAwVDELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcM
+CVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzENMAsGA1UEAwwEY2EtMTAeFw0yNTA2
+MTExMTQ0MjlaFw0yNjA2MTExMTQ0MjlaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQI
+DApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1Mx
+EDAOBgNVBAMMB2NsaWVudDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCdOWq8vdO8CznGN83uAXCuN4PcdTJaRFEdJIEfqHjlcG0MZQuPIAlDbOU+IWmu
+QBmeCj7SlbYtVYo1uQOMUaIrAvxLIQUaL1Y60oLVTF5eAPrGV+NSTQR5uMApcH9/
+RcZcW530pu/QpYinKTbGkEd54so6YRVPmYbIOPNUMbnZbccpinYi5t2dqubBb585
+A7L40043VtsVVbPjQq5V0HDursvqlaMqMRcffhR8H4B4ByU/EPRK4yTKm1hi19v3
+UtRHiq74CfGtJzYtplgrLJBON7TsbIi/fEux4q1yhbKA0S66L6e5DZldRxNZOXG6
+QjEL0RkYloMgkbv/2HLCu09hAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAwDgYDVR0P
+AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0GA1UdDgQWBBQCkfdfq3hv
+7UtqAxq/5VDRIdgJLTAfBgNVHSMEGDAWgBQAb2W+vsDMn/Li9j9eVbFeu77qbTAN
+BgkqhkiG9w0BAQsFAAOCAQEAJ43+aDVRC+y2vsu6WRG2l6zYnLoIJZW4afdKMC1a
+nhTWhj4AhAt8evhVbAxi/8qhQX3yXF2bUQKdS++8AVcvZFlSES32S5eBx83AwGLt
+QkgvGx+QThKmoJwrelyuS2X0XX3P0WzohYI6HzSr6p9F8KhTvSW97E6SnldpdvEM
+uG1C+61/Vys7WLmDBh1PZTGE03nRp3H4Q9ynyXEEf1MK3eZkzg5H3Evj66p82pD5
+8IauRfghMHJf3tOC+y0YIoXshF3lPq4nYso5Jc/HGCHlsboCODMCnY3CZsH7/O1n
+/MI710KpzZTCLnv4Qtx9JpZxR7FTddl36OOuYUXU3Gcnsg==
+-----END CERTIFICATE-----
+
+</cert>
+
+<key>
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCdOWq8vdO8CznG
+N83uAXCuN4PcdTJaRFEdJIEfqHjlcG0MZQuPIAlDbOU+IWmuQBmeCj7SlbYtVYo1
+uQOMUaIrAvxLIQUaL1Y60oLVTF5eAPrGV+NSTQR5uMApcH9/RcZcW530pu/QpYin
+KTbGkEd54so6YRVPmYbIOPNUMbnZbccpinYi5t2dqubBb585A7L40043VtsVVbPj
+Qq5V0HDursvqlaMqMRcffhR8H4B4ByU/EPRK4yTKm1hi19v3UtRHiq74CfGtJzYt
+plgrLJBON7TsbIi/fEux4q1yhbKA0S66L6e5DZldRxNZOXG6QjEL0RkYloMgkbv/
+2HLCu09hAgMBAAECggEAOR3xRVUO9Sr816JRSQwz486eNDpNSxazgwtOb3JUTUH9
+E7onq1y/kMOgOmSIEHoP9GaTcQxbbPe86IxomhLT/50ri52YzWzx/heY2SVPyQXB
+FMo79putKw0vnj5UyydNiyLrbMQyrhFc5iFmWVdz5/c4cWHwjIThPp7V4znXYwHZ
+OB/Xn1NNHDNy872oQn5wZWzuA4ml0OqjU5D+Ne9srODl3r4OTo3lb1N3JuH3aOSA
+cACl1JnN/KElN8IotIdweeUFAdn2jsGjZnCpGaJvZQ+2iMn6doJXHgFiF5+GMF7o
+aOatglElIuqgPtB/4nvnegSL0DSnB36ojqv2PAh24wKBgQDPBt4S4muqo8SqP2e0
+8X78MyK3tz1VmgPKn3O68Vdi1V7FPz0RHRGsw/kdgxXsJlfZTWgzcq2NNFu0yPBJ
+A/h7qo16mv8GW7cJCd2exjb+/oq4r5iWeqLdSsMUXN87x02LRaMNd9wz1mls1Z73
+oQ5hJ7zTtlyYXnvKPQo8X1ImjwKBgQDCaptQxZ/a3tcUQQlXAFMAScviODZd0LCL
+30ZalwpNs6nVVIPoZHD3tlzWN5Es74gndfkC7/Gm2cnsOW9QQaU56q+5LeNXItW8
+rc6yXq3vNQerqJxHNUmKWwLCQtSyLRjFqpGTl/PyX2bGXQ7/zjTL3W8VMD5otf4Y
+SJJB+sKjDwKBgHSVX3WvAAamFtfwwMwKuwH3IfPnQqj0BHKUfK2nvxgvJCFbzV3X
+yt5Jtf3ClhPYO9xpVOa0C7va4lHaXkYf8Exj7SxAIKFKALccUStaYBoU6bW7XOhQ
+w2pu8ZCEBEo7oBVv77Rj7SNb+R6K5ex5TAm2QQXQSjCb9IYc/ail3TNNAoGBALu6
+GPMrgKnlFyV1j0E1DPBwUbDEuqpoArFtDRAYXFifLVTS4PQbWIG403f9++659Gy2
+G5ZcfqiwD6xL4VJLsPF1zewvhR/0gRJJehb+GVGrkRaOHykbKUGxk75kreDGbu8f
+PqaXyXS17hWIch1Lzes0jDiXdwvA//QOzztqmVq9AoGAVMbmf04+QtzckLolAP4q
+Uwr5svfy14A7V3IGkwlsHZdm37L26lfxW0kpOOE7g7D6gdinuALo6oopP7RN/IDq
+PLaaHaGrIoLAEVFa0bRLGsrU2q87ytwfSgdra4jmsTn+xEabdI4IgmqWgwSRvGVf
+KN18e19Ssw5x7Wq0Rsw/3VM=
+-----END PRIVATE KEY-----
+
+</key>
+```
+
+When prompted, log in with the username and password.
diff --git a/docs/configuration/interfaces/openvpn.md b/docs/configuration/interfaces/openvpn.md
new file mode 100644
index 00000000..170c585d
--- /dev/null
+++ b/docs/configuration/interfaces/openvpn.md
@@ -0,0 +1,614 @@
+(openvpn)=
+
+# OpenVPN
+
+Traditionally, hardware routers use IPsec exclusively because it is easy to
+implement in hardware, and their CPUs lack sufficient power for software-based
+encryption. This limitation is less relevant for VyOS, as it is a software
+router.
+
+OpenVPN has been widely used on UNIX platforms for a long time and is a popular
+choice for remote-access VPNs. It also supports site-to-site connections.
+
+OpenVPN offers the following advantages:
+
+- It uses a single TCP or UDP connection and does not rely on packet source
+ addresses, so it works even through double NAT. This makes it well-suited for
+ public hotspots.
+- It is easy to set up and offers very flexible split tunneling.
+- A variety of client GUI frontends are available for any platform.
+
+Disadvantages include:
+
+- It is slower than IPsec due to higher protocol overhead and because it runs
+ in user mode, while IPsec on Linux runs in kernel mode.
+- No operating system includes OpenVPN client software by default.
+
+In the VyOS CLI, OpenVPN is configured as a network interface using `set
+interfaces openvpn` rather than `set vpn`, which is often overlooked.
+
+## Configuration
+
+```{cfgcmd} set interfaces openvpn \<interface\> authentication password \<text\>
+
+ **Configure the password for the** ``auth-user-pass`` **authentication method.**
+
+ This option applies only to OpenVPN clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> authentication username \<text\>
+
+**Configure the username for the** ``auth-user-pass`` **authentication method.**
+
+This option applies only to OpenVPN clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> description \<description\>
+
+Configure the description for the OpenVPN interface.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> device-type \<tap | tun\>
+
+**Configure the virtual network device type for the OpenVPN interface:**
+
+* ``tun`` **(default)**: Operates at Layer 3, encapsulating IPv4 or IPv6 packets.
+* ``tap``: Operates at Layer 2, encapsulating Ethernet 802.3 frames.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> disable
+
+Disable the specific OpenVPN interface.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> encryption cipher \< 3des | aes128 | aes128gcm | aes192 | aes192gcm | aes256 | aes256gcm | none \>
+
+**Configure the static encryption cipher for the OpenVPN tunnel.**
+
+The ``cipher`` option maps to OpenVPN’s ``--cipher`` directive and specifies
+the symmetric encryption algorithm for both control and data channels.
+
+This was previously the default encryption method in all OpenVPN modes. In
+newer OpenVPN versions, the ``--cipher`` directive is considered **legacy**
+and should be used only in compatibility scenarios.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> encryption data-ciphers \< 3des | aes128 | aes128gcm | aes192 | aes192gcm | aes256 | aes256gcm | none \>
+
+**Configure a prioritized list of negotiated ciphers for OpenVPN in**
+``client`` **or** ``server`` **mode.**
+
+The ``data-ciphers`` option represents a list of supported encryption
+algorithms. It corresponds to OpenVPN’s ``--data-ciphers`` directive and
+enables cipher negotiation, where both peers automatically agree on a mutually
+supported cipher during session startup.
+
+:::{note}
+This option is not compatible with ``site-to-site`` mode.
+:::
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> encryption data-ciphers-fallback \< 3des | aes128 | aes128gcm | aes192 | aes192gcm | aes256 | aes256gcm | none \>
+
+**Configure the fallback cipher for** ``site-to-site`` **mode.**
+
+The ``data-ciphers-fallback`` option maps to OpenVPN’s ``--data-ciphers-
+fallback`` directive. It defines the cipher to use if negotiation is **not
+supported**.
+
+:::{note}
+This option ensures consistent encryption between two static peers
+without cipher negotiation capability.
+:::
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> hash \<md5 | sha1 | sha256 | ...\>
+
+Configure the hashing algorithm for the OpenVPN interface.
+```
+
+
+```{cmdincludemd} /_include/interface-ip.txt
+:var0: openvpn
+:var1: vtun0
+```
+
+
+```{cmdincludemd} /_include/interface-ipv6.txt
+:var0: openvpn
+:var1: vtun0
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> keep-alive failure-count \<value\>
+
+**Configure the number of tolerated keepalive packet failures.**
+
+Default: 60 consecutive failures.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> keep-alive interval \<value\>
+
+**Configure the frequency, in seconds, at which keepalive packets are sent.**
+
+Default: 10 seconds.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> local-address \<address\>
+
+Configure the local tunnel IP address for ``site-to-site`` mode.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> local-host \<address\>
+
+**Configure the local IP address to accept connections.**
+
+If configured, OpenVPN binds to this IP address only.
+
+By default, OpenVPN binds to all interfaces.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> local-port \<port\>
+
+Configure the local port to accept connections.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> mirror egress \<monitor-interface\>
+
+Configure mirroring of outgoing traffic from this OpenVPN interface to the
+designated monitor interface.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> mirror ingress \<monitor-interface\>
+
+Configure mirroring of incoming traffic from this OpenVPN interface to the
+designated monitor interface.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> mode \<site-to-site | server | client\>
+
+**Configure OpenVPN operation mode:**
+
+* ``site-to-site``: Establishes a site-to-site VPN connection.
+* ``client``: Operates as a client in server-client mode.
+* ``server``: Operates as a server in server-client mode.
+```
+
+### OpenVPN Data Channel Offload (DCO)
+
+OpenVPN {abbr}`DCO (Data Channel Offload)` improves the performance of
+encrypted OpenVPN data processing by keeping most data handling in the kernel
+and avoiding frequent context switches between the kernel and user space.
+
+As a result, packet processing becomes more efficient and may utilize hardware
+encryption offload support available in the kernel.
+
+:::{note}
+- {abbr}`DCO (Data Channel Offload)` is an **experimental**, not fully supported
+ OpenVPN feature. Some OpenVPN features and deployment scenarios are **not
+ compatible** with {abbr}`DCO (Data Channel Offload)`.
+
+ For a complete list of supported features, visit:
+ <https://community.openvpn.net/openvpn/wiki/DataChannelOffload/Features>
+- {abbr}`DCO (Data Channel Offload)` is configured per tunnel and disabled
+ by default. Existing tunnels operate without {abbr}`DCO (Data Channel
+ Offload)` unless it is explicitly enabled.
+- Enabling {abbr}`DCO (Data Channel Offload)` resets the interface.
+:::
+
+**Best practice:** Create a new tunnel with {abbr}`DCO (Data Channel Offload)`
+enabled to avoid compatibility issues with existing clients.
+
+```{cfgcmd} set interfaces openvpn \<interface\> offload dco
+
+ **Enable** {abbr}`DCO (Data Channel Offload)` **for the specified OpenVPN
+ interface.**
+
+ Example:
+
+ :::{code-block} none
+ set interfaces openvpn vtun0 offload dco
+ :::
+ This command enables {abbr}`DCO (Data Channel Offload)` and loads the required
+ kernel module.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> openvpn-option \<text\>
+
+**Add raw OpenVPN configuration options to the openvpn.conf file.**
+
+OpenVPN provides many configuration options, but not all are available in the
+VyOS CLI.
+
+If a required option is missing, you may submit a feature request at
+Phabricator so all users can benefit from it (see Contributing/Issues and Features).
+
+Alternatively, use ``openvpn-option`` to pass raw OpenVPN configuration options
+to the openvpn.conf file.
+
+:::{warning}
+Use this option only as a last resort. Invalid options or syntax
+may prevent OpenVPN from starting. Check system logs for errors after applying
+changes.
+:::
+Example:
+
+:::{code-block} none
+set interfaces openvpn vtun0 openvpn-option 'persist-key'
+:::
+This command adds ``persist-key`` to the configuration file. This solves the
+problem by persisting keys across resets, so they do not need to be re-read.
+
+:::{code-block} none
+set interfaces openvpn vtun0 openvpn-option 'route-up &quot;/config/auth/tun_up.sh arg1&quot;'
+:::
+This command adds ``route-up "/config/auth/tun_up.sh arg1"`` to the
+configuration file. This option is executed after connection authentication,
+either immediately or after a short delay, as defined.
+
+Ensure the path and arguments are enclosed in single or double quotes.
+
+:::{note}
+Some raw configuration options require quotes. To include them, use
+the " statement.
+:::
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> persistent-tunnel
+
+**Enable always-active mode for the TUN/TAP device.**
+
+When enabled, the TUN/TAP device remains active upon connection resets or
+daemon reloads.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> protocol \<udp | tcp-passive | tcp-active \>
+
+**Configure the protocol for OpenVPN communication with a remote host:**
+
+* ``udp`` **(default)**: Uses the UDP protocol.
+* ``tcp-passive``: Uses the TCP protocol and accepts connections passively.
+* ``tcp-active``: Uses the TCP protocol and initiates connections actively.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> redirect \<interface\>
+
+Enable redirection of incoming packets to the specified interface.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> remote-address \<address\>
+
+Configure the remote tunnel IP address for site-to-site mode.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> remote-host \<address | host\>
+
+**Configure the IPv4/IPv6 address or hostname for a server device if OpenVPN
+runs in client mode.**
+
+This setting is not used in server mode.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> remote-port \<port\>
+
+Configure the remote port to connect to the server.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> replace-default-route
+
+Configure the OpenVPN tunnel as the default route.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server bridge disable
+
+Disable the given instance.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server bridge gateway \<ipv4 address\>
+
+Configure the gateway IP address.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server bridge start \<ipv4 address\>
+
+Configure the first IP address in the pool to allocate to connecting clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server bridge stop \<ipv4 address\>
+
+Configure the last IP address in the pool to allocate to connecting clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server bridge subnet-mask \<ipv4 subnet mask\>
+
+Configure the subnet mask pushed to dynamic clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client \<name\>
+
+Configure the Common Name (CN) specified in the client certificate.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client \<name\> disable
+
+Disable the client connection.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client \<name\> ip \<address\>
+
+Configure the IPv4/IPv6 address for the client.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client \<name\> push-route \<subnet\>
+
+Configure a route to be pushed to the specific client.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client \<name\> subnet \<subnet\>
+
+**Configure a fixed subnet to be routed from the server to the specified
+client.**
+
+Used as OpenVPN’s ``iroute`` directive.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client-ip-pool start \<address\>
+
+Configure the first IP address in the subnet's IPv4 pool to be dynamically
+allocated to connecting clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client-ip-pool stop \<address\>
+
+Configure the last IP address in the subnet's IPv4 pool to be dynamically
+allocated to connecting clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client-ip-pool subnet \<netmask\>
+
+**Configure the subnet mask pushed to dynamic clients.**
+
+Use this command only for the TAP device type. Do not use it for bridged
+interfaces.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server client-ipv6-pool base \<ipv6addr/bits\>
+
+Configure the IPv6 address pool for dynamic assignment to clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server domain-name \<name\>
+
+Configure the DNS suffix to be pushed to all clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server max-connections \<1-4096\>
+
+Configure the maximum number of client connections.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server mfa totp challenge \<enable | disable\>
+
+If enabled, openvpn-otp expects a password as a result of the challenge/
+response protocol.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server mfa totp digits \<1-65535\>
+
+**Configure the number of digits to use for the** {abbr}`TOTP (Time-based
+One-Time Password)` **hash.**
+
+Default: 6.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server mfa totp drift \<1-65535\>
+
+**Configure the time drift in seconds.**
+
+Default: 0.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server mfa totp slop \<1-65535\>
+
+**Configure the allowed clock slop in seconds.**
+
+Default: 180.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server mfa totp step \<1-65535\>
+
+**Configure the step value for** {abbr}`TOTP (Time-based One-Time Password)`
+**in seconds.**
+
+Default: 30.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server name-server \<address\>
+
+Define the client DNS configuration to be used with the connection.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server push-route \<subnet\>
+
+Configure the route to be pushed to all clients.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server reject-unconfigured-client
+
+Reject connections from clients that are not explicitly configured.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server subnet \<subnet\>
+
+**Configure the IPv4 or IPv6 network.**
+
+This parameter is mandatory when operating in server mode.
+```
+
+
+```{cfgcmd} set interfaces openvpn \<interface\> server topology \< net30 | point-to-point | subnet\>
+
+**Configure the virtual addressing topology for** ``tun`` **mode.**
+
+This command does not affect ``tap`` mode, which always uses the ``subnet``
+topology.
+
+* ``subnet`` **(default)**: Allocates a single IP address to each connecting client.
+This is the recommended topology.
+* ``net30``: Allocates a /30 subnet to each connecting client. This is a legacy
+topology used to support Windows clients. It is now effectively deprecated.
+* ``point-to-point``: Creates a point-to-point topology where the remote
+endpoint of the client’s ``tun`` interface always points to the local endpoint
+of the server’s ``tun`` interface.
+
+Like ``subnet``, this topology allocates a single IP address per client. Use it
+only if no clients run Windows operating systems.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> shared-secret-key \<key\>
+
+Configure the static secret key for a site-to-site OpenVPN connection.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls auth-key \<key\>
+
+**Configure the TLS secret key for tls-auth.**
+
+This adds an HMAC signature to all SSL/TLS handshake packets to verify
+integrity.
+
+Use ``run generate pki openvpn shared-secret install <name>`` to generate
+the key.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls ca-certificate \<name\>
+
+Configure the Certificate Authority chain in the PKI configuration.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls certificate \<name\>
+
+Configure the certificate name in the PKI configuration.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls crypt-key
+
+Configure a shared secret key to provide an additional level of security,
+a variant similar to tls-auth.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls dh-params
+
+Configure Diffie-Hellman parameters for server mode.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls peer-fingerprint \<text\>
+
+Configure the peer certificate SHA256 fingerprint for site-to-site mode.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls role \<active | passive\>
+
+**Configure the TLS negotiation role, preferably used in site-to-site mode:**
+* ``active``: Initiates TLS negotiation actively.
+* ``passive``: Waits for incoming TLS connections.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> tls tls-version-min \<1.0 | 1.1 | 1.2 | 1.3 \>
+
+Configure the minimum TLS version to be accepted from the peer.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> use-lzo-compression
+
+Configure fast LZO compression on this TUN/TAP interface.
+```
+```{cfgcmd} set interfaces openvpn \<interface\> vrf \<name\>
+
+Assign the interface to a specific VRF instance.
+```
+
+## Operation mode
+
+```{opcmd} show openvpn site-to-site
+
+Show tunnel status for OpenVPN site-to-site interfaces.
+```
+```{opcmd} show openvpn server
+
+Show tunnel status for OpenVPN server interfaces.
+```
+```{opcmd} show openvpn client
+
+Show tunnel status for OpenVPN client interfaces.
+```
+```{opcmd} show log openvpn
+
+Show logs for all OpenVPN interfaces.
+```
+```{opcmd} show log openvpn interface \<interface\>
+
+Show logs for the specific OpenVPN interface.
+```
+```{opcmd} reset openvpn client \<text\>
+
+Reset the specified OpenVPN client.
+```
+```{opcmd} reset openvpn interface \<interface\>
+
+Reset the OpenVPN process on the specified interface.
+```
+```{opcmd} generate openvpn client-config interface \<interface\> ca \<name\> certificate \<name\>
+
+Generate an OpenVPN client configuration file in the .ovpn format for client machines.
+```
+
+## Examples
+
+This section covers examples of OpenVPN configurations for various deployments.
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+openvpn-examples
+```
+
diff --git a/docs/configuration/interfaces/pppoe.md b/docs/configuration/interfaces/pppoe.md
new file mode 100644
index 00000000..b79f41a2
--- /dev/null
+++ b/docs/configuration/interfaces/pppoe.md
@@ -0,0 +1,419 @@
+---
+lastproofread: '2026-03-03'
+---
+
+(pppoe-interface)=
+
+# PPPoE
+
+{abbr}`PPPoE (Point-to-Point Protocol over Ethernet)` is a network protocol
+that encapsulates PPP frames within Ethernet frames.
+It's often used for connecting ISP clients to a broadband access server.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: pppoe
+:var1: pppoe0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: pppoe
+:var1: pppoe0
+```
+
+```{cmdincludemd} /_include/interface-mtu.txt
+:var0: pppoe
+:var1: pppoe0
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: pppoe
+:var1: pppoe0
+```
+
+
+### PPPoE options
+
+```{cfgcmd} set interfaces pppoe \<interface\> access-concentrator \<name\>
+
+**Configure the name of the target access concentrator for the PPPoE session.**
+
+During the PPPoE discovery process, the client sends a PPPoE initiation packet.
+Multiple access concentrators may respond with offer packets, and the client
+selects one of them.
+
+This setting restricts the client to establishing sessions only with the
+specified access concentrator.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> authentication username \<username\>
+
+**Configure the username for PPPoE session authentication.**
+
+Although authentication is optional in the interface configuration, most ISPs
+require it to establish a connection.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> authentication password \<password\>
+
+**Configure the password for PPPoE session authentication.**
+
+Although authentication is optional in the interface configuration, most ISPs
+require it to establish a connection.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> connect-on-demand
+
+**Enable dial-on-demand on the PPPoE interface.**
+
+When enabled, the system establishes a PPPoE connection only when traffic
+passes through the interface. If the connection fails, it is reestablished when
+traffic resumes.
+
+For on-demand connections, you must also configure an ``idle-timeout`` period
+to disconnect the session after inactivity.
+
+:::{note}
+Setting the idle timeout to zero, or leaving it unconfigured, keeps
+the connection active continuously once established.
+:::
+
+By default, the PPPoE connection is established at boot and remains active
+continuously; if the connection fails, it is reestablished immediately.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> no-default-route
+
+Request an IP address from the PPPoE server without installing a default route.
+
+Example:
+
+:::{code-block} none
+set interfaces pppoe pppoe0 no-default-route
+:::
+
+:::{note}
+Introduced in VyOS 1.4, this command inverts the logic of the former
+``default-route`` CLI option.
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> default-route-distance \<distance\>
+
+Configure the distance for the default gateway provided by the PPPoE server.
+
+Example:
+
+:::{code-block} none
+set interfaces pppoe pppoe0 default-route-distance 220
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> mru \<mru\>
+
+**Configure the** {abbr}`MRU (Maximum Receive Unit)` **for the PPPoE
+interface.**
+
+This setting instructs the pppd daemon to restrict the remote peer from sending
+packets larger than the configured MRU. Allowed MRU values range from 128 to
+16384 bytes.
+
+An MRU of 296 is suitable for very slow links (40 bytes for the TCP/IP header
+and 256 bytes for data).
+
+The default MRU is 1492 bytes.
+
+:::{note}
+When using the IPv6 protocol, the MRU must be at least 1280 bytes.
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> idle-timeout \<time\>
+
+**Configure the idle timeout for on-demand PPPoE sessions.**
+
+This setting defines how long the connection remains active without any traffic
+before being disconnected.
+
+:::{note}
+Setting the idle timeout to zero, or leaving it unconfigured, keeps
+the connection active continuously once established.
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> holdoff \<time\>
+
+**Configure the redial delay for persistent PPPoE sessions.**
+
+If a persistent session (with ``connect-on-demand`` disabled) is terminated by
+the remote peer or drops unexpectedly, the router waits the specified interval
+before attempting to reconnect.
+
+The default redial delay is 30 seconds.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> local-address \<address\>
+
+**Configure the local endpoint IP address for PPPoE sessions.**
+
+By default, this IP address is negotiated.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> no-peer-dns
+
+Disable the installation of advertised DNS nameservers on the local system.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> remote-address \<address\>
+
+**Configure the remote endpoint IP address for PPPoE sessions.**
+
+By default, this IP address is negotiated.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> service-name \<name\>
+
+**Configure the service name of the target access concentrator for the PPPoE
+session.**
+
+By default, the PPPoE interface connects to any available access concentrator.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> source-interface \<source-interface\>
+
+**Configure the underlying interface for the PPPoE connection.**
+
+Each PPPoE connection is established over an underlying interface, which can be
+an Ethernet interface, a VIF, or a bonding interface.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> ip adjust-mss \<mss | clamp-mss-to-pmtu\>
+
+**Configure the** {abbr}`MSS (Maximum Segment Size)` **advertised in outgoing
+TCP SYN packets on the specified interface.**
+
+By clamping the MSS value in TCP SYN packets, you instruct the remote side not
+to send packets larger than the specified size. This helps prevent connection
+issues if {abbr}`PMTUD (Path MTU Discovery)` fails.
+
+The following options are available:
+
+* ``mss``: Sets the MSS to a specific value in bytes.
+* ``clamp-mss-to-pmtu``: Sets the MSS to the interface’s MTU minus 40 bytes for
+ IPv4 traffic (20 bytes for the IPv4 header and 20 bytes for the TCP header).
+ This option is recommended to automatically set the proper value.
+
+:::{note}
+Introduced in VyOS 1.4, this command replaces the older ``set firewall
+options interface <name> adjust-mss <value>`` syntax.
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> ip disable-forwarding
+
+**Configure the interface for host or router behavior.**
+
+If configured, the interface switches to host mode, and IPv4 forwarding is
+disabled on it.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> ip source-validation \<strict | loose | disable\>
+
+**Configure source IP address validation using**
+{abbr}`RPF (Reverse Path Forwarding)` **on this interface, as specified in**
+{rfc}`3704`.
+
+The following options are available:
+
+* ``strict``: Each incoming packet’s source IP address is checked against the
+ {abbr}`FIB (Forwarding Information Base)`. If the interface is not the best
+ route back to that source, validation fails, and the packet is dropped.
+* ``loose``: Each incoming packet’s source IP address is checked against the
+ {abbr}`FIB (Forwarding Information Base)`. If the source IP address is
+ unreachable through any interface, validation fails.
+* ``disable``: No source IP address validation is performed. All incoming
+ packets are accepted.
+
+{rfc}`3704` recommends enabling ``strict`` mode to prevent IP spoofing, such as
+DDoS attacks. For asymmetric or other complex routing scenarios, use ``loose``
+mode.
+```
+
+
+#### IPv6
+
+```{cfgcmd} set interfaces pppoe \<interface\> ipv6 address autoconf
+
+Enable IPv6 address assignment via {abbr}`SLAAC (Stateless Address
+Auto-Configuration)` on this interface.
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> ipv6 adjust-mss \<mss | clamp-mss-to-pmtu\>
+
+**Configure the** {abbr}`MSS (Maximum Segment Size)` **advertised in outgoing
+TCP SYN packets on the specified interface.**
+
+By clamping the MSS value in TCP SYN packets, you instruct the remote side not
+to send packets larger than the specified size. This helps prevent connection
+issues if {abbr}`PMTUD (Path MTU Discovery)` fails.
+
+The following options are available:
+
+* ``mss``: Sets the MSS to a specific value in bytes.
+* ``clamp-mss-to-pmtu``: Sets the MSS to the interface’s MTU minus 60 bytes for
+ IPv6 traffic (40 bytes for the IPv6 header and 20 bytes for the TCP header).
+ This option is recommended to automatically set the proper value.
+
+:::{note}
+Introduced in VyOS 1.4, this command replaces the older ``set firewall
+options interface <name> adjust-mss <value>`` syntax.
+:::
+```
+
+```{cfgcmd} set interfaces pppoe \<interface\> ipv6 disable-forwarding
+
+**Configure the interface for host or router behavior.**
+
+If configured, the interface switches to host mode, and IPv6 forwarding is
+disabled on it.
+```
+
+```{cmdincludemd} /_include/interface-dhcpv6-prefix-delegation.txt
+:var0: pppoe
+:var1: pppoe0
+```
+
+
+## Operation
+
+```{opcmd} show interfaces pppoe \<interface\>
+
+Show detailed information about a specific PPPoE interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces pppoe pppoe0
+pppoe0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc pfifo_fast state UNKNOWN group default qlen 3
+ link/ppp
+ inet 192.0.2.1 peer 192.0.2.255/32 scope global pppoe0
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 7002658233 5064967 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 533822843 1620173 0 0 0 0
+:::
+```
+
+```{opcmd} show interfaces pppoe \<interface\> queue
+
+Show queue information for a specific PPPoE interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces pppoe pppoe0 queue
+qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
+ Sent 534625359 bytes 1626761 pkt (dropped 62, overlimits 0 requeues 0)
+ backlog 0b 0p requeues 0
+:::
+```
+
+
+### Connect/disconnect
+
+```{opcmd} disconnect interface \<interface\>
+
+Disconnect the specified interface.
+```
+
+```{opcmd} connect interface \<interface\>
+
+Initiate a session on the specified interface.
+```
+
+
+## Example
+
+### PPPoE over DSL
+
+**Configuration scenario:**
+
+- Your ISP's DSL modem is connected to the `eth0` interface on your VyOS
+ router.
+- Your ISP does not require VLAN tagging.
+- PPPoE credentials are provided by your ISP. The typical username format is
+ `name@host.net`, though this may vary.
+
+**Configuration notes:**
+
+- The maximum MTU size for DSL is 1492 because of PPPoE overhead. If you are
+ switching from a DHCP-based ISP (e.g., a standard cable connection), ensure
+ VPN links have MTU sizes adjusted accordingly.
+- To ignore ISP-provided nameservers and use only your statically configured
+ ones, set the `name-server` option to `none`.
+- A default route is automatically installed once the interface is up. To
+ change this behavior, use the `no-default-route` CLI option.
+
+:::{note}
+The PPPoE configuration syntax changed after VyOS 1.2 (Crux) and is
+automatically migrated during an upgrade.
+:::
+
+```none
+set interfaces pppoe pppoe0 authentication username 'userid'
+set interfaces pppoe pppoe0 authentication password 'secret'
+set interfaces pppoe pppoe0 source-interface 'eth0'
+```
+
+Secure your setup by creating rules matching the `pppoe0` interface in the
+firewall chains:
+
+```none
+set firewall ipv4 input filter rule 10 inbound-interface name 'pppoe0'
+set firewall ipv4 forward filter rule 10 inbound-interface name 'pppoe0'
+```
+
+
+### PPPoE over VLAN
+
+Some ISPs require PPPoE connections to be
+established over a VLAN interface. This specific topology is fully supported by
+VyOS.
+
+The following configuration establishes the PPPoE connection through VLAN 7,
+which is the default VLAN for Deutsche Telekom:
+
+```none
+set interfaces pppoe pppoe0 authentication username 'userid'
+set interfaces pppoe pppoe0 authentication password 'secret'
+set interfaces pppoe pppoe0 source-interface 'eth0.7'
+```
+
+
+#### IPv6 DHCPv6 prefix delegation
+
+**Configuration scenario:**
+
+The following configuration establishes a PPPoE session on the `eth1`
+interface, requests a `/56` IPv6 prefix delegation from the ISP, and assigns
+a `/64` subnet from that delegation to the `eth0` interface.
+
+**Configuration notes:**
+
+- The IPv6 address assigned to `eth0` is `<prefix>::1/64`.
+- If you do not know your delegated prefix size, begin with `sla-len 0`.
+- To advertise the prefix on the `eth0` link, configure IPv6 Router
+ Advertisement.
+
+```none
+set interfaces pppoe pppoe0 authentication username vyos
+set interfaces pppoe pppoe0 authentication password vyos
+set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth0 address '1'
+set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth0 sla-id '0'
+set interfaces pppoe pppoe0 dhcpv6-options pd 0 length '56'
+set interfaces pppoe pppoe0 ipv6 address autoconf
+set interfaces pppoe pppoe0 source-interface eth1
+
+set service router-advert interface eth0 prefix ::/64
+```
diff --git a/docs/configuration/interfaces/pseudo-ethernet.md b/docs/configuration/interfaces/pseudo-ethernet.md
new file mode 100644
index 00000000..fc8833eb
--- /dev/null
+++ b/docs/configuration/interfaces/pseudo-ethernet.md
@@ -0,0 +1,52 @@
+---
+lastproofread: '2026-03-05'
+---
+
+(pseudo-ethernet-interface)=
+
+# MACVLAN (pseudo-Ethernet)
+
+MACVLAN, or pseudo-Ethernet interfaces, operate as logical subinterfaces of
+standard Ethernet interfaces. Each subinterface has a unique MAC address but
+shares a single physical Ethernet port.
+That allows the user to send packets from different source IPv4 or IPv6 addresses
+using a different MAC address.
+
+Pseudo-Ethernet interfaces behave like physical Ethernet interfaces. They
+support IPv4 and IPv6 addressing, can obtain IP addresses through DHCP or
+DHCPv6, and are mapped to a physical Ethernet port. They inherit
+characteristics such as speed and duplex from their parent interface and can
+be referenced like standard Ethernet interfaces once created.
+
+```{eval-rst}
+Pseudo-Ethernet interfaces may not work in environments that require a
+ :abbr:`NIC (Network Interface Card)` to have only one MAC address.
+ This includes:
+
+ * VMware machines with default settings.
+ * Network switches that permit only a single MAC address.
+ * xDSL modems that learn the NIC's MAC address.
+```
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: pseudo-ethernet
+:var1: peth0
+```
+
+### MACVLAN (pseudo-Ethernet) options
+
+```{cfgcmd} set interfaces pseudo-ethernet \<interface\> source-interface \<ethX\>
+
+Assign a physical Ethernet interface to the specified pseudo-Ethernet interface.
+```
+
+### VLAN
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: pseudo-ethernet
+:var1: peth0
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/sstp-client.md b/docs/configuration/interfaces/sstp-client.md
new file mode 100644
index 00000000..da98aecd
--- /dev/null
+++ b/docs/configuration/interfaces/sstp-client.md
@@ -0,0 +1,170 @@
+---
+lastproofread: '2026-03-16'
+---
+
+(sstp-client-interface)=
+
+# SSTP client
+
+{abbr}`SSTP (Secure Socket Tunneling Protocol)` transports PPP traffic over an
+SSL/TLS channel, providing transport-level security through key negotiation,
+encryption, and traffic integrity checking. The use of SSL/TLS over TCP port
+443 (by default, the port can be changed) allows SSTP to pass through virtually
+all firewalls and proxy servers, except for authenticated web proxies.
+
+:::{note}
+VyOS includes a built-in SSTP server. For more information, see
+{ref}`sstp`.
+:::
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: sstpc
+:var1: sstpc0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: sstpc
+:var1: sstpc0
+```
+
+```{cmdincludemd} /_include/interface-mtu.txt
+:var0: sstpc
+:var1: sstpc0
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: sstpc
+:var1: sstpc0
+```
+
+
+### SSTP client options
+
+```{cfgcmd} set interfaces sstpc \<interface\> no-default-route
+
+Request an IP address from the SSTP server without installing a default route.
+
+Example:
+
+:::{code-block} none
+set interfaces sstpc sstpc0 no-default-route
+:::
+:::{note} Introduced in VyOS 1.4, this command inverts the logic of the former
+``default-route`` CLI option.
+:::
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> default-route-distance \<distance\>
+
+Configure the distance for the default gateway provided by the SSTP server.
+
+Example:
+
+:::{code-block} none
+set interfaces sstpc sstpc0 default-route-distance 220
+:::
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> no-peer-dns
+
+Disable the installation of advertised DNS nameservers on the local system.
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> server \<address\>
+
+**Configure the remote SSTP server address for the client connection.**
+
+The address can be either an IP address or a {abbr}`FQDN (Fully Qualified
+Domain Name)`.
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> ip adjust-mss \<mss | clamp-mss-to-pmtu\>
+
+**Configure the** {abbr}`MSS (Maximum Segment Size)` **advertised in outgoing
+TCP SYN packets on the specified interface.**
+
+By clamping the MSS value in TCP SYN packets, you instruct the remote side not
+to send packets larger than the specified size. This helps prevent connection
+issues if {abbr}`PMTUD (Path MTU Discovery)` fails.
+
+The following options are available:
+
+* ``mss``: Sets the MSS to a specific value in bytes.
+* ``clamp-mss-to-pmtu``: Sets the MSS to the interface’s MTU minus 40 bytes for
+IPv4 traffic (20 bytes for the IPv4 header and 20 bytes for the TCP header).
+This option is recommended to automatically set the proper value.
+
+:::{note} Introduced in VyOS 1.4, this command replaces the older ``set firewall
+options interface <name> adjust-mss <value>`` syntax.
+:::
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> ip disable-forwarding
+
+**Configure the interface for host or router behavior.**
+
+If configured, the interface switches to host mode, and IPv4 forwarding is
+disabled on it.
+```
+
+```{cfgcmd} set interfaces sstpc \<interface\> ip source-validation \<strict | loose | disable\>
+
+**Configure source IP address validation using**
+{abbr}`RPF (Reverse Path Forwarding)` **on this interface, as specified in**
+{rfc}`3704`.
+
+The following options are available:
+
+* ``strict``: Each incoming packet’s source IP address is checked against the
+{abbr}`FIB (Forwarding Information Base)`. If the interface is not the best
+route back to that source, validation fails, and the packet is dropped.
+* ``loose``: Each incoming packet’s source IP address is checked against the
+{abbr}`FIB (Forwarding Information Base)`. If the source IP address is
+unreachable through any interface, validation fails.
+* ``disable``: No source IP address validation is performed. All incoming
+packets are accepted.
+
+{rfc}`3704` recommends enabling ``strict`` mode to prevent IP spoofing, such as
+DDoS attacks. For asymmetric or other complex routing scenarios, use ``loose``
+mode.
+```
+
+
+## Operation
+
+```{opcmd} show interfaces sstpc \<interface\>
+
+Show detailed information about the specified interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces sstpc sstpc10
+sstpc10: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 3
+ link/ppp
+ inet 192.0.2.5 peer 192.0.2.254/32 scope global sstpc10
+ valid_lft forever preferred_lft forever
+ inet6 fe80::fd53:c7ff:fe8b:144f/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 215 9 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 539 14 0 0 0 0
+:::
+```
+
+
+### Connect/disconnect
+
+```{opcmd} disconnect interface \<interface\>
+
+Disconnect the specified interface.
+```
+
+```{opcmd} connect interface \<interface\>
+
+Initiate a session on the specified interface.
+``` \ No newline at end of file
diff --git a/docs/configuration/interfaces/tunnel.md b/docs/configuration/interfaces/tunnel.md
new file mode 100644
index 00000000..9c9885d2
--- /dev/null
+++ b/docs/configuration/interfaces/tunnel.md
@@ -0,0 +1,309 @@
+---
+lastproofread: '2026-01-23'
+---
+
+(tunnel-interface)=
+
+# Tunnel
+
+Tunnel interfaces are virtual links that transmit encapsulated traffic between
+private networks or hosts across public infrastructure, such as the Internet.
+They operate using encapsulation protocols to wrap original traffic for
+transport. The supported protocols include {abbr}`GRE (Generic Routing
+Encapsulation)`, IPIP, IPIP6, IP6IP6, and 6in4 (SIT).
+
+While {abbr}`GRE (Generic Routing Encapsulation)` is often the preferred
+one-size-fits-all solution due to its versatility, other encapsulation
+protocols may be better suited for specific use cases.
+
+VyOS uses a single tunnel interface type for all of these protocols. There are
+no separate {abbr}`GRE (Generic Routing Encapsulation)`, IPIP, or IP6IP6
+interface types; instead, the desired encapsulation protocol is selected within
+the `set interfaces tunnel` configuration.
+
+Configuration options for each protocol are described below.
+
+:::{warning}
+Do not change the encapsulation type for already configured tunnel
+interfaces, as this may break their dependent configurations.
+:::
+
+## Common interface configuration
+
+```{cmdincludemd} /_include/interface-address.txt
+:var0: tunnel
+:var1: tun0
+```
+
+```{cmdincludemd} /_include/interface-common-without-mac.txt
+:var0: tunnel
+:var1: tun0
+```
+
+
+## IPIP
+
+IPIP is a straightforward encapsulation protocol defined in RFC 2003. It
+encapsulates one IPv4 packet inside another IPv4 packet.
+
+Tunnels with IPIP encapsulation do not have protocol-specific configuration
+options except for explicitly defining the encapsulation type as IPIP (see
+the example below).
+
+Example:
+
+```none
+set interfaces tunnel tun0 encapsulation ipip
+set interfaces tunnel tun0 source-address 192.0.2.10
+set interfaces tunnel tun0 remote 203.0.113.20
+set interfaces tunnel tun0 address 192.168.100.200/24
+```
+
+
+## IP6IP6
+
+IP6IP6 is the IPv6 counterpart to IPIP. It encapsulates one IPv6 packet inside
+another IPv6 packet.
+
+Similar to their IPIP counterparts, tunnels with IP6IP6 encapsulation do not
+have protocol-specific configuration options except for explicitly defining
+the encapsulation type as IP6IP6.
+
+Example:
+
+```none
+set interfaces tunnel tun0 encapsulation ip6ip6
+set interfaces tunnel tun0 source-address 2001:db8:aa::1
+set interfaces tunnel tun0 remote 2001:db8:aa::2
+set interfaces tunnel tun0 address 2001:db8:bb::1/64
+```
+
+
+## IPIP6
+
+IPIP6 is an encapsulation protocol that wraps IPv4 packets inside IPv6 packets.
+
+Similar to IPIP and IP6IP6, protocol-specific configuration for tunnels with
+IPIP6 encapsulation only requires defining the encapsulation type as IP6IP6.
+
+Example:
+
+```none
+set interfaces tunnel tun0 encapsulation ipip6
+set interfaces tunnel tun0 source-address 2001:db8:aa::1
+set interfaces tunnel tun0 remote 2001:db8:aa::2
+set interfaces tunnel tun0 address 192.168.70.80/24
+```
+
+
+## 6in4 (SIT)
+
+6in4, also known as {abbr}`SIT (Simple Internet Transition)`, is an
+encapsulation protocol defined in {rfc}`4213` that wraps IPv6 packets
+inside IPv4 packets. The encapsulating IPv4 headers use IP protocol number 41,
+which is reserved exclusively for IPv6 encapsulation.
+
+The encapsulation process adds a 20-byte IPv4 header to each IPv6 packet.
+Consequently, 6in4 tunnel interfaces can transmit IPv6 packets up to 1480 bytes
+over an underlying network with a standard MTU of 1500 bytes without
+fragmentation.
+
+6in4 tunnel interfaces are frequently used by IPv6 tunnel brokers (such as
+[Hurricane Electric]) to connect isolated IPv6 networks or individual hosts to
+the IPv6 internet.
+
+Example:
+
+```none
+set interfaces tunnel tun0 encapsulation sit
+set interfaces tunnel tun0 source-address 192.0.2.10
+set interfaces tunnel tun0 remote 192.0.2.20
+set interfaces tunnel tun0 address 2001:db8:bb::1/64
+```
+
+:::{seealso}
+For a practical configuration example, see the
+{ref}`Tunnelbroker.net (IPv6) <examples-tunnelbroker-ipv6>` section.
+:::
+
+## Generic Routing Encapsulation (GRE)
+
+{abbr}`GRE (Generic Routing Encapsulation)` is a versatile encapsulation
+protocol defined in RFC 2784. Unlike simpler protocols such as IPIP, it allows
+both IPv4 and IPv6 to be transported through the same tunnel.
+
+{abbr}`GRE (Generic Routing Encapsulation)` encapsulates original data packets
+by adding a {abbr}`GRE (Generic Routing Encapsulation)` header, followed by an
+IP header (the delivery header). The delivery header uses IP protocol number 47
+to identify {abbr}`GRE (Generic Routing Encapsulation)`-encapsulated traffic.
+
+In VyOS, {abbr}`GRE (Generic Routing Encapsulation)` tunnels can be established
+over both IPv4 (encapsulation `gre`) and IPv6 (encapsulation `ip6gre`)
+transport networks.
+
+### Configuration
+
+To configure a {abbr}`GRE (Generic Routing Encapsulation)` tunnel, you need to
+define a tunnel source IP address, a tunnel destination IP address, an
+encapsulation type ({abbr}`GRE (Generic Routing Encapsulation)`), and a tunnel
+interface IP address.
+
+Example:
+
+The following example shows how to configure an IPv4/IPv6-over-IPv6 {abbr}`GRE
+(Generic Routing Encapsulation)` tunnel between a VyOS router and a Linux host
+running `systemd-networkd`.
+
+**VyOS router:**
+
+```none
+set interfaces tunnel tun101 address '2001:db8:feed:beef::1/126'
+set interfaces tunnel tun101 address '192.168.5.1/30'
+set interfaces tunnel tun101 encapsulation 'ip6gre'
+set interfaces tunnel tun101 source-address '2001:db8:babe:face::3afe:3'
+set interfaces tunnel tun101 remote '2001:db8:9bb:3ce::5'
+```
+
+**Linux** `systemd-networkd`:
+
+The `systemd-networkd` setup requires two configuration files: `xxx.netdev`
+to create the {abbr}`GRE (Generic Routing Encapsulation)` tunnel interface, and
+`xxx.network` to assign IP addresses to it.
+
+```none
+# cat /etc/systemd/network/gre-example.netdev
+[NetDev]
+Name=gre-example
+Kind=ip6gre
+MTUBytes=14180
+
+[Tunnel]
+Remote=2001:db8:babe:face::3afe:3
+
+
+# cat /etc/systemd/network/gre-example.network
+[Match]
+Name=gre-example
+
+[Network]
+Address=2001:db8:feed:beef::2/126
+
+[Address]
+Address=192.168.5.2/30
+```
+
+
+### GRE keys
+
+A GRE key is an optional 32-bit field in the GRE header that allows multiple
+GRE tunnels to operate between the same source and destination endpoints. When
+a packet arrives, the receiver checks the GRE key to determine which tunnel
+interface should process it.
+
+Although it may sound security-related, the GRE key is only an identifier and
+provides no encryption or data protection.
+
+Example:
+
+```none
+set interfaces tunnel tun0 source-address 192.0.2.10
+set interfaces tunnel tun0 remote 192.0.2.20
+set interfaces tunnel tun0 address 10.40.50.60/24
+set interfaces tunnel tun0 parameters ip key 10
+```
+
+```none
+set interfaces tunnel tun1 source-address 192.0.2.10
+set interfaces tunnel tun1 remote 192.0.2.20
+set interfaces tunnel tun1 address 172.16.17.18/24
+set interfaces tunnel tun1 parameters ip key 20
+```
+
+
+### GRETAP
+
+Unlike GRE, which encapsulates only Layer 3 (IP) traffic, GRETAP encapsulates
+Layer 2 (Ethernet) frames.
+
+That means that GRETAP tunnel interfaces can be members of a bridge interface.
+This allows two geographically distant sites to connect as if they were on the
+same LAN.
+
+GRETAP tunnels can be established over both IPv4 and IPv6 transport networks.
+
+Example:
+
+```none
+set interfaces bridge br0 member interface eth0
+set interfaces bridge br0 member interface tun0
+set interfaces tunnel tun0 encapsulation gretap
+set interfaces tunnel tun0 source-address 198.51.100.2
+set interfaces tunnel tun0 remote 203.0.113.10
+```
+
+
+### Troubleshooting
+
+GRE is a standardized tunneling protocol used in many network environments.
+
+Although the GRE tunnel setup is straightforward, connectivity failures
+frequently occur because ACLs or firewall rules block IP protocol 47 or
+prevent direct communication between the tunnel endpoints.
+
+If your GRE tunnel fails to establish, perform these diagnostic steps:
+
+1\. Verify that the remote peer is reachable from the configured
+`source-address`.
+
+This ensures that the underlying physical path between the two endpoints is
+functional.
+
+```none
+vyos@vyos:~$ ping 203.0.113.10 interface 198.51.100.2 count 4
+PING 203.0.113.10 (203.0.113.10) from 198.51.100.2 : 56(84) bytes of data.
+64 bytes from 203.0.113.10: icmp_seq=1 ttl=254 time=0.807 ms
+64 bytes from 203.0.113.10: icmp_seq=2 ttl=254 time=1.50 ms
+64 bytes from 203.0.113.10: icmp_seq=3 ttl=254 time=0.624 ms
+64 bytes from 203.0.113.10: icmp_seq=4 ttl=254 time=1.41 ms
+
+--- 203.0.113.10 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3007ms
+rtt min/avg/max/mdev = 0.624/1.087/1.509/0.381 ms
+```
+
+2\. Verify that the tunnel interface is correctly configured (with the link type
+set to GRE) and is actively processing traffic.
+
+```none
+vyos@vyos:~$ show interfaces tunnel tun100
+tun100@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1476 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/gre 198.51.100.2 peer 203.0.113.10
+ inet 10.0.0.1/30 brd 10.0.0.3 scope global tun100
+ valid_lft forever preferred_lft forever
+ inet6 fe80::5efe:c612:2/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 2183 27 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 836 9 0 0 0 0
+```
+
+3\. Test the connection through the tunnel using the private IP addresses
+assigned to each tunnel endpoint.
+
+```none
+vyos@vyos:~$ ping 10.0.0.2 interface 10.0.0.1 count 4
+PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
+64 bytes from 10.0.0.2: icmp_seq=1 ttl=255 time=1.05 ms
+64 bytes from 10.0.0.2: icmp_seq=2 ttl=255 time=1.88 ms
+64 bytes from 10.0.0.2: icmp_seq=3 ttl=255 time=1.98 ms
+64 bytes from 10.0.0.2: icmp_seq=4 ttl=255 time=1.98 ms
+
+--- 10.0.0.2 ping statistics ---
+4 packets transmitted, 4 received, 0% packet loss, time 3008ms
+rtt min/avg/max/mdev = 1.055/1.729/1.989/0.395 ms
+```
+
+[hurricane electric]: https://tunnelbroker.net/
+[other proposals]: https://www.isc.org/othersoftware/
diff --git a/docs/configuration/interfaces/virtual-ethernet.md b/docs/configuration/interfaces/virtual-ethernet.md
new file mode 100644
index 00000000..dee1b332
--- /dev/null
+++ b/docs/configuration/interfaces/virtual-ethernet.md
@@ -0,0 +1,119 @@
+---
+lastproofread: '2026-01-26'
+---
+
+(virtual-ethernet)=
+
+# Virtual Ethernet
+
+Virtual Ethernet (veth) interfaces are software-based interfaces that operate
+in pairs, creating a tunnel between each other. Traffic transmitted into one
+interface of the pair (e.g., `veth0`) is delivered directly to its peer
+interface (e.g., `veth1`).
+
+Veth interfaces are commonly used to connect network namespaces or VRFs, but
+they can also function as standalone virtual network interfaces.
+
+:::{note}
+Veth interfaces must be created in pairs, where each interface acts
+as the peer of the other.
+:::
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address-with-dhcp.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+
+### VLAN
+
+#### Regular VLANs (802.1q)
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+
+#### 802.1ad (QinQ)
+
+```{cmdincludemd} /_include/interface-vlan-8021ad.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: virtual-ethernet
+:var1: veth0
+```
+
+
+## Operation
+
+```{opcmd} show interfaces virtual-ethernet
+
+Show brief interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces virtual-ethernet
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+veth10 100.64.0.0/31 u/u
+veth11 100.64.0.1/31 u/u
+:::
+```
+
+```{opcmd} show interfaces virtual-ethernet \<interface\>
+
+Show detailed interface information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces virtual-ethernet veth11
+10: veth11@veth10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master red state UP group default qlen 1000
+link/ether b2:7b:df:47:e9:11 brd ff:ff:ff:ff:ff:ff
+inet 100.64.0.1/31 scope global veth11
+valid_lft forever preferred_lft forever
+inet6 fe80::b07b:dfff:fe47:e911/64 scope link
+valid_lft forever preferred_lft forever
+
+RX: bytes packets errors dropped overrun mcast
+0 0 0 0 0 0
+TX: bytes packets errors dropped carrier collisions
+1369707 4267 0 0 0 0
+:::
+```
+
+
+## Example
+
+The following example shows how to connect the global VRF to VRF ‘red ‘ using
+the `veth10` and `veth11` veth pair.
+
+```none
+set interfaces virtual-ethernet veth10 address '100.64.0.0/31'
+set interfaces virtual-ethernet veth10 peer-name 'veth11'
+set interfaces virtual-ethernet veth11 address '100.64.0.1/31'
+set interfaces virtual-ethernet veth11 peer-name 'veth10'
+set interfaces virtual-ethernet veth11 vrf 'red'
+set vrf name red table '1000'
+
+vyos@vyos:~$ ping 100.64.0.1
+PING 100.64.0.1 (100.64.0.1) 56(84) bytes of data.
+64 bytes from 100.64.0.1: icmp_seq=1 ttl=64 time=0.080 ms
+64 bytes from 100.64.0.1: icmp_seq=2 ttl=64 time=0.119 ms
+```
diff --git a/docs/configuration/interfaces/vti.md b/docs/configuration/interfaces/vti.md
new file mode 100644
index 00000000..dbd2c88c
--- /dev/null
+++ b/docs/configuration/interfaces/vti.md
@@ -0,0 +1,121 @@
+(vti-interface)=
+
+# VTI (virtual tunnel interface)
+
+{abbr}`VTIs (virtual tunnel interfaces)` let you create secure, encrypted
+tunnels between private networks or hosts across public infrastructure, such as
+the Internet. They operate alongside an underlying IPsec tunnel, which handles
+encapsulation and encryption, while VTIs function exclusively as routing
+interfaces.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cmdincludemd} /_include/interface-ip.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cmdincludemd} /_include/interface-ipv6.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cmdincludemd} /_include/interface-mtu.txt
+:var0: vti
+:var1: vti0
+```
+
+```{cfgcmd} set interfaces vti \<interface\> mirror egress \<monitor-interface\>
+
+Configure mirroring of outgoing traffic from the specified VTI to the
+designated monitor interface.
+```
+
+```{cfgcmd} set interfaces vti \<interface\> mirror ingress \<monitor-interface\>
+
+Configure mirroring of incoming traffic from the specified VTI to the
+designated monitor interface.
+```
+
+```{cfgcmd} set interfaces vti \<interface\> redirect \<interface\>
+
+Enable redirection of incoming packets to the specified interface.
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: vti
+:var1: vti0
+```
+
+
+## Operation
+
+```{opcmd} show interfaces vti \<vtiX\>
+
+Show the operational status and traffic statistics for the specified VTI.
+```
+
+```{opcmd} show interfaces vti \<vtiX\> brief
+
+Show a brief operational status summary for the specified VTI.
+```
+
+
+## Example
+
+**Configure a VTI**
+
+Assign IPv4 and IPv6 addresses to the VTI, along with a brief description:
+
+```none
+set interfaces vti vti0 address 192.168.2.249/30
+set interfaces vti vti0 address 2001:db8:2::249/64
+set interfaces vti vti0 description "Description"
+```
+
+Resulting configuration:
+
+```none
+vyos@vyos# show interfaces vti
+vti vti0 {
+ address 192.168.2.249/30
+ address 2001:db8:2::249/64
+ description "Description"
+}
+```
+
+:::{warning}
+When configuring site-to-site IPsec with VTIs, ensure that route
+autoinstall is disabled.
+:::
+
+```none
+set vpn ipsec options disable-route-autoinstall
+```
+
+For more information about the IPsec and VTI issue, as well as the
+`disable-route-autoinstall` option, see:
+<https://blog.vyos.io/vyos-1-dot-2-0-development-news-in-july.>
+
+The root cause of the problem is that VTI tunnels require their traffic
+selectors to be set to `0.0.0.0/0` for traffic to match the tunnel, even
+though routing decisions are based on netfilter marks. Unless route insertion
+is explicitly disabled, strongSWAN incorrectly inserts a default route through
+the VTI peer address, causing all traffic to be misrouted.
diff --git a/docs/configuration/interfaces/vxlan.md b/docs/configuration/interfaces/vxlan.md
new file mode 100644
index 00000000..8dae75ff
--- /dev/null
+++ b/docs/configuration/interfaces/vxlan.md
@@ -0,0 +1,373 @@
+---
+lastproofread: '2026-03-16'
+---
+
+(vxlan-interface)=
+
+# VXLAN
+
+{abbr}`VXLAN (Virtual Extensible LAN)` is a network virtualization technology
+that addresses scalability challenges in large cloud computing environments.
+It encapsulates Ethernet frames (Layer 2) within UDP datagrams (Layer 4), which
+are then transmitted via UDP port 4789, as assigned by IANA. VXLAN endpoints,
+called {abbr}`VTEPs (VXLAN tunnel endpoints)`, terminate VXLAN tunnels and can
+be either virtual or physical switch ports.
+
+VXLAN supports up to 16 million logical networks and enables Layer 2 adjacency
+across Layer 3 IP networks. It uses multicast or unicast with head-end
+replication (HER) to flood broadcast, unknown unicast, and multicast (BUM)
+traffic.
+
+The VXLAN specification was initially developed by VMware, Arista Networks, and
+Cisco. Other supporters include Huawei, Broadcom, Citrix, Pica8, Big Switch
+Networks, Cumulus Networks, Dell EMC, Ericsson, Mellanox, FreeBSD, OpenBSD, Red
+Hat, Joyent, and Juniper Networks.
+
+VXLAN is officially documented by the IETF in {rfc}`7348`.
+
+When configuring VXLAN in a VyOS virtual machine, ensure that MAC spoofing
+(Hyper-V) or Forged Transmits (ESX) are permitted. Otherwise, the hypervisor
+may block forwarded frames.
+
+:::{note}
+Although the IANA-assigned VXLAN port is **4789**, VyOS uses the
+Linux default UDP port **8472** for VXLAN interfaces. To ensure compatibility
+with other vendors, set the port to the IANA standard **4789**.
+:::
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-without-dhcp.txt
+:var0: vxlan
+:var1: vxlan0
+```
+
+
+### VXLAN-specific options
+
+```{cfgcmd} set interfaces vxlan \<interface\> vni \<number\>
+
+**Configure a** {abbr}`VNI (VXLAN Network Identifier)` **for the VXLAN
+interface.**
+
+Each VXLAN segment is identified by this 24-bit VNI, allowing up to 16 million
+segments to coexist within the same administrative domain.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> port \<port\>
+
+Configure the UDP port of the remote VXLAN endpoint.
+
+:::{note}
+Although the IANA-assigned VXLAN port is **4789**, VyOS uses the
+Linux default UDP port **8472** for VXLAN interfaces.
+:::
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> source-address \<address\>
+
+Configure the source IP address for the VXLAN underlay.
+
+:::{warning}
+This setting is mandatory when deploying VXLAN via L2VPN/EVPN.
+:::
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> gpe
+
+**Enable the** {abbr}`GPE (Generic Protocol Extension)` **for the VXLAN
+interface.**
+
+To use this feature, you must configure the interface with the ``external``
+parameter.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> parameters external
+
+**Configure the VXLAN interface to use an external control plane, such as BGP
+L2VPN/EVPN, for remote endpoint discovery.**
+
+If not configured, the internal {abbr}`FDB (Forwarding Database)` is used.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> parameters neighbor-suppress
+
+**Enable ARP and ND suppression on the VXLAN interface.**
+
+This reduces ARP and ND message flooding across the VXLAN network. As defined
+in {rfc}`7432#section-10`, participating VTEPs use known MAC-to-IP bindings
+to reply to local requests on behalf of remote hosts.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> parameters nolearning
+
+Disable {abbr}`SLLA (Source Link-Layer Address)` and IP address learning on
+the VXLAN interface.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> parameters vni-filter
+
+**Enable** {abbr}`VNI (VXLAN Network Identifier)` **filtering on the VXLAN
+interface.**
+
+When enabled, the interface only receives packets with VNIs configured in its
+VNI filtering table.
+
+:::{note}
+VNI filtering works only if the interface is configured with the
+``external`` parameter.
+:::
+```
+
+
+#### Unicast
+
+```{cfgcmd} set interfaces vxlan \<interface\> remote \<address\>
+
+**Configure the IPv4 or IPv6 address of the remote VTEP.**
+
+Unlike multicast setups, this command allows you to directly configure the
+remote IPv4 or IPv6 address.
+```
+
+
+#### Multicast
+
+```{cfgcmd} set interfaces vxlan \<interface\> source-interface \<interface\>
+
+**Configure the source interface for the VXLAN underlay.**
+
+All VXLAN traffic is sent and received through the specified interface.
+This setting is mandatory when deploying VXLAN over a multicast network.
+```
+
+```{cfgcmd} set interfaces vxlan \<interface\> group \<address\>
+
+**Configure the IPv4 or IPv6 multicast group address for the VXLAN interface.**
+
+VXLAN tunnels can be built using either multicast group or unicast IP addresses.
+```
+
+
+## Multicast VXLAN
+
+Topology: PC4 - Leaf2 - Spine1 - Leaf3 - PC5
+
+PC4 uses the IP address `10.0.0.4/24`, and PC5 uses the IP address
+`10.0.0.5/24`. Both devices assume they reside within the same broadcast
+domain.
+
+Assume PC4 on Leaf2 pings PC5 on Leaf3. Rather than manually specifying Leaf3
+as the remote endpoint, Leaf2 encapsulates the packet into a UDP datagram and
+sends it to the designated multicast address via Spine1. Spine1 forwards the
+packet to all leaves in the same multicast group, including Leaf3. Upon
+receiving the datagram, Leaf3 forwards it to PC5 and learns that PC4 is
+reachable through Leaf2 by inspecting the source IP in the encapsulated
+datagram.
+
+PC5 receives the ping and responds with an echo reply. Leaf3, now aware of
+PC4's location, forwards the reply directly to Leaf2's unicast address. Upon
+receiving the echo reply, Leaf2 learns that PC5 is reachable through Leaf3.
+
+After this discovery, subsequent traffic between PC4 and PC5 will not use the
+multicast address between the leaves, as both leaves have learned the PCs'
+locations. This reduces multicast traffic and network load, improving
+scalability as more leaves are added.
+
+## Single VXLAN device (SVD)
+
+In VyOS, you can configure multiple **VLAN-to-VNI mappings** for EVPN-VXLAN on
+a single container interface, known as a single VXLAN device (SVD). This
+enables significant VNI scaling because a separate VXLAN interface is not
+required for each VNI.
+
+```{cfgcmd} set interfaces vxlan \<interface\> vlan-to-vni \<vlan\> vni \<vni\>
+
+**Map a VLAN ID to a VNI on the specified VXLAN interface.**
+
+The VXLAN interface can be added to a bridge.
+
+The following example shows an SVD configuration with multiple VLAN-to-VNI
+mappings.
+
+:::{code-block} none
+set interfaces bridge br0 member interface vxlan0
+set interfaces vxlan vxlan0 parameters external
+set interfaces vxlan vxlan0 source-interface 'dum0'
+set interfaces vxlan vxlan0 vlan-to-vni 10 vni '10010'
+set interfaces vxlan vxlan0 vlan-to-vni 11 vni '10011'
+set interfaces vxlan vxlan0 vlan-to-vni 30 vni '10030'
+set interfaces vxlan vxlan0 vlan-to-vni 31 vni '10031'
+:::
+```
+
+
+### Example
+
+The following example demonstrates a multicast VXLAN deployment.
+
+The setup includes three routers: Spine1, a Cisco IOS router, and Leaf2 and
+Leaf3, which are VyOS routers.
+
+**Topology:** Leaf2 - Spine1 - Leaf3.
+
+The topology is built using GNS3.
+
+```none
+Spine1:
+fa0/2 towards Leaf2, IP-address: 10.1.2.1/24
+fa0/3 towards Leaf3, IP-address: 10.1.3.1/24
+
+Leaf2:
+Eth0 towards Spine1, IP-address: 10.1.2.2/24
+Eth1 towards a VLAN-aware switch
+
+Leaf3:
+Eth0 towards Spine1, IP-address 10.1.3.3/24
+Eth1 towards a VLAN-aware switch
+```
+
+**Spine1 configuration:**
+
+```none
+conf t
+ip multicast-routing
+!
+interface fastethernet0/2
+ ip address 10.1.2.1 255.255.255.0
+ ip pim sparse-dense-mode
+!
+interface fastethernet0/3
+ ip address 10.1.3.1 255.255.255.0
+ ip pim sparse-dense-mode
+!
+router ospf 1
+ network 10.0.0.0 0.255.255.255 area 0
+```
+
+Multicast routing is required for scalable traffic forwarding between leaves.
+{abbr}`PIM (Protocol Independent Multicast)` must be enabled towards the leaves
+so the spine can learn from which multicast groups each leaf expects traffic.
+
+**Leaf2 configuration:**
+
+```none
+set interfaces ethernet eth0 address '10.1.2.2/24'
+set protocols ospf area 0 network '10.0.0.0/8'
+
+! First VXLAN interface
+set interfaces bridge br241 address '172.16.241.1/24'
+set interfaces bridge br241 member interface 'eth1.241'
+set interfaces bridge br241 member interface 'vxlan241'
+
+set interfaces vxlan vxlan241 group '239.0.0.241'
+set interfaces vxlan vxlan241 source-interface 'eth0'
+set interfaces vxlan vxlan241 vni '241'
+
+! Second VXLAN interface
+set interfaces bridge br242 address '172.16.242.1/24'
+set interfaces bridge br242 member interface 'eth1.242'
+set interfaces bridge br242 member interface 'vxlan242'
+
+set interfaces vxlan vxlan242 group '239.0.0.242'
+set interfaces vxlan vxlan242 source-interface 'eth0'
+set interfaces vxlan vxlan242 vni '242'
+```
+
+**Leaf3 configuration:**
+
+```none
+set interfaces ethernet eth0 address '10.1.3.3/24'
+set protocols ospf area 0 network '10.0.0.0/8'
+
+! First VXLAN interface
+set interfaces bridge br241 address '172.16.241.1/24'
+set interfaces bridge br241 member interface 'eth1.241'
+set interfaces bridge br241 member interface 'vxlan241'
+
+set interfaces vxlan vxlan241 group '239.0.0.241'
+set interfaces vxlan vxlan241 source-interface 'eth0'
+set interfaces vxlan vxlan241 vni '241'
+
+! Second VXLAN interface
+set interfaces bridge br242 address '172.16.242.1/24'
+set interfaces bridge br242 member interface 'eth1.242'
+set interfaces bridge br242 member interface 'vxlan242'
+
+set interfaces vxlan vxlan242 group '239.0.0.242'
+set interfaces vxlan vxlan242 source-interface 'eth0'
+set interfaces vxlan vxlan242 vni '242'
+```
+
+The configurations for Leaf2 and Leaf3 are nearly identical. Detailed
+explanations for each command are provided below.
+
+```none
+set interfaces bridge br241 address '172.16.241.1/24'
+```
+
+This command creates a bridge to bind traffic on `eth1` VLAN 241 with the
+`vxlan241` interface. The IP address is optional. If configured, it can serve
+as the default gateway for each leaf, allowing devices on the VLAN to reach
+other subnets. Subnets must be redistributed by {abbr}`OSPF (Open Shortest Path
+First)` so the spine can learn how to reach them. To advertise `172.16/12`
+networks, change the {abbr}`OSPF (Open Shortest Path First)` network from
+`10.0.0.0/8` to `0.0.0.0/0`.
+
+```none
+set interfaces bridge br241 member interface 'eth1.241'
+set interfaces bridge br241 member interface 'vxlan241'
+```
+
+These commands bind `eth1.241` and `vxlan241` as member interfaces of the
+same bridge.
+
+```none
+set interfaces vxlan vxlan241 group '239.0.0.241'
+```
+
+This command configures the multicast group used by all leaves for this VLAN
+extension. It must be the same on all leaves that have this interface.
+
+```none
+set interfaces vxlan vxlan241 source-interface 'eth0'
+```
+
+This command configures the interface that listens for multicast packets. It
+can also be a loopback interface.
+
+```none
+set interfaces vxlan vxlan241 vni '241'
+```
+
+This command configures the unique ID for the VXLAN interface.
+
+```none
+set interfaces vxlan vxlan241 port 12345
+```
+
+VyOS uses the Linux default UDP port **8472** for VXLAN interfaces. This
+command allows you to configure a different UDP port.
+
+## Unicast VXLAN
+
+As an alternative to multicast, you can configure the VXLAN tunnel by
+specifying the remote IPv4 address directly. The following updates the previous
+multicast example:
+
+```none
+# leaf2 and leaf3
+delete interfaces vxlan vxlan241 group '239.0.0.241'
+delete interfaces vxlan vxlan241 source-interface 'eth0'
+
+# leaf2
+set interfaces vxlan vxlan241 remote 10.1.3.3
+
+# leaf3
+set interfaces vxlan vxlan241 remote 10.1.2.2
+```
+
+The default UDP port is 8472. To configure a different port, use `set
+interfaces vxlan <vxlanN> port <port>`.
diff --git a/docs/configuration/interfaces/wireguard.md b/docs/configuration/interfaces/wireguard.md
new file mode 100644
index 00000000..121d1df0
--- /dev/null
+++ b/docs/configuration/interfaces/wireguard.md
@@ -0,0 +1,434 @@
+---
+lastproofread: '2026-03-02'
+---
+
+(wireguard)=
+
+# WireGuard
+
+WireGuard is an extremely simple, fast, and modern VPN that utilizes
+state-of-the-art cryptography. See <https://www.wireguard.com> for more
+information.
+
+## Site-to-site VPN
+
+The following diagram illustrates a site-to-site VPN setup.
+
+:::{figure} /_static/images/wireguard_site2site_diagram.webp
+:::
+
+## Keypairs
+
+WireGuard requires a keypair, which includes a **private** key
+to decrypt incoming traffic, and a **public** key for peer(s) to encrypt
+outgoing traffic.
+
+### Generate keypair
+
+```{opcmd} generate pki wireguard key-pair
+
+Generate a keypair: a public and a private key.
+
+:::{note}
+This command only outputs the keys to your console. It neither stores
+them in the system nor applies them to the system configuration.
+:::
+
+:::{code-block} none
+vyos@vyos:~$ generate pki wireguard key-pair
+Private key: iJJyEARGK52Ls1GYRCcFvPuTj7WyWYDo//BknoDU0XY=
+Public key: EKY0dxRrSD98QHjfHOK13mZ5PJ7hnddRZt5woB3szyw=
+:::
+```
+
+
+```{opcmd} generate pki wireguard key-pair install interface \<interface\>
+
+Generate a keypair and output the private key assignment command for the
+specified interface.
+
+:::{code-block} none
+vyos@vyos:~$ generate pki wireguard key-pair install interface wg10
+"generate" CLI command executed from operational level.
+Generated private key is not automatically added to the VyOS configuration, use the following configuration mode commands to install key:
+
+set interfaces wireguard wg10 private-key '4Krkv8h6NkAYMMaBWI957yYDJDMvj9URTHstdlOcDU0='
+
+Corresponding public-key to use on peer system is: 'UxDsYT6EnpTIOKUzvMlw2p0sNOKQvFxEdSVrnNrX1Ro='
+:::
+
+:::{note}
+If you invoke this command from configuration mode with the ``run``
+prefix, the generated private key is automatically assigned to the specified
+interface.
+:::
+
+:::{code-block} none
+vyos@vyos# run generate pki wireguard key-pair install interface wg10
+"generate" CLI command executed from config session.
+Generated private-key was imported to CLI!
+
+Use the following command to verify: show interfaces wireguard wg10
+Corresponding public-key to use on peer system is: '7d9KwabjLhHpJiEJeIGd0CBlao/eTwFOh6xyCovTfG8='
+
+vyos@vyos# compare
+[edit interfaces]
++wireguard wg10 {
++ private-key CJweb8FC6BU3Loj4PC2pn5V82cDjIPs7G1saW0ZfLWc=
++}
+:::
+```
+
+
+```{opcmd} show interfaces wireguard \<interface\> public-key
+
+Show the public key assigned to the interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wireguard wg01 public-key
+EKY0dxRrSD98QHjfHOK13mZ5PJ7hnddRZt5woB3szyw=
+:::
+```
+
+#### Optional
+
+```{opcmd} generate pki wireguard preshared-key
+
+Generate a pre-shared key.
+
+The pre-shared key is optional. It adds an additional layer of symmetric-key
+cryptography on top of the asymmetric cryptography.
+
+:::{code-block} none
+vyos@vyos:~$ generate pki wireguard preshared-key
+Pre-shared key: OHH2EwZfMNK+1L6BXbYw3bKCtMrfjpR4mCAEeBlFnRs=
+:::
+```
+
+```{opcmd} generate pki wireguard preshared-key install interface \<interface\> peer \<peer\>
+
+Generate a pre-shared key and output the key assignment command for the
+specified peer.
+
+:::{code-block} none
+vyos@vyos:~$ generate pki wireguard preshared-key install interface wg10 peer foo
+"generate" CLI command executed from operational level.
+Generated preshared-key is not stored to CLI, use configure mode commands to install key:
+
+set interfaces wireguard wg10 peer foo preshared-key '32vQ1w1yFKTna8n7Gu7EimubSe2Y63m8bafz55EG3Ro='
+
+Pre-shared key: +LuaZ8W6DjsDFJFX3jJzoNqrsXHhvq08JztM9z8LHCs=
+:::
+
+:::{note}
+If you invoke this command from configuration mode with the run
+prefix, the generated key is automatically assigned to the specified peer.
+:::
+```
+
+## Interface configuration
+
+The next step is to configure your local WireGuard interface and define the
+networks you want to tunnel (`allowed-ips`).
+
+If your system only initiates connections, specifying the listen port is
+optional. If your system accepts incoming connections, you must define a port
+for peers to connect to. Otherwise, WireGuard selects a random port at each
+reboot, and that may break your peers' ability to connect if that port is not enabled in your firewall rules.
+
+To configure a WireGuard tunnel, you also need your peer's public key.
+
+:::{note}
+The public key specified in the peer configuration block is always
+the **remote** peer's public key, never your local one.
+:::
+
+**Local side configuration**
+
+The local side is configured with the following parameters:
+- Local WireGuard interface IP: `10.1.0.1/30`
+- Local listen port: `51820`
+- Remote peer name: `to-wg02`
+- Remote peer endpoint: `192.0.2.1` on port `51820`
+- Remote peer public key: `XMrlPykaxhdAAiSjhtPlvi30NVkvLQliQuKP7AI7CyI=`
+- Allowed networks: `192.168.2.0/24`
+
+```none
+set interfaces wireguard wg01 address '10.1.0.1/30'
+set interfaces wireguard wg01 description 'VPN-to-wg02'
+set interfaces wireguard wg01 peer to-wg02 allowed-ips '192.168.2.0/24'
+set interfaces wireguard wg01 peer to-wg02 address '192.0.2.1'
+set interfaces wireguard wg01 peer to-wg02 port '51820'
+set interfaces wireguard wg01 peer to-wg02 public-key 'XMrlPykaxhdAAiSjhtPlvi30NVkvLQliQuKP7AI7CyI='
+set interfaces wireguard wg01 port '51820'
+
+set protocols static route 192.168.2.0/24 interface wg01
+```
+
+To send traffic destined for `192.168.2.0/24` through the WireGuard interface
+(`wg01`), configure a static route. Multiple IP addresses or networks can be
+defined and routed. The final check is performed against `allowed-ips`, which
+either permits or drops the traffic.
+
+:::{warning}
+You cannot assign the same `allowed-ips` to multiple WireGuard
+peers. This is a strict design restriction. For more information, check the
+[WireGuard mailing list].
+:::
+
+```{cfgcmd} set interfaces wireguard \<interface\> private-key \<private-key\>
+
+Assign a private key to the specified WireGuard interface.
+
+Example:
+
+:::{code-block} none
+set interfaces wireguard wg01 private-key 'iJJyEARGK52Ls1GYRCcFvPuTj7WyWYDo//BknoDU0XY='
+:::
+
+To generate a private key, use the following command:
+{opcmd}`generate pki wireguard key-pair`.
+
+To view the public key assigned to the interface so you can share it with a
+peer, use the following command:
+{opcmd}`show interfaces wireguard wg01 public-key`.
+```
+
+
+```{cmdincludemd} /_include/interface-per-client-thread.txt
+:var0: wireguard
+:var1: wg01
+```
+
+**Remote side configuration**
+
+```none
+set interfaces wireguard wg01 address '10.1.0.2/30'
+set interfaces wireguard wg01 description 'VPN-to-wg01'
+set interfaces wireguard wg01 peer to-wg01 allowed-ips '192.168.1.0/24'
+set interfaces wireguard wg01 peer to-wg01 address '192.0.2.2'
+set interfaces wireguard wg01 peer to-wg01 port '51820'
+set interfaces wireguard wg01 peer to-wg01 public-key 'EKY0dxRrSD98QHjfHOK13mZ5PJ7hnddRZt5woB3szyw='
+set interfaces wireguard wg01 port '51820'
+set interfaces wireguard wg01 private-key 'OLTQY3HuK5qWDgVs6fJR093SwPgOmCKkDI1+vJLGoFU='
+
+set protocols static route 192.168.1.0/24 interface wg01
+```
+
+## Firewall exceptions
+
+
+To allow WireGuard traffic through the WAN interface, create a firewall
+exception:
+
+```none
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 action accept
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 description 'Allow established/related'
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 state established enable
+set firewall ipv4 name OUTSIDE_LOCAL rule 10 state related enable
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 action accept
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 description WireGuard_IN
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 destination port 51820
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 log enable
+set firewall ipv4 name OUTSIDE_LOCAL rule 20 protocol udp
+```
+
+Ensure that the OUTSIDE_LOCAL firewall group is applied to the WAN interface
+and in an input (local) direction.
+
+```none
+set firewall ipv4 input filter rule 10 action jump
+set firewall ipv4 input filter rule 10 jump-target 'OUTSIDE_LOCAL'
+set firewall ipv4 input filter rule 10 inbound-interface name 'eth0'
+```
+
+Verify that your firewall rules permit traffic. If so, your WireGuard VPN
+should be operational.
+
+```none
+wg01# ping 192.168.1.1
+PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
+64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.16 ms
+64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.77 ms
+
+wg02# ping 192.168.2.1
+PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
+64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=4.40 ms
+64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=1.02 ms
+```
+
+An additional layer of symmetric-key cryptography can be used on top of the
+asymmetric cryptography. This is optional.
+
+```none
+vyos@vyos:~$ generate pki wireguard preshared-key
+Pre-shared key: rvVDOoc2IYEnV+k5p7TNAmHBMEGTHbPU8Qqg8c/sUqc=
+```
+
+Copy the key, as it is not stored locally. Since it is a symmetric key, only
+you and your peer should know its contents. Distribute the key securely.
+
+```none
+wg01# set interfaces wireguard wg01 peer to-wg02 preshared-key 'rvVDOoc2IYEnV+k5p7TNAmHBMEGTHbPU8Qqg8c/sUqc='
+wg02# set interfaces wireguard wg01 peer to-wg01 preshared-key 'rvVDOoc2IYEnV+k5p7TNAmHBMEGTHbPU8Qqg8c/sUqc='
+```
+
+## Remote access (road warrior)
+
+
+With WireGuard, a road warrior VPN configuration is similar to a site-to-site
+VPN. It just omits the `address` and `port` statements.
+
+
+In the following example, the IP addresses for remote clients are defined
+within each peer configuration. This allows peers to communicate with each
+other.
+
+
+Additionally, this setup uses a `persistent-keepalive` flag set to 15 seconds
+to keep the connection alive. This setting is mainly relevant if a peer is
+behind NAT and cannot be reached if the connection is lost. For effectiveness,
+the value should be lower than the UDP timeout.
+
+```none
+wireguard wg01 {
+ address 10.172.24.1/24
+ address 2001:db8:470:22::1/64
+ description RoadWarrior
+ peer MacBook {
+ allowed-ips 10.172.24.30/32
+ allowed-ips 2001:db8:470:22::30/128
+ persistent-keepalive 15
+ pubkey F5MbW7ye7DsoxdOaixjdrudshjjxN5UdNV+pGFHqehc=
+ }
+ peer iPhone {
+ allowed-ips 10.172.24.20/32
+ allowed-ips 2001:db8:470:22::20/128
+ persistent-keepalive 15
+ pubkey BknHcLFo8nOo8Dwq2CjaC/TedchKQ0ebxC7GYn7Al00=
+ }
+ port 2224
+ private-key OLTQY3HuK5qWDgVs6fJR093SwPgOmCKkDI1+vJLGoFU=
+}
+```
+
+Below is the configuration for the iPhone peer. The `AllowedIPs` wildcard
+setting directs all IPv4 and IPv6 traffic through the VPN connection.
+
+```none
+[Interface]
+PrivateKey = ARAKLSDJsadlkfjasdfiowqeruriowqeuasdf=
+Address = 10.172.24.20/24, 2001:db8:470:22::20/64
+DNS = 10.0.0.53, 10.0.0.54
+
+[Peer]
+PublicKey = RIbtUTCfgzNjnLNPQ/ulkGnnB2vMWHm7l2H/xUfbyjc=
+AllowedIPs = 0.0.0.0/0, ::/0
+Endpoint = 192.0.2.1:2224
+PersistentKeepalive = 15
+```
+
+To enable split tunneling, specify the remote subnets. This ensures that only
+traffic destined for the remote site is sent through the tunnel, while all
+other traffic remains unaffected.
+
+```none
+[Interface]
+PrivateKey = 8Iasdfweirousd1EVGUk5XsT+wYFZ9mhPnQhmjzaJE6Go=
+Address = 10.172.24.30/24, 2001:db8:470:22::30/64
+
+[Peer]
+PublicKey = RIbtUTCfgzNjnLNPQ/ulkGnnB2vMWHm7l2H/xUfbyjc=
+AllowedIPs = 10.172.24.30/24, 2001:db8:470:22::/64
+Endpoint = 192.0.2.1:2224
+PersistentKeepalive = 15
+```
+
+## Operational commands
+
+
+### Status
+
+```{opcmd} show interfaces wireguard wg01 summary
+
+Show information about the WireGuard service, including the latest handshake.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wireguard wg01 summary
+interface: wg01
+public key:
+private key: (hidden)
+listening port: 51820
+
+peer: <peer pubkey>
+endpoint: <peer public IP>
+allowed ips: 10.69.69.2/32
+latest handshake: 23 hours, 45 minutes, 26 seconds ago
+transfer: 1.26 MiB received, 6.47 MiB sent
+:::
+```
+
+
+```{opcmd} show interfaces wireguard
+
+Show a list of all WireGuard interfaces.
+
+:::{code-block} none
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+wg01 10.0.0.1/24 u/u
+:::
+```
+
+```{opcmd} show interfaces wireguard \<interface\>
+
+Show general information about a specific WireGuard interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wireguard wg01
+interface: wg01
+address: 10.0.0.1/24
+public key: h1HkYlSuHdJN6Qv4Hz4bBzjGg5WUty+U1L7DJsZy1iE=
+private key: (hidden)
+listening port: 41751
+RX: bytes packets errors dropped overrun mcast
+0 0 0 0 0 0
+TX: bytes packets errors dropped carrier collisions
+0 0 0 0 0 0
+:::
+```
+
+## Remote access (road warrior) clients
+
+Some users connect mobile devices to their VyOS router using WireGuard. To
+simplify deployment, generate a per-mobile configuration from the VyOS CLI.
+
+:::{warning}
+From a security perspective, it is not recommended to let a third
+party create and share the private key for a secure connection. You should
+create the private portion yourself and hand out only the public key.
+:::
+
+```{opcmd} generate wireguard client-config \<name\> interface \<interface\> server \<ip|fqdn\> address \<client-ip\>
+
+**Generate a client configuration file that establishes a connection to the
+specified interface.**
+
+The public key from the specified interface is automatically included in the
+configuration file.
+
+The command also generates a configuration snippet that can be copied into the
+VyOS CLI. The ``<name>`` you provide will be used as the peer name in the
+snippet.
+
+You must also specify the IP address or FQDN of the server the client connects
+to. The address parameter can be used twice to assign both an IPv4 (/32) and
+an IPv6 (/128) address to the client.
+
+:::{figure} /_static/images/wireguard_qrcode.webp
+:alt: WireGuard Client QR code
+:::
+```
+
+[wireguard mailing list]: https://lists.zx2c4.com/pipermail/wireguard/2018-December/003704.html
diff --git a/docs/configuration/interfaces/wireless.md b/docs/configuration/interfaces/wireless.md
new file mode 100644
index 00000000..9e6b7c99
--- /dev/null
+++ b/docs/configuration/interfaces/wireless.md
@@ -0,0 +1,923 @@
+---
+lastproofread: '2026-03-23'
+---
+
+(wireless-interface)=
+
+# Wireless LAN / Wi-Fi
+
+{abbr}`WLAN (Wireless LAN)` interfaces provide 802.11 (a/b/g/n/ac) wireless
+connectivity, referred to as Wi-Fi, and operate in one of the following
+modes:
+
+- {abbr}`WAP (Wireless Access-Point)` mode provides network access to connecting
+ stations if the physical hardware supports acting as a WAP
+- Station mode acts as a Wi-Fi client accessing the network through an available
+ WAP
+- Monitor mode lets the system passively monitor wireless traffic
+
+If the system detects an unconfigured wireless device, it will be automatically
+added to the configuration tree, specifying any detected settings (for example,
+its MAC address) and configured to run in monitor mode.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-common-with-dhcp.txt
+:var0: wireless
+:var1: wlan0
+```
+
+
+### System-wide configuration
+
+```{cfgcmd} set system wireless country-code \<cc\>
+
+Country code (ISO/IEC 3166-1). Used to set regulatory domain. Set as needed
+to indicate country in which device is operating. This can limit available
+channels and transmit power.
+
+:::{note}
+This option is mandatory in ``access-point`` mode.
+:::
+```
+
+
+### Wireless options
+
+```{cfgcmd} set interfaces wireless \<interface\> channel \<number\>
+
+Configure the IEEE 802.11 wireless radio channel for the interface.
+Channel allocation depends on the frequency band:
+* **2.4 GHz** (802.11b/g/n/ax): Channels range from 1 to 14.
+* **5 GHz** (802.11a/h/j/n/ac/ax): Channels range from 34 to 177.
+* **6 GHz** (802.11ax): Channels range from 1 to 233.
+* **Automatic channel selection:** 0.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> disable-broadcast-ssid
+
+Send empty SSID in beacons and ignore probe request frames that do not specify
+full SSID, i.e., require stations to know the SSID.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> expunge-failing-stations
+
+Disassociate stations based on excessive transmission failures or other
+indications of connection loss.
+
+This depends on the driver capabilities and may not be available with all
+drivers.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> isolate-stations
+
+Client isolation can be used to prevent low-level bridging of frames between
+associated stations in the BSS.
+
+By default, this bridging is allowed.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> max-stations \<count\>
+
+Maximum number of stations allowed in station table. New stations will be
+rejected after the station table is full. IEEE 802.11 has a limit of 2007
+different association IDs, so this number should not be larger than that.
+
+This defaults to 2007.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> mgmt-frame-protection
+
+Management Frame Protection (MFP) according to IEEE 802.11w
+
+:::{note}
+{abbr}`MFP (Management Frame Protection)` is required for WPA3.
+:::
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> enable-bf-protection
+
+Beacon Protection: management frame protection for Beacon frames.
+
+:::{note}
+This option requires {abbr}`MFP (Management Frame Protection)`
+to be enabled.
+:::
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> mode \<a | b | g | n | ac | ax\>
+
+Operation mode of wireless radio.
+* ``a`` - 802.11a - 54 Mbits/sec
+* ``b`` - 802.11b - 11 Mbits/sec
+* ``g`` - 802.11g - 54 Mbits/sec (default)
+* ``n`` - 802.11n - 600 Mbits/sec
+* ``ac`` - 802.11ac - 1300 Mbits/sec
+* ``ax`` - 802.11ax - exceeds 1GBit/sec
+
+:::{note}
+In VyOS, 802.11ax is only implemented for 2.4GHz and 6GHz.
+:::
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> physical-device \<device\>
+
+Wireless hardware device used as underlay radio.
+
+This defaults to phy0.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> reduce-transmit-power \<number\>
+
+Adds the Power Constraint information element to Beacon and Probe Response
+frames.
+
+This option adds the Power Constraint information element when applicable
+and the Country information element is configured. The Power Constraint
+element is required by Transmit Power Control.
+
+Valid values are 0..255.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> ssid \<ssid\>
+
+SSID to be used in IEEE 802.11 management frames
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> type \<access-point | station | monitor\>
+
+Wireless device type for this interface
+* ``access-point``: Forwards packets between other nodes.
+* ``station``: Connects to another {abbr}`AP (Access Point)`.
+* ``monitor``: Passively monitors all packets on the frequency/channel.
+```
+
+```{cmdincludemd} /_include/interface-per-client-thread.txt
+:var0: wireless
+:var1: wlan0
+```
+
+
+#### PPDU
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities require-ht
+
+```
+```{cfgcmd} set interfaces wireless \<interface\> capabilities require-vht
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities require-he
+```
+
+##### HT (High Throughput) capabilities (802.11n)
+
+> Configuring HT mode options is required when using 802.11n or
+> 802.11ax at 2.4GHz.
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht 40mhz-incapable
+
+Device is incapable of 40 MHz, do not advertise. This sets ``[40-INTOLERANT]``
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht auto-powersave
+
+WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD]
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht channel-set-width \<ht20 | ht40+ | ht40-\>
+
+Supported channel width set.
+* ``ht20`` - 20 MHz channel width
+* ``ht40-`` - Both 20 MHz and 40 MHz with secondary channel below the primary
+channel
+* ``ht40+`` - Both 20 MHz and 40 MHz with secondary channel above the primary
+channel
+
+:::{note}
+Channel availability for HT40- and HT40+ is limited. The following
+table lists channels permitted for HT40- and HT40+ according to IEEE
+802.11n Annex J. Channel availability may vary by location.
+
+ ::::{code-block} none
+ freq HT40- HT40+
+ 2.4 GHz 5-13 1-7 (1-9 in Europe/Japan)
+ 5 GHz 40,48,56,64 36,44,52,60
+ ::::
+:::
+
+:::{note}
+40 MHz channels may switch their primary and secondary channels if
+needed or creation of 40 MHz channel may be rejected based on overlapping
+BSSes. These changes are done automatically when hostapd is setting up the
+40 MHz channel.
+:::
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht delayed-block-ack
+
+Enable HT-delayed Block Ack ``[DELAYED-BA]``
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht dsss-cck-40
+
+DSSS/CCK Mode in 40 MHz, this sets ``[DSSS_CCK-40]``
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht greenfield
+
+This enables the greenfield option which sets the ``[GF]`` option
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht ldpc
+
+Enable LDPC coding capability
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht lsig-protection
+
+Enable L-SIG TXOP protection capability
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht max-amsdu \<3839 | 7935\>
+
+Maximum A-MSDU length 3839 (default) or 7935 octets
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht short-gi \<20 | 40\>
+
+Short GI capabilities for 20 and 40 MHz
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht smps \<static | dynamic\>
+
+Spatial Multiplexing Power Save (SMPS) settings
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht stbc rx \<num\>
+
+Enable receiving PPDU using STBC (Space Time Block Coding)
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities ht stbc tx
+
+Enable sending PPDU using STBC (Space Time Block Coding)
+```
+
+##### VHT (Very High Throughput) capabilities (802.11ac)
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht antenna-count \<count\>
+```
+
+%
+% Number of antennas on this card
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht antenna-pattern-fixed
+
+Set if antenna pattern does not change during the lifetime of an association
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht beamform \<single-user-beamformer | single-user-beamformee | multi-user-beamformer | multi-user-beamformee>
+
+Beamforming capabilities:
+* ``single-user-beamformer`` - Support for operation as
+single user beamformer
+* ``single-user-beamformee`` - Support for operation as
+single user beamformee
+* ``multi-user-beamformer`` - Support for operation as
+multi user beamformer
+* ``multi-user-beamformee`` - Support for operation as
+multi user beamformee
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht center-channel-freq \<freq-1 | freq-2\> \<number\>
+
+VHT operating channel center frequency - center freq 1
+(for use with 80, 80+80 and 160 modes)
+
+VHT operating channel center frequency - center freq 2
+(for use with the 80+80 mode)
+
+\<number\> must be from 34 - 173. For 80 MHz channels it should be channel + 6.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht channel-set-width \<0 | 1 | 2 | 3\>
+
+* ``0`` - 20 or 40 MHz channel width (default)
+* ``1`` - 80 MHz channel width
+* ``2`` - 160 MHz channel width
+* ``3`` - 80+80 MHz channel width
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht ldpc
+
+Enable LDPC (Low Density Parity Check) coding capability
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht link-adaptation
+
+VHT link adaptation capabilities
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht max-mpdu \<value\>
+
+Increase Maximum MPDU length to 7991 or 11454 octets (default 3895 octets)
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht max-mpdu-exp \<value\>
+
+Set the maximum length of A-MPDU pre-EOF padding that the station can
+receive
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht short-gi \<80 | 160\>
+
+Short GI capabilities
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht stbc rx \<num\>
+
+Enable receiving PPDU using STBC (Space Time Block Coding)
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht stbc tx
+
+Enable sending PPDU using STBC (Space Time Block Coding)
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht tx-powersave
+
+Enable VHT TXOP Power Save Mode
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities vht vht-cf
+
+Station supports receiving VHT variant HT Control field
+```
+
+##### HE (High Efficiency) capabilities (802.11ax)
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he antenna-pattern-fixed
+
+Tell the AP that antenna positions are fixed and will not change
+during the lifetime of an association.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he beamform \<single-user-beamformer | single-user-beamformee | multi-user-beamformer\>
+
+Beamforming capabilities:
+* ``single-user-beamformer`` - Support for operation as
+single user beamformer
+* ``single-user-beamformee`` - Support for operation as
+single user beamformee
+* ``multi-user-beamformer`` - Support for operation as multi
+user beamformer
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he bss-color \<number\>
+
+BSS coloring helps to prevent channel jamming when multiple APs use
+the same channels.
+
+Valid values are 1..63
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he center-channel-freq \<freq-1 | freq-2\> \<number\>
+
+HE operating channel center frequency - center freq 1
+(for use with 80, 80+80 and 160 modes)
+
+HE operating channel center frequency - center freq 2
+(for use with the 80+80 mode)
+
+\<number\> must be within 1..233. For 80 MHz channels it should be
+channel + 6 and for 160 MHz channels, it should be channel + 14.
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he channel-set-width \<number\>
+
+\<number\> must be one of:
+
+* ``81`` - 20 MHz channel width (2.4GHz)
+* ``83`` - 40 MHz channel width, secondary 20MHz channel above primary
+channel (2.4GHz)
+* ``84`` - 40 MHz channel width, secondary 20MHz channel below primary
+channel (2.4GHz)
+* ``131`` - 20 MHz channel width (6GHz)
+* ``132`` - 40 MHz channel width (6GHz)
+* ``133`` - 80 MHz channel width (6GHz)
+* ``134`` - 160 MHz channel width (6GHz)
+* ``135`` - 80+80 MHz channel width (6GHz)
+```
+
+```{cfgcmd} set interfaces wireless \<interface\> capabilities he coding-scheme \<number\>
+
+This setting configures Spatial Stream and Modulation Coding Scheme
+settings for HE mode (HE-MCS). It is usually not needed to set this
+explicitly, but it might help with some WiFi adapters.
+
+\<number\> must be one of:
+* ``0`` - HE-MCS 0-7
+* ``1`` - HE-MCS 0-9
+* ``2`` - HE-MCS 0-11
+* ``3`` - HE-MCS is not supported
+```
+
+### Wireless options (Station/Client)
+
+The example creates a wireless station (commonly referred to as Wi-Fi client)
+that accesses the network through the WAP defined in the above example. The
+default physical device (`phy0`) is used.
+
+```none
+set system wireless country-code de
+set interfaces wireless wlan0 type station
+set interfaces wireless wlan0 address dhcp
+set interfaces wireless wlan0 ssid 'TEST'
+set interfaces wireless wlan0 security wpa passphrase '12345678'
+```
+
+Resulting configuration:
+
+```none
+system {
+ wireless {
+ country-code de
+ }
+}
+interfaces {
+ wireless wlan0 {
+ address dhcp
+ security {
+ wpa {
+ passphrase "12345678"
+ }
+ }
+ ssid TEST
+ type station
+ }
+```
+
+### Security
+
+{abbr}`WPA (Wi-Fi Protected Access)`, WPA2 Enterprise and WPA3 Enterprise in
+combination with 802.1X based authentication can be used to authenticate
+users or computers in a domain.
+
+The wireless client (supplicant) authenticates against the RADIUS server
+(authentication server) using an {abbr}`EAP (Extensible Authentication
+Protocol)` method configured on the RADIUS server. The WAP (also referred
+to as authenticator) role is to send all authentication messages between the
+supplicant and the configured authentication server, thus the RADIUS server
+is responsible for authenticating the users.
+
+The WAP in this example has the following characteristics:
+- IP address `192.168.2.1/24`
+- Network ID (SSID) `Enterprise-TEST`
+- WPA passphrase `12345678`
+- Use 802.11n protocol
+- Wireless channel `1`
+- RADIUS server at `192.168.3.10` with shared-secret `VyOSPassword`
+
+```none
+set system wireless country-code de
+set interfaces wireless wlan0 address '192.168.2.1/24'
+set interfaces wireless wlan0 type access-point
+set interfaces wireless wlan0 channel 1
+set interfaces wireless wlan0 mode n
+set interfaces wireless wlan0 ssid 'Enterprise-TEST'
+set interfaces wireless wlan0 security wpa mode wpa2
+set interfaces wireless wlan0 security wpa cipher CCMP
+set interfaces wireless wlan0 security wpa radius server 192.168.3.10 key 'VyOSPassword'
+set interfaces wireless wlan0 security wpa radius server 192.168.3.10 port 1812
+```
+
+Resulting configuration:
+
+```none
+system {
+ wireless {
+ country-code de
+ }
+}
+interfaces {
+ [...]
+ wireless wlan0 {
+ address 192.168.2.1/24
+ channel 1
+ mode n
+ security {
+ wpa {
+ cipher CCMP
+ mode wpa2
+ radius {
+ server 192.168.3.10 {
+ key 'VyOSPassword'
+ port 1812
+ }
+ }
+ }
+ }
+ ssid "Enterprise-TEST"
+ type access-point
+ }
+}
+```
+
+### VLAN
+#### Regular VLANs (802.1q)
+
+```{cmdincludemd} /_include/interface-vlan-8021q.txt
+:var0: wireless
+:var1: wlan0
+```
+
+#### QinQ (802.1ad)
+
+```{cmdincludemd} /_include/interface-vlan-8021ad.txt
+:var0: wireless
+:var1: wlan0
+```
+
+## Operation
+
+```{opcmd} show interfaces wireless info
+```
+
+Use this command to view operational status and wireless-specific information
+about all wireless interfaces.
+
+```none
+vyos@vyos:~$ show interfaces wireless info
+Interface Type SSID Channel
+wlan0 access-point VyOS-TEST-0 1
+```
+
+```{opcmd} show interfaces wireless detail
+```
+
+Show the operational status and detailed wireless-specific
+information about all wireless interfaces.
+
+```none
+vyos@vyos:~$ show interfaces wireless detail
+wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether XX:XX:XX:XX:XX:c3 brd XX:XX:XX:XX:XX:ff
+ inet xxx.xxx.99.254/24 scope global wlan0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::xxxx:xxxx:fe54:2fc3/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 66072 282 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 83413 430 0 0 0 0
+
+wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether XX:XX:XX:XX:XX:c3 brd XX:XX:XX:XX:XX:ff
+ inet xxx.xxx.100.254/24 scope global wlan0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::xxxx:xxxx:ffff:2ed3/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 166072 5282 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 183413 5430 0 0 0 0
+```
+
+```{opcmd} show interfaces wireless \<wlanX\>
+```
+
+This command shows both status and statistics on the specified wireless
+interface. The wireless interface identifier can range from wlan0 to wlan999.
+
+```none
+vyos@vyos:~$ show interfaces wireless wlan0
+wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether XX:XX:XX:XX:XX:c3 brd XX:XX:XX:XX:XX:ff
+ inet xxx.xxx.99.254/24 scope global wlan0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::xxxx:xxxx:fe54:2fc3/64 scope link
+ valid_lft forever preferred_lft forever
+
+ RX: bytes packets errors dropped overrun mcast
+ 66072 282 0 0 0 0
+ TX: bytes packets errors dropped carrier collisions
+ 83413 430 0 0 0 0
+```
+
+```{opcmd} show interfaces wireless \<wlanX\> brief
+```
+
+This command gives a brief status overview of a specified wireless interface.
+The wireless interface identifier can range from wlan0 to wlan999.
+
+```none
+vyos@vyos:~$ show interfaces wireless wlan0 brief
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+wlan0 192.168.2.254/24 u/u
+```
+
+```{opcmd} show interfaces wireless \<wlanX\> queue
+```
+
+Use this command to view wireless interface queue information.
+The wireless interface identifier can range from wlan0 to wlan999.
+
+```none
+vyos@vyos:~$ show interfaces wireless wlan0 queue
+qdisc pfifo_fast 0: root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
+ Sent 810323 bytes 6016 pkt (dropped 0, overlimits 0 requeues 0)
+ rate 0bit 0pps backlog 0b 0p requeues 0
+```
+
+```{opcmd} show interfaces wireless \<wlanX\> scan
+```
+
+This command is used to retrieve information about WAP within the range of your
+wireless interface. This command is useful on wireless interfaces configured
+in station mode.
+
+:::{note}
+Scanning is not supported on all wireless drivers and wireless
+hardware. Refer to your driver and wireless hardware documentation for
+further details.
+:::
+```none
+vyos@vyos:~$ show interfaces wireless wlan0 scan
+Address SSID Channel Signal (dbm)
+00:53:3b:88:6e:d8 WLAN-576405 1 -64.00
+00:53:3b:88:6e:da Telekom_FON 1 -64.00
+00:53:00:f2:c2:a4 BabyView_F2C2A4 6 -60.00
+00:53:3b:88:6e:d6 Telekom_FON 100 -72.00
+00:53:3b:88:6e:d4 WLAN-576405 100 -71.00
+00:53:44:a4:96:ec KabelBox-4DC8 56 -81.00
+00:53:d9:7a:67:c2 WLAN-741980 1 -75.00
+00:53:7c:99:ce:76 Vodafone Homespot 1 -86.00
+00:53:44:a4:97:21 KabelBox-4DC8 1 -78.00
+00:53:44:a4:97:21 Vodafone Hotspot 1 -79.00
+00:53:44:a4:97:21 Vodafone Homespot 1 -79.00
+00:53:86:40:30:da Telekom_FON 1 -86.00
+00:53:7c:99:ce:76 Vodafone Hotspot 1 -86.00
+00:53:44:46:d2:0b Vodafone Hotspot 1 -87.00
+```
+
+## Examples
+
+The following example creates a WAP. When configuring multiple WAP interfaces,
+you must specify unique IP addresses, channels, Network IDs commonly referred
+to as {abbr}`SSID (Service Set Identifier)`, and MAC addresses.
+
+The WAP in this example has the following characteristics:
+- IP address `192.168.2.1/24`
+- Network ID (SSID) `TEST`
+- WPA passphrase `12345678`
+- Use 802.11n protocol
+- Wireless channel `1`
+
+```none
+set system wireless country-code de
+set interfaces wireless wlan0 address '192.168.2.1/24'
+set interfaces wireless wlan0 type access-point
+set interfaces wireless wlan0 channel 1
+set interfaces wireless wlan0 mode n
+set interfaces wireless wlan0 ssid 'TEST'
+set interfaces wireless wlan0 security wpa mode wpa2
+set interfaces wireless wlan0 security wpa cipher CCMP
+set interfaces wireless wlan0 security wpa passphrase '12345678'
+```
+
+Resulting configuration:
+
+```none
+system {
+ wireless {
+ country-code de
+ }
+}
+interfaces {
+ [...]
+ wireless wlan0 {
+ address 192.168.2.1/24
+ channel 1
+ mode n
+ security {
+ wpa {
+ cipher CCMP
+ mode wpa2
+ passphrase "12345678"
+ }
+ }
+ ssid "TEST"
+ type access-point
+ }
+}
+```
+
+To enable access point functionality, configure a DHCP server for this
+interface's network, or add the interface to an existing local bridge
+(see {ref}`bridge-interface` for details).
+
+### Wi-Fi 6/6E (802.11ax)
+
+The following examples configure Wi-Fi 6 (2.4 GHz) and Wi-Fi 6E (6 GHz)
+{abbr}`APs (Access Points)` with the following parameters:
+- Network ID (SSID): `test.ax`
+- WPA passphrase: `super-dooper-secure-passphrase`
+- Protocol: 802.11ax
+- Wireless channel for 2.4 GHz: `11`
+- Wireless channel for 6 GHz: `5`
+
+#### Example configuration: Wi-Fi 6 at 2.4 GHz
+
+You may expect real throughput around 10 MB/s or higher in crowded areas.
+
+```none
+set system wireless country-code de
+set interfaces wireless wlan0 capabilities he antenna-pattern-fixed
+set interfaces wireless wlan0 capabilities he beamform multi-user-beamformer
+set interfaces wireless wlan0 capabilities he beamform single-user-beamformee
+set interfaces wireless wlan0 capabilities he beamform single-user-beamformer
+set interfaces wireless wlan0 capabilities he bss-color 13
+set interfaces wireless wlan0 capabilities he channel-set-width 81
+set interfaces wireless wlan0 capabilities ht 40mhz-incapable
+set interfaces wireless wlan0 capabilities ht channel-set-width ht20
+set interfaces wireless wlan0 capabilities ht channel-set-width ht40+
+set interfaces wireless wlan0 capabilities ht channel-set-width ht40-
+set interfaces wireless wlan0 capabilities ht short-gi 20
+set interfaces wireless wlan0 capabilities ht short-gi 40
+set interfaces wireless wlan0 capabilities ht stbc rx 2
+set interfaces wireless wlan0 capabilities ht stbc tx
+set interfaces wireless wlan0 channel 11
+set interfaces wireless wlan0 description "802.11ax 2.4GHz"
+set interfaces wireless wlan0 mode ax
+set interfaces wireless wlan0 security wpa cipher CCMP
+set interfaces wireless wlan0 security wpa cipher CCMP-256
+set interfaces wireless wlan0 security wpa cipher GCMP-256
+set interfaces wireless wlan0 security wpa cipher GCMP
+set interfaces wireless wlan0 security wpa mode wpa2
+set interfaces wireless wlan0 security wpa passphrase super-dooper-secure-passphrase
+set interfaces wireless wlan0 ssid test.ax
+set interfaces wireless wlan0 type access-point
+commit
+```
+
+Resulting configuration:
+
+```none
+system {
+ wireless {
+ country-code de
+ }
+}
+interfaces {
+ [...]
+ wireless wlan0 {
+ capabilities {
+ he {
+ antenna-pattern-fixed
+ beamform {
+ multi-user-beamformer
+ single-user-beamformee
+ single-user-beamformer
+ }
+ bss-color 13
+ channel-set-width 81
+ }
+ ht {
+ 40mhz-incapable
+ channel-set-width ht20
+ channel-set-width ht40+
+ channel-set-width ht40-
+ short-gi 20
+ short-gi 40
+ stbc {
+ rx 2
+ tx
+ }
+ }
+ }
+ channel 11
+ description "802.11ax 2.4GHz"
+ hw-id [...]
+ mode ax
+ physical-device phy0
+ security {
+ wpa {
+ cipher CCMP
+ cipher CCMP-256
+ cipher GCMP-256
+ cipher GCMP
+ mode wpa2
+ passphrase super-dooper-secure-passphrase
+ }
+ }
+ ssid test.ax
+ type access-point
+ }
+}
+```
+
+#### Example configuration: Wi-Fi 6E at 6 GHz
+
+You may expect real throughput between 50 MB/s and 150 MB/s, depending on
+obstructions from walls, water, metal, or other materials
+with high electromagnetic damping at 6 GHz. Best results are achieved
+with the AP being in the same room and in line-of-sight.
+
+```none
+set system wireless country-code de
+set interfaces wireless wlan0 capabilities he antenna-pattern-fixed
+set interfaces wireless wlan0 capabilities he beamform multi-user-beamformer
+set interfaces wireless wlan0 capabilities he beamform single-user-beamformee
+set interfaces wireless wlan0 capabilities he beamform single-user-beamformer
+set interfaces wireless wlan0 capabilities he bss-color 13
+set interfaces wireless wlan0 capabilities he channel-set-width 134
+set interfaces wireless wlan0 capabilities he center-channel-freq freq-1 15
+set interfaces wireless wlan0 channel 5
+set interfaces wireless wlan0 description "802.11ax 6GHz"
+set interfaces wireless wlan0 mode ax
+set interfaces wireless wlan0 security wpa cipher CCMP
+set interfaces wireless wlan0 security wpa cipher CCMP-256
+set interfaces wireless wlan0 security wpa cipher GCMP-256
+set interfaces wireless wlan0 security wpa cipher GCMP
+set interfaces wireless wlan0 security wpa mode wpa3
+set interfaces wireless wlan0 security wpa passphrase super-dooper-secure-passphrase
+set interfaces wireless wlan0 mgmt-frame-protection required
+set interfaces wireless wlan0 enable-bf-protection
+set interfaces wireless wlan0 ssid test.ax
+set interfaces wireless wlan0 type access-point
+set interfaces wireless wlan0 stationary-ap
+commit
+```
+
+Resulting configuration:
+
+```none
+system {
+ wireless {
+ country-code de
+ }
+}
+interfaces {
+ [...]
+ wireless wlan0 {
+ capabilities {
+ he {
+ antenna-pattern-fixed
+ beamform {
+ multi-user-beamformer
+ single-user-beamformee
+ single-user-beamformer
+ }
+ bss-color 13
+ center-channel-freq {
+ freq-1 15
+ }
+ channel-set-width 134
+ }
+ }
+ channel 5
+ description "802.11ax 6GHz"
+ enable-bf-protection
+ hw-id [...]
+ mgmt-frame-protection required
+ mode ax
+ physical-device phy0
+ security {
+ wpa {
+ cipher CCMP
+ cipher CCMP-256
+ cipher GCMP-256
+ cipher GCMP
+ mode wpa3
+ passphrase super-dooper-secure-passphrase
+ }
+ }
+ ssid test.ax
+ stationary-ap
+ type access-point
+ }
+}
+```
+
+(wireless-interface-intel-ax200)=
+
+### Intel AX200
+
+The Intel AX200 card does not work out of the box in AP mode. You can
+still put this card into AP mode using the following configuration:
+
+```none
+set system wireless country-code 'us'
+set interfaces wireless wlan0 channel '1'
+set interfaces wireless wlan0 mode 'n'
+set interfaces wireless wlan0 physical-device 'phy0'
+set interfaces wireless wlan0 ssid 'VyOS'
+set interfaces wireless wlan0 type 'access-point'
+```
+
diff --git a/docs/configuration/interfaces/wwan.md b/docs/configuration/interfaces/wwan.md
new file mode 100644
index 00000000..e8121f28
--- /dev/null
+++ b/docs/configuration/interfaces/wwan.md
@@ -0,0 +1,355 @@
+---
+lastproofread: '2026-03-30'
+---
+
+(wwan-interface)=
+
+# WWAN
+
+{abbr}`WWAN (Wireless Wide Area Network)` interfaces provide access to cellular
+networks via a cellular modem or card.
+
+Configure these interfaces under the `interfaces wwan` node.
+
+## Configuration
+
+### Common interface configuration
+
+```{cmdincludemd} /_include/interface-address-with-dhcp.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-description.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-disable.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-disable-link-detect.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-mtu.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-ip.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-ipv6.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-vrf.txt
+:var0: wwan
+:var1: wwan0
+```
+
+**DHCP(v6)**
+
+```{cmdincludemd} /_include/interface-dhcp-options.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-dhcpv6-options.txt
+:var0: wwan
+:var1: wwan0
+```
+
+```{cmdincludemd} /_include/interface-dhcpv6-prefix-delegation.txt
+:var0: wwan
+:var1: wwan0
+```
+
+
+### WWAN options
+
+```{cfgcmd} set interfaces wwan \<interface\> apn \<apn\>
+
+**Configure the** {abbr}`APN (Access Point Name)` **for the WWAN connection.**
+
+Every WWAN connection requires an {abbr}`APN (Access Point Name)` to connect to
+the cellular network.
+
+This parameter is mandatory. Contact your service provider for the correct
+{abbr}`APN (Access Point Name)`.
+```
+
+
+## Operation
+
+```{opcmd} show interfaces wwan \<interface\>
+
+Show the operational status and traffic statistics for the specified WWAN
+interface.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0
+wwan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
+link/ether 02:c2:f3:00:01:02 brd ff:ff:ff:ff:ff:ff
+inet 10.155.144.12/30 brd 10.155.144.15 scope global dynamic wwan0
+valid_lft 7012sec preferred_lft 7012sec
+inet6 fe80::c2:f3ff:fe00:0102/64 scope link
+valid_lft forever preferred_lft forever
+
+RX: bytes packets errors dropped overrun mcast
+640 2 0 0 0 0
+TX: bytes packets errors dropped carrier collisions
+3229 16 0 0 0 0
+:::
+```
+
+
+```{opcmd} show interfaces wwan \<interface\> summary
+
+Show WWAN module hardware characteristics and connection information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 summary
+--------------------------------
+General | dbus path: /org/freedesktop/ModemManager1/Modem/0
+| device id: 79f4e9cc2e9fc8d4a3b8c8f6327c2e363170194d
+--------------------------------
+Hardware | manufacturer: Sierra Wireless, Incorporated
+| model: MC7710
+| revision: SWI9200X_03.05.29.03ap r6485 CNSHZ-ED-XP0031 2014/12/02 17:53:15
+| h/w revision: 1.0
+| supported: gsm-umts, lte
+| current: gsm-umts, lte
+| equipment id: 358xxxxxxxxxxxx
+--------------------------------
+System | device: /sys/devices/pci0000:00/0000:00:13.0/usb3/3-1/3-1.3
+| drivers: qcserial, qmi_wwan
+| plugin: Generic
+| primary port: cdc-wdm0
+| ports: ttyUSB0 (qcdm), ttyUSB2 (at), cdc-wdm0 (qmi), wwan0 (net)
+--------------------------------
+Numbers | own: 4917xxxxxxxx
+--------------------------------
+Status | lock: sim-pin2
+| unlock retries: sim-pin (3), sim-pin2 (3), sim-puk (10), sim-puk2 (10)
+| state: connected
+| power state: on
+| access tech: lte
+| signal quality: 63% (recent)
+--------------------------------
+Modes | supported: allowed: 2g; preferred: none
+| allowed: 3g; preferred: none
+| allowed: 4g; preferred: none
+| allowed: 2g, 3g; preferred: 3g
+| allowed: 2g, 3g; preferred: 2g
+| allowed: 2g, 4g; preferred: 4g
+| allowed: 2g, 4g; preferred: 2g
+| allowed: 3g, 4g; preferred: 3g
+| allowed: 3g, 4g; preferred: 4g
+| allowed: 2g, 3g, 4g; preferred: 4g
+| allowed: 2g, 3g, 4g; preferred: 3g
+| allowed: 2g, 3g, 4g; preferred: 2g
+| current: allowed: 2g, 3g, 4g; preferred: 2g
+--------------------------------
+Bands | supported: egsm, dcs, pcs, utran-1, utran-8, eutran-1, eutran-3,
+| eutran-7, eutran-8, eutran-20
+| current: egsm, dcs, pcs, utran-1, utran-8, eutran-1, eutran-3,
+| eutran-7, eutran-8, eutran-20
+--------------------------------
+IP | supported: ipv4, ipv6, ipv4v6
+--------------------------------
+3GPP | imei: 358xxxxxxxxxxxx
+| operator id: 26201
+| operator name: Telekom.de
+| registration: home
+--------------------------------
+3GPP EPS | ue mode of operation: ps-1
+--------------------------------
+SIM | dbus path: /org/freedesktop/ModemManager1/SIM/0
+--------------------------------
+Bearer | dbus path: /org/freedesktop/ModemManager1/Bearer/0
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> capabilities
+
+Show WWAN module radio capabilities.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 capabilities
+Max TX channel rate: '50000000'
+Max RX channel rate: '100000000'
+Data Service: 'simultaneous-cs-ps'
+SIM: 'supported'
+Networks: 'gsm, umts, lte'
+Bands: 'gsm-dcs-1800, gsm-900-extended, gsm-900-primary, gsm-pcs-1900, wcdma-2100, wcdma-900'
+LTE bands: '1, 3, 7, 8, 20'
+:::
+```
+
+
+```{opcmd} show interfaces wwan \<interface\> firmware
+
+Show WWAN module firmware information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 firmware
+Model: MC7710
+Boot version: SWI9200X_03.05.29.03bt r6485 CNSHZ-ED-XP0031 2014/12/02 17:33:08
+AMSS version: SWI9200X_03.05.29.03ap r6485 CNSHZ-ED-XP0031 2014/12/02 17:53:15
+SKU ID: unknown
+Package ID: unknown
+Carrier ID: 0
+Config version: unknown
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> imei
+
+Show WWAN module IMEI.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 imei
+ESN: '0'
+IMEI: '358xxxxxxxxxxxx'
+MEID: 'unknown'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> imsi
+
+Show the IMSI of the associated SIM card.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 imsi
+IMSI: '262xxxxxxxxxxxx'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> model
+
+Show WWAN module model.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 model
+Model: 'MC7710'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> msisdn
+
+Show the MSISDN of the associated SIM card.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 msisdn
+MSISDN: '4917xxxxxxxx'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> revision
+
+Show WWAN module hardware revision.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 revision
+Revision: 'SWI9200X_03.05.29.03ap r6485 CNSHZ-ED-XP0031 2014/12/02 17:53:15'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> signal
+
+Show signal information for the cellular connection.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 signal
+LTE:
+RSSI: '-74 dBm'
+RSRQ: '-7 dB'
+RSRP: '-100 dBm'
+SNR: '13.0 dB'
+Radio Interface: 'lte'
+Active Band Class: 'eutran-3'
+Active Channel: '1300'
+:::
+```
+
+```{opcmd} show interfaces wwan \<interface\> sim
+
+Show WWAN module SIM card information.
+
+:::{code-block} none
+vyos@vyos:~$ show interfaces wwan wwan0 sim
+Provisioning applications:
+Primary GW: slot '1', application '1'
+Primary 1X: session doesn't exist
+Secondary GW: session doesn't exist
+Secondary 1X: session doesn't exist
+Slot [1]:
+Card state: 'present'
+UPIN state: 'not-initialized'
+UPIN retries: '0'
+UPUK retries: '0'
+Application [1]:
+Application type: 'usim (2)'
+Application state: 'ready'
+Application ID:
+A0:00:00:00:87:10:02:FF:49:94:20:89:03:10:00:00
+Personalization state: 'ready'
+UPIN replaces PIN1: 'no'
+PIN1 state: 'disabled'
+PIN1 retries: '3'
+PUK1 retries: '10'
+PIN2 state: 'enabled-not-verified'
+PIN2 retries: '3'
+PUK2 retries: '10'
+:::
+```
+
+
+## Example
+
+The following example shows how to configure a cellular connection using a
+Sierra Wireless MC7710 miniPCIe card that operates over USB despite its form
+factor. The card is installed in a {ref}`pc-engines-apu4`.
+
+```none
+set interfaces wwan wwan0 apn 'internet.telekom'
+set interfaces wwan wwan0 address 'dhcp'
+```
+
+
+## Supported hardware
+
+The following WWAN modules have been successfully tested with a
+{ref}`pc-engines-apu4` board:
+- Sierra Wireless AirPrime MC7304 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7430 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7455 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7710 miniPCIe card (LTE)
+- Huawei ME909u-521 miniPCIe card (LTE)
+- Huawei ME909s-120 miniPCIe card (LTE)
+- HP LT4120 Snapdragon X5 LTE
+
+## Firmware update
+
+WWAN modules include reprogrammable firmware, and most vendors regularly
+provide updates for it.
+
+Since VyOS communicates with these devices via the QMI interface, you can
+update firmware directly within the system using the `qmi-firmware-update`
+utility.
+
+The following example shows how to update the firmware for a Sierra Wireless
+MC7710 module using the provided .cwe file.
+
+```bash
+$ sudo qmi-firmware-update --update -d 1199:68a2 \
+ 9999999_9999999_9200_03.05.14.00_00_generic_000.000_001_SPKG_MC.cwe
+```
diff --git a/docs/configuration/loadbalancing/haproxy.md b/docs/configuration/loadbalancing/haproxy.md
new file mode 100644
index 00000000..d60c5248
--- /dev/null
+++ b/docs/configuration/loadbalancing/haproxy.md
@@ -0,0 +1,510 @@
+---
+lastproofread: '2026-04-06'
+---
+
+# HAproxy
+
+```{include} /_include/need_improvement.txt
+```
+
+HAProxy is a load balancer and proxy server that provides
+high-availability, load balancing, and proxying for TCP (level 4) and
+HTTP-based (level 7) applications.
+
+## Configuration
+
+Service configuration specifies the port to bind to. Backend
+configuration defines the load balancing method and specifies the backend
+servers.
+
+### Service
+
+```{cfgcmd} set load-balancing haproxy service \<name\> listen-address \<address\>
+
+Set the IP address for the service to bind to. By default, the service
+listens on all IPv4 and IPv6 addresses.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> port \<port\>
+
+Create service *<name>* to listen on \<port\>
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> mode \<tcp|http\>
+
+Configure service *<name>* mode TCP or HTTP
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> backend \<name\>
+
+Configure service *<name>* to use the backend \<name\>
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> ssl certificate \<name\>
+
+Set the SSL certificate \<name\> for service \<name\>. You can define
+multiple certificates.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> http-response-headers \<header-name\> value \<header-value\>
+
+Set custom HTTP headers to include in all responses.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> logging facility \<facility\> level \<level\>
+
+Specify facility and level for logging.
+For an explanation on {ref}`syslog_facilities` and
+{ref}`syslog_severity_level`,
+see tables in the syslog configuration section.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> timeout client \<seconds\>
+
+Set the maximum inactivity time on the client side for this service.
+Value range 1-3600 seconds.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> http-compression algorithm \<gzip | deflate | identity | raw-deflate\>
+
+Set the compression algorithm to be used when compressing HTTP responses.
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> http-compression mime-type \<mime-type\>
+
+Set the list of HTTP response MIME types which haproxy will attempt to
+compress, if received uncompressed from backend server.
+```
+
+#### Rules
+
+Rules control and route incoming traffic to specific backends based on
+predefined conditions. Rules define matching criteria and specify actions
+to perform.
+
+```{cfgcmd} set load-balancing haproxy service \<name\> rule \<rule\> domain-name \<name\>
+
+Match domain name
+```
+
+````{cfgcmd} set load-balancing haproxy service \<name\> rule \<rule\> ssl \<sni\>
+
+```{eval-rst}
+SSL match Server Name Indication (SNI) option:
+ * ``req-ssl-sni`` SSL Server Name Indication (SNI) request match
+ * ``ssl-fc-sni`` SSL frontend connection Server Name Indication match
+ * ``ssl-fc-sni-end`` SSL frontend match end of connection Server Name
+
+ Indication
+```
+````
+
+````{cfgcmd} set load-balancing haproxy service \<name\> rule \<rule\> url-path \<match\> \<url\>
+
+Define URL path matching rules for a specific service. Use this command
+to specify how to match the URL path against incoming requests.
+
+```{eval-rst}
+The available options for <match> are:
+ * ``begin`` Matches the beginning of the URL path
+ * ``end`` Matches the end of the URL path.
+ * ``exact`` Matches the URL path exactly.
+```
+````
+
+```{cfgcmd} set load-balancing haproxy service \<name\> rule \<rule\> set backend \<name\>
+
+Assign a specific backend to a rule
+```
+
+```{cfgcmd} set load-balancing haproxy service \<name\> rule \<rule\> redirect-location \<url\>
+
+Redirect URL to a new location.
+```
+
+### Backend
+
+````{cfgcmd} set load-balancing haproxy backend \<name\> balance \<balance\>
+
+Specify the load balancing algorithm for distributing requests among
+available servers.
+
+```{eval-rst}
+Balance algorithms:
+ * ``source-address`` Distributes requests based on the source IP address
+ of the client.
+ * ``round-robin`` Distributes requests in a circular manner,
+ sequentially sending each request to the next server in line.
+ * ``least-connection`` Distributes requests to the server with the fewest
+ active connections.
+```
+````
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> mode \<mode\>
+
+Configure backend *<name>* mode TCP or HTTP.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> address \<x.x.x.x\>
+
+Set the address of the backend server that receives incoming traffic.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> port \<port\>
+
+Set the address of the backend port.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> check
+
+Active health check backend server.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> check port \<port\>
+
+Set an alternative port number for health checks.
+Overrides the default server port used for TCP/HTTP checks.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> send-proxy
+
+Send a Proxy Protocol version 1 header (text format).
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> server \<name\> send-proxy-v2
+
+Send a Proxy Protocol version 2 header (binary format).
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> ssl ca-certificate \<ca-certificate\>
+
+Use SSL encryption for backend requests and authenticate the backend
+against ``<ca-certificate>``.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> ssl no-verify
+
+Use SSL encryption for backend requests without validating the server
+certificate.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> http-response-headers \<header-name\> value \<header-value\>
+
+Set custom HTTP headers to include in all responses from the backend.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> logging facility \<facility\> level \<level\>
+
+Specify facility and level for logging.
+For an explanation on {ref}`syslog_facilities` and
+{ref}`syslog_severity_level`,
+see tables in the syslog configuration section.
+```
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> timeout check \<seconds\>
+
+Set the timeout in seconds for established connections.
+Value range 1-3600 seconds.
+```
+```{cfgcmd} set load-balancing haproxy backend \<name\> timeout connect \<seconds\>
+
+Set the maximum time to wait for a connection attempt to a server to succeed.
+Value range 1-3600 seconds.
+```
+
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> timeout server \<seconds\>
+
+Set the maximum inactivity time on the server side.
+Value range 1-3600 seconds.
+```
+
+### Global
+
+Global configuration parameters:
+
+```{cfgcmd} set load-balancing haproxy global-parameters max-connections \<num\>
+
+Limit maximum number of connections
+```
+
+
+```{cfgcmd} set load-balancing haproxy global-parameters ssl-bind-ciphers \<ciphers\>
+
+Limit the cipher algorithms allowed during SSL/TLS handshake.
+```
+
+
+```{cfgcmd} set load-balancing haproxy global-parameters tls-version-min \<version\>
+
+Specify the minimum required TLS version 1.2 or 1.3
+```
+
+
+```{cfgcmd} set load-balancing haproxy global-parameters logging facility \<facility\> level \<level\>
+
+Specify facility and level for logging.
+For an explanation on {ref}`syslog_facilities` and
+{ref}`syslog_severity_level`,
+see tables in the syslog configuration section.
+```
+
+
+```{cfgcmd} set load-balancing haproxy timeout check \<seconds\>
+
+Set the timeout in seconds for established connections.
+Value range 1-3600 seconds. Default is 5 seconds.
+```
+
+
+```{cfgcmd} set load-balancing haproxy timeout client \<seconds\>
+
+Set the maximum inactivity time on the client side.
+Value range 1-3600 seconds. Default is 50 seconds.
+```
+
+
+```{cfgcmd} set load-balancing haproxy timeout connect \<seconds\>
+
+Set the maximum time to wait for a connection attempt to a server to succeed.
+Value range 1-3600 seconds. Default is 10 seconds.
+```
+
+
+```{cfgcmd} set load-balancing haproxy timeout server \<seconds\>
+
+Set the maximum inactivity time on the server side.
+Value range 1-3600 seconds. Default is 50 seconds.
+```
+
+## Health checks
+
+
+### HTTP checks
+
+
+Use HTTP health checks to monitor web applications that provide health status
+information and determine their availability.
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> http-check
+
+Enables HTTP health checks using OPTION HTTP requests against '/' and
+expecting a successful response code in the 200-399 range.
+```
+
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> http-check method \<method\>
+
+Set the HTTP method: ``OPTION``, ``GET``, ``POST``, or ``PUT``.
+```
+
+
+```{cfgcmd} set load-balancing haproxy backend \<name\> http-check uri \<path\>
+
+Set the endpoint to use for health checks.
+```
+
+
+````{cfgcmd} set load-balancing haproxy backend \<name\> http-check expect \<condition\>
+
+Set the expected result condition for a server to be considered healthy.
+
+```{eval-rst}
+Some possible examples are:
+ * ``status 200`` Expecting a 200 response code
+ * ``status 200-399`` Expecting a non-failure response code
+ * ``string success`` Expecting the string success in the response body
+```
+````
+
+### TCP checks
+
+Configure health checks for TCP mode backends. You can configure protocol-aware
+checks for a range of Layer 7 protocols:
+
+````{cfgcmd} set load-balancing haproxy backend \<name\> health-check \<protocol\>
+
+```{eval-rst}
+Available health check protocols:
+ * ``ldap`` LDAP protocol check.
+ * ``redis`` Redis protocol check.
+ * ``mysql`` MySQL protocol check.
+ * ``pgsql`` PostgreSQL protocol check.
+ * ``smtp`` SMTP protocol check.
+```
+````
+
+:::{note}
+If you specify a server to check but do not configure a
+protocol, HAProxy performs a basic TCP health check. A server is online if
+it responds to a connection attempt with a valid `SYN/ACK` packet.
+:::
+## Redirect HTTP to HTTPS
+
+Configure a HAProxy service for HTTP that listens on port 80 and redirects
+incoming requests to HTTPS:
+
+```none
+set load-balancing haproxy service http port '80'
+set load-balancing haproxy service http redirect-http-to-https
+```
+
+You can use a different service name; in this example, `http` is just for
+convenience.
+
+## Examples
+### Level 4 balancing
+
+This configuration enables the TCP reverse proxy for the `my-tcp-api`
+service. Incoming TCP connections on port 8888 are load balanced across the
+backend servers (srv01 and srv02) using the round-robin load balancing
+algorithm.
+
+```none
+set load-balancing haproxy service my-tcp-api backend 'bk-01'
+set load-balancing haproxy service my-tcp-api mode 'tcp'
+set load-balancing haproxy service my-tcp-api port '8888'
+
+set load-balancing haproxy backend bk-01 balance 'round-robin'
+set load-balancing haproxy backend bk-01 mode 'tcp'
+
+set load-balancing haproxy backend bk-01 server srv01 address '192.0.2.11'
+set load-balancing haproxy backend bk-01 server srv01 port '8881'
+set load-balancing haproxy backend bk-01 server srv02 address '192.0.2.12'
+set load-balancing haproxy backend bk-01 server srv02 port '8882'
+```
+
+### Balancing based on domain name
+
+The following configuration demonstrates how to use VyOS
+to achieve load balancing based on the domain name:
+
+The HTTP service listens on TCP port 80.
+
+Rule 10 matches requests with the domain name `node1.example.com` and
+forwards them to the backend `bk-api-01`.
+
+Rule 20 matches requests with the domain name `node2.example.com` and
+forwards them to the backend `bk-api-02`.
+
+```none
+set load-balancing haproxy service http description 'bind app listen on 443 port'
+set load-balancing haproxy service http mode 'tcp'
+set load-balancing haproxy service http port '80'
+
+set load-balancing haproxy service http rule 10 domain-name 'node1.example.com'
+set load-balancing haproxy service http rule 10 set backend 'bk-api-01'
+set load-balancing haproxy service http rule 20 domain-name 'node2.example.com'
+set load-balancing haproxy service http rule 20 set backend 'bk-api-02'
+
+set load-balancing haproxy backend bk-api-01 description 'My API-1'
+set load-balancing haproxy backend bk-api-01 mode 'tcp'
+set load-balancing haproxy backend bk-api-01 server api01 address '127.0.0.1'
+set load-balancing haproxy backend bk-api-01 server api01 port '4431'
+set load-balancing haproxy backend bk-api-02 description 'My API-2'
+set load-balancing haproxy backend bk-api-02 mode 'tcp'
+set load-balancing haproxy backend bk-api-02 server api01 address '127.0.0.2'
+set load-balancing haproxy backend bk-api-02 server api01 port '4432'
+```
+
+### Terminate SSL
+
+The following configuration terminates SSL on the router.
+
+The `http` service listens on port 80 and redirects HTTP requests to
+HTTPS.
+
+The `https` service listens on port 443 with the `bk-default` backend
+and handles HTTPS traffic using the `cert` certificate for SSL termination.
+The HSTS header is set with a 1-year expiry to tell browsers to always use
+SSL for the site.
+
+Rule 10 matches requests with the exact URL path `/.well-known/xxx` and
+redirects them to `/certs/`.
+
+Rule 20 matches requests with URL paths ending in `/mail` or the exact
+path `/email/bar` and redirects them to `/postfix/`.
+
+Global parameters include a maximum connection limit of 4000 and a minimum
+TLS version of 1.3.
+
+```none
+set load-balancing haproxy service http description 'Force redirect to HTTPS'
+set load-balancing haproxy service http port '80'
+set load-balancing haproxy service http redirect-http-to-https
+
+set load-balancing haproxy service https backend 'bk-default'
+set load-balancing haproxy service https description 'listen on 443 port'
+set load-balancing haproxy service https mode 'http'
+set load-balancing haproxy service https port '443'
+set load-balancing haproxy service https ssl certificate 'cert'
+set load-balancing haproxy service https http-response-headers Strict-Transport-Security value 'max-age=31536000'
+
+set load-balancing haproxy service https rule 10 url-path exact '/.well-known/xxx'
+set load-balancing haproxy service https rule 10 set redirect-location '/certs/'
+set load-balancing haproxy service https rule 20 url-path end '/mail'
+set load-balancing haproxy service https rule 20 url-path exact '/email/bar'
+set load-balancing haproxy service https rule 20 set redirect-location '/postfix/'
+
+set load-balancing haproxy backend bk-default description 'Default backend'
+set load-balancing haproxy backend bk-default mode 'http'
+set load-balancing haproxy backend bk-default server sr01 address '192.0.2.23'
+set load-balancing haproxy backend bk-default server sr01 port '80'
+
+set load-balancing haproxy global-parameters max-connections '4000'
+set load-balancing haproxy global-parameters tls-version-min '1.3'
+```
+
+### SSL Bridging
+
+The following configuration terminates incoming HTTPS traffic on the router,
+then re-encrypts the traffic and sends it to the backend server via HTTPS.
+Use this when encryption is required for both paths but you do not want to
+install publicly trusted certificates on each backend server.
+
+Backend service certificates are checked against the certificate authority
+specified in the configuration, which could be an internal CA.
+
+The `https` service listens on port 443 with backend `bk-bridge-ssl` to
+handle HTTPS traffic. It uses certificate named `cert` for SSL termination.
+
+The `bk-bridge-ssl` backend connects to `sr01` server on port 443 via HTTPS
+and checks backend server has a valid certificate trusted by CA `cacert`
+
+```none
+set load-balancing haproxy service https backend 'bk-bridge-ssl'
+set load-balancing haproxy service https description 'listen on 443 port'
+set load-balancing haproxy service https mode 'http'
+set load-balancing haproxy service https port '443'
+set load-balancing haproxy service https ssl certificate 'cert'
+
+set load-balancing haproxy backend bk-bridge-ssl description 'SSL backend'
+set load-balancing haproxy backend bk-bridge-ssl mode 'http'
+set load-balancing haproxy backend bk-bridge-ssl ssl ca-certificate 'cacert'
+set load-balancing haproxy backend bk-bridge-ssl server sr01 address '192.0.2.23'
+set load-balancing haproxy backend bk-bridge-ssl server sr01 port '443'
+```
+
+### Balancing with HTTP health checks
+
+This configuration enables HTTP health checks for backend servers.
+
+```none
+set load-balancing haproxy service my-tcp-api backend 'bk-01'
+set load-balancing haproxy service my-tcp-api mode 'tcp'
+set load-balancing haproxy service my-tcp-api port '8888'
+
+set load-balancing haproxy backend bk-01 balance 'round-robin'
+set load-balancing haproxy backend bk-01 mode 'tcp'
+
+set load-balancing haproxy backend bk-01 http-check method 'get'
+set load-balancing haproxy backend bk-01 http-check uri '/health'
+set load-balancing haproxy backend bk-01 http-check expect 'status 200'
+
+set load-balancing haproxy backend bk-01 server srv01 address '192.0.2.11'
+set load-balancing haproxy backend bk-01 server srv01 port '8881'
+set load-balancing haproxy backend bk-01 server srv01 check
+set load-balancing haproxy backend bk-01 server srv02 address '192.0.2.12'
+set load-balancing haproxy backend bk-01 server srv02 port '8882'
+set load-balancing haproxy backend bk-01 server srv02 check port '8892'
+```
diff --git a/docs/configuration/loadbalancing/index.md b/docs/configuration/loadbalancing/index.md
new file mode 100644
index 00000000..3241edb7
--- /dev/null
+++ b/docs/configuration/loadbalancing/index.md
@@ -0,0 +1,15 @@
+---
+lastproofread: '2026-04-06'
+---
+
+(load-balancing)=
+
+# Load-balancing
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+wan
+haproxy
+```
diff --git a/docs/configuration/loadbalancing/wan.md b/docs/configuration/loadbalancing/wan.md
new file mode 100644
index 00000000..a19bbfae
--- /dev/null
+++ b/docs/configuration/loadbalancing/wan.md
@@ -0,0 +1,306 @@
+---
+lastproofread: '2026-04-06'
+---
+
+# WAN load balancing
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+The load balancer distributes outbound traffic across two or more
+interfaces. If a path fails, the load balancer balances traffic across the
+remaining healthy paths. When a path recovers, it is automatically added back
+to the routing table. The load balancer adds routes for each path and
+distributes traffic based on interface health and weight.
+
+In a minimal configuration, the following must be provided:
+> - An interface with a `nexthop`.
+> - One rule with a LAN (inbound-interface) and the WAN (interface).
+
+The following examples uses two DHCP WAN interfaces and one LAN (`eth2`):
+
+```none
+set load-balancing wan interface-health eth0 nexthop 'dhcp'
+set load-balancing wan interface-health eth1 nexthop 'dhcp'
+set load-balancing wan rule 1 inbound-interface 'eth2'
+set load-balancing wan rule 1 interface eth0
+set load-balancing wan rule 1 interface eth1
+```
+
+:::{note}
+Do not use WAN load balancing with dynamic routing protocols. This
+feature creates customized routing tables and firewall rules that are
+incompatible with routing protocols.
+:::
+
+## Load balancing rules
+
+You define interfaces, their weight, and the traffic type to balance in
+numbered rule sets. The load balancer executes rules in numerical order
+against outgoing packets. When a packet matches a rule, it is sent through the
+specified interface. Packets that do not match any rule use the system routing
+table. You cannot change rule numbers.
+
+Create a load balancing rule, it can be a number between 1 and 9999:
+
+```none
+vyos@vyos# set load-balancing wan rule 1
+Possible completions:
+description Description for this rule
+> destination Destination
+exclude Exclude packets matching this rule from wan load balance
+failover Enable failover for packets matching this rule from wan load balance
+inbound-interface Inbound interface name (e.g., "eth0") [REQUIRED]
++> interface Interface name [REQUIRED]
+> limit Enable packet limit for this rule
+per-packet-balancing Option to match traffic per-packet instead of the default, per-flow
+protocol Protocol to match
+> source Source information
+```
+
+
+### Interface weight
+
+By default, the load balancer distributes outbound
+traffic randomly across available interfaces. You can assign weights to
+interfaces to influence the distribution. If `eth0` has more bandwidth
+than `eth1`, you can assign a higher weight to `eth0` to send more
+traffic through it:
+
+```none
+set load-balancing wan rule 1 interface eth0 weight 2
+set load-balancing wan rule 1 interface eth1 weight 1
+```
+
+In this example,\`\`eth0\`\` receives 66% of traffic, and `eth1` receives
+33% of traffic.
+
+### Rate limit
+
+Set a packet rate limit for a rule to apply it to traffic above or below a
+specified threshold. To configure rate limiting, use:
+
+```none
+set load-balancing wan rule <rule> limit <parameter>
+```
+
+- `burst`: Number of packets allowed to overshoot the limit within `period`.
+ Default 5.
+- `period`: Time window for rate calculation. Possible values:
+ `second` (one second), `minute` (one minute), `hour` (one hour).
+ Default is `second`.
+- `rate`: Number of packets. Default: `5`.
+- `threshold`: `below` or `above` the specified rate limit.
+
+### Flow and packet-based balancing
+
+The load balancer balances outgoing traffic by flow. A connection tracking
+table tracks flows by source address, destination address, and port. Each
+flow is assigned to an interface based on the balancing rules, and subsequent
+packets use the same interface. This ensures packets arrive in order when links
+have different speeds.
+
+Packet-based balancing can improve balance across interfaces when packet
+order is not critical. Enable per-packet balancing for a rule with:
+
+```none
+set load-balancing wan rule <rule> per-packet-balancing
+```
+
+
+### Exclude traffic
+
+To exclude traffic from load balancing, traffic matching an exclude rule
+bypasses load balancing and uses the system routing table instead:
+
+```none
+set load-balancing wan rule <rule> exclude
+```
+
+
+## Health checks
+
+The load balancer periodically checks the health of interfaces and paths by
+sending ICMP packets (ping) to remote destinations, performing TTL tests, or
+executing a user-defined script. If an interface fails the health check, the
+load balancer removes it from its interface pool.
+To enable health checking for an interface:
+
+```none
+vyos@vyos# set load-balancing wan interface-health <interface>
+Possible completions:
+failure-count Failure count
+nexthop Outbound interface nexthop address. Can be 'dhcp or ip address' [REQUIRED]
+success-count Success count
++> test Rule number
+```
+
+Specify the nexthop on the path to the destination. You can set
+`ipv4-address` to `dhcp`.
+
+```none
+set load-balancing wan interface-health <interface> nexthop <ipv4-address>
+```
+
+Set the number of health check failures before the load balancer marks an
+interface as unavailable (range 1-10, default 1). Or set the number of
+successful health checks before adding an interface back to the pool
+(range 1-10, default 1).
+
+```none
+set load-balancing wan interface-health <interface> failure-count <number>
+set load-balancing wan interface-health <interface> success-count <number>
+```
+
+Configure each health check in its own test. Tests are numbered and processed
+in numeric order. You can define multiple tests for multi-target health
+checking:
+
+```none
+vyos@vyos# set load-balancing wan interface-health eth1 test 0
+Possible completions:
+resp-time Ping response time (seconds)
+target Health target address
+test-script Path to user defined script
+ttl-limit Ttl limit (hop count)
+type WLB test type
+```
+
+- `resp-time`: The maximum response time for ping in seconds. Range
+ 1-30, default `5`.
+- `target`: The target to receive ICMP packets. The address can be an IPv4
+ address or hostname.
+- `test-script`: A user-defined script must return 0 to succeed and
+ non-zero to fail. Scripts reside in `/config/scripts`. For other locations,
+ provide the full path.
+- `ttl-limit`: For the UDP TTL limit test, specify the hop count limit.
+ The limit must be shorter than the path length. The test succeeds when an
+ ICMP time-expired message is returned. Default `1`.
+- `type`: Specify the test type: `ping`, `ttl`, or a user-defined
+ script.
+
+## Source NAT rules
+
+By default, interfaces in a load balancing pool replace the source IP of
+each outgoing packet with their own address to ensure replies arrive on the
+same interface. The load balancer handles this through automatically generated
+Source NAT (SNAT) rules applied only to balanced traffic. To disable the
+automatic generation of SNAT rules when this behavior is not desired, use:
+
+```none
+set load-balancing wan disable-source-nat
+```
+
+
+## Sticky connections
+
+Inbound connections to a WAN interface can be improperly handled when
+replies are sent back to the client.
+
+```{image} /_static/images/sticky-connections.webp
+:align: center
+:width: 80%
+```
+
+When responding to an incoming packet, you may want to ensure the response
+leaves from the same interface as the incoming packet. Enable sticky
+connections in the load balancer to do this:
+
+```none
+set load-balancing wan sticky-connections inbound
+```
+
+
+## Failover
+
+In failover mode, one interface is primary and other interfaces are
+secondary or spare. The load balancer uses only the primary interface. If it
+fails, a secondary interface from the available pool takes over. The load
+balancer selects the primary interface based on its weight and health. Other
+interfaces become secondary. Secondary interfaces are chosen based on their
+weight and health. You can also select interface roles based on rule order by
+including interfaces in balancing rules and ordering those rules accordingly.
+To enable failover mode, create a failover rule:
+
+```none
+set load-balancing wan rule <number> failover
+```
+
+Existing sessions do not automatically fail over to a new path. Flush the
+session table on each connection state change to enable failover:
+
+```none
+set load-balancing wan flush-connections
+```
+
+:::{warning}
+Flushing the session table causes other connections to revert from
+flow-based to packet-based balancing until each flow is reestablished.
+:::
+
+## Script execution
+
+Run a script when an interface state changes. Scripts run from the
+`/config/scripts` directory. To use a script in another location,
+specify the full path:
+
+```none
+set load-balancing wan hook script-name
+```
+
+Two environment variables are available:
+- `WLB_INTERFACE_NAME=[interfacename]`: Interface to be monitored
+- `WLB_INTERFACE_STATE=[ACTIVE|FAILED]`: Interface state
+
+:::{warning}
+Blocking call with no timeout: VyOS becomes unresponsive if the
+script does not return.
+:::
+
+## Handling and monitoring
+
+The following command shows WAN load balancer information including test
+types and targets. The character at the start of each line indicates the test
+state:
+- `+` successful.
+- `-` failed.
+- A blank indicates that no test has been carried out.
+
+```none
+vyos@vyos:~$ show wan-load-balance
+Interface: eth0
+Status: failed
+Last Status Change: Tue Jun 11 20:12:19 2019
+-Test: ping Target:
+ Last Interface Success: 55s
+ Last Interface Failure: 0s
+ # Interface Failure(s): 5
+
+Interface: eth1
+Status: active
+Last Status Change: Tue Jun 11 20:06:42 2019
++Test: ping Target:
+ Last Interface Success: 0s
+ Last Interface Failure: 6m26s
+ # Interface Failure(s): 0
+```
+
+Show connection data of load balanced traffic:
+
+```none
+vyos@vyos:~$ show wan-load-balance connection
+conntrack v1.4.2 (conntrack-tools): 3 flow entries have been shown.
+Type State Src Dst Packets Bytes
+tcp TIME_WAIT 10.1.1.13:38040 203.0.113.2:80 203.0.113.2 192.168.188.71
+udp 10.1.1.13:41891 198.51.100.3:53 198.51.100.3 192.168.188.71
+udp 10.1.1.13:55437 198.51.100.3:53 198.51.100.3 192.168.188.71
+```
+
+
+### Restart
+
+```none
+restart wan-load-balance
+```
diff --git a/docs/configuration/nat/cgnat.md b/docs/configuration/nat/cgnat.md
new file mode 100644
index 00000000..914a466b
--- /dev/null
+++ b/docs/configuration/nat/cgnat.md
@@ -0,0 +1,200 @@
+(cgnat)=
+
+# CGNAT
+
+{abbr}`CGNAT (Carrier-Grade Network Address Translation)` , also known as
+Large-Scale NAT (LSN), is a type of network address translation used by
+Internet Service Providers (ISPs) to enable multiple private IP addresses to
+share a single public IP address. This technique helps to conserve the limited
+IPv4 address space.
+The 100.64.0.0/10 address block is reserved for use in carrier-grade NAT
+
+## Overview
+
+CGNAT works by placing a NAT device within the ISP's network. This device
+translates private IP addresses from customer networks to a limited pool of
+public IP addresses assigned to the ISP. This allows many customers to share a
+smaller number of public IP addresses.
+
+Not all {rfc}`6888` requirements are implemented in CGNAT.
+
+Implemented the following {rfc}`6888` requirements:
+
+- REQ 2: A CGN must have a default "IP address pooling" behavior of "Paired".
+ CGN must use the same external IP address mapping for all sessions associated
+ with the same internal IP address, be they TCP, UDP, ICMP, something else,
+ or a mix of different protocols.
+- REQ 3: The CGN function should not have any limitations on the size or the
+ contiguity of the external address pool.
+- REQ 4: A CGN must support limiting the number of external ports (or,
+ equivalently, "identifiers" for ICMP) that are assigned per subscriber
+
+### Advantages of CGNAT
+
+- **IPv4 Address Conservation**: CGNAT helps mitigate the exhaustion of IPv4 addresses by allowing multiple customers to share a single public IP address.
+- **Scalability**: ISPs can support more customers without needing a proportional increase in public IP addresses.
+- **Cost-Effective**: Reduces the cost associated with acquiring additional public IPv4 addresses.
+
+### Considerations
+
+- **Traceability Issues**: Since multiple users share the same public IP address, tracking individual users for security and legal purposes can be challenging.
+- **Performance Overheads**: The translation process can introduce latency and potential performance bottlenecks, especially under high load.
+- **Application Compatibility**: Some applications and protocols may not work well with CGNAT due to their reliance on unique public IP addresses.
+- **Port Allocation Limits**: Each public IP address has a limited number of ports, which can be exhausted, affecting the ability to establish new connections.
+- **Port Control Protocol**: PCP is not implemented.
+
+## Port calculation
+
+When implementing CGNAT, ensuring that there are enough ports allocated per subscriber is critical. Below is a summary based on RFC 6888.
+
+1. **Total Ports Available**:
+
+ - Total Ports: 65536 (0 to 65535)
+ - Reserved Ports: Assume 1024 ports are reserved for well-known services and administrative purposes.
+ - Usable Ports: 65536 - 1024 = 64512
+
+2. **Estimate Ports Needed per Subscriber**:
+
+ - Example: A household might need 1000 ports to ensure smooth operation for multiple devices and applications.
+
+3. **Calculate the Number of Subscribers per Public IP**:
+
+ - Usable Ports / Ports per Subscriber
+ - 64512 / 1000 ≈ 64 subscribers per public IP
+
+## Configuration
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> external-port-range \<port-range\>
+
+Set an external port-range for the external pool, the default range is
+1024-65535. Multiple entries can be added to the same pool.
+```
+
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> per-user-limit port \<num\>
+
+Set external source port limits that will be allocated to each subscriber
+individually. The default value is 2000.
+```
+
+
+```{cfgcmd} set nat cgnat pool external \<pool-name\> range [address | address range | network] [seq]
+
+Set the range of external IP addresses for the CGNAT pool.
+The sequence is optional; if set, a lower value means higher priority.
+```
+
+
+```{cfgcmd} set nat cgnat pool internal \<pool-name\> range [address range | network]
+
+Set the range of internal IP addresses for the CGNAT pool.
+```
+
+
+```{cfgcmd} set nat cgnat rule \<num\> source pool \<internal-pool-name\>
+
+Set the rule for the source pool.
+```
+
+
+```{cfgcmd} set nat cgnat rule \<num\> translation pool \<external-pool-name\>
+
+Set the rule for the translation pool.
+```
+
+
+```{cfgcmd} set nat cgnat log-allocation
+
+Enable logging of IP address and ports allocations.
+```
+
+
+## Configuration Examples
+
+### Single external address
+
+Example of setting up a basic CGNAT configuration:
+In the following example, we define an external pool named `ext-1` with one
+external IP address.
+
+Each subscriber will be allocated a maximum of 2000 ports from the external pool.
+
+```none
+set nat cgnat pool external ext1 external-port-range '1024-65535'
+set nat cgnat pool external ext1 per-user-limit port '2000'
+set nat cgnat pool external ext1 range '192.0.2.222/32'
+set nat cgnat pool internal int1 range '100.64.0.0/28'
+set nat cgnat rule 10 source pool 'int1'
+set nat cgnat rule 10 translation pool 'ext1'
+```
+
+
+### Multiple external addresses
+
+```none
+set nat cgnat pool external ext1 external-port-range '1024-65535'
+set nat cgnat pool external ext1 per-user-limit port '8000'
+set nat cgnat pool external ext1 range '192.0.2.1-192.0.2.2'
+set nat cgnat pool external ext1 range '203.0.113.253-203.0.113.254'
+set nat cgnat pool internal int1 range '100.64.0.1-100.64.0.32'
+set nat cgnat rule 10 source pool 'int1'
+set nat cgnat rule 10 translation pool 'ext1'
+```
+
+
+### External address sequences
+
+```none
+set nat cgnat pool external ext-01 per-user-limit port '16000'
+set nat cgnat pool external ext-01 range 203.0.113.1/32 seq '10'
+set nat cgnat pool external ext-01 range 192.0.2.1/32 seq '20'
+set nat cgnat pool internal int-01 range '100.64.0.0/29'
+set nat cgnat rule 10 source pool 'int-01'
+set nat cgnat rule 10 translation pool 'ext-01'
+```
+
+
+## Operation commands
+
+```{opcmd} show nat cgnat allocation
+
+Show address and port allocations
+```
+
+```{opcmd} show nat cgnat allocation external-address \<address\>
+
+Show all allocations for an external IP address
+```
+
+```{opcmd} show nat cgnat allocation internal-address \<address\>
+
+Show all allocations for an internal IP address
+```
+
+
+### Show CGNAT allocations
+
+```none
+vyos@vyos:~$ show nat cgnat allocation
+Internal IP External IP Port range
+------------- ------------- ------------
+100.64.0.0 203.0.113.1 1024-17023
+100.64.0.1 203.0.113.1 17024-33023
+100.64.0.2 203.0.113.1 33024-49023
+100.64.0.3 203.0.113.1 49024-65023
+100.64.0.4 192.0.2.1 1024-17023
+100.64.0.5 192.0.2.1 17024-33023
+100.64.0.6 192.0.2.1 33024-49023
+100.64.0.7 192.0.2.1 49024-65023
+
+vyos@vyos:~$ show nat cgnat allocation internal-address 100.64.0.4
+Internal IP External IP Port range
+------------- ------------- ------------
+100.64.0.4 192.0.2.1 1024-17023
+```
+
+
+## Further Reading
+
+- {rfc}`6598` - IANA-Reserved IPv4 Prefix for Shared Address Space
+- {rfc}`6888` - Requirements for CGNAT
diff --git a/docs/configuration/nat/index.md b/docs/configuration/nat/index.md
new file mode 100644
index 00000000..35e5d32b
--- /dev/null
+++ b/docs/configuration/nat/index.md
@@ -0,0 +1,13 @@
+(nat)=
+
+# NAT
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+nat44
+nat64
+nat66
+cgnat
+```
diff --git a/docs/configuration/nat/nat44.md b/docs/configuration/nat/nat44.md
new file mode 100644
index 00000000..4f5bd580
--- /dev/null
+++ b/docs/configuration/nat/nat44.md
@@ -0,0 +1,788 @@
+(nat44)=
+
+# NAT44
+
+{abbr}`NAT (Network Address Translation)` is a common method of
+remapping one IP address space into another by modifying network address
+information in the IP header of packets while they are in transit across
+a traffic routing device. The technique was originally used as a
+shortcut to avoid the need to readdress every host when a network was
+moved. It has become a popular and essential tool in conserving global
+address space in the face of IPv4 address exhaustion. One
+Internet-routable IP address of a NAT gateway can be used for an entire
+private network.
+
+IP masquerading is a technique that hides an entire IP address space,
+usually consisting of private IP addresses, behind a single IP address
+in another, usually public address space. The hidden addresses are
+changed into a single (public) IP address as the source address of the
+outgoing IP packets so they appear as originating not from the hidden
+host but from the routing device itself. Because of the popularity of
+this technique to conserve IPv4 address space, the term NAT has become
+virtually synonymous with IP masquerading.
+
+As network address translation modifies the IP address information in
+packets, NAT implementations may vary in their specific behavior in
+various addressing cases and their effect on network traffic. The
+specifics of NAT behavior are not commonly documented by vendors of
+equipment containing NAT implementations.
+
+The computers on an internal network can use any of the addresses set
+aside by the {abbr}`IANA (Internet Assigned Numbers Authority)` for
+private addressing (see {rfc}`1918`). These reserved IP addresses are
+not in use on the Internet, so an external machine will not directly
+route to them. The following addresses are reserved for private use:
+
+- 10.0.0.0 to 10.255.255.255 (CIDR: 10.0.0.0/8)
+- 172.16.0.0 to 172.31.255.255 (CIDR: 172.16.0.0/12)
+- 192.168.0.0 to 192.168.255.255 (CIDR: 192.168.0.0/16)
+
+If an ISP deploys a {abbr}`CGN (Carrier-grade NAT)`, and uses
+{rfc}`1918` address space to number customer gateways, the risk of
+address collision, and therefore routing failures, arises when the
+customer network already uses an {rfc}`1918` address space.
+
+This prompted some ISPs to develop a policy within the {abbr}`ARIN
+(American Registry for Internet Numbers)` to allocate new private
+address space for CGNs, but ARIN deferred to the IETF before
+implementing the policy indicating that the matter was not a typical
+allocation issue but a reservation of addresses for technical purposes
+(per {rfc}`2860`).
+
+IETF published {rfc}`6598`, detailing a shared address space for use in
+ISP CGN deployments that can handle the same network prefixes occurring
+both on inbound and outbound interfaces. ARIN returned address space to
+the {abbr}`IANA (Internet Assigned Numbers Authority)` for this
+allocation.
+
+The allocated address block is 100.64.0.0/10.
+
+Devices evaluating whether an IPv4 address is public must be updated to
+recognize the new address space. Allocating more private IPv4 address
+space for NAT devices might prolong the transition to IPv6.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat)=
+
+#### SNAT
+
+{abbr}`SNAT (Source Network Address Translation)` is the most common
+form of {abbr}`NAT (Network Address Translation)` and is typically
+referred to simply as NAT. To be more correct, what most people refer
+to as {abbr}`NAT (Network Address Translation)` is actually the process
+of {abbr}`PAT (Port Address Translation)`, or NAT overload. SNAT is
+typically used by internal users/private hosts to access the Internet
+\- the source address is translated and thus kept private.
+
+(destination-nat)=
+
+#### DNAT
+
+{abbr}`DNAT (Destination Network Address Translation)` changes the
+destination address of packets passing through the router, while
+{ref}`source-nat` changes the source address of packets. DNAT is
+typically used when an external (public) host needs to initiate a
+session with an internal (private) host. A customer needs to access a
+private service behind the routers public IP. A connection is
+established with the routers public IP address on a well known port and
+thus all traffic for this port is rewritten to address the internal
+(private) host.
+
+(bidirectional-nat)=
+
+#### Bidirectional NAT
+
+This is a common scenario where both {ref}`source-nat` and
+{ref}`destination-nat` are configured at the same time. It's commonly
+used when internal (private) hosts need to establish a connection with
+external resources and external systems need to access internal
+(private) resources.
+
+### NAT, Routing, Firewall Interaction
+
+There is a very nice picture/explanation in the Vyatta documentation
+which should be rewritten here.
+
+### NAT Ruleset
+
+{abbr}`NAT (Network Address Translation)` is configured entirely on a
+series of so called *rules*. Rules are numbered and evaluated by the
+underlying OS in numerical order! The rule numbers can be changes by
+utilizing the {cfgcmd}`rename` and {cfgcmd}`copy` commands.
+
+:::{note}
+Changes to the NAT system only affect newly established
+connections. Already established connections are not affected.
+:::
+
+:::{hint}
+When designing your NAT ruleset leave some space between
+consecutive rules for later extension. Your ruleset could start with
+numbers 10, 20, 30. You thus can later extend the ruleset and place
+new rules between existing ones.
+:::
+
+Rules will be created for both {ref}`source-nat` and
+{ref}`destination-nat`.
+
+For {ref}`bidirectional-nat` a rule for both {ref}`source-nat` and
+{ref}`destination-nat` needs to be created.
+
+(traffic-filters)=
+
+### Traffic Filters
+
+Traffic Filters are used to control which packets will have the defined
+NAT rules applied. Five different filters can be applied within a NAT
+rule.
+
+- **outbound-interface** - applicable only to {ref}`source-nat`. It
+ configures the interface which is used for the outside traffic that
+ this translation rule applies to. Interface groups, inverted
+ selection and wildcard, are also supported.
+
+ Examples:
+
+ ```none
+ set nat source rule 20 outbound-interface name eth0
+ set nat source rule 30 outbound-interface name bond1*
+ set nat source rule 20 outbound-interface name !vtun2
+ set nat source rule 20 outbound-interface group GROUP1
+ set nat source rule 20 outbound-interface group !GROUP2
+ ```
+
+- **inbound-interface** - applicable only to {ref}`destination-nat`. It
+ configures the interface which is used for the inside traffic the
+ translation rule applies to. Interface groups, inverted
+ selection and wildcard, are also supported.
+
+ Example:
+
+ ```none
+ set nat destination rule 20 inbound-interface name eth0
+ set nat destination rule 30 inbound-interface name bond1*
+ set nat destination rule 20 inbound-interface name !vtun2
+ set nat destination rule 20 inbound-interface group GROUP1
+ set nat destination rule 20 inbound-interface group !GROUP2
+ ```
+
+- **protocol** - specify which types of protocols this translation rule
+ applies to. Only packets matching the specified protocol are NATed.
+ By default this applies to *all* protocols.
+
+ Example:
+
+ - Set SNAT rule 20 to only NAT TCP and UDP packets
+ - Set DNAT rule 20 to only NAT UDP packets
+
+ ```none
+ set nat source rule 20 protocol tcp_udp
+ set nat destination rule 20 protocol udp
+ ```
+
+- **source** - specifies which packets the NAT translation rule applies
+ to based on the packets source IP address and/or source port. Only
+ matching packets are considered for NAT.
+
+ Example:
+
+ - Set SNAT rule 20 to only NAT packets arriving from the 192.0.2.0/24
+ network
+ - Set SNAT rule 30 to only NAT packets arriving from the 203.0.113.0/24
+ network with a source port of 80 and 443
+
+ ```none
+ set nat source rule 20 source address 192.0.2.0/24
+ set nat source rule 30 source address 203.0.113.0/24
+ set nat source rule 30 source port 80,443
+ ```
+
+- **destination** - specify which packets the translation will be
+ applied to, only based on the destination address and/or port number
+ configured.
+
+ :::{note}
+ If no destination is specified the rule will match on any
+ destination address and port.
+ :::
+
+ Example:
+
+ - Configure SNAT rule (40) to only NAT packets with a destination
+ address of 192.0.2.1.
+
+ ```none
+ set nat source rule 40 destination address 192.0.2.1
+ ```
+
+### Address Conversion
+
+Every NAT rule has a translation command defined. The address defined
+for the translation is the address used when the address information in
+a packet is replaced.
+
+#### Source Address
+
+For {ref}`source-nat` rules the packets source address will be replaced
+with the address specified in the translation command. A port
+translation can also be specified and is part of the translation
+address.
+
+:::{note}
+The translation address must be set to one of the available
+addresses on the configured *outbound-interface* or it must be set to
+*masquerade* which will use the primary IP address of the
+*outbound-interface* as its translation address.
+:::
+
+:::{note}
+When using NAT for a large number of host systems it
+recommended that a minimum of 1 IP address is used to NAT every 256
+private host systems. This is due to the limit of 65,000 port numbers
+available for unique translations and a reserving an average of
+200-300 sessions per host system.
+:::
+
+Example:
+
+- Define a discrete source IP address of 100.64.0.1 for SNAT rule 20
+- Use address *masquerade* (the interfaces primary address) on rule 30
+- For a large amount of private machines behind the NAT your address
+ pool might to be bigger. Use any address in the range 100.64.0.10 -
+ 100.64.0.20 on SNAT rule 40 when doing the translation
+
+```none
+set nat source rule 20 translation address 100.64.0.1
+set nat source rule 30 translation address 'masquerade'
+set nat source rule 40 translation address 100.64.0.10-100.64.0.20
+```
+
+#### Destination Address
+
+For {ref}`destination-nat` rules the packets destination address will be
+replaced by the specified address in the *translation address* command.
+
+Example:
+
+- DNAT rule 10 replaces the destination address of an inbound packet
+ with 192.0.2.10
+
+```none
+set nat destination rule 10 translation address 192.0.2.10
+```
+
+Also, in {ref}`destination-nat`, redirection to localhost is supported.
+The redirect statement is a special form of dnat which always translates
+the destination address to the local host’s one.
+
+Example of redirection:
+
+```none
+set nat destination rule 10 translation redirect port 22
+```
+
+### NAT Load Balance
+
+Advanced configuration can be used in order to apply source or destination NAT,
+and within a single rule, be able to define multiple translated addresses,
+so NAT balances the translations among them.
+
+NAT Load Balance uses an algorithm that generates a hash and based on it, then
+it applies corresponding translation. This hash can be generated randomly, or
+can use data from the ip header: source-address, destination-address,
+source-port and/or destination-port. By default, it will generate the hash
+randomly.
+
+When defining the translated address, called `backends`, a `weight` must
+be configured. This lets the user define load balance distribution according
+to their needs. Them sum of all the weights defined for the backends should
+be equal to 100. In oder words, the weight defined for the backend is the
+percentage of the connections that will receive such backend.
+
+```{cfgcmd} set nat [source | destination] rule \<rule\> load-balance hash [source-address | destination-address | source-port | destination-port | random]
+```
+
+```{cfgcmd} set nat [source | destination] rule \<rule\> load-balance backend \<x.x.x.x\> weight \<1-100\>
+```
+
+## Configuration Examples
+
+To setup SNAT, we need to know:
+- The internal IP addresses we want to translate
+- The outgoing interface to perform the translation on
+- The external IP address to translate to
+
+In the example used for the Quick Start configuration above, we
+demonstrate the following configuration:
+
+```none
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 source address '192.168.0.0/24'
+set nat source rule 100 translation address 'masquerade'
+```
+
+Which generates the following configuration:
+
+```none
+rule 100 {
+ outbound-interface {
+ name eth0
+ }
+ source {
+ address 192.168.0.0/24
+ }
+ translation {
+ address masquerade
+ }
+}
+```
+
+In this example, we use **masquerade** as the translation address
+instead of an IP address. The **masquerade** target is effectively an
+alias to say "use whatever IP address is on the outgoing interface",
+rather than a statically configured IP address. This is useful if you
+use DHCP for your outgoing interface and do not know what the external
+address will be.
+
+When using NAT for a large number of host systems it recommended that a
+minimum of 1 IP address is used to NAT every 256 host systems. This is
+due to the limit of 65,000 port numbers available for unique
+translations and a reserving an average of 200-300 sessions per host
+system.
+
+Example: For an ~8,000 host network a source NAT pool of 32 IP addresses
+is recommended.
+
+A pool of addresses can be defined by using a hyphen between two IP
+addresses:
+
+```none
+set nat source rule 100 translation address '203.0.113.32-203.0.113.63'
+```
+
+(avoidng-leaky-nat)=
+
+### Avoiding "leaky" NAT
+
+Linux netfilter will not NAT traffic marked as INVALID. This often
+confuses people into thinking that Linux (or specifically VyOS) has a
+broken NAT implementation because non-NATed traffic is seen leaving an
+external interface. This is actually working as intended, and a packet
+capture of the "leaky" traffic should reveal that the traffic is either
+an additional TCP "RST", "FIN,ACK", or "RST,ACK" sent by client systems
+after Linux netfilter considers the connection closed. The most common
+is the additional TCP RST some host implementations send after
+terminating a connection (which is implementation-specific).
+
+In other words, connection tracking has already observed the connection
+be closed and has transition the flow to INVALID to prevent attacks from
+attempting to reuse the connection.
+
+You can avoid the "leaky" behavior by using a firewall policy that drops
+"invalid" state packets.
+
+Having control over the matching of INVALID state traffic, e.g. the
+ability to selectively log, is an important troubleshooting tool for
+observing broken protocol behavior. For this reason, VyOS does not
+globally drop invalid state traffic, instead allowing the operator to
+make the determination on how the traffic is handled.
+
+(hairpin-nat-reflection)=
+
+### Hairpin NAT/NAT Reflection
+
+A typical problem with using NAT and hosting public servers is the
+ability for internal systems to reach an internal server using it's
+external IP address. The solution to this is usually the use of
+split-DNS to correctly point host systems to the internal address when
+requests are made internally. Because many smaller networks lack DNS
+infrastructure, a work-around is commonly deployed to facilitate the
+traffic by NATing the request from internal hosts to the source address
+of the internal interface on the firewall.
+
+This technique is commonly referred to as NAT Reflection or Hairpin NAT.
+
+Example:
+
+- Redirect Microsoft RDP traffic from the outside (WAN, external) world
+ via {ref}`destination-nat` in rule 100 to the internal, private host
+ 192.0.2.40.
+- Redirect Microsoft RDP traffic from the internal (LAN, private)
+ network via {ref}`destination-nat` in rule 110 to the internal,
+ private host 192.0.2.40. We also need a {ref}`source-nat` rule 110 for
+ the reverse path of the traffic. The internal network 192.0.2.0/24 is
+ reachable via interface *eth0.10*.
+
+```none
+set nat destination rule 100 description 'Regular destination NAT from external'
+set nat destination rule 100 destination port '3389'
+set nat destination rule 100 inbound-interface name 'pppoe0'
+set nat destination rule 100 protocol 'tcp'
+set nat destination rule 100 translation address '192.0.2.40'
+
+set nat destination rule 110 description 'NAT Reflection: INSIDE'
+set nat destination rule 110 destination port '3389'
+set nat destination rule 110 inbound-interface name 'eth0.10'
+set nat destination rule 110 protocol 'tcp'
+set nat destination rule 110 translation address '192.0.2.40'
+
+set nat source rule 110 description 'NAT Reflection: INSIDE'
+set nat source rule 110 destination address '192.0.2.0/24'
+set nat source rule 110 outbound-interface name 'eth0.10'
+set nat source rule 110 protocol 'tcp'
+set nat source rule 110 source address '192.0.2.0/24'
+set nat source rule 110 translation address 'masquerade'
+```
+
+Which results in a configuration of:
+
+```none
+vyos@vyos# show nat
+ destination {
+ rule 100 {
+ description "Regular destination NAT from external"
+ destination {
+ port 3389
+ }
+ inbound-interface {
+ name pppoe0
+ }
+ protocol tcp
+ translation {
+ address 192.0.2.40
+ }
+ }
+ rule 110 {
+ description "NAT Reflection: INSIDE"
+ destination {
+ port 3389
+ }
+ inbound-interface {
+ name eth0.10
+ }
+ protocol tcp
+ translation {
+ address 192.0.2.40
+ }
+ }
+ }
+ source {
+ rule 110 {
+ description "NAT Reflection: INSIDE"
+ destination {
+ address 192.0.2.0/24
+ }
+ outbound-interface {
+ name eth0.10
+ }
+ protocol tcp
+ source {
+ address 192.0.2.0/24
+ }
+ translation {
+ address masquerade
+ }
+ }
+ }
+```
+
+### Destination NAT
+
+DNAT is typically referred to as a **Port Forward**. When using VyOS as
+a NAT router and firewall, a common configuration task is to redirect
+incoming traffic to a system behind the firewall.
+
+In this example, we will be using the example Quick Start configuration
+above as a starting point.
+
+To setup a destination NAT rule we need to gather:
+- The interface traffic will be coming in on;
+- The protocol and port we wish to forward;
+- The IP address of the internal system we wish to forward traffic to.
+
+In our example, we will be forwarding web server traffic to an internal
+web server on 192.168.0.100. HTTP traffic makes use of the TCP protocol
+on port 80. For other common port numbers, see:
+<https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers>
+
+Our configuration commands would be:
+
+```none
+set nat destination rule 10 description 'Port Forward: HTTP to 192.168.0.100'
+set nat destination rule 10 destination port '80'
+set nat destination rule 10 inbound-interface name 'eth0'
+set nat destination rule 10 protocol 'tcp'
+set nat destination rule 10 translation address '192.168.0.100'
+```
+
+Which would generate the following NAT destination configuration:
+
+```none
+nat {
+ destination {
+ rule 10 {
+ description "Port Forward: HTTP to 192.168.0.100"
+ destination {
+ port 80
+ }
+ inbound-interface {
+ name eth0
+ }
+ protocol tcp
+ translation {
+ address 192.168.0.100
+ }
+ }
+ }
+}
+```
+:::{note}
+If forwarding traffic to a different port than it is arriving
+on, you may also configure the translation port using
+*set nat destination rule [n] translation port*.
+:::
+
+This establishes our Port Forward rule, but if we created a firewall
+policy it will likely block the traffic.
+
+#### Firewall rules for Destination NAT
+
+It is important to note that when creating firewall rules, the DNAT
+translation occurs **before** traffic traverses the firewall. In other
+words, the destination address has already been translated to
+192.168.0.100.
+
+So in our firewall ruleset, we want to allow traffic which previously matched
+a destination nat rule. In order to avoid creating many rules, one for each
+destination nat rule, we can accept all **'dnat'** connections with one simple
+rule, using `connection-status` matcher:
+
+```none
+set firewall ipv4 forward filter rule 10 action accept
+set firewall ipv4 forward filter rule 10 connection-status nat destination
+set firewall ipv4 forward filter rule 10 state new
+```
+
+This would generate the following configuration:
+
+```none
+ipv4 {
+ forward {
+ filter {
+ rule 10 {
+ action accept
+ connection-status {
+ nat destination
+ }
+ state new
+ }
+ }
+ }
+}
+```
+
+### 1-to-1 NAT
+
+Another term often used for DNAT is **1-to-1 NAT**. For a 1-to-1 NAT
+configuration, both DNAT and SNAT are used to NAT all traffic from an
+external IP address to an internal IP address and vice-versa.
+
+Typically, a 1-to-1 NAT rule omits the destination port (all ports) and
+replaces the protocol with either **all** or **ip**.
+
+Then a corresponding SNAT rule is created to NAT outgoing traffic for
+the internal IP to a reserved external IP. This dedicates an external IP
+address to an internal IP address and is useful for protocols which
+don't have the notion of ports, such as GRE.
+
+Here's an extract of a simple 1-to-1 NAT configuration with one internal
+and one external interface:
+
+```none
+set interfaces ethernet eth0 address '192.168.1.1/24'
+set interfaces ethernet eth0 description 'Inside interface'
+set interfaces ethernet eth1 address '192.0.2.30/24'
+set interfaces ethernet eth1 description 'Outside interface'
+set nat destination rule 2000 description '1-to-1 NAT example'
+set nat destination rule 2000 destination address '192.0.2.30'
+set nat destination rule 2000 inbound-interface name 'eth1'
+set nat destination rule 2000 translation address '192.168.1.10'
+set nat source rule 2000 description '1-to-1 NAT example'
+set nat source rule 2000 outbound-interface name 'eth1'
+set nat source rule 2000 source address '192.168.1.10'
+set nat source rule 2000 translation address '192.0.2.30'
+```
+
+Firewall rules are written as normal, using the internal IP address as
+the source of outbound rules and the destination of inbound rules.
+
+### NAT before VPN
+
+Some application service providers (ASPs) operate a VPN gateway to
+provide access to their internal resources, and require that a
+connecting organisation translate all traffic to the service provider
+network to a source address provided by the ASP.
+
+### Load Balance
+
+Here we provide two examples on how to apply NAT Load Balance.
+
+First scenario: apply destination NAT for all HTTP traffic comming through
+interface eth0, and user 4 backends. First backend should received 30% of
+the request, second backend should get 20%, third 15% and the fourth 35%
+We will use source and destination address for hash generation.
+
+```none
+set nat destination rule 10 inbound-interface name eth0
+set nat destination rule 10 protocol tcp
+set nat destination rule 10 destination port 80
+set nat destination rule 10 load-balance hash source-address
+set nat destination rule 10 load-balance hash destination-address
+set nat destination rule 10 load-balance backend 198.51.100.101 weight 30
+set nat destination rule 10 load-balance backend 198.51.100.102 weight 20
+set nat destination rule 10 load-balance backend 198.51.100.103 weight 15
+set nat destination rule 10 load-balance backend 198.51.100.104 weight 35
+```
+
+Second scenario: apply source NAT for all outgoing connections from
+LAN 10.0.0.0/8, using 3 public addresses and equal distribution.
+We will generate the hash randomly.
+
+```none
+set nat source rule 10 outbound-interface name eth0
+set nat source rule 10 source address 10.0.0.0/8
+set nat source rule 10 load-balance hash random
+set nat source rule 10 load-balance backend 192.0.2.251 weight 33
+set nat source rule 10 load-balance backend 192.0.2.252 weight 33
+set nat source rule 10 load-balance backend 192.0.2.253 weight 34
+```
+
+#### Example Network
+
+Here's one example of a network environment for an ASP.
+The ASP requests that all connections from this company should come from
+172.29.41.89 - an address that is assigned by the ASP and not in use at
+the customer site.
+
+```{eval-rst}
+.. figure:: /_static/images/nat_before_vpn_topology.webp
+ :scale: 100 %
+ :alt: NAT before VPN Topology
+
+ NAT before VPN Topology
+```
+#### Configuration
+
+The required configuration can be broken down into 4 major pieces:
+- A dummy interface for the provider-assigned IP;
+- NAT (specifically, Source NAT);
+- IPSec IKE and ESP Groups;
+- IPSec VPN tunnels.
+
+##### Dummy interface
+
+The dummy interface allows us to have an equivalent of the Cisco IOS
+Loopback interface - a router-internal interface we can use for IP
+addresses the router must know about, but which are not actually
+assigned to a real network.
+
+We only need a single step for this interface:
+
+```none
+set interfaces dummy dum0 address '172.29.41.89/32'
+```
+
+##### NAT Configuration
+
+```none
+set nat source rule 110 description 'Internal to ASP'
+set nat source rule 110 destination address '172.27.1.0/24'
+set nat source rule 110 source address '192.168.43.0/24'
+set nat source rule 110 translation address '172.29.41.89'
+set nat source rule 120 description 'Internal to ASP'
+set nat source rule 120 destination address '10.125.0.0/16'
+set nat source rule 120 source address '192.168.43.0/24'
+set nat source rule 120 translation address '172.29.41.89'
+```
+
+##### IPSec IKE and ESP
+
+The ASP has documented their IPSec requirements:
+- IKE Phase:
+ - aes256 Encryption
+ - sha256 Hashes
+- ESP Phase:
+ - aes256 Encryption
+ - sha256 Hashes
+ - DH Group 14
+
+Additionally, we want to use VPNs only on our eth1 interface (the
+external interface in the image above)
+
+```none
+set vpn ipsec ike-group my-ike key-exchange 'ikev1'
+set vpn ipsec ike-group my-ike lifetime '7800'
+set vpn ipsec ike-group my-ike proposal 1 dh-group '14'
+set vpn ipsec ike-group my-ike proposal 1 encryption 'aes256'
+set vpn ipsec ike-group my-ike proposal 1 hash 'sha256'
+
+set vpn ipsec esp-group my-esp lifetime '3600'
+set vpn ipsec esp-group my-esp mode 'tunnel'
+set vpn ipsec esp-group my-esp pfs 'disable'
+set vpn ipsec esp-group my-esp proposal 1 encryption 'aes256'
+set vpn ipsec esp-group my-esp proposal 1 hash 'sha256'
+
+set vpn ipsec interface 'eth1'
+```
+
+##### IPSec VPN Tunnels
+
+We'll use the IKE and ESP groups created above for this VPN. Because we
+need access to 2 different subnets on the far side, we will need two
+different tunnels. If you changed the names of the ESP group and IKE
+group in the previous step, make sure you use the correct names here
+too.
+
+```none
+set vpn ipsec authentication psk vyos id '203.0.113.46'
+set vpn ipsec authentication psk vyos id '198.51.100.243'
+set vpn ipsec authentication psk vyos secret 'MYSECRETPASSWORD'
+set vpn ipsec site-to-site peer branch authentication local-id '203.0.113.46'
+set vpn ipsec site-to-site peer branch authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer branch authentication remote-id '198.51.100.243'
+set vpn ipsec site-to-site peer branch connection-type 'initiate'
+set vpn ipsec site-to-site peer branch default-esp-group 'my-esp'
+set vpn ipsec site-to-site peer branch ike-group 'my-ike'
+set vpn ipsec site-to-site peer branch ikev2-reauth 'inherit'
+set vpn ipsec site-to-site peer branch local-address '203.0.113.46'
+set vpn ipsec site-to-site peer branch remote-address '198.51.100.243'
+set vpn ipsec site-to-site peer branch tunnel 0 local prefix '172.29.41.89/32'
+set vpn ipsec site-to-site peer branch tunnel 0 remote prefix '172.27.1.0/24'
+set vpn ipsec site-to-site peer branch tunnel 1 local prefix '172.29.41.89/32'
+set vpn ipsec site-to-site peer branch tunnel 1 remote prefix '10.125.0.0/16'
+```
+
+##### Testing and Validation
+
+If you've completed all the above steps you no doubt want to see if it's
+all working.
+
+Start by checking for IPSec SAs (Security Associations) with:
+
+```none
+$ show vpn ipsec sa
+
+Peer ID / IP Local ID / IP
+------------ -------------
+198.51.100.243 203.0.113.46
+
+ Tunnel State Bytes Out/In Encrypt Hash NAT-T A-Time L-Time Proto
+ ------ ----- ------------- ------- ---- ----- ------ ------ -----
+ 0 up 0.0/0.0 aes256 sha256 no 1647 3600 all
+ 1 up 0.0/0.0 aes256 sha256 no 865 3600 all
+```
+
+That looks good - we defined 2 tunnels and they're both up and running.
diff --git a/docs/configuration/nat/nat64.md b/docs/configuration/nat/nat64.md
new file mode 100644
index 00000000..c1b1c994
--- /dev/null
+++ b/docs/configuration/nat/nat64.md
@@ -0,0 +1,73 @@
+(nat64)=
+
+# NAT64
+
+{abbr}`NAT64 (IPv6-to-IPv4 Prefix Translation)` is a critical component in
+modern networking, facilitating communication between IPv6 and IPv4 networks.
+This documentation outlines the setup, configuration, and usage of the NAT64
+feature in your project. Whether you are transitioning to IPv6 or need to
+seamlessly connect IPv4 and IPv6 devices.
+NAT64 is a stateful translation mechanism that translates IPv6 addresses to
+IPv4 addresses and IPv4 addresses to IPv6 addresses. NAT64 is used to enable
+IPv6-only clients to contact IPv4 servers using unicast UDP, TCP, or ICMP.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat64)=
+
+#### SNAT64
+
+{abbr}`SNAT64 (IPv6-to-IPv4 Source Address Translation)` is a stateful
+translation mechanism that translates IPv6 addresses to IPv4 addresses.
+
+`64:ff9b::/96` is the well-known prefix for IPv4-embedded IPv6 addresses.
+The prefix is used to represent IPv4 addresses in an IPv6 address format.
+The IPv4 address is encoded in the low-order 32 bits of the IPv6 address.
+The high-order 32 bits are set to the well-known prefix 64:ff9b::/96.
+
+## Configuration Examples
+
+The following examples show how to configure NAT64 on a VyOS router.
+The 192.0.2.10 address is used as the IPv4 address for the translation pool.
+
+NAT64 server configuration:
+
+```none
+set interfaces ethernet eth0 address '192.0.2.1/24'
+set interfaces ethernet eth0 address '192.0.2.10/24'
+set interfaces ethernet eth0 description 'WAN'
+set interfaces ethernet eth1 address '2001:db8::1/64'
+set interfaces ethernet eth1 description 'LAN'
+
+set service dns forwarding allow-from '2001:db8::/64'
+set service dns forwarding dns64-prefix '64:ff9b::/96'
+set service dns forwarding listen-address '2001:db8::1'
+
+set nat64 source rule 100 source prefix '64:ff9b::/96'
+set nat64 source rule 100 translation pool 10 address '192.0.2.10'
+set nat64 source rule 100 translation pool 10 port '1-65535'
+```
+
+NAT64 client configuration:
+
+```none
+set interfaces ethernet eth1 address '2001:db8::2/64'
+set protocols static route6 64:ff9b::/96 next-hop 2001:db8::1
+set system name-server '2001:db8::1'
+```
+
+Test from the IPv6 only client:
+
+```none
+vyos@r1:~$ ping 64:ff9b::192.0.2.1 count 2
+PING 64:ff9b::192.0.2.1(64:ff9b::c000:201) 56 data bytes
+64 bytes from 64:ff9b::c000:201: icmp_seq=1 ttl=63 time=0.351 ms
+64 bytes from 64:ff9b::c000:201: icmp_seq=2 ttl=63 time=0.373 ms
+
+--- 64:ff9b::192.0.2.1 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1023ms
+rtt min/avg/max/mdev = 0.351/0.362/0.373/0.011 ms
+```
+
diff --git a/docs/configuration/nat/nat66.md b/docs/configuration/nat/nat66.md
new file mode 100644
index 00000000..1cbe3317
--- /dev/null
+++ b/docs/configuration/nat/nat66.md
@@ -0,0 +1,243 @@
+(nat66)=
+
+# NAT66(NPTv6)
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+{abbr}`NPTv6 (IPv6-to-IPv6 Network Prefix Translation)` is an address
+translation technology based on IPv6 networks, used to convert an IPv6
+address prefix in an IPv6 message into another IPv6 address prefix.
+We call this address translation method NAT66. Devices that support the NAT66
+function are called NAT66 devices, which can provide NAT66 source
+and destination address translation functions.
+
+## Overview
+
+### Different NAT Types
+
+(source-nat66)=
+
+#### SNAT66
+
+{abbr}`SNPTv6 (Source IPv6-to-IPv6 Network Prefix Translation)` The conversion
+function is mainly used in the following scenarios:
+- A single internal network and external network. Use the NAT66 device to
+ connect a single internal network and public network, and the hosts in
+ the internal network use IPv6 address prefixes that only support
+ routing within the local range. When a host in the internal network
+ accesses the external network, the source IPv6 address prefix in
+ the message will be converted into a global unicast IPv6 address
+ prefix by the NAT66 device.
+- Redundancy and load sharing. There are multiple NAT66 devices at the edge
+ of an IPv6 network to another IPv6 network. The path through the NAT66
+ device to another IPv6 network forms an equivalent route, and traffic
+ can be load-shared on these NAT66 devices. In this case, you
+ can configure the same source address translation rules on these
+ NAT66 devices, so that any NAT66 device can handle IPv6 traffic between
+ different sites.
+- Multi-homed. In a multi-homed network environment, the NAT66 device
+ connects to an internal network and simultaneously connects to
+ different external networks. Address translation can be configured
+ on each external network side interface of the NAT66 device to
+ convert the same internal network address into different external
+ network addresses, and realize the mapping of the same internal
+ address to multiple external addresses.
+(destination-nat66)=
+
+#### DNAT66
+
+The {abbr}`DNPTv6 (Destination IPv6-to-IPv6 Network Prefix Translation)`
+destination address translation function is used in scenarios where the
+server in the internal network provides services to the external network,
+such as providing Web services or FTP services to the external network.
+By configuring the mapping relationship between the internal server
+address and the external network address on the external network
+side interface of the NAT66 device, external network users can
+access the internal network server through the designated
+external network address.
+
+### Prefix Conversion
+
+#### Source Prefix
+
+Every SNAT66 rule has a translation command defined. The prefix defined
+for the translation is the prefix used when the address information in
+a packet is replaced.、
+
+The {ref}`source-nat66` rule replaces the source address of the packet
+and calculates the converted address using the prefix specified in the rule.
+
+Example:
+- Convert the address prefix of a single `fc01::/64` network to `fc00::/64`
+- Output from `eth0` network interface
+
+```none
+set nat66 source rule 1 outbound-interface name 'eth0'
+set nat66 source rule 1 source prefix 'fc01::/64'
+set nat66 source rule 1 translation address 'fc00::/64'
+```
+
+
+#### Destination Prefix
+
+For the {ref}`destination-nat66` rule, the destination address of
+the packet isreplaced by the address calculated from the specified
+address or prefix in the `translation address` command
+
+Example:
+- Convert the address prefix of a single `fc00::/64` network
+ to `fc01::/64`
+- Input from `eth0` network interface
+
+```none
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 destination address 'fc00::/64'
+set nat66 destination rule 1 translation address 'fc01::/64'
+```
+
+For the destination, groups can also be used instead of an address.
+
+Example:
+
+```none
+set firewall group ipv6-address-group ADR-INSIDE-v6 address fc00::1
+
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 destination group address-group ADR-INSIDE-v6
+set nat66 destination rule 1 translation address 'fc01::/64'
+```
+
+
+## Configuration Examples
+
+Use the following topology to build a nat66 based isolated
+network between internal and external networks (dynamic prefix is
+not supported):
+
+:::{figure} /_static/images/vyos_1_4_nat66_simple.webp
+:alt: VyOS NAT66 Simple Configure
+:::
+
+R1:
+
+```none
+set interfaces ethernet eth0 ipv6 address autoconf
+set interfaces ethernet eth1 address 'fc01::1/64'
+set nat66 destination rule 1 destination address 'fc00:470:f1cd:101::/64'
+set nat66 destination rule 1 inbound-interface name 'eth0'
+set nat66 destination rule 1 translation address 'fc01::/64'
+set nat66 source rule 1 outbound-interface name 'eth0'
+set nat66 source rule 1 source prefix 'fc01::/64'
+set nat66 source rule 1 translation address 'fc00:470:f1cd:101::/64'
+```
+
+R2:
+
+```none
+set interfaces bridge br1 address 'fc01::2/64'
+set interfaces bridge br1 member interface eth0
+set interfaces bridge br1 member interface eth1
+set protocols static route6 ::/0 next-hop fc01::1
+set service router-advert interface br1 prefix ::/0
+```
+
+Use the following topology to translate internal user local addresses
+(`fc::/7`) to DHCPv6-PD provided prefixes from an ISP connected to
+a VyOS HA pair.
+
+:::{figure} /_static/images/vyos_1_5_nat66_dhcpv6_wdummy.webp
+:alt: VyOS NAT66 DHCPv6 using a dummy interface
+:::
+
+Configure both routers (a and b) for DHCPv6-PD via dummy interface:
+
+```none
+set interfaces dummy dum1 description 'DHCPv6-PD NPT dummy'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 0 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 1 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 2 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options pd 3 interface dum1 address '0'
+set interfaces bonding bond0 vif 20 dhcpv6-options rapid-commit
+commit
+```
+
+Get the DHCPv6-PD prefixes from both routers:
+
+```none
+trae@cr01a-vyos# run show interfaces dummy dum1 br
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+dum1 2001:db8:123:b008::/64 u/u DHCPv6-PD NPT dummy
+ 2001:db8:123:b00a::/64
+ 2001:db8:123:b00b::/64
+ 2001:db8:123:b009::/64
+
+trae@cr01b-vyos# run show int dummy dum1 brief
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+dum1 2001:db8:123:b00d::/64 u/u DHCPv6-PD NPT dummy
+ 2001:db8:123:b00c::/64
+ 2001:db8:123:b00e::/64
+ 2001:db8:123:b00f::/64
+```
+
+Configure the A-side router for NPTv6 using the prefixes above:
+
+```none
+set nat66 source rule 10 description 'NPT to VLAN 10'
+set nat66 source rule 10 outbound-interface name 'bond0.20'
+set nat66 source rule 10 source prefix 'fd52:d62e:8011:a::/64'
+set nat66 source rule 10 translation address '2001:db8:123:b008::/64'
+set nat66 source rule 20 description 'NPT to VLAN 70'
+set nat66 source rule 20 outbound-interface name 'bond0.20'
+set nat66 source rule 20 source prefix 'fd52:d62e:8011:46::/64'
+set nat66 source rule 20 translation address '2001:db8:123:b009::/64'
+set nat66 source rule 30 description 'NPT to VLAN 200'
+set nat66 source rule 30 outbound-interface name 'bond0.20'
+set nat66 source rule 30 source prefix 'fd52:d62e:8011:c8::/64'
+set nat66 source rule 30 translation address '2001:db8:123:b00a::/64'
+set nat66 source rule 40 description 'NPT to VLAN 240'
+set nat66 source rule 40 outbound-interface name 'bond0.20'
+set nat66 source rule 40 source prefix 'fd52:d62e:8011:f0::/64'
+set nat66 source rule 40 translation address '2001:db8:123:b00b::/64'
+commit
+```
+
+Configure the B-side router for NPTv6 using the prefixes above:
+
+```none
+set nat66 source rule 10 description 'NPT to VLAN 10'
+set nat66 source rule 10 outbound-interface name 'bond0.20'
+set nat66 source rule 10 source prefix 'fd52:d62e:8011:a::/64'
+set nat66 source rule 10 translation address '2001:db8:123:b00c::/64'
+set nat66 source rule 20 description 'NPT to VLAN 70'
+set nat66 source rule 20 outbound-interface name 'bond0.20'
+set nat66 source rule 20 source prefix 'fd52:d62e:8011:46::/64'
+set nat66 source rule 20 translation address '2001:db8:123:b00d::/64'
+set nat66 source rule 30 description 'NPT to VLAN 200'
+set nat66 source rule 30 outbound-interface name 'bond0.20'
+set nat66 source rule 30 source prefix 'fd52:d62e:8011:c8::/64'
+set nat66 source rule 30 translation address '2001:db8:123:b00e::/64'
+set nat66 source rule 40 description 'NPT to VLAN 240'
+set nat66 source rule 40 outbound-interface name 'bond0.20'
+set nat66 source rule 40 source prefix 'fd52:d62e:8011:f0::/64'
+set nat66 source rule 40 translation address '2001:db8:123:b00f::/64'
+commit
+```
+
+Verify that connections are hitting the rule on both sides:
+
+```none
+trae@cr01a-vyos# run show nat66 source statistics
+Rule Packets Bytes Interface
+------ --------- ------- -----------
+10 1 104 bond0.20
+20 1 104 bond0.20
+30 8093 669445 bond0.20
+40 2446 216912 bond0.20
+```
diff --git a/docs/configuration/pki/index.md b/docs/configuration/pki/index.md
new file mode 100644
index 00000000..e7d793de
--- /dev/null
+++ b/docs/configuration/pki/index.md
@@ -0,0 +1,583 @@
+---
+lastproofread: '2024-01-05'
+---
+
+```{include} /_include/need_improvement.txt
+```
+
+(pki)=
+
+# PKI
+
+VyOS 1.4 changed the way in how encryption keys or certificates are stored on the
+system. In the pre VyOS 1.4 era, certificates got stored under /config and every
+service referenced a file. That made copying a running configuration from system
+A to system B a bit harder, as you had to copy the files and their permissions
+by hand.
+
+{vytask}`T3642` describes a new CLI subsystem that serves as a "certstore" to
+all services requiring any kind of encryption key(s). In short, public and
+private certificates are now stored in PKCS#8 format in the regular VyOS CLI.
+Keys can now be added, edited, and deleted using the regular set/edit/delete
+CLI commands.
+
+VyOS not only can now manage certificates issued by 3rd party Certificate
+Authorities, it can also act as a CA on its own. You can create your own root
+CA and sign keys with it by making use of some simple op-mode commands.
+
+Don't be afraid that you need to re-do your configuration. Key transformation is
+handled, as always, by our migration scripts, so this will be a smooth transition
+for you!
+
+## Key Generation
+
+### Certificate Authority (CA)
+
+VyOS now also has the ability to create CAs, keys, Diffie-Hellman and other
+keypairs from an easy to access operational level command.
+
+```{opcmd} generate pki ca
+
+Create a new {abbr}`CA (Certificate Authority)` and output the CAs public and
+private key on the console.
+```
+
+```{opcmd} generate pki ca install \<name\>
+
+Create a new {abbr}`CA (Certificate Authority)` and output the CAs public and
+private key on the console.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+```{opcmd} generate pki ca sign \<ca-name\>
+
+Create a new subordinate {abbr}`CA (Certificate Authority)` and sign it using
+the private key referenced by ca-name.
+```
+
+```{opcmd} generate pki ca sign \<ca-name\> install \<name\>
+
+Create a new subordinate {abbr}`CA (Certificate Authority)` and sign it using
+the private key referenced by `name`.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+### Certificates
+
+```{opcmd} generate pki certificate
+
+Create a new public/private keypair and output the certificate on the console.
+```
+
+```{opcmd} generate pki certificate install \<name\>
+
+Create a new public/private keypair and output the certificate on the console.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+```{opcmd} generate pki certificate self-signed
+
+Create a new self-signed certificate. The public/private is then shown on the
+console.
+```
+
+```{opcmd} generate pki certificate self-signed install \<name\>
+
+Create a new self-signed certificate. The public/private is then shown on the
+console.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+```{opcmd} generate pki certificate sign \<ca-name\>
+
+Create a new public/private keypair which is signed by the CA referenced by
+ca-name. The signed certificate is then output to the console.
+```
+
+```{opcmd} generate pki certificate sign \<ca-name\> install \<name\>
+
+Create a new public/private keypair which is signed by the CA referenced by
+ca-name. The signed certificate is then output to the console.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+### Diffie-Hellman parameters
+
+```{opcmd} generate pki dh
+
+Generate a new set of {abbr}`DH (Diffie-Hellman)` parameters. The key size
+is requested by the CLI and defaults to 2048 bit.
+
+The generated parameters are then output to the console.
+```
+
+```{opcmd} generate pki dh install \<name\>
+
+Generate a new set of {abbr}`DH (Diffie-Hellman)` parameters. The key size
+is requested by the CLI and defaults to 2048 bit.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+### OpenVPN
+
+```{opcmd} generate pki openvpn shared-secret
+
+Generate a new OpenVPN shared secret. The generated secret is the output to
+the console.
+```
+
+```{opcmd} generate pki openvpn shared-secret install \<name\>
+
+Generate a new OpenVPN shared secret. The generated secret is the output to
+the console.
+
+:::{note}
+In addition to the command above, the output is in a format which can be used
+to directly import the key into the VyOS CLI by simply copy-pasting the output
+from op-mode into configuration mode.
+
+``name`` is used for the VyOS CLI command to identify this key. This
+key ``name`` is then used in the CLI configuration to reference the key
+instance.
+:::
+```
+
+### WireGuard
+
+```{opcmd} generate pki wireguard key-pair
+
+Generate a new WireGuard public/private key portion and output the result to
+the console.
+```
+
+```{opcmd} generate pki wireguard key-pair install \<interface\>
+
+Generate a new WireGuard public/private key portion and output the result to
+the console.
+
+:::{note}
+In addition to the command above, the output is in a format which can
+be used to directly import the key into the VyOS CLI by simply copy-pasting
+the output from op-mode into configuration mode.
+
+``interface`` is used for the VyOS CLI command to identify the WireGuard
+interface where this private key is to be used.
+:::
+```
+
+```{opcmd} generate pki wireguard preshared-key
+
+Generate a WireGuard pre-shared secret used for peers to communicate.
+```
+
+```{opcmd} generate pki wireguard preshared-key install \<peer\>
+
+Generate a WireGuard pre-shared secret used for peers to communicate.
+
+:::{note}
+In addition to the command above, the output is in a format which can
+be used to directly import the key into the VyOS CLI by simply copy-pasting
+the output from op-mode into configuration mode.
+
+``peer`` is used for the VyOS CLI command to identify the WireGuard peer where
+this secret is to be used.
+:::
+```
+
+## Key usage (CLI)
+### CA (Certificate Authority)
+
+```{cfgcmd} set pki ca \<name\> certificate
+
+Add the public CA certificate for the CA named `name` to the VyOS CLI.
+
+:::{note}
+When loading the certificate you need to manually strip the
+``-----BEGIN CERTIFICATE-----`` and ``-----END CERTIFICATE-----`` tags.
+Also, the certificate/key needs to be presented in a single line without
+line breaks (``\n``), this can be done using the following shell command:
+
+``$ tail -n +2 ca.pem | head -n -1 | tr -d '\n'``
+:::
+```
+
+```{cfgcmd} set pki ca \<name\> crl
+
+Certificate revocation list in PEM format.
+```
+
+```{cfgcmd} set pki ca \<name\> description
+
+A human readable description what this CA is about.
+```
+
+```{cfgcmd} set pki ca \<name\> private key
+
+Add the CAs private key to the VyOS CLI. This should never leave the system,
+and is only required if you use VyOS as your certificate generator as
+mentioned above.
+
+:::{note}
+When loading the certificate you need to manually strip the
+``-----BEGIN KEY-----`` and ``-----END KEY-----`` tags. Also, the
+certificate/key needs to be presented in a single line without line
+breaks (``\n``), this can be done using the following shell command:
+
+``$ tail -n +2 ca.key | head -n -1 | tr -d '\n'``
+:::
+```
+
+```{cfgcmd} set pki ca \<name\> private password-protected
+
+Mark the CAs private key as password protected. User is asked for the password
+when the key is referenced.
+```
+
+### Server Certificate
+
+After we have imported the CA certificate(s) we can now import and add
+certificates used by services on this router.
+
+```{cfgcmd} set pki certificate \<name\> certificate
+
+Add public key portion for the certificate named `name` to the VyOS CLI.
+
+:::{note}
+When loading the certificate you need to manually strip the
+``-----BEGIN CERTIFICATE-----`` and ``-----END CERTIFICATE-----`` tags.
+Also, the certificate/key needs to be presented in a single line without
+line breaks (``\n``), this can be done using the following shell command:
+
+``$ tail -n +2 cert.pem | head -n -1 | tr -d '\n'``
+:::
+```
+
+```{cfgcmd} set pki certificate \<name\> description
+
+A human readable description what this certificate is about.
+```
+
+```{cfgcmd} set pki certificate \<name\> private key
+
+Add the private key portion of this certificate to the CLI. This should never
+leave the system as it is used to decrypt the data.
+
+:::{note}
+When loading the certificate you need to manually strip the
+``-----BEGIN KEY-----`` and ``-----END KEY-----`` tags. Also, the
+certificate/key needs to be presented in a single line without line
+breaks (``\n``), this can be done using the following shell command:
+
+``$ tail -n +2 cert.key | head -n -1 | tr -d '\n'``
+:::
+```
+
+```{cfgcmd} set pki certificate \<name\> private password-protected
+
+Mark the private key as password protected. User is asked for the password
+when the key is referenced.
+```
+
+```{cfgcmd} set pki certificate \<name\> revoke
+
+If CA is present, this certificate will be included in generated CRLs
+```
+
+### Import files to PKI format
+
+VyOS provides this utility to import existing certificates/key files directly
+into PKI from op-mode. Previous to VyOS 1.4, certificates were stored under the
+/config folder permanently and will be retained post upgrade.
+
+```{opcmd} import pki ca \<name\> file \<Path to CA certificate file\>
+
+Import the public CA certificate from the defined file to VyOS CLI.
+```
+
+```{opcmd} import pki ca \<name\> key-file \<Path to private key file\>
+
+Import the CAs private key portion to the CLI. This should never leave the
+system as it is used to decrypt the data. The key is required if you use
+VyOS as your certificate generator.
+```
+
+```{opcmd} import pki certificate \<name\> file \<path to certificate\>
+
+Import the certificate from the file to VyOS CLI.
+```
+
+```{opcmd} import pki certificate \<name\> key-file \<path to private key\>
+
+Import the private key of the certificate to the VyOS CLI. This should never
+leave the system as it is used to decrypt the data.
+```
+
+```{opcmd} import pki openvpn shared-secret \<name\> file \<path to OpenVPN secret key\>
+
+Import the OpenVPN shared secret stored in file to the VyOS CLI.
+```
+
+#### ACME
+
+The VyOS PKI subsystem can also be used to automatically retrieve Certificates
+using the {abbr}`ACME (Automatic Certificate Management Environment)` protocol.
+
+```{cfgcmd} set pki certificate \<name\> acme domain-name \<name\>
+
+Domain names to apply, multiple domain-names can be specified.
+
+This is a mandatory option
+```
+
+```{cfgcmd} set pki certificate \<name\> acme email \<address\>
+
+Email used for registration and recovery contact.
+
+This is a mandatory option
+```
+
+```{cfgcmd} set pki certificate \<name\> acme listen-address \<address\>
+
+The address the server listens to during http-01 challenge
+```
+
+```{cfgcmd} set pki certificate \<name\> acme rsa-key-size \<2048 | 3072 | 4096\>
+
+Size of the RSA key.
+
+This options defaults to 2048
+```
+
+```{cfgcmd} set pki certificate \<name\> acme url \<url\>
+
+ACME Directory Resource URI.
+
+This defaults to https://acme-v02.api.letsencrypt.org/directory
+
+:::{note}
+During initial deployment we recommend using the staging API
+of LetsEncrypt to prevent and blacklisting of your system. The API
+endpoint is https://acme-staging-v02.api.letsencrypt.org/directory
+:::
+```
+
+## Operation
+
+VyOS operational mode commands are not only available for generating keys but
+also to display them.
+
+```{opcmd} show pki ca
+
+Show a list of installed {abbr}`CA (Certificate Authority)` certificates.
+
+:::{code-block} none
+vyos@vyos:~$ show pki ca
+Certificate Authorities:
+Name Subject Issuer CN Issued Expiry Private Key Parent
+-------------- ------------------------------------------------------- ----------------- ------------------- ------------------- ------------- --------------
+DST_Root_CA_X3 CN=ISRG Root X1,O=Internet Security Research Group,C=US CN=DST Root CA X3 2021-01-20 19:14:03 2024-09-30 18:14:03 No N/A
+R3 CN=R3,O=Let's Encrypt,C=US CN=ISRG Root X1 2020-09-04 00:00:00 2025-09-15 16:00:00 No DST_Root_CA_X3
+vyos_rw CN=VyOS RW CA,O=VyOS,L=Some-City,ST=Some-State,C=GB CN=VyOS RW CA 2021-07-05 13:46:03 2026-07-04 13:46:03 Yes N/A
+:::
+```
+
+```{opcmd} show pki ca \<name\>
+
+Show only information for specified Certificate Authority.
+```
+
+```{opcmd} show pki certificate
+
+Show a list of installed certificates
+
+:::{code-block} none
+vyos@vyos:~$ show pki certificate
+Certificates:
+Name Type Subject CN Issuer CN Issued Expiry Revoked Private Key CA Present
+--------- ------ --------------------- ------------- ------------------- ------------------- --------- ------------- -------------
+ac2 Server CN=ac2.vyos.net CN=R3 2021-07-05 07:29:59 2021-10-03 07:29:58 No Yes Yes (R3)
+rw_server Server CN=VyOS RW CN=VyOS RW CA 2021-07-05 13:48:02 2022-07-05 13:48:02 No Yes Yes (vyos_rw)
+:::
+```
+
+```{opcmd} show pki certificate \<name\>
+
+Show only information for specified certificate.
+```
+
+```{opcmd} show pki crl
+
+Show a list of installed {abbr}`CRLs (Certificate Revocation List)`.
+```
+
+```{opcmd} renew certbot
+
+Manually trigger certificate renewal. This will be done twice a day.
+```
+
+## Examples
+
+### Create a CA chain and leaf certificates
+
+This configuration generates & installs into the VyOS PKI system a root
+certificate authority, alongside two intermediary certificate authorities for
+client & server certificates. These CAs are then used to generate a server
+certificate for the router, and a client certificate for a user.
+- `vyos_root_ca` is the root certificate authority.
+- `vyos_client_ca` and `vyos_server_ca` are intermediary certificate authorities,
+ which are signed by the root CA.
+- `vyos_cert` is a leaf server certificate used to identify the VyOS router,
+ signed by the server intermediary CA.
+- `vyos_example_user` is a leaf client certificate used to identify a user,
+ signed by client intermediary CA.
+
+First, we create the root certificate authority.
+
+```none
+[edit]
+vyos@vyos# run generate pki ca install vyos_root_ca
+Enter private key type: [rsa, dsa, ec] (Default: rsa) rsa
+Enter private key bits: (Default: 2048) 2048
+Enter country code: (Default: GB) GB
+Enter state: (Default: Some-State) Some-State
+Enter locality: (Default: Some-City) Some-City
+Enter organization name: (Default: VyOS) VyOS
+Enter common name: (Default: vyos.io) VyOS Root CA
+Enter how many days certificate will be valid: (Default: 1825) 1825
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] n
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+```
+
+Secondly, we create the intermediary certificate authorities, which are used to
+sign the leaf certificates.
+
+```none
+[edit]
+vyos@vyos# run generate pki ca sign vyos_root_ca install vyos_server_ca
+Do you already have a certificate request? [y/N] n
+Enter private key type: [rsa, dsa, ec] (Default: rsa) rsa
+Enter private key bits: (Default: 2048) 2048
+Enter country code: (Default: GB) GB
+Enter state: (Default: Some-State) Some-State
+Enter locality: (Default: Some-City) Some-City
+Enter organization name: (Default: VyOS) VyOS
+Enter common name: (Default: vyos.io) VyOS Intermediary Server CA
+Enter how many days certificate will be valid: (Default: 1825) 1095
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] n
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+
+
+[edit]
+vyos@vyos# run generate pki ca sign vyos_root_ca install vyos_client_ca
+Do you already have a certificate request? [y/N] n
+Enter private key type: [rsa, dsa, ec] (Default: rsa) rsa
+Enter private key bits: (Default: 2048) 2048
+Enter country code: (Default: GB) GB
+Enter state: (Default: Some-State) Some-State
+Enter locality: (Default: Some-City) Some-City
+Enter organization name: (Default: VyOS) VyOS
+Enter common name: (Default: vyos.io) VyOS Intermediary Client CA
+Enter how many days certificate will be valid: (Default: 1825) 1095
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] n
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+```
+
+Lastly, we can create the leaf certificates that devices and users will utilise.
+
+```none
+[edit]
+vyos@vyos# run generate pki certificate sign vyos_server_ca install vyos_cert
+Do you already have a certificate request? [y/N] n
+Enter private key type: [rsa, dsa, ec] (Default: rsa) rsa
+Enter private key bits: (Default: 2048) 2048
+Enter country code: (Default: GB) GB
+Enter state: (Default: Some-State) Some-State
+Enter locality: (Default: Some-City) Some-City
+Enter organization name: (Default: VyOS) VyOS
+Enter common name: (Default: vyos.io) vyos.net
+Do you want to configure Subject Alternative Names? [y/N] y
+Enter alternative names in a comma separate list, example: ipv4:1.1.1.1,ipv6:fe80::1,dns:vyos.net
+Enter Subject Alternative Names: dns:vyos.net,dns:www.vyos.net
+Enter how many days certificate will be valid: (Default: 365) 365
+Enter certificate type: (client, server) (Default: server) server
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] n
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+
+
+[edit]
+vyos@vyos# run generate pki certificate sign vyos_client_ca install vyos_example_user
+Do you already have a certificate request? [y/N] n
+Enter private key type: [rsa, dsa, ec] (Default: rsa) rsa
+Enter private key bits: (Default: 2048) 2048
+Enter country code: (Default: GB) GB
+Enter state: (Default: Some-State) Some-State
+Enter locality: (Default: Some-City) Some-City
+Enter organization name: (Default: VyOS) VyOS
+Enter common name: (Default: vyos.io) Example User
+Do you want to configure Subject Alternative Names? [y/N] y
+Enter alternative names in a comma separate list, example: ipv4:1.1.1.1,ipv6:fe80::1,dns:vyos.net,rfc822:user@vyos.net
+Enter Subject Alternative Names: rfc822:example.user@vyos.net
+Enter how many days certificate will be valid: (Default: 365) 365
+Enter certificate type: (client, server) (Default: server) client
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] n
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+```
diff --git a/docs/configuration/policy/access-list.md b/docs/configuration/policy/access-list.md
new file mode 100644
index 00000000..c3a92e56
--- /dev/null
+++ b/docs/configuration/policy/access-list.md
@@ -0,0 +1,70 @@
+# Access List Policy
+
+Filtering is used for both input and output of the routing information. Once
+filtering is defined, it can be applied in any direction. VyOS makes filtering
+possible using acls and prefix lists.
+
+Basic filtering can be done using access-list and access-list6.
+
+## Configuration
+
+### Access Lists
+
+```{cfgcmd} set policy access-list \<acl_number\>
+
+This command creates the new access list policy, where `<acl_number>` must be
+a number from 1 to 2699.
+```
+
+```{cfgcmd} set policy access-list \<acl_number\> description \<text\>
+
+Set description for the access list.
+```
+
+```{cfgcmd} set policy access-list \<acl_number\> rule \<1-65535\> action \<permit|deny\>
+
+This command creates a new rule in the access list and defines an action.
+```
+
+```{cfgcmd} set policy access-list \<acl_number\> rule \<1-65535\> \<destination|source\> \<any|host|inverse-mask|network\>
+
+This command defines matching parameters for access list rule. Matching
+criteria could be applied to destination or source parameters:
+
+* any: any IP address to match.
+* host: single host IP address to match.
+* inverse-match: network/netmask to match (requires network be defined).
+* network: network/netmask to match (requires inverse-match be defined).
+```
+
+
+### IPv6 Access List
+
+Basic filtering could also be applied to IPv6 traffic.
+
+```{cfgcmd} set policy access-list6 \<text\>
+
+This command creates the new IPv6 access list, identified by `<text>`
+```
+
+```{cfgcmd} set policy access-list6 \<text\> description \<text\>
+
+Set description for the IPv6 access list.
+```
+
+```{cfgcmd} set policy access-list6 \<text\> rule \<1-65535\> action \<permit|deny\>
+
+This command creates a new rule in the IPv6 access list and defines an
+action.
+```
+
+```{cfgcmd} set policy access-list6 \<text\> rule \<1-65535\> source \<any|exact-match|network\>
+
+This command defines matching parameters for IPv6 access list rule. Matching
+criteria could be applied to source parameters:
+
+* any: any IPv6 address to match.
+* exact-match: exact match of the network prefixes.
+* network: network/netmask to match (requires inverse-match be defined) BUG,
+NO invert-match option in access-list6
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/as-path-list.md b/docs/configuration/policy/as-path-list.md
new file mode 100644
index 00000000..1fcece91
--- /dev/null
+++ b/docs/configuration/policy/as-path-list.md
@@ -0,0 +1,29 @@
+# BGP - AS Path Policy
+
+VyOS provides policies commands exclusively for BGP traffic filtering and
+manipulation: **as-path-list** is one of them.
+
+## Configuration
+
+### policy as-path-list
+
+```{cfgcmd} set policy as-path-list \<text\>
+
+Create as-path-policy identified by name `<text>`.
+```
+```{cfgcmd} set policy as-path-list \<text\> description \<text\>
+
+Set description for as-path-list policy.
+```
+```{cfgcmd} set policy as-path-list \<text\> rule \<1-65535\> action \<permit|deny\>
+
+Set action to take on entries matching this rule.
+```
+```{cfgcmd} set policy as-path-list \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule.
+```
+```{cfgcmd} set policy as-path-list \<text\> rule \<1-65535\> regex \<text\>
+
+Regular expression to match against an AS path. For example "64501 64502".
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/community-list.md b/docs/configuration/policy/community-list.md
new file mode 100644
index 00000000..bdcf4140
--- /dev/null
+++ b/docs/configuration/policy/community-list.md
@@ -0,0 +1,29 @@
+# BGP - Community List
+
+VyOS provides policies commands exclusively for BGP traffic filtering and
+manipulation: **community-list** is one of them.
+
+## Configuration
+
+### policy community-list
+
+```{cfgcmd} set policy community-list \<text\>
+
+Creat community-list policy identified by name `<text>`.
+```
+```{cfgcmd} set policy community-list \<text\> description \<text\>
+
+Set description for community-list policy.
+```
+```{cfgcmd} set policy community-list \<text\> rule \<1-65535\> action \<permit|deny\>
+
+Set action to take on entries matching this rule.
+```
+```{cfgcmd} set policy community-list \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule.
+```
+```{cfgcmd} set policy community-list \<text\> rule \<1-65535\> regex \<aa:nn|local-AS|no-advertise|no-export|additive\>
+
+Regular expression to match against a community-list.
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/examples.md b/docs/configuration/policy/examples.md
new file mode 100644
index 00000000..86aba9a9
--- /dev/null
+++ b/docs/configuration/policy/examples.md
@@ -0,0 +1,205 @@
+# BGP Example
+
+**Policy definition:**
+
+```none
+# Create policy
+set policy route-map setmet rule 2 action 'permit'
+set policy route-map setmet rule 2 set as-path prepend '2 2 2'
+
+# Apply policy to BGP
+set protocols bgp system-as 1
+set protocols bgp neighbor 203.0.113.2 address-family ipv4-unicast route-map import 'setmet'
+set protocols bgp neighbor 203.0.113.2 address-family ipv4-unicast soft-reconfiguration 'inbound'
+```
+
+Using 'soft-reconfiguration' we get the policy update without bouncing the
+neighbor.
+
+**Routes learned before routing policy applied:**
+
+```none
+vyos@vos1:~$ show ip bgp
+BGP table version is 0, local router ID is 192.168.56.101
+Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
+ r RIB-failure, S Stale, R Removed
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 198.51.100.3/32 203.0.113.2 1 0 2 i < Path
+
+Total number of prefixes 1
+```
+
+**Routes learned after routing policy applied:**
+
+```none
+vyos@vos1:~$ show ip bgp
+BGP table version is 0, local router ID is 192.168.56.101
+Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
+ r RIB-failure, S Stale, R Removed
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 198.51.100.3/32 203.0.113.2 1 0 2 2 2 2 i
+
+Total number of prefixes 1
+vyos@vos1:~$
+```
+
+You now see the longer AS path.
+
+# Transparent Proxy
+
+The following example will show how VyOS can be used to redirect web
+traffic to an external transparent proxy:
+
+```none
+set policy route FILTER-WEB rule 1000 destination port 80
+set policy route FILTER-WEB rule 1000 protocol tcp
+set policy route FILTER-WEB rule 1000 set table 100
+```
+
+This creates a route policy called FILTER-WEB with one rule to set the
+routing table for matching traffic (TCP port 80) to table ID 100
+instead of the default routing table.
+
+To create routing table 100 and add a new default gateway to be used by
+traffic matching our route policy:
+
+```none
+set protocols static table 100 route 0.0.0.0/0 next-hop 10.255.0.2
+```
+
+This can be confirmed using the `show ip route table 100` operational
+command.
+
+Finally, to apply the policy route to ingress traffic on our LAN
+interface, we use:
+
+```none
+set policy route FILTER-WEB interface eth1
+```
+
+
+# Multiple Uplinks
+
+VyOS Policy-Based Routing (PBR) works by matching source IP address
+ranges and forwarding the traffic using different routing tables.
+
+Routing tables that will be used in this example are:
+
+- `table 10` Routing table used for VLAN 10 (192.168.188.0/24)
+- `table 11` Routing table used for VLAN 11 (192.168.189.0/24)
+- `main` Routing table used by VyOS and other interfaces not
+ participating in PBR
+
+:::{figure} /_static/images/pbr_example_1.webp
+:alt: PBR multiple uplinks
+:scale: 80 %
+
+Policy-Based Routing with multiple ISP uplinks
+(source ./draw.io/pbr_example_1.drawio)
+:::
+
+Add default routes for routing `table 10` and `table 11`
+
+```none
+set protocols static table 10 route 0.0.0.0/0 next-hop 192.0.1.1
+set protocols static table 11 route 0.0.0.0/0 next-hop 192.0.2.2
+```
+
+Add policy route matching VLAN source addresses
+
+```none
+set policy route PBR rule 20 set table '10'
+set policy route PBR rule 20 description 'Route VLAN10 traffic to table 10'
+set policy route PBR rule 20 source address '192.168.188.0/24'
+
+set policy route PBR rule 30 set table '11'
+set policy route PBR rule 30 description 'Route VLAN11 traffic to table 11'
+set policy route PBR rule 30 source address '192.168.189.0/24'
+```
+
+Apply routing policy to **inbound** direction of out VLAN interfaces
+
+```none
+set policy route 'PBR' interface eth0.10
+set policy route 'PBR' interface eth0.11
+```
+
+**OPTIONAL:** Exclude Inter-VLAN traffic (between VLAN10 and VLAN11)
+from PBR
+
+```none
+set firewall group network-group VLANS-GR description 'VLANs networks'
+set firewall group network-group VLANS-GR network '192.168.188.0/24'
+set firewall group network-group VLANS-GR network '192.168.189.0/24'
+
+set policy route PBR rule 10 description 'VLAN10 <-> VLAN11 shortcut'
+set policy route PBR rule 10 destination group network-group 'VLANS-GR'
+set policy route PBR rule 10 set table 'main'
+```
+
+These commands allow the VLAN10 and VLAN11 hosts to communicate with
+each other using the main routing table.
+
+## Local route
+
+The following example allows VyOS to use {abbr}`PBR (Policy-Based Routing)`
+for traffic, which originated from the router itself. That solution for multiple
+ISP's and VyOS router will respond from the same interface that the packet was
+received. Also, it used, if we want that one VPN tunnel to be through one
+provider, and the second through another.
+
+- `203.0.113.254` IP addreess on VyOS eth1 from ISP1
+- `192.168.2.254` IP addreess on VyOS eth2 from ISP2
+- `table 10` Routing table used for ISP1
+- `table 11` Routing table used for ISP2
+
+```none
+set policy local-route rule 101 set table '10'
+set policy local-route rule 101 source address '203.0.113.254'
+set policy local-route rule 102 set table '11'
+set policy local-route rule 102 source address '192.0.2.254'
+set protocols static table 10 route 0.0.0.0/0 next-hop '203.0.113.1'
+set protocols static table 11 route 0.0.0.0/0 next-hop '192.0.2.2'
+```
+
+Add multiple source IP in one rule with same priority
+
+```none
+set policy local-route rule 101 set table '10'
+set policy local-route rule 101 source address '203.0.113.254'
+set policy local-route rule 101 source address '203.0.113.253'
+set policy local-route rule 101 source address '198.51.100.0/24'
+```
+
+
+# Clamp MSS for a specific IP
+
+This example shows how to target an MSS clamp (in our example to 1360 bytes)
+to a specific destination IP.
+
+```none
+set policy route IP-MSS-CLAMP rule 10 description 'Clamp TCP session MSS to 1360 for 198.51.100.30'
+set policy route IP-MSS-CLAMP rule 10 destination address '198.51.100.30/32'
+set policy route IP-MSS-CLAMP rule 10 protocol 'tcp'
+set policy route IP-MSS-CLAMP rule 10 set tcp-mss '1360'
+set policy route IP-MSS-CLAMP rule 10 tcp flags 'SYN'
+```
+
+To apply this policy to the correct interface, configure it on the
+interface the inbound local host will send through to reach our
+destined target host (in our example eth1).
+
+```none
+set policy route IP-MSS-CLAMP interface eth1
+```
+
+You can view that the policy is being correctly (or incorrectly) utilised
+with the following command:
+
+```none
+show policy route statistics
+```
diff --git a/docs/configuration/policy/extcommunity-list.md b/docs/configuration/policy/extcommunity-list.md
new file mode 100644
index 00000000..5247c13c
--- /dev/null
+++ b/docs/configuration/policy/extcommunity-list.md
@@ -0,0 +1,33 @@
+# BGP - Extended Community List
+
+VyOS provides policies commands exclusively for BGP traffic filtering and
+manipulation: **extcommunity-list** is one of them.
+
+## Configuration
+
+### policy extcommunity-list
+
+```{cfgcmd} set policy extcommunity-list \<text\>
+
+Creat extcommunity-list policy identified by name \<text\>.
+```
+```{cfgcmd} set policy extcommunity-list \<text\> description \<text\>
+
+Set description for extcommunity-list policy.
+```
+```{cfgcmd} set policy extcommunity-list \<text\> rule \<1-65535\> action \<permit|deny\>
+
+Set action to take on entries matching this rule.
+```
+```{cfgcmd} set policy extcommunity-list \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule.
+```
+```{cfgcmd} set policy extcommunity-list \<text\> rule \<1-65535\> regex \<text\>
+
+Regular expression to match against an extended community list, where text
+could be:
+* \<aa:nn:nn\>: Extended community list regular expression.
+* \<rt aa:nn:nn\>: Route Target regular expression.
+* \<soo aa:nn:nn\>: Site of Origin regular expression.
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/index.md b/docs/configuration/policy/index.md
new file mode 100644
index 00000000..f919e70a
--- /dev/null
+++ b/docs/configuration/policy/index.md
@@ -0,0 +1,53 @@
+---
+lastproofread: '2021-07-12'
+---
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# Policy
+
+Policies are used for filtering and traffic management. With policies, network
+administrators could filter and treat traffic
+according to their needs.
+
+There could be a wide range of routing policies. Some examples are listed
+below:
+- Filter traffic based on source/destination address.
+- Set some metric to routes learned from a particular neighbor.
+- Set some attributes (like AS PATH or Community value) to advertised routes
+ to neighbors.
+- Prefer a specific routing protocol routes over another routing protocol
+ running on the same router.
+
+Policies, in VyOS, are implemented using FRR filtering and route maps. Detailed
+information of FRR could be found in <http://docs.frrouting.org/>
+
+## Policy Sections
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+access-list
+prefix-list
+route
+route-map
+local-route
+as-path-list
+community-list
+extcommunity-list
+large-community-list
+```
+
+## Examples
+
+Examples of policies usage:
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+examples
+```
diff --git a/docs/configuration/policy/large-community-list.md b/docs/configuration/policy/large-community-list.md
new file mode 100644
index 00000000..23b9a85a
--- /dev/null
+++ b/docs/configuration/policy/large-community-list.md
@@ -0,0 +1,29 @@
+# BGP - Large Community List
+
+VyOS provides policies commands exclusively for BGP traffic filtering and
+manipulation: **large-community-list** is one of them.
+
+## Configuration
+
+### policy large-community-list
+
+```{cfgcmd} set policy large-community-list \<text\>
+
+Create large-community-list policy identified by name `<text>`.
+```
+```{cfgcmd} set policy large-community-list \<text\> description \<text\>
+
+Set description for large-community-list policy.
+```
+```{cfgcmd} set policy large-community-list \<text\> rule \<1-65535\> action \<permit|deny\>
+
+Set action to take on entries matching this rule.
+```
+```{cfgcmd} set policy large-community-list \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule.
+```
+```{cfgcmd} set policy large-community-list \<text\> rule \<1-65535\> regex \<aa:nn:nn\>
+
+Regular expression to match against a large community list.
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/local-route.md b/docs/configuration/policy/local-route.md
new file mode 100644
index 00000000..527a2380
--- /dev/null
+++ b/docs/configuration/policy/local-route.md
@@ -0,0 +1,100 @@
+# Local Route Policy
+
+Policies for local traffic are defined in this section.
+
+## Configuration
+
+### Local Route IPv4
+
+```{cfgcmd} set policy local-route rule \<1-32765\> set table \<1-200|main\>
+
+Set the routing table to use for forwarding matching packets.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> set vrf \<vrf|default\>
+
+Set the VRF to use for forwarding matching packets.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> protocol \<protocol\>
+
+Match specified protocol (name or number).
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> fwmark \<1-2147483647\>
+
+Match specified firewall mark (fwmark).
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> source address \<x.x.x.x|x.x.x.x/x\>
+
+Match specified source address or prefix.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> source port \<1-65535\>
+
+Match specified source port.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> destination address \<x.x.x.x|x.x.x.x/x\>
+
+Match specified destination address or prefix.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> destination port \<1-65535\>
+
+Match specified destination port.
+```
+
+```{cfgcmd} set policy local-route rule \<1-32765\> inbound-interface \<interface\>
+
+Match specified inbound interface.
+```
+
+
+### Local Route IPv6
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> set table \<1-200|main\>
+
+Set the routing table to use for forwarding matching packets.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> set vrf \<vrf|default\>
+
+Set the VRF to use for forwarding matching packets.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> protocol \<protocol\>
+
+Match specified protocol (name or number).
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> fwmark \<1-2147483647\>
+
+Match specified firewall mark (fwmark).
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> source address \<h:h:h:h:h:h:h:h|h:h:h:h:h:h:h:h/x\>
+
+Match specified source address or prefix.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> source port \<1-65535\>
+
+Match specified source port.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> destination address \<h:h:h:h:h:h:h:h|h:h:h:h:h:h:h:h/x\>
+
+Match specified destination address or prefix.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> destination port \<1-65535\>
+
+Match specified destination port.
+```
+
+```{cfgcmd} set policy local-route6 rule \<1-32765\> inbound-interface \<interface\>
+
+Match specified inbound interface.
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/prefix-list.md b/docs/configuration/policy/prefix-list.md
new file mode 100644
index 00000000..eb827c77
--- /dev/null
+++ b/docs/configuration/policy/prefix-list.md
@@ -0,0 +1,152 @@
+# Prefix List Policy
+
+Prefix lists provides the most powerful prefix based filtering mechanism. In
+addition to access-list functionality, ip prefix-list has prefix length range
+specification.
+
+If no ip prefix list is specified, it acts as permit. If ip prefix list is
+defined, and no match is found, default deny is applied.
+
+Prefix filtering can be done using prefix-list and prefix-list6.
+
+## Configuration
+
+### IPv4 Prefix Lists (prefix-list)
+
+```{cfgcmd} set policy prefix-list \<text\>
+
+This command creates the new prefix-list policy, identified by `<text>`.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> description \<text\>
+
+Set description for the prefix-list policy.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> rule \<1-65535\> action \<permit|deny\>
+
+This command creates a new rule in the prefix-list and defines an action.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule in the prefix-list.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> rule \<1-65535\> prefix \<x.x.x.x/x\>
+
+Prefix to match against.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> rule \<1-65535\> ge \<0-32\>
+
+Netmask greater than length.
+```
+
+```{cfgcmd} set policy prefix-list \<text\> rule \<1-65535\> le \<0-32\>
+
+Netmask less than length
+```
+
+
+### Example: IPv4 Prefix Lists (prefix-list)
+
+This example creates an IPv4 prefix-list named PL4-EXAMPLE-NAME, defines 3
+rules each with 1 prefix, and matches le (less than/equal to) /32.
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 10 action 'permit'
+
+```
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 10 le '32'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 10 prefix '192.0.2.0/24'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 20 action 'permit'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 20 le '32'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 20 prefix '198.51.100.0/24'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 30 action 'permit'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 30 le '32'
+```
+
+```{cfgcmd} set policy prefix-list PL4-EXAMPLE-NAME rule 30 prefix '203.0.113.0/24'
+```
+
+### IPv6 Prefix Lists (prefix-list6)
+
+```{cfgcmd} set policy prefix-list6 \<text\>
+
+This command creates the new IPv6 prefix-list policy, identified by `<text>`.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> description \<text\>
+
+Set description for the IPv6 prefix-list policy.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> rule \<1-65535\> action \<permit|deny\>
+
+This command creates a new rule in the IPv6 prefix-list and defines an
+action.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> rule \<1-65535\> description \<text\>
+
+Set description for rule in IPv6 prefix-list.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> rule \<1-65535\> prefix \<h:h:h:h:h:h:h:h/x\>
+
+IPv6 prefix.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> rule \<1-65535\> ge \<0-128\>
+
+Netmask greater than length.
+```
+
+```{cfgcmd} set policy prefix-list6 \<text\> rule \<1-65535\> le \<0-128\>
+
+Netmask less than length
+```
+
+### Example: IPv6 Prefix Lists (prefix-list6)
+
+This example creates an IPv6 prefix-list6 named PL6-EXAMPLE-NAME, defines 3
+rules each with 1 prefix, and matches le (less than/equal to) /128.
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 10 action 'permit'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 10 le '128'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 10 prefix '2001:db8:0:0::/64'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 20 action 'permit'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 20 le '128'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 20 prefix '2001:db8:0:1::/64'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 30 action 'permit'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 30 le '128'
+```
+
+```{cfgcmd} set policy prefix-list6 PL6-EXAMPLE-NAME rule 30 prefix '2001:db8:0:2::/64'
+``` \ No newline at end of file
diff --git a/docs/configuration/policy/route-map.md b/docs/configuration/policy/route-map.md
new file mode 100644
index 00000000..624b542c
--- /dev/null
+++ b/docs/configuration/policy/route-map.md
@@ -0,0 +1,439 @@
+# Route Map Policy
+
+Route map is a powerfull command, that gives network administrators a very
+useful and flexible tool for traffic manipulation.
+
+## Configuration
+
+### Route Map
+
+```{cfgcmd} set policy route-map \<text\>
+
+ This command creates a new route-map policy, identified by \<text\>.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> description \<text\>
+
+Set description for the route-map policy.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> action \<permit|deny\>
+
+Set action for the route-map policy.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> call \<text\>
+
+Call another route-map policy on match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> continue \<1-65535\>
+
+Jump to a different rule in this route-map on a match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> description \<text\>
+
+Set description for the rule in the route-map policy.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match as-path \<text\>
+
+BGP as-path list to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match community community-list \<text\>
+
+BGP community-list to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match community exact-match
+
+Set BGP community-list to exactly match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match extcommunity \<text\>
+
+BGP extended community to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match interface \<text\>
+
+First hop interface of a route to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip address access-list \<1-2699\>
+
+IP address of route to match, based on access-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip address prefix-list \<text\>
+
+IP address of route to match, based on prefix-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip address prefix-len \<0-32\>
+
+IP address of route to match, based on specified prefix-length.
+Note that this can be used for kernel routes only.
+Do not apply to the routes of dynamic routing protocols (e.g. BGP,
+RIP, OSFP), as this can lead to unexpected results..
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip nexthop access-list \<1-2699\>
+
+IP next-hop of route to match, based on access-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip nexthop address \<x.x.x.x\>
+
+IP next-hop of route to match, based on ip address.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip nexthop prefix-len \<0-32\>
+
+IP next-hop of route to match, based on prefix length.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip nexthop prefix-list \<text\>
+
+IP next-hop of route to match, based on prefix-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip nexthop type \<blackhole\>
+
+IP next-hop of route to match, based on type.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip route-source access-list \<1-2699\>
+
+IP route source of route to match, based on access-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ip route-source prefix-list \<text\>
+
+IP route source of route to match, based on prefix-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ipv6 address access-list \<text\>
+
+IPv6 address of route to match, based on IPv6 access-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ipv6 address prefix-list \<text\>
+
+IPv6 address of route to match, based on IPv6 prefix-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ipv6 address prefix-len \<0-128\>
+
+IPv6 address of route to match, based on specified prefix-length.
+Note that this can be used for kernel routes only.
+Do not apply to the routes of dynamic routing protocols (e.g. BGP,
+RIP, OSFP), as this can lead to unexpected results..
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match ipv6 nexthop \<h:h:h:h:h:h:h:h\>
+
+Nexthop IPv6 address to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match large-community large-community-list \<text\>
+
+Match BGP large communities.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match local-preference \<0-4294967295\>
+
+Match local preference.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match metric \<1-65535\>
+
+Match route metric.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match origin \<egp|igp|incomplete\>
+
+Boarder Gateway Protocol (BGP) origin code to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match peer \<x.x.x.x\>
+
+Peer IP address to match.
+```
+
+
+````{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match protocol \<protocol\>
+
+```{eval-rst}
+Source protocol to match.
+ * ``babel`` - Babel routing protocol (Babel)
+ * ``bgp`` - Border Gateway Protocol (BGP)
+ * ``connected`` - Connected routes (directly attached subnet or host)
+ * ``isis`` - Intermediate System to Intermediate System (IS-IS)
+ * ``kernel`` - Kernel routes
+ * ``ospf`` - Open Shortest Path First (OSPFv2)
+ * ``ospfv3`` - Open Shortest Path First (IPv6) (OSPFv3)
+ * ``rip`` - Routing Information Protocol (RIP)
+ * ``ripng`` - Routing Information Protocol next-generation (IPv6) (RIPng)
+ * ``static`` - Statically configured routes
+ * ``table`` - Non-main Kernel Routing Table
+ * ``vnc`` - Virtual Network Control (VNC)
+```
+````
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match rpki \<invalid|notfound|valid\>
+
+Match RPKI validation result.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match source-vrf \<text\>
+
+Source VRF to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> match tag \<1-65535\>
+
+Route tag to match.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> on-match goto \<1-65535\>
+
+Exit policy on match: go to rule <1-65535>
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> on-match next
+
+Exit policy on match: go to next sequence number.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set aggregator \<as|ip\> \<1-4294967295|x.x.x.x\>
+
+BGP aggregator attribute: AS number or IP address of an aggregation.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set as-path exclude \<1-4294967295 | all\>
+
+Drop AS-NUMBER from the BGP AS path.
+
+If ``all`` is specified, remove all AS numbers from the AS_PATH of the BGP
+path's NLRI.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set as-path prepend \<1-4294967295\>
+
+Prepend the given string of AS numbers to the AS_PATH of the BGP path's NLRI.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set as-path prepend-last-as \<n\>
+
+Prepend the existing last AS number (the leftmost ASN) to the AS_PATH.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set atomic-aggregate
+
+BGP atomic aggregate attribute.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set community \<add|replace\> \<community\>
+
+Add or replace BGP community attribute in format ``<0-65535:0-65535>``
+or from well-known community list
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set community none
+
+Delete all BGP communities
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set community delete \<text\>
+
+Delete BGP communities matching the community-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set large-community \<add|replace\> \<GA:LDP1:LDP2\>
+
+Add or replace BGP large-community attribute in format
+``<0-4294967295:0-4294967295:0-4294967295>``
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set large-community none
+
+Delete all BGP large-communities
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set large-community delete \<text\>
+
+Delete BGP communities matching the large-community-list.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set extcommunity bandwidth \<1-25600|cumulative|num-multipaths\>
+
+Set extcommunity bandwidth
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set extcommunity bandwidth-non-transitive
+
+The link bandwidth extended community is encoded as non-transitive
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set extcommunity rt \<text\>
+
+Set route target value in format ``<0-65535:0-4294967295>`` or ``<IP:0-65535>``.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set extcommunity soo \<text\>
+
+Set site of origin value in format ``<0-65535:0-4294967295>`` or ``<IP:0-65535>``.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set extcommunity none
+
+Clear all BGP extcommunities.
+```
+
+
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set distance \<0-255\>
+
+Locally significant administrative distance.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ip-next-hop \<x.x.x.x\>
+
+Nexthop IP address.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ip-next-hop unchanged
+
+Set the next-hop as unchanged. Pass through the route-map without
+changing its value
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ip-next-hop peer-address
+
+Set the BGP nexthop address to the address of the peer. For an incoming
+route-map this means the ip address of our peer is used. For an
+outgoing route-map this means the ip address of our self is used to
+establish the peering with our neighbor.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ipv6-next-hop \<global|local\> \<h:h:h:h:h:h:h:h\>
+
+Nexthop IPv6 address.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ipv6-next-hop peer-address
+
+Set the BGP nexthop address to the address of the peer. For an incoming
+route-map this means the ip address of our peer is used. For an
+outgoing route-map this means the ip address of our self is used to
+establish the peering with our neighbor.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set ipv6-next-hop prefer-global
+
+For Incoming and Import Route-maps if we receive a v6 global and v6 LL
+address for the route, then prefer to use the global address as the
+nexthop.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set local-preference \<0-4294967295\>
+
+Set BGP local preference attribute.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set metric \<+/-metric|0-4294967295|rtt|+rtt|-rtt\>
+
+Set the route metric. When used with BGP, set the BGP attribute MED
+to a specific value. Use ``+/-`` to add or subtract the specified value
+to/from the existing/MED. Use ``rtt`` to set the MED to the round trip
+time or ``+rtt/-rtt`` to add/subtract the round trip time to/from the MED.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set metric-type \<type-1|type-2\>
+
+Set OSPF external metric-type.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set origin \<igp|egp|incomplete\>
+
+Set BGP origin code.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set originator-id \<x.x.x.x\>
+
+Set BGP originator ID attribute.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set src \<x.x.x.x|h:h:h:h:h:h:h:h\>
+
+Set source IP/IPv6 address for route.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set table \<1-200\>
+
+Set prefixes to table.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set tag \<1-65535\>
+
+Set tag value for routing protocol.
+```
+```{cfgcmd} set policy route-map \<text\> rule \<1-65535\> set weight \<0-4294967295\>
+
+Set BGP weight attribute
+```
+
+### List of well-known communities
+
+> - `local-as` - Well-known communities value NO_EXPORT_SUBCONFED 0xFFFFFF03
+> - `no-advertise` - Well-known communities value NO_ADVERTISE 0xFFFFFF02
+> - `no-export` - Well-known communities value NO_EXPORT 0xFFFFFF01
+> - `graceful-shutdown` - Well-known communities value GRACEFUL_SHUTDOWN 0xFFFF0000
+> - `accept-own` - Well-known communities value ACCEPT_OWN 0xFFFF0001
+> - `route-filter-translated-v4` - Well-known communities value ROUTE_FILTER_TRANSLATED_v4 0xFFFF0002
+> - `route-filter-v4` - Well-known communities value ROUTE_FILTER_v4 0xFFFF0003
+> - `route-filter-translated-v6` - Well-known communities value ROUTE_FILTER_TRANSLATED_v6 0xFFFF0004
+> - `route-filter-v6` - Well-known communities value ROUTE_FILTER_v6 0xFFFF0005
+> - `llgr-stale` - Well-known communities value LLGR_STALE 0xFFFF0006
+> - `no-llgr` - Well-known communities value NO_LLGR 0xFFFF0007
+> - `accept-own-nexthop` - Well-known communities value accept-own-nexthop 0xFFFF0008
+> - `blackhole` - Well-known communities value BLACKHOLE 0xFFFF029A
+> - `no-peer` - Well-known communities value NOPEER 0xFFFFFF04
diff --git a/docs/configuration/policy/route.md b/docs/configuration/policy/route.md
new file mode 100644
index 00000000..828bd0f1
--- /dev/null
+++ b/docs/configuration/policy/route.md
@@ -0,0 +1,424 @@
+# Route and Route6 Policy
+
+IPv4 route and IPv6 route policies are defined in this section. These route
+policies can then be associated to interfaces.
+
+## Rule-Sets
+
+A rule-set is a named collection of rules that can be applied to an interface.
+Each rule is numbered, has an action to apply if the rule is matched, and the
+ability to specify the criteria to match. Data packets go through the rules
+from 1 - 999999, at the first match the action of the rule will be executed.
+
+```{cfgcmd} set policy route \<name\> description \<text\>
+
+```
+```{cfgcmd} set policy route6 \<name\> description \<text\>
+
+Provide a rule-set description.
+```
+
+```{cfgcmd} set policy route \<name\> default-log
+```
+
+```{cfgcmd} set policy route6 \<name\> default-log
+
+Option to log packets hitting default-action.
+```
+
+```{cfgcmd} set policy route \<name\> interface \<interface\>
+```
+
+```{cfgcmd} set policy route6 \<name\> interface \<interface\>
+
+Apply routing policy to interface
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> description \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> description \<text\>
+
+Provide a description for each rule.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> log \<enable|disable\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> log \<enable|disable\>
+
+Option to enable or disable log matching rule.
+```
+
+### Matching criteria
+
+There are a lot of matching criteria options available, both for
+`policy route` and `policy route6`. These options are listed
+in this section.
+
+```{cfgcmd} set policy route \<name\> rule \<n\> connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> connection-mark \<1-2147483647\>
+
+Set match criteria based on connection mark.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> mark \<match_criteria\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> mark \<match_criteria\>
+
+Match based on the firewall mark (fwmark), where \<match_criteria\> can be:
+ * \<0-2147483647\> a single fwmark
+ * !\<0-2147483647\> everything except a single fwmark
+ * &lt;start-end&gt; a range of marks
+ * !&lt;start-end&gt; everything except the range of marks
+
+:::{note}
+When using the ``set table`` or ``set vrf`` commands the mark
+settings are ignored and overwritten with a table-specific mark that
+is set to 0x7FFFFFFF - the id of the table/VRF.
+:::
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> source address \<match_criteria\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> destination address \<match_criteria\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> source address \<match_criteria\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> destination address \<match_criteria\>
+
+Set match criteria based on source or destination ipv4|ipv6 address, where
+&lt;match_criteria&gt; could be:
+```
+
+For ipv4:
+: - \<x.x.x.x>: IP address to match.
+ - \<x.x.x.x/x>: Subnet to match.
+ - \<x.x.x.x>-\<x.x.x.x>: IP range to match.
+ - !\<x.x.x.x>: Match everything except the specified address.
+ - !\<x.x.x.x/x>: Match everything except the specified subnet.
+ - !\<x.x.x.x>-\<x.x.x.x>: Match everything except the specified range.
+
+And for ipv6:
+: - \<h:h:h:h:h:h:h:h>: IPv6 address to match.
+ - \<h:h:h:h:h:h:h:h/x>: IPv6 prefix to match.
+ - \<h:h:h:h:h:h:h:h>-\<h:h:h:h:h:h:h:h>: IPv6 range to match.
+ - !\<h:h:h:h:h:h:h:h>: Match everything except the specified address.
+ - !\<h:h:h:h:h:h:h:h/x>: Match everything except the specified prefix.
+ - !\<h:h:h:h:h:h:h:h>-\<h:h:h:h:h:h:h:h>: Match everything except the
+ specified range.
+
+```{cfgcmd} set policy route \<name\> rule \<n\> source group \<address-group|domain-group|mac-group|network-group|port-group\> \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> destination group \<address-group|domain-group|mac-group|network-group|port-group\> \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> source group \<address-group|domain-group|mac-group|network-group|port-group\> \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> destination group \<address-group|domain-group|mac-group|network-group|port-group\> \<text\>
+
+Set match criteria based on source or destination groups, where &lt;text&gt;
+would be the group name/identifier. Prepend character '!' for inverted
+matching criteria.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> destination port \<match_criteria\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> destination port \<match_criteria\>
+
+Set match criteria based on destination port, where \<match_criteria\> could
+be:
+* &lt;port name&gt;: Named port (any name in /etc/services, e.g., http).
+* \<1-65535\>: Numbered port.
+* &lt;start&gt;-&lt;end&gt;: Numbered port range (e.g., 1001-1005).
+
+Multiple destination ports can be specified as a comma-separated list. The
+whole list can also be "negated" using '!'. For example:
+'!22,telnet,http,123,1001-1005'
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> disable
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> disable
+
+Option to disable rule.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> dscp \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> dscp \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> dscp-exclude \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> dscp-exclude \<text\>
+
+Match based on dscp value criteria. Multiple values from 0 to 63
+and ranges are supported.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> fragment \<match-grag|match-non-frag\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> fragment \<match-grag|match-non-frag\>
+
+Set IP fragment match, where:
+* match-frag: Second and further fragments of fragmented packets.
+* match-non-frag: Head fragments or unfragmented packets.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> icmp \<code | type\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> icmpv6 \<code | type\>
+
+Match based on icmp|icmpv6 code and type.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> icmp type-name \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> icmpv6 type-name \<text\>
+
+Match based on icmp|icmpv6 type-name criteria. Use tab for information
+about what type-name criteria are supported.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> ipsec \<match-ipsec|match-none\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> ipsec \<match-ipsec|match-none\>
+
+Set IPSec inbound match criterias, where:
+* match-ipsec: match inbound IPsec packets.
+* match-none: match inbound non-IPsec packets.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> limit burst \<0-4294967295\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> limit burst \<0-4294967295\>
+
+Set maximum number of packets to alow in excess of rate.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> limit rate \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> limit rate \<text\>
+
+Set maximum average matching rate. Format for rate: integer/time_unit, where
+time_unit could be any one of second, minute, hour or day.For example
+1/second implies rule to be matched at an average of once per second.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> protocol \<text | 0-255 | tcp_udp | all \>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> protocol \<text | 0-255 | tcp_udp | all \>
+
+Match a protocol criteria. A protocol number or a name which is defined in:
+``/etc/protocols``. Special names are ``all`` for all protocols and
+``tcp_udp`` for tcp and udp based packets. The ``!`` negates the selected
+protocol.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> packet-length \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> packet-length \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> packet-length-exclude \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> packet-length-exclude \<text\>
+
+Match based on packet length criteria. Multiple values from 1 to 65535
+and ranges are supported.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> packet-type \[broadcast | host | multicast | other\]
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> packet-type \[broadcast | host | multicast | other\]
+
+Match based on packet type criteria.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> recent count \<1-255\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> recent count \<1-255\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> recent time \<1-4294967295\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> recent time \<1-4294967295\>
+
+Set parameters for matching recently seen sources. This match could be used
+by seeting count (source address seen more than <1-255> times) and/or time
+(source address seen in the last <0-4294967295> seconds).
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> state \<established | invalid | new | related\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> state \<established | invalid | new | related\>
+
+Set match criteria based on session state.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> tcp flags \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> tcp flags \<text\>
+
+Set match criteria based on tcp flags. Allowed values for TCP flags: SYN ACK
+FIN RST URG PSH ALL. When specifying more than one flag, flags should be
+comma-separated. For example : value of 'SYN,!ACK,!FIN,!RST' will only match
+packets with the SYN flag set, and the ACK, FIN and RST flags unset.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time monthdays \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time monthdays \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time startdate \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time startdate \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time starttime \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time starttime \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time stopdate \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time stopdate \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time stoptime \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time stoptime \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time weekdays \<text\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time weekdays \<text\>
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> time utc
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> time utc
+
+Time to match the defined rule.
+```
+
+```{cfgcmd} set policy route rule \<n\> ttl \<eq | gt | lt\> \<0-255\>
+
+Match time to live parameter, where 'eq' stands for 'equal'; 'gt' stands for
+'greater than', and 'lt' stands for 'less than'.
+```
+
+```{cfgcmd} set policy route6 rule \<n\> hop-limit \<eq | gt | lt\> \<0-255\>
+
+Match hop-limit parameter, where 'eq' stands for 'equal'; 'gt' stands for
+'greater than', and 'lt' stands for 'less than'.
+```
+
+### Actions
+
+When mathcing all patterns defined in a rule, then different actions can
+be made. This includes droping the packet, modifying certain data, or
+setting a different routing table.
+
+```{cfgcmd} set policy route \<name\> rule \<n\> action drop
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> action drop
+
+Set rule action to drop.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set connection-mark \<1-2147483647\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set connection-mark \<1-2147483647\>
+
+Set a specific connection mark.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set dscp \<0-63\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set dscp \<0-63\>
+
+Set packet modifications: Packet Differentiated Services Codepoint (DSCP)
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set mark \<1-2147483647\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set mark \<1-2147483647\>
+
+Set a specific packet mark.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set table \<main | 1-200\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set table \<main | 1-200\>
+
+Set the routing table to forward packet with.
+
+:::{note}
+When using the ``set table`` or ``set vrf`` commands matching
+against the mark is not possible, because it gets overwritten with a
+table-specific mark that is 0x7FFFFFFF - the id of the table/VRF.
+:::
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set tcp-mss \<500-1460\>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set tcp-mss \<500-1460\>
+
+Set packet modifications: Explicitly set TCP Maximum segment size value.
+```
+
+```{cfgcmd} set policy route \<name\> rule \<n\> set vrf \<default | text \>
+```
+
+```{cfgcmd} set policy route6 \<name\> rule \<n\> set vrf \<default | text \>
+
+Set the VRF to forward packet with.
+
+:::{note}
+When using the ``set table`` or ``set vrf`` commands matching
+against the mark is not possible, because it gets overwritten with a
+table-specific mark that is 0x7FFFFFFF - the id of the table/VRF.
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/protocols/arp.md b/docs/configuration/protocols/arp.md
new file mode 100644
index 00000000..7d9bf4f9
--- /dev/null
+++ b/docs/configuration/protocols/arp.md
@@ -0,0 +1,72 @@
+```{eval-rst}
+.. meta::
+ :description: The Address Resolution Protocol (ARP) resolves
+ network-layer addresses to link-layer MAC addresses.
+ :keywords: arp, network, protocol, mac, address, ipv4, static
+```
+
+(routing_static_arp)=
+
+# ARP
+
+The {abbr}`ARP (Address Resolution Protocol)` resolves IPv4 network layer addresses
+to link layer MAC addresses.
+addresses. This mapping is essential for communication within the Internet
+Protocol suite. ARP was standardized in 1982 by {rfc}`826` (STD 37).
+
+:::{note}
+In Internet Protocol version 6 (IPv6) networks, address resolution is
+performed by the Neighbor Discovery Protocol (NDP).
+:::
+
+Use the following commands to configure or view ARP table entries.
+
+## Configuration
+
+```{eval-rst}
+.. cfgcmd:: set protocols static arp interface <interface> address <host> mac <mac>
+
+ **Configure a static ARP entry on the specified interface.**
+
+ This creates a permanent mapping between an IP address and a MAC address
+ on the specified interface.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols static arp interface eth0 address 192.0.2.1 mac 01:23:45:67:89:01
+```
+
+## Operation
+
+```{eval-rst}
+.. opcmd:: show protocols static arp
+
+ Show all ARP table entries across all interfaces.
+
+ .. code-block:: none
+
+ vyos@vyos:~$ show protocols static arp
+ Address HWtype HWaddress Flags Mask Iface
+ 10.1.1.1 ether 00:53:00:de:23:2e C eth1
+ 10.1.1.100 ether 00:53:00:de:23:aa CM eth1
+```
+
+```{eval-rst}
+.. opcmd:: show protocols static arp interface <interface>
+
+ Show all ARP table entries for the specific interface.
+
+ Example for ``eth1``:
+
+ .. code-block:: none
+
+ vyos@vyos:~$ show protocols static arp interface eth1
+ Address HWtype HWaddress Flags Mask Iface
+ 10.1.1.1 ether 00:53:00:de:23:2e C eth1
+ 10.1.1.100 ether 00:53:00:de:23:aa CM eth1
+```
+
+[arp]: https://en.wikipedia.org/wiki/Address_Resolution_Protocol
+
diff --git a/docs/configuration/protocols/babel.md b/docs/configuration/protocols/babel.md
new file mode 100644
index 00000000..b03e9fa4
--- /dev/null
+++ b/docs/configuration/protocols/babel.md
@@ -0,0 +1,296 @@
+```{eval-rst}
+.. meta::
+ :description: The Babel routing protocol provides robust and efficient
+ routing for wired and wireless mesh networks.
+ :keywords: babel, routing, protocol, wireless, mesh, network, metric,
+ ipv4, ipv6
+```
+
+(babel)=
+
+# Babel
+
+The Babel protocol provides robust and efficient routing for both wired and
+wireless mesh networks. By default, Babel uses hop-count metrics on wired links
+and a variant of Expected Transmission Count (ETX) on wireless links.
+Administrators can configure Babel to account for radio diversity,
+automatically compute link latency, and include that latency in the routing
+metric. {rfc}`8966` defines the Babel protocol.
+
+Babel is a dual-stack protocol. A single Babel instance routes both IPv4 and
+IPv6 traffic simultaneously.
+
+## General configuration
+
+VyOS does not require a specific command to start the Babel process. The system
+automatically starts the routing process when you configure the first
+Babel-enabled interface.
+
+```{cfgcmd} set protocols babel interface \<interface\>
+
+**Enable Babel routing on the specified interface.**
+
+The system immediately begins sending and receiving Babel packets on this
+interface.
+```
+
+## Optional configuration
+
+```{cfgcmd} set protocols babel parameters diversity
+
+**Enable radio-frequency diversity routing for the Babel process.**
+
+Enabling this feature is highly recommended for networks with many
+wireless nodes.
+
+:::{note}
+When you enable diversity routing, you should also configure the
+``diversity-factor`` and ``channel`` parameters.
+:::
+```
+
+```{cfgcmd} set protocols babel parameters diversity-factor \<1-256\>
+
+**Configure the multiplicative factor for diversity routing, in units of
+1/256.**
+
+Lower multiplicative factors give greater weight to diversity in route
+selection. The default value is 256, which disables diversity routing.
+On nodes with multiple independent radios, configure a value of 128 or less.
+```
+
+```{cfgcmd} set protocols babel parameters resend-delay \<20-655340\>
+
+**Configure the delay in milliseconds before the system resends an
+important request or update.**
+
+The default value is 2000 ms.
+```
+
+```{cfgcmd} set protocols babel parameters smoothing-half-life \<0-65534\>
+
+**Configure the time constant, in seconds, for the smoothing algorithm used
+to implement hysteresis.**
+
+Higher values reduce route oscillation but slightly increase convergence
+time. A value of 0 disables hysteresis and is suitable for wired networks.
+The default is 4 seconds.
+```
+
+## Interfaces configuration
+
+```{cfgcmd} set protocols babel interface \<interface\> type \<auto|wired|wireless\>
+
+**Configure the network type for the Babel-enabled interface.**
+
+Choose from the following:
+
+* ``auto``: Babel automatically detects if an interface is wired or
+ wireless.
+* ``wired``: Babel enables optimizations for wired interfaces.
+* ``wireless``: Babel disables optimizations suitable only for wired
+ interfaces. Specifying wireless is always correct, but may cause slower
+ convergence and increased routing traffic.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> split-horizon \<default|disable|enable\>
+
+**Configure the split-horizon routing behavior for the specified
+interface.**
+
+Use one of the following options:
+
+* ``default``: Babel automatically enables split-horizon on wired
+ interfaces and disables it on wireless interfaces.
+* ``enable``: Babel enables split-horizon on the interface. This
+ optimization should be used only on symmetric, transitive (wired)
+ networks.
+* ``disable``: Babel disables split-horizon on the interface. Disabling
+ split-horizon is always safe and correct.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> hello-interval \<20-655340\>
+
+**Configure the interval, in milliseconds, between scheduled hello messages
+on the specified interface.**
+
+On wired links, Babel detects link failures within two hello intervals.
+On wireless links, link quality is reestimated at each interval. The
+default is 4000 ms.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> update-interval \<20-655340\>
+
+**Configure the interval, in milliseconds, between scheduled routing
+updates on the specified interface.**
+
+Because Babel uses triggered updates extensively, you can increase this
+value on reliable links with minimal packet loss. The default is 20000 ms.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> rxcost \<1-65534\>
+
+**Configure the base receive cost for the specified interface.**
+
+Babel applies this value based on the configured network type:
+
+* ``wired``: The value is the routing cost advertised to neighboring
+ routers.
+* ``wireless``: The value is a multiplier used to compute the ETX
+ (Expected Transmission Count) reception cost.
+
+The default value is 256.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> rtt-decay \<1-256\>
+
+**Configure the decay factor for the exponential moving average of RTT
+samples, in units of 1/256.**
+
+Higher values discard older samples faster. The default value is 42.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> rtt-min \<1-65535\>
+
+**Configure the minimum RTT, in milliseconds, at which the cost to a
+neighbor begins to increase.**
+
+The additional cost is linear in (rtt - rtt-min). The default value is 10 ms.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> rtt-max \<1-65535\>
+
+**Configure the maximum RTT, in milliseconds, above which the cost to a
+neighbor stops increasing.**
+
+The default value is 120 ms.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> max-rtt-penalty \<0-65535\>
+
+**Configure the maximum cost added to a neighbor when RTT meets or exceeds
+rtt-max.**
+
+Setting this value to 0 disables RTT-based costs. The default value is 150.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> enable-timestamps
+
+**Configure adding timestamps to each Hello and IHU message to calculate
+RTT values.**
+
+Enabling timestamps is recommended for tunnel interfaces.
+```
+
+```{cfgcmd} set protocols babel interface \<interface\> channel \<1-254|interfering|noninterfering\>
+
+**Configure the channel identifier that diversity routing uses for the
+specified interface.**
+
+Interfaces interfere with each other based on the assigned channel
+identifier:
+
+* ``1–254``: The interface interferes with interfaces sharing the same
+ channel number and with interfaces configured as ``interfering``.
+* ``interfering``: The interface interferes with all others except those
+ configured as ``noninterfering``.
+* ``noninterfering``: The interface interferes only with itself.
+```
+
+## Redistribution configuration
+
+```{cfgcmd} set protocols babel redistribute \<ipv4|ipv6\> \<route source\>
+
+**Configure the redistribution of routing information from the specified
+route source into the Babel process.**
+
+The following route sources are available:
+
+* **ipv4:** ``bgp``, ``connected``, ``eigrp``, ``isis``, ``kernel``,
+ ``nhrp``, ``ospf``, ``rip``, ``static``
+* **ipv6:** ``bgp``, ``connected``, ``eigrp``, ``isis``, ``kernel``,
+ ``nhrp``, ``ospfv3``, ``ripng``, ``static``
+```
+
+```{cfgcmd} set protocols babel distribute-list \<ipv4|ipv6\> access-list \<in|out\> \<number\>
+
+**Configure global Babel route filtering using an access list.**
+
+Specify the direction in which the access list is applied:
+
+* ``in``: Filters incoming routes.
+* ``out``: Filters outgoing routes.
+```
+
+```{cfgcmd} set protocols babel distribute-list \<ipv4|ipv6\> interface \<interface\> access-list \<in|out\> \<number\>
+
+**Configure Babel route filtering on the specified interface using an
+access list.**
+
+Specify the direction in which the access list is applied:
+
+* ``in``: Filters incoming routes.
+* ``out``: Filters outgoing routes.
+```
+
+```{cfgcmd} set protocols babel distribute-list \<ipv4|ipv6\> prefix-list \<in|out\> \<name\>
+
+**Configure global Babel route filtering using a prefix list.**
+
+Specify the direction in which the prefix list is applied:
+
+* ``in``: Filters incoming routes.
+* ``out``: Filters outgoing routes.
+```
+
+```{cfgcmd} set protocols babel distribute-list \<ipv4|ipv6\> interface \<interface\> prefix-list \<in|out\> \<name\>
+
+**Configure Babel route filtering on the specified interface using a
+prefix list.**
+
+Specify the direction in which the prefix list is applied:
+
+* ``in``: Filters incoming routes.
+* ``out``: Filters outgoing routes.
+```
+
+## Configuration example
+
+### Basic two-node babel network
+
+**Goal:** The following example connects two routers (Node 1 and Node 2) via
+their eth0 interfaces and uses the Babel routing protocol to advertise
+(redistribute) each router's locally configured networks (represented by
+loopback addresses) to one another.
+
+**Node 1:**
+
+```none
+# Configure the loopback (local networks) and physical (eth0) addresses
+set interfaces loopback lo address 10.1.1.1/32
+set interfaces loopback lo address fd12:3456:dead:beef::1/128
+set interfaces ethernet eth0 address 192.168.1.1/24
+
+# Enable Babel on the physical link
+set protocols babel interface eth0 type wired
+
+# Instruct Babel to advertise (redistribute) the locally configured networks
+set protocols babel redistribute ipv4 connected
+set protocols babel redistribute ipv6 connected
+```
+
+**Node 2:**
+
+```none
+# Configure the loopback (local networks) and physical (eth0) addresses
+set interfaces loopback lo address 10.2.2.2/32
+set interfaces loopback lo address fd12:3456:beef:dead::2/128
+set interfaces ethernet eth0 address 192.168.1.2/24
+
+# Enable Babel on the physical link
+set protocols babel interface eth0 type wired
+
+# Tell Babel to advertise (redistribute) the locally configured networks
+set protocols babel redistribute ipv4 connected
+set protocols babel redistribute ipv6 connected
+```
diff --git a/docs/configuration/protocols/bfd.md b/docs/configuration/protocols/bfd.md
new file mode 100644
index 00000000..59541abc
--- /dev/null
+++ b/docs/configuration/protocols/bfd.md
@@ -0,0 +1,205 @@
+---
+lastproofread: '2023-01-27'
+---
+
+```{include} /_include/need_improvement.txt
+```
+
+(routing-bfd)=
+
+# BFD
+
+{abbr}`BFD (Bidirectional Forwarding Detection)` is described and extended by
+the following RFCs: {rfc}`5880`, {rfc}`5881` and {rfc}`5883`.
+
+In the age of very fast networks, a second of unreachability may equal millions of lost packets.
+The idea behind BFD is to detect very quickly when a peer is down and take action extremely fast.
+
+BFD sends lots of small UDP packets very quickly to ensures that the peer is still alive.
+
+This allows avoiding the timers defined in BGP and OSPF protocol to expires.
+
+## Configure BFD
+
+```{cfgcmd} set protocols bfd peer \<address\>
+
+Set BFD peer IPv4 address or IPv6 address
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> echo-mode
+
+Enables the echo transmission mode
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> multihop
+
+Allow this BFD peer to not be directly connected
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> source [address \<address\> | interface \<interface\>]
+
+Bind listener to specific interface/address, mandatory for IPv6
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> interval echo-interval \<10-60000\>
+
+The minimal echo receive transmission interval that this system is
+capable of handling
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> interval multiplier \<2-255\>
+
+Remote transmission interval will be multiplied by this value
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> interval [receive | transmit] \<10-60000\>
+
+Interval in milliseconds
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> shutdown
+
+Disable a BFD peer
+```
+
+```{cfgcmd} set protocols bfd peer \<address\> minimum-ttl \<1-254\>
+
+For multi hop sessions only. Configure the minimum expected TTL for an
+incoming BFD control packet.
+
+This feature serves the purpose of thightening the packet validation
+requirements to avoid receiving BFD control packets from other sessions.
+```
+
+### Enable BFD in BGP
+
+```{cfgcmd} set protocols bgp neighbor \<neighbor\> bfd
+
+Enable BFD on a single BGP neighbor
+```
+
+```{cfgcmd} set protocols bgp peer-group \<neighbor\> bfd
+
+Enable BFD on a BGP peer group
+```
+
+### Enable BFD in OSPF
+
+```{cfgcmd} set protocols ospf interface \<interface\> bfd
+
+ Enable BFD for OSPF on an interface
+
+```
+
+```{cfgcmd} set protocols ospfv3 interface \<interface\> bfd
+
+Enable BFD for OSPFv3 on an interface
+```
+
+### Enable BFD in ISIS
+
+```{cfgcmd} set protocols isis \<name\> interface \<interface\> bfd
+
+Enable BFD for ISIS on an interface
+
+```
+
+## Operational Commands
+
+```{opcmd} show bfd peers
+
+ Show all BFD peers
+
+ :::{code-block} none
+ BFD Peers:
+ peer 198.51.100.33 vrf default interface eth4.100
+ ID: 4182341893
+ Remote ID: 12678929647
+ Status: up
+ Uptime: 1 month(s), 16 hour(s), 29 minute(s), 38 second(s)
+ Diagnostics: ok
+ Remote diagnostics: ok
+ Local timers:
+ Receive interval: 300ms
+ Transmission interval: 300ms
+ Echo transmission interval: 50ms
+ Remote timers:
+ Receive interval: 300ms
+ Transmission interval: 300ms
+ Echo transmission interval: 0ms
+
+ peer 198.51.100.55 vrf default interface eth4.101
+ ID: 4618932327
+ Remote ID: 3312345688
+ Status: up
+ Uptime: 20 hour(s), 16 minute(s), 19 second(s)
+ Diagnostics: ok
+ Remote diagnostics: ok
+ Local timers:
+ Receive interval: 300ms
+ Transmission interval: 300ms
+ Echo transmission interval: 50ms
+ Remote timers:
+ Receive interval: 300ms
+ Transmission interval: 300ms
+ Echo transmission interval: 0ms
+ :::
+```
+
+## BFD Static Route Monitoring
+
+
+A monitored static route conditions the installation to the RIB on the BFD
+session running state: when BFD session is up the route is installed to RIB,
+but when the BFD session is down it is removed from the RIB.
+
+
+### Configuration
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> bfd profile \<profile\>
+
+Configure a static route for \<subnet\> using gateway \<address\>
+and use the gateway address as BFD peer destination address.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> bfd multi-hop source \<address\> profile \<profile\>
+
+Configure a static route for \<subnet\> using gateway \<address\>,
+use source address to indentify the peer when is multi-hop session
+and the gateway address as BFD peer destination address.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> bfd profile \<profile\>
+
+Configure a static route for \<subnet\> using gateway \<address\>
+and use the gateway address as BFD peer destination address.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> bfd multi-hop source \<address\> profile \<profile\>
+
+Configure a static route for \<subnet\> using gateway \<address\>,
+use source address to indentify the peer when is multi-hop session
+and the gateway address as BFD peer destination address.
+```
+
+(bfd-operational-commands)=
+
+## Operational Commands
+
+```{opcmd} show bfd static routes
+
+Showing BFD monitored static routes
+
+:::{code-block} none
+Showing BFD monitored static routes:
+
+ Next hops:
+ VRF default IPv4 Unicast:
+ 10.10.13.3/32 peer 192.168.2.3 (status: installed)
+ 172.16.10.3/32 peer 192.168.10.1 (status: uninstalled)
+
+ VRF default IPv4 Multicast:
+
+ VRF default IPv6 Unicast:
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/protocols/bgp.md b/docs/configuration/protocols/bgp.md
new file mode 100644
index 00000000..0af79f6e
--- /dev/null
+++ b/docs/configuration/protocols/bgp.md
@@ -0,0 +1,1414 @@
+(routing-bgp)=
+
+# BGP
+
+{abbr}`BGP (Border Gateway Protocol)` is one of the Exterior Gateway Protocols
+and the de facto standard interdomain routing protocol. The latest BGP version
+is 4. BGP-4 is described in {rfc}`1771` and updated by {rfc}`4271`. {rfc}`2858`
+adds multiprotocol support to BGP.
+
+VyOS makes use of {abbr}`FRR (Free Range Routing)` and we would like to thank
+them for their effort!
+
+## Basic Concepts
+
+(bgp-autonomous-systems)=
+
+### Autonomous Systems
+
+From {rfc}`1930`:
+
+> An AS is a connected group of one or more IP prefixes run by one or more
+> network operators which has a SINGLE and CLEARLY DEFINED routing policy.
+
+Each {abbr}`AS (Autonomous System)` has an identifying number associated with it
+called an {abbr}`ASN (Autonomous System Number)`. This is a two octet value
+ranging in value from 1 to 65535. The AS numbers 64512 through 65535 are defined
+as private AS numbers. Private AS numbers must not be advertised on the global
+Internet. The 2-byte AS number range has been exhausted. 4-byte AS numbers are
+specified in {rfc}`6793`, and provide a pool of 4294967296 AS numbers.
+
+The {abbr}`ASN (Autonomous System Number)` is one of the essential elements of
+BGP. BGP is a distance vector routing protocol, and the AS-Path framework
+provides distance vector metric and loop detection to BGP.
+
+```{cfgcmd} set protocols bgp system-as \<asn\>
+
+Set local {abbr}`ASN (Autonomous System Number)` that this router represents.
+This is a a mandatory option!
+```
+
+(bgp-address-families)=
+
+
+### Address Families
+
+
+Multiprotocol extensions enable BGP to carry routing information for multiple
+network layer protocols. BGP supports an Address Family Identifier (AFI) for
+IPv4 and IPv6.
+
+
+(bgp-route-selection)=
+
+
+### Route Selection
+
+
+The route selection process used by FRR's BGP implementation uses the following
+decision criterion, starting at the top of the list and going towards the
+bottom until one of the factors can be used.
+
+
+01. **Weight check**
+
+
+ Prefer higher local weight routes to lower routes.
+
+
+02. **Local preference check**
+
+
+ Prefer higher local preference routes to lower.
+
+
+03. **Local route check**
+
+
+ Prefer local routes (statics, aggregates, redistributed) to received routes.
+
+
+04. **AS path length check**
+
+
+ Prefer shortest hop-count AS_PATHs.
+
+
+05. **Origin check**
+
+
+ Prefer the lowest origin type route. That is, prefer IGP origin routes to
+ EGP, to Incomplete routes.
+
+
+06. **MED check**
+
+
+ Where routes with a MED were received from the same AS, prefer the route
+ with the lowest MED.
+
+
+07. **External check**
+
+
+ Prefer the route received from an external, eBGP peer over routes received
+ from other types of peers.
+
+
+08. **IGP cost check**
+
+
+ Prefer the route with the lower IGP cost.
+
+
+09. **Multi-path check**
+
+
+ If multi-pathing is enabled, then check whether the routes not yet
+ distinguished in preference may be considered equal. If
+ {cfgcmd}`bgp bestpath as-path multipath-relax` is set, all such routes are
+ considered equal, otherwise routes received via iBGP with identical AS_PATHs
+ or routes received from eBGP neighbours in the same AS are considered equal.
+
+
+10. **Already-selected external check**
+
+
+ Where both routes were received from eBGP peers, then prefer the route
+ which is already selected. Note that this check is not applied if
+ {cfgcmd}`bgp bestpath compare-routerid` is configured. This check can
+ prevent some cases of oscillation.
+
+
+11. **Router-ID check**
+
+
+ Prefer the route with the lowest router-ID. If the route has an
+ ORIGINATOR_ID attribute, through iBGP reflection, then that router ID is
+ used, otherwise the router-ID of the peer the route was received from is
+ used.
+
+
+12. **Cluster-List length check**
+
+
+ The route with the shortest cluster-list length is used. The cluster-list
+ reflects the iBGP reflection path the route has taken.
+
+
+13. **Peer address**
+
+
+ Prefer the route received from the peer with the higher transport layer
+ address, as a last-resort tie-breaker.
+
+
+(bgp-capability-negotiation)=
+
+
+### Capability Negotiation
+
+
+When adding IPv6 routing information exchange feature to BGP. There were some
+proposals. {abbr}`IETF (Internet Engineering Task Force)`
+{abbr}`IDR (Inter Domain Routing)` adopted a proposal called Multiprotocol
+Extension for BGP. The specification is described in {rfc}`2283`. The protocol
+does not define new protocols. It defines new attributes to existing BGP. When
+it is used exchanging IPv6 routing information it is called BGP-4+. When it is
+used for exchanging multicast routing information it is called MBGP.
+
+
+*bgpd* supports Multiprotocol Extension for BGP. So if a remote peer supports
+the protocol, *bgpd* can exchange IPv6 and/or multicast routing information.
+
+
+Traditional BGP did not have the feature to detect a remote peer's
+capabilities, e.g. whether it can handle prefix types other than IPv4 unicast
+routes. This was a big problem using Multiprotocol Extension for BGP in an
+operational network. {rfc}`2842` adopted a feature called Capability
+Negotiation. *bgpd* use this Capability Negotiation to detect the remote peer's
+capabilities. If a peer is only configured as an IPv4 unicast neighbor, *bgpd*
+does not send these Capability Negotiation packets (at least not unless other
+optional BGP features require capability negotiation).
+
+
+By default, FRR will bring up peering with minimal common capability for the
+both sides. For example, if the local router has unicast and multicast
+capabilities and the remote router only has unicast capability the local router
+will establish the connection with unicast only capability. When there are no
+common capabilities, FRR sends Unsupported Capability error and then resets the
+connection.
+
+
+## Configuration
+
+
+(bgp-router-configuration)=
+
+
+### BGP Router Configuration
+
+
+First of all you must configure BGP router with the {abbr}`ASN (Autonomous
+System Number)`. The AS number is an identifier for the autonomous system.
+The BGP protocol uses the AS number for detecting whether the BGP connection
+is internal or external. VyOS does not have a special command to start the BGP
+process. The BGP process starts when the first neighbor is configured.
+
+```{cfgcmd} set protocols bgp system-as \<asn\>
+
+Set local autonomous system number that this router represents. This is a
+mandatory option!
+```
+
+#### Peers Configuration
+
+
+##### Defining Peers
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> remote-as \<asn\>
+
+This command creates a new neighbor whose remote-as is \<asn\>. The neighbor
+address can be an IPv4 address or an IPv6 address or an interface to use
+for the connection. The command is applicable for peer and peer group.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> remote-as internal
+
+Create a peer as you would when you specify an ASN, except that if the
+peers ASN is different than mine as specified under the {cfgcmd}`protocols
+bgp <asn>` command the connection will be denied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> remote-as external
+
+Create a peer as you would when you specify an ASN, except that if the
+peers ASN is the same as mine as specified under the {cfgcmd}`protocols
+bgp <asn>` command the connection will be denied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> remote-as auto
+
+Create a peer as you would when you specify an ASN, except that the peers
+remote ASN is detected automatically from the OPEN message.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> local-role \<role\> [strict]
+
+BGP roles are defined in RFC {rfc}`9234` and provide an easy way to
+add route leak prevention, detection and mitigation. The local Role
+value is negotiated with the new BGP Role capability which has a
+built-in check of the corresponding value. In case of a mismatch the
+new OPEN Roles Mismatch Notification <2, 11> would be sent.
+The correct Role pairs are:
+
+Provider - Customer
+
+Peer - Peer
+
+RS-Server - RS-Client
+
+If {cfgcmd}`strict` is set the BGP session won’t become established
+until the BGP neighbor sets local Role on its side. This
+configuration parameter is defined in RFC {rfc}`9234` and is used to
+enforce the corresponding configuration at your counter-parts side.
+
+Routes that are sent from provider, rs-server, or the peer local-role
+(or if received by customer, rs-client, or the peer local-role) will
+be marked with a new Only to Customer (OTC) attribute.
+
+Routes with this attribute can only be sent to your neighbor if your
+local-role is provider or rs-server. Routes with this attribute can
+be received only if your local-role is customer or rs-client.
+
+In case of peer-peer relationship routes can be received only if OTC
+value is equal to your neighbor AS number.
+
+All these rules with OTC will help to detect and mitigate route leaks
+and happen automatically if local-role is set.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> shutdown
+
+This command disable the peer or peer group. To reenable the peer use
+the delete form of this command.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> description \<text\>
+
+Set description of the peer or peer group.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> update-source \<address|interface\>
+
+Specify the IPv4 source address to use for the BGP session to this neighbor,
+may be specified as either an IPv4 address directly or as an interface name.
+```
+
+(bgp-capability-negotiation-1)=
+
+
+##### Capability Negotiation
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> capability dynamic
+
+This command would allow the dynamic update of capabilities over an
+established BGP session.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> capability extended-nexthop
+
+Allow bgp to negotiate the extended-nexthop capability with it’s peer.
+If you are peering over a IPv6 Link-Local address then this capability
+is turned on automatically. If you are peering over a IPv6 Global Address
+then turning on this command will allow BGP to install IPv4 routes with
+IPv6 nexthops if you do not have IPv4 configured on interfaces.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> disable-capability-negotiation
+
+Suppress sending Capability Negotiation as OPEN message optional
+parameter to the peer. This command only affects the peer is
+configured other than IPv4 unicast configuration.
+
+When remote peer does not have capability negotiation feature,
+remote peer will not send any capabilities at all. In that case,
+bgp configures the peer with configured capabilities.
+
+You may prefer locally configured capabilities more than the negotiated
+capabilities even though remote peer sends capabilities. If the peer is
+configured by {cfgcmd}`override-capability`, VyOS ignores received
+capabilities then override negotiated capabilities with configured values.
+
+Additionally you should keep in mind that this feature fundamentally
+disables the ability to use widely deployed BGP features. BGP unnumbered,
+hostname support, AS4, Addpath, Route Refresh, ORF, Dynamic Capabilities,
+and graceful restart.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> override-capability
+
+This command allow override the result of Capability Negotiation with
+local configuration. Ignore remote peer’s capability value.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> strict-capability-match
+
+This command forces strictly compare remote capabilities and local
+capabilities. If capabilities are different, send Unsupported Capability
+error then reset connection.
+
+You may want to disable sending Capability Negotiation OPEN message
+optional parameter to the peer when remote peer does not implement
+Capability Negotiation. Please use {cfgcmd}`disable-capability-negotiation`
+command to disable the feature.
+```
+
+##### Peer Parameters
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> allowas-in number \<number\>
+
+This command accept incoming routes with AS path containing AS
+number with the same value as the current system AS. This is
+used when you want to use the same AS number in your sites,
+but you can’t connect them directly.
+
+ The number parameter (1-10) configures the amount of accepted
+ occurences of the system AS number in AS path.
+
+ This command is only allowed for eBGP peers. It is not applicable
+ for peer groups.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> as-override
+
+This command override AS number of the originating router with
+the local AS number.
+
+Usually this configuration is used in PEs (Provider Edge) to
+replace the incoming customer AS number so the connected CE (
+Customer Edge) can use the same AS number as the other customer
+sites. This allows customers of the provider network to use the
+same AS number across their sites.
+
+This command is only allowed for eBGP peers.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> attribute-unchanged \<as-path|med|next-hop\>
+
+This command specifies attributes to be left unchanged for
+advertisements sent to a peer or peer group.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> maximum-prefix \<number\>
+
+This command specifies a maximum number of prefixes we can receive
+from a given peer. If this number is exceeded, the BGP session
+will be destroyed. The number range is 1 to 4294967295.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> nexthop-self
+
+This command forces the BGP speaker to report itself as the
+next hop for an advertised route it advertised to a neighbor.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> remove-private-as
+
+This command removes the private ASN of routes that are advertised
+to the configured peer. It removes only private ASNs on routes
+advertised to EBGP peers.
+
+If the AS-Path for the route has only private ASNs, the private
+ASNs are removed.
+
+If the AS-Path for the route has a private ASN between public
+ASNs, it is assumed that this is a design choice, and the
+private ASN is not removed.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> soft-reconfiguration inbound
+
+Changes in BGP policies require the BGP session to be cleared. Clearing has a
+large negative impact on network operations. Soft reconfiguration enables you
+to generate inbound updates from a neighbor, change and activate BGP policies
+without clearing the BGP session.
+
+This command specifies that route updates received from this neighbor will be
+stored unmodified, regardless of the inbound policy. When inbound soft
+reconfiguration is enabled, the stored updates are processed by the new
+policy configuration to create new inbound updates.
+
+:::{note}
+Storage of route updates uses memory. If you enable soft
+reconfiguration inbound for multiple neighbors, the amount of memory used
+can become significant.
+:::
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> weight \<number\>
+
+This command specifies a default weight value for the neighbor’s
+routes. The number range is 1 to 65535.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> advertisement-interval \<seconds\>
+
+This command specifies the minimum route advertisement interval for
+the peer. The interval value is 0 to 600 seconds, with the default
+advertisement interval being 0.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> disable-connected-check
+
+This command allows peerings between directly connected eBGP peers
+using loopback addresses without adjusting the default TTL of 1.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> disable-send-community \<extended|standard\>
+
+This command specifies that the community attribute should not be sent
+in route updates to a peer. By default community attribute is sent.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> ebgp-multihop \<number\>
+
+This command allows sessions to be established with eBGP neighbors
+when they are multiple hops away. When the neighbor is not directly
+connected and this knob is not enabled, the session will not establish.
+The number of hops range is 1 to 255. This command is mutually
+exclusive with {cfgcmd}`ttl-security hops`.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> local-as \<asn\> [no-prepend] [replace-as]
+
+Specify an alternate AS for this BGP process when interacting with
+the specified peer or peer group. With no modifiers, the specified
+local-as is prepended to the received AS_PATH when receiving routing
+updates from the peer, and prepended to the outgoing AS_PATH (after
+the process local AS) when transmitting local routes to the peer.
+
+If the {cfgcmd}`no-prepend` attribute is specified, then the supplied
+local-as is not prepended to the received AS_PATH.
+
+If the {cfgcmd}`replace-as` attribute is specified, then only the supplied
+local-as is prepended to the AS_PATH when transmitting local-route
+updates to this peer.
+
+:::{note}
+This command is only allowed for eBGP peers.
+:::
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> passive
+
+Configures the BGP speaker so that it only accepts inbound connections
+from, but does not initiate outbound connections to the peer or peer group.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> password \<text\>
+
+This command specifies a MD5 password to be used with the tcp socket that
+is being used to connect to the remote peer.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> ttl-security hops \<number\>
+
+This command enforces Generalized TTL Security Mechanism (GTSM),
+as specified in {rfc}`5082`. With this command, only neighbors
+that are specified number of hops away will be allowed to
+become neighbors. The number of hops range is 1 to 254. This
+command is mutually exclusive with {cfgcmd}`ebgp-multihop`.
+```
+
+##### Peer Groups
+
+Peer groups are used to help improve scaling by generating the same update
+information to all members of a peer group. Note that this means that the
+routes generated by a member of a peer group will be sent back to that
+originating peer with the originator identifier attribute set to indicated
+the originating peer. All peers not associated with a specific peer group
+are treated as belonging to a default peer group, and will share updates.
+
+```{cfgcmd} set protocols bgp peer-group \<name\>
+
+ This command defines a new peer group. You can specify to the group the same
+ parameters that you can specify for specific neighbors.
+
+ :::{note}
+ If you apply a parameter to an individual neighbor IP address, you
+ override the action defined for a peer group that includes that IP
+ address.
+ :::
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> peer-group \<name\>
+
+This command bind specific peer to peer group with a given name.
+```
+
+#### Network Advertisement Configuration
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> network \<prefix\>
+
+This command is used for advertising IPv4 or IPv6 networks.
+
+ :::{note}
+ By default, the BGP prefix is advertised even if it's not present
+ in the routing table. This behaviour differs from the implementation of
+ some vendors.
+ :::
+```
+
+
+```{cfgcmd} set protocols bgp parameters network-import-check
+
+This configuration modifies the behavior of the network statement. If you
+have this configured the underlying network must exist in the routing table.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> default-originate [route-map \<name\>]
+
+By default, VyOS does not advertise a default route (0.0.0.0/0) even if it is
+in routing table. When you want to announce default routes to the peer, use
+this command. Using optional argument {cfgcmd}`route-map` you can inject the
+default route to given neighbor only if the conditions in the route map are
+met.
+```
+
+#### Route Aggregation Configuration
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> aggregate-address \<prefix\>
+
+This command specifies an aggregate address. The router will also
+announce longer-prefixes inside of the aggregate address.
+```
+
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> aggregate-address \<prefix\> as-set
+
+This command specifies an aggregate address with a mathematical set of
+autonomous systems. This command summarizes the AS_PATH attributes of
+all the individual routes.
+```
+
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> aggregate-address \<prefix\> summary-only
+
+This command specifies an aggregate address and provides that
+longer-prefixes inside of the aggregate address are suppressed
+before sending BGP updates out to peers.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> unsuppress-map \<name\>
+
+This command applies route-map to selectively unsuppress prefixes
+suppressed by summarisation.
+```
+
+#### Redistribution Configuration
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> redistribute <route source>
+
+This command redistributes routing information from the given route source
+to the BGP process. There are six modes available for route source:
+connected, kernel, ospf, rip, static, table.
+```
+
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> redistribute <route source> metric \<number\>
+
+This command specifies metric (MED) for redistributed routes. The
+metric range is 0 to 4294967295. There are six modes available for
+route source: connected, kernel, ospf, rip, static, table.
+```
+
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> redistribute <route source> route-map \<name\>
+
+This command allows to use route map to filter redistributed routes.
+There are six modes available for route source: connected, kernel,
+ospf, rip, static, table.
+```
+
+#### General Configuration
+##### Common parameters
+
+```{cfgcmd} set protocols bgp parameters allow-martian-nexthop
+
+ When a peer receives a martian nexthop as part of the NLRI for a route
+ permit the nexthop to be used as such, instead of rejecting and resetting
+ the connection.
+```
+
+
+```{cfgcmd} set protocols bgp parameters router-id \<id\>
+
+This command specifies the router-ID. If router ID is not specified it will
+use the highest interface IP address.
+```
+
+
+```{cfgcmd} set protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> maximum-paths \<ebgp|ibgp\> \<number\>
+
+This command defines the maximum number of parallel routes that
+the BGP can support. In order for BGP to use the second path, the
+following attributes have to match: Weight, Local Preference, AS
+Path (both AS number and AS path length), Origin code, MED, IGP
+metric. Also, the next hop address for each path must be different.
+```
+
+
+```{cfgcmd} set protocols bgp parameters no-hard-administrative-reset
+
+Do not send Hard Reset CEASE Notification for "Administrative Reset"
+events. When set and Graceful Restart Notification capability is exchanged
+between the peers, Graceful Restart procedures apply, and routes will be retained.
+```
+
+
+```{cfgcmd} set protocols bgp parameters log-neighbor-changes
+
+This command enable logging neighbor up/down changes and reset reason.
+```
+
+
+```{cfgcmd} set protocols bgp parameters no-client-to-client-reflection
+
+This command disables route reflection between route reflector clients.
+By default, the clients of a route reflector are not required to be
+fully meshed and the routes from a client are reflected to other clients.
+However, if the clients are fully meshed, route reflection is not required.
+In this case, use the {cfgcmd}`no-client-to-client-reflection` command
+to disable client-to-client reflection.
+```
+
+
+```{cfgcmd} set protocols bgp parameters no-fast-external-failover
+
+Disable immediate session reset if peer's connected link goes down.
+```
+
+
+```{cfgcmd} set protocols bgp parameters no-ipv6-auto-ra
+
+By default, FRR sends router advertisement packets when Extended Next Hop is
+on or when a connection is established directly using the device name (Unnumbered BGP).
+Setting this option prevents FRR from sending router advertisement packets, but could break Unnumbered BGP.
+```
+
+
+```{cfgcmd} set protocols bgp listen range \<prefix\> peer-group \<name\>
+
+This command is useful if one desires to loosen the requirement for BGP
+to have strictly defined neighbors. Specifically what is allowed is for
+the local router to listen to a range of IPv4 or IPv6 addresses defined
+by a prefix and to accept BGP open messages. When a TCP connection
+(and subsequently a BGP open message) from within this range tries to
+connect the local router then the local router will respond and connect
+with the parameters that are defined within the peer group. One must define
+a peer-group for each range that is listed. If no peer-group is defined
+then an error will keep you from committing the configuration.
+```
+
+
+```{cfgcmd} set protocols bgp listen limit \<number\>
+
+This command goes hand in hand with the listen range command to limit the
+amount of BGP neighbors that are allowed to connect to the local router.
+The limit range is 1 to 5000.
+```
+
+
+```{cfgcmd} set protocols bgp parameters ebgp-requires-policy
+
+This command changes the eBGP behavior of FRR. By default FRR enables
+{rfc}`8212` functionality which affects how eBGP routes are advertised,
+namely no routes are advertised across eBGP sessions without some
+sort of egress route-map/policy in place. In VyOS however we have this
+RFC functionality disabled by default so that we can preserve backwards
+compatibility with older versions of VyOS. With this option one can
+enable {rfc}`8212` functionality to operate.
+```
+
+
+```{cfgcmd} set protocols bgp parameters labeled-unicast \<explicit-null | ipv4-explicit-null | ipv6-explicit-null\>
+
+By default, locally advertised prefixes use the implicit-null label to
+encode in the outgoing NLRI.
+
+The following command uses the explicit-null label value for all the
+BGP instances.
+```
+
+##### Administrative Distance
+
+```{cfgcmd} set protocols bgp parameters distance global \<external|internal|local\> \<distance\>
+
+This command change distance value of BGP. The arguments are the distance
+values for external routes, internal routes and local routes respectively.
+The distance range is 1 to 255.
+```
+
+
+```{cfgcmd} set protocols bgp parameters distance prefix \<subnet\> distance \<distance\>
+
+This command sets the administrative distance for a particular route. The
+distance range is 1 to 255.
+
+:::{note}
+Routes with a distance of 255 are effectively disabled and not
+installed into the kernel.
+:::
+```
+
+##### Timers
+
+```{cfgcmd} set protocols bgp timers holdtime \<seconds\>
+
+ This command specifies hold-time in seconds. The timer range is
+ 4 to 65535. The default value is 180 second. If you set value to 0
+ VyOS will not hold routes.
+```
+
+
+```{cfgcmd} set protocols bgp timers keepalive \<seconds\>
+
+This command specifies keep-alive time in seconds. The timer
+can range from 4 to 65535. The default value is 60 second.
+```
+
+##### Route Dampening
+
+When a route fails, a routing update is sent to withdraw the route from the
+network's routing tables. When the route is re-enabled, the change in
+availability is also advertised. A route that continually fails and returns
+requires a great deal of network traffic to update the network about the
+route's status.
+
+Route dampening wich described in {rfc}`2439` enables you to identify routes
+that repeatedly fail and return. If route dampening is enabled, an unstable
+route accumulates penalties each time the route fails and returns. If the
+accumulated penalties exceed a threshold, the route is no longer advertised.
+This is route suppression. Routes that have been suppressed are re-entered
+into the routing table only when the amount of their penalty falls below a
+threshold.
+
+A penalty of 1000 is assessed each time the route fails. When the penalties
+reach a predefined threshold (suppress-value), the router stops advertising
+the route.
+
+Once a route is assessed a penalty, the penalty is decreased by half each time
+a predefined amount of time elapses (half-life-time). When the accumulated
+penalties fall below a predefined threshold (reuse-value), the route is
+unsuppressed and added back into the BGP routing table.
+
+No route is suppressed indefinitely. Maximum-suppress-time defines the maximum
+time a route can be suppressed before it is re-advertised.
+
+```{cfgcmd} set protocols bgp parameters dampening half-life \<minutes\>
+
+This command defines the amount of time in minutes after
+which a penalty is reduced by half. The timer range is
+10 to 45 minutes.
+```
+
+
+```{cfgcmd} set protocols bgp parameters dampening re-use \<seconds\>
+
+This command defines the accumulated penalty amount at which the
+route is re-advertised. The penalty range is 1 to 20000.
+```
+
+
+```{cfgcmd} set protocols bgp parameters dampening start-suppress-time \<seconds\>
+
+This command defines the accumulated penalty amount at which the
+route is suppressed. The penalty range is 1 to 20000.
+```
+
+
+```{cfgcmd} set protocols bgp parameters dampening max-suppress-time \<seconds\>
+
+This command defines the maximum time in minutes that a route is
+suppressed. The timer range is 1 to 255 minutes.
+```
+
+#### Route Selection Configuration
+
+```{cfgcmd} set protocols bgp parameters always-compare-med
+
+ This command provides to compare the MED on routes, even when they were
+ received from different neighbouring ASes. Setting this option makes the
+ order of preference of routes more defined, and should eliminate MED
+ induced oscillations.
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath as-path confed
+
+This command specifies that the length of confederation path sets and
+sequences should be taken into account during the BGP best path
+decision process.
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath as-path multipath-relax
+
+This command specifies that BGP decision process should consider paths
+of equal AS_PATH length candidates for multipath computation. Without
+the knob, the entire AS_PATH must match for multipath computation.
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath as-path ignore
+
+Ignore AS_PATH length when selecting a route
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath compare-routerid
+
+Ensure that when comparing routes where both are equal on most metrics,
+including local-pref, AS_PATH length, IGP cost, MED, that the tie is
+broken based on router-ID.
+
+If this option is enabled, then the already-selected check, where
+already selected eBGP routes are preferred, is skipped.
+
+If a route has an ORIGINATOR_ID attribute because it has been reflected,
+that ORIGINATOR_ID will be used. Otherwise, the router-ID of the peer
+the route was received from will be used.
+
+The advantage of this is that the route-selection (at this point) will
+be more deterministic. The disadvantage is that a few or even one lowest-ID
+router may attract all traffic to otherwise-equal paths because of this
+check. It may increase the possibility of MED or IGP oscillation, unless
+other measures were taken to avoid these. The exact behaviour will be
+sensitive to the iBGP and reflection topology.
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath med confed
+
+This command specifies that BGP considers the MED when comparing routes
+originated from different sub-ASs within the confederation to which this
+BGP speaker belongs. The default state, where the MED attribute is not
+considered.
+```
+
+
+```{cfgcmd} set protocols bgp parameters bestpath med missing-as-worst
+
+This command specifies that a route with a MED is always considered to be
+better than a route without a MED by causing the missing MED attribute to
+have a value of infinity. The default state, where the missing MED
+attribute is considered to have a value of zero.
+```
+
+
+```{cfgcmd} set protocols bgp parameters default local-pref <local-pref value>
+
+This command specifies the default local preference value. The local
+preference range is 0 to 4294967295.
+```
+
+
+```{cfgcmd} set protocols bgp parameters deterministic-med
+
+This command provides to compare different MED values that advertised by
+neighbours in the same AS for routes selection. When this command is
+enabled, routes from the same autonomous system are grouped together, and
+the best entries of each group are compared.
+```
+
+
+```{cfgcmd} set protocols bgp address-family ipv4-unicast network \<prefix\> backdoor
+
+This command allows the router to prefer route to specified prefix learned
+via IGP through backdoor link instead of a route to the same prefix learned
+via EBGP.
+```
+
+#### Route Filtering Configuration
+
+In order to control and modify routing information that is exchanged between
+peers you can use route-map, filter-list, prefix-list, distribute-list.
+
+For inbound updates the order of preference is:
+
+> - route-map
+> - filter-list
+> - prefix-list, distribute-list
+
+For outbound updates the order of preference is:
+> - prefix-list, distribute-list
+> - filter-list
+> - route-map
+>
+> :::{note}
+> The attributes {cfgcmd}`prefix-list` and {cfgcmd}`distribute-list`
+> are mutually exclusive, and only one command (distribute-list or
+> prefix-list) can be applied to each inbound or outbound direction for a
+> particular neighbor.
+> :::
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> distribute-list \<export|import\> \<number\>
+
+This command applies the access list filters named in \<number\> to the
+specified BGP neighbor to restrict the routing information that BGP learns
+and/or advertises. The arguments {cfgcmd}`export` and {cfgcmd}`import`
+specify the direction in which the access list are applied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> prefix-list \<export|import\> \<name\>
+
+This command applies the prfefix list filters named in \<name\> to the
+specified BGP neighbor to restrict the routing information that BGP learns
+and/or advertises. The arguments {cfgcmd}`export` and {cfgcmd}`import`
+specify the direction in which the prefix list are applied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> route-map \<export|import\> \<name\>
+
+This command applies the route map named in \<name\> to the specified BGP
+neighbor to control and modify routing information that is exchanged
+between peers. The arguments {cfgcmd}`export` and {cfgcmd}`import`
+specify the direction in which the route map are applied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> filter-list \<export|import\> \<name\>
+
+This command applies the AS path access list filters named in \<name\> to the
+specified BGP neighbor to restrict the routing information that BGP learns
+and/or advertises. The arguments {cfgcmd}`export` and {cfgcmd}`import`
+specify the direction in which the AS path access list are applied.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> address-family \<ipv4-unicast|ipv6-unicast\> capability orf \<receive|send\>
+
+This command enables the ORF capability (described in {rfc}`5291`) on the
+local router, and enables ORF capability advertisement to the specified BGP
+peer. The {cfgcmd}`receive` keyword configures a router to advertise ORF
+receive capabilities. The {cfgcmd}`send` keyword configures a router to
+advertise ORF send capabilities. To advertise a filter from a sender, you
+must create an IP prefix list for the specified BGP peer applied in inbound
+derection.
+```
+
+
+```{cfgcmd} set protocols bgp neighbor \<address|interface\> solo
+
+This command prevents from sending back prefixes learned from the neighbor.
+```
+
+#### BGP Scaling Configuration
+
+
+BGP routers connected inside the same AS through BGP belong to an internal BGP
+session, or IBGP. In order to prevent routing table loops, IBGP speaker does
+not advertise IBGP-learned routes to other IBGP speaker (Split Horizon
+mechanism). As such, IBGP requires a full mesh of all peers. For large
+networks, this quickly becomes unscalable.
+
+
+There are two ways that help us to mitigate the BGPs full-mesh requirement in
+a network:
+
+
+> - Using BGP route-reflectors
+> - Using BGP confederation
+
+
+##### Route Reflector Configuration
+
+
+Introducing route reflectors removes the need for the full-mesh. When you
+configure a route reflector you have to tell the router whether the other IBGP
+router is a client or non-client. A client is an IBGP router that the route
+reflector will “reflect” routes to, the non-client is just a regular IBGP
+neighbor. Route reflectors mechanism is described in {rfc}`4456` and updated
+by {rfc}`7606`.
+
+```{cfgcmd} set protocols bgp neighbor \<address\> address-family \<ipv4-unicast|ipv6-unicast\> route-reflector-client
+
+This command specifies the given neighbor as route reflector client.
+```
+
+
+```{cfgcmd} set protocols bgp parameters cluster-id \<id\>
+
+This command specifies cluster ID which identifies a collection of route
+reflectors and their clients, and is used by route reflectors to avoid
+looping. By default cluster ID is set to the BGP router id value, but can be
+set to an arbitrary 32-bit value.
+```
+
+##### Confederation Configuration
+
+A BGP confederation divides our AS into sub-ASes to reduce the number of
+required IBGP peerings. Within a sub-AS we still require full-mesh IBGP but
+between these sub-ASes we use something that looks like EBGP but behaves like
+IBGP (called confederation BGP). Confederation mechanism is described in
+{rfc}`5065`
+
+```{cfgcmd} set protocols bgp parameters confederation identifier \<asn\>
+
+This command specifies a BGP confederation identifier. \<asn\> is the number
+of the autonomous system that internally includes multiple sub-autonomous
+systems (a confederation).
+```
+
+
+```{cfgcmd} set protocols bgp parameters confederation peers \<nsubasn\>
+
+This command sets other confederations \<nsubasn\> as members of autonomous
+system specified by {cfgcmd}`confederation identifier <asn>`.
+```
+
+## Operational Mode Commands
+### Show
+
+```{opcmd} show bgp \<ipv4|ipv6\>
+
+ This command displays all entries in BGP routing table.
+```
+
+
+```none
+BGP table version is 10, local router ID is 10.0.35.3, vrf id 0
+Default local pref 100, local AS 65000
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+RPKI validation codes: V valid, I invalid, N Not found
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 198.51.100.0/24 10.0.34.4 0 0 65004 i
+*> 203.0.113.0/24 10.0.35.5 0 0 65005 i
+
+Displayed 2 routes and 2 total paths
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> \<address|prefix\>
+
+This command displays information about the particular entry in the BGP
+routing table.
+```
+
+
+```none
+BGP routing table entry for 198.51.100.0/24
+Paths: (1 available, best #1, table default)
+ Advertised to non peer-group peers:
+ 10.0.13.1 10.0.23.2 10.0.34.4 10.0.35.5
+ 65004
+ 10.0.34.4 from 10.0.34.4 (10.0.34.4)
+ Origin IGP, metric 0, valid, external, best (First path received)
+ Last update: Wed Jan 6 12:18:53 2021
+```
+
+
+```{opcmd} show bgp cidr-only
+
+This command displays routes with classless interdomain routing (CIDR).
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> community \<value\>
+
+This command displays routes that belong to specified BGP communities.
+Valid value is a community number in the range from 1 to 4294967200,
+or AA:NN (autonomous system-community number/2-byte number), no-export,
+local-as, or no-advertise.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> community-list \<name\>
+
+This command displays routes that are permitted by the BGP
+community list.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> dampening dampened-paths
+
+This command displays BGP dampened routes.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> dampening flap-statistics
+
+This command displays information about flapping BGP routes.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> filter-list \<name\>
+
+This command displays BGP routes allowed by the specified AS Path
+access list.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> neighbors \<address\> advertised-routes
+
+This command displays BGP routes advertised to a neighbor.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> neighbors \<address\> received-routes
+
+This command displays BGP routes originating from the specified BGP
+neighbor before inbound policy is applied. To use this command inbound
+soft reconfiguration must be enabled.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> neighbors \<address\> routes
+
+This command displays BGP received-routes that are accepted after filtering.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> neighbors \<address\> dampened-routes
+
+This command displays dampened routes received from BGP neighbor.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> regexp \<text\>
+
+This command displays information about BGP routes whose AS path
+matches the specified regular expression.
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> summary
+
+This command displays the status of all BGP connections.
+```
+
+
+```none
+IPv4 Unicast Summary:
+BGP router identifier 10.0.35.3, local AS number 65000 vrf-id 0
+BGP table version 11
+RIB entries 5, using 920 bytes of memory
+Peers 4, using 82 KiB of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
+10.0.13.1 4 65000 148 159 0 0 0 02:16:01 0
+10.0.23.2 4 65000 136 143 0 0 0 02:13:21 0
+10.0.34.4 4 65004 161 163 0 0 0 02:16:01 1
+10.0.35.5 4 65005 162 166 0 0 0 02:16:01 1
+
+Total number of neighbors 4
+```
+
+### Reset
+
+```{opcmd} reset bgp \<ipv4|ipv6\> \<address\> [soft [in|out]]
+
+This command resets BGP connections to the specified neighbor IP address.
+With argument {cfgcmd}`soft` this command initiates a soft reset. If
+you do not specify the {cfgcmd}`in` or {cfgcmd}`out` options, both
+inbound and outbound soft reconfiguration are triggered.
+```
+
+
+```{opcmd} reset bgp all
+
+This command resets all BGP connections of given router.
+```
+
+
+```{opcmd} reset bgp \<ipv4|ipv6\> external
+
+This command resets all external BGP peers of given router.
+```
+
+
+```{opcmd} reset bgp \<ipv4|ipv6\> peer-group \<name\> [soft [in|out]]
+
+This command resets BGP connections to the specified peer group.
+With argument {cfgcmd}`soft` this command initiates a soft reset. If
+you do not specify the {cfgcmd}`in` or {cfgcmd}`out` options, both
+inbound and outbound soft reconfiguration are triggered.
+```
+
+## Examples
+### IPv4 peering
+
+A simple eBGP configuration:
+
+**Node 1:**
+
+```none
+set protocols bgp system-as 65534
+set protocols bgp neighbor 192.168.0.2 ebgp-multihop '2'
+set protocols bgp neighbor 192.168.0.2 remote-as '65535'
+set protocols bgp neighbor 192.168.0.2 update-source '192.168.0.1'
+set protocols bgp neighbor 192.168.0.2 address-family ipv4-unicast
+set protocols bgp address-family ipv4-unicast network '172.16.0.0/16'
+set protocols bgp parameters router-id '192.168.0.1'
+```
+
+**Node 2:**
+
+```none
+set protocols bgp system-as 65535
+set protocols bgp neighbor 192.168.0.1 ebgp-multihop '2'
+set protocols bgp neighbor 192.168.0.1 remote-as '65534'
+set protocols bgp neighbor 192.168.0.1 update-source '192.168.0.2'
+set protocols bgp neighbor 192.168.0.1 address-family ipv4-unicast
+set protocols bgp address-family ipv4-unicast network '172.17.0.0/16'
+set protocols bgp parameters router-id '192.168.0.2'
+```
+
+Don't forget, the CIDR declared in the network statement MUST **exist in your
+routing table (dynamic or static), the best way to make sure that is true is
+creating a static route:**
+
+**Node 1:**
+
+```none
+set protocols static route 172.16.0.0/16 blackhole distance '254'
+```
+
+**Node 2:**
+
+```none
+set protocols static route 172.17.0.0/16 blackhole distance '254'
+```
+
+### IPv6 peering
+
+A simple BGP configuration via IPv6.
+
+**Node 1:**
+
+```none
+set protocols bgp system-as 65534
+set protocols bgp neighbor 2001:db8::2 ebgp-multihop '2'
+set protocols bgp neighbor 2001:db8::2 remote-as '65535'
+set protocols bgp neighbor 2001:db8::2 update-source '2001:db8::1'
+set protocols bgp neighbor 2001:db8::2 address-family ipv6-unicast
+set protocols bgp address-family ipv6-unicast network '2001:db8:1::/48'
+set protocols bgp parameters router-id '10.1.1.1'
+```
+
+**Node 2:**
+
+```none
+set protocols bgp system-as 65535
+set protocols bgp neighbor 2001:db8::1 ebgp-multihop '2'
+set protocols bgp neighbor 2001:db8::1 remote-as '65534'
+set protocols bgp neighbor 2001:db8::1 update-source '2001:db8::2'
+set protocols bgp neighbor 2001:db8::1 address-family ipv6-unicast
+set protocols bgp address-family ipv6-unicast network '2001:db8:2::/48'
+set protocols bgp parameters router-id '10.1.1.2'
+```
+
+Don't forget, the CIDR declared in the network statement **MUST exist in your
+routing table (dynamic or static), the best way to make sure that is true is
+creating a static route:**
+
+**Node 1:**
+
+```none
+set protocols static route6 2001:db8:1::/48 blackhole distance '254'
+```
+
+**Node 2:**
+
+```none
+set protocols static route6 2001:db8:2::/48 blackhole distance '254'
+```
+
+### Route Filtering
+
+Route filter can be applied using a route-map:
+
+**Node1:**
+
+```none
+set policy prefix-list AS65535-IN rule 10 action 'permit'
+set policy prefix-list AS65535-IN rule 10 prefix '172.16.0.0/16'
+set policy prefix-list AS65535-OUT rule 10 action 'deny'
+set policy prefix-list AS65535-OUT rule 10 prefix '172.16.0.0/16'
+set policy prefix-list6 AS65535-IN rule 10 action 'permit'
+set policy prefix-list6 AS65535-IN rule 10 prefix '2001:db8:2::/48'
+set policy prefix-list6 AS65535-OUT rule 10 action 'deny'
+set policy prefix-list6 AS65535-OUT rule 10 prefix '2001:db8:2::/48'
+
+set policy route-map AS65535-IN rule 10 action 'permit'
+set policy route-map AS65535-IN rule 10 match ip address prefix-list 'AS65535-IN'
+set policy route-map AS65535-IN rule 10 match ipv6 address prefix-list 'AS65535-IN'
+set policy route-map AS65535-IN rule 20 action 'deny'
+set policy route-map AS65535-OUT rule 10 action 'deny'
+set policy route-map AS65535-OUT rule 10 match ip address prefix-list 'AS65535-OUT'
+set policy route-map AS65535-OUT rule 10 match ipv6 address prefix-list 'AS65535-OUT'
+set policy route-map AS65535-OUT rule 20 action 'permit'
+
+set protocols bgp system-as 65534
+set protocols bgp neighbor 2001:db8::2 address-family ipv4-unicast route-map export 'AS65535-OUT'
+set protocols bgp neighbor 2001:db8::2 address-family ipv4-unicast route-map import 'AS65535-IN'
+set protocols bgp neighbor 2001:db8::2 address-family ipv6-unicast route-map export 'AS65535-OUT'
+set protocols bgp neighbor 2001:db8::2 address-family ipv6-unicast route-map import 'AS65535-IN'
+```
+
+**Node2:**
+
+```none
+set policy prefix-list AS65534-IN rule 10 action 'permit'
+set policy prefix-list AS65534-IN rule 10 prefix '172.17.0.0/16'
+set policy prefix-list AS65534-OUT rule 10 action 'deny'
+set policy prefix-list AS65534-OUT rule 10 prefix '172.17.0.0/16'
+set policy prefix-list6 AS65534-IN rule 10 action 'permit'
+set policy prefix-list6 AS65534-IN rule 10 prefix '2001:db8:1::/48'
+set policy prefix-list6 AS65534-OUT rule 10 action 'deny'
+set policy prefix-list6 AS65534-OUT rule 10 prefix '2001:db8:1::/48'
+
+set policy route-map AS65534-IN rule 10 action 'permit'
+set policy route-map AS65534-IN rule 10 match ip address prefix-list 'AS65534-IN'
+set policy route-map AS65534-IN rule 10 match ipv6 address prefix-list 'AS65534-IN'
+set policy route-map AS65534-IN rule 20 action 'deny'
+set policy route-map AS65534-OUT rule 10 action 'deny'
+set policy route-map AS65534-OUT rule 10 match ip address prefix-list 'AS65534-OUT'
+set policy route-map AS65534-OUT rule 10 match ipv6 address prefix-list 'AS65534-OUT'
+set policy route-map AS65534-OUT rule 20 action 'permit'
+
+set protocols bgp system-as 65535
+set protocols bgp neighbor 2001:db8::1 address-family ipv4-unicast route-map export 'AS65534-OUT'
+set protocols bgp neighbor 2001:db8::1 address-family ipv4-unicast route-map import 'AS65534-IN'
+set protocols bgp neighbor 2001:db8::1 address-family ipv6-unicast route-map export 'AS65534-OUT'
+set protocols bgp neighbor 2001:db8::1 address-family ipv6-unicast route-map import 'AS65534-IN'
+```
+
+We could expand on this and also deny link local and multicast in the rule 20
+action deny.
diff --git a/docs/configuration/protocols/failover.md b/docs/configuration/protocols/failover.md
new file mode 100644
index 00000000..96374d11
--- /dev/null
+++ b/docs/configuration/protocols/failover.md
@@ -0,0 +1,237 @@
+---
+description: |-
+ Failover routes are static routes that are installed in the routing
+ table only while a configured health-check target responds. VyOS uses them
+ to switch traffic to a backup path when the primary next hop becomes
+ unreachable, and to restore the primary path automatically once it recovers.
+keywords: |-
+ failover, failover route, static route, health check, icmp probe,
+ next hop, route metric
+---
+
+# Failover
+
+Failover routes are manually configured network paths used only while their
+health-check targets are reachable. If the target stops responding, VyOS
+removes the route from the routing table and reinstalls it once the target
+recovers.
+
+## Configuration
+
+Use the following commands to configure failover routes for a specific remote
+`<subnet>` reachable via next-hop `<address>`.
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> check target <target-address>
+
+ **Configure the health check target IP address.**
+
+ This is typically a highly available host, either within the destination
+ subnet or on the public internet.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 check target 8.8.8.8
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> check timeout <timeout>
+
+ **Configure the timeout interval, in seconds, between target health checks.**
+
+ The valid range is 1 to 300 seconds. The default is 10 seconds.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 check timeout 2
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> check type <protocol>
+
+ **Configure the protocol to use for health checks.**
+
+ The following protocols are available:
+
+ * ``icmp``: VyOS sends two ICMP echo request packets with a 1-second
+ response timeout. The health check is successful if at least one response
+ is received.
+ * ``arp``: VyOS sends two ARP requests with a 1-second response timeout.
+ The health check is successful if at least one response is received.
+ * ``tcp``: VyOS verifies whether the destination TCP port is open. The
+ health check is successful if a TCP connection is successfully
+ established with the target port.
+
+ The default protocol is ``icmp``.
+
+ .. note::
+
+ When the check type is set to ``tcp``, you must also define the target
+ TCP port.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 check type tcp
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> check port <port>
+
+ **Configure the destination TCP port on the health check target.**
+
+ This parameter applies only when the check type is configured as ``tcp``.
+
+ The valid port range is 1 to 65535.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 check port 443
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> check policy <policy>
+
+ **Configure the health check success policy for multiple targets.**
+
+ The following policies are available:
+
+ * ``any-available``: The health check succeeds if at least one of the
+ configured targets responds successfully.
+ * ``all-available``: The health check succeeds only if every configured
+ target responds successfully.
+
+ The default policy is ``any-available``.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 check policy all-available
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> interface <interface>
+
+ **Configure the local interface used to reach the next-hop address.**
+
+ This parameter is mandatory.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 interface eth0
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> metric <1-255>
+
+ **Configure the metric (cost) for the failover route.**
+
+ The metric defines the route priority. A lower metric value indicates a
+ more preferred route.
+
+ The default value is 1.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 metric 50
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols failover route <subnet> next-hop <address> onlink
+
+ Configure the next-hop to be reachable via the assigned interface, even
+ when ``<address>`` is outside any subnet configured on that interface.
+
+ Example:
+
+ .. code-block:: none
+
+ set protocols failover route 203.0.113.1/32 next-hop 10.217.37.254 onlink
+```
+
+## Examples
+
+### Failover route with a single next-hop and ICMP health check
+
+The following example configures a failover route to `203.0.113.1/32`
+through next-hop `192.0.2.1` on `eth0`. The next-hop is monitored with
+ICMP probes to `192.0.2.1` every 5 seconds, and the route is installed with
+a metric of 10.
+
+```none
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check target '192.0.2.1'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check timeout '5'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check type 'icmp'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 interface 'eth0'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 metric '10'
+```
+
+Verify the route:
+
+```none
+vyos@vyos:~$ show ip route 203.0.113.1
+Routing entry for 203.0.113.1/32
+ Known via "kernel", distance 0, metric 10, best
+ Last update 00:00:39 ago
+ Flags: Selected
+ Status: Installed
+ * 192.0.2.1, via eth0, weight 1
+```
+
+### Two failover routes with different metrics
+
+The following example configures two failover routes to `203.0.113.1/32`,
+each through a different next-hop. The primary next-hop `192.0.2.1` is
+reached on `eth0` with metric 10, and the backup next-hop `198.51.100.1`
+is reached on `eth2` with metric 20. Both next-hops are monitored with ICMP
+probes every 5 seconds.
+
+While both health checks succeed, the lower-metric route through `eth0` is
+preferred. If the primary target stops responding, its route is removed from
+the routing table, and traffic falls over to `198.51.100.1` via `eth2`.
+
+```none
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check target '192.0.2.1'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check timeout '5'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 check type 'icmp'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 interface 'eth0'
+set protocols failover route 203.0.113.1/32 next-hop 192.0.2.1 metric '10'
+
+set protocols failover route 203.0.113.1/32 next-hop 198.51.100.1 check target '198.51.100.99'
+set protocols failover route 203.0.113.1/32 next-hop 198.51.100.1 check timeout '5'
+set protocols failover route 203.0.113.1/32 next-hop 198.51.100.1 check type 'icmp'
+set protocols failover route 203.0.113.1/32 next-hop 198.51.100.1 interface 'eth2'
+set protocols failover route 203.0.113.1/32 next-hop 198.51.100.1 metric '20'
+```
+
+Verify routes:
+
+```none
+vyos@vyos:~$ show ip route 203.0.113.1
+Routing entry for 203.0.113.1/32
+ Known via "kernel", distance 0, metric 10, best
+ Last update 00:08:06 ago
+ Flags: Selected
+ Status: Installed
+ * 192.0.2.1, via eth0, weight 1
+
+Routing entry for 203.0.113.1/32
+ Known via "kernel", distance 0, metric 20
+ Last update 00:08:14 ago
+ Flags: None
+ Status: Installed
+ * 198.51.100.1, via eth2, weight 1
+```
+
diff --git a/docs/configuration/protocols/igmp-proxy.md b/docs/configuration/protocols/igmp-proxy.md
new file mode 100644
index 00000000..961f921b
--- /dev/null
+++ b/docs/configuration/protocols/igmp-proxy.md
@@ -0,0 +1,79 @@
+---
+lastproofread: '2023-11-13'
+---
+
+(igmp-proxy)=
+
+# IGMP Proxy
+
+{abbr}`IGMP (Internet Group Management Protocol)` proxy sends IGMP host messages
+on behalf of a connected client. The configuration must define one, and only one
+upstream interface, and one or more downstream interfaces.
+
+## Configuration
+
+```{cfgcmd} set protocols igmp-proxy interface \<interface\> role \<upstream | downstream\>
+
+* **upstream:** The upstream network interface is the outgoing interface
+which is responsible for communicating to available multicast data sources.
+There can only be one upstream interface.
+
+* **downstream:** Downstream network interfaces are the distribution
+interfaces to the destination networks, where multicast clients can join
+groups and receive multicast data. One or more downstream interfaces must
+be configured.
+```
+
+```{cfgcmd} set protocols igmp-proxy interface \<interface\> alt-subnet \<network\>
+
+Defines alternate sources for multicasting and IGMP data. The network address
+must be on the following format 'a.b.c.d/n'. By default, the router will
+accept data from sources on the same network as configured on an interface.
+If the multicast source lies on a remote network, one must define from where
+traffic should be accepted.
+
+This is especially useful for the upstream interface, since the source for
+multicast traffic is often from a remote location.
+
+This option can be supplied multiple times.
+```
+
+```{cfgcmd} set protocols igmp-proxy disable-quickleave
+
+Disables quickleave mode. In this mode the daemon will not send a Leave IGMP
+message upstream as soon as it receives a Leave message for any downstream
+interface. The daemon will not ask for Membership reports on the downstream
+interfaces, and if a report is received the group is not joined again the
+upstream.
+
+If it's vital that the daemon should act exactly like a real multicast client
+on the upstream interface, this function should be enabled.
+
+Enabling this function increases the risk of bandwidth saturation.
+```
+
+```{cfgcmd} set protocols igmp-proxy disable
+
+Disable this service.
+```
+
+(igmp-proxy-example)=
+
+### Example
+
+Interface eth1 LAN is behind NAT. In order to subscribe 10.0.0.0/23 subnet
+multicast which is in eth0 WAN we need to configure igmp-proxy.
+
+```none
+set protocols igmp-proxy interface eth0 role upstream
+set protocols igmp-proxy interface eth0 alt-subnet 10.0.0.0/23
+set protocols igmp-proxy interface eth1 role downstream
+```
+
+
+## Operation
+
+```{opcmd} restart igmp-proxy
+
+Restart the IGMP proxy process.
+``` \ No newline at end of file
diff --git a/docs/configuration/protocols/index.md b/docs/configuration/protocols/index.md
new file mode 100644
index 00000000..5f190ce1
--- /dev/null
+++ b/docs/configuration/protocols/index.md
@@ -0,0 +1,25 @@
+# Protocols
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+arp
+babel
+bfd
+bgp
+failover
+igmp-proxy
+isis
+mpls
+multicast
+segment-routing
+traffic-engineering
+openfabric
+ospf
+pim
+pim6
+rip
+rpki
+static
+```
diff --git a/docs/configuration/protocols/isis.md b/docs/configuration/protocols/isis.md
new file mode 100644
index 00000000..ac6db346
--- /dev/null
+++ b/docs/configuration/protocols/isis.md
@@ -0,0 +1,746 @@
+```{include} /_include/need_improvement.txt
+```
+
+(routing-isis)=
+
+# IS-IS
+
+{abbr}`IS-IS (Intermediate System to Intermediate System)` is a link-state
+interior gateway protocol (IGP) which is described in ISO10589,
+{rfc}`1195`, {rfc}`5308`. IS-IS runs the Dijkstra shortest-path first (SPF)
+algorithm to create a database of the network’s topology, and
+from that database to determine the best (that is, lowest cost) path to a
+destination. The intermediate systems (the name for routers) exchange topology
+information with their directly connected neighbors. IS-IS runs directly on
+the data link layer (Layer 2). IS-IS addresses are called
+{abbr}`NETs (Network Entity Titles)` and can be 8 to 20 bytes long, but are
+generally 10 bytes long. The tree database that is created with IS-IS is
+similar to the one that is created with OSPF in that the paths chosen should
+be similar. Comparisons to OSPF are inevitable and often are reasonable ones
+to make in regards to the way a network will respond with either IGP.
+
+## General
+
+### Configuration
+
+#### Mandatory Settings
+
+For IS-IS top operate correctly, one must do the equivalent of a Router ID in
+CLNS. This Router ID is called the {abbr}`NET (Network Entity Title)`. This
+must be unique for each and every router that is operating in IS-IS. It also
+must not be duplicated otherwise the same issues that occur within OSPF will
+occur within IS-IS when it comes to said duplication.
+
+```{cfgcmd} set protocols isis net \<network-entity-title\>
+
+This command sets network entity title (NET) provided in ISO format.
+
+Here is an example {abbr}`NET (Network Entity Title)` value:
+
+:::{code-block} none
+49.0001.1921.6800.1002.00
+:::
+The CLNS address consists of the following parts:
+
+* {abbr}`AFI (Address family authority identifier)` - ``49`` The AFI value
+ 49 is what IS-IS uses for private addressing.
+
+* Area identifier: ``0001`` IS-IS area number (numerical area ``1``)
+
+* System identifier: ``1921.6800.1002`` - for system identifiers we recommend
+ to use IP address or MAC address of the router itself. The way to construct
+ this is to keep all of the zeroes of the router IP address, and then change
+ the periods from being every three numbers to every four numbers. The
+ address that is listed here is ``192.168.1.2``, which if expanded will turn
+ into ``192.168.001.002``. Then all one has to do is move the dots to have
+ four numbers instead of three. This gives us ``1921.6800.1002``.
+
+* {abbr}`NET (Network Entity Title)` selector: ``00`` Must always be 00. This
+ setting indicates "this system" or "local system."
+
+```
+
+```{cfgcmd} set protocols isis interface \<interface\>
+
+This command enables IS-IS on this interface, and allows for
+adjacency to occur. Note that the name of IS-IS instance must be
+the same as the one used to configure the IS-IS process.
+```
+
+#### IS-IS Global Configuration
+
+```{cfgcmd} set protocols isis dynamic-hostname
+
+This command enables support for dynamic hostname TLV. Dynamic hostname
+mapping determined as described in {rfc}`2763`, Dynamic Hostname
+Exchange Mechanism for IS-IS.
+```
+
+```{cfgcmd} set protocols isis level \<level-1|level-1-2|level-2\>
+
+This command defines the IS-IS router behavior:
+
+* **level-1** - Act as a station (Level 1) router only.
+* **level-1-2** - Act as a station (Level 1) router and area (Level 2) router.
+* **level-2-only** - Act as an area (Level 2) router only.
+```
+
+```{cfgcmd} set protocols isis lsp-mtu \<size\>
+
+This command configures the maximum size of generated
+{abbr}`LSPs (Link State PDUs)`, in bytes. The size range is 128 to 4352.
+```
+
+```{cfgcmd} set protocols isis metric-style \<narrow|transition|wide\>
+
+This command sets old-style (ISO 10589) or new style packet formats:
+
+* **narrow** - Use old style of TLVs with narrow metric.
+* **transition** - Send and accept both styles of TLVs during transition.
+* **wide** - Use new style of TLVs to carry wider metric.
+```
+
+```{cfgcmd} set protocols isis purge-originator
+
+This command enables {rfc}`6232` purge originator identification. Enable
+purge originator identification (POI) by adding the type, length and value
+(TLV) with the Intermediate System (IS) identification to the LSPs that do
+not contain POI information. If an IS generates a purge, VyOS adds this TLV
+with the system ID of the IS to the purge.
+```
+
+```{cfgcmd} set protocols isis set-attached-bit
+
+This command sets ATT bit to 1 in Level1 LSPs. It is described in {rfc}`3787`.
+```
+
+```{cfgcmd} set protocols isis set-overload-bit
+
+This command sets overload bit to avoid any transit traffic through this
+router. It is described in {rfc}`3787`.
+```
+
+```{cfgcmd} set protocols isis default-information originate \<ipv4|ipv6\> level-1
+
+This command will generate a default-route in L1 database.
+```
+
+```{cfgcmd} set protocols isis default-information originate \<ipv4|ipv6\> level-2
+
+This command will generate a default-route in L2 database.
+```
+
+```{cfgcmd} set protocols isis ldp-sync
+
+This command will enable IGP-LDP synchronization globally for ISIS. This
+requires for LDP to be functional. This is described in {rfc}`5443`. By
+default all interfaces operational in IS-IS are enabled for synchronization.
+Loopbacks are exempt.
+
+```
+
+```{cfgcmd} set protocols isis ldp-sync holddown \<seconds\>
+
+This command will change the hold down value globally for IGP-LDP
+synchronization during convergence/interface flap events.
+```
+
+#### Interface Configuration
+
+```{cfgcmd} set protocols isis interface \<interface\> circuit-type \<level-1|level-1-2|level-2-only\>
+
+This command specifies circuit type for interface:
+
+* **level-1** - Level-1 only adjacencies are formed.
+* **level-1-2** - Level-1-2 adjacencies are formed
+* **level-2-only** - Level-2 only adjacencies are formed
+
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> hello-interval \<seconds\>
+
+This command sets hello interval in seconds on a given interface.
+The range is 1 to 600.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> hello-multiplier \<seconds\>
+
+This command sets multiplier for hello holding time on a given
+interface. The range is 2 to 100.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> hello-padding
+
+This command configures padding on hello packets to accommodate asymmetrical
+maximum transfer units (MTUs) from different hosts as described in
+{rfc}`3719`. This helps to prevent a premature adjacency Up state when one
+routing devices MTU does not meet the requirements to establish the adjacency.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> metric \<metric\>
+
+This command set default metric for circuit.
+
+The metric range is 1 to 16777215 (Max value depend if metric support narrow
+or wide value).
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> network point-to-point
+
+This command specifies network type to Point-to-Point. The default
+network type is broadcast.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> passive
+
+This command configures the passive mode for this interface.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> password plaintext-password \<text\>
+
+This command configures the authentication password for the interface.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> priority \<number\>
+
+This command sets priority for the interface for
+{abbr}`DIS (Designated Intermediate System)` election. The priority
+range is 0 to 127.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> psnp-interval \<number\>
+
+This command sets PSNP interval in seconds. The interval range is 0
+to 127.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> no-three-way-handshake
+
+This command disables Three-Way Handshake for P2P adjacencies which
+described in {rfc}`5303`. Three-Way Handshake is enabled by default.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> ldp-sync disable
+
+This command disables IGP-LDP sync for this specific interface.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> ldp-sync holddown \<seconds\>
+
+This command will change the hold down value for IGP-LDP synchronization
+during convergence/interface flap events, but for this interface only.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> fast-reroute lfa [level-1 | level-2] enable
+
+This command enables per-prefix local LFA fast reroute link protection.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> fast-reroute lfa [level-1 | level-2] exclude
+
+This command excludes an interface from the local LFA backup nexthop computation.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> fast-reroute remote-lfa [level-1 | level-2] tunnel mpls-ldp
+
+This command enables per-prefix Remote LFA fast reroute link protection.
+Note that other routers in the network need to be configured to accept LDP
+targeted hello messages in order for RLFA to work.
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> fast-reroute remote-lfa [level-1 | level-2] maximum-metric \<metric\>
+
+This command limits Remote LFA PQ node selection within the specified metric. Metric value range (1-16777215).
+```
+
+```{cfgcmd} set protocols isis interface \<interface\> fast-reroute ti-lfa [level-1|level-2] [node-protection [link-fallback]]
+
+This command enables per-prefix TI-LFA fast reroute link or node protection.
+When node protection is used, option link-fallback enables the computation
+and use of link-protecting LFAs for destinations unprotected by node
+protection.
+```
+
+#### Route Redistribution
+
+```{cfgcmd} set protocols isis redistribute ipv4 \<route source\> level-1
+
+This command redistributes routing information from the given route source
+into the ISIS database as Level-1. There are six modes available for route
+source: bgp, connected, kernel, ospf, rip, static.
+```
+
+```{cfgcmd} set protocols isis redistribute ipv4 \<route source\> level-2
+
+This command redistributes routing information from the given route source
+into the ISIS database as Level-2. There are six modes available for route
+source: bgp, connected, kernel, ospf, rip, static.
+```
+
+```{cfgcmd} set protocols isis redistribute ipv4 \<route source\> \<level-1|level-2\> metric \<number\>
+
+This command specifies metric for redistributed routes from the given route
+source. There are six modes available for route source: bgp, connected,
+kernel, ospf, rip, static. The metric range is 1 to 16777215.
+```
+
+```{cfgcmd} set protocols isis redistribute ipv4 \<route source\> \<level-1|level-2\> route-map \<name\>
+
+This command allows to use route map to filter redistributed routes from
+the given route source. There are six modes available for route source:
+bgp, connected, kernel, ospf, rip, static.
+```
+
+#### Timers
+
+```{cfgcmd} set protocols isis lsp-gen-interval \<seconds\>
+
+This command sets minimum interval in seconds between regenerating same
+LSP. The interval range is 1 to 120.
+```
+
+```{cfgcmd} set protocols isis lsp-refresh-interval \<seconds\>
+
+This command sets LSP refresh interval in seconds. IS-IS generates LSPs
+when the state of a link changes. However, to ensure that routing
+databases on all routers remain converged, LSPs in stable networks are
+generated on a regular basis even though there has been no change to
+the state of the links. The interval range is 1 to 65235. The default
+value is 900 seconds.
+```
+
+```{cfgcmd} set protocols isis max-lsp-lifetime \<seconds\>
+
+This command sets LSP maximum LSP lifetime in seconds. The interval range
+is 350 to 65535. LSPs remain in a database for 1200 seconds by default.
+If they are not refreshed by that time, they are deleted. You can change
+the LSP refresh interval or the LSP lifetime. The LSP refresh interval
+should be less than the LSP lifetime or else LSPs will time out before
+they are refreshed.
+```
+
+```{cfgcmd} set protocols isis spf-interval \<seconds\>
+
+This command sets minimum interval between consecutive SPF calculations in
+seconds.The interval range is 1 to 120.
+```
+
+```{cfgcmd} set protocols isis spf-delay-ietf holddown \<milliseconds\>
+```
+
+```{cfgcmd} set protocols isis spf-delay-ietf init-delay \<milliseconds\>
+```
+
+```{cfgcmd} set protocols isis spf-delay-ietf long-delay \<milliseconds\>
+```
+
+```{cfgcmd} set protocols isis spf-delay-ietf short-delay \<milliseconds\>
+```
+
+```{cfgcmd} set protocols isis spf-delay-ietf time-to-learn \<milliseconds\>
+
+This commands specifies the Finite State Machine (FSM) intended to
+control the timing of the execution of SPF calculations in response
+to IGP events. The process described in {rfc}`8405`.
+```
+
+#### Loop Free Alternate (LFA)
+
+```{cfgcmd} set protocols isis fast-reroute lfa remote prefix-list \<name\> \<level-1|level-2\>
+
+This command enables IP fast re-routing that is part of {rfc}`5286`.
+Specifically this is a prefix list which references a prefix in which
+will select eligible PQ nodes for remote LFA backups.
+```
+
+```{cfgcmd} set protocols isis fast-reroute lfa local load-sharing disable \<level-1|level-2\>
+
+This command disables the load sharing across multiple LFA backups.
+```
+
+```{cfgcmd} set protocols isis fast-reroute lfa local tiebreaker \<downstream|lowest-backup-metric|node-protecting\> index \<number\> \<level-1|level-2\>
+
+This command will configure a tie-breaker for multiple local LFA backups.
+The lower index numbers will be processed first.
+```
+
+```{cfgcmd} set protocols isis fast-reroute lfa local priority-limit \<medium|high|critical\> \<level-1|level-2\>
+
+This command will limit LFA backup computation up to the specified
+prefix priority.
+```
+
+#### Segment Routing over IPv6 (SRv6)
+
+```{cfgcmd} set protocols isis segment-routing srv6 interface \<interface\>
+
+The dummy interface used
+to install SRv6 SIDs into the Linux data plane. The interface must exist and
+must be present when configuring IS-IS with
+SRv6.
+```
+
+```{cfgcmd} set protocols isis segment-routing srv6 locator \<locator\>
+
+Specifies the SRv6 locator to use for IS-IS. IS-IS automatically allocates
+prefix and adjacency SIDs, creates local SID entries and advertises them
+into the IGP domain.
+```
+
+```{cfgcmd} set protocols isis segment-routing srv6 node-msd max-end-d \<0-255\>
+
+The Maximum End D MSD Type specifies the maximum number of SIDs present in an
+SRH when performing decapsulation. As specified in {rfc}`8986`, the permitted
+SID types include, but are not limited to, End.DX6, End.DT4, End.DT46, End
+with USD, and End.X with USD.
+
+If the advertised value is zero or no value is advertised, then the router
+cannot apply any behavior that results in decapsulation and forwarding of the
+inner packet if the outer IPv6 header contains an SRH.
+
+Reference: {rfc}`9352`
+```
+
+```{cfgcmd} set protocols isis segment-routing srv6 node-msd max-end-pop \<0-255\>
+
+The Maximum End Pop MSD Type signals the maximum number of SIDs in the SRH to
+which the router can apply "Penultimate Segment Pop (PSP) of the SRH" or
+"Ultimate Segment Pop (USP) of the SRH" behavior, as defined in "Flavors"
+(Section 4.16 of {rfc}`8986`).
+
+If the advertised value is zero or no value is advertised, then the router
+cannot apply PSP or USP flavors.
+
+Reference: {rfc}`9352`
+```
+
+```{cfgcmd} set protocols isis segment-routing srv6 node-msd max-h-encaps \<0-255\>
+
+The Maximum H.Encaps MSD Type signals the maximum number of SIDs that can be
+added to the segment list of an SRH as part of the "H.Encaps" behavior, as
+defined in {rfc}`8986`.
+
+If the advertised value is zero or no value is advertised, then the headend
+can apply an SR Policy that only contains one segment without inserting any
+SRH header. A non-zero SRH Max H.encaps MSD indicates that the headend can
+insert an SRH up to the advertised number of SIDs.
+
+Reference: {rfc}`9352`
+```
+
+```{cfgcmd} set protocols isis segment-routing srv6 node-msd max-segs-left \<0-255\>
+
+The Maximum Segments Left MSD Type signals the maximum value of the
+"Segments Left" field ({rfc}`8754`) in the SRH of a received packet before
+applying the Endpoint behavior associated with a SID.
+
+If no value is advertised, the supported value is 0.
+
+Reference: {rfc}`9352`
+```
+
+## Examples
+
+### Enable IS-IS
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address '192.168.255.255/32'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5255.00'
+```
+
+**Node 2:**
+
+```none
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set interfaces loopback lo address '192.168.255.254/32'
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5254.00'
+```
+
+This gives us the following neighborships, Level 1 and Level 2:
+
+```none
+Node-1@vyos:~$ show isis neighbor
+Area VyOS:
+ System Id Interface L State Holdtime SNPA
+ vyos eth1 1 Up 28 0c87.6c09.0001
+ vyos eth1 2 Up 28 0c87.6c09.0001
+
+Node-2@vyos:~$ show isis neighbor
+Area VyOS:
+ System Id Interface L State Holdtime SNPA
+ vyos eth1 1 Up 29 0c33.0280.0001
+ vyos eth1 2 Up 28 0c33.0280.0001
+```
+
+Here's the IP routes that are populated. Just the loopback:
+
+```none
+Node-1@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.2, eth1 inactive, weight 1, 00:02:22
+I>* 192.168.255.254/32 [115/20] via 192.0.2.2, eth1, weight 1, 00:02:22
+
+Node-2@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.1, eth1 inactive, weight 1, 00:02:21
+I>* 192.168.255.255/32 [115/20] via 192.0.2.1, eth1, weight 1, 00:02:21
+```
+
+### Enable IS-IS and redistribute routes not natively in IS-IS
+
+**Node 1:**
+
+```none
+set interfaces dummy dum0 address '203.0.113.1/24'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+
+set policy prefix-list EXPORT-ISIS rule 10 action 'permit'
+set policy prefix-list EXPORT-ISIS rule 10 prefix '203.0.113.0/24'
+set policy route-map EXPORT-ISIS rule 10 action 'permit'
+set policy route-map EXPORT-ISIS rule 10 match ip address prefix-list 'EXPORT-ISIS'
+
+set protocols isis interface eth1
+set protocols isis net '49.0001.1921.6800.1002.00'
+set protocols isis redistribute ipv4 connected level-2 route-map 'EXPORT-ISIS'
+```
+
+**Node 2:**
+
+```none
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set protocols isis interface eth1
+set protocols isis net '49.0001.1921.6800.2002.00'
+```
+
+Routes on Node 2:
+
+```none
+Node-2@r2:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+I 203.0.113.0/24 [115/10] via 192.0.2.1, eth1, 00:03:42
+```
+
+### Enable IS-IS and IGP-LDP synchronization
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address 192.168.255.255/32
+set interfaces ethernet eth0 address 192.0.2.1/24
+
+set protocols isis interface eth0
+set protocols isis interface lo passive
+set protocols isis ldp-sync
+set protocols isis net 49.0001.1921.6825.5255.00
+
+set protocols mpls interface eth0
+set protocols mpls ldp discovery transport-ipv4-address 192.168.255.255
+set protocols mpls ldp interface lo
+set protocols mpls ldp interface eth0
+set protocols mpls ldp parameters transport-prefer-ipv4
+set protocols mpls ldp router-id 192.168.255.255
+```
+
+This gives us IGP-LDP synchronization for all non-loopback interfaces with
+a holddown timer of zero seconds:
+
+```none
+Node-1@vyos:~$ show isis mpls ldp-sync
+eth0
+ LDP-IGP Synchronization enabled: yes
+ holddown timer in seconds: 0
+ State: Sync achieved
+```
+
+### Enable IS-IS with Segment Routing (Experimental)
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address '192.168.255.255/32'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5255.00'
+set protocols isis segment-routing global-block high-label-value '599'
+set protocols isis segment-routing global-block low-label-value '550'
+set protocols isis segment-routing prefix 192.168.255.255/32 index value '1'
+set protocols isis segment-routing prefix 192.168.255.255/32 index explicit-null
+set protocols mpls interface 'eth1'
+```
+
+**Node 2:**
+
+```none
+set interfaces loopback lo address '192.168.255.254/32'
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5254.00'
+set protocols isis segment-routing global-block high-label-value '599'
+set protocols isis segment-routing global-block low-label-value '550'
+set protocols isis segment-routing prefix 192.168.255.254/32 index value '2'
+set protocols isis segment-routing prefix 192.168.255.254/32 index explicit-null
+set protocols mpls interface 'eth1'
+```
+
+This gives us MPLS segment routing enabled and labels for far end loopbacks:
+
+```none
+Node-1@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ ----------------------------------------------------------------------
+ 552 SR (IS-IS) 192.0.2.2 IPv4 Explicit Null <-- Node-2 loopback learned on Node-1
+ 15000 SR (IS-IS) 192.0.2.2 implicit-null
+ 15001 SR (IS-IS) fe80::e87:6cff:fe09:1 implicit-null
+ 15002 SR (IS-IS) 192.0.2.2 implicit-null
+ 15003 SR (IS-IS) fe80::e87:6cff:fe09:1 implicit-null
+
+Node-2@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ ---------------------------------------------------------------------
+ 551 SR (IS-IS) 192.0.2.1 IPv4 Explicit Null <-- Node-1 loopback learned on Node-2
+ 15000 SR (IS-IS) 192.0.2.1 implicit-null
+ 15001 SR (IS-IS) fe80::e33:2ff:fe80:1 implicit-null
+ 15002 SR (IS-IS) 192.0.2.1 implicit-null
+ 15003 SR (IS-IS) fe80::e33:2ff:fe80:1 implicit-null
+```
+
+Here is the routing tables showing the MPLS segment routing label operations:
+
+```none
+Node-1@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.2, eth1 inactive, weight 1, 00:07:48
+I>* 192.168.255.254/32 [115/20] via 192.0.2.2, eth1, label IPv4 Explicit Null, weight 1, 00:03:39
+
+Node-2@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.1, eth1 inactive, weight 1, 00:07:46
+I>* 192.168.255.255/32 [115/20] via 192.0.2.1, eth1, label IPv4 Explicit Null, weight 1, 00:03:43
+```
+
+### Enable IS-IS with Segment Routing over IPv6 (Experimental)
+
+**Node 1:**
+
+```none
+set interfaces dummy dum6 description "SRv6 IS-IS"
+set interfaces ethernet eth1 address '192.0.2.1/24'
+set interfaces loopback lo address '192.168.255.255/32'
+
+set protocols segment-routing srv6 locator MAIN prefix 2001:db8:1::/64
+set protocols segment-routing interface eth1
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5255.00'
+set protocols isis segment-routing srv6 locator MAIN
+set protocols isis segment-routing srv6 interface dum6
+```
+
+**Node 2:**
+
+```none
+set interfaces dummy dum6 description "SRv6 IS-IS"
+set interfaces ethernet eth1 address '192.0.2.2/24'
+set interfaces loopback lo address '192.168.255.254/32'
+
+set protocols segment-routing srv6 locator MAIN prefix 2001:db8:2::/64
+set protocols segment-routing interface eth1
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5254.00'
+set protocols isis segment-routing srv6 locator MAIN
+set protocols isis segment-routing srv6 interface dum6
+```
+
+### Enable IS-IS with Segment Routing over IPv6 (uSID) (Experimental)
+
+**Node 1:**
+
+```none
+set interfaces dummy dum6 description "SRv6 IS-IS"
+set interfaces ethernet eth1 address '192.0.2.1/24'
+set interfaces loopback lo address '192.168.255.255/32'
+
+set protocols segment-routing interface eth1
+set protocols segment-routing srv6 locator MAIN prefix 2001:db8:1::/48
+set protocols segment-routing srv6 locator MAIN behavior-usid
+set protocols segment-routing srv6 locator MAIN block-len 32
+set protocols segment-routing srv6 locator MAIN format usid-f3216
+set protocols segment-routing srv6 locator MAIN func-bits 16
+set protocols segment-routing srv6 locator MAIN node-len 16
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5255.00'
+set protocols isis segment-routing srv6 interface dum6
+set protocols isis segment-routing srv6 locator MAIN
+```
+
+**Node 2:**
+
+```none
+set interfaces dummy dum6 description "SRv6 IS-IS"
+set interfaces ethernet eth1 address '192.0.2.2/24'
+set interfaces loopback lo address '192.168.255.254/32'
+
+set protocols segment-routing interface eth1
+set protocols segment-routing srv6 locator MAIN prefix 2001:db8:2::/48
+set protocols segment-routing srv6 locator MAIN behavior-usid
+set protocols segment-routing srv6 locator MAIN block-len 32
+set protocols segment-routing srv6 locator MAIN format usid-f3216
+set protocols segment-routing srv6 locator MAIN func-bits 16
+set protocols segment-routing srv6 locator MAIN node-len 16
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5254.00'
+set protocols isis segment-routing srv6 interface dum6
+set protocols isis segment-routing srv6 locator MAIN
+```
diff --git a/docs/configuration/protocols/mpls.md b/docs/configuration/protocols/mpls.md
new file mode 100644
index 00000000..71b14be2
--- /dev/null
+++ b/docs/configuration/protocols/mpls.md
@@ -0,0 +1,285 @@
+(mpls)=
+
+# MPLS
+
+{abbr}`MPLS (Multi-Protocol Label Switching)` is a packet forwarding paradigm
+which differs from regular IP forwarding. Instead of IP addresses being used to
+make the decision on finding the exit interface, a router will instead use an
+exact match on a 32 bit/4 byte header called the MPLS label. This label is
+inserted between the ethernet (layer 2) header and the IP (layer 3) header.
+One can statically or dynamically assign label allocations, but we will focus
+on dynamic allocation of labels using some sort of label distribution protocol
+(such as the aptly named Label Distribution Protocol / LDP, Resource Reservation
+Protocol / RSVP, or Segment Routing through OSPF/ISIS). These protocols allow
+for the creation of a unidirectional/unicast path called a labeled switched
+path (initialized as LSP) throughout the network that operates very much like
+a tunnel through the network. An easy way of thinking about how an MPLS LSP
+actually forwards traffic throughout a network is to think of a GRE tunnel.
+They are not the same in how they operate, but they are the same in how they
+handle the tunneled packet. It would be good to think of MPLS as a tunneling
+technology that can be used to transport many different types of packets, to
+aid in traffic engineering by allowing one to specify paths throughout the
+network (using RSVP or SR), and to generally allow for easier intra/inter
+network transport of data packets.
+
+For more information on how MPLS label switching works, please go visit
+[Wikipedia (MPLS)].
+
+:::{note}
+MPLS support in VyOS is not finished yet, and therefore its
+functionality is limited. Currently there is no support for MPLS enabled VPN
+services such as L2VPNs and mVPNs. RSVP support is also not present as the
+underlying routing stack (FRR) does not implement it. Currently VyOS
+implements LDP as described in RFC 5036; other LDP standard are the
+following ones: RFC 6720, RFC 6667, RFC 5919, RFC 5561, RFC 7552, RFC 4447.
+Because MPLS is already available (FRR also supports RFC 3031).
+:::
+
+## Label Distribution Protocol
+
+The {abbr}`MPLS (Multi-Protocol Label Switching)` architecture does not assume
+a single protocol to create MPLS paths. VyOS supports the Label Distribution
+Protocol (LDP) as implemented by FRR, based on {rfc}`5036`.
+
+{abbr}`LDP (Label Distribution Protocol)` is a TCP based MPLS signaling protocol
+that distributes labels creating MPLS label switched paths in a dynamic manner.
+LDP is not a routing protocol, as it relies on other routing protocols for
+forwarding decisions. LDP cannot bootstrap itself, and therefore relies on said
+routing protocols for communication with other routers that use LDP.
+
+In order to allow for LDP on the local router to exchange label advertisements
+with other routers, a TCP session will be established between automatically
+discovered and statically assigned routers. LDP will try to establish a TCP
+session to the **transport address** of other routers. Therefore for LDP to
+function properly please make sure the transport address is shown in the
+routing table and reachable to traffic at all times.
+
+It is highly recommended to use the same address for both the LDP router-id and
+the discovery transport address, but for VyOS MPLS LDP to work both parameters
+must be explicitly set in the configuration.
+
+Another thing to keep in mind with LDP is that much like BGP, it is a protocol
+that runs on top of TCP. It however does not have an ability to do something
+like a refresh capability like BGPs route refresh capability. Therefore one
+might have to reset the neighbor for a capability change or a configuration
+change to work.
+
+## Configuration Options
+
+```{cfgcmd} set protocols mpls interface \<interface\>
+
+Use this command to enable MPLS processing on the interface you define.
+```
+
+
+```{cfgcmd} set protocols mpls ldp interface \<interface\>
+
+Use this command to enable LDP on the interface you define.
+```
+
+
+```{cfgcmd} set protocols mpls ldp router-id \<address\>
+
+Use this command to configure the IP address used as the LDP router-id of the
+local device.
+```
+
+
+```{cfgcmd} set protocols mpls ldp discovery transport-ipv4-address \<address\>
+
+```
+```{cfgcmd} set protocols mpls ldp discovery transport-ipv6-address \<address\>
+
+Use this command to set the IPv4 or IPv6 transport-address used by LDP.
+```
+
+```{cfgcmd} set protocols mpls ldp neighbor \<address\> password \<password\>
+
+Use this command to configure authentication for LDP peers. Set the
+IP address of the LDP peer and a password that should be shared in
+order to become neighbors.
+```
+
+```{cfgcmd} set protocols mpls ldp neighbor \<address\> session-holdtime \<seconds\>
+
+Use this command to configure a specific session hold time for LDP peers.
+Set the IP address of the LDP peer and a session hold time that should be
+configured for it. You may have to reset the neighbor for this to work.
+```
+
+```{cfgcmd} set protocols mpls ldp neighbor \<address\> ttl-security \<disable | hop count\>
+
+Use this command to enable, disable, or specify hop count for TTL security
+for LDP peers. By default the value is set to 255 (or max TTL).
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp discovery hello-ipv4-interval <seconds>
+.. cfgcmd:: set protocols mpls ldp discovery hello-ipv4-holdtime <seconds>
+.. cfgcmd:: set protocols mpls ldp discovery hello-ipv6-interval <seconds>
+.. cfgcmd:: set protocols mpls ldp discovery hello-ipv6-holdtime <seconds>
+
+ Use these commands if you would like to set the discovery hello and hold time
+ parameters.
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp discovery session-ipv4-holdtime <seconds>
+.. cfgcmd:: set protocols mpls ldp discovery session-ipv6-holdtime <seconds>
+
+ Use this command if you would like to set the TCP session hold time intervals.
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp import ipv4 import-filter filter-access-list
+ <access list number>
+.. cfgcmd:: set protocols mpls ldp import ipv6 import-filter filter-access-list6
+ <access list number>
+
+ Use these commands to control the importing of forwarding equivalence classes
+ (FECs) for LDP from neighbors. This would be useful for example on only
+ accepting the labeled routes that are needed and not ones that are not
+ needed, such as accepting loopback interfaces and rejecting all others.
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp export ipv4 export-filter filter-access-list
+ <access list number>
+.. cfgcmd:: set protocols mpls ldp export ipv6 export-filter filter-access-list6
+ <access list number>
+
+ Use these commands to control the exporting of forwarding equivalence classes
+ (FECs) for LDP to neighbors. This would be useful for example on only
+ announcing the labeled routes that are needed and not ones that are not
+ needed, such as announcing loopback interfaces and no others.
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp export ipv4 explicit-null
+.. cfgcmd:: set protocols mpls ldp export ipv6 explicit-null
+
+ Use this command if you would like for the router to advertise FECs with a
+ label of 0 for explicit null operations.
+```
+
+```{eval-rst}
+.. cfgcmd:: set protocols mpls ldp allocation ipv4 access-list <access list number>
+.. cfgcmd:: set protocols mpls ldp allocation ipv6 access-list6 <access list number>
+
+ Use this command if you would like to control the local FEC allocations for
+ LDP. A good example would be for your local router to not allocate a label for
+ everything. Just a label for what it's useful. A good example would be just a
+ loopback label.
+```
+
+```{cfgcmd} set protocols mpls ldp parameters cisco-interop-tlv
+
+Use this command to use a Cisco non-compliant format to send and interpret
+the Dual-Stack capability TLV for IPv6 LDP communications. This is related to
+{rfc}`7552`.
+```
+
+```{cfgcmd} set protocols mpls ldp parameters ordered-control
+
+Use this command to use ordered label distribution control mode. FRR
+by default uses independent label distribution control mode for label
+distribution. This is related to {rfc}`5036`.
+```
+
+```{cfgcmd} set protocols mpls ldp parameters transport-prefer-ipv4
+
+Use this command to prefer IPv4 for TCP peer transport connection for LDP
+when both an IPv4 and IPv6 LDP address are configured on the same interface.
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv4 enable
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv6 enable
+
+Use this command to enable targeted LDP sessions to the local router. The
+router will then respond to any sessions that are trying to connect to it that
+are not a link local type of TCP connection.
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv4 address \<address\>
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv6 address \<address\>
+
+Use this command to enable the local router to try and connect with a targeted
+LDP session to another router.
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv4 hello-holdtime \<seconds\>
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv4 hello-interval \<seconds\>
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv6 hello-holdtime \<seconds\>
+```
+
+```{cfgcmd} set protocols mpls ldp targeted-neighbor ipv6 hello-interval \<seconds\>
+
+Use these commands if you would like to set the discovery hello and hold time
+parameters for the targeted LDP neighbors.
+```
+
+### Sample configuration to setup LDP on VyOS
+
+```none
+set protocols ospf area 0 network '192.168.255.252/32' <--- Routing for loopback
+set protocols ospf area 0 network '192.168.0.5/32' <--- Routing for an interface connecting to the network
+set protocols ospf parameters router-id '192.168.255.252' <--- Router ID setting for OSPF
+set protocols mpls interface 'eth1' <--- Enable MPLS for an interface connecting to network
+set protocols mpls ldp discovery transport-ipv4-address '192.168.255.252' <--- Transport address for LDP for TCP sessions to connect to
+set protocols mpls ldp interface 'eth1' <--- Enable LDP for an interface connecting to network
+set protocols mpls ldp interface 'lo' <--- Enable LDP on loopback for future services connectivity
+set protocols mpls ldp router-id '192.168.255.252' <--- Router ID setting for LDP
+set interfaces ethernet eth1 address '192.168.0.5/31' <--- Interface IP for connecting to network
+set interfaces loopback lo address '192.168.255.252/32' <--- Interface loopback IP for router ID and other uses
+```
+
+## Operational Mode Commands
+
+When LDP is working, you will be able to see label information in the outcome
+of `show ip route`. Besides that information, there are also specific *show*
+commands for LDP:
+
+### Show
+
+```{opcmd} show mpls ldp binding
+
+Use this command to see the Label Information Base.
+
+```
+
+```{opcmd} show mpls ldp discovery
+
+Use this command to see discovery hello information
+```
+
+```{opcmd} show mpls ldp interface
+
+Use this command to see LDP interface information
+```
+
+```{opcmd} show mpls ldp neighbor
+
+Use this command to see LDP neighbor information
+```
+
+```{opcmd} show mpls ldp neighbor detail
+
+Use this command to see detailed LDP neighbor information
+```
+
+### Reset
+
+```{opcmd} reset mpls ldp neighbor \<IPv4 or IPv6 address\>
+
+Use this command to reset an LDP neighbor/TCP session that is established
+```
+
+[wikipedia (mpls)]: <https://en.wikipedia.org/wiki/Multiprotocol_Label_Switching>
diff --git a/docs/configuration/protocols/multicast.md b/docs/configuration/protocols/multicast.md
new file mode 100644
index 00000000..27150a29
--- /dev/null
+++ b/docs/configuration/protocols/multicast.md
@@ -0,0 +1,31 @@
+(routing-static)=
+
+# Multicast
+
+In order to influence Multicast {abbr}`RPF (Reverse Path Forwarding)` lookup,
+it is possible to insert into zebra routes for the Multicast
+{abbr}`RIB (Routing Information Base)`. These routes are only used for RPF
+lookup and will not be used by ZEBRA for insertion into the kernel or for
+normal RIB processing. As such it is possible to create weird states with
+these commands.
+
+Use with caution. Most of the time this will not be necessary.
+
+```{cfgcmd} set protocols static mroute \<subnet\> next-hop \<address\> [distance \<distance\>]
+
+Insert into the Multicast RIB Route `<subnet>` with specified next-hop.
+The distance can be specified as well if desired.
+```
+```{cfgcmd} set protocols static mroute \<subnet\> next-hop \<address\> disable
+
+Do not install route for `<subnet>` into the Multicast RIB.
+```
+```{cfgcmd} set protocols static mroute \<subnet\> interface \<interface\> [distance \<distance\>]
+
+Insert into the Multicast RIB Route `<subnet>` with specified `<interface>`.
+The distance can be specified as well if desired.
+```
+```{cfgcmd} set protocols static mroute \<subnet\> interface \<interface\> disable
+
+Do not install route for `<subnet>` into the Multicast RIB.
+``` \ No newline at end of file
diff --git a/docs/configuration/protocols/openfabric.md b/docs/configuration/protocols/openfabric.md
new file mode 100644
index 00000000..09ff5900
--- /dev/null
+++ b/docs/configuration/protocols/openfabric.md
@@ -0,0 +1,242 @@
+(openfabric)=
+
+# OpenFabric
+
+OpenFabric, specified in [draft-white-openfabric-06.txt](https://datatracker.ietf.org/doc/html/draft-white-openfabric-06), is
+a routing protocol derived from IS-IS, providing link-state routing with
+efficient flooding for topologies like spine-leaf networks.
+
+OpenFabric a dual stack protocol.
+A single OpenFabric instance is able to perform routing for both IPv4 and IPv6.
+
+## General
+
+### Configuration
+
+#### Mandatory Settings
+
+For OpenFabric to operate correctly, one must do the equivalent of a Router ID
+in Connectionless Network Service (CLNS). This Router ID is called the
+{abbr}`NET (Network Entity Title)`. The system identifier must be unique within
+the network
+
+```{cfgcmd} set protocols openfabric net \<network-entity-title\>
+
+This command sets network entity title (NET) provided in ISO format.
+
+Here is an example {abbr}`NET (Network Entity Title)` value:
+
+:::{code-block} none
+49.0001.1921.6800.1002.00
+:::
+The CLNS address consists of the following parts:
+
+* {abbr}`AFI (Address family authority identifier)` - ``49`` The AFI value
+ 49 is what OpenFabric uses for private addressing.
+
+* Area identifier: ``0001`` OpenFabric area number (numerical area ``1``)
+
+* System identifier: ``1921.6800.1002`` - for system identifiers we recommend
+ to use IP address or MAC address of the router itself. The way to construct
+ this is to keep all of the zeroes of the router IP address, and then change
+ the periods from being every three numbers to every four numbers. The
+ address that is listed here is ``192.168.1.2``, which if expanded will turn
+ into ``192.168.001.002``. Then all one has to do is move the dots to have
+ four numbers instead of three. This gives us ``1921.6800.1002``.
+
+* {abbr}`NET (Network Entity Title)` selector: ``00`` Must always be 00. This
+ setting indicates "this system" or "local system."
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> address-family \<ipv4|ipv6\>
+
+This command enables OpenFabric instance with \<NAME\> on this interface, and
+allows for adjacency to occur for address family (IPv4 or IPv6 or both).
+```
+
+#### OpenFabric Global Configuration
+
+```{cfgcmd} set protocols openfabric domain-password \<plaintext-password|md5\> \<password\>
+
+This command configures the authentication password for a routing domain,
+as clear text or md5 one.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> purge-originator
+
+This command enables {rfc}`6232` purge originator identification.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> set-overload-bit
+
+This command sets overload bit to avoid any transit traffic through this
+router.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> log-adjacency-changes
+
+Log changes in adjacency state.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> fabric-tier \<number\>
+
+This command sets a static tier number to advertise as location
+in the fabric.
+```
+
+#### Interface Configuration
+
+```{cfgcmd} set protocols openfabric interface \<interface\> hello-interval \<seconds\>
+
+This command sets hello interval in seconds on a given interface.
+The range is 1 to 600. Hello packets are used to establish and maintain
+adjacency between OpenFabric neighbors.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> hello-multiplier \<number\>
+
+This command sets multiplier for hello holding time on a given
+interface. The range is 2 to 100.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> metric \<metric\>
+
+This command sets default metric for circuit.
+The metric range is 1 to 16777215.
+```
+
+
+```{cfgcmd} set protocols openfabric interface \<interface\> passive
+
+This command enables the passive mode for this interface.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> password plaintext-password \<text\>
+
+This command sets the authentication password for the interface.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> csnp-interval \<seconds\>
+
+This command sets Complete Sequence Number Packets (CSNP) interval in seconds.
+The interval range is 1 to 600.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> interface \<interface\> psnp-interval \<number\>
+
+This command sets Partial Sequence Number Packets (PSNP) interval in seconds.
+The interval range is 1 to 120.
+```
+
+#### Timers
+
+```{cfgcmd} set protocols openfabric domain \<name\> lsp-gen-interval \<seconds\>
+
+This command sets minimum interval at which link-state packets (LSPs) are
+generated. The interval range is 1 to 120.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> lsp-refresh-interval \<seconds\>
+
+This command sets LSP refresh interval in seconds. The interval range
+is 1 to 65235.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> max-lsp-lifetime \<seconds\>
+
+This command sets LSP maximum LSP lifetime in seconds. The interval range
+is 360 to 65535. LSPs remain in a database for 1200 seconds by default.
+If they are not refreshed by that time, they are deleted. You can change
+the LSP refresh interval or the LSP lifetime. The LSP refresh interval
+should be less than the LSP lifetime or else LSPs will time out before
+they are refreshed.
+```
+
+
+```{cfgcmd} set protocols openfabric domain \<name\> spf-interval \<seconds\>
+
+This command sets minimum interval between consecutive shortest path first
+(SPF) calculations in seconds.The interval range is 1 to 120.
+```
+
+## Examples
+### Enable OpenFabric
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address '192.168.255.255/32'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+
+set protocols openfabric domain VyOS interface eth1 address-family ipv4
+set protocols openfabric domain VyOS interface lo address-family ipv4
+set protocols openfabric net '49.0001.1921.6825.5255.00'
+```
+
+**Node 2:**
+
+```none
+set interfaces loopback lo address '192.168.255.254/32'
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set protocols openfabric domain VyOS interface eth1 address-family ipv4
+set protocols openfabric domain VyOS interface lo address-family ipv4
+set protocols openfabric net '49.0001.1921.6825.5254.00'
+```
+
+This gives us the following neighborships:
+
+```none
+Node-1@vyos:~$ show openfabric neighbor
+show openfabric neighbor
+Area VyOS:
+ System Id Interface L State Holdtime SNPA
+ vyos eth1 2 Up 27 2020.2020.2020
+
+
+Node-2@vyos:~$ show openfabric neighbor
+show openfabric neighbor
+Area VyOS:
+ System Id Interface L State Holdtime SNPA
+ vyos eth1 2 Up 30 2020.2020.2020
+```
+
+Here's the IP routes that are populated:
+
+```none
+Node-1@vyos:~$ show ip route openfabric
+show ip route openfabric
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+f 192.0.2.0/24 [115/20] via 192.0.2.2, eth1 onlink, weight 1, 00:00:10
+f>* 192.168.255.254/32 [115/20] via 192.0.2.2, eth1 onlink, weight 1, 00:00:10
+
+Node-2@vyos:~$ show ip route openfabric
+show ip route openfabric
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+f 192.0.2.0/24 [115/20] via 192.0.2.1, eth1 onlink, weight 1, 00:00:48
+f>* 192.168.255.255/32 [115/20] via 192.0.2.1, eth1 onlink, weight 1, 00:00:48
+```
diff --git a/docs/configuration/protocols/ospf.md b/docs/configuration/protocols/ospf.md
new file mode 100644
index 00000000..72fefb84
--- /dev/null
+++ b/docs/configuration/protocols/ospf.md
@@ -0,0 +1,1504 @@
+(routing-ospf)=
+
+# OSPF
+
+{abbr}`OSPF (Open Shortest Path First)` is a routing protocol for Internet
+Protocol (IP) networks. It uses a link state routing (LSR) algorithm and falls
+into the group of interior gateway protocols (IGPs), operating within a single
+autonomous system (AS). It is defined as OSPF Version 2 in {rfc}`2328` (1998)
+for IPv4. Updates for IPv6 are specified as OSPF Version 3 in {rfc}`5340`
+(2008). OSPF supports the {abbr}`CIDR (Classless Inter-Domain Routing)`
+addressing model.
+
+OSPF is a widely used IGP in large enterprise networks.
+
+## OSPFv2 (IPv4)
+
+### Configuration
+
+#### General
+
+VyOS does not have a special command to start the OSPF process. The OSPF process
+starts when the first ospf enabled interface is configured.
+
+```{cfgcmd} set protocols ospf area \<number\> network \<A.B.C.D/M\>
+
+ This command specifies the OSPF enabled interface(s). If the interface has
+ an address from defined range then the command enables OSPF on this
+ interface so router can provide network information to the other ospf
+ routers via this interface.
+
+ This command is also used to enable the OSPF process. The area number can be
+ specified in decimal notation in the range from 0 to 4294967295. Or it
+ can be specified in dotted decimal notation similar to ip address.
+
+ Prefix length in interface must be equal or bigger (i.e. smaller network)
+ than prefix length in network statement. For example statement above doesn't
+ enable ospf on interface with address 192.168.1.1/23, but it does on
+ interface with address 192.168.1.129/25.
+
+ In some cases it may be more convenient to enable OSPF on a per
+ interface/subnet
+ basis {cfgcmd}`set protocols ospf interface <interface> area <x.x.x.x | x>`
+```
+
+
+```{cfgcmd} set protocols ospf auto-cost reference-bandwidth \<number\>
+
+This command sets the reference bandwidth for cost calculations, where
+bandwidth can be in range from 1 to 4294967, specified in Mbits/s. The
+default is 100Mbit/s (i.e. a link of bandwidth 100Mbit/s or higher will
+have a cost of 1. Cost of lower bandwidth links will be scaled with
+reference to this cost).
+```
+
+
+```{cfgcmd} set protocols ospf parameters router-id \<rid\>
+
+This command sets the router-ID of the OSPF process. The router-ID may be an
+IP address of the router, but need not be – it can be any arbitrary 32bit
+number. However it MUST be unique within the entire OSPF domain to the OSPF
+speaker – bad things will happen if multiple OSPF speakers are configured
+with the same router-ID!
+```
+
+#### Optional
+
+```{cfgcmd} set protocols ospf default-information originate [always] [metric \<number\>] [metric-type \<1|2\>] [route-map \<name\>]
+
+Originate an AS-External (type-5) LSA describing a default route into all
+external-routing capable areas, of the specified metric and metric type.
+If the {cfgcmd}`always` keyword is given then the default is always
+advertised, even when there is no default present in the routing table.
+The argument {cfgcmd}`route-map` specifies to advertise the default route
+if the route map is satisfied.
+```
+
+
+```{cfgcmd} set protocols ospf distance global \<distance\>
+
+This command change distance value of OSPF globally.
+The distance range is 1 to 255.
+```
+
+
+```{cfgcmd} set protocols ospf distance ospf \<external|inter-area|intra-area\> \<distance\>
+
+This command change distance value of OSPF. The arguments are the distance
+values for external routes, inter-area routes and intra-area routes
+respectively. The distance range is 1 to 255.
+
+:::{note}
+Routes with a distance of 255 are effectively disabled and not
+installed into the kernel.
+:::
+```
+
+
+```{cfgcmd} set protocols ospf log-adjacency-changes [detail]
+
+This command allows to log changes in adjacency. With the optional
+{cfgcmd}`detail` argument, all changes in adjacency status are shown.
+Without {cfgcmd}`detail`, only changes to full or regressions are shown.
+```
+
+
+```{cfgcmd} set protocols ospf max-metric router-lsa \<administrative|on-shutdown <seconds\>|on-startup \<seconds\>>
+
+This enables {rfc}`3137` support, where the OSPF process describes its
+transit links in its router-LSA as having infinite distance so that other
+routers will avoid calculating transit paths through the router while
+still being able to reach networks through the router.
+
+This support may be enabled administratively (and indefinitely) with the
+{cfgcmd}`administrative` command. It may also be enabled conditionally.
+Conditional enabling of max-metric router-lsas can be for a period of
+seconds after startup with the {cfgcmd}`on-startup <seconds>` command
+and/or for a period of seconds prior to shutdown with the
+{cfgcmd}`on-shutdown <seconds>` command. The time range is 5 to 86400.
+```
+
+
+```{cfgcmd} set protocols ospf parameters abr-type \<cisco|ibm|shortcut|standard\>
+
+This command selects ABR model. OSPF router supports four ABR models:
+
+**cisco** – a router will be considered as ABR if it has several configured
+links to the networks in different areas one of which is a backbone area.
+Moreover, the link to the backbone area should be active (working).
+**ibm** – identical to "cisco" model but in this case a backbone area link
+may not be active.
+**standard** – router has several active links to different areas.
+**shortcut** – identical to "standard" but in this model a router is
+allowed to use a connected areas topology without involving a backbone
+area for inter-area connections.
+
+Detailed information about "cisco" and "ibm" models differences can be
+found in {rfc}`3509`. A "shortcut" model allows ABR to create routes
+between areas based on the topology of the areas connected to this router
+but not using a backbone area in case if non-backbone route will be
+cheaper. For more information about "shortcut" model,
+see ospf-shortcut-abr-02.txt
+```
+
+
+```{cfgcmd} set protocols ospf parameters rfc1583-compatibility
+
+{rfc}`2328`, the successor to {rfc}`1583`, suggests according to section
+G.2 (changes) in section 16.4.1 a change to the path preference algorithm
+that prevents possible routing loops that were possible in the old version
+of OSPFv2. More specifically it demands that inter-area paths and
+intra-area backbone path are now of equal preference but still both
+preferred to external paths.
+
+This command should NOT be set normally.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> passive [disable]
+
+This command specifies interface as passive. Passive interface advertises
+its address, but does not run the OSPF protocol (adjacencies are not formed
+and hello packets are not generated).
+
+The optional disable option allows to exclude interface from passive state.
+This command is used if the command {cfgcmd}`passive-interface default` was
+configured.
+```
+
+
+```{cfgcmd} set protocols ospf passive-interface default
+
+This command specifies all interfaces as passive by default. Because this
+command changes the configuration logic to a default passive; therefore,
+interfaces where router adjacencies are expected need to be configured
+with the {cfgcmd}`passive-interface-exclude` command.
+```
+
+
+```{cfgcmd} set protocols ospf maximum-paths \<1-64\>
+
+Use this command to control the maximum number of equal cost paths to reach
+a specific destination. The upper limit may differ if you change the value
+of MULTIPATH_NUM during compilation. The default is MULTIPATH_NUM (64).
+```
+
+
+```{cfgcmd} set protocols ospf refresh timers \<seconds\>
+
+The router automatically updates link-state information with its neighbors.
+Only an obsolete information is updated which age has exceeded a specific
+threshold. This parameter changes a threshold value, which by default is
+1800 seconds (half an hour). The value is applied to the whole OSPF router.
+The timer range is 10 to 1800.
+```
+
+
+```{cfgcmd} set protocols ospf timers throttle spf \<delay|initial-holdtime|max-holdtime\> \<seconds\>
+
+This command sets the initial delay, the initial-holdtime and the
+maximum-holdtime between when SPF is calculated and the event which
+triggered the calculation. The times are specified in milliseconds and must
+be in the range of 0 to 600000 milliseconds. {cfgcmd}`delay` sets the
+initial SPF schedule delay in milliseconds. The default value is 200 ms.
+{cfgcmd}`initial-holdtime` sets the minimum hold time between two
+consecutive SPF calculations. The default value is 1000 ms.
+{cfgcmd}`max-holdtime` sets the maximum wait time between two
+consecutive SPF calculations. The default value is 10000 ms.
+```
+
+
+```{cfgcmd} set protocols ospf ldp-sync
+
+This command will enable IGP-LDP synchronization globally for OSPF. This
+requires for LDP to be functional. This is described in {rfc}`5443`. By
+default all interfaces operational in OSPF are enabled for synchronization.
+Loopbacks are exempt.
+```
+
+
+```{cfgcmd} set protocols ospf ldp-sync holddown \<seconds\>
+
+This command will change the hold down value globally for IGP-LDP
+synchronization during convergence/interface flap events.
+```
+
+
+```{cfgcmd} set protocols ospf capability opaque
+
+ospfd supports Opaque LSA {rfc}`2370` as partial support for MPLS Traffic
+Engineering LSAs. The opaque-lsa capability must be enabled in the
+configuration.
+
+An alternate command could be "mpls-te on" (Traffic Engineering)
+
+:::{note}
+FRR offers only partial support for some of the routing
+protocol extensions that are used with MPLS-TE; it does not
+support a complete RSVP-TE solution.
+:::
+```
+
+#### Area Configuration
+
+```{cfgcmd} set protocols ospf area \<number\> area-type stub
+
+This command specifies the area to be a Stub Area. That is, an area where
+no router originates routes external to OSPF and hence an area where all
+external routes are via the ABR(s). Hence, ABRs for such an area do not
+need to pass AS-External LSAs (type-5) or ASBR-Summary LSAs (type-4) into
+the area. They need only pass Network-Summary (type-3) LSAs into such an
+area, along with a default-route summary.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type stub no-summary
+
+This command specifies the area to be a Totally Stub Area. In addition to
+stub area limitations this area type prevents an ABR from injecting
+Network-Summary (type-3) LSAs into the specified stub area. Only default
+summary route is allowed.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type stub default-cost \<number\>
+
+This command sets the cost of default-summary LSAs announced to stubby
+areas. The cost range is 0 to 16777215.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type nssa
+
+This command specifies the area to be a Not So Stubby Area. External
+routing information is imported into an NSSA in Type-7 LSAs. Type-7 LSAs
+are similar to Type-5 AS-external LSAs, except that they can only be
+flooded into the NSSA. In order to further propagate the NSSA external
+information, the Type-7 LSA must be translated to a Type-5 AS-external-LSA
+by the NSSA ABR.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type nssa no-summary
+
+This command specifies the area to be a NSSA Totally Stub Area. ABRs for
+such an area do not need to pass Network-Summary (type-3) LSAs (except the
+default summary route), ASBR-Summary LSAs (type-4) and AS-External LSAs
+(type-5) into the area. But Type-7 LSAs that convert to Type-5 at the NSSA
+ABR are allowed.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type nssa default-cost \<number\>
+
+This command sets the default cost of LSAs announced to NSSA areas.
+The cost range is 0 to 16777215.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> area-type nssa translate \<always|candidate|never\>
+
+Specifies whether this NSSA border router will unconditionally translate
+Type-7 LSAs into Type-5 LSAs. When role is Always, Type-7 LSAs are
+translated into Type-5 LSAs regardless of the translator state of other
+NSSA border routers. When role is Candidate, this router participates in
+the translator election to determine if it will perform the translations
+duties. When role is Never, this router will never translate Type-7 LSAs
+into Type-5 LSAs.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> authentication plaintext-password
+
+This command specifies that simple password authentication should be used
+for the given area. The password must also be configured on a per-interface
+basis.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> authentication md5
+
+This command specify that OSPF packets must be authenticated with MD5 HMACs
+within the given area. Keying material must also be configured on a
+per-interface basis.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> range \<A.B.C.D/M\> [cost \<number\>]
+
+This command summarizes intra area paths from specified area into one
+summary-LSA (Type-3) announced to other areas. This command can be used
+only in ABR and ONLY router-LSAs (Type-1) and network-LSAs (Type-2)
+(i.e. LSAs with scope area) can be summarized. AS-external-LSAs (Type-5)
+can’t be summarized - their scope is AS. The optional argument
+{cfgcmd}`cost` specifies the aggregated link metric. The metric range is 0
+to 16777215.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> range \<A.B.C.D/M\> not-advertise
+
+This command instead of summarizing intra area paths filter them - i.e.
+intra area paths from this range are not advertised into other areas.
+This command makes sense in ABR only.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> export-list \<acl_number\>
+
+Filter Type-3 summary-LSAs announced to other areas originated from
+intra- area paths from specified area.
+This command makes sense in ABR only.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> import-list \<acl_number\>
+
+Same as export-list, but it applies to paths announced into specified
+area as Type-3 summary-LSAs.
+This command makes sense in ABR only.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> range \<A.B.C.D/M\> substitute \<E.F.G.H/M\>
+
+One Type-3 summary-LSA with routing info <E.F.G.H/M> is announced into
+backbone area if defined area contains at least one intra-area network
+(i.e. described with router-LSA or network-LSA) from range <A.B.C.D/M>.
+This command makes sense in ABR only.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> shortcut \<default|disable|enable\>
+
+This parameter allows to "shortcut" routes (non-backbone) for inter-area
+routes. There are three modes available for routes shortcutting:
+
+**default** – this area will be used for shortcutting only if ABR does not
+have a link to the backbone area or this link was lost.
+**enable** – the area will be used for shortcutting every time the route
+that goes through it is cheaper.
+**disable** – this area is never used by ABR for routes shortcutting.
+```
+
+
+```{cfgcmd} set protocols ospf area \<number\> virtual-link \<A.B.C.D\>
+
+Provides a backbone area coherence by virtual link establishment.
+
+In general, OSPF protocol requires a backbone area (area 0) to be coherent
+and fully connected. I.e. any backbone area router must have a route to any
+other backbone area router. Moreover, every ABR must have a link to
+backbone area. However, it is not always possible to have a physical link
+to a backbone area. In this case between two ABR (one of them has a link to
+the backbone area) in the area (not stub area) a virtual link is organized.
+
+\<number\> – area identifier through which a virtual link goes.
+\<A.B.C.D\> – ABR router-id with which a virtual link is established. Virtual
+link must be configured on both routers.
+
+Formally, a virtual link looks like a point-to-point network connecting two
+ABR from one area one of which physically connected to a backbone area.
+This pseudo-network is considered to belong to a backbone area.
+```
+
+#### Interface Configuration
+
+```{cfgcmd} set protocols ospf interface \<interface\> area \<x.x.x.x | x\>
+
+ Enable ospf on an interface and set associated area.
+
+ If you have a lot of interfaces, and/or a lot of subnets, then enabling
+ OSPF via this command may result in a slight performance improvement.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> authentication plaintext-password \<text\>
+
+This command sets OSPF authentication key to a simple password. After
+setting, all OSPF packets are authenticated. Key has length up to 8 chars.
+
+Simple text password authentication is insecure and deprecated in favour of
+MD5 HMAC authentication.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> authentication md5 key-id \<id\> md5-key \<text\>
+
+This command specifys that MD5 HMAC authentication must be used on this
+interface. It sets OSPF authentication key to a cryptographic password.
+Key-id identifies secret key used to create the message digest. This ID
+is part of the protocol and must be consistent across routers on a link.
+The key can be long up to 16 chars (larger strings will be truncated),
+and is associated with the given key-id.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> bandwidth \<number\>
+
+This command sets the interface bandwidth for cost calculations, where
+bandwidth can be in range from 1 to 100000, specified in Mbits/s.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> cost \<number\>
+
+This command sets link cost for the specified interface. The cost value is
+set to router-LSA’s metric field and used for SPF calculation. The cost
+range is 1 to 65535.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> dead-interval \<number\>
+
+Set number of seconds for router Dead Interval timer value used for Wait
+Timer and Inactivity Timer. This value must be the same for all routers
+attached to a common network. The default value is 40 seconds. The
+interval range is 1 to 65535.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> hello-multiplier \<number\>
+
+The hello-multiplier specifies how many Hellos to send per second, from 1
+(every second) to 10 (every 100ms). Thus one can have 1s convergence time
+for OSPF. If this form is specified, then the hello-interval advertised in
+Hello packets is set to 0 and the hello-interval on received Hello packets
+is not checked, thus the hello-multiplier need NOT be the same across
+multiple routers on a common link.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> hello-interval \<number\>
+
+Set number of seconds for Hello Interval timer value. Setting this value,
+Hello packet will be sent every timer value seconds on the specified
+interface. This value must be the same for all routers attached to a
+common network. The default value is 10 seconds. The interval range is 1
+to 65535.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> bfd
+
+This command enables {abbr}`BFD (Bidirectional Forwarding Detection)` on
+this OSPF link interface.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> mtu-ignore
+
+This command disables check of the MTU value in the OSPF DBD packets. Thus,
+use of this command allows the OSPF adjacency to reach the FULL state even
+though there is an interface MTU mismatch between two OSPF routers.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> network \<type\>
+
+This command allows to specify the distribution type for the network
+connected to this interface:
+
+**broadcast** – broadcast IP addresses distribution.
+**non-broadcast** – address distribution in NBMA networks topology.
+**point-to-multipoint** – address distribution in point-to-multipoint
+networks.
+**point-to-point** – address distribution in point-to-point networks.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> priority \<number\>
+
+This command sets Router Priority integer value. The router with the
+highest priority will be more eligible to become Designated Router.
+Setting the value to 0, makes the router ineligible to become
+Designated Router. The default value is 1. The interval range is 0 to 255.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> retransmit-interval \<number\>
+
+This command sets number of seconds for RxmtInterval timer value. This
+value is used when retransmitting Database Description and Link State
+Request packets if acknowledge was not received. The default value is 5
+seconds. The interval range is 3 to 65535.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> transmit-delay \<number\>
+
+This command sets number of seconds for InfTransDelay value. It allows to
+set and adjust for each interface the delay interval before starting the
+synchronizing process of the router's database with all neighbors. The
+default value is 1 seconds. The interval range is 3 to 65535.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> ldp-sync disable
+
+This command disables IGP-LDP sync for this specific interface.
+```
+
+
+```{cfgcmd} set protocols ospf interface \<interface\> ldp-sync holddown \<seconds\>
+
+This command will change the hold down value for IGP-LDP synchronization
+during convergence/interface flap events, but for this interface only.
+```
+
+#### External Route Summarisation
+
+
+This feature summarises originated external LSAs (Type-5 and Type-7). Summary
+Route will be originated on-behalf of all matched external LSAs.
+
+```{cfgcmd} set protocols ospf aggregation timer \<seconds\>
+
+Configure aggregation delay timer interval.
+
+Summarisation starts only after this delay timer expiry.
+```
+
+
+```{cfgcmd} set protocols ospf summary-address x.x.x.x/y [tag (1-4294967295)]
+
+This command enable/disables summarisation for the configured address range.
+
+Tag is the optional parameter. If tag configured Summary route will be
+originated with the configured tag.
+```
+
+
+```{cfgcmd} set protocols ospf summary-address x.x.x.x/y no-advertise
+
+This command to ensure not advertise the summary lsa for the matched
+external LSAs.
+```
+
+#### Graceful Restart
+
+```{cfgcmd} set protocols ospf graceful-restart [grace-period (1-1800)]
+
+Configure Graceful Restart {rfc}`3623` restarting support. When enabled,
+the default grace period is 120 seconds.
+
+To perform a graceful shutdown, the FRR ``graceful-restart prepare ip
+ospf`` EXEC-level command needs to be issued before restarting the
+ospfd daemon.
+```
+
+
+```{cfgcmd} set protocols ospf graceful-restart helper enable [router-id A.B.C.D]
+
+Configure Graceful Restart {rfc}`3623` helper support. By default, helper support
+is disabled for all neighbours. This config enables/disables helper support
+on this router for all neighbours.
+
+To enable/disable helper support for a specific neighbour, the router-id
+(A.B.C.D) has to be specified.
+```
+
+
+```{cfgcmd} set protocols ospf graceful-restart helper no-strict-lsa-checking
+
+By default strict-lsa-checking is configured then the helper will abort
+the Graceful Restart when a LSA change occurs which affects the restarting
+router.
+
+This command disables it.
+```
+
+
+```{cfgcmd} set protocols ospf graceful-restart helper supported-grace-time
+
+Supports as HELPER for configured grace period.
+```
+
+
+```{cfgcmd} set protocols ospf graceful-restart helper planned-only
+
+It helps to support as HELPER only for planned restarts.
+
+By default, it supports both planned and unplanned outages.
+```
+
+#### Manual Neighbor Configuration
+
+
+OSPF routing devices normally discover their neighbors dynamically by
+listening to the broadcast or multicast hello packets on the network.
+Because an NBMA network does not support broadcast (or multicast), the
+device cannot discover its neighbors dynamically, so you must configure all
+the neighbors statically.
+
+```{cfgcmd} set protocols ospf neighbor \<A.B.C.D\>
+
+This command specifies the IP address of the neighboring device.
+```
+
+
+```{cfgcmd} set protocols ospf neighbor \<A.B.C.D\> poll-interval \<seconds\>
+
+This command specifies the length of time, in seconds, before the routing
+device sends hello packets out of the interface before it establishes
+adjacency with a neighbor. The range is 1 to 65535 seconds. The default
+value is 60 seconds.
+```
+
+
+```{cfgcmd} set protocols ospf neighbor \<A.B.C.D\> priority \<number\>
+
+This command specifies the router priority value of the nonbroadcast
+neighbor associated with the IP address specified. The default is 0.
+This keyword does not apply to point-to-multipoint interfaces.
+```
+
+#### Redistribution Configuration
+
+```{cfgcmd} set protocols ospf redistribute \<route source\>
+
+ This command redistributes routing information from the given route source
+ to the OSPF process. There are five modes available for route source: bgp,
+ connected, kernel, rip, static.
+```
+
+
+```{cfgcmd} set protocols ospf default-metric \<number\>
+
+This command specifies the default metric value of redistributed routes.
+The metric range is 0 to 16777214.
+```
+
+
+```{cfgcmd} set protocols ospf redistribute \<route source\> metric \<number\>
+
+This command specifies metric for redistributed routes from the given
+route source. There are five modes available for route source: bgp,
+connected, kernel, rip, static. The metric range is 1 to 16777214.
+```
+
+
+```{cfgcmd} set protocols ospf redistribute \<route source\> metric-type \<1|2\>
+
+This command specifies metric type for redistributed routes. Difference
+between two metric types that metric type 1 is a metric which is
+"commensurable" with inner OSPF links. When calculating a metric to the
+external destination, the full path metric is calculated as a metric sum
+path of a router which had advertised this link plus the link metric.
+Thus, a route with the least summary metric will be selected. If external
+link is advertised with metric type 2 the path is selected which lies
+through the router which advertised this link with the least metric
+despite of the fact that internal path to this router is longer (with more
+cost). However, if two routers advertised an external link and with metric
+type 2 the preference is given to the path which lies through the router
+with a shorter internal path. If two different routers advertised two
+links to the same external destimation but with different metric type,
+metric type 1 is preferred. If type of a metric left undefined the router
+will consider these external links to have a default metric type 2.
+```
+
+
+```{cfgcmd} set protocols ospf redistribute \<route source\> route-map \<name\>
+
+This command allows to use route map to filter redistributed routes from
+the given route source. There are five modes available for route source:
+bgp, connected, kernel, rip, static.
+```
+
+#### Operational Mode Commands
+
+```{opcmd} show ip ospf neighbor
+
+ This command displays the neighbors status.
+```
+
+
+```none
+Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL
+10.0.13.1 1 Full/DR 38.365s 10.0.13.1 eth0:10.0.13.3 0 0 0
+10.0.23.2 1 Full/Backup 39.175s 10.0.23.2 eth1:10.0.23.3 0 0 0
+```
+
+
+```{opcmd} show ip ospf neighbor detail
+
+This command displays the neighbors information in a detailed form, not
+just a summary table.
+```
+
+
+```none
+ Neighbor 10.0.13.1, interface address 10.0.13.1
+
+ In the area 0.0.0.0 via interface eth0
+
+ Neighbor priority is 1, State is Full, 5 state changes
+
+ Most recent state change statistics:
+
+ Progressive change 11m55s ago
+
+ DR is 10.0.13.1, BDR is 10.0.13.3
+
+ Options 2 *|-|-|-|-|-|E|-
+
+ Dead timer due in 34.854s
+
+ Database Summary List 0
+
+ Link State Request List 0
+
+ Link State Retransmission List 0
+
+ Thread Inactivity Timer on
+
+ Thread Database Description Retransmision off
+
+ Thread Link State Request Retransmission on
+
+ Thread Link State Update Retransmission on
+
+
+Neighbor 10.0.23.2, interface address 10.0.23.2
+
+ In the area 0.0.0.1 via interface eth1
+
+ Neighbor priority is 1, State is Full, 4 state changes
+
+ Most recent state change statistics:
+
+ Progressive change 41.193s ago
+
+ DR is 10.0.23.3, BDR is 10.0.23.2
+
+ Options 2 *|-|-|-|-|-|E|-
+
+ Dead timer due in 35.661s
+
+ Database Summary List 0
+
+ Link State Request List 0
+
+ Link State Retransmission List 0
+
+ Thread Inactivity Timer on
+
+ Thread Database Description Retransmision off
+
+ Thread Link State Request Retransmission on
+
+ Thread Link State Update Retransmission on
+```
+
+
+```{opcmd} show ip ospf neighbor \<A.B.C.D\>
+
+This command displays the neighbors information in a detailed form for a
+neighbor whose IP address is specified.
+```
+
+
+```{opcmd} show ip ospf neighbor \<interface\>
+
+This command displays the neighbors status for a neighbor on the specified
+interface.
+```
+
+
+```{opcmd} show ip ospf interface [\<interface\>]
+
+This command displays state and configuration of OSPF the specified
+interface, or all interfaces if no interface is given.
+```
+
+
+```none
+eth0 is up
+ ifindex 2, MTU 1500 bytes, BW 4294967295 Mbit <UP,BROADCAST,RUNNING,MULTICAST>
+ Internet Address 10.0.13.3/24, Broadcast 10.0.13.255, Area 0.0.0.0
+ MTU mismatch detection: enabled
+ Router ID 10.0.23.3, Network Type BROADCAST, Cost: 1
+ Transmit Delay is 1 sec, State Backup, Priority 1
+ Backup Designated Router (ID) 10.0.23.3, Interface Address 10.0.13.3
+ Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
+ Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
+ Hello due in 4.470s
+ Neighbor Count is 1, Adjacent neighbor count is 1
+eth1 is up
+ ifindex 3, MTU 1500 bytes, BW 4294967295 Mbit <UP,BROADCAST,RUNNING,MULTICAST>
+ Internet Address 10.0.23.3/24, Broadcast 10.0.23.255, Area 0.0.0.1
+ MTU mismatch detection: enabled
+ Router ID 10.0.23.3, Network Type BROADCAST, Cost: 1
+ Transmit Delay is 1 sec, State DR, Priority 1
+ Backup Designated Router (ID) 10.0.23.2, Interface Address 10.0.23.2
+ Saved Network-LSA sequence number 0x80000002
+ Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
+ Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
+ Hello due in 4.563s
+ Neighbor Count is 1, Adjacent neighbor count is 1
+```
+
+
+```{opcmd} show ip ospf route [detail]
+
+This command displays the OSPF routing table, as determined by the most
+recent SPF calculation. With the optional {cfgcmd}`detail` argument,
+each route item's advertiser router and network attribute will be shown.
+```
+
+
+```none
+============ OSPF network routing table ============
+N IA 10.0.12.0/24 [3] area: 0.0.0.0
+ via 10.0.13.3, eth0
+N 10.0.13.0/24 [1] area: 0.0.0.0
+ directly attached to eth0
+N IA 10.0.23.0/24 [2] area: 0.0.0.0
+ via 10.0.13.3, eth0
+N 10.0.34.0/24 [2] area: 0.0.0.0
+ via 10.0.13.3, eth0
+
+============ OSPF router routing table =============
+R 10.0.23.3 [1] area: 0.0.0.0, ABR
+ via 10.0.13.3, eth0
+R 10.0.34.4 [2] area: 0.0.0.0, ASBR
+ via 10.0.13.3, eth0
+
+============ OSPF external routing table ===========
+N E2 172.16.0.0/24 [2/20] tag: 0
+ via 10.0.13.3, eth0
+```
+
+The table consists of following data:
+
+
+**OSPF network routing table** – includes a list of acquired routes for all
+accessible networks (or aggregated area ranges) of OSPF system. "IA" flag
+means that route destination is in the area to which the router is not
+connected, i.e. it’s an inter-area path. In square brackets a summary metric
+for all links through which a path lies to this network is specified. "via"
+prefix defines a router-gateway, i.e. the first router on the way to the
+destination (next hop).
+**OSPF router routing table** – includes a list of acquired routes to all
+accessible ABRs and ASBRs.
+**OSPF external routing table** – includes a list of acquired routes that are
+external to the OSPF process. "E" flag points to the external link metric type
+(E1 – metric type 1, E2 – metric type 2). External link metric is printed in
+the "\<metric of the router which advertised the link>/\<link metric>" format.
+
+```{opcmd} show ip ospf border-routers
+
+This command displays a table of paths to area boundary and autonomous
+system boundary routers.
+```
+
+
+```{opcmd} show ip ospf database
+
+This command displays a summary table with a database contents (LSA).
+```
+
+
+```none
+ OSPF Router with ID (10.0.13.1)
+
+ Router Link States (Area 0.0.0.0)
+
+Link ID ADV Router Age Seq# CkSum Link count
+10.0.13.1 10.0.13.1 984 0x80000005 0xd915 1
+10.0.23.3 10.0.23.3 1186 0x80000008 0xfe62 2
+10.0.34.4 10.0.34.4 1063 0x80000004 0x4e3f 1
+
+ Net Link States (Area 0.0.0.0)
+
+Link ID ADV Router Age Seq# CkSum
+10.0.13.1 10.0.13.1 994 0x80000003 0x30bb
+10.0.34.4 10.0.34.4 1188 0x80000001 0x9411
+
+ Summary Link States (Area 0.0.0.0)
+
+Link ID ADV Router Age Seq# CkSum Route
+10.0.12.0 10.0.23.3 1608 0x80000001 0x6ab6 10.0.12.0/24
+10.0.23.0 10.0.23.3 981 0x80000003 0xe232 10.0.23.0/24
+
+ AS External Link States
+
+Link ID ADV Router Age Seq# CkSum Route
+172.16.0.0 10.0.34.4 1063 0x80000001 0xc40d E2 172.16.0.0/24 [0x0]
+```
+
+
+```{opcmd} show ip ospf database \<type\> [A.B.C.D] [adv-router \<A.B.C.D\>|self-originate]
+
+ This command displays a database contents for a specific link advertisement
+ type.
+
+ The type can be the following:
+ asbr-summary, external, network, nssa-external, opaque-area, opaque-as,
+ opaque-link, router, summary.
+
+ [A.B.C.D] – link-state-id. With this specified the command displays portion
+ of the network environment that is being described by the advertisement.
+ The value entered depends on the advertisement’s LS type. It must be
+ entered in the form of an IP address.
+
+ {cfgcmd}`adv-router <A.B.C.D>` – router id, which link advertisements need
+ to be reviewed.
+
+ {cfgcmd}`self-originate` displays only self-originated LSAs from the local
+ router.
+```
+
+
+```none
+ OSPF Router with ID (10.0.13.1)
+
+ Router Link States (Area 0.0.0.0)
+
+LS age: 1213
+Options: 0x2 : *|-|-|-|-|-|E|-
+LS Flags: 0x3
+Flags: 0x0
+LS Type: router-LSA
+Link State ID: 10.0.13.1
+Advertising Router: 10.0.13.1
+LS Seq Number: 80000009
+Checksum: 0xd119
+Length: 36
+
+ Number of Links: 1
+
+ Link connected to: a Transit Network
+ (Link ID) Designated Router address: 10.0.13.1
+ (Link Data) Router Interface address: 10.0.13.1
+ Number of TOS metrics: 0
+ TOS 0 Metric: 1
+```
+
+
+```{opcmd} show ip ospf database max-age
+
+This command displays LSAs in MaxAge list.
+```
+
+#### Examples
+### Enable OSPF
+
+**Node 1**
+
+```none
+set interfaces loopback lo address 10.1.1.1/32
+set interfaces ethernet eth0 address 192.168.0.1/24
+set protocols ospf area 0 network 192.168.0.0/24
+set protocols ospf area 0 network 10.1.1.1/32
+set protocols ospf parameters router-id 10.1.1.1
+```
+
+**Node 2**
+
+```none
+set interfaces loopback lo address 10.1.1.2/32
+set interfaces ethernet eth0 address 192.168.0.2/24
+set protocols ospf area 0 network 192.168.0.0/24
+set protocols ospf area 0 network 10.1.1.2/32
+set protocols ospf parameters router-id 10.1.1.2
+```
+
+Here's the neighbors up:
+
+```none
+Node-1@vyos:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
+10.1.1.2 1 Full/DR 3m43s 36.094s 192.168.0.2 eth0:192.168.0.1 0 0 0
+
+
+Node-2@vyos:~$ show ip ospf neighbor
+
+Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
+10.1.1.1 1 Full/Backup 3m47s 31.736s 192.168.0.1 eth0:192.168.0.2 0 0 0
+```
+
+Here's the routes:
+
+```none
+Node-1@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O 10.1.1.1/32 [110/0] is directly connected, lo, weight 1, 00:00:14
+O>* 10.1.1.2/32 [110/1] via 192.168.0.2, eth0, weight 1, 00:00:07
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:32
+
+Node-2@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O>* 10.1.1.1/32 [110/1] via 192.168.0.1, eth0, weight 1, 00:00:11
+O 10.1.1.2/32 [110/0] is directly connected, lo, weight 1, 00:00:04
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:18
+```
+
+### Enable OSPF with route redistribution of the loopback and default originate:
+
+**Node 1**
+
+```none
+set interfaces loopback lo address 10.1.1.1/32
+set protocols ospf area 0 network 192.168.0.0/24
+set protocols ospf default-information originate always
+set protocols ospf default-information originate metric 10
+set protocols ospf default-information originate metric-type 2
+set protocols ospf log-adjacency-changes
+set protocols ospf parameters router-id 10.1.1.1
+set protocols ospf redistribute connected metric-type 2
+set protocols ospf redistribute connected route-map CONNECT
+
+set policy route-map CONNECT rule 10 action permit
+set policy route-map CONNECT rule 10 match interface lo
+```
+
+**Node 2**
+
+```none
+set interfaces loopback lo address 10.2.2.2/32
+set protocols ospf area 0 network 192.168.0.0/24
+set protocols ospf log-adjacency-changes
+set protocols ospf parameters router-id 10.2.2.2
+set protocols ospf redistribute connected metric-type 2
+set protocols ospf redistribute connected route-map CONNECT
+
+set policy route-map CONNECT rule 10 action permit
+set policy route-map CONNECT rule 10 match interface lo
+```
+
+### Enable OSPF and IGP-LDP synchronization:
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address 10.1.1.1/32
+set interfaces ethernet eth0 address 192.168.0.1/24
+
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '10.1.1.1/32'
+set protocols ospf parameters router-id '10.1.1.1'
+set protocols ospf ldp-sync
+
+set protocols mpls interface eth0
+set protocols mpls ldp discovery transport-ipv4-address 10.1.1.1
+set protocols mpls ldp interface lo
+set protocols mpls ldp interface eth0
+set protocols mpls ldp parameters transport-prefer-ipv4
+set protocols mpls ldp router-id 10.1.1.1
+```
+
+This gives us IGP-LDP synchronization for all non-loopback interfaces with
+a holddown timer of zero seconds:
+
+```none
+Node-1@vyos:~$ show ip ospf mpls ldp-sync
+ eth0
+ LDP-IGP Synchronization enabled: yes
+ Holddown timer in seconds: 0
+ State: Sync achieved
+```
+
+### Enable OSPF with Segment Routing (Experimental):
+
+**Node 1**
+
+```none
+set interfaces loopback lo address 10.1.1.1/32
+set interfaces ethernet eth0 address 192.168.0.1/24
+
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '10.1.1.1/32'
+set protocols ospf parameters opaque-lsa
+set protocols ospf parameters router-id '10.1.1.1'
+set protocols ospf segment-routing global-block high-label-value '1100'
+set protocols ospf segment-routing global-block low-label-value '1000'
+set protocols ospf segment-routing prefix 10.1.1.1/32 index explicit-null
+set protocols ospf segment-routing prefix 10.1.1.1/32 index value '1'
+```
+
+**Node 2**
+
+```none
+set interfaces loopback lo address 10.1.1.2/32
+set interfaces ethernet eth0 address 192.168.0.2/24
+
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '10.1.1.2/32'
+set protocols ospf parameters opaque-lsa
+set protocols ospf parameters router-id '10.1.1.2'
+set protocols ospf segment-routing global-block high-label-value '1100'
+set protocols ospf segment-routing global-block low-label-value '1000'
+set protocols ospf segment-routing prefix 10.1.1.2/32 index explicit-null
+set protocols ospf segment-routing prefix 10.1.1.2/32 index value '2'
+```
+
+This gives us MPLS segment routing enabled and labels for far end loopbacks:
+
+```none
+Node-1@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------------------
+ 1002 SR (OSPF) 192.168.0.2 IPv4 Explicit Null <-- Node-2 loopback learned on Node-1
+ 15000 SR (OSPF) 192.168.0.2 implicit-null
+ 15001 SR (OSPF) 192.168.0.2 implicit-null
+
+Node-2@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------------------
+ 1001 SR (OSPF) 192.168.0.1 IPv4 Explicit Null <-- Node-1 loopback learned on Node-2
+ 15000 SR (OSPF) 192.168.0.1 implicit-null
+ 15001 SR (OSPF) 192.168.0.1 implicit-null
+```
+
+Here is the routing tables showing the MPLS segment routing label operations:
+
+```none
+Node-1@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O 10.1.1.1/32 [110/0] is directly connected, lo, weight 1, 00:03:43
+O>* 10.1.1.2/32 [110/1] via 192.168.0.2, eth0, label IPv4 Explicit Null, weight 1, 00:03:32
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:43
+
+Node-2@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O>* 10.1.1.1/32 [110/1] via 192.168.0.1, eth0, label IPv4 Explicit Null, weight 1, 00:03:36
+O 10.1.1.2/32 [110/0] is directly connected, lo, weight 1, 00:03:51
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:51
+```
+
+(routing-ospfv3)=
+
+## OSPFv3 (IPv6)
+
+(ospf-v3-configuration)=
+
+### Configuration
+
+(ospf-v3-general)=
+
+#### General
+
+VyOS does not have a special command to start the OSPFv3 process. The OSPFv3
+process starts when the first ospf enabled interface is configured.
+
+```{cfgcmd} set protocols ospfv3 interface \<interface\> area \<number\>
+
+ This command specifies the OSPFv3 enabled interface. This command is also
+ used to enable the OSPF process. The area number can be specified in
+ decimal notation in the range from 0 to 4294967295. Or it can be specified
+ in dotted decimal notation similar to ip address.
+```
+
+
+```{cfgcmd} set protocols ospfv3 parameters router-id \<rid\>
+
+This command sets the router-ID of the OSPFv3 process. The router-ID may be
+an IP address of the router, but need not be – it can be any arbitrary
+32bit number. However it MUST be unique within the entire OSPFv3 domain to
+the OSPFv3 speaker – bad things will happen if multiple OSPFv3 speakers are
+configured with the same router-ID!
+```
+
+(ospf-v3-optional)=
+
+#### Optional
+
+```{cfgcmd} set protocols ospfv3 distance global \<distance\>
+
+This command change distance value of OSPFv3 globally.
+The distance range is 1 to 255.
+```
+```{cfgcmd} set protocols ospfv3 distance ospfv3 \<external|inter-area|intra-area\> \<distance\>
+
+This command change distance value of OSPFv3. The arguments are the
+distance values for external routes, inter-area routes and intra-area
+routes respectively. The distance range is 1 to 255.
+```
+
+(ospf-v3-area-configuration)=
+
+#### Area Configuration
+
+```{cfgcmd} set protocols ospfv3 area \<number\> range \<prefix\>
+
+This command summarizes intra area paths from specified area into one
+Type-3 Inter-Area Prefix LSA announced to other areas. This command can be
+used only in ABR.
+```
+```{cfgcmd} set protocols ospfv3 area \<number\> range \<prefix\> not-advertise
+
+This command instead of summarizing intra area paths filter them - i.e.
+intra area paths from this range are not advertised into other areas. This
+command makes sense in ABR only.
+```
+
+(ospf-v3-interface-config)=
+
+#### Interface Configuration
+
+```{cfgcmd} set protocols ospfv3 interface \<interface\> ipv6 cost \<number\>
+
+This command sets link cost for the specified interface. The cost value is
+set to router-LSA’s metric field and used for SPF calculation. The cost
+range is 1 to 65535.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> dead-interval \<number\>
+
+Set number of seconds for router Dead Interval timer value used for Wait
+Timer and Inactivity Timer. This value must be the same for all routers
+attached to a common network. The default value is 40 seconds. The
+interval range is 1 to 65535.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> hello-interval \<number\>
+
+Set number of seconds for Hello Interval timer value. Setting this value,
+Hello packet will be sent every timer value seconds on the specified
+interface. This value must be the same for all routers attached to a
+common network. The default value is 10 seconds. The interval range is 1
+to 65535.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> mtu-ignore
+
+This command disables check of the MTU value in the OSPF DBD packets.
+Thus, use of this command allows the OSPF adjacency to reach the FULL
+state even though there is an interface MTU mismatch between two OSPF
+routers.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> network \<type\>
+
+This command allows to specify the distribution type for the network
+connected to this interface:
+
+**broadcast** – broadcast IP addresses distribution.
+**point-to-point** – address distribution in point-to-point networks.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> priority \<number\>
+
+This command sets Router Priority integer value. The router with the
+highest priority will be more eligible to become Designated Router.
+Setting the value to 0, makes the router ineligible to become Designated
+Router. The default value is 1. The interval range is 0 to 255.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> passive
+
+This command specifies interface as passive. Passive interface advertises
+its address, but does not run the OSPF protocol (adjacencies are not formed
+and hello packets are not generated).
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> retransmit-interval \<number\>
+
+This command sets number of seconds for RxmtInterval timer value. This
+value is used when retransmitting Database Description and Link State
+Request packets if acknowledge was not received. The default value is 5
+seconds. The interval range is 3 to 65535.
+```
+```{cfgcmd} set protocols ospfv3 interface \<interface\> transmit-delay \<number\>
+
+This command sets number of seconds for InfTransDelay value. It allows to
+set and adjust for each interface the delay interval before starting the
+synchronizing process of the router's database with all neighbors. The
+default value is 1 seconds. The interval range is 3 to 65535.
+```
+
+(ospf-v3-graceful-restart)=
+
+#### Graceful Restart
+
+```{cfgcmd} set protocols ospfv3 graceful-restart [grace-period (1-1800)]
+
+Configure Graceful Restart {rfc}`3623` restarting support. When enabled,
+the default grace period is 120 seconds.
+
+To perform a graceful shutdown, the FRR ``graceful-restart prepare ip
+ospf`` EXEC-level command needs to be issued before restarting the
+ospfd daemon.
+```
+```{cfgcmd} set protocols ospfv3 graceful-restart helper enable [router-id A.B.C.D]
+
+Configure Graceful Restart {rfc}`3623` helper support. By default, helper support
+is disabled for all neighbours. This config enables/disables helper support
+on this router for all neighbours.
+
+To enable/disable helper support for a specific neighbour, the router-id
+(A.B.C.D) has to be specified.
+```
+```{cfgcmd} set protocols ospfv3 graceful-restart helper lsa-check-disable
+
+By default strict-lsa-checking is configured then the helper will abort
+the Graceful Restart when a LSA change occurs which affects the restarting
+router.
+
+This command disables it.
+```
+```{cfgcmd} set protocols ospfv3 graceful-restart helper supported-grace-time
+
+Supports as HELPER for configured grace period.
+```
+```{cfgcmd} set protocols ospfv3 graceful-restart helper planned-only
+
+It helps to support as HELPER only for planned restarts.
+By default, it supports both planned and unplanned outages.
+```
+
+(ospf-v3-redistribution-config)=
+
+#### Redistribution Configuration
+
+```{cfgcmd} set protocols ospfv3 redistribute \<route source\>
+
+This command redistributes routing information from the given route source
+to the OSPFv3 process. There are five modes available for route source:
+bgp, connected, kernel, ripng, static.
+```
+```{cfgcmd} set protocols ospf redistribute \<route source\> route-map \<name\>
+
+This command allows to use route map to filter redistributed routes from
+given route source. There are five modes available for route source: bgp,
+connected, kernel, ripng, static.
+```
+
+(ospf-v3-op-cmd)=
+
+#### Operational Mode Commands
+
+```{opcmd} show ipv6 ospfv3 neighbor
+
+This command displays the neighbors status.
+```
+```{opcmd} show ipv6 ospfv3 neighbor detail
+
+This command displays the neighbors information in a detailed form, not
+just a summary table.
+```
+```{opcmd} show ipv6 ospfv3 neighbor drchoice
+
+This command displays the neighbor DR choice information.
+```
+```{opcmd} show ipv6 ospfv3 interface [prefix]|[\<interface\> [prefix]]
+
+This command displays state and configuration of OSPF the specified
+interface, or all interfaces if no interface is given. Whith the argument
+{cfgcmd}`prefix` this command shows connected prefixes to advertise.
+```
+```{opcmd} show ipv6 ospfv3 route
+
+This command displays the OSPF routing table, as determined by the most
+recent SPF calculation.
+```
+```{opcmd} show ipv6 ospfv3 border-routers
+
+This command displays a table of paths to area boundary and autonomous
+system boundary routers.
+```
+```{opcmd} show ipv6 ospfv3 database
+
+This command displays a summary table with a database contents (LSA).
+```
+```{opcmd} show ipv6 ospfv3 database \<type\> [A.B.C.D] [adv-router \<A.B.C.D\>|self-originate]
+
+This command displays a database contents for a specific link
+advertisement type.
+```
+```{opcmd} show ipv6 ospfv3 redistribute
+
+This command displays external information redistributed into OSPFv3
+```
+
+(ospf-v3-config-example)=
+
+#### Configuration Example
+
+A typical configuration using 2 nodes.
+
+**Node 1:**
+
+```none
+set protocols ospfv3 interface eth1 area 0.0.0.0
+set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
+set protocols ospfv3 parameters router-id 192.168.1.1
+set protocols ospfv3 redistribute connected
+```
+
+**Node 2:**
+
+```none
+set protocols ospfv3 interface eth1 area 0.0.0.0
+set protocols ospfv3 area 0.0.0.0 range 2001:db8:2::/64
+set protocols ospfv3 parameters router-id 192.168.2.1
+set protocols ospfv3 redistribute connected
+```
+
+**To see the redistributed routes:**
+
+```none
+show ipv6 ospfv3 redistribute
+```
+
+Cost calculation wireguard interfaces is unreliable as ospfv3 uses the link speed to calculate the link cost.
+You might therefore want to set the link cost to a fixed value on WireGuard tunnels.
+
+Example configuration for WireGuard interfaces:
+
+**Node 1**
+
+```none
+set interfaces wireguard wg01 peer ospf02 allowed-ips '::/0'
+set interfaces wireguard wg01 peer ospf02 endpoint '10.1.1.101:12345'
+set interfaces wireguard wg01 peer ospf02 pubkey 'ie3...='
+set interfaces wireguard wg01 port '12345'
+set protocols ospfv3 parameters router-id 192.168.1.1
+set protocols ospfv3 interface 'wg01' area 0.0.0.0
+set protocols ospfv3 interface 'wg01' cost 10
+set protocols ospfv3 interface 'lo' area 0.0.0.0
+```
+
+**Node 2**
+
+```none
+set interfaces wireguard wg01 peer ospf01 allowed-ips '::/0'
+set interfaces wireguard wg01 peer ospf01 endpoint '10.1.1.100:12345'
+set interfaces wireguard wg01 peer ospf01 pubkey 'NHI...='
+set interfaces wireguard wg01 port '12345'
+set protocols ospfv3 parameters router-id 192.168.1.2
+set protocols ospfv3 interface 'wg01' area 0.0.0.0
+set protocols ospfv3 interface 'wg01' cost 10
+set protocols ospfv3 interface 'lo' area 0.0.0.0
+```
+
+**Status**
+
+```none
+vyos@ospf01:~$ sh ipv6 ospfv3 neighbor
+Neighbor ID Pri DeadTime State/IfState Duration I/F[State]
+192.168.0.2 1 00:00:37 Full/PointToPoint 00:18:03 wg01[PointToPoint]
+
+vyos@ospf02# run sh ipv6 ospfv3 neighbor
+Neighbor ID Pri DeadTime State/IfState Duration I/F[State]
+192.168.0.1 1 00:00:39 Full/PointToPoint 00:19:44 wg01[PointToPoint]
+```
diff --git a/docs/configuration/protocols/pim.md b/docs/configuration/protocols/pim.md
new file mode 100644
index 00000000..db8c9fb7
--- /dev/null
+++ b/docs/configuration/protocols/pim.md
@@ -0,0 +1,282 @@
+---
+lastproofread: '2023-11-13'
+---
+
+(pim)=
+
+# PIM – Protocol Independent Multicast
+
+VyOS supports {abbr}`PIM-SM (PIM Sparse Mode)` as well as
+{abbr}`IGMP (Internet Group Management Protocol)` v2 and v3
+
+{abbr}`PIM (Protocol Independent Multicast)` must be configured in every
+interface of every participating router. Every router must also have the
+location of the Rendevouz Point manually configured. Then, unidirectional
+shared trees rooted at the Rendevouz Point will automatically be built
+for multicast distribution.
+
+Traffic from multicast sources will go to the Rendezvous Point, and
+receivers will pull it from a shared tree using {abbr}`IGMP (Internet
+Group Management Protocol)`.
+
+Multicast receivers will talk IGMP to their local router, so, besides
+having PIM configured in every router, IGMP must also be configured in
+any router where there could be a multicast receiver locally connected.
+
+VyOS supports both IGMP version 2 and version 3 (which allows
+source-specific multicast).
+
+## PIM-SM - PIM Sparse Mode
+
+```{cfgcmd} set protocols pim ecmp
+
+If PIM has the a choice of ECMP nexthops for a particular
+{abbr}`RPF (Reverse Path Forwarding)`, PIM will cause S,G flows to be
+spread out amongst the nexthops. If this command is not specified then
+the first nexthop found will be used.
+```
+
+```{cfgcmd} set protocols pim ecmp rebalance
+
+If PIM is using ECMP and an interface goes down, cause PIM to rebalance all
+S,G flows across the remaining nexthops. If this command is not configured
+PIM only modifies those S,G flows that were using the interface that went
+down.
+```
+
+```{cfgcmd} set protocols pim join-prune-interval \<n\>
+
+Modify the join/prune interval that PIM uses to the new value. Time is
+specified in seconds.
+
+The default time is 60 seconds.
+
+If you enter a value smaller than 60 seconds be aware that this can and
+will affect convergence at scale.
+```
+
+```{cfgcmd} set protocols pim keep-alive-timer \<n\>
+
+Modify the time out value for a S,G flow from 1-65535 seconds. If choosing
+a value below 31 seconds be aware that some hardware platforms cannot see
+data flowing in better than 30 second chunks.
+```
+
+```{cfgcmd} set protocols pim packets \<n\>
+
+When processing packets from a neighbor process the number of packets
+incoming at one time before moving on to the next task.
+
+The default value is 3 packets.
+
+This command is only useful at scale when you can possibly have a large
+number of PIM control packets flowing.
+```
+
+```{cfgcmd} set protocols pim register-accept-list \<prefix-list\>
+
+When PIM receives a register packet the source of the packet will be compared
+to the prefix-list specified, and if a permit is received normal processing
+continues. If a deny is returned for the source address of the register packet
+a register stop message is sent to the source.
+```
+
+```{cfgcmd} set protocols pim register-suppress-time \<n\>
+
+Modify the time that pim will register suppress a FHR will send register
+notifications to the kernel.
+```
+
+```{cfgcmd} set protocols pim rp \<address\> group \<group\>
+
+In order to use PIM, it is necessary to configure a {abbr}`RP (Rendezvous Point)`
+for join messages to be sent to. Currently the only methodology to do this is
+via static rendezvous point commands.
+
+All routers in the PIM network must agree on these values.
+
+The first ip address is the RP's address and the second value is the matching
+prefix of group ranges covered.
+```
+
+```{cfgcmd} set protocols pim rp keep-alive-timer \<n\>
+
+Modify the time out value for a S,G flow from 1-65535 seconds at
+{abbr}`RP (Rendezvous Point)`. The normal keepalive period for the KAT(S,G)
+defaults to 210 seconds. However, at the {abbr}`RP (Rendezvous Point)`, the
+keepalive period must be at least the Register_Suppression_Time, or the RP
+may time out the (S,G) state before the next Null-Register arrives.
+Thus, the KAT(S,G) is set to max(Keepalive_Period, RP_Keepalive_Period)
+when a Register-Stop is sent.
+
+If choosing a value below 31 seconds be aware that some hardware platforms
+cannot see data flowing in better than 30 second chunks.
+
+See {rfc}`7761#section-4.1` for details.
+```
+
+```{cfgcmd} set protocols pim no-v6-secondary
+
+When sending PIM hello packets tell PIM to not send any v6 secondary
+addresses on the interface. This information is used to allow PIM to use v6
+nexthops in it's decision for {abbr}`RPF (Reverse Path Forwarding)` lookup
+if this option is not set (default).
+```
+
+```{cfgcmd} set protocols pim spt-switchover infinity-and-beyond [prefix-list \<list\>]
+
+On the last hop router if it is desired to not switch over to the SPT tree
+configure this command.
+
+Optional parameter prefix-list can be use to control which groups to switch or
+not switch. If a group is PERMIT as per the prefix-list, then the SPT switchover
+does not happen for it and if it is DENY, then the SPT switchover happens.
+```
+
+```{cfgcmd} set protocols pim ssm prefix-list \<list\>
+
+Specify a range of group addresses via a prefix-list that forces PIM to never
+do {abbr}`SSM (Source-Specific Multicast)` over.
+```
+
+
+### Interface specific commands
+
+```{cfgcmd} set protocols pim interface \<interface\> bfd [profile \<name\>]
+
+Automatically create BFD session for each RIP peer discovered in this
+interface. When the BFD session monitor signalize that the link is down
+the RIP peer is removed and all the learned routes associated with that
+peer are removed.
+
+If optional profile parameter is used, select a BFD profile for the BFD
+sessions created via this interface.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> dr-priority \<n\>
+
+Set the {abbr}`DR (Designated Router)` Priority for the interface.
+This command is useful to allow the user to influence what node becomes
+the DR for a LAN segment.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> hello \<n\>
+
+Set the PIM hello and hold interval for a interface.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> no-bsm
+
+Tell PIM that we would not like to use this interface to process
+bootstrap messages.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> no-unicast-bsm
+
+Tell PIM that we would not like to use this interface to process
+unicast bootstrap messages.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> passive
+
+Disable sending and receiving PIM control packets on the interface.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> source-address \<ip-address\>
+
+If you have multiple addresses configured on a particular interface and would
+like PIM to use a specific source address associated with that interface.
+```
+
+
+## IGMP - Internet Group Management Protocol)
+
+```{cfgcmd} set protocols pim igmp watermark-warning \<n\>
+
+Configure watermark warning generation for an IGMP group limit. Generates
+warning once the configured group limit is reached while adding new groups.
+```
+
+(pim-igmp-interface-commands)=
+
+### Interface specific commands
+
+```{cfgcmd} set protocols pim interface \<interface\> igmp join \<multicast-address\> source-address \<IP-address\>
+
+Use this command to allow the selected interface to join a multicast
+group defining the multicast address you want to join and the source
+IP address too.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> igmp query-interval \<seconds\>
+
+Use this command to configure in the selected interface the IGMP
+host query interval (1-1800) in seconds that PIM will use.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> igmp query-max-response-time \<n\>
+
+Use this command to configure in the selected interface the IGMP
+query response timeout value (10-250) in deciseconds. If a report is
+not returned in the specified time, it will be assumed the (S,G) or
+(\*,G) state {rfc}`7761#section-4.1` has timed out.
+```
+
+```{cfgcmd} set protocols pim interface \<interface\> igmp version \<version-number\>
+
+Use this command to define in the selected interface whether you
+choose IGMP version 2 or 3.
+
+The default value is 3.
+```
+
+
+#### Example
+
+In the following example we can see a basic multicast setup:
+
+```{image} /_static/images/multicast-basic.webp
+:align: center
+:alt: Network Topology Diagram
+:width: 90%
+```
+
+**Router 1**
+
+```none
+set interfaces ethernet eth2 address '172.16.0.2/24'
+set interfaces ethernet eth1 address '100.64.0.1/24'
+set protocols ospf area 0 network '172.16.0.0/24'
+set protocols ospf area 0 network '100.64.0.0/24'
+set protocols igmp interface eth1
+set protocols pim interface eth1
+set protocols pim interface eth2
+set protocols pim rp address 172.16.255.1 group '224.0.0.0/4'
+```
+
+**Router 3**
+
+```none
+set interfaces dummy dum0 address '172.16.255.1/24'
+set interfaces ethernet eth0 address '172.16.0.1/24'
+set interfaces ethernet eth1 address '172.16.1.1/24'
+set protocols ospf area 0 network '172.16.0.0/24'
+set protocols ospf area 0 network '172.16.255.0/24'
+set protocols ospf area 0 network '172.16.1.0/24'
+set protocols pim interface dum0
+set protocols pim interface eth0
+set protocols pim interface eth1
+set protocols pim rp address 172.16.255.1 group '224.0.0.0/4'
+```
+
+**Router 2**
+
+```none
+set interfaces ethernet eth1 address '10.0.0.1/24'
+set interfaces ethernet eth2 address '172.16.1.2/24'
+set protocols ospf area 0 network '10.0.0.0/24'
+set protocols ospf area 0 network '172.16.1.0/24'
+set protocols pim interface eth1
+set protocols pim interface eth2
+set protocols pim rp address 172.16.255.1 group '224.0.0.0/4'
+```
diff --git a/docs/configuration/protocols/pim6.md b/docs/configuration/protocols/pim6.md
new file mode 100644
index 00000000..707ae606
--- /dev/null
+++ b/docs/configuration/protocols/pim6.md
@@ -0,0 +1,100 @@
+(pim6)=
+
+# PIM6 - Protocol Independent Multicast for IPv6
+
+VyOS facilitates IPv6 Multicast by supporting **PIMv6** and **MLD**.
+
+PIMv6 (Protocol Independent Multicast for IPv6) must be configured in every
+interface of every participating router. Every router must also have the
+location of the Rendevouz Point manually configured.
+Then, unidirectional shared trees rooted at the Rendevouz Point will
+automatically be built for multicast distribution.
+
+Traffic from multicast sources will go to the Rendezvous Point, and receivers
+will pull it from a shared tree using MLD (Multicast Listener Discovery).
+
+Multicast receivers will talk MLD to their local router, so, besides having
+PIMv6 configured in every router, MLD must also be configured in any router
+where there could be a multicast receiver locally connected.
+
+VyOS supports both MLD version 1 and version 2
+(which allows source-specific multicast).
+
+## Basic commands
+
+These are the commands for a basic setup.
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\>
+
+ Use this command to enable PIMv6 in the selected interface so that it
+ can communicate with PIMv6 neighbors. This command also enables MLD reports
+ and query on the interface unless {cfgcmd}`mld disable` is configured.
+```
+
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld disable
+
+Disable MLD reports and query on the interface.
+```
+
+
+## Tuning commands
+
+You can also tune multicast with the following commands.
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld interval \<seconds\>
+
+Use this command to configure in the selected interface the MLD
+host query interval (1-65535) in seconds that PIM will use.
+The default value is 125 seconds.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld join \<multicast-address\>
+
+Use this command to allow the selected interface to join a multicast group.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld join \<multicast-address\> source \<source-address\>
+
+Use this command to allow the selected interface to join a source-specific multicast
+group.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld last-member-query-count \<count\>
+
+Set the MLD last member query count. The default value is 2.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld last-member-query-interval \<milliseconds\>
+
+Set the MLD last member query interval in milliseconds (100-6553500). The default value is 1000 milliseconds.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld max-response-time \<milliseconds\>
+
+Set the MLD query response timeout in milliseconds (100-6553500). The default value is 10000 milliseconds.
+```
+
+```{cfgcmd} set protocols pim6 interface \<interface-name\> mld version \<version-number\>
+
+Set the MLD version used on this interface. The default value is 2.
+```
+
+
+### Configuration Example
+
+To enable MLD reports and query on interfaces `eth0` and `eth1`:
+
+```none
+set protocols pim6 interface eth0
+set protocols pim6 interface eth1
+```
+
+The following configuration explicitly joins multicast group `ff15::1234` on interface `eth1`
+and source-specific multicast group `ff15::5678` with source address `2001:db8::1` on interface
+`eth1`:
+
+```none
+set protocols pim6 interface eth0 mld join ff15::1234
+set protocols pim6 interface eth1 mld join ff15::5678 source 2001:db8::1
+```
diff --git a/docs/configuration/protocols/rip.md b/docs/configuration/protocols/rip.md
new file mode 100644
index 00000000..684337d6
--- /dev/null
+++ b/docs/configuration/protocols/rip.md
@@ -0,0 +1,294 @@
+---
+lastproofread: '2021-10-04'
+---
+
+(rip)=
+
+# RIP
+
+{abbr}`RIP (Routing Information Protocol)` is a widely deployed interior gateway
+protocol. RIP was developed in the 1970s at Xerox Labs as part of the XNS
+routing protocol. RIP is a distance-vector protocol and is based on the
+Bellman-Ford algorithms. As a distance-vector protocol, RIP router send updates
+to its neighbors periodically, thus allowing the convergence to a known
+topology. In each update, the distance to any given network will be broadcast
+to its neighboring router.
+
+Supported versions of RIP are:
+
+> - RIPv1 as described in {rfc}`1058`
+> - RIPv2 as described in {rfc}`2453`
+
+## General Configuration
+
+```{cfgcmd} set protocols rip network \<A.B.C.D/M\>
+
+This command enables RIP and sets the RIP enable interface by NETWORK.
+The interfaces which have addresses matching with NETWORK are enabled.
+```
+
+
+```{cfgcmd} set protocols rip interface \<interface\>
+
+This command specifies a RIP enabled interface by interface name. Both
+the sending and receiving of RIP packets will be enabled on the port
+specified in this command.
+```
+
+
+```{cfgcmd} set protocols rip neighbor \<A.B.C.D\>
+
+This command specifies a RIP neighbor. When a neighbor doesn’t understand
+multicast, this command is used to specify neighbors. In some cases, not
+all routers will be able to understand multicasting, where packets are
+sent to a network or a group of addresses. In a situation where a neighbor
+cannot process multicast packets, it is necessary to establish a direct
+link between routers.
+```
+
+
+```{cfgcmd} set protocols rip passive-interface interface \<interface\>
+
+This command sets the specified interface to passive mode. On passive mode
+interface, all receiving packets are processed as normal and VyOS does not
+send either multicast or unicast RIP packets except to RIP neighbors
+specified with neighbor command.
+```
+
+
+```{cfgcmd} set protocols rip passive-interface interface default
+
+This command specifies all interfaces to passive mode.
+```
+
+## Optional Configuration
+
+```{cfgcmd} set protocols rip default-distance \<distance\>
+
+This command change the distance value of RIP. The distance range is 1 to 255.
+
+> :::{note}
+> Routes with a distance of 255 are effectively disabled and not
+> installed into the kernel.
+> :::
+```
+
+
+```{cfgcmd} set protocols rip network-distance \<A.B.C.D/M\> distance \<distance\>
+
+This command sets default RIP distance to a specified value when the routes
+source IP address matches the specified prefix.
+```
+
+
+```{cfgcmd} set protocols rip network-distance \<A.B.C.D/M\> access-list \<name\>
+
+This command can be used with previous command to sets default RIP distance
+to specified value when the route source IP address matches the specified
+prefix and the specified access-list.
+```
+
+
+```{cfgcmd} set protocols rip default-information originate
+
+This command generate a default route into the RIP.
+```
+
+
+```{cfgcmd} set protocols rip distribute-list access-list \<in|out\> \<number\>
+
+This command can be used to filter the RIP path using access lists.
+{cfgcmd}`in` and {cfgcmd}`out` this is the direction in which the access
+lists are applied.
+```
+
+
+```{cfgcmd} set protocols rip distribute-list interface \<interface\> access-list \<in|out\> \<number\>
+
+This command allows you apply access lists to a chosen interface to
+filter the RIP path.
+```
+
+
+```{cfgcmd} set protocols rip distribute-list prefix-list \<in|out\> \<name\>
+
+This command can be used to filter the RIP path using prefix lists.
+{cfgcmd}`in` and {cfgcmd}`out` this is the direction in which the prefix
+lists are applied.
+```
+
+
+```{cfgcmd} set protocols rip distribute-list interface \<interface\> prefix-list \<in|out\> \<name\>
+
+This command allows you apply prefix lists to a chosen interface to
+filter the RIP path.
+```
+
+
+```{cfgcmd} set protocols rip route \<A.B.C.D/M\>
+
+This command is specific to FRR and VyOS. The route command makes a static
+route only inside RIP. This command should be used only by advanced users
+who are particularly knowledgeable about the RIP protocol. In most cases,
+we recommend creating a static route in VyOS and redistributing it in RIP
+using {cfgcmd}`redistribute static`.
+```
+
+
+```{cfgcmd} set protocols rip timers update \<seconds\>
+
+This command specifies the update timer. Every update timer seconds, the
+RIP process is awakened to send an unsolicited response message containing
+the complete routing table to all neighboring RIP routers. The time range
+is 5 to 2147483647. The default value is 30 seconds.
+```
+
+
+```{cfgcmd} set protocols rip timers timeout \<seconds\>
+
+This command specifies the timeout timer. Upon expiration of the timeout,
+the route is no longer valid; however, it is retained in the routing table
+for a short time so that neighbors can be notified that the route has been
+dropped. The time range is 5 to 2147483647. The default value is 180
+seconds.
+```
+
+
+```{cfgcmd} set protocols rip timers garbage-collection \<seconds\>
+
+This command specifies the garbage-collection timer. Upon expiration of
+the garbage-collection timer, the route is finally removed from the
+routing table. The time range is 5 to 2147483647. The default value is 120
+seconds.
+```
+
+## Redistribution Configuration
+
+```{cfgcmd} set protocols rip redistribute \<route source\>
+
+This command redistributes routing information from the given route source
+into the RIP tables. There are five modes available for route source: bgp,
+connected, kernel, ospf, static.
+```
+
+
+```{cfgcmd} set protocols rip redistribute \<route source\> metric \<metric\>
+
+This command specifies metric for redistributed routes from the given route
+source. There are five modes available for route source: bgp, connected,
+kernel, ospf, static. The metric range is 1 to 16.
+```
+
+
+```{cfgcmd} set protocols rip redistribute \<route source\> route-map \<name\>
+
+This command allows to use route map to filter redistributed routes from
+the given route source. There are five modes available for route source:
+bgp, connected, kernel, ospf, static.
+```
+
+
+```{cfgcmd} set protocols rip default-metric \<metric\>
+
+This command modifies the default metric (hop count) value for redistributed
+routes. The metric range is 1 to 16. The default value is 1. This command
+does not affect connected route even if it is redistributed by
+{cfgcmd}`redistribute connected`. To modify connected routes metric
+value, please use {cfgcmd}`redistribute connected metric`.
+```
+
+## Interfaces Configuration
+
+```{cfgcmd} set interfaces \<inttype\> \<intname\> ip rip authentication plaintext-password \<text\>
+
+This command sets the interface with RIP simple password authentication.
+This command also sets authentication string. The string must be shorter
+than 16 characters.
+```
+
+
+```{cfgcmd} set interfaces \<inttype\> \<intname\> ip rip authentication md5 \<id\> password \<text\>
+
+This command sets the interface with RIP MD5 authentication. This command
+also sets MD5 Key. The key must be shorter than 16 characters.
+```
+
+
+```{cfgcmd} set interfaces \<inttype\> \<intname\> ip rip split-horizon disable
+
+This command disables split-horizon on the interface. By default, VyOS does
+not advertise RIP routes out the interface over which they were learned
+(split horizon).3
+```
+
+
+```{cfgcmd} set interfaces \<inttype\> \<intname\> ip rip split-horizon poison-reverse
+
+This command enables poison-reverse on the interface. If both poison reverse
+and split horizon are enabled, then VyOS advertises the learned routes
+as unreachable over the interface on which the route was learned.
+```
+
+## Operational Mode Commands
+
+```{opcmd} show ip rip
+
+This command displays RIP routes.
+```
+```none
+Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
+Sub-codes:
+ (n) - normal, (s) - static, (d) - default, (r) - redistribute,
+ (i) - interface
+
+ Network Next Hop Metric From Tag Time
+C(i) 10.0.12.0/24 0.0.0.0 1 self 0
+C(i) 10.0.13.0/24 0.0.0.0 1 self 0
+R(n) 10.0.23.0/24 10.0.12.2 2 10.0.12.2 0 02:53
+```
+
+```{opcmd} show ip rip status
+
+The command displays current RIP status. It includes RIP timer, filtering,
+version, RIP enabled interface and RIP peer information.
+```
+```none
+Routing Protocol is "rip"
+ Sending updates every 30 seconds with +/-50%, next due in 11 seconds
+ Timeout after 180 seconds, garbage collect after 120 seconds
+ Outgoing update filter list for all interface is not set
+ Incoming update filter list for all interface is not set
+ Default redistribution metric is 1
+ Redistributing:
+ Default version control: send version 2, receive any version
+ Interface Send Recv Key-chain
+ eth0 2 1 2
+ eth2 2 1 2
+ Routing for Networks:
+ 10.0.12.0/24
+ eth0
+ Routing Information Sources:
+ Gateway BadPackets BadRoutes Distance Last Update
+ 10.0.12.2 0 0 120 00:00:11
+ Distance: (default is 120)
+```
+
+## Configuration Example
+
+Simple RIP configuration using 2 nodes and redistributing connected interfaces.
+
+**Node 1:**
+
+```none
+set interfaces loopback address 10.1.1.1/32
+set protocols rip network 192.168.0.0/24
+set protocols rip redistribute connected
+```
+
+**Node 2:**
+
+```none
+set interfaces loopback address 10.2.2.2/32
+set protocols rip network 192.168.0.0/24
+set protocols rip redistribute connected
+```
diff --git a/docs/configuration/protocols/rpki.md b/docs/configuration/protocols/rpki.md
new file mode 100644
index 00000000..1f4cf5bf
--- /dev/null
+++ b/docs/configuration/protocols/rpki.md
@@ -0,0 +1,210 @@
+(rpki)=
+
+# RPKI
+
+:::{pull-quote}
+
+There are two types of Network Admins who deal with BGP, those who have
+created an international incident and/or outage, and those who are lying
+
+-- [tweet by EvilMog](https://twitter.com/Evil_Mog/status/1230924170508169216), 2020-02-21
+:::
+
+{abbr}`RPKI (Resource Public Key Infrastructure)` is a framework designed to
+secure the Internet routing infrastructure. It associates BGP route
+announcements with the correct originating {abbr}`ASN (Autonomus System
+Number)` which BGP routers can then use to check each route against the
+corresponding {abbr}`ROA (Route Origin Authorisation)` for validity. RPKI is
+described in {rfc}`6480`.
+
+A BGP-speaking router like VyOS can retrieve ROA information from RPKI
+"Relying Party software" (often just called an "RPKI server" or "RPKI
+validator") by using {abbr}`RTR (RPKI to Router)` protocol. There are several
+open source implementations to choose from, such as NLNetLabs' [Routinator]
+(written in Rust), OpenBSD's [rpki-client] (written in C), and [StayRTR] (written
+in Go). The RTR protocol is described in {rfc}`8210`.
+
+:::{tip}
+If you are new to these routing security technologies then there is an
+[excellent guide to RPKI] by NLnet Labs which will get you up to speed
+very quickly. Their documentation explains everything from what RPKI is to
+deploying it in production. It also has some
+[help and operational guidance] including "What can I do about my route
+having an Invalid state?"
+:::
+
+## Getting started
+
+First you will need to deploy an RPKI validator for your routers to use. NLnet
+Labs provides a collection of [software] you can compare and settle on one.
+Once your server is running you can start validating announcements.
+
+Imported prefixes during the validation may have values:
+
+> valid
+>
+> : The prefix and ASN that originated it match a signed ROA. These are
+> probably trustworthy route announcements.
+>
+> invalid
+>
+> : The prefix or prefix length and ASN that originated it doesn't
+> match any existing ROA. This could be the result of a prefix hijack, or
+> merely a misconfiguration, but should probably be treated as
+> untrustworthy route announcements.
+>
+> notfound
+>
+> : No ROA exists which covers that prefix. Unfortunately this is the case for
+> about 40%-50% of the prefixes which were announced to the {abbr}`DFZ
+> (default-free zone)` at the start of 2024.
+
+:::{note}
+If you are responsible for the global addresses assigned to your
+network, please make sure that your prefixes have ROAs associated with them
+to avoid being `notfound` by RPKI. For most ASNs this will involve
+publishing ROAs via your {abbr}`RIR (Regional Internet Registry)` (RIPE
+NCC, APNIC, ARIN, LACNIC, or AFRINIC), and is something you are encouraged
+to do whenever you plan to announce addresses into the DFZ.
+
+Particularly large networks may wish to run their own RPKI certificate
+authority and publication server instead of publishing ROAs via their RIR.
+This is a subject far beyond the scope of VyOS' documentation. Consider
+reading about [Krill] if this is a rabbit hole you need or especially want
+to dive down.
+:::
+
+### Features of the Current Implementation
+
+In a nutshell, the current implementation provides the following features:
+
+- The BGP router can connect to one or more RPKI cache servers to receive
+ validated prefix to origin AS mappings. Advanced failover can be implemented
+ by server sockets with different preference values.
+- If no connection to an RPKI cache server can be established after a
+ pre-defined timeout, the router will process routes without prefix origin
+ validation. It still will try to establish a connection to an RPKI cache
+ server in the background.
+- By default, enabling RPKI does not change best path selection. In particular,
+ invalid prefixes will still be considered during best path selection. However,
+ the router can be configured to ignore all invalid prefixes.
+- Route maps can be configured to match a specific RPKI validation state. This
+ allows the creation of local policies, which handle BGP routes based on the
+ outcome of the Prefix Origin Validation.
+- Updates from the RPKI cache servers are directly applied and path selection is
+ updated accordingly. (Soft reconfiguration must be enabled for this to work).
+
+## Configuration
+
+```{cfgcmd} set protocols rpki polling-period \<1-86400\>
+
+Define the time interval to update the local cache
+
+The default value is 300 seconds.
+```
+
+```{cfgcmd} set protocols rpki expire-interval \<600-172800\>
+
+Set the number of seconds the router waits until the router
+expires the cache.
+
+The default value is 7200 seconds.
+```
+
+```{cfgcmd} set protocols rpki retry-interval \<1-7200\>
+
+Set the number of seconds the router waits until retrying to connect
+to the cache server.
+
+The default value is 600 seconds.
+```
+
+```{cfgcmd} set protocols rpki cache \<address\> port \<port\>
+
+Defined the IPv4, IPv6 or FQDN and port number of the caching RPKI caching
+instance which is used.
+
+This is a mandatory setting.
+```
+
+```{cfgcmd} set protocols rpki cache \<address\> preference \<preference\>
+
+Multiple RPKI caching instances can be supplied and they need a preference in
+which their result sets are used.
+
+This is a mandatory setting.
+```
+
+
+### SSH
+
+Connections to the RPKI caching server can not only be established by TCP using
+the RTR protocol but you can also rely on a secure SSH session to the server.
+This provides transport integrity and confidentiality and it is a good idea if
+your validation software supports it. To enable SSH, first you need to create
+an SSH client keypair using `generate ssh client-key
+/config/auth/id_rsa_rpki`. Once your key is created you can setup the
+connection.
+
+```{cfgcmd} set protocols rpki cache \<address\> ssh username \<user\>
+
+SSH username to establish an SSH connection to the cache server.
+```
+
+```{cfgcmd} set protocols rpki cache \<address\> ssh private-key-file \<filepath\>
+
+Local path that includes the private key file of the router.
+```
+
+```{cfgcmd} set protocols rpki cache \<address\> ssh public-key-file \<filepath\>
+
+Local path that includes the public key file of the router.
+```
+
+:::{note}
+When using SSH, private-key-file and public-key-file
+are mandatory options.
+:::
+
+## Example
+
+We can build route-maps for import based on these states. Here is a simple
+RPKI configuration, where `routinator` is the RPKI-validating "cache"
+server with ip `192.0.2.1`:
+
+```none
+set protocols rpki cache 192.0.2.1 port '3323'
+set protocols rpki cache 192.0.2.1 preference '1'
+```
+
+Here is an example route-map to apply to routes learned at import. In this
+filter we reject prefixes with the state `invalid`, and set a higher
+`local-preference` if the prefix is RPKI `valid` rather than merely
+`notfound`.
+
+```none
+set policy route-map ROUTES-IN rule 10 action 'permit'
+set policy route-map ROUTES-IN rule 10 match rpki 'valid'
+set policy route-map ROUTES-IN rule 10 set local-preference '300'
+set policy route-map ROUTES-IN rule 20 action 'permit'
+set policy route-map ROUTES-IN rule 20 match rpki 'notfound'
+set policy route-map ROUTES-IN rule 20 set local-preference '125'
+set policy route-map ROUTES-IN rule 30 action 'deny'
+set policy route-map ROUTES-IN rule 30 match rpki 'invalid'
+```
+
+Once your routers are configured to reject RPKI-invalid prefixes, you can
+test whether the configuration is working correctly using Cloudflare's [test]
+website. Keep in mind that in order for this to work, you need to have no
+default routes or anything else that would still send traffic to RPKI-invalid
+destinations.
+
+[excellent guide to rpki]: https://rpki.readthedocs.io/
+[help and operational guidance]: https://rpki.readthedocs.io/en/latest/about/help.html
+[krill]: https://www.nlnetlabs.nl/projects/rpki/krill/
+[routinator]: https://www.nlnetlabs.nl/projects/rpki/routinator/
+[rpki-client]: https://www.rpki-client.org/
+[software]: https://rpki.readthedocs.io/en/latest/ops/tools.html#relying-party-software
+[stayrtr]: https://github.com/bgp/stayrtr/
+[test]: https://isbgpsafeyet.com/
+[tweet by evilmog]: <https://twitter.com/Evil_Mog/status/1230924170508169216>
diff --git a/docs/configuration/protocols/segment-routing.md b/docs/configuration/protocols/segment-routing.md
new file mode 100644
index 00000000..45c89a41
--- /dev/null
+++ b/docs/configuration/protocols/segment-routing.md
@@ -0,0 +1,359 @@
+(segment-routing)=
+
+# Segment Routing
+
+Segment Routing (SR) is a network architecture that is similar to source-routing
+. In this architecture, the ingress router adds a list of segments, known as
+SIDs, to the packet as it enters the network. These segments represent different
+portions of the network path that the packet will take.
+
+The SR segments are portions of the network path taken by the packet, and are
+called SIDs. At each node, the first SID of the list is read, executed as a
+forwarding function, and may be popped to let the next node read the next SID of
+the list. The SID list completely determines the path where the packet is
+forwarded.
+
+Segment Routing can be applied to an existing MPLS-based data plane and defines
+a control plane network architecture. In MPLS networks, segments are encoded as
+MPLS labels and are added at the ingress router. These MPLS labels are then
+exchanged and populated by Interior Gateway Protocols (IGPs) like IS-IS or OSPF
+which are running on most ISPs.
+
+:::{note}
+Segment routing defines a control plane network architecture and
+can be applied to an existing MPLS based dataplane. In the MPLS networks,
+segments are encoded as MPLS labels and are imposed at the ingress router.
+MPLS labels are exchanged and populated by IGPs like IS-IS.Segment Routing
+as per RFC8667 for MPLS dataplane. It supports IPv4, IPv6 and ECMP and has
+been tested against Cisco & Juniper routers.however,this deployment is still
+EXPERIMENTAL for FRR.
+:::
+
+## IS-IS SR Configuration
+
+Segment routing (SR) is used by the IGP protocols to interconnect network
+devices, below configuration shows how to enable SR on IS-IS:
+
+:::{note}
+``Known limitations:``
+
+No support for level redistribution (L1 to L2 or L2 to L1)
+
+No support for binding SID
+
+No support for SRLB
+
+Only one SRGB and default SPF Algorithm is supported
+:::
+
+```{cfgcmd} set protocols isis segment-routing global-block high-label-value \<label-value\>
+
+Set the Segment Routing Global Block i.e. the label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.
+```
+
+
+```{cfgcmd} set protocols isis segment-routing global-block low-label-value \<label-value\>
+
+Set the Segment Routing Global Block i.e. the low label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.
+```
+
+
+```{cfgcmd} set protocols isis segment-routing local-block high-label-value \<label-value\>
+
+Set the Segment Routing Local Block i.e. the label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.Segment Routing Local Block, The negative command always
+unsets both.
+```
+
+
+```{cfgcmd} set protocols isis segment-routing local-block \<low-label-value \<label-value\>
+
+Set the Segment Routing Local Block i.e. the low label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.Segment Routing Local Block, The negative command always
+unsets both.
+```
+
+
+```{cfgcmd} set protocols isis segment-routing maximum-label-depth \<1-16\>
+
+Set the Maximum Stack Depth supported by the router. The value depend of
+the MPLS dataplane.
+```
+
+
+```{cfgcmd} set protocols isis segment-routing prefix \<address\> index value \<0-65535\>
+
+A segment ID that contains an IP address prefix calculated by an IGP in the
+service provider core network. Prefix SIDs are globally unique, this value
+indentify it
+```
+
+
+```{cfgcmd} set protocols isis segment-routing prefix \<address\> index \<no-php-flag | explicit-null| n-flag-clear\>
+
+this option allows to configure prefix-sid on SR. The ‘no-php-flag’ means NO
+Penultimate Hop Popping that allows SR node to request to its neighbor to
+not pop the label. The ‘explicit-null’ flag allows SR node to request to its
+neighbor to send IP packet with the EXPLICIT-NULL label. The ‘n-flag-clear’
+option can be used to explicitly clear the Node flag that is set by default
+for Prefix-SIDs associated to loopback addresses. This option is necessary
+to configure Anycast-SIDs.
+```
+
+```{opcmd} show isis segment-routing node
+
+ Show detailed information about all learned Segment Routing Nodes
+```
+
+
+```{opcmd} show isis route prefix-sid
+
+Show detailed information about prefix-sid and label learned
+```
+
+:::{note}
+more information related IGP - {ref}`routing-isis`
+:::
+
+
+## OSPF SR Configuration
+
+
+Segment routing (SR) is used by the IGP protocols to interconnect network
+devices, below configuration shows how to enable SR on OSPF:
+
+```{cfgcmd} set protocols ospf parameters opaque-lsa
+
+Enable the Opaque-LSA capability (rfc2370), necessary to transport label
+on IGP
+```
+
+```{cfgcmd} set protocols ospf segment-routing global-block high-label-value \<label-value\>
+
+Set the Segment Routing Global Block i.e. the label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.
+```
+
+```{cfgcmd} set protocols ospf segment-routing global-block low-label-value \<label-value\>
+
+Set the Segment Routing Global Block i.e. the low label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.
+```
+
+```{cfgcmd} set protocols ospf segment-routing local-block high-label-value \<label-value\>
+
+Set the Segment Routing Local Block i.e. the label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.Segment Routing Local Block, The negative command always
+unsets both.
+```
+
+```{cfgcmd} set protocols ospf segment-routing local-block \<low-label-value \<label-value\>
+
+Set the Segment Routing Local Block i.e. the low label range used by MPLS to
+store label in the MPLS FIB for Prefix SID. Note that the block size may
+not exceed 65535.Segment Routing Local Block, The negative command always
+unsets both.
+```
+
+```{cfgcmd} set protocols ospf segment-routing maximum-label-depth \<1-16\>
+
+Set the Maximum Stack Depth supported by the router. The value depend of
+the MPLS dataplane.
+```
+
+```{cfgcmd} set protocols ospf segment-routing prefix \<address\> index value \<0-65535\>
+
+A segment ID that contains an IP address prefix calculated by an IGP in the
+service provider core network. Prefix SIDs are globally unique, this value
+indentify it
+```
+
+```{cfgcmd} set protocols ospf segment-routing prefix \<address\> index \<no-php-flag | explicit-null| n-flag-clear\>
+
+this option allows to configure prefix-sid on SR. The ‘no-php-flag’ means NO
+Penultimate Hop Popping that allows SR node to request to its neighbor to
+not pop the label. The ‘explicit-null’ flag allows SR node to request to its
+neighbor to send IP packet with the EXPLICIT-NULL label. The ‘n-flag-clear’
+option can be used to explicitly clear the Node flag that is set by default
+for Prefix-SIDs associated to loopback addresses. This option is necessary
+to configure Anycast-SIDs.
+```
+
+:::{note}
+more information related IGP - {ref}`routing-ospf`
+:::
+
+## Configuration Example
+
+we described the configuration SR ISIS / SR OSPF using 2 connected with them to
+share label information.
+
+### Enable IS-IS with Segment Routing (Experimental)
+
+**Node 1:**
+
+```none
+set interfaces loopback lo address '192.168.255.255/32'
+set interfaces ethernet eth1 address '192.0.2.1/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5255.00'
+set protocols isis segment-routing global-block high-label-value '599'
+set protocols isis segment-routing global-block low-label-value '550'
+set protocols isis segment-routing prefix 192.168.255.255/32 index value '1'
+set protocols isis segment-routing prefix 192.168.255.255/32 index explicit-null
+set protocols mpls interface 'eth1'
+```
+
+**Node 2:**
+
+```none
+set interfaces loopback lo address '192.168.255.254/32'
+set interfaces ethernet eth1 address '192.0.2.2/24'
+
+set protocols isis interface eth1
+set protocols isis interface lo
+set protocols isis net '49.0001.1921.6825.5254.00'
+set protocols isis segment-routing global-block high-label-value '599'
+set protocols isis segment-routing global-block low-label-value '550'
+set protocols isis segment-routing prefix 192.168.255.254/32 index value '2'
+set protocols isis segment-routing prefix 192.168.255.254/32 index explicit-null
+set protocols mpls interface 'eth1'
+```
+
+This gives us MPLS segment routing enabled and labels for far end loopbacks:
+
+```none
+Node-1@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ ----------------------------------------------------------------------
+ 552 SR (IS-IS) 192.0.2.2 IPv4 Explicit Null <-- Node-2 loopback learned on Node-1
+ 15000 SR (IS-IS) 192.0.2.2 implicit-null
+ 15001 SR (IS-IS) fe80::e87:6cff:fe09:1 implicit-null
+ 15002 SR (IS-IS) 192.0.2.2 implicit-null
+ 15003 SR (IS-IS) fe80::e87:6cff:fe09:1 implicit-null
+
+Node-2@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ ---------------------------------------------------------------------
+ 551 SR (IS-IS) 192.0.2.1 IPv4 Explicit Null <-- Node-1 loopback learned on Node-2
+ 15000 SR (IS-IS) 192.0.2.1 implicit-null
+ 15001 SR (IS-IS) fe80::e33:2ff:fe80:1 implicit-null
+ 15002 SR (IS-IS) 192.0.2.1 implicit-null
+ 15003 SR (IS-IS) fe80::e33:2ff:fe80:1 implicit-null
+```
+
+Here is the routing tables showing the MPLS segment routing label operations:
+
+```none
+Node-1@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.2, eth1 inactive, weight 1, 00:07:48
+I>* 192.168.255.254/32 [115/20] via 192.0.2.2, eth1, label IPv4 Explicit Null, weight 1, 00:03:39
+
+Node-2@vyos:~$ show ip route isis
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+I 192.0.2.0/24 [115/20] via 192.0.2.1, eth1 inactive, weight 1, 00:07:46
+I>* 192.168.255.255/32 [115/20] via 192.0.2.1, eth1, label IPv4 Explicit Null, weight 1, 00:03:43
+```
+
+
+### Enable OSPF with Segment Routing (Experimental):
+
+**Node 1**
+
+```none
+set interfaces loopback lo address 10.1.1.1/32
+set interfaces ethernet eth0 address 192.168.0.1/24
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '10.1.1.1/32'
+set protocols ospf parameters opaque-lsa
+set protocols ospf parameters router-id '10.1.1.1'
+set protocols ospf segment-routing global-block high-label-value '1100'
+set protocols ospf segment-routing global-block low-label-value '1000'
+set protocols ospf segment-routing prefix 10.1.1.1/32 index explicit-null
+set protocols ospf segment-routing prefix 10.1.1.1/32 index value '1'
+```
+
+**Node 2**
+
+```none
+set interfaces loopback lo address 10.1.1.2/32
+set interfaces ethernet eth0 address 192.168.0.2/24
+set protocols ospf area 0 network '192.168.0.0/24'
+set protocols ospf area 0 network '10.1.1.2/32'
+set protocols ospf parameters opaque-lsa
+set protocols ospf parameters router-id '10.1.1.2'
+set protocols ospf segment-routing global-block high-label-value '1100'
+set protocols ospf segment-routing global-block low-label-value '1000'
+set protocols ospf segment-routing prefix 10.1.1.2/32 index explicit-null
+set protocols ospf segment-routing prefix 10.1.1.2/32 index value '2'
+```
+
+This gives us MPLS segment routing enabled and labels for far end loopbacks:
+
+```none
+Node-1@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------------------
+ 1002 SR (OSPF) 192.168.0.2 IPv4 Explicit Null <-- Node-2 loopback learned on Node-1
+ 15000 SR (OSPF) 192.168.0.2 implicit-null
+ 15001 SR (OSPF) 192.168.0.2 implicit-null
+
+Node-2@vyos:~$ show mpls table
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------------------
+ 1001 SR (OSPF) 192.168.0.1 IPv4 Explicit Null <-- Node-1 loopback learned on Node-2
+ 15000 SR (OSPF) 192.168.0.1 implicit-null
+ 15001 SR (OSPF) 192.168.0.1 implicit-null
+```
+
+Here is the routing tables showing the MPLS segment routing label operations:
+
+```none
+Node-1@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O 10.1.1.1/32 [110/0] is directly connected, lo, weight 1, 00:03:43
+O>* 10.1.1.2/32 [110/1] via 192.168.0.2, eth0, label IPv4 Explicit Null, weight 1, 00:03:32
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:43
+
+Node-2@vyos:~$ show ip route ospf
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+
+O>* 10.1.1.1/32 [110/1] via 192.168.0.1, eth0, label IPv4 Explicit Null, weight 1, 00:03:36
+O 10.1.1.2/32 [110/0] is directly connected, lo, weight 1, 00:03:51
+O 192.168.0.0/24 [110/1] is directly connected, eth0, weight 1, 00:03:51
+```
diff --git a/docs/configuration/protocols/static.md b/docs/configuration/protocols/static.md
new file mode 100644
index 00000000..357f7076
--- /dev/null
+++ b/docs/configuration/protocols/static.md
@@ -0,0 +1,298 @@
+(routing-static)=
+
+# Static
+
+Static routes are manually configured routes, which, in general, cannot be
+updated dynamically from information VyOS learns about the network topology from
+other routing protocols. However, if a link fails, the router will remove
+routes, including static routes, from the {abbr}`RIPB (Routing Information
+Base)` that used this interface to reach the next hop. In general, static
+routes should only be used for very simple network topologies, or to override
+the behavior of a dynamic routing protocol for a small number of routes. The
+collection of all routes the router has learned from its configuration or from
+its dynamic routing protocols is stored in the RIB. Unicast routes are directly
+used to determine the forwarding table used for unicast packet forwarding.
+
+## IPv4 Unicast Routes
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\>
+
+Configure next-hop *\<address\>* for an IPv4 static route. Multiple static
+routes can be created.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> disable
+
+Disable this IPv4 static route entry.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> distance \<distance\>
+
+Defines next-hop distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+
+Range is 1 to 255, default is 1.
+
+:::{note}
+Routes with a distance of 255 are effectively disabled and not
+installed into the kernel.
+:::
+```
+
+
+### IPv4 Interface Routes
+
+```{cfgcmd} set protocols static route \<subnet\> interface \<interface\>
+
+Allows you to configure the next-hop interface for an interface-based IPv4
+static route. *\<interface\>* will be the next-hop interface where traffic is
+routed for the given *\<subnet\>*.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> interface \<interface\> disable
+
+Disables interface-based IPv4 static route.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> interface \<interface\> distance \<distance\>
+
+Defines next-hop distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+
+Range is 1 to 255, default is 1.
+```
+
+
+### IPv4 BFD
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> bfd
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> bfd profile \<profile\>
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address with BFD profile *\<profile\>*.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> next-hop \<address\> bfd multi-hop source-address \<source-address\>
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address with source address
+*\<source\>* but initiate a multi-hop session.
+```
+
+
+### DHCP Interface Routes
+
+```{cfgcmd} set protocols static route \<subnet\> dhcp-interface \<interface\>
+
+Defines route with DHCP interface supplying next-hop IP address.
+```
+
+
+### IPv4 Reject Routes
+
+```{cfgcmd} set protocol static route \<subnet\> reject
+
+Defines route which emits an ICMP unreachable when matched.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> reject distance \<distance\>
+
+Defines distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> reject tag \<tag\>
+
+Sets a tag for this route.
+```
+
+```{cfgcmd} set protocol static route6 \<subnet\> reject
+
+Defines route which emits an ICMP unreachable when matched.
+```
+
+
+### IPv4 Blackhole Routes
+
+```{cfgcmd} set protocols static route \<subnet\> blackhole
+
+Use this command to configure a "black-hole" route on the router. A
+black-hole route is a route for which the system silently discard packets
+that are matched. This prevents networks leaking out public interfaces, but
+it does not prevent them from being used as a more specific route inside your
+network.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> blackhole distance \<distance\>
+
+Defines blackhole distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+```
+
+```{cfgcmd} set protocols static route \<subnet\> blackhole tag \<tag\>
+
+Sets a tag for this route.
+```
+
+
+## IPv6 Unicast Routes
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\>
+
+Configure next-hop *\<address\>* for an IPv6 static route. Multiple static
+routes can be created.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> disable
+
+Disable this IPv6 static route entry.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> distance \<distance\>
+
+Defines next-hop distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+
+Range is 1 to 255, default is 1.
+
+:::{note}
+Routes with a distance of 255 are effectively disabled and not
+installed into the kernel.
+:::
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> segments \<segments\>
+
+It is possible to specify a static route for ipv6 prefixes using an
+SRv6 segments instruction. The ``/`` separator can be used to specify
+multiple segment instructions.
+
+Example:
+
+:::{code-block} none
+set protocols static route6 2001:db8:1000::/36 next-hop 2001:db8:201::ffff segments '2001:db8:aaaa::7/2002::4/2002::3/2002::2'
+:::
+
+:::{code-block} none
+vyos@vyos:~$ show ipv6 route
+Codes: K - kernel route, C - connected, S - static, R - RIPng,
+ O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
+ v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+ t - trapped, o - offload failure
+C>* 2001:db8:201::/64 is directly connected, eth0.201, 00:00:46
+S>* 2001:db8:1000::/36 [1/0] via 2001:db8:201::ffff, eth0.201, seg6 2001:db8:aaaa::7,2002::4,2002::3,2002::2, weight 1, 00:00:08
+:::
+```
+
+
+### IPv6 Interface Routes
+
+```{cfgcmd} set protocols static route6 \<subnet\> interface \<interface\>
+
+Allows you to configure the next-hop interface for an interface-based IPv6
+static route. *\<interface\>* will be the next-hop interface where traffic is
+routed for the given *\<subnet\>*.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> interface \<interface\> disable
+
+Disables interface-based IPv6 static route.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> interface \<interface\> distance \<distance\>
+
+Defines next-hop distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+
+Range is 1 to 255, default is 1.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> interface \<interface\> segments \<segments\>
+
+It is possible to specify a static route for ipv6 prefixes using an
+SRv6 segments instruction. The ``/`` separator can be used to specify
+multiple segment instructions.
+
+Example:
+
+:::{code-block} none
+set protocols static route6 2001:db8:1000::/36 interface eth0 segments '2001:db8:aaaa::7/2002::4/2002::3/2002::2'
+:::
+```
+
+
+### IPv6 BFD
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> bfd
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> bfd profile \<profile\>
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address with BFD profile *\<profile\>*.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> next-hop \<address\> bfd multi-hop source-address \<source\>
+
+Configure a static route for *\<subnet\>* using gateway *\<address\>* and use the
+gateway address as BFD peer destination address with source address
+*\<source\>* but initiate a multi-hop session.
+```
+
+
+### IPv6 Reject Routes
+
+```{cfgcmd} set protocol static route6 \<subnet\> reject
+
+Defines route which emits an ICMP unreachable when matched.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> reject distance \<distance\>
+
+Defines distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> reject tag \<tag\>
+
+Sets a tag for this route.
+```
+
+
+### IPv6 Blackhole Routes
+
+```{cfgcmd} set protocols static route6 \<subnet\> blackhole
+
+Use this command to configure a "black-hole" route on the router. A
+black-hole route is a route for which the system silently discard packets
+that are matched. This prevents networks leaking out public interfaces, but
+it does not prevent them from being used as a more specific route inside your
+network.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> blackhole distance \<distance\>
+
+Defines blackhole distance for this route, routes with smaller administrative
+distance are elected prior to those with a higher distance.
+```
+
+```{cfgcmd} set protocols static route6 \<subnet\> blackhole tag \<tag\>
+
+Sets a tag for this route.
+```
+
+
+## Alternate Routing Tables
+
+Alternate routing tables are used with policy based routing by utilizing
+{ref}`vrf`.
diff --git a/docs/configuration/protocols/traffic-engineering.md b/docs/configuration/protocols/traffic-engineering.md
new file mode 100644
index 00000000..832023a7
--- /dev/null
+++ b/docs/configuration/protocols/traffic-engineering.md
@@ -0,0 +1,54 @@
+(traffic-engineering)=
+
+# Traffic Engineering
+
+Traffic Engineering (TE) is possibility to send traffic from node to node using
+alternative path.
+
+## Common link parameters
+
+Traffic Engineering parameters are used for both IS-IS and OSPF (not supported yet).
+
+```{cfgcmd} set protocols traffic-engineering admin-group \<admin-group-name\> bit-position \<bit-position-value\>
+
+Create Administrative group and assosiate bit position with it. These groups can be
+used in the following commands.
+
+\<bit-position-value\> can have value 0-31. There cannot be two groups with same bit position.
+```
+
+
+```{cfgcmd} set protocols traffic-engineering interface \<ifname\> admin-group \<admin-group-name\>
+
+Set administrative group for interface \<ifname\>. Multiple values can be provided.
+```
+
+
+```{cfgcmd} set protocols traffic-engineering interface \<ifname\> max-bandwidth \<max-bandwidth-value-mbps\>
+
+Set maximum bandwidth for interface \<ifname\>. Value given in Mbits per second.
+```
+
+
+```{cfgcmd} set protocols traffic-engineering interface \<ifname\> max-reservable-bandwidth \<max-reservable-bandwidth-value-mbps\>
+
+Set maximum reservable bandwidth for interface \<ifname\>. Value given in Mbits per second.
+```
+
+## IS-IS TE Configuration
+
+Traffic Engineering (TE) can be enabled and exported for IS-IS
+using the following commands:
+
+```{cfgcmd} set protocols isis traffic-engineering enable
+
+Enable Traffic Engineering for IS-IS.
+```
+```{cfgcmd} set protocols isis traffic-engineering export
+
+Export Traffic Engineering data to neighbors.
+```
+```{cfgcmd} set protocols isis traffic-engineering address \<ipv4-address\>
+
+Configure IPv4 address for MPLS-TE.
+``` \ No newline at end of file
diff --git a/docs/configuration/service/broadcast-relay.md b/docs/configuration/service/broadcast-relay.md
new file mode 100644
index 00000000..4202ad6b
--- /dev/null
+++ b/docs/configuration/service/broadcast-relay.md
@@ -0,0 +1,70 @@
+(udp-broadcast-relay)=
+
+# UDP Broadcast Relay
+
+Certain vendors use broadcasts to identify their equipment within one ethernet
+segment. Unfortunately if you split your network with multiple VLANs you loose
+the ability of identifying your equipment.
+
+This is where "UDP broadcast relay" comes into play! It will forward received
+broadcasts to other configured networks.
+
+Every UDP port which will be forward requires one unique ID. Currently we
+support 99 IDs!
+
+## Configuration
+
+```{cfgcmd} set service broadcast-relay id \<n\> description \<description\>
+
+A description can be added for each and every unique relay ID. This is
+useful to distinguish between multiple different ports/applications.
+```
+
+```{cfgcmd} set service broadcast-relay id \<n\> interface \<interface\>
+
+The interface used to receive and relay individual broadcast packets. If you
+want to receive/relay packets on both `eth1` and `eth2` both interfaces need
+to be added.
+```
+
+```{cfgcmd} set service broadcast-relay id \<n\> address \<ipv4-address\>
+
+Set the source IP of forwarded packets, otherwise original senders address
+is used.
+```
+
+```{cfgcmd} set service broadcast-relay id \<n\> port \<port\>
+
+The UDP port number used by your application. It is mandatory for this kind
+of operation.
+```
+
+```{cfgcmd} set service broadcast-relay id \<n\> disable
+
+Each broadcast relay instance can be individually disabled without deleting
+the configured node by using the following command:
+```
+
+```{cfgcmd} set service broadcast-relay disable
+
+In addition you can also disable the whole service without the need to remove
+it from the current configuration.
+```
+
+:::{note}
+You can run the UDP broadcast relay service on multiple routers
+connected to a subnet. There is **NO** UDP broadcast relay packet storm!
+:::
+
+## Example
+
+To forward all broadcast packets received on `UDP port 1900` on `eth3`, `eth4`
+or `eth5` to all other interfaces in this configuration.
+
+```none
+set service broadcast-relay id 1 description 'SONOS'
+set service broadcast-relay id 1 interface 'eth3'
+set service broadcast-relay id 1 interface 'eth4'
+set service broadcast-relay id 1 interface 'eth5'
+set service broadcast-relay id 1 port '1900'
+```
diff --git a/docs/configuration/service/config-sync.md b/docs/configuration/service/config-sync.md
new file mode 100644
index 00000000..a575f947
--- /dev/null
+++ b/docs/configuration/service/config-sync.md
@@ -0,0 +1,164 @@
+(config-sync)=
+
+# Config Sync
+
+Configuration synchronization (config sync) is a feature of VyOS that
+permits synchronization of the configuration of one VyOS router to
+another in a network.
+
+The main benefit to configuration synchronization is that it eliminates having
+to manually replicate configuration changes made on the primary router to the
+secondary (replica) router.
+
+The writing of the configuration to the secondary router is performed through
+the VyOS HTTP API. The user can specify which portion(s) of the configuration will
+be synchronized and the mode to use - whether to replace or add.
+
+To prevent issues with divergent configurations between the pair of routers,
+synchronization is strictly unidirectional from primary to replica. Both
+routers should be online and run the same version of VyOS.
+
+## Configuration
+
+```{cfgcmd} set service config-sync secondary \<address|key|timeout|port\>
+
+Specify the address, API key, timeout and port of the secondary router.
+You need to enable and configure the HTTP API service on the secondary
+router for config sync to operate.
+```
+
+```{cfgcmd} set service config-sync section \<section\>
+
+Specify the section of the configuration to synchronize. If more than one
+section is to be synchronized, repeat the command to add additional
+sections as required.
+```
+
+```{cfgcmd} set service config-sync mode \<load|set\>
+
+Two options are available for *mode*: either *load* and replace or *set*
+the configuration section.
+```
+
+```none
+Supported options for <section> include:
+ firewall
+ interfaces <interface>
+ nat
+ nat66
+ pki
+ policy
+ protocols <protocol>
+ qos <interface|policy>
+ service <service>
+ system <conntrack|
+ flow-accounting|option|sflow|static-host-mapping|sysctl|time-zone>
+ vpn
+ vrf
+```
+
+
+## Operational Commands
+
+````{opcmd} show configuration secondary sync [commands] [running | candidate | saved] [\<config-node-path\>]
+
+Display configuration differences between the local node and
+a config-sync secondary node.
+
+This command allows operators to compare configurations across nodes
+participating in configuration synchronization (e.g., primary and
+secondary routers). It helps detect configuration drift and validate
+intended changes before synchronization.
+
+**Parameters:**
+
+```{eval-rst}
+.. list-table::
+ :widths: 30 70
+ :header-rows: 0
+
+ * - ``commands`` (optional)
+ - Show output as a list of configuration commands instead of raw diff.
+ * - ``running|candidate|saved`` (optional, mutually exclusive)
+ - Select which configuration to compare:
+ ``running`` (current active configuration, default),
+ ``candidate`` (uncommitted changes), or
+ ``saved`` (last saved configuration). Only one of these may be
+ specified at a time; if omitted, ``running`` is used.
+```
+
+**Examples:**
+
+:::{code-block} none
+# compare full running configuration with a secondary node
+show configuration secondary sync
+
+# compare only interface configuration
+show configuration secondary sync running interfaces dummy
+
+# compare candidate configuration and display as a list of commands
+show configuration secondary sync commands candidate
+:::
+````
+
+Without a built-in cross-node diff, operators may unintentionally push
+changes that conflict with the remote configuration (e.g., mismatched
+interfaces, firewall policies, or protocol settings).
+
+
+## Example
+
+- Synchronize the time-zone and OSPF configuration from Router A to Router B
+- The address of Router B is 10.0.20.112 and the port used is 8443
+
+Configure the HTTP API service on Router B
+
+```none
+set service https listen-address '10.0.20.112'
+set service https port '8443'
+set service https api keys id KID key 'foo'
+set service https api rest
+```
+
+Configure the config-sync service on Router A
+
+```none
+set service config-sync mode 'load'
+set service config-sync secondary address '10.0.20.112'
+set service config-sync secondary port '8443'
+set service config-sync secondary key 'foo'
+set service config-sync section protocols 'ospf'
+set service config-sync section system 'time-zone'
+```
+
+Make config-sync relevant changes to Router A's configuration
+
+```none
+vyos@vyos-A# set system time-zone 'America/Los_Angeles'
+vyos@vyos-A# commit
+INFO:vyos_config_sync:Config synchronization: Mode=load,
+Secondary=10.0.20.112
+vyos@vyos-A# save
+
+vyos@vyos-A# set protocols ospf area 0 network '10.0.48.0/30'
+vyos@vyos-A# commit
+INFO:vyos_config_sync:Config synchronization: Mode=load,
+Secondary=10.0.20.112
+yos@vyos-A# save
+```
+
+Verify configuration changes have been replicated to Router B
+
+```none
+vyos@vyos-B:~$ show configuration commands | match time-zone
+set system time-zone 'America/Los_Angeles'
+
+vyos@vyos-B:~$ show configuration commands | match ospf
+set protocols ospf area 0 network '10.0.48.0/30'
+```
+
+
+## Known issues
+
+Configuration resynchronization. With the current implementation of *service
+config-sync*, the secondary node must be online.
diff --git a/docs/configuration/service/conntrack-sync.md b/docs/configuration/service/conntrack-sync.md
new file mode 100644
index 00000000..47a0ae2f
--- /dev/null
+++ b/docs/configuration/service/conntrack-sync.md
@@ -0,0 +1,321 @@
+(conntrack-sync)=
+
+# Conntrack Sync
+
+One of the important features built on top of the Netfilter framework is
+connection tracking. Connection tracking allows the kernel to keep track of all
+logical network connections or sessions, and thereby relate all of the packets
+which may make up that connection. NAT relies on this information to translate
+all related packets in the same way, and iptables can use this information to
+act as a stateful firewall.
+
+The connection state however is completely independent of any upper-level
+state, such as TCP's or SCTP's state. Part of the reason for this is that when
+merely forwarding packets, i.e. no local delivery, the TCP engine may not
+necessarily be invoked at all. Even connectionless-mode transmissions such as
+UDP, IPsec (AH/ESP), GRE and other tunneling protocols have, at least, a pseudo
+connection state. The heuristic for such protocols is often based upon a preset
+timeout value for inactivity, after whose expiration a Netfilter connection is
+dropped.
+
+Each Netfilter connection is uniquely identified by a (layer-3 protocol, source
+address, destination address, layer-4 protocol, layer-4 key) tuple. The layer-4
+key depends on the transport protocol; for TCP/UDP it is the port numbers, for
+tunnels it can be their tunnel ID, but otherwise is just zero, as if it were
+not part of the tuple. To be able to inspect the TCP port in all cases, packets
+will be mandatorily defragmented.
+
+It is possible to use either Multicast or Unicast to sync conntrack traffic.
+Most examples below show Multicast, but unicast can be specified by using the
+"peer" keywork after the specified interface, as in the following example:
+
+{cfgcmd}`set service conntrack-sync interface eth0 peer 192.168.0.250`
+
+## Configuration
+
+```{cfgcmd} set service conntrack-sync accept-protocol
+
+Accept only certain protocols: You may want to replicate the state of flows
+depending on their layer 4 protocol.
+
+Protocols are: tcp, sctp, dccp, udp, icmp and ipv6-icmp.
+```
+
+
+```{cfgcmd} set service conntrack-sync event-listen-queue-size \<size\>
+
+The daemon doubles the size of the netlink event socket buffer size if it
+detects netlink event message dropping. This clause sets the maximum buffer
+size growth that can be reached.
+
+Queue size for listening to local conntrack events in MB.
+```
+
+
+```{cfgcmd} set service conntrack-sync expect-sync \<all|ftp|h323|nfs|sip|sqlnet\>
+
+Protocol for which expect entries need to be synchronized.
+```
+
+
+```{cfgcmd} set service conntrack-sync failover-mechanism vrrp sync-group \<group\>
+
+Failover mechanism to use for conntrack-sync.
+
+Only VRRP is supported. Required option.
+```
+
+
+```{cfgcmd} set service conntrack-sync ignore-address \<x.x.x.x\>
+
+IP addresses or networks for which local conntrack entries will not be synced
+```
+
+
+```{cfgcmd} set service conntrack-sync interface \<name\>
+
+Interface to use for syncing conntrack entries.
+```
+
+
+```{cfgcmd} set service conntrack-sync interface \<name\> port \<port\>
+
+Port number used by connection.
+```
+
+
+```{cfgcmd} set service conntrack-sync listen-address \<ipv4address\>
+
+Local IPv4 addresses for service to listen on.
+```
+
+
+```{cfgcmd} set service conntrack-sync mcast-group \<x.x.x.x\>
+
+Multicast group to use for syncing conntrack entries.
+
+Defaults to 225.0.0.50.
+```
+
+
+```{cfgcmd} set service conntrack-sync interface \<name\> peer \<address\>
+
+Peer to send unicast UDP conntrack sync entires to, if not using Multicast
+configuration from above above.
+```
+
+
+```{cfgcmd} set service conntrack-sync sync-queue-size \<size\>
+
+Queue size for syncing conntrack entries in MB.
+```
+
+
+```{cfgcmd} set service conntrack-sync disable-external-cache
+
+This diable the external cache and directly injects the flow-states into the
+in-kernel Connection Tracking System of the backup firewall.
+```
+
+
+```{cfgcmd} set service conntrack-sync purge-timeout \<timeout\>
+
+Timeout (in seconds) for purging synchronized entries on handover events.
+
+On handover, ``conntrackd -t`` is invoked, which schedules a conntrack table
+flush after ``<timeout>`` seconds to purge stale (“zombie”) entries and
+reduce clashes when multiple handovers occur in a short period.
+The default is 60 seconds.
+```
+
+:::{note}
+In VRRP stateful firewall deployments, align VRRP timing with this
+behavior: because synchronized conntrack state is purged after the purge
+timeout, set **VRRP preempt-delay** to ≥ **purge-timeout** so mastership
+can be restored before conntrack state is purged.
+:::
+
+```{cfgcmd} set service conntrack-sync disable-syslog
+
+Disable connection logging via Syslog.
+```
+
+
+```{cfgcmd} set service conntrack-sync startup-resync
+
+Order conntrackd to request a complete conntrack table resync against
+the other node at startup.
+```
+
+## Operation
+
+```{opcmd} show conntrack table ipv4
+
+Make sure conntrack is enabled by running and show connection tracking table.
+
+:::{code-block} none
+vyos@vyos:~$ show conntrack table ipv4
+TCP state codes: SS - SYN SENT, SR - SYN RECEIVED, ES - ESTABLISHED,
+FW - FIN WAIT, CW - CLOSE WAIT, LA - LAST ACK,
+TW - TIME WAIT, CL - CLOSE, LI - LISTEN
+
+CONN ID Source Destination Protocol TIMEOUT
+1015736576 10.35.100.87:58172 172.31.20.12:22 tcp [6] ES 430279
+1006235648 10.35.101.221:57483 172.31.120.21:22 tcp [6] ES 413310
+1006237088 10.100.68.100 172.31.120.21 icmp [1] 29
+1015734848 10.35.100.87:56282 172.31.20.12:22 tcp [6] ES 300
+1015734272 172.31.20.12:60286 239.10.10.14:694 udp [17] 29
+1006239392 10.35.101.221 172.31.120.21 icmp [1] 29
+:::
+:::{note}
+If the table is empty and you have a warning message, it means
+conntrack is not enabled. To enable conntrack, just create a NAT or a firewall
+rule. {cfgcmd}`set firewall state-policy established action accept`
+:::
+```
+
+
+```{opcmd} show conntrack-sync cache external
+
+Show connection syncing external cache entries
+```
+
+
+```{opcmd} show conntrack-sync cache internal
+
+Show connection syncing internal cache entries
+```
+
+
+```{opcmd} show conntrack-sync statistics
+
+Retrieve current statistics of connection tracking subsystem.
+
+:::{code-block} none
+vyos@vyos:~$ show conntrack-sync statistics
+Main Table Statistics:
+
+cache internal:
+current active connections: 19606
+connections created: 6298470 failed: 0
+connections updated: 3786793 failed: 0
+connections destroyed: 6278864 failed: 0
+
+cache external:
+current active connections: 15771
+connections created: 1660193 failed: 0
+connections updated: 77204 failed: 0
+connections destroyed: 1644422 failed: 0
+
+traffic processed:
+0 Bytes 0 Pckts
+
+multicast traffic (active device=eth0.5):
+976826240 Bytes sent 212898000 Bytes recv
+8302333 Pckts sent 2009929 Pckts recv
+0 Error send 0 Error recv
+
+message tracking:
+0 Malformed msgs 263 Lost msgs
+:::
+```
+```{opcmd} show conntrack-sync status
+
+Retrieve current status of connection tracking subsystem.
+
+:::{code-block} none
+vyos@vyos:~$ show conntrack-sync status
+sync-interface : eth0.5
+failover-mechanism : vrrp [sync-group GEFOEKOM]
+last state transition : no transition yet!
+ExpectationSync : disabled
+:::
+```
+
+## Example
+
+The next example is a simple configuration of conntrack-sync.
+
+:::{figure} /_static/images/service_conntrack_sync-schema.webp
+:alt: Conntrack Sync Example
+:scale: 60 %
+:::
+
+Now configure conntrack-sync service on `router1` **and** `router2`
+
+```none
+set high-availability vrrp group internal virtual-address ... etc ...
+set high-availability vrrp sync-group syncgrp member 'internal'
+set service conntrack-sync accept-protocol 'tcp'
+set service conntrack-sync accept-protocol 'udp'
+set service conntrack-sync accept-protocol 'icmp'
+set service conntrack-sync failover-mechanism vrrp sync-group 'syncgrp'
+set service conntrack-sync interface 'eth0'
+set service conntrack-sync mcast-group '225.0.0.50'
+```
+
+On the active router, you should have information in the internal-cache of
+conntrack-sync. The same current active connections number should be shown in
+the external-cache of the standby router
+
+On active router run:
+
+```none
+$ show conntrack-sync statistics
+
+Main Table Statistics:
+
+cache internal:
+current active connections: 10
+connections created: 8517 failed: 0
+connections updated: 127 failed: 0
+connections destroyed: 8507 failed: 0
+
+cache external:
+current active connections: 0
+connections created: 0 failed: 0
+connections updated: 0 failed: 0
+connections destroyed: 0 failed: 0
+
+traffic processed:
+ 0 Bytes 0 Pckts
+
+multicast traffic (active device=eth0):
+ 868780 Bytes sent 224136 Bytes recv
+ 20595 Pckts sent 14034 Pckts recv
+ 0 Error send 0 Error recv
+
+message tracking:
+ 0 Malformed msgs 0 Lost msgs
+```
+
+On standby router run:
+
+```none
+$ show conntrack-sync statistics
+
+Main Table Statistics:
+
+cache internal:
+current active connections: 0
+connections created: 0 failed: 0
+connections updated: 0 failed: 0
+connections destroyed: 0 failed: 0
+
+cache external:
+current active connections: 10
+connections created: 888 failed: 0
+connections updated: 134 failed: 0
+connections destroyed: 878 failed: 0
+
+traffic processed:
+ 0 Bytes 0 Pckts
+
+multicast traffic (active device=eth0):
+ 234184 Bytes sent 907504 Bytes recv
+ 14663 Pckts sent 21495 Pckts recv
+ 0 Error send 0 Error recv
+
+message tracking:
+ 0 Malformed msgs 0 Lost msgs
+```
diff --git a/docs/configuration/service/console-server.md b/docs/configuration/service/console-server.md
new file mode 100644
index 00000000..9402e935
--- /dev/null
+++ b/docs/configuration/service/console-server.md
@@ -0,0 +1,139 @@
+(console-server)=
+
+# Console Server
+
+Starting of with VyOS 1.3 (equuleus) we added support for running VyOS as an
+Out-of-Band Management device which provides remote access by means of SSH to
+directly attached serial interfaces.
+
+Serial interfaces can be any interface which is directly connected to the CPU
+or chipset (mostly known as a ttyS interface in Linux) or any other USB to
+serial converter (Prolific PL2303 or FTDI FT232/FT4232 based chips).
+
+If you happened to use a Cisco NM-16A - Sixteen Port Async Network Module or
+NM-32A - Thirty-two Port Async Network Module - this is your VyOS replacement.
+
+For USB port information please refor to: {ref}`hardware_usb`.
+
+## Configuration
+
+Between computers, the most common configuration used was "8N1": eight bit
+characters, with one start bit, one stop bit, and no parity bit. Thus 10 Baud
+times are used to send a single character, and so dividing the signalling
+bit-rate by ten results in the overall transmission speed in characters per
+second. This is also the default setting if none of those options are defined.
+
+```{cfgcmd} set service console-server device \<device\> data-bits [7 | 8]
+
+Configure either seven or eight data bits. This defaults to eight data
+bits if left unconfigured.
+```
+
+
+```{cfgcmd} set service console-server device \<device\> description \<string\>
+
+A user friendly description identifying the connected peripheral.
+```
+
+
+```{cfgcmd} set service console-server device \<device\> alias \<string\>
+
+A user friendly alias for this connection. Can be used instead of the
+device name when connecting.
+```
+
+
+```{cfgcmd} set service console-server device \<device\> parity [even | odd | none]
+
+Set the parity option for the console. If unset this will default to none.
+```
+
+
+```{cfgcmd} set service console-server device \<device\> stop-bits [1 | 2]
+
+Configure either one or two stop bits. This defaults to one stop bits if
+left unconfigured.
+```
+
+
+```{cfgcmd} set service console-server device \<device\> speed [ 300 | 1200 | 2400 | 4800 | 9600 | 19200 | 38400 | 57600 | 115200 ]
+
+:::{note}
+USB to serial converters will handle most of their work in software
+so you should be carefull with the selected baudrate as some times they
+can't cope with the expected speed.
+:::
+```
+
+### Remote Access
+
+
+Each individual configured console-server device can be directly exposed to
+the outside world. A user can directly connect via SSH to the configured
+port.
+
+```{cfgcmd} set service console-server device \<device\> ssh port \<port\>
+
+Accept SSH connections for the given `<device>` on TCP port `<port>`.
+After successfull authentication the user will be directly dropped to
+the connected serial device.
+
+:::{hint}
+Multiple users can connect to the same serial device but only
+one is allowed to write to the console port.
+:::
+```
+
+## Operation
+
+```{opcmd} show console-server ports
+
+Show configured serial ports and their respective interface configuration.
+
+:::{code-block} none
+vyos@vyos:~$ show console-server ports
+usb0b2.4p1.0 on /dev/serial/by-bus/usb0b2.4p1.0@ at 9600n
+:::
+```
+
+
+```{opcmd} show console-server user
+
+Show currently connected users.
+
+:::{code-block} none
+vyos@vyos:~$ show console-server user
+usb0b2.4p1.0 up vyos@localhost
+:::
+```
+```{opcmd} connect console \<device\>
+
+Locally connect to serial port identified by `<device>`.
+
+:::{code-block} none
+vyos@vyos-r1:~$ connect console usb0b2.4p1.0
+[Enter `^Ec?' for help]
+[-- MOTD -- VyOS Console Server]
+
+vyos-r2 login:
+:::
+
+:::{hint}
+Multiple users can connect to the same serial device but only
+one is allowed to write to the console port.
+:::
+
+:::{hint}
+The sequence ``^Ec?`` translates to: ``Ctrl+E c ?``. To quit
+the session use: ``Ctrl+E c .``
+:::
+
+:::{hint}
+If ``alias`` is set, it can be used instead of the device when
+connecting.
+:::
+```
+```{opcmd} show log console-server
+
+Show the console server log.
+``` \ No newline at end of file
diff --git a/docs/configuration/service/dhcp-relay.md b/docs/configuration/service/dhcp-relay.md
new file mode 100644
index 00000000..a4a10109
--- /dev/null
+++ b/docs/configuration/service/dhcp-relay.md
@@ -0,0 +1,205 @@
+(dhcp-relay)=
+
+# DHCP Relay
+
+If you want your router to forward DHCP requests to an external DHCP server
+you can configure the system to act as a DHCP relay agent. The DHCP relay
+agent works with IPv4 and IPv6 addresses.
+
+All interfaces used for the DHCP relay must be configured. This includes the
+uplink to the DHCP server.
+
+## IPv4 relay
+
+### Configuration
+
+```{cfgcmd} set service dhcp-relay interface \<interface\>
+
+Interfaces that participate in the DHCP relay process. If this command is
+used, at least two entries of it are required: one for the interface that
+captures the dhcp-requests, and one for the interface to forward such
+requests. A warning message will be shown if this command is used, since
+new implementations should use ``listen-interface`` and
+``upstream-interface``.
+```
+
+```{cfgcmd} set service dhcp-relay listen-interface \<interface\>
+
+Interface for DHCP Relay Agent to listen for requests.
+```
+
+```{cfgcmd} set service dhcp-relay upstream-interface \<interface\>
+
+Interface for DHCP Relay Agent to forward requests out.
+```
+
+```{cfgcmd} set service dhcp-relay server \<server\>
+
+Configure IP address of the DHCP `<server>` which will handle the relayed
+packets.
+```
+
+```{cfgcmd} set service dhcp-relay relay-options relay-agents-packets discard
+
+The router should discard DHCP packages already containing relay agent
+information to ensure that only requests from DHCP clients are forwarded.
+```
+
+```{cfgcmd} set service dhcp-relay disable
+
+Disable dhcp-relay service.
+```
+
+
+#### Options
+
+```{cfgcmd} set service dhcp-relay relay-options hop-count \<count\>
+
+Set the maximum hop `<count>` before packets are discarded. Range 0...255,
+default 10.
+```
+
+```{cfgcmd} set service dhcp-relay relay-options max-size \<size\>
+
+Set maximum `<size>` of DHCP packets including relay agent information. If a
+DHCP packet size surpasses this value it will be forwarded without appending
+relay agent information. Range 64...1400, default 576.
+```
+
+```{cfgcmd} set service dhcp-relay relay-options relay-agents-packets \<append | discard | forward | replace\>
+
+Four policies for reforwarding DHCP packets exist:
+* **append:** The relay agent is allowed to append its own relay information
+to a received DHCP packet, disregarding relay information already present
+in the packet.
+* **discard:** Received packets which already contain relay information will
+be discarded.
+* **forward:** All packets are forwarded, relay information already present
+will be ignored.
+* **replace:** Relay information already present in a packet is stripped and
+replaced with the router's own relay information set.
+```
+
+
+### Example
+
+- Listen for DHCP requests on interface `eth1`.
+- DHCP server is located at IPv4 address 10.0.1.4 on `eth2`.
+- Router receives DHCP client requests on `eth1` and relays them to the
+ server at 10.0.1.4 on `eth2`.
+
+:::{figure} /_static/images/service_dhcp-relay01.webp
+:alt: DHCP relay example
+:scale: 80 %
+DHCP relay example
+:::
+
+The generated configuration will look like:
+
+```none
+show service dhcp-relay
+ listen-interface eth1
+ upstream-interface eth2
+ server 10.0.1.4
+ relay-options {
+ relay-agents-packets discard
+ }
+```
+
+Also, for backwards compatibility this configuration, which uses generic
+interface definition, is still valid:
+
+```none
+show service dhcp-relay
+ interface eth1
+ interface eth2
+ server 10.0.1.4
+ relay-options {
+ relay-agents-packets discard
+ }
+```
+
+
+### Operation
+
+```{opcmd} restart dhcp relay-agent
+
+Restart DHCP relay service
+```
+
+
+## IPv6 relay
+
+(dhcp-relay-ipv6-configuration)=
+
+### Configuration
+
+```{cfgcmd} set service dhcpv6-relay listen-interface \<interface\>
+
+Set eth1 to be the listening interface for the DHCPv6 relay.
+
+Multiple interfaces may be specified.
+```
+
+```{cfgcmd} set service dhcpv6-relay upstream-interface \<interface\> address \<server\>
+
+Specifies an upstream network `<interface>` from which replies from
+`<server>` and other relay agents will be accepted.
+```
+
+(dhcp-relay-ipv6-options)=
+
+```{cfgcmd} set service dhcpv6-relay disable
+
+Disable dhcpv6-relay service.
+```
+
+(dhcp-relay-v6-options)=
+
+#### Options
+
+```{cfgcmd} set service dhcpv6-relay max-hop-count \<count\>
+
+Set maximum hop count before packets are discarded, default: 10
+```
+
+```{cfgcmd} set service dhcpv6-relay use-interface-id-option
+
+If this is set the relay agent will insert the interface ID. This option is
+set automatically if more than one listening interfaces are in use.
+```
+
+(dhcp-relay-ipv6-example)=
+
+### Example
+
+- DHCPv6 requests are received by the router on `listening interface` `eth1`
+- Requests are forwarded through `eth2` as the `upstream interface`
+- External DHCPv6 server is at 2001:db8::4
+
+:::{figure} /_static/images/service_dhcpv6-relay01.webp
+:alt: DHCPv6 relay example
+:scale: 80 %
+DHCPv6 relay example
+:::
+
+The generated configuration will look like:
+
+```none
+commit
+show service dhcpv6-relay
+ listen-interface eth1 {
+ }
+ upstream-interface eth2 {
+ address 2001:db8::4
+ }
+```
+
+(dhcp-relay-ipv6-op-cmd)=
+
+### Operation
+
+```{opcmd} restart dhcpv6 relay-agent
+
+Restart DHCPv6 relay agent immediately.
+``` \ No newline at end of file
diff --git a/docs/configuration/service/dhcp-server.md b/docs/configuration/service/dhcp-server.md
new file mode 100644
index 00000000..96c375da
--- /dev/null
+++ b/docs/configuration/service/dhcp-server.md
@@ -0,0 +1,1178 @@
+(dhcp-server)=
+
+# DHCP Server
+
+VyOS uses Kea DHCP server for both IPv4 and IPv6 address assignment.
+
+## IPv4 server
+
+The network topology is declared by shared-network-name and the subnet
+declarations. The DHCP service can serve multiple shared networks, with each
+shared network having 1 or more subnets. Each subnet must be present on an
+interface. A range can be declared inside a subnet to define a pool of dynamic
+addresses. Multiple ranges can be defined and can contain holes. Static
+mappings can be set to assign "static" addresses to clients based on their MAC
+address.
+
+### Configuration
+
+```{cfgcmd} set service dhcp-server hostfile-update
+
+ Create DNS record per client lease, by adding clients to /etc/hosts file.
+ Entry will have format: `<shared-network-name>_<hostname>.<domain-name>`
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> option domain-name \<domain-name\>
+
+The domain-name parameter should be the domain name that will be appended to
+the client's hostname to form a fully-qualified domain-name (FQDN) (DHCP
+Option 015).
+
+This is the configuration parameter for the entire shared network definition.
+All subnets will inherit this configuration item if not specified locally.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> option domain-search \<domain-name\>
+
+The domain-name parameter should be the domain name used when completing DNS
+request where no full FQDN is passed. This option can be given multiple times
+if you need multiple search domains (DHCP Option 119).
+
+This is the configuration parameter for the entire shared network definition.
+All subnets will inherit this configuration item if not specified locally.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> option name-server \<address\>
+
+Inform client that the DNS server can be found at `<address>`.
+
+This is the configuration parameter for the entire shared network definition.
+All subnets will inherit this configuration item if not specified locally.
+Multiple DNS servers can be defined.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> option vendor-option \<option-name\>
+
+This configuration parameter lets you specify a vendor-option for the
+entire shared network definition. All subnets will inherit this
+configuration item if not specified locally. An example for Ubiquiti is
+shown below:
+```
+
+**Example:**
+
+
+Pass address of Unifi controller at `172.16.100.1` to all clients of `NET1`
+
+```none
+set service dhcp-server shared-network-name 'NET1' option vendor-option
+ubiquiti '172.16.100.1'
+```
+
+
+```{cfgcmd} set service dhcp-server listen-address \<address\>
+
+This configuration parameter lets the DHCP server to listen for DHCP
+requests sent to the specified address, it is only realistically useful for
+a server whose only clients are reached via unicasts, such as via DHCP relay
+agents.
+```
+
+#### Individual Client Subnet
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> authoritative
+
+This says that this device is the only DHCP server for this network. If other
+devices are trying to offer DHCP leases, this machine will send 'DHCPNAK' to
+any device trying to request an IP address that is not valid for this
+network.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> subnet-id \<id\>
+
+This configuration parameter is required and must be unique to each subnet.
+It is required to map subnets to lease file entries.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> option default-router \<address\>
+
+This is a configuration parameter for the `<subnet>`, saying that as part of
+the response, tell the client that the default gateway can be reached at
+`<address>`.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> option name-server \<address\>
+
+This is a configuration parameter for the subnet, saying that as part of the
+response, tell the client that the DNS server can be found at `<address>`.
+
+Multiple DNS servers can be defined.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> lease \<time\>
+
+Assign the IP address to this machine for `<time>` seconds.
+
+The default value is 86400 seconds which corresponds to one day.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> range \<n\> start \<address\>
+
+Create DHCP address range with a range id of `<n>`. DHCP leases are taken
+from this pool. The pool starts at address `<address>`.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> range \<n\> stop \<address\>
+
+Create DHCP address range with a range id of `<n>`. DHCP leases are taken
+from this pool. The pool stops with address `<address>`.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> exclude \<address\>
+
+Always exclude this address from any defined range. This address will never
+be assigned by the DHCP server.
+
+This option can be specified multiple times.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> option domain-name \<domain-name\>
+
+The domain-name parameter should be the domain name that will be appended to
+the client's hostname to form a fully-qualified domain-name (FQDN) (DHCP
+Option 015).
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> option domain-search \<domain-name\>
+
+The domain-name parameter should be the domain name used when completing DNS
+request where no full FQDN is passed. This option can be given multiple times
+if you need multiple search domains (DHCP Option 119).
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> option vendor-option \<option-name\>
+
+This configuration parameter lets you specify a vendor-option for the
+subnet specified within the shared network definition. An example for
+Ubiquiti is shown below:
+```
+
+**Example:**
+
+
+Create `172.18.201.0/24` as a subnet within `NET1` and pass address of
+Unifi controller at `172.16.100.1` to clients of that subnet.
+
+```none
+set service dhcp-server shared-network-name 'NET1' subnet
+'172.18.201.0/24' option vendor-option ubiquiti '172.16.100.1'
+```
+
+#### Dynamic DNS Update (RFC 2136)
+
+
+VyOS DHCP service supports RFC-2136 DDNS protocol. Based on DHCP lease change
+events, DHCP server generates DDNS update requests (defines as NameChangeRequests
+or NCRs) and posts them to a compliant DNS server, that will update its name
+database accordingly.
+
+
+VyOS built-in DNS Forwarder does not support DDNS, you will need an external DNS
+server with RFC-2136 DDNS support.
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update
+
+Enables DDNS globally.
+```
+
+**Behavioral settings**
+
+
+These settings can be configured on the global level and overridden on the scope
+level, i.e. for individual shared networks or subnets. See examples below.
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update send-updates [ enable | disable ]
+
+If set to ``enable`` on global level, updates for all scopes will be enabled,
+except if explicitly set to ``disable`` on the scope level. If set to ``disable``,
+updates will only be sent for scopes, where ``send-updates`` is explicity
+set to ``enable``.
+
+This model is followed for a few behavioral settings below: if the option is
+not set, the setting is inherited from the parent scope. You can override the
+parent scope setting by setting the option explicitly.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update override-no-update [ enable | disable ]
+
+VyOS will ignore client request not to update DNS records and send DDNS
+update requests regardless.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update override-client-update [ enable | disable ]
+
+VyOS will override client DDNS request settings and always update both
+forward and reverse DNS records.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update update-on-renew [ enable | disable ]
+
+Issue DDNS update requests on DHCP lease renew. In busy networks this may
+generate a lot of traffic.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update conflict-resolution [ enable | disable ]
+
+Use RFC-4703 conflict resolution. This algorithm helps in situation when
+multiple clients reserve same IP addresses or advertise identical hostnames.
+Should be used in most situations.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update replace-client-name [ never | always | when-present | when-not-present ]
+
+* **never**: use the name sent by the client. If the client didn't provide any,
+do not generate one. This is the default behavior
+
+* **always**: always generate a name for the client
+
+* **when-present**: replace the name the client sent with a generated one, if
+the client didn't send any, do not generate one
+
+* **when-not-present**: use the name sent by the client. If the client didn't
+send any, generate one for the client
+
+The names are generated using ``generated-prefix``, ``qualifying-suffix`` and the
+client's IP address string.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update generated-prefix \<prefix\>
+
+Prefix used in client name generation.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update qualifying-suffix \<suffix\>
+
+DNS suffix used in client name generation.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update ttl-percent \<0-100\>
+
+TTL of the DNS record as a percentage of the DHCP lease time.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update hostname-char-set \<character string\>
+
+Characters, that are considered invalid in the client name. They will be replaced
+with ``hostname-char-replacement`` string.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update hostname-char-replacement \<character string\>
+
+Replacement string for the invalid characters defined by ``hostname-char-set``.
+```
+
+**TSIG keys definition**
+
+
+This is the global list of TSIG keys for DDNS updates. They need to be specified by
+the name in the DNS domain definitions.
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update tsig-key \<key-name\> algorithm \<algorithm\>
+
+Sets the algorithm for the TSIG key. Supported algorithms are ``hmac-md5``,
+``hmac-sha1``, ``hmac-sha224``, ``hmac-sha256``, ``hmac-sha384``, ``hmac-sha512``
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update tsig-key \<key-name\> secret \<key-secret\>
+
+base64-encoded TSIG key secret value
+```
+
+**DNS domains definition**
+
+
+This is global configuration of DNS servers for the updatable forward and reverse
+DNS domains. For every domain multiple DNS servers can be specified.
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update [forward|reverse]-domain \<domain-name\> key-name \<tsig-key-name\>
+
+TSIG key used for the domain.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update [forward|reverse]-domain \<domain-name\> dns-server \<number\> address \<ip-address\>
+
+IP address of the DNS server.
+```
+
+
+```{cfgcmd} set service dhcp-server dynamic-dns-update [forward|reverse]-domain \<domain-name\> dns-server \<number\> port \<port\>
+
+UDP port of the DNS server. ``53`` is the default.
+```
+
+**Example:**
+
+
+Global configuration you will most likely want:
+
+```none
+set service dhcp-server dynamic-dns-update send-updates enable
+set service dhcp-server dynamic-dns-update conflict-resolution enable
+```
+
+Override the above configuration for a shared network NET1:
+
+```none
+set service dhcp-server shared-network-name 'NET1' dynamic-dns-update replace-client-name when-not-present
+set service dhcp-server shared-network-name 'NET1' dynamic-dns-update generated-prefix ip
+set service dhcp-server shared-network-name 'NET1' dynamic-dns-update qualifying-suffix mybigdomain.net
+```
+
+And in a subnet within the same shared network:
+
+```none
+set service dhcp-server shared-network-name 'NET1' subnet '172.18.201.0/24' dynamic-dns-update qualifying-suffix mydomain.net
+```
+
+Configure TSIG keys:
+
+```none
+set service dhcp-server dynamic-dns-update tsig-key mydomain-net algorithm hmac-sha256
+set service dhcp-server dynamic-dns-update tsig-key mydomain-net secret eWF5YW15bGl0dGxla2V5IQ==
+set service dhcp-server dynamic-dns-update tsig-key reverse-172-18-201 algorithm hmac-sha256
+set service dhcp-server dynamic-dns-update tsig-key reverse-172-18-201 secret eWF5YW15YW5vdGhlcmxpdHRsZWtleSE=
+```
+
+Configure DDNS domains:
+
+```none
+set service dhcp-server dynamic-dns-update forward-domain mydomain.net key-name mydomain-net
+set service dhcp-server dynamic-dns-update forward-domain mydomain.net dns-server 1 address '172.18.0.254'
+set service dhcp-server dynamic-dns-update forward-domain mydomain.net dns-server 1 port 1053
+set service dhcp-server dynamic-dns-update forward-domain mydomain.net dns-server 2 address '192.168.124.254'
+set service dhcp-server dynamic-dns-update forward-domain mydomain.net dns-server 2 port 53
+set service dhcp-server dynamic-dns-update forward-domain 201.18.172.in-addr.arpa key-name reverse-172-18-201
+set service dhcp-server dynamic-dns-update reverse-domain 201.18.172.in-addr.arpa dns-server 1 address '172.18.0.254'
+set service dhcp-server dynamic-dns-update reverse-domain 201.18.172.in-addr.arpa dns-server 1 port 1053
+set service dhcp-server dynamic-dns-update reverse-domain 201.18.172.in-addr.arpa dns-server 2 address '192.168.124.254'
+set service dhcp-server dynamic-dns-update reverse-domain 201.18.172.in-addr.arpa dns-server 2 port 53
+```
+
+#### High Availability
+
+
+VyOS provides High Availability support for DHCP server. DHCP High
+Availability can act in two different modes:
+
+
+- **Active-active**: both DHCP servers will respond to DHCP requests. If
+ `mode` is not defined, this is the default behavior.
+- **Active-passive**: only `primary` server will respond to DHCP requests.
+ If this server goes offline, then `secondary` server will take place.
+
+
+DHCP High Availability must be configured explicitly by the following
+statements on both servers:
+
+```{cfgcmd} set service dhcp-server high-availability mode [active-active | active-passive]
+
+Define operation mode of High Availability feature. Default value if command
+is not specified is `active-active`
+```
+
+
+```{cfgcmd} set service dhcp-server high-availability source-address \<address\>
+
+Local IP `<address>` used when communicating to the HA peer.
+```
+
+
+```{cfgcmd} set service dhcp-server high-availability remote \<address\>
+
+Remote peer IP `<address>` of the second DHCP server in this HA
+cluster.
+```
+
+
+```{cfgcmd} set service dhcp-server high-availability name \<name\>
+
+Define the name of the peer server to establish and identify the HA (High Availability) connection.
+
+:::{note}
+Make sure the specified value does not conflict with the system host-name.
+:::
+```
+
+
+```{cfgcmd} set service dhcp-server high-availability status \<primary | secondary\>
+
+The primary and secondary statements determines whether the server is primary
+or secondary.
+
+:::{note}
+In order for the primary and the secondary DHCP server to keep
+their lease tables in sync, they must be able to reach each other on TCP
+port 647. If you have firewall rules in effect, adjust them accordingly.
+:::
+:::{hint}
+The dialogue between HA partners is neither encrypted nor
+authenticated. Since most DHCP servers exist within an organisation's own
+secure Intranet, this would be an unnecessary overhead. However, if you
+have DHCP HA peers whose communications traverse insecure networks,
+then we recommend that you consider the use of VPN tunneling between them
+to ensure that the HA partnership is immune to disruption
+(accidental or otherwise) via third parties.
+:::
+```
+
+#### Static mappings
+
+
+You can specify a static DHCP assignment on a per host basis. You will need the
+MAC address of the station and your desired IP address. The address must be
+inside the subnet definition but can be outside of the range statement.
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> static-mapping \<description\> mac \<address\>
+
+Create a new DHCP static mapping named `<description>` which is valid for
+the host identified by its MAC `<address>`.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> static-mapping \<description\> duid \<identifier\>
+
+Create a new DHCP static mapping named `<description>` which is valid for
+the host identified by its DHCP unique identifier (DUID) `<identifier>`.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<name\> subnet \<subnet\> static-mapping \<description\> ip-address \<address\>
+
+Static DHCP IP address assign to host identified by `<description>`. IP
+address must be inside the `<subnet>` which is defined but can be outside
+the dynamic range created with {cfgcmd}`set service dhcp-server
+shared-network-name <name> subnet <subnet> range <n>`. If no ip-address is
+specified, an IP from the dynamic pool is used.
+
+This is useful, for example, in combination with hostfile update.
+
+:::{hint}
+This is the equivalent of the host block in dhcpd.conf of
+isc-dhcpd.
+:::
+```
+
+**Example:**
+
+
+- IP address `192.168.1.100` shall be statically mapped to client named `client1`
+
+```none
+set service dhcp-server shared-network-name 'NET1' subnet 192.168.1.0/24 subnet-id 1
+set service dhcp-server shared-network-name 'NET1' subnet 192.168.1.0/24 static-mapping client1 ip-address 192.168.1.100
+set service dhcp-server shared-network-name 'NET1' subnet 192.168.1.0/24 static-mapping client1 mac aa:bb:11:22:33:00
+```
+
+The configuration will look as follows:
+
+```none
+show service dhcp-server shared-network-name NET1
+ subnet 192.168.1.0/24 {
+ static-mapping client1 {
+ ip-address 192.168.1.100
+ mac aa:bb:11:22:33:00
+ }
+ subnet-id 1
+ }
+```
+
+#### Relay agent information (Option 82)
+
+
+Some DHCP relays support the injection of information into a DHCP request, depending on
+where the request originated from. This is commonly used to determine the
+behaviour of the DHCP server, based on the port/switch combination where the
+request was first detected. I.e. the device plugged into a particular port (or
+set of ports) always gets the same IP address (or range of IP addresses). This
+information is usually included in the request using Option 82, hence this
+is what we call this part of the configuration.
+
+
+This behaviour is controlled in two parts. First, "client classes" are defined
+which determine which inputs match. Once a positive match has been found the
+request is "tagged" with this client class. Second, when the DHCP server
+processes the request it checks to see if the configuration has a client class
+defined. If it does then that part of the configuration will override the others
+
+
+Client classes can be applied at either the subnet or range level, depending on
+how you want the server to behave.
+
+
+**Client Class definition**
+
+```{cfgcmd} set service dhcp-server client-class \<name\> relay-agent-information circuit-id \<value\>
+
+Create a new client class (if not already defined) and set it to match on
+the "Circuit ID" part of the Option 82 field in the DHCP request. This is
+sub option "1" as specified by RFC 3046. The value specified here is either
+interpreted as a raw hex value, if it starts with the prefix 0x, or ASCII text
+otherwise. e.g. ``e1-5`` and ``0x65312d35`` are the same
+```
+
+
+```{cfgcmd} set service dhcp-server client-class \<name\> relay-agent-information remote-id \<value\>
+
+Create a new client class (if not already defined) and set it to match on
+the "Remote ID" part of the Option 82 field in the DHCP request. This is
+sub option "2" as specified by RFC 3046. The value specified here is either
+interpreted as a raw hex value, if it starts with the prefix 0x, or ASCII text
+otherwise. e.g. ``10.100.0.41`` and ``0x31302e3130302e302e3431`` are the
+same
+```
+
+**Client Class application**
+
+```{cfgcmd} set service dhcp-server shared-network-name \<subnet-name\> subnet \<CIDR\> client-class \<class-name\>
+
+Applies the Client Class with the name `<class-name>` to the subnet `<subnet-name>`.
+This means that whenever the client class matches a request it is always
+routed to this subnet definition first.
+```
+
+
+```{cfgcmd} set service dhcp-server shared-network-name \<subnet-name\> subnet \<CIDR\> range \<range-name\> client-class \<class-name\>
+
+Applies the Client Class with the name `<class-name>` to the range
+`<range-name>` which belongs to subnet `<subnet-name>`. This means that whenever the
+client class matches a request it is always routed to this range definition
+first.
+```
+
+NB: Kea (the DHCP server used by VyOS) is programmed to offer as many
+alternatives as it can to repeated DHCP Discover requests. Some operating
+systems (Notably Microsoft Windows) make multiple DHCP Discover requests before
+settling on an address. This particularly seems to happen when the DHCP server
+isn't set to authorative. This may explain why the address you espect isn't
+being chosen. Wireshark is helpful in these situations.
+
+
+**Example:**
+
+
+The following configuration example will classify requests coming in on port
+`e1-5` from DHCP Relay `192.0.2.1` and make sure that they are allocated the
+address `192.0.2.4`. Any requests which do not match the circuit and remote ID
+will, instead, be allocated from the range otherRange in the usual manner.
+
+
+NB: Both the Circuit ID and Remote ID fields are arbitrary free text. *Most*
+switches set the Remote ID to the IP address of the management interface but
+that should not be relied upon. Check the documentation of your DHCP Relay for
+more detail or, as a measure of last resort, inspect the DHCP requests in
+Wireshark.
+
+```none
+service {
+ dhcp-server {
+ client-class className {
+ relay-agent-information {
+ circuit-id e1-5
+ remote-id 192.0.2.1
+ }
+ }
+ shared-network-name test {
+ subnet 192.0.2.0/24 {
+ range classNameRange {
+ client-class className
+ start 192.0.2.4
+ stop 192.0.2.4
+ }
+ range otherRange {
+ start 192.0.2.5
+ stop 192.0.2.100
+ }
+ subnet-id 1
+ }
+ }
+ }
+}
+```
+
+### Options
+
+
+:::{list-table}
+:header-rows: 1
+:stub-columns: 0
+:widths: 12 7 23 40 20
+
+* - Setting name
+ - Option number
+ - ISC-DHCP Option name
+ - Option description
+ - Multi
+* - client-prefix-length
+ - 1
+ - subnet-mask
+ - Specifies the clients subnet mask as per RFC 950. If unset,
+ subnet declaration is used.
+ - N
+* - time-offset
+ - 2
+ - time-offset
+ - Offset of the client's subnet in seconds from Coordinated
+ Universal Time (UTC)
+ - N
+* - default-router
+ - 3
+ - routers
+ - IPv4 address of router on the client's subnet
+ - N
+* - time-server
+ - 4
+ - time-servers
+ - RFC 868 time server IPv4 address
+ - Y
+* - name-server
+ - 6
+ - domain-name-servers
+ - DNS server IPv4 address
+ - Y
+* - domain-name
+ - 15
+ - domain-name
+ - Client domain name
+ - Y
+* - ip-forwarding
+ - 19
+ - ip-forwarding
+ - Enable IP forwarding on client
+ - N
+* - ntp-server
+ - 42
+ - ntp-servers
+ - IP address of NTP server
+ - Y
+* - wins-server
+ - 44
+ - netbios-name-servers
+ - NetBIOS over TCP/IP name server
+ - Y
+* - server-identifier
+ - 54
+ - dhcp-server-identifier
+ - IP address for DHCP server identifier
+ - N
+* - bootfile-server
+ - siaddr
+ - next-server
+ - IPv4 address of next bootstrap server
+ - N
+* - tftp-server-name
+ - 66
+ - tftp-server-name
+ - Name or IPv4 address of TFTP server
+ - N
+* - bootfile-name
+ - 67
+ - bootfile-name, filename
+ - Bootstrap file name
+ - N
+* - bootfile-size
+ - 13
+ - boot-size
+ - Boot image length in 512-octet blocks
+ - N
+* - smtp-server
+ - 69
+ - smtp-server
+ - IP address of SMTP server
+ - Y
+* - pop-server
+ - 70
+ - pop-server
+ - IP address of POP3 server
+ - Y
+* - domain-search
+ - 119
+ - domain-search
+ - Client domain search
+ - Y
+* - static-route
+ - 121, 249
+ - rfc3442-static-route, windows-static-route
+ - Classless static route
+ - N
+* - wpad-url
+ - 252
+ - wpad-url, wpad-url code 252 = text
+ - Web Proxy Autodiscovery (WPAD) URL
+ - N
+* - lease
+ -
+ - default-lease-time, max-lease-time
+ - Lease timeout in seconds (default: 86400)
+ - N
+* - range
+ -
+ - range
+ - DHCP lease range
+ - Y
+* - exclude
+ -
+ -
+ - IP address to exclude from DHCP lease range
+ - Y
+* - failover
+ -
+ -
+ - DHCP failover parameters
+ -
+* - static-mapping
+ -
+ -
+ - Name of static mapping
+ - Y
+:::
+
+
+Multi: can be specified multiple times.
+
+
+### Example
+
+
+Please see the {ref}`dhcp-dns-quick-start` configuration.
+
+
+(dhcp-server-v4-example-failover)=
+
+
+#### High Availability
+
+
+Configuration of a DHCP HA pair:
+
+
+- Setup DHCP HA for network 192.0.2.0/24
+- Use active-active HA mode.
+- Default gateway and DNS server is at `192.0.2.254`
+- The primary DHCP server named dhcp-primary uses address `192.168.189.252`
+- The secondary DHCP server with named dhcp-secondary uses address `192.168.189.253`
+- DHCP range spans from `192.168.189.10` - `192.168.189.250`
+
+
+Common configuration, valid for both primary and secondary node.
+
+```none
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 option default-router '192.0.2.254'
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 option name-server '192.0.2.254'
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 option domain-name 'vyos.net'
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 range 0 start '192.0.2.10'
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 range 0 stop '192.0.2.250'
+set service dhcp-server shared-network-name NET-VYOS subnet 192.0.2.0/24 subnet-id '1'
+```
+
+**Primary**
+
+```none
+set service dhcp-server high-availability mode 'active-active'
+set service dhcp-server high-availability source-address '192.168.189.252'
+set service dhcp-server high-availability name 'dhcp-secondary'
+set service dhcp-server high-availability remote '192.168.189.253'
+set service dhcp-server high-availability status 'primary'
+```
+
+**Secondary**
+
+```none
+set service dhcp-server high-availability mode 'active-active'
+set service dhcp-server high-availability source-address '192.168.189.253'
+set service dhcp-server high-availability name 'dhcp-primary'
+set service dhcp-server high-availability remote '192.168.189.252'
+set service dhcp-server high-availability status 'secondary'
+```
+
+(dhcp-server-v4-example-raw)=
+
+
+### Operation Mode
+
+```{opcmd} show log dhcp server
+
+Show DHCP server daemon log file
+```
+
+
+```{opcmd} show log dhcp client
+
+Show logs from all DHCP client processes.
+```
+
+
+```{opcmd} show log dhcp client interface \<interface\>
+
+Show logs from specific `interface` DHCP client process.
+```
+
+
+```{opcmd} restart dhcp server
+
+Restart the DHCP server
+```
+
+
+```{opcmd} show dhcp server statistics
+
+Show the DHCP server statistics:
+```
+
+
+```none
+vyos@vyos:~$ show dhcp server statistics
+Pool Size Leases Available Usage
+----------- ------ -------- ----------- -------
+dhcpexample 99 2 97 2%
+```
+
+
+```{opcmd} show dhcp server statistics pool \<pool\>
+
+Show the DHCP server statistics for the specified pool.
+```
+
+
+```{opcmd} show dhcp server leases
+
+Show statuses of all active leases:
+```
+
+
+```none
+vyos@vyos:~$ show dhcp server leases
+IP Address MAC address State Lease start Lease expiration Remaining Pool Hostname Origin
+-------------- ----------------- ------- ------------------- ------------------- ----------- -------- ---------- --------
+192.168.11.134 00:50:79:66:68:09 active 2023/11/29 09:51:05 2023/11/29 10:21:05 0:24:10 LAN VPCS1 local
+192.168.11.133 50:00:00:06:00:00 active 2023/11/29 09:51:38 2023/11/29 10:21:38 0:24:43 LAN VYOS-6 local
+10.11.11.108 50:00:00:05:00:00 active 2023/11/29 09:51:43 2023/11/29 10:21:43 0:24:48 VIF-1001 VYOS5 local
+192.168.11.135 00:50:79:66:68:07 active 2023/11/29 09:55:16 2023/11/29 09:59:16 0:02:21 remote
+vyos@vyos:~$
+```
+
+:::{hint}
+Static mappings aren't shown. To show all states, use
+`show dhcp server leases state all`.
+:::
+
+```{opcmd} show dhcp server leases origin [local | remote]
+
+Show statuses of all active leases granted by local (this server) or
+remote (failover server):
+```
+
+
+```none
+vyos@vyos:~$ show dhcp server leases origin remote
+IP Address MAC address State Lease start Lease expiration Remaining Pool Hostname Origin
+-------------- ----------------- ------- ------------------- ------------------- ----------- -------- ---------- --------
+192.168.11.135 00:50:79:66:68:07 active 2023/11/29 09:55:16 2023/11/29 09:59:16 0:02:21 remote
+vyos@vyos:~$
+```
+
+
+```{opcmd} show dhcp server leases pool \<pool\>
+
+Show only leases in the specified pool.
+```
+
+
+```none
+vyos@vyos:~$ show dhcp server leases pool LAN
+IP Address MAC address State Lease start Lease expiration Remaining Pool Hostname Origin
+-------------- ----------------- ------- ------------------- ------------------- ----------- ------ ---------- --------
+192.168.11.134 00:50:79:66:68:09 active 2023/11/29 09:51:05 2023/11/29 10:21:05 0:23:55 LAN VPCS1 local
+192.168.11.133 50:00:00:06:00:00 active 2023/11/29 09:51:38 2023/11/29 10:21:38 0:24:28 LAN VYOS-6 local
+vyos@vyos:~$
+```
+
+
+```{opcmd} show dhcp server leases sort \<key\>
+
+Sort the output by the specified key. Possible keys: ip, hardware_address,
+state, start, end, remaining, pool, hostname (default = ip)
+```
+
+
+```{opcmd} show dhcp server leases state \<state\>
+
+Show only leases with the specified state. Possible states: all, active,
+free, expired, released, abandoned, reset, backup (default = active)
+```
+
+## IPv6 server
+
+VyOS also provides DHCPv6 server functionality which is described in this
+section.
+(dhcp-server-v6-config)=
+
+### Configuration
+
+```{cfgcmd} set service dhcpv6-server preference \<preference value\>
+
+ Clients receiving advertise messages from multiple servers choose the server
+ with the highest preference value. The range for this value is ``0...255``.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<subnet\> subnet-id \<id\>
+
+This configuration parameter is required and must be unique to each subnet.
+It is required to map subnets to lease file entries.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> lease-time {default | maximum | minimum}
+
+The default lease time for DHCPv6 leases is 24 hours. This can be changed by
+supplying a ``default-time``, ``maximum-time`` and ``minimum-time``. All
+values need to be supplied in seconds.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option nis-domain \<domain-name\>
+
+A {abbr}`NIS (Network Information Service)` domain can be set to be used for
+DHCPv6 clients.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option nisplus-domain \<domain-name\>
+
+The procedure to specify a {abbr}`NIS+ (Network Information Service Plus)`
+domain is similar to the NIS domain one:
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option nis-server \<address\>
+
+Specify a NIS server address for DHCPv6 clients.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option nisplus-server \<address\>
+
+Specify a NIS+ server address for DHCPv6 clients.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option sip-server \<address | fqdn\>
+
+Specify a {abbr}`SIP (Session Initiation Protocol)` server by IPv6
+address of Fully Qualified Domain Name for all DHCPv6 clients.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> option sntp-server-address \<address\>
+
+A SNTP server address can be specified for DHCPv6 clients.
+```
+
+#### Prefix Delegation
+
+
+To hand out individual prefixes to your clients the following configuration is
+used:
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> prefix-delegation prefix \<pd-prefix\> prefix-length \<lenght\>
+
+Delegate prefixes from `<pd-prefix>` to clients in subnet `<prefix>`. Range
+is defined by `<lenght>` in bits, 32 to 64.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> prefix-delegation prefix \<pd-prefix\> delegated-length \<lenght\>
+
+Hand out prefixes of size `<length>` in bits from `<pd-prefix>` to clients
+in subnet `<prefix>` when the request for prefix delegation.
+```
+
+
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> prefix-delegation prefix \<pd-prefix\> excluded-prefix \<exclude-prefix\>
+
+Exclude `<exclude-prefix>` from `<pd-prefix>`.
+```
+```{cfgcmd} set service dhcpv6-server shared-network-name \<name\> subnet \<prefix\> prefix-delegation prefix \<pd-prefix\> excluded-prefix-length \<length\>
+
+Define lenght of exclude prefix in `<pd-prefix>`.
+```
+
+**Example:**
+- A shared network named `PD-NET` serves subnet `2001:db8::/64`.
+- It is connected to `eth1`.
+- Address pool shall be `2001:db8::100` through `2001:db8::199`.
+- It hands out prefixes `2001:db8:0:10::/64` through `2001:db8:0:1f::/64`.
+
+```none
+set service dhcpv6-server shared-network-name 'PD-NET' interface 'eth1'
+set service dhcpv6-server shared-network-name 'PD-NET' subnet 2001:db8::/64 range 1 start 2001:db8::100
+set service dhcpv6-server shared-network-name 'PD-NET' subnet 2001:db8::/64 range 1 stop 2001:db8::199
+set service dhcpv6-server shared-network-name 'PD-NET' subnet 2001:db8::/64 prefix-delegation prefix 2001:db8:0:10:: delegated-length '64'
+set service dhcpv6-server shared-network-name 'PD-NET' subnet 2001:db8::/64 prefix-delegation prefix 2001:db8:0:10:: prefix-length '60'
+set service dhcpv6-server shared-network-name 'PD-NET' subnet 2001:db8::/64 subnet-id 1
+```
+
+#### Address pools
+
+DHCPv6 address pools must be configured for the system to act as a DHCPv6
+server. The following example describes a common scenario.
+
+**Example:**
+- A shared network named `NET1` serves subnet `2001:db8::/64`
+- It is connected to `eth1`
+- DNS server is located at `2001:db8::ffff`
+- Address pool shall be `2001:db8::100` through `2001:db8::199`.
+- Lease time will be left at the default value which is 24 hours
+
+```none
+set service dhcpv6-server shared-network-name 'NET' interface 'eth1'
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 range 1 start 2001:db8::100
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 range 1 stop 2001:db8::199
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 option name-server 2001:db8::ffff
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 subnet-id 1
+```
+
+The configuration will look as follows:
+
+```none
+show service dhcpv6-server
+ shared-network-name NET1 {
+ subnet 2001:db8::/64 {
+ range 1 {
+ start 2001:db8::100
+ stop 2001:db8::199
+ }
+ option {
+ name-server 2001:db8::ffff
+ }
+ subnet-id 1
+ }
+ }
+```
+
+(dhcp-server-v6-static-mapping)=
+
+#### Static mappings
+
+In order to map specific IPv6 addresses to specific hosts static mappings can
+be created. The following example explains the process.
+
+**Example:**
+- IPv6 address `2001:db8::101` shall be statically mapped
+- IPv6 prefix `2001:db8:0:101::/64` shall be statically mapped
+- Host specific mapping shall be named `client1`
+
+:::{hint}
+The identifier is the device's DUID: colon-separated hex list (as
+used by isc-dhcp option dhcpv6.client-id). If the device already has a
+dynamic lease from the DHCPv6 server, its DUID can be found with `show
+service dhcpv6 server leases`. The DUID begins at the 5th octet (after the
+4th colon) of IAID_DUID.
+:::
+```none
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 static-mapping client1 ipv6-address 2001:db8::101
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 static-mapping client1 ipv6-prefix 2001:db8:0:101::/64
+set service dhcpv6-server shared-network-name 'NET1' subnet 2001:db8::/64 static-mapping client1 duid 00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:ff
+```
+
+The configuration will look as follows:
+
+```none
+show service dhcpv6-server shared-network-name NET1
+ subnet 2001:db8::/64 {
+ static-mapping client1 {
+ duid 00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:ff
+ ipv6-address 2001:db8::101
+ ipv6-prefix 2001:db8:0:101::/64
+ }
+ }
+```
+
+(dhcp-server-v6-op-cmd)=
+
+### Operation Mode
+
+```{opcmd} show log dhcpv6 server
+
+Show DHCPv6 server daemon log file
+```
+```{opcmd} show log dhcpv6 client
+
+Show logs from all DHCPv6 client processes.
+```
+```{opcmd} show log dhcpv6 client interface \<interface\>
+
+Show logs from specific `interface` DHCPv6 client process.
+```
+```{opcmd} restart dhcpv6 server
+
+To restart the DHCPv6 server
+```
+```{opcmd} show dhcpv6 server leases
+
+Shows status of all assigned leases:
+```
+```none
+vyos@vyos:~$ show dhcpv6 server leases
+IPv6 address State Last communication Lease expiration Remaining Type Pool DUID
+---------------- ------- -------------------- ------------------- ----------- ----- -------- --------------------------------------------
+2001:db8::101 active 2019/12/05 19:40:10 2019/12/06 07:40:10 11:45:21 IA_NA NET1 98:76:54:32:00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:ff
+2001:db8::102 active 2019/12/05 14:01:23 2019/12/06 02:01:23 6:06:34 IA_NA NET1 87:65:43:21:00:01:00:01:11:22:33:44:fa:fb:fc:fd:fe:ff
+2001:db8:10::/64 active 2019/12/05 23:20:10 2019/12/06 11:40:10 11:45:21 IA_PD PD-NET1 98:76:54:32:00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:ff
+```
+
+:::{hint}
+Static mappings aren't shown. To show all states, use `show dhcp
+server leases state all`.
+:::
+
+```{opcmd} show dhcpv6 server leases pool \<pool\>
+
+Show only leases in the specified pool.
+```
+```{opcmd} show dhcpv6 server leases sort \<key\>
+
+Sort the output by the specified key. Possible keys: expires, iaid_duid, ip,
+last_comm, pool, remaining, state, type (default = ip)
+```
+```{opcmd} show dhcpv6 server leases state \<state\>
+
+Show only leases with the specified state. Possible states: abandoned,
+active, all, backup, expired, free, released, reset (default = active)
+``` \ No newline at end of file
diff --git a/docs/configuration/service/dns.md b/docs/configuration/service/dns.md
new file mode 100644
index 00000000..e7e9b457
--- /dev/null
+++ b/docs/configuration/service/dns.md
@@ -0,0 +1,582 @@
+(dns-forwarding)=
+
+# DNS Forwarding
+
+## Configuration
+
+VyOS provides DNS infrastructure for small networks. It is designed to be
+lightweight and have a small footprint, suitable for resource constrained
+routers and firewalls. For this we utilize PowerDNS recursor.
+
+The VyOS DNS forwarder does not require an upstream DNS server. It can serve as
+a full recursive DNS server - but it can also forward queries to configurable
+upstream DNS servers. By not configuring any upstream DNS servers you also
+avoid being tracked by the provider of your upstream DNS server.
+
+```{cfgcmd} set service dns forwarding system
+
+ Forward incoming DNS queries to the DNS servers configured under the ``system
+ name-server`` nodes.
+```
+
+
+```{cfgcmd} set service dns forwarding dhcp \<interface\>
+
+Interfaces whose DHCP client nameservers to forward requests to.
+```
+
+
+```{cfgcmd} set service dns forwarding name-server \<address\> port \<port\>
+
+Send all DNS queries to the IPv4/IPv6 DNS server specified under `<address>`
+on optional port specified under `<port>`. The port defaults to 53. You can
+configure multiple nameservers here.
+```
+
+
+```{cfgcmd} set service dns forwarding domain \<domain-name\> name-server \<address\>
+
+Forward received queries for a particular domain
+(specified via `domain-name`) to a given nameserver. Multiple nameservers
+can be specified. You can use this feature for a DNS split-horizon
+configuration.
+
+:::{note}
+This also works for reverse-lookup zones (``18.172.in-addr.arpa``).
+:::
+```
+
+
+```{cfgcmd} set service dns forwarding domain \<domain-name\> addnta
+
+Add NTA (negative trust anchor) for this domain. This must be set if the
+domain does not support DNSSEC.
+```
+
+
+```{cfgcmd} set service dns forwarding domain \<domain-name\> recursion-desired
+
+Set the "recursion desired" bit in requests to the upstream nameserver.
+```
+
+
+```{cfgcmd} set service dns forwarding allow-from \<network\>
+
+Given the fact that open DNS recursors could be used on DDoS amplification
+attacks, you must configure the networks which are allowed to use this
+recursor. A network of ``0.0.0.0/0`` or ``::/0`` would allow all IPv4 and
+IPv6 networks to query this server. This is generally a bad idea.
+```
+
+
+```{cfgcmd} set service dns forwarding dnssec \<off | process-no-validate | process | log-fail | validate\>
+
+The PowerDNS recursor has 5 different levels of DNSSEC processing, which can
+be set with the dnssec setting. In order from least to most processing, these
+are:
+
+* **off** In this mode, no DNSSEC processing takes place. The recursor will
+not set the DNSSEC OK (DO) bit in the outgoing queries and will ignore the
+DO and AD bits in queries.
+
+* **process-no-validate** In this mode the recursor acts as a "security
+aware, non-validating" nameserver, meaning it will set the DO-bit on
+outgoing queries and will provide DNSSEC related RRsets (NSEC, RRSIG) to
+clients that ask for them (by means of a DO-bit in the query), except for
+zones provided through the auth-zones setting. It will not do any
+validation in this mode, not even when requested by the client.
+
+* **process** When dnssec is set to process the behavior is similar to
+process-no-validate. However, the recursor will try to validate the data
+if at least one of the DO or AD bits is set in the query; in that case,
+it will set the AD-bit in the response when the data is validated
+successfully, or send SERVFAIL when the validation comes up bogus.
+
+* **log-fail** In this mode, the recursor will attempt to validate all data
+it retrieves from authoritative servers, regardless of the client's DNSSEC
+desires, and will log the validation result. This mode can be used to
+determine the extra load and amount of possibly bogus answers before
+turning on full-blown validation. Responses to client queries are the same
+as with process.
+
+* **validate** The highest mode of DNSSEC processing. In this mode, all
+queries will be validated and will be answered with a SERVFAIL in case of
+bogus data, regardless of the client's request.
+
+:::{note}
+The popular Unix/Linux ``dig`` tool sets the AD-bit in the query.
+This might lead to unexpected query results when testing. Set ``+noad``
+on the ``dig`` command line when this is the case.
+:::
+
+:::{note}
+The ``CD``-bit is honored correctly for process and validate. For
+log-fail, failures will be logged too.
+:::
+```
+
+
+```{cfgcmd} set service dns forwarding ignore-hosts-file
+
+Do not use the local ``/etc/hosts`` file in name resolution. VyOS DHCP
+server will use this file to add resolvers to assigned addresses.
+```
+
+
+```{cfgcmd} set service dns forwarding cache-size \<0-2147483647\>
+
+Maximum number of DNS cache entries. 1 million per CPU core will generally
+suffice for most installations.
+
+This defaults to 10000.
+```
+
+
+```{cfgcmd} set service dns forwarding negative-ttl \<0-7200\>
+
+A query for which there is authoritatively no answer is cached to quickly
+deny a record's existence later on, without putting a heavy load on the
+remote server. In practice, caches can become saturated with hundreds of
+thousands of hosts which are tried only once.
+
+This setting, which defaults to 3600 seconds, puts a maximum on the amount
+of time negative entries are cached.
+```
+
+
+```{cfgcmd} set service dns forwarding timeout \<10-60000\>
+
+The number of milliseconds to wait for a remote authoritative server to
+respond before timing out and responding with SERVFAIL.
+
+This setting defaults to 1500 and is valid between 10 and 60000.
+```
+
+
+```{cfgcmd} set service dns forwarding listen-address \<address\>
+
+The local IPv4 or IPv6 addresses to bind the DNS forwarder to. The forwarder
+will listen on this address for incoming connections.
+```
+
+
+```{cfgcmd} set service dns forwarding source-address \<address\>
+
+The local IPv4 or IPv6 addresses to use as a source address for sending queries.
+The forwarder will send forwarded outbound DNS requests from this address.
+```
+
+
+```{cfgcmd} set service dns forwarding no-serve-rfc1918
+
+This makes the server authoritatively not aware of: 10.in-addr.arpa,
+168.192.in-addr.arpa, 16-31.172.in-addr.arpa, which enabling upstream
+DNS server(s) to be used for reverse lookups of these zones.
+```
+
+### Authoritative zones
+
+
+The VyOS DNS forwarder can also be configured to host authoritative records for a domain.
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> disable
+
+Disable hosting authoritative zone for `<domain-name>` without deleting from
+configuration.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records \<type\> \<name\> disable
+
+Disable specific record without deleting it from configuration.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records \<type\> \<name\> ttl \<seconds\>
+
+Set the {abbr}`TTL (Time-to-live)` for the record in seconds. Default is 300 seconds.
+```
+
+#### Record types
+
+
+Below are a list of record types available to be configured within VyOS. Some records
+support special `<name>` keywords:
+
+
+- `@` Use @ as record name to set the record for the root domain.
+- `any` Use any as record name to configure the record as a wildcard.
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records a \<name\> address \<x.x.x.x\>
+
+Set an {abbr}`A (Address)` record. Supports ``@`` and ``any`` keywords.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records aaaa \<name\> address \<h:h:h:h:h:h:h:h\>
+
+Set an {abbr}`AAAA (IPv6 Address)` record. Supports ``@`` and ``any`` keywords.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records cname \<name\> target \<target-domain-name\>
+
+Set an {abbr}`CNAME (Canonical name)` record. Supports ``@`` keyword.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records naptr \<name\> rule \<rule-number\> \<option\> \<value\>
+
+Set an {abbr}`NAPTR (Naming authority pointer)` record. Supports ``@`` keyword.
+NAPTR records support the following options:
+
+* **lookup-a** A Flag.
+
+* **lookup-srv** S flag.
+
+* **order** Rule order. Requires `<value>`.
+
+* **preference** Rule preference. Requires `<value>`. Defaults to 0 if not set.
+
+* **protocol-specific** P flag.
+
+* **regexp** Regular expression. Requires `<value>`.
+
+* **replacement** Replacement DNS name.
+
+* **resolve-uri** U flag.
+
+* **service** Service type. Requires `<value>`.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records ns \<name\> target \<target-name\>
+
+Set an {abbr}`NS (Nameserver)` record.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records ptr \<name\> target \<target-name\>
+
+Set an {abbr}`PTR (Pointer record)` record. Supports ``@`` keyword.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records spf \<name\> value \<value\>
+
+Set an {abbr}`SPF (Sender policy framework)` record. Supports ``@`` keyword.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records srv \<name\> entry \<entry-number\> [hostname | port | priority | weight] \<value\>
+
+Set an {abbr}`SRV (Service)` record. Supports ``@`` keyword.
+```
+
+
+```{cfgcmd} set service dns forwarding authoritative-domain \<domain-name\> records txt \<name\> value \<value\>
+
+Set an {abbr}`TXT (Text)` record. Supports ``@`` keyword.
+```
+
+## Example
+
+
+A VyOS router with two interfaces - eth0 (WAN) and eth1 (LAN) - is required to
+implement a split-horizon DNS configuration for example.com.
+
+
+In this scenario:
+
+
+- All DNS requests for example.com must be forwarded to a DNS server
+ at 192.0.2.254 and 2001:db8:cafe::1
+- All other DNS requests will be forwarded to a different set of DNS servers at
+ 192.0.2.1, 192.0.2.2, 2001:db8::1:ffff and 2001:db8::2:ffff
+- The VyOS DNS forwarder will only listen for requests on the eth1 (LAN)
+ interface addresses - 192.168.1.254 for IPv4 and 2001:db8::ffff for IPv6
+- The VyOS DNS forwarder will only accept lookup requests from the
+ LAN subnets - 192.168.1.0/24 and 2001:db8::/64
+- The VyOS DNS forwarder will pass reverse lookups for 10.in-addr.arpa,
+ 168.192.in-addr.arpa, 16-31.172.in-addr.arpa zones to upstream server.
+
+```none
+set service dns forwarding domain example.com name-server 192.0.2.254
+set service dns forwarding domain example.com name-server 2001:db8:cafe::1
+set service dns forwarding name-server 192.0.2.1
+set service dns forwarding name-server 192.0.2.2
+set service dns forwarding name-server 192.0.2.3 port 853
+set service dns forwarding name-server 2001:db8::1:ffff
+set service dns forwarding name-server 2001:db8::2:ffff
+set service dns forwarding name-server 2001:db8::3:ffff port 8053
+set service dns forwarding listen-address 192.168.1.254
+set service dns forwarding listen-address 2001:db8::ffff
+set service dns forwarding allow-from 192.168.1.0/24
+set service dns forwarding allow-from 2001:db8::/64
+set service dns forwarding no-serve-rfc1918
+```
+
+## Operation
+
+```{opcmd} reset dns forwarding \<all | domain\>
+
+Resets the local DNS forwarding cache database. You can reset the cache
+for all entries or only for entries to a specific domain.
+```
+
+
+```{opcmd} restart dns forwarding
+
+Restarts the DNS recursor process. This also invalidates the local DNS
+forwarding cache.
+```
+
+(dynamic-dns)=
+
+# Dynamic DNS
+
+VyOS is able to update a remote DNS record when an interface gets a new IP
+address. In order to do so, VyOS includes [ddclient], a Perl script written for
+this only one purpose.
+
+[ddclient] uses two methods to update a DNS record. The first one will send
+updates directly to the DNS daemon, in compliance with {rfc}`2136`. The second
+one involves a third party service, like DynDNS.com or any other such
+service provider. This method uses HTTP requests to transmit the new IP address.
+You can configure both in VyOS.
+(dns-dynamic-config)=
+
+## Configuration
+### {rfc}`2136` Based
+
+```{cfgcmd} set service dns dynamic name \<service-name\> address interface \<interface\>
+
+ Create new dynamic DNS update configuration which will update the IP
+ address assigned to `<interface>` on the service you configured under
+ `<service-name>`.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> description \<text\>
+
+Set description `<text>` for dynamic DNS service being configured.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> key \<filename\>
+
+File identified by `<filename>` containing the TSIG authentication key for RFC2136
+nsupdate on remote DNS server.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> server \<server\>
+
+Configure the DNS `<server>` IP/FQDN used when updating this dynamic
+assignment.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> zone \<zone\>
+
+Configure DNS `<zone>` to be updated.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> host-name \<record\>
+
+Configure DNS `<record>` which should be updated. This can be set multiple times.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> ttl \<ttl\>
+
+Configure optional TTL value on the given resource record. This defaults to
+600 seconds.
+```
+
+
+```{cfgcmd} set service dns dynamic interval \<60-3600\>
+
+Specify interval in seconds to wait between Dynamic DNS updates.
+The default is 300 seconds.
+```
+
+(dns-dynamic-example)=
+
+
+#### Example
+
+
+- Register DNS record `example.vyos.io` on DNS server `ns1.vyos.io`
+- Use auth key file at `/config/auth/my.key`
+- Set TTL to 300 seconds
+
+```none
+# Configuration commands entered:
+#
+set service dns dynamic name 'VyOS-DNS' address interface 'eth0'
+set service dns dynamic name 'VyOS-DNS' description 'RFC 2136 dynamic dns service'
+set service dns dynamic name 'VyOS-DNS' key '/config/auth/my.key'
+set service dns dynamic name 'VyOS-DNS' server 'ns1.vyos.io'
+set service dns dynamic name 'VyOS-DNS' zone 'vyos.io'
+set service dns dynamic name 'VyOS-DNS' host-name 'example.vyos.io'
+set service dns dynamic name 'VyOS-DNS' protocol 'nsupdate'
+set service dns dynamic name 'VyOS-DNS' ttl '300'
+
+# Resulting config:
+#
+vyos@vyos# show service dns dynamic
+ name VyOS-DNS {
+ address {
+ interface eth0
+ }
+ description "RFC 2136 dynamic dns service"
+ host-name example.vyos.io
+ key /config/auth/my.key
+ protocol nsupdate
+ server ns1.vyos.io
+ ttl 300
+ zone vyos.io
+ }
+```
+
+This will render the following [ddclient] configuration entry:
+
+```none
+# ddclient configuration for interface "eth0":
+#
+
+# Web service dynamic DNS configuration for VyOS-DNS: [nsupdate, example.vyos.io]
+use=if, \
+if=eth0, \
+protocol=nsupdate, \
+server=ns1.vyos.io, \
+zone=vyos.io, \
+password='/config/auth/my.key', \
+ttl=300 \
+example.vyos.io
+```
+
+:::{note}
+You can also keep different DNS zone updated. Just create a new
+config node: `set service dns dynamic interface <interface> rfc2136
+<other-service-name>`
+:::
+
+
+### HTTP based services
+
+
+VyOS is also able to use any service relying on protocols supported by ddclient.
+
+
+To use such a service, one must define a login, password, one or multiple
+hostnames, protocol and server.
+
+```{cfgcmd} set service dns dynamic name \<service-name\> address interface \<interface\>
+
+Create new dynamic DNS update configuration which will update the IP
+address assigned to `<interface>` on the service you configured under
+`<service-name>`.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> description \<text\>
+
+Set description `<text>` for dynamic DNS service being configured.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> host-name \<hostname\>
+
+Setup the dynamic DNS hostname `<hostname>` associated with the DynDNS
+provider identified by `<service-name>`.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> username \<username\>
+
+Configure `<username>` used when authenticating the update request for
+DynDNS service identified by `<service-name>`.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> password \<password\>
+
+Configure `<password>` used when authenticating the update request for
+DynDNS service identified by `<service-name>`.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> protocol \<protocol\>
+
+When a ``custom`` DynDNS provider is used, the protocol used for communicating
+to the provider must be specified under `<protocol>`. See the embedded
+completion helper when entering above command for available protocols.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> server \<server\>
+
+When a ``custom`` DynDNS provider is used the `<server>` where update
+requests are being sent to must be specified.
+```
+
+
+```{cfgcmd} set service dns dynamic name \<service-name\> ip-version 'ipv6'
+
+Allow explicit IPv6 address for the interface.
+```
+
+#### Example:
+
+Use deSEC (dedyn.io) as your preferred provider:
+
+```none
+set service dns dynamic name dedyn description 'deSEC dynamic dns service'
+set service dns dynamic name dedyn username 'myusername'
+set service dns dynamic name dedyn password 'mypassword'
+set service dns dynamic name dedyn host-name 'myhostname.dedyn.io'
+set service dns dynamic name dedyn protocol 'dyndns2'
+set service dns dynamic name dedyn server 'update.dedyn.io'
+set service dns dynamic name dedyn address interface 'eth0'
+```
+
+:::{note}
+Multiple services can be used per interface. Just specify as many
+services per interface as you like!
+:::
+#### Example IPv6 only:
+
+```none
+set service dns dynamic name dedyn description 'deSEC ipv6 dynamic dns service'
+set service dns dynamic name dedyn username 'myusername'
+set service dns dynamic name dedyn password 'mypassword'
+set service dns dynamic name dedyn host-name 'myhostname.dedyn.io'
+set service dns dynamic name dedyn protocol 'dyndns2'
+set service dns dynamic name dedyn ip-version 'ipv6'
+set service dns dynamic name dedyn server 'update6.dedyn.io'
+set service dns dynamic name dedyn address interface 'eth0'
+```
+
+### Running Behind NAT
+
+By default, [ddclient] will update a dynamic dns record using the IP address
+directly attached to the interface. If your VyOS instance is behind NAT, your
+record will be updated to point to your internal IP.
+
+[ddclient] has another way to determine the WAN IP address. This is controlled
+by:
+
+```{cfgcmd} set service dns dynamic name \<service-name\> address web \<url\>
+
+Use configured `<url>` to determine your IP address. [ddclient] will load
+`<url>` and tries to extract your IP address from the response.
+```
+```{cfgcmd} set service dns dynamic name \<service-name\> address web skip \<pattern\>
+
+ddclient will skip any address located before the string set in `<pattern>`.
+```
+
+[ddclient]: https://github.com/ddclient/ddclient
diff --git a/docs/configuration/service/eventhandler.md b/docs/configuration/service/eventhandler.md
new file mode 100644
index 00000000..48031909
--- /dev/null
+++ b/docs/configuration/service/eventhandler.md
@@ -0,0 +1,130 @@
+(event-handler)=
+
+# Event Handler
+
+## Event Handler Technology Overview
+
+Event handler allows you to execute scripts when a string that matches
+a regex or a regex with a service name appears in journald logs. You
+can pass variables, arguments, and a full matching string to the script.
+
+## How to configure Event Handler
+
+> [1. Create an event handler](#create-an-event-handler)
+>
+> [2. Add regex to the script](#add-regex-to-the-script)
+>
+> [3. Add a full path to the script](#add-a-full-path-to-the-script)
+>
+> [4. Add optional parameters](#add-optional-parameters)
+
+## Event Handler Configuration Steps
+
+### 1. Create an event handler
+
+```{cfgcmd} set service event-handler event \<event-handler name\>
+
+This is an optional command because the event handler will be
+automatically created after any of the next commands.
+```
+
+
+### 2. Add regex to the script
+
+```{cfgcmd} set service event-handler event \<event-handler name\> filter pattern \<regex\>
+
+This is a mandatory command. Sets regular expression to match
+against log string message.
+
+:::{note}
+The regular expression matches if and only if the entire
+string matches the pattern.
+:::
+```
+
+
+### 3. Add a full path to the script
+
+```{cfgcmd} set service event-handler event \<event-handler name\> script path \<path to script\>
+
+This is a mandatory command. Sets the full path to the script.
+The script file must be executable.
+```
+
+
+### 4. Add optional parameters
+
+```{cfgcmd} set service event-handler event \<event-handler name\> filter syslog-identifier \<syslogid name\>
+
+This is an optional command. Filters log messages by
+syslog-identifier.
+```
+
+```{cfgcmd} set service event-handler event \<event-handler name\> script environment \<env name\> value \<env value\>
+
+This is an optional command. Adds environment and its value to
+the script. Use separate commands for each environment.
+
+One implicit environment exists.
+
+* ``message``: Full message that has triggered the script.
+```
+
+```{cfgcmd} set service event-handler event \<event-handler name\> script arguments \<arguments\>
+
+This is an optional command. Adds arguments to the script.
+Arguments must be separated by spaces.
+
+:::{note}
+We don't recommend to use arguments. Using environments
+is more preferable.
+:::
+```
+
+
+## Example
+
+Event handler that monitors the state of interface eth0.
+
+```none
+set service event-handler event INTERFACE_STATE_DOWN filter pattern '.*eth0.*,RUNNING,.*->.*'
+set service event-handler event INTERFACE_STATE_DOWN filter syslog-identifier 'netplugd'
+set service event-handler event INTERFACE_STATE_DOWN script environment interface_action value 'down'
+set service event-handler event INTERFACE_STATE_DOWN script environment interface_name value 'eth0'
+set service event-handler event INTERFACE_STATE_DOWN script path '/config/scripts/eventhandler.py'
+```
+
+Event handler script
+
+```none
+#!/usr/bin/env python3
+#
+# VyOS event-handler script example
+from os import environ
+import subprocess
+from sys import exit
+
+# Perform actions according to requirements
+def process_event() -> None:
+ # Get variables
+ message_text = environ.get('message')
+ interface_name = environ.get('interface_name')
+ interface_action = environ.get('interface_action')
+ # Print the message that triggered this script
+ print(f'Logged message: {message_text}')
+ # Prepare a command to run
+ command = f'sudo ip link set {interface_name} {interface_action}'.split()
+ # Execute a command
+ subprocess.run(command)
+
+if __name__ == '__main__':
+ try:
+ # Run script actions and exit
+ process_event()
+ exit(0)
+ except Exception as err:
+ # Exit properly in case if something in the script goes wrong
+ print(f'Error running script: {err}')
+ exit(1)
+```
+
diff --git a/docs/configuration/service/https.md b/docs/configuration/service/https.md
new file mode 100644
index 00000000..184fd088
--- /dev/null
+++ b/docs/configuration/service/https.md
@@ -0,0 +1,138 @@
+(http-api)=
+
+# HTTP API
+
+VyOS provide an HTTP API. You can use it to execute op-mode commands,
+update VyOS, set or delete config.
+
+Please take a look at the {ref}`vyosapi` page for an detailed how-to.
+
+## Configuration
+
+```{cfgcmd} set service https allow-client address \<address\>
+
+Only allow certain IP addresses or prefixes to access the https
+webserver.
+```
+
+```{cfgcmd} set service https certificates ca-certificate \<name\>
+
+Use CA certificate from PKI subsystem
+```
+
+```{cfgcmd} set service https certificates certificate \<name\>
+
+Use certificate from PKI subsystem
+```
+
+```{cfgcmd} set service https certificates dh-params \<name\>
+
+Use {abbr}`DH (Diffie–Hellman)` parameters from PKI subsystem.
+Must be at least 2048 bits in length.
+```
+
+```{cfgcmd} set service https listen-address \<address\>
+
+Webserver should only listen on specified IP address
+```
+
+```{cfgcmd} set service https port \<number\>
+
+Webserver should listen on specified port.
+
+Default: 443
+```
+
+```{cfgcmd} set service https enable-http-redirect
+
+Enable automatic redirect from http to https.
+```
+
+```{cfgcmd} set service https tls-version \<1.2 | 1.3\>
+
+Select TLS version used.
+
+This defaults to both 1.2 and 1.3.
+```
+
+```{cfgcmd} set service https vrf \<name\>
+
+Start Webserver in given VRF.
+```
+
+```{cfgcmd} set service https request-body-size-limit \<size\>
+
+Set the maximum request body size in megabytes. Default is 1MB.
+```
+
+
+### API
+
+```{cfgcmd} set service https api keys id \<name\> key \<apikey\>
+
+Set a named api key. Every key has the same, full permissions
+on the system.
+```
+
+
+### REST
+
+```{cfgcmd} set service https api rest
+
+Enable REST API
+```
+
+```{cfgcmd} set service https api rest debug
+
+To enable debug messages. Available via {opcmd}`show log` or
+{opcmd}`monitor log`
+```
+
+```{cfgcmd} set service https api rest strict
+
+Enforce strict path checking.
+```
+
+
+### GraphQL
+
+```{cfgcmd} set service https api graphql introspection
+
+Enable GraphQL Schema introspection.
+```
+
+:::{note}
+Do not leave introspection enabled in production, it is a security risk.
+:::
+
+```{cfgcmd} set service https api graphql authentication type \<key | token\>
+
+Set the authentication type for GraphQL, default option is key. Available options are:
+* ``key`` use API keys configured in ``service https api keys``
+* ``token`` use JWT tokens.
+```
+
+```{cfgcmd} set service https api graphql authentication expiration
+
+Set the lifetime for JWT tokens in seconds. Default is 3600 seconds.
+```
+
+```{cfgcmd} set service https api graphql authentication secret-length
+
+Set the byte length of the JWT secret. Default is 32.
+```
+
+```{cfgcmd} set service https api graphql cors allow-origin \<origin\>
+
+Allow cross-origin requests from \<origin\>.
+```
+
+
+## Example Configuration
+
+Setting REST API and an API-KEY is the minimal configuration to get a working API Endpoint.
+
+```none
+set service https api keys id MY-HTTPS-API-ID key MY-HTTPS-API-PLAINTEXT-KEY
+set service https api rest
+```
diff --git a/docs/configuration/service/index.md b/docs/configuration/service/index.md
new file mode 100644
index 00000000..4018c5be
--- /dev/null
+++ b/docs/configuration/service/index.md
@@ -0,0 +1,29 @@
+# Service
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+broadcast-relay
+config-sync
+conntrack-sync
+console-server
+dhcp-relay
+dhcp-server
+dns
+eventhandler
+https
+ipoe-server
+lldp
+mdns
+monitoring
+ntp
+pppoe-server
+router-advert
+salt-minion
+snmp
+ssh
+tftp-server
+webproxy
+suricata
+```
diff --git a/docs/configuration/service/ipoe-server.md b/docs/configuration/service/ipoe-server.md
new file mode 100644
index 00000000..88ec4f51
--- /dev/null
+++ b/docs/configuration/service/ipoe-server.md
@@ -0,0 +1,512 @@
+(ipoe-server)=
+
+# IPoE Server
+
+VyOS utilizes [accel-ppp] to provide {abbr}`IPoE (Internet Protocol over
+Ethernet)` server functionality. It can be used with local authentication
+(mac-address) or a connected RADIUS server.
+
+IPoE is a method of delivering an IP payload over an Ethernet-based access
+network or an access network using bridged Ethernet over Asynchronous Transfer
+Mode (ATM) without using PPPoE. It directly encapsulates the IP datagrams in
+Ethernet frames, using the standard {rfc}`894` encapsulation.
+
+The use of IPoE addresses the disadvantage that PPP is unsuited for multicast
+delivery to multiple users. Typically, IPoE uses Dynamic Host Configuration
+Protocol and Extensible Authentication Protocol to provide the same
+functionality as PPPoE, but in a less robust manner.
+
+:::{note}
+Please be aware, due to an upstream bug, config changes/commits
+will restart the ppp daemon and will reset existing IPoE sessions,
+in order to become effective.
+:::
+
+## Configuring IPoE Server
+
+IPoE can be configured on different interfaces, it will depend on each specific
+situation which interface will provide IPoE to clients. The client's mac address
+and the incoming interface is being used as control parameter, to authenticate
+a client.
+
+The example configuration below will assign an IP to the client on the incoming
+interface eth1 with the client mac address 00:50:79:66:68:00. Other DHCP
+discovery requests will be ignored, unless the client mac has been enabled in
+the configuration.
+
+```none
+set interfaces ethernet eth1 address '192.168.0.1/24'
+set service ipoe-server authentication interface eth1.100 mac 00:50:79:66:68:00
+set service ipoe-server authentication interface eth1.101 mac 00:50:79:66:68:01
+set service ipoe-server authentication mode 'local'
+set service ipoe-server client-ip-pool IPOE-POOL range '192.168.0.2-192.168.0.254'
+set service ipoe-server default-pool 'IPOE-POOL'
+set service ipoe-server gateway-address '192.168.0.1/24'
+set service ipoe-server interface eth1 mode 'l2'
+set service ipoe-server interface eth1 network 'vlan'
+set service ipoe-server interface eth1 vlan '100-200'
+```
+
+```{cfgcmd} set service ipoe-server authentication interface \<interface\> mac \<MAC\>
+
+Creates local IPoE user with username=\*\*\<interface\>\*\* and
+password=\*\*\<MAC\>\*\* (mac-address)
+```
+
+
+```{cfgcmd} set service ipoe-server authentication mode \<local | radius\>
+
+Set authentication backend. The configured authentication backend is used
+for all queries.
+
+* **radius**: All authentication queries are handled by a configured RADIUS
+server.
+* **local**: All authentication queries are handled locally.
+* **noauth**: Authentication disabled
+```
+
+
+```{cfgcmd} set service ipoe-server client-ip-pool \<POOL-NAME\> range \<x.x.x.x-x.x.x.x | x.x.x.x/x\>
+
+Use this command to define the first IP address of a pool of
+addresses to be given to IPoE clients. If notation ``x.x.x.x-x.x.x.x``,
+it must be within a /24 subnet. If notation ``x.x.x.x/x`` is
+used there is possibility to set host/netmask.
+```
+
+
+```{cfgcmd} set service ipoe-server default-pool \<POOL-NAME\>
+
+Use this command to define default address pool name.
+```
+
+
+```{cfgcmd} set service ipoe-server gateway-address \<x.x.x.x/x\>
+
+Specifies address to be used as server ip address if radius can assign
+only client address. In such case if client address is matched network
+and mask then specified address and mask will be used. You can specify
+multiple such options.
+```
+
+
+```{cfgcmd} set service ipoe-server interface \<interface\> mode \<l2 | l3\>
+
+> Specifies the client connectivity mode.
+
+* **l2**: It means that clients are on same network where interface
+is.\*\*(default)\*\*
+* **l3**: It means that client are behind some router.
+```
+
+
+```{cfgcmd} set service ipoe-server interface \<interface\> network \<shared | vlan\>
+
+Specify where interface is shared by multiple users or it is vlan-per-user.
+
+* **shared**: Multiple clients share the same network. **(default)**
+* **vlan**: One VLAN per client.
+```
+
+
+```none
+vyos@vyos:~$ show ipoe-server sessions
+
+ ifname | username | calling-sid | ip | rate-limit | type | comp | state | uptime
+--------+----------+-------------------+-------------+------------+------+------+--------+----------
+ ipoe0 | eth1.100 | 00:50:79:66:68:00 | 192.168.0.2 | | ipoe | | active | 00:04:55
+ ipoe1 | eth1.101 | 00:50:79:66:68:01 | 192.168.0.3 | | ipoe | | active | 00:04:44
+```
+
+## Configuring RADIUS authentication
+
+
+To enable RADIUS based authentication, the authentication mode needs to be
+changed within the configuration. Previous settings like the local users, still
+exists within the configuration, however they are not used if the mode has been
+changed from local to radius. Once changed back to local, it will use all local
+accounts again.
+
+```none
+set service ipoe-server authentication mode radius
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius server \<server\> key \<secret\>
+
+Configure RADIUS *\<server\>* and its required shared *\<secret\>* for
+communicating with the RADIUS server.
+```
+
+Since the RADIUS server would be a single point of failure, multiple RADIUS
+servers can be setup and will be used subsequentially.
+For example:
+
+```none
+set service ipoe-server authentication radius server 10.0.0.1 key 'foo'
+set service ipoe-server authentication radius server 10.0.0.2 key 'foo'
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+
+### RADIUS source address
+
+
+If you are using OSPF as IGP, always the closest interface connected to the
+RADIUS server is used. With VyOS 1.2 you can bind all outgoing RADIUS requests
+to a single source IP e.g. the loopback interface.
+
+```{cfgcmd} set service ipoe-server authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+:::{note}
+The ``source-address`` must be configured on one of VyOS interface.
+Best practice would be a loopback or dummy interface.
+:::
+
+
+### RADIUS advanced options
+
+```{cfgcmd} set service ipoe-server authentication radius server \<server\> port \<port\>
+
+Configure RADIUS *\<server\>* and its required port for authentication requests.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius server \<server\> fail-time \<time\>
+
+Mark RADIUS server as offline for this given *\<time\>* in seconds.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius server \<server\> disable
+
+Temporary disable this RADIUS server.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius acct-timeout \<timeout\>
+
+Timeout to wait reply for Interim-Update packets. (default 3 seconds)
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius dynamic-author server \<address\>
+
+Specifies IP address for Dynamic Authorization Extension server (DM/CoA).
+This IP must exist on any VyOS interface or it can be ``0.0.0.0``.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius dynamic-author port \<port\>
+
+UDP port for Dynamic Authorization Extension server (DM/CoA)
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius dynamic-author key \<secret\>
+
+Secret for Dynamic Authorization Extension server (DM/CoA)
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius max-try \<number\>
+
+Maximum number of tries to send Access-Request/Accounting-Request queries
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius timeout \<timeout\>
+
+Timeout to wait response from server (seconds)
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius nas-identifier \<identifier\>
+
+Value to send to RADIUS server in NAS-Identifier attribute and to be matched
+in DM/CoA requests.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius nas-ip-address \<address\>
+
+Value to send to RADIUS server in NAS-IP-Address attribute and to be matched
+in DM/CoA requests. Also DM/CoA server will bind to that address.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius rate-limit attribute \<attribute\>
+
+Specifies which RADIUS server attribute contains the rate limit information.
+The default attribute is *Filter-Id*.
+```
+
+:::{note}
+If you set a custom RADIUS attribute you must define it on both
+dictionaries at RADIUS server and client.
+:::
+
+```{cfgcmd} set service ipoe-server authentication radius rate-limit enable
+
+Enables bandwidth shaping via RADIUS.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication radius rate-limit vendor
+
+Specifies the vendor dictionary, dictionary needs to be in
+/usr/share/accel-ppp/radius.
+```
+
+Received RADIUS attributes have a higher priority than parameters defined within
+the CLI configuration, refer to the explanation below.
+
+
+### Allocation clients ip addresses by RADIUS
+
+
+If the RADIUS server sends the attribute ``Framed-IP-Address`` then this IP
+address will be allocated to the client and the option ``default-pool`` within the CLI
+config is being ignored.
+
+
+If the RADIUS server sends the attribute ``Framed-Pool``, IP address will be allocated
+from a predefined IP pool whose name equals the attribute value.
+
+
+If the RADIUS server sends the attribute ``Stateful-IPv6-Address-Pool``, IPv6 address
+will be allocated from a predefined IPv6 pool ``prefix`` whose name equals the attribute value.
+
+
+If the RADIUS server sends the attribute ``Delegated-IPv6-Prefix-Pool``, IPv6
+delegation pefix will be allocated from a predefined IPv6 pool ``delegate``
+whose name equals the attribute value.
+
+
+:::{note}
+``Stateful-IPv6-Address-Pool`` and ``Delegated-IPv6-Prefix-Pool`` are defined in
+RFC6911. If they are not defined in your RADIUS server, add new [dictionary].
+:::
+
+
+User interface can be put to VRF context via RADIUS Access-Accept packet, or change
+it via RADIUS CoA. ``Accel-VRF-Name`` is used from these purposes. It is custom [ACCEL-PPP attribute].
+Define it in your RADIUS server.
+
+
+## IPv6
+
+```{cfgcmd} set service ipoe-server client-ipv6-pool \<IPv6-POOL-NAME\> prefix \<address\> mask \<number-of-bits\>
+
+Use this comand to set the IPv6 address pool from which an IPoE client
+will get an IPv6 prefix of your defined length (mask) to terminate the
+IPoE endpoint at their side. The mask length can be set from 48 to 128
+bit long, the default value is 64.
+```
+
+
+```{cfgcmd} set service ipoe-server client-ipv6-pool \<IPv6-POOL-NAME\> delegate \<address\> delegation-prefix \<number-of-bits\>
+
+Use this command to configure DHCPv6 Prefix Delegation (RFC3633) on
+IPoE. You will have to set your IPv6 pool and the length of the
+delegation prefix. From the defined IPv6 pool you will be handing out
+networks of the defined length (delegation-prefix). The length of the
+delegation prefix can be set from 32 to 64 bit long.
+```
+
+
+```{cfgcmd} set service ipoe-server default-ipv6-pool \<IPv6-POOL-NAME\>
+
+Use this command to define default IPv6 address pool name.
+```
+
+
+```none
+set service ipoe-server client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set service ipoe-server client-ipv6-pool IPv6-POOL prefix '2001:db8:8002::/48' mask '64'
+set service ipoe-server default-ipv6-pool IPv6-POOL
+```
+
+## Scripting
+
+```{cfgcmd} set service ipoe-server extended-scripts on-change \<path_to_script\>
+
+Script to run when session interface changed by RADIUS CoA handling
+```
+
+
+```{cfgcmd} set service ipoe-server extended-scripts on-down \<path_to_script\>
+
+Script to run when session interface going to terminate
+```
+
+
+```{cfgcmd} set service ipoe-server extended-scripts on-pre-up \<path_to_script\>
+
+Script to run before session interface comes up
+```
+
+
+```{cfgcmd} set service ipoe-server extended-scripts on-up \<path_to_script\>
+
+Script to run when session interface is completely configured and started
+```
+
+## Advanced Options
+
+
+### Authentication Advanced Options
+
+```{cfgcmd} set service ipoe-server authentication interface \<interface\> mac \<MAC\> vlan \<vlan-id\>
+
+VLAN monitor for automatic creation of VLAN interfaces for specific user on specific \<interface\>
+```
+
+
+```{cfgcmd} set service ipoe-server authentication interface \<interface\> mac \<MAC\> rate-limit download \<bandwidth\>
+
+Download bandwidth limit in kbit/s for user on interface *\<interface\>*.
+```
+
+
+```{cfgcmd} set service ipoe-server authentication interface \<interface\> mac \<MAC\> rate-limit upload \<bandwidth\>
+
+Upload bandwidth limit in kbit/s for for user on interface *\<interface\>*.
+```
+
+### Client IP Pool Advanced Options
+
+```{cfgcmd} set service ipoe-server client-ip-pool \<POOL-NAME\> next-pool \<NEXT-POOL-NAME\>
+
+Use this command to define the next address pool name.
+```
+
+### Advanced Interface Options
+
+```{cfgcmd} set service ipoe-server interface \<interface\> client-subnet \<x.x.x.x/x\>
+
+Specify local range of ip address to give to dhcp clients. First IP in range is router IP.
+If you need more customization use *client-ip-pool*
+```
+
+
+```{cfgcmd} set service ipoe-server interface \<interface\> external-dhcp dhcp-relay \<x.x.x.x\>
+
+Specify DHCPv4 relay IP address to pass requests to. If specified giaddr is also needed.
+```
+
+
+```{cfgcmd} set service ipoe-server interface \<interface\> external-dhcp giaddr \<x.x.x.x\>
+
+Specifies relay agent IP addre
+```
+
+### Global Advanced options
+
+```{cfgcmd} set service ipoe-server description \<description\>
+
+Set description.
+```
+```{cfgcmd} set service ipoe-server limits burst \<value\>
+
+Burst count
+```
+```{cfgcmd} set service ipoe-server limits connection-limit \<value\>
+
+Acceptable rate of connections (e.g. 1/min, 60/sec)
+```
+```{cfgcmd} set service ipoe-server limits timeout \<value\>
+
+Timeout in seconds
+```
+```{cfgcmd} set service ipoe-server max-concurrent-sessions
+
+Maximum number of concurrent session start attempts
+```
+```{cfgcmd} set service ipoe-server name-server \<address\>
+
+Connected client should use *\<address\>* as their DNS server. This
+command accepts both IPv4 and IPv6 addresses. Up to two nameservers
+can be configured for IPv4, up to three for IPv6.
+```
+```{cfgcmd} set service ipoe-server shaper fwmark \<1-2147483647\>
+
+Match firewall mark value
+```
+```{cfgcmd} set service ipoe-server snmp master-agent
+
+Enable SNMP
+```
+
+## Monitoring
+
+```{opcmd} show ipoe-server sessions
+
+Use this command to locally check the active sessions in the IPoE
+server.
+```
+```none
+vyos@vyos:~$ show ipoe-server sessions
+ifname | username | calling-sid | ip | rate-limit | type | comp | state | uptime
+----------+----------+-------------------+-------------+------------+------+------+--------+----------
+ eth1.100 | eth1.100 | 0c:98:bd:b8:00:01 | 192.168.0.3 | | ipoe | | active | 03:03:58
+```
+
+```none
+vyos@vyos:~$ show ipoe-server statistics
+uptime: 0.03:31:36
+cpu: 0%
+mem(rss/virt): 6044/101360 kB
+core:
+ mempool_allocated: 148628
+ mempool_available: 144748
+ thread_count: 1
+ thread_active: 1
+ context_count: 10
+ context_sleeping: 0
+ context_pending: 0
+ md_handler_count: 6
+ md_handler_pending: 0
+ timer_count: 1
+ timer_pending: 0
+sessions:
+ starting: 0
+ active: 1
+ finishing: 0
+ipoe:
+ starting: 0
+ active: 1
+ delayed: 0
+```
+
+## Toubleshooting
+
+```none
+vyos@vyos:~$ show log ipoe-server
+
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:: recv [DHCPv4 Discover xid=55df9228 chaddr=0c:98:bd:b8:00:01 <Message-Type Discover> <Request-IP 192.168.0.3> <Host-Name vyos> <Request-List Subnet,Broadcast,Router,DNS,Classless-Route,Domain-Name,MTU>]
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: eth1.100: authentication succeeded
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: send [DHCPv4 Offer xid=55df9228 yiaddr=192.168.0.4 chaddr=0c:98:bd:b8:00:01 <Message-Type Offer> <Server-ID 192.168.0.1> <Lease-Time 600> <T1 300> <T2 525> <Router 192.168.0.1> <Subnet 255.255.255.0>]
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: recv [DHCPv4 Request xid=55df9228 chaddr=0c:98:bd:b8:00:01 <Message-Type Request> <Server-ID 192.168.0.1> <Request-IP 192.168.0.4> <Host-Name vyos> <Request-List Subnet,Broadcast,Router,DNS,Classless-Route,Domain-Name,MTU>]
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: ipoe: activate session
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: ipoe: no free IPv6 address
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: ipoe: session started
+Feb 27 14:29:27 vyos accel-ipoe[2262]: eth1.100:eth1.100: send [DHCPv4 Ack xid=55df9228 yiaddr=192.168.0.4 chaddr=0c:98:bd:b8:00:01 <Message-Type Ack> <Server-ID 192.168.0.1> <Lease-Time 600> <T1 300> <T2 525> <Router 192.168.0.1> <Subnet 255.255.255.0>]
+```
+
+[accel-ppp]: https://accel-ppp.org/
+[accel-ppp attribute]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.accel
+[dictionary]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.rfc6911
diff --git a/docs/configuration/service/lldp.md b/docs/configuration/service/lldp.md
new file mode 100644
index 00000000..7fdba6c8
--- /dev/null
+++ b/docs/configuration/service/lldp.md
@@ -0,0 +1,154 @@
+(lldp)=
+
+# LLDP
+
+{abbr}`LLDP (Link Layer Discovery Protocol)` is a vendor-neutral link layer
+protocol in the Internet Protocol Suite used by network devices for advertising
+their identity, capabilities, and neighbors on an IEEE 802 local area network,
+principally wired Ethernet. The protocol is formally referred to by the IEEE
+as Station and Media Access Control Connectivity Discovery specified in IEEE
+802.1AB and IEEE 802.3-2012 section 6 clause 79.
+
+LLDP performs functions similar to several proprietary protocols, such as
+{abbr}`CDP (Cisco Discovery Protocol)`,
+{abbr}`FDP (Foundry Discovery Protocol)`,
+{abbr}`NDP (Nortel Discovery Protocol)` and {abbr}`LLTD (Link Layer Topology
+Discovery)`.
+
+Information gathered with LLDP is stored in the device as a {abbr}`MIB
+(Management Information Database)` and can be queried with {abbr}`SNMP (Simple
+Network Management Protocol)` as specified in {rfc}`2922`. The topology of an
+LLDP-enabled network can be discovered by crawling the hosts and querying this
+database. Information that may be retrieved include:
+
+- System Name and Description
+- Port name and description
+- VLAN name
+- IP management address
+- System capabilities (switching, routing, etc.)
+- MAC/PHY information
+- MDI power
+- Link aggregation
+
+## Configuration
+
+```{cfgcmd} set service lldp
+
+Enable LLDP service
+```
+
+```{cfgcmd} set service lldp management-address \<address\>
+
+Define IPv4/IPv6 management address transmitted via LLDP. Multiple addresses
+can be defined. Only addresses connected to the system will be transmitted.
+```
+
+```{cfgcmd} set service lldp interface \<interface\>
+
+Enable transmission of LLDP information on given \<interface\>. You can also
+say ``all`` here so LLDP is turned on on every interface.
+```
+
+```{cfgcmd} set service lldp interface \<interface\> mode [disable|rx-tx|rx|tx]
+
+Configure the administrative status of the given port.
+
+By default, all ports are configured to be in rx-tx mode. This means they
+can receive and transmit LLDP frames.
+
+In rx mode, they won't emit any frames. In tx mode, they won't receive
+any frames. In disabled mode, no frame will be sent and any incoming frame
+will be discarded.
+```
+
+```{cfgcmd} set service lldp snmp
+
+Enable SNMP queries of the LLDP database
+```
+
+```{cfgcmd} set service lldp legacy-protocols \<cdp|edp|fdp|sonmp\>
+
+Enable given legacy protocol on this LLDP instance. Legacy protocols include:
+* ``cdp`` - Listen for CDP for Cisco routers/switches
+* ``edp`` - Listen for EDP for Extreme routers/switches
+* ``fdp`` - Listen for FDP for Foundry routers/switches
+* ``sonmp`` - Listen for SONMP for Nortel routers/switches
+```
+
+
+## Operation
+
+```{opcmd} show lldp neighbors
+
+Displays information about all neighbors discovered via LLDP.
+
+:::{code-block} none
+vyos@vyos:~$ show lldp neighbors
+Capability Codes: R - Router, B - Bridge, W - Wlan r - Repeater, S - Station
+ D - Docsis, T - Telephone, O - Other
+
+Device ID Local Proto Cap Platform Port ID
+--------- ----- ----- --- -------- -------
+BR2.vyos.net eth0 LLDP R VyOS 1.2.4 eth1
+BR3.vyos.net eth0 LLDP RB VyOS 1.2.4 eth2
+SW1.vyos.net eth0 LLDP B Cisco IOS Software GigabitEthernet0/6
+:::
+```
+
+```{opcmd} show lldp neighbors detail
+
+Get detailed information about LLDP neighbors.
+
+:::{code-block} none
+vyos@vyos:~$ show lldp neighbors detail
+-------------------------------------------------------------------------------
+LLDP neighbors:
+-------------------------------------------------------------------------------
+Interface: eth0, via: LLDP, RID: 28, Time: 0 day, 00:24:33
+Chassis:
+ ChassisID: mac 00:53:00:01:02:c9
+ SysName: BR2.vyos.net
+ SysDescr: VyOS 1.3-rolling-201912230217
+ MgmtIP: 192.0.2.1
+ MgmtIP: 2001:db8::ffff
+ Capability: Bridge, on
+ Capability: Router, on
+ Capability: Wlan, off
+ Capability: Station, off
+Port:
+ PortID: mac 00:53:00:01:02:c9
+ PortDescr: eth0
+ TTL: 120
+ PMD autoneg: supported: no, enabled: no
+ MAU oper type: 10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable
+VLAN: 201 eth0.201
+VLAN: 205 eth0.205
+LLDP-MED:
+ Device Type: Network Connectivity Device
+ Capability: Capabilities, yes
+ Capability: Policy, yes
+ Capability: Location, yes
+ Capability: MDI/PSE, yes
+ Capability: MDI/PD, yes
+ Capability: Inventory, yes
+ Inventory:
+ Hardware Revision: None
+ Software Revision: 4.19.89-amd64-vyos
+ Firmware Revision: 6.00
+ Serial Number: VMware-42 1d 83 b9 fe c1 bd b2-7
+ Manufacturer: VMware, Inc.
+ Model: VMware Virtual Platform
+ Asset ID: No Asset Tag
+-------------------------------------------------------------------------------
+:::
+```
+
+```{opcmd} show lldp neighbors interface \<interface\>
+
+Show LLDP neighbors connected via interface \<interface\>.
+```
+
+```{opcmd} show log lldp
+
+Used for troubleshooting.
+``` \ No newline at end of file
diff --git a/docs/configuration/service/mdns.md b/docs/configuration/service/mdns.md
new file mode 100644
index 00000000..088bca3c
--- /dev/null
+++ b/docs/configuration/service/mdns.md
@@ -0,0 +1,131 @@
+# mDNS Repeater
+
+Starting with VyOS 1.2 a {abbr}`mDNS (Multicast DNS)` repeater functionality is
+provided. Additional information can be obtained from
+<https://en.wikipedia.org/wiki/Multicast_DNS>.
+
+Multicast DNS uses the reserved address `224.0.0.251`, which is
+"administratively scoped" and does not leave the subnet. mDNS repeater
+retransmits mDNS packets from one interface to other interfaces. This enables
+support for devices using mDNS discovery (like network printers, Apple Airplay,
+Chromecast, various IP based home-automation devices etc) across multiple VLANs.
+
+Since the mDNS protocol sends the {abbr}`AA(Authoritative Answer)` records in
+the packet itself, the repeater does not need to forge the source address.
+Instead, the source address is of the interface that repeats the packet.
+
+:::{note}
+You can not run this in a VRRP setup, if multiple mDNS repeaters
+are launched in a subnet you will experience the mDNS packet storm death!
+:::
+
+## Configuration
+
+```{cfgcmd} set service mdns repeater interface \<interface\>
+
+To enable mDNS repeater you need to configure at least two interfaces so that
+all incoming mDNS packets from one interface configured here can be
+re-broadcasted to any other interface(s) configured under this section.
+```
+
+```{cfgcmd} set service mdns repeater disable
+
+mDNS repeater can be temporarily disabled without deleting the service using
+```
+
+```{cfgcmd} set service mdns repeater ip-version \<ipv4 | ipv6 | both\>
+
+mDNS repeater can be enabled either on IPv4 socket or on IPv6 socket or both
+to re-broadcast. By default, mDNS repeater will listen on both IPv4 and IPv6.
+```
+
+```{cfgcmd} set service mdns repeater allow-service \<service\>
+
+mDNS repeater can be configured to re-broadcast only specific services. By
+default, all services are re-broadcasted.
+```
+
+```{cfgcmd} set service mdns repeater browse-domain \<domain\>
+
+Allow listing additional custom domains to be browsed (in addition to the
+default ``local``) so that they can be reflected.
+```
+
+```{cfgcmd} set service mdns repeater cache-entries \<entries\>
+
+Specify how many resource records are cached per interface. Bigger values
+allow mDNS work correctly in large LANs but also increase memory consumption.
+
+Defaults to: 4096
+```
+
+
+## Firewall recommendations
+
+Unlike typical routed traffic, mDNS packets relayed between interfaces do not
+traverse the FORWARD hook chain in the firewall. Instead, they are processed
+through the following hooks:
+> - **INPUT**: For packets received by the local system
+> - **OUTPUT**: For packets sent from the local system
+
+To control or allow mDNS packet forwarding via the relay, you must define
+appropriate rules in the INPUT and OUTPUT directions. Rules in the FORWARD
+direction will have no effect on mDNS relay traffic.
+
+```none
+set firewall ipv4 input filter rule 10 action 'accept'
+set firewall ipv4 input filter rule 10 destination address '224.0.0.251'
+set firewall ipv4 input filter rule 10 destination port '5353'
+set firewall ipv4 input filter rule 10 protocol 'udp'
+set firewall ipv4 output filter rule 10 action 'accept'
+set firewall ipv4 output filter rule 10 destination address '224.0.0.251'
+set firewall ipv4 output filter rule 10 destination port '5353'
+set firewall ipv4 output filter rule 10 protocol 'udp'
+```
+
+
+## Example
+
+To listen on both `eth0` and `eth1` mDNS packets and also repeat packets
+received on `eth0` to `eth1` (and vice-versa) use the following commands:
+
+```none
+set service mdns repeater interface 'eth0'
+set service mdns repeater interface 'eth1'
+```
+
+To allow only specific services, for example `_airplay._tcp` or `_ipp._tcp`,
+(instead of all services) to be re-broadcasted, use the following command:
+
+```none
+set service mdns repeater allow-service '_airplay._tcp'
+set service mdns repeater allow-service '_ipp._tcp'
+```
+
+To allow listing additional custom domain, for example
+`openthread.thread.home.arpa`, so that it can reflected in addition to the
+default `local`, use the following command:
+
+```none
+set service mdns repeater browse-domain 'openthread.thread.home.arpa'
+```
+
+
+## Operation
+
+```{opcmd} restart mdns repeater
+
+Restart mDNS repeater service.
+```
+
+```{opcmd} show log mdns repeater
+
+Show logs for mDNS repeater service.
+```
+
+```{opcmd} monitor log mdns repeater
+
+Follow the logs for mDNS repeater service.
+```
+
+[multicast dns]: <https://en.wikipedia.org/wiki/Multicast_DNS>
diff --git a/docs/configuration/service/monitoring.md b/docs/configuration/service/monitoring.md
new file mode 100644
index 00000000..a6bf2605
--- /dev/null
+++ b/docs/configuration/service/monitoring.md
@@ -0,0 +1,334 @@
+# Monitoring
+
+VyOS supports monitoring through Telegraf as well as through Prometheus exporters.
+
+## Telegraf
+
+Telegraf is the open source server agent to help you collect metrics, events
+and logs from your routers.
+
+The following Telegraf plugins are configurable to export metrics and logs:
+: - Azure Data Explorer
+ - Prometheus Client
+ - Splunk
+ - InfluxDB
+ - Loki
+
+### Azure data explorer
+
+Telegraf output plugin [azure-data-explorer].
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer authentication client-id \<client-id\>
+
+ Authentication application client-id.
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer authentication client-secret \<client-secret\>
+
+Authentication application client-secret.
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer authentication tenant-id \<tenant-id\>
+
+Authentication application tenant-id
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer database \<name\>
+
+Remote database name.
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer group-metrics \<single-table | table-per-metric\>
+
+Type of metrics grouping when push to Azure Data Explorer. The default is
+``table-per-metric``.
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer table \<name\>
+
+Name of the single table Only if set group-metrics single-table.
+```
+
+
+```{cfgcmd} set service monitoring telegraf azure-data-explorer url \<url\>
+
+Remote URL.
+```
+
+### Prometheus client
+
+Telegraf output plugin [prometheus-client]
+This plugin allows export of Telegraf metrics to Prometheus,
+for Prometheus native metrics through exporters see section below.
+
+```{cfgcmd} set service monitoring telegraf prometheus-client
+
+ Output plugin Prometheus client
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client allow-from \<prefix\>
+
+Networks allowed to query this server
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client authentication username \<username\>
+
+HTTP basic authentication username
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client authentication password \<password\>
+
+HTTP basic authentication username
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client listen-address \<address\>
+
+Local IP addresses to listen on
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client metric-version \<1 | 2\>
+
+Metris version, the default is ``2``
+```
+
+
+```{cfgcmd} set service monitoring telegraf prometheus-client port \<port\>
+
+Port number used by connection, default is ``9273``
+```
+
+Example:
+
+```none
+set service monitoring telegraf prometheus-client
+```
+
+
+```none
+vyos@r14:~$ curl --silent localhost:9273/metrics | egrep -v "#" | grep cpu_usage_system
+cpu_usage_system{cpu="cpu-total",host="r14"} 0.20040080160320556
+cpu_usage_system{cpu="cpu0",host="r14"} 0.17182130584191915
+cpu_usage_system{cpu="cpu1",host="r14"} 0.22896393817971655
+```
+
+### Splunk
+
+
+Telegraf output plugin [splunk] HTTP Event Collector.
+
+```{cfgcmd} set service monitoring telegraf splunk authentication insecure
+
+Use TLS but skip host validation
+```
+
+
+```{cfgcmd} set service monitoring telegraf splunk authentication token \<token\>
+
+Authorization token
+```
+
+
+```{cfgcmd} set service monitoring telegraf splunk authentication url \<url\>
+
+Remote URL to Splunk collector
+```
+
+Example:
+
+```none
+set service monitoring telegraf splunk authentication insecure
+set service monitoring telegraf splunk authentication token 'xxxxf5b8-xxxx-452a-xxxx-43828911xxxx'
+set service monitoring telegraf splunk url 'https://192.0.2.10:8088/services/collector'
+```
+
+### InfluxDB
+
+
+Telegraf output plugin [influxdb] to write metrics to `InfluxDB` via HTTP.
+
+```{cfgcmd} set service monitoring telegraf influxdb authentication organization \<organization\>
+
+Authentication organization name
+```
+
+
+```{cfgcmd} set service monitoring telegraf influxdb authentication token \<token\>
+
+Authentication token
+```
+
+
+```{cfgcmd} set service monitoring telegraf bucket \<bucket\>
+
+Remote ``InfluxDB`` bucket name
+```
+
+
+```{cfgcmd} set service monitoring telegraf influxdb port \<port\>
+
+Remote port
+```
+
+
+```{cfgcmd} set service monitoring telegraf influxdb url \<url\>
+
+Remote URL
+```
+
+Example:
+
+```none
+set service monitoring telegraf influxdb authentication organization 'vyos'
+set service monitoring telegraf influxdb authentication token 'ZAml9Uy5wrhA...=='
+set service monitoring telegraf influxdb bucket 'bucket_vyos'
+set service monitoring telegraf influxdb port '8086'
+set service monitoring telegraf influxdb url 'http://r1.influxdb2.local'
+```
+
+### Loki
+
+Telegraf can be used to send logs to [loki] using tags as labels.
+
+```{cfgcmd} set service monitoring telegraf loki port \<port\>
+
+ Remote Loki port
+
+ Default is 3100
+```
+
+
+```{cfgcmd} set service monitoring telegraf loki url \<url\>
+
+Remote Loki url
+```
+
+
+```{cfgcmd} set service monitoring telegraf loki authentication username \<username\>
+```
+
+```{cfgcmd} set service monitoring telegraf loki authentication password \<password\>
+
+HTTP basic authentication.
+
+If either is set both must be set.
+```
+
+```{cfgcmd} set service monitoring telegraf loki metric-name-label \<label\>
+
+Label to use for the metric name when sending metrics.
+
+If set to an empty string, the label will not be added.
+This is NOT recommended, as it makes it impossible to differentiate
+between multiple metrics.
+```
+
+## Prometheus
+
+
+The following Prometheus exporters are configurable to export metrics:
+: - Node Exporter
+ - FRR Exporter
+
+
+### Node Exporter
+
+
+Prometheus [node_exporter] which provides a wide range of hardware and OS metrics.
+
+```{cfgcmd} set service monitoring prometheus node-exporter listen-address \<address\>
+
+Configure the address node_exporter is listening on.
+```
+
+```{cfgcmd} set service monitoring prometheus node-exporter port \<port\>
+
+Configure the port number node_exporter is listening on.
+```
+
+```{cfgcmd} set service monitoring prometheus node-exporter vrf \<name\>
+
+Configure name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance.
+```
+
+```{cfgcmd} set service monitoring prometheus node-exporter collectors textfile
+
+Configure textfile collector to export custom metrics read from
+`/run/node_exporter/collector`
+```
+
+### FRR Exporter
+
+Prometheus [frr_exporter] which provides free range routing metrics.
+
+```{cfgcmd} set service monitoring prometheus frr-exporter listen-address \<address\>
+
+Configure the address frr_exporter is listening on.
+
+```
+
+```{cfgcmd} set service monitoring prometheus frr-exporter port \<port\>
+
+Configure the port number frr_exporter is listening on.
+```
+
+```{cfgcmd} set service monitoring prometheus frr-exporter vrf \<name\>
+
+Configure name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance.
+```
+
+### Blackbox Exporter
+
+Prometheus [blackbox_exporter] which allows probing of endpoints over
+HTTP, HTTPS, DNS, TCP, ICMP and gRPC .
+
+```{cfgcmd} set service monitoring prometheus blackbox-exporter listen-address \<address\>
+
+Configure the address blackbox_exporter is listening on.
+```
+```{cfgcmd} set service monitoring prometheus blackbox-exporter port \<port\>
+
+Configure the port number blackbox_exporter is listening on.
+```
+```{cfgcmd} set service monitoring prometheus blackbox-exporter vrf \<name\>
+
+Configure name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance.
+```
+
+#### Configuring modules
+
+Blackbox exporter can be configured with different modules for probing DNS or ICMP.
+
+DNS module example:
+
+```none
+set service monitoring prometheus blackbox-exporter modules dns name dns4 preferred-ip-protocol ipv4
+set service monitoring prometheus blackbox-exporter modules dns name dns4 query-name vyos.io
+set service monitoring prometheus blackbox-exporter modules dns name dns4 query-type A
+```
+
+ICMP module example:
+
+```none
+set service monitoring prometheus blackbox-exporter modules icmp name ping6 preferred-ip-protocol ipv6
+set service monitoring prometheus blackbox-exporter modules icmp name ping6 ip-protocol-fallback
+set service monitoring prometheus blackbox-exporter modules icmp name ping6 timeout 3
+```
+
+[azure-data-explorer]: <https://github.com/influxdata/telegraf/tree/master/plugins/outputs/azure_data_explorer>
+[blackbox_exporter]: <https://github.com/prometheus/blackbox_exporter>
+[frr_exporter]: <https://github.com/tynany/frr_exporter>
+[influxdb]: <https://github.com/influxdata/telegraf/tree/master/plugins/outputs/influxdb_v2>
+[loki]: https://github.com/influxdata/telegraf/tree/master/plugins/outputs/loki
+[node_exporter]: <https://github.com/prometheus/node_exporter>
+[prometheus-client]: <https://github.com/influxdata/telegraf/tree/master/plugins/outputs/prometheus_client>
+[splunk]: <https://www.splunk.com/en_us/blog/it/splunk-metrics-via-telegraf.html>
diff --git a/docs/configuration/service/ntp.md b/docs/configuration/service/ntp.md
new file mode 100644
index 00000000..c8c1dee3
--- /dev/null
+++ b/docs/configuration/service/ntp.md
@@ -0,0 +1,202 @@
+(ntp)=
+
+# NTP
+
+{abbr}`NTP (Network Time Protocol`) is a networking protocol for clock
+synchronization between computer systems over packet-switched, variable-latency
+data networks. In operation since before 1985, NTP is one of the oldest Internet
+protocols in current use.
+
+NTP is intended to synchronize all participating computers to within a few
+milliseconds of {abbr}`UTC (Coordinated Universal Time)`. It uses the
+intersection algorithm, a modified version of Marzullo's algorithm, to select
+accurate time servers and is designed to mitigate the effects of variable
+network latency. NTP can usually maintain time to within tens of milliseconds
+over the public Internet, and can achieve better than one millisecond accuracy
+in local area networks under ideal conditions. Asymmetric routes and network
+congestion can cause errors of 100 ms or more.
+
+The protocol is usually described in terms of a client-server model, but can as
+easily be used in peer-to-peer relationships where both peers consider the other
+to be a potential time source. Implementations send and receive timestamps using
+{abbr}`UDP (User Datagram Protocol)` on port number 123.
+
+NTP supplies a warning of any impending leap second adjustment, but no
+information about local time zones or daylight saving time is transmitted.
+
+The current protocol is version 4 (NTPv4), which is a proposed standard as
+documented in {rfc}`5905`. It is backward compatible with version 3, specified
+in {rfc}`1305`.
+
+:::{note}
+VyOS 1.4 uses chrony instead of ntpd (see {vytask}`T3008`) which will
+no longer accept anonymous NTP requests as in VyOS 1.3. All configurations
+will be migrated to keep the anonymous functionality. For new setups if you
+have clients using your VyOS installation as NTP server, you must specify
+the `allow-client` directive.
+:::
+
+## Configuration
+
+```{cfgcmd} set service ntp server \<address\>
+
+ Configure one or more servers for synchronisation. Server name can be either
+ an IP address or {abbr}`FQDN (Fully Qualified Domain Name)`.
+
+ There are 3 default NTP server set. You are able to change them.
+
+ * ``time1.vyos.net``
+ * ``time2.vyos.net``
+ * ``time3.vyos.net``
+```
+
+
+```{cfgcmd} set service ntp server \<address\> \<noselect | nts | pool | prefer | ptp | interleave\>
+
+Configure one or more attributes to the given NTP server.
+
+* ``noselect`` marks the server as unused, except for display purposes. The
+server is discarded by the selection algorithm.
+
+* ``nts`` enables Network Time Security (NTS) for the server as specified
+in {rfc}`8915`
+
+* ``pool`` mobilizes persistent client mode association with a number of
+remote servers.
+
+* ``prefer`` marks the server as preferred. All other things being equal,
+this host will be chosen for synchronization among a set of correctly
+operating hosts.
+
+* ``ptp`` enables the PTP transport for this server (see {ref}`ptp-transport`).
+
+* ``interleave`` enables NTP interleaved mode (see [draft-ntp-interleaved-modes]), which can improve
+synchronization accuracy and stability when supported by both parties.
+```
+
+
+```{cfgcmd} set service ntp listen-address \<address\>
+
+NTP process will only listen on the specified IP address. You must specify
+the `<address>` and optionally the permitted clients. Multiple listen
+addresses for same IP family is no longer supported. Only one IPv4 and one
+IPv6 address can be configured, using separate commands for each.
+```
+
+
+```{cfgcmd} set service ntp allow-client address \<address\>
+
+List of networks or client addresses permitted to contact this NTP server.
+
+Multiple networks/client IP addresses can be configured.
+```
+
+
+```{cfgcmd} set service ntp vrf \<name\>
+
+Specify name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance.
+```
+
+
+```{cfgcmd} set service ntp leap-second [ignore|smear|system|timezone]
+
+Define how to handle leap-seconds.
+
+* `ignore`: No correction is applied to the clock for the leap second. The
+clock will be corrected later in normal operation when new measurements are
+made and the estimated offset includes the one second error.
+
+* `smear`: When smearing a leap second, the leap status is suppressed on the
+server and the served time is corrected slowly by slewing instead of
+stepping. The clients do not need any special configuration as they do not
+know there is any leap second and they follow the server time which
+eventually brings them back to UTC. Care must be taken to ensure they use
+only NTP servers which smear the leap second in exactly the same way for
+synchronisation.
+
+* `system`: When inserting a leap second, the kernel steps the system clock
+backwards by one second when the clock gets to 00:00:00 UTC. When deleting
+a leap second, it steps forward by one second when the clock gets to
+23:59:59 UTC.
+
+* `timezone`: This directive specifies a timezone in the system timezone
+database which chronyd can use to determine when will the next leap second
+occur and what is the current offset between TAI and UTC. It will
+periodically check if 23:59:59 and 23:59:60 are valid times in the
+timezone. This normally works with the right/UTC timezone which is the
+default
+```
+
+## Hardware Timestamping of NTP Packets
+
+
+The chrony daemon on VyOS can leverage NIC hardware capabilities to record the
+exact time packets are received on the interface, as well as when packets were
+actually transmitted. This provides improved accuracy and stability when the
+system is under load, as queuing and OS context switching can introduce a
+variable delay between when the packet is received on the network and when it
+is actually processed by the NTP daemon.
+
+
+Hardware timestamping depends on NIC support. Some NICs can be configured to
+apply timestamps to any incoming packet, while others only support applying
+timestamps to specific protocols (e.g. PTP).
+
+
+When timestamping is enabled on an interface, chrony's default behavior is to
+try to configure the interface to only timestamp NTP packets. If this mode is
+not supported, chrony will attempt to set it to timestamp all packets. If
+neither option is supported (e.g. the NIC can only timestamp received PTP
+packets), chrony will leverage timestamping on transmitted packets only, which
+still provides some benefit.
+
+```{cfgcmd} set service ntp timestamp interface \<interface\>
+
+Configures hardware timestamping on the interface \<interface\>. The special
+value `all` can also be specified to enable timestamping on all interfaces
+that support it.
+
+Configure the timestamping behavior with the following option:
+
+* ``receive-filter [all|ntp|ptp|none]`` selects the receive filter mode,
+which controls which inbound packets the NIC applies timestamps to. The
+selected mode must be supported by the NIC, or timestamping will be
+disabled for the interface.
+```
+
+The following `receive-filter` modes can be selected:
+- *all*: All received packets will be timestamped.
+- *ntp*: Only received NTP protocol packets will be timestamped.
+- *ptp*: Only received PTP protocol packets will be timestamped. Combined with
+ the PTP transport for NTP packets, this can be leveraged to take advantage of
+ hardware timestamping on NICs that only support the ptp filter mode.
+- *none*: No received packets will be timestamped. Hardware timestamping of
+ transmitted packets will still be leveraged, if supported by the NIC.
+(ptp-transport)=
+
+## PTP Transport of NTP Packets
+
+The Precision Time Protocol (IEEE 1588) is a local network time synchronization
+protocol that provides high precision time synchronization by leveraging
+hardware clocks in NICs and other network elements. VyOS does not currently
+support standards-based PTP, which can be deployed independently of
+NTP.
+
+For networks consisting of VyOS and other Linux systems running relatively
+recent versions of the chrony daemon, NTP packets can be "tunneled" over
+PTP. NTP over PTP provides the best of both worlds, leveraging hardware support
+for timestamping PTP packets while retaining the configuration flexibility and
+fault tolerance of NTP.
+
+```{cfgcmd} set service ntp ptp
+
+Enables the NTP daemon PTP transport. The NTP daemon will listen on the
+configured PTP port. Note that one or more servers must be individually
+enabled for PTP before the daemon will synchronize over the transport.
+```
+```{cfgcmd} set service ntp ptp port \<port\>
+
+Configures the PTP port. By default, the standard port 319 is used.
+```
+
+[draft-ntp-interleaved-modes]: https://datatracker.ietf.org/doc/draft-ietf-ntp-interleaved-modes/07/
diff --git a/docs/configuration/service/pppoe-server.md b/docs/configuration/service/pppoe-server.md
new file mode 100644
index 00000000..32881845
--- /dev/null
+++ b/docs/configuration/service/pppoe-server.md
@@ -0,0 +1,753 @@
+---
+lastproofread: '2022-09-17'
+---
+
+(pppoe-server)=
+
+# PPPoE Server
+
+VyOS utilizes [accel-ppp](https://accel-ppp.org/) to provide PPPoE server functionality. It can
+be used with local authentication or a connected RADIUS server.
+
+:::{note}
+Please be aware, due to an upstream bug, config
+changes/commits will restart the ppp daemon and will reset existing
+PPPoE connections from connected users, in order to become effective.
+:::
+
+## Configuring PPPoE Server
+
+```none
+set service pppoe-server access-concentrator PPPoE-Server
+set service pppoe-server authentication mode local
+set service pppoe-server authentication local-users username test password 'test'
+set service pppoe-server client-ip-pool PPPOE-POOL range 192.168.255.2-192.168.255.254
+set service pppoe-server default-pool 'PPPOE-POOL'
+set service pppoe-server gateway-address 192.168.255.1
+set service pppoe-server interface eth0
+```
+
+```{cfgcmd} set service pppoe-server access-concentrator \<name\>
+
+ Use this command to set a name for this PPPoE-server access
+ concentrator.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication mode \<local | radius\>
+
+Set authentication backend. The configured authentication backend is used
+for all queries.
+
+* **radius**: All authentication queries are handled by a configured RADIUS
+server.
+* **local**: All authentication queries are handled locally.
+* **noauth**: Authentication disabled.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication local-users username \<name\> password \<password\>
+
+Create `<user>` for local authentication on this system. The users password
+will be set to `<pass>`.
+```
+
+
+```{cfgcmd} set service pppoe-server client-ip-pool \<POOL-NAME\> range \<x.x.x.x-x.x.x.x | x.x.x.x/x\>
+
+Use this command to define the first IP address of a pool of
+addresses to be given to pppoe clients. If notation ``x.x.x.x-x.x.x.x``,
+it must be within a /24 subnet. If notation ``x.x.x.x/x`` is
+used there is possibility to set host/netmask.
+```
+
+
+```{cfgcmd} set service pppoe-server default-pool \<POOL-NAME\>
+
+Use this command to define default address pool name.
+```
+
+
+```{cfgcmd} set service pppoe-server interface \<interface\>
+
+Use this command to define the interface the PPPoE server will use to
+listen for PPPoE clients.
+```
+
+
+```{cfgcmd} set service pppoe-server gateway-address \<address\>
+
+Specifies single `<gateway>` IP address to be used as local address of PPP
+interfaces.
+```
+
+## Configuring RADIUS authentication
+
+To enable RADIUS based authentication, the authentication mode needs to be
+changed within the configuration. Previous settings like the local users, still
+exists within the configuration, however they are not used if the mode has been
+changed from local to radius. Once changed back to local, it will use all local
+accounts again.
+
+```none
+set service pppoe-server authentication mode radius
+```
+
+```{cfgcmd} set service pppoe-server authentication radius server \<server\> key \<secret\>
+
+Configure RADIUS `<server>` and its required shared `<secret>` for
+communicating with the RADIUS server.
+```
+
+Since the RADIUS server would be a single point of failure, multiple RADIUS
+servers can be setup and will be used subsequentially.
+For example:
+
+```none
+set service pppoe-server authentication radius server 10.0.0.1 key 'foo'
+set service pppoe-server authentication radius server 10.0.0.2 key 'foo'
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+
+### RADIUS source address
+
+
+If you are using OSPF as IGP, always the closest interface connected to the
+RADIUS server is used. With VyOS 1.2 you can bind all outgoing RADIUS requests
+to a single source IP e.g. the loopback interface.
+
+```{cfgcmd} set service pppoe-server authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+:::{note}
+The `source-address` must be configured on one of VyOS interface.
+Best practice would be a loopback or dummy interface.
+:::
+
+
+### RADIUS advanced options
+
+```{cfgcmd} set service pppoe-server authentication radius server \<server\> port \<port\>
+
+Configure RADIUS `<server>` and its required port for authentication requests.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius server \<server\> fail-time \<time\>
+
+Mark RADIUS server as offline for this given `<time>` in seconds.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius server \<server\> disable
+
+Temporary disable this RADIUS server.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius acct-timeout \<timeout\>
+
+Timeout to wait reply for Interim-Update packets. (default 3 seconds)
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius dynamic-author server \<address\>
+
+Specifies IP address for Dynamic Authorization Extension server (DM/CoA).
+This IP must exist on any VyOS interface or it can be ``0.0.0.0``.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius dynamic-author port \<port\>
+
+UDP port for Dynamic Authorization Extension server (DM/CoA)
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius dynamic-author key \<secret\>
+
+Secret for Dynamic Authorization Extension server (DM/CoA)
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius max-try \<number\>
+
+Maximum number of tries to send Access-Request/Accounting-Request queries
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius timeout \<timeout\>
+
+Timeout to wait response from server (seconds)
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius nas-identifier \<identifier\>
+
+Value to send to RADIUS server in NAS-Identifier attribute and to be matched
+in DM/CoA requests.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius nas-ip-address \<address\>
+
+Value to send to RADIUS server in NAS-IP-Address attribute and to be matched
+in DM/CoA requests. Also DM/CoA server will bind to that address.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius rate-limit attribute \<attribute\>
+
+Specifies which RADIUS server attribute contains the rate limit information.
+The default attribute is ``Filter-Id``.
+```
+
+:::{note}
+If you set a custom RADIUS attribute you must define it on both
+dictionaries at RADIUS server and client.
+:::
+
+```{cfgcmd} set service pppoe-server authentication radius rate-limit enable
+
+Enables bandwidth shaping via RADIUS.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication radius rate-limit vendor
+
+Specifies the vendor dictionary, dictionary needs to be in
+/usr/share/accel-ppp/radius.
+```
+
+Received RADIUS attributes have a higher priority than parameters defined within
+the CLI configuration, refer to the explanation below.
+
+
+### Allocation clients ip addresses by RADIUS
+
+
+If the RADIUS server sends the attribute `Framed-IP-Address` then this IP
+address will be allocated to the client and the option `default-pool`
+within the CLI config is being ignored.
+
+
+If the RADIUS server sends the attribute `Framed-Pool`, IP address will
+be allocated from a predefined IP pool whose name equals the attribute value.
+
+
+If the RADIUS server sends the attribute `Stateful-IPv6-Address-Pool`,
+IPv6 address will be allocated from a predefined IPv6 pool `prefix`
+whose name equals the attribute value.
+
+
+If the RADIUS server sends the attribute `Delegated-IPv6-Prefix-Pool`,
+IPv6 delegation pefix will be allocated from a predefined IPv6 pool `delegate`
+whose name equals the attribute value.
+
+
+:::{note}
+`Stateful-IPv6-Address-Pool` and `Delegated-IPv6-Prefix-Pool`
+are defined in RFC6911. If they are not defined in your RADIUS server,
+add new [dictionary].
+:::
+
+
+User interface can be put to VRF context via RADIUS Access-Accept packet,
+or change it via RADIUS CoA. `Accel-VRF-Name` is used from these purposes.
+It is custom [ACCEL-PPP attribute]. Define it in your RADIUS server.
+
+
+### Renaming clients interfaces by RADIUS
+
+
+If the RADIUS server uses the attribute `NAS-Port-Id`, ppp tunnels will be
+renamed.
+
+
+:::{note}
+The value of the attribute `NAS-Port-Id` must be less than 16
+characters, otherwise the interface won't be renamed.
+:::
+
+
+## Automatic VLAN Creation
+
+```{cfgcmd} set service pppoe-server interface \<interface\> vlan \<id | range\>
+
+VLAN's can be created by Accel-ppp on the fly via the use of a Kernel module
+named ``vlan_mon``, which is monitoring incoming vlans and creates the
+necessary VLAN if required and allowed. VyOS supports the use of either
+VLAN ID's or entire ranges, both values can be defined at the same time for
+an interface.
+
+When configured, PPPoE will create the necessary VLANs when required. Once
+the user session has been cancelled and the VLAN is not needed anymore, VyOS
+will remove it again.
+```
+
+
+```none
+set service pppoe-server interface eth3 vlan 100
+set service pppoe-server interface eth3 vlan 200
+set service pppoe-server interface eth3 vlan 500-1000
+set service pppoe-server interface eth3 vlan 2000-3000
+```
+
+## Bandwidth Shaping
+
+
+Bandwidth rate limits can be set for local users or RADIUS based
+attributes.
+
+
+### For Local Users
+
+```{cfgcmd} set service pppoe-server authentication local-users username \<user\> rate-limit download \<bandwidth\>
+
+Download bandwidth limit in kbit/s for `<user>`.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication local-users username \<user\> rate-limit upload \<bandwidth\>
+
+Upload bandwidth limit in kbit/s for `<user>`.
+```
+```none
+set service pppoe-server access-concentrator 'ACN'
+set service pppoe-server authentication local-users username foo password 'bar'
+set service pppoe-server authentication local-users username foo rate-limit download '20480'
+set service pppoe-server authentication local-users username foo rate-limit upload '10240'
+set service pppoe-server authentication mode 'local'
+set service pppoe-server client-ip-pool IP-POOL range '10.1.1.100/24'
+set service pppoe-server default-pool 'IP-POOL'
+set service pppoe-server name-server '10.100.100.1'
+set service pppoe-server name-server '10.100.200.1'
+set service pppoe-server interface 'eth1'
+set service pppoe-server gateway-address '10.1.1.2'
+```
+
+Once the user is connected, the user session is using the set limits and
+can be displayed via `show pppoe-server sessions`.
+
+```none
+show pppoe-server sessions
+ifname | username | ip | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+-------+----------+------------+-------------------+-------------+--------+----------+----------+----------
+ppp0 | foo | 10.1.1.100 | 00:53:00:ba:db:15 | 20480/10240 | active | 00:00:11 | 214 B | 76 B
+```
+
+### For RADIUS users
+
+The current attribute `Filter-Id` is being used as default and can be
+setup within RADIUS:
+
+Filter-Id=2000/3000 (means 2000Kbit down-stream rate and 3000Kbit
+up-stream rate)
+
+The command below enables it, assuming the RADIUS connection has been
+setup and is working.
+
+```{cfgcmd} set service pppoe-server authentication radius rate-limit enable
+
+ Use this command to enable bandwidth shaping via RADIUS.
+```
+
+Other attributes can be used, but they have to be in one of the
+dictionaries in */usr/share/accel-ppp/radius*.
+
+
+## Load Balancing
+
+```{cfgcmd} set service pppoe-server pado-delay \<number-of-ms\> sessions \<number-of-sessions\>
+
+Use this command to enable the delay of PADO (PPPoE Active Discovery
+Offer) packets, which can be used as a session balancing mechanism
+with other PPPoE servers.
+```
+
+
+```none
+set service pppoe-server pado-delay 50 sessions '500'
+set service pppoe-server pado-delay 100 sessions '1000'
+set service pppoe-server pado-delay 300 sessions '3000'
+```
+
+In the example above, the first 499 sessions connect without delay. PADO
+packets will be delayed 50 ms for connection from 500 to 999, this trick
+allows other PPPoE servers send PADO faster and clients will connect to
+other servers. Last command says that this PPPoE server can serve only
+3000 clients.
+
+
+## IPv6
+
+```{cfgcmd} set service pppoe-server ppp-options ipv6 \<require | prefer | allow | deny\>
+
+Specifies IPv6 negotiation preference.
+
+* **require** - Require IPv6 negotiation
+* **prefer** - Ask client for IPv6 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv6 only if client requests
+* **deny** - Do not negotiate IPv6 (default value)
+```
+
+
+```{cfgcmd} set service pppoe-server client-ipv6-pool \<IPv6-POOL-NAME\> prefix \<address\> mask \<number-of-bits\>
+
+Use this comand to set the IPv6 address pool from which an PPPoE client
+will get an IPv6 prefix of your defined length (mask) to terminate the
+PPPoE endpoint at their side. The mask length can be set from 48 to 128
+bit long, the default value is 64.
+```
+
+
+```{cfgcmd} set service pppoe-server client-ipv6-pool \<IPv6-POOL-NAME\> delegate \<address\> delegation-prefix \<number-of-bits\>
+
+Use this command to configure DHCPv6 Prefix Delegation (RFC3633) on
+PPPoE. You will have to set your IPv6 pool and the length of the
+delegation prefix. From the defined IPv6 pool you will be handing out
+networks of the defined length (delegation-prefix). The length of the
+delegation prefix can be set from 32 to 64 bit long.
+```
+
+
+```{cfgcmd} set service pppoe-server default-ipv6-pool \<IPv6-POOL-NAME\>
+
+Use this command to define default IPv6 address pool name.
+```
+
+
+```none
+set service pppoe-server ppp-options ipv6 allow
+set service pppoe-server client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set service pppoe-server client-ipv6-pool IPv6-POOL prefix '2001:db8:8002::/48' mask '64'
+set service pppoe-server default-ipv6-pool IPv6-POOL
+```
+
+### IPv6 Advanced Options
+
+```{cfgcmd} set service pppoe-server ppp-options ipv6-accept-peer-interface-id
+
+Accept peer interface identifier. By default is not defined.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies fixed or random interface identifier for IPv6.
+By default is fixed.
+
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies peer interface identifier for IPv6. By default is fixed.
+
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+* **ipv4-addr** - Calculate interface identifier from IPv4 address.
+* **calling-sid** - Calculate interface identifier from calling-station-id.
+```
+
+## Scripting
+
+```{cfgcmd} set service pppoe-server extended-scripts on-change \<path_to_script\>
+
+Script to run when session interface changed by RADIUS CoA handling
+```
+
+
+```{cfgcmd} set service pppoe-server extended-scripts on-down \<path_to_script\>
+
+Script to run when session interface going to terminate
+```
+
+
+```{cfgcmd} set service pppoe-server extended-scripts on-pre-up \<path_to_script\>
+
+Script to run before session interface comes up
+```
+
+
+```{cfgcmd} set service pppoe-server extended-scripts on-up \<path_to_script\>
+
+Script to run when session interface is completely configured and started
+```
+
+## Advanced Options
+
+
+### Authentication Advanced Options
+
+```{cfgcmd} set service pppoe-server authentication local-users username \<user\> disable
+
+Disable `<user>` account.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication local-users username \<user\> static-ip \<address\>
+
+Assign static IP address to `<user>` account.
+```
+
+
+```{cfgcmd} set service pppoe-server authentication protocols \<pap | chap | mschap | mschap-v2\>
+
+Require the peer to authenticate itself using one of the following protocols:
+pap, chap, mschap, mschap-v2.
+```
+
+### Client IP Pool Advanced Options
+
+```{cfgcmd} set service pppoe-server client-ip-pool \<POOL-NAME\> next-pool \<NEXT-POOL-NAME\>
+
+Use this command to define the next address pool name.
+```
+
+### PPP Advanced Options
+
+```{cfgcmd} set service pppoe-server ppp-options disable-ccp
+
+Disable Compression Control Protocol (CCP).
+CCP is enabled by default.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options interface-cache \<number\>
+
+Specifies number of interfaces to keep in cache. It means that don’t
+destroy interface after corresponding session is destroyed, instead
+place it to cache and use it later for new sessions repeatedly.
+This should reduce kernel-level interface creation/deletion rate lack.
+Default value is **0**.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options ipv4 \<require | prefer | allow | deny\>
+
+Specifies IPv4 negotiation preference.
+
+* **require** - Require IPv4 negotiation
+* **prefer** - Ask client for IPv4 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv4 only if client requests (Default value)
+* **deny** - Do not negotiate IPv4
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options lcp-echo-failure \<number\>
+
+Defines the maximum `<number>` of unanswered echo requests. Upon reaching the
+value `<number>`, the session will be reset. Default value is **3**.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options lcp-echo-interval \<interval\>
+
+If this option is specified and is greater than 0, then the PPP module will
+send LCP pings of the echo request every `<interval>` seconds.
+Default value is **30**.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options lcp-echo-timeout
+
+Specifies timeout in seconds to wait for any peer activity. If this option
+specified it turns on adaptive lcp echo functionality and "lcp-echo-failure"
+is not used. Default value is **0**.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options min-mtu \<number\>
+
+Defines minimum acceptable MTU. If client will try to negotiate less then
+specified MTU then it will be NAKed or disconnected if rejects greater MTU.
+Default value is **100**.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options mppe \<require | prefer | deny\>
+
+Specifies {abbr}`MPPE (Microsoft Point-to-Point Encryption)` negotiation
+preference.
+
+* **require** - ask client for mppe, if it rejects drop connection
+* **prefer** - ask client for mppe, if it rejects don't fail. (Default value)
+* **deny** - deny mppe
+
+Default behavior - don't ask client for mppe, but allow it if client wants.
+Please note that RADIUS may override this option by MS-MPPE-Encryption-Policy
+attribute.
+```
+
+
+```{cfgcmd} set service pppoe-server ppp-options mru \<number\>
+
+Defines preferred MRU. By default is not defined.
+```
+
+### Global Advanced options
+
+```{cfgcmd} set service pppoe-server description \<description\>
+
+Set description.
+```
+
+
+```{cfgcmd} set service pppoe-server limits burst \<value\>
+
+Burst count
+```
+
+
+```{cfgcmd} set service pppoe-server limits connection-limit \<value\>
+
+Acceptable rate of connections (e.g. 1/min, 60/sec)
+```
+
+
+```{cfgcmd} set service pppoe-server limits timeout \<value\>
+
+Timeout in seconds
+```
+
+
+```{cfgcmd} set service pppoe-server mtu
+
+Maximum Transmission Unit (MTU) (default: **1492**)
+```
+
+
+```{cfgcmd} set service pppoe-server max-concurrent-sessions
+
+Maximum number of concurrent session start attempts
+```
+
+
+```{cfgcmd} set service pppoe-server name-server \<address\>
+
+Connected client should use `<address>` as their DNS server. This
+command accepts both IPv4 and IPv6 addresses. Up to two nameservers
+can be configured for IPv4, up to three for IPv6.
+```
+
+
+```{cfgcmd} set service pppoe-server service-name \<names\>
+
+Specifies Service-Name to respond. If absent any Service-Name is
+acceptable and client’s Service-Name will be sent back. Also possible
+set multiple service-names: `sn1,sn2,sn3`
+```
+
+Per default the user session is being replaced if a second
+authentication request succeeds. Such session requests can be either
+denied or allowed entirely, which would allow multiple sessions for a
+user in the latter case. If it is denied, the second session is being
+rejected even if the authentication succeeds, the user has to terminate
+its first session and can then authentication again.
+
+```{cfgcmd} set service pppoe-server session-control
+
+* **disable**: Disables session control.
+* **deny**: Deny second session authorization.
+* **replace**: Terminate first session when second is authorized **(default)**
+```
+
+
+```{cfgcmd} set service pppoe-server shaper fwmark \<1-2147483647\>
+
+Match firewall mark value
+```
+
+
+```{cfgcmd} set service pppoe-server snmp master-agent
+
+Enable SNMP
+```
+
+
+```{cfgcmd} set service pppoe-server wins-server \<address\>
+
+Windows Internet Name Service (WINS) servers propagated to client
+```
+
+## Monitoring
+
+```{opcmd} show pppoe-server sessions
+
+Use this command to locally check the active sessions in the PPPoE
+server.
+```
+```none
+show pppoe-server sessions
+ifname | username | ip | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+-------+----------+------------+-------------------+-------------+--------+----------+----------+----------
+ppp0 | foo | 10.1.1.100 | 00:53:00:ba:db:15 | 20480/10240 | active | 00:00:11 | 214 B | 76 B
+```
+
+## Examples
+### IPv4
+
+The example below uses ACN as access-concentrator name, assigns an
+address from the pool 10.1.1.100-111, terminates at the local endpoint
+10.1.1.1 and serves requests only on eth1.
+
+```none
+set service pppoe-server access-concentrator 'ACN'
+set service pppoe-server authentication local-users username foo password 'bar'
+set service pppoe-server authentication mode 'local'
+set service pppoe-server client-ip-pool IP-POOL range '10.1.1.100-10.1.1.111'
+set service pppoe-server default-pool 'IP-POOL'
+set service pppoe-server interface eth1
+set service pppoe-server gateway-address '10.1.1.2'
+set service pppoe-server name-server '10.100.100.1'
+set service pppoe-server name-server '10.100.200.1'
+```
+
+### Dual-Stack IPv4/IPv6 provisioning with Prefix Delegation
+
+The example below covers a dual-stack configuration.
+
+```none
+set service pppoe-server authentication local-users username test password 'test'
+set service pppoe-server authentication mode 'local'
+set service pppoe-server client-ip-pool IP-POOL range '192.168.0.1/24'
+set service pppoe-server default-pool 'IP-POOL'
+set service pppoe-server client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set service pppoe-server client-ipv6-pool IPV6-POOL prefix '2001:db8:8002::/48' mask '64'
+set service pppoe-server default-ipv6-pool IPv6-POOL
+set service pppoe-server ppp-options ipv6 allow
+set service pppoe-server name-server '10.1.1.1'
+set service pppoe-server name-server '2001:db8:4860::8888'
+set service pppoe-server interface 'eth2'
+set service pppoe-server gateway-address '10.100.100.1'
+```
+
+The client, once successfully authenticated, will receive an IPv4 and an
+IPv6 /64 address to terminate the PPPoE endpoint on the client side and
+a /56 subnet for the clients internal use.
+
+```none
+vyos@pppoe-server:~$ sh pppoe-server sessions
+ ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+--------+----------+-------------+--------------------------+---------------------+-------------------+------------+--------+----------+----------+----------
+ ppp0 | test | 192.168.0.1 | 2001:db8:8002:0:200::/64 | 2001:db8:8003::1/56 | 00:53:00:12:42:eb | | active | 00:00:49 | 875 B | 2.1 KiB
+```
+
+[accel-ppp attribute]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.accel
+[dictionary]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.rfc6911
diff --git a/docs/configuration/service/router-advert.md b/docs/configuration/service/router-advert.md
new file mode 100644
index 00000000..10753105
--- /dev/null
+++ b/docs/configuration/service/router-advert.md
@@ -0,0 +1,121 @@
+(router-advert)=
+
+# Router Advertisements
+
+{abbr}`RAs (Router advertisements)` are described in {rfc}`4861#section-4.6.2`.
+They are part of what is known as {abbr}`SLAAC (Stateless Address
+Autoconfiguration)`.
+
+Supported interface types:
+
+> - bonding
+> - bridge
+> - ethernet
+> - geneve
+> - l2tpv3
+> - openvpn
+> - pseudo-ethernet
+> - tunnel
+> - vxlan
+> - wireguard
+> - wireless
+> - wwan
+
+## Configuration
+
+```{cfgcmd} set service router-advert interface \<interface\> ...
+```
+
+```{eval-rst}
+.. csv-table::
+ :header: "Field", "VyOS Option", "Description"
+ :widths: 10, 10, 20
+
+ "Cur Hop Limit", "hop-limit", "Hop count field of the outgoing RA packets"
+ """Managed address configuration"" flag", "managed-flag", "Tell hosts to use the administered stateful protocol (i.e. DHCP) for autoconfiguration"
+ """Other configuration"" flag", "other-config-flag", "Tell hosts to use the administered (stateful) protocol (i.e. DHCP) for autoconfiguration of other (non-address) information"
+ "MTU","link-mtu","Link MTU value placed in RAs, excluded in RAs if unset"
+ "Router Lifetime","default-lifetime","Lifetime associated with the default router in units of seconds"
+ "Reachable Time","reachable-time","Time, in milliseconds, that a node assumes a neighbor is reachable after having received a reachability confirmation"
+ "Retransmit Timer","retrans-timer","Time in milliseconds between retransmitted Neighbor Solicitation messages"
+ "Default Router Preference","default-preference","Preference associated with the default router"
+ "Interval", "interval", "Min and max intervals between unsolicited multicast RAs"
+ "DNSSL", "dnssl", "DNS search list to advertise"
+ "Name Server", "name-server", "Advertise DNS server per https://tools.ietf.org/html/rfc6106"
+ "Auto Ignore Prefix", "auto-ignore", "Exclude a prefix from being advertised when the wildcard ::/64 prefix is used"
+ "Captive Portal", "captive-portal", "Advertise a URL pointing to an RFC 8908-compliant API to tell hosts that they are behind a captive portal"
+```
+
+### Advertising a Prefix
+
+```{cfgcmd} set service router-advert interface \<interface\> prefix \<prefix/mask\>
+
+:::{note}
+You can also opt for using ::/64 as prefix for your {abbr}`RAs (Router
+Advertisements)`. This is a special wildcard prefix that will emit {abbr}`RAs (Router Advertisements)` for every prefix assigned to the interface.
+This comes in handy when using dynamically obtained prefixes from DHCPv6-PD.
+:::
+```
+```{eval-rst}
+.. csv-table::
+ :header: "VyOS Field", "Description"
+ :widths: 10,30
+
+ "decrement-lifetime", "Lifetime is decremented by the number of seconds since the last RA - use in conjunction with a DHCPv6-PD prefix"
+ "deprecate-prefix", "Upon shutdown, this option will deprecate the prefix by announcing it in the shutdown RA"
+ "no-autonomous-flag","Prefix can not be used for stateless address auto-configuration"
+ "no-on-link-flag","Prefix can not be used for on-link determination"
+ "preferred-lifetime","Time in seconds that the prefix will remain preferred (default 4 hours)"
+ "valid-lifetime","Time in seconds that the prefix will remain valid (default: 30 days)"
+```
+
+### Advertising a NAT64 Prefix
+
+```{cfgcmd} set service router-advert interface \<interface\> nat64prefix \<prefix/mask\>
+
+Enable PREF64 option as outlined in {rfc}`8781`.
+
+NAT64 prefix mask must be one of: /32, /40, /48, /56, /64 or 96.
+
+:::{note}
+The well known NAT64 prefix is ``64:ff9b::/96``
+:::
+```
+```{eval-rst}
+.. csv-table::
+ :header: "VyOS Field", "Description"
+ :widths: 10,30
+
+ "valid-lifetime","Time in seconds that the prefix will remain valid (default: 65528 seconds)"
+```
+
+### Disabling Advertisements
+
+To disable advertisements without deleting the configuration:
+
+```{cfgcmd} set service router-advert interface \<interface\> no-send-advert
+
+If set, the router will no longer send periodic router advertisements and
+will not respond to router solicitations.
+```
+
+```{cfgcmd} set service router-advert interface \<interface\> no-send-interval
+
+Advertisement Interval Option (specified by Mobile IPv6) is always included in
+Router Advertisements unless this option is set.
+```
+
+## Example
+
+Your LAN connected on eth0 uses prefix `2001:db8:beef:2::/64` with the router
+beeing `2001:db8:beef:2::1`
+
+```none
+set interfaces ethernet eth0 address 2001:db8:beef:2::1/64
+
+set service router-advert interface eth0 default-preference 'high'
+set service router-advert interface eth0 name-server '2001:db8::1'
+set service router-advert interface eth0 name-server '2001:db8::2'
+set service router-advert interface eth0 other-config-flag
+set service router-advert interface eth0 prefix 2001:db8:beef:2::/64
+```
diff --git a/docs/configuration/service/salt-minion.md b/docs/configuration/service/salt-minion.md
new file mode 100644
index 00000000..e6f99752
--- /dev/null
+++ b/docs/configuration/service/salt-minion.md
@@ -0,0 +1,51 @@
+(saltminion)=
+
+# Salt-Minion
+
+[SaltStack] is Python-based, open-source
+software for event-driven IT automation, remote task execution, and
+configuration management. Supporting the "infrastructure as code"
+approach to data center system and network deployment and management,
+configuration automation, SecOps orchestration, vulnerability remediation,
+and hybrid cloud control.
+
+## Requirements
+
+To use the Salt-Minion, a running Salt-Master is required. You can find more
+in the [Salt Project Documentation](https://docs.saltproject.io/en/latest/contents.html)
+
+## Configuration
+
+```{cfgcmd} set service salt-minion hash \<type\>
+
+ The hash type used when discovering file on master server (default: sha256)
+```
+
+
+```{cfgcmd} set service salt-minion id \<id\>
+
+Explicitly declare ID for this minion to use (default: hostname)
+```
+
+
+```{cfgcmd} set service salt-minion interval \<1-1440\>
+
+Interval in minutes between updates (default: 60)
+```
+
+
+```{cfgcmd} set service salt-minion master \<hostname | IP\>
+
+The hostname or IP address of the master
+```
+
+
+```{cfgcmd} set service salt-minion master-key \<key\>
+
+URL with signature of master for auth reply verification
+```
+
+Please take a look in the Automation section to find some usefull
+Examples.
+
+[saltstack]: https://saltproject.io/
diff --git a/docs/configuration/service/snmp.md b/docs/configuration/service/snmp.md
new file mode 100644
index 00000000..ac0429ff
--- /dev/null
+++ b/docs/configuration/service/snmp.md
@@ -0,0 +1,258 @@
+(snmp)=
+
+# SNMP
+
+{abbr}`SNMP (Simple Network Management Protocol)` is an Internet Standard
+protocol for collecting and organizing information about managed devices on
+IP networks and for modifying that information to change device behavior.
+Devices that typically support SNMP include cable modems, routers, switches,
+servers, workstations, printers, and more.
+
+SNMP is widely used in network management for network monitoring. SNMP exposes
+management data in the form of variables on the managed systems organized in
+a management information base ([MIB]) which describe the system status and
+configuration. These variables can then be remotely queried (and, in some
+circumstances, manipulated) by managing applications.
+
+Three significant versions of SNMP have been developed and deployed. SNMPv1 is
+the original version of the protocol. More recent versions, SNMPv2c and SNMPv3,
+feature improvements in performance, flexibility and security.
+
+SNMP is a component of the Internet Protocol Suite as defined by the Internet
+Engineering Task Force (IETF). It consists of a set of standards for network
+management, including an application layer protocol, a database schema, and a
+set of data objects.
+
+## Overview and basic concepts
+
+In typical uses of SNMP, one or more administrative computers called managers
+have the task of monitoring or managing a group of hosts or devices on a
+computer network. Each managed system executes a software component called an
+agent which reports information via SNMP to the manager.
+
+An SNMP-managed network consists of three key components:
+
+- Managed devices
+- Agent - software which runs on managed devices
+- Network management station (NMS) - software which runs on the manager
+
+A managed device is a network node that implements an SNMP interface that
+allows unidirectional (read-only) or bidirectional (read and write) access to
+node-specific information. Managed devices exchange node-specific information
+with the NMSs. Sometimes called network elements, the managed devices can be
+any type of device, including, but not limited to, routers, access servers,
+switches, cable modems, bridges, hubs, IP telephones, IP video cameras,
+computer hosts, and printers.
+
+An agent is a network-management software module that resides on a managed
+device. An agent has local knowledge of management information and translates
+that information to or from an SNMP-specific form.
+
+A network management station executes applications that monitor and control
+managed devices. NMSs provide the bulk of the processing and memory resources
+required for network management. One or more NMSs may exist on any managed
+network.
+
+:::{figure} /_static/images/service_snmp_communication_principles_diagram.webp
+:alt: Principle of SNMP Communication
+:scale: 20 %
+
+Image thankfully borrowed from
+<https://en.wikipedia.org/wiki/File:SNMP_communication_principles_diagram.PNG>
+which is under the GNU Free Documentation License
+:::
+
+:::{note}
+VyOS SNMP supports both IPv4 and IPv6.
+:::
+
+## SNMP Protocol Versions
+
+VyOS itself supports [SNMPv2] (version 2) and [SNMPv3] (version 3) where the
+later is recommended because of improved security (optional authentication and
+encryption).
+
+### SNMPv2
+
+SNMPv2 is the original and most commonly used version. For authorizing clients,
+SNMP uses the concept of communities. Communities may have authorization set
+to read only (this is most common) or to read and write (this option is not
+actively used in VyOS).
+
+SNMP can work synchronously or asynchronously. In synchronous communication,
+the monitoring system queries the router periodically. In asynchronous, the
+router sends notification to the "trap" (the monitoring host).
+
+SNMPv2 does not support any authentication mechanisms, other than client source
+address, so you should specify addresses of clients allowed to monitor the
+router. Note that SNMPv2 also supports no encryption and always sends data in
+plain text.
+
+#### Example
+
+```none
+# Define a community
+set service snmp community routers authorization ro
+
+# Allow monitoring access from the entire network
+set service snmp community routers network 192.0.2.0/24
+set service snmp community routers network 2001::db8:ffff:eeee::/64
+
+# Allow monitoring access from specific addresses
+set service snmp community routers client 203.0.113.10
+set service snmp community routers client 203.0.113.20
+
+# Define optional router information
+set service snmp location "UK, London"
+set service snmp contact "admin@example.com"
+
+# Trap target if you want asynchronous communication
+set service snmp trap-target 203.0.113.10
+
+# Listen only on specific IP addresses (port defaults to 161)
+set service snmp listen-address 172.16.254.36 port 161
+set service snmp listen-address 2001:db8::f00::1
+```
+
+
+### SNMPv3
+
+SNMPv3 (version 3 of the SNMP protocol) introduced a whole slew of new security
+related features that have been missing from the previous versions. Security
+was one of the biggest weakness of SNMP until v3. Authentication in SNMP
+Versions 1 and 2 amounts to nothing more than a password (community string)
+sent in clear text between a manager and agent. Each SNMPv3 message contains
+security parameters which are encoded as an octet string. The meaning of these
+security parameters depends on the security model being used.
+
+The security approach in SNMPv3 targets:
+
+- Confidentiality – Encryption of packets to prevent snooping by an
+ unauthorized source.
+- Integrity – Message integrity to ensure that a packet has not been tampered
+ while in transit including an optional packet replay protection mechanism.
+- Authentication – to verify that the message is from a valid source.
+
+(snmp-v3-example)=
+
+#### Example
+
+- Let SNMP daemon listen only on IP address 192.0.2.1
+- Configure new SNMP user named "vyos" with password "vyos12345678"
+- New user will use SHA/AES for authentication and privacy
+
+```none
+set service snmp listen-address 192.0.2.1
+set service snmp location 'VyOS Datacenter'
+set service snmp v3 engineid '000000000000000000000002'
+set service snmp v3 group default mode 'ro'
+set service snmp v3 group default view 'default'
+set service snmp v3 user vyos auth plaintext-password 'vyos12345678'
+set service snmp v3 user vyos auth type 'sha'
+set service snmp v3 user vyos group 'default'
+set service snmp v3 user vyos privacy plaintext-password 'vyos12345678'
+set service snmp v3 user vyos privacy type 'aes'
+set service snmp v3 view default oid 1
+```
+
+After commit the plaintext passwords will be hashed and stored in your
+configuration. The resulting CLI config will look like:
+
+```none
+vyos@vyos# show service snmp
+ listen-address 192.0.2.1 {
+ }
+ location "VyOS Datacenter"
+ v3 {
+ engineid 000000000000000000000002
+ group default {
+ mode ro
+ view default
+ }
+ user vyos {
+ auth {
+ encrypted-password 4e52fe55fd011c9c51ae2c65f4b78ca93dcafdfe
+ type sha
+ }
+ group default
+ privacy {
+ encrypted-password 4e52fe55fd011c9c51ae2c65f4b78ca93dcafdfe
+ type aes
+ }
+ }
+ view default {
+ oid 1 {
+ }
+ }
+ }
+```
+
+You can test the SNMPv3 functionality from any linux based system, just run the
+following command: `snmpwalk -v 3 -u vyos -a SHA -A vyos12345678 -x AES
+-X vyos12345678 -l authPriv 192.0.2.1 .1`
+
+## VyOS MIBs
+
+All SNMP MIBs are located in each image of VyOS here: `/usr/share/snmp/mibs/`
+
+You are be able to download the files using SCP, once the SSH service
+has been activated like so
+
+```none
+scp -r vyos@your_router:/usr/share/snmp/mibs /your_folder/mibs
+```
+
+
+## SNMP Extensions
+
+To extend SNMP agent functionality, custom scripts can be executed every time
+the agent is being called. This can be achieved by using
+`arbitrary extensioncommands`. The first step is to create a functional
+script of course, then upload it to your VyOS instance via the command
+`scp your_script.sh vyos@your_router:/config/user-data`.
+Once the script is uploaded, it needs to be configured via the command below.
+
+```none
+set service snmp script-extensions extension-name my-extension script your_script.sh
+commit
+```
+
+The OID `.1.3.6.1.4.1.8072.1.3.2.3.1.1.4.116.101.115.116`, once called, will
+contain the output of the extension.
+
+```none
+root@vyos:/home/vyos# snmpwalk -v2c -c public 127.0.0.1 nsExtendOutput1
+NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."my-extension" = STRING: hello
+NET-SNMP-EXTEND-MIB::nsExtendOutputFull."my-extension" = STRING: hello
+NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."my-extension" = INTEGER: 1
+NET-SNMP-EXTEND-MIB::nsExtendResult."my-extension" = INTEGER: 0
+```
+
+
+## SolarWinds
+
+If you happen to use SolarWinds Orion as NMS you can also use the Device
+Templates Management. A template for VyOS can be easily imported.
+
+Create a file named `VyOS-1.3.6.1.4.1.44641.ConfigMgmt-Commands` using the
+following content:
+
+```none
+<Configuration-Management Device="VyOS" SystemOID="1.3.6.1.4.1.44641">
+ <Commands>
+ <Command Name="Reset" Value="set terminal width 0${CRLF}set terminal length 0"/>
+ <Command Name="Reboot" Value="reboot${CRLF}Yes"/>
+ <Command Name="EnterConfigMode" Value="configure"/>
+ <Command Name="ExitConfigMode" Value="commit${CRLF}exit"/>
+ <Command Name="DownloadConfig" Value="show configuration commands"/>
+ <Command Name="SaveConfig" Value="commit${CRLF}save"/>
+ <Command Name="Version" Value="show version"/>
+ <Command Name="MenuBased" Value="False"/>
+ <Command Name="VirtualPrompt" Value=":~"/>
+ </Commands>
+</Configuration-Management>
+```
+
+[mib]: <https://en.wikipedia.org/wiki/Management_information_base>
+[snmpv2]: <https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#Version_2>
+[snmpv3]: <https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#Version_3>
diff --git a/docs/configuration/service/ssh.md b/docs/configuration/service/ssh.md
new file mode 100644
index 00000000..d873cbee
--- /dev/null
+++ b/docs/configuration/service/ssh.md
@@ -0,0 +1,366 @@
+(ssh)=
+
+# SSH
+
+{abbr}`SSH (Secure Shell)` is a cryptographic network protocol for operating
+network services securely over an unsecured network. The standard TCP port for
+SSH is 22. The best known example application is for remote login to computer
+systems by users.
+
+SSH provides a secure channel over an unsecured network in a client-server
+architecture, connecting an SSH client application with an SSH server. Common
+applications include remote command-line login and remote command execution,
+but any network service can be secured with SSH. The protocol specification
+distinguishes between two major versions, referred to as SSH-1 and SSH-2.
+
+The most visible application of the protocol is for access to shell accounts
+on Unix-like operating systems, but it sees some limited use on Windows as
+well. In 2015, Microsoft announced that they would include native support for
+SSH in a future release.
+
+SSH was designed as a replacement for Telnet and for unsecured remote shell
+protocols such as the Berkeley rlogin, rsh, and rexec protocols.
+Those protocols send information, notably passwords, in plaintext,
+rendering them susceptible to interception and disclosure using packet
+analysis. The encryption used by SSH is intended to provide confidentiality
+and integrity of data over an unsecured network, such as the Internet.
+
+:::{note}
+VyOS 1.1 supported login as user `root`. This has been removed due
+to tighter security in VyOS 1.2.
+:::
+
+:::{seealso}
+SSH {ref}`ssh_key_based_authentication`
+:::
+
+## Configuration
+
+```{cfgcmd} set service ssh port \<port\>
+
+Enabling SSH only requires you to specify the port ``<port>`` you want SSH to
+listen on. By default, SSH runs on port 22.
+```
+
+
+```{cfgcmd} set service ssh listen-address \<address\>
+
+Specify IPv4/IPv6 listen address of SSH server. Multiple addresses can be
+defined.
+```
+
+
+```{cfgcmd} set service ssh cipher \<cipher\>
+
+Define allowed ciphers used for the SSH connection. A number of allowed
+ciphers can be specified, use multiple occurrences to allow multiple ciphers.
+
+List of supported ciphers: ``3des-cbc``, ``aes128-cbc``, ``aes192-cbc``,
+``aes256-cbc``, ``aes128-ctr``, ``aes192-ctr``, ``aes256-ctr``,
+``aes128-gcm@openssh.com``, ``aes256-gcm@openssh.com``,
+``chacha20-poly1305@openssh.com``
+```
+
+
+```{cfgcmd} set service ssh disable-password-authentication
+
+Disable password based authentication. Login via SSH keys only. This hardens
+security!
+```
+
+
+```{cfgcmd} set service ssh fido pin-required
+
+Require FIDO2 keys to attest that a user has been verified (e.g. via a PIN).
+```
+
+
+````{cfgcmd} set service ssh fido touch-required
+
+Require FIDO2 keys to attest that a user is physically present.
+
+VyOS supports SSH authentication using FIDO2-backed keys generated by OpenSSH.
+Two FIDO2 key types are supported by OpenSSH: ``ed25519-sk``, ``ecdsa-sk``
+
+Generic FIDO2-backed SSH key generation example:
+
+:::{code-block} none
+ssh-keygen -t ecdsa-sk -O verify-required -C "fido2-ssh-key"
+:::
+
+```{eval-rst}
+During key generation, OpenSSH will:
+ * Request user presence (for example, a physical touch or confirmation)
+ * Optionally request user verification (PIN), if supported by the authenticator
+ * Create a local key handle file and a corresponding public key (``.pub``)
+```
+
+The private key material never leaves the authenticator device.
+
+VyOS configuration example:
+
+:::{code-block} none
+# Generate a FIDO2 SSH key on the client system
+# Copy the public key to the VyOS instance
+set system login user vyos authentication public-keys fido key '<public-key>'
+set system login user vyos authentication public-keys fido type 'sk-ecdsa-sha2-nistp256@openssh.com'
+set service ssh fido touch-required
+:::
+
+You can now log into the system using: ``ssh -i ~/.ssh/id_fido_key vyos@192.0.2.1``
+````
+
+
+```{cfgcmd} set service ssh disable-host-validation
+
+Disable the host validation through reverse DNS lookups - can speedup login
+time when reverse lookup is not possible.
+```
+
+
+```{cfgcmd} set service ssh mac \<mac\>
+
+Specifies the available {abbr}`MAC (Message Authentication Code)` algorithms.
+The MAC algorithm is used in protocol version 2 for data integrity protection.
+Multiple algorithms can be provided by using multiple commands, defining
+one algorithm per command.
+
+List of supported MACs: ``hmac-md5``, ``hmac-md5-96``, ``hmac-ripemd160``,
+``hmac-sha1``, ``hmac-sha1-96``, ``hmac-sha2-256``, ``hmac-sha2-512``,
+``umac-64@openssh.com``, ``umac-128@openssh.com``,
+``hmac-md5-etm@openssh.com``, ``hmac-md5-96-etm@openssh.com``,
+``hmac-ripemd160-etm@openssh.com``, ``hmac-sha1-etm@openssh.com``,
+``hmac-sha1-96-etm@openssh.com``, ``hmac-sha2-256-etm@openssh.com``,
+``hmac-sha2-512-etm@openssh.com``, ``umac-64-etm@openssh.com``,
+``umac-128-etm@openssh.com``
+```
+
+
+```{cfgcmd} set service ssh access-control \<allow | deny\> \<group | user\> \<name\>
+
+Add access-control directive to allow or deny users and groups. Directives
+are processed in the following order of precedence: ``deny-users``,
+``allow-users``, ``deny-groups`` and ``allow-groups``.
+```
+
+
+```{cfgcmd} set service ssh client-keepalive-interval \<interval\>
+
+Specify timeout interval for keepalive message in seconds.
+```
+
+
+```{cfgcmd} set service ssh key-exchange \<kex\>
+
+Specify allowed {abbr}`KEX (Key Exchange)` algorithms.
+
+List of supported algorithms: ``diffie-hellman-group1-sha1``,
+``diffie-hellman-group14-sha1``, ``diffie-hellman-group14-sha256``,
+``diffie-hellman-group16-sha512``, ``diffie-hellman-group18-sha512``,
+``diffie-hellman-group-exchange-sha1``,
+``diffie-hellman-group-exchange-sha256``,
+``ecdh-sha2-nistp256``, ``ecdh-sha2-nistp384``, ``ecdh-sha2-nistp521``,
+``curve25519-sha256`` and ``curve25519-sha256@libssh.org``.
+```
+
+
+```{cfgcmd} set service ssh loglevel \<quiet | fatal | error | info | verbose\>
+
+Set the ``sshd`` log level. The default is ``info``.
+```
+
+
+```{cfgcmd} set service ssh vrf \<name\>
+
+Specify name of the {abbr}`VRF (Virtual Routing and Forwarding)` instance.
+```
+
+
+```{cfgcmd} set service ssh pubkey-accepted-algorithm \<name\>
+
+Specifies the signature algorithms that will be accepted for public key
+authentication
+
+List of supported algorithms: ``ssh-ed25519``,
+``ssh-ed25519-cert-v01@openssh.com``, ``sk-ssh-ed25519@openssh.com``,
+``sk-ssh-ed25519-cert-v01@openssh.com``, ``ecdsa-sha2-nistp256``,
+``ecdsa-sha2-nistp256-cert-v01@openssh.com``, ``ecdsa-sha2-nistp384``,
+``ecdsa-sha2-nistp384-cert-v01@openssh.com``, ``ecdsa-sha2-nistp521``,
+``ecdsa-sha2-nistp521-cert-v01@openssh.com``,
+``sk-ecdsa-sha2-nistp256@openssh.com``,
+``sk-ecdsa-sha2-nistp256-cert-v01@openssh.com``,
+``webauthn-sk-ecdsa-sha2-nistp256@openssh.com``,
+``ssh-dss``, ``ssh-dss-cert-v01@openssh.com``, ``ssh-rsa``,
+``ssh-rsa-cert-v01@openssh.com``, ``rsa-sha2-256``,
+``rsa-sha2-256-cert-v01@openssh.com``, ``rsa-sha2-512``,
+``rsa-sha2-512-cert-v01@openssh.com``
+```
+
+
+```{cfgcmd} set service ssh trusted-user-ca \<name\>
+
+Specify the name of the OpenSSH key-pair that acts as certificate authority
+and will be used to verify user certificates.
+
+You can use it by adding the OpenSSH key-pair under the PKI subsystem.
+
+Example:
+
+:::{code-block} none
+# Generate key-pair acting as CA
+$ ssh-keygen -f vyos-ssh-ca.key
+
+# Generate key for user: vyos_testca
+$ ssh-keygen -f vyos_testca -C "vyos_tesca@vyos.net"
+
+# Sign public key from user vyos_testca and insert principal names: vyos, vyos_testca
+# with a key lifetime of two weeks - after which the key is unusable
+$ ssh-keygen -s vyos-ssh-ca.key -I vyos_testca@vyos.net -n vyos,vyos_testca -V +2w vyos_testca.pub
+
+$ set system login user vyos_testca
+$ set pki openssh test_ca public key AAAAB3N.....
+$ set pki openssh test_ca public type ssh-rsa
+$ set service ssh trusted-user-ca test_ca
+:::
+You can now log into the system using: ``ssh -i vyos_testca vyos_testca@vyos.test.com``
+```
+
+## Dynamic-protection
+
+Protects host from brute-force attacks against
+SSH. Log messages are parsed, line-by-line, for recognized patterns. If an
+attack, such as several login failures within a few seconds, is detected, the
+offending IP is blocked. Offenders are unblocked after a set interval.
+
+```{cfgcmd} set service ssh dynamic-protection
+
+Allow ``ssh`` dynamic-protection.
+```
+```{cfgcmd} set service ssh dynamic-protection allow-from \<address | prefix\>
+
+Whitelist of addresses and networks. Always allow inbound connections from
+these systems.
+```
+```{cfgcmd} set service ssh dynamic-protection block-time \<sec\>
+
+Block source IP in seconds. Subsequent blocks increase by a factor of 1.5
+The default is 120.
+```
+```{cfgcmd} set service ssh dynamic-protection detect-time \<sec\>
+
+Remember source IP in seconds before reset their score. The default is 1800.
+```
+```{cfgcmd} set service ssh dynamic-protection threshold \<sec\>
+
+Block source IP when their cumulative attack score exceeds threshold. The
+default is 30.
+```
+
+(ssh-operation)=
+
+## Operation
+
+```{opcmd} restart ssh
+
+Restart the SSH daemon process, the current session is not affected, only the
+background daemon is restarted.
+```
+```{opcmd} generate ssh server-key
+
+Re-generated the public/private keyportion which SSH uses to secure
+connections.
+
+:::{note}
+Already learned known_hosts files of clients need an update as the
+public key will change.
+:::
+```
+```{opcmd} generate ssh client-key /path/to/private_key
+
+Re-generated a known pub/private keyfile which can be used to connect to
+other services (e.g. RPKI cache).
+
+Example:
+
+:::{code-block} none
+vyos@vyos:~$ generate ssh client-key /config/auth/id_rsa_rpki
+Generating public/private rsa key pair.
+Your identification has been saved in /config/auth/id_rsa_rpki.
+Your public key has been saved in /config/auth/id_rsa_rpki.pub.
+The key fingerprint is:
+SHA256:XGv2PpdOzVCzpmEzJZga8hTRq7B/ZYL3fXaioLFLS5Q vyos@vyos
+The key's randomart image is:
++---[RSA 2048]----+
+| oo |
+| ..o |
+| . o.o.. o.|
+| o+ooo o.o|
+| Eo* =.o |
+| o = +.o*+ |
+| = o *.o.o|
+| o * +.o+.+|
+| =.. o=.oo|
++----[SHA256]-----+
+:::
+Two new files ``/config/auth/id_rsa_rpki`` and
+``/config/auth/id_rsa_rpki.pub``
+will be created.
+```
+```{opcmd} generate public-key-command user \<username\> path \<location\>
+
+> Generate the configuration mode commands to add a public key for
+> {ref}`ssh_key_based_authentication`.
+> ``<location>`` can be a local path or a URL pointing at a remote file.
+>
+> Supported remote protocols are FTP, FTPS, HTTP, HTTPS, SCP/SFTP and TFTP.
+
+Example:
+
+:::{code-block} none
+alyssa@vyos:~$ generate public-key-command user alyssa path sftp://example.net/home/alyssa/.ssh/id_rsa.pub
+# To add this key as an embedded key, run the following commands:
+configure
+set system login user alyssa authentication public-keys alyssa@example.net key AAA...
+set system login user alyssa authentication public-keys alyssa@example.net type ssh-rsa
+commit
+save
+exit
+
+ben@vyos:~$ generate public-key-command user ben path ~/.ssh/id_rsa.pub
+# To add this key as an embedded key, run the following commands:
+configure
+set system login user ben authentication public-keys ben@vyos key AAA...
+set system login user ben authentication public-keys ben@vyos type ssh-dss
+commit
+save
+exit
+:::
+```
+```{opcmd} show log ssh
+
+Show SSH server log.
+```
+```{opcmd} monitor log ssh
+
+Follow the SSH server log.
+```
+```{opcmd} show log ssh dynamic-protection
+
+Show SSH dynamic-protection log.
+```
+```{opcmd} monitor log ssh dynamic-protection
+
+Follow the SSH dynamic-protection log.
+```
+```{opcmd} show ssh dynamic-protection
+
+Show list of IPs currently blocked by SSH dynamic-protection.
+```
+```{opcmd} show ssh fingerprints
+
+Show SSH server public key fingerprints.
+```
+```{opcmd} show ssh fingerprints ascii
+
+Show SSH server public key fingerprints, including a visual ASCII art representation.
+``` \ No newline at end of file
diff --git a/docs/configuration/service/suricata.md b/docs/configuration/service/suricata.md
new file mode 100644
index 00000000..ca9ae968
--- /dev/null
+++ b/docs/configuration/service/suricata.md
@@ -0,0 +1,93 @@
+(suricata)=
+
+# suricata
+
+Suricata and VyOS are powerful tools for ensuring network security and traffic management.
+Suricata is an open-source intrusion detection and prevention system (IDS/IPS) that analyzes network packets in real-time.
+
+## Suricata Features
+
+Intrusion Detection (IDS): Analyzes network traffic and detects suspicious activities, attacks, and malicious traffic.
+Intrusion Prevention (IPS): Blocks or modifies suspicious traffic in real-time, preventing attacks before they penetrate the network.
+Network Security Monitoring (NSM): Collects and analyzes network data to detect anomalies and identify threats.
+Multi-Protocol Support: Suricata supports analysis of various network protocols such as HTTP, FTP, SMB, and many others.
+In configuration mode, the commands are as follows:
+
+```none
+vyos@vyos# set service suricata
+Possible completions:
++> address-group Address group name
++ interface Interface to use
+ > log Suricata log outputs
++> port-group Port group name
+```
+
+These commands create a flexible interface for configuring the Suricata service, allowing users to specify addresses, ports,
+and logging parameters.
+
+After completing the service configuration in configuration mode, the main configuration file suricata.yaml is created,
+into which all specified parameters are added. Then, to ensure proper operation, the command {opcmd}`update suricata` must be run
+from operational mode, waiting for Suricata to update all its rules, which are used for analyzing traffic for threats and attacks.
+
+## Configuration
+
+```{cfgcmd} set service suricata address-group \<text\> \<address | group\>
+
+ Address groups are useful when you need to create rules that apply to specific IP addresses.
+ For example, if you want to create a rule that monitors traffic going to or from a specific IP address,
+ you can use the group name instead of the actual IP address. This simplifies rule management and makes the
+ configuration more flexible.
+
+ * ``address`` IP address or subnet.
+
+ * ``group`` Address group.
+```
+
+
+```{cfgcmd} set service suricata port-group \<text\> \<address | group\>
+
+Port groups are useful when you need to create rules that apply to specific ports.
+For example, if you want to create a rule that monitors traffic directed to a specific port or group of ports,
+you can use the group name instead of the actual port. This also simplifies rule management and makes
+the configuration more flexible.
+
+* ``port`` Port number.
+
+* ``group`` Port group.
+```
+
+
+```{cfgcmd} set service suricata interface \<text\>
+
+The interface that will be monitored by the Suricata service.
+```
+```{cfgcmd} set service suricata log eve \<filename | filetype | type\>
+
+ Configuration of the logging file.
+
+ * ``filename`` Log file (default: eve.json).
+
+ * ``filetype`` EVE logging destination (default: regular).
+
+ * ``type`` Log types.
+```
+
+## Operation Mode
+
+```{cfgcmd} update suricata
+
+Checks for the existence of the Suricata configuration file, updates the service,
+and then restarts it. If the configuration file is not found, a message indicates that Suricata is not configured.
+```
+```{cfgcmd} restart suricata
+
+Restarts the service. It checks if the Suricata service is active before attempting to restart it.
+If it is not active, a message indicates that the service is not configured. This command is used when adding new rules manually.
+```
+
+## Conclusion
+
+Using address and port groups allows you to make your Suricata configuration more flexible and manageable.
+Instead of specifying IP addresses and ports directly in each rule, you can define them once in the vars section and then
+reference them by group names. This is especially useful in large networks and complex configurations where multiple IP addresses
+and ports need to be monitored.
diff --git a/docs/configuration/service/tftp-server.md b/docs/configuration/service/tftp-server.md
new file mode 100644
index 00000000..f4a6c34c
--- /dev/null
+++ b/docs/configuration/service/tftp-server.md
@@ -0,0 +1,78 @@
+(tftp-server)=
+
+# TFTP Server
+
+{abbr}`TFTP (Trivial File Transfer Protocol)` is a simple, lockstep file
+transfer protocol which allows a client to get a file from or put a file onto
+a remote host. One of its primary uses is in the early stages of nodes booting
+from a local area network. TFTP has been used for this application because it
+is very simple to implement.
+
+## Configuration
+
+```{cfgcmd} set service tftp-server directory \<directory\>
+
+Enable TFTP service by specifying the `<directory>` which will be used to serve
+files.
+```
+
+:::{hint}
+Choose your `directory` location carefully or you will loose the
+content on image upgrades. Any directory under `/config` is save at this
+will be migrated.
+:::
+
+```{cfgcmd} set service tftp-server listen-address \<address\>
+
+Configure the IPv4 or IPv6 listen address of the TFTP server. Multiple IPv4 and
+IPv6 addresses can be given. There will be one TFTP server instances listening
+on each IP address.
+```
+
+```{cfgcmd} set service tftp-server listen-address \<address\> vrf \<name\>
+```
+
+Additional option to run TFTP server in the {abbr}`VRF (Virtual Routing and Forwarding)` context
+
+:::{note}
+Configuring a listen-address is essential for the service to work.
+:::
+```{cfgcmd} set service tftp-server allow-upload
+
+Optional, if you want to enable uploads, else TFTP server will act as a
+read-only server.
+```
+
+### Example
+
+Provide TFTP server listening on both IPv4 and IPv6 addresses `192.0.2.1` and
+`2001:db8::1` serving the content from `/config/tftpboot`. Uploading via
+TFTP to this server is disabled.
+
+The resulting configuration will look like:
+
+```none
+vyos@vyos# show service
+ tftp-server {
+ directory /config/tftpboot
+ listen-address 2001:db8::1
+ listen-address 192.0.2.1
+ }
+```
+
+### Verification
+
+Client:
+
+```none
+vyos@RTR2:~$ tftp -p -l /config/config.boot -r backup 192.0.2.1
+backup1 100% |******************************| 723 0:00:00 ETA
+```
+
+Server:
+
+```none
+vyos@RTR1# ls -ltr /config/tftpboot/
+total 1
+-rw-rw-rw- 1 tftp tftp 1995 May 19 16:02 backup
+```
diff --git a/docs/configuration/service/webproxy.md b/docs/configuration/service/webproxy.md
new file mode 100644
index 00000000..28156b2b
--- /dev/null
+++ b/docs/configuration/service/webproxy.md
@@ -0,0 +1,459 @@
+(webproxy)=
+
+# Webproxy
+
+The proxy service in VyOS is based on [Squid] and some related modules.
+
+[Squid] is a caching and forwarding HTTP web proxy. It has a wide variety of
+uses, including speeding up a web server by caching repeated requests, caching
+web, DNS and other computer network lookups for a group of people sharing
+network resources, and aiding security by filtering traffic. Although primarily
+used for HTTP and FTP, Squid includes limited support for several other
+protocols including Internet Gopher, SSL,[6] TLS and HTTPS. Squid does not
+support the SOCKS protocol.
+
+URL Filtering is provided by [SquidGuard].
+
+## Configuration
+
+```{cfgcmd} set service webproxy append-domain \<domain\>
+
+Use this command to specify a domain name to be appended to domain-names
+within URLs that do not include a dot ``.`` the domain is appended.
+
+Example: to be appended is set to ``vyos.net`` and the URL received is
+``www/foo.html``, the system will use the generated, final URL of
+``www.vyos.net/foo.html``.
+
+:::{code-block} none
+set service webproxy append-domain vyos.net
+:::
+```
+
+
+```{cfgcmd} set service webproxy cache-size \<size\>
+
+The size of the on-disk Proxy cache is user configurable. The Proxies default
+cache-size is configured to 100 MB.
+
+Unit of this command is MB.
+
+:::{code-block} none
+set service webproxy cache-size 1024
+:::
+```
+
+
+```{cfgcmd} set service webproxy default-port \<port\>
+
+Specify the port used on which the proxy service is listening for requests.
+This port is the default port used for the specified listen-address.
+
+Default port is 3128.
+
+:::{code-block} none
+set service webproxy default-port 8080
+:::
+```
+
+
+```{cfgcmd} set service webproxy domain-block \<domain\>
+
+Used to block specific domains by the Proxy. Specifying "vyos.net" will block
+all access to vyos.net, and specifying ".xxx" will block all access to URLs
+having an URL ending on .xxx.
+
+:::{code-block} none
+set service webproxy domain-block vyos.net
+:::
+```
+
+
+```{cfgcmd} set service webproxy domain-noncache \<domain\>
+
+Allow access to sites in a domain without retrieving them from the Proxy
+cache. Specifying "vyos.net" will allow access to vyos.net but the pages
+accessed will not be cached. It useful for working around problems with
+"If-Modified-Since" checking at certain sites.
+
+:::{code-block} none
+set service webproxy domain-noncache vyos.net
+:::
+```
+
+
+```{cfgcmd} set service webproxy listen-address \<address\>
+
+Specifies proxy service listening address. The listen address is the IP
+address on which the web proxy service listens for client requests.
+
+For security, the listen address should only be used on internal/trusted
+networks!
+
+:::{code-block} none
+set service webproxy listen-address 192.0.2.1
+:::
+```
+
+
+```{cfgcmd} set service webproxy listen-address \<address\> disable-transparent
+
+Disables web proxy transparent mode at a listening address.
+
+In transparent proxy mode, all traffic arriving on port 80 and destined for
+the Internet is automatically forwarded through the proxy. This allows
+immediate proxy forwarding without configuring client browsers.
+
+Non-transparent proxying requires that the client browsers be configured with
+the proxy settings before requests are redirected. The advantage of this is
+that the client web browser can detect that a proxy is in use and can behave
+accordingly. In addition, web-transmitted malware can sometimes be blocked by
+a non-transparent web proxy, since they are not aware of the proxy settings.
+
+:::{code-block} none
+set service webproxy listen-address 192.0.2.1 disable-transparent
+:::
+```
+
+
+```{cfgcmd} set service webproxy listen-address \<address\> port \<port\>
+
+Sets the listening port for a listening address. This overrides the default
+port of 3128 on the specific listen address.
+
+:::{code-block} none
+set service webproxy listen-address 192.0.2.1 port 8080
+:::
+```
+```{cfgcmd} set service webproxy reply-block-mime \<mime\>
+
+Used to block a specific mime-type.
+
+:::{code-block} none
+# block all PDFs
+set service webproxy reply-block-mime application/pdf
+:::
+```
+```{cfgcmd} set service webproxy reply-body-max-size \<size\>
+
+Specifies the maximum size of a reply body in KB, used to limit the reply
+size.
+
+All reply sizes are accepted by default.
+
+:::{code-block} none
+set service webproxy reply-body-max-size 2048
+:::
+```
+
+
+```{cfgcmd} set service webproxy safe-ports \<port\>
+
+Add new port to Safe-ports acl. Ports included by default in Safe-ports acl:
+21, 70, 80, 210, 280, 443, 488, 591, 777, 873, 1025-65535
+```
+
+
+```{cfgcmd} set service webproxy ssl-safe-ports \<port\>
+
+Add new port to SSL-ports acl. Ports included by default in SSL-ports acl:
+443
+```
+
+### Authentication
+
+The embedded Squid proxy can use LDAP to authenticate users against a company
+wide directory. The following configuration is an example of how to use Active
+Directory as authentication backend. Queries are done via LDAP.
+
+```{cfgcmd} set service webproxy authentication children \<number\>
+
+Maximum number of authenticator processes to spawn. If you start too few
+Squid will have to wait for them to process a backlog of credential
+verifications, slowing it down. When password verifications are done via a
+(slow) network you are likely to need lots of authenticator processes.
+
+This defaults to 5.
+
+:::{code-block} none
+set service webproxy authentication children 10
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication credentials-ttl \<time\>
+
+Specifies how long squid assumes an externally validated username:password
+pair is valid for - in other words how often the helper program is called for
+that user. Set this low to force revalidation with short lived passwords.
+
+Time is in minutes and defaults to 60.
+
+:::{code-block} none
+set service webproxy authentication credentials-ttl 120
+:::
+```
+```{cfgcmd} set service webproxy authentication method \<ldap\>
+
+Proxy authentication method, currently only LDAP is supported.
+
+:::{code-block} none
+set service webproxy authentication method ldap
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication realm
+
+Specifies the protection scope (aka realm name) which is to be reported to
+the client for the authentication scheme. It is commonly part of the text
+the user will see when prompted for their username and password.
+
+:::{code-block} none
+set service webproxy authentication realm "VyOS proxy auth"
+:::
+```
+
+#### LDAP
+
+```{cfgcmd} set service webproxy authentication ldap base-dn \<base-dn\>
+
+Specifies the base DN under which the users are located.
+
+:::{code-block} none
+set service webproxy authentication ldap base-dn DC=vyos,DC=net
+:::
+```
+```{cfgcmd} set service webproxy authentication ldap bind-dn \<bind-dn\>
+
+The DN and password to bind as while performing searches.
+
+:::{code-block} none
+set service webproxy authentication ldap bind-dn CN=proxyuser,CN=Users,DC=vyos,DC=net
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap filter-expression \<expr\>
+
+LDAP search filter to locate the user DN. Required if the users are in a
+hierarchy below the base DN, or if the login name is not what builds the user
+specific part of the users DN.
+
+The search filter can contain up to 15 occurrences of %s which will be
+replaced by the username, as in "uid=%s" for {rfc}`2037` directories. For a
+detailed description of LDAP search filter syntax see {rfc}`2254`.
+
+:::{code-block} none
+set service webproxy authentication ldap filter-expression (cn=%s)
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap password \<password\>
+
+The DN and password to bind as while performing searches. As the password
+needs to be printed in plain text in your Squid configuration it is strongly
+recommended to use a account with minimal associated privileges. This to limit
+the damage in case someone could get hold of a copy of your Squid
+configuration file.
+
+:::{code-block} none
+set service webproxy authentication ldap password vyos
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap persistent-connection
+
+Use a persistent LDAP connection. Normally the LDAP connection is only open
+while validating a username to preserve resources at the LDAP server. This
+option causes the LDAP connection to be kept open, allowing it to be reused
+for further user validations.
+
+Recommended for larger installations.
+
+:::{code-block} none
+set service webproxy authentication ldap persistent-connection
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap port \<port\>
+
+Specify an alternate TCP port where the ldap server is listening if other than
+the default LDAP port 389.
+
+:::{code-block} none
+set service webproxy authentication ldap port 389
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap server \<server\>
+
+Specify the LDAP server to connect to.
+
+:::{code-block} none
+set service webproxy authentication ldap server ldap.vyos.net
+:::
+```
+```{cfgcmd} set service webproxy authentication ldap use-ssl
+
+Use TLS encryption.
+
+:::{code-block} none
+set service webproxy authentication ldap use-ssl
+:::
+```
+```{cfgcmd} set service webproxy authentication ldap username-attribute \<attr\>
+
+Specifies the name of the DN attribute that contains the username/login.
+Combined with the base DN to construct the users DN when no search filter is
+specified (filter-expression).
+
+Defaults to 'uid'
+
+:::{note}
+This can only be done if all your users are located directly under
+the same position in the LDAP tree and the login name is used for naming
+each user object. If your LDAP tree does not match these criterias or if you
+want to filter who are valid users then you need to use a search filter to
+search for your users DN (filter-expression).
+:::
+
+:::{code-block} none
+set service webproxy authentication ldap username-attribute uid
+:::
+```
+
+
+```{cfgcmd} set service webproxy authentication ldap version \<2 | 3\>
+
+LDAP protocol version. Defaults to 3 if not specified.
+
+:::{code-block} none
+set service webproxy authentication ldap version 2
+:::
+```
+
+### URL filtering
+
+```{include} /_include/need_improvement.txt
+```
+```{cfgcmd} set service webproxy url-filtering disable
+
+Disables web filtering without discarding configuration.
+
+:::{code-block} none
+set service webproxy url-filtering disable
+:::
+```
+
+## Operation
+
+```{include} /_include/need_improvement.txt
+```
+
+### Filtering
+#### Update
+
+If you want to use existing blacklists you have to create/download a database
+first. Otherwise you will not be able to commit the config changes.
+
+```{opcmd} update webproxy blacklists
+
+Download/Update complete blacklist
+
+:::{code-block} none
+vyos@vyos:~$ update webproxy blacklists
+Warning: No url-filtering blacklist installed
+Would you like to download a default blacklist? [confirm][y]
+Connecting to ftp.univ-tlse1.fr (193.49.48.249:21)
+blacklists.gz 100% |*************************************************************************************************************| 17.0M 0:00:00 ETA
+Uncompressing blacklist...
+Checking permissions...
+Skip link for [ads] -> [publicite]
+Building DB for [adult/domains] - 2467177 entries
+Building DB for [adult/urls] - 67798 entries
+Skip link for [aggressive] -> [agressif]
+Building DB for [agressif/domains] - 348 entries
+Building DB for [agressif/urls] - 36 entries
+Building DB for [arjel/domains] - 69 entries
+...
+Building DB for [webmail/domains] - 374 entries
+Building DB for [webmail/urls] - 9 entries
+The webproxy daemon must be restarted
+Would you like to restart it now? [confirm][y]
+[ ok ] Restarting squid (via systemctl): squid.service.
+vyos@vyos:~$
+:::
+```
+```{opcmd} update webproxy blacklists category \<category\>
+
+Download/Update partial blacklist.
+
+Use tab completion to get a list of categories.
+```
+
+- To auto update the blacklist files
+
+ `set service webproxy url-filtering squidguard auto-update update-hour 23`
+
+- To configure blocking add the following to the configuration
+
+ `set service webproxy url-filtering squidguard block-category ads`
+
+ `set service webproxy url-filtering squidguard block-category malware`
+
+#### Bypassing the webproxy
+
+```{include} /_include/need_improvement.txt
+```
+
+Some services don't work correctly when being handled via a web proxy.
+So sometimes it is useful to bypass a transparent proxy:
+
+- To bypass the proxy for every request that is directed to a specific
+ destination:
+
+ `set service webproxy whitelist destination-address 198.51.100.33`
+
+ `set service webproxy whitelist destination-address 192.0.2.0/24`
+
+- To bypass the proxy for every request that is coming from a specific source:
+
+ `set service webproxy whitelist source-address 192.168.1.2`
+
+ `set service webproxy whitelist source-address 192.168.2.0/24`
+
+ (This can be useful when a called service has many and/or often changing
+ destination addresses - e.g. Netflix.)
+
+## Examples
+
+```none
+vyos@vyos# show service webproxy
+ authentication {
+ children 5
+ credentials-ttl 60
+ ldap {
+ base-dn DC=example,DC=local
+ bind-dn CN=proxyuser,CN=Users,DC=example,DC=local
+ filter-expression (cn=%s)
+ password Qwert1234
+ server ldap.example.local
+ username-attribute cn
+ }
+ method ldap
+ realm "VyOS Webproxy"
+ }
+ cache-size 100
+ default-port 3128
+ listen-address 192.168.188.103 {
+ disable-transparent
+ }
+```
+
+[squid]: http://www.squid-cache.org/
+[squidguard]: http://www.squidguard.org/
diff --git a/docs/configuration/system/acceleration.md b/docs/configuration/system/acceleration.md
new file mode 100644
index 00000000..871129e6
--- /dev/null
+++ b/docs/configuration/system/acceleration.md
@@ -0,0 +1,158 @@
+(acceleration)=
+
+# Acceleration
+
+In this command tree, all hardware acceleration options will be handled.
+At the moment only [Intel® QAT] is supported
+
+## Intel® QAT
+
+```{opcmd} show system acceleration qat
+
+use this command to check if there is an Intel® QAT supported Processor in your system.
+
+:::{code-block} none
+vyos@vyos:~$ show system acceleration qat
+01:00.0 Co-processor [0b40]: Intel Corporation Atom Processor C3000 Series QuickAssist Technology [8086:19e2] (rev 11)
+:::
+
+if there is non device the command will show `` `No QAT device found` ``
+```
+
+```{cfgcmd} set system acceleration qat
+
+if there is a supported device, enable Intel® QAT
+```
+
+
+```{opcmd} show system acceleration qat status
+
+Check if the Intel® QAT device is up and ready to do the job.
+
+:::{code-block} none
+vyos@vyos:~$ show system acceleration qat status
+Checking status of all devices.
+There is 1 QAT acceleration device(s) in the system:
+qat_dev0 - type: c3xxx, inst_id: 0, node_id: 0, bsf: 0000:01:00.0, #accel: 3 #engines: 6 state: up
+:::
+```
+
+
+### Operation Mode
+
+```{opcmd} show system acceleration qat device \<device\> config
+
+Show the full config uploaded to the QAT device.
+```
+
+
+```{opcmd} show system acceleration qat device \<device\> flows
+
+Get an overview over the encryption counters.
+```
+
+
+```{opcmd} show system acceleration qat interrupts
+
+Show binded qat device interrupts to certain core.
+```
+
+
+### Example
+
+Let's build a simple VPN between 2 Intel® QAT ready devices.
+
+Side A:
+
+```
+set interfaces vti vti1 address '192.168.1.2/24'
+set vpn ipsec authentication psk right id '10.10.10.2'
+set vpn ipsec authentication psk right id '10.10.10.1'
+set vpn ipsec authentication psk right secret 'Qwerty123'
+set vpn ipsec esp-group MyESPGroup proposal 1 encryption 'aes256'
+set vpn ipsec esp-group MyESPGroup proposal 1 hash 'sha256'
+set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group '14'
+set vpn ipsec ike-group MyIKEGroup proposal 1 encryption 'aes256'
+set vpn ipsec ike-group MyIKEGroup proposal 1 hash 'sha256'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer right authentication local-id '10.10.10.2'
+set vpn ipsec site-to-site peer right authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer right authentication remote-id '10.10.10.1'
+set vpn ipsec site-to-site peer right connection-type 'initiate'
+set vpn ipsec site-to-site peer right default-esp-group 'MyESPGroup'
+set vpn ipsec site-to-site peer right ike-group 'MyIKEGroup'
+set vpn ipsec site-to-site peer right local-address '10.10.10.2'
+set vpn ipsec site-to-site peer right remote-address '10.10.10.1'
+set vpn ipsec site-to-site peer right vti bind 'vti1'
+```
+
+Side B:
+
+```
+set interfaces vti vti1 address '192.168.1.1/24'
+set vpn ipsec authentication psk left id '10.10.10.2'
+set vpn ipsec authentication psk left id '10.10.10.1'
+set vpn ipsec authentication psk left secret 'Qwerty123'
+set vpn ipsec esp-group MyESPGroup proposal 1 encryption 'aes256'
+set vpn ipsec esp-group MyESPGroup proposal 1 hash 'sha256'
+set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group '14'
+set vpn ipsec ike-group MyIKEGroup proposal 1 encryption 'aes256'
+set vpn ipsec ike-group MyIKEGroup proposal 1 hash 'sha256'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer left authentication local-id '10.10.10.1'
+set vpn ipsec site-to-site peer left authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer left authentication remote-id '10.10.10.2'
+set vpn ipsec site-to-site peer left connection-type 'initiate'
+set vpn ipsec site-to-site peer left default-esp-group 'MyESPGroup'
+set vpn ipsec site-to-site peer left ike-group 'MyIKEGroup'
+set vpn ipsec site-to-site peer left local-address '10.10.10.1'
+set vpn ipsec site-to-site peer left remote-address '10.10.10.2'
+set vpn ipsec site-to-site peer left vti bind 'vti1'
+```
+
+a bandwidth test over the VPN got these results:
+
+```
+Connecting to host 192.168.1.2, port 5201
+[ 9] local 192.168.1.1 port 51344 connected to 192.168.1.2 port 5201
+[ ID] Interval Transfer Bitrate Retr Cwnd
+[ 9] 0.00-1.01 sec 32.3 MBytes 268 Mbits/sec 0 196 KBytes
+[ 9] 1.01-2.03 sec 32.5 MBytes 268 Mbits/sec 0 208 KBytes
+[ 9] 2.03-3.03 sec 32.5 MBytes 271 Mbits/sec 0 208 KBytes
+[ 9] 3.03-4.04 sec 32.5 MBytes 272 Mbits/sec 0 208 KBytes
+[ 9] 4.04-5.00 sec 31.2 MBytes 272 Mbits/sec 0 208 KBytes
+[ 9] 5.00-6.01 sec 32.5 MBytes 272 Mbits/sec 0 234 KBytes
+[ 9] 6.01-7.04 sec 32.5 MBytes 265 Mbits/sec 0 234 KBytes
+[ 9] 7.04-8.04 sec 32.5 MBytes 272 Mbits/sec 0 234 KBytes
+[ 9] 8.04-9.04 sec 32.5 MBytes 273 Mbits/sec 0 336 KBytes
+[ 9] 9.04-10.00 sec 31.2 MBytes 272 Mbits/sec 0 336 KBytes
+- - - - - - - - - - - - - - - - - - - - - - - - -
+[ ID] Interval Transfer Bitrate Retr
+[ 9] 0.00-10.00 sec 322 MBytes 270 Mbits/sec 0 sender
+[ 9] 0.00-10.00 sec 322 MBytes 270 Mbits/sec receiver
+```
+
+with {cfgcmd}`set system acceleration qat` on both systems the bandwidth
+increases.
+
+```
+Connecting to host 192.168.1.2, port 5201
+[ 9] local 192.168.1.1 port 51340 connected to 192.168.1.2 port 5201
+[ ID] Interval Transfer Bitrate Retr Cwnd
+[ 9] 0.00-1.00 sec 97.3 MBytes 817 Mbits/sec 0 1000 KBytes
+[ 9] 1.00-2.00 sec 92.5 MBytes 776 Mbits/sec 0 1.07 MBytes
+[ 9] 2.00-3.00 sec 92.5 MBytes 776 Mbits/sec 0 820 KBytes
+[ 9] 3.00-4.00 sec 92.5 MBytes 776 Mbits/sec 0 899 KBytes
+[ 9] 4.00-5.00 sec 91.2 MBytes 765 Mbits/sec 0 972 KBytes
+[ 9] 5.00-6.00 sec 92.5 MBytes 776 Mbits/sec 0 1.02 MBytes
+[ 9] 6.00-7.00 sec 92.5 MBytes 776 Mbits/sec 0 1.08 MBytes
+[ 9] 7.00-8.00 sec 92.5 MBytes 776 Mbits/sec 0 1.14 MBytes
+[ 9] 8.00-9.00 sec 91.2 MBytes 765 Mbits/sec 0 915 KBytes
+[ 9] 9.00-10.00 sec 92.5 MBytes 776 Mbits/sec 0 1000 KBytes
+- - - - - - - - - - - - - - - - - - - - - - - - -
+[ ID] Interval Transfer Bitrate Retr
+[ 9] 0.00-10.00 sec 927 MBytes 778 Mbits/sec 0 sender
+[ 9] 0.00-10.01 sec 925 MBytes 775 Mbits/sec receiver
+```
+
+[intel® qat]: https://www.intel.com/content/www/us/en/architecture-and-technology/intel-quick-assist-technology-overview.html
diff --git a/docs/configuration/system/conntrack.md b/docs/configuration/system/conntrack.md
new file mode 100644
index 00000000..f83f0684
--- /dev/null
+++ b/docs/configuration/system/conntrack.md
@@ -0,0 +1,218 @@
+# Conntrack
+
+VyOS can be configured to track connections using the connection
+tracking subsystem. Connection tracking becomes operational once either
+stateful firewall or NAT is configured.
+
+## Configure
+
+```{cfgcmd} set system conntrack table-size \<1-50000000\>
+:defaultvalue:
+
+The connection tracking table contains one entry for each connection being
+tracked by the system.
+```
+
+```{cfgcmd} set system conntrack expect-table-size \<1-50000000\>
+:defaultvalue:
+
+The connection tracking expect table contains one entry for each expected
+connection related to an existing connection. These are generally used by
+“connection tracking helper” modules such as FTP.
+The default size of the expect table is 2048 entries.
+```
+
+```{cfgcmd} set system conntrack hash-size \<1-50000000\>
+:defaultvalue:
+
+Set the size of the hash table. The connection tracking hash table makes
+searching the connection tracking table faster. The hash table uses
+“buckets” to record entries in the connection tracking table.
+```
+
+```{eval-rst}
+.. cfgcmd:: set system conntrack modules ftp
+.. cfgcmd:: set system conntrack modules h323
+.. cfgcmd:: set system conntrack modules nfs
+.. cfgcmd:: set system conntrack modules pptp
+.. cfgcmd:: set system conntrack modules sip
+.. cfgcmd:: set system conntrack modules sqlnet
+.. cfgcmd:: set system conntrack modules tftp
+
+ Configure the connection tracking protocol helper modules.
+ All modules are enable by default.
+
+ | Use `delete system conntrack modules` to deactive all modules.
+ | Or, for example ftp, `delete system conntrack modules ftp`.
+```
+
+```{cfgcmd} set system conntrack tcp half-open-connections \<1-21474836\>
+:defaultvalue:
+
+Set the maximum number of TCP half-open connections.
+```
+
+```{cfgcmd} set system conntrack tcp loose \<enable | disable\>
+:defaultvalue:
+
+Policy to track previously established connections.
+```
+
+```{cfgcmd} set system conntrack tcp max-retrans \<1-2147483647\>
+:defaultvalue:
+
+Set the number of TCP maximum retransmit attempts.
+```
+
+### Contrack Timeouts
+
+You can define custom timeout values to apply to a specific subset of
+connections, based on a packet and flow selector. To do this, you need to
+create a rule defining the packet and flow selector.
+
+```{eval-rst}
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ description <test>
+
+ Set a rule description.
+
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ destination address <ip-address>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ source address <ip-address>
+
+ Set a destination and/or source address. Accepted input for ipv4:
+
+ .. code-block:: none
+
+ set system conntrack timeout custom ipv4 rule <1-999999> [source | destination] address
+ Possible completions:
+ <x.x.x.x> IPv4 address to match
+ <x.x.x.x/x> IPv4 prefix to match
+ <x.x.x.x>-<x.x.x.x> IPv4 address range to match
+ !<x.x.x.x> Match everything except the specified address
+ !<x.x.x.x/x> Match everything except the specified prefix
+ !<x.x.x.x>-<x.x.x.x> Match everything except the specified range
+
+ set system conntrack timeout custom ipv6 rule <1-999999> [source | destination] address
+ Possible completions:
+ <h:h:h:h:h:h:h:h> IP address to match
+ <h:h:h:h:h:h:h:h/x> Subnet to match
+ <h:h:h:h:h:h:h:h>-<h:h:h:h:h:h:h:h>
+ IP range to match
+ !<h:h:h:h:h:h:h:h> Match everything except the specified address
+ !<h:h:h:h:h:h:h:h/x> Match everything except the specified prefix
+ !<h:h:h:h:h:h:h:h>-<h:h:h:h:h:h:h:h>
+ Match everything except the specified range
+
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ destination port <value>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ source port <value>
+
+ Set a destination and/or source port. Accepted input:
+
+ .. code-block:: none
+
+ <port name> Named port (any name in /etc/services, e.g., http)
+ <1-65535> Numbered port
+ <start>-<end> Numbered port range (e.g., 1001-1005)
+
+ Multiple destination ports can be specified as a comma-separated list.
+ The whole list can also be "negated" using '!'. For example:
+ `!22,telnet,http,123,1001-1005``
+
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp close <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp close-wait <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp established <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp fin-wait <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp last-ack <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp syn-recv <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp syn-sent <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol tcp time-wait <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol udp replied <1-21474836>
+.. cfgcmd:: set system conntrack timeout custom [ipv4 | ipv6] rule <1-999999>
+ protocol udp unreplied <1-21474836>
+
+ Set the timeout in seconds for a protocol or state in a custom rule.
+```
+
+### Conntrack ignore rules
+
+:::{note}
+**Important note about conntrack ignore rules:**
+Starting from vyos-1.5-rolling-202406120020, ignore rules can be defined in
+``set firewall [ipv4 | ipv6] prerouting raw ...``. It's expected that in
+the future the conntrack ignore rules will be removed.
+
+> Customized ignore rules, based on a packet and flow selector.
+:::
+
+```{eval-rst}
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ description <text>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ destination address <ip-address>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ destination port <port>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ inbound-interface <interface>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ protocol <protocol>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ source address <ip-address>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ source port <port>
+.. cfgcmd:: set system conntrack ignore [ipv4 | ipv6] rule <1-999999>
+ tcp flags [not] <text>
+
+ Allowed values fpr TCP flags: ``ack``, ``cwr``, ``ecn``, ``fin``, ``psh``,
+ ``rst``, ``syn`` and ``urg``. Multiple values are supported, and for
+ inverted selection use ``not``, as shown in the example.
+```
+
+### Conntrack log
+
+```{eval-rst}
+.. cfgcmd:: set system conntrack log event destroy
+.. cfgcmd:: set system conntrack log event new
+.. cfgcmd:: set system conntrack log event update
+
+ Log the connection tracking events per type.
+
+.. cfgcmd:: set system conntrack log event destroy icmp
+.. cfgcmd:: set system conntrack log event destroy other
+.. cfgcmd:: set system conntrack log event destroy tcp
+.. cfgcmd:: set system conntrack log event destroy udp
+.. cfgcmd:: set system conntrack log event new icmp
+.. cfgcmd:: set system conntrack log event new other
+.. cfgcmd:: set system conntrack log event new tcp
+.. cfgcmd:: set system conntrack log event new udp
+.. cfgcmd:: set system conntrack log event update icmp
+.. cfgcmd:: set system conntrack log event update other
+.. cfgcmd:: set system conntrack log event update tcp
+.. cfgcmd:: set system conntrack log event update udp
+
+ Log the connection tracking events per protocol.
+
+.. cfgcmd:: set system conntrack log timestamp
+
+ Turn on flow-based timestamp extension.
+
+.. cfgcmd:: set system conntrack log queue-size <100-999999>
+
+ Manage internal queue size, default size is 4096 events.
+
+.. cfgcmd:: set system conntrack log log-level <info | debug>
+
+ Manage log level
+``` \ No newline at end of file
diff --git a/docs/configuration/system/console.md b/docs/configuration/system/console.md
new file mode 100644
index 00000000..9017fa30
--- /dev/null
+++ b/docs/configuration/system/console.md
@@ -0,0 +1,59 @@
+(serial-console)=
+
+# Serial Console
+
+For the average user a serial console has no advantage over a console offered
+by a directly attached keyboard and screen. Serial consoles are much slower,
+taking up to a second to fill a 80 column by 24 line screen. Serial consoles
+generally only support non-proportional ASCII text, with limited support for
+languages other than English.
+
+There are some scenarios where serial consoles are useful. System administration
+of remote computers is usually done using {ref}`ssh`, but there are times when
+access to the console is the only way to diagnose and correct software failures.
+Major upgrades to the installed distribution may also require console access.
+
+```{cfgcmd} set system console device \<device\>
+
+Defines the specified device as a system console. Available console devices
+can be (see completion helper):
+* ``ttySN`` - Serial device name
+* ``ttyAMAN``- Serial device name for some arm64 systems
+* ``ttyUSBX`` - USB Serial device name
+* ``hvc0`` - Xen console
+```
+
+```{cfgcmd} set system console device \<device\> kernel
+
+When set, the selected serial console is used as the kernel boot console.
+When removed, the kernel boot console falls back to tty0.
+
+:::{note}
+Only one serial console can carry the ``kernel`` option.
+When VyOS is installed via serial console, this option is set automatically
+for the serial interface used during installation; usually ``ttyS0`` or
+``ttyAMA0``.
+:::
+```
+
+```{cfgcmd} set system console device \<device\> speed \<speed\>
+
+The speed (baudrate) of the console device. Supported values are:
+* ``1200`` - 1200 bps
+* ``2400`` - 2400 bps
+* ``4800`` - 4800 bps
+* ``9600`` - 9600 bps
+* ``19200`` - 19,200 bps
+* ``38400`` - 38,400 bps (default for Xen console)
+* ``57600`` - 57,600 bps
+* ``115200`` - 115,200 bps (default for serial console)
+
+:::{note}
+If you use USB to serial converters for connecting to your VyOS
+appliance please note that most of them use software emulation without flow
+control. This means you should start with a common baud rate (most likely
+9600 baud) as otherwise you probably can not connect to the device using
+high speed baud rates as your serial converter simply can not process this
+data rate.
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/system/default-route.md b/docs/configuration/system/default-route.md
new file mode 100644
index 00000000..9f2793d1
--- /dev/null
+++ b/docs/configuration/system/default-route.md
@@ -0,0 +1,40 @@
+(default-gateway)=
+
+# Default Gateway/Route
+
+In the past (VyOS 1.1) used a gateway-address configured under the system tree
+({cfgcmd}`set system gateway-address <address>`), this is no longer supported
+and existing configurations are migrated to the new CLI command.
+
+## Configuration
+
+```{cfgcmd} set protocols static route 0.0.0.0/0 next-hop \<address\>
+
+Specify static route into the routing table sending all non local traffic
+to the nexthop address \<address\>.
+```
+
+```{cfgcmd} delete protocols static route 0.0.0.0/0
+
+Delete default route from the system.
+```
+
+
+## Operation
+
+```{opcmd} show ip route 0.0.0.0
+
+Show routing table entry for the default route.
+
+:::{code-block} none
+vyos@vyos:~$ show ip route 0.0.0.0
+Routing entry for 0.0.0.0/0
+Known via "static", distance 10, metric 0, best
+Last update 09:46:30 ago
+* 172.18.201.254, via eth0.201
+:::
+```
+
+:::{seealso}
+Configuration of {ref}`routing-static`
+:::
diff --git a/docs/configuration/system/flow-accounting.md b/docs/configuration/system/flow-accounting.md
new file mode 100644
index 00000000..c97d5473
--- /dev/null
+++ b/docs/configuration/system/flow-accounting.md
@@ -0,0 +1,209 @@
+(flow-accounting)=
+
+# Flow Accounting
+
+VyOS supports flow-accounting for both IPv4 and IPv6 traffic. The system acts
+as a flow exporter, and you are free to use it with any compatible collector.
+
+Flows can be exported via protocol NetFlow (versions 5, 9 and
+10/IPFIX). Additionally, you may save flows to an in-memory table
+internally in a router.
+
+:::{warning}
+You need to disable the in-memory table in production environments!
+Using {abbr}`IMT (In-Memory Table)` may lead to heavy CPU overloading and
+unstable flow-accounting behavior.
+:::
+
+## NetFlow / IPFIX
+
+NetFlow is a feature that was introduced on Cisco routers around 1996 that
+provides the ability to collect IP network traffic as it enters or exits an
+interface. By analyzing the data provided by NetFlow, a network administrator
+can determine things such as the source and destination of traffic, class of
+service, and the causes of congestion. A typical flow monitoring setup (using
+NetFlow) consists of three main components:
+
+- **exporter**: aggregates packets into flows and exports flow records towards
+ one or more flow collectors
+- **collector**: responsible for reception, storage and pre-processing of flow
+ data received from a flow exporter
+- **application**: analyzes received flow data in the context of intrusion
+ detection or traffic profiling, for example
+
+For connectionless protocols as like ICMP and UDP, a flow is considered
+complete once no more packets for this flow appear after configurable timeout.
+
+NetFlow is usually enabled on a per-interface basis to limit load on the router
+components involved in NetFlow, or to limit the amount of NetFlow records
+exported.
+
+## Configuration
+
+:::{warning}
+Using NetFlow on routers with high traffic levels may lead to
+high CPU usage and may affect the router's performance. In such cases,
+consider using sFlow instead.
+:::
+
+In order for flow accounting information to be collected and displayed for an
+interface, the interface must be configured for flow accounting.
+
+```{cfgcmd} set system flow-accounting interface \<interface\>
+
+Configure and enable collection of flow information for the interface
+identified by \<interface\>.
+
+You can configure multiple interfaces which would participate in flow
+accounting.
+```
+
+:::{note}
+Will be recorded only packets/flows on **incoming** direction in
+configured interfaces by default.
+:::
+
+By default, recorded flows will be saved internally and can be listed with the
+CLI command. You may disable using the local in-memory table with the command:
+
+```{cfgcmd} set system flow-accounting disable-imt
+
+If you need to sample also egress traffic, you may want to
+configure egress flow-accounting:
+```
+
+```{cfgcmd} set system flow-accounting enable-egress
+
+Internally, in flow-accounting processes exist a buffer for data exchanging
+between core process and plugins (each export target is a separated plugin).
+If you have high traffic levels or noted some problems with missed records
+or stopping exporting, you may try to increase a default buffer size (10
+MiB) with the next command:
+```
+
+```{cfgcmd} set system flow-accounting buffer-size \<buffer size\>
+
+In case, if you need to catch some logs from flow-accounting daemon, you may
+configure logging facility:
+```
+
+```{cfgcmd} set system flow-accounting syslog-facility \<facility\>
+
+Set the syslog facility for flow-accounting log messages. Supported values
+include ``daemon``, ``local0`` through ``local7``, and other standard syslog
+facilities.
+```
+
+
+### Flow Export
+
+In addition to displaying flow accounting information locally, one can also
+exported them to a collection server.
+
+#### NetFlow
+
+```{cfgcmd} set system flow-accounting netflow version \<version\>
+
+There are multiple versions available for the NetFlow data. The \<version\>
+used in the exported flow data can be configured here. The following
+versions are supported:
+* **5** - Most common version, but restricted to IPv4 flows only
+* **9** - NetFlow version 9 (default)
+* **10** - {abbr}`IPFIX (IP Flow Information Export)` as per {rfc}`3917`
+```
+
+```{cfgcmd} set system flow-accounting netflow server \<address\>
+
+Configure address of NetFlow collector. NetFlow server at \<address\> can
+be both listening on an IPv4 or IPv6 address.
+```
+
+```{cfgcmd} set system flow-accounting netflow source-ip \<address\>
+
+IPv4 or IPv6 source address of NetFlow packets
+```
+
+```{cfgcmd} set system flow-accounting netflow engine-id \<id\>
+
+NetFlow engine-id which will appear in NetFlow data. The range is 0 to 255.
+```
+
+```{cfgcmd} set system flow-accounting netflow sampling-rate \<rate\>
+
+Use this command to configure the sampling rate for flow accounting. The
+system samples one in every \<rate\> packets, where \<rate\> is the value
+configured for the sampling-rate option. The advantage of sampling every n
+packets, where n > 1, allows you to decrease the amount of processing
+resources required for flow accounting. The disadvantage of not sampling
+every packet is that the statistics produced are estimates of actual data
+flows.
+
+Per default every packet is sampled (that is, the sampling rate is 1).
+```
+
+```{cfgcmd} set system flow-accounting netflow timeout expiry-interval \<interval\>
+
+Specifies the interval at which Netflow data will be sent to a collector. As
+per default, Netflow data will be sent every 60 seconds.
+
+You may also additionally configure timeouts for different types of
+connections.
+```
+
+```{cfgcmd} set system flow-accounting netflow max-flows \<n\>
+
+If you want to change the maximum number of flows, which are tracking
+simultaneously, you may do this with this command (default 8192).
+```
+
+
+### Example:
+
+NetFlow v5 example:
+
+```none
+set system flow-accounting netflow engine-id 100
+set system flow-accounting netflow version 5
+set system flow-accounting netflow server 192.168.2.10 port 2055
+```
+
+
+## Operation
+
+Once flow accounting is configured on an interfaces it provides the ability to
+display captured network traffic information for all configured interfaces.
+
+```{opcmd} show flow-accounting interface \<interface\>
+
+Show flow accounting information for given \<interface\>.
+
+
+:::{code-block} none
+vyos@vyos:~$ show flow-accounting interface eth0
+IN_IFACE SRC_MAC DST_MAC SRC_IP DST_IP SRC_PORT DST_PORT PROTOCOL TOS PACKETS FLOWS BYTES
+---------- ----------------- ----------------- ------------------------ --------------- ---------- ---------- ---------- ----- --------- ------- -------
+eth0 00:53:01:a8:28:ac ff:ff:ff:ff:ff:ff 192.0.2.2 255.255.255.255 5678 5678 udp 0 1 1 178
+eth0 00:53:01:b2:2f:34 33:33:ff:00:00:00 fe80::253:01ff:feb2:2f34 ff02::1:ff00:0 0 0 ipv6-icmp 0 2 1 144
+eth0 00:53:01:1a:b4:53 33:33:ff:00:00:00 fe80::253:01ff:fe1a:b453 ff02::1:ff00:0 0 0 ipv6-icmp 0 1 1 72
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 40152 22 tcp 16 39 1 2064
+eth0 00:53:01:c8:33:af ff:ff:ff:ff:ff:ff 192.0.2.3 255.255.255.255 5678 5678 udp 0 1 1 154
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 40006 22 tcp 16 146 1 9444
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 0 0 icmp 192 27 1 4455
+:::
+```
+
+```{opcmd} show flow-accounting interface \<interface\> host \<address\>
+
+Show flow accounting information for given \<interface\> for a specific host
+only.
+
+
+:::{code-block} none
+vyos@vyos:~$ show flow-accounting interface eth0 host 192.0.2.14
+IN_IFACE SRC_MAC DST_MAC SRC_IP DST_IP SRC_PORT DST_PORT PROTOCOL TOS PACKETS FLOWS BYTES
+---------- ----------------- ----------------- ----------- ---------- ---------- ---------- ---------- ----- --------- ------- -------
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 40006 22 tcp 16 197 2 12940
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 40152 22 tcp 16 94 1 4924
+eth0 00:53:01:b2:22:48 00:53:02:58:a2:92 192.0.2.100 192.0.2.14 0 0 icmp 192 36 1 5877
+:::
+``` \ No newline at end of file
diff --git a/docs/configuration/system/frr.md b/docs/configuration/system/frr.md
new file mode 100644
index 00000000..1741e286
--- /dev/null
+++ b/docs/configuration/system/frr.md
@@ -0,0 +1,45 @@
+(system-frr)=
+
+# FRR
+
+VyOS uses [FRRouting](https://frrouting.org/) as the control plane for dynamic
+and static routing. The routing daemon behavior can be adjusted during runtime,
+but requires either a restart of the routing daemon, or a reboot of the system.
+
+```{cfgcmd} set system frr bmp
+
+Enable {abbr}`BMP (BGP Monitoring Protocol)` support.
+```
+
+```{cfgcmd} set system frr descriptors \<numer\>
+
+This allows the operator to control the number of open file descriptors
+each daemon is allowed to start with. If the operator plans to run bgp with
+several thousands of peers then this is where we would modify FRR to allow
+this to happen.
+```
+
+```{cfgcmd} set system frr irdp
+
+Enable ICMP Router Discovery Protocol support.
+```
+
+```{cfgcmd} set system frr profile \<traditional | datacenter\>
+
+Select an FRR profile to adapt its default settings. If unset, the
+traditional profile is applied.
+```
+
+```{cfgcmd} set system frr snmp \<daemon\>
+
+Enable SNMP support for an individual routing daemon.
+
+Supported daemons:
+- bgpd
+- isisd
+- ldpd
+- ospf6d
+- ospfd
+- ripd
+- zebra
+``` \ No newline at end of file
diff --git a/docs/configuration/system/host-name.md b/docs/configuration/system/host-name.md
new file mode 100644
index 00000000..81840d1f
--- /dev/null
+++ b/docs/configuration/system/host-name.md
@@ -0,0 +1,70 @@
+(host-information)=
+
+# Host Information
+
+This section describes the system's host information and how to configure them,
+it covers the following topics:
+
+- Host name
+- Domain
+- IP address
+- Aliases
+
+## Hostname
+
+A hostname is the label (name) assigned to a network device (a host) on a
+network and is used to distinguish one device from another on specific networks
+or over the internet. On the other hand this will be the name which appears on
+the command line prompt.
+
+```{cfgcmd} set system host-name \<hostname\>
+
+ The hostname can be up to 63 characters. A hostname
+ must start and end with a letter or digit, and have as interior characters
+ only letters, digits, or a hyphen.
+
+ The default hostname used is `vyos`.
+```
+
+## Domain Name
+
+
+A domain name is the label (name) assigned to a computer network and is thus
+unique. VyOS appends the domain name as a suffix to any unqualified name. For
+example, if you set the domain name `example.com`, and you would ping the
+unqualified name of `crux`, then VyOS qualifies the name to `crux.example.com`.
+
+```{cfgcmd} set system domain-name \<domain\>
+
+Configure system domain name. A domain name must start and end with a letter
+or digit, and have as interior characters only letters, digits, or a hyphen.
+```
+
+## Static Hostname Mapping
+
+
+How an IP address is assigned to an interface in {ref}`ethernet-interface`.
+This section shows how to statically map an IP address to a hostname for local
+(meaning on this VyOS instance) name resolution. This is the VyOS equivalent to
+`/etc/hosts` file entries.
+
+
+:::{note}
+Do *not* manually edit `/etc/hosts`. This file will automatically be
+regenerated on boot based on the settings in this section, which means you'll
+lose all your manual edits. Instead, configure static host mappings as follows.
+:::
+
+```{cfgcmd} set system static-host-mapping host-name \<hostname\> inet \<address\>
+
+Create a static hostname mapping which will always resolve the name
+`<hostname>` to IP address `<address>`.
+```
+```{cfgcmd} set system static-host-mapping host-name \<hostname\> alias \<alias\>
+
+Create named `<alias>` for the configured static mapping for `<hostname>`.
+Thus the address configured as {cfgcmd}`set system static-host-mapping
+host-name <hostname> inet <address>` can be reached via multiple names.
+
+Multiple aliases can be specified per host-name.
+``` \ No newline at end of file
diff --git a/docs/configuration/system/index.md b/docs/configuration/system/index.md
new file mode 100644
index 00000000..e0b8a5a1
--- /dev/null
+++ b/docs/configuration/system/index.md
@@ -0,0 +1,34 @@
+# System
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+acceleration
+conntrack
+console
+flow-accounting
+frr
+host-name
+ip
+ipv6
+lcd
+login
+name-server
+option
+proxy
+sflow
+syslog
+sysctl
+task-scheduler
+time-zone
+updates
+watchdog
+```
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+default-route
+```
diff --git a/docs/configuration/system/ip.md b/docs/configuration/system/ip.md
new file mode 100644
index 00000000..717ee57d
--- /dev/null
+++ b/docs/configuration/system/ip.md
@@ -0,0 +1,126 @@
+# IP
+
+## System configuration commands
+
+```{cfgcmd} set system ip disable-forwarding
+
+Use this command to disable IPv4 forwarding on all interfaces.
+```
+
+```{cfgcmd} set system ip disable-directed-broadcast
+
+Use this command to disable IPv4 directed broadcast forwarding on all
+interfaces.
+
+If set, IPv4 directed broadcast forwarding will be completely disabled
+regardless of whether per-interface directed broadcast forwarding is
+enabled or not.
+```
+
+```{cfgcmd} set system ip arp table-size \<number\>
+
+Use this command to define the maximum number of entries to keep in
+the ARP cache (1024, 2048, 4096, 8192, 16384, 32768).
+```
+
+```{cfgcmd} set system ip multipath layer4-hashing
+
+Use this command to use Layer 4 information for IPv4 ECMP hashing.
+```
+
+```{cfgcmd} set system ip import-table \<table-id\>
+
+Use this command to immport the table, by given table id, into the main RIB.
+```
+
+```{cfgcmd} set system ip import-table \<table-id\> distance \<distance\>
+
+Use this command to override the default distance when importing routers
+from the alternate table.
+```
+
+```{cfgcmd} set system ip import-table \<table-id\> route-map \<route-map\>
+
+Use this command to filter routes that are imported into the main table
+from alternate table using route-map.
+```
+
+
+### Zebra/Kernel route filtering
+
+Zebra supports prefix-lists and Route Maps to match routes received from
+other FRR components. The permit/deny facilities provided by these commands
+can be used to filter which routes zebra will install in the kernel.
+
+```{cfgcmd} set system ip protocol \<protocol\> route-map \<route-map\>
+
+Apply a route-map filter to routes for the specified protocol. The following
+protocols can be used: any, babel, bgp, eigrp, isis, ospf, rip, static
+
+:::{note}
+If you choose any as the option that will cause all protocols that
+are sending routes to zebra.
+:::
+```
+
+
+### Nexthop Tracking
+
+Nexthop tracking resolve nexthops via the default route by default. This is enabled
+by default for a traditional profile of FRR which we use. It and can be disabled if
+you do not want to e.g. allow BGP to peer across the default route.
+
+```{cfgcmd} set system ip nht no-resolve-via-default
+
+Do not allow IPv4 nexthop tracking to resolve via the default route. This
+parameter is configured per-VRF, so the command is also available in the VRF
+subnode.
+```
+
+
+## Operational commands
+
+### show commands
+
+See below the different parameters available for the IPv4 **show** command:
+
+```none
+vyos@vyos:~$ show ip
+Possible completions:
+ access-list Show all IP access-lists
+ as-path-access-list
+ Show all as-path-access-lists
+ bgp Show Border Gateway Protocol (BGP) information
+ community-list
+ Show IP community-lists
+ extcommunity-list
+ Show extended IP community-lists
+ forwarding Show IP forwarding status
+ groups Show IP multicast group membership
+ igmp Show IGMP (Internet Group Management Protocol) information
+ large-community-list
+ Show IP large-community-lists
+ multicast Show IP multicast
+ ospf Show IPv4 Open Shortest Path First (OSPF) routing information
+ pim Show PIM (Protocol Independent Multicast) information
+ ports Show IP ports in use by various system services
+ prefix-list Show all IP prefix-lists
+ protocol Show IP route-maps per protocol
+ rip Show Routing Information Protocol (RIP) information
+ route Show IP routes
+```
+
+
+### reset commands
+
+And the different IPv4 **reset** commands available:
+
+```none
+vyos@vyos:~$ reset ip
+Possible completions:
+ arp Reset Address Resolution Protocol (ARP) cache
+ bgp Clear Border Gateway Protocol (BGP) statistics or status
+ igmp IGMP clear commands
+ multicast IP multicast routing table
+ route Reset IP route
+```
diff --git a/docs/configuration/system/ipv6.md b/docs/configuration/system/ipv6.md
new file mode 100644
index 00000000..ee0a6ade
--- /dev/null
+++ b/docs/configuration/system/ipv6.md
@@ -0,0 +1,193 @@
+# IPv6
+
+## System configuration commands
+
+```{cfgcmd} set system ipv6 disable-forwarding
+
+ Use this command to disable IPv6 forwarding on all interfaces.
+```
+
+
+```{cfgcmd} set system ipv6 neighbor table-size \<number\>
+
+Use this command to define the maximum number of entries to keep in
+the Neighbor cache (1024, 2048, 4096, 8192, 16384, 32768).
+```
+
+
+```{cfgcmd} set system ipv6 strict-dad
+
+Use this command to disable IPv6 operation on interface when
+Duplicate Address Detection fails on Link-Local address.
+```
+
+
+```{cfgcmd} set system ipv6 multipath layer4-hashing
+
+Use this command to user Layer 4 information for ECMP hashing.
+```
+
+### Zebra/Kernel route filtering
+
+
+Zebra supports prefix-lists and Route Maps to match routes received from
+other FRR components. The permit/deny facilities provided by these commands
+can be used to filter which routes zebra will install in the kernel.
+
+```{cfgcmd} set system ipv6 protocol \<protocol\> route-map \<route-map\>
+
+Apply a route-map filter to routes for the specified protocol. The following
+protocols can be used: any, babel, bgp, isis, ospfv3, ripng, static
+
+:::{note}
+If you choose any as the option that will cause all protocols that
+are sending routes to zebra.
+:::
+```
+
+### Nexthop Tracking
+
+
+Nexthop tracking resolve nexthops via the default route by default. This is enabled
+by default for a traditional profile of FRR which we use. It and can be disabled if
+you do not want to e.g. allow BGP to peer across the default route.
+
+```{cfgcmd} set system ipv6 nht no-resolve-via-default
+
+Do not allow IPv6 nexthop tracking to resolve via the default route. This
+parameter is configured per-VRF, so the command is also available in the VRF
+subnode.
+```
+
+## Operational commands
+
+
+### Show commands
+
+```{opcmd} show ipv6 neighbors
+
+Use this command to show IPv6 Neighbor Discovery Protocol information.
+```
+
+
+```{opcmd} show ipv6 groups
+
+Use this command to show IPv6 multicast group membership.
+```
+
+
+```{opcmd} show ipv6 forwarding
+
+Use this command to show IPv6 forwarding status.
+```
+
+
+```{opcmd} show ipv6 route
+
+Use this command to show IPv6 routes.
+
+Check the many parameters available for the show ipv6 route command:
+
+:::{code-block} none
+vyos@vyos:~$ show ipv6 route
+Possible completions:
+ <Enter> Execute the current command
+ <X:X::X:X> Show IPv6 routes of given address or prefix
+ <X:X::X:X/M>
+ bgp Show IPv6 BGP routes
+ cache Show kernel IPv6 route cache
+ connected Show IPv6 connected routes
+ forward Show kernel IPv6 route table
+ isis Show IPv6 ISIS routes
+ kernel Show IPv6 kernel routes
+ ospfv3 Show IPv6 OSPF6 routes
+ ripng Show IPv6 RIPNG routes
+ static Show IPv6 static routes
+ summary Show IPv6 routes summary
+ table Show IP routes in policy table
+ tag Show only routes with tag
+ vrf Show IPv6 routes in VRF
+:::
+```
+```{opcmd} show ipv6 prefix-list
+
+ Use this command to show all IPv6 prefix lists
+
+ There are different parameters for getting prefix-list information:
+
+ :::{code-block} none
+ vyos@vyos:~$ show ipv6 prefix-list
+ Possible completions:
+ <Enter> Execute the current command
+ <WORD> Show specified IPv6 prefix-list
+ detail Show detail of IPv6 prefix-lists
+ summary Show summary of IPv6 prefix-lists
+ :::
+```
+
+
+```{opcmd} show ipv6 access-list
+
+Use this command to show all IPv6 access lists
+
+You can also specify which IPv6 access-list should be shown:
+
+:::{code-block} none
+vyos@vyos:~$ show ipv6 access-list
+Possible completions:
+ <Enter> Execute the current command
+ <text> Show specified IPv6 access-list
+:::
+```
+```{opcmd} show ipv6 ospfv3
+
+ Use this command to get information about OSPFv3.
+
+ You can get more specific OSPFv3 information by using the parameters
+ shown below:
+
+ :::{code-block} none
+ vyos@vyos:~$ show ipv6 ospfv3
+ Possible completions:
+ <Enter> Execute the current command
+ area Show OSPFv3 spf-tree information
+ border-routers
+ Show OSPFv3 border-router (ABR and ASBR) information
+ database Show OSPFv3 Link state database information
+ interface Show OSPFv3 interface information
+ linkstate Show OSPFv3 linkstate routing information
+ neighbor Show OSPFv3 neighbor information
+ redistribute Show OSPFv3 redistribute External information
+ route Show OSPFv3 routing table information
+ :::
+```
+
+
+```{opcmd} show ipv6 ripng
+
+Use this command to get information about the RIPNG protocol
+```
+
+
+```{opcmd} show ipv6 ripng status
+
+Use this command to show the status of the RIPNG protocol
+```
+
+### Reset commands
+
+```{opcmd} reset bgp ipv6 \<address\>
+
+Use this command to clear Border Gateway Protocol statistics or
+status.
+```
+```{opcmd} reset ipv6 neighbors \<address | interface\>
+
+Use this command to reset IPv6 Neighbor Discovery Protocol cache for
+an address or interface.
+```
+```{opcmd} reset ipv6 route cache
+
+Use this command to flush the kernel IPv6 route cache.
+An address can be added to flush it only for that route.
+``` \ No newline at end of file
diff --git a/docs/configuration/system/lcd.md b/docs/configuration/system/lcd.md
new file mode 100644
index 00000000..ef9031ea
--- /dev/null
+++ b/docs/configuration/system/lcd.md
@@ -0,0 +1,41 @@
+(system-display)=
+
+# System Display (LCD)
+
+The system LCD {abbr}`LCD (Liquid-crystal display)` option is for users running
+VyOS on hardware that features an LCD display. This is typically a small display
+built in an 19 inch rack-mountable appliance. Those displays are used to show
+runtime data.
+
+To configure your LCD display you must first identify the used hardware, and
+connectivity of the display to your system. This can be any serial port
+(`ttySxx`) or serial via USB or even old parallel port interfaces.
+
+## Configuration
+
+```{cfgcmd} set system lcd device \<device\>
+
+This is the name of the physical interface used to connect to your LCD
+display. Tab completion is supported and it will list you all available
+serial interface.
+
+For serial via USB port information please refer to the USB hardware section.
+```
+
+```{cfgcmd} set system lcd model \<model\>
+
+This is the LCD model used in your system.
+
+At the time of this writing the following displays are supported:
+* Crystalfontz CFA-533
+* Crystalfontz CFA-631
+* Crystalfontz CFA-633
+* Crystalfontz CFA-635
+
+:::{note}
+We can't support all displays from the beginning. If your display
+type is missing, please create a feature request via
+Phabricator.
+:::
+```
+
diff --git a/docs/configuration/system/login.md b/docs/configuration/system/login.md
new file mode 100644
index 00000000..288d30a8
--- /dev/null
+++ b/docs/configuration/system/login.md
@@ -0,0 +1,604 @@
+---
+lastproofread: '2026-01-12'
+---
+
+(user-management)=
+
+# Login/user management
+
+The default VyOS user account (`vyos`), as well as newly created user accounts,
+possess full system configuration privileges. These accounts are granted sudo
+privileges, allowing them to execute commands as the root user.
+
+VyOS supports both local authentication and remote authentication via
+{abbr}`RADIUS (Remote Authentication Dial-In User Service)`/ {abbr}`TACACS+
+(Terminal Access Controller Access-Control System)`.
+
+## Local authentication
+
+```{cfgcmd} set system login user \<name\> full-name "\<string\>"
+
+**Configure the real name or description for a system user.**
+
+If the description includes spaces, enclose ``<string>`` in double quotes.
+
+If the user ``<name>`` already exists, the command updates the current
+description. If not, it creates a new user with the specified description.
+```
+
+```{cfgcmd} set system login user \<name\> authentication plaintext-password \<password\>
+
+**Configure a password for a system user.**
+
+Enter the password in plaintext. Upon ``commit``, VyOS hashes the password for
+secure storage and removes the plaintext value.
+
+If the user ``<name>`` already exists, the command updates the current password.
+If not, it creates a new user with the specified plaintext password.
+```
+
+```{cfgcmd} set system login user \<name\> authentication encrypted-password \<password\>
+
+**Configure a pre-encrypted password for a system user.**
+
+Enter the password in its hashed format. Upon ``commit``, VyOS stores this value
+directly without modification.
+
+If the user ``<name>`` already exists, the command updates the current password.
+If not, it creates a new user with the specified pre-encrypted password.
+```
+
+```{cfgcmd} set system login user \<name\> authentication principal \<principal\>
+
+**Configure an SSH certificate principal for a system user.**
+
+Enter the principal (a string included in the user's signed SSH certificate).
+Upon ``commit``, VyOS stores this mapping, allowing the user to log in if the
+certificate they present contains this principal.
+
+If the user ``<name>`` already exists, the command updates the principal. If not,
+it creates a new user linked to the specified principal.
+
+**If not configured**, the principal defaults to ``<name>``.
+```
+
+```{cfgcmd} set system login user \<name\> disable
+
+**Disable a system user account.**
+
+VyOS locks the account, preventing the user from logging in.
+```
+
+(ssh_key_based_authentication)=
+
+## Key-based authentication
+
+Key-based authentication is the recommended method for securing SSH access in
+VyOS. It uses a **public/private key pair** to verify user identity without
+requiring a password. To authorize access, you assign **SSH public keys** to
+user accounts on the router, while SSH private keys remain on local devices.
+VyOS allows assigning multiple SSH public keys to a single user account, which
+is useful for accessing a router from different devices.
+
+### Generate the key pair
+
+Generate an SSH key pair on your **local machine** using the `ssh-keygen`
+command. This creates two files:
+- **Private key** (e.g., `id_rsa`): Remains on your local machine and must
+ never be shared.
+- **Public key** (e.g., `id_rsa.pub`): Is used to configure the VyOS user
+ account. By default, it is saved to `~/.ssh/id_rsa.pub`.
+
+Each SSH public key consists of three parts, separated by spaces:
+- **Encryption algorithm type:** `ssh-rsa`, `ssh-ed25519`, etc.
+- **Key:** The actual data (a long string beginning with `AAAA...`).
+- **Comment:** An identifier for your reference (e.g., `user@host`).
+
+Only the encryption algorithm type and key parts are required to
+configure the authorization entry in VyOS. The comment part is optional.
+
+:::{seealso}
+{ref}`SSH operation <ssh_operation>`
+:::
+
+:::{warning}
+SSH key strings are long. When copying and pasting, ensure your
+terminal does not insert line breaks. The key must be entered as a **single
+line** to function correctly.
+:::
+
+### Configure the router
+
+To configure SSH public key authentication for a user account, run the
+following two commands using the same `<identifier>`:
+
+```{cfgcmd} set system login user \<username\> authentication public-keys \<identifier\> key \<key\>
+
+**Configure the SSH public key for the user account.**
+* ``<identifier>``: A unique label that identifies this specific key entry.
+* ``<key>``: The actual string of characters from your public key.
+```
+
+```{cfgcmd} set system login user \<username\> authentication public-keys \<identifier\> type \<type\>
+
+**Configure the SSH key's encryption type.**
+
+The following encryption algorithm types are available:
+
+* ``ecdsa-sha2-nistp256``
+* ``ecdsa-sha2-nistp384``
+* ``ecdsa-sha2-nistp521``
+* ``ssh-dss``
+* ``ssh-ed25519``
+* ``ssh-rsa``
+
+:::{note}
+To assign multiple SSH public keys to a user account, repeat the
+commands above with a unique identifier for each key.
+:::
+```
+
+```{cfgcmd} set system login user \<username\> authentication public-keys \<identifier\> options \<options\>
+
+**Configure specific restrictions or behaviors for an SSH public key.**
+
+``<options>``: A string of comma-separated values that define permissions
+or restrictions for this key.
+
+The command accepts standard OpenSSH options listed in the router's
+``~/.ssh/authorized_keys`` file.
+
+To include a ``"`` character in the options string, use ``&quot;``.
+
+For example, to restrict allowed source IP addresses for an SSH public key,
+use: ``from=&quot;10.0.0.0/24&quot;``.
+```
+
+
+## OTP-based MFA
+
+VyOS lets you enhance user access security by enabling {abbr}`OTP (One-time
+password)`-based {abbr}`MFA (Multi-factor Authentication)` for individual
+users. Users with {abbr}`OTP (One-time password)`-based {abbr}`MFA
+(Multi-factor Authentication)` must enter a valid {abbr}`OTP (One-time
+password)` along with their password at login. Users without {abbr}`OTP
+(One-time password)`-based {abbr}`MFA (Multi-factor Authentication)` use
+standard authentication.
+
+```{cfgcmd} set system login user \<username\> authentication otp key \<key\>
+
+**Configure** {abbr}`OTP (One-time password)`**-based** {abbr}`MFA
+(Multi-factor Authentication)` **for a user.**
+
+``<key>``: A Base32-encoded secret key. This key must be added to the user's
+authenticator app to generate valid {abbr}`OTPs (One-time passwords)`.
+
+**When configured**, the user is required to enter their password followed by
+a valid OTP for all subsequent logins.
+```
+
+
+### OTP settings
+
+```{cfgcmd} set system login user \<username\> authentication otp rate-limit \<limit\>
+
+**Configure the number of** {abbr}`OTP (One-time password)` **authentication
+attempts allowed within a specified time period.**
+
+If this limit is exceeded, the user is temporarily blocked.
+
+The default value is 3 attempts. The valid range is 1 to 10 attempts.
+```
+
+```{cfgcmd} set system login user \<username\> authentication otp rate-time \<seconds\>
+
+**Configure the time period, in seconds, for tracking** {abbr}`OTP (One-time
+password)` **authentication attempts.**
+
+The default value is 30 seconds. The valid range is 1 to 600 seconds.
+```
+
+```{cfgcmd} set system login user \<username\> authentication otp window-size \<size\>
+
+**Configure the** {abbr}`OTP (One-time password)` **window size for a user.**
+
+The {abbr}`OTP (One-time password)` window size defines the number of
+concurrently valid {abbr}`OTPs (One-time passwords)` that the authentication
+server accepts. This setting assumes a new token is generated every 30 seconds.
+
+The default value is 3. This permits 3 concurrent codes: the code for the
+current 30-second interval, the preceding code, and the following code. This
+allows up to 30 seconds of time skew between the authentication server and
+client.
+
+If the window size is increased to 17, the system permits 17 concurrent codes
+(the current code, the 8 preceding codes, and the 8 following codes). This
+allows for a time skew of up to 4 minutes.
+
+The valid range is 1 to 21.
+```
+
+
+### Generate an OTP-key
+
+Use the following command to generate an OTP key:
+
+```{cfgcmd} generate system login username \<username\> otp-key hotp-time rate-limit \<1-10\> rate-time \<15-600\> window-size \<1-21\>
+```
+
+Key generation example:
+
+```none
+vyos@vyos:~$ generate system login username otptester otp-key hotp-time rate-limit 2 rate-time 20 window-size 5
+# You can share it with the user, he just needs to scan the QR in his OTP app
+# username: otptester
+# OTP KEY: J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY
+# OTP URL: otpauth://totp/otptester@vyos?secret=J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY&digits=6&period=30
+█████████████████████████████████████████████
+█████████████████████████████████████████████
+████ ▄▄▄▄▄ █▀█ █▄ ▀▄▀▄█▀▄ ▀█▀ █ ▄▄▄▄▄ ████
+████ █ █ █▀▀▀█ ▄▀ █▄▀ ▀▄ ▄ ▀ ▄█ █ █ ████
+████ █▄▄▄█ █▀ █▀▀██▄▄ █ █ ██ ▀▄▀ █ █▄▄▄█ ████
+████▄▄▄▄▄▄▄█▄▀ ▀▄█ █ ▀ █ █ █ █▄█▄█▄▄▄▄▄▄▄████
+████ ▄ █▄ ▄ ▀▄▀▀▀▀▄▀▄▀▄▄▄▀▀▄▄▄ █ █▄█ █████
+████▄▄ ██▀▄▄▄▀▀█▀ ▄ ▄▄▄ ▄▀ ▀ █ ▄ ▄ ██▄█ ████
+█████▄ ██▄▄▀█▄█▄█▄ ▀█▄▀▄ ▀█▀▄ █▄▄▄ ▄ ▄████
+████▀▀▄ ▄█▀▄▀ ▄█▀█▀▄▄▄▀█▄ ██▄▄▄ ▀█ █ ████
+████ ▄▀▄█▀▄▄█▀▀▄▀▀▀▀█ ▄▀▄▀ ▄█ ▀▄ ▄ ▄▀ █▄████
+████▄ ██ ▀▄▀▀ ▄█▀ ▄ ██ ▀█▄█ ▄█ ▄ ▀▄ ▄▄ ████
+████▄█▀▀▄ ▄▄ █▄█▄█▄ █▄▄▀▄▄▀▀▄▄██▀ ▄▀▄▄ ▀▄████
+████▀▄▀ ▄ ▄▀█ ▄ ▄█▀ █ ▀▄▄ ▄█▀ ▄▄ ▀▄▄ ████
+████ ▀███▄ █▄█▄▀▀▀▀▄ ▄█▄▄▀ ▀███ ▄▄█▄▄ ▄████
+████ ███▀ ▄▄▀▀██▀ ▄▀▄█▄▄▄ ██▄▄▀▄▀ ███▄ ▄████
+████▄████▄▄▄▀▄ █▄█▄▀▄▄▄▄██▀ ▄▀ ▄ ▄▄▄ █▄▄█████
+████ ▄▄▄▄▄ █▄▄▄ ▄█▀█▀▀▀▀█▀█▀ █▄█ █▄█ ▄█ ████
+████ █ █ █ ██▄▀▀▀▀▄▄▄▀ ▄▄▄ ▀ ▄ ▄ ▄▄████
+████ █▄▄▄█ █ ▀▀█▀ ▄▄█ █▄▄██▀▀█▀ █▄▀▄██▄█ ████
+████▄▄▄▄▄▄▄█▄█▄█▄█▄▄▄▄▄█▄▄▄█▄██████▄██▄▄▄████
+█████████████████████████████████████████████
+█████████████████████████████████████████████
+# To add this OTP key to configuration, run the following commands:
+set system login user otptester authentication otp key 'J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY'
+set system login user otptester authentication otp rate-limit '2'
+set system login user otptester authentication otp rate-time '20'
+set system login user otptester authentication otp window-size '5'
+```
+
+### Display the OTP key for a user
+
+Use the following command to display the {abbr}`OTP (One-time password)`
+key for a user:
+
+```{cfgcmd} sh system login authentication user \<username\> otp \<full | key-b32 | qrcode | uri\>
+```
+
+Example:
+
+```none
+vyos@vyos:~$ sh system login authentication user otptester otp full
+# You can share the OTP key with the user. They just need to scan the QR in their OTP app.
+# username: otptester
+# OTP KEY: J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY
+# OTP URL: otpauth://totp/otptester@vyos?secret=J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY&digits=6&period=30
+█████████████████████████████████████████████
+█████████████████████████████████████████████
+████ ▄▄▄▄▄ █▀█ █▄ ▀▄▀▄█▀▄ ▀█▀ █ ▄▄▄▄▄ ████
+████ █ █ █▀▀▀█ ▄▀ █▄▀ ▀▄ ▄ ▀ ▄█ █ █ ████
+████ █▄▄▄█ █▀ █▀▀██▄▄ █ █ ██ ▀▄▀ █ █▄▄▄█ ████
+████▄▄▄▄▄▄▄█▄▀ ▀▄█ █ ▀ █ █ █ █▄█▄█▄▄▄▄▄▄▄████
+████ ▄ █▄ ▄ ▀▄▀▀▀▀▄▀▄▀▄▄▄▀▀▄▄▄ █ █▄█ █████
+████▄▄ ██▀▄▄▄▀▀█▀ ▄ ▄▄▄ ▄▀ ▀ █ ▄ ▄ ██▄█ ████
+█████▄ ██▄▄▀█▄█▄█▄ ▀█▄▀▄ ▀█▀▄ █▄▄▄ ▄ ▄████
+████▀▀▄ ▄█▀▄▀ ▄█▀█▀▄▄▄▀█▄ ██▄▄▄ ▀█ █ ████
+████ ▄▀▄█▀▄▄█▀▀▄▀▀▀▀█ ▄▀▄▀ ▄█ ▀▄ ▄ ▄▀ █▄████
+████▄ ██ ▀▄▀▀ ▄█▀ ▄ ██ ▀█▄█ ▄█ ▄ ▀▄ ▄▄ ████
+████▄█▀▀▄ ▄▄ █▄█▄█▄ █▄▄▀▄▄▀▀▄▄██▀ ▄▀▄▄ ▀▄████
+████▀▄▀ ▄ ▄▀█ ▄ ▄█▀ █ ▀▄▄ ▄█▀ ▄▄ ▀▄▄ ████
+████ ▀███▄ █▄█▄▀▀▀▀▄ ▄█▄▄▀ ▀███ ▄▄█▄▄ ▄████
+████ ███▀ ▄▄▀▀██▀ ▄▀▄█▄▄▄ ██▄▄▀▄▀ ███▄ ▄████
+████▄████▄▄▄▀▄ █▄█▄▀▄▄▄▄██▀ ▄▀ ▄ ▄▄▄ █▄▄█████
+████ ▄▄▄▄▄ █▄▄▄ ▄█▀█▀▀▀▀█▀█▀ █▄█ █▄█ ▄█ ████
+████ █ █ █ ██▄▀▀▀▀▄▄▄▀ ▄▄▄ ▀ ▄ ▄ ▄▄████
+████ █▄▄▄█ █ ▀▀█▀ ▄▄█ █▄▄██▀▀█▀ █▄▀▄██▄█ ████
+████▄▄▄▄▄▄▄█▄█▄█▄█▄▄▄▄▄█▄▄▄█▄██████▄██▄▄▄████
+█████████████████████████████████████████████
+█████████████████████████████████████████████
+# To add this OTP key to configuration, run the following commands:
+set system login user otptester authentication otp key 'J5A64ERPMGJOZXY6FMHHLKXKANNI6TCY'
+set system login user otptester authentication otp rate-limit '2'
+set system login user otptester authentication otp rate-time '20'
+set system login user otptester authentication otp window-size '5'
+```
+
+Once {abbr}`OTP (One-time password)`-based {abbr}`MFA (Multi-factor
+Authentication)` is configured for a user account, this user must enter their
+standard password followed by the current 6-digit OTP code at login. For
+example, if the user's password is `vyosrocks` and the OTP is `817454`, they
+should enter `vyosrocks817454`.
+
+## RADIUS authentication
+
+For large-scale deployments, managing individual user accounts across multiple
+VyOS instances is inefficient. VyOS supports centralized authentication via
+{abbr}`RADIUS (Remote Authentication Dial-In User Service)`, consolidating user
+account management on a single backend server.
+
+### Configuration
+
+```{cfgcmd} set system login radius server \<address\> key \<secret\>
+
+**Configure the** {abbr}`RADIUS (Remote Authentication Dial-In User Service)`
+**server's IP address and shared secret.**
+
+The shared secret is used to verify the router's identity and to encrypt user
+passwords during authentication.
+
+You can configure multiple {abbr}`RADIUS (Remote Authentication Dial-In User
+Service)` servers.
+```
+
+```{cfgcmd} set system login radius server \<address\> port \<port\>
+
+**Configure the UDP port for communication with the** {abbr}`RADIUS (Remote
+Authentication Dial-In User Service)` **server.**
+
+The default port is 1812.
+```
+
+```{cfgcmd} set system login radius server \<address\> disable
+
+**Disable a** {abbr}`RADIUS (Remote Authentication Dial-In User Service)`
+**server from the authentication process.**
+
+Disabling a specific {abbr}`RADIUS (Remote Authentication Dial-In User
+Service)` server doesn’t remove its configuration settings (the server’s IP
+address and shared secret).
+```
+
+```{cfgcmd} set system login radius server \<address\> timeout \<timeout\>
+
+Configure the duration, in seconds, that the VyOS router waits for a
+response from the {abbr}`RADIUS (Remote Authentication Dial-In User Service)`
+server after sending an authentication request.
+
+If the server does not respond within this timeframe, the VyOS router tries to
+connect to another configured server or falls back to local authentication.
+```
+
+```{cfgcmd} set system login radius source-address \<address\>
+
+**Configure the source IP address the router uses for** {abbr}`RADIUS (Remote
+Authentication Dial-In User Service)` **authentication requests.**
+
+A consistent source IP address is recommended as RADIUS servers typically
+accept requests only from known, trusted IP addresses.
+
+If not explicitly defined, the router uses the current egress interface
+address, which may change (e.g., due to a link outage), causing authentication
+failures.
+```
+
+```{cfgcmd} set system login radius vrf \<name\>
+
+**Configure the router to send all** {abbr}`RADIUS (Remote Authentication
+Dial-In User Service)` **authentication requests via a specific VRF.**
+
+By default, {abbr}`RADIUS (Remote Authentication Dial-In User Service)`
+authentication requests are sent via the global routing table.
+```
+
+### Configuration example
+
+```none
+set system login radius server 192.168.0.2 key 'test-vyos'
+set system login radius server 192.168.0.2 port '1812'
+set system login radius server 192.168.0.2 timeout '5'
+set system login radius source-address '192.168.0.1'
+```
+
+If communication with the {abbr}`RADIUS (Remote Authentication Dial-In User
+Service)` server fails, the router falls back to local user authentication.
+During this process, users may experience a login delay while the system waits
+for the {abbr}`RADIUS (Remote Authentication Dial-In User Service)` request to
+time out. This delay depends on the configured timeout value.
+
+:::{hint}
+To grant administrative privileges to {abbr}`RADIUS (Remote
+Authentication Dial-In User Service)`-authenticated users, the server must
+return the Cisco-AV-Pair attribute set to `shell:priv-lvl=15`. Otherwise, users
+receive standard privileges and cannot perform configuration tasks.
+:::
+
+## TACACS+ authentication
+
+In addition to {abbr}`RADIUS (Remote Authentication Dial-In User Service)`,
+VyOS supports {abbr}`TACACS+ (Terminal Access Controller Access Control
+System)`, which is commonly used in large enterprise environments.
+
+Unlike {abbr}`RADIUS (Remote Authentication Dial-In User Service)`,
+{abbr}`TACACS+ (Terminal Access Controller Access Control System)` separates
+Authentication, Authorization, and Accounting (AAA) into independent processes
+and encrypts the entire packet body for enhanced security.
+
+{abbr}`TACACS+ (Terminal Access Controller Access Control System)` is defined
+in {rfc}`8907`.
+(tacacs-configuration)=
+
+### Configuration
+
+```{cfgcmd} set system login tacacs server \<address\> key \<secret\>
+
+**Configure the** {abbr}`TACACS+ (Terminal Access Controller Access Control
+System)` **server IP address and shared secret.**
+
+Unlike {abbr}`RADIUS (Remote Authentication Dial-In User Service)`, which
+encrypts only passwords, {abbr}`TACACS+ (Terminal Access Controller Access
+Control System)` encrypts the entire packet body for enhanced security.
+
+You can configure multiple {abbr}`TACACS+ (Terminal Access Controller Access
+Control System)` servers.
+```
+
+```{cfgcmd} set system login tacacs server \<address\> port \<port\>
+
+**Configure the TCP port for communication with the** {abbr}`TACACS+ (Terminal
+Access Controller Access Control System)` **server.**
+
+The default port is 49.
+```
+
+```{cfgcmd} set system login tacacs server \<address\> disable
+
+**Disable a** {abbr}`TACACS+ (Terminal Access Controller Access Control
+System)` **server from the authentication process.**
+
+Disabling a specific {abbr}`TACACS+ (Terminal Access Controller Access Control
+System)` server doesn’t remove its configuration settings (the server’s IP
+address and shared secret).
+```
+
+```{cfgcmd} set system login tacacs server \<address\> timeout \<timeout\>
+
+Configure the duration, in seconds, that the VyOS router waits for a
+response from the {abbr}`TACACS+ (Terminal Access Controller Access
+Control System)` server after sending an authentication request.
+
+If the server does not respond within this timeframe, the VyOS router tries
+to connect to another configured server or falls back to local authentication.
+```
+
+```{cfgcmd} set system login tacacs source-address \<address\>
+
+**Configure the source IP address the router uses for**
+{abbr}`TACACS+ (Terminal Access Controller Access Control System)`
+**authentication requests.**
+
+A consistent source IP address is recommended as {abbr}`TACACS+ (Terminal
+Access Controller Access Control System)` servers typically accept requests
+only from known, trusted IP addresses.
+
+If not explicitly defined, the router uses the current egress interface address,
+which may change (e.g., due to a link outage), causing authentication failures.
+```
+
+```{cfgcmd} set system login tacacs vrf \<name\>
+
+Configure the router to send all {abbr}`TACACS+ (Terminal Access Controller
+Access Control System)` authentication requests via a specific VRF.
+
+By default, {abbr}`TACACS+ (Terminal Access Controller Access Control System)`
+authentication requests are sent via the global routing table.
+```
+
+(login-tacacs-example)=
+
+### Configuration example
+
+```none
+set system login tacacs server 192.168.0.2 key 'test-vyos'
+set system login tacacs server 192.168.0.2 port '49'
+set system login tacacs source-address '192.168.0.1'
+```
+
+If communication with the {abbr}`TACACS+ (Terminal Access Controller Access
+Control System)` server fails, the router falls back to local user
+authentication.
+
+## Login banners
+
+VyOS allows you to configure **pre-login** and **post-login** banners.
+Pre-login banners are typically used for system identification, legal disclaimers, or security warnings
+displayed before authentication, while post-login banners provide system
+information or operational notices to users after login.
+
+```{cfgcmd} set system login banner pre-login \<message\>
+
+Configure a message to be shown to users before the ``username`` and ``password``
+prompts appear.
+```
+
+```{cfgcmd} set system login banner post-login \<message\>
+
+Configure a message to be shown to users after successful authentication.
+```
+:::{note}
+Use `\\n` to insert line breaks in multi-line banner messages.
+:::
+
+## Login session limits
+
+```{cfgcmd} set system login max-login-session \<number\>
+
+**Configure the maximum number of concurrent login sessions.**
+```
+:::{note}
+If you limit concurrent login sessions, you must also configure a
+session `<timeout>`. This clears inactive sessions and prevents blocking new
+login attempts.
+:::
+```{cfgcmd} set system login timeout \<timeout\>
+
+**Configure the login session timeout, in seconds.**
+
+Idle login sessions are terminated after this period.
+```
+
+## Configuration examples
+
+Example 1: Multi-key SSH with MFA and source restrictions
+
+In this configuration, `User1` and `User2` both use the vyos user account,
+each with a unique SSH key. `User1` is restricted to authentication from a
+single IP address.
+
+For both users, password-based logins require {abbr}`OTP (One-time password)`
+-based {abbr}`MFA (Multi-factor Authentication)`.
+
+```none
+set system login user vyos authentication public-keys 'User1' key "AAAAB3Nz...KwEW"
+set system login user vyos authentication public-keys 'User1' type ssh-rsa
+set system login user vyos authentication public-keys 'User1' options "from=&quot;192.168.0.100&quot;"
+
+set system login user vyos authentication public-keys 'User2' key "AAAAQ39x...fbV3"
+set system login user vyos authentication public-keys 'User2' type ssh-rsa
+
+set system login user vyos authentication otp key OHZ3OJ7U2N25BK4G7SOFFJTZDTCFUUE2
+set system login user vyos authentication plaintext-password vyos
+```
+
+Example 2: Containerized {abbr}`TACACS+ (Terminal Access Controller Access Control System)`
+deployment with redundancy.
+
+In this configuration, the VyOS router hosts its own authentication
+infrastructure using two containerized {abbr}`TACACS+ (Terminal Access
+Controller Access Control System)` servers (`tacacs1` and `tacacs2`) on a
+private network for redundancy.
+
+System logins are authenticated against credentials stored within these internal
+containers rather than the router's local user database.
+
+First, download the image in operational mode:
+
+```none
+add container image lfkeitel/tacacs_plus:latest
+```
+
+Next, configure the containers in configuration mode:
+
+```none
+set container network tac-test prefix '100.64.0.0/24'
+
+set container name tacacs1 image 'lfkeitel/tacacs_plus:latest'
+set container name tacacs1 network tac-test address '100.64.0.11'
+
+set container name tacacs2 image 'lfkeitel/tacacs_plus:latest'
+set container name tacacs2 network tac-test address '100.64.0.12'
+
+set system login tacacs server 100.64.0.11 key 'tac_plus_key'
+set system login tacacs server 100.64.0.12 key 'tac_plus_key'
+
+commit
+```
+
+You can now log in via SSH or console using `admin/admin` credentials supplied
+by the container image.
diff --git a/docs/configuration/system/name-server.md b/docs/configuration/system/name-server.md
new file mode 100644
index 00000000..9090ba5f
--- /dev/null
+++ b/docs/configuration/system/name-server.md
@@ -0,0 +1,65 @@
+(system-dns)=
+
+# System DNS
+
+:::{warning}
+If you are configuring a VRF for management purposes, there is
+currently no way to force system DNS traffic via a specific VRF.
+:::
+
+This section describes configuring DNS on the system, namely:
+
+> - DNS name servers
+> - Domain search order
+
+## DNS name servers
+
+```{cfgcmd} set system name-server \<address\>
+
+Use this command to specify a DNS server for the system to be used
+for DNS lookups. More than one DNS server can be added, configuring
+one at a time. Both IPv4 and IPv6 addresses are supported.
+```
+
+
+### Example
+
+In this example, some *OpenNIC* servers are used, two IPv4 addresses
+and two IPv6 addresses:
+
+```none
+set system name-server 176.9.37.132
+set system name-server 195.10.195.195
+set system name-server 2a01:4f8:161:3441::1
+set system name-server 2a00:f826:8:2::195
+```
+
+
+## Domain search order
+
+In order for the system to use and complete unqualified host names, a
+list can be defined which will be used for domain searches.
+
+```{cfgcmd} set system domain-search \<domain\>
+
+Use this command to define domains, one at a time, so that the system
+uses them to complete unqualified host names. Maximum: 6 entries.
+```
+
+:::{note}
+Domain names can include letters, numbers, hyphens and periods
+with a maximum length of 253 characters.
+:::
+
+(name-server-domain-search-order-example)=
+
+### Example
+
+The system is configured to attempt domain completion in the following
+order: vyos.io (first), vyos.net (second) and vyos.network (last):
+
+```none
+set system domain-search vyos.io
+set system domain-search vyos.net
+set system domain-search vyos.network
+```
diff --git a/docs/configuration/system/option.md b/docs/configuration/system/option.md
new file mode 100644
index 00000000..c7a6ccf2
--- /dev/null
+++ b/docs/configuration/system/option.md
@@ -0,0 +1,190 @@
+(system-option)=
+
+# Option
+
+This chapter describe the possibilities of advanced system behavior.
+
+## General
+
+```{cfgcmd} set system option ctrl-alt-delete \<ignore | reboot | poweroff\>
+
+Action which will be run once the ctrl-alt-del keystroke is received.
+```
+
+```{cfgcmd} set system option reboot-on-panic
+
+Automatically reboot system on kernel panic after 60 seconds.
+```
+
+```{cfgcmd} set system option reboot-on-upgrade-failure \<timeout\>
+
+Automatically reboot after `timeout` minutes into the previous running
+image, that was used to perform the image upgrade.
+
+Reboot `timeout` is configurable in minutes. This gives the user the change
+to log into the system and perform some analysis before automatic rebooting.
+
+Automatic reboot can be cancelled after login using: {opcmd}`reboot cancel`
+```
+
+```{cfgcmd} set system option startup-beep
+
+Play an audible beep to the system speaker when system is ready.
+```
+
+```{cfgcmd} set system option root-partition-auto-resize
+
+Enables the root partition auto-extension and resizes to the maximum
+available space on system boot.
+```
+
+
+### Kernel
+
+```{cfgcmd} set system option kernel disable-mitigations
+
+Disable all optional CPU mitigations. This improves system performance,
+but it may also expose users to several CPU vulnerabilities.
+
+This will add the following option to the Kernel commandline:
+* ``mitigations=off``
+
+:::{note}
+Setting will only become active with the next reboot!
+:::
+```
+
+```{cfgcmd} set system option kernel disable-power-saving
+
+This will add the following two options to the Kernel commandline:
+* ``intel_idle.max_cstate=0`` Disable intel_idle and fall back on acpi_idle
+* ``processor.max_cstate=1`` Limit processor to maximum C-state 1
+
+:::{note}
+Setting will only become active with the next reboot!
+:::
+```
+
+```{cfgcmd} set system option kernel amd-pstate-driver \<mode\>
+
+Enables and configures p-state driver for modern AMD Ryzen and Epyc CPUs.
+
+The available modes are:
+* ``active`` This is the low-level firmware control mode based on the profile
+set and the system governor has no effect.
+* ``passive`` The driver allows the system governor to manage CPU frequency
+while providing available performance states.
+* ``guided`` The driver allows to set desired performance levels and the firmware
+selects a performance level in this range and fitting to the current workload.
+
+This will add the following two options to the Kernel commandline:
+* ``initcall_blacklist=acpi_cpufreq_init`` Disable default ACPI CPU frequency scale
+* ``amd_pstate={mode}`` Sets the p-state mode
+
+:::{note}
+Setting will only become active with the next reboot!
+:::
+
+:::{seealso}
+<https://docs.kernel.org/admin-guide/pm/amd-pstate.html>
+:::
+```
+
+```{cfgcmd} set system option kernel quiet
+
+Suppress most kernel messages during boot. This is useful for systems with
+embedded serial console interfaces to speed up the boot process.
+```
+
+
+## HTTP client
+
+```{cfgcmd} set system option http-client source-address \<address\>
+
+Several commands utilize cURL to initiate transfers. Configure the local
+source IPv4/IPv6 address used for all cURL operations.
+```
+
+```{cfgcmd} set system option http-client source-interface \<interface\>
+
+Several commands utilize curl to initiate transfers. Configure the local
+source interface used for all CURL operations.
+```
+
+:::{note}
+`source-address` and `source-interface` can not be used at the same
+time.
+:::
+
+## SSH client
+
+```{cfgcmd} set system option ssh-client source-address \<address\>
+
+Use the specified address on the local machine as the source address of the
+connection. Only useful on systems with more than one address.
+```
+
+```{cfgcmd} set system option ssh-client source-interface \<interface\>
+
+Use the address of the specified interface on the local machine as the
+source address of the connection.
+```
+
+
+## Keyboard Layout
+
+When starting a VyOS live system (the installation CD) the configured keyboard
+layout defaults to US. As this might not suite everyone's use case you can adjust
+the used keyboard layout on the system console.
+
+```{cfgcmd} set system option keyboard-layout \<us | fr | de | fi | no | dk\>
+
+Change system keyboard layout to given language.
+
+Defaults to ``us``.
+
+:::{note}
+Changing the keymap only has an effect on the system console, using
+SSH or Serial remote access to the device is not affected as the keyboard
+layout here corresponds to your access system.
+:::
+```
+
+(system-options-performance)=
+
+## Performance
+
+As more and more routers run on Hypervisors, expecially with a {abbr}`NOS
+(Network Operating System)` as VyOS, it makes fewer and fewer sense to use
+static resource bindings like `smp-affinity` as present in VyOS 1.2 and
+earlier to pin certain interrupt handlers to specific CPUs.
+
+We now utilize `tuned` for dynamic resource balancing based on profiles.
+
+:::{seealso}
+<https://access.redhat.com/sites/default/files/attachments/201501-perf-brief-low-latency-tuning-rhel7-v2.1.pdf>
+:::
+
+```{cfgcmd} set system option performance \< throughput | latency \>
+
+Configure one of the predefined system performance profiles.
+
+* ``throughput``: A server profile focused on improving network throughput.
+ This profile favors performance over power savings by setting
+ ``intel_pstate`` and ``max_perf_pct=100`` and increasing kernel network
+ buffer sizes.
+
+ It enables transparent huge pages, and uses cpupower to set the performance
+ cpufreq governor. It also sets ``kernel.sched_min_granularity_ns`` to 10 us,
+ ``kernel.sched_wakeup_granularity_ns`` to 15 uss, and ``vm.dirty_ratio`` to
+ 40%.
+
+* ``latency``: A server profile focused on lowering network latency.
+ This profile favors performance over power savings by setting
+ ``intel_pstate`` and ``min_perf_pct=100``.
+
+ It disables transparent huge pages, and automatic NUMA balancing. It also
+ uses cpupower to set the performance cpufreq governor, and requests a
+ cpu_dma_latency value of 1. It also sets busy_read and busy_poll times to
+ 50 us, and tcp_fastopen to 3.
+``` \ No newline at end of file
diff --git a/docs/configuration/system/proxy.md b/docs/configuration/system/proxy.md
new file mode 100644
index 00000000..286e835f
--- /dev/null
+++ b/docs/configuration/system/proxy.md
@@ -0,0 +1,27 @@
+(system-proxy)=
+
+# System Proxy
+
+Some IT environments require the use of a proxy to connect to the Internet.
+Without this configuration VyOS updates could not be installed directly by
+using the {opcmd}`add system image` command ({ref}`update_vyos`).
+
+```{cfgcmd} set system proxy url \<url\>
+
+Set proxy for all connections initiated by VyOS, including HTTP, HTTPS, and
+FTP (anonymous ftp).
+```
+```{cfgcmd} set system proxy port \<port\>
+
+Configure proxy port if it does not listen to the default port 80.
+```
+```{cfgcmd} set system proxy username \<username\>
+
+Some proxys require/support the "basic" HTTP authentication scheme as per
+{rfc}`7617`, thus a username can be configured.
+```
+```{cfgcmd} set system proxy password \<password\>
+
+Some proxys require/support the "basic" HTTP authentication scheme as per
+{rfc}`7617`, thus a password can be configured.
+``` \ No newline at end of file
diff --git a/docs/configuration/system/sflow.md b/docs/configuration/system/sflow.md
new file mode 100644
index 00000000..350bbdd8
--- /dev/null
+++ b/docs/configuration/system/sflow.md
@@ -0,0 +1,66 @@
+# sFlow
+
+VyOS supports sFlow accounting for both IPv4 and IPv6 traffic. The system acts as a flow exporter, and you are free to use it with any compatible collector.
+
+sFlow is a technology that enables monitoring of network traffic by sending sampled packets to a collector device.
+
+The sFlow accounting based on hsflowd <https://sflow.net/>
+
+## Configuration
+
+```{cfgcmd} set system sflow agent-address \<address\>
+
+Configure sFlow agent IPv4 or IPv6 address
+```
+```{cfgcmd} set system sflow agent-interface \<interface\>
+
+Configure agent IP address associated with this interface.
+```
+```{cfgcmd} set system sflow drop-monitor-limit \<limit\>
+
+ Dropped packets reported on DROPMON Netlink channel by Linux kernel are exported via the standard sFlow v5 extension for reporting dropped packets
+```
+
+
+```{cfgcmd} set system sflow interface \<interface\>
+
+Configure and enable collection of flow information for the interface identified by \<interface\>.
+
+You can configure multiple interfaces which would participate in sflow accounting.
+```
+```{cfgcmd} set system sflow polling \<sec\>
+
+ Configure schedule counter-polling in seconds (default: 30)
+```
+
+
+```{cfgcmd} set system sflow sampling-rate \<rate\>
+
+Use this command to configure the sampling rate for sFlow accounting (default: 1000)
+```
+
+
+```{cfgcmd} set system sflow server \<address\> port \<port\>
+
+Configure address of sFlow collector. sFlow server at \<address\> can be both listening on an IPv4 or IPv6 address.
+```
+
+
+```{cfgcmd} set system sflow enable-egress
+
+Use this command to if you need to sample also egress traffic
+```
+
+## Example
+
+```none
+set system sflow agent-address '192.0.2.14'
+set system sflow agent-interface 'eth0'
+set system sflow drop-monitor-limit '50'
+set system sflow interface 'eth0'
+set system sflow interface 'eth1'
+set system sflow polling '30'
+set system sflow sampling-rate '1000'
+set system sflow server 192.0.2.1 port '6343'
+set system sflow server 203.0.113.23 port '6343'
+```
diff --git a/docs/configuration/system/sysctl.md b/docs/configuration/system/sysctl.md
new file mode 100644
index 00000000..90434fb2
--- /dev/null
+++ b/docs/configuration/system/sysctl.md
@@ -0,0 +1,16 @@
+(sysctl)=
+
+# Sysctl
+
+:::{note}
+This page is a stub and needs expansion. Contributions
+welcome via the [VyOS documentation repository](https://github.com/vyos/vyos-documentation).
+:::
+
+This chapter describes how to configure kernel parameters at runtime.
+
+`sysctl` is used to modify kernel parameters at runtime. The parameters
+available are those listed under /proc/sys/.
+
+```{cfgcmd} set system sysctl parameter \<parameter\> value \<value\>
+``` \ No newline at end of file
diff --git a/docs/configuration/system/syslog.md b/docs/configuration/system/syslog.md
new file mode 100644
index 00000000..ae30d272
--- /dev/null
+++ b/docs/configuration/system/syslog.md
@@ -0,0 +1,450 @@
+(syslog)=
+
+# Syslog
+
+## Overview
+
+By default, VyOS provides a minimal logging configuration with local storage
+and log rotation. All errors, including local7 messages, are saved to a local
+file. Emergency alerts are sent to the console.
+
+To change these settings, enter configuration mode.
+
+## Syslog configuration
+
+Syslog supports logging to multiple destinations: a local file, a console, or
+a remote syslog server over UDP or TCP.
+
+The syslog configuration is organized into the following categories:
+
+- Global settings
+- Local logging
+- Console logging
+- Remote logging
+- TLS-encrypted remote logging
+
+### Global settings
+
+Configure the general behavior of the syslog service.
+
+```{cfgcmd} set system syslog marker interval \<number\>
+
+**Configure the interval, in seconds, for sending syslog mark messages.**
+
+Syslog mark messages confirm the logging service is operational.
+
+Default: 1200 seconds.
+```
+
+```{cfgcmd} set system syslog marker disable
+
+Disable sending syslog mark messages.
+```
+
+```{cfgcmd} set system syslog preserve-fqdn
+
+**Configure how the logging device's hostname appears in log messages sent
+to a remote syslog server.**
+
+If configured, the device includes its {abbr}`FQDN (Fully Qualified Domain
+Name)` in log messages, even if the syslog server is in the same domain.
+```
+
+
+### Local logging
+
+Configure which log messages to save to a local log file.
+
+```{cfgcmd} set system syslog local \<filename\> facility \<keyword\> level \<keyword\>
+
+**Configure syslog to save log messages for a specific facility and
+severity level to \`\`/var/log/messages\`\`.**
+
+Refer to the tables below for valid facility and severity options.
+```
+
+(syslog-console)=
+
+### Console logging
+
+Configure which log messages to send to `/dev/console`.
+
+```{cfgcmd} set system syslog console facility \<keyword\> level \<keyword\>
+
+**Configure syslog to send log messages for a specific facility and severity
+level to the device's console.**
+
+Refer to the tables below for valid facility and severity options.
+```
+
+(syslog-remote)=
+
+### Remote logging
+
+Configure **remote logging** to send log messages to a remote syslog server.
+
+Remote logging does not affect either **local** or **console logging** and
+runs in parallel with them. Remote logging supports sending log messages
+to multiple hosts.
+
+```{cfgcmd} set system syslog remote \<address\> facility \<keyword\> level \<keyword\>
+
+**Configure log transmission to the remote syslog server for a specific
+facility and severity level.**
+
+The server’s address can be specified using either a {abbr}`FQDN (Fully
+Qualified Domain Name)` or an IP address.
+
+Refer to the tables below for valid facility and severity options.
+```
+
+```{cfgcmd} set system syslog remote \<address\> protocol \<udp | tcp\>
+
+**Configure the protocol for log transmission.**
+
+The protocol can be either UDP or TCP. By default, log messages are sent
+over UDP.
+```
+
+```{cfgcmd} set system syslog remote \<address\> port \<port\>
+
+**Configure the port for log transmission.**
+
+By default, the standard port 514 is used.
+```
+
+```{cfgcmd} set system syslog remote \<address\> format include-timezone
+
+**Configure log transmission in the RFC 5424 format.**
+
+The RFC 5424 format includes the timezone in the timestamp. For example:
+
+:::{code-block} none
+<34>1 2003-10-11T22:14:15.003-07:00 mymachine.example.com su - ID47 - BOM’su root’ failed for lonvick on /dev/pts/8.
+:::
+
+By default, log messages are sent in the RFC 3164 format. For example:
+
+:::{code-block} none
+<34>Oct 11 22:14:15 mymachine su: ‘su root’ failed for lonvick on /dev/pts/8
+:::
+```
+
+```{cfgcmd} set system syslog remote \<address\> format octet-counted
+
+**Enable octet-counted framing for log transmission.**
+
+When enabled, multi-line log messages are sent without splitting. Ensure
+the remote server supports octet-counted framing to avoid parsing errors.
+
+Octet-counted framing is not available for the UDP protocol.
+```
+
+```{cfgcmd} set system syslog remote \<address\> vrf \<name\>
+
+Configure the {abbr}`VRF (Virtual Routing and Forwarding)` instance
+for log transmission.
+```
+
+```{cfgcmd} set system syslog remote \<address\> source-address \<address\>
+
+Configure the source IP address (IPv4 or IPv6) for log transmission.
+```
+
+
+#### {abbr}`TLS (Transport Layer Security)`-encrypted remote logging
+
+VyOS supports {abbr}`TLS (Transport Layer Security)`-encrypted remote logging
+over TCP to ensure secure transmission of syslog data to remote syslog servers.
+
+**Prerequisites**: Before configuring {abbr}`TLS (Transport Layer
+Security)`-encrypted remote logging, ensure you have:
+- A valid remote syslog server address.
+- Valid {abbr}`CA (Certificate Authority)` and client certificates uploaded
+ to the local {abbr}`PKI (Public Key Infrastructure)` storage.
+- The **remote syslog transport protocol** is set to **TCP**:
+
+ ```none
+ set system syslog remote <address> protocol tcp
+ ```
+
+:::{note}
+{abbr}`TLS (Transport Layer Security)`-encrypted remote logging is
+**not supported** over **UDP**.
+:::
+```{cfgcmd} set system syslog remote \<address\> tls
+
+Enable TLS-encrypted remote logging.
+
+```
+
+```{cfgcmd} set system syslog remote \<address\> tls ca-certificate \<ca_name\>
+
+**Configure the** {abbr}`CA (Certificate Authority)` **certificate.**
+
+The syslog client uses the {abbr}`CA (Certificate Authority)` certificate to
+verify the identity of the remote syslog server.
+
+The {abbr}`CA (Certificate Authority)` certificate is required for **all**
+authentication modes except ``anon``.
+
+```
+
+```{cfgcmd} set system syslog remote \<address\> tls certificate \<cert_name\>
+
+**Configure the client certificate.**
+
+The remote syslog server uses the client certificate to verify the identity
+of the syslog client.
+
+The client certificate is required if the remote syslog server enforces
+client certificate verification.
+
+```
+
+````{cfgcmd} set system syslog remote \<address\> tls auth-mode \<anon | fingerprint | certvalid | name\>
+
+**Configure the authentication mode.**
+
+The authentication mode defines how the syslog client verifies the syslog
+server's identity.
+
+The following authentication modes are available:
+
+```{eval-rst}
+* ``anon`` **(default)**: Allows encrypted connections without verifying the syslog
+ server's identity. This mode is **not recommended**, as it is vulnerable to
+ :abbr:`MITM (Man-in-the-Middle)` attacks.
+* ``fingerprint``: Verifies the server’s certificate fingerprint against the
+ value preconfigured with:
+
+ .. code-block:: none
+
+ set system syslog remote <address> tls permitted-peer <peer>
+
+* ``certvalid``: Verifies the server certificate is signed by a trusted
+ :abbr:`CA (Certificate Authority)`, skipping :abbr:`CN (Common Name)` check.
+* ``name``: Verifies that:
+
+ * The server’s certificate is signed by a trusted :abbr:`CA (Certificate
+ Authority)`.
+ * The :abbr:`CN (Common Name)` in the certificate matches the value
+ preconfigured with:
+
+ .. code-block:: none
+
+ set system syslog remote <address> tls permitted-peer <peer>
+
+ This is a **recommended** secure mode for production environments.
+```
+
+````
+
+```{cfgcmd} set system syslog remote \<address\> tls permitted-peer \<peer\>
+
+**Configure the peer certificate identifiers.**
+
+The certificate identifier format depends on the authentication mode:
+* ``fingerprint``: Enter the expected certificate fingerprints (SHA-1 or
+SHA-256).
+* ``name``: Enter the expected certificate {abbr}`CNs (Common Names)`.
+
+For ``anon`` and ``certvalid`` authentication modes, certificate identifiers
+are not required.
+
+```
+
+#### Examples:
+
+```none
+# Example of 'anon' authentication mode
+set system syslog remote 10.10.2.3 facility all level debug
+set system syslog remote 10.10.2.3 port 6514
+set system syslog remote 10.10.2.3 protocol tcp
+set system syslog remote 10.10.2.3 tls auth-mode anon
+# or just use 'set system syslog remote 10.10.2.3 tls'
+
+# Example of 'certvalid' authentication mode
+set system syslog remote elk.example.com facility all level debug
+set system syslog remote elk.example.com port 6514
+set system syslog remote elk.example.com protocol tcp
+set system syslog remote elk.example.com tls ca-certificate my-ca
+set system syslog remote elk.example.com tls auth-mode certvalid
+
+# Example of 'fingerprint' authentication mode
+set system syslog remote syslog.example.com facility all level debug
+set system syslog remote syslog.example.com port 6514
+set system syslog remote syslog.example.com protocol tcp
+set system syslog remote syslog.example.com tls ca-certificate my-ca
+set system syslog remote syslog.example.com tls auth-mode fingerprint
+set system syslog remote syslog.example.com tls permitted-peers 'SHA1:10:C4:26:...,SHA256:7B:4B:10:...'
+
+# Example of 'name' authentication mode
+set system syslog remote graylog.example.com facility all level debug
+set system syslog remote graylog.example.com port 6514
+set system syslog remote graylog.example.com protocol tcp
+set system syslog remote graylog.example.com tls ca-certificate my-ca
+set system syslog remote graylog.example.com tls certificate syslog-client
+set system syslog remote graylog.example.com tls auth-mode name
+set system syslog remote graylog.example.com tls permitted-peers 'graylog.example.com'
+```
+
+#### Security recommendations
+
+- For secure deployments, always use the `name` authentication mode. It
+ ensures that the server is validated by a trusted {abbr}`CA (Certificate
+ Authority)` and that the hostname matches the certificate.
+- Use the `anon` authentication mode only in testing environments, as it
+ doesn't provide server authentication.
+- Ensure private keys are generated, stored, and maintained exclusively within
+ the {doc}`PKI system </configuration/pki/index>`.
+(syslog_facilities)=
+
+## Syslog facilities
+
+This section lists facilities used by syslog. Most facility names are self-
+explanatory. The local0–local7 facilities are used for custom purposes, such as
+logging from network nodes and equipment. Facility assignment is flexible and
+should be tailored to your company's needs. Consider facilities as categorization
+tools, rather than strict directives.
+
+```{eval-rst}
++----------+----------+----------------------------------------------------+
+| Facility | Keyword | Description |
+| code | | |
++==========+==========+====================================================+
+| | all | All facilities |
++----------+----------+----------------------------------------------------+
+| 0 | kern | Kernel messages |
++----------+----------+----------------------------------------------------+
+| 1 | user | User-level messages |
++----------+----------+----------------------------------------------------+
+| 2 | mail | Mail system |
++----------+----------+----------------------------------------------------+
+| 3 | daemon | System daemons |
++----------+----------+----------------------------------------------------+
+| 4 | auth | Security/authentication messages |
++----------+----------+----------------------------------------------------+
+| 5 | syslog | Messages generated internally by syslog |
++----------+----------+----------------------------------------------------+
+| 6 | lpr | Line printer subsystem |
++----------+----------+----------------------------------------------------+
+| 7 | news | Network news subsystem |
++----------+----------+----------------------------------------------------+
+| 8 | uucp | UUCP subsystem |
++----------+----------+----------------------------------------------------+
+| 9 | cron | Clock daemon |
++----------+----------+----------------------------------------------------+
+| 10 | security | Security/authentication messages |
++----------+----------+----------------------------------------------------+
+| 11 | ftp | FTP daemon |
++----------+----------+----------------------------------------------------+
+| 12 | ntp | NTP subsystem |
++----------+----------+----------------------------------------------------+
+| 13 | logaudit | Log audit |
++----------+----------+----------------------------------------------------+
+| 14 | logalert | Log alert |
++----------+----------+----------------------------------------------------+
+| 15 | clock | clock daemon (note 2) |
++----------+----------+----------------------------------------------------+
+| 16 | local0 | local use 0 (local0) |
++----------+----------+----------------------------------------------------+
+| 17 | local1 | local use 1 (local1) |
++----------+----------+----------------------------------------------------+
+| 18 | local2 | local use 2 (local2) |
++----------+----------+----------------------------------------------------+
+| 19 | local3 | local use 3 (local3) |
++----------+----------+----------------------------------------------------+
+| 20 | local4 | local use 4 (local4) |
++----------+----------+----------------------------------------------------+
+| 21 | local5 | local use 5 (local5) |
++----------+----------+----------------------------------------------------+
+| 22 | local6 | local use 6 (local6) |
++----------+----------+----------------------------------------------------+
+| 23 | local7 | local use 7 (local7) |
++----------+----------+----------------------------------------------------+
+```
+
+(syslog_severity_level)=
+
+## Severity levels
+
+```{eval-rst}
++-------+---------------+---------+-------------------------------------------+
+| Value | Severity | Keyword | Description |
++=======+===============+=========+===========================================+
+| | | all | Log everything. |
++-------+---------------+---------+-------------------------------------------+
+| 0 | Emergency | emerg | System is unusable - a panic condition. |
++-------+---------------+---------+-------------------------------------------+
+| 1 | Alert | alert | Action must be taken immediately - A |
+| | | | condition that should be corrected |
+| | | | immediately, such as a corrupted system |
+| | | | database. |
++-------+---------------+---------+-------------------------------------------+
+| 2 | Critical | crit | Critical conditions - e.g., hard drive |
+| | | | errors. |
++-------+---------------+---------+-------------------------------------------+
+| 3 | Error | err | Error conditions. |
++-------+---------------+---------+-------------------------------------------+
+| 4 | Warning | warning | Warning conditions. |
++-------+---------------+---------+-------------------------------------------+
+| 5 | Notice | notice | Normal but significant conditions - |
+| | | | conditions that are not error conditions, |
+| | | | but that may require special handling. |
++-------+---------------+---------+-------------------------------------------+
+| 6 | Informational | info | Informational messages. |
++-------+---------------+---------+-------------------------------------------+
+| 7 | Debug | debug | Debug-level messages - Messages that |
+| | | | contain information normally of use only |
+| | | | when debugging a program. |
++-------+---------------+---------+-------------------------------------------+
+```
+
+## Display logs
+
+```{opcmd} show log [all | authorization | cluster | conntrack-sync | ...]
+
+**Display logs for a specific category on the console.**
+
+Use tab completion to view a list of available categories.
+
+If no category is specified, all logs are shown.
+
+```
+
+````{opcmd} show log image \<name\> [all | authorization | directory | file \<file name\> | tail \<lines\>]
+
+**Display logs for a specific image on the console.**
+
+Available log categories:
+
+```{eval-rst}
+.. list-table::
+ :widths: 25 75
+ :header-rows: 0
+
+ * - all
+ - Displays the contents of system log files of the specified image.
+ * - authorization
+ - Displays authorization attempts of the specified image.
+ * - directory
+ - Displays user-defined log files of the specified image.
+ * - file <file name>
+ - Displays the contents of a specified user-defined log file of the specified
+ image.
+ * - tail
+ - Displays last lines of the system log of the specified image.
+ * - <lines>
+ - Number of lines to be displayed, default 10.
+```
+
+````
+
+If no category is specified, the contents of the main syslog file are
+displayed.
+
+:::{hint}
+Use `show log | strip-private` to hide private data
+when displaying your logs.
+:::
diff --git a/docs/configuration/system/task-scheduler.md b/docs/configuration/system/task-scheduler.md
new file mode 100644
index 00000000..94ca9f4d
--- /dev/null
+++ b/docs/configuration/system/task-scheduler.md
@@ -0,0 +1,45 @@
+(task-scheduler)=
+
+# Task Scheduler
+
+The task scheduler allows you to execute tasks on a given schedule. It makes
+use of UNIX [cron].
+
+:::{note}
+All scripts executed this way are executed as root user - this may
+be dangerous. Together with {ref}`command-scripting` this can be used for
+automating (re-)configuration.
+:::
+
+```{cfgcmd} set system task-scheduler task \<task\> interval \<interval\>
+
+Specify the time interval when `<task>` should be executed. The interval
+is specified as number with one of the following suffixes:
+* ``none`` - Execution interval in minutes
+* ``m`` - Execution interval in minutes
+* ``h`` - Execution interval in hours
+* ``d`` - Execution interval in days
+
+:::{note}
+If suffix is omitted, minutes are implied.
+:::
+```
+
+```{cfgcmd} set system task-scheduler task \<task\> crontab-spec \<spec\>
+
+Set execution time in common cron time format. A cron `<spec>` of
+``30 */6 * * *`` would execute the `<task>` at minute 30 past every 6th hour.
+```
+
+```{cfgcmd} set system task-scheduler task \<task\> executable path \<path\>
+
+Specify absolute `<path>` to script which will be run when `<task>` is
+executed.
+```
+
+```{cfgcmd} set system task-scheduler task \<task\> executable arguments \<args\>
+
+Arguments which will be passed to the executable.
+```
+
+[cron]: https://en.wikipedia.org/wiki/Cron
diff --git a/docs/configuration/system/time-zone.md b/docs/configuration/system/time-zone.md
new file mode 100644
index 00000000..2279a773
--- /dev/null
+++ b/docs/configuration/system/time-zone.md
@@ -0,0 +1,17 @@
+(timezone)=
+
+# Time Zone
+
+Time Zone setting is very important as e.g all your logfile entries will be
+based on the configured zone. Without proper time zone configuration it will
+be very difficult to compare logfiles from different systems.
+
+```{cfgcmd} set system time-zone \<timezone\>
+
+Specify the systems \<timezone\> as the Region/Location that best defines
+your location. For example, specifying US/Pacific sets the time zone to US
+Pacific time.
+
+Command completion can be used to list available time zones. The adjustment
+for daylight time will take place automatically based on the time of year.
+``` \ No newline at end of file
diff --git a/docs/configuration/system/updates.md b/docs/configuration/system/updates.md
new file mode 100644
index 00000000..c82d37be
--- /dev/null
+++ b/docs/configuration/system/updates.md
@@ -0,0 +1,36 @@
+# Updates
+
+VyOS supports online checking for updates
+
+## Configuration
+
+```{cfgcmd} set system update-check auto-check
+
+Configure auto-checking for new images
+```
+
+```{cfgcmd} set system update-check url \<url\>
+
+Configure a URL that contains information about images.
+```
+
+
+## Example
+
+```none
+set system update-check auto-check
+set system update-check url 'https://raw.githubusercontent.com/vyos/vyos-rolling-nightly-builds/main/version.json'
+```
+
+Check:
+
+```none
+vyos@r4:~$ show system updates
+Current version: 1.5-rolling-202312220023
+
+Update available: 1.5-rolling-202312250024
+Update URL: https://github.com/vyos/vyos-rolling-nightly-builds/releases/download/1.5-rolling-202312250024/1.5-rolling-202312250024-amd64.iso
+vyos@r4:~$
+
+vyos@r4:~$ add system image latest
+```
diff --git a/docs/configuration/system/watchdog.md b/docs/configuration/system/watchdog.md
new file mode 100644
index 00000000..700051a6
--- /dev/null
+++ b/docs/configuration/system/watchdog.md
@@ -0,0 +1,212 @@
+(system-watchdog)=
+
+# Watchdog
+
+VyOS supports hardware watchdog timers to automatically reboot the system if
+it becomes unresponsive. This is particularly useful for remote or embedded
+systems where physical access is limited.
+
+A watchdog timer is a hardware or software mechanism that automatically resets
+the system if the operating system stops responding within a configured timeout
+period. The system will periodically notify the watchdog that it is still
+running. If the watchdog is not notified within the timeout period, the watchdog
+will reset the system.
+
+## Configuration
+
+The watchdog feature is configured under the `system watchdog` configuration
+tree. The presence of the `system watchdog` node enables the watchdog feature.
+
+```{cfgcmd} set system watchdog
+
+Enable watchdog support.
+
+The watchdog is enabled only when a watchdog device is available as
+``/dev/watchdog0``.
+
+:::{note}
+If multiple watchdog devices are present, only the first watchdog
+device is supported (VyOS uses ``/dev/watchdog0`` only).
+:::
+If ``/dev/watchdog0`` does not exist and no module is configured, commit will
+fail. If a module is configured but ``/dev/watchdog0`` still cannot be
+created, VyOS will emit a warning and will not enable the systemd watchdog.
+```
+
+```{cfgcmd} set system watchdog module \<module-name\>
+
+Specify the kernel watchdog driver module to load for ``/dev/watchdog0``.
+
+The configured module must be a watchdog driver module, not an arbitrary
+kernel module.
+
+**In most cases, this option is not required** as the kernel will
+automatically load the appropriate watchdog driver for your system. Use this
+option if the kernel fails to load the required driver, or when you want to
+use the software watchdog (``softdog``).
+
+Common modules include:
+* ``softdog`` - Software watchdog timer (available on all systems)
+* ``iTCO_wdt`` - Intel TCO watchdog timer
+* ``sp5100_tco`` - AMD SP5100 TCO watchdog timer
+* ``i6300esb`` - Intel 6300ESB watchdog timer
+* ``ipmi_watchdog`` - IPMI watchdog timer
+
+:::{warning}
+``softdog`` is not a hardware watchdog. It is implemented using
+kernel timers and therefore depends on the Linux kernel continuing to run.
+In some fault conditions (for example, a kernel hang), ``softdog`` may not
+be able to trigger a reset.
+
+Prefer a hardware watchdog driver whenever possible, as hardware watchdogs
+can operate independently of the operating system.
+:::
+
+If no module is specified, VyOS will use an existing ``/dev/watchdog0``
+device if available.
+
+:::{note}
+If a module is specified but a different driver is actually bound
+to ``watchdog0``, VyOS will emit a warning during commit.
+:::
+Example:
+
+:::{code-block} none
+set system watchdog module softdog
+:::
+```
+
+```{cfgcmd} set system watchdog timeout \<seconds\>
+:defaultvalue:
+
+Set the watchdog timeout for normal runtime operation in seconds.
+
+Valid range: 1-65535 seconds
+
+:::{note}
+Some watchdog drivers expose minimum and maximum supported runtime
+timeouts via sysfs. When available, VyOS validates ``timeout`` against
+those driver limits during commit.
+:::
+
+This is the interval during which the system must respond to the watchdog.
+If the system does not respond within this time, the watchdog will trigger
+a reboot.
+
+Example:
+
+:::{code-block} none
+set system watchdog timeout 30
+:::
+```
+
+```{cfgcmd} set system watchdog shutdown-timeout \<seconds\>
+:defaultvalue:
+
+Set the watchdog timeout during system shutdown in seconds.
+
+Valid range: 60-65535 seconds
+
+This extended timeout allows the system to complete a graceful shutdown
+without triggering the watchdog.
+
+:::{warning}
+Setting this value too low (below 120 seconds) may cause
+unclean shutdowns, as the system may not have enough time to properly
+stop all services and flush disk buffers. The recommended minimum value
+is 120 seconds.
+:::
+Example:
+
+:::{code-block} none
+set system watchdog shutdown-timeout 180
+:::
+```
+
+```{cfgcmd} set system watchdog reboot-timeout \<seconds\>
+:defaultvalue:
+
+Set the watchdog timeout during system reboot in seconds.
+
+Valid range: 60-65535 seconds
+
+This extended timeout allows the system to complete the reboot process
+without triggering the watchdog during the transition.
+
+:::{warning}
+Setting this value too low (below 120 seconds) may cause
+unclean reboots, as the system may not have enough time to properly
+stop all services before restarting. The recommended minimum value
+is 120 seconds.
+:::
+Example:
+
+:::{code-block} none
+set system watchdog reboot-timeout 180
+:::
+```
+
+
+## Examples
+
+### Basic Configuration with Software Watchdog
+
+This example configures a basic software watchdog with default timeouts:
+
+```none
+set system watchdog module softdog
+```
+
+This will:
+- Enable the watchdog feature
+- Load the `softdog` kernel module
+- Use a 10-second runtime timeout (default)
+- Use 120-second shutdown and reboot timeouts (default)
+
+### Advanced Configuration
+
+This example shows a more customized configuration suitable for a production
+system:
+
+```none
+set system watchdog module iTCO_wdt
+set system watchdog timeout 30
+set system watchdog shutdown-timeout 300
+set system watchdog reboot-timeout 300
+```
+
+This configuration:
+
+- Enables the watchdog feature
+- Loads the Intel TCO hardware watchdog module
+- Sets a 30-second runtime timeout
+- Allows 5 minutes for shutdown and reboot operations
+
+## Best Practices
+
+- **Start with conservative timeouts**: Use longer timeouts initially and
+ reduce them as you gain confidence in system stability.
+- **Test before deployment**: Verify the watchdog works as expected in a
+ non-production environment before deploying to production systems.
+- **Choose appropriate modules**: Use hardware watchdog modules (like
+ `iTCO_wdt`) when available, as they are more reliable than software
+ watchdogs.
+- **Consider shutdown time**: Set `shutdown-timeout` and `reboot-timeout`
+ values high enough to allow for normal shutdown procedures, especially on
+ systems with many services or slow storage.
+- **Monitor watchdog events**: Check system logs after any unexpected reboots
+ to determine if the watchdog triggered the reboot.
+- **Remote systems**: For systems without physical console access, use
+ conservative timeout values to avoid false-positive reboots during high
+ load conditions.
+
+:::{note}
+The watchdog configuration takes effect immediately after commit,
+but systemd must be reloaded. This happens automatically during commit.
+:::
+
+:::{warning}
+Incorrect watchdog configuration on remote systems can result
+in unexpected reboots. Always test watchdog settings in a controlled
+environment before deploying to production systems.
+:::
diff --git a/docs/configuration/trafficpolicy/index.md b/docs/configuration/trafficpolicy/index.md
new file mode 100644
index 00000000..01a820a9
--- /dev/null
+++ b/docs/configuration/trafficpolicy/index.md
@@ -0,0 +1,1299 @@
+(qos)=
+
+# Traffic Policy
+
+## QoS
+
+The generic name of Quality of Service or Traffic Control involves
+things like shaping traffic, scheduling or dropping packets, which
+are the kind of things you may want to play with when you have, for
+instance, a bandwidth bottleneck in a link and you want to somehow
+prioritize some type of traffic over another.
+
+[tc] is a powerful tool for Traffic Control found at the Linux kernel.
+However, its configuration is often considered a cumbersome task.
+Fortunately, VyOS eases the job through its CLI, while using `tc` as
+backend.
+
+### How to make it work
+
+In order to have VyOS Traffic Control working you need to follow 2
+steps:
+
+> 1. **Create a traffic policy**.
+> 2. **Apply the traffic policy to an interface ingress or egress**.
+
+But before learning to configure your policy, we will warn you
+about the different units you can use and also show you what *classes*
+are and how they work, as some policies may require you to configure
+them.
+
+### Units
+
+When configuring your traffic policy, you will have to set data rate
+values, watch out the units you are managing, it is easy to get confused
+with the different prefixes and suffixes you can use. VyOS will always
+show you the different units you can use.
+
+#### Prefixes
+
+They can be **decimal** prefixes.
+
+```{eval-rst}
+ .. code-block:: none
+
+ kbit (10^3) kilobit per second
+ mbit (10^6) megabit per second
+ gbit (10^9) gigabit per second
+ tbit (10^12) terabit per second
+
+ kbps (8*10^3) kilobyte per second
+ mbps (8*10^6) megabyte per second
+ gbps (8*10^9) gigabyte per second
+ tbps (8*10^12) terabyte per second
+```
+
+Or **binary** prefixes.
+
+```{eval-rst}
+ .. code-block:: none
+
+ kibit (2^10 = 1024) kibibit per second
+ mibit (2^20 = 1024^2) mebibit per second
+ gibit (2^30 = 1024^3) gibibit per second
+ tbit (2^40 = 1024^4) tebibit per second
+
+ kibps (1024*8) kibibyte (KiB) per second
+ mibps (1024^2*8) mebibyte (MiB) per second
+ gibps (1024^3*8) gibibyte (GiB) per second
+ tibps (1024^4*8) tebibyte (TiB) per second
+```
+
+
+#### Suffixes
+
+A *bit* is written as **bit**,
+
+```{eval-rst}
+ .. code-block:: none
+
+ kbit (kilobits per second)
+ mbit (megabits per second)
+ gbit (gigabits per second)
+ tbit (terabits per second)
+```
+
+while a *byte* is written as a single **b**.
+
+```{eval-rst}
+ .. code-block:: none
+
+ kbps (kilobytes per second)
+ mbps (megabytes per second)
+ gbps (gigabytes per second)
+```
+
+(classes)=
+
+### Classes
+
+In the {ref}`creating_a_traffic_policy` section you will see that
+some of the policies use *classes*. Those policies let you distribute
+traffic into different classes according to different parameters you can
+choose. So, a class is just a specific type of traffic you select.
+
+The ultimate goal of classifying traffic is to give each class a
+different treatment.
+
+#### Matching traffic
+
+In order to define which traffic goes into which class, you define
+filters (that is, the matching criteria). Packets go through these matching
+rules (as in the rules of a firewall) and, if a packet matches the filter, it
+is assigned to that class.
+
+In VyOS, a class is identified by a number you can choose when
+configuring it.
+
+:::{note}
+The meaning of the Class ID is not the same for every type of
+policy. Normally policies just need a meaningless number to identify
+a class (Class ID), but that does not apply to every policy.
+The number of a class in a Priority Queue it does not only
+identify it, it also defines its priority.
+:::
+```none
+set qos policy <policy> <policy-name> class <class-ID> match <class-matching-rule-name>
+```
+
+In the command above, we set the type of policy we are going to
+work with and the name we choose for it; a class (so that we can
+differentiate some traffic) and an identifiable number for that class;
+then we configure a matching rule (or filter) and a name for it.
+
+A class can have multiple match filters:
+
+```none
+set qos policy shaper MY-SHAPER class 30 match HTTP
+set qos policy shaper MY-SHAPER class 30 match HTTPs
+```
+
+A match filter can contain multiple criteria and will match traffic if
+all those criteria are true.
+
+For example:
+
+```none
+set qos policy shaper MY-SHAPER class 30 match HTTP ip protocol tcp
+set qos policy shaper MY-SHAPER class 30 match HTTP ip source port 80
+```
+
+This will match TCP traffic with source port 80.
+
+There are many parameters you will be able to use in order to match the
+traffic you want for a class:
+
+> - **Ethernet (protocol, destination address or source address)**
+> - **Interface name**
+> - **IPv4 (DSCP value, maximum packet length, protocol, source address,**
+> **destination address, source port, destination port or TCP flags)**
+> - **IPv6 (DSCP value, maximum payload length, protocol, source address,**
+> **destination address, source port, destination port or TCP flags)**
+> - **Firewall mark**
+> - **VLAN ID**
+
+When configuring your filter, you can use the `Tab` key to see the many
+different parameters you can configure.
+
+```none
+vyos@vyos# set qos policy shaper MY-SHAPER class 30 match MY-FIRST-FILTER
+Possible completions:
+ description Description
+ > ether Ethernet header match
+ interface Interface to use
+ > ip Match IP protocol header
+ > ipv6 Match IPV6 protocol header
+ mark Match on mark applied by firewall
+ vif Virtual Local Area Network (VLAN) ID for this match
+```
+
+As shown in the example above, one of the possibilities to match packets
+is based on marks done by the firewall,
+[that can give you a great deal of flexibility].
+
+You can also write a description for a filter:
+
+```none
+set qos policy shaper MY-SHAPER class 30 match MY-FIRST-FILTER description "My filter description"
+```
+:::{note}
+An IPv4 TCP filter will only match packets with an IPv4 header
+length of 20 bytes (which is the majority of IPv4 packets anyway).
+:::
+
+:::{note}
+IPv6 TCP filters will only match IPv6 packets with no header
+extension, see <https://en.wikipedia.org/wiki/IPv6_packet#Extension_headers>
+:::
+
+#### Traffic Match Group
+
+In some case where we need to have an organization of our matching selection,
+in order to be more flexible and organize with our filter definition. We can
+apply traffic match groups, allowing us to create distinct filter groups within
+our policy and define various parameters for each group:
+
+```none
+set qos traffic-match-group <group_name> match <match_name>
+Possible completions:
+ description Description
+ > ip Match IP protocol header
+ > ipv6 Match IPv6 protocol header
+ mark Match on mark applied by firewall
+ vif Virtual Local Area Network (VLAN) ID for this match
+```
+
+inherit matches from another group
+
+```none
+set qos traffic-match-group <group_name> match-group <match_group_name>
+```
+
+A match group can contain multiple criteria and inherit them in the same policy.
+
+For example:
+
+```none
+set qos traffic-match-group Mission-Critical match AF31 ip dscp 'AF31'
+set qos traffic-match-group Mission-Critical match AF32 ip dscp 'AF42'
+set qos traffic-match-group Mission-Critical match CS3 ip dscp 'CS3'
+set qos traffic-match-group Streaming-Video match AF11 ip dscp 'AF11'
+set qos traffic-match-group Streaming-Video match AF41 ip dscp 'AF41'
+set qos traffic-match-group Streaming-Video match AF43 ip dscp 'AF43'
+set qos policy shaper VyOS-HTB class 10 bandwidth '30%'
+set qos policy shaper VyOS-HTB class 10 description 'Multimedia'
+set qos policy shaper VyOS-HTB class 10 match CS4 ip dscp 'CS4'
+set qos policy shaper VyOS-HTB class 10 match-group 'Streaming-Video'
+set qos policy shaper VyOS-HTB class 10 priority '1'
+set qos policy shaper VyOS-HTB class 10 queue-type 'fair-queue'
+set qos policy shaper VyOS-HTB class 20 description 'MC'
+set qos policy shaper VyOS-HTB class 20 match-group 'Mission-Critical'
+set qos policy shaper VyOS-HTB class 20 priority '2'
+set qos policy shaper VyOS-HTB class 20 queue-type 'fair-queue'
+set qos policy shaper VyOS-HTB default bandwidth '20%'
+set qos policy shaper VyOS-HTB default queue-type 'fq-codel'
+```
+
+In this example, we can observe that different DSCP criteria are defined based
+on our QoS configuration within the same policy group.
+
+#### Default
+
+Often you will also have to configure your *default* traffic in the same
+way you do with a class. *Default* can be considered a class as it
+behaves like that. It contains any traffic that did not match any
+of the defined classes, so it is like an open class, a class without
+matching filters.
+
+#### Class treatment
+
+Once a class has a filter configured, you will also have to define what
+you want to do with the traffic of that class, what specific
+Traffic-Control treatment you want to give it. You will have different
+possibilities depending on the Traffic Policy you are configuring.
+
+```none
+vyos@vyos# set qos policy shaper MY-SHAPER class 30
+Possible completions:
+ bandwidth Available bandwidth for this policy (default: auto)
+ burst Burst size for this class (default: 15k)
+ ceiling Bandwidth limit for this class
+ codel-quantum
+ Deficit in the fair queuing algorithm (default 1514)
+ description Description
+ flows Number of flows into which the incoming packets are classified(default 1024)
+ interval Interval used to measure the delay (default 100)
++> match Class matching rule name
+ priority Priority for rule evaluation
+ queue-limit Maximum queue size
+ queue-type Queue type for default traffic (default: fq-codel)
+ set-dscp Change the Differentiated Services (DiffServ) field in the IP header
+ target Acceptable minimum standing/persistent queue delay (default: 5)
+```
+
+For instance, with {code}`set qos policy shaper MY-SHAPER
+class 30 set-dscp EF` you would be modifying the DSCP field value of packets in
+that class to Expedite Forwarding.
+
+> DSCP values as per {rfc}`2474` and {rfc}`4595`:
+>
+> | Binary value | Configured value | Drop rate | Description |
+> | ------------ | ---------------- | --------- | ---------------------------- |
+> | 101110 | 46 | - | Expedited forwarding (EF) |
+> | 000000 | 0 | - | Best effort traffic, default |
+> | 001010 | 10 | Low | Assured Forwarding(AF) 11 |
+> | 001100 | 12 | Medium | Assured Forwarding(AF) 12 |
+> | 001110 | 14 | High | Assured Forwarding(AF) 13 |
+> | 010010 | 18 | Low | Assured Forwarding(AF) 21 |
+> | 010100 | 20 | Medium | Assured Forwarding(AF) 22 |
+> | 010110 | 22 | High | Assured Forwarding(AF) 23 |
+> | 011010 | 26 | Low | Assured Forwarding(AF) 31 |
+> | 011100 | 28 | Medium | Assured Forwarding(AF) 32 |
+> | 011110 | 30 | High | Assured Forwarding(AF) 33 |
+> | 100010 | 34 | Low | Assured Forwarding(AF) 41 |
+> | 100100 | 36 | Medium | Assured Forwarding(AF) 42 |
+> | 100110 | 38 | High | Assured Forwarding(AF) 43 |
+
+(embed)=
+
+#### Embedding one policy into another one
+
+Often we need to embed one policy into another one. It is possible to do
+so on classful policies, by attaching a new policy into a class. For
+instance, you might want to apply different policies to the different
+classes of a Round-Robin policy you have configured.
+
+A common example is the case of some policies which, in order to be
+effective, they need to be applied to an interface that is directly
+connected where the bottleneck is. If your router is not
+directly connected to the bottleneck, but some hop before it, you can
+emulate the bottleneck by embedding your non-shaping policy into a
+classful shaping one so that it takes effect.
+
+You can configure a policy into a class through the `queue-type`
+setting.
+
+```none
+set qos policy shaper FQ-SHAPER bandwidth 4gbit
+set qos policy shaper FQ-SHAPER default bandwidth 100%
+set qos policy shaper FQ-SHAPER default queue-type fq-codel
+```
+
+As shown in the last command of the example above, the `queue-type`
+setting allows these combinations. You will be able to use it
+in many policies.
+
+:::{note}
+Some policies already include other embedded policies inside.
+That is the case of Shaper: each of its classes use fair-queue
+unless you change it.
+:::
+
+(creating_a_traffic_policy)=
+
+### Creating a traffic policy
+
+VyOS lets you control traffic in many different ways, here we will cover
+every possibility. You can configure as many policies as you want, but
+you will only be able to apply one policy per interface and direction
+(inbound or outbound).
+
+Some policies can be combined, you will be able to embed a different
+policy that will be applied to a class of the main policy.
+
+:::{hint}
+**If you are looking for a policy for your outbound traffic**
+but you don't know which one you need and you don't want to go
+through every possible policy shown here, **our bet is that highly
+likely you are looking for a** Shaper **policy and you want to**
+{ref}`set its queues <embed>` **as FQ-CoDel**.
+:::
+
+#### Drop Tail
+
+```{eval-rst}
+| **Queueing discipline:** PFIFO (Packet First In First Out).
+| **Applies to:** Outbound traffic.
+```
+
+This the simplest queue possible you can apply to your traffic. Traffic
+must go through a finite queue before it is actually sent. You must
+define how many packets that queue can contain.
+
+When a packet is to be sent, it will have to go through that queue, so
+the packet will be placed at the tail of it. When the packet completely
+goes through it, it will be dequeued emptying its place in the queue and
+being eventually handed to the NIC to be actually sent out.
+
+Despite the Drop-Tail policy does not slow down packets, if many packets
+are to be sent, they could get dropped when trying to get enqueued at
+the tail. This can happen if the queue has still not been able to
+release enough packets from its head.
+
+This is the policy that requires the lowest resources for the same
+amount of traffic. But **very likely you do not need it as you cannot
+get much from it. Sometimes it is used just to enable logging.**
+
+```{cfgcmd} set qos policy drop-tail \<policy-name\> queue-limit \<number-of-packets\>
+
+Use this command to configure a drop-tail policy (PFIFO). Choose a
+unique name for this policy and the size of the queue by setting the
+number of packets it can contain (maximum 4294967295).
+
+```
+
+#### Fair Queue
+
+```{eval-rst}
+| **Queueing discipline:** SFQ (Stochastic Fairness Queuing).
+| **Applies to:** Outbound traffic.
+```
+
+Fair Queue is a work-conserving scheduler which schedules the
+transmission of packets based on flows, that is, it balances traffic
+distributing it through different sub-queues in order to ensure
+fairness so that each flow is able to send data in turn, preventing any
+single one from drowning out the rest.
+
+```{cfgcmd} set qos policy fair-queue \<policy-name\>
+
+ Use this command to create a Fair-Queue policy and give it a name.
+ It is based on the Stochastic Fairness Queueing and can be applied to
+ outbound traffic.
+
+```
+
+In order to separate traffic, Fair Queue uses a classifier based on
+source address, destination address and source port. The algorithm
+enqueues packets to hash buckets based on those tree parameters.
+Each of these buckets should represent a unique flow. Because multiple
+flows may get hashed to the same bucket, the hashing algorithm is
+perturbed at configurable intervals so that the unfairness lasts only
+for a short while. Perturbation may however cause some inadvertent
+packet reordering to occur. An advisable value could be 10 seconds.
+
+
+One of the uses of Fair Queue might be the mitigation of Denial of
+Service attacks.
+
+```{cfgcmd} set qos policy fair-queue \<policy-name\> hash-interval \<seconds\>
+
+Use this command to define a Fair-Queue policy, based on the
+Stochastic Fairness Queueing, and set the number of seconds at which
+a new queue algorithm perturbation will occur (maximum 4294967295).
+```
+
+When dequeuing, each hash-bucket with data is queried in a round robin
+fashion. You can configure the length of the queue.
+
+```{cfgcmd} set qos policy fair-queue \<policy-name\> queue-limit \<limit\>
+
+Use this command to define a Fair-Queue policy, based on the
+Stochastic Fairness Queueing, and set the number of maximum packets
+allowed to wait in the queue. Any other packet will be dropped.
+```
+:::{note}
+Fair Queue is a non-shaping (work-conserving) policy, so it
+will only be useful if your outgoing interface is really full. If it
+is not, VyOS will not own the queue and Fair Queue will have no
+effect. If there is bandwidth available on the physical link, you can
+embed Fair-Queue into a classful shaping policy to make sure it owns
+the queue.
+:::
+
+
+(fq-codel)=
+
+
+#### FQ-CoDel
+
+
+```{eval-rst}
+| **Queueing discipline:** Fair/Flow Queue CoDel.
+| **Applies to:** Outbound Traffic.
+```
+
+
+The FQ-CoDel policy distributes the traffic into 1024 FIFO queues and
+tries to provide good service between all of them. It also tries to keep
+the length of all the queues short.
+
+
+FQ-CoDel fights bufferbloat and reduces latency without the need of
+complex configurations. It has become the new default Queueing
+Discipline for the interfaces of some GNU/Linux distributions.
+
+
+It uses a stochastic model to classify incoming packets into
+different flows and is used to provide a fair share of the bandwidth to
+all the flows using the queue. Each flow is managed by the CoDel
+queuing discipline. Reordering within a flow is avoided since Codel
+internally uses a FIFO queue.
+
+
+FQ-CoDel is based on a modified Deficit Round Robin (DRR) queue
+scheduler with the CoDel Active Queue Management (AQM) algorithm
+operating on each queue.
+
+
+:::{note}
+FQ-Codel is a non-shaping (work-conserving) policy, so it
+will only be useful if your outgoing interface is really full. If it
+is not, VyOS will not own the queue and FQ-Codel will have no
+effect. If there is bandwidth available on the physical link, you can
+embed FQ-Codel into a classful shaping policy to make sure it owns
+the queue. If you are not sure if you need to embed your FQ-CoDel
+policy into a Shaper, do it.
+:::
+
+
+FQ-CoDel is tuned to run ok with its default parameters at 10Gbit
+speeds. It might work ok too at other speeds without configuring
+anything, but here we will explain some cases when you might want to
+tune its parameters.
+
+
+When running it at 1Gbit and lower, you may want to reduce the
+`queue-limit` to 1000 packets or less. In rates like 10Mbit, you may
+want to set it to 600 packets.
+
+
+If you are using FQ-CoDel embedded into Shaper and you have large rates
+(100Mbit and above), you may consider increasing `quantum` to 8000 or
+higher so that the scheduler saves CPU.
+
+
+On low rates (below 40Mbit) you may want to tune `quantum` down to
+something like 300 bytes.
+
+
+At very low rates (below 3Mbit), besides tuning `quantum` (300 keeps
+being ok) you may also want to increase `target` to something like 15ms
+and increase `interval` to something around 150 ms.
+
+```{cfgcmd} set qos policy fq-codel \<policy name\> codel-quantum \<bytes\>
+
+Use this command to configure an fq-codel policy, set its name and
+the maximum number of bytes (default: 1514) to be dequeued from a
+queue at once.
+```
+
+```{cfgcmd} set qos policy fq-codel \<policy name\> flows \<number-of-flows\>
+
+Use this command to configure an fq-codel policy, set its name and
+the number of sub-queues (default: 1024) into which packets are
+classified.
+```
+
+```{cfgcmd} set qos policy fq-codel \<policy name\> interval \<milliseconds\>
+
+Use this command to configure an fq-codel policy, set its name and
+the time period used by the control loop of CoDel to detect when a
+persistent queue is developing, ensuring that the measured minimum
+delay does not become too stale (default: 100ms).
+```
+
+```{cfgcmd} set qos policy fq-codel \<policy-name\> queue-limit \<number-of-packets\>
+
+Use this command to configure an fq-codel policy, set its name, and
+define a hard limit on the real queue size. When this limit is
+reached, new packets are dropped (default: 10240 packets).
+```
+
+```{cfgcmd} set qos policy fq-codel \<policy-name\> target \<milliseconds\>
+
+Use this command to configure an fq-codel policy, set its name, and
+define the acceptable minimum standing/persistent queue delay. This
+minimum delay is identified by tracking the local minimum queue delay
+that packets experience (default: 5ms).
+```
+
+##### Example
+
+A simple example of an FQ-CoDel policy working inside a Shaper one.
+
+```none
+set qos policy shaper FQ-CODEL-SHAPER bandwidth 2gbit
+set qos policy shaper FQ-CODEL-SHAPER default bandwidth 100%
+set qos policy shaper FQ-CODEL-SHAPER default queue-type fq-codel
+```
+
+#### Limiter
+
+```{eval-rst}
+| **Queueing discipline:** Ingress policer.
+| **Applies to:** Inbound traffic.
+```
+
+Limiter is one of those policies that uses classes (Ingress qdisc is
+actually a classless policy but filters do work in it).
+
+The limiter performs basic ingress policing of traffic flows. Multiple
+classes of traffic can be defined and traffic limits can be applied to
+each class. Although the policer uses a token bucket mechanism
+internally, it does not have the capability to delay a packet as a
+shaping mechanism does. Traffic exceeding the defined bandwidth limits
+is directly dropped. A maximum allowed burst can be configured too.
+
+You can configure classes (up to 4090) with different settings and a
+default policy which will be applied to any traffic not matching any of
+the configured classes.
+
+:::{note}
+In the case you want to apply some kind of **shaping** to your
+**inbound** traffic, check the ingress-shaping section.
+:::
+```{cfgcmd} set qos policy limiter \<policy-name\> class \<class ID\> match \<match-name\> description \<description\>
+
+Use this command to configure an Ingress Policer, defining its name,
+a class identifier (1-4090), a class matching rule name and its
+description.
+
+```
+
+Once the matching rules are set for a class, you can start configuring
+how you want matching traffic to behave.
+
+```{cfgcmd} set qos policy limiter \<policy-name\> class \<class-ID\> bandwidth \<rate\>
+
+Use this command to configure an Ingress Policer, defining its name,
+a class identifier (1-4090) and the maximum allowed bandwidth for
+this class.
+
+```
+
+```{cfgcmd} set qos policy limiter \<policy-name\> class \<class-ID\> burst \<burst-size\>
+
+Use this command to configure an Ingress Policer, defining its name,
+a class identifier (1-4090) and the burst size in bytes for this
+class (default: 15).
+
+```
+
+```{cfgcmd} set qos policy limiter \<policy-name\> default bandwidth \<rate\>
+
+Use this command to configure an Ingress Policer, defining its name
+and the maximum allowed bandwidth for its default policy.
+
+```
+
+```{cfgcmd} set qos policy limiter \<policy-name\> default burst \<burst-size\>
+
+Use this command to configure an Ingress Policer, defining its name
+and the burst size in bytes (default: 15) for its default policy.
+
+```
+
+```{cfgcmd} set qos policy limiter \<policy-name\> class \<class ID\> priority \<value\>
+
+Use this command to configure an Ingress Policer, defining its name,
+a class identifier (1-4090), and the priority (0-20, default 20) in
+which the rule is evaluated (the lower the number, the higher the
+priority).
+
+```
+
+#### Network Emulator
+
+```{eval-rst}
+| **Queueing discipline:** netem (Network Emulator) + TBF (Token Bucket Filter).
+| **Applies to:** Outbound traffic.
+```
+
+VyOS Network Emulator policy emulates the conditions you can suffer in a
+real network. You will be able to configure things like rate, burst,
+delay, packet loss, packet corruption or packet reordering.
+
+This could be helpful if you want to test how an application behaves
+under certain network conditions.
+
+```{cfgcmd} set qos policy network-emulator \<policy-name\> bandwidth \<rate\>
+
+ Use this command to configure the maximum rate at which traffic will
+ be shaped in a Network Emulator policy. Define the name of the policy
+ and the rate.
+
+```
+
+```{cfgcmd} set qos policy network-emulator \<policy-name\> burst \<burst-size\>
+
+Use this command to configure the burst size of the traffic in a
+Network Emulator policy. Define the name of the Network Emulator
+policy and its traffic burst size (it will be configured through the
+Token Bucket Filter qdisc). Default:15kb. It will only take effect if
+you have configured its bandwidth too.
+```
+
+```{cfgcmd} set qos policy network-emulator \<policy-name\> delay \<delay\>
+
+Use this command to configure a Network Emulator policy defining its
+name and the fixed amount of time you want to add to all packet going
+out of the interface. The latency will be added through the
+Token Bucket Filter qdisc. It will only take effect if you have
+configured its bandwidth too. You can use secs, ms and us. Default:
+50ms.
+```
+
+```{cfgcmd} set qos policy network-emulator \<policy-name\> corruption \<percent\>
+
+Use this command to emulate noise in a Network Emulator policy. Set
+the policy name and the percentage of corrupted packets you want. A
+random error will be introduced in a random position for the chosen
+percent of packets.
+```
+
+```{cfgcmd} set qos policy network-emulator \<policy-name\> loss \<percent\>
+
+Use this command to emulate packet-loss conditions in a Network
+Emulator policy. Set the policy name and the percentage of loss
+packets your traffic will suffer.
+```
+
+```{cfgcmd} set traffic-policy network-emulator \<policy-name\> reordering \<percent\>
+
+Use this command to emulate packet-reordering conditions in a Network
+Emulator policy. Set the policy name and the percentage of reordered
+packets your traffic will suffer.
+```
+
+```{cfgcmd} set traffic-policy network-emulator \<policy-name\> queue-limit \<limit\>
+
+Use this command to define the length of the queue of your Network
+Emulator policy. Set the policy name and the maximum number of
+packets (1-4294967295) the queue may hold queued at a time.
+```
+
+#### Priority Queue
+
+```{eval-rst}
+| **Queueing discipline:** PRIO.
+| **Applies to:** Outbound traffic.
+```
+
+The Priority Queue is a classful scheduling policy. It does not delay
+packets (Priority Queue is not a shaping policy), it simply dequeues
+packets according to their priority.
+
+:::{note}
+Priority Queue, as other non-shaping policies, is only useful
+if your outgoing interface is really full. If it is not, VyOS will
+not own the queue and Priority Queue will have no effect. If there is
+bandwidth available on the physical link, you can embed Priority
+Queue into a classful shaping policy to make sure it owns the queue.
+In that case packets can be prioritized based on DSCP.
+:::
+
+Up to seven queues -defined as classes with different priorities- can
+be configured. Packets are placed into queues based on associated match
+criteria. Packets are transmitted from the queues in priority order. If
+classes with a higher priority are being filled with packets
+continuously, packets from lower priority classes will only be
+transmitted after traffic volume from higher priority classes decreases.
+
+:::{note}
+In Priority Queue we do not define classes with a meaningless
+class ID number but with a class priority number (1-7). The lower the
+number, the higher the priority.
+:::
+
+As with other policies, you can define different type of matching rules
+for your classes:
+
+```none
+vyos@vyos# set qos policy priority-queue MY-PRIO class 3 match MY-MATCH-RULE
+Possible completions:
+ description Description
+ > ether Ethernet header match
+ interface Interface to use
+ > ip Match IP protocol header
+ > ipv6 Match IPV6 protocol header
+ mark Match on mark applied by firewall
+ vif Virtual Local Area Network (VLAN) ID for this match
+```
+
+As with other policies, you can embed other policies into the classes
+(and default) of your Priority Queue policy through the `queue-type`
+setting:
+
+```none
+vyos@vyos# set qos policy priority-queue MY-PRIO class 3 queue-type
+Possible completions:
+ drop-tail First-In-First-Out (FIFO) (default)
+ fq-codel Fair Queue Codel
+ fair-queue Stochastic Fair Queue (SFQ)
+ priority Priority queueing
+ random-detect
+ Random Early Detection (RED)
+```
+
+```{cfgcmd} set qos policy priority-queue \<policy-name\> class \<class-ID\> queue-limit \<limit\>
+
+Use this command to configure a Priority Queue policy, set its name,
+set a class with a priority from 1 to 7 and define a hard limit on
+the real queue size. When this limit is reached, new packets are
+dropped.
+
+```
+
+(random-detect)=
+
+#### Random-Detect
+
+```{eval-rst}
+| **Queueing discipline:** Generalized Random Early Drop.
+| **Applies to:** Outbound traffic.
+```
+
+A simple Random Early Detection (RED) policy would start randomly
+dropping packets from a queue before it reaches its queue limit thus
+avoiding congestion. That is good for TCP connections as the gradual
+dropping of packets acts as a signal for the sender to decrease its
+transmission rate.
+
+In contrast to simple RED, VyOS' Random-Detect uses a Generalized Random
+Early Detect policy that provides different virtual queues based on the
+IP Precedence value so that some virtual queues can drop more packets
+than others.
+
+This is achieved by using the first three bits of the ToS (Type of
+Service) field to categorize data streams and, in accordance with the
+defined precedence parameters, a decision is made.
+
+IP precedence as defined in {rfc}`791`:
+> | Precedence | Priority |
+> | ---------- | -------------------- |
+> | 7 | Network Control |
+> | 6 | Internetwork Control |
+> | 5 | CRITIC/ECP |
+> | 4 | Flash Override |
+> | 3 | Flash |
+> | 2 | Immediate |
+> | 1 | Priority |
+> | 0 | Routine |
+Random-Detect could be useful for heavy traffic. One use of this
+algorithm might be to prevent a backbone overload. But only for TCP
+(because dropped packets could be retransmitted), not for UDP.
+
+```{cfgcmd} set qos policy random-detect \<policy-name\> bandwidth \<bandwidth\>
+
+ Use this command to configure a Random-Detect policy, set its name
+ and set the available bandwidth for this policy. It is used for
+ calculating the average queue size after some idle time. It should be
+ set to the bandwidth of your interface. Random Detect is not a
+ shaping policy, this command will not shape.
+
+```
+
+```{cfgcmd} set qos policy random-detect \<policy-name\> precedence \<IP-precedence-value\> average-packet \<bytes\>
+
+Use this command to configure a Random-Detect policy and set its
+name, then state the IP Precedence for the virtual queue you are
+configuring and what the size of its average-packet should be
+(in bytes, default: 1024).
+```
+:::{note}
+When configuring a Random-Detect policy: **the higher the
+precedence number, the higher the priority**.
+:::
+```{cfgcmd} set qos policy random-detect \<policy-name\> precedence \<IP-precedence-value\> mark-probability \<value\>
+
+Use this command to configure a Random-Detect policy and set its
+name, then state the IP Precedence for the virtual queue you are
+configuring and what its mark (drop) probability will be. Set the
+probability by giving the N value of the fraction 1/N (default: 10).
+```
+
+```{cfgcmd} set qos policy random-detect \<policy-name\> precedence \<IP-precedence-value\> maximum-threshold \<packets\>
+
+Use this command to configure a Random-Detect policy and set its
+name, then state the IP Precedence for the virtual queue you are
+configuring and what its maximum threshold for random detection will
+be (from 0 to 4096 packets, default: 18). At this size, the marking
+(drop) probability is maximal.
+
+```
+
+```{cfgcmd} set qos policy random-detect \<policy-name\> precedence \<IP-precedence-value\> minimum-threshold \<packets\>
+
+Use this command to configure a Random-Detect policy and set its
+name, then state the IP Precedence for the virtual queue you are
+configuring and what its minimum threshold for random detection will
+be (from 0 to 4096 packets). If this value is exceeded, packets
+start being eligible for being dropped.
+```
+
+The default values for the minimum-threshold depend on IP precedence:
+> | Precedence | default min-threshold |
+> | ---------- | --------------------- |
+> | 7 | 16 |
+> | 6 | 15 |
+> | 5 | 14 |
+> | 4 | 13 |
+> | 3 | 12 |
+> | 2 | 11 |
+> | 1 | 10 |
+> | 0 | 9 |
+
+```{cfgcmd} set qos policy random-detect \<policy-name\> precedence \<IP-precedence-value\> queue-limit \<packets\>
+
+Use this command to configure a Random-Detect policy and set its
+name, then name the IP Precedence for the virtual queue you are
+configuring and what the maximum size of its queue will be (from 1 to
+1-4294967295 packets). Packets are dropped when the current queue
+length reaches this value.
+
+```
+
+If the average queue size is lower than the **min-threshold**, an
+arriving packet will be placed in the queue.
+
+In the case the average queue size is between **min-threshold** and
+**max-threshold**, then an arriving packet would be either dropped or
+placed in the queue, it will depend on the defined **mark-probability**.
+
+If the current queue size is larger than **queue-limit**,
+then packets will be dropped. The average queue size depends on its
+former average size and its current one.
+
+If **max-threshold** is set but **min-threshold is not, then
+\*\*min-threshold** is scaled to 50% of **max-threshold**.
+
+In principle, values must be
+{code}`min-threshold` < {code}`max-threshold` < {code}`queue-limit`.
+
+#### Rate Control
+
+```{eval-rst}
+| **Queueing discipline:** Token Bucket Filter.
+| **Applies to:** Outbound traffic.
+```
+
+Rate-Control is a classless policy that limits the packet flow to a set
+rate. It is a pure shaper, it does not schedule traffic. Traffic is
+filtered based on the expenditure of tokens. Tokens roughly correspond
+to bytes.
+
+Short bursts can be allowed to exceed the limit. On creation, the
+Rate-Control traffic is stocked with tokens which correspond to the
+amount of traffic that can be burst in one go. Tokens arrive at a steady
+rate, until the bucket is full.
+
+```{cfgcmd} set qos policy rate-control \<policy-name\> bandwidth \<rate\>
+
+ Use this command to configure a Rate-Control policy, set its name
+ and the rate limit you want to have.
+
+```
+
+```{cfgcmd} set qos policy rate-control \<policy-name\> burst \<burst-size\>
+
+Use this command to configure a Rate-Control policy, set its name
+and the size of the bucket in bytes which will be available for
+burst.
+```
+
+As a reference: for 10mbit/s on Intel, you might need at least 10kbyte
+buffer if you want to reach your configured rate.
+
+A very small buffer will soon start dropping packets.
+
+```{cfgcmd} set qos policy rate-control \<policy-name\> latency
+
+Use this command to configure a Rate-Control policy, set its name
+and the maximum amount of time a packet can be queued (default: 50
+ms).
+
+```
+
+Rate-Control is a CPU-friendly policy. You might consider using it when
+you just simply want to slow traffic down.
+(drr)=
+
+#### Round Robin
+
+**Queueing discipline:**
+ Deficit Round Robin.
+**Applies to:**
+ Outbound traffic.
+
+The round-robin policy is a classful scheduler that divides traffic in
+different classes you can configure (up to 4096). You can embed a
+new policy into each of those classes (default included).
+
+Each class is assigned a deficit counter (the number of bytes that a
+flow is allowed to transmit when it is its turn) initialized to quantum.
+Quantum is a parameter you configure which acts like a credit of fix
+bytes the counter receives on each round. Then the Round-Robin policy
+starts moving its Round Robin pointer through the queues. If the deficit
+counter is greater than the packet's size at the head of the queue, this
+packet will be sent and the value of the counter will be decremented by
+the packet size. Then, the size of the next packet will be compared to
+the counter value again, repeating the process. Once the queue is empty
+or the value of the counter is insufficient, the Round-Robin pointer
+will move to the next queue. If the queue is empty, the value of the
+deficit counter is reset to 0.
+
+At every round, the deficit counter adds the quantum so that even large
+packets will have their opportunity to be dequeued.
+
+```{cfgcmd} set qos policy round-robin \<policy name\> class \<class-ID\> quantum \<packets\>
+
+Use this command to configure a Round-Robin policy, set its name, set
+a class ID, and the quantum for that class. The deficit counter will
+add that value each round.
+
+```
+
+```{cfgcmd} set qos policy round-robin \<policy name\> class <class ID> queue-limit \<packets\>
+
+Use this command to configure a Round-Robin policy, set its name, set
+a class ID, and the queue size in packets.
+```
+
+As with other policies, Round-Robin can embed another policy into a
+class through the `queue-type` setting.
+
+```none
+vyos@vyos# set qos policy round-robin DRR class 10 queue-type
+Possible completions:
+ drop-tail First-In-First-Out (FIFO) (default)
+ fq-codel Fair Queue Codel
+ fair-queue Stochastic Fair Queue (SFQ)
+ priority Priority queueing based
+ random-detect
+ Random Early Detection (RED)
+```
+
+(shaper)=
+
+
+#### Shaper
+
+
+```{eval-rst}
+| **Queueing discipline:** Hierarchical Token Bucket.
+| **Applies to:** Outbound traffic.
+```
+
+
+The Shaper policy does not guarantee a low delay, but it does guarantee
+bandwidth to different traffic classes and also lets you decide how to
+allocate more traffic once the guarantees are met.
+
+
+Each class can have a guaranteed part of the total bandwidth defined for
+the whole policy, so all those shares together should not be higher
+than the policy's whole bandwidth.
+
+
+If guaranteed traffic for a class is met and there is room for more
+traffic, the ceiling parameter can be used to set how much more
+bandwidth could be used. If guaranteed traffic is met and there are
+several classes willing to use their ceilings, the priority parameter
+will establish the order in which that additional traffic will be
+allocated. Priority can be any number from 0 to 7. The lower the number,
+the higher the priority.
+
+```{cfgcmd} set qos policy shaper \<policy-name\> bandwidth \<rate\>
+
+Use this command to configure a Shaper policy, set its name
+and the maximum bandwidth for all combined traffic.
+```
+
+```{cfgcmd} set qos policy shaper \<policy-name\> class \<class-ID\> bandwidth \<rate\>
+
+Use this command to configure a Shaper policy, set its name, define
+a class and set the guaranteed traffic you want to allocate to that
+class.
+
+```
+
+```{cfgcmd} set qos policy shaper \<policy-name\> class \<class-ID\> burst \<bytes\>
+
+Use this command to configure a Shaper policy, set its name, define
+a class and set the size of the tocken bucket in bytes, which will
+be available to be sent at ceiling speed (default: 15Kb).
+```
+
+```{cfgcmd} set qos policy shaper \<policy-name\> class \<class-ID\> ceiling \<bandwidth\>
+
+Use this command to configure a Shaper policy, set its name, define
+a class and set the maximum speed possible for this class. The
+default ceiling value is the bandwidth value.
+```
+
+```{cfgcmd} set qos policy shaper \<policy-name\> class \<class-ID\> priority \<0-7\>
+
+Use this command to configure a Shaper policy, set its name, define
+a class and set the priority for usage of available bandwidth once
+guarantees have been met. The lower the priority number, the higher
+the priority. The default priority value is 0, the highest priority.
+```
+
+As with other policies, Shaper can embed other policies into its
+classes through the `queue-type` setting and then configure their
+parameters.
+
+```none
+vyos@vyos# set qos policy shaper HTB class 10 queue-type
+Possible completions:
+ fq-codel Fair Queue Codel (default)
+ fair-queue Stochastic Fair Queue (SFQ)
+ drop-tail First-In-First-Out (FIFO)
+ priority Priority queueing
+ random-detect
+ Random Early Detection (RED)
+```
+
+```none
+vyos@vyos# set qos policy shaper HTB class 10
+Possible completions:
+ bandwidth Available bandwidth for this policy (default: auto)
+ burst Burst size for this class (default: 15k)
+ ceiling Bandwidth limit for this class
+ codel-quantum
+ Deficit in the fair queuing algorithm (default 1514)
+ description Description
+ flows Number of flows into which the incoming packets are classified (default 1024)
+ interval Interval used to measure the delay (default 100)
++> match Class matching rule name
+ priority Priority for rule evaluation
+ queue-limit Maximum queue size (packets)
+ queue-type Queue type for default traffic (default: fq-codel)
+ set-dscp Change the Differentiated Services (DiffServ) field in the IP header
+ target Acceptable minimum standing/persistent queue delay (default: 5)
+```
+:::{note}
+If you configure a class for **VoIP traffic**, don't give it any
+*ceiling*, otherwise new VoIP calls could start when the link is
+available and get suddenly dropped when other classes start using
+their assigned *bandwidth* share.
+:::
+
+(traffic-policy-shaper-example)=
+
+##### Example
+
+A simple example of Shaper using priorities.
+
+```none
+set qos policy shaper MY-HTB bandwidth '50mbit'
+set qos policy shaper MY-HTB class 10 bandwidth '20%'
+set qos policy shaper MY-HTB class 10 match DSCP ip dscp 'EF'
+set qos policy shaper MY-HTB class 10 queue-type 'fq-codel'
+set qos policy shaper MY-HTB class 20 bandwidth '10%'
+set qos policy shaper MY-HTB class 20 ceiling '50%'
+set qos policy shaper MY-HTB class 20 match PORT666 ip destination port '666'
+set qos policy shaper MY-HTB class 20 priority '3'
+set qos policy shaper MY-HTB class 20 queue-type 'fair-queue'
+set qos policy shaper MY-HTB class 30 bandwidth '10%'
+set qos policy shaper MY-HTB class 30 ceiling '50%'
+set qos policy shaper MY-HTB class 30 match ADDRESS30 ip source address '192.168.30.0/24'
+set qos policy shaper MY-HTB class 30 priority '5'
+set qos policy shaper MY-HTB class 30 queue-type 'fair-queue'
+set qos policy shaper MY-HTB default bandwidth '10%'
+set qos policy shaper MY-HTB default ceiling '100%'
+set qos policy shaper MY-HTB default priority '7'
+set qos policy shaper MY-HTB default queue-type 'fair-queue'
+```
+
+(cake)=
+
+#### CAKE
+
+```{eval-rst}
+| **Queueing discipline:** Deficit mode.
+| **Applies to:** Outbound traffic.
+```
+
+Common Applications Kept Enhanced (CAKE) is a comprehensive queue management
+system, implemented as a queue discipline (qdisc) for the Linux kernel. It is
+designed to replace and improve upon the complex hierarchy of simple qdiscs
+presently required to effectively tackle the bufferbloat problem at the network
+edge.
+
+```{cfgcmd} set qos policy cake \<text\> bandwidth \<value\>
+
+ Set the shaper bandwidth, either as an explicit bitrate or a percentage
+ of the interface bandwidth.
+
+```
+
+```{cfgcmd} set qos policy cake \<text\> description
+
+Set a description for the shaper.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation blind
+
+Disables flow isolation, all traffic passes through a single queue.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation dst-host
+
+Flows are defined only by destination address.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation dual-dst-host
+
+Flows are defined by the 5-tuple. Fairness is applied first over destination
+addresses, then over individual flows.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation dual-src-host
+
+Flows are defined by the 5-tuple. Fairness is applied first over source
+addresses, then over individual flows.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation flow
+
+Flows are defined by the entire 5-tuple (source IP address, source port,
+destination IP address, destination port, transport protocol).
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation host
+
+Flows are defined by source-destination host pairs.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation nat
+
+Perform NAT lookup before applying flow-isolation rules.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation src-host
+
+Flows are defined only by source address.
+```
+
+```{cfgcmd} set qos policy cake \<text\> flow-isolation triple-isolate
+
+**(Default)** Flows are defined by the 5-tuple, fairness is applied
+over source and destination addresses and also over individual flows.
+```
+
+```{cfgcmd} set qos policy cake \<text\> rtt
+
+Defines the round-trip time used for active queue management (AQM) in
+milliseconds. The default value is 100.
+```
+
+### Applying a traffic policy
+
+Once a traffic-policy is created, you can apply it to an interface:
+
+```none
+set qos interface eth0 egress WAN-OUT
+```
+
+You can only apply one policy per interface and direction, but you could
+reuse a policy on different interfaces and directions:
+
+```none
+set qos interface eth0 ingress WAN-IN
+set qos interface eth0 egress WAN-OUT
+set qos interface eth1 ingress LAN-IN
+set qos interface eth1 egress LAN-OUT
+set qos interface eth2 ingress LAN-IN
+set qos interface eth2 egress LAN-OUT
+set qos interface eth3 ingress TWO-WAY-POLICY
+set qos interface eth3 egress TWO-WAY-POLICY
+set qos interface eth4 ingress TWO-WAY-POLICY
+set qos interface eth4 egress TWO-WAY-POLICY
+```
+
+(ingress-shaping)=
+
+### The case of ingress shaping
+
+**Applies to:**
+ Inbound traffic.
+
+For the ingress traffic of an interface, there is only one policy you
+can directly apply, a **Limiter** policy. You cannot apply a shaping
+policy directly to the ingress traffic of any interface because shaping
+only works for outbound traffic.
+
+This workaround lets you apply a shaping policy to the ingress traffic
+by first redirecting it to an in-between virtual interface
+([Intermediate Functional Block]). There, in that virtual interface,
+you will be able to apply any of the policies that work for outbound
+traffic, for instance, a shaping one.
+
+That is how it is possible to do the so-called "ingress shaping".
+
+```none
+set qos policy shaper MY-INGRESS-SHAPING bandwidth 1000kbit
+set qos policy shaper MY-INGRESS-SHAPING default bandwidth 1000kbit
+set qos policy shaper MY-INGRESS-SHAPING default queue-type fair-queue
+
+set qos interface ifb0 egress MY-INGRESS-SHAPING
+set interfaces ethernet eth0 redirect ifb0
+
+set interfaces input ifb0
+```
+
+:::{warning}
+Do not configure IFB as the first step. First create everything else
+of your traffic-policy, and then you can configure IFB.
+Otherwise you might get the `RTNETLINK answer: File exists` error,
+which can be solved with `sudo ip link delete ifb0`.
+:::
+
+[common applications kept enhanced]: https://www.bufferbloat.net/projects/codel/wiki/Cake/
+[hfsc]: <https://en.wikipedia.org/wiki/Hierarchical_fair-service_curve>
+[intermediate functional block]: https://www.linuxfoundation.org/collaborate/workgroups/networking/ifb
+[tc]: <https://en.wikipedia.org/wiki/Tc_(Linux)>
+[that can give you a great deal of flexibility]: https://blog.vyos.io/using-the-policy-route-and-packet-marking-for-custom-qos-matches
+[tocken bucket]: <https://en.wikipedia.org/wiki/Token_bucket>
diff --git a/docs/configuration/vpn/dmvpn.md b/docs/configuration/vpn/dmvpn.md
new file mode 100644
index 00000000..4dc2c85f
--- /dev/null
+++ b/docs/configuration/vpn/dmvpn.md
@@ -0,0 +1,431 @@
+(vpn-dmvpn)=
+
+# DMVPN
+
+{abbr}`DMVPN (Dynamic Multipoint Virtual Private Network)` is a dynamic
+{abbr}`VPN (Virtual Private Network)` technology originally developed by Cisco.
+While their implementation was somewhat proprietary, the underlying
+technologies are actually standards based. The three technologies are:
+
+- {abbr}`NHRP (Next Hop Resolution Protocol)` {rfc}`2332`
+- {abbr}`mGRE (Multipoint Generic Routing Encapsulation)` {rfc}`1702`
+- {abbr}`IPSec (IP Security)` - too many RFCs to list, but start with
+ {rfc}`4301`
+
+NHRP provides the dynamic tunnel endpoint discovery mechanism (endpoint
+registration, and endpoint discovery/lookup), mGRE provides the tunnel
+encapsulation itself, and the IPSec protocols handle the key exchange, and
+crypto mechanism.
+
+In short, DMVPN provides the capability for creating a dynamic-mesh VPN
+network without having to pre-configure (static) all possible tunnel end-point
+peers.
+
+:::{note}
+DMVPN only automates the tunnel endpoint discovery and setup. A
+complete solution also incorporates the use of a routing protocol. BGP is
+particularly well suited for use with DMVPN.
+:::
+
+:::{figure} /_static/images/vpn_dmvpn_topology01.webp
+:alt: Baseline DMVPN topology
+:scale: 40 %
+Baseline DMVPN topology
+:::
+
+## Configuration
+
+### Tunnel interface configuration
+
+NHRP never handles routing of prefixes itself. You need to run some real routing
+protocol (e.g. BGP) to advertise routes over the tunnels. What nhrpd does it
+establishes ‘shortcut routes’ that optimizes the routing protocol to avoid going
+through extra nodes in NBMA GRE mesh.
+
+NHRP does route NHRP domain addresses individually using per-host prefixes.
+This is similar to Cisco FlexVPN, but in contrast to opennhrp which uses
+a generic subnet route.
+
+To create NBMA GRE tunnel you might use the following:
+
+```none
+set interfaces tunnel tun100 address '10.0.0.1/32'
+set interfaces tunnel tun100 enable-multicast
+set interfaces tunnel tun100 encapsulation 'gre'
+set interfaces tunnel tun100 ip adjust-mss '1360'
+set interfaces tunnel tun100 mtu '1400'
+set interfaces tunnel tun100 parameters ip key '42'
+set interfaces tunnel tun100 source-interface 'eth0'
+```
+
+- Please refer to the {ref}`tunnel-interface` documentation for the individual
+ tunnel related options.
+
+ :::{note}
+ The IP-address is assigned as host prefix to tunnel interface.
+ NHRP will automatically create additional host routes pointing to tunnel interface
+ when a connection with these hosts is established.
+ :::
+
+The tunnel interface subnet prefix should be announced by routing protocol
+from the hub nodes (e.g. BGP ‘network’ announce). This allows the routing
+protocol to decide which is the closest hub and determine the relay hub on
+prefix basis when direct tunnel is not established.
+
+### NHRP protocol configuration
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> authentication \<secret\>
+
+Enables Cisco style authentication on NHRP packets. This embeds the
+plaintext password to the outgoing NHRP packets. Maximum length of
+the password is 8 characters.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> holdtime \<timeout\>
+
+Holdtime is the number of seconds that have to pass before stopping to
+advertise an NHRP NBMA address as valid. It also controls how often NHRP
+registration requests are sent. By default registrations are sent every
+one third of the holdtime
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> map tunnel-ip \<tunnel-ip\> nbma \<nbma-ip\>
+
+* **tunnel-ip** - Tunnel ip address in format **x.x.x.x**.
+* **nbma-ip** - NBMA ip address in format **x.x.x.x** or **local**
+
+Map an IP address of a station to the station’s NBMA address.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> mtu \<mtu\>
+
+Configure NHRP advertised MTU.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> multicast \<nbma-ip\>
+
+* **nbma-ip** - NBMA ip address in format **x.x.x.x** or **dynamic**
+
+Sends multicast packets to the specified NBMA address. If dynamic is specified
+then destination NBMA address (or addresses) are learnt dynamically.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> network-id \<network-id\>
+
+* **network-id** - NHRP network id <1-4294967295>
+
+Enable NHRP on this interface and set the interface’s network ID. The network ID
+is used to allow creating multiple nhrp domains on a router when multiple interfaces
+are configured on the router. Interfaces configured with the same ID are part of the
+same logical NBMA network. The ID is a local only parameter and is not sent to other
+NHRP nodes and so IDs on different nodes do not need to match. When NHRP packets are
+received on an interface they are assigned to the local NHRP domain for that interface.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> nhs tunnel-ip \<tunnel-ip\> nbma \<nbma-ip\>
+
+* **tunnel-ip** - Tunnel ip address in format **x.x.x.x** or **dynamic**
+* **nbma-ip** - NBMA ip address in format **x.x.x.x**
+
+Configure the Next Hop Server address and its NBMA address. If dynamic is specified
+then Next Hop Server can have dynamic address which maps to its NBMA address.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> redirect
+
+This enable redirect replies on the NHS similar to ICMP redirects except this is
+managed by the nhrp protocol. This setting allows spokes to communicate with each
+others directly.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> registration-no-unique
+
+Allow the client to not set the unique flag in the NHRP packets. This is useful when
+a station has a dynamic IP address that could change over time.
+```
+
+```{cfgcmd} set protocols nhrp tunnel \<tunnel\> shortcut
+
+Enable shortcut (spoke-to-spoke) tunnels to allow NHC to talk to each others directly
+after establishing a connection without going through the hub.
+```
+
+
+### IPSEC configuration
+
+- Please refer to the {ref}`ipsec_general` documentation for the individual IPSec
+ related options.
+
+:::{note}
+NHRP daemon based on FRR nhrpd. It controls IPSEC. That's why 'close-action'
+parameter in IKE configuration always is set to 'close' and 'dead-peer-detection action'
+always is set to 'clear'.
+:::
+
+```{cfgcmd} set vpn ipsec profile \<profile-name\> authentication mode pre-shared-secret
+
+Set preshared secret mode authentication
+```
+
+```{cfgcmd} set vpn ipsec profile \<profile-name\> authentication pre-shared-secret \<secret\>
+
+Set preshared secret
+```
+
+```{cfgcmd} set vpn ipsec profile \<profile-name\> bind tunnel \<tunnel name\>
+
+Bind IPSEC profile to the specific tunnel interface.
+```
+
+```{cfgcmd} set vpn ipsec profile \<profile-name\> esp-group 'ESP-HUB'
+
+Map ESP group to IPSEC profile
+```
+
+```{cfgcmd} set vpn ipsec profile \<profile-name\> ike-group 'IKE-HUB'
+
+Map IKE group to IPSEC profile
+```
+
+
+## Monitoring
+
+```{opcmd} show ip nhrp cache
+
+Forwarding cache information.
+```
+
+```{opcmd} show ip nhrp nhs
+
+Next hop server information.
+```
+
+```{opcmd} show ip nhrp shortcut
+
+Shortcut information.
+```
+
+
+## Example
+
+This blueprint uses VyOS as the DMVPN Hub and Cisco IOSv 15.5(3)M and VyOS as
+multiple spoke sites.
+
+:::{figure} /_static/images/blueprint-dmvpn.webp
+:align: center
+:alt: DMVPN Network Topology Diagram
+:width: 70%
+DMVPN Network Topology Diagram
+:::
+
+Each node (Hub and Spoke) uses an IP address from the network 10.0.0.0/24.
+
+The below referenced IP address `192.168.0.2` is used as example address
+representing a global unicast address under which the HUB can be contacted by
+each and every individual spoke.
+(dmvpn-example-configuration)=
+
+### Configuration
+
+#### Hub
+
+##### VyOS-HUB-1
+
+```none
+set interfaces ethernet eth0 address '192.168.0.2/30'
+
+set interfaces tunnel tun100 address '10.0.0.100/32'
+set interfaces tunnel tun100 enable-multicast
+set interfaces tunnel tun100 encapsulation 'gre'
+set interfaces tunnel tun100 parameters ip key '42'
+set interfaces tunnel tun100 source-interface 'eth0'
+
+set protocols nhrp tunnel tun100 authentication 'test123'
+set protocols nhrp tunnel tun100 holdtime '300'
+set protocols nhrp tunnel tun100 multicast 'dynamic'
+set protocols nhrp tunnel tun100 network-id '1'
+set protocols nhrp tunnel tun100 redirect
+set protocols nhrp tunnel tun100 registration-no-unique
+
+set protocols static route 0.0.0.0/0 next-hop 192.168.0.1
+
+set vpn ipsec esp-group ESP-HUB lifetime '1800'
+set vpn ipsec esp-group ESP-HUB mode 'transport'
+set vpn ipsec esp-group ESP-HUB pfs 'dh-group2'
+set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
+set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
+set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-HUB lifetime '3600'
+set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
+set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
+set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
+set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
+set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
+set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
+set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
+```
+
+:::{note}
+Setting this up on AWS will require a "Custom Protocol Rule" for
+protocol number "47" (GRE) Allow Rule in TWO places. Firstly on the VPC
+Network ACL, and secondly on the security group network ACL attached to the
+EC2 instance. This has been tested as working for the official AMI image on
+the AWS Marketplace. (Locate the correct VPC and security group by navigating
+through the details pane below your EC2 instance in the AWS console).
+:::
+
+#### Spokes
+
+> The individual spoke configurations only differ in interface IP addresses.
+
+##### VyOS-Spoke-1 and VyOS-Spoke-2
+
+```none
+set interfaces ethernet eth0 address '192.168.1.2/30'
+
+set interfaces tunnel tun100 address '10.0.0.1/32'
+set interfaces tunnel tun100 enable-multicast
+set interfaces tunnel tun100 encapsulation 'gre'
+set interfaces tunnel tun100 parameters ip key '42'
+set interfaces tunnel tun100 source-interface 'eth0'
+
+set protocols nhrp tunnel tun100 authentication 'test123'
+set protocols nhrp tunnel tun100 holdtime '300'
+set protocols nhrp tunnel tun100 multicast 'dynamic'
+set protocols nhrp tunnel tun100 network-id '1'
+set protocols nhrp tunnel tun100 nhs tunnel-ip dynamic nbma '192.168.0.2'
+set protocols nhrp tunnel tun100 registration-no-unique
+set protocols nhrp tunnel tun100 shortcut
+
+set protocols static route 0.0.0.0/0 next-hop 192.168.1.1
+set protocols static route 10.0.0.0/24 next-hop 10.0.0.100
+
+set vpn ipsec esp-group ESP-HUB lifetime '1800'
+set vpn ipsec esp-group ESP-HUB mode 'transport'
+set vpn ipsec esp-group ESP-HUB pfs 'dh-group2'
+set vpn ipsec esp-group ESP-HUB proposal 1 encryption 'aes256'
+set vpn ipsec esp-group ESP-HUB proposal 1 hash 'sha1'
+set vpn ipsec ike-group IKE-HUB key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-HUB lifetime '3600'
+set vpn ipsec ike-group IKE-HUB proposal 1 dh-group '2'
+set vpn ipsec ike-group IKE-HUB proposal 1 encryption 'aes256'
+set vpn ipsec ike-group IKE-HUB proposal 1 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec profile NHRPVPN authentication mode 'pre-shared-secret'
+set vpn ipsec profile NHRPVPN authentication pre-shared-secret 'secret'
+set vpn ipsec profile NHRPVPN bind tunnel 'tun100'
+set vpn ipsec profile NHRPVPN esp-group 'ESP-HUB'
+set vpn ipsec profile NHRPVPN ike-group 'IKE-HUB'
+```
+
+
+##### Cisco-Spoke-3
+
+```none
+crypto isakmp policy 10
+ encr aes 256
+ authentication pre-share
+ group 2
+ lifetime 3600
+crypto isakmp key secret address 0.0.0.0
+!
+!
+crypto ipsec transform-set DMVPNESP esp-aes 256 esp-sha-hmac
+ mode transport
+!
+crypto ipsec profile DMVPNPROFILE
+ set security-association lifetime seconds 1800
+ set transform-set DMVPNESP
+ set pfs group2
+!
+!
+!
+!
+!
+!
+!
+interface Tunnel100
+ ip address 10.0.0.3 255.255.255.0
+ no ip redirects
+ ip nhrp authentication test123
+ ip nhrp map multicast dynamic
+ ip nhrp network-id 1
+ ip nhrp holdtime 300
+ ip nhrp nhs 10.0.0.100 nbma 192.168.0.2
+ ip nhrp registration no-unique
+ ip nhrp redirect
+tunnel source GigabitEthernet0/0
+ tunnel mode gre multipoint
+ tunnel key 42
+ tunnel protection ipsec profile DMVPNPROFILE
+!
+interface GigabitEthernet0/0
+ ip address 192.168.3.2 255.255.255.252
+ duplex auto
+ speed auto
+ media-type rj45
+!
+ip route 0.0.0.0 0.0.0.0 192.168.3.1
+```
+
+
+##### Monitoring DMVPN Network
+
+Let send ICMP packets from VyOS-SPOKE-1 to Cisco-SPOKE-3
+
+```none
+vyos@vyos:~$ ping 10.0.0.3
+PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
+64 bytes from 10.0.0.3: icmp_seq=1 ttl=255 time=3.44 ms
+64 bytes from 10.0.0.3: icmp_seq=2 ttl=255 time=3.07 ms
+^C
+--- 10.0.0.3 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 3.072/3.257/3.442/0.185 ms
+```
+
+
+##### Monitoring on HUB
+
+```none
+vyos@vyos:~$ show ip nhrp cache
+Iface Type Protocol NBMA Claimed NBMA Flags Identity
+tun100 dynamic 10.0.0.1 192.168.1.2 192.168.1.2 T 192.168.1.2
+tun100 dynamic 10.0.0.3 192.168.3.2 192.168.3.2 T 192.168.3.2
+tun100 dynamic 10.0.0.2 192.168.2.2 192.168.2.2 T 192.168.2.2
+tun100 local 10.0.0.100 192.168.0.2 192.168.0.2 -
+
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------------------- ------- -------- -------------- ---------------- ---------------- ----------- ----------------------------------
+dmvpn-NHRPVPN-tun100-child up 3m46s 230B/270B 2/2 192.168.1.2 192.168.1.2 AES_CBC_256/HMAC_SHA1_96/MODP_1024
+dmvpn-NHRPVPN-tun100-child up 5m48s 460B/540B 4/4 192.168.2.2 192.168.2.2 AES_CBC_256/HMAC_SHA1_96/MODP_1024
+dmvpn-NHRPVPN-tun100-child up 16m26s 1K/1K 13/12 192.168.3.2 192.168.3.2 AES_CBC_256/HMAC_SHA1_96/MODP_1024
+```
+
+
+##### Monitoring on Spokes
+
+```none
+vyos@vyos:~$ show ip nhrp cache
+Iface Type Protocol NBMA Claimed NBMA Flags Identity
+tun100 local 10.0.0.1 192.168.1.2 192.168.1.2 -
+tun100 dynamic 10.0.0.3 192.168.3.2 192.168.3.2 T 192.168.3.2
+tun100 nhs 10.0.0.100 192.168.0.2 192.168.0.2 T 192.168.0.2
+
+vyos@vyos:~$ show ip nhrp nhs
+Iface FQDN NBMA Protocol
+tun100 192.168.0.2 192.168.0.2 10.0.0.100
+
+vyos@vyos:~$ show ip nhrp shortcut
+Type Prefix Via Identity
+dynamic 10.0.0.3/32 10.0.0.3 192.168.3.2
+
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------------------- ------- -------- -------------- ---------------- ---------------- ----------- ----------------------------------
+dmvpn-NHRPVPN-tun100-child up 6m43s 898B/695B 7/6 192.168.0.2 192.168.0.2 AES_CBC_256/HMAC_SHA1_96/MODP_1024
+dmvpn-NHRPVPN-tun100-child up 49s 215B/187B 2/2 192.168.3.2 192.168.3.2 AES_CBC_256/HMAC_SHA1_96/MODP_1024
+```
diff --git a/docs/configuration/vpn/index.md b/docs/configuration/vpn/index.md
new file mode 100644
index 00000000..9b06e5df
--- /dev/null
+++ b/docs/configuration/vpn/index.md
@@ -0,0 +1,14 @@
+# VPN
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+ipsec/index
+l2tp
+openconnect
+pptp
+rsa-keys
+sstp
+dmvpn
+```
diff --git a/docs/configuration/vpn/ipsec/index.md b/docs/configuration/vpn/ipsec/index.md
new file mode 100644
index 00000000..cc40b6f8
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/index.md
@@ -0,0 +1,11 @@
+# IPsec
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+ipsec_general
+site2site_ipsec
+remoteaccess_ipsec
+troubleshooting_ipsec
+```
diff --git a/docs/configuration/vpn/ipsec/ipsec_general.md b/docs/configuration/vpn/ipsec/ipsec_general.md
new file mode 100644
index 00000000..6fc47386
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/ipsec_general.md
@@ -0,0 +1,407 @@
+(ipsec_general)=
+
+# IPsec General Information
+
+## Information about IPsec
+
+IPsec is the framework used to secure data.
+IPsec accomplishes these goals by providing authentication,
+encryption of IP network packets, key exchange, and key management.
+VyOS uses Strongswan package to implement IPsec.
+
+**Authentication Header (AH)** is defined in {rfc}`4302`. It creates
+a hash using the IP header and data payload, and prepends it to the
+packet. This hash is used to validate that the data has not been
+changed during transfer over the network.
+
+**Encapsulating Security Payload (ESP)** is defined in {rfc}`4303`.
+It provides encryption and authentication of the data.
+
+```{eval-rst}
+There are two IPsec modes:
+ **IPsec Transport Mode**:
+ In transport mode, an IPSec header (AH or ESP) is inserted
+ between the IP header and the upper layer protocol header.
+
+ **IPsec Tunnel Mode:**
+ In tunnel mode, the original IP packet is encapsulated in
+ another IP datagram, and an IPsec header (AH or ESP) is
+ inserted between the outer and inner headers.
+
+.. figure:: /_static/images/ESP_AH.webp
+ :scale: 80 %
+ :alt: AH and ESP in Transport Mode and Tunnel Mode
+```
+
+## IKE (Internet Key Exchange)
+
+The default IPsec method for secure key negotiation is the Internet Key
+Exchange (IKE) protocol. IKE is designed to provide mutual authentication
+of systems, as well as to establish a shared secret key to create IPsec
+security associations. A security association (SA) includes all relevant
+attributes of the connection, including the cryptographic algorithm used,
+the IPsec mode, the encryption key, and other parameters related to the
+transmission of data over the VPN connection.
+
+### IKEv1
+
+IKEv1 is the older version and is still used today. Nowadays, most
+manufacturers recommend using IKEv2 protocol.
+
+IKEv1 is described in the next RFCs: {rfc}`2409` (IKE), {rfc}`3407`
+(IPsec DOI), {rfc}`3947` (NAT-T), {rfc}`3948` (UDP Encapsulation
+of ESP Packets), {rfc}`3706` (DPD)
+
+```{eval-rst}
+IKEv1 operates in two phases to establish these IKE and IPsec SAs:
+ * **Phase 1** provides mutual authentication of the IKE peers and
+ establishment of the session key. This phase creates an IKE SA (a
+ security association for IKE) using a DH exchange, cookies, and an
+ ID exchange. Once an IKE SA is established, all IKE communication
+ between the initiator and responder is protected with encryption
+ and an integrity check that is authenticated. The purpose of IKE
+ phase 1 is to facilitate a secure channel between the peers so that
+ phase 2 negotiations can occur securely. IKE phase 1 offers two modes:
+ Main and Aggressive.
+
+ * **Main Mode** is used for site-to-site VPN connections.
+
+ * **Aggressive Mode** is used for remote access VPN connections.
+
+ * **Phase 2** provides for the negotiation and establishment of the
+ IPsec SAs using ESP or AH to protect IP data traffic.
+```
+
+### IKEv2
+
+IKEv2 is described in {rfc}`7296`. The biggest difference between IKEv1 and
+IKEv2 is that IKEv2 is much simpler and more reliable than IKEv1 because
+fewer messages are exchanged during the establishment of the VPN and
+additional security capabilities are available.
+
+### IKE Authentication
+
+```{eval-rst}
+VyOS supports 3 authentication methods.
+ * **Pre-shared keys**: In this method, both peers of the IPsec
+ tunnel must have the same preshared keys.
+ * **Digital certificates**: PKI is used in this method.
+ * **RSA-keys**: If the RSA-keys method is used in your IKE policy,
+ you need to make sure each peer has the other peer’s public keys.
+```
+
+## DPD (Dead Peer Detection)
+
+This is a mechanism used to detect when a VPN peer is no longer active.
+This mechanism has different algorithms in IKEv1 and IKEv2 in VyOS.
+DPD Requests are sent as ISAKMP R-U-THERE messages and DPD Responses
+are sent as ISAKMP R-U-THERE-ACK messages. In IKEv1, DPD sends messages
+every configured interval. The remote peer is considered unreachable
+if no response to these packets is received within the DPD timeout.
+In IKEv2, DPD sends messages every configured interval. If one request
+is not responded, Strongswan execute its retransmission algorithm with
+its timers. [IKEv2 Retransmission](#ikev2-retransmission)
+
+## Post-Quantum Preshared Keys (PPK)
+
+Post-Quantum Preshared Keys help provide some quantum resistance to IPSec
+tunnels when a post-quantum key exchange algorithm such as ML-KEM is not
+available. The use of PPKs in IKEv2 is described in {rfc}`8784`.
+
+```{eval-rst}
+.. cfgmod:: edit vpn authentication ppk <name>
+```
+
+PPKs can be configued within VyOS under the `vpn ipsec authentication ppk`
+config.
+
+```{eval-rst}
+.. cfgmod:: set vpn authentication ppk <name> secret-type <plaintext|hex|base64>
+```
+
+PPKs need an id and a secret value. The ID and the secret must match if PPKs are
+required for a successful IPsec connection. The secret can be plain text, a
+hex value, or a Base64 value. The default is plain text. If using another
+type of value, you must define the secret type.
+
+```{eval-rst}
+.. cfgmod:: set vpn ipsec site-to-site <name> ppk id <id>
+```
+
+To use a PPK within a site-to-site or remote access connection, define the PPK
+id under the connection.
+
+```{eval-rst}
+.. cfgmod:: set vpn ipsec site-to-site <name> ppk required
+```
+
+Optionally, you can require the use of PPK to have a successful connection.
+
+```{eval-rst}
+.. cfgmod:: show vpn ipsec connections
+```
+
+You can view the PPK column for information on if PPK is configured, and
+if it is in use. The output is in the format of `<configured> / <in use>`.
+The options for configured are none if not conifugred, opt if configured
+but optional, and req is configured and required. The in use will show yes
+Possible values of the `configured` field are `none` if not
+conifgured, `opt` if configured but optional, and `req` is
+configured and required. The in use will show yes
+
+## Configuration IKE
+
+```{eval-rst}
+IKE (Internet Key Exchange) Attributes
+======================================
+
+VyOS IKE group has the next options:
+
+.. cfgcmd:: set vpn ipsec ike-group <name> close-action <action>
+
+ Defines the action to take if the remote peer unexpectedly
+ closes a CHILD_SA:
+
+ * **none** - Set action to none (default),
+ * **trap** - Installs a trap policy (IPsec policy without Security
+ Association) for the CHILD_SA and traffic matching these policies
+ will trigger acquire events that cause the daemon to establish the
+ required IKE/IPsec SAs.
+ * **start** - Tries to immediately re-create the CHILD_SA.
+
+.. cfgcmd:: set vpn ipsec ike-group <name> ikev2-reauth
+
+ Whether rekeying of an IKE_SA should also reauthenticate
+ the peer. In IKEv1, reauthentication is always done.
+ Setting this parameter enables remote host re-authentication
+ during an IKE rekey.
+
+.. cfgcmd:: set vpn ipsec ike-group <name> key-exchange
+
+ Which protocol should be used to initialize the connection
+ If not set both protocols are handled and connections will
+ use IKEv2 when initiating, but accept any protocol version
+ when responding:
+
+ * **ikev1** - Use IKEv1 for Key Exchange.
+ * **ikev2** - Use IKEv2 for Key Exchange.
+
+.. cfgcmd:: set vpn ipsec ike-group <name> lifetime
+
+ IKE lifetime in seconds <0-86400> (default 28800).
+
+.. cfgcmd:: set vpn ipsec ike-group <name> mode
+
+ IKEv1 Phase 1 Mode Selection:
+
+ * **main** - Use Main mode for Key Exchanges in the IKEv1 Protocol
+ (Recommended Default).
+ * **aggressive** - Use Aggressive mode for Key Exchanges in the IKEv1
+ protocol aggressive mode is much more insecure compared to Main mode.
+
+.. stop_vyoslinter
+
+.. cfgcmd:: set vpn ipsec ike-group <name> proposal <number> dh-group <dh-group number>
+
+ Dh-group. Default value is **2**.
+
+.. cfgcmd:: set vpn ipsec ike-group <name> proposal <number> encryption <encryption>
+
+ Encryption algorithm. Default value is **aes128**.
+
+.. start_vyoslinter
+
+.. cfgcmd:: set vpn ipsec ike-group <name> proposal <number> hash <hash>
+
+ Hash algorithm. Default value is **sha1**.
+
+.. cfgcmd:: set vpn ipsec ike-group <name> proposal <number> prf <prf>
+
+ Pseudo-random function.
+
+
+DPD (Dead Peer Detection) Configuration
+=======================================
+
+.. cfgcmd:: set vpn ipsec ike-group <name> dead-peer-detection action <action>
+
+ Action to perform for this CHILD_SA on DPD timeout.
+
+ * **trap** - Installs a trap policy (IPsec policy without Security
+ Association), which will catch matching traffic and tries to
+ re-negotiate the tunnel on-demand.
+ * **clear** - Closes the CHILD_SA and does not take further action
+ (default).
+ * **restart** - Immediately tries to re-negotiate the CHILD_SA
+ under a fresh IKE_SA.
+
+.. stop_vyoslinter
+
+.. cfgcmd:: set vpn ipsec ike-group <name> dead-peer-detection interval <interval>
+
+ Keep-alive interval in seconds <2-86400> (default 30).
+
+.. start_vyoslinter
+
+.. cfgcmd:: set vpn ipsec ike-group <name> dead-peer-detection timeout <timeout>
+
+ Keep-alive timeout in seconds <2-86400> (default 120) **IKEv1 only**
+
+ESP (Encapsulating Security Payload) Attributes
+===============================================
+
+In VyOS, ESP attributes are specified through ESP groups.
+Multiple proposals can be specified in a single group.
+
+VyOS ESP group has the next options:
+
+.. cfgcmd:: set vpn ipsec esp-group <name> compression
+
+ Enables the IPComp(IP Payload Compression) protocol which allows
+ compressing the content of IP packets.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> disable-rekey
+
+ Do not locally initiate a re-key of the SA, remote peer must
+ re-key before expiration.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> life-bytes <bytes>
+
+ ESP life in bytes <1024-26843545600000>. Number of bytes
+ transmitted over an IPsec SA before it expires.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> life-packets <packets>
+
+ ESP life in packets <1000-26843545600000>.
+ Number of packets transmitted over an IPsec SA before it expires.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> lifetime <timeout>
+
+ ESP lifetime in seconds <30-86400> (default 3600).
+ How long a particular instance of a connection (a set of
+ encryption/authentication keys for user packets) should last,
+ from successful negotiation to expiry.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> mode <mode>
+
+ The type of the connection:
+
+ * **tunnel** - Tunnel mode (default).
+ * **transport** - Transport mode.
+
+.. cfgcmd:: set vpn ipsec esp-group <name> pfs < dh-group>
+
+ Whether Perfect Forward Secrecy of keys is desired on the
+ connection's keying channel and defines a Diffie-Hellman group for
+ PFS:
+
+ * **enable** - Inherit Diffie-Hellman group from IKE group (default).
+ * **disable** - Disable PFS.
+ * **<dh-group>** - Defines a Diffie-Hellman group for PFS.
+
+.. stop_vyoslinter
+
+.. cfgcmd:: set vpn ipsec esp-group <name> proposal <number> encryption <encryption>
+
+ Encryption algorithm. Default value is **aes128**.
+
+.. start_vyoslinter
+
+.. cfgcmd:: set vpn ipsec esp-group <name> proposal <number> hash <hash>
+
+ Hash algorithm. Default value is **sha1**.
+
+Global IPsec Settings
+=====================
+
+.. cfgcmd:: set vpn ipsec interface <name>
+
+ Interface name to restrict outbound IPsec policies. There is a possibility
+ to specify multiple interfaces. If an interfaces are not specified, IPsec
+ policies apply to all interfaces.
+
+
+.. cfgcmd:: set vpn ipsec log level <number>
+
+ Level of logging. Default value is **0**.
+
+.. cfgcmd:: set vpn ipsec log subsystem <name>
+
+ Subsystem of the daemon.
+
+Options
+=======
+
+.. cfgcmd:: set vpn ipsec options disable-route-autoinstall
+
+ Do not automatically install routes to remote
+ networks.
+
+.. cfgcmd:: set vpn ipsec options flexvpn
+
+ Allows FlexVPN vendor ID payload (IKEv2 only). Send the Cisco
+ FlexVPN vendor ID payload (IKEv2 only), which is required in order to make
+ Cisco brand devices allow negotiating a local traffic selector (from
+ strongSwan's point of view) that is not the assigned virtual IP address if
+ such an address is requested by strongSwan. Sending the Cisco FlexVPN
+ vendor ID prevents the peer from narrowing the initiator's local traffic
+ selector and allows it to e.g. negotiate a TS of 0.0.0.0/0 == 0.0.0.0/0
+ instead. This has been tested with a "tunnel mode ipsec ipv4" Cisco
+ template but should also work for GRE encapsulation.
+
+.. cfgcmd:: set vpn ipsec options interface <name>
+
+ Interface Name to use. The name of the interface on which
+ virtual IP addresses should be installed. If not specified the addresses
+ will be installed on the outbound interface.
+
+.. cfgcmd:: set vpn ipsec options virtual-ip
+
+ Allows the installation of virtual-ip addresses.
+```
+
+### IKEv2 Retransmission
+
+If the peer does not respond on DPD packet, the router starts retransmission procedure.
+
+The following formula is used to calculate the timeout:
+
+```none
+relative timeout = timeout * base ^ (attempts-1)
+```
+
+```{cfgcmd} set vpn ipsec options retransmission attempts
+
+Number of attempts before the peer is considered to be in the down state.
+Default value is **5**.
+```
+
+```{cfgcmd} set vpn ipsec options retransmission base
+
+Base number of exponential backoff. Default value is **1.8**.
+```
+
+```{cfgcmd} set vpn ipsec options retransmission timeout
+
+Timeout in seconds before the first retransmission. Default value is **4**.
+```
+
+Using the default values, packets are retransmitted as follows:
+
+```{eval-rst}
++-----------+-------------+------------------+------------------+
+| Attempts | Formula | Relative timeout | Absolute timeout |
++-----------+-------------+------------------+------------------+
+| 1 | 4 * 1.8 ^ 0 | 4s | 4s |
++-----------+-------------+------------------+------------------+
+| 2 | 4 * 1.8 ^ 1 | 7s | 11s |
++-----------+-------------+------------------+------------------+
+| 3 | 4 * 1.8 ^ 2 | 13s | 24s |
++-----------+-------------+------------------+------------------+
+| 4 | 4 * 1.8 ^ 3 | 23s | 47s |
++-----------+-------------+------------------+------------------+
+| 5 | 4 * 1.8 ^ 4 | 42s | 89s |
++-----------+-------------+------------------+------------------+
+| peer down | 4 * 1.8 ^ 5 | 76s | 165s |
++-----------+-------------+------------------+------------------+
+```
diff --git a/docs/configuration/vpn/ipsec/remoteaccess_ipsec.md b/docs/configuration/vpn/ipsec/remoteaccess_ipsec.md
new file mode 100644
index 00000000..6931e00b
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/remoteaccess_ipsec.md
@@ -0,0 +1,186 @@
+(remoteaccess-ipsec)=
+
+# IPSec IKEv2 Remote Access VPN
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+Internet Key Exchange version 2 (IKEv2) is a tunneling protocol, based on IPsec,
+that establishes a secure VPN communication between VPN devices, and defines
+negotiation and authentication processes for IPsec security associations (SAs).
+It is often known as IKEv2/IPSec or IPSec IKEv2 remote-access — or road-warriors
+as others call it.
+
+Key exchange and payload encryption is done using IKE and ESP proposals as known
+from IKEv1 but the connections are faster to establish, more reliable, and also
+support roaming from IP to IP (called MOBIKE which makes sure your connection
+does not drop when changing networks from e.g. WIFI to LTE and back).
+Authentication can be achieved with X.509 certificates.
+
+## Setting up certificates:
+
+First of all, we need to create a CA root certificate and server certificate
+on the server side.
+
+```none
+vyos@vpn.vyos.net# run generate pki ca install ca_root
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io)
+Enter how many days certificate will be valid: (Default: 1825)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] N
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+
+
+vyos@vpn.vyos.net# comp
+[pki ca]
++ ca_root {
++ certificate "MIIDnTCCAoWgAwI…."
++ private {
++ key "MIIEvAIBADANBgkqhkiG9….”
+
+vyos@vpn.vyos.net# run generate pki certificate sign ca_root install server_cert
+Do you already have a certificate request? [y/N] N
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB)
+Enter state: (Default: Some-State)
+Enter locality: (Default: Some-City)
+Enter organization name: (Default: VyOS)
+Enter common name: (Default: vyos.io) vpn.vyos.net
+Do you want to configure Subject Alternative Names? [y/N] N
+Enter how many days certificate will be valid: (Default: 365)
+Enter certificate type: (client, server) (Default: server)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] N
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+
+vyos@vpn.vyos.net# comp
+[pki certificate]
++ server_cert {
++ certificate "MIIDuzCCAqOgAwIBAgIUaSrCPWx………"
++ private {
++ key "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBK….."
++ }
++ }
+```
+
+Once the command is completed, it will add the certificate to the configuration
+session, to the pki subtree. You can then review the proposed changes and
+commit them.
+
+## Setting up IPSec:
+
+After the PKI certs are all set up we can start configuring our IPSec/IKE
+proposals used for key-exchange end data encryption. The used encryption ciphers
+and integrity algorithms vary from operating system to operating system. The
+ones used in this example are validated to work on Windows 10.
+
+```none
+set vpn ipsec esp-group ESP-RW lifetime '3600'
+set vpn ipsec esp-group ESP-RW pfs 'disable'
+set vpn ipsec esp-group ESP-RW proposal 10 encryption 'aes128gcm128'
+set vpn ipsec esp-group ESP-RW proposal 10 hash 'sha256'
+
+set vpn ipsec ike-group IKE-RW key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-RW lifetime '7200'
+set vpn ipsec ike-group IKE-RW proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-RW proposal 10 encryption 'aes128gcm128'
+set vpn ipsec ike-group IKE-RW proposal 10 hash 'sha256'
+```
+
+Every connection/remote-access pool we configure also needs a pool where we
+can draw our client IP addresses from. We provide one IPv4 and IPv6 pool.
+Authorized clients will receive an IPv4 address from the configured IPv4 prefix
+and an IPv6 address from the IPv6 prefix. We can also send some DNS nameservers
+down to our clients used on their connection.
+
+```none
+set vpn ipsec remote-access pool ra-rw-ipv4 name-server '192.0.2.1'
+set vpn ipsec remote-access pool ra-rw-ipv4 prefix '192.0.2.128/25'
+
+set vpn ipsec remote-access pool ra-rw-ipv6 name-server '2001:db8:1000::1'
+set vpn ipsec remote-access pool ra-rw-ipv6 prefix '2001:db8:2000::/64'
+```
+
+
+## Setting up tunnel:
+
+```none
+set vpn ipsec remote-access connection rw authentication local-id '192.0.2.1'
+set vpn ipsec remote-access connection rw authentication server-mode 'x509'
+set vpn ipsec remote-access connection rw authentication x509 ca-certificate 'ca_root'
+set vpn ipsec remote-access connection rw authentication x509 certificate 'server_cert'
+set vpn ipsec remote-access connection rw esp-group 'ESP-RW'
+set vpn ipsec remote-access connection rw ike-group 'IKE-RW'
+set vpn ipsec remote-access connection rw local-address '192.0.2.1'
+set vpn ipsec remote-access connection rw pool 'ra-rw-ipv4'
+set vpn ipsec remote-access connection rw pool 'ra-rw-ipv6'
+```
+
+VyOS also supports two different modes of authentication, local and RADIUS.
+To create a new local user named "vyos" with a password of "vyos" use the
+following commands.
+
+```none
+set vpn ipsec remote-access connection rw authentication client-mode 'eap-mschapv2'
+set vpn ipsec remote-access connection rw authentication local-users username vyos password 'vyos'
+```
+
+Some client operating systems like to see the servers certificate. The following
+option causes the server to voluntarily send its certificate, even if it wasn't
+requested.
+
+```none
+set vpn ipsec remote-access connection rw authentication always-send-cert
+```
+
+
+## Client Configuration
+
+Most operating systems include native client support for IPsec IKEv2 VPN
+connections, and others typically have an app or add-on package which adds the
+capability.
+This section covers IPsec IKEv2 client configuration for Windows 10.
+
+VyOS provides a command to generate a connection profile used by Windows clients
+that will connect to the "rw" connection on our VyOS server.
+
+:::{note}
+Windows expects the server name to be also used in the server's
+certificate common name, so it's best to use this DNS name for your VPN
+connection.
+:::
+
+```none
+vyos@vpn.vyos.net:~$ generate ipsec profile windows-remote-access rw remote vpn.vyos.net
+
+
+==== <snip> ====
+Add-VpnConnection -Name "VyOS IKEv2 VPN" -ServerAddress "vpn.vyos.net" -TunnelType "Ikev2"
+
+Set-VpnConnectionIPsecConfiguration -ConnectionName "VyOS IKEv2 VPN" -AuthenticationTransformConstants GCMAES128 -CipherTransformConstants
+GCMAES128 -EncryptionMethod GCMAES128 -IntegrityCheckMethod SHA256128 -PfsGroup None -DHGroup "Group14" -PassThru -Force
+==== </snip> ====
+```
+
+Add the commands from Snippet in the Windows side via PowerShell.
+Also import the root CA cert to the Windows “Trusted Root Certification
+Authorities” and establish the connection.
+
+## Verification:
+
+```none
+vyos@vpn.vyos.net:~$ show vpn ipsec remote-access summary
+ Connection ID Username Protocol State Uptime Tunnel IP Remote Host Remote ID IKE Proposal IPSec Proposal
+--------------- ---------- ---------- ------- -------- ----------- ------------- ----------- ------------------------------------------ ------------------
+ 5 vyos IKEv2 UP 37s 192.0.2.129 10.0.0.2 10.0.0.2 AES_GCM_16-128/PRF_HMAC_SHA2_256/MODP_2048 ESP:AES_GCM_16-128
+```
diff --git a/docs/configuration/vpn/ipsec/site2site_ipsec.md b/docs/configuration/vpn/ipsec/site2site_ipsec.md
new file mode 100644
index 00000000..d3b65ae1
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/site2site_ipsec.md
@@ -0,0 +1,780 @@
+(size2site-ipsec)=
+
+# IPsec Site-to-Site VPN
+
+## IPsec Site-to-Site VPN Types
+
+VyOS supports two types of IPsec VPN: Policy-based IPsec VPN and Route-based
+IPsec VPN.
+
+### Policy-based VPN
+
+Policy-based VPN is based on static configured policies. Each policy creates
+individual IPSec SA. Traffic matches these SAs encrypted and directed to the
+remote peer.
+
+### Route-Based VPN
+
+Route-based VPN is based on secure traffic passing over Virtual Tunnel
+Interfaces (VTIs). This type of IPsec VPNs allows using routing protocols.
+
+## Configuration Site-to-Site VPN
+
+### Requirements and Prerequisites for Site-to-Site VPN
+
+**Negotiated parameters that need to match**
+
+```{eval-rst}
+Phase 1
+ * IKE version
+ * Authentication
+ * Encryption
+ * Hashing
+ * PRF
+ * Lifetime
+
+ .. note:: Strongswan recommends to use the same lifetime value on both peers
+
+Phase 2
+ * Encryption
+ * Hashing
+ * PFS
+ * Mode (tunnel or transport)
+ * Lifetime
+
+ .. note:: Strongswan recommends to use the same lifetime value on both peers
+
+ * Remote and Local networks in SA must be compatible on both peers
+```
+
+### Configuration Steps for Site-to-Site VPN
+
+The next example shows the configuration one of the router participating in
+IPsec VPN.
+
+```{eval-rst}
+Tunnel information:
+ * Phase 1:
+ * encryption: AES256
+ * hash: SHA256
+ * PRF: SHA256
+ * DH: 14
+ * lifetime: 28800
+ * Phase 2:
+ * IPsec mode: tunnel
+ * encryption: AES256
+ * hash: SHA256
+ * PFS: inherited from DH Phase 1
+ * lifetime: 3600
+ * If Policy based VPN is used
+ * Remote network is 192.168.50.0/24. Local network is 192.168.10.0/24
+ * If Route based VPN is used
+ * IP of the VTI interface is 10.0.0.1/30
+```
+
+:::{note}
+We do not recommend using policy-based vpn and route-based vpn configurations to the same peer.
+:::
+
+**1. Configure ike-group (IKE Phase 1)**
+
+```none
+set vpn ipsec ike-group IKE close-action 'start'
+set vpn ipsec ike-group IKE key-exchange 'ikev1'
+set vpn ipsec ike-group IKE lifetime '28800'
+set vpn ipsec ike-group IKE proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE proposal 10 hash 'sha256'
+set vpn ipsec ike-group IKE proposal 10 prf 'prfsha256'
+```
+
+**2. Configure ESP-group (IKE Phase 2)**
+
+```none
+set vpn ipsec esp-group ESP lifetime '3600'
+set vpn ipsec esp-group ESP mode 'tunnel'
+set vpn ipsec esp-group ESP pfs 'enable'
+set vpn ipsec esp-group ESP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP proposal 10 hash 'sha256'
+```
+
+**3. Specify interface facing to the protected destination.**
+
+```none
+set vpn ipsec interface eth0
+```
+
+**4. Configure PSK keys and authentication ids for this key if authentication type is PSK**
+
+```none
+set vpn ipsec authentication psk PSK-KEY id '192.168.0.2'
+set vpn ipsec authentication psk PSK-KEY id '192.168.5.2'
+set vpn ipsec authentication psk PSK-KEY secret 'vyos'
+```
+
+To set base64 secret encode plaintext password to base64 and set secret-type
+
+```none
+echo -n "vyos" | base64
+dnlvcw==
+```
+
+```none
+set vpn ipsec authentication psk PSK-KEY secret 'dnlvcw=='
+set vpn ipsec authentication psk PSK-KEY secret-type base64
+```
+
+**5. Configure peer and apply IKE-group and esp-group to peer.**
+
+```none
+set vpn ipsec site-to-site peer PEER1 authentication local-id '192.168.0.2'
+set vpn ipsec site-to-site peer PEER1 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer PEER1 authentication remote-id '192.168.5.2'
+set vpn ipsec site-to-site peer PEER1 connection-type 'initiate'
+set vpn ipsec site-to-site peer PEER1 default-esp-group 'ESP'
+set vpn ipsec site-to-site peer PEER1 ike-group 'IKE'
+set vpn ipsec site-to-site peer PEER1 local-address '192.168.0.2'
+set vpn ipsec site-to-site peer PEER1 remote-address '192.168.5.2'
+
+Peer selects the key from step 4 according to local-id/remote-id pair.
+```
+
+**6. Depends to vpn type (route-based vpn or policy-based vpn).**
+
+> **6.1 For Policy-based VPN configure SAs using tunnel command specifying remote and local networks.**
+>
+> > ```none
+> > set vpn ipsec site-to-site peer PEER1 tunnel 1 local prefix '192.168.10.0/24'
+> > set vpn ipsec site-to-site peer PEER1 tunnel 1 remote prefix '192.168.50.0/24'
+> > ```
+>
+> **6.2 For Route-based VPN create VTI interface, set IP address to this interface and bind this interface to the vpn peer.**
+>
+> > ```none
+> > set interfaces vti vti1 address 10.0.0.1/30
+> > set vpn ipsec site-to-site peer PEER1 vti bind vti1
+> > set vpn ipsec options disable-route-autoinstall
+> > ```
+> >
+> > Create routing between local networks via VTI interface using dynamic or
+> > static routing.
+> >
+> > ```none
+> > set protocol static route 192.168.50.0/24 next-hop 10.0.0.2
+> > ```
+
+### Initiator and Responder Connection Types
+
+In Site-to-Site IPsec VPN it is recommended that one peer should be an
+initiator and the other - the responder. The initiator actively establishes
+the VPN tunnel. The responder passively waits for the remote peer to
+establish the VPN tunnel. Depends on selected role it is recommended
+select proper values for close-action and DPD action.
+
+The result of wrong value selection can be unstable work of the VPN.
+: - Duplicate CHILD SA creation.
+ - None of the VPN sides initiates the tunnel establishment.
+
+Below flow-chart could be a quick reference for the close-action
+combination depending on how the peer is configured.
+
+```{eval-rst}
+.. figure:: /_static/images/IPSec_close_action_settings.webp
+```
+
+Similar combinations are applicable for the dead-peer-detection.
+
+### Detailed Configuration Commands
+
+#### PSK Key Authentication
+
+```{cfgcmd} set vpn ipsec authentication psk \<name\> dhcp-interface
+
+ID for authentication generated from DHCP address
+dynamically.
+
+```
+
+```{cfgcmd} set vpn ipsec authentication psk id \<id\>
+
+static ID's for authentication. In general local and remote address
+``<x.x.x.x>``, ``<h:h:h:h:h:h:h:h>`` or ``%any``.
+```
+
+```{cfgcmd} set vpn ipsec authentication psk secret \<secret\>
+
+A predefined shared secret used in configured mode
+``pre-shared-secret``. Base64-encoded secrets are allowed if
+`secret-type base64` is configured.
+```
+
+```{cfgcmd} set vpn ipsec authentication psk secret-type \<type\>
+
+Specifies the secret type:
+
+* **plaintext** - Plain text type (default value).
+* **base64** - Base64 type.
+```
+
+#### Peer Configuration
+
+
+##### Peer Authentication Commands
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication mode \<mode\>
+
+Mode for authentication between VyOS and remote peer:
+
+* **pre-shared-secret** - Use predefined shared secret phrase.
+* **rsa** - Use simple shared RSA key.
+* **x509** - Use certificates infrastructure for authentication.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication local-id \<id\>
+
+ID for the local VyOS router. If defined, during the authentication
+it will be send to remote peer.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication remote-id \<id\>
+
+ID for remote peer, instead of using peer name or
+address. Useful in case if the remote peer is behind NAT
+or if ``mode x509`` is used.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication rsa local-key \<key\>
+
+Name of PKI key-pair with local private key.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication rsa remote-key \<key\>
+
+Name of PKI key-pair with remote public key.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication rsa passphrase \<passphrase\>
+
+Local private key passphrase.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication use-x509-id \<id\>
+
+Use local ID from x509 certificate. Cannot be used when
+``id`` is defined.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication x509 ca-certificate \<name\>
+
+Name of CA certificate in PKI configuration. Using for authenticating
+remote peer in x509 mode.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> authentication x509 certificate \<name\>
+
+Name of certificate in PKI configuration, which will be used
+for authenticating local router on remote peer.
+```
+
+```{cfgcmd} set vpn ipsec authentication x509 passphrase \<passphrase\>
+
+Private key passphrase, if needed.
+```
+
+##### Global Peer Configuration Commands
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> connection-type \<type\>
+
+Operational mode defines how to handle this connection process.
+
+* **initiate** - does initial connection to remote peer immediately
+ after configuring and after boot. In this mode the connection will
+ not be restarted in case of disconnection, therefore should be used
+ only together with DPD or another session tracking methods.
+
+* **trap** - does not try to initiate a connection to a remote
+ peer immediately. Instead, it installs a trap policy that will
+ trigger IKE negotiation and establish the IPsec session when
+ matching traffic is sent from the local side. This can be useful
+ when there is no direct connectivity to the peer due to firewall
+ or NAT in the middle of the local and remote side.
+
+ :::{warning}
+ The ``trap`` mode is not needed in most environments
+ and can lead to connection confusion or unintended tunnel uptime
+ behavior if used incorrectly. Using this mode requires careful
+ coordination with parameters such as ``close-action`` and DPD.
+ For most deployments, use ``initiate`` and ``none`` as described below.
+ :::
+
+* **none** - loads the connection only, which then can be manually
+ initiated or used as a responder configuration.
+
+:::{note}
+For most site-to-site VPNs, configure one peer
+with ``connection-type initiate`` (active side) and the other peer
+with ``connection-type none`` (passive side) to
+ensure stable and predictable tunnel behavior.
+When using ``connection-type initiate``, you must also configure
+DPD or another session tracking method (such as ``close-action``)
+to automatically re-establish the tunnel after a disconnection.
+Otherwise, the tunnel will not reconnect automatically if it goes down.
+:::
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> default-esp-group \<name\>
+
+Name of ESP group to use by default for traffic encryption.
+Might be overwritten by individual settings for tunnel or VTI
+interface binding.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> description \<description\>
+
+Description for this peer.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> dhcp-interface \<interface\>
+
+Specify the interface which IP address, received from DHCP for IPSec
+connection with this peer, will be used as ``local-address``.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> force-udp-encapsulation
+
+Force encapsulation of ESP into UDP datagrams. Useful in case if
+between local and remote side is firewall or NAT, which not
+allows passing plain ESP packets between them.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> ike-group \<name\>
+
+Name of IKE group to use for key exchanges.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> local-address \<address\>
+
+Local IP address for IPsec connection with this peer.
+If defined ``any``, then an IP address which configured on interface with
+default route will be used.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> remote-address \<address\>
+
+Remote IP address or hostname for IPsec connection. IPv4 or IPv6
+address is used when a peer has a public static IP address. Hostname
+is a DNS name which could be used when a peer has a public IP
+address and DNS name, but an IP address could be changed from time
+to time.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> replay-window \<size\>
+
+IPsec replay window to configure for CHILD_SAs
+(default: 32), a value of 0 disables IPsec replay protection.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> virtual-address \<address\>
+
+Defines a virtual IP address which is requested by the initiator and
+one or several IPv4 and/or IPv6 addresses are assigned from multiple
+pools by the responder. The wildcard addresses 0.0.0.0 and ::
+request an arbitrary address, specific addresses may be defined.
+```
+
+##### CHILD SAs Configuration Commands
+
+###### Policy-Based CHILD SAs Configuration Commands
+
+Every configured tunnel under peer configuration is a new CHILD SA.
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> disable
+
+Disable this tunnel.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> esp-group \<name\>
+
+Specify ESP group for this CHILD SA.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> priority \<number\>
+
+Priority for policy-based IPsec VPN tunnels (lowest value more
+preferable).
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> protocol \<name\>
+
+Define the protocol for match traffic, which should be encrypted and
+send to this peer.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> local prefix \<network\>
+
+IP network at the local side.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> local port \<number\>
+
+Local port number. Have effect only when used together with
+``prefix``.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> remote prefix \<network\>
+
+IP network at the remote side.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> tunnel \<number\> remote port \<number\>
+
+Remote port number. Have effect only when used together with
+``prefix``.
+```
+
+###### Route-Based CHILD SAs Configuration Commands
+
+To configure route-based VPN it is enough to create vti interface and
+bind it to the peer. Any traffic, which will be send to VTI interface
+will be encrypted and send to this peer. Using VTI makes IPsec
+configuration much flexible and easier in complex situation, and
+allows to dynamically add/delete remote networks, reachable via a
+peer, as in this mode router don't need to create additional SA/policy
+for each remote network.
+
+:::{warning}
+When using site-to-site IPsec with VTI interfaces,
+be sure to disable route autoinstall.
+:::
+```none
+set vpn ipsec options disable-route-autoinstall
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> vti bind \<interface\>
+
+VTI interface to bind to this peer.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> vti esp-group \<name\>
+
+ESP group for encrypt traffic, passed this VTI interface.
+```
+
+Traffic-selectors parameters for traffic that should pass via vti
+interface.
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> vti traffic-selector local prefix \<network\>
+
+Local prefix for interesting traffic.
+```
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<name\> vti traffic-selector remote prefix \<network\>
+
+Remote prefix for interesting traffic.
+```
+
+### IPsec Op-mode Commands
+
+```{opcmd} show vpn ike sa
+
+Shows active IKE SAs information.
+```
+
+```{opcmd} show vpn ike secrets
+
+Shows configured authentication keys.
+```
+
+```{opcmd} show vpn ike status
+
+Shows Strongswan daemon status.
+```
+
+```{opcmd} show vpn ipsec connections
+
+Shows summary status of all configured IKE and IPsec SAs.
+```
+
+```{opcmd} show vpn ipsec sa [detail]
+
+Shows active IPsec SAs information.
+```
+
+```{opcmd} show vpn ipsec status
+
+Shows status of IPsec process.
+```
+
+```{opcmd} show vpn ipsec policy
+
+Shows the in-kernel crypto policies.
+```
+
+```{opcmd} show vpn ipsec state
+
+Shows the in-kernel crypto state.
+```
+
+```{opcmd} show log ipsec
+
+Shows IPsec logs.
+```
+
+```{opcmd} reset vpn ipsec site-to-site all
+
+Clear all ipsec connection and reinitiate them if VyOS is configured
+as initiator.
+```
+
+```{opcmd} reset vpn ipsec site-to-site peer \<name\>
+
+Clear all peer IKE SAs with IPsec SAs and reinitiate them if VyOS is
+configured as initiator.
+```
+
+```{opcmd} reset vpn ipsec site-to-site peer \<name\> tunnel \<number\>
+
+Clear scpecific IPsec SA and reinitiate it if VyOS is configured as
+initiator.
+```
+
+```{opcmd} reset vpn ipsec site-to-site peer \<name\> vti \<number\>
+
+Clear IPsec SA which is map to vti interface of this peer and
+reinitiate it if VyOS is configured as initiator.
+```
+
+```{opcmd} restart ipsec
+
+Restart Strongswan daemon.
+```
+
+## Examples:
+
+### Policy-Based VPN Example
+
+**PEER1:**
+- WAN interface on `eth0`
+- `eth0` interface IP: `10.0.1.2/30`
+- `dum0` interface IP: `192.168.0.1/24` (for testing purposes)
+- Initiator
+
+**PEER2:**
+- WAN interface on `eth0`
+- `eth0` interface IP: `10.0.2.2/30`
+- `dum0` interface IP: `192.168.1.0/24` (for testing purposes)
+- Responder
+
+```none
+# PEER1
+set interfaces dummy dum0 address '192.168.0.1/32'
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'test'
+set vpn ipsec esp-group ESP-GRPOUP lifetime '3600'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 hash 'sha1'
+set vpn ipsec ike-group IKE-GROUP close-action 'start'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '30'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection timeout '120'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer PEER2 authentication local-id '10.0.1.2'
+set vpn ipsec site-to-site peer PEER2 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer PEER2 authentication remote-id '10.0.2.2'
+set vpn ipsec site-to-site peer PEER2 connection-type 'initiate'
+set vpn ipsec site-to-site peer PEER2 default-esp-group 'ESP-GRPOUP'
+set vpn ipsec site-to-site peer PEER2 ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer PEER2 local-address '10.0.1.2'
+set vpn ipsec site-to-site peer PEER2 remote-address '10.0.2.2'
+set vpn ipsec site-to-site peer PEER2 tunnel 0 local prefix '192.168.0.0/24'
+set vpn ipsec site-to-site peer PEER2 tunnel 0 remote prefix '192.168.1.0/24'
+
+
+# PEER2
+set interfaces dummy dum0 address '192.168.1.1/32'
+set interfaces ethernet eth0 address '10.0.2.2/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.2.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'test'
+set vpn ipsec esp-group ESP-GRPOUP lifetime '3600'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 hash 'sha1'
+set vpn ipsec ike-group IKE-GROUP close-action 'none'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'clear'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '30'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection timeout '120'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev1'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec site-to-site peer PEER1 authentication local-id '10.0.2.2'
+set vpn ipsec site-to-site peer PEER1 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer PEER1 authentication remote-id '10.0.1.2'
+set vpn ipsec site-to-site peer PEER1 connection-type 'none'
+set vpn ipsec site-to-site peer PEER1 default-esp-group 'ESP-GRPOUP'
+set vpn ipsec site-to-site peer PEER1 ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer PEER1 local-address '10.0.2.2'
+set vpn ipsec site-to-site peer PEER1 remote-address '10.0.1.2'
+set vpn ipsec site-to-site peer PEER1 tunnel 0 local prefix '192.168.1.0/24'
+set vpn ipsec site-to-site peer PEER1 tunnel 0 remote prefix '192.168.0.0/24'
+```
+
+Show status of policy-based IPsec VPN setup:
+
+```none
+vyos@PEER2:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+10.0.1.2 10.0.1.2 10.0.2.2 10.0.2.2
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv1 AES_CBC_256 HMAC_SHA1_96 MODP_2048 no 1254 25633
+
+
+vyos@srv-gw0:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+-------------- ------- -------- -------------- ---------------- ---------------- ----------- ----------------------------------
+PEER1-tunnel-0 up 20m42s 0B/0B 0/0 10.0.1.2 10.0.1.2 AES_CBC_256/HMAC_SHA1_96/MODP_2048
+
+vyos@PEER2:~$ show vpn ipsec connections
+Connection State Type Remote address Local TS Remote TS Local id Remote id Proposal
+-------------- ------- ------ ---------------- -------------- -------------- ---------- ----------- ----------------------------------
+PEER1 up IKEv1 10.0.1.2 - - 10.0.2.2 10.0.1.2 AES_CBC/256/HMAC_SHA1_96/MODP_2048
+PEER1-tunnel-0 up IPsec 10.0.1.2 192.168.1.0/24 192.168.0.0/24 10.0.2.2 10.0.1.2 AES_CBC/256/HMAC_SHA1_96/MODP_2048
+```
+
+If there is SNAT rules on eth0, need to add exclude rule
+
+```none
+# PEER1 side
+set nat source rule 10 destination address '192.168.1.0/24'
+set nat source rule 10 'exclude'
+set nat source rule 10 outbound-interface name 'eth0'
+set nat source rule 10 source address '192.168.0.0/24'
+
+# PEER2 side
+set nat source rule 10 destination address '192.168.0.0/24'
+set nat source rule 10 'exclude'
+set nat source rule 10 outbound-interface name 'eth0'
+set nat source rule 10 source address '192.168.1.0/24'
+```
+
+### Route-Based VPN Example
+
+**PEER1:**
+- WAN interface on `eth0`
+- `eth0` interface IP: `10.0.1.2/30`
+- 'vti0' interface IP: `10.100.100.1/30`
+- `dum0` interface IP: `192.168.0.1/24` (for testing purposes)
+- Role: Initiator
+
+**PEER2:**
+- WAN interface on `eth0`
+- `eth0` interface IP: `10.0.2.2/30`
+- 'vti0' interface IP: `10.100.100.2/30`
+- `dum0` interface IP: `192.168.1.0/24` (for testing purposes)
+- Role: Responder
+
+```none
+# PEER1
+set interfaces dummy dum0 address '192.168.0.1/32'
+set interfaces ethernet eth0 address '10.0.1.2/30'
+set interfaces vti vti0 address '10.100.100.1/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.1.1
+set protocols static route 192.168.1.0/24 next-hop 10.100.100.2
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'test'
+set vpn ipsec esp-group ESP-GRPOUP lifetime '3600'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 hash 'sha1'
+set vpn ipsec ike-group IKE-GROUP close-action 'start'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '30'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec options disable-route-autoinstall
+set vpn ipsec site-to-site peer PEER2 authentication local-id '10.0.1.2'
+set vpn ipsec site-to-site peer PEER2 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer PEER2 authentication remote-id '10.0.2.2'
+set vpn ipsec site-to-site peer PEER2 connection-type 'initiate'
+set vpn ipsec site-to-site peer PEER2 default-esp-group 'ESP-GRPOUP'
+set vpn ipsec site-to-site peer PEER2 ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer PEER2 local-address '10.0.1.2'
+set vpn ipsec site-to-site peer PEER2 remote-address '10.0.2.2'
+set vpn ipsec site-to-site peer PEER2 vti bind 'vti0'
+
+
+# PEER2
+set interfaces dummy dum0 address '192.168.1.1/32'
+set interfaces ethernet eth0 address '10.0.2.2/30'
+set interfaces vti vti0 address '10.100.100.2/30'
+set protocols static route 0.0.0.0/0 next-hop 10.0.2.1
+set protocols static route 192.168.0.0/24 next-hop 10.100.100.1
+set vpn ipsec authentication psk AUTH-PSK id '10.0.1.2'
+set vpn ipsec authentication psk AUTH-PSK id '10.0.2.2'
+set vpn ipsec authentication psk AUTH-PSK secret 'test'
+set vpn ipsec esp-group ESP-GRPOUP lifetime '3600'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 encryption 'aes256'
+set vpn ipsec esp-group ESP-GRPOUP proposal 10 hash 'sha1'
+set vpn ipsec ike-group IKE-GROUP close-action 'none'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'clear'
+set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '30'
+set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
+set vpn ipsec ike-group IKE-GROUP lifetime '28800'
+set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
+set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
+set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha1'
+set vpn ipsec interface 'eth0'
+set vpn ipsec options disable-route-autoinstall
+set vpn ipsec site-to-site peer PEER1 authentication local-id '10.0.2.2'
+set vpn ipsec site-to-site peer PEER1 authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer PEER1 authentication remote-id '10.0.1.2'
+set vpn ipsec site-to-site peer PEER1 connection-type 'none'
+set vpn ipsec site-to-site peer PEER1 default-esp-group 'ESP-GRPOUP'
+set vpn ipsec site-to-site peer PEER1 ike-group 'IKE-GROUP'
+set vpn ipsec site-to-site peer PEER1 local-address '10.0.2.2'
+set vpn ipsec site-to-site peer PEER1 remote-address '10.0.1.2'
+set vpn ipsec site-to-site peer PEER1 vti bind 'vti0'
+```
+
+Show status of route-based IPsec VPN setup:
+
+```none
+vyos@PEER2:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+10.0.1.2 10.0.1.2 10.0.2.2 10.0.2.2
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv2 AES_CBC_256 HMAC_SHA1_96 MODP_2048 no 404 27650
+
+vyos@PEER2:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------ ------- -------- -------------- ---------------- ---------------- ----------- ----------------------------------
+PEER1-vti up 3m28s 0B/0B 0/0 10.0.1.2 10.0.1.2 AES_CBC_256/HMAC_SHA1_96/MODP_2048
+
+vyos@PEER2:~$ show vpn ipsec connections
+Connection State Type Remote address Local TS Remote TS Local id Remote id Proposal
+------------ ------- ------ ---------------- ---------- ----------- ---------- ----------- ----------------------------------
+PEER1 up IKEv2 10.0.1.2 - - 10.0.2.2 10.0.1.2 AES_CBC/256/HMAC_SHA1_96/MODP_2048
+PEER1-vti up IPsec 10.0.1.2 0.0.0.0/0 0.0.0.0/0 10.0.2.2 10.0.1.2 AES_CBC/256/HMAC_SHA1_96/MODP_2048
+ ::/0 ::/0
+```
diff --git a/docs/configuration/vpn/ipsec/troubleshooting_ipsec.md b/docs/configuration/vpn/ipsec/troubleshooting_ipsec.md
new file mode 100644
index 00000000..2ca37bc2
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/troubleshooting_ipsec.md
@@ -0,0 +1,313 @@
+(troubleshooting-ipsec)=
+
+# Troubleshooting Site-to-Site VPN IPsec
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+
+## Introduction
+
+This document describes the methodology to monitor and troubleshoot
+Site-to-Site VPN IPsec.
+
+Steps for troubleshooting problems with Site-to-Site VPN IPsec:
+: 1. Ping the remote site through the tunnel using the source and
+ destination IPs included in the policy.
+ 2. Check connectivity between the routers using the ping command
+ (if ICMP traffic is allowed).
+ 3. Check the IKE SAs' statuses.
+ 4. Check the IPsec SAs' statuses.
+ 5. Check logs to view debug messages.
+
+## Checking IKE SA Status
+
+The next command shows IKE SAs' statuses.
+
+```none
+vyos@vyos:~$ show vpn ike sa
+
+Peer ID / IP Local ID / IP
+------------ -------------
+192.168.1.2 192.168.1.2 192.168.0.1 192.168.0.1
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv2 AES_CBC_128 HMAC_SHA1_96 MODP_2048 no 162 27023
+```
+
+This command shows the next information:
+: - IKE SA status.
+ - Selected IKE version.
+ - Selected Encryption, Hash and Diffie-Hellman Group.
+ - NAT-T.
+ - ID and IP of both peers.
+ - A-Time: established time, L-Time: time for next rekeying.
+
+## IPsec SA (CHILD SA) Status
+
+The next commands show IPsec SAs' statuses.
+
+```none
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------- ------- -------- -------------- ---------------- ---------------- ----------- ----------------------------------
+PEER-tunnel-1 up 16m30s 168B/168B 2/2 192.168.1.2 192.168.1.2 AES_CBC_128/HMAC_SHA1_96/MODP_2048
+```
+
+```none
+vyos@vyos:~$ show vpn ipsec sa detail
+PEER: #1, ESTABLISHED, IKEv2, 101275ac719d5a1b_i* 68ea4ec3bed3bf0c_r
+ local '192.168.0.1' @ 192.168.0.1[4500]
+ remote '192.168.1.2' @ 192.168.1.2[4500]
+ AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+ established 4054s ago, rekeying in 23131s
+ PEER-tunnel-1: #2, reqid 1, INSTALLED, TUNNEL, ESP:AES_CBC-128/HMAC_SHA1_96/MODP_2048
+ installed 1065s ago, rekeying in 1998s, expires in 2535s
+ in c5821882, 168 bytes, 2 packets, 81s ago
+ out c433406a, 168 bytes, 2 packets, 81s ago
+ local 10.0.0.0/24
+ remote 10.0.1.0/24
+```
+
+These commands show the next information:
+: - IPsec SA status.
+ - Uptime and time for the next rekeing.
+ - Amount of transferred data.
+ - Remote and local ID and IP.
+ - Selected Encryption, Hash and Diffie-Hellman Group.
+ - Mode (tunnel or transport).
+ - Remote and local prefixes which are use for policy.
+
+There is a possibility to view the summarized information of SAs' status
+
+```none
+vyos@vyos:~$ show vpn ipsec connections
+Connection State Type Remote address Local TS Remote TS Local id Remote id Proposal
+------------- ------- ------ ---------------- ----------- ----------- ----------- ----------- ----------------------------------
+PEER up IKEv2 192.168.1.2 - - 192.168.0.1 192.168.1.2 AES_CBC/128/HMAC_SHA1_96/MODP_2048
+PEER-tunnel-1 up IPsec 192.168.1.2 10.0.0.0/24 10.0.1.0/24 192.168.0.1 192.168.1.2 AES_CBC/128/HMAC_SHA1_96/MODP_2048
+```
+
+
+## Viewing Logs for Debugging
+
+If IKE SAs or IPsec SAs are down, need to debug IPsec connectivity
+using logs `show log ipsec`
+
+The next example of the successful IPsec connection initialization.
+
+```none
+vyos@vyos:~$ show log ipsec
+Jun 20 14:29:47 charon[2428]: 02[NET] <PEER|1> received packet: from 192.168.1.2[500] to 192.168.0.1[500] (472 bytes)
+Jun 20 14:29:47 charon[2428]: 02[ENC] <PEER|1> parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
+Jun 20 14:29:47 charon-systemd[2428]: received packet: from 192.168.1.2[500] to 192.168.0.1[500] (472 bytes)
+Jun 20 14:29:47 charon[2428]: 02[CFG] <PEER|1> selected proposal: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 20 14:29:47 charon-systemd[2428]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
+Jun 20 14:29:47 charon-systemd[2428]: selected proposal: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 20 14:29:47 charon[2428]: 02[IKE] <PEER|1> authentication of '192.168.0.1' (myself) with pre-shared key
+Jun 20 14:29:47 charon-systemd[2428]: authentication of '192.168.0.1' (myself) with pre-shared key
+Jun 20 14:29:47 charon[2428]: 02[IKE] <PEER|1> establishing CHILD_SA PEER-tunnel-1{1}
+Jun 20 14:29:47 charon-systemd[2428]: establishing CHILD_SA PEER-tunnel-1{1}
+Jun 20 14:29:47 charon[2428]: 02[ENC] <PEER|1> generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
+Jun 20 14:29:47 charon-systemd[2428]: generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
+Jun 20 14:29:47 charon[2428]: 02[NET] <PEER|1> sending packet: from 192.168.0.1[4500] to 192.168.1.2[4500] (268 bytes)
+Jun 20 14:29:47 charon-systemd[2428]: sending packet: from 192.168.0.1[4500] to 192.168.1.2[4500] (268 bytes)
+Jun 20 14:29:47 charon[2428]: 13[NET] <PEER|1> received packet: from 192.168.1.2[4500] to 192.168.0.1[4500] (220 bytes)
+Jun 20 14:29:47 charon[2428]: 13[ENC] <PEER|1> parsed IKE_AUTH response 1 [ IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
+Jun 20 14:29:47 charon-systemd[2428]: received packet: from 192.168.1.2[4500] to 192.168.0.1[4500] (220 bytes)
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> authentication of '192.168.1.2' with pre-shared key successful
+Jun 20 14:29:47 charon-systemd[2428]: parsed IKE_AUTH response 1 [ IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> peer supports MOBIKE
+Jun 20 14:29:47 charon-systemd[2428]: authentication of '192.168.1.2' with pre-shared key successful
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> IKE_SA PEER[1] established between 192.168.0.1[192.168.0.1]...192.168.1.2[192.168.1.2]
+Jun 20 14:29:47 charon-systemd[2428]: peer supports MOBIKE
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> scheduling rekeying in 27703s
+Jun 20 14:29:47 charon-systemd[2428]: IKE_SA PEER[1] established between 192.168.0.1[192.168.0.1]...192.168.1.2[192.168.1.2]
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> maximum IKE_SA lifetime 30583s
+Jun 20 14:29:47 charon-systemd[2428]: scheduling rekeying in 27703s
+Jun 20 14:29:47 charon[2428]: 13[CFG] <PEER|1> selected proposal: ESP:AES_CBC_128/HMAC_SHA1_96/NO_EXT_SEQ
+Jun 20 14:29:47 charon-systemd[2428]: maximum IKE_SA lifetime 30583s
+Jun 20 14:29:47 charon-systemd[2428]: selected proposal: ESP:AES_CBC_128/HMAC_SHA1_96/NO_EXT_SEQ
+Jun 20 14:29:47 charon[2428]: 13[IKE] <PEER|1> CHILD_SA PEER-tunnel-1{1} established with SPIs cb94fb3f_i ca99c8a9_o and TS 10.0.0.0/24 === 10.0.1.0/24
+Jun 20 14:29:47 charon-systemd[2428]: CHILD_SA PEER-tunnel-1{1} established with SPIs cb94fb3f_i ca99c8a9_o and TS 10.0.0.0/24 === 10.0.1.0/24
+```
+
+
+## Troubleshooting Examples
+
+### IKE PROPOSAL are Different
+
+In this situation, IKE SAs can be down or not active.
+
+```none
+vyos@vyos:~$ show vpn ike sa
+```
+
+The problem is in IKE phase (Phase 1). The next step is checking debug logs.
+
+Responder Side:
+
+```none
+Jun 23 07:36:33 charon[2440]: 01[CFG] <1> received proposals: IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 07:36:33 charon-systemd[2440]: received proposals: IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 07:36:33 charon[2440]: 01[CFG] <1> configured proposals: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 07:36:33 charon-systemd[2440]: configured proposals: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 07:36:33 charon[2440]: 01[IKE] <1> received proposals unacceptable
+Jun 23 07:36:33 charon-systemd[2440]: received proposals unacceptable
+Jun 23 07:36:33 charon[2440]: 01[ENC] <1> generating IKE_SA_INIT response 0 [ N(NO_PROP) ]
+```
+
+Initiator side:
+
+```none
+Jun 23 07:36:32 charon-systemd[2444]: parsed IKE_SA_INIT response 0 [ N(NO_PROP) ]
+Jun 23 07:36:32 charon[2444]: 14[IKE] <PEER|1> received NO_PROPOSAL_CHOSEN notify error
+Jun 23 07:36:32 charon-systemd[2444]: received NO_PROPOSAL_CHOSEN notify error
+```
+
+The notification **NO_PROPOSAL_CHOSEN** means that the proposal mismatch.
+On the Responder side there is concrete information where is mismatch.
+Encryption **AES_CBC_128** is configured in IKE policy on the responder
+but **AES_CBC_256** is configured on the initiator side.
+
+### PSK Secret Mismatch
+
+In this situation, IKE SAs can be down or not active.
+
+```none
+vyos@vyos:~$ show vpn ike sa
+```
+
+The problem is in IKE phase (Phase 1). The next step is checking debug logs.
+
+Responder:
+
+```none
+Jun 23 08:07:26 charon-systemd[2440]: tried 1 shared key for '192.168.1.2' - '192.168.0.1', but MAC mismatched
+Jun 23 08:07:26 charon[2440]: 13[ENC] <PEER|3> generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
+```
+
+Initiator side:
+
+```none
+Jun 23 08:07:24 charon[2436]: 12[ENC] <PEER|1> parsed IKE_AUTH response 1 [ N(AUTH_FAILED) ]
+Jun 23 08:07:24 charon-systemd[2436]: parsed IKE_AUTH response 1 [ N(AUTH_FAILED) ]
+Jun 23 08:07:24 charon[2436]: 12[IKE] <PEER|1> received AUTHENTICATION_FAILED notify error
+Jun 23 08:07:24 charon-systemd[2436]: received AUTHENTICATION_FAILED notify error
+```
+
+The notification **AUTHENTICATION_FAILED** means that the authentication
+is failed. There is a reason to check PSK on both side.
+
+### ESP Proposal Mismatch
+
+The output of **show** commands shows us that IKE SA is established but
+IPSec SA is not.
+
+```none
+vyos@vyos:~$ show vpn ike sa
+Peer ID / IP Local ID / IP
+------------ -------------
+192.168.1.2 192.168.1.2 192.168.0.1 192.168.0.1
+
+ State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time
+ ----- ------ ------- ---- --------- ----- ------ ------
+ up IKEv2 AES_CBC_128 HMAC_SHA1_96 MODP_2048 no 158 26817
+```
+
+```none
+vyos@vyos:~$ show vpn ipsec sa
+Connection State Uptime Bytes In/Out Packets In/Out Remote address Remote ID Proposal
+------------ ------- -------- -------------- ---------------- ---------------- ----------- ----------
+```
+
+The next step is checking debug logs.
+
+Initiator side:
+
+```none
+Jun 23 08:16:10 charon[3789]: 13[NET] <PEER|1> received packet: from 192.168.1.2[500] to 192.168.0.1[500] (472 bytes)
+Jun 23 08:16:10 charon[3789]: 13[ENC] <PEER|1> parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
+Jun 23 08:16:10 charon-systemd[3789]: received packet: from 192.168.1.2[500] to 192.168.0.1[500] (472 bytes)
+Jun 23 08:16:10 charon[3789]: 13[CFG] <PEER|1> selected proposal: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 08:16:10 charon-systemd[3789]: parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
+Jun 23 08:16:10 charon-systemd[3789]: selected proposal: IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
+Jun 23 08:16:10 charon[3789]: 13[IKE] <PEER|1> authentication of '192.168.0.1' (myself) with pre-shared key
+Jun 23 08:16:10 charon-systemd[3789]: authentication of '192.168.0.1' (myself) with pre-shared key
+Jun 23 08:16:10 charon[3789]: 13[IKE] <PEER|1> establishing CHILD_SA PEER-tunnel-1{1}
+Jun 23 08:16:10 charon-systemd[3789]: establishing CHILD_SA PEER-tunnel-1{1}
+Jun 23 08:16:10 charon[3789]: 13[ENC] <PEER|1> generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
+Jun 23 08:16:10 charon-systemd[3789]: generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
+Jun 23 08:16:10 charon[3789]: 13[NET] <PEER|1> sending packet: from 192.168.0.1[4500] to 192.168.1.2[4500] (268 bytes)
+Jun 23 08:16:10 charon-systemd[3789]: sending packet: from 192.168.0.1[4500] to 192.168.1.2[4500] (268 bytes)
+Jun 23 08:16:10 charon[3789]: 09[NET] <PEER|1> received packet: from 192.168.1.2[4500] to 192.168.0.1[4500] (140 bytes)
+Jun 23 08:16:10 charon-systemd[3789]: received packet: from 192.168.1.2[4500] to 192.168.0.1[4500] (140 bytes)
+Jun 23 08:16:10 charon[3789]: 09[ENC] <PEER|1> parsed IKE_AUTH response 1 [ IDr AUTH N(MOBIKE_SUP) N(NO_ADD_ADDR) N(NO_PROP) ]
+Jun 23 08:16:10 charon-systemd[3789]: parsed IKE_AUTH response 1 [ IDr AUTH N(MOBIKE_SUP) N(NO_ADD_ADDR) N(NO_PROP) ]
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> authentication of '192.168.1.2' with pre-shared key successful
+Jun 23 08:16:10 charon-systemd[3789]: authentication of '192.168.1.2' with pre-shared key successful
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> peer supports MOBIKE
+Jun 23 08:16:10 charon-systemd[3789]: peer supports MOBIKE
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> IKE_SA PEER[1] established between 192.168.0.1[192.168.0.1]...192.168.1.2[192.168.1.2]
+Jun 23 08:16:10 charon-systemd[3789]: IKE_SA PEER[1] established between 192.168.0.1[192.168.0.1]...192.168.1.2[192.168.1.2]
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> scheduling rekeying in 26975s
+Jun 23 08:16:10 charon-systemd[3789]: scheduling rekeying in 26975s
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> maximum IKE_SA lifetime 29855s
+Jun 23 08:16:10 charon-systemd[3789]: maximum IKE_SA lifetime 29855s
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> received NO_PROPOSAL_CHOSEN notify, no CHILD_SA built
+Jun 23 08:16:10 charon-systemd[3789]: received NO_PROPOSAL_CHOSEN notify, no CHILD_SA built
+Jun 23 08:16:10 charon[3789]: 09[IKE] <PEER|1> failed to establish CHILD_SA, keeping IKE_SA
+Jun 23 08:16:10 charon-systemd[3789]: failed to establish CHILD_SA, keeping IKE_SA
+```
+
+There are messages: **NO_PROPOSAL_CHOSEN** and
+**failed to establish CHILD_SA** which refers that the problem is in
+the IPsec(ESP) proposal mismatch.
+
+The reason of this problem is showed on the responder side.
+
+```none
+Jun 23 08:16:12 charon[2440]: 01[CFG] <PEER|5> received proposals: ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ
+Jun 23 08:16:12 charon-systemd[2440]: received proposals: ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ
+Jun 23 08:16:12 charon[2440]: 01[CFG] <PEER|5> configured proposals: ESP:AES_CBC_128/HMAC_SHA1_96/MODP_2048/NO_EXT_SEQ
+Jun 23 08:16:12 charon-systemd[2440]: configured proposals: ESP:AES_CBC_128/HMAC_SHA1_96/MODP_2048/NO_EXT_SEQ
+Jun 23 08:16:12 charon[2440]: 01[IKE] <PEER|5> no acceptable proposal found
+Jun 23 08:16:12 charon-systemd[2440]: no acceptable proposal found
+Jun 23 08:16:12 charon[2440]: 01[IKE] <PEER|5> failed to establish CHILD_SA, keeping IKE_SA
+```
+
+Encryption **AES_CBC_128** is configured in IKE policy on the responder but **AES_CBC_256**
+is configured on the initiator side.
+
+### Prefixes in Policies Mismatch
+
+As in previous situation, IKE SA is in up state but IPsec SA is not up.
+According to logs we can see **TS_UNACCEPTABLE** notification. It means
+that prefixes (traffic selectors) mismatch on both sides
+
+Initiator:
+
+```none
+Jun 23 14:13:17 charon[4996]: 11[IKE] <PEER|1> received TS_UNACCEPTABLE notify, no CHILD_SA built
+Jun 23 14:13:17 charon-systemd[4996]: maximum IKE_SA lifetime 29437s
+Jun 23 14:13:17 charon[4996]: 11[IKE] <PEER|1> failed to establish CHILD_SA, keeping IKE_SA
+Jun 23 14:13:17 charon-systemd[4996]: received TS_UNACCEPTABLE notify, no CHILD_SA built
+Jun 23 14:13:17 charon-systemd[4996]: failed to establish CHILD_SA, keeping IKE_SA
+```
+
+The reason of this problem is showed on the responder side.
+
+```none
+Jun 23 14:13:19 charon[2440]: 01[IKE] <PEER|7> traffic selectors 10.0.2.0/24 === 10.0.0.0/24 unacceptable
+Jun 23 14:13:19 charon-systemd[2440]: traffic selectors 10.0.2.0/24 === 10.0.0.0/24 unacceptable
+Jun 23 14:13:19 charon[2440]: 01[IKE] <PEER|7> failed to establish CHILD_SA, keeping IKE_SA
+Jun 23 14:13:19 charon-systemd[2440]: failed to establish CHILD_SA, keeping IKE_SA
+Jun 23 14:13:19 charon[2440]: 01[ENC] <PEER|7> generating IKE_AUTH response 1 [ IDr AUTH N(MOBIKE_SUP) N(NO_ADD_ADDR) N(TS_UNACCEPT) ]
+Jun 23 14:13:19 charon-systemd[2440]: generating IKE_AUTH response 1 [ IDr AUTH N(MOBIKE_SUP) N(NO_ADD_ADDR) N(TS_UNACCEPT) ]
+```
+
+Traffic selectors **10.0.2.0/24 === 10.0.0.0/24** are unacceptable on the
+responder side.
diff --git a/docs/configuration/vpn/l2tp.md b/docs/configuration/vpn/l2tp.md
new file mode 100644
index 00000000..d932d095
--- /dev/null
+++ b/docs/configuration/vpn/l2tp.md
@@ -0,0 +1,624 @@
+(l2tp)=
+
+# L2TP
+
+VyOS utilizes [accel-ppp] to provide L2TP server functionality. It can be used
+with local authentication or a connected RADIUS server.
+
+## Configuring L2TP Server
+
+```none
+set vpn l2tp remote-access authentication mode local
+set vpn l2tp remote-access authentication local-users username test password 'test'
+set vpn l2tp remote-access client-ip-pool L2TP-POOL range 192.168.255.2-192.168.255.254
+set vpn l2tp remote-access default-pool 'L2TP-POOL'
+set vpn l2tp remote-access outside-address 192.0.2.2
+set vpn l2tp remote-access gateway-address 192.168.255.1
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication mode \<local | radius\>
+
+Set authentication backend. The configured authentication backend is used
+for all queries.
+
+* **radius**: All authentication queries are handled by a configured RADIUS
+ server.
+* **local**: All authentication queries are handled locally.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access authentication local-users username \<user\> password \<pass\>
+
+Create `<user>` for local authentication on this system. The users password
+will be set to `<pass>`.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access client-ip-pool \<POOL-NAME\> range \<x.x.x.x-x.x.x.x | x.x.x.x/x\>
+
+Use this command to define the first IP address of a pool of
+addresses to be given to l2tp clients. If notation ``x.x.x.x-x.x.x.x``,
+it must be within a /24 subnet. If notation ``x.x.x.x/x`` is
+used there is possibility to set host/netmask.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access default-pool \<POOL-NAME\>
+
+Use this command to define default address pool name.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access gateway-address \<gateway\>
+
+Specifies single `<gateway>` IP address to be used as local address of PPP
+interfaces.
+```
+
+
+## Configuring IPsec
+
+```none
+set vpn ipsec interface eth0
+set vpn l2tp remote-access ipsec-settings authentication mode pre-shared-secret
+set vpn l2tp remote-access ipsec-settings authentication pre-shared-secret secret
+```
+
+
+```{cfgcmd} set vpn ipsec interface \<INTERFACE\>
+
+Use this command to define IPsec interface.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access ipsec-settings authentication mode \<pre-shared-secret | x509\>
+
+Set mode for IPsec authentication between VyOS and L2TP clients.
+```
+
+
+```{cfgcmd} set vpn l2tp remote-access ipsec-settings authentication pre-shared-secret \<secret\>
+
+Set predefined shared secret phrase.
+```
+
+If a local firewall policy is in place on your external interface you will need
+to allow the ports below:
+- UDP port 500 (IKE)
+- IP protocol number 50 (ESP)
+- UDP port 1701 for IPsec
+
+As well as the below to allow NAT-traversal (when NAT is detected by the
+VPN client, ESP is encapsulated in UDP for NAT-traversal):
+
+- UDP port 4500 (NAT-T)
+
+Example:
+
+```none
+set firewall ipv4 name OUTSIDE-LOCAL rule 40 action 'accept'
+set firewall ipv4 name OUTSIDE-LOCAL rule 40 protocol 'esp'
+set firewall ipv4 name OUTSIDE-LOCAL rule 41 action 'accept'
+set firewall ipv4 name OUTSIDE-LOCAL rule 41 destination port '500'
+set firewall ipv4 name OUTSIDE-LOCAL rule 41 protocol 'udp'
+set firewall ipv4 name OUTSIDE-LOCAL rule 42 action 'accept'
+set firewall ipv4 name OUTSIDE-LOCAL rule 42 destination port '4500'
+set firewall ipv4 name OUTSIDE-LOCAL rule 42 protocol 'udp'
+set firewall ipv4 name OUTSIDE-LOCAL rule 43 action 'accept'
+set firewall ipv4 name OUTSIDE-LOCAL rule 43 destination port '1701'
+set firewall ipv4 name OUTSIDE-LOCAL rule 43 ipsec 'match-ipsec'
+set firewall ipv4 name OUTSIDE-LOCAL rule 43 protocol 'udp'
+```
+
+To allow VPN-clients access via your external address, a NAT rule is required:
+
+```none
+set nat source rule 110 outbound-interface name 'eth0'
+set nat source rule 110 source address '192.168.255.0/24'
+set nat source rule 110 translation address masquerade
+```
+
+
+## Configuring RADIUS authentication
+
+To enable RADIUS based authentication, the authentication mode needs to be
+changed within the configuration. Previous settings like the local users, still
+exists within the configuration, however they are not used if the mode has been
+changed from local to radius. Once changed back to local, it will use all local
+accounts again.
+
+```none
+set vpn l2tp remote-access authentication mode radius
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius server \<server\> key \<secret\>
+
+Configure RADIUS `<server>` and its required shared `<secret>` for
+communicating with the RADIUS server.
+```
+
+Since the RADIUS server would be a single point of failure, multiple RADIUS
+servers can be setup and will be used subsequentially.
+For example:
+
+```none
+set vpn l2tp remote-access authentication radius server 10.0.0.1 key 'foo'
+set vpn l2tp remote-access authentication radius server 10.0.0.2 key 'foo'
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+### RADIUS source address
+
+If you are using OSPF as your IGP, use the interface connected closest to the
+RADIUS server. You can bind all outgoing RADIUS requests to a single source IP
+e.g. the loopback interface.
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+:::{note}
+The `source-address` must be configured to that of an interface.
+Best practice would be a loopback or dummy interface.
+:::
+
+### RADIUS advanced options
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius server \<server\> port \<port\>
+
+Configure RADIUS `<server>` and its required port for authentication requests.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius server \<server\> fail-time \<time\>
+
+Mark RADIUS server as offline for this given `<time>` in seconds.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius server \<server\> disable
+
+Temporary disable this RADIUS server.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius acct-timeout \<timeout\>
+
+Timeout to wait reply for Interim-Update packets. (default 3 seconds)
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius dynamic-author server \<address\>
+
+Specifies IP address for Dynamic Authorization Extension server (DM/CoA).
+This IP must exist on any VyOS interface or it can be ``0.0.0.0``.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius dynamic-author port \<port\>
+
+UDP port for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius dynamic-author key \<secret\>
+
+Secret for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius max-try \<number\>
+
+Maximum number of tries to send Access-Request/Accounting-Request queries
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius timeout \<timeout\>
+
+Timeout to wait response from server (seconds)
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius nas-identifier \<identifier\>
+
+Value to send to RADIUS server in NAS-Identifier attribute and to be matched
+in DM/CoA requests.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius nas-ip-address \<address\>
+
+Value to send to RADIUS server in NAS-IP-Address attribute and to be matched
+in DM/CoA requests. Also DM/CoA server will bind to that address.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius rate-limit attribute \<attribute\>
+
+Specifies which RADIUS server attribute contains the rate limit information.
+The default attribute is `Filter-Id`.
+```
+
+:::{note}
+If you set a custom RADIUS attribute you must define it on both
+dictionaries on the RADIUS server and client.
+:::
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius rate-limit enable
+
+Enables bandwidth shaping via RADIUS.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication radius rate-limit vendor
+
+Specifies the vendor dictionary. This dictionary needs to be present in
+/usr/share/accel-ppp/radius.
+```
+
+Received RADIUS attributes have a higher priority than parameters defined within
+the CLI configuration, refer to the explanation below.
+
+### Allocation clients ip addresses by RADIUS
+
+If the RADIUS server sends the attribute `Framed-IP-Address` then this IP
+address will be allocated to the client and the option `default-pool` within
+the CLI config will be ignored.
+
+If the RADIUS server sends the attribute `Framed-Pool`, then the IP address
+will be allocated from a predefined IP pool whose name equals the attribute
+value.
+
+If the RADIUS server sends the attribute `Stateful-IPv6-Address-Pool`, the
+IPv6 address will be allocated from a predefined IPv6 pool `prefix` whose
+name equals the attribute value.
+
+If the RADIUS server sends the attribute `Delegated-IPv6-Prefix-Pool`, an
+IPv6 delegation prefix will be allocated from a predefined IPv6 pool
+`delegate` whose name equals the attribute value.
+
+:::{note}
+`Stateful-IPv6-Address-Pool` and `Delegated-IPv6-Prefix-Pool` are defined in
+RFC6911. If they are not defined in your RADIUS server, add new [dictionary].
+:::
+
+The client's interface can be put into a VRF context via a RADIUS Access-Accept
+packet, or changed via RADIUS CoA. `Accel-VRF-Name` is used for these
+purposes. This is a custom [ACCEL-PPP attribute]. Define it in your RADIUS
+server.
+
+### Renaming clients interfaces by RADIUS
+
+If the RADIUS server uses the attribute `NAS-Port-Id`, ppp tunnels will be
+renamed.
+
+:::{note}
+The value of the attribute `NAS-Port-Id` must be less than 16
+characters, otherwise the interface won't be renamed.
+:::
+
+## Configuring LNS (L2TP Network Server)
+
+LNS are often used to connect to a LAC (L2TP Access Concentrator).
+
+```{cfgcmd} set vpn l2tp remote-access lns host-name \<hostname\>
+
+Sent to the client (LAC) in the Host-Name attribute
+```
+
+```{cfgcmd} set vpn l2tp remote-access lns shared-secret \<secret\>
+
+Tunnel password used to authenticate the client (LAC)
+```
+
+To explain the usage of LNS follow our blueprint {ref}`examples-lac-lns`.
+
+## IPv6
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options ipv6 \<require | prefer | allow | deny\>
+
+Specifies IPv6 negotiation preference.
+* **require** - Require IPv6 negotiation
+* **prefer** - Ask client for IPv6 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv6 only if client requests
+* **deny** - Do not negotiate IPv6 (default value)
+```
+
+```{cfgcmd} set vpn l2tp remote-access client-ipv6-pool \<IPv6-POOL-NAME\> prefix \<address\> mask \<number-of-bits\>
+
+Use this comand to set the IPv6 address pool from which an l2tp client will
+get an IPv6 prefix of your defined length (mask) to terminate the l2tp
+endpoint at their side. The mask length can be set between 48 and 128 bits
+long, the default value is 64.
+```
+
+```{cfgcmd} set vpn l2tp remote-access client-ipv6-pool \<IPv6-POOL-NAME\> delegate \<address\> delegation-prefix \<number-of-bits\>
+
+Use this command to configure DHCPv6 Prefix Delegation (RFC3633) on l2tp.
+You will have to set your IPv6 pool and the length of the delegation
+prefix. From the defined IPv6 pool you will be handing out networks of the
+defined length (delegation-prefix). The length of the delegation prefix can
+be between 32 and 64 bits long.
+```
+
+```{cfgcmd} set vpn l2tp remote-access default-ipv6-pool \<IPv6-POOL-NAME\>
+
+Use this command to define default IPv6 address pool name.
+```
+
+```none
+set vpn l2tp remote-access ppp-options ipv6 allow
+set vpn l2tp remote-access client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set vpn l2tp remote-access client-ipv6-pool IPv6-POOL prefix '2001:db8:8002::/48' mask '64'
+set vpn l2tp remote-access default-ipv6-pool IPv6-POOL
+```
+
+
+### IPv6 Advanced Options
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options ipv6-accept-peer-interface-id
+
+Accept peer interface identifier. By default this is not defined.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies if a fixed or random interface identifier is used for IPv6. The
+default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies the peer interface identifier for IPv6. The default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+* **ipv4-addr** - Calculate interface identifier from IPv4 address.
+* **calling-sid** - Calculate interface identifier from calling-station-id.
+```
+
+
+## Scripting
+
+```{cfgcmd} set vpn l2tp remote-access extended-scripts on-change \<path_to_script\>
+
+Script to run when the session interface is changed by RADIUS CoA handling
+```
+
+```{cfgcmd} set vpn l2tp remote-access extended-scripts on-down \<path_to_script\>
+
+Script to run when the session interface is about to terminate
+```
+
+```{cfgcmd} set vpn l2tp remote-access extended-scripts on-pre-up \<path_to_script\>
+
+Script to run before the session interface comes up
+```
+
+```{cfgcmd} set vpn l2tp remote-access extended-scripts on-up \<path_to_script\>
+
+Script to run when the session interface is completely configured and started
+```
+
+
+## Advanced Options
+
+### Authentication Advanced Options
+
+```{cfgcmd} set vpn l2tp remote-access authentication local-users username \<user\> disable
+
+Disable `<user>` account.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication local-users username \<user\> static-ip \<address\>
+
+Assign a static IP address to `<user>` account.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication local-users username \<user\> rate-limit download \<bandwidth\>
+
+Rate limit the download bandwidth for `<user>` to `<bandwidth>` kbit/s.
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication local-users username \<user\> rate-limit upload \<bandwidth\>
+
+Rate limit the upload bandwidth for `<user>` to `<bandwidth>` kbit/s
+```
+
+```{cfgcmd} set vpn l2tp remote-access authentication protocols \<pap | chap | mschap | mschap-v2\>
+
+Require the peer to authenticate itself using one of the following protocols:
+pap, chap, mschap, mschap-v2.
+```
+
+
+### Client IP Pool Advanced Options
+
+```{cfgcmd} set vpn l2tp remote-access client-ip-pool \<POOL-NAME\> next-pool \<NEXT-POOL-NAME\>
+
+Use this command to define the next address pool name.
+```
+
+
+### PPP Advanced Options
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options disable-ccp
+
+Disable Compression Control Protocol (CCP).
+CCP is enabled by default.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options interface-cache \<number\>
+
+Specifies number of interfaces to cache. This prevents interfaces from being
+removed once the corresponding session is destroyed. Instead, interfaces are
+cached for later use in new sessions. This should reduce the kernel-level
+interface creation/deletion rate.
+Default value is **0**.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options ipv4 \<require | prefer | allow | deny\>
+
+Specifies IPv4 negotiation preference.
+* **require** - Require IPv4 negotiation
+* **prefer** - Ask client for IPv4 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv4 only if client requests (Default value)
+* **deny** - Do not negotiate IPv4
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options lcp-echo-failure \<number\>
+
+Defines the maximum `<number>` of unanswered echo requests. Upon reaching the
+value `<number>`, the session will be reset. Default value is **3**.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options lcp-echo-interval \<interval\>
+
+If this option is specified and is greater than 0, then the PPP module will
+send LCP echo requests every `<interval>` seconds.
+Default value is **30**.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options lcp-echo-timeout
+
+Specifies timeout in seconds to wait for any peer activity. If this option is
+specified it turns on adaptive lcp echo functionality and "lcp-echo-failure"
+is not used. Default value is **0**.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options min-mtu \<number\>
+
+Defines the minimum acceptable MTU. If a client tries to negotiate an MTU
+lower than this it will be NAKed, and disconnected if it rejects a greater
+MTU.
+Default value is **100**.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options mppe \<require | prefer | deny\>
+
+Specifies {abbr}`MPPE (Microsoft Point-to-Point Encryption)` negotiation
+preference.
+* **require** - ask client for mppe, if it rejects drop connection
+* **prefer** - ask client for mppe, if it rejects don't fail. (Default value)
+* **deny** - deny mppe
+
+Default behavior - don't ask the client for mppe, but allow it if the client
+wants. Please note that RADIUS may override this option with the
+MS-MPPE-Encryption-Policy attribute.
+```
+
+```{cfgcmd} set vpn l2tp remote-access ppp-options mru \<number\>
+
+Defines preferred MRU. By default is not defined.
+```
+
+
+### Global Advanced options
+
+```{cfgcmd} set vpn l2tp remote-access description \<description\>
+
+Set description.
+```
+
+```{cfgcmd} set vpn l2tp remote-access limits burst \<value\>
+
+Burst count
+```
+
+```{cfgcmd} set vpn l2tp remote-access limits connection-limit \<value\>
+
+Maximum accepted connection rate (e.g. 1/min, 60/sec)
+```
+
+```{cfgcmd} set vpn l2tp remote-access limits timeout \<value\>
+
+Timeout in seconds
+```
+
+```{cfgcmd} set vpn l2tp remote-access mtu
+
+Maximum Transmission Unit (MTU) (default: **1436**)
+```
+
+```{cfgcmd} set vpn l2tp remote-access max-concurrent-sessions
+
+Maximum number of concurrent session start attempts
+```
+
+```{cfgcmd} set vpn l2tp remote-access name-server \<address\>
+
+Connected clients should use `<address>` as their DNS server. This command
+accepts both IPv4 and IPv6 addresses. Up to two nameservers can be configured
+for IPv4, up to three for IPv6.
+```
+
+```{cfgcmd} set vpn l2tp remote-access shaper fwmark \<1-2147483647\>
+
+Match firewall mark value
+```
+
+```{cfgcmd} set vpn l2tp remote-access snmp master-agent
+
+Enable SNMP
+```
+
+```{cfgcmd} set vpn l2tp remote-access wins-server \<address\>
+
+Windows Internet Name Service (WINS) servers propagated to client
+```
+
+
+## Monitoring
+
+```none
+vyos@vyos:~$ show l2tp-server sessions
+ ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+--------+----------+---------------+-----+--------+-------------+------------+--------+----------+----------+----------
+ l2tp0 | test | 192.168.255.3 | | | 192.168.0.36 | | active | 02:01:47 | 7.7 KiB | 1.2 KiB
+```
+
+```none
+vyos@vyos:~$ show l2tp-server statistics
+ uptime: 0.02:49:49
+cpu: 0%
+mem(rss/virt): 5920/100892 kB
+core:
+ mempool_allocated: 133202
+ mempool_available: 131770
+ thread_count: 1
+ thread_active: 1
+ context_count: 5
+ context_sleeping: 0
+ context_pending: 0
+ md_handler_count: 3
+ md_handler_pending: 0
+ timer_count: 0
+ timer_pending: 0
+sessions:
+ starting: 0
+ active: 0
+ finishing: 0
+l2tp:
+ tunnels:
+ starting: 0
+ active: 0
+ finishing: 0
+ sessions (control channels):
+ starting: 0
+ active: 0
+ finishing: 0
+ sessions (data channels):
+ starting: 0
+ active: 0
+ finishing: 0
+```
+
+[accel-ppp]: https://accel-ppp.org/
+[accel-ppp attribute]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.accel
+[cloudflare]: https://blog.cloudflare.com/announcing-1111
+[dictionary]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.rfc6911
+[freeradius]: https://freeradius.org
+[google public dns]: https://developers.google.com/speed/public-dns
+[network policy server]: <https://en.wikipedia.org/wiki/Network_Policy_Server>
+[opennic]: https://www.opennic.org/
+[quad9]: https://quad9.net
+[radius]: https://en.wikipedia.org/wiki/RADIUS
diff --git a/docs/configuration/vpn/openconnect.md b/docs/configuration/vpn/openconnect.md
new file mode 100644
index 00000000..0bf804ff
--- /dev/null
+++ b/docs/configuration/vpn/openconnect.md
@@ -0,0 +1,330 @@
+(vpn-openconnect)=
+
+# OpenConnect
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+OpenConnect-compatible server feature has been available since Equuleus (1.3).
+Openconnect VPN supports SSL connection and offers full network access. SSL VPN
+network extension connects the end-user system to the corporate network with
+access controls based only on network layer information, such as destination IP
+address and port number. So, it provides safe communication for all types of
+device traffic across public networks and private networks, also encrypts the
+traffic with SSL protocol.
+
+The remote user will use the openconnect client to connect to the router and
+will receive an IP address from a VPN pool, allowing full access to the
+network.
+
+## Configuration
+
+### SSL Certificates
+
+We need to generate the certificate which authenticates users who attempt to
+access the network resource through the SSL VPN tunnels. The following commands
+will create a self signed certificates and will be stored in configuration:
+
+```none
+run generate pki ca install <CA name>
+run generate pki certificate sign <CA name> install <Server name>
+```
+
+We can also create the certificates using Certbot which is an easy-to-use
+client that fetches a certificate from Let's Encrypt an open certificate
+authority launched by the EFF, Mozilla, and others and deploys it to a web
+server.
+
+```none
+sudo certbot certonly --standalone --preferred-challenges http -d <domain name>
+```
+
+
+### Server Configuration
+
+```none
+set vpn openconnect authentication local-users username <user> password <pass>
+set vpn openconnect authentication mode <local password|radius|certificate>
+set vpn openconnect network-settings client-ip-settings subnet <subnet>
+set vpn openconnect network-settings name-server <address>
+set vpn openconnect network-settings name-server <address>
+set vpn openconnect ssl ca-certificate <pki-ca-name>
+set vpn openconnect ssl certificate <pki-cert-name>
+set vpn openconnect ssl passphrase <pki-password>
+```
+
+
+### 2FA OTP support
+
+Instead of password only authentication, 2FA password
+authentication + OTP key can be used. Alternatively, OTP authentication only,
+without a password, can be used.
+To do this, an OTP configuration must be added to the configuration above:
+
+```none
+set vpn openconnect authentication mode local <password-otp|otp>
+set vpn openconnect authentication local-users username <user> otp <key>
+set vpn openconnect authentication local-users username <user> interval <interval (optional)>
+set vpn openconnect authentication local-users username <user> otp-length <otp-length (optional)>
+set vpn openconnect authentication local-users username <user> token-type <token-type (optional)>
+```
+
+For generating an OTP key in VyOS, you can use the CLI command
+(operational mode):
+
+```none
+generate openconnect username <user> otp-key hotp-time
+```
+
+
+### User Certificate Authentication
+
+You can configure users to be authenticated by certificate by setting
+the authentication mode to certificate, and defining what field (by OID)
+in the certificate will be used to identify the username. Two pre-defined
+
+shortcuts for Common Name (OID 2.5.4.3) and User ID
+(OID 0.9.2342.19200300.100.1.1) have been provided as cn or uid.
+
+Otherwise a specific OID value must be provided.
+
+The user's certificate must be signed by the certificate authority
+defined in the configuration for it to be validated for authentication.
+
+```none
+set vpn openconnect authentication mode certificate
+set vpn openconnect authentication mode certificate user-identifier-field cn
+set vpn openconnect ssl ca-certificate <cert>
+```
+
+
+## Verification
+
+```none
+vyos@vyos:~$ sh openconnect-server sessions
+interface username ip remote IP RX TX state uptime
+----------- ---------- ------------- ----------- ------- --------- --------- --------
+sslvpn0 tst 172.20.20.198 192.168.6.1 0 bytes 152 bytes connected 3s
+```
+
+:::{note}
+It is compatible with Cisco (R) AnyConnect (R) clients.
+:::
+
+## Example
+
+### SSL Certificates generation
+
+Follow the instructions to generate CA cert (in configuration mode):
+
+```none
+vyos@vyos# run generate pki ca install ca-ocserv
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB) US
+Enter state: (Default: Some-State) Delaware
+Enter locality: (Default: Some-City) Mycity
+Enter organization name: (Default: VyOS) MyORG
+Enter common name: (Default: vyos.io) oc-ca
+Enter how many days certificate will be valid: (Default: 1825) 3650
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] N
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+```
+
+Follow the instructions to generate server cert (in configuration mode):
+
+```none
+vyos@vyos# run generate pki certificate sign ca-ocserv install srv-ocserv
+Do you already have a certificate request? [y/N] N
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Enter country code: (Default: GB) US
+Enter state: (Default: Some-State) Delaware
+Enter locality: (Default: Some-City) Mycity
+Enter organization name: (Default: VyOS) MyORG
+Enter common name: (Default: vyos.io) oc-srv
+Do you want to configure Subject Alternative Names? [y/N] N
+Enter how many days certificate will be valid: (Default: 365) 1830
+Enter certificate type: (client, server) (Default: server)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] N
+2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
+[edit]
+```
+
+Each of the install command should be applied to the configuration and commited
+before using under the openconnect configuration:
+
+```none
+vyos@vyos# commit
+[edit]
+vyos@vyos# save
+Saving configuration to '/config/config.boot'...
+Done
+[edit]
+```
+
+
+### Openconnect Configuration
+
+Simple setup with one user added and password authentication:
+
+```none
+set vpn openconnect authentication local-users username tst password 'OC_bad_Secret'
+set vpn openconnect authentication mode local password
+set vpn openconnect network-settings client-ip-settings subnet '172.20.20.0/24'
+set vpn openconnect network-settings name-server '10.1.1.1'
+set vpn openconnect network-settings name-server '10.1.1.2'
+set vpn openconnect ssl ca-certificate 'ca-ocserv'
+set vpn openconnect ssl certificate 'srv-ocserv'
+```
+
+To enable the HTTP security headers in the configuration file, use the command:
+
+```none
+set vpn openconnect http-security-headers
+```
+
+
+### Adding a 2FA with an OTP-key
+
+First the OTP keys must be generated and sent to the user and to the
+configuration:
+
+```none
+vyos@vyos:~$ generate openconnect username tst otp-key hotp-time
+# You can share it with the user, he just needs to scan the QR in his OTP app
+# username: tst
+# OTP KEY: 5PA4SGYTQSGOBO3H3EQSSNCUNZAYAPH2
+# OTP URL: otpauth://totp/tst@vyos?secret=5PA4SGYTQSGOBO3H3EQSSNCUNZAYAPH2&digits=6&period=30
+█████████████████████████████████████████
+█████████████████████████████████████████
+████ ▄▄▄▄▄ █▀ ██▄▀ ▄█▄▀▀▄▄▄▄██ ▄▄▄▄▄ ████
+████ █ █ █▀ █▄▄▀▀▀▄█ ▄▄▀▄ █ █ █ ████
+████ █▄▄▄█ █▀█▀▄▄▀ ▄▀ █▀ ▀▄██ █▄▄▄█ ████
+████▄▄▄▄▄▄▄█▄█▄▀ ▀▄█ ▀ ▀ ▀ █▄█▄▄▄▄▄▄▄████
+████ ▄▄▄▀▄▄ ▄███▀▄▀█▄██▀ ▀▄ ▀▄█ ▀ ▀████
+████ ▀▀ ▀ ▄█▄ ▀ ▀▄ ▄█▀ ▄█ ▄▀▀▄██ █████
+████▄ █▄▀▀▄█▀ ▀█▄█▄▄▄▄ ▄▀█▀▀█ ▀ ▄ ▀█▀████
+█████ ▀█▀▄▄ █ ▀▄▄ ▄█▄ ▀█▀▀ █▀ ▄█████
+████▀██▀█▄▄ ▀▀▀▀█▄▀ ▀█▄▄▀▀▀ ▀ ▀█▄██▀▀████
+████▄ ▄ ▄▀▄██▀█ ▄ ▀▄██ ▄▄ ▀▀▄█▄██ ▄█████
+████▀▀ ▄▀ ▄ ▀█▀█▀█ █▀█▄▄▀█▀█▄██▄▄█ ▀████
+████ █ ▀█▄▄█▄ ▀ ▄▄▀▀ ▀ █▄█▀████ █▀ ▀████
+████▄██▄██▄█▀ ▄▀ ▄▄▀▄ ▄▀█ ▄ ▄▄▄ ▀█▄ ████
+████ ▄▄▄▄▄ █▄ ▀█▄█ ▄ ▀ ▄ ▄ █▄█ ▄▀▄█████
+████ █ █ █ ▀▄██▄▄▀█▄▀▄██▄▀ ▄ ▀██▀████
+████ █▄▄▄█ █ ██▀▄▄ ▀▄▄▀█▀ ▀█ ▄▀█ ▀██████
+████▄▄▄▄▄▄▄█▄███▄███▄█▄▄▄▄█▄▄█▄██▄█▄█████
+█████████████████████████████████████████
+█████████████████████████████████████████
+# To add this OTP key to configuration, run the following commands:
+set vpn openconnect authentication local-users username tst otp key 'ebc1c91b13848ce0bb67d9212934546e41803cfa'
+```
+
+Next it is necessary to configure 2FA for OpenConnect:
+
+```none
+set vpn openconnect authentication mode local password-otp
+set vpn openconnect authentication local-users username tst otp key 'ebc1c91b13848ce0bb67d9212934546e41803cfa'
+```
+
+Now when connecting the user will first be asked for the password
+and then the OTP key.
+
+:::{warning}
+When using Time-based one-time password (TOTP) (OTP HOTP-time),
+be sure that the time on the server and the
+OTP token generator are synchronized by NTP
+:::
+
+To display the configured OTP user settings, use the command:
+
+```none
+show openconnect-server user <username> otp <full|key-b32|key-hex|qrcode|uri>
+```
+
+
+### Identity Based Configuration
+
+OpenConnect supports a subset of it's configuration options to be applied on a
+per user/group basis, for configuration purposes we refer to this functionality
+as "Identity based config". The following [OpenConnect Server Manual](https://ocserv.gitlab.io/www/manual.html#:~:text=Configuration%20files%20that%20will%20be%20applied%20per%20user%20connection%20or%0A%23%20per%20group)
+outlines the set of configuration options that are allowed. This can be
+leveraged to apply different sets of configs to different users or groups of
+users.
+
+```none
+sudo mkdir -p /config/auth/ocserv/config-per-user
+sudo touch /config/auth/ocserv/default-user.conf
+
+set vpn openconnect authentication identity-based-config mode user
+set vpn openconnect authentication identity-based-config directory /config/auth/ocserv/config-per-user
+set vpn openconnect authentication identity-based-config default-config /config/auth/ocserv/default-user.conf
+```
+
+:::{warning}
+The above directory and default-config must be a child directory
+of /config/auth, since files outside this directory are not persisted after an
+image upgrade.
+:::
+
+Once you commit the above changes you can create a config file in the
+/config/auth/ocserv/config-per-user directory that matches a username of a
+user you have created e.g. "tst". Now when logging in with the "tst" user the
+config options you set in this file will be loaded.
+
+Be sure to set a sane default config in the default config file, this will be
+loaded in the case that a user is authenticated and no file is found in the
+configured directory matching the users username/group.
+
+```none
+sudo nano /config/auth/ocserv/config-per-user/tst
+```
+
+The same configuration options apply when Identity based config is configured
+in group mode except that group mode can only be used with RADIUS
+authentication.
+
+:::{warning}
+OpenConnect server matches the filename in a case sensitive
+manner, make sure the username/group name you configure matches the
+filename exactly.
+:::
+
+### Configuring RADIUS accounting
+
+OpenConnect can be configured to send accounting information to a
+RADIUS server to capture user session data such as time of
+connect/disconnect, data transferred, and so on.
+
+Configure an accounting server and enable accounting with:
+
+```none
+set vpn openconnect accounting mode radius
+set vpn openconnect accounting radius server 172.20.20.10
+set vpn openconnect accounting radius server 172.20.20.10 port 1813
+set vpn openconnect accounting radius server 172.20.20.10 key your_radius_secret
+```
+
+:::{warning}
+The RADIUS accounting feature must be used with the OpenConnect
+authentication mode RADIUS. It cannot be used with local authentication.
+You must configure the OpenConnect authentication mode to "radius".
+:::
+
+An example of the data captured by a FREERADIUS server with sql accounting:
+
+```none
+mysql> SELECT username, nasipaddress, acctstarttime, acctstoptime, acctinputoctets, acctoutputoctets, callingstationid, framedipaddress, connectinfo_start FROM radacct;
++----------+---------------+---------------------+---------------------+-----------------+------------------+-------------------+-----------------+-----------------------------------+
+| username | nasipaddress | acctstarttime | acctstoptime | acctinputoctets | acctoutputoctets | callingstationid | framedipaddress | connectinfo_start |
++----------+---------------+---------------------+---------------------+-----------------+------------------+-------------------+-----------------+-----------------------------------+
+| test | 198.51.100.15 | 2023-01-13 00:59:15 | 2023-01-13 00:59:21 | 10606 | 152 | 192.168.6.1 | 172.20.20.198 | Open AnyConnect VPN Agent v8.05-1 |
++----------+---------------+---------------------+---------------------+-----------------+------------------+-------------------+-----------------+-----------------------------------+
+```
+
diff --git a/docs/configuration/vpn/pptp.md b/docs/configuration/vpn/pptp.md
new file mode 100644
index 00000000..5df63755
--- /dev/null
+++ b/docs/configuration/vpn/pptp.md
@@ -0,0 +1,594 @@
+(pptp)=
+
+# PPTP-Server
+
+The Point-to-Point Tunneling Protocol (PPTP) has been implemented in VyOS only
+for backwards compatibility. PPTP has many well known security issues and you
+should use one of the many other new VPN implementations.
+
+## Configuring PPTP Server
+
+```none
+set vpn pptp remote-access authentication mode local
+set vpn pptp remote-access authentication local-users username test password 'test'
+set vpn pptp remote-access client-ip-pool PPTP-POOL range 192.168.255.2-192.168.255.254
+set vpn pptp remote-access default-pool 'PPTP-POOL'
+set vpn pptp remote-access outside-address 192.0.2.2
+set vpn pptp remote-access gateway-address 192.168.255.1
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication mode \<local | radius\>
+
+Set authentication backend. The configured authentication backend is used
+for all queries.
+* **radius**: All authentication queries are handled by a configured RADIUS
+server.
+* **local**: All authentication queries are handled locally.
+* **noauth**: Authentication disabled.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication local-users username \<user\> password \<pass\>
+
+Create `<user>` for local authentication on this system. The users password
+will be set to `<pass>`.
+```
+
+```{cfgcmd} set vpn pptp remote-access client-ip-pool \<POOL-NAME\> range \<x.x.x.x-x.x.x.x | x.x.x.x/x\>
+
+Use this command to define the first IP address of a pool of
+addresses to be given to PPTP clients. If notation ``x.x.x.x-x.x.x.x``,
+it must be within a /24 subnet. If notation ``x.x.x.x/x`` is
+used there is possibility to set host/netmask.
+```
+
+```{cfgcmd} set vpn pptp remote-access default-pool \<POOL-NAME\>
+
+Use this command to define default address pool name.
+```
+
+```{cfgcmd} set vpn pptp remote-access gateway-address \<gateway\>
+
+Specifies single `<gateway>` IP address to be used as local address of PPP
+interfaces.
+```
+
+
+## Configuring RADIUS authentication
+
+To enable RADIUS based authentication, the authentication mode needs to be
+changed within the configuration. Previous settings like the local users, still
+exists within the configuration, however they are not used if the mode has been
+changed from local to radius. Once changed back to local, it will use all local
+accounts again.
+
+```none
+set vpn pptp remote-access authentication mode radius
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius server \<server\> key \<secret\>
+
+Configure RADIUS `<server>` and its required shared `<secret>` for
+communicating with the RADIUS server.
+```
+
+Since the RADIUS server would be a single point of failure, multiple RADIUS
+servers can be setup and will be used subsequentially.
+For example:
+
+```none
+set vpn pptp remote-access authentication radius server 10.0.0.1 key 'foo'
+set vpn pptp remote-access authentication radius server 10.0.0.2 key 'foo'
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+### RADIUS source address
+
+If you are using OSPF as IGP, always the closest interface connected to the
+RADIUS server is used. You can bind all outgoing RADIUS requests
+to a single source IP e.g. the loopback interface.
+
+```{cfgcmd} set vpn pptp remote-access authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+### RADIUS advanced options
+
+```{cfgcmd} set vpn pptp remote-access authentication radius server \<server\> port \<port\>
+
+Configure RADIUS `<server>` and its required port for authentication requests.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius server \<server\> fail-time \<time\>
+
+Mark RADIUS server as offline for this given `<time>` in seconds.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius server \<server\> disable
+
+Temporary disable this RADIUS server.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius acct-timeout \<timeout\>
+
+Timeout to wait reply for Interim-Update packets. (default 3 seconds)
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius dynamic-author server \<address\>
+
+Specifies IP address for Dynamic Authorization Extension server (DM/CoA).
+This IP must exist on any VyOS interface or it can be ``0.0.0.0``.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius dynamic-author port \<port\>
+
+UDP port for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius dynamic-author key \<secret\>
+
+Secret for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius max-try \<number\>
+
+Maximum number of tries to send Access-Request/Accounting-Request queries
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius timeout \<timeout\>
+
+Timeout to wait response from server (seconds)
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius nas-identifier \<identifier\>
+
+Value to send to RADIUS server in NAS-Identifier attribute and to be matched
+in DM/CoA requests.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius nas-ip-address \<address\>
+
+Value to send to RADIUS server in NAS-IP-Address attribute and to be matched
+in DM/CoA requests. Also DM/CoA server will bind to that address.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius rate-limit attribute \<attribute\>
+
+Specifies which RADIUS server attribute contains the rate limit information.
+The default attribute is `Filter-Id`.
+```
+
+:::{note}
+If you set a custom RADIUS attribute you must define it on both
+dictionaries at RADIUS server and client.
+:::
+
+```{cfgcmd} set vpn pptp remote-access authentication radius rate-limit enable
+
+Enables bandwidth shaping via RADIUS.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication radius rate-limit vendor
+
+Specifies the vendor dictionary, dictionary needs to be in
+/usr/share/accel-ppp/radius.
+```
+
+Received RADIUS attributes have a higher priority than parameters defined within
+the CLI configuration, refer to the explanation below.
+
+### Allocation clients ip addresses by RADIUS
+
+If the RADIUS server sends the attribute `Framed-IP-Address` then this IP
+address will be allocated to the client and the option `default-pool` within the CLI
+config is being ignored.
+
+If the RADIUS server sends the attribute `Framed-Pool`, IP address will be allocated
+from a predefined IP pool whose name equals the attribute value.
+
+If the RADIUS server sends the attribute `Stateful-IPv6-Address-Pool`, IPv6 address
+will be allocated from a predefined IPv6 pool `prefix` whose name equals the attribute value.
+
+If the RADIUS server sends the attribute `Delegated-IPv6-Prefix-Pool`, IPv6
+delegation pefix will be allocated from a predefined IPv6 pool `delegate`
+whose name equals the attribute value.
+
+:::{note}
+`Stateful-IPv6-Address-Pool` and `Delegated-IPv6-Prefix-Pool` are defined in
+RFC6911. If they are not defined in your RADIUS server, add new [dictionary].
+:::
+
+User interface can be put to VRF context via RADIUS Access-Accept packet, or change
+it via RADIUS CoA. `Accel-VRF-Name` is used from these purposes. It is custom [ACCEL-PPP attribute].
+Define it in your RADIUS server.
+
+### Renaming clients interfaces by RADIUS
+
+If the RADIUS server uses the attribute `NAS-Port-Id`, ppp tunnels will be
+renamed.
+
+:::{note}
+The value of the attribute `NAS-Port-Id` must be less than 16
+characters, otherwise the interface won't be renamed.
+:::
+
+## IPv6
+
+```{cfgcmd} set vpn pptp remote-access ppp-options ipv6 \<require | prefer | allow | deny\>
+
+Specifies IPv6 negotiation preference.
+* **require** - Require IPv6 negotiation
+* **prefer** - Ask client for IPv6 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv6 only if client requests
+* **deny** - Do not negotiate IPv6 (default value)
+```
+
+```{cfgcmd} set vpn pptp remote-access client-ipv6-pool \<IPv6-POOL-NAME\> prefix \<address\> mask \<number-of-bits\>
+
+Use this comand to set the IPv6 address pool from which an PPTP client
+will get an IPv6 prefix of your defined length (mask) to terminate the
+PPTP endpoint at their side. The mask length can be set from 48 to 128
+bit long, the default value is 64.
+```
+
+```{cfgcmd} set vpn pptp remote-access client-ipv6-pool \<IPv6-POOL-NAME\> delegate \<address\> delegation-prefix \<number-of-bits\>
+
+Use this command to configure DHCPv6 Prefix Delegation (RFC3633) on
+PPTP. You will have to set your IPv6 pool and the length of the
+delegation prefix. From the defined IPv6 pool you will be handing out
+networks of the defined length (delegation-prefix). The length of the
+delegation prefix can be set from 32 to 64 bit long.
+```
+
+```{cfgcmd} set vpn pptp remote-access default-ipv6-pool \<IPv6-POOL-NAME\>
+
+Use this command to define default IPv6 address pool name.
+```
+
+```none
+set vpn pptp remote-access ppp-options ipv6 allow
+set vpn pptp remote-access client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set vpn pptp remote-access client-ipv6-pool IPv6-POOL prefix '2001:db8:8002::/48' mask '64'
+set vpn pptp remote-access default-ipv6-pool IPv6-POOL
+```
+
+
+### IPv6 Advanced Options
+
+```{cfgcmd} set vpn pptp remote-access ppp-options ipv6-accept-peer-interface-id
+
+Accept peer interface identifier. By default is not defined.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies fixed or random interface identifier for IPv6.
+By default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies peer interface identifier for IPv6. By default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+* **ipv4-addr** - Calculate interface identifier from IPv4 address.
+* **calling-sid** - Calculate interface identifier from calling-station-id.
+```
+
+
+## Scripting
+
+```{cfgcmd} set vpn pptp remote-access extended-scripts on-change \<path_to_script\>
+
+Script to run when session interface changed by RADIUS CoA handling
+```
+
+```{cfgcmd} set vpn pptp remote-access extended-scripts on-down \<path_to_script\>
+
+Script to run when session interface going to terminate
+```
+
+```{cfgcmd} set vpn pptp remote-access extended-scripts on-pre-up \<path_to_script\>
+
+Script to run before session interface comes up
+```
+
+```{cfgcmd} set vpn pptp remote-access extended-scripts on-up \<path_to_script\>
+
+Script to run when session interface is completely configured and started
+```
+
+
+## Advanced Options
+
+### Authentication Advanced Options
+
+```{cfgcmd} set vpn pptp remote-access authentication local-users username \<user\> disable
+
+Disable `<user>` account.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication local-users username \<user\> static-ip \<address\>
+
+Assign static IP address to `<user>` account.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication local-users username \<user\> rate-limit download \<bandwidth\>
+
+Download bandwidth limit in kbit/s for `<user>`.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication local-users username \<user\> rate-limit upload \<bandwidth\>
+
+Upload bandwidth limit in kbit/s for `<user>`.
+```
+
+```{cfgcmd} set vpn pptp remote-access authentication protocols \<pap | chap | mschap | mschap-v2\>
+
+Require the peer to authenticate itself using one of the following protocols:
+pap, chap, mschap, mschap-v2.
+```
+
+
+### Client IP Pool Advanced Options
+
+```{cfgcmd} set vpn pptp remote-access client-ip-pool \<POOL-NAME\> next-pool \<NEXT-POOL-NAME\>
+
+Use this command to define the next address pool name.
+```
+
+
+### PPP Advanced Options
+
+```{cfgcmd} set vpn pptp remote-access ppp-options disable-ccp
+
+Disable Compression Control Protocol (CCP).
+CCP is enabled by default.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options interface-cache \<number\>
+
+Specifies number of interfaces to keep in cache. It means that don’t
+destroy interface after corresponding session is destroyed, instead
+place it to cache and use it later for new sessions repeatedly.
+This should reduce kernel-level interface creation/deletion rate lack.
+Default value is **0**.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options ipv4 \<require | prefer | allow | deny\>
+
+Specifies IPv4 negotiation preference.
+* **require** - Require IPv4 negotiation
+* **prefer** - Ask client for IPv4 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv4 only if client requests (Default value)
+* **deny** - Do not negotiate IPv4
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options lcp-echo-failure \<number\>
+
+Defines the maximum `<number>` of unanswered echo requests. Upon reaching the
+value `<number>`, the session will be reset. Default value is **3**.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options lcp-echo-interval \<interval\>
+
+If this option is specified and is greater than 0, then the PPP module will
+send LCP pings of the echo request every `<interval>` seconds.
+Default value is **30**.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options lcp-echo-timeout
+
+Specifies timeout in seconds to wait for any peer activity. If this option
+specified it turns on adaptive lcp echo functionality and "lcp-echo-failure"
+is not used. Default value is **0**.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options min-mtu \<number\>
+
+Defines minimum acceptable MTU. If client will try to negotiate less then
+specified MTU then it will be NAKed or disconnected if rejects greater MTU.
+Default value is **100**.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options mppe \<require | prefer | deny\>
+
+Specifies {abbr}`MPPE (Microsoft Point-to-Point Encryption)` negotiation
+preference.
+* **require** - ask client for mppe, if it rejects drop connection
+* **prefer** - ask client for mppe, if it rejects don't fail. (Default value)
+* **deny** - deny mppe
+
+Default behavior - don't ask client for mppe, but allow it if client wants.
+Please note that RADIUS may override this option by MS-MPPE-Encryption-Policy
+attribute.
+```
+
+```{cfgcmd} set vpn pptp remote-access ppp-options mru \<number\>
+
+Defines preferred MRU. By default is not defined.
+```
+
+
+### Global Advanced options
+
+```{cfgcmd} set vpn pptp remote-access description \<description\>
+
+Set description.
+```
+
+```{cfgcmd} set vpn pptp remote-access limits burst \<value\>
+
+Burst count
+```
+
+```{cfgcmd} set vpn pptp remote-access limits connection-limit \<value\>
+
+Acceptable rate of connections (e.g. 1/min, 60/sec)
+```
+
+```{cfgcmd} set vpn pptp remote-access limits timeout \<value\>
+
+Timeout in seconds
+```
+
+```{cfgcmd} set vpn pptp remote-access mtu
+
+Maximum Transmission Unit (MTU) (default: **1436**)
+```
+
+```{cfgcmd} set vpn pptp remote-access max-concurrent-sessions
+
+Maximum number of concurrent session start attempts
+```
+
+```{cfgcmd} set vpn pptp remote-access name-server \<address\>
+
+Connected client should use `<address>` as their DNS server. This
+command accepts both IPv4 and IPv6 addresses. Up to two nameservers
+can be configured for IPv4, up to three for IPv6.
+```
+
+```{cfgcmd} set vpn pptp remote-access shaper fwmark \<1-2147483647\>
+
+Match firewall mark value
+```
+
+```{cfgcmd} set vpn pptp remote-access snmp master-agent
+
+Enable SNMP
+```
+
+```{cfgcmd} set vpn pptp remote-access wins-server \<address\>
+
+Windows Internet Name Service (WINS) servers propagated to client
+```
+
+
+## Monitoring
+
+```{opcmd} show pptp-server sessions
+
+Use this command to locally check the active sessions in the PPTP
+server.
+```
+
+```none
+vyos@vyos:~$ show pptp-server sessions
+ ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+--------+----------+----------+-----+--------+----------------+------------+--------+----------+----------+----------
+ pptp0 | test | 10.0.0.2 | | | 192.168.10.100 | | active | 00:01:26 | 6.9 KiB | 220 B
+```
+
+```none
+vyos@vyos:~$ show pptp-server statistics
+ uptime: 0.00:04:52
+cpu: 0%
+mem(rss/virt): 5504/100176 kB
+core:
+ mempool_allocated: 152007
+ mempool_available: 149007
+ thread_count: 1
+ thread_active: 1
+ context_count: 6
+ context_sleeping: 0
+ context_pending: 0
+ md_handler_count: 6
+ md_handler_pending: 0
+ timer_count: 2
+ timer_pending: 0
+sessions:
+ starting: 0
+ active: 1
+ finishing: 0
+pptp:
+ starting: 0
+ active: 1
+```
+
+
+## Troubleshooting
+
+```none
+vyos@vyos:~$sudo journalctl -u accel-ppp@pptp -b 0
+
+Feb 29 14:58:57 vyos accel-pptp[4629]: pptp: new connection from 192.168.10.100
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: recv [PPTP Start-Ctrl-Conn-Request <Version 1> <Framing 1> <Bearer 1> <Max-Chan 0>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: send [PPTP Start-Ctrl-Conn-Reply <Version 1> <Result 1> <Error 0> <Framing 3> <Bearer 3> <Max-Chan 1>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: recv [PPTP Outgoing-Call-Request <Call-ID 2961> <Call-Serial 2> <Min-BPS 300> <Max-BPS 100000000> <Bearer 3> <Framing 3> <Window-Size 64> <Delay 0>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: send [PPTP Outgoing-Call-Reply <Call-ID 2> <Peer-Call-ID 2961> <Result 1> <Error 0> <Cause 0> <Speed 100000000> <Window-Size 64> <Delay 0> <Channel 0>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: lcp_layer_init
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: auth_layer_init
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: ccp_layer_init
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: ipcp_layer_init
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: ipv6cp_layer_init
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: ppp establishing
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: lcp_layer_start
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: send [LCP ConfReq id=75 <auth PAP> <mru 1436> <magic 483920bd>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: recv [PPTP Set-Link-Info]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: recv [LCP ConfReq id=0 <mru 1400> <magic 0142785a> <pcomp> <accomp> < d 3 6 >]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: send [LCP ConfRej id=0 <pcomp> <accomp> < d 3 6 >]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: recv [LCP ConfReq id=1 <mru 1400> <magic 0142785a>]
+Feb 29 14:58:57 vyos accel-pptp[4629]: :: send [LCP ConfAck id=1]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: fsm timeout 9
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: send [LCP ConfReq id=75 <auth PAP> <mru 1436> <magic 483920bd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP ConfNak id=75 <auth MSCHAP-v2>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: send [LCP ConfReq id=76 <auth CHAP-md5> <mru 1436> <magic 483920bd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP ConfNak id=76 <auth MSCHAP-v2>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: send [LCP ConfReq id=77 <auth MSCHAP-v1> <mru 1436> <magic 483920bd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP ConfNak id=77 <auth MSCHAP-v2>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: send [LCP ConfReq id=78 <auth MSCHAP-v2> <mru 1436> <magic 483920bd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP ConfAck id=78 <auth MSCHAP-v2> <mru 1436> <magic 483920bd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: lcp_layer_started
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: auth_layer_start
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: send [MSCHAP-v2 Challenge id=1 <8aa758781676e6a8e85c11963ee010>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP Ident id=2 <MSRASV5.20>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [LCP Ident id=3 <MSRAS-0-MSEDGEWIN10>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: [43B blob data]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [PPTP Set-Link-Info]
+Feb 29 14:59:00 vyos accel-pptp[4629]: :: recv [MSCHAP-v2 Response id=1 <90c21af1091f745e8bf22388b058>, <e695ae5aae274c88a3fa1ee3dc9057aece4d53c87b9fea>, F=0, name="test"]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: connect: ppp0 <--> pptp(192.168.10.100)
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ppp connected
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [MSCHAP-v2 Success id=1 "S=347F417CF04BEBBC7F75CFA7F43474C36FB218F9 M=Authentication succeeded"]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: test: authentication succeeded
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: auth_layer_started
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ccp_layer_start
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [CCP ConfReq id=b9 <mppe +H -M +S -L -D -C>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ipcp_layer_start
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ipv6cp_layer_start
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: IPV6CP: discarding packet
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [LCP ProtoRej id=122 <8057>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: recv [IPCP ConfReq id=6 <addr 0.0.0.0> <dns1 0.0.0.0> <wins1 0.0.0.0> <dns2 0.0.0.0> <wins2 0.0.0.0>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [IPCP ConfReq id=3b <addr 10.0.0.1>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [IPCP ConfRej id=6 <dns1 0.0.0.0> <wins1 0.0.0.0> <dns2 0.0.0.0> <wins2 0.0.0.0>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: recv [LCP ProtoRej id=7 <80fd>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ccp_layer_finished
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: recv [IPCP ConfAck id=3b <addr 10.0.0.1>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: recv [IPCP ConfReq id=8 <addr 0.0.0.0>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [IPCP ConfNak id=8 <addr 10.0.0.2>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: recv [IPCP ConfReq id=9 <addr 10.0.0.2>]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: send [IPCP ConfAck id=9]
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: ipcp_layer_started
+Feb 29 14:59:00 vyos accel-pptp[4629]: ppp0:test: rename interface to 'pptp0'
+Feb 29 14:59:00 vyos accel-pptp[4629]: pptp0:test: pptp: ppp started
+```
+
+[accel-ppp]: https://accel-ppp.org/
+[accel-ppp attribute]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.accel
+[dictionary]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.rfc6911
diff --git a/docs/configuration/vpn/rsa-keys.md b/docs/configuration/vpn/rsa-keys.md
new file mode 100644
index 00000000..b224b514
--- /dev/null
+++ b/docs/configuration/vpn/rsa-keys.md
@@ -0,0 +1,114 @@
+# RSA-Keys
+
+```{todo}
+Convert raw command blocks in this file to cfgcmd/opcmd
+directives for command coverage tracking.
+```
+
+RSA can be used for services such as key exchanges and for encryption purposes.
+To make IPSec work with dynamic address on one/both sides, we will have to use
+RSA keys for authentication. They are very fast and easy to setup.
+
+First, on both routers run the operational command "generate pki key-pair
+install \<key-pair nam>>". You may choose different length than 2048 of course.
+
+```none
+vyos@left# run generate pki key-pair install ipsec-LEFT
+Enter private key type: [rsa, dsa, ec] (Default: rsa)
+Enter private key bits: (Default: 2048)
+Note: If you plan to use the generated key on this router, do not encrypt the private key.
+Do you want to encrypt the private key with a passphrase? [y/N] N
+Configure mode commands to install key pair:
+Do you want to install the public key? [Y/n] Y
+set pki key-pair ipsec-LEFT public key 'MIIBIjANBgkqh...'
+Do you want to install the private key? [Y/n] Y
+set pki key-pair ipsec-LEFT private key 'MIIEvgIBADAN...'
+[edit]
+```
+
+Configuration commands will display.
+Note the command with the public key
+(set pki key-pair ipsec-LEFT public key 'MIIBIjANBgkqh...').
+Then do the same on the opposite router:
+
+```none
+vyos@left# run generate pki key-pair install ipsec-RIGHT
+```
+
+Note the command with the public key
+(set pki key-pair ipsec-RIGHT public key 'FAAOCAQ8AMII...').
+
+The noted public keys should be entered on the opposite routers.
+
+On the LEFT:
+
+```none
+set pki key-pair ipsec-RIGHT public key 'FAAOCAQ8AMII...'
+```
+
+On the RIGHT:
+
+```none
+set pki key-pair ipsec-LEFT public key 'MIIBIjANBgkqh...'
+```
+
+Now you are ready to setup IPsec. The key points:
+1. Since both routers do not know their effective public addresses,
+ we set the local-address of the peer to "any".
+2. On the initiator, we set the peer address to its public address,
+ but on the responder we only set the id.
+3. On the initiator, we need to set the remote-id option so that it
+ can identify IKE traffic from the responder correctly.
+4. On the responder, we need to set the local id so that initiator
+ can know who's talking to it for the point #3 to work.
+
+On the LEFT (static address):
+
+```none
+set vpn ipsec interface eth0
+
+set vpn ipsec esp-group MyESPGroup proposal 1 encryption aes128
+set vpn ipsec esp-group MyESPGroup proposal 1 hash sha1
+
+set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group 2
+set vpn ipsec ike-group MyIKEGroup proposal 1 encryption aes128
+set vpn ipsec ike-group MyIKEGroup proposal 1 hash sha1
+
+set vpn ipsec site-to-site peer @RIGHT authentication id LEFT
+set vpn ipsec site-to-site peer @RIGHT authentication mode rsa
+set vpn ipsec site-to-site peer @RIGHT authentication rsa local-key ipsec-LEFT
+set vpn ipsec site-to-site peer @RIGHT authentication rsa remote-key ipsec-RIGHT
+set vpn ipsec site-to-site peer @RIGHT authentication remote-id RIGHT
+set vpn ipsec site-to-site peer @RIGHT default-esp-group MyESPGroup
+set vpn ipsec site-to-site peer @RIGHT ike-group MyIKEGroup
+set vpn ipsec site-to-site peer @RIGHT local-address 192.0.2.10
+set vpn ipsec site-to-site peer @RIGHT connection-type none
+set vpn ipsec site-to-site peer @RIGHT tunnel 1 local prefix 192.168.99.1/32 # Additional loopback address on the local
+set vpn ipsec site-to-site peer @RIGHT tunnel 1 remote prefix 192.168.99.2/32 # Additional loopback address on the remote
+```
+
+On the RIGHT (dynamic address):
+
+```none
+set vpn ipsec interface eth0
+
+set vpn ipsec esp-group MyESPGroup proposal 1 encryption aes128
+set vpn ipsec esp-group MyESPGroup proposal 1 hash sha1
+
+set vpn ipsec ike-group MyIKEGroup proposal 1 dh-group 2
+set vpn ipsec ike-group MyIKEGroup proposal 1 encryption aes128
+set vpn ipsec ike-group MyIKEGroup proposal 1 hash sha1
+
+set vpn ipsec site-to-site peer 192.0.2.10 authentication id RIGHT
+set vpn ipsec site-to-site peer 192.0.2.10 authentication mode rsa
+set vpn ipsec site-to-site peer 192.0.2.10 authentication rsa local-key ipsec-RIGHT
+set vpn ipsec site-to-site peer 192.0.2.10 authentication rsa remote-key ipsec-LEFT
+set vpn ipsec site-to-site peer 192.0.2.10 authentication remote-id LEFT
+set vpn ipsec site-to-site peer 192.0.2.10 connection-type initiate
+set vpn ipsec site-to-site peer 192.0.2.10 default-esp-group MyESPGroup
+set vpn ipsec site-to-site peer 192.0.2.10 ike-group MyIKEGroup
+set vpn ipsec site-to-site peer 192.0.2.10 local-address any
+set vpn ipsec site-to-site peer 192.0.2.10 tunnel 1 local prefix 192.168.99.2/32 # Additional loopback address on the local
+set vpn ipsec site-to-site peer 192.0.2.10 tunnel 1 remote prefix 192.168.99.1/32 # Additional loopback address on the remote
+```
+
diff --git a/docs/configuration/vpn/sstp.md b/docs/configuration/vpn/sstp.md
new file mode 100644
index 00000000..54383cc6
--- /dev/null
+++ b/docs/configuration/vpn/sstp.md
@@ -0,0 +1,698 @@
+(sstp)=
+
+# SSTP Server
+
+{abbr}`SSTP (Secure Socket Tunneling Protocol)` is a form of {abbr}`VPN
+(Virtual Private Network)` tunnel that provides a mechanism to transport PPP
+traffic through an SSL/TLS channel. SSL/TLS provides transport-level security
+with key negotiation, encryption and traffic integrity checking. The use of
+SSL/TLS over TCP port 443 allows SSTP to pass through virtually all firewalls
+and proxy servers except for authenticated web proxies.
+
+SSTP is available for Linux, BSD, and Windows.
+
+VyOS utilizes [accel-ppp](https://accel-ppp.org/) to provide SSTP server functionality. We support both
+local and RADIUS authentication.
+
+As SSTP provides PPP via a SSL/TLS channel the use of either publicly signed
+certificates or private PKI is required.
+
+## Configuring SSTP Server
+
+### Certificates
+
+Using our documentation chapter - {ref}`pki` generate and install CA and Server certificate
+
+```none
+vyos@vyos:~$ generate pki ca install CA
+```
+
+```none
+vyos@vyos:~$ generate pki certificate sign CA install Server
+```
+
+
+### Configuration
+
+```none
+set vpn sstp authentication local-users username test password 'test'
+set vpn sstp authentication mode 'local'
+set vpn sstp client-ip-pool SSTP-POOL range '10.0.0.2-10.0.0.100'
+set vpn sstp default-pool 'SSTP-POOL'
+set vpn sstp gateway-address '10.0.0.1'
+set vpn sstp ssl ca-certificate 'CA1'
+set vpn sstp ssl certificate 'Server'
+```
+
+```{cfgcmd} set vpn sstp authentication mode \<local | radius\>
+
+Set authentication backend. The configured authentication backend is used
+for all queries.
+* **radius**: All authentication queries are handled by a configured RADIUS
+server.
+* **local**: All authentication queries are handled locally.
+```
+
+```{cfgcmd} set vpn sstp authentication local-users username \<user\> password \<pass\>
+
+Create `<user>` for local authentication on this system. The users password
+will be set to `<pass>`.
+```
+
+```{cfgcmd} set vpn sstp client-ip-pool \<POOL-NAME\> range \<x.x.x.x-x.x.x.x | x.x.x.x/x\>
+
+Use this command to define the first IP address of a pool of
+addresses to be given to SSTP clients. If notation ``x.x.x.x-x.x.x.x``,
+it must be within a /24 subnet. If notation ``x.x.x.x/x`` is
+used there is possibility to set host/netmask.
+```
+
+```{cfgcmd} set vpn sstp default-pool \<POOL-NAME\>
+
+Use this command to define default address pool name.
+```
+
+```{cfgcmd} set vpn sstp gateway-address \<gateway\>
+
+Specifies single `<gateway>` IP address to be used as local address of PPP
+interfaces.
+```
+
+```{cfgcmd} set vpn sstp ssl ca-certificate \<file\>
+
+Name of installed certificate authority certificate.
+```
+
+```{cfgcmd} set vpn sstp ssl certificate \<file\>
+
+Name of installed server certificate.
+```
+
+
+## Configuring RADIUS authentication
+
+To enable RADIUS based authentication, the authentication mode needs to be
+changed within the configuration. Previous settings like the local users still
+exist within the configuration, however they are not used if the mode has been
+changed from local to radius. Once changed back to local, it will use all local
+accounts again.
+
+```none
+set vpn sstp authentication mode radius
+```
+
+```{cfgcmd} set vpn sstp authentication radius server \<server\> key \<secret\>
+
+Configure RADIUS `<server>` and its required shared `<secret>` for
+communicating with the RADIUS server.
+```
+
+Since the RADIUS server would be a single point of failure, multiple RADIUS
+servers can be setup and will be used subsequentially.
+For example:
+
+```none
+set vpn sstp authentication radius server 10.0.0.1 key 'foo'
+set vpn sstp authentication radius server 10.0.0.2 key 'foo'
+```
+
+:::{note}
+Some RADIUS severs use an access control list which allows or denies
+queries, make sure to add your VyOS router to the allowed client list.
+:::
+
+### RADIUS source address
+
+If you are using OSPF as your IGP, use the interface connected closest to the
+RADIUS server. You can bind all outgoing RADIUS requests to a single source IP
+e.g. the loopback interface.
+
+```{cfgcmd} set vpn sstp authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+:::{note}
+The `source-address` must be configured to that of an interface.
+Best practice would be a loopback or dummy interface.
+:::
+
+### RADIUS advanced options
+
+```{cfgcmd} set vpn sstp authentication radius server \<server\> port \<port\>
+
+Configure RADIUS `<server>` and its required port for authentication requests.
+```
+
+```{cfgcmd} set vpn sstp authentication radius server \<server\> fail-time \<time\>
+
+Mark RADIUS server as offline for this given `<time>` in seconds.
+```
+
+```{cfgcmd} set vpn sstp authentication radius server \<server\> disable
+
+Temporary disable this RADIUS server.
+```
+
+```{cfgcmd} set vpn sstp authentication radius acct-timeout \<timeout\>
+
+Timeout to wait reply for Interim-Update packets. (default 3 seconds)
+```
+
+```{cfgcmd} set vpn sstp authentication radius dynamic-author server \<address\>
+
+Specifies IP address for Dynamic Authorization Extension server (DM/CoA).
+This IP must exist on any VyOS interface or it can be ``0.0.0.0``.
+```
+
+```{cfgcmd} set vpn sstp authentication radius dynamic-author port \<port\>
+
+UDP port for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn sstp authentication radius dynamic-author key \<secret\>
+
+Secret for Dynamic Authorization Extension server (DM/CoA)
+```
+
+```{cfgcmd} set vpn sstp authentication radius max-try \<number\>
+
+Maximum number of tries to send Access-Request/Accounting-Request queries
+```
+
+```{cfgcmd} set vpn sstp authentication radius timeout \<timeout\>
+
+Timeout to wait response from server (seconds)
+```
+
+```{cfgcmd} set vpn sstp authentication radius nas-identifier \<identifier\>
+
+Value to send to RADIUS server in NAS-Identifier attribute and to be matched
+in DM/CoA requests.
+```
+
+```{cfgcmd} set vpn sstp authentication radius nas-ip-address \<address\>
+
+Value to send to RADIUS server in NAS-IP-Address attribute and to be matched
+in DM/CoA requests. Also DM/CoA server will bind to that address.
+```
+
+```{cfgcmd} set vpn sstp authentication radius source-address \<address\>
+
+Source IPv4 address used in all RADIUS server queires.
+```
+
+```{cfgcmd} set vpn sstp authentication radius rate-limit attribute \<attribute\>
+
+Specifies which RADIUS server attribute contains the rate limit information.
+The default attribute is `Filter-Id`.
+```
+
+:::{note}
+If you set a custom RADIUS attribute you must define it on both
+dictionaries on the RADIUS server and client.
+:::
+
+```{cfgcmd} set vpn sstp authentication radius rate-limit enable
+
+Enables bandwidth shaping via RADIUS.
+```
+
+```{cfgcmd} set vpn sstp authentication radius rate-limit vendor
+
+Specifies the vendor dictionary, This dictionary needs to be present in
+/usr/share/accel-ppp/radius.
+```
+
+Received RADIUS attributes have a higher priority than parameters defined within
+the CLI configuration, refer to the explanation below.
+
+### Allocation clients ip addresses by RADIUS
+
+If the RADIUS server sends the attribute `Framed-IP-Address` then this IP
+address will be allocated to the client and the option `default-pool` within
+the CLI config will being ignored.
+
+If the RADIUS server sends the attribute `Framed-Pool`, then the IP address
+will be allocated from a predefined IP pool whose name equals the attribute
+value.
+
+If the RADIUS server sends the attribute `Stateful-IPv6-Address-Pool`, the
+IPv6 address will be allocated from a predefined IPv6 pool `prefix` whose
+name equals the attribute value.
+
+If the RADIUS server sends the attribute `Delegated-IPv6-Prefix-Pool`, an
+IPv6 delegation prefix will be allocated from a predefined IPv6 pool `delegate`
+whose name equals the attribute value.
+
+:::{note}
+`Stateful-IPv6-Address-Pool` and `Delegated-IPv6-Prefix-Pool` are defined in
+RFC6911. If they are not defined in your RADIUS server, add new [dictionary].
+:::
+
+The client's interface can be put into a VRF context via a RADIUS Access-Accept
+packet, or changed via RADIUS CoA. `Accel-VRF-Name` is used for these
+purposes. This is a custom [ACCEL-PPP attribute]. Define it in your RADIUS
+server.
+
+### Renaming clients interfaces by RADIUS
+
+If the RADIUS server uses the attribute `NAS-Port-Id`, ppp tunnels will be
+renamed.
+
+:::{note}
+The value of the attribute `NAS-Port-Id` must be less than 16
+characters, otherwise the interface won't be renamed.
+:::
+
+## IPv6
+
+```{cfgcmd} set vpn sstp ppp-options ipv6 \<require | prefer | allow | deny\>
+
+Specifies IPv6 negotiation preference.
+* **require** - Require IPv6 negotiation
+* **prefer** - Ask client for IPv6 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv6 only if client requests
+* **deny** - Do not negotiate IPv6 (default value)
+```
+
+```{cfgcmd} set vpn sstp client-ipv6-pool \<IPv6-POOL-NAME\> prefix \<address\> mask \<number-of-bits\>
+
+Use this comand to set the IPv6 address pool from which an SSTP client will
+get an IPv6 prefix of your defined length (mask) to terminate the SSTP
+endpoint at their side. The mask length can be set between 48 and 128 bits
+long, the default value is 64.
+```
+
+```{cfgcmd} set vpn sstp client-ipv6-pool \<IPv6-POOL-NAME\> delegate \<address\> delegation-prefix \<number-of-bits\>
+
+Use this command to configure DHCPv6 Prefix Delegation (RFC3633) on SSTP. You
+will have to set your IPv6 pool and the length of the delegation prefix. From
+the defined IPv6 pool you will be handing out networks of the defined length
+(delegation-prefix). The length of the delegation prefix can be set between
+32 and 64 bits long.
+```
+
+```{cfgcmd} set vpn sstp default-ipv6-pool \<IPv6-POOL-NAME\>
+
+Use this command to define default IPv6 address pool name.
+```
+
+```none
+set vpn sstp ppp-options ipv6 allow
+set vpn sstp client-ipv6-pool IPv6-POOL delegate '2001:db8:8003::/48' delegation-prefix '56'
+set vpn sstp client-ipv6-pool IPv6-POOL prefix '2001:db8:8002::/48' mask '64'
+set vpn sstp default-ipv6-pool IPv6-POOL
+```
+
+
+### IPv6 Advanced Options
+
+```{cfgcmd} set vpn sstp ppp-options ipv6-accept-peer-interface-id
+
+Accept peer interface identifier. By default this is not defined.
+```
+
+```{cfgcmd} set vpn sstp ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies if a fixed or random interface identifier is used for IPv6. The
+default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+```
+
+```{cfgcmd} set vpn sstp ppp-options ipv6-interface-id \<random | x:x:x:x\>
+
+Specifies the peer interface identifier for IPv6. The default is fixed.
+* **random** - Random interface identifier for IPv6
+* **x:x:x:x** - Specify interface identifier for IPv6
+* **ipv4-addr** - Calculate interface identifier from IPv4 address.
+* **calling-sid** - Calculate interface identifier from calling-station-id.
+```
+
+
+## Scripting
+
+```{cfgcmd} set vpn sstp extended-scripts on-change \<path_to_script\>
+
+Script to run when the session interface is changed by RADIUS CoA handling
+```
+
+```{cfgcmd} set vpn sstp extended-scripts on-down \<path_to_script\>
+
+Script to run when the session interface about to terminate
+```
+
+```{cfgcmd} set vpn sstp extended-scripts on-pre-up \<path_to_script\>
+
+Script to run before the session interface comes up
+```
+
+```{cfgcmd} set vpn sstp extended-scripts on-up \<path_to_script\>
+
+Script to run when the session interface is completely configured and started
+```
+
+
+## Advanced Options
+
+### Authentication Advanced Options
+
+```{cfgcmd} set vpn sstp authentication local-users username \<user\> disable
+
+Disable `<user>` account.
+```
+
+```{cfgcmd} set vpn sstp authentication local-users username \<user\> static-ip \<address\>
+
+Assign a static IP address to `<user>` account.
+```
+
+```{cfgcmd} set vpn sstp authentication local-users username \<user\> rate-limit download \<bandwidth\>
+
+Rate limit the download bandwidth for `<user>` to `<bandwidth>` kbit/s.
+```
+
+```{cfgcmd} set vpn sstp authentication local-users username \<user\> rate-limit upload \<bandwidth\>
+
+Rate limit the upload bandwidth for `<user>` to `<bandwidth>` kbit/s.
+```
+
+```{cfgcmd} set vpn sstp authentication protocols \<pap | chap | mschap | mschap-v2\>
+
+Require the peer to authenticate itself using one of the following protocols:
+pap, chap, mschap, mschap-v2.
+```
+
+
+### Client IP Pool Advanced Options
+
+```{cfgcmd} set vpn sstp client-ip-pool \<POOL-NAME\> next-pool \<NEXT-POOL-NAME\>
+
+Use this command to define the next address pool name.
+```
+
+
+### PPP Advanced Options
+
+```{cfgcmd} set vpn sstp ppp-options disable-ccp
+
+Disable Compression Control Protocol (CCP).
+CCP is enabled by default.
+```
+
+```{cfgcmd} set vpn sstp ppp-options interface-cache \<number\>
+
+Specifies number of interfaces to cache. This prevents interfaces from being
+removed once the corresponding session is destroyed. Instead, interfaces are
+cached for later use in new sessions. This should reduce the kernel-level
+interface creation/deletion rate.
+Default value is **0**.
+```
+
+```{cfgcmd} set vpn sstp ppp-options ipv4 \<require | prefer | allow | deny\>
+
+Specifies IPv4 negotiation preference.
+* **require** - Require IPv4 negotiation
+* **prefer** - Ask client for IPv4 negotiation, do not fail if it rejects
+* **allow** - Negotiate IPv4 only if client requests (Default value)
+* **deny** - Do not negotiate IPv4
+```
+
+```{cfgcmd} set vpn sstp ppp-options lcp-echo-failure \<number\>
+
+Defines the maximum `<number>` of unanswered echo requests. Upon reaching the
+value `<number>`, the session will be reset. Default value is **3**.
+```
+
+```{cfgcmd} set vpn sstp ppp-options lcp-echo-interval \<interval\>
+
+If this option is specified and is greater than 0, then the PPP module will
+send LCP echo requests every `<interval>` seconds.
+Default value is **30**.
+```
+
+```{cfgcmd} set vpn sstp ppp-options lcp-echo-timeout
+
+Specifies timeout in seconds to wait for any peer activity. If this option is
+specified it turns on adaptive lcp echo functionality and "lcp-echo-failure"
+is not used. Default value is **0**.
+```
+
+```{cfgcmd} set vpn sstp ppp-options min-mtu \<number\>
+
+Defines the minimum acceptable MTU. If a client tries to negotiate an MTU
+lower than this it will be NAKed, and disconnected if it rejects a greater
+MTU.
+Default value is **100**.
+```
+
+```{cfgcmd} set vpn sstp ppp-options mppe \<require | prefer | deny\>
+
+Specifies {abbr}`MPPE (Microsoft Point-to-Point Encryption)` negotiation
+preference.
+* **require** - ask client for mppe, if it rejects drop connection
+* **prefer** - ask client for mppe, if it rejects don't fail. (Default value)
+* **deny** - deny mppe
+
+Default behavior - don't ask the client for mppe, but allow it if the client
+wants. Please note that RADIUS may override this option by MS-MPPE-Encryption-Policy
+attribute.
+```
+
+```{cfgcmd} set vpn sstp ppp-options mru \<number\>
+
+Defines preferred MRU. By default is not defined.
+```
+
+
+### Global Advanced options
+
+```{cfgcmd} set vpn sstp description \<description\>
+
+Set description.
+```
+
+```{cfgcmd} set vpn sstp limits burst \<value\>
+
+Burst count
+```
+
+```{cfgcmd} set vpn sstp limits connection-limit \<value\>
+
+Maximum accepted connection rate (e.g. 1/min, 60/sec)
+```
+
+```{cfgcmd} set vpn sstp limits timeout \<value\>
+
+Timeout in seconds
+```
+
+```{cfgcmd} set vpn sstp mtu
+
+Maximum Transmission Unit (MTU) (default: **1500**)
+```
+
+```{cfgcmd} set vpn sstp max-concurrent-sessions
+
+Maximum number of concurrent session start attempts
+```
+
+```{cfgcmd} set vpn sstp name-server \<address\>
+
+Connected clients should use `<address>` as their DNS server. This command
+accepts both IPv4 and IPv6 addresses. Up to two nameservers can be configured
+for IPv4, up to three for IPv6.
+```
+
+```{cfgcmd} set vpn sstp shaper fwmark \<1-2147483647\>
+
+Match firewall mark value
+```
+
+```{cfgcmd} set vpn sstp snmp master-agent
+
+Enable SNMP
+```
+
+```{cfgcmd} set vpn sstp wins-server \<address\>
+
+Windows Internet Name Service (WINS) servers propagated to client
+```
+
+```{cfgcmd} set vpn sstp host-name \<hostname\>
+
+If this option is given, only SSTP connections to the specified host
+and with the same TLS SNI will be allowed.
+```
+
+
+## Configuring SSTP client
+
+Once you have setup your SSTP server there comes the time to do some basic
+testing. The Linux client used for testing is called [sstpc]. [sstpc] requires a
+PPP configuration/peer file.
+
+If you use a self-signed certificate, do not forget to install CA on the client side.
+
+The following PPP configuration tests MSCHAP-v2:
+
+```none
+$ cat /etc/ppp/peers/vyos
+usepeerdns
+#require-mppe
+#require-pap
+require-mschap-v2
+noauth
+lock
+refuse-pap
+refuse-eap
+refuse-chap
+refuse-mschap
+#refuse-mschap-v2
+nobsdcomp
+nodeflate
+debug
+```
+
+You can now "dial" the peer with the follwoing command: `sstpc --log-level 4
+--log-stderr --user vyos --password vyos vpn.example.com -- call vyos`.
+
+A connection attempt will be shown as:
+
+```none
+$ sstpc --log-level 4 --log-stderr --user vyos --password vyos vpn.example.com -- call vyos
+
+Mar 22 13:29:12 sstpc[12344]: Resolved vpn.example.com to 192.0.2.1
+Mar 22 13:29:12 sstpc[12344]: Connected to vpn.example.com
+Mar 22 13:29:12 sstpc[12344]: Sending Connect-Request Message
+Mar 22 13:29:12 sstpc[12344]: SEND SSTP CRTL PKT(14)
+Mar 22 13:29:12 sstpc[12344]: TYPE(1): CONNECT REQUEST, ATTR(1):
+Mar 22 13:29:12 sstpc[12344]: ENCAP PROTO(1): 6
+Mar 22 13:29:12 sstpc[12344]: RECV SSTP CRTL PKT(48)
+Mar 22 13:29:12 sstpc[12344]: TYPE(2): CONNECT ACK, ATTR(1):
+Mar 22 13:29:12 sstpc[12344]: CRYPTO BIND REQ(4): 40
+Mar 22 13:29:12 sstpc[12344]: Started PPP Link Negotiation
+Mar 22 13:29:15 sstpc[12344]: Sending Connected Message
+Mar 22 13:29:15 sstpc[12344]: SEND SSTP CRTL PKT(112)
+Mar 22 13:29:15 sstpc[12344]: TYPE(4): CONNECTED, ATTR(1):
+Mar 22 13:29:15 sstpc[12344]: CRYPTO BIND(3): 104
+Mar 22 13:29:15 sstpc[12344]: Connection Established
+
+$ ip addr show ppp0
+164: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1452 qdisc fq_codel state UNKNOWN group default qlen 3
+ link/ppp promiscuity 0
+ inet 100.64.2.2 peer 100.64.1.1/32 scope global ppp0
+ valid_lft forever preferred_lft forever
+```
+
+
+## Monitoring
+
+```{opcmd} show sstp-server sessions
+
+Use this command to locally check the active sessions in the SSTP
+server.
+```
+
+```none
+vyos@vyos:~$ show sstp-server sessions
+ ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
+--------+----------+----------+-----+--------+----------------+------------+--------+----------+----------+----------
+ sstp0 | test | 10.0.0.2 | | | 192.168.10.100 | | active | 00:15:46 | 16.3 KiB | 210 B
+```
+
+```none
+vyos@vyos:~$ show sstp-server statistics
+ uptime: 0.01:21:54
+cpu: 0%
+mem(rss/virt): 6688/100464 kB
+core:
+ mempool_allocated: 149420
+ mempool_available: 146092
+ thread_count: 1
+ thread_active: 1
+ context_count: 6
+ context_sleeping: 0
+ context_pending: 0
+ md_handler_count: 7
+ md_handler_pending: 0
+ timer_count: 2
+ timer_pending: 0
+sessions:
+ starting: 0
+ active: 1
+ finishing: 0
+sstp:
+ starting: 0
+ active: 1
+```
+
+
+## Troubleshooting
+
+```none
+vyos@vyos:~$sudo journalctl -u accel-ppp@sstp -b 0
+
+Feb 28 17:03:04 vyos accel-sstp[2492]: sstp: new connection from 192.168.10.100:49852
+Feb 28 17:03:04 vyos accel-sstp[2492]: sstp: starting
+Feb 28 17:03:04 vyos accel-sstp[2492]: sstp: started
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [HTTP <SSTP_DUPLEX_POST /sra_{BA195980-CD49-458b-9E23-C84EE0ADCD75}/ HTTP/1.1>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [HTTP <SSTPCORRELATIONID: {48B82435-099A-4158-A987-052E7570CFAA}>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [HTTP <Content-Length: 18446744073709551615>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [HTTP <Host: vyos.io>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [HTTP <HTTP/1.1 200 OK>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [HTTP <Date: Wed, 28 Feb 2024 17:03:04 GMT>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [HTTP <Content-Length: 18446744073709551615>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [SSTP SSTP_MSG_CALL_CONNECT_REQUEST]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [SSTP SSTP_MSG_CALL_CONNECT_ACK]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: lcp_layer_init
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: auth_layer_init
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: ccp_layer_init
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: ipcp_layer_init
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: ipv6cp_layer_init
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: ppp establishing
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: lcp_layer_start
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [LCP ConfReq id=56 <auth PAP> <mru 1452> <magic 1cd9ad05>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [LCP ConfReq id=0 <mru 4091> <magic 345f64ca> <pcomp> <accomp> < d 3 6 >]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [LCP ConfRej id=0 <pcomp> <accomp> < d 3 6 >]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [LCP ConfReq id=1 <mru 4091> <magic 345f64ca>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [LCP ConfNak id=1 <mru 1452>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: recv [LCP ConfReq id=2 <mru 1452> <magic 345f64ca>]
+Feb 28 17:03:04 vyos accel-sstp[2492]: :: send [LCP ConfAck id=2]
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: fsm timeout 9
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: send [LCP ConfReq id=56 <auth PAP> <mru 1452> <magic 1cd9ad05>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: recv [LCP ConfAck id=56 <auth PAP> <mru 1452> <magic 1cd9ad05>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: lcp_layer_started
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: auth_layer_start
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: recv [LCP Ident id=3 <MSRASV5.20>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: recv [LCP Ident id=4 <MSRAS-0-MSEDGEWIN10>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: [50B blob data]
+Feb 28 17:03:07 vyos accel-sstp[2492]: :: recv [PAP AuthReq id=3]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: connect: ppp0 <--> sstp(192.168.10.100:49852)
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: ppp connected
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [PAP AuthAck id=3 "Authentication succeeded"]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: test: authentication succeeded
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: auth_layer_started
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: ccp_layer_start
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: ipcp_layer_start
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: ipv6cp_layer_start
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: recv [SSTP SSTP_MSG_CALL_CONNECTED]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: IPV6CP: discarding packet
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [LCP ProtoRej id=88 <8057>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: recv [IPCP ConfReq id=7 <addr 0.0.0.0> <dns1 0.0.0.0> <wins1 0.0.0.0> <dns2 0.0.0.0> <wins2 0.0.0.0>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [IPCP ConfReq id=25 <addr 10.0.0.1>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [IPCP ConfRej id=7 <dns1 0.0.0.0> <wins1 0.0.0.0> <dns2 0.0.0.0> <wins2 0.0.0.0>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: recv [IPCP ConfAck id=25 <addr 10.0.0.1>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: recv [IPCP ConfReq id=8 <addr 0.0.0.0>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [IPCP ConfNak id=8 <addr 10.0.0.5>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: recv [IPCP ConfReq id=9 <addr 10.0.0.5>]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: send [IPCP ConfAck id=9]
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: ipcp_layer_started
+Feb 28 17:03:07 vyos accel-sstp[2492]: ppp0:test: rename interface to 'sstp0'
+Feb 28 17:03:07 vyos accel-sstp[2492]: sstp0:test: sstp: ppp: started
+```
+
+[accel-ppp attribute]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.accel
+[dictionary]: https://github.com/accel-ppp/accel-ppp/blob/master/accel-pppd/radius/dict/dictionary.rfc6911
+[sstpc]: https://github.com/reliablehosting/sstp-client
diff --git a/docs/configuration/vrf/index.md b/docs/configuration/vrf/index.md
new file mode 100644
index 00000000..d679d1c9
--- /dev/null
+++ b/docs/configuration/vrf/index.md
@@ -0,0 +1,646 @@
+---
+lastproofread: '2021-07-07'
+---
+
+(vrf)=
+
+# VRF
+
+{abbr}`VRF (Virtual Routing and Forwarding)` devices combined with ip rules
+provides the ability to create virtual routing and forwarding domains (aka
+VRFs, VRF-lite to be specific) in the Linux network stack. One use case is the
+multi-tenancy problem where each tenant has their own unique routing tables and
+in the very least need different default gateways.
+
+## Configuration
+
+A VRF device is created with an associated route table. Network interfaces are
+then enslaved to a VRF device.
+
+```{cfgcmd} set vrf name \<name\> table \<id\>
+
+Create a new VRF instance with `<name>` and `<id>`. The name is used when placing
+individual interfaces into the VRF.
+
+:::{note}
+A routing table ID can not be modified once it is assigned. It can
+only be changed by deleting and re-adding the VRF instance.
+:::
+```
+
+```{cfgcmd} set vrf bind-to-all
+
+By default the scope of the port bindings for unbound sockets is limited to
+the default VRF. That is, it will not be matched by packets arriving on
+interfaces enslaved to a VRF and processes may bind to the same port if
+they bind to a VRF.
+
+TCP & UDP services running in the default VRF context (ie., not bound to any
+VRF device) can work across all VRF domains by enabling this option.
+```
+
+### Zebra/Kernel route filtering
+
+
+Zebra supports prefix-lists and Route Maps to match routes received from
+other FRR components. The permit/deny facilities provided by these commands
+can be used to filter which routes zebra will install in the kernel.
+
+```{cfgcmd} set vrf \<name\> ip protocol \<protocol\> route-map \<route-map\>
+
+Apply a route-map filter to routes for the specified protocol.
+
+The following protocols can be used: any, babel, bgp, eigrp,
+isis, ospf, rip, static
+
+:::{note}
+If you choose any as the option that will cause all protocols that
+are sending routes to zebra.
+:::
+```
+
+
+```{cfgcmd} set vrf \<name\> ipv6 protocol \<protocol\> route-map \<route-map\>
+
+Apply a route-map filter to routes for the specified protocol.
+
+The following protocols can be used: any, babel, bgp, isis,
+ospfv3, ripng, static
+
+:::{note}
+If you choose any as the option that will cause all protocols that
+are sending routes to zebra.
+:::
+```
+
+### Nexthop Tracking
+
+
+Nexthop tracking resolve nexthops via the default route by default. This is enabled
+by default for a traditional profile of FRR which we use. It and can be disabled if
+you do not want to e.g. allow BGP to peer across the default route.
+
+```{cfgcmd} set vrf name \<name\> ip nht no-resolve-via-default
+
+Do not allow IPv4 nexthop tracking to resolve via the default route. This
+parameter is configured per-VRF, so the command is also available in the VRF
+subnode.
+```
+
+
+```{cfgcmd} set vrf name \<name\> ipv6 nht no-resolve-via-default
+
+Do not allow IPv6 nexthop tracking to resolve via the default route. This
+parameter is configured per-VRF, so the command is also available in the VRF
+subnode.
+```
+
+### Interfaces
+
+
+When VRFs are used it is not only mandatory to create a VRF but also the VRF
+itself needs to be assigned to an interface.
+
+```{cfgcmd} set interfaces \<dummy | ethernet | bonding | bridge | pppoe\> \<interface\> vrf \<name\>
+
+Assign interface identified by `<interface>` to VRF named `<name>`.
+```
+
+### Routing
+
+
+:::{note}
+VyOS 1.4 (sagitta) introduced dynamic routing support for VRFs.
+:::
+
+
+Currently dynamic routing is supported for the following protocols:
+
+
+- {ref}`routing-bgp`
+- {ref}`routing-isis`
+- {ref}`routing-ospf`
+- {ref}`routing-ospfv3`
+- {ref}`routing-static`
+
+
+The CLI configuration is same as mentioned in above articles. The only
+difference is, that each routing protocol used, must be prefixed with the `vrf
+name <name>` command.
+
+
+#### Example
+
+
+The following commands would be required to set options for a given dynamic
+routing protocol inside a given vrf:
+
+
+- {ref}`routing-bgp`: `set vrf name <name> protocols bgp ...`
+- {ref}`routing-isis`: `set vrf name <name> protocols isis ...`
+- {ref}`routing-ospf`: `set vrf name <name> protocols ospf ...`
+- {ref}`routing-ospfv3`: `set vrf name <name> protocols ospfv3 ...`
+- {ref}`routing-static`: `set vrf name <name> protocols static ...`
+
+
+### Services
+
+
+Currently the following services can be created isolated in VRFs
+
+
+- {ref}`dhcp-server`
+
+
+The CLI configuration is same as mentioned in above articles. The only
+difference is, that each service used, must be prefixed with the `vrf
+name <name>` command.
+
+
+#### Example
+
+
+The following commands would be required to set options for a given service
+inside a given vrf:
+
+
+- {ref}`dhcp-server`: `set vrf name <name> service dhcp-server ...`
+- {ref}`dhcp-server`: `set vrf name <name> service dhcpv6-server ...`
+
+
+## Operation
+
+
+It is not sufficient to only configure a VRF but VRFs must be maintained, too.
+For VRF maintenance the following operational commands are in place.
+
+```{opcmd} show vrf
+
+Lists VRFs that have been created
+
+:::{code-block} none
+vyos@vyos:~$ show vrf
+VRF name state mac address flags interfaces
+-------- ----- ----------- ----- ----------
+blue up 00:53:12:d8:74:24 noarp,master,up,lower_up dum200,eth0.302
+red up 00:53:de:02:df:aa noarp,master,up,lower_up dum100,eth0.300,bond0.100,peth0
+:::
+:::{note}
+Command should probably be extended to list also the real
+interfaces assigned to this one VRF to get a better overview.
+:::
+```
+
+
+```{opcmd} show vrf \<name\>
+
+:::{code-block} none
+vyos@vyos:~$ show vrf name blue
+VRF name state mac address flags interfaces
+-------- ----- ----------- ----- ----------
+blue up 00:53:12:d8:74:24 noarp,master,up,lower_up dum200,eth0.302
+:::
+```
+
+
+```{opcmd} show ip route vrf \<name\>
+
+Display IPv4 routing table for VRF identified by `<name>`.
+
+:::{code-block} none
+vyos@vyos:~$ show ip route vrf blue
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+VRF blue:
+K 0.0.0.0/0 [255/8192] unreachable (ICMP unreachable), 00:00:50
+S>* 172.16.0.0/16 [1/0] via 192.0.2.1, dum1, 00:00:02
+C>* 192.0.2.0/24 is directly connected, dum1, 00:00:06
+:::
+```
+```{opcmd} show ipv6 route vrf \<name\>
+
+Display IPv6 routing table for VRF identified by `<name>`.
+
+:::{code-block} none
+vyos@vyos:~$ show ipv6 route vrf red
+Codes: K - kernel route, C - connected, S - static, R - RIPng,
+ O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
+ v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR,
+ f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+VRF red:
+K ::/0 [255/8192] unreachable (ICMP unreachable), 00:43:20
+C>* 2001:db8::/64 is directly connected, dum1, 00:02:19
+C>* fe80::/64 is directly connected, dum1, 00:43:19
+K>* ff00::/8 [0/256] is directly connected, dum1, 00:43:19
+:::
+```
+```{opcmd} ping \<host\> vrf \<name\>
+
+ The ping command is used to test whether a network host is reachable or not.
+
+ Ping uses ICMP protocol's mandatory ECHO_REQUEST datagram to elicit an
+ ICMP ECHO_RESPONSE from a host or gateway. ECHO_REQUEST datagrams (pings)
+ will have an IP and ICMP header, followed by "struct timeval" and an
+ arbitrary number of pad bytes used to fill out the packet.
+
+ When doing fault isolation with ping, you should first run it on the local
+ host, to verify that the local network interface is up and running. Then,
+ continue with hosts and gateways further down the road towards your
+ destination. Round-trip time and packet loss statistics are computed.
+
+ Duplicate packets are not included in the packet loss calculation, although
+ the round-trip time of these packets is used in calculating the minimum/
+ average/maximum round-trip time numbers.
+
+ :::{note}
+ Ping command can be interrupted at any given time using ``<Ctrl>+c``.
+ A brief statistic is shown afterwards.
+ :::
+
+ :::{code-block} none
+ vyos@vyos:~$ ping 192.0.2.1 vrf red
+ PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
+ 64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.070 ms
+ 64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=0.078 ms
+ ^C
+ --- 192.0.2.1 ping statistics ---
+ 2 packets transmitted, 2 received, 0% packet loss, time 4ms
+ rtt min/avg/max/mdev = 0.070/0.074/0.078/0.004 ms
+ :::
+```
+
+
+```{opcmd} traceroute vrf \<name\> [ipv4 | ipv6] \<host\>
+
+Displays the route packets taken to a network host utilizing VRF instance
+identified by `<name>`. When using the IPv4 or IPv6 option, displays the
+route packets taken to the given hosts IP address family. This option is
+useful when the host is specified as a hostname rather than an IP address.
+```
+
+
+```{opcmd} force vrf \<name\>
+
+Join a given VRF. This will open a new subshell within the specified VRF.
+
+The prompt is adjusted to reflect this change in both config and op-mode.
+
+:::{code-block} none
+vyos@vyos:~$ force vrf blue
+vyos@vyos(vrf:blue):~$
+:::
+```
+
+(vrf-example)=
+
+
+## Example
+
+
+### VRF route leaking
+
+
+The following example topology was built using EVE-NG.
+
+
+```{eval-rst}
+.. figure:: /_static/images/vrf-example-topology-01.webp
+ :alt: VRF topology example
+
+
+ VRF route leaking
+```
+
+
+- PC1 is in the `default` VRF and acting as e.g. a "fileserver"
+- PC2 is in VRF `blue` which is the development department
+- PC3 and PC4 are connected to a bridge device on router `R1` which is in VRF
+ `red`. Say this is the HR department.
+- R1 is managed through an out-of-band network that resides in VRF `mgmt`
+
+
+(vrf-example-configuration)=
+
+
+#### Configuration
+
+
+```none
+set interfaces bridge br10 address '10.30.0.254/24'
+set interfaces bridge br10 member interface eth3
+set interfaces bridge br10 member interface eth4
+set interfaces bridge br10 vrf 'red'
+
+set interfaces ethernet eth0 address 'dhcp'
+set interfaces ethernet eth0 vrf 'mgmt'
+set interfaces ethernet eth1 address '10.0.0.254/24'
+set interfaces ethernet eth2 address '10.20.0.254/24'
+set interfaces ethernet eth2 vrf 'blue'
+
+set protocols static route 10.20.0.0/24 interface eth2 vrf 'blue'
+set protocols static route 10.30.0.0/24 interface br10 vrf 'red'
+
+set service ssh disable-host-validation
+set service ssh vrf 'mgmt'
+
+set system name-server 'eth0'
+
+set vrf name blue protocols static route 10.0.0.0/24 interface eth1 vrf 'default'
+set vrf name blue table '3000'
+set vrf name mgmt table '1000'
+set vrf name red protocols static route 10.0.0.0/24 interface eth1 vrf 'default'
+set vrf name red table '2000'
+```
+
+### VRF and NAT
+
+
+(vrf-nat-configuration)=
+
+
+#### Configuration
+
+
+```none
+set interfaces ethernet eth0 address '172.16.50.12/24'
+set interfaces ethernet eth0 vrf 'red'
+
+set interfaces ethernet eth1 address '192.168.130.100/24'
+set interfaces ethernet eth1 vrf 'blue'
+
+set nat destination rule 110 description 'NAT ssh- INSIDE'
+set nat destination rule 110 destination port '2022'
+set nat destination rule 110 inbound-interface name 'eth0'
+set nat destination rule 110 protocol 'tcp'
+set nat destination rule 110 translation address '192.168.130.40'
+
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 protocol 'all'
+set nat source rule 100 source address '192.168.130.0/24'
+set nat source rule 100 translation address 'masquerade'
+
+set service ssh vrf 'red'
+
+set vrf bind-to-all
+set vrf name blue protocols static route 0.0.0.0/0 next-hop 172.16.50.1 vrf 'red'
+set vrf name blue protocols static route 172.16.50.0/24 interface eth0 vrf 'red'
+set vrf name blue table '1010'
+
+set vrf name red protocols static route 0.0.0.0/0 next-hop 172.16.50.1
+set vrf name red protocols static route 192.168.130.0/24 interface eth1 vrf 'blue'
+set vrf name red table '2020'
+```
+
+(vrf-example-operation)=
+
+
+#### Operation
+
+
+After committing the configuration we can verify all leaked routes are
+installed, and try to ICMP ping PC1 from PC3.
+
+
+```none
+PCS> ping 10.0.0.1
+
+84 bytes from 10.0.0.1 icmp_seq=1 ttl=63 time=1.943 ms
+84 bytes from 10.0.0.1 icmp_seq=2 ttl=63 time=1.618 ms
+84 bytes from 10.0.0.1 icmp_seq=3 ttl=63 time=1.745 ms
+```
+
+```none
+VPCS> show ip
+NAME : VPCS[1]
+IP/MASK : 10.30.0.1/24
+GATEWAY : 10.30.0.254
+DNS :
+MAC : 00:50:79:66:68:0f
+```
+
+###### VRF default routing table
+
+
+```none
+vyos@R1:~$ show ip route
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+C>* 10.0.0.0/24 is directly connected, eth1, 00:07:44
+S>* 10.20.0.0/24 [1/0] is directly connected, eth2 (vrf blue), weight 1, 00:07:38
+S>* 10.30.0.0/24 [1/0] is directly connected, br10 (vrf red), weight 1, 00:07:38
+```
+
+###### VRF red routing table
+
+
+```none
+vyos@R1:~$ show ip route vrf red
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+VRF red:
+K>* 0.0.0.0/0 [255/8192] unreachable (ICMP unreachable), 00:07:57
+S>* 10.0.0.0/24 [1/0] is directly connected, eth1 (vrf default), weight 1, 00:07:40
+C>* 10.30.0.0/24 is directly connected, br10, 00:07:54
+```
+
+###### VRF blue routing table
+
+
+```none
+vyos@R1:~$ show ip route vrf blue
+Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued, r - rejected, b - backup
+
+VRF blue:
+K>* 0.0.0.0/0 [255/8192] unreachable (ICMP unreachable), 00:08:00
+S>* 10.0.0.0/24 [1/0] is directly connected, eth1 (vrf default), weight 1, 00:07:44
+C>* 10.20.0.0/24 is directly connected, eth2, 00:07:53
+```
+
+# L3VPN VRFs
+
+
+{abbr}`L3VPN VRFs ( Layer 3 Virtual Private Networks )` bgpd supports for
+IPv4 RFC 4364 and IPv6 RFC 4659. L3VPN routes, and their associated VRF
+MPLS labels, can be distributed to VPN SAFI neighbors in the default, i.e.,
+non VRF, BGP instance. VRF MPLS labels are reached using core MPLS labels
+which are distributed using LDP or BGP labeled unicast.
+bgpd also supports inter-VRF route leaking.
+
+
+(l3vpn-vrf-route-leaking)=
+
+
+## VRF Route Leaking
+
+
+BGP routes may be leaked (i.e. copied) between a unicast VRF RIB and the VPN
+SAFI RIB of the default VRF for use in MPLS-based L3VPNs. Unicast routes may
+also be leaked between any VRFs (including the unicast RIB of the default BGP
+instance). A shortcut syntax is also available for specifying leaking from
+one VRF to another VRF using the default instance’s VPN RIB as the intemediary
+. A common application of the VRF-VRF feature is to connect a customer’s
+private routing domain to a provider’s VPN service. Leaking is configured from
+the point of view of an individual VRF: import refers to routes leaked from VPN
+to a unicast VRF, whereas export refers to routes leaked from a unicast VRF to
+VPN.
+
+
+:::{note}
+Routes exported from a unicast VRF to the VPN RIB must be augmented
+by two parameters:
+
+
+> an RD / RTLIST
+
+
+Configuration for these exported routes must, at a minimum, specify
+these two parameters.
+:::
+
+
+(l3vpn-vrf-example-configuration)=
+
+
+## Configuration
+
+
+Configuration of route leaking between a unicast VRF RIB and the VPN SAFI RIB
+of the default VRF is accomplished via commands in the context of a VRF
+address-family.
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> rd vpn export \<asn:nn|address:nn\>
+
+Specifies the route distinguisher to be added to a route exported from the
+current unicast VRF to VPN.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> route-target vpn \<import|export|both\> [RTLIST]
+
+Specifies the route-target list to be attached to a route (export) or the
+route-target list to match against (import) when exporting/importing
+between the current unicast VRF and VPN.The RTLIST is a space-separated
+list of route-targets, which are BGP extended community values as
+described in Extended Communities Attribute.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> label vpn export \<0-1048575|auto\>
+
+Enables an MPLS label to be attached to a route exported from the current
+unicast VRF to VPN. If the value specified is auto, the label value is
+automatically assigned from a pool maintained.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> label vpn allocation-mode per-nexthop
+
+Select how labels are allocated in the given VRF. By default, the per-vrf
+mode is selected, and one label is used for all prefixes from the VRF. The
+per-nexthop will use a unique label for all prefixes that are reachable via
+the same nexthop.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> route-map vpn \<import|export\> [route-map \<name\>]
+
+Specifies an optional route-map to be applied to routes imported or
+exported between the current unicast VRF and VPN.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> \<import|export\> vpn
+
+Enables import or export of routes between the current unicast VRF and VPN.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> import vrf \<name\>
+
+Shortcut syntax for specifying automatic leaking from vrf VRFNAME to the
+current VRF using the VPN RIB as intermediary. The RD and RT are auto
+derived and should not be specified explicitly for either the source or
+destination VRF’s.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp address-family \<ipv4-unicast|ipv6-unicast\> route-map vrf import [route-map \<name\>]
+
+Specifies an optional route-map to be applied to routes imported from VRFs.
+```
+
+
+```{cfgcmd} set vrf name \<name\> protocols bgp interface \<interface\> mpls forwarding
+
+It is possible to permit BGP install VPN prefixes without transport labels.
+This configuration will install VPN prefixes originated from an e-bgp session,
+and with the next-hop directly connected.
+```
+
+(l3vpn-vrf-example-operation)=
+
+
+## Operation
+
+
+It is not sufficient to only configure a L3VPN VRFs but L3VPN VRFs must be
+maintained, too.For L3VPN VRF maintenance the following operational commands
+are in place.
+
+```{opcmd} show bgp \<ipv4|ipv6\> vpn
+
+ Print active IPV4 or IPV6 routes advertised via the VPN SAFI.
+
+:::{code-block} none
+BGP table version is 2, local router ID is 10.0.1.1, vrf id 0
+Default local pref 100, local AS 65001
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+Network Next Hop Metric LocPrf Weight Path
+Route Distinguisher: 10.50.50.1:1011
+*>i10.50.50.0/24 10.0.0.7 0 100 0 i
+UN=10.0.0.7 EC{65035:1011} label=80 type=bgp, subtype=0
+Route Distinguisher: 10.60.60.1:1011
+*>i10.60.60.0/24 10.0.0.10 0 100 0 i
+UN=10.0.0.10 EC{65035:1011} label=80 type=bgp, subtype=0
+:::
+```
+
+
+```{opcmd} show bgp \<ipv4|ipv6\> vpn summary
+
+Print a summary of neighbor connections for the specified AFI/SAFI
+combination.
+
+:::{code-block} none
+BGP router identifier 10.0.1.1, local AS number 65001 vrf-id 0
+BGP table version 0
+RIB entries 9, using 1728 bytes of memory
+Peers 4, using 85 KiB of memory
+Peer groups 1, using 64 bytes of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+10.0.0.7 4 65001 2860 2870 0 0 0 1d23h34m 2 10
+:::
+```
diff --git a/docs/contributing/build-vyos.md b/docs/contributing/build-vyos.md
new file mode 100644
index 00000000..bfda5298
--- /dev/null
+++ b/docs/contributing/build-vyos.md
@@ -0,0 +1,730 @@
+---
+lastproofread: '2025-12-05'
+---
+
+(build)=
+
+# Build VyOS
+
+## Prerequisites
+
+There are different ways you can build VyOS. Building using a
+{ref}`build_docker`
+container is the easiest way because all dependencies are managed for you.
+Alternatively, you can set up your own build machine and run a
+{ref}`build_native` build.
+
+:::{note}
+Starting with VyOS 1.4, only source code and Debian package
+repositories of the rolling release (the **current** branch) are publicly
+available.
+
+The source code and pre-built Debian package repositories of LTS releases
+are only available to subscription holders (customers and active community
+members with contributors subscriptions).
+
+The following includes the build process for VyOS rolling release.
+:::
+
+This will guide you through the process of building a VyOS ISO using [Docker].
+This process has been tested on clean installs of Debian Bookworm.
+
+(build_native)=
+
+### Native Build
+
+To build VyOS natively, you need a properly configured build host with
+Debian Bookworm installed.
+
+To get started, clone the repository to your local machine:
+
+```none
+$ sudo make clean
+$ sudo ./build-vyos-image --architecture amd64 --build-by "j.randomhacker@vyos.io" generic
+```
+
+For required packages, refer to the `docker/Dockerfile` file in the
+[repository]. The `./build-vyos-image` script will also warn you if any
+dependencies are missing.
+
+(build_docker)=
+
+### Docker
+
+Installing [Docker] and prerequisites:
+
+:::{hint}
+Docker versions are updated frequently. The following examples may
+become outdated.
+:::
+
+```none
+# Add Docker's official GPG key:
+sudo apt-get update
+sudo apt-get install ca-certificates curl gnupg
+sudo install -m 0755 -d /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+sudo chmod a+r /etc/apt/keyrings/docker.gpg
+
+# Add the repository to Apt sources:
+echo \
+ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
+ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
+ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+
+sudo apt-get update
+sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
+```
+
+To use Docker without `sudo`, add your current non-root user to the `docker`
+group: `sudo usermod -aG docker yourusername`.
+
+:::{hint}
+Adding a user to the `docker` group grants privileges equivalent to
+`root`. It is recommended to remove the non-root user from the `docker`
+group after building the VyOS ISO. See also [Docker as non-root].
+:::
+
+:::{note}
+The build process must run on a local file system. Building on SMB or
+NFS shares will cause the container to fail. VirtualBox shared folders are
+also not supported because block device operations are not implemented.
+:::
+
+#### Build Container
+
+The container can be built by hand or by fetching the pre-built one from
+DockerHub. It is recommended to use the pre-built containers from the
+[VyOS DockerHub organisation](https://hub.docker.com/u/vyos). The container
+is built from Docker packages automatically after every commit to the
+``vyos-build`` repository (this process may take 2-3 hours).
+
+:::{note}
+If you use the pre-built container, it will be automatically
+downloaded from DockerHub if it is not found on your local machine when
+you build the ISO.
+:::
+
+##### Dockerhub
+
+To manually download the container from DockerHub, run:
+
+```none
+$ docker pull vyos/vyos-build:current # For VyOS rolling release
+```
+
+
+##### Build from source
+
+The container can also be built directly from source:
+
+```none
+$ git clone -b current --single-branch https://github.com/vyos/vyos-build
+
+$ cd vyos-build
+$ docker build -t vyos/vyos-build:current docker
+```
+
+:::{note}
+VyOS switched to Debian Bookworm (12) in its `current` branch.
+Due to software version updates, it is recommended to use the official
+Docker Hub image to build VyOS ISO.
+:::
+
+#### Tips and Tricks
+
+You can create Bash aliases to easily launch the latest container per release
+train (`current`). Add the following to your `.bash_aliases` file:
+
+```none
+alias vybld='docker pull vyos/vyos-build:current && docker run --rm -it \
+ -v "$(pwd)":/vyos \
+ -v "$HOME/.gitconfig":/etc/gitconfig \
+ -v "$HOME/.bash_aliases":/home/vyos_bld/.bash_aliases \
+ -v "$HOME/.bashrc":/home/vyos_bld/.bashrc \
+ -w /vyos --privileged --sysctl net.ipv6.conf.lo.disable_ipv6=0 \
+ -e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) \
+ vyos/vyos-build:current bash'
+```
+
+Now you have a new alias `vybld` that launches development containers in
+your current working directory.
+
+:::{note}
+Some VyOS packages (namely vyos-1x) come with build-time tests which
+verify some of the internal library calls that they work as expected. Those
+tests are carried out through the Python Unittest module. If you want to
+build the `vyos-1x` package (which is our main development package) you
+need to start your Docker container using the following argument:
+`--sysctl net.ipv6.conf.lo.disable_ipv6=0`, otherwise those tests will
+fail.
+:::
+
+(build-iso)=
+
+## Build ISO
+
+Now that you understand the prerequisites, you can build a VyOS ISO from source.
+First, fetch the latest source code from GitHub:
+
+```none
+$ git clone -b current --single-branch https://github.com/vyos/vyos-build
+```
+
+Now you can begin a fresh VyOS ISO build. Change to the `vyos-build`
+directory and run:
+
+```none
+$ cd vyos-build
+$ docker run --rm -it --privileged -v $(pwd):/vyos -w /vyos vyos/vyos-build:current bash
+```
+
+Start the build:
+
+```none
+vyos_bld@8153428c7e1f:/vyos$ sudo make clean
+vyos_bld@8153428c7e1f:/vyos$ sudo ./build-vyos-image --architecture amd64 --build-by "j.randomhacker@vyos.io" generic
+```
+
+When the build is successful, find the resulting ISO in the `build` directory
+as `live-image-[architecture].hybrid.iso`.
+
+(build-source)=
+
+(customize)=
+
+### Customize
+
+You can customize the ISO with the following configure options. Generate the
+full and current list with `./build-vyos-image --help`:
+
+```none
+$ vyos_bld@8153428c7e1f:/vyos$ sudo ./build-vyos-image --help
+ I: Checking if packages required for VyOS image build are installed
+ usage: build-vyos-image [-h] [--architecture ARCHITECTURE]
+ [--build-by BUILD_BY] [--debian-mirror DEBIAN_MIRROR]
+ [--debian-security-mirror DEBIAN_SECURITY_MIRROR]
+ [--pbuilder-debian-mirror PBUILDER_DEBIAN_MIRROR]
+ [--vyos-mirror VYOS_MIRROR] [--build-type BUILD_TYPE]
+ [--version VERSION] [--build-comment BUILD_COMMENT] [--debug] [--dry-run]
+ [--custom-apt-entry CUSTOM_APT_ENTRY] [--custom-apt-key CUSTOM_APT_KEY]
+ [--custom-package CUSTOM_PACKAGE]
+ [build_flavor]
+
+ positional arguments:
+ build_flavor Build flavor
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --architecture ARCHITECTURE
+ Image target architecture (amd64 or arm64)
+ --build-by BUILD_BY Builder identifier (e.g. jrandomhacker@example.net)
+ --debian-mirror DEBIAN_MIRROR
+ Debian repository mirror
+ --debian-security-mirror DEBIAN_SECURITY_MIRROR
+ Debian security updates mirror
+ --pbuilder-debian-mirror PBUILDER_DEBIAN_MIRROR
+ Debian repository mirror for pbuilder env bootstrap
+ --vyos-mirror VYOS_MIRROR
+ VyOS package mirror
+ --build-type BUILD_TYPE
+ Build type, release or development
+ --version VERSION Version number (release builds only)
+ --build-comment BUILD_COMMENT
+ Optional build comment
+ --debug Enable debug output
+ --dry-run Check build configuration and exit
+ --custom-apt-entry CUSTOM_APT_ENTRY
+ Custom APT entry
+ --custom-apt-key CUSTOM_APT_KEY
+ Custom APT key file
+ --custom-package CUSTOM_PACKAGE
+ Custom package to install from repositories
+```
+
+(iso_build_issues)=
+
+#### ISO Build Issues
+
+There are (rare) situations where building an ISO image is not possible at all
+due to a broken package feed in the background. APT is not very good at
+reporting the root cause of the issue. Your ISO build will likely fail with a
+more or less similar looking error message:
+
+```none
+The following packages have unmet dependencies:
+ vyos-1x : Depends: accel-ppp but it is not installable
+E: Unable to correct problems, you have held broken packages.
+P: Begin unmounting filesystems...
+P: Saving caches...
+Reading package lists...
+Building dependency tree...
+Reading state information...
+Del frr-pythontools 7.5-20210215-00-g8a5d3b7cd-0 [38.9 kB]
+Del accel-ppp 1.12.0-95-g59f8e1b [475 kB]
+Del frr 7.5-20210215-00-g8a5d3b7cd-0 [2671 kB]
+Del frr-snmp 7.5-20210215-00-g8a5d3b7cd-0 [55.1 kB]
+Del frr-rpki-rtrlib 7.5-20210215-00-g8a5d3b7cd-0 [37.3 kB]
+make: *** [Makefile:30: iso] Error 1
+(10:13) vyos_bld ece068908a5b:/vyos [current] #
+```
+
+To debug the build process and gain additional information of what could be the
+root cause, you need to use `chroot` to change into the build directory. This is
+explained in the following step by step procedure:
+
+```none
+vyos_bld ece068908a5b:/vyos [current] # sudo chroot build/chroot /bin/bash
+```
+
+We now need to mount some required, volatile filesystems
+
+```none
+(live)root@ece068908a5b:/# mount -t proc none /proc
+(live)root@ece068908a5b:/# mount -t sysfs none /sys
+(live)root@ece068908a5b:/# mount -t devtmpfs none /dev
+```
+
+We now are free to run any command we would like to use for debugging, e.g.
+re-installing the failed package after updating the repository.
+
+```none
+(live)root@ece068908a5b:/# apt-get update; apt-get install vyos-1x
+Get:1 file:/root/packages ./ InRelease
+Ign:1 file:/root/packages ./ InRelease
+Get:2 file:/root/packages ./ Release [1235 B]
+Get:2 file:/root/packages ./ Release [1235 B]
+Get:3 file:/root/packages ./ Release.gpg
+Ign:3 file:/root/packages ./ Release.gpg
+Hit:4 http://repo.powerdns.com/debian buster-rec-43 InRelease
+Hit:5 http://repo.saltstack.com/py3/debian/10/amd64/archive/3002.2 buster InRelease
+Hit:6 http://deb.debian.org/debian bullseye InRelease
+Hit:7 http://deb.debian.org/debian buster InRelease
+Hit:8 http://deb.debian.org/debian-security buster/updates InRelease
+Hit:9 http://deb.debian.org/debian buster-updates InRelease
+Hit:10 http://deb.debian.org/debian buster-backports InRelease
+Hit:11 http://dev.packages.vyos.net/repositories/current current InRelease
+Reading package lists... Done
+N: Download is performed unsandboxed as root as file '/root/packages/./InRelease' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
+Reading package lists... Done
+Building dependency tree
+Reading state information... Done
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ vyos-1x : Depends: accel-ppp but it is not installable
+E: Unable to correct problems, you have held broken packages.
+```
+
+Now it's time to fix the package mirror and rerun the last step until the
+package installation succeeds again!
+
+(build_custom_packages)=
+
+### Linux Kernel
+
+The Linux kernel used by VyOS is heavily tied to the ISO build process. The
+file `data/defaults.json` hosts a JSON definition of the kernel version used
+`kernel_version` and the `kernel_flavor` of the kernel which represents the
+kernel's LOCAL_VERSION. Both together form the kernel version variable in the
+system:
+
+```none
+vyos@vyos:~$ uname -r
+6.1.52-amd64-vyos
+```
+
+- Accel-PPP
+- Intel NIC drivers
+- Intel QAT
+
+Each of those modules holds a dependency on the kernel version and if you are
+lucky enough to receive an ISO build error which sounds like:
+
+```none
+I: Create initramfs if it does not exist.
+Extra argument '6.1.52-amd64-vyos'
+Usage: update-initramfs {-c|-d|-u} [-k version] [-v] [-b directory]
+Options:
+ -k version Specify kernel version or 'all'
+ -c Create a new initramfs
+ -u Update an existing initramfs
+ -d Remove an existing initramfs
+ -b directory Set alternate boot directory
+ -v Be verbose
+See update-initramfs(8) for further details.
+E: config/hooks/live/17-gen_initramfs.chroot failed (exit non-zero). You should check for errors.
+```
+
+The most obvious reasons could be:
+
+- `vyos-build` repo is outdated, please `git pull` to update to the latest
+ release kernel version from us.
+- You have your own custom kernel `*.deb` packages in the `packages` folder but
+ neglected to create all required out-of tree modules like Accel-PPP, Intel
+ QAT or Intel NIC drivers
+
+#### Building The Kernel
+
+The kernel build is quite easy, most of the required steps can be found in the
+`vyos-build/packages/linux-kernel/Jenkinsfile` but we will walk you through
+it.
+
+Clone the kernel source to `vyos-build/packages/linux-kernel/`:
+
+```none
+$ cd vyos-build/packages/linux-kernel/
+$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
+```
+
+Check out the required kernel version - see `vyos-build/data/defaults.json`
+file (example uses kernel 4.19.146):
+
+```none
+$ cd vyos-build/packages/linux-kernel/linux
+$ git checkout v4.19.146
+Checking out files: 100% (61536/61536), done.
+Note: checking out 'v4.19.146'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by performing another checkout.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -b with the checkout command again. Example:
+ git checkout -b <new-branch-name>
+HEAD is now at 015e94d0e37b Linux 4.19.146
+```
+
+Now you can use the helper script `build-kernel.sh`, which completes all
+the necessary steps: applying required patches from the
+`vyos-build/packages/linux-kernel/patches` folder, copying the kernel
+configuration `x86_64_vyos_defconfig` to the correct location, and building
+the Debian packages.
+
+:::{note}
+Building the kernel will take some time depending on the speed and
+quantity of your CPU/cores and disk speed. Expect 20 minutes
+(or even longer) on lower end hardware.
+:::
+
+```none
+(18:59) vyos_bld 412374ca36b8:/vyos/vyos-build/packages/linux-kernel [current] # ./build-kernel.sh
+I: Copy Kernel config (x86_64_vyos_defconfig) to Kernel Source
+I: Apply Kernel patch: /vyos/vyos-build/packages/linux-kernel/patches/kernel/0001-VyOS-Add-linkstate-IP-device-attribute.patch
+patching file Documentation/networking/ip-sysctl.txt
+patching file include/linux/inetdevice.h
+patching file include/linux/ipv6.h
+patching file include/uapi/linux/ip.h
+patching file include/uapi/linux/ipv6.h
+patching file net/ipv4/devinet.c
+Hunk #1 succeeded at 2319 (offset 1 line).
+patching file net/ipv6/addrconf.c
+patching file net/ipv6/route.c
+I: Apply Kernel patch: /vyos/vyos-build/packages/linux-kernel/patches/kernel/0002-VyOS-add-inotify-support-for-stackable-filesystems-o.patch
+patching file fs/notify/inotify/Kconfig
+patching file fs/notify/inotify/inotify_user.c
+patching file fs/overlayfs/super.c
+Hunk #2 succeeded at 1713 (offset 9 lines).
+Hunk #3 succeeded at 1739 (offset 9 lines).
+Hunk #4 succeeded at 1762 (offset 9 lines).
+patching file include/linux/inotify.h
+I: Apply Kernel patch: /vyos/vyos-build/packages/linux-kernel/patches/kernel/0003-RFC-builddeb-add-linux-tools-package-with-perf.patch
+patching file scripts/package/builddeb
+I: make x86_64_vyos_defconfig
+ HOSTCC scripts/basic/fixdep
+ HOSTCC scripts/kconfig/conf.o
+ YACC scripts/kconfig/zconf.tab.c
+ LEX scripts/kconfig/zconf.lex.c
+ HOSTCC scripts/kconfig/zconf.tab.o
+ HOSTLD scripts/kconfig/conf
+#
+
+# configuration written to .config
+#
+I: Generate environment file containing Kernel variable
+I: Build Debian Kernel package
+ UPD include/config/kernel.release
+/bin/sh ./scripts/package/mkdebian
+dpkg-buildpackage -r"fakeroot -u" -a$(cat debian/arch) -b -nc -uc
+dpkg-buildpackage: info: source package linux-4.19.146-amd64-vyos
+dpkg-buildpackage: info: source version 4.19.146-1
+dpkg-buildpackage: info: source distribution buster
+dpkg-buildpackage: info: source changed by vyos_bld <christian@poessinger.com>
+dpkg-buildpackage: info: host architecture amd64
+dpkg-buildpackage: warning: debian/rules is not executable; fixing that
+ dpkg-source --before-build .
+ debian/rules build
+make KERNELRELEASE=4.19.146-amd64-vyos ARCH=x86 KBUILD_BUILD_VERSION=1 KBUILD_SRC=
+ SYSTBL arch/x86/include/generated/asm/syscalls_32.h
+...
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
+dpkg-shlibdeps: warning: package could avoid a useless dependency if /vyos/vyos-build/packages/linux-kernel/linux/debian/toolstmp/usr/bin/trace /vyos/vyos-build/packages/linux-kernel/linux/debian/toolstmp/usr/bin/perf were not linked against libcrypto.so.1.1 (they use none of the library's symbols)
+dpkg-shlibdeps: warning: package could avoid a useless dependency if /vyos/vyos-build/packages/linux-kernel/linux/debian/toolstmp/usr/bin/trace /vyos/vyos-build/packages/linux-kernel/linux/debian/toolstmp/usr/bin/perf were not linked against libcrypt.so.1 (they use none of the library's symbols)
+dpkg-deb: building package 'linux-tools-4.19.146-amd64-vyos' in '../linux-tools-4.19.146-amd64-vyos_4.19.146-1_amd64.deb'.
+ dpkg-genbuildinfo --build=binary
+ dpkg-genchanges --build=binary >../linux-4.19.146-amd64-vyos_4.19.146-1_amd64.changes
+dpkg-genchanges: warning: package linux-image-4.19.146-amd64-vyos-dbg in control file but not in files list
+dpkg-genchanges: info: binary-only upload (no source code included)
+ dpkg-source --after-build .
+dpkg-buildpackage: info: binary-only upload (no source included)
+```
+
+When complete, you will have kernel binary packages to use in your custom ISO
+build. Place all `*.deb` files in the `vyos-build/packages` folder, where
+the build process will use them automatically.
+
+##### Firmware
+
+If you upgrade your kernel or include new drivers you may need new firmware.
+This builds a new `vyos-linux-firmware` package using the included helper
+scripts.
+
+```none
+$ cd vyos-build/packages/linux-kernel
+$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+$ ./build-linux-firmware.sh
+$ cp vyos-linux-firmware_*.deb ../
+```
+
+The script automatically detects which firmware blobs are needed based on the
+built drivers. If detection fails, you can manually add files to
+`vyos-build/packages/linux-kernel/build-linux-firmware.sh`:
+
+```bash
+ADD_FW_FILES="iwlwifi* ath11k/QCA6390/*/*.bin"
+```
+
+
+#### Building Out-Of-Tree Modules
+
+Building the kernel is one step. You must also build required out-of-tree
+modules so the ABIs match.
+Refer to `vyos-build/packages/linux-kernel/Jenkinsfile`
+for all required modules and their versions. We show you how to build the
+currently required modules.
+
+##### Accel-PPP
+
+First, clone the source code and check out the appropriate version:
+
+```none
+$ cd vyos-build/packages/linux-kernel
+$ git clone https://github.com/accel-ppp/accel-ppp.git
+```
+
+Use the helper script and patches to build the package. Run the following
+command:
+
+```none
+$ ./build-accel-ppp.sh
+I: Build Accel-PPP Debian package
+CMake Deprecation Warning at CMakeLists.txt:3 (cmake_policy):
+ The OLD behavior for policy CMP0003 will be removed from a future version
+ of CMake.
+ The cmake-policies(7) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+-- The C compiler identification is GNU 8.3.0
+...
+
+CPack: Create package using DEB
+CPack: Install projects
+CPack: - Run preinstall target for: accel-ppp
+CPack: - Install project: accel-ppp
+CPack: Create package
+CPack: - package: /vyos/vyos-build/packages/linux-kernel/accel-ppp/build/accel-ppp.deb generated.
+```
+
+After compiling the packages you will find yourself the newly generated `*.deb`
+binaries in `vyos-build/packages/linux-kernel` from which you can copy them
+to the `vyos-build/packages` folder for inclusion during the ISO build.
+
+##### Intel NIC
+
+The Intel NIC drivers do not come from a Git repository. VyOS fetches the
+tarballs from a mirror and compiles them. Use the following wrapper script
+to build all driver modules:
+
+```none
+./build-intel-drivers.sh
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 490k 100 490k 0 0 648k 0 --:--:-- --:--:-- --:--:-- 648k
+I: Compile Kernel module for Intel ixgbe driver
+...
+
+I: Building Debian package vyos-intel-iavf
+Doing `require 'backports'` is deprecated and will not load any backport in the next major release.
+Require just the needed backports instead, or 'backports/latest'.
+Debian packaging tools generally labels all files in /etc as config files, as mandated by policy, so fpm defaults to this behavior for deb packages. You can disable this default behavior with --deb-no-default-config-files flag {:level=>:warn}
+Created package {:path=>"vyos-intel-iavf_4.0.1-0_amd64.deb"}
+I: Cleanup iavf source
+```
+
+After compilation, find the generated `*.deb` binaries in
+`vyos-build/packages/linux-kernel`. Copy them to the `vyos-build/packages`
+folder for inclusion in the ISO build.
+
+##### Intel QAT
+
+The Intel QAT (Quick Assist Technology) drivers do not come from a Git
+repository. VyOS fetches the tarballs from `01.org`, Intel's open-source
+website.
+Use the following wrapper script to build all driver modules:
+
+```none
+$ ./build-intel-qat.sh
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 5065k 100 5065k 0 0 1157k 0 0:00:04 0:00:04 --:--:-- 1157k
+I: Compile Kernel module for Intel qat driver
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+checking for a thread-safe mkdir -p... /bin/mkdir -p
+checking for gawk... gawk
+checking whether make sets $(MAKE)... yes
+...
+
+I: Building Debian package vyos-intel-qat
+Doing `require 'backports'` is deprecated and will not load any backport in the next major release.
+Require just the needed backports instead, or 'backports/latest'.
+Debian packaging tools generally labels all files in /etc as config files, as mandated by policy, so fpm defaults to this behavior for deb packages. You can disable this default behavior with --deb-no-default-config-files flag {:level=>:warn}
+Created package {:path=>"vyos-intel-qat_1.7.l.4.9.0-00008-0_amd64.deb"}
+I: Cleanup qat source
+```
+
+After compiling the packages you will find yourself the newly generated `*.deb`
+binaries in `vyos-build/packages/linux-kernel` from which you can copy them
+to the `vyos-build/packages` folder for inclusion during the ISO build.
+
+### Packages
+
+If you are brave enough to build your own ISO image with any modified package
+from VyOS's GitHub organisation, this is the place for you.
+
+Any modified package may be an altered version (e.g., `vyos-1x`) that you
+want to test before filing a pull request on GitHub.
+
+Building an ISO with a customized package is the same as building a regular
+ISO image. Place your modified `*.deb` package inside the `packages` folder
+within `vyos-build`. The build process will automatically use your custom
+package during the ISO build.
+
+### Troubleshooting
+
+Debian APT does not provide verbose error messages. If your ISO build fails and
+you suspect an APT dependencies or installation issue, you can apply this patch
+to increase APT verbosity during the ISO build.
+
+```diff
+diff --git i/scripts/live-build-config w/scripts/live-build-config
+index 1b3b454..3696e4e 100755
+--- i/scripts/live-build-config
++++ w/scripts/live-build-config
+@@ -57,7 +57,8 @@ lb config noauto \
+ --firmware-binary false \
+ --updates true \
+ --security true \
+- --apt-options "--yes -oAcquire::Check-Valid-Until=false" \
++ --apt-options "--yes -oAcquire::Check-Valid-Until=false -oDebug::BuildDeps=true -oDebug::pkgDepCache::AutoInstall=true \
++ -oDebug::pkgDepCache::Marker=true -oDebug::pkgProblemResolver=true -oDebug::Acquire::gpgv=true" \
+ --apt-indices false
+ "${@}"
+ """
+```
+
+(build-packages)=
+
+## Packages
+
+VyOS comes with specific packages that cannot be found in any
+Debian mirror. These packages are located in the [VyOS GitHub project] in
+source format and can easily be compiled into custom
+Debian (`*.deb`) packages.
+
+The easiest way to compile your package is with the {ref}`build_docker`
+container mentioned earlier, as it includes all required dependencies for all
+VyOS related packages.
+
+Assuming you want to build the `vyos-1x` package and modify it for your needs,
+first clone the repository from GitHub:
+
+```none
+$ git clone --recurse-submodules https://github.com/vyos/vyos-1x
+```
+
+
+### Build
+
+Launch the Docker container and build the package:
+
+```none
+# For VyOS 1.3 (equuleus, current)
+$ docker run --rm -it --privileged -v $(pwd):/vyos -w /vyos vyos/vyos-build:current bash
+
+# Change to source directory
+$ cd vyos-1x
+
+# Build DEB
+$ dpkg-buildpackage -uc -us -tc -b
+```
+
+After a minute or two, the generated DEB packages are located next to the
+`vyos-1x` source directory:
+
+```none
+# ls -al ../vyos-1x*.deb
+-rw-r--r-- 1 vyos_bld vyos_bld 567420 Aug 3 12:01 ../vyos-1x_1.3dev0-1847-gb6dcb0a8_all.deb
+-rw-r--r-- 1 vyos_bld vyos_bld 3808 Aug 3 12:01 ../vyos-1x-vmware_1.3dev0-1847-gb6dcb0a8_amd64.deb
+```
+
+
+### Install
+
+To test your newly created package, you can SCP it to a running VyOS instance
+and install the new `*.deb` package to replace the current one.
+
+Install the package using the following commands:
+
+```none
+vyos@vyos:~$ dpkg --install /tmp/vyos-1x_1.3dev0-1847-gb6dcb0a8_all.deb
+(Reading database ... 58209 files and directories currently installed.)
+Preparing to unpack .../vyos-1x_1.3dev0-1847-gb6dcb0a8_all.deb ...
+Unpacking vyos-1x (1.3dev0-1847-gb6dcb0a8) over (1.3dev0-1847-gb6dcb0a8) ...
+Setting up vyos-1x (1.3dev0-1847-gb6dcb0a8) ...
+Processing triggers for rsyslog (8.1901.0-1) ...
+```
+
+You can also place the generated `*.deb` in your ISO build environment to
+include it in a custom ISO. See {ref}`build_custom_packages` for more
+information.
+
+:::{warning}
+Any packages in the `packages` directory will be added to the
+ISO during the build, replacing upstream packages. Delete both the source
+directories and built DEB packages if you want to build an ISO from purely
+upstream packages.
+:::
+
+[docker]: https://docs.docker.com/engine/install/debian/
+[docker as non-root]: https://docs.docker.com/engine/install/linux-postinstall
+[repository]: https://github.com/vyos/vyos-build
+[vyos dockerhub organisation]: https://hub.docker.com/u/vyos
+[vyos github project]: https://github.com/vyos
diff --git a/docs/contributing/cla.md b/docs/contributing/cla.md
new file mode 100644
index 00000000..01323111
--- /dev/null
+++ b/docs/contributing/cla.md
@@ -0,0 +1,45 @@
+---
+lastproofread: '2025-12-05'
+---
+
+(cla)=
+
+# Contributor License Agreement
+
+Before we can accept your contributions to VyOS, you must sign a **Contributor
+License Agreement (CLA)**.
+
+This is a standard open-source practice that protects both you and the project.
+
+The process is straightforward and fully automated:
+
+1. **Review the CLA document**
+
+ Find the CLA text in our
+ [GitHub repository](https://github.com/vyos/vyos-cla-signatures/).
+
+2. **Submit a pull request**
+
+ When you open a pull request, a CLA bot automatically checks whether all
+ commit authors have signed the CLA.
+
+3. **Follow the bot's instructions**
+
+ If the CLA has not been signed, the bot leaves a comment with instructions.
+ Reply to that comment with the suggested text to sign the CLA.
+
+4. **Wait for confirmation**
+
+ The CLA bot verifies your response and updates the pull request status.
+ Once all commit authors have signed, the bot confirms that the CLA
+ requirement is met and unlocks the pull request for merging.
+
+:::{note}
+Each commit author must sign the CLA.
+
+If your pull request includes commits from multiple contributors, each one
+must sign the CLA before the pull request can be accepted.
+:::
+
+Once you sign the CLA, it remains valid for all your past and future
+contributions to VyOS under the same GitHub identity.
diff --git a/docs/contributing/debugging.md b/docs/contributing/debugging.md
new file mode 100644
index 00000000..d3b4b513
--- /dev/null
+++ b/docs/contributing/debugging.md
@@ -0,0 +1,204 @@
+---
+lastproofread: '2025-12-05'
+---
+
+(debugging)=
+
+# Debugging
+
+Two flags are available to help debug configuration scripts. Configuration
+loading issues manifest during boot, so these flags are passed as kernel boot
+parameters.
+
+## ISO image build
+
+If you have trouble compiling your own ISO image or debugging Jenkins issues,
+follow the steps at {ref}`iso_build_issues`.
+
+## System Startup
+
+Debug system startup by examining the configuration file loading from
+`/config/config.boot`. Extend the kernel command-line in the bootloader to
+enable this.
+
+### Kernel
+
+- `vyos-debug` - Add this parameter to the Linux boot line to produce
+ timing results for script execution during commit. If you see an unexpected
+ delay during manual or boot commit, this parameter helps identify bottlenecks.
+ The internal flag is `VYOS_DEBUG`, found in [vyatta-cfg]. Output is directed
+ to `/var/log/vyatta/cfg-stdout.log`.
+- `vyos-config-debug` - During development, coding errors can cause commit
+ failures on boot, potentially preventing CLI initialization. This kernel boot
+ parameter ensures access to the system as user `vyos` and logs a Python
+ stack trace to `/tmp/boot-config-trace`. The file is created only if the
+ configuration load fails.
+
+## Live System
+
+Several flags can be set to change VyOS behavior at runtime. Toggle these flags
+using environment variables or by creating files.
+
+For each feature, create a file called `vyos.feature.debug` to enable it.
+If a parameter is required, place it as the first line inside the file.
+
+Place the file in `/tmp` for one-time debugging (the file is removed on
+reboot) or in `/config` to persist permanently.
+
+For example, `/tmp/vyos.ifconfig.debug` can be created to enable
+interface debugging.
+
+You can also enable debugging using environment variables.
+The environment variable name follows the convention `VYOS_FEATURE_DEBUG`.
+
+For example, `export VYOS_IFCONFIG_DEBUG=""` in your vbash has the same effect
+as `touch /tmp/vyos.ifconfig.debug`.
+
+- `ifconfig` - Display all commands and their responses from the OS on
+ screen for inspection.
+- `command` - Display all commands and their responses from the OS on screen
+ for inspection.
+- `developer` - When a command fails, start a PDB post-mortem session instead
+ of showing a standard error message. This allows developers to debug issues
+ interactively. Because the debugger waits for input, it can prevent the router
+ from booting, so only enable this permanently on production systems if you are
+ ready for potential boot failures.
+- `log` - Send all commands used by VyOS to a log file for inspection. This
+ is useful in rare cases when you need to see what the OS is doing, including
+ during boot. The default file is `/tmp/full-log`, but you can change it.
+
+:::{note}
+To retrieve debug output on the command line, disable `vyos-configd`
+in addition. You can do this one-time with
+`sudo systemctl stop vyos-configd`
+or permanently with `sudo systemctl disable vyos-configd`.
+:::
+
+### FRR
+
+Recent versions use the `vyos.frr` framework. The Python class is located in
+`vyos-1x:python/vyos/frr.py`. It includes an embedded debugger similar to the
+one in `vyos.ifconfig`.
+
+Enable debugging by running: `touch /tmp/vyos.frr.debug`
+
+### Debug Python code with PDB
+
+Sometimes it is useful to debug Python code interactively on the live system
+rather than in an IDE. You can do this using pdb.
+
+Assuming you want to debug a Python script called by an op-mode command, find
+the script by looking up the op-mode definitions, then edit it on the live
+system using vi:
+`vi /usr/libexec/vyos/op_mode/show_xyz.py`
+
+Insert the following statement right before the section where you want to
+investigate a problem (for example, a statement you see in a backtrace):
+`import pdb; pdb.set_trace()`
+
+Optionally, surround this statement with an `if` condition that triggers only
+for the conditions you are interested in.
+
+When you run `show xyz` and your condition triggers, you enter the Python
+debugger:
+
+```none
+> /usr/libexec/vyos/op_mode/show_nat_translations.py(109)process()
+-> rule_type = rule.get('type', '')
+(Pdb)
+```
+
+You can type `help` to get an overview of the available commands, and
+`help command` to get more information on each command.
+
+Common useful commands include:
+
+- examine variables using `pp(var)`
+- continue execution using `cont`
+- get a backtrace using `bt`
+
+### Config Migration Scripts
+
+Starting with VyOS 1.5, a new mechanism is used for config migration that
+improves migration performance. New migrators use only the new format with a
+`migration()` function.
+
+```python
+from vyos.configtree import ConfigTree
+base = ['vpn', 'ipsec']
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+ # do your stuff here
+```
+
+New-style migration scripts can no longer run on their own. However, the new
+migration subsystem handler includes a test kit:
+
+```none
+vyos@vyos:~$ /usr/libexec/vyos/run-config-migration.py --help
+usage: run-config-migration.py [-h] [--test-script TEST_SCRIPT] [--output-file OUTPUT_FILE] [--force] config_file
+
+positional arguments:
+ config_file configuration file to migrate
+
+options:
+ -h, --help show this help message and exit
+ --test-script TEST_SCRIPT
+ test named script
+ --output-file OUTPUT_FILE
+ write to named output file instead of config file
+ --force force run of all migration scripts
+```
+
+To test your migration, run:
+
+```none
+vyos@vyos:~$ /usr/libexec/vyos/run-config-migration.py --test-script /opt/vyatta/etc/config-migrate/migrate/quagga/11-to-12 --output-file /tmp/foo /tmp/static-route-basic
+vyos@vyos:~$ cat /tmp/foo
+```
+
+The file `/tmp/foo` contains the migrated configuration.
+
+### Configuration Error on System Boot
+
+Running the latest rolling releases sometimes exposes bugs due to edge cases
+missed in design. File these bugs via [Phabricator](https://vyos.dev/), but you can help narrow
+down the issue by following these steps:
+
+1. Log in to your VyOS system.
+2. Enter configuration mode: `configure`
+3. Reload your boot configuration: `load`
+
+You should see a Python backtrace that helps identify the issue. Attach it to
+the [Phabricator](https://vyos.dev/) task.
+
+### Boot Timing
+
+During the migration and rewrite of functionality from Perl to Python, system
+boot time increased significantly. You can analyze and graph boot time to see
+detailed call sequences during startup.
+
+This uses the `systemd-bootchart` package, which is installed by default on
+VyOS 1.3 (equuleus) and later. Configuration is versioned for comparable
+results. Refer to [bootchart.conf] for the configuration file.
+
+To enable boot time graphing, add the following to the kernel command line:
+`init=/usr/lib/systemd/systemd-bootchart`
+
+You can also make this permanent by editing `/boot/grub/grub.cfg`.
+
+## Priorities
+
+VyOS CLI depends heavily on priorities. Every CLI node has a corresponding
+`node.def` file and possibly an attached script. Nodes can have priorities,
+and on system bootup or any `commit` to the configuration, scripts execute
+from lowest to highest priority. This provides deterministic behavior.
+
+To debug priority issues or see script execution order, use the
+`/opt/vyatta/sbin/priority.pl` script, which lists the execution order of
+scripts.
+
+[bootchart.conf]: https://github.com/vyos/vyos-build/blob/current/data/live-build-config/includes.chroot/etc/systemd/bootchart.conf
+[vyatta-cfg]: https://github.com/vyos/vyatta-cfg
diff --git a/docs/contributing/development.md b/docs/contributing/development.md
new file mode 100644
index 00000000..8d2cec40
--- /dev/null
+++ b/docs/contributing/development.md
@@ -0,0 +1,549 @@
+---
+lastproofread: '2025-12-12'
+---
+
+(development)=
+
+# Development
+
+Learn how to contribute to VyOS.
+
+(architecture-overview)=
+
+## Architecture overview
+
+VyOS source code is hosted on GitHub in the VyOS organization:
+<https://github.com/vyos>
+
+VyOS is composed of multiple modules spread across different
+repositories. Some modules contain forks of upstream
+packages and are periodically synced.
+VyOS consolidates most packages into the
+[vyos-1x](https://github.com/vyos/vyos-1x)
+repository while maintaining a consistent structure.
+The base code is being rewritten
+from Perl and Bash to Python using an XML-based CLI interface definition.
+
+VyOS ISO build scripts are hosted in the
+[vyos-build](https://github.com/vyos/vyos-build) repository. See the
+`vyos-build` repository
+[README.md file](https://github.com/vyos/vyos-build/blob/current/README.md)
+for more information on building VyOS ISO images.
+
+## Contributing code
+
+:::{warning}
+You must sign the {doc}`Contributor License Agreement<cla>`
+for your contributions to be accepted.
+:::
+
+VyOS is open-source and welcomes patches.
+All submissions must adhere to these guidelines:
+
+- Each commit addresses a single issue or feature.
+- Each commit message references a [Phabricator](https://vyos.dev/) task ID
+ (for example, `T1234`).
+- Each commit is associated with a username and email address
+ to identify the author (see [Configure your Git identity](configure-your-git-identity)).
+- Only submit bugfixes in packages other than <https://github.com/vyos/vyos-1x>.
+- Commits follow the [coding guidelines](coding-guidelines) outlined below.
+
+### Determining package ownership
+
+To determine which VyOS package contains a file you want to modify, use Debian's
+`dpkg -S` command on your running VyOS installation.
+
+### Submitting your code
+
+Fork the repository and submit a GitHub pull request. This is the preferred way
+to contribute changes to VyOS.
+
+To fork a VyOS repository:
+
+1. Append `/fork` to the repository URL on GitHub. For example, to fork
+ `vyos-1x`, use: <https://github.com/vyos/vyos-1x/fork>
+
+2. Clone your fork or add it as a remote to your local repository:
+
+ - Clone: `git clone https://github.com/<user>/vyos-1x.git`
+ - Add remote: `git remote add myfork https://github.com/<user>/vyos-1x.git`
+
+(configure-your-git-identity)=
+
+3. Configure your Git identity:
+
+ ```none
+ git config --global user.name "J. Random Hacker"
+ git config --global user.email "jrhacker@example.net"
+ ```
+
+4. Make your changes and add files to the Git index:
+
+ - Single file: `git add myfile`
+ - Directory: `git add somedir/*`
+
+5. Commit your changes with a meaningful headline and [Phabricator](https://vyos.dev/) reference:
+
+ `git commit`
+
+6. Push to your fork and create a GitHub pull request:
+
+ `git push`
+
+Alternatively, you can export commits as patches and send them to
+[maintainers@vyos.net](mailto:maintainers@vyos.net) or attach them directly to the [Phabricator](https://vyos.dev/) task:
+
+- Export last commit: `git format-patch`
+- Export last two commits: `git format-patch -2`
+
+## Commit messages
+
+For guidance on writing commit messages, review the file history
+with `git log path/to/file.txt`.
+
+Every change must be associated with a task number (prefixed with **T**) and
+a component. If no bug report or feature request exists for your changes,
+create a [Phabricator](https://vyos.dev/) task first. Reference the task ID in your commit message:
+
+- `ddclient: T1030: auto create runtime directories`
+- `Jenkins: add current Git commit ID to build description`
+
+If your pull request lacks a [Phabricator](https://vyos.dev/) reference, maintainers will request
+that you amend the commit message.
+
+### Writing good commit messages
+
+Follow the format described in
+the [Git documentation](https://git-scm.com/book/ch5-2.html)
+and [Chris Beams' guide](https://chris.beams.io/posts/git-commit/).
+
+Commit message format:
+
+1. **Summary line** (50 characters recommended, 80 maximum): Include the
+ component
+ prefix and [Phabricator](https://vyos.dev/) reference (for example, `snmp: T1111:` or
+ `ethernet: T2222:`). Concatenate multiple components with colons
+ (for example, `snmp: ethernet: T3333`).
+2. **Blank line**: Separate the summary from the body.
+ This blank line is critical.
+
+4) **Message body** with details:
+
+ - Describe what changed, why, and how. This helps with `git bisect`.
+ - Wrap text at 72 characters for readability with `git log` on an 80x25
+ terminal.
+ - Reference previous commits when applicable:
+ `After commit abcd12ef ("snmp: this is a headline")
+ a Python import statement is missing, throwing the following exception:
+ ABCDEF`
+
+5) **Cherry-pick option**: Always use the `-x` option when back-porting or
+ forward-porting commits:
+
+ `git cherry-pick -x <commit>`
+
+ This appends `(cherry picked from commit <ID>)` to the commit message,
+ making bisecting easier.
+
+6) **Single responsibility**: Each commit must be self-contained. Do not fix
+ multiple bugs in a single commit. Use `git add --patch` to stage only
+ the parts related to one issue.
+
+Constraints:
+
+- Bugfixes are only accepted for packages other than
+ <https://github.com/vyos/vyos-1x>.
+ New functionality must use the new XML/Python interface, not old-style
+ templates (`node.def` files and Perl/Bash code).
+
+## Coding guidelines
+
+VyOS maintains consistent coding standards to help contributors navigate the
+codebase and understand its logic.
+
+### Formatting
+
+- **Python**: Use 4 spaces per indentation level. Tabs **must not** be used.
+- **XML**: Use 2 spaces per indentation level. Tabs **must not** be used.
+
+Use tools like VIM extensions (xmllint) to enforce correct indentation. Add this
+to your `.vimrc` file:
+
+```none
+au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null
+```
+
+Then use `gg=G` in command mode to run the linter.
+
+### Text generation
+
+Use a template processor for generating config files:
+
+- **Jinja2** is the default template processor for VyOS code.
+- Built-in string formatting **may** be used for simple line-oriented formats
+ (for example, iptables rules) where every line is self-contained.
+- Template processors **must** be used for structured, multi-line formats
+ (for example, ISC DHCPd configuration).
+
+### Python code
+
+Configuration scripts and operation mode scripts written in Python3 should
+follow these guidelines:
+
+- Wrap lines at 80 characters. This improves readability when browsing
+ GitHub on mobile devices and reads well in side-by-side diffs.
+
+Structure your scripts with these functions:
+
+```python
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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 sys
+
+from vyos.config import Config
+from vyos import ConfigError
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ # Base path to CLI nodes
+ base = ['...', '...']
+ # Convert the VyOS config to an abstract internal representation
+ config_data = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ return config_data
+
+def verify(config):
+ # Verify that configuration is valid
+ if invalid:
+ raise ConfigError("Descriptive message")
+
+def generate(config):
+ # Generate daemon configs
+ pass
+
+def apply(config):
+ # Apply the generated configs to the live system
+ pass
+
+try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+except ConfigError as e:
+ print(e)
+ sys.exit(1)
+```
+
+`get_config()`: This function converts a VyOS config object to an abstract
+internal representation. No other function may call the `vyos.config.Config`
+object directly. Limiting config reads to one function makes it easier to
+modify the config syntax in the future. Additionally, this design improves
+testability since you can construct an internal representation by hand rather
+than mocking the entire config subsystem.
+
+`verify()`: This function validates the internal representation. It must
+raise `ConfigError` with a descriptive message if the config is invalid. It
+**must not** make any changes to the system. This design enables future features
+like commit dry-run ("commit test" as in JunOS) where the system can abort a
+commit before making changes.
+
+`generate()`: This function generates config files for system components.
+
+`apply()`: This function applies the generated configuration to the live
+system. Prefer non-disruptive reload when possible. Disruptive operations like
+daemon restarts are acceptable only when:
+
+- The component does not support non-disruptive reload, or
+- The expected service degradation is minimal (for example, auxiliary services
+ like LLDPd)
+
+For high-impact services (VPN daemons, routing protocols), make effort to
+determine if changes can be applied non-disruptively before resorting to
+restarts.
+
+Never modify active configuration directly unless absolutely necessary. Instead,
+generate configuration files and apply them with a single command like service
+reload through systemd. For example, save iptables rules to a file and load them
+with `iptables-restore` rather than executing iptables commands one by one.
+
+The `apply()` and `generate()` functions may raise `ConfigError` if the
+daemon fails to start with the updated config. However, this is not a substitute
+for proper config validation in the `verify()` function. Make reasonable
+effort to verify that generated configuration is valid and will be accepted by
+the daemon, including cross-checks with other VyOS configuration subtrees when
+necessary.
+
+Exceptions like `VyOSError` (raised by `vyos.config.Config` on improper
+operations) should not be silenced or caught. While this may produce less
+polished error output for users, it generates better bug reports and helps
+maintainers debug issues.
+
+For reference implementations, see `ntp.py` or `interfaces-bonding.py` (for
+tag nodes) in the [vyos-1x](https://github.com/vyos/vyos-1x) repository.
+
+### Other considerations: `vyos-configd`
+
+All scripts now run under the config daemon and must conform to these
+requirements:
+
+1. The signature and first four lines of `get_config(...)` **must** be as
+ specified above.
+2. Each of `get_config`, `verify`, `apply`, and `generate` **must**
+ appear
+ with the correct signatures, even if they are a no-op.
+3. `Config` objects other than those in `get_config` **must not** appear.
+4. The legacy function `my_set` **must not** appear. Modifications to active
+ config **should not** appear in new code (alternative mechanisms may be used
+ if absolutely necessary).
+
+## XML for CLI definitions
+
+XML interface definitions define the VyOS CLI structure.
+Before VyOS `1.2` (crux), these
+files were created manually. After a redesign, new-style templates are
+automatically generated from XML input files.
+
+VyOS interface definitions come with a RelaxNG schema located in the
+[vyos-1x](https://github.com/vyos/vyos-1x/tree/current/schema)
+repository. This schema is a modified version from `VyConf` (VyOS `2.0`).
+VyOS `1.2.x`
+interface definitions are reusable in future VyOS versions with minimal changes.
+
+Schemas provide two benefits:
+
+- Complete grammar verification
+- Automatic validation against the schema
+
+The [build-command-templates](https://github.com/vyos/vyos-1x/blob/current/scripts/build-command-templates)
+script converts XML definitions to
+old-style templates and verifies them against the schema. A bad definition
+causes the package build to fail. While the XML format is verbose, no other
+format provides this level of verification. Specialized XML editors can help
+manage verbosity.
+
+Example XML interface definition:
+
+```xml
+<?xml version="1.0"?>
+<!-- Cron configuration -->
+<interfaceDefinition>
+ <node name="system">
+ <children>
+ <node name="task-scheduler">
+ <properties>
+ <help>Task scheduler settings</help>
+ </properties>
+ <children>
+ <tagNode name="task" owner="${vyos_conf_scripts_dir}/task_scheduler.py">
+ <properties>
+ <help>Scheduled task</help>
+ <valueHelp>
+ <format>&lt;string&gt;</format>
+ <description>Task name</description>
+ </valueHelp>
+ <priority>999</priority>
+ </properties>
+ <children>
+ <leafNode name="crontab-spec">
+ <properties>
+ <help>UNIX crontab time specification string</help>
+ </properties>
+ </leafNode>
+ <leafNode name="interval">
+ <properties>
+ <help>Execution interval</help>
+ <valueHelp>
+ <format>&lt;minutes&gt;</format>
+ <description>Execution interval in minutes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;minutes&gt;m</format>
+ <description>Execution interval in minutes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;hours&gt;h</format>
+ <description>Execution interval in hours</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;days&gt;d</format>
+ <description>Execution interval in days</description>
+ </valueHelp>
+ <constraint>
+ <regex>[1-9]([0-9]*)([mhd]{0,1})</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <node name="executable">
+ <properties>
+ <help>Executable path and arguments</help>
+ </properties>
+ <children>
+ <leafNode name="path">
+ <properties>
+ <help>Path to executable</help>
+ </properties>
+ </leafNode>
+ <leafNode name="arguments">
+ <properties>
+ <help>Arguments passed to the executable</help>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
+```
+
+XML definitions are purely declarative and contain no logic. All logic for
+generating config files, restarting services, and related tasks is implemented
+in configuration scripts.
+
+### Template Processors
+
+XML interface definition files use the `.xml.in` file extension (implemented
+in {vytask}`T1843`). These files use the GCC preprocessor to reduce code
+duplication in common areas:
+
+- VIF (including VIF-S and VIF-C)
+- Address configuration
+- Description
+- Enabled/Disabled state
+
+Instead of repeating XML nodes, use include files with predefined features:
+
+- [IPv4, IPv6, and DHCP(v6)](https://github.com/vyos/vyos-1x/blob/current/interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i)
+ address assignment.
+- [IPv4 and IPv6](https://github.com/vyos/vyos-1x/blob/current/interface-definitions/include/interface/address-ipv4-ipv6.xml.i)
+ address assignment.
+- [VLAN (VIF)](https://github.com/vyos/vyos-1x/blob/current/interface-definitions/include/accel-ppp/vlan.xml.i)
+ definition.
+- [MAC address](https://github.com/vyos/vyos-1x/blob/current/interface-definitions/include/firewall/mac-address.xml.i)
+ assignment.
+
+The `.in` files are preprocessed and stored in the [interface-definitions](https://github.com/vyos/vyos-1x/tree/current/interface-definitions)
+folder. The [scripts/build-command-templates](https://github.com/vyos/vyos-1x/blob/current/scripts/build-command-templates)
+script then operates on this folder to generate all required CLI nodes.
+
+Example preprocessor output:
+
+```none
+$ make interface_definitions
+install -d -m 0755 build/interface-definitions
+install -d -m 0755 build/op-mode-definitions
+Generating build/interface-definitions/intel_qat.xml from interface-definitions/intel_qat.xml.in
+Generating build/interface-definitions/interfaces-bonding.xml from interface-definitions/interfaces-bonding.xml.in
+Generating build/interface-definitions/cron.xml from interface-definitions/cron.xml.in
+Generating build/interface-definitions/pppoe-server.xml from interface-definitions/pppoe-server.xml.in
+Generating build/interface-definitions/mdns-repeater.xml from interface-definitions/mdns-repeater.xml.in
+Generating build/interface-definitions/tftp-server.xml from interface-definitions/tftp-server.xml.in
+[...]
+```
+
+
+### Command Definition Guidelines
+
+#### Use of Numbers
+
+Avoid using numbers in command names unless the number is part of a protocol
+name or similar. For example, `protocols ospfv3` is appropriate,
+but `server-1` is questionable.
+
+#### Help Strings
+
+Follow these guidelines for consistent, readable help strings:
+
+##### Capitalization and Punctuation
+
+- Capitalize the first word of every help string.
+- Do not use a period at the end of help strings.
+
+This standard mirrors network device CLIs and improves aesthetics.
+
+Examples:
+
+- Good: "Frobnication algorithm"
+- Bad: "frobnication algorithm"
+- Bad: "Frobnication algorithm."
+- Incorrect: "frobnication algorithm."
+
+##### Abbreviations and Acronyms
+
+- Capitalize all abbreviations and acronyms.
+
+Examples:
+
+- Good: "TCP connection timeout"
+- Bad: "tcp connection timeout"
+- Bad: "Tcp connection timeout"
+- Capitalize acronyms to distinguish them from normal words.
+
+Examples:
+
+- Good: RADIUS (remote authentication for dial-in user services)
+- Bad: radius (unless referring to circular distance)
+- Follow accepted spelling conventions for mixed-case abbreviations. If it
+ contains "over" or "version", use lowercase. Follow RFC or standard spellings
+ when they exist.
+
+Examples:
+
+- Good: PPPoE, IPsec
+- Bad: PPPOE, IPSEC
+- Bad: pppoe, ipsec
+
+##### Verbs
+
+- Avoid verbs. If a verb can be omitted, omit it.
+
+Examples:
+
+- Good: "TCP connection timeout"
+- Bad: "Set TCP connection timeout"
+- When a verb is essential, use it. For example: "Disable IPv6 forwarding on
+ all interfaces" for `set system ipv6 disable-forwarding`.
+- Use infinitive form for necessary verbs.
+
+Examples:
+
+- Good: "Disable IPv6 forwarding"
+- Bad: "Disables IPv6 forwarding"
+
+## C++ Backend Code
+
+The VyOS CLI parser combines bash, bash-completion helpers, and the C++ backend
+library [vyatta-cfg](https://github.com/vyos/vyatta-cfg). This section
+references common CLI commands and their C/C++ entry points:
+
+`set`:
+
+- <https://github.com/vyos/vyatta-cfg/blob/0f42786a0b3/src/cstore/cstore.cpp#L352>
+- <https://github.com/vyos/vyatta-cfg/blob/0f42786a0b3/src/cstore/cstore.cpp#L2549>
+
+`commit`:
+
+- <https://github.com/vyos/vyatta-cfg/blob/0f42786a0b3/src/commit/commit-algorithm.cpp#L1252>
+
+
diff --git a/docs/contributing/index.md b/docs/contributing/index.md
new file mode 100644
index 00000000..f26a6b70
--- /dev/null
+++ b/docs/contributing/index.md
@@ -0,0 +1,13 @@
+# Contributing
+
+```{toctree}
+:maxdepth: 1
+
+build-vyos
+development
+cla
+issues-features
+upstream-packages
+debugging
+testing
+```
diff --git a/docs/contributing/issues-features.md b/docs/contributing/issues-features.md
new file mode 100644
index 00000000..ab235326
--- /dev/null
+++ b/docs/contributing/issues-features.md
@@ -0,0 +1,122 @@
+---
+lastproofread: '2025-12-08'
+---
+
+(issues_features)=
+
+# Issues/Feature requests
+
+(bug_report)=
+
+## Bug Report/Issue
+
+Issues and bugs occur in every software project, and VyOS is no exception.
+
+### I found a bug, what should I do?
+
+When you find a potential bug, first:
+
+- Consult the [documentation] to ensure you configured your system
+ correctly.
+- Check if the VyOS community has identified a workaround for the bug through
+ [Slack] or the VyOS [Forum].
+
+### Ensure the bug is reproducible
+
+Include the following information when reporting a bug:
+
+- A sequence of configuration commands or a complete configuration file needed
+ to recreate the bug. Avoid partial configurations: a sequence of commands is
+ easy to paste and a complete configuration is easy to load, but a partial
+ config is hard to reconstruct.
+- Describe the expected behavior and how it differs from what you observe.
+ Include command outputs or traffic dumps. Explain briefly why these outputs
+ are incorrect and what the correct behavior should be.
+- A sequence of actions that trigger the bug. While not always possible, this
+ helps developers and community members confirm the issue and verify fixes.
+- If the bug is a regression, specify the VyOS version where the feature worked
+ correctly (any working version is acceptable). Identify the exact version
+ that the feature stopped working, if possible.
+
+If you are uncertain whether the behavior is a bug or what the correct behavior
+is, or if you lack a reliable reproducing procedure, post on the forum or ask in
+chat first. If you have a subscription, create a support ticket. The team and
+community can help identify the issue, work around it, and create an actionable
+bug report.
+
+### Report a Bug
+
+To open a bug report or feature request, create an account on
+[vyos.dev](https://vyos.dev), the public issue tracker for VyOS.
+
+When creating a new issue, select the appropriate project and:
+
+- Provide as much information as you can.
+- Specify which VyOS version you are using: `run show version`.
+- Explain how to reproduce the bug.
+
+(feature-request)=
+
+## Feature Requests
+
+Have an idea to improve VyOS or need a feature that would benefit all users?
+Before submitting a feature request, search the public issue tracker
+[vyos.dev](https://vyos.dev) to check if a request already exists. You can
+also enhance an existing request by providing additional information.
+
+Create a task before starting work on a feature,
+even if it is a trivial feature.
+The task tracker generates release notes, so all work must be reflected
+in the tracker.
+
+Include at least the following information:
+
+- Provide a detailed description of the feature: what it is, how it works, and
+ how you would use it. Maintainers may not have experience with every feature,
+ protocol, and tool in VyOS. Detailed information helps VyOS contributors and
+ maintainers test new features they are unfamiliar with.
+- Include proposed CLI syntax if the feature requires new commands. Provide both
+ configuration and operational mode commands if both are needed.
+
+Consider including the following information:
+
+- Is the feature already supported by the underlying component
+ (FreeRangeRouting, nftables, Kea, etc.)?
+- How would you configure the feature manually within that component?
+- Are there any limitations to using the feature
+ (hardware support, resource usage)?
+- Are there any adverse or non-obvious interactions with other features? Should
+ the feature be mutually exclusive?
+- Any relevant documentation or references about the feature.
+
+You do not need to provide all this information, but if you can, it simplifies
+developers' work considerably. Research these questions when possible.
+
+## Task auto-closing
+
+A special task status exists for when all work by maintainers and contributors
+is complete: **Needs reporter action**.
+
+VyOS assigns this status to:
+
+- Feature requests that do not include required information and need
+ clarification.
+- Bug reports that lack reproducing procedures.
+- Tasks that are implemented and tested by the implementation author,
+ but require testing in the real-world environment that only the reporter
+ can replicate (for example, hardware VyOS does not support or specific
+ network conditions).
+
+When a task is set to **Needs reporter action**:
+
+- If the reporter does not respond within two weeks, the task bot adds a comment
+ ("Any news?") to remind the reporter.
+- If there is still no response after another two weeks,
+ the task is closed automatically.
+
+We do not auto-close tasks with any other status and do not close tasks due to
+lack of maintainer activity.
+
+[documentation]: https://docs.vyos.io
+[forum]: https://forum.vyos.io
+[slack]: https://slack.vyos.io
diff --git a/docs/contributing/testing.md b/docs/contributing/testing.md
new file mode 100644
index 00000000..b68cad1b
--- /dev/null
+++ b/docs/contributing/testing.md
@@ -0,0 +1,207 @@
+---
+lastproofread: '2025-12-02'
+---
+
+(testing)=
+
+# Testing
+
+One of the major features introduced in VyOS 1.3 is an automated test
+framework. When you assemble an ISO image, several things can go wrong.
+VyOS uses this framework to detect issues before they cause downstream problems.
+
+This section describes how the automated testing process at VyOS works.
+
+## Smoketests
+
+Smoketests execute predefined VyOS CLI commands and check if the desired
+daemon or service configuration is rendered.
+
+When an ISO image is assembled by the [VyOS CI](https://ci.vyos.net), the `BUILD_SMOKETEST`
+parameter is enabled by default. This extends the ISO configuration line
+with the following packages:
+
+```python
+def CUSTOM_PACKAGES = ''
+ if (params.BUILD_SMOKETESTS)
+ CUSTOM_PACKAGES = '--custom-package vyos-1x-smoketest'
+```
+
+If you plan to build your own custom ISO image and want to use VyOS's
+smoketests, ensure that you have the `vyos-1x-smoketest` package installed.
+
+The `make test` command from the [vyos-build](https://github.com/vyos/vyos-build) repository launches a new
+QEMU instance, and the ISO image is first installed to the virtual hard disk.
+
+After the first boot into the newly installed system, the main Smoketest script
+is executed. It can be found at `/usr/bin/vyos-smoketest`.
+
+The script searches for executable test cases under
+`/usr/libexec/vyos/tests/smoke/cli/` and executes them one by one.
+
+:::{note}
+Smoketests will alter the system configuration. If you are logged
+in remotely, you may lose your connection to the system.
+:::
+
+:::{note}
+To enable smoketest debugging (print the CLI set commands used),
+run: `touch /tmp/vyos.smoketest.debug`.
+:::
+
+### Manual Smoketest Run
+
+Each test is contained in its own file, so you can execute a single Smoketest
+manually by running the Python test script.
+
+Example:
+
+```none
+vyos@vyos:~$ /usr/libexec/vyos/tests/smoke/cli/test_protocols_bgp.py
+test_bgp_01_simple (__main__.TestProtocolsBGP) ... ok
+test_bgp_02_neighbors (__main__.TestProtocolsBGP) ... ok
+test_bgp_03_peer_groups (__main__.TestProtocolsBGP) ... ok
+test_bgp_04_afi_ipv4 (__main__.TestProtocolsBGP) ... ok
+test_bgp_05_afi_ipv6 (__main__.TestProtocolsBGP) ... ok
+test_bgp_06_listen_range (__main__.TestProtocolsBGP) ... ok
+test_bgp_07_l2vpn_evpn (__main__.TestProtocolsBGP) ... ok
+test_bgp_08_zebra_route_map (__main__.TestProtocolsBGP) ... ok
+test_bgp_09_distance_and_flowspec (__main__.TestProtocolsBGP) ... ok
+test_bgp_10_vrf_simple (__main__.TestProtocolsBGP) ... ok
+test_bgp_11_confederation (__main__.TestProtocolsBGP) ... ok
+test_bgp_12_v6_link_local (__main__.TestProtocolsBGP) ... ok
+test_bgp_13_solo (__main__.TestProtocolsBGP) ... ok
+
+----------------------------------------------------------------------
+Ran 13 tests in 348.191s
+
+OK
+```
+
+
+### Interface-based tests
+
+Our smoketests not only test daemons and services, but also check if interface
+configuration works as expected. There is a common base class named
+`base_interfaces_test.py` that holds all the common code for interface tests.
+
+These common tests consist of:
+
+- Add one or more IP addresses
+
+- DHCP client and DHCPv6 prefix delegation
+
+- MTU size
+
+- IP and IPv6 options
+
+- Port description
+
+- Port disable
+
+- VLANs (QinQ and regular 802.1q)
+
+- ...
+
+:::{note}
+When you are working on interface configuration and want to test
+if the Smoketests pass, you would normally lose the remote SSH connection
+to your {abbr}`DUT (Device Under Test)`. To handle this, some interface-based
+tests can be called with an environment variable beforehand to limit the
+number of interfaces used in the test. By default, all interfaces (e.g., all
+Ethernet interfaces) are used.
+:::
+
+```none
+vyos@vyos:~$ TEST_ETH="eth1 eth2" /usr/libexec/vyos/tests/smoke/cli/test_interfaces_bonding.py
+test_add_multiple_ip_addresses (__main__.BondingInterfaceTest) ... ok
+test_add_single_ip_address (__main__.BondingInterfaceTest) ... ok
+test_bonding_hash_policy (__main__.BondingInterfaceTest) ... ok
+test_bonding_lacp_rate (__main__.BondingInterfaceTest) ... ok
+test_bonding_min_links (__main__.BondingInterfaceTest) ... ok
+test_bonding_remove_member (__main__.BondingInterfaceTest) ... ok
+test_dhcpv6_client_options (__main__.BondingInterfaceTest) ... ok
+test_dhcpv6pd_auto_sla_id (__main__.BondingInterfaceTest) ... ok
+test_dhcpv6pd_manual_sla_id (__main__.BondingInterfaceTest) ... ok
+test_interface_description (__main__.BondingInterfaceTest) ... ok
+test_interface_disable (__main__.BondingInterfaceTest) ... ok
+test_interface_ip_options (__main__.BondingInterfaceTest) ... ok
+test_interface_ipv6_options (__main__.BondingInterfaceTest) ... ok
+test_interface_mtu (__main__.BondingInterfaceTest) ... ok
+test_ipv6_link_local_address (__main__.BondingInterfaceTest) ... ok
+test_mtu_1200_no_ipv6_interface (__main__.BondingInterfaceTest) ... ok
+test_span_mirror (__main__.BondingInterfaceTest) ... ok
+test_vif_8021q_interfaces (__main__.BondingInterfaceTest) ... ok
+test_vif_8021q_lower_up_down (__main__.BondingInterfaceTest) ... ok
+test_vif_8021q_mtu_limits (__main__.BondingInterfaceTest) ... ok
+test_vif_8021q_qos_change (__main__.BondingInterfaceTest) ... ok
+test_vif_s_8021ad_vlan_interfaces (__main__.BondingInterfaceTest) ... ok
+test_vif_s_protocol_change (__main__.BondingInterfaceTest) ... ok
+
+----------------------------------------------------------------------
+Ran 23 tests in 244.694s
+
+OK
+```
+
+This will limit the `bond` interface test to use only `eth1` and `eth2`
+as member ports.
+
+## Config Load Tests
+
+The other part of our tests are called "config load tests." Config load tests
+sequentially load arbitrary configuration files to verify that configuration
+migration scripts work as designed and that a given set of functionality can
+still be loaded with a fresh VyOS ISO image.
+
+The configurations are all derived from production systems and can act as
+test cases or as references for enabling certain features. The configurations
+can be found here:
+<https://github.com/vyos/vyos-1x/tree/current/smoketest/configs>
+
+The entire test is controlled by the main wrapper script
+`/usr/bin/vyos-configtest`.
+It behaves in the same way as the main smoketest script. It scans the folder
+for potential configuration files and issues a `load` command for each file.
+
+### Manual config load test
+
+You do not have to load all configurations sequentially; you can also load
+individual test configurations manually.
+
+```none
+vyos@vyos:~$ configure
+load[edit]
+
+vyos@vyos# load /usr/libexec/vyos/tests/config/ospf-small
+Loading configuration from '/usr/libexec/vyos/tests/config/ospf-small'
+Load complete. Use 'commit' to make changes effective.
+[edit]
+vyos@vyos# compare
+[edit interfaces ethernet eth0]
+-hw-id 00:50:56:bf:c5:6d
+[edit interfaces ethernet eth1]
++duplex auto
+-hw-id 00:50:56:b3:38:c5
++speed auto
+[edit interfaces]
+-ethernet eth2 {
+- hw-id 00:50:56:b3:9c:1d
+-}
+-vti vti1 {
+- address 192.0.2.1/30
+-}
+...
+
+vyos@vyos# commit
+vyos@vyos#
+```
+
+:::{note}
+Some configurations have preconditions that must be met. These most
+likely include generation of cryptographic keys before the config can be
+applied; otherwise, you will get a commit error. If you are interested in
+how those preconditions are fulfilled, check the [vyos-build](https://github.com/vyos/vyos-build) repository and
+the `scripts/check-qemu-install` file.
+:::
+
diff --git a/docs/contributing/upstream-packages.md b/docs/contributing/upstream-packages.md
new file mode 100644
index 00000000..fe01df82
--- /dev/null
+++ b/docs/contributing/upstream-packages.md
@@ -0,0 +1,147 @@
+---
+lastproofread: '2026-01-30'
+---
+
+(upstream-packages)=
+
+# Upstream Packages
+
+Many base system packages are pulled straight from Debian's `main` and
+`contrib` repositories, but there are exceptions. If you only want to build
+a fresh ISO image, you can skip
+this section. This information may be useful for a deeper dive into VyOS.
+
+System packages that are not directly pulled from Debian are built through a
+separate build system, `build.py` in the [vyos-build](https://github.com/vyos/vyos-build/tree/current/scripts/package-build) repository.
+
+## Overview
+
+Previously, VyOS used Jenkins for building upstream packages. With the move away
+from Jenkins, the build system was replaced with a Python-based solution using
+`build.py` and `package.toml` configuration files.
+
+Each package directory contains:
+
+- A `package.toml` configuration file that defines how the package is built.
+- A symlink to the common `build.py` script in the build system.
+
+## Building Packages
+
+To build a package, navigate to the package directory and execute the
+build script:
+
+```console
+cd package-build/<package-name>
+./build.py
+```
+
+The script will:
+
+1. Check out the source code from the configured repository.
+2. Apply any patches defined in the configuration.
+3. Execute pre-build hooks (if configured).
+4. Build the package using the specified build command.
+5. Generate both binary (`.deb`) packages and source tarballs.
+
+## Package Configuration (package.toml)
+
+Each package directory contains a `package.toml` file that defines the build
+parameters. The key configuration fields are:
+
+```{eval-rst}
+**name**
+ The package name (e.g., ``frr``)
+
+**commit_id**
+ The specific commit, tag, or branch to check out from the source repository
+ (e.g., ``stable/10.5``)
+
+**scm_url**
+ The Git URL of the upstream source repository
+ (e.g., ``https://github.com/FRRouting/frr.git``)
+
+.. stop_vyoslinter
+**build_cmd**
+ The command to execute for building the package. This replaces what was
+ previously defined in the Jenkins ``Jenkinsfile``.
+
+ Default if not specified: ``dpkg-buildpackage -uc -us -tc -F --source-option=--tar-ignore=.git --source-option=--tar-ignore=.github``
+
+ Example with custom build command:
+
+ .. code-block:: toml
+
+ build_cmd = "sudo dpkg -i ../*.deb; dpkg-buildpackage -us -uc -tc -b -Ppkg.frr.rtrlib,pkg.frr.lua"
+.. start_vyoslinter
+
+**pre_build_hook** (Optional)
+ A shell command or script that executes after the repository is checked out
+ and before the build process begins. This allows you to perform preparatory
+ tasks such as:
+
+ - Creating directories
+ - Copying files
+ - Running custom setup scripts
+ - Installing dependencies
+
+ Single command example:
+
+ .. code-block:: toml
+
+ pre_build_hook = "echo 'Preparing build environment'"
+
+ Multi-line commands example:
+
+ .. code-block:: toml
+
+ pre_build_hook = """
+ mkdir -p ../hello/vyos
+ mkdir -p ../vyos
+ cp example.txt ../vyos
+ """
+
+ Combined commands and scripts:
+
+ .. code-block:: toml
+
+ pre_build_hook = "ls -l; ./script.sh"
+
+**apply_patches** (Optional)
+ Boolean flag to control whether patches should be applied. Defaults to
+ ``True``.
+
+ .. code-block:: toml
+
+ apply_patches = false
+
+**prepare_package** (Optional)
+ Boolean flag to enable package preparation. When set to ``True``, the
+ ``install_data`` configuration is used.
+
+**install_data** (Optional)
+ Data used for package preparation when ``prepare_package`` is enabled.
+```
+
+## Example package.toml file
+
+Here's an example configuration for the FRRouting (FRR) package:
+
+```toml
+name = "frr"
+commit_id = "stable/10.5"
+scm_url = "https://github.com/FRRouting/frr.git"
+build_cmd = "sudo dpkg -i ../*.deb; dpkg-buildpackage -us -uc -tc -b -Ppkg.frr.rtrlib,pkg.frr.lua"
+```
+
+
+## Build Output
+
+After running `./build.py`, the following artifacts are generated in the
+package directory:
+
+- `.deb` files - Binary Debian packages ready for installation
+- `.tar.gz` files - Source tarballs of the checked-out repositories
+- Additional build artifacts as produced by the Debian build system
+
+The build script also creates build dependency packages (`*build-deps*.deb`),
+which are automatically cleaned up after the build completes.
diff --git a/docs/coverage.md b/docs/coverage.md
new file mode 100644
index 00000000..fff0dc4e
--- /dev/null
+++ b/docs/coverage.md
@@ -0,0 +1,59 @@
+---
+lastproofread: '2025-11-14'
+---
+
+# Coverage
+
+Overview over all commands that are documented in the
+`.. cfgcmd::` or `.. opcmd::` directives.
+
+The build process takes all XML definition files
+from the [vyos-1x](https://github.com/vyos/vyos-1x) repository and a
+periodical export of all VyOS commands and extracts each leaf command, or
+executable command.
+The script compares only the fixed part of a command.
+All variables and values are removed and the string of the commands
+are compared.
+
+For example, take the following two commands:
+
+- documentation: `interfaces ethernet <interface> address
+ <address | dhcp | dhcpv6>`
+- xml: `interfaces ethernet <ethernet> address <address>`
+- VyOS: `interfaces ethernet <text> address <value>`
+
+**There are 3 kinds of issues with commands in the following tables:**
+
+`Not documented yet`
+
+- An XML command is not found in `.. cfgcmd::` or `.. opcmd::` directives.
+- The command should be documented.
+
+`Nothing found in XML Definitions`
+
+- `.. cfgcmd::` or `.. opcmd::` The command is not found in the XML
+ definition.
+- The command location may have changed in the XML definition, the feature
+ is no longer supported in VyOS, or there is a typo in the command.
+
+`Nothing found in VyOS`
+
+- `.. cfgcmd::` or `.. opcmd::` The command is not found in VyOS
+ documentation or the XML definition.
+- The command location may have changed in the XML definition, the feature
+ is no longer supported in VyOS, or there is a typo in the command.
+
+The final list of commands are shown in
+the following two tables:
+
+## Configuration Commands
+
+```{cfgcmdlist}
+:show-coverage:
+```
+
+## Operational Commands
+
+```{opcmdlist}
+:show-coverage:
+``` \ No newline at end of file
diff --git a/docs/documentation.md b/docs/documentation.md
new file mode 100644
index 00000000..6a25a413
--- /dev/null
+++ b/docs/documentation.md
@@ -0,0 +1,442 @@
+---
+lastproofread: '2021-06-25'
+---
+
+(documentation)=
+
+# Write Documentation
+
+We encourage every VyOS user to help us improve our documentation as we have
+a deficit like most software projects. This not only helps you when reading
+but also everyone else.
+
+:::{warning}
+Please read and sign the
+{doc}`Contributor License Agreement<contributing/cla>` before submitting any
+documentation updates.
+:::
+
+If you are willing to contribute to our documentation this is the definite
+guide how to do so.
+
+:::{note}
+In contrast to submitting code patches, there is no requirement that
+you open up a [Phabricator](https://vyos.dev/) task prior to submitting a Pull-Request to the
+documentation.
+:::
+
+VyOS documentation is written in reStructuredText and generated to Read the Docs
+pages with Sphinx, as per the Python tradition. We welcome all sorts of
+contributions to the documentation.
+Not just new additions but also corrections to existing documentation.
+
+The documentation source is kept in the Git repository at
+<https://github.com/vyos/vyos-documentation> and you can follow the instructions
+in the [README.md] to build and test your changes.
+
+You can either install Sphinx and build the documentation locally,
+or use the [Dockerfile] to build it in a container.
+
+## Guidelines
+
+There are a few things to keep in mind when contributing to the
+documentation, for the sake of consistency and readability.
+
+The following is a quick summary of the rules:
+
+- Use American English at all times. It's always a good idea to run
+ your text through a grammar and spell checker, such as [Grammarly].
+- Don't forget to update `index.rst` when adding a new node.
+- Try not to exceed 80 characters per line, but don't break URLs over this.
+- Properly quote commands, filenames and brief code snippets with double backticks.
+- Use literal blocks for longer snippets.
+- Leave a newline before and after a header.
+- Indent with two spaces.
+- When in doubt, follow the style of existing documentation.
+
+And finally, remember that the reStructuredText files aren't
+exclusively for generating HTML and PDF. They should be human-readable
+and easily perused from a console.
+
+## Page content
+
+All RST files must follow the same TOC Level syntax and have to start with
+
+```{eval-rst}
+.. code-block::
+
+ #####
+ Title
+ #####
+```
+
+The configuration mode folder and the articles cover the specific level of
+the commands. The exact level depends on the command. This should provide
+stability for URLs used in the forum or blogpost.
+
+For example:
+
+> - `set firewall zone` is written in `firewall/zone.rst`
+> - `set interfaces ethernet` is written in `interfaces/ethernet.rst`
+
+In the configuration part of the page, all possible configuration options
+should be documented. Use `.. cfgcmd::` described above.
+
+Related operation command must be documented in the next part of the article.
+Use `::opcmd..` for these commands.
+
+Each page must contain the following parts:
+
+### 1. Theoretical information
+
+Theoretical information required for users to understand the next document sections:
+
+> - a simple explanation of what is this page about, why or when it is required to be used
+> - references to standards, RFCs
+
+### 2. Configuration description
+
+> Describe CLI items related to the service or use case. Each config line
+> or section must be explained, using information provided in the 1st part
+> of the page.
+
+### 3. Configuration examples
+
+> Practical examples of the service or use case configuration. They must
+> contain topology maps (if applicable) and short descriptions.
+
+### 4. Known issues
+
+This section must contain a list of:
+
+> - known issues or potential problems for the service or use case
+> - workarounds for known issues (if any exist)
+
+### 5. Debugging
+
+Described procedures for debugging a service:
+
+> - how to collect logs or other debugging information (like `show` commands output)
+> - how to read and what to search for in logs and collected information
+> - what are indicators of good and bad states in debugging outputs
+
+## Style Guide
+
+### Formatting and Sphinxmarkup
+
+#### TOC Level
+
+We use the following syntax for Headlines.
+
+```none
+#####
+Title
+#####
+
+********
+Chapters
+********
+
+Sections
+========
+
+Subsections
+-----------
+
+Subsubsections
+^^^^^^^^^^^^^^
+
+Paragraphs
+""""""""""
+```
+
+
+#### Cross-References
+
+A plugin will be used to generate a reference label for each headline.
+To reference a page or a section in the documentation use the
+`{ref}` command.
+
+For example, you want to reference the headline **VLAN** in the
+**ethernet.rst** page. The plugin generates the label based on
+the headline and the file path.
+
+`` {ref}`configuration/interfaces/ethernet:vlan ``
+
+to use an alternative hyperlink use it this way:
+
+`` {ref}`Check out VLAN<configuration/interfaces/ethernet:vlan> ``
+
+##### handle build errors
+
+The plugin will warn on build if a headline has a duplicate name in the
+same document. To prevent this warning, you have to put a custom link on
+top of the headline.
+
+```none
+Section A
+==========
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr
+
+Example
+-------
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr
+
+Section B
+==========
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr
+
+.. _section B example:
+
+Example
+-------
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr
+```
+
+
+#### Address space
+
+Note the following RFCs ({rfc}`5737`, {rfc}`3849`, {rfc}`5389` and
+{rfc}`7042`), which describe the reserved public IP addresses and autonomous
+system numbers for the documentation:
+
+> - `192.0.2.0/24`
+> - `198.51.100.0/24`
+> - `203.0.113.0/24`
+> - `2001:db8::/32`
+> - 16bit ASN: `64496 - 64511`
+> - 32bit ASN: `65536 - 65551`
+> - Unicast MAC Addresses: `00-53-00` to `00-53-FF`
+> - Multicast MAC-Addresses: `90-10-00` to `90-10-FF`
+
+Please do not use other public address space.
+
+#### Line length
+
+Limit all lines to a maximum of 80 characters.
+
+Except in `.. code-block::` because it uses the html tag `<pre>` and
+renders the same line format from the source rst file.
+
+#### Autolinter
+
+Each GitHub pull request is automatically linted to check the address space and
+line length.
+
+Sometimes it is necessary to provide real IP addresses like in the
+{ref}`examples`. For this, please use the sphinx comment syntax
+`.. stop_vyoslinter` to stop the linter and `.. start_vyoslinter` to start.
+
+#### Custom Sphinx-doc Markup
+
+Custom commands have been developed for writing the documentation. Please
+make yourself comfortable with those commands as this eases the way we
+render the documentation.
+
+##### cfgcmd
+
+When documenting CLI commands, use the ``.. cfgcmd::`` directive
+for all configuration mode commands. An explanation of the described command
+should be added below this statement.
+Replace all variable contents with \<value> or something similar.
+
+With those custom commands, it will be possible to render them in a more
+descriptive way in the resulting HTML/PDF manual.
+
+```none
+.. cfgcmd:: protocols static arp <ipaddress> hwaddr <macaddress>
+
+ This will configure a static ARP entry, always resolving `192.0.2.100` to
+ `00:53:27:de:23:aa`.
+```
+
+For an inline configuration level command, use ``:cfgcmd:``
+
+```none
+:cfgcmd:`set interface ethernet eth0`
+```
+
+
+To extract a defaultvalue from the XML definitions add a ``:defaultvalue:``
+to ``.. cfgcmd::`` directive.
+To have this feature locally, the vyos-1x submodule must be initialized before.
+Please be aware to not update the submodule in your PR.
+
+```none
+.. cfgcmd:: set system conntrack table-size <1-50000000>
+ :defaultvalue:
+
+ The connection tracking table contains one entry for each connection being
+ tracked by the system.
+```
+
+
+##### opcmd
+
+When documenting operational level commands, use the ``.. opcmd::`` directive.
+An explanation of the described command should be added below this statement.
+
+With those custom commands, it is possible to render them in a more
+descriptive way in the resulting HTML/PDF manual.
+
+```none
+.. opcmd:: show protocols static arp
+
+ Display all known ARP table entries spanning across all interfaces
+```
+
+For an inline operational level command, use ``:opcmd:``
+
+```none
+:opcmd:`add system image`
+```
+
+##### cmdinclude
+
+To minimize redundancy, there is a special include directive. It includes a txt
+file and replace the `{{ var0 }}` - `{{ var9 }}` with the correct value.
+
+```none
+.. cmdinclude:: /_include/interface-address.txt
+ :var0: ethernet
+ :var1: eth1
+```
+
+the content of interface-address.txt looks like this
+
+```none
+.. cfgcmd:: set interfaces {{ var0 }} <interface> address <address | dhcp |
+ dhcpv6>
+
+ Configure interface `<interface>` with one or more interface
+ addresses.
+
+ * **address** can be specified multiple times as IPv4 and/or IPv6
+ address, e.g. 192.0.2.1/24 and/or 2001:db8::1/64
+ * **dhcp** interface address is received by DHCP from a DHCP server
+ on this segment.
+ * **dhcpv6** interface address is received by DHCPv6 from a DHCPv6
+ server on this segment.
+
+ Example:
+
+ .. code-block:: none
+
+ set interfaces {{ var0 }} {{ var1 }} address 192.0.2.1/24
+ set interfaces {{ var0 }} {{ var1 }} address 192.0.2.2/24
+ set interfaces {{ var0 }} {{ var1 }} address 2001:db8::ffff/64
+ set interfaces {{ var0 }} {{ var1 }} address 2001:db8:100::ffff/64
+```
+##### vytask
+
+When referencing to VyOS Phabricator Tasks, there is a custom Sphinx Markup
+command called `vytask` that automatically renders to a proper Phabricator
+URL. This is heavily used in the {ref}`release-notes` section.
+
+```none
+* {vytask}`T1605` Fixed regression in L2TP/IPsec server
+* {vytask}`T1613` Netflow/sFlow captures IPv6 traffic correctly
+```
+
+## Forking Workflow
+
+The Forking Workflow is fundamentally different from other popular Git
+workflows. Instead of using a single server-side repository to act as the
+"central" codebase, it gives every developer their own server-side repository.
+This means that each contributor has not one, but two Git repositories: a
+private local one and a public server-side one.
+
+The main advantage of the Forking Workflow is that contributions can be
+integrated without the need for everybody to push to a single central
+repository. Developers push to their own server-side repositories, and only the
+project maintainer can push to the official repository. This allows the
+maintainer to accept commits from any developer without giving them write
+access to the official codebase.
+
+:::{note}
+Updates to our documentation should be delivered by a GitHub
+pull-request. This requires you already have a GitHub account.
+:::
+
+
+- Fork this project on GitHub <https://github.com/vyos/vyos-documentation/fork>
+
+- Clone fork to local machine, then change to that directory
+ `$ cd vyos-documentation`
+
+- Install the requirements `$ pip install -r requirements.txt`
+ (or something similar)
+
+- Create a new branch for your work, use a descriptive name of your work:
+ `$ git checkout -b <branch-name>`
+
+- Make all your changes - please keep our commit rules in mind
+ ({ref}`prepare_commit`). This mainly applies to proper commit messages
+ describing your change (how and why). Please check out the documentation of
+ [Sphinx-doc] or [reStructuredText] if you are not familiar with it. This is used
+ for writing our docs. Additional directives how to write in RST can be
+ obtained from [reStructuredTextDirectives].
+
+- Check your changes by locally building the documentation `$ make livehtml`.
+ Sphinx will build the html files in the `docs/_build` folder. We provide
+ you with a Docker container for an easy-to-use user experience. Check the
+ [README.md] file of this repository.
+
+- View modified files by calling `$ git status`. You will get an overview of
+ all files modified by you. You can add individual files to the Git Index in
+ the next step.
+
+- Add modified files to Git index `$ git add path/to/filename` or add all
+ unstaged files `$ git add .`. All files added to the Git index will be part
+ of you following Git commit.
+
+- Commit your changes with the message, `$ git commit -m "<commit message>"`
+ or use `$ git commit -v` to have your configured editor launched. You can
+ type in a commit message. Again please make yourself comfortable without
+ rules ({ref}`prepare_commit`).
+
+- Push commits to your GitHub project: `$ git push -u origin <branch-name>`
+
+- Submit pull-request. In GitHub visit the main repository and you should
+ see a banner suggesting to make a pull request. Fill out the form and
+ describe what you do.
+
+- Once pull requests have been approved, you may want to locally update
+ your forked repository too. First you'll have to add a second remote
+ called `upstream` which points to our main repository. `$ git remote add
+ upstream https://github.com/vyos/vyos-documentation.git`
+
+ Check your configured remote repositories:
+
+ ```none
+ $ git remote -v
+ origin https://github.com/<username>/vyos-documentation.git (fetch)
+ origin https://github.com/<username>/vyos.documentation.git (push)
+ upstream https://github.com/vyos/vyos-documentation.git (fetch)
+ upstream https://github.com/vyos/vyos-documentation.git (push)
+
+ ```
+
+ Your remote repo on Github is called `origin`, while the original repo you
+ have forked is called `upstream`. Now you can locally update your forked
+ repo.
+
+ ```none
+ $ git fetch upstream
+ $ git checkout current
+ $ git merge upstream/current
+```
+
+- If you also want to update your fork on GitHub, use the following: `$ git
+ push origin current`
+
+[dockerfile]: https://github.com/vyos/vyos-documentation/blob/current/docker/Dockerfile
+[grammarly]: https://www.grammarly.com/
+[readme.md]: https://github.com/vyos/vyos-documentation/blob/current/README.md
+[restructuredtext]: http://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html
+[restructuredtextdirectives]: https://docutils.sourceforge.io/docs/ref/rst/directives.html
+[sphinx-doc]: https://www.sphinx-doc.org
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..359fea44
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,113 @@
+(index)=
+
+# VyOS User Guide
+
+::::::{grid} 3
+:gutter: 2
+
+:::::{grid-item-card} Get / Build VyOS
+
+Quickly {ref}`Build<contributing/build-vyos:build vyos>`
+your own Image or take a look at how to
+{ref}`download<installation/install:download>`
+a free or supported version.
+:::::
+
+:::::{grid-item-card} Install VyOS
+
+Read about how to install VyOS on
+{ref}`Bare Metal<installation/install:installation>`
+or in a {ref}`VM <installation/virtual/index:Virtual Environments>`
+and how to use an image with the usual
+{ref}`cloud<installation/cloud/index:Cloud Environments>`
+providers
+:::::
+
+:::::{grid-item-card} Configuration and Operation
+
+Use the {ref}`Quickstart Guide<quick-start:Quick Start>`,
+to have a fast overview. Or go deeper and set up
+{ref}`advanced routing<configuration/protocols/index:protocols>`,
+{ref}`VRFs<configuration/vrf/index:vrf>`, or
+{ref}`VPNs<configuration/vpn/index:vpn>` for example.
+:::::
+
+:::::{grid-item-card} Automate
+
+Integrate VyOS in your automation Workflow with
+{ref}`Ansible<vyos-ansible>`,
+have your own {ref}`local scripts<command-scripting>`,
+or configure VyOS with the
+{ref}`HTTPS-API<vyosapi>`.
+:::::
+
+:::::{grid-item-card} Examples
+
+Get some inspiration from the
+{ref}`Blueprints <configexamples/index:Configuration Blueprints>`
+to build your infrastructure.
+:::::
+
+:::::{grid-item-card} Contribute and Community
+
+There are many ways to contribute to the project.
+Add missing parts or improve the
+{ref}`Documentation<documentation:Write Documentation>`.
+
+Discuss in [Slack](https://slack.vyos.io/)
+or the [Forum](https://forum.vyos.io).
+
+Or you can pick up a [Task](https://vyos.dev/)
+and fix the
+{ref}`code<contributing/development:development>`.
+:::::
+::::::
+
+```{toctree}
+:hidden: true
+:maxdepth: 1
+
+introducing/about
+introducing/history
+```
+
+```{toctree}
+:caption: First Steps
+:hidden: true
+:maxdepth: 2
+
+installation/index
+quick-start
+cli
+```
+
+```{toctree}
+:caption: Adminguide
+:hidden: true
+:maxdepth: 2
+
+configuration/index
+operation/index
+automation/index
+troubleshooting/index
+configexamples/index
+vpp/index
+```
+
+```{toctree}
+:caption: Development
+:hidden: true
+:maxdepth: 2
+
+contributing/index
+```
+
+```{toctree}
+:caption: Misc
+:hidden: true
+:maxdepth: 2
+
+documentation
+coverage
+copyright
+```
diff --git a/docs/installation/bare-metal.md b/docs/installation/bare-metal.md
new file mode 100644
index 00000000..ed813545
--- /dev/null
+++ b/docs/installation/bare-metal.md
@@ -0,0 +1,626 @@
+(vyosonbaremetal)=
+
+# Bare Metal Deployment
+
+## Supermicro A2SDi (Atom C3000)
+
+I opted to get one of the new Intel Atom C3000 CPUs to spawn VyOS on it.
+Running VyOS on an UEFI only device is supported as of VyOS release 1.2.
+
+### Supermicro Shopping Cart
+
+- 1x Supermicro CSE-505-203B (19" 1U chassis, inkl. 200W PSU)
+- 1x Supermicro MCP-260-00085-0B (I/O Shield for A2SDi-2C-HLN4F)
+- 1x Supermicro A2SDi-2C-HLN4F (Intel Atom C3338, 2C/2T, 4MB cache, Quad LAN
+ with Intel C3000 SoC 1GbE)
+- 1x Crucial CT4G4DFS824A (4GB DDR4 RAM 2400 MT/s, PC4-19200)
+- 1x SanDisk Ultra Fit 32GB (USB-A 3.0 SDCZ43-032G-G46 mass storage for OS)
+- 1x Supermicro MCP-320-81302-0B (optional FAN tray)
+
+### Optional (10GE)
+
+If you want to get additional ethernet ports or even 10GE connectivity
+the following optional parts will be required:
+
+- 1x Supermicro RSC-RR1U-E8 (Riser Card)
+- 1x Supermicro MCP-120-00063-0N (Riser Card Bracket)
+
+Latest VyOS rolling releases boot without any problem on this board. You also
+receive a nice IPMI interface realized with an ASPEED AST2400 BMC (no
+information about [OpenBMC](https://www.openbmc.org/) so far on this
+motherboard).
+
+### Pictures
+
+:::{figure} /_static/images/1u_vyos_back.webp
+:alt: CSE-505-203B Back
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front.webp
+:alt: CSE-505-203B Front
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_1.webp
+:alt: CSE-505-203B Open 1
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_2.webp
+:alt: CSE-505-203B Open 2
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_3.webp
+:alt: CSE-505-203B Open 3
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_1.webp
+:alt: CSE-505-203B w/ 10GE Open 1
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_2.webp
+:alt: CSE-505-203B w/ 10GE Open 2
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_3.webp
+:alt: CSE-505-203B w/ 10GE Open 3
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_4.webp
+:alt: CSE-505-203B w/ 10GE Open
+:scale: 25 %
+:::
+
+(pc-engines-apu4)=
+
+## PC Engines APU4
+
+As this platform seems to be quite common in terms of noise, cost, power and
+performance it makes sense to write a small installation manual.
+
+This guide was developed using an APU4C4 board with the following specs:
+
+- AMD Embedded G series GX-412TC, 1 GHz quad Jaguar core with 64 bit and AES-NI
+ support, 32K data + 32K instruction cache per core, shared 2MB L2 cache.
+- 4 GB DDR3-1333 DRAM, with optional ECC support
+- About 6 to 10W of 12V DC power depending on CPU load
+- 2 miniPCI express (one with SIM socket for 3G modem).
+- 4 Gigabit Ethernet channels using Intel i211AT NICs
+
+The board can be powered via 12V from the front or via a 5V onboard connector.
+
+(vyos-on-baremetal-apu4-shopping)=
+
+### APU4 Shopping Cart
+
+- 1x apu4c4 = 4 i211AT LAN / AMD GX-412TC CPU / 4 GB DRAM / dual SIM
+- 1x Kingston SUV500MS/120G
+- 1x VARIA Group Item 326745 19" dual rack for APU4
+
+The 19" enclosure can accommodate up to two APU4 boards - there is a single and
+dual front cover.
+
+#### Extension Modules
+
+##### WiFi
+
+Refer to {ref}`wireless-interface` for additional information, below listed
+modules have been tested successfully on this Hardware platform:
+
+- Compex WLE900VX mini-PCIe WiFi module, only supported in mPCIe slot 1.
+- Intel Corporation AX200 mini-PCIe WiFi module, only supported in mPCIe slot 1.
+ (see {ref}`wireless-interface-intel-ax200`)
+
+##### WWAN
+
+Refer to {ref}`wwan-interface` for additional information, below listed modules
+have been tested successfully on this Hardware platform using VyOS 1.3
+(equuleus):
+
+- Sierra Wireless AirPrime MC7304 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7430 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7455 miniPCIe card (LTE)
+- Sierra Wireless AirPrime MC7710 miniPCIe card (LTE)
+- Huawei ME909u-521 miniPCIe card (LTE)
+
+### VyOS 1.4 (sagitta)
+
+Depending on the VyOS versions you intend to install there is a difference in
+the serial port settings ({vytask}`T1327`).
+
+Create a bootable USB pendrive using e.g. [Rufus] on a Windows machine.
+
+Connect serial port to a PC through null modem cable (RXD / TXD crossed over).
+Set terminal emulator to 115200 8N1.
+
+```none
+PC Engines apu4
+coreboot build 20171130
+BIOS version v4.6.4
+4080 MB ECC DRAM
+SeaBIOS (version rel-1.11.0.1-0-g90da88d)
+
+Press F10 key now for boot menu:
+
+Select boot device:
+
+1. ata0-0: KINGSTON SUV500MS120G ATA-11 Hard-Disk (111 GiBytes)
+2. USB MSC Drive Generic Flash Disk 8.07
+3. Payload [memtest]
+4. Payload [setup]
+```
+
+Now boot from the `USB MSC Drive Generic Flash Disk 8.07` media by pressing
+`2`, the VyOS boot menu will appear, just wait 10 seconds or press `Enter`
+to continue.
+
+```none
+lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
+x VyOS - Boot Menu x
+tqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqu
+x Live system (amd64-vyos) x
+x Live system (amd64-vyos fail-safe mode) x
+x Live system (amd64-vyos) - Serial console x
+x x
+mqqqqqqPress ENAutomatic boot in 10 seconds...nu entryqqqqqqqj
+```
+
+The image will be loaded and the last lines you will get will be:
+
+```none
+Loading /live/vmlinuz... ok
+Loading /live/initrd.img...
+...
+Welcome to VyOS - vyos ttyS0
+
+vyos login:
+```
+
+You can now proceed with a regular image installation as described in
+{ref}`installation`.
+
+(vyos-on-baremetal-apu4-pictures)=
+
+### Pictures
+
+:::{note}
+Both device types operate without any moving parts and emit zero
+noise.
+:::
+
+#### Rack Mount
+
+:::{figure} /_static/images/apu4_rack_1.webp
+:alt: APU4 rack closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_2.webp
+:alt: APU4 rack front
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_3.webp
+:alt: 'APU4 rack module #1'
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_4.webp
+:alt: 'APU4 rack module #2'
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_5.webp
+:alt: 'APU4 rack module #3 with PSU'
+:scale: 25 %
+:::
+
+##### VyOS custom print
+
+:::{figure} /_static/images/apu4_rack_vyos_print.webp
+:alt: APU4 custom VyOS powder coat
+:scale: 25 %
+:::
+
+#### Desktop / Bench Top
+
+:::{figure} /_static/images/apu4_desk_1.webp
+:alt: APU4 desktop closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_2.webp
+:alt: APU4 desktop closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_3.webp
+:alt: APU4 desktop back
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_4.webp
+:alt: APU4 desktop back
+:scale: 25 %
+:::
+
+## Qotom Q355G4
+
+The install on this Q355G4 box is pretty much plug and play. The port numbering
+the OS does might differ from the labels on the outside, but the UEFI firmware
+has a port blink test built in with MAC addresses so you can very quickly
+identify which is which. MAC labels are on the inside as well, and this test
+can be done from VyOS or plain Linux too. Default settings in the UEFI will
+make it boot, but depending on your installation wishes (i.e. storage type,
+boot type, console type) you might want to adjust them. This Qotom company
+seems to be the real OEM/ODM for many other relabelling companies like
+Protectli.
+
+### Hardware
+
+There are a number of other options, but they all seem to be close to Intel
+reference designs, with added features like more serial ports, more network
+interfaces and the likes. Because they don't deviate too much from standard
+designs all the hardware is well-supported by mainline. It accepts one LPDDR3
+SO-DIMM, but chances are that if you need more than that, you'll also want
+something even beefier than an i5. There are options for antenna holes, and SIM
+slots, so you could in theory add an LTE/Cell modem (not tested so far).
+
+The chassis is a U-shaped alu extrusion with removable I/O plates and removable
+bottom plate. Cooling is completely passive with a heatsink on the SoC with
+internal and external fins, a flat interface surface, thermal pad on top of
+that, which then directly attaches to the chassis, which has fins as well. It
+comes with mounting hardware and rubber feet, so you could place it like a
+desktop model or mount it on a VESA mount, or even wall mount it with the
+provided mounting plate. The closing plate doubles as internal 2.5" mounting
+place for an HDD or SSD, and comes supplied with a small SATA cable and SATA
+power cable.
+
+Power supply is a 12VDC barrel jack, and included switching power supply, which
+is why SATA power regulation is on-board. Internally it has a NUC-board-style
+on-board 12V input header as well, the molex locking style.
+
+There are WDT options and auto-boot on power enable, which is great for remote
+setups. Firmware is reasonably secure (no backdoors found, BootGuard is enabled
+in enforcement mode, which is good but also means no coreboot option), yet has
+most options available to configure (so it's not locked out like most firmwares
+are).
+
+An external RS232 serial port is available, internally a GPIO header as well.
+It does have Realtek based audio on board for some reason, but you can disable
+that. Booting works on both USB2 and USB3 ports. Switching between serial BIOS
+mode and HDMI BIOS mode depends on what is connected at startup; it goes into
+serial mode if you disconnect HDMI and plug in serial, in all other cases it's
+HDMI mode.
+
+## Partaker i5
+
+:::{figure} ../_static/images/600px-Partaker-i5.webp
+:::
+
+I believe this is actually the same hardware as the Protectli. I purchased it
+in June 2018. It came pre-loaded with pfSense.
+
+[Manufacturer product page](http://www.inctel.com.cn/product/detail/338.html).
+
+### Installation
+
+- Write VyOS ISO to USB drive of some sort
+- Plug in VGA, power, USB keyboard, and USB drive
+- Press "SW" button on the front (this is the power button; I don't know what
+ "SW" is supposed to mean).
+- Begin rapidly pressing delete on the keyboard. The boot prompt is very quick,
+ but with a few tries you should be able to get into the BIOS.
+- Chipset > South Bridge > USB Configuration: set XHCI to Disabled and USB 2.0
+ (EHCI) to Enabled. Without doing this, the USB drive won't boot.
+- Boot to the VyOS installer and install as usual.
+
+Warning the interface labels on my device are backwards; the left-most "LAN4"
+port is eth0 and the right-most "LAN1" port is eth3.
+
+## Acrosser AND-J190N1
+
+:::{figure} ../_static/images/480px-Acrosser_ANDJ190N1_Front.webp
+:::
+
+:::{figure} ../_static/images/480px-Acrosser_ANDJ190N1_Back.webp
+:::
+
+This microbox network appliance was build to create OpenVPN bridges. It can
+saturate a 100Mbps link. It is a small (serial console only) PC with 6 Gb LAN
+
+You may have to add your own RAM and HDD/SSD. There is no VGA connector. But
+Acrosser provides a DB25 adapter for the VGA header on the motherboard (not
+used).
+
+### BIOS Settings:
+
+First thing you want to do is getting a more user friendly console to configure
+BIOS. Default VT100 brings a lot of issues. Configure VT100+ instead.
+
+For practical issues change speed from 115200 to 9600. 9600 is the default
+speed at which both linux kernel and VyOS will reconfigure the serial port
+when loading.
+
+Connect to serial (115200bps). Power on the appliance and press Del in the
+console when requested to enter BIOS settings.
+
+Advanced > Serial Port Console Redirection > Console Redirection Settings:
+
+- Terminal Type : VT100+
+- Bits per second : 9600
+
+Save, reboot and change serial speed to 9600 on your client.
+
+Some options have to be changed for VyOS to boot correctly. With XHCI enabled
+the installer can’t access the USB key. Enable EHCI instead.
+
+Reboot into BIOS, Chipset > South Bridge > USB Configuration:
+
+- Disable XHCI
+- Enable USB 2.0 (EHCI) Support
+
+Perform Image installation using `install image` CLI command.
+
+(gowin-gw-fn-1ur1-10g)=
+
+## Gowin GW-FN-1UR1-10G
+
+A platform utilizing an Intel Alder Lake-N100 CPU with 6M cache, TDP 6W.
+Onboard LPDDR5 16GB RAM and 128GB eMMC (can be used for image installation).
+
+The appliance comes with 2 * 2.5GbE Intel I226-V and 3 * 1GbE Intel I210
+where one supports IEEE802.3at PoE+ (Typical 30W).
+
+In addition there is a Mellanox ConnectX-3 2\* 10GbE SFP+ NIC available.
+
+**NOTE:** This is the entry level platform. Other derivates exists with
+i3-N305 CPU and 2x 25GbE!
+
+### Gowin Shopping Cart
+
+- 1x Gowin GW-FN-1UR1-10G
+- 2x 128GB M.2 NVMe SSDs
+
+### Optional (WiFi + WWAN)
+
+- 1x MediaTek 7921E M.2 NGFF WIFI module (not tested as this currently leads to
+ a Kernel crash)
+- 1x HP LT4120 Snapdragon X5 LTE WWAN module
+
+### Pictures
+
+:::{figure} ../_static/images/gowin-01.webp
+:::
+
+:::{figure} ../_static/images/gowin-02.webp
+:::
+
+:::{figure} ../_static/images/gowin-03.webp
+:::
+
+:::{figure} ../_static/images/gowin-04.webp
+:::
+
+### Cooling
+
+The device itself is passivly cooled, whereas the power supply has an active fan.
+Even if the main processor is powered off, the power supply fan is operating and
+the entire chassis draws 7.5W. During operation the chassis drew arround 38W.
+
+### BIOS Settings
+
+No settings needed to be altered, everything worked out of the box!
+
+### Installation
+
+The system provides a regular RS232 console port using 115200,8n1 setting which
+is sufficient to install VyOS from a USB pendrive.
+
+### First Boot
+
+Please note that there is a weirdness on the network interface mapping.
+The interface \<-> MAC mapping is going upwards but the NICs are placed
+somehow swapped on the mainboard/MACs programmed in a swapped order.
+
+See interface description for more detailed mapping.
+
+```none
+vyos@vyos:~$ show interfaces
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address MAC VRF MTU S/L Description
+----------- -------------- ----------------- ------- ----- ----- -------------
+eth0 - 00:f0:cb:00:00:99 default 1500 u/D Intel I226-V - Front eth2
+eth1 - 00:f0:cb:00:00:9a default 1500 u/D Intel I226-V - Front eth1
+eth2 - 00:f0:cb:00:00:9b default 1500 u/D Intel I210 - Front eth4
+eth3 - 00:f0:cb:00:00:9c default 1500 u/D Intel I210 - Front eth3
+eth4 - 00:f0:cb:00:00:9d default 1500 u/D Intel I210 - Front POE
+eth5 - 00:02:c9:00:00:30 default 1500 u/D Mellanox ConnectX-3 - SFP2
+eth6 - 00:02:c9:00:00:31 default 1500 u/D Mellanox ConnectX-3 - SFP1
+lo 127.0.0.1/8 00:00:00:00:00:00 default 65536 u/u
+ ::1/128
+wwan0 - d2:39:76:8e:05:12 default 1500 A/D
+```
+
+
+#### VyOS 1.4 (sagitta)
+
+Connect serial port to a PC through a USB \<-> RJ45 console cable. Set terminal
+emulator to 115200 8N1. You can also perform the installation using VGA or HDMI
+ports.
+
+In this example I choose to install VyOS as RAID-1 on both NVMe drives. However,
+a previous installation on the 128GB eMMC storage worked without any issues,
+too.
+
+```none
+Welcome to VyOS - vyos ttyS0
+vyos login:
+```
+
+Perform Image installation using `install image` CLI command. This installation
+uses two 128GB NVMe disks setup as RAID1.
+
+```none
+Welcome to VyOS!
+
+ ┌── ┐
+ . VyOS 1.4.0
+ └ ──┘ sagitta
+
+* Support portal: https://support.vyos.io
+* Documentation: https://docs.vyos.io/en/sagitta
+* Project news: https://blog.vyos.io
+* Bug reports: https://vyos.dev
+
+You can change this banner using "set system login banner post-login" command.
+
+VyOS is a free software distribution that includes multiple components,
+you can check individual component licenses under /usr/share/doc/*/copyright
+Use of this pre-built image is governed by the EULA you can find in
+/usr/share/vyos/EULA
+
+vyos@vyos:~$ install image
+
+Welcome to VyOS installation!
+This command will install VyOS to your permanent storage.
+Would you like to continue? [y/N] y
+
+What would you like to name this image? (Default: 1.4.0)
+
+Please enter a password for the "vyos" user:
+Please confirm password for the "vyos" user:
+
+What console should be used by default? (K: KVM, S: Serial)? (Default: S)
+
+Probing disks
+4 disk(s) found
+Would you like to configure RAID-1 mirroring? [Y/n] y
+
+The following disks were found:
+ /dev/sda (14.4 GB)
+ /dev/mmcblk0 (116.5 GB)
+Would you like to configure RAID-1 mirroring on them? [Y/n] n
+
+Would you like to choose two disks for RAID-1 mirroring? [Y/n] y
+Disks available:
+ 1: /dev/sda (14.4 GB)
+ 2: /dev/mmcblk0 (116.5 GB)
+ 3: /dev/nvme1n1 (119.2 GB)
+ 4: /dev/nvme0n1 (119.2 GB)
+Select first disk: 3
+
+Remaining disks:
+ 1: /dev/sda (14.4 GB)
+ 2: /dev/mmcblk0 (116.5 GB)
+ 3: /dev/nvme0n1 (119.2 GB)
+Select second disk: 3
+
+Installation will delete all data on both drives. Continue? [y/N] y
+
+Searching for data from previous installations
+No previous installation found
+Creating partitions on /dev/nvme1n1
+Creating partition table...
+Creating partitions on /dev/nvme0n1
+Creating partition table...
+Creating RAID array
+Updating initramfs
+Creating filesystem on RAID array
+The following config files are available for boot:
+ 1: /opt/vyatta/etc/config/config.boot
+ 2: /opt/vyatta/etc/config.boot.default
+
+Which file would you like as boot config? (Default: 1)
+Creating temporary directories
+Mounting new partitions
+Creating a configuration file
+Copying system image files
+Installing GRUB configuration files
+Installing GRUB to the drives
+Cleaning up
+Unmounting target filesystems
+Removing temporary files
+The image installed successfully; please reboot now.
+```
+
+
+### Hardware
+
+```none
+vyos@vyos:~$ lspci
+00:00.0 Host bridge: Intel Corporation Device 461c
+00:02.0 VGA compatible controller: Intel Corporation Alder Lake-N [UHD Graphics]
+00:0a.0 Signal processing controller: Intel Corporation Platform Monitoring Technology (rev 01)
+00:0d.0 USB controller: Intel Corporation Device 464e
+00:14.0 USB controller: Intel Corporation Device 54ed
+00:14.2 RAM memory: Intel Corporation Device 54ef
+00:15.0 Serial bus controller: Intel Corporation Device 54e8
+00:16.0 Communication controller: Intel Corporation Device 54e0
+00:1a.0 SD Host controller: Intel Corporation Device 54c4
+00:1c.0 PCI bridge: Intel Corporation Device 54b8
+00:1c.2 PCI bridge: Intel Corporation Device 54ba
+00:1c.3 PCI bridge: Intel Corporation Device 54bb
+00:1c.6 PCI bridge: Intel Corporation Device 54be
+00:1d.0 PCI bridge: Intel Corporation Device 54b0
+00:1f.0 ISA bridge: Intel Corporation Device 5481
+00:1f.4 SMBus: Intel Corporation Device 54a3
+00:1f.5 Serial bus controller: Intel Corporation Device 54a4
+01:00.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+02:00.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+02:02.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+02:06.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+02:0e.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+03:00.0 Ethernet controller: Intel Corporation Ethernet Controller I226-V (rev 04)
+04:00.0 Ethernet controller: Intel Corporation Ethernet Controller I226-V (rev 04)
+05:00.0 Network controller: MEDIATEK Corp. MT7922 802.11ax PCI Express Wireless Network Adapter
+06:00.0 SATA controller: ASMedia Technology Inc. Device 0622 (rev 01)
+07:00.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+08:00.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+08:02.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+08:06.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+08:0e.0 PCI bridge: ASMedia Technology Inc. Device 1806 (rev 01)
+09:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
+0a:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
+0b:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
+0d:00.0 Non-Volatile memory controller: Device 1ed0:2283
+0f:00.0 Non-Volatile memory controller: Device 1ed0:2283
+11:00.0 Ethernet controller: Mellanox Technologies MT27500 Family [ConnectX-3]
+```
+
+```none
+vyos@vyos:~$ lsusb
+Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+Bus 003 Device 005: ID 0e8d:c616 MediaTek Inc. Wireless_Device
+Bus 003 Device 003: ID 413c:2113 Dell Computer Corp. KB216 Wired Keyboard
+Bus 003 Device 004: ID 03f0:9d1d HP, Inc HP lt4120 Snapdragon X5 LTE
+Bus 003 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
+Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 002 Device 002: ID 05e3:0620 Genesys Logic, Inc. GL3523 Hub
+Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+```
+
+
+#### WWAN
+
+The LTE module can be enabled as simple as this config snippet:
+
+```none
+interfaces {
+ wwan wwan0 {
+ address "dhcp"
+ apn "YOUR-APN-GOES-HERE"
+ }
+}
+```
+
+For more information please refer to chapter: {ref}`wwan-interface`
+
+[rufus]: https://rufus.ie/
diff --git a/docs/installation/cloud/aws.md b/docs/installation/cloud/aws.md
new file mode 100644
index 00000000..de5da3aa
--- /dev/null
+++ b/docs/installation/cloud/aws.md
@@ -0,0 +1,188 @@
+---
+lastproofread: '2026-02-06'
+---
+
+# Amazon AWS
+
+## Deploy VM
+
+Deploy VyOS on Amazon {abbr}`AWS (Amazon Web Services)`.
+
+1. Click **Instances** and then click **Launch Instance**.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-01.webp
+```
+
+2. Search for "VyOS" in the Marketplace.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-02.webp
+```
+
+3. Choose the instance type. The recommended minimum is `m3.medium`.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-03.webp
+```
+
+4. Configure the instance for your requirements. Select the number of
+ instances, network, and subnet.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-04.webp
+```
+
+5. Configure additional storage. You can remove the additional storage
+ `/dev/sdb`. The root device will be `/dev/xvda`. You can skip this step.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-05.webp
+```
+
+6. Configure the security group. We recommend configuring SSH access
+ only from specific sources, or you can permit any IP address (the default).
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-06.webp
+```
+
+7. Select the SSH key pair and click **Launch Instances**.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-07.webp
+```
+
+8. Note your public IP address.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-aws-08.webp
+```
+
+9. Connect to the instance using your SSH key.
+
+```{eval-rst}
+
+ .. code-block:: none
+
+ ssh -i ~/.ssh/amazon.pem vyos@203.0.113.3
+ vyos@ip-192-0-2-10:~$
+```
+
+
+## Amazon CloudWatch Agent Usage
+
+To use the Amazon CloudWatch agent, configure it in the Amazon Systems Manager
+Parameter Store. For instructions on creating a configuration, see
+{ref}`configuration_creation`.
+
+1. Create an {abbr}`IAM (Identity and Access Management)` role for the
+ {abbr}`EC2 (Elastic Compute Cloud)` instance to access CloudWatch service,
+ and name it CloudWatchAgentServerRole. The role should contain two default
+ policies: `CloudWatchAgentServerPolicy` and
+ `AmazonSSMManagedInstanceCore`.
+2. Attach the created role to your VyOS {abbr}`EC2 (Elastic Compute Cloud)`
+ instance.
+3. Ensure the amazon-cloudwatch-agent package is installed.
+
+```{eval-rst}
+
+ .. code-block:: none
+
+ $ sudo apt list --installed | grep amazon-cloudwatch-agent
+
+ .. note:: The amazon-cloudwatch-agent package is normally included in
+ VyOS 1.3.3+ and 1.4+
+```
+
+4. Retrieve an existing CloudWatch Agent configuration from the
+ {abbr}`SSM (Systems Manager)` Parameter Store.
+
+```{eval-rst}
+
+ .. code-block:: none
+
+ $ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:<your-configuration-name>
+
+ This step also enables systemd service and runs it.
+
+ .. note:: The VyOS platform-specific scripts feature is under development.
+ Thus, this step should be repeated manually after changing system image
+ (:doc:`/installation/update`)
+```
+
+(configuration_creation)=
+
+### CloudWatch SSM Configuration creation
+
+Creating the Amazon Cloudwatch Agent Configuration in Amazon
+{abbr}`SSM (Systems Manager)` Parameter Store.
+
+1. Create an {abbr}`IAM (Identity and Access Management)` role for your
+ {abbr}`EC2 (Elastic Compute Cloud)` instance to access the CloudWatch
+ service. Name it `CloudWatchAgentAdminRole`. The role must contain at
+ least two policies: `CloudWatchAgentAdminPolicy` and
+ `AmazonSSMManagedInstanceCore`.
+
+```{eval-rst}
+
+ .. note:: CloudWatchAgentServerRole is too permissive and should be used only
+ for
+ creating and deploying a single configuration. After step 3, we recommend
+ replacing the ``CloudWatchAgentAdminRole`` with the
+ ``CloudWatchAgentServerRole``.
+```
+
+2. Run the CloudWatch configuration wizard.
+
+```{eval-rst}
+
+ .. code-block:: none
+
+ $ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+```
+
+3. When prompted, enter "yes" to the question "Do you want to store the
+ config in the SSM parameter store?".
+
+## AWS Gateway Load Balancer
+
+VyOS supports the AWS Gateway Load Balancer (GWLB) tunnel handler (`gwlbtun`),
+which enables VyOS to act as an inspection or processing target for GWLB. GWLB
+uses Geneve encapsulation with custom metadata to deliver traffic to VyOS for
+packet filtering, shaping, deep packet inspection, NAT, or other traffic
+manipulation functions. The tunnel handler automatically creates Linux tunnel
+interfaces (`gwi-*` for ingress and `gwo-*` for egress) per endpoint,
+allowing you to use standard Linux utilities like iptables, tc, and netfilter
+to implement your inspection or processing logic. This enables VyOS to serve as
+a centralized appliance for traffic inspection in your AWS infrastructure,
+supporting both single-endpoint (1-arm) and multi-endpoint (2-arm) deployment
+modes.
+
+For more information about integrating with AWS Gateway Load Balancer, see
+the following article from AWS:
+[How to integrate Linux instances with AWS Gateway Load Balancer](https://aws.amazon.com/blogs/networking-and-content-delivery/how-to-integrate-linux-instances-with-aws-gateway-load-balancer/).
+
+### Configuration Example
+
+Configure the AWS GWLB service with the following commands:
+
+```none
+set service aws glb script on-create '/config/scripts/glb-create.sh'
+set service aws glb script on-destroy '/config/scripts/glb-destroy.sh'
+set service aws glb status format 'simple'
+set service aws glb status port '8282'
+set service aws glb threads tunnel '4'
+set service aws glb threads tunnel-affinity '1-2'
+set service aws glb threads udp '4'
+set service aws glb threads udp-affinity '0-3'
+```
+
+
+## References
+
+- <https://console.aws.amazon.com/>
+- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html>
+- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-EC2-Instance-fleet.html>
+- <https://aws.amazon.com/blogs/networking-and-content-delivery/how-to-integrate-linux-instances-with-aws-gateway-load-balancer/>
+
diff --git a/docs/installation/cloud/azure.md b/docs/installation/cloud/azure.md
new file mode 100644
index 00000000..24b7b166
--- /dev/null
+++ b/docs/installation/cloud/azure.md
@@ -0,0 +1,98 @@
+---
+lastproofread: '2026-02-09'
+---
+
+# Azure
+
+## Deploy VM
+
+Deploy VyOS on Azure.
+
+1. Go to Azure services and click **Add new Virtual machine**.
+2. Choose a VM name, resource group, and region, then click **Browse all public
+ and private images**.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-01.webp
+```
+
+3. Search for "VyOS" in the marketplace and choose the appropriate
+ subscription.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-02.webp
+```
+
+4. Generate new SSH key pair or use existing.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-03.webp
+```
+
+5. Configure the network, subnet, and public IP. Or use the defaults.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-04.webp
+```
+
+6. Click **Review + create**. Your deployment completes in a few seconds.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-05.webp
+```
+
+7. Select your new VM and note your public IP address.
+
+```{eval-rst}
+.. figure:: /_static/images/cloud-azure-06.webp
+```
+
+8. Connect to the instance with your SSH key.
+
+```{eval-rst}
+
+ .. code-block:: none
+
+ ssh -i ~/.ssh/vyos_azure vyos@203.0.113.3
+ vyos@vyos-doc-r1:~$
+```
+
+
+## Add interface
+
+If your instance was deployed with one **eth0** (`WAN`) interface and you
+want to add another, you must shut down the instance. To add a new interface,
+such as **eth1** (`LAN`), attach it in the Azure portal and then restart the
+instance.
+
+:::{note}
+Azure doesn't allow you to attach an interface while the instance is
+running.
+:::
+
+## Absorbing Routes
+
+If you're using the VM as a router, you can use a route table to absorb some or
+all traffic from your virtual network (VNET) with your LAN interface.
+
+1. Create a route table and navigate to **Configuration**.
+2. Add one or more routes for the networks you want to route through the VyOS
+ VM. For **Next hop type**, select **Virtual Appliance** and set the **Next
+ Hop Address** to the VyOS `LAN` interface.
+
+:::{note}
+To create a default route for VMs on the subnet, use
+**Address Prefix** `0.0.0.0/0`. For a typical edge device configuration,
+configure masquerade NAT on the `WAN` interface.
+:::
+
+## Serial Console
+
+VyOS includes serial console support by default. However, if you replace the
+`config.boot` file and reboot, ensure this configuration is present:
+
+`set system console device ttyS0 speed '9600'`
+
+## References
+
+<https://azure.microsoft.com>
diff --git a/docs/installation/cloud/gcp.md b/docs/installation/cloud/gcp.md
new file mode 100644
index 00000000..828312cd
--- /dev/null
+++ b/docs/installation/cloud/gcp.md
@@ -0,0 +1,61 @@
+---
+lastproofread: '2026-02-09'
+---
+
+# Google Cloud Platform
+
+## Deploy VM
+
+To deploy VyOS on Google Cloud Platform (GCP):
+
+1. Generate an SSH key pair of type **ssh-rsa** on the host that will connect
+ to VyOS.
+
+ Example:
+
+ ```none
+ ssh-keygen -t rsa -f ~/.ssh/vyos_gcp -C "vyos@mypc"
+ ```
+
+:::{note}
+The SSH key comment must begin with `vyos@` because that's the
+default VyOS user. GCP uses this value to set the username on the instance.
+:::
+
+2. Open the GCP Console and navigate to **Metadata**. Select **SSH Keys** and
+ click **Edit**.
+
+:::{figure} /_static/images/cloud-gcp-01.webp
+Click **Add item**, paste your public SSH key, and click **Save**.
+:::
+
+:::{figure} /_static/images/cloud-gcp-02.webp
+:::
+
+3. Search for "VyOS" in the Marketplace.
+4. Configure the deployment name, zone, and machine type, then click **Deploy**.
+
+:::{figure} /_static/images/cloud-gcp-03.webp
+:::
+
+5. After a few seconds, select your **instance**.
+
+:::{figure} /_static/images/cloud-gcp-04.webp
+:::
+
+6. Note your external IP address.
+
+:::{figure} /_static/images/cloud-gcp-05.webp
+:::
+
+7. Connect to the instance using the SSH key you generated in step 1.
+
+```none
+ssh -i ~/.ssh/vyos_gcp vyos@203.0.113.3
+vyos@vyos-r1-vm:~$
+```
+
+
+## References
+
+<https://console.cloud.google.com/>
diff --git a/docs/installation/cloud/index.md b/docs/installation/cloud/index.md
new file mode 100644
index 00000000..cf7d447d
--- /dev/null
+++ b/docs/installation/cloud/index.md
@@ -0,0 +1,10 @@
+# Cloud Environments
+
+```{toctree}
+:caption: Content
+
+aws
+azure
+gcp
+oracle
+```
diff --git a/docs/installation/cloud/oracle.md b/docs/installation/cloud/oracle.md
new file mode 100644
index 00000000..f8cee52c
--- /dev/null
+++ b/docs/installation/cloud/oracle.md
@@ -0,0 +1,17 @@
+---
+lastproofread: '2026-02-09'
+---
+
+# Oracle
+
+:::{note}
+This page is a stub and needs expansion. Contributions
+welcome via the [VyOS documentation repository](https://github.com/vyos/vyos-documentation).
+:::
+
+## References
+
+<https://www.oracle.com/cloud/>
+
+<https://docs.oracle.com/en/cloud/paas/developer-cloud-classic/csdcc/deploy-application.html>
+
diff --git a/docs/installation/image.md b/docs/installation/image.md
new file mode 100644
index 00000000..a0fc89d4
--- /dev/null
+++ b/docs/installation/image.md
@@ -0,0 +1,113 @@
+---
+lastproofread: '2026-01-26'
+---
+
+(image-mgmt)=
+
+# Image Management
+
+VyOS uses an image-based installation that creates a directory for each image
+on the storage device you select during installation.
+
+The boot device has the following directory structure:
+
+```none
+/
+/boot
+/boot/grub
+/boot/2025.07.16-0020-rolling.squashfs
+```
+
+The image directory contains the system kernel, a compressed root filesystem
+image, and a directory for persistent storage (such as configuration). During
+boot, the system extracts the OS image into memory and mounts the appropriate
+live-rw subdirectories to provide persistent storage for system configuration.
+
+This process ensures that the system always boots to a known working state,
+since the OS image is fixed and non-persistent. You can also install multiple
+VyOS releases on the same storage device. You can manually select the image at
+boot if needed, but the system boots the default image by default.
+
+```{opcmd} show system image
+
+List all available system images which can be booted on the current system.
+
+:::{code-block} none
+vyos@vyos:~$ show system image
+Name Default boot Running
+----------------------- -------------- ---------
+2025.07.16-0020-rolling Yes Yes
+1.4.1
+1.4.0
+:::
+```
+```{opcmd} delete system image [image-name]
+
+ Delete unused images from the system. You can specify an optional image name
+ to delete. Use the {opcmd}`show system image` command to list available
+ images.
+
+ :::{code-block} none
+ vyos@vyos:~$ delete system image
+ The following images are installed:
+ 1: 2025.07.16-0020-rolling (running) (default boot)
+ 2: 1.4.1
+ 3: 1.4.0
+ Select an image to delete: 3
+ Do you really want to delete the image 1.4.0? [y/N] y
+ The image "1.4.0" was successfully deleted
+ :::
+```
+
+
+```{opcmd} show version
+
+Show current system image version.
+
+:::{code-block} none
+vyos@vyos:~$ show version
+Version: VyOS 2025.07.16-0020-rolling
+Release train: current
+Release flavor: generic
+
+Built by: autobuild@vyos.net
+Built on: Wed 16 Jul 2025 00:21 UTC
+Build UUID: 20d432ee-6d55-4ebc-8462-46fe836246c9
+Build Commit ID: f7ce0d8a692f2d
+
+Architecture: x86_64
+Boot via: installed image
+System type: KVM guest
+Secure Boot: n/a (BIOS)
+
+Hardware vendor: QEMU
+Hardware model: Standard PC (i440FX + PIIX, 1996)
+Hardware S/N:
+Hardware UUID: b9831d42-c1fe-b2bd-7d3d-49db9418f5c9
+
+Copyright: VyOS maintainers and contributors
+:::
+```
+
+## System rollback
+
+To roll back to a previous image, first view the available images by using the
+{opcmd}`show system image` command, then select your image with the following
+command:
+
+```{opcmd} set system image default-boot [image-name]
+
+Select the default boot image which will be started on the next boot
+of the system.
+```
+
+Then reboot the system.
+
+:::{note}
+VyOS automatically associates the configuration with each image,
+so you don't need to manage this separately. Each image has its own unique
+configuration copy.
+:::
+
+If you have console access, you can also select the boot image by restarting
+the system and using the GRUB menu at startup.
diff --git a/docs/installation/index.md b/docs/installation/index.md
new file mode 100644
index 00000000..4256aa9b
--- /dev/null
+++ b/docs/installation/index.md
@@ -0,0 +1,30 @@
+---
+lastproofread: '2026-01-26'
+---
+
+# Installation and Image Management
+
+:::{note}
+This information applies primarily to virtual installations:
+
+When installing VyOS, ensure that the MAC address you select for your NICs
+is not a locally administered MAC address. Locally administered addresses are
+distinguished from universally administered addresses by setting the
+second-least-significant bit of the first octet to 1:
+
+Example: `02:00:00:00:00:01`, where the second-least-significant bit
+(`02` in hexadecimal) is set to `1`.
+:::
+
+```{toctree}
+:caption: Content
+:maxdepth: 2
+
+install
+virtual/index
+cloud/index
+bare-metal
+update
+image
+secure-boot
+```
diff --git a/docs/installation/install.md b/docs/installation/install.md
new file mode 100644
index 00000000..532bdc0c
--- /dev/null
+++ b/docs/installation/install.md
@@ -0,0 +1,466 @@
+---
+lastproofread: '2026-01-26'
+---
+
+(installation)=
+
+# Installation
+
+VyOS installation requires a VyOS .iso file. This file is a live installation
+image that you can use to boot a live VyOS system. From there, you can proceed
+with a permanent installation on a hard drive or other storage device.
+
+:::{list-table} Comparison of VyOS image releases
+:header-rows: 1
+:widths: 15 35 15 25 15 15
+
+* - Release Type
+ - Description
+ - Release Cycle
+ - Intended Use
+ - Access to Images
+ - Access to Source
+
+* - Nightly (Current)
+ - Automatically built from the current branch. Always up to date
+ with cutting edge development but guaranteed to contain bugs.
+ - Every night
+ - Developing VyOS, testing new features, experimenting.
+ - Everyone
+ - Everyone
+
+* - Stream
+ - VyOS Stream serves as a technology preview and a quality gate
+ for the upcoming LTS release. Allows everyone to try new features
+ and check if they work well or need improvements.
+ - Every quarter
+ - Non-critical production environments, preparing for the LTS
+ release.
+ - Everyone
+ - Everyone
+
+* - Release Candidate
+ - Rather stable. All development focuses on testing and hunting
+ down remaining bugs following the feature freeze.
+ - Irregularly until EPA comes out
+ - Labs, small offices and non-critical production systems backed
+ by a high-availability setup.
+ - Everyone
+ - Everyone
+
+* - Early Production Access
+ - Highly stable with no known bugs. Needs to be tested repeatedly
+ under different conditions before it can become the final
+ release.
+ - Irregularly until LTS comes out
+ - Non-critical production environments, preparing for the LTS
+ release.
+ - Everyone
+ - Everyone
+
+* - Long-Term Support
+ - Guaranteed to be stable and carefully maintained for several
+ years after the release. No features are introduced but security
+ updates are released in a timely manner.
+ - Every major version
+ - Large-scale enterprise networks, internet service providers,
+ critical production environments that call for minimum downtime.
+ - Subscribers, contributors, non-profits, emergency services,
+ academic institutions
+ - Subscribers, contributors, non-profits, emergency services,
+ academic institutions
+:::
+
+## Hardware requirements
+
+The minimum system requirements for VyOS are 4 GB RAM and 10 GB storage.
+Depending on your use case, you might need additional RAM and CPU resources.
+
+## Download
+
+### Registered Subscribers
+
+Registered subscribers can log into <https://support.vyos.io/> to access
+a variety of different downloads via the "Downloads" link. These
+downloads include LTS (Long-Term Support), the associated hot-fix releases,
+early public access releases, pre-built VM images, as well as device
+specific installation ISOs. See this [article] for more information on
+downloads.
+
+:::{note}
+The `.qcow2` image provided for Proxmox deployment can also be
+used to deploy VyOS on KVM environments. This image includes cloud-init
+support. See {ref}`cloud-init` for more information.
+:::
+
+:::{figure} /_static/images/vyosnew-downloads.webp
+:::
+
+### Building from source
+
+Subscribers can download the source code for the LTS release from the
+"Downloads" link. Non-subscribers can access the source code for the
+Rolling release. For instructions, see the {ref}`build` section. The
+VyOS source code repository is available at
+<https://github.com/vyos/vyos-build>.
+
+### Rolling Release
+
+Everyone can download bleeding-edge VyOS rolling images from:
+<https://downloads.vyos.io/>
+
+:::{note}
+Rolling releases contain the latest enhancements and fixes.
+This means there may be new bugs. If you encounter a bug, follow the
+guide at {ref}`bug_report`. We depend on your feedback to improve VyOS.
+:::
+
+The following link contains the most recent VyOS builds for AMD64
+systems from the `current` branch: <https://vyos.net/get/nightly-builds/>
+
+### Download Verification
+
+LTS images are signed with the VyOS lead package maintainer's private key.
+You can verify the authenticity of the package using the official public key
+and Minisign.
+
+(minisign-verification)=
+
+#### Minisign verification
+
+VyOS uses [Minisign](https://github.com/jedisct1/minisign) for release
+signing. Minisign is a tool for signing files and verifying signatures.
+
+OpenBSD introduced signify in 2015. Minisign is an alternative
+implementation of the same protocol, available for Windows, macOS, and
+most GNU/Linux distributions. Minisign is portable, lightweight, and
+uses the Ed25519 public-key signature system.
+
+{vytask}`T2108` switched the validation system to prefer Minisign over GPG keys.
+
+To verify a VyOS image starting with VyOS `1.3.0-rc6`, run:
+
+```none
+$ minisign -V -P RWSIhkR/dkM2DSaBRniv/bbbAf8hmDqdbOEmgXkf1RxRoxzodgKcDyGq -m vyos-1.5-rolling-202409250007-generic-amd64.iso vyos-1.5-rolling-202409250007-generic-amd64.iso.minisig
+
+Signature and comment signature verified
+Trusted comment: timestamp:1727223408 file:vyos-1.5-rolling-202409250007-generic-amd64.iso hashed
+```
+
+During an image upgrade, VyOS runs the following command:
+
+```none
+$ minisign -V -p /usr/share/vyos/keys/vyos-release.minisign.pub -m vyos-1.3.0-rc6-amd64.iso vyos-1.3.0-rc6-amd64.iso.minisig
+Signature and comment signature verified
+Trusted comment: timestamp:1629997936 file:vyos-1.3.0-rc6-amd64.iso
+```
+
+:::{note}
+Starting with version `1.4.3`, VyOS uses Minisign exclusively.
+If you see an unexpected verification error, update your system to version
+`1.4.2` first. Support for GnuPG signatures has been
+removed ({vytask}`T7301`).
+:::
+
+(live_installation)=
+
+## Live installation
+
+:::{note}
+To permanently install VyOS, you must first complete a live
+installation.
+:::
+
+You can test VyOS without installing it on your hard drive. **Using your
+downloaded VyOS .iso file, you can create a bootable USB drive to boot
+into a fully functional VyOS system**. After testing it, you can start a
+{ref}`permanent_installation` on your hard drive or power off your system
+and remove the USB drive.
+
+```{eval-rst}
+If you have a GNU/Linux system, you can create a bootable VyOS USB drive using
+the ``dd`` command:
+
+ 1. Open your terminal emulator.
+
+ 2. Find the device name of your USB drive (use the ``lsblk`` command).
+
+ 3. Unmount the USB drive. Replace ``X`` with your device letter and keep the
+ asterisk (*) to unmount all partitions.
+
+ .. code-block:: none
+
+ $ umount /dev/sdX*
+
+ 1. Write the image (your VyOS .iso file) to the USB drive. Use the device
+ name (for example, ``/dev/sdb``), not the partition name
+ (for example, ``/dev/sdb1``).
+
+ **Warning**: This will destroy all data on the USB drive!
+
+ .. code-block:: none
+
+ # dd if=/path/to/vyos.iso of=/dev/sdX bs=8M; sync
+
+ 1. Wait for the operation to complete (bytes copied). On some systems, this
+ may take more than one minute.
+
+ 2. Once ``dd`` has finished, pull the USB drive out and plug it into
+ the powered-off computer where you want to install (or test) VyOS.
+
+ 3. Power on the computer and ensure it boots from the USB drive
+ (you may need to select the boot device or change boot settings).
+
+ 4. When VyOS finishes loading, sign in using the default credentials
+ (login: ``vyos``, password: ``vyos``).
+```
+
+If you encounter issues with this method, prefer a different operating
+system, or want a GUI program, you can use other tools to create a
+bootable USB drive, such as [balenaEtcher] (GNU/Linux, macOS, and Windows),
+[Rufus] (Windows), and [many others]. Follow their instructions to create
+a bootable USB drive from an `.iso` file.
+
+:::{hint}
+The default username and password for the live system is *vyos*.
+:::
+
+(permanent_installation)=
+
+## Permanent installation
+
+:::{note}
+Before a permanent installation, VyOS requires a
+{ref}`live_installation`.
+:::
+
+Unlike general-purpose Linux distributions, VyOS uses "image installation",
+which mimics the user experience of traditional hardware routers and allows
+you to keep multiple VyOS versions installed simultaneously. This lets you
+switch to a previous version if something breaks or misbehaves after an
+image upgrade.
+
+Each version is contained in its own squashfs image mounted in a union
+filesystem along with a directory for mutable data such as configurations,
+keys, and custom scripts.
+
+```{eval-rst}
+In order to proceed with a permanent installation:
+
+ 1. Sign in to the VyOS live system using the default credentials
+ (login: ``vyos``, password: ``vyos``).
+
+ 2. Run the ``install image`` command and follow the wizard:
+
+ .. code-block:: none
+
+ vyos@vyos:~$ install image
+ Welcome to VyOS installation!
+ This command will install VyOS to your permanent storage.
+ Would you like to continue? [y/N] y
+ What would you like to name this image? (Default: 2025.09.17-0018-rolling)
+ Please enter a password for the "vyos" user:
+ Please confirm password for the "vyos" user:
+ What console should be used by default? (K: KVM, S: Serial)? (Default: S)
+ Probing disks
+ 1 disk(s) found
+ The following disks were found:
+ Drive: /dev/vda (10.0 GB)
+ Which one should be used for installation? (Default: /dev/vda)
+ Installation will delete all data on the drive. Continue? [y/N] y
+ Searching for data from previous installations
+ No previous installation found
+ Would you like to use all the free space on the drive? [Y/n] Y
+ Creating partition table...
+ The following config files are available for boot:
+ 1: /opt/vyatta/etc/config/config.boot
+ 2: /opt/vyatta/etc/config.boot.default
+ Which file would you like as boot config? (Default: 1)
+ Creating temporary directories
+ Mounting new partitions
+ Creating a configuration file
+ Copying system image files
+ Installing GRUB configuration files
+ Installing GRUB to the drive
+ Cleaning up
+ Unmounting target filesystems
+ Removing temporary files
+ The image installed successfully; please reboot now.
+
+
+ 3. After installation completes, remove the live USB drive or CD.
+
+ 4. Reboot the system.
+
+ .. code-block:: none
+
+ vyos@vyos:~$ reboot
+ Proceed with reboot? (Yes/No) [No] Yes
+
+ You will boot now into a permanent VyOS system.
+```
+
+## PXE Boot
+
+You can also install VyOS using PXE, a more complex installation method that
+allows you to deploy VyOS over the network.
+
+**Requirements**
+
+- A machine (client) with a PXE-enabled NIC.
+- {ref}`dhcp-server`
+- {ref}`tftp-server`
+- Webserver (HTTP). Optional, but speeds up installation.
+- VyOS ISO image (do not use images prior to VyOS `1.2.3`).
+- Files *pxelinux.0* and *ldlinux.c32* from the
+ [Syslinux distribution](https://kernel.org/pub/linux/utils/boot/syslinux/).
+
+### Configuration
+
+#### Step 1: DHCP
+
+Configure a DHCP server to provide the client with:
+
+- An IP address
+- The TFTP server address (DHCP option 66), sometimes referred to as the
+ *boot server*
+- The *bootfile name* (DHCP option 67): *pxelinux.0*
+
+In this example we configured an existent VyOS as the DHCP server:
+
+```none
+vyos@vyos# show service dhcp-server
+ shared-network-name mydhcp {
+ subnet 192.168.1.0/24 {
+ option {
+ bootfile-name pxelinux.0
+ bootfile-server 192.168.1.50
+ default-router 192.168.1.50
+ }
+ range 0 {
+ start 192.168.1.70
+ stop 192.168.1.100
+ }
+ subnet-id 1
+ }
+ }
+```
+
+(install_from_tftp)=
+
+#### Step 2: TFTP
+
+Configure a TFTP server to serve the following:
+
+- The *pxelinux.0* file from the Syslinux distribution
+- The *ldlinux.c32* file from the Syslinux distribution
+- The VyOS kernel you want to deploy (*vmlinuz* file from the
+ */live* directory in the extracted ISO file)
+- The VyOS initial ramdisk (*initrd.img* file from the */live* directory
+ in the extracted ISO file). Do not use an empty (0 bytes) initrd.img
+ file; the correct file may have a longer name.
+- A directory named *pxelinux.cfg* containing the configuration file.
+ By default, the VyOS configuration file is named [default].
+
+In the example you configured your existent VyOS as the TFTP server too:
+
+```none
+vyos@vyos# show service tftp-server
+ directory /config/tftpboot
+ listen-address 192.168.1.50
+```
+
+Example of the contents of the TFTP server:
+
+```none
+vyos@vyos# ls -hal /config/tftpboot/
+total 29M
+drwxr-sr-x 3 tftp tftp 4.0K Oct 14 00:23 .
+drwxrwsr-x 9 root vyattacfg 4.0K Oct 18 00:05 ..
+-r--r--r-- 1 root vyattacfg 25M Oct 13 23:24 initrd.img-4.19.54-amd64-vyos
+-rwxr-xr-x 1 root vyattacfg 120K Oct 13 23:44 ldlinux.c32
+-rw-r--r-- 1 root vyattacfg 46K Oct 13 23:24 pxelinux.0
+drwxr-xr-x 2 root vyattacfg 4.0K Oct 14 01:10 pxelinux.cfg
+-r--r--r-- 1 root vyattacfg 3.7M Oct 13 23:24 vmlinuz
+
+vyos@vyos# ls -hal /config/tftpboot/pxelinux.cfg
+total 12K
+drwxr-xr-x 2 root vyattacfg 4.0K Oct 14 01:10 .
+drwxr-sr-x 3 tftp tftp 4.0K Oct 14 00:23 ..
+-rw-r--r-- 1 root root 191 Oct 14 01:10 default
+```
+
+Example of simple (no menu) configuration file:
+
+```none
+vyos@vyos# cat /config/tftpboot/pxelinux.cfg/default
+DEFAULT VyOS123
+
+LABEL VyOS123
+ KERNEL vmlinuz
+ APPEND initrd=initrd.img-4.19.54-amd64-vyos boot=live nopersistence noautologin nonetworking fetch=http://address:8000/filesystem.squashfs
+```
+
+
+#### Step 3: HTTP
+
+You also need to provide the *filesystem.squashfs* file. Because this is a
+large file and TFTP is slow, you can send it through HTTP to speed up the
+transfer. In our example, we do this—see the configuration file above.
+
+1. Start a web server. You can use one like
+ [Python's SimpleHTTPServer] to serve the `filesystem.squashfs` file.
+ The file is in the `/live` directory of the extracted ISO file.
+2. Edit the {ref}`install_from_tftp` configuration file to show the correct
+ URL: `fetch=http://<address_of_your_HTTP_server>/filesystem.squashfs`.
+
+:::{note}
+Do not rename the *filesystem.squashfs* file. If you're working with
+different versions, create different directories instead.
+:::
+
+3. restart the TFTP service. If you're using VyOS as your TFTP server, restart
+ the service with `sudo service tftpd-hpa restart`.
+
+:::{note}
+Ensure the directories and files on both the TFTP and HTTP servers
+have the correct permissions for the booting clients to access them.
+:::
+
+### Client Boot
+
+Finally, power on your PXE-enabled clients. They will automatically receive an
+IP address from the DHCP server and boot into VyOS live using files from the
+TFTP and HTTP servers.
+
+Once finished you will be able to proceed with the `install image`
+command as in a regular VyOS installation.
+
+## Known Issues
+
+This is a list of known issues that can arise during installation.
+
+### Black screen on install
+
+GRUB redirects all output to a serial port to facilitate installation
+on headless hosts. On some hardware that lacks a serial port, this causes
+a hard lockup and displays a black screen after you select the
+`Live system` option from the installation image.
+
+The workaround is to press `e` when the boot menu appears and edit the
+GRUB boot options. Specifically, remove the:
+
+`console=ttyS0,115200`
+
+option, and type CTRL-X to boot.
+
+Installation can then continue as outlined above.
+
+[article]: https://customers.support.vyos.com/servicedesk/customer/portal/1/article/159055913
+[balenaetcher]: https://www.balena.io/etcher/
+[configuration]: https://wiki.syslinux.org/wiki/index.php?title=Config
+[default]: https://wiki.syslinux.org/wiki/index.php?title=PXELINUX#Configuration
+[many others]: <https://en.wikipedia.org/wiki/List_of_tools_to_create_Live_USB_systems>
+[python's simplehttpserver]: https://docs.python.org/2/library/simplehttpserver.html
+[rufus]: https://rufus.ie/
+[syslinux]: http://www.syslinux.org/
diff --git a/docs/installation/secure-boot.md b/docs/installation/secure-boot.md
new file mode 100644
index 00000000..ecbc432d
--- /dev/null
+++ b/docs/installation/secure-boot.md
@@ -0,0 +1,194 @@
+---
+lastproofread: '2026-01-26'
+---
+
+(secure-boot)=
+
+# Secure Boot
+
+Initial UEFI Secure Boot support is available ({vytask}`T861`). VyOS uses
+`shim` from Debian 12 (Bookworm), which is properly signed by the UEFI
+Secure Boot key from Microsoft.
+
+:::{note}
+There is yet no signed version of `shim` for VyOS, thus we
+provide no signed image for secure boot yet. If you are interested in
+secure boot you can build an image on your own.
+:::
+
+To generate a custom ISO with your own secure boot keys, run the following
+commands prior to your ISO image build:
+
+```bash
+cd vyos-build
+CA_DIR="data/certificates"
+SHIM_CERT_NAME="vyos-dev-2025-shim"
+VYOS_KERNEL_CERT_NAME="vyos-dev-2025-linux"
+
+openssl req -new -x509 -newkey rsa:4096 -keyout ${CA_DIR}/${SHIM_CERT_NAME}.key -out ${CA_DIR}/${SHIM_CERT_NAME}.der \
+ -outform DER -days 36500 -subj "/CN=VyOS Networks Secure Boot CA/" -nodes
+openssl x509 -inform der -in ${CA_DIR}/${SHIM_CERT_NAME}.der -out ${CA_DIR}/${SHIM_CERT_NAME}.pem
+
+openssl req -newkey rsa:4096 -sha256 -nodes -keyout ${CA_DIR}/${VYOS_KERNEL_CERT_NAME}.key \
+ -out ${CA_DIR}/${VYOS_KERNEL_CERT_NAME}.csr -outform PEM -days 3650 \
+ -subj "/CN=VyOS Networks Secure Boot Signer 2025 - linux/"
+openssl x509 -req -in ${CA_DIR}/${VYOS_KERNEL_CERT_NAME}.csr -CA ${CA_DIR}/${SHIM_CERT_NAME}.pem \
+ -CAkey ${CA_DIR}/${SHIM_CERT_NAME}.key -CAcreateserial -out ${CA_DIR}/${VYOS_KERNEL_CERT_NAME}.pem -days 3650 -sha256
+```
+
+
+## Installation
+
+As our version of `shim` is not signed by Microsoft we need to enroll the
+previously generated {abbr}`MOK (Machine Owner Key)` to the system.
+
+First, disable UEFI Secure Boot for the installation.
+
+:::{figure} /_static/images/uefi_secureboot_01.webp
+:alt: Disable UEFI secure boot
+:::
+
+Proceed with the standard VyOS {ref}`installation <permanent_installation>` on
+your system. Instead of the final `reboot` command, enroll the
+{abbr}`MOK (Machine Owner Key)`.
+
+```none
+vyos@vyos:~$ install mok
+input password:
+input password again:
+```
+
+You can set the `input password` to any value you choose. You'll need this
+password after reboot when MOK Manager launches to permanently install the keys.
+
+With the next reboot, MOK Manager will automatically launch
+
+:::{figure} /_static/images/uefi_secureboot_02.webp
+:alt: Disable UEFI secure boot
+:::
+
+Select `Enroll MOK`
+
+:::{figure} /_static/images/uefi_secureboot_03.webp
+:alt: Disable UEFI secure boot
+:::
+
+You can now view the key to be installed and continue with key installation.
+
+:::{figure} /_static/images/uefi_secureboot_04.webp
+:alt: Disable UEFI secure boot
+:::
+
+:::{figure} /_static/images/uefi_secureboot_05.webp
+:alt: Disable UEFI secure boot
+:::
+
+Now you need to enter the password you defined previously.
+
+:::{figure} /_static/images/uefi_secureboot_06.webp
+:alt: Disable UEFI secure boot
+:::
+
+Now reboot and re-enable UEFI Secure Boot.
+
+:::{figure} /_static/images/uefi_secureboot_07.webp
+:alt: Disable UEFI secure boot
+:::
+
+VyOS will now launch in UEFI Secure Boot mode. You can verify this by running
+one of the following commands:
+
+```none
+vyos@vyos:~$ show secure-boot
+SecureBoot enabled
+```
+
+```none
+vyos@vyos:~$ show log kernel | match Secure
+Oct 08 19:15:41 kernel: Secure boot enabled
+```
+
+```none
+vyos@vyos:~$ show version
+Version: VyOS 1.5-secureboot
+Release train: current
+Release flavor: generic
+
+Built by: autobuild@vyos.net
+Built on: Tue 08 Oct 2024 18:00 UTC
+Build UUID: 5702ca38-e6f4-470f-b89e-ffc29baee474
+Build commit ID: 9eb61d3b6cf426
+
+Architecture: x86_64
+Boot via: installed image
+System type: KVM guest
+Secure Boot: enabled <-- UEFI secure boot indicator
+
+Hardware vendor: QEMU
+Hardware model: Standard PC (i440FX + PIIX, 1996)
+Hardware S/N:
+Hardware UUID: 1f6e7f5c-fb52-4c33-96c9-782fbea36436
+
+Copyright: VyOS maintainers and contributors
+```
+
+
+## Image Update
+
+:::{note}
+Currently, there is no signed version of `shim` for VyOS. If you
+want Secure Boot support, you can build a custom image with your own keys.
+:::
+
+During image installation, you install your {abbr}`MOK (Machine Owner Key)`
+into the UEFI variables to add trust to this key. After you re-enable Secure
+Boot in UEFI, you can only boot into your signed image.
+
+You can no longer boot into a CI-generated rolling release because those
+are not signed by a trusted party ({vytask}`T861` work in progress). This
+also means you must sign all successor builds with the same key; otherwise,
+you'll see this error:
+
+```none
+error: bad shim signature
+error: you need to load the kernel first
+```
+
+
+## Linux Kernel
+
+In addition to Secure Boot support, VyOS uses ephemeral key signing of Linux
+Kernel modules for an extra security layer in both Secure and non-Secure boot
+images.
+
+<https://patchwork.kernel.org/project/linux-integrity/patch/20210218220011.67625-5-nayna@linux.ibm.com/>
+
+When the CI system builds a Kernel package and required third-party modules,
+it generates a temporary (ephemeral) key pair for signing the modules. The
+public key is embedded in the Kernel binary to verify loaded modules.
+
+After the Kernel CI build completes, the generated key is discarded, meaning
+we can no longer sign additional modules with that key. The Kernel configuration
+also includes the option `CONFIG_MODULE_SIG_FORCE=y`, which enforces signature
+verification for all modules. If you try to load an unsigned module, you'll
+get this error:
+
+`insmod: ERROR: could not insert module malicious.ko: Key was rejected by
+service`
+
+This prevents loading any malicious code after the image is assembled into the
+Kernel as a module. You can disable this behavior on custom builds if needed.
+
+## Troubleshoot
+
+In most cases, if something goes wrong during system boot, you'll see this
+error message:
+
+```none
+error: bad shim signature
+error: you need to load the kernel first
+```
+
+This error means the Machine Owner Key used to sign the Kernel is not trusted
+by your UEFI. Install the MOK using the `install mok` command as described
+above.
diff --git a/docs/installation/update.md b/docs/installation/update.md
new file mode 100644
index 00000000..e8b5f912
--- /dev/null
+++ b/docs/installation/update.md
@@ -0,0 +1,105 @@
+---
+lastproofread: '2026-01-26'
+---
+
+(update_vyos)=
+
+# Update VyOS
+
+New system images can be added using the {opcmd}`add system image` command.
+This command extracts the image and prompts you to use the current system
+configuration and SSH security keys, allowing the new image to boot with your
+current configuration.
+
+:::{note}
+Only LTS releases are PGP-signed.
+:::
+
+```{opcmd} add system image \<url | path\> | [latest] [vrf name] [username user [password pass]]
+
+Use this command to install a new system image. You can retrieve the
+image from the web (``http://``, ``https://``) or from your local system.
+For example: /tmp/vyos-1.2.3-amd64.iso.
+
+ The ``add system image`` command also supports installing new VyOS versions
+ through an optional VRF. If the URL requires authentication, you can specify
+ an optional username and password on the command line, which will be passed
+ as "Basic-Auth" to the server.
+```
+
+If there isn't enough free disk space, the installation will be canceled.
+To delete images, use the {opcmd}`delete system image` command.
+
+
+VyOS associates configuration with each image, and each image has its own
+unique configuration copy. This differs from traditional network routers where
+the configuration is shared across all images.
+
+
+:::{note}
+If you have personal files such as scripts that you want to preserve
+during the upgrade, store them in `/config` since this directory is always
+copied to newly installed images.
+:::
+
+
+You can access files from a previous installation and copy them to your
+current image if they were stored in the `/config` directory. Use the
+{opcmd}`copy` command to do this. For example, to copy `/config/config.boot`
+from the VyOS `1.2.1` image, run:
+
+```none
+copy file 1.2.1://config/config.boot to /tmp/config.boot.1.2.1
+```
+
+
+#### Example
+
+```none
+vyos@vyos:~$ add system image https://s3.amazonaws.com/s3-us.vyos.io/rolling/current/vyos-1.4-rolling-202201120317-amd64.iso
+Trying to fetch ISO file from https://s3.amazonaws.com/s3-us.vyos.io/rolling/current/vyos-1.4-rolling-202201120317-amd64.iso
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 338M 100 338M 0 0 3837k 0 0:01:30 0:01:30 --:--:-- 3929k
+ISO download succeeded.
+Checking for digital signature file...
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+ 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
+curl: (22) The requested URL returned error: 404 Not Found
+
+Unable to fetch digital signature file.
+Do you want to continue without signature check? (yes/no) [yes]
+Checking MD5 checksums of files on the ISO image...OK.
+Done!
+
+What would you like to name this image? [vyos-1.3-rolling-201912201452]:
+
+OK. This image will be named: vyos-1.3-rolling-201912201452
+```
+
+You can use `latest` option. It loads the latest available Rolling release.
+
+```none
+vyos@vyos:~$ add system image latest
+```
+
+:::{note}
+To use the `latest` option, "system update-check url" must be
+configured appropriately for your installed release.
+
+For updates to the Rolling Release for AMD64, the following URL may be
+used:
+
+<https://raw.githubusercontent.com/vyos/vyos-nightly-build/refs/heads/current/version.json>
+:::
+
+:::{hint}
+You can access the latest Rolling Release for AMD64 from a web
+browser at:
+
+<https://vyos.net/get/nightly-builds/>
+:::
+
+After rebooting, verify the version you're running using the
+{opcmd}`show version` command.
diff --git a/docs/installation/virtual/docker.md b/docs/installation/virtual/docker.md
new file mode 100644
index 00000000..3489b94a
--- /dev/null
+++ b/docs/installation/virtual/docker.md
@@ -0,0 +1,72 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(docker)=
+
+# Run VyOS in a Docker Container
+
+Docker is an open-source project for deploying applications as standardized
+units called containers. Deploying VyOS in a container provides a simple and
+lightweight mechanism for both testing and packet routing for container
+workloads.
+
+## IPv6 support for Docker
+
+VyOS requires an IPv6-enabled Docker network. Currently Linux distributions
+do not enable Docker IPv6 support by default. You can enable IPv6 support in
+two ways.
+
+### Method 1: Create a docker network with IPv6 support
+
+Here's an example using the `macvlan` driver.
+
+```none
+docker network create --ipv6 -d macvlan -o parent=eth0 --subnet 2001:db8::/64 --subnet 192.0.2.0/24 mynet
+```
+
+
+### Method 2: Add IPv6 support to the Docker daemon
+
+Edit /etc/docker/daemon.json to set the `ipv6` key to `true` and specify
+the `fixed-cidr-v6` to your desired IPv6 subnet.
+
+```none
+{
+ "ipv6": true,
+ "fixed-cidr-v6": "2001:db8::/64"
+}
+```
+
+Reload the Docker configuration.
+
+```none
+$ sudo systemctl reload docker
+```
+
+
+## Deploy container from ISO
+
+Download the ISO you want to base the container on. In this example,
+the ISO is `vyos-1.4-rolling-202308240020-amd64.iso`. If you
+created a custom IPv6-enabled network, include it as the `--net` parameter
+to `docker run`.
+
+```none
+$ mkdir vyos && cd vyos
+$ curl -o vyos-1.4-rolling-202308240020-amd64.iso https://github.com/vyos/vyos-rolling-nightly-builds/releases/download/1.4-rolling-202308240020/vyos-1.4-rolling-202308240020-amd64.iso
+$ mkdir rootfs
+$ sudo mount -o loop vyos-1.4-rolling-202308240020-amd64.iso rootfs
+$ sudo apt-get install -y squashfs-tools
+$ mkdir unsquashfs
+$ sudo unsquashfs -f -d unsquashfs/ rootfs/live/filesystem.squashfs
+$ sudo tar -C unsquashfs -c . | docker import - vyos:1.4-rolling-202111281249
+$ sudo umount rootfs
+$ cd ..
+$ sudo rm -rf vyos
+$ docker run -d --rm --name vyos --privileged -v /lib/modules:/lib/modules \
+> vyos:1.4-rolling-202111281249 /sbin/init
+$ docker exec -ti vyos su - vyos
+```
+
+To stop the container, run `docker stop vyos`.
diff --git a/docs/installation/virtual/eve-ng.md b/docs/installation/virtual/eve-ng.md
new file mode 100644
index 00000000..1ee1c016
--- /dev/null
+++ b/docs/installation/virtual/eve-ng.md
@@ -0,0 +1,14 @@
+---
+lastproofread: '2026-02-02'
+---
+
+# EVE-NG
+
+:::{note}
+This page is a stub and needs expansion. Contributions
+welcome via the [VyOS documentation repository](https://github.com/vyos/vyos-documentation).
+:::
+
+## References
+
+<https://www.eve-ng.net/>
diff --git a/docs/installation/virtual/gns3.md b/docs/installation/virtual/gns3.md
new file mode 100644
index 00000000..e4cb49c0
--- /dev/null
+++ b/docs/installation/virtual/gns3.md
@@ -0,0 +1,191 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(vyos-on-gns3)=
+
+# Run VyOS on GNS3
+
+You may want to test VyOS in a lab environment.
+[GNS3](http://www.gns3.com) is a network emulation software that you
+can use for this purpose.
+
+This guide will provide the necessary steps for installing
+and setting up VyOS on GNS3.
+
+## Requirements
+
+The following items are required:
+
+- A VyOS installation image (.iso file). You
+ can find how to get it on the {ref}`installation` page
+- A working GNS3 installation. For further information see the
+ [GNS3 documentation](https://docs.gns3.com/).
+
+(vm-setup)=
+
+## VM setup
+
+First, a virtual machine (VM) for the VyOS installation must be created
+in GNS3.
+
+Go to the GNS3 **File** menu, click **New template**, and select
+**Manually create a new Template**.
+
+:::{figure} /_static/images/gns3-01.webp
+:::
+
+Select **Qemu VMs** and then click the `New` button.
+
+:::{figure} /_static/images/gns3-02.webp
+:::
+
+Write a name for your VM, such as "VyOS", and click `Next`.
+
+:::{figure} /_static/images/gns3-03.webp
+:::
+
+Select **qemu-system-x86_64** as Quemu binary, then **512MB** of RAM
+and click `Next`.
+
+:::{figure} /_static/images/gns3-04.webp
+:::
+
+Select **telnet** as your console type and click `Next`.
+
+:::{figure} /_static/images/gns3-05.webp
+:::
+
+Select **New image** for the base disk image of your VM and click
+`Create`.
+
+:::{figure} /_static/images/gns3-06.webp
+:::
+
+Use the defaults in the **Binary and format** window and click
+`Next`.
+
+:::{figure} /_static/images/gns3-07.webp
+:::
+
+Use the defaults in the **Qcow2 options** window and click `Next`.
+
+:::{figure} /_static/images/gns3-08.webp
+:::
+
+Set the disk size to 2000 MiB, and click `Finish` to end the **Quemu
+image creator**.
+
+:::{figure} /_static/images/gns3-09.webp
+:::
+
+Click `Finish` to end the **New QEMU VM template** wizard.
+
+:::{figure} /_static/images/gns3-10.webp
+:::
+
+Now you need to edit the VM settings.
+
+In the **Preferences** window, with **Qemu VMs** selected and your new VM
+selected, click the `Edit` button.
+
+:::{figure} /_static/images/gns3-11.webp
+:::
+
+In the **General settings** tab of your **QEMU VM template
+configuration**, do the following:
+
+- Click on the `Browse...` button to choose the **Symbol** you want to
+ have representing your VM.
+- In **Category** select in which group you want to find your VM.
+- Set the **Boot priority** to **CD/DVD-ROM**.
+
+:::{figure} /_static/images/gns3-12.webp
+:::
+
+At the **HDD** tab, change the Disk interface to **sata** to speed up
+the boot process.
+
+:::{figure} /_static/images/gns3-13.webp
+:::
+
+At the **CD/DVD** tab click on `Browse...` and locate the VyOS image
+you want to install.
+
+:::{figure} /_static/images/gns3-14.webp
+:::
+
+:::{note}
+You probably will want to accept to copy the .iso file to your
+default image directory when you are asked.
+:::
+
+In the **Network** tab, set the number of adapters to **0**, set the
+**Name format** to **eth\{0}**, and set the **Type** to **Paravirtualized
+Network I/O (virtio-net-pci)**.
+
+:::{figure} /_static/images/gns3-15.webp
+:::
+
+In the **Advanced** tab, unmark the checkbox **Use as a linked base
+VM** and click `OK`, which will save and close the **QEMU VM template
+configuration** window.
+
+:::{figure} /_static/images/gns3-16.webp
+:::
+
+At the general **Preferences** window, click `OK` to save and close.
+
+:::{figure} /_static/images/gns3-17.webp
+:::
+
+(vyos-installation)=
+
+## VyOS installation
+
+- Create a new project.
+- Drag the newly created VyOS VM into it.
+- Start the VM.
+- Open a console.
+ The console displays the system booting. It prompts for login
+ credentials. You're now at the VyOS live system.
+- {ref}`Install VyOS <installation>`
+ as normal (that is, using the `install image` command).
+- After successful installation, shut down the VM with the `poweroff`
+ command.
+- **Delete the VM** from the GNS3 project.
+
+The *VyOS-hda.qcow2* file now contains a working VyOS image and can be
+used as a template. But it still needs some fixes before we can deploy
+VyOS in our labs.
+
+(vyos-vm-configuration)=
+
+## VyOS VM configuration
+
+To turn the template into a working VyOS machine, further steps are
+necessary as outlined below:
+
+**General settings** tab: Set the boot priority to **HDD**
+
+:::{figure} /_static/images/gns3-20.webp
+:::
+
+**CD/DVD** tab: Clear the **Image** entry field to unmount the installation
+image.
+
+:::{figure} /_static/images/gns3-21.webp
+:::
+
+Set the number of required network adapters. For example, set it to **4**.
+
+:::{figure} /_static/images/gns3-215.webp
+:::
+
+**Advanced** settings tab: Check the **Use as a linked
+base VM** checkbox and click `OK` to save the changes.
+
+:::{figure} /_static/images/gns3-22.webp
+:::
+
+The VyOS VM is now ready to be deployed.
diff --git a/docs/installation/virtual/index.md b/docs/installation/virtual/index.md
new file mode 100644
index 00000000..97579129
--- /dev/null
+++ b/docs/installation/virtual/index.md
@@ -0,0 +1,16 @@
+---
+lastproofread: '2026-02-02'
+---
+
+# Virtual Environments
+
+```{toctree}
+:caption: Content
+
+libvirt
+proxmox
+vmware
+gns3
+eve-ng
+docker
+```
diff --git a/docs/installation/virtual/libvirt.md b/docs/installation/virtual/libvirt.md
new file mode 100644
index 00000000..0a21a97a
--- /dev/null
+++ b/docs/installation/virtual/libvirt.md
@@ -0,0 +1,186 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(libvirt)=
+
+# Run VyOS on Libvirt QEMU/KVM
+
+Libvirt is an open-source API, daemon, and management tool for managing platform
+virtualization. You can deploy VyOS on libvirt KVM in several ways:
+using Virt-Manager or the native CLI. This example uses 4 gigabytes
+of memory, 2 CPU cores, and the default network `virbr0`.
+
+## CLI
+
+### Deploy from ISO
+
+Create VM name `vyos_r1`. You must specify the path to the `ISO` image,
+the disk `qcow2` will be created automatically. The `default` network is
+the virtual network (type Virtio) created by the hypervisor with NAT.
+
+```none
+$ virt-install -n vyos_r1 \
+ --ram 4096 \
+ --vcpus 2 \
+ --cdrom /var/lib/libvirt/images/vyos.iso \
+ --os-variant debian10 \
+ --network network=default \
+ --graphics vnc \
+ --hvm \
+ --virt-type kvm \
+ --disk path=/var/lib/libvirt/images/vyos_r1.qcow2,bus=virtio,size=8 \
+ --noautoconsole
+```
+
+Connect to the VM with the command `virsh console vyos_r1`
+
+```none
+$ virsh console vyos_r1
+
+Connected to domain vyos_r1
+Escape character is ^]
+
+vyos login: vyos
+Password:
+
+vyos@vyos:~$ install image
+```
+
+After installation, exit the console using the key combination
+`Ctrl + ]` and reboot the system.
+
+### Deploy from qcow2
+
+The benefit of using {abbr}`KVM (Kernel-based Virtual Machine)`
+images is that they don't require installation.
+Download the predefined VyOS `.qcow2` image.
+
+```none
+curl --url link_to_vyos_kvm.qcow2 --output /var/lib/libvirt/images/vyos_kvm.qcow2
+```
+
+Create VM with `import` qcow2 disk option.
+
+```none
+$ virt-install -n vyos_r2 \
+ --ram 4096 \
+ --vcpus 2 \
+ --os-variant debian10 \
+ --network network=default \
+ --graphics vnc \
+ --hvm \
+ --virt-type kvm \
+ --disk path=/var/lib/libvirt/images/vyos_kvm.qcow2,bus=virtio \
+ --import \
+ --noautoconsole
+```
+
+Connect to the VM with the command `virsh console vyos_r2`
+
+```none
+$ virsh console vyos_r2
+
+Connected to domain vyos_r2
+Escape character is ^]
+
+vyos login: vyos
+Password:
+
+vyos@vyos:~$
+```
+
+If you cannot access the login screen, the KVM console may be set as the
+default boot option.
+
+Open a secondary session and run this command to reboot the VM:
+
+```none
+$ virsh reboot vyos_r2
+```
+
+Then go to the first session where you opened the console.
+Select `VyOS 1.4.x for QEMU (Serial console)` and press `Enter`.
+
+The system is fully operational.
+
+## Virt-Manager
+
+The Virt-Manager application is a desktop user interface for managing virtual
+machines through libvirt. On Linux, open the
+{abbr}`VMM (Virtual Machine Manager)`.
+
+(libvirt-virt-manager-iso)=
+
+### Deploy from ISO
+
+1. Open {abbr}`VMM (Virtual Machine Manager)` and create a new
+ {abbr}`VM (Virtual Machine)`
+2. Choose `Local install media` (ISO)
+
+:::{figure} /_static/images/virt-libvirt-01.webp
+:::
+
+3. Choose the path to the VyOS ISO image. Select any Debian-based operating
+ system.
+
+:::{figure} /_static/images/virt-libvirt-02.webp
+:::
+
+4. Choose Memory and CPU
+
+:::{figure} /_static/images/virt-libvirt-03.webp
+:::
+
+5. Disk size
+
+:::{figure} /_static/images/virt-libvirt-04.webp
+:::
+
+6. Name of VM and network selection
+
+:::{figure} /_static/images/virt-libvirt-05.webp
+:::
+
+7. Then the system will be taken to the console.
+
+:::{figure} /_static/images/virt-libvirt-06.webp
+:::
+
+(libvirt-virt-manager-qcow2)=
+
+### Deploy from qcow2
+
+Download the predefined VyOS `.qcow2` image.
+
+```none
+curl --url link_to_vyos_kvm.qcow2 --output /var/lib/libvirt/images/vyos_kvm.qcow2
+```
+
+1. Open {abbr}`VMM (Virtual Machine Manager)` and create a new
+ {abbr}`VM (Virtual Machine)`
+2. Choose `Import existing disk` image
+
+:::{figure} /_static/images/virt-libvirt-qc-01.webp
+:::
+
+3. Choose the path to the `vyos_kvm.qcow2` image that you downloaded.
+ Select any Debian-based operating system.
+
+:::{figure} /_static/images/virt-libvirt-qc-02.webp
+:::
+
+4. Choose Memory and CPU
+
+:::{figure} /_static/images/virt-libvirt-03.webp
+:::
+
+5. Name of VM and network selection
+
+:::{figure} /_static/images/virt-libvirt-05.webp
+:::
+
+6. Then the system will be taken to the console.
+
+:::{figure} /_static/images/virt-libvirt-qc-03.webp
+:::
diff --git a/docs/installation/virtual/proxmox.md b/docs/installation/virtual/proxmox.md
new file mode 100644
index 00000000..6b959341
--- /dev/null
+++ b/docs/installation/virtual/proxmox.md
@@ -0,0 +1,80 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(proxmox)=
+
+# Running on Proxmox
+
+Proxmox is an open-source platform for virtualization.
+
+## Deploy VyOS from CLI with qcow2 image
+
+1. Download the `.qcow2` image from <https://support.vyos.io/>.
+ Official images are available to users with a valid subscription.
+
+2. Copy the `.qcow2` image to a temporary directory on the Proxmox server.
+
+3. The following commands assume that virtual machine (VM) ID `200` is unused
+ and that the imported disk will be stored in a storage pool named `local-lvm`.
+
+ > ```none
+ > $ qm create 200 --name vyos --memory 4096 --net0 virtio,bridge=vmbr0
+ > $ qm importdisk 200 /var/lib/vz/images/vyos-<version>-proxmox-amd64.qcow2 local-lvm
+ > $ qm set 200 --virtio0 local-lvm:vm-200-disk-0
+ > $ qm set 200 --boot order=virtio0
+ > ```
+
+4. When using a `qcow2` image on Proxmox, the system
+ **does not include any preconfigured user accounts**.
+ You must define a user account using **Cloud-Init** before the
+ first boot. Otherwise, login access is not possible.
+
+ Attach a Cloud-Init data source to the VM. For example, using
+ `local-lvm` storage:
+
+ ```bash
+ $ qm set 200 --ide2 local-lvm:cloudinit
+ ```
+
+ Alternatively, add a Cloud-Init drive using the Proxmox GUI:
+
+ 1. Open the VM and navigate to **Hardware**
+ 2. Click **Add** → **CloudInit Drive**
+ 3. Select a storage (for example, `local-lvm`)
+ 4. Click **Add**
+
+5. Start the virtual machine using the Proxmox GUI or by running `qm start 200`.
+
+## Deploy VyOS from CLI with rolling release ISO
+
+1. Download the rolling release ISO from
+ <https://vyos.net/get/nightly-builds/>.
+2. Prepare the VM for ISO installation.
+ The commands below assume that the ISO image is available in the
+ `local` storage, a VM ID `200` is unused, and a 15GB disk will be
+ created on storage pool `local-lvm`.
+
+```none
+qm create 200 --name vyos --memory 4096 \
+--net0 virtio,bridge=vmbr0 \
+--scsihw virtio-scsi-pci \
+--scsi0 local-lvm:15 \
+--ide2 local:iso/vyos-<version>.iso,media=cdrom \
+--boot order=ide2
+```
+
+3. Start the VM using `qm start 200` or by clicking the **Start**
+ button in the Proxmox GUI.
+4. In the Proxmox GUI, open the virtual console for your new VM.
+ The login username and password are `vyos`/`vyos`.
+5. After booting into the live system, type `install image` and follow
+ the prompts to install VyOS to the virtual drive.
+6. After installation completes, remove the installation ISO using the
+ GUI or run `qm set 200 --ide2 none`, then set the boot device
+ with `qm set 200 --boot order=scsi0`.
+7. Reboot the virtual machine using the GUI or run `qm reboot 200`.
+
+For more information about downloading and installing Proxmox, visit
+<https://www.proxmox.com/en/>.
+
diff --git a/docs/installation/virtual/vmware.md b/docs/installation/virtual/vmware.md
new file mode 100644
index 00000000..34fb2197
--- /dev/null
+++ b/docs/installation/virtual/vmware.md
@@ -0,0 +1,38 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(vyosonvmware)=
+
+# Running on VMware ESXi
+
+## ESXi 5.5 or later
+
+`.ova` files are available for supporting users. You can also set up VyOS
+using a generic Linux instance by attaching the bootable ISO file and
+installing using the `install image` command.
+
+:::{NOTE}
+Previous issues have been documented with GRE/IPSEC tunneling
+using the E1000 adapter on VyOS guests. Use the VMXNET3 adapter instead.
+:::
+
+### Memory Contention Considerations
+
+When the underlying ESXi host reaches approximately 92% memory utilization,
+it begins the balloon process to reclaim memory from guest operating systems.
+This creates artificial memory pressure through the `vmmemctl` driver. Because
+VyOS does not have a swap file by default, this pressure cannot move memory
+data to a paging file. Instead, it consumes memory and forces the guest into
+a low memory state with no recovery option. The balloon can expand to 65% of
+guest allocated memory, so a VyOS guest using more than 35% of memory can
+encounter an out-of-memory situation and trigger the kernel `oom_kill`
+process. The `oom_kill` process then terminates memory-hungry processes.
+
+To prevent ballooning, configure VyOS routers in a resource group with
+adequate memory reservations.
+
+### References
+
+<https://muralidba.blogspot.com/2018/03/how-does-linux-out-of-memory-oom-killer.html>
+
diff --git a/docs/introducing/about.md b/docs/introducing/about.md
new file mode 100644
index 00000000..ec4ff30d
--- /dev/null
+++ b/docs/introducing/about.md
@@ -0,0 +1,21 @@
+(about)=
+
+# About
+
+VyOS is an open-source network operating system that provides a single unified
+CLI and API to manage routing protocols, firewall and NAT, QoS, load balancing,
+DHCP and DNS servers, and many other features.
+
+VyOS runs on a wide variety of commodity hardware, virtual machines, and
+multiple cloud environments.
+
+We provide a dedicated user guide for each major
+VyOS release that receives long-term support (LTS). We maintain multiple user
+guide versions, all hosted at <https://docs.vyos.io>.
+To switch between versions, select the appropriate version in the bottom-right
+corner.
+
+VyOS CLI syntax may vary between major and sometimes minor releases. Always
+refer to the documentation matching your current running installation. If
+a change in the CLI is required, VyOS provides a migration script to handle
+the syntax adjustments. No user action is required.
diff --git a/docs/introducing/history.md b/docs/introducing/history.md
new file mode 100644
index 00000000..77b82986
--- /dev/null
+++ b/docs/introducing/history.md
@@ -0,0 +1,171 @@
+---
+description: |-
+ Overview of the VyOS project's history, from its 2013 fork of Vyatta Core
+ through each major LTS release. Covers release codenames, base Debian
+ versions, and the headline features introduced in each version.
+keywords: |-
+ vyos history, vyatta fork, lts release, scutum, circinus, sagitta,
+ equuleus, crux, debian
+---
+
+(history)=
+
+# History
+
+## In the beginning...
+
+There was a network operating system based on Debian GNU/Linux, called
+Vyatta. [^footnote-1] Introduced in 2006, it served as a great free-software alternative
+to proprietary products. Vyatta came in two editions: Vyatta Core
+(formerly known as Vyatta Community Edition), which was free software, and
+Vyatta Subscription Edition, which included proprietary features and was
+available only to paying customers.
+
+Brocade Communications Systems acquired Vyatta in 2012. Shortly after, Brocade
+renamed Vyatta Subscription Edition to Brocade vRouter, discontinued Vyatta
+Core, and shut down the community forum without notice. The bug tracker and Git
+repositories were closed the following year.
+
+By the time Brocade acquired Vyatta, the development of Vyatta Core had
+already stagnated. The focus had shifted to Vyatta Subscription Edition,
+where core components were replaced with proprietary software. As a result,
+Vyatta Core received fewer new features, and some of those added faced issues.
+
+In 2013, shortly after Vyatta Core was discontinued, the community forked its
+final version (6.6R1) to create the VyOS project. In 2014, the maintainers
+established a company to fund VyOS development through technical support,
+consulting services, and LTS release access subscriptions. The company was
+originally named Sentrium and was later reorganized under the VyOS brand.
+
+## Major releases
+
+VyOS originally named its major versions after elements by atomic number.
+Beginning with version 1.2, this naming scheme was changed. It now uses the
+Latin names of constellations recognized by the International Astronomical
+Union ([IAU](https://en.wikipedia.org/wiki/IAU_designated_constellations_by_area)),
+ordered by their solid angle area, beginning with the smallest.
+
+### Hydrogen (1.0)
+
+Released just in time for the holidays on 22 December 2013, Hydrogen was
+the first major VyOS release. It fixed features that were broken in
+Vyatta Core 6.6, such as IPv4 BGP peer groups and DHCPv6 relay, and
+introduced command scripting, a task scheduler, and web proxy LDAP
+authentication.
+
+### Helium (1.1)
+
+Helium, released on 9 October 2014, marked the first anniversary of the
+VyOS Project. The release introduced an event handler, L2TPv3 support,
+802.1ad (QinQ), and IGMP proxy, as well as experimental support for VXLAN
+and DMVPN. Notably, DMVPN remained non-functional in Vyatta Core due to its
+reliance on a proprietary NHRP implementation.
+
+### Crux (1.2)
+
+Crux (the Southern Cross) was released on 28 January 2019 and marked a
+departure from legacy Vyatta codebase and the start of the migration from
+Perl to Python as the primary language. The underlying base system was
+upgraded from Debian 6 (Squeeze) to Debian 8 (Jessie).
+
+Crux introduced many new features, some of the most noteworthy are:
+an mDNS repeater, a broadcast relay, a high-performance PPPoE server,
+an HFSC scheduler, and support for Wireguard, unicast VRRP, RPKI for BGP,
+and fully 802.1ad-compliant QinQ ethertype. The telnet server and support
+for P2P filtering were removed.
+
+Crux was the first VyOS release to feature a modular image build system.
+CLI definitions were written using an XML syntax automatically checked
+against a schema at build time. Python APIs were introduced for command
+scripting and configuration migration. New Perl code and old-style (non-XML)
+command definition were no longer accepted from that point.
+
+Crux reached the end of support in 2023.
+
+### Equuleus (1.3)
+
+Equuleus (the Little Horse) was a long-term support version released
+on 21 December 2021, just in time for the winter holidays.
+
+Equuleus brought many long-awaited features, most notably an SSTP VPN
+server, an IPoE server, an OpenConnect VPN server, and a serial console
+server. It also introduced reworked support for WWAN interfaces, support
+for GENEVE and MACSec interfaces, VRF, IS-IS routing, and preliminary support
+for MPLS and LDP.
+
+Equuleus reached the end of support in 2025.
+
+### Sagitta (1.4)
+
+Sagitta (the Arrow), the current LTS release, became generally available on
+4 June 2024. Its development began in late 2021 and focused on eliminating
+remaining legacy components and reworking core subsystems.
+
+The transition to XML-defined command definitions and script refactoring with
+separate verify, update, and apply stages were completed. The firewall
+subsystem was rebuilt on nftables, introducing interface-independent rulesets
+and the reimplemented zone-based firewall model. The PKI subsystem was
+redesigned to manage cryptographic material directly within the configuration
+file.
+
+Sagitta introduced rollback without reboot, support for Babel and PIM6 routing
+protocols, failover routes, segment routing, NAT64, an IKEv2 remote-access VPN
+server, Zabbix monitoring, HTTP load balancing, and configuration
+synchronization using the HTTP API.
+
+The underlying base system was upgraded to Debian 12 (Bookworm).
+
+### Circinus (1.5)
+
+Circinus (the Drawing Compass) became generally available as an LTS release on
+31 March 2026. Its development began in 2024 and focused on major performance
+upgrades and modernizing core subsystems.
+
+Circinus introduces several major architectural improvements, most notably an
+optional VPP-based accelerated dataplane. Using the DPDK driver, this dataplane
+can offer performance up to 15x faster than the Linux kernel dataplane and
+allows administrators to selectively enable hardware acceleration on a
+per-interface and per-feature basis.
+
+Other significant additions and updates include:
+
+- A high-performance kernel-mode NetFlow sensor based on ipt-netflow,
+ replacing the older pmacct implementation.
+- Unification of sFlow to exclusively use the much faster hsflowd
+ implementation.
+- Transition of the DHCP server to a Kea-based implementation, replacing the
+ legacy, end-of-life ISC DHCPD.
+- A completely rewritten WAN load balancing implementation to resolve
+ long-standing stability issues and introduce support for firewall groups in
+ load balancing rules.
+- A new `execute` operational mode command family to separate action commands
+ that do not depend on or modify system configuration.
+
+The release also cleans up several legacy and underutilized components.
+FastNetMon was removed, OpenVPN support for Blowfish and Twofish ciphers was
+dropped for security reasons, and the Salt minion integration was deprecated.
+
+Like Sagitta (1.4), the underlying base system for Circinus remains Debian 12
+(Bookworm).
+
+### Scutum (1.6)
+
+Scutum (the Shield) is the codename for the upcoming development
+branch. VyOS 1.6 Scutum has not been released yet.
+
+## A note on copyright
+
+Unlike Vyatta, VyOS has never had closed-source code and never will.
+The only proprietary material in VyOS is non-code assets, such as
+graphics and the trademark "VyOS". [^footnote-2]
+
+Note that we do not provide support for images distributed by a third party.
+See the
+[artwork license](https://github.com/vyos/vyos-build/blob/current/LICENSE.artwork)
+and the end-user license agreement at `/usr/share/vyos/EULA` in
+any pre-built image for more information.
+
+[^footnote-1]: From the Sanskrit adjective "Vyātta" (व्यात्त), meaning opened.
+
+[^footnote-2]: This is similar to how Linus Torvalds owns the Linux trademark.
+
diff --git a/docs/operation/boot-options.md b/docs/operation/boot-options.md
new file mode 100644
index 00000000..3c33ee3e
--- /dev/null
+++ b/docs/operation/boot-options.md
@@ -0,0 +1,55 @@
+---
+lastproofread: '2025-11-14'
+---
+
+(boot-options)=
+
+# Boot Options
+
+:::{warning}
+This function can disrupt services.
+Run it only when necessary, and verify all input values before proceeding.
+:::
+
+VyOS provides several kernel command-line options to modify the normal boot
+process.
+To add an option, select the desired image in the GRUB menu at load time.
+Type **e** to edit the first line, then type **Ctrl+X** to boot.
+
+```{image} /_static/images/boot-options.webp
+:align: center
+:width: 80%
+```
+
+
+## Specify custom config file
+
+You can use a configuration file instead of the default `/config/config.boot`
+file. If the specified file doesn't exist or isn't readable, the system uses the
+default configuration file. No additional verification is performed, so specify
+a valid configuration file.
+
+```none
+vyos-config=/path/to/file
+```
+
+To load the *factory default* configuration, use:
+
+```none
+vyos-config=/opt/vyatta/etc/config.boot.default
+```
+
+
+## Disable specific boot process steps
+
+These options disable certain steps in the boot process. Understand the
+{ref}`boot process <boot-steps>` before using them.
+
+:::{glossary}
+no-vyos-migrate
+ Do not perform config migration.
+
+no-vyos-firewall
+ Do not initialize default firewall chains, renders any firewall
+ configuration unusable.
+:::
diff --git a/docs/operation/index.md b/docs/operation/index.md
new file mode 100644
index 00000000..b3c02571
--- /dev/null
+++ b/docs/operation/index.md
@@ -0,0 +1,12 @@
+# Operation Mode
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+information
+boot-options
+upgrade-recovery
+password-recovery
+raid
+```
diff --git a/docs/operation/information.md b/docs/operation/information.md
new file mode 100644
index 00000000..a6b6de0c
--- /dev/null
+++ b/docs/operation/information.md
@@ -0,0 +1,106 @@
+---
+lastproofread: '2025-11-19'
+---
+
+(information)=
+
+# System Information
+
+VyOS features a rich set of operational level commands to retrieve arbitrary
+information about your running system. For more information on the VyOS command
+line interface (CLI), see {ref}`cli`.
+
+# Hardware
+
+(hardware_usb)=
+
+## USB
+
+In the past, serial interfaces were defined as `ttySx` and `ttyUSBx` where
+`x` was the instance number. However, the mapping of USB-based
+serial interfaces can change from one system boot to another, depending on
+which driver the operating system loads first.
+This inconsistency can be problematic when you
+use multiple serial interfaces.
+For example, both console-server connections and a serial-backed
+{ref}`wwan-interface`.
+
+To address this issue, and because many low-cost USB-to-serial converters
+do not have a programmed serial number, VyOS now identifies USB-to-serial
+interfaces by the USB root bridge and the bus they connect to.
+This approach is similar to the network interface naming conventions used in
+recent Linux distributions.
+
+```{opcmd} show hardware usb
+
+Retrieve a tree-like representation of all connected USB devices.
+
+:::{note}
+If a device is unplugged and plugged in again, it is assigned a new
+``Port``, ``Dev``, and ``If``.
+:::
+```
+
+```{opcmd} show hardware usb serial
+
+Retrieve a list and description of all connected USB serial devices. The
+device name displayed, (for example ``usb0b2.4p1.0``), can be used
+directly when accessing the serial console as console-server device.
+```
+
+(information-version)=
+
+# Version
+
+```{opcmd} show version
+
+Return the currently running VyOS version and build information. This
+includes the name of the release train, e.g., ``sagitta`` on VyOS 1.4,
+and ``circinus`` on VyOS 1.5.
+
+:::{code-block} none
+vyos@vyos:~$ show version
+
+Version: VyOS 1.4-rolling-202106270801
+Release Train: sagitta
+
+Built by: autobuild@vyos.net
+Built on: Sun 27 Jun 2021 09:50 UTC
+Build UUID: ab43e735-edcb-405a-9f51-f16a1b104e52
+Build Commit ID: f544d75eab758f
+
+Architecture: x86_64
+Boot via: installed image
+System type: KVM guest
+
+Hardware vendor: QEMU
+Hardware model: Standard PC (i440FX + PIIX, 1996)
+Hardware S/N:
+Hardware UUID: Unknown
+
+Copyright: VyOS maintainers and contributors
+:::
+```
+
+```{opcmd} show version kernel
+
+Return the version number of the currently running Linux kernel.
+
+:::{code-block} none
+vyos@vyos:~$ show version kernel
+5.10.46-amd64-vyos
+:::
+```
+
+```{opcmd} show version frr
+
+Return the version number of FRR (Free Range Routing - <https://frrouting.org/>)
+used in this release. This is the routing control plane and a successor to GNU
+Zebra and Quagga.
+
+:::{code-block} none
+vyos@vyos:~$ show version frr
+ FRRouting 7.5.1-20210625-00-gf07d935a2 (vyos).
+ Copyright 1996-2005 Kunihiro Ishiguro, et al.
+:::
+```
diff --git a/docs/operation/password-recovery.md b/docs/operation/password-recovery.md
new file mode 100644
index 00000000..2f1b93c3
--- /dev/null
+++ b/docs/operation/password-recovery.md
@@ -0,0 +1,46 @@
+---
+lastproofread: '2026-02-04'
+---
+
+(password-recovery)=
+
+# Password Recovery
+
+Restart VyOS from the console. The GRUB menu appears.
+Select **Boot options**.
+
+:::{figure} /_static/images/reset-password-step-1.webp
+:width: 600
+:::
+
+Next, select **Select boot mode**.
+
+:::{figure} /_static/images/reset-password-step-2.webp
+:width: 600
+:::
+
+Select **Password reset**.
+
+:::{figure} /_static/images/reset-password-step-3.webp
+:width: 600
+:::
+
+Boot the desired VyOS version.
+
+:::{figure} /_static/images/reset-password-step-4.webp
+:width: 600
+:::
+
+The standalone user password recovery tool runs and prompts you to reset the
+local system user password. VyOS automatically reboots after you reset your
+password.
+
+```console
+Do you wish to reset the admin password? (y or n)
+y
+Which admin account do you want to reset?[vyos]
+my_username
+Enter my_username password:
+Retype my_username password:
+System will reboot in 10 seconds...
+```
diff --git a/docs/operation/raid.md b/docs/operation/raid.md
new file mode 100644
index 00000000..bd0f9a69
--- /dev/null
+++ b/docs/operation/raid.md
@@ -0,0 +1,236 @@
+---
+lastproofread: '2025-11-20'
+---
+
+(raid)=
+
+# RAID 1
+
+A Redundant Array of Independent Disks (RAID) uses two or more hard disk drives
+to improve disk speed, store more data, and/or provide fault tolerance.
+There are several storage schemes possible in a RAID array, each offering a
+different combination of storage, reliability, and performance.
+VyOS supports **RAID 1** deployments. RAID 1 uses two or more
+disks that mirror one another to provide system fault tolerance. In a RAID 1
+configuration, every sector on one disk is duplicated on every sector of all
+disks in the array. Provided even one disk in the RAID 1 set is operational,
+the system continues to run, even through disk replacement (provided that the
+hardware supports in-service replacement of drives).
+RAID 1 can be implemented using special hardware or it can be implemented in
+software. VyOS supports software RAID 1 on two disks.
+The VyOS implementation of RAID 1 features the following:
+
+- Detection and reporting of disk failure.
+- Maintain system operation with one failed disk.
+- Boot the system with one failed disk.
+- Replace a failed disk and initiate re-mirroring.
+- Monitor the status of re-mirroring.
+
+(raid-installation)=
+
+## Installation implications
+
+The VyOS installation utility provides several options for installing
+to a RAID 1 set. You can:
+
+- Use the install system to create the RAID 1 set.
+- Use the built-in Linux commands to create a RAID 1 set before running the
+ install system command.
+- Use a previously-created RAID 1 set.
+
+:::{note}
+Before a permanent installation, VyOS runs a live installation.
+:::
+
+## Configuration
+
+### Standard installation on a single disk
+
+VyOS automatically detects the presence of two or more
+disks that are not currently part of a RAID array when installed. The VyOS
+installation utility automatically offers you the option to configure RAID 1
+mirroring for eligible drives with the following prompt:
+
+```none
+Would you like to configure RAID 1 mirroring on them?
+```
+
+- If you do not want to configure RAID 1 mirroring, enter **No** at the prompt.
+
+### Empty 2+ disk
+
+If VyOS detects two identical disks that are not currently part of a
+RAID 1 set, the VyOS installation utility automatically offers the option
+to configure RAID 1 mirroring for the drives with the following prompt:
+
+```none
+Would you like to configure RAID 1 mirroring on them?
+```
+
+1\. To create a new RAID 1 array, enter **Yes** at the prompt. If VyOS
+detects a filesystem on the partitions being used for RAID 1, it will prompt you
+to indicate whether you want to continue creating the RAID 1 array.
+
+```none
+Continue creating array?
+```
+
+2. To overwrite the old filesystem, enter **Yes**.
+
+3\. The system informs you that all data on both drives will be erased.
+Confirm you want to continue.
+
+```none
+Are you sure you want to do this?
+```
+
+4\. Enter **Yes** at the prompt to retain the current VyOS configuration.
+Enter **No** to delete the current VyOS configuration.
+
+```none
+Would you like me to save the data on it before I delete it?
+```
+
+5\. Enter **Yes** at the prompt to retain the current VyOS configuration.
+Enter **No** to delete the current VyOS configuration.
+
+6. Continue installing VyOS.
+
+### Preexisting RAID 1 configuration
+
+When VyOS detects a previously configured RAID 1 set,
+the installation utility displays the following prompt:
+
+```none
+Would you like to use this one?
+```
+
+1\. To break up the current RAID 1 set, enter **No** at the prompt. The
+installation utility detects that there are two identical disks and offers you
+the option of configuring RAID 1 mirroring with the following
+prompt:
+
+```none
+Would you like to configure RAID 1 mirroring on them?
+```
+
+2\. To decline to set up a new RAID 1 configuration on the disks, enter **No**
+at the prompt. VyOS prompts you to indicate which partition you would
+like the system installed on.
+
+```none
+Which partition should I install the root on? [sda1]:
+```
+
+3\. Enter the partition where you would like the system installed. The system
+then prompts you to indicate whether you want to save the old configuration
+data. This represents the current VyOS configuration.
+
+```none
+Would you like me to save the data on it before I delete it?
+```
+
+4\. Enter **Yes** at the prompt to retain the current VyOS configuration once
+installation is complete. Enter **No** to delete the current VyOS configuration.
+
+5. Continue installing VyOS.
+
+### Detecting and replacing a failed RAID 1 disk
+
+VyOS system detects disk failures within a RAID 1 set and
+reports them to the system console. You can verify the failure by running the
+`show raid` command.
+
+To replace a bad disk within a RAID 1 set:
+
+1. Remove the failed disk from the RAID 1 set:
+
+ ```{opcmd} delete raid \<RAID‐1‐device\> member \<disk‐partition\>
+ ```
+ where `RAID-1-device` is the name of the RAID 1 device. For example,
+ `md0` and
+ `disk-partition` is the name of the failed disk partition. For example,
+ `sdb2`.
+2. Physically remove the failed disk from the system. If the drives are not
+ hot-swappable, then you must shut down the system before removing the disk.
+3. Replace the failed drive with a drive of the same size or larger.
+4. Format the new disk for RAID 1 by running the following command:
+
+ ```{opcmd} format disk \<disk‐device1\> like \<disk‐device2\>
+ ```
+ where `disk-device1` is the replacement disk. For example, `sdb` and
+ `disk-device2` is the existing healthy disk. For example, `sda`.
+
+5. Add the replacement disk to the RAID 1 set by running the following command:
+
+ ```{opcmd} add raid \<RAID‐1‐device\> member \<disk‐partition\>
+ ```
+ where `RAID-1-device` is the name of the RAID 1 device. For example,
+ `md0` and `disk-partition` is the name of the replacement disk partition.
+ For example, `sdb2`.
+
+## Operation
+
+Learn how to add a disk partition to a RAID 1 set, initiate
+mirror synchronization, and check and display information.
+
+```{opcmd} add raid \<RAID‐1‐device\> member \<disk‐partition\>
+
+ Use this command to add a member disk partition to the RAID 1 set. Adding a
+ disk partition to a RAID 1 set initiates mirror synchronization, where all
+ data on the existing member partition is copied to the new partition.
+
+```
+
+```{opcmd} format disk \<disk‐device1\> like \<disk‐device2\>
+
+This command is typically used to prepare a disk to be added to a preexisting
+RAID 1 set (of which ``disk-device2`` is already a member).
+```
+
+```{opcmd} show raid \<RAID‐1‐device\>
+
+shows output for ``show raid md0`` as ``sdb1`` is being added to the RAID 1
+set and is in the process of being resynchronized.
+
+:::{code-block} none
+vyos@vyos:~$ show raid md0
+/dev/md0:
+ Version : 00.90
+Creation Time : Wed Oct 29 09:19:09 2008
+ Raid Level : raid1
+ Array Size : 1044800 (1020.48 MiB 1069.88 MB)
+Used Dev Size : 1044800 (1020.48 MiB 1069.88 MB)
+ Raid Devices : 2
+Total Devices : 2
+Preferred Minor : 0
+Persistence : Superblock is persistent
+Update Time : Wed Oct 29 19:34:23 2008
+ State : active, degraded, recovering
+Active Devices : 1
+Working Devices : 2
+Failed Devices : 0
+Spare Devices : 1
+Rebuild Status : 17% complete
+ UUID : 981abd77:9f8c8dd8:fdbf4de4:3436c70f
+ Events : 0.103
+Number Major Minor RaidDevice State
+ 0 8 1 0 active sync /dev/sda1
+ 2 8 17 1 spare rebuilding /dev/sdb1
+:::
+```
+
+```{opcmd} show disk sda format
+
+Use this command to display the formatting of a hard disk.
+
+:::{code-block} none
+vyos@vyos:~$ show disk sda format
+Disk /dev/sda: 1073 MB, 1073741824 bytes
+85 heads, 9 sectors/track, 2741 cylinders
+Units = cylinders of 765 * 512 = 391680 bytes
+Disk identifier: 0x000b7179
+Device Boot      Start         End      Blocks   Id  System
+/dev/sda1               6        2737     1044922+  fd  Linux raid autodetect
+:::
+``` \ No newline at end of file
diff --git a/docs/operation/upgrade-recovery.md b/docs/operation/upgrade-recovery.md
new file mode 100644
index 00000000..7c0c428d
--- /dev/null
+++ b/docs/operation/upgrade-recovery.md
@@ -0,0 +1,70 @@
+---
+lastproofread: '2025-11-20'
+---
+
+(upgrade-recovery)=
+
+# Recovery after Failed Upgrades
+
+Use **VyOS upgrade recovery** to restore the system to the last working
+version after a failed upgrade.
+
+- {ref}`Configuration: <configuration>` How to enable upgrade recovery
+- {ref}`How it works: <how-it-works>` Overview of the recovery process
+- {ref}`Cancelling recovery: <cancelling-recovery>` Overview of the recovery
+ process
+
+(configuration)=
+
+## Configuration
+
+:::{warning}
+Upgrade recovery is disabled by default. To use it,
+**enable it first**.
+:::
+
+To enable upgrade recovery, run the following command:
+
+```{cfgcmd} set system option reboot-on-upgrade-failure [timeout \<min\>]
+```
+
+- `timeout <min>:` The time in minutes (5 - 30) to cancel upgrade
+ recovery before VyOS reboots.
+ See {ref}`Cancelling Recovery <cancelling-recovery>`.
+(how-it-works)=
+
+## How it works
+
+After a VyOS upgrade, the system monitors the boot process. Upon detecting a
+boot failure, VyOS initiates a revert to the last working version and displays
+the following warning:
+
+```none
+Booting failed, reverting to previous image
+Automatic reboot in xx minutes
+Use "reboot cancel" to cancel
+```
+
+If no action is taken, the reboot happens automatically after the configured
+timeout. Upon successful recovery and reboot, the following message appears:
+
+```none
+WARNING: Image update to "VyOS 1.5.xxxx" failed
+Please check the logs:
+/usr/lib/live/mount/persistence/boot/NAME/rw/var/log
+Message is cleared on next reboot!
+```
+
+(cancelling-recovery)=
+
+## Cancelling recovery
+
+Upon detecting a boot failure, you have the predefined timeout to cancel
+upgrade recovery. This is useful if you want to troubleshoot the faulty VyOS
+version on your own.
+
+To cancel upgrade recovery, run the following command:
+
+```none
+reboot cancel
+```
diff --git a/docs/quick-start.md b/docs/quick-start.md
new file mode 100644
index 00000000..9d1a6eee
--- /dev/null
+++ b/docs/quick-start.md
@@ -0,0 +1,381 @@
+(quick-start)=
+
+# Quick Start
+
+This chapter will guide you on how to get up to speed quickly using your new
+VyOS system. It will show you a very basic configuration example that will
+provide a {ref}`nat` gateway for a device with two network interfaces
+(`eth0` and `eth1`).
+
+(quick-start-configuration-mode)=
+
+## Configuration Mode
+
+By default, VyOS is in operational mode, and the command prompt displays
+a `$`. To configure VyOS, you will need to enter configuration mode, resulting
+in the command prompt displaying a `#`, as demonstrated below:
+
+```none
+vyos@vyos$ configure
+vyos@vyos#
+```
+
+
+## Commit and Save
+
+After every configuration change, you need to apply the changes by using the
+following command:
+
+```none
+commit
+```
+
+Once your configuration works as expected, you can save it permanently by using
+the following command:
+
+```none
+save
+```
+
+
+## Interface Configuration
+
+- Your outside/WAN interface will be `eth0`. It will receive its interface
+ address via DHCP.
+- Your internal/LAN interface will be `eth1`. It will use a static IP address
+ of `192.168.0.1/24`.
+
+After switching to {ref}`quick-start-configuration-mode` issue the following
+commands:
+
+```none
+set interfaces ethernet eth0 address dhcp
+set interfaces ethernet eth0 description 'OUTSIDE'
+set interfaces ethernet eth1 address '192.168.0.1/24'
+set interfaces ethernet eth1 description 'LAN'
+```
+
+
+## SSH Management
+
+After switching to {ref}`quick-start-configuration-mode` issue the following
+commands, and your system will listen on every interface for incoming SSH
+connections. You might want to check the {ref}`ssh` chapter on how to listen
+on specific addresses only.
+
+```none
+set service ssh port '22'
+```
+
+(dhcp-dns-quick-start)=
+
+## DHCP/DNS quick-start
+
+The following settings will configure DHCP and DNS services on
+your internal/LAN network, where VyOS will act as the default gateway and
+DNS server.
+
+- The default gateway and DNS recursor address will be `192.168.0.1/24`
+- The address range `192.168.0.2/24 - 192.168.0.8/24` will be reserved for
+ static assignments
+- DHCP clients will be assigned IP addresses within the range of
+ `192.168.0.9 - 192.168.0.254` and have a domain name of `internal-network`
+- DHCP leases will hold for one day (86400 seconds)
+- VyOS will serve as a full DNS recursor, replacing the need to utilize Google,
+ Cloudflare, or other public DNS servers (which is good for privacy)
+- Only hosts from your internal/LAN network can use the DNS recursor
+
+```none
+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 name-server '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 lease '86400'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range 0 start '192.168.0.9'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range 0 stop '192.168.0.254'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 subnet-id '1'
+
+set service dns forwarding cache-size '0'
+set service dns forwarding listen-address '192.168.0.1'
+set service dns forwarding allow-from '192.168.0.0/24'
+```
+
+
+## NAT
+
+The following settings will configure {ref}`source-nat` rules for our
+internal/LAN network, allowing hosts to communicate through the outside/WAN
+network via IP masquerade.
+
+```none
+set nat source rule 100 outbound-interface name 'eth0'
+set nat source rule 100 source address '192.168.0.0/24'
+set nat source rule 100 translation address masquerade
+```
+
+
+## Firewall
+
+A new firewall structure—which uses the `nftables` backend, rather
+than `iptables`—is available on all installations starting from
+VyOS `1.4-rolling-202308040557`. The firewall supports creation of distinct,
+interlinked chains for each [Netfilter hook](<https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks>)
+and allows for more granular control over the packet filtering process.
+
+The firewall begins with the base `filter` tables you define for each of the
+`forward`, `input`, and `output` Netfiter hooks. Each of these tables is
+populated with rules that are processed in order and can jump to other chains
+for more granular filtering.
+
+### Configure Firewall Groups
+
+To make firewall configuration easier, we can create groups of interfaces,
+networks, addresses, ports, and domains that describe different parts of
+our network. We can then use them for filtering within our firewall rulesets,
+allowing for more concise and readable configuration.
+
+In this case, we will create two interface groups — a `WAN` group for our
+interfaces connected to the public internet and a `LAN` group for the
+interfaces connected to our internal network. Additionally, we will create a
+network group, `NET-INSIDE-v4`, that contains our internal subnet.
+
+```none
+set firewall group interface-group WAN interface eth0
+set firewall group interface-group LAN interface eth1
+set firewall group network-group NET-INSIDE-v4 network '192.168.0.0/24'
+```
+
+
+### Configure Stateful Packet Filtering
+
+With the new firewall structure, we have have a lot of flexibility in how we
+group and order our rules, as shown by the three alternative approaches below.
+
+#### Option 1: Global State Policies
+
+Using options defined in `set firewall global-options state-policy`, state
+policy rules that applies for both IPv4 and IPv6 are created. These global
+state policies also applies for all traffic that passes through the router
+(transit) and for traffic originated/destinated to/from the router itself, and
+will be evaluated before any other rule defined in the firewall.
+
+Most installations would choose this option, and will contain:
+
+```none
+set firewall global-options state-policy established action accept
+set firewall global-options state-policy related action accept
+set firewall global-options state-policy invalid action drop
+```
+
+
+#### Option 2: Common/Custom Chain
+
+We can create a common chain for stateful connection filtering of multiple
+interfaces (or multiple netfilter hooks on one interface). Those individual
+chains can then jump to the common chain for stateful connection filtering,
+returning to the original chain for further rule processing if no action is
+taken on the packet.
+
+The chain we will create is called `CONN_FILTER` and has three rules:
+
+- A default action of `return`, which returns the packet back to the original
+ chain if no action is taken.
+- A rule to `accept` packets from established and related connections.
+- A rule to `drop` packets from invalid connections.
+
+```none
+set firewall ipv4 name CONN_FILTER default-action 'return'
+
+set firewall ipv4 name CONN_FILTER rule 10 action 'accept'
+set firewall ipv4 name CONN_FILTER rule 10 state established
+set firewall ipv4 name CONN_FILTER rule 10 state related
+
+set firewall ipv4 name CONN_FILTER rule 20 action 'drop'
+set firewall ipv4 name CONN_FILTER rule 20 state invalid
+```
+
+Then, we can jump to the common chain from both the `forward` and `input`
+hooks as the first filtering rule in the respective chains:
+
+```none
+set firewall ipv4 forward filter rule 10 action 'jump'
+set firewall ipv4 forward filter rule 10 jump-target CONN_FILTER
+
+set firewall ipv4 input filter rule 10 action 'jump'
+set firewall ipv4 input filter rule 10 jump-target CONN_FILTER
+```
+
+
+#### Option 3: Per-Hook Chain
+
+Alternatively, you can take the more traditional stateful connection
+filtering approach by creating rules on each base hook's chain:
+
+```none
+set firewall ipv4 forward filter rule 5 action 'accept'
+set firewall ipv4 forward filter rule 5 state established
+set firewall ipv4 forward filter rule 5 state related
+set firewall ipv4 forward filter rule 10 action 'drop'
+set firewall ipv4 forward filter rule 10 state invalid
+
+set firewall ipv4 input filter rule 5 action 'accept'
+set firewall ipv4 input filter rule 5 state established
+set firewall ipv4 input filter rule 5 state related
+set firewall ipv4 input filter rule 10 action 'drop'
+set firewall ipv4 input filter rule 10 state invalid
+```
+
+
+### Block Incoming Traffic
+
+Now that we have configured stateful connection filtering to allow traffic from
+established and related connections, we can block all other incoming traffic
+addressed to our local network.
+
+Create a new chain (`OUTSIDE-IN`) which will drop all traffic that is not
+explicitly allowed at some point in the chain. Then, we can jump to that chain
+from the `forward` hook when traffic is coming from the `WAN` interface
+group and is addressed to our local network.
+
+```none
+set firewall ipv4 name OUTSIDE-IN default-action 'drop'
+
+set firewall ipv4 forward filter rule 100 action jump
+set firewall ipv4 forward filter rule 100 jump-target OUTSIDE-IN
+set firewall ipv4 forward filter rule 100 inbound-interface group WAN
+set firewall ipv4 forward filter rule 100 destination group network-group NET-INSIDE-v4
+```
+
+We should also block all traffic destinated to the router itself that isn't
+explicitly allowed at some point in the chain for the `input` hook. As
+we've already configured stateful packet filtering above, we only need to
+set the default action to `drop`:
+
+```none
+set firewall ipv4 input filter default-action 'drop'
+```
+
+
+### Allow Management Access
+
+We can now configure access to the router itself, allowing SSH
+access from the inside/LAN network and rate limiting SSH access from the
+outside/WAN network.
+
+First, create a new dedicated chain (`VyOS_MANAGEMENT`) for management
+access, which returns to the parent chain if no action is taken. Add a rule
+to accept traffic from the `LAN` interface group:
+
+```none
+set firewall ipv4 name VyOS_MANAGEMENT default-action 'return'
+```
+
+Configure a rule on the `input` hook filter to jump to the `VyOS_MANAGEMENT`
+chain when new connections are addressed to port 22 (SSH) on the router itself:
+
+```none
+set firewall ipv4 input filter rule 20 action jump
+set firewall ipv4 input filter rule 20 jump-target VyOS_MANAGEMENT
+set firewall ipv4 input filter rule 20 destination port 22
+set firewall ipv4 input filter rule 20 protocol tcp
+```
+
+Finally, configure the `VyOS_MANAGEMENT` chain to accept connection from the
+`LAN` interface group while limiting requests coming from the `WAN`
+interface group to 4 per minute:
+
+```none
+set firewall ipv4 name VyOS_MANAGEMENT rule 15 action 'accept'
+set firewall ipv4 name VyOS_MANAGEMENT rule 15 inbound-interface group 'LAN'
+
+set firewall ipv4 name VyOS_MANAGEMENT rule 20 action 'drop'
+set firewall ipv4 name VyOS_MANAGEMENT rule 20 recent count 4
+set firewall ipv4 name VyOS_MANAGEMENT rule 20 recent time minute
+set firewall ipv4 name VyOS_MANAGEMENT rule 20 state new
+set firewall ipv4 name VyOS_MANAGEMENT rule 20 inbound-interface group 'WAN'
+
+set firewall ipv4 name VyOS_MANAGEMENT rule 21 action 'accept'
+set firewall ipv4 name VyOS_MANAGEMENT rule 21 state new
+set firewall ipv4 name VyOS_MANAGEMENT rule 21 inbound-interface group 'WAN'
+```
+
+
+### Allow Access to Services
+
+Here we're allowing the router to respond to pings. Then, we can allow access to
+the DNS recursor we configured earlier, accepting traffic bound for port 53 from
+all hosts on the `NET-INSIDE-v4` network:
+
+```none
+set firewall ipv4 input filter rule 30 action 'accept'
+set firewall ipv4 input filter rule 30 icmp type-name 'echo-request'
+set firewall ipv4 input filter rule 30 protocol 'icmp'
+set firewall ipv4 input filter rule 30 state new
+
+set firewall ipv4 input filter rule 40 action 'accept'
+set firewall ipv4 input filter rule 40 destination port '53'
+set firewall ipv4 input filter rule 40 protocol 'tcp_udp'
+set firewall ipv4 input filter rule 40 source group network-group NET-INSIDE-v4
+```
+
+Finally, we can now configure access to the services running on this router,
+allowing all connections coming from localhost:
+
+```none
+set firewall ipv4 input filter rule 50 action 'accept'
+set firewall ipv4 input filter rule 50 source address 127.0.0.0/8
+```
+
+Commit changes, save the configuration, and exit configuration mode:
+
+```none
+vyos@vyos# commit
+vyos@vyos# save
+Saving configuration to '/config/config.boot'...
+Done
+vyos@vyos# exit
+vyos@vyos$
+```
+
+
+## Hardening
+
+Especially if you are allowing SSH remote access from the outside/WAN
+interface, there are a few additional configuration steps that should be taken.
+
+Replace the default `vyos` system user:
+
+```none
+set system login user myvyosuser authentication plaintext-password mysecurepassword
+```
+
+Set up {ref}`ssh_key_based_authentication`:
+
+```none
+set system login user myvyosuser authentication public-keys myusername@mydesktop type ssh-rsa
+set system login user myvyosuser authentication public-keys myusername@mydesktop key contents_of_id_rsa.pub
+```
+
+Finally, try and SSH into the VyOS install as your new user. Once you have
+confirmed that your new user can access your router without a password, delete
+the original `vyos` user and completely disable password authentication for
+{ref}`ssh`:
+
+```none
+delete system login user vyos
+set service ssh disable-password-authentication
+```
+
+As above, commit your changes, save the configuration, and exit
+configuration mode:
+
+```none
+vyos@vyos# commit
+vyos@vyos# save
+Saving configuration to '/config/config.boot'...
+Done
+vyos@vyos# exit
+vyos@vyos$
+```
+
+You now should have a simple yet secure and functioning router to experiment
+with further. Enjoy!
diff --git a/docs/troubleshooting/connectivity.md b/docs/troubleshooting/connectivity.md
new file mode 100644
index 00000000..a3c95d8c
--- /dev/null
+++ b/docs/troubleshooting/connectivity.md
@@ -0,0 +1,147 @@
+# Connectivity Tests
+
+## Basic Connectivity Tests
+
+Verifying connectivity can be done with the familiar ping and traceroute
+commands. The options for each are shown (the options for each command were
+displayed using the built-in help as described in the {ref}`cli`
+section and are omitted from the output here):
+
+```{opcmd} ping \<destination\>
+
+Send ICMP echo requests to destination host. There are multiple options to
+ping, including VRF support.
+
+:::{code-block} none
+vyos@vyos:~$ ping 10.1.1.1
+Possible completions:
+<Enter> Execute the current command
+adaptive Ping options
+allow-broadcast
+audible
+bypass-route
+count
+deadline
+do-not-fragment
+flood
+interface
+interval
+mark
+no-loopback
+numeric
+pattern
+quiet
+record-route
+size
+timestamp
+tos
+ttl
+verbose
+vrf
+:::
+```
+
+```{opcmd} traceroute \<destination\>
+
+Trace path to target.
+
+:::{code-block} none
+vyos@vyos:~$ traceroute
+Possible completions:
+<hostname> Track network path to specified node
+<x.x.x.x>
+<h:h:h:h:h:h:h:h>
+ipv4 Track network path to <hostname|IPv4 address>
+ipv6 Track network path to <hostname|IPv6 address>
+:::
+```
+
+
+## Advanced Connectivity Tests
+
+```{opcmd} monitor traceroute \<destination\>
+
+However, another helper is available which combines ping and traceroute
+into a single tool. An example of its output is shown:
+
+:::{code-block} none
+vyos@vyos:~$ mtr 10.62.212.12
+
+ My traceroute [v0.85]
+vyos (0.0.0.0)
+Keys: Help Display mode Restart statistics Order of fields quit
+ Packets Pings
+Host Loss% Snt Last Avg Best Wrst StDev
+1. 10.11.110.4 0.0% 34 0.5 0.5 0.4 0.8 0.1
+2. 10.62.255.184 0.0% 34 1.1 1.0 0.9 1.4 0.1
+3. 10.62.255.71 0.0% 34 1.4 1.4 1.3 2.0 0.1
+4. 10.62.212.12 0.0% 34 1.6 1.6 1.6 1.7 0.0
+:::
+
+:::{note}
+The output consumes the screen and will replace your command
+prompt.
+:::
+
+Several options are available for changing the display output. Press h to
+invoke the built in help system. To quit, just press q and you'll be
+returned to the VyOS command prompt.
+```
+
+
+## IPv6 Topology Discovery
+
+IPv6 uses different techniques to discover its Neighbors/topology.
+
+### Router Discovery
+
+```{opcmd} force ipv6-rd interface \<interface\> [address \<ipv6-address\>]
+
+Discover routers via eth0.
+
+Example:
+
+:::{code-block} none
+vyos@vyos:~$ force ipv6-rd interface eth0
+Soliciting ff02::2 (ff02::2) on eth0...
+
+Hop limit : 60 ( 0x3c)
+Stateful address conf. : No
+Stateful other conf. : No
+Mobile home agent : No
+Router preference : high
+Neighbor discovery proxy : No
+Router lifetime : 1800 (0x00000708) seconds
+Reachable time : unspecified (0x00000000)
+Retransmit time : unspecified (0x00000000)
+ Prefix : 240e:fe:8ca7:ea01::/64
+On-link : Yes
+Autonomous address conf.: Yes
+Valid time : 2592000 (0x00278d00) seconds
+Pref. time : 14400 (0x00003840) seconds
+ Prefix : fc00:470:f1cd:101::/64
+On-link : Yes
+Autonomous address conf.: Yes
+Valid time : 2592000 (0x00278d00) seconds
+Pref. time : 14400 (0x00003840) seconds
+ Recursive DNS server : fc00:470:f1cd::ff00
+DNS server lifetime : 600 (0x00000258) seconds
+ Source link-layer address: 00:98:2B:F8:3F:11
+ from fe80::298:2bff:fef8:3f11
+:::
+```
+
+
+### Neighbor Discovery
+
+```{opcmd} force ipv6-nd interface \<interface\> address \<ipv6-address\>
+
+Example:
+
+:::{code-block} none
+vyos@vyos:~$ force ipv6-nd interface eth0 address fc00:470:f1cd:101::1
+
+Soliciting fc00:470:f1cd:101::1 (fc00:470:f1cd:101::1) on eth0...
+Target link-layer address: 00:98:2B:F8:3F:11 from fc00:470:f1cd:101::1
+:::
+``` \ No newline at end of file
diff --git a/docs/troubleshooting/index.md b/docs/troubleshooting/index.md
new file mode 100644
index 00000000..31dbd87b
--- /dev/null
+++ b/docs/troubleshooting/index.md
@@ -0,0 +1,17 @@
+(troubleshooting)=
+
+# Troubleshooting
+
+Sometimes things break or don't work as expected. This section describes
+several troubleshooting tools provided by VyOS that can help when something
+goes wrong.
+
+```{toctree}
+:maxdepth: 1
+
+connectivity
+interfaces
+monitoring
+terminal
+system
+```
diff --git a/docs/troubleshooting/interfaces.md b/docs/troubleshooting/interfaces.md
new file mode 100644
index 00000000..553cbf90
--- /dev/null
+++ b/docs/troubleshooting/interfaces.md
@@ -0,0 +1,36 @@
+# Interface Names
+
+If you find the names of your interfaces have changed, this could be because
+your MAC addresses have changed.
+
+- For example, you have a VyOS VM with 4 Ethernet interfaces named
+ eth0, eth1, eth2 and eth3. Then, you migrate your VyOS VM to a different
+ host and find your interfaces now are eth4, eth5, eth6 and eth7.
+
+ One way to fix this issue **taking control of the MAC addresses** is:
+
+ Log into VyOS and run this command to display your interface settings.
+
+ ```none
+ show interfaces detail
+ ```
+
+ Take note of MAC addresses.
+
+ Now, in order to update a MAC address in the configuration, run this command
+ specifying the interface name and MAC address you want.
+
+ ```none
+ set interfaces ethernet eth0 hw-id 00:0c:29:da:a4:fe
+ ```
+
+ If it is a VM, go into the settings of the host and set the MAC address to
+ the settings found in the config.boot file. You can also set the MAC to
+ static if the host allows so.
+
+- Another example could be when cloning VyOS VMs in GNS3 and you get into the
+ same issue: interface names have changed.
+
+ And **a more generic way to fix it** is just deleting every MAC address at
+ the configuration file of the cloned machine. They will be correctly
+ regenerated automatically.
diff --git a/docs/troubleshooting/monitoring.md b/docs/troubleshooting/monitoring.md
new file mode 100644
index 00000000..778bb057
--- /dev/null
+++ b/docs/troubleshooting/monitoring.md
@@ -0,0 +1,152 @@
+# Monitoring
+
+VyOS features several monitoring tools.
+
+```none
+vyos@vyos:~$ monitor
+Possible completions:
+ bandwidth Monitor interface bandwidth in real time
+ bandwidth-test
+ Initiate or wait for bandwidth test
+ cluster Monitor clustering service
+ command Monitor an operational mode command (refreshes every 2 seconds)
+ conntrack-sync
+ Monitor conntrack-sync
+ content-inspection
+ Monitor Content-Inspection
+ dhcp Monitor Dynamic Host Control Protocol (DHCP)
+ dns Monitor a Domain Name Service (DNS) daemon
+ firewall Monitor Firewall
+ https Monitor the Secure Hypertext Transfer Protocol (HTTPS) service
+ lldp Monitor Link Layer Discovery Protocol (LLDP) daemon
+ log Monitor last lines of messages file
+ nat Monitor network address translation (NAT)
+ ndp Monitor the NDP information received by the router through the device
+ openvpn Monitor OpenVPN
+ protocol Monitor routing protocols
+ snmp Monitor Simple Network Management Protocol (SNMP) daemon
+ stop-all Stop all current background monitoring processes
+ traceroute Monitor the path to a destination in realtime
+ traffic Monitor traffic dumps
+ vpn Monitor VPN
+ vrrp Monitor Virtual Router Redundancy Protocol (VRRP)
+ webproxy Monitor Webproxy service
+```
+
+
+## Traffic Dumps
+
+To monitor interface traffic, issue the {code}`monitor traffic interface <name>`
+command, replacing `<name>` with your chosen interface.
+
+```none
+vyos@vyos:~$ monitor traffic interface eth0
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
+15:54:28.581601 IP 192.168.0.1 > vyos: ICMP echo request, id 1870, seq 3848, length 64
+15:54:28.581660 IP vyos > 192.168.0.1: ICMP echo reply, id 1870, seq 3848, length 64
+15:54:29.583399 IP 192.168.0.1 > vyos: ICMP echo request, id 1870, seq 3849, length 64
+15:54:29.583454 IP vyos > 192.168.0.1: ICMP echo reply, id 1870, seq 3849, length 64
+^C
+4 packets captured
+4 packets received by filter
+0 packets dropped by kernel
+vyos@vyos:~$
+```
+
+To quit monitoring, press {kbd}`Ctrl-C` and you'll be returned to the VyOS command
+prompt.
+
+Traffic can be filtered and saved.
+
+```none
+vyos@vyos:~$ monitor traffic interface eth0
+Possible completions:
+ <Enter> Execute the current command
+ filter Monitor traffic matching filter conditions
+ save Save traffic dump from an interface to a file
+```
+
+
+## Interface Bandwidth Usage
+
+To quickly view the bandwidth usage of an interface, use the `monitor bandwidth` command:
+
+```none
+vyos@vyos:~$ monitor bandwidth interface eth0
+```
+
+This shows the following:
+
+```none
+ B (RX Bytes/second)
+198.00 .|....|.....................................................
+165.00 .|....|.....................................................
+132.00 ||..|.|.....................................................
+ 99.00 ||..|.|.....................................................
+ 66.00 |||||||.....................................................
+ 33.00 |||||||.....................................................
+ 1 5 10 15 20 25 30 35 40 45 50 55 60
+
+ KiB (TX Bytes/second)
+ 3.67 ......|.....................................................
+ 3.06 ......|.....................................................
+ 2.45 ......|.....................................................
+ 1.84 ......|.....................................................
+ 1.22 ......|.....................................................
+ 0.61 :::::||.....................................................
+ 1 5 10 15 20 25 30 35 40 45 50 55 60
+```
+
+
+## Interface Performance
+
+To take a look on the network bandwidth between two nodes, the `monitor
+bandwidth-test` command is used to run iperf.
+
+```none
+vyos@vyos:~$ monitor bandwidth-test
+Possible completions:
+ accept Wait for bandwidth test connections (port TCP/5001)
+ initiate Initiate a bandwidth test
+```
+
+- The `accept` command opens a listening iperf server on TCP Port 5001
+- The `initiate` command connects to that server to perform the test.
+
+```none
+vyos@vyos:~$ monitor bandwidth-test initiate
+Possible completions:
+ <hostname> Initiate a bandwidth test to specified host (port TCP/5001)
+ <x.x.x.x>
+ <h:h:h:h:h:h:h:h>
+```
+
+
+## Monitor command
+
+The `monitor command` command allows you to repeatedly run a command to view
+a continuously refreshed output. The command is run and output every 2 seconds,
+allowing you to monitor the output continuously without having to re-run the
+command. This can be useful to follow routing adjacency formation.
+
+```none
+vyos@router:~$ monitor command "show interfaces"
+```
+
+Will clear the screen and show you the output of `show interfaces` every
+2 seconds.
+
+```none
+Every 2.0s: /opt/vyatta/bin/vyatta-op-cmd-wrapper Sun Mar 26 02:49:46 2019
+
+Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
+Interface IP Address S/L Description
+--------- ---------- --- -----------
+eth0 192.168.1.1/24 u/u
+eth0.5 198.51.100.4/24 u/u WAN
+lo 127.0.0.1/8 u/u
+ ::1/128
+vti0 172.25.254.2/30 u/u
+vti1 172.25.254.9/30 u/u
+```
diff --git a/docs/troubleshooting/system.md b/docs/troubleshooting/system.md
new file mode 100644
index 00000000..e855e385
--- /dev/null
+++ b/docs/troubleshooting/system.md
@@ -0,0 +1,48 @@
+# System Information
+
+(boot-steps)=
+
+## Boot Steps
+
+VyOS 1.2 uses [Debian Jessie] as the base Linux operating system. Jessie was
+the first version of Debian that uses [systemd] as the default init system.
+
+These are the boot steps for VyOS 1.2
+
+1. The BIOS loads Grub (or isolinux for the Live CD)
+2. Grub then starts the Linux boot and loads the Linux Kernel `/boot/vmlinuz`
+3. Kernel Launches Systemd `/lib/systemd/systemd`
+4. Systemd loads the VyOS service file
+ `/lib/systemd/system/vyos-router.service`
+5. The service file launches the VyOS router init script
+ `/usr/libexec/vyos/init/vyos-router` - this is part of the [vyatta-cfg]
+ Debian package
+
+> 1. Starts [FRR] - successor to [GNU Zebra] and [Quagga]
+> 2. Initialises the boot configuration file - copies over
+> `config.boot.default` if there is no configuration
+> 3. Runs the configuration migration, if the configuration is for an older
+> version of VyOS
+> 4. Runs The pre-config script, if there is one
+> `/config/scripts/vyos-preconfig-bootup.script`
+> 5. If the config file was upgraded, runs any post upgrade scripts
+> `/config/scripts/post-upgrade.d`
+> 6. Starts `rl-system` and `firewall`
+> 7. Mounts the `/boot` partition
+> 8. The boot configuration file is then applied by `/opt/vyatta/sbin/vyatta-boot-config-loader/opt/vyatta/etc/config/config.boot`
+>
+> > 1. The config loader script writes log entries to
+> > `/var/log/vyatta-config-loader.log`
+>
+> 09. Runs `telinit q` to tell the init system to reload `/etc/inittab`
+> 10. Finally it runs the post-config script
+> `/config/scripts/vyos-postconfig-bootup.script`
+
+[debian jessie]: https://www.debian.org/releases/jessie/
+[frr]: https://frrouting.org/
+[gnu zebra]: https://www.gnu.org/software/zebra/
+[pcap filter expressions]: http://www.tcpdump.org/manpages/pcap-filter.7.html
+[quagga]: https://www.quagga.net/
+[systemd]: https://freedesktop.org/wiki/Software/systemd/
+[tshark]: https://www.wireshark.org/docs/man-pages/tshark.html
+[vyatta-cfg]: https://github.com/vyos/vyatta-cfg
diff --git a/docs/troubleshooting/terminal.md b/docs/troubleshooting/terminal.md
new file mode 100644
index 00000000..0d421972
--- /dev/null
+++ b/docs/troubleshooting/terminal.md
@@ -0,0 +1,39 @@
+# Terminal/Console
+
+Sometimes you need to clear counters or statistics to troubleshoot better.
+
+To do this use the `clear` command in Operational mode.
+
+to clear the console output
+
+```none
+vyos@vyos:~$ clear console
+```
+
+to clear interface counters
+
+```none
+# clear all interfaces
+vyos@vyos:~$ clear interface ethernet counters
+# clear specific interface
+vyos@vyos:~$ clear interface ethernet eth0 counters
+```
+
+The command follows the same logic as the `set` command in configuration mode.
+
+```none
+# clear all counters of an interface type
+vyos@vyos:~$ clear interface <interface_type> counters
+# clear counter of an interface in interface_type
+vyos@vyos:~$ clear interface <interface_type> <interface_name> counters
+```
+
+to clear counters on firewall rulesets or single rules
+
+```none
+vyos@vyos:~$ clear firewall name <ipv4 ruleset name> counters
+vyos@vyos:~$ clear firewall name <ipv4 ruleset name> rule <rule#> counters
+
+vyos@vyos:~$ clear firewall ipv6-name <ipv6 ruleset name> counters
+vyos@vyos:~$ clear firewall ipv6-name <ipv6 ruleset name> rule <rule#> counters
+```
diff --git a/docs/vpp/configuration/acl.md b/docs/vpp/configuration/acl.md
new file mode 100644
index 00000000..88296673
--- /dev/null
+++ b/docs/vpp/configuration/acl.md
@@ -0,0 +1,582 @@
+---
+lastproofread: '2025-09-04'
+---
+
+(vpp-config-acl)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP ACL Configuration
+
+VPP ACLs (Access Control Lists) provide a way to filter traffic passing through VPP interfaces. They offer a high-performance packet filtering solution that can be used as a fast firewall alternative.
+
+VyOS VPP ACL implementation supports two main types of access control lists:
+- **IP ACLs** - Layer 3 filtering based on IPv4/IPv6 addresses, ports, and protocols (can be applied to both input and output directions)
+- **MAC ACLs** - Layer 2 filtering based on MAC addresses and IP prefixes (can only be applied to input direction)
+
+## Structure and Components
+
+### Tags
+
+ACL tags are named rule sets that contain one or more access control entries (ACEs). Tags provide a way to group related rules and apply them consistently across different interfaces.
+- Tag names are user-defined text strings
+- Each tag can contain multiple numbered rules
+- Tags can be applied to interfaces in input or output direction
+- Multiple tags can be applied to a single interface
+
+### Interface Application
+
+ACL tags are applied to interfaces to control traffic flow:
+- **Input direction**: Filters traffic entering the interface
+- **Output direction**: Filters traffic leaving the interface
+
+:::{note}
+**Important Limitation**: MAC ACLs can only be applied to the input direction of interfaces. They cannot filter outbound traffic. Use IP ACLs if you need to filter traffic in both directions.
+:::
+
+### Rule Processing
+
+Rules within an ACL are processed in numerical order (lowest to highest). The first matching rule determines the action taken on the packet.
+
+Available actions:
+- `permit` - Allow the packet to continue
+- `deny` - Drop the packet
+- `permit-reflect` - Allow traffic and automatically permit return traffic
+
+## L3/IP ACLs
+
+IP ACLs provide Layer 3 filtering capabilities based on IPv4 and IPv6 addresses, port numbers, and protocols. They support both stateless and stateful (reflexive) filtering.
+
+### Creating IP ACL Tags
+
+IP ACL tags are created under the `vpp acl ip` configuration node:
+
+```none
+set vpp acl ip tag-name <tag-name>
+set vpp acl ip tag-name <tag-name> description '<description>'
+```
+
+Example:
+
+```none
+set vpp acl ip tag-name 'WEB-FILTER'
+set vpp acl ip tag-name 'WEB-FILTER' description 'Web server access control'
+```
+
+### Adding Rules to IP ACL Tags
+
+Rules are added to IP ACL tags with specific rule numbers:
+
+```none
+set vpp acl ip tag-name <tag-name> rule <rule-number>
+```
+
+#### Basic IP ACL Rule Configuration
+
+Each rule requires an action and matching criteria:
+
+```none
+set vpp acl ip tag-name <tag-name> rule <rule-number> action <permit|deny|permit-reflect>
+set vpp acl ip tag-name <tag-name> rule <rule-number> description '<description>'
+set vpp acl ip tag-name <tag-name> rule <rule-number> protocol <protocol>
+```
+
+**Actions:**
+- `permit` - Allow matching traffic
+- `deny` - Block matching traffic
+- `permit-reflect` - Allow outbound traffic and automatically permit return traffic
+
+**Protocols:**
+- `all` - Match all IP protocols (default)
+- Or specific protocol by name, e.g. `tcp`, `udp`, `icmp`
+
+#### Source and Destination Matching
+
+Configure source and destination parameters:
+
+```none
+# Source configuration
+set vpp acl ip tag-name <tag-name> rule <rule-number> source prefix <ip-prefix>
+set vpp acl ip tag-name <tag-name> rule <rule-number> source port <port-spec>
+
+# Destination configuration
+set vpp acl ip tag-name <tag-name> rule <rule-number> destination prefix <ip-prefix>
+set vpp acl ip tag-name <tag-name> rule <rule-number> destination port <port-spec>
+```
+
+**Prefix Specification:**
+- `<x.x.x.x/x>` - IPv4 prefix in CIDR notation
+- `<h:h:h:h:h:h:h:h/x>` - IPv6 prefix in CIDR notation
+
+**Port Specification:**
+- `<1-65535>` - Single port number
+- `<start>-<end>` - Port range (e.g., 1001-1005)
+
+#### TCP Flags Matching
+
+For TCP protocol rules, you can match specific TCP flags:
+
+```none
+# Match packets with specific flags set
+set vpp acl ip tag-name <tag-name> rule <rule-number> tcp-flags is-set <ack|cwr|ecn|fin|psh|rst|syn|urg>
+
+# Match packets without specific flags set
+set vpp acl ip tag-name <tag-name> rule <rule-number> tcp-flags is-not-set <ack|cwr|ecn|fin|psh|rst|syn|urg>
+```
+
+### IP ACL Configuration Examples
+#### Example 1: Basic Web Server ACL
+
+```none
+# Create ACL for web server access
+set vpp acl ip tag-name 'WEB-SERVER'
+set vpp acl ip tag-name 'WEB-SERVER' description 'Web server access control'
+
+# Allow HTTP traffic
+set vpp acl ip tag-name 'WEB-SERVER' rule 10 action permit
+set vpp acl ip tag-name 'WEB-SERVER' rule 10 protocol tcp
+set vpp acl ip tag-name 'WEB-SERVER' rule 10 destination port 80
+
+# Allow HTTPS traffic
+set vpp acl ip tag-name 'WEB-SERVER' rule 20 action permit
+set vpp acl ip tag-name 'WEB-SERVER' rule 20 protocol tcp
+set vpp acl ip tag-name 'WEB-SERVER' rule 20 destination port 443
+
+# Deny all other traffic
+set vpp acl ip tag-name 'WEB-SERVER' rule 999 action deny
+set vpp acl ip tag-name 'WEB-SERVER' rule 999 protocol all
+```
+
+#### Example 2: Network Segmentation ACL
+
+```none
+# Create ACL for network segmentation
+set vpp acl ip tag-name 'DMZ-FILTER'
+set vpp acl ip tag-name 'DMZ-FILTER' description 'DMZ to internal network filter'
+
+# Allow specific internal subnet access
+set vpp acl ip tag-name 'DMZ-FILTER' rule 10 action permit
+set vpp acl ip tag-name 'DMZ-FILTER' rule 10 destination prefix '192.168.100.0/24'
+set vpp acl ip tag-name 'DMZ-FILTER' rule 10 protocol tcp
+set vpp acl ip tag-name 'DMZ-FILTER' rule 10 destination port 443
+
+# Allow DNS queries
+set vpp acl ip tag-name 'DMZ-FILTER' rule 20 action permit
+set vpp acl ip tag-name 'DMZ-FILTER' rule 20 destination prefix '192.168.1.10/32'
+set vpp acl ip tag-name 'DMZ-FILTER' rule 20 protocol udp
+set vpp acl ip tag-name 'DMZ-FILTER' rule 20 destination port 53
+
+# Block everything else to internal networks
+set vpp acl ip tag-name 'DMZ-FILTER' rule 100 action deny
+set vpp acl ip tag-name 'DMZ-FILTER' rule 100 destination prefix '192.168.0.0/16'
+```
+
+#### Example 3: Reflexive ACL
+
+```none
+# Create reflexive ACL for outbound connections
+set vpp acl ip tag-name 'OUTBOUND-REFLECT'
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' description 'Allow outbound with return traffic'
+
+# Allow outbound HTTP/HTTPS with return traffic
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 10 action permit-reflect
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 10 protocol tcp
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 10 destination port 80
+
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 20 action permit-reflect
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 20 protocol tcp
+set vpp acl ip tag-name 'OUTBOUND-REFLECT' rule 20 destination port 443
+```
+
+### Applying IP ACL Tags to Interfaces
+
+IP ACL tags are applied to interfaces using the interface configuration:
+
+```none
+# Apply to input direction
+set vpp acl ip interface <interface> input acl-tag <number> tag-name <tag-name>
+
+# Apply to output direction
+set vpp acl ip interface <interface> output acl-tag <number> tag-name <tag-name>
+```
+
+Where:
+- `<interface>` - Interface name (e.g., eth0, eth1)
+- `<number>` - ACL rule number (0-4294967295) for ordering multiple ACL tags
+- `<tag-name>` - Name of the ACL tag to apply
+
+Multiple tags can be applied to the same interface and direction by using different ACL rule numbers.
+
+Example:
+
+```none
+# Apply web server ACL to input direction
+set vpp acl ip interface eth0 input acl-tag 10 tag-name 'WEB-SERVER'
+
+# Apply outbound reflexive ACL to output direction
+set vpp acl ip interface eth1 output acl-tag 10 tag-name 'OUTBOUND-REFLECT'
+
+# Apply multiple ACLs to the same interface and direction
+set vpp acl ip interface eth0 input acl-tag 20 tag-name 'FIREWALL'
+```
+
+## L2/MAC ACLs
+
+MAC ACLs provide Layer 2 filtering capabilities based on MAC addresses and IP prefixes. They are particularly useful for controlling access at the data link layer.
+
+:::{important}
+**Direction Limitation**: MAC ACLs can **only** be applied to the **input direction** of interfaces. They cannot filter outbound/output traffic. If you need bidirectional filtering, use IP ACLs instead.
+:::
+
+### Creating MAC ACL Tags
+
+MAC ACL tags are created under the `vpp acl mac` configuration node:
+
+```none
+set vpp acl mac tag-name <tag-name>
+set vpp acl mac tag-name <tag-name> description '<description>'
+```
+
+Example:
+
+```none
+set vpp acl mac tag-name 'MAC-FILTER'
+set vpp acl mac tag-name 'MAC-FILTER' description 'Layer 2 MAC address filtering'
+```
+
+### Adding Rules to MAC ACL Tags
+
+Rules are added to MAC ACL tags with specific rule numbers:
+
+```none
+set vpp acl mac tag-name <tag-name> rule <rule-number>
+```
+
+#### Basic MAC ACL Rule Configuration
+
+Each rule requires an action and matching criteria:
+
+```none
+set vpp acl mac tag-name <tag-name> rule <rule-number> action <permit|deny>
+set vpp acl mac tag-name <tag-name> rule <rule-number> description '<description>'
+```
+
+**Actions:**
+- `permit` - Allow matching traffic
+- `deny` - Block matching traffic
+
+Note: MAC ACLs do not support the `permit-reflect` action available in IP ACLs.
+
+#### MAC Address Matching
+
+Configure MAC address matching criteria:
+
+```none
+set vpp acl mac tag-name <tag-name> rule <rule-number> mac-address <mac-address>
+set vpp acl mac tag-name <tag-name> rule <rule-number> mac-mask <mac-mask>
+```
+
+**MAC Address Specification:**
+- `mac-address` - Source MAC address to match (format: xx:xx:xx:xx:xx:xx)
+- `mac-mask` - MAC address mask (default: ff:ff:ff:ff:ff:ff for exact match)
+
+The MAC mask allows for partial MAC address matching. For example:
+\- `ff:ff:ff:00:00:00` matches the first 3 octets (OUI)
+\- `ff:ff:ff:ff:ff:ff` matches the complete MAC address (default)
+
+#### IP Prefix Matching
+
+Configure IP prefix matching for the source:
+
+```none
+set vpp acl mac tag-name <tag-name> rule <rule-number> prefix <ip-prefix>
+```
+
+**Prefix Specification:**
+- Supports both IPv4 and IPv6 prefixes in CIDR notation
+- Examples: `192.168.1.0/24`, `10.0.0.0/8`, `2001:db8::/32`
+
+### MAC ACL Configuration Examples
+
+#### Example 1: Device Whitelist
+
+```none
+# Create MAC ACL for device whitelisting
+set vpp acl mac tag-name 'DEVICE-WHITELIST'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' description 'Allow only approved devices'
+
+# Allow specific workstation
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 10 action permit
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 10 mac-address '00:1b:21:12:34:56'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 10 prefix '192.168.1.100/32'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 10 description 'Admin workstation'
+
+# Allow specific server
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 20 action permit
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 20 mac-address '00:1b:21:78:90:ab'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 20 prefix '192.168.1.10/32'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 20 description 'Web server'
+
+# Deny everything else
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 999 action deny
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 999 mac-address '00:00:00:00:00:00'
+set vpp acl mac tag-name 'DEVICE-WHITELIST' rule 999 mac-mask '00:00:00:00:00:00'
+```
+
+#### Example 2: Vendor-Based Filtering
+
+```none
+# Create MAC ACL for vendor-based filtering
+set vpp acl mac tag-name 'VENDOR-FILTER'
+set vpp acl mac tag-name 'VENDOR-FILTER' description 'Filter by MAC vendor OUI'
+
+# Deny Realtek devices (OUI: 00:e0:4c)
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 10 action deny
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 10 mac-address '00:e0:4c:00:00:00'
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 10 mac-mask 'ff:ff:ff:00:00:00'
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 10 description 'Block Realtek devices'
+
+# Allow all other devices
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 100 action permit
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 100 mac-address '00:00:00:00:00:00'
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 100 mac-mask '00:00:00:00:00:00'
+set vpp acl mac tag-name 'VENDOR-FILTER' rule 100 description 'Allow all other vendors'
+```
+
+#### Example 3: Network Segmentation by MAC
+
+```none
+# Create MAC ACL for network segmentation
+set vpp acl mac tag-name 'SEGMENT-FILTER'
+set vpp acl mac tag-name 'SEGMENT-FILTER' description 'Segment networks by MAC/IP binding'
+
+# Allow management VLAN devices
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 10 action permit
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 10 mac-address '02:01:00:00:00:00'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 10 mac-mask 'ff:ff:00:00:00:00'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 10 prefix '10.1.0.0/16'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 10 description 'Management VLAN'
+
+# Allow user VLAN devices
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 20 action permit
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 20 mac-address '02:02:00:00:00:00'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 20 mac-mask 'ff:ff:00:00:00:00'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 20 prefix '10.2.0.0/16'
+set vpp acl mac tag-name 'SEGMENT-FILTER' rule 20 description 'User VLAN'
+```
+
+### Applying MAC ACL Tags to Interfaces
+
+MAC ACL tags can only be applied to the input direction of interfaces:
+
+```none
+set vpp acl mac interface <interface> tag-name <tag-name>
+```
+:::{note}
+**Syntax Difference**: Unlike IP ACLs, MAC ACL interface application does not use the `acl-tag <number>` structure since only single MAC ACLs can be applied.
+:::
+
+:::{warning}
+Unlike IP ACLs, MAC ACLs do **not** support output direction filtering. There is no `output` option available for MAC ACL interface application.
+:::
+
+Example:
+
+```none
+# Apply MAC filtering to interface input
+set vpp acl mac interface eth0 tag-name 'MAC-FILTER'
+set vpp acl mac interface eth1 tag-name 'DEVICE-WHITELIST'
+```
+
+## Configuration Best Practices
+
+### Rule Ordering
+
+- **Number rules strategically**: Use gaps between rule numbers (10, 20, 30) to allow for future insertions
+- **Place specific rules first**: More specific matches should have lower rule numbers
+- **End with catch-all**: Always include a final rule that matches all traffic with explicit action
+- **Document rules**: Use descriptions for complex rules to aid troubleshooting
+
+### Performance Considerations
+
+- **Minimize rule count**: Fewer rules generally mean better performance
+- **Use appropriate ACL type**: Use MAC ACLs for Layer 2/3 filtering, IP ACLs for Layer 3/4 filtering
+- **Consider direction limitations**: Remember that MAC ACLs only work on input traffic; use IP ACLs for filtering in both directions
+- **Combine related rules**: Group similar filtering requirements into single ACL tags
+- **Apply strategically**: Apply ACLs at ingress points where possible to minimize processing
+
+## Troubleshooting
+
+### Common Issues
+
+- **ACL not taking effect:**
+ - Verify ACL is applied to correct interface and direction
+ - Check rule numbering and order
+ - Ensure interface is properly configured in VPP
+- **Performance degradation:**
+ - Review ACL complexity and rule count
+ - Consider consolidating rules
+ - Check for unnecessary broad matches
+- **Traffic blocked unexpectedly:**
+ - Review rule order (first match wins)
+ - Check for overly restrictive rules
+ - Verify protocol and port specifications
+
+### Verification Commands
+
+Use these commands to verify ACL configuration and operation:
+
+```none
+# Show VPP ACL configuration
+show configuration commands | grep "vpp acl"
+
+# Show VPP interface configuration
+show configuration commands | grep "vpp acl.*interface"
+
+# View commit history for ACL changes
+show configuration commit-revisions | grep -A5 -B5 "vpp acl"
+```
+
+## Operational Commands
+
+VyOS provides several operational commands to monitor and troubleshoot VPP ACL configurations and their status.
+
+### Viewing All ACLs
+
+Display all configured ACLs (both IP and MAC):
+
+```{opcmd} show vpp acl
+```
+
+This command shows a summary of all configured ACL tags with their rules, displaying both IP ACLs and MAC ACLs in a tabular format.
+Example output:
+
+```none
+---------------------------------
+IP ACL "tag-name WEB-SERVER" acl_index 0
+
+Rule Action Src prefix Src port Dst prefix Dst port Proto TCP flags set TCP flags not set
+------ -------- ------------ ---------- ------------ ---------- ------- --------------- -------------------
+ 10 permit 0.0.0.0/0 0-65535 0.0.0.0/0 80 6
+ 20 permit 0.0.0.0/0 0-65535 0.0.0.0/0 443 6
+ 999 deny 0.0.0.0/0 0-65535 0.0.0.0/0 0-65535 0
+
+---------------------------------
+MACIP ACL "tag-name VENDOR-FILTER" acl_index 0
+
+Rule Action IP prefix MAC address MAC mask
+------ -------- ----------- ----------------- -----------------
+ 10 deny 0.0.0.0/0 00:e0:4c:00:00:00 ff:ff:ff:00:00:00
+ 100 permit 0.0.0.0/0 00:00:00:00:00:00 00:00:00:00:00:00
+```
+
+### IP ACL Commands
+
+View all IP ACLs:
+
+```{opcmd} show vpp acl ip
+```
+
+View IP ACL interface assignments:
+
+```{opcmd} show vpp acl ip interface
+```
+
+Example output:
+
+```none
+Interface Input ACLs Output ACLs
+----------- ------------ -------------
+eth1 WEB-SERVER
+```
+
+View specific IP ACL by tag name:
+
+```{opcmd} show vpp acl ip tag-name \<tag-name\>
+```
+
+Example:
+
+```none
+vyos@vyos:~$ show vpp acl ip tag-name WEB-SERVER
+
+---------------------------------
+IP ACL "tag-name WEB-SERVER" acl_index 0
+
+ Rule Action Src prefix Src port Dst prefix Dst port Proto TCP flags set TCP flags not set
+------ -------- ------------ ---------- ------------ ---------- ------- --------------- -------------------
+ 10 permit 0.0.0.0/0 0-65535 0.0.0.0/0 80 6
+ 20 permit 0.0.0.0/0 0-65535 0.0.0.0/0 443 6
+ 999 deny 0.0.0.0/0 0-65535 0.0.0.0/0 0-65535 0
+```
+
+### MAC ACL Commands
+
+View all MAC ACLs:
+
+```{opcmd} show vpp acl mac
+```
+
+View MAC ACL interface assignments:
+
+```{opcmd} show vpp acl mac interface
+```
+
+Example output:
+
+```none
+Interface ACL
+----------- -----
+eth0 VENDOR-FILTER
+```
+
+View specific MAC ACL by tag name:
+
+```{opcmd} show vpp acl mac tag-name \<tag-name\>
+```
+
+Example:
+
+```none
+vyos@vyos:~$ show vpp acl mac tag-name VENDOR-FILTER
+
+---------------------------------
+MACIP ACL "tag-name VENDOR-FILTER" acl_index 0
+
+ Rule Action IP prefix MAC address MAC mask
+------ -------- ----------- ----------------- -----------------
+ 10 deny 0.0.0.0/0 00:e0:4c:00:00:00 ff:ff:ff:00:00:00
+ 100 permit 0.0.0.0/0 00:00:00:00:00:00 00:00:00:00:00:00
+```
+
+
+### Understanding Command Output
+
+**IP ACL Output Fields:**
+
+- **Rule**: Rule number within the ACL
+- **Action**: permit, deny, or permit-reflect
+- **Src prefix**: Source IP prefix (0.0.0.0/0 = any source)
+- **Src port**: Source port range (0-65535 = any port)
+- **Dst prefix**: Destination IP prefix
+- **Dst port**: Destination port or port range
+- **Proto**: IP protocol number (6=TCP, 17=UDP, 1=ICMP, 0=any)
+- **TCP flags set**: Required TCP flags (for TCP protocol)
+- **TCP flags not set**: Prohibited TCP flags (for TCP protocol)
+
+**MAC ACL Output Fields:**
+
+- **Rule**: Rule number within the ACL
+- **Action**: permit or deny
+- **IP prefix**: Source IP prefix constraint
+- **MAC address**: Source MAC address to match
+- **MAC mask**: MAC address mask for partial matching
+
+**Interface Assignment Output:**
+
+- Shows which interfaces have ACLs applied
+- **Input ACLs**: ACL tags applied to incoming traffic
+- **Output ACLs**: ACL tags applied to outgoing traffic (IP ACLs only)
+- **ACL**: MAC ACL tag applied to interface (input only)
diff --git a/docs/vpp/configuration/dataplane/buffers.md b/docs/vpp/configuration/dataplane/buffers.md
new file mode 100644
index 00000000..c9e38a54
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/buffers.md
@@ -0,0 +1,102 @@
+---
+lastproofread: '2026-02-23'
+---
+
+(vpp-config-dataplane-buffers)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane Buffers Configuration
+
+Buffers are essential for handling network packets efficiently. Proper
+configuration enhances performance and reliability, and is mandatory for
+VPP to work. Buffers temporarily store packets during processing. Therefore,
+their configuration must be in sync with NIC configuration, CPU threads, and
+overall system resources.
+
+:::{important}
+VPP buffers are allocated from the physical memory pool (`physmem`). The
+total amount of memory available for buffer allocation is controlled by the
+`physmem-max-size` setting, while the buffer configuration parameters
+below control how that memory is used for buffer allocation.
+
+See {ref}`VPP Physical Memory Configuration <vpp-config-dataplane-physmem>`
+for details on configuring `physmem`.
+:::
+
+## Buffer Configuration Parameters
+
+The following parameters can be configured for VPP buffers:
+
+### buffers-per-numa
+
+Number of buffers allocated per NUMA node. This setting optimizes
+memory access patterns for multi-CPU systems.
+
+Typically, you need to tune this value if:
+- The system has many interfaces
+- NICs have many queues
+- NICs have large descriptor sizes
+
+Set this value carefully to balance memory usage and performance.
+
+```{cfgcmd} set vpp settings resource-allocation buffers buffers-per-numa \<value\>
+```
+
+The common approach for the calculation is to use the formula:
+
+```none
+buffers-per-numa = (num-rx-queues * num-rx-desc) + (num-tx-queues * num-tx-desc)
+```
+
+Calculate this formula for each NIC and sum the results. Multiply the
+total by 2.5 to get the minimum recommended value for
+`buffers-per-numa`.
+
+Avoid setting this value too low to prevent packet drops.
+
+### data-size
+
+This value sets how much payload data can be stored in a single buffer
+allocated by VPP. Larger values reduce buffer chains for large packets,
+while smaller values conserve memory for environments handling mostly
+small packets.
+
+```{cfgcmd} set vpp settings resource-allocation buffers data-size \<value\>
+```
+
+Optimal size depends on the typical packet size in your network. If
+unsure, use the largest MTU in your network plus overhead (for example,
+128 bytes).
+
+### page-size
+
+A memory pages type used for buffer allocation. Common values are 4K, 2M, or 1G.
+
+Use page sizes configured in your system settings.
+
+```{cfgcmd} set vpp settings resource-allocation buffers page-size \<value\>
+```
+
+
+## Potential Issues and Troubleshooting
+
+Improper buffer configuration can lead to issues such as:
+
+- Increased latency and packet loss
+- Inefficient CPU utilization
+- Interface initialization failures
+
+Indicators of such issues are:
+
+- Errors during interfaces initialization in VPP logs
+- Packet drops observed in VPP statistics
+
+To troubleshoot buffer-related issues, consider the following steps:
+
+- Review VPP logs for errors related to buffer allocation. Look for
+ error `-5` messages.
+- Tune available buffers by adjusting the `buffers-per-numa` and
+ `data-size` parameters.
diff --git a/docs/vpp/configuration/dataplane/cpu.md b/docs/vpp/configuration/dataplane/cpu.md
new file mode 100644
index 00000000..d92f6587
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/cpu.md
@@ -0,0 +1,71 @@
+---
+lastproofread: '2026-02-23'
+---
+
+(vpp-config-dataplane-cpu)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane CPU Configuration
+
+VPP can utilize multiple CPU cores for better packet processing
+performance. Proper CPU configuration is essential for optimal
+throughput and low latency.
+
+VPP CPU assignment is handled automatically. You specify how many CPU
+cores VPP may use, and the system distributes them between the main
+thread and worker threads.
+
+:::{important}
+Review the system configuration settings page before changing CPU
+settings: {doc}`system`.
+:::
+
+If you don't configure CPU settings, VPP uses a single core for the
+main thread and doesn't create worker threads.
+
+## CPU Configuration Parameters
+
+### `cpu-cores`
+
+This parameter defines the total number of CPU cores allocated to VPP.
+
+```{cfgcmd} set vpp settings resource-allocation cpu-cores \<core-number\>
+```
+
+The system automatically assigns cores using the following rules:
+
+> - The first two CPU cores are always reserved for the operating system and
+> other services.
+> - The main VPP thread is assigned to the first available core after the
+> reserved ones.
+> - The remaining allocated cores are used for worker threads.
+
+For example:
+
+> - If cpu-cores is set to 1, VPP runs only a main thread.
+>
+> - If cpu-cores is set to 4, VPP uses:
+>
+> > - 1 core for the main thread
+> > - 3 cores for worker threads
+
+Choose a value based on available hardware resources and expected
+traffic load. Too few cores may limit performance, while too many can
+negatively impact other system services.
+
+## Potential Issues and Troubleshooting
+
+Improper CPU configuration can lead to issues such as:
+
+- VPP underperformance when not enough cores are assigned, or kernel
+ underperformance when too many cores are assigned to VPP.
+- Resource conflicts with other processes and services.
+
+Indicators of such issues are:
+
+- VPP or kernel forwarding performance is lower than expected
+- Degraded performance of system components or services, such as DNS,
+ DHCP, and dynamic routing
diff --git a/docs/vpp/configuration/dataplane/index.md b/docs/vpp/configuration/dataplane/index.md
new file mode 100644
index 00000000..c9ad7746
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/index.md
@@ -0,0 +1,36 @@
+---
+lastproofread: '2026-02-23'
+---
+
+(vpp-config-dataplane-index)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP Dataplane Core Configuration
+
+This section covers the core configuration options for the VPP dataplane in
+VyOS. It includes settings for memory management, CPU allocation, hugepages,
+and other essential parameters that influence the performance and behavior
+of the VPP dataplane.
+
+Please review the general system configuration, before starting to configure
+VPP. Without proper VyOS preconditions, VPP will not start or its efficiency
+will be significantly degraded.
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+system
+buffers
+cpu
+interface
+ipsec
+ipv6
+l2learn
+lcp
+logging
+memory
+unix
+```
diff --git a/docs/vpp/configuration/dataplane/interface.md b/docs/vpp/configuration/dataplane/interface.md
new file mode 100644
index 00000000..3f345c8d
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/interface.md
@@ -0,0 +1,104 @@
+---
+lastproofread: '2026-02-23'
+---
+
+(vpp-config-dataplane-interface)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane Interfaces Configuration
+
+Only Ethernet interfaces (physical or virtual) can be connected to the
+VPP dataplane. Interfaces configured here act as a bridge between VPP
+and the outside world, allowing VPP to send and receive network
+packets.
+
+## Interface Configuration Parameters
+
+Interfaces connected to the VPP dataplane use the DPDK driver by default,
+providing high performance and low latency.
+
+```{cfgcmd} set vpp settings interface \<interface-name\>
+```
+
+Some network interface cards (NICs) may not be compatible with the DPDK driver.
+
+### DPDK interface options
+
+This section shows how to configures DPDK-specific settings for an interface.
+
+```{cfgcmd} set vpp settings interface \<interface-name\> num-rx-queues \<value\>
+```
+
+Specifies the number of receive queues for the interface. More queues
+improve performance on multi-core systems by allowing parallel
+processing of incoming packets. Each queue is assigned to a separate
+CPU core.
+
+```{cfgcmd} set vpp settings interface \<interface-name\> num-tx-queues \<value\>
+```
+
+Specifies the number of transmit queues for the interface. Similar to
+receive queues, more transmit queues improve performance by enabling
+parallel processing of outgoing packets. By default, the VPP Dataplane
+has one TX queue per enabled CPU worker, or a single queue if no
+workers are configured.
+
+:::{seealso}
+{doc}`cpu`
+:::
+```{cfgcmd} set vpp settings interface \<interface-name\> num-rx-desc \<value\>
+```
+
+Defines the size of each receive queue. Larger queue sizes accommodate
+bursts of incoming traffic and reduce the likelihood of packet drops
+during high traffic periods.
+
+```{cfgcmd} set vpp settings interface \<interface-name\> num-tx-desc \<value\>
+```
+
+Defines the size of each transmit queue. Larger sizes help manage
+bursts of outgoing traffic more effectively.
+
+## Global Interface Parameters
+
+(vpp-config-dataplane-interface-rx-mode)=
+
+### interface-rx-mode
+
+The `interface-rx-mode` parameter defines how VPP handles incoming
+packets on interfaces. There are several modes available, each with its
+own advantages and use cases:
+- `interrupt`: In this mode, VPP relies on hardware interrupts to
+ notify it of incoming packets. This mode suits low to moderate
+ traffic loads and reduces CPU usage during idle periods. It is not
+ recommended for low-latency processing. Some NICs may not support
+ this mode.
+- `polling`: In polling mode, VPP continuously checks the interface
+ for incoming packets. This mode is ideal for high-throughput
+ scenarios where low latency is critical, as it minimizes packet
+ waiting time. However, it can increase CPU usage, especially during
+ low traffic periods, as the polling process is always active.
+- `adaptive`: Adaptive mode combines the benefits of interrupt and
+ polling modes. VPP starts in interrupt mode and switches to polling
+ mode when traffic load increases.
+
+```{cfgcmd} set vpp settings interface-rx-mode \<mode\>
+```
+
+Choose an rx-mode based on expected traffic patterns and performance
+requirements of your network.
+
+## Potential Issues and Troubleshooting
+
+Improper interface configuration can lead to issues such as:
+
+- Failure to initialize the interface
+- Poor performance due to suboptimal driver selection or settings
+
+Indicators of such issues are:
+
+- Failed commits after adding or modifying an interface settings
+- Low throughput or high latency on the interface
diff --git a/docs/vpp/configuration/dataplane/ipsec.md b/docs/vpp/configuration/dataplane/ipsec.md
new file mode 100644
index 00000000..0a66221f
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/ipsec.md
@@ -0,0 +1,74 @@
+---
+lastproofread: '2026-02-23'
+---
+
+(vpp-config-dataplane-ipsec)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP IPsec Configuration
+
+VPP supports IPsec (Internet Protocol Security) offloading from the
+kernel, which speeds up cryptographic operations by leveraging VPP's
+high-performance packet processing capabilities.
+
+IPsec does not require any specific configuration on VPP side. If both
+sources and destinations of the IPsec traffic are reachable via VPP
+interfaces, VPP will automatically offload the IPsec processing from
+the kernel. IPsec tunnels are configured in the VPN configuration
+section, see {ref}`ipsec_general`.
+
+## IPsec Configuration Parameters
+
+### enable IPsec acceleration
+
+When VPP is used for offloading IPsec, it creates a virtual interface to
+connect to peers. The interface type is always 'ipsec', which is used for
+IPsec tunnels.
+
+```{cfgcmd} set vpp settings ipsec-acceleration
+```
+
+Enabling this option allows VPP to handle IPsec traffic more efficiently by
+offloading processing from the kernel.
+
+### netlink
+
+VPP uses netlink to receive IPsec event messages from the kernel. Proper
+settings of the following parameters are crucial for ensuring that VPP can
+process all such messages:
+
+```{cfgcmd} set vpp settings lcp netlink batch-delay-ms \<milliseconds\>
+```
+
+This parameter specifies the delay in milliseconds between processing
+batch netlink messages.
+
+```{cfgcmd} set vpp settings lcp netlink batch-size \<number\>
+```
+
+This parameter specifies the maximum number of netlink messages to
+process in a single batch.
+
+```{cfgcmd} set vpp settings lcp netlink rx-buffer-size \<number\>
+```
+
+This parameter specifies the size of the receive buffer for netlink
+socket. If you expect to offload many IPsec tunnels or get frequent and
+intensive rekeying, you may need to increase this value.
+
+:::{note}
+IPsec uses the same netlink parameters as LCP, so tuning them
+affects both LCP and IPsec processing.
+:::
+
+## Potential Issues and Troubleshooting
+
+Improper IPsec configuration can lead to various issues, including:
+
+- Failure to offload IPsec tunnels to VPP
+- Lost IPsec event messages due to insufficient netlink buffer size or
+ batch settings
+- IPsec states or SAs are not synchronized between kernel and VPP
diff --git a/docs/vpp/configuration/dataplane/ipv6.md b/docs/vpp/configuration/dataplane/ipv6.md
new file mode 100644
index 00000000..5f2ba3c5
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/ipv6.md
@@ -0,0 +1,46 @@
+---
+lastproofread: '2026-02-26'
+---
+
+(vpp-config-dataplane-ipv6)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP IPv6 Configuration
+
+VPP lets you configure resources allocated for IPv6 traffic processing
+independently from IPv4. This helps ensure that in networks without IPv6
+traffic, resources are not wasted. If IPv6 traffic is present, especially
+with large routing tables, you must allocate additional resources for IPv6
+processing to keep the dataplane stable.
+
+You can configure two main resources for IPv6 traffic processing:
+
+```{cfgcmd} set vpp settings resource-allocation ipv6 hash-buckets \<value\>
+```
+
+This parameter configures the number of hash buckets used for IPv6
+routing. If you have a large IPv6 routing table, you may need to increase
+this value to ensure efficient routing table performance and fast lookups.
+
+```{cfgcmd} set vpp settings resource-allocation ipv6 heap-size \<value\>
+```
+
+This parameter configures the heap size used for IPv6 forwarding. If you
+have a large IPv6 routing table, you may need to increase this value to
+ensure the routing table can accommodate all routes.
+
+## Potential Issues and Troubleshooting
+
+Improper IPv6 configuration can lead to various issues, including:
+
+- Inefficient, slow routing table lookups and traffic processing due to
+ insufficient hash buckets
+- Dataplane crashes or instability due to insufficient heap size when
+ handling a large number of IPv6 routes
+- Overall dataplane instability when handling IPv6 traffic
+
+Consider increasing configuration values if you experience issues with
+IPv6 traffic processing or if you have a large IPv6 routing table.
diff --git a/docs/vpp/configuration/dataplane/l2learn.md b/docs/vpp/configuration/dataplane/l2learn.md
new file mode 100644
index 00000000..2ce572a1
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/l2learn.md
@@ -0,0 +1,35 @@
+---
+lastproofread: '2026-02-26'
+---
+
+(vpp-config-dataplane-l2learn)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP L2LEARN Configuration
+
+When VPP dataplane connects to an L2 domain, it learns MAC addresses of
+devices in the domain. By default, the number of MAC addresses it can
+learn is limited.
+
+You can configure the limit using the following command:
+
+```{cfgcmd} set vpp settings resource-allocation mac-limit \<value\>
+```
+
+This parameter sets the maximum number of MAC addresses that can be
+learned in the L2 domain. If you have many devices, you may need to
+increase this limit to ensure VPP learns all MAC addresses.
+
+## Potential Issues and Troubleshooting
+
+Improper L2LEARN configuration can lead to various issues, including:
+
+- MAC address learning failure in the L2 domain if the limit is set too
+ low
+- Increased packet loss or latency for devices that aren't learned
+- Overall dataplane instability when handling L2 traffic
+
+Consider increasing the L2LEARN limit if you experience issues with MAC
+address learning or if you have many devices in the L2 domain.
diff --git a/docs/vpp/configuration/dataplane/lcp.md b/docs/vpp/configuration/dataplane/lcp.md
new file mode 100644
index 00000000..a68247e1
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/lcp.md
@@ -0,0 +1,46 @@
+---
+lastproofread: '2026-02-26'
+---
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP LCP Configuration
+
+Linux Control Plane (LCP) is a core component of VPP that lets you
+offload various control plane functions to the Linux kernel. LCP provides
+seamless integration with other VyOS components, letting you use system
+components like DHCP clients and routing daemons together with the VPP
+dataplane.
+
+VPP integration in VyOS relies heavily on LCP. Almost all control plane
+functions are handled by other daemons and services, while VPP handles
+high-performance packet forwarding exclusively. This approach also reduces
+VPP management processing load, improving overall dataplane performance and
+stability.
+
+VyOS integrates the kernel and VPP routing tables uniquely. By default,
+all routes, even those not directly connected to VPP interfaces, are
+imported from the kernel routing table to the VPP routing table, pointing
+to the kernel. This lets you forward traffic to any destination known to
+the kernel, even if VPP doesn't have a route to that destination.
+
+However, in some scenarios this behavior may not be desired. For example,
+if you have many routes in the kernel routing table not directly connected
+to VPP interfaces, and you don't need forwarding between those
+destinations and destinations reachable via VPP, you can disable this
+behavior using the following command:
+(vpp_config_dataplane_lcp_ignore_kernel_routes)=
+
+```{cfgcmd} set vpp settings ignore-kernel-routes
+```
+
+Pay attention that disabling this option leads to loss of connectivity to
+destinations if there are no direct routes in VPP routing table.
+
+## Potential Issues and Troubleshooting
+
+Disabling kernel route import can result in:
+
+- Loss of connectivity to certain destinations if kernel routes are ignored
+- Incomplete route synchronization between the kernel and VPP
diff --git a/docs/vpp/configuration/dataplane/logging.md b/docs/vpp/configuration/dataplane/logging.md
new file mode 100644
index 00000000..50e6277b
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/logging.md
@@ -0,0 +1,59 @@
+---
+lastproofread: '2026-02-27'
+---
+
+(vpp-config-dataplane-logging)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Logging Configuration
+
+VPP logging is an important part of monitoring and troubleshooting
+the performance and behavior of the VPP dataplane.
+
+VPP stores logs in two places:
+- `/var/log/vpp.log` — This file contains logs related to daemon
+ startup and logs of commands executed directly via VPP CLI. Pay
+ attention: VyOS does not use VPP CLI for configuration, so this log
+ will not contain any configuration changes made via VyOS CLI and will
+ not be informative in most cases.
+- System journal — contains logs related to the VPP daemon work,
+ including errors, warnings, and informational messages. It is the
+ main destination of logs generated by VPP.
+
+Logging detail level can be configured via the next command:
+
+```{cfgcmd} set vpp settings logging default-level \<level\>
+```
+
+Where `<level>` can be one of the following:
+
+- `emerg` (Emergency) - System is unusable.
+- `alert` (Alert) - Immediate action required.
+- `crit` (Critical) - Critical conditions.
+- `error` (Error) - Error conditions.
+- `warn` (Warning) - Warning conditions.
+- `notice` (Notice) - Normal but significant.
+- `info` (Informational) - Routine informational messages.
+- `debug` (Debug) - Detailed debugging messages.
+- `disabled` (Disabled) - Logging disabled.
+
+It is recommended to set logging level to `debug` only for
+troubleshooting purposes, as it can generate a large volume of log
+data. For regular operation, a level of `info` or `warn` is usually
+sufficient.
+
+## Troubleshooting
+
+Improper logging configuration can lead to various issues, including:
+
+- Excessive log file sizes if the logging level is set too high
+ (for example, `debug`).
+- Missing critical information if the logging level is set too low
+ (for example, `alert`).
+- Performance degradation due to excessive logging overhead
+
+Consider adjusting the logging level if you experience issues mentioned
+above.
diff --git a/docs/vpp/configuration/dataplane/memory.md b/docs/vpp/configuration/dataplane/memory.md
new file mode 100644
index 00000000..2465e3b3
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/memory.md
@@ -0,0 +1,142 @@
+---
+lastproofread: '2026-02-27'
+---
+
+(vpp_config_dataplane_memory)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP Memory Configuration
+
+VPP heavily relies on hugepages for its memory management. Hugepages
+are larger memory pages that reduce the overhead of page management and
+improve performance for applications that require large amounts of
+memory, such as VPP.
+
+VPP supports both 2MB and 1GB hugepages, but the default and most
+commonly used size is 2MB. The choice of hugepage size can impact
+performance, with larger pages generally providing better performance
+for memory-intensive applications.
+
+Before configuring memory in VPP dataplane settings, you need to
+ensure that hugepages are enabled and properly configured on your
+system.
+
+:::{seealso}
+{ref}`Hugepages in VyOS Configuration for VPP <vpp-config-hugepages>`
+:::
+
+To configure memory settings for VPP, you can use the following
+commands in the VPP CLI:
+
+VPP uses a main heap as a central memory pool for FIB data structures
+entry allocations.
+
+Efficient memory management is crucial for VPP's performance, and the
+main heap plays a significant role in this.
+
+It can be configured using the following command:
+
+```{cfgcmd} set vpp settings resource-allocation memory main-heap-page-size \<size\>
+```
+
+Sets the main heap page size for VPP.
+
+```{cfgcmd} set vpp settings resource-allocation memory main-heap-size \<size\>
+```
+
+Sets the main heap size for VPP.
+(vpp-config-dataplane-physmem)=
+
+## Physical Memory Configuration
+
+VPP uses physical memory for packet buffers and interface operations.
+The `physmem` setting controls how much memory VPP can allocate for
+these operations.
+
+```{cfgcmd} set vpp settings resource-allocation memory physmem-max-size \<size\>
+```
+
+Sets the maximum amount of physical memory VPP can use for packet
+processing and interface buffers.
+
+**Default**: 16GB (usually sufficient for most deployments)
+
+You may need to modify the value for high-throughput environments with
+many interfaces, large packet buffers, very high packet rates, or
+memory-constrained systems where you need to limit VPP's memory usage.
+
+**Physmem independent of main heap size** — physmem is for packet
+buffers, main heap is for routing tables.
+
+:::{seealso}
+- {ref}`Hugepages in VyOS Configuration for VPP <vpp-config-hugepages>`
+- {ref}`VPP Buffer Configuration <vpp-config-dataplane-buffers>` - for
+ controlling buffer allocation within physmem
+:::
+
+### Common configurations
+
+```none
+# Reduce for memory-constrained systems
+set vpp settings physmem max-size 4G
+
+# Increase for high-throughput environments
+set vpp settings physmem max-size 32G
+```
+
+## Stats Memory Configuration
+
+VPP uses a dedicated statistics memory segment to store runtime
+counters and telemetry data. This segment is used by the VPP CLI and
+monitoring tools to access performance and status information.
+
+The statistics segment is allocated from hugepage memory and can be
+configured independently from the main heap and physmem settings.
+
+You can configure statistics memory using the following commands:
+
+```{cfgcmd} set vpp settings resource-allocation memory stats page-size \<size\>
+```
+
+Sets the hugepage page size used for the statistics memory segment.
+
+```{cfgcmd} set vpp settings resource-allocation memory stats size \<size\>
+```
+
+Sets the total size of the statistics memory segment.
+
+Increasing this value may be required in large deployments with many
+interfaces or enabled features that generate a high number of counters.
+
+Statistics memory is used only for telemetry and monitoring. It does
+not affect packet buffer allocation or routing table memory.
+
+## Troubleshooting
+
+Improper configuration of main heap size can lead to performance
+degradation or even system instability. If VPP runs out of memory in the
+main heap, it may crash or exhibit erratic behavior. Symptoms you may
+observe include:
+
+- Increased latency or packet loss
+- Crashes or restarts of VPP processes, especially during routing table
+ population (for example, BGP session establishment)
+- Error messages related to memory allocation failures
+
+You need to tune the main heap size based on expected FIB entries. Pay
+attention: the same amount of routes with a single next-hop and with
+multiple next-hops will consume different amounts of memory.
+
+For physmem, insufficient allocation can lead to packet drops, interface
+initialization failures, and overall degraded performance. Symptoms
+include:
+
+- Packet drops or failures to allocate buffers
+- Increased latency or jitter in packet processing
+- Crashes or restarts of VPP processes under heavy load
+
+You need to tune the physmem settings based on expected traffic patterns
+and interface usage. Monitor memory usage closely and adjust the
+configuration as needed to ensure optimal performance.
diff --git a/docs/vpp/configuration/dataplane/system.md b/docs/vpp/configuration/dataplane/system.md
new file mode 100644
index 00000000..51ee8f54
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/system.md
@@ -0,0 +1,212 @@
+---
+lastproofread: '2026-02-27'
+---
+
+(vpp_config_system)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VyOS Configuration for VPP
+
+(vpp-config-hugepages)=
+
+## Hugepages
+
+VPP uses hugepages for efficient memory management. Hugepages are larger
+memory pages that reduce the overhead of page management and improve
+performance for applications that require large amounts of memory.
+
+Hugepages can be configured in VyOS using the following commands:
+
+:::{warning}
+Changes to hugepage settings require a system reboot to take effect.
+
+Hugepages must be enabled before VPP configuration is applied.
+:::
+
+To enable hugepages:
+
+```{cfgcmd} set system option kernel memory hugepage-size \<size\> hugepage-count '\<count\>'
+```
+
+Enables hugepages with the specified size and count. The size can be either
+2MB or 1GB, and the count specifies the number of hugepages to allocate.
+
+If your system has multiple NUMA nodes, the total amount of hugepages will be
+divided equally among them.
+
+## Resources Limits
+
+:::{note}
+By default, system will calculate and set the recommended values for
+resource limits. Avoid tuning these values if you are not sure what you
+are doing.
+:::
+
+During operations VPP utilizes a significant amount of system resources,
+especially memory. There are two main settings that may need to be
+adjusted to ensure VPP runs smoothly:
+
+Maximum number of memory map areas a process may have:
+
+```{cfgcmd} set system option resource-limits max-map-count \<value\>
+```
+
+Maximum shared memory segment size:
+
+```{cfgcmd} set system option resource-limits shmmax \<value\>
+```
+
+Both settings are automatically calculated based on configured hugepages.
+
+## Kernel Tuning
+
+VPP performance greatly benefits from proper kernel tuning, especially
+CPU isolation and disabling unnecessary kernel features. These
+optimizations ensure dedicated CPU cores are available exclusively for
+VPP dataplane processing without interference from the kernel scheduler
+or other system processes.
+
+:::{warning}
+Kernel tuning changes require a system reboot to take effect.
+
+Improper CPU isolation can lead to system instability if essential
+system processes are starved of CPU resources.
+:::
+
+### CPU Isolation and Optimization
+
+CPU isolation is crucial for VPP performance as it dedicates specific
+CPU cores exclusively to VPP dataplane processing. The isolated cores are
+removed from the kernel scheduler and will not run regular system
+processes.
+
+**Disable NMI Watchdog**
+
+The NMI (Non-Maskable Interrupt) watchdog can interfere with VPP
+performance by generating interrupts on isolated cores and is not
+compatible with nohz-full mode:
+
+```{cfgcmd} set system option kernel cpu disable-nmi-watchdog
+
+Disables the NMI watchdog for detecting hard CPU lockups. This
+prevents unnecessary interrupts on VPP worker cores.
+```
+
+**CPU Core Isolation**
+
+```{cfgcmd} set system option kernel cpu isolate-cpus \<cpu-range\>
+
+Isolates specified CPUs from the kernel scheduler. Isolated cores will
+not run regular system processes and are dedicated to applications like
+VPP.
+
+The ``<cpu-range>`` can be:
+* Single core: ``2``
+* Range: ``2-5``
+* Mixed: ``1,3-5,7``
+
+:::{important}
+Always reserve at least 2 cores for the operating system to ensure
+system stability. For example, on a 4-core system, isolate cores
+2-3 for VPP and leave cores 0-1 for the OS.
+
+Assign the first isolated core as the VPP main core and the
+remaining isolated cores as VPP worker cores. Ensure that VPP CPU
+assignments match the isolated CPU range.
+:::
+```
+
+**Adaptive-Tick Mode**
+
+```{cfgcmd} set system option kernel cpu nohz-full \<cpu-range\>
+
+Enables adaptive-tick mode (NO_HZ_FULL) for specified CPUs. This
+causes the kernel to avoid sending scheduling-clock interrupts to CPUs
+that have only one runnable task, significantly reducing interrupt
+overhead for dedicated workloads like VPP.
+
+Use the same CPU range as configured for ``isolate-cpus``.
+```
+
+**RCU Callback Offloading**
+
+```{cfgcmd} set system option kernel cpu rcu-no-cbs \<cpu-range\>
+
+Offloads Read-Copy-Update (RCU) callback processing from specified
+CPUs. This ensures that RCU callbacks do not prevent the specified CPUs
+from entering dyntick-idle or adaptive-tick mode, which is essential
+for nohz-full functionality.
+
+Use the same CPU range as configured for ``isolate-cpus``.
+```
+
+### System Optimization
+
+Additional kernel optimizations can further improve VPP performance by
+disabling unnecessary features and reducing system overhead.
+
+**Disable High Precision Event Timer**
+
+```{cfgcmd} set system option kernel disable-hpet
+
+Disables the High Precision Event Timer (HPET). HPET can cause
+additional interrupts and overhead that may impact VPP performance.
+```
+
+**Disable Machine Check Exceptions**
+
+```{cfgcmd} set system option kernel disable-mce
+
+Disables Machine Check Exception (MCE) reporting and handling. While
+MCE provides hardware error detection, it can introduce latency in
+high-performance scenarios.
+```
+
+**Disable CPU Power Saving**
+
+```{cfgcmd} set system option kernel disable-power-saving
+
+Disables CPU power saving mechanisms (C-states). This keeps CPU cores
+at maximum performance levels, eliminating latency from power state
+transitions.
+```
+
+**Disable Soft Lockup Detection**
+
+```{cfgcmd} set system option kernel disable-softlockup
+
+Disables the soft lockup detector for kernel threads. This prevents
+false positives when VPP worker threads are busy processing packets.
+```
+
+**Disable CPU Mitigations**
+
+```{cfgcmd} set system option kernel disable-mitigations
+
+Disables all optional CPU mitigations for security vulnerabilities
+(for example, Spectre, Meltdown). This may improve performance on some
+platforms.
+```
+
+### Optimal Configuration Example
+
+For a system with 4 CPU cores (0-3) where cores 2-3 are dedicated to VPP:
+
+```none
+# Kernel CPU optimizations
+set system option kernel cpu disable-nmi-watchdog
+set system option kernel cpu isolate-cpus '2-3'
+set system option kernel cpu nohz-full '2-3'
+set system option kernel cpu rcu-no-cbs '2-3'
+
+# System optimizations
+set system option kernel disable-hpet
+set system option kernel disable-mce
+set system option kernel disable-power-saving
+set system option kernel disable-softlockup
+
+# VPP CPU assignment
+set vpp settings resource-allocation cpu-cores '2'
+```
diff --git a/docs/vpp/configuration/dataplane/unix.md b/docs/vpp/configuration/dataplane/unix.md
new file mode 100644
index 00000000..a1f6a1fd
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/unix.md
@@ -0,0 +1,57 @@
+---
+lastproofread: '2026-02-27'
+---
+
+(vpp-config-dataplane-unix)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Unix Dataplane Configuration
+
+The UNIX configuration section is used to control VPP's interaction
+with the underlying operating system, including operations scheduling.
+
+VPP relies on the polling mechanism to efficiently manage I/O operations
+and system events. By default VPP continuously polls for events, which
+leads to permanent 100% CPU usage by all cores assigned to VPP dataplane.
+This is optimal for performance, but may not be desirable in all
+environments, especially where power consumption is a concern or where VPP
+is running inside a hypervisor, especially if the VM has burstable
+thresholds and CPU usage limits.
+
+To mitigate this, VPP provides a configurable polling delay that allows
+reducing CPU usage by introducing a delay between polling cycles. This
+introduces a trade-off between CPU usage and latency, as longer delays
+can lead to increased latency in processing events.
+
+You can configure the polling delay using the following command in the
+VyOS CLI:
+
+```{cfgcmd} set vpp settings poll-sleep-usec \<delay\>
+```
+
+Sets the polling delay in microseconds. A value of 0 means no delay
+(default), while higher values introduce a delay between polling cycles.
+
+## Troubleshooting
+
+Setting the polling delay too high can lead to increased latency and
+reduced performance, as VPP may not respond to events as quickly.
+Conversely, setting it too low may result in high CPU usage, which can be
+problematic in resource-constrained environments.
+
+Symptoms of improper configuration may include:
+
+- Increased latency in packet processing
+- Higher CPU usage than expected
+- Packets lost due to buffer overruns
+
+If you do not need to reduce CPU usage, it is recommended to leave the
+polling delay at its default value of 0 for optimal performance.
+
+If you need to reduce CPU usage, you may also consider using `interrupt` or
+`adaptive` {ref}`DPDK driver modes <vpp-config-dataplane-interface-rx-mode>`,
+which can provide a balance between performance and resource utilization
+without affecting polling behavior.
diff --git a/docs/vpp/configuration/index.md b/docs/vpp/configuration/index.md
new file mode 100644
index 00000000..a4aa33d3
--- /dev/null
+++ b/docs/vpp/configuration/index.md
@@ -0,0 +1,47 @@
+---
+lastproofread: '2025-09-04'
+---
+
+(vpp-dconfig-index)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Configuration
+
+VPP settings consist of several main sections.
+
+Main Dataplane settings and internal VPP interfaces:
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+dataplane/index
+interfaces/index
+```
+
+Features that can be enabled on VPP Dataplane:
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+acl
+ipfix
+ipsec
+nat/index
+sflow
+```
+
+
+## VPP Initialization
+
+When VPP Dataplane is configured and the configuration is committed, VyOS will attempt to start VPP and initialize all interfaces assigned to it. During this process the following steps occur:
+
+1. VyOS checks that the system meets all requirements for VPP operation. If any requirement is not met, VPP will not start and an error message will be displayed.
+2. VPP is started and its initial configuration is applied.
+3. All interfaces assigned to VPP are initialized and brought up.
+4. A special virtual interfaces are reinstalled to the kernel with the same names as interfaces that were attached to VPP to maintain compatibility with the configuration.
+5. VyOS configuration initializes those virtual interfaces, so that features that exist only in kernel dataplane continue to operate.
diff --git a/docs/vpp/configuration/interfaces/bonding.md b/docs/vpp/configuration/interfaces/bonding.md
new file mode 100644
index 00000000..0e6ec837
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/bonding.md
@@ -0,0 +1,255 @@
+---
+lastproofread: '2026-03-09'
+---
+
+(vpp-config-interfaces-bonding)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Bonding Configuration
+
+VPP bonding interfaces provide link aggregation capabilities by combining
+multiple physical interfaces into a single logical interface for increased
+bandwidth and redundancy. VPP bonding offers high-performance packet
+processing compared to traditional Linux bonding.
+
+## Basic Configuration
+
+### Creating a Bonding Interface
+
+To create a VPP bonding interface:
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\>
+
+Create a bonding interface where ``<vppbondN>`` follows the naming
+convention ``vppbond0``, ``vppbond1``, and so on. A kernel pair interface is
+automatically created for the VPP bonding interface. This allows
+standard Linux networking tools and services to interact with the VPP
+bond.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0
+```
+
+### Interface Description
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> description \<description\>
+
+Set a descriptive name for the bonding interface.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0 description "Primary uplink bond"
+```
+
+### Administrative Control
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> disable
+
+Administratively disable the bonding interface. By default, interfaces
+are enabled.
+```
+
+## Member Interface Configuration
+### Adding Member Interfaces
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> member interface \<interface-name\>
+
+Add physical interfaces as members of the bond. You can add multiple
+interfaces to the same bond.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0 member interface eth0
+set interfaces vpp bonding vppbond0 member interface eth1
+```
+:::{note}
+Member interfaces must have the same speed and duplex for optimal
+performance. They must already be attached to VPP.
+:::
+
+## Bonding Modes
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> mode \<mode\>
+
+Configure the bonding mode. Available modes:
+* **802.3ad**: IEEE 802.3ad Dynamic Link Aggregation (LACP) - Default
+* **active-backup**: Fault tolerant, only one slave interface active
+* **broadcast**: Transmits everything on all slave interfaces
+* **round-robin**: Load balance by transmitting packets in sequential order
+* **xor-hash**: Distribute based on hash policy
+```
+
+**Examples:**
+
+```none
+# Use LACP (recommended for switch environments)
+set interfaces vpp bonding vppbond0 mode 802.3ad
+
+# Use active-backup for simple failover
+set interfaces vpp bonding vppbond0 mode active-backup
+```
+
+## Hash Policies
+
+For load balancing modes, configure how the system distributes traffic
+across member interfaces:
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> hash-policy \<policy\>
+
+Set the transmit hash policy:
+* **layer2**: Use MAC addresses to generate hash (default)
+* **layer2+3**: Combine MAC addresses and IP addresses
+* **layer3+4**: Combine IP addresses and port numbers
+```
+
+**Examples:**
+
+```none
+# Layer 2 hashing (default)
+set interfaces vpp bonding vppbond0 hash-policy layer2
+
+# Layer 3+4 for better distribution with multiple flows
+set interfaces vpp bonding vppbond0 hash-policy layer3+4
+```
+
+## MAC Address Configuration
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> mac \<mac-address\>
+
+Set a specific MAC address for the bonding interface.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0 mac 00:11:22:33:44:55
+```
+
+## IP Address Configuration
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> address \<ip-address/prefix\>
+
+Configure IPv4 or IPv6 addresses on the kernel interface. You can
+assign multiple addresses.
+```
+
+**Examples:**
+
+```none
+# IPv4 address
+set interfaces vpp bonding vppbond0 address 192.168.1.10/24
+
+# IPv6 address
+set interfaces vpp bonding vppbond0 address 2001:db8::10/64
+
+# Multiple addresses
+set interfaces vpp bonding vppbond0 address 192.168.1.10/24
+set interfaces vpp bonding vppbond0 address 10.0.0.10/8
+```
+
+## MTU Configuration
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> mtu \<size\>
+
+Set the Maximum Transmission Unit (MTU) for the kernel interface. The
+MTU must be compatible with the connected VPP interface.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0 mtu 9000
+```
+:::{note}
+The MTU setting must match or be smaller than the MTU supported by the
+associated VPP interface.
+:::
+
+## VLAN Configuration
+
+VPP kernel interfaces support VLAN (Virtual LAN) sub-interfaces for
+network segmentation.
+
+### Creating VLAN Sub-interfaces
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> vif \<vlan-id\>
+
+Create a VLAN sub-interface with the specified VLAN ID (0-4094).
+```
+
+**Example:**
+
+```none
+set interfaces vpp bonding vppbond0 vif 100
+```
+
+### VLAN Sub-interface Configuration
+
+VLAN sub-interfaces support the same configuration options as the parent
+interface:
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> vif \<vlan-id\> address \<ip-address/prefix\>
+```
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> vif \<vlan-id\> description \<description\>
+```
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> vif \<vlan-id\> disable
+```
+
+```{cfgcmd} set interfaces vpp bonding \<vppbondN\> vif \<vlan-id\> mtu \<size\>
+```
+
+**Examples:**
+
+```none
+# Configure VLAN 100
+set interfaces vpp bonding vppbond0 vif 100 address 192.168.100.1/24
+set interfaces vpp bonding vppbond0 vif 100 description "Management VLAN"
+set interfaces vpp bonding vppbond0 vif 100 mtu 1500
+
+# Configure VLAN 200
+set interfaces vpp bonding vppbond0 vif 200 address 192.168.200.1/24
+set interfaces vpp bonding vppbond0 vif 200 description "Guest VLAN"
+```
+
+## Complete Configuration Example
+
+Here's a complete example configuring a bonding interface with LACP:
+
+```none
+# Create bonding interface
+set interfaces vpp bonding vppbond0
+set interfaces vpp bonding vppbond0 description "Server uplink bond"
+
+# Configure bonding parameters
+set interfaces vpp bonding vppbond0 mode 802.3ad
+set interfaces vpp bonding vppbond0 hash-policy layer3+4
+
+# Add member interfaces
+set interfaces vpp bonding vppbond0 member interface eth0
+set interfaces vpp bonding vppbond0 member interface eth1
+
+# Configure IP on kernel interface
+set interfaces vpp bonding vppbond0 address 192.168.1.10/24
+```
+
+
+## Best Practices
+
+- Use **802.3ad mode** with LACP-capable switches for best performance
+ and standards compliance.
+- Configure **layer3+4 hash policy** for environments with multiple
+ traffic flows.
+- Ensure member interfaces have identical settings (speed, duplex,
+ MTU).
diff --git a/docs/vpp/configuration/interfaces/bridge.md b/docs/vpp/configuration/interfaces/bridge.md
new file mode 100644
index 00000000..dbe4758b
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/bridge.md
@@ -0,0 +1,194 @@
+---
+lastproofread: '2026-03-10'
+---
+
+(vpp-config-interfaces-bridge)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Bridge Configuration
+
+VPP bridge interfaces provide Layer 2 switching functionality, allowing
+multiple interfaces to be connected at the data link layer.
+
+VPP bridges operate as learning bridges, automatically discovering MAC
+addresses and building forwarding tables to efficiently switch traffic
+between member interfaces. This provides transparent connectivity between
+different network segments while maintaining the performance benefits of
+VPP's optimized data plane.
+
+**Supported Member Interface Types:**
+
+VPP bridges support various interface types as members:
+- Physical Ethernet interfaces (managed through linux-cp)
+- {doc}`bonding` - VPP bonding interfaces
+- {doc}`gre` - GRE tunnel interfaces
+- {doc}`loopback` - Loopback interfaces (required for BVI)
+- {doc}`vxlan` - VXLAN tunnel interfaces
+
+This flexibility allows you to create complex Layer 2 topologies
+combining different networking technologies.
+
+## Basic Configuration
+
+### Creating a Bridge Interface
+
+```{cfgcmd} set interfaces vpp bridge \<vppbrN\>
+
+Create a bridge interface where ``<vppbrN>`` follows the naming
+convention ``vppbr1``, ``vppbr2``, etc.
+```
+:::{note}
+Bridge domain `vppbr0` is reserved by VPP and cannot be
+configured through VyOS. Start with `vppbr1` for your bridge
+configurations.
+:::
+
+**Example:**
+
+```none
+set interfaces vpp bridge vppbr1
+```
+
+### Interface Description
+
+```{cfgcmd} set interfaces vpp bridge \<vppbrN\> description \<description\>
+
+Set a descriptive name for the bridge interface.
+```
+
+**Example:**
+
+```none
+set interfaces vpp bridge vppbr1 description "Main campus bridge"
+```
+
+## Member Interface Configuration
+### Adding Member Interfaces
+
+```{cfgcmd} set interfaces vpp bridge \<vppbrN\> member interface \<interface-name\>
+
+Add an interface as a member of the bridge.
+```
+
+**Examples:**
+
+```none
+# Add physical interfaces
+set interfaces vpp bridge vppbr1 member interface eth0
+set interfaces vpp bridge vppbr1 member interface eth1
+
+# Add other VPP interfaces
+set interfaces vpp bridge vppbr1 member interface vppbond0
+set interfaces vpp bridge vppbr1 member interface vppgre1
+```
+:::{important}
+Bridge members can include various interface types such as:
+- Physical Ethernet interfaces (eth0, eth1, etc.)
+- {doc}`bonding` - VPP bonding interfaces (vppbond0, vppbond1, etc.)
+- {doc}`gre` - GRE tunnel interfaces
+- {doc}`loopback` - Loopback interfaces
+- {doc}`vxlan` - VXLAN tunnel interfaces
+:::
+
+## Bridge Virtual Interface (BVI)
+
+A Bridge Virtual Interface (BVI) provides Layer 3 connectivity to a
+bridge domain, allowing the bridge to have an IP address and participate
+in routing.
+
+### Configuring BVI
+
+```{cfgcmd} set interfaces vpp bridge \<vppbrN\> member interface \<loopback-interface\> bvi
+
+Designate a loopback interface as the Bridge Virtual Interface for
+the bridge domain.
+```
+
+**Example:**
+
+```none
+# Create a loopback interface first
+set interfaces vpp loopback vpplo1
+
+# Add it to the bridge as BVI
+set interfaces vpp bridge vppbr1 member interface vpplo1 bvi
+```
+:::{important}
+**BVI Restrictions:**
+- Only loopback interfaces can be configured as BVI
+- Each bridge domain can have only one BVI interface
+:::
+
+## Configuration Examples
+
+### Basic Bridge Setup
+
+```none
+# Create bridge interface
+set interfaces vpp bridge vppbr1
+set interfaces vpp bridge vppbr1 description "Office network bridge"
+
+# Add member interfaces
+set interfaces vpp bridge vppbr1 member interface eth0
+set interfaces vpp bridge vppbr1 member interface eth1
+set interfaces vpp bridge vppbr1 member interface eth2
+```
+
+### Bridge with BVI
+
+```none
+# Create bridge and loopback for BVI
+set interfaces vpp bridge vppbr2
+set interfaces vpp bridge vppbr2 description "Server segment with gateway"
+set interfaces vpp loopback vpplo1
+
+# Configure bridge members
+set interfaces vpp bridge vppbr2 member interface eth3
+set interfaces vpp bridge vppbr2 member interface eth4
+set interfaces vpp bridge vppbr2 member interface vpplo1 bvi
+```
+
+### Multi-Technology Bridge
+
+```none
+# Create bridge combining different interface types
+set interfaces vpp bridge vppbr3
+set interfaces vpp bridge vppbr3 description "Hybrid network bridge"
+
+# Add various interface types
+set interfaces vpp bridge vppbr3 member interface vppbond1
+set interfaces vpp bridge vppbr3 member interface vppgre1
+set interfaces vpp bridge vppbr3 member interface vppvxlan1
+set interfaces vpp bridge vppbr3 member interface vpplo2 bvi
+```
+
+## Integration with Kernel Interfaces
+
+Bridge interfaces can be integrated with kernel interfaces for
+management and compatibility with standard Linux networking services.
+This is accomplished by binding a kernel interface to the Bridge
+Virtual Interface (BVI).
+
+**Example Integration:**
+
+```none
+# Create VPP bridge with member interfaces
+set interfaces vpp bridge vppbr1
+set interfaces vpp bridge vppbr1 member interface eth1
+set interfaces vpp bridge vppbr1 member interface eth2
+
+# Create loopback interface and configure as BVI
+set interfaces vpp loopback vpplo1
+set interfaces vpp bridge vppbr1 member interface vpplo1 bvi
+
+# Bind LCP kernel interface to the BVI loopback
+set interfaces vpp loopback vpplo1 address '192.0.2.1/24'
+```
+
+This configuration creates a kernel interface bound to the BVI,
+allowing standard Linux applications and routing daemons to interact
+with the VPP bridge. The kernel interface provides Layer 3 access to
+the bridge domain.
diff --git a/docs/vpp/configuration/interfaces/gre.md b/docs/vpp/configuration/interfaces/gre.md
new file mode 100644
index 00000000..30f49b15
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/gre.md
@@ -0,0 +1,168 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-gre)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP GRE Configuration
+
+VPP GRE interfaces provide Generic Routing Encapsulation tunneling with
+high-performance packet processing. GRE tunnels encapsulate various
+protocols within IP packets, enabling connectivity across Layer 3
+networks while maintaining the performance benefits of VPP's optimized
+data plane.
+
+## Basic Configuration
+
+### Creating a GRE Interface
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\>
+
+Create a GRE interface where ``<vppgreN>`` follows the naming convention
+``vppgre1``, ``vppgre2``, etc.
+```
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> remote \<address\>
+
+Set the tunnel remote endpoint address. Supports both IPv4 and IPv6
+addresses.
+```
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> source-address \<address\>
+
+Set the tunnel source address. Must match an address configured on
+the local system.
+```
+
+**Basic Example:**
+
+```none
+set interfaces vpp gre vppgre1
+set interfaces vpp gre vppgre1 remote 203.0.113.2
+set interfaces vpp gre vppgre1 source-address 192.168.1.1
+```
+
+## Interface Configuration
+### Description and Administrative Control
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> description \<description\>
+
+Set a descriptive name for the GRE interface.
+```
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> disable
+
+Administratively disable the GRE interface.
+```
+
+### Tunnel Type
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> tunnel-type \<type\>
+
+Set the GRE tunnel encapsulation type:
+* ``l3`` - Generic Routing Encapsulation for network layer traffic (default).
+* ``teb`` - Transparent Ethernet Bridge for Layer 2 frame transport.
+* ``erspan`` - Encapsulated Remote Switched Port Analyzer for traffic
+mirroring.
+```
+
+### Kernel Interface Integration
+
+LCP kernel pair interface bound to the VPP GRE interface is created
+automatically. This allows standard Linux networking tools and
+services to interact with the VPP GRE.
+
+## IP Address Configuration
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> address \<ip-address/prefix\>
+
+Configure IPv4 or IPv6 addresses on the kernel interface. Multiple
+addresses can be assigned.
+```
+
+**Examples:**
+
+```none
+# IPv4 address
+set interfaces vpp gre vppgre0 address 192.168.1.10/24
+
+# IPv6 address
+set interfaces vpp gre vppgre0 address 2001:db8::10/64
+```
+
+## MTU Configuration
+
+```{cfgcmd} set interfaces vpp gre \<vppgreN\> mtu \<size\>
+
+Set the Maximum Transmission Unit (MTU) for the kernel interface.
+The MTU must be compatible with the connected VPP interface.
+```
+
+**Example:**
+
+```none
+set interfaces vpp gre vppgre0 mtu 9000
+```
+:::{note}
+The MTU size must not exceed the MTU size
+supported by the associated VPP interface.
+:::
+
+## Configuration Examples
+
+### Layer 3 GRE Tunnel
+
+```none
+# IPv4 GRE tunnel
+set interfaces vpp gre vppgre1
+set interfaces vpp gre vppgre1 description "Site-to-site tunnel"
+set interfaces vpp gre vppgre1 remote 203.0.113.10
+set interfaces vpp gre vppgre1 source-address 192.168.1.1
+set interfaces vpp gre vppgre1 tunnel-type l3
+```
+
+### Layer 2 GRE Tunnel (TEB)
+
+```none
+# Transparent Ethernet Bridge
+set interfaces vpp gre vppgre2
+set interfaces vpp gre vppgre2 description "L2 extension tunnel"
+set interfaces vpp gre vppgre2 remote 203.0.113.20
+set interfaces vpp gre vppgre2 source-address 192.168.1.1
+set interfaces vpp gre vppgre2 tunnel-type teb
+```
+
+### IPv6 GRE Tunnel
+
+```none
+# IPv6 endpoints
+set interfaces vpp gre vppgre3
+set interfaces vpp gre vppgre3 remote 2001:db8::2
+set interfaces vpp gre vppgre3 source-address 2001:db8::1
+```
+
+### GRE with Kernel Interface
+
+```none
+# GRE tunnel with management interface
+set interfaces vpp gre vppgre4
+set interfaces vpp gre vppgre4 remote 203.0.113.30
+set interfaces vpp gre vppgre4 source-address 192.168.1.1
+set interfaces vpp gre vppgre4 address 10.0.1.1/30
+```
+
+## Bridge Integration
+
+GRE interfaces can be added as members to VPP bridges for Layer 2
+switching. See {doc}`bridge` for detailed bridge configuration.
+
+```none
+# Add TEB GRE tunnel to bridge
+set interfaces vpp bridge vppbr1
+set interfaces vpp bridge vppbr1 member interface vppgre2
+set interfaces vpp bridge vppbr1 member interface eth1
+```
diff --git a/docs/vpp/configuration/interfaces/index.md b/docs/vpp/configuration/interfaces/index.md
new file mode 100644
index 00000000..6f070ff1
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/index.md
@@ -0,0 +1,49 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-index)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP Interfaces Configuration
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+bonding
+bridge
+gre
+ipip
+loopback
+vxlan
+xconnect
+```
+
+VyOS utilizes VPP (Vector Packet Processor) to provide high-performance data
+plane processing. While physical interfaces are typically managed through the
+Linux kernel using `linux-cp` (Linux Control Plane) integration, VyOS also
+supports creating dedicated VPP interfaces for enhanced flexibility and
+performance.
+
+## Why VPP Interfaces?
+
+VPP interfaces offer several advantages:
+
+- **Total Isolation**: VPP interfaces operate entirely within the VPP data
+ plane, providing isolation from the Linux kernel when needed.
+- **Advanced Features**: Access to VPP-specific functionality not available
+ in standard Linux interfaces.
+- **Flexible Deployment**: Some interface types are only available as VPP
+ interfaces or may not be supported by the kernel.
+- **Specific scenarios**: Not all use cases require integration with the
+ Linux Kernel.
+
+### Integration with Kernel
+
+VyOS provides seamless integration between VPP and kernel networking.
+This allows you to leverage the strengths of both approaches:
+create interfaces inside VPP, and access them from the Linux kernel and other
+services.
diff --git a/docs/vpp/configuration/interfaces/ipip.md b/docs/vpp/configuration/interfaces/ipip.md
new file mode 100644
index 00000000..80a724b0
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/ipip.md
@@ -0,0 +1,119 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-ipip)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP IPIP Configuration
+
+VPP IPIP interfaces provide IP-in-IP tunneling with high-performance
+packet processing. IPIP tunnels encapsulate IP packets within IP
+packets, creating point-to-point connections across Layer 3 networks.
+
+## Basic Configuration
+
+### Creating an IPIP Interface
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\>
+
+Create an IPIP interface where ``<vppipipN>`` follows the naming
+convention ``vppipip1``, ``vppipip2``, etc.
+```
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> remote \<address\>
+
+Set the tunnel remote endpoint address. Supports both IPv4 and IPv6
+addresses.
+```
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> source-address \<address\>
+
+Set the tunnel source address. The source address must match an address
+configured on the local system.
+```
+
+**Basic Example:**
+
+```none
+set interfaces vpp ipip vppipip1
+set interfaces vpp ipip vppipip1 remote 203.0.113.2
+set interfaces vpp ipip vppipip1 source-address 192.168.1.1
+```
+
+## Interface Configuration
+### Description and Administrative Control
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> description \<description\>
+
+Set a descriptive name for the IPIP interface.
+```
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> disable
+
+Administratively disable the IPIP interface.
+```
+
+### Kernel Interface Integration
+
+Kernel interface is bound to the VPP IPIP interface for management and
+application compatibility.
+
+## IP Address Configuration
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> address \<ip-address/prefix\>
+
+Configure IPv4 or IPv6 addresses on the kernel interface. Multiple
+addresses can be assigned.
+```
+
+**Examples:**
+
+```none
+# IPv4 address
+set interfaces vpp ipip vppipip0 address 192.168.1.10/24
+
+# IPv6 address
+set interfaces vpp ipip vppipip0 address 2001:db8::10/64
+```
+
+## MTU Configuration
+
+```{cfgcmd} set interfaces vpp ipip \<vppipipN\> mtu \<size\>
+
+Set the Maximum Transmission Unit (MTU) for the kernel interface.
+The MTU must be compatible with the connected VPP interface.
+```
+
+## Configuration Examples
+### IPv4 IPIP Tunnel
+
+```none
+# Basic IPv4 IPIP tunnel
+set interfaces vpp ipip vppipip1
+set interfaces vpp ipip vppipip1 description "Site-to-site IPIP tunnel"
+set interfaces vpp ipip vppipip1 remote 203.0.113.10
+set interfaces vpp ipip vppipip1 source-address 192.168.1.1
+```
+
+### IPv6 IPIP Tunnel
+
+```none
+# IPv6 endpoints
+set interfaces vpp ipip vppipip2
+set interfaces vpp ipip vppipip2 remote 2001:db8::2
+set interfaces vpp ipip vppipip2 source-address 2001:db8::1
+```
+
+### IPIP with Kernel Interface
+
+```none
+# IPIP tunnel with management interface
+set interfaces vpp ipip vppipip3
+set interfaces vpp ipip vppipip3 remote 203.0.113.30
+set interfaces vpp ipip vppipip3 source-address 192.168.1.1
+set interfaces vpp ipip vppipip3 address 10.0.2.1/30
+```
diff --git a/docs/vpp/configuration/interfaces/loopback.md b/docs/vpp/configuration/interfaces/loopback.md
new file mode 100644
index 00000000..552ec7e3
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/loopback.md
@@ -0,0 +1,148 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-loopback)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Loopback Interface Configuration
+
+VPP loopback interfaces provide virtual interfaces that remain
+administratively up and are commonly used for stable addressing,
+routing protocols, and as Bridge Virtual Interfaces (BVI). Loopback
+interfaces in VPP offer high-performance virtual connectivity with optimized
+packet processing.
+
+## Basic Configuration
+
+### Creating a Loopback Interface
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\>
+
+Create a loopback interface where ``<vpploN>`` follows the naming
+convention ``vpplo1``, ``vpplo2``, etc.
+```
+
+**Basic Example:**
+
+```none
+set interfaces vpp loopback vpplo1
+```
+
+## Interface Configuration
+### Description and Administrative Control
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> description \<description\>
+
+Set a descriptive name for the loopback interface.
+```
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> disable
+
+Administratively disable the loopback interface.
+```
+
+### Kernel Interface Integration
+
+Kernel interface is bounded to the VPP loopback interface for management
+and application compatibility.
+
+## IP Address Configuration
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> address \<ip-address/prefix\>
+
+Configure IPv4 or IPv6 addresses on the kernel interface. Multiple
+addresses can be assigned.
+```
+
+**Examples:**
+
+```none
+# IPv4 address
+set interfaces vpp loopback vpplo1 address 192.168.1.10/24
+
+# IPv6 address
+set interfaces vpp loopback vpplo1 address 2001:db8::10/64
+```
+
+## MTU Configuration
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> mtu \<size\>
+
+Set the Maximum Transmission Unit (MTU) for the kernel interface.
+The MTU must be compatible with the connected VPP interface.
+```
+
+## VLAN Configuration
+
+VPP kernel interfaces support VLAN (Virtual LAN) sub-interfaces for network
+segmentation.
+
+### Creating VLAN Sub-interfaces
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> vif \<vlan-id\>
+
+Create a VLAN sub-interface with the specified VLAN ID (0-4094).
+```
+
+### VLAN Sub-interface Configuration
+
+VLAN sub-interfaces support the same configuration options as the parent
+interface:
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> vif \<vlan-id\> address \<ip-address/prefix\>
+```
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> vif \<vlan-id\> description \<description\>
+```
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> vif \<vlan-id\> disable
+```
+
+```{cfgcmd} set interfaces vpp loopback \<vpploN\> vif \<vlan-id\> mtu \<size\>
+```
+
+**Examples:**
+
+```none
+# Configure VLAN 100
+set interfaces vpp loopback vpplo1 vif 100 address 192.168.100.1/24
+set interfaces vpp loopback vpplo1 vif 100 description "Management VLAN"
+set interfaces vpp loopback vpplo1 vif 100 mtu 1500
+
+# Configure VLAN 200
+set interfaces vpp loopback vpplo1 vif 200 address 192.168.200.1/24
+set interfaces vpp loopback vpplo1 vif 200 description "Guest VLAN"
+```
+
+## Configuration Examples
+### Basic Loopback Interface
+
+```none
+# Create simple loopback
+set interfaces vpp loopback vpplo1
+set interfaces vpp loopback vpplo1 description "Router ID interface"
+```
+
+### Loopback with Kernel Interface
+
+```none
+# Loopback with management access
+set interfaces vpp loopback vpplo2
+set interfaces vpp loopback vpplo2 description "Management loopback"
+set interfaces vpp loopback vpplo2 address 10.255.255.1/32
+```
+
+### Bridge Virtual Interface (BVI)
+
+```none
+# Loopback as BVI for bridge
+set interfaces vpp loopback vpplo3
+set interfaces vpp loopback vpplo3 description "Bridge gateway interface"
+set interfaces vpp bridge vppbr1
+set interfaces vpp bridge vppbr1 member interface vpplo3 bvi
+set interfaces vpp loopback vpplo3 address 192.168.100.1/24
+```
diff --git a/docs/vpp/configuration/interfaces/vxlan.md b/docs/vpp/configuration/interfaces/vxlan.md
new file mode 100644
index 00000000..2139f120
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/vxlan.md
@@ -0,0 +1,157 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-vxlan)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP VXLAN Configuration
+
+VPP VXLAN interfaces provide virtual extensible local area network (VXLAN)
+tunneling with high-performance packet processing. VXLAN extends Layer 2
+domains across Layer 3 networks using UDP encapsulation, enabling scalable
+multi-tenant networking while leveraging VPP's optimized data plane.
+
+## Basic Configuration
+
+### Creating a VXLAN Interface
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\>
+
+Create a VXLAN interface where ``<vppvxlanN>`` follows the naming
+convention ``vppvxlan1``, ``vppvxlan2``, etc.
+```
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> vni \<vni\>
+
+Set the Virtual Network Identifier (VNI) for the VXLAN tunnel. Valid range
+is 0-16777214.
+```
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> remote \<address\>
+
+Set the tunnel remote endpoint address. Supports both IPv4 and IPv6
+addresses.
+```
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> source-address \<address\>
+
+Set the tunnel source address. Must match an address configured on the
+local system.
+```
+
+**Basic Example:**
+
+```none
+set interfaces vpp vxlan vppvxlan1
+set interfaces vpp vxlan vppvxlan1 vni 100
+set interfaces vpp vxlan vppvxlan1 remote 203.0.113.2
+set interfaces vpp vxlan vppvxlan1 source-address 192.168.1.1
+```
+
+## Interface Configuration
+### Description and Administrative Control
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> description \<description\>
+
+Set a descriptive name for the VXLAN interface.
+```
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> disable
+
+Administratively disable the VXLAN interface.
+```
+
+### Kernel Interface Integration
+
+The kernel interface is bound to the VXLAN tunnel for management and
+application compatibility.
+
+## IP Address Configuration
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> address \<ip-address/prefix\>
+
+Configure IPv4 or IPv6 addresses on the kernel interface. Multiple
+addresses can be assigned.
+```
+
+**Examples:**
+
+```none
+set interfaces vpp vxlan vppvxlan1 address 192.168.1.10/24
+set interfaces vpp vxlan vppvxlan1 address 2001:db8::10/64
+```
+
+## MTU Configuration
+
+```{cfgcmd} set interfaces vpp vxlan \<vppvxlanN\> mtu \<size\>
+
+Set the Maximum Transmission Unit (MTU) for the kernel interface. The MTU
+must be compatible with the connected VPP interface.
+```
+
+## Configuration Examples
+### Basic VXLAN Tunnel
+
+```none
+# IPv4 VXLAN tunnel
+set interfaces vpp vxlan vppvxlan1
+set interfaces vpp vxlan vppvxlan1 description "Tenant A network extension"
+set interfaces vpp vxlan vppvxlan1 vni 1000
+set interfaces vpp vxlan vppvxlan1 remote 203.0.113.10
+set interfaces vpp vxlan vppvxlan1 source-address 192.168.1.1
+```
+
+### IPv6 VXLAN Tunnel
+
+```none
+# IPv6 endpoints
+set interfaces vpp vxlan vppvxlan2
+set interfaces vpp vxlan vppvxlan2 vni 2000
+set interfaces vpp vxlan vppvxlan2 remote 2001:db8::2
+set interfaces vpp vxlan vppvxlan2 source-address 2001:db8::1
+```
+
+### VXLAN with Kernel Interface
+
+```none
+# VXLAN tunnel with management interface
+set interfaces vpp vxlan vppvxlan3
+set interfaces vpp vxlan vppvxlan3 vni 3000
+set interfaces vpp vxlan vppvxlan3 remote 203.0.113.30
+set interfaces vpp vxlan vppvxlan3 source-address 192.168.1.1
+set interfaces vpp vxlan vppvxlan3 address 10.0.3.1/24
+```
+
+## Bridge Integration
+
+VXLAN interfaces are commonly used as members in VPP bridges for Layer 2
+extension. See {doc}`bridge` for more information.
+
+```none
+# Add VXLAN tunnel to bridge
+set interfaces vpp bridge vppbr1
+set interfaces vpp bridge vppbr1 member interface vppvxlan1
+set interfaces vpp bridge vppbr1 member interface eth1
+set interfaces vpp bridge vppbr1 member interface vpplo1 bvi
+```
+
+### Multi-Tenant Configuration
+
+```none
+# Multiple VNIs for tenant separation
+set interfaces vpp vxlan vppvxlan10
+set interfaces vpp vxlan vppvxlan10 description "Tenant A - Production"
+set interfaces vpp vxlan vppvxlan10 vni 1001
+set interfaces vpp vxlan vppvxlan10 remote 203.0.113.20
+set interfaces vpp vxlan vppvxlan10 source-address 192.168.1.1
+
+set interfaces vpp vxlan vppvxlan11
+set interfaces vpp vxlan vppvxlan11 description "Tenant A - Development"
+set interfaces vpp vxlan vppvxlan11 vni 1002
+set interfaces vpp vxlan vppvxlan11 remote 203.0.113.21
+set interfaces vpp vxlan vppvxlan11 source-address 192.168.1.1
+```
diff --git a/docs/vpp/configuration/interfaces/xconnect.md b/docs/vpp/configuration/interfaces/xconnect.md
new file mode 100644
index 00000000..b970da28
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/xconnect.md
@@ -0,0 +1,108 @@
+---
+lastproofread: '2026-03-13'
+---
+
+(vpp-config-interfaces-xconnect)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP XConnect Configuration
+
+VPP XConnect provides direct Layer 2 packet forwarding between two
+interfaces with maximum transparency and minimal overhead. XConnect
+creates a simple point-to-point bridge that forwards all Layer 2 packets
+bidirectionally without MAC learning or flooding, making it ideal for
+transparent connectivity scenarios.
+
+XConnect operates as a super-transparent bridge, forwarding all frames
+between the connected interfaces without any packet inspection or
+modification. This provides the simplest possible Layer 2 forwarding with
+VPP's high-performance packet processing.
+
+## Comparison with Bridges
+
+- **XConnect**: Point-to-point only, no MAC learning, maximum
+ transparency, minimal overhead
+- **Bridge**: Multi-port, MAC learning, broadcast handling, more
+ features but higher overhead
+
+Choose XConnect when you need simple point-to-point Layer 2 forwarding
+with maximum performance and transparency. Use bridges when you need
+multi-port switching with MAC learning and broadcast handling.
+
+## Basic Configuration
+
+### Creating an XConnect Interface
+
+```{cfgcmd} set interfaces vpp xconnect \<vppxconN\>
+
+Create an XConnect interface where ``<vppxconN>`` follows the naming
+convention ``vppxcon1``, ``vppxcon2``, etc.
+```
+
+```{cfgcmd} set interfaces vpp xconnect \<vppxconN\> member interface \<interface-name\>
+
+Add an interface as a member of the XConnect. Exactly two member
+interfaces must be configured to create bidirectional forwarding.
+```
+
+**Basic Example:**
+
+```none
+set interfaces vpp xconnect vppxcon1
+set interfaces vpp xconnect vppxcon1 member interface eth0
+set interfaces vpp xconnect vppxcon1 member interface eth1
+```
+
+This configuration creates transparent forwarding between `eth0` and `eth1`,
+where any packet received on either interface is immediately forwarded to
+the other without any processing.
+
+## Interface Configuration
+
+```{cfgcmd} set interfaces vpp xconnect \<vppxconN\> description \<description\>
+
+Set a descriptive name for the XConnect interface.
+```
+
+## Configuration Examples
+### Physical Interface XConnect
+
+```none
+# Connect two physical interfaces
+set interfaces vpp xconnect vppxcon1
+set interfaces vpp xconnect vppxcon1 description "Transparent wire between ports"
+set interfaces vpp xconnect vppxcon1 member interface eth0
+set interfaces vpp xconnect vppxcon1 member interface eth1
+```
+
+This creates a transparent wire between two physical ports, effectively
+making them function as a single cable.
+
+### Tunnel to Physical XConnect
+
+```none
+# Connect tunnel to physical interface
+set interfaces vpp xconnect vppxcon2
+set interfaces vpp xconnect vppxcon2 description "GRE tunnel to physical bridge"
+set interfaces vpp xconnect vppxcon2 member interface vppgre1
+set interfaces vpp xconnect vppxcon2 member interface eth2
+```
+
+This forwards all traffic from a GRE tunnel directly to a physical
+interface and vice versa.
+
+### Mixed Interface Types
+
+```none
+# Connect different interface types
+set interfaces vpp xconnect vppxcon3
+set interfaces vpp xconnect vppxcon3 description "VXLAN to bonding bridge"
+set interfaces vpp xconnect vppxcon3 member interface vppvxlan1
+set interfaces vpp xconnect vppxcon3 member interface vppbond0
+```
+
+This demonstrates XConnect's flexibility in connecting various VPP interface
+types.
diff --git a/docs/vpp/configuration/ipfix.md b/docs/vpp/configuration/ipfix.md
new file mode 100644
index 00000000..7ed2aee3
--- /dev/null
+++ b/docs/vpp/configuration/ipfix.md
@@ -0,0 +1,50 @@
+# VPP IPFIX Configuration
+
+VPP IPFIX in VyOS allows monitoring and exporting network traffic flows
+for analytics, security, and accounting. IPFIX works with the VPP
+(Vector Packet Processing) backend to provide high-performance flow tracking.
+
+## Overview
+
+VyOS integrates VPP for high-performance packet processing. IPFIX
+configuration controls how flows are monitored, exported, and which
+interfaces are included.
+
+## Key IPFIX Concepts
+
+- **Active timeout**: Maximum time a flow is kept active before export.
+- **Inactive timeout**: Maximum time an idle flow is kept before export.
+- **Collector**: The remote host and port to which flow records are sent.
+- **Flow layers**: Determines which layer information is included
+ (`l2`, `l3`, `l4`).
+- **Interfaces**: Physical or virtual interfaces to monitor.
+- **Direction**: Which traffic to monitor (`rx`, `tx`, `both`).
+- **Flow variant**: Optional filter for IPv4 or IPv6 flows.
+
+## Configuration Options
+
+- **active-timeout**: Duration (in seconds) after which active flows
+ are exported.
+- **inactive-timeout**: Duration (in seconds) after which idle flows
+ are exported.
+- **collector \`\<ip>\` port \`\<port>\`**: IP and UDP port of the IPFIX collector.
+- **collector \`\<ip>\` source-address \`\<ip>\`**: Source address for flow export.
+- **flowprobe-record \`\<l2|l3|l4>\`**: Layers to include in flow records.
+- **interface** `<interface>` **\[direction** `<rx|tx|both>`**\]**
+ **\[flow-variant** `<ipv4|ipv6>`**\]**: Interfaces to monitor,
+ direction of traffic, and optional flow variant filter.
+
+## Example Configuration
+
+```none
+set vpp ipfix active-timeout '15'
+set vpp ipfix inactive-timeout '120'
+set vpp ipfix collector 192.0.2.2 port '4739'
+set vpp ipfix collector 192.0.2.2 source-address '192.0.2.1'
+set vpp ipfix flowprobe-record 'l2'
+set vpp ipfix flowprobe-record 'l3'
+set vpp ipfix flowprobe-record 'l4'
+set vpp ipfix interface eth0
+set vpp ipfix interface eth1 direction 'both'
+set vpp ipfix interface eth1 flow-variant 'ipv4'
+```
diff --git a/docs/vpp/configuration/ipsec.md b/docs/vpp/configuration/ipsec.md
new file mode 100644
index 00000000..523b4a90
--- /dev/null
+++ b/docs/vpp/configuration/ipsec.md
@@ -0,0 +1,188 @@
+---
+lastproofread: '2025-09-04'
+---
+
+(vpp_config_ipsec)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP IPsec Configuration
+
+VPP Dataplane in VyOS can offload IPSec processing from kernel. This allows to speed-up IPSec traffic handling significantly, when necessary conditions are met.
+
+:::{note}
+VPP IPsec implementation is not as feature rich as Linux kernel IPsec. It supports only a subset of algorithms and modes.
+:::
+
+## Requirements
+
+To make IPSec offloading work, following requirements must be met:
+- VPP dataplane must be configured.
+- VPP {doc}`IPsec settings </vpp/configuration/dataplane/ipsec>` should be configured as needed.
+- IPSec should be configured in the VPN configuration section, see {doc}`/configuration/vpn/ipsec/index`.
+- Both source and destination of the IPSec traffic must be reachable via VPP interfaces, so it can perform both encryption and decryption of the traffic.
+
+## Integration Details
+
+VPP Dataplane offloads IPSec processing from kernel, but does not handle IPSec configuration itself. IPSec configuration management and control-plane operation, like IKE negotiation, is still done by the kernel and other daemons.
+
+After an IPSec tunnel is configured in the kernel, VPP receives the necessary information via netlink messages and creates a corresponding SAs and policies to be able to offload the traffic.
+
+When VPP is used for offloading IPsec, it creates a virtual interface of a specific type to connect to a peer. The type of the interface can be configured using the `interface-type` parameter in the dataplane settings.
+
+## Supported IPsec Modes
+
+VPP supports offloading IPsec connections in the following IPsec modes:
+- Tunnel mode
+- Transport mode
+
+## Supported Encryption and Integrity Algorithms
+
+:::{warning}
+Since VPP dataplane is used only to offload IPsec traffic processing, algorithms mentioned below are applicable to ESP profiles in the IPsec configuration. IKE profiles are not affected by these limitations and can use any algorithms supported by the kernel.
+:::
+
+VPP **supports** only the following **encryption algorithms**:
+- AES-CBC
+- AES-GCM with ICV
+
+VPP **does not** support the following **encryption algorithms**:
+- Null encryption
+- AES-CTR
+- AES-CCM with ICV
+- Null encryption with AES-GMAC
+- 3DES-EDE-CBC
+- Blowfish-CBC
+- Camellia-CBC
+- Camellia-COUNTER
+- Camellia-CCM with ICV
+- Serpent-CBC
+- Twofish-CBC
+- CAST-CBC
+- ChaCha20/Poly1305 with ICV
+
+VPP **supports** the following **integrity algorithms**:
+- MD5 HMAC
+- SHA1 HMAC
+- SHA2_256_128 HMAC
+- SHA2_384_192 HMAC
+- SHA2_512_256 HMAC
+
+VPP **does not** support the following **integrity algorithms**:
+- MD5_128 HMAC
+- SHA1_160 HMAC
+- SHA2_256_96 HMAC
+- AES XCBC
+- AES CMAC
+- AES-GMAC
+
+If you have configured ESP profiles with algorithms not supported by VPP and the traffic for such peers flows trough VPP interfaces, such traffic will be dropped.
+
+## Configuration Examples
+
+**ACL for VPP IPsec Traffic**
+
+When using VPP for offloading IPsec traffic, you may need to adjust your firewall rules to allow the necessary protocols and ports. Below is an example of how to configure ACLs for VPP IPsec traffic:
+
+```none
+set vpp acl ip interface <interface-name> input acl-tag 10 tag-name 'IPSEC'
+set vpp acl ip tag-name IPSEC description 'Allow IPsec traffic'
+set vpp acl ip tag-name IPSEC rule 10 action 'permit'
+set vpp acl ip tag-name IPSEC rule 10 destination port '500'
+set vpp acl ip tag-name IPSEC rule 10 protocol 'tcp'
+set vpp acl ip tag-name IPSEC rule 20 action 'permit'
+set vpp acl ip tag-name IPSEC rule 20 destination port '500'
+set vpp acl ip tag-name IPSEC rule 20 protocol 'udp'
+set vpp acl ip tag-name IPSEC rule 30 action 'permit'
+set vpp acl ip tag-name IPSEC rule 30 destination port '4500'
+set vpp acl ip tag-name IPSEC rule 30 protocol 'tcp'
+set vpp acl ip tag-name IPSEC rule 40 action 'permit'
+set vpp acl ip tag-name IPSEC rule 40 destination port '4500'
+set vpp acl ip tag-name IPSEC rule 40 protocol 'udp'
+set vpp acl ip tag-name IPSEC rule 50 action 'permit'
+set vpp acl ip tag-name IPSEC rule 50 protocol 'esp'
+```
+
+Pay attention to the order of the rules, as they are processed sequentially. Make sure to place IPsec-related rules before any other rules that might deny traffic to ensure that IPsec traffic is allowed.
+
+**Simple VTI-based IPsec Tunnel**
+
+On the VPP host:
+
+```none
+set interfaces ethernet eth1 address '192.168.1.1/24'
+set interfaces ethernet eth2 address '192.168.100.1/24'
+
+set interfaces vti vti1
+set protocols static route 192.168.200.0/24 interface vti1
+
+set vpn ipsec authentication psk psk1 id 'peerA'
+set vpn ipsec authentication psk psk1 id 'peerB'
+set vpn ipsec authentication psk psk1 secret 'AB'
+
+set vpn ipsec esp-group esp1 mode 'tunnel'
+set vpn ipsec esp-group esp1 pfs 'disable'
+set vpn ipsec esp-group esp1 proposal 10 encryption 'aes256'
+set vpn ipsec esp-group esp1 proposal 10 hash 'sha256'
+set vpn ipsec ike-group ike1 close-action 'none'
+set vpn ipsec ike-group ike1 dead-peer-detection action 'clear'
+set vpn ipsec ike-group ike1 proposal 10 encryption 'aes256'
+set vpn ipsec ike-group ike1 proposal 10 hash 'sha256'
+
+set vpn ipsec interface 'eth1'
+
+set vpn ipsec site-to-site peer peerB authentication local-id 'peerA'
+set vpn ipsec site-to-site peer peerB authentication mode 'pre-shared-secret'
+set vpn ipsec site-to-site peer peerB authentication remote-id 'peerB'
+set vpn ipsec site-to-site peer peerB connection-type 'none'
+set vpn ipsec site-to-site peer peerB default-esp-group 'esp1'
+set vpn ipsec site-to-site peer peerB ike-group 'ike1'
+set vpn ipsec site-to-site peer peerB local-address '192.168.1.1'
+set vpn ipsec site-to-site peer peerB remote-address '192.168.1.3'
+set vpn ipsec site-to-site peer peerB vti bind 'vti1'
+set vpn ipsec site-to-site peer peerB vti traffic-selector remote prefix '192.168.200.0/24'
+
+set vpp settings interface eth1
+set vpp settings interface eth2
+set vpp settings ipsec netlink rx-buffer-size '32000'
+set vpp settings lcp ignore-kernel-routes
+```
+
+Where:
+- `eth1` is the interface connected to the IPsec peer.
+- `eth2` is the interface connected to the local subnet, where unencrypted traffic is expected.
+- `192.168.100.0/24` is the local subnet that will be accessible through the IPsec tunnel.
+- `192.168.200.0/24` is the remote subnet that will be accessible through the IPsec tunnel.
+- `vti1` is the VTI interface created by VPP for the IPsec tunnel.
+- `peerA` and `peerB` are the identifiers for the local side and remote peer, respectively.
+
+:::{note}
+**What is important in this configuration**
+
+VPP uses only remote traffic-selector to determine what traffic should be offloaded to the IPsec tunnel.
+
+Adding additional routes via VTI interface does not affect actual VPP IPsec operation.
+:::
+
+## Potential Issues and Troubleshooting
+
+Improper IPsec configuration can lead to various issues, including:
+- **Unidirectional traffic flow or acceleration**
+
+ If kernel has a conflicting route for the remote subnet, such route may take precedence over the policy route created for the IPsec tunnel in VPP. This may lead to unidirectional traffic flow or acceleration only in one direction. This has no security impact because traffic will still be encrypted by the kernel, but it may lead to performance degradation. To avoid this, ensure that no conflicting routes exist in the kernel routing table.
+
+- **Conflicting with kernel routes**
+
+ If the kernel routes synchronization option is enabled, VPP will install all the routes from kernel. If you have there routes configured via VTI interfaces to the IPsec peer, they will conflict with the policy routes created for the IPsec tunnel in VPP. Consider using policy-based IPSec configuration to avoid this or [disable the kernel routes synchronization](lcp.md#vpp-lcp-configuration).
+
+- **Unsupported algorithms**
+
+ If you have configured ESP profiles with algorithms not supported by VPP and the traffic for such peers flows through VPP interfaces, such traffic will be dropped. You can check system logs for messages from VPP with `linux-cp/ipsec: Invalid/Unsupported crypto algo` or `linux-cp/ipsec: Invalid/Unsupported integ algo` line to identify such cases.
+
+- **Connection is established but no traffic flows**
+
+ Even if you use compatible algorithms, there can be other reasons why traffic is not flowing. One of most frequent is blocking traffic between peers - that is especially common in public clouds. Make sure that TCP/UDP ports 500 and 4500 and ESP protocol are allowed between the peers. Alternatively, consider enforcing UDP encapsulation on both sides of the tunnel:
+
+```{cfgcmd} set vpn ipsec site-to-site peer \<peer-name\> force-udp-encapsulation
+``` \ No newline at end of file
diff --git a/docs/vpp/configuration/nat/cgnat.md b/docs/vpp/configuration/nat/cgnat.md
new file mode 100644
index 00000000..d3742b59
--- /dev/null
+++ b/docs/vpp/configuration/nat/cgnat.md
@@ -0,0 +1,249 @@
+---
+lastproofread: '2026-03-03'
+---
+
+(vpp_config_nat_cgnat)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP CGNAT Configuration
+
+Carrier-grade NAT (CGNAT) is a NAT type designed for Internet Service
+Providers (ISPs) to manage limited pools of public IP addresses. It
+solves two main problems:
+- Enables fair sharing of a limited number of public IP addresses among
+ multiple customers, ensuring all have internet access without interfering
+ with each other.
+- Enables tracking and logging of public IP address usage by different
+ customers, which is often a regulatory requirement.
+
+CGNAT configuration is straightforward. Define the inside and outside
+interfaces, then create rules to manage the translation of private IP
+addresses to public IP addresses.
+
+:::{warning}
+**Enabling CGNAT** on an interface (both inside and outside)
+**disables normal routing** on these interfaces and **blocks management
+access** to the VyOS router itself.
+
+Ensure you have an alternative management path to the router before applying
+your CGNAT configuration.
+:::
+
+## Interface Configuration
+
+Define the inside and outside interfaces. The inside interface connects
+to the private network, while the outside interface connects to the public
+network.
+
+```{cfgcmd} set vpp nat cgnat interface inside \<inside-interface\>
+```
+
+```{cfgcmd} set vpp nat cgnat interface outside \<outside-interface\>
+```
+
+This is a mandatory step, as the CGNAT needs to know on which interfaces it
+needs to apply rules and operate.
+
+## NAT Rules Configuration
+
+Next, you need to create the NAT rules.
+
+```{cfgcmd} set vpp nat cgnat rule \<rule-number\> description \<description\>
+```
+
+Add a description to the rule for easier identification.
+
+```{cfgcmd} set vpp nat cgnat rule \<rule-number\> inside-prefix \<inside-prefix\>
+```
+
+Specify the inside prefix (private IP range) to translate.
+
+```{cfgcmd} set vpp nat cgnat rule \<rule-number\> outside-prefix \<outside-prefix\>
+```
+
+Specify the outside prefix (public IP range) to use for translation.
+
+## Exclude Rules Configuration
+
+CGNAT exclude rules are implemented as DET44 identity mappings. Matching
+traffic is excluded from CGNAT translation and keeps its original
+address/port tuple.
+
+```{cfgcmd} set vpp nat cgnat exclude rule \<rule-number\> description \<description\>
+```
+
+Adds a description (stored as VPP identity-mapping tag) for easier
+identification.
+
+```{cfgcmd} set vpp nat cgnat exclude rule \<rule-number\> local-address \<local-address\>
+```
+
+Sets the local IPv4 address that should be excluded from translation. This
+option is mandatory for each exclude rule.
+
+```{cfgcmd} set vpp nat cgnat exclude rule \<rule-number\> protocol \<tcp|udp|icmp|all\>
+```
+
+Matches a specific protocol. Default is `all`.
+
+```{cfgcmd} set vpp nat cgnat exclude rule \<rule-number\> local-port \<1-65535\>
+```
+
+Matches a specific local port (or ICMP identifier in case of ICMP protocol).
+
+:::{important}
+Exclude-rule validation rules:
+- `local-address` must be specified.
+- `protocol` and `local-port` must either both be specified or both be
+ : omitted.
+- Duplicate identity mappings are not allowed (same local-address,
+ : protocol, local-port tuple).
+:::
+
+:::{note}
+A common use case for exclude rules is preserving management-plane access to
+the router itself (for example SSH) and local-originated services (for
+example DNS queries) when CGNAT is enabled.
+:::
+
+:::{important}
+**Memory Requirements**
+
+CGNAT memory usage scales with the number of internal customers.
+
+**Each 256 customers** (equivalent to a /24 subnet) requires
+approximately **4 MB of main heap memory**. This memory maintains
+customer-to-port mappings and session state information.
+
+Configure your VPP main heap size appropriately based on your expected
+customer count. See {ref}`VPP Memory Configuration <vpp_config_dataplane_memory>` for details on adjusting main heap size.
+:::
+
+## Session Limitations
+
+CGNAT has built-in session limitations to ensure fair resource allocation:
+
+Each customer (internal IP address) is limited to a maximum of 1000
+simultaneous sessions, even if more than 1000 ports are allocated to that
+customer. This limitation applies to all session types (TCP, UDP, ICMP).
+
+## Timeouts Configuration
+
+You can adjust NAT session timers to optimize address space usage by
+controlling how long sessions remain active and how long they occupy IP
+address and port combinations.
+
+Adjust these settings for different protocols individually:
+
+```
+set vpp nat cgnat timeout icmp <timeout-value>
+set vpp nat cgnat timeout tcp-established <timeout-value>
+set vpp nat cgnat timeout tcp-transitory <timeout-value>
+set vpp nat cgnat timeout udp <timeout-value>
+```
+
+## Example Configuration
+
+Here is an example CGNAT configuration with these assumptions:
+- Inside interface: `eth2`
+- Outside interface: `eth1`
+- Inside prefix: `100.64.0.0/16`
+- Outside prefix: `203.0.113.0/24`
+
+```
+set vpp nat cgnat interface inside eth2
+set vpp nat cgnat interface outside eth1
+set vpp nat cgnat rule 1 description "CGNAT Rule 1"
+set vpp nat cgnat rule 1 inside-prefix 100.64.0.0/16
+set vpp nat cgnat rule 1 outside-prefix 203.0.113.0/24
+set vpp nat cgnat exclude rule 10 description "Bypass management host"
+set vpp nat cgnat exclude rule 10 local-address 100.64.0.10
+set vpp nat cgnat exclude rule 20 description "Bypass subscriber DNS"
+set vpp nat cgnat exclude rule 20 local-address 100.64.0.20
+set vpp nat cgnat exclude rule 20 protocol udp
+set vpp nat cgnat exclude rule 20 local-port 53
+```
+
+### Operational Commands
+
+Once the CGNAT is configured, you can use the following commands to monitor
+its status and operation:
+
+```{opcmd} show vpp nat cgnat interfaces
+```
+
+Displays the configured inside and outside interfaces.
+
+```
+vyos@vyos:~$ show vpp nat cgnat interfaces
+CGNAT interfaces:
+ eth2 in
+ eth1 out
+```
+
+```{opcmd} show vpp nat cgnat sessions
+```
+
+Display active NAT sessions. This command may produce extensive output if
+many sessions are active.
+
+```{opcmd} show vpp nat cgnat mappings
+```
+
+Display current NAT mappings, including inside and outside address
+prefixes.
+
+```
+vyos@vyos:~$ show vpp nat cgnat mappings
+Inside Outside Sharing ratio Ports per host Sessions
+------------- -------------- --------------- ---------------- ----------
+100.64.0.0/16 203.0.113.0/24 256 252 0
+```
+
+```{opcmd} show vpp nat cgnat exclude-rules
+```
+
+Displays configured CGNAT exclude rules (identity mappings).
+
+```
+vyos@vyos:~$ show vpp nat cgnat exclude-rules
+Address Protocol Port VRF Description
+----------- ---------- ------ ----- ---------------------
+100.64.0.10 all any 0 Bypass management host
+100.64.0.20 udp 53 0 Bypass subscriber DNS
+```
+
+### Potential Issues and Troubleshooting
+
+Configuration fails to apply with an error similar to:
+
+```
+vpp_papi.vpp_papi.VPPIOError: [Errno 2] VPP API client: read failed
+```
+
+CGNAT utilizes main heap memory and if you are trying to configure big
+prefixes or a large number of NAT sessions, you may run into memory allocation
+issues. Try to {ref}`increase the main heap size in VPP configuration
+<vpp-config-dataplane-memory>`.
+
+## SSH/DNS Reachability After Enabling CGNAT
+
+If SSH access to the router (or local-originated DNS queries) stops working
+after enabling CGNAT, traffic may be dropped by DET44 when it does not match a
+translation mapping.
+
+In this case, add an exclude rule for the router local address that must
+bypass CGNAT translation.
+
+```
+set vpp nat cgnat exclude rule 100 local-address <router-ip>
+```
+
+Then verify:
+
+```
+show vpp nat cgnat exclude-rules
+```
diff --git a/docs/vpp/configuration/nat/index.md b/docs/vpp/configuration/nat/index.md
new file mode 100644
index 00000000..aa1698ea
--- /dev/null
+++ b/docs/vpp/configuration/nat/index.md
@@ -0,0 +1,42 @@
+---
+lastproofread: '2026-03-05'
+---
+
+(vpp-config-nat-index)=
+
+```{include} /_include/need_improvement.txt
+
+```
+
+# VPP NAT Configuration
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+cgnat
+nat44
+```
+
+VPP Dataplane in VyOS supports two types of NAT:
+
+## NAT44
+
+This type is a classic NAT implementation where you can configure static
+and dynamic NAT rules. It supports both source and destination NAT. While the
+configuration may look a bit unusual compared to traditional NAT
+implementations, it provides flexibility in network configurations.
+
+## CGNAT
+
+CGNAT is a special type of NAT44, which is highly useful when you have
+multiple local customers and a limited number of public IP addresses. It
+shares the public IP address space fairly between customers by using a
+combination of IP address and port number to distinguish between them.
+
+ISPs often use this NAT type to provide internet access to customers.
+
+It supports only source NAT.
+
+CGNAT also supports exclude rules (identity mappings) to bypass translation
+for selected local addresses or protocol/port tuples.
diff --git a/docs/vpp/configuration/nat/nat44.md b/docs/vpp/configuration/nat/nat44.md
new file mode 100644
index 00000000..01b1cd3a
--- /dev/null
+++ b/docs/vpp/configuration/nat/nat44.md
@@ -0,0 +1,755 @@
+---
+lastproofread: '2026-03-05'
+---
+
+(vpp-config-nat-nat44)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP NAT44 Configuration
+
+NAT44 has two main use cases:
+- **Source NAT (SNAT)**: Enabling internet access for hosts in private
+ networks using dynamic or static address translation.
+- **Destination NAT (DNAT)**: Providing external access to internal services
+ through static port forwarding rules.
+
+VyOS supports both dynamic translation using address pools and static
+mappings for predictable address translation requirements.
+
+Configuring NAT44 involves a few steps:
+1. Define the inside and outside interfaces.
+2. Create NAT rules for SNAT or DNAT.
+
+## Dynamic and Static Operations
+
+NAT44 configuration can be done in one of two ways or in both ways
+simultaneously:
+1. Dynamically performing NAT using a pool of public IP addresses.
+2. Statically mapping private IP addresses to public IP addresses.
+
+To configure dynamic NAT, you need to define a pool of public IP
+addresses that will be used for translation. This offers an easy way to
+provide internet access to internal users.
+
+Static rules are suitable for scenarios where you need consistent and
+predictable mappings between private and public IP addresses. They are also
+the only way to configure DNAT.
+
+### NAT Rule Processing and Traffic Flow
+
+This section explains how different combinations of NAT rules affect
+traffic handling on a router. There are three possible combinations of NAT
+rule configurations:
+1. **Dynamic NAT Only**
+ - **All** traffic received on the "in" interface is processed by
+ dynamic NAT rules without exceptions.
+2. **Dynamic + Static NAT**
+ - **All** traffic received on the "in" interface is first matched
+ against static NAT rules.
+ - If no match is found, it is then processed against dynamic NAT rules.
+3. **Static NAT Only**
+ - **All** traffic on the "in" interface is checked against static NAT
+ rules.
+ - If no match is found, the traffic is routed **without NAT**.
+
+:::{important}
+- If **dynamic NAT rules** are present, **all** traffic received on
+ "in" interfaces is subject to NAT processing.
+- If **only static NAT rules** are configured, traffic that does not
+ match any static rule is routed unchanged.
+:::
+
+## Interfaces Configuration
+
+The first step in configuring NAT44 is defining which interfaces handle
+inside (private) and outside (public) traffic. VyOS uses these interface
+designations to determine the direction of translation.
+
+### Inside Interfaces
+
+Inside interfaces connect to private networks where hosts need source NAT
+to access external networks.
+
+```{cfgcmd} set vpp nat nat44 interface inside \<inside-interface\>
+```
+
+Traffic flowing **from** inside interfaces gets source NAT applied,
+translating private source addresses to public addresses from the
+translation pool.
+
+### Outside Interfaces
+
+Outside interfaces connect to public networks where external hosts may
+need to access internal services.
+
+```{cfgcmd} set vpp nat nat44 interface outside \<outside-interface\>
+```
+
+Traffic flowing **to** outside interfaces can trigger destination NAT
+based on static rules, allowing external access to internal services.
+
+### Interface Roles and Traffic Flow
+
+:::{note}
+While VyOS uses "inside" and "outside" as established conventions,
+the technical definitions are:
+- **Inside interface**: Interface where traffic originates that needs
+ source NAT (SNAT)
+- **Outside interface**: Interface where traffic originates that needs
+ destination NAT (DNAT)
+
+In complex network topologies, the same physical interface can be
+configured as both inside and outside to handle bidirectional NAT
+scenarios.
+:::
+
+**Traffic Processing:**
+1. **Inside → Outside** (SNAT): Private hosts accessing external networks
+2. **Outside → Inside** (DNAT): External hosts accessing internal services
+ via static rules
+3. **Dynamic NAT**: Created automatically for inside→outside traffic
+4. **Static NAT**: Requires explicit configuration for outside→inside
+ traffic
+
+### Multiple Interface Support
+
+You can configure multiple interfaces as inside or outside to support
+complex network topologies:
+
+```none
+# Multiple inside interfaces (different private networks)
+set vpp nat nat44 interface inside eth0
+set vpp nat nat44 interface inside eth2
+
+# Multiple outside interfaces (redundancy or load balancing)
+set vpp nat nat44 interface outside eth1
+set vpp nat nat44 interface outside eth3
+```
+
+## Address Pool Configuration
+
+Address pools define ranges of IP addresses that can be used for NAT
+translations. VyOS NAT44 supports two types of address pools, each serving
+different purposes.
+
+### Translation Pools
+
+Translation pools are used for dynamic source NAT (SNAT). They provide a
+range of public IP addresses that can be dynamically assigned to private
+hosts when they access external networks.
+
+```{cfgcmd} set vpp nat nat44 address-pool translation address \<ip-address | ip-address-range\>
+```
+
+```{cfgcmd} set vpp nat nat44 address-pool translation interface \<interface-name\>
+```
+
+**Examples:**
+
+```none
+# Single address pool
+set vpp nat nat44 address-pool translation address 203.0.113.10
+
+# Address range pool
+set vpp nat nat44 address-pool translation address 203.0.113.10-203.0.113.20
+
+# Interface-based pool (use a first IP assigned to the interface)
+set vpp nat nat44 address-pool translation interface eth1
+```
+
+### Twice-NAT Pools
+
+Twice-NAT pools are used when performing both source and destination NAT on
+the same traffic flow. This is particularly useful in scenarios where you
+need to:
+- Translate both source and destination addresses
+- Provide access between networks with overlapping IP ranges
+- Implement advanced NAT scenarios like self-twice-nat
+
+```{cfgcmd} set vpp nat nat44 address-pool twice-nat address \<ip-address | ip-address-range\>
+```
+
+```{cfgcmd} set vpp nat nat44 address-pool twice-nat interface \<interface-name\>
+```
+
+**Examples:**
+
+```none
+# Twice-NAT pool for advanced scenarios
+set vpp nat nat44 address-pool twice-nat address 192.168.100.1-192.168.100.10
+
+# Interface-based twice-nat pool
+set vpp nat nat44 address-pool twice-nat interface eth2
+```
+
+### Pool Requirements
+
+:::{important}
+- For dynamic NAT to work, you must configure at least one
+ **translation** pool.
+- For static rules with twice-nat options, you must configure a
+ **twice-nat** pool.
+- Interface-based pools automatically include main (first) IP address
+ assigned to the specified interface.
+:::
+
+### Pool Selection Priority
+
+When multiple pools are configured, VyOS uses the following selection
+priority:
+1. **Static mappings**: Always use the specific external address defined in
+ the rule.
+2. **Dynamic NAT**: Use available addresses from translation pools in the
+ order they were configured.
+3. **Twice-NAT**: Use addresses from twice-nat pools for secondary
+ translation.
+
+:::{note}
+As soon as you have configured interfaces and pool, the NAT44 is
+operational.
+:::
+
+## Static Rules Configuration
+
+Static NAT rules provide predictable and consistent mappings between private
+and public IP addresses. They are essential for:
+- **Destination NAT (DNAT)**: Allowing external hosts to access services in
+ the private network.
+- **Server publishing**: Making internal services available from the
+ Internet.
+- **Consistent mappings**: Ensuring the same private IP always maps to the
+ same public IP.
+
+Unlike dynamic NAT that uses a pool of addresses, static rules create
+one-to-one mappings that persist until explicitly removed.
+
+### Basic Static Rule Configuration
+
+To create a static NAT rule, you need to define the local (internal) and
+external (public) address mappings:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> local address \<internal-ip\>
+```
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> external address \<external-ip\>
+```
+
+Where:
+- `<rule-number>` is a unique identifier for the rule
+- `<internal-ip>` is the private IP address in your local network
+- `<external-ip>` is the public IP address that external hosts will use
+
+This basic configuration creates a static one-to-one mapping. Traffic from
+outside to the external IP will be translated to the internal IP, and vice
+versa.
+
+### Port-based Static Rules
+
+For more granular control, you can create port-specific static rules. This
+is useful when you want to publish specific services:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> local address \<internal-ip\>
+```
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> local port \<internal-port\>
+```
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> external address \<external-ip\>
+```
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> external port \<external-port\>
+```
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> protocol \<protocol\>
+```
+
+Where:
+- `<internal-port>` and `<external-port>` are the port numbers used by
+ the connection.
+- `<protocol>` specifies the protocol (tcp, udp, icmp).
+
+:::{important}
+If you do not specify ports and protocol, the rule will apply to *all*
+traffic between the specified internal and external addresses.
+
+Rules must contain either both ports and protocol, or neither.
+:::
+
+### Advanced Static Rule Options
+
+VyOS NAT44 supports several advanced options for static rules:
+
+#### Twice-NAT
+
+Twice-NAT performs both source and destination NAT. When an external host
+accesses an internal service, the source IP of such a connection is
+translated to an address from the twice-NAT address pool.
+
+This is practical in scenarios where internal services cannot connect to
+public networks, so they see such traffic as internal.
+
+The twice-NAT option can be enabled with the following command:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> options twice-nat
+```
+
+#### Self Twice-NAT
+
+Self Twice-NAT is used when a local host needs to access itself via the
+external address:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> options self-twice-nat
+```
+
+This option rewrites source IP addresses on packets sent only from a local
+address to an external address configured in a rule.
+
+:::{important}
+- Using `self-twice-nat` option requires you to set the interface
+ connected to the local network as both inside and outside, because
+ both source and destination NAT need to be applied.
+- External IP address used in static rules must belong to one of the
+ configured translation pools.
+:::
+
+#### Out-to-In Only
+
+Restricts the rule to only apply to traffic from outside to inside
+interfaces:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> options out-to-in-only
+```
+
+This prevents the creation of sessions from the inside interface, making it
+a purely DNAT rule.
+
+#### Force Twice-NAT Address
+
+When using twice-nat, you can force the use of a specific IP address from
+the twice-nat address pool:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> options twice-nat-address \<ip-address\>
+```
+
+#### Rule Description
+
+To document your rules, you can add a description:
+
+```{cfgcmd} set vpp nat nat44 static rule \<rule-number\> description \<description\>
+```
+
+### Static Rules Configuration Examples
+
+**Full one-to-one NAT mapping:**
+
+```none
+set vpp nat nat44 static rule 100 local address 192.168.1.10
+set vpp nat nat44 static rule 100 external address 203.0.113.10
+set vpp nat nat44 static rule 100 description "One-to-one mapping"
+```
+
+**Port-specific SSH access:**
+
+```none
+set vpp nat nat44 static rule 200 local address 192.168.1.20
+set vpp nat nat44 static rule 200 local port 22
+set vpp nat nat44 static rule 200 external address 203.0.113.10
+set vpp nat nat44 static rule 200 external port 2222
+set vpp nat nat44 static rule 200 protocol tcp
+set vpp nat nat44 static rule 200 description "SSH access to server"
+```
+
+**Twice-NAT for local service access:**
+
+```none
+set vpp nat nat44 static rule 300 local address 192.168.1.30
+set vpp nat nat44 static rule 300 local port 80
+set vpp nat nat44 static rule 300 external address 203.0.113.10
+set vpp nat nat44 static rule 300 external port 80
+set vpp nat nat44 static rule 300 protocol tcp
+set vpp nat nat44 static rule 300 options twice-nat
+set vpp nat nat44 static rule 300 description "Web service with twice-nat"
+```
+:::{note}
+When using twice-nat or self-twice-nat options, ensure you have
+configured a twice-nat address pool using:
+```none
+set vpp nat nat44 address-pool twice-nat address <twice-nat-ip-range>
+```
+:::
+
+## Exclude Rules Configuration
+
+Exclude rules allow you to prevent specific traffic from undergoing NAT
+translation. This is particularly useful for:
+- **Router management**: Allowing SSH access to the router itself from
+ external networks.
+- **Service bypass**: Excluding specific services from NAT processing
+- **Traffic forwarding**: Allowing forwarded traffic to bypass NAT with 1-to-1
+ mapping.
+
+Exclude rules take precedence over both dynamic and static NAT rules,
+ensuring that matching traffic bypasses NAT processing. For forwarded
+traffic, exclude rules create invisible 1-to-1 mappings that allow packets
+to pass through without NAT modifications.
+
+### Basic Exclude Rule Configuration
+
+To create an exclude rule, you need to specify the traffic characteristics
+that should bypass NAT. You can configure exclude rules in two ways:
+
+**Option 1: Using local address**
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> local-address \<internal-ip\>
+```
+
+**Option 2: Using external interface**
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> external-interface \<interface-name\>
+```
+
+Where:
+- `<rule-number>` is a unique identifier for the exclude rule.
+- `<internal-ip>` is the local IP address that should be excluded from
+ : NAT.
+- `<interface-name>` is the external interface where the traffic
+ : originates.
+
+:::{important}
+You must use either `local-address` OR `external-interface` in an
+exclude rule, but not both simultaneously. These options are mutually
+exclusive.
+:::
+
+### Port-specific Exclude Rules
+
+For more granular control, you can exclude only specific ports and protocols.
+You can combine port and protocol specifications with either `local-address` or
+`external-interface`:
+
+**With local address:**
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> local-address \<internal-ip\>
+```
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> local-port \<port-number\>
+```
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> protocol \<protocol\>
+```
+
+**With external interface:**
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> external-interface \<interface-name\>
+```
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> local-port \<port-number\>
+```
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> protocol \<protocol\>
+```
+
+Where:
+- `<port-number>` is the specific port to exclude (1-65535)
+- `<protocol>` can be `tcp`, `udp`, `icmp`, or `all` (default)
+
+### Rule Documentation
+
+Add descriptions to your exclude rules for better management:
+
+```{cfgcmd} set vpp nat nat44 exclude rule \<rule-number\> description \<description\>
+```
+
+### Exclude Rules Configuration Examples
+
+**Exclude SSH access to router:**
+
+```none
+# Allow external SSH access to router without NAT
+set vpp nat nat44 exclude rule 10 local-address 192.168.1.1
+set vpp nat nat44 exclude rule 10 local-port 22
+set vpp nat nat44 exclude rule 10 protocol tcp
+set vpp nat nat44 exclude rule 10 description "SSH access to router"
+```
+
+**Exclude SNMP monitoring:**
+
+```none
+# Allow SNMP monitoring without NAT translation
+set vpp nat nat44 exclude rule 20 local-port 161
+set vpp nat nat44 exclude rule 20 protocol udp
+set vpp nat nat44 exclude rule 20 external-interface eth1
+set vpp nat nat44 exclude rule 20 description "SNMP monitoring"
+```
+
+**Exclude all traffic to router management interface:**
+
+```none
+# Exclude all traffic to router's management IP
+set vpp nat nat44 exclude rule 30 local-address 192.168.100.1
+set vpp nat nat44 exclude rule 30 description "Management interface bypass"
+```
+
+**Exclude all traffic from external interface:**
+
+```none
+# Exclude all traffic from external interface (alternative approach)
+set vpp nat nat44 exclude rule 31 external-interface eth1
+set vpp nat nat44 exclude rule 31 description "External interface bypass"
+```
+
+**Exclude forwarded traffic for specific service:**
+
+```none
+# Allow external access to internal server without NAT translation
+set vpp nat nat44 exclude rule 40 local-address 192.168.1.50
+set vpp nat nat44 exclude rule 40 local-port 8080
+set vpp nat nat44 exclude rule 40 protocol tcp
+set vpp nat nat44 exclude rule 40 description "Direct access to internal service"
+```
+
+### Common Use Cases
+
+**Router Administration:**
+
+Exclude rules are essential when you need to manage the router from external
+networks. Without exclude rules, NAT would attempt to translate the router's
+own traffic, potentially breaking management connections.
+
+**Service Monitoring:**
+
+Network monitoring systems often need direct access to router services.
+Exclude rules ensure that monitoring traffic bypasses NAT translation.
+
+**Routing Protocols:**
+
+Some routing protocols or network services may require direct communication
+without NAT interference.
+
+**Traffic Forwarding:**
+
+Exclude rules also work for forwarded traffic between networks. Without
+exclude rules, traffic from external to local networks must either match a
+static rule or be dropped. With exclude rules, traffic can bypass NAT
+processing with invisible 1-to-1 mappings.
+
+:::{important}
+Exclude rules affect both traffic destined for the router itself and
+forwarded traffic flowing through the router. For forwarded traffic, exclude
+rules create transparent 1-to-1 mappings that allow packets to pass without
+NAT modifications, while from the outside perspective, the traffic appears to
+bypass NAT entirely.
+:::
+
+## Advanced NAT44 Settings
+
+VyOS provides additional NAT44 settings for fine-tuning performance and
+behavior.
+
+### Session Timeouts
+
+NAT44 maintains translation sessions with configurable timeout values for
+different protocols:
+
+```{cfgcmd} set vpp nat nat44 timeout icmp \<seconds\>
+
+Set the timeout for ICMP sessions (Default: 60 seconds).
+```
+
+```{cfgcmd} set vpp nat nat44 timeout tcp-established \<seconds\>
+
+Set the timeout for established TCP connections (Default: 7440 seconds
+or 2 hours 4 minutes).
+```
+
+```{cfgcmd} set vpp nat nat44 timeout tcp-transitory \<seconds\>
+
+Set the timeout for transitory TCP connections (setup/teardown) (Default:
+240 seconds or 4 minutes).
+```
+
+```{cfgcmd} set vpp nat nat44 timeout udp \<seconds\>
+
+Set the timeout for UDP sessions (Default: 300 seconds or 5 minutes).
+```
+
+**Example:**
+
+```none
+# Customize timeouts for high-traffic environment
+set vpp nat nat44 timeout tcp-established 3600
+set vpp nat nat44 timeout udp 600
+set vpp nat nat44 timeout icmp 30
+```
+
+### Session Limits
+
+Control the maximum number of concurrent NAT sessions:
+
+```{cfgcmd} set vpp nat nat44 session-limit \<number\>
+
+Set the maximum number of NAT sessions per worker thread (Default:
+64512).
+```
+
+This setting helps prevent memory exhaustion and ensures predictable
+performance under high load.
+
+**Example:**
+
+```none
+# Increase session limit for high-capacity deployment
+set vpp nat nat44 session-limit 100000
+```
+
+## Complete Configuration Example
+
+Here's a complete example showing how to configure VyOS NAT44 for a typical
+network setup:
+
+**Network Topology:**
+
+```none
+Internet (203.0.113.0/24)
+ |
+┌───────────────────┐
+│ eth1 (outside) │ 203.0.113.1/24
+│ VyOS Router │
+│ eth0 (inside) │ 192.168.1.1/24
+└───────────────────┘
+ |
+Internal Network (192.168.1.0/24)
+├── 192.168.1.10 (Web Server)
+├── 192.168.1.20 (SSH Server)
+└── 192.168.1.30 (API Service)
+```
+
+**Configuration:**
+
+```none
+# Configure interfaces
+set vpp nat nat44 interface inside eth0
+set vpp nat nat44 interface outside eth1
+
+# Configure address pools
+set vpp nat nat44 address-pool translation address 203.0.113.10-203.0.113.50
+set vpp nat nat44 address-pool twice-nat address 203.0.113.100-203.0.113.110
+
+# Exclude rules for router management
+set vpp nat nat44 exclude rule 10 local-address 203.0.113.1
+set vpp nat nat44 exclude rule 10 local-port 22
+set vpp nat nat44 exclude rule 10 protocol tcp
+set vpp nat nat44 exclude rule 10 description "SSH access to router"
+
+set vpp nat nat44 exclude rule 11 local-address 203.0.113.1
+set vpp nat nat44 exclude rule 11 local-port 443
+set vpp nat nat44 exclude rule 11 protocol tcp
+set vpp nat nat44 exclude rule 11 description "HTTPS access to router web interface"
+
+# Static rule for web server (HTTP)
+set vpp nat nat44 static rule 100 local address 192.168.1.10
+set vpp nat nat44 static rule 100 local port 80
+set vpp nat nat44 static rule 100 external address 203.0.113.10
+set vpp nat nat44 static rule 100 external port 80
+set vpp nat nat44 static rule 100 protocol tcp
+set vpp nat nat44 static rule 100 description "Public web server"
+
+# Static rule for web server (HTTPS)
+set vpp nat nat44 static rule 101 local address 192.168.1.10
+set vpp nat nat44 static rule 101 local port 443
+set vpp nat nat44 static rule 101 external address 203.0.113.10
+set vpp nat nat44 static rule 101 external port 443
+set vpp nat nat44 static rule 101 protocol tcp
+set vpp nat nat44 static rule 101 description "Public web server HTTPS"
+
+# Static rule for SSH server with custom port
+set vpp nat nat44 static rule 200 local address 192.168.1.20
+set vpp nat nat44 static rule 200 local port 22
+set vpp nat nat44 static rule 200 external address 203.0.113.11
+set vpp nat nat44 static rule 200 external port 2222
+set vpp nat nat44 static rule 200 protocol tcp
+set vpp nat nat44 static rule 200 description "SSH access"
+
+# Static rule for API service (out-to-in only for security)
+set vpp nat nat44 static rule 300 local address 192.168.1.30
+set vpp nat nat44 static rule 300 local port 8080
+set vpp nat nat44 static rule 300 external address 203.0.113.12
+set vpp nat nat44 static rule 300 external port 8080
+set vpp nat nat44 static rule 300 protocol tcp
+set vpp nat nat44 static rule 300 options out-to-in-only
+set vpp nat nat44 static rule 300 description "API service (No Internet access for it)"
+```
+
+## Best Practices and Troubleshooting
+
+### Recommendations
+
+- **Use exclude rules** for router management services like SSH
+- **Use out-to-in-only** for services that do not need access to external
+ : networks.
+- **Limit port ranges** in static rules to only necessary ports.
+- **Document all rules** using descriptions for easier management.
+- **Use non-standard ports** for publishing SSH and other administrative
+ : services.
+- **Configure appropriate pool sizes** based on expected concurrent
+ : connections in your network.
+
+### Common Configuration Issues
+
+**Static rules not working:**
+
+1. Verify that the external IP address is included in an address pool
+2. Check that interfaces are correctly configured as inside or outside
+3. Ensure firewall rules allow the traffic
+
+**Twice-NAT not functioning:**
+
+1. Confirm twice-nat pool is configured
+2. Verify static rules have the correct twice-nat option
+3. Check that both translation and twice-nat pools are properly defined
+
+**Router management access issues:**
+
+1. Verify exclude rules are configured for management services
+2. Check that local-address matches the router's interface IP
+3. Ensure external-interface is correctly specified
+
+**Forwarded traffic from external networks not bypassing NAT:**
+
+1. Verify exclude rules are configured for the specific traffic flow
+2. Check that local-address matches the destination IP in the internal
+ network
+3. Ensure protocol and port specifications match the traffic requirements
+
+## Operational Commands
+
+Monitor NAT44 status and active connections using VyOS operational
+commands:
+
+```{opcmd} show vpp nat nat44 addresses
+
+Display configured NAT44 address pools.
+```
+
+```{opcmd} show vpp nat nat44 interfaces
+
+Show which interfaces are configured as inside or outside for NAT44.
+```
+
+```{opcmd} show vpp nat nat44 sessions
+
+Display active NAT44 translation sessions.
+```
+
+```{opcmd} show vpp nat nat44 static
+
+Show all configured static NAT mappings.
+```
+
+```{opcmd} show vpp nat nat44 summary
+
+Display a summary of NAT44 and statistics.
+``` \ No newline at end of file
diff --git a/docs/vpp/configuration/sflow.md b/docs/vpp/configuration/sflow.md
new file mode 100644
index 00000000..a065b6b0
--- /dev/null
+++ b/docs/vpp/configuration/sflow.md
@@ -0,0 +1,45 @@
+---
+lastproofread: '2025-09-04'
+---
+
+(vpp-config-sflow)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP sFlow Configuration
+
+VPP Dataplane in VyOS support sFlow for traffic monitoring and analysis.
+
+The VPP Dataplane integration works hand-in-hand with normal kernel sFlow agent, which is responsible for collecting and exporting sFlow samples. VPP itself is responsible for generating the samples.
+
+To enable sFlow in VPP, you first need to configure the service using the same steps as for normal kernel sFlow agent, as described in {doc}`/configuration/system/sflow`. Then you can enable sFlow on VPP interfaces.
+
+Then, you need to enable sFlow on the VPP interfaces you want to monitor. This is done using the following commands:
+
+```{cfgcmd} set vpp sflow interface \<interface-name\>
+```
+
+This will enable sFlow on the specified interface. You can repeat this command for each interface you want to monitor.
+
+:::{note}
+sFlow collects statistics only for traffic *received* on the interface. If you want to monitor traffic *sent* on the interface, you need to enable sFlow on the corresponding interface in the opposite direction.
+:::
+
+Optionally, you can specify the number of bytes from each packet that should be included in the sFlow sample using the following command:
+
+```{cfgcmd} set vpp sflow header-bytes \<bytes\>
+```
+
+This defines the size of the packet header (in bytes) captured for each sFlow sample.
+
+The sampling rate is configured globally under the `system sflow` section and automatically applied to VPP sFlow.
+This ensures consistent sampling behavior between the system and VPP, and prevents configuration conflicts.
+
+Finally, you need to enable integration between VPP and the kernel sFlow agent using the following command:
+
+```{cfgcmd} set system sflow vpp
+```
+
+After this, collecting and exporting sFlow samples will be handled by the kernel sFlow agent, while VPP will generate the samples.
diff --git a/docs/vpp/description.md b/docs/vpp/description.md
new file mode 100644
index 00000000..b6899564
--- /dev/null
+++ b/docs/vpp/description.md
@@ -0,0 +1,87 @@
+---
+lastproofread: '2026-02-16'
+---
+
+(vpp-description)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane Description
+
+## What is VPP in VyOS?
+
+VyOS supports two packet forwarding dataplanes:
+- **Linux kernel dataplane** (traditional)
+- **Vector Packet Processor (VPP) dataplane** (optional)
+
+VPP is a high-performance user space packet processor that improves
+throughput for demanding network workloads.
+
+## Key Benefits
+
+**Performance Improvement**
+
+VPP uses vector-based packet processing instead of one-by-one handling,
+delivering:
+- **Higher throughput** compared to kernel forwarding.
+- **Lower and more consistent latency** for time-sensitive applications.
+- **Linear scaling** with additional CPU cores.
+
+**VyOS Hybrid Integration**
+
+VyOS supports both dataplanes simultaneously, providing:
+- **Cross-dataplane forwarding**: Traffic can flow between the VPP dataplane
+ and kernel interfaces seamlessly.
+- **Transparent configuration**: Same CLI commands and most services work
+ regardless of dataplane.
+- **Gradual migration**: Enable VPP on high-traffic interfaces while keeping
+ others on kernel.
+
+## When to Use VPP
+
+**Consider VPP if you have:**
+- High-throughput requirements
+- Latency-sensitive applications requiring consistent performance
+
+**Stay with kernel dataplane if you have:**
+- Low to moderate traffic volumes
+- No latency-sensitive workloads
+- Applications requiring specific features not supported by VPP Dataplane
+
+## Packet Processing Integration
+
+VPP Dataplane integration minimizes configuration changes. Features in the
+kernel dataplane continue to operate there. VPP Dataplane only handles packet
+forwarding for interfaces explicitly assigned to it.
+
+Traffic flow examples between VPP and kernel dataplane interfaces:
+
+```{image} /_static/images/vpp/vyos_vpp_integration.svg
+:align: center
+```
+
+
+### Green path
+
+Traffic between two VPP interfaces stays within VPP for maximum performance
+and can use only VPP dataplane features.
+
+### Blue path
+
+Traffic between a VPP interface and a kernel interface is processed by both
+dataplanes and can use features from both.
+
+**Note:** This path has slower performance than pure VPP or pure kernel
+forwarding because packets traverse both dataplanes.
+
+### Red path
+
+Traffic between two kernel interfaces stays within the kernel dataplane without
+VPP acceleration. This is the traditional VyOS dataplane operation.
+
+## CLI Integration
+
+VyOS CLI commands work with both dataplanes. Use the same commands to
+configure interfaces, routing, and other features regardless of the dataplane.
diff --git a/docs/vpp/index.md b/docs/vpp/index.md
new file mode 100644
index 00000000..d9777329
--- /dev/null
+++ b/docs/vpp/index.md
@@ -0,0 +1,25 @@
+---
+lastproofread: '2025-09-04'
+---
+
+(vpp-index)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP Dataplane
+
+VPP (Vector Packet Processing) is a high performance packet processing stack
+that runs in user space. VyOS can use VPP as an alternative dataplane to
+the Linux kernel networking stack.
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+description
+requirements
+limitations
+configuration/index
+troubleshooting
+```
diff --git a/docs/vpp/limitations.md b/docs/vpp/limitations.md
new file mode 100644
index 00000000..9582347a
--- /dev/null
+++ b/docs/vpp/limitations.md
@@ -0,0 +1,42 @@
+---
+lastproofread: '2026-02-17'
+---
+
+(vpp-limitations)=
+
+```{include} /_include/need_improvement.txt
+```
+
+# VPP Dataplane Limitations
+
+VPP Dataplane provides significant performance advantages, but has some
+limitations you should consider.
+
+- **Feature Parity**
+
+ VPP does not support all features available in the Linux kernel dataplane.
+ Some networking features, specific protocols, or services may not be
+ available.
+
+ While VPP supports various interface types similar to the kernel, their
+ capabilities may differ.
+
+- **NIC and Driver Compatibility**
+
+ VyOS currently supports only DPDK drivers for network interfaces.
+ Not all network interface cards are compatible with DPDK drivers.
+
+- **Data Path Limitations**
+
+ If a feature exists only in the kernel dataplane, traffic that uses that
+ feature cannot traverse VPP interfaces. Examples include:
+
+ - Firewall
+ - QoS
+
+ When traffic uses the pure VPP path, it does not reach the kernel, where
+ such features are implemented. Plan how traffic flows through your VyOS
+ instance to ensure it reaches the necessary features.
+
+ VPP provides native alternatives for some features. For example, VPP
+ native ACLs provide basic firewall functionality.
diff --git a/docs/vpp/requirements.md b/docs/vpp/requirements.md
new file mode 100644
index 00000000..e1443577
--- /dev/null
+++ b/docs/vpp/requirements.md
@@ -0,0 +1,131 @@
+---
+lastproofread: '2026-02-16'
+---
+
+(vpp-requirements)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane Requirements
+
+VPP Dataplane requires specific hardware. Ensure your system meets these
+prerequisites before enabling VPP:
+
+- **Deployment Platform**
+
+ VPP Dataplane is available on both bare-metal, on-premise virtualized, and
+ cloud deployment platforms.
+
+- **CPU Requirements**
+
+ Regardless of the platform, VPP Dataplane requires a CPU with:
+
+ - SSE4.2 support (available on most modern Intel and AMD CPUs).
+ - At least 4 physical CPU cores for a minimum configuration (more cores
+ recommended for higher throughput).
+
+ :::{important}
+ **Physical Cores vs Logical Cores**
+
+ VPP Dataplane requires 4 *physical* CPU cores, not logical cores.
+ Systems with Simultaneous Multithreading (SMT) or Hyper-Threading (HT)
+ present each physical core as 2 logical cores.
+
+ Cloud providers often display logical cores as "cores" or "vCPUs".
+ For example, a cloud instance showing "4 cores" may have only 2 physical
+ cores with SMT/HT enabled. Always verify the actual physical core count
+ in your cloud provider's documentation.
+ :::
+
+ For virtualized environments, ensure CPU features are passed through to the
+ VM and that sufficient physical cores are allocated.
+
+- **Memory Requirements**
+
+ Memory significantly affects VPP stability. Insufficient RAM can cause
+ initialization failures or prevent the dataplane from starting.
+
+ - Minimum: 8 GB RAM. VyOS will not start the VPP Dataplane if less than 8 GB
+ is available.
+ - Recommended: 16 GB or more (especially for high throughput, many interfaces,
+ or large routing tables).
+
+- **Network Interface Cards (NICs)**
+
+ :::{warning}
+ VyOS supports only specific NICs for the VPP dataplane. Using unsupported
+ hardware may cause activation failures, initialization errors, crashes,
+ or degraded performance.
+ :::
+
+ When enabling VPP, VyOS checks detected network interfaces against a list
+ of validated NICs. Validation is based on the **PCI ID** of the device or
+ the **kernel driver** used by the interface.
+
+ Supported NICs:
+
+ :::{list-table}
+ :widths: 15 18 40 35
+ :header-rows: 1
+
+ * - **Filter Type**
+ - **Filter Value**
+ - **NIC Name/Description**
+ - **Platform Where NIC Can Be Found**
+ * - PCI ID
+ - 15b3:1019
+ - Mellanox Technologies MT28800 Family
+ [ConnectX-5 Ex]
+ - Bare-metal
+ * - PCI ID
+ - 15b3:101d
+ - Mellanox Technologies MT2892 Family
+ [ConnectX-6 Dx]
+ - Bare-metal
+ * - PCI ID
+ - 15b3:101e
+ - Mellanox Technologies ConnectX Family
+ mlx5Gen Virtual Function
+ - Oracle Cloud
+ * - PCI ID
+ - 8086:1592
+ - Intel Corporation Ethernet Controller
+ E810-C for QSFP
+ - Bare-metal
+ * - PCI ID
+ - 1ae0:0042
+ - Google, Inc. Compute Engine Virtual
+ Ethernet [gVNIC]
+ - Google Cloud
+ * - PCI ID
+ - 1af4:1000
+ - Red Hat, Inc. Virtio network device
+ - KVM-based hypervisors, including with
+ Open vSwitch; Google Cloud
+ * - PCI ID
+ - 1d0f:ec20
+ - Amazon.com, Inc. Elastic Network
+ Adapter (ENA)
+ - AWS
+ * - Kernel Driver
+ - hv_netvsc
+ - Microsoft Hyper-V network interface
+ card
+ - Microsoft Azure
+ :::
+
+ If no supported NIC is detected, VPP activation will be rejected.
+
+ In testing or advanced deployments, unsupported hardware can be explicitly
+ allowed in the configuration:
+
+ ```{cfgcmd} set vpp settings allow-unsupported-nics
+ ```
+
+ :::{note}
+ This option bypass the hardware validation checks for the specified
+ devices. Stability and performance are not guaranteed when using
+ unsupported NICs or drivers.
+ :::
diff --git a/docs/vpp/troubleshooting.md b/docs/vpp/troubleshooting.md
new file mode 100644
index 00000000..98715e8e
--- /dev/null
+++ b/docs/vpp/troubleshooting.md
@@ -0,0 +1,474 @@
+---
+lastproofread: '2026-02-18'
+---
+
+(vpp-troubleshooting)=
+
+```{include} /_include/need_improvement.txt
+```
+
+
+# VPP Dataplane Troubleshooting
+
+This page shows you how to collect diagnostic information to troubleshoot VPP
+dataplane issues. These techniques help you resolve problems yourself and
+provide support teams with the information they need.
+
+Collecting the right diagnostic data is crucial for effective troubleshooting.
+
+## Packet Capture (PCAP)
+
+Packet capture is a valuable debugging tool for analyzing network traffic and
+identifying issues with packet processing, routing, and filtering.
+
+`pcap trace` in VPP captures packets at different states: received (rx),
+transmitted (tx), and dropped (drop).
+
+### Starting Packet Capture
+
+**Command syntax:**
+
+```{opcmd} sudo vppctl pcap trace [rx] [tx] [drop] [max \<n\>] [intfc \<interface-name|any\>] [file \<name\>] [max-bytes-per-pkt \<n\>]
+```
+
+**Parameters:**
+- `rx` - Capture received packets
+- `tx` - Capture transmitted packets
+- `drop` - Capture dropped packets
+- `max <n>` - Depth of the local buffer. After `n` packets arrive, the
+ buffer flushes to file. When the next `n` packets arrive, the file
+ overwrites with new data. (default: 100)
+- `intfc <interface-name|any>` - Specify an interface or use `any` for
+ all interfaces (default: any)
+- `file <name>` - Output filename. The PCAP file is stored in the `/tmp/`
+ directory.
+- `max-bytes-per-pkt <n>` - Maximum bytes to capture per packet
+ (must be >= 32, \<= 9000)
+
+**Examples:**
+
+```none
+# Start capturing tx packets with specific parameters
+sudo vppctl pcap trace tx max 35 intfc eth1 file vpp_eth1.pcap
+
+# Capture all packet types from any interface
+sudo vppctl pcap trace rx tx drop max 1000 intfc any file vpp_capture.pcap max-bytes-per-pkt 128
+```
+
+### Monitoring Capture Status
+
+To check the capture status:
+
+```{opcmd} sudo vppctl pcap trace status
+```
+
+This command displays:
+- Whether capture is active
+- Capture parameters
+- Number of packets captured
+- Output file location
+
+### Stopping Packet Capture
+
+:::{warning}
+VPP does not automatically stop packet captures. If left running, captures
+consume resources indefinitely. Always stop captures when you're done
+with them.
+:::
+
+To stop the active packet capture:
+
+```{opcmd} sudo vppctl pcap trace off
+```
+
+Example output when stopping:
+
+```none
+Write 35 packets to /tmp/vpp_eth1.pcap, and stop capture...
+```
+
+**Notes:**
+- PCAP files are stored in the `/tmp/` directory.
+- Existing files are overwritten.
+- If you don't specify a filename, default names are used: `/tmp/rx.pcap`,
+ `/tmp/tx.pcap`, and `/tmp/rxandtx.pcap`.
+- Large captures consume significant disk space—monitor available space.
+- Stop captures promptly to avoid filling storage.
+
+## Packet Tracing
+
+VPP packet tracing shows how packets flow through the VPP processing graph,
+including which nodes process each packet and what transformations occur.
+
+:::{warning}
+Tracing generates large amounts of data, especially on high-traffic
+systems. Limit the number of traced packets to avoid overwhelming the system.
+:::
+
+### Basic Packet Tracing Commands
+
+#### Start tracing
+
+To start tracing packets at a specific graph node:
+
+```{opcmd} sudo vppctl trace add \<input-graph-node\> \<pkts\> [verbose]
+```
+
+- `<input-graph-node>` - Graph node name where tracing starts
+ (for example, `dpdk-input`, `ethernet-input`, or `ip4-input`).
+- `<pkts>` - Number of packets to trace (for example, 100).
+- `[verbose]` - Optional flag to include detailed buffer information in the
+ trace output.
+
+**Common node names for tracing:**
+- `dpdk-input`: Packets received from DPDK interfaces
+- `ethernet-input`: Ethernet frame processing
+- `ip4-input`: IPv4 packet processing
+- `ip6-input`: IPv6 packet processing
+- `ip4-lookup`: IPv4 routing table lookup
+- `ip6-lookup`: IPv6 routing table lookup
+
+#### View traces
+
+After packets are traced, view the results:
+
+```{opcmd} sudo vppctl show trace [max COUNT]
+```
+
+- `[max COUNT]` - Optional limit on number of packets to display
+ (default: all)
+
+#### Clear traces
+
+After reviewing traces, clear them to free up resources:
+
+```{opcmd} sudo vppctl clear trace
+```
+
+#### Example Workflow
+
+```none
+# Add traces for 100 packets on dpdk-input node
+sudo vppctl trace add dpdk-input 100
+
+# Send some traffic, then view results
+sudo vppctl show trace
+
+# Clear traces for next test
+sudo vppctl clear trace
+```
+
+### Understanding Trace Output
+
+Trace output shows how packets flow through VPP processing nodes:
+
+```none
+Packet 1
+
+01:00:09:508438: dpdk-input
+ eth2 rx queue 0
+ buffer 0x8533: current data 0, length 98, buffer-pool 0, ref-count 1, trace handle 0x1000000
+ ext-hdr-valid
+ PKT MBUF: port 1, nb_segs 1, pkt_len 98
+ buf_len 1828, data_len 98, ol_flags 0x0, data_off 128, phys_addr 0x78814d40
+ packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0
+ rss 0x0 fdir.hi 0x0 fdir.lo 0x0
+ IP4: 0c:87:6c:4e:00:01 -> 0c:de:0d:e2:00:02
+ ICMP: 192.168.102.2 -> 192.168.99.3
+ tos 0x00, ttl 64, length 84, checksum 0xb88d dscp CS0 ecn NON_ECN
+ fragment id 0x37c5, flags DONT_FRAGMENT
+ ICMP echo_request checksum 0x64e id 3024
+01:00:09:508449: ethernet-input
+ frame: flags 0x1, hw-if-index 2, sw-if-index 2
+ IP4: 0c:87:6c:4e:00:01 -> 0c:de:0d:e2:00:02
+01:00:09:508455: ip4-input
+ ICMP: 192.168.102.2 -> 192.168.99.3
+ tos 0x00, ttl 64, length 84, checksum 0xb88d dscp CS0 ecn NON_ECN
+ fragment id 0x37c5, flags DONT_FRAGMENT
+ ICMP echo_request checksum 0x64e id 3024
+01:00:09:508458: ip4-sv-reassembly-feature
+ [not-fragmented]
+01:00:09:508460: nat-pre-in2out
+ in2out next_index 2 arc_next_index 10
+01:00:09:508462: nat44-ed-in2out
+ NAT44_IN2OUT_ED_FAST_PATH: sw_if_index 2, next index 10, session 0, translation result 'success' via i2of
+ i2of match: saddr 192.168.102.2 sport 3024 daddr 192.168.99.3 dport 3024 proto ICMP fib_idx 0 rewrite: saddr 192.168.99.1 daddr 192.168.99.3 icmp-id 3024 txfib 0
+ o2if match: saddr 192.168.99.3 sport 3024 daddr 192.168.99.1 dport 3024 proto ICMP fib_idx 0 rewrite: saddr 192.168.99.3 daddr 192.168.102.2 icmp-id 3024 txfib 0
+ search key local 192.168.102.2:3024 remote 192.168.99.3:3024 proto ICMP fib 0 thread-index 0 session-index 0
+01:00:09:508469: ip4-lookup
+ fib 0 dpo-idx 10 flow hash: 0x00000000
+ ICMP: 192.168.99.1 -> 192.168.99.3
+ tos 0x00, ttl 64, length 84, checksum 0xbb8e dscp CS0 ecn NON_ECN
+ fragment id 0x37c5, flags DONT_FRAGMENT
+ ICMP echo_request checksum 0x64e id 3024
+01:00:09:508472: ip4-rewrite
+ tx_sw_if_index 1 dpo-idx 10 : ipv4 via 192.168.99.3 eth1: mtu:1500 next:5 flags:[] 0ccea70400010cde0de200010800 flow hash: 0x00000000
+ 00000000: 0ccea70400010cde0de2000108004500005437c540003f01bc8ec0a86301c0a8
+ 00000020: 63030800064e0bd00d9a52c2d26800000000f4490000000000001011
+01:00:09:508474: eth1-output
+ eth1 flags 0x0038000d
+ IP4: 0c:de:0d:e2:00:01 -> 0c:ce:a7:04:00:01
+ ICMP: 192.168.99.1 -> 192.168.99.3
+ tos 0x00, ttl 63, length 84, checksum 0xbc8e dscp CS0 ecn NON_ECN
+ fragment id 0x37c5, flags DONT_FRAGMENT
+ ICMP echo_request checksum 0x64e id 3024
+01:00:09:508477: eth1-tx
+ eth1 tx queue 0
+ buffer 0x8533: current data 0, length 98, buffer-pool 0, ref-count 1, trace handle 0x1000000
+ ext-hdr-valid
+ natted l2-hdr-offset 0 l3-hdr-offset 14
+ PKT MBUF: port 1, nb_segs 1, pkt_len 98
+ buf_len 1828, data_len 98, ol_flags 0x0, data_off 128, phys_addr 0x78814d40
+ packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0
+ rss 0x0 fdir.hi 0x0 fdir.lo 0x0
+ IP4: 0c:de:0d:e2:00:01 -> 0c:ce:a7:04:00:01
+ ICMP: 192.168.99.1 -> 192.168.99.3
+ tos 0x00, ttl 63, length 84, checksum 0xbc8e dscp CS0 ecn NON_ECN
+ fragment id 0x37c5, flags DONT_FRAGMENT
+ ICMP echo_request checksum 0x64e id 3024
+```
+
+In this example, the trace shows:
+- The packet is received on `eth2` interface at the `dpdk-input` node.
+- It flows through `ethernet-input` and `ip4-input` nodes.
+- NAT translation occurs at the `nat44-ed-in2out` node, changing the source
+ IP.
+- The packet is routed through `ip4-lookup` and `ip4-rewrite` nodes.
+- It transmits out of `eth1` interface at the `eth1-tx` node.
+
+## Additional Diagnostic Information
+
+When reporting issues to support teams or performing advanced troubleshooting,
+collect additional diagnostic information.
+
+### Before/After Traffic Analysis
+
+Before you send traffic:
+
+```none
+sudo vppctl clear hardware-interfaces
+sudo vppctl clear interfaces
+sudo vppctl clear error
+sudo vppctl clear runtime
+```
+
+After you send traffic:
+
+```none
+sudo vppctl show version verbose
+sudo vppctl show hardware-interfaces
+sudo vppctl show interface address
+sudo vppctl show interface
+sudo vppctl show runtime
+sudo vppctl show error
+```
+
+### Core System Information
+
+**Memory and buffer information:**
+
+```none
+sudo vppctl show memory api-segment stats-segment numa-heaps main-heap map verbose
+sudo vppctl show buffers
+sudo vppctl show physmem detail
+sudo vppctl show physmem map
+```
+
+**Runtime and performance data:**
+
+```none
+sudo vppctl show cpu
+sudo vppctl show threads
+sudo vppctl show runtime
+sudo vppctl show node counters
+```
+
+### Protocol-Specific Information
+
+**Layer 2 data (if configured):**
+
+```none
+sudo vppctl show l2fib
+sudo vppctl show bridge-domain
+```
+
+**IPv4 data (if configured):**
+
+```none
+sudo vppctl show ip fib
+sudo vppctl show ip neighbors
+```
+
+**IPv6 data (if configured):**
+
+```none
+sudo vppctl show ip6 fib
+sudo vppctl show ip6 neighbors
+```
+
+**MPLS data (if configured):**
+
+```none
+sudo vppctl show mpls fib
+sudo vppctl show mpls tunnel
+```
+
+## Creating Support Packages
+
+Use the automated diagnostic collection script to gather comprehensive VPP
+troubleshooting information when contacting support or reporting issues.
+
+### VPP Diagnostic Collection Script
+
+Create the diagnostic collection script:
+
+```python
+#!/usr/bin/env python3
+"""VyOS VPP Diagnostic Collection Script"""
+
+import datetime
+import shutil
+import subprocess
+import tarfile
+from pathlib import Path
+
+
+def run_cmd(cmd, output_file, diag_dir):
+ """Run command and save output to file."""
+ try:
+ result = subprocess.run(
+ cmd, shell=True, capture_output=True, text=True, timeout=30
+ )
+ content = f"Command: {cmd}\nExit code: {result.returncode}\nTimestamp: {datetime.datetime.now()}\n{'-' * 50}\n"
+ if result.stdout:
+ content += f"\nSTDOUT:\n{result.stdout}"
+ if result.stderr:
+ content += f"\nSTDERR:\n{result.stderr}"
+ (diag_dir / output_file).write_text(content)
+ except Exception as e:
+ (diag_dir / output_file).write_text(f"Command: {cmd}\nERROR: {e}")
+
+
+def collect_diagnostics():
+ """Collect all VPP diagnostics and create archive."""
+ timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
+ diag_dir = Path.home() / f"vpp-diagnostics-{timestamp}"
+
+ # VPP commands to collect
+ commands = [
+ ("sudo vppctl show version verbose cmdline", "vpp-version.txt"),
+ ("sudo vppctl show hardware-interfaces", "hardware-interfaces.txt"),
+ ("sudo vppctl show interface address", "interface-addresses.txt"),
+ ("sudo vppctl show interface", "interfaces.txt"),
+ ("sudo vppctl show errors", "errors.txt"),
+ ("sudo vppctl show runtime", "runtime.txt"),
+ (
+ "sudo vppctl show memory api-segment stats-segment numa-heaps main-heap map verbose",
+ "memory.txt",
+ ),
+ ("sudo vppctl show buffers", "buffers.txt"),
+ ("sudo vppctl show physmem detail", "physmem.txt"),
+ ("sudo vppctl show physmem map", "physmem-map.txt"),
+ ("sudo vppctl show cpu", "cpu.txt"),
+ ("sudo vppctl show threads", "threads.txt"),
+ ("sudo vppctl show node counters", "node-counters.txt"),
+ ("sudo vppctl show l2fib", "l2fib.txt"),
+ ("sudo vppctl show bridge-domain", "bridge-domains.txt"),
+ ("sudo vppctl show ip fib", "ip4-fib.txt"),
+ ("sudo vppctl show ip neighbors", "ip4-neighbors.txt"),
+ ("sudo vppctl show ip6 fib", "ip6-fib.txt"),
+ ("sudo vppctl show ip6 neighbors", "ip6-neighbors.txt"),
+ ("sudo vppctl show mpls fib", "mpls-fib.txt"),
+ ("sudo vppctl show mpls tunnel", "mpls-tunnels.txt"),
+ ("sudo vppctl show trace", "packet-traces.txt"),
+ ]
+
+ try:
+ # Create diagnostics directory
+ diag_dir.mkdir(parents=True, exist_ok=True)
+
+ # Collect VPP data
+ for cmd, output_file in commands:
+ run_cmd(cmd, output_file, diag_dir)
+
+ # Collect PCAP files
+ pcap_files = list(Path("/tmp").glob("*.pcap"))
+ if pcap_files:
+ pcap_dir = diag_dir / "pcap-files"
+ pcap_dir.mkdir(exist_ok=True)
+ for pcap_file in pcap_files:
+ try:
+ shutil.copy2(pcap_file, pcap_dir)
+ except (PermissionError, OSError):
+ pass
+
+ # Create archive
+ archive_name = f"vpp-diagnostics-{timestamp}.tar.gz"
+ archive_path = Path.home() / archive_name
+
+ with tarfile.open(archive_path, "w:gz") as tar:
+ tar.add(diag_dir, arcname=diag_dir.name)
+
+ # Cleanup
+ shutil.rmtree(diag_dir)
+
+ print(f"VPP diagnostics collected: {archive_path}")
+ return archive_path
+
+ except Exception as e:
+ if diag_dir.exists():
+ shutil.rmtree(diag_dir)
+ print(f"Collection failed: {e}")
+ return None
+
+
+def main():
+ """Main function."""
+ collect_diagnostics()
+
+
+if __name__ == "__main__":
+ main()
+```
+
+Save this script as `/config/scripts/vpp-collect-diagnostics`
+
+### Installation and Usage
+
+**1. Make the script executable**
+
+```{opcmd} sudo chmod +x /config/scripts/vpp-collect-diagnostics
+```
+
+**2. Run VPP diagnostic collection**
+
+The script automatically collects all diagnostics and stores them in your home
+directory.
+
+```{opcmd} /config/scripts/vpp-collect-diagnostics
+```
+
+**3. Generate VyOS tech-support archive separately**
+You can also generate a tech-support archive with system-wide diagnostics:
+
+```{opcmd} generate tech-support archive
+```
+
+
+### What the Script Collects
+
+- **System information**: Version details, build information, command-line
+ parameters.
+- **Interface data**: Hardware interfaces, interface addresses, statistics,
+ and configurations.
+- **Performance metrics**: Runtime statistics, error counters, node counters,
+ CPU, and thread information.
+- **Memory analysis**: Memory usage (API segment, stats segment, NUMA heaps,
+ main heap), buffers, and physical memory.
+- **Layer 2 data**: L2 forwarding table (L2FIB) and bridge domain
+ configurations.
+- **IPv4 data**: IPv4 forwarding table (FIB) and IPv4 neighbor table.
+- **IPv6 data**: IPv6 forwarding table (FIB) and IPv6 neighbor table.
+- **MPLS data**: MPLS forwarding table (FIB) and MPLS tunnel information.
+- **Packet traces**: Captured packet traces (if available).
+- **Packet captures**: PCAP files from the `/tmp` directory (if available).