More networking fixes

This commit is contained in:
bergware
2025-06-09 02:29:04 +02:00
parent 194f972edf
commit ddb71eb635
4 changed files with 99 additions and 50 deletions

View File

@@ -30,6 +30,7 @@ DOCKER_TIMEOUT=$(awk -F'"' '/^DOCKER_TIMEOUT=/{print $2}' $DOCKER_CFG 2>/dev/nul
# network file references
INI=/var/local/emhttp/network.ini
STA=/var/local/emhttp/statics.ini
TMP=/var/tmp/network.tmp
# run & log functions
@@ -57,6 +58,19 @@ carrier(){
return 1
}
# add entry to watch list
add_entry(){
rm -f /var/tmp/${1%% *}.down
[[ -e $STA ]] && echo "$1" >>$STA
}
# delete enty from watch list
del_entry(){
touch /var/tmp/$1.down
[[ -e $STA ]] && sed -i "/^$1 .*/d" $STA
sleep 0.5
}
# initialize docker settings
docker_read_options(){
# determine active port name
@@ -178,11 +192,6 @@ network(){
docker network ls --filter driver="$1" --format='{{.Name}}' 2>/dev/null | grep -P "^[a-z]+$2(\$|\.)" | tr '\n' ' '
}
# Does the ipv4 address exist?
ipv4_exist(){
ip -4 -br addr show to $2 dev $1 | awk '{print $3;exit}'
}
# Is container running?
container_running(){
local CONTAINER
@@ -414,22 +423,29 @@ docker_network_start(){
done
# hack to let containers talk to host
if [[ $TYPE == br ]]; then
LINK=shim-$NETWORK
SHIM=shim-$NETWORK
if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
# create shim interface
[[ -e $SYSTEM/$LINK ]] || run ip link add link $NETWORK name $LINK type $ATTACH mode $MODE
if [[ ! -e $SYSTEM/$SHIM ]]; then
run ip link add link $NETWORK name $SHIM type $ATTACH mode $MODE
run ip link set $SHIM up
fi
# disable IPv6 on shim interface
echo 1 >$CONF6/$LINK/disable_ipv6
run ip -6 addr flush dev $LINK
echo 1 >$CONF6/$SHIM/disable_ipv6
run ip -6 addr flush dev $SHIM
# copy parent IPv4 address to shim interface
run ip addr add $IPV4 dev $LINK metric 0
run ip link set $LINK up
log "created network $LINK for host access"
elif [[ -e $SYSTEM/$LINK ]]; then
# remove shim interface
run ip addr flush dev $LINK
run ip link set $LINK down
run ip link del $LINK
run ip -4 addr add $IPV4 dev $SHIM metric 0
add_entry "$SHIM $IPV4 metric 0"
GW4=$(ip -4 route show to default dev $NETWORK | awk '{print $3;exit}')
if [[ -n $GW4 ]]; then
run ip -4 route add default via $GW4 dev $SHIM metric 0
add_entry "$SHIM GW4 default via $GW4 metric 0"
fi
log "created network $SHIM for host access"
elif [[ -e $SYSTEM/$SHIM ]]; then
# remove shim interface assignment
del_entry $SHIM
run ip -4 addr del $IPV4 dev $SHIM metric 0
fi
else
if [[ $TYPE == wlan ]]; then
@@ -442,11 +458,18 @@ docker_network_start(){
echo 1 >$CONF6/$VHOST/disable_ipv6
run ip -6 addr flush dev $VHOST
# copy parent IPv4 address to vhost interface
[[ -z $(ipv4_exist $VHOST ${IPV4%/*}) ]] && run ip addr add $IPV4 dev $VHOST metric 0
run ip -4 addr add $IPV4 dev $VHOST metric 0
add_entry "$VHOST $IPV4 metric 0"
GW4=$(ip -4 route show to default dev $NETWORK | awk '{print $3;exit}')
if [[ -n $GW4 ]]; then
run ip -4 route add default via $GW4 dev $VHOST metric 0
add_entry "$VHOST GW4 default via $GW4 metric 0"
fi
log "created network $VHOST for host access"
elif [[ -n $IPV4 && -e $SYSTEM/$VHOST && -n $(ipv4_exist $VHOST ${IPV4%/*}) ]]; then
# remove parent IPv4 address from vhost interface
run ip addr del $IPV4 dev $VHOST metric 0
elif [[ -n $IPV4 && -e $SYSTEM/$VHOST ]]; then
# remove vhost interface assignment
del_entry $VHOST
run ip -4 addr del $IPV4 dev $VHOST metric 0
fi
fi
fi
@@ -468,25 +491,24 @@ docker_network_stop(){
[[ ${NIC:0:3} == eth ]] && NIC=$(active $NIC)
driver ${NIC//[0-9]/} forced
for NETWORK in $(network $ATTACH ${NIC//[^0-9]/}); do
IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}')
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK &>/dev/null
TYPE=${NETWORK//[0-9.]/}
if [[ $TYPE == br ]]; then
LINK=shim-$NETWORK
if [[ -e $SYSTEM/$LINK ]]; then
run ip addr flush dev $LINK
run ip link set $LINK down
run ip link del $LINK
if [[ $TYPE == br || $TYPE == wlan ]]; then
SHIM=shim-$NETWORK
if [[ -e $SYSTEM/$SHIM ]]; then
del_entry $SHIM
run ip -4 addr del $IPV4 dev $SHIM metric 0
fi
elif [[ $TYPE != wlan ]]; then
else
VHOST=vhost${NETWORK//[^0-9.]/}
[[ -e $SYSTEM/$VHOST ]] && run ip addr flush dev $VHOST
if [[ -e $SYSTEM/$VHOST ]]; then
del_entry $VHOST
run ip -4 addr del $IPV4 dev $VHOST metric 0
fi
fi
done
done
if [[ -e $SYSTEM/shim-wlan0 ]]; then
IPV4=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
[[ -n $IPV4 ]] && run ip addr del $IPV4 dev shim-wlan0
fi
log "Network stopped."
}

View File

@@ -87,6 +87,7 @@
# Adapted by Bergware for use in Unraid OS - June 2025
# - revert metric assignment to static addresses
# - remove duplicate ipv6 parameters
# - improve gateway creation
###########
# LOGGING #
@@ -632,8 +633,13 @@ gateway_up(){
[[ -z ${i[1]} ]] && DEV=${IFNAME[$i]} || DEV=${IFNAME[$i]}.${VLANID[$x]}
IP=${PROTOCOL[$x]:-ipv4}
AD=${METRIC[$x]}
[[ -n $AD ]] && AD="metric $AD"
EXIST=$(ip -4 route show to default via $(unzero $GW) dev $DEV | grep "$AD ")
if [[ -z $AD ]]; then
AD="metric 1"
EXIST=$(ip -4 route show to default via $(unzero $GW) dev $DEV | grep -vm1 metric)
else
AD="metric $AD"
EXIST=$(ip -4 route show to default via $(unzero $GW) dev $DEV | grep -m1 "$AD ")
fi
[[ $IP != ipv6 && -z $EXIST ]] && run ip -4 route add default via $(unzero $GW) dev $DEV $AD
done
for GW6 in ${GATEWAY6[@]}; do
@@ -644,8 +650,13 @@ gateway_up(){
[[ -z ${i[1]} ]] && DEV=${IFNAME[$i]} || DEV=${IFNAME[$i]}.${VLANID[$x]}
IP=${PROTOCOL[$x]:-ipv4}
AD6=${METRIC6[$x]}
[[ -n $AD6 ]] && AD6="metric $AD6"
EXIST=$(ip -6 route show to default via $(unzero6 $GW6) dev $DEV | grep "$AD6 ")
if [[ -z $AD6 ]]; then
AD6="metric 1"
EXIST=$(ip -6 route show to default via $(unzero6 $GW6) dev $DEV | grep -vm1 metric)
else
AD6="metric $AD6"
EXIST=$(ip -6 route show to default via $(unzero6 $GW6) dev $DEV | grep -m1 "$AD6 ")
fi
[[ $IP != ipv4 && -z $EXIST ]] && run ip -6 route add default via $(unzero6 $GW6) dev $DEV $AD6
done
}

View File

@@ -163,7 +163,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
IPV4="$(ip -4 -br addr show scope global primary dev $IFACE | awk '{$2="";print;exit}')"
if [[ -n $IPV4 ]]; then
echo "$IPV4" >>$STA
echo "$IFACE GW4 $(ip -4 route show to default dev $IFACE)" >>$STA
GW4="$(ip -4 route show to default dev $IFACE)"
[[ -n $GW4 ]] && echo "$IFACE GW4 $GW4" >>$STA
fi
fi
echo "USE_DHCP6:0=\"${USE_DHCP6[$i]}\"" >>$INI
@@ -187,7 +188,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
IPV6="$(ip -6 -br addr show scope global primary -deprecated dev $IFACE | awk '{$2="";print;exit}')"
if [[ -n $IPV6 ]]; then
echo "$IPV6" >>$STA
echo "$IFACE GW6 $(ip -6 route show to default dev $IFACE)" >>$STA
GW6="$(ip -6 route show to default dev $IFACE)"
[[ -n $GW6 ]] && echo "$IFACE GW6 $GW6" >>$STA
fi
fi
echo "USE_MTU=\"${USE_MTU[$i]}\"" >>$INI
@@ -219,7 +221,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
IPV4="$(ip -4 -br addr show scope global primary dev $DEV | awk '{$2="";print;exit}')"
if [[ -n $IPV4 ]]; then
echo "${IPV4/@$IFACE/}" >>$STA
echo "$DEV GW4 $(ip -4 route show to default dev $DEV)" >>$STA
GW4="$(ip -4 route show to default dev $DEV)"
[[ -n $GW4 ]] && echo "$DEV GW4 $GW4" >>$STA
fi
fi
echo "USE_DHCP6:$j=\"${USE_DHCP6[$i,$j]}\"" >>$INI
@@ -244,7 +247,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
IPV6="$(ip -6 -br addr show scope global primary -deprecated dev $DEV | awk '{$2="";print;exit}')"
if [[ -n $IPV6 ]]; then
echo "${IPV6/@$IFACE/}" >>$STA
echo "$DEV GW6 $(ip -6 route show to default dev $DEV)" >>$STA
GW6="$(ip -6 route show to default dev $DEV)"
[[ -n $GW6 ]] && echo "$DEV GW6 $GW6" >>$STA
fi
fi
done

View File

@@ -58,32 +58,44 @@ while :; do
for i in ${!TASK[@]}; do
ADDR=(${TASK[$i]})
PORT=${ADDR[0]}
[[ $LAST != $PORT ]] && STATE=$(state $PORT)
[[ $LAST != ${PORT%.*} ]] && STATE=$(state ${PORT%.*})
case $STATE in
1) # up
case ${ADDR[1]} in
GW4)
# no existing default and new default is defined?
ROUTE=$(ip -4 route show to default dev $PORT)
[[ -z $ROUTE && "${TASK[$i]}" =~ "default" ]] && ip -4 route add dev ${TASK[$i]/GW4/}
IPV4=$(ip -4 -br addr show scope global primary dev $PORT | awk '{print $3;exit}')
if [[ -n $IPV4 ]]; then
ROUTE=$(ip -4 route show to default dev $PORT)
[[ -z $ROUTE ]] && ip -4 route add dev ${TASK[$i]/GW4/}
fi
;;
GW6)
# no existing default and new default is defined?
ROUTE=$(ip -6 route show to default dev $PORT)
[[ -z $ROUTE && "${TASK[$i]}" =~ "default" ]] && ip -6 route add dev ${TASK[$i]/GW6/}
IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $PORT | awk '{print $3;exit}')
if [[ -n $IPV6 ]]; then
ROUTE=$(ip -6 route show to default dev $PORT)
[[ -z $ROUTE ]] && ip -6 route add dev ${TASK[$i]/GW6/}
fi
;;
*)
# IP address not present? create it
[[ "$(ip -br addr show dev $PORT)" =~ "${ADDR[1]}" ]] || ip addr add dev ${TASK[$i]}
IPA=$(ip -br addr show to ${ADDR[1]} dev $PORT)
if [[ -f /var/tmp/$PORT.down ]]; then
# Special treatment for shim and vhost interfaces
[[ -n $IPA ]] && ip addr del dev ${TASK[$i]}
else
# IP address not present? create it
[[ -z $IPA ]] && ip addr add dev ${TASK[$i]}
fi
;;
esac
;;
0) # down
# IP address present, remove it
[[ "$(ip -br addr show dev $PORT)" =~ "${ADDR[1]}" ]] && ip addr del dev ${TASK[$i]}
[[ -n $(ip -br addr show to ${ADDR[1]} dev $PORT) ]] && ip addr del dev ${TASK[$i]}
;;
esac
LAST=$PORT
LAST=${PORT%.*}
done
fi
# check every 3 seconds