Skip to content

Instantly share code, notes, and snippets.

@yakatz
Created March 19, 2018 18:04
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 yakatz/f16824ea3a4597d35737463c612eb8a3 to your computer and use it in GitHub Desktop.
Save yakatz/f16824ea3a4597d35737463c612eb8a3 to your computer and use it in GitHub Desktop.
netplugd bridge sync script
#!/bin/bash
## This script will bounce a br interface if a member interface goes down.
## This will cause router BGP timers to reset, making outages last only seconds instead of minutes.
##
## This script is called by netplug on Vyos:
## /etc/netplug/linkdown.d/my-brdown
##
## Version History
## 1.0 - Initial version
## 1.1 - Add per-interface lockfile
##
LOCKDIR=/var/run/my-bridge-ctl
# Since we only have one br, not going to implement this right now.
#IGNORE_BRIDGES=()
IFACE=$1
#Remove the lock directory
function cleanup {
# Can't delete directory we are in
popd > /dev/null
if rmdir $LOCKDIR; then
logger -is -t "my-bridge-ctl" -p "kern.info" "Finished"
else
logger -is -t "my-bridge-ctl" -p "kern.error" "Failed to remove lock directory '$LOCKDIR'"
exit 1
fi
}
# TODO: Make lockdir based on bridge ID to support multiple bridges on one firewall.
if mkdir $LOCKDIR; then
# We don't want to deal with paths in loops
pushd $LOCKDIR > /dev/null
#Ensure that if we "grabbed a lock", we release it
#Works for SIGTERM and SIGINT(Ctrl-C)
trap "cleanup" EXIT
logger -is -t "my-bridge-ctl" -p "kern.info" "Acquired lock, running"
# Processing starts here
IFACE_DESC=$(<"/sys/class/net/${IFACE}/ifalias")
IFACE_BR_DIR="/sys/class/net/${IFACE}/brport"
if [ ! -d "$IFACE_BR_DIR" ]; then
logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC-no desc}) went down. Not a member of a bridge. Skipping."
else
# Make lockfile for our interface
touch "${IFACE}.starter"
IFACE_BR_LINK=$(realpath "/sys/class/net/${IFACE}/master")
IFACE_BR_NAME=$(basename $IFACE_BR_LINK)
IFACE_BR_DESC=$(<"${IFACE_BR_LINK}/ifalias")
logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC:-no desc}) went down. Member of bridge ${IFACE_BR_NAME} (${IFACE_BR_DESC:-no desc})."
# TODO: Insert IGNORE_BRIDGE check here
find "${IFACE_BR_LINK}/brif" -type l -print0 | while IFS= read -r -d $'\0' IFACE_BR_MEMBER_LINK; do
IFACE_BR_MEMBER_NAME=$(basename $IFACE_BR_MEMBER_LINK)
IFACE_BR_MEMBER_DESC=$(<"/sys/class/net/${IFACE_BR_MEMBER_NAME}/ifalias")
if [ "${IFACE}" == "${IFACE_BR_MEMBER_NAME}" ]; then
logger -is -t "my-bridge-ctl" -p "kern.info" "${IFACE_BR_NAME} caused by ${IFACE_BR_MEMBER_NAME} (${IFACE_BR_MEMBER_DESC}). Skipping."
continue
fi
# Make lockfile for member interfaces
touch "${IFACE_BR_MEMBER_NAME}.member"
logger -is -t "my-bridge-ctl" -p "kern.info" "${IFACE_BR_NAME} member interface ${IFACE_BR_MEMBER_NAME} (${IFACE_BR_MEMBER_DESC}). Setting down."
# Actually bounce link
ip link set dev ${IFACE_BR_MEMBER_NAME} down
#logger -is -t "my-bridge-ctl" -p "kern.info" "Interface ${IFACE_BR_MEMBER_NAME} set down."
done
# Sleep for a second to let interfaces stabalize
logger -is -t "my-bridge-ctl" -p "kern.info" "Sleeping 2 seconds."
sleep 2
for IFACE_BR_MEMBER_LINK in *.member; do
IFACE_BR_MEMBER_NAME=${IFACE_BR_MEMBER_LINK%.*}
# Actually bounce link
ip link set dev ${IFACE_BR_MEMBER_NAME} up
# Remove interface lockfile
rm "${IFACE_BR_MEMBER_LINK}"
logger -is -t "my-bridge-ctl" -p "kern.info" "Interface ${IFACE_BR_MEMBER_NAME} set up."
done
rm "${IFACE}.starter"
fi
else
logger -is -t "my-bridge-ctl" -p "kern.info" "Could not create lock directory '$LOCKDIR'"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment