mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 07:33:01 +02:00
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:
@@ -24,7 +24,6 @@ on:
|
||||
default: kernelkit/infix
|
||||
type: string
|
||||
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
target:
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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.
|
||||
|
||||

|
||||
|
||||
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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
------------
|
||||
{ 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.
|
||||
|
||||
{ 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>
|
||||
{ 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
@@ -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. Don’t 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. Don’t 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
@@ -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
@@ -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` |
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
# Introduction
|
||||
|
||||
{ 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 1.7 KiB |
+1
-1
@@ -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 |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 18 KiB |
+187
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -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
@@ -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
|
||||
|
||||
Vendored
+23
@@ -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>
|
||||
Vendored
+148
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 © 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
|
||||
Reference in New Issue
Block a user