summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-04-29 06:35:31 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-05-06 16:18:03 +0300
commit9277e2f189115d9c544834f77fb216eaf3711407 (patch)
treee7fda1b7ea00bef67fd8a23cf541cf4067236b93
parente87bfdfc7483af48b54bb8a6993a750c568c2310 (diff)
downloadvyos-documentation-9277e2f189115d9c544834f77fb216eaf3711407.tar.gz
vyos-documentation-9277e2f189115d9c544834f77fb216eaf3711407.zip
feat: activate 106 visual-validated canaries via swap
Imports 105 MD files (plus quick-start already present) from origin/myst/current and adds them to docs/_swap.txt. The selection is the BackstopJS visual-passers cohort: pages with <5% rendered diff vs the live RST docs at docs.vyos.io/en/latest/, filtered to those with an RST counterpart on current and no cmdincludemd usage (template-format reconciliation pending). Local sphinx-build with all 106 swapped: succeeded with 100 warnings (vs 95 baseline). The 5 new warnings are all undefined cross-reference labels, not build failures: - contributing/development.md (missing 'coding-guidelines') - operation/upgrade-recovery.md (3 missing 'how_it_works' / 'cancelling_recovery') - vpp/configuration/dataplane/{buffers,memory,unix}.md (missing 'vpp_config_dataplane_*' labels) Source list: ~/.claude/projects/-Users-vybot-GitHub-vyos-documentation/docs/2026-04-29-myst-conversion-audit/visual-passers-under-5pct.txt BackstopJS report: claude/gifted-hertz-74b9f9 worktree (visual-compare/), 2026-04-23 vs vyos--1838.org.readthedocs.build. πŸ€– Generated by [robots](https://vyos.io)
-rw-r--r--docs/_swap.txt106
-rw-r--r--docs/automation/md-command-scripting.md216
-rw-r--r--docs/automation/md-index.md16
-rw-r--r--docs/automation/md-vyos-ansible.md99
-rw-r--r--docs/automation/md-vyos-govyos.md186
-rw-r--r--docs/automation/md-vyos-napalm.md152
-rw-r--r--docs/automation/md-vyos-netmiko.md76
-rw-r--r--docs/automation/md-vyos-pyvyos.md138
-rw-r--r--docs/automation/terraform/md-index.md28
-rw-r--r--docs/configexamples/md-ansible.md203
-rw-r--r--docs/configexamples/md-bgp-ipv6-unnumbered.md173
-rw-r--r--docs/configexamples/md-dmvpn-dualhub-dualcloud.md523
-rw-r--r--docs/configexamples/md-firewall.md16
-rw-r--r--docs/configexamples/md-fwall-and-bridge.md487
-rw-r--r--docs/configexamples/md-index.md59
-rw-r--r--docs/configexamples/md-lac-lns.md172
-rw-r--r--docs/configexamples/md-nmp.md71
-rw-r--r--docs/configexamples/md-ospf-unnumbered.md117
-rw-r--r--docs/configexamples/md-policy-based-ipsec-and-firewall.md255
-rw-r--r--docs/configexamples/md-segment-routing-isis.md277
-rw-r--r--docs/configexamples/md-site-2-site-cisco.md167
-rw-r--r--docs/configexamples/md-wan-load-balancing.md158
-rw-r--r--docs/configexamples/md-zone-policy.md413
-rw-r--r--docs/configuration/firewall/md-bridge.md673
-rw-r--r--docs/configuration/firewall/md-global-options.md203
-rw-r--r--docs/configuration/firewall/md-groups.md418
-rw-r--r--docs/configuration/firewall/md-ipv6.md1624
-rw-r--r--docs/configuration/interfaces/md-index.md26
-rw-r--r--docs/configuration/loadbalancing/md-index.md15
-rw-r--r--docs/configuration/md-index.md23
-rw-r--r--docs/configuration/nat/md-index.md13
-rw-r--r--docs/configuration/pki/md-index.md551
-rw-r--r--docs/configuration/policy/md-examples.md203
-rw-r--r--docs/configuration/policy/md-index.md47
-rw-r--r--docs/configuration/policy/md-route.md415
-rw-r--r--docs/configuration/protocols/md-index.md25
-rw-r--r--docs/configuration/service/md-index.md29
-rw-r--r--docs/configuration/service/md-snmp.md255
-rw-r--r--docs/configuration/system/md-index.md34
-rw-r--r--docs/configuration/system/md-sysctl.md16
-rw-r--r--docs/configuration/vpn/ipsec/md-index.md11
-rw-r--r--docs/configuration/vpn/ipsec/md-remoteaccess_ipsec.md181
-rw-r--r--docs/configuration/vpn/ipsec/md-troubleshooting_ipsec.md302
-rw-r--r--docs/configuration/vpn/md-index.md14
-rw-r--r--docs/configuration/vpn/md-rsa-keys.md114
-rw-r--r--docs/contributing/md-cla.md45
-rw-r--r--docs/contributing/md-debugging.md204
-rw-r--r--docs/contributing/md-development.md541
-rw-r--r--docs/contributing/md-index.md13
-rw-r--r--docs/contributing/md-issues-features.md122
-rw-r--r--docs/contributing/md-testing.md206
-rw-r--r--docs/contributing/md-upstream-packages.md149
-rw-r--r--docs/installation/cloud/md-index.md10
-rw-r--r--docs/installation/md-bare-metal.md623
-rw-r--r--docs/installation/md-index.md30
-rw-r--r--docs/installation/md-install.md460
-rw-r--r--docs/installation/md-secure-boot.md191
-rw-r--r--docs/installation/virtual/md-docker.md70
-rw-r--r--docs/installation/virtual/md-eve-ng.md14
-rw-r--r--docs/installation/virtual/md-gns3.md191
-rw-r--r--docs/installation/virtual/md-proxmox.md62
-rw-r--r--docs/installation/virtual/md-vmware.md38
-rw-r--r--docs/introducing/md-about.md21
-rw-r--r--docs/introducing/md-history.md127
-rw-r--r--docs/md-404.md13
-rw-r--r--docs/md-index.md113
-rw-r--r--docs/operation/md-boot-options.md52
-rw-r--r--docs/operation/md-index.md12
-rw-r--r--docs/operation/md-password-recovery.md46
-rw-r--r--docs/operation/md-raid.md236
-rw-r--r--docs/operation/md-upgrade-recovery.md63
-rw-r--r--docs/troubleshooting/md-index.md17
-rw-r--r--docs/troubleshooting/md-interfaces.md36
-rw-r--r--docs/troubleshooting/md-monitoring.md148
-rw-r--r--docs/troubleshooting/md-system.md48
-rw-r--r--docs/troubleshooting/md-terminal.md39
-rw-r--r--docs/vpp/configuration/dataplane/md-buffers.md90
-rw-r--r--docs/vpp/configuration/dataplane/md-cpu.md66
-rw-r--r--docs/vpp/configuration/dataplane/md-index.md32
-rw-r--r--docs/vpp/configuration/dataplane/md-interface.md88
-rw-r--r--docs/vpp/configuration/dataplane/md-ipsec.md63
-rw-r--r--docs/vpp/configuration/dataplane/md-ipv6.md41
-rw-r--r--docs/vpp/configuration/dataplane/md-l2learn.md32
-rw-r--r--docs/vpp/configuration/dataplane/md-lcp.md46
-rw-r--r--docs/vpp/configuration/dataplane/md-logging.md56
-rw-r--r--docs/vpp/configuration/dataplane/md-memory.md127
-rw-r--r--docs/vpp/configuration/dataplane/md-unix.md54
-rw-r--r--docs/vpp/configuration/interfaces/md-bonding.md206
-rw-r--r--docs/vpp/configuration/interfaces/md-bridge.md169
-rw-r--r--docs/vpp/configuration/interfaces/md-gre.md140
-rw-r--r--docs/vpp/configuration/interfaces/md-index.md47
-rw-r--r--docs/vpp/configuration/interfaces/md-ipip.md99
-rw-r--r--docs/vpp/configuration/interfaces/md-loopback.md120
-rw-r--r--docs/vpp/configuration/interfaces/md-vxlan.md132
-rw-r--r--docs/vpp/configuration/interfaces/md-xconnect.md94
-rw-r--r--docs/vpp/configuration/md-acl.md485
-rw-r--r--docs/vpp/configuration/md-index.md41
-rw-r--r--docs/vpp/configuration/md-ipfix.md50
-rw-r--r--docs/vpp/configuration/md-sflow.md37
-rw-r--r--docs/vpp/configuration/nat/md-index.md41
-rw-r--r--docs/vpp/configuration/nat/md-nat44.md653
-rw-r--r--docs/vpp/md-description.md81
-rw-r--r--docs/vpp/md-index.md22
-rw-r--r--docs/vpp/md-limitations.md41
-rw-r--r--docs/vpp/md-requirements.md130
-rw-r--r--docs/vpp/md-troubleshooting.md412
106 files changed, 16935 insertions, 0 deletions
diff --git a/docs/_swap.txt b/docs/_swap.txt
index 87552b5d..b4d95536 100644
--- a/docs/_swap.txt
+++ b/docs/_swap.txt
@@ -5,4 +5,110 @@
# Example:
# configuration/firewall/zone
+# Visual-validated canaries (<5% BackstopJS diff vs RST reference, 2026-04-23)
+vpp/configuration/interfaces/xconnect
+vpp/configuration/interfaces/bonding
+automation/command-scripting
+configexamples/ansible
+operation/raid
+vpp/troubleshooting
+contributing/debugging
+configexamples/bgp-ipv6-unnumbered
+configuration/firewall/global-options
+configuration/vpn/ipsec/remoteaccess_ipsec
+vpp/configuration/ipfix
+automation/vyos-govyos
+configexamples/lac-lns
+configexamples/segment-routing-isis
+vpp/configuration/interfaces/gre
+contributing/development
+vpp/configuration/interfaces/vxlan
+configuration/firewall/groups
+configuration/firewall/ipv6
+vpp/configuration/interfaces/loopback
+configexamples/zone-policy
+installation/bare-metal
+troubleshooting/monitoring
+vpp/configuration/dataplane/memory
+configuration/policy/examples
+configexamples/policy-based-ipsec-and-firewall
+vpp/configuration/interfaces/ipip
+configuration/firewall/bridge
+configuration/pki/index
+vpp/configuration/acl
+vpp/description
+automation/vyos-ansible
+contributing/issues-features
+installation/install
+vpp/configuration/dataplane/interface
+vpp/configuration/dataplane/buffers
+vpp/requirements
+configexamples/index
+automation/vyos-napalm
quick-start
+vpp/configuration/dataplane/cpu
+automation/vyos-netmiko
+vpp/configuration/dataplane/ipsec
+configexamples/nmp
+vpp/configuration/dataplane/logging
+vpp/configuration/sflow
+operation/upgrade-recovery
+vpp/configuration/dataplane/unix
+configuration/vpn/rsa-keys
+vpp/configuration/dataplane/lcp
+vpp/configuration/dataplane/ipv6
+vpp/configuration/interfaces/index
+troubleshooting/terminal
+vpp/configuration/nat/index
+contributing/cla
+configexamples/dmvpn-dualhub-dualcloud
+vpp/configuration/dataplane/l2learn
+vpp/limitations
+configuration/service/index
+configuration/system/index
+troubleshooting/system
+troubleshooting/interfaces
+configuration/interfaces/index
+configuration/index
+configuration/service/snmp
+configexamples/firewall
+configuration/policy/index
+automation/terraform/index
+installation/virtual/docker
+configuration/system/sysctl
+vpp/index
+configuration/vpn/index
+contributing/index
+vpp/configuration/interfaces/bridge
+configuration/vpn/ipsec/index
+installation/virtual/proxmox
+configexamples/fwall-and-bridge
+configexamples/wan-load-balancing
+vpp/configuration/nat/nat44
+installation/virtual/vmware
+installation/cloud/index
+automation/vyos-pyvyos
+contributing/testing
+configuration/policy/route
+configuration/loadbalancing/index
+configuration/vpn/ipsec/troubleshooting_ipsec
+introducing/about
+installation/secure-boot
+404
+configexamples/ospf-unnumbered
+introducing/history
+operation/password-recovery
+operation/index
+automation/index
+index
+troubleshooting/index
+installation/virtual/gns3
+operation/boot-options
+installation/index
+configuration/nat/index
+vpp/configuration/index
+vpp/configuration/dataplane/index
+configuration/protocols/index
+installation/virtual/eve-ng
+configexamples/site-2-site-cisco
+contributing/upstream-packages
diff --git a/docs/automation/md-command-scripting.md b/docs/automation/md-command-scripting.md
new file mode 100644
index 00000000..c1e1c239
--- /dev/null
+++ b/docs/automation/md-command-scripting.md
@@ -0,0 +1,216 @@
+---
+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/md-index.md b/docs/automation/md-index.md
new file mode 100644
index 00000000..62e60f84
--- /dev/null
+++ b/docs/automation/md-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/md-vyos-ansible.md b/docs/automation/md-vyos-ansible.md
new file mode 100644
index 00000000..1ced72be
--- /dev/null
+++ b/docs/automation/md-vyos-ansible.md
@@ -0,0 +1,99 @@
+---
+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/md-vyos-govyos.md b/docs/automation/md-vyos-govyos.md
new file mode 100644
index 00000000..f1ad3e91
--- /dev/null
+++ b/docs/automation/md-vyos-govyos.md
@@ -0,0 +1,186 @@
+---
+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/md-vyos-napalm.md b/docs/automation/md-vyos-napalm.md
new file mode 100644
index 00000000..87567593
--- /dev/null
+++ b/docs/automation/md-vyos-napalm.md
@@ -0,0 +1,152 @@
+---
+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/md-vyos-netmiko.md b/docs/automation/md-vyos-netmiko.md
new file mode 100644
index 00000000..2e947b6a
--- /dev/null
+++ b/docs/automation/md-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/md-vyos-pyvyos.md b/docs/automation/md-vyos-pyvyos.md
new file mode 100644
index 00000000..2a9599d7
--- /dev/null
+++ b/docs/automation/md-vyos-pyvyos.md
@@ -0,0 +1,138 @@
+---
+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/terraform/md-index.md b/docs/automation/terraform/md-index.md
new file mode 100644
index 00000000..9f741c35
--- /dev/null
+++ b/docs/automation/terraform/md-index.md
@@ -0,0 +1,28 @@
+---
+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
+
+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/configexamples/md-ansible.md b/docs/configexamples/md-ansible.md
new file mode 100644
index 00000000..3f984812
--- /dev/null
+++ b/docs/configexamples/md-ansible.md
@@ -0,0 +1,203 @@
+---
+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.png
+: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/md-bgp-ipv6-unnumbered.md b/docs/configexamples/md-bgp-ipv6-unnumbered.md
new file mode 100644
index 00000000..36d8cf39
--- /dev/null
+++ b/docs/configexamples/md-bgp-ipv6-unnumbered.md
@@ -0,0 +1,173 @@
+---
+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/md-dmvpn-dualhub-dualcloud.md b/docs/configexamples/md-dmvpn-dualhub-dualcloud.md
new file mode 100644
index 00000000..8f5639b1
--- /dev/null
+++ b/docs/configexamples/md-dmvpn-dualhub-dualcloud.md
@@ -0,0 +1,523 @@
+---
+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.png
+: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
+
+```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
+
+```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
+
+```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
+
+```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/md-firewall.md b/docs/configexamples/md-firewall.md
new file mode 100644
index 00000000..5d170511
--- /dev/null
+++ b/docs/configexamples/md-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/md-fwall-and-bridge.md b/docs/configexamples/md-fwall-and-bridge.md
new file mode 100644
index 00000000..75fb6b25
--- /dev/null
+++ b/docs/configexamples/md-fwall-and-bridge.md
@@ -0,0 +1,487 @@
+---
+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/md-index.md b/docs/configexamples/md-index.md
new file mode 100644
index 00000000..66b3359e
--- /dev/null
+++ b/docs/configexamples/md-index.md
@@ -0,0 +1,59 @@
+(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/md-lac-lns.md b/docs/configexamples/md-lac-lns.md
new file mode 100644
index 00000000..1b020924
--- /dev/null
+++ b/docs/configexamples/md-lac-lns.md
@@ -0,0 +1,172 @@
+---
+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.jpg
+: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.jpg
+: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/md-nmp.md b/docs/configexamples/md-nmp.md
new file mode 100644
index 00000000..9c422172
--- /dev/null
+++ b/docs/configexamples/md-nmp.md
@@ -0,0 +1,71 @@
+---
+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.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp2.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp3.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp4.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp5.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp6.png
+:align: center
+:alt: Network Topology Diagram
+:width: 80%
+```
+
+```{image} /_static/images/nmp7.png
+: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/md-ospf-unnumbered.md b/docs/configexamples/md-ospf-unnumbered.md
new file mode 100644
index 00000000..9c4d5399
--- /dev/null
+++ b/docs/configexamples/md-ospf-unnumbered.md
@@ -0,0 +1,117 @@
+---
+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/md-policy-based-ipsec-and-firewall.md b/docs/configexamples/md-policy-based-ipsec-and-firewall.md
new file mode 100644
index 00000000..00110117
--- /dev/null
+++ b/docs/configexamples/md-policy-based-ipsec-and-firewall.md
@@ -0,0 +1,255 @@
+(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.png
+```
+
+## 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/md-segment-routing-isis.md b/docs/configexamples/md-segment-routing-isis.md
new file mode 100644
index 00000000..76cb726c
--- /dev/null
+++ b/docs/configexamples/md-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.png
+: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/md-site-2-site-cisco.md b/docs/configexamples/md-site-2-site-cisco.md
new file mode 100644
index 00000000..a3b33d21
--- /dev/null
+++ b/docs/configexamples/md-site-2-site-cisco.md
@@ -0,0 +1,167 @@
+(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/md-wan-load-balancing.md b/docs/configexamples/md-wan-load-balancing.md
new file mode 100644
index 00000000..21c78f2a
--- /dev/null
+++ b/docs/configexamples/md-wan-load-balancing.md
@@ -0,0 +1,158 @@
+---
+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.png
+: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.png
+: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/md-zone-policy.md b/docs/configexamples/md-zone-policy.md
new file mode 100644
index 00000000..6018e7fe
--- /dev/null
+++ b/docs/configexamples/md-zone-policy.md
@@ -0,0 +1,413 @@
+---
+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.png
+: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/firewall/md-bridge.md b/docs/configuration/firewall/md-bridge.md
new file mode 100644
index 00000000..42442ee7
--- /dev/null
+++ b/docs/configuration/firewall/md-bridge.md
@@ -0,0 +1,673 @@
+---
+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.png
+:::
+
+
+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.png
+:::
+
+
+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.png
+:::
+
+
+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/md-global-options.md b/docs/configuration/firewall/md-global-options.md
new file mode 100644
index 00000000..adff2d5a
--- /dev/null
+++ b/docs/configuration/firewall/md-global-options.md
@@ -0,0 +1,203 @@
+---
+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.
+```{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/md-groups.md b/docs/configuration/firewall/md-groups.md
new file mode 100644
index 00000000..ceb1783f
--- /dev/null
+++ b/docs/configuration/firewall/md-groups.md
@@ -0,0 +1,418 @@
+---
+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:
+```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:
+```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:
+```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/md-ipv6.md b/docs/configuration/firewall/md-ipv6.md
new file mode 100644
index 00000000..bbbaec16
--- /dev/null
+++ b/docs/configuration/firewall/md-ipv6.md
@@ -0,0 +1,1624 @@
+---
+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.png
+:::
+
+
+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.png
+:::
+
+
+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](https://datatracker.ietf.org/doc/id/draft-chown-6man-tokenised-ipv6-identifiers-02.txt)
+
+
+This function works for both individual addresses and address groups.
+
+
+% stop_vyoslinter
+
+:::{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
+:::
+% start_vyoslinter
+```
+
+```{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](https://wiki.nftables.org/wiki-nftables/index.php/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/interfaces/md-index.md b/docs/configuration/interfaces/md-index.md
new file mode 100644
index 00000000..9082cd80
--- /dev/null
+++ b/docs/configuration/interfaces/md-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/loadbalancing/md-index.md b/docs/configuration/loadbalancing/md-index.md
new file mode 100644
index 00000000..3241edb7
--- /dev/null
+++ b/docs/configuration/loadbalancing/md-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/md-index.md b/docs/configuration/md-index.md
new file mode 100644
index 00000000..3e215502
--- /dev/null
+++ b/docs/configuration/md-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/nat/md-index.md b/docs/configuration/nat/md-index.md
new file mode 100644
index 00000000..35e5d32b
--- /dev/null
+++ b/docs/configuration/nat/md-index.md
@@ -0,0 +1,13 @@
+(nat)=
+
+# NAT
+
+```{toctree}
+:includehidden: true
+:maxdepth: 1
+
+nat44
+nat64
+nat66
+cgnat
+```
diff --git a/docs/configuration/pki/md-index.md b/docs/configuration/pki/md-index.md
new file mode 100644
index 00000000..be59e30f
--- /dev/null
+++ b/docs/configuration/pki/md-index.md
@@ -0,0 +1,551 @@
+---
+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/md-examples.md b/docs/configuration/policy/md-examples.md
new file mode 100644
index 00000000..992aa82c
--- /dev/null
+++ b/docs/configuration/policy/md-examples.md
@@ -0,0 +1,203 @@
+# 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.png
+: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/md-index.md b/docs/configuration/policy/md-index.md
new file mode 100644
index 00000000..29c9ca87
--- /dev/null
+++ b/docs/configuration/policy/md-index.md
@@ -0,0 +1,47 @@
+---
+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/md-route.md b/docs/configuration/policy/md-route.md
new file mode 100644
index 00000000..bf5e552e
--- /dev/null
+++ b/docs/configuration/policy/md-route.md
@@ -0,0 +1,415 @@
+# 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/md-index.md b/docs/configuration/protocols/md-index.md
new file mode 100644
index 00000000..5f190ce1
--- /dev/null
+++ b/docs/configuration/protocols/md-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/service/md-index.md b/docs/configuration/service/md-index.md
new file mode 100644
index 00000000..4018c5be
--- /dev/null
+++ b/docs/configuration/service/md-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/md-snmp.md b/docs/configuration/service/md-snmp.md
new file mode 100644
index 00000000..6a5a66e5
--- /dev/null
+++ b/docs/configuration/service/md-snmp.md
@@ -0,0 +1,255 @@
+(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.png
+: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/system/md-index.md b/docs/configuration/system/md-index.md
new file mode 100644
index 00000000..e0b8a5a1
--- /dev/null
+++ b/docs/configuration/system/md-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/md-sysctl.md b/docs/configuration/system/md-sysctl.md
new file mode 100644
index 00000000..90434fb2
--- /dev/null
+++ b/docs/configuration/system/md-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/vpn/ipsec/md-index.md b/docs/configuration/vpn/ipsec/md-index.md
new file mode 100644
index 00000000..cc40b6f8
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/md-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/md-remoteaccess_ipsec.md b/docs/configuration/vpn/ipsec/md-remoteaccess_ipsec.md
new file mode 100644
index 00000000..de553aec
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/md-remoteaccess_ipsec.md
@@ -0,0 +1,181 @@
+(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/md-troubleshooting_ipsec.md b/docs/configuration/vpn/ipsec/md-troubleshooting_ipsec.md
new file mode 100644
index 00000000..2dfd3fec
--- /dev/null
+++ b/docs/configuration/vpn/ipsec/md-troubleshooting_ipsec.md
@@ -0,0 +1,302 @@
+(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/md-index.md b/docs/configuration/vpn/md-index.md
new file mode 100644
index 00000000..9b06e5df
--- /dev/null
+++ b/docs/configuration/vpn/md-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/md-rsa-keys.md b/docs/configuration/vpn/md-rsa-keys.md
new file mode 100644
index 00000000..b224b514
--- /dev/null
+++ b/docs/configuration/vpn/md-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/contributing/md-cla.md b/docs/contributing/md-cla.md
new file mode 100644
index 00000000..01323111
--- /dev/null
+++ b/docs/contributing/md-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/md-debugging.md b/docs/contributing/md-debugging.md
new file mode 100644
index 00000000..d3b4b513
--- /dev/null
+++ b/docs/contributing/md-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/md-development.md b/docs/contributing/md-development.md
new file mode 100644
index 00000000..8581a28e
--- /dev/null
+++ b/docs/contributing/md-development.md
@@ -0,0 +1,541 @@
+---
+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
+<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/md-index.md b/docs/contributing/md-index.md
new file mode 100644
index 00000000..f26a6b70
--- /dev/null
+++ b/docs/contributing/md-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/md-issues-features.md b/docs/contributing/md-issues-features.md
new file mode 100644
index 00000000..ab235326
--- /dev/null
+++ b/docs/contributing/md-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/md-testing.md b/docs/contributing/md-testing.md
new file mode 100644
index 00000000..5e2371d6
--- /dev/null
+++ b/docs/contributing/md-testing.md
@@ -0,0 +1,206 @@
+---
+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/md-upstream-packages.md b/docs/contributing/md-upstream-packages.md
new file mode 100644
index 00000000..c7da9066
--- /dev/null
+++ b/docs/contributing/md-upstream-packages.md
@@ -0,0 +1,149 @@
+---
+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:
+
+**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`)
+
+**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:
+
+ ```toml
+ build_cmd = "sudo dpkg -i ../*.deb; dpkg-buildpackage -us -uc -tc -b -Ppkg.frr.rtrlib,pkg.frr.lua"
+ ```
+
+**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:
+
+ ```toml
+ pre_build_hook = "echo 'Preparing build environment'"
+ ```
+
+ Multi-line commands example:
+
+ ```toml
+ pre_build_hook = """
+ mkdir -p ../hello/vyos
+ mkdir -p ../vyos
+ cp example.txt ../vyos
+ """
+ ```
+
+ Combined commands and scripts:
+
+ ```toml
+ pre_build_hook = "ls -l; ./script.sh"
+ ```
+
+**apply_patches** (Optional)
+
+: Boolean flag to control whether patches should be applied. Defaults to
+ `True`.
+
+ ```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/installation/cloud/md-index.md b/docs/installation/cloud/md-index.md
new file mode 100644
index 00000000..cf7d447d
--- /dev/null
+++ b/docs/installation/cloud/md-index.md
@@ -0,0 +1,10 @@
+# Cloud Environments
+
+```{toctree}
+:caption: Content
+
+aws
+azure
+gcp
+oracle
+```
diff --git a/docs/installation/md-bare-metal.md b/docs/installation/md-bare-metal.md
new file mode 100644
index 00000000..7017b6a2
--- /dev/null
+++ b/docs/installation/md-bare-metal.md
@@ -0,0 +1,623 @@
+(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.jpg
+:alt: CSE-505-203B Back
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front.jpg
+:alt: CSE-505-203B Front
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_1.jpg
+:alt: CSE-505-203B Open 1
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_2.jpg
+:alt: CSE-505-203B Open 2
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_open_3.jpg
+:alt: CSE-505-203B Open 3
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_1.jpg
+:alt: CSE-505-203B w/ 10GE Open 1
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_2.jpg
+:alt: CSE-505-203B w/ 10GE Open 2
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_3.jpg
+:alt: CSE-505-203B w/ 10GE Open 3
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/1u_vyos_front_10ge_open_4.jpg
+: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.jpg
+:alt: APU4 rack closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_2.jpg
+:alt: APU4 rack front
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_3.jpg
+:alt: 'APU4 rack module #1'
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_4.jpg
+:alt: 'APU4 rack module #2'
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_rack_5.jpg
+:alt: 'APU4 rack module #3 with PSU'
+:scale: 25 %
+:::
+
+##### VyOS custom print
+
+:::{figure} /_static/images/apu4_rack_vyos_print.jpg
+:alt: APU4 custom VyOS powder coat
+:scale: 25 %
+:::
+
+#### Desktop / Bench Top
+
+:::{figure} /_static/images/apu4_desk_1.jpg
+:alt: APU4 desktop closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_2.jpg
+:alt: APU4 desktop closed
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_3.jpg
+:alt: APU4 desktop back
+:scale: 25 %
+:::
+
+:::{figure} /_static/images/apu4_desk_4.jpg
+: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.jpg
+:::
+
+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.jpg
+:::
+
+:::{figure} ../_static/images/480px-Acrosser_ANDJ190N1_Back.jpg
+:::
+
+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.png
+:::
+
+:::{figure} ../_static/images/gowin-02.png
+:::
+
+:::{figure} ../_static/images/gowin-03.png
+:::
+
+:::{figure} ../_static/images/gowin-04.png
+:::
+
+### 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/md-index.md b/docs/installation/md-index.md
new file mode 100644
index 00000000..4256aa9b
--- /dev/null
+++ b/docs/installation/md-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/md-install.md b/docs/installation/md-install.md
new file mode 100644
index 00000000..789b0ec9
--- /dev/null
+++ b/docs/installation/md-install.md
@@ -0,0 +1,460 @@
+---
+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.png
+:::
+
+### 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.
+
+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.
+
+```none
+$ umount /dev/sdX*
+```
+
+4. 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!
+
+```none
+# dd if=/path/to/vyos.iso of=/dev/sdX bs=8M; sync
+```
+
+5. Wait for the operation to complete (bytes copied). On some systems, this
+ may take more than one minute.
+
+6. 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.
+
+7. Power on the computer and ensure it boots from the USB drive
+ (you may need to select the boot device or change boot settings).
+
+8. 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.
+
+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:
+
+```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.
+
+```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/md-secure-boot.md b/docs/installation/md-secure-boot.md
new file mode 100644
index 00000000..3c2013a4
--- /dev/null
+++ b/docs/installation/md-secure-boot.md
@@ -0,0 +1,191 @@
+---
+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.png
+: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.png
+:alt: Disable UEFI secure boot
+:::
+
+Select `Enroll MOK`
+
+:::{figure} /_static/images/uefi_secureboot_03.png
+: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.png
+:alt: Disable UEFI secure boot
+:::
+
+:::{figure} /_static/images/uefi_secureboot_05.png
+:alt: Disable UEFI secure boot
+:::
+
+Now you need to enter the password you defined previously.
+
+:::{figure} /_static/images/uefi_secureboot_06.png
+:alt: Disable UEFI secure boot
+:::
+
+Now reboot and re-enable UEFI Secure Boot.
+
+:::{figure} /_static/images/uefi_secureboot_07.png
+: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/virtual/md-docker.md b/docs/installation/virtual/md-docker.md
new file mode 100644
index 00000000..901483bb
--- /dev/null
+++ b/docs/installation/virtual/md-docker.md
@@ -0,0 +1,70 @@
+---
+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/md-eve-ng.md b/docs/installation/virtual/md-eve-ng.md
new file mode 100644
index 00000000..1ee1c016
--- /dev/null
+++ b/docs/installation/virtual/md-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/md-gns3.md b/docs/installation/virtual/md-gns3.md
new file mode 100644
index 00000000..aeac7bbf
--- /dev/null
+++ b/docs/installation/virtual/md-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.png
+:::
+
+Select **Qemu VMs** and then click the `New` button.
+
+:::{figure} /_static/images/gns3-02.png
+:::
+
+Write a name for your VM, such as "VyOS", and click `Next`.
+
+:::{figure} /_static/images/gns3-03.png
+:::
+
+Select **qemu-system-x86_64** as Quemu binary, then **512MB** of RAM
+and click `Next`.
+
+:::{figure} /_static/images/gns3-04.png
+:::
+
+Select **telnet** as your console type and click `Next`.
+
+:::{figure} /_static/images/gns3-05.png
+:::
+
+Select **New image** for the base disk image of your VM and click
+`Create`.
+
+:::{figure} /_static/images/gns3-06.png
+:::
+
+Use the defaults in the **Binary and format** window and click
+`Next`.
+
+:::{figure} /_static/images/gns3-07.png
+:::
+
+Use the defaults in the **Qcow2 options** window and click `Next`.
+
+:::{figure} /_static/images/gns3-08.png
+:::
+
+Set the disk size to 2000 MiB, and click `Finish` to end the **Quemu
+image creator**.
+
+:::{figure} /_static/images/gns3-09.png
+:::
+
+Click `Finish` to end the **New QEMU VM template** wizard.
+
+:::{figure} /_static/images/gns3-10.png
+:::
+
+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.png
+:::
+
+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.png
+:::
+
+At the **HDD** tab, change the Disk interface to **sata** to speed up
+the boot process.
+
+:::{figure} /_static/images/gns3-13.png
+:::
+
+At the **CD/DVD** tab click on `Browse...` and locate the VyOS image
+you want to install.
+
+:::{figure} /_static/images/gns3-14.png
+:::
+
+:::{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.png
+:::
+
+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.png
+:::
+
+At the general **Preferences** window, click `OK` to save and close.
+
+:::{figure} /_static/images/gns3-17.png
+:::
+
+(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.png
+:::
+
+**CD/DVD** tab: Clear the **Image** entry field to unmount the installation
+image.
+
+:::{figure} /_static/images/gns3-21.png
+:::
+
+Set the number of required network adapters. For example, set it to **4**.
+
+:::{figure} /_static/images/gns3-215.png
+:::
+
+**Advanced** settings tab: Check the **Use as a linked
+base VM** checkbox and click `OK` to save the changes.
+
+:::{figure} /_static/images/gns3-22.png
+:::
+
+The VyOS VM is now ready to be deployed.
diff --git a/docs/installation/virtual/md-proxmox.md b/docs/installation/virtual/md-proxmox.md
new file mode 100644
index 00000000..0eddc2c7
--- /dev/null
+++ b/docs/installation/virtual/md-proxmox.md
@@ -0,0 +1,62 @@
+---
+lastproofread: '2026-02-02'
+---
+
+(proxmox)=
+
+# Running on Proxmox
+
+Proxmox is an open-source platform for virtualization. Visit
+<https://vyos.io> to download a `.qcow2` image that you can import into
+Proxmox.
+
+## Deploy VyOS from CLI with qcow2 image
+
+1. Copy the `.qcow2` image to a temporary directory on the Proxmox server.
+2. The commands assume virtual machine ID 200 is unused and you want
+ the disk stored in a storage pool named `local-lvm`.
+
+```none
+$ qm create 200 --name vyos2 --memory 2048 --net0 virtio,bridge=vmbr0
+$ qm importdisk 200 /path/to/image/vyos-1.2.8-proxmox-2G.qcow2 local-lvm
+$ qm set 200 --virtio0 local-lvm:vm-200-disk-0
+$ qm set 200 --boot order=virtio0
+```
+
+3. You can optionally attach a CDROM with an ISO as a cloud-init data
+ source. The command assumes the ISO is uploaded to the `local`
+ storage pool as `seed.iso`.
+
+```none
+$ qm set 200 --ide2 media=cdrom,file=local:iso/seed.iso
+```
+
+4. Start the virtual machine using the Proxmox GUI or run `qm start 200`.
+
+## Deploy VyOS from CLI with rolling release ISO
+
+1. Download the rolling release ISO from
+ <https://vyos.net/get/nightly-builds/>. Non-subscribers can use the
+ LTS release by building from source. For instructions, see the
+ {ref}`build` section. The VyOS source code repository
+ is available at <https://github.com/vyos/vyos-build>.
+2. Prepare the VM for ISO installation. The commands assume your ISO is
+ in storage pool 'local', you want VM ID '200', and you want to create
+ a new 15GB disk on storage pool 'local-lvm'.
+
+```none
+qm create 200 --name vyos --memory 2048 --net0 virtio,bridge=vmbr0 --ide2 media=cdrom,file=local:iso/live-image-amd64.hybrid.iso --virtio0 local-lvm:15
+```
+
+3. Start the VM using `qm start 200` or the start button in the
+ Proxmox GUI.
+4. Open the virtual console for your VM using the Proxmox web GUI.
+ Login username and password are both `vyos`.
+5. Once booted 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`.
+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/md-vmware.md b/docs/installation/virtual/md-vmware.md
new file mode 100644
index 00000000..34fb2197
--- /dev/null
+++ b/docs/installation/virtual/md-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/md-about.md b/docs/introducing/md-about.md
new file mode 100644
index 00000000..ec4ff30d
--- /dev/null
+++ b/docs/introducing/md-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/md-history.md b/docs/introducing/md-history.md
new file mode 100644
index 00000000..190ee20c
--- /dev/null
+++ b/docs/introducing/md-history.md
@@ -0,0 +1,127 @@
+(history)=
+
+# History
+
+## In the beginning...
+
+There was a network operating system based on Debian GNU/Linux, called
+Vyatta. :sup:`\*` 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) is the codename for the upcoming development
+branch. VyOS 1.5 Circinus 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". :sup:`†`
+
+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.
+
+[\*] From the Sanskrit adjective "Vyātta" (ΰ€΅ΰ₯ΰ€―ΰ€Ύΰ€€ΰ₯ΰ€€), meaning opened.
+
+[†] This is similar to how Linus Torvalds owns the Linux trademark.
diff --git a/docs/md-404.md b/docs/md-404.md
new file mode 100644
index 00000000..f5530747
--- /dev/null
+++ b/docs/md-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/md-index.md b/docs/md-index.md
new file mode 100644
index 00000000..359fea44
--- /dev/null
+++ b/docs/md-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/operation/md-boot-options.md b/docs/operation/md-boot-options.md
new file mode 100644
index 00000000..e686bd3c
--- /dev/null
+++ b/docs/operation/md-boot-options.md
@@ -0,0 +1,52 @@
+---
+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.png
+: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/md-index.md b/docs/operation/md-index.md
new file mode 100644
index 00000000..b3c02571
--- /dev/null
+++ b/docs/operation/md-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/md-password-recovery.md b/docs/operation/md-password-recovery.md
new file mode 100644
index 00000000..c828fb27
--- /dev/null
+++ b/docs/operation/md-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.jpg
+:width: 600
+:::
+
+Next, select **Select boot mode**.
+
+:::{figure} /_static/images/reset-password-step-2.jpg
+:width: 600
+:::
+
+Select **Password reset**.
+
+:::{figure} /_static/images/reset-password-step-3.jpg
+:width: 600
+:::
+
+Boot the desired VyOS version.
+
+:::{figure} /_static/images/reset-password-step-4.jpg
+: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/md-raid.md b/docs/operation/md-raid.md
new file mode 100644
index 00000000..c4160a64
--- /dev/null
+++ b/docs/operation/md-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/md-upgrade-recovery.md b/docs/operation/md-upgrade-recovery.md
new file mode 100644
index 00000000..89b2fd5e
--- /dev/null
+++ b/docs/operation/md-upgrade-recovery.md
@@ -0,0 +1,63 @@
+---
+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/troubleshooting/md-index.md b/docs/troubleshooting/md-index.md
new file mode 100644
index 00000000..31dbd87b
--- /dev/null
+++ b/docs/troubleshooting/md-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/md-interfaces.md b/docs/troubleshooting/md-interfaces.md
new file mode 100644
index 00000000..553cbf90
--- /dev/null
+++ b/docs/troubleshooting/md-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/md-monitoring.md b/docs/troubleshooting/md-monitoring.md
new file mode 100644
index 00000000..4016a949
--- /dev/null
+++ b/docs/troubleshooting/md-monitoring.md
@@ -0,0 +1,148 @@
+# 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/md-system.md b/docs/troubleshooting/md-system.md
new file mode 100644
index 00000000..e855e385
--- /dev/null
+++ b/docs/troubleshooting/md-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/md-terminal.md b/docs/troubleshooting/md-terminal.md
new file mode 100644
index 00000000..0d421972
--- /dev/null
+++ b/docs/troubleshooting/md-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/dataplane/md-buffers.md b/docs/vpp/configuration/dataplane/md-buffers.md
new file mode 100644
index 00000000..80f2f23c
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-buffers.md
@@ -0,0 +1,90 @@
+---
+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/md-cpu.md b/docs/vpp/configuration/dataplane/md-cpu.md
new file mode 100644
index 00000000..9b798631
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-cpu.md
@@ -0,0 +1,66 @@
+---
+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/md-index.md b/docs/vpp/configuration/dataplane/md-index.md
new file mode 100644
index 00000000..f147ebe8
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-index.md
@@ -0,0 +1,32 @@
+---
+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/md-interface.md b/docs/vpp/configuration/dataplane/md-interface.md
new file mode 100644
index 00000000..231a49a9
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-interface.md
@@ -0,0 +1,88 @@
+---
+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/md-ipsec.md b/docs/vpp/configuration/dataplane/md-ipsec.md
new file mode 100644
index 00000000..17e16f8e
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-ipsec.md
@@ -0,0 +1,63 @@
+---
+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/md-ipv6.md b/docs/vpp/configuration/dataplane/md-ipv6.md
new file mode 100644
index 00000000..a72dbbfa
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-ipv6.md
@@ -0,0 +1,41 @@
+---
+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/md-l2learn.md b/docs/vpp/configuration/dataplane/md-l2learn.md
new file mode 100644
index 00000000..fe5deb55
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-l2learn.md
@@ -0,0 +1,32 @@
+---
+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/md-lcp.md b/docs/vpp/configuration/dataplane/md-lcp.md
new file mode 100644
index 00000000..8ffdb7fb
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-lcp.md
@@ -0,0 +1,46 @@
+---
+lastproofread: '2026-02-26'
+---
+
+(vpp-config-dataplane-lcp)=
+
+```{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/md-logging.md b/docs/vpp/configuration/dataplane/md-logging.md
new file mode 100644
index 00000000..e7fcf455
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-logging.md
@@ -0,0 +1,56 @@
+---
+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/md-memory.md b/docs/vpp/configuration/dataplane/md-memory.md
new file mode 100644
index 00000000..4e9d653d
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-memory.md
@@ -0,0 +1,127 @@
+---
+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/md-unix.md b/docs/vpp/configuration/dataplane/md-unix.md
new file mode 100644
index 00000000..ba89d650
--- /dev/null
+++ b/docs/vpp/configuration/dataplane/md-unix.md
@@ -0,0 +1,54 @@
+---
+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/interfaces/md-bonding.md b/docs/vpp/configuration/interfaces/md-bonding.md
new file mode 100644
index 00000000..24868166
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-bonding.md
@@ -0,0 +1,206 @@
+---
+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/md-bridge.md b/docs/vpp/configuration/interfaces/md-bridge.md
new file mode 100644
index 00000000..f7b24b1d
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-bridge.md
@@ -0,0 +1,169 @@
+---
+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/md-gre.md b/docs/vpp/configuration/interfaces/md-gre.md
new file mode 100644
index 00000000..fa91caae
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-gre.md
@@ -0,0 +1,140 @@
+---
+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/md-index.md b/docs/vpp/configuration/interfaces/md-index.md
new file mode 100644
index 00000000..662f37c5
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-index.md
@@ -0,0 +1,47 @@
+---
+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/md-ipip.md b/docs/vpp/configuration/interfaces/md-ipip.md
new file mode 100644
index 00000000..8a847e48
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-ipip.md
@@ -0,0 +1,99 @@
+---
+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/md-loopback.md b/docs/vpp/configuration/interfaces/md-loopback.md
new file mode 100644
index 00000000..bc65338b
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-loopback.md
@@ -0,0 +1,120 @@
+---
+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/md-vxlan.md b/docs/vpp/configuration/interfaces/md-vxlan.md
new file mode 100644
index 00000000..6fa1322a
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-vxlan.md
@@ -0,0 +1,132 @@
+---
+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/md-xconnect.md b/docs/vpp/configuration/interfaces/md-xconnect.md
new file mode 100644
index 00000000..0ee052d2
--- /dev/null
+++ b/docs/vpp/configuration/interfaces/md-xconnect.md
@@ -0,0 +1,94 @@
+---
+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/md-acl.md b/docs/vpp/configuration/md-acl.md
new file mode 100644
index 00000000..59b96070
--- /dev/null
+++ b/docs/vpp/configuration/md-acl.md
@@ -0,0 +1,485 @@
+---
+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/md-index.md b/docs/vpp/configuration/md-index.md
new file mode 100644
index 00000000..7e02ae74
--- /dev/null
+++ b/docs/vpp/configuration/md-index.md
@@ -0,0 +1,41 @@
+---
+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/md-ipfix.md b/docs/vpp/configuration/md-ipfix.md
new file mode 100644
index 00000000..7ed2aee3
--- /dev/null
+++ b/docs/vpp/configuration/md-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/md-sflow.md b/docs/vpp/configuration/md-sflow.md
new file mode 100644
index 00000000..752b8377
--- /dev/null
+++ b/docs/vpp/configuration/md-sflow.md
@@ -0,0 +1,37 @@
+---
+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/configuration/nat/md-index.md b/docs/vpp/configuration/nat/md-index.md
new file mode 100644
index 00000000..4d5c01d1
--- /dev/null
+++ b/docs/vpp/configuration/nat/md-index.md
@@ -0,0 +1,41 @@
+---
+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/md-nat44.md b/docs/vpp/configuration/nat/md-nat44.md
new file mode 100644
index 00000000..a0805ed3
--- /dev/null
+++ b/docs/vpp/configuration/nat/md-nat44.md
@@ -0,0 +1,653 @@
+---
+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/md-description.md b/docs/vpp/md-description.md
new file mode 100644
index 00000000..03ade42c
--- /dev/null
+++ b/docs/vpp/md-description.md
@@ -0,0 +1,81 @@
+---
+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/md-index.md b/docs/vpp/md-index.md
new file mode 100644
index 00000000..06b48792
--- /dev/null
+++ b/docs/vpp/md-index.md
@@ -0,0 +1,22 @@
+---
+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/md-limitations.md b/docs/vpp/md-limitations.md
new file mode 100644
index 00000000..e6d43b85
--- /dev/null
+++ b/docs/vpp/md-limitations.md
@@ -0,0 +1,41 @@
+---
+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/md-requirements.md b/docs/vpp/md-requirements.md
new file mode 100644
index 00000000..7758cabd
--- /dev/null
+++ b/docs/vpp/md-requirements.md
@@ -0,0 +1,130 @@
+---
+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/md-troubleshooting.md b/docs/vpp/md-troubleshooting.md
new file mode 100644
index 00000000..8e3f977c
--- /dev/null
+++ b/docs/vpp/md-troubleshooting.md
@@ -0,0 +1,412 @@
+---
+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).