Compare commits

..
1 Commits
Author SHA1 Message Date
Joachim Wiberg 6f210174c2 package/skeleton-init-finit: enable rngd by default
Platforms with /dev/hwrandom use that to see /dev/urandom.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-11-05 13:32:38 +01:00
114 changed files with 1367 additions and 3021 deletions
-1
View File
@@ -33,4 +33,3 @@ Releases
- Easy to forget adaptations/hacks in customer repos -- may need Infix change/support
- Ensure the markdown link for the release diff is updated
- Ensure subrepos are tagged (can be automated, see kernelkit/infix#393)
- Sync tags for all repo. sync activities
+1 -4
View File
@@ -101,7 +101,6 @@ jobs:
runs-on: [ self-hosted, release ]
permissions:
contents: write
discussions: write
steps:
- uses: actions/checkout@v4
with:
@@ -116,14 +115,12 @@ jobs:
ver=${GITHUB_REF#refs/tags/}
fi
echo "ver=${ver}" >> $GITHUB_OUTPUT
echo "cat=" >> $GITHUB_OUTPUT
if echo $ver | grep -qE 'v[0-9.]+(-alpha|-beta|-rc)[0-9]*'; then
echo "pre=true" >> $GITHUB_OUTPUT
echo "latest=false" >> $GITHUB_OUTPUT
elif echo $ver | grep -qE '^v[0-9.]+\.[0-9.]+(\.[0-9]+)?$'; then
echo "pre=false" >> $GITHUB_OUTPUT
echo "latest=true" >> $GITHUB_OUTPUT
echo "cat=Releases" >> $GITHUB_OUTPUT
else
echo "pre=false" >> $GITHUB_OUTPUT
echo "latest=false" >> $GITHUB_OUTPUT
@@ -153,7 +150,7 @@ jobs:
name: Infix ${{ github.ref_name }}
prerelease: ${{ steps.rel.outputs.pre }}
makeLatest: ${{ steps.rel.outputs.latest }}
discussionCategory: ${{ steps.rel.outputs.cat }}
discussionCategory: Releases
bodyFile: release.md
artifacts: "*.tar.gz*"
+4 -28
View File
@@ -265,38 +265,14 @@
};
};
#define SWP_LED \
#define SWP_LED(_func) \
leds { \
#address-cells = <1>; \
#size-cells = <0>; \
\
led@0 { \
reg = <0>; \
function = "tp"; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "keep"; \
}; \
led@1 { \
reg = <1>; \
function = "aux"; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "off"; \
}; \
}
/* SFP LEDs
* Rev A. LEDs do not work at all
* Rev B. only outer-most (green) LEDs work
*/
#define SFP_LED \
leds { \
#address-cells = <1>; \
#size-cells = <0>; \
\
led@0 { \
reg = <0>; \
function = "sfp"; \
function = _func; \
color = <LED_COLOR_ID_GREEN>; \
default-state = "keep"; \
}; \
@@ -311,7 +287,7 @@
phy-mode = "10gbase-r"; \
managed = "in-band-status"; \
sfp = <_sfp>; \
SFP_LED; \
SWP_LED("sfp"); \
}
#define XSWCPU(_n, _eth) \
@@ -345,7 +321,7 @@
nvmem-cell-names = "mac-address"; \
phy-mode = "gmii"; \
phy-handle = <_phy>; \
SWP_LED; \
SWP_LED("tp"); \
}
#define GPHY(_n) \
@@ -1,111 +0,0 @@
#!/bin/sh
# Raw switch LED Control for systems that do not run iitod
LEDS=$(find /sys/class/leds -iname '*mdio-mii*')
LINK=$(find /sys/class/leds -iname '*mdio-mii*p')
# Disable ALL switch port LEDs
clear()
{
for led in $LEDS; do
echo 0 > "${led}/brightness"
done
}
setup()
{
for led in $LINK; do
echo netdev > "${led}/trigger"
done
for led in $LINK; do
cd "$led"
# No sleep here, it's enough with the delay from previous loop
echo 1 > link
sleep 0.1
echo 1 > rx
sleep 0.1
echo 1 > tx
cd - >/dev/null
done
}
leds()
{
for led in $LINK; do
printf "%3s: %s\n" "$(cat "$led/device_name" 2>/dev/null)" "$led"
done
}
list()
{
leds | sort | while read -r port path; do
printf "%4s %s\n" "$port" "$(basename "$path")"
aux=${path%%:tp}:aux
if [ -e "$aux" ]; then
printf "%3s: %s\n" "" "$(basename "$aux")"
fi
done
}
flash()
{
sec=$1
for led in $LEDS; do
echo timer > "${led}/trigger"
done
for led in $LEDS; do
echo 84 > "${led}/delay_on"
echo 84 > "${led}/delay_off"
done
sleep "$sec"
clear
}
usage()
{
echo "usage: $0 [command]"
echo
echo "flash [SEC] Flash all LEDs to locate device in rack, default: 5 sec"
echo "list List all LEDs"
echo "setup Set up and start normal operation"
echo "start Call at system init, clears all LEDs and sets up normal op"
echo "stop Clear all LEDs, may be called at system shutdown"
echo
echo "Please ensure no other tool or daemon is already managing the LEDs."
}
cmd=$1; shift
case $cmd in
flash)
flash ${1:-5}
setup
;;
help)
usage
exit 0
;;
list | ls)
list
;;
setup)
setup
;;
start)
initctl -nbq cond clear led
clear
setup
;;
stop)
clear
;;
*)
usage
exit 1
;;
esac
@@ -1 +0,0 @@
/usr/libexec/styx/led.sh
-1
View File
@@ -1 +0,0 @@
RAUC_ARGS="-s"
@@ -1,4 +1,4 @@
service :%i pid:!/run/k8s-logger-%i.pid <usr/container:%i> \
[2345] k8s-logger -cni %i -f local1 /run/containers/%i.fifo -- Logger for container %i
sysv :%i pid:!/run/container:%i.pid <!pid/k8s-logger:%i> log kill:10 \
sysv :%i pid:!/run/container:%i.pid <pid/k8s-logger:%i> log kill:10 \
[2345] container -n %i -- container %i
-1
View File
@@ -1 +0,0 @@
/var/lib/dbus/machine-id
@@ -1 +1,2 @@
alias cli='clish'
alias cfg='sysrepocfg -f json'
-58
View File
@@ -1,58 +0,0 @@
#!/bin/sh
# User-friendly wrapper for sysrepocfg
# TODO: add import/export, copy, ...
# Edit YANG binary types using sysrepo, base64, and duct tape.
edit()
{
xpath=$1
if [ -z "$xpath" ]; then
echo "Usage: cfg edit \"/full/xpath/to/binary/leaf\""
exit 1
fi
if tmp=$(sysrepocfg -G "$xpath"); then
file=$(mktemp)
echo "$tmp" | base64 -d > "$file"
if /usr/bin/editor "$file"; then
tmp=$(base64 -w0 < "$file")
sysrepocfg -S "$xpath" -u "$tmp"
fi
rm -f "$file"
else
echo "Failed to retrieve value for $xpath"
exit 1
fi
}
usage()
{
echo "Usage:"
echo " cfg CMD [ARG]"
echo
echo "Command:"
echo " edit XPATH Edit YANG binary type"
echo " help This help text"
echo
echo "As a backwards compatible fallback, this script forwards"
echo "all other commands as options to sysrepocfg."
echo
exit 0
}
cmd=$1; shift
case $cmd in
edit)
edit "$1"
;;
help)
usage
;;
*)
set -- "$cmd" "$@"
exec sysrepocfg -f json "$@"
;;
esac
-13
View File
@@ -1,13 +0,0 @@
#!/bin/sh
# -d ;; suppress error message "the terminal is dumb"
# -F :: exit if the entire file can be displayed on the first screen
# -I :: Ignore case, even for patterns
# -K :: exit immediately when an interrupt character (usually ^C) is typed
# -R :: Almost raw control charachters, only ANSI color escape sequences and
# OSC 8 hyperlink sequences are output. Allows veritcal scrolling
# -S :: lines longer than the screen width are chopped (truncated), not wrapped
# -X :: No termcap initialization and deinitialization set to the terminal.
# This is what leaves the contents of the output on screen.
export LESS="-P %f (press h for help or q to quit)"
less -RISKd -FX "$@"
+1
View File
@@ -0,0 +1 @@
less
@@ -1,2 +1 @@
d /var/run/frr 0755 frr frr -
R /var/tmp/frr - - - -
@@ -8,11 +8,10 @@ import struct
import subprocess
import sys
onieprom = importlib.machinery.SourceFileLoader("onieprom", "/bin/onieprom").load_module()
SYSTEM_JSON = "/run/system.json"
onieprom = importlib.machinery.SourceFileLoader("onieprom","/bin/onieprom").load_module()
SYSTEM_JSON = "/run/system.json"
KKIT_IANA_PEM = 61046
class DTSystem:
BASE = "/sys/firmware/devicetree/base"
INFIX = BASE + "/chosen/infix"
@@ -29,9 +28,7 @@ class DTSystem:
if not os.path.exists(phandle):
continue
with open(phandle, "rb") as f:
data = f.read()
ph, = struct.unpack(">L", data)
ph, = struct.unpack(">L", open(phandle, "rb").read())
dt[ph] = root
sys = {}
@@ -43,18 +40,14 @@ class DTSystem:
if not os.path.exists(phandle):
continue
with open(phandle, "rb") as f:
data = f.read()
ph, = struct.unpack(">L", data)
ph, = struct.unpack(">L", open(phandle, "rb").read())
if ph not in sys:
sys[ph] = []
sys[ph].append(root)
phs = set(list(dt.keys()) + list(sys.keys()))
self.devs = {ph: [Device(ph, dt.get(ph), s if s is not None else "")
for s in (sys.get(ph) or []) if ph is not None]
for ph in phs}
self.devs = { ph: [Device(ph, dt.get(ph), s if s is not None else "") for s in (sys.get(ph) or []) if ph is not None] for ph in phs }
self.base = Device(0, None, DTSystem.BASE)
self.infix = Device(0, None, DTSystem.INFIX)
@@ -63,8 +56,7 @@ class DTSystem:
if not os.path.exists(path):
return ()
with open(path, "rb") as f:
data = f.read()
data = open(path, "rb").read()
elems = len(data) // struct.calcsize(">L")
return struct.unpack(">" + elems * "L", data)
@@ -77,8 +69,7 @@ class DTSystem:
return {}
try:
with open(dev.attrpath("nvmem"), "rb", 0) as f:
data = onieprom.from_tlv(f)
data = onieprom.from_tlv(open(dev.attrpath("nvmem"), "rb", 0))
except:
data = {}
@@ -93,18 +84,14 @@ class DTSystem:
}
def infix_usb_devices(self, out):
names = self.infix.str_array("usb-port-names", ())
phs = self.__get_phandle_array("usb-ports")
data = dict(zip(names, phs))
names=self.infix.str_array("usb-port-names", ())
phs=self.__get_phandle_array("usb-ports")
data=dict(zip(names,phs))
if data != {}:
out["usb-ports"] = []
for name, ph in data.items():
[out["usb-ports"].extend([{
"name": name,
"path": dev.attrpath("authorized")}, {
"name": name,
"path": dev.attrpath("authorized_default")
}]) for dev in self.devices_from_ph(ph)]
for name,ph in data.items():
[out["usb-ports"].extend([{"name": name, "path": dev.attrpath("authorized")}, {"name": name, "path": dev.attrpath("authorized_default")}]) for dev in self.devices_from_ph(ph)]
def infix_devices(self, kind):
phs = self.__get_phandle_array(kind)
@@ -114,7 +101,6 @@ class DTSystem:
flat_devices = [device for sublist in self.infix_devices("vpds") for device in sublist]
return [self.into_vpd(device) for device in flat_devices]
class QEMUSystem:
BASE = "/sys/firmware/qemu_fw_cfg"
REV = BASE + "/rev"
@@ -124,8 +110,7 @@ class QEMUSystem:
data = {}
if os.path.exists(QEMUSystem.VPD):
try:
with open(QEMUSystem.VPD, "rb", 0) as f:
data = onieprom.from_tlv(f)
data = onieprom.from_tlv(open(QEMUSystem.VPD, "rb", 0))
except:
pass
@@ -142,27 +127,31 @@ class QEMUSystem:
def usb_ports(self):
ports = [
{
"name": "USB",
"path": "/sys/bus/usb/devices/usb1/authorized"
}, {
"name": "USB",
"path": "/sys/bus/usb/devices/usb1/authorized_default"
}, {
"name": "USB2",
"path": "/sys/bus/usb/devices/usb2/authorized"
}, {
"name": "USB2",
"path": "/sys/bus/usb/devices/usb2/authorized_default"
}]
"name": "USB",
"path": "/sys/bus/usb/devices/usb1/authorized"
},
{
"name": "USB",
"path": "/sys/bus/usb/devices/usb1/authorized_default"
},
{
"name": "USB2",
"path": "/sys/bus/usb/devices/usb2/authorized"
},
{
"name": "USB2",
"path": "/sys/bus/usb/devices/usb2/authorized_default"
}]
return ports
class Device:
def __init__(self, ph, dtpath, syspath):
self.ph, self.dtpath, self.syspath = ph, dtpath, syspath
def available(self):
return self.syspath is not None
return self.syspath != None
def __getitem__(self, attr):
return self.attr(attr).decode("utf-8").strip("\0")
@@ -170,6 +159,7 @@ class Device:
def __setitem__(self, attr, value):
return self.attr(attr, val=value.encode("utf-8"))
def attrpath(self, attr):
return os.path.join(self.syspath, attr)
@@ -178,16 +168,13 @@ class Device:
def attr(self, attr, default=None, val=None):
if not self.hasattr(attr):
return default if val is None else False
return default if val == None else False
if val:
with open(self.attrpath(attr), "wb") as f:
f.write(val)
open(self.attrpath(attr), "wb").write(value)
return True
with open(self.attrpath(attr), "rb") as f:
data = f.read()
return data
return open(self.attrpath(attr), "rb").read()
def str(self, attr, default=None):
val = self.attr(attr)
@@ -207,9 +194,7 @@ class Device:
if not self.hasdtattr(attr):
return default
with open(self.dtattrpath(attr), "rb") as f:
data = f.read()
return data
return open(self.dtattrpath(attr), "rb").read()
def dtstr(self, attr, default=None):
val = self.dtattr(attr)
@@ -227,7 +212,6 @@ def vpd_get_json_ve(vpd, pem):
return out
def vpd_get_pwhash(vpd):
if not vpd.get("trusted"):
return None
@@ -235,9 +219,8 @@ def vpd_get_pwhash(vpd):
kkit = vpd_get_json_ve(vpd, KKIT_IANA_PEM)
return kkit.get("pwhash")
def vpd_inject(out, vpds):
out["vpd"] = {vpd["board"]: vpd for vpd in vpds}
out["vpd"] = { vpd["board"]: vpd for vpd in vpds }
product = out["vpd"].get("product", {}).get("data", {})
hoistattrs = ("vendor", "product-name", "part-number", "serial-number", "mac-address")
@@ -251,7 +234,6 @@ def vpd_inject(out, vpds):
out["factory-password-hash"] = pwhash
break
def qemu_base_mac():
"""Find MAC address of first non-loopback interface, subtract with 1"""
base_path = '/sys/class/net'
@@ -262,8 +244,7 @@ def qemu_base_mac():
continue
try:
# pylint: disable=invalid-name
fn = os.path.join(base_path, iface, 'address')
with open(fn, 'r', encoding='ascii') as f:
with open(os.path.join(base_path, iface, 'address'), 'r', encoding='ascii') as f:
mac = f.read().strip()
interfaces.append((mac, iface))
except FileNotFoundError:
@@ -280,7 +261,6 @@ def qemu_base_mac():
return None
def probe_qemusystem(out):
"""Probe Qemu based test systems and 'make run'"""
admin_hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
@@ -308,7 +288,6 @@ def probe_qemusystem(out):
subprocess.run("initctl -nbq cond set qemu".split(), check=False)
return 0
def probe_dtsystem(out):
"""Probe DTS based system, expects a VPD in ONIE PROM format."""
dtsys = DTSystem()
@@ -318,8 +297,6 @@ def probe_dtsystem(out):
if model:
out["product-name"] = model
out["compatible"] = dtsys.base.str_array("compatible")
staticpw = dtsys.infix.str("factory-password-hash")
if not out["factory-password-hash"]:
out["factory-password-hash"] = staticpw
@@ -327,7 +304,6 @@ def probe_dtsystem(out):
vpd_inject(out, vpds)
return 0
def main():
out = {
"vendor": None,
@@ -362,6 +338,5 @@ def main():
shutil.chown(SYSTEM_JSON, user="root", group="wheel")
return err
if __name__ == "__main__":
sys.exit(main())
@@ -1,48 +1,22 @@
#!/bin/sh
# Find, install, and run product specific files and script in /etc
# before resuming bootstrap.
#
# Use /etc/product/init.d/S01-myscript for scripts, may be a symlink, it
# will be called with `start` as its only argument.
#
# The compatible array is listed in the same order as the device tree,
# most significant to least. Hence the reverse.[], to ensure overrides
# are applied in order of significance.
# Find and install any product specific files in /etc before bootstrap
ident=$(basename "$0")
PRODUCT_INIT=/etc/product/init.d
PREFIXD=/usr/share/product
COMPATIBLES=$(jq -r '.compatible | reverse.[] | ascii_downcase' /run/system.json)
PRODUCT=$(jq -r '."product-name" | ascii_downcase' /run/system.json)
note()
{
logger -I $$ -k -p user.notice -t "$ident" "$1"
}
found=false
for PRODUCT in $COMPATIBLES; do
DIR="$PREFIXD/$PRODUCT"
if [ -d "$DIR" ]; then
note "Using vendor/product-specific defaults for $PRODUCT."
for dir in "$DIR"/*; do
[ -d "$dir" ] && cp -a "$dir" /
done
found=true
fi
done
if [ "$found" = false ]; then
note "No vendor/product-specific directory found, using built-in defaults."
DIR="$PREFIXD/$PRODUCT"
if [ -z "$PRODUCT" ] || [ ! -d "$DIR" ]; then
note "No vendor/product specific directory found, using built-in defaults."
exit 0
fi
# Conditions for bootstrap services, this enables product specific
# init scripts to prevent select services from starting.
initctl -nbq cond set led
note "Calling runparts $PRODUCT_INIT/S[0-9]+.* start"
/usr/libexec/finit/runparts -bsp "$PRODUCT_INIT"
# Product specific init done.
initctl -nbq cond set product
exit 0
note "Using vendor/product specific defaults."
for dir in "$DIR"/*; do
[ -d "$dir" ] && cp -a "$dir" /
done
@@ -46,11 +46,7 @@ while [ "$1" ]; do
[ $txqs -lt 2 ] && continue
[ $txqs -gt 8 ] && txqs=8
output=$(tc qdisc add dev $iface root mqprio hw 1 \
num_tc $txqs $(map $txqs) $(queues $txqs) 2>&1) || true
if echo "$output" | grep -q "does not support hardware offload"; then
echo "Skipping $iface, hardware offload not supported."
elif [ -n "$output" ]; then
echo "$output"
fi
tc qdisc add dev $iface root mqprio hw 1 \
num_tc $txqs $(map $txqs) $(queues $txqs) || true
done
@@ -1,2 +1,2 @@
#!/bin/sh
exec initctl -bq cond set ixinit
exec initctl -bq cond set ixinit-done
@@ -45,6 +45,11 @@ factory_reset()
find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \;
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
# Shred all files to prevent restoring contents
find /mnt/cfg -type f -exec shred -zu {} \;
find /mnt/var -type f -exec shred -zu {} \;
# Remove any lingering directories and symlinks as well
rm -rf /mnt/cfg/* /mnt/var/*
logger $opt -p user.crit -t "$nm" "Factory reset complete."
+52 -175
View File
@@ -1,18 +1,5 @@
#!/bin/sh
# This script can be used to start, stop, create, and delete containers.
# It is primarily used by confd to create jobs for execd to run from its
# /run/containers/queue, but it can also be used manually.
#
# NOTE: when creating/deleting containers, remember 'initctl reload' to
# activate the changes! When called by confd, via execd, this is
# already handled.
#
DOWNLOADS=/var/lib/containers/oci
BUILTIN=/lib/oci
TMPDIR=/var/tmp
checksum=""
extracted=
dir=""
all=""
env=""
port=""
@@ -23,87 +10,6 @@ log()
logger -I $PPID -t container -p local1.notice -- "$*"
}
err()
{
rc=$1; shift
logger -I $PPID -t container -p local1.err -- "Error: $*"
if [ -n "$extracted" ]; then
if [ -d "$TMPDIR/$dir" ]; then
log "Cleaning up extracted $dir"
rm -rf "$dir"
fi
fi
[ "$rc" -eq 0 ] || exit "$rc"
}
check()
{
file=$1
if [ -z "$checksum" ]; then
log "no checksum to verify $file against, continuing."
return 0
fi
if echo "${checksum} ${file}" | "$cmdsum" -c -s; then
log "$file checksum verified OK."
return 0
fi
got=$("$cmdsum" "${file}" | awk '{print $1}')
log "$file checksum mismatch, got $got, expected $checksum, removing file."
rm -f "$file"
return 1
}
# Fetch an OCI image over ftp/http/https. Use wget for FTP, which curl
# empirically does not work well with. Log progress+ & error to syslog.
fetch()
{
url=$1
file=$(basename "$url")
dst="$DOWNLOADS/$file"
cd "$DOWNLOADS" || return
if [ -e "$file" ]; then
log "$file already available."
if check "$file"; then
echo "$dst"
return 0
fi
fi
log "Fetching $url"
if echo "$url" | grep -qE "^ftp://"; then
cmd="wget -q $url"
elif echo "$url" | grep -qE "^https?://"; then
cmd="curl $creds -sSL --fail -o \"$file\" $url"
else
log "Unsupported URL scheme: $url"
return 1
fi
if out=$(eval "$cmd" 2>&1); then
log "$file downloaded successfully."
if check "$file"; then
echo "$dst"
return 0
fi
fi
# log error message from backend
while IFS= read -r line; do
log "$line"
done <<EOF
$out
EOF
return 1
}
# Unpacks a given oci-archive.tar[.gz] in the current directory. Sanity
# checks, at least one index.json in the top-level dir of the archive.
# If there are more index files, this function does not handle them.
@@ -120,11 +26,6 @@ unpack_archive()
oci-archive:*) # Packed OCI image, .tar or .tar.gz format
file=${image#oci-archive:}
;;
ftp://* | http://* | https://*)
if ! file=$(fetch "$image"); then
return 1
fi
;;
*) # docker://*, docker-archive:*, or URL
echo "$image"
return 0
@@ -132,52 +33,38 @@ unpack_archive()
esac
if [ ! -e "$file" ]; then
if [ -e "$DOWNLOADS/$file" ]; then
file="$DOWNLOADS/$file"
elif [ -e "$BUILTIN/$file" ]; then
file="$BUILTIN/$file"
if [ -e "/var/lib/containers/oci/$file" ]; then
file="/var/lib/containers/oci/$file"
elif [ -e "/lib/oci/$file" ]; then
file="/lib/oci/$file"
else
err 1 "cannot find OCI archive $file in search path."
log "Error: cannot find OCI archive $file in search path."
exit 1
fi
fi
if [ -d "$file" ]; then
index=$(find "$file" -name index.json)
if [ -z "$index" ]; then
err 1 "cannot find index.json in OCI image $file"
log "Error: cannot find index.json in OCI image $file"
exit 1
fi
else
cd "$TMPDIR" || err 0 "failed cd $TMPDIR, wiill use $(pwd) for OCI archive extraction."
index=$(tar tf "$file" |grep index.json)
if [ -z "$index" ]; then
err 1 "invalid OCI archive, cannot find index.json in $file"
log "Error: invalid OCI archive, cannot find index.json in $file"
exit 1
fi
[ -n "$quiet" ] || log "Extracting OCI archive $file ..."
tar xf "$file" || err 1 "failed unpacking $file in $(pwd)"
extracted=true
tar xf "$file" || (log "Error: failed unpacking $file in $(pwd)"; exit 1)
remove=true
fi
dir=$(dirname "$index")
if echo "$dir" | grep -q ":"; then
if [ -z "$name" ]; then
name="$dir"
fi
sanitized_dir=$(echo "$dir" | cut -d':' -f1)
mv "$dir" "$sanitized_dir" || err 1 "failed renaming $dir to $sanitized_dir"
dir="$sanitized_dir"
fi
[ -n "$quiet" ] || log "Loading OCI image $dir ..."
podman load -qi "$dir" >/dev/null
# Clean up after ourselves
if [ -n "$extracted" ]; then
log "Cleaning up extracted $dir"
rm -rf "$dir"
fi
# Rename image from podman default $dir:latest
if [ -n "$name" ]; then
podman tag "$dir" "$name" >/dev/null
@@ -186,6 +73,10 @@ unpack_archive()
name=$dir
fi
if [ "$remove" = "true" ]; then
rm -rf "$file"
fi
echo "$name"
}
@@ -211,21 +102,15 @@ create()
# Unpack and load docker-archive/oci/oci-archive, returning image
# name, or return docker:// URL for download.
if ! image=$(unpack_archive "$image"); then
exit 1
fi
image=$(unpack_archive "$image")
if [ -z "$logging" ]; then
logging="--log-driver k8s-file --log-opt path=/run/containers/$name.fifo"
fi
# Pull quietly and don't retry on failure, we use execd for this,
# or user retry manually when run interactively, we may have other
# containers waiting to start that have an image locally already.
# Use --retry=0 with Podman 5.0 or later.
args="$args --read-only --replace --quiet --cgroup-parent=containers $caps"
args="$args --replace --quiet --cgroup-parent=containers $caps"
args="$args --restart=$restart --systemd=false --tz=local $privileged"
args="$args $vol $mount $hostname $entrypoint $env $port $logging"
args="$args $ro $vol $mount $hostname $entrypoint $env $port $logging"
pidfn=/run/container:${name}.pid
[ -n "$quiet" ] || log "---------------------------------------"
@@ -249,16 +134,16 @@ create()
fi
# shellcheck disable=SC2048
log "podman create --name $name --conmon-pidfile=$pidfn $args $image $*"
log "Calling podman create --name $name --conmon-pidfile=$pidfn $args $image $*"
if podman create --name "$name" --conmon-pidfile="$pidfn" $args "$image" $*; then
[ -n "$quiet" ] || log "Successfully created container $name from $image"
[ -n "$quiet" ] || log "Successfully created container $name from $image"
rm -f "/run/containers/env/${name}.env"
[ -n "$manual" ] || start "$name"
# Should already be enabled by confd (this is for manual use)
initctl -bnq enable "container@${name}.conf"
exit 0
fi
err 1 "failed creating container $name, please check the configuration."
log "Error: failed creating container $name, please check the configuration."
exit 1
}
delete()
@@ -272,9 +157,6 @@ delete()
exit 1
fi
# Should already be disabled (and stopped) by confd (this is for manual use)
initctl -bnq disable "container@${name}.conf"
podman rm -vif "$name" >/dev/null 2>&1
[ -n "$quiet" ] || log "Container $name has been removed."
}
@@ -285,7 +167,8 @@ waitfor()
while [ ! -f "$1" ]; do
_=$((timeout -= 1))
if [ $timeout -le 0 ]; then
err 1 "timed out waiting for $1, aborting!"
log "Timeout waiting for $1, aborting!"
exit 1
fi
sleep 1;
done
@@ -365,7 +248,6 @@ options:
--dns-search LIST Set host lookup search list when creating container
--cap-add CAP Add capability to unprivileged container
--cap-drop CAP Drop capability, for privileged containter
--checksum TYPE:SUM Use md5/sha256/sha512 to verify ftp/http/https archives
-c, --creds USR[:PWD] Credentials to pass to curl -u for remote ops
-d, --detach Detach a container started with 'run IMG [CMD]'
-e, --env FILE Environment variables when creating container
@@ -385,6 +267,7 @@ options:
Syntax: [[ip:][hostPort]:]containerPort[/protocol]
-q, --quiet Quiet operation, called from confd
-r, --restart POLICY One of "no", "always", or "on-failure:NUM"
--read-only Do not create a writable layer
-s, --simple Show output in simplified format
-v, --volume NAME:PATH Create named volume mounted inside container on PATH
@@ -392,7 +275,6 @@ commands:
create NAME IMAGE NET Create container NAME using IMAGE with networks NET
delete [network] NAME Remove container NAME or network NAME from all containers
exec NAME CMD Run a command inside a container
flush Clean up lingering containers and associated anonymous volumes
find [ifname PID] Find PID of container where '--net IFNAME' currently lives
or, find the name of our IFNAME inside the container @PID
help Show this help text
@@ -425,25 +307,6 @@ while [ "$1" != "" ]; do
shift
caps="$caps --cap-drop=$1"
;;
--checksum)
shift
type="${1%%:*}"
checksum="${1#*:}"
case "$type" in
md5)
cmdsum=md5sum
;;
sha256)
cmdsum=sha256sum
;;
sha512)
cmdsum=sha512sum
;;
*)
err 1 "Unsupported checksum type: $type"
;;
esac
;;
-c | --creds)
shift
creds="-u $1"
@@ -488,6 +351,7 @@ while [ "$1" != "" ]; do
--log-path)
shift
logging="$logging --log-opt path=$1"
log_path="$1"
;;
-m | --mount)
shift
@@ -522,6 +386,9 @@ while [ "$1" != "" ]; do
shift
restart=$1
;;
--read-only)
ro="--read-only=true"
;;
-s | --simple)
simple=true
;;
@@ -563,10 +430,6 @@ case $cmd in
exec)
podman exec -it "$@"
;;
flush)
echo "Cleaning up any lingering containers";
podman rm -av
;;
find)
cmd=$1
pid=$2
@@ -592,12 +455,25 @@ case $cmd in
usage
;;
load)
url=$1
name=$2
# shellcheck disable=SC2086
name=$(unpack_archive "$1" $2)
[ -n "$name" ] || exit 1
if echo "$url" | grep -q "://"; then
file=$(basename "$url")
curl -k $creds -Lo "$file" "$url"
else
file="$url"
fi
# shellcheck disable=SC2086
name=$(unpack_archive "$file" $name)
# Show resulting image(s) matching $name
podman images -n "$name"
if [ -n "$name" ]; then
podman images -n "$name"
else
exit 1
fi
;;
locate) # Find where the host's ifname lives
if [ -z "$network" ]; then
@@ -624,7 +500,7 @@ case $cmd in
podman images $all --format "{{.Repository}}:{{.Tag}}"
;;
oci)
find $BUILTIN $DOWNLOADS -type f 2>/dev/null
find /lib/oci /var/lib/containers/oci -type f 2>/dev/null
;;
*)
podman ps $all --format "{{.Names}}"
@@ -724,7 +600,8 @@ case $cmd in
while running "$name"; do
_=$((timeout -= 1))
if [ $timeout -le 0 ]; then
err 1 "timed out waiting for container $1 to stop before restarting it."
log "Timeout waiting for container $1 to stop before restarting it."
exit 1
fi
sleep 1
done
@@ -750,7 +627,7 @@ case $cmd in
;;
upgrade)
# Start script used to initially create container
script=/run/containers/${1}.sh
script=/var/lib/containers/active/S01-${1}.sh
# Find container image
img=$(podman inspect "$1" | jq -r .[].ImageName)
+3 -90
View File
@@ -4,55 +4,7 @@ Change Log
All notable changes to the project are documented in this file.
[v24.11.0][] - 2024-11-20
-------------------------
> [!CAUTION]
> This release contains breaking changes for container users! As of
> v24.11.0, all persistent[^1] containers always run in `read-only` mode
> and the setting itself is deprecated (kept only for compatibility
> reasons). The main reason for this change is to better serve users
> with embedded container images in their builds of Infix. I.e., they
> can now upgrade the OCI image in their build and rely on the container
> being automatically upgraded when Infix is upgraded, issue #823. For
> other users, the benefit is that *all* container configuration changes
> take when activated, issue #822, without having to perform any tricks.
### Changes
- Add validation of interface name lengths, (1..15), Linux limit
- Add support for ftp/http/https URI:s in container image, with a new
`checksum` setting for MD5/SHA256/SHA512 verification, issue #801
- Add a retry timer to the background container create service. This
will ensure failing `docker pull` operations from remote images are
retrying after 60 seconds, or quicker
- CLI base component, `klish`, has been updated with better support for
raw terminal mode and alternate quotes (' in addition to ")
- Log silenced from container activation messages, only the very bare
necessities are now logged, e.g., `podman create` command + status
- Factory reset no longer calls `shred` to "securely erase" any files
from writable data partitions. This will speed up the next boot
considerably
### Fixes
- Fix #659: paged output in CLI accessed via console port sometimes
causes lost lines, e.g. missing interfaces. With updated `klish`
and the terminal in raw mode, the pager (less) can now control both
the horizontal and vertical
- Fix #822: adding, or changing, an environment variable to a running
container does not take without the `container upgrade NAME` trick
- Fix #823: with an OCI image embedded in the Infix image, an existing
container in the configuration is not upgraded to the new OCI image
with the Infix upgrade.
- Frr leaves log files in `/var/tmp/frr` on unclean shutdowns. This
has now been fixed with a "tmpfiles" cleanup of that path at boot
[^1]: I.e., set up in the configuration, as opposed to temporary ones
started with `container run` from the CLI admin-exec context.
[v24.10.2][] - 2024-11-08
[v24.10.2][UNRELEASED]
-------------------------
### Changes
@@ -70,44 +22,23 @@ All notable changes to the project are documented in this file.
- Support for saving and restoring system clock from a disk file. This
allows restoring the system clock to a sane date in case the RTC is
disabled or does not have a valid time, issue #794
- Update device discovery chapter with information on `infix.local` mDNS
alias, `netbrowse` support to discover *all* local units, and command
examples for disabling LLDP and mDNS services, issue #786
- Updated OSPF documentation to include information on *global OSPF
settings* (`redistribution`, `explicit-router-id`, etc.), issue #812
- Added information on *forwarding of IEEE reserved group addresses*
to bridge section of networking documentation, issue #788
- Add support for bootstrap conditions and early init product overrides
- Styx: enable second Ethernet port LED in device tree, again, rename
it: yellow -> aux, and make sure it is turned off at boot
- Styx: disable second port LED for the 4xSFP slots, does not work
- Styx: override iitod (LED daemon) with a product specific LED script
### Fixes
- Fix #685: DSA conduit interface not always detected, randomly causing
major issues configuring systems with multiple switch cores
- Fix #778: reactivate OpenSSL backend for libssh/libssh2 for NanoPI R2S.
This fixes a regression in v24.10.0 causing loss of NETCONF support
- Fix #809: enable syslog logging for RAUC
- Fix harmless bootstrap log error message on systems without USB ports:
`jq: error (at <stdin>:0): Cannot iterate over null (null)`
- Change confusing `tc` log error message: `Error: does not support
hardware offload` to `Skipping $iface, hardware offload not supported.`
This fixes a regression in v24.10.0 causing loss of NETCONF supprt
[v24.10.1][] - 2024-10-18
-------------------------
### Changes
- Add support for interface description, sometimes referred to as
"ifAlias". Saved as an Linux interface alias (not `altname`), e.g.,
`/sys/class/interfaces/veth0a/ifalias`, includes operational support
### Fixes
- Fix #735: `copy` and `erase` commands missing from CLI, regression
in Infix v24.10.0 defconfigs, now added as dep. in klish package
@@ -122,9 +53,7 @@ Also, heads-up to all downstream users of Infix. YANG models have been
renamed to ease maintenance, more info below.
### Changes
- Software control of port LEDs on the Styx platform has been disabled.
Default driver behavior, green link and green traffic blink, is kept
as-is, which should mitigate issues reported in #670
- Correcting documentation on QoS. For packets containing both a VLAN
@@ -160,7 +89,6 @@ renamed to ease maintenance, more info below.
see <https://kernelkit.org/posts/firewall-container/>
### Fixes
- Fix #499: add an NACM rule to factory-config, which by default deny
everyone to read user password hash(es)
- Fix #663: internal Ethernet interfaces shown in CLI tab completion
@@ -209,7 +137,6 @@ also been added to facilitate site specific adaptations. Please see the
documentation for details.
### Known Issues
- The CLI command `show interfaces` may for some terminal resolutions
not display all interfaces (on systems with >20 interfaces). This
problem is limited to the console port and only occurs for smaller
@@ -218,7 +145,6 @@ documentation for details.
using the CLI from an SSH session, is not affected. Issue #659
### Changes
- Upgrade Buildroot to 2024.02.6 (LTS)
- Upgrade Linux kernel to 6.6.52 (LTS)
- Upgrade libyang to 3.4.2
@@ -238,7 +164,6 @@ documentation for details.
by `mctl` reporting no multicast filtering enabled on bridge
### Fixes
- Fix #357: EUI-64 based IPv6 autoconf address on bridges seem to be
randomized. Problem caused by kernel setting a random MAC before any
bridge port is added. Fixed by using the device's base MAC address on
@@ -301,7 +226,6 @@ Finally, the following consumer boards are now fully supported:
- StarFive VisionFive2 (RISC-V)
### Changes
- Upgrade Buildroot to 2024.02.5 (LTS)
- Upgrade Linux kernel to 6.6.46 (LTS)
- Issue #158: enhance security of factory reset. All file content
@@ -353,7 +277,6 @@ Finally, the following consumer boards are now fully supported:
log messages. See `/var/log/debug` for *all* log messages
### Fixes
- Fix #274: add missing link/traffic LEDs on NanoPi R2S LAN port
- Fix #489: ensure all patches are versioned, including Linux kernel
- Fix #531: creating a new VLAN interface named `vlanN` should not set
@@ -383,7 +306,6 @@ Finally, the following consumer boards are now fully supported:
> upgrade, but before reboot, a factory reset is required!
### Changes
- Upgrade Buildroot to 2024.02.3 (LTS)
- Upgrade Linux kernel to 6.6.34 (LTS)
- Upgrade bundled curiOS httpd container to v24.05.0
@@ -450,7 +372,6 @@ Finally, the following consumer boards are now fully supported:
[yescrypt]: https://en.wikipedia.org/wiki/Yescrypt
### Fixes
- Fix #424: regression, root user can log in without password
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
@@ -482,13 +403,11 @@ Finally, the following consumer boards are now fully supported:
-------------------------
### Changes
- Add small delay in U-Boot to allow stopping boot on reference boards
- Document how to provision the bootloader and Infix on a blank board
- Use initial hostname from `/etc/os-release` as configuration fallback
### Fixes
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
- Fix provisioning script after changes to make GRUB loading more robust
@@ -503,7 +422,6 @@ Finally, the following consumer boards are now fully supported:
-------------------------
### Changes
- Default web landing page refactored into a Buildroot package to make
it possible to overload from customer repos.
- Enable DCB support in aarch64 kernel (for EtherType prio override)
@@ -514,7 +432,6 @@ Finally, the following consumer boards are now fully supported:
- Issue #374: add timestamps to dagger .log files
### Fixes
- Add missing LICENSE hash for factory reset tool
- Fix #424: regression, root user can log in without password
@@ -536,7 +453,6 @@ idea is to generate supported features from the models and include in
future releases.
### Changes
- Bump the base Buildroot version to v2024.02 LTS
- Bump the base Linux kernel version to 6.6 LTS
- Drop Classic variant to reduce overhead, simplify build & release
@@ -617,7 +533,6 @@ future releases.
named 'default'
### Fixes
- confd: Fix memory leak when operating on candidate configuration
- probe: Fix crash on systems without USB
- Reduced syslog errors for accesses no non-existing xpaths
@@ -1360,9 +1275,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
- N/A
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.11.0...HEAD
[v24.11.0]: https://github.com/kernelkit/infix/compare/v24.10.0...v24.11.0
[v24.10.2]: https://github.com/kernelkit/infix/compare/v24.10.1...v24.10.2
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.10.1...HEAD
[v24.10.1]: https://github.com/kernelkit/infix/compare/v24.10.0...v24.10.1
[v24.10.0]: https://github.com/kernelkit/infix/compare/v24.09.0...v24.10.0
[v24.09.0]: https://github.com/kernelkit/infix/compare/v24.08.0...v24.09.0
+76 -225
View File
@@ -20,9 +20,6 @@ Containers in Infix
* [Application Container: ntpd](#application-container-ntpd)
* [Advanced](#advanced)
* [Running Host Commands From Container](#running-host-commands-from-container)
* [Container Requirements](#container-requirements)
* [Advanced Users](#advanced-users)
Introduction
------------
@@ -39,11 +36,10 @@ All network specific settings are done using the IETF interfaces YANG
model, with augments for containers to ensure smooth integration with
container networking in podman.
> [!IMPORTANT]
> 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.
> **Note:** 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.
Caution
@@ -87,26 +83,26 @@ 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 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 create a container with a semi-persistent writable layer that
survives container restarts and host system restarts. However, if you
change the container configuration or upgrade the image (see below), the
container will be recreated and the writable layer is lost. This is why
it is recommended to set up a named volume for directories, or use file
[Content Mounts](#content-mounts), in your container if you want truly
persistent content.
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`.
In fact, in many cases the best way is to create a `read-only` container
and use file mounts and volumes only for the critical parts. Podman
ensures (using tmpfs) `read-only` containers still have writable
directories for certain critical file system paths: `/dev`, `/dev/shm`,
`/run`, `/tmp`, and `/var/tmp`. Meaning, what you most often need is
writable volumes for `/var/lib` and `/etc`, or only file mounts for a
few files in `/etc`. The actual needs depend on the container image and
application to run.
Podman ensures (using tmpfs) all containers have writable directories
for certain critical file system paths: `/dev`, `/dev/shm`, `/run`,
`/tmp`, and `/var/tmp`. Meaning, what you most often need is writable
volumes for `/var/lib` and `/etc`, or only file mounts for a few files
in `/etc`. The [actual requirements](#container-requirements) depend on
your container image and application to run.
> [!IMPORTANT]
> When running containers from public registries, double-check that they
> support the CPU architecture of your host system. Remember, unlike
> virtualization, containers reuse the host's CPU and kernel.
> **Note:** when running containers from public registries, double-check
> that they support the CPU architecture of your host system. Remember,
> unlike virtualization, containers reuse the host's CPU and kernel.
<img align="right" src="img/docker-hello-world.svg" alt="Hello World" width=360>
@@ -172,20 +168,13 @@ The CLI help shows:
oci-archive:/lib/oci/archive -- Use archive:latest from OCI archive
May be in .tar or .tar.gz format
Additionally, the following URIs are also supported for setups
that do not use a HUB or similar. Recommend using 'checksum'!
ftp://addr/path/to/archive -- Downloaded using wget
http://addr/path/to/archive -- Downloaded using curl
https://addr/path/to/archive -- Downloaded using curl
Note: if a remote repository cannot be reached, the creation of the
container will be put on a queue that retries pull every time
there is a route change in the host's system.
> [!TIP]
> The built-in help system in the CLI is generated from the YANG model,
> so the same information is also available for remote NETCONF users.
> **Note::** the built-in help system in the CLI is generated from the
> YANG model, so the same information is also available for remote
> NETCONF users.
The two most common variants are `docker://` and `oci-archive:/`.
@@ -228,46 +217,21 @@ mind.
-rw-r--r-- 1 root root 7261785 Mar 27 14:22 curios-oci-amd64.tar.gz
drwx------ 6 frr frr 4096 Mar 27 11:57 frr/
Importing the image into Podman can be done either from the CLI
Importing the image into podman can be done either from the CLI
admin-exec context ...
admin@example:/var/tmp$ cli
admin@example:/> container load /var/tmp/curios-oci-amd64.tar.gz name curios:edge
> [!TIP]
> The `name curios:edge` is the tag you give the imported (raw) archive
> which you can then reference in your container image configuration:
> `set image curios:edge`.
> The `name curios:edge` is the tag you give the imported
> (raw) archive which you can then reference in your container image
> configuration: `set image curios:edge`.
... or by giving the container configuration the full path to the OCI
archive, which helps greatly with container upgrades (see below):
admin@example:/config/container/system/> set image oci-archive:/var/tmp/curios-oci-amd64.tar.gz
**Checksum Example:**
admin@example:/> configure
admin@example:/config/> edit container sys
admin@example:/config/container/sys/> set hostname sys
admin@example:/config/container/sys/> set image ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz
admin@example:/config/container/sys/> set checksum
md5 sha256 sha512
admin@example:/config/container/sys/> set checksum sha256 4f01077036527498ed910f1a3e80645ae3eff629d10043cf80ebc6850c99c629
admin@example:/config/container/sys/> leave
admin@example:/> copy running-config startup-config
admin@example:/> show container
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b02e945c43c9 localhost/curios-oci-amd64-v24.05.0:latest 5 seconds ago Up 5 seconds sys
admin@example:/> show log
...
Nov 20 07:24:56 infix container[5040]: Fetching ftp://192.168.122.1/curios-oci-amd64-v24.05.0.tar.gz
Nov 20 07:24:56 infix container[5040]: curios-oci-amd64-v24.05.0.tar.gz downloaded successfully.
Nov 20 07:24:56 infix container[5040]: curios-oci-amd64-v24.05.0.tar.gz checksum verified OK.
Nov 20 07:24:57 infix container[5040]: Cleaning up extracted curios-oci-amd64-v24.05.0
Nov 20 07:24:57 infix container[5040]: podman create --name sys --conmon-pidfile=/run/container:sys.pid --read-only --replace --quiet --cgroup-parent=containers --restart=always --systemd=false --tz=local --hostname sys --log-driver k8s-file --log-opt path=/run/containers/sys.fifo --network=none curios-oci-amd64-v24.05.0
Nov 20 07:24:57 infix container[3556]: b02e945c43c9bce2c4be88e31d6f63cfdb1a3c8bdd02179376eb059a49ae05e4
Upgrading a Container Image
---------------------------
@@ -276,24 +240,21 @@ Upgrading a Container Image
The applications in your container are an active part of the system as a
whole, so make it a routine to keep your container images up-to-date!
Containers are created at first setup and at every boot. If the image
exists in the file system it is reused -- i.e., an image pulled from a
remote registry is not fetched again.
> **Note:** the default writable layer is lost when upgrading the image.
> Use named volumes for content that you want to persist across upgrades.
To upgrade a versioned image:
- update your `running-config` to use the new `image:tag`
- `leave` to activate the change, if you are in the CLI
- Podman pulls the new image in the background
- Your container is recreated with the new image
- The container is started
For "unversioned" images, e.g., images using a `:latest` or `:edge` tag,
use the following CLI command (`NAME` is the name of your container):
All container configurations are locked to the image hash at the time of
first download, not just ones that use an `:edge` or `:latest` tag. An
upgrade of containers using versioned images is more obvious -- update
the configuration to use the new `image:tag` -- the latter is a bit
trickier. Either remove the configuration and recreate it (leave/apply
the changes between), or use the admin-exec level command:
admin@example:/> container upgrade NAME
This stops the container, does `container pull IMAGE`, and recreates it
with the new image. Upgraded containers are automatically restarted.
Where `NAME` is the name of your container. This command stops the
container, does `container pull IMAGE`, and then recreates it with the
new image. Upgraded containers are automatically restarted.
**Example using registry:**
@@ -318,30 +279,12 @@ the upgrade command as
Upgrading container system with local archive: oci-archive:/var/tmp/curios-oci-amd64.tar.gz ...
7ab4a07ee0c6039837419b7afda4da1527a70f0c60c0f0ac21cafee05ba24b52
OCI archives can also be fetched from ftp/http/https URL, in that case
the upgrade can be done the same way as a registry image (above).
> [!TIP]
> Containers running from OCI images embedded in the operating system,
> e.g., `/lib/oci/mycontainer.tar.gz`, always run from the version in
> the operating system. To upgrade, install the new container image at
> build time, after system upgrade the container is also upgraded. The
> system unpacks and loads the OCI images into Podman every boot, which
> ensures the running container always has known starting state.
>
> **Example:** default builds of Infix include a couple of OCI images
> for reference, one is `/lib/oci/curios-nftables-v24.11.0.tar.gz`, but
> there is also a symlink called `curios-nftables-latest.tar.gz` in the
> same directory, which is what the Infix regression tests use in the
> image configuration of the container. This is what enables easy
> upgrades of the container along with the system itself.
Capabilities
-------------
An unprivileged container works for almost all use-cases, but there are
occasions where they are too restricted and users start looking for the
occasions where they are too restricted and users being looking for the
`privileged` flag. Capabilities offers a middle ground.
For example, a system container from which `ping` does not work:
@@ -357,9 +300,9 @@ For example, a system container from which `ping` does not work:
...
Infix supports a subset of all [capabilities][6] that are relevant for
containers. Please note, that this is an advanced topic that require
time and analysis of your container application to figure out which
capabilities you need.
containers. Please note, that this is and advanced topic and will
require time and analysis of your container application to figure out
which capabilities you need.
Networking and Containers
@@ -369,16 +312,9 @@ By default, unlike other systems, persistent[^1] containers have no
networking enabled. All network access has to be set up explicitly.
Currently two types of of container networks are supported:
- `host`: an managed host interface, e.g., one end of a VETH pair,
or even a physical interface
- `host`: one end of a VETH pair, or a physical Ethernet port
- `bridge`: an IP masquerading bridge
In the former the interface is delegated to (moved into) the container,
while in the latter a VETH pair is automatically created by Podman and
one end delegated to the container, while the other end is assigned to
the bridge (see the next section).
> [!TIP]
> For more information on VETH pairs, see the [Networking Guide][0].
@@ -411,12 +347,10 @@ have to set manually:
admin@example:/config/interface/docker0/> set type bridge
admin@example:/config/interface/docker0/> set container-network type bridge
> [!IMPORTANT]
> When configuring the system via an API such as NETCONF or RESTCONF, no
> settings are inferred. Instead it is up to the caller to fully define
> the desired setup. This makes the CLI very useful for first setup and
> then extracting the resulting XML from the shell using the `cfg -X`
> command.
> **Note:** when doing the same operation over NETCONF there is no
> inference, so all the "magic" settings need to be defined. This
> makes the CLI very useful for first setup and then extracting the
> resulting XML from the shell using the `cfg -X` command.
We have to declare the interface as a container network, ensuring the
interface cannot be used by the system for any other purpose. E.g., a
@@ -485,12 +419,8 @@ example.
The network `option` setting is available also for this case, but only
the `interface_name=foo0` option works. Which is still very useful. To
set:
- IP address, use IPv4/IPv6 settings in the interface settings
- MAC address, to use the `custom-phys-address` in the interface settings
For an example of both, see the next section.
change the MAC address, you need to use the `custom-phys-address` in the
general network settings.
[^3]: Something which the container bridge network type does behind the
scenes with one end of an automatically created VETH pair.
@@ -517,7 +447,6 @@ line where we declare the `ntpd` end as a container network interface:
admin@example:/config/interface/ntpd/> set custom-phys-address static 00:c0:ff:ee:00:01
admin@example:/config/interface/ntpd/> set container-network
> [!TIP]
> Notice how you can also set a custom MAC address at the same time.
Adding the interface to the container is the same as before, but since
@@ -527,7 +456,6 @@ can take a bit of a shortcut.
admin@example:/config/container/ntpd/> set network interface ntpd
admin@example:/config/container/ntpd/> leave
> [!TIP]
> Use the `set network interface ntpd option interface_name=foo0` to set
> the name of the interface inside the container to `foo0`.
@@ -550,7 +478,6 @@ We start by adding the second VETH pair:
admin@example:/config/interface/veth1a/> set veth peer veth1
admin@example:/config/interface/veth1a/> set ipv4 address 192.168.1.2 prefix-length 24
> [!NOTE]
> The LAN bridge (br1) in this example has IP address 192.168.1.1.
When a container has multiple host interfaces it can often be useful to
@@ -602,40 +529,29 @@ file system:
admin@example:/config/container/system/mount/leds> end
admin@example:/config/container/system/>
Any type of file can be *bind mounted* into the container, just watch
out for permissions though. In the example above, `/sys/class/leds` is
not writable from a container unless it runs in *privileged* mode. For
plain configuration files you get more freedom, and your container can
rely on, e.g., *inotify* events to trigger reloading its services when
you change the file on the host.
So it depends on the container, and indeed your overall setup, what to
use. An intriguing option is *Content Mounts*, which when changed also
trigger a container restart.
Other times *volumes* are a better fit. A volume is an automatically
Sometimes *volumes* are a better fit. A volume is an automatically
created read-writable entity that follows the life of your container.
admin@example:/config/container/ntpd/> set volume varlib target /var/lib
Volumes are persistent across both reboots and upgrades of the base
image. They are created by Podman when the container first starts up,
unlike a regular bind mount it synchronizes with the contents of the
underlying container image's path at first use. I.e., "bind-mount, if
empty: then rsync".
Volumes survive reboots and upgrading of the base image, unlike the
persistent writable layer you get by default, which does not survive
upgrades. The volume is created by podman when the container first
starts up, unlike a regular bind mount it synchronizes with the contents
of the underlying container image's path on the first start. I.e.,
"bind-mount, if empty: then rsync".
> [!NOTE]
> Infix support named volumes (only), and it is not possible to share a
> volume between containers. All the tricks possible with volumes may
> be added in a later release.
### Content Mounts
Content mounts are a special type of file mount where the file contents
is stored with the container configuration. This can be very useful
when deploying similar systems at multiple sites. When the host loads
its `startup-config` (or even `factory-config`) a temporary file is
created using the decoded base64 data from the `content` node.
Content mount is a special type of where the file contents for the
container is stored alongside the container configuration. This can be
very useful when deploying similar systems at multiple sites. When the
host loads its `startup-config` (or even `factory-config`) a temporary
file is created using the decoded base64 data from the `content` node.
admin@example:/config/container/ntpd/> edit mount ntpd.conf
admin@example:/config/container/ntpd/mount/ntpd.conf> text-editor content
@@ -648,10 +564,9 @@ The editor is a small [Emacs clone called Mg][2], see the built-in help
text, or press Ctrl-x Ctrl-c to exit and save. When the editor exits
the contents are base64 encoded and stored in the candidate datastore.
> [!NOTE]
> Since these files are always recreated when the host is restarted,
> changes made by the container are not preserved, or saved back to the
> host's startup-config.
> **Note:** since these files are always recreated when the host is
> restarted, changes made by the container are not preserved, or saved
> back to the host's startup-config even if the read-only option is off.
Infix has three different text editors available. For more information,
see [CLI Text Editor](cli/text-editor.md).
@@ -673,11 +588,10 @@ we created previously:
admin@example:/config/container/system/> set publish 222:22
admin@example:/config/container/system/> leave
> [!NOTE]
> Ensure you have a network connection to the registry. If the image
> cannot be pulled, creation of the container will be put in a queue and
> be retried every time there is a change in the routing table, e.g.,
> default route is added, and every 60 seconds.
> **Note:** ensure you have a network connection to the registry.
> If the image cannot be pulled, creation of the container will be
> put in a queue and be retried every time there is a change in the
> routing table, e.g., default route is added.
Provided the image is downloaded successfully, a new `system` container
now runs behind the docker0 interface, forwarding container port 22 to
@@ -793,13 +707,12 @@ Another *insecure* approach is to access the host system directly,
bypassing the namespaces that make up the boundary between host and
container.
> [!CAUTION]
> Please note, this completely demolishes the isolation barrier between
> container and host operating system. It is only suitable in
> situations where the container serves more as a unit of distribution
> rather than as a separate component of the system. *Strongly
> recommended* to use this only in trusted setups! Consider also
> limiting the time frame in which this is active!
> **Security:** Please note, this completely demolishes the isolation
> barrier between container and host operating system. It is only
> suitable in situations where the container serves more as a unit of
> distribution rather than as a separate component of the system.
> *Strongly recommended* to use this only in trusted setups! Consider
> also limiting the time frame in which this is active!
First, enable *Privileged* mode, this unlocks the door and allows the
container to manage resources on the host system. An example is the
@@ -834,58 +747,6 @@ control an Infix system this way, see [Scripting Infix](scripting.md).
it may not be enabled by default in BusyBox.
Container Requirements
----------------------
In addition to general [*best practices*][7] for container images, there
are a few more things to consider when targeting embedded systems:
- Ensure the image targets the CPU architecture of the target system,
learn more about [Multi-platform Builds][8]
- Follow [best practices for naming and tagging][10], e.g., `:latest` vs `:1.0`
- Follow [OCI recommendations and layout][9],
learn more about [OCI and Docker Exporters][6]
If the [Docker documentation][11] is not enough, there are plenty of
[guides online][12] with examples on how to create your own container
image. For the more advanced, please see the next section.
### Advanced Users
Most people prefer their system containers small, often based on Alpine
Linux, or similar, with only a few small applications, including their
own, and an SSH server perhaps. For some developers, even this is too
big, so they roll their own from source. This section is for you.
Depending on your needs, here is a checklist:
- you need something that can forward signals, e.g.,
- [tini][]
- [Bash only][13], or
- BusyBox init, a classic most embedded developers know, but read on ...
- a system container only need the bare necessities of a system bringup
- E.g., BusyBox's init, [but not everything][15]
- Some of the networking is set up by Podman and CNI for you, but
you may want to run a DHCP client?
- Do *not* rename interfaces inside the container, use the dedicated
`interface_name` option in the configuration instead
- Remember, Podman provides a `tmpfs` for all critical system paths:
`/dev`, `/dev/shm`, `/run`, `/tmp`, and `/var/tmp`, so you don't
need to clean or set up any of these mount points
Examples using `tini` and BusyBox init are available from the KernelKit
[curiOS project][14]. It is a small Buildroot based container image
builder that generates OCI compatible image tarballs without any tools
from Docker or Podman -- ready-made images exist for testing on both
AMD64 and ARM64 targets, as well as `docker pull` images and and OCI
tarballs with SHA256 checksums for integrity checking.
Finally, if you build your own version of Infix, and embed OCI tarballs
in the system image, then see the tip at the end of [Upgrading a
Container Image](#upgrading-a-container-image) (above).
[0]: networking.md
[1]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-containers.yang
[2]: https://github.com/troglobit/mg
@@ -893,14 +754,4 @@ Container Image](#upgrading-a-container-image) (above).
[4]: system.md#ssh-authorized-key
[5]: https://docs.docker.com/build/exporters/oci-docker/
[6]: https://man7.org/linux/man-pages/man7/capabilities.7.html
[7]: https://docs.docker.com/build/building/best-practices/
[8]: https://docs.docker.com/build/building/multi-platform/
[9]: https://github.com/opencontainers/image-spec/blob/main/image-layout.md
[10]: https://docs.docker.com/get-started/docker-concepts/building-images/build-tag-and-publish-an-image/#tagging-images
[11]: https://www.docker.com/blog/multi-arch-images/
[12]: https://lemariva.com/blog/2018/05/tutorial-docker-on-embedded-systems-raspberry-pi-beagleboard
[13]: https://sirikon.me/posts/0009-pid-1-bash-script-docker-container.html
[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
[podman]: https://podman.io
+28 -142
View File
@@ -16,14 +16,14 @@ seen in the response.
In the example below, the PC is connected to Infix via interface *tap0*
(*tap0* is *if1* in Figure 1) and Infix responds with address
*fe80::ff:fec0:ffed*.
*fe80::ff:fe00:0*.
```
linux-pc:# ping -6 -L -c 3 ff02::1%tap0
PING ff02::1%tap0(ff02::1%tap0) 56 data bytes
64 bytes from fe80::ff:fec0:ffed%tap0: icmp_seq=1 ttl=64 time=0.558 ms
64 bytes from fe80::ff:fec0:ffed%tap0: icmp_seq=2 ttl=64 time=0.419 ms
64 bytes from fe80::ff:fec0:ffed%tap0: icmp_seq=3 ttl=64 time=0.389 ms
64 bytes from fe80::ff:fe00:0%tap0: icmp_seq=1 ttl=64 time=0.558 ms
64 bytes from fe80::ff:fe00:0%tap0: icmp_seq=2 ttl=64 time=0.419 ms
64 bytes from fe80::ff:fe00:0%tap0: icmp_seq=3 ttl=64 time=0.389 ms
--- ff02::1%tap0 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2043ms
@@ -34,9 +34,9 @@ linux-pc:#
The PC could connect then connect to Infix, e.g., using SSH.
```
linux-pc:# ssh admin@fe80::ff:fec0:ffed%tap0
admin@fe80::ff:fec0:ffed%tap0's password: admin
admin@infix-c0-ff-ee:~$
linux-pc:# ssh admin@fe80::ff:fe00:0%tap0
admin@fe80::ff:fe00:0%tap0's password: admin
admin@infix-00-00-00:~$
```
## Discovery mechanisms available in Infix
@@ -55,18 +55,18 @@ linux-pc:# tcpdump -i tap0 -Qin -v ether proto 0x88cc
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:51:52.061071 LLDP, length 193
Chassis ID TLV (1), length 7
Subtype MAC address (4): 02:00:00:c0:ff:ee (oui Unknown)
Subtype MAC address (4): 02:00:00:00:00:00 (oui Unknown)
Port ID TLV (2), length 7
Subtype MAC address (3): 02:00:00:c0:ff:ee (oui Unknown)
Subtype MAC address (3): 02:00:00:00:00:00 (oui Unknown)
Time to Live TLV (3), length 2: TTL 120s
System Name TLV (5), length 14: infix-c0-ff-ee
System Name TLV (5), length 14: infix-00-00-00
System Description TLV (6), length 91
Infix by KernelKit Linux 5.19.17 #1 SMP PREEMPT_DYNAMIC Wed Jun 7 08:47:23 CEST 2023 x86_64
System Capabilities TLV (7), length 4
System Capabilities [Bridge, WLAN AP, Router, Station Only] (0x009c)
Enabled Capabilities [Station Only] (0x0080)
Management Address TLV (8), length 24
Management Address length 17, AFI IPv6 (2): fe80::ff:fec0:ffed
Management Address length 17, AFI IPv6 (2): fe80::ff:fe00:0
Interface Index Interface Numbering (2): 2
Port Description TLV (4), length 4: eth0
Organization specific TLV (127), length 9: OUI IEEE 802.3 Private (0x00120f)
@@ -97,11 +97,11 @@ linux-pc:# sudo tcpdump -i tap0 -Qin -v ether proto 0x88cc
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:46:07.908665 LLDP, length 207
Chassis ID TLV (1), length 7
Subtype MAC address (4): 02:00:00:c0:ff:ee (oui Unknown)
Subtype MAC address (4): 02:00:00:00:00:00 (oui Unknown)
Port ID TLV (2), length 7
Subtype MAC address (3): 02:00:00:c0:ff:ee (oui Unknown)
Subtype MAC address (3): 02:00:00:00:00:00 (oui Unknown)
Time to Live TLV (3), length 2: TTL 120s
System Name TLV (5), length 14: infix-c0-ff-ee
System Name TLV (5), length 14: infix-00-00-00
System Description TLV (6), length 91
Infix by KernelKit Linux 5.19.17 #1 SMP PREEMPT_DYNAMIC Wed Jun 7 08:47:23 CEST 2023 x86_64
System Capabilities TLV (7), length 4
@@ -134,15 +134,6 @@ linux-pc:#
(LLDP)](https://github.com/lldp/lldpd) includes *lldpcli*, which
is handy to sniff and display LLDP packets.
The LLDP service can be disabled using the following commands.
```
admin@infix-c0-ff-ee:/> configure
admin@infix-c0-ff-ee:/config/> no lldp
admin@infix-c0-ff-ee:/config/> leave
admin@infix-c0-ff-ee:/>
```
### mDNS
DNS-SD/mDNS can be used to discover Infix units and services. Infix
@@ -153,138 +144,33 @@ be used to search for devices advertising their services via mDNS.
```
linux-pc:# avahi-browse -ar
+ tap0 IPv6 infix-c0-ff-ee SFTP File Transfer local
+ tap0 IPv4 infix-c0-ff-ee SFTP File Transfer local
+ tap0 IPv6 infix-c0-ff-ee SSH Remote Terminal local
+ tap0 IPv4 infix-c0-ff-ee SSH Remote Terminal local
= tap0 IPv4 infix-c0-ff-ee SFTP File Transfer local
hostname = [infix-c0-ff-ee.local]
+ tap0 IPv6 infix-00-00-00 SFTP File Transfer local
+ tap0 IPv4 infix-00-00-00 SFTP File Transfer local
+ tap0 IPv6 infix-00-00-00 SSH Remote Terminal local
+ tap0 IPv4 infix-00-00-00 SSH Remote Terminal local
= tap0 IPv4 infix-00-00-00 SFTP File Transfer local
hostname = [infix-00-00-00.local]
address = [10.0.1.1]
port = [22]
txt = []
= tap0 IPv4 infix-c0-ff-ee SSH Remote Terminal local
hostname = [infix-c0-ff-ee.local]
= tap0 IPv4 infix-00-00-00 SSH Remote Terminal local
hostname = [infix-00-00-00.local]
address = [10.0.1.1]
port = [22]
txt = []
= tap0 IPv6 infix-c0-ff-ee SFTP File Transfer local
hostname = [infix-c0-ff-ee.local]
address = [fe80::ff:fec0:ffed]
= tap0 IPv6 infix-00-00-00 SFTP File Transfer local
hostname = [infix-00-00-00.local]
address = [fe80::ff:fe00:0]
port = [22]
txt = []
= tap0 IPv6 infix-c0-ff-ee SSH Remote Terminal local
hostname = [infix-c0-ff-ee.local]
address = [fe80::ff:fec0:ffed]
= tap0 IPv6 infix-00-00-00 SSH Remote Terminal local
hostname = [infix-00-00-00.local]
address = [fe80::ff:fe00:0]
port = [22]
txt = []
^C
linux-pc:#
```
Additionally, *avahi-resolve-host-name* can be used to verify domain
name mappings for IP addresses. By default, it translates from IPv4
addresses. This function allows users to confirm that addresses are
mapped correctly.
```
linux-pc:# avahi-resolve-host-name infix-c0-ff-ee.local
infix-c0-ff-ee.local 10.0.1.1
linux-pc:#
```
Thanks to mDNS we can use the advertised name instead of the IP
address for operations like `ping` and `ssh` as shown below:
```
linux-pc:# ping infix-c0-ff-ee.local -c 3
PING infix-c0-ff-ee.local (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.852 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=1.12 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=1.35 ms
--- infix-c0-ff-ee.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.852/1.105/1.348/0.202 ms
linux-pc:# ssh admin@infix-c0-ff-ee.local
(admin@infix-c0-ff-ee.local) Password:
.-------.
| . . | Infix -- a Network Operating System
|-. v .-| https://kernelkit.org
'-'---'-
Run the command 'cli' for interactive OAM
linux-pc:#
```
To disable mDNS/mDNS-SD, type the commands:
```
admin@infix-c0-ff-ee:/> configure
admin@infix-c0-ff-ee:/config/> no mdns
admin@infix-c0-ff-ee:/config/> leave
```
#### Human-Friendly Hostname Alias
Each Infix unit will advertise itself as *infix.local*, in addition to
its full hostname (e.g., *infix-c0-ff-ee.local* or *foo.local*). This
alias works seamlessly on a network with a single Infix device, and
makes it easy to connect when the exact hostname is not known in
advance. The examples below show how the alias can be used for
actions such as pinging or establishing an SSH connection:
```
linux-pc:# ping infix.local -c 3
PING infix.local (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.751 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=2.28 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=1.42 ms
--- infix.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.751/1.482/2.281/0.626 ms
linux-pc:# ssh admin@infix.local
(admin@infix.local) Password:
.-------.
| . . | Infix -- a Network Operating System
|-. v .-| https://kernelkit.org
'-'---'-
Run the command 'cli' for interactive OAM
linux-pc:#
```
When multiple Infix devices are present on the LAN the alias will not
uniquely identify a device; *infix.local* will refer to any of the
Infix devices, likely the one that first appeared.
> When multiple Infix units are present, use the full hostname (e.g.,
> *infix-c0-ff-ee.local* or *foo.local*) rather than the alias
> infix.local to deterministically connect to a unit.
#### Netbrowse service to find all your devices
Another mDNS alias that all Infix devices can advertise is
*network.local*. This is a web service which basically runs avahi-browse
and displays a table of other Infix devices and their services.
![Netbrowse Service - network.local](img/network-local.png)
With multiple Infix devices on the LAN, one will be your portal to
access all others, if it goes down another will take its place.
To disable the netbrowse service, the following commands can be used:
```
admin@infix-c0-ff-ee:/> configure
admin@infix-c0-ff-ee:/config/> edit web
admin@infix-c0-ff-ee:/config/web/> no netbrowse
admin@infix-c0-ff-ee:/config/web/> leave
```
[^2]: [mdns-scan](http://0pointer.de/lennart/projects/mdns-scan/): a
tool for scanning for mDNS/DNS-SD published services on the local
network
Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

+40 -120
View File
@@ -7,10 +7,9 @@ model forms the base, extended with [ietf-ip.yang][2] and other layer-3
IETF models. The layer-2 bridge and aggregate models are defined by
Infix to exploit the unique features not available in IEEE models.
> [!IMPORTANT]
> When issuing `leave` to activate your changes, remember to also save
> your settings, `copy running-config startup-config`. See the [CLI
> Introduction](cli/introduction.md) for a background.
> **Note:** when issuing `leave` to activate your changes, remember to
> also save your settings, `copy running-config startup-config`. See
> the [CLI Introduction](cli/introduction.md) for a background.
## Interface LEGO®
@@ -104,11 +103,10 @@ The `description` is saved as Linux `ifalias` on an interface. It is a
free-form string, useful for describing purpose or just adding comments
for remote debugging, e.g., using the operational datastore.
> [!CAUTION]
> There is no validation or safety checks performed by the system when
> using `custom-phys-address`. In particular the `offset` variant can
> be dangerous to use -- pay attention to the meaning of bits in the
> upper-most octet: local bit, multicast/group, etc.
> **Note:** there is no validation or safety checks performed by the
> system when using `custom-phys-address`. In particular the `offset`
> variant can be dangerous to use -- pay attention to the meaning of
> bits in the upper-most octet: local bit, multicast/group, etc.
#### Fixed custom MAC
@@ -169,14 +167,11 @@ admin@example:/config/> leave
Here we add two ports to bridge `br0`: `eth0` and `eth1`.
> [!TIP]
> Infix has many built-in helpers controlled by convention. Example,
> naming your bridge `brN`, where `N` is a number, hints Infix to set
> interface type automatically and unlocks all bridge features. Other
> "magic" names are `vethNA`, where `N` is a number and `A` is a letter
> ('a' for access port and 'b' for bridge side is common), and `ethN.M`
> for VLAN M on top of `ethN`, or `dockerN` to create an IP masquerading
> container bridge.
> **Note:** Infix has many built-in helpers controlled by convention.
> E.g., if you name your bridge `brN`, where `N` is a number, Infix sets
> the interface type automatically and unlocks all bridge features.
> Other "magic" names are `ethN.M` for VLAN M on top of `ethN`, or
> `dockerN` to create an IP masquerading container bridge.
![A MAC bridge with two ports](img/mac-bridge.svg)
@@ -219,7 +214,6 @@ admin@example:/config/interface/br0/> set bridge vlans vlan 10 tagged br0
admin@example:/config/interface/br0/> set bridge vlans vlan 20 tagged br0
```
> [!NOTE]
> To route or to manage via a VLAN, a VLAN interface needs to be created
> on top of the bridge, see section [VLAN Interfaces](#vlan-interfaces)
> below for more on this topic.
@@ -233,11 +227,10 @@ also supports "snooping", i.e., IGMP and MLD, to automatically reduce
the broadcast effects of multicast. See the next section for a summary
of the [terminology used](#terminology--abbreviations).
> [!IMPORTANT]
> Currently there is no way to just enable multicast filtering without
> also enabling snooping. This may change in the future, in which case
> a `filtering` enabled setting will be made available along with the
> existing `snooping` setting.
> **Note:** currently there is no way to just enable multicast filtering
> without also enabling snooping. This may change in the future, in
> which case a `filtering` enabled setting will be made available along
> with the existing `snooping` setting.
When creating your bridge you must decide if you need a VLAN filtering
bridge or a plain bridge (see previous section). Multicast filtering is
@@ -377,52 +370,19 @@ an IGMP/MLD fast-leave port.
tables shown above, a *None* timeout is declared when the current
device is the active querier
> [!TIP]
> The reason why multicast flooding is enabled by default is to ensure
> safe co-existence with MAC multicast, which is common in industrial
> networks. It also allows end devices that do not know of IGMP/MLD to
> communicate over multicast as long as the group they have chosen is
> not used by other IGMP/MLD aware devices on the LAN.
> **Note:** the reason why multicast flooding is enabled by default is
> to ensure safe co-existence with MAC multicast, which is very common
> in industrial networks. It also allows end devices that do not know
> of IGMP/MLD to communicate over multicast as long as the group they
> have chosen is not used by other IGMP/MLD aware devices on the LAN.
>
> As soon as an IGMP/MLD membership report to "join" a group is received
> the group is added to the kernel MDB and forwarding to other ports
> stop. The only exception to this rule is multicast router ports.
>
> If your MAC multicast forwarding is not working properly, it may be
> because an IP multicast group maps to the same MAC address. Please
> see [RFC 1112][RFC1112] for details. Use static multicast router
> ports, or static multicast MAC filters, to mitigate.
> the group is added to the MDB and forwarding to other ports stop. The
> only exception to this rule is multicast router ports.
[RFC1112]: https://www.rfc-editor.org/rfc/rfc1112.html
[RFC3376]: https://www.rfc-editor.org/rfc/rfc3376.html
[RFC3810]: https://www.rfc-editor.org/rfc/rfc3810.html
#### Forwarding of IEEE Reserved Group Addresses
Addresses in range `01:80:C2:00:00:0X` are used by various bridge
signaling protocols, and are not forwarded by default. Still, it is
sometimes useful to let the bridge forward such packets, and Infix
supports this by specifying protocol names or the last address
*nibble* as decimal value `0..15`.
```
admin@example:/config/> edit interface br0 bridge
admin@example:/config/interface/br0/bridge/> set ieee-group-forward <?>
[0..15] List of IEEE link-local protocols to forward, e.g., STP, LLDP
dot1x 802.1X Port-Based Network Access Control.
lacp 802.3 Slow Protocols, e.g., LACP.
lldp 802.1AB Link Layer Discovery Protocol (LLDP).
stp Spanning Tree (STP/RSPT/MSTP).
admin@example:/config/interface/br0/bridge/> set ieee-group-forward
```
The following example configures bridge *br0* to forward LLDP packets.
```
admin@example:/config/interface/br0/bridge/> set ieee-group-forward lldp
admin@example:/config/interface/br0/bridge/>
```
### VLAN Interfaces
Creating a VLAN can be done in many ways. This section assumes VLAN
@@ -524,10 +484,9 @@ Auto-negotiation of speed/duplex mode is desired in almost all
use-cases, but it is possible to disable auto-negotiation and specify
a fixed speed and duplex mode.
> [!IMPORTANT]
> When setting a fixed speed and duplex mode, ensure both sides of the
> link have matching configuration. If speed does not match, the link
> will not come up. If duplex mode does not match, the result is
> If setting a fixed speed and duplex mode, ensure both sides of the
> link have matching configuration. If speed does not match, the link
> will not come up. If duplex mode does not match, the result is
> reported collisions and/or bad throughput.
The example below configures port eth3 to fixed speed 100 Mbit/s
@@ -620,10 +579,9 @@ interfaces {
admin@example:/config/>
```
> [!TIP]
> This is another example of the automatic inference of the interface
> type from the name. Any name can be used, but then you have to set
> the interface type to `veth` manually.
> **Note:** this is another example of the automatic inference of the
> interface type from the name. Any name can be used, but then you have
> to set the interface type to `veth` manually.
## Management Plane
@@ -645,8 +603,7 @@ Multiple address assignment methods are available:
| link-local | infix-ip | Auto-assignment of IPv4 address in 169.254.x.x/16 range |
| dhcp | infix-dhcp-client | Assignment of IPv4 address by DHCP server, e.g., *10.0.1.1/24* |
> [!NOTE]
> The DHCP address method is only available for *LAN* interfaces
> **Note:** DHCP address method is only available for *LAN* interfaces
> (Ethernet, virtual Ethernet (veth), bridge, link aggregates, etc.)
Supported DHCP (request) options, configurability (Cfg) and defaults,
@@ -680,10 +637,9 @@ client is not enabled, any NTP servers provided by the DHCP server will
be ignored. For details on how to enable the NTP client, see the
[NTP Client Configuration](system.md#ntp-client-configuration) section.
> [!IMPORTANT]
> Per [RFC3442][4], if the DHCP server returns both a Classless Static
> Routes option (121) and Router option (3), the DHCP client *must*
> ignore the latter.
> **Note:** as per [RFC3442][4], if the DHCP server returns both a
> Classless Static Routes option (121) and Router option (3), the
> DHCP client *must* ignore the latter.
### IPv6 Address Assignment
@@ -950,10 +906,9 @@ The base model, ietf-routing, is where all the other models hook in. It
is used to set configuration and read operational status (RIB tables) in
the other models.
> [!NOTE]
> The standard IETF routing models allows multiple instances, but Infix
> currently *only support one instance* per routing protocol! In the
> examples presented here, the instance name `default` is used.
> **Note:** the standard IETF routing models allows multiple instances,
> but Infix currently *only support one instance* per routing protocol!
> In the examples presented here, the instance name `default` is used.
### IPv4 Static routes
@@ -979,7 +934,6 @@ router 192.168.1.1, using the highest possible distance:
admin@example:/config/routing/control-plane-protocol/static/name/default/> leave
admin@example:/>
> [!TIP]
> Remember to enable [IPv4 forwarding](#IPv4-forwarding) for the
> interfaces you want to route between.
@@ -1003,7 +957,6 @@ enable OSPF and set one active interface in area 0:
admin@example:/config/routing/control-plane-protocol/ospfv2/name/default/> leave
admin@example:/>
> [!TIP]
> Remember to enable [IPv4 forwarding](#IPv4-forwarding) for all the
> interfaces you want to route between.
@@ -1058,38 +1011,6 @@ an Ethernet interface can be done as follows.
admin@example:/config/routing/control-plane-protocol/ospfv2/name/default/ospf/area/0.0.0.0/interface/e0/> set interface-type point-to-point
admin@example:/config/routing/control-plane-protocol/ospfv2/name/default/ospf/area/0.0.0.0/interface/e0/>
#### OSPF global settings
In addition to *area* and *interface* specific settings, OSPF provides
global settings for route redistribution and OSPF router identifier.
```
admin@example:/config/> edit routing control-plane-protocol ospfv2 name default ospf
admin@example:/config/routing/control-plane-protocol/ospfv2/name/default/ospf/> set ?
area List of OSPF areas.
default-route-advertise Distribute default route to network
explicit-router-id Defined in RFC 2328. A 32-bit number
redistribute Redistribute protocols into OSPF
admin@example:/config/routing/control-plane-protocol/ospfv2/name/default/ospf/> set
```
- Explicit router ID: By default the router will pick an IP address
from one of its OSPF interfaces as OSPF router ID. An explicit ID is
used to get a deterministic behavior, e.g., `set explicit-router-id
1.1.1.1`.
- Redistribution: `set redistribute static` and `set redistribute connected`
can be used to include static or connected routes into the OSPF routing
domain. These routes are redistributed as *external type-2* (E2)
routes.
- Advertising default route: An OSPF router can be made to distribute
a default route into the OSPF domain by command `set
default-route-advertise enabled`. This route is distributed as long
as the router itself has an *active* default route in its routing
table. By adding command `set default-route-advertise always` the
router will distribute a default route even when it lacks a default
route. The default route will be distributed as an *external type-2*
(E2) route.
#### Debug OSPFv2
@@ -1192,11 +1113,10 @@ different next-hop, learned from a DHCP server wins over an OSPF route.
The distance used for static routes and DHCP routes can be changed by
setting a different *routing preference* value.
> [!NOTE]
> The kernel metric is an unsigned 32-bit value, which is read by Frr as
> (upper) 8 bits distance and 24 bits metric. But it does not write it
> back to the kernel FIB this way, only selected routes are candidates
> to be installed in the FIB by Frr.
> **Note:** the kernel metric is an unsigned 32-bit value, which is read
> by Frr as (upper) 8 bits distance and 24 bits metric. But it does not
> write it back to the kernel FIB this way, only selected routes are
> candidates to be installed in the FIB by Frr.
#### Source protocol
-64
View File
@@ -653,70 +653,6 @@ on interface *e0*.
~$
```
### Change a Binary Setting
A YANG `binary` type setting is Base64 encoded and requires a little bit
more tricks. We take the opportunity to showcase a shell script helper:
`/usr/bin/text-editor`, which works just like the `text-editor` command
in the CLI, but this one takes an XPath argument to the binary leaf to
edit.
Stripped down, it looks something like this:
```bash
if tmp=$(sysrepocfg -G "$xpath"); then
file=$(mktemp)
echo "$tmp" | base64 -d > "$file"
if edit "$file"; then
tmp=$(base64 -w0 < "$file")
sysrepocfg -S "$xpath" -u "$tmp"
fi
rm -f "$file"
else
echo "Failed to retrieve value for $xpath"
exit 1
fi
```
An example container configuration, with an embedded file that is
mounted to `/var/www/index.html` can look like this:
```json
"infix-containers:containers": {
"container": [
{
"name": "web",
"image": "oci-archive:/lib/oci/curios-httpd-latest.tar.gz",
"hostname": "web",
"network": {
"interface": [
{
"name": "veth-sys0"
}
]
},
"mount": [
{
"name": "index.html",
"content": "PCFET0NUWVBFIGh0bWwjibberish.shortened.down==",
"target": "/var/www/index.html"
}
]
}
]
}
```
The command to edit this file, and restart the container with the new
contents, look like this:
```
admin@infix:~$ cfg edit "/infix-containers:containers/container[name='web']/mount[name='index.html']/content"
```
### <a id="backup"></a> Backup Configuration Using sysrepocfg And scp
Displaying running or startup configuration is possible with
+1 -1
View File
@@ -1,6 +1,6 @@
#set DEBUG=1
run name:bootstrap log:prio:user.notice norestart <usr/ixinit> \
run name:bootstrap log:prio:user.notice norestart <usr/ixinit-done> \
[S] /usr/libexec/confd/bootstrap \
-- Bootstrapping YANG datastore
+2 -2
View File
@@ -1,4 +1,4 @@
# Locally computed
sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 COPYING
sha256 3e7f777a054fbc29173bcdafe50ca096a8abf9e556bec9f52617c9881c9ce3e3 curios-httpd-oci-arm64-v24.11.0.tar.gz
sha256 bfa52f712301427a21b89cfee31ca315e1404973affaf34b23978a70a3ec4f63 curios-httpd-oci-amd64-v24.11.0.tar.gz
sha256 988a523bf4be543cb4ea1d3472ce4720e0b92511546817028b90150a3f054e9f curios-httpd-oci-arm64-v24.05.0.tar.gz
sha256 25f94a7c44cdbbceca3f89382b8bea0dcd8d178032c97a9113bb69bbc1770528 curios-httpd-oci-amd64-v24.05.0.tar.gz
+2 -4
View File
@@ -4,7 +4,7 @@
#
################################################################################
CURIOS_HTTPD_VERSION = v24.11.0
CURIOS_HTTPD_VERSION = v24.05.0
CURIOS_HTTPD_SOURCE = curios-httpd-oci-$(GO_GOARCH)-$(CURIOS_HTTPD_VERSION).tar.gz
CURIOS_HTTPD_SITE = https://github.com/kernelkit/curiOS/releases/download/$(CURIOS_HTTPD_VERSION)
CURIOS_HTTPD_LICENSE = GPL
@@ -13,9 +13,7 @@ CURIOS_HTTPD_LICENSE_FILES = COPYING
define CURIOS_HTTPD_INSTALL_TARGET_CMDS
mkdir -p $(TARGET_DIR)/lib/oci
cp $(CURIOS_HTTPD_DL_DIR)/$(CURIOS_HTTPD_SOURCE) \
$(TARGET_DIR)/lib/oci/$(CURIOS_HTTPD_NAME)-$(CURIOS_HTTPD_VERSION).tar.gz
ln -sf $(CURIOS_HTTPD_NAME)-$(CURIOS_HTTPD_VERSION).tar.gz \
$(TARGET_DIR)/lib/oci/$(CURIOS_HTTPD_NAME)-latest.tar.gz
$(TARGET_DIR)/lib/oci/$(notdir $(@D)).tar.gz
endef
$(eval $(generic-package))
+2 -2
View File
@@ -1,4 +1,4 @@
# Locally computed
sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 COPYING
sha256 95b3625587738cb0a8cc6e9eb41d10a0b2f77ae99dbb1d9b213148d35268eb75 curios-nftables-oci-arm64-v24.11.0.tar.gz
sha256 4f61ccef90721b8f95a5c7b77b69ccccb5dbd215b9c38986d20e5b245244e902 curios-nftables-oci-amd64-v24.11.0.tar.gz
sha256 f25651505bf4fc635dc8d391f377b1116837e99dee522ce0691c15b090cee818 curios-nftables-oci-arm64-v24.05.0.tar.gz
sha256 025c2a5d6c71c62ebbe6f96d8b9ffa3235d6812e87b51645f6e89357d9762669 curios-nftables-oci-amd64-v24.05.0.tar.gz
+2 -4
View File
@@ -4,7 +4,7 @@
#
################################################################################
CURIOS_NFTABLES_VERSION = v24.11.0
CURIOS_NFTABLES_VERSION = v24.05.0
CURIOS_NFTABLES_SOURCE = curios-nftables-oci-$(GO_GOARCH)-$(CURIOS_NFTABLES_VERSION).tar.gz
CURIOS_NFTABLES_SITE = https://github.com/kernelkit/curiOS/releases/download/$(CURIOS_NFTABLES_VERSION)
CURIOS_NFTABLES_LICENSE = GPL
@@ -14,9 +14,7 @@ CURIOS_NFTABLES_INSTALL_TARGET = YES
define CURIOS_NFTABLES_INSTALL_TARGET_CMDS
mkdir -p $(TARGET_DIR)/lib/oci
cp $(CURIOS_NFTABLES_DL_DIR)/$(CURIOS_NFTABLES_SOURCE) \
$(TARGET_DIR)/lib/oci/$(CURIOS_NFTABLES_NAME)-$(CURIOS_NFTABLES_VERSION).tar.gz
ln -sf $(CURIOS_NFTABLES_NAME)-$(CURIOS_NFTABLES_VERSION).tar.gz \
$(TARGET_DIR)/lib/oci/$(CURIOS_NFTABLES_NAME)-latest.tar.gz
$(TARGET_DIR)/lib/oci/$(notdir $(@D)).tar.gz
endef
$(eval $(generic-package))
+1 -3
View File
@@ -1,4 +1,2 @@
task log:prio:local1.notice,tag:container-flush <pid/syslogd> \
[S] container flush -- Cleaning up lingering containers
service log:prio:local1.err,tag:container \
[2345] execd /run/containers/queue -- Container job runner
[2345] execd /run/containers/queue /var/lib/containers/active -- Container job runner
+1
View File
@@ -1,5 +1,6 @@
d /run/containers/args 0700 - -
d /run/containers/files 0700 - -
d /var/lib/containers/active 0700 - -
d /var/lib/containers/oci 0755 - -
d /run/containers/inbox 0700 - -
d /run/containers/queue 0700 - -
+1 -1
View File
@@ -1 +1 @@
service [S0123456789] <!usr/product,usr/led> iitod -- LED daemon
service [S0123456789] <!pid/syslogd> iitod -- LED daemon
@@ -1,3 +1,3 @@
# Locally calculated
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
sha256 b579d0028c8c88ddea27282f03c8c23fa9a758ad47918aeffb048456cf204375 klish-plugin-sysrepo-b693714a1ff5f8021651d7619556afb19945e5e6-br1.tar.gz
sha256 58b6b271912f9331ea78a815a8cec073924b423403868dd9fcc48de0942f49f8 klish-plugin-sysrepo-213cd51aa8863e7ef66944137db3dffc88d58cc1-br1.tar.gz
@@ -4,7 +4,7 @@
#
################################################################################
KLISH_PLUGIN_SYSREPO_VERSION = b693714a1ff5f8021651d7619556afb19945e5e6
KLISH_PLUGIN_SYSREPO_VERSION = 213cd51aa8863e7ef66944137db3dffc88d58cc1
KLISH_PLUGIN_SYSREPO_SITE = https://github.com/kernelkit/klish-plugin-sysrepo.git
#KLISH_PLUGIN_SYSREPO_VERSION = cdd3eb51a7f7ee0ed5bd925fa636061d3b1b85fb
#KLISH_PLUGIN_SYSREPO_SITE = https://src.libcode.org/pkun/klish-plugin-sysrepo.git
+1 -1
View File
@@ -1,3 +1,3 @@
# Locally calculated
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
sha256 0305355dd29dc276f7957d51e2406907e0c862dfd46f496c8a921df4f3d72a8d klish-019ebd2704e322b5d500f5687d526431e535eec8-br1.tar.gz
sha256 4293851b355285be3564873fc1f92ce5a3f4386fe8ce1195f18a79b55b5c99ac klish-710a6314c00bc0485221769d73a5b5d6897c1d81-br1.tar.gz
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
KLISH_VERSION = 019ebd2704e322b5d500f5687d526431e535eec8
KLISH_VERSION = 710a6314c00bc0485221769d73a5b5d6897c1d81
KLISH_SITE = https://github.com/kernelkit/klish.git
#KLISH_VERSION = tags/3.0.0
#KLISH_SITE = https://src.libcode.org/pkun/klish.git
@@ -204,6 +204,14 @@ endif
endif # BR2_PACKAGE_QUAGGA
ifeq ($(BR2_PACKAGE_RNG_TOOLS),y)
define SKELETON_INIT_FINIT_SET_RNGD
cp $(SKELETON_INIT_FINIT_AVAILABLE)/rngd.conf $(FINIT_D)/available/
ln -sf ../available/rngd.conf $(FINIT_D)/enabled/rngd.conf
endef
SKELETON_INIT_FINIT_POST_INSTALL_TARGET_HOOKS += SKELETON_INIT_FINIT_SET_RNGD
endif
ifeq ($(BR2_PACKAGE_SMCROUTE),y)
define SKELETON_INIT_FINIT_SET_SMCROUTE
cp $(SKELETON_INIT_FINIT_AVAILABLE)/smcroute.conf $(FINIT_D)/available/
@@ -0,0 +1 @@
service [S12345789] log rngd -f -- Entropy gathering daemon (rngd)
@@ -1,7 +1,7 @@
From 4be3e500b670f7b98e3dd6696b8e51e83f122c65 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 25 Jan 2024 21:36:59 +0100
Subject: [PATCH 01/34] net: phy: add support for PHY LEDs polarity modes
Subject: [PATCH 01/33] net: phy: add support for PHY LEDs polarity modes
Organization: Addiva Elektronik
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
@@ -22,7 +22,6 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/phy_device.c | 16 ++++++++++++++++
include/linux/phy.h | 22 ++++++++++++++++++++++
@@ -1,7 +1,7 @@
From 4833b140cd11a57dd9f59754cdacfd71bc564c8f Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 4 Dec 2023 11:08:11 +0100
Subject: [PATCH 02/34] net: mvmdio: Support setting the MDC frequency on XSMI
Subject: [PATCH 02/33] net: mvmdio: Support setting the MDC frequency on XSMI
controllers
Organization: Addiva Elektronik
@@ -14,7 +14,6 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20231204100811.2708884-4-tobias@waldekranz.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/ethernet/marvell/mvmdio.c | 44 +++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
@@ -1,7 +1,7 @@
From 50a2973e8a520a82e9f9ec15a1f69e059ce7a334 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:23 +0100
Subject: [PATCH 03/34] net: dsa: mv88e6xxx: Create API to read a single stat
Subject: [PATCH 03/33] net: dsa: mv88e6xxx: Create API to read a single stat
counter
Organization: Addiva Elektronik
@@ -16,7 +16,6 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 162 ++++++++++++++++++-------------
drivers/net/dsa/mv88e6xxx/chip.h | 27 +++---
@@ -1,7 +1,7 @@
From 5916503e23e7f85796c1f927747e66b9535bac53 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:25 +0100
Subject: [PATCH 04/34] net: dsa: mv88e6xxx: Give each hw stat an ID
Subject: [PATCH 04/33] net: dsa: mv88e6xxx: Give each hw stat an ID
Organization: Addiva Elektronik
With the upcoming standard counter group support, we are no longer
@@ -16,7 +16,6 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 138 +++++++++++++++++--------------
1 file changed, 75 insertions(+), 63 deletions(-)
@@ -1,7 +1,7 @@
From 32dda6562734ec8ee667bc546f3ef56794d5bf82 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:26 +0100
Subject: [PATCH 05/34] net: dsa: mv88e6xxx: Add "eth-mac" counter group
Subject: [PATCH 05/33] net: dsa: mv88e6xxx: Add "eth-mac" counter group
support
Organization: Addiva Elektronik
@@ -12,7 +12,6 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 39 ++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
@@ -1,7 +1,7 @@
From 36adbdd466ec550cab8b2ae54177f674c02cf631 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:27 +0100
Subject: [PATCH 06/34] net: dsa: mv88e6xxx: Limit histogram counters to
Subject: [PATCH 06/33] net: dsa: mv88e6xxx: Limit histogram counters to
ingress traffic
Organization: Addiva Elektronik
@@ -27,7 +27,6 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 6 +++---
drivers/net/dsa/mv88e6xxx/global1.c | 7 +++----
@@ -1,7 +1,7 @@
From abfa532c1149525b128b8c76d80965f55e208240 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:28 +0100
Subject: [PATCH 07/34] net: dsa: mv88e6xxx: Add "rmon" counter group support
Subject: [PATCH 07/33] net: dsa: mv88e6xxx: Add "rmon" counter group support
Organization: Addiva Elektronik
Report the applicable subset of an mv88e6xxx port's counters using
@@ -11,7 +11,6 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 42 ++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
@@ -1,13 +1,11 @@
From 4407b94b4a08536fccb6eea2826955ff12d63ec2 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 19:44:32 +0100
Subject: [PATCH 09/34] net: dsa: mv88e6xxx: Add LED infrastructure
Subject: [PATCH 09/33] net: dsa: mv88e6xxx: Add LED infrastructure
Organization: Addiva Elektronik
Parse DT for LEDs and register them for devices that support it,
though no actual implementations exist yet.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/Makefile | 1 +
drivers/net/dsa/mv88e6xxx/chip.c | 5 +-
@@ -1,15 +1,13 @@
From a5cf5c0353db07e74d7a29dd4d5c2cb7775d5bec Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 21:59:35 +0100
Subject: [PATCH 10/34] net: dsa: mv88e6xxx: Add LED support for 6393X
Subject: [PATCH 10/33] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Addiva Elektronik
Trigger support:
- "none"
- "timer"
- "netdev"
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
drivers/net/dsa/mv88e6xxx/leds.c | 226 +++++++++++++++++++++++++++++++
@@ -1,15 +1,13 @@
From be94ec851dbb8e55c3f5e82f197b2dc59566aea2 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Mar 2024 10:27:24 +0100
Subject: [PATCH 11/34] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
Subject: [PATCH 11/33] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
6393X
Organization: Addiva Elektronik
In a multi-chip setup, delays of up to 750ms are observed before the
device (6393X) signals completion of PPU initialization (Global 1,
register 0, bit 15). Therefore, increase the timeout threshold to 1s.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -1,7 +1,7 @@
From 69092f83541e6539ab82eec3052325c403675de4 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 16 Jan 2024 16:00:55 +0100
Subject: [PATCH 12/34] net: dsa: Support MDB memberships whose L2 addresses
Subject: [PATCH 12/33] net: dsa: Support MDB memberships whose L2 addresses
overlap
Organization: Addiva Elektronik
@@ -29,8 +29,6 @@ as long as the count is positive. Fortunately, all the infrastructure
needed to do this is already in place, since it is also needed on CPU
and DSA ports. Thus, "implement" this by simply removing the guards
which previously skipped reference countung on user ports.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
net/dsa/switch.c | 16 ----------------
1 file changed, 16 deletions(-)
@@ -1,7 +1,7 @@
From 7c19df77212d0728874515e97cf297863a6ff2cd Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 13/34] net: phy: marvell10g: Support firmware loading on
Subject: [PATCH 13/33] net: phy: marvell10g: Support firmware loading on
88X3310
Organization: Addiva Elektronik
@@ -11,8 +11,6 @@ its RAM, ask userspace for the binary and load it over XMDIO.
We have no choice but to bail out of the probe if firmware is not
available, as the device does not have any built-in image on which to
fall back.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 161 +++++++++++++++++++++++++++++++++++
1 file changed, 161 insertions(+)
@@ -1,15 +1,13 @@
From 0c34b42b7a72ddf1af6f3534870d647801e493fa Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 21 Nov 2023 20:15:24 +0100
Subject: [PATCH 14/34] net: phy: marvell10g: Fix power-up when strapped to
Subject: [PATCH 14/33] net: phy: marvell10g: Fix power-up when strapped to
start powered down
Organization: Addiva Elektronik
On devices which are hardware strapped to start powered down (PDSTATE
== 1), make sure that we clear the power-down bit on all units
affected by this setting.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
@@ -1,7 +1,7 @@
From 6576918d3348f8e20802379d568d7632228af4d7 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 Nov 2023 20:58:42 +0100
Subject: [PATCH 15/34] net: phy: marvell10g: Add LED support for 88X3310
Subject: [PATCH 15/33] net: phy: marvell10g: Add LED support for 88X3310
Organization: Addiva Elektronik
Pickup the LEDs from the state in which the hardware reset or
@@ -17,8 +17,6 @@ Trigger support:
software blinking
- "netdev": Offload link or duplex information to the solid behavior;
tx and/or rx activity to blink behavior.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 422 +++++++++++++++++++++++++++++++++++
1 file changed, 422 insertions(+)
@@ -1,7 +1,7 @@
From 1ad7f010e46133c725df5cab4d85f71f689ca191 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Dec 2023 09:51:05 +0100
Subject: [PATCH 16/34] net: phy: marvell10g: Support LEDs tied to a single
Subject: [PATCH 16/33] net: phy: marvell10g: Support LEDs tied to a single
media side
Organization: Addiva Elektronik
@@ -14,8 +14,6 @@ tied to a particular media side, and use that information to refine
the offloading of the "netdev" trigger, such that LEDs attached to the
RJ45 jack only lights up when a copper link is established, and vice
versa for the SFP cage.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/marvell10g.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
@@ -1,7 +1,7 @@
From 11b9a3e328241edede03b6615bb9b0f1a40b9b7d Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 24 Nov 2023 23:29:55 +0100
Subject: [PATCH 17/34] nvmem: layouts: onie-tlv: Let device probe even when
Subject: [PATCH 17/33] nvmem: layouts: onie-tlv: Let device probe even when
TLV is invalid
Organization: Addiva Elektronik
@@ -13,8 +13,6 @@ be successfully probed.
Therefore, settle for reporting data corruption issues in the log, and
simply refrain from registering any cells in those cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/nvmem/layouts/onie-tlv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
@@ -1,7 +1,7 @@
From ce1148b5c2e33541ad13ff2c4769d0b37d4e42b9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 4 Mar 2024 16:47:28 +0100
Subject: [PATCH 18/34] net: bridge: avoid classifying unknown multicast as
Subject: [PATCH 18/33] net: bridge: avoid classifying unknown multicast as
mrouters_only
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From ce74ee8c5461cc53851ca323b4dfc9937cab0e41 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 06:44:41 +0100
Subject: [PATCH 19/34] net: bridge: Ignore router ports when forwarding L2
Subject: [PATCH 19/33] net: bridge: Ignore router ports when forwarding L2
multicast
Organization: Addiva Elektronik
@@ -1,10 +1,9 @@
From 3c9b05198e0b7193f2dcddc1860cd77f0adbc3a2 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Mar 2024 19:12:15 +0100
Subject: [PATCH 20/34] net: dsa: Support EtherType based priority overrides
Subject: [PATCH 20/33] net: dsa: Support EtherType based priority overrides
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/net/dsa.h | 4 ++++
net/dsa/slave.c | 56 +++++++++++++++++++++++++++++++++++++++++++++--
@@ -1,11 +1,10 @@
From 333134a4ff2b8dd7fb00a75560254de96d1082ad Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 22 Mar 2024 16:15:43 +0100
Subject: [PATCH 21/34] net: dsa: mv88e6xxx: Support EtherType based priority
Subject: [PATCH 21/33] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/chip.h | 21 ++++++++++
@@ -1,7 +1,7 @@
From cdddc24c05cedc0d0fabc48da17ec26aeb7c1ef9 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 10:10:19 +0100
Subject: [PATCH 22/34] net: phy: Do not resume PHY when attaching
Subject: [PATCH 22/33] net: phy: Do not resume PHY when attaching
Organization: Addiva Elektronik
The PHY should not start negotiating with its link-partner until
@@ -15,8 +15,6 @@ Otherwise, drivers that attached to their PHYs during
probing (e.g. DSA) would end up with a physical link being
established, even though the corresponding interface was still
administratively down.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/phy/phy_device.c | 1 -
1 file changed, 1 deletion(-)
@@ -1,7 +1,7 @@
From 1ec21a3fc54fb447501fd7edbf692b00a31fe3ec Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 15:52:43 +0100
Subject: [PATCH 23/34] net: dsa: mv88e6xxx: Improve indirect register access
Subject: [PATCH 23/33] net: dsa: mv88e6xxx: Improve indirect register access
perf on 6393
Organization: Addiva Elektronik
@@ -13,8 +13,6 @@ previous families).
Therefore, add a new set of SMI operations which remaps accesses to
such registers to the corresponding directly addressable register. All
other accesses use the regular indirect interface.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 7 +++
drivers/net/dsa/mv88e6xxx/global1.h | 3 ++
@@ -1,7 +1,7 @@
From 5d7be493dcaa75ee69d521043062389d7772f8dc Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 4 Apr 2024 16:36:30 +0200
Subject: [PATCH 24/34] net: bridge: drop delay for applying strict multicast
Subject: [PATCH 24/33] net: bridge: drop delay for applying strict multicast
filtering
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 492a824661dbc188b5abeb7434b5cf67c2016415 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 22 Apr 2024 23:18:01 +0200
Subject: [PATCH 25/34] net: dsa: mv88e6xxx: Honor ports being managed via
Subject: [PATCH 25/33] net: dsa: mv88e6xxx: Honor ports being managed via
in-band-status
Organization: Addiva Elektronik
@@ -13,8 +13,6 @@ USXGMII autoneg)
This state is the default set up by mv88e6xxx_port_setup_mac(), so all
we have to do is to make the phylink MAC callbacks no-ops in cases
when in-band-status is being used.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 6 ++++++
1 file changed, 6 insertions(+)
@@ -1,7 +1,7 @@
From c9c9597a47b00b720f5223c83ab05bb89481eda8 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 21:35:26 +0200
Subject: [PATCH 26/34] net: dsa: mv88e6xxx: Fix port policy config on 6393X
Subject: [PATCH 26/33] net: dsa: mv88e6xxx: Fix port policy config on 6393X
Organization: Addiva Elektronik
mv88e6393x_port_policy_{read,write} expect the `pointer` argument to
@@ -16,7 +16,6 @@ never enabled on DSA ports, which broke standalone port isolation in
multichip switch trees made up of 6393X decices.
Fixes: 6584b26020fc ("net: dsa: mv88e6xxx: implement .port_set_policy for Amethyst")
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/port.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -1,7 +1,7 @@
From 4ff224b5f5de1347a1f686aa85cb918a7db18879 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 22:41:04 +0200
Subject: [PATCH 27/34] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
Subject: [PATCH 27/33] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
ports on 6393X
Organization: Addiva Elektronik
@@ -29,8 +29,6 @@ Before this change, due to rsvd2cpu being enabled on the CPU port, the
switch would try to trap it back to the CPU. Given that the CPU is
trusted, instead assume that it indeed meant for the packet to be
forwarded like any other.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/port.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
@@ -1,7 +1,7 @@
From f0d4beabe769fec594b309c3f1ebb79cfdbede8b Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 29 Apr 2024 15:14:51 +0200
Subject: [PATCH 28/34] usb: core: adjust log level for unauthorized devices
Subject: [PATCH 28/33] usb: core: adjust log level for unauthorized devices
Organization: Addiva Elektronik
The fact that a USB device currently is not authorized is not an error,
@@ -1,7 +1,7 @@
From 5f96d718c850084504c53ec0b8d9fcf75ea9996c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 May 2024 13:50:58 +0200
Subject: [PATCH 29/34] net: dsa: mv88e6xxx: Grab register lock during counter
Subject: [PATCH 29/33] net: dsa: mv88e6xxx: Grab register lock during counter
snapshotting
Organization: Addiva Elektronik
@@ -9,8 +9,6 @@ This was missing for the standard counter groups. Since no caller
already holds the lock, opt for pushing the locking down into
mv88e6xxx_stats_snapshot() rather than having it duplicated at each
call site.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
@@ -1,7 +1,7 @@
From 6d4c436335003259cc02a0f015fd3d1d54e988a2 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 May 2024 14:51:54 +0200
Subject: [PATCH 30/34] net: bridge: Differentiate MDB additions from
Subject: [PATCH 30/33] net: bridge: Differentiate MDB additions from
modifications
Organization: Addiva Elektronik
@@ -21,8 +21,6 @@ generated.
Therefore, discriminate new groups from changes to existing groups by
introducing a RTM_SETMDB events to be used in the latter scenario.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/uapi/linux/rtnetlink.h | 2 ++
net/bridge/br_mdb.c | 4 ++--
@@ -1,7 +1,7 @@
From c333c612688d5e974b95fcf4b04f185d7cf4f80d Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 10:38:42 +0200
Subject: [PATCH 31/34] net: dsa: tag_dsa: Use tag priority as initial
Subject: [PATCH 31/33] net: dsa: tag_dsa: Use tag priority as initial
skb->priority
Organization: Addiva Elektronik
@@ -19,8 +19,6 @@ Ideally we could then map this priority to an internal one, like we
can do with an "ingress-qos-map" on VLAN interfaces. Until that is
implemented, support the setup that is likely to be the most common; a
1:1 mapping from FPri to skb->priority.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
net/dsa/tag_dsa.c | 7 +++++++
1 file changed, 7 insertions(+)
@@ -1,7 +1,7 @@
From 18c025745fd8b8c9b3e688e9d78668a56cf71217 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 11:04:22 +0200
Subject: [PATCH 32/34] net: dsa: mv88e6xxx: Add mqprio qdisc support
Subject: [PATCH 32/33] net: dsa: mv88e6xxx: Add mqprio qdisc support
Organization: Addiva Elektronik
Add support for attaching mqprio qdisc's to mv88e6xxx ports and use
@@ -24,8 +24,6 @@ are effectively only specifying the QPri.
Since FPri is always a 3-bit field, even on older chips with only 4
physical queues, always report 8 queues and let the chip's policy
handle the mapping down to the "real" number.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 70 ++++++++++++++++++++++++++++++++
net/dsa/tag_dsa.c | 4 +-
@@ -1,7 +1,7 @@
From f2d4ff12c7a0e644cbeac6675b755fb4a87b362a Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 29 May 2024 13:20:41 +0200
Subject: [PATCH 33/34] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
Subject: [PATCH 33/33] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
are available
Organization: Addiva Elektronik
@@ -22,8 +22,6 @@ main reasons for choosing the new default:
packet's priority. As the packet then moves through the network
core over trusted VLAN trunks, the packet should keep its original
priority, independent of what inner protocol fields may indicate.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
@@ -1,43 +0,0 @@
From ceaaa4f44f9b3ec82c4e0a24c2322aae58fa3aa0 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 6 Nov 2024 15:39:33 +0100
Subject: [PATCH 34/34] net: dsa: mb88e6xxx: use EOPNOTSUPP for unsupported
flags
Organization: Addiva Elektronik
Make sure to return correct error code for unsupported flags, and
propagate any error.
Follow-up to a5cf5c0
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
drivers/net/dsa/mv88e6xxx/leds.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
index b2a55d96b506..fe1ed3ed2a8a 100644
--- a/drivers/net/dsa/mv88e6xxx/leds.c
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
@@ -99,7 +99,7 @@ static int mv88e6393x_led_flags_to_mode(struct mv88e6xxx_led *led, unsigned long
return i;
}
- return -EINVAL;
+ return -EOPNOTSUPP;
}
static int mv88e6393x_led_mode_to_flags(struct mv88e6xxx_led *led, u8 mode,
@@ -216,6 +216,9 @@ static int mv88e6393x_led_hw_control_set(struct mv88e6xxx_led *led,
{
int mode = mv88e6393x_led_flags_to_mode(led, flags);
+ if (mode < 0)
+ return mode;
+
return mv88e6393x_led_set(led, mode);
}
--
2.43.0
@@ -1,21 +0,0 @@
This patch disables the default "podman pull" retry value, which otherwise
blocks execd from trying other jobs in its queue.
As of podman v5.0.0 a --retry=NUM has been added to the podman create, run,
and pull commands. However, CNI is no longer supported, and a lot of other
breaking changes have been made, e.g., output of podman inspect. So there's
a lot of work upgrading.
-- Joachim
--- a/vendor/github.com/containers/common/libimage/copier.go 2023-04-14 15:28:20.000000000 +0200
+++ b/vendor/github.com/containers/common/libimage/copier.go 2024-11-16 13:05:42.207641898 +0100
@@ -24,7 +24,7 @@
)
const (
- defaultMaxRetries = 3
+ defaultMaxRetries = 0
defaultRetryDelay = time.Second
)
@@ -1,29 +0,0 @@
This makes the output more user friendly on systems where the bootname
is the common way to refer to a slot.
Example output:
...
40% Checking slot rootfs.1 (secondary)
46% Checking slot rootfs.1 (secondary) done.
...
diff --git a/src/install.c b/src/install.c
index ea7c95b3..fb38bcab 100644
--- a/src/install.c
+++ b/src/install.c
@@ -965,7 +965,11 @@ static gboolean handle_slot_install_plan(const RaucManifest *manifest, const RIm
install_args_update(args, "Checking slot %s", plan->target_slot->name);
- r_context_begin_step_weighted_formatted("check_slot", 0, 1, "Checking slot %s", plan->target_slot->name);
+ r_context_begin_step_weighted_formatted("check_slot", 0, 1, "Checking slot %s%s%s%s",
+ plan->target_slot->name,
+ plan->target_slot->bootname ? " (" : "",
+ plan->target_slot->bootname ? plan->target_slot->bootname : "",
+ plan->target_slot->bootname ? ")" : "");
r_slot_status_load(plan->target_slot);
slot_state = plan->target_slot->status;
--
2.34.1
@@ -1,24 +0,0 @@
Print "the standard" warning banner at start of installation.
diff --git a/src/main.c b/src/main.c
index 8e851b47..bba1d012 100644
--- a/src/main.c
+++ b/src/main.c
@@ -258,6 +258,14 @@ static gboolean install_start(int argc, char **argv)
if (access_args.http_headers)
args->access_args.http_headers = g_strdupv(access_args.http_headers);
+ g_print("+------------------------------------------------------------------------------+\n");
+ g_print("| |\n");
+ g_print("| [!] Installation might take a while. DO NOT power off the device. |\n");
+ g_print("| |\n");
+ g_print("| Please wait while the upgrade completes. |\n");
+ g_print("| |\n");
+ g_print("+------------------------------------------------------------------------------+\n");
+
r_loop = g_main_loop_new(NULL, FALSE);
if (ENABLE_SERVICE) {
g_auto(GVariantDict) dict = G_VARIANT_DICT_INIT(NULL);
--
2.34.1
+11 -15
View File
@@ -1,23 +1,19 @@
#!/bin/sh
set -e
if jq -e '.["usb-ports"]' /run/system.json > /dev/null; then
usb_ports=$(jq -r '.["usb-ports"] | map(.name) | unique | join(" ")' /run/system.json)
else
usb_ports=""
fi
usb_ports=$(cat /run/system.json | jq -r '.["usb-ports"] | map(.name) | unique | join(" ")')
gen_port()
{
port="$1"
cat <<EOF
{
"class": "infix-hardware:usb",
"name": "$port",
"state": {
"admin-state": "unlocked"
}
}
local port="$1"
cat <<EOF
{
"class": "infix-hardware:usb",
"name": "$port",
"state": {
"admin-state": "unlocked"
}
}
EOF
}
first=1
@@ -28,7 +24,7 @@ cat <<EOF
EOF
for port in $usb_ports; do
if [ $first -eq 0 ]; then
echo -n ','
echo -n ','
fi
first=0;
gen_port "$port"
+131 -72
View File
@@ -13,16 +13,13 @@
#include <srx/srx_val.h>
#include "core.h"
#define ARPING_MSEC 1000
#define LOGGER "logger -t container -p local1.notice"
#define MODULE "infix-containers"
#define CFG_XPATH "/infix-containers:containers"
#define _PATH_CONT "/run/containers"
#define _PATH_INBOX _PATH_CONT "/INBOX"
#define _PATH_QUEUE _PATH_CONT "/queue"
#define INBOX_QUEUE "/run/containers/inbox"
#define JOB_QUEUE "/run/containers/queue"
#define ACTIVE_QUEUE "/var/lib/containers/active"
#define LOGGER "logger -t container -p local1.notice"
static int add(const char *name, struct lyd_node *cif)
@@ -30,21 +27,19 @@ static int add(const char *name, struct lyd_node *cif)
const char *image = lydx_get_cattr(cif, "image");
const char *restart_policy, *string;
struct lyd_node *node, *nets, *caps;
char script[strlen(name) + 5];
FILE *fp, *ap;
snprintf(script, sizeof(script), "%s.sh", name);
fp = fopenf("w", "%s/%s", _PATH_CONT, script);
fp = fopenf("w", "%s/S01-%s.sh", INBOX_QUEUE, name);
if (!fp) {
ERRNO("Failed creating container script %s/%s", _PATH_CONT, script);
ERRNO("Failed adding job S01-%s.sh to job queue" INBOX_QUEUE, name);
return SR_ERR_SYS;
}
/* Stop any running container gracefully so it releases its IP addresses. */
fprintf(fp, "#!/bin/sh\n"
"container --quiet stop %s >/dev/null\n" /* Silence "not running" on upgrade */
"container --quiet delete %s >/dev/null\n" /* Silence any hashes when deleting */
"container --quiet", name, name);
"container stop %s >/dev/null\n" /* Silence "not running" on upgrade */
"container delete %s >/dev/null\n" /* Silence any hashes when deleting */
"container", name, name);
LYX_LIST_FOR_EACH(lyd_child(cif), node, "dns")
fprintf(fp, " --dns %s", lyd_get_value(node));
@@ -61,6 +56,9 @@ static int add(const char *name, struct lyd_node *cif)
fprintf(fp, " --hostname %s", buf);
}
if (lydx_is_enabled(cif, "read-only"))
fprintf(fp, " --read-only");
if (lydx_is_enabled(cif, "privileged"))
fprintf(fp, " --privileged");
@@ -175,61 +173,43 @@ static int add(const char *name, struct lyd_node *cif)
if (lydx_is_enabled(cif, "manual"))
fprintf(fp, " --manual");
node = lydx_get_descendant(lyd_child(cif), "checksum", NULL);
if (node) {
if ((string = lydx_get_cattr(node, "md5")))
fprintf(fp, " --checksum md5:%s", string);
if ((string = lydx_get_cattr(node, "sha256")))
fprintf(fp, " --checksum sha256:%s", string);
if ((string = lydx_get_cattr(node, "sha512")))
fprintf(fp, " --checksum sha512:%s", string);
}
fprintf(fp, " create %s %s", name, image);
if ((string = lydx_get_cattr(cif, "command")))
fprintf(fp, " %s", string);
fprintf(fp, "\n");
if (lydx_is_enabled(cif, "manual"))
fprintf(fp, "initctl -bnq cond set container:%s\n", name);
fchmod(fileno(fp), 0700);
fclose(fp);
systemf("initctl -bnq enable container@%s.conf", name);
/*
* All start scripts must wait for the rest of confd to complete
* before being enqueued to execd, so we postpone it using this
* "inbox" to the post hook.
*/
writesf(script, "a", "%s", _PATH_INBOX);
return 0;
}
static int del(const char *name)
{
char fn[strlen(_PATH_QUEUE) + strlen(name) + 10];
const char *queue[] = {
JOB_QUEUE,
INBOX_QUEUE,
ACTIVE_QUEUE,
};
FILE *fp;
/* Remove any pending download/create job first */
snprintf(fn, sizeof(fn), "%s/S01-%s.sh", _PATH_QUEUE, name);
erase(fn);
for (size_t i = 0; i < NELEMS(queue); i++) {
char fn[strlen(queue[i]) + strlen(name) + 5];
/* Remove container script itself */
snprintf(fn, sizeof(fn), "%s/%s.sh", _PATH_CONT, name);
erase(fn);
snprintf(fn, sizeof(fn), "%s/%s.sh", queue[i], name);
erase(fn);
}
/* Disable service and schedule for deletion. */
systemf("initctl -bnq disable container@%s.conf", name);
snprintf(fn, sizeof(fn), "%s/K01-%s.sh", _PATH_CONT, name);
fp = fopen(fn, "w");
fp = fopenf("w", "%s/K01-%s.sh", INBOX_QUEUE, name);
if (!fp) {
ERRNO("Failed creating container stop script %s", fn);
ERRNO("Failed adding job 00-delete-%s.sh to job queue" INBOX_QUEUE, name);
return SR_ERR_SYS;
}
@@ -238,9 +218,6 @@ static int del(const char *name)
fchmod(fileno(fp), 0700);
fclose(fp);
/* Enqueue kill job immediately on execd */
movefile(fn, _PATH_QUEUE);
return SR_ERR_OK;
}
@@ -356,42 +333,124 @@ static int oci_load(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
return SR_ERR_OK;
}
static int is_active(sr_session_ctx_t *session, const char *name)
{
return srx_enabled(session, CFG_XPATH "/container[name='%s']/enabled", name);
}
static int is_manual(sr_session_ctx_t *session, const char *name)
{
return srx_enabled(session, CFG_XPATH "/container[name='%s']/manual", name);
}
/*
* When container configurations are not saved to startup-config and the
* user reboot the system (or lose power) we will have lingering active
* containers cached on persistent storage.
*
* This function runs every time a configuration is applied to clean up
* any lingering active jobs to prevent false matches in the cmp magic
* in the below post-hook.
*/
static void cleanup(sr_session_ctx_t *session, struct confd *confd)
{
struct dirent *d;
DIR *dir;
dir = opendir(ACTIVE_QUEUE);
if (!dir)
return;
while ((d = readdir(dir))) {
char name[strlen(ACTIVE_QUEUE) + strlen(d->d_name) + 2];
char *ptr;
if (d->d_name[0] == '.')
continue;
strlcpy(name, d->d_name, sizeof(name));
ptr = strstr(name, ".sh");
if (!ptr)
continue; /* odd, non-script file? */
*ptr = 0;
if (strncmp(name, "S01-", 4))
continue; /* odd, not start script? */
if (is_active(session, &name[4]))
continue;
/* Not found in running-config, remove stale cache. */
snprintf(name, sizeof(name), "%s/%s", ACTIVE_QUEUE, d->d_name);
if (erase(name))
ERRNO("Failed removing stale container job %s", name);
}
closedir(dir);
}
/*
* Containers depend on a lot of other system resources being properly
* set up, e.g., networking, which is run by dagger. So we need to wait
* for all that before we can launch new, or modified, containers. This
* post hook runs as (one of) the last actions on a config change/boot.
* for all that before we can launch new, or modified, containers. The
* latter is the tricky part.
*
* By default, containers get a writable layer which is preserved across
* restarts/reboots of container or host -- provided we don't recreate
* them on a reboot. Hence the cmp magic below: we check if the command
* to create a container is the same as what is already activated, if it
* is already activated we know 'podman create' has done its thing and
* we can safely start the container.
*/
void infix_containers_post_hook(sr_session_ctx_t *session, struct confd *confd)
{
char script[256];
FILE *fp;
struct dirent *d;
DIR *dir;
fp = fopen(_PATH_INBOX, "r");
if (!fp)
return; /* nothing to do today */
cleanup(session, confd);
while (fgets(script, sizeof(script), fp)) {
char link[strlen(_PATH_QUEUE) + strlen(script) + 10];
char path[strlen(script) + 10];
chomp(script);
/*
* Enqueue start job on execd, use a symlink since we
* want to be able to reuse the script for manual image
* uprgade (and debugging) purposes.
*/
snprintf(link, sizeof(link), "%s/S01-%s", _PATH_QUEUE, script);
snprintf(path, sizeof(path), "../%s", script);
if (symlink(path, link) && errno != EEXIST)
ERRNO("Creating symlink %s -> %s", link, path);
dir = opendir(INBOX_QUEUE);
if (!dir) {
ERROR("Cannot open %s to launch scripts.", INBOX_QUEUE);
return;
}
fclose(fp);
erase(_PATH_INBOX);
while ((d = readdir(dir))) {
char curr[strlen(ACTIVE_QUEUE) + strlen(d->d_name) + 2];
char next[strlen(INBOX_QUEUE) + strlen(d->d_name) + 2];
systemf("initctl -bnq touch execd");
if (d->d_name[0] == '.')
continue;
snprintf(curr, sizeof(curr), "%s/%s", ACTIVE_QUEUE, d->d_name);
snprintf(next, sizeof(next), "%s/%s", INBOX_QUEUE, d->d_name);
if (!systemf("cmp %s %s >/dev/null 2>&1", curr, next)) {
char name[strlen(d->d_name) + 1];
char *ptr;
strlcpy(name, d->d_name, sizeof(name));
ptr = strstr(name, ".sh");
if (ptr) {
char *nm = NULL;
*ptr = 0;
if (!strncmp(name, "S01-", 4))
nm = &name[4];
/* New job is already active, no changes, skipping ... */
if (nm && !is_manual(session, nm))
systemf("initctl -bnq cond set container:%s", nm);
}
remove(next);
continue;
}
if (movefile(next, JOB_QUEUE))
ERRNO("Failed moving %s to job queue %s", next, JOB_QUEUE);
}
closedir(dir);
systemf("container volume prune -f >/dev/null 2>&1");
}
int infix_containers_init(struct confd *confd)
+2 -2
View File
@@ -27,7 +27,7 @@ MODULES=(
"ieee802-dot1q-types@2022-10-29.yang"
"infix-ip@2024-09-16.yang"
"infix-if-type@2024-10-13.yang"
"infix-routing@2024-11-15.yang"
"infix-routing@2024-10-01.yang"
"ieee802-dot1ab-lldp@2022-03-15.yang"
"infix-lldp@2023-08-23.yang"
"infix-dhcp-client@2024-09-20.yang"
@@ -37,7 +37,7 @@ MODULES=(
"ieee802-ethernet-interface@2019-06-21.yang"
"infix-ethernet-interface@2024-02-27.yang"
"infix-factory-default@2023-06-28.yang"
"infix-interfaces@2024-11-15.yang -e vlan-filtering"
"infix-interfaces@2024-10-28.yang -e vlan-filtering"
# from rousette
"ietf-restconf@2017-01-26.yang"
+2 -2
View File
@@ -1,6 +1,6 @@
# -*- sh -*-
# REMEMBER TO UPDATE infix-interfaces ALSO IN confd.inc
MODULES=(
"infix-interfaces@2024-11-15.yang -e vlan-filtering -e containers"
"infix-containers@2024-11-15.yang"
"infix-interfaces@2024-10-28.yang -e vlan-filtering -e containers"
"infix-containers@2024-10-14.yang"
)
+7 -47
View File
@@ -6,6 +6,10 @@ module infix-containers {
namespace "urn:ietf:params:xml:ns:yang:infix-containers";
prefix infix-cont;
import ietf-yang-types {
prefix yang;
}
import ietf-interfaces {
prefix if;
}
@@ -22,26 +26,19 @@ module infix-containers {
prefix infix-sys;
}
revision 2024-11-15 {
description "Two major changes:
- Add support for ftp/http/https images with checksum
- Deprecate read-only, it is now always true";
reference "internal";
}
revision 2024-10-14 {
revision 2024-10-14 {
description "Two major changes:
- Allow changing name of host interfaces inside container
- Support hostname format specifiers, like ietf-system";
reference "internal";
}
revision 2024-03-27 {
revision 2024-03-27 {
description "Add support for capabilities.";
reference "internal";
}
revision 2024-02-01 {
revision 2024-02-01 {
description "Initial revision";
reference "internal";
}
@@ -136,13 +133,6 @@ module infix-containers {
oci-archive:/lib/oci/archive -- Use archive:latest from OCI archive
May be in .tar or .tar.gz format
Additionally, the following URIs are also supported for setups
that do not use a HUB or similar. Recommend using 'checksum'!
ftp://addr/path/to/archive -- Downloaded using wget
http://addr/path/to/archive -- Downloaded using curl
https://addr/path/to/archive -- Downloaded using curl
Note: if a remote repository cannot be reached, the creation of the
container will be put on a queue that retries pull every time
there is a route change in the host's system.";
@@ -150,35 +140,6 @@ module infix-containers {
type string;
}
container checksum {
description "Checksum for ftp/http/https OCI archives.";
choice checksum {
leaf md5 {
description "MD5 checksum for the archive.";
type string {
length "32";
pattern "[a-fA-F0-9]{32}";
}
}
leaf sha256 {
description "SHA256 checksum for the archive.";
type string {
length "64";
pattern "[a-fA-F0-9]{64}";
}
}
leaf sha512 {
description "SHA512 checksum for the archive.";
type string {
length "128";
pattern "[a-fA-F0-9]{128}";
}
}
}
}
leaf image-id {
description "Docker image ID, exact hash used.";
config false;
@@ -295,7 +256,6 @@ module infix-containers {
}
leaf read-only {
status deprecated; // This is now the default, setting kept only to not break configs
description "Create a read-only container. Use volumes for writable directories.";
type boolean;
}
+6 -4
View File
@@ -3,6 +3,9 @@ submodule infix-if-bridge {
belongs-to infix-interfaces {
prefix infix-if;
}
import ietf-yang-types {
prefix yang;
}
import iana-if-type {
prefix ianaift;
}
@@ -12,6 +15,9 @@ submodule infix-if-bridge {
import ietf-interfaces {
prefix if;
}
import ietf-inet-types {
prefix inet;
}
import ietf-ip {
prefix ip;
}
@@ -26,10 +32,6 @@ submodule infix-if-bridge {
contact "kernelkit@googlegroups.com";
description "Linux bridge extension for ietf-interfaces.";
revision 2024-11-15 {
description "Fix pyang linter warnings, drop unused imports.";
reference "internal";
}
revision 2024-08-26 {
description "Improve must expressions for multicast.
+7 -19
View File
@@ -13,6 +13,9 @@ submodule infix-if-container {
import ietf-ip {
prefix ip;
}
import infix-if-type {
prefix infixift;
}
organization "KernelKit";
contact "kernelkit@googlegroups.com";
@@ -20,13 +23,6 @@ submodule infix-if-container {
Ensures a container interface can never be a bridge port, or
LAG member, at the same time.";
revision 2024-11-15 {
description "Two changes:
- Relocate 'feature containers' declaration to here
- Fix pyang linter errors and warnings, dropping unused
imports and dropping the default value for subnet";
reference "internal";
}
revision 2024-10-29 {
description "Add read only container list to container-network";
reference "internal";
@@ -36,14 +32,6 @@ submodule infix-if-container {
reference "internal";
}
/*
* Features
*/
feature containers {
description "Containers is an optional build-time feature in Infix.";
}
/*
* Identities
*/
@@ -88,9 +76,6 @@ submodule infix-if-container {
list subnet {
description "Static IP ranges to hand out addresses to containers from.
If no subnet is provided, a default 172.17.0.0/16 one is
set up. This is the default in a standard Docker setup.
A container bridge forwards DNS, NTP, and SSH by default to
the host interfaces.";
when "../type = 'infix-if:bridge'";
@@ -98,7 +83,10 @@ submodule infix-if-container {
leaf subnet {
type inet:ip-prefix;
description "Subnet to assign addresses from, round-robin assignment.";
description "Subnet to assign addresses from, round-robin assignment.
The default is from a standard Docker setup.";
default "172.17.0.0/16";
}
leaf gateway {
+10 -17
View File
@@ -4,7 +4,7 @@ module infix-interfaces {
prefix infix-if;
import infix-if-type {
prefix infix-ift;
prefix infixift;
}
import ietf-interfaces {
prefix if;
@@ -23,13 +23,6 @@ module infix-interfaces {
contact "kernelkit@googlegroups.com";
description "Linux bridge and lag extensions for ietf-interfaces.";
revision 2024-11-15 {
description "Two changes:
- Limit name 1-15 chars, Linux limitation
- Relocate 'feature containers' to submodule";
reference "internal";
}
revision 2024-10-28 {
description "Limit description to 64 chars, matching IF-MIB max.";
reference "internal";
@@ -76,6 +69,14 @@ module infix-interfaces {
reference "internal";
}
/*
* Features
*/
feature containers {
description "Containers is an optional build-time feature in Infix.";
}
/*
* Data Nodes
*/
@@ -83,15 +84,7 @@ module infix-interfaces {
deviation "/if:interfaces/if:interface/if:type" {
deviate replace {
type identityref {
base infix-ift:infix-interface-type;
}
}
}
deviation "/if:interfaces/if:interface/if:name" {
deviate replace {
type string {
length "1..15";
base infixift:infix-interface-type;
}
}
}
+26 -6
View File
@@ -15,17 +15,17 @@ module infix-routing {
import ietf-ospf {
prefix ospf;
}
import ietf-interfaces {
prefix if;
}
import ietf-routing-types {
prefix rt-types;
}
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description "Deviations and augments for ietf-routing and ietf-ospf.";
revision 2024-11-15 {
description "Fix pyang linter errors and warnings:
- Drop OSPF database deviations, already deviated earlier
- Drop unused imports";
reference "internal";
}
revision 2024-10-01 {
description "Remove possibility to have loopack in multiple areas.";
reference "internal";
@@ -457,6 +457,26 @@ module infix-routing {
deviate not-supported;
}
/* OSPF database */
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv3" {
deviate not-supported;
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv2/ospf:ospfv2/ospf:body/ospf:opaque" {
deviate not-supported;
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv2/ospf:ospfv2/ospf:body/ospf:external" {
deviate not-supported;
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv2/ospf:ospfv2/ospf:body/ospf:summary" {
deviate not-supported;
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv2/ospf:ospfv2/ospf:body/ospf:router" {
deviate not-supported;
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database/ospf:as-scope-lsa-type/ospf:as-scope-lsas/ospf:as-scope-lsa/ospf:version/ospf:ospfv2/ospf:ospfv2/ospf:header" {
deviate not-supported;
}
/* OSPF RPCs */
deviation "/ospf:clear-neighbor" {
deviate not-supported;
+1 -1
View File
@@ -2,7 +2,7 @@ DISTCLEANFILES = *~ *.d
ACLOCAL_AMFLAGS = -I m4
sbin_PROGRAMS = execd
execd_SOURCES = execd.c execd.h
execd_SOURCES = execd.c
execd_CPPFLAGS = -D_GNU_SOURCE
execd_CFLAGS = -W -Wall -Wextra -Wno-unused
execd_CFLAGS = $(libuev_CFLAGS) $(libite_CFLAGS)
+124 -73
View File
@@ -1,15 +1,38 @@
/* SPDX-License-Identifier: ISC */
#include "execd.h"
#define RETRY_TIMER 60
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SYSLOG_NAMES
#include <syslog.h>
#include <unistd.h>
static uev_t retry_watcher;
static int retry = RETRY_TIMER;
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <sys/inotify.h>
#include <sys/socket.h>
#include <uev/uev.h>
#include <libite/lite.h>
#define err(fmt, args...) syslog(LOG_ERR, fmt ": %s", ##args, strerror(errno))
#define errx(fmt, args...) syslog(LOG_ERR, fmt, ##args)
#define warn(fmt, args...) syslog(LOG_WARNING, fmt, ": %s", ##args, strerror(errno))
#define warnx(fmt, args...) syslog(LOG_WARNING, fmt, ##args)
#define log(fmt, args...) syslog(LOG_NOTICE, fmt, ##args)
#define dbg(fmt, args...) syslog(LOG_DEBUG, fmt, ##args)
static int logmask = LOG_UPTO(LOG_NOTICE);
static char buffer[BUFSIZ];
static char *done;
static int run_job(const char *path, const char *file)
static void run_job(const char *path, char *file, int archive)
{
char cmd[strlen(path) + strlen(file) + 2];
int rc;
@@ -24,28 +47,77 @@ static int run_job(const char *path, const char *file)
snprintf(cmd, sizeof(cmd), "%s/%s", path, file);
if (access(cmd, X_OK)) {
errx("%s skipping, not executable.", cmd);
return -1;
errx("skipping %s, not executable", cmd);
return;
}
dbg("running job %s", cmd);
if ((rc = systemf("%s", cmd))) {
errx("%s failed, exit code: %d", cmd, rc);
return -1;
errx("failed %s: rc %d", cmd, rc);
return;
}
return erase(cmd);
dbg("job %s in %s done %p, archive: %d", file, path, done, archive);
if (done && archive)
movefile(cmd, done);
else
erase(cmd);
}
static int run_dir(const char *path, int type)
/*
* Allow SNN and KNN style jobs, for inotyify_cb() we also allow
* a type '*' just to figure out if a job should be archived in
* the done directory.
*/
static int should_run(const char *name, int type, int *archive)
{
if (!name || strlen(name) < 3)
return 0;
if (isdigit(name[1]) && isdigit(name[2])) {
if (type == '*') {
switch (name[0]) {
case 'K':
*archive = 0;
return 1;
case 'S':
*archive = 1;
return 1;
default:
errx("unsupported '%s', scripts must start with S or K", name);
return 0;
}
}
switch (type) {
case 'K':
*archive = 0;
break;
case 'S':
*archive = 1;
break;
default:
return 0;
}
dbg("name:%s type:'%c' archive:%d => run:%d", name, type, *archive, type == name[0]);
return type == name[0];
}
errx("unsupported script %s, must follow pattern SNN/KNN", name);
return 0;
}
static void run_dir(const char *path, int type)
{
struct dirent **namelist;
int n, i, num = 0;
int archive = 0;
int n, i;
n = scandir(path, &namelist, NULL, alphasort);
if (n < 0) {
err("scandir %s", path);
return 0;
return;
}
for (i = 0; i < n; i++) {
@@ -54,41 +126,28 @@ static int run_dir(const char *path, int type)
if (d->d_type == DT_DIR)
continue;
if (should_run(d->d_name, type))
num += !!run_job(path, d->d_name);
if (should_run(d->d_name, type, &archive))
run_job(path, d->d_name, archive);
free(d);
}
free(namelist);
return num;
}
/*
* Call stop/cleanup jobs first, may use same container name or
* resources as replacement container start scripts use.
*/
static void run_queue(const char *path)
static void run_queue(char *path)
{
int num;
num = run_dir(path, 'K');
num += run_dir(path, 'S');
if (num)
uev_timer_set(&retry_watcher, retry, 0);
run_dir(path, 'K');
run_dir(path, 'S');
}
static void signal_cb(uev_t *w, void *arg, int signo)
static void signal_cb(uev_t *w, void *arg, int _)
{
dbg("signal %d, calling job queue", signo);
run_queue(arg);
}
static void timer_cb(uev_t *w, void *arg, int _)
{
dbg("timer, retry job queue");
dbg("Got signal, calling job queue");
run_queue(arg);
}
@@ -105,7 +164,6 @@ static void toggle_debug(uev_t *w, void *arg, int _)
static void inotify_cb(uev_t *w, void *arg, int _)
{
ssize_t bytes;
int num = 0;
bytes = read(w->fd, buffer, sizeof(buffer));
if (bytes == -1) {
@@ -116,20 +174,18 @@ static void inotify_cb(uev_t *w, void *arg, int _)
for (char *p = buffer; p < buffer + bytes;) {
struct inotify_event *event = (struct inotify_event *)p;
char *name = event->name;
int archive;
if (event->mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO)) {
dbg("Got inotify event %s 0x%04x", name, event->mask);
if (!should_run(name, '*'))
if (!should_run(name, '*', &archive))
continue;
num += !!run_job(arg, name);
run_job(arg, name, archive);
}
p += sizeof(struct inotify_event) + event->len;
}
if (num)
uev_timer_set(&retry_watcher, retry, 0);
}
static void netlink_cb(uev_t *w, void *arg, int _)
@@ -155,20 +211,28 @@ static void netlink_cb(uev_t *w, void *arg, int _)
run_queue(arg);
}
static int usage(const char *arg0, int rc)
int logmask_from_str(const char *str)
{
const CODE *code;
for (code = prioritynames; code->c_name; code++)
if (!strcmp(str, code->c_name))
return LOG_UPTO(code->c_val);
return -1;
}
static int usage(char *arg0, int rc)
{
printf("Usage:\n"
" %s [-dh] [-l LVL] [-t SEC] QUEUE\n"
" %s [-dh] [-l LVL] JOBDIR\n"
"Options:\n"
" -d Log to stderr as well\n"
" -h This help text\n"
" -d Log to stderr as well\n"
" -h This help text\n"
" -l LVL Set log level: none, err, warn, notice*, info, debug\n"
" -t SEC Retry timer in seconds [10, 604800], default: %d\n"
"\n"
"Run jobs from QUEUE. Triggers on inotify of new jobs, route changes, and\n"
"retries failing jobs every minute until the queue has been emtied.\n"
"Use SIGHUP to trigger a manual retry.\n"
"Use SIGUSR1 to toggle debug messages at runtime.\n", arg0, RETRY_TIMER);
"Runs jobs from JOBDIR, re-runs failing jobs on route changes or SIGHUP.\n"
"Use SIGUSR1 to toggle debug messages at runtime.\n", arg0);
return rc;
}
@@ -182,11 +246,11 @@ int main(int argc, char *argv[])
uev_t sighup_watcher;
int logopt = LOG_PID;
int wd, sd, fd, c;
char *queue;
char *jobdir;
uev_ctx_t ctx;
int rc = 0;
while ((c = getopt(argc, argv, "dhl:t:")) != EOF) {
while ((c = getopt(argc, argv, "dhl:")) != EOF) {
switch (c) {
case 'd':
logopt |= LOG_PERROR;
@@ -200,13 +264,6 @@ int main(int argc, char *argv[])
return usage(argv[0], 1);
}
break;
case 't':
retry = atoi(optarg);
if (retry < 10 || retry > 604800) {
fprintf(stderr, "Invalid value %d, accepted [10, 604800]", retry);
return 1;
}
break;
default:
return usage(argv[0], 1);
}
@@ -215,12 +272,13 @@ int main(int argc, char *argv[])
if (optind >= argc)
return usage(argv[0], 1);
queue = argv[optind];
retry *= 1000;
jobdir = argv[optind++];
if (optind < argc)
done = argv[optind];
if (access(queue, X_OK)) {
if (access(jobdir, X_OK)) {
fprintf(stderr, "Cannot find job directory %s, errno %d: %s\n",
queue, errno, strerror(errno));
jobdir, errno, strerror(errno));
return 1;
}
@@ -241,7 +299,7 @@ int main(int argc, char *argv[])
return 1;
}
wd = inotify_add_watch(fd, queue, IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO);
wd = inotify_add_watch(fd, jobdir, IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO);
if (wd == -1) {
err("inotify_add_watch");
close(fd);
@@ -265,37 +323,30 @@ int main(int argc, char *argv[])
}
uev_init(&ctx);
if (uev_signal_init(&ctx, &sighup_watcher, signal_cb, queue, SIGHUP) == -1) {
if (uev_signal_init(&ctx, &sighup_watcher, signal_cb, jobdir, SIGHUP) == -1) {
err("uev_signal_init (sighup)");
rc = 1;
goto done;
}
/* Initial delay of 1 sec, lots of other events happening at boot. */
if (uev_timer_init(&ctx, &retry_watcher, timer_cb, queue, 1000, 0) == -1) {
err("uev_timer_init (1000, %d)", retry);
rc = 1;
goto done;
}
if (uev_signal_init(&ctx, &sigusr1_watcher, toggle_debug, NULL, SIGUSR1) == -1) {
err("uev_signal_init (sigusr1)");
rc = 1;
goto done;
}
if (uev_io_init(&ctx, &inotify_watcher, inotify_cb, queue, fd, UEV_READ) == -1) {
if (uev_io_init(&ctx, &inotify_watcher, inotify_cb, jobdir, fd, UEV_READ) == -1) {
err("uev_io_init (inotify)");
rc = 1;
goto done;
}
if (uev_io_init(&ctx, &netlink_watcher, netlink_cb, queue, sd, UEV_READ) == -1) {
if (uev_io_init(&ctx, &netlink_watcher, netlink_cb, jobdir, sd, UEV_READ) == -1) {
err("uev_io_init (netlink)");
rc = 1;
goto done;
}
run_queue(jobdir);
if (uev_run(&ctx, 0) == -1) {
err("uev_run");
rc = 1;
-76
View File
@@ -1,76 +0,0 @@
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SYSLOG_NAMES
#include <syslog.h>
#include <unistd.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <sys/inotify.h>
#include <sys/socket.h>
#include <uev/uev.h>
#include <libite/lite.h>
#define err(fmt, args...) syslog(LOG_ERR, fmt ": %s", ##args, strerror(errno))
#define errx(fmt, args...) syslog(LOG_ERR, fmt, ##args)
#define warn(fmt, args...) syslog(LOG_WARNING, fmt, ": %s", ##args, strerror(errno))
#define warnx(fmt, args...) syslog(LOG_WARNING, fmt, ##args)
#define log(fmt, args...) syslog(LOG_NOTICE, fmt, ##args)
#define dbg(fmt, args...) syslog(LOG_DEBUG, fmt, ##args)
/*
* Allow SNN and KNN style jobs, for inotyify_cb() we also allow
* a type '*' just to figure out if a job should be archived in
* the done directory.
*/
static inline int should_run(const char *name, int type)
{
if (!name || strlen(name) < 3)
return 0;
if (isdigit(name[1]) && isdigit(name[2])) {
if (type == '*') {
switch (name[0]) {
case 'K':
case 'S':
return 1;
default:
goto done;
}
}
switch (type) {
case 'K':
case 'S':
break;
default:
return 0;
}
dbg("name:%s type:'%c' => run:%d", name, type, type == name[0]);
return type == name[0];
}
done:
errx("unsupported script %s, must follow pattern SNN/KNN", name);
return 0;
}
static inline int logmask_from_str(const char *str)
{
const CODE *code;
for (code = prioritynames; code->c_name; code++)
if (!strcmp(str, code->c_name))
return LOG_UPTO(code->c_val);
return -1;
}
+3
View File
@@ -50,6 +50,9 @@ AS_IF([test "x$with_shell" != "xno"], [
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
KLISHLIBDIR=`eval echo $libdir/klish`
AC_SUBST(KLISHLIBDIR)
KLISHCONFDIR=`eval echo $sysconfdir/klish`
AC_SUBST(KLISHCONFDIR)
+6 -5
View File
@@ -1,9 +1,10 @@
AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE
CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter
lib_LTLIBRARIES = libklish-plugin-infix.la
pluginsdir = $(KLISHLIBDIR)/plugins
plugins_LTLIBRARIES = kplugin-infix.la
libklish_plugin_infix_la_CFLAGS = $(sysrepo_CFLAGS) $(klish_CFLAGS) $(libyang_CFLAGS) $(CFLAGS)
libklish_plugin_infix_la_LIBADD = $(sysrepo_LIBS) $(klish_LIBS) $(libyang_LIBS)
libklish_plugin_infix_la_LDFLAGS = -module -avoid-version -shared
libklish_plugin_infix_la_SOURCES = infix.c
kplugin_infix_la_CFLAGS = $(sysrepo_CFLAGS) $(klish_CFLAGS) $(libyang_CFLAGS) $(CFLAGS)
kplugin_infix_la_LIBADD = $(sysrepo_LIBS) $(klish_LIBS) $(libyang_LIBS)
kplugin_infix_la_LDFLAGS = -module -avoid-version -shared
kplugin_infix_la_SOURCES = infix.c
+8 -26
View File
@@ -75,15 +75,11 @@
<COMMAND name="creds" help="Credentials for remote access">
<PARAM name="creds" ptype="/STRING" help="username[:password]"/>
</COMMAND>
<COMMAND name="checksum" help="Checksum to verify against (SHA56)">
<PARAM name="sha" ptype="/STRING" help="SHA256"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
creds=${KLISH_PARAM_creds:+-c $KLISH_PARAM_creds}
sha=${KLISH_PARAM_sha:+--checksum $KLISH_PARAM_sha}
cd /var/lib/containers/oci
doas container $creds $sha load $KLISH_PARAM_url $KLISH_PARAM_name
doas container $creds load $KLISH_PARAM_url $KLISH_PARAM_name
</ACTION>
</COMMAND>
@@ -181,48 +177,34 @@
<COMMAND name="show" help="Show system status and configuration files" mode="switch">
<COMMAND name="container" help="Show container status">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container show |pager
</ACTION>
<ACTION sym="script">doas container show</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="all" help="Show all containers (default only running)">
<ACTION sym="script">doas container -a show</ACTION>
</COMMAND>
<COMMAND name="log" help="Show container log (alias for show log container)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas -u $USER cat /log/container |pager
</ACTION>
<ACTION sym="script">doas -u $USER cat /log/container</ACTION>
</COMMAND>
<COMMAND name="images" help="Show container images">
<ACTION sym="script">doas container show images</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="all" help="All images (default hides intermediate imaages)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container -a show images |pager
</ACTION>
<ACTION sym="script">doas container -a show images</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
<COMMAND name="oci" help="Show OCI archives (for loading as image)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container list oci |pager
</ACTION>
<ACTION sym="script">doas container list oci</ACTION>
</COMMAND>
<COMMAND name="stat" help="Show continuous containers stats (Ctrl-C aborts)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container stat
</ACTION>
<ACTION sym="script">doas container stat</ACTION>
</COMMAND>
<COMMAND name="usage" help="Show container resource usage">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas podman system df -v
</ACTION>
<ACTION sym="script">doas podman system df -v</ACTION>
</COMMAND>
<COMMAND name="volumes" help="Show container volumes">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container show volumes |pager
</ACTION>
<ACTION sym="script">doas container show volumes</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
+39 -66
View File
@@ -133,11 +133,11 @@
<ACTION sym="printl">upgrade</ACTION>
</COMPL>
</PARAM>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
topic=${KLISH_PARAM_topic:-quick}
fn="/usr/share/infix/cli/${topic}.md"
if [ -f "$fn" ]; then
lowdown -t term --term-vmargin=1 "$fn" |pager
lowdown -t term --term-vmargin=1 "$fn"
else
echo "Help topic not available, try help without an argument, or tap '?' for a list."
fi
@@ -226,36 +226,27 @@
<COMMAND name="show" help="Show system status and configuration files" mode="switch">
<COMMAND name="bridge" help="Show bridge (ports/fdb/mdb/vlans)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
bridge -color link |pager
</ACTION>
<ACTION sym="script">bridge -color link</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="fdb" help="Show unicast forwarding database">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
bridge -color fdb |pager
</ACTION>
<ACTION sym="script">bridge -color fdb</ACTION>
</COMMAND>
<COMMAND name="mdb" help="Show mulficast forwarding database">
<SWITCH name="optional" min="0">
<COMMAND name="detailed" help="Detailed (full) output">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
bridge -color -d mdb |pager
</ACTION>
<ACTION sym="script">bridge -color -d mdb</ACTION>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
sysrepocfg -d operational -X -f json -x /ietf-interfaces:interfaces | \
/usr/libexec/statd/cli-pretty show-bridge-mdb |pager
<ACTION sym="script"> sysrepocfg -d operational -X -f json -x /ietf-interfaces:interfaces | \
/usr/libexec/statd/cli-pretty show-bridge-mdb
</ACTION>
</COMMAND>
<COMMAND name="vlan" help="Show VLAN table">
<ACTION sym="script">bridge -color vlan</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="detailed" help="Detailed (full) output">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
bridge -color -d vlan |pager
</ACTION>
<ACTION sym="script">bridge -color -d vlan</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
@@ -273,9 +264,7 @@
<COMMAND name="dns" help="Show DNS (client) status">
<!-- Show static/configured nameservers and then all learned ones from DHCP clients -->
<ACTION sym="script" in="tty" out="tty" interrupt="true">
cat /etc/resolv.conf.head 2>/dev/null; resolvconf -l | sed 's/#.*//; /^\s*$/d' |pager
</ACTION>
<ACTION sym="script">cat /etc/resolv.conf.head 2>/dev/null; resolvconf -l | sed 's/#.*//; /^\s*$/d'</ACTION>
</COMMAND>
<COMMAND name="ntp" help="Show NTP (client) status">
@@ -317,19 +306,19 @@
<ACTION sym="printl">bfd</ACTION>
</COMPL>
</PARAM>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
if [ -z "$KLISH_PARAM_name" ]; then
doas vtysh -c "show ip ospf" |pager
doas vtysh -c "show ip ospf"
elif [ "$KLISH_PARAM_name" == "neighbor" ];then
doas vtysh -c "show ip ospf neighbor" |pager
doas vtysh -c "show ip ospf neighbor"
elif [ "$KLISH_PARAM_name" == "interfaces" ];then
doas vtysh -c "show ip ospf interface" |pager
doas vtysh -c "show ip ospf interface"
elif [ "$KLISH_PARAM_name" == "routes" ];then
doas vtysh -c "show ip ospf route" |pager
doas vtysh -c "show ip ospf route"
elif [ "$KLISH_PARAM_name" == "database" ];then
doas vtysh -c "show ip ospf database" |pager
doas vtysh -c "show ip ospf database"
elif [ "$KLISH_PARAM_name" == "bfd" ];then
doas vtysh -c "show bfd peers" |pager
doas vtysh -c "show bfd peers"
fi
</ACTION>
</COMMAND>
@@ -341,7 +330,7 @@
<ACTION sym="printl">ipv6</ACTION>
</COMPL>
</PARAM>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
case $KLISH_PARAM_ip in
ipv4)
KLISH_PARAM_ip=ip
@@ -350,14 +339,14 @@
KLISH_PARAM_ip=ipv6
;;
esac
show -p $KLISH_PARAM_ip route |pager
show -p $KLISH_PARAM_ip route
</ACTION>
</COMMAND>
<COMMAND name="hardware" help="Show hardware information">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
sysrepocfg -f json -X -d operational -x "/ietf-hardware:hardware" | \
/usr/libexec/statd/cli-pretty "show-hardware" |pager
/usr/libexec/statd/cli-pretty "show-hardware"
</ACTION>
</COMMAND>
@@ -369,60 +358,46 @@
</PARAM>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
if [ -n "$KLISH_PARAM_name" ]; then
sysrepocfg -f json -X -d operational -x \
"/ietf-interfaces:interfaces/interface[name=\"$KLISH_PARAM_name\"]" | \
/usr/libexec/statd/cli-pretty "show-interfaces" -n "$KLISH_PARAM_name" |pager
/usr/libexec/statd/cli-pretty "show-interfaces" -n "$KLISH_PARAM_name"
else
sysrepocfg -f json -X -d operational -m ietf-interfaces | \
/usr/libexec/statd/cli-pretty "show-interfaces" |pager
/usr/libexec/statd/cli-pretty "show-interfaces"
fi
</ACTION>
</COMMAND>
<COMMAND name="ip" help="Show IP level status (Layer-3)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
ip -color addr |pager
</ACTION>
<ACTION sym="script">ip -color addr</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="brief" help="Simplified (human-readable) output" mode="switch">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
ip -color -br addr | sort -V | sed 's/@dsa[0-9]/ /' |pager
</ACTION>
<ACTION sym="script">ip -color -br addr | sort -V | sed 's/@dsa[0-9]/ /'</ACTION>
</COMMAND>
<COMMAND name="detailed" help="Detailed (full) output" mode="switch">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
ip -color -d addr |pager
</ACTION>
<ACTION sym="script">ip -color -d addr</ACTION>
</COMMAND>
<COMMAND name="multicast" help="Show IGMP/MLD status" mode="switch">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
mctl |pager
</ACTION>
<ACTION sym="script">mctl</ACTION>
</COMMAND>
<COMMAND name="route" help="Show IPv4 routing table" mode="switch">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
show -p ip route |pager
</ACTION>
<ACTION sym="script">show -p ip route</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
<COMMAND name="ipv6" help="Show IPv6 level status (Layer-3)">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
ip -color -6 addr |pager
</ACTION>
<ACTION sym="script">ip -color -6 addr</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="route" help="Show IPv6 routing table" mode="switch">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
show -p ipv6 route |pager
</ACTION>
<ACTION sym="script">show -p ipv6 route</ACTION>
</COMMAND>
</SWITCH>
</COMMAND>
@@ -434,7 +409,7 @@
<PARAM name="lines" ptype="/UINT" help="Last number of lines to show"/>
</COMMAND>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
file=/log/${KLISH_PARAM_fn:-syslog}
case "$file" in
*.gz)
@@ -447,7 +422,7 @@
if [ -n "$KLISH_PARAM_lines" ]; then
$cmd "$file" | tail -n $KLISH_PARAM_lines
else
$cmd "$file" | pager
$cmd "$file"
fi
</ACTION>
</COMMAND>
@@ -461,26 +436,24 @@
</COMMAND>
-->
<COMMAND name="version" help="Show software version">
<ACTION sym="script" in="tty" interrupt="true">cat /etc/version</ACTION>
<ACTION sym="script">cat /etc/version</ACTION>
</COMMAND>
<COMMAND name="factory-config" help="Show factory-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /etc/factory-config.cfg |pager</ACTION>
<ACTION sym="script">jq -C . /etc/factory-config.cfg</ACTION>
</COMMAND>
<COMMAND name="running-config" help="Show running-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">sysrepocfg -X -f json | jq -C . |pager</ACTION>
<ACTION sym="script">sysrepocfg -X -f json | jq -C .</ACTION>
</COMMAND>
<COMMAND name="startup-config" help="Show startup-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /cfg/startup-config.cfg |pager</ACTION>
<ACTION sym="script">jq -C . /cfg/startup-config.cfg</ACTION>
</COMMAND>
</COMMAND>
<COMMAND name="factory-reset" help="Restore the system to factory default state">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
/bin/yorn "This will restore the device to factory defaults"
</ACTION>
<ACTION sym="srp_rpc@sysrepo">/ietf-factory-default:factory-reset</ACTION>
<ACTION sym="script" in="tty" out="tty" interrupt="true">/bin/yorn "This will restore the device to factory defaults"</ACTION>
<ACTION sym="srp_rpc@sysrepo">/ietf-factory-default:factory-reset</ACTION>
</COMMAND>
<COMMAND name="follow" help="Monitor a log file, use Ctrl-C to abort">
@@ -496,7 +469,7 @@
<PARAM name="addrlen" ptype="/STRING" help="ADDRESS[/LEN]"/>
<PARAM name="netmask" ptype="/STRING" min="0" help="Optional NETMASK"/>
<PARAM name="split" ptype="/UINT" min="0" help="Split network: 1-32 (IPv4), 1-128 (IPv6)"/>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
<ACTION sym="script">
if [ -n "$KLISH_PARAM_split" ]; then
if echo $KLISH_PARAM_addrlen |grep -q ':'; then
split="-S $KLISH_PARAM_split"
+186 -189
View File
@@ -46,211 +46,208 @@ with infamy.Test() as test:
with test.step("Configure device"):
dut1.put_config_dicts(
{
"ietf-interfaces": {
"interfaces": {
"interface": [
dut1.put_config_dict("ietf-interfaces",
{
"name": d1send,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
{
"name": d1receiver,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d1trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
"interfaces": {
"interface": [
{
"ip": "10.0.1.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
"name": d1send,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
}
},
{
"ip": "10.0.2.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d1send ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
"name": d1receiver,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d1trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.1.1",
"prefix-length": 24
}
]
},
{
"vid": 77,
"untagged": [ d1receiver ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d1send ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d1receiver ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
]
}
}
]
}
}
]
}
},
"ietf-system": {
"system": {
"hostname": "dut1"
}
}
})
dut1.put_config_dict("ietf-system", {
"system": {
"hostname": "dut1"
}
)
dut2.put_config_dicts(
{
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": d2receive,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
})
dut2.put_config_dict("ietf-interfaces",
{
"name": d2sender,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d2trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
"interfaces": {
"interface": [
{
"name": d2receive,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
{
"ip": "10.0.1.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
"name": d2sender,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"ip": "10.0.2.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d2receive ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
"name": d2trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.1.2",
"prefix-length": 24
}
]
},
{
"vid": 77,
"untagged": [ d2sender ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d2receive ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d2sender ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
]
}
}
]
}
}
]
}
},
"ietf-system": {
"system": {
"hostname": "dut2"
}
}
})
})
dut2.put_config_dict("ietf-system", {
"system": {
"hostname": "dut2"
}
})
with infamy.IsolatedMacVlan(hsendd1) as d1send_ns, \
infamy.IsolatedMacVlan(hreceived1) as d1receive_ns, \
@@ -16,12 +16,10 @@ endif::testgroup[]
endif::topdoc[]
==== Test sequence
. Set up topology and attach to target DUT
. Set up VLAN interface on host:data with IP 10.0.0.1
. Configure VLAN 10 interface on target:data with IP 10.0.0.2
. Wait for links to come up
. Verify that host:data can reach 10.0.0.2
. Remove VLAN interface from target:data
. Verify that host:data can no longer reach 10.0.0.2
. Waiting for links to come up
. Ping 10.0.0.2 from VLAN 10 on host:data with IP 10.0.0.1
. Remove VLAN interface from target:data, and test again (should not be able to ping)
<<<
+24 -16
View File
@@ -10,21 +10,31 @@ import infamy.iface as iface
from infamy import until
def test_ping(hport, should_pass):
with infamy.IsolatedMacVlan(hport) as ns:
try:
ns.runsh("""
set -ex
ip link set iface up
ip link add dev vlan10 link iface up type vlan id 10
ip addr add 10.0.0.1/24 dev vlan10
""")
if should_pass:
ns.must_reach("10.0.0.2")
else:
ns.must_not_reach("10.0.0.2")
except Exception as e:
print(f"An error occurred during the VLAN setup or ping test: {e}")
raise
with infamy.Test() as test:
with test.step("Set up topology and attach to target DUT"):
env = infamy.Env()
target = env.attach("target", "mgmt")
_, tport = env.ltop.xlate("target", "data")
with test.step("Set up VLAN interface on host:data with IP 10.0.0.1"):
_, hport = env.ltop.xlate("host", "data")
datanet = infamy.IsolatedMacVlan(hport).start()
datanet.runsh("""
set -ex
ip link set iface up
ip link add dev vlan10 link iface up type vlan id 10
ip addr add 10.0.0.1/24 dev vlan10
""")
with test.step("Configure VLAN 10 interface on target:data with IP 10.0.0.2"):
target.put_config_dict("ietf-interfaces", {
@@ -54,18 +64,16 @@ with infamy.Test() as test:
}
})
with test.step("Wait for links to come up"):
with test.step("Waiting for links to come up"):
until(lambda: iface.get_param(target, tport, "oper-status") == "up")
with test.step("Verify that host:data can reach 10.0.0.2"):
with test.step("Ping 10.0.0.2 from VLAN 10 on host:data with IP 10.0.0.1"):
_, hport = env.ltop.xlate("host", "data")
datanet.must_reach("10.0.0.2")
test_ping(hport,True)
with test.step("Remove VLAN interface from target:data"):
with test.step("Remove VLAN interface from target:data, and test again (should not be able to ping)"):
target.delete_xpath(f"/ietf-interfaces:interfaces/interface[name='{tport}.10']")
with test.step("Verify that host:data can no longer reach 10.0.0.2"):
_, hport = env.ltop.xlate("host", "data")
datanet.must_not_reach("10.0.0.2")
test_ping(hport,False)
test.succeed()
-2
View File
@@ -11,5 +11,3 @@ include::ospf_basic/Readme.adoc[]
include::ospf_unnumbered_interface/Readme.adoc[]
include::ospf_multiarea/Readme.adoc[]
include::ospf_bfd/Readme.adoc[]

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