Compare commits

...
Author SHA1 Message Date
Tobias Waldekranz 257f1df1d5 test: case: user_scripts: Add test
Verify that:
- Scripts are executed when the service is enabled
- Scripts are not enabled when the service is disabled
2024-05-21 22:02:28 +02:00
Tobias Waldekranz 8664c27096 confd: Add support for running user scripts
Add a new service that, when enabled, will execute run-parts on
`/cfg/user-scripts.d`.

This strikes a balance between two conflicting objectives:

1. There should be no implicit way to schedule arbitrary code
   execution on the device, i.e. no default run-parts directory.

2. It is very useful to have a way of scheduling arbitrary code
   execution on the device, e.g. being able to install a debug script
   on a production image.

With this feature, we still meet (1), since the feature has to be
explicitly enabled in the startup-config; but we also fulfill (2),
since we can easily enable it when needed.
2024-05-21 22:02:28 +02:00
Joachim Wiberg c7c1b5b12d .github: build aarch64 target as well in regression workflow
- Add aarch64 to build matrix on Reggie
 - Rename platform -> target in all workflows

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-21 10:10:16 +02:00
Joachim Wiberg 2f4cdd0d9c Fix 'ip addr show proto NAME'
- Add support for proto by name in ip addr show
 - Add missing static protos, needed for show

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-21 09:00:10 +02:00
Joachim Wiberg f1e7fda956 doc: revise developer's guide a bit wrt. packge overrides
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-21 09:00:10 +02:00
Tobias Waldekranz 7bb48ece49 test: Reinstate podman as default runner
Partial revert of 23469bbe3b. When running tests in a GitHub action,
we do not want to run as host root user. Therefore, restore podman as
the default runner, but make sure to prefer docker when attaching to
the host network namespace.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 508e2287b8 doc: testing: Sync documentation with latest changes
Update docs to match the recent developments in the test system.

Spin off the architecture description to its own document, and focus
testing.md on the day-to-day usage.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 03d48e9aab test: Unify the different test modes to a smaller number of targets
Now that tests in the host's network namespce can be run inside the
container, simplify test.mk for increased reusability.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz d7c41489e0 test: Always run tests inside container
When we want to test a `make run` instance, or a physical topology,
start the docker in the host's network namespace instead.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 897faf08d9 qemu: Fix off-by-one in topology generation
When interface naming switched to use 1-based indices instead of
0-based, the topology generation was overlooked thus breaking tests
against a `make run` instance.

Bring everything back in sync.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 3ad20dfd5b test: Drop support for running tests with podman
When testing in the host's namespace, only docker seems to offer the
required capabilities (due to its daemon/client architecture).

Qeneth tests can still be run in podman. Users will have to install
the docker wrappers for podman to make use of this.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 3f2ae3f3fc test: case: igmp_basic: Speed up positive reception tests
Use must{,_not}_receive instead of the general sniffer, so that we can
continue the test as soon as we see the transmission at the receiver,
rather than always waiting the full 5s.

While we're here:
- Show the port mappings in the top block-comment
- Define a few more steps to show the user what is going on
2024-05-20 16:21:06 +02:00
Tobias Waldekranz f94815cf46 test: case: static_multicast_filters: Speed up positive reception tests
Use must{,_not}_receive instead of the general sniffer, so that we can
continue the test as soon as we see the transmission at the receiver,
rather than always waiting the full 5s.

While we're here:
- Show the port mappings in the top block-comment
- Define a few more steps to show the user what is going on
- Avoid global variable references in set_static_multicast_filter()
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 2190c3bc52 test: netns: Add must{,_not}_receive
In test cases, it is common that we want to verify that a certain type
of traffic reaches a namespace. This has, up to this point, been
solved by the generic sniffer.Sniffer.

Try to improve the two most common use-cases...
1. Test if a flow reaches a namespace
2. Ensure that a flow does not reach a namespace
...by always exiting as soon as the first packet is received.

This saves time on positive tests, and the synchronous API allows it
to compose well with infamy.parallel().
2024-05-20 16:21:06 +02:00
Tobias Waldekranz e65625e32f test: Add support for attaching to devices via SSH
Support the familiar subprocess.run API, and runsh from netns.py.

This should only be used for debugging, or in the rare instances when
we want to test functionality that is not available via NETCONF.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz af65bbe7f9 test: furl: Cap time spent waiting for HTTP requests
Without an explicit timeout, urllib will wait indefinitely for a
connection to be made.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 1dbe09b428 test: Spellchecking 2024-05-20 16:21:06 +02:00
Tobias Waldekranz 232c2329af test: netns: Let the default ping timeout be tuned in the topology
QEMU systems seem work fine with the 5s timeout, whereas some physical
devices can't quite keep up with that.

Let the slower systems indicate that they need a bit more time without
punishing faster ones with a longer default.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 772019db22 test: env: Add support for querying global attributes
This will let other Infamy submodules tune their behavior based on the
particular test system they are running on.

Attributes are defined by creating graph-global attributes with an
"ix_" prefix.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 52c6c2274e test: topology: Add helper to retrieve graph-global attributes
This will allow us to define attributes that are specific to a
particular test system.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz e53f3362be test: case: routing_basic: Restructure to reuse existing namespace
Rather than setting up and tearing down two identical namespaces,
create it once and use it for the duration of the test.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz c3945a996c test: case: static_routing: Restructure to reuse existing namespace
Rather than setting up and tearing down two identical namespaces,
create it once and use it for the duration of the test. (This is
probably a documentation issue with Infamy: there is no requirement
that test.steps are direct descendants of the test, but until this
point there was no example of this in the source base)

In the process of this, it was also discovered that no positive ping
test was done over v6, so that has been added.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz c2d357a185 test: Use stable MAC addresses when creating MACVLANs
To work around the issue detailed in the method's doc comment.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 74b0679cf0 test: case: container_*: Use standard ping tests 2024-05-20 16:21:06 +02:00
Tobias Waldekranz dc6dffbff9 test: case: bridge_*: Use standard ping tests 2024-05-20 16:21:06 +02:00
Tobias Waldekranz 4c6dfdf600 test: Run negative ping tests in parallel
Rather than having to wait for each timeout sequentially, run each
test in parallel.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz b62fd627f0 test: Never buffer output
Avoid having log messages stuck in a pipe when stdout is not a tty,
e.g. when running a suite of tests using 9pm.

Two benefits:
- Nicer experience when interactively running a suite
- Timestamps inserted by 9pm are more useful
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 177b65587b test: case: routing_basic: Remove bridge from figure
This a routed setup, no bridge is used.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz b5679aa603 test: Improve robustness of pinging from within namespaces
It turns out that the semantics of ping's -c option does not match our
expectations. The manual says:

> Stop after sending count ECHO_REQUEST packets. With deadline option,
> ping waits for count ECHO_REPLY packets, until the timeout expires.

But in fact, something like an ICMP_DEST_UNREACH will also count as a
response, meaning that the process will terminate with non-zero
exitcode even though the deadline has not yet been crossed, rather
than keep waiting for an ECHO_REPLY.

To add some extra flavor: this is only the case for iputils' ping,
Busybox's implementation will hold out for a response until the
deadline expires.

Therefore, wrap the ping in an ugly retry loop.

Also, return the full available context from must{,_not}_reach on
failures, instead of just the output. This allows us to show the exit
code in the top-level exception handler.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz fb2bd2c2b7 test: Whitespace cleanup 2024-05-20 16:21:06 +02:00
Tobias Waldekranz b9907fa7ae test: Add nsenter helper script to enter Infamy namespaces
When a test starts an isolated MACVLAN namespace, it is often useful
to interactively join that namespace to investigate issues. To do
this, we need to find the "sleeper" process backing the namespace, and
`nsenter` into that process's network namespace.

Add a script that automates this process.

To start a shell in the netns of the MACVLAN stacked on top of d1b,
start a shell in the test environment:

    infix/test $ ./shell
    13:37:00 infamy0:test # ./nsenter d1b
    13:37:01 infamy0(netns:d1b):test #
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 7d6792a638 test: Always log logical-to-physical mappings
For tests using a logical topology, log the resulting mapping to the
physical one. This way, we always have a record of the entire
environment.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz b6cf866f52 test: Log the output of failing subprocesses
It is not uncommon for subprocesses to fail when developing new tests,
but the default representation of CalledProcessError does not print
the stdout of the program, only that it failed.

Catch this common case when a test is about to fail, and make sure to
log any output it produced.
2024-05-20 16:21:06 +02:00
Tobias Waldekranz 2c72aaf6e1 test: Move all test related targets from board/x86_64 to test/
The list of binaries needed inside the test environment is the only
architecture specific bit, so refactor that out to a separate
variable.
2024-05-20 16:21:06 +02:00
Tobias WaldekranzandJoachim Wiberg b5f2252650 kernel: Latest fixes
- Add missing locking around standard counter groups
- Fix reference counting issue with IGMPv3/MLDv2 reports

Found as part of debugging the regression test suite on hardware.
2024-05-20 16:15:23 +02:00
Joachim Wiberg ca026a37fc Add link to Latest Build
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-18 12:11:37 +02:00
Joachim WibergandTobias Waldekranz abd8621e92 doc: split container host interface, add w/ phys-address example
The container host interface text was a bit hard to understand.  This
patch splits it up in two parts, basic routed setup and an advanced
with two interfaces.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-18 09:58:19 +02:00
Joachim WibergandTobias Waldekranz 0df778a5f6 confd: fix custom mac support for veth interfaces
This patch adds support for setting the mac address already when
creating veth interfaces.  Necessary to cooperate with containers.

Fixes #453

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-18 09:58:19 +02:00
Joachim WibergandTobias Waldekranz 0a7f8ce216 confd: always create factory bridges with multicast snooping enabled
The confd `gen-interfaces` script is called for some customers with a
default to create a bridge with all, or a subset of all, ports.  The
safe default, which incidentally coincides with the same customer's
requirements, is to have IGMP/MLD snooping enabled by default.

Fixes #454

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-18 09:58:19 +02:00
Joachim WibergandTobias Waldekranz 7e2d433857 Prepare ChangeLog for next release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-18 09:58:19 +02:00
Joachim Wiberg 413470569e doc: clarify with before and after
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-17 16:54:09 +02:00
Joachim Wiberg b2adf639ff doc: initial section on developing new features for confd
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-17 16:42:06 +02:00
Joachim Wiberg 3ac1dfbf4c .github: ensure clean and recursive submodules
Minor change, mostly for consistency across repos.

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-17 14:38:57 +02:00
Joachim Wiberg 975a7b466c .github: introduce issue templates
We already have a pull request template.  This is a propsal to add issue
templates as well.  These yml templates change the behavior of reporting
issues to more a of a pre-formatted form with guard rails.

It is still possible to report blank issues the old way.

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-16 13:32:35 +02:00
Joachim Wiberg bdefe9452c .github: revise and update contributing guidelines
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-16 13:32:35 +02:00
Joachim Wiberg 9211fba6d5 .github: simplify pull-request template slightly
Referencing/Linking to issues is now supported in the GitHub GUI.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-16 13:32:35 +02:00
Joachim Wiberg 1d58d2058d package/gencert: declare dependency on pkg-config and libopenssl
Plain openssl is a meta-package, gencert requires libopenssl v3.x and
later, and use pkg-config to detect its presence.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-16 13:32:35 +02:00
Joachim WibergandMattias Walström 23dc237403 Switch to PAM for system authentication
- Add sshd 'UsePAM yes'
 - Buildroot automatically adds and enables:
   - /etc/pam.d/ with authentication for login, sshd, and sudo
   - PAM support in BusyBox login

Also, prepare for adding RADIUS authentication support to ietf-system
the only tricky part is testing against a RADIUS server.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-15 16:06:08 +02:00
Joachim Wiberg 406dbfdff4 Update release date for v24.04.2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 15:50:12 +02:00
Joachim WibergandTobias Waldekranz 9d7817356f statd: support for enabling DEBUG() logs with env, like confd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 16c21f0da8 doc: update ChangeLog for v24.04.2 patch release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz aa20f29b36 confd: fix missing /etc/resolv.conf after 'no system'
When a CLI user performs the following command, the DNS resolver was
left in an undefined state.

    admin@infix-00-00-00:/config/> no system
    admin@infix-00-00-00:/config/> leave
    admin@infix:/>

The avahi-daemon reported the missing /etc/resolv.conf and the fix is to
ensure `resolvconf -u` runs on every major change ot ietf-system, even
if there is no new resolv.conf to roll in.  At bootstrap this has been
handled by another mechanism so has not been seen by most users.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz c6b818d0bc confd: fix error handling for sr_get_data()
The sr_get_data() API may return SR_ERR_OK and still set the cfg pointer
to NULL!  This happens when, e.g., executing 'no system' from the CLI.

This patch adds a check for this in all occurrences of sr_get_data().

Also, in ietf-routing.c there was *no* error handling for this API, this
required some restructuring to ensure a FILE *fp was closed properly in
all cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 89c9a12db2 confd: on failure to load startup-config, reset and regroup
With the sysrepo patch from the previous commit, we can now properly
detect if a callback failed to apply its changes in SR_EV_DONE.  When
this occurs the system may be in an undefined state, so we must try
to recover it before loading failure-config.

This patch tries to perform a factory-default RPC, which is an Infix
specifc RPC that does "copy factory-config running-config".  We give
sysrepocfg some time to clean up any stale SHM connections before we
do a hard scratch of the db state and restart sysrepo-plugind.

Fixes #429

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 9df97d9a1b patches/sysrepo: add support for non-zero exit code from syrepocfg
This local patch of sysrepo adds support for detecting non-zero return
code from sysrepo callbacks during SR_EV_DONE, which upstream sysrepo
currently, as of v2.2.105, discards.

With this change failure to load startup-config results in the system
detecting the failure applying failure-config instead.

Fixes #429

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz d0cfe429c4 confd: fix regression, loss of admin account after upgrade to v24.04
Fix regression introduced in 3f87945, which tries to map a user to an
existing home directory.  The root cause for the problem is basically an
invalid check of the /home/admin UID being in use by any system account
or not.  This patch uses the same check used by the BusyBox adduser
command.

In addition to the uid-already-in-use fix, several other checks have
been added to ensure we do not end up with an invalid system state:

 - If reusing an existing /home/admin fails in the 'adduser admin'
   command, wipe out /home/admin and retry adding the user cleanly
 - Always delete any group with the same name before trying to add
   the user, regardless if /home/$user exists or not, this prevents
   issues with stale group records if we end up failing to load the
   startup-config and need to load failure-config
 - For the same reason (failure-config), make sure to always clean
   up any stale user in the retry step.  The same step is used when
   there is a uid:gid mismapping (the original bug)

Fixes #428

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz adf37394f4 confd: follow-up to 2412fff3, simplify chown of startup-config
Instead of having a chown process started by Finit in runlevel S, we can
just chown in the confd load script instead.

Issue #415

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz bc020436e7 confd: increased severity for log messages caught on stdout/stderr
Error messages from system() calls, like adduser, should be logged with
severity LOG_ERR to not arrive out of sequence with ERROR() messages.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz ad8a74fa7b confd: minor, fix variable shadowing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 3315a46423 confd: minor, skip shell update when deleting user
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 334d222f7c confd: minor, logging cleanup
- Drop unnecessary \n
 - Drop needless ERROR() message triggered when deleting users

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz d624203815 confd: minor, match syslog tag with other log messages
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz ab21eff6c8 confd: minor, use initial hostname from /etc/os-release as fallback
Instead of hard-coding the fallback hostname we can now use the one
generated to /etc/os-release (for netbrowse).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Jon-Olov Vatnandjovatn a05e28d349 Updating text after feedback.
I found similar error in other parts of the doc, as well
as some typos, and fixed them there too.

[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn 81c8f1c944 Fixing more typos.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn d039d9fc2b Fix typo.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn e1dd636ed0 Update link list and fixing typo.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn c4236eaa80 Yet another try for anchors for cross-references 2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn a8c47779a2 New try for explicit anchors for cross-references
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn 3178d5aae4 Adding script examples for production tests
- reading out eeprom/vpd data
- led testing
- power supply testing
- ethernet port test (example for looping ports)

[skip ci]
2024-05-13 07:50:34 +02:00
Tobias Waldekranz e63256edbb cn9130-crb: Document bootstrapping procedure 2024-05-07 15:34:47 +02:00
Tobias Waldekranz 68a0b289d2 board/aarch64: Separate board specific documentation
This should make it easier to find what you're after as the number of
supported boards increase.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 8a7eb80878 cn9130-crb: Set Infix default password
Since we don't have any VPD defined on this board, supply a default
password hash via the device tree instead.

Also, specify the path to external USB port, so that Infix will pick
it up in ietf-hardware.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 473d48097c cn9130-crb: Enable eth2, avoid polling of SFP io lines
Provide a patched device tree that:

- Uses the correct phy-mode for eth2, allowing it to be probed
  properly

- Wires up the interrupt signal to the GPIO expander, so that the SFP
  cage's I/O lines can be configured as interrupts, rather than having
  to poll them
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 50a9bba1c7 board/common: fdisk: Allow reformatting of disks
Assume that the caller always want to create a new partition table,
even in scenarios where one already exists. This allows devices to be
reprovisioned with a newer image, for example.

Fixes #394
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 21ab842357 board/common: Fix incorrect path to /etc/partition-uuid
While we're here, fix some whitespace nits.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz b5abcc8af9 cn9130-crb: Add a small bootdelay in U-Boot
This is not a production target, so we choose the more developer
friendly option of allowing the boot process to be interrupted.

Also, remove the old update cruft and rely on Marvell's `bubt`
instead.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz ca968c7d87 cn9130-crb: Switch to using SPI FLASH for bootloader storage
The BootROM wants the bootloader to be located on LBA1, which is not
ideal when using a GPT to describe the partition table.

Make sure the `bubt` command targets SPI by default.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz d96f3ae2e9 defconfig: cn9130_crb_boot: Pin ATF version after Buildroot update
Buildroot's default ATF version changed from 2.9 to 2.10 when we
upgraded to 24.02.x. This meant that our patches were not applied,
which broke the build.

Take a conservative approach for now, and just pin the ATF version to
the known-good 2.9 series.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz f45e1d57a0 defconfig: cn9130_crb_boot: Restore image signing functionality
During the addition of multi-key support to RAUC and U-Boot, the
bootloader defconfig for CN9130 CRB was overlooked, which meant that
the Infix specific U-Boot hooks never ran, thereby ultimately breaking
the build.

Restore the required options to build in the dev-key by default.
2024-05-07 15:34:47 +02:00
Joachim Wiberg f5b0f37386 confd: rename 10-infix-system.json -> 10-infix-services.json
Mislabled from the start, the file holds default services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-05 18:20:03 +02:00
Joachim Wiberg f0205b0a35 board/common: document reserved syslog facilities
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-05 18:15:03 +02:00
Joachim Wiberg 80659ef299 Final ChangeLog update for v24.04.1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 17:06:15 +02:00
Joachim Wiberg 59b3e583f1 doc: update build deps, bison needed new uboot-tools
The Buildroot 2024.02.x-kkit branch recently had uboot-tools upgraded
and the patches needed require bison to rebuild.

The recommendation is to also install flex, they always go together.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 17:03:03 +02:00
Joachim WibergandMattias Walström 6a8eaacc6e Replace python + rust based gencert2 with C based gencert3
Also, sync r2s_defconfig with latest major changes.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 15:33:00 +02:00
Joachim WibergandMattias Walström 6b8bd4caf3 package/gencert: new package
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 15:33:00 +02:00
Joachim WibergandMattias Walström 39f868fc61 gencert: C replacement for python+rust gencert
Smaller, fewer dependencies, and quicker to cross-compile.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 15:33:00 +02:00
Joachim WibergandMattias Walström be1c00f469 package/factory: add checksum for LICENSE
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 15:33:00 +02:00
Joachim WibergandMattias Walström 71e63de0c1 execd: minor, drop dummy line from configure summary
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 15:33:00 +02:00
Tobias WaldekranzandJoachim Wiberg 6c1c31e5c0 doc: testing: Document how to use deterministic topology mappings 2024-05-03 14:44:54 +02:00
Tobias WaldekranzandJoachim Wiberg a2906acdf7 test: Optionally use deterministic topology mappings
Due to the salting being applied to Python's `hash()` (see [1]), the
hash of an object is not stable across different Python processes. As
a result, neither are the topology mappings generated by networkx.

The upside of this is randomness that we get better test coverage over
time, especially on physical devices where the underlying hardware
could differ between ports, for example.

On the other hand, it can be very frustrating to track down a bug when
locial nodes are suffled around between phyical nodes on each
invocation of a test case.

Therefore, use a random seed by default, but allow the user to specify
a fixed value if they so choose. We then add a meta test that logs the
seed being used for the current suite - which means we can simply
copy&paste that value to rerun the suite (or single test) with the
same topology mappings.

[1]: https://docs.python.org/3/reference/datamodel.html#object.__hash__
2024-05-03 14:44:54 +02:00
Tobias WaldekranzandJoachim Wiberg 753f3806a1 test: Improve efficiency of logical to physical topology matching
- Present the topologies to networkx as multigraphs, rather than
  expaning each port of the record shape as a separate node.

- Create a topology mapping by locating a subgraph monomorphism of the
  logical topology in the physical ditto.

This cuts down the time of finding a mapping by several orders of
magnitude. Example:

Before:

time python3 test/infamy/topology.py \
     	     test/virt/quad/topology.dot.in \
	     test/infamy/topologies/ring-4-duts.dot >/dev/null

real    13m1,213s
user    13m0,112s
sys     0m0,732s

After:

time python3 test/infamy/topology.py \
     	     test/virt/quad/topology.dot.in \
	     test/infamy/topologies/ring-4-duts.dot >/dev/null

real    0m0,153s
user    0m0,128s
sys     0m0,024s
2024-05-03 14:44:54 +02:00
Joachim WibergandTobias Waldekranz 2a218ce6e9 doc: update ChangeLog for v24.04.1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 07:54:48 +02:00
Joachim WibergandTobias Waldekranz 474820c44b Fix #424: regression, root user can log in without password
This fixes a serious security regression introduced late in the v24.04
release cycle.  The root cause is the placement of the shadow file in
the rootfs overlay, which causes any changes made by the Buildroot
setting BR2_TARGET_ENABLE_ROOT_LOGIN to be discarded/overwritten just
before creating the squashfs image.

The fix in this commit relocates all files from b4eb450 to the skeleton
in Infix, package/skeleton-init-finit/skeleton/etc, which is one of the
first packages to be installed when starting a build.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 07:54:48 +02:00
Joachim WibergandTobias Waldekranz 9609fc144d confd: add timestamps to dagger .log files
Sample output:

    root@infix-00-00-00:~# cat /run/net/0/action/init/lo/45-init.sysctl.log
    May 02 13:45:58 net.ipv6.conf.lo.autoconf = 1
    May 02 13:45:58 net.ipv6.conf.lo.dad_transmits = 1
    May 02 13:45:58 net.ipv6.conf.lo.temp_prefered_lft = 86400
    May 02 13:45:58 net.ipv6.conf.lo.temp_valid_lft = 604800
    May 02 13:45:58 [exit:0]

Fixes #374

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 07:54:48 +02:00
Joachim WibergandTobias Waldekranz a0df130852 board/common: relocate dagger script to confd tree
The dagger tool is a helper for scripts generated by confd and should
therefore be installed by confd instead of the rootfs overlay.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 07:54:48 +02:00
Joachim WibergandTobias Waldekranz 22c911f85e package/landing: new package
Relocate the default landing page from the rootfs overlay to a package
so that customer repos can override it.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-03 07:54:48 +02:00
Tobias WaldekranzandJoachim Wiberg 3d8b64f939 aarch64: kernel: Enable DCB
In order to make use of the DCB support in mv88e6xxx we also enable it
in the kernel config.

Fixes: 3a73ce3cfb ("kernel: Import EtherType based priority override support")
2024-05-02 15:30:02 +02:00
Joachim Wiberg 1176560bb2 package/python-statd: update LICENSE hash
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 17:44:26 +02:00
Joachim Wiberg ec4a311f47 package/statd: update LICENSE hash
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 17:42:38 +02:00
Joachim Wiberg 7fd746e56f doc: add markdown link to v24.04.0 diff
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 15:17:50 +02:00
Joachim Wiberg 258368d814 .github: drop build in /mnt workaround for release build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 15:16:11 +02:00
Joachim Wiberg 9dfb0ea1f1 doc: update ChangeLog for v24.04
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 12:35:13 +02:00
Joachim Wiberg 3408f02709 doc: follow-up to aaaad535, ACLs for guest and operator dropped
As mentioned previously, the NACM default ACLs in `factory-config` were
removed as part of the work on the nacm-basic branch.

Adjust text to not mention any pre-configured user levels, for now.  A
future update may change the defaults when we've found resonable levels.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 11:09:01 +02:00
Joachim Wiberg b557d69b8a package/confd: follow-up to 2412fff, chown only in runlevel S
Run chown only at bootstrap, after confd has started and we've loaded
startup-config.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 11:08:50 +02:00
Joachim Wiberg 3a2579ec9e board/common: follow-up to bb18afa, adjust qemu.sh interface names
This adjusts the name of the first interface in all network modes, not
just tap, for consistency.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 11:08:36 +02:00
Joachim Wiberg ab3a09b260 board/x86_64: follow-up to c637ab4, allow console also on ttyS0
Fixes #419

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-01 10:45:17 +02:00
Tobias Waldekranz f1d21a4bae uboot: Install all trusted keys into U-Boot's control DT
Now that RAUC can have multiple keys in its keyring, we should include
the same set of keys in the bootloader.
2024-04-30 16:03:09 +02:00
Tobias Waldekranz 6e4aa0d7be buildroot: Bump to latest 2024.02.x-kkit for new uboot-tools 2024-04-30 16:03:09 +02:00
Joachim WibergandTobias Waldekranz 0629022b1f confd: minor, adjust log levels and drop duplicate log messages
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz cffaf71d6e board/common: generate a small aux partition for 'make run'
This patch helps silence kernel errors to console at boot.  To fully
silence errors, enable emulated /var in your Qemu runs as well.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz d1b0f69e18 board/common: minor, whitespace
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz fe33d0d733 patches/linux: adjust log level for unauthorized usb devices
The fact that a USB device currently is not authorized is not an error.
This patch adjusts the log level to slip below 'quiet' to prevent logs
to console at boot.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz aaaad53549 doc: new section, multiple users, and multiple admins
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz 053d9c2131 test: reenable infix-services test with a link toggle
Since we do not yet have lldpTxFast, or similar, to enable on LLDP, we
tickle both services to resend their HELLO frames on link down/up event
instead.

 + Reduces turnaround times drastically
 + Restore regression test for mDNS, which we lost recently

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz db628ee3f3 test: revert back to tcpdump output format when reading pcap
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz dee36ce801 confd: fix mDNS service type generation
In the 34fa6a3 refactor we lost announcement of mDNS completely:

 - The type of all services was set to 'all', instead of, e.g., _ssh._tcp
 - The web console service was not added properly
 - Web services for plain HTTP/HTTPS were not created at all

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz 3f87945f75 confd: map new users to existing home directories
UNIX home directories are persistent across reboots, but user accounts
are not.  If multiple users exist in startup-config and one or more are
removed, we must use the UID of their $HOME on the next reboot to ensure
they do not lose their files.

If a home directory exists and its UID is already in /etc/passwd we have
triggered an unsupported use-case and must remove the home directory on
disk before recreating it empty.  This should not happen, but may occur
on upgrades from a time before UIDs started at 1000 and instead shared
the UID range with reserved system accounts.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz fbeeed7a2c confd: refactor add/remove user from UNIX sysadmin group (wheel)
In review discussions we've decided to go for Augeas to modify the file
/etc/group instead of relying on the BusyBox tools adduser and delgroup,
which check for the existence of the user in /etc/passwd -- which we, at
the point in time the NACM callback runs, cannot guarantee.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz b03db7f994 confd: disable shell for non-admin users
A user that is not part of the 'admin' group may only have /bin/false or
/bin/clish as login shells for ssh/console.  Any POSIX shell is reserved
for administrators.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz 26820111f7 confd: add basic support for nacm
This patch adds basic NACM support to detect users assigned to a group
granting full access privileges.  Full privileges require membership of
at least one group listed in an ACL rule with:

   module-name=*
   access-operations=*
   action=permit

This matches the `admin-acl` rule in factory-config, which the 'admin'
group is part of, and in turn the 'admin' *user* is a member of.

Also, drop unused guest and limited ACLs from factory-config.  Added
from the RFC as an example, but is likely more confusing than helpful.

Note: this does not add all NACM groups to the system, it maps users
      with administrator privileges to the UNIX 'wheel' group, which
      grants access to all IPC sockets (klish, finit, mctl), and sudo
      access to all other parts of the system.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz e395c90958 confd: create admin user without -S flag to adduser
After the upgrade to Buildroot 2024.02 a new system user was added to
/etc/passwd, sshd.  Used for drop-privs sshd.  This caused files that
were previously owned by the 'admin' user to now be owned by 'sshd'.

This patch drops the `-S` flag from adduser for the adin user, ensuring
no future clashes with system system users and instead mapping the uid
to a range starting from uid 1000 (default for BusyBox adduser).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz 969ec1dd11 board/common: drop operator and staff, add backup user and group
- Free up 'operator' and 'staff' groups for NETCONF use
 - Reserve 'backup' user and group for future auto-backup (Debian)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz a972966a02 board/common: override default Buildroot passwd and group files
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Joachim WibergandTobias Waldekranz 1d7eeb5c53 doc: minor, follow-up to scripting.md
Drop sysrepocfg commands from first section.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-30 15:51:17 +02:00
Tobias Waldekranz 5e2475c742 confd: Avoid needless Ethernet flow-control reconfigurations
Unless some configuration has changed that affects flow-control (only
auto-neg for now, until we allow actual configuration of flow-control
itself), do not issue any commands that might trigger a link down/up
cycle.

Additionally, make sure that we always configure it on boot, as the
driver defaults might not necessarily line up with our defaults.
2024-04-29 14:31:40 +02:00
Tobias Waldekranz 824b911f49 confd: Unify determination of Ethernet auto-negotiation config
As detailed in the block comment in iface_uses_autoneg(), we make some
special considerations around this, so make sure we always reach the
same conclusion.
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 66ae2eb2e8 Update src/confd/src/ietf-interfaces.c
Co-authored-by: Tobias Waldekranz <tobias@waldekranz.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz f5408d9fbc doc: update ChangeLog with latest fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 0f7983008e confd: allow admin user to send factory reset rpc using sysrepocfg
Fixes #416

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 2412fff39c confd: ensure correct ownership of startup-config after factory reset
Fixes #415

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 809e6b44be confd: spellcheck infix-hardware.yang
Fixes #414

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 7c7b9ee1f6 confd: fix missing support for globally disable dhcp client
Fixes #412

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 132dca844a board/common: disable lldpd on dsa0 interface
Fixes #404

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Joachim WibergandTobias Waldekranz 8a007d61d0 Disable Ethernet flow-control completely by default
We have previously stated configuration and status flow-control as not
supported, see infix-ethernet-interface.yang.  This is also the default
for flow-control in the ieee-ethernet-interface.yang model.

This patch change the actual value to disabled, so that devices properly
advertise flow-control as disabled/not-supported in auto-negotiation.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 14:31:40 +02:00
Jon-Olov VatnandJoachim Wiberg c58a624a51 Updating scripting file with sysrepo examples
[skip ci]
2024-04-29 11:09:01 +02:00
Jon-Olov VatnandJoachim Wiberg 9326812430 Updating sysrepocfg scripting examples
[skip ci]
2024-04-29 11:09:01 +02:00
Jon-Olov VatnandJoachim Wiberg 9bf4f1d982 Adding sysrepocfg examples
Initial examples added.
More can be done to show how config files are transferred to infix.

[skip ci]
2024-04-29 11:09:01 +02:00
Joachim Wiberg d722b108dc .github: let Coverity Scan run on GitHub infra
Our local runners do not allow sudo, e.g., when installing libyang and
the other dependencies.

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 11:08:27 +02:00
Joachim WibergandTobias Waldekranz d1a7e1d744 .github: revert massive-parallel builds and select new runners
The massive-parallel build change added recently is a bit shaky still,
so while we stabilze that, we revert it and also take the oppportunity
to tag the new build server.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 286d5e9c0d .github: cleanup and minor changes for consistency.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 7dc0542d01 test/virt: override default Qeneth OUI
Over the lifetime of Infix, so far, we've run into at least one customer
issue where we had qualms about our use of the local bit causing issues
with 3rd party software.  In the end that was not the root cause of our
problems, but we spent way too much time worrying about it.  Hence this
patch, which brings our virtual environments another step closer to the
real hardware that Infix runs on.

The OUI used is one of the "private" ones, taken completly at random.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 0480d0f16b test/virt: rename according to new interface naming standard
Ethernet ports start with 'e'
Port numbers start with '1'

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 59f81e9391 test/qeneth: bump for new mac ranges and mactab support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 3f2ead2528 doc: update list of required packages
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 3f1c360287 doc: add section on multicast filtering and snooping
Final work item for the Infix bridge MDB support epic.

Fixes #334

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz c3a227289d confd: allow setting factory hostname from qemu_fw_cfg
This patch adds support for overriding the default hostname generation
on Qemu systems with the /sys/firmware/qemu_fw_cfg/by_name/opt/hostname
file.  E.g., virtual Infamy test systems using Qeneth.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz bb18afa883 board/common: probe system base mac also on qemu systems
The base mac address is used by bridges in Infix.  This patch adds
support for extracting a base mac from the first interface "- 1",
e.g., if the mac address of e1 is 08:00:20:00:00:01, the base mac
will be 08:00:20:00:00:00.

This works with the Infamy test framework (Qeneth) and also with
the qemu script, included in this patch.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz adab286bf9 board/common: ensure /run/system.json is readable only wheel group
Writable by root, readble only by wheel members, e.g. admin.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz b993c8daa7 board/common: minor, fix a few pylint warnings
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz e59bab16c0 confd: set mcast_vlan_snooping and correct IGMP/MLD versions
As described in issue #396, multicast filtering on VLAN filtering
bridges did not work at all.  This because bridge_mcast_settings()
exited when no global multicast settings were found -- a change to
the YANG model made previously triggered this fauled behavior.

Also, the initial IGMP/MLD versions were set to 2/1 (kernel default)
instead of 3/2 (Infix default).

Fixes #396

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
Joachim WibergandTobias Waldekranz 4ce1be6f0a package/mcd: bump from v2.1 to v2.3
For a full ChangeLog, see:

  - https://github.com/kernelkit/mcd/releases/tag/v2.2
  - https://github.com/kernelkit/mcd/releases/tag/v2.3

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-04-29 08:44:44 +02:00
176 changed files with 4447 additions and 1316 deletions
+36 -20
View File
@@ -11,7 +11,7 @@ Talking about code and problems first is often the best way to get started
before submitting a pull request.
When submitting a bug report, patch, or pull request, please start by
stating the version the change is made against, what it does, and why.
stating the version the change is made against, what it does, *and why*.
Please take care to ensure you follow the project coding style and the
commit message format. If you follow these recommendations you help
@@ -21,13 +21,28 @@ the maintainer(s) and make it easier for them to include your code.
Coding Style
------------
> **Tip:** Always submit code that follows the style of surrounding code!
Before jumping into code, remember to **document new features** and bug
fixes. Both the manual and ChangeLog are in the `doc/` sub-directory
and it is expected that you provide a human-readable summary for the
release notes (ChangeLog) and at least a configuration example in the
manual for new features.
First of all, lines are allowed to be longer than 72 characters these
days. In fact, there exist no enforced maximum, but keeping it around
100 chars is OK.
> **Tip:** consider ["Readme driven development"][RDD] for new features.
> It is amazing how many flaws in your own bright ideas come to bare
> when you suddenly have to explain them to someone else!
The coding style itself is otherwise strictly Linux [KNF][].
We expect code contributions for:
- C code in [Linux Coding Style][Linux]
- Python code should follow [PEP-8][]
> **However,** always submit code that follows the style of surrounding
> code! Legacy takes precedence, and remember, we read code a lot more
> than write it, so legibility is important.
As a final note, lines are allowed to be longer than 72 characters these
days. There is no enforced maximum, but the team usually keep it around
100 characters for both C and Python.
Commit Messages
@@ -37,22 +52,21 @@ Commit messages exist to track *why* a change was made. Try to be as
clear and concise as possible in your commit messages, and always, be
proud of your work and set up a proper GIT identity for your commits:
git config --global user.name "Jane Doe"
git config --global user.email jane.doe@example.com
$ git config --global user.name "Jacky Linker"
$ git config --global user.email jacky.linker@example.com
Example commit message from the [Pro Git][gitbook] online book, notice
how `git commit -s` is used to automatically add a `Signed-off-by`:
Brief, but clear and concise summary of changes
subsystem: brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
blank line separating the ummary from the body is critical (unless
you omit the body entirely); tools like rebase can get confused if
you run the two together.
empty line separating summary from body is critical. Tools like
rebase can get confused if the empty line is missing.
Further paragraphs come after blank lines.
Further paragraphs should be separated with empty lines.
- Bullet points are okay, too
@@ -60,17 +74,19 @@ how `git commit -s` is used to automatically add a `Signed-off-by`:
by a single space, with blank lines in between, but conventions
vary here
Signed-off-by: Jane Doe <jane.doe@example.com>
Signed-off-by: Jacky Linker <jacky.linker@example.com>
Code of Conduct
---------------
It is expected of everyone to respect the [Code of Conduct][conduct].
The *"maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct."*
The *"maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, discussion forum threads, issues, and
other contributions that are not aligned to this Code of Conduct."*
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
[gitbook]: https://git-scm.com/book/ch5-2.html
[conduct]: CODE-OF-CONDUCT.md
[Linux]: https://www.kernel.org/doc/html/v6.9/process/coding-style.html
[PEP-8]: https://peps.python.org/pep-0008/
[RDD]: https://tom.preston-werner.com/2010/08/23/readme-driven-development
[gitbook]: https://git-scm.com/book/ch5-2.html
[conduct]: CODE-OF-CONDUCT.md
+69
View File
@@ -0,0 +1,69 @@
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: "\U0001F41E Bug report"
description: Create a bug report
labels:
- "bug"
- "triage"
body:
- type: markdown
attributes:
value: |
**Thank :heart: you for taking the time to fill out this bug report!**
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for the bug you encountered.
- type: textarea
attributes:
label: Current Behavior
description: |
A clear and concise description of the issue you're experiencing.
value: |
For code snippets, logs, commands, etc., please use triple backticks:
```
admin@infix-c0-ff-ee:/> show log
May 15 07:21:02 infix-00-00-00 container[3192]: Failed creating container test from curios-httpd-v24.03.0
- (press h for help or q to quit)
```
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
A clear and concise description of what you expected to happen.
value: |
```
admin@infix-c0-ff-ee:/> show log
May 15 07:21:02 infix-c0-ff-ee container[3192]: Successfully created container test from curios-httpd-v24.03.0
- (press h for help or q to quit)
```
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: |
Steps to reproduce the issue. For example:
1. Built from source
2. Upgrade to latest release, vYY.MM.P
3. Factory reset
4. Enable feature
5. Check the logs/show command/operational status
validations:
required: false
- type: textarea
attributes:
label: Additional information
description: |
- Relevant parts of `startup-config`
- Output from `show interfaces`, if applicable
- Other observations, screenshots, log files ...
**Tip:** You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
+7
View File
@@ -0,0 +1,7 @@
contact_links:
- name: "🔍 Look for my Issue"
url: https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+
about: Thank ❤️ you for your time! We kindly ask that you first check if an issue already exists.
- name: "💬 Discussions and Q&A"
url: https://github.com/kernelkit/infix/discussions
about: Discussions are perfect for quick questions, bouncing ideas, and things that may be a bug.
@@ -0,0 +1,45 @@
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: "\U0001F6E0 Feature request"
description: Suggest a new feature, idea or improvement of the OS
labels:
- "feature"
- "triage"
body:
- type: markdown
attributes:
value: |
**Thank :heart: you for taking the time to fill out this feature request!**
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature. We are also happy to accept contributions from our users. For details see [CONTRIBUTING](https://github.com/kernelkit/infix/blob/master/.github/CONTRIBUTING.md).
- type: textarea
attributes:
label: Description
description: |
A clear and concise description of the problem or missing feature.
**Example:** *I'm always frustrated when [...]*, or *I'd like to see support for [...]*
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: |
Any other related information, e.g. existing YANG model(s), or possibly screenshots about the feature request here.
validations:
required: false
- type: textarea
attributes:
label: General Information
description: |
Appended to all feature requests for future readers.
value: |
Anyone can help out by [sponsoring][1] development of new features or [contributing][2] pull requests.
Please use this issue for discussions related to the feature.
[1]: https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md
[2]: https://github.com/kernelkit/infix/blob/main/.github/CONTRIBUTING.md
validations:
required: true
+1 -7
View File
@@ -1,5 +1,3 @@
<!--- **Summarize** your changes in the title above -->
## Description
<!--
@@ -15,7 +13,7 @@
## Checklist
Tick relevant boxes, this PR is-a or has-a:
Tick *relevant* boxes, this PR is-a or has-a:
- [ ] Bugfix
- [ ] Regression tests
@@ -31,7 +29,3 @@ Tick relevant boxes, this PR is-a or has-a:
- [ ] Documentation content changes
- [ ] Other (please describe):
## References
<!-- Please list references to related issue(s) -->
+23 -15
View File
@@ -8,25 +8,25 @@ on:
jobs:
build:
name: Build Infix ${{ matrix.platform }}
runs-on: self-hosted
name: Build Infix ${{ matrix.target }}
runs-on: [ self-hosted, latest ]
strategy:
matrix:
platform: [aarch64, x86_64]
target: [aarch64, x86_64]
fail-fast: false
steps:
- name: Maintenance
run: |
docker image prune -af
docker volume prune -f
docker container prune -f
- uses: actions/checkout@v4
with:
clean: true
submodules: recursive
- name: Set Build Variables
id: vars
run: |
target=${{ matrix.platform }}
target=${{ matrix.target }}
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
@@ -34,39 +34,45 @@ jobs:
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-${{ matrix.platform }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-${{ matrix.platform }}-
ccache-${{ matrix.target }}-
ccache-
- name: Configure & Build
run: |
target=${{ matrix.platform }}_defconfig
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target
make
- name: Prepare Artifact
run: |
cd output/
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- name: Test
if: matrix.platform == 'x86_64'
if: matrix.target == 'x86_64'
run: |
make test
- uses: actions/upload-artifact@v4
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ matrix.platform }}
name: artifact-${{ matrix.target }}
release:
if: ${{github.repository_owner == 'kernelkit' && github.ref_name == 'main'}}
name: Upload Latest Build
needs: build
runs-on: self-hosted
runs-on: [ self-hosted, latest ]
permissions:
contents: write
steps:
@@ -74,6 +80,7 @@ jobs:
with:
pattern: "artifact-*"
merge-multiple: true
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -84,6 +91,7 @@ jobs:
tag: "latest"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
+8 -1
View File
@@ -12,7 +12,7 @@ env:
jobs:
coverity:
if: ${{github.repository_owner == 'kernelkit'}}
runs-on: self-hosted
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch latest Coverity Scan MD5
@@ -24,6 +24,7 @@ jobs:
--post-data "token=$TOKEN&project=${PROJECT_NAME}&md5=1" \
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
id: cache
with:
@@ -33,6 +34,7 @@ jobs:
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
${{ runner.os }}-coverity-
${{ runner.os }}-coverity
- name: Download Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
@@ -47,12 +49,14 @@ jobs:
fi
mkdir coverity
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
libaugeas-dev libglib2.0-dev libpcre2-dev \
libuev-dev libite-dev
- name: Build dependencies
run: |
git clone https://github.com/CESNET/libyang.git
@@ -62,10 +66,12 @@ jobs:
mkdir sysrepo/build
(cd sysrepo/build && cmake .. && make all && sudo make install)
make dep
- name: Check applications
run: |
export PATH=`pwd`/coverity/bin:$PATH
cov-build --dir cov-int make check
- name: Submit results to Coverity Scan
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
@@ -78,6 +84,7 @@ jobs:
--form version=$(git rev-parse HEAD) \
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${PROJECT_NAME}
- name: Upload build.log
uses: actions/upload-artifact@v4
with:
+31 -14
View File
@@ -15,61 +15,78 @@ concurrency:
jobs:
build:
name: Regression Testing
runs-on: self-hosted
name: Regression Testing ${{ matrix.target }}
runs-on: [ self-hosted, regression ]
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
target: [aarch64, x86_64]
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
clean: true
submodules: recursive
- name: Clean up cruft ...
run: |
./test/env -c
- name: Set Build Variables
id: vars
run: |
target=x86_64
target=${{ matrix.target }}
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
path: dl/
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/refs/heads/master', 'package/*/*.hash') }}
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-netconf-
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/refs/head/master', 'package/*/*.hash') }}
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-x86_64-
ccache-${{ matrix.target }}-
ccache-
- name: Configure NETCONF
- name: Configure ${{ matrix.target }}
run: |
make x86_64_defconfig
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target
- name: Unit Test
run: make test-unit
run: |
make test-unit
- name: Build
run: |
make -j
make
- name: Prepare Artifact
run: |
cd output
cd output/
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ matrix.target }}
- name: Regression Test
run: make test-qeneth
if: matrix.target == 'x86_64'
run: |
make test
- name: Publish Test Result
# Ensure this runs even if Regression Test fails
+30 -20
View File
@@ -20,19 +20,18 @@ on:
jobs:
build:
if: github.repository == 'kernelkit/infix' && startsWith(github.ref, 'refs/tags/')
name: Build Infix ${{ github.ref_name }} [${{ matrix.platform }}]
runs-on: self-hosted
name: Build Infix ${{ github.ref_name }} [${{ matrix.target }}]
runs-on: [ self-hosted, release ]
strategy:
matrix:
platform: [aarch64, x86_64]
target: [aarch64, x86_64]
fail-fast: false
steps:
- name: Maintenance
run: |
docker image prune -af
docker volume prune -f
docker container prune -f
- uses: actions/checkout@v4
with:
clean: true
submodules: recursive
- name: Set Release Variables
id: vars
run: |
@@ -43,10 +42,10 @@ jobs:
fi
echo "ver=${ver}" >> $GITHUB_OUTPUT
fver=${ver#v}
target=${{ matrix.platform }}-${fver}
target=${{ matrix.target }}-${fver}
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
echo "out=/mnt/x-$target" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
@@ -54,49 +53,55 @@ jobs:
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
path: .ccache/
key: ccache-${{ matrix.platform }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
ccache-${{ matrix.platform }}-
ccache-${{ matrix.target }}-
ccache-
- name: Configure & Build
env:
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
run: |
target=${{ matrix.platform }}_defconfig
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
sudo mkdir ${{ steps.vars.outputs.out }}
sudo chown $(id -un):$(id -gn) ${{ steps.vars.outputs.out }}
export O=${{ steps.vars.outputs.out }}
make $target
make
- name: Generate SBOM from Build
run: |
make legal-info
- name: Prepare Artifacts
run: |
cd ${{ steps.vars.outputs.out }}
cd output/
mv images ${{ steps.vars.outputs.dir }}
ln -s ${{ steps.vars.outputs.dir }} images
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
mv legal-info legal-info-$target
tar chfz legal-info-$target.tar.gz legal-info-$target
- uses: actions/upload-artifact@v4
with:
name: artifact-${{ matrix.platform }}
path: ${{ steps.vars.outputs.out }}/*.tar.gz
name: artifact-${{ matrix.target }}
path: output/*.tar.gz
release:
name: Release Infix ${{ github.ref_name }}
needs: build
runs-on: self-hosted
runs-on: [ self-hosted, release ]
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
- name: Set Release Variables
id: rel
run: |
@@ -118,20 +123,24 @@ jobs:
fi
echo "pre=${{ steps.rel.outputs.pre }}"
echo "latest=${{ steps.rel.outputs.latest }}"
- uses: actions/download-artifact@v4
with:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- name: Extract ChangeLog entry ...
run: |
awk '/^-----*$/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|head -n -1 > release.md
cat release.md
- uses: ncipollo/release-action@v1
with:
name: Infix ${{ github.ref_name }}
@@ -139,6 +148,7 @@ jobs:
makeLatest: ${{ steps.rel.outputs.latest }}
bodyFile: release.md
artifacts: "*.tar.gz*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
+2 -1
View File
@@ -100,7 +100,7 @@ and testing, but can also be used for evaluation and demo purposes. For
more information, see: [Infix in Virtual Environments](doc/virtual.md).
> See the [GitHub Releases](https://github.com/kernelkit/infix/releases)
> page for our pre-built images. The *Latest Build* has the bleeding
> page for our pre-built images. The *[Latest Build][]* has bleeding
> edge images, if possible we recommend using a versioned release.
>
> For *customer specific builds* of Infix, see your product repository.
@@ -116,6 +116,7 @@ more information, see: [Infix in Virtual Environments](doc/virtual.md).
[1]: https://buildroot.org/
[2]: https://www.sysrepo.org/
[3]: doc/cli/introduction.md
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest
[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/
+4 -64
View File
@@ -1,67 +1,7 @@
aarch64
=======
Microchip SparX-5i PCB135 (eMMC)
--------------------------------
At present, only FIT images are supported via the SparX-5i eval
board's U-Boot, which must contain a valid load address. If you are
using this board, after selecting your base configuration, run the
following command to supplement the existing config with the required
FIT options:
make board-enable-sparx-fit
### Unbricking
1. Don't load a corrupt bootloader to begin with
2. Done
If, for some reason, you didn't manage to follow step 1, you can use
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
directly.
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
you can load a new bootloader. The schematic below details how to
connect the Bus Blaster to the board, but the concept should be
portable to any debugger/device based around an FTDI2232 chip.
```
Bus Blaster: FLASH_PROG (J4):
.---. .---.
VTG >o o| VTG SCK >o o| GND
TRST |o o| GND MISO |o o| #RESET_FLASH
TDI |o o| GND o o| 3V3
TMS |o o| GND #CS |o o| #SYSRESET
TCK o o| GND MOSI |o o| GND
RTCK o o| GND '---'
TDO |o o| GND
TSRST |o o| GND
DBGRQ |o o| GND
DBGACK |o o| GND
'---'
```
| Bus Blaster | FLASH_PROG |
|-------------|----------------|
| `VTG` | `3V3` |
| `GND` | `GND` |
| | |
| `VTG` | `#RESET_FLASH` |
| `GND` | `#SYSRESET` |
| | |
| `TDI` | `MOSI` |
| `TMS` | `#CS` |
| `TCK` | `SCK` |
| `TDO` | `MISO` |
With the cable in place, build U-Boot with the correct configuration:
make fireant_boot_defconfig && make
To flash it to the board, connect the cable to `J4` and run:
make board-sparx-flash-uboot
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
[dangerspi]: https://github.com/wkz/dangerspi
Board Specific Documentation
----------------------------
- [Marvell CN9130-CRB](cn9130-crb/)
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
+132
View File
@@ -0,0 +1,132 @@
Marvell CN9130-CRB
==================
## Build instructions
### Bootloader
Build the bootloader from the supplied `defconfig`. It might be useful
to build in a separate output directory if you want to build Infix
from the same working tree later:
make O=$(pwd)/x-cn9130-boot cn9130_crb_boot_defconfig
cd x-cn9130-boot
make
The artifact of interest is called `flash-image.bin`, which will be
located in the `images/` directory once the build completes.
### Infix
> If you do not want to build Infix from source, feel free to use a pre-built [release]
The standard `aarch64_defconfig` is compatible with this board:
make O=$(pwd)/x-aarch64 aarch64_defconfig
cd x-aarch64
make
Two artifacts from the `images/` directory of this build are required
to provision a new board:
- `rootfs.itb`: Netbootable image
- `infix-aarch64.pkg`: Standard upgrade bundle
## Provisioning
The overall provisioning flow, in which each step in described in
details in the following sections, is as follows:
- Strap board to boot from SPI FLASH
- Load `flash-image.bin` over UART
- Burn `flash-image.bin` to SPI FLASH
- Netboot `rootfs.itb`
- Run Infix's built-in provisioning script
- Reboot, now booting from the primary partition of the SD-card
#### Strap Board to Boot from SPI FLASH
By default, the board is strapped to boot from eMMC. However, Infix
assumes that the board will boot from SPI FLASH. Therefore we have to
ensure that the DIP switches of `SW2` on the board selects a
`BOOT_MODE` of `0x32`, meaning that the switches on positions 4, 3,
and 1 should be enabled (i.e. these need to be tied to ground):
```
.-----. .-----. .-----.
| | | | | PWR |
| SIM | | uSD | | |
| | | | '-----'
'-----' '-----'
|
v
.-----. .-----.
| SW1 | | SW2 |
'-----' '-----'
.--------------------------.
| |
| |
| CN9130 |
```
#### UART Boot U-Boot
Make sure that:
- [mvebu64boot] is installed and available in your shell's `$PATH`
- No other program is attached to `ttyUSB0`
- No power is applied to the board
1. Start `mvebu64boot`:
mvebu64boot -b /path/to/flash-image.bin /dev/ttyUSB0
2. Apply power
As soon as `mvebu64boot` completes, attach to the serial port,
e.g. using `screen(1)`, or `console(1)` and stop the normal boot
process by hitting any key.
#### Burn U-Boot to SPI FLASH
Make sure that:
- `eth1` is connected to a machine which serves `flash-image.bin` over
TFTP
- U-Boot can reach the TFTP server. If the neighboring machine is also
set up as a DHCP server, simply run the command `dhcp -`
To burn the bootloader to SPI FLASH, run the `bubt` command:
bubt flash-image.bin
Once the command completes, reset the board to verify that it can now
boot unassisted:
reset
#### Boot up `rootfs.itb`
U-Boot will automatically fallback to netboot since the SD-card is
still blank. Make sure that the PC provides the path to `rootfs.itb`
in DHCP option 67 ("bootfile").
#### Install Firmware
Login as `admin`/`admin`, setup networking to the PC, ensure that the date on
the device is reasonably correct, and run the provisioning script:
admin@infix:~$ sudo -i
root@infix:~$ udhcpc -i e28
root@infix:~$ date -us YYYY-MM-DD
root@infix:~$ /libexec/infix/prod/provision tftp://<PC-IP>/infix-aarch64.pkg /dev/mmcblk0
After successful completion, the device is fully provisioned. On the
next boot, the device will boot of its own accord from the primary
SD-card partition.
> If possible, serve `infix-aarch64.pkg` over HTTP instead, as
> libcurl's TFTP implementation is quite slow.
[release]: https://github.com/kernelkit/infix/releases
[mvebu64boot]: https://github.com/addiva-elektronik/mvebu64boot
@@ -16,36 +16,7 @@ run ixboot
";
boot_targets = "mmc1";
ethprime = "eth1";
/* Uncomment this if you're debugging U-Boot
*
* This will allow you to break out of the
* normal boot flow and into the interactive
* console.
*
* To upgrade U-Boot itself, simply set the
* `bootfile` variable to the path of
* `flash-image.bin` on your TFTP server, then
* issue `run ixupgradeboot`.
*/
/* bootdelay = "2"; */
/* ixupgradeboot = " */
/* dhcp */
/* setexpr fileblks ${filesize} + 0x1ff */
/* setexpr fileblks ${fileblks} / 0x200 */
/* mmc dev 1 */
/* part start mmc 1 boot bootstart */
/* part size mmc 1 boot bootsize */
/* mmc erase ${bootstart} ${bootsize} */
/* mmc write ${fileaddr} ${bootstart} ${fileblks} */
/* "; */
bootdelay = "1";
};
};
};
/* &cp0_eth0 { */
/* phy-mode = "10gbase-r"; */
/* }; */
@@ -1,4 +1,6 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi cn9130-crb-env.dtsi"
CONFIG_SYS_PROMPT="(cn9130-crb) "
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_MVEBU_SPI_BOOT=y
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Marvell International Ltd.
*/
#include "cn9130-crb.dtsi"
/ {
model = "Marvell Armada CN9130-CRB-A";
chosen {
infix {
/* "admin" */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
usb-ports = <&cp0_usb3_1>;
usb-port-names = "USB";
};
};
};
&cp0_pcie0 {
status = "okay";
num-lanes = <4>;
num-viewport = <8>;
/* Generic PHY, providing serdes lanes */
phys = <&cp0_comphy0 0
&cp0_comphy1 0
&cp0_comphy2 0
&cp0_comphy3 0>;
iommu-map =
<0x0 &smmu 0x480 0x20>,
<0x100 &smmu 0x4a0 0x20>,
<0x200 &smmu 0x4c0 0x20>;
iommu-map-mask = <0x031f>;
};
&cp0_usb3_0 {
status = "okay";
usb-phy = <&cp0_usb3_0_phy0>;
phy-names = "usb";
};
&cp0_usb3_1 {
status = "okay";
usb-phy = <&cp0_usb3_0_phy1>;
phy-names = "usb";
};
&cp0_eth2 {
status = "okay";
phy-mode = "2500base-x";
};
&cp0_pinctrl {
cp0_expander0_pins: cp0-expander-pins-0 {
marvell,pins = "mpp39";
marvell,function = "gpio";
};
};
&expander0 {
pinctrl-names = "default";
pinctrl-0 = <&cp0_expander0_pins>;
interrupt-parent = <&cp0_gpio2>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
};
+1
View File
@@ -178,6 +178,7 @@ CONFIG_NET_SCHED=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_FLOWER=y
CONFIG_DCB=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=y
+64
View File
@@ -0,0 +1,64 @@
Microchip SparX-5i PCB135 (eMMC)
================================
At present, only FIT images are supported via the SparX-5i eval
board's U-Boot, which must contain a valid load address. If you are
using this board, after selecting your base configuration, run the
following command to supplement the existing config with the required
FIT options:
make board-enable-sparx-fit
## Unbricking
1. Don't load a corrupt bootloader to begin with
2. Done
If, for some reason, you didn't manage to follow step 1, you can use
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
directly.
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
you can load a new bootloader. The schematic below details how to
connect the Bus Blaster to the board, but the concept should be
portable to any debugger/device based around an FTDI2232 chip.
```
Bus Blaster: FLASH_PROG (J4):
.---. .---.
VTG >o o| VTG SCK >o o| GND
TRST |o o| GND MISO |o o| #RESET_FLASH
TDI |o o| GND o o| 3V3
TMS |o o| GND #CS |o o| #SYSRESET
TCK o o| GND MOSI |o o| GND
RTCK o o| GND '---'
TDO |o o| GND
TSRST |o o| GND
DBGRQ |o o| GND
DBGACK |o o| GND
'---'
```
| Bus Blaster | FLASH_PROG |
|-------------|----------------|
| `VTG` | `3V3` |
| `GND` | `GND` |
| | |
| `VTG` | `#RESET_FLASH` |
| `GND` | `#SYSRESET` |
| | |
| `TDI` | `MOSI` |
| `TMS` | `#CS` |
| `TCK` | `SCK` |
| `TDO` | `MISO` |
With the cable in place, build U-Boot with the correct configuration:
make fireant_boot_defconfig && make
To flash it to the board, connect the cable to `J4` and run:
make board-sparx-flash-uboot
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
[dangerspi]: https://github.com/wkz/dangerspi
+15 -9
View File
@@ -157,6 +157,12 @@ rw_args()
{
[ "$CONFIG_QEMU_RW" ] || return
if ! [ -f "aux.ext4" ]; then
dd if=/dev/zero of="aux.ext4" bs=1M count=1 >/dev/null 2>&1
mkfs.ext4 -L aux "aux.ext4" >/dev/null 2>&1
fi
echo -n "-drive file=aux.ext4,if=virtio,format=raw,bus=0,unit=3 "
if ! [ -f "$CONFIG_QEMU_RW" ]; then
dd if=/dev/zero of="$CONFIG_QEMU_RW" bs=16M count=1 >/dev/null 2>&1
mkfs.ext4 -L cfg "$CONFIG_QEMU_RW" >/dev/null 2>&1
@@ -198,10 +204,10 @@ net_args()
echo -n "-fw_cfg name=opt/mactab,file=$mactab "
if [ "$CONFIG_QEMU_NET_BRIDGE" = "y" ]; then
echo -n "-netdev bridge,id=e0,br=$CONFIG_QEMU_NET_BRIDGE_DEV "
net_dev_args 0
echo -n "-netdev bridge,id=e1,br=$CONFIG_QEMU_NET_BRIDGE_DEV "
net_dev_args 1
elif [ "$CONFIG_QEMU_NET_TAP" = "y" ]; then
for i in $(seq 0 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
for i in $(seq 1 $(($CONFIG_QEMU_NET_TAP_N))); do
echo -n "-netdev tap,id=e$i,ifname=qtap$i "
net_dev_args $i
done
@@ -209,8 +215,8 @@ net_args()
local useropts=
[ "$CONFIG_QEMU_NET_USER_OPTS" ] && useropts=",$CONFIG_QEMU_NET_USER_OPTS"
echo -n "-netdev user,id=e0${useropts} "
net_dev_args 0
echo -n "-netdev user,id=e1${useropts} "
net_dev_args 1
else
echo -n "-nic none"
fi
@@ -306,10 +312,10 @@ generate_dot()
{
[ "$CONFIG_QEMU_NET_TAP" = "y" ] || return
hostports="<qtap0> qtap0"
targetports="<e0> e0"
edges="host:qtap0 -- target:e0 [kind=mgmt];"
for tap in $(seq 1 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
hostports="<qtap1> qtap1"
targetports="<e1> e1"
edges="host:qtap1 -- target:e1 [kind=mgmt];"
for tap in $(seq 2 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
hostports="$hostports | <qtap$tap> qtap$tap "
targetports="$targetports | <e$tap> e$tap "
edges="$edges host:qtap$tap -- target:e$tap;"
-67
View File
@@ -1,67 +0,0 @@
#!/usr/bin/env python3
# Generate a self signed certificate with unlimited expire time
import argparse
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
from datetime import datetime, timedelta
# Generate private key
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
parser = argparse.ArgumentParser(description="Generate a self signed certificate")
parser.add_argument('--country', required=True, help="Set country")
parser.add_argument('--state', required=True, help="Set state or province name")
parser.add_argument('--city', required=True, help="Set city name")
parser.add_argument('--organisation', required=True, help="Set organisation name")
parser.add_argument('--organisation-unit', required=True, help="Set organisation unit name")
parser.add_argument('--common-name', required=True, help="Set common name")
parser.add_argument('--out-certificate', required=True, help="Output certificate")
parser.add_argument('--out-key', required=True, help="Output key")
args = parser.parse_args()
# Builder for certificate
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, args.country),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, args.state),
x509.NameAttribute(NameOID.LOCALITY_NAME, args.city),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, args.organisation),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, args.organisation_unit),
x509.NameAttribute(NameOID.COMMON_NAME, args.common_name),
])
certificate = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).public_key(
private_key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
datetime(2000, 1, 1)
).not_valid_after(
datetime(9999, 1, 1)
).add_extension(
x509.SubjectAlternativeName([x509.DNSName(args.common_name)]),
critical=False,
).sign(private_key, hashes.SHA256(), default_backend())
# Serialize certificate and private key
with open(args.out_certificate, "wb") as f:
f.write(certificate.public_bytes(serialization.Encoding.PEM))
with open(args.out_key, "wb") as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
))
+1 -1
View File
@@ -19,4 +19,4 @@ LABEL=aux /mnt/aux auto noatime,nodiratime,noauto 0 0
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 0 0
hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0
/libexec/infix/mnt# /cfg helper none 0 0
/libexec/infix/mnt# /cfg helper none 0 0
@@ -1,3 +1,7 @@
0 unspec
1 kernel_lo
2 kernel_ra
3 kernel_ll
4 static
5 dhcp
6 random
@@ -0,0 +1 @@
configure ports dsa0 lldp status disabled
@@ -0,0 +1 @@
UsePAM yes
@@ -0,0 +1,10 @@
Reserved facilities for logging in various subsystems:
- local0: rauc
- local1: containers
- local2:
- local3:
- local5:
- local6: reserved
- local7: nginx
+42 -7
View File
@@ -3,12 +3,13 @@
import importlib.machinery
import json
import os
import shutil
import struct
import subprocess
import sys
onieprom = importlib.machinery.SourceFileLoader("onieprom","/bin/onieprom").load_module()
SYSTEM_JSON = "/run/system.json"
KKIT_IANA_PEM = 61046
class DTSystem:
@@ -233,8 +234,36 @@ def vpd_inject(out, vpds):
out["factory-password-hash"] = pwhash
break
def qemu_base_mac():
"""Find MAC address of first non-loopback interface, subtract with 1"""
base_path = '/sys/class/net'
interfaces = []
for iface in os.listdir(base_path):
if iface == 'lo':
continue
try:
# pylint: disable=invalid-name
with open(os.path.join(base_path, iface, 'address'), 'r', encoding='ascii') as f:
mac = f.read().strip()
interfaces.append((mac, iface))
except FileNotFoundError:
continue
if interfaces:
interfaces.sort()
mac = interfaces[0][0]
mac = int(mac.replace(':', ''), 16)
mac -= 1
mac %= 1 << 48
mac = ':'.join(f"{(mac >> 8 * i) & 0xff:02x}" for i in range(5, -1, -1))
return mac
return None
def probe_qemusystem(out):
ADMINHASH = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
"""Probe Qemu based test systems and 'make run'"""
admin_hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
qsys = QEMUSystem()
vpds = qsys.vpds()
@@ -244,6 +273,7 @@ def probe_qemusystem(out):
for (attr, default) in (
("vendor", "QEMU"),
("product-name", "VM"),
("mac-address", qemu_base_mac()),
):
if not out[attr]:
out[attr] = default
@@ -252,13 +282,14 @@ def probe_qemusystem(out):
not out["vpd"]["product"]["available"]:
# Virtual instance without VPD emulation, fallback to
# admin/admin
out["factory-password-hash"] = ADMINHASH
out["factory-password-hash"] = admin_hash
# Let others react to the fact that we are running in QEMU
subprocess.run("initctl -nbq cond set qemu".split())
subprocess.run("initctl -nbq cond set qemu".split(), check=False)
return 0
def probe_dtsystem(out):
"""Probe DTS based system, expects a VPD in ONIE PROM format."""
dtsys = DTSystem()
vpds = dtsys.infix_vpds()
dtsys.infix_usb_devices(out)
@@ -296,11 +327,15 @@ def main():
return err
if not out["factory-password-hash"]:
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\nNO FACTORY PASSWORD FOUND\033[0m\n\n")
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\n" +
"NO FACTORY PASSWORD FOUND\033[0m\n\n")
err = 1
json.dump(out, open("/run/system.json", "w"))
os.chmod("/run/system.json", 0o444)
os.umask(0o337)
# pylint: disable=invalid-name
with open(SYSTEM_JSON, "w", encoding="ascii") as f:
json.dump(out, f)
shutil.chown(SYSTEM_JSON, user="root", group="wheel")
return err
if __name__ == "__main__":
+4 -4
View File
@@ -1,7 +1,7 @@
#!/bin/sh
set -e
. /etc/partion-uuid
. /etc/partition-uuid
disk=$1
bootoffs=$2
@@ -28,11 +28,11 @@ else
fi
sgdisk \
-o \
-Z \
-n1:${bootoffs}:+${bootsize} -t1:8301 -c1:boot \
-n2::+${auxsize} -t2:8301 -c2:aux -u2:${AUX_UUID}\
-n2::+${auxsize} -t2:8301 -c2:aux -u2:${AUX_UUID} \
-n3::+${imgsize} -t3:8300 -c3:primary -u3:${PRIMARY_UUID} \
-n4::+${imgsize} -t4:8300 -c4:secondary -u4:${SECONDARY_UUID}\
-n4::+${imgsize} -t4:8300 -c4:secondary -u4:${SECONDARY_UUID} \
-n5::+${cfgsize} -t5:8302 -c5:cfg \
-n6:: -t6:8310 -c6:var \
-p \
+22 -21
View File
@@ -1,26 +1,27 @@
# This is a bit awkward. If you know about a more straight forward way
# of doing this, please simplify.
#
# U-Boot needs the public part of the signing key to be preprocessed
# and then inserted into its control DT. mkimage(1) can perform this
# conversion, but only as a side-effect of building/signing an FIT
# image. Since we might not always be doing that, e.g. when only
# building a hardware specific bootloader, we build a dummy FIT just
# to get the key information into a DTB, which we then convert back to
# a .dtsi and install in the U-Boot build tree. This will then be
# built in to the final U-Boot image's control DT via the
# CONFIG_DEVICE_TREE_INCLUDES option (see extras.config).
define uboot-add-pubkey
$(call IXMSG,"Installing trusted key $1")
$(HOST_DIR)/bin/fdt_add_pubkey \
-a sha256,rsa$(shell \
openssl x509 -text -noout -in $1 | \
grep 'Public-Key: ' | \
sed -e 's/.*(\(.*\) bit)/\1/') \
-k $(dir $1) \
-n $(notdir $(basename $1)) \
-r image \
$2
endef
# U-Boot has its own public key format which has to be stored in its
# control DT. So we collect all of the trusted keys, convert them to
# the required format, and write the result to infix-key.dtb in the
# U-Boot build tree. This will then be built in to the final U-Boot
# image's control DT via the CONFIG_DEVICE_TREE_INCLUDES option (see
# extras.config).
define UBOOT_PRE_BUILD_INSTALL_KEY
@$(call IXMSG,"Installing Infix signing key ($(SIGN_KEY))")
$(HOST_DIR)/bin/dtc <(echo '/dts-v1/; / { signature {}; };') >$(@D)/infix-key.dtb
$(HOST_DIR)/bin/mkimage \
-k $(SIGN_KEY) \
-f $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/key-dummy.its \
-K $(@D)/infix-key.dtb \
$(if $(SIGN_SRC_PKCS11),-N pkcs11) \
-r \
$(@D)/key-dummy.itb
rm $(@D)/key-dummy.itb
$(foreach key, \
$(call qstrip,$(TRUSTED_KEYS_DEVELOPMENT_PATH)) $(call qstrip,$(TRUSTED_KEYS_EXTRA_PATH)),\
$(call uboot-add-pubkey,$(key),$(@D)/infix-key.dtb))
$(HOST_DIR)/bin/dtc -I dtb -O dts \
<$(@D)/infix-key.dtb \
| sed -e 's:/dts-v[0-9]\+/;::' >$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi
-34
View File
@@ -1,34 +0,0 @@
test-dir := $(BR2_EXTERNAL_INFIX_PATH)/test
INFIX_TESTS ?= $(test-dir)/case/all.yaml
test-env = $(test-dir)/env \
-f $(BINARIES_DIR)/infix-x86_64.img \
-f $(BINARIES_DIR)/infix-x86_64-disk.img \
-f $(BINARIES_DIR)/OVMF.fd \
-p $(BINARIES_DIR)/infix-x86_64.pkg \
$(1) $(2)
test-env-qeneth = $(call test-env,-q $(test-dir)/virt/quad,$(1))
test-env-run = $(call test-env,-C -t $(BINARIES_DIR)/qemu.dot,$(1))
test test-qeneth:
$(call test-env-qeneth,\
$(BR2_EXTERNAL_INFIX_PATH)/test/9pm/9pm.py \
$(INFIX_TESTS))
test-sh test-qeneth-sh:
$(call test-env-qeneth,-i /bin/sh)
test-run: | ~/.infix-test-venv
$(call test-env-run,\
$(BR2_EXTERNAL_INFIX_PATH)/test/9pm/9pm.py \
$(INFIX_TESTS))
test-run-sh: | ~/.infix-test-venv
$(call test-env-run,/bin/sh)
test-run-play: | ~/.infix-test-venv
$(call test-env-run,$(test-dir)/case/meta/play.py)
~/.infix-test-venv:
$(test-dir)/docker/init-venv.sh $(test-dir)/docker/pip-requirements.txt
.PHONY: test test-sh test-qeneth test-qeneth-sh test-run test-run-sh test-run-play
+3 -3
View File
@@ -42,14 +42,14 @@ export secondary
submenu "primary" "$log" {
set slot="$1"
set append="console=hvc0 root=PARTLABEL=$slot $2"
set append="console=ttyS0 console=hvc0 root=PARTLABEL=$slot $2"
set root="($primary)"
source /boot/grub/grub.cfg
}
submenu "secondary" "$log" {
set slot="$1"
set append="console=hvc0 root=PARTLABEL=$slot $2"
set append="console=ttyS0 console=hvc0 root=PARTLABEL=$slot $2"
set root="($secondary)"
source /boot/grub/grub.cfg
}
@@ -63,7 +63,7 @@ submenu "net" "$log" {
set root=(initrd)
set slot="$1"
set append="console=hvc0 root=/dev/ram0 ramdisk_size=65536 $2"
set append="console=ttyS0 console=hvc0 qroot=/dev/ram0 ramdisk_size=65536 $2"
source /boot/grub/grub.cfg
else
if [ -z "$net_efinet0_dhcp_next_server" ]; then
+4 -2
View File
@@ -54,7 +54,6 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
BR2_PACKAGE_PYTHON_GUNICORN=y
BR2_PACKAGE_LIBSSH_OPENSSL=y
BR2_PACKAGE_LIBSSH2=y
@@ -63,6 +62,8 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBCURL_CURL=y
BR2_PACKAGE_NETOPEER2_CLI=y
BR2_PACKAGE_NSS_MDNS=y
BR2_PACKAGE_LINUX_PAM=y
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
BR2_PACKAGE_ONIGURUMA=y
BR2_PACKAGE_AVAHI=y
BR2_PACKAGE_AVAHI_DAEMON=y
@@ -130,6 +131,7 @@ INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_CURIOS_HTTPD=y
BR2_PACKAGE_EXECD=y
BR2_PACKAGE_GENCERT=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
@@ -142,6 +144,7 @@ BR2_PACKAGE_IITO=y
BR2_PACKAGE_K8S_LOGGER=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -155,6 +158,5 @@ BR2_PACKAGE_LIBINPUT=y
DISK_IMAGE_BOOT_BIN=y
GNS3_APPLIANCE_RAM=512
GNS3_APPLIANCE_IFNUM=10
BR2_PER_PACKAGE_DIRECTORIES=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+4 -2
View File
@@ -16,6 +16,8 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.9"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="t9130"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
@@ -36,8 +38,8 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
# SIGN_ENABLED is not set
DISK_IMAGE=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
DISK_IMAGE_BOOT_BIN=y
DISK_IMAGE_BOOT_DATA="${BINARIES_DIR}/flash-image.bin"
DISK_IMAGE_BOOT_OFFSET=0x00200000
+7 -4
View File
@@ -13,7 +13,7 @@ BR2_TARGET_GENERIC_HOSTNAME="infix"
BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
BR2_INIT_FINIT=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs"
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
BR2_SYSTEM_BIN_SH_BASH=y
BR2_TARGET_GENERIC_GETTY_PORT="@console"
@@ -22,8 +22,8 @@ BR2_SYSTEM_DHCP="eth0"
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
BR2_GENERATE_LOCALE="en_US en_CA"
BR2_TARGET_TZ_INFO=y
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/rootfs"
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/post-build.sh"
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rootfs"
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh support/scripts/genimage.sh"
BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/genimage.cfg"
BR2_LINUX_KERNEL=y
@@ -64,7 +64,6 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
BR2_PACKAGE_PYTHON_GUNICORN=y
BR2_PACKAGE_CA_CERTIFICATES=y
BR2_PACKAGE_LIBSSH_OPENSSL=y
@@ -74,6 +73,8 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBCURL_CURL=y
BR2_PACKAGE_NETOPEER2_CLI=y
BR2_PACKAGE_NSS_MDNS=y
BR2_PACKAGE_LINUX_PAM=y
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
BR2_PACKAGE_ONIGURUMA=y
BR2_PACKAGE_AVAHI=y
BR2_PACKAGE_AVAHI_DAEMON=y
@@ -159,6 +160,7 @@ INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_EXECD=y
BR2_PACKAGE_GENCERT=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
@@ -171,6 +173,7 @@ BR2_PACKAGE_IITO=y
BR2_PACKAGE_K8S_LOGGER=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
+4 -2
View File
@@ -49,7 +49,6 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
BR2_PACKAGE_PYTHON_GUNICORN=y
BR2_PACKAGE_LIBSSH_OPENSSL=y
BR2_PACKAGE_LIBSSH2=y
@@ -58,6 +57,8 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBCURL_CURL=y
BR2_PACKAGE_NETOPEER2_CLI=y
BR2_PACKAGE_NSS_MDNS=y
BR2_PACKAGE_LINUX_PAM=y
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
BR2_PACKAGE_ONIGURUMA=y
BR2_PACKAGE_AVAHI=y
BR2_PACKAGE_AVAHI_DAEMON=y
@@ -133,6 +134,7 @@ INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_CURIOS_HTTPD=y
BR2_PACKAGE_EXECD=y
BR2_PACKAGE_GENCERT=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
@@ -145,6 +147,7 @@ BR2_PACKAGE_IITO=y
BR2_PACKAGE_K8S_LOGGER=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -156,6 +159,5 @@ BR2_PACKAGE_PODMAN_DRIVER_VFS=y
BR2_PACKAGE_TETRIS=y
GNS3_APPLIANCE_RAM=512
GNS3_APPLIANCE_IFNUM=10
BR2_PER_PACKAGE_DIRECTORIES=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+175 -25
View File
@@ -4,23 +4,114 @@ Change Log
All notable changes to the project are documented in this file.
[v24.03.0][UNRELEASED]
-------------------------
Please note, as of this release the Infix Classic variant has been
dropped. This was the legacy, pre-NETCONF, Infix with manual config of
the system using a persistent `/etc`. It may be resurrected later as a
separate project. Going forward Infix' focus is entirely on NETCONF.
> Development in progress, for daily updates see the team board:
> <https://github.com/orgs/kernelkit/projects/3/views/2>
[v24.05.0][UNRELEASED]
----------------------
### Changes
- Bump the base Linux kernel version to 6.6
- Default web landing page refactored into a Buildroot package to make
it possible to overload from customer repos.
- Enable DCB support in aarch64 kernel (for EtherType prio override)
- Topology mapper improvements, including option for deterministic
reproduction of logical to physical mappings
- New version of `gencert` tool, for self signed HTTPS certificates.
This allows dropping dependency on building a host rust toolchain
- Issue #374: add timestamps to dagger .log files
- Add small delay in U-Boot to allow stopping boot on reference boards
- Document how to provision the bootloader and Infix on a blank board
- Use initial hostname from `/etc/os-release` as configuration fallback
- Update documentation for use of VETH pairs in containers
- Issue #454: create bridges in `factory-config` with IGMP/MLD snooping
enabled by default
- Add support for optionally running user scripts from
`/cfg/user-scripts.d`
### Fixes
- Add missing LICENSE hash for factory reset tool
- Fix #424: regression, root user can log in without password
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
- Fix provisioning script after changes to make GRUB loading more robust
- Fix missing `/etc/resolv.conf`, as noticed by `avahi-daemon`, when a
user calls `no system` from the CLI
- Fix #428: loss of admin account after upgrade to v24.04
- Fix #429: failing to load `startup-config` does not trigger the fail
secure mode, causing the system to end up in an undefined state
- Fix #453: fix inconsistent behavior of custom MAC address (interface
`phys-address` for VETH pairs. Allows fixed MAC in containers
- Fix locking issue with standard counter groups on `mv88e6xxx`
- Fix MDB/ATU synchronization issue from IGMPv3/MLDv2 reports on
`mv88e6xxx` systems
[v24.04.2][] - 2024-05-15
-------------------------
### Changes
- Add small delay in U-Boot to allow stopping boot on reference boards
- Document how to provision the bootloader and Infix on a blank board
- Use initial hostname from `/etc/os-release` as configuration fallback
### Fixes
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
- Fix provisioning script after changes to make GRUB loading more robust
- Fix missing `/etc/resolv.conf`, as noticed by `avahi-daemon`, when a
user calls `no system` from the CLI
- Fix #428: loss of admin account after upgrade to v24.04
- Fix #429: failing to load `startup-config` does not trigger the fail
secure mode, causing the system to end up in an undefined state
[v24.04.1][] - 2024-05-03
-------------------------
### Changes
- Default web landing page refactored into a Buildroot package to make
it possible to overload from customer repos.
- Enable DCB support in aarch64 kernel (for EtherType prio override)
- Topology mapper improvements, including option for deterministic
reproduction of logical to physical mappings
- New version of `gencert` tool, for self signed HTTPS certificates.
This allows dropping dependency on building a host rust toolchain
- Issue #374: add timestamps to dagger .log files
### Fixes
- Add missing LICENSE hash for factory reset tool
- Fix #424: regression, root user can log in without password
[v24.04.0][] - 2024-04-30
-------------------------
**News:** this release marks the first major upgrade of the underlying
Buildroot to the latest LTS release, v2024.02. This caused a few small
regressions in the release cycle, all known issues have been addressed.
Also worth highlighting, as of this release the Infix Classic variant
has been dropped. It was the legacy Infix with manual configuration of
the system using a persistent `/etc`. May be resurrected later as a
separate project. Going forward Infix' focus is entirely on NETCONF.
Finally, the YANG Status section has been dropped for this release, the
idea is to generate supported features from the models and include in
future releases.
### Changes
- Bump the base Buildroot version to v2024.02 LTS
- Bump the base Linux kernel version to 6.6 LTS
- Drop Classic variant to reduce overhead, simplify build & release
processes, and focus on NETCONF for Arm64 and Amd64 platforms
- Add hostname restrictions to ietf-system, and infix-dhcp-client
models. Max 64 characters on Linux systems
- Add mDNS CNAME (alias) advertisement, e.g., infix.local in addition to
the default infix-c0-ff-ee.local. Note: this is build-specific and
does not change if system hostname is changed
- Add mDNS browser web application, https://network.local that shows all
mDNS devices on the LAN. The network.local mDNS name is also a CNAME,
so with multiple Infix devices, only one will act as the mDNS browser
- Add temporary landing page to web server for https://infix.local
- Add web console using ttyd, https://infix.local:7681
- Add support for disabling web services using CLI
- The bridge model now has built-in validation of port memberships,
i.e., a port must be a bridge member to be used in VLAN filtering
- The bridge model only permits the bridge itself to be a tagged
@@ -28,8 +119,49 @@ separate project. Going forward Infix' focus is entirely on NETCONF.
such bridges is to use a VLAN interface on top
- A VLAN filtering bridge now validates that no IP address has been
set. Use a VLAN interface on top for that (see above)
- Container documentation: CLI prompts have been updated to match the
examples used in other parts of the User Guide
- Restructure documentation, let first page in doc/ be table of contents
- Scripting Infix, new document on how to script Infix from remote,
e.g., for production or from a container
- Introduction, update documentation now that the `admin` user's default
login shell is `/bin/bash`
- System documentation, first outline of how to change hostname, add
users, add system administrator users, changing login banner, change
the system default editor, and more
- Network documentation, add section on VETH pairs
- Container documentation:
- CLI prompts have been updated to match the examples used in other
parts of the User Guide
- Default route example for static container interfaces
- How to upgrade a container image
- As a follow-up to port speed/duplex/autoneg support added in v24.02,
this release ensures flow-control is always disabled on all Ethernet
ports, as described in the IEEE Ethernet interfaces YANG model
- Add support for core dumps, saving them in `/var/crash`, max one dump
per process, for use with future support tarballs
- Add support for multicast snooping, both IPv4 (IGMP) and IPv6 (MLD) in
bridge setups, including offloading to switchdev
- Add support for acting as passive (proxy) or active IGMP querier
- Add support for static multicast filters, MAC, IPv4 and IPv6 groups
are supported -- multicast snooping must be enabled
- Include Buildroot `legal-info` in releases, i.e., licenses, sources
with patches, as well as csv files for packages and toolchain
- Drop `shell` command from CLI to allow confining users
- The CLI `copy` command now allows absolute paths
- Local resolver, `dnsmasq`, had port 53 visible from external `nmap`
scans, even though it dropped non-local requests, it now only binds to
the loopback interface reduce number of externally visible ports
- Kernel log messages, of severity error or higher, now log directly to
the console. This may cause some annoyance but has been enabled to
ease debugging, in particular issues where the system crashes before
the syslog daemon has flushed logs to disk. (Logs are still saved to
log files as well.)
- Issue #325: Add support for multiple administrator users by opening
up basic NETCONF ACM support. See documentation for details
- Any user can be added to the `admin` NACM group
- Any user *not* in the `admin` group is not allowed to have a login
shell other than the CLI (or disabled). POSIX shell, e.g., Bash is
reserved for system administrators
- Issue #327: Remove IPv6LL from bridge port interfaces
- Issue #358: translate YANG model's LOWER-LAYER-DOWN -> LINK-DOWN in
CLI `show interfaces` command
- Issue #360: document factory-config, startup-config, and the various
@@ -41,20 +173,12 @@ separate project. Going forward Infix' focus is entirely on NETCONF.
users to avoid enabling privileged mode
- Issue #367: setting date/time over NETCONF now saves system time also
to the RTC, which otherwise is only saved on reboot or power-down
- Add support for static multicast filters, MAC, IPv4 and IPv6 groups
are supported.
- Include Buildroot `legal-info` in releases, i.e., licenses, sources
with patches, as well as csv files for packages and toolchain
- Issue #369: Remove limitation that the routing instance must be
named 'default'
### Fixes
- Issue #391 Creating VLAN interface in the CLI with "edit interface vlanN"
does not set VLAN id to N.
- confd: Fix memory leak when operating on candidate configuration.
- CLI: fix VLAN inference for interfaces named `eth0.1`, i.e., VID 1 on
lower-layer-if `eth0`. Only affects automatic inference in the CLI,
entering the values manually (CLI/NETCONF) not affected by this bug
- confd: Fix memory leak when operating on candidate configuration
- probe: Fix crash on systems without USB
- Reduced syslog errors for accesses no non-existing xpaths
- Fix bogus warning about not properly updating `/etc/motd` in new
`motd-banner` setting, introduced in v24.02.0
@@ -63,8 +187,16 @@ separate project. Going forward Infix' focus is entirely on NETCONF.
- Fix #328: when setting up a VLAN filtering bridge, the PVID for bridge
ports defaulted to 1, making it impossible to set up "tagged-only"
ports which drop ingressing untagged traffic
- Fix #329: VLAN inference for interfaces named `eth0.1`, i.e., VID 1 on
lower-layer-if `eth0`. Only affects automatic inference in the CLI,
entering the values manually (CLI/NETCONF) not affected by this bug
- Fix #331: inconsistent naming of 'enabled' in infix-routing.yang
- Fix #349: minor changes to `bridge-port` settings, like setting `pvid`
when you forget it, did not take without a reboot
- Fix #353: impossible to remove bridge port with `no bridge-port`
- Fix #358: MAC address no longer shown for bridge interfaces in CLI
`show interfaces` command
- Fix #365: not possible to run `ping` from container
- Fix #366: static routes from container host interfaces do not work.
Documentation updated with an example
- Fix #368: upgrading `oci-archive:/` images fail because system thinks
@@ -74,11 +206,25 @@ separate project. Going forward Infix' focus is entirely on NETCONF.
declare `network` settings, Infix v23.02 had a late regression that
reverted back to the podman default: network behind a CNI bridge
(firewalled and NAT:ed, hidden from the rest of the network)
- Fix #385: segfault in helper function when disabling the DHCP client
- Fix #375: k8s-logger, used for containers, does not exit properly and
causes 100% CPU load when container stop or are restarted. Also in
this issue: handle ip/route additions to container networks at runtime
- Fix #384: segfault in helper function when disabling the DHCP client
using `no dhcp-client` from the CLI
- Fix #391 Creating VLAN interface in the CLI with "edit interface vlanN"
does not set VLAN id to N.
- Fix #404: `lldpd` should be disabled on internal interface `dsa0`
- Fix #406: an overly restrictive `when` expression in the bridge YANG
model prevented users from adding VLAN interfaces as bridge ports.
E.g., creating interface `eth0.10` and adding that to `br0`
- Fix #412: after starting up with DHCP client enabled on any interface
`set dhcp-client enabled false` does not bite at runtime
- Fix #414: spelling error in `infix-hardware.yang`, leaf node `coutry`
- Fix #415: `startup-config` owned by `root` user and group instead of
`admin`. The file ownership is now adjusted on every boot
- Fix #416: `admin` user cannot perform a factory reset with RPC using
`sysrepocfg` tool over SSH
- Fix bogus syslog warning about not updating `/etc/motd` properly
[v24.02.0][] - 2024-03-01
@@ -773,7 +919,11 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
- N/A
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.02.0...HEAD
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.04.0...HEAD
[v24.05.0]: https://github.com/kernelkit/infix/compare/v24.04.0...v24.05.0
[v24.04.2]: https://github.com/kernelkit/infix/compare/v24.04.1...v24.04.2
[v24.04.1]: https://github.com/kernelkit/infix/compare/v24.04.0...v24.04.1
[v24.04.0]: https://github.com/kernelkit/infix/compare/v24.02.0...v24.04.0
[v24.02.0]: https://github.com/kernelkit/infix/compare/v23.11.0...v24.02.0
[v23.11.0]: https://github.com/kernelkit/infix/compare/v23.10.0...v23.11.0
[v23.10.0]: https://github.com/kernelkit/infix/compare/v23.09.0...v23.10.0
+60 -19
View File
@@ -390,12 +390,30 @@ network:
### Container Host Interface
Another common use-case is to move a network interface into the network
namespace of a container. Which the container bridge network type does
behind the scenes with one end of the automatically created VETH pair.
This works with regular Ethernet interfaces as well, but here we will
use a VETH pair as an example along with a regular bridge (where other
Ethernet interfaces may live as well).
Another common use-case is to move network interfaces into the network
namespace of a container[^3]. This of course works with plain Ethernet
interfaces as well, but here we will use one end of a VETH pair as an
example.
[^3]: Something which the container bridge network type does behind the
scenes with one end of an automatically created VETH pair.
#### Routed Setup
In this routed setup we reserve 192.168.0.0/24 for the network between
the host and the `ntpd` container.
_____________
| |
veth0 .1 | .2 eth0 |
\ 192.168.0.0/24 | / |
'--------------------' [ntpd] |
|_____________|
Configuration is a straight-forward VETH pair setup where we name the
container-end of pair `ntpd`. This is just a convenience for us when
reading the configuration later. The *real action* happens on the last
line where we declare the `ntpd` end as a container network interface:
admin@example:/config/> edit interface veth0
admin@example:/config/interface/veth0/> set veth peer ntpd
@@ -403,23 +421,49 @@ Ethernet interfaces may live as well).
admin@example:/config/interface/veth0/> end
admin@example:/config/> edit interface ntpd
admin@example:/config/interface/ntpd/> set ipv4 address 192.168.0.2 prefix-length 24
admin@example:/config/interface/ntpd/> set phys-address 00:c0:ff:ee:00:01
admin@example:/config/interface/ntpd/> set container-network
This is a routed setup, where we reserve 192.168.0.0/24 for the network
between the host and the `ntpd` container. A perhaps more common case
is to put `veth0` as a port in a bridge with other physical ports. The
point of the routed case is that port forwarding from the container in
this case is limited to a single interface, not *all interfaces* as is
the default in the masquerading container bridge setup.
> Notice how you can also set a custom MAC address at the same time.
When a container has multiple host interfaces it can often be useful to
have a default route installed. This can be added from the host with a
`0.0.0.0/0` route on one of the interfaces. The following is an example
when adding a second VETH pair to the container:
Adding the interface to the container is the same as before, but since
everything for host interfaces is set up in the interfaces context, we
can take a bit of a shortcut.
admin@example:/config/container/ntpd/> set network ntpd
admin@example:/config/container/ntpd/> leave
The point of the routed case is that port forwarding from the container
in this case is limited to a single interface, not *all interfaces* as
is the default in the masquerading container bridge setup.
#### Bridged Setup
A perhaps more common case is to bridge the other end of the VETH pair
with other physical ports. In this section we show how to add a new
pair to give our container two interfaces:
_______________
| | .1 br0
veth0 .1 | .2 eth0 | / \
\ 192.168.0.0/24 | / eth1 .2 | veth1b e1
'------------------' \ | 192.168.1.0/24 /
| [ntpd] '------------------'
|_______________|
We start by adding the second VETH pair:
admin@example:/config/> edit interface veth1a
admin@example:/config/interface/veth1a/> set veth peer veth1b
admin@example:/config/interface/veth1a/> set ipv4 address 192.168.1.2 prefix-length 24
> The LAN bridge (br0) in this example has IP address 192.168.1.1.
When a container has multiple host interfaces it can often be useful to
have a default route installed. This can be added from the host with a
`0.0.0.0/0` route on one of the interfaces:
admin@example:/config/interface/veth1a/> set container-network route 0.0.0.0/0 gateway 192.168.1.1
admin@example:/config/interface/veth1a/> show
type veth;
@@ -439,9 +483,6 @@ Please note, container network routes require the base interface also
have a static IP address set. Setting only the route, but no address,
means the route is skipped.
> The LAN bridge (br0) in this example has IP address 192.168.1.1.
### Host Networking
The third use-case is host networking, this is where a container share
+43 -6
View File
@@ -66,7 +66,8 @@ The instructions here are for Debian/Ubuntu based systems (YMMV):
$ sudo apt install bc binutils build-essential bzip2 cpio \
diffutils file findutils git gzip \
libncurses-dev libssl-dev perl patch \
python rsync sed tar unzip wget
python3 rsync sed tar unzip wget \
autopoint bison flex
```
For testing, a few more tools and services are required on your system:
@@ -96,8 +97,10 @@ To see available defconfigs for supported targets, use:
Development
-----------
When changing a package, locally kept sources, or when using [`local.mk`](override-package.md),
you only want to rebuild the parts you have modified:
Developing with Infix is the same as [developing with Buildroot][4].
When working with a package, be it locally kept sources, or when using
[`local.mk`](override-package.md), you only want to rebuild the parts
you have modified:
make foo-rebuild
@@ -105,7 +108,7 @@ or
make foo-reconfigure
or, when nothing seems to bite:
or, as a last resort when nothing seems to bite:
make foo-dirclean foo-rebuild
@@ -118,6 +121,38 @@ This rebuilds (and installs) `foo` and `bar`, the `all` target calls
on Buildroot to finalize the target filesystem and generate the images.
The final `run` argument is explained below.
### `confd`
The Infix `src/confd/` is the engine of the system. Currently it is a
plugin for `systemd-plugind` and contains XPath subscriptions to all the
supported YANG models.
There are essentially two ways of adding support for a new YANG model:
- The [sysrepo way][3], or
- The Infix way, using libsrx (the `lydx_*()` functions)
The former is well documented in sysrepo, and the latter is best taught
by example, e.g., `src/confd/src/infix-dhcp.c`. Essentially libsrx is a
way of traversing the libyang tree instead of fetching changes by XPath.
When working with `confd` you likely want to enable full debug mode,
this is how you do it:
1. Open the file `package/confd/confd.conf`
2. Uncomment the first line `set DEBUG=1`
3. Change the following line to add `-v3` at the end
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
to:
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -v3 -- Configuration daemon
Now you can rebuild `confd`, just as described above, and restart Infix:
make confd-rebuild all run
Testing
-------
@@ -141,8 +176,8 @@ and then use GitHub to create a *Pull Reqeuest*.
For this to work as painlessly as possible:
1. Fork Infix to your own user or organization[^1]
2. Fork all the Infix submodules, e.g., `buildroot` to your own user
or organization as well
2. 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
If you use a GitHub organization you get the added benefit of having
@@ -169,3 +204,5 @@ $ git submodule update --init
[0]: https://github.com/kernelkit/infix/releases
[1]: https://buildroot.org/downloads/manual/manual.html
[2]: https://github.com/wkz/qeneth
[3]: https://netopeer.liberouter.org/doc/sysrepo/master/html/dev_guide.html
[4]: https://buildroot.org/downloads/manual/manual.html#_developer_guide
+167
View File
@@ -114,6 +114,169 @@ admin@example:/config/interface/br0/> set bridge vlans vlan 20 tagged br0
> on top of the bridge, see section [VLAN Interfaces](#vlan-interfaces)
> below for more on this topic.
#### Multicast Filtering and Snooping
Multicast filtering in the bridge is handled by the bridge itself. It
can filter both IP multicast and MAC multicast. For IP multicast it
also supports "snooping", i.e., IGMP and MLD, to automatically reduce
the broadcast effects of multicast. See the next section for a summary
of the [terminology used](#terminology--abbreviations).
> **Note:** currently there is no way to just enable multicast filtering
> without also enabling snooping. This may change in the future, in
> which case a `filtering` enabled setting will be made available along
> with the existing `snooping` setting.
When creating your bridge you must decide if you need a VLAN filtering
bridge or a plain bridge (see previous section). Multicast filtering is
supported for either, but take note that it must be enabled and set up
per VLAN when VLAN filtering is enabled -- there are no global multicast
settings in this operating mode.
In the following example we have a regular 8-port bridge without VLAN
filtering. We focus on the multicast specific settings:
```
admin@example:/> configure
admin@example:/config/> edit interface br0
admin@example:/config/interface/br0/> set bridge multicast snooping
admin@example:/config/interface/br0/> set ipv4 address 192.168.2.1 prefix-length 24
admin@example:/config/interface/br0/> leave
admin@example:/> copy running-config startup-config
```
Here we enable snooping and set a static IPv4 address so that the switch
can take part in IGMP querier elections. (MLD querier election
currently not supported.) We can inspect the current state:
```
admin@example:/> show ip multicast
Multicast Overview
Query Interval (default): 125 sec
Router Timeout : 255
Fast Leave Ports :
Router Ports :
Flood Ports : e0, e1, e2, e3, e4, e5, e6, e7
Interface VID Querier State Interval Timeout Ver
br0 192.168.2.1 Up 125 None 3
Bridge VID Multicast Group Ports
br0 224.1.1.1 e3, e2
br0 ff02::6a br0
```
It is a small LAN, so our bridge has already become the elected IGMP
querier. We see it is ours because the timeout is `None`, and we
recognize our IP address. We can also see two ports that have joined
the same IPv4 multicast group, 224.1.1.1, and one join from Infix itself
for the IPv6 group ff02::6a.
Now, let's see what happens when we add another bridge, with VLAN
filtering enabled. We skip the boring parts about how to move ports
e4-e7 to `br1` and assign them to VLANs, and again, focus on the
multicast bits only:
```
admin@example:/> configure
admin@example:/config/> edit interface br1
admin@example:/config/interface/br1/> set bridge vlans vlan 1 multicast snooping
admin@example:/config/interface/br1/> set bridge vlans vlan 2 multicast snooping
admin@example:/config/interface/br1/> leave
admin@example:/> copy running-config startup-config
```
Let's see what we get:
```
admin@example:/> show ip multicast
Multicast Overview
Query Interval (default): 125 sec
Router Timeout : 255
Fast Leave Ports : e5
Router Ports : e1, e2, e5, e6, e7
Flood Ports : e1, e2, e3, e4, e5, e6, e7, e8
Interface VID Querier State Interval Timeout Ver
br0 192.168.2.1 Up 125 None 3
br1 1 0.0.0.0 Up 125 None 3
br1 2 0.0.0.0 Up 125 None 3
Bridge VID Multicast Group Ports
br0 224.1.1.1 e2
br0 ff02::fb br0
br0 ff02::6a br0
br0 ff02::1:ff00:0 br0
br1 1 224.1.1.1 e5
br1 2 224.1.1.1 e7
br1 1 ff02::fb br1
br1 1 ff02::1:ff00:0 br1
```
In this setup we have a lot more going on. Multiple multicast router
ports have been detected, and behind the scenes someone has also added
an IGMP/MLD fast-leave port.
##### Terminology & Abbreviations
- **IGMP**: Internet Group Membership Protocol, multicast subscription
for IPv4, for details see [RFC3376][]
- **MLD**: Multicast Listener Discovery (Protocol), multicast
subscription for IPv6, for details see [RFC3810][]
- **Unknown/Unregistered multicast**: multicast groups that are *not*
in the multicast forwarding database (MDB)
- **Known/Registered multicast**: multicast groups that *are* in the
multicast forwarding database (MDB)
- **MDB**: the multicast forwarding database, consists of filters for
multicast groups, directing where multicast is allowed to egress. A
filter entry consists of a group and a port list. The bridge filters
with a unique database per VLAN, in the same was as the unicast FDB
- **Join/Leave**: the terminology used in earlier versions of the two
protocols to subscribe and unsubscribe to a multicast group. For
more information, see *Membership Report*
- **Membership Report** A membership report is sent by end-devices and
forwarded by switches to the elected querier on the LAN. They
consist of multiple "join" and "leave" operations on groups. They
can also, per group, list which senders to allow or block. Switches
usually only support the group subscription, and even more common
also only support filtering on the MAC level[^3]
- **Querier election**: the process of determining who is the elected
IGMP/MLD querier on a LAN. Lowest numerical IP address wins, the
special address 0.0.0.0 (proxy querier) never wins
- **Proxy querier**: when no better querier exists on a LAN, one or
more devices can send proxy queries with source address 0.0.0.0 (or
:: for IPv6). See **Query Interval**, below, why this is a good
thing
- **Query interval**: the time in seconds between two queries from an
IGMP/MLD querier. It is not uncommon that end-devices do not send
their membership reports unless they first hear a query
- **Fast Leave**: set on a bridge port to ensure multicast is pruned as
quickly as possible when a "leave" membership report is received. In
effect, this option marks the port as directly connected to an
end-device. When not set (default), a query with timeout is first
sent to ensure no unintentional loss of multicast is incurred
- **Router port**: can be both configured statically and detected at
runtime based on connected devices, usually multicast routers. On
a router port *all* multicast is forwarded, both known and unknown
- **Flood port**: set on a bridge port (default: enabled) to ensure
all *unknown* multicast is forwarded
- **Router timeout**: the time in seconds until a querier is deemed to
have been lost and another device (switch/router) takes over. In the
tables shown above, a *None* timeout is declared when the current
device is the active querier
> **Note:** the reason why multicast flooding is enabled by default is
> to ensure safe co-existence with MAC multicast, which is very common
> in industrial networks. It also allows end devices that do not know
> of IGMP/MLD to communicate over multicast as long as the group they
> have chosen is not used by other IGMP/MLD aware devices on the LAN.
>
> As soon as an IGMP/MLD membership report to "join" a group is received
> the group is added to the MDB and forwarding to other ports stop. The
> only exception to this rule is multicast router ports.
[RFC3376]: https://www.rfc-editor.org/rfc/rfc3376.html
[RFC3810]: https://www.rfc-editor.org/rfc/rfc3810.html
### VLAN Interfaces
@@ -634,3 +797,7 @@ currently supported, namely `ipv4` and `ipv6`.
[^2]: Link-local IPv6 addresses are implicitly enabled when enabling
IPv6. IPv6 can be enabled/disabled per interface in the
[ietf-ip][2] YANG model.
[^3]: For example, IPv4 groups are mapped to MAC multicast addresses by
mapping the low-order 23-bits of the IP address in the low-order 23
bits of the Ethernet address 01:00:5E:00:00:00. Meaning, more than
one IP multicast group maps to the same MAC multicast group.
+53 -28
View File
@@ -1,50 +1,75 @@
Package override
Package Override
================
This guide demonstrates how the `local.mk` file is utilized to override
a Linux Buildroot package. The example of `tcpdump` serves to illustrate
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.
In an instance such as `Infix` using tcpdump, the `local.mk` file is modified
as shown below:
> 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.
Setup
-----
Since the `output/` directory is often wiped for rebuilds, make sure you
keep the file `local.mk` in the top directory and only symlink it to your
build directory:
~$ cd infix/
~/infix(main)$ touch local.mk
~/infix/output(main)$ ln -s ../local.mk .
~/infix/output(main)$ cd ..
Override
--------
Now edit the file:
~/infix(main)$ editor local.mk
Add an override for `tcpdump`. The file is a Makefile snippet so you
can add a lot of things. Comment out lines with the UNIX comment `#`
character if needed:
```
TCPDUMP_OVERRIDE_SRCDIR = /path/to/tcpdump/repo
```
and stored in the `output/` folder, alongside the `.config` file:
```
user@PC:~/infix$ll output/ | grep -e 'local.mk' -e '.config'
-rw-r--r-- 1 group user 119936 Nov 10 18:04 .config
-rw-r--r-- 1 group user 43 Nov 10 18:25 local.mk
```
Building
--------
The execution of `make tcpdump-rebuild all` triggers a process where
Buildroot synchronizes the tcpdump source code from the specified override directory
to `output/build/tcpdump-custom`, followed by the rebuilding of the entire project.
The execution of `make tcpdump-rebuild all` triggers a process where
Buildroot synchronizes the tcpdump source code from the specified
override directory to `output/build/tcpdump-custom`, followed by the
rebuilding of the entire project.
```
user@PC:~/infix$ make tcpdump-rebuild all
~/infix$(main)$ make tcpdump-rebuild all
```
Buildroot follows a process of downloading and processing tarballs:
extraction, configuration, compilation, and installation. The source
for each package is extracted to a temporary build directory:
output/build/<package>-<version> # e.g., tcpdump-4.99.4
Let's have a look at what we got:
```
user@PC:~/infix$ ll /output/build/ | grep tcpdump
~/infix$(main)$ ll /output/build/ | grep tcpdump
drwxr-xr-x 7 group user 20480 Nov 10 18:26 tcpdump-4.99.4/
drwxr-xr-x 7 group user 12288 Nov 10 18:28 tcpdump-custom/
```
Buildroot follows a process of downloading and processing tarballs
(extraction, configuration, compilation, and installation).
The source code is stored in a temporary directory:
`output/build/<package>-<version>` (i.e. `tcpdump-4.99.4/`),
which is removed and recreated with each `make` command. That is why
the direct modifications in the `output/build` directory are generally
**not recommended**.
As long as your local override is in place, Buildroot will use your
custom version.
To manage the development changes more effectively, where the package source code
remains untouched, Buildroot incorporates the `<pkg>_OVERRIDE_SRCDIR` feature.
> **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.
For a comprehensive understanding of utilizing Buildroot during development,
including detailed elaboration on the `<pkg>_OVERRIDE_SRCDIR` feature,
refer to section 8.13.6 in [Using Buildroot during development](https://nightly.buildroot.org/).
[1]: https://buildroot.org/downloads/manual/manual.html#_using_buildroot_during_development
+808 -3
View File
@@ -168,9 +168,9 @@ There are two ways to do it:
1. Change the configuration without saving it to `startup-config`
2. Change the operational state
The first involves sending a NETCONF command/config in XML, the second
we will cover here. We start by querying available interfaces (ports)
on the remote system:
The first involves sending a NETCONF command/config in XML. The second
we will cover here. We start by querying available interfaces (ports) on
the remote system:
```
~$ ssh admin@infix.local%qtap0 ip -br a
@@ -331,6 +331,811 @@ admin@infix.local%eth0's password: *****
~$
```
### Controlling LEDs for Production Tests
As part of production testing, LED verification is often expected to
be performed. Infix uses standard [Linux support for LED
management][6], where LEDs appear in the file system under
/sys/class/leds and can be controlled using *echo* command. `sudo`
privileges are required.
When interacting with LEDs this way, first disable the Infix *iitod*
daemon to avoid conflicting LED control.
```
~$ ssh admin@example.local 'initctl stop iitod'
```
Then run the test, e.g., visually control that a red LED labeled
'LAN' is working.
```
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
~$ ssh admin@example.local 'echo 1 | sudo tee /sys/class/leds/red\:lan/brightness'
```
To turn off the same LED, run the following commands.
```
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
~$ ssh admin@example.local 'echo 0 | sudo tee /sys/class/leds/red\:lan/brightness'
```
When done with LED testing, enable Infix *iitod* daemon again.
```
~$ ssh admin@example.local 'initctl start iitod'
```
### Reading Power Feed Status for Production Tests
As part of production tests, verification of Power Feed sensors is
often expected to be performed. Infix uses standard [Linux support for
Power management][7], where power sources appear in the file system
under /sys/class/power_supply. The following example reads status of
two power supplies named *pwr1* and *pwr2*.
```
~$ ssh admin@example 'cat /sys/class/power_supply/pwr1/online'
1
~$ ssh admin@example 'cat /sys/class/power_supply/pwr2/online'
0
~$
```
Here, only *pwr1* happened to have power.
## Examples using SSH and sysrepocfg
[sysrepocfg][4] can be used to interact with the YANG models when logged
in to infix. Thus, *set config*, *read config*, *read status* and
*RPC* can be conducted using sysrepocfg for supported YANG models.
It is possible to make configuration changes by operating on the
*startup* database.
See [sysrepocfg][4] for 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 examples below we assume
it been transferred to Infix in advance, e.g. using `scp` as shown below.
```
~$ cat file.json
{
"ietf-factory-default:factory-reset": {
}
}
~$ scp file.json admin@example.local:/tmp/file.json
~$
```
### Factory Reset Using sysrepocfg
```
~$ 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](#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 Using sysrepocfg
```
~$ 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](#system-reboot) for another (simpler) alternative.
### Set Date and Time Using sysrepocfg
```
~$ 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](#set-date-and-time) for another (simpler) alternative.
### Remote Control of Ethernet Ports Using sysrepocfg
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
~$
```
### <a id="backup"></a> Backup Configuration Using sysrepocfg And scp
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
~$
```
### <a id="restore"></a> Restore Configuration Using sysrepocfg and ssh/scp
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: admin login credentials (hash) 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 Using sysrepocfg
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 Out Hardware Information Using sysrepocfg
Infix supports IETF Hardware YANG with augments for ONIE formatted
production data stored in EEPROMs, if available. See Infix [VPD
documentation][5], as well as *ietf-hardware* and *infix-hardware* YANG
models for details.
```
~$ 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"
}
}
]
}
}
~$
```
## Miscellaneous
### <a id="port-test-intro"></a> Port Configuration Example for Production Tests
As part of production tests, verification Ethernet ports are expected
to be performed. A common way 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
[above](#restore).
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).
> 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).
``` shell
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 example below uses Infix documentation on [creating bridges][8].
``` shell
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 interface" after
leaving configuration context. If configuration via SSH, first assign
an IP address to br0 before *leaving* configuration context, e.g.,
`set interface br0 ipv6 enabled` to get auto-configured IPv6
address. Or skip 'leave' and stay in configuration context until done
with all sections, including the one on [Add IP on
Switch](#ip-on-switch).
``` shell
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
Then configure VLANs as outlined [above](#port-test-intro):
default VID for ingress (PVID), which is done per port, and egress
mode (untagged), which is done at the bridge level. See Infix
[documentation for VLAN bridges][9] for more information.
``` shell
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
``` shell
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, and the other ports are
patched according to plan [above](#port-test-intro). We should get
link up on all ports.
``` shell
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.
> A recommendation is to use network name spaces on PC to ensure
> traffic really goes out to switch, instead of being looped
> internally. Or use two PCs.
``` shell
~ $ 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
``` shell
~ $ 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
~ $
```
#### <a id="ip-on-switch"></a> Add IP Address on Switch
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.
``` shell
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.
``` shell
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.
``` shell
~ $ 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).
``` shell
~ $ ssh admin@fe80::0053:00ff:fe06:1101%eth1
admin@fe80::0053:00ff:fe06:1101%eth1's password:
.-------.
| . . | Infix -- a Network Operating System
|-. v .-| https://kernelkit.github.io
'-'---'-'
Run the command 'cli' for interactive OAM
admin@example:~$ exit
~ $
```
See previous sections on [backup](#backup) and [restore](#restore) of
the created configuration.
[1]: discovery.md
[2]: https://rauc.io/
[3]: boot.md#system-upgrade
[4]: https://netopeer.liberouter.org/doc/sysrepo/libyang1/html/sysrepocfg.html
[5]: vpd.md
[6]: https://docs.kernel.org/leds/leds-class.html
[7]: https://docs.kernel.org/power/power_supply_class.html
[8]: networking.md#bridging
[9]: networking.md#vlan-filtering-bridge
+67
View File
@@ -70,6 +70,72 @@ admin@host:/config/system/authentication/user/admin/authorized-key/example@host/
> does the job.
## Multiple Users
The system supports multiple users and multiple user levels, or groups,
that a user can be a member of. Access control is entirely handled by
the NETCONF ["NACM"][3] YANG model, which provides granular access to
configuration, data, and RPC commands over NETCONF.
By default the system ships with a single group, `admin`, which the
default user `admin` is a member of. The broad permissions granted by
the `admin` group is what gives its users full system administrator
privileges. There are no restrictions on the number of users with
administrator privileges, nor is the `admin` user reserved or protected
in any way -- it is completely possible to remove the default `admin`
user from the configuration. However, it is recommended to keep at
least one user with administrator privileges in the system, otherwise
the only way to regain full access is to perform a *factory reset*.
### Adding a User
Similar to how to change password, adding a new user is done using the
same set of commands:
```
admin@host:/config/> edit system authentication user jacky
admin@host:/config/system/authentication/user/jacky/> change password
New password:
Retype password:
admin@host:/config/system/authentication/user/jacky/> leave
```
An authorized SSH key is added the same way as presented previously.
### Adding a User to the Admin Group
The following commands add user `jacky` to the `admin` group.
```
admin@host:/config/> edit nacm group admin
admin@host:/config/nacm/group/admin/> set user-name jacky
admin@host:/config/nacm/group/admin/> leave
```
### Security Aspects
The NACM user levels apply primarily to NETCONF, with exception of the
`admin` group which is granted full system administrator privileges to
the underlying UNIX system with the following ACL rules:
```json
...
"module-name": "*",
"access-operations": "*",
"action": "permit",
...
```
A user in the `admin` group is allowed to also use a POSIX login shell
and use the `sudo` command to perform system administrative commands.
This makes it possible to use all the underlying UNIX tooling, which
to many can be very useful, in particular when debugging a system, but
please remember to use with care -- the system is not built to require
managing from the shell. The tools available in the CLI and automated
services, started from the system's configuration, are the recommended
way of using the system, in addition to NETCONF tooling.
## Changing Hostname
Notice how the hostname in the prompt does not change until the change
@@ -137,3 +203,4 @@ admin@host:/>
[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
+246
View File
@@ -0,0 +1,246 @@
Test System Architecture
========================
Tenets
------
- **Keep overhead to a minimum**. Tests should be fast to both write
and run. Ideally, the developer should _want_ to add tests early in
the development cycle because they instinctively feel that that is
the quickest route to arrive at a correct and robust implementation.
- **Both physical and virtual hardware matters**. Infix is primarily
deployed on physical hardware, so being able to run the test suite
on real devices is crucial to guarantee a high quality product. At
the same time, there is much value in running the same suite on
virtual hardware, as it makes it easy to catch regressions early.
It is also much more practical and economical to build large virtual
networks than physical ones.
- **Avoid CLI scipting & scraping**. Reliably interacting with a DUT
over a serial line in a robust way is _very_ hard to get right.
Given that we have a proper API (RESTCONF), we should leverage that
when testing. Front-ends can be tested by other means.
Overview
--------
![Infix Testing Architecture](img/testing-overview.svg)
The test system is made up of several independent components, which
are typically used in concert to run a full test suite.
### Test Cases
A test case is an executable, receiving the physical topology as a
positional argument, which produces [TAP][] compliant output on its
`stdout`. I.e., it is executed in the following manner:
test-case [OPTS] <physical-topology>
Test cases are typically written in Python, using the
[Infamy](#infamy) library. Ultimately though, it can be implemented
in any language, as long as it matches the calling convention above.
### Infamy
Rather than having each test case come up with its own implementation
of how to map topologies, how to push NETCONF data to a device, etc.,
we provide a library of functions to take care of all that, dubbed
"Infamy". When adding a new test case, ask yourself if any parts of
it might belong in Infamy as a generalized component that can be
reused by other tests.
Some of the core functions provided by Infamy are:
- Mapping a logical topology to a physical one
- Finding and attaching to a device over an Ethernet interface, using
NETCONF
- Pushing/pulling NETCONF data to/from a device
- Generating TAP compliant output
### 9PM
To run multiple tests, we employ [9PM][]. It let's us define test
suites as simple YAML files. Suites can also be hierarchically
structured, with a suite being made up of other suites, etc.
It also validates the TAP output, making sure to catch early exits
from a case, and produces a nice summary report.
### `/test/env`
A good way to ensure that nobody ever runs the test suite is to make
it _really_ hard to do so. `/test/env`'s job is instead to make it
very _easy_ to create a reproducible environment in which tests can be
executed.
Several technologies are leveraged to accomplish this:
- **Containers**: The entire execution is optionally done inside a
standardized `docker` container environment. This ensures that the
software needed to run the test suite is always available, no matter
which distribution the user is running on their machine.
- **Python Virtual Environments**: To make sure that the expected
versions of all Python packages are available, the execution is
wrapped inside a `venv`. This is true for containerized executions,
where the container comes with a pre-installed environment, but it
can also be sourced from the host system when running outside of the
container.
- **Virtual Test Topology**: Using [Qeneth][], the environment can
optionally be started with a virtual topology of DUTs to run the
tests on.
> `docker` is the only supported container environment when running
> tests in the host's network namespace. When running on a virtual
> Qeneth topology, `podman` may also be used by installing the
> `podman-docker` package from your host system's distro.
Physical and Logical Topologies
-------------------------------
Imagine that we want to create a test with three DUTs; one acting as a
DHCP server, and the other two as DHCP clients - with all three having
a management connection to the host PC running the test. In other
words, the test requires a _logical_ topology like the one below.
<img align="right" src="img/testing-log.dot.svg" alt="Example Logical Topology">
```dot
graph "dhcp-client-server" {
host [
label="host | { <c1> c1 | <srv> srv | <c2> c2 }",
kind="controller",
];
server [
label="{ <mgmt> mgmt } | server | { <c1> c1 | <c2> c2 }",
kind="infix",
];
client1 [
label="{ <mgmt> mgmt } | client1 | { <srv> srv }",
kind="infix",
];
client2 [
label="{ <mgmt> mgmt } | client2 | { <srv> srv }",
kind="infix",
];
host:srv -- server:mgmt
host:c1 -- client1:mgmt
host:c2 -- client2:mgmt
server:c1 -- client1:srv;
server:c2 -- client2:srv;
}
```
When running in a virtualized environment, one could simply create a
setup that matches the test's logical topology. But in scenarios when
devices are physical systems, connected by real copper cables, this is
not possible (unless you have some wicked L1 relay matrix thingy).
Instead, the test implementation does not concern itself with the
exact nodes used to run the test, only that the _logical_ topology can
be _mapped_ to some subset of the _physical_ topology. In
mathematical terms, the physical topology must contain a subgraph that
is _isomorphic_ to the logical topology.
Standing on the shoulders of giants (i.e. people with mathematics
degrees), we can deploy well-known algorithms to find such subgraphs.
Continuing our example, let's say we want to run our DHCP test on the
_physical_ topology below.
<img align="right" src="img/testing-phy.dot.svg" alt="Example Physical Topology">
```dot
graph "quad-ring" {
host [
label="host | { <d1a> d1a | <d1b> d1b | <d1c> d1c | <d2a> d2a | <d2b> d2b | <d2c> d2c | <d3a> d3a | <d3b> d3b | <d3c> d3c | <d4a> d4a | <d4b> d4b | <d4c> d4c }",
kind="controller",
];
dut1 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut1 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut2 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut2 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut3 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut3 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut4 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut4 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
host:d1a -- dut1:e1
host:d1b -- dut1:e2
host:d1c -- dut1:e3
host:d2a -- dut2:e1
host:d2b -- dut2:e2
host:d2c -- dut2:e3
host:d3a -- dut3:e1
host:d3b -- dut3:e2
host:d3c -- dut3:e3
host:d4a -- dut4:e1
host:d4b -- dut4:e2
host:d4c -- dut4:e3
dut1:e5 -- dut2:e4
dut2:e5 -- dut3:e4
dut3:e5 -- dut4:e4
dut4:e5 -- dut1:e4
}
```
Our test (in fact, all tests) receives the physical topology as an
input parameter, and then maps the desired logical topology onto it,
producing a mapping from logical nodes and ports to their physical
counterparts.
```dot
{
"client1": "dut1",
"client1:mgmt": "dut1:e1",
"client1:srv": "dut1:e4",
"client2": "dut3",
"client2:mgmt": "dut3:e2",
"client2:srv": "dut3:e5",
"host": "host",
"host:c1": "host:d1a",
"host:c2": "host:d3b",
"host:srv": "host:d4c",
"server": "dut4",
"server:c1": "dut4:e5",
"server:c2": "dut4:e4",
"server:mgmt": "dut4:e3"
}
```
With this information, the test knows that, in this particular
environment, the server should be managed via the port called `d4c` on
the node called `host`; that the port connected to the server on
`client1` is `e4` on `dut1`, etc. Thereby separating the
implementation of the test from any specific physical setup.
Testcases are not required to use a logical topology; they may choose
to accept whatever physical topology its given, and dynamically
determine the DUTs to use for testing. As an example, an STP test
could accept an arbitrary physical topology, run the STP algorithm on
it offline, enable STP on all DUTs, and then verify that the resulting
spanning tree matches the expected one.
[9PM]: https://github.com/rical/9pm
[Qeneth]: https://github.com/wkz/qeneth
[TAP]: https://testanything.org/
+130 -284
View File
@@ -7,287 +7,57 @@ that one or more DUTs are configured over NETCONF; the resulting
network is then black-box tested by injecting and inspecting network
traffic at various points.
This document is intended to be a practical guide on how to run,
develop and debug tests. There is a separate document describing the
[Test System Architecture](test-arch.md).
TL;DR
-----
Build Infix and run the test suite on a set of virtual Infix nodes.
Modes of Testing
----------------
### Virtual Devices
By default, tests are run on a topology made up of virtual Infix nodes
using [Qeneth][]. To run the full regression test suite: build Infix
for `x86_64`:
$ make x86_64_defconfig
$ make
$ make test
To run a subset of tests, e.g., only the DHCP client tests:
### Physical Devices
$ make test INFIX_TESTS=case/infix_dhcp/all.yaml
To run the tests on a preexisting topology from the host's network
namespace, specify the `host` `TEST_MODE`:
> **Note:** see the below section [Quick Start Guide][] for how to
> connect to the test system, debug and develop tests, and more.
$ make TEST_MODE=host test
This typically used when testing on physical hardware. By default the
topology will be sourced from `/etc/infamy.dot`, but this can be
overwritten by setting the `TOPOLOGY` variable:
$ make TEST_MODE=host TOPOLOGY=~/my-topology.dot test
Tenets
------
### `make run` Devices
- **Keep overhead to a minimum**. Tests should be fast to both write
and run. Ideally, the developer should _want_ to add tests early in
the development cycle because they instinctively feel that that is
the quickest route to arrive at a correct and robust implementation.
Some tests only require a single DUT. These can therefore be run
against an Infix image started from `make run`. This requires that the
instance is configured to use TAP networking.
- **Both physical and virtual hardware matters**. Infix is primarily
deployed on physical hardware, so being able to run the test suite
on real devices is crucial to guarantee a high quality product. At
the same time, there is much value in running the same suite on
virtual hardware, as it makes it easy to catch regressions early.
It is also much more practical and economical to build large virtual
networks than physical ones.
When the instance is running, you can open a separate terminal and run
the subset of the test suite that can be mapped to it:
- **Avoid CLI scipting & scraping**. Reliably interacting with a DUT
over a serial line in a robust way is _very_ hard to get right.
Given that we have a proper API (RESTCONF), we should leverage that
when testing. Front-ends can be tested by other means.
Architectural Overview
----------------------
![Infix Testing Architecture](img/testing-overview.svg)
The test system is made up of several independent components, which
are typically used in concert to run a full test suite.
### Test Cases
A test case is an executable, receiving the physical topology as a
positional argument, which produces [TAP][] compliant output on its
`stdout`. I.e., it is executed in the following manner:
test-case [OPTS] <physical-topology>
Test cases are typically written in Python, using the
[Infamy](#infamy) library. Ultimately though, it can be implemented
in any language, as long as it matches the calling convention above.
### Infamy
Rather than having each test case come up with its own implementation
of how to map topologies, how to push NETCONF data to a device, etc.,
we provide a library of functions to take care of all that, dubbed
"Infamy". When adding a new test case, ask yourself if any parts of
it might belong in Infamy as a generalized component that can be
reused by other tests.
Some of the core functions provided by Infamy are:
- Mapping a logical topology to a physical one
- Finding and attaching to a device over an Ethernet interface, using
NETCONF
- Pushing/pulling NETCONF data to/from a device
- Generating TAP compliant output
### 9PM
To run multiple tests, we employ [9PM][]. It let's us define test
suites as simple YAML files. Suites can also be hierarchically
structured, with a suite being made up of other suites, etc.
It also validates the TAP output, making sure to catch early exits
from a case, and produces a nice summary report.
### `/test/env`
A good way to ensure that nobody ever runs the test suite is to make
it _really_ hard to do so. `/test/env`'s job is instead to make it
very _easy_ to create a reproducible environment in which tests can be
executed.
Several technologies are leveraged to accomplish this:
- **Containers**: The entire execution is optionally done inside a
standardized container environment, using either `podman` or
`docker`. This ensures that the software needed to run the test
suite is always available, no matter which distribution the user is
running on their machine.
- **Python Virtual Environments**: To make sure that the expected
versions of all Python packages are available, the execution is
wrapped inside a `venv`. This is true for containerized executions,
where the container comes with a pre-installed environment, but it
can also be sourced from the host system when running outside of the
container.
- **Virtual Test Topology**: Using [Qeneth][], the environment can
optionally be started with a virtual topology of DUTs to run the
tests on.
$ make TEST_MODE=run test
Interactive Usage
-----------------
Some tests only require a single DUT. These can therefore be run
against an Infix image started from `make run`. When the instance is
running, you can open a separate terminal and run `make test-run`, to
run the subset of the test suite that can be mapped to it.
Both `make test` and `make test-run` targets have a respective target
with a `-sh` suffix. These can be used to start an interactive session
in the reproducible environment, which is usually much easier to work
with during a debugging session.
Inside the reproducible environment, a wrapper for Qeneth is created for
the running network's directory. E.g., calling `qeneth status` inside a
`make test-sh` environment show the expected status information.
> **Note:** for more information and help writing a test, see the below
> [Quick Start Guide][].
Physical and Logical Topologies
-------------------------------
Imagine that we want to create a test with three DUTs; one acting as a
DHCP server, and the other two as DHCP clients - with all three having
a management connection to the host PC running the test. In other
words, the test requires a _logical_ topology like the one below.
<img align="right" src="img/testing-log.dot.svg" alt="Example Logical Topology">
```dot
graph "dhcp-client-server" {
host [
label="host | { <c1> c1 | <srv> srv | <c2> c2 }",
kind="controller",
];
server [
label="{ <mgmt> mgmt } | server | { <c1> c1 | <c2> c2 }",
kind="infix",
];
client1 [
label="{ <mgmt> mgmt } | client1 | { <srv> srv }",
kind="infix",
];
client2 [
label="{ <mgmt> mgmt } | client2 | { <srv> srv }",
kind="infix",
];
host:srv -- server:mgmt
host:c1 -- client1:mgmt
host:c2 -- client2:mgmt
server:c1 -- client1:srv;
server:c2 -- client2:srv;
}
```
When running in a virtualized environment, one could simply create a
setup that matches the test's logical topology. But in scenarios when
devices are physical systems, connected by real copper cables, this is
not possible (unless you have some wicked L1 relay matrix thingy).
Instead, the test implementation does not concern itself with the
exact nodes used to run the test, only that the _logical_ topology can
be _mapped_ to some subset of the _physical_ topology. In
mathematical terms, the physical topology must contain a subgraph that
is _isomorphic_ to the logical topology.
Standing on the shoulders of giants (i.e. people with mathematics
degrees), we can deploy well-known algorithms to find such subgraphs.
Continuing our example, let's say we want to run our DHCP test on the
_physical_ topology below.
<img align="right" src="img/testing-phy.dot.svg" alt="Example Physical Topology">
```dot
graph "quad-ring" {
host [
label="host | { <d1a> d1a | <d1b> d1b | <d1c> d1c | <d2a> d2a | <d2b> d2b | <d2c> d2c | <d3a> d3a | <d3b> d3b | <d3c> d3c | <d4a> d4a | <d4b> d4b | <d4c> d4c }",
kind="controller",
];
dut1 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut1 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut2 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut2 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut3 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut3 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
dut4 [
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut4 | { <e4> e4 | <e5> e5 }",
kind="infix",
];
host:d1a -- dut1:e1
host:d1b -- dut1:e2
host:d1c -- dut1:e3
host:d2a -- dut2:e1
host:d2b -- dut2:e2
host:d2c -- dut2:e3
host:d3a -- dut3:e1
host:d3b -- dut3:e2
host:d3c -- dut3:e3
host:d4a -- dut4:e1
host:d4b -- dut4:e2
host:d4c -- dut4:e3
dut1:e5 -- dut2:e4
dut2:e5 -- dut3:e4
dut3:e5 -- dut4:e4
dut4:e5 -- dut1:e4
}
```
Our test (in fact, all tests) receives the physical topology as an
input parameter, and then maps the desired logical topology onto it,
producing a mapping from logical nodes and ports to their physical
counterparts.
```dot
{
"client1": "dut1",
"client1:mgmt": "dut1:e1",
"client1:srv": "dut1:e4",
"client2": "dut3",
"client2:mgmt": "dut3:e2",
"client2:srv": "dut3:e5",
"host": "host",
"host:c1": "host:d1a",
"host:c2": "host:d3b",
"host:srv": "host:d4c",
"server": "dut4",
"server:c1": "dut4:e5",
"server:c2": "dut4:e4",
"server:mgmt": "dut4:e3"
}
```
With this information, the test knows that, in this particular
environment, the server should be managed via the port called `d4c` on
the node called `host`; that the port connected to the server on
`client1` is `e4` on `dut1`, etc. Thereby separating the
implementation of the test from any specific physical setup.
Testcases are not required to use a logical topology; they may choose
to accept whatever physical topology its given, and dynamically
determine the DUTs to use for testing. As an example, an STP test
could accept an arbitrary physical topology, run the STP algorithm on
it offline, enable STP on all DUTs, and then verify that the resulting
spanning tree matches the expected one.
Quick Start Guide
-----------------
When developing a test, instead of blindly coding in Python and running
`make test` over and over, start a test shell:
When developing and debugging tests, the overhead of repeatedly
setting up and tearing down the test environment can quickly start to
weigh you down. In these situation, you can start an interactive test
environment:
$ make test-sh
Info: Generating topology
@@ -299,13 +69,28 @@ When developing a test, instead of blindly coding in Python and running
Info: Launching dut4
11:42:52 infamy0:test #
The example above uses the default mode (`qeneth`), but the `host` and
`run` modes also support the `test-sh` target.
It takes a little while to start up, but then we have a shell prompt
inside the container running Infamy. It's a very limited environment,
but it has enough to easily run single tests, connect to the virtual
devices, and *step* your code. Let's run a test:
devices, and *step* your code.
### Running Subsets of Tests
Each test case is a separate executable, which can be run without
arguments:
11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
To run a suite of tests, e.g., only the DHCP client tests, pass the
suite as an argument to [9PM][]:
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/all.yaml
### Connecting to Infamy
The test system runs in a Docker container, so to get a shell prompt in
@@ -313,6 +98,7 @@ The test system runs in a Docker container, so to get a shell prompt in
with a helper script for this:
$ ./test/shell
11:42:53 infamy0:test #
By default it connect to the latest started Infamy instance. If you for
some reason run multiple instances of Infamy the `shell` script takes an
@@ -320,6 +106,8 @@ optional argument "system", which is the hostname of the container you
want to connect to:
$ ./test/shell infamy2
11:42:53 infamy2:test #
### Connecting to a DUT
@@ -369,10 +157,47 @@ You can also connect to the console of a DUT from within a `shell`:
> the BusyBox version so you press 'e' + enter instead of 'q' to quit.
### Debug a Test
### Attaching to MACVLANs
First, add a Python `breakpoint()` to your test and run it from your
`make test-sh` Infamy instance:
To fully isolate the host's interfaces from one another, many tests
will stack a MACVLAN on an interface, which is then placed in a
separate network namespace.
It is often useful to attach to those namespaces, so that you can
interactively inject traffic into the test setup.
First, connect to the Infamy instance in question:
$ ./test/shell
11:43:19 infamy0:test #
Then, attach to the MACVLAN namespace by running the `nsenter` helper
script from the test directory, supplying the base interface name as
the first argument:
11:43:19 infamy0:test # ./nsenter d1b
11:43:20 infamy0(d1b):test #
By default, an interactive shell is started, but you can also supply
another command:
11:43:19 infamy0:test # ./nsenter d1b ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
You can now freely debug the network activity of your test and the
responses from the DUT.
### Using the Python Debugger
The built in `breakpoint()` function in Python is very useful when you
want to run a test case to a certain point at which you might want to
interactively inspect either the test's or the device's state.
Simply insert a call to `breakpoint()` at the point of interest in
your test and run it as normal. Once Python executes the call, it will
drop you into the Python debugger:
11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
# Starting (2024-02-10 11:42:59)
@@ -382,34 +207,55 @@ First, add a Python `breakpoint()` to your test and run it from your
> /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)<module>()
(Pdb)
You are now in the Python debugger, Pdb.
At this point you have full access to the test's state, but it is also
an opportunity to inspect the state of the DUTs (e.g. via their
console or over SSH).
### Debug a Test in a MacVLAN
It is also possible to run a test under Pdb from the get-go, if you
want to setup breakpoints without modifying the source, or simply step
through the code:
Most tests use some sort of network connection to the DUTs. From a test
shell you cannot see or debug that connection by default. So you need
to employ a little trick.
11:42:58 infamy0:test # python -m pdb case/infix_dhcp/dhcp_basic.py
Open another terminal, and start a test shell in your Infamy instance:
$ ./test/shell
11:43:19 infamy0:test #
### Deterministic Topology Mappings
MacVLAN interfaces created by Infamy run in another network namespace,
to enter it we can look for a sleeper process:
By default, mappings from logical to physical topologies are not
stable across test case executions. This can be very frustrating when
debugging a failing test, since logical nodes are suffled around
between phyical nodes. In such cases, supplying a `PYTHONHASHSEED`
variable (set to any 32-bit unsigned integer) when launching the test
environment will make sure that topology mappings are deterministic:
11:43:20 infamy0:test # nsenter -n U -t $(pidof sleep infinity)
$ make PYTHONHASHSEED=0 test-sh
You are now one step further down:
If a seed is not supplied, a random value is chosen. This seed is
logged by the `meta/reproducible.py` test case when running a test
suite:
infamy0:/home/jocke/src/infix/test# ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
$ make test
Info: Generating topology
Info: Generating node YAML
Info: Generating executables
Info: Launching dut1
Info: Launching dut2
Info: Launching dut3
Info: Launching dut4
9PM - Simplicity is the ultimate sophistication
You can now freely debug the network activity of your test and the
responses from the DUT.
Starting test 0002-reproducible.py
2024-05-03 10:40:30 # Starting (2024-05-03 10:40:30)
2024-05-03 10:40:30 # Specify PYTHONHASHSEED=3773822171 to reproduce this test environment
2024-05-03 10:40:30 ok 1 - $PYTHONHASHSEED is set
2024-05-03 10:40:30 # Exiting (2024-05-03 10:40:30)
2024-05-03 10:40:30 1..1
...
This is useful because this value can then be used to rerun a test (or
the whole suite) with identical topology mappings:
$ make PYTHONHASHSEED=3773822171 INFIX_TESTS=case/ietf_system/hostname.py test
[9PM]: https://github.com/rical/9pm
[Qeneth]: https://github.com/wkz/qeneth
[TAP]: https://testanything.org/
+4 -2
View File
@@ -1,10 +1,12 @@
source "$BR2_EXTERNAL_INFIX_PATH/package/confd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/curios-httpd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/execd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/gencert/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/statd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/factory/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/faux/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/finit/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/greenpak-programmer/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/ifupdown-ng/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/iito/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/k8s-logger/Config.in"
@@ -12,13 +14,13 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/keyack/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-infix/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/klish/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/python-statd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/landing/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/libsrx/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/lowdown/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/mcd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/mdns-alias/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/netbrowse/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/python-statd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/greenpak-programmer/Config.in"
+1 -1
View File
@@ -7,7 +7,7 @@ run name:bootstrap log:prio:user.notice norestart <pid/syslogd> \
run name:error :1 log:console norestart if:<run/bootstrap/failure> \
[S] /usr/libexec/confd/error --
service name:confd log <run/bootstrap/success> \
service name:confd log:prio:daemon.err <run/bootstrap/success> \
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
# Bootstrap system with startup-config
+1
View File
@@ -0,0 +1 @@
sha256 518cd23d81f17b912f1c4ccc6acb67ff614ddcc2caf14def5044126d1a60f364 LICENSE
+8
View File
@@ -0,0 +1,8 @@
config BR2_PACKAGE_GENCERT
bool "gencert"
select BR2_PACKAGE_OPENSSL
help
Generate a self-signed certificate for embedded systems confused
about the current time. Start date: 2000-01-01, end: 9999-01-01
https://github.com/kernelkit/infix
+1
View File
@@ -0,0 +1 @@
sha256 fff5e150e496c6bb6035ae388ee13cf2d0df842335e5145a4b902ef6b7892088 LICENSE
+22
View File
@@ -0,0 +1,22 @@
################################################################################
#
# gencert
#
################################################################################
GENCERT_VERSION = 1.0
GENCERT_SITE_METHOD = local
GENCERT_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/gencert
GENCERT_LICENSE = ISC
GENCERT_LICENSE_FILES = LICENSE
GENCERT_REDISTRIBUTE = NO
GENCERT_DEPENDENCIES = host-pkgconf libopenssl
GENCERT_AUTORECONF = YES
define GENCERT_CONF_ENV
CFLAGS="$(INFIX_CFLAGS)"
endef
GENCERT_CONF_OPTS = --prefix= --disable-silent-rules
$(eval $(autotools-package))
+6
View File
@@ -0,0 +1,6 @@
config BR2_PACKAGE_LANDING
bool "Landing page (temporary)"
help
Temporary landing page before upcoming webui.
https://github.com/kernelkit/infix
+1
View File
@@ -0,0 +1 @@
sha256 fff5e150e496c6bb6035ae388ee13cf2d0df842335e5145a4b902ef6b7892088 LICENSE
+18
View File
@@ -0,0 +1,18 @@
################################################################################
#
# landing
#
################################################################################
LANDING_VERSION = 1.0
LANDING_SITE_METHOD = local
LANDING_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/landing
LANDING_LICENSE = ISC
LANDING_LICENSE_FILES = LICENSE
define LANDING_INSTALL_TARGET_CMDS
cp $(@D)/*.html $(TARGET_DIR)/usr/html/
cp $(@D)/*.png $(TARGET_DIR)/usr/html/
endef
$(eval $(generic-package))
+2 -2
View File
@@ -1,2 +1,2 @@
sha256 818c003ff153d914a829cd169a7cddb06643f423ebbf8b9e3932aad34c5ed60d mcd-2.1.tar.gz
sha256 99a0480db163445c5a1a5bf7f85bc37cbb5be8c40e9e441291ad78e8d4252d0b LICENSE
sha256 dcd639c77689c432e84e63267202c00958fb1032e066ae355e3cbc68d9fcd063 mcd-2.3.tar.gz
sha256 99a0480db163445c5a1a5bf7f85bc37cbb5be8c40e9e441291ad78e8d4252d0b LICENSE
+2 -1
View File
@@ -4,10 +4,11 @@
#
################################################################################
MCD_VERSION = 2.1
MCD_VERSION = 2.3
MCD_SITE = https://github.com/kernelkit/mcd/releases/download/v$(MCD_VERSION)
MCD_LICENSE = BSD-3-Clause
MCD_LICENSE_FILES = LICENSE
MCD_CONF_OPTS = --disable-silent-rules --with-group=wheel
define MCD_INSTALL_CONFIG
$(INSTALL) -D -m 0644 $(@D)/mcd.conf $(TARGET_DIR)/etc/mcd.conf
+1 -1
View File
@@ -1 +1 @@
sha256 755d3a387cd124ff34e2b73cc58e7cec4d8d85ae6c295e30ffeb8d36eacecb1d LICENSE
sha256 360336cbf0f228b12b7ca0996b33e442d97f496edcf2ec31b655e63631e7f96f LICENSE
+2 -2
View File
@@ -1,8 +1,8 @@
PYTHON_STATD_VERSION = 1.0
PYTHON_STATD_SITE_METHOD = local
PYTHON_STATD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/statd/python
STATD_LICENSE = BSD-3-Clause
STATD_LICENSE_FILES = LICENSE
PYTHON_STATD_LICENSE = BSD-3-Clause
PYTHON_STATD_LICENSE_FILES = LICENSE
PYTHON_STATD_DEPENDENCIES = host-python3 python3 host-python-poetry-core
PYTHON_STATD_SETUP_TYPE = pep517 # poetry
@@ -0,0 +1 @@
task [2] run-parts /cfg/user-scripts.d -- Running user startup scripts
@@ -0,0 +1,25 @@
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
kmem:x:9:
wheel:x:10:root
cdrom:x:11:
dialout:x:18:
floppy:x:19:
video:x:28:
audio:x:29:
tape:x:32:
www-data:x:33:
backup:x:34:
utmp:x:43:
plugdev:x:46:
lock:x:54:
netdev:x:82:
users:x:100:
nobody:x:65534:
@@ -0,0 +1,9 @@
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
backup:x:34:34:backup:/var/backups:/bin/false
nobody:x:65534:65534:nobody:/home:/bin/false
@@ -0,0 +1,9 @@
root::::::::
daemon:*:::::::
bin:*:::::::
sys:*:::::::
sync:*:::::::
mail:*:::::::
www-data:*:::::::
backup:*:::::::
nobody:*:::::::
+2
View File
@@ -1 +1,3 @@
#set DEBUG=1
service name:statd log [S12345] <pid/confd> statd -f -p /run/statd.pid -n -- Status daemon
+1 -1
View File
@@ -1 +1 @@
sha256 755d3a387cd124ff34e2b73cc58e7cec4d8d85ae6c295e30ffeb8d36eacecb1d LICENSE
sha256 360336cbf0f228b12b7ca0996b33e442d97f496edcf2ec31b655e63631e7f96f LICENSE
@@ -1,3 +1,20 @@
From 50fafdc63dc3d6152e2494cc693871e9bd04bfe5 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 09:41:46 +0100
Subject: [PATCH 1/2] iplink_bridge: add mcast_flood_always bridge option
Organization: Addiva Elektronik
- Break out boolopt handling to simplify parsing and setting
- Add set/get support for mcast_flood_always
- Add get support for mst_enabled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/uapi/linux/if_bridge.h | 1 +
ip/iplink_bridge.c | 75 +++++++++++++++++++++++++---------
man/man8/ip-link.8.in | 12 ++++++
3 files changed, 68 insertions(+), 20 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index adb75f7d..611ab413 100644
--- a/include/uapi/linux/if_bridge.h
@@ -153,3 +170,6 @@ index 6764a9ad..8f77c5ad 100644
.BI mcast_snooping " MULTICAST_SNOOPING "
- turn multicast snooping on
.RI ( MULTICAST_SNOOPING " > 0) "
--
2.34.1
@@ -0,0 +1,31 @@
From 226a8b532fc074165ba76d71c4488629daed2625 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 20 May 2024 21:35:11 +0200
Subject: [PATCH 2/2] ipaddress: accept symbolic names also for show
Organization: Addiva Elektronik
This is a follow-up to 709063e, which in turn was a follow-up to
bdb8d85, to add support for 'ip addr show proto static', where
'static' is defined in /etc/iproute2/rt_addrprotos.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ip/ipaddress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e536912f..19900157 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2217,7 +2217,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
__u8 proto;
NEXT_ARG();
- if (get_u8(&proto, *argv, 0))
+ if (rtnl_addrprot_a2n(&proto, *argv))
invarg("\"proto\" value is invalid\n", *argv);
filter.have_proto = true;
filter.proto = proto;
--
2.34.1
@@ -1,7 +1,7 @@
From 79abf7872e35080ca5b519bb4ad2acc1fbd96e8c Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 25 Jan 2024 21:36:59 +0100
Subject: [PATCH 01/27] net: phy: add support for PHY LEDs polarity modes
Subject: [PATCH 01/30] net: phy: add support for PHY LEDs polarity modes
Organization: Addiva Elektronik
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
@@ -1,7 +1,7 @@
From 424ddb5d5d8ce06c578cc08cbedf519c42dd8b69 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 4 Dec 2023 11:08:11 +0100
Subject: [PATCH 02/27] net: mvmdio: Support setting the MDC frequency on XSMI
Subject: [PATCH 02/30] net: mvmdio: Support setting the MDC frequency on XSMI
controllers
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 337cf21833cef6ab456a8562338de88ab1a84ead Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:23 +0100
Subject: [PATCH 03/27] net: dsa: mv88e6xxx: Create API to read a single stat
Subject: [PATCH 03/30] net: dsa: mv88e6xxx: Create API to read a single stat
counter
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From dbdbfd57998b4f8224146ac94cd5d0a577326087 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:25 +0100
Subject: [PATCH 04/27] net: dsa: mv88e6xxx: Give each hw stat an ID
Subject: [PATCH 04/30] net: dsa: mv88e6xxx: Give each hw stat an ID
Organization: Addiva Elektronik
With the upcoming standard counter group support, we are no longer
@@ -1,7 +1,7 @@
From 26815572016d9851ec6362f23746035fb933acf3 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:26 +0100
Subject: [PATCH 05/27] net: dsa: mv88e6xxx: Add "eth-mac" counter group
Subject: [PATCH 05/30] net: dsa: mv88e6xxx: Add "eth-mac" counter group
support
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From cc5badac76e76692eb516a5c086fcf54a5a93080 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:27 +0100
Subject: [PATCH 06/27] net: dsa: mv88e6xxx: Limit histogram counters to
Subject: [PATCH 06/30] net: dsa: mv88e6xxx: Limit histogram counters to
ingress traffic
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 35ecc84237bfccbe5b93c0aef6c07cc506d43070 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:28 +0100
Subject: [PATCH 07/27] net: dsa: mv88e6xxx: Add "rmon" counter group support
Subject: [PATCH 07/30] net: dsa: mv88e6xxx: Add "rmon" counter group support
Organization: Addiva Elektronik
Report the applicable subset of an mv88e6xxx port's counters using
@@ -1,7 +1,7 @@
From 7750d0a5bfae46ab783e8e7087b70175860f808c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 19:44:32 +0100
Subject: [PATCH 09/27] net: dsa: mv88e6xxx: Add LED infrastructure
Subject: [PATCH 09/30] net: dsa: mv88e6xxx: Add LED infrastructure
Organization: Addiva Elektronik
Parse DT for LEDs and register them for devices that support it,
@@ -1,7 +1,7 @@
From 63fcd626fdb108d2ac07cb0aa16b91fc43894bff Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 21:59:35 +0100
Subject: [PATCH 10/27] net: dsa: mv88e6xxx: Add LED support for 6393X
Subject: [PATCH 10/30] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Addiva Elektronik
Trigger support:
@@ -1,7 +1,7 @@
From 0bc6f19d18d7c0e374c824bcc86433b04210a378 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Mar 2024 10:27:24 +0100
Subject: [PATCH 11/27] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
Subject: [PATCH 11/30] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
6393X
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From fe60e3ad1e3b43a924c311658b15a1106e813661 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 16 Jan 2024 16:00:55 +0100
Subject: [PATCH 12/27] net: dsa: Support MDB memberships whose L2 addresses
Subject: [PATCH 12/30] net: dsa: Support MDB memberships whose L2 addresses
overlap
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 5f5bf4a50e98c5aff05fe85994a981253ae85987 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 13/27] net: phy: marvell10g: Support firmware loading on
Subject: [PATCH 13/30] net: phy: marvell10g: Support firmware loading on
88X3310
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 27d5241d3ddf70d65af5f4dd029f99f0fea866a5 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 21 Nov 2023 20:15:24 +0100
Subject: [PATCH 14/27] net: phy: marvell10g: Fix power-up when strapped to
Subject: [PATCH 14/30] net: phy: marvell10g: Fix power-up when strapped to
start powered down
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From e389ee690ce56ef20863aeabdf389bed842d7f42 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 Nov 2023 20:58:42 +0100
Subject: [PATCH 15/27] net: phy: marvell10g: Add LED support for 88X3310
Subject: [PATCH 15/30] net: phy: marvell10g: Add LED support for 88X3310
Organization: Addiva Elektronik
Pickup the LEDs from the state in which the hardware reset or
@@ -1,7 +1,7 @@
From 3113b64290b5b7b20c294535c12ea4c732a02f51 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Dec 2023 09:51:05 +0100
Subject: [PATCH 16/27] net: phy: marvell10g: Support LEDs tied to a single
Subject: [PATCH 16/30] net: phy: marvell10g: Support LEDs tied to a single
media side
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2570c2350d3d614a31e14dd87d0e99e8fcb5096b Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 24 Nov 2023 23:29:55 +0100
Subject: [PATCH 17/27] nvmem: layouts: onie-tlv: Let device probe even when
Subject: [PATCH 17/30] nvmem: layouts: onie-tlv: Let device probe even when
TLV is invalid
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 681ce95c15bff94ac83eb26db3c718594f8dfa16 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 4 Mar 2024 16:47:28 +0100
Subject: [PATCH 18/27] net: bridge: avoid classifying unknown multicast as
Subject: [PATCH 18/30] net: bridge: avoid classifying unknown multicast as
mrouters_only
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2482848726a5b8185a04d90891693a1713f894b5 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 06:44:41 +0100
Subject: [PATCH 19/27] net: bridge: Ignore router ports when forwarding L2
Subject: [PATCH 19/30] net: bridge: Ignore router ports when forwarding L2
multicast
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 25efcdb13ae720ee662f4b6091b270e48ac4d375 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Mar 2024 19:12:15 +0100
Subject: [PATCH 20/27] net: dsa: Support EtherType based priority overrides
Subject: [PATCH 20/30] net: dsa: Support EtherType based priority overrides
Organization: Addiva Elektronik
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
@@ -1,7 +1,7 @@
From 213e9a1d9145723897fbba40fc4afc5b5f70c1de Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 22 Mar 2024 16:15:43 +0100
Subject: [PATCH 21/27] net: dsa: mv88e6xxx: Support EtherType based priority
Subject: [PATCH 21/30] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 1c1c81864c9803831c2d5b7df0d7da28e566f3b2 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 10:10:19 +0100
Subject: [PATCH 22/27] net: phy: Do not resume PHY when attaching
Subject: [PATCH 22/30] net: phy: Do not resume PHY when attaching
Organization: Addiva Elektronik
The PHY should not start negotiating with its link-partner until
@@ -1,7 +1,7 @@
From b53e5007cd5be42eb5d9a510d63f89c7c6edd9b6 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 15:52:43 +0100
Subject: [PATCH 23/27] net: dsa: mv88e6xxx: Improve indirect register access
Subject: [PATCH 23/30] net: dsa: mv88e6xxx: Improve indirect register access
perf on 6393
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From f53652205b1c044fa00f896d6422c82ac808f16a Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 4 Apr 2024 16:36:30 +0200
Subject: [PATCH 24/27] net: bridge: drop delay for applying strict multicast
Subject: [PATCH 24/30] net: bridge: drop delay for applying strict multicast
filtering
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 56208d4cba23496c09f69961a32b1b9662f06aef Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 22 Apr 2024 23:18:01 +0200
Subject: [PATCH 25/27] net: dsa: mv88e6xxx: Honor ports being managed via
Subject: [PATCH 25/30] net: dsa: mv88e6xxx: Honor ports being managed via
in-band-status
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 04023a449a6894c0ec46e246c52e94566b3be4b3 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 21:35:26 +0200
Subject: [PATCH 26/27] net: dsa: mv88e6xxx: Fix port policy config on 6393X
Subject: [PATCH 26/30] net: dsa: mv88e6xxx: Fix port policy config on 6393X
Organization: Addiva Elektronik
mv88e6393x_port_policy_{read,write} expect the `pointer` argument to
@@ -1,7 +1,7 @@
From 7529102af1693138349032b7d1339d91d2b6a578 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 22:41:04 +0200
Subject: [PATCH 27/27] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
Subject: [PATCH 27/30] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
ports on 6393X
Organization: Addiva Elektronik
@@ -0,0 +1,50 @@
From c446111df33d9d6064395e37235bbbeee422358e Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 29 Apr 2024 15:14:51 +0200
Subject: [PATCH 28/30] usb: core: adjust log level for unauthorized devices
Organization: Addiva Elektronik
The fact that a USB device currently is not authorized is not an error,
so let's adjust the log level so these messages slip below radar for the
commonly used 'quiet' log level.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/usb/core/driver.c | 4 ++--
drivers/usb/core/generic.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f58a0299fb3b..46450d806373 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -332,10 +332,10 @@ static int usb_probe_interface(struct device *dev)
return error;
if (udev->authorized == 0) {
- dev_err(&intf->dev, "Device is not authorized for usage\n");
+ dev_warn(&intf->dev, "Device is not authorized for usage\n");
return error;
} else if (intf->authorized == 0) {
- dev_err(&intf->dev, "Interface %d is not authorized for usage\n",
+ dev_warn(&intf->dev, "Interface %d is not authorized for usage\n",
intf->altsetting->desc.bInterfaceNumber);
return error;
}
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 740342a2812a..2682bcf3e79f 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -231,7 +231,7 @@ int usb_generic_driver_probe(struct usb_device *udev)
* with the driver core and lets interface drivers bind to them.
*/
if (udev->authorized == 0)
- dev_err(&udev->dev, "Device is not authorized for usage\n");
+ dev_warn(&udev->dev, "Device is not authorized for usage\n");
else {
c = usb_choose_configuration(udev);
if (c >= 0) {
--
2.34.1
@@ -0,0 +1,52 @@
From eeeab4de57f77712ca5f920e03a68aa5e426784c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 May 2024 13:50:58 +0200
Subject: [PATCH 29/30] net: dsa: mv88e6xxx: Grab register lock during counter
snapshotting
Organization: Addiva Elektronik
This was missing for the standard counter groups. Since no caller
already holds the lock, opt for pushing the locking down into
mv88e6xxx_stats_snapshot() rather than having it duplicated at each
call site.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 29691280cff4..4916d8344a5a 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -950,10 +950,15 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
{
+ int err;
+
if (!chip->info->ops->stats_snapshot)
return -EOPNOTSUPP;
- return chip->info->ops->stats_snapshot(chip, port);
+ mv88e6xxx_reg_lock(chip);
+ err = chip->info->ops->stats_snapshot(chip, port);
+ mv88e6xxx_reg_unlock(chip);
+ return err;
}
#define MV88E6XXX_HW_STAT_MAPPER(_fn) \
@@ -1325,10 +1330,7 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
struct mv88e6xxx_chip *chip = ds->priv;
int ret;
- mv88e6xxx_reg_lock(chip);
-
ret = mv88e6xxx_stats_snapshot(chip, port);
- mv88e6xxx_reg_unlock(chip);
if (ret < 0)
return;
--
2.34.1
@@ -0,0 +1,109 @@
From 52eabcd2cfb30013d43ef72c2ec09c76043a0f4a Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 May 2024 14:51:54 +0200
Subject: [PATCH 30/30] net: bridge: Differentiate MDB additions from
modifications
Organization: Addiva Elektronik
Before this change, the reception of an IGMPv3 report (and analogously
for MLDv2) that adds a new group, would trigger two MDB RTM_NEWMDB
notifications from br_ip4_multicast_igmp3_report():
1. In br_ip4_multicast_add_group() when creating the entry
2. Directly at the end of br_ip4_multicast_igmp3_report(), as the new
group is also deemed to be "changed"
The corresponding switchdev notifications generated by these present a
problem for drivers wanting to reference count group memberships,
since logically there is only a single reference to the group. Indeed,
when the membership eventually times out, only a single RTM_DELMDB is
generated.
Therefore, discriminate new groups from changes to existing groups by
introducing a RTM_SETMDB events to be used in the latter scenario.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
include/uapi/linux/rtnetlink.h | 2 ++
net/bridge/br_mdb.c | 4 ++--
net/bridge/br_multicast.c | 8 ++++----
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 51c13cf9c5ae..fbc8fd1d5f2c 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -134,6 +134,8 @@ enum {
#define RTM_DELMDB RTM_DELMDB
RTM_GETMDB = 86,
#define RTM_GETMDB RTM_GETMDB
+ RTM_SETMDB = 87,
+#define RTM_SETMDB RTM_SETMDB
RTM_NEWNSID = 88,
#define RTM_NEWNSID RTM_NEWNSID
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 7305f5f8215c..a2882b126ecb 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -724,7 +724,7 @@ static int br_mdb_replace_group_sg(const struct br_mdb_config *cfg,
else
del_timer(&pg->timer);
- br_mdb_notify(cfg->br->dev, mp, pg, RTM_NEWMDB);
+ br_mdb_notify(cfg->br->dev, mp, pg, RTM_SETMDB);
return 0;
}
@@ -945,7 +945,7 @@ static int br_mdb_replace_group_star_g(const struct br_mdb_config *cfg,
else
del_timer(&pg->timer);
- br_mdb_notify(cfg->br->dev, mp, pg, RTM_NEWMDB);
+ br_mdb_notify(cfg->br->dev, mp, pg, RTM_SETMDB);
if (br_multicast_should_handle_mode(brmctx, cfg->group.proto))
br_multicast_star_g_handle_mode(pg, cfg->filter_mode);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 8fcd8faf99f3..7ba1eee1a024 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -618,7 +618,7 @@ static void br_multicast_fwd_src_handle(struct net_bridge_group_src *src)
sg_mp = br_mdb_ip_get(src->br, &sg_key.addr);
if (!sg_mp)
return;
- br_mdb_notify(src->br->dev, sg_mp, sg, RTM_NEWMDB);
+ br_mdb_notify(src->br->dev, sg_mp, sg, RTM_SETMDB);
}
}
@@ -885,7 +885,7 @@ static void br_multicast_port_group_expired(struct timer_list *t)
if (WARN_ON(!mp))
goto out;
- br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB);
+ br_mdb_notify(br->dev, mp, pg, RTM_SETMDB);
}
out:
spin_unlock(&br->multicast_lock);
@@ -2888,7 +2888,7 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge_mcast *brmctx,
break;
}
if (changed)
- br_mdb_notify(brmctx->br->dev, mdst, pg, RTM_NEWMDB);
+ br_mdb_notify(brmctx->br->dev, mdst, pg, RTM_SETMDB);
unlock_continue:
spin_unlock(&brmctx->br->multicast_lock);
}
@@ -3030,7 +3030,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge_mcast *brmctx,
break;
}
if (changed)
- br_mdb_notify(brmctx->br->dev, mdst, pg, RTM_NEWMDB);
+ br_mdb_notify(brmctx->br->dev, mdst, pg, RTM_SETMDB);
unlock_continue:
spin_unlock(&brmctx->br->multicast_lock);
}
--
2.34.1
@@ -1,7 +1,7 @@
From 49c660c412342e1af76735e75cd3f286ae655b82 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 28 Mar 2023 10:37:53 +0200
Subject: [PATCH 1/4] sysrepo-plugind: add support for running in foreground
Subject: [PATCH 1/5] sysrepo-plugind: add support for running in foreground
with syslog
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 87224ddce4ed1a118b3efb24e0dc7167f8754c22 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 7 Jun 2023 15:19:13 +0200
Subject: [PATCH 2/4] Refactor _sr_install_modules() to use
Subject: [PATCH 2/5] Refactor _sr_install_modules() to use
ly_ctx_load_module()
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2d3b9524b1448dd6a8ef83e4e101e509d2552dcc Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 16 Jun 2023 12:13:16 +0200
Subject: [PATCH 3/4] Add support for loading /etc/sysrepo/factory-default
Subject: [PATCH 3/5] Add support for loading /etc/sysrepo/factory-default
Organization: Addiva Elektronik
Follow-up to 3d07270 which adds support for compile-time defaults, this
@@ -1,7 +1,7 @@
From 7726017815243818f07936e4ff3bb979e9291f04 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 16 Jun 2023 16:17:27 +0200
Subject: [PATCH 4/4] sysrepoctl: add support for -Cfactory -d running
Subject: [PATCH 4/5] sysrepoctl: add support for -Cfactory -d running
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
@@ -0,0 +1,152 @@
From 49b558067ab7c6f59ec84f14cc89201b4a7bde57 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 7 May 2024 15:41:53 +0200
Subject: [PATCH 5/5] Allow SR_EV_DONE to return any error to sysrepocfg
Organization: Addiva Elektronik
Importing a system configuration with sysrepocfg the model callbacks do
their best to validate the configuration and prepare the transaction in
SR_EV_CHANGE. In cases when dealing with a complex system, like adding
a route, address, or other change using iproute2, we may still get into
trouble when actually sending off the transaction in SR_EV_DONE.
If something does go wrong we'd like to know this by the exit code of
sysrepocfg, not by inspecting logs or expected system state.
This patch is a clumsy way of forcing the (first) error to bubble up to
the surface and cause a non-zero exit code from sysrepocfg.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/shm_sub.c | 36 ++++++++++++++++++++++++++++--------
src/shm_sub.h | 2 +-
src/sysrepo.c | 2 +-
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/shm_sub.c b/src/shm_sub.c
index 99b2be37..298d7dd3 100644
--- a/src/shm_sub.c
+++ b/src/shm_sub.c
@@ -1586,7 +1586,7 @@ cleanup:
sr_error_info_t *
sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *orig_name, const void *orig_data,
- uint32_t timeout_ms)
+ uint32_t timeout_ms, sr_error_info_t **cb_err_info)
{
sr_error_info_t *err_info = NULL;
struct sr_mod_info_mod_s *mod = NULL;
@@ -1717,12 +1717,19 @@ sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *
sr_rwunlock(&nsub->sub_shm->lock, 0, SR_LOCK_WRITE, cid, __func__);
nsub->lock = SR_LOCK_NONE;
- /* we do not care about an error */
- sr_errinfo_free(&nsub->cb_err_info);
-
SR_LOG_INF("EV ORIGIN: \"%s\" \"%s\" ID %" PRIu32 " priority %" PRIu32 " succeeded.",
nsub->mod->ly_mod->name, sr_ev2str(SR_SUB_EV_DONE), nsub->mod->request_id, nsub->cur_priority);
+ /*
+ * unexpected critical error, merge and cleanup, let
+ * sysrepocfg caller handle undefined system state.
+ */
+ if (nsub->cb_err_info) {
+ sr_errinfo_merge(cb_err_info, nsub->cb_err_info);
+ nsub->cb_err_info = NULL;
+ goto cleanup;
+ }
+
nsub->pending_event = 0;
}
} while (1);
@@ -3167,7 +3174,7 @@ sr_shmsub_change_listen_check_update_edit(sr_session_ctx_t *ev_sess, const char
sr_error_info_t *
sr_shmsub_change_listen_process_module_events(struct modsub_change_s *change_subs, sr_conn_ctx_t *conn)
{
- sr_error_info_t *err_info = NULL;
+ sr_error_info_t *err_info = NULL, *err_tmp;
uint32_t i, data_len = 0, valid_subscr_count;
char *data = NULL, *shm_data_ptr;
int ret = SR_ERR_OK;
@@ -3289,6 +3296,11 @@ process_event:
}
break;
}
+ } else if (sub_info.event == SR_SUB_EV_DONE) {
+ if (ret && err_code == SR_ERR_OK) {
+ /* unexpected, callback actually failed, save for later. */
+ err_code = ret;
+ }
}
/* subscription processed this event */
@@ -3330,6 +3342,11 @@ process_event:
}
break;
case SR_SUB_EV_DONE:
+ if (err_code) {
+ /* prepare unexepected error from session to be written to SHM */
+ sr_errinfo_new(&err_info, err_code, "Oups, error detected in SR_EV_DONE");
+ }
+ break;
case SR_SUB_EV_ABORT:
/* nothing to do */
break;
@@ -3349,14 +3366,17 @@ process_event:
/* SUB WRITE URGE LOCK */
if (sr_shmsub_change_listen_relock(multi_sub_shm, SR_LOCK_WRITE_URGE, &sub_info, change_sub, change_subs->module_name,
- ret, ev_sess, &err_info)) {
+ ret, ev_sess, &err_tmp)) {
+ if (err_tmp)
+ err_info = err_tmp;
goto cleanup;
}
sub_lock = SR_LOCK_WRITE_URGE;
/* finish event */
- if ((err_info = sr_shmsub_multi_listen_write_event(multi_sub_shm, valid_subscr_count, err_code, &shm_data_sub, data,
+ if ((err_tmp = sr_shmsub_multi_listen_write_event(multi_sub_shm, valid_subscr_count, err_code, &shm_data_sub, data,
data_len, change_subs->module_name, err_code ? "fail" : "success"))) {
+ err_info = err_tmp;
goto cleanup;
}
@@ -3886,7 +3906,7 @@ finish_iter:
sr_errinfo_free(&cb_err_info);
/* publish "done" event */
- if ((err_info = sr_shmsub_change_notify_change_done(&mod_info, NULL, NULL, SR_CHANGE_CB_TIMEOUT))) {
+ if ((err_info = sr_shmsub_change_notify_change_done(&mod_info, NULL, NULL, SR_CHANGE_CB_TIMEOUT, &cb_err_info))) {
goto cleanup_unlock;
}
diff --git a/src/shm_sub.h b/src/shm_sub.h
index 3056e4c5..460ad927 100644
--- a/src/shm_sub.h
+++ b/src/shm_sub.h
@@ -144,7 +144,7 @@ sr_error_info_t *sr_shmsub_change_notify_change(struct sr_mod_info_s *mod_info,
* @return err_info, NULL on success.
*/
sr_error_info_t *sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *orig_name,
- const void *orig_data, uint32_t timeout_ms);
+ const void *orig_data, uint32_t timeout_ms, sr_error_info_t **cb_err_info);
/**
* @brief Notify about (generate) a change "abort" event.
diff --git a/src/sysrepo.c b/src/sysrepo.c
index ca2a20b7..e7c1fd0e 100644
--- a/src/sysrepo.c
+++ b/src/sysrepo.c
@@ -3801,7 +3801,7 @@ store:
}
/* publish "done" event, all changes were applied */
- if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms))) {
+ if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, cb_err_info))) {
goto cleanup;
}
--
2.34.1
+3 -2
View File
@@ -1,2 +1,3 @@
pkglibexec_SCRIPTS = bootstrap error load gen-service \
gen-hostkeys gen-admin-auth gen-hostname gen-interfaces gen-motd gen-hardware
pkglibexec_SCRIPTS = bootstrap error load gen-service gen-hostkeys gen-admin-auth \
gen-hostname gen-interfaces gen-motd gen-hardware
sbin_SCRIPTS = dagger
+7 -6
View File
@@ -72,7 +72,7 @@ collate()
# Report error on console, syslog, and set login banners for getty + ssh
console_error()
{
logger -p user.crit -t "BOOTSTRAP" "$1"
logger -p user.crit -t bootstrap "$1"
# shellcheck disable=SC3037
/bin/echo -e "\n\n\e[31mCRITICAL BOOTSTRAP ERROR\n$1\e[0m\n" > /dev/console
@@ -214,7 +214,7 @@ sysrepoctl -s $SEARCH \
-i iana-hardware@2018-03-13.yang -g wheel -p 0660 \
-i ietf-hardware@2018-03-13.yang -g wheel -p 0660 \
-e hardware-state \
-i infix-hardware@2024-01-18.yang -g wheel -p 0660 \
-i infix-hardware@2024-04-25.yang -g wheel -p 0660 \
-i ieee802-dot1q-types@2022-10-29.yang -g wheel -p 0660 \
-i infix-ip@2023-09-14.yang -g wheel -p 0660 \
-i infix-if-type@2024-01-29.yang -g wheel -p 0660 \
@@ -226,7 +226,7 @@ sysrepoctl -s $SEARCH \
-i infix-dhcp-client@2024-04-12.yang -g wheel -p 0660 \
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-system@2024-04-12.yang -g wheel -p 0660 \
-i infix-services@2024-04-08.yang -g wheel -p 0660 \
-i infix-services@2024-05-21.yang -g wheel -p 0660 \
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
-i infix-ethernet-interface@2024-02-27.yang -g wheel -p 0660 \
-I "${INIT_DATA}"
@@ -245,8 +245,10 @@ sysrepoctl -c ietf-netconf -g wheel -p 0660 \
-e url \
-e xpath \
-e confirmed-commit
# Allow wheel group users (admin) to modify NACM
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660
# Allow wheel group users (admin) to modify NACM and do factory reset
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660
sysrepoctl -c ietf-factory-default -g wheel -p 0660
sysrepoctl -c sysrepo-plugind -g wheel -p 0660
# On first boot, install factory-config as startup-config. Due to a
# limitation in sysrepo we cannot initialize ietf-netconf-acm, so we
@@ -255,7 +257,6 @@ chgrp wheel /cfg
chmod g+w /cfg
if [ ! -f "$STARTUP_CFG" ]; then
sysrepocfg -f json -X"$STARTUP_CFG"
chown admin:wheel "$STARTUP_CFG"
fi
# Clear running-config so we can load startup in the next step

Some files were not shown because too many files have changed in this diff Show More