mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-26 10:43:02 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2291e9fd11 | ||
|
|
095c9c331e | ||
|
|
b8fc8b7f62 | ||
|
|
95931c8c0a | ||
|
|
dd788f5611 | ||
|
|
5d99c12089 | ||
|
|
03437fc936 | ||
|
|
56a086ef52 | ||
|
|
3f3fb4eeb4 | ||
|
|
4998e320c5 | ||
|
|
496d56e975 | ||
|
|
82df624ae9 | ||
|
|
5021a1da88 | ||
|
|
df1fc6f2d7 | ||
|
|
2ebcf26ede | ||
|
|
b1a77deadf | ||
|
|
bce1b34873 | ||
|
|
91f31c00c3 | ||
|
|
4b4ffdd14e | ||
|
|
50c83f1be7 | ||
|
|
ee86d12dc2 | ||
|
|
b388e080ad | ||
|
|
6e630018df | ||
|
|
9de5e5b802 | ||
|
|
399d3c365d | ||
|
|
3867abe4da | ||
|
|
90d2ae3868 | ||
|
|
581d1742e5 | ||
|
|
172d7607bb | ||
|
|
62a4b48679 | ||
|
|
3e07c9a960 | ||
|
|
05c197c457 | ||
|
|
77c321daa3 | ||
|
|
3d99af87d6 | ||
|
|
28c2a4a6cc | ||
|
|
1bbd62c021 | ||
|
|
ecc0b63da2 | ||
|
|
347e493542 | ||
|
|
77499790ba | ||
|
|
a960267c40 | ||
|
|
b9f3254ba7 | ||
|
|
266f18bbeb | ||
|
|
b70129f178 | ||
|
|
888f0c4207 | ||
|
|
88fa47c664 | ||
|
|
2ecc2c3602 | ||
|
|
02d8288863 | ||
|
|
d1dde5406e | ||
|
|
fd7b4bbe39 | ||
|
|
c28ea1db19 | ||
|
|
d68dacdc80 | ||
|
|
91f0094048 | ||
|
|
5660f6239d | ||
|
|
58cf5abf0b | ||
|
|
fc32d8a9db | ||
|
|
4b2f140140 | ||
|
|
67cb307f2d | ||
|
|
3811df9ab2 | ||
|
|
53d0995d0c | ||
|
|
7a692fd57d | ||
|
|
73e1c158f5 | ||
|
|
ab3b389f69 | ||
|
|
417d48f015 | ||
|
|
b6aa604cdd | ||
|
|
0dbf99cc82 | ||
|
|
7127caf6b5 | ||
|
|
638862d268 | ||
|
|
2d7dedf79c | ||
|
|
f690cd216c | ||
|
|
6a5bf66a42 | ||
|
|
5707711d84 | ||
|
|
5b3eb23aeb | ||
|
|
51987948ad | ||
|
|
e70559a68d | ||
|
|
83797ca19c | ||
|
|
d82b3e51ea | ||
|
|
e03bd37660 | ||
|
|
ee26cec88a | ||
|
|
88763034ed | ||
|
|
dad1c024aa | ||
|
|
f92d3846db | ||
|
|
ffab761274 | ||
|
|
b4c648229a | ||
|
|
1ca7acda14 | ||
|
|
8f30f88967 | ||
|
|
8eaaaa9d38 | ||
|
|
4e0ad1df1b | ||
|
|
dc3b78e678 | ||
|
|
4d7dde5366 | ||
|
|
3c0679991d | ||
|
|
fe741a92f3 | ||
|
|
f6879e24cc | ||
|
|
7e252ba941 | ||
|
|
46d5e750d7 | ||
|
|
5988249f84 | ||
|
|
7aee2600ba | ||
|
|
6f99a9c2dc | ||
|
|
eee1ce32fa | ||
|
|
d9f2f2c8f9 | ||
|
|
31d0f79a10 | ||
|
|
b290e44318 | ||
|
|
2d806de2cd | ||
|
|
c5db34b491 | ||
|
|
3d816d2525 | ||
|
|
fb394db981 | ||
|
|
da39855cec | ||
|
|
a6b79857db | ||
|
|
f1271f28b9 | ||
|
|
f62900699a | ||
|
|
cf16efe499 | ||
|
|
4260d24143 | ||
|
|
3ef1da1096 | ||
|
|
a90a39e8d8 | ||
|
|
dc5c7732d7 | ||
|
|
5bf9200880 | ||
|
|
f9b155b49f | ||
|
|
9782ac9afa | ||
|
|
773683bfd5 | ||
|
|
3dbb1759eb | ||
|
|
d7895d5c9c | ||
|
|
78499757b0 | ||
|
|
ec2e161649 | ||
|
|
18d8c439bd | ||
|
|
1ca11f1fe7 | ||
|
|
b70d0015a6 | ||
|
|
6a417f2f23 | ||
|
|
f212f0cc16 | ||
|
|
01d07b4942 | ||
|
|
039cb5db74 | ||
|
|
65bce0378e | ||
|
|
91cef6d57b | ||
|
|
f3da31b18c | ||
|
|
af1f173497 | ||
|
|
14fede3e56 | ||
|
|
d3bfbb57b6 | ||
|
|
3203ee925a | ||
|
|
fae1265587 | ||
|
|
97f3db8fdb | ||
|
|
a8b5120871 | ||
|
|
c22339c2cd | ||
|
|
b1830a36d4 | ||
|
|
05510c5001 | ||
|
|
343c465352 | ||
|
|
0cb2987de4 | ||
|
|
7d646c9494 | ||
|
|
395b21c693 | ||
|
|
6ef3ad9020 | ||
|
|
a608c4a36d | ||
|
|
e48da5bb21 | ||
|
|
f389a1f087 | ||
|
|
84521ea9b5 | ||
|
|
4ba43e2ddd | ||
|
|
3606bc05cf |
@@ -0,0 +1,26 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability in Infix, please use GitHub's built-in
|
||||
[Report a Vulnerability](https://github.com/kernelkit/infix/security/advisories/new)
|
||||
feature for a private and secure disclosure.
|
||||
|
||||
When reporting, include:
|
||||
|
||||
- A clear description of the vulnerability.
|
||||
- Steps to reproduce the issue.
|
||||
- Potential impact of the vulnerability.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We provide security updates only for the main branch.
|
||||
|
||||
Individual support contracts are provided by _Wires_. See
|
||||
[Support](https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md)
|
||||
for more information.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
We appreciate the efforts of the security community to help improve the security
|
||||
of Infix. Thank you for your responsible disclosure.
|
||||
@@ -35,6 +35,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
clean: true
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Set Build Variables
|
||||
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
|
||||
libcrypt-dev libglib2.0-dev libpcre2-dev \
|
||||
libuev-dev libite-dev
|
||||
libuev-dev
|
||||
|
||||
- name: Build dependencies
|
||||
run: |
|
||||
@@ -65,6 +65,8 @@ jobs:
|
||||
git clone https://github.com/sysrepo/sysrepo.git
|
||||
mkdir sysrepo/build
|
||||
(cd sysrepo/build && cmake .. && make all && sudo make install)
|
||||
git clone https://github.com/troglobit/libite.git
|
||||
(cd libite && ./autogen.sh && ./configure && make && sudo make install)
|
||||
make dep
|
||||
|
||||
- name: Check applications
|
||||
|
||||
@@ -106,6 +106,16 @@ more information, see: [Infix in Virtual Environments](doc/virtual.md).
|
||||
>
|
||||
> For *customer specific builds* of Infix, see your product repository.
|
||||
|
||||
|
||||
----
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/wires-se"><img src="https://raw.githubusercontent.com/wires-se/.github/main/profile/logo.png" width=300></a>
|
||||
<br />Infix development is sponsored by <a href="https://wires.se">Wires<a>
|
||||
</div>
|
||||
|
||||
----
|
||||
|
||||
[^1]: An immutable operating system is one with read-only file systems,
|
||||
atomic updates, rollbacks, declarative configuration, and workload
|
||||
isolation. All to improve reliability, scalability, and security.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Busybox version: 1.36.1
|
||||
# Tue Oct 22 13:12:02 2024
|
||||
# Sun Feb 9 12:25:37 2025
|
||||
#
|
||||
CONFIG_HAVE_DOT_CONFIG=y
|
||||
|
||||
@@ -17,7 +17,7 @@ CONFIG_SHOW_USAGE=y
|
||||
CONFIG_FEATURE_VERBOSE_USAGE=y
|
||||
# CONFIG_FEATURE_COMPRESS_USAGE is not set
|
||||
CONFIG_LFS=y
|
||||
# CONFIG_PAM is not set
|
||||
CONFIG_PAM=y
|
||||
CONFIG_FEATURE_DEVPTS=y
|
||||
CONFIG_FEATURE_UTMP=y
|
||||
CONFIG_FEATURE_WTMP=y
|
||||
@@ -325,7 +325,7 @@ CONFIG_FEATURE_STAT_FILESYSTEM=y
|
||||
CONFIG_STTY=y
|
||||
CONFIG_SUM=y
|
||||
CONFIG_SYNC=y
|
||||
# CONFIG_FEATURE_SYNC_FANCY is not set
|
||||
CONFIG_FEATURE_SYNC_FANCY=y
|
||||
CONFIG_FSYNC=y
|
||||
# CONFIG_TAC is not set
|
||||
CONFIG_TAIL=y
|
||||
@@ -336,7 +336,7 @@ CONFIG_TEST=y
|
||||
CONFIG_TEST1=y
|
||||
CONFIG_TEST2=y
|
||||
CONFIG_FEATURE_TEST_64=y
|
||||
# CONFIG_TIMEOUT is not set
|
||||
CONFIG_TIMEOUT=y
|
||||
CONFIG_TOUCH=y
|
||||
CONFIG_FEATURE_TOUCH_SUSV3=y
|
||||
CONFIG_TR=y
|
||||
@@ -357,7 +357,7 @@ CONFIG_BASE32=y
|
||||
CONFIG_BASE64=y
|
||||
CONFIG_UUENCODE=y
|
||||
CONFIG_WC=y
|
||||
# CONFIG_FEATURE_WC_LARGE is not set
|
||||
CONFIG_FEATURE_WC_LARGE=y
|
||||
CONFIG_WHO=y
|
||||
CONFIG_W=y
|
||||
CONFIG_USERS=y
|
||||
|
||||
@@ -66,7 +66,7 @@ endchoice
|
||||
|
||||
config QEMU_MACHINE
|
||||
string "Select emulated machine"
|
||||
default "qemu-system-aarch64 -M virt,accel=kvm:tcg -cpu max" if QEMU_aarch64
|
||||
default "qemu-system-aarch64 -M virt,accel=kvm:tcg -cpu max,pauth-impdef=on" if QEMU_aarch64
|
||||
default "qemu-system-x86_64 -M pc,accel=kvm:tcg -cpu max" if QEMU_x86_64
|
||||
help
|
||||
You should not have to change this setting, although you may
|
||||
|
||||
@@ -9,46 +9,20 @@
|
||||
# $3 IP adddress
|
||||
|
||||
PATH="$PATH:/usr/bin:/usr/sbin:/bin:/sbin"
|
||||
NAME="/etc/frr/static.d/$2-zeroconf.conf"
|
||||
NEXT="${NAME}+"
|
||||
|
||||
log()
|
||||
{
|
||||
logger -I $$ -t zeroconf -p user.notice "$*"
|
||||
}
|
||||
|
||||
# Reduce changes needed by comparing with previous route(s)
|
||||
act()
|
||||
{
|
||||
case $1 in
|
||||
add)
|
||||
echo "! Generated by avahi-autoipd" > "$NEXT"
|
||||
echo "ip route 0.0.0.0/0 $2 254" >> "$NEXT"
|
||||
cmp -s "$NAME" "$NEXT" && return
|
||||
mv "$NEXT" "$NAME"
|
||||
;;
|
||||
del)
|
||||
[ -f "$NAME" ] || return
|
||||
rm "$NAME"
|
||||
;;
|
||||
*)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
initctl -nbq restart staticd
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
BIND)
|
||||
ip addr flush dev "$2" proto random
|
||||
ip addr add "$3"/16 brd 169.254.255.255 scope link dev "$2" proto random
|
||||
act add "$2"
|
||||
log "set ipv4ll $3 on iface $2"
|
||||
;;
|
||||
|
||||
CONFLICT|UNBIND|STOP)
|
||||
act del "$2"
|
||||
ip addr flush dev "$2" proto random
|
||||
log "clr ipv4ll on iface $2"
|
||||
;;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
task name:container-%i :setup \
|
||||
[2345] container -n %i setup -- Setup container %i
|
||||
sysv <!usr/container:%i> :%i pid:!/run/container:%i.pid log:prio:local1,tag:%i kill:10 \
|
||||
[2345] container -n %i -- container %i
|
||||
# Start a container instance (%i) and redirect logs to /log/container
|
||||
# Give podman enough time to properly shut down the container. Every
|
||||
# time we start a container we run the setup stage, disable the Finit
|
||||
# timeout to allow the setup stage to run to completion.
|
||||
sysv log:prio:local1,tag:%i kill:10 pid:!/run/container:%i.pid \
|
||||
pre:0,/usr/sbin/container cleanup:0,/usr/sbin/container \
|
||||
[2345] <!> :%i container -n %i -- container %i
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
net.ipv6.route.max_size=131072
|
||||
net.ipv6.conf.all.ignore_routes_with_linkdown=1
|
||||
|
||||
# IP Routing
|
||||
net.ipv6.conf.all.forwarding=1
|
||||
# IP Routing is disabled by default, enabled globally, and per
|
||||
# interface, for each interface in confd. See also accept_ra.
|
||||
net.ipv6.conf.all.forwarding=0
|
||||
net.ipv6.conf.default.forwarding=0
|
||||
|
||||
# Accept router advertisements even when forwarding is enabled
|
||||
net.ipv6.conf.all.accept_ra=2
|
||||
net.ipv6.conf.default.accept_ra=2
|
||||
|
||||
# IPv6 SLAAC
|
||||
net.ipv6.conf.all.autoconf=0
|
||||
net.ipv6.conf.default.autoconf=0
|
||||
|
||||
@@ -21,7 +21,11 @@ dir()
|
||||
if [ -d "$1" ]; then
|
||||
dir "$1"
|
||||
else
|
||||
dir "$HOME"
|
||||
if [ "$USER" = "root" ]; then
|
||||
dir "$HOME"
|
||||
else
|
||||
dir "/home/$USER"
|
||||
fi
|
||||
dir "/cfg"
|
||||
dir "/log"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
# Initialize speed/duplex of virtio interfaces
|
||||
# For virtual test systems (lacp tests)
|
||||
|
||||
ifaces=$(ip -d -json link show | jq -r '.[] | select(.parentbus == "virtio") | .ifname')
|
||||
for iface in $ifaces; do
|
||||
ethtool -s "$iface" speed 1000 duplex full
|
||||
done
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# This script can be used to start, stop, create, and delete containers.
|
||||
# It is what confd use, with the Finit container@.conf template, to set
|
||||
# up, run, and delete containers.
|
||||
@@ -9,6 +9,7 @@
|
||||
DOWNLOADS=/var/lib/containers/oci
|
||||
BUILTIN=/lib/oci
|
||||
TMPDIR=/var/tmp
|
||||
container=$0
|
||||
checksum=""
|
||||
extracted=
|
||||
timeout=30
|
||||
@@ -109,33 +110,34 @@ EOF
|
||||
# If there are more index files, this function does not handle them.
|
||||
unpack_archive()
|
||||
{
|
||||
image=$1
|
||||
name=$2
|
||||
uri=$1
|
||||
tag=$2
|
||||
img=$(basename "$uri")
|
||||
|
||||
# Supported transports for load and create
|
||||
case "$image" in
|
||||
case "$uri" in
|
||||
oci:*) # Unpacked OCI image
|
||||
file=${image#oci:}
|
||||
file=${uri#oci:}
|
||||
;;
|
||||
oci-archive:*) # Packed OCI image, .tar or .tar.gz format
|
||||
file=${image#oci-archive:}
|
||||
file=${uri#oci-archive:}
|
||||
;;
|
||||
ftp://* | http://* | https://*)
|
||||
if ! file=$(fetch "$image"); then
|
||||
if ! file=$(fetch "$uri"); then
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*) # docker://*, docker-archive:*, or URL
|
||||
if podman image exists "$image"; then
|
||||
echo "$image"
|
||||
if podman image exists "$img"; then
|
||||
echo "$img"
|
||||
return 0
|
||||
fi
|
||||
# XXX: use --retry=0 with Podman 5.0 or later.
|
||||
if ! id=$(podman pull --quiet "$image"); then
|
||||
log "Failed pulling $image"
|
||||
if ! id=$(podman pull --quiet "$uri"); then
|
||||
log "Failed pulling $uri"
|
||||
return 1
|
||||
fi
|
||||
# Echo image name to caller
|
||||
# Echo image tag to caller
|
||||
podman images --filter id="$id" --format "{{.Repository}}:{{.Tag}}"
|
||||
return 0
|
||||
;;
|
||||
@@ -147,7 +149,7 @@ unpack_archive()
|
||||
elif [ -e "$BUILTIN/$file" ]; then
|
||||
file="$BUILTIN/$file"
|
||||
else
|
||||
err 1 "cannot find OCI archive $file in search path."
|
||||
err 1 "cannot find OCI archive $file in URI $uri"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -171,8 +173,8 @@ unpack_archive()
|
||||
|
||||
dir=$(dirname "$index")
|
||||
if echo "$dir" | grep -q ":"; then
|
||||
if [ -z "$name" ]; then
|
||||
name="$dir"
|
||||
if [ -z "$tag" ]; then
|
||||
tag="$dir"
|
||||
fi
|
||||
sanitized_dir=$(echo "$dir" | cut -d':' -f1)
|
||||
mv "$dir" "$sanitized_dir" || err 1 "failed renaming $dir to $sanitized_dir"
|
||||
@@ -188,21 +190,21 @@ unpack_archive()
|
||||
rm -rf "$dir"
|
||||
fi
|
||||
|
||||
# Rename image from podman default $dir:latest
|
||||
if [ -n "$name" ]; then
|
||||
podman tag "$dir" "$name" >/dev/null
|
||||
podman rmi "$dir" >/dev/null
|
||||
# Retag image from podman default $dir:latest
|
||||
if [ -n "$tag" ]; then
|
||||
podman tag "$dir" "$tag" >/dev/null
|
||||
podman rmi "$dir" >/dev/null
|
||||
else
|
||||
name=$dir
|
||||
tag=$dir
|
||||
fi
|
||||
|
||||
echo "$name"
|
||||
echo "$tag"
|
||||
}
|
||||
|
||||
running()
|
||||
{
|
||||
run=$(podman inspect "$1" 2>/dev/null |jq .[].State.Running)
|
||||
[ "$run" = "true" ] && return 0
|
||||
status=$(podman inspect -f '{{.State.Status}}' "$1" 2>/dev/null)
|
||||
[ "$status" = "running" ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -272,7 +274,6 @@ create()
|
||||
delete()
|
||||
{
|
||||
name=$1
|
||||
image=$2
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
echo "Usage:"
|
||||
@@ -281,9 +282,11 @@ delete()
|
||||
fi
|
||||
|
||||
# Should already be stopped, but if not ...
|
||||
container stop "$name"
|
||||
log "$name: should already be stopped, double checking ..."
|
||||
container stop "$name" >/dev/null
|
||||
|
||||
while running "$name"; do
|
||||
log "$name: still running, waiting for it to stop ..."
|
||||
_=$((timeout -= 1))
|
||||
if [ $timeout -le 0 ]; then
|
||||
err 1 "timed out waiting for container $1 to stop before deleting it."
|
||||
@@ -291,6 +294,7 @@ delete()
|
||||
sleep 1
|
||||
done
|
||||
|
||||
log "$name: calling podman rm -vif ..."
|
||||
podman rm -vif "$name" >/dev/null 2>&1
|
||||
[ -n "$quiet" ] || log "Container $name has been removed."
|
||||
}
|
||||
@@ -315,7 +319,7 @@ start()
|
||||
return
|
||||
fi
|
||||
|
||||
initctl -bq cond set "container:$name"
|
||||
initctl start container:$name
|
||||
# Real work is done by wrap() courtesy of finit sysv emulation
|
||||
}
|
||||
|
||||
@@ -328,7 +332,7 @@ stop()
|
||||
return
|
||||
fi
|
||||
|
||||
initctl -bq cond clr "container:$name"
|
||||
initctl stop container:$name
|
||||
# Real work is done by wrap() courtesy of finit sysv emulation
|
||||
}
|
||||
|
||||
@@ -337,7 +341,8 @@ wrap()
|
||||
name=$1
|
||||
cmd=$2
|
||||
|
||||
podman "$cmd" "$name"
|
||||
# Skip "echo $name" from podman start in log
|
||||
podman "$cmd" "$name" >/dev/null
|
||||
}
|
||||
|
||||
# Removes network $1 from all containers
|
||||
@@ -426,11 +431,12 @@ commands:
|
||||
run NAME [CMD] Run a container interactively, with an optional command
|
||||
save IMAGE FILE Save a container image to an OCI tarball FILE[.tar.gz]
|
||||
setup NAME Create and set up container as a Finit task
|
||||
shell Start a shell inside a container
|
||||
shell [CMD] Start a shell, or run CMD, inside a container
|
||||
show [image | volume] Show containers, images, or volumes
|
||||
stat Show continuous stats about containers (Ctrl-C aborts)
|
||||
start [NAME] Start a container, see -n
|
||||
stop [NAME] Stop a container, see -n
|
||||
upgrade NAME Upgrade a running container (stop, pull, restart)
|
||||
volume [prune] Prune unused volumes
|
||||
EOF
|
||||
}
|
||||
@@ -582,19 +588,24 @@ case $cmd in
|
||||
;;
|
||||
delete)
|
||||
cmd=$1
|
||||
name=$2
|
||||
[ -n "$name" ] || name=$2
|
||||
if [ "$cmd" = "network" ] && [ -n "$name" ]; then
|
||||
netwrm "$name"
|
||||
else
|
||||
delete "$@"
|
||||
[ -n "$name" ] || name=$1
|
||||
delete "$name"
|
||||
fi
|
||||
;;
|
||||
exec)
|
||||
podman exec -it "$@"
|
||||
if [ -z "$name" ]; then
|
||||
name="$1"
|
||||
shift
|
||||
fi
|
||||
podman exec -i "$name" "$@"
|
||||
;;
|
||||
flush)
|
||||
echo "Cleaning up any lingering containers";
|
||||
podman rm -av
|
||||
podman rm -av $force
|
||||
;;
|
||||
find)
|
||||
cmd=$1
|
||||
@@ -700,17 +711,25 @@ case $cmd in
|
||||
script=/run/containers/${name}.sh
|
||||
[ -x "$script" ] || err 1 "setup: $script does not exist or is not executable."
|
||||
while ! "$script"; do
|
||||
# Wait for address/route changes, or retry every 60 secods
|
||||
# shellcheck disable=2162,3045
|
||||
ip monitor address route | while read -t 60 _; do break; done
|
||||
log "${name}: setup failed, waiting for network changes ..."
|
||||
read -t 60 _ < <(ip monitor address route)
|
||||
|
||||
# On IP address/route changes, wait a few seconds more to ensure
|
||||
# the system has ample time to react and set things up for us.
|
||||
log "${name}: retrying ..."
|
||||
sleep 2
|
||||
done
|
||||
;;
|
||||
shell)
|
||||
podman exec -it "$1" sh -l
|
||||
if [ -z "$name" ]; then
|
||||
name="$1"
|
||||
shift
|
||||
fi
|
||||
if [ $# -gt 0 ]; then
|
||||
podman exec -i "$name" sh -c "$*"
|
||||
else
|
||||
podman exec -it "$name" sh -l
|
||||
fi
|
||||
;;
|
||||
show)
|
||||
cmd=$1
|
||||
@@ -803,15 +822,15 @@ case $cmd in
|
||||
|
||||
# Likely an OCI archive, or local directory, assume user has updated image.
|
||||
if echo "$img" | grep -Eq '^localhost/'; then
|
||||
file=$(awk '{s=$NF} END{print s}' "$script")
|
||||
echo "Upgrading container ${1} with local archive: $file ..."
|
||||
file=$(awk '/^# meta-image:/ {print $3}' "$script")
|
||||
echo ">> Upgrading container $1 using $file ..."
|
||||
else
|
||||
printf ">> Stopping ... "
|
||||
podman stop "$1"
|
||||
printf ">> "
|
||||
podman pull "$img" || (echo "Failed fetching $img, check your network (settings)."; exit 1)
|
||||
echo ">> Starting $1 ..."
|
||||
fi
|
||||
echo ">> Starting $1 ..."
|
||||
if ! "$script"; then
|
||||
echo ">> Failed recreating container $1"
|
||||
exit 1
|
||||
@@ -831,6 +850,22 @@ case $cmd in
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
if [ -n "$SERVICE_SCRIPT_TYPE" ] && [ -n "$SERVICE_ID" ]; then
|
||||
case "$SERVICE_SCRIPT_TYPE" in
|
||||
pre)
|
||||
# Called as pre-script from Finit service
|
||||
exec $container -q -n "$SERVICE_ID" setup
|
||||
;;
|
||||
cleanup)
|
||||
# Called as cleanup-script from Finit service
|
||||
log "Calling $container -n $SERVICE_ID delete"
|
||||
exec $container -q -n "$SERVICE_ID" delete
|
||||
;;
|
||||
*)
|
||||
false
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
|
||||
+1
-1
Submodule buildroot updated: 92e256798b...3592f7d3e1
@@ -27,7 +27,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.11"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.18"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -27,7 +27,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.11"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.18"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -26,7 +26,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.11"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.18"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -26,7 +26,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.11"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.18"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -4,6 +4,39 @@ Change Log
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
|
||||
[v25.02.0][] - 2025-03-04
|
||||
-------------------------
|
||||
|
||||
### Changes
|
||||
- Upgrade Linux kernel to 6.12.18 (LTS)
|
||||
- Upgrade Buildroot to 2024.02.11 (LTS)
|
||||
- Add support for link aggregation (lag), static (balance-xor) and LACP
|
||||
- Add support for the [i.MX 8M Plus EVK][EVK]
|
||||
- YANG type change for SSH private/public keys, from ietf-crypto-types
|
||||
to infix-crypto-types
|
||||
- Disable global IPv6 forwarding by default, enable by per-interface
|
||||
setting. Note, route advertisements are always accepted. Issue #785
|
||||
- Drop automatic default route (interface route) for IPv4 autoconf, not
|
||||
necessary and causes more confusion than good. Issue #923
|
||||
- Update scripting with new RESTCONF examples
|
||||
|
||||
### Fixes
|
||||
- Fix #896: `/etc/resolv.conf` not properly generated when system runs
|
||||
in fail secure mode (failing to load `startup-config`)
|
||||
- Fix #902: containers "linger" in the system (state 'exited') after
|
||||
having removed them from the configuration
|
||||
- Fix #930: container configuration changes does not apply at runtime
|
||||
only when saved to `startup-config` and system is rebooted
|
||||
- Fix #936: DHCP server reconfiguration does not always take effect.
|
||||
- Fix #956: CLI `copy` command complains it cannot change owner when
|
||||
copying `factory-config` to `running-config`. Bogus error, the
|
||||
latter is not really a file
|
||||
- Fix #977: "Operation not permitted" when saving `running-config` to
|
||||
`startup-config` (harmless warning but annoying and concerning)
|
||||
|
||||
[EVK]: https://www.nxp.com/design/design-center/development-boards-and-designs/8MPLUSLPD4-EVK
|
||||
|
||||
|
||||
[v25.01.0][] - 2025-01-31
|
||||
-------------------------
|
||||
|
||||
@@ -1472,6 +1505,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
|
||||
|
||||
[buildroot]: https://buildroot.org/
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v25.01.0...HEAD
|
||||
[v25.02.0]: https://github.com/kernelkit/infix/compare/v25.01.0...v25.02.0
|
||||
[v25.01.0]: https://github.com/kernelkit/infix/compare/v24.11.0...v25.01.0
|
||||
[v24.11.1]: https://github.com/kernelkit/infix/compare/v24.11.0...v24.11.1
|
||||
[v24.11.0]: https://github.com/kernelkit/infix/compare/v24.10.0...v24.11.0
|
||||
|
||||
+9
-5
@@ -1,13 +1,16 @@
|
||||
<img align="right" src="logo.png" alt="Infix - Linux <3 NETCONF" width=480 border=10>
|
||||
|
||||
Welcome to Infix, your friendly Network Operating System! On these
|
||||
pages you can find both user and developer documentation.
|
||||
|
||||
> Topics on configuring the system include CLI examples, every setting
|
||||
> is also possible to perform using NETCONF. In fact, the Infix test
|
||||
> system solely relies on NETCONF for configuring network topologies.
|
||||
Most topics on configuring the system include CLI examples, but every
|
||||
setting, as well as status read-back from the operational datastore, is
|
||||
also possible to perform using NETCONF or RESTCONF. In fact, the Infix
|
||||
regression test system solely relies on NETCONF and RESTCONF.
|
||||
|
||||
The CLI documentation is also available from inside the CLI itself using
|
||||
the `help` command.
|
||||
> [!TIP]
|
||||
> The CLI documentation is also available from inside the CLI itself
|
||||
> using the `help` command in admin-exec mode.
|
||||
|
||||
- **CLI Topics**
|
||||
- [Introduction to the CLI](cli/introduction.md)
|
||||
@@ -18,6 +21,7 @@ the `help` command.
|
||||
- [Introduction](introduction.md)
|
||||
- [System Configuration](system.md)
|
||||
- [Network Configuration](networking.md)
|
||||
- [DHCP Server](dhcp.md)
|
||||
- [Syslog Support](syslog.md)
|
||||
- **Infix In-Depth**
|
||||
- [Boot Procedure](boot.md)
|
||||
|
||||
+40
-31
@@ -31,9 +31,9 @@ Infix comes with native support for Docker containers using [podman][].
|
||||
The [YANG model][1] describes the current level of support, complete
|
||||
enough to run both system and application containers.
|
||||
|
||||
Key design features, like using Linux switchdev, allow users to assign
|
||||
switch ports directly to containers, not just bridged VETH pairs, this
|
||||
is a rare and in many cases *unique* feature of Infix.
|
||||
Key design features of Infix, like using Linux switchdev, allow users to
|
||||
assign switch ports directly to containers, not just bridged VETH pairs.
|
||||
This is a rare and in many cases *unique* feature of Infix.
|
||||
|
||||
All network specific settings are done using the IETF interfaces YANG
|
||||
model, with augments for containers to ensure smooth integration with
|
||||
@@ -43,7 +43,7 @@ container networking in podman.
|
||||
> Even though the `podman` command can be used directly from a shell
|
||||
> prompt, we strongly recommend using the CLI commands instead. They
|
||||
> employ the services of a wrapper `container` script which handles the
|
||||
> integration of containers in the system.
|
||||
> integration of Docker containers in the system.
|
||||
|
||||
|
||||
Caution
|
||||
@@ -83,18 +83,20 @@ In the CLI, containers can be run in one of two ways:
|
||||
1. `container run IMAGE [COMMAND]`, or
|
||||
2. enter `configure` context, then `edit container NAME`
|
||||
|
||||
The former is useful mostly for testing, or running single commands in
|
||||
an image. It is a wrapper for `podman run -it --rm ...`, while the
|
||||
latter is a wrapper and adaptation of `podman create ...`.
|
||||
The first is useful mostly for testing, or running single commands in
|
||||
an image. It is a wrapper for `podman run -it --rm ...`.
|
||||
|
||||
The second creates a read-only container that is automatically started
|
||||
at every boot. When non-volatile storage is needed, data stored in a
|
||||
volume is persisted until explicitly removed from the configuration,
|
||||
i.e., across host and container reboots and upgrades.
|
||||
The second creates a read-only container that by default automatically
|
||||
start at every boot. It basically wraps `podman create ...`.
|
||||
|
||||
Another option is [Content Mounts](#content-mounts), where the content
|
||||
of a file mounted into the container is kept along with the container
|
||||
configuration in the device's `startup-config`.
|
||||
When non-volatile storage is needed two complementary options exist:
|
||||
|
||||
- **Volumes:** data stored in a volume is persisted until explicitly
|
||||
removed from the configuration, i.e., across host reboots and
|
||||
container upgrades
|
||||
- **[Content Mounts](#content-mounts):** where the content of a file
|
||||
mounted into the container is kept along with the container
|
||||
configuration in the device's `startup-config`
|
||||
|
||||
Podman ensures (using tmpfs) all containers have writable directories
|
||||
for certain critical file system paths: `/dev`, `/dev/shm`, `/run`,
|
||||
@@ -127,24 +129,30 @@ Classic Hello World:
|
||||
Hello from Docker!
|
||||
This message shows that your installation appears to be working correctly.
|
||||
|
||||
Persistent web server using nginx, sharing the host's network:
|
||||
A web server with [nginx][], using standard docker bridge. Podman will
|
||||
automatically create a VETH pair for us, connecting the container to the
|
||||
`docker0` bridge:
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config> edit container web
|
||||
admin@example:/config/container/web> set image docker://nginx:alpine
|
||||
admin@example:/config/container/web> set publish 80:80
|
||||
admin@example:/config/container/web> set network host
|
||||
admin@example:/config/container/web> leave
|
||||
admin@example:/config/> edit interface docker0
|
||||
admin@example:/config/interface/docker0/> set container-network
|
||||
admin@example:/config/interface/docker0/> end
|
||||
admin@example:/config/> edit container web
|
||||
admin@example:/config/container/web/> set image docker://nginx:alpine
|
||||
admin@example:/config/container/web/> set network publish 8080:80
|
||||
admin@example:/config/container/web/> set network interface docker0
|
||||
admin@example:/config/container/web/> set volume cache target /var/cache
|
||||
admin@example:/config/container/web/> leave
|
||||
admin@example:/> show container
|
||||
|
||||
Exit to the shell and verify the service with curl, or try to attach
|
||||
to your device's IP address using your browser:
|
||||
|
||||
admin@example:~$ curl http://localhost
|
||||
admin@example:~$ curl http://localhost:8080
|
||||
|
||||
or connect to port 80 of your running Infix system with a browser. See
|
||||
the following sections for how to add more interfaces and manage your
|
||||
container at runtime.
|
||||
or connect to port 8080 of your running Infix system with a browser.
|
||||
See the following sections for how to add more interfaces and manage
|
||||
your container at runtime.
|
||||
|
||||
|
||||
Container Images
|
||||
@@ -456,11 +464,11 @@ in a `bridge`. Below an example of a system container calls `set
|
||||
network interface docker0`, here we show how to set options for that
|
||||
network:
|
||||
|
||||
admin@example:/config/container/ntpd/> edit network docker0
|
||||
admin@example:/config/container/ntpd/network/docker0/>
|
||||
admin@example:/config/container/ntpd/network/docker0/> set option
|
||||
admin@example:/config/container/ntpd/> edit network interface docker0
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/>
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option
|
||||
<string> Options for masquerading container bridges.
|
||||
admin@example:/config/container/ntpd/network/docker0/> help option
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> help option
|
||||
NAME
|
||||
option <string>
|
||||
|
||||
@@ -471,9 +479,9 @@ network:
|
||||
mac=00:01:02:c0:ff:ee -- set fixed MAC address in container
|
||||
interface_name=foo0 -- set interface name inside container
|
||||
|
||||
admin@example:/config/container/ntpd/network/docker0/> set option ip=172.17.0.2
|
||||
admin@example:/config/container/ntpd/network/docker0/> set option interface_name=wan
|
||||
admin@example:/config/container/ntpd/network/docker0/> leave
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option ip=172.17.0.2
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> set option interface_name=wan
|
||||
admin@example:/config/container/ntpd/network/interface/docker0/> leave
|
||||
|
||||
|
||||
### Container Host Interface
|
||||
@@ -903,4 +911,5 @@ Container Image](#upgrading-a-container-image) (above).
|
||||
[14]: https://github.com/kernelkit/curiOS/
|
||||
[15]: https://github.com/kernelkit/curiOS/blob/2e4748f65e356b2c117f586cd9420d7ba66f79d5/board/system/rootfs/etc/inittab
|
||||
[tini]: https://github.com/krallin/tini
|
||||
[nginx]: https://hub.docker.com/_/nginx
|
||||
[podman]: https://podman.io
|
||||
|
||||
@@ -164,6 +164,59 @@ Now you can rebuild `confd`, just as described above, and restart Infix:
|
||||
make confd-rebuild all run
|
||||
|
||||
|
||||
### `statd`
|
||||
|
||||
The Infix status daemon, `src/statd`, is responsible for populating the
|
||||
sysrepo `operational` datastore. Like `confd`, it uses XPath subscriptions,
|
||||
but unlike `confd`, it relies entirely on `yanger`, a Python script that
|
||||
gathers data from local linux services and feeds it into sysrepo.
|
||||
|
||||
To apply changes, rebuild the image:
|
||||
|
||||
make python-statd-rebuild statd-rebuild all
|
||||
|
||||
Rebuilding the image and testing on target for every change during
|
||||
development process can be tedious. Instead, `yanger` allows remote
|
||||
execution, running the script directly on the host system (test
|
||||
container):
|
||||
|
||||
infamy0:test # ../src/statd/python/yanger/yanger -x "../utils/ixll -A ssh d3a" ieee802-dot1ab-lldp
|
||||
|
||||
`ixll` is a utility script that lets you run network commands using an
|
||||
**interface name** instead of a hostname. It makes operations like
|
||||
`ssh`, `scp`, and network discovery easier.
|
||||
|
||||
Normally, `yanger` runs commands **locally** to retrieve data
|
||||
(e.g., `lldpcli` when handling `ieee802-dot1ab-lldp`). However, when
|
||||
executed with `-x "../utils/ixll -A ssh d3a"` it redirects these
|
||||
commands to a remote system connected to the local `d3a` interface via
|
||||
SSH. This setup is used for running `yanger` in an
|
||||
[interactive test environment](testing.md#interactive-usage). The yanger
|
||||
script runs on the `host` system, but key commands are executed on the
|
||||
`target` system.
|
||||
|
||||
For debugging or testing, you can capture system command output and
|
||||
replay it later without needing a live system.
|
||||
|
||||
To capture:
|
||||
|
||||
infamy0:test # ../src/statd/python/yanger/yanger -c /tmp/capture ieee802-dot1ab-lldp
|
||||
|
||||
To replay:
|
||||
|
||||
infamy0:test # ../src/statd/python/yanger/yanger -r /tmp/capture ieee802-dot1ab-lldp
|
||||
|
||||
This is especially useful when working in isolated environments or debugging
|
||||
issues without direct access to the DUT.
|
||||
|
||||
### Agree on YANG Model
|
||||
|
||||
When making changes to the `confd` and `statd` services, you will often need to update
|
||||
the YANG models. If you are adding a new YANG module, it's best to follow the
|
||||
structure of an existing one. However, before making any changes, **always discuss
|
||||
them with the Infix core team**. This helps avoid issues later in development and
|
||||
makes pull request reviews smoother.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
@@ -175,6 +228,11 @@ The Infix automated test suite is built around Qemu and [Qeneth][2], see:
|
||||
* [Testing](testing.md)
|
||||
* [Docker Image](../test/docker/README.md)
|
||||
|
||||
With any new feature added to Infix, it is essential to include a
|
||||
relevant test case. See the
|
||||
[Test Development](testing.md#test-development) section for guidance
|
||||
on adding test cases.
|
||||
|
||||
|
||||
Reviewing
|
||||
---------
|
||||
|
||||
+17
-8
@@ -6,13 +6,7 @@ This column contains the mapping between YANG and Linux / Ethtool counters.
|
||||
┌─────────────────────────────────┬──────────────────────────────────┐
|
||||
│ YANG │ Linux / Ethtool │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-frames │ FramesTransmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-multicast-frames │ MulticastFramesXmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-broadcast-frames │ BroadcastFramesXmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-total-frames │ FramesReceivedOK, │
|
||||
│ in-total-octets │ FramesReceivedOK, │
|
||||
│ │ FrameCheckSequenceErrors │
|
||||
│ │ FramesLostDueToIntMACRcvError │
|
||||
│ │ AlignmentErrors │
|
||||
@@ -25,8 +19,23 @@ This column contains the mapping between YANG and Linux / Ethtool counters.
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-broadcast-frames │ BroadcastFramesReceivedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-error-fcs-frames │ FrameCheckSequenceErrors │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-error-undersize-frames │ undersize_pkts │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-error-fcs-frames │ FrameCheckSequenceErrors │
|
||||
| in-error-oversize-frames | etherStatsJabbers, |
|
||||
| | etherStatsOversizePkts |
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ in-error-mac-internal-frames │ FramesLostDueToIntMACRcvError │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-frames │ FramesTransmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-multicast-frames │ MulticastFramesXmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ out-broadcast-frames │ BroadcastFramesXmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ infix-eth:out-good-octets │ OctetsTransmittedOK │
|
||||
├─────────────────────────────────┼──────────────────────────────────┤
|
||||
│ infix-eth:in-good-octets │ OctetsReceivedOK │
|
||||
└─────────────────────────────────┴──────────────────────────────────┘
|
||||
```
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 368 KiB |
+1
-1
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 281 KiB After Width: | Height: | Size: 280 KiB |
+288
-24
@@ -48,7 +48,7 @@ other traffic would be bridged as usual.
|
||||
| bridge | infix-if-bridge | SW implementation of an IEEE 802.1Q bridge |
|
||||
| ip | ietf-ip, infix-ip | IP address to the subordinate interface |
|
||||
| vlan | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
|
||||
| lag[^1] | infix-if-lag | Bond multiple interfaces into one, creating a link aggregate |
|
||||
| lag | infix-if-lag | Link aggregation, static and IEEE 802.3ad (LACP) |
|
||||
| lo | ietf-interfaces | Software loopback interface |
|
||||
| eth | ieee802-ethernet-interface | Physical Ethernet device/port. |
|
||||
| | infix-ethernet-interface | |
|
||||
@@ -430,6 +430,265 @@ admin@example:/config/interface/br0/bridge/> set ieee-group-forward lldp
|
||||
admin@example:/config/interface/br0/bridge/>
|
||||
```
|
||||
|
||||
|
||||
### Link Aggregation
|
||||
|
||||
A link aggregate, or *lag*, allows multiple physical interfaces to be
|
||||
combined into a single logical interface, providing increased bandwidth
|
||||
(in some cases) and redundancy (primarily). Two modes of qualifying lag
|
||||
member ports are available:
|
||||
|
||||
1. **static**: Active members selected based on link status (carrier)
|
||||
2. **lacp:** IEEE 802.3ad Link Aggregation Control Protocol
|
||||
|
||||
In LACP mode, LACPDUs are exchanged by the link partners to qualify each
|
||||
lag member, while in static mode only carrier is used. This additional
|
||||
exchange in LACP ensures traffic can be forwarded in both directions.
|
||||
|
||||
Traffic distribution, for both modes, across the active lag member ports
|
||||
is determined by the hash policy[^1]. It uses an XOR of the source,
|
||||
destination MAC addresses and the EtherType field. This, IEEE
|
||||
802.3ad-compliant, algorithm will place all traffic to a particular
|
||||
network peer on the same link. Meaning there is no increased bandwidth
|
||||
for communication between two specific devices.
|
||||
|
||||
> [!TIP]
|
||||
> Similar to other interface types, naming your interface `lagN`, where
|
||||
> `N` is a number, allows the CLI to automatically infer the interface
|
||||
> type as LAG.
|
||||
|
||||
|
||||
#### Basic Configuration
|
||||
|
||||
Creating a link aggregate interface and adding member ports:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface lag0
|
||||
admin@example:/config/interface/lag0/> set lag mode static
|
||||
admin@example:/config/interface/lag0/> end
|
||||
admin@example:/config/> set interface eth7 lag-port lag lag0
|
||||
admin@example:/config/> set interface eth8 lag-port lag lag0
|
||||
admin@example:/config/> leave
|
||||
```
|
||||
|
||||
A static lag responds only to link (carrier) changes of member ports.
|
||||
E.g., in this example egressing traffic is continuously distributed over
|
||||
the two links until link down on one link is detected, triggering all
|
||||
traffic to be steered to the sole remaining link.
|
||||
|
||||
|
||||
#### LACP Configuration
|
||||
|
||||
LACP mode provides dynamic negotiation of the link aggregate. Key
|
||||
settings include:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface lag0
|
||||
admin@example:/config/interface/lag0/> set lag mode lacp
|
||||
admin@example:/config/interface/lag0/> set lag lacp mode passive
|
||||
admin@example:/config/interface/lag0/> set lag lacp rate fast
|
||||
admin@example:/config/interface/lag0/> set lag lacp system-priority 100
|
||||
```
|
||||
|
||||
LACP mode supports two operational modes:
|
||||
|
||||
- **active:** Initiates negotiation by sending LACPDUs (default)
|
||||
- **passive:** Waits for peer to initiate negotiation
|
||||
|
||||
> [!NOTE]
|
||||
> At least one end of the link must be in active mode for negotiation to occur.
|
||||
|
||||
The LACP rate setting controls protocol timing:
|
||||
|
||||
- **slow:** LACPDUs sent every 30 seconds, with 90 second timeout (default)
|
||||
- **fast:** LACPDUs sent every second, with 3 second timeout
|
||||
|
||||
|
||||
#### Link Flapping
|
||||
|
||||
To protect against link flapping, debounce timers can be configured to
|
||||
delay link qualification. Usually only the `up` delay is needed:
|
||||
|
||||
```
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/> edit debounce
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> set up 500
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> set down 200
|
||||
```
|
||||
|
||||
#### Operational Status, Overview
|
||||
|
||||
Like other interfaces, link aggregates are also available in the general
|
||||
interfaces overview in the CLI admin-exec context. Here is the above
|
||||
static mode aggregate:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP static: balance-xor, hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE
|
||||
└ eth8 lag ACTIVE
|
||||
```
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
```
|
||||
|
||||
|
||||
#### Operational Status, Detail
|
||||
|
||||
In addition to basic status shown in the interface overview, detailed
|
||||
LAG status can be inspected:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces name lag0
|
||||
name : lag0
|
||||
index : 25
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : static
|
||||
lag type : balance-xor
|
||||
lag hash : layer2
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 0
|
||||
out-octets : 2142
|
||||
```
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces name lag0
|
||||
name : lag0
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : lacp
|
||||
lag hash : layer2
|
||||
lacp mode : active
|
||||
lacp rate : fast (1s)
|
||||
lacp aggregate id : 1
|
||||
lacp system priority: 65535
|
||||
lacp actor key : 9
|
||||
lacp partner key : 9
|
||||
lacp partner mac : 00:a0:85:00:03:00
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 100892
|
||||
out-octets : 111776
|
||||
```
|
||||
|
||||
Member ports provide additional status information:
|
||||
|
||||
- Link failure counter: number of detected link failures
|
||||
- LACP state flags: various states of LACP negotiation:
|
||||
- `active`: port is actively sending LACPDUs
|
||||
- `short_timeout`: using fast rate (1s) vs. slow rate (30s)
|
||||
- `aggregating`: port is allowed to aggregate in this LAG
|
||||
- `in_sync`: port is synchronized with partner
|
||||
- `collecting`: port is allowed to receive traffic
|
||||
- `distributing`: port is allowed to send traffic
|
||||
- `defaulted`: using default partner info (partner not responding)
|
||||
- `expired`: partner info has expired (no LACPDUs received)
|
||||
- Aggregator ID: unique identifier for this LAG group
|
||||
- Actor state: LACP state flags for this port (local)
|
||||
- Partner state: LACP state flags from the remote port
|
||||
|
||||
Example member port status:
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces name eth7
|
||||
name : eth7
|
||||
index : 8
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag member : lag0
|
||||
lag member state : active
|
||||
lacp aggregate id : 1
|
||||
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
link failure count : 0
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 473244
|
||||
out-octets : 499037
|
||||
```
|
||||
|
||||
|
||||
#### Example: Switch Uplink with LACP
|
||||
|
||||
LACP mode provides the most robust operation, automatically negotiating
|
||||
the link aggregate and detecting configuration mismatches.
|
||||
|
||||
A common use case is connecting a switch to an upstream device:
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface lag0
|
||||
admin@example:/config/interface/lag0/> set lag mode lacp
|
||||
```
|
||||
|
||||
Enable fast LACP for quicker fail-over:
|
||||
|
||||
```
|
||||
admin@example:/config/interface/lag0/> set lag lacp rate fast
|
||||
```
|
||||
|
||||
Add uplink ports
|
||||
|
||||
```
|
||||
admin@example:/config/interface/lag0/> end
|
||||
admin@example:/config/> set interface eth7 lag-port lag lag0
|
||||
admin@example:/config/> set interface eth8 lag-port lag lag0
|
||||
```
|
||||
|
||||
Enable protection against "link flapping".
|
||||
|
||||
```
|
||||
admin@example:/config/interface/lag0/> edit lag link-monitor
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/> edit debounce
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> set up 500
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> set down 200
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> top
|
||||
```
|
||||
|
||||
Add to bridge for switching
|
||||
|
||||
```
|
||||
admin@example:/config/interface/lag0/lag/link-monitor/debounce/> end
|
||||
admin@example:/config/> set interface lag0 bridge-port bridge br0
|
||||
admin@example:/config/> leave
|
||||
```
|
||||
|
||||
|
||||
### VLAN Interfaces
|
||||
|
||||
Creating a VLAN can be done in many ways. This section assumes VLAN
|
||||
@@ -800,7 +1059,7 @@ The resulting address (10.1.2.100/24) is of type *dhcp*.
|
||||
The (only) way to disable IPv6 link-local addresses is by disabling IPv6
|
||||
on the interface.
|
||||
|
||||
```(disabling
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface eth0 ipv6
|
||||
admin@example:/config/interface/eth0/ipv6/> set enabled false
|
||||
@@ -914,33 +1173,38 @@ have changed type to *random*.
|
||||
To be able to route (static or dynamic) on the interface it is
|
||||
required to enable forwarding. This setting controls if packets
|
||||
received on this interface can be forwarded.
|
||||
```
|
||||
admin@example:/config/> edit interface eth0
|
||||
admin@example:/config/interface/eth0/> set ipv4 forwarding
|
||||
admin@example:/config/interface/eth0/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface eth0
|
||||
admin@example:/config/interface/eth0/> set ipv4 forwarding
|
||||
admin@example:/config/interface/eth0/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
|
||||
|
||||
### IPv6 forwarding
|
||||
|
||||
This flag behaves totally different than for IPv4. For IPv6 the
|
||||
ability to route between interfaces is always enabled, instead this
|
||||
flag controls if the interface will be in host/router mode.
|
||||
Due to how the Linux kernel manages IPv6 forwarding, we can not fully
|
||||
control it per interface via this setting like how IPv4 works. Instead,
|
||||
IPv6 forwarding is globally enabled when at least one interface enable
|
||||
forwarding, otherwise it is disabled.
|
||||
|
||||
| **Feature** | **Forward enabled** | **Forward disabled** |
|
||||
|:-----------------------------------------|:--------------------|:---------------------|
|
||||
| IsRouter set in Neighbour Advertisements | Yes | No |
|
||||
| Transmit Router Solicitations | No | Yes |
|
||||
| Router Advertisements are ignored | No | Yes |
|
||||
| Accept Redirects | No | Yes |
|
||||
The following table shows the system IPv6 features that the `forwarding`
|
||||
setting control when it is *Enabled* or *Disabled:
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface eth0
|
||||
admin@example:/config/interface/eth0/> set ipv6 forwarding
|
||||
admin@example:/config/interface/eth0/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
| **IPv6 Feature** | **Enabled** | **Disabled** |
|
||||
|:-----------------------------------------|:------------|:-------------|
|
||||
| IsRouter set in Neighbour Advertisements | Yes | No |
|
||||
| Transmit Router Solicitations | No | Yes |
|
||||
| Router Advertisements are ignored | Yes | Yes |
|
||||
| Accept Redirects | No | Yes |
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interface eth0
|
||||
admin@example:/config/interface/eth0/> set ipv6 forwarding
|
||||
admin@example:/config/interface/eth0/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
|
||||
|
||||
## Routing support
|
||||
@@ -1228,7 +1492,7 @@ currently supported, namely `ipv4` and `ipv6`.
|
||||
[4]: https://www.rfc-editor.org/rfc/rfc3442
|
||||
[0]: https://frrouting.org/
|
||||
|
||||
[^1]: Please note, link aggregates are not yet supported.
|
||||
[^1]: `(source MAC XOR destination MAC XOR EtherType) MODULO num_links`
|
||||
[^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.
|
||||
|
||||
+56
-3
@@ -853,14 +853,18 @@ models for details.
|
||||
### Factory Reset
|
||||
|
||||
```
|
||||
~$ curl -kX POST -H "Content-Type: application/yang-data+json" https://example.local/restconf/operations/ietf-factory-default:factory-reset -u admin:admin
|
||||
~$ curl -kX POST -u admin:admin \
|
||||
-H "Content-Type: application/yang-data+json" \
|
||||
https://example.local/restconf/operations/ietf-factory-default:factory-reset
|
||||
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
|
||||
```
|
||||
|
||||
### System Reboot
|
||||
|
||||
```
|
||||
~$ curl -kX POST -H "Content-Type: application/yang-data+json" https://example.local/restconf/operations/ietf-system:system-restart -u admin:admin
|
||||
~$ curl -kX POST -u admin:admin \
|
||||
-H "Content-Type: application/yang-data+json" \
|
||||
https://example.local/restconf/operations/ietf-system:system-restart
|
||||
```
|
||||
|
||||
### Set Date and Time
|
||||
@@ -868,7 +872,11 @@ curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while r
|
||||
Here's an example of an RPC that takes input/argument:
|
||||
|
||||
```
|
||||
~$ curl -kX POST -H "Content-Type: application/yang-data+json" https://example.local/restconf/operations/ietf-system:set-current-datetime -u admin:admin -d '{"ietf-system:input": {"current-datetime": "2024-04-17T13:48:02-01:00"}}'
|
||||
~$ curl -kX POST -u admin:admin \
|
||||
-H "Content-Type: application/yang-data+json" \
|
||||
-d '{"ietf-system:input": {"current-datetime": "2024-04-17T13:48:02-01:00"}}' \
|
||||
https://example.local/restconf/operations/ietf-system:set-current-datetime
|
||||
|
||||
```
|
||||
|
||||
You can verify that the changes took by a remote SSH command:
|
||||
@@ -879,6 +887,51 @@ Wed Apr 17 14:48:12 UTC 2024
|
||||
~$
|
||||
```
|
||||
|
||||
### Read Hostname
|
||||
|
||||
Example of fetching JSON configuration data to stdout:
|
||||
|
||||
```
|
||||
~$ curl -kX GET -u admin:admin \
|
||||
-H 'Accept: application/yang-data+json' \
|
||||
https://example.local/restconf/data/ietf-system:system/hostname
|
||||
{
|
||||
"ietf-system:system": {
|
||||
"hostname": "foo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Set Hostname
|
||||
|
||||
Example of inline JSON data:
|
||||
|
||||
```
|
||||
~$ curl -kX PATCH -u admin:admin \
|
||||
-H 'Content-Type: application/yang-data+json' \
|
||||
-d '{"ietf-system:system":{"hostname":"bar"}}' \
|
||||
https://example.local/restconf/data/ietf-system:system
|
||||
```
|
||||
|
||||
### Copy Running to Startup
|
||||
|
||||
No copy command available yet to copy between datastores, and the
|
||||
Rousette back-end also does not support "write-through" to the
|
||||
startup datastore.
|
||||
|
||||
To save running-config to startup-config, use the following example to
|
||||
fetch running to a local file and then update startup with it:
|
||||
|
||||
```
|
||||
~$ curl -kX GET -u admin:admin -o running-config.json \
|
||||
-H 'Accept: application/yang-data+json' \
|
||||
https://example.local/restconf/ds/ietf-datastores:running
|
||||
|
||||
~$ curl -kX PUT -u admin:admin -d @running-config.json \
|
||||
-H 'Content-Type: application/yang-data+json' \
|
||||
https://example.local/restconf/ds/ietf-datastores:startup
|
||||
```
|
||||
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
|
||||
+8
-16
@@ -243,23 +243,15 @@ spanning tree matches the expected one.
|
||||
|
||||
Integration to Infix
|
||||
--------------------
|
||||
To successfully run all Infix tests, the image must be built in
|
||||
'test-mode'. This can be achieved by setting the DISK_IMAGE_TEST_MODE
|
||||
parameter to true. Although this is the default setting, it’s advisable
|
||||
to verify it by running:
|
||||
When the test environment is started with Qeneth, it doesn't use the
|
||||
base image directly. Instead, it creates a copy and inserts a `test-mode`
|
||||
flag into it. During the bootstrap phase, the system checks for the
|
||||
presence of the test-mode flag (file).
|
||||
|
||||
$ make menuconfig
|
||||
(External Options --> -*- Disk image --> [*] Enable Test Mode)
|
||||
|
||||
Building an image in 'test-mode' results in the creation of a 'test-mode'
|
||||
file within the auxiliary (aux) partition of the Infix disk image
|
||||
(/mnt/aux/test-mode).
|
||||
|
||||
During the bootstrap phase, the system checks for the presence of this
|
||||
test-mode flag (file). If the flag exists, a 'test-config.cfg' file is
|
||||
generated. In the following step, the system loads the 'test-config'
|
||||
instead of the standard startup-config (or factory-config). This
|
||||
configuration is simple and safe, equivalent to the one used in 'Secure Mode'
|
||||
If the flag exists, a 'test-config.cfg' file is generated. In the
|
||||
following step, the system loads the 'test-config' instead of the
|
||||
standard `startup-config` (or `factory-config`). This configuration
|
||||
is simple and safe, equivalent to the one used in 'Secure Mode'
|
||||
(also known as 'failure-config').
|
||||
|
||||
Additionally, the configuration enables extra RPCs related to system
|
||||
|
||||
+51
-12
@@ -25,17 +25,6 @@ for `x86_64`:
|
||||
$ make
|
||||
$ make test
|
||||
|
||||
It is important to mention that Infix build system by default creates
|
||||
an image in 'test-mode'. The mode is set by DISK_IMAGE_TEST_MODE
|
||||
parameter (default=true). To generate a standard image set the
|
||||
DISK_IMAGE_TEST_MODE to 'false'. However, only the test mode ensures
|
||||
that all Infix tests are executed properly. Prior to the set of commands
|
||||
above, it is always good to check that DISK_IMAGE_TEST_MODE is properly
|
||||
set by running:
|
||||
|
||||
$ make menuconfig
|
||||
(External Options --> -*- Disk image --> [*] Enable Test Mode)
|
||||
|
||||
### Physical Devices
|
||||
|
||||
To run the tests on a preexisting topology from the host's network
|
||||
@@ -99,8 +88,11 @@ arguments:
|
||||
To run a suite of tests, e.g., only the DHCP client tests, pass the
|
||||
suite as an argument to [9PM][]:
|
||||
|
||||
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/all.yaml
|
||||
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/infix_dhcp.yaml
|
||||
|
||||
To run the suite of all tests:
|
||||
|
||||
11:42:53 infamy0:test # ./9pm/9pm.py case/all.yaml
|
||||
|
||||
### Connecting to Infamy
|
||||
|
||||
@@ -315,5 +307,52 @@ The test specifaction can be genererated with:
|
||||
|
||||
$ make test-spec
|
||||
|
||||
### Test Development
|
||||
|
||||
For adding a new test to the automated regression test suite, it's best
|
||||
to start by reviewing an existing test case.
|
||||
|
||||
All tests are located in the `infix/test/case` repository and are
|
||||
grouped by the features they verify. For example,
|
||||
`infix/test/case/infix_services` contains tests for various Infix
|
||||
services, such as LLDP and mDNS.
|
||||
|
||||
While test grouping is flexible, each test should be placed in a
|
||||
logically relevant category.
|
||||
|
||||
When creating a new test group, add it to `infix/test/case/all.yaml`,
|
||||
to enable it to run as a
|
||||
[subset of the test suite](#running-subsets-of-tests):
|
||||
|
||||
```
|
||||
- name: infix-services
|
||||
suite: infix_services/infix_services.yaml
|
||||
```
|
||||
|
||||
A new test (e.g., lldp_enable_disable) should be added to the
|
||||
corresponding test group .yaml file, such as
|
||||
`infix/test/cases/infix_services.yaml`:
|
||||
|
||||
```
|
||||
- name: lldp_enable_disable
|
||||
case: lldp_enable_disable/test.py
|
||||
```
|
||||
|
||||
It is necessary to include the test in
|
||||
`infix/test/case/infix_services/Readme.adoc` to ensure proper test
|
||||
specification generation:
|
||||
|
||||
```
|
||||
include::lldp_enable_disable/Readme.adoc[]
|
||||
```
|
||||
|
||||
Each test case should have its own directory under,
|
||||
`infix/test/case/infix_services`, containing:
|
||||
- `test.py` - the test script
|
||||
- `topology.dot` - the logical topology definition.
|
||||
|
||||
When the [test specification](#test-specification) is generated,
|
||||
`topology.svg` and `Readme.adoc` should also be created.
|
||||
|
||||
[9PM]: https://github.com/rical/9pm
|
||||
[Qeneth]: https://github.com/wkz/qeneth
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
menu "Boards"
|
||||
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/board/alder-alder/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/board/freescale-imx8mp-evk/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/board/marvell-cn9130-crb/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/board/marvell-espressobin/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/board/microchip-sparx5-pcb135/Config.in"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
config BR2_PACKAGE_FREESCALE_IMX8MP_EVK
|
||||
bool "NXP i.MX8MP EVK"
|
||||
depends on BR2_aarch64
|
||||
help
|
||||
NXP i.MX8MP EVK
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
define FREESCALE_IMX8MP_EVK_LINUX_CONFIG_FIXUPS
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_NXP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_MXC)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_FEC)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_STMICRO)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_STMMAC_ETH)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_DWMAC_IMX8)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_IMX)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_IMX_CONSOLE)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_I2C_IMX)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SPI_IMX)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_IMX8MP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_GPIO_MXC)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_IMX2_WDT)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_OF_ESDHC)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_ESDHC_IMX)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_CLK_IMX8MP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NVMEM_IMX_OCOTP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX8MP)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
|
||||
endef
|
||||
|
||||
$(eval $(ix-board))
|
||||
$(eval $(generic-package))
|
||||
@@ -1,3 +1,9 @@
|
||||
################################################################################
|
||||
#
|
||||
# confd-test-mode
|
||||
#
|
||||
################################################################################
|
||||
|
||||
CONFD_TEST_MODE_VERSION = 1.0
|
||||
CONFD_TEST_MODE_SITE_METHOD = local
|
||||
CONFD_TEST_MODE_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/test-mode
|
||||
@@ -16,7 +22,8 @@ COMMON_SYSREPO_ENV = \
|
||||
|
||||
define CONFD_TEST_MODE_INSTALL_YANG_MODULES
|
||||
$(COMMON_SYSREPO_ENV) \
|
||||
SEARCH_PATH="$(TARGET_DIR)/usr/share/yang/modules/test-mode/" $(BR2_EXTERNAL_INFIX_PATH)/utils/sysrepo-load-modules.sh $(@D)/yang/test-mode.inc
|
||||
SEARCH_PATH="$(TARGET_DIR)/usr/share/yang/modules/test-mode/" \
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/test-mode.inc
|
||||
endef
|
||||
define CONFD_TEST_MODE_PERMISSIONS
|
||||
/etc/sysrepo/data/ r 660 root wheel - - - - -
|
||||
|
||||
@@ -17,17 +17,15 @@ run name:startup log:prio:user.notice norestart <pid/confd> env:/etc/default/con
|
||||
-- Loading startup-config
|
||||
|
||||
# Run if loading startup-config fails for some reason
|
||||
run name:failure log:prio:user.critical norestart <pid/confd> env:/etc/default/confd if:<run/startup/failure> \
|
||||
[S] /usr/libexec/confd/load -t $CONFD_TIMEOUT failure-config \
|
||||
run name:failure log:prio:user.critical norestart env:/etc/default/confd \
|
||||
if:<run/startup/failure> \
|
||||
[S] <pid/confd> /usr/libexec/confd/load -t $CONFD_TIMEOUT failure-config \
|
||||
-- Loading failure-config
|
||||
|
||||
run name:error :2 log:console norestart if:<run/failure/failure> \
|
||||
run name:error :2 log:console norestart \
|
||||
if:<run/failure/failure> \
|
||||
[S] /usr/libexec/confd/error --
|
||||
|
||||
service name:netopeer notify:none log <pid/confd> env:/etc/default/confd \
|
||||
[12345] netopeer2-server -F -t $CONFD_TIMEOUT -v 1 \
|
||||
service name:netopeer notify:none log env:/etc/default/confd \
|
||||
[12345] <pid/confd> netopeer2-server -F -t $CONFD_TIMEOUT -v 1 \
|
||||
-- NETCONF server
|
||||
|
||||
# Create initial /etc/resolv.conf after successful bootstrap
|
||||
task name:resolv :conf norestart <pid/dnsmasq> if:<run/startup/success> \
|
||||
[S] resolvconf -u -- Update DNS configuration
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
CONFD_VERSION = 1.4
|
||||
CONFD_VERSION = 1.5
|
||||
CONFD_SITE_METHOD = local
|
||||
CONFD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/confd
|
||||
CONFD_LICENSE = BSD-3-Clause
|
||||
@@ -26,8 +26,10 @@ CONFD_CONF_OPTS += --disable-containers
|
||||
endif
|
||||
|
||||
define CONFD_INSTALL_EXTRA
|
||||
cp $(CONFD_PKGDIR)/confd.conf $(FINIT_D)/available/
|
||||
ln -sf ../available/confd.conf $(FINIT_D)/enabled/confd.conf
|
||||
for fn in confd.conf resolvconf.conf; do \
|
||||
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
|
||||
ln -sf ../available/$$fn $(FINIT_D)/enabled/$$fn; \
|
||||
done
|
||||
cp $(CONFD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/confd.conf
|
||||
mkdir -p $(TARGET_DIR)/etc/avahi/services
|
||||
cp $(CONFD_PKGDIR)/avahi.service $(TARGET_DIR)/etc/avahi/services/netconf.service
|
||||
@@ -41,13 +43,13 @@ COMMON_SYSREPO_ENV = \
|
||||
|
||||
define CONFD_INSTALL_YANG_MODULES
|
||||
$(COMMON_SYSREPO_ENV) \
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/utils/sysrepo-load-modules.sh $(@D)/yang/confd.inc
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/confd.inc
|
||||
endef
|
||||
|
||||
ifeq ($(BR2_PACKAGE_PODMAN),y)
|
||||
define CONFD_INSTALL_YANG_MODULES_CONTAINERS
|
||||
$(COMMON_SYSREPO_ENV) \
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/utils/sysrepo-load-modules.sh $(@D)/yang/containers.inc
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/containers.inc
|
||||
endef
|
||||
endif
|
||||
|
||||
@@ -63,9 +65,7 @@ endef
|
||||
CONFD_PRE_INSTALL_TARGET_HOOKS += CONFD_CLEANUP
|
||||
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_EXTRA
|
||||
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES
|
||||
ifeq ($(BR2_PACKAGE_PODMAN),y)
|
||||
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_CONTAINERS
|
||||
endif
|
||||
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_CLEANUP
|
||||
|
||||
$(eval $(autotools-package))
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Create initial /etc/resolv.conf after successful bootstrap, regardless
|
||||
# of startup-config or failure-config. Condition set by confd.
|
||||
task [S12345] <usr/bootstrap> resolvconf -u -- Update DNS configuration
|
||||
@@ -1,67 +0,0 @@
|
||||
From 46ffa81f5c88ce95db011369d8bfb802313e4217 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 17 Oct 2024 14:23:24 +0200
|
||||
Subject: [PATCH 1/7] Only mark rdeps dirty if main service is nohup
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
This patch changes a behavior that's been default since Finit 4.0,
|
||||
introduced in 4d05bf9 with 4.0-rc2.
|
||||
|
||||
If service B depends on A and A needs to be reloaded, then B may be
|
||||
affected. If A is declared as NOHUP <!>, then A will be stopped and
|
||||
restarted, during which time the condition it provides is removed,
|
||||
and B will also be stopped.
|
||||
|
||||
However, and as of this patch, if A is declared supporting HUP, then the
|
||||
condition A provides will only go into flux, during which time B will be
|
||||
SIGSTOPed instead of needing to be reloaded.
|
||||
|
||||
Fix #415
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
src/service.c | 8 ++++++++
|
||||
src/svc.h | 1 +
|
||||
2 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/src/service.c b/src/service.c
|
||||
index 61be85c..b995ff4 100644
|
||||
--- a/src/service.c
|
||||
+++ b/src/service.c
|
||||
@@ -2001,6 +2001,10 @@ static void svc_mark_affected(char *cond)
|
||||
* Called on conf_reload() to update service reverse dependencies.
|
||||
* E.g., if ospfd depends on zebra and the zebra Finit conf has
|
||||
* changed, we need to mark the ospfd Finit conf as changed too.
|
||||
+ *
|
||||
+ * However, a daemon that depends on syslogd (sysklogd project), need
|
||||
+ * not be reloeaded (SIGHUP'ed or stop/started) because syslogd support
|
||||
+ * reloading its configuration file on SIGHUP.
|
||||
*/
|
||||
void service_update_rdeps(void)
|
||||
{
|
||||
@@ -2012,6 +2016,10 @@ void service_update_rdeps(void)
|
||||
if (!svc_is_changed(svc))
|
||||
continue;
|
||||
|
||||
+ /* Service supports reloading conf without stop/start */
|
||||
+ if (!svc_is_nohup(svc))
|
||||
+ continue; /* Yup, no need to stop start rdeps */
|
||||
+
|
||||
svc_mark_affected(mkcond(svc, cond, sizeof(cond)));
|
||||
}
|
||||
}
|
||||
diff --git a/src/svc.h b/src/svc.h
|
||||
index d00ac14..e2f6bd8 100644
|
||||
--- a/src/svc.h
|
||||
+++ b/src/svc.h
|
||||
@@ -259,6 +259,7 @@ static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY
|
||||
static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);}
|
||||
static inline int svc_is_forking (svc_t *svc) { return svc && svc->forking; }
|
||||
static inline int svc_is_manual (svc_t *svc) { return svc && svc->manual; }
|
||||
+static inline int svc_is_nohup (svc_t *svc) { return svc && (0 == svc->sighup); }
|
||||
|
||||
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
||||
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
From 119e66a7e9c95283918639b51dd03a3d666955f8 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 28 Oct 2024 10:58:04 +0100
|
||||
Subject: [PATCH 2/7] Reset color attributes and clear screen when starting up
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Some boot loaders, like GRUB, leave background color artifacts from
|
||||
their boot menu. This patch resets the foreground and background
|
||||
color attributes, and then clears the screen, without clearing the
|
||||
scrollback buffer.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
src/helpers.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/helpers.c b/src/helpers.c
|
||||
index 8768de8..99c4557 100644
|
||||
--- a/src/helpers.c
|
||||
+++ b/src/helpers.c
|
||||
@@ -87,6 +87,9 @@ void console_init(void)
|
||||
/* Enable line wrap, if disabled previously, e.g., qemu */
|
||||
dprint(STDOUT_FILENO, "\033[?7h", 5);
|
||||
|
||||
+ /* Reset atttributes, background and foreground color */
|
||||
+ dprint(STDOUT_FILENO, "\033[49m\033[39m\e[2J", 14);
|
||||
+
|
||||
log_init();
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
From 0c0e880f3fdd38f7bbde618408378dc0a19ff005 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 3 Nov 2024 09:39:46 +0100
|
||||
Subject: [PATCH 3/7] plugins: refactor rtc.so
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Factor out time_set() and time_get() for readability and reuse.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
plugins/rtc.c | 116 +++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 68 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/plugins/rtc.c b/plugins/rtc.c
|
||||
index 238791f..9520c7d 100644
|
||||
--- a/plugins/rtc.c
|
||||
+++ b/plugins/rtc.c
|
||||
@@ -68,6 +68,60 @@ static void tz_restore(char *tz)
|
||||
tzset();
|
||||
}
|
||||
|
||||
+static int time_set(struct tm *tm)
|
||||
+{
|
||||
+ struct tm fallback = { 0 };
|
||||
+ struct timeval tv = { 0 };
|
||||
+ char tz[128];
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ tz_set(tz, sizeof(tz));
|
||||
+
|
||||
+ if (!tm) {
|
||||
+ logit(LOG_NOTICE, "Resetting system clock to kernel default, %s.", rtc_timestamp);
|
||||
+ tm = &fallback;
|
||||
+
|
||||
+ /* Attempt to set RTC to a sane value ... */
|
||||
+ tv.tv_sec = rtc_date_fallback;
|
||||
+ if (!gmtime_r(&tv.tv_sec, tm)) {
|
||||
+ rc = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tm->tm_isdst = -1; /* Use tzdata to figure it out, please. */
|
||||
+ tv.tv_sec = mktime(tm);
|
||||
+ if (tv.tv_sec == (time_t)-1 || tv.tv_sec < rtc_date_fallback) {
|
||||
+ errno = EINVAL;
|
||||
+ rc = 2;
|
||||
+ } else {
|
||||
+ if (settimeofday(&tv, NULL) == -1)
|
||||
+ rc = 1;
|
||||
+ }
|
||||
+out:
|
||||
+ tz_restore(tz);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int time_get(struct tm *tm)
|
||||
+{
|
||||
+ struct timeval tv = { 0 };
|
||||
+ char tz[128];
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ tz_set(tz, sizeof(tz));
|
||||
+
|
||||
+ rc = gettimeofday(&tv, NULL);
|
||||
+ if (rc < 0 || tv.tv_sec < rtc_date_fallback)
|
||||
+ rc = 2;
|
||||
+ else
|
||||
+ gmtime_r(&tv.tv_sec, tm);
|
||||
+
|
||||
+ tz_restore(tz);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static int rtc_open(void)
|
||||
{
|
||||
char *alt[] = {
|
||||
@@ -91,10 +145,8 @@ static int rtc_open(void)
|
||||
|
||||
static void rtc_save(void *arg)
|
||||
{
|
||||
- struct timeval tv = { 0 };
|
||||
struct tm tm = { 0 };
|
||||
int fd, rc = 0;
|
||||
- char tz[128];
|
||||
|
||||
if (rescue) {
|
||||
dbg("Skipping %s plugin in rescue mode.", __FILE__);
|
||||
@@ -105,38 +157,26 @@ static void rtc_save(void *arg)
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
- tz_set(tz, sizeof(tz));
|
||||
- rc = gettimeofday(&tv, NULL);
|
||||
- if (rc < 0 || tv.tv_sec < rtc_date_fallback) {
|
||||
+ if ((rc = time_get(&tm))) {
|
||||
print_desc(NULL, "System clock invalid, not saving to RTC");
|
||||
- invalid:
|
||||
- logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
|
||||
- rc = 2;
|
||||
- goto out;
|
||||
+ } else {
|
||||
+ print_desc(NULL, "Saving system clock (UTC) to RTC");
|
||||
+ rc = ioctl(fd, RTC_SET_TIME, &tm);
|
||||
}
|
||||
|
||||
- print_desc(NULL, "Saving system time (UTC) to RTC");
|
||||
-
|
||||
- gmtime_r(&tv.tv_sec, &tm);
|
||||
- if (ioctl(fd, RTC_SET_TIME, &tm) < 0) {
|
||||
- if (EINVAL == errno)
|
||||
- goto invalid;
|
||||
- rc = 1;
|
||||
- goto out;
|
||||
+ if (rc && errno == EINVAL) {
|
||||
+ logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
|
||||
+ rc = 2;
|
||||
}
|
||||
|
||||
-out:
|
||||
- tz_restore(tz);
|
||||
print(rc, NULL);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void rtc_restore(void *arg)
|
||||
{
|
||||
- struct timeval tv = { 0 };
|
||||
struct tm tm = { 0 };
|
||||
int fd, rc = 0;
|
||||
- char tz[128];
|
||||
|
||||
if (rescue) {
|
||||
dbg("Skipping %s plugin in rescue mode.", __FILE__);
|
||||
@@ -149,16 +189,19 @@ static void rtc_restore(void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
- tz_set(tz, sizeof(tz));
|
||||
- if (ioctl(fd, RTC_RD_TIME, &tm) < 0) {
|
||||
+ if ((rc = ioctl(fd, RTC_RD_TIME, &tm)) < 0) {
|
||||
char msg[120];
|
||||
|
||||
snprintf(msg, sizeof(msg), "Failed restoring system clock, %s",
|
||||
EINVAL == errno ? "RTC time is too old" :
|
||||
ENOENT == errno ? "RTC has no saved time" : "see log for details");
|
||||
print_desc(NULL, msg);
|
||||
+ } else {
|
||||
+ print_desc(NULL, "Restoring system clock (UTC) from RTC");
|
||||
+ rc = time_set(&tm);
|
||||
+ }
|
||||
|
||||
- invalid:
|
||||
+ if (rc) {
|
||||
logit(LOG_ERR, "Failed restoring system clock from RTC.");
|
||||
if (EINVAL == errno)
|
||||
logit(LOG_ERR, "RTC time is too old (before %s)", rtc_timestamp);
|
||||
@@ -167,33 +210,10 @@ static void rtc_restore(void *arg)
|
||||
else
|
||||
logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
|
||||
|
||||
- /* Been here already? */
|
||||
- if (rc)
|
||||
- goto out;
|
||||
-
|
||||
- /* Attempt to set RTC to a sane value ... */
|
||||
- tv.tv_sec = rtc_date_fallback;
|
||||
- if (!gmtime_r(&tv.tv_sec, &tm))
|
||||
- goto out;
|
||||
-
|
||||
- logit(LOG_NOTICE, "Resetting RTC to kernel default, %s.", rtc_timestamp);
|
||||
+ time_set(NULL);
|
||||
rc = 2;
|
||||
}
|
||||
|
||||
- if (!rc)
|
||||
- print_desc(NULL, "Restoring system clock (UTC) from RTC");
|
||||
- tm.tm_isdst = -1; /* Use tzdata to figure it out, please. */
|
||||
- tv.tv_sec = mktime(&tm);
|
||||
- if (tv.tv_sec == (time_t)-1 || tv.tv_sec < rtc_date_fallback) {
|
||||
- errno = EINVAL;
|
||||
- goto invalid;
|
||||
- }
|
||||
-
|
||||
- if (settimeofday(&tv, NULL) == -1)
|
||||
- rc = 1;
|
||||
-
|
||||
-out:
|
||||
- tz_restore(tz);
|
||||
print(rc, NULL);
|
||||
close(fd);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
From bc8118d515839dc598f437aa01f07a771646968d Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 3 Nov 2024 09:47:16 +0100
|
||||
Subject: [PATCH 4/7] Fix #418: support systems with a broken RTC
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
This patch introduces a new configure option --with-rtc-file=FILE. When
|
||||
enabled the RTC plugin detects missing RTC device and falls back to save
|
||||
and restore system time from a file instead. When --with-rtc-file is
|
||||
used without an argument the default file is /var/lib/misc/rtc, but the
|
||||
feature itself is disabled by default.
|
||||
|
||||
The usefulness of this feature may not be obvious at first, but some
|
||||
systems are equipped with an RTC that resets to a random date at power
|
||||
on. This can be really bad in the case the date is far in the future,
|
||||
because an NTP sync would then cause time skips backwards, which shows
|
||||
up in logs and causes a whole lot of pain in alarm systems.
|
||||
|
||||
The solution is to disable the RTC driver or device tree node, and when
|
||||
Finit starts up, the RTC plugin detects a the device node and instead
|
||||
restores time from the last save game. Meaning time will always only
|
||||
move forwards.
|
||||
|
||||
NOTE: when Finit is built --with-rtc-file we always save to disk, but
|
||||
only restore from the "save game" if restoring from RTC fails.
|
||||
If the system has no RTC we always restore from disk.
|
||||
|
||||
As an added bonus, this change also makes sure to periodically
|
||||
sync also the RTC with the system clock. Useful for systems
|
||||
that do not run an NTP client.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
configure.ac | 12 ++++++
|
||||
plugins/rtc.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 110 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 483457f..ae7cd23 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -180,6 +180,10 @@ AC_ARG_WITH(rtc-date,
|
||||
AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM", default "2000-01-01 00:00"]),
|
||||
[rtc_date=$withval], [rtc_date=no])
|
||||
|
||||
+AC_ARG_WITH(rtc-file,
|
||||
+ AS_HELP_STRING([--with-rtc-file=FILE], [If RTC is missing, save and restore system clock from this file, default: no]),
|
||||
+ [rtc_file=$withval], [rtc_file=no])
|
||||
+
|
||||
### Enable features ###########################################################################
|
||||
|
||||
# Create config.h from selected features and fallback defaults
|
||||
@@ -281,6 +285,13 @@ AS_IF([test "x$rtc_date" != "xno"], [
|
||||
AC_DEFINE(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
|
||||
rtc_date=""])
|
||||
|
||||
+AS_IF([test "x$rtc_file" != "xno"], [
|
||||
+ AS_IF([test "x$rtc_file" = "xyes"], [
|
||||
+ rtc_file=/var/lib/misc/rtc])
|
||||
+ AC_EXPAND_DIR(rtcfile_path, "$rtc_file")
|
||||
+ AC_DEFINE_UNQUOTED(RTC_FILE, "$rtcfile_path", [Save and restore system time from this file if /dev/rtc is missing.])],[
|
||||
+ AC_DEFINE_UNQUOTED(RTC_FILE, NULL)])
|
||||
+
|
||||
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
|
||||
|
||||
AS_IF([test "x$with_sulogin" != "xno"], [
|
||||
@@ -387,6 +398,7 @@ Behavior:
|
||||
Boot heading..........: $heading
|
||||
Plugins...............: $plugins
|
||||
RTC restore date......: $RTC_DATE
|
||||
+ RTC fallback file.....: $rtc_file
|
||||
|
||||
Optional features:
|
||||
Install doc/..........: $enable_doc
|
||||
diff --git a/plugins/rtc.c b/plugins/rtc.c
|
||||
index 9520c7d..9b4eeae 100644
|
||||
--- a/plugins/rtc.c
|
||||
+++ b/plugins/rtc.c
|
||||
@@ -36,8 +36,15 @@
|
||||
#include "helpers.h"
|
||||
#include "plugin.h"
|
||||
|
||||
-/* Kernel RTC driver validates against this date for sanity check */
|
||||
+/*
|
||||
+ * Kernel RTC driver validates against this date for sanity check. The
|
||||
+ * on NTP sync the driver can also update the RTC every 11 mins. We use
|
||||
+ * the same update interval to handle manual time set and file save.
|
||||
+ */
|
||||
#define RTC_TIMESTAMP_BEGIN_2000 "2000-01-01 00:00:00"
|
||||
+#define RTC_FMT "%Y-%m-%d %H:%M:%S"
|
||||
+#define RTC_PERIOD (11 * 60 * 1000)
|
||||
+
|
||||
#ifdef RTC_TIMESTAMP_CUSTOM
|
||||
static char *rtc_timestamp = RTC_TIMESTAMP_CUSTOM;
|
||||
#else
|
||||
@@ -45,6 +52,10 @@ static char *rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
|
||||
#endif
|
||||
static time_t rtc_date_fallback = 946684800LL;
|
||||
|
||||
+static char *rtc_file = RTC_FILE;
|
||||
+static uev_t rtc_timer;
|
||||
+
|
||||
+
|
||||
static void tz_set(char *tz, size_t len)
|
||||
{
|
||||
char *ptr;
|
||||
@@ -122,6 +133,68 @@ static int time_get(struct tm *tm)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static void file_save(void *arg)
|
||||
+{
|
||||
+ struct tm tm = { 0 };
|
||||
+ int rc = 0;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ fp = fopen(rtc_file, "w");
|
||||
+ if (!fp) {
|
||||
+ logit(LOG_WARNING, "Failed saving system clock to %s, code %d: %s",
|
||||
+ rtc_file, errno, strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((rc = time_get(&tm))) {
|
||||
+ logit(LOG_ERR, "System clock invalid, before %s, not saving", rtc_timestamp);
|
||||
+ print_desc(NULL, "System clock invalid, skipping");
|
||||
+ } else {
|
||||
+ char buf[32] = { 0 };
|
||||
+
|
||||
+ print_desc(NULL, "Saving system clock to file");
|
||||
+ strftime(buf, sizeof(buf), RTC_FMT, &tm);
|
||||
+ fprintf(fp, "%s\n", buf);
|
||||
+ }
|
||||
+
|
||||
+ print(rc, NULL);
|
||||
+ fclose(fp);
|
||||
+}
|
||||
+
|
||||
+static void file_restore(void *arg)
|
||||
+{
|
||||
+ struct tm tm = { 0 };
|
||||
+ int rc = 1;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ if (!rtc_file) {
|
||||
+ logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore.");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ print_desc(NULL, "Restoring system clock from backup");
|
||||
+
|
||||
+ fp = fopen(rtc_file, "r");
|
||||
+ if (fp) {
|
||||
+ char buf[32];
|
||||
+
|
||||
+ if (fgets(buf, sizeof(buf), fp)) {
|
||||
+ chomp(buf);
|
||||
+ strptime(buf, RTC_FMT, &tm);
|
||||
+ rc = time_set(&tm);
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+ } else
|
||||
+ logit(LOG_WARNING, "Missing %s", rtc_file);
|
||||
+
|
||||
+ if (rc) {
|
||||
+ time_set(NULL);
|
||||
+ rc = 2;
|
||||
+ }
|
||||
+
|
||||
+ print(rc, NULL);
|
||||
+}
|
||||
+
|
||||
static int rtc_open(void)
|
||||
{
|
||||
char *alt[] = {
|
||||
@@ -185,7 +258,7 @@ static void rtc_restore(void *arg)
|
||||
|
||||
fd = rtc_open();
|
||||
if (fd < 0) {
|
||||
- logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore.");
|
||||
+ file_restore(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,21 +283,37 @@ static void rtc_restore(void *arg)
|
||||
else
|
||||
logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
|
||||
|
||||
- time_set(NULL);
|
||||
- rc = 2;
|
||||
- }
|
||||
+ print(2, NULL);
|
||||
+
|
||||
+ /* Try restoring from last save game */
|
||||
+ if (rtc_file)
|
||||
+ file_restore(arg);
|
||||
+ } else
|
||||
+ print(0, NULL);
|
||||
|
||||
- print(rc, NULL);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
+
|
||||
+static void save(void *arg)
|
||||
+{
|
||||
+ rtc_save(arg);
|
||||
+ file_save(arg);
|
||||
+}
|
||||
+
|
||||
+static void update(uev_t *w, void *arg, int events)
|
||||
+{
|
||||
+ save(arg);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static plugin_t plugin = {
|
||||
.name = __FILE__,
|
||||
.hook[HOOK_BASEFS_UP] = {
|
||||
.cb = rtc_restore
|
||||
},
|
||||
.hook[HOOK_SHUTDOWN] = {
|
||||
- .cb = rtc_save
|
||||
+ .cb = save
|
||||
}
|
||||
};
|
||||
|
||||
@@ -237,6 +326,8 @@ PLUGIN_INIT(plugin_init)
|
||||
else
|
||||
rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
|
||||
|
||||
+ uev_timer_init(ctx, &rtc_timer, update, NULL, RTC_PERIOD, RTC_PERIOD);
|
||||
+
|
||||
plugin_register(&plugin);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
From 6be16f2f6d093ef495d0fe4313f7b05b4ba3e08f Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 3 Nov 2024 10:38:38 +0100
|
||||
Subject: [PATCH 5/7] Fix buggy --with-rtc-date=DATE, introduced in Finit v4.4
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
In 42ef3d3c, for v4.4-rc1, support for setting a custom RTC restore date
|
||||
was introduced. Unfortunately the configure script was wrong and caused
|
||||
config.h to contain
|
||||
|
||||
#define RTC_TIMESTAMP_CUSTOM "$rtc_date"
|
||||
|
||||
instead of
|
||||
|
||||
#define RTC_TIMESTAMP_CUSTOM "2023-04-10 14:35:42"
|
||||
|
||||
Furthermore, the error handling for strptime() was wrong, so the restore
|
||||
date was always reverted to the default.
|
||||
|
||||
This patch fixes both issues and extends the DATE of --with-rtc-date to
|
||||
also include seconds.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
configure.ac | 4 ++--
|
||||
plugins/rtc.c | 8 +++++---
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ae7cd23..58b78ac 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -177,7 +177,7 @@ AC_ARG_WITH(plugin-path,
|
||||
[plugin_path=$withval], [plugin_path=yes])
|
||||
|
||||
AC_ARG_WITH(rtc-date,
|
||||
- AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM", default "2000-01-01 00:00"]),
|
||||
+ AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM:SS", default "2000-01-01 00:00:00"]),
|
||||
[rtc_date=$withval], [rtc_date=no])
|
||||
|
||||
AC_ARG_WITH(rtc-file,
|
||||
@@ -282,7 +282,7 @@ AS_IF([test "x$with_random_seed" != "xno"], [
|
||||
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
|
||||
|
||||
AS_IF([test "x$rtc_date" != "xno"], [
|
||||
- AC_DEFINE(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
|
||||
+ AC_DEFINE_UNQUOTED(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
|
||||
rtc_date=""])
|
||||
|
||||
AS_IF([test "x$rtc_file" != "xno"], [
|
||||
diff --git a/plugins/rtc.c b/plugins/rtc.c
|
||||
index 9b4eeae..a733f75 100644
|
||||
--- a/plugins/rtc.c
|
||||
+++ b/plugins/rtc.c
|
||||
@@ -321,10 +321,12 @@ PLUGIN_INIT(plugin_init)
|
||||
{
|
||||
struct tm tm = { 0 };
|
||||
|
||||
- if (!strptime(rtc_timestamp, "%Y-%m-%d %H:%M", &tm))
|
||||
- rtc_date_fallback = mktime(&tm);
|
||||
- else
|
||||
+ if (!strptime(rtc_timestamp, RTC_FMT, &tm)) {
|
||||
+ logit(LOG_ERR, "Invalid restore date '%s', reverting to '%s'",
|
||||
+ rtc_timestamp, RTC_TIMESTAMP_BEGIN_2000);
|
||||
rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
|
||||
+ } else
|
||||
+ rtc_date_fallback = mktime(&tm);
|
||||
|
||||
uev_timer_init(ctx, &rtc_timer, update, NULL, RTC_PERIOD, RTC_PERIOD);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
From 49c0557cedd8d3c1a2f74d27fa7db83dd529914a Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 3 Nov 2024 20:49:04 +0100
|
||||
Subject: [PATCH 6/7] plugins: reduce log level LOG_ERR -> LOG_WARNING
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
These plugins signal success and failure directly to the console, the
|
||||
user should inspect syslog for more information.
|
||||
|
||||
This change is a follow-up to 340cae4, where kernel logs of LOG_ERR and
|
||||
higher are allowed to log directly to the console. Since syslogd has
|
||||
not been started before these plugins, the log messages would otherwise
|
||||
leak to the console.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
plugins/rtc.c | 14 +++++++-------
|
||||
plugins/urandom.c | 2 +-
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/plugins/rtc.c b/plugins/rtc.c
|
||||
index a733f75..96203a0 100644
|
||||
--- a/plugins/rtc.c
|
||||
+++ b/plugins/rtc.c
|
||||
@@ -147,7 +147,7 @@ static void file_save(void *arg)
|
||||
}
|
||||
|
||||
if ((rc = time_get(&tm))) {
|
||||
- logit(LOG_ERR, "System clock invalid, before %s, not saving", rtc_timestamp);
|
||||
+ logit(LOG_WARNING, "System clock invalid, before %s, not saving", rtc_timestamp);
|
||||
print_desc(NULL, "System clock invalid, skipping");
|
||||
} else {
|
||||
char buf[32] = { 0 };
|
||||
@@ -238,7 +238,7 @@ static void rtc_save(void *arg)
|
||||
}
|
||||
|
||||
if (rc && errno == EINVAL) {
|
||||
- logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
|
||||
+ logit(LOG_WARNING, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
|
||||
rc = 2;
|
||||
}
|
||||
|
||||
@@ -275,13 +275,13 @@ static void rtc_restore(void *arg)
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
- logit(LOG_ERR, "Failed restoring system clock from RTC.");
|
||||
+ logit(LOG_WARNING, "Failed restoring system clock from RTC.");
|
||||
if (EINVAL == errno)
|
||||
- logit(LOG_ERR, "RTC time is too old (before %s)", rtc_timestamp);
|
||||
+ logit(LOG_WARNING, "RTC time is too old (before %s)", rtc_timestamp);
|
||||
else if (ENOENT == errno)
|
||||
- logit(LOG_ERR, "RTC has no previously saved (valid) time.");
|
||||
+ logit(LOG_WARNING, "RTC has no previously saved (valid) time.");
|
||||
else
|
||||
- logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
|
||||
+ logit(LOG_WARNING, "RTC error code %d: %s", errno, strerror(errno));
|
||||
|
||||
print(2, NULL);
|
||||
|
||||
@@ -322,7 +322,7 @@ PLUGIN_INIT(plugin_init)
|
||||
struct tm tm = { 0 };
|
||||
|
||||
if (!strptime(rtc_timestamp, RTC_FMT, &tm)) {
|
||||
- logit(LOG_ERR, "Invalid restore date '%s', reverting to '%s'",
|
||||
+ logit(LOG_WARNING, "Invalid restore date '%s', reverting to '%s'",
|
||||
rtc_timestamp, RTC_TIMESTAMP_BEGIN_2000);
|
||||
rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
|
||||
} else
|
||||
diff --git a/plugins/urandom.c b/plugins/urandom.c
|
||||
index b9f6039..6f82779 100644
|
||||
--- a/plugins/urandom.c
|
||||
+++ b/plugins/urandom.c
|
||||
@@ -154,7 +154,7 @@ static void setup(void *arg)
|
||||
close(fd);
|
||||
free(rpi);
|
||||
if (rc < 0)
|
||||
- logit(LOG_ERR, "Failed adding entropy to kernel random pool: %s", strerror(err));
|
||||
+ logit(LOG_WARNING, "Failed adding entropy to kernel random pool: %s", strerror(err));
|
||||
print_result(rc < 0);
|
||||
return;
|
||||
fallback:
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
From 465bc17ca4b131f8c1ef27ff8279f4ea13745a78 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 28 Nov 2024 11:06:57 +0100
|
||||
Subject: [PATCH 7/7] Fix unintended restart of template siblings
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Consider the case where container@.conf is an available template. When
|
||||
creating a container@foo.conf it will share the same base .conf as an
|
||||
existing container@bar.conf, but we do not expect to restart bar just
|
||||
because foo is instantiated.
|
||||
|
||||
Up until this change, all template siblings were considered "dirty" if a
|
||||
new one was created or updated. Skipping realpath() for all files that
|
||||
have a '@' works around the problem.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
src/conf.c | 20 +++++++++++++-------
|
||||
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/conf.c b/src/conf.c
|
||||
index 1cfcd87..531923c 100644
|
||||
--- a/src/conf.c
|
||||
+++ b/src/conf.c
|
||||
@@ -1432,16 +1432,22 @@ static int conf_change_act(char *dir, char *name, uint32_t mask)
|
||||
strlcpy(fn, dir, sizeof(fn));
|
||||
dbg("path: %s mask: %08x", fn, mask);
|
||||
|
||||
- /* Handle disabling/removal of service */
|
||||
- rp = realpath(fn, NULL);
|
||||
- if (!rp) {
|
||||
- if (errno != ENOENT)
|
||||
- goto fail;
|
||||
+ if (strchr(name, '@')) {
|
||||
+ /* Skip realpath for templates */
|
||||
rp = strdup(fn);
|
||||
- if (!rp)
|
||||
- goto fail;
|
||||
+ } else {
|
||||
+ /* Handle disabling/removal of service */
|
||||
+ rp = realpath(fn, NULL);
|
||||
+ if (!rp) {
|
||||
+ if (errno != ENOENT)
|
||||
+ goto fail;
|
||||
+ rp = strdup(fn);
|
||||
+ }
|
||||
}
|
||||
|
||||
+ if (!rp)
|
||||
+ goto fail;
|
||||
+
|
||||
node = conf_find(rp);
|
||||
if (node) {
|
||||
dbg("event already registered for %s ...", name);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# From https://github.com/troglobit/finit/releases/
|
||||
sha256 5026965e33f31b8fa4e2e465b9521e805fa01c31cade884c07d0fcff97cd0ddf finit-4.8.tar.gz
|
||||
sha256 da14f5f05f595e15abc73bbacabfb55e8e1a4c40fc6ca6ab294be34ea437cc82 finit-4.10.tar.gz
|
||||
|
||||
# Locally calculated
|
||||
sha256 2fd62c0fe6ea6d1861669f4c87bda83a0b5ceca64f4baa4d16dd078fbd218c14 LICENSE
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
FINIT_VERSION = 4.8
|
||||
FINIT_VERSION = 4.10
|
||||
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
|
||||
FINIT_LICENSE = MIT
|
||||
FINIT_LICENSE_FILES = LICENSE
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 74ec0f8335f811e4f5becc8bbea4a52af4d3e749 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Tue, 17 Sep 2024 04:08:12 +0200
|
||||
Subject: [PATCH 1/2] On SIGTERM, allow dispatcher to process event before
|
||||
Subject: [PATCH 1/3] On SIGTERM, allow dispatcher to process event before
|
||||
exiting
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From bceb724d328f156efa4ad18f26f1760504bd093d Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Wed, 27 Nov 2024 08:44:57 +0100
|
||||
Subject: [PATCH 2/2] avahi-daemon: allow adjusting log level
|
||||
Subject: [PATCH 2/3] avahi-daemon: allow adjusting log level
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
From 50ddfbefe5ac4d87040cb177e7cf432d4da04e97 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Wed, 26 Feb 2025 17:42:08 +0100
|
||||
Subject: [PATCH 3/3] avahi-daemon: improve error reporting in chroot
|
||||
communication
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Improve logging of error in chroot communication by including the
|
||||
filename in the log message. Instead of this:
|
||||
|
||||
avahi-daemon[3590]: chroot.c: open() failed: No such file or directory
|
||||
|
||||
log this:
|
||||
|
||||
avahi-daemon[3590]: chroot.c: open(/etc/resolv.conf) failed: No such file or directory
|
||||
|
||||
Which on a system with resolvconf would make the sysadmin a lot calmer,
|
||||
since the file had not yet been created at boot.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
avahi-daemon/chroot.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/avahi-daemon/chroot.c b/avahi-daemon/chroot.c
|
||||
index ccd56be..fbaad69 100644
|
||||
--- a/avahi-daemon/chroot.c
|
||||
+++ b/avahi-daemon/chroot.c
|
||||
@@ -237,12 +237,13 @@ static int helper_main(int fd) {
|
||||
case AVAHI_CHROOT_GET_RECORD_BROWSER_INTROSPECT:
|
||||
#endif
|
||||
case AVAHI_CHROOT_GET_RESOLV_CONF: {
|
||||
+ const char *fn = get_file_name_table[(int) command];
|
||||
int payload;
|
||||
|
||||
- if ((payload = open(get_file_name_table[(int) command], O_RDONLY)) < 0) {
|
||||
+ if ((payload = open(fn, O_RDONLY)) < 0) {
|
||||
uint8_t c = AVAHI_CHROOT_FAILURE;
|
||||
|
||||
- avahi_log_error(__FILE__": open() failed: %s", strerror(errno));
|
||||
+ avahi_log_error(__FILE__": open(%s) failed: %s", fn, strerror(errno));
|
||||
|
||||
if (write(fd, &c, sizeof(c)) != sizeof(c)) {
|
||||
avahi_log_error(__FILE__": write() failed: %s\n", strerror(errno));
|
||||
@@ -262,9 +263,11 @@ static int helper_main(int fd) {
|
||||
|
||||
case AVAHI_CHROOT_UNLINK_SOCKET:
|
||||
case AVAHI_CHROOT_UNLINK_PID: {
|
||||
+ const char *fn = unlink_file_name_table[(int) command];
|
||||
uint8_t c = AVAHI_CHROOT_SUCCESS;
|
||||
|
||||
- unlink(unlink_file_name_table[(int) command]);
|
||||
+ if (unlink(fn) && errno != ENOENT)
|
||||
+ avahi_log_error(__FILE__": unlink(%s) failed: %s", fn, strerror(errno));
|
||||
|
||||
if (write(fd, &c, sizeof(c)) != sizeof(c)) {
|
||||
avahi_log_error(__FILE__": write() failed: %s\n", strerror(errno));
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From 9b2f6b94132d14b1d2d2a7d3b65bac4f3a056aac Mon Sep 17 00:00:00 2001
|
||||
From: Mohan Prasad J <mohan.prasad@microchip.com>
|
||||
Date: Mon, 4 Nov 2024 04:04:07 +0530
|
||||
Subject: netlink: settings: Fix for wrong auto-negotiation state
|
||||
|
||||
Auto-negotiation state in json format showed the
|
||||
opposite state due to wrong comparison.
|
||||
Fix for returning the correct auto-neg state implemented.
|
||||
|
||||
Signed-off-by: Mohan Prasad J <mohan.prasad@microchip.com>
|
||||
---
|
||||
netlink/settings.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/netlink/settings.c b/netlink/settings.c
|
||||
index dbfb520..b9b3ba9 100644
|
||||
--- a/netlink/settings.c
|
||||
+++ b/netlink/settings.c
|
||||
@@ -546,7 +546,7 @@ int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data)
|
||||
(autoneg == AUTONEG_DISABLE) ? "off" : "on");
|
||||
else
|
||||
print_bool(PRINT_JSON, "auto-negotiation", NULL,
|
||||
- autoneg == AUTONEG_DISABLE);
|
||||
+ autoneg != AUTONEG_DISABLE);
|
||||
}
|
||||
if (tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]) {
|
||||
uint8_t val;
|
||||
--
|
||||
cgit 1.2.3-korg
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 998f0e99f2bd7ab54e1d25acac4227335c8caaec Mon Sep 17 00:00:00 2001
|
||||
From 38625958e097c63ec25fddfbbf606c4b157cd058 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 12 Mar 2024 10:27:24 +0100
|
||||
Subject: [PATCH 01/25] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for
|
||||
Subject: [PATCH 01/26] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for
|
||||
PPU on 6393X
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
In a multi-chip setup, delays of up to 750ms are observed before the
|
||||
device (6393X) signals completion of PPU initialization (Global 1,
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 3002b9e08272f3d740c2b582cf9b01fa1fde46b8 Mon Sep 17 00:00:00 2001
|
||||
From b41039e6b8db5a484950aa8e839d13029c7f0424 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 27 Mar 2024 15:52:43 +0100
|
||||
Subject: [PATCH 02/25] net: dsa: mv88e6xxx: Improve indirect register access
|
||||
Subject: [PATCH 02/26] net: dsa: mv88e6xxx: Improve indirect register access
|
||||
perf on 6393
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
When operating in multi-chip mode, the 6393 family maps a subset of
|
||||
commonly used global registers to the outermost address space (in
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 6bad36ecd3bb8f9b97c51f8ee2409f250344c1fc Mon Sep 17 00:00:00 2001
|
||||
From 31d3700b09b634676ab88f0f3469538903b12ace Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Mon, 22 Apr 2024 23:18:01 +0200
|
||||
Subject: [PATCH 03/25] net: dsa: mv88e6xxx: Honor ports being managed via
|
||||
Subject: [PATCH 03/26] net: dsa: mv88e6xxx: Honor ports being managed via
|
||||
in-band-status
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Keep all link parameters in their unforced states when the port is
|
||||
declared as being managed via in-band-status, and let the MAC
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 980366a1f8709fdfe643edb666c86a916c681a6c Mon Sep 17 00:00:00 2001
|
||||
From d048a31995fa82ccde7dc12df27b8162ae31762c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 24 Apr 2024 22:41:04 +0200
|
||||
Subject: [PATCH 04/25] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
||||
Subject: [PATCH 04/26] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
||||
ports on 6393X
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
For packets with a DA in the IEEE reserved L2 group range, originating
|
||||
from a CPU, forward it as normal, rather than classifying it as
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From cfc55d98057160753158b7c5357c94ac24d918fe Mon Sep 17 00:00:00 2001
|
||||
From a255c151a82221cccc896d6be5817c037cc563bb Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 19:44:32 +0100
|
||||
Subject: [PATCH 05/25] net: dsa: mv88e6xxx: Add LED infrastructure
|
||||
Subject: [PATCH 05/26] net: dsa: mv88e6xxx: Add LED infrastructure
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Parse DT for LEDs and register them for devices that support it,
|
||||
though no actual implementations exist yet.
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From 180f2b90c73bc9fdfb27335327571daf8507f9c8 Mon Sep 17 00:00:00 2001
|
||||
From 2d2c9fdd45ab42b725b4a063b4444661b30bc59c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 21:59:35 +0100
|
||||
Subject: [PATCH 06/25] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
Subject: [PATCH 06/26] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Trigger support:
|
||||
- "none"
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 2e42839d4edb250b298f7683975382e9ec97c9a9 Mon Sep 17 00:00:00 2001
|
||||
From 91465d6568ea89cdf9e0092c1ff35a757aef5116 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 28 May 2024 10:38:42 +0200
|
||||
Subject: [PATCH 07/25] net: dsa: tag_dsa: Use tag priority as initial
|
||||
Subject: [PATCH 07/26] net: dsa: tag_dsa: Use tag priority as initial
|
||||
skb->priority
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Use the 3-bit priority field from the DSA tag as the initial packet
|
||||
priority on ingress to the CPU.
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 681fc63548bae02cd286042a3470011617ff78fd Mon Sep 17 00:00:00 2001
|
||||
From fb892bdcfd4b7784a0506058b3e56c6055b4e4e8 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 16 Jan 2024 16:00:55 +0100
|
||||
Subject: [PATCH 08/25] net: dsa: Support MDB memberships whose L2 addresses
|
||||
Subject: [PATCH 08/26] net: dsa: Support MDB memberships whose L2 addresses
|
||||
overlap
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Multiple IP multicast groups (32 for v4, 2^80 for v6) map to the same
|
||||
L2 address. This means that switchdev drivers may receive multiple MDB
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From d1c7aeac75ffe6e1350d8a08ee9ba99209636df5 Mon Sep 17 00:00:00 2001
|
||||
From a569ea3aa01cea0eef5181f1a4d5f06260c3ca6a Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Mar 2024 19:12:15 +0100
|
||||
Subject: [PATCH 09/25] net: dsa: Support EtherType based priority overrides
|
||||
Subject: [PATCH 09/26] net: dsa: Support EtherType based priority overrides
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 79d68d69f6cd6cf57ef5ed4bcba45134ff8ba174 Mon Sep 17 00:00:00 2001
|
||||
From 8e61cdafeabd25b88e591d7f9593fbc65453328a Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Fri, 22 Mar 2024 16:15:43 +0100
|
||||
Subject: [PATCH 10/25] net: dsa: mv88e6xxx: Support EtherType based priority
|
||||
Subject: [PATCH 10/26] net: dsa: mv88e6xxx: Support EtherType based priority
|
||||
overrides
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From 57eabbff1169a5641c59fc698d7b122d17733d49 Mon Sep 17 00:00:00 2001
|
||||
From 9ddfb92b70bd73bacd358b699d30a8b8fd05b813 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 28 May 2024 11:04:22 +0200
|
||||
Subject: [PATCH 11/25] net: dsa: mv88e6xxx: Add mqprio qdisc support
|
||||
Subject: [PATCH 11/26] net: dsa: mv88e6xxx: Add mqprio qdisc support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Add support for attaching mqprio qdisc's to mv88e6xxx ports and use
|
||||
the packet's traffic class as the outgoing priority when no PCP bits
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 752cce791dfe31525e3974d6f6419e4be0535343 Mon Sep 17 00:00:00 2001
|
||||
From fcf728f4442e961fc8361bba0d58aba8712f6893 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 29 May 2024 13:20:41 +0200
|
||||
Subject: [PATCH 12/25] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
|
||||
Subject: [PATCH 12/26] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
|
||||
are available
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Switch the priority sourcing precdence to prefer VLAN PCP over IP
|
||||
DSCP, when both are available.
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From b3b9b97cbe4eebd6cd3d68744e11a1bde5b98a47 Mon Sep 17 00:00:00 2001
|
||||
From c7fb329301a2889540d6416b1ec9145a00de443c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 26 Nov 2024 19:45:59 +0100
|
||||
Subject: [PATCH 13/25] [FIX] net: dsa: mv88e6xxx: Trap locally terminated
|
||||
Subject: [PATCH 13/26] [FIX] net: dsa: mv88e6xxx: Trap locally terminated
|
||||
VLANs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Before this change, in a setup like the following, packets assigned to
|
||||
VLAN 10 were forwarded between the switch ports, even though the
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 1e19f28f4f44973f349ad8bbb2fe0f4624e3c0f3 Mon Sep 17 00:00:00 2001
|
||||
From 31909f3d1f148d0bee1047abb76b890bf40bcb94 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:38:10 +0200
|
||||
Subject: [PATCH 14/25] net: phy: marvell10g: Support firmware loading on
|
||||
Subject: [PATCH 14/26] net: phy: marvell10g: Support firmware loading on
|
||||
88X3310
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
When probing, if a device is waiting for firmware to be loaded into
|
||||
its RAM, ask userspace for the binary and load it over XMDIO.
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 95ff23729224c6c08801c2dba8830b18c177431b Mon Sep 17 00:00:00 2001
|
||||
From c7c930ee6d4003f8fda995b03cf7cbaf148ea58e Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 21 Nov 2023 20:15:24 +0100
|
||||
Subject: [PATCH 15/25] net: phy: marvell10g: Fix power-up when strapped to
|
||||
Subject: [PATCH 15/26] net: phy: marvell10g: Fix power-up when strapped to
|
||||
start powered down
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
On devices which are hardware strapped to start powered down (PDSTATE
|
||||
== 1), make sure that we clear the power-down bit on all units
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From ecdfc7324dd50d79c81af453699467023d72e2bf Mon Sep 17 00:00:00 2001
|
||||
From 16fb7c5087266f173d8a5a3bf72f6798f702038f Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 15 Nov 2023 20:58:42 +0100
|
||||
Subject: [PATCH 16/25] net: phy: marvell10g: Add LED support for 88X3310
|
||||
Subject: [PATCH 16/26] net: phy: marvell10g: Add LED support for 88X3310
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Pickup the LEDs from the state in which the hardware reset or
|
||||
bootloader left them, but also support further configuration via
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From df3d8aede0c04a0ae93e0dc02ba6b471e3791500 Mon Sep 17 00:00:00 2001
|
||||
From 1c7ecd73741ecb39efd3b51720c81a15cf22e464 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 12 Dec 2023 09:51:05 +0100
|
||||
Subject: [PATCH 17/25] net: phy: marvell10g: Support LEDs tied to a single
|
||||
Subject: [PATCH 17/26] net: phy: marvell10g: Support LEDs tied to a single
|
||||
media side
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
In a combo-port setup, i.e. where both the copper and fiber interface
|
||||
are available to the user, the LEDs may be physically located either
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From f76443118313f681a62cf34a6f8b38f743832dff Mon Sep 17 00:00:00 2001
|
||||
From c6dd269683ee65b1a2879692379fba13cae40bd5 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 27 Mar 2024 10:10:19 +0100
|
||||
Subject: [PATCH 18/25] net: phy: Do not resume PHY when attaching
|
||||
Subject: [PATCH 18/26] net: phy: Do not resume PHY when attaching
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
The PHY should not start negotiating with its link-partner until
|
||||
explicitly instructed to do so.
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From cd73e20a5c51dc26ab6a768a813ab805ad8b0689 Mon Sep 17 00:00:00 2001
|
||||
From 604f9a09bf90c6dcec29b946851c59847ad368a7 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 4 Mar 2024 16:47:28 +0100
|
||||
Subject: [PATCH 19/25] net: bridge: avoid classifying unknown multicast as
|
||||
Subject: [PATCH 19/26] net: bridge: avoid classifying unknown multicast as
|
||||
mrouters_only
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Unknown multicast, MAC/IPv4/IPv6, should always be flooded according to
|
||||
the per-port mcast_flood setting, as well as to detected and configured
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From ed61171f9f5d42000b7315d8af12691bb02dac35 Mon Sep 17 00:00:00 2001
|
||||
From 8c489b7e9abc123d1808546cd1dd8428b5482088 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Tue, 5 Mar 2024 06:44:41 +0100
|
||||
Subject: [PATCH 20/25] net: bridge: Ignore router ports when forwarding L2
|
||||
Subject: [PATCH 20/26] net: bridge: Ignore router ports when forwarding L2
|
||||
multicast
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Multicast router ports are either statically configured or learned from
|
||||
control protocol traffic (IGMP/MLD/PIM). These protocols regulate IP
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 73702e1c0331ef8644f326f2dc155a73749cb1c5 Mon Sep 17 00:00:00 2001
|
||||
From 55e616c4e37d316b5d9266390dc13531d0bbd765 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 4 Apr 2024 16:36:30 +0200
|
||||
Subject: [PATCH 21/25] net: bridge: drop delay for applying strict multicast
|
||||
Subject: [PATCH 21/26] net: bridge: drop delay for applying strict multicast
|
||||
filtering
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
This *local* patch drops the initial delay before applying strict multicast
|
||||
filtering, introduced in [1] and recently updated in [2].
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From a48795ef7dbcfd7f1921753ad943144b933020b0 Mon Sep 17 00:00:00 2001
|
||||
From 186ecab132b86588eb6c1e93bcc33f3c5cc95c03 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 May 2024 14:51:54 +0200
|
||||
Subject: [PATCH 22/25] net: bridge: Differentiate MDB additions from
|
||||
Subject: [PATCH 22/26] net: bridge: Differentiate MDB additions from
|
||||
modifications
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Before this change, the reception of an IGMPv3 report (and analogously
|
||||
for MLDv2) that adds a new group, would trigger two MDB RTM_NEWMDB
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From f0bbef0a94ed2e00475036b25dac8746e061c114 Mon Sep 17 00:00:00 2001
|
||||
From e31128eb97256ae37bda13e8c02a1f53b92b3524 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Fri, 24 Nov 2023 23:29:55 +0100
|
||||
Subject: [PATCH 23/25] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
Subject: [PATCH 23/26] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
TLV is invalid
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Before this change, probing an NVMEM device, expected to contain a
|
||||
valid TLV, would fail if it had not been provisioned yet. But an
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
From 7135f0ab4f04b5cea7a0b67df0fe91f925ef19df Mon Sep 17 00:00:00 2001
|
||||
From 1e31630dd13b534d70440826df9c3b01c85966e7 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 29 Apr 2024 15:14:51 +0200
|
||||
Subject: [PATCH 24/25] usb: core: adjust log level for unauthorized devices
|
||||
Subject: [PATCH 24/26] usb: core: adjust log level for unauthorized devices
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
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
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
From 733067c41391c3b9f10d0bf62b1097dce9996df1 Mon Sep 17 00:00:00 2001
|
||||
From cfb28602d7b9425f75fc37acdb123634e5717c2a Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 16 Jan 2025 12:35:12 +0100
|
||||
Subject: [PATCH 25/25] net: dsa: mv88e6xxx: collapse disabled state into
|
||||
Subject: [PATCH 25/26] net: dsa: mv88e6xxx: collapse disabled state into
|
||||
blocking
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
This patch changes the behavior of switchcore ports wrt. the port state.
|
||||
Instead of disabling the port, the driver now treats the disabled state
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
From 5474cc6141ebdb748eea0b4ee6b79cce8b084585 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 12 Feb 2025 22:03:14 +0100
|
||||
Subject: [PATCH 26/26] net: dsa: mv88e6xxx: Only activate LAG offloading when
|
||||
bridged
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Wires
|
||||
|
||||
The current port isolation scheme for mv88e6xxx is detailed here:
|
||||
https://lore.kernel.org/netdev/20220203101657.990241-1-tobias@waldekranz.com/
|
||||
|
||||
As it turns out, this is not compatible with LAGs. Consider the
|
||||
following setup:
|
||||
|
||||
.-----.
|
||||
| CPU |
|
||||
'--+--'
|
||||
|
|
||||
.--0--. .-----.
|
||||
| sw1 9---0 sw2 |
|
||||
'-----' '-4-5-'
|
||||
|
||||
A LAG is created from sw2p{4,5}, using ID 0, but it is not attached
|
||||
to any bridge - so port isolation is active. Let's walk through a
|
||||
packet's journey to the CPU:
|
||||
|
||||
1. Packet ingresses sw2p4, the MapDA bit is not set, so it is flooded
|
||||
according to the PVT, which only contains sw2p0
|
||||
2. Packet egresses sw2p0 with FORWARD vid:0 dev:2 port:0(lag)
|
||||
3. Packet ingresses sw1p9, the VTU policy bit is set for VLAN 0, thus
|
||||
the packet is classified as MGMT and trapped to the CPU
|
||||
4. Packet egresses sw1p0 with TO_CPU vid:0 dev:2 port:0
|
||||
5. Packet ingresses CPU, since no user port is mapped to sw2p0 the
|
||||
packet is dropped
|
||||
|
||||
The problem is that in step 2, the original source port information is
|
||||
lost (replaced with "lag 0"), and then sw1 rewrites the ingressing
|
||||
FORWARD to a TO_CPU, which does not have a LAG bit. As a result, after
|
||||
the translation between steps 3 and 4, it now looks as if the packet
|
||||
originally ingressed on sw2p0.
|
||||
|
||||
Therefore, defer enabling the LAG offload until it joins a bridge. In
|
||||
the example above, it means that the original source port (sw2p4)
|
||||
information will be in the FORWARD sent in step 2, which allows the
|
||||
existing port isolation to work as intended.
|
||||
|
||||
Before joining a bridge, the offload does not offer any performance
|
||||
benefit anyway. All ingressing packet will always have to go to the
|
||||
CPU; egress traffic always relies on software hashing.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 42 +++++++++++++++-----------------
|
||||
1 file changed, 20 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 785cd3d0e2b1..37e79d52c175 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -3065,6 +3065,7 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
+ unsigned int lagid;
|
||||
int err;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
@@ -3073,6 +3074,13 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
+ if ((lagid = dsa_port_lag_id_get(dsa_to_port(ds, port)))) {
|
||||
+ /* DSA LAG IDs are one-based */
|
||||
+ err = mv88e6xxx_port_set_trunk(chip, port, true, lagid - 1);
|
||||
+ if (err)
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+
|
||||
err = mv88e6xxx_port_set_map_da(chip, port, true);
|
||||
if (err)
|
||||
goto unlock;
|
||||
@@ -3117,6 +3125,14 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
|
||||
"port %d failed to restore map-DA: %pe\n",
|
||||
port, ERR_PTR(err));
|
||||
|
||||
+ if (dsa_port_lag_id_get(dsa_to_port(ds, port))) {
|
||||
+ err = mv88e6xxx_port_set_trunk(chip, port, false, 0);
|
||||
+ if (err)
|
||||
+ dev_err(ds->dev,
|
||||
+ "port %d failed to disable trunking: %pe\n",
|
||||
+ port, ERR_PTR(err));
|
||||
+ }
|
||||
+
|
||||
err = mv88e6xxx_port_commit_pvid(chip, port);
|
||||
if (err)
|
||||
dev_err(ds->dev,
|
||||
@@ -6992,30 +7008,13 @@ static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
- int err, id;
|
||||
+ int err;
|
||||
|
||||
if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- /* DSA LAG IDs are one-based */
|
||||
- id = lag.id - 1;
|
||||
-
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
-
|
||||
- err = mv88e6xxx_port_set_trunk(chip, port, true, id);
|
||||
- if (err)
|
||||
- goto err_unlock;
|
||||
-
|
||||
err = mv88e6xxx_lag_sync_masks_map(ds, lag);
|
||||
- if (err)
|
||||
- goto err_clear_trunk;
|
||||
-
|
||||
- mv88e6xxx_reg_unlock(chip);
|
||||
- return 0;
|
||||
-
|
||||
-err_clear_trunk:
|
||||
- mv88e6xxx_port_set_trunk(chip, port, false, 0);
|
||||
-err_unlock:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
return err;
|
||||
}
|
||||
@@ -7024,13 +7023,12 @@ static int mv88e6xxx_port_lag_leave(struct dsa_switch *ds, int port,
|
||||
struct dsa_lag lag)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
- int err_sync, err_trunk;
|
||||
+ int err;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
- err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
|
||||
- err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0);
|
||||
+ err = mv88e6xxx_lag_sync_masks_map(ds, lag);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
- return err_sync ? : err_trunk;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index,
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
From 2950046cd17bf9296a0b70b8f6b38114f6985864 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 22 Jun 2023 10:24:57 +0200
|
||||
Subject: [PATCH 1/3] Allow 'factory' as copy-from (only) in rpc copy-config
|
||||
Subject: [PATCH 1/4] Allow 'factory' as copy-from (only) in rpc copy-config
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
From d2e4e60838761e2bdd02d651b8e0bea47cc2dcb5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Tue, 2 Jul 2024 14:56:15 +0200
|
||||
Subject: [PATCH 2/3] Disable local users (backwards compat with older model)
|
||||
Subject: [PATCH 2/4] Disable local users (backwards compat with older model)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
Organization: Wires
|
||||
|
||||
Drop local-users, because if enabled netopeer require all users that
|
||||
should be allowed to use NETCONF to also be configured in the updated
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
From 2f09813c91def7672c036c7f713302cb3a12cf18 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Tue, 4 Feb 2025 20:14:50 +0100
|
||||
Subject: [PATCH 4/4] Do not generate data in sysrepo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Wires
|
||||
|
||||
We generate the host keys and configuration for netconf on boot, do not generate anything when
|
||||
building/installing netopeer2
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 40 ----------------------------------------
|
||||
1 file changed, 40 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 4341be1..f1c4ae8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -383,47 +383,7 @@ if(SYSREPO_SETUP)
|
||||
message(FATAL_ERROR \" OUTPUT:\\n \${CMD_OUT_F}\\n ERROR:\\n \${CMD_ERR_F}\")
|
||||
endif()
|
||||
")
|
||||
-
|
||||
- # generate hostkey
|
||||
- install(CODE "
|
||||
- message(STATUS \"Generating a new RSA host key \\\"genkey\\\" if not already added (merge_hostkey.sh)...\")
|
||||
- set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
|
||||
- set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
|
||||
- execute_process(COMMAND \"\$ENV{DESTDIR}${DATA_DIR}/scripts/merge_hostkey.sh\"
|
||||
- RESULT_VARIABLE CMD_RES
|
||||
- OUTPUT_VARIABLE CMD_OUT
|
||||
- ERROR_VARIABLE CMD_ERR
|
||||
- OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
- ERROR_STRIP_TRAILING_WHITESPACE)
|
||||
- if(NOT CMD_RES EQUAL 0)
|
||||
- string(REPLACE \"\\n\" \"\\n \" CMD_OUT_F \"\${CMD_OUT}\")
|
||||
- string(REPLACE \"\\n\" \"\\n \" CMD_ERR_F \"\${CMD_ERR}\")
|
||||
- message(FATAL_ERROR \" OUTPUT:\\n \${CMD_OUT_F}\\n ERROR:\\n \${CMD_ERR_F}\")
|
||||
- endif()
|
||||
- ")
|
||||
-
|
||||
- # merge listen config
|
||||
- install(CODE "
|
||||
- message(STATUS \"Merging default server listen configuration if there is none (merge_config.sh)...\")
|
||||
- set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
|
||||
- set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
|
||||
- set(ENV{NP2_VERSION} \"${NP2SRV_VERSION}\")
|
||||
- execute_process(COMMAND \"\$ENV{DESTDIR}${DATA_DIR}/scripts/merge_config.sh\"
|
||||
- RESULT_VARIABLE CMD_RES
|
||||
- OUTPUT_VARIABLE CMD_OUT
|
||||
- ERROR_VARIABLE CMD_ERR
|
||||
- OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
- ERROR_STRIP_TRAILING_WHITESPACE)
|
||||
- if(NOT CMD_RES EQUAL 0)
|
||||
- string(REPLACE \"\\n\" \"\\n \" CMD_OUT_F \"\${CMD_OUT}\")
|
||||
- string(REPLACE \"\\n\" \"\\n \" CMD_ERR_F \"\${CMD_ERR}\")
|
||||
- message(FATAL_ERROR \" OUTPUT:\\n \${CMD_OUT_F}\\n ERROR:\\n \${CMD_ERR_F}\")
|
||||
- endif()
|
||||
- ")
|
||||
-else()
|
||||
- message(WARNING "Server will refuse to start if the modules are not installed!")
|
||||
endif()
|
||||
-
|
||||
# tests
|
||||
if(ENABLE_TESTS OR (BUILD_NETOPEER2_LIB AND NETOPEER2_LIB_TESTS))
|
||||
if(ENABLE_TESTS)
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
diff -ru openresolv-3.12.0.orig/resolvconf.in openresolv-3.12.0/resolvconf.in
|
||||
--- openresolv-3.12.0.orig/resolvconf.in 2020-12-27 19:05:10.000000000 +0100
|
||||
+++ openresolv-3.12.0/resolvconf.in 2023-03-27 00:19:03.365164029 +0200
|
||||
@@ -315,6 +315,8 @@
|
||||
then
|
||||
/usr/bin/systemctl restart $1.service
|
||||
fi'
|
||||
+ elif [ -x /sbin/initctl ]; then
|
||||
+ RESTARTCMD="/sbin/initctl -bnq restart \$1"
|
||||
elif [ -x /sbin/rc-service ] &&
|
||||
{ [ -s /libexec/rc/init.d/softlevel ] ||
|
||||
[ -s /run/openrc/softlevel ]; }
|
||||
@@ -1,16 +0,0 @@
|
||||
diff -ru openresolv-3.12.0.orig/resolvconf.in openresolv-3.12.0/resolvconf.in
|
||||
--- openresolv-3.12.0.orig/resolvconf.in 2020-12-27 19:05:10.000000000 +0100
|
||||
+++ openresolv-3.12.0/resolvconf.in 2023-03-27 00:19:03.365164029 +0200
|
||||
@@ -315,6 +315,12 @@
|
||||
then
|
||||
/usr/bin/systemctl restart $1.service
|
||||
fi'
|
||||
+ elif [ -x /sbin/initctl ]; then
|
||||
+ # Finit
|
||||
+ RESTARTCMD='
|
||||
+ if /sbin/initctl -bq status $1; then
|
||||
+ /sbin/initctl -bnq restart $1
|
||||
+ fi'
|
||||
elif [ -x /sbin/rc-service ] &&
|
||||
{ [ -s /libexec/rc/init.d/softlevel ] ||
|
||||
[ -s /run/openrc/softlevel ]; }
|
||||
+97
-26
@@ -3,8 +3,10 @@
|
||||
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -23,11 +25,11 @@ struct infix_ds {
|
||||
};
|
||||
|
||||
struct infix_ds infix_config[] = {
|
||||
{ "startup-config", "startup", SR_DS_STARTUP, 1, "/cfg/startup-config.cfg" },
|
||||
{ "running-config", "running", SR_DS_RUNNING, 1, NULL },
|
||||
{ "candidate-config", "candidate", SR_DS_CANDIDATE, 1, NULL },
|
||||
{ "operational-config", "operational", SR_DS_OPERATIONAL, 1, NULL },
|
||||
{ "factory-config", "factory-default", SR_DS_FACTORY_DEFAULT, 0, NULL }
|
||||
{ "startup-config", "startup", SR_DS_STARTUP, 1, "/cfg/startup-config.cfg" },
|
||||
{ "running-config", "running", SR_DS_RUNNING, 1, NULL },
|
||||
{ "candidate-config", "candidate", SR_DS_CANDIDATE, 1, NULL },
|
||||
{ "operational-config", "operational", SR_DS_OPERATIONAL, 1, NULL },
|
||||
{ "factory-config", "factory-default", SR_DS_FACTORY_DEFAULT, 0, NULL }
|
||||
};
|
||||
|
||||
static const char *prognm = "copy";
|
||||
@@ -64,6 +66,9 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Current system user, same as sysrepo user
|
||||
*/
|
||||
static char *getuser(void)
|
||||
{
|
||||
const struct passwd *pw;
|
||||
@@ -79,18 +84,83 @@ static char *getuser(void)
|
||||
return pw->pw_name;
|
||||
}
|
||||
|
||||
static void set_owner(const char *fn, const char *user)
|
||||
/*
|
||||
* If UNIX user is in UNIX group of directory containing file,
|
||||
* return 1, otherwise 0.
|
||||
*
|
||||
* E.g., writing to /cfg/foo, where /cfg is owned by root:wheel,
|
||||
* should result in the file being owned by $LOGNAME:wheel with
|
||||
* 0660 perms for other users in same group.
|
||||
*/
|
||||
static int in_group(const char *user, const char *fn, gid_t *gid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
char path[PATH_MAX];
|
||||
const struct passwd *pw;
|
||||
int i, num = 0, rc = 0;
|
||||
struct stat st;
|
||||
gid_t *groups;
|
||||
char *dir;
|
||||
|
||||
pw = getpwnam(user);
|
||||
if (!pw) {
|
||||
fprintf(stderr, ERRMSG "setting owner %s on %s: %s\n", fn, user, strerror(errno));
|
||||
return;
|
||||
if (!pw)
|
||||
return 0;
|
||||
|
||||
strlcpy(path, fn, sizeof(path));
|
||||
dir = dirname(path);
|
||||
|
||||
if (stat(dir, &st))
|
||||
return 0;
|
||||
|
||||
num = NGROUPS_MAX;
|
||||
groups = malloc(num * sizeof(gid_t));
|
||||
if (!groups) {
|
||||
perror("in_group() malloc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
chmod(fn, 0660);
|
||||
chown(fn, pw->pw_uid, pw->pw_gid);
|
||||
getgrouplist(user, pw->pw_gid, groups, &num);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (groups[i] == st.st_gid) {
|
||||
*gid = st.st_gid;
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(groups);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set group owner so other users with same directory permissions can
|
||||
* read/write the file as well. E.g., an 'admin' level user in group
|
||||
* 'wheel' writing a new file to `/cfg` should be possible to read and
|
||||
* write to by other administrators.
|
||||
*
|
||||
* This function is called only when the file has been successfully
|
||||
* copied or created in a file system directory. This is why we can
|
||||
* safely ignore any EPERM errors to chown(), below, because if the file
|
||||
* already existed, created by another user, we are not allowed to chgrp
|
||||
* it. The sole purpose of this function is to allow other users in the
|
||||
* same group to access the file in the future.
|
||||
*/
|
||||
static void set_owner(const char *fn, const char *user)
|
||||
{
|
||||
gid_t gid = 9999;
|
||||
|
||||
if (!fn)
|
||||
return; /* not an error, e.g., running-config is not a file */
|
||||
|
||||
if (!in_group(user, fn, &gid))
|
||||
return; /* user not in parent directory's group */
|
||||
|
||||
if (chown(fn, -1, gid) && errno != EPERM) {
|
||||
int _errno = errno;
|
||||
const struct group *gr = getgrgid(gid);
|
||||
|
||||
fprintf(stderr, ERRMSG "setting group owner %s (%d) on %s: %s\n",
|
||||
gr ? gr->gr_name : "<unknown>", gid, fn, strerror(_errno));
|
||||
}
|
||||
}
|
||||
|
||||
static const char *infix_ds(const char *text, struct infix_ds **ds)
|
||||
@@ -108,20 +178,21 @@ static const char *infix_ds(const char *text, struct infix_ds **ds)
|
||||
}
|
||||
|
||||
|
||||
static int copy(const char *src, const char *dst, const char *user)
|
||||
static int copy(const char *src, const char *dst, const char *remote_user)
|
||||
{
|
||||
struct infix_ds *srcds = NULL, *dstds = NULL;
|
||||
char temp_file[20] = "/tmp/copy.XXXXXX";
|
||||
const char *tmpfn = NULL;
|
||||
sr_session_ctx_t *sess;
|
||||
const char *fn = NULL;
|
||||
const char *username;
|
||||
sr_conn_ctx_t *conn;
|
||||
const char *user;
|
||||
char adjust[256];
|
||||
mode_t oldmask;
|
||||
int rc = 0;
|
||||
|
||||
oldmask = umask(0660);
|
||||
/* rw for user and group only */
|
||||
oldmask = umask(0006);
|
||||
|
||||
src = infix_ds(src, &srcds);
|
||||
if (!src)
|
||||
@@ -131,11 +202,11 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
goto err;
|
||||
|
||||
if (!strcmp(src, dst)) {
|
||||
fprintf(stderr, ERRMSG "source and destination are the same, aborting.");
|
||||
fprintf(stderr, ERRMSG "source and destination are the same, aborting.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
username = getuser();
|
||||
user = getuser();
|
||||
|
||||
/* 1. Regular ds copy */
|
||||
if (srcds && dstds) {
|
||||
@@ -157,13 +228,13 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
if (sr_session_start(conn, dstds->datastore, &sess)) {
|
||||
fprintf(stderr, ERRMSG "unable to open transaction to %s\n", dst);
|
||||
} else {
|
||||
sr_nacm_set_user(sess, username);
|
||||
sr_nacm_set_user(sess, user);
|
||||
rc = sr_copy_config(sess, NULL, srcds->datastore, timeout * 1000);
|
||||
if (rc)
|
||||
emsg(sess, ERRMSG "unable to copy configuration, err %d: %s\n",
|
||||
rc, sr_strerror(rc));
|
||||
else
|
||||
set_owner(dstds->path, username);
|
||||
set_owner(dstds->path, user);
|
||||
}
|
||||
rc = sr_disconnect(conn);
|
||||
|
||||
@@ -187,11 +258,11 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
if (rc)
|
||||
fprintf(stderr, ERRMSG "failed exporting %s to %s\n", src, fn);
|
||||
else {
|
||||
rc = systemf("curl %s -LT %s %s", user, fn, dst);
|
||||
rc = systemf("curl %s -LT %s %s", remote_user, fn, dst);
|
||||
if (rc)
|
||||
fprintf(stderr, ERRMSG "failed uploading %s to %s\n", src, dst);
|
||||
else
|
||||
set_owner(dst, username);
|
||||
set_owner(dst, user);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
@@ -219,7 +290,7 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
if (rc)
|
||||
fprintf(stderr, ERRMSG "failed copy %s to %s\n", src, fn);
|
||||
else
|
||||
set_owner(fn, username);
|
||||
set_owner(fn, user);
|
||||
} else if (dstds) {
|
||||
if (!dstds->sysrepocfg) {
|
||||
fprintf(stderr, ERRMSG "not possible to import to this datastore.\n");
|
||||
@@ -245,7 +316,7 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
}
|
||||
|
||||
if (tmpfn)
|
||||
rc = systemf("curl %s -Lo %s %s", user, fn, src);
|
||||
rc = systemf("curl %s -Lo %s %s", remote_user, fn, src);
|
||||
if (rc) {
|
||||
fprintf(stderr, ERRMSG "failed downloading %s", src);
|
||||
} else {
|
||||
@@ -274,7 +345,7 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
}
|
||||
}
|
||||
|
||||
rc = systemf("curl %s -Lo %s %s", user, fn, src);
|
||||
rc = systemf("curl %s -Lo %s %s", remote_user, fn, src);
|
||||
} else if (strstr(dst, "://")) {
|
||||
fn = cfg_adjust(src, NULL, adjust, sizeof(adjust));
|
||||
if (!fn) {
|
||||
@@ -286,7 +357,7 @@ static int copy(const char *src, const char *dst, const char *user)
|
||||
if (access(fn, F_OK))
|
||||
fprintf(stderr, ERRMSG "no such file %s, aborting.", fn);
|
||||
else
|
||||
rc = systemf("curl %s -LT %s %s", user, fn, dst);
|
||||
rc = systemf("curl %s -LT %s %s", remote_user, fn, dst);
|
||||
} else {
|
||||
if (!access(dst, F_OK)) {
|
||||
if (!yorn("Overwrite existing file %s", dst)) {
|
||||
@@ -347,7 +418,7 @@ int main(int argc, char *argv[])
|
||||
if (timeout < 0)
|
||||
timeout = 120;
|
||||
|
||||
if (optind >= argc)
|
||||
if (argc - optind != 2)
|
||||
return usage(1);
|
||||
|
||||
src = argv[optind++];
|
||||
|
||||
@@ -28,6 +28,10 @@ int files(const char *path, const char *stripext)
|
||||
if (d->d_type != DT_REG || d->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
/* skip startup in /cfg, listed by plugin */
|
||||
if (!strcmp(path, "/cfg") && !strcmp(d->d_name, "startup-config.cfg"))
|
||||
continue;
|
||||
|
||||
strlcpy(name, d->d_name, sizeof(name));
|
||||
if (stripext) {
|
||||
size_t pos = has_ext(name, stripext);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2024 The KernelKit Authors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1 @@
|
||||
dtb-y += freescale/imx8mp-evk.dtb
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <arm64/freescale/imx8mp-evk.dts>
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
infix {
|
||||
/* "admin" */
|
||||
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
|
||||
};
|
||||
};
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"eth0": {
|
||||
"phy-detached-when-down": true
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ do_prune()
|
||||
local keep=${1:-10}
|
||||
|
||||
cd "$basedir"
|
||||
rm -f old=$(ls -rv *.tar.gz | tail "+$((keep + 1))")
|
||||
rm -f old=$(ls -rv *.tar.gz 2>/dev/null | tail "+$((keep + 1))")
|
||||
}
|
||||
|
||||
usage()
|
||||
|
||||
@@ -56,16 +56,6 @@ EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
iftype()
|
||||
{
|
||||
iftype=$(ip -d -j link show "$1" |jq -r .[].parentbus)
|
||||
if [ "$iftype" = "virtio" ]; then
|
||||
echo "infix-if-type:etherlike"
|
||||
else
|
||||
echo "infix-if-type:ethernet"
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC3043
|
||||
gen_iface_json()
|
||||
{
|
||||
@@ -75,7 +65,7 @@ gen_iface_json()
|
||||
cat <<EOF
|
||||
,{
|
||||
"name": "$ifname",
|
||||
"type": "$(iftype "$ifname")",
|
||||
"type": "infix-if-type:ethernet",
|
||||
EOF
|
||||
|
||||
if [ -n "$br" ]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
AC_PREREQ(2.61)
|
||||
# confd version is same as system YANG model version, step on breaking changes
|
||||
AC_INIT([confd], [1.4], [https://github.com/kernelkit/infix/issues])
|
||||
AC_INIT([confd], [1.5], [https://github.com/kernelkit/infix/issues])
|
||||
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
|
||||
AM_SILENT_RULES(yes)
|
||||
|
||||
@@ -18,6 +18,7 @@ AC_CONFIG_FILES([
|
||||
share/migrate/1.2/Makefile
|
||||
share/migrate/1.3/Makefile
|
||||
share/migrate/1.4/Makefile
|
||||
share/migrate/1.5/Makefile
|
||||
src/Makefile
|
||||
yang/Makefile
|
||||
])
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "ietf-crypto-types:ssh-public-key-format",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "ietf-crypto-types:rsa-private-key-format",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# Rename SSH key type in keystore, from ietf-crypto-types to infix-crypto-types
|
||||
#
|
||||
|
||||
file=$1
|
||||
temp=${file}.tmp
|
||||
|
||||
jq '.["ietf-keystore:keystore"]["asymmetric-keys"]["asymmetric-key"][] |= (
|
||||
.["public-key-format"] |= sub("ietf-crypto-types";"infix-crypto-types") |
|
||||
.["private-key-format"] |= sub("ietf-crypto-types";"infix-crypto-types"))' "$file" > "$temp" &&
|
||||
mv "$temp" "$file"
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# Rename interface type etherlike => ethernet
|
||||
#
|
||||
|
||||
file=$1
|
||||
temp=${file}.tmp
|
||||
|
||||
jq '(.["ietf-interfaces:interfaces"].interface[] | select(.type == "infix-if-type:etherlike") .type) |= "infix-if-type:ethernet"' "$file" > "$temp" &&
|
||||
mv "$temp" "$file"
|
||||
@@ -0,0 +1,2 @@
|
||||
migratedir = $(pkgdatadir)/migrate/1.5
|
||||
dist_migrate_DATA = 10-change-key-types.sh 11-rename-etherlike.sh
|
||||
@@ -1,2 +1,2 @@
|
||||
SUBDIRS = 1.0 1.1 1.2 1.3 1.4
|
||||
SUBDIRS = 1.0 1.1 1.2 1.3 1.4 1.5
|
||||
migratedir = $(pkgdatadir)/migrate
|
||||
|
||||
@@ -30,6 +30,7 @@ confd_plugin_la_SOURCES = \
|
||||
ieee802-ethernet-interface.c \
|
||||
ietf-ip.c \
|
||||
infix-if-bridge.c \
|
||||
infix-if-lag.c \
|
||||
infix-if-bridge-mcd.c \
|
||||
infix-if-bridge-port.c \
|
||||
infix-if-veth.c \
|
||||
|
||||
+7
-8
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "core.h"
|
||||
#include "cni.h"
|
||||
#include "ietf-interfaces.h"
|
||||
|
||||
#define CNI_NAME "/etc/cni/net.d/%s.conflist"
|
||||
|
||||
@@ -86,13 +87,13 @@ FILE *cni_popen(const char *fmt, const char *ifname)
|
||||
return popenf("re", "nsenter -t %d -n %s", pid, cmd);
|
||||
}
|
||||
|
||||
static bool iface_is_cni(const char *ifname, struct lyd_node *node, const char **type)
|
||||
static bool iface_is_cni(const char *ifname, struct lyd_node *node, enum iftype *type)
|
||||
{
|
||||
struct lyd_node *net = lydx_get_child(node, "container-network");
|
||||
|
||||
if (net) {
|
||||
if (type)
|
||||
*type = lydx_get_cattr(net, "type");
|
||||
*type = iftype_from_iface(net);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -365,9 +366,7 @@ static int iface_gen_cni(const char *ifname, struct lyd_node *cif)
|
||||
* "container-network": {}, so someone does their job.
|
||||
*/
|
||||
if (!type) {
|
||||
const char *iftype = lydx_get_cattr(cif, "type");
|
||||
|
||||
if (iftype && !strcmp(iftype, "infix-if-type:bridge"))
|
||||
if (iftype_from_iface(cif) == IFT_BRIDGE)
|
||||
type = "infix-interfaces:bridge";
|
||||
else
|
||||
type = "infix-interfaces:host";
|
||||
@@ -386,7 +385,7 @@ static int iface_gen_cni(const char *ifname, struct lyd_node *cif)
|
||||
int cni_netdag_gen_iface(struct dagger *net, const char *ifname,
|
||||
struct lyd_node *dif, struct lyd_node *cif)
|
||||
{
|
||||
const char *cni_type = NULL;
|
||||
enum iftype cni_type;
|
||||
FILE *fp;
|
||||
|
||||
if (iface_is_cni(ifname, cif, &cni_type)) {
|
||||
@@ -403,7 +402,7 @@ int cni_netdag_gen_iface(struct dagger *net, const char *ifname,
|
||||
err = iface_gen_cni(ifname, cif);
|
||||
if (err)
|
||||
return err;
|
||||
if (cni_type && !strcmp(cni_type, "bridge"))
|
||||
if (cni_type == IFT_BRIDGE)
|
||||
return 1; /* CNI bridges are managed by podman */
|
||||
} else if (iface_is_cni(ifname, dif, &cni_type)) {
|
||||
/* No longer a container-network, clean up. */
|
||||
@@ -414,7 +413,7 @@ int cni_netdag_gen_iface(struct dagger *net, const char *ifname,
|
||||
fprintf(fp, "container -a -f delete network %s >/dev/null\n", ifname);
|
||||
fclose(fp);
|
||||
|
||||
if (cni_type && !strcmp(cni_type, "bridge"))
|
||||
if (cni_type == IFT_BRIDGE)
|
||||
return 1; /* CNI bridges are managed by podman */
|
||||
}
|
||||
|
||||
|
||||
+16
-15
@@ -56,7 +56,7 @@ int core_pre_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
int core_post_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
|
||||
{
|
||||
static int num_changes = 0;
|
||||
static size_t num_changes = 0;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_CHANGE:
|
||||
@@ -66,28 +66,23 @@ int core_post_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *modul
|
||||
num_changes = 0;
|
||||
return SR_ERR_OK;
|
||||
case SR_EV_DONE:
|
||||
if (num_changes <= 0) {
|
||||
ERROR("BUG in core_post_hook(): callback tracking out of sync");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (--num_changes == 0)
|
||||
break;
|
||||
|
||||
return SR_ERR_OK;
|
||||
num_changes--;
|
||||
if (num_changes > 0)
|
||||
return SR_ERR_OK;
|
||||
break;
|
||||
default:
|
||||
ERROR("core_post_hook() should not be called with event %s", ev2str(event));
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
/* Everything done, including interfaces, launch all container scripts */
|
||||
infix_containers_post_hook(session, priv);
|
||||
|
||||
/* skip reload in bootstrap, implicit reload in runlevel change */
|
||||
if (systemf("runlevel >/dev/null 2>&1"))
|
||||
if (systemf("runlevel >/dev/null 2>&1")) {
|
||||
/* trigger any tasks waiting for confd to have applied *-config */
|
||||
system("initctl -nbq cond set bootstrap");
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
if (systemf("initctl -nbq reload"))
|
||||
if (systemf("initctl -b reload"))
|
||||
return SR_ERR_SYS;
|
||||
|
||||
return SR_ERR_OK;
|
||||
@@ -131,6 +126,12 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
|
||||
confd.root = json_load_file("/run/system.json", 0, NULL);
|
||||
if (!confd.root)
|
||||
goto err;
|
||||
|
||||
/* An optional file that contains hardware specific quirks for
|
||||
* the network interfaces on running board.
|
||||
*/
|
||||
confd.ifquirks = json_load_file("/etc/product/interface-quirks.json", 0, NULL);
|
||||
|
||||
rc = ietf_interfaces_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
@@ -124,6 +124,7 @@ struct confd {
|
||||
sr_subscription_ctx_t *sub;
|
||||
sr_subscription_ctx_t *fsub; /* factory-default sub */
|
||||
json_t *root;
|
||||
json_t *ifquirks;
|
||||
struct dagger netdag;
|
||||
};
|
||||
|
||||
@@ -212,13 +213,9 @@ int hostnamefmt (struct confd *confd, const char *fmt, char *hostnm, size_t
|
||||
|
||||
/* infix-containers.c */
|
||||
#ifdef CONTAINERS
|
||||
int infix_containers_init(struct confd *confd);
|
||||
void infix_containers_pre_hook(sr_session_ctx_t *session, struct confd *confd);
|
||||
void infix_containers_post_hook(sr_session_ctx_t *session, struct confd *confd);
|
||||
int infix_containers_init(struct confd *confd);
|
||||
#else
|
||||
static inline int infix_containers_init(struct confd *confd) { return 0; }
|
||||
static inline void infix_containers_pre_hook(sr_session_ctx_t *session, struct confd *confd) {}
|
||||
static inline void infix_containers_post_hook(sr_session_ctx_t *session, struct confd *confd) {}
|
||||
static inline int infix_containers_init(struct confd *confd) { return 0; }
|
||||
#endif
|
||||
|
||||
/* infix-dhcp-common.c */
|
||||
|
||||
+25
-23
@@ -87,10 +87,32 @@ FILE *dagger_fopen_net_exit(struct dagger *d, const char *node, enum netdag_exit
|
||||
return dagger_fopen_current(d, "exit", node, order, script);
|
||||
}
|
||||
|
||||
int dagger_add_dep(struct dagger *d, const char *depender, const char *dependee)
|
||||
int dagger_add_dep(const struct dagger *d, const char *depender, const char *dependee)
|
||||
{
|
||||
return systemf("ln -s ../%s %s/%d/dag/%s", dependee,
|
||||
d->path, d->next, depender);
|
||||
char link[strlen(d->path) + strlen(depender) + strlen(dependee) + 16];
|
||||
char target[strlen(dependee) + 16];
|
||||
char path[strlen(dependee) + 16];
|
||||
ssize_t len;
|
||||
|
||||
/*
|
||||
* Some callbacks may run twice, double check symlink, if it
|
||||
* exists already and points to the same target, we're OK.
|
||||
*/
|
||||
snprintf(target, sizeof(target), "../%s", dependee);
|
||||
snprintf(link, sizeof(link), "%s/%d/dag/%s/%s", d->path, d->next, depender, dependee);
|
||||
|
||||
len = readlink(link, path, sizeof(path));
|
||||
if (len > 0) {
|
||||
path[len] = 0;
|
||||
if (strcmp(target, path)) {
|
||||
ERROR("Dagger dependency already exists %s -> %s", target, path);
|
||||
return errno = EEXIST;
|
||||
}
|
||||
|
||||
return 0; /* same, ignore */
|
||||
}
|
||||
|
||||
return symlink(target, link);
|
||||
}
|
||||
|
||||
int dagger_add_node(struct dagger *d, const char *node)
|
||||
@@ -155,26 +177,6 @@ int dagger_evolve_or_abandon(struct dagger *d)
|
||||
return err;
|
||||
}
|
||||
|
||||
void dagger_skip_iface(struct dagger *d, const char *ifname)
|
||||
{
|
||||
touchf("%s/%d/skip/%s", d->path, d->next, ifname);
|
||||
}
|
||||
|
||||
void dagger_skip_current_iface(struct dagger *d, const char *ifname)
|
||||
{
|
||||
touchf("%s/%d/skip/%s", d->path, d->current, ifname);
|
||||
}
|
||||
|
||||
int dagger_should_skip(struct dagger *d, const char *ifname)
|
||||
{
|
||||
return fexistf("%s/%d/skip/%s", d->path, d->next, ifname);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -21,16 +21,12 @@ FILE *dagger_fopen_next(struct dagger *d, const char *action, const char *node,
|
||||
FILE *dagger_fopen_current(struct dagger *d, const char *action, const char *node,
|
||||
unsigned char prio, const char *script);
|
||||
|
||||
int dagger_add_dep(struct dagger *d, const char *depender, const char *dependee);
|
||||
int dagger_add_dep(const struct dagger *d, const char *depender, const char *dependee);
|
||||
int dagger_add_node(struct dagger *d, const char *node);
|
||||
int dagger_abandon(struct dagger *d);
|
||||
int dagger_evolve(struct dagger *d);
|
||||
int dagger_evolve_or_abandon(struct dagger *d);
|
||||
|
||||
void dagger_skip_iface(struct dagger *d, const char *ifname);
|
||||
void dagger_skip_current_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);
|
||||
|
||||
@@ -35,12 +35,16 @@ static bool iface_uses_autoneg(struct lyd_node *cif)
|
||||
static int netdag_gen_ethtool_flow_control(struct dagger *net, struct lyd_node *cif)
|
||||
{
|
||||
const char *ifname = lydx_get_cattr(cif, "name");
|
||||
enum netdag_init phase = NETDAG_INIT_PHYS;
|
||||
FILE *fp;
|
||||
|
||||
fp = dagger_fopen_net_init(net, ifname, NETDAG_INIT_PHYS, "ethtool-aneg.sh");
|
||||
if (iface_has_quirk(ifname, "phy-detached-when-down"))
|
||||
phase = NETDAG_INIT_POST;
|
||||
|
||||
fp = dagger_fopen_net_init(net, ifname, phase, "ethtool-flow-control.sh");
|
||||
if (!fp)
|
||||
return -EIO;
|
||||
|
||||
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supported-pause-frame-use\" == \"No\")') ]] && exit 0\n", ifname);
|
||||
fprintf(fp, "ethtool --pause %s autoneg %s rx off tx off\n",
|
||||
ifname, iface_uses_autoneg(cif) ? "on" : "off");
|
||||
fclose(fp);
|
||||
@@ -52,18 +56,22 @@ static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
|
||||
{
|
||||
struct lyd_node *eth = lydx_get_child(cif, "ethernet");
|
||||
const char *ifname = lydx_get_cattr(cif, "name");
|
||||
enum netdag_init phase = NETDAG_INIT_PHYS;
|
||||
const char *speed, *duplex;
|
||||
int mbps, err = 0;
|
||||
FILE *fp;
|
||||
|
||||
fp = dagger_fopen_net_init(net, ifname, NETDAG_INIT_PHYS, "ethtool-aneg.sh");
|
||||
if (iface_has_quirk(ifname, "phy-detached-when-down"))
|
||||
phase = NETDAG_INIT_POST;
|
||||
|
||||
fp = dagger_fopen_net_init(net, ifname, phase, "ethtool-aneg.sh");
|
||||
if (!fp)
|
||||
return -EIO;
|
||||
|
||||
fprintf(fp, "ethtool --change %s autoneg ", ifname);
|
||||
|
||||
if (iface_uses_autoneg(cif)) {
|
||||
fputs("on\n", fp);
|
||||
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supports-auto-negotiation\" == false)') ]] && exit 0\n", ifname);
|
||||
fprintf(fp, "ethtool --change %s autoneg on", ifname);
|
||||
} else {
|
||||
speed = lydx_get_cattr(eth, "speed");
|
||||
if (!speed) {
|
||||
@@ -93,7 +101,7 @@ static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
|
||||
goto out;
|
||||
}
|
||||
|
||||
fprintf(fp,"off speed %d duplex %s\n", mbps, duplex);
|
||||
fprintf(fp,"ethtool --change %s autoneg off speed %d duplex %s\n", ifname, mbps, duplex);
|
||||
}
|
||||
out:
|
||||
fclose(fp);
|
||||
@@ -104,7 +112,6 @@ out:
|
||||
int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node *dif)
|
||||
{
|
||||
struct lyd_node *eth = lydx_get_child(dif, "ethernet");
|
||||
const char *type = lydx_get_cattr(cif, "type");
|
||||
int err;
|
||||
|
||||
/*
|
||||
@@ -121,7 +128,7 @@ int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node
|
||||
*
|
||||
* Hence this "redundant" check.
|
||||
*/
|
||||
if (strcmp(type, "infix-if-type:ethernet"))
|
||||
if (iftype_from_iface(cif) != IFT_ETH)
|
||||
return 0;
|
||||
|
||||
if (!eth)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user