Compare commits

...
Author SHA1 Message Date
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
134 changed files with 2943 additions and 619 deletions
+13 -7
View File
@@ -9,24 +9,23 @@ on:
jobs:
build:
name: Build Infix ${{ matrix.platform }}
runs-on: self-hosted
runs-on: [ self-hosted, latest ]
strategy:
matrix:
platform: [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:
submodules: 'true'
- name: Set Build Variables
id: vars
run: |
target=${{ matrix.platform }}
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,6 +33,7 @@ jobs:
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
@@ -42,18 +42,21 @@ jobs:
restore-keys: |
ccache-${{ matrix.platform }}-
ccache-
- name: Configure & Build
run: |
target=${{ matrix.platform }}_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'
run: |
@@ -62,11 +65,12 @@ jobs:
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ matrix.platform }}
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 +78,7 @@ jobs:
with:
pattern: "artifact-*"
merge-multiple: true
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -84,6 +89,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:
+13 -5
View File
@@ -16,21 +16,24 @@ concurrency:
jobs:
build:
name: Regression Testing
runs-on: self-hosted
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
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
- name: Clean up cruft ...
run: |
./test/env -c
- name: Set Build Variables
id: vars
run: |
target=x86_64
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
@@ -39,6 +42,7 @@ jobs:
restore-keys: |
dl-netconf-
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
@@ -47,19 +51,22 @@ jobs:
restore-keys: |
ccache-x86_64-
ccache-
- name: Configure NETCONF
run: |
make x86_64_defconfig
- 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 }}
@@ -69,7 +76,8 @@ jobs:
path: output/${{ steps.vars.outputs.tgz }}
- name: Regression Test
run: make test-qeneth
run: |
make test
- name: Publish Test Result
# Ensure this runs even if Regression Test fails
+22 -13
View File
@@ -21,18 +21,16 @@ jobs:
build:
if: github.repository == 'kernelkit/infix' && startsWith(github.ref, 'refs/tags/')
name: Build Infix ${{ github.ref_name }} [${{ matrix.platform }}]
runs-on: self-hosted
runs-on: [ self-hosted, release ]
strategy:
matrix:
platform: [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:
submodules: 'true'
- name: Set Release Variables
id: vars
run: |
@@ -46,7 +44,7 @@ jobs:
target=${{ matrix.platform }}-${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,6 +52,7 @@ jobs:
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
dl-
- name: Restore Cache of .ccache/
uses: actions/cache@v4
with:
@@ -62,41 +61,46 @@ jobs:
restore-keys: |
ccache-${{ matrix.platform }}-
ccache-
- name: Configure & Build
env:
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
run: |
target=${{ matrix.platform }}_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
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 +122,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 +147,7 @@ jobs:
makeLatest: ${{ steps.rel.outputs.latest }}
bodyFile: release.md
artifacts: "*.tar.gz*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
+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
+11 -5
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
-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
@@ -0,0 +1 @@
configure ports dsa0 lldp status disabled
@@ -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
+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
+2 -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
@@ -130,6 +129,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 +142,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 +156,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
+5 -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
@@ -159,6 +158,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 +171,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
+2 -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
@@ -133,6 +132,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 +145,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 +157,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
+132 -22
View File
@@ -4,23 +4,75 @@ Change Log
All notable changes to the project are documented in this file.
[v24.03.0][UNRELEASED]
[v24.04.2][] - 2024-05-15
-------------------------
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.
### 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
> Development in progress, for daily updates see the team board:
> <https://github.com/orgs/kernelkit/projects/3/views/2>
### 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
- 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
### 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 +80,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 +134,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 +148,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 +167,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 +880,10 @@ 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.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
+2 -1
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:
+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.
+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
+39
View File
@@ -410,6 +410,45 @@ You can now freely debug the network activity of your test and the
responses from the DUT.
### Deterministic Topology Mappings
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:
$ make PYTHONHASHSEED=0 test-sh
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:
$ 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
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 = openssl
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,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,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/28] 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
@@ -22,7 +22,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/phy_device.c | 16 ++++++++++++++++
include/linux/phy.h | 22 ++++++++++++++++++++++
@@ -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/28] net: mvmdio: Support setting the MDC frequency on XSMI
controllers
Organization: Addiva Elektronik
@@ -14,6 +14,7 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20231204100811.2708884-4-tobias@waldekranz.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/ethernet/marvell/mvmdio.c | 44 +++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
@@ -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/28] net: dsa: mv88e6xxx: Create API to read a single stat
counter
Organization: Addiva Elektronik
@@ -16,6 +16,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 162 ++++++++++++++++++-------------
drivers/net/dsa/mv88e6xxx/chip.h | 27 +++---
@@ -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/28] net: dsa: mv88e6xxx: Give each hw stat an ID
Organization: Addiva Elektronik
With the upcoming standard counter group support, we are no longer
@@ -16,6 +16,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 138 +++++++++++++++++--------------
1 file changed, 75 insertions(+), 63 deletions(-)
@@ -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/28] net: dsa: mv88e6xxx: Add "eth-mac" counter group
support
Organization: Addiva Elektronik
@@ -12,6 +12,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 39 ++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
@@ -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/28] net: dsa: mv88e6xxx: Limit histogram counters to
ingress traffic
Organization: Addiva Elektronik
@@ -27,6 +27,7 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 6 +++---
drivers/net/dsa/mv88e6xxx/global1.c | 7 +++----
@@ -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/28] net: dsa: mv88e6xxx: Add "rmon" counter group support
Organization: Addiva Elektronik
Report the applicable subset of an mv88e6xxx port's counters using
@@ -11,6 +11,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 42 ++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
@@ -1,13 +1,13 @@
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/28] net: dsa: mv88e6xxx: Add LED infrastructure
Organization: Addiva Elektronik
Parse DT for LEDs and register them for devices that support it,
though no actual implementations exist yet.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/Makefile | 1 +
drivers/net/dsa/mv88e6xxx/chip.c | 5 +-
@@ -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/28] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Addiva Elektronik
Trigger support:
@@ -9,7 +9,7 @@ Trigger support:
- "timer"
- "netdev"
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
drivers/net/dsa/mv88e6xxx/leds.c | 226 +++++++++++++++++++++++++++++++
@@ -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/28] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
6393X
Organization: Addiva Elektronik
@@ -9,7 +9,7 @@ In a multi-chip setup, delays of up to 750ms are observed before the
device (6393X) signals completion of PPU initialization (Global 1,
register 0, bit 15). Therefore, increase the timeout threshold to 1s.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -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/28] net: dsa: Support MDB memberships whose L2 addresses
overlap
Organization: Addiva Elektronik
@@ -30,7 +30,7 @@ needed to do this is already in place, since it is also needed on CPU
and DSA ports. Thus, "implement" this by simply removing the guards
which previously skipped reference countung on user ports.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
net/dsa/switch.c | 16 ----------------
1 file changed, 16 deletions(-)
@@ -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/28] net: phy: marvell10g: Support firmware loading on
88X3310
Organization: Addiva Elektronik
@@ -12,7 +12,7 @@ We have no choice but to bail out of the probe if firmware is not
available, as the device does not have any built-in image on which to
fall back.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 161 +++++++++++++++++++++++++++++++++++
1 file changed, 161 insertions(+)
@@ -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/28] net: phy: marvell10g: Fix power-up when strapped to
start powered down
Organization: Addiva Elektronik
@@ -9,7 +9,7 @@ On devices which are hardware strapped to start powered down (PDSTATE
== 1), make sure that we clear the power-down bit on all units
affected by this setting.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
@@ -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/28] net: phy: marvell10g: Add LED support for 88X3310
Organization: Addiva Elektronik
Pickup the LEDs from the state in which the hardware reset or
@@ -18,7 +18,7 @@ Trigger support:
- "netdev": Offload link or duplex information to the solid behavior;
tx and/or rx activity to blink behavior.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 422 +++++++++++++++++++++++++++++++++++
1 file changed, 422 insertions(+)
@@ -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/28] net: phy: marvell10g: Support LEDs tied to a single
media side
Organization: Addiva Elektronik
@@ -15,7 +15,7 @@ the offloading of the "netdev" trigger, such that LEDs attached to the
RJ45 jack only lights up when a copper link is established, and vice
versa for the SFP cage.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
@@ -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/28] nvmem: layouts: onie-tlv: Let device probe even when
TLV is invalid
Organization: Addiva Elektronik
@@ -14,7 +14,7 @@ be successfully probed.
Therefore, settle for reporting data corruption issues in the log, and
simply refrain from registering any cells in those cases.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/nvmem/layouts/onie-tlv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
@@ -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/28] net: bridge: avoid classifying unknown multicast as
mrouters_only
Organization: Addiva Elektronik
@@ -16,7 +16,6 @@ Because a multicast router should always receive both known and unknown
multicast.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
include/uapi/linux/if_bridge.h | 1 +
net/bridge/br.c | 5 +++++
@@ -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/28] net: bridge: Ignore router ports when forwarding L2
multicast
Organization: Addiva Elektronik
@@ -1,10 +1,10 @@
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/28] net: dsa: Support EtherType based priority overrides
Organization: Addiva Elektronik
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/net/dsa.h | 4 ++++
net/dsa/slave.c | 56 +++++++++++++++++++++++++++++++++++++++++++++--
@@ -1,11 +1,11 @@
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/28] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Addiva Elektronik
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/chip.h | 21 ++++++++++
@@ -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/28] net: phy: Do not resume PHY when attaching
Organization: Addiva Elektronik
The PHY should not start negotiating with its link-partner until
@@ -16,7 +16,7 @@ probing (e.g. DSA) would end up with a physical link being
established, even though the corresponding interface was still
administratively down.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/phy_device.c | 1 -
1 file changed, 1 deletion(-)
@@ -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/28] net: dsa: mv88e6xxx: Improve indirect register access
perf on 6393
Organization: Addiva Elektronik
@@ -14,7 +14,7 @@ Therefore, add a new set of SMI operations which remaps accesses to
such registers to the corresponding directly addressable register. All
other accesses use the regular indirect interface.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 7 +++
drivers/net/dsa/mv88e6xxx/global1.h | 3 ++
@@ -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/28] net: bridge: drop delay for applying strict multicast
filtering
Organization: Addiva Elektronik
@@ -19,7 +19,6 @@ A proper fix for upstreaming could be to add a knob to disable the delay.
[2]: https://lore.kernel.org/netdev/20240127175033.9640-1-linus.luessing@c0d3.blue/
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
net/bridge/br_multicast.c | 42 +++++++--------------------------------
net/bridge/br_private.h | 4 +---
@@ -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/28] net: dsa: mv88e6xxx: Honor ports being managed via
in-band-status
Organization: Addiva Elektronik
@@ -14,7 +14,7 @@ This state is the default set up by mv88e6xxx_port_setup_mac(), so all
we have to do is to make the phylink MAC callbacks no-ops in cases
when in-band-status is being used.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 6 ++++++
1 file changed, 6 insertions(+)
@@ -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/28] net: dsa: mv88e6xxx: Fix port policy config on 6393X
Organization: Addiva Elektronik
mv88e6393x_port_policy_{read,write} expect the `pointer` argument to
@@ -16,7 +16,7 @@ never enabled on DSA ports, which broke standalone port isolation in
multichip switch trees made up of 6393X decices.
Fixes: 6584b26020fc ("net: dsa: mv88e6xxx: implement .port_set_policy for Amethyst")
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/port.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -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/28] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
ports on 6393X
Organization: Addiva Elektronik
@@ -30,7 +30,7 @@ switch would try to trap it back to the CPU. Given that the CPU is
trusted, instead assume that it indeed meant for the packet to be
forwarded like any other.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/port.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
@@ -0,0 +1,49 @@
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/28] 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>
---
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
@@ -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
+6 -5
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 \
@@ -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
@@ -50,8 +50,8 @@ action_exec()
for node in $order; do
for work in $(find "$actdir/$node" -type f -executable 2>/dev/null | sort); do
$work >>"$work.log" 2>&1 || code=$?
echo "[exit:$code]" >>"$work.log"
$work | ts >>"$work.log" 2>&1 || code=$?
echo "[exit:$code]" | ts >>"$work.log"
[ $code -eq 0 ] || abort "$work failed with exitcode $code"
done
+15 -24
View File
@@ -1,38 +1,29 @@
#!/bin/sh
# Generate ietf-system.yang hostname based on:
# 1. Command line argument + MAC suffix
# 2. Specific hostname from qemu_fw_cfg, from Qeneth
# 3. /etc/hostname from squashfs + MAC suffix
#
set -e
base_mac_lowest_physical()
gen()
{
ip -d -j link show | jq -r '
.[] |
select(.link_type == "ether") |
select(has("linkinfo") | not) | .address' \
| sort | head -n 1
}
base_mac=$(jq -r '.["mac-address"]' /run/system.json)
if [ -z "$base_mac" ] || [ "$base_mac" = "null" ]; then
base_mac=00:00:00:00:00:00
fi
source_base_mac()
{
# TODO: Source the base MAC from the vital product data memory, if
# available.
# base_mac=$(base_mac_vpd)
# [ "$base_mac" ] && return
base_mac=$(base_mac_lowest_physical)
[ "$base_mac" ] && return
base_mac=00:00:00:00:00:00
echo "$1-$(echo $base_mac | tail -c 9 | tr ':' '-')"
}
if [ "$1" ]; then
sysname="$1"
sysname=$(gen "$1")
elif [ -f "/sys/firmware/qemu_fw_cfg/by_name/opt/hostname/raw" ]; then
sysname="$(cat /sys/firmware/qemu_fw_cfg/by_name/opt/hostname/raw)"
else
sysname="$(cat /etc/hostname)"
sysname=$(gen "$(cat /etc/hostname)")
fi
source_base_mac
sysname="${sysname}-$(echo $base_mac | tail -c 9 | tr ':' '-')"
cat <<EOF
{
"ietf-system:system": {
+34 -4
View File
@@ -19,6 +19,16 @@ banner_append()
return 0
}
note()
{
logger -s -I $$ -p user.notice -t load "$*"
}
err()
{
logger -s -I $$ -p user.error -t load "$*"
}
# shellcheck disable=SC1091
. /etc/confdrc
@@ -35,17 +45,31 @@ else
fi
if [ ! -f "$fn" ]; then
logger -sik -p user.error "No such file, $fn, aborting!"
err "No such file, $fn, aborting!"
exit 1
fi
note "Loading $config ..."
if ! sysrepocfg -v3 -I"$fn" -f json; then
case "$config" in
startup-config)
logger -sik -p user.error "Failed loading $fn, reverting to Fail Secure mode!"
err "Failed loading $fn, reverting to Fail Secure mode!"
# On failure to load startup-config the system is in an undefined state
cat <<-EOF >/tmp/factory.json
{
"infix-factory-default:factory-default": {}
}
EOF
# Default timeout is 2 seconds, allow time to clean up shm
if ! sysrepocfg -f json -t 10 -R /tmp/factory.json; then
rm -f /etc/sysrepo/data/*startup*
rm -f /etc/sysrepo/data/*running*
rm -f /dev/shm/sr_*
killall sysrepo-plugind
fi
;;
failure-config)
logger -sik -p user.error "Failed loading $fn, aborting!"
err "Failed loading $fn, aborting!"
banner_append "CRITICAL ERROR: Logins are disabled, no credentials available"
initctl -nbq runlevel 9
;;
@@ -53,7 +77,13 @@ if ! sysrepocfg -v3 -I"$fn" -f json; then
exit 1
fi
logger -sik -p user.notice "Loaded $fn successfully."
note "Loaded $fn successfully."
if [ "$config" = "failure-config" ]; then
banner_append "ERROR: Corrupt startup-config, system has reverted to default login credentials"
else
# Ensure correct ownership and permissions, in particular after factory reset
# Created by the system, writable by any user in the admin group.
chown root:wheel "$fn"
chmod 0660 "$fn"
fi
-37
View File
@@ -11,43 +11,6 @@
]
},
"rule-list": [
{
"name": "guest-acl",
"group": [
"guest"
],
"rule": [
{
"name": "deny-ncm",
"module-name": "ietf-netconf-monitoring",
"access-operations": "*",
"action": "deny",
"comment": "Disallow guests access to any NETCONF monitoring information."
}
]
},
{
"name": "limited-acl",
"group": [
"limited"
],
"rule": [
{
"name": "permit-ncm",
"module-name": "ietf-netconf-monitoring",
"access-operations": "read",
"action": "permit",
"comment": "Allow read access to the NETCONF monitoring information."
},
{
"name": "permit-exec",
"module-name": "*",
"access-operations": "exec",
"action": "permit",
"comment": "Allow invocation of the supported server operations."
}
]
},
{
"name": "admin-acl",
"group": [
+1 -1
View File
@@ -1,3 +1,3 @@
factorydir = $(pkgdatadir)/factory.d
dist_factory_DATA = 10-nacm.json 10-netconf-server.json \
10-infix-system.json 10-system.json
10-infix-services.json 10-system.json
+1 -1
View File
@@ -434,7 +434,7 @@ int cni_ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
return SR_ERR_SYS;
err = sr_get_data(session, path, 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err;
node = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
+4
View File
@@ -127,6 +127,10 @@ int dagger_should_skip_current(struct dagger *d, const char *ifname)
return fexistf("%s/%d/skip/%s", d->path, d->current, ifname);
}
int dagger_is_bootstrap(struct dagger *d)
{
return d->next == 0;
}
int dagger_claim(struct dagger *d, const char *path)
{
+1
View File
@@ -30,6 +30,7 @@ int dagger_evolve_or_abandon(struct dagger *d);
void dagger_skip_iface(struct dagger *d, const char *ifname);
int dagger_should_skip(struct dagger *d, const char *ifname);
int dagger_should_skip_current(struct dagger *d, const char *ifname);
int dagger_is_bootstrap(struct dagger *d);
int dagger_claim(struct dagger *d, const char *path);
+1 -1
View File
@@ -196,7 +196,7 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
return SR_ERR_OK;
rc = sr_get_data(session, XPATH_BASE_ "//.", 0, 0, 0, &cfg);
if (rc)
if (rc || !cfg)
goto err;
rc = srx_get_diff(session, &diff);
+65 -16
View File
@@ -663,10 +663,45 @@ skip_mtu:
return err;
}
static bool iface_uses_autoneg(struct lyd_node *cif)
{
struct lyd_node *aneg = lydx_get_descendant(lyd_child(cif), "ethernet",
"auto-negotiation", NULL);
/* Because `ieee802-ethernet-interface` declares
* `auto-negotiation` as a presence container, the `enabled`
* leaf, although `true` by default, is not set if the whole
* container is absent. Since auto-negotiation is the expected
* default behavior for most Ethernet links, we choose to
* enable it in these situations.
*/
return !aneg || lydx_get_bool(aneg, "enable");
}
/*
* XXX: always disable flow control, for now, until we've added
* configurable support for flow-control/pause/direction and
* flow-control/force-flow-control
*/
static int netdag_gen_ethtool_flow_control(struct dagger *net, struct lyd_node *cif)
{
const char *ifname = lydx_get_cattr(cif, "name");
FILE *fp;
fp = dagger_fopen_next(net, "init", ifname, 10, "ethtool-aneg.sh");
if (!fp)
return -EIO;
fprintf(fp, "ethtool --pause %s autoneg %s rx off tx off\n",
ifname, iface_uses_autoneg(cif) ? "on" : "off");
fclose(fp);
return 0;
}
static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
{
struct lyd_node *eth = lydx_get_child(cif, "ethernet");
struct lyd_node *aneg = lydx_get_child(eth, "auto-negotiation");
const char *ifname = lydx_get_cattr(cif, "name");
const char *speed, *duplex;
int mbps, err = 0;
@@ -678,7 +713,7 @@ static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
fprintf(fp, "ethtool --change %s autoneg ", ifname);
if (!aneg || lydx_is_enabled(aneg, "enable")) {
if (iface_uses_autoneg(cif)) {
fputs("on\n", fp);
} else {
speed = lydx_get_cattr(eth, "speed");
@@ -740,7 +775,18 @@ static int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct l
if (strcmp(type, "infix-if-type:ethernet"))
return 0;
if (lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL) ||
if (!eth)
return 0;
if (dagger_is_bootstrap(net) ||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL)) {
err = netdag_gen_ethtool_flow_control(net, cif);
if (err)
return err;
}
if (dagger_is_bootstrap(net) ||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL) ||
lydx_get_child(eth, "speed") ||
lydx_get_child(eth, "duplex")) {
err = netdag_gen_ethtool_autoneg(net, cif);
@@ -1126,8 +1172,9 @@ static int vlan_mcast_settings(sr_session_ctx_t *session, FILE *br, const char *
snooping = lydx_is_enabled(mcast, "snooping");
querier = querier_mode(lydx_get_cattr(mcast, "querier"));
fprintf(br, "vlan global set vid %d dev %s mcast_snooping %d\n",
fprintf(br, "vlan global set vid %d dev %s mcast_snooping %d",
vid, brname, snooping);
fprintf(br, " mcast_igmp_version 3 mcast_mld_version 2\n");
interval = atoi(lydx_get_cattr(mcast, "query-interval"));
ifname = find_vlan_interface(session, brname, vid);
@@ -1139,7 +1186,7 @@ static int vlan_mcast_settings(sr_session_ctx_t *session, FILE *br, const char *
return 0;
}
static int bridge_mcast_settings(FILE *ip, const char *brname, struct lyd_node *cif, int vlan_filtering)
static int bridge_mcast_settings(FILE *ip, const char *brname, struct lyd_node *cif, int vlan_mcast)
{
int interval, querier, snooping;
struct lyd_node *mcast;
@@ -1147,19 +1194,21 @@ static int bridge_mcast_settings(FILE *ip, const char *brname, struct lyd_node *
mcast = lydx_get_descendant(lyd_child(cif), "bridge", "multicast", NULL);
if (!mcast) {
mcast_querier(brname, 0, 0, 0);
return 0;
interval = snooping = querier = 0;
} else {
snooping = lydx_is_enabled(mcast, "snooping");
querier = querier_mode(lydx_get_cattr(mcast, "querier"));
interval = atoi(lydx_get_cattr(mcast, "query-interval"));
}
snooping = lydx_is_enabled(mcast, "snooping");
querier = querier_mode(lydx_get_cattr(mcast, "querier"));
fprintf(ip, " mcast_vlan_snooping %d", vlan_mcast ? 1 : 0);
fprintf(ip, " mcast_snooping %d mcast_querier 0", vlan_mcast ? 1 : snooping);
if (snooping)
fprintf(ip, " mcast_igmp_version 3 mcast_mld_version 2");
if (interval)
fprintf(ip, " mcast_query_interval %d", interval * 100);
fprintf(ip, " mcast_vlan_snooping %d", vlan_filtering ? snooping : 0);
fprintf(ip, " mcast_snooping %d mcast_querier 0", snooping);
interval = atoi(lydx_get_cattr(mcast, "query-interval"));
fprintf(ip, " mcast_query_interval %d", interval * 100);
if (!vlan_filtering)
if (!vlan_mcast)
mcast_querier(brname, 0, querier, interval);
else
mcast_querier(brname, 0, 0, 0);
@@ -1650,7 +1699,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
return err;
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, (struct lyd_node **)&diff);
+9 -2
View File
@@ -348,6 +348,11 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
}
rc = sr_get_data(session, "/ietf-routing:routing/control-plane-protocols//.", 0, 0, 0, &cfg);
if (rc || !cfg) {
NOTE("No control-plane-protocols available.");
goto err_close;
}
LY_LIST_FOR(lyd_child(cfg->tree), tmp) {
LY_LIST_FOR(lyd_child(tmp), cplane) {
const char *type;
@@ -360,11 +365,13 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
}
}
}
fclose(fp);
sr_release_data(cfg);
err_close:
fclose(fp);
if (!staticd_enabled)
(void)remove(STATICD_CONF_NEXT);
sr_release_data(cfg);
err_abandon:
return rc;
}
+263 -43
View File
@@ -4,6 +4,8 @@
#include <ctype.h>
#include <paths.h>
#include <pwd.h>
#include <grp.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
@@ -16,6 +18,7 @@
#include "base64.h"
#include "core.h"
#define NACM_BASE_ "/ietf-netconf-acm:nacm"
#define XPATH_BASE_ "/ietf-system:system"
#define XPATH_AUTH_ XPATH_BASE_"/authentication"
#define CLOCK_PATH_ "/ietf-system:system-state/clock"
@@ -291,7 +294,30 @@ static int aug_set_dynpath(augeas *aug, const char *val, const char *fmt, ...)
res = aug_set(aug, path, val);
if (res != 0)
ERROR("Unable to set aug path \"%s\" to \"%s\"\n", path, val);
ERROR("Unable to set aug path \"%s\" to \"%s\"", path, val);
free(path);
return res;
}
static int aug_get_dynpath(augeas *aug, const char **val, const char *fmt, ...)
{
va_list ap;
char *path;
int res;
va_start(ap, fmt);
res = vasprintf(&path, fmt, ap);
va_end(ap);
if (res == -1)
return res;
res = aug_get(aug, path, val);
if (res <= 0)
ERROR("Unable to get aug path \"%s\"", path);
else
res = 0;
free(path);
@@ -418,7 +444,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
continue;
name = sr_val_to_str(old);
DEBUG("Removing NTP server %s\n", name);
DEBUG("Removing NTP server %s", name);
erasef("/etc/chrony/sources.d/%s.sources", name);
free(name);
changes++;
@@ -518,12 +544,11 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
case SR_EV_DONE:
/* Check if passed validation in previous event */
if (access(RESOLV_NEXT, F_OK))
return SR_ERR_OK;
(void)remove(RESOLV_PREV);
(void)rename(RESOLV_CONF, RESOLV_PREV);
(void)rename(RESOLV_NEXT, RESOLV_CONF);
if (!access(RESOLV_NEXT, F_OK)) {
(void)remove(RESOLV_PREV);
(void)rename(RESOLV_CONF, RESOLV_PREV);
(void)rename(RESOLV_NEXT, RESOLV_CONF);
}
/* in bootstrap, another resolvconf will soon take your call */
if (systemf("initctl -bq cond get hook/sys/up"))
@@ -570,11 +595,10 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
goto fail;
for (size_t i = 0; i < cnt; i++) {
const char *xpath = val[i].xpath;
char *ptr;
/* Get /ietf-system:system/dns-resolver/server[name='foo'] */
ptr = srx_get_str(session, "%s/udp-and-tcp/address", xpath);
ptr = srx_get_str(session, "%s/udp-and-tcp/address", val[i].xpath);
if (ptr)
/* XXX: add support also for udp-and-tcp/port */
fprintf(fp, "nameserver %s\n", ptr);
@@ -613,7 +637,7 @@ static char *sys_find_usable_shell(sr_session_ctx_t *sess, char *name)
sr_data_t *cfg;
snprintf(xpath, sizeof(xpath), XPATH_AUTH_"/user[name='%s']/infix-system:shell", name);
if (!sr_get_data(sess, xpath, 0, 0, 0, &cfg)) {
if (!sr_get_data(sess, xpath, 0, 0, 0, &cfg) && cfg) {
struct lyd_node *node;
if (!lyd_find_path(cfg->tree, xpath, 0, &node))
@@ -642,12 +666,18 @@ static char *sys_find_usable_shell(sr_session_ctx_t *sess, char *name)
shell = LOGIN_SHELL;
shell = strdup(shell);
sr_release_data(cfg);
if (cfg)
sr_release_data(cfg);
return shell;
}
static int sys_del_user(char *user)
/*
* Used both when deleting a user from the system configuration, and
* when cleaning up stale users while adding a new user to the system.
* In the latter case we don't need to log failure/success.
*/
static int sys_del_user(char *user, bool silent)
{
char *args[] = {
"deluser", "--remove-home", user, NULL
@@ -657,37 +687,71 @@ static int sys_del_user(char *user)
erasef("/var/run/sshd/%s.keys", user);
err = systemv_silent(args);
if (err) {
ERROR("Error deleting user \"%s\"\n", user);
if (!silent)
ERROR("Error deleting user \"%s\"", user);
/* Ensure $HOME is removed at least. */
systemf("rm -rf /home/%s", user);
return SR_ERR_SYS;
}
DEBUG("User \"%s\" deleted\n", user);
if (!silent)
NOTE("User \"%s\" deleted", user);
return SR_ERR_OK;
}
/*
* XXX: drop superuser/wheel exception as soon as we have clish-ng in place.
* It is supposed to connect to the netopeer server via 127.0.0.1 so
* that the full NACM applies to the user instead of the file system
* permissions that apply to the current klish.
* Helper for sys_add_user(), notice how uid:gid must never be 0:0, it
* is reserved for the system root user which is never created/deleted.
*
* This function balances both /etc/passwd and /etc/group, so to make
* things a little bit easier, we simplify the world and reserve the
* same group name as the username. This means we can always remove
* any stale group entries first.
*
* When uid:gid is non-zero we create the user and re-attach them with
* their $HOME. When uid:gid *is* zero, however, we must make sure to
* clean up any stale user + $HOME before calling adduser to allocate
* a new uid:gid pair for the new user.
*
* If this function fails, it is up to the callee to retry the operation
* with a zero uid:gid pair, which is the most iron clad form.
*/
static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
static int sys_call_adduser(sr_session_ctx_t *sess, char *name, uid_t uid, gid_t gid)
{
char *shell = sys_find_usable_shell(sess, name);
char *sargs[] = {
"adduser", "-d", "-s", shell, "-S", "-G", "wheel", name, NULL
char *eargs[] = {
"adduser", "-d", "-s", shell, "-u", NULL, "-G", NULL, "-H", name, NULL
};
char *uargs[] = {
char *nargs[] = {
"adduser", "-d", "-s", shell, name, NULL
};
char uid_str[10], grp_str[strlen(name) + 1];
char **args;
int err;
/* XXX: group mapping to wheel should be done using nacm ACLs instead. */
if (!strcmp(name, "admin"))
args = sargs; /* superuser */
else
args = uargs; /* user */
DEBUG("Adding new user %s, cleaning up any stale group.", name);
systemf("delgroup %s 2>/dev/null", name);
/* reusing existing uid:gid from $HOME */
if (uid && gid) {
/* recreate group first */
systemf("addgroup -g %d %s", gid, name);
snprintf(uid_str, sizeof(uid_str), "%d", uid);
snprintf(grp_str, sizeof(grp_str), "%s", name);
eargs[5] = uid_str;
eargs[7] = grp_str;
args = eargs;
} else {
DEBUG("Cleaning up any stale user %s and /home/%s", name, name);
sys_del_user(name, true);
args = nargs;
}
/**
* The Busybox implementation of 'adduser -d' sets the password
@@ -696,11 +760,51 @@ static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
*/
err = systemv_silent(args);
free(shell);
return err;
}
/*
* Create a new (locked) user, if they have a matching $HOME we use the
* uid:gid from that, if they are free. In all cases of conflict with
* any (type of) user we remove the existing $HOME and start with a new
* uid:gid pair.
*/
static int sys_add_user(sr_session_ctx_t *sess, char *name)
{
char home[strlen(name) + 10];
bool reused = false;
struct stat st;
int err;
/* Map users to their existing $HOME */
snprintf(home, sizeof(home), "/home/%s", name);
if (!stat(home, &st)) {
/* Verify IDs aren't already used, like BusyBox adduser */
if (getpwuid(st.st_uid) || getgrgid(st.st_uid) || getgrgid(st.st_gid)) {
/* Exists but owned by someone else. */
ERROR("Failed mapping user %s to /home/%s, uid:gid (%d:%d) already exists.",
name, name, st.st_uid, st.st_gid);
err = sys_call_adduser(sess, name, 0, 0);
} else {
DEBUG("Reusing uid:gid %d:%d and /home/%s for new user %s",
st.st_uid, st.st_gid, name, name);
err = sys_call_adduser(sess, name, st.st_uid, st.st_gid);
if (err) {
ERROR("Failed reusing uid:gid from /home/%s, retrying create user ...", name);
err = sys_call_adduser(sess, name, 0, 0);
} else
reused = true;
}
} else
err = sys_call_adduser(sess, name, 0, 0);
if (err) {
ERROR("Failed creating new user \"%s\"\n", name);
ERROR("Failed creating new user \"%s\"", name);
return SR_ERR_SYS;
}
NOTE("New user \"%s\" created\n", name);
NOTE("User \"%s\" created%s.", name, reused ? ", mapped to existing home directory" : "");
/*
* OpenSSH in Infix has been set up to use /var/run/sshd/%s.keys
@@ -708,6 +812,7 @@ static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
* /home/%s/.ssh/authorized_keys file. This creates a both the
* directory and the symlink owned by root to prevent tampering.
*/
DEBUG("Adding secure /home/%s/.ssh directory.", name);
fmkpath(0750, "/home/%s/.ssh", name);
systemf("ln -sf /var/run/sshd/%s.keys /home/%s/.ssh/authorized_keys", name, name);
@@ -735,7 +840,7 @@ static char *change_get_user(struct sr_change *change)
if (user) {
pw = getpwnam(user);
if (!pw) {
ERROR("Skipping attribute for missing user (%s)", user);
/* Skipping, user probably deleted. */
free(user);
user = NULL;
}
@@ -760,7 +865,7 @@ static sr_error_t handle_sr_passwd_update(augeas *aug, sr_session_ctx_t *, struc
assert(change->new);
if (change->new->type != SR_STRING_T) {
ERROR("Internal error, expected pass to be string type\n");
ERROR("Internal error, expected pass to be string type.");
err = SR_ERR_INTERNAL;
break;
}
@@ -773,7 +878,7 @@ static sr_error_t handle_sr_passwd_update(augeas *aug, sr_session_ctx_t *, struc
* it as "*", meaning the user can log in with SSH keys.
*/
if (!hash || !strlen(hash)) {
ERROR("Empty passwords are not allowed, disabling password login.\n");
ERROR("Empty passwords are not allowed, disabling password login.");
hash = "*";
}
if (aug_set_dynpath(aug, hash, "etc/shadow/%s/password", user))
@@ -795,12 +900,28 @@ static sr_error_t handle_sr_passwd_update(augeas *aug, sr_session_ctx_t *, struc
return err;
}
/* Is user allowed to use a POSIX shell? */
static void check_shell(augeas *aug, const char *user)
{
const char *shell;
if (!aug_get_dynpath(aug, &shell, "/files/etc/passwd/%s/shell", user)) {
if (strcmp(shell, "/bin/false") && strcmp(shell, "/bin/clish")) {
WARN("Disabling ssh/console login for %s, only CLI shell allowed.", user);
aug_set_dynpath(aug, "/bin/false", "etc/passwd/%s/shell", user);
}
}
}
static sr_error_t handle_sr_shell_update(augeas *aug, sr_session_ctx_t *sess, struct sr_change *change)
{
char *shell = NULL;
char *user;
int err;
if (change->op == SR_OP_DELETED)
return SR_ERR_OK;
user = change_get_user(change);
if (!user)
return SR_ERR_OK;
@@ -833,7 +954,7 @@ static sr_error_t check_sr_user_update(augeas *aug, sr_session_ctx_t *, struct s
ERROR("Invalid username \"%s\"", name);
return SR_ERR_VALIDATION_FAILED;
}
ERROR("Username \"%s\" is valid", name);
NOTE("Username \"%s\" is valid", name);
return SR_ERR_OK;
}
@@ -849,24 +970,22 @@ static sr_error_t handle_sr_user_update(augeas *aug, sr_session_ctx_t *sess, str
assert(change->new);
name = sr_xpath_key_value(change->new->xpath, "user", "name", &state);
err = sys_add_new_user(sess, name);
err = sys_add_user(sess, name);
if (err) {
sr_xpath_recover(&state);
return err;
}
NOTE("User %s created", name);
sr_xpath_recover(&state);
break;
case SR_OP_DELETED:
assert(change->old);
name = sr_xpath_key_value(change->old->xpath, "user", "name", &state);
err = sys_del_user(name);
err = sys_del_user(name, false);
if (err) {
sr_xpath_recover(&state);
return err;
}
NOTE("User %s deleted", name);
sr_xpath_recover(&state);
break;
case SR_OP_MOVED:
@@ -894,8 +1013,9 @@ static sr_error_t generate_auth_keys(sr_session_ctx_t *session, const char *xpat
sr_error_t err = 0;
sr_data_t *cfg;
/* err may be OK and cfg NULL if 'no system' */
err = sr_get_data(session, xpath, 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
return err;
auth = lydx_get_descendant(cfg->tree, "system", "authentication", NULL);
@@ -964,7 +1084,7 @@ static sr_error_t change_auth_done(augeas *aug, sr_session_ctx_t *session)
*/
err = aug_load(aug);
if (err) {
ERROR("Error loading files into aug tree\n");
ERROR("Error loading files into aug tree.");
return SR_ERR_INTERNAL;
}
@@ -1000,7 +1120,7 @@ static sr_error_t change_auth_done(augeas *aug, sr_session_ctx_t *session)
return err;
}
DEBUG("Changes to authentication saved\n");
DEBUG("Changes to authentication saved.");
return SR_ERR_OK;
}
@@ -1018,6 +1138,102 @@ static int change_auth(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return SR_ERR_OK;
}
static int change_nacm(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *_, sr_event_t event, unsigned request_id, void *priv)
{
sr_val_t *users = NULL, *groups = NULL, *rules = NULL;
size_t user_count = 0, group_count = 0, rule_count = 0;
struct confd *confd = (struct confd *)priv;
int rc;
if (event != SR_EV_DONE)
return SR_ERR_OK;
/* Fetch all users from ietf-system */
rc = sr_get_items(session, XPATH_AUTH_"/user/name", 0, 0, &users, &user_count);
if (SR_ERR_OK != rc) {
ERROR("Failed fetching system users: %s", sr_strerror(rc));
goto cleanup;
}
aug_load(confd->aug);
for (size_t i = 0; i < user_count; i++) {
const char *user = users[i].data.string_val;
char xpath[256];
bool is_admin = false;
char *path = NULL;
char **match;
int num;
/* Fetch groups for each user */
snprintf(xpath, sizeof(xpath), NACM_BASE_"/groups/group[user-name='%s']/name", user);
rc = sr_get_items(session, xpath, 0, 0, &groups, &group_count);
if (!rc) {
for (size_t j = 0; j < group_count; j++) {
/* Fetch and check rules for each group */
snprintf(xpath, sizeof(xpath), NACM_BASE_"/rule-list[group='%s']/rule"
"[module-name='*'][access-operations='*'][action='permit']",
groups[j].data.string_val);
rc = sr_get_items(session, xpath, 0, 0, &rules, &rule_count);
if (rc)
continue; /* not found, this is OK */
/* At least one group grants full administrator permissions */
is_admin = true;
sr_free_values(rules, rule_count);
}
sr_free_values(groups, group_count);
}
/* Check if user is already in group */
num = aug_match(confd->aug, "/files/etc/group/wheel/user", &match);
if (num) {
for (int j = 0; j < num; j++) {
const char *val = NULL;
aug_get(confd->aug, match[j], &val);
if (val && !strcmp(val, user))
path = match[j];
else
free(match[j]);
}
free(match);
}
if (is_admin) {
if (path)
goto done; /* already admin */
if (aug_set(confd->aug, "/files/etc/group/wheel/user[last() + 1]", user))
ERROR("Failed giving user %s UNIX sysadmin permissions.", user);
else
NOTE("User %s added to UNIX sysadmin group.", user);
} else {
check_shell(confd->aug, user);
if (!path)
goto done; /* not member of wheel */
if (aug_rm(confd->aug, path) < 1)
ERROR("Failed removing user %s from UNIX sysadmin group.", user);
else
NOTE("User %s removed from UNIX sysadmin group.", user);
}
done:
if (path)
free(path);
}
aug_save(confd->aug);
cleanup:
if (users)
sr_free_values(users, user_count);
return 0;
}
static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
{
@@ -1151,8 +1367,9 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha
nm = srx_get_str(session, "%s", xpath);
if (!nm) {
/* XXX: derive from global "options.h" or /usr/share/factory/ */
nm = strdup("infix");
nm = fgetkey("/etc/os-release", "DEFAULT_HOSTNAME");
if (nm)
nm = strdup(nm);
if (!nm) {
err = SR_ERR_NO_MEMORY;
goto err;
@@ -1233,6 +1450,9 @@ int ietf_system_init(struct confd *confd)
}
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_AUTH_, 0, change_auth, confd, &confd->sub);
REGISTER_MONITOR(confd->session, "ietf-netconf-acm", "/ietf-netconf-acm:nacm//.",
0, change_nacm, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/hostname", 0, change_hostname, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd", 0, change_motd, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd-banner", 0, change_motd_banner, confd, &confd->sub);
+1 -1
View File
@@ -226,7 +226,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
+10 -1
View File
@@ -278,7 +278,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
err = sr_get_data(session, XPATH "//.", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
@@ -312,6 +312,15 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
}
if (!ena) {
LYX_LIST_FOR_EACH(cifs, cif, "client-if") {
const char *ifname = lydx_get_cattr(cif, "if-name");
INFO("DHCP client globally disabled, stopping client on %s ...", ifname);
del(ifname);
}
}
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
+4 -4
View File
@@ -87,7 +87,7 @@ static int mdns_records(const char *cmd, svc type)
snprintf(buf, sizeof(buf), srv->text, hostname);
systemf("/usr/libexec/confd/gen-service %s %s %s %s %d \"%s\" %s", cmd,
hostname, srv->name, name[type], srv->port, srv->desc, buf);
hostname, srv->name, srv->type, srv->port, srv->desc, buf);
}
return SR_ERR_OK;
@@ -104,7 +104,7 @@ static sr_data_t *get(sr_session_ctx_t *session, sr_event_t event, const char *x
return NULL; /* Don't care about CHANGE, ABORT, etc. */
snprintf(path, sizeof(path), "%s//.", xpath);
if (sr_get_data(session, path, 0, 0, 0, &cfg)) {
if (sr_get_data(session, path, 0, 0, 0, &cfg) || !cfg) {
ERROR("no data for %s", path);
return NULL;
}
@@ -165,7 +165,7 @@ static void svc_enadis(int ena, svc type, const char *svc)
}
if (type != none)
mdns_records(ena ? "" : "delete", type);
mdns_records(ena ? "add" : "delete", type);
systemf("initctl -nbq touch avahi");
systemf("initctl -nbq touch nginx");
@@ -285,7 +285,7 @@ static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
svc_enadis(0, netbrowse, NULL);
}
svc_enadis(ena, none, "nginx"); /* fake it, not nginx .conf */
svc_enadis(ena, web, "nginx");
mdns_cname(session);
return put(cfg, srv);
@@ -13,10 +13,19 @@ module infix-hardware {
prefix yang;
}
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description "Vital Product Data augmentation of ieee-hardware and deviations.";
revision 2024-04-25 {
description "Spellcheck leaf: coutry-code -> country-code";
reference "internal";
}
revision 2024-01-18 {
description "Initial";
reference "internal";
}
typedef country-code {
type string {
length 2;
@@ -114,7 +123,7 @@ module infix-hardware {
leaf manufacturer {
type string;
}
leaf coutry-code {
leaf country-code {
type country-code;
}
leaf vendor {

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