Skip to content

Instantly share code, notes, and snippets.

@MichaelSasser
Last active April 25, 2021 00:08
Show Gist options
  • Save MichaelSasser/773cc15c39a990006089a284d587b219 to your computer and use it in GitHub Desktop.
Save MichaelSasser/773cc15c39a990006089a284d587b219 to your computer and use it in GitHub Desktop.
Temporary workaround for network interface race condition
#!/usr/bin/env bash
# dotfiles
# Copyright (c) 2021 Michael Sasser <Michael@MichaelSasser.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ------------------------------- [ README ] ----------------------------------
# This is a simple workaround, when your devices network interface runs into a
# race condition. This is not considered a permanent solution. If you can, fix
# your device.
#
# This script checks for an default route and tries to "ping" it. If something
# went wrong in those steps, it restarts the interface. This is repeated until
# the script was able to find and ping the default gateway. The script can be
# stopped by sending a SIGTERM or a SIGKILL or simply by pressing CTRL+c.
# To show a status, the script tells you how many retries it needed until a
# proper network connection was established. Every retry the counter is
# incremented by one and updated on the virtual terminal.
# If the script is started with a proper network connection, it will just
# print a message, that nothing is to do.
#
# To use this script, you need at least configure the interface ("iface") in
# the configuration section below this readme.
# -------------------------- [ Configure here ] -------------------------------
# The interface to restart. (The interface to check is automatically
# determined.)
iface="bond0"
# Time in seconds to wait before checking the connection.
# Four seconds is a good value for that on my machine.
wait_before_check=4
# Time in seconds to wait before setting up the interface up again.
# Two seconds is a good value for that on my machine.
wait_before_iface_up=2
# ------------------- [ Don't change anything below ] -------------------------
# Restarts the interface.
function restart_iface() {
sudo ip link set "${iface}" down
sleep $wait_before_iface_up
sudo ip link set "${iface}" up
}
# Check, if the device has a network connection by checking if there is a
# default route. If there is one, try to ping the default root.
# returns 1 if there is a network connection.
# returns 0 if not.
function is_connected() {
local default
default="$(/usr/bin/ip r | grep default | cut -d ' ' -f 3)"
[ -z "$default" ] && return 0
/usr/bin/ping -q -w 1 -c 1 "${default}" > /dev/null && return 1 || return 0
}
# The "main" function continuously checks if there is a network connection.
# If not, it restarts the main interface until a network connection could be
# established. After that the program ends.
function main() {
local tries
tries=0
while is_connected; do
tries=$((tries+1))
echo -ne "Restarting Network. Tries: ${tries}\033[0K\r"
restart_iface
sleep $wait_before_check
done
if [[ $tries -gt 0 ]]; then
echo "A network connection has been established."
else
echo "You already have an active network connection."
fi
}
main
# vim: set ft=sh :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment