mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-25 18:23:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
deee48d36a | ||
|
|
23e24635fe | ||
|
|
eb38d4538f | ||
|
|
2910d8b9bf | ||
|
|
6bdfdbe164 | ||
|
|
ceb78d66a2 | ||
|
|
9ac77be9eb | ||
|
|
d692a3d745 | ||
|
|
597da90b05 | ||
|
|
5d524006a3 | ||
|
|
4c1de659cb | ||
|
|
3b01f2d806 | ||
|
|
4e2458e18a | ||
|
|
dc741bb567 | ||
|
|
d5d487070f | ||
|
|
7052c54165 | ||
|
|
e25eb1966e | ||
|
|
fe1c47e107 | ||
|
|
57b66ec6d3 | ||
|
|
9103d31950 | ||
|
|
32ec9887b9 | ||
|
|
e0458ca079 | ||
|
|
e9aefc517f | ||
|
|
20295b08b5 | ||
|
|
7a9f1c1d7a | ||
|
|
7e08555013 | ||
|
|
82ff83c50d | ||
|
|
d277f5a860 | ||
|
|
f537e2fc13 | ||
|
|
73070f40c4 | ||
|
|
a0fb42e46d | ||
|
|
a820beebfa | ||
|
|
204672779b | ||
|
|
6a9f9fd3cc | ||
|
|
a78fd3da0a | ||
|
|
8721255554 | ||
|
|
5079691201 | ||
|
|
a23634dd7e | ||
|
|
3840ebc9fe | ||
|
|
56abfde8ec | ||
|
|
96d200fe70 | ||
|
|
7f2f3768db | ||
|
|
dc92db4e9f | ||
|
|
be828d46c9 | ||
|
|
a4a4a49eae | ||
|
|
2a6e4402f8 | ||
|
|
3031bba047 | ||
|
|
f9e430e41d | ||
|
|
17403afeb4 |
@@ -33,3 +33,4 @@ 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
|
||||
|
||||
@@ -101,6 +101,7 @@ jobs:
|
||||
runs-on: [ self-hosted, release ]
|
||||
permissions:
|
||||
contents: write
|
||||
discussions: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -115,12 +116,14 @@ 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
|
||||
@@ -150,7 +153,7 @@ jobs:
|
||||
name: Infix ${{ github.ref_name }}
|
||||
prerelease: ${{ steps.rel.outputs.pre }}
|
||||
makeLatest: ${{ steps.rel.outputs.latest }}
|
||||
discussionCategory: Releases
|
||||
discussionCategory: ${{ steps.rel.outputs.cat }}
|
||||
bodyFile: release.md
|
||||
artifacts: "*.tar.gz*"
|
||||
|
||||
|
||||
@@ -265,14 +265,38 @@
|
||||
};
|
||||
};
|
||||
|
||||
#define SWP_LED(_func) \
|
||||
#define SWP_LED \
|
||||
leds { \
|
||||
#address-cells = <1>; \
|
||||
#size-cells = <0>; \
|
||||
\
|
||||
led@0 { \
|
||||
reg = <0>; \
|
||||
function = _func; \
|
||||
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"; \
|
||||
color = <LED_COLOR_ID_GREEN>; \
|
||||
default-state = "keep"; \
|
||||
}; \
|
||||
@@ -287,7 +311,7 @@
|
||||
phy-mode = "10gbase-r"; \
|
||||
managed = "in-band-status"; \
|
||||
sfp = <_sfp>; \
|
||||
SWP_LED("sfp"); \
|
||||
SFP_LED; \
|
||||
}
|
||||
|
||||
#define XSWCPU(_n, _eth) \
|
||||
@@ -321,7 +345,7 @@
|
||||
nvmem-cell-names = "mac-address"; \
|
||||
phy-mode = "gmii"; \
|
||||
phy-handle = <_phy>; \
|
||||
SWP_LED("tp"); \
|
||||
SWP_LED; \
|
||||
}
|
||||
|
||||
#define GPHY(_n) \
|
||||
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/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 +1 @@
|
||||
/usr/libexec/styx/led.sh
|
||||
@@ -0,0 +1 @@
|
||||
RAUC_ARGS="-s"
|
||||
+1
@@ -0,0 +1 @@
|
||||
/var/lib/dbus/machine-id
|
||||
@@ -8,10 +8,11 @@ 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"
|
||||
@@ -28,7 +29,9 @@ class DTSystem:
|
||||
if not os.path.exists(phandle):
|
||||
continue
|
||||
|
||||
ph, = struct.unpack(">L", open(phandle, "rb").read())
|
||||
with open(phandle, "rb") as f:
|
||||
data = f.read()
|
||||
ph, = struct.unpack(">L", data)
|
||||
dt[ph] = root
|
||||
|
||||
sys = {}
|
||||
@@ -40,14 +43,18 @@ class DTSystem:
|
||||
if not os.path.exists(phandle):
|
||||
continue
|
||||
|
||||
ph, = struct.unpack(">L", open(phandle, "rb").read())
|
||||
with open(phandle, "rb") as f:
|
||||
data = f.read()
|
||||
ph, = struct.unpack(">L", data)
|
||||
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)
|
||||
|
||||
@@ -56,7 +63,8 @@ class DTSystem:
|
||||
if not os.path.exists(path):
|
||||
return ()
|
||||
|
||||
data = open(path, "rb").read()
|
||||
with open(path, "rb") as f:
|
||||
data = f.read()
|
||||
elems = len(data) // struct.calcsize(">L")
|
||||
return struct.unpack(">" + elems * "L", data)
|
||||
|
||||
@@ -69,7 +77,8 @@ class DTSystem:
|
||||
return {}
|
||||
|
||||
try:
|
||||
data = onieprom.from_tlv(open(dev.attrpath("nvmem"), "rb", 0))
|
||||
with open(dev.attrpath("nvmem"), "rb", 0) as f:
|
||||
data = onieprom.from_tlv(f)
|
||||
except:
|
||||
data = {}
|
||||
|
||||
@@ -84,14 +93,18 @@ 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)
|
||||
@@ -101,6 +114,7 @@ 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"
|
||||
@@ -110,7 +124,8 @@ class QEMUSystem:
|
||||
data = {}
|
||||
if os.path.exists(QEMUSystem.VPD):
|
||||
try:
|
||||
data = onieprom.from_tlv(open(QEMUSystem.VPD, "rb", 0))
|
||||
with open(QEMUSystem.VPD, "rb", 0) as f:
|
||||
data = onieprom.from_tlv(f)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -127,31 +142,27 @@ 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 != None
|
||||
return self.syspath is not None
|
||||
|
||||
def __getitem__(self, attr):
|
||||
return self.attr(attr).decode("utf-8").strip("\0")
|
||||
@@ -159,7 +170,6 @@ 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)
|
||||
|
||||
@@ -168,13 +178,16 @@ class Device:
|
||||
|
||||
def attr(self, attr, default=None, val=None):
|
||||
if not self.hasattr(attr):
|
||||
return default if val == None else False
|
||||
return default if val is None else False
|
||||
|
||||
if val:
|
||||
open(self.attrpath(attr), "wb").write(value)
|
||||
with open(self.attrpath(attr), "wb") as f:
|
||||
f.write(val)
|
||||
return True
|
||||
|
||||
return open(self.attrpath(attr), "rb").read()
|
||||
with open(self.attrpath(attr), "rb") as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def str(self, attr, default=None):
|
||||
val = self.attr(attr)
|
||||
@@ -194,7 +207,9 @@ class Device:
|
||||
if not self.hasdtattr(attr):
|
||||
return default
|
||||
|
||||
return open(self.dtattrpath(attr), "rb").read()
|
||||
with open(self.dtattrpath(attr), "rb") as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def dtstr(self, attr, default=None):
|
||||
val = self.dtattr(attr)
|
||||
@@ -212,6 +227,7 @@ def vpd_get_json_ve(vpd, pem):
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def vpd_get_pwhash(vpd):
|
||||
if not vpd.get("trusted"):
|
||||
return None
|
||||
@@ -219,8 +235,9 @@ 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")
|
||||
@@ -234,6 +251,7 @@ 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'
|
||||
@@ -244,7 +262,8 @@ def qemu_base_mac():
|
||||
continue
|
||||
try:
|
||||
# pylint: disable=invalid-name
|
||||
with open(os.path.join(base_path, iface, 'address'), 'r', encoding='ascii') as f:
|
||||
fn = os.path.join(base_path, iface, 'address')
|
||||
with open(fn, 'r', encoding='ascii') as f:
|
||||
mac = f.read().strip()
|
||||
interfaces.append((mac, iface))
|
||||
except FileNotFoundError:
|
||||
@@ -261,6 +280,7 @@ def qemu_base_mac():
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def probe_qemusystem(out):
|
||||
"""Probe Qemu based test systems and 'make run'"""
|
||||
admin_hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
|
||||
@@ -288,6 +308,7 @@ 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()
|
||||
@@ -297,6 +318,8 @@ 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
|
||||
@@ -304,6 +327,7 @@ def probe_dtsystem(out):
|
||||
vpd_inject(out, vpds)
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
out = {
|
||||
"vendor": None,
|
||||
@@ -338,5 +362,6 @@ def main():
|
||||
shutil.chown(SYSTEM_JSON, user="root", group="wheel")
|
||||
return err
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
@@ -1,22 +1,48 @@
|
||||
#!/bin/sh
|
||||
# Find and install any product specific files in /etc before bootstrap
|
||||
# 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.
|
||||
ident=$(basename "$0")
|
||||
|
||||
PRODUCT_INIT=/etc/product/init.d
|
||||
PREFIXD=/usr/share/product
|
||||
PRODUCT=$(jq -r '."product-name" | ascii_downcase' /run/system.json)
|
||||
COMPATIBLES=$(jq -r '.compatible | reverse.[] | ascii_downcase' /run/system.json)
|
||||
|
||||
note()
|
||||
{
|
||||
logger -I $$ -k -p user.notice -t "$ident" "$1"
|
||||
}
|
||||
|
||||
DIR="$PREFIXD/$PRODUCT"
|
||||
if [ -z "$PRODUCT" ] || [ ! -d "$DIR" ]; then
|
||||
note "No vendor/product specific directory found, using built-in defaults."
|
||||
exit 0
|
||||
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."
|
||||
fi
|
||||
|
||||
note "Using vendor/product specific defaults."
|
||||
for dir in "$DIR"/*; do
|
||||
[ -d "$dir" ] && cp -a "$dir" /
|
||||
done
|
||||
# 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
|
||||
|
||||
@@ -46,7 +46,11 @@ while [ "$1" ]; do
|
||||
[ $txqs -lt 2 ] && continue
|
||||
[ $txqs -gt 8 ] && txqs=8
|
||||
|
||||
tc qdisc add dev $iface root mqprio hw 1 \
|
||||
num_tc $txqs $(map $txqs) $(queues $txqs) || true
|
||||
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
|
||||
done
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec initctl -bq cond set ixinit-done
|
||||
exec initctl -bq cond set ixinit
|
||||
|
||||
+21
-2
@@ -4,7 +4,7 @@ Change Log
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
|
||||
[v24.10.2][UNRELEASED]
|
||||
[v24.10.2][] - 2024-11-08
|
||||
-------------------------
|
||||
|
||||
### Changes
|
||||
@@ -22,12 +22,30 @@ 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 supprt
|
||||
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.`
|
||||
|
||||
|
||||
|
||||
[v24.10.1][] - 2024-10-18
|
||||
@@ -1276,6 +1294,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
|
||||
|
||||
[buildroot]: https://buildroot.org/
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.10.1...HEAD
|
||||
[v24.10.2]: https://github.com/kernelkit/infix/compare/v24.10.1...v24.10.2
|
||||
[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
|
||||
|
||||
+142
-28
@@ -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:fe00:0*.
|
||||
*fe80::ff:fec0:ffed*.
|
||||
|
||||
```
|
||||
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: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
|
||||
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
|
||||
|
||||
--- 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:fe00:0%tap0
|
||||
admin@fe80::ff:fe00:0%tap0's password: admin
|
||||
admin@infix-00-00-00:~$
|
||||
linux-pc:# ssh admin@fe80::ff:fec0:ffed%tap0
|
||||
admin@fe80::ff:fec0:ffed%tap0's password: admin
|
||||
admin@infix-c0-ff-ee:~$
|
||||
```
|
||||
|
||||
## 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:00:00:00 (oui Unknown)
|
||||
Subtype MAC address (4): 02:00:00:c0:ff:ee (oui Unknown)
|
||||
Port ID TLV (2), length 7
|
||||
Subtype MAC address (3): 02:00:00:00:00:00 (oui Unknown)
|
||||
Subtype MAC address (3): 02:00:00:c0:ff:ee (oui Unknown)
|
||||
Time to Live TLV (3), length 2: TTL 120s
|
||||
System Name TLV (5), length 14: infix-00-00-00
|
||||
System Name TLV (5), length 14: infix-c0-ff-ee
|
||||
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:fe00:0
|
||||
Management Address length 17, AFI IPv6 (2): fe80::ff:fec0:ffed
|
||||
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:00:00:00 (oui Unknown)
|
||||
Subtype MAC address (4): 02:00:00:c0:ff:ee (oui Unknown)
|
||||
Port ID TLV (2), length 7
|
||||
Subtype MAC address (3): 02:00:00:00:00:00 (oui Unknown)
|
||||
Subtype MAC address (3): 02:00:00:c0:ff:ee (oui Unknown)
|
||||
Time to Live TLV (3), length 2: TTL 120s
|
||||
System Name TLV (5), length 14: infix-00-00-00
|
||||
System Name TLV (5), length 14: infix-c0-ff-ee
|
||||
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,6 +134,15 @@ 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
|
||||
@@ -144,33 +153,138 @@ be used to search for devices advertising their services via mDNS.
|
||||
|
||||
```
|
||||
linux-pc:# avahi-browse -ar
|
||||
+ 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]
|
||||
+ 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]
|
||||
address = [10.0.1.1]
|
||||
port = [22]
|
||||
txt = []
|
||||
= tap0 IPv4 infix-00-00-00 SSH Remote Terminal local
|
||||
hostname = [infix-00-00-00.local]
|
||||
= tap0 IPv4 infix-c0-ff-ee SSH Remote Terminal local
|
||||
hostname = [infix-c0-ff-ee.local]
|
||||
address = [10.0.1.1]
|
||||
port = [22]
|
||||
txt = []
|
||||
= tap0 IPv6 infix-00-00-00 SFTP File Transfer local
|
||||
hostname = [infix-00-00-00.local]
|
||||
address = [fe80::ff:fe00:0]
|
||||
= tap0 IPv6 infix-c0-ff-ee SFTP File Transfer local
|
||||
hostname = [infix-c0-ff-ee.local]
|
||||
address = [fe80::ff:fec0:ffed]
|
||||
port = [22]
|
||||
txt = []
|
||||
= tap0 IPv6 infix-00-00-00 SSH Remote Terminal local
|
||||
hostname = [infix-00-00-00.local]
|
||||
address = [fe80::ff:fe00:0]
|
||||
= tap0 IPv6 infix-c0-ff-ee SSH Remote Terminal local
|
||||
hostname = [infix-c0-ff-ee.local]
|
||||
address = [fe80::ff:fec0:ffed]
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
After Width: | Height: | Size: 258 KiB |
@@ -383,6 +383,32 @@ an IGMP/MLD fast-leave port.
|
||||
[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
|
||||
@@ -1011,6 +1037,38 @@ 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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#set DEBUG=1
|
||||
|
||||
run name:bootstrap log:prio:user.notice norestart <usr/ixinit-done> \
|
||||
run name:bootstrap log:prio:user.notice norestart <usr/ixinit> \
|
||||
[S] /usr/libexec/confd/bootstrap \
|
||||
-- Bootstrapping YANG datastore
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [S0123456789] <!pid/syslogd> iitod -- LED daemon
|
||||
service [S0123456789] <!usr/product,usr/led> iitod -- LED daemon
|
||||
|
||||
@@ -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/33] net: phy: add support for PHY LEDs polarity modes
|
||||
Subject: [PATCH 01/34] 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,6 +22,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/phy/phy_device.c | 16 ++++++++++++++++
|
||||
include/linux/phy.h | 22 ++++++++++++++++++++++
|
||||
|
||||
+2
-1
@@ -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/33] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
Subject: [PATCH 02/34] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
controllers
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -14,6 +14,7 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20231204100811.2708884-4-tobias@waldekranz.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/marvell/mvmdio.c | 44 +++++++++++++++++++++++++++
|
||||
1 file changed, 44 insertions(+)
|
||||
|
||||
+2
-1
@@ -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/33] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
Subject: [PATCH 03/34] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
counter
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -16,6 +16,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 162 ++++++++++++++++++-------------
|
||||
drivers/net/dsa/mv88e6xxx/chip.h | 27 +++---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 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/33] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
Subject: [PATCH 04/34] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
With the upcoming standard counter group support, we are no longer
|
||||
@@ -16,6 +16,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 138 +++++++++++++++++--------------
|
||||
1 file changed, 75 insertions(+), 63 deletions(-)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 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/33] net: dsa: mv88e6xxx: Add "eth-mac" counter group
|
||||
Subject: [PATCH 05/34] net: dsa: mv88e6xxx: Add "eth-mac" counter group
|
||||
support
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -12,6 +12,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 39 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
+2
-1
@@ -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/33] net: dsa: mv88e6xxx: Limit histogram counters to
|
||||
Subject: [PATCH 06/34] net: dsa: mv88e6xxx: Limit histogram counters to
|
||||
ingress traffic
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -27,6 +27,7 @@ Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 6 +++---
|
||||
drivers/net/dsa/mv88e6xxx/global1.c | 7 +++----
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 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/33] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
Subject: [PATCH 07/34] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Report the applicable subset of an mv88e6xxx port's counters using
|
||||
@@ -11,6 +11,7 @@ Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 42 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 42 insertions(+)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
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/33] net: dsa: mv88e6xxx: Add LED infrastructure
|
||||
Subject: [PATCH 09/34] 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,13 +1,15 @@
|
||||
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/33] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
Subject: [PATCH 10/34] 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 +++++++++++++++++++++++++++++++
|
||||
|
||||
+3
-1
@@ -1,13 +1,15 @@
|
||||
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/33] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
|
||||
Subject: [PATCH 11/34] 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(-)
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: Support MDB memberships whose L2 addresses
|
||||
Subject: [PATCH 12/34] net: dsa: Support MDB memberships whose L2 addresses
|
||||
overlap
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -29,6 +29,8 @@ 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(-)
|
||||
|
||||
+3
-1
@@ -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/33] net: phy: marvell10g: Support firmware loading on
|
||||
Subject: [PATCH 13/34] net: phy: marvell10g: Support firmware loading on
|
||||
88X3310
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -11,6 +11,8 @@ 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(+)
|
||||
|
||||
+3
-1
@@ -1,13 +1,15 @@
|
||||
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/33] net: phy: marvell10g: Fix power-up when strapped to
|
||||
Subject: [PATCH 14/34] 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/33] net: phy: marvell10g: Add LED support for 88X3310
|
||||
Subject: [PATCH 15/34] net: phy: marvell10g: Add LED support for 88X3310
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Pickup the LEDs from the state in which the hardware reset or
|
||||
@@ -17,6 +17,8 @@ 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(+)
|
||||
|
||||
+3
-1
@@ -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/33] net: phy: marvell10g: Support LEDs tied to a single
|
||||
Subject: [PATCH 16/34] net: phy: marvell10g: Support LEDs tied to a single
|
||||
media side
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -14,6 +14,8 @@ 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(-)
|
||||
|
||||
+3
-1
@@ -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/33] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
Subject: [PATCH 17/34] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
TLV is invalid
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -13,6 +13,8 @@ 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
-1
@@ -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/33] net: bridge: avoid classifying unknown multicast as
|
||||
Subject: [PATCH 18/34] net: bridge: avoid classifying unknown multicast as
|
||||
mrouters_only
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
|
||||
+1
-1
@@ -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/33] net: bridge: Ignore router ports when forwarding L2
|
||||
Subject: [PATCH 19/34] net: bridge: Ignore router ports when forwarding L2
|
||||
multicast
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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/33] net: dsa: Support EtherType based priority overrides
|
||||
Subject: [PATCH 20/34] 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 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
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/33] net: dsa: mv88e6xxx: Support EtherType based priority
|
||||
Subject: [PATCH 21/34] 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/33] net: phy: Do not resume PHY when attaching
|
||||
Subject: [PATCH 22/34] net: phy: Do not resume PHY when attaching
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
The PHY should not start negotiating with its link-partner until
|
||||
@@ -15,6 +15,8 @@ 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(-)
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: mv88e6xxx: Improve indirect register access
|
||||
Subject: [PATCH 23/34] net: dsa: mv88e6xxx: Improve indirect register access
|
||||
perf on 6393
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -13,6 +13,8 @@ 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
-1
@@ -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/33] net: bridge: drop delay for applying strict multicast
|
||||
Subject: [PATCH 24/34] net: bridge: drop delay for applying strict multicast
|
||||
filtering
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: mv88e6xxx: Honor ports being managed via
|
||||
Subject: [PATCH 25/34] net: dsa: mv88e6xxx: Honor ports being managed via
|
||||
in-band-status
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -13,6 +13,8 @@ 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/33] net: dsa: mv88e6xxx: Fix port policy config on 6393X
|
||||
Subject: [PATCH 26/34] net: dsa: mv88e6xxx: Fix port policy config on 6393X
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
mv88e6393x_port_policy_{read,write} expect the `pointer` argument to
|
||||
@@ -16,6 +16,7 @@ never enabled on DSA ports, which broke standalone port isolation in
|
||||
multichip switch trees made up of 6393X decices.
|
||||
|
||||
Fixes: 6584b26020fc ("net: dsa: mv88e6xxx: implement .port_set_policy for Amethyst")
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/port.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
||||
Subject: [PATCH 27/34] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
||||
ports on 6393X
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -29,6 +29,8 @@ 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/33] usb: core: adjust log level for unauthorized devices
|
||||
Subject: [PATCH 28/34] 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,
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: mv88e6xxx: Grab register lock during counter
|
||||
Subject: [PATCH 29/34] net: dsa: mv88e6xxx: Grab register lock during counter
|
||||
snapshotting
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -9,6 +9,8 @@ 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(-)
|
||||
|
||||
+3
-1
@@ -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/33] net: bridge: Differentiate MDB additions from
|
||||
Subject: [PATCH 30/34] net: bridge: Differentiate MDB additions from
|
||||
modifications
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -21,6 +21,8 @@ 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 ++--
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: tag_dsa: Use tag priority as initial
|
||||
Subject: [PATCH 31/34] net: dsa: tag_dsa: Use tag priority as initial
|
||||
skb->priority
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -19,6 +19,8 @@ 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/33] net: dsa: mv88e6xxx: Add mqprio qdisc support
|
||||
Subject: [PATCH 32/34] net: dsa: mv88e6xxx: Add mqprio qdisc support
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Add support for attaching mqprio qdisc's to mv88e6xxx ports and use
|
||||
@@ -24,6 +24,8 @@ 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 +-
|
||||
|
||||
+3
-1
@@ -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/33] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
|
||||
Subject: [PATCH 33/34] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
|
||||
are available
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
@@ -22,6 +22,8 @@ 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(-)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
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
|
||||
|
||||
+15
-11
@@ -1,19 +1,23 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
usb_ports=$(cat /run/system.json | jq -r '.["usb-ports"] | map(.name) | unique | join(" ")')
|
||||
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
|
||||
|
||||
gen_port()
|
||||
{
|
||||
local port="$1"
|
||||
cat <<EOF
|
||||
{
|
||||
"class": "infix-hardware:usb",
|
||||
"name": "$port",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
}
|
||||
port="$1"
|
||||
cat <<EOF
|
||||
{
|
||||
"class": "infix-hardware:usb",
|
||||
"name": "$port",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
first=1
|
||||
@@ -24,7 +28,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"
|
||||
|
||||
@@ -46,208 +46,211 @@ with infamy.Test() as test:
|
||||
|
||||
|
||||
with test.step("Configure device"):
|
||||
dut1.put_config_dict("ietf-interfaces",
|
||||
dut1.put_config_dicts(
|
||||
{
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"ip": "10.0.1.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"name": d1send,
|
||||
"enabled": True,
|
||||
"bridge-port": {
|
||||
"bridge": "br0",
|
||||
"pvid": 55
|
||||
|
||||
}
|
||||
})
|
||||
dut1.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": "dut1"
|
||||
}
|
||||
})
|
||||
dut2.put_config_dict("ietf-interfaces",
|
||||
},
|
||||
{
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": d2receive,
|
||||
"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": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"ip": "10.0.1.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
"vlan": {
|
||||
"id": 55,
|
||||
"lower-layer-if": "br0"
|
||||
}
|
||||
})
|
||||
|
||||
dut2.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": "dut2"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
dut2.put_config_dicts(
|
||||
{
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": d2receive,
|
||||
"enabled": True,
|
||||
"bridge-port": {
|
||||
"bridge": "br0",
|
||||
"pvid": 55
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with infamy.IsolatedMacVlan(hsendd1) as d1send_ns, \
|
||||
infamy.IsolatedMacVlan(hreceived1) as d1receive_ns, \
|
||||
|
||||
@@ -16,10 +16,12 @@ 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
|
||||
. 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)
|
||||
. 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
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
@@ -10,31 +10,21 @@ 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", {
|
||||
@@ -64,16 +54,18 @@ with infamy.Test() as test:
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Waiting for links to come up"):
|
||||
with test.step("Wait for links to come up"):
|
||||
until(lambda: iface.get_param(target, tport, "oper-status") == "up")
|
||||
|
||||
with test.step("Ping 10.0.0.2 from VLAN 10 on host:data with IP 10.0.0.1"):
|
||||
with test.step("Verify that host:data can reach 10.0.0.2"):
|
||||
_, hport = env.ltop.xlate("host", "data")
|
||||
test_ping(hport,True)
|
||||
datanet.must_reach("10.0.0.2")
|
||||
|
||||
with test.step("Remove VLAN interface from target:data, and test again (should not be able to ping)"):
|
||||
with test.step("Remove VLAN interface from target:data"):
|
||||
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")
|
||||
test_ping(hport,False)
|
||||
datanet.must_not_reach("10.0.0.2")
|
||||
|
||||
test.succeed()
|
||||
|
||||
@@ -11,3 +11,5 @@ include::ospf_basic/Readme.adoc[]
|
||||
include::ospf_unnumbered_interface/Readme.adoc[]
|
||||
|
||||
include::ospf_multiarea/Readme.adoc[]
|
||||
|
||||
include::ospf_bfd/Readme.adoc[]
|
||||
|
||||
@@ -10,3 +10,6 @@
|
||||
|
||||
- name: ospf_multiarea
|
||||
case: ospf_multiarea/test.py
|
||||
|
||||
- name: ospf_bfd
|
||||
case: ospf_bfd/test.py
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
=== OSPF BFD
|
||||
==== Description
|
||||
Verify that a router running OSPF, with Bidirectional Forwarding
|
||||
Detection (BFD) enabled, will detect link faults even when the
|
||||
physical layer is still operational.
|
||||
|
||||
This can typically happen when one logical link, from OSPF's
|
||||
perspective, is made up of multiple physical links containing media
|
||||
converters without link fault forwarding.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/ietf_routing/ospf_bfd/topology.svg[OSPF BFD topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::ospf_bfd/topology.svg[OSPF BFD topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[OSPF BFD topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUTs
|
||||
. Setup TPMR between R1fast and R2fast
|
||||
. Configure R1 and R2
|
||||
. Setup IP addresses and default routes on h1 and h2
|
||||
. Wait for R1 and R2 to peer
|
||||
. Verify connectivity from PC:src to PC:dst via fast link
|
||||
. Disable forwarding between R1fast and R2fast to trigger fail-over
|
||||
. Verify connectivity from PC:src to PC:dst via slow link
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
Executable
+183
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
OSPF BFD
|
||||
|
||||
Verify that a router running OSPF, with Bidirectional Forwarding
|
||||
Detection (BFD) enabled, will detect link faults even when the
|
||||
physical layer is still operational.
|
||||
|
||||
This can typically happen when one logical link, from OSPF's
|
||||
perspective, is made up of multiple physical links containing media
|
||||
converters without link fault forwarding.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
from infamy.netns import TPMR
|
||||
from infamy.util import until, parallel
|
||||
|
||||
def config(target, params):
|
||||
name = params["name"]
|
||||
dif, fif, sif = \
|
||||
params["link"]["data"], \
|
||||
params["link"]["fast"], \
|
||||
params["link"]["slow"]
|
||||
rid, daddr, faddr, saddr = \
|
||||
params["addr"]["rid"], \
|
||||
params["addr"]["data"], \
|
||||
params["addr"]["fast"], \
|
||||
params["addr"]["slow"]
|
||||
|
||||
def ifconfig(name, addr, plen):
|
||||
return {
|
||||
"name": name,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": addr,
|
||||
"prefix-length": plen,
|
||||
}]}
|
||||
}
|
||||
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
ifconfig("lo", rid, 32),
|
||||
|
||||
ifconfig(dif, daddr, 24),
|
||||
ifconfig(fif, faddr, 30),
|
||||
ifconfig(sif, saddr, 30),
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": name,
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces":
|
||||
{
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": fif,
|
||||
"hello-interval": 1,
|
||||
"dead-interval": 10,
|
||||
"cost": 100,
|
||||
},
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": sif,
|
||||
"hello-interval": 1,
|
||||
"dead-interval": 10,
|
||||
"cost": 200,
|
||||
}, {
|
||||
"name": dif,
|
||||
"passive": True,
|
||||
}]
|
||||
},
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to target DUTs"):
|
||||
env = infamy.Env()
|
||||
R1 = env.attach("R1", "mgmt")
|
||||
R2 = env.attach("R2", "mgmt")
|
||||
|
||||
with test.step("Setup TPMR between R1fast and R2fast"):
|
||||
breaker = TPMR(env.ltop.xlate("PC", "R1fast")[1],
|
||||
env.ltop.xlate("PC", "R2fast")[1]).start()
|
||||
|
||||
with test.step("Configure R1 and R2"):
|
||||
r1cfg = {
|
||||
"name": "R1",
|
||||
"addr": {
|
||||
"rid": "192.168.1.1",
|
||||
|
||||
"data": "192.168.10.1",
|
||||
"fast": "192.168.100.1",
|
||||
"slow": "192.168.200.1",
|
||||
},
|
||||
"link": {
|
||||
"data": env.ltop.xlate("R1", "h1")[1],
|
||||
"fast": env.ltop.xlate("R1", "fast")[1],
|
||||
"slow": env.ltop.xlate("R1", "slow")[1],
|
||||
}
|
||||
}
|
||||
r2cfg = {
|
||||
"name": "R2",
|
||||
"addr": {
|
||||
"rid": "192.168.1.2",
|
||||
|
||||
"data": "192.168.20.1",
|
||||
"fast": "192.168.100.2",
|
||||
"slow": "192.168.200.2",
|
||||
},
|
||||
"link": {
|
||||
"data": env.ltop.xlate("R2", "h2")[1],
|
||||
"fast": env.ltop.xlate("R2", "fast")[1],
|
||||
"slow": env.ltop.xlate("R2", "slow")[1],
|
||||
}
|
||||
}
|
||||
|
||||
parallel(config(R1, r1cfg), config(R2, r2cfg))
|
||||
|
||||
with test.step("Setup IP addresses and default routes on h1 and h2"):
|
||||
_, h1 = env.ltop.xlate("PC", "h1")
|
||||
_, h2 = env.ltop.xlate("PC", "h2")
|
||||
|
||||
h1net = infamy.IsolatedMacVlan(h1).start()
|
||||
h1net.addip("192.168.10.2")
|
||||
h1net.addroute("default", "192.168.10.1")
|
||||
|
||||
h2net = infamy.IsolatedMacVlan(h2).start()
|
||||
h2net.addip("192.168.20.2")
|
||||
h2net.addroute("default", "192.168.20.1")
|
||||
|
||||
with test.step("Wait for R1 and R2 to peer"):
|
||||
print("Waiting for R1 and R2 to peer")
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.20.0/24", "192.168.100.2", proto="ietf-ospf:ospfv2"), attempts=200)
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.10.0/24", "192.168.100.1", proto="ietf-ospf:ospfv2"), attempts=200)
|
||||
|
||||
with test.step("Verify connectivity from PC:src to PC:dst via fast link"):
|
||||
h1net.must_reach("192.168.20.2")
|
||||
hops = [row[1] for row in h1net.traceroute("192.168.20.2")]
|
||||
assert "192.168.100.2" in hops, f"Path to h2 ({repr(hops)}), does not use fast link"
|
||||
|
||||
with test.step("Disable forwarding between R1fast and R2fast to trigger fail-over"):
|
||||
breaker.block()
|
||||
print("Give BFD some time to detect the bad link, " +
|
||||
"but not enough for the OSPF dead interval expire")
|
||||
time.sleep(1)
|
||||
|
||||
with test.step("Verify connectivity from PC:src to PC:dst via slow link"):
|
||||
h1net.must_reach("192.168.20.2")
|
||||
hops = [row[1] for row in h1net.traceroute("192.168.20.2")]
|
||||
assert "192.168.200.2" in hops, f"Path to h2 ({repr(hops)}), does not use slow link"
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,39 @@
|
||||
graph "ospf-bfd" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+20";
|
||||
size=10
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
R1 [
|
||||
label=" { { R1 | <slow> slow } | { <mgmt> mgmt | <h1> h1 | <fast> fast } }",
|
||||
pos="0,6!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
R2 [
|
||||
label="{ { <slow> slow | R2 } | { <fast> fast | <h2> h2 | <mgmt> mgmt } }",
|
||||
pos="18,6!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
PC [
|
||||
label="{ { <R1mgmt> R1mgmt | <h1> h1 | <R1fast> R1fast | <R2fast> R2fast | <h2> h2 | <R2mgmt> R2mgmt } | PC }",
|
||||
pos="9,0!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
PC:R1mgmt -- R1:mgmt [kind=mgmt, color="lightgray"]
|
||||
PC:R2mgmt -- R2:mgmt [kind=mgmt, color="lightgray"]
|
||||
|
||||
PC:h1 -- R1:h1
|
||||
PC:h2 -- R2:h2
|
||||
|
||||
R1:fast -- PC:R1fast [color="lightgreen", taillabel="Cost: 100"]
|
||||
R2:fast -- PC:R2fast [color="lightgreen"]
|
||||
|
||||
R1:slow -- R2:slow [color="crimson", taillabel="Cost: 200"]
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: ospf-bfd Pages: 1 -->
|
||||
<svg width="432pt" height="156pt"
|
||||
viewBox="0.00 0.00 432.03 155.51" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 151.51)">
|
||||
<title>ospf-bfd</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-151.51 428.03,-151.51 428.03,4 -4,4"/>
|
||||
<!-- R1 -->
|
||||
<g id="node1" class="node">
|
||||
<title>R1</title>
|
||||
<polygon fill="none" stroke="black" points="0,-97.51 0,-143.51 133,-143.51 133,-97.51 0,-97.51"/>
|
||||
<text text-anchor="middle" x="29" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1</text>
|
||||
<polyline fill="none" stroke="black" points="58,-120.51 58,-143.51 "/>
|
||||
<text text-anchor="middle" x="95.5" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">slow</text>
|
||||
<polyline fill="none" stroke="black" points="0,-120.51 133,-120.51 "/>
|
||||
<text text-anchor="middle" x="25" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="50,-97.51 50,-120.51 "/>
|
||||
<text text-anchor="middle" x="66.5" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">h1</text>
|
||||
<polyline fill="none" stroke="black" points="83,-97.51 83,-120.51 "/>
|
||||
<text text-anchor="middle" x="108" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">fast</text>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node2" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="291.03,-97.51 291.03,-143.51 424.03,-143.51 424.03,-97.51 291.03,-97.51"/>
|
||||
<text text-anchor="middle" x="328.53" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">slow</text>
|
||||
<polyline fill="none" stroke="black" points="366.03,-120.51 366.03,-143.51 "/>
|
||||
<text text-anchor="middle" x="395.03" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2</text>
|
||||
<polyline fill="none" stroke="black" points="291.03,-120.51 424.03,-120.51 "/>
|
||||
<text text-anchor="middle" x="316.03" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">fast</text>
|
||||
<polyline fill="none" stroke="black" points="341.03,-97.51 341.03,-120.51 "/>
|
||||
<text text-anchor="middle" x="357.53" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">h2</text>
|
||||
<polyline fill="none" stroke="black" points="374.03,-97.51 374.03,-120.51 "/>
|
||||
<text text-anchor="middle" x="399.03" y="-105.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>R1:slow--R2:slow</title>
|
||||
<path fill="none" stroke="crimson" stroke-width="2" d="M133.5,-132.51C133.5,-132.51 290.53,-132.51 290.53,-132.51"/>
|
||||
<text text-anchor="middle" x="168" y="-136.31" font-family="DejaVu Serif, Book" font-size="14.00">Cost: 200</text>
|
||||
</g>
|
||||
<!-- PC -->
|
||||
<g id="node3" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="47.01,-0.5 47.01,-46.5 377.01,-46.5 377.01,-0.5 47.01,-0.5"/>
|
||||
<text text-anchor="middle" x="80.01" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="113.01,-23.5 113.01,-46.5 "/>
|
||||
<text text-anchor="middle" x="129.51" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">h1</text>
|
||||
<polyline fill="none" stroke="black" points="146.01,-23.5 146.01,-46.5 "/>
|
||||
<text text-anchor="middle" x="179.01" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1fast</text>
|
||||
<polyline fill="none" stroke="black" points="212.01,-23.5 212.01,-46.5 "/>
|
||||
<text text-anchor="middle" x="245.01" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2fast</text>
|
||||
<polyline fill="none" stroke="black" points="278.01,-23.5 278.01,-46.5 "/>
|
||||
<text text-anchor="middle" x="294.51" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">h2</text>
|
||||
<polyline fill="none" stroke="black" points="311.01,-23.5 311.01,-46.5 "/>
|
||||
<text text-anchor="middle" x="344.01" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="47.01,-23.5 377.01,-23.5 "/>
|
||||
<text text-anchor="middle" x="212.01" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
</g>
|
||||
<!-- R1--PC -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>R1:fast--PC:R1fast</title>
|
||||
<path fill="none" stroke="lightgreen" stroke-width="2" d="M133.5,-108.51C133.5,-108.51 179.01,-46.5 179.01,-46.5"/>
|
||||
<text text-anchor="middle" x="168" y="-112.31" font-family="DejaVu Serif, Book" font-size="14.00">Cost: 100</text>
|
||||
</g>
|
||||
<!-- R2--PC -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>R2:fast--PC:R2fast</title>
|
||||
<path fill="none" stroke="lightgreen" stroke-width="2" d="M290.53,-108.51C290.53,-108.51 245.01,-46.5 245.01,-46.5"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>PC:R1mgmt--R1:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M80.01,-46.5C80.01,-46.5 24.5,-97.51 24.5,-97.51"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:h1--R1:h1</title>
|
||||
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M129.01,-46.5C129.01,-46.5 66.5,-97.51 66.5,-97.51"/>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>PC:R2mgmt--R2:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M344.01,-46.5C344.01,-46.5 399.53,-97.51 399.53,-97.51"/>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>PC:h2--R2:h2</title>
|
||||
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M295.01,-46.5C295.01,-46.5 357.53,-97.51 357.53,-97.51"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -54,7 +54,8 @@ import infamy
|
||||
import infamy.route as route
|
||||
from infamy.util import until, parallel
|
||||
def config_target1(target, ring1, ring2, cross):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
@@ -65,7 +66,8 @@ def config_target1(target, ring1, ring2, cross):
|
||||
"address": [{
|
||||
"ip": "10.0.12.1",
|
||||
"prefix-length": 30
|
||||
}]}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ring2,
|
||||
@@ -75,7 +77,8 @@ def config_target1(target, ring1, ring2, cross):
|
||||
"address": [{
|
||||
"ip": "10.0.41.2",
|
||||
"prefix-length": 30
|
||||
}]}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": cross,
|
||||
@@ -92,93 +95,103 @@ def config_target1(target, ring1, ring2, cross):
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"address": [
|
||||
{
|
||||
"ip": "11.0.8.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "10.0.0.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
},
|
||||
{
|
||||
"ip": "10.0.0.1",
|
||||
"prefix-length": 32
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "10.0.0.1",
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces":
|
||||
{
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "10.0.0.1",
|
||||
"areas": {
|
||||
"area": [
|
||||
{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
}]
|
||||
}
|
||||
},{
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces":
|
||||
{
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
{
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 2000
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 2000
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}]
|
||||
|
||||
{
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"interface-type": "point-to-point"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},{
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces":
|
||||
{
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"interface-type": "point-to-point"
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
target.put_config_dict("ietf-system", {
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R1"
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
def config_target2(target, ring1, ring2, cross):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
@@ -189,7 +202,8 @@ def config_target2(target, ring1, ring2, cross):
|
||||
"address": [{
|
||||
"ip": "10.0.23.1",
|
||||
"prefix-length": 30
|
||||
}]}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ring2,
|
||||
@@ -199,7 +213,8 @@ def config_target2(target, ring1, ring2, cross):
|
||||
"address": [{
|
||||
"ip": "10.0.12.2",
|
||||
"prefix-length": 30
|
||||
}]}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": cross,
|
||||
@@ -209,212 +224,238 @@ def config_target2(target, ring1, ring2, cross):
|
||||
"address": [{
|
||||
"ip": "10.0.24.1",
|
||||
"prefix-length": 30
|
||||
}]}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "10.0.0.2",
|
||||
"prefix-length": 32
|
||||
},
|
||||
{
|
||||
"ip": "11.0.9.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.10.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.11.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.12.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.13.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.14.1",
|
||||
"prefix-length": 24
|
||||
},
|
||||
{
|
||||
"ip": "11.0.15.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "1.1.1.1",
|
||||
"areas": {
|
||||
"area": [
|
||||
{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"cost": 2000,
|
||||
"enabled": True
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def config_target3(target, ring2, cross, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": ring2,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "10.0.23.2",
|
||||
"prefix-length": 30
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.3.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": cross,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "10.0.13.2",
|
||||
"prefix-length": 30
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "10.0.0.2",
|
||||
"ip": "10.0.0.3",
|
||||
"prefix-length": 32
|
||||
}, {
|
||||
"ip": "11.0.9.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.10.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.11.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.12.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.13.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.14.1",
|
||||
"prefix-length": 24
|
||||
}, {
|
||||
"ip": "11.0.15.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
target.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "1.1.1.1",
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"cost": 2000
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_target3(target, ring2, cross, link):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": ring2,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "10.0.23.2",
|
||||
"prefix-length": 30
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.3.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": cross,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "10.0.13.2",
|
||||
"prefix-length": 30
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "10.0.0.3",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": "R3"
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R3"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "10.0.0.3",
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.1",
|
||||
"area-type": "nssa-area",
|
||||
"summary": False,
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 2000
|
||||
}, {
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 2000
|
||||
}, {
|
||||
"bfd": {
|
||||
}, {
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"passive": True
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring2,
|
||||
"hello-interval": 1,
|
||||
"enabled": True
|
||||
}, {
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"passive": True
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_target4(target, ring1, cross, link):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": ring1,
|
||||
@@ -459,57 +500,57 @@ def config_target4(target, ring1, cross, link):
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": "R4"
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"interface-type": "point-to-point"
|
||||
}, {
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 5000
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R4"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"explicit-router-id": "10.0.0.4",
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
}
|
||||
}]
|
||||
},
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.2",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": ring1,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"interface-type": "point-to-point"
|
||||
}, {
|
||||
"bfd": {
|
||||
"enabled": True
|
||||
},
|
||||
"name": cross,
|
||||
"hello-interval": 1,
|
||||
"enabled": True,
|
||||
"cost": 5000
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -27,96 +27,99 @@ from infamy.util import until, parallel
|
||||
|
||||
|
||||
def config_target1(target, data, link):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}]},
|
||||
"ipv6": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:10::1",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:50::1",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.100.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:100::1",
|
||||
"prefix-length": 128
|
||||
}]
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "192.168.200.1/32",
|
||||
"next-hop": {
|
||||
"next-hop-address": "192.168.50.2"
|
||||
}
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}]},
|
||||
"ipv6": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:10::1",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"route": [{
|
||||
"destination-prefix": "2001:db8:3c4d:200::1/128",
|
||||
"next-hop": {
|
||||
"next-hop-address": "2001:db8:3c4d:50::2"
|
||||
}
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:50::1",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.100.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:100::1",
|
||||
"prefix-length": 128
|
||||
}]
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "192.168.200.1/32",
|
||||
"next-hop": {
|
||||
"next-hop-address": "192.168.50.2"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"route": [{
|
||||
"destination-prefix": "2001:db8:3c4d:200::1/128",
|
||||
"next-hop": {
|
||||
"next-hop-address": "2001:db8:3c4d:50::2"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_target2(target, link):
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
@@ -157,33 +160,33 @@ def config_target2(target, link):
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
target.put_config_dict("ietf-routing", {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "0.0.0.0/0",
|
||||
"next-hop": {
|
||||
"next-hop-address": "192.168.50.1"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"route": [{
|
||||
"destination-prefix": "::/0",
|
||||
"next-hop": {
|
||||
"next-hop-address": "2001:db8:3c4d:50::1"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "0.0.0.0/0",
|
||||
"next-hop": {
|
||||
"next-hop-address": "192.168.50.1"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"route": [{
|
||||
"destination-prefix": "::/0",
|
||||
"next-hop": {
|
||||
"next-hop-address": "2001:db8:3c4d:50::1"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -14,13 +14,13 @@ with infamy.Test() as test:
|
||||
target = env.attach("target", "mgmt")
|
||||
|
||||
with test.step("Set timezone to Australia/Perth"):
|
||||
target.put_config_dict("ietf-system", {
|
||||
target.put_config_dicts({"ietf-system": {
|
||||
"system": {
|
||||
"clock": {
|
||||
"timezone-name": "Australia/Perth" # always +8:00, no DTS
|
||||
}
|
||||
}
|
||||
})
|
||||
}})
|
||||
|
||||
with test.step("Verify current time offset is +08:00"):
|
||||
current_datetime=target.get_current_time_with_offset()
|
||||
|
||||
@@ -13,13 +13,13 @@ with infamy.Test() as test:
|
||||
target = env.attach("target", "mgmt")
|
||||
|
||||
with test.step("Set timezone UTC offset to +12"):
|
||||
target.put_config_dict("ietf-system", {
|
||||
target.put_config_dicts({"ietf-system": {
|
||||
"system": {
|
||||
"clock": {
|
||||
"timezone-utc-offset": "12"
|
||||
}
|
||||
}
|
||||
})
|
||||
}})
|
||||
|
||||
with test.step("Verify current time offset is +12:00"):
|
||||
current_datetime=target.get_current_time_with_offset()
|
||||
|
||||
+15
-6
@@ -16,7 +16,7 @@ import lxml
|
||||
import netconf_client.connect
|
||||
import netconf_client.ncclient
|
||||
import infamy.iface as iface
|
||||
from infamy.transport import Transport
|
||||
from infamy.transport import Transport,infer_put_dict
|
||||
from netconf_client.error import RpcError
|
||||
from . import env
|
||||
|
||||
@@ -214,7 +214,7 @@ class Device(Transport):
|
||||
else:
|
||||
return f"<filter type=\"xpath\" select=\"{xpath}\" {xmlns} />"
|
||||
return None
|
||||
|
||||
|
||||
def _parse_response(self, response, parse):
|
||||
"""Helper function to handle XML response parsing."""
|
||||
if not response:
|
||||
@@ -273,10 +273,10 @@ class Device(Transport):
|
||||
xpath_filter = self._build_xpath_filter(xpath, get_data_xpath=True)
|
||||
response = self.ncc.get_data(datastore="ds:operational", filter=xpath_filter)
|
||||
parsed_data = self._parse_response(response, parse)
|
||||
|
||||
|
||||
if parse and parsed_data:
|
||||
return parsed_data.print_dict()
|
||||
|
||||
|
||||
return parsed_data
|
||||
|
||||
def get_config(self, xpath):
|
||||
@@ -313,6 +313,16 @@ class Device(Transport):
|
||||
continue
|
||||
break
|
||||
|
||||
def put_config_dicts(self, models):
|
||||
config = ""
|
||||
infer_put_dict(self.name, models)
|
||||
|
||||
for model in models.keys():
|
||||
mod = self.ly.get_module(model)
|
||||
lyd = mod.parse_data_dict(models[model], no_state=True, validate=False)
|
||||
config+=lyd.print_mem("xml", with_siblings=True, pretty=False)+"\n"
|
||||
return self.put_config(config)
|
||||
|
||||
def put_config_dict(self, modname, edit):
|
||||
"""Convert Python dictionary to XMl and send as configuration"""
|
||||
mod = self.ly.get_module(modname)
|
||||
@@ -344,8 +354,8 @@ class Device(Transport):
|
||||
|
||||
def get_schemas_list(self):
|
||||
schemas = []
|
||||
|
||||
data = self.get_dict("/netconf-state")
|
||||
|
||||
for d in data["netconf-state"]["schemas"]["schema"]:
|
||||
schema = {}
|
||||
schema["identifier"] = d['identifier']
|
||||
@@ -428,4 +438,3 @@ class Device(Transport):
|
||||
return current_datetime.text
|
||||
else:
|
||||
raise ValueError("current-datetime element not found in the response")
|
||||
|
||||
+164
-27
@@ -1,4 +1,5 @@
|
||||
import ctypes
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import random
|
||||
@@ -18,31 +19,58 @@ def setns(fd, nstype):
|
||||
__NR_setns = 308
|
||||
__libc.syscall(__NR_setns, fd, nstype)
|
||||
|
||||
class IsolatedMacVlan:
|
||||
"""Create an isolated interface on top of a PC interface."""
|
||||
def __init__(self, parent, ifname="iface", lo=True):
|
||||
class IsolatedMacVlans:
|
||||
"""A network namespace containing a multiple MACVLANs
|
||||
|
||||
Stacks a MACVLAN on top of each specificed controller interface,
|
||||
and moves those interfaces to a separate namespace, isolating it
|
||||
from all others.
|
||||
|
||||
NOTE: For the simple case when only one interface needs to be
|
||||
mapped, see IsolatedMacVlan below.
|
||||
|
||||
Example:
|
||||
|
||||
netns = IsolatedMacVlans({ "eth2": "a", "eth3": "b" })
|
||||
|
||||
netns:
|
||||
.--------.
|
||||
| a b | (MACVLANs)
|
||||
'-+----+-'
|
||||
| |
|
||||
eth0 eth1 eth2 eth3
|
||||
|
||||
"""
|
||||
|
||||
Instances = []
|
||||
def Cleanup():
|
||||
for ns in list(IsolatedMacVlans.Instances):
|
||||
ns.stop()
|
||||
|
||||
def __init__(self, ifmap, lo=True):
|
||||
self.sleeper = None
|
||||
self.parent, self.ifname, self.lo = parent, ifname, lo
|
||||
self.ifmap, self.lo = ifmap, lo
|
||||
self.ping_timeout = env.ENV.attr("ping_timeout", 5)
|
||||
|
||||
def __enter__(self):
|
||||
def start(self):
|
||||
self.sleeper = subprocess.Popen(["unshare", "-r", "-n", "sh", "-c",
|
||||
"echo && exec sleep infinity"],
|
||||
stdout=subprocess.PIPE)
|
||||
self.sleeper.stdout.readline()
|
||||
|
||||
try:
|
||||
subprocess.run(["ip", "link", "add",
|
||||
"dev", self.ifname,
|
||||
"link", self.parent,
|
||||
"address", self._stable_mac(),
|
||||
"netns", str(self.sleeper.pid),
|
||||
"type", "macvlan"], check=True)
|
||||
self.runsh(f"""
|
||||
while ! ip link show dev {self.ifname}; do
|
||||
sleep 0.1
|
||||
done
|
||||
""")
|
||||
for parent, ifname in self.ifmap.items():
|
||||
subprocess.run(["ip", "link", "add",
|
||||
"dev", ifname,
|
||||
"link", parent,
|
||||
"address", self._stable_mac(parent),
|
||||
"netns", str(self.sleeper.pid),
|
||||
"type", "macvlan", "mode", "passthru"], check=True)
|
||||
self.runsh(f"""
|
||||
while ! ip link show dev {ifname}; do
|
||||
sleep 0.1
|
||||
done
|
||||
""")
|
||||
except Exception as e:
|
||||
self.__exit__(None, None, None)
|
||||
raise e
|
||||
@@ -54,14 +82,43 @@ class IsolatedMacVlan:
|
||||
self.__exit__(None, None, None)
|
||||
raise e
|
||||
|
||||
self.Instances.append(self)
|
||||
return self
|
||||
|
||||
def __exit__(self, val, typ, tb):
|
||||
def stop(self):
|
||||
self.sleeper.kill()
|
||||
self.sleeper.wait()
|
||||
time.sleep(0.5)
|
||||
|
||||
def _stable_mac(self):
|
||||
for n in range(100):
|
||||
promisc = False
|
||||
for parent in self.ifmap.keys():
|
||||
iplink = subprocess.run(f"ip -d -j link show dev {parent}".split(),
|
||||
stdout=subprocess.PIPE, check=True)
|
||||
link = json.loads(iplink.stdout)[0]
|
||||
if link["promiscuity"]:
|
||||
# Use promisc as a substitute for an indicator
|
||||
# of whether the kernel has actually removed
|
||||
# the passthru MACVLAN yet or not
|
||||
promisc = True
|
||||
break
|
||||
|
||||
if not promisc:
|
||||
break
|
||||
|
||||
time.sleep(.1)
|
||||
else:
|
||||
raise TimeoutError("Lingering MACVLAN")
|
||||
|
||||
if self in self.Instances:
|
||||
self.Instances.remove(self)
|
||||
|
||||
def __enter__(self):
|
||||
return self.start()
|
||||
|
||||
def __exit__(self, val, typ, tb):
|
||||
return self.stop()
|
||||
|
||||
def _stable_mac(self, parent):
|
||||
"""Generate address for MACVLAN
|
||||
|
||||
By default, the kernel will assign a random address. This
|
||||
@@ -75,7 +132,7 @@ class IsolatedMacVlan:
|
||||
the resource exhaustion issue.
|
||||
|
||||
"""
|
||||
random.seed(self.parent)
|
||||
random.seed(parent)
|
||||
a = list(random.randbytes(6))
|
||||
a[0] |= 0x02
|
||||
a[0] &= ~0x01
|
||||
@@ -146,13 +203,13 @@ class IsolatedMacVlan:
|
||||
ip -{p} route add {subnet}{prefix_length} via {nexthop}
|
||||
""", check=True)
|
||||
|
||||
def addip(self, addr, prefix_length=24, proto="ipv4"):
|
||||
def addip(self, ifname, addr, prefix_length=24, proto="ipv4"):
|
||||
p=proto[3]
|
||||
|
||||
self.runsh(f"""
|
||||
set -ex
|
||||
ip link set iface up
|
||||
ip -{p} addr add {addr}/{prefix_length} dev iface
|
||||
ip -{p} addr add {addr}/{prefix_length} dev {ifname}
|
||||
""", check=True)
|
||||
|
||||
|
||||
@@ -188,8 +245,7 @@ class IsolatedMacVlan:
|
||||
|
||||
raise Exception(res)
|
||||
|
||||
def must_receive(self, expr, timeout=None, ifname=None, must=True):
|
||||
ifname = ifname if ifname else self.ifname
|
||||
def must_receive(self, expr, ifname, timeout=None, must=True):
|
||||
timeout = timeout if timeout else self.ping_timeout
|
||||
|
||||
tshark = self.run(["tshark", "-nl", f"-i{ifname}",
|
||||
@@ -207,10 +263,43 @@ class IsolatedMacVlan:
|
||||
def must_not_receive(self, *args, **kwargs):
|
||||
self.must_receive(*args, **kwargs, must=False)
|
||||
|
||||
def pcap(self, expr, ifname=None):
|
||||
ifname = ifname if ifname else self.ifname
|
||||
def pcap(self, expr, ifname):
|
||||
return Pcap(self, ifname, expr)
|
||||
|
||||
class IsolatedMacVlan(IsolatedMacVlans):
|
||||
"""A network namespace containing a single MACVLAN
|
||||
|
||||
Stacks a MACVLAN on top of an interface on the controller, and
|
||||
moves that interface to a separate namespace, isolating it from
|
||||
all other interfaces.
|
||||
|
||||
Example:
|
||||
|
||||
netns = IsolatedMacVlan("eth3")
|
||||
|
||||
netns:
|
||||
.-------.
|
||||
| iface | (MACVLAN)
|
||||
'---+---'
|
||||
|
|
||||
eth0 eth1 eth2 eth3
|
||||
|
||||
"""
|
||||
def __init__(self, parent, ifname="iface", lo=True):
|
||||
self._ifname = ifname
|
||||
return super().__init__(ifmap={ parent: ifname }, lo=lo)
|
||||
|
||||
def addip(self, addr, prefix_length=24, proto="ipv4"):
|
||||
return super().addip(ifname=self._ifname, addr=addr, prefix_length=prefix_length, proto=proto)
|
||||
|
||||
def must_receive(self, expr, timeout=None, ifname=None, must=True):
|
||||
ifname = ifname if ifname else self._ifname
|
||||
return super().must_receive(expr=expr, ifname=ifname, timeout=timeout, must=must)
|
||||
|
||||
def pcap(self, expr, ifname=None):
|
||||
ifname = ifname if ifname else self._ifname
|
||||
return super().pcap(expr=expr, ifname=ifname)
|
||||
|
||||
class Pcap:
|
||||
def __init__(self, netns, ifname, expr):
|
||||
self.netns, self.ifname, self.expr = netns, ifname, expr
|
||||
@@ -253,7 +342,6 @@ class Pcap:
|
||||
# terminating the capture.
|
||||
time.sleep(sleep)
|
||||
|
||||
self.proc.send_signal(signal.SIGUSR2)
|
||||
self.proc.terminate()
|
||||
try:
|
||||
_, stderr = self.proc.communicate(5)
|
||||
@@ -272,3 +360,52 @@ class Pcap:
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
text=True, check=True)
|
||||
return tcpdump.stdout
|
||||
|
||||
class TPMR(IsolatedMacVlans):
|
||||
"""Two-Port MAC Relay
|
||||
|
||||
Creates a network namespace containing two controller interfaces
|
||||
(`a` and `b`). By default, tc rules are setup to copy all frames
|
||||
ingressing on `a` to egress on `b`, and vice versa.
|
||||
|
||||
These rules can be removed and reinserted dynamically using the
|
||||
`block()` and `forward()` methods, respectively.
|
||||
|
||||
This is useful to verify the correctness of fail-over behavior in
|
||||
various protocols. See ospf_bfd for a usage example.
|
||||
"""
|
||||
|
||||
def __init__(self, a, b):
|
||||
super().__init__(ifmap={ a: "a", b: "b" }, lo=False)
|
||||
|
||||
def start(self, forward=True):
|
||||
ret = super().start()
|
||||
|
||||
for dev in ("a", "b"):
|
||||
self.run(f"ip link set dev {dev} promisc on up".split())
|
||||
self.run(f"tc qdisc add dev {dev} clsact".split())
|
||||
|
||||
if forward:
|
||||
self.forward()
|
||||
|
||||
return ret
|
||||
|
||||
def _clear_ingress(self, iface):
|
||||
return self.run(f"tc filter del dev {iface} ingress".split())
|
||||
|
||||
def _add_redir(self, frm, to):
|
||||
cmd = \
|
||||
"tc filter add dev".split() \
|
||||
+ [frm] \
|
||||
+ "ingress matchall action mirred egress redirect dev".split() \
|
||||
+ [to]
|
||||
return self.run(cmd)
|
||||
|
||||
def forward(self):
|
||||
for iface in ("a", "b"):
|
||||
self._clear_ingress(iface)
|
||||
self._add_redir(iface, "a" if iface == "b" else "b")
|
||||
|
||||
def block(self):
|
||||
for iface in ("a", "b"):
|
||||
self._clear_ingress(iface)
|
||||
|
||||
+14
-2
@@ -10,7 +10,7 @@ import time
|
||||
from requests.auth import HTTPBasicAuth
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
from dataclasses import dataclass
|
||||
from infamy.transport import Transport
|
||||
from infamy.transport import Transport, infer_put_dict
|
||||
from . import env
|
||||
|
||||
# We know we have a self-signed certificate, silence warning about it
|
||||
@@ -244,7 +244,7 @@ class Device(Transport):
|
||||
|
||||
# Directly pass the dictionary without using json.dumps
|
||||
response = requests_workaround_put(
|
||||
f"{self.restconf_url}/ds/ietf-datastores:{datastore}/",
|
||||
f"{self.restconf_url}/ds/ietf-datastores:{datastore}",
|
||||
json=data,
|
||||
headers=self.headers,
|
||||
auth=self.auth,
|
||||
@@ -262,6 +262,18 @@ class Device(Transport):
|
||||
for k, v in ds.items():
|
||||
return {container: v}
|
||||
|
||||
def put_config_dicts(self, models):
|
||||
infer_put_dict(self.name, models)
|
||||
running = self.get_running()
|
||||
|
||||
for model in models.keys():
|
||||
mod = self.lyctx.get_module(model)
|
||||
lyd = mod.parse_data_dict(models[model], no_state=True, validate=False)
|
||||
running.merge(lyd)
|
||||
|
||||
return self.put_datastore("running", json.loads(running.print_mem("json", with_siblings=True, pretty=False)))
|
||||
|
||||
|
||||
def put_config_dict(self, modname, edit):
|
||||
"""Add @edit to running config and put the whole configuration"""
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import infamy.netns
|
||||
|
||||
class Test:
|
||||
def __init__(self, output=sys.stdout):
|
||||
self.out = output
|
||||
@@ -24,6 +26,8 @@ class Test:
|
||||
self.out.write(f"# Exiting ({now})\n")
|
||||
self.out.flush()
|
||||
|
||||
infamy.netns.IsolatedMacVlans.Cleanup()
|
||||
|
||||
if not e:
|
||||
self._not_ok("Missing explicit test result\n")
|
||||
else:
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from infamy.neigh import ll6ping
|
||||
|
||||
def infer_put_dict(name, models):
|
||||
if not models.get("ietf-system"):
|
||||
models["ietf-system"] = { "system": { "hostname": name} }
|
||||
else:
|
||||
if not models["ietf-system"].get("system"):
|
||||
models["ieft-system"]["system"] = {}
|
||||
if not models["ietf-system"]["system"].get("hostname"):
|
||||
models["ietf-system"]["system"]["hostname"] = name
|
||||
|
||||
class Transport(ABC):
|
||||
"""Common functions for NETCONF/RESTCONF"""
|
||||
|
||||
Reference in New Issue
Block a user