Skip to content

Instantly share code, notes, and snippets.

@afresh1
Created February 26, 2023 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afresh1/0e91e75684d1b54735152ee0304c9572 to your computer and use it in GitHub Desktop.
Save afresh1/0e91e75684d1b54735152ee0304c9572 to your computer and use it in GitHub Desktop.
A small shellscript to work around a FreeBSD bug (208910) that requires you to move the vlan onto an epair member of the bridge, not on the physical interface in the bridge.
#!/bin/sh
set -o errexit -o pipefail -o nounset -o noclobber -o noglob
# Copyright (c) 2023 Andrew Hewus Fresh <andrew@afresh1.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
usage() {
echo "$( basename $0 ) vlan [ bridge ]"
exit ${1-0}
}
err() {
echo "$1" >&2
exit 1
}
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
usage 1
fi
if [ "$1" = "-h" ]; then
cat <<EOL
The '$(basename "$0")' tool works around a FreeBSD bug
when an interface both needs to be a bridge member and have a vlan
on top of it.
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208910
EOL
exit
fi
description="workaround for vlan bridge bug"
vlan=$1; shift
vid="$( ifconfig $vlan | sed -n 's/.*vlan: \([0-9][0-9]*\) .*/\1/p' )"
bridge=bridge0
if [ $# -gt 0 ]; then
bridge=$1; shift
fi
parent="$( ifconfig "$vlan" | sed -n 's/.*parent interface: //p' )"
[ "$parent" ] || err "Unable to find parent interface for $vlan"
if [ "$parent" != "${parent#epair}" ]; then
echo "Already worked around"
exit 0
fi
epair=epair0
while ifconfig "$epair"a > /dev/null 2>&1; do
ifconfig "$epair"a | grep -q "description: $description" && break
epair=epair$(( ${epair#epair} + 1 ))
done
ifconfig "$epair"a > /dev/null 2>&1 || ifconfig "$epair" create
ifconfig "$epair"a description "$description"
ifconfig "$epair"b description "$description"
ifconfig "$bridge" > /dev/null 2>&1 || ifconfig "$bridge" create
for i in "$epair"a "$epair"b "$bridge"; do
ifconfig "$i" up
done
ifconfig "$bridge" | grep -q "member: $parent " ||
ifconfig "$bridge" addm "$parent"
ifconfig "$bridge" addm "$epair"a
ifconfig "$vlan" -vlandev -wlanaddr
ifconfig "$vlan" vlan "$vid" vlandev "$epair"b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment