. "$BST_LIB" require ifup ifupdown/present # ifupdown ships ifup and ifdown (a hard link to the same binary, dispatching on # argv[0]) plus the interfaces(5) parser. Everything below drives a sample # interfaces file in a scratch dir via -i, with --state-dir pointing at that same # scratch dir, so the suite never reads or writes the live /etc/network/interfaces # or /run/network/ifstate. --no-scripts keeps the /etc/network/if-*.d hooks out: # run-parts hooks are not part of what this port delivers, and a hook that resolves # a hostname would trap in static-glibc __nss_module_load (BRINTOS-77). tmp=${TMPDIR:-/tmp}/bst-ifupdown.$$ mkdir -p "$tmp" cfg="$tmp/interfaces" IF="ifup -i $cfg --state-dir $tmp --no-scripts" ID="ifdown -i $cfg --state-dir $tmp --no-scripts" cat > "$cfg" <<'EOF' auto lo iface lo inet loopback allow-hotplug bst0 iface bst0 inet static address 10.99.0.1 netmask 255.255.255.0 EOF command -v ifdown >/dev/null 2>&1 \ && bst_ok ifupdown/ifdown-present \ || bst_notok ifupdown/ifdown-present "ifdown missing (recipe installs it as a hard link to ifup)" # `ifup -V` prints " version " -- the binary names itself, not the # package, so the needle is "ifup version" and not "ifupdown". check_out ifupdown/version "ifup version" sh -c 'ifup -V 2>&1' # --- interfaces(5) parsing, via the dry run (-n) ----------------------------- # With -n, execute.c prints each command it *would* run to stderr and runs # nothing, so this asserts the parse and the address->command conversion without # needing the interface to exist. check ifupdown/parse-dryrun sh -c "$IF -n bst0 >/dev/null 2>&1" check_out ifupdown/dryrun-addr "10.99.0.1" sh -c "$IF -n bst0 2>&1" check_out ifupdown/dryrun-mask "10.99.0.1/255.255.255.0" sh -c "$IF -n bst0 2>&1" check_out ifupdown/dryrun-link "ip link set dev bst0" sh -c "$IF -n bst0 2>&1" # The static `down` sequence flushes and downs the link. check_out ifupdown/dryrun-down "ip addr del" sh -c "$ID -n bst0 2>&1" # An interface with no stanza is an error, not a silent success. check_rc ifupdown/unknown-iface 1 sh -c "$IF -n nosuchif0 >/dev/null 2>&1" # A malformed stanza must fail the parse rather than be skipped. bad="$tmp/interfaces.bad" printf 'iface bst9 inet static\n\taddress\n' > "$bad" check_rc ifupdown/parse-error 1 \ sh -c "ifup -i $bad --state-dir $tmp --no-scripts -n bst9 >/dev/null 2>&1" # --- real state transitions (not a dry run) --------------------------------- # `iface lo inet loopback` is the one stanza whose up/down commands are guarded # by `if (!iface_is_lo())`, so ifup/ifdown on lo run NO kernel command while still # taking the full real path: fcntl(F_SETLKW) on the state lock, and the # read/modify/write of ifstate. That makes it a safe on-target exercise of the # machinery the dry run skips. check ifupdown/state-up sh -c "$IF lo >/dev/null 2>&1" check_out ifupdown/state-file "lo=lo" sh -c "cat $tmp/ifstate 2>&1" # A second ifup is a no-op that says so (rc is non-zero; the message is the point). check_out ifupdown/state-already "already configured" sh -c "$IF lo 2>&1 || true" check ifupdown/state-down sh -c "$ID lo >/dev/null 2>&1" check ifupdown/state-cleared sh -c "! grep -q '^lo=' $tmp/ifstate 2>/dev/null" # --- dummy interface, up then down ------------------------------------------ # The ticket's deliverable: bring a real interface up from the interfaces file # and back down, checking the address lands and is withdrawn. Needs `ip` and a # kernel that can create a dummy link; both are probed, and a kernel without # dummy support is reported as skip (a coverage gap to close) rather than a # failure of ifupdown. if ! command -v ip >/dev/null 2>&1; then bst_skip ifupdown/dummy-up "iproute2 ip not installed on this image" bst_skip ifupdown/dummy-down "iproute2 ip not installed on this image" elif ! ip link add bst0 type dummy >/dev/null 2>&1; then bst_skip ifupdown/dummy-up "kernel cannot create a dummy link (no CONFIG_DUMMY)" bst_skip ifupdown/dummy-down "kernel cannot create a dummy link (no CONFIG_DUMMY)" else check_out ifupdown/dummy-up "10.99.0.1" \ sh -c "$IF bst0 >/dev/null 2>&1; ip -4 addr show dev bst0 2>&1" check ifupdown/dummy-down \ sh -c "$ID bst0 >/dev/null 2>&1; ! ip -4 addr show dev bst0 2>/dev/null | grep -q 10.99.0.1" ip link del bst0 >/dev/null 2>&1 fi rm -rf "$tmp"