From nobody Thu Sep 03 06:20:18 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hb8bW4KJ2z6qjK0 for ; Thu, 03 Sep 2026 06:20:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hb8bW3hv1z3HNk for ; Thu, 03 Sep 2026 06:20:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788416423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DEvjOF8RBnJ843y/A9X+0edeqOLxUera9umkI+cKXdM=; b=lJCxk4u9KkJ5uq9SAlWlRZLGkEuJzGgueQU9WYTCUnzsTaUfdCZh0g47wgQBrB2yC1vOGV QSv21v7dAt0RPiD6fr116E+QzYAJwN2A0uTJ6UYsGEN72bN+IQ6UaEZBsWt/RKTevGeUTg EHkkhJS5q7WohjJTYfyEk96aCByta2Bdx3vr6g8CD8P6ITZKMFV5cUZP+jHIxJnWHw1xQl zOA9AsCfxurm2qfRhoQ/Gt8jfeTsaJtDreNT3TTcI5BDUD6wDUrSuLj6dS5A2UWBiWtNLE 79pMD3l76CKUVR88M3nAL2VNcb3aOkxwBU6AYszpG35YcrSFIv1TKVv+gOJDxw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788416423; a=rsa-sha256; cv=none; b=RdgP1INGRizM9B7FU7rwLycWpH3Oqkj8XmMz0lrWQSoBuqQ9VwNnctMsbmBmwg57EPiZYO o5dqetD92G+UEVec8rsNWAiR88eVYI21Cj/cpsAoI69qubrRQB/v6r1roU8ypT3pCMlME9 Ed3u8jryaljVglKTeH4rDvJyCDMuY6wgapswPo/Qxy2aqSXnybNypKcWFaqJcSPFLl34So 3h4rAT0ntb2zlBB9qsJ2/ZpXBWVZfXPDllwOtpSNex2RwsUOCnoAPU8uASrf6KaHn61dxk uMnNx+0/75hKHqQ79LY4vFgFPxTgKITmW5bxLhsQg129vPkHWcsGEBb4I0vZxw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788416423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DEvjOF8RBnJ843y/A9X+0edeqOLxUera9umkI+cKXdM=; b=bJdUDR6chYlTVqhjLlYwgwXgD2bMexJ8Csll3eI/3GItGhZQ26eXV0Odpu9i52EsY8+FOU UV5tIGm14UiHfyEbMmKWHeqTPalCl9ydYlgnSKSoS1SBsv11sPsz5fsHmdbgbpsi4qS3Ef 4W+TZU4Htb4mzpOExSS8TIdXLJSetk84XqkIonV1EaqwVdQz3I6+k07w1PEwgj5aDGl4IK vlYCcAwDHDpZ5wrZ0QDJv0Pp9afIVfmFjyhsL5sW1kXGy4sjjV30ips0IS7hnsN4E7MHMU dQo72OrzwLjx2s0LV8SRnEhzMqlPNRe0tYvX3g8MmgangyWGEPQYsPkV4QMqjg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hb8bW2PDkz1GbG for ; Thu, 03 Sep 2026 06:20:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 45b6e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 03 Sep 2026 06:20:18 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Devin Teske Subject: git: 19b0b1f648d8 - main - examples/jails: Encode ifnames used as derive_mac counters List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dteske X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 19b0b1f648d8f114f77e82495618587b1729c4cc Auto-Submitted: auto-generated Date: Thu, 03 Sep 2026 06:20:18 +0000 Message-Id: <6a9911a2.45b6e.25f11662@gitrepo.freebsd.org> The branch main has been updated by dteske: URL: https://cgit.FreeBSD.org/src/commit/?id=19b0b1f648d8f114f77e82495618587b1729c4cc commit 19b0b1f648d8f114f77e82495618587b1729c4cc Author: Devin Teske AuthorDate: 2026-09-03 06:17:52 +0000 Commit: Devin Teske CommitDate: 2026-09-03 06:17:52 +0000 examples/jails: Encode ifnames used as derive_mac counters derive_mac keeps a per-parent branch index in a global named from the parent interface so the N nibble can increment when the same PHY is presented more than once. That name must be a POSIX identifier; a vlan-style parent (em0.20) is not. Encode the ifname first (alnum unchanged, every other byte as _HH) so the lookup stays a symbol-table hit and em0.20 does not collide with em0_20. Same change in jib (9.2) and jng (9.4). In jng, also address netgraph by node name. ngctl(8) treats `.' and `:' as control characters, so ng_ether(4) names its node after the sanitized ifname (vtnet0.20 becomes vtnet0_20). Sanitize the parent ifname where it enters and use that for every ngctl call; ifconfig(8) and derive_mac keep the real name. Previously jng failed outright on such parents where jib did not. PR: 291143 Reported by: Victor MFC after: 1 week Reviewed by: jlduran Differential Revision: https://reviews.freebsd.org/D59326 --- share/examples/jails/jib | 32 +++++++++++++--- share/examples/jails/jng | 99 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 96 insertions(+), 35 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 44d53c44bf11..b18c60da15ec 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -7,7 +7,7 @@ ############################################################ IDENT(1) # # $Title: if_bridge(4) management script for vnet jails $ -# $Version: 9.1 $ +# $Version: 9.2 $ # ############################################################ INFORMATION # @@ -111,7 +111,7 @@ # ############################################################ GLOBALS -VERSION='$Version: 9.1 $' +VERSION='$Version: 9.2 $' pgm="${0##*/}" # Program basename @@ -157,6 +157,25 @@ action_usage() exit $FAILURE } +iface_encode() +{ + LC_ALL=C iface="$1" awk 'BEGIN { + for (n = 0; n < 256; n++) + pack[sprintf("%c", n)] = sprintf("_%02x", n) + numbers = "0123456789" + uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + lowercase = "abcdefghijklmnopqrstuvwxyz" + valid = "[" numbers uppercase lowercase "]" + iface = ENVIRON["iface"] + len = length(iface) + for (n = 1; n <= len; n++) { + let = substr(iface, n, 1) + _iface = _iface (let ~ valid ? let : pack[let]) + } + print _iface + }' +} + derive_mac() { local OPTIND=1 OPTARG __flag @@ -169,13 +188,16 @@ derive_mac() done shift $(( $OPTIND - 1 )) + local __iface="$1" if [ ! "$__mac_num" ]; then - eval __mac_num=\${_${iface}_num:--1} + local __iface_encoded + __iface_encoded=$( iface_encode "$__iface" ) + eval __mac_num=\${_${__iface_encoded}_num:--1} __mac_num=$(( $__mac_num + 1 )) - eval _${iface}_num=\$__mac_num + eval _${__iface_encoded}_num=\$__mac_num fi - local __iface="$1" __name="$2" __var_to_set="$3" __var_to_set_b="$4" + local __name="$2" __var_to_set="$3" __var_to_set_b="$4" local __iface_devid __new_devid __num __new_devid_b # # Calculate MAC address derived from given iface. diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 48dc3eb67967..db7f16334884 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -7,7 +7,7 @@ ############################################################ IDENT(1) # # $Title: netgraph(4) management script for vnet jails $ -# $Version: 9.3 $ +# $Version: 9.4 $ # ############################################################ INFORMATION # @@ -138,7 +138,7 @@ NG_BRIDGE_MAX_STALENESS=4294967295 ############################################################ GLOBALS -VERSION='$Version: 9.3 $' +VERSION='$Version: 9.4 $' pgm="${0##*/}" # Program basename @@ -214,6 +214,25 @@ action_usage() die } +iface_encode() +{ + LC_ALL=C iface="$1" awk 'BEGIN { + for (n = 0; n < 256; n++) + pack[sprintf("%c", n)] = sprintf("_%02x", n) + numbers = "0123456789" + uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + lowercase = "abcdefghijklmnopqrstuvwxyz" + valid = "[" numbers uppercase lowercase "]" + iface = ENVIRON["iface"] + len = length(iface) + for (n = 1; n <= len; n++) { + let = substr(iface, n, 1) + _iface = _iface (let ~ valid ? let : pack[let]) + } + print _iface + }' +} + derive_mac() { local OPTIND=1 OPTARG __flag @@ -226,13 +245,16 @@ derive_mac() done shift $(( $OPTIND - 1 )) + local __iface="$1" if [ ! "$__mac_num" ]; then - eval __mac_num=\${_${iface}_num:--1} + local __iface_encoded + __iface_encoded=$( iface_encode "$__iface" ) + eval __mac_num=\${_${__iface_encoded}_num:--1} __mac_num=$(( $__mac_num + 1 )) - eval _${iface}_num=\$__mac_num + eval _${__iface_encoded}_num=\$__mac_num fi - local __iface="$1" __name="$2" __var_to_set="$3" __var_to_set_b="$4" + local __name="$2" __var_to_set="$3" __var_to_set_b="$4" local __iface_devid __new_devid __num __new_devid_b # # Calculate MAC address derived from given iface. @@ -391,6 +413,16 @@ jng_pin_jiface() jng_bridge_persist_hosts "$pbridge" || : persist optional } +ng_ether_sanitize_ifname() +{ + # NB: Emulates function of same name in sys/netgraph/ng_ether.c + ifname="$1" awk 'BEGIN { + _ifname = ENVIRON["ifname"] + gsub(/[.:]/, "_", _ifname) + print _ifname + }' +} + jng_bridge_usage="bridge [-h] [-b BRIDGE_NAME] NAME [!|=]iface0 [[!|=]iface1 ...]" jng_bridge_descr="Create ng0_NAME [ng1_NAME ...]" jng_bridge() @@ -417,7 +449,7 @@ jng_bridge() mustberoot_to_continue - local iface parent jiface jiface_devid + local iface node parent jiface jiface_devid local new clone_mac no_derive num quad mtu i=0 for iface in $*; do @@ -428,6 +460,10 @@ jng_bridge() !*) iface=${iface#!} no_derive=1 ;; esac + # ngctl(8) treats `.' and `:' as control characters, so + # ng_ether(4) names its node after the sanitized ifname + node=$( ng_ether_sanitize_ifname "$iface" ) + # Make sure the interface doesn't exist already jiface=ng${i}_$name if quietly ngctl msg "$jiface:" getifname; then @@ -439,18 +475,18 @@ jng_bridge() ifconfig $iface up || return # Set promiscuous mode and don't overwrite src addr - ngctl msg $iface: setpromisc 1 || return - ngctl msg $iface: setautosrc 0 || return + ngctl msg $node: setpromisc 1 || return + ngctl msg $node: setautosrc 0 || return # Make sure the interface has been bridged # NB: You must connect uplinkX before linkX # NB: see ng_bridge(4) for policy on first connected hook - if ! quietly ngctl info ${iface}bridge:; then - ngctl mkpeer $iface: bridge lower uplink1 || return - ngctl connect $iface: $iface:lower upper link0 || + if ! quietly ngctl info ${node}bridge:; then + ngctl mkpeer $node: bridge lower uplink1 || return + ngctl connect $node: $node:lower upper link0 || return - ngctl name $iface:lower ${iface}bridge || return - jng_bridge_persist_hosts ${iface}bridge || + ngctl name $node:lower ${node}bridge || return + jng_bridge_persist_hosts ${node}bridge || : persist optional fi @@ -459,33 +495,33 @@ jng_bridge() # Optionally create a secondary bridge # NB: This time, you want to only connect linkX (no uplinkX) if [ "$bridge" != "bridge" ] && - ! quietly ngctl info "$iface$bridge:" + ! quietly ngctl info "$node$bridge:" then num=1 - while quietly ngctl msg ${iface}bridge: getstats $num + while quietly ngctl msg ${node}bridge: getstats $num do num=$(( $num + 1 )) done - ngctl mkpeer $iface:lower bridge link$num link0 || + ngctl mkpeer $node:lower bridge link$num link0 || return - ngctl name ${iface}bridge:link$num "$iface$bridge" || + ngctl name ${node}bridge:link$num "$node$bridge" || return fi # Create a new interface to the bridge num=1 - while quietly ngctl msg "$iface$bridge:" getstats $num; do + while quietly ngctl msg "$node$bridge:" getstats $num; do num=$(( $num + 1 )) done - ngctl mkpeer "$iface$bridge:" eiface link$num ether || return + ngctl mkpeer "$node$bridge:" eiface link$num ether || return # Rename the new interface while [ ${#jiface} -gt 15 ]; do # OS limitation jiface=${jiface%?} done - new=$( ngctl show -n "$iface$bridge:link$num" ) || return + new=$( ngctl show -n "$node$bridge:link$num" ) || return new=$( set -- $new; echo $2 ) - ngctl name "$iface$bridge:link$num" $jiface || return + ngctl name "$node$bridge:link$num" $jiface || return ifconfig $new name $jiface || return ifconfig $jiface mtu $mtu || return ifconfig $jiface up || return @@ -515,7 +551,7 @@ jng_pin() { local OPTIND=1 OPTARG flag local show_all= err=$SUCCESS - local name iface jiface + local name iface node jiface while getopts ah flag; do case "$flag" in @@ -528,8 +564,9 @@ jng_pin() [ $# -eq 0 ] || action_usage pin "too many arguments" # NOTREACHED for iface in $( ifconfig -l ); do - quietly ngctl info ${iface}bridge: || continue - jng_bridge_persist_hosts ${iface}bridge || + node=$( ng_ether_sanitize_ifname "$iface" ) + quietly ngctl info ${node}bridge: || continue + jng_bridge_persist_hosts ${node}bridge || : persist optional done set -- $( jls -q name 2> /dev/null ) @@ -663,7 +700,7 @@ jng_stats() { local OPTIND=1 OPTARG flag local show_all= - local name iface ether= + local name iface node ether= while getopts ahj flag; do case "$flag" in a) show_all=1 ;; @@ -682,7 +719,8 @@ jng_stats() # Get a list of bridged ng_ether(4) devices for iface in $( ifconfig -l ); do - quietly ngctl info ${iface}bridge: || continue + node=$( ng_ether_sanitize_ifname "$iface" ) + quietly ngctl info ${node}bridge: || continue ether="$ether $iface" done set -- $ether $( "$0" show ) @@ -702,14 +740,15 @@ jng_stats() # NOTREACHED if ifconfig -l | xargs -n1 2> /dev/null | fgrep -qw "$name" then + node=$( ng_ether_sanitize_ifname "$name" ) [ "$STATS_FMT" != "text" ] || - echo "${name}bridge:uplink1 [lower]" - ngctl msg ${name}bridge: getstats -1 | + echo "${node}bridge:uplink1 [lower]" + ngctl msg ${node}bridge: getstats -1 | fmt_stats -n "${name}.lower" -t "$now" [ "$STATS_FMT" != "text" ] || - echo "${name}bridge:link0 [upper]" - ngctl msg ${name}bridge: getstats 0 | + echo "${node}bridge:link0 [upper]" + ngctl msg ${node}bridge: getstats 0 | fmt_stats -n "${name}.upper" -t "$now" fi local jiface