Merge pull request #1086 from kernelkit/doc

Switch from GitHub to MkDocs Material for documentation

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Jon-Olov Vatn <jo@vatn.se>
This commit is contained in:
Joachim Wiberg
2025-07-30 15:04:17 +02:00
committed by GitHub
40 changed files with 2569 additions and 1947 deletions
-1
View File
@@ -24,7 +24,6 @@ on:
default: kernelkit/infix
type: string
workflow_call:
inputs:
target:
+73
View File
@@ -0,0 +1,73 @@
name: User Guide Generator
on:
push:
branches:
- doc
- main
tags:
- 'v*'
paths:
- 'doc/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
pull_request:
types: [opened, synchronize, reopened, labeled]
paths:
- 'doc/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
permissions:
contents: write
concurrency:
group: "docs-${{ github.ref }}"
cancel-in-progress: false
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pipx install mkdocs
pipx inject mkdocs mkdocs-material
pipx inject mkdocs pymdown-extensions
pipx inject mkdocs mkdocs-callouts
pipx inject mkdocs mike
pipx inject mkdocs mkdocs-to-pdf
# Workaround, if pipx inject fails to install symlink
ln -s "$(pipx environment -V PIPX_LOCAL_VENVS)/mkdocs/bin/mike" \
"$(pipx environment -V PIPX_BIN_DIR)/mike" || true
- name: Configure Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Deploy dev version
if: github.event_name == 'push' && (github.ref == 'refs/heads/doc' || github.ref == 'refs/heads/main')
run: |
mike deploy --push --update-aliases dev latest
mike set-default --push latest
- name: Deploy tagged version
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
run: |
TAG=${GITHUB_REF#refs/tags/v}
# Extract YEAR.MONTH from tag (e.g., v25.06.0-beta1 -> 25.06)
VERSION=$(echo $TAG | sed -E 's/^([0-9]+\.[0-9]+)(\.[0-9]+)?(-.*)?$/\1/')
echo "Deploying tag $TAG as docs version $VERSION"
mike deploy --push --update-aliases $VERSION latest
mike set-default --push latest
+14 -11
View File
@@ -8,12 +8,13 @@ different platforms, simplify long-term maintenance, and provide
made-easy management using NETCONF, RESTCONF[^2], or the built-in
command line interface (CLI) from a console or SSH login.
> Click the **▶ Example CLI Session** foldout below for an example, or
> head on over to the [Infix Documentation](doc/README.md) for more
> information on how to set up the system.
> [!TIP]
> _Curious how it works?_ Click the **▶ Example CLI Session** below to see
> it in action
> — or jump into the comprehensive [Infix Documentation][4] to learn even more.
Although primarily focused on switches and routers, the core values
may be appealing for other use-cases as well:
Geared for switches and routers — yet its core value fits plenty of
other use cases:
- Runs from a squashfs image on a read-only partition
- Single configuration file on a separate partition
@@ -95,6 +96,7 @@ The [following boards](board/aarch64/README.md) are fully supported:
- Marvell CN9130 CRB
- Marvell EspressoBIN
- Microchip SparX-5i PCB135 (eMMC)
- NXP i.MX8MP EVK
- Raspberry Pi 4B
- NanoPi R2S
@@ -123,16 +125,17 @@ Environments](doc/virtual.md).
[^1]: An immutable operating system is one with read-only file systems,
atomic updates, rollbacks, declarative configuration, and workload
isolation. All to improve reliability, scalability, and security.
For more information, see <https://ceur-ws.org/Vol-3386/paper9.pdf>
and <https://www.zdnet.com/article/what-is-immutable-linux-heres-why-youd-run-an-immutable-linux-distro/>.
For more information, see this [survey paper][5] and [article][6].
[^2]: Partial RESTCONF support, features like HTTP PATCH, OPTIONS, HEAD,
and copying between datastores are still missing.
[1]: https://buildroot.org/
[2]: https://www.sysrepo.org/
[1]: https://buildroot.org/ "Buildroot Homepage"
[2]: https://www.sysrepo.org/ "Sysrepo Homepage"
[3]: doc/cli/introduction.md
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest
[4]: https://kernelkit.org/infix/ "Infix User's Guide"
[5]: https://ceur-ws.org/Vol-3386/paper9.pdf "Immutable Operating Systems: A Survey"
[6]: https://www.zdnet.com/article/what-is-immutable-linux-heres-why-youd-run-an-immutable-linux-distro/ "Why you should run an immutable Linux distro"
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest "Latest build"
[License]: https://en.wikipedia.org/wiki/GPL_license
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
[GitHub]: https://github.com/kernelkit/infix/actions/workflows/build.yml/
+122 -51
View File
@@ -67,15 +67,15 @@ minimum. Two settings are available:
sources are considered can be configured. To select the active
source, use [RAUC][]:
`rauc status mark-active <slot>`
rauc status mark-active <slot>
Where `<slot>` is one of:
Where `<slot>` is one of:
| `<slot>` | Source |
|----------|---------------------------|
| rootfs.0 | Primary partition |
| rootfs.1 | Secondary partition |
| net.0 | Netboot (where supported) |
| `<slot>` | Source |
|------------|---------------------------|
| `rootfs.0` | Primary partition |
| `rootfs.1` | Secondary partition |
| `net.0` | Netboot (where supported) |
- **Debug**: By default, the kernel will only output errors to the
console during boot. Optionally, this can be altered such that all
@@ -107,7 +107,7 @@ and TFTP to transfer the image to the system's RAM.
Access to U-Boot's shell is disabled to prevent side-loading of
malicious software. To configure the active boot partition, refer to
the [Bootloader Interface](#bootloader-interface) section.
the [Bootloader Configuration](#configuration) section.
### GRUB
@@ -119,14 +119,84 @@ standard [System Upgrade](#system-upgrade) can be performed on
virtualized instances.
Access to the GRUB shell is not limited in any way, and the boot
partition can be selected interactively at boot using the arrow
keys. It is also possible to permanently configure the default
partition from Infix using the [Bootloader
Interface](#bootloader-interface).
partition can be selected interactively at boot using the arrow keys. It
is also possible to permanently configure the default partition from
Infix using the [Bootloader Configuration](#configuration).
## System Boot
After the system firmware (BIOS or and [boot loader](boot.md) start
Linux the following happens. The various failure modes, e.g., missing
password in VPD, are detailed later in this section.
![System boot flowchart](img/fail-secure.svg)
1. Before mounting `/cfg` and `/var` partitions, hosting read-writable
data like `startup-config` and container images, the system first
checks if a factory reset has been requested by the user, if so it
wipes the contents of these partitions
2. Linux boots with a device tree which is used for detecting generic
make and model of the device, e.g., number of interfaces. It may
also reference an EEPROM with [Vital Product Data](vpd.md). That is
where the base MAC address and per-device password hash is stored.
(Generic builds use the same MAC address and password)
3. On every boot the system's `factory-config` and `failure-config` are
generated from the YANG[^2] models of the current firmware version.
This ensures that a factory reset device can always boot, and that
there is a working fail safe, or rather *fail secure*, mode
4. On first power-on, and after a factory reset, the system does not
have a `startup-config`, in which case `factory-config` is copied
to `startup-config` -- if a per-product specific version exists it
is preferred over the generated one
5. Provided the integrity of the `startup-config` is OK, a system
service loads and activates the configuration
### Failure Modes
So, what happens if any of the steps above fail?
**VPD Fail**
The per-device password cannot be read, or is corrupt, so the system
`factory-config` and `failure-config` are not generated:
1. First boot, or after factory reset: `startup-config` cannot be
created or loaded, and `failure-config` cannot be loaded. The
system ends up in an unrecoverable state, i.e., **RMA[^3] Mode**
2. The system has booted (at least) once with correct VPD and password
and already has a `startup-config`. Provided the `startup-config`
is OK (see below), it is loaded and system boots successfully
In both cases, external factory reset modes/button will not help, and
in the second case will cause the device to fail on the next boot.
> The second case does not yet have any warning or event that can be
> detected from the outside. This is planned for a later release.
**Broken startup-config**
If loading `startup-config` fails for some reason, e.g., invalid JSON
syntax, failed validation against the system's YANG model, or a bug in
the system's `confd` service, the *Fail Secure Mode* is triggered and
`failure-config` is loaded (unless VPD Failure, see above).
> [!TIP]
> Please see the [Branding & Releases](branding.md) document for how to
> provide per-product `failure-config`, or `factory-config` to suit your
> product's preferences.
*Fail Secure Mode* is a fail-safe mode provided for debugging the
system. The default[^4] creates a setup of isolated interfaces with
communication only to the management CPU, SSH and console login using
the device's factory reset password, IP connectivity only using IPv6
link-local, and device discovery protocols: LLDP, mDNS-SD. The login
and shell prompt are set to `failure-c0-ff-ee`, the last three octets of
the device's base MAC address.
System Upgrade
==============
--------------
Much of the minutiae of software upgrades is delegated to [RAUC][],
which offers lots of benefits out-of-the-box:
@@ -147,8 +217,7 @@ To initiate a system upgrade from the shell[^1], run:
rauc install <file|url>
Where the file or URL points to a [RAUC Upgrade
Bundle](#rauc-upgrade-bundle).
Where the file or URL points to a [RAUC Upgrade Bundle](#rauc-upgrade-bundle).
This will upgrade the partition not currently running. After a
successful upgrade is completed, you can reboot your system, which
@@ -156,14 +225,11 @@ will then boot from the newly installed image. Since the partition
from which you were originally running is now inactive, running the
same upgrade command again will bring both partitions into sync.
[RAUC]: https://rauc.io
Image Formats
=============
-------------
SquashFS Image
--------------
### SquashFS Image
**Canonical Name**: `rootfs.squashfs`
@@ -174,10 +240,7 @@ this image, or is dependent on it, in one way or another.
On its own, it can be used as an [initrd][] to efficiently boot a
virtual instance of Infix.
[initrd]: https://docs.kernel.org/admin-guide/initrd.html
FIT Framed Squash Image
-----------------------
### FIT Framed Squash Image
**Canonical Name**: `rootfs.itb`
@@ -194,9 +257,9 @@ stored in the `/boot` directory of the filesystem.
On disk, this image is then stored broken up into its two components;
the _FIT header_ (`rootfs.itbh`) and the SquashFS image. The header
is stored on the [Auxiliary Data](#aux---auxiliary-data) partition of
is stored on the [Auxiliary Data](#aux-auxiliary-data) partition of
the [Disk Image](#disk-image), while the SquashFS image is stored in
one of the [Root Filesystem](#primarysecondary---root-filesystems)
one of the [Root Filesystem](#primarysecondary-root-filesystems)
partitions.
When the system boots, U-Boot will concatenate the two parts to
@@ -216,25 +279,22 @@ validate the SquashFS's contents. This path was chosen because:
In its full form, it can be used to netboot Infix, as it contains all
the information needed by U-Boot in a single file.
[FIT]: https://u-boot.readthedocs.io/en/latest/usage/fit.html
RAUC Upgrade Bundle
-------------------
### RAUC Upgrade Bundle
**Canonical Name**: `infix-${ARCH}.pkg`
Itself a SquashFS image, it contains the Infix [SquashFS
Image](#squashfs-image) along with the header of the [FIT Framed
Squash Image](#fit-framed-squash-image), and some supporting files to
let [RAUC][] know how install it on the target system.
Itself a SquashFS image, this bundle (sometimes referred to package)
contains the Infix [SquashFS Image](#squashfs-image) along with the
header of the [FIT Framed Squash Image](#fit-framed-squash-image), and
some supporting files to let [RAUC][] know how install it on the target
system.
When performing a [System Upgrade](#system-upgrade), this is the
format to use.
When performing a [System Upgrade](#system-upgrade), this is the format
to use.
Disk Image
----------
### Disk Image
**Canonical Name**: `disk.img`
@@ -264,7 +324,7 @@ scheme. Partitions marked with an asterisk are optional.
| |
'-----------'
### `boot` - Bootloader
#### `boot` - Bootloader
| Parameter | Value |
|-----------|-----------------------------------------|
@@ -278,8 +338,7 @@ in a separate storage device, e.g. a serial FLASH.
On x86_64, this partition holds the EFI system partition, containing
the GRUB bootloader.
### `aux` - Auxiliary Data
#### `aux` - Auxiliary Data
| Parameter | Value |
|-----------|-----------------|
@@ -293,10 +352,12 @@ bootloader configuration etc.
Typical layout when using U-Boot bootloader:
```
/
├ primary.itbh
├ secondary.itbh
└ uboot.env
```
During boot, an ITB header along with the corresponding root
filesystem image are concatenated in memory, by U-Boot, to form a
@@ -307,8 +368,7 @@ Note that the bootloader's primary environment is bundled in the
binary - `uboot.env` is only used to import a few settings that is
required to configure the boot order.
### `primary`/`secondary` - Root Filesystems
#### `primary`/`secondary` - Root Filesystems
| Parameter | Value |
|-----------|-------------------|
@@ -320,8 +380,7 @@ Holds the [SquashFS Image](#squashfs-image). Two copies exist so that
an incomplete upgrade does not brick the system, and to allow fast
rollbacks when upgrading to a new version.
### `cfg` - Configuration Data
#### `cfg` - Configuration Data
| Parameter | Value |
|-----------|-----------------|
@@ -332,8 +391,7 @@ rollbacks when upgrading to a new version.
Non-volatile storage of the system configuration and user data.
Concretely, user data is everything stored under `/root` and `/home`.
### `var` - Variable Data
#### `var` - Variable Data
| Parameter | Value |
|-----------|-----------------|
@@ -349,8 +407,21 @@ can funtion reasonably well without a persistent `/var`, loosing
If `var` is not available, Infix will still persist `/var/lib` using
`cfg` as the backing storage.
[^1]: See [Upgrading procedures and boot
order](system.md#upgrade-procedures-and-boot-order) for
information on upgrading via CLI.
[^1]: See [Upgrade & Boot Order](upgrade.md) for more information.
[^2]: YANG is a modeling language from IETF, replacing that used for
SNMP (MIB), used to describe the subsystems and properties of
the system.
[^3]: Return Merchandise Authorization (RMA), i.e., broken beyond repair
by end-user and eligible for return to manufacturer.
[^4]: Customer specific builds can define their own `failure-config`.
It may be the same as `factory-config`, with the hostname set to
`failure`, or a dedicated configuration that isolates interfaces, or
even disables ports, to ensure that the device does not cause any
security problems on the network. E.g., start forwarding traffic
between previously isolated VLANs.
[2]: netboot.md
[2]: netboot.md
[FIT]: https://u-boot.readthedocs.io/en/latest/usage/fit.html
[RAUC]: https://rauc.io
[initrd]: https://docs.kernel.org/admin-guide/initrd.html
+1 -1
View File
@@ -50,7 +50,7 @@ at boot. This also ensures the device can always be restored to a known
state after a factory reset, since the `factory-config` is guaranteed to
be compatible with the YANG models for the given software version. (For
more information on how the system boots, please see the section [Key
Concepts](introduction.md#key-concepts) in the Introduction document.)
Concepts](index.md#key-concepts) in the Introduction document.)
However, for custom builds of Infix it is possible to override this with
a single static `/etc/factory-config.cfg` (and failure-config) in your
+37 -15
View File
@@ -1,5 +1,4 @@
Configure Context
-----------------
# CLI Configure Context
Enter the configure context from admin-exec by typing `configure`
followed by Enter. Available commands, press `?` at the prompt:
@@ -41,14 +40,17 @@ admin@host:/config/interface/eth0/> up
admin@host:/config/>
```
> **Note:** the tree structure in the configure context is automatically
> generated from the system's supported NETCONF YANG models, which may
> vary between products. However, the `ietf-interfaces.yang` and
> `ietf-ip.yang` models, for instance, that provide basic networking
----
> **Note:** commands in configure context are automatically generated
> from the system's YANG models, hence different products likely have a
> different set of commands. However, both the `ietf-interfaces.yang`
> and `ietf-ip.yang` models, for instance, that provide the networking
> support are common to all systems.
----
### Set IP Address on an Interface
## Set IP Address on an Interface
```
admin@host:/config/> edit interface eth0
@@ -73,7 +75,7 @@ interfaces {
```
### Saving Changes
## Saving Changes
Apply the changes (from candidate to `running-config`):
@@ -104,11 +106,14 @@ admin@host:/> copy running-config startup-config
The `startup-config` can also be inspected with the `show` command to
verify the changes are saved.
> **Note:** most (all) commands need to be spelled out, no short forms
> are allowed at the moment. Use the `TAB` key to make this easier.
----
> **Note:** all commands need to be spelled out, no short forms are
> allowed in the CLI. Use the `TAB` key to make your life easier.
### Changing Hostname
----
## Changing Hostname
Settings like hostname are located in the `ietf-system.yang` model.
Here is how it can be set.
@@ -123,11 +128,14 @@ admin@example:/>
Notice how the hostname in the prompt does not change until the change
is committed.
----
> **Note:** critical services like syslog, mDNS, LLDP, and similar that
> advertise the hostname, are restarted when the hostname is changed.
----
### Changing Password
## Changing Password
User management, including passwords, is also a part of `ietf-system`.
@@ -149,12 +157,15 @@ the `do password encrypt` command. This launches the admin-exec command
to hash, and optionally salt, your password. This encrypted string can
then be used with `set password ...`.
----
> **Tip:** if you are having trouble thinking of a password, there is
> also `do password generate`, which generates random but readable
> strings using the UNIX command `pwgen`.
----
### SSH Authorized Key
## SSH Authorized Key
Logging in remotely with SSH is possible by adding a *public key* to a
user. Here we add the authorized key to the admin user, multiple keys
@@ -174,11 +185,15 @@ key-data AAAAB3NzaC1yc2EAAAADAQABAAABgQC8iBL42yeMBioFay7lty1C4ZDTHcHyo739gc91rTT
admin@host:/config/system/authentication/user/admin/authorized-key/example@host/> leave
```
----
> **Note:** the `ssh-keygen` program already base64 encodes the public
> key data, so there is no need to use the `text-editor` command, `set`
> does the job.
### Creating a VETH Pair
----
## Creating a VETH Pair
The following example creates a `veth0a <--> veth0b` virtual Ethernet
pair which is useful for connecting, e.g., a container to the physical
@@ -214,12 +229,15 @@ admin@host:/config/> leave
See the bridging example below for more.
----
> **Note:** in the CLI you do not have to create the `veth0b` interface.
> The system _infers_ this for you. When setting up a VETH pair using
> NETCONF, however, you must include the `veth0b` interface.
----
### Creating a Bridge
## Creating a Bridge
Building on the previous example, we now create a non-VLAN filtering
bridge (`br0`) that forwards any, normally link-local, LLDP traffic
@@ -273,6 +291,10 @@ the VETH pair from the previous example) are now bridged. Any traffic
ingressing one port will egress the other. Only reserved IEEE multicast
is filtered, except LLDP frames as shown above.
----
> **Note:** the bridge can be named anything, provided the interface
> name is not already taken. However, for any name outside the pattern
> `br[0-9]+`, you have to set the interface type manually to `bridge`.
----
+15 -9
View File
@@ -1,4 +1,4 @@
# Introduction
# CLI Introduction
The command line interface (CLI, see-ell-aye) implements a CISCO-like,
or Juniper Networks JunOS-like, CLI. It is the traditional way of
@@ -10,8 +10,7 @@ Nevertheless, when it comes to initial deployment and debugging, it
is very useful to know how to navigate and use the CLI. This very
short guide intends to help you with that.
## About
----
New users usually get the CLI as the default "shell" when logging in,
but the default `admin` user logs in to `bash`. To access the CLI,
@@ -35,9 +34,12 @@ admin@host-12-34-56:/> show # Try: Tab or ?
admin@host-12-34-56:/> # Try: Tab or ?
```
> **Tip:** Even on an empty command line you can tap the Tab or ? keys.
> See `help keybindings` for more tips!
----
> **Note:** even on an empty command line, you can tap the `Tab` or `?` keys.
> See [`help keybindings`](keybindings.md) for more tips!
----
## Key Concepts
@@ -129,10 +131,15 @@ In *configure context* the following commands are available:
| `do command` | Call admin-exec command: `do show log` |
| `commit` | |
### Example Session
> Remember to use the `TAB` and `?` keys to speed up your navigation.
> See `help keybindings` for more tips!
## Example Session
----
> Remember to use the `TAB` and `?` keys to speed up your navigation.
> See [`help keybindings`](keybindings.md) for more tips!
----
In this example we enter configure context to add an IPv4 address to
interface `eth0`, then we apply the changes using the `leave` command.
@@ -180,4 +187,3 @@ admin@host-12-34-56:/> copy startup-config running-config
```
Or restarting the device.
+6 -4
View File
@@ -1,4 +1,4 @@
# Keybindings
# CLI Keybindings
Writing CLI commands by hand is very tedious. To make things easier the
CLI has several keybindings, most significant first:
@@ -27,10 +27,12 @@ CLI has several keybindings, most significant first:
| Ctrl-n | Down arrow | History, next command |
| Ctrl-r | | History, reversed interactive search (i-search) |
> **Note:** the Meta key is called Alt on most modern keyboards. If you
> have neither, first tap the Esc key instead of holding down Alt/Meta.
## What is Meta?
## Examples
The Meta key is called Alt on most modern keyboards. If you have
neither, first tap the Esc key instead of holding down Alt/Meta.
## Usage
Complete a word. Start by typing a few characters, then tap the TAB key
on your keyboard:
+3 -3
View File
@@ -1,4 +1,4 @@
## Usage
# Network Calculator
```
netcalc <ADDRESS/LEN | NETWORK NETMASK> [split <1-32 | 64-128>]
@@ -12,8 +12,8 @@ information about the subnet. Both IPv4 and IPv6 is supported.
A subnet can be entered in two ways:
- `192.168.2.0 255.255.255.0`: traditional IPv4 'address netmask' style
- `192.168.2.0/24`: modern prefix length, same also for IPv6
- `192.168.2.0 255.255.255.0`: traditional IPv4 'address netmask' style
- `192.168.2.0/24`: modern prefix length, same also for IPv6
An optional `split LEN` can be given as argument, the new length value
must be bigger than the current prefix length. See example below.
+10 -7
View File
@@ -1,4 +1,4 @@
# Quick Overview
# CLI Quickstart Guide
The question mark `?` key along with the `Tab` key are your best friends
in the command line interface. They provide context help and completion
@@ -16,14 +16,17 @@ of commands you input. See the table below for a handful of examples.
Explore the following topics for more information. Note, the
keybindings are really useful to learn!
| **Command** | **Description** |
|---------------------|--------------------------------------------|
| `help introduction` | An introduction to the CLI |
| `help configure` | How to use configure context |
| `help text-editor` | Help with the built-in text-editor command |
| `help keybindings` | Lists keybindings and other helpful tricks |
| **Command** | **Description** |
|---------------------|----------------------------------------------------|
| `help introduction` | An introduction to the CLI |
| `help configure` | How to use configure context |
| `help text-editor` | Help with the built-in text-editor command |
| `help keybindings` | Lists available keybindings & other helpful tricks |
----
> In `configure` context the `help setting` command shows the YANG
> description text for each node and container. To reach the admin
> exec help from configure context, e.g., `do help text-editor`
----
+7 -3
View File
@@ -1,4 +1,4 @@
## Network Traffic Inspection
# Network Monitoring
`tcpdump` is useful tool for analyzing and diagnosing network problems.
This document presents the limited feature set that exposed is in the
@@ -10,7 +10,7 @@ A section called [Examples](#examples) follows that, which may be what
you want to scroll down to.
### Hardware Overview
## Hardware Overview
Using `tcpdump` effectively requires an understanding of how the
underlying hardware works. For a standard PC, or common single-board
@@ -57,17 +57,21 @@ up the switch core to mirror traffic ingressing and/or egressing a set
of ports to another port. On this *monitor port* you can then run your
tcpdump, which means you need an external device (laptop).
----
> A planned feature is to support mirroring traffic to the CPU port,
> which would be an effective way to log and monitor traffic over a
> longer period of time. Highly effective for diagnosing intermittent
> and other rare network issues.
----
If only "proof of life" is required, then sometimes port counters, also
called *RMON counters*, can be very useful too. Seeing counters of a
particular type increment means traffic is ingressing or egressing.
### Examples
## Examples
Listen to all traffic on an interface:
+3
View File
@@ -44,10 +44,13 @@ C-x i insert C-x g goto-ln C-x o other win C-x C-x swap M-q reform
- tap `c`
- release `Ctrl`
----
> The status field at the bottom asks if you are really sure, and/or if
> you want to add a final Enter/newline to the file. For binary content
> that final newline may be important.
----
## Changing the Editor
+2 -6
View File
@@ -1,5 +1,4 @@
Upgrading the Software
----------------------
# Upgrading the System
The admin-exec command `upgrade` can be used to install software images, or
bundles. A bundle is a signed and self-contained package that carries all the
@@ -39,12 +38,9 @@ The secondary partition (`rootfs.1`) has now been upgraded and will be used as
the *active* partition on the next boot. Leaving the primary partition, with
the version we are currently running, intact in case of trouble.
See [upgrading procedures and boot order][2] for more information on
upgrading.
See [Upgrade & Boot Order](../upgrade.md) for more information on upgrading.
[^1]: It is not possible to upgrade the partition we booted from. Thankfully
the underlying "rauc" subsystem keeps track of this. Hence, to upgrade
both partitions you must reboot to the new version (to verify it works)
and then repeat the same command.
[2]: ../system.md#upgrade-procedures-and-boot-order
+8 -31
View File
@@ -1,31 +1,7 @@
Containers in Infix
===================
<img align="right" src="img/docker.webp" alt="Docker whale" width=360>
Docker Container Support
========================
* [Introduction](#introduction)
* [Caution](#caution)
* [Getting Started](#getting-started)
* [Examples](#examples)
* [Container Images](#container-images)
* [Upgrading a Container Image](#upgrading-a-container-image)
* [Networking and Containers](#networking-and-containers)
* [Container Bridge](#container-bridge)
* [Container Host Interface](#container-host-interface)
* [Host Networking](#host-networking)
* [Mounts and Volumes](#mounts-and-volumes)
* [Content Mounts](#content-mounts)
* [Example Containers](#example-containers)
* [System Container](#system-container)
* [Application Container: nftables](#application-container-nftables)
* [Application Container: ntpd](#application-container-ntpd)
* [Advanced](#advanced)
* [Running Host Commands From Container](#running-host-commands-from-container)
* [Container Requirements](#container-requirements)
* [Advanced Users](#advanced-users)
Introduction
------------
![Docker whale](img/docker.webp){ align=right width="360" }
Infix comes with native support for Docker containers using [podman][].
The [YANG model][1] describes the current level of support, complete
@@ -110,10 +86,9 @@ your container image and application to run.
> support the CPU architecture of your host system. Remember, unlike
> virtualization, containers reuse the host's CPU and kernel.
![Hello World](img/docker-hello-world.svg){ align=right width="200" }
<img align="right" src="img/docker-hello-world.svg" alt="Hello World" width=360>
### Examples
### Example: Hello World
Classic Hello World:
@@ -129,6 +104,8 @@ Classic Hello World:
Hello from Docker!
This message shows that your installation appears to be working correctly.
### Example: Web Server
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:
@@ -279,7 +256,7 @@ archive, which helps greatly with container upgrades (see below):
Upgrading a Container Image
---------------------------
<img align="right" src="img/shield-checkmark.svg" alt="Hello World" width=100>
![Up-to-date Shield](img/shield-checkmark.svg){ align=right width="100" }
The applications in your container are an active part of the system as a
whole, so make it a routine to keep your container images up-to-date!
+186 -156
View File
@@ -14,6 +14,9 @@ the Buildroot `make menuconfig` system.
-> System configuration
-> [*]Enable root login with password
> [!IMPORTANT]
> Please see the [Contributing](#contributing) section, below, for
> details on how to fork and clone when contributing to Infix.
Cloning
-------
@@ -25,14 +28,12 @@ tree to your PC:
```bash
$ mkdir ~/Projects; cd ~/Projects
$ git clone https://github.com/kernelkit/infix.git
..
$ cd infix/
$ git submodule update --init
..
```
> Please see the [Contributing](#contributing) section, below, for
> details on how to fork and clone when contributing to Infix.
### Customer Builds
Customer builds add product specific device trees, more OSS packages,
@@ -57,6 +58,10 @@ Other caveats should be documented in the customer specific trees.
Building
--------
> [!TIP]
> For more details, see the Getting Started and System Requirements
> sections of the [excellent Buildroot manual][1].
Buildroot is almost stand-alone, it needs a few locally installed tools
to bootstrap itself. The most common ones are usually part of the base
install of the OS, but specific ones for building need the following.
@@ -71,9 +76,6 @@ $ sudo apt install bc binutils build-essential bzip2 cpio \
mtools
```
> For details, see the Getting Started and System Requirements sections
> of the [excellent manual][1].
To build an Infix image; select the target and then make:
make x86_64_defconfig
@@ -96,12 +98,43 @@ and services are required on your system:
```bash
$ sudo apt install jq graphviz qemu-system-x86 qemu-system-arm \
ethtool gdb-multiarch tcpdump tshark
..
```
To be able to build the test specification you also need:
```bash
$ sudo apt-get install python3-graphviz ruby-asciidoctor-pdf
..
```
### Documentation
The documentation is written in Markdown, with GitHub extensions, and
published using [MkDocs, material theme][11]. This means some features
require MkDocs *hinting* which may not render fully when previewing on
GitHub -- this is OK.
MkDocs is packaged and available to install via `apt`, but not all of
the plugins and extensions we rely on are available, so instead we do
recommend using `pipx` to install the necessary tooling:
```bash
$ sudo apt install pipx
$ pipx install mkdocs
$ pipx inject mkdocs mkdocs-material pymdown-extensions mkdocs-callouts mike mkdocs-to-pdf
```
The last two packages, `mike` and `mkdocs-to-pdf`, are used for online
versioning and PDF generation by GitHub Actions, but since they are in
the `mkdocs.yml` file, everyone who wants to preview the documentation
have to install all the tooling.
Preview with:
```
$ cd ~/src/infix/
$ mkdocs serve
```
@@ -133,6 +166,14 @@ on Buildroot to finalize the target filesystem and generate the images.
The final `run` argument is explained below.
### YANG Model
When making changes to the `confd` and `statd` services, you will often
need to update the YANG models. If you are adding a new YANG module,
it's best to follow the structure of an existing one. However, before
making any changes, **always discuss them with the Infix core team**.
This helps avoid issues later in development and makes pull request
reviews smoother.
### `confd`
@@ -212,174 +253,156 @@ To replay:
This is especially useful when working in isolated environments or debugging
issues without direct access to the DUT.
### Upgrading Packages
#### Buildroot
## Upgrading Packages
Kernelkit maintains an internal [fork of
Buildroot](https://github.com/kernelkit/buildroot), with branches
following the naming scheme `YYYY.MM.patch-kkit`
### Buildroot
The Kernelkit team maintains an internal [fork of Buildroot][9], with
branches following the naming scheme `YYYY.MM.patch-kkit`
e.g. `2025.02.1-kkit`, which means a new branch should be created
whenever Buildroot is updated. These branches should contain **only**
changes to existing packages (but no new patches), modifications to
Buildroot itself or upstream backports.
KernelKit track the latest Buildroot LTS (Long-Term Support) release
and updates. The upgrade of LTS minor releases is expected to have low
impact and should be done as soon there is a patch release of
Buildroot LTS is available.
The team tracks the latest Buildroot LTS (Long-Term Support) release and
updates. The impact of minor LTS release upgrades is expected to have a
very low impact and should be done as soon there is a patch release of a
Buildroot LTS available.
> **Depending on your setup, follow the appropriate steps below.**
🔁 If you **already have** the Buildroot repo locally
#### Repo locally cloned already
1. Navigate to the Buildroot directory
```bash
$ cd buildroot
```
2. Pull the latest changes from KernelKit
```bash
$ git pull
```
3. Fetch the latest tags from upstream
```bash
$ git fetch upstream --tags
```
cd buildroot/
🆕 If you don't have the repo locally
1. Pull the latest changes from KernelKit
git pull
1. Fetch the latest tags from upstream
git fetch upstream --tags
#### No local repo yet
1. Clone the Kernelkit Buildroot repository
```bash
$ git clone git@github.com:kernelkit/buildroot.git
```
2. Add the upstream remote
```bash
$ git remote add upstream https://gitlab.com/buildroot.org/buildroot.git
```
3. Checkout old KernelKit branch
```bash
$ git checkout 2025.02.1-kkit
```
git clone git@github.com:kernelkit/buildroot.git
1. Add the upstream remote
git remote add upstream https://gitlab.com/buildroot.org/buildroot.git
1. Checkout old KernelKit branch
git checkout 2025.02.1-kkit
> [!NOTE]
> Below, it is **not** allowed to rebase the branch when bumped in Infix.
#### Continue Here
1. Create a new branch based on the **previous** KernelKit Buildroot
release (e.g. `2025.02.1-kkit`) and name it according to the naming
scheme (e.g. `2025.02.2-kkit`)
git checkout -b 2025.02.2-kkit
1. Rebase the new branch onto the corresponding upstream release
git rebase 2025.02.2
1. Push the new branch and tags
git push origin 2025.02.2-kkit --tags
1. In Infix, checkout new branch of Buildroot
cd buildroot
git fetch
git checkout 2025.02.2-kkit
1. Commit and push the changes. *Remember to update the ChangeLog!*
1. Create a pull request.
> [!NOTE]
> Remember to set the pull request label to `ci:main` to ensure full CI
> coverage.
🛠 Continue from here (applies to both cases):
### Linux kernel
4. Create a new branch based on the **previous** KernelKit Buildroot
release (e.g. `2025.02.1-kkit`) and name it according to the naming scheme (e.g. `2025.02.2-kkit`)
```bash
$ git checkout -b 2025.02.2-kkit
```
5. Rebase the new branch onto the corresponding upstream release
```bash
$ git rebase 2025.02.2
```
> [!NOTE] It is **not** allowed to rebase the branch when bumped in Infix.
The KernelKit team maintains an internal [fork of Linux kernel][10],
with branches following the naming scheme `kkit-linux-[version].y`,
e.g. `kkit-6.12.y`, which means a new branch should be created whenever
the major kernel version is updated. This branch should contain *all*
kernel patches used by Infix.
6. Push the new branch and tags
```bash
$ git push origin 2025.02.2-kkit --tags
```
7. In Infix, checkout new branch of Buildroot
```bash
$ cd buildroot
$ git fetch
$ git checkout 2025.02.2-kkit
```
8. Push changes
Commit and push the changes. Dont forget to update the changelog.
The team tracks the latest Linux kernel LTS (Long-Term Support) release
and updates. The upgrade of LTS minor releases is expected to have low
impact and should be done as soon as a patch release of the LTS Linux
kernel is available.
9. Create a pull request.
> [!NOTE] Remember to set the pull request label to `ci:main` to ensure full CI coverage.
#### Linux kernel
KernelKit maintains an internal [fork of Linux
kernel](https://github.com/kernelkit/linux), with branches following
the naming scheme `kkit-linux-[version].y`, e.g. `kkit-6.12.y`, which
means a new branch should be created whenever the major kernel version
is updated. This branch should contain *all* kernel patches used by
Infix.
KernelKit track the latest Linux kernel LTS (Long-Term Support)
release and updates. The upgrade of LTS minor releases is expected to
have low impact and should be done as soon as a patch release of the
LTS Linux kernel is available.
🔁 If you **already have** the Linux kernel repo locally
#### Repo locally cloned already
1. Navigate to the Linux kernel directory
```bash
$ cd linux
```
2. Get latest changes from KernelKit
```bash
$ git pull
```
3. Fetch the latest tags from upstream
```bash
$ git fetch upstream --tags
```
🆕 If you don't have the repo locally
cd linux
1. Get latest changes from KernelKit
git pull
1. Fetch the latest tags from upstream
git fetch upstream --tags
#### No local repo yet
1. Clone the KernelKit Linux kernel repository
```bash
$ git clone git@github.com:kernelkit/linux.git
```
2. Add the upstream remote
```bash
$ git remote add upstream git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
```
3. Checkout correct kernel branch
```bash
$ git checkout kkit-linux-6.12.y
```
git clone git@github.com:kernelkit/linux.git
🛠 Continue from here (applies to both cases)
1. Add the upstream remote
git remote add upstream git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
4. Rebase on the upstream release
```bash
$ git rebase v6.12.29
```
1. Checkout correct kernel branch
6. Push changes and the tags
```bash
git checkout kkit-linux-6.12.y
$ git push -f origin kkit-linux-6.12.y --tags
```
#### Continue Here
**Move to your infix directory**
1. Rebase on the upstream release
7. Generate patches
```bash
$ make x86_64_defconfig
$ cd output
$ ../utils/kernel-refresh.sh -k /path/to/linux -o 6.12.28 -t v6.12.29
```
> [!NOTE] See help of `kernel-refresh.sh` script for more information
git rebase v6.12.29
1. Push changes and the tags
git push -f origin kkit-linux-6.12.y --tags
8. Push changes
Commit and push the changes. Dont forget to update the s:changelog:doc/ChangeLog.md.
**Move to your Infix source tree**
9. Create a pull request.
> [!NOTE] Remember to set the pull request label to `ci:main` to ensure full CI coverage.
> [!NOTE]
> See help of `kernel-refresh.sh` script for more information.
1. Generate patches
### Agree on YANG Model
make x86_64_defconfig
cd output
../utils/kernel-refresh.sh -k /path/to/linux -o 6.12.28 -t v6.12.29
1. Commit and push the changes. Remember to update the ChangeLog
1. Create a pull request
> [!NOTE]
> Remember to set the pull request label to `ci:main` to ensure full CI
> coverage.
When making changes to the `confd` and `statd` services, you will often need to update
the YANG models. If you are adding a new YANG module, it's best to follow the
structure of an existing one. However, before making any changes, **always discuss
them with the Infix core team**. This helps avoid issues later in development and
makes pull request reviews smoother.
Testing
@@ -393,8 +416,8 @@ work is done -- **much quicker** change-load-test cycles.
The Infix automated test suite is built around Qemu and [Qeneth][2], see:
* [Testing](testing.md)
* [Docker Image](../test/docker/README.md)
* [Regression Testing with Infamy](testing.md)
* [Docker Image](https://github.com/kernelkit/infix/blob/main/test/docker/README.md)
With any new feature added to Infix, it is essential to include relevant
test case(s). See the [Test Development](testing.md#test-development)
@@ -404,14 +427,13 @@ section for guidance on adding test cases.
Reviewing
---------
While reviewing a pull request, you might find yourself wanting to
play around with a VM running that _exact_ version. For such
occations, [gh-dl-artifact.sh](../utils/gh-dl-artifact.sh) is your
friend in need! It will use the [GitHub CLI
(gh)](https://cli.github.com) to locate a prebuilt image from our CI
While reviewing a pull request, you might find yourself wanting to play
around with a VM running that _exact_ version. For such occasions,
[gh-dl-artifact.sh][8] is your friend in need! It employs the [GitHub
CLI (gh)](https://cli.github.com) to locate a prebuilt image from our CI
workflow, download it, and prepare a local output directory from which
you can launch both `make run` instances, and run regression tests
with `make test` and friends.
you can launch both `make run` instances, and run regression tests with
`make test` and friends.
For example, if you are curious about how PR 666 behaves in some
particular situation, you can use `gh` to switch to that branch, from
@@ -423,10 +445,10 @@ corresponding image for execution with our normal tooling:
cd x-artifact-a1b2c3d4-x86_64
make run
> **Note:** CI artifacts are built from a merge commit of the source
> and target branches. Therefore, the version in the Infix banner
> will not match the SHA of the commit you have checked out.
> [!NOTE]
> CI artifacts are built from a merge commit of the source and target
> branches. Therefore, the version in the Infix banner will not match
> the SHA of the commit you have checked out.
Contributing
------------
@@ -438,28 +460,32 @@ fork, and then use GitHub to create a *Pull Reqeuest*.
For this to work as *painlessly as possible* for everyone involved:
1. Fork Infix to your own user or organization[^1]
2. Fork all the Infix submodules, e.g., `kernelkit/buildroot` to your
1. Fork all the Infix submodules, e.g., `kernelkit/buildroot` to your
own user or organization as well
3. Clone your fork of Infix to your laptop/workstation
4. [Deactivate the Actions][6] you don't want in your fork
5. Please read the [Contributing Guidelines][5] as well!
1. Clone your fork of Infix to your laptop/workstation
1. [Deactivate the Actions][6] you don't want in your fork
1. Please read the [Contributing Guidelines][5] as well!
```bash
$ cd ~/Projects
$ git clone https://github.com/YOUR_USER_NAME/infix.git
...
$ cd infix/
$ git submodule update --init
...
```
> **Note:** when updating/synchronizing with upstream Infix changes you
> may have to synchronize your forks as well. GitHub have a `Sync fork`
> button in the GUI for your fork for this purpose. A cronjob on your
> server of choice can do this for you with the [GitHub CLI tool][7].
> [!NOTE]
> When updating/synchronizing with upstream Infix changes you may have
> to synchronize your forks as well. GitHub have a `Sync fork` button
> in the GUI for your fork for this purpose. A cronjob on your server
> of choice can do this for you with the [GitHub CLI tool][7].
[^1]: Organizations should make sure to lock the `main` (or `master`)
branch of their clones to ensure members do not accidentally merge
changes there. Keeping these branches in sync with upstream Infix
is highly recommended as a baseline and reference. For integration
of local changes another company-specific branch can be used instead.
of local changes another company-specific branch can be used instead.
[0]: https://github.com/kernelkit/infix/releases
[1]: https://buildroot.org/downloads/manual/manual.html
@@ -469,3 +495,7 @@ $ git submodule update --init
[5]: https://github.com/kernelkit/infix/blob/main/.github/CONTRIBUTING.md
[6]: https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow
[7]: https://cli.github.com/
[8]: https://github.com/kernelkit/infix/blob/main/utils/gh-dl-artifact.sh
[9]: https://github.com/kernelkit/buildroot
[10]: https://github.com/kernelkit/linux
[11]: https://squidfunk.github.io/mkdocs-material/
+4 -4
View File
@@ -1,4 +1,4 @@
# Discover Devices
# Device Discovery
Infix advertises itself via the [mDNS-SD](#mdns-sd) and [LLDP](#lldp)
discovery protocols. mDNS-SD has good client support in Windows, macOS
@@ -8,9 +8,9 @@ An even simpler method is available when directly attached to an Infix
device:
```
.----. Ethernet .-------.
| PC +---------------------+ Infix |
'----' if1 e1 '-------'
.----. Ethernet .--------.
| PC +---------------------+ Device |
'----' if1 e1 '--------'
```
With IPv6 you can *ping the all-hosts* address (ff02::1), the device's
+17 -39
View File
@@ -1,41 +1,19 @@
# YANG to Ethtool Mapping
# RMON Counters
This column contains the mapping between YANG and Linux / Ethtool counters.
This document show the mapping between YANG and Linux / Ethtool counters.
```
┌─────────────────────────────────┬──────────────────────────────────┐
│ YANG │ Linux / Ethtool │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-total-octets │ FramesReceivedOK,
│ │ FrameCheckSequenceErrors │
│ │ FramesLostDueToIntMACRcvError │
│ │ AlignmentErrors │
│ │ etherStatsOversizePkts │
│ │ etherStatsJabbers │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-frames │ FramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-multicast-frames │ MulticastFramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-broadcast-frames │ BroadcastFramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-error-fcs-frames │ FrameCheckSequenceErrors │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-error-undersize-frames │ undersize_pkts │
├─────────────────────────────────┼──────────────────────────────────┤
| in-error-oversize-frames | etherStatsJabbers, |
| | etherStatsOversizePkts |
├─────────────────────────────────┼──────────────────────────────────┤
│ in-error-mac-internal-frames │ FramesLostDueToIntMACRcvError │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-frames │ FramesTransmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-multicast-frames │ MulticastFramesXmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-broadcast-frames │ BroadcastFramesXmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ infix-eth:out-good-octets │ OctetsTransmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ infix-eth:in-good-octets │ OctetsReceivedOK │
└─────────────────────────────────┴──────────────────────────────────┘
```
| **YANG** | **Linux / Ethtool** |
|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| `in-total-octets` | `FramesReceivedOK`, `FrameCheckSequenceErrors`, `FramesLostDueToIntMACRcvError`, `AlignmentErrors`, `etherStatsOversizePkts`, `etherStatsJabbers` |
| `in-frames` | `FramesReceivedOK` |
| `in-multicast-frames` | `MulticastFramesReceivedOK` |
| `in-broadcast-frames` | `BroadcastFramesReceivedOK` |
| `in-error-fcs-frames` | `FrameCheckSequenceErrors` |
| `in-error-undersize-frames` | `undersize_pkts` |
| `in-error-oversize-frames` | `etherStatsJabbers`, `etherStatsOversizePkts` |
| `in-error-mac-internal-frames` | `FramesLostDueToIntMACRcvError` |
| `out-frames` | `FramesTransmittedOK` |
| `out-multicast-frames` | `MulticastFramesXmittedOK` |
| `out-broadcast-frames` | `BroadcastFramesXmittedOK` |
| `infix-eth:out-good-octets` | `OctetsTransmittedOK` |
| `infix-eth:in-good-octets` | `OctetsReceivedOK` |
+12
View File
@@ -0,0 +1,12 @@
.md-header__title {
font-size: 1.1rem;
line-height: 2.6rem;
}
[data-md-color-primary="orange"] {
--md-primary-fg-color: #ff7f2a;
--md-primary-bg-color: #5c5f5c;
}
[data-md-color-primary="black"] {
--md-primary-bg-color: #5c5f5c;
}
+92
View File
@@ -0,0 +1,92 @@
# Introduction
![Infix - Linux <3 NETCONF](logo.png){ align=right width="480" }
Welcome to Infix, your immutable, friendly, and secure operating system!
On these pages you can find both user and developer documentation.
Most topics on configuring the system include CLI examples, but every
setting, as well as status read-back from the operational datastore, is
also possible to perform using NETCONF or RESTCONF. In fact, the Infix
regression test system solely relies on NETCONF and RESTCONF.
> [!TIP]
> The CLI documentation is also available from inside the CLI itself
> using the `help` command in admin-exec mode.
This document provides an introduction of key concepts, details how
the system boots, including failure modes, and provides links to
other documents for further study.
## Command Line Interface
The command line interface (CLI, see-ell-i) is the traditional way of
interacting with single network equipment like switches and routers.
Today users have come to expect more advanced graphical GUIs, like a web
interface, to manage a device or NETCONF-based tools that allow for
managing entire fleets of installed equipment.
Nevertheless, when it comes to initial deployment and debugging, it
is very useful to know how to navigate and use the CLI.
> [!INFO]
> For more information, see the [CLI Introduction](cli/introduction.md)
> and the [CLI Configuration Tutorial](cli/configure.md).
## Key Concepts
The two modes in the CLI are the admin-exec and the configure context.
However, when logging in to the system, from the console port or SSH,
you land in a standard UNIX shell, Bash. This is for advanced users
and remote scripting purposes (production equipment):
```
Run the command 'cli' for interactive OAM
admin@example:~$
```
To enter the CLI, follow the instructions, for interactive Operations,
Administration, and Management (OAM), type:
```
admin@example:~$ cli
admin@example:/>
```
The prompt, constructed from your username and the device's hostname,
changes slightly. You are now in the admin-exec context of the CLI.
Here you can inspect system status and do operations to debug networking
issues, e.g. ping. You can also enter configure context by typing:
`configure` followed by commands to `set`, `edit`, apply changes using
`leave`, or `abort` and return to admin-exec.
> [!TIP]
> If you haven't already, the [CLI Introduction](cli/introduction.md)
> would be useful to skim through at this point.
## Datastores
The system has several datastores (or files):
- `factory-config` consists of a set of default configurations, some
static and others generated per-device, e.g., a unique hostname and
number of ports/interfaces. This file is generated at boot.
- `failure-config` is also generated at boot, from the same YANG models
as `factory-config`, and holds the system *Fail Secure Mode*
- `startup-config` is created from `factory-config` at boot if it does
not exist. It is loaded as the system configuration on each boot.
- `running-config` is what is actively running on the system. If no
changes have been made since the system booted, it is the same as
`startup-config`.
- `candidate-config` is created from `running-config` when entering the
configure context. Any changes made here can be discarded (`abort`,
`rollback`) or committed (`commit`, `leave`) to `running-config`.
> [!TIP]
> Please see the [Branding & Releases](branding.md) document for more
> in-depth information on how `factory-config` and `failure-config` can
> be adapted to different customer requirements. Including how you can
> override the generated versions of these files with plain per-product
> ones -- this may even protect against some of the failure modes below.
-152
View File
@@ -1,152 +0,0 @@
# Introduction
This document provides an introduction of key concepts, details how
the system boots, including failure modes, and provides links to
other documents for further study.
## CLI
The command line interface (CLI, see-ell-i) is the traditional way of
interacting with single network equipment like switches and routers.
Today users have come to expect more advanced graphical GUIs, like a web
interface, to manage a device or NETCONF-based tools that allow for
managing entire fleets of installed equipment.
Nevertheless, when it comes to initial deployment and debugging, it
is very useful to know how to navigate and use the CLI.
> Proceed to the [CLI Introduction](cli/introduction.md) or [CLI
> Configuration Tutorial](cli/configure.md).
## Key Concepts
The two modes in the CLI are the admin-exec and the configure context.
However, when logging in to the system, from the console port or SSH,
you land in a standard UNIX shell, Bash. This is for advanced users
and remote scripting purposes (production equipment):
Run the command 'cli' for interactive OAM
admin@example:~$
To enter the CLI, follow the instructions, for interactive Operations,
Administration, and Management (OAM), type:
admin@example:~$ cli
admin@example:/>
The prompt, constructed from your username and the device's hostname,
changes slightly. You are now in the admin-exec context of the CLI.
Here you can inspect system status and do operations to debug networking
issues, e.g. ping. You can also enter configure context by typing:
`configure` followed by commands to `set`, `edit`, apply changes using
`leave`, or `abort` and return to admin-exec.
> The [CLI Introduction](cli/introduction.md) can be useful to skim
> through at this point.
The system has several datastores (or files):
- `factory-config` consists of a set of default configurations, some
static and others generated per-device, e.g., a unique hostname and
number of ports/interfaces. This file is generated at boot.
- `failure-config` is also generated at boot, from the same YANG models
as `factory-config`, and holds the system *Fail Secure Mode*
- `startup-config` is created from `factory-config` at boot if it does
not exist. It is loaded as the system configuration on each boot.
- `running-config` is what is actively running on the system. If no
changes have been made since the system booted, it is the same as
`startup-config`.
- `candidate-config` is created from `running-config` when entering the
configure context. Any changes made here can be discarded (`abort`,
`rollback`) or committed (`commit`, `leave`) to `running-config`.
> Please see the [Branding & Releases](branding.md) document for more
> in-depth information on how `factory-config` and `failure-config` can
> be adapted to different customer requirements. Including how you can
> override the generated versions of these files with plain per-product
> ones -- this may even protect against some of the failure modes below.
## System Boot
After the system firmware (BIOS or and [boot loader](boot.md) start
Linux the following happens. The various failure modes, e.g., missing
password in VPD, are detailed later in this section.
![System boot flowchart](img/fail-secure.svg)
1. Before mounting `/cfg` and `/var` partitions, hosting read-writable
data like `startup-config` and container images, the system first
checks if a factory reset has been requested by the user, if so it
wipes the contents of these partitions
2. Linux boots with a device tree which is used for detecting generic
make and model of the device, e.g., number of interfaces. It may
also reference an EEPROM with [Vital Product Data](vpd.md). That is
where the base MAC address and per-device password hash is stored.
(Generic builds use the same MAC address and password)
3. On every boot the system's `factory-config` and `failure-config` are
generated from the YANG[^1] models of the current firmware version.
This ensures that a factory reset device can always boot, and that
there is a working fail safe, or rather *fail secure*, mode
4. On first power-on, and after a factory reset, the system does not
have a `startup-config`, in which case `factory-config` is copied
to `startup-config` -- if a per-product specific version exists it
is preferred over the generated one
5. Provided the integrity of the `startup-config` is OK, a system
service loads and activates the configuration
### Failure Modes
So, what happens if any of the steps above fail?
**VPD Fail**
The per-device password cannot be read, or is corrupt, so the system
`factory-config` and `failure-config` are not generated:
1. First boot, or after factory reset: `startup-config` cannot be
created or loaded, and `failure-config` cannot be loaded. The
system ends up in an unrecoverable state, i.e., **RMA[^2] Mode**
2. The system has booted (at least) once with correct VPD and password
and already has a `startup-config`. Provided the `startup-config`
is OK (see below), it is loaded and system boots successfully
In both cases, external factory reset modes/button will not help, and
in the second case will cause the device to fail on the next boot.
> The second case does not yet have any warning or event that can be
> detected from the outside. This is planned for a later release.
**Broken startup-config**
If loading `startup-config` fails for some reason, e.g., invalid JSON
syntax, failed validation against the system's YANG model, or a bug in
the system's `confd` service, the *Fail Secure Mode* is triggered and
`failure-config` is loaded (unless VPD Failure, see above).
> Again, please see the [Branding & Releases](branding.md) document for
> how to provide a per-product hard-coded `failure-config` to suit your
> products preferences.
*Fail Secure Mode* is a fail-safe mode provided for debugging the
system. The default[^3] creates a setup of isolated interfaces with
communication only to the management CPU, SSH and console login using
the device's factory reset password, IP connectivity only using IPv6
link-local, and device discovery protocols: LLDP, mDNS-SD. The login
and shell prompt are set to `failure-c0-ff-ee`, the last three octets of
the device's base MAC address.
[^1]: YANG is a modeling language from IETF, replacing that used for
SNMP (MIB), used to describe the subsystems and properties of
the system.
[^2]: Return Merchandise Authorization (RMA), i.e., broken beyond repair
by end-user and eligible for return to manufacturer.
[^3]: Customer specific builds can define their own `failure-config`.
It may be the same as `factory-config`, with the hostname set to
`failure`, or a dedicated configuration that isolates interfaces, or
even disables ports, to ensure that the device does not cause any
security problems on the network. E.g., start forwarding traffic
between previously isolated VLANs.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

+1 -1
View File
@@ -1,5 +1,5 @@
Origin & Licensing
------------------
==================
Infix is entirely built on Open Source components (packages). Most of
them, as well as the build system with its helper scripts and tools, is
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

+187
View File
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="logo2.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="5.1481021"
inkscape:cx="371.01052"
inkscape:cy="472.98985"
inkscape:window-width="2560"
inkscape:window-height="1385"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<rect
x="505.95288"
y="579.6032"
width="127.6438"
height="127.94966"
id="rect1266" />
<rect
x="309.92126"
y="404.51989"
width="483.77954"
height="358.02926"
id="rect600" />
<inkscape:path-effect
effect="bspline"
id="path-effect5591"
is_visible="true"
lpeversion="1"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
</defs>
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="bg"
style="display:none;fill:#ff0000;fill-opacity:1"
transform="matrix(1.2831201,0,0,3.2117929,-26.690111,-224.39813)">
<rect
style="fill:#22272e;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect10264"
width="163.66356"
height="92.471725"
x="20.800945"
y="69.866936"
inkscape:label="bg" />
</g>
<g
inkscape:groupmode="layer"
id="layer5"
inkscape:label="tagline"
style="display:inline">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.77333px;font-family:Laksaman;-inkscape-font-specification:'Laksaman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#5c5f5c;stroke-width:0;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
x="85.018883"
y="131.54915"
id="text9503"
inkscape:label="linux-netconf"
inkscape:export-filename="logo.png"
inkscape:export-xdpi="191.95932"
inkscape:export-ydpi="191.95932"><tspan
sodipodi:role="line"
id="tspan9519"
x="85.018883"
y="131.54915"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.77333px;font-family:Laksaman;-inkscape-font-specification:'Laksaman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#5c5f5c;fill-opacity:1;stroke:#5c5f5c;stroke-opacity:1"
id="tspan11822">Linux</tspan> <tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.77333px;font-family:Laksaman;-inkscape-font-specification:'Laksaman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff7f2a;fill-opacity:1;stroke:#5c5f5c;stroke-opacity:1"
id="tspan9929"></tspan> <tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.77333px;font-family:Laksaman;-inkscape-font-specification:'Laksaman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#5c5f5c;fill-opacity:1;stroke:#5c5f5c;stroke-opacity:1"
id="tspan11824">NETCONF</tspan></tspan></text>
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="heading">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.4px;font-family:'URW Bookman';-inkscape-font-specification:'URW Bookman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#5c5f5c;stroke-width:1.029;fill-opacity:1"
x="84.745331"
y="124.1693"
id="text1160"
inkscape:label="infix"
inkscape:export-filename="logo-plain.png"
inkscape:export-xdpi="191.95932"
inkscape:export-ydpi="191.95932"><tspan
sodipodi:role="line"
id="tspan1272"
x="84.745331"
y="124.1693">Infix</tspan></text>
</g>
<g
inkscape:label="tux"
inkscape:groupmode="layer"
id="layer1"
style="display:inline">
<rect
style="fill:#f9f9f9;stroke:#5c5f5c;stroke-width:1.029;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="rect1698"
width="22.470779"
height="16.970779"
x="59.529221"
y="107.02922"
inkscape:label="body"
inkscape:export-filename="jack.png"
inkscape:export-xdpi="191.95932"
inkscape:export-ydpi="191.95932" />
<rect
style="fill:#ff7f2a;stroke:#5c5f5c;stroke-width:1;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="rect184-3"
width="6"
height="4"
x="76"
y="120"
inkscape:label="foot-r" />
<rect
style="fill:#ff7f2a;stroke:#5c5f5c;stroke-width:1;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="rect184"
width="6"
height="4"
x="59.529221"
y="120"
inkscape:label="foot-l" />
<path
sodipodi:type="star"
style="fill:#ff7f2a;stroke:none;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
id="path11801"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="42.414055"
sodipodi:cy="98.701302"
sodipodi:r1="1.9660654"
sodipodi:r2="0.9830327"
sodipodi:arg1="1.5707963"
sodipodi:arg2="2.6179939"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 42.414055,100.66737 -1.702663,-2.949101 3.405325,0 z"
inkscape:transform-center-y="0.49151511"
transform="translate(28.350554,16.321792)"
inkscape:label="nose" />
<circle
style="display:inline;fill:#5c5f5c;stroke:none;stroke-width:4.99999;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="path6519-5"
cx="73.211082"
cy="111.02191"
r="0.5"
inkscape:label="eye-r" />
<circle
style="fill:#5c5f5c;stroke:none;stroke-width:4.99999;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="path6519"
cx="68.31813"
cy="111.02191"
r="0.5"
inkscape:label="eye-l" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

+3 -7
View File
@@ -1,4 +1,4 @@
# Management
# System Management
The system utilizes YANG models for keeping configuration and operational
data. These databases can be managed through different interfaces such
@@ -194,10 +194,6 @@ admin@example:/config/web/restconf/> no enabled
admin@example:/config/web/restconf/>
```
# System Upgrade
## System Upgrade
See [upgrading procedures and boot order][1] for information on
upgrading.
[1]: system.md#upgrade-procedures-and-boot-order
See [Upgrade & Boot Order](upgrade.md) for information on upgrading.
+3 -3
View File
@@ -238,7 +238,7 @@ 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).
of the [terminology used](#terminology-abbreviations).
> [!IMPORTANT]
> Currently there is no way to just enable multicast filtering without
@@ -1253,7 +1253,7 @@ router 192.168.1.1, using the highest possible distance:
admin@example:/>
> [!TIP]
> Remember to enable [IPv4 forwarding](#IPv4-forwarding) for the
> Remember to enable [IPv4 forwarding](#ipv4-forwarding) for the
> interfaces you want to route between.
@@ -1277,7 +1277,7 @@ enable OSPF and set one active interface in area 0:
admin@example:/>
> [!TIP]
> Remember to enable [IPv4 forwarding](#IPv4-forwarding) for all the
> Remember to enable [IPv4 forwarding](#ipv4-forwarding) for all the
> interfaces you want to route between.
+9 -6
View File
@@ -2,9 +2,11 @@ Package Override
================
This guide demonstrates how the `local.mk` file is utilized to override
a Linux Buildroot package. As an example we use `tcpdump` to illustrate
this process.
a Buildroot package, which can be very useful when fixing bugs, adding
features, or evaluating new releases of packages. As an example we use
`tcpdump` to illustrate this process.
> [!TIP]
> For a comprehensive guide to utilizing Buildroot during development,
> including the `<pkg>_OVERRIDE_SRCDIR` mechanism, shown below, please
> see [Using Buildroot during development][1] in the official docs.
@@ -67,9 +69,10 @@ drwxr-xr-x 7 group user 12288 Nov 10 18:28 tcpdump-custom/
As long as your local override is in place, Buildroot will use your
custom version.
> **Remember:** the build directory is ephemeral, so be careful to
> change any of the files therein. It can be useful though during
> debugging, but just make sure to learn the difference between the
> various Buildroot commands to build, clean, reconfigure, etc.
> [!NOTE]
> Remember, the build directory is ephemeral, so be careful to change
> any of the files therein. It can be useful though during debugging,
> but just make sure to learn the difference between the various
> Buildroot commands to build, clean, reconfigure, etc.
[1]: https://buildroot.org/downloads/manual/manual.html#_using_buildroot_during_development
+354
View File
@@ -0,0 +1,354 @@
# Scripting for Production Tests
This document shows how to set up and remotely script devices with a
focus on production testing.
## VLAN Snake
As part of production tests, verification of Ethernet ports is usually
expected. A common way for devices with multiple bridged Ethernet ports
is to connect a test PC to two ports and send a *ping* traversing all
ports. This can be achieved by using VLANs, on the switch, as described
in this section. The resulting configuration file can be applied to the
running configuration of the produced unit, e.g, use config file restore
as [described previously][2].
In this example we assume a 10 port switch, with ports e1-e10. The
following VLAN configuration and cable connections will be used:
| VLAN & Ports | Connect |
|:------------------|:----------|
| VLAN 10: e1 & e2 | e2 <=> e3 |
| VLAN 20: e3 & e4 | e4 <=> e5 |
| VLAN 30: e5 & e6 | e6 <=> e7 |
| VLAN 40: e7 & e8 | e8 <=> e9 |
| VLAN 50: e9 & e10 | |
The test PC is connected to e1 and e10 via different interfaces
(alternatively, two different PCs are used).
> [!TIP]
> Configuration here is done via console. When configuring remotely
> over SSH, remember to keep one IP address (the one used for the SSH
> connection)! I.e., set a static IP address first, then perform the
> VLAN configuration step.
## Configuration at Start
Starting out, we assume a configuration where all ports are network
interfaces (possibly with IPv6 enabled).
```
admin@example:/> show interfaces
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
e10 ethernet UP 00:53:00:06:11:0a
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
admin@example:/>
```
## Creating Bridge and Adding Ports
The following example [creates a bridge][8] and adds all Ethernet ports
to it. On a device with layer-2 offloading (switch fabric), this sets
all ports in the same VLAN. The next section sets up VLAN isolation.
```
admin@example:/> configure
admin@example:/config/> edit interface br0
admin@example:/config/interface/br0/> end
admin@example:/config/> set interface e1 bridge-port bridge br0
admin@example:/config/> set interface e2 bridge-port bridge br0
admin@example:/config/> set interface e3 bridge-port bridge br0
admin@example:/config/> set interface e4 bridge-port bridge br0
admin@example:/config/> set interface e5 bridge-port bridge br0
admin@example:/config/> set interface e6 bridge-port bridge br0
admin@example:/config/> set interface e7 bridge-port bridge br0
admin@example:/config/> set interface e8 bridge-port bridge br0
admin@example:/config/> set interface e9 bridge-port bridge br0
admin@example:/config/> set interface e10 bridge-port bridge br0
admin@example:/config/>
```
The interface status can be viewed using `show interfaces` after leaving
configuration context. When configuring via SSH, first assign an IP
address to `br0` *before leaving* configuration context, e.g.
```
admin@example:/config/> set interface br0 ipv6 enabled
```
This enables IPv6 SLAAC, auto-configured address. Or skip `leave` and
stay in configuration context until you have completed all the device
setup, including [setting IP address](#set-ip-address).
```
admin@example:/config/> leave
admin@example:/>
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN
├ e2 bridge LOWER-DOWN
├ e3 bridge LOWER-DOWN
├ e4 bridge LOWER-DOWN
├ e5 bridge LOWER-DOWN
├ e6 bridge LOWER-DOWN
├ e7 bridge LOWER-DOWN
├ e8 bridge LOWER-DOWN
├ e9 bridge LOWER-DOWN
└ e10 bridge FORWARDING
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
## Assign VLANs to Ports
Now, configure VLANs as outlined [previously](#vlan-snake): default VID
for ingress (PVID), which is done per port, and egress mode (untagged),
which is done at the bridge level. See the [VLAN bridges][9] section for
more information.
```
admin@example:/>
admin@example:/> configure
admin@example:/config/> set interface e1 bridge-port pvid 10
admin@example:/config/> set interface e2 bridge-port pvid 10
admin@example:/config/> set interface e3 bridge-port pvid 20
admin@example:/config/> set interface e4 bridge-port pvid 20
admin@example:/config/> set interface e5 bridge-port pvid 30
admin@example:/config/> set interface e6 bridge-port pvid 30
admin@example:/config/> set interface e7 bridge-port pvid 40
admin@example:/config/> set interface e8 bridge-port pvid 40
admin@example:/config/> set interface e9 bridge-port pvid 50
admin@example:/config/> set interface e10 bridge-port pvid 50
admin@example:/config/> edit interface br0
admin@example:/config/interface/br0/> edit bridge vlans
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e1
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e2
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e3
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e4
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e5
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e6
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e7
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e8
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e9
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e10
admin@example:/config/interface/br0/bridge/vlans/> leave
admin@example:/>
```
Interface status would now should something like the following
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
## Connect Cables and Test
We can now connect the PC to e1 and e10, while the other ports are
patched according to [above](#vlan-snake). We should see link up and
*FORWARDING* on all ports in the bridge.
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
Here we use IPv6 ping all hosts (ff02::1) on PC interface eth1 to
check reachability to the other interface of the PC.
> [!TIP]
> We recommend using network namespaces (Linux only) on the PC to ensure
> that traffic is actually sent out to the switch, rather than being
> looped back internally. Alternatively, use two separate PCs.
```
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.496 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.514 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.473 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.736 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.563 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.507 ms
^C
--- ff02::1%eth1 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5108ms
rtt min/avg/max/mdev = 0.473/0.548/0.736/0.088 ms
~ $
```
We can verify that traffic goes through the switch by disconnecting
one of the patch cables, e.g., between e4 and e5
```
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.510 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.448 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.583 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.515 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.521 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.495 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=7 ttl=64 time=0.743 ms
... Disconnecting patch cable, thus losing packets
... and reconnecting again. Connectivity resumes.
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=16 ttl=64 time=0.961 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=17 ttl=64 time=0.513 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=18 ttl=64 time=0.794 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=19 ttl=64 time=0.755 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=20 ttl=64 time=0.779 ms
^C
--- ff02::1%eth1 ping statistics ---
20 packets transmitted, 12 received, 40% packet loss, time 19432ms
rtt min/avg/max/mdev = 0.448/0.634/0.961/0.156 ms
~ $
```
## Set IP Address
The configuration so far does not provide a means to connect to the
switch management via SSH or NETCONF, as the switch has no IP address.
The example below shows how to add the switch to VLAN 10 (as used for
ports e1 and e2) and enables IPv6.
```
admin@example:/config/> edit interface vlan10
admin@example:/config/interface/vlan10/> set vlan lower-layer-if br0
admin@example:/config/interface/vlan10/> set ipv6 enabled
admin@example:/config/interface/vlan10/> show
type vlan;
ipv6 {
enabled true;
}
vlan {
tag-type c-vlan;
id 10;
lower-layer-if br0;
}
admin@example:/config/interface/vlan10/>
admin@example:/config/interface/vlan10/> end
admin@example:/config/> edit interface br0 bridge vlans
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 tagged br0
admin@example:/config/interface/br0/bridge/vlans/> leave
admin@example:/>
```
Interface *vlan10* with an auto-configured IPv6 address should appear.
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge vlan:10t
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
vlan10 ethernet UP 00:53:00:06:11:01
│ ipv6 fe80::0053:00ff:fe06:1101/64 (link-layer)
└ br0 ethernet UP 00:53:00:06:11:01
admin@example:/>
```
When pinging "IPv6 all hosts" from the PC, there should be two
responses for every ping, one from the switch and one from the PC
attached to e10.
```
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.508 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=1 ttl=64 time=0.968 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.866 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=2 ttl=64 time=0.867 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=3 ttl=64 time=0.467 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.469 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.452 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=4 ttl=64 time=0.453 ms
^C
--- ff02::1%eth1 ping statistics ---
4 packets transmitted, 4 received, +4 duplicates, 0% packet loss, time 3031ms
rtt min/avg/max/mdev = 0.452/0.631/0.968/0.211 ms
~ $
```
It should now be possible to access the switch from the PC via SSH (or NETCONF).
```
~ $ ssh admin@fe80::0053:00ff:fe06:1101%eth1
admin@fe80::0053:00ff:fe06:1101%eth1's password:
.-------.
| . . | Infix OS — Immutable.Friendly.Secure
|-. v .-| https://kernelkit.org
'-'---'-'
Run the command 'cli' for interactive OAM
admin@example:~$ exit
~ $
```
See previous sections on [backup][1] and [restore][2] of
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
+82
View File
@@ -0,0 +1,82 @@
# Examples using RESTCONF
## Factory Reset
```
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
https://example.local/restconf/operations/ietf-factory-default:factory-reset
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
```
## System Reboot
```
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
https://example.local/restconf/operations/ietf-system:system-restart
```
## Set Date and Time
Here's an example of an RPC that takes input/argument:
```
~$ curl -kX POST -u admin:admin \
-H "Content-Type: application/yang-data+json" \
-d '{"ietf-system:input": {"current-datetime": "2024-04-17T13:48:02-01:00"}}' \
https://example.local/restconf/operations/ietf-system:set-current-datetime
```
You can verify that the changes took by a remote SSH command:
```
~$ ssh admin@example.local 'date'
Wed Apr 17 14:48:12 UTC 2024
~$
```
## Read Hostname
Example of fetching JSON configuration data to stdout:
```
~$ curl -kX GET -u admin:admin \
-H 'Accept: application/yang-data+json' \
https://example.local/restconf/data/ietf-system:system/hostname
{
"ietf-system:system": {
"hostname": "foo"
}
}
```
## Set Hostname
Example of inline JSON data:
```
~$ curl -kX PATCH -u admin:admin \
-H 'Content-Type: application/yang-data+json' \
-d '{"ietf-system:system":{"hostname":"bar"}}' \
https://example.local/restconf/data/ietf-system:system
```
## Copy Running to Startup
No copy command available yet to copy between datastores, and the
Rousette back-end also does not support "write-through" to the
startup datastore.
To save running-config to startup-config, use the following example to
fetch running to a local file and then update startup with it:
```
~$ curl -kX GET -u admin:admin -o running-config.json \
-H 'Accept: application/yang-data+json' \
https://example.local/restconf/ds/ietf-datastores:running
~$ curl -kX PUT -u admin:admin -d @running-config.json \
-H 'Content-Type: application/yang-data+json' \
https://example.local/restconf/ds/ietf-datastores:startup
```
+467
View File
@@ -0,0 +1,467 @@
> [!NOTE]
> This method is a legacy "simple and human-friendly" way to manage the
> system. These days we strongly recommend using [RESTCONF][1] instead.
# Legacy Scripting
Although not the primary interface for Infix, it is possible to interact
with the system using raw [sysrepocfg][0] commands. This way you get to
interact directly with the YANG models when logged in to Infix. Thus, a
*set config*, *read config*, *read status* and an *RPC* can be conducted
using `sysrepocfg` for any supported YANG model.
See [sysrepocfg][0] for more information. Examples below will utilize:
- `sysrepocfg -I FILE -fjson -d DATABASE` to import/write a JSON
formatted configuration file to the specified database.
- `sysrepocfg -E FILE -fjson -d DATABASE` to edit/merge JSON formatted
configuration in FILE with the specified database.
- `sysrepocfg -R FILE -fjson` to execute remote procedure call (RPC)
defined in FILE (JSON formatted).
- `sysrepocfg -X -fjson -d DATABASE -x xpath` to read configuration or
status from specified database.
For importing (-I) and editing (-E), `-d running` is typically used in
examples below. Specify `-d startup` to apply changes to startup
configuration. Exporting (-X) could operate on configuration (e.g.,
`-d running`) or status (`-d operational`).
Some commands require a file as input. In the examples below we assume
it has been transferred to the device in advance, e.g. using `scp`:
```
~$ cat file.json
{
"ietf-factory-default:factory-reset": {
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$
```
## Factory Reset
```
~$ cat file.json
{
"ietf-factory-default:factory-reset": {
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
^C
~$
```
See [Factory Reset](scripting.md#factory-reset) for another (simpler)
alternative.
If it is only wished to copy factory config to running config the
following RPC is available
```
~$ cat file.json
{
"infix-factory-default:factory-default": {
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
^C
~$
```
## System Reboot
```
~$ cat /tmp/file.json
{
"ietf-system:system-restart": {
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
~$
```
See [System Reboot](scripting.md#system-reboot) for another (simpler)
alternative.
## Set Date and Time
```
~$ ssh admin@example.local 'date'
Sun Nov 20 10:20:23 UTC 2005
~$ cat file.json
{
"ietf-system:set-current-datetime": {
"current-datetime": "2024-04-17T13:48:02-01:00"
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
~$ ssh admin@example.local 'date'
Wed Apr 17 14:48:12 UTC 2024
~$
```
See [Set Date and Time](scripting.md#set-date-and-time) for another
(simpler) alternative.
## Remote Control of Ethernet Ports
Reading administrative status of interface *e0* of running configuration.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running -e report-all \
-x \"/ietf-interfaces:interfaces/interface[name='e0']/enabled\"'
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "e0",
"enabled": true
}
]
}
}
~$
```
> [!NOTE]
> Without `-e report-all` argument the line `"enabled: true` would not
> be shown as `true` is default.
```
~$ ssh admin@example.local "sysrepocfg -X -fjson -d running \
-x \"/ietf-interfaces:interfaces/interface[name='e0']/enabled\""
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "e0"
}
]
}
}
~$
```
Setting the administrative status of interface *e0* of running configuration.
```
$ cat file.json
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "e0",
"enabled": false
}
]
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
~$
```
## Enable/Disable DHCPv4 client
Enabling DHCPv4 client on interface *e0*, with current default options.
```
~$ cat /tmp/file.json
{
"infix-dhcp-client:dhcp-client": {
"enabled": true,
"client-if": [
{
"if-name": "e0"
}
]
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
~$
```
Disabling DHCPv4 client.
```
~$ cat /tmp/file.json
{
"infix-dhcp-client:dhcp-client": {
"enabled": false
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
~$
```
Configuration for client interface *e0* remains, but does not apply as
DHCPv4 is disabled.
```
admin@example:~$ sysrepocfg -X -fjson -d running -x "/infix-dhcp-client:dhcp-client"
{
"infix-dhcp-client:dhcp-client": {
"enabled": false,
"client-if": [
{
"if-name": "e0"
}
]
}
}
admin@example:~$
```
To fully remove the DHCPv4 client configuration or a specific
*client-if* with sysrepocfg, one would need to read out the full
configuration, remove relevant parts and read back.
## Enable/Disable IPv6
IPv6 is typically enabled on all interfaces by default. The example
below shows IPv4 and IPv6 addresses assigned on *e0*.
```
~$ ssh admin@example.local 'ip addr show dev e0'
2: e0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 scope global proto dhcp e0
valid_lft forever preferred_lft forever
inet6 fec0::ff:fe00:0/64 scope site dynamic mngtmpaddr proto kernel_ra
valid_lft 86380sec preferred_lft 14380sec
inet6 fe80::ff:fe00:0/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
~$
```
IPv6 is enabled/disabled per interface. The example below disables IPv6
on interface *e0*.
```
~$ cat /tmp/file.json
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "e0",
"ietf-ip:ipv6": {
"enabled": false
}
}
]
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
~$ ssh admin@example.local 'ip addr show dev e0'
2: e0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 scope global proto dhcp e0
valid_lft forever preferred_lft forever
~$
```
## Change a Binary Setting
A YANG `binary` type setting is Base64 encoded and requires a little bit
more tricks. We take the opportunity to showcase a shell script helper:
`/usr/bin/text-editor`, which works just like the `text-editor` command
in the CLI, but this one takes an XPath argument to the binary leaf to
edit.
Stripped down, it looks something like this:
```bash
if tmp=$(sysrepocfg -G "$xpath"); then
file=$(mktemp)
echo "$tmp" | base64 -d > "$file"
if edit "$file"; then
tmp=$(base64 -w0 < "$file")
sysrepocfg -S "$xpath" -u "$tmp"
fi
rm -f "$file"
else
echo "Failed to retrieve value for $xpath"
exit 1
fi
```
An example container configuration, with an embedded file that is
mounted to `/var/www/index.html` can look like this:
```json
"infix-containers:containers": {
"container": [
{
"name": "web",
"image": "oci-archive:/lib/oci/curios-httpd-latest.tar.gz",
"hostname": "web",
"network": {
"interface": [
{
"name": "veth-sys0"
}
]
},
"mount": [
{
"name": "index.html",
"content": "PCFET0NUWVBFIGh0bWwjibberish.shortened.down==",
"target": "/var/www/index.html"
}
]
}
]
}
```
The command to edit this file, and restart the container with the new
contents, look like this:
```
admin@infix:~$ cfg edit "/infix-containers:containers/container[name='web']/mount[name='index.html']/content"
```
## Backup Configuration
Displaying running or startup configuration is possible with
`sysrepocfg -X`, as shown below.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running'
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
...
~$
```
An example for backing up startup configuration from remote PC.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d startup > /tmp/backup.json'
~$ scp admin@example.local:/tmp/backup.json .
~$
```
Or possibly skip intermediate storage of file
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d startup' > backup.json
~$
```
A final example is to only use `scp`. This is simpler, but only works to
backup the startup configuration (not running).
```
~$ scp admin@example.local:/cfg/startup-config.cfg backup.json
~$
```
## Restore Configuration
To restore a backup configuration to startup, the simplest way is to use
`scp` and reboot as shown below
```
~$ scp admin@example.local:/cfg/startup-config.cfg backup.json
~$ ssh admin@example.local 'reboot'
Connection to switch.local closed by remote host.
~$
```
An alternative method to restore a backup configuration is to use the
`sysrepocfg -I FILE` (import) command.
The example below imports the backup configuration to startup, and
reboots the unit.
```
~$ scp backup.json admin@example.local:/tmp/
~$ ssh admin@example.local 'sudo sysrepocfg -I /tmp/backup.json -fjson -d startup'
~$ ssh admin@example.local 'reboot'
Connection to switch.local closed by remote host.
~$
```
> [!NOTE]
> The login credentials (hash) for the `admin` user are stored as part
> of the configuration file. When replacing a switch and applying the
> backed up configuration from the former switch, the password on the
> replacement unit will also change.
## Copy Running to Startup
The following command reads out the running config via `sysrepocfg -X`
and writes the result to the startup configuration.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running > /cfg/startup-config.cfg'
~$
```
An alternative is to write it to a temporary file, and use `sysrepocfg
-I` to import it to startup.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running > /tmp/running.json'
~$ ssh admin@example.local 'sysrepocfg -I /tmp/running.json -fjson -d startup'
~$
```
## Read Hardware Information
The IETF Hardware YANG model has been augmented for ONIE formatted
production data stored in EEPROMs, if available. For details, see the
[VPD documentation][2] and the *ietf-hardware* and *infix-hardware*
YANG models.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d operational -x /ietf-hardware:hardware'
{
"ietf-hardware:hardware": {
"component": [
{
"name": "product",
"class": "infix-hardware:vpd",
"serial-num": "12345",
"model-name": "Switch2010",
"mfg-date": "2024-01-30T16:42:37+00:00",
"infix-hardware:vpd-data": {
"product-name": "Switch2010",
"part-number": "ABC123-001",
"serial-number": "007",
"mac-address": "00:53:00:01:23:45",
"manufacture-date": "01/30/2024 16:42:37",
"num-macs": 11,
"manufacturer": "ACME Production",
"vendor": "SanFran Networks"
}
},
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked",
"oper-state": "enabled"
}
}
]
}
}
~$
```
[0]: https://netopeer.liberouter.org/doc/sysrepo/libyang1/html/sysrepocfg.html
[1]: scripting-restconf.md
[2]: vpd.md
+95 -985
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -1,4 +1,4 @@
## Syslog Support
# Syslog Support
The system comes with native logging to internal storage, `/var/log/`,
or `/log` for a shortcut. Depending on the device, this may be a RAM
@@ -13,7 +13,7 @@ sink), this is covered briefly at the very end of this document.
> a listing of existing native log files.
### Log to File
## Log to File
Logging to a local file is useful when combined with an external media.
E.g., a USB stick with a log partition (named/labeled: "log"). Below is
@@ -43,7 +43,7 @@ admin@example:/>
> that the filename is not already in use.
### Log Rotation
## Log Rotation
By default log files are allowed to grow to a size of 1 MiB after which
they are "rotated". The whole reason for this is to not fill up the
@@ -113,7 +113,7 @@ admin@example:/>
```
### Log Format
## Log Format
There are three major syslog log formats, the default is [RFC3164][] for
log files and BSD for remote logging. Depending on time synchronization
@@ -144,7 +144,7 @@ admin@example:/>
[RFC3164]: https://datatracker.ietf.org/doc/html/rfc3164
[RFC5424]: https://datatracker.ietf.org/doc/html/rfc5424
### Log to Remote Server
## Log to Remote Server
Logging to a remote syslog server is the recommended way of supervising
the system. This way all login attempts (console, SSH, or web) and any
@@ -176,7 +176,7 @@ admin@example:/>
> above can be found by tapping the Tab key.
### Acting as a Log Server
## Acting as a Log Server
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.
-432
View File
@@ -323,439 +323,7 @@ reference ID, stratum, time offsets, frequency, and root delay.
> The system uses `chronyd` Network Time Protocol (NTP) daemon. The
> output shown here is best explained in the [Chrony documentation][4].
## Upgrade procedures and boot order
For resilience purposes, Infix maintains two software
images referred to as the _primary_ and _secondary_ partition image.
In addition, some bootloaders support [netbooting][6].
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
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
admin@example:/>
```
YANG support for upgrading Infix, inspecting and _modifying_ the
boot-order, is defined in [infix-system-software][5].
### Upgrading Infix
Upgrading Infix is done one partition at a time. If the system has
booted from one partition, an `upgrade` will apply to the other
(inactive) partition.
1. Download and unpack the release to install. Make the image *pkg*
bundle available at some URL[^10]
2. (Optional) Backup the startup configuration
3. Assume the unit has booted the `primary` image. Then running the
`upgrade` command installs a new image on the `secondary`
partition
4. As part of a successful upgrade, the boot-order is implictly
changed to boot the newly installed image
5. Reboot the unit
6. The unit now runs the new image. To upgrade the remaining partition
(`primary`), run the same upgrade command again, and (optionally)
reboot to verify the upgrade
> [!CAUTION]
> During boot (step 5), the unit may
> [migrate](#configuration-migration) the startup configuration for
> any syntax changes. It is therefore important that you make sure to
> upgrade the other partition as well after reboot, of course after
> having verified your setup.
The CLI example below shows steps 2-5.
*Backup startup configuration:* It is recommended to backup the
startup configuration before performing an upgrade. The backup is
useful if the upgrade fails, and makes a later
[downgrade](#downgrading-infix) smoother to conduct.
```
admin@example:/> dir /cfg
/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
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
*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
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
98% Copying image to rootfs.1
99% Copying image to rootfs.1
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.03.1.pkg` succeeded
admin@example:/>
```
*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
[ OK ] Stopping Static routing daemon
[ OK ] Stopping Zebra routing daemon
...
[ OK ] Loading startup-config
[ OK ] Verifying self-signed https certificate
[ OK ] Update DNS configuration
[ OK ] Starting Status daemon
Infix OS — Immutable.Friendly.Secure v25.03.1 (ttyS0)
example login: admin
Password:
.-------.
| . . | Infix OS — Immutable.Friendly.Secure
|-. v .-| https://kernelkit.org
'-'---'-'
Run the command 'cli' for interactive OAM
admin@example:~$ cli
See the 'help' command for an introduction to the system
admin@example:/> show software
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
admin@example:/>
```
As shown, the *boot order* has been updated, so that *secondary* is
now the preferred boot source.
To upgrade the remaining partition (`primary`), run the `upgrade URL`
command again, and (optionally) reboot.
### Configuration Migration
The example above illustrated an upgrade from Infix v25.01.0 to
v25.03.1. Inbetween these versions, YANG configuration definitions
changed slightly (more details given below).
During boot, Infix inspects the `version` meta information within the
startup configuration file to determine if configuration migration is
needed. In this specific case, the configuration file has version
`1.4` while the booted software expects version `1.5` (the
configuration version numbering differs from the Infix image version
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/
/cfg/backup/ directory
startup-config-1.4.cfg
admin@example:/>
```
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
--- /cfg/backup/startup-config-1.4.cfg
+++ /cfg/startup-config.cfg
...
- "public-key-format": "ietf-crypto-types:ssh-public-key-format",
+ "public-key-format": "infix-crypto-types:ssh-public-key-format",
...
- "private-key-format": "ietf-crypto-types:rsa-private-key-format",
+ "private-key-format": "infix-crypto-types:rsa-private-key-format",
...
- "version": "1.4"
+ "version": "1.5"
...
admin@example:~$
```
### Downgrading Infix
Downgrading to an earlier Infix version is possible, however,
downgrading is **not** guaranteed to work smoothly. In particular,
when the unit boots up with the downgraded version, it may fail to
apply the *startup config*, and instead apply its [failure config][7].
We consider two cases: downgrading with or without applying a backup
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
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
admin@example:/>
```
#### Downgrading when applying a backup startup configuration
This is the recommended approach to downgrade, given that you have a
backup configuration available. The objective is to avoid ending up
with the unit in *failure config*.
1. Find the backup configuration file.
2. Run `upgrade URL` to install Infix image to downgrade to.
3. Copy backup startup configuration to current startup configuration
(from shell).
4. Reboot.
*Find the backup configuration file:*
Assume you have a backup startup config for the Infix version to
downgrade to (here Infix v25.01.0, config `version 1.4`).
The preferred approach is to use a startup configuration backed up
when running Infix v25.01.0 on the unit. See the section on [upgrading
Infix](#upgrading-infix) above for more information. In the example
below, there is a backup file available named
*v25.01.0-startup-config.cfg*
```
admin@example:/> dir /cfg
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
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/
/cfg/backup/ directory
startup-config-1.4.cfg
admin@example:/>
```
> [!CAUTION] Using a backup configuration file stored when the unit
> was running the old version (e.g., v25.01.0-startup-config.cfg) is
> preferred. Although backup files stored due to configuration
> migration (e.g., startup-config-1.4.cfg) usually works too if the
> configuration file version (`1.4`) matches, there are
> situations when the system may fail to apply it as described below.
The *configuration file version* (`1.4`) is only incremented when
changes in YANG configuration syntax mandates it to handle
*upgrading*. Say the next Infix version includes a new feature
setting, it can still have version `1.4`, as upgrading to it would not
need migration. If a user then enables the new feature setting, the
new configuration will no longer be compatible with the previous *Infix
version*. A downgrade after enabling new features risks ending up with
the unit in *failure config*.
*Use `upgrade` command to downgrade:*
```
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
admin@example:/>
```
*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
admin@example:/>
```
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
admin@example:/>
```
*Reboot:*
The unit will come up with the applied backup configuration.
```
admin@example:/> reboot
[ OK ] Saving system clock to file
[ OK ] Stopping Software update service
[ OK ] Stopping Status daemon
...
[ OK ] Bootstrapping YANG datastore
[ OK ] Starting Configuration daemon
[ OK ] Loading startup-config
[ OK ] Update DNS configuration
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
example login:
```
> [!NOTE]
> If the unit despite these measures ends up in *failure config*, see
> the next section for more information on how to recover.
#### Downgrading without applying a backup startup configuration
This procedure assumes you have access to the unit's console port and
its default login credentials[^9].
1. Downgrade
2. Reboot
3. Login with unit's default credentials
4. Conduct factory reset
5. (Then go on configure the unit as you wish)
*Use `upgrade` command to downgrade:*
```
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
admin@example:/>
```
*Reboot:*
Conduct a reboot. During boot, the unit fails to apply the existing
startup configuration (config version `1.5` while software expects
version `1.4` or earlier), and instead applies its [failure
config][7]. 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
[ OK ] Saving system clock to file
[ OK ] Stopping Software update service
[ OK ] Stopping Status daemon
...
[ OK ] Verifying SSH host keys
[ OK ] Bootstrapping YANG datastore
[ OK ] Starting Configuration daemon
[FAIL] Loading startup-config
[ OK ] Loading failure-config
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
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:
```
To remedy a situation like this, you can login with the unit's *default
login credentials*, preferrably via a [console port][8].
The unit's default credentials are typically printed on a sticker on
the unit.
```
failed-00-00-00 login: admin
Password:
Run the command 'cli' for interactive OAM
admin@failed-00-00-00:~$
```
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
factory: scheduled factory reset on next boot.
Reboot now to perform reset, (y/N)? y
[ OK ] Saving system time (UTC) to RTC
[ OK ] Stopping mDNS alias advertiser
...
[ OK ] Starting Configuration daemon
[ OK ] Loading startup-config
[ OK ] Update DNS configuration
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
[ OK ] Starting Status daemon
Please press Enter to activate this console.
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
example login:
```
Continued configuration is done as with any unit after factory reset.
[1]: https://www.rfc-editor.org/rfc/rfc7317
[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://github.com/kernelkit/infix/blob/main/src/confd/yang/confd/infix-system-software.yang
[6]: netboot.md
[7]: introduction.md#system-boot
[8]: management.md#console-port
[^9]: In failure config, Infix puts all Ethernet ports as individual
interfaces. With direct access, one can connect with e.g., SSH,
using link local IPv6 addresses. This as an alternative to
connecting via a console port.
[^10]: Set up an FTP/TFTP/SFTP or HTTP/HTTPS server on the same LAN.
[11]: scripting.md#-backup-configuration-using-sysrepocfg-and-scp
+23
View File
@@ -0,0 +1,23 @@
<article id="doc-cover">
{% if cover_logo is defined %}
<div class="wrapper upper">
<img src="{{ cover_logo | to_url }}" alt="Logo" class="logo">
</div>
{% else %}
<div class="wrapper"></div>
{% endif %}
<div class="wrapper">
<h2>{{ cover_subtitle | e }}</h2>
<div class="divider"></div>
<h1>{{ cover_title | e }}</h1>
</div>
<div class="properties">
<address>
{% if copyright is defined %}
<p id="copyright">{{ copyright | e }}</p>
{% endif %}
</address>
</div>
</article>
+148
View File
@@ -0,0 +1,148 @@
// Override plugin defaults with !important to ensure our styles take precedence
article#doc-cover {
display: flex !important;
flex-direction: column !important;
height: 100vh !important;
text-align: center !important;
padding: 20px !important;
}
article#doc-cover > .wrapper.upper {
flex: 0 0 120px !important;
text-align: center !important;
margin-bottom: 20px !important;
max-height: none !important;
}
// Simple img tag approach for centered logo
article#doc-cover > .wrapper.upper > img.logo {
width: 360px !important;
height: auto !important; // Maintains aspect ratio automatically
display: block !important;
margin: 250px auto 0 auto !important;
padding: 0;
}
article#doc-cover > .wrapper h1 {
font-size: 52px !important;
margin: 0 auto 0 auto !important;
color: #808080 !important;
border-bottom: none !important;
}
// Copyright text on cover page should match logo grey color
article#doc-cover .properties address p#copyright {
color: #808080 !important;
}
article#doc-cover > .wrapper h2 {
font-size: 28px !important;
color: #808080 !important;
margin: 0 !important;
}
article#doc-cover .divider {
width: 150px !important;
height: 3px !important;
background: #ff7f2a !important;
margin: 20px auto !important;
border: none !important;
}
// Proper heading hierarchy for 12pt base text (print standards)
h1 {
color: black !important;
font-size: 24pt !important; // 2.0x base text
line-height: 1.2 !important;
margin-top: 24pt !important;
margin-bottom: 12pt !important;
}
h2 {
color: black !important;
font-size: 20pt !important; // 1.67x base text
line-height: 1.3 !important;
margin-top: 20pt !important;
margin-bottom: 10pt !important;
}
h3 {
color: black !important;
font-size: 16pt !important; // 1.33x base text
line-height: 1.3 !important;
margin-top: 16pt !important;
margin-bottom: 8pt !important;
}
h4 {
color: black !important;
font-size: 14pt !important; // 1.17x base text
line-height: 1.4 !important;
margin-top: 14pt !important;
margin-bottom: 7pt !important;
}
h5, h6 {
color: black !important;
font-size: 13pt !important; // 1.08x base text
line-height: 1.4 !important;
margin-top: 12pt !important;
margin-bottom: 6pt !important;
}
article h1 {
border-bottom: 2px solid #ff7f2a;
}
article h2 {
border-bottom: 1px solid #ff7f2a;
}
article h3 {
border-bottom: 0.5px solid #ff7f2a;
}
// Set base font size to 12pt for all content
body, article {
font-size: 12pt !important;
line-height: 1.6 !important;
}
// Ensure paragraphs use 12pt
p {
font-size: 12pt !important;
line-height: 1.6 !important;
}
// Code blocks and inline code should be 10pt
pre, code, var, samp, kbd, tt {
font-size: 10pt !important;
}
// Override any nested code font sizes
pre code, pre var, pre samp, pre kbd, pre tt {
font-size: 10pt !important;
}
// Lists should also use 12pt
ul, ol, li {
font-size: 12pt !important;
}
// Table content can be smaller to fit all details
table, td, th {
font-size: 10pt !important;
}
// Override the tiny @page header/footer fonts to be more readable
@page {
@top-right {
font-size: 10pt !important;
}
@bottom-center {
font-size: 10pt !important;
}
@bottom-right {
font-size: 10pt !important;
}
}
+429
View File
@@ -0,0 +1,429 @@
# Upgrading & Boot Order
For resilience purposes, Infix maintains two software images referred to
as the _primary_ and _secondary_ partition image. In addition, some
bootloaders support [netbooting][1].
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
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
admin@example:/>
```
YANG support for upgrading Infix, inspecting and _modifying_ the
boot-order, is defined in [infix-system-software][2].
## Upgrading
Upgrading Infix is done one partition at a time. If the system has
booted from one partition, an `upgrade` will apply to the other
(inactive) partition.
1. Download and unpack the release to install. Make the image *pkg*
bundle available at some URL[^2]
2. (Optional) Backup the startup configuration
3. Assume the unit has booted the `primary` image. Then running the
`upgrade` command installs a new image on the `secondary` partition
4. As part of a successful upgrade, the boot-order is implictly
changed to boot the newly installed image
5. Reboot the unit
6. The unit now runs the new image. To upgrade the remaining partition
(`primary`), run the same upgrade command again, and (optionally)
reboot to verify the upgrade
> [!CAUTION]
> During boot (step 5), the unit may [migrate](#configuration-migration)
> the startup configuration for any syntax changes. It is therefore
> important that you make sure to upgrade the other partition as well
> after reboot, of course after having verified your setup.
The CLI example below shows steps 2-5.
*Backup startup configuration:* It is recommended to backup the startup
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
/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
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
*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
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
98% Copying image to rootfs.1
99% Copying image to rootfs.1
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.03.1.pkg` succeeded
admin@example:/>
```
*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
[ OK ] Stopping Static routing daemon
[ OK ] Stopping Zebra routing daemon
...
[ OK ] Loading startup-config
[ OK ] Verifying self-signed https certificate
[ OK ] Update DNS configuration
[ OK ] Starting Status daemon
Infix OS — Immutable.Friendly.Secure v25.03.1 (ttyS0)
example login: admin
Password:
.-------.
| . . | Infix OS — Immutable.Friendly.Secure
|-. v .-| https://kernelkit.org
'-'---'-'
Run the command 'cli' for interactive OAM
admin@example:~$ cli
See the 'help' command for an introduction to the system
admin@example:/> show software
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
admin@example:/>
```
As shown, the *boot order* has been updated, so that *secondary* is
now the preferred boot source.
To upgrade the remaining partition (`primary`), run the `upgrade URL`
command again, and (optionally) reboot.
## Configuration Migration
The example above illustrated an upgrade from Infix v25.01.0 to
v25.03.1. Inbetween these versions, YANG configuration definitions
changed slightly (more details given below).
During boot, Infix inspects the `version` meta information within the
startup configuration file to determine if configuration migration is
needed. In this specific case, the configuration file has version
`1.4` while the booted software expects version `1.5` (the
configuration version numbering differs from the Infix image version
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/
/cfg/backup/ directory
startup-config-1.4.cfg
admin@example:/>
```
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
--- /cfg/backup/startup-config-1.4.cfg
+++ /cfg/startup-config.cfg
...
- "public-key-format": "ietf-crypto-types:ssh-public-key-format",
+ "public-key-format": "infix-crypto-types:ssh-public-key-format",
...
- "private-key-format": "ietf-crypto-types:rsa-private-key-format",
+ "private-key-format": "infix-crypto-types:rsa-private-key-format",
...
- "version": "1.4"
+ "version": "1.5"
...
admin@example:~$
```
## Downgrading
Downgrading to an earlier version is possible, however, downgrading is
**not** guaranteed to work smoothly. In particular, when the unit boots
up with the downgraded version, it may fail to apply the *startup
config*, and instead apply its [failure config][3].
We consider two cases: downgrading with and without applying a backup
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
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
admin@example:/>
```
### With Backup `startup-config`
This is the recommended approach to downgrade, given that you have a
backup configuration available. The objective is to avoid ending up
with the unit in *failure config*.
1. Find the backup configuration file
1. Run `upgrade URL` to install Infix image to downgrade to
1. Copy backup startup configuration to current startup configuration
(from shell)
1. Reboot
*Find the backup configuration file:*
Assume you have a backup startup config for the Infix version to
downgrade to (here Infix v25.01.0, config `version 1.4`).
The preferred approach is to use a startup configuration backed up when
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
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
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/
/cfg/backup/ directory
startup-config-1.4.cfg
admin@example:/>
```
> [!CAUTION]
> Using a backup configuration file stored when the unit was running the
> old version (e.g., v25.01.0-startup-config.cfg) is preferred. Although
> backup files stored due to configuration migration (e.g.,
> `startup-config-1.4.cfg`) usually works too if the configuration file
> version (`1.4`) matches, there are situations when the system may fail
> to apply it as described below.
The *configuration file version* (`1.4`) is only incremented when
changes in YANG configuration syntax mandates it to handle *upgrading*.
Say the next Infix version includes a new feature setting, it can still
have version `1.4`, as upgrading to it would not need migration. If a
user then enables the new feature setting, the new configuration will no
longer be compatible with the previous *Infix version*. A downgrade
after enabling new features risks ending up with the unit in *failure
config*.
*Use `upgrade` command to downgrade:*
```
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
admin@example:/>
```
*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
admin@example:/>
```
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
admin@example:/>
```
*Reboot:*
The unit will come up with the applied backup configuration.
```
admin@example:/> reboot
[ OK ] Saving system clock to file
[ OK ] Stopping Software update service
[ OK ] Stopping Status daemon
...
[ OK ] Bootstrapping YANG datastore
[ OK ] Starting Configuration daemon
[ OK ] Loading startup-config
[ OK ] Update DNS configuration
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
example login:
```
> [!NOTE]
> If the unit despite these measures ends up in *failure config*, see
> the next section for more information on how to recover.
### Without a Backup `startup-config`
This procedure assumes you have access to the unit's console port and
its default login credentials[^1].
1. Downgrade
1. Reboot
1. Login with unit's default credentials
1. Conduct factory reset
1. (Then go on configure the unit as you wish)
*Use `upgrade` command to downgrade:*
```
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.01.0.pkg
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
...
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
Installing `tftp://198.18.117.1/infix-aarch64-25.01.0.pkg` succeeded
admin@example:/>
```
*Reboot:*
Conduct a reboot. During boot, the unit fails to apply the existing
startup configuration (config version `1.5` while software expects
version `1.4` or earlier), and instead applies its [failure
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
[ OK ] Saving system clock to file
[ OK ] Stopping Software update service
[ OK ] Stopping Status daemon
...
[ OK ] Verifying SSH host keys
[ OK ] Bootstrapping YANG datastore
[ OK ] Starting Configuration daemon
[FAIL] Loading startup-config
[ OK ] Loading failure-config
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
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:
```
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
Password:
Run the command 'cli' for interactive OAM
admin@failed-00-00-00:~$
```
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
factory: scheduled factory reset on next boot.
Reboot now to perform reset, (y/N)? y
[ OK ] Saving system time (UTC) to RTC
[ OK ] Stopping mDNS alias advertiser
...
[ OK ] Starting Configuration daemon
[ OK ] Loading startup-config
[ OK ] Update DNS configuration
[ OK ] Verifying self-signed https certificate
[ OK ] Starting Status daemon
[ OK ] Starting Status daemon
Please press Enter to activate this console.
Infix OS — Immutable.Friendly.Secure v25.01.0 (ttyS0)
example login:
```
Continued configuration is done as with any unit after factory reset.
[1]: netboot.md
[2]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/confd/infix-system-software.yang
[3]: boot.md#system-boot
[4]: management.md#console-port
[5]: scripting.md#-backup-configuration-using-sysrepocfg-and-scp
[^1]: In failure config, Infix puts all Ethernet ports as individual
interfaces. With direct access, one can connect with e.g., SSH,
using link local IPv6 addresses. This as an alternative to
connecting via a console port.
[^2]: Set up an FTP/TFTP/SFTP or HTTP/HTTPS server on the same LAN.
+4 -4
View File
@@ -1,5 +1,5 @@
Infix in Virtual Environments
=============================
Virtual Environments
=====================
Infix primarily targets real hardware, deployment to the cloud is not a
priority at the moment. However, for development and testing purposes
@@ -33,8 +33,8 @@ from a pre-built Infix release tarball, using <kbd>./qemu.sh -c</kbd>
The Infix test suite is built around Qemu and [Qeneth][qeth], see:
* [Testing](testing.md)
* [Docker Image](../test/docker/README.md)
* [Regression Testing with Infamy](testing.md)
* [Infamy Docker Image](https://github.com/kernelkit/infix/blob/main/test/docker/README.md)
GNS3
+11 -10
View File
@@ -74,12 +74,13 @@ encoded strings is a decision imposed by Infix; the ONIE specification
allows for arbitrary binary data.
**Example**:
```json
{
...
"vendor-extension": [
[ 12345, "my extension data" ]
]
...
"vendor-extension": [
[ 12345, "my extension data" ]
]
}
```
@@ -102,12 +103,13 @@ Since the extension is itself stored in a JSON document, it has to be
appropriately quoted.
**Example**:
```json
{
...
"vendor-extension": [
[ 61046, "{\"pwhash\":\"$6$9rufAxdqCrxrwfQR$G0l9cTVlu/vOhxgo/uMKfRDOmZRd5XWF3vKr5da6qYoxuTJBS/Pl9K.5lrabWoWFFc.71yFMaSlZz0O8FtAtl.\"}" ]
]
...
"vendor-extension": [
[ 61046, "{\"pwhash\":\"$6$9rufAxdqCrxrwfQR$G0l9cTVlu/vOhxgo/uMKfRDOmZRd5XWF3vKr5da6qYoxuTJBS/Pl9K.5lrabWoWFFc.71yFMaSlZz0O8FtAtl.\"}" ]
]
}
```
@@ -152,9 +154,8 @@ binary in its equivalent JSON representation:
}
```
[oniespec]: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html
[onieprom]: ../board/common/rootfs/bin/onieprom
[onieprom]: https://github.com/kernelkit/infix/blob/main/board/common/rootfs/usr/bin/onieprom
[driver]: https://elixir.bootlin.com/linux/latest/source/drivers/nvmem/layouts/onie-tlv.c
[pens]: https://www.iana.org/assignments/enterprise-numbers/
[kkit]: https://github.com/kernelkit
+135
View File
@@ -0,0 +1,135 @@
site_name: User's Guide
site_description: Infix Documentation
site_url: https://kernelkit.github.io/infix/
repo_url: https://github.com/kernelkit/infix/
repo_name: kernelkit/infix
copyright: Copyright &copy; 2022-2025 The KernelKit Team
docs_dir: doc/
edit_uri: edit/master/doc/
extra_css:
- extra.css
exclude_docs: |
ChangeLog.md
cli/README.md
README.md
TODO.org
nav:
- Introduction: index.md
- CLI:
- Introduction: cli/introduction.md
- Configuration: cli/configure.md
- Keybindings: cli/keybindings.md
- Network Calculator: cli/netcalc.md
- Network Monitoring: cli/tcpdump.md
- Quickstart Guide: cli/quick.md
- Text Editor: cli/text-editor.md
- Upgrading: cli/upgrade.md
- Docker Containers: container.md
- Networking:
- Network Configuration: networking.md
- Quality of Service: qos.md
- RMON Counters: eth-counters.md
- Tunneling (L2/L3): tunnels.md
- Wireless LAN (WiFi): wifi.md
- Services:
- Device Discovery: discovery.md
- DHCP Server: dhcp.md
- System:
- Boot Procedure: boot.md
- Configuration: system.md
- Hardware Info & Status: hardware.md
- Management: management.md
- Syslog Support: syslog.md
- Upgrade: upgrade.md
- Scripting:
- Introduction: scripting.md
- Legacy Scripting: scripting-sysrepocfg.md
- Production Testing: scripting-prod.md
- Remote RESTCONF: scripting-restconf.md
- Developer's Corner:
- Branding & Releases: branding.md
- Developer's Guide: developers-guide.md
- Developing with Buildroot: override-package.md
- Netboot HowTo: netboot.md
- Regression Testing: testing.md
- Test System Architecture: test-arch.md
- Virtual Environments: virtual.md
- Vital Product Data (VPD): vpd.md
- Origin & Licensing: license.md
theme:
logo: logo-plain.png
name: material
features:
- toc.follow
# - toc.integrate
- navigation.path
- navigation.instant
- navigation.instant.progress
- navigation.tracking
- navigation.indexes
# - navigation.tabs
# - navigation.sections
# - navigation.expand
# - navigation.top
# - navigation.footer
- search.highlight
- search.share
# - content.action.edit
- content.code.copy
- content.code.annotate
- content.footnote.tooltips
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: orange
accent: orange
toggle:
icon: material/weather-night
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: black
accent: orange
toggle:
icon: material/weather-sunny
name: Switch to light mode
markdown_extensions:
- admonition
- attr_list
- footnotes
- pymdownx.details
- pymdownx.superfences
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.tabbed:
alternate_style: true
- tables
- toc:
permalink: true
plugins:
- search
- callouts
- mike
- to-pdf:
cover: true
enabled_if_env: PDF_EXPORT
cover_logo: logo-plain.png
cover_subtitle: Immutable.Friendly.Secure
custom_template_path: doc/templates
output_path: pdf/infix-user-guide.pdf
toc_level: 2
ordered_chapter_level: 3
heading_shift: false
extra:
generator: false
homepage: https://kernelkit.org/
version:
provider: mike