mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 17:23:00 +02:00
Merge pull request #1367 from kernelkit/wifi-dongles
This commit is contained in:
@@ -104,11 +104,7 @@ jobs:
|
||||
|
||||
- name: Extract ChangeLog entry ...
|
||||
run: |
|
||||
awk '/^-----*$/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|
||||
|head -n -1 > release.md
|
||||
echo "" >> release.md
|
||||
echo "> [!TIP]" >> release.md
|
||||
echo "> **Try Infix in GNS3!** Download the appliance from the [GNS3 Marketplace](https://gns3.com/marketplace/appliances/infix) to test Infix in a virtual network environment without hardware." >> release.md
|
||||
cat doc/ChangeLog.md | ./utils/extract-changelog.sh > release.md
|
||||
cat release.md
|
||||
|
||||
- uses: ncipollo/release-action@v1
|
||||
|
||||
@@ -16,10 +16,12 @@ if something goes wrong. Deploy once, trust forever.
|
||||
|
||||
**🤝 Friendly**
|
||||
Actually easy to use. Auto-generated CLI from standard YANG models comes
|
||||
with built-in help for every command — just hit `?` or TAB for
|
||||
context-aware assistance. Familiar NETCONF/RESTCONF APIs and
|
||||
[comprehensive documentation][4] mean you're never stuck. Whether
|
||||
you're learning networking or managing enterprise infrastructure.
|
||||
with built-in help for every command — just hit <kbd>?</kbd> or
|
||||
<kbd>TAB</kbd> for context-aware assistance.
|
||||
|
||||
Familiar NETCONF & RESTCONF APIs and [comprehensive documentation][4]
|
||||
mean you're never stuck. Whether you're learning networking or managing
|
||||
enterprise infrastructure.
|
||||
|
||||
**🛡️ Secure**
|
||||
Built with security as a foundation, not an afterthought. Minimal
|
||||
@@ -53,27 +55,24 @@ your device, your rules.
|
||||
Consistent tooling from development to production deployment.
|
||||
How about a digital twin using raw Qemu or [GNS3](https://gns3.com/infix)!
|
||||
|
||||
## See It In Action
|
||||
## Quick Example
|
||||
|
||||
Configure an interface in seconds - the CLI guides you with built-in help:
|
||||
|
||||
<details><summary><b>Click Here for an example CLI Session</b></summary>
|
||||
|
||||
```bash
|
||||
admin@infix-12-34-56:/> configure
|
||||
admin@infix-12-34-56:/config/> edit interface eth0
|
||||
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 <TAB>
|
||||
address autoconf bind-ni-name enabled
|
||||
forwarding mtu neighbor
|
||||
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@infix-12-34-56:/config/interface/eth0/> show
|
||||
<pre><code>admin@infix-12-34-56:/> <b>configure</b>
|
||||
admin@infix-12-34-56:/config/> <b>edit interface eth0</b>
|
||||
admin@infix-12-34-56:/config/interface/eth0/> <b>set ipv4</b> <kbd>TAB</kbd>
|
||||
address autoconf bind-ni-name dhcp
|
||||
enabled forwarding mtu neighbor
|
||||
admin@infix-12-34-56:/config/interface/eth0/> <b>set ipv4 address 192.168.2.200 prefix-length 24</b>
|
||||
admin@infix-12-34-56:/config/interface/eth0/> <b>show</b>
|
||||
type ethernet;
|
||||
ipv4 {
|
||||
address 192.168.2.200 {
|
||||
prefix-length 24;
|
||||
}
|
||||
}
|
||||
admin@infix-12-34-56:/config/interface/eth0/> diff
|
||||
admin@infix-12-34-56:/config/interface/eth0/> <b>diff</b>
|
||||
interfaces {
|
||||
interface eth0 {
|
||||
+ ipv4 {
|
||||
@@ -83,25 +82,23 @@ interfaces {
|
||||
+ }
|
||||
}
|
||||
}
|
||||
admin@infix-12-34-56:/config/interface/eth0/> leave
|
||||
admin@infix-12-34-56:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@infix-12-34-56:/config/interface/eth0/> <b>leave</b>
|
||||
admin@infix-12-34-56:/> <b>show interfaces</b>
|
||||
<u>INTERFACE PROTOCOL STATE DATA </u>
|
||||
eth0 ethernet UP 52:54:00:12:34:56
|
||||
ipv4 192.168.2.200/24 (static)
|
||||
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@infix-12-34-56:/> copy running-config startup-config
|
||||
```
|
||||
admin@infix-12-34-56:/> <b>copy running startup</b>
|
||||
</code></pre>
|
||||
|
||||
Notice how TAB completion shows available options, `show` displays
|
||||
current config, and `diff` shows exactly what changed before you
|
||||
commit your changes with the `leave` command.
|
||||
Notice how <kbd>TAB</kbd> completion shows available options, `show`
|
||||
displays current config, and `diff` shows exactly what changed before
|
||||
you commit your changes with the `leave` command.
|
||||
|
||||
</details>
|
||||
|
||||
> [Full CLI documentation →][3]
|
||||
For more information, see [CLI documentation][3].
|
||||
|
||||
## Get Started
|
||||
|
||||
@@ -111,7 +108,7 @@ containers for any custom functionality you need.
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- **Raspberry Pi 4B** - Perfect for home labs, learning, and prototyping
|
||||
- **Raspberry Pi 2B/3B/4B/CM4** - Perfect for home labs, learning, and prototyping
|
||||
- **Banana Pi-R3** - Your next home router and gateway
|
||||
- **NanoPi R2S** - Compact dual-port router in a tiny package
|
||||
- **x86_64** - Run in VMs or on mini PCs for development and testing
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
Board Support
|
||||
=============
|
||||
|
||||
The board support for an architecture always starts with Qemu support,
|
||||
this is what each `linux_defconfig` at the very least sets up. Then
|
||||
each `$BR2_ARCH` has additional BSPs, e.g., Banana Pi BPI-R3.
|
||||
|
||||
The `board/` directory is matched with the `configs/*_defconfigs` and
|
||||
the only execption is `board/common/`, which holds all shared files for
|
||||
Infix builds.
|
||||
|
||||
Each `board/$BR2_ARCH/` can then have vendor/product sub-directories
|
||||
for the BSPs which may contain "fixups" to the base kernel config and
|
||||
any additional device tree files that should be included as well.
|
||||
|
||||
To rebuild a board-specific package, e.g. NanoPi R2S:
|
||||
|
||||
make friendlyarm-nanopi-r2s-rebuild all
|
||||
@@ -353,6 +353,7 @@ CONFIG_SND_SOC=y
|
||||
CONFIG_SND_BCM2835_SOC_I2S=y
|
||||
CONFIG_HID_GENERIC=m
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_DWC2=y
|
||||
|
||||
+59
-3
@@ -88,6 +88,9 @@
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
@@ -95,6 +98,14 @@
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -114,6 +125,37 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
@@ -121,11 +163,25 @@
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-read",
|
||||
"module-name": "ietf-system",
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+59
-3
@@ -226,6 +226,9 @@
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
@@ -233,6 +236,14 @@
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -252,6 +263,37 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
@@ -259,11 +301,25 @@
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-read",
|
||||
"module-name": "ietf-system",
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+59
-3
@@ -126,6 +126,9 @@
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
@@ -133,6 +136,14 @@
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,6 +163,37 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
@@ -159,11 +201,25 @@
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-read",
|
||||
"module-name": "ietf-system",
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -497,6 +497,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
# CONFIG_HID_MONTEREY is not set
|
||||
CONFIG_USB_ULPI_BUS=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_XHCI_HCD=m
|
||||
CONFIG_USB_XHCI_MVEBU=m
|
||||
|
||||
+59
-3
@@ -103,6 +103,9 @@
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
@@ -110,6 +113,14 @@
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -129,6 +140,37 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
@@ -136,11 +178,25 @@
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-read",
|
||||
"module-name": "ietf-system",
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ cleanup()
|
||||
{
|
||||
rm -f "$LED_FILE"
|
||||
rm -f "$PID_FILE"
|
||||
kill %% 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
|
||||
@@ -31,11 +32,13 @@ remaining_time=$((1800 - $(awk '{print int($1)}' /proc/uptime)))
|
||||
|
||||
while [ "$remaining_time" -gt 0 ]; do
|
||||
check_wan
|
||||
sleep 1
|
||||
sleep 1 &
|
||||
wait $!
|
||||
remaining_time=$((remaining_time - 1))
|
||||
done
|
||||
|
||||
while :; do
|
||||
check_wan
|
||||
sleep 5
|
||||
sleep 5 &
|
||||
wait $!
|
||||
done
|
||||
|
||||
@@ -358,6 +358,7 @@ CONFIG_SND_SOC_JH7110_TDM=y
|
||||
CONFIG_SND_SOC_WM8960=y
|
||||
CONFIG_SND_SIMPLE_CARD=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
|
||||
@@ -287,6 +287,7 @@ CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_SOFT_WATCHDOG=y
|
||||
CONFIG_I6300ESB_WDT=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_XHCI_HCD=m
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
CONFIG_USB_UHCI_HCD=m
|
||||
|
||||
+3
-2
@@ -21,10 +21,9 @@ All notable changes to the project are documented in this file.
|
||||
|
||||
### Changes
|
||||
|
||||
- Upgrade Linux kernel to 6.18.7 (LTS)
|
||||
Noteworthy changes and additions in this release are marked below in bold text.
|
||||
|
||||
- Upgrade **Linux kernel to 6.18.6** (LTS)
|
||||
- Upgrade **Linux kernel to 6.18.7** (LTS)
|
||||
- Upgrade Buildroot to 2025.02.10 (LTS)
|
||||
- Upgrade libyang to 4.2.2
|
||||
- Upgrade sysrepo to 4.2.10
|
||||
@@ -59,9 +58,11 @@ Noteworthy changes and additions in this release are marked below in bold text.
|
||||
details, see the updated system configuration documentation, as well as a
|
||||
new dedicated NACM configuration guide
|
||||
- New `show nacm` admin-exec command to inspect access control rules
|
||||
- CLI now supports Ctrl-@ and Ctrl-w/Meta-w to mark and copy test regions
|
||||
- CLI now uses `copy` and `rpc` tools instead of deprecated `sysrepocfg`. The
|
||||
latter now also require the use of `sudo` for `admin` level users
|
||||
- Enhanced `copy` command with XPath filtering support
|
||||
- Kernel now announces details of new USB devices
|
||||
|
||||
### Fixes
|
||||
|
||||
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
# Bridging
|
||||
|
||||
This is the most central part of the system. A bridge is a switch, and
|
||||
a switch is a bridge. In Linux, setting up a bridge with ports
|
||||
connected to physical switch fabric, means you manage the actual switch
|
||||
fabric!
|
||||
|
||||
## MAC Bridge
|
||||
|
||||
In Infix ports are by default not switch ports, unless the customer
|
||||
specific factory config sets it up this way. To enable switching, with
|
||||
offloading if you have a switch chipset, between ports you create a
|
||||
bridge and then add ports to that bridge. Like this:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>up</b>
|
||||
admin@example:/config/> <b>set interface eth0 bridge-port bridge br0</b>
|
||||
admin@example:/config/> <b>set interface eth1 bridge-port bridge br0</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Here we add two ports to bridge `br0`: `eth0` and `eth1`.
|
||||
|
||||
> [!TIP]
|
||||
> The CLI has several built-in helpers governed by convention. E.g.,
|
||||
> naming bridges `brN`, where `N` is a number, the type is *inferred*
|
||||
> automatically and unlocks all bridge features. Other conventions are
|
||||
> `vethNA`, where `N` is a number and `A` is a letter ('a' for access
|
||||
> port and 'b' for bridge side is common), and `ethN.M` for VLAN M on
|
||||
> top of `ethN`, or `dockerN` for a IP masquerading container bridge.
|
||||
>
|
||||
> Note, this inference only works with the CLI, configuring networking
|
||||
> over NETCONF or RESTCONF requires setting the type explicitly.
|
||||
|
||||

|
||||
|
||||
It is possible to create multiple MAC bridges, however, it is
|
||||
currently[^1] _not recommended_ to use more than one MAC bridge on
|
||||
products with Marvell LinkStreet switching ASICs. A VLAN filtering
|
||||
bridge should be used instead.
|
||||
|
||||
## VLAN Filtering Bridge
|
||||
|
||||
By default bridges in Linux do not filter based on VLAN tags. This can
|
||||
be enabled when creating a bridge by adding a port to a VLAN as a tagged
|
||||
or untagged member. Use the port default VID (PVID) setting to control
|
||||
VLAN association for traffic ingressing a port untagged (default PVID:
|
||||
1).
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>up</b>
|
||||
admin@example:/config/> <b>set interface eth0 bridge-port bridge br0</b>
|
||||
admin@example:/config/> <b>set interface eth0 bridge-port pvid 10</b>
|
||||
admin@example:/config/> <b>set interface eth1 bridge-port bridge br0</b>
|
||||
admin@example:/config/> <b>set interface eth1 bridge-port pvid 20</b>
|
||||
admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>set bridge vlans vlan 10 untagged eth0</b>
|
||||
admin@example:/config/interface/br0/> <b>set bridge vlans vlan 20 untagged eth1</b>
|
||||
</code></pre>
|
||||
|
||||
This sets `eth0` as an untagged member of VLAN 10 and `eth1` as an
|
||||
untagged member of VLAN 20. Switching between these ports is thus
|
||||
prohibited.
|
||||
|
||||

|
||||
|
||||
To terminate a VLAN in the switch itself, either for switch management
|
||||
or for routing, the bridge must become a (tagged) member of the VLAN.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/br0/> <b>set bridge vlans vlan 10 tagged br0</b>
|
||||
admin@example:/config/interface/br0/> <b>set bridge vlans vlan 20 tagged br0</b>
|
||||
</code></pre>
|
||||
|
||||
To route or to manage via a VLAN, a VLAN interface needs to be created
|
||||
on top of the bridge, see section [VLAN Interfaces](ethernet.md#vlan-interfaces)
|
||||
for more on this topic.
|
||||
|
||||
> [!NOTE]
|
||||
> In some use-cases only a single management VLAN on the bridge is used.
|
||||
> For the example above, if the bridge itself is an untagged member only
|
||||
> in VLAN 10, IP addresses can be set directly on the bridge without the
|
||||
> need for dedicated VLAN interfaces on top of the bridge.
|
||||
|
||||
|
||||
## Multicast Filtering and Snooping
|
||||
|
||||
Multicast filtering in the bridge is handled by the bridge itself. It
|
||||
can filter both IP multicast and MAC multicast. For IP multicast it
|
||||
also supports "snooping", i.e., IGMP and MLD, to automatically reduce
|
||||
the broadcast effects of multicast. See the next section for a summary
|
||||
of the [terminology used](#terminology-abbreviations).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Currently there is no way to just enable multicast filtering without
|
||||
> also enabling snooping. This may change in the future, in which case
|
||||
> a `filtering` enabled setting will be made available along with the
|
||||
> existing `snooping` setting.
|
||||
|
||||
When creating your bridge you must decide if you need a VLAN filtering
|
||||
bridge or a plain bridge (see previous section). Multicast filtering is
|
||||
supported for either, but take note that it must be enabled and set up
|
||||
per VLAN when VLAN filtering is enabled -- there are no global multicast
|
||||
settings in this operating mode.
|
||||
|
||||
In the following example we have a regular 8-port bridge without VLAN
|
||||
filtering. We focus on the multicast specific settings:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>set bridge multicast snooping</b>
|
||||
admin@example:/config/interface/br0/> <b>set ipv4 address 192.168.2.1 prefix-length 24</b>
|
||||
admin@example:/config/interface/br0/> <b>leave</b>
|
||||
admin@example:/> <b>copy running-config startup-config</b>
|
||||
</code></pre>
|
||||
|
||||
Here we enable snooping and set a static IPv4 address so that the switch
|
||||
can take part in IGMP querier elections. (MLD querier election
|
||||
currently not supported.) We can inspect the current state:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ip multicast</b>
|
||||
Multicast Overview
|
||||
Query Interval (default): 125 sec
|
||||
Router Timeout : 255
|
||||
Fast Leave Ports :
|
||||
Router Ports :
|
||||
Flood Ports : e0, e1, e2, e3, e4, e5, e6, e7
|
||||
|
||||
<span class="header">Interface VID Querier State Interval Timeout Ver</span>
|
||||
br0 192.168.2.1 Up 125 None 3
|
||||
|
||||
<span class="header">Bridge VID Multicast Group Ports </span>
|
||||
br0 224.1.1.1 e3, e2
|
||||
br0 ff02::6a br0
|
||||
</code></pre>
|
||||
|
||||
This is a rather small LAN, so our bridge has already become the elected
|
||||
IGMP querier. We see it is ours because the timeout is `None`, and we
|
||||
recognize the IP address the system has detected, as ours. We can also
|
||||
see two ports that have joined the same IPv4 multicast group, 224.1.1.1,
|
||||
and one join from the system itself for the IPv6 group ff02::6a.
|
||||
|
||||
Now, let us see what happens when we add another bridge, this time with
|
||||
VLAN filtering enabled. We skip the boring parts about how to move
|
||||
ports e4-e7 to `br1` and assign them to VLANs, and again, focus on the
|
||||
multicast bits only:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface br1</b>
|
||||
admin@example:/config/interface/br1/> <b>set bridge vlans vlan 1 multicast snooping</b>
|
||||
admin@example:/config/interface/br1/> <b>set bridge vlans vlan 2 multicast snooping</b>
|
||||
admin@example:/config/interface/br1/> <b>leave</b>
|
||||
admin@example:/> <b>copy running-config startup-config</b>
|
||||
</code></pre>
|
||||
|
||||
Let us see what we get:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ip multicast</b>
|
||||
Multicast Overview
|
||||
Query Interval (default): 125 sec
|
||||
Router Timeout : 255
|
||||
Fast Leave Ports : e5
|
||||
Router Ports : e1, e2, e5, e6, e7
|
||||
Flood Ports : e1, e2, e3, e4, e5, e6, e7, e8
|
||||
|
||||
<span class="header">Interface VID Querier State Interval Timeout Ver</span>
|
||||
br0 192.168.2.1 Up 125 None 3
|
||||
br1 1 0.0.0.0 Up 125 None 3
|
||||
br1 2 0.0.0.0 Up 125 None 3
|
||||
|
||||
<span class="header">Bridge VID Multicast Group Ports </span>
|
||||
br0 224.1.1.1 e2
|
||||
br0 ff02::fb br0
|
||||
br0 ff02::6a br0
|
||||
br0 ff02::1:ff00:0 br0
|
||||
br1 1 224.1.1.1 e5
|
||||
br1 2 224.1.1.1 e7
|
||||
br1 1 ff02::fb br1
|
||||
br1 1 ff02::1:ff00:0 br1
|
||||
</code></pre>
|
||||
|
||||
In this setup we have a lot more going on. Multiple multicast router
|
||||
ports have been detected, and behind the scenes someone has also added
|
||||
an IGMP/MLD fast-leave port.
|
||||
|
||||
### Terminology & Abbreviations
|
||||
|
||||
- **IGMP**: Internet Group Membership Protocol, multicast subscription
|
||||
for IPv4, for details see [RFC3376][]
|
||||
- **MLD**: Multicast Listener Discovery (Protocol), multicast
|
||||
subscription for IPv6, for details see [RFC3810][]
|
||||
- **Unknown/Unregistered multicast**: multicast groups that are *not*
|
||||
in the multicast forwarding database (MDB)
|
||||
- **Known/Registered multicast**: multicast groups that *are* in the
|
||||
multicast forwarding database (MDB)
|
||||
- **MDB**: the multicast forwarding database, consists of filters for
|
||||
multicast groups, directing where multicast is allowed to egress. A
|
||||
filter entry consists of a group and a port list. The bridge filters
|
||||
with a unique database per VLAN, in the same was as the unicast FDB
|
||||
- **Join/Leave**: the terminology used in earlier versions of the two
|
||||
protocols to subscribe and unsubscribe to a multicast group. For
|
||||
more information, see *Membership Report*
|
||||
- **Membership Report** A membership report is sent by end-devices and
|
||||
forwarded by switches to the elected querier on the LAN. They
|
||||
consist of multiple "join" and "leave" operations on groups. They
|
||||
can also, per group, list which senders to allow or block. Switches
|
||||
usually only support the group subscription, and even more common
|
||||
also only support filtering on the MAC level[^2]
|
||||
- **Querier election**: the process of determining who is the elected
|
||||
IGMP/MLD querier on a LAN. Lowest numerical IP address wins, the
|
||||
special address 0.0.0.0 (proxy querier) never wins
|
||||
- **Proxy querier**: when no better querier exists on a LAN, one or
|
||||
more devices can send proxy queries with source address 0.0.0.0 (or
|
||||
:: for IPv6). See **Query Interval**, below, why this is a good
|
||||
thing
|
||||
- **Query interval**: the time in seconds between two queries from an
|
||||
IGMP/MLD querier. It is not uncommon that end-devices do not send
|
||||
their membership reports unless they first hear a query
|
||||
- **Fast Leave**: set on a bridge port to ensure multicast is pruned as
|
||||
quickly as possible when a "leave" membership report is received. In
|
||||
effect, this option marks the port as directly connected to an
|
||||
end-device. When not set (default), a query with timeout is first
|
||||
sent to ensure no unintentional loss of multicast is incurred
|
||||
- **Router port**: can be both configured statically and detected at
|
||||
runtime based on connected devices, usually multicast routers. On
|
||||
a router port *all* multicast is forwarded, both known and unknown
|
||||
- **Flood port**: set on a bridge port (default: enabled) to ensure
|
||||
all *unknown* multicast is forwarded
|
||||
- **Router timeout**: the time in seconds until a querier is deemed to
|
||||
have been lost and another device (switch/router) takes over. In the
|
||||
tables shown above, a *None* timeout is declared when the current
|
||||
device is the active querier
|
||||
|
||||
> [!TIP]
|
||||
> The reason why multicast flooding is enabled by default is to ensure
|
||||
> safe co-existence with MAC multicast, which is common in industrial
|
||||
> networks. It also allows end devices that do not know of IGMP/MLD to
|
||||
> communicate over multicast as long as the group they have chosen is
|
||||
> not used by other IGMP/MLD aware devices on the LAN.
|
||||
>
|
||||
> As soon as an IGMP/MLD membership report to "join" a group is received
|
||||
> the group is added to the kernel MDB and forwarding to other ports
|
||||
> stop. The only exception to this rule is multicast router ports.
|
||||
>
|
||||
> If your MAC multicast forwarding is not working properly, it may be
|
||||
> because an IP multicast group maps to the same MAC address. Please
|
||||
> see [RFC 1112][RFC1112] for details. Use static multicast router
|
||||
> ports, or static multicast MAC filters, to mitigate.
|
||||
|
||||
[RFC1112]: https://www.rfc-editor.org/rfc/rfc1112.html
|
||||
[RFC3376]: https://www.rfc-editor.org/rfc/rfc3376.html
|
||||
[RFC3810]: https://www.rfc-editor.org/rfc/rfc3810.html
|
||||
|
||||
## Forwarding of IEEE Reserved Group Addresses
|
||||
|
||||
Addresses in the range `01:80:C2:00:00:0X` are used by various bridge
|
||||
signaling protocols, and are not forwarded by default. Still, it is
|
||||
sometimes useful to let the bridge forward such packets, this can be
|
||||
done by specifying protocol names or the last address *nibble* as
|
||||
decimal value `0..15`:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface br0 bridge</b>
|
||||
admin@example:/config/interface/br0/bridge/> <b>set ieee-group-forward</b> # Tap the ? key for alternatives
|
||||
[0..15] List of IEEE link-local protocols to forward, e.g., STP, LLDP
|
||||
dot1x 802.1X Port-Based Network Access Control.
|
||||
lacp 802.3 Slow Protocols, e.g., LACP.
|
||||
lldp 802.1AB Link Layer Discovery Protocol (LLDP).
|
||||
stp Spanning Tree (STP/RSPT/MSTP).
|
||||
admin@example:/config/interface/br0/bridge/> <b>set ieee-group-forward</b>
|
||||
</code></pre>
|
||||
|
||||
The following example configures bridge *br0* to forward LLDP packets.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/br0/bridge/> <b>set ieee-group-forward lldp</b>
|
||||
admin@example:/config/interface/br0/bridge/>
|
||||
</code></pre>
|
||||
|
||||
[^1]: MAC bridges on Marvell Linkstreet devices are currently limited to
|
||||
a single MAC database, this may be a problem if the same MAC address
|
||||
appears in different MAC bridges.
|
||||
[^2]: For example, IPv4 groups are mapped to MAC multicast addresses by
|
||||
mapping the low-order 23-bits of the IP address in the low-order 23
|
||||
bits of the Ethernet address 01:00:5E:00:00:00. Meaning, more than
|
||||
one IP multicast group maps to the same MAC multicast group.
|
||||
@@ -16,16 +16,21 @@ CLI has several keybindings, most significant first:
|
||||
| Meta-b | Ctrl-Left | Move cursor back one word |
|
||||
| Ctrl-e | End | Move cursor to end of line |
|
||||
| Ctrl-a | Home | Move cursor to beginning of line |
|
||||
| Ctrl-@ | Ctrl-Space | Mark current position for region operations |
|
||||
| Meta w | | Copy region to kill buffer without deleting |
|
||||
| Ctrl-k | | Kill (cut) text from cursor to end of line |
|
||||
| Ctrl-u | | Delete (cut) entire line |
|
||||
| Ctrl-y | | Yank (paste) from kill buffer to cursor |
|
||||
| Meta-. | | Yank (paste) last argument from previous line |
|
||||
| Ctrl-w | Meta-Backspace | Delete (cut) word to the left |
|
||||
| Ctrl-w | | Kill region if mark set, else kill word backward |
|
||||
| | Meta-Backspace | Delete (cut) word to the left |
|
||||
| | Meta-Delete | Delete (cut) word to the right |
|
||||
| Ctrl-l | | Clear screen and refresh current line |
|
||||
| Ctrl-p | Up arrow | History, previous command |
|
||||
| Ctrl-n | Down arrow | History, next command |
|
||||
| Ctrl-q | Ctrl-v | Insert next character literally |
|
||||
| Ctrl-r | | History, reversed interactive search (i-search) |
|
||||
| Ctrl-t | | Transpose/Swap characters before and at cursor |
|
||||
|
||||
## What is Meta?
|
||||
|
||||
|
||||
+279
-250
@@ -92,17 +92,18 @@ your container image and application to run.
|
||||
|
||||
Classic Hello World:
|
||||
|
||||
admin@example:/> container run docker://hello-world
|
||||
Starting docker://hello-world :: use Ctrl-p Ctrl-q to detach
|
||||
Trying to pull docker.io/library/hello-world:latest...
|
||||
Getting image source signatures
|
||||
Copying blob c1ec31eb5944 done
|
||||
Copying config d2c94e258d done
|
||||
Writing manifest to image destination
|
||||
Storing signatures
|
||||
<pre class="cli"><code>admin@example:/> <b>container run docker://hello-world</b>
|
||||
Starting docker://hello-world :: use Ctrl-p Ctrl-q to detach
|
||||
Trying to pull docker.io/library/hello-world:latest...
|
||||
Getting image source signatures
|
||||
Copying blob c1ec31eb5944 done
|
||||
Copying config d2c94e258d done
|
||||
Writing manifest to image destination
|
||||
Storing signatures
|
||||
|
||||
Hello from Docker!
|
||||
This message shows that your installation appears to be working correctly.
|
||||
Hello from Docker!
|
||||
This message shows that your installation appears to be working correctly.
|
||||
</code></pre>
|
||||
|
||||
### Example: Web Server
|
||||
|
||||
@@ -110,22 +111,24 @@ A web server with [nginx][], using standard docker bridge. Podman will
|
||||
automatically create a VETH pair for us, connecting the container to the
|
||||
`docker0` bridge:
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface docker0
|
||||
admin@example:/config/interface/docker0/> set container-network
|
||||
admin@example:/config/interface/docker0/> end
|
||||
admin@example:/config/> edit container web
|
||||
admin@example:/config/container/web/> set image docker://nginx:alpine
|
||||
admin@example:/config/container/web/> set network publish 8080:80
|
||||
admin@example:/config/container/web/> set network interface docker0
|
||||
admin@example:/config/container/web/> set volume cache target /var/cache
|
||||
admin@example:/config/container/web/> leave
|
||||
admin@example:/> show container
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface docker0</b>
|
||||
admin@example:/config/interface/docker0/> <b>set container-network</b>
|
||||
admin@example:/config/interface/docker0/> <b>end</b>
|
||||
admin@example:/config/> <b>edit container web</b>
|
||||
admin@example:/config/container/web/> <b>set image docker://nginx:alpine</b>
|
||||
admin@example:/config/container/web/> <b>set network publish 8080:80</b>
|
||||
admin@example:/config/container/web/> <b>set network interface docker0</b>
|
||||
admin@example:/config/container/web/> <b>set volume cache target /var/cache</b>
|
||||
admin@example:/config/container/web/> <b>leave</b>
|
||||
admin@example:/> <b>show container</b>
|
||||
</code></pre>
|
||||
|
||||
Exit to the shell and verify the service with curl, or try to attach
|
||||
to your device's IP address using your browser:
|
||||
|
||||
admin@example:~$ curl http://localhost:8080
|
||||
<pre class="cli"><code>admin@example:~$ <b>curl http://localhost:8080</b>
|
||||
</code></pre>
|
||||
|
||||
or connect to port 8080 of your running Infix system with a browser.
|
||||
See the following sections for how to add more interfaces and manage
|
||||
@@ -142,31 +145,32 @@ how to upgrade to a newer base image.
|
||||
|
||||
The CLI help shows:
|
||||
|
||||
admin@example:/config/container/system/> help image
|
||||
NAME
|
||||
image <string>
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>help image</b>
|
||||
<b>NAME</b>
|
||||
image <string>
|
||||
|
||||
DESCRIPTION
|
||||
Docker image for the container: [transport]name[:tag|@digest]
|
||||
<b>DESCRIPTION</b>
|
||||
Docker image for the container: [transport]name[:tag|@digest]
|
||||
|
||||
quay.io/username/myimage -- Pull myimage:latest
|
||||
docker://busybox -- Pull busybox:latest from Docker Hub
|
||||
docker://ghcr.io/usr/img -- Pull img:latest from GitHub packages
|
||||
dir:/media/usb/myimage:1.1 -- Use myimage v1.1 from USB media
|
||||
docker-archive:/tmp/archive -- Use archive:latest from tarball
|
||||
oci-archive:/lib/oci/archive -- Use archive:latest from OCI archive
|
||||
May be in .tar or .tar.gz format
|
||||
quay.io/username/myimage -- Pull myimage:latest
|
||||
docker://busybox -- Pull busybox:latest from Docker Hub
|
||||
docker://ghcr.io/usr/img -- Pull img:latest from GitHub packages
|
||||
dir:/media/usb/myimage:1.1 -- Use myimage v1.1 from USB media
|
||||
docker-archive:/tmp/archive -- Use archive:latest from tarball
|
||||
oci-archive:/lib/oci/archive -- Use archive:latest from OCI archive
|
||||
May be in .tar or .tar.gz format
|
||||
|
||||
Additionally, the following URIs are also supported for setups
|
||||
that do not use a HUB or similar. Recommend using 'checksum'!
|
||||
Additionally, the following URIs are also supported for setups
|
||||
that do not use a HUB or similar. Recommend using 'checksum'!
|
||||
|
||||
ftp://addr/path/to/archive -- Downloaded using wget
|
||||
http://addr/path/to/archive -- Downloaded using curl
|
||||
https://addr/path/to/archive -- Downloaded using curl
|
||||
ftp://addr/path/to/archive -- Downloaded using wget
|
||||
http://addr/path/to/archive -- Downloaded using curl
|
||||
https://addr/path/to/archive -- Downloaded using curl
|
||||
|
||||
Note: if a remote repository cannot be reached, the creation of the
|
||||
container will be put on a queue that retries pull every time
|
||||
there is a route change in the host's system.
|
||||
Note: if a remote repository cannot be reached, the creation of the
|
||||
container will be put on a queue that retries pull every time
|
||||
there is a route change in the host's system.
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> The built-in help system in the CLI is generated from the YANG model,
|
||||
@@ -198,26 +202,28 @@ mind.
|
||||
|
||||
**Shell OCI Example:**
|
||||
|
||||
admin@example:~$ cd /var/tmp/
|
||||
admin@example:/var/tmp$ sudo wget https://github.com/kernelkit/curiOS/releases/download/edge/curios-oci-amd64.tar.gz
|
||||
Connecting to github.com (140.82.121.3:443)
|
||||
wget: note: TLS certificate validation not implemented
|
||||
Connecting to objects.githubusercontent.com (185.199.109.133:443)
|
||||
saving to 'curios-oci-amd64.tar.gz'
|
||||
curios-oci-amd64.tar 100% |*********************************| 7091k 0:00:00 ETA
|
||||
'curios-oci-amd64.tar.gz' saved
|
||||
admin@example:/var/tmp$ ll
|
||||
total 7104
|
||||
drwxr-xr-x 3 root root 4096 Mar 27 14:22 ./
|
||||
drwxr-xr-x 14 root root 4096 Mar 27 11:57 ../
|
||||
-rw-r--r-- 1 root root 7261785 Mar 27 14:22 curios-oci-amd64.tar.gz
|
||||
drwx------ 6 frr frr 4096 Mar 27 11:57 frr/
|
||||
<pre class="cli"><code>admin@example:~$ <b>cd /var/tmp/</b>
|
||||
admin@example:/var/tmp$ <b>sudo wget https://github.com/kernelkit/curiOS/releases/download/edge/curios-oci-amd64.tar.gz</b>
|
||||
Connecting to github.com (140.82.121.3:443)
|
||||
wget: note: TLS certificate validation not implemented
|
||||
Connecting to objects.githubusercontent.com (185.199.109.133:443)
|
||||
saving to 'curios-oci-amd64.tar.gz'
|
||||
curios-oci-amd64.tar 100% |*********************************| 7091k 0:00:00 ETA
|
||||
'curios-oci-amd64.tar.gz' saved
|
||||
admin@example:/var/tmp$ <b>ll</b>
|
||||
total 7104
|
||||
drwxr-xr-x 3 root root 4096 Mar 27 14:22 ./
|
||||
drwxr-xr-x 14 root root 4096 Mar 27 11:57 ../
|
||||
-rw-r--r-- 1 root root 7261785 Mar 27 14:22 curios-oci-amd64.tar.gz
|
||||
drwx------ 6 frr frr 4096 Mar 27 11:57 frr/
|
||||
</code></pre>
|
||||
|
||||
Importing the image into Podman can be done either from the CLI
|
||||
admin-exec context ...
|
||||
|
||||
admin@example:/var/tmp$ cli
|
||||
admin@example:/> container load /var/tmp/curios-oci-amd64.tar.gz name curios:edge
|
||||
<pre class="cli"><code>admin@example:/var/tmp$ <b>cli</b>
|
||||
admin@example:/> <b>container load /var/tmp/curios-oci-amd64.tar.gz name curios:edge</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> The `name curios:edge` is the tag you give the imported (raw) archive
|
||||
@@ -227,31 +233,33 @@ admin-exec context ...
|
||||
... or by giving the container configuration the full path to the OCI
|
||||
archive, which helps greatly with container upgrades (see below):
|
||||
|
||||
admin@example:/config/container/system/> set image oci-archive:/var/tmp/curios-oci-amd64.tar.gz
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>set image oci-archive:/var/tmp/curios-oci-amd64.tar.gz</b>
|
||||
</code></pre>
|
||||
|
||||
**Checksum Example:**
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit container sys
|
||||
admin@example:/config/container/sys/> set hostname sys
|
||||
admin@example:/config/container/sys/> set image ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz
|
||||
admin@example:/config/container/sys/> set checksum
|
||||
md5 sha256 sha512
|
||||
admin@example:/config/container/sys/> set checksum sha256 4f01077036527498ed910f1a3e80645ae3eff629d10043cf80ebc6850c99c629
|
||||
admin@example:/config/container/sys/> leave
|
||||
admin@example:/> copy running-config startup-config
|
||||
admin@example:/> show container
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
b02e945c43c9 localhost/curios-oci-amd64-v24.05.0:latest 5 seconds ago Up 5 seconds sys
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit container sys</b>
|
||||
admin@example:/config/container/sys/> <b>set hostname sys</b>
|
||||
admin@example:/config/container/sys/> <b>set image ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz</b>
|
||||
admin@example:/config/container/sys/> <b>set checksum</b>
|
||||
md5 sha256 sha512
|
||||
admin@example:/config/container/sys/> <b>set checksum sha256 4f01077036527498ed910f1a3e80645ae3eff629d10043cf80ebc6850c99c629</b>
|
||||
admin@example:/config/container/sys/> <b>leave</b>
|
||||
admin@example:/> <b>copy running-config startup-config</b>
|
||||
admin@example:/> <b>show container</b>
|
||||
<span class="header">NAME STATUS NETWORK MEMORY (KiB) CPU%</span>
|
||||
sys Up 5 seconds 72/512 0.02
|
||||
|
||||
admin@example:/> show log
|
||||
...
|
||||
Nov 20 07:24:56 example container[5040]: Fetching ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz
|
||||
Nov 20 07:24:56 example container[5040]: curios-oci-amd64-v24.05.0.tar.gz downloaded successfully.
|
||||
Nov 20 07:24:56 example container[5040]: curios-oci-amd64-v24.05.0.tar.gz checksum verified OK.
|
||||
Nov 20 07:24:57 example container[5040]: Cleaning up extracted curios-oci-amd64-v24.05.0
|
||||
Nov 20 07:24:57 example container[5040]: podman create --name sys --conmon-pidfile=/run/container:sys.pid --read-only --replace --quiet --cgroup-parent=containers --restart=always --systemd=false --tz=local --hostname sys --log-driver k8s-file --log-opt path=/run/containers/sys.fifo --network=none curios-oci-amd64-v24.05.0
|
||||
Nov 20 07:24:57 example container[3556]: b02e945c43c9bce2c4be88e31d6f63cfdb1a3c8bdd02179376eb059a49ae05e4
|
||||
admin@example:/> <b>show log</b>
|
||||
...
|
||||
Nov 20 07:24:56 example container[5040]: Fetching ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz
|
||||
Nov 20 07:24:56 example container[5040]: curios-oci-amd64-v24.05.0.tar.gz downloaded successfully.
|
||||
Nov 20 07:24:56 example container[5040]: curios-oci-amd64-v24.05.0.tar.gz checksum verified OK.
|
||||
Nov 20 07:24:57 example container[5040]: Cleaning up extracted curios-oci-amd64-v24.05.0
|
||||
Nov 20 07:24:57 example container[5040]: podman create --name sys --conmon-pidfile=/run/container:sys.pid --read-only --replace --quiet --cgroup-parent=containers --restart=always --systemd=false --tz=local --hostname sys --log-driver k8s-file --log-opt path=/run/containers/sys.fifo --network=none curios-oci-amd64-v24.05.0
|
||||
Nov 20 07:24:57 example container[3556]: b02e945c43c9bce2c4be88e31d6f63cfdb1a3c8bdd02179376eb059a49ae05e4
|
||||
</code></pre>
|
||||
|
||||
|
||||
Understanding Image Tags
|
||||
@@ -359,12 +367,11 @@ writable paths provided by Podman (`/dev`, `/dev/shm`, `/run`, `/tmp`,
|
||||
When using version-specific tags, you upgrade by explicitly changing the
|
||||
image reference in your configuration:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit container web
|
||||
admin@example:/config/container/web/> set image docker://nginx:1.25.3
|
||||
admin@example:/config/container/web/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit container web</b>
|
||||
admin@example:/config/container/web/> <b>set image docker://nginx:1.25.3</b>
|
||||
admin@example:/config/container/web/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**What happens:**
|
||||
|
||||
@@ -375,29 +382,27 @@ admin@example:/config/container/web/> leave
|
||||
|
||||
**Example:** Upgrading from one version to another:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit container system
|
||||
admin@example:/config/container/system/> show image
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit container system</b>
|
||||
admin@example:/config/container/system/> <b>show image</b>
|
||||
image ghcr.io/kernelkit/curios:v24.11.0;
|
||||
admin@example:/config/container/system/> set image ghcr.io/kernelkit/curios:v24.12.0
|
||||
admin@example:/config/container/system/> leave
|
||||
admin@example:/> show log
|
||||
admin@example:/config/container/system/> <b>set image ghcr.io/kernelkit/curios:v24.12.0</b>
|
||||
admin@example:/config/container/system/> <b>leave</b>
|
||||
admin@example:/> <b>show log</b>
|
||||
...
|
||||
Dec 13 14:32:15 example container[1523]: Pulling ghcr.io/kernelkit/curios:v24.12.0...
|
||||
Dec 13 14:32:18 example container[1523]: Stopping old container instance...
|
||||
Dec 13 14:32:19 example container[1523]: Creating new container with updated image...
|
||||
Dec 13 14:32:20 example container[1523]: Container system started successfully
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### Method 2: Upgrading Mutable Tags
|
||||
|
||||
For images using mutable tags like `:latest` or `:edge`, use the
|
||||
`container upgrade` command:
|
||||
|
||||
```
|
||||
admin@example:/> container upgrade NAME
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>container upgrade NAME</b>
|
||||
</code></pre>
|
||||
|
||||
This command:
|
||||
|
||||
@@ -408,8 +413,7 @@ This command:
|
||||
|
||||
**Example using registry:**
|
||||
|
||||
```
|
||||
admin@example:/> container upgrade system
|
||||
<pre class="cli"><code>admin@example:/> <b>container upgrade system</b>
|
||||
system
|
||||
Trying to pull ghcr.io/kernelkit/curios:edge...
|
||||
Getting image source signatures
|
||||
@@ -420,7 +424,7 @@ Storing signatures
|
||||
0cb6059c0f4111650ddbc7dbc4880c64ab8180d4bdbb7269c08034defc348f17
|
||||
system: not running.
|
||||
59618cc3c84bef341c1f5251a62be1592e459cc990f0b8864bc0f5be70e60719
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Example using local OCI archive:**
|
||||
|
||||
@@ -429,11 +433,10 @@ new archive onto the system (see Container Images section above), then,
|
||||
provided the `oci-archive:/path/to/archive` format is used in your
|
||||
configuration, call the upgrade command:
|
||||
|
||||
```
|
||||
admin@example:/> container upgrade system
|
||||
<pre class="cli"><code>admin@example:/> <b>container upgrade system</b>
|
||||
Upgrading container system with local archive: oci-archive:/var/tmp/curios-oci-amd64.tar.gz ...
|
||||
7ab4a07ee0c6039837419b7afda4da1527a70f0c60c0f0ac21cafee05ba24b52
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
OCI archives can also be fetched from ftp/http/https URLs. In that case,
|
||||
the upgrade works the same way as a registry image — Infix downloads the
|
||||
@@ -472,15 +475,16 @@ occasions where they are too restricted and users start looking for the
|
||||
|
||||
For example, a system container from which `ping` does not work:
|
||||
|
||||
admin@example:/config/container/system/> edit capabilities
|
||||
admin@example:/config/container/system/capabilities/> set add net_raw
|
||||
admin@example:/config/container/system/capabilities/> end
|
||||
admin@infix-00-00-00:/config/container/system/> show
|
||||
...
|
||||
capabilities {
|
||||
add net_raw;
|
||||
}
|
||||
...
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>edit capabilities</b>
|
||||
admin@example:/config/container/system/capabilities/> <b>set add net_raw</b>
|
||||
admin@example:/config/container/system/capabilities/> <b>end</b>
|
||||
admin@infix-00-00-00:/config/container/system/> <b>show</b>
|
||||
...
|
||||
capabilities {
|
||||
add net_raw;
|
||||
}
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
Infix supports a subset of all [capabilities][6] that are relevant for
|
||||
containers. Please note, that this is an advanced topic that require
|
||||
@@ -504,12 +508,13 @@ Resource limits are set per container and include:
|
||||
|
||||
Example configuration limiting a container to 512 MiB of memory and 1.5 CPU cores:
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit container web
|
||||
admin@example:/config/container/web/> edit resource-limit
|
||||
admin@example:/config/container/web/resource-limit/> set memory 524288
|
||||
admin@example:/config/container/web/resource-limit/> set cpu 1500
|
||||
admin@example:/config/container/web/resource-limit/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit container web</b>
|
||||
admin@example:/config/container/web/> <b>edit resource-limit</b>
|
||||
admin@example:/config/container/web/resource-limit/> <b>set memory 524288</b>
|
||||
admin@example:/config/container/web/resource-limit/> <b>set cpu 1500</b>
|
||||
admin@example:/config/container/web/resource-limit/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Common CPU limit examples:
|
||||
|
||||
@@ -521,8 +526,9 @@ Common CPU limit examples:
|
||||
|
||||
Runtime resource usage statistics are available in the operational datastore:
|
||||
|
||||
admin@example:/> show container web
|
||||
...
|
||||
<pre class="cli"><code>admin@example:/> <b>show container web</b>
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
Use `show container usage` to see resource consumption across all containers,
|
||||
including memory, CPU, block I/O, network I/O, and process counts.
|
||||
@@ -563,10 +569,11 @@ container use seem to be so simple.
|
||||
|
||||
All interface configuration is done in configure context.
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config> edit interface docker0
|
||||
admin@example:/config/interface/docker0/> set container-network
|
||||
admin@example:/config/interface/docker0/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config> <b>edit interface docker0</b>
|
||||
admin@example:/config/interface/docker0/> <b>set container-network</b>
|
||||
admin@example:/config/interface/docker0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
There is more to this story. When using the CLI, and sticking to common
|
||||
interface nomenclature, Infix helps you with some of the boring stuff.
|
||||
@@ -574,8 +581,9 @@ E.g., creating a new interface with a name like `brN` or `dockerN`
|
||||
automatically *infers* the interface types, which you would otherwise
|
||||
have to set manually:
|
||||
|
||||
admin@example:/config/interface/docker0/> set type bridge
|
||||
admin@example:/config/interface/docker0/> set container-network type bridge
|
||||
<pre class="cli"><code>admin@example:/config/interface/docker0/> <b>set type bridge</b>
|
||||
admin@example:/config/interface/docker0/> <b>set container-network type bridge</b>
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> When configuring the system via an API such as NETCONF or RESTCONF, no
|
||||
@@ -601,16 +609,17 @@ other networking parameters (DNS, default route) are set up.
|
||||
Some of the defaults of a container `bridge` can be changed, e.g.,
|
||||
instead of `set container-network type bridge`, above, do:
|
||||
|
||||
admin@example:/config/interface/docker0/> edit container-network
|
||||
admin@example:/config/interface/docker0/container-network/> set type bridge
|
||||
admin@example:/config/interface/docker0/container-network/> edit subnet 192.168.0.0/16
|
||||
admin@example:/config/interface/docker0/container-network/subnet/192.168.0.0/16/> set gateway 192.168.255.254
|
||||
admin@example:/config/interface/docker0/container-network/subnet/192.168.0.0/16/> end
|
||||
admin@example:/config/interface/docker0/container-network/> edit route 10.0.10.0/24
|
||||
admin@example:/config/interface/docker0/container-network/route/10.0.10.0/24/> set gateway 192.168.10.254
|
||||
admin@example:/config/interface/docker0/container-network/route/10.0.10.0/24/> end
|
||||
admin@example:/config/interface/docker0/container-network/> end
|
||||
admin@example:/config/interface/docker0/> leave
|
||||
<pre class="cli"><code>admin@example:/config/interface/docker0/> <b>edit container-network</b>
|
||||
admin@example:/config/…/container-network/> <b>set type bridge</b>
|
||||
admin@example:/config/…/container-network/> <b>edit subnet 192.168.0.0/16</b>
|
||||
admin@example:/config/…/subnet/192.168.0.0/16/> <b>set gateway 192.168.255.254</b>
|
||||
admin@example:/config/…/subnet/192.168.0.0/16/> <b>end</b>
|
||||
admin@example:/config/…/container-network/> <b>edit route 10.0.10.0/24</b>
|
||||
admin@example:/config/…/route/10.0.10.0/24/> <b>set gateway 192.168.10.254</b>
|
||||
admin@example:/config/…/route/10.0.10.0/24/> <b>end</b>
|
||||
admin@example:/config/…/container-network/> <b>end</b>
|
||||
admin@example:/config/interface/docker0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Other network settings, like DNS and domain, use built-in defaults, but
|
||||
can be overridden from each container. Other common settings per
|
||||
@@ -622,24 +631,25 @@ in a `bridge`. Below an example of a system container calls `set
|
||||
network interface docker0`, here we show how to set options for that
|
||||
network:
|
||||
|
||||
admin@example:/config/container/ntpd/> edit network interface docker0
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/>
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option
|
||||
<string> Options for masquerading container bridges.
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> help option
|
||||
NAME
|
||||
option <string>
|
||||
|
||||
DESCRIPTION
|
||||
Options for masquerading container bridges.
|
||||
<pre class="cli"><code>admin@example:/config/container/ntpd/> <b>edit network interface docker0</b>
|
||||
admin@example:/config/…/network/interface/docker0/>
|
||||
admin@example:/config/…/network/interface/docker0/> <b>set option</b>
|
||||
<string> Options for masquerading container bridges.
|
||||
admin@example:/config/…/network/interface/docker0/> <b>help option</b>
|
||||
NAME
|
||||
option <string>
|
||||
|
||||
Example: ip=1.2.3.4 -- request a specific IP (IPv4 or IPv6)
|
||||
mac=00:01:02:c0:ff:ee -- set fixed MAC address in container
|
||||
interface_name=foo0 -- set interface name inside container
|
||||
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option ip=172.17.0.2
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option interface_name=wan
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> leave
|
||||
DESCRIPTION
|
||||
Options for masquerading container bridges.
|
||||
|
||||
Example: ip=1.2.3.4 -- request a specific IP (IPv4 or IPv6)
|
||||
mac=00:01:02:c0:ff:ee -- set fixed MAC address in container
|
||||
interface_name=foo0 -- set interface name inside container
|
||||
|
||||
admin@example:/config/…/network/interface/docker0/> <b>set option ip=172.17.0.2</b>
|
||||
admin@example:/config/…/network/interface/docker0/> <b>set option interface_name=wan</b>
|
||||
admin@example:/config/…/network/interface/docker0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Container Host Interface
|
||||
@@ -674,14 +684,15 @@ container-end of pair `ntpd`. This is just a convenience for us when
|
||||
reading the configuration later. The *real action* happens on the last
|
||||
line where we declare the `ntpd` end as a container network interface:
|
||||
|
||||
admin@example:/config/> edit interface veth0
|
||||
admin@example:/config/interface/veth0/> set veth peer ntpd
|
||||
admin@example:/config/interface/veth0/> set ipv4 address 192.168.0.1 prefix-length 24
|
||||
admin@example:/config/interface/veth0/> end
|
||||
admin@example:/config/> edit interface ntpd
|
||||
admin@example:/config/interface/ntpd/> set ipv4 address 192.168.0.2 prefix-length 24
|
||||
admin@example:/config/interface/ntpd/> set custom-phys-address static 00:c0:ff:ee:00:01
|
||||
admin@example:/config/interface/ntpd/> set container-network
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface veth0</b>
|
||||
admin@example:/config/interface/veth0/> <b>set veth peer ntpd</b>
|
||||
admin@example:/config/interface/veth0/> <b>set ipv4 address 192.168.0.1 prefix-length 24</b>
|
||||
admin@example:/config/interface/veth0/> <b>end</b>
|
||||
admin@example:/config/> <b>edit interface ntpd</b>
|
||||
admin@example:/config/interface/ntpd/> <b>set ipv4 address 192.168.0.2 prefix-length 24</b>
|
||||
admin@example:/config/interface/ntpd/> <b>set custom-phys-address static 00:c0:ff:ee:00:01</b>
|
||||
admin@example:/config/interface/ntpd/> <b>set container-network</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Notice how you can also set a custom MAC address at the same time.
|
||||
@@ -690,8 +701,9 @@ Adding the interface to the container is the same as before, but since
|
||||
everything for host interfaces is set up in the interfaces context, we
|
||||
can take a bit of a shortcut.
|
||||
|
||||
admin@example:/config/container/ntpd/> set network interface ntpd
|
||||
admin@example:/config/container/ntpd/> leave
|
||||
<pre class="cli"><code>admin@example:/config/container/ntpd/> <b>set network interface ntpd</b>
|
||||
admin@example:/config/container/ntpd/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Use the `set network interface ntpd option interface_name=foo0` to set
|
||||
@@ -712,9 +724,10 @@ pair to give our container two interfaces:
|
||||
|
||||
We start by adding the second VETH pair:
|
||||
|
||||
admin@example:/config/> edit interface veth1a
|
||||
admin@example:/config/interface/veth1a/> set veth peer veth1
|
||||
admin@example:/config/interface/veth1a/> set ipv4 address 192.168.1.2 prefix-length 24
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface veth1a</b>
|
||||
admin@example:/config/interface/veth1a/> <b>set veth peer veth1</b>
|
||||
admin@example:/config/interface/veth1a/> <b>set ipv4 address 192.168.1.2 prefix-length 24</b>
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> The LAN bridge (br1) in this example has IP address 192.168.1.1.
|
||||
@@ -723,20 +736,21 @@ When a container has multiple host interfaces it can often be useful to
|
||||
have a default route installed. This can be added from the host with a
|
||||
`0.0.0.0/0` route on one of the interfaces:
|
||||
|
||||
admin@example:/config/interface/veth1a/> set container-network route 0.0.0.0/0 gateway 192.168.1.1
|
||||
admin@example:/config/interface/veth1a/> show
|
||||
type veth;
|
||||
container-network {
|
||||
type host;
|
||||
route 0.0.0.0/0 {
|
||||
gateway 192.168.1.1;
|
||||
}
|
||||
}
|
||||
veth {
|
||||
peer veth1;
|
||||
}
|
||||
admin@example:/config/interface/veth1a/> end
|
||||
admin@example:/config/> set interface veth1 bridge-port bridge br1
|
||||
<pre class="cli"><code>admin@example:/config/interface/veth1a/> <b>set container-network route 0.0.0.0/0 gateway 192.168.1.1</b>
|
||||
admin@example:/config/interface/veth1a/> <b>show</b>
|
||||
type veth;
|
||||
container-network {
|
||||
type host;
|
||||
route 0.0.0.0/0 {
|
||||
gateway 192.168.1.1;
|
||||
}
|
||||
}
|
||||
veth {
|
||||
peer veth1;
|
||||
}
|
||||
admin@example:/config/interface/veth1a/> <b>end</b>
|
||||
admin@example:/config/> <b>set interface veth1 bridge-port bridge br1</b>
|
||||
</code></pre>
|
||||
|
||||
Please note, container network routes require the base interface also
|
||||
have a static IP address set. Setting only the route, but no address,
|
||||
@@ -762,11 +776,12 @@ It is possible to mount files, directories, and even files matching a
|
||||
glob, into a container. This gives precise control over the container's
|
||||
file system:
|
||||
|
||||
admin@example:/config/container/system/> edit mount leds
|
||||
admin@example:/config/container/system/mount/leds> set source /sys/class/leds
|
||||
admin@example:/config/container/system/mount/leds> set target /sys/class/leds
|
||||
admin@example:/config/container/system/mount/leds> end
|
||||
admin@example:/config/container/system/>
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>edit mount leds</b>
|
||||
admin@example:/config/container/system/mount/leds> <b>set source /sys/class/leds</b>
|
||||
admin@example:/config/container/system/mount/leds> <b>set target /sys/class/leds</b>
|
||||
admin@example:/config/container/system/mount/leds> <b>end</b>
|
||||
admin@example:/config/container/system/>
|
||||
</code></pre>
|
||||
|
||||
Any type of file can be *bind mounted* into the container, just watch
|
||||
out for permissions though. In the example above, `/sys/class/leds` is
|
||||
@@ -782,7 +797,8 @@ trigger a container restart.
|
||||
Other times *volumes* are a better fit. A volume is an automatically
|
||||
created read-writable entity that follows the life of your container.
|
||||
|
||||
admin@example:/config/container/ntpd/> set volume varlib target /var/lib
|
||||
<pre class="cli"><code>admin@example:/config/container/ntpd/> <b>set volume varlib target /var/lib</b>
|
||||
</code></pre>
|
||||
|
||||
Volumes are persistent across both reboots and upgrades of the base
|
||||
image. They are created by Podman when the container first starts up,
|
||||
@@ -812,14 +828,15 @@ where:
|
||||
To clean up unused volumes and reclaim disk space, use the admin-exec
|
||||
command:
|
||||
|
||||
admin@example:/> container prune
|
||||
Deleted Images
|
||||
...
|
||||
Deleted Volumes
|
||||
ntpd-varlib
|
||||
system-data
|
||||
<pre class="cli"><code>admin@example:/> <b>container prune</b>
|
||||
Deleted Images
|
||||
...
|
||||
Deleted Volumes
|
||||
ntpd-varlib
|
||||
system-data
|
||||
|
||||
Total reclaimed space: 45.2MB
|
||||
Total reclaimed space: 45.2MB
|
||||
</code></pre>
|
||||
|
||||
The `container prune` command safely removes:
|
||||
|
||||
@@ -830,14 +847,16 @@ The `container prune` command safely removes:
|
||||
> [!TIP]
|
||||
> You can monitor container resource usage with the command:
|
||||
>
|
||||
> admin@example:/> show container usage
|
||||
> <pre class="cli"><code>admin@example:/> <b>show container usage</b>
|
||||
> </code></pre>
|
||||
>
|
||||
> This displays disk space used by images, containers, and volumes,
|
||||
> helping you decide when to run the prune command.
|
||||
>
|
||||
> To see which volumes exist and which containers use them:
|
||||
>
|
||||
> admin@example:/> show container volumes
|
||||
> <pre class="cli"><code>admin@example:/> <b>show container volumes</b>
|
||||
> </code></pre>
|
||||
|
||||
### Content Mounts
|
||||
|
||||
@@ -847,12 +866,13 @@ when deploying similar systems at multiple sites. When the host loads
|
||||
its `startup-config` (or even `factory-config`) a temporary file is
|
||||
created using the decoded base64 data from the `content` node.
|
||||
|
||||
admin@example:/config/container/ntpd/> edit mount ntpd.conf
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> text-editor content
|
||||
... interactive editor starts up ...
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> set target /etc/ntpd.conf
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> end
|
||||
admin@example:/config/container/ntpd/>
|
||||
<pre class="cli"><code>admin@example:/config/container/ntpd/> <b>edit mount ntpd.conf</b>
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> <b>text-editor content</b>
|
||||
... interactive editor starts up ...
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> <b>set target /etc/ntpd.conf</b>
|
||||
admin@example:/config/container/ntpd/mount/ntpd.conf> <b>end</b>
|
||||
admin@example:/config/container/ntpd/>
|
||||
</code></pre>
|
||||
|
||||
The editor is a small [Emacs clone called Mg][2], see the built-in help
|
||||
text, or press Ctrl-x Ctrl-c to exit and save. When the editor exits
|
||||
@@ -876,12 +896,13 @@ Let's try out what we've learned by setting up a system container, a
|
||||
container providing multiple services, using the `docker0` interface
|
||||
we created previously:
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config> edit container system
|
||||
admin@example:/config/container/system/> set image ghcr.io/kernelkit/curios:edge
|
||||
admin@example:/config/container/system/> set network interface docker0
|
||||
admin@example:/config/container/system/> set publish 222:22
|
||||
admin@example:/config/container/system/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config> <b>edit container system</b>
|
||||
admin@example:/config/container/system/> <b>set image ghcr.io/kernelkit/curios:edge</b>
|
||||
admin@example:/config/container/system/> <b>set network interface docker0</b>
|
||||
admin@example:/config/container/system/> <b>set publish 222:22</b>
|
||||
admin@example:/config/container/system/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> Ensure you have a network connection to the registry. If the image
|
||||
@@ -896,26 +917,29 @@ container configuration context for the full syntax.)
|
||||
|
||||
Available containers can be accessed from admin-exec:
|
||||
|
||||
admin@example:/> show container
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
439af2917b44 ghcr.io/kernelkit/curios:edge 41 hours ago Up 16 hours 0.0.0.0:222->222/tcp system
|
||||
<pre class="cli"><code>admin@example:/> <b>show container</b>
|
||||
<span class="header">NAME STATUS NETWORK MEMORY (KiB) CPU%</span>
|
||||
system Up 16 hours docker0 136/512 0.02
|
||||
</code></pre>
|
||||
|
||||
This is a system container, so you can "attach" to it by starting a
|
||||
shell (or logging in with SSH):
|
||||
|
||||
admin@example:/> container shell system
|
||||
root@439af2917b44:/#
|
||||
<pre class="cli"><code>admin@example:/> <b>container shell system</b>
|
||||
root@439af2917b44:/#
|
||||
</code></pre>
|
||||
|
||||
Notice how the hostname inside the container changes. By default the
|
||||
container ID (hash) is used, but this can be easily changed:
|
||||
|
||||
root@439af2917b44:/# exit
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit container system
|
||||
admin@example:/config/container/system/> set hostname sys101
|
||||
admin@example:/config/container/system/> leave
|
||||
admin@example:/> container shell system
|
||||
root@sys101:/#
|
||||
<pre class="cli"><code>root@439af2917b44:/# <b>exit</b>
|
||||
admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit container system</b>
|
||||
admin@example:/config/container/system/> <b>set hostname sys101</b>
|
||||
admin@example:/config/container/system/> <b>leave</b>
|
||||
admin@example:/> <b>container shell system</b>
|
||||
root@sys101:/#
|
||||
</code></pre>
|
||||
|
||||
In fact, the container `hostname` setting supports the same format
|
||||
specifiers as the host's `hostname` setting:
|
||||
@@ -940,16 +964,17 @@ Infix currently does not have a native firewall configuration, and even
|
||||
when it does it will never expose the full capabilities of `nftables`.
|
||||
For advanced setups, the following is an interesting alternative.
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config> edit container nftables
|
||||
admin@example:/config/container/nftables/> set image ghcr.io/kernelkit/curios-nftables:edge
|
||||
admin@example:/config/container/nftables/> set network host
|
||||
admin@example:/config/container/nftables/> set privileged
|
||||
admin@example:/config/container/nftables/> edit mount nftables.conf
|
||||
admin@example:/config/container/nftables/mount/nftables.conf/> set target /etc/nftables.conf
|
||||
admin@example:/config/container/nftables/mount/nftables.conf/> text-editor content
|
||||
... interactive editor starts up where you can paste your rules ...
|
||||
admin@example:/config/container/nftables/mount/nftables.conf/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config> <b>edit container nftables</b>
|
||||
admin@example:/config/container/nftables/> <b>set image ghcr.io/kernelkit/curios-nftables:edge</b>
|
||||
admin@example:/config/container/nftables/> <b>set network host</b>
|
||||
admin@example:/config/container/nftables/> <b>set privileged</b>
|
||||
admin@example:/config/container/nftables/> <b>edit mount nftables.conf</b>
|
||||
admin@example:/config/…/mount/nftables.conf/> <b>set target /etc/nftables.conf</b>
|
||||
admin@example:/config/…/mount/nftables.conf/> <b>text-editor content</b>
|
||||
... interactive editor starts up where you can paste your rules ...
|
||||
admin@example:/config/…/mount/nftables.conf/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Notice how we `set network host`, so the container can see and act on
|
||||
all the host's interfaces, and that we also have to run the container
|
||||
@@ -968,19 +993,20 @@ file system and store in the host's `startup-config`. However, `ntpd`
|
||||
also saves clock drift information in `/var/lib/ntpd`, so we will also
|
||||
use volumes in this example.
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config> edit container ntpd
|
||||
admin@example:/config/container/ntpd/> set image ghcr.io/kernelkit/curios-ntpd:edge
|
||||
admin@example:/config/container/ntpd/> set network interface ntpd # From veth0 above
|
||||
admin@example:/config/container/ntpd/> edit mount ntp.conf
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> set target /etc/ntp.conf
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> text-editor content
|
||||
... interactive editor starts up where you can paste your rules ...
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> end
|
||||
admin@example:/config/container/ntpd/> edit volume varlib
|
||||
admin@example:/config/container/ntpd/volume/varlib/> set target /var/lib
|
||||
admin@example:/config/container/ntpd/volume/varlib/> leave
|
||||
admin@example:/> copy running-config startup-config
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config> <b>edit container ntpd</b>
|
||||
admin@example:/config/container/ntpd/> <b>set image ghcr.io/kernelkit/curios-ntpd:edge</b>
|
||||
admin@example:/config/container/ntpd/> <b>set network interface ntpd</b> # From veth0 above
|
||||
admin@example:/config/container/ntpd/> <b>edit mount ntp.conf</b>
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> <b>set target /etc/ntp.conf</b>
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> <b>text-editor content</b>
|
||||
... interactive editor starts up where you can paste your rules ...
|
||||
admin@example:/config/container/ntpd/mount/ntp.conf/> <b>end</b>
|
||||
admin@example:/config/container/ntpd/> <b>edit volume varlib</b>
|
||||
admin@example:/config/container/ntpd/volume/varlib/> <b>set target /var/lib</b>
|
||||
admin@example:/config/container/ntpd/volume/varlib/> <b>leave</b>
|
||||
admin@example:/> <b>copy running-config startup-config</b>
|
||||
</code></pre>
|
||||
|
||||
The `ntp.conf` file is stored in the host's `startup-config` and any
|
||||
state data in the container's `/var/lib` is retained between reboots
|
||||
@@ -1015,25 +1041,28 @@ First, enable *Privileged* mode, this unlocks the door and allows the
|
||||
container to manage resources on the host system. An example is the
|
||||
`nftables` container mentioned previously.
|
||||
|
||||
admin@example:/config/container/system/> set privileged
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>set privileged</b>
|
||||
</code></pre>
|
||||
|
||||
Second, mount the host's `/proc/1` directory to somewhere inside your
|
||||
container. Here we pick `/1`:
|
||||
|
||||
admin@example:/config/container/system/> edit mount host
|
||||
admin@example:/config/container/system/mount/host/> set source /proc/1
|
||||
admin@example:/config/container/system/mount/host/> set target /1
|
||||
admin@example:/config/container/system/mount/host/> leave
|
||||
<pre class="cli"><code>admin@example:/config/container/system/> <b>edit mount host</b>
|
||||
admin@example:/config/container/system/mount/host/> <b>set source /proc/1</b>
|
||||
admin@example:/config/container/system/mount/host/> <b>set target /1</b>
|
||||
admin@example:/config/container/system/mount/host/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Third, from inside the container, use the host's PID 1 namespaces with
|
||||
the `nsenter`[^2] command to slide through the container's walls. Here
|
||||
we show two example calls to `hostname`, first the container's own name
|
||||
and then asking what the hostname is on the host:
|
||||
|
||||
root@sys101:/# hostname
|
||||
sys101
|
||||
root@sys101:/# nsenter -m/1/ns/mnt -u/1/ns/uts -i/1/ns/ipc -n/1/ns/net hostname
|
||||
example
|
||||
<pre class="cli"><code>root@sys101:/# <b>hostname</b>
|
||||
sys101
|
||||
root@sys101:/# <b>nsenter -m/1/ns/mnt -u/1/ns/uts -i/1/ns/ipc -n/1/ns/net hostname</b>
|
||||
example
|
||||
</code></pre>
|
||||
|
||||
One use-case for this method is when extending Infix with a management
|
||||
container that connects to other systems. For some tips on how to
|
||||
|
||||
+46
-54
@@ -19,20 +19,18 @@ servers[^1].
|
||||
The following example configures a DHCP server for subnet 192.168.2.0/24
|
||||
with an address pool:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit dhcp-server subnet 192.168.2.0/24
|
||||
admin@example:/config/dhcp-server/…/192.168.2.0/24/> set pool start-address 192.168.2.100 end-address 192.168.2.200
|
||||
admin@example:/config/dhcp-server/…/192.168.2.0/24/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit dhcp-server subnet 192.168.2.0/24</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.2.0/24/> <b>set pool start-address 192.168.2.100 end-address 192.168.2.200</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.2.0/24/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
When setting up the server from the CLI, the system automatically adds a
|
||||
few default DHCP options that will be sent to clients: both DNS server
|
||||
and default gateway will use the system address on the matching
|
||||
interface.
|
||||
|
||||
```
|
||||
admin@example:/> show running-config
|
||||
<pre class="cli"><code>admin@example:/> <b>show running-config</b>
|
||||
"infix-dhcp-server:dhcp-server": {
|
||||
"subnet": [
|
||||
{
|
||||
@@ -54,7 +52,7 @@ admin@example:/> show running-config
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Remember to set up an interface in this subnet, avoid using addresses
|
||||
@@ -68,23 +66,21 @@ admin@example:/> show running-config
|
||||
To reserve specific IP addresses for clients based on their MAC address,
|
||||
hostname, or client ID:
|
||||
|
||||
```
|
||||
admin@example:/config/dhcp-server/…/192.168.2.0/24/> edit host 192.168.2.10
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> set match mac-address 00:11:22:33:44:55
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> set hostname printer
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/dhcp-server/…/192.168.2.0/24/> <b>edit host 192.168.2.10</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> <b>set match mac-address 00:11:22:33:44:55</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> <b>set hostname printer</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.2.10/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Match hosts using a client identifier instead of MAC address:
|
||||
|
||||
```
|
||||
admin@example:/config/dhcp-server/…/192.168.1.0/24/> edit host 192.168.1.50
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> edit match
|
||||
admin@example:/config/dhcp-server/…/match/> set client-id hex c0:ff:ee
|
||||
admin@example:/config/dhcp-server/…/match/> leave
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> set lease-time infinite
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/dhcp-server/…/192.168.1.0/24/> <b>edit host 192.168.1.50</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> <b>edit match</b>
|
||||
admin@example:/config/dhcp-server/…/match/> <b>set client-id hex c0:ff:ee</b>
|
||||
admin@example:/config/dhcp-server/…/match/> <b>leave</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> <b>set lease-time infinite</b>
|
||||
admin@example:/config/dhcp-server/…/192.168.1.50/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The `hex` prefix here ensures matching of client ID is done using the
|
||||
hexadecimal octets `c0:ff:ee`, three bytes. Without the prefix the
|
||||
@@ -100,32 +96,30 @@ ASCII string "c0:ff:ee", eight bytes, is used.
|
||||
|
||||
Configure additional DHCP options globally, per subnet, or per host:
|
||||
|
||||
```
|
||||
admin@example:/config/dhcp-server/> edit subnet 192.168.2.0/24
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> edit option dns-server
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/dns-server/> set address 8.8.8.8
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/dns-server/> leave
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> edit option ntp-server
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/ntp-server/> set address 192.168.2.1
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/ntp-server/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/dhcp-server/> <b>edit subnet 192.168.2.0/24</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> <b>edit option dns-server</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/dns-server/> <b>set address 8.8.8.8</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/dns-server/> <b>leave</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> <b>edit option ntp-server</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/ntp-server/> <b>set address 192.168.2.1</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/option/ntp-server/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
When configuring, e.g., `dns-server`, or `router` options with the value
|
||||
`auto`, the system uses the IP address from the interface matching the
|
||||
subnet. For example:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 192.168.1.1/24 (static)
|
||||
eth1 ethernet UP 02:00:00:00:00:01
|
||||
ipv4 192.168.2.1/24 (static)
|
||||
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> edit option dns-server
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/option/dns-server/> set address auto
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/option/dns-server/> leave
|
||||
```
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>edit option dns-server</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/option/dns-server/> <b>set address auto</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/option/dns-server/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
In this case, clients in subnet 192.168.1.0/24 will receive 192.168.1.1
|
||||
as their DNS server address.
|
||||
@@ -135,29 +129,27 @@ as their DNS server address.
|
||||
|
||||
Configure DHCP for multiple networks:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit dhcp-server
|
||||
admin@example:/config/dhcp-server/> edit subnet 192.168.1.0/24
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> set pool start-address 192.168.1.100 end-address 192.168.1.200
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> leave
|
||||
admin@example:/config/dhcp-server/> edit subnet 192.168.2.0/24
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> set pool start-address 192.168.2.100 end-address 192.168.2.200
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit dhcp-server</b>
|
||||
admin@example:/config/dhcp-server/> <b>edit subnet 192.168.1.0/24</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>set pool start-address 192.168.1.100 end-address 192.168.1.200</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>leave</b>
|
||||
admin@example:/config/dhcp-server/> <b>edit subnet 192.168.2.0/24</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> <b>set pool start-address 192.168.2.100 end-address 192.168.2.200</b>
|
||||
admin@example:/config/dhcp-server/subnet/192.168.2.0/24/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Monitoring
|
||||
|
||||
View active leases and server statistics:
|
||||
|
||||
```
|
||||
admin@example:/> show dhcp-server
|
||||
IP ADDRESS MAC HOSTNAME CLIENT ID EXPIRES
|
||||
<pre class="cli"><code>admin@example:/> <b>show dhcp-server</b>
|
||||
<span class="header">IP ADDRESS MAC HOSTNAME CLIENT ID EXPIRES</span>
|
||||
192.168.2.22 00:a0:85:00:02:05 00:c0:ff:ee 3591s
|
||||
192.168.1.11 00:a0:85:00:04:06 foo 01:00:a0:85:00:04:06 3591s
|
||||
|
||||
admin@example:/> show dhcp-server statistics
|
||||
admin@example:/> <b>show dhcp-server statistics</b>
|
||||
DHCP offers sent : 6
|
||||
DHCP ACK messages sent : 5
|
||||
DHCP NAK messages sent : 0
|
||||
@@ -166,7 +158,7 @@ DHCP discover messages received : 6
|
||||
DHCP request messages received : 5
|
||||
DHCP release messages received : 6
|
||||
DHCP inform messages received : 6
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
|
||||
[^1]: This requires the system DNS resolver to be configured.
|
||||
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
# Ethernet Interfaces
|
||||
|
||||
This document covers VLAN interfaces, physical Ethernet interfaces,
|
||||
and virtual Ethernet (VETH) pairs.
|
||||
|
||||
|
||||
## VLAN Interfaces
|
||||
|
||||
Creating a VLAN can be done in many ways. This section assumes VLAN
|
||||
interfaces created atop another Linux interface. E.g., the VLAN
|
||||
interfaces created on top of the Ethernet interface or bridge in the
|
||||
picture below.
|
||||
|
||||

|
||||
|
||||
A VLAN interface is basically a filtering abstraction. When you run
|
||||
`tcpdump` on a VLAN interface you will only see the frames matching the
|
||||
VLAN ID of the interface, compared to *all* the VLAN IDs if you run
|
||||
`tcpdump` on the lower-layer interface.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0.20</b>
|
||||
admin@example:/config/interface/eth0.20/> <b>show</b>
|
||||
type vlan;
|
||||
vlan {
|
||||
tag-type c-vlan;
|
||||
id 20;
|
||||
lower-layer-if eth0;
|
||||
}
|
||||
admin@example:/config/interface/eth0.20/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The example below assumes bridge br0 is already created, see [VLAN
|
||||
Filtering Bridge](bridging.md#vlan-filtering-bridge).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface vlan10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan id 10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan lower-layer-if br0</b>
|
||||
admin@example:/config/interface/vlan10/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
As conventions, a VLAN interface for VID 20 on top of an Ethernet
|
||||
interface *eth0* is named *eth0.20*, and a VLAN interface for VID 10 on
|
||||
top of a bridge interface *br0* is named *vlan10*.
|
||||
|
||||
> [!NOTE]
|
||||
> If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a
|
||||
> number, the CLI infers the interface type automatically.
|
||||
|
||||
|
||||
## Physical Ethernet Interfaces
|
||||
|
||||
### Ethernet Settings and Status
|
||||
|
||||
Physical Ethernet interfaces provide low-level settings for speed/duplex as
|
||||
well as packet status and [statistics](#ethernet-statistics).
|
||||
|
||||
By default, Ethernet interfaces defaults to auto-negotiating
|
||||
speed/duplex modes, advertising all speed and duplex modes available.
|
||||
In the example below, the switch would by default auto-negotiate speed
|
||||
1 Gbit/s on port eth1 and 100 Mbit/s on port eth4, as those are the
|
||||
highest speeds supported by H1 and H2 respectively.
|
||||
|
||||

|
||||
|
||||
The speed and duplex status for the links can be listed as shown
|
||||
below, assuming the link operational status is 'up'.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:01
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
...
|
||||
admin@example:/> <b>show interface eth4</b>
|
||||
name : eth4
|
||||
index : 5
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 100
|
||||
physical address : 00:53:00:06:11:04
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75439
|
||||
out-octets : 550704
|
||||
...
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
### Configuring fixed speed and duplex
|
||||
|
||||
Auto-negotiation of speed/duplex mode is desired in almost all
|
||||
use-cases, but it is possible to disable auto-negotiation and specify
|
||||
a fixed speed and duplex mode.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> When setting a fixed speed and duplex mode, ensure both sides of the
|
||||
> link have matching configuration. If speed does not match, the link
|
||||
> will not come up. If duplex mode does not match, the result is
|
||||
> reported collisions and/or bad throughput.
|
||||
|
||||
The example below configures port eth3 to fixed speed 100 Mbit/s
|
||||
half-duplex mode.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth3 ethernet</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set speed 0.1</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set duplex half</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation enable false</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>show</b>
|
||||
auto-negotiation {
|
||||
enable false;
|
||||
}
|
||||
duplex half;
|
||||
speed 0.1;
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Speed metric is in Gbit/s. Auto-negotiation needs to be disabled in
|
||||
order for fixed speed/duplex to apply. Only speeds `0.1`(100 Mbit/s)
|
||||
and `0.01` (10 Mbit/s) can be specified. 1 Gbit/s and higher speeds
|
||||
require auto-negotiation to be enabled.
|
||||
|
||||
### Ethernet statistics
|
||||
|
||||
Ethernet packet statistics[^1] can be listed as shown below.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:0a
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
|
||||
eth-in-frames : 434
|
||||
eth-in-multicast-frames : 296
|
||||
eth-in-broadcast-frames : 138
|
||||
eth-in-error-fcs-frames : 0
|
||||
eth-in-error-oversize-frames : 0
|
||||
eth-out-frames : 310
|
||||
eth-out-multicast-frames : 310
|
||||
eth-out-broadcast-frames : 0
|
||||
eth-out-good-octets : 76821
|
||||
eth-in-good-octets : 60598
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## VETH Pairs
|
||||
|
||||
A Virtual Ethernet (VETH) pair is basically a virtual Ethernet cable. A
|
||||
cable can be "plugged in" to a bridge and the other end can be given to
|
||||
a [container](container.md), or plugged into another bridge.
|
||||
|
||||
The latter example is useful if you have multiple bridges in the system
|
||||
with different properties (VLAN filtering, IEEE group forwarding, etc.),
|
||||
but still want some way of communicating between these domains.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface veth0a</b>
|
||||
admin@example:/config/interface/veth0a/> <b>set veth peer veth0b</b>
|
||||
admin@example:/config/interface/veth0a/> <b>end</b>
|
||||
admin@example:/config/> <b>diff</b>
|
||||
interfaces {
|
||||
+ interface veth0a {
|
||||
+ type veth;
|
||||
+ veth {
|
||||
+ peer veth0b;
|
||||
+ }
|
||||
+ }
|
||||
+ interface veth0b {
|
||||
+ type veth;
|
||||
+ veth {
|
||||
+ peer veth0a;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
admin@example:/config/>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> This is another example of the automatic inference of the interface
|
||||
> type from the name. Any name can be used, but then you have to set
|
||||
> the interface type to `veth` manually.
|
||||
|
||||
[^1]: Ethernet counters are described in *ieee802-ethernet-interface.yang*
|
||||
and *infix-ethernet-interface.yang*. There is a dedicated document on
|
||||
[Ethernet Counters](eth-counters.md) that provide additional details
|
||||
on the statistics support.
|
||||
@@ -24,3 +24,14 @@
|
||||
/* Reset alignment for table cells */
|
||||
text-align: initial;
|
||||
}
|
||||
|
||||
/* CLI terminal output styling */
|
||||
.md-typeset pre.cli .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.md-typeset pre.cli .header {
|
||||
background-color: #e0e0e0;
|
||||
color: #1a1a1a;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
+23
-19
@@ -93,7 +93,7 @@ about this in the [example below](#end-device-protection).
|
||||
> [!IMPORTANT] Remember IP forwarding on interfaces!
|
||||
> Firewall policies only control whether traffic is allowed on input, to be
|
||||
> forwarded, or blocked (default). For the actual routing between interfaces
|
||||
> to work, you must also enable [IP forwarding](networking.md#ipv4-forwarding)
|
||||
> to work, you must also enable [IP forwarding](ip.md#ipv4-forwarding)
|
||||
> on the relevant interfaces.
|
||||
|
||||
### Intra-Zone Traffic
|
||||
@@ -151,7 +151,8 @@ allowed access to.
|
||||
|
||||
See the [examples below](#enterprise-gateway) for how to set up a policy. The
|
||||
built-in help system can also be useful:
|
||||
<code><pre>admin@example:/config/firewall/policy/lan-to-dmz/> <b>help masquerade</b>
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/firewall/policy/lan-to-dmz/> <b>help masquerade</b>
|
||||
<b>NAME</b>
|
||||
masquerade <true/false><br/>
|
||||
<b>DESCRIPTION</b>
|
||||
@@ -159,7 +160,7 @@ built-in help system can also be useful:
|
||||
Matching traffic will have their source IP address changed on egress,
|
||||
using the IP address of the interface the traffic egresses.<br/>
|
||||
admin@example:/config/firewall/policy/lan-to-dmz/>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
### Symbolic Names
|
||||
|
||||
@@ -229,7 +230,8 @@ The firewall includes over 100 pre-defined services, such as:
|
||||
This is the default firewall setup, useful for end devices on untrusted
|
||||
networks. It provides maximum protection while allowing essential
|
||||
connectivity.
|
||||
<code><pre>admin@example:/> <b>configure</b>
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit firewall</b>
|
||||
admin@example:/config/firewall/> <b>show</b>
|
||||
default public;
|
||||
@@ -240,21 +242,21 @@ zone public {
|
||||
service ssh;
|
||||
}
|
||||
admin@example:/config/firewall/> <b>leave</b>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
The `reject` action differs from `drop` in that it responds to ICMP messages,
|
||||
although maybe not how you may think. Pinging the device we may[^1] see this:
|
||||
<code><pre>
|
||||
<b>$</b> ping 192.168.122.161
|
||||
|
||||
<pre class="cli"><code><b>$</b> ping 192.168.122.161
|
||||
From 192.168.122.161 icmp_seq=1 <u>Packet filtered</u>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
If we run `tcpdump` it shows us why:
|
||||
<code><pre>
|
||||
<b>$</b> tcpdump -lni eth0
|
||||
|
||||
<pre class="cli"><code><b>$</b> tcpdump -lni eth0
|
||||
20:10:40.245707 IP 192.168.122.1 > 192.168.122.161: ICMP echo request, id 56838, seq 1, length 64
|
||||
20:10:40.245961 IP 192.168.122.161 > 192.168.122.1: ICMP <u>host 192.168.122.161 unreachable - admin prohibited filter</u>, length 92
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
The key here is that, yes the device responds, but not with `ICMP reply` but
|
||||
`ICMP unreachable`, and a little helpful message.
|
||||
@@ -285,7 +287,8 @@ Zone matrix and firewall overview from <kbd>show firewall</kbd>.
|
||||
For typical routers that need to protect internal devices while providing
|
||||
internet access. The LAN zone trusts internal devices, while the WAN zone
|
||||
blocks external threats.
|
||||
<code><pre>admin@example:/> <b>configure</b>
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit firewall</b>
|
||||
admin@example:/config/firewall/> <b>set default wan</b>
|
||||
admin@example:/config/firewall/> <b>edit zone lan</b>
|
||||
@@ -308,14 +311,15 @@ admin@example:/config/firewall/…/loc-to-wan/> <b>set egress wan</b>
|
||||
admin@example:/config/firewall/…/loc-to-wan/> <b>set action accept</b>
|
||||
admin@example:/config/firewall/…/loc-to-wan/> <b>set masquerade</b>
|
||||
admin@example:/config/firewall/…/loc-to-wan/> <b>leave</b>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
### Enterprise Gateway
|
||||
|
||||
For businesses that need to host public services while protecting internal
|
||||
resources. We can build upon the Home/Office Router example above and add
|
||||
a DMZ zone with additional policies for controlled access.
|
||||
<code><pre>admin@example:/> <b>configure</b>
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit firewall zone dmz</b>
|
||||
admin@example:/config/firewall/…/dmz/> <b>set description "Semi-trusted public services"</b>
|
||||
admin@example:/config/firewall/…/dmz/> <b>set action drop</b>
|
||||
@@ -339,7 +343,7 @@ admin@example:/config/firewall/> <b>edit zone wan port-forward 8080 tcp</b>
|
||||
admin@example:/config/firewall/…/tcp/> <b>set to addr 192.168.2.10</b>
|
||||
admin@example:/config/firewall/…/tcp/> <b>set to port 80</b>
|
||||
admin@example:/config/firewall/…/tcp/> <b>leave</b>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
This adds a DMZ zone for public services, updates the internet access policy
|
||||
to include DMZ traffic, allows LAN management of DMZ services, and forwards
|
||||
@@ -349,12 +353,12 @@ external web traffic to the DMZ server.
|
||||
|
||||
Different log levels are available to monitor and debug firewall behavior.
|
||||
Configure logging using the CLI:
|
||||
<code><pre>
|
||||
admin@example:/> <b>configure</b>
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit firewall</b>
|
||||
admin@example:/config/firewall/> <b>set logging all</b>
|
||||
admin@example:/config/firewall/> <b>leave</b>
|
||||
</pre></code>
|
||||
</code></pre>
|
||||
|
||||
Firewall logs help you understand traffic patterns and security events. The
|
||||
CLI admin-exec command <kbd>show firewall</kbd> shows the last 10 log messages in the
|
||||
@@ -457,4 +461,4 @@ You can check the current lockdown state:
|
||||
}
|
||||
```
|
||||
|
||||
[1]: networking.md#bridging
|
||||
[1]: bridging.md
|
||||
|
||||
+27
-17
@@ -8,7 +8,7 @@ hardware][1], with deviations and augmentations in _infix-hardware_.
|
||||
For Infix to be able to control USB port(s), a device tree modification
|
||||
is needed (see _alder.dtsi_ for full example).
|
||||
|
||||
```
|
||||
```json
|
||||
chosen {
|
||||
infix {
|
||||
usb-ports = <&cp0_usb3_1>;
|
||||
@@ -24,26 +24,38 @@ All USB ports in the system will be disabled during boot due to the file
|
||||
Infix to control USB port(s), remove the file or manually enable the USB
|
||||
bus, here is an example:
|
||||
|
||||
```
|
||||
```bash
|
||||
# Enable the bus
|
||||
echo 1 > /sys/bus/usb/devices/usb1/authorized
|
||||
```
|
||||
|
||||
And then enable sub-devices (e.g. USB memory)
|
||||
|
||||
```
|
||||
```bash
|
||||
# Enable a device plugged into usb1
|
||||
echo 1 > /sys/bus/usb/devices/usb1/1-1/authorized
|
||||
```
|
||||
|
||||
### Current status
|
||||
|
||||
```
|
||||
admin@example:/> show hardware
|
||||
USB PORTS
|
||||
NAME STATE
|
||||
USB unlocked
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>show hardware</b>
|
||||
<span class="header">HARDWARE COMPONENTS </span>
|
||||
──────────────────────────────────────────────────────────────
|
||||
<span class="title">Board Information </span>
|
||||
Model : FriendlyElec NanoPi R2S
|
||||
Manufacturer : FriendlyElec
|
||||
Serial Number : 9d1fbfdab6d171ce
|
||||
Base MAC Address : 4a:dc:d8:20:0d:85
|
||||
──────────────────────────────────────────────────────────────
|
||||
<span class="title">USB Ports </span>
|
||||
<span class="header">NAME STATE OPER </span>
|
||||
USB unlocked enabled
|
||||
──────────────────────────────────────────────────────────────
|
||||
<span class="title">Sensors </span>
|
||||
<span class="header">NAME VALUE STATUS </span>
|
||||
soc 44.1 °C ok
|
||||
soc 44.5 °C ok
|
||||
</code></pre>
|
||||
|
||||
An USB port can be in two states _unlocked_ and _locked_. When a port is
|
||||
locked, all connected devices will get power, but never authorized by
|
||||
@@ -56,12 +68,11 @@ Linux to use.
|
||||
> command `show hardware` in admin-exec context. (Use `do` prefix in
|
||||
> configure context.)
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> set hardware component USB state admin-state unlocked
|
||||
admin@example:/config/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>set hardware component USB state admin-state unlocked</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### Using a USB Stick
|
||||
|
||||
@@ -81,8 +92,7 @@ The only way currently to safely "eject" a USB memory stick is to use
|
||||
`umount` command from a UNIX shell, which explicitly synchronizes any
|
||||
cached data to disk before returning the prompt:
|
||||
|
||||
```
|
||||
admin@example:~$ sudo umount /media/log
|
||||
```
|
||||
<pre class="cli"><code>admin@example:~$ <b>sudo umount /media/log</b>
|
||||
</code></pre>
|
||||
|
||||
[1]: https://www.rfc-editor.org/rfc/rfc8348.html
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
# Common Interface Settings
|
||||
|
||||
Common interface settings include `name`, `type`, `enabled`, `description`,
|
||||
and custom MAC address. Type-specific settings are covered in the dedicated
|
||||
sections for [Bridging](bridging.md), [Link Aggregation](lag.md),
|
||||
[Ethernet](ethernet.md), [IP Addressing](ip.md), and [Routing](routing.md).
|
||||
|
||||
|
||||
## Interface Name
|
||||
|
||||
The interface name is limited to 1-15 characters due to Linux kernel
|
||||
constraints. Physical interfaces use their system-assigned names (e.g.,
|
||||
`eth0`, `eth1`), while user-created interfaces can be named freely within
|
||||
this limit.
|
||||
|
||||
> [!TIP]
|
||||
> Naming conventions like `br0`, `lag0`, `vlan10`, or `eth0.20` allow
|
||||
> the CLI to automatically infer the interface type.
|
||||
|
||||
|
||||
## Interface Type
|
||||
|
||||
The `type` setting defines what kind of interface this is: `bridge`, `lag`,
|
||||
`vlan`, `veth`, etc. When configuring via the CLI, the type is often
|
||||
inferred from the interface name. However, when configuring remotely via
|
||||
NETCONF or RESTCONF, the type *must* be set explicitly.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>set type bridge</b>
|
||||
</code></pre>
|
||||
|
||||
Available types can be listed from the CLI:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/br0/> <b>set type ?</b>
|
||||
bridge IEEE bridge interface.
|
||||
dummy Linux dummy interface. Useful mostly for testing.
|
||||
ethernet Any Ethernet interfaces, regardless of speed, RFC 3635.
|
||||
gre GRE tunnel interface.
|
||||
gretap GRETAP (Ethernet over GRE) tunnel interface.
|
||||
lag IEEE link aggregate interface.
|
||||
loopback Linux loopback interface.
|
||||
other Other interface, i.e., unknown.
|
||||
veth Linux virtual Ethernet pair.
|
||||
vlan Layer 2 Virtual LAN using 802.1Q.
|
||||
vxlan Virtual eXtensible LAN tunnel interface.
|
||||
wifi WiFi (802.11) interface
|
||||
wireguard WireGuard VPN tunnel interface.
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Enable/Disable
|
||||
|
||||
An interface can be administratively disabled using the `enabled` setting.
|
||||
By default, interfaces are enabled (`true`).
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface eth0</b>
|
||||
admin@example:/config/interface/eth0/> <b>set enabled false</b>
|
||||
admin@example:/config/interface/eth0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The operational status can be inspected to see both administrative and
|
||||
actual link state:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
|
||||
eth1 ethernet UP 02:00:00:00:00:01
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
The `description` is a free-form text string (max 64 characters) saved
|
||||
as the Linux interface alias (`ifalias`). Use it to document an interface's
|
||||
purpose or add notes for remote debugging.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface eth0</b>
|
||||
admin@example:/config/interface/eth0/> <b>set description "Uplink to core switch"</b>
|
||||
admin@example:/config/interface/eth0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The description is visible in the operational datastore and in `show`
|
||||
commands:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth0</b>
|
||||
name : eth0
|
||||
description : Uplink to core switch
|
||||
index : 2
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Custom MAC Address
|
||||
|
||||
The `custom-phys-address` can be used to set an interface's MAC address.
|
||||
This is an extension to the ietf-interfaces YANG model, which defines
|
||||
`phys-address` as read-only[^1].
|
||||
|
||||
> [!CAUTION]
|
||||
> There is no validation or safety checks performed by the system when
|
||||
> using `custom-phys-address`. In particular the `offset` variant can
|
||||
> be dangerous to use -- pay attention to the meaning of bits in the
|
||||
> upper-most octet: local bit, multicast/group, etc.
|
||||
|
||||
### Fixed custom MAC
|
||||
|
||||
Use a fixed custom MAC address when the interface must present a
|
||||
specific, deterministic identity on the network. This option bypasses
|
||||
any chassis-derived logic and applies the configured address verbatim.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface veth0a</b>
|
||||
admin@example:/config/interface/veth0a/> <b>set custom-phys-address static 00:ab:00:11:22:33</b>
|
||||
|
||||
=> 00:ab:00:11:22:33
|
||||
</code></pre>
|
||||
|
||||
### Chassis MAC
|
||||
|
||||
Chassis MAC, sometimes also referred to as base MAC. In these two
|
||||
examples it is `00:53:00:c0:ff:ee`.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface veth0a</b>
|
||||
admin@example:/config/interface/veth0a/> <b>set custom-phys-address chassis</b>
|
||||
|
||||
=> 00:53:00:c0:ff:ee
|
||||
</code></pre>
|
||||
|
||||
### Chassis MAC, with offset
|
||||
|
||||
When constructing a derived address it is recommended to set the locally
|
||||
administered bit. Same chassis MAC as before.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface veth0a</b>
|
||||
admin@example:/config/interface/veth0a/> <b>set custom-phys-address chassis offset 02:00:00:00:00:02</b>
|
||||
|
||||
=> 02:53:00:c0:ff:f0
|
||||
</code></pre>
|
||||
|
||||
|
||||
[^1]: A YANG deviation was previously used to make it possible to set
|
||||
`phys-address`, but this has been replaced with the more flexible
|
||||
`custom-phys-address`.
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 250 KiB |
@@ -0,0 +1,445 @@
|
||||
# IP Address Configuration
|
||||
|
||||
This section details IP Addresses And Other Per-Interface IP settings.
|
||||
|
||||
Infix support several network interface types, each can be assigned one
|
||||
or more IP addresses, both IPv4 and IPv6 are supported. (There is no
|
||||
concept of a "primary" address.)
|
||||
|
||||

|
||||
|
||||
## IPv4 Address Assignment
|
||||
|
||||
Multiple address assignment methods are available:
|
||||
|
||||
| **Type** | **Yang Model** | **Description** |
|
||||
|:---------- |:----------------- |:-------------------------------------------------------------- |
|
||||
| static | ietf-ip | Static assignment of IPv4 address, e.g., *10.0.1.1/24* |
|
||||
| link-local | infix-ip | Auto-assignment of IPv4 address in 169.254.x.x/16 range |
|
||||
| dhcp | infix-dhcp-client | Assignment of IPv4 address by DHCP server, e.g., *10.0.1.1/24* |
|
||||
|
||||
> [!NOTE]
|
||||
> The DHCP address method is only available for *LAN* interfaces
|
||||
> (Ethernet, virtual Ethernet (veth), bridge, link aggregates, etc.)
|
||||
|
||||
Supported DHCP (request) options, configurability (Cfg) and defaults,
|
||||
are listed below. Configurable options can be disabled on a per client
|
||||
interface basis, some options, like `clientid` and option 81, are
|
||||
possible to set the value of as well.
|
||||
|
||||
| **Opt** | **Name** | **Cfg** | **Description** |
|
||||
|---------|-----------------------------|---------|-----------------------------------------------------|
|
||||
| 1 | `netmask` | No | Request IP address and netmask |
|
||||
| 3 | `router` | Yes | Default route(s), see also option 121 and 249 |
|
||||
| 6 | `dns-server` | Yes | DNS server(s), static ones take precedence |
|
||||
| 12 | `hostname` | Yes | DHCP cannot set hostname, only for informing server |
|
||||
| 15 | `domain` | Yes | Default domain name, for name resolution |
|
||||
| 28 | `broadcast` | Yes | Broadcast address, calculated if disabled |
|
||||
| 42 | `ntp-server` | Yes | NTP server(s), static ones take precedence |
|
||||
| 50 | `address` | Yes | Request (previously cached) address |
|
||||
| 61 | `client-id` | Yes | Default MAC address (and option 12) |
|
||||
| 81 | `fqdn` | Yes | Similar to option 12, request FQDN update in DNS |
|
||||
| 119 | `search` | Yes | Request domain search list |
|
||||
| 121 | `classless-static-route` | Yes | Classless static routes |
|
||||
| 249 | `ms-classless-static-route` | Yes | Microsoft static route, same as option 121 |
|
||||
| | | | |
|
||||
|
||||
**Default:** `router`, `dns-server`, `domain`, `broadcast`, `ntp-server`, `search`,
|
||||
`address`, `classless-static-route`, `ms-classless-static-route`
|
||||
|
||||
When configuring a DHCP client, ensure that the NTP client is enabled
|
||||
for the `ntp-server` DHCP option to be processed correctly. If the NTP
|
||||
client is not enabled, any NTP servers provided by the DHCP server will
|
||||
be ignored. For details on how to enable the NTP client, see the [NTP
|
||||
Client Configuration](system.md#ntp-client-configuration) section.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Per [RFC3442][1], if the DHCP server returns both a Classless Static
|
||||
> Routes option (121) and Router option (3), the DHCP client *must*
|
||||
> ignore the latter.
|
||||
|
||||
|
||||
## IPv6 Address Assignment
|
||||
|
||||
Multiple address assignment methods are available:
|
||||
|
||||
| **Type** | **Yang Model** | **Description** |
|
||||
|:---------------- |:-------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| static | ietf-ip | Static assignment of IPv6 address, e.g., *2001:db8:0:1::1/64* |
|
||||
| link-local | ietf-ip[^1] | (RFC4862) Auto-configured link-local IPv6 address (*fe80::0* prefix + interface identifier, e.g., *fe80::ccd2:82ff:fe52:728b/64*) |
|
||||
| global auto-conf | ietf-ip | (RFC4862) Auto-configured (stateless) global IPv6 address (prefix from router + interface identifier, e.g., *2001:db8:0:1:ccd2:82ff:fe52:728b/64* |
|
||||
| dhcp | infix-dhcpv6-client | Assignment of IPv6 address by DHCPv6 server, e.g., *2001:db8::42/128* |
|
||||
|
||||
Both for *link-local* and *global auto-configuration*, it is possible
|
||||
to auto-configure using a random suffix instead of the interface
|
||||
identifier.
|
||||
|
||||
> [!NOTE]
|
||||
> The DHCPv6 address method is only available for *LAN* interfaces
|
||||
> (Ethernet, virtual Ethernet (veth), bridge, link aggregates, etc.)
|
||||
|
||||
Supported DHCPv6 (request) options, configurability (Cfg) and defaults,
|
||||
are listed below. Configurable options can be disabled on a per client
|
||||
interface basis, some options, like `client-id` and `client-fqdn`, are
|
||||
possible to set the value of as well.
|
||||
|
||||
| **Opt** | **Name** | **Cfg** | **Description** |
|
||||
|---------|----------------------------|---------|--------------------------------------------------------|
|
||||
| 1 | `client-id` | Yes | Client identifier (DUID), auto-generated by default |
|
||||
| 2 | `server-id` | Yes | Server identifier (DUID) |
|
||||
| 23 | `dns-server` | Yes | DNS recursive name servers, static ones take precedence|
|
||||
| 24 | `domain-search` | Yes | Domain search list |
|
||||
| 25 | `ia-pd` | Yes | Prefix delegation for downstream networks |
|
||||
| 31 | `sntp-server` | Yes | Simple Network Time Protocol servers |
|
||||
| 32 | `information-refresh-time` | Yes | Refresh time for stateless DHCPv6 |
|
||||
| 39 | `client-fqdn` | Yes | Client FQDN, request DNS update from server |
|
||||
| 56 | `ntp-server` | Yes | NTP time servers, static ones take precedence |
|
||||
| | | | |
|
||||
|
||||
**Default:** `dns-server`, `domain-search`, `ntp-server`
|
||||
|
||||
DHCPv6 supports both **stateful** (address assignment) and **stateless**
|
||||
(information-only) modes:
|
||||
|
||||
- **Stateful DHCPv6**: The server assigns IPv6 addresses to clients. This is
|
||||
the default mode when enabling the DHCPv6 client.
|
||||
- **Stateless DHCPv6**: Used with SLAAC (Stateless Address Autoconfiguration)
|
||||
when only configuration information (DNS, NTP, etc.) is needed. Enable with
|
||||
the `information-only` setting.
|
||||
|
||||
When configuring a DHCPv6 client, ensure that the NTP client is enabled
|
||||
for the `ntp-server` DHCPv6 option to be processed correctly. If the
|
||||
NTP client is not enabled, any NTP servers provided by the DHCPv6 server
|
||||
will be ignored. For details on how to enable the NTP client, see the
|
||||
[NTP Client Configuration](system.md#ntp-client-configuration) section.
|
||||
|
||||
## Examples
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
To illustrate IP address configuration, the examples below uses a
|
||||
switch with a single Ethernet interface (eth0) and a loopback
|
||||
interface (lo). As shown above, these examples assume *eth0* has an
|
||||
IPv6 link-local address and *lo* has static IPv4 and IPv6 addresses by
|
||||
default.
|
||||
|
||||
### Static and link-local IPv4 addresses
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv4</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>set address 10.0.1.1 prefix-length 24</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>set autoconf</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>diff</b>
|
||||
+interfaces {
|
||||
+ interface eth0 {
|
||||
+ ipv4 {
|
||||
+ address 10.0.1.1 {
|
||||
+ prefix-length 24;
|
||||
+ }
|
||||
+ autoconf;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 169.254.1.3/16 (random)
|
||||
ipv4 10.0.1.1/24 (static)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
As shown, the link-local IPv4 address is configured with `set autoconf`.
|
||||
The presence of the `autoconf` container enables IPv4 link-local address
|
||||
assignment. The resulting address (169.254.1.3/16) is of type *random*
|
||||
([ietf-ip.yang][2]).
|
||||
|
||||
The IPv4LL client also supports a `request-address` setting which can be
|
||||
used to "seed" the client's starting address. If the address is free it
|
||||
will be used, otherwise it falls back to the default algorithm.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/eth0/ipv4/> <b>edit autoconf</b>
|
||||
admin@example:/config/interface/eth0/ipv4/autoconf/> <b>set request-address 169.254.1.2</b>
|
||||
admin@example:/config/interface/eth0/ipv4/autoconf/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Use of DHCP for IPv4 address assignment
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv4</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>set dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 10.1.2.100/24 (dhcp)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
The resulting address (10.1.2.100/24) is of type *dhcp*.
|
||||
|
||||
To configure DHCP client options, such as sending a specific hostname to the
|
||||
server, you can specify options with values:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv4 dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv4/dhcp/> <b>set option hostname value myhost</b>
|
||||
admin@example:/config/interface/eth0/ipv4/dhcp/> <b>show</b>
|
||||
option hostname {
|
||||
value myhost;
|
||||
}
|
||||
admin@example:/config/interface/eth0/ipv4/dhcp/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> The special value `auto` can be used with the hostname option to
|
||||
> automatically use the configured system hostname.
|
||||
|
||||
Other useful DHCP options include:
|
||||
|
||||
- `client-id` - Send a specific client identifier to the server
|
||||
- `route-preference` - Set the administrative distance for DHCP-learned routes (default: 5)
|
||||
|
||||
For advanced usage with vendor-specific options, see the YANG model.
|
||||
|
||||
### Use of DHCPv6 for IPv6 address assignment
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8::42/128 (dhcp)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
The resulting address (2001:db8::42/128) is of type *dhcp*.
|
||||
|
||||
To configure DHCPv6 client options, such as requesting prefix delegation
|
||||
for downstream networks, you can specify options:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6 dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>set option ia-pd</b>
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>set option dns-server</b>
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>show</b>
|
||||
option dns-server;
|
||||
option ia-pd;
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
For stateless DHCPv6 (used with SLAAC to get only configuration information):
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6 dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>set information-only true</b>
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>show</b>
|
||||
information-only true;
|
||||
option dns-server;
|
||||
option domain-search;
|
||||
admin@example:/config/interface/eth0/ipv6/dhcp/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Other useful DHCPv6 options include:
|
||||
|
||||
- `duid` - Set a specific DHCPv6 Unique Identifier (auto-generated by default)
|
||||
- `client-fqdn` - Request the server to update DNS records with client's FQDN
|
||||
- `route-preference` - Set the administrative distance for DHCPv6-learned routes (default: 5)
|
||||
|
||||
For advanced usage with vendor-specific options, see the YANG model.
|
||||
|
||||
### Disabling IPv6 link-local address(es)
|
||||
|
||||
The (only) way to disable IPv6 link-local addresses is by disabling IPv6
|
||||
on the interface.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set enabled false</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
### Static IPv6 address
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set address 2001:db8::1 prefix-length 64</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8::1/64 (static)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Stateless Auto-configuration of Global IPv6 Address
|
||||
|
||||

|
||||
|
||||
Stateless address auto-configuration of global addresses is enabled by
|
||||
default. The address is formed by concatenating the network prefix
|
||||
advertised by the router (here 2001:db8:0:1::0/64) and the interface
|
||||
identifier. The resulting address is of type *link-layer*, as it is
|
||||
formed based on the interface identifier ([ietf-ip.yang][2]).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Disabling auto-configuration of global IPv6 addresses can be done as shown
|
||||
below.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-global-addresses false</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Random Link Identifiers for IPv6 Stateless Autoconfiguration
|
||||
|
||||

|
||||
|
||||
By default, the auto-configured link-local and global IPv6 addresses
|
||||
are formed from a link-identifier based on the MAC address.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
To avoid revealing identity information in the IPv6 address, it is
|
||||
possible to specify use of a random identifier ([ietf-ip.yang][2] and
|
||||
[RFC8981][3]).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-temporary-addresses true</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
|
||||
ipv6 fe80::ad3d:b274:885a:9ffb/64 (random)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Both the link-local address (fe80::) and the global address (2001:)
|
||||
have changed type to *random*.
|
||||
|
||||
|
||||
## IPv4 forwarding
|
||||
|
||||
To be able to route (static or dynamic) on the interface it is
|
||||
required to enable forwarding. This setting controls if packets
|
||||
received on this interface can be forwarded.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface eth0</b>
|
||||
admin@example:/config/interface/eth0/> <b>set ipv4 forwarding</b>
|
||||
admin@example:/config/interface/eth0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## IPv6 forwarding
|
||||
|
||||
Due to how the Linux kernel manages IPv6 forwarding, we can not fully
|
||||
control it per interface via this setting like how IPv4 works. Instead,
|
||||
IPv6 forwarding is globally enabled when at least one interface enable
|
||||
forwarding, otherwise it is disabled.
|
||||
|
||||
The following table shows the system IPv6 features that the `forwarding`
|
||||
setting control when it is *Enabled* or *Disabled:
|
||||
|
||||
| **IPv6 Feature** | **Enabled** | **Disabled** |
|
||||
|:-----------------------------------------|:------------|:-------------|
|
||||
| IsRouter set in Neighbour Advertisements | Yes | No |
|
||||
| Transmit Router Solicitations | No | Yes |
|
||||
| Router Advertisements are ignored | Yes | Yes |
|
||||
| Accept Redirects | No | Yes |
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface eth0</b>
|
||||
admin@example:/config/interface/eth0/> <b>set ipv6 forwarding</b>
|
||||
admin@example:/config/interface/eth0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
[1]: https://www.rfc-editor.org/rfc/rfc3442
|
||||
[2]: https://www.rfc-editor.org/rfc/rfc8344
|
||||
[3]: https://www.rfc-editor.org/rfc/rfc8981
|
||||
|
||||
[^1]: Link-local IPv6 addresses are implicitly enabled when enabling
|
||||
IPv6. IPv6 can be enabled/disabled per interface in the
|
||||
[ietf-ip][2] YANG model.
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
# Link Aggregation
|
||||
|
||||
A link aggregate, or *lag*, allows multiple physical interfaces to be
|
||||
combined into a single logical interface, providing increased bandwidth
|
||||
(in some cases) and redundancy (primarily). Two modes of qualifying lag
|
||||
member ports are available:
|
||||
|
||||
1. **static**: Active members selected based on link status (carrier)
|
||||
2. **lacp:** IEEE 802.3ad Link Aggregation Control Protocol
|
||||
|
||||
In LACP mode, LACPDUs are exchanged by the link partners to qualify each
|
||||
lag member, while in static mode only carrier is used. This additional
|
||||
exchange in LACP ensures traffic can be forwarded in both directions.
|
||||
|
||||
Traffic distribution, for both modes, across the active lag member ports
|
||||
is determined by the hash policy[^1]. It uses an XOR of the source,
|
||||
destination MAC addresses and the EtherType field. This, IEEE
|
||||
802.3ad-compliant, algorithm will place all traffic to a particular
|
||||
network peer on the same link. Meaning there is no increased bandwidth
|
||||
for communication between two specific devices.
|
||||
|
||||
> [!TIP]
|
||||
> Similar to other interface types, naming your interface `lagN`, where
|
||||
> `N` is a number, allows the CLI to automatically infer the interface
|
||||
> type as LAG.
|
||||
|
||||
|
||||
## Basic Configuration
|
||||
|
||||
Creating a link aggregate interface and adding member ports:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface lag0</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag mode static</b>
|
||||
admin@example:/config/interface/lag0/> <b>end</b>
|
||||
admin@example:/config/> <b>set interface eth7 lag-port lag lag0</b>
|
||||
admin@example:/config/> <b>set interface eth8 lag-port lag lag0</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
A static lag responds only to link (carrier) changes of member ports.
|
||||
E.g., in this example egressing traffic is continuously distributed over
|
||||
the two links until link down on one link is detected, triggering all
|
||||
traffic to be steered to the sole remaining link.
|
||||
|
||||
|
||||
## LACP Configuration
|
||||
|
||||
LACP mode provides dynamic negotiation of the link aggregate. Key
|
||||
settings include:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface lag0</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag mode lacp</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag lacp mode passive</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag lacp rate fast</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag lacp system-priority 100</b>
|
||||
</code></pre>
|
||||
|
||||
LACP mode supports two operational modes:
|
||||
|
||||
- **active:** Initiates negotiation by sending LACPDUs (default)
|
||||
- **passive:** Waits for peer to initiate negotiation
|
||||
|
||||
> [!NOTE]
|
||||
> At least one end of the link must be in active mode for negotiation to occur.
|
||||
|
||||
The LACP rate setting controls protocol timing:
|
||||
|
||||
- **slow:** LACPDUs sent every 30 seconds, with 90 second timeout (default)
|
||||
- **fast:** LACPDUs sent every second, with 3 second timeout
|
||||
|
||||
|
||||
## Link Flapping
|
||||
|
||||
To protect against link flapping, debounce timers can be configured to
|
||||
delay link qualification. Usually only the `up` delay is needed:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/lag0/lag/link-monitor/> <b>edit debounce</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>set up 500</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>set down 200</b>
|
||||
</code></pre>
|
||||
|
||||
## Operational Status, Overview
|
||||
|
||||
Like other interfaces, link aggregates are also available in the general
|
||||
interfaces overview in the CLI admin-exec context. Here is the above
|
||||
static mode aggregate:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP static: balance-xor, hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE
|
||||
└ eth8 lag ACTIVE
|
||||
</code></pre>
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Operational Status, Detail
|
||||
|
||||
In addition to basic status shown in the interface overview, detailed
|
||||
LAG status can be inspected:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||
name : lag0
|
||||
index : 25
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : static
|
||||
lag type : balance-xor
|
||||
lag hash : layer2
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 0
|
||||
out-octets : 2142
|
||||
</code></pre>
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||
name : lag0
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : lacp
|
||||
lag hash : layer2
|
||||
lacp mode : active
|
||||
lacp rate : fast (1s)
|
||||
lacp aggregate id : 1
|
||||
lacp system priority: 65535
|
||||
lacp actor key : 9
|
||||
lacp partner key : 9
|
||||
lacp partner mac : 00:a0:85:00:03:00
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 100892
|
||||
out-octets : 111776
|
||||
</code></pre>
|
||||
|
||||
Member ports provide additional status information:
|
||||
|
||||
- Link failure counter: number of detected link failures
|
||||
- LACP state flags: various states of LACP negotiation:
|
||||
- `active`: port is actively sending LACPDUs
|
||||
- `short_timeout`: using fast rate (1s) vs. slow rate (30s)
|
||||
- `aggregating`: port is allowed to aggregate in this LAG
|
||||
- `in_sync`: port is synchronized with partner
|
||||
- `collecting`: port is allowed to receive traffic
|
||||
- `distributing`: port is allowed to send traffic
|
||||
- `defaulted`: using default partner info (partner not responding)
|
||||
- `expired`: partner info has expired (no LACPDUs received)
|
||||
- Aggregator ID: unique identifier for this LAG group
|
||||
- Actor state: LACP state flags for this port (local)
|
||||
- Partner state: LACP state flags from the remote port
|
||||
|
||||
Example member port status:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth7</b>
|
||||
name : eth7
|
||||
index : 8
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag member : lag0
|
||||
lag member state : active
|
||||
lacp aggregate id : 1
|
||||
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
link failure count : 0
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 473244
|
||||
out-octets : 499037
|
||||
</code></pre>
|
||||
|
||||
|
||||
## Example: Switch Uplink with LACP
|
||||
|
||||
LACP mode provides the most robust operation, automatically negotiating
|
||||
the link aggregate and detecting configuration mismatches.
|
||||
|
||||
A common use case is connecting a switch to an upstream device:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface lag0</b>
|
||||
admin@example:/config/interface/lag0/> <b>set lag mode lacp</b>
|
||||
</code></pre>
|
||||
|
||||
Enable fast LACP for quicker fail-over:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/lag0/> <b>set lag lacp rate fast</b>
|
||||
</code></pre>
|
||||
|
||||
Add uplink ports
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/lag0/> <b>end</b>
|
||||
admin@example:/config/> <b>set interface eth7 lag-port lag lag0</b>
|
||||
admin@example:/config/> <b>set interface eth8 lag-port lag lag0</b>
|
||||
</code></pre>
|
||||
|
||||
Enable protection against "link flapping".
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/lag0/> <b>edit lag link-monitor</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/> <b>edit debounce</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>set up 500</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>set down 200</b>
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>top</b>
|
||||
</code></pre>
|
||||
|
||||
Add to bridge for switching
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/lag0/lag/link-monitor/debounce/> <b>end</b>
|
||||
admin@example:/config/> <b>set interface lag0 bridge-port bridge br0</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
[^1]: `(source MAC XOR destination MAC XOR EtherType) MODULO num_links`
|
||||
+40
-48
@@ -9,22 +9,20 @@ as NETCONF, RESTCONF, and CLI via SSH or Console.
|
||||
An SSH server (SSHv2) is provided for remote management. It can be
|
||||
enabled/disabled as shown below.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit ssh
|
||||
admin@example:/config/ssh/> set enabled
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit ssh</b>
|
||||
admin@example:/config/ssh/> <b>set enabled</b>
|
||||
admin@example:/config/ssh/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
By default the SSH server accepts connections to port 22 on all its IP
|
||||
addresses, but this can be adjusted using the `listen` command. To
|
||||
make the server (only) listen for incoming connections to IP address
|
||||
_192.168.1.1_ and port _12345_ the following commands can be used.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit ssh
|
||||
admin@example:/config/ssh/> show
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit ssh</b>
|
||||
admin@example:/config/ssh/> <b>show</b>
|
||||
enabled true;
|
||||
hostkey genkey;
|
||||
listen ipv4 {
|
||||
@@ -35,12 +33,12 @@ listen ipv6 {
|
||||
address ::;
|
||||
port 22;
|
||||
}
|
||||
admin@example:/config/ssh/> no listen ipv6
|
||||
admin@example:/config/ssh/> edit listen ipv4
|
||||
admin@example:/config/ssh/listen/ipv4/> set address 192.168.1.1
|
||||
admin@example:/config/ssh/listen/ipv4/> set port 12345
|
||||
admin@example:/config/ssh/> <b>no listen ipv6</b>
|
||||
admin@example:/config/ssh/> <b>edit listen ipv4</b>
|
||||
admin@example:/config/ssh/listen/ipv4/> <b>set address 192.168.1.1</b>
|
||||
admin@example:/config/ssh/listen/ipv4/> <b>set port 12345</b>
|
||||
admin@example:/config/ssh/listen/ipv4/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The default SSH hostkey is generated on first boot and is used in both
|
||||
SSH and NETCONF (SSH transport). Custom keys can be added to the
|
||||
@@ -62,9 +60,10 @@ created by OpenSSL.
|
||||
After the key has been stored in the keystore and given the name
|
||||
_mykey_ it can be added to SSH configuration:
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit ssh
|
||||
admin@example:/config/ssh/> set hostkey mykey
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit ssh</b>
|
||||
admin@example:/config/ssh/> <b>set hostkey mykey</b>
|
||||
</code></pre>
|
||||
|
||||
## Console Port
|
||||
|
||||
@@ -78,9 +77,8 @@ connected to the console port of the device. The serial port is
|
||||
typically setup to run at 115200 baud, 8N1.
|
||||
|
||||
|
||||
```
|
||||
Infix OS — Immutable.Friendly.Secure v24.11.1 (ttyS0)
|
||||
example login: admin
|
||||
<pre class="cli"><code>Infix OS — Immutable.Friendly.Secure v24.11.1 (ttyS0)
|
||||
example login: <b>admin</b>
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
@@ -90,26 +88,24 @@ Password:
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
admin@example:~$
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The `resize` command can be used to update terminal settings to the
|
||||
size of your terminal window.
|
||||
|
||||
```
|
||||
admin@example:~$ resize
|
||||
<pre class="cli"><code>admin@example:~$ <b>resize</b>
|
||||
COLUMNS=115;LINES=59;export COLUMNS LINES;
|
||||
admin@example:~$
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
CLI can be entered from shell in the same way as for SSH.
|
||||
|
||||
```
|
||||
admin@example:~$ cli
|
||||
<pre class="cli"><code>admin@example:~$ <b>cli</b>
|
||||
|
||||
See the 'help' command for an introduction to the system
|
||||
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
@@ -117,7 +113,7 @@ e1 ethernet LOWER-DOWN 00:53:00:06:03:01
|
||||
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
|
||||
...
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
## Web, Web-console and RESTCONF
|
||||
|
||||
@@ -132,27 +128,25 @@ There is also a *Netbrowse* Web service presenting information about
|
||||
the unit's neighbors, collected via mDNS (see
|
||||
[Discovery](discovery.md) for more details).
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit web
|
||||
admin@example:/config/web/> help
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit web</b>
|
||||
admin@example:/config/web/> <b>help</b>
|
||||
enabled Enable or disable on all web services.
|
||||
console Web console interface.
|
||||
netbrowse mDNS Network Browser.
|
||||
restconf IETF RESTCONF Server.
|
||||
admin@example:/config/web/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### Enable/disable Web Service and Server
|
||||
|
||||
The Web service can be enabled as shown below.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit web
|
||||
admin@example:/config/web/> set enabled
|
||||
admin@example:/config/web/>
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit web</b>
|
||||
admin@example:/config/web/> <b>set enabled</b>
|
||||
admin@example:/config/web/>
|
||||
</code></pre>
|
||||
|
||||
Enabling the Web service implies that a Web server is
|
||||
enabled. Currently this Web server provides generic Infix information,
|
||||
@@ -172,11 +166,10 @@ The Web console has its own enable/disable setting, but will only be
|
||||
activated if the Web service is enabled. The example below shows how
|
||||
to disable the Web console.
|
||||
|
||||
```
|
||||
admin@example:/config/web/> edit console
|
||||
admin@example:/config/web/console/> no enabled
|
||||
<pre class="cli"><code>admin@example:/config/web/> <b>edit console</b>
|
||||
admin@example:/config/web/console/> <b>no enabled</b>
|
||||
admin@example:/config/web/console/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### Enable/disable RESTCONF Service
|
||||
|
||||
@@ -188,11 +181,10 @@ The RESTCONF service has its own enable/disable setting, but will
|
||||
only be activated if the Web service is enabled. The example below
|
||||
shows how to disable the RESTCONF service.
|
||||
|
||||
```
|
||||
admin@example:/config/web/> edit restconf
|
||||
admin@example:/config/web/restconf/> no enabled
|
||||
<pre class="cli"><code>admin@example:/config/web/> <b>edit restconf</b>
|
||||
admin@example:/config/web/restconf/> <b>no enabled</b>
|
||||
admin@example:/config/web/restconf/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
## System Upgrade
|
||||
|
||||
|
||||
+22
-26
@@ -399,11 +399,11 @@ operators can immediately configure them without updating NACM rules.
|
||||
|
||||
**Effective permissions by group:**
|
||||
|
||||
| Group | Read | Write | Exec | Exceptions |
|
||||
|-------|------|-------|------|------------|
|
||||
| admin | All | All | All | None |
|
||||
| operator | All | All | All | Cannot access passwords, keystore, truststore |
|
||||
| guest | All | None | None | Read-only access |
|
||||
| Group | Read | Write | Exec | Exceptions |
|
||||
|----------|------|-------|------|-----------------------------------------------|
|
||||
| admin | All | All | All | None |
|
||||
| operator | All | All | All | Cannot access passwords, keystore, truststore |
|
||||
| guest | All | None | None | Read-only access |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
@@ -505,8 +505,7 @@ Deny access to sensitive data for all users (except admins with permit-all):
|
||||
|
||||
Check what NACM groups a user belongs to:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm</b>
|
||||
enabled : yes
|
||||
default read access : permit
|
||||
default write access : permit
|
||||
@@ -524,77 +523,74 @@ denied notifications : 0
|
||||
└──────────┴─────────┴─────────┴─────────┘
|
||||
✓ Full ⚠ Restricted ✗ Denied
|
||||
|
||||
USER SHELL LOGIN
|
||||
<span class="header">USER SHELL LOGIN </span>
|
||||
admin bash password+key
|
||||
jacky bash password
|
||||
monitor false key
|
||||
|
||||
GROUP USERS
|
||||
<span class="header">GROUP USERS </span>
|
||||
admin admin
|
||||
operator jacky
|
||||
guest monitor
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
For details about a group's restrictions, use `show nacm group <name>`:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm group operator
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm group operator</b>
|
||||
members : jacky
|
||||
read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
applicable rules : 4
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
permit-system-rpcs
|
||||
<span class="title">permit-system-rpcs</span>
|
||||
action : permit
|
||||
operations : exec
|
||||
target : ietf-system (rpc: *)
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-password-access (via '*')
|
||||
<span class="title">deny-password-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : /ietf-system:system/authentication/user/password
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-keystore-access (via '*')
|
||||
<span class="title">deny-keystore-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-keystore
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-truststore-access (via '*')
|
||||
<span class="title">deny-truststore-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-truststore
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### Testing Access
|
||||
|
||||
The easiest way to test NACM permissions is to log in as the user and try
|
||||
the operation:
|
||||
|
||||
```bash
|
||||
$ ssh jacky@host
|
||||
jacky@example:/> configure
|
||||
jacky@example:/config/> edit system authentication user admin
|
||||
jacky@example:/config/system/authentication/user/admin/> set authorized-key foo
|
||||
<pre class="cli"><code>$ ssh jacky@host
|
||||
jacky@example:/> <b>configure</b>
|
||||
jacky@example:/config/> <b>edit system authentication user admin</b>
|
||||
jacky@example:/config/system/authentication/user/admin/> <b>set authorized-key foo</b>
|
||||
Error: Access to the data model "ietf-system" is denied because "jacky" NACM authorization failed.
|
||||
Error: Failed applying changes (2).
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### NACM Statistics
|
||||
|
||||
NACM tracks denied operations. If you suspect permission issues, check
|
||||
the statistics:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm</b>
|
||||
...
|
||||
denied operations : 5
|
||||
denied data writes : 12
|
||||
...
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Increasing counters indicate permission denials are occurring.
|
||||
|
||||
|
||||
+10
-1717
File diff suppressed because it is too large
Load Diff
+75
-57
@@ -13,37 +13,34 @@ while serving time to downstream clients.
|
||||
|
||||
Configure a standalone NTP server using only a local reference clock:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit ntp
|
||||
admin@example:/config/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit ntp</b>
|
||||
admin@example:/config/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
When setting up NTP via the CLI the system automatically configures a local
|
||||
reference clock. The default [stratum](#ntp-stratum-levels) is 16 (unsynchronized),
|
||||
which is suitable for isolated networks. For production use, configure a specific
|
||||
stratum level:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit ntp
|
||||
admin@example:/config/ntp/> set refclock-master master-stratum 10
|
||||
admin@example:/config/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit ntp</b>
|
||||
admin@example:/config/ntp/> <b>set refclock-master master-stratum 10</b>
|
||||
admin@example:/config/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
## Server Mode
|
||||
|
||||
Synchronize from upstream NTP servers while serving time to clients:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit ntp
|
||||
admin@example:/config/ntp/> edit unicast-configuration 0.pool.ntp.org type uc-server
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set iburst true
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> end
|
||||
admin@example:/config/ntp/> edit unicast-configuration 1.pool.ntp.org type uc-server
|
||||
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> set iburst true
|
||||
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> end
|
||||
admin@example:/config/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit ntp</b>
|
||||
admin@example:/config/ntp/> <b>edit unicast-configuration 0.pool.ntp.org type uc-server</b>
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> <b>set iburst true</b>
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> <b>end</b>
|
||||
admin@example:/config/ntp/> <b>edit unicast-configuration 1.pool.ntp.org type uc-server</b>
|
||||
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> <b>set iburst true</b>
|
||||
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> <b>end</b>
|
||||
admin@example:/config/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The `unicast-configuration` uses a composite key with both address and type.
|
||||
Both hostnames and IP addresses are supported. The `iburst` option enables
|
||||
@@ -56,23 +53,21 @@ Each server acts as both client and server to the other:
|
||||
|
||||
**First peer:**
|
||||
|
||||
```
|
||||
admin@peer1:/config/> edit ntp
|
||||
admin@peer1:/config/ntp/> edit unicast-configuration 192.168.1.2 type uc-peer
|
||||
admin@peer1:/config/ntp/…/192.168.1.2/type/uc-peer/> end
|
||||
admin@peer1:/config/ntp/> set refclock-master master-stratum 8
|
||||
admin@peer1:/config/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@peer1:/config/> <b>edit ntp</b>
|
||||
admin@peer1:/config/ntp/> <b>edit unicast-configuration 192.168.1.2 type uc-peer</b>
|
||||
admin@peer1:/config/ntp/…/192.168.1.2/type/uc-peer/> <b>end</b>
|
||||
admin@peer1:/config/ntp/> <b>set refclock-master master-stratum 8</b>
|
||||
admin@peer1:/config/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Second peer:**
|
||||
|
||||
```
|
||||
admin@peer2:/config/> edit ntp
|
||||
admin@peer2:/config/ntp/> edit unicast-configuration 192.168.1.1 type uc-peer
|
||||
admin@peer2:/config/ntp/…/192.168.1.1/type/uc-peer/> end
|
||||
admin@peer2:/config/ntp/> set refclock-master master-stratum 8
|
||||
admin@peer2:/config/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@peer2:/config/> <b>edit ntp</b>
|
||||
admin@peer2:/config/ntp/> <b>edit unicast-configuration 192.168.1.1 type uc-peer</b>
|
||||
admin@peer2:/config/ntp/…/192.168.1.1/type/uc-peer/> <b>end</b>
|
||||
admin@peer2:/config/ntp/> <b>set refclock-master master-stratum 8</b>
|
||||
admin@peer2:/config/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
This configuration provides mutual synchronization between peers. If one peer
|
||||
fails, the other continues to serve time to clients.
|
||||
@@ -103,12 +98,11 @@ the other peer.
|
||||
|
||||
Control how often the NTP server polls upstream sources:
|
||||
|
||||
```
|
||||
admin@example:/config/ntp/> edit unicast-configuration 0.pool.ntp.org type uc-server
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set minpoll 4
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set maxpoll 10
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> end
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/ntp/> <b>edit unicast-configuration 0.pool.ntp.org type uc-server</b>
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> <b>set minpoll 4</b>
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> <b>set maxpoll 10</b>
|
||||
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> <b>end</b>
|
||||
</code></pre>
|
||||
|
||||
Poll intervals are specified as powers of 2:
|
||||
- `minpoll 4` = poll every 2^4 = 16 seconds (minimum polling rate)
|
||||
@@ -126,12 +120,11 @@ critical for embedded systems without RTC that boot with epoch time.
|
||||
|
||||
To customize the values:
|
||||
|
||||
```
|
||||
admin@example:/config/ntp/> edit makestep
|
||||
admin@example:/config/ntp/makestep/> set threshold 2.0
|
||||
admin@example:/config/ntp/makestep/> set limit 1
|
||||
admin@example:/config/ntp/makestep/> end
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/ntp/> <b>edit makestep</b>
|
||||
admin@example:/config/ntp/makestep/> <b>set threshold 2.0</b>
|
||||
admin@example:/config/ntp/makestep/> <b>set limit 1</b>
|
||||
admin@example:/config/ntp/makestep/> <b>end</b>
|
||||
</code></pre>
|
||||
|
||||
- **threshold** - If clock offset exceeds this (in seconds), step immediately
|
||||
instead of slewing slowly
|
||||
@@ -143,19 +136,44 @@ correct time within seconds instead of hours.
|
||||
|
||||
## Monitoring
|
||||
|
||||
Check NTP server statistics:
|
||||
For a quick overview:
|
||||
|
||||
```
|
||||
admin@example:/> show ntp server
|
||||
NTP SERVER CONFIGURATION
|
||||
Local Stratum : 10
|
||||
To view the sources being used by the NTP client, run:
|
||||
|
||||
SERVER STATISTICS
|
||||
Packets Received : 142
|
||||
Packets Sent : 142
|
||||
Packets Dropped : 0
|
||||
Send Failures : 0
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>show ntp</b>
|
||||
Mode : Client
|
||||
Stratum : 3
|
||||
Ref time (UTC) : Sat Jan 24 23:41:42 2026
|
||||
|
||||
<span class="header">ADDRESS MODE STATE STRATUM POLL</span>
|
||||
147.78.228.41 server outlier 2 64s
|
||||
192.168.0.1 server unusable 0 128s
|
||||
176.126.86.247 server selected 2 64s
|
||||
</code></pre>
|
||||
|
||||
Check NTP source status:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ntp source</b>
|
||||
<span class="header">MS Name/IP address Stratum Poll Reach LastRx Last sample</span>
|
||||
^+ 147.78.228.41 2 6 007 15 -431us +/- 33.573ms
|
||||
^* 176.126.86.247 2 6 007 14 -389us +/- 4.307ms
|
||||
</code></pre>
|
||||
|
||||
For detailed information about a specific source:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ntp source 176.126.86.247</b>
|
||||
Address : 176.126.86.247
|
||||
Mode : Server (client mode) [^]
|
||||
State : Selected sync source [*]
|
||||
Configured : Yes
|
||||
Stratum : 2
|
||||
Poll interval : 7 (2^7 seconds = 128s)
|
||||
Reachability : 377 (octal) = 11111111b
|
||||
Last RX : 75s ago
|
||||
Offset : +2.0us (+0.002000ms)
|
||||
Delay : 4.270ms (0.004270s)
|
||||
Dispersion : 205.0us (0.205000ms)
|
||||
</code></pre>
|
||||
|
||||
## NTP Stratum Levels
|
||||
|
||||
|
||||
+8
-9
@@ -91,15 +91,14 @@ These `ingress-qos` and `egress-qos` settings are done per VLAN, both
|
||||
defaulting to '0'. The example below shows how to keep the PCP priority
|
||||
for packets being routed between two VLAN interfaces.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface e1.10
|
||||
admin@example:/config/interface/e1.10/> set vlan ingress-qos priority from-pcp
|
||||
admin@example:/config/interface/e1.10/> up
|
||||
admin@example:/config/> edit interface e1.20
|
||||
admin@example:/config/interface/e1.20/> set vlan egress-qos pcp from-priority
|
||||
admin@example:/config/interface/e1.20/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface e1.10</b>
|
||||
admin@example:/config/interface/e1.10/> <b>set vlan ingress-qos priority from-pcp</b>
|
||||
admin@example:/config/interface/e1.10/> <b>up</b>
|
||||
admin@example:/config/> <b>edit interface e1.20</b>
|
||||
admin@example:/config/interface/e1.20/> <b>set vlan egress-qos pcp from-priority</b>
|
||||
admin@example:/config/interface/e1.20/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
## A complex example
|
||||
|
||||
|
||||
+453
@@ -0,0 +1,453 @@
|
||||
# Routing
|
||||
|
||||
Currently supported YANG models:
|
||||
|
||||
| **YANG Model** | **Description** |
|
||||
|:--------------------------|:--------------------------------|
|
||||
| ietf-routing | Base model for all other models |
|
||||
| ietf-ipv4-unicast-routing | Static IPv4 unicast routing |
|
||||
| ietf-ipv6-unicast-routing | Static IPv6 unicast routing |
|
||||
| ietf-ospf | OSPF routing |
|
||||
| ietf-rip | RIP routing |
|
||||
| infix-routing | Infix deviations and extensions |
|
||||
|
||||
The base model, ietf-routing, is where all the other models hook in. It
|
||||
is used to set configuration and read operational status (RIB tables) in
|
||||
the other models.
|
||||
|
||||
> [!NOTE]
|
||||
> The standard IETF routing models allows multiple instances, but Infix
|
||||
> currently *only support one instance* per routing protocol! In the
|
||||
> examples presented here, the instance name `default` is used.
|
||||
|
||||
|
||||
## IPv4 Static routes
|
||||
|
||||
The standard IETF model for static routes reside under the `static`
|
||||
control plane protocol. For our examples we use the instance name
|
||||
`default`, you can use any name.
|
||||
|
||||
For a route with destination 192.168.200.0/24 via 192.168.1.1:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit routing control-plane-protocol static name default ipv4</b>
|
||||
admin@example:/config/routing/…/ipv4/> <b>set route 192.168.200.0/24 next-hop next-hop-address 192.168.1.1</b>
|
||||
admin@example:/config/routing/…/ipv4/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
For a "floating" static route with destination 10.0.0.0/16 via a backup
|
||||
router 192.168.1.1, using the highest possible distance:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit routing control-plane-protocol static name default ipv4</b>
|
||||
admin@example:/config/routing/…/ipv4/> <b>set route 10.0.0.0/16 next-hop next-hop-address 192.168.1.1 route-preference 254</b>
|
||||
admin@example:/config/routing/…/ipv4/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Remember to enable [IPv4 forwarding](ip.md#ipv4-forwarding) for the
|
||||
> interfaces you want to route between.
|
||||
|
||||
|
||||
## IPv6 Static routes
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit routing control-plane-protocol static name default ipv6</b>
|
||||
admin@example:/config/routing/…/ipv6/> <b>set route 2001:db8:3c4d:200::/64 next-hop next-hop-address 2001:db8:3c4d:1::1</b>
|
||||
admin@example:/config/routing/…/ipv6/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## OSPFv2 Routing
|
||||
|
||||
The system supports OSPF dynamic routing for IPv4, i.e., OSPFv2. To
|
||||
enable OSPF and set one active interface in area 0:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 enabled</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Remember to enable [IPv4 forwarding](ip.md#ipv4-forwarding) for all the
|
||||
> interfaces you want to route between.
|
||||
|
||||
|
||||
### OSPF area types
|
||||
|
||||
In addition to *regular* OSPF areas, area types *NSSA* and *Stub* are
|
||||
also supported. To configure an NSSA area with summary routes:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.1 area-type nssa-area</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.1 summary true</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Bidirectional Forwarding Detection (BFD)
|
||||
|
||||
It is possible to enable BFD per OSPF interface to speed up detection of
|
||||
link loss.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 bfd enabled true</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### OSPF interface settings
|
||||
|
||||
We have already seen how to enable OSPF per interface (*enabled true*)
|
||||
and BFD for OSPF per interface (*bfd enabled true*). These and other
|
||||
OSPF interface settings are done in context of an OSFP area, e.g., *area
|
||||
0.0.0.0*. Available commands can be listed using the `?` mark.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/routing/…/> <b>edit ospf area 0.0.0.0</b>
|
||||
admin@example:/config/routing/…/ospf/area/0.0.0.0/> <b>edit interface e0</b>
|
||||
admin@example:/config/routing/…/ospf/area/0.0.0.0/interface/e0/> <b>set ?</b>
|
||||
bfd BFD interface configuration.
|
||||
cost Interface's cost.
|
||||
dead-interval Interval after which a neighbor is declared down
|
||||
enabled Enables/disables the OSPF protocol on the interface.
|
||||
hello-interval Interval between Hello packets (seconds). It must
|
||||
interface-type Interface type.
|
||||
passive Enables/disables a passive interface. A passive
|
||||
retransmit-interval Interval between retransmitting unacknowledged Link
|
||||
transmit-delay Estimated time needed to transmit Link State Update
|
||||
admin@example:/config/routing/…/ospf/area/0.0.0.0/interface/e0/> set
|
||||
</code></pre>
|
||||
|
||||
For example, setting the OSPF *interface type* to *point-to-point* for
|
||||
an Ethernet interface can be done as follows.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/routing/…/ospf/area/0.0.0.0/interface/e0/> <b>set interface-type point-to-point</b>
|
||||
admin@example:/config/routing/…/ospf/area/0.0.0.0/interface/e0/>
|
||||
</code></pre>
|
||||
|
||||
### OSPF global settings
|
||||
|
||||
In addition to *area* and *interface* specific settings, OSPF provides
|
||||
global settings for route redistribution and OSPF router identifier.
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@example:/config/routing/…/ospf/> <b>set ?</b>
|
||||
area List of OSPF areas.
|
||||
default-route-advertise Distribute default route to network
|
||||
explicit-router-id Defined in RFC 2328. A 32-bit number
|
||||
redistribute Redistribute protocols into OSPF
|
||||
admin@example:/config/routing/…/ospf/> set
|
||||
</code></pre>
|
||||
|
||||
- Explicit router ID: By default the router will pick an IP address
|
||||
from one of its OSPF interfaces as OSPF router ID. An explicit ID is
|
||||
used to get a deterministic behavior, e.g., `set explicit-router-id
|
||||
1.1.1.1`.
|
||||
- Redistribution: `set redistribute static` and `set redistribute connected`
|
||||
can be used to include static or connected routes into the OSPF routing
|
||||
domain. These routes are redistributed as *external type-2* (E2)
|
||||
routes.
|
||||
- Advertising default route: An OSPF router can be made to distribute
|
||||
a default route into the OSPF domain by command `set
|
||||
default-route-advertise enabled`. This route is distributed as long
|
||||
as the router itself has an *active* default route in its routing
|
||||
table. By adding command `set default-route-advertise always` the
|
||||
router will distribute a default route even when it lacks a default
|
||||
route. The default route will be distributed as an *external type-2*
|
||||
(E2) route.
|
||||
|
||||
|
||||
### Debug OSPFv2
|
||||
|
||||
Using NETCONF and the YANG model *ietf-routing* it is possible to read
|
||||
the OSPF routing table, neighbors and more, that may be useful for
|
||||
debugging the OSPFv2 setup. The CLI has various OSPF status commands
|
||||
such as `show ospf neighbor`, `show ospf interface` and `show ospf
|
||||
routes`.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ospf neighbor</b>
|
||||
<span class="header">Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL</span>
|
||||
10.1.1.2 1 Full/- 3h46m59s 30.177s 10.1.1.2 e0:10.1.1.1 0 0 0
|
||||
10.1.1.3 1 Full/- 3h46m55s 34.665s 10.1.1.3 e1:10.1.1.1 0 0 0
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
For more detailed troubleshooting, OSPF debug logging can be enabled to
|
||||
capture specific protocol events. Debug messages are written to the
|
||||
routing log file (`/var/log/routing`).
|
||||
|
||||
> [!CAUTION]
|
||||
> Debug logging significantly increases log output and may impact
|
||||
> performance. Only enable debug categories needed for troubleshooting,
|
||||
> and disable them when done.
|
||||
|
||||
To enable specific OSPF debug categories:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf debug</b>
|
||||
admin@example:/config/routing/…/ospf/debug/> <b>set bfd true</b>
|
||||
admin@example:/config/routing/…/ospf/debug/> <b>set nsm true</b>
|
||||
admin@example:/config/routing/…/ospf/debug/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Available debug categories include:
|
||||
|
||||
- `bfd`: BFD (Bidirectional Forwarding Detection) events
|
||||
- `packet`: Detailed packet debugging (all OSPF packets)
|
||||
- `ism`: Interface State Machine events
|
||||
- `nsm`: Neighbor State Machine events
|
||||
- `default-information`: Default route origination
|
||||
- `nssa`: Not-So-Stubby Area events
|
||||
|
||||
All debug options are disabled by default. Refer to the `infix-routing`
|
||||
YANG model for the complete list of available debug options.
|
||||
|
||||
To view current debug settings:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show running-config routing control-plane-protocol</b>
|
||||
</code></pre>
|
||||
|
||||
To disable all debug logging, simply delete the debug settings or set
|
||||
all options back to `false`:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>delete routing control-plane-protocol ospfv2 name default ospf debug</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## RIP Routing
|
||||
|
||||
The system supports RIP dynamic routing for IPv4, i.e., RIPv2. To enable
|
||||
RIP and set active interfaces:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ripv2 name default rip</b>
|
||||
admin@example:/config/routing/…/rip/> <b>set interfaces interface e0</b>
|
||||
admin@example:/config/routing/…/rip/> <b>set interfaces interface e1</b>
|
||||
admin@example:/config/routing/…/rip/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Remember to enable [IPv4 forwarding](ip.md#ipv4-forwarding) for all the
|
||||
> interfaces you want to route between.
|
||||
|
||||
|
||||
### RIP interface settings
|
||||
|
||||
By default, interfaces send and receive RIPv2 packets. To control the
|
||||
RIP version per interface:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/routing/…/rip/> <b>edit interfaces interface e0</b>
|
||||
admin@example:/config/routing/…/rip/interfaces/interface/e0/> <b>set send-version 1</b>
|
||||
admin@example:/config/routing/…/rip/interfaces/interface/e0/> <b>set receive-version 1-2</b>
|
||||
admin@example:/config/routing/…/rip/interfaces/interface/e0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Valid version values are `1`, `2`, or `1-2` (both versions).
|
||||
|
||||
To configure a passive interface (advertise network but don't send/receive
|
||||
RIP updates):
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/routing/…/rip/> <b>edit interfaces interface e0</b>
|
||||
admin@example:/config/routing/…/rip/interfaces/interface/e0/> <b>set passive</b>
|
||||
admin@example:/config/routing/…/rip/interfaces/interface/e0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### RIP global settings
|
||||
|
||||
RIP supports redistribution of connected and static routes:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/routing/…/rip/> <b>set redistribute connected</b>
|
||||
admin@example:/config/routing/…/rip/> <b>set redistribute static</b>
|
||||
admin@example:/config/routing/…/rip/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Debug RIPv2
|
||||
|
||||
The CLI provides various RIP status commands:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ip rip</b>
|
||||
Default version control: send version 2, receive version 2
|
||||
<span class="header"> Interface Send Recv Key-chain </span>
|
||||
e0 2 2
|
||||
e1 2 2
|
||||
|
||||
Routing for Networks:
|
||||
e0
|
||||
e1
|
||||
|
||||
Routing Information Sources:
|
||||
<span class="header"> Gateway BadPackets BadRoutes Distance Last Update</span>
|
||||
10.0.1.2 0 0 120 00:00:16
|
||||
Distance: (default is 120)
|
||||
|
||||
admin@example:/> <b>show ip rip neighbor</b>
|
||||
<span class="header">ADDRESS BAD-PACKETS BAD-ROUTES </span>
|
||||
10.0.1.2 0 0
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
For more detailed troubleshooting, RIP debug logging can be enabled to
|
||||
capture specific protocol events. Debug messages are written to the
|
||||
routing log file (`/var/log/routing`).
|
||||
|
||||
> [!CAUTION]
|
||||
> Debug logging significantly increases log output and may impact
|
||||
> performance. Only enable debug categories needed for troubleshooting,
|
||||
> and disable them when done.
|
||||
|
||||
To enable specific RIP debug categories:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit routing control-plane-protocol ripv2 name default rip debug</b>
|
||||
admin@example:/config/routing/…/rip/debug/> <b>set events true</b>
|
||||
admin@example:/config/routing/…/rip/debug/> <b>set packet true</b>
|
||||
admin@example:/config/routing/…/rip/debug/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Available debug categories include:
|
||||
|
||||
- `events`: RIP events (sending/receiving packets, timers, interface changes)
|
||||
- `packet`: Detailed packet debugging (packet dumps with origin and port)
|
||||
- `kernel`: Kernel routing table updates (route add/delete, interface updates)
|
||||
|
||||
All debug options are disabled by default. Refer to the `infix-routing`
|
||||
YANG model for the complete list of available debug options.
|
||||
|
||||
To view current debug settings:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show running-config routing control-plane-protocol</b>
|
||||
</code></pre>
|
||||
|
||||
To disable all debug logging, simply delete the debug settings or set
|
||||
all options back to `false`:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>delete routing control-plane-protocol ripv2 name default rip debug</b>
|
||||
admin@example:/config/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
## View routing table
|
||||
|
||||
The routing table can be inspected from the operational datastore, XPath
|
||||
`/routing/ribs`, using sysrepocfg, NETCONF/RESTCONF, or using the CLI.
|
||||
|
||||
|
||||
### IPv4 routing table
|
||||
|
||||
This CLI example shows the IPv4 routing table with a few connected
|
||||
routes and some routes learned from OSPF. See the next section for
|
||||
an explanation of route preferences (PREF).
|
||||
|
||||
The `>` at the start of a line marks a selected route (in the IETF YANG
|
||||
model referred to as *active*), if there are more than one route with
|
||||
the same destination the `*` marks the next-hop used and installed in
|
||||
the kernel FIB (the YANG model refers to this as *installed*).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ip route</b>
|
||||
<span class="header"> DESTINATION PREF NEXT-HOP PROTO UPTIME</span>
|
||||
>* 0.0.0.0/0 110/2 10.0.23.1 ospfv2 4h2m43s
|
||||
>* 10.0.0.1/32 110/4000 10.0.13.1 ospfv2 4h2m43s
|
||||
10.0.0.3/32 110/0 lo ospfv2 4h2m57s
|
||||
>* 10.0.0.3/32 0/0 lo direct 4h2m58s
|
||||
10.0.13.0/30 110/2000 e5 ospfv2 4h2m57s
|
||||
>* 10.0.13.0/30 0/0 e5 direct 4h2m58s
|
||||
10.0.23.0/30 110/1 e6 ospfv2 4h2m57s
|
||||
>* 10.0.23.0/30 0/0 e6 direct 4h2m58s
|
||||
192.168.3.0/24 110/1 e2 ospfv2 4h2m57s
|
||||
>* 192.168.3.0/24 0/0 e2 direct 4h2m58s
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### IPv6 routing table
|
||||
|
||||
This CLI example show the IPv6 routing table.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ipv6 route</b>
|
||||
<span class="header"> DESTINATION PREF NEXT-HOP PROTO UPTIME</span>
|
||||
>* ::/0 1/0 2001:db8:3c4d:50::1 static 0h1m20s
|
||||
>* 2001:db8:3c4d:50::/64 0/0 e6 direct 0h1m20s
|
||||
>* 2001:db8:3c4d:200::1/128 0/0 lo direct 0h1m20s
|
||||
* fe80::/64 0/0 e7 direct 0h1m20s
|
||||
* fe80::/64 0/0 e6 direct 0h1m20s
|
||||
* fe80::/64 0/0 e5 direct 0h1m20s
|
||||
* fe80::/64 0/0 e4 direct 0h1m20s
|
||||
* fe80::/64 0/0 e3 direct 0h1m20s
|
||||
* fe80::/64 0/0 e2 direct 0h1m20s
|
||||
>* fe80::/64 0/0 e1 direct 0h1m20s
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
### Route Preference
|
||||
|
||||
The operating system leverages FRRouting ([Frr][0]) as routing engine
|
||||
for both static and dynamic routing. Even routes injected from a DHCP
|
||||
client, and IPv4 link-local (IPv4) routes, are injected into Frr to let
|
||||
it weigh all routes before installing them into the kernel routing table
|
||||
(sometimes referred to as FIB).
|
||||
|
||||
Routes have different weights made up from a *distance* and a *metric*.
|
||||
The kernel routing table only talks about *metric*, which unfortunately
|
||||
is **not the same** -- this is one of the reasons why the term *route
|
||||
preference* is used instead. It is recommended to use the CLI, or any
|
||||
of the other previously mentioned YANG based front-ends, to inspect the
|
||||
routing table.
|
||||
|
||||
Default distances used (lower numeric value wins):
|
||||
|
||||
| **Distance** | **Protocol** |
|
||||
|--------------|-----------------------------------------|
|
||||
| 0 | Kernel routes, i.e., connected routes |
|
||||
| 1 | Static routes |
|
||||
| 5 | DHCP routes |
|
||||
| 110 | OSPF |
|
||||
| 254 | IPv4LL (ZeroConf) device routes |
|
||||
| 255 | Route will not be used or redistributed |
|
||||
|
||||
Hence, a route learned from OSPF may be overridden by a static route set
|
||||
locally. By default, even a route to the same destination, but with a
|
||||
different next-hop, learned from a DHCP server wins over an OSPF route.
|
||||
|
||||
The distance used for static routes and DHCP routes can be changed by
|
||||
setting a different *routing preference* value.
|
||||
|
||||
> [!NOTE]
|
||||
> The kernel metric is an unsigned 32-bit value, which is read by Frr as
|
||||
> (upper) 8 bits distance and 24 bits metric. But it does not write it
|
||||
> back to the kernel FIB this way, only selected routes are candidates
|
||||
> to be installed in the FIB by Frr.
|
||||
|
||||
|
||||
### Source protocol
|
||||
|
||||
The source protocol describes the origin of the route.
|
||||
|
||||
| **Protocol** | **Description** |
|
||||
|:-------------|:----------------------------------------------------|
|
||||
| kernel | Added when setting a subnet address on an interface |
|
||||
| static | User created, learned from DHCP, or IPv4LL |
|
||||
| ospfv2 | Routes learned from OSPFv2 |
|
||||
|
||||
The YANG model *ietf-routing* support multiple ribs but only two are
|
||||
currently supported, namely `ipv4` and `ipv6`.
|
||||
|
||||
[0]: https://frrouting.org/
|
||||
@@ -350,5 +350,5 @@ the created configuration.
|
||||
|
||||
[1]: scripting-sysrepocfg.md#backup-configuration
|
||||
[2]: scripting-sysrepocfg.md#restore-configuration
|
||||
[8]: networking.md#bridging
|
||||
[9]: networking.md#vlan-filtering-bridge
|
||||
[8]: bridging.md
|
||||
[9]: bridging.md#vlan-filtering-bridge
|
||||
|
||||
+78
-93
@@ -21,20 +21,19 @@ an example.
|
||||
|
||||
For a list of available log facilities, see the table in a later section.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit syslog actions log-file file:/media/log/mylog
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> set facility-list
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit syslog actions log-file file:/media/log/mylog</b>
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> <b>set facility-list</b>
|
||||
all audit auth authpriv console cron cron2 daemon ftp kern
|
||||
local0 local1 local2 local3 local4 local5 local6 local7 lpr mail
|
||||
news ntp syslog user uucp
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> set facility-list all severity
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> <b>set facility-list all severity</b>
|
||||
alert all critical debug emergency error info none notice warning
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> set facility-list all severity critical
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> set facility-list mail severity warning
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> leave
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> <b>set facility-list all severity critical</b>
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> <b>set facility-list mail severity warning</b>
|
||||
admin@example:/config/syslog/…/file:/media/log/mylog/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The `log-file` syntax requires the leading prefix `file:`. If the
|
||||
@@ -50,11 +49,10 @@ disk with outdated logs. A rotated file is saved in stages and older
|
||||
ones are also compressed (using `gzip`). Use the `show log` command in
|
||||
admin-exec context to start the log file viewer:
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/> do show log
|
||||
<pre class="cli"><code>admin@example:/config/syslog/> <b>do show log</b>
|
||||
log log.0 log.1.gz log.2.gz log.3.gz log.4.gz log.5.gz
|
||||
admin@example:/config/syslog/> do show log log.1.gz
|
||||
```
|
||||
admin@example:/config/syslog/> <b>do show log log.1.gz</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> Use the Tab key on your keyboard list available log files. The `do`
|
||||
@@ -68,51 +66,48 @@ Log file rotation can be configured both globally and per log file.
|
||||
Here we show the global settings, the set up is the same for per log
|
||||
file, which if unset inherit the global settings:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit syslog file-rotation
|
||||
admin@example:/config/syslog/file-rotation/> show
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit syslog file-rotation</b>
|
||||
admin@example:/config/syslog/file-rotation/> <b>show</b>
|
||||
admin@example:/config/syslog/file-rotation/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The defaults are not shown. We can inspect them by asking the YANG
|
||||
model for the help texts:
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/file-rotation/> help
|
||||
<pre class="cli"><code>admin@example:/config/syslog/file-rotation/> <b>help</b>
|
||||
max-file-size number-of-files
|
||||
admin@example:/config/syslog/file-rotation/> help max-file-size
|
||||
NAME
|
||||
admin@example:/config/syslog/file-rotation/> <b>help max-file-size</b>
|
||||
<b>NAME</b>
|
||||
max-file-size kilobytes
|
||||
|
||||
DESCRIPTION
|
||||
<b>DESCRIPTION</b>
|
||||
Maximum log file size (kiB), before rotation.
|
||||
|
||||
DEFAULT
|
||||
<b>DEFAULT</b>
|
||||
1024
|
||||
admin@example:/config/syslog/file-rotation/> help number-of-files
|
||||
NAME
|
||||
admin@example:/config/syslog/file-rotation/> <b>help number-of-files</b>
|
||||
<b>NAME</b>
|
||||
number-of-files [0..4294967295]
|
||||
|
||||
DESCRIPTION
|
||||
<b>DESCRIPTION</b>
|
||||
Maximum number of log files retained.
|
||||
|
||||
DEFAULT
|
||||
<b>DEFAULT</b>
|
||||
10
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
To change the defaults to something smaller, 512 kiB and 20 (remember
|
||||
everything after .0 is compressed, and text compresses well):
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/file-rotation/> set max-file-size 512
|
||||
admin@example:/config/syslog/file-rotation/> set number-of-files 20
|
||||
admin@example:/config/syslog/file-rotation/> show
|
||||
<pre class="cli"><code>admin@example:/config/syslog/file-rotation/> <b>set max-file-size 512</b>
|
||||
admin@example:/config/syslog/file-rotation/> <b>set number-of-files 20</b>
|
||||
admin@example:/config/syslog/file-rotation/> <b>show</b>
|
||||
number-of-files 20;
|
||||
max-file-size 512;
|
||||
admin@example:/config/syslog/file-rotation/> leave
|
||||
admin@example:/config/syslog/file-rotation/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
## Log Format
|
||||
|
||||
@@ -135,14 +130,13 @@ perform time stamping at the time of arrival.
|
||||
|
||||
Configuring the log format is the same for log files and remotes:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog actions log-file file:foobar
|
||||
admin@example:/config/syslog/…/file:foobar/> set log-format
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog actions log-file file:foobar</b>
|
||||
admin@example:/config/syslog/…/file:foobar/> <b>set log-format</b>
|
||||
bsd rfc3164 rfc5424
|
||||
admin@example:/config/syslog/…/file:foobar/> set log-format rfc5424
|
||||
admin@example:/config/syslog/…/file:foobar/> leave
|
||||
admin@example:/config/syslog/…/file:foobar/> <b>set log-format rfc5424</b>
|
||||
admin@example:/config/syslog/…/file:foobar/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
## Log to Remote Server
|
||||
|
||||
@@ -158,19 +152,18 @@ remote syslog servers do not support receiving time stamped log messages
|
||||
-- this is of course entirely dependent on how the remote server is set
|
||||
up, as well as local policy.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog</b>
|
||||
actions file-rotation server
|
||||
admin@example:/config/> edit syslog actions destination moon
|
||||
admin@example:/config/syslog/…/moon/> set
|
||||
admin@example:/config/> <b>edit syslog actions destination moon</b>
|
||||
admin@example:/config/syslog/…/moon/> <b>set</b>
|
||||
facility-list log-format udp
|
||||
admin@example:/config/syslog/…/moon/> set udp
|
||||
admin@example:/config/syslog/…/moon/> <b>set udp</b>
|
||||
address port
|
||||
admin@example:/config/syslog/…/moon/> set udp address 192.168.0.12
|
||||
admin@example:/config/syslog/…/moon/> set facility-list container severity all
|
||||
admin@example:/config/syslog/…/moon/> leave
|
||||
admin@example:/config/syslog/…/moon/> <b>set udp address 192.168.0.12</b>
|
||||
admin@example:/config/syslog/…/moon/> <b>set facility-list container severity all</b>
|
||||
admin@example:/config/syslog/…/moon/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> The alternatives shown below each prompt in the example above can be
|
||||
@@ -181,14 +174,13 @@ admin@example:/>
|
||||
The syslog server can act as a log sink for other devices on a LAN. For
|
||||
this to work you need a static IP address, here we use 10.0.0.1/24.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit syslog server
|
||||
admin@example:/config/syslog/server/> set enabled true
|
||||
admin@example:/config/syslog/server/> set listen udp 514 address 10.0.0.1
|
||||
admin@example:/config/syslog/server/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit syslog server</b>
|
||||
admin@example:/config/syslog/server/> <b>set enabled true</b>
|
||||
admin@example:/config/syslog/server/> <b>set listen udp 514 address 10.0.0.1</b>
|
||||
admin@example:/config/syslog/server/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
See the above [Log to File](#log-to-file) section on how to set up
|
||||
filtering of received logs to local files. Advanced filtering based
|
||||
@@ -208,13 +200,12 @@ Messages can be filtered using regular expressions (POSIX extended regex)
|
||||
on the message content. This is useful when you want to log only messages
|
||||
containing specific keywords or patterns:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog actions log-file file:errors
|
||||
admin@example:/config/syslog/…/file:errors/> set pattern-match "ERROR|CRITICAL|FATAL"
|
||||
admin@example:/config/syslog/…/file:errors/> set facility-list all severity info
|
||||
admin@example:/config/syslog/…/file:errors/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog actions log-file file:errors</b>
|
||||
admin@example:/config/syslog/…/file:errors/> <b>set pattern-match "ERROR|CRITICAL|FATAL"</b>
|
||||
admin@example:/config/syslog/…/file:errors/> <b>set facility-list all severity info</b>
|
||||
admin@example:/config/syslog/…/file:errors/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
This will log all messages containing ERROR, CRITICAL, or FATAL.
|
||||
|
||||
@@ -224,22 +215,20 @@ By default, severity filtering uses "equals-or-higher" comparison,
|
||||
meaning a severity of `error` will match error, critical, alert, and
|
||||
emergency messages. You can change this behavior:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog actions log-file file:daemon-errors
|
||||
admin@example:/config/syslog/…/file:daemon-errors/> set facility-list daemon
|
||||
admin@example:/config/syslog/…/daemon/> set severity error
|
||||
admin@example:/config/syslog/…/daemon/> set advanced-compare compare equals
|
||||
admin@example:/config/syslog/…/daemon/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog actions log-file file:daemon-errors</b>
|
||||
admin@example:/config/syslog/…/file:daemon-errors/> <b>set facility-list daemon</b>
|
||||
admin@example:/config/syslog/…/daemon/> <b>set severity error</b>
|
||||
admin@example:/config/syslog/…/daemon/> <b>set advanced-compare compare equals</b>
|
||||
admin@example:/config/syslog/…/daemon/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
This will log only `error` severity messages, not higher severities.
|
||||
|
||||
You can also block specific severities:
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/…/daemon/> set advanced-compare action block
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/syslog/…/daemon/> <b>set advanced-compare action block</b>
|
||||
</code></pre>
|
||||
|
||||
This will exclude `error` messages from the log.
|
||||
|
||||
@@ -248,13 +237,12 @@ This will exclude `error` messages from the log.
|
||||
When acting as a log server, you can filter messages by hostname. This
|
||||
is useful for directing logs from different devices to separate files:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog actions log-file file:router1
|
||||
admin@example:/config/syslog/…/file:router1/> set hostname-filter router1
|
||||
admin@example:/config/syslog/…/file:router1/> set facility-list all severity info
|
||||
admin@example:/config/syslog/…/file:router1/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog actions log-file file:router1</b>
|
||||
admin@example:/config/syslog/…/file:router1/> <b>set hostname-filter router1</b>
|
||||
admin@example:/config/syslog/…/file:router1/> <b>set facility-list all severity info</b>
|
||||
admin@example:/config/syslog/…/file:router1/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Multiple hostnames can be added to the filter list.
|
||||
|
||||
@@ -263,15 +251,14 @@ Multiple hostnames can be added to the filter list.
|
||||
For more advanced filtering, you can match on specific message properties
|
||||
using various comparison operators:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit syslog actions log-file file:myapp
|
||||
admin@example:/config/syslog/…/file:myapp/> edit property-filter
|
||||
admin@example:/config/syslog/…/property-filter/> set property programname
|
||||
admin@example:/config/syslog/…/property-filter/> set operator isequal
|
||||
admin@example:/config/syslog/…/property-filter/> set value myapp
|
||||
admin@example:/config/syslog/…/property-filter/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit syslog actions log-file file:myapp</b>
|
||||
admin@example:/config/syslog/…/file:myapp/> <b>edit property-filter</b>
|
||||
admin@example:/config/syslog/…/property-filter/> <b>set property programname</b>
|
||||
admin@example:/config/syslog/…/property-filter/> <b>set operator isequal</b>
|
||||
admin@example:/config/syslog/…/property-filter/> <b>set value myapp</b>
|
||||
admin@example:/config/syslog/…/property-filter/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Available properties:
|
||||
- `msg`: Message body
|
||||
@@ -290,15 +277,13 @@ Available operators:
|
||||
|
||||
The comparison can be made case-insensitive:
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/…/property-filter/> set case-insensitive true
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/syslog/…/property-filter/> <b>set case-insensitive true</b>
|
||||
</code></pre>
|
||||
|
||||
Or negated to exclude matching messages:
|
||||
|
||||
```
|
||||
admin@example:/config/syslog/…/property-filter/> set negate true
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/syslog/…/property-filter/> <b>set negate true</b>
|
||||
</code></pre>
|
||||
|
||||
### Facilities
|
||||
|
||||
|
||||
+110
-116
@@ -22,13 +22,12 @@ hostname is included below.
|
||||
User management, including passwords, SSH keys, remote authentication is
|
||||
available in the system authentication configuration context.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system authentication user admin
|
||||
admin@example:/config/system/authentication/user/admin/> change password
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system authentication user admin</b>
|
||||
admin@example:/config/system/…/user/admin/> <b>change password</b>
|
||||
New password:
|
||||
Retype password:
|
||||
admin@example:/config/system/authentication/user/admin/> leave
|
||||
```
|
||||
admin@example:/config/system/…/user/admin/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The `change password` command starts an interactive dialogue that asks
|
||||
for the new password, with a confirmation, and then salts and encrypts
|
||||
@@ -56,16 +55,15 @@ are supported.
|
||||
With SSH keys in place it is possible to disable password login, just
|
||||
remember to verify SSH login and network connectivity before doing so.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system authentication user admin
|
||||
admin@example:/config/system/authentication/user/admin/> edit authorized-key admin@example
|
||||
admin@example:/config/system/authentication/user/admin/authorized-key/example@host/> set algorithm ssh-rsa
|
||||
admin@example:/config/system/authentication/user/admin/authorized-key/example@host/> set key-data AAAAB3NzaC1yc2EAAAADAQABAAABgQC8iBL42yeMBioFay7lty1C4ZDTHcHyo739gc91rTTH8SKvAE4g8Rr97KOz/8PFtOObBrE9G21K7d6UBuPqmd0RUF2CkXXN/eN2PBSHJ50YprRFt/z/304bsBYkDdflKlPDjuSmZ/+OMp4pTsq0R0eNFlX9wcwxEzooIb7VPEdvWE7AYoBRUdf41u3KBHuvjGd1M6QYJtbFLQMMTiVe5IUfyVSZ1RCxEyAB9fR9CBhtVheTVsY3iG0fZc9eCEo89ErDgtGUTJK4Hxt5yCNwI88YaVmkE85cNtw8YwubWQL3/tGZHfbbQ0fynfB4kWNloyRHFr7E1kDxuX5+pbv26EqRdcOVGucNn7hnGU6C1+ejLWdBD7vgsoilFrEaBWF41elJEPKDzpszEijQ9gTrrWeYOQ+x++lvmOdssDu4KvGmj2K/MQTL2jJYrMJ7GDzsUu3XikChRL7zNfS2jYYQLzovboUCgqfPUsVba9hqeX3U67GsJo+hy5MG9RSry4+ucHs=
|
||||
admin@example:/config/system/authentication/user/admin/authorized-key/example@host/> show
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system authentication user admin</b>
|
||||
admin@example:/config/system/…/user/admin/> <b>edit authorized-key admin@example</b>
|
||||
admin@example:/config/system/…/example@host/> <b>set algorithm ssh-rsa</b>
|
||||
admin@example:/config/system/…/example@host/> <b>set key-data AAAAB3NzaC1yc2EAAAADAQABAAABgQC8iBL42yeMBioFay7lty1C4ZDTHcHyo739gc91rTTH8SKvAE4g8Rr97KOz/8PFtOObBrE9G21K7d6UBuPqmd0RUF2CkXXN/eN2PBSHJ50YprRFt/z/304bsBYkDdflKlPDjuSmZ/+OMp4pTsq0R0eNFlX9wcwxEzooIb7VPEdvWE7AYoBRUdf41u3KBHuvjGd1M6QYJtbFLQMMTiVe5IUfyVSZ1RCxEyAB9fR9CBhtVheTVsY3iG0fZc9eCEo89ErDgtGUTJK4Hxt5yCNwI88YaVmkE85cNtw8YwubWQL3/tGZHfbbQ0fynfB4kWNloyRHFr7E1kDxuX5+pbv26EqRdcOVGucNn7hnGU6C1+ejLWdBD7vgsoilFrEaBWF41elJEPKDzpszEijQ9gTrrWeYOQ+x++lvmOdssDu4KvGmj2K/MQTL2jJYrMJ7GDzsUu3XikChRL7zNfS2jYYQLzovboUCgqfPUsVba9hqeX3U67GsJo+hy5MG9RSry4+ucHs=</b>
|
||||
admin@example:/config/system/…/example@host/> <b>show</b>
|
||||
algorithm ssh-rsa;
|
||||
key-data AAAAB3NzaC1yc2EAAAADAQABAAABgQC8iBL42yeMBioFay7lty1C4ZDTHcHyo739gc91rTTH8SKvAE4g8Rr97KOz/8PFtOObBrE9G21K7d6UBuPqmd0RUF2CkXXN/eN2PBSHJ50YprRFt/z/304bsBYkDdflKlPDjuSmZ/+OMp4pTsq0R0eNFlX9wcwxEzooIb7VPEdvWE7AYoBRUdf41u3KBHuvjGd1M6QYJtbFLQMMTiVe5IUfyVSZ1RCxEyAB9fR9CBhtVheTVsY3iG0fZc9eCEo89ErDgtGUTJK4Hxt5yCNwI88YaVmkE85cNtw8YwubWQL3/tGZHfbbQ0fynfB4kWNloyRHFr7E1kDxuX5+pbv26EqRdcOVGucNn7hnGU6C1+ejLWdBD7vgsoilFrEaBWF41elJEPKDzpszEijQ9gTrrWeYOQ+x++lvmOdssDu4KvGmj2K/MQTL2jJYrMJ7GDzsUu3XikChRL7zNfS2jYYQLzovboUCgqfPUsVba9hqeX3U67GsJo+hy5MG9RSry4+ucHs=;
|
||||
admin@example:/config/system/authentication/user/admin/authorized-key/example@host/> leave
|
||||
```
|
||||
admin@example:/config/system/…/example@host/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> The `ssh-keygen` program already base64 encodes the public key data,
|
||||
@@ -112,8 +110,7 @@ way to regain full access is to perform a *factory reset*.
|
||||
For an overview of users and groups on the system, there is an admin-exec
|
||||
command:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm</b>
|
||||
enabled : yes
|
||||
default read access : permit
|
||||
default write access : permit
|
||||
@@ -131,16 +128,16 @@ denied notifications : 0
|
||||
└──────────┴─────────┴─────────┴─────────┘
|
||||
✓ Full ⚠ Restricted ✗ Denied
|
||||
|
||||
USER SHELL LOGIN
|
||||
<span class="header">USER SHELL LOGIN </span>
|
||||
admin bash password+key
|
||||
jacky clish password
|
||||
monitor false key
|
||||
|
||||
GROUP USERS
|
||||
<span class="header">GROUP USERS </span>
|
||||
admin admin
|
||||
operator jacky
|
||||
guest monitor
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The permissions matrix shows effective access for each NACM group:
|
||||
|
||||
@@ -151,46 +148,44 @@ The permissions matrix shows effective access for each NACM group:
|
||||
|
||||
For detailed information about a specific group's rules:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm group operator
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm group operator</b>
|
||||
members : jacky
|
||||
read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
applicable rules : 4
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
permit-system-rpcs
|
||||
<span class="title">permit-system-rpcs</span>
|
||||
action : permit
|
||||
operations : exec
|
||||
target : ietf-system (rpc: *)
|
||||
comment : Operators can reboot, shutdown, and set system time.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-password-access (via '*')
|
||||
<span class="title">deny-password-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : /ietf-system:system/authentication/user/password
|
||||
comment : No user except admins can access password hashes.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-keystore-access (via '*')
|
||||
<span class="title">deny-keystore-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-keystore
|
||||
comment : No user except admins can access cryptographic keys.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-truststore-access (via '*')
|
||||
<span class="title">deny-truststore-access (via '*')</span>
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-truststore
|
||||
comment : No user except admins can access trust store.
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
For user details:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm user jacky
|
||||
<pre class="cli"><code>admin@example:/> <b>show nacm user jacky</b>
|
||||
shell : clish
|
||||
login : password
|
||||
nacm group : operator
|
||||
@@ -198,20 +193,26 @@ read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
|
||||
For detailed rules, use: show nacm group <name>
|
||||
```
|
||||
For detailed rules, use: show nacm group <name>
|
||||
</code></pre>
|
||||
|
||||
### Adding a User
|
||||
|
||||
Creating a new user starts with defining the user account in the system:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system authentication user jacky
|
||||
admin@example:/config/system/authentication/user/jacky/> change password
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system authentication user jacky</b>
|
||||
admin@example:/config/system/…/user/jacky/> <b>change password</b>
|
||||
New password:
|
||||
Retype password:
|
||||
admin@example:/config/system/authentication/user/jacky/> leave
|
||||
```
|
||||
admin@example:/config/system/…/user/jacky/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> It is also possible to use <kbd>set password ...</kbd> if you have the
|
||||
> fully crypted and salted string ready. This can be created offline
|
||||
> with the [`mkpasswd(1)`][5] tool, or the built-in CLI version <kbd>do
|
||||
> password encrypt [OPTS]</kbd>. The `do` prefix is handy for reaching
|
||||
> all top-level commands when in configure context.
|
||||
|
||||
An authorized SSH key can be added the same way as described in the
|
||||
previous sections.
|
||||
@@ -219,11 +220,10 @@ previous sections.
|
||||
By default, shell access is disabled (`shell false`). To allow CLI/SSH
|
||||
access, set the shell:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system authentication user jacky
|
||||
admin@example:/config/system/authentication/user/jacky/> set shell clish
|
||||
admin@example:/config/system/authentication/user/jacky/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system authentication user jacky</b>
|
||||
admin@example:/config/system/…/user/jacky/> <b>set shell clish</b>
|
||||
admin@example:/config/system/…/user/jacky/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Available shells:
|
||||
|
||||
@@ -250,27 +250,24 @@ corresponding NACM group:
|
||||
|
||||
**Operator user:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group operator
|
||||
admin@example:/config/nacm/group/operator/> set user-name jacky
|
||||
admin@example:/config/nacm/group/operator/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit nacm group operator</b>
|
||||
admin@example:/config/nacm/group/operator/> <b>set user-name jacky</b>
|
||||
admin@example:/config/nacm/group/operator/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Adding another admin:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group admin
|
||||
admin@example:/config/nacm/group/admin/> set user-name alice
|
||||
admin@example:/config/nacm/group/admin/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit nacm group admin</b>
|
||||
admin@example:/config/nacm/group/admin/> <b>set user-name alice</b>
|
||||
admin@example:/config/nacm/group/admin/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Guest user:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group guest
|
||||
admin@example:/config/nacm/group/guest/> set user-name monitor
|
||||
admin@example:/config/nacm/group/guest/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit nacm group guest</b>
|
||||
admin@example:/config/nacm/group/guest/> <b>set user-name monitor</b>
|
||||
admin@example:/config/nacm/group/guest/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!TIP]
|
||||
> For technical details about NACM rule evaluation, module-name vs path
|
||||
@@ -363,12 +360,11 @@ cryptographic key material through global NACM rules.
|
||||
Notice how the hostname in the prompt does not change until the change
|
||||
is committed by issuing the `leave` command.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system
|
||||
admin@example:/config/system/> set hostname myrouter
|
||||
admin@example:/config/system/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system</b>
|
||||
admin@example:/config/system/> <b>set hostname myrouter</b>
|
||||
admin@example:/config/system/> <b>leave</b>
|
||||
admin@myrouter:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The hostname is advertised over mDNS-SD in the `.local` domain. If
|
||||
another device already has claimed the `myrouter.local` CNAME, in our
|
||||
@@ -379,12 +375,11 @@ available devices on your LAN.
|
||||
In some cases you may want to set the device's *domain name* as well.
|
||||
This is handled the same way:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system
|
||||
admin@example:/config/system/> set hostname foo.example.com
|
||||
admin@example:/config/system/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system</b>
|
||||
admin@example:/config/system/> <b>set hostname foo.example.com</b>
|
||||
admin@example:/config/system/> <b>leave</b>
|
||||
admin@foo:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Both host and domain name are stored in the system files `/etc/hosts`
|
||||
and `/etc/hostname`. The latter is exclusively for the host name. The
|
||||
@@ -406,12 +401,11 @@ built-in [`text-editor` command](cli/text-editor.md).
|
||||
> See the next section for how to change the editor used to something
|
||||
> you may be more familiar with.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit system
|
||||
admin@example:/config/system/> text-editor motd-banner
|
||||
admin@example:/config/system/> leave
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit system</b>
|
||||
admin@example:/config/system/> <b>text-editor motd-banner</b>
|
||||
admin@example:/config/system/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Log out and log back in again to inspect the changes.
|
||||
|
||||
@@ -427,13 +421,12 @@ as the `text-editor` command:
|
||||
|
||||
To change the editor to GNU Nano:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit system
|
||||
admin@example:/config/system/> set text-editor nano
|
||||
admin@example:/config/system/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit system</b>
|
||||
admin@example:/config/system/> <b>set text-editor nano</b>
|
||||
admin@example:/config/system/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Configuration changes only take effect after issuing the `leave`
|
||||
@@ -447,18 +440,17 @@ The system supports both static and dynamic (DHCP) DNS setup. The
|
||||
locally configured (static) server is preferred over any acquired
|
||||
from a DHCP client.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit system dns-resolver
|
||||
admin@example:/config/system/dns-resolver/> set server google udp-and-tcp address 8.8.8.8
|
||||
admin@example:/config/system/dns-resolver/> show
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit system dns-resolver</b>
|
||||
admin@example:/config/system/dns-resolver/> <b>set server google udp-and-tcp address 8.8.8.8</b>
|
||||
admin@example:/config/system/dns-resolver/> <b>show</b>
|
||||
server google {
|
||||
udp-and-tcp {
|
||||
address 8.8.8.8;
|
||||
}
|
||||
}
|
||||
admin@example:/config/system/dns-resolver/> leave
|
||||
```
|
||||
admin@example:/config/system/dns-resolver/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
It is also possible to configure resolver options like timeout and
|
||||
retry attempts. See the YANG model for details, or use the built-in
|
||||
@@ -475,16 +467,15 @@ help system in the CLI.
|
||||
Below is an example configuration for enabling NTP with a specific
|
||||
server and the `iburst` option for faster initial synchronization.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit system ntp
|
||||
admin@example:/config/system/ntp/> set enabled
|
||||
admin@example:/config/system/ntp/> set server ntp-pool
|
||||
admin@example:/config/system/ntp/> set server ntp-pool udp address pool.ntp.org
|
||||
admin@example:/config/system/ntp/> set server ntp-pool iburst
|
||||
admin@example:/config/system/ntp/> set server ntp-pool prefer
|
||||
admin@example:/config/system/ntp/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit system ntp</b>
|
||||
admin@example:/config/system/ntp/> <b>set enabled</b>
|
||||
admin@example:/config/system/ntp/> <b>set server ntp-pool</b>
|
||||
admin@example:/config/system/ntp/> <b>set server ntp-pool udp address pool.ntp.org</b>
|
||||
admin@example:/config/system/ntp/> <b>set server ntp-pool iburst</b>
|
||||
admin@example:/config/system/ntp/> <b>set server ntp-pool prefer</b>
|
||||
admin@example:/config/system/ntp/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
This configuration enables the NTP client and sets the NTP server to
|
||||
`pool.ntp.org` with the `iburst` and `prefer` options. The `iburst`
|
||||
@@ -504,36 +495,38 @@ The status for NTP sources is availble in YANG and accessable with
|
||||
CLI/NETCONF/RESTCONF.
|
||||
|
||||
To view the sources being used by the NTP client, run:
|
||||
```
|
||||
admin@target:/> show ntp
|
||||
ADDRESS MODE STATE STRATUM POLL-INTERVAL
|
||||
192.168.1.1 server candidate 1 6
|
||||
192.168.2.1 server candidate 1 6
|
||||
192.168.3.1 server selected 1 6
|
||||
```
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show ntp</b>
|
||||
Mode : Client
|
||||
Stratum : 3
|
||||
Ref time (UTC) : Sat Jan 24 23:41:42 2026
|
||||
|
||||
<span class="header">ADDRESS MODE STATE STRATUM POLL</span>
|
||||
147.78.228.41 server outlier 2 64s
|
||||
192.168.0.1 server unusable 0 128s
|
||||
176.126.86.247 server selected 2 64s
|
||||
</code></pre>
|
||||
|
||||
### Show NTP Status
|
||||
|
||||
To check the status of NTP synchronization (only availble in CLI), use
|
||||
the following command:
|
||||
|
||||
```
|
||||
admin@example:/> show ntp tracking
|
||||
Reference ID : C0248F86 (192.36.143.134)
|
||||
Stratum : 2
|
||||
Ref time (UTC) : Mon Oct 21 10:06:45 2024
|
||||
System time : 0.000000001 seconds slow of NTP time
|
||||
Last offset : -3845.151367188 seconds
|
||||
RMS offset : 3845.151367188 seconds
|
||||
Frequency : 4.599 ppm slow
|
||||
Residual freq : +1293.526 ppm
|
||||
Skew : 12.403 ppm
|
||||
Root delay : 1.024467230 seconds
|
||||
Root dispersion : 0.273462683 seconds
|
||||
Update interval : 0.0 seconds
|
||||
Leap status : Normal
|
||||
admin@example:/>
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>show ntp tracking</b>
|
||||
Reference ID : 176.126.86.247
|
||||
Stratum : 3
|
||||
Ref time (UTC) : Sat Jan 24 23:41:42 2026
|
||||
System time : 0.000000 seconds slow of NTP time
|
||||
Last offset : -454779.375000000 seconds
|
||||
RMS offset : 454779.375000000 seconds
|
||||
Frequency : 0.000 ppm slow
|
||||
Residual freq : -26.383 ppm
|
||||
Skew : 1000000.000 ppm
|
||||
Root delay : 0.007395 seconds
|
||||
Root dispersion : 39.181149 seconds
|
||||
Update interval : 0.0 seconds
|
||||
Leap status : Normal
|
||||
</code></pre>
|
||||
|
||||
This output provides detailed information about the NTP status, including
|
||||
reference ID, stratum, time offsets, frequency, and root delay.
|
||||
@@ -546,3 +539,4 @@ reference ID, stratum, time offsets, frequency, and root delay.
|
||||
[2]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-system%402024-02-29.yang
|
||||
[3]: https://www.rfc-editor.org/rfc/rfc8341
|
||||
[4]: https://chrony-project.org/doc/4.6.1/chronyc.html
|
||||
[5]: https://linux.die.net/man/1/mkpasswd
|
||||
|
||||
+61
-70
@@ -28,14 +28,13 @@ IPv6 tunnels in two modes:
|
||||
|
||||
A basic GRE tunnel for routing between two sites:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface gre0
|
||||
admin@example:/config/interface/gre0/> set gre local 192.168.3.1 remote 192.168.3.2
|
||||
admin@example:/config/interface/gre0/> set ipv4 address 10.255.0.1 prefix-length 30
|
||||
admin@example:/config/interface/gre0/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface gre0</b>
|
||||
admin@example:/config/interface/gre0/> <b>set gre local 192.168.3.1 remote 192.168.3.2</b>
|
||||
admin@example:/config/interface/gre0/> <b>set ipv4 address 10.255.0.1 prefix-length 30</b>
|
||||
admin@example:/config/interface/gre0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
This creates a Layer 3 tunnel between 192.168.3.1 and 192.168.3.2 using
|
||||
the outer IP addresses, with the tunnel itself using 10.255.0.0/30 for
|
||||
@@ -45,17 +44,16 @@ the inner IP addressing.
|
||||
|
||||
GRETAP tunnels operate at Layer 2, allowing bridging across the tunnel:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface gretap0
|
||||
admin@example:/config/interface/gretap0/> set type gretap
|
||||
admin@example:/config/interface/gretap0/> set gre local 192.168.3.1 remote 192.168.3.2
|
||||
admin@example:/config/interface/gretap0/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface gretap0</b>
|
||||
admin@example:/config/interface/gretap0/> <b>set type gretap</b>
|
||||
admin@example:/config/interface/gretap0/> <b>set gre local 192.168.3.1 remote 192.168.3.2</b>
|
||||
admin@example:/config/interface/gretap0/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
GRETAP interfaces can be added to a bridge, bridging local and remote Ethernet
|
||||
segments. See the [Bridge Configuration](networking.md#bridging)
|
||||
segments. See the [Bridge Configuration](bridging.md)
|
||||
for more on bridges.
|
||||
|
||||
### OSPF over GRE
|
||||
@@ -69,37 +67,35 @@ exchange routes.
|
||||
|
||||
**Site A configuration:**
|
||||
|
||||
```
|
||||
admin@siteA:/> configure
|
||||
admin@siteA:/config/> edit interface gre0
|
||||
admin@siteA:/config/interface/gre0/> set gre local 203.0.113.1 remote 203.0.113.2
|
||||
admin@siteA:/config/interface/gre0/> set ipv4 address 10.255.0.1 prefix-length 30
|
||||
admin@siteA:/config/interface/gre0/> set ipv4 forwarding
|
||||
admin@siteA:/config/interface/gre0/> end
|
||||
admin@siteA:/config/> edit routing control-plane-protocol ospfv2 name default ospf
|
||||
admin@siteA:/config/routing/…/ospf/> set area 0.0.0.0 interface gre0
|
||||
admin@siteA:/config/routing/…/ospf/> leave
|
||||
<pre class="cli"><code>admin@siteA:/> <b>configure</b>
|
||||
admin@siteA:/config/> <b>edit interface gre0</b>
|
||||
admin@siteA:/config/interface/gre0/> <b>set gre local 203.0.113.1 remote 203.0.113.2</b>
|
||||
admin@siteA:/config/interface/gre0/> <b>set ipv4 address 10.255.0.1 prefix-length 30</b>
|
||||
admin@siteA:/config/interface/gre0/> <b>set ipv4 forwarding</b>
|
||||
admin@siteA:/config/interface/gre0/> <b>end</b>
|
||||
admin@siteA:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@siteA:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface gre0</b>
|
||||
admin@siteA:/config/routing/…/ospf/> <b>leave</b>
|
||||
admin@siteA:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Site B configuration:**
|
||||
|
||||
```
|
||||
admin@siteB:/> configure
|
||||
admin@siteB:/config/> edit interface gre0
|
||||
admin@siteB:/config/interface/gre0/> set gre local 203.0.113.2 remote 203.0.113.1
|
||||
admin@siteB:/config/interface/gre0/> set ipv4 address 10.255.0.2 prefix-length 30
|
||||
admin@siteB:/config/interface/gre0/> set ipv4 forwarding
|
||||
admin@siteB:/config/interface/gre0/> end
|
||||
admin@siteB:/config/> edit routing control-plane-protocol ospfv2 name default ospf
|
||||
admin@siteB:/config/routing/…/ospf/> set area 0.0.0.0 interface gre0
|
||||
admin@siteB:/config/routing/…/ospf/> leave
|
||||
<pre class="cli"><code>admin@siteB:/> <b>configure</b>
|
||||
admin@siteB:/config/> <b>edit interface gre0</b>
|
||||
admin@siteB:/config/interface/gre0/> <b>set gre local 203.0.113.2 remote 203.0.113.1</b>
|
||||
admin@siteB:/config/interface/gre0/> <b>set ipv4 address 10.255.0.2 prefix-length 30</b>
|
||||
admin@siteB:/config/interface/gre0/> <b>set ipv4 forwarding</b>
|
||||
admin@siteB:/config/interface/gre0/> <b>end</b>
|
||||
admin@siteB:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
|
||||
admin@siteB:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface gre0</b>
|
||||
admin@siteB:/config/routing/…/ospf/> <b>leave</b>
|
||||
admin@siteB:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Once configured, OSPF will establish a neighbor relationship through the
|
||||
tunnel and exchange routes between the sites. For more info on OSPF
|
||||
configuration, see [OSPFv2 Routing](networking.md#ospfv2-routing).
|
||||
configuration, see [OSPFv2 Routing](routing.md#ospfv2-routing).
|
||||
|
||||
> [!NOTE]
|
||||
> Consider adjusting MTU on the tunnel interface to account for GRE
|
||||
@@ -118,11 +114,10 @@ The TTL setting controls the Time To Live value for the outer tunnel packets.
|
||||
By default, tunnels use a fixed TTL of 64, which allows packets to traverse
|
||||
multiple hops between tunnel endpoints.
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface gre0
|
||||
admin@example:/config/interface/gre0/> set gre ttl 255
|
||||
admin@example:/config/interface/gre0/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface gre0</b>
|
||||
admin@example:/config/interface/gre0/> <b>set gre ttl 255</b>
|
||||
admin@example:/config/interface/gre0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Valid values are 1-255, or the special value `inherit` which copies the TTL
|
||||
from the encapsulated packet.
|
||||
@@ -136,11 +131,10 @@ from the encapsulated packet.
|
||||
|
||||
The ToS setting controls QoS marking for tunnel traffic:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface gre0
|
||||
admin@example:/config/interface/gre0/> set gre tos 0x10
|
||||
admin@example:/config/interface/gre0/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface gre0</b>
|
||||
admin@example:/config/interface/gre0/> <b>set gre tos 0x10</b>
|
||||
admin@example:/config/interface/gre0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Valid values are 0-255 for fixed ToS/DSCP marking, or `inherit` (default)
|
||||
to copy the ToS value from the encapsulated packet.
|
||||
@@ -151,11 +145,10 @@ The `pmtu-discovery` setting can be used to control the Path MTU Discovery on
|
||||
GRE tunnels. When enabled (default), the tunnel respects the Don't Fragment
|
||||
(DF) bit and performs PMTU discovery:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface gre0
|
||||
admin@example:/config/interface/gre0/> set gre pmtudisc false
|
||||
admin@example:/config/interface/gre0/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface gre0</b>
|
||||
admin@example:/config/interface/gre0/> <b>set gre pmtudisc false</b>
|
||||
admin@example:/config/interface/gre0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
Disabling PMTU discovery may be necessary in networks with broken ICMP
|
||||
filtering but can lead to suboptimal performance and fragmentation.
|
||||
@@ -175,15 +168,14 @@ Infix supports both IPv4 and IPv6 for VXLAN tunnel endpoints.
|
||||
> If you name your VXLAN interface `vxlanN`, where `N` is a number, the
|
||||
> CLI infers the interface type automatically.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface vxlan100
|
||||
admin@example:/config/interface/vxlan100/> set vxlan local 192.168.3.1
|
||||
admin@example:/config/interface/vxlan100/> set vxlan remote 192.168.3.2
|
||||
admin@example:/config/interface/vxlan100/> set vxlan vni 100
|
||||
admin@example:/config/interface/vxlan100/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface vxlan100</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan local 192.168.3.1</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan remote 192.168.3.2</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan vni 100</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The VNI uniquely identifies the VXLAN segment and must match on both
|
||||
tunnel endpoints.
|
||||
@@ -193,16 +185,15 @@ tunnel endpoints.
|
||||
The default VXLAN UDP destination port is 4789 (IANA assigned). In some
|
||||
cases you may need to use a different port:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface vxlan100
|
||||
admin@example:/config/interface/vxlan100/> set vxlan local 192.168.3.1
|
||||
admin@example:/config/interface/vxlan100/> set vxlan remote 192.168.3.2
|
||||
admin@example:/config/interface/vxlan100/> set vxlan vni 100
|
||||
admin@example:/config/interface/vxlan100/> set vxlan remote-port 8472
|
||||
admin@example:/config/interface/vxlan100/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface vxlan100</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan local 192.168.3.1</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan remote 192.168.3.2</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan vni 100</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>set vxlan remote-port 8472</b>
|
||||
admin@example:/config/interface/vxlan100/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The remote-port setting allows interoperability with systems using
|
||||
non-standard VXLAN ports.
|
||||
|
||||
+80
-102
@@ -8,16 +8,14 @@ The _boot order_ defines which image is tried first, and is listed with
|
||||
the CLI `show software` command. It also shows Infix version installed
|
||||
per partition, and which image was used when booting (`STATE booted`).
|
||||
|
||||
```
|
||||
admin@example:/> show software
|
||||
BOOT ORDER
|
||||
primary secondary net
|
||||
<pre class="cli"><code>admin@example:/> <b>show software</b>
|
||||
Boot order : primary secondary net
|
||||
|
||||
NAME STATE VERSION DATE
|
||||
primary booted v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary inactive v25.01.0 2025-04-25T10:07:20+00:00
|
||||
<span class="header">NAME STATE VERSION DATE </span>
|
||||
primary booted v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary inactive v25.01.0 2025-04-25T10:07:20+00:00
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
YANG support for upgrading Infix, inspecting and _modifying_ the
|
||||
boot-order, is defined in [infix-system-software][2].
|
||||
@@ -41,52 +39,47 @@ valid values.
|
||||
|
||||
Example: View current boot order and change it:
|
||||
|
||||
```
|
||||
admin@example:/> show boot-order
|
||||
<pre class="cli"><code>admin@example:/> <b>show boot-order</b>
|
||||
primary secondary net
|
||||
admin@example:/> set boot-order secondary primary net
|
||||
admin@example:/> show boot-order
|
||||
admin@example:/> <b>set boot-order secondary primary net</b>
|
||||
admin@example:/> <b>show boot-order</b>
|
||||
secondary primary net
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Example: Set boot order to only try primary partition:
|
||||
|
||||
```
|
||||
admin@example:/> show boot-order
|
||||
<pre class="cli"><code>admin@example:/> <b>show boot-order</b>
|
||||
secondary primary net
|
||||
admin@example:/> set boot-order primary
|
||||
admin@example:/> show boot-order
|
||||
admin@example:/> <b>set boot-order primary</b>
|
||||
admin@example:/> <b>show boot-order</b>
|
||||
primary
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Example: Using tab-completion (press TAB to see available options):
|
||||
|
||||
```
|
||||
admin@example:/> set boot-order <TAB>
|
||||
<pre class="cli"><code>admin@example:/> <b>set boot-order </b><kbd>TAB</kbd>
|
||||
net primary secondary
|
||||
admin@example:/> set boot-order secondary <TAB>
|
||||
admin@example:/> <b>set boot-order secondary </b><kbd>TAB</kbd>
|
||||
net primary secondary
|
||||
admin@example:/> set boot-order secondary primary
|
||||
admin@example:/> show boot-order
|
||||
admin@example:/> <b>set boot-order secondary primary</b>
|
||||
admin@example:/> <b>show boot-order</b>
|
||||
secondary primary
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The new boot order takes effect on the next reboot and can be verified
|
||||
with `show boot-order` or `show software`:
|
||||
|
||||
```
|
||||
admin@example:/> show software
|
||||
BOOT ORDER
|
||||
secondary primary
|
||||
<pre class="cli"><code>admin@example:/> <b>show software</b>
|
||||
Boot order : secondary primary
|
||||
|
||||
NAME STATE VERSION DATE
|
||||
primary booted v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary inactive v25.01.0 2025-04-25T10:07:20+00:00
|
||||
<span class="header">NAME STATE VERSION DATE </span>
|
||||
primary booted v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary inactive v25.01.0 2025-04-25T10:07:20+00:00
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> The boot order is automatically updated when performing an upgrade.
|
||||
@@ -127,27 +120,28 @@ configuration before performing an upgrade. The backup is useful if the
|
||||
upgrade fails, and makes a later [downgrade](#downgrading) a smoother
|
||||
process.
|
||||
|
||||
```
|
||||
admin@example:/> dir /cfg
|
||||
<pre class="cli"><code>admin@example:/> <b>dir /cfg</b>
|
||||
/cfg directory
|
||||
backup/ ssl/ startup-config.cfg
|
||||
|
||||
admin@example:/> copy /cfg/startup-config.cfg /cfg/v25.01.0-startup-config.cfg
|
||||
admin@example:/> dir /cfg
|
||||
admin@example:/> <b>copy /cfg/startup-config.cfg /cfg/v25.01.0-startup-config.cfg</b>
|
||||
admin@example:/> <b>dir /cfg</b>
|
||||
/cfg directory
|
||||
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
|
||||
|
||||
admin@example:/>
|
||||
```
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
*Upgrade:* Here the image *pkg bundle* was made available via TFTP.
|
||||
|
||||
```
|
||||
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.03.1.pkg
|
||||
<pre class="cli"><code>admin@example:/> <b>upgrade tftp://198.18.117.1/infix-aarch64-25.03.1.pkg</b>
|
||||
installing
|
||||
0% Installing
|
||||
0% Determining slot states
|
||||
10% Determining slot states done.
|
||||
...
|
||||
40% Checking slot rootfs.1 (secondary)
|
||||
46% Checking slot rootfs.1 (secondary) done.
|
||||
...
|
||||
98% Copying image to rootfs.1
|
||||
99% Copying image to rootfs.1
|
||||
@@ -156,14 +150,13 @@ installing
|
||||
100% Installing done.
|
||||
Installing `tftp://198.18.117.1/infix-aarch64-25.03.1.pkg` succeeded
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
*Reboot:* The unit will boot on the other partition, with the newly
|
||||
installed image. The `Loading startup-config` step conducts migration
|
||||
of startup configuration if applicable.
|
||||
|
||||
```
|
||||
admin@example:/> reboot
|
||||
<pre class="cli"><code>admin@example:/> <b>reboot</b>
|
||||
[ OK ] Stopping Static routing daemon
|
||||
[ OK ] Stopping Zebra routing daemon
|
||||
...
|
||||
@@ -173,7 +166,7 @@ admin@example:/> reboot
|
||||
[ OK ] Starting Status daemon
|
||||
|
||||
Infix OS — Immutable.Friendly.Secure v25.03.1 (ttyS0)
|
||||
example login: admin
|
||||
example login: <b>admin</b>
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
@@ -182,19 +175,18 @@ Password:
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
admin@example:~$ cli
|
||||
admin@example:~$ <b>cli</b>
|
||||
|
||||
See the 'help' command for an introduction to the system
|
||||
|
||||
admin@example:/> show software
|
||||
BOOT ORDER
|
||||
secondary primary net
|
||||
admin@example:/> <b>show software</b>
|
||||
Boot order : secondary primary net
|
||||
|
||||
NAME STATE VERSION DATE
|
||||
primary inactive v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary booted v25.03.1 2025-04-25T10:24:31+00:00
|
||||
<span class="header">NAME STATE VERSION DATE </span>
|
||||
primary inactive v25.01.0 2025-04-25T10:15:00+00:00
|
||||
secondary booted v25.03.1 2025-04-25T10:24:31+00:00
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
As shown, the *boot order* has been updated, so that *secondary* is
|
||||
now the preferred boot source.
|
||||
@@ -217,20 +209,18 @@ numbering). The startup configuration is migrated to `1.5`
|
||||
definitions and stored, while a backup previous startup configuration
|
||||
is stored in directory `/cfg/backup/`.
|
||||
|
||||
```
|
||||
admin@example:/> dir /cfg/backup/
|
||||
<pre class="cli"><code>admin@example:/> <b>dir /cfg/backup/</b>
|
||||
/cfg/backup/ directory
|
||||
startup-config-1.4.cfg
|
||||
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The modifications made to the startup configuration can be viewed by
|
||||
comparing the files from the *shell*. An example is shown below.
|
||||
|
||||
```
|
||||
admin@example:/> exit
|
||||
admin@example:~$ diff /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg
|
||||
<pre class="cli"><code>admin@example:/> <b>exit</b>
|
||||
admin@example:~$ <b>diff /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg</b>
|
||||
--- /cfg/backup/startup-config-1.4.cfg
|
||||
+++ /cfg/startup-config.cfg
|
||||
...
|
||||
@@ -244,7 +234,7 @@ admin@example:~$ diff /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg
|
||||
+ "version": "1.5"
|
||||
...
|
||||
admin@example:~$
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
## Downgrading
|
||||
|
||||
@@ -259,16 +249,14 @@ startup configuration before rebooting.
|
||||
In both cases we start out with a unit running Infix v25.03.1, and
|
||||
wish to downgrade to v25.01.0.
|
||||
|
||||
```
|
||||
admin@example:/> show software
|
||||
BOOT ORDER
|
||||
primary secondary net
|
||||
<pre class="cli"><code>admin@example:/> <b>show software</b>
|
||||
Boot order : primary secondary net
|
||||
|
||||
NAME STATE VERSION DATE
|
||||
primary booted v25.03.1 2025-04-25T11:36:26+00:00
|
||||
secondary inactive v25.03.1 2025-04-25T10:24:31+00:00
|
||||
<span class="header">NAME STATE VERSION DATE </span>
|
||||
primary booted v25.03.1 2025-04-25T11:36:26+00:00
|
||||
secondary inactive v25.03.1 2025-04-25T10:24:31+00:00
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
### With Backup `startup-config`
|
||||
|
||||
@@ -292,24 +280,22 @@ running Infix v25.01.0 on the unit. See section [Upgrading](#upgrading)
|
||||
above for more information. In the following example, there is a backup
|
||||
file available named `v25.01.0-startup-config.cfg`:
|
||||
|
||||
```
|
||||
admin@example:/> dir /cfg
|
||||
<pre class="cli"><code>admin@example:/> <b>dir /cfg</b>
|
||||
/cfg directory
|
||||
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
|
||||
|
||||
admin@example:/>
|
||||
```
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
The alternative is to use a startup config implicitly backed up by the
|
||||
system as part of [Configuration Migration](#configuration-migration).
|
||||
|
||||
```
|
||||
admin@example:/> dir /cfg/backup/
|
||||
<pre class="cli"><code>admin@example:/> <b>dir /cfg/backup/</b>
|
||||
/cfg/backup/ directory
|
||||
startup-config-1.4.cfg
|
||||
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!CAUTION]
|
||||
> Using a backup configuration file stored when the unit was running the
|
||||
@@ -330,8 +316,7 @@ config*.
|
||||
|
||||
*Use `upgrade` command to downgrade:*
|
||||
|
||||
```
|
||||
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
|
||||
<pre class="cli"><code>admin@example:/> <b>upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg</b>
|
||||
installing
|
||||
0% Installing
|
||||
0% Determining slot states
|
||||
@@ -342,35 +327,32 @@ installing
|
||||
100% Installing done.
|
||||
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
*Apply the backup configuration file:*
|
||||
|
||||
It is recommended to use a backup configuration file for the Infix version to
|
||||
downgrade to, if there is one available.
|
||||
|
||||
```
|
||||
admin@example:/> copy /cfg/v25.01.0-startup-config.cfg /cfg/startup-config.cfg
|
||||
Overwrite existing file /cfg/startup-config.cfg (y/N)? y
|
||||
<pre class="cli"><code>admin@example:/> <b>copy /cfg/v25.01.0-startup-config.cfg /cfg/startup-config.cfg</b>
|
||||
Overwrite existing file /cfg/startup-config.cfg (y/N)? <b>y</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
An alternative is to use a backup file stored when the system
|
||||
conducted a [configuration migration](#configuration-migration). See
|
||||
the *caution* note above.
|
||||
|
||||
```
|
||||
admin@example:/> copy /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg
|
||||
Overwrite existing file /cfg/startup-config.cfg (y/N)? y
|
||||
<pre class="cli"><code>admin@example:/> <b>copy /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg</b>
|
||||
Overwrite existing file /cfg/startup-config.cfg (y/N)? <b>y</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
*Reboot:*
|
||||
|
||||
The unit will come up with the applied backup configuration.
|
||||
|
||||
```
|
||||
admin@example:/> reboot
|
||||
<pre class="cli"><code>admin@example:/> <b>reboot</b>
|
||||
[ OK ] Saving system clock to file
|
||||
[ OK ] Stopping Software update service
|
||||
[ OK ] Stopping Status daemon
|
||||
@@ -384,7 +366,7 @@ admin@example:/> reboot
|
||||
|
||||
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
|
||||
example login:
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> If the unit despite these measures ends up in *failure config*, see
|
||||
@@ -403,8 +385,7 @@ its default login credentials[^1].
|
||||
|
||||
*Use `upgrade` command to downgrade:*
|
||||
|
||||
```
|
||||
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
|
||||
<pre class="cli"><code>admin@example:/> <b>upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg</b>
|
||||
installing
|
||||
0% Installing
|
||||
0% Determining slot states
|
||||
@@ -415,7 +396,7 @@ installing
|
||||
100% Installing done.
|
||||
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
*Reboot:*
|
||||
|
||||
@@ -426,8 +407,7 @@ config][3]. This is what is seen on the console when this situation
|
||||
occurs. Note that the login prompt displays `failed` as part of the
|
||||
*hostname*.
|
||||
|
||||
```
|
||||
admin@example:/> reboot
|
||||
<pre class="cli"><code>admin@example:/> <b>reboot</b>
|
||||
[ OK ] Saving system clock to file
|
||||
[ OK ] Stopping Software update service
|
||||
[ OK ] Stopping Status daemon
|
||||
@@ -444,32 +424,30 @@ Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
|
||||
|
||||
ERROR: Corrupt startup-config, system has reverted to default login credentials
|
||||
failed-00-00-00 login:
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
To remedy a situation like this, you can login with the unit's *default
|
||||
login credentials*, preferrably via a [console port][4].
|
||||
The unit's default credentials are typically printed on a sticker on
|
||||
the unit.
|
||||
|
||||
```
|
||||
failed-00-00-00 login: admin
|
||||
<pre class="cli"><code>failed-00-00-00 login: <b>admin</b>
|
||||
Password:
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
admin@failed-00-00-00:~$
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
When it is *safe* from a network operations perspective, you can
|
||||
conduct a factory reset and reboot. It is recommended to remove the
|
||||
unit from any production network before doing this, as a factory reset
|
||||
may enable undesired connectivity between the unit's ports.
|
||||
|
||||
```
|
||||
admin@failed-00-00-00:~$ factory
|
||||
Factory reset device (y/N)? y
|
||||
<pre class="cli"><code>admin@failed-00-00-00:~$ <b>factory</b>
|
||||
Factory reset device (y/N)? <b>y</b>
|
||||
factory: scheduled factory reset on next boot.
|
||||
Reboot now to perform reset, (y/N)? y
|
||||
Reboot now to perform reset, (y/N)? <b>y</b>
|
||||
[ OK ] Saving system time (UTC) to RTC
|
||||
[ OK ] Stopping mDNS alias advertiser
|
||||
...
|
||||
@@ -485,7 +463,7 @@ Please press Enter to activate this console.
|
||||
|
||||
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
|
||||
example login:
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
Continued configuration is done as with any unit after factory reset.
|
||||
|
||||
|
||||
+135
-148
@@ -41,27 +41,25 @@ and saves it to `publickey`.
|
||||
|
||||
**Import the private key into the keystore:**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit keystore asymmetric-key wg-site-a
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set public-key-format x25519-public-key-format
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set private-key-format x25519-private-key-format
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set public-key bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP=
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set private-key aMqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP=
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit keystore asymmetric-key wg-site-a</b>
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> <b>set public-key-format x25519-public-key-format</b>
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> <b>set private-key-format x25519-private-key-format</b>
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> <b>set public-key bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP=</b>
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> <b>set private-key aMqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP=</b>
|
||||
admin@example:/config/keystore/asymmetric-key/wg-site-a/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Import peer public keys into the truststore:**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit truststore public-key-bag wg-peers public-key peer-b
|
||||
admin@example:/config/truststore/…/peer-b/> set public-key-format x25519-public-key-format
|
||||
admin@example:/config/truststore/…/peer-b/> set public-key PEER_PUBLIC_KEY_HERE
|
||||
admin@example:/config/truststore/…/peer-b/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit truststore public-key-bag wg-peers public-key peer-b</b>
|
||||
admin@example:/config/truststore/…/peer-b/> <b>set public-key-format x25519-public-key-format</b>
|
||||
admin@example:/config/truststore/…/peer-b/> <b>set public-key PEER_PUBLIC_KEY_HERE</b>
|
||||
admin@example:/config/truststore/…/peer-b/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Keep private keys secure! Never share your private key. Only exchange
|
||||
@@ -78,37 +76,35 @@ A basic WireGuard tunnel between two sites:
|
||||
|
||||
**Site A configuration:**
|
||||
|
||||
```
|
||||
admin@siteA:/> configure
|
||||
admin@siteA:/config/> edit interface wg0
|
||||
admin@siteA:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@siteA:/config/interface/wg0/> set wireguard private-key wg-site-a
|
||||
admin@siteA:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
|
||||
admin@siteA:/config/interface/wg0/> edit wireguard peer wg-peers peer-b
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> set endpoint 203.0.113.2
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> set endpoint-port 51820
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> set allowed-ips 10.0.0.2/32
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> set persistent-keepalive 25
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> leave
|
||||
<pre class="cli"><code>admin@siteA:/> <b>configure</b>
|
||||
admin@siteA:/config/> <b>edit interface wg0</b>
|
||||
admin@siteA:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@siteA:/config/interface/wg0/> <b>set wireguard private-key wg-site-a</b>
|
||||
admin@siteA:/config/interface/wg0/> <b>set ipv4 address 10.0.0.1 prefix-length 24</b>
|
||||
admin@siteA:/config/interface/wg0/> <b>edit wireguard peer wg-peers peer-b</b>
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> <b>set endpoint 203.0.113.2</b>
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> <b>set endpoint-port 51820</b>
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> <b>set allowed-ips 10.0.0.2/32</b>
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> <b>set persistent-keepalive 25</b>
|
||||
admin@siteA:/config/interface/…/wg-peers/peer/peer-b/> <b>leave</b>
|
||||
admin@siteA:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Site B configuration:**
|
||||
|
||||
```
|
||||
admin@siteB:/> configure
|
||||
admin@siteB:/config/> edit interface wg0
|
||||
admin@siteB:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@siteB:/config/interface/wg0/> set wireguard private-key wg-site-b
|
||||
admin@siteB:/config/interface/wg0/> set ipv4 address 10.0.0.2 prefix-length 24
|
||||
admin@siteB:/config/interface/wg0/> edit wireguard peer wg-peers peer-a
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> set endpoint 203.0.113.1
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> set endpoint-port 51820
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> set allowed-ips 10.0.0.1/32
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> set persistent-keepalive 25
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> leave
|
||||
<pre class="cli"><code>admin@siteB:/> <b>configure</b>
|
||||
admin@siteB:/config/> <b>edit interface wg0</b>
|
||||
admin@siteB:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@siteB:/config/interface/wg0/> <b>set wireguard private-key wg-site-b</b>
|
||||
admin@siteB:/config/interface/wg0/> <b>set ipv4 address 10.0.0.2 prefix-length 24</b>
|
||||
admin@siteB:/config/interface/wg0/> <b>edit wireguard peer wg-peers peer-a</b>
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> <b>set endpoint 203.0.113.1</b>
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> <b>set endpoint-port 51820</b>
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> <b>set allowed-ips 10.0.0.1/32</b>
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> <b>set persistent-keepalive 25</b>
|
||||
admin@siteB:/config/interface/…/wg-peers/peer/peer-a/> <b>leave</b>
|
||||
admin@siteB:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
This creates an encrypted tunnel with Site A at 10.0.0.1 and Site B at 10.0.0.2.
|
||||
|
||||
@@ -130,10 +126,9 @@ For a simple point-to-point tunnel, you typically allow only the peer's
|
||||
tunnel IP address (e.g., `10.0.0.2/32`). For site-to-site VPNs connecting
|
||||
entire networks, include the remote network prefixes:
|
||||
|
||||
```
|
||||
admin@example:/config/interface/…/wg-peers/peer/peer-a/> set allowed-ips 10.0.0.2/32
|
||||
admin@example:/config/interface/…/wg-peers/peer/peer-a/> set allowed-ips 192.168.2.0/24
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/interface/…/wg-peers/peer/peer-a/> <b>set allowed-ips 10.0.0.2/32</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/peer-a/> <b>set allowed-ips 192.168.2.0/24</b>
|
||||
</code></pre>
|
||||
|
||||
This allows traffic to/from the peer at 10.0.0.2 and routes traffic destined
|
||||
for 192.168.2.0/24 through this peer.
|
||||
@@ -141,7 +136,7 @@ for 192.168.2.0/24 through this peer.
|
||||
> [!NOTE]
|
||||
> When routing traffic to networks behind WireGuard peers, you also need
|
||||
> to configure static routes pointing to the WireGuard interface. See
|
||||
> [Static Routes](networking.md#static-routes) for more information.
|
||||
> [Static Routes](routing.md) for more information.
|
||||
|
||||
## Peer Configuration and Key Bags
|
||||
|
||||
@@ -174,35 +169,34 @@ Settings that support bag-level defaults and per-peer overrides:
|
||||
|
||||
**Example with bag-level defaults:**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface wg0
|
||||
admin@example:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@example:/config/interface/wg0/> set wireguard private-key wg-key
|
||||
admin@example:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface wg0</b>
|
||||
admin@example:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@example:/config/interface/wg0/> <b>set wireguard private-key wg-key</b>
|
||||
admin@example:/config/interface/wg0/> <b>set ipv4 address 10.0.0.1 prefix-length 24</b>
|
||||
|
||||
# Configure defaults for all peers in the 'branch-offices' bag
|
||||
admin@example:/config/interface/wg0/> edit wireguard peers branch-offices
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> set endpoint-port 51820
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> set persistent-keepalive 25
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> end
|
||||
admin@example:/config/interface/wg0/> <b>edit wireguard peers branch-offices</b>
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> <b>set endpoint-port 51820</b>
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> <b>set persistent-keepalive 25</b>
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> <b>end</b>
|
||||
|
||||
# Configure peer-specific settings (inherits endpoint-port and keepalive from bag)
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> edit peer office-east
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> set endpoint 203.0.113.10
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> set allowed-ips 10.0.0.10/32
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> set allowed-ips 192.168.10.0/24
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> end
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> <b>edit peer office-east</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> <b>set endpoint 203.0.113.10</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> <b>set allowed-ips 10.0.0.10/32</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> <b>set allowed-ips 192.168.10.0/24</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-east/> <b>end</b>
|
||||
|
||||
# Another peer with an override for persistent-keepalive
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> edit peer office-west
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> set endpoint 203.0.113.20
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> set allowed-ips 10.0.0.20/32
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> set allowed-ips 192.168.20.0/24
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> set persistent-keepalive 10
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> leave
|
||||
admin@example:/config/interface/…/wireguard/peers/branch-offices/> <b>edit peer office-west</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> <b>set endpoint 203.0.113.20</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> <b>set allowed-ips 10.0.0.20/32</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> <b>set allowed-ips 192.168.20.0/24</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> <b>set persistent-keepalive 10</b>
|
||||
admin@example:/config/interface/…/branch-offices/peer/office-west/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
In this example:
|
||||
- Both peers inherit `endpoint-port 51820` and `persistent-keepalive 25` from the bag
|
||||
@@ -235,13 +229,12 @@ then add the remote network to `allowed-ips` and configure static routes.
|
||||
For mobile clients or peers without fixed IPs, omit the `endpoint` setting.
|
||||
WireGuard learns the peer's endpoint from authenticated incoming packets:
|
||||
|
||||
```
|
||||
admin@hub:/> configure
|
||||
admin@hub:/config/> edit interface wg0 wireguard peers wg-peers peer mobile-client
|
||||
admin@hub:/config/interface/…/wg-peers/peer/mobile-client/> set allowed-ips 10.0.0.10/32
|
||||
admin@hub:/config/interface/…/wg-peers/peer/mobile-client/> leave
|
||||
<pre class="cli"><code>admin@hub:/> <b>configure</b>
|
||||
admin@hub:/config/> <b>edit interface wg0 wireguard peers wg-peers peer mobile-client</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/mobile-client/> <b>set allowed-ips 10.0.0.10/32</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/mobile-client/> <b>leave</b>
|
||||
admin@hub:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The mobile client configures the hub's endpoint normally. The hub learns
|
||||
and tracks the mobile client's changing IP address automatically.
|
||||
@@ -256,59 +249,57 @@ sites connect to a central hub.
|
||||
|
||||
**Hub configuration:**
|
||||
|
||||
```
|
||||
admin@hub:/> configure
|
||||
admin@hub:/config/> edit interface wg0
|
||||
admin@hub:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
|
||||
admin@hub:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@hub:/config/interface/wg0/> set wireguard private-key wg-hub
|
||||
admin@hub:/config/interface/wg0/> edit wireguard peers wg-peers
|
||||
<pre class="cli"><code>admin@hub:/> <b>configure</b>
|
||||
admin@hub:/config/> <b>edit interface wg0</b>
|
||||
admin@hub:/config/interface/wg0/> <b>set ipv4 address 10.0.0.1 prefix-length 24</b>
|
||||
admin@hub:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@hub:/config/interface/wg0/> <b>set wireguard private-key wg-hub</b>
|
||||
admin@hub:/config/interface/wg0/> <b>edit wireguard peers wg-peers</b>
|
||||
|
||||
# Spoke 1
|
||||
admin@hub:/config/interface/…/wireguard/peers/wg-peers/> edit peer spoke1
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> set allowed-ips 10.0.0.2/32
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> set allowed-ips 192.168.1.0/24
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> end
|
||||
admin@hub:/config/interface/…/wireguard/peers/wg-peers/> <b>edit peer spoke1</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> <b>set allowed-ips 10.0.0.2/32</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> <b>set allowed-ips 192.168.1.0/24</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke1/> <b>end</b>
|
||||
|
||||
# Spoke 2
|
||||
admin@hub:/config/interface/…/wireguard/peers/wg-peers/> edit peer spoke2
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> set allowed-ips 10.0.0.3/32
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> set allowed-ips 192.168.2.0/24
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> leave
|
||||
admin@hub:/config/interface/…/wireguard/peers/wg-peers/> <b>edit peer spoke2</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> <b>set allowed-ips 10.0.0.3/32</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> <b>set allowed-ips 192.168.2.0/24</b>
|
||||
admin@hub:/config/interface/…/wg-peers/peer/spoke2/> <b>leave</b>
|
||||
|
||||
# Add routes for spoke networks
|
||||
admin@hub:/> configure
|
||||
admin@hub:/config/> edit routing control-plane-protocol static name default
|
||||
admin@hub:/config/routing/…/static/name/default/> set ipv4 route 192.168.1.0/24 wg0
|
||||
admin@hub:/config/routing/…/static/name/default/> set ipv4 route 192.168.2.0/24 wg0
|
||||
admin@hub:/config/routing/…/static/name/default/> leave
|
||||
admin@hub:/> <b>configure</b>
|
||||
admin@hub:/config/> <b>edit routing control-plane-protocol static name default</b>
|
||||
admin@hub:/config/routing/…/static/name/default/> <b>set ipv4 route 192.168.1.0/24 wg0</b>
|
||||
admin@hub:/config/routing/…/static/name/default/> <b>set ipv4 route 192.168.2.0/24 wg0</b>
|
||||
admin@hub:/config/routing/…/static/name/default/> <b>leave</b>
|
||||
admin@hub:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Spoke 1 configuration:**
|
||||
|
||||
```
|
||||
admin@spoke1:/> configure
|
||||
admin@spoke1:/config/> edit interface wg0
|
||||
admin@spoke1:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@spoke1:/config/interface/wg0/> set wireguard private-key wg-spoke1
|
||||
admin@spoke1:/config/interface/wg0/> set ipv4 address 10.0.0.2 prefix-length 24
|
||||
admin@spoke1:/config/interface/wg0/> edit wireguard peers wg-peers peer hub
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set endpoint 203.0.113.1
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set endpoint-port 51820
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set allowed-ips 10.0.0.1/32
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set allowed-ips 10.0.0.3/32
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set allowed-ips 192.168.0.0/24
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set allowed-ips 192.168.2.0/24
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> set persistent-keepalive 25
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> leave
|
||||
admin@spoke1:/> configure
|
||||
admin@spoke1:/config/> edit routing control-plane-protocol static name default
|
||||
admin@spoke1:/config/routing/…/static/name/default/> set ipv4 route 192.168.0.0/24 wg0
|
||||
admin@spoke1:/config/routing/…/static/name/default/> set ipv4 route 192.168.2.0/24 wg0
|
||||
admin@spoke1:/config/routing/…/static/name/default/> leave
|
||||
<pre class="cli"><code>admin@spoke1:/> <b>configure</b>
|
||||
admin@spoke1:/config/> <b>edit interface wg0</b>
|
||||
admin@spoke1:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@spoke1:/config/interface/wg0/> <b>set wireguard private-key wg-spoke1</b>
|
||||
admin@spoke1:/config/interface/wg0/> <b>set ipv4 address 10.0.0.2 prefix-length 24</b>
|
||||
admin@spoke1:/config/interface/wg0/> <b>edit wireguard peers wg-peers peer hub</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set endpoint 203.0.113.1</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set endpoint-port 51820</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set allowed-ips 10.0.0.1/32</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set allowed-ips 10.0.0.3/32</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set allowed-ips 192.168.0.0/24</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set allowed-ips 192.168.2.0/24</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>set persistent-keepalive 25</b>
|
||||
admin@spoke1:/config/interface/…/wg-peers/peer/hub/> <b>leave</b>
|
||||
admin@spoke1:/> <b>configure</b>
|
||||
admin@spoke1:/config/> <b>edit routing control-plane-protocol static name default</b>
|
||||
admin@spoke1:/config/routing/…/static/name/default/> <b>set ipv4 route 192.168.0.0/24 wg0</b>
|
||||
admin@spoke1:/config/routing/…/static/name/default/> <b>set ipv4 route 192.168.2.0/24 wg0</b>
|
||||
admin@spoke1:/config/routing/…/static/name/default/> <b>leave</b>
|
||||
admin@spoke1:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
This configuration allows Spoke 1 to reach both the hub network (192.168.0.0/24)
|
||||
and Spoke 2's network (192.168.2.0/24) via the hub, enabling spoke-to-spoke
|
||||
@@ -319,9 +310,8 @@ communication through the central hub.
|
||||
The `persistent-keepalive` setting sends periodic packets to keep the tunnel
|
||||
active through NAT devices and firewalls:
|
||||
|
||||
```
|
||||
admin@example:/config/interface/…/wg-peers/peer/hub/> set persistent-keepalive 25
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/interface/…/wg-peers/peer/hub/> <b>set persistent-keepalive 25</b>
|
||||
</code></pre>
|
||||
|
||||
This is particularly important when:
|
||||
|
||||
@@ -340,21 +330,20 @@ for peers with public static IPs that initiate connections.
|
||||
|
||||
WireGuard fully supports IPv6 for tunnel endpoints:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface wg0
|
||||
admin@example:/config/interface/wg0/> set wireguard listen-port 51820
|
||||
admin@example:/config/interface/wg0/> set wireguard private-key wg-key
|
||||
admin@example:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
|
||||
admin@example:/config/interface/wg0/> set ipv6 address fd00::1 prefix-length 64
|
||||
admin@example:/config/interface/wg0/> edit wireguard peers wg-peers peer remote
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> set endpoint 2001:db8::2
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> set endpoint-port 51820
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> set allowed-ips 10.0.0.2/32
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> set allowed-ips fd00::2/128
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface wg0</b>
|
||||
admin@example:/config/interface/wg0/> <b>set wireguard listen-port 51820</b>
|
||||
admin@example:/config/interface/wg0/> <b>set wireguard private-key wg-key</b>
|
||||
admin@example:/config/interface/wg0/> <b>set ipv4 address 10.0.0.1 prefix-length 24</b>
|
||||
admin@example:/config/interface/wg0/> <b>set ipv6 address fd00::1 prefix-length 64</b>
|
||||
admin@example:/config/interface/wg0/> <b>edit wireguard peers wg-peers peer remote</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>set endpoint 2001:db8::2</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>set endpoint-port 51820</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>set allowed-ips 10.0.0.2/32</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>set allowed-ips fd00::2/128</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
WireGuard can carry both IPv4 and IPv6 traffic regardless of whether the
|
||||
tunnel endpoints use IPv4 or IPv6.
|
||||
@@ -363,13 +352,12 @@ tunnel endpoints use IPv4 or IPv6.
|
||||
|
||||
Check WireGuard interface status and peer connections:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
wg0 wireguard UP 2 peers (1 up)
|
||||
ipv4 10.0.0.1/24 (static)
|
||||
ipv6 fd00::1/64 (static)
|
||||
|
||||
admin@example:/> show interfaces wg0
|
||||
admin@example:/> <b>show interfaces wg0</b>
|
||||
name : wg0
|
||||
type : wireguard
|
||||
index : 12
|
||||
@@ -389,7 +377,7 @@ peers : 2
|
||||
latest handshake : 2025-12-09T09:15:22+0000
|
||||
transfer tx : 45120 bytes
|
||||
transfer rx : 32768 bytes
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The connection status shows `UP` if a handshake occurred within the last 3
|
||||
minutes, indicating an active tunnel. The `latest handshake` timestamp shows
|
||||
@@ -416,17 +404,16 @@ cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=
|
||||
|
||||
**Import the preshared key into the keystore:**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit keystore symmetric-key wg-psk
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> set key-format wireguard-symmetric-key-format
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> set key cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> end
|
||||
admin@example:/config/interface/wg0/> edit wireguard peers wg-peers peer remote
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> set preshared-key wg-psk
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> leave
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key wg-psk</b>
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> <b>set key-format wireguard-symmetric-key-format</b>
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> <b>set key cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=</b>
|
||||
admin@example:/config/keystore/symmetric-key/wg-psk/> <b>end</b>
|
||||
admin@example:/config/interface/wg0/> <b>edit wireguard peers wg-peers peer remote</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>set preshared-key wg-psk</b>
|
||||
admin@example:/config/interface/…/wg-peers/peer/remote/> <b>leave</b>
|
||||
admin@example:/>
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
The preshared key must be securely shared between both peers and configured
|
||||
on both sides.
|
||||
|
||||
+249
-157
@@ -10,14 +10,35 @@ host virtual interfaces.
|
||||
Infix uses a two-layer WiFi architecture:
|
||||
|
||||
1. **WiFi Radio (PHY layer)**: Represents the physical wireless hardware
|
||||
- Configured via `ietf-hardware` module
|
||||
- Controls channel, transmit power, regulatory domain
|
||||
- One radio can host multiple virtual interfaces
|
||||
- Configured via `ietf-hardware` module
|
||||
- Controls channel, transmit power, regulatory domain
|
||||
- One radio can host multiple virtual interfaces
|
||||
|
||||
2. **WiFi Interface (Network layer)**: Virtual interface on a radio
|
||||
- Configured via `infix-interfaces` module
|
||||
- Can operate in Station (client) or Access Point mode
|
||||
- Each interface references a parent radio
|
||||
- Configured via `infix-interfaces` module
|
||||
- Can operate in Station (client) or Access Point mode
|
||||
- Each interface references a parent radio
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
Like other interface types in Infix, WiFi components follow naming conventions
|
||||
that allow the CLI to automatically infer types:
|
||||
|
||||
| **Name Pattern** | **Type** | **Description** |
|
||||
|------------------|-----------------|------------------------------------------|
|
||||
| `radioN` | WiFi Radio | Hardware component for WiFi PHY |
|
||||
| `wifiN` | WiFi Interface | Virtual WiFi interface on a radio |
|
||||
|
||||
Where `N` is a number (0, 1, 2, ...).
|
||||
|
||||
> [!TIP]
|
||||
> Using these naming conventions simplifies configuration since type/class
|
||||
> settings are automatically inferred. For example, creating a hardware
|
||||
> component named `radio0` automatically sets its class to `wifi`, enabling
|
||||
> the `wifi-radio` configuration container.
|
||||
>
|
||||
> **Note:** This inference only works with the CLI. Configuring WiFi over
|
||||
> NETCONF or RESTCONF requires setting the class/type explicitly.
|
||||
|
||||
## Current Limitations
|
||||
|
||||
@@ -31,81 +52,132 @@ Wi-Fi support is primarily tested with Realtek chipset-based adapters.
|
||||
|
||||
### Known Working Chipsets
|
||||
|
||||
- Built-in Wi-Fi on Banana Pi r3
|
||||
- Built-in Wi-Fi on Banana Pi BPi-R3
|
||||
- Built-in Wi-Fi on Raspberry Pi 4/CM4
|
||||
- RTL8821CU
|
||||
- Other Realtek chipsets may work but are not guaranteed
|
||||
- Realtek:
|
||||
- RTL8188CU
|
||||
- RTL8188FU
|
||||
- RTL8821CU
|
||||
|
||||
Other Realtek chipsets may work but are not tested.
|
||||
|
||||
> [!NOTE] Some Realtek chipsets require proprietary drivers not included in the standard kernel
|
||||
> Firmware requirements vary by chipset
|
||||
> Check kernel logs if your adapter is not detected
|
||||
> [!NOTE]
|
||||
> Some Realtek chipsets require proprietary drivers not included in the
|
||||
> standard kernel.
|
||||
>
|
||||
> - Firmware requirements vary by chipset
|
||||
> - Check kernel logs if your adapter is not detected
|
||||
|
||||
### USB WiFi Dongles
|
||||
|
||||
USB WiFi dongles may be slow to initialize at boot due to firmware
|
||||
loading. If your USB dongle is not detected reliably, configure a
|
||||
`probe-timeout` on the radio to wait for the PHY:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set probe-timeout 30</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
This waits up to 30 seconds for the radio PHY to appear before creating
|
||||
WiFi interfaces. If the PHY is not detected within the timeout, a dummy
|
||||
interface is created as a placeholder, allowing IP configuration to proceed.
|
||||
Reboot when the radio becomes available.
|
||||
|
||||
## Radio Configuration
|
||||
|
||||
Before configuring WiFi interfaces, you must first configure the WiFi radio.
|
||||
Radios are automatically discovered and named `radio0`, `radio1`, etc.
|
||||
|
||||
### Country Code and Regulatory Compliance
|
||||
### Country Code ⚠
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The `country-code` setting is **legally required** and determines which WiFi channels and power levels are permitted in your location. Using an incorrect country code may violate local wireless regulations.
|
||||
The radio defaults to "00" for World domain, but some systems may ship with a
|
||||
factory default country code (typically "DE" for the BPi-R3).
|
||||
|
||||
**Factory default**: Systems may ship with a default country code (typically "DE" for Germany in European builds or "00" for World domain). **You must configure the correct country code for your deployment location.**
|
||||
> [!IMPORTANT] Legal notice!
|
||||
> The `country-code` setting is **legally required** and determines
|
||||
> which WiFi channels and power levels are permitted in your
|
||||
> location. Using an incorrect country code may violate local wireless
|
||||
> regulations.
|
||||
|
||||
**Common country codes**:
|
||||
- Europe: DE (Germany), SE (Sweden), GB (UK), FR (France), ES (Spain)
|
||||
- Americas: US (United States), CA (Canada), BR (Brazil)
|
||||
- Asia-Pacific: JP (Japan), AU (Australia), CN (China)
|
||||
**Common country codes, see [ISO 3166-1 alpha-2][1] for the complete list**:
|
||||
|
||||
See [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) for the complete list.
|
||||
- Europe:
|
||||
- DE: Germany
|
||||
- SE: Sweden
|
||||
- GB: UK
|
||||
- FR: France
|
||||
- ES: Spain
|
||||
- Americas:
|
||||
- US: United States
|
||||
- CA: Canada
|
||||
- BR: Brazil
|
||||
- Asia-Pacific:
|
||||
- JP: Japan
|
||||
- AU: Australia
|
||||
- CN: China
|
||||
|
||||
### Basic Radio Setup
|
||||
|
||||
Configure the radio with channel, power, and regulatory domain.
|
||||
|
||||
**For Station (client) mode:**
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit hardware component radio0 wifi-radio
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set country-code DE
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> leave
|
||||
```
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set country-code DE</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**For Access Point mode:**
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit hardware component radio0 wifi-radio
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set country-code DE
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set band 5GHz
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set channel 36
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> leave
|
||||
```
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set country-code DE</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set band 5GHz</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set channel 36</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Key radio parameters:**
|
||||
- `country-code`: Two-letter ISO 3166-1 code - determines allowed channels and maximum power. Examples: US, DE, GB, SE, FR, JP. **Must match your physical location for legal compliance.**
|
||||
- `band`: 2.4GHz, 5GHz, or 6GHz (required for AP mode). Automatically enables appropriate WiFi standards (2.4GHz: 802.11n/ax, 5GHz: 802.11n/ac/ax, 6GHz: 802.11ax)
|
||||
- `channel`: Channel number (1-196) or "auto" (required for AP mode). When set to "auto", defaults to channel 6 for 2.4GHz, channel 36 for 5GHz, or channel 109 for 6GHz
|
||||
|
||||
- `country-code`: Two-letter [ISO 3166-1 alpha-2][1] code, determines allowed
|
||||
channels and maximum power. Examples: US, DE, GB, SE, FR, JP.
|
||||
**⚠ Must match your physical location for legal compliance! ⚠**
|
||||
- `band`: 2.4GHz, 5GHz, or 6GHz (required for AP mode). Automatically enables
|
||||
appropriate WiFi standards:
|
||||
- 2.4GHz: 802.11n/ax
|
||||
- 5GHz: 802.11n/ac/ax
|
||||
- 6GHz: 802.11ax
|
||||
- `channel`: Channel number (1-196) or "auto". When set to "auto", defaults to
|
||||
channel 6 for 2.4GHz, channel 36 for 5GHz, or channel 109 for 6GHz
|
||||
- `probe-timeout`: Seconds to wait for PHY detection at boot (default: 0). Set
|
||||
to a non-zero value (e.g., 30) for USB WiFi dongles that are slow to
|
||||
initialize due to firmware loading
|
||||
|
||||
> [!NOTE]
|
||||
> TX power and channel width are automatically determined by the driver based on regulatory constraints, PHY mode, and hardware capabilities.
|
||||
> TX power and channel width are automatically determined by the driver
|
||||
> based on regulatory constraints, PHY mode, and hardware capabilities.
|
||||
|
||||
### WiFi 6 (802.11ax) Support
|
||||
### WiFi 6 Support
|
||||
|
||||
WiFi 6 (802.11ax) is always enabled in AP mode on all bands, providing improved
|
||||
performance through features like OFDMA, BSS Coloring, and beamforming.
|
||||
|
||||
**WiFi 6 Features (always enabled):**
|
||||
|
||||
- **OFDMA**: Better multi-user efficiency in dense environments
|
||||
- **BSS Coloring**: Reduced interference from neighboring networks
|
||||
- **Beamforming**: Improved signal quality and range
|
||||
|
||||
**Requirements:**
|
||||
|
||||
- Hardware must support 802.11ax
|
||||
- Client devices must support WiFi 6 for full benefits
|
||||
- Older WiFi 5/4 clients can still connect but won't use WiFi 6 features
|
||||
|
||||
## Discovering Available Networks (Scanning)
|
||||
## Discovering Available Networks
|
||||
|
||||
Before connecting to a WiFi network, you need to discover which networks
|
||||
are available. Infix automatically scans for networks when a WiFi interface
|
||||
@@ -118,21 +190,19 @@ interface referencing it:
|
||||
|
||||
**Step 1: Configure the radio**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit hardware component radio0 wifi-radio
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set country-code DE
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set country-code DE</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Step 2: Create WiFi interface with radio reference only**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface wifi0
|
||||
admin@example:/config/interface/wifi0/> set wifi radio radio0
|
||||
admin@example:/config/interface/wifi0/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface wifi0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi radio radio0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The system will now start scanning in the background. The interface will
|
||||
operate in scan-only mode until you configure a specific mode (station or
|
||||
@@ -142,25 +212,30 @@ access-point).
|
||||
|
||||
Use `show interface` to see discovered networks and their signal strength:
|
||||
|
||||
```
|
||||
admin@example:/> show interface wifi0
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||
name : wifi0
|
||||
type : wifi
|
||||
index : 3
|
||||
mtu : 1500
|
||||
operational status : down
|
||||
operational status : up
|
||||
ip forwarding : enabled
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
ipv4 addresses :
|
||||
ipv4 addresses : 192.168.1.100/24 (dhcp)
|
||||
ipv6 addresses :
|
||||
SSID : ----
|
||||
Signal : ----
|
||||
|
||||
SSID SECURITY SIGNAL
|
||||
MyNetwork WPA2-Personal excellent
|
||||
GuestWiFi WPA2-WPA3-Personal good
|
||||
CoffeeShop Open fair
|
||||
IoT-Devices WPA2-Personal good
|
||||
```
|
||||
in-octets : 148388
|
||||
out-octets : 24555
|
||||
mode : station
|
||||
ssid : MyNetwork
|
||||
signal : -45 dBm (good)
|
||||
rx bitrate : 72.2 Mbps
|
||||
tx bitrate : 86.6 Mbps
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
<span class="title">Available Networks</span>
|
||||
<span class="header">SSID BSSID SECURITY SIGNAL CHANNEL</span>
|
||||
MyNetwork b4:fb:e4:17:b6:a7 WPA2-Personal good 6
|
||||
GuestWiFi c8:3a:35:12:34:56 WPA2-Personal fair 11
|
||||
CoffeeShop 00:1a:2b:3c:4d:5e Open bad 1
|
||||
</code></pre>
|
||||
|
||||
In the CLI, signal strength is reported as: excellent, good, fair or bad.
|
||||
For precise RSSI values in dBm, use NETCONF or RESTCONF to access the
|
||||
@@ -172,47 +247,48 @@ Station mode connects to an existing Wi-Fi network. Before configuring station
|
||||
mode, follow the "Discovering Available Networks (Scanning)" section above to
|
||||
scan for available networks and identify the SSID you want to connect to.
|
||||
|
||||
### Step 1: Configure WiFi Password
|
||||
### Step 1: Configure Password
|
||||
|
||||
Create a keystore entry for your WiFi password (8-63 characters):
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit keystore symmetric-key my-wifi-key
|
||||
admin@example:/config/keystore/…/my-wifi-key/> set key-format wifi-preshared-key-format
|
||||
admin@example:/config/keystore/…/my-wifi-key/> set symmetric-key MyPassword123
|
||||
admin@example:/config/keystore/…/my-wifi-key/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key my-wifi-key</b>
|
||||
admin@example:/config/keystore/…/my-wifi-key/> <b>set key-format wifi-preshared-key-format</b>
|
||||
admin@example:/config/keystore/…/my-wifi-key/> <b>set symmetric-key MyPassword123</b>
|
||||
admin@example:/config/keystore/…/my-wifi-key/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
### Step 2: Connect to Network
|
||||
|
||||
Configure station mode with the SSID and password to connect:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface wifi0
|
||||
admin@example:/config/interface/wifi0/> set wifi station ssid MyHomeNetwork
|
||||
admin@example:/config/interface/wifi0/> set wifi station security secret my-wifi-key
|
||||
admin@example:/config/interface/wifi0/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface wifi0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi station ssid MyHomeNetwork</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi station security secret my-wifi-key</b>
|
||||
admin@example:/config/interface/wifi0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The connection attempt will start immediately. You can verify the connection status:
|
||||
|
||||
```
|
||||
admin@example:/> show interface wifi0
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||
name : wifi0
|
||||
type : wifi
|
||||
operational status : up
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
SSID : MyHomeNetwork
|
||||
Signal : excellent
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
**Station configuration parameters:**
|
||||
|
||||
- `radio`: Reference to the WiFi radio (mandatory) - already set during scanning
|
||||
- `station ssid`: Network name to connect to (mandatory)
|
||||
- `station security mode`: `auto` (default, WPA2/WPA3 auto-negotiation) or `disabled` (open network)
|
||||
- `station security secret`: Reference to keystore entry (required unless mode is `disabled`)
|
||||
- `station security mode`:
|
||||
- `auto`: default, WPA2/WPA3 auto-negotiation
|
||||
- `disabled`: open network
|
||||
- `station security secret`: Reference to keystore entry, required unless mode
|
||||
is `disabled`
|
||||
|
||||
> [!NOTE]
|
||||
> The `auto` security mode automatically selects WPA3-SAE or WPA2-PSK based on
|
||||
@@ -228,23 +304,33 @@ a WiFi radio.
|
||||
### Basic AP Configuration
|
||||
|
||||
First, ensure the radio is configured (see Radio Configuration above). Then
|
||||
create an AP interface:
|
||||
create a keystore entry for your WiFi password and configure the AP interface:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface wifi0
|
||||
admin@example:/config/interface/wifi0/> set wifi radio radio0
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point ssid MyNetwork
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point security mode wpa2-personal
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point security secret example
|
||||
admin@example:/config/interface/wifi0/> leave
|
||||
```
|
||||
**Step 1: Create keystore entry for the WiFi password**
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key my-wifi-secret</b>
|
||||
admin@example:/config/keystore/…/my-wifi-secret/> <b>set key-format wifi-preshared-key-format</b>
|
||||
admin@example:/config/keystore/…/my-wifi-secret/> <b>set symmetric-key MySecurePassword123</b>
|
||||
admin@example:/config/keystore/…/my-wifi-secret/> <b>end</b>
|
||||
</code></pre>
|
||||
|
||||
**Step 2: Create the AP interface**
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/> <b>edit interface wifi0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi radio radio0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point ssid MyNetwork</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point security mode wpa2-personal</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point security secret my-wifi-secret</b>
|
||||
admin@example:/config/interface/wifi0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!NOTE]
|
||||
> Using `wifiN` as the interface name automatically sets the type to WiFi.
|
||||
> Alternatively, you can use any name and explicitly set `type wifi`.
|
||||
|
||||
**Access Point configuration parameters:**
|
||||
|
||||
- `radio`: Reference to the WiFi radio (mandatory)
|
||||
- `access-point ssid`: Network name (SSID) to broadcast
|
||||
- `access-point hidden`: Set to `true` to hide SSID (optional, default: false)
|
||||
@@ -252,18 +338,18 @@ admin@example:/config/interface/wifi0/> leave
|
||||
- `access-point security secret`: Reference to keystore entry (for secured networks)
|
||||
|
||||
**Security modes:**
|
||||
|
||||
- `open`: No encryption (not recommended)
|
||||
- `wpa2-personal`: WPA2-PSK (most compatible)
|
||||
- `wpa3-personal`: WPA3-SAE (more secure, requires WPA3-capable clients)
|
||||
- `wpa2-wpa3-personal`: Mixed mode (maximum compatibility)
|
||||
|
||||
### Hidden Network (SSID Hiding)
|
||||
### SSID Hiding
|
||||
|
||||
To create a hidden network that doesn't broadcast its SSID:
|
||||
|
||||
```
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point hidden true
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/config/interface/wifi0/> <b>set wifi access-point hidden true</b>
|
||||
</code></pre>
|
||||
|
||||
### Multi-SSID Configuration
|
||||
|
||||
@@ -273,59 +359,56 @@ IoT devices, or segregating traffic into different VLANs.
|
||||
|
||||
**Step 1: Configure the radio** (shared by all APs)
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit hardware component radio0 wifi-radio
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set country-code DE
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set band 5GHz
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> set channel 36
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set country-code DE</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set band 5GHz</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set channel 36</b>
|
||||
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Step 2: Configure keystore secrets**
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit keystore symmetric-key main-secret
|
||||
admin@example:/config/keystore/…/main-secret/> set key-format wifi-preshared-key-format
|
||||
admin@example:/config/keystore/…/main-secret/> set symmetric-key MyMainPassword
|
||||
admin@example:/config/> edit keystore symmetric-key guest-secret
|
||||
admin@example:/config/keystore/…/guest-secret/> set key-format wifi-preshared-key-format
|
||||
admin@example:/config/keystore/…/guest-secret/> set symmetric-key GuestPassword123
|
||||
admin@example:/config/> edit keystore symmetric-key iot-secret
|
||||
admin@example:/config/keystore/…/iot-secret/> set key-format wifi-preshared-key-format
|
||||
admin@example:/config/keystore/…/iot-secret/> set symmetric-key IoTDevices2025
|
||||
admin@example:/config/keystore/…/iot-secret/> leave
|
||||
```
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key main-secret</b>
|
||||
admin@example:/config/keystore/…/main-secret/> <b>set key-format wifi-preshared-key-format</b>
|
||||
admin@example:/config/keystore/…/main-secret/> <b>set symmetric-key MyMainPassword</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key guest-secret</b>
|
||||
admin@example:/config/keystore/…/guest-secret/> <b>set key-format wifi-preshared-key-format</b>
|
||||
admin@example:/config/keystore/…/guest-secret/> <b>set symmetric-key GuestPassword123</b>
|
||||
admin@example:/config/> <b>edit keystore symmetric-key iot-secret</b>
|
||||
admin@example:/config/keystore/…/iot-secret/> <b>set key-format wifi-preshared-key-format</b>
|
||||
admin@example:/config/keystore/…/iot-secret/> <b>set symmetric-key IoTDevices2025</b>
|
||||
admin@example:/config/keystore/…/iot-secret/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
**Step 3: Create multiple AP interfaces** (all on radio0)
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
# Primary AP - Main network (WPA3 for maximum security)
|
||||
admin@example:/config/> edit interface wifi0
|
||||
admin@example:/config/interface/wifi0/> set wifi radio radio0
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point ssid MainNetwork
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point security mode wpa3-personal
|
||||
admin@example:/config/interface/wifi0/> set wifi access-point security secret main-secret
|
||||
admin@example:/config/> <b>edit interface wifi0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi radio radio0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point ssid MainNetwork</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point security mode wpa3-personal</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set wifi access-point security secret main-secret</b>
|
||||
|
||||
# Guest AP - Guest network (WPA2/WPA3 mixed for compatibility)
|
||||
admin@example:/config/> edit interface wifi1
|
||||
admin@example:/config/interface/wifi1/> set wifi radio radio0
|
||||
admin@example:/config/interface/wifi1/> set wifi access-point ssid GuestNetwork
|
||||
admin@example:/config/interface/wifi1/> set wifi access-point security mode wpa2-wpa3-personal
|
||||
admin@example:/config/interface/wifi1/> set wifi access-point security secret guest-secret
|
||||
admin@example:/config/interface/wifi1/> set custom-phys-address static 00:0c:43:26:60:01
|
||||
admin@example:/config/> <b>edit interface wifi1</b>
|
||||
admin@example:/config/interface/wifi1/> <b>set wifi radio radio0</b>
|
||||
admin@example:/config/interface/wifi1/> <b>set wifi access-point ssid GuestNetwork</b>
|
||||
admin@example:/config/interface/wifi1/> <b>set wifi access-point security mode wpa2-wpa3-personal</b>
|
||||
admin@example:/config/interface/wifi1/> <b>set wifi access-point security secret guest-secret</b>
|
||||
admin@example:/config/interface/wifi1/> <b>set custom-phys-address static 00:0c:43:26:60:01</b>
|
||||
|
||||
# IoT AP - IoT devices (WPA2 for older device compatibility)
|
||||
admin@example:/config/> edit interface wifi2
|
||||
admin@example:/config/interface/wifi2/> set wifi radio radio0
|
||||
admin@example:/config/interface/wifi2/> set wifi access-point ssid IoT-Devices
|
||||
admin@example:/config/interface/wifi2/> set wifi access-point security mode wpa2-personal
|
||||
admin@example:/config/interface/wifi2/> set wifi access-point security secret iot-secret
|
||||
admin@example:/config/interface/wifi2/> set custom-phys-address static 00:0c:43:26:60:02
|
||||
admin@example:/config/interface/wifi2/> leave
|
||||
```
|
||||
admin@example:/config/> <b>edit interface wifi2</b>
|
||||
admin@example:/config/interface/wifi2/> <b>set wifi radio radio0</b>
|
||||
admin@example:/config/interface/wifi2/> <b>set wifi access-point ssid IoT-Devices</b>
|
||||
admin@example:/config/interface/wifi2/> <b>set wifi access-point security mode wpa2-personal</b>
|
||||
admin@example:/config/interface/wifi2/> <b>set wifi access-point security secret iot-secret</b>
|
||||
admin@example:/config/interface/wifi2/> <b>set custom-phys-address static 00:0c:43:26:60:02</b>
|
||||
admin@example:/config/interface/wifi2/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **MAC Address Requirement for Multi-SSID:**
|
||||
@@ -342,12 +425,14 @@ admin@example:/config/interface/wifi2/> leave
|
||||
> - Tertiary (wifi2): `00:0c:43:26:60:02` (increment last octet)
|
||||
|
||||
**Result:** Three SSIDs broadcasting simultaneously on radio0:
|
||||
|
||||
- `MainNetwork` (WPA3, most secure)
|
||||
- `GuestNetwork` (WPA2/WPA3 mixed mode)
|
||||
- `IoT-Devices` (WPA2 for compatibility)
|
||||
|
||||
All APs on the same radio share the same channel and physical layer settings
|
||||
(configured at the radio level). Each AP can have its own:
|
||||
|
||||
- SSID (network name)
|
||||
- Security mode and passphrase
|
||||
- Hidden/visible SSID setting
|
||||
@@ -365,25 +450,32 @@ radio settings, and `show interface` to see all active AP interfaces.
|
||||
WiFi AP interfaces can be added to bridges to integrate wireless devices
|
||||
into your LAN:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface br0
|
||||
admin@example:/config/interface/br0/> set type bridge
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface br0</b>
|
||||
admin@example:/config/interface/br0/> <b>set type bridge</b>
|
||||
|
||||
admin@example:/config/> edit interface wifi0
|
||||
admin@example:/config/interface/wifi0/> set bridge-port bridge br0
|
||||
admin@example:/config/interface/wifi0/> leave
|
||||
```
|
||||
admin@example:/config/> <b>edit interface wifi0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>set bridge-port bridge br0</b>
|
||||
admin@example:/config/interface/wifi0/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
## Troubleshooting Connection Issues
|
||||
## Troubleshooting
|
||||
|
||||
Use `show interface wifi0` to verify signal strength and connection status.
|
||||
If issues arise, try the following troubleshooting steps:
|
||||
|
||||
1. **Verify signal strength**: Check that the target network shows "good" or "excellent" signal in scan results
|
||||
2. **Check credentials**: Verify the preshared key in the keystore matches the network password
|
||||
3. **Review logs**: Check system logs with `show log` for Wi-Fi related errors
|
||||
4. **Regulatory compliance**: Ensure the country-code on the radio matches your location
|
||||
5. **Hardware detection**: Confirm the WiFi radio appears in `show hardware`
|
||||
1. **Verify signal strength**: Check that the target network shows
|
||||
"good" or "excellent" signal in scan results
|
||||
2. **Check credentials**: Verify the preshared key in the keystore
|
||||
matches the network password
|
||||
3. **Review logs**: Check system logs with `show log` for Wi-Fi related
|
||||
errors
|
||||
4. **Regulatory compliance**: Ensure the country-code on the radio
|
||||
matches your location
|
||||
5. **Hardware detection**: Confirm the WiFi radio appears in `show
|
||||
hardware`
|
||||
|
||||
If issues persist, check the system log for specific error messages that can help identify the root cause.
|
||||
If issues persist, check the system log for specific error messages that
|
||||
can help identify the root cause.
|
||||
|
||||
[1]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
||||
|
||||
+10
-2
@@ -28,12 +28,20 @@ nav:
|
||||
- Upgrading: cli/upgrade.md
|
||||
- Docker Containers: container.md
|
||||
- Networking:
|
||||
- Network Configuration: networking.md
|
||||
- Overview: networking.md
|
||||
- Common Settings: iface.md
|
||||
- Bridging: bridging.md
|
||||
- Link Aggregation: lag.md
|
||||
- Ethernet Interfaces: ethernet.md
|
||||
- IP Addressing: ip.md
|
||||
- Routing: routing.md
|
||||
- Firewall Configuration: firewall.md
|
||||
- Quality of Service: qos.md
|
||||
- RMON Counters: eth-counters.md
|
||||
- Tunneling (L2/L3): tunnels.md
|
||||
- VPN Tunnels: vpn.md
|
||||
- VPN Tunnels:
|
||||
- Overview: vpn.md
|
||||
- WireGuard: vpn-wireguard.md
|
||||
- Wireless LAN (WiFi): wifi.md
|
||||
- Services:
|
||||
- Device Discovery: discovery.md
|
||||
|
||||
@@ -18,6 +18,7 @@ config BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK
|
||||
bool "Realtek USB WiFi Dongles"
|
||||
depends on BR2_PACKAGE_FEATURE_WIFI
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89
|
||||
help
|
||||
|
||||
@@ -15,8 +15,9 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS
|
||||
|
||||
$(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK)),
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_WLAN_VENDOR_REALTEK)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTL8XXXU)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTL8XXXU_UNTESTED)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8703B)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8723CS)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8723D)
|
||||
@@ -35,6 +36,14 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8822C)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8822CU)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88_8822CE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8851BE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8852AE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8852BE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8852BTE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8852CE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_8922AE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW89_DEBUGMSG)
|
||||
)
|
||||
endef
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
|
||||
sha256 4c1b6b461a805f0cf80f797f85415e0663ee371df6495641bb494bfb18829fe8 klish-7c5f1c4045d9a868dea547bd7ef0143bff5a84d7-git4.tar.gz
|
||||
sha256 39a73fdaa7e41001e804e2bbdebdc885da79d540f0246777e8fd1c0dd9fc9475 klish-1c31f50ab775d467fa18f2e0a798006949536a2a-git4.tar.gz
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
KLISH_VERSION = 7c5f1c4045d9a868dea547bd7ef0143bff5a84d7
|
||||
KLISH_VERSION = 1c31f50ab775d467fa18f2e0a798006949536a2a
|
||||
KLISH_SITE = https://github.com/kernelkit/klish.git
|
||||
#KLISH_VERSION = tags/3.0.0
|
||||
#KLISH_SITE = https://src.libcode.org/pkun/klish.git
|
||||
|
||||
+1
-1
@@ -579,8 +579,8 @@ static int resolve_dst(const char **dst, const struct infix_ds **ds, char **path
|
||||
|
||||
static int copy(const char *src, const char *dst)
|
||||
{
|
||||
char *srcpath = NULL, *dstpath = NULL;
|
||||
const struct infix_ds *srcds = NULL, *dstds = NULL;
|
||||
char *srcpath = NULL, *dstpath = NULL;
|
||||
bool rmsrc = false;
|
||||
mode_t oldmask;
|
||||
int err = 1;
|
||||
|
||||
@@ -531,8 +531,9 @@ def system(args: List[str]) -> None:
|
||||
name = component.get("name", "")
|
||||
value_type = sensor_data.get("value-type")
|
||||
|
||||
# Only capture CPU temperature (ignore phy, sfp, etc.)
|
||||
if value_type == "celsius" and name == "cpu" and cpu_temp is None:
|
||||
# Only capture CPU/SoC temperature (ignore phy, sfp, etc.)
|
||||
# Different platforms use different names: cpu, soc, core, etc.
|
||||
if value_type == "celsius" and name in ("cpu", "soc", "core") and cpu_temp is None:
|
||||
temp_millidegrees = sensor_data.get("value", 0)
|
||||
cpu_temp = temp_millidegrees / 1000.0
|
||||
|
||||
|
||||
@@ -354,6 +354,10 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ietf-hardware */
|
||||
if ((rc = hardware_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-interfaces */
|
||||
if ((rc = interfaces_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
@@ -392,10 +396,6 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
|
||||
goto free_diff;
|
||||
#endif
|
||||
|
||||
/* ietf-hardware */
|
||||
if ((rc = hardware_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-routing */
|
||||
if ((rc = routing_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
+43
-37
@@ -1,13 +1,13 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
#include <fnmatch.h>
|
||||
#include <ftw.h>
|
||||
#include <jansson.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <srx/common.h>
|
||||
#include <srx/lyx.h>
|
||||
#include <srx/srx_val.h>
|
||||
#include <jansson.h>
|
||||
#include <ftw.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "interfaces.h"
|
||||
@@ -17,10 +17,10 @@
|
||||
#define HOSTAPD_CONF "/etc/hostapd-%s.conf"
|
||||
#define HOSTAPD_CONF_NEXT HOSTAPD_CONF"+"
|
||||
|
||||
static int dir_cb(const char *fpath, const struct stat *sb,
|
||||
int typeflag, struct FTW *ftwbuf)
|
||||
static int dir_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
|
||||
{
|
||||
char *filename;
|
||||
const char *filename;
|
||||
|
||||
if (typeflag == FTW_DP)
|
||||
return 0;
|
||||
|
||||
@@ -31,59 +31,55 @@ static int dir_cb(const char *fpath, const struct stat *sb,
|
||||
return FTW_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool usb_authorize(struct json_t *root, const char *name, int enabled)
|
||||
{
|
||||
json_t *usb_port, *usb_ports;
|
||||
json_t *port, *ports;
|
||||
int index;
|
||||
|
||||
usb_ports = json_object_get(root, "usb-ports");
|
||||
if (!usb_ports) /* No Infix controlled USB ports is ok */
|
||||
ports = json_object_get(root, "usb-ports");
|
||||
if (!ports)
|
||||
return 0;
|
||||
|
||||
json_array_foreach(usb_ports, index, usb_port) {
|
||||
struct json_t *jname;
|
||||
json_array_foreach(ports, index, port) {
|
||||
struct json_t *obj;
|
||||
|
||||
jname = json_object_get(usb_port, "name");
|
||||
if (!jname || !json_is_string(jname)) {
|
||||
obj = json_object_get(port, "name");
|
||||
if (!obj || !json_is_string(obj)) {
|
||||
ERROR("Did not find USB hardware port (name) for %s", name);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(name, json_string_value(jname))) {
|
||||
struct json_t *jpath = json_object_get(usb_port, "path");
|
||||
char authorized_default_path[PATH_MAX];
|
||||
|
||||
if (!strcmp(name, json_string_value(obj))) {
|
||||
char apath[PATH_MAX];
|
||||
const char *path;
|
||||
|
||||
if (!jpath || !json_is_string(jpath)) {
|
||||
obj = json_object_get(port, "path");
|
||||
if (!obj || !json_is_string(obj)) {
|
||||
ERROR("Did not find USB hardware port (path) for %s", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Path now points to USB device directory, not the attribute file */
|
||||
path = json_string_value(jpath);
|
||||
snprintf(authorized_default_path, sizeof(authorized_default_path),
|
||||
"%s/authorized_default", path);
|
||||
path = json_string_value(obj);
|
||||
snprintf(apath, sizeof(apath), "%s/authorized_default", path);
|
||||
|
||||
if (!enabled) {
|
||||
if (fexist(authorized_default_path)) {
|
||||
if (writedf(0, "w", "%s", authorized_default_path)) {
|
||||
ERROR("Failed to unauthorize %s", authorized_default_path);
|
||||
if (fexist(apath)) {
|
||||
if (writedf(0, "w", "%s", apath)) {
|
||||
ERROR("Failed to unauthorize %s", apath);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char *rpath;
|
||||
|
||||
rpath = realpath(path, NULL);
|
||||
if (rpath) {
|
||||
nftw(rpath, dir_cb, 0, FTW_DEPTH | FTW_PHYS);
|
||||
free(rpath);
|
||||
}
|
||||
if (realpath(path, apath))
|
||||
nftw(apath, dir_cb, 20, FTW_DEPTH | FTW_PHYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -145,9 +141,14 @@ static int hardware_cand_infer_class(json_t *root, sr_session_ctx_t *session, co
|
||||
inferred.data.string_val = "infix-hardware:usb";
|
||||
err = srx_set_item(session, &inferred, 0,
|
||||
"%s/class", xpath);
|
||||
break;
|
||||
goto out_free_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fnmatch("radio+([0-9])", name, FNM_EXTMATCH)) {
|
||||
inferred.data.string_val = "infix-hardware:wifi";
|
||||
err = srx_set_item(session, &inferred, 0, "%s/class", xpath);
|
||||
}
|
||||
out_free_name:
|
||||
free(name);
|
||||
out_free_xpath:
|
||||
@@ -457,12 +458,14 @@ static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
char hostapd_conf[256];
|
||||
char **ap_list = NULL;
|
||||
FILE *hostapd = NULL;
|
||||
int ap_count = 0;
|
||||
int rc = SR_ERR_OK;
|
||||
int ap_count = 0;
|
||||
mode_t oldmask;
|
||||
int i;
|
||||
|
||||
wifi_find_radio_aps(cifs, radio_name, &ap_list, &ap_count);
|
||||
oldmask = umask(0077);
|
||||
|
||||
wifi_find_radio_aps(cifs, radio_name, &ap_list, &ap_count);
|
||||
if (ap_count == 0) {
|
||||
DEBUG("No APs found on radio %s", radio_name);
|
||||
goto cleanup;
|
||||
@@ -537,6 +540,8 @@ static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
fclose(hostapd);
|
||||
|
||||
cleanup:
|
||||
umask(oldmask);
|
||||
|
||||
for (i = 0; i < ap_count; i++)
|
||||
free(ap_list[i]);
|
||||
free(ap_list);
|
||||
@@ -579,7 +584,8 @@ static int hardware_cand(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
return err;
|
||||
}
|
||||
|
||||
int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff,
|
||||
sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *difs = NULL, *dif = NULL;
|
||||
int rc = SR_ERR_OK;
|
||||
@@ -618,7 +624,7 @@ int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
|
||||
}
|
||||
continue;
|
||||
}
|
||||
state = lydx_get_child(dif, "state");
|
||||
state = lydx_get_child(cif, "state");
|
||||
admin_state = lydx_get_cattr(state, "admin-state");
|
||||
if (usb_authorize(confd->root, name, !strcmp(admin_state, "unlocked"))) {
|
||||
rc = SR_ERR_INTERNAL;
|
||||
|
||||
+52
-5
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
#include <srx/lyx.h>
|
||||
#include <srx/srx_val.h>
|
||||
|
||||
#include "interfaces.h"
|
||||
|
||||
@@ -60,6 +61,7 @@ static int wifi_gen_station(struct lyd_node *cif)
|
||||
char *security_str = NULL;
|
||||
const char *country;
|
||||
int rc = SR_ERR_OK;
|
||||
mode_t oldmask;
|
||||
|
||||
ifname = lydx_get_cattr(cif, "name");
|
||||
wifi = lydx_get_child(cif, "wifi");
|
||||
@@ -94,6 +96,7 @@ static int wifi_gen_station(struct lyd_node *cif)
|
||||
secret = NULL;
|
||||
}
|
||||
|
||||
oldmask = umask(0077);
|
||||
wpa_supplicant = fopenf("w", WPA_SUPPLICANT_CONF, ifname);
|
||||
if (!wpa_supplicant) {
|
||||
rc = SR_ERR_INTERNAL;
|
||||
@@ -131,9 +134,30 @@ static int wifi_gen_station(struct lyd_node *cif)
|
||||
out:
|
||||
if (wpa_supplicant)
|
||||
fclose(wpa_supplicant);
|
||||
umask(oldmask);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get probe-timeout for a radio from sysrepo config.
|
||||
* Returns 0 if not set.
|
||||
*/
|
||||
static int wifi_get_probe_timeout(sr_session_ctx_t *session, const char *radio)
|
||||
{
|
||||
char *timeout_str;
|
||||
int timeout = 0;
|
||||
|
||||
timeout_str = srx_get_str(session,
|
||||
"/ietf-hardware:hardware/component[name='%s']/infix-hardware:wifi-radio/probe-timeout",
|
||||
radio);
|
||||
if (timeout_str) {
|
||||
timeout = atoi(timeout_str);
|
||||
free(timeout_str);
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add WiFi virtual interface using iw
|
||||
*/
|
||||
@@ -142,6 +166,7 @@ int wifi_add_iface(struct lyd_node *cif, struct dagger *net)
|
||||
const char *ifname, *radio;
|
||||
struct lyd_node *wifi;
|
||||
wifi_mode_t mode;
|
||||
int probe_timeout;
|
||||
FILE *iw;
|
||||
int rc = SR_ERR_OK;
|
||||
|
||||
@@ -166,11 +191,34 @@ int wifi_add_iface(struct lyd_node *cif, struct dagger *net)
|
||||
}
|
||||
|
||||
mode = wifi_get_mode(wifi);
|
||||
probe_timeout = wifi_get_probe_timeout(net->session, radio);
|
||||
|
||||
fprintf(iw, "# Generated by Infix confd - WiFi Interface Creation\n");
|
||||
fprintf(iw, "# Create %s interface %s on radio %s\n",
|
||||
mode == wifi_station ? "station" : "access point", ifname, radio);
|
||||
|
||||
/* Wait for PHY if probe-timeout is set (slow USB dongles) */
|
||||
if (probe_timeout > 0) {
|
||||
fprintf(iw, "\n# Wait for PHY (USB dongle may be slow to initialize)\n");
|
||||
fprintf(iw, "timeout=%d\n", probe_timeout);
|
||||
fprintf(iw, "while [ $timeout -gt 0 ]; do\n");
|
||||
fprintf(iw, " iw phy %s info >/dev/null 2>&1 && break\n", radio);
|
||||
fprintf(iw, " sleep 1\n");
|
||||
fprintf(iw, " timeout=$((timeout - 1))\n");
|
||||
fprintf(iw, "done\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* If radio doesn't exist, create a dummy interface as placeholder. This allows all
|
||||
* downstream config (IP addresses, etc.) to work. User must reboot when radio becomes
|
||||
* available.
|
||||
*/
|
||||
fprintf(iw, "if ! iw phy %s info >/dev/null 2>&1; then\n", radio);
|
||||
fprintf(iw, " logger -t wifi \"%s: radio %s not available, creating dummy placeholder\"\n", ifname, radio);
|
||||
fprintf(iw, " ip link add %s type dummy\n", ifname);
|
||||
fprintf(iw, " exit 0\n");
|
||||
fprintf(iw, "fi\n\n");
|
||||
|
||||
switch(mode) {
|
||||
case wifi_station:
|
||||
fprintf(iw, "iw phy %s interface add %s type managed\n", radio, ifname);
|
||||
@@ -209,16 +257,15 @@ int wifi_del_iface(struct lyd_node *dif, struct dagger *net)
|
||||
}
|
||||
|
||||
fprintf(iw, "# Generated by Infix confd - WiFi Interface Deletion\n");
|
||||
fprintf(iw, "ip link set %s down\n", ifname); /* Required to change modes. */
|
||||
fprintf(iw, "iw dev %s disconnect\n", ifname);
|
||||
fprintf(iw, "iw dev %s del\n", ifname);
|
||||
fprintf(iw, "ip link set %s down\n", ifname);
|
||||
fprintf(iw, "iw dev %s disconnect 2>/dev/null\n", ifname);
|
||||
fprintf(iw, "iw dev %s del 2>/dev/null || ip link del %s 2>/dev/null || true\n", ifname, ifname);
|
||||
|
||||
wifi = lydx_get_child(dif, "wifi");
|
||||
if (wifi && wifi_get_mode(wifi) == wifi_ap) { /* if not station or scanning mode */
|
||||
if (wifi && wifi_get_mode(wifi) != wifi_ap) {
|
||||
erasef(WPA_SUPPLICANT_CONF, ifname);
|
||||
fprintf(iw, "initctl -bfq disable wifi@%s\n", ifname);
|
||||
}
|
||||
|
||||
fclose(iw);
|
||||
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -599,14 +599,16 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif,
|
||||
static sr_error_t netdag_gen_iface_timeout(struct dagger *net, const char *ifname, const char *iftype)
|
||||
{
|
||||
if (!strcmp(iftype, "infix-if-type:ethernet")) {
|
||||
FILE *wait = dagger_fopen_net_init(net, ifname, NETDAG_INIT_TIMEOUT, "wait-interface.sh");
|
||||
if (!wait) {
|
||||
FILE *wait;
|
||||
|
||||
wait = dagger_fopen_net_init(net, ifname, NETDAG_INIT_TIMEOUT, "wait-interface.sh");
|
||||
if (!wait)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
fprintf(wait, "/usr/libexec/confd/wait-interface %s %d\n", ifname, IFACE_PROBE_TIMEOUT);
|
||||
fclose(wait);
|
||||
}
|
||||
}
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ MODULES=(
|
||||
"infix-syslog@2025-11-17.yang"
|
||||
"iana-hardware@2018-03-13.yang"
|
||||
"ietf-hardware@2018-03-13.yang -e hardware-state -e hardware-sensor"
|
||||
"infix-hardware@2025-12-04.yang"
|
||||
"infix-hardware@2026-01-19.yang"
|
||||
"ieee802-dot1q-types@2022-10-29.yang"
|
||||
"infix-ip@2025-11-02.yang"
|
||||
"infix-if-type@2026-01-07.yang"
|
||||
|
||||
@@ -21,6 +21,10 @@ module infix-hardware {
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "Vital Product Data augmentation of ieee-hardware and deviations.";
|
||||
|
||||
revision 2026-01-19 {
|
||||
description "Add probe-timeout for slow USB WiFi dongles.";
|
||||
reference "internal";
|
||||
}
|
||||
revision 2025-12-04 {
|
||||
description "Add WiFi radio survey container for channel utilization data.";
|
||||
reference "internal";
|
||||
@@ -262,6 +266,21 @@ module infix-hardware {
|
||||
congestion in most environments.";
|
||||
}
|
||||
|
||||
leaf probe-timeout {
|
||||
type uint8;
|
||||
description
|
||||
"Seconds to wait for PHY detection at boot.
|
||||
|
||||
USB WiFi dongles may be slow to initialize due to firmware
|
||||
loading. Set this to a non-zero value (e.g., 30) to wait
|
||||
for the radio PHY to appear before creating WiFi interfaces.
|
||||
|
||||
If the PHY is not detected within the timeout, interface
|
||||
creation is skipped gracefully instead of failing.
|
||||
|
||||
Value 0 (default) disables waiting.";
|
||||
}
|
||||
|
||||
/*
|
||||
* Operational state
|
||||
*/
|
||||
|
||||
@@ -77,17 +77,22 @@ module infix-if-type {
|
||||
reference "RFC 3635";
|
||||
}
|
||||
|
||||
|
||||
identity gre {
|
||||
base infix-interface-type;
|
||||
description "GRE tunnel interface.";
|
||||
}
|
||||
identity gretap {
|
||||
base infix-interface-type;
|
||||
description "GRETAP (Ethernet over GRE) tunnel interface.";
|
||||
}
|
||||
identity vxlan {
|
||||
base infix-interface-type;
|
||||
description "Virtual eXtensible LAN tunnel interface.";
|
||||
}
|
||||
identity wireguard {
|
||||
base infix-interface-type;
|
||||
description "WireGuard VPN tunnel interface.";
|
||||
}
|
||||
identity lag {
|
||||
base infix-interface-type;
|
||||
|
||||
@@ -218,6 +218,36 @@ submodule infix-if-wifi {
|
||||
- Below -80 dBm: Very weak";
|
||||
}
|
||||
|
||||
leaf rx-speed {
|
||||
config false;
|
||||
type uint32;
|
||||
units "100 kbps";
|
||||
description
|
||||
"Last received data rate from the access point in 100 kbps.
|
||||
|
||||
Only available when connected.
|
||||
|
||||
Examples:
|
||||
- 10 = 1 Mbps
|
||||
- 65 = 6.5 Mbps
|
||||
- 866 = 86.6 Mbps";
|
||||
}
|
||||
|
||||
leaf tx-speed {
|
||||
config false;
|
||||
type uint32;
|
||||
units "100 kbps";
|
||||
description
|
||||
"Last transmitted data rate to the access point in 100 kbps.
|
||||
|
||||
Only available when connected.
|
||||
|
||||
Examples:
|
||||
- 10 = 1 Mbps
|
||||
- 65 = 6.5 Mbps
|
||||
- 866 = 86.6 Mbps";
|
||||
}
|
||||
|
||||
list scan-results {
|
||||
config false;
|
||||
key ssid;
|
||||
@@ -421,26 +451,26 @@ submodule infix-if-wifi {
|
||||
|
||||
leaf rx-speed {
|
||||
type uint32;
|
||||
units "100 kbit/s";
|
||||
units "100 kbps";
|
||||
description
|
||||
"Last received data rate from this client in 100 kbit/s.
|
||||
"Last received data rate from this client in 100 kbps.
|
||||
|
||||
Examples:
|
||||
- 10 = 1 Mbit/s
|
||||
- 65 = 6.5 Mbit/s
|
||||
- 866 = 86.6 Mbit/s";
|
||||
- 10 = 1 Mbps
|
||||
- 65 = 6.5 Mbps
|
||||
- 866 = 86.6 Mbps";
|
||||
}
|
||||
|
||||
leaf tx-speed {
|
||||
type uint32;
|
||||
units "100 kbit/s";
|
||||
units "100 kbps";
|
||||
description
|
||||
"Last transmitted data rate to this client in 100 kbit/s.
|
||||
"Last transmitted data rate to this client in 100 kbps.
|
||||
|
||||
Examples:
|
||||
- 10 = 1 Mbit/s
|
||||
- 65 = 6.5 Mbit/s
|
||||
- 866 = 86.6 Mbit/s";
|
||||
- 10 = 1 Mbps
|
||||
- 65 = 6.5 Mbps
|
||||
- 866 = 86.6 Mbps";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ class PadRoute:
|
||||
|
||||
|
||||
class PadSoftware:
|
||||
name = 10
|
||||
name = 11
|
||||
date = 25
|
||||
hash = 64
|
||||
state = 10
|
||||
@@ -170,14 +170,6 @@ class PadSensor:
|
||||
return cls.name + cls.value + cls.status
|
||||
|
||||
|
||||
class PadNtpSource:
|
||||
address = 16
|
||||
mode = 13
|
||||
state = 13
|
||||
stratum = 11
|
||||
poll = 14
|
||||
|
||||
|
||||
class PadLldp:
|
||||
interface = 16
|
||||
rem_idx = 10
|
||||
@@ -353,8 +345,11 @@ class SimpleTable:
|
||||
# Add separator " " only between columns, not after the last one
|
||||
separator = "" if is_last else " "
|
||||
|
||||
# Don't pad the last column to avoid trailing spaces
|
||||
# Don't add trailing spaces to the last column
|
||||
if is_last:
|
||||
if column.align == 'right':
|
||||
padding = width - visible_len
|
||||
return ' ' * max(0, padding) + value_str
|
||||
return value_str
|
||||
elif column.align == 'right':
|
||||
padding = width - visible_len
|
||||
@@ -1238,22 +1233,26 @@ class Iface:
|
||||
print(row)
|
||||
|
||||
def pr_wifi_ssids(self):
|
||||
print("\nAVAILABLE NETWORKS:")
|
||||
width = 70
|
||||
Decore.title("Available Networks", width)
|
||||
ssid_table = SimpleTable([
|
||||
Column('SSID'),
|
||||
Column('SSID', flexible=True),
|
||||
Column('BSSID'),
|
||||
Column('SECURITY'),
|
||||
Column('SIGNAL'),
|
||||
Column('CHANNEL')
|
||||
])
|
||||
Column('CHANNEL', 'right')
|
||||
], min_width=width)
|
||||
|
||||
station = self.wifi.get("station", {})
|
||||
results = station.get("scan-results", {})
|
||||
for result in results:
|
||||
ssid = result.get('ssid', 'Hidden')
|
||||
bssid = result.get("bssid", "unknown")
|
||||
encstr = ", ".join(result.get("encryption", ["Unknown"]))
|
||||
status = rssi_to_status(result.get("rssi", -100))
|
||||
channel = result.get("channel", "?")
|
||||
|
||||
ssid_table.row(result.get('ssid', 'Hidden'), encstr, status, channel)
|
||||
ssid_table.row(ssid, bssid, encstr, status, channel)
|
||||
ssid_table.print()
|
||||
|
||||
def pr_wifi_stations(self):
|
||||
@@ -1295,7 +1294,7 @@ class Iface:
|
||||
rx_bytes = station.get("rx-bytes", 0)
|
||||
tx_bytes = station.get("tx-bytes", 0)
|
||||
|
||||
# Speed in 100 kbit/s units, convert to Mbps for display
|
||||
# Speed in 100 kbps units, convert to Mbps for display
|
||||
rx_speed = station.get("rx-speed", 0)
|
||||
tx_speed = station.get("tx-speed", 0)
|
||||
rx_speed_str = f"{rx_speed / 10:.1f}" if rx_speed else "-"
|
||||
@@ -1640,6 +1639,12 @@ class Iface:
|
||||
if rssi is not None:
|
||||
signal_status = rssi_to_status(rssi)
|
||||
print(f"{'signal':<{20}}: {rssi} dBm ({signal_status})")
|
||||
rx_speed = station.get('rx-speed')
|
||||
tx_speed = station.get('tx-speed')
|
||||
if rx_speed is not None:
|
||||
print(f"{'rx bitrate':<{20}}: {rx_speed / 10:.1f} Mbps")
|
||||
if tx_speed is not None:
|
||||
print(f"{'tx bitrate':<{20}}: {tx_speed / 10:.1f} Mbps")
|
||||
if "scan-results" in station:
|
||||
self.pr_wifi_ssids()
|
||||
|
||||
@@ -2050,11 +2055,10 @@ def show_software(json, name):
|
||||
if slot:
|
||||
slot.detail()
|
||||
else:
|
||||
print(Decore.invert("BOOT ORDER"))
|
||||
order=""
|
||||
order = ""
|
||||
for boot in boot_order:
|
||||
order+=f"{boot.strip()} "
|
||||
print(order)
|
||||
order += f"{boot.strip()} "
|
||||
print(f"Boot order : {order}")
|
||||
print("")
|
||||
|
||||
hdr = (f"{'NAME':<{PadSoftware.name}}"
|
||||
@@ -2569,12 +2573,14 @@ def show_ntp(json, address=None):
|
||||
show_ntp_source_detail_single(sources[0], is_server)
|
||||
return
|
||||
print()
|
||||
hdr = (f"{'ADDRESS':<{PadNtpSource.address}}"
|
||||
f"{'MODE':<{PadNtpSource.mode}}"
|
||||
f"{'STATE':<{PadNtpSource.state}}"
|
||||
f"{'STRATUM':>{PadNtpSource.stratum}}"
|
||||
f"{'POLL':>{PadNtpSource.poll}}")
|
||||
print(Decore.invert(hdr))
|
||||
table = SimpleTable([
|
||||
Column('ADDRESS'),
|
||||
Column('MODE'),
|
||||
Column('STATE'),
|
||||
Column('STRATUM', 'right'),
|
||||
Column('POLL', 'right')
|
||||
])
|
||||
|
||||
for source in sources:
|
||||
# Extract fields - handle both association and ietf-system format
|
||||
address = source.get('address', 'N/A')
|
||||
@@ -2598,12 +2604,9 @@ def show_ntp(json, address=None):
|
||||
poll = source.get('poll', 0)
|
||||
poll_str = f"{2**poll}s" if poll else "-"
|
||||
|
||||
row = f"{address:<{PadNtpSource.address}}"
|
||||
row += f"{mode_str:<{PadNtpSource.mode}}"
|
||||
row += f"{state_str:<{PadNtpSource.state}}"
|
||||
row += f"{stratum:>{PadNtpSource.stratum}}"
|
||||
row += f"{poll_str:>{PadNtpSource.poll}}"
|
||||
print(row)
|
||||
table.row(address, mode_str, state_str, stratum, poll_str)
|
||||
|
||||
table.print()
|
||||
|
||||
|
||||
def show_ntp_tracking(json):
|
||||
@@ -2821,21 +2824,18 @@ def show_ntp_source(json, address=None):
|
||||
show_ntp_association_detail(associations[0])
|
||||
return
|
||||
|
||||
# First pass: determine maximum address width needed
|
||||
max_addr_len = len("Name/IP address") # Minimum width to match chronyc header
|
||||
for assoc in associations:
|
||||
addr_len = len(assoc.get("address", ""))
|
||||
if addr_len > max_addr_len:
|
||||
max_addr_len = addr_len
|
||||
# Table with chronyc-style columns
|
||||
table = SimpleTable([
|
||||
Column('MS'),
|
||||
Column('Name/IP address', flexible=True),
|
||||
Column('Stratum', 'right'),
|
||||
Column('Poll', 'right'),
|
||||
Column('Reach', 'right'),
|
||||
Column('LastRx', 'right'),
|
||||
Column('Last sample', 'right')
|
||||
])
|
||||
|
||||
# Cap at reasonable maximum (IPv6 can be up to 39 chars uncompressed)
|
||||
max_addr_len = min(max_addr_len, 39)
|
||||
|
||||
# Table header - similar to chronyc sources
|
||||
hdr = f"{'MS':<3}{f'Name/IP address':<{max_addr_len}} {'Stratum':>7} {'Poll':>4} {'Reach':>5} {'LastRx':>6} {'Last sample':>24}"
|
||||
print(Decore.invert(hdr))
|
||||
|
||||
# Display each association
|
||||
# Build rows
|
||||
for assoc in associations:
|
||||
# State indicator: * = prefer (sync source), + = candidate
|
||||
prefer = assoc.get("prefer", False)
|
||||
@@ -2852,6 +2852,7 @@ def show_ntp_source(json, address=None):
|
||||
elif local_mode == "broadcast-client":
|
||||
mode_indicator = "#"
|
||||
|
||||
ms_col = f"{mode_indicator}{state}"
|
||||
address = assoc.get("address", "N/A")
|
||||
stratum = assoc.get("stratum", 0)
|
||||
|
||||
@@ -2896,14 +2897,13 @@ def show_ntp_source(json, address=None):
|
||||
|
||||
# Last sample column combines offset and delay like chronyc
|
||||
if offset_str != "-":
|
||||
last_sample = f"{offset_str:>12} {delay_str}"
|
||||
last_sample = f"{offset_str} {delay_str}"
|
||||
else:
|
||||
last_sample = "-"
|
||||
|
||||
# Format row
|
||||
ms_col = f"{mode_indicator}{state}"
|
||||
row = f"{ms_col:<3}{address:<{max_addr_len}} {stratum:>7} {poll_str:>4} {reach_str:>5} {now_str:>6} {last_sample:>24}"
|
||||
print(row)
|
||||
table.row(ms_col, address, stratum, poll_str, reach_str, now_str, last_sample)
|
||||
|
||||
table.print()
|
||||
|
||||
|
||||
def _analyze_group_permissions(nacm):
|
||||
|
||||
@@ -70,6 +70,10 @@ def wifi_station(ifname):
|
||||
station_data['ssid'] = link['ssid']
|
||||
if link.get('rssi') is not None:
|
||||
station_data['rssi'] = link['rssi']
|
||||
if link.get('rx-speed') is not None:
|
||||
station_data['rx-speed'] = link['rx-speed']
|
||||
if link.get('tx-speed') is not None:
|
||||
station_data['tx-speed'] = link['tx-speed']
|
||||
|
||||
# Get scan results from wpa_supplicant (better scan support)
|
||||
try:
|
||||
|
||||
+1
-3
@@ -96,7 +96,6 @@ static int ly_add_yanger_data(const struct ly_ctx *ctx, struct lyd_node **parent
|
||||
if (err) {
|
||||
ERROR("Error, running yanger");
|
||||
fclose(stream);
|
||||
close(fd);
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
@@ -105,7 +104,6 @@ static int ly_add_yanger_data(const struct ly_ctx *ctx, struct lyd_node **parent
|
||||
if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
|
||||
ERROR("Error, unable reset stream (seek)");
|
||||
fclose(stream);
|
||||
close(fd);
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
@@ -114,7 +112,7 @@ static int ly_add_yanger_data(const struct ly_ctx *ctx, struct lyd_node **parent
|
||||
ERROR("Error, parsing yanger data (%d)", err);
|
||||
|
||||
fclose(stream);
|
||||
close(fd);
|
||||
/* Note: fclose() already closes the underlying fd from fdopen() */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Mode : Client
|
||||
|
||||
[7mADDRESS MODE STATE STRATUM POLL[0m
|
||||
192.168.1.1 server candidate 1 64s
|
||||
192.168.2.1 server candidate 1 64s
|
||||
192.168.3.1 server selected 1 64s
|
||||
[7mADDRESS MODE STATE STRATUM POLL[0m
|
||||
192.168.1.1 server candidate 1 64s
|
||||
192.168.2.1 server candidate 1 64s
|
||||
192.168.3.1 server selected 1 64s
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[7mBOOT ORDER[0m
|
||||
primary secondary net
|
||||
Boot order : primary secondary net
|
||||
|
||||
[7mNAME STATE VERSION DATE [0m
|
||||
primary booted 94cd526 2025-01-15T10:00:56Z
|
||||
secondary inactive 94cd526 2025-01-15T10:00:56Z
|
||||
[7mNAME STATE VERSION DATE [0m
|
||||
primary booted 94cd526 2025-01-15T10:00:56Z
|
||||
secondary inactive 94cd526 2025-01-15T10:00:56Z
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Extract the latest release entry from ChangeLog.md and unwrap lines
|
||||
# for GitHub's web view (lets the browser handle line wrapping).
|
||||
#
|
||||
# Usage: cat doc/ChangeLog.md | extract-changelog.sh > release.md
|
||||
#
|
||||
# Output goes to stdout.
|
||||
#
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
# Extract section between first two --- lines, skip trailing blank lines
|
||||
head -n -1 < <(awk '/^-----*$/{if (x == 1) exit; x=1;next}x') |
|
||||
|
||||
# Unwrap lines for GitHub's web view (browser does wrapping)
|
||||
# Preserves: blank lines, list items, headings, blockquotes, indented blocks
|
||||
# Joins: soft-wrapped paragraph/list continuations
|
||||
awk '
|
||||
{
|
||||
if (/^$/) {
|
||||
if (buf) print buf
|
||||
buf = ""
|
||||
print
|
||||
blank = 1
|
||||
next
|
||||
}
|
||||
if (/^ / && buf) {
|
||||
# Indented continuation - strip indent and join
|
||||
sub(/^ /, " ")
|
||||
buf = buf $0
|
||||
} else if (/^[-*>#\[|]/ || /^[0-9]+\./ || blank || !buf || brk) {
|
||||
# New block: special char, after blank, first line, or after md break
|
||||
if (buf) print buf
|
||||
buf = $0
|
||||
} else {
|
||||
# Paragraph continuation - join with space
|
||||
buf = buf " " $0
|
||||
}
|
||||
blank = 0
|
||||
brk = / $/
|
||||
}
|
||||
END { if (buf) print buf }
|
||||
'
|
||||
|
||||
# Append tip for GNS3
|
||||
cat <<EOF
|
||||
|
||||
> [!TIP]
|
||||
> **Try Infix in GNS3!** Download the appliance from the [GNS3 Marketplace](https://gns3.com/marketplace/appliances/infix) to test Infix in a virtual network environment without hardware.
|
||||
EOF
|
||||
+4
-14
@@ -255,26 +255,16 @@ update_changelog() {
|
||||
fi
|
||||
|
||||
# Extract just the UNRELEASED section (from start until next version header)
|
||||
# Need to find the second [v occurrence (first is UNRELEASED itself, second is previous release)
|
||||
UNRELEASED_SECTION=$(awk '/^\[v[0-9]/ { count++; if (count == 2) exit } { print }' doc/ChangeLog.md)
|
||||
|
||||
# Check if there's already a kernel upgrade entry in the UNRELEASED section
|
||||
if echo "$UNRELEASED_SECTION" | grep -q "^- Upgrade Linux kernel to"; then
|
||||
# Update existing kernel upgrade line in UNRELEASED section only
|
||||
# Find a real release marker (not UNRELEASED), then replace before that
|
||||
awk -v new_version="$NEW_VERSION" '
|
||||
/^\[v[0-9]/ && !/UNRELEASED/ { found_version=1 }
|
||||
/^- Upgrade Linux kernel to/ && !found_version && !replaced {
|
||||
print "- Upgrade Linux kernel to " new_version " (LTS)"
|
||||
replaced=1
|
||||
next
|
||||
}
|
||||
{print}
|
||||
' doc/ChangeLog.md > doc/ChangeLog.md.tmp && mv doc/ChangeLog.md.tmp doc/ChangeLog.md
|
||||
# Match both plain and bold formats: "- Upgrade Linux" or "- Upgrade **Linux"
|
||||
if echo "$UNRELEASED_SECTION" | grep -qE "^- Upgrade (\*\*)?Linux kernel to"; then
|
||||
# Update existing kernel upgrade line using sed (first match only)
|
||||
sed -i '0,/^- Upgrade \(\*\*\)\?Linux kernel to .*/s//- Upgrade Linux kernel to '"$NEW_VERSION"' (LTS)/' doc/ChangeLog.md
|
||||
log_info "Updated existing kernel version entry to $NEW_VERSION"
|
||||
else
|
||||
# Add new kernel upgrade entry after first "### Changes"
|
||||
# Use awk to insert at the right place
|
||||
awk -v new_line="- Upgrade Linux kernel to $NEW_VERSION (LTS)" '
|
||||
/^### Changes/ && !done {
|
||||
print
|
||||
|
||||
Reference in New Issue
Block a user