mirror of
https://github.com/unraid/webgui.git
synced 2026-01-06 09:39:58 -06:00
Backport networking fixes to 7.1
This commit is contained in:
@@ -55,15 +55,13 @@ function index($key) {
|
||||
return filter_var($key, FILTER_SANITIZE_NUMBER_INT);
|
||||
}
|
||||
|
||||
function metric($eth, $prot, $index) {
|
||||
function metric($eth) {
|
||||
$system = '/sys/class/net';
|
||||
$bridge = str_replace('eth','br', $eth);
|
||||
$bond = str_replace('eth','bond', $eth);
|
||||
$bridge = str_replace('eth', 'br', $eth);
|
||||
$bond = str_replace('eth', 'bond', $eth);
|
||||
$port = file_exists("$system/$bridge") ? $bridge : (file_exists("$system/$bond") ? $bond : $eth);
|
||||
$metric = exec("ip -$prot route show default dev $port 2>/dev/null | grep -Pom1 ' metric \K\d+'");
|
||||
if ($metric) return $metric + $index;
|
||||
exec("ip -$prot route show default 2>/dev/null | grep -Po ' metric \K\d+'",$metrics);
|
||||
return (count($metrics) ? max($metrics) : 0) + $index + 1;
|
||||
$index = exec("cat $system/$port/ifindex 2>/dev/null");
|
||||
return 1000 + ($index ?: exec("cat $system/*/ifindex | sort -n | tail -1") + 1);
|
||||
}
|
||||
|
||||
// remove non-existing ethernet ports
|
||||
@@ -476,9 +474,9 @@ function addVLAN(port) {
|
||||
}
|
||||
|
||||
function removeVLAN(element) {
|
||||
var id = $(element).prop('id').split('-');
|
||||
var form = $(element).closest('form');
|
||||
$(element).remove();
|
||||
$('#view-'+id[1]).find('select').first().trigger('change');
|
||||
form.find('select').first().trigger('change');
|
||||
}
|
||||
|
||||
function showVLAN(port) {
|
||||
@@ -729,7 +727,7 @@ _(IPv4 address)_:
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:0" maxlength="15" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"GATEWAY:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC:0")?:metric('eth0',4,0)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC:0")?:metric('eth0')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
@@ -752,7 +750,7 @@ _(IPv6 address)_:
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:0" maxlength="39" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"GATEWAY6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC6:0")?:metric('eth0',6,0)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC6:0")?:metric('eth0')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
@@ -830,7 +828,7 @@ _(IPv4 address)_:
|
||||
<div markdown="1" class="more-gw4-eth0-<?=$i?> hide">
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"GATEWAY:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC:$i")?:metric('eth0.<?=_var($eth0,"VLANID:$i")?>',4,$i)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC:$i")?:metric('eth0.'._var($eth0,"VLANID:$i"))?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
@@ -859,7 +857,7 @@ _(IPv6 address)_:
|
||||
<div markdown="1" class="more-gw6-eth0-<?=$i?> hide">
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"GATEWAY6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC6:$i")?:metric('eth0.<?=_var($eth0,"VLANID:$i")?>',6,$i)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($eth0,"METRIC6:$i")?:metric('eth0.'._var($eth0,"VLANID:$i"))?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
@@ -921,7 +919,7 @@ _(IPv4 address)_:
|
||||
<div markdown="1" class="more-gw4-eth0-INDEX hide">
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" autocomplete="off" spellcheck="false" value="" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('eth0.INDEX',4,$i+1)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('eth0.INDEX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -942,7 +940,7 @@ _(IPv6 address)_:
|
||||
<div markdown="1" class="more-gw6-eth0-INDEX hide">
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" autocomplete="off" spellcheck="false" value="" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('eth0.INDEX',6,$i+1)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('eth0.INDEX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -186,7 +186,7 @@ _(IPv4 address)_:
|
||||
<div markdown="1" class="more-gw4-ethX-0 hide">
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:0" maxlength="15" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"GATEWAY:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC:0")?:metric('ethX',4,0)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC:0")?:metric('ethX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
@@ -213,7 +213,7 @@ _(IPv6 address)_:
|
||||
<div markdown="1" class="more-gw6-ethX-0 hide">
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:0" maxlength="39" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"GATEWAY6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC6:0")?:metric('ethX',6,0)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC6:0")?:metric('ethX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
@@ -293,7 +293,7 @@ _(IPv4 address)_:
|
||||
<div markdown="1" class="more-gw4-ethX-<?=$i?> hide">
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"GATEWAY:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC:$i")?:metric('ethX.<?=_var($ethX,"VLANID:$i")?>',4,$i)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC:$i")?:metric('ethX.'._var($ethX,"VLANID:$i"))?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
@@ -320,7 +320,7 @@ _(IPv6 address)_:
|
||||
<div markdown="1" class="more-gw6-ethX-<?=$i?> hide">
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"GATEWAY6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC6:$i")?:metric('ethX.<?=_var($ethX,"VLANID:$i")?>',6,$i)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" autocomplete="off" spellcheck="false" value="<?=_var($ethX,"METRIC6:$i")?:metric('ethX.'._var($ethX,"VLANID:$i"))?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
@@ -383,7 +383,7 @@ _(IPv4 address)_:
|
||||
<div markdown="1" class="more-gw4-ethX-INDEX hide">
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" autocomplete="off" spellcheck="false" value="" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('ethX.INDEX',4,$i+1)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('ethX.INDEX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -404,7 +404,7 @@ _(IPv6 address)_:
|
||||
<div markdown="1" class="more-gw6-ethX-INDEX hide">
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" autocomplete="off" spellcheck="false" value="" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('ethX.INDEX',6,$i+1)?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" autocomplete="off" spellcheck="false" value="<?=metric('ethX.INDEX')?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *<?=$metric?>*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,8 +26,8 @@ case 'Add Route':
|
||||
if ($gateway && $route) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$gateway}_{$route}_{$metric}_add"));
|
||||
break;
|
||||
default:
|
||||
exec("ip -4 route show table all|grep -Pv '^(127\\.0\\.0\\.0)|table local|unreachable'",$ipv4);
|
||||
exec("ip -6 route show table all|grep -Pv '^([am:]|(f[ef][0-9][0-9])::)|table local|unreachable'",$ipv6);
|
||||
exec("ip -4 route show table all | grep -Pv '^(127\\.0\\.0\\.0)|table local|unreachable|linkdown|broadcast'",$ipv4);
|
||||
exec("ip -6 route show table all | grep -Pv '^([am:]|(f[ef][0-9][0-9])::)|table local|unreachable|linkdown'",$ipv6);
|
||||
foreach ($ipv4 as $info) {
|
||||
$cell = explode(' ',$info);
|
||||
$route = $cell[0];
|
||||
|
||||
@@ -8,9 +8,6 @@ queue(){
|
||||
atq | grep -Pom1 '^\d+'
|
||||
}
|
||||
|
||||
# delayed execution
|
||||
sleep ${1:-1}
|
||||
|
||||
JOB=$(queue)
|
||||
if [[ -n $JOB ]]; then
|
||||
atrm $JOB 2>/dev/null
|
||||
|
||||
@@ -15,6 +15,6 @@ else
|
||||
log "no queued job present"
|
||||
fi
|
||||
|
||||
echo "/usr/local/emhttp/webGui/scripts/reload_services ${1:-1}" | at -M now 2>/dev/null
|
||||
echo "sleep ${1:-1}; /usr/local/emhttp/webGui/scripts/reload_services" | at -M now 2>/dev/null
|
||||
log "queue new job $(queue), wait for ${1:-1}s"
|
||||
exit 0
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# VMs, bare metal, OpenStack clusters, public clouds and more.
|
||||
#
|
||||
# LimeTech - modified for Unraid OS
|
||||
# Bergware - modified for Unraid OS, January 2025
|
||||
# Bergware - modified for Unraid OS, May 2025
|
||||
|
||||
DAEMON="Docker daemon"
|
||||
UNSHARE="/usr/bin/unshare"
|
||||
@@ -35,6 +35,22 @@ TMP=/var/tmp/network.tmp
|
||||
# run & log functions
|
||||
. /etc/rc.d/rc.runlog
|
||||
|
||||
# return interface index
|
||||
index(){
|
||||
cat $SYSTEM/$1/ifindex 2>/dev/null
|
||||
}
|
||||
|
||||
# return active interface
|
||||
active(){
|
||||
if [[ -e $SYSTEM/${1/eth/br} ]]; then
|
||||
echo ${1/eth/br}
|
||||
elif [[ -e $SYSTEM/${1/eth/bond} ]]; then
|
||||
echo ${1/eth/bond}
|
||||
else
|
||||
echo $1
|
||||
fi
|
||||
}
|
||||
|
||||
# wait for interface to go up
|
||||
carrier(){
|
||||
local n e
|
||||
@@ -49,20 +65,13 @@ carrier(){
|
||||
# initialize docker settings
|
||||
docker_read_options(){
|
||||
# determine active port name
|
||||
[[ -e $SYSTEM/bond0 ]] && PORT=bond0 || PORT=eth0
|
||||
[[ -e $SYSTEM/br0 ]] && PORT=br0
|
||||
PORT=$(active eth0)
|
||||
[[ ! $(carrier $PORT) && $(carrier wlan0 1) ]] && PORT=wlan0
|
||||
|
||||
# Set defaults used by the docker daemon
|
||||
if [[ -f $DOCKER_CFG ]]; then
|
||||
for NIC in $NICS; do
|
||||
if [[ ${NIC:0:3} == eth ]]; then
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
fi
|
||||
[[ ${NIC:0:3} == eth ]] && NIC=$(active $NIC)
|
||||
CFG=($(grep -Pom2 "_SUBNET_|_${NIC^^}(_[0-9]+)?=" $DOCKER_CFG))
|
||||
if [[ ${CFG[0]} == _SUBNET_ && -z ${CFG[1]} ]]; then
|
||||
# interface has changed, update configuration
|
||||
@@ -103,7 +112,7 @@ docker_read_options(){
|
||||
[[ -n $MTU && $MTU -ne 1500 ]] && DOCKER_OPTS="--mtu=$MTU $DOCKER_OPTS"
|
||||
|
||||
# Enable IPv6 for docker bridge network
|
||||
if [[ -n $(ip -6 route show default dev $PORT) ]]; then
|
||||
if [[ -n $(ip -6 route show to default dev $PORT) ]]; then
|
||||
DOCKER0='fd17::/64'
|
||||
DOCKER_OPTS="--ipv6 --fixed-cidr-v6=$DOCKER0 $DOCKER_OPTS"
|
||||
IPV6_FORWARD=${IPV6_FORWARD:=accept}
|
||||
@@ -165,6 +174,8 @@ driver(){
|
||||
ATTACH='macvlan'
|
||||
MODE='bridge'
|
||||
fi
|
||||
# wlan0 has forced ipvlan
|
||||
[[ $1 == wlan && $2 == forced ]] && ATTACH=ipvlan
|
||||
}
|
||||
|
||||
# Custom networks
|
||||
@@ -172,6 +183,11 @@ 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
|
||||
@@ -213,9 +229,9 @@ container_add_route(){
|
||||
local NET=${CT[1]#*[}
|
||||
local LAN=${NET%:*}
|
||||
if [[ $PID -gt 0 && "eth0 br0 bond0 wlan0" =~ $LAN ]]; then
|
||||
local THISIP=$(ip -4 -br addr show dev $LAN scope global | awk '{print $3;exit}')
|
||||
local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
|
||||
for CFG in /etc/wireguard/wg*.cfg ; do
|
||||
local NETWORK=$(ip -4 show route dev $LAN $THISIP | awk '{print $1;exit}')
|
||||
local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')
|
||||
[[ -n $NETWORK ]] && nsenter -n -t $PID ip -4 route add $NETWORK via ${THISIP%/*} dev $LAN 2>/dev/null
|
||||
done
|
||||
fi
|
||||
@@ -246,8 +262,7 @@ docker_network_start(){
|
||||
if ! docker_running; then return 1; fi
|
||||
# get container settings for custom networks to reconnect later
|
||||
declare -A NETRESTORE CTRESTORE
|
||||
CONTAINERS=$(docker container ls -a --format='{{.Names}}' | tr '\n' ' ')
|
||||
for CONTAINER in $CONTAINERS; do
|
||||
for CONTAINER in $(docker container ls -a --format='{{.Names}}'); do
|
||||
# the file case (due to fat32) might be different so use find to match
|
||||
XMLFILE=$(find /boot/config/plugins/dockerMan/templates-user -maxdepth 1 -iname my-${CONTAINER}.xml)
|
||||
if [[ -n $XMLFILE ]]; then
|
||||
@@ -255,13 +270,7 @@ docker_network_start(){
|
||||
MAIN=
|
||||
# update custom network reference (if changed)
|
||||
for NIC in $NICS; do
|
||||
if [[ ${NIC:0:3} == eth ]]; then
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
fi
|
||||
[[ ${NIC:0:3} == eth ]] && NIC=$(active $NIC)
|
||||
X=${NIC//[^0-9]/}
|
||||
REF=$(grep -Pom1 "<Network>\K(br|bond|eth|wlan)$X" $XMLFILE)
|
||||
[[ $X == 0 && ! $(carrier $NIC 1) ]] && continue
|
||||
@@ -307,24 +316,18 @@ docker_network_start(){
|
||||
done
|
||||
# detach custom networks
|
||||
for NIC in $NICS; do
|
||||
if [[ ${NIC:0:3} == eth ]]; then
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
fi
|
||||
[[ ${NIC:0:3} == eth ]] && NIC=$(active $NIC)
|
||||
X=${NIC//[^0-9]/}
|
||||
driver ${NIC//[0-9]/}
|
||||
for NETWORK in $(network $DETACH $X); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK &>/dev/null
|
||||
done
|
||||
# get existing custom networks
|
||||
for NETWORK in $(network $ATTACH $X); do
|
||||
if [[ $STOCK =~ ${NETWORK%%[0-9]*} ]]; then
|
||||
[[ $EXCLUDE =~ "$NETWORK " || ! $ACTIVE =~ "$NETWORK " ]] && docker network rm $NETWORK >/dev/null
|
||||
[[ $EXCLUDE =~ "$NETWORK " || ! $ACTIVE =~ "$NETWORK " ]] && docker network rm $NETWORK &>/dev/null
|
||||
else
|
||||
[[ $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
[[ $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK &>/dev/null
|
||||
fi
|
||||
done
|
||||
NETWORKS=$(network $ATTACH $X)
|
||||
@@ -336,27 +339,27 @@ docker_network_start(){
|
||||
AUTO=${NETWORK/./_}
|
||||
AUTO=DOCKER_AUTO_${AUTO^^}
|
||||
if [[ ${!AUTO} == no ]]; then
|
||||
[[ $NETWORKS =~ "$NETWORK " ]] && docker network rm $NETWORK >/dev/null
|
||||
[[ $NETWORKS =~ "$NETWORK " ]] && docker network rm $NETWORK &>/dev/null
|
||||
continue
|
||||
fi
|
||||
# add auto defined networks
|
||||
SUBNET=; GATEWAY=; SERVER=; RANGE=;
|
||||
[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show $NETWORK scope global | awk '{print $3;exit}') || IPV4=
|
||||
[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
|
||||
if [[ -n $IPV4 ]]; then
|
||||
SUBNET=$(ip -4 route show $IPV4 dev $NETWORK | awk '{print $1;exit}')
|
||||
SUBNET=$(ip -4 route show to $IPV4 dev $NETWORK | awk '{print $1;exit}')
|
||||
SERVER=${IPV4%/*}
|
||||
DHCP=${NETWORK/./_}
|
||||
DHCP=DOCKER_DHCP_${DHCP^^}
|
||||
RANGE=${!DHCP}
|
||||
GATEWAY=$(ip -4 route show default dev $NETWORK | awk '{print $3;exit}')
|
||||
GATEWAY=$(ip -4 route show to default dev $NETWORK | awk '{print $3;exit}')
|
||||
fi
|
||||
SUBNET6=; GATEWAY6=; SERVER6=;
|
||||
[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show $NETWORK scope global -temporary -deprecated | awk '{print $3;exit}') || IPV6=
|
||||
# get IPv6 address - ignore any /128 networks
|
||||
[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
|
||||
if [[ -n $IPV6 ]]; then
|
||||
# get IPV6 subnet, preset to /64 if single host address is given
|
||||
[[ ${IPV6#*/} == 128 ]] && SUBNET6=$(echo $IPV6 | sed -r 's/^([^:]+):([^:]+):([^:]+):([^:]+).*$/\1:\2:\3:\4::\/64/') || SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}')
|
||||
SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')
|
||||
SERVER6=${IPV6%/*}
|
||||
GATEWAY6=$(ip -6 route show default dev $NETWORK | awk '{print $3;exit}')
|
||||
GATEWAY6=$(ip -6 route show to default dev $NETWORK | awk '{print $3;exit}')
|
||||
# replace link local address for first address in subnet
|
||||
[[ ${GATEWAY6:0:4} == fe80 ]] && GATEWAY6=${SUBNET6%/*}1
|
||||
fi
|
||||
@@ -378,38 +381,7 @@ docker_network_start(){
|
||||
GATEWAY6=${!GATEWAY6}
|
||||
SERVER6=;
|
||||
fi
|
||||
# custom network already existing and changed?
|
||||
if [[ $NETWORKS =~ "$NETWORK " ]]; then
|
||||
UPDATE=;
|
||||
SUBNETS=($(docker network inspect --format='{{range .IPAM.Config}}{{.Subnet}} {{end}}' $NETWORK 2>/dev/null))
|
||||
RANGES=($(docker network inspect --format='{{range .IPAM.Config}}{{.IPRange}} {{end}}' $NETWORK 2>/dev/null))
|
||||
GATEWAYS=($(docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}} {{end}}' $NETWORK 2>/dev/null))
|
||||
SERVERS=($(docker network inspect --format='{{range .IPAM.Config}}{{range $IPAddr := .AuxiliaryAddresses}}{{$IPAddr}}{{end}} {{end}}' $NETWORK 2>/dev/null))
|
||||
# distribute ipv4 and ipv6 assignments
|
||||
[[ ${SUBNETS[0]} =~ '.' ]] && SUBNET0=${SUBNETS[0]} || SUBNET1=${SUBNETS[0]}
|
||||
[[ -n ${SUBNETS[1]} && ${SUBNETS[1]} =~ '.' ]] && SUBNET0=${SUBNETS[1]} || SUBNET1=${SUBNETS[1]}
|
||||
[[ ${RANGES[0]} =~ '.' ]] && RANGE0=${RANGES[0]} || RANGE1=${RANGES[0]}
|
||||
[[ -n ${RANGES[1]} && ${RANGES[1]} =~ '.' ]] && RANGE0=${RANGES[1]} || RANGE1=${RANGES[1]}
|
||||
[[ ${GATEWAYS[0]} =~ '.' ]] && GATEWAY0=${GATEWAYS[0]} || GATEWAY1=${GATEWAYS[0]}
|
||||
[[ -n ${GATEWAYS[1]} && ${GATEWAYS[1]} =~ '.' ]] && GATEWAY0=${GATEWAYS[1]} || GATEWAY1=${GATEWAYS[1]}
|
||||
[[ ${SERVERS[0]} =~ '.' ]] && SERVER0=${SERVERS[0]} || SERVER1=${SERVERS[0]}
|
||||
[[ -n ${SERVERS[1]} && ${SERVERS[1]} =~ '.' ]] && SERVER0=${SERVERS[1]} || SERVER1=${SERVERS[1]}
|
||||
# check for changes
|
||||
[[ $SUBNET != $SUBNET0 || $SUBNET6 != $SUBNET1 ]] && UPDATE=1
|
||||
[[ $RANGE != $RANGE0 ]] && UPDATE=1
|
||||
[[ (-n $GATEWAY && $GATEWAY != $GATEWAY0) || (-n $GATEWAY6 && $GATEWAY6 != $GATEWAY1) ]] && UPDATE=1
|
||||
[[ (-n $SERVER && $SERVER != $SERVER0) || (-n $SERVER6 && $SERVER6 != $SERVER1) ]] && UPDATE=1
|
||||
if [[ -z $UPDATE ]]; then
|
||||
# no changes, ignore
|
||||
SUBNET=; SUBNET6=;
|
||||
else
|
||||
# changed, remove first
|
||||
docker network rm $NETWORK >/dev/null
|
||||
fi
|
||||
fi
|
||||
# set parameters for custom network creation
|
||||
N4=$SUBNET; R4=$RANGE;
|
||||
N6=$SUBNET6;
|
||||
[[ -n $SUBNET && -n $GATEWAY ]] && GATEWAY="--gateway=$GATEWAY" || GATEWAY=;
|
||||
[[ -n $SUBNET && -n $SERVER ]] && SERVER="--aux-address=server=$SERVER" || SERVER=;
|
||||
[[ -n $SUBNET && -n $RANGE ]] && RANGE="--ip-range=$RANGE" || RANGE=;
|
||||
@@ -419,15 +391,15 @@ docker_network_start(){
|
||||
[[ -n $SUBNET6 ]] && SUBNET6="--ipv6 --subnet=$SUBNET6"
|
||||
if [[ -n $SUBNET || -n $SUBNET6 ]]; then
|
||||
TYPE=${NETWORK//[0-9.]/}
|
||||
driver $TYPE
|
||||
if [[ $TYPE == br ]]; then
|
||||
driver $TYPE forced
|
||||
if [[ $TYPE == br || $TYPE == wlan ]]; then
|
||||
VHOST=$NETWORK
|
||||
elif [[ $TYPE == wlan ]]; then
|
||||
VHOST=$NETWORK
|
||||
ATTACH=ipvlan
|
||||
else
|
||||
[[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]] && VHOST=vhost${NETWORK//[^0-9.]/} || VHOST=$NETWORK
|
||||
[[ -n $IPV4 && $DOCKER_ALLOW_ACCESS == yes ]] && VHOST=vhost${NETWORK//[^0-9.]/} || VHOST=$NETWORK
|
||||
fi
|
||||
# delete and recreate unconditionally
|
||||
log "Processing... $NETWORK"
|
||||
docker network rm $NETWORK &>/dev/null
|
||||
docker network create -d $ATTACH $SUBNET $GATEWAY $SERVER $RANGE $SUBNET6 $GATEWAY6 $SERVER6 -o parent=$VHOST $NETWORK | xargs docker network inspect -f "created network $ATTACH {{.Name}} with subnets: {{range .IPAM.Config}}{{.Subnet}}; {{end}}" 2>/dev/null | log
|
||||
# connect containers to this new network
|
||||
for CONNECT in ${NETRESTORE[$NETWORK]}; do
|
||||
@@ -448,57 +420,50 @@ docker_network_start(){
|
||||
# hack to let containers talk to host
|
||||
if [[ $TYPE == br ]]; then
|
||||
LINK=shim-$NETWORK
|
||||
GW=($(ip -4 route show default dev $NETWORK | awk '{print $3,$5;exit}'))
|
||||
if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
|
||||
# create shim interface and copy parent IPv4 address to shim interface
|
||||
IPV4="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
|
||||
# create shim interface
|
||||
[[ -e $SYSTEM/$LINK ]] || run ip link add link $NETWORK name $LINK type $ATTACH mode $MODE
|
||||
run ip addr flush dev $LINK scope global
|
||||
run ip -4 addr add $IPV4 dev $LINK metric 0
|
||||
# disable IPv6 on shim interface
|
||||
echo 1 >$CONF6/$LINK/disable_ipv6
|
||||
run ip -6 addr flush dev $LINK
|
||||
# copy parent IPv4 address to shim interface
|
||||
run ip addr add $IPV4 dev $LINK
|
||||
run ip link set $LINK up
|
||||
if [[ -n $GW ]]; then
|
||||
if [[ -z ${GW[1]} ]]; then
|
||||
METRIC=1
|
||||
METRICS=$(ip -4 route show default | grep -Po 'metric \K\d+')
|
||||
while [[ " $METRICS " =~ " $METRIC " ]]; do ((METRIC++)); done
|
||||
# update existing route to avoid conflict with shim route
|
||||
run ip -4 route del default via $GW dev $NETWORK
|
||||
run ip -4 route add default via $GW dev $NETWORK metric $METRIC
|
||||
fi
|
||||
run ip -4 route add default via $GW dev $LINK metric 0
|
||||
fi
|
||||
log "created network $LINK for host access"
|
||||
elif [[ -e $SYSTEM/$LINK ]]; then
|
||||
# remove shim interface
|
||||
[[ -n $GW ]] && ip -4 route del default via $GW dev $LINK
|
||||
run ip addr flush dev $LINK
|
||||
run ip link set $LINK down
|
||||
run ip link del $LINK
|
||||
fi
|
||||
elif [[ $TYPE != wlan ]]; then
|
||||
if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
|
||||
run ip addr flush dev $VHOST scope global
|
||||
# copy IPv4 address to vhost interface
|
||||
run ip -4 addr add $IPV4 dev $VHOST metric 0
|
||||
log "prepared network $VHOST for host access"
|
||||
else
|
||||
if [[ $TYPE == wlan ]]; then
|
||||
VHOST=shim-$NETWORK
|
||||
INDEX=3000
|
||||
else
|
||||
VHOST=vhost${NETWORK//[^0-9.]/}
|
||||
if [[ -e $SYSTEM/$VHOST ]]; then
|
||||
# remove IP addresses of vhost
|
||||
run ip addr flush dev $VHOST scope global
|
||||
# remove routing of vhost
|
||||
run ip -4 route flush dev $VHOST
|
||||
run ip -6 route flush dev $VHOST
|
||||
fi
|
||||
INDEX=1000
|
||||
fi
|
||||
INDEX=$(($INDEX - 1 + $(index $NETWORK)))
|
||||
if [[ -n $IPV4 && $DOCKER_ALLOW_ACCESS == yes ]]; then
|
||||
# disable IPv6 on vhost interface
|
||||
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 metric $INDEX dev $VHOST
|
||||
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 metric $INDEX dev $VHOST
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# create IPv6 forward accept rule
|
||||
if [[ $IPV6_FORWARD == accept ]]; then
|
||||
log "creating forward accept rule for IPv6 network"
|
||||
ip6tables -P FORWARD ACCEPT
|
||||
log "created forward accept rule for IPv6 network"
|
||||
fi
|
||||
log "Network started."
|
||||
}
|
||||
@@ -506,33 +471,31 @@ docker_network_start(){
|
||||
docker_network_stop(){
|
||||
log "Stopping network..."
|
||||
if ! docker_running; then return 1; fi
|
||||
# Read docker configuration file
|
||||
[[ -f $DOCKER_CFG ]] && . $DOCKER_CFG
|
||||
for NIC in $NICS; do
|
||||
if [[ ${NIC:0:3} == eth ]]; then
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
fi
|
||||
driver ${NIC//[0-9]/}
|
||||
[[ ${NIC:0:3} == eth ]] && NIC=$(active $NIC)
|
||||
driver ${NIC//[0-9]/} forced
|
||||
for NETWORK in $(network $ATTACH ${NIC//[^0-9]/}); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
[[ $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
|
||||
GW=$(ip -4 route show default dev $LINK | awk '{print $3;exit}')
|
||||
[[ -n $GW ]] && run ip -4 route del default via $GW dev $LINK
|
||||
run ip addr flush dev $LINK
|
||||
run ip link set $LINK down
|
||||
run ip link del $LINK
|
||||
fi
|
||||
else
|
||||
elif [[ $TYPE != wlan ]]; then
|
||||
VHOST=vhost${NETWORK//[^0-9.]/}
|
||||
[[ -e $SYSTEM/$VHOST ]] && run ip addr flush dev $VHOST
|
||||
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."
|
||||
}
|
||||
|
||||
@@ -549,7 +512,7 @@ docker_container_start(){
|
||||
if [[ $OUT =~ "Error:" ]]; then
|
||||
log "$CONTAINER: $OUT" &
|
||||
else
|
||||
run container_add_route $CONTAINER
|
||||
container_add_route $CONTAINER
|
||||
log "$CONTAINER: started successfully!" &
|
||||
if [[ $WAIT -gt 0 ]]; then
|
||||
log "$CONTAINER: wait $WAIT seconds" &
|
||||
@@ -650,7 +613,6 @@ case "$1" in
|
||||
docker_service_start
|
||||
docker_network_start
|
||||
docker_container_start &>/dev/null &
|
||||
disown
|
||||
;;
|
||||
'stop')
|
||||
docker_container_stop
|
||||
@@ -670,7 +632,6 @@ case "$1" in
|
||||
docker_service_start
|
||||
docker_network_start
|
||||
docker_container_start &>/dev/null &
|
||||
disown
|
||||
;;
|
||||
'status')
|
||||
docker_status
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# @(#)/etc/rc.d/rc.inet1 10.2 Sun Jul 24 12:45:56 PDT 2005 (pjv)
|
||||
|
||||
# LimeTech - modified for Unraid OS
|
||||
# Bergware - modified for Unraid OS, February 2025
|
||||
# Bergware - modified for Unraid OS, May 2025
|
||||
|
||||
# Adapted by Bergware for use in Unraid OS - April 2016
|
||||
# - improved interface configuration
|
||||
@@ -81,6 +81,9 @@
|
||||
# - added metric value to interface IP assignment
|
||||
# - fixed DNS entries get removed when configuring interface other then eth0
|
||||
|
||||
# Adapted by Bergware for use in Unraid OS - May 2025
|
||||
# - improved metric value to interface IP assignment
|
||||
|
||||
###########
|
||||
# LOGGING #
|
||||
###########
|
||||
@@ -122,22 +125,18 @@ done
|
||||
# LOOPBACK FUNCTIONS #
|
||||
######################
|
||||
|
||||
# function to bring up loopback interface
|
||||
# bring up loopback interface
|
||||
lo_up(){
|
||||
if [[ -e $SYSTEM/lo ]]; then
|
||||
if ! ip -4 addr show lo | grep -qw 'inet'; then
|
||||
run ip -4 addr add 127.0.0.1/8 dev lo
|
||||
fi
|
||||
if ! ip -6 addr show lo | grep -qw 'inet6'; then
|
||||
run ip -6 addr add ::1/128 dev lo
|
||||
fi
|
||||
[[ -z $(ip -4 -br addr show lo | awk '{print $3;exit}') ]] && run ip -4 addr add 127.0.0.1/8 dev lo
|
||||
[[ -z $(ip -6 -br addr show lo | awk '{print $3;exit}') ]] && run ip -6 addr add ::1/128 dev lo
|
||||
run ip link set lo up
|
||||
else
|
||||
[[ $DEBUG_ETH_UP == yes ]] && log "interface lo not present, can't bring up"
|
||||
fi
|
||||
}
|
||||
|
||||
# function to take down loopback interface
|
||||
# take down loopback interface
|
||||
lo_down(){
|
||||
if [[ -e $SYSTEM/lo ]]; then
|
||||
run ip link set lo down
|
||||
@@ -150,12 +149,17 @@ lo_down(){
|
||||
# INTERFACE FUNCTIONS #
|
||||
#######################
|
||||
|
||||
# function to get link mtu size
|
||||
# return interface index
|
||||
index(){
|
||||
cat $SYSTEM/$1/ifindex 2>/dev/null
|
||||
}
|
||||
|
||||
# get link mtu size
|
||||
get_mtu(){
|
||||
ip link show $1 | grep -Po 'mtu \K\d+'
|
||||
}
|
||||
|
||||
# function to set/reset link mtu size
|
||||
# set/reset link mtu size
|
||||
set_mtu(){
|
||||
if [[ -n ${MTU[$i]} ]]; then
|
||||
# set MTU to specified value
|
||||
@@ -166,8 +170,8 @@ set_mtu(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to wait for carrier of interface
|
||||
carrier_up(){
|
||||
# wait for carrier of interface
|
||||
carrier(){
|
||||
local n
|
||||
for n in {1..10}; do
|
||||
[[ $(cat $SYSTEM/$1/carrier 2>/dev/null) == 1 ]] && return 0 || sleep 1
|
||||
@@ -175,7 +179,7 @@ carrier_up(){
|
||||
return 1
|
||||
}
|
||||
|
||||
# function to create bond interface
|
||||
# create bond interface
|
||||
bond_up(){
|
||||
[[ -d /proc/net/bonding ]] || modprobe bonding mode=${BONDING_MODE[$i]} miimon=${BONDING_MIIMON[$i]}
|
||||
run ip link add name ${BONDNAME[$i]} type bond mode ${BONDING_MODE[$i]} miimon ${BONDING_MIIMON[$i]}
|
||||
@@ -194,7 +198,7 @@ bond_up(){
|
||||
[[ -n $PRIMARY ]] && run ip link set name ${BONDNAME[$i]} type bond primary $PRIMARY
|
||||
}
|
||||
|
||||
# function to delete bond interface
|
||||
# delete bond interface
|
||||
bond_down(){
|
||||
if [[ -e $SYSTEM/${BONDNAME[$i]} ]]; then
|
||||
# loop thru attached interfaces in bond
|
||||
@@ -208,7 +212,7 @@ bond_down(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to create bridge interface
|
||||
# create bridge interface
|
||||
br_up(){
|
||||
for ((j=0;j<${VLANS[$i]:-1};j++)); do
|
||||
[[ $j -eq 0 ]] && BRIDGE=${BRNAME[$i]} || BRIDGE=${BRNAME[$i]}.${VLANID[$i,$j]}
|
||||
@@ -235,7 +239,7 @@ br_up(){
|
||||
done
|
||||
}
|
||||
|
||||
# function to delete bridge interface
|
||||
# delete bridge interface
|
||||
br_down(){
|
||||
for ((j=0;j<${VLANS[$i]:-1};j++)); do
|
||||
# loop thru main bridge and bridge VLAN interfaces
|
||||
@@ -253,7 +257,7 @@ br_down(){
|
||||
done
|
||||
}
|
||||
|
||||
# function to create VLAN interfaces
|
||||
# create VLAN interfaces
|
||||
vlan_up(){
|
||||
for PORT in ${BRNICS[$i]:-${IFNAME[$i]}}; do
|
||||
for ((j=1;j<${VLANS[$i]};j++)); do
|
||||
@@ -265,7 +269,7 @@ vlan_up(){
|
||||
done
|
||||
}
|
||||
|
||||
# function to delete VLAN interfaces
|
||||
# delete VLAN interfaces
|
||||
vlan_down(){
|
||||
for PORT in ${BRNICS[$i]:-${IFNAME[$i]}}; do
|
||||
for VLAN in $(ls --indicator-style=none $SYSTEM | grep -Po "$PORT\.\d+"); do
|
||||
@@ -275,7 +279,7 @@ vlan_down(){
|
||||
done
|
||||
}
|
||||
|
||||
# function to create macvtap interfaces
|
||||
# create macvtap interfaces
|
||||
macvtap_up(){
|
||||
PARENT=${IFNAME[$i]}
|
||||
[[ -n ${BONDNICS[$i]} ]] && PARENT=${BONDNAME[$i]}
|
||||
@@ -283,16 +287,18 @@ macvtap_up(){
|
||||
MAC=$(echo $(hostname)-$VTAP | md5sum | sed -r 's/^(..)(..)(..)(..)(..).*$/02:\1:\2:\3:\4:\5/')
|
||||
run ip link add link $PARENT name $VTAP address $MAC type macvtap mode bridge
|
||||
set_mtu $VTAP
|
||||
echo 1 >$CONF6/$VTAP/disable_ipv6
|
||||
run ip link set $VTAP up
|
||||
for ((j=1;j<${VLANS[$i]:-0};j++)); do
|
||||
VLAN=${VLANID[$i,$j]}
|
||||
run ip link add link $PARENT.$VLAN name $VTAP.$VLAN address $MAC type macvtap mode bridge
|
||||
set_mtu $VTAP.$VLAN
|
||||
echo 1 >$CONF6/$VTAP.$VLAN/disable_ipv6
|
||||
run ip link set $VTAP.$VLAN up
|
||||
done
|
||||
}
|
||||
|
||||
# function to delete macvtap interfaces
|
||||
# delete macvtap interfaces
|
||||
macvtap_down(){
|
||||
PARENT=${IFNAME[$i]}
|
||||
[[ -n ${BONDNICS[$i]} ]] && PARENT=${BONDNAME[$i]}
|
||||
@@ -308,26 +314,26 @@ macvtap_down(){
|
||||
run ip link del $VTAP
|
||||
}
|
||||
|
||||
# function to enable/disable ipv6 protocol per interface
|
||||
# enable/disable ipv6 protocol per interface
|
||||
ipv6_up(){
|
||||
[[ -d $CONF6/${IFACE/$1/$2} ]] && echo $4 >$CONF6/${IFACE/$1/$2}/disable_ipv6
|
||||
[[ -d $CONF6/${IFACE/$1/$3} ]] && echo $4 >$CONF6/${IFACE/$1/$3}/disable_ipv6
|
||||
}
|
||||
|
||||
# function to enable/disable ipv6 assignment per interface
|
||||
# enable/disable ipv6 assignment per interface
|
||||
ipv6_ra(){
|
||||
echo $2 >$CONF6/$1/accept_ra
|
||||
echo $2 >$CONF6/$1/accept_ra_defrtr
|
||||
echo $3 >$CONF6/$1/autoconf
|
||||
}
|
||||
|
||||
# function to enable/disable ipv6 assignment per interface
|
||||
# enable/disable ipv6 assignment per interface
|
||||
ipv6_conf(){
|
||||
[[ -d $CONF6/${IFACE/$1/$2} ]] && ipv6_ra ${IFACE/$1/$2} $4 $5
|
||||
[[ -d $CONF6/${IFACE/$1/$3} ]] && ipv6_ra ${IFACE/$1/$3} $4 $5
|
||||
}
|
||||
|
||||
# function to enable/disable ipv6 assignment per interface
|
||||
# enable/disable ipv6 assignment per interface
|
||||
ipv6_addr(){
|
||||
[[ -d $CONF6/$IFACE ]] && ipv6_ra $IFACE $1 $2
|
||||
[[ -d $CONF6/$VHOST ]] && ipv6_ra $VHOST $1 $2
|
||||
@@ -342,7 +348,7 @@ ipv6_addr(){
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# function to assign IP address
|
||||
# assign IP address
|
||||
ipaddr_up(){
|
||||
if [[ -z $RENEW ]]; then
|
||||
# disable IPv6 per interface when IPv4 only
|
||||
@@ -371,7 +377,7 @@ ipaddr_up(){
|
||||
[[ $IP == ipv4 ]] && DHCP_OPTIONS="$DHCP_OPTIONS -4"
|
||||
[[ $IP == ipv6 ]] && DHCP_OPTIONS="$DHCP_OPTIONS -6"
|
||||
[[ $IP != ipv4 && -n $PRIV6 && -d $CONF6/$IFACE ]] && echo $PRIV6 >$CONF6/$IFACE/use_tempaddr
|
||||
if carrier_up $IFACE; then
|
||||
if carrier $IFACE; then
|
||||
# interface is UP
|
||||
log "interface $IFACE is UP, polling up to 60 sec for DHCP $IP server"
|
||||
if ! run timeout 60 dhcpcd -w $DHCP_OPTIONS $IFACE; then
|
||||
@@ -385,21 +391,23 @@ ipaddr_up(){
|
||||
fi
|
||||
elif [[ $DHCP == no ]]; then
|
||||
# bring up interface using static IP address
|
||||
if carrier_up $IFACE; then STATE="UP"; else STATE="DOWN"; fi
|
||||
if carrier $IFACE; then STATE="UP"; else STATE="DOWN"; fi
|
||||
log "interface $IFACE is $STATE, setting static $IP address"
|
||||
ipv6_addr 0 1
|
||||
INDEX=$(index $IFACE)
|
||||
INDEX=$((1000 + ${INDEX:-$(($(index * | sort -n | tail -1) + 1))}))
|
||||
if [[ $IP != ipv6 ]]; then
|
||||
[[ $j -eq 0 ]] && ADDR=${IPADDR[$i]} || ADDR=${IPADDR[$i,$j]}
|
||||
if [[ -n $ADDR ]]; then
|
||||
[[ $j -eq 0 ]] && MASK=${NETMASK[$i]} || MASK=${NETMASK[$i,$j]}
|
||||
[[ -n $MASK ]] && run ip -4 addr add $(unzero $ADDR)/$MASK dev $IFACE metric ${DHCP_METRIC:-1}
|
||||
[[ -n $MASK ]] && run ip -4 addr add $(unzero $ADDR)/$MASK metric $INDEX dev $IFACE
|
||||
fi
|
||||
fi
|
||||
if [[ $IP != ipv4 ]]; then
|
||||
[[ $j -eq 0 ]] && ADDR6=${IPADDR6[$i]} || ADDR6=${IPADDR6[$i,$j]}
|
||||
if [[ -n $ADDR6 ]]; then
|
||||
[[ $j -eq 0 ]] && MASK6=${NETMASK6[$i]} || MASK6=${NETMASK6[$i,$j]}
|
||||
[[ -n $MASK6 ]] && run ip -6 addr add $(unzero6 $ADDR6)/$MASK6 dev $IFACE metric ${DHCP_METRIC:-1}
|
||||
[[ -n $MASK6 ]] && run ip -6 addr add $(unzero6 $ADDR6)/$MASK6 metric $INDEX dev $IFACE
|
||||
[[ -n $PRIV6 && -d $CONF6/$IFACE ]] && echo 0 >$CONF6/$IFACE/use_tempaddr
|
||||
fi
|
||||
fi
|
||||
@@ -410,7 +418,7 @@ ipaddr_up(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to release IP addresses and routes
|
||||
# release IP addresses and routes
|
||||
ipaddr_conf(){
|
||||
if [[ -e $SYSTEM/${IFACE/$1/$2} ]]; then
|
||||
run ip -$4 addr flush dev ${IFACE/$1/$2}
|
||||
@@ -422,7 +430,7 @@ ipaddr_conf(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to release IP addresses and routes
|
||||
# release IP addresses and routes
|
||||
ipaddr_flush(){
|
||||
run ip -$1 addr flush dev $IFACE
|
||||
run ip -$1 route flush dev $IFACE
|
||||
@@ -436,7 +444,7 @@ ipaddr_flush(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to release IP addresses and routes
|
||||
# release IP addresses and routes
|
||||
ipaddr_down(){
|
||||
if [[ $DHCP == yes ]]; then
|
||||
DHCP_OPTIONS="-q -k"
|
||||
@@ -453,7 +461,7 @@ ipaddr_down(){
|
||||
fi
|
||||
}
|
||||
|
||||
# function to bring up network interface
|
||||
# bring up network interface
|
||||
if_up(){
|
||||
# set index of INTERFACE in array
|
||||
i=0
|
||||
@@ -555,7 +563,7 @@ if_up(){
|
||||
done
|
||||
}
|
||||
|
||||
# function to take down network interface
|
||||
# take down network interface
|
||||
if_down(){
|
||||
# set index of INTERFACE in array
|
||||
i=0
|
||||
@@ -612,7 +620,7 @@ if_down(){
|
||||
# GATEWAY FUNCTIONS #
|
||||
#####################
|
||||
|
||||
# function to add default gateway per interface
|
||||
# add default gateway per interface
|
||||
gateway_up(){
|
||||
for GW in ${GATEWAY[@]}; do
|
||||
[[ -z $GW ]] && continue
|
||||
@@ -623,7 +631,7 @@ gateway_up(){
|
||||
IP=${PROTOCOL[$x]:-ipv4}
|
||||
AD=${METRIC[$x]}
|
||||
[[ -n $AD ]] && AD="metric $AD"
|
||||
EXIST=$(ip -4 route show default via $(unzero $GW) dev $DEV | grep "$AD ")
|
||||
EXIST=$(ip -4 route show to default via $(unzero $GW) dev $DEV | grep "$AD ")
|
||||
[[ $IP != ipv6 && -z $EXIST ]] && run ip -4 route add default via $(unzero $GW) dev $DEV $AD
|
||||
done
|
||||
for GW6 in ${GATEWAY6[@]}; do
|
||||
@@ -635,12 +643,12 @@ gateway_up(){
|
||||
IP=${PROTOCOL[$x]:-ipv4}
|
||||
AD6=${METRIC6[$x]}
|
||||
[[ -n $AD6 ]] && AD6="metric $AD6"
|
||||
EXIST=$(ip -6 route show default via $(unzero6 $GW6) dev $DEV | grep "$AD6 ")
|
||||
EXIST=$(ip -6 route show to default via $(unzero6 $GW6) dev $DEV | grep "$AD6 ")
|
||||
[[ $IP != ipv4 && -z $EXIST ]] && run ip -6 route add default via $(unzero6 $GW6) dev $DEV $AD6
|
||||
done
|
||||
}
|
||||
|
||||
# function to delete default gateway per interface
|
||||
# delete default gateway per interface
|
||||
gateway_down(){
|
||||
for GW in ${GATEWAY[@]}; do
|
||||
[[ -z $GW ]] && continue
|
||||
@@ -649,7 +657,7 @@ gateway_down(){
|
||||
i=(${x/,/ })
|
||||
[[ -z ${i[1]} ]] && DEV=${IFNAME[$i]} || DEV=${IFNAME[$i]}.${VLANID[$x]}
|
||||
IP=${PROTOCOL[$x]:-ipv4}
|
||||
EXIST=$(ip -4 route show default dev $DEV)
|
||||
EXIST=$(ip -4 route show to default dev $DEV)
|
||||
[[ $IP != ipv6 && -n $EXIST ]] && run ip -4 route flush default dev $DEV
|
||||
done
|
||||
for GW6 in ${GATEWAY6[@]}; do
|
||||
@@ -659,12 +667,12 @@ gateway_down(){
|
||||
i=(${x/,/ })
|
||||
[[ -z ${i[1]} ]] && DEV=${IFNAME[$i]} || DEV=${IFNAME[$i]}.${VLANID[$x]}
|
||||
IP=${PROTOCOL[$x]:-ipv4}
|
||||
EXIST=$(ip -6 route show default dev $DEV)
|
||||
EXIST=$(ip -6 route show to default dev $DEV)
|
||||
[[ $IP != ipv4 && -n $EXIST ]] && run ip -6 route flush default dev $DEV
|
||||
done
|
||||
}
|
||||
|
||||
# function to start network
|
||||
# start network
|
||||
start(){
|
||||
lo_up
|
||||
for INTERFACE in ${IFNAME[@]}; do
|
||||
@@ -673,7 +681,7 @@ start(){
|
||||
gateway_up
|
||||
}
|
||||
|
||||
# function to stop network
|
||||
# stop network
|
||||
stop(){
|
||||
gateway_down
|
||||
for INTERFACE in ${IFNAME[@]}; do
|
||||
@@ -682,7 +690,7 @@ stop(){
|
||||
lo_down
|
||||
}
|
||||
|
||||
# function to show network status
|
||||
# show network status
|
||||
status(){
|
||||
echo "INTERFACE STATE INFORMATION"
|
||||
echo "========================================================================"
|
||||
@@ -693,38 +701,38 @@ status(){
|
||||
# STATIC ROUTE FUNCTIONS #
|
||||
##########################
|
||||
|
||||
# function to add static route
|
||||
# add static route
|
||||
route_up(){
|
||||
[[ -n $3 ]] && METRIC="metric $3" || METRIC=
|
||||
if [[ $2 == default ]]; then
|
||||
# determine IP protocol & optional device
|
||||
[[ -n ${1##*:*} ]] && IP=-4 || IP=-6
|
||||
[[ -z ${1##*-*} ]] && DEV="dev ${1#*-}" || DEV=
|
||||
EXIST=$(ip $IP route show default via ${1%-*} $DEV | grep "$METRIC ")
|
||||
EXIST=$(ip $IP route show to default via ${1%-*} $DEV | grep "$METRIC ")
|
||||
[[ -z $EXIST ]] && run ip $IP route add default via ${1%-*} $DEV $METRIC
|
||||
elif [[ -n $2 ]]; then
|
||||
# determine IP protocol & gateway syntax
|
||||
[[ -n ${2##*:*} ]] && IP=-4 || IP=-6
|
||||
[[ -e $SYSTEM/$1 ]] && GW="dev $1" || GW="via $1"
|
||||
EXIST=$(ip $IP route show $2 $GW | grep "$METRIC ")
|
||||
EXIST=$(ip $IP route show to $2 $GW | grep "$METRIC ")
|
||||
[[ -z $EXIST ]] && run ip $IP route add $2 $GW $METRIC
|
||||
fi
|
||||
}
|
||||
|
||||
# function to delete static route
|
||||
# delete static route
|
||||
route_down(){
|
||||
[[ -n $3 ]] && METRIC="metric $3" || METRIC=
|
||||
if [[ $2 == default ]]; then
|
||||
# determine IP protocol & optional device
|
||||
[[ -n ${1##*:*} ]] && IP=-4 || IP=-6
|
||||
[[ -z ${1##*-*} ]] && DEV="dev ${1#*-}" || DEV=
|
||||
EXIST=$(ip $IP route show default via ${1%-*} $DEV)
|
||||
EXIST=$(ip $IP route show to default via ${1%-*} $DEV)
|
||||
[[ -n $EXIST ]] && run ip $IP route del default via ${1%-*} $DEV $METRIC
|
||||
elif [[ -n $2 ]]; then
|
||||
# determine IP protocol & gateway syntax
|
||||
[[ -n ${2##*:*} ]] && IP=-4 || IP=-6
|
||||
[[ -e $SYSTEM/$1 ]] && GW="dev $1" || GW="via $1"
|
||||
EXIST=$(ip $IP route show $2 $GW)
|
||||
EXIST=$(ip $IP route show to $2 $GW)
|
||||
[[ -n $EXIST ]] && run ip $IP route del $2 $GW $METRIC
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Library used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces
|
||||
#
|
||||
# Bergware - created for Unraid OS, December 2023
|
||||
# Bergware - updated January 2025
|
||||
# Bergware - updated May 2025
|
||||
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
@@ -56,8 +56,8 @@ good(){
|
||||
|
||||
show(){
|
||||
case $# in
|
||||
1) ip -br addr show scope global -temporary -deprecated to $1 2>/dev/null | awk '{gsub("@.+","",$1);print $1;exit}' ;;
|
||||
2) ip -br addr show scope global -temporary -deprecated $1 $2 2>/dev/null | awk '{$1=$2="";print;exit}' | sed -r 's/ metric [0-9]+//g' ;;
|
||||
1) ip -br addr show scope global primary -deprecated to $1 2>/dev/null | awk '{gsub("@.+","",$1);print $1;exit}' ;;
|
||||
2) ip -br addr show scope global primary -deprecated $1 $2 2>/dev/null | awk '{$1=$2="";print;exit}' | sed -r 's/ metric [0-9]+//g' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ check(){
|
||||
fi
|
||||
[[ $(ipv $ADDR) == 4 ]] && IPV4=yes || IPV6=yes
|
||||
done
|
||||
done <<< $(ip -br addr show scope global -temporary -deprecated | awk '$1~"^(br|bond|eth|wlan|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort)
|
||||
done <<< $(ip -br addr show scope global primary -deprecated | awk '$1~"^(br|bond|eth|wlan|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort)
|
||||
# add loopback interface
|
||||
if [[ "smb nfs" =~ "$CALLER" ]]; then
|
||||
[[ $IPV4 == yes ]] && BIND+=(127.0.0.1)
|
||||
|
||||
@@ -80,9 +80,14 @@ fi
|
||||
/usr/local/emhttp/webGui/scripts/notify smtp-init
|
||||
/usr/local/emhttp/webGui/scripts/notify cron-init
|
||||
|
||||
# start interface state monitoring
|
||||
if [[ -x /usr/local/sbin/monitor_interface ]]; then
|
||||
/usr/local/sbin/monitor_interface &>/dev/null
|
||||
fi
|
||||
|
||||
# start nchan monitoring -> stop all running nchan processes when no subscribers are connected
|
||||
if [[ -x /usr/local/sbin/monitor_nchan ]]; then
|
||||
/usr/local/sbin/monitor_nchan
|
||||
/usr/local/sbin/monitor_nchan &>/dev/null
|
||||
fi
|
||||
|
||||
# First boot following Unraid Server OS update: delete plugin file
|
||||
@@ -184,7 +189,7 @@ else
|
||||
if [[ -f "$PRIORITY_PLUGIN_PATH" ]]; then
|
||||
/usr/local/sbin/plugin install "$PRIORITY_PLUGIN_PATH" | log
|
||||
fi
|
||||
done
|
||||
done
|
||||
# Install remaining plugins
|
||||
shopt -s nullglob
|
||||
for PLUGIN in $CONFIG/plugins/*.plg; do
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Written for Slackware Linux by Cherife Li <cherife-#-dotimes.com>.
|
||||
|
||||
# LimeTech - modified for Unraid OS
|
||||
# Bergware - modified for Unraid OS, October 2023
|
||||
# Bergware - modified for Unraid OS, May 2025
|
||||
|
||||
# reference:
|
||||
# LANNAME 'tower'
|
||||
@@ -537,12 +537,12 @@ build_ssl(){
|
||||
# fetch LAN IP address (read management interface eth0)
|
||||
[[ -e $SYSTEM/bond0 ]] && DEV=bond0 || DEV=eth0
|
||||
[[ -e $SYSTEM/br0 ]] && DEV=br0
|
||||
LANIP=$(ip -4 -br addr show $DEV scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}')
|
||||
LANIP6=$(ip -6 -br addr show $DEV scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}')
|
||||
LANIP=$(ip -4 -br addr show scope global primary dev $DEV | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
LANIP6=$(ip -6 -br addr show scope global primary -deprecated dev $DEV | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
|
||||
# try wireless connection if no IP address on interface eth0
|
||||
[[ -z $LANIP && -e $SYSTEM/wlan0 ]] && LANIP=$(ip -4 -br addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}')
|
||||
[[ -z $LANIP6 && -e $SYSTEM/wlan0 ]] && LANIP6=$(ip -6 -br addr show wlan0 scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}')
|
||||
[[ -z $LANIP && -e $SYSTEM/wlan0 ]] && LANIP=$(ip -4 -br addr show scope global primary dev wlan0 | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
[[ -z $LANIP6 && -e $SYSTEM/wlan0 ]] && LANIP6=$(ip -6 -br addr show scope global primary -deprecated dev wlan0 | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
|
||||
# regenerate self-signed cert if local TLD changes */
|
||||
SELFCERTPATH=$SSL/certs/${LANNAME}_unraid_bundle.pem
|
||||
@@ -716,7 +716,7 @@ nginx_start(){
|
||||
# side-load unraid-api
|
||||
unraid_api_control start
|
||||
# resume nchan publishers
|
||||
/usr/local/sbin/monitor_nchan start
|
||||
/usr/local/sbin/monitor_nchan start
|
||||
rm -f /tmp/publishPaused
|
||||
|
||||
if nginx_running; then REPLY="Started"; else REPLY="Failed"; fi
|
||||
|
||||
@@ -10,8 +10,10 @@ DAEMON="WiFi network"
|
||||
CALLER="wifi"
|
||||
INI="/var/local/emhttp/wireless.ini"
|
||||
CFG="/boot/config/wireless.cfg"
|
||||
DOCKER="/boot/config/docker.cfg"
|
||||
OPENSSL="/usr/local/emhttp/webGui/scripts/open_ssl"
|
||||
STARTWIFI="/usr/local/emhttp/webGui/scripts/wireless"
|
||||
SERVICES="/usr/local/emhttp/webGui/scripts/update_services"
|
||||
WPA="/etc/wpa_supplicant.conf"
|
||||
|
||||
# system network references
|
||||
@@ -28,6 +30,16 @@ CONF6="/proc/sys/net/ipv6/conf"
|
||||
[[ -r $INI ]] && . $INI
|
||||
PORT=${PORT:-wlan0}
|
||||
|
||||
# return variable value from file
|
||||
var(){
|
||||
[[ -r "$2" ]] && grep -Pom1 "^$1=\"\K[^\"]+" "$2"
|
||||
}
|
||||
|
||||
# return interface index
|
||||
index(){
|
||||
cat $SYSTEM/$1/ifindex 2>/dev/null
|
||||
}
|
||||
|
||||
# translate security to informational text
|
||||
trans(){
|
||||
case "$1" in
|
||||
@@ -126,13 +138,21 @@ ipaddr_up(){
|
||||
if carrier $PORT; then STATE="UP"; else STATE="DOWN"; fi
|
||||
log "interface $PORT is $STATE, setting static $IP address"
|
||||
ipv6_addr $PORT 0 1
|
||||
INDEX=$(index $PORT)
|
||||
INDEX=$((3000 + ${INDEX:-$(($(index * | sort -n | tail -1) + 1))}))
|
||||
if [[ $IP == ipv4 ]]; then
|
||||
[[ -n $IP4 && -n $MASK4 ]] && run ip -4 addr add $(unzero $IP4)/$MASK4 dev $PORT metric 3004
|
||||
[[ -n $GATEWAY4 ]] && run ip -4 route add default via $GATEWAY4 dev $PORT metric 3004
|
||||
if [[ -n $IP4 && -n $MASK4 ]]; then
|
||||
run ip -4 addr add $(unzero $IP4)/$MASK4 metric $INDEX dev $PORT
|
||||
# re-add IPv4 address of parent (if docker is running)
|
||||
if [[ $(var DOCKER_ALLOW_ACCESS $DOCKER) == yes && -S /var/run/docker.sock ]]; then
|
||||
ip addr add $(unzero $IP4)/$MASK4 metric $(($INDEX - 1)) dev shim-$PORT
|
||||
fi
|
||||
fi
|
||||
[[ -n $GATEWAY4 ]] && run ip -4 route add default via $GATEWAY4 metric $INDEX dev $PORT
|
||||
fi
|
||||
if [[ $IP == ipv6 ]]; then
|
||||
[[ -n $IP6 && -n $MASK6 ]] && run ip -6 addr add $(unzero6 $IP6)/$MASK6 dev $PORT metric 3004
|
||||
[[ -n $GATEWAY6 ]] && run ip -6 route add default via $GATEWAY6 dev $PORT metric 3004
|
||||
[[ -n $IP6 && -n $MASK6 ]] && run ip -6 addr add $(unzero6 $IP6)/$MASK6 metric $INDEX dev $PORT
|
||||
[[ -n $GATEWAY6 ]] && run ip -6 route add default via $GATEWAY6 metric $INDEX dev $PORT
|
||||
fi
|
||||
fi
|
||||
if [[ $DNS == yes ]]; then
|
||||
@@ -148,17 +168,13 @@ ipaddr_up(){
|
||||
ipaddr_down(){
|
||||
if [[ $DHCP == yes ]]; then
|
||||
# release DHCP assigned address and default route
|
||||
OPTIONS="-q -k"
|
||||
OPTIONS="-q -k -$1"
|
||||
[[ $DNS == yes ]] && OPTIONS="$OPTIONS -C resolv.conf"
|
||||
[[ $IP == ipv4 ]] && OPTIONS="$OPTIONS -4"
|
||||
[[ $IP == ipv6 ]] && OPTIONS="$OPTIONS -6"
|
||||
run dhcpcd $OPTIONS $PORT
|
||||
elif [[ $DHCP == no ]]; then
|
||||
# release static assigned address and default route
|
||||
[[ $IP == ipv4 ]] && run ip -4 addr flush dev $PORT
|
||||
[[ $IP == ipv4 ]] && run ip -4 route flush default dev $PORT
|
||||
[[ $IP == ipv6 ]] && run ip -6 addr flush dev $PORT
|
||||
[[ $IP == ipv6 ]] && run ip -6 route flush default dev $PORT
|
||||
run ip -$1 addr flush dev $PORT
|
||||
run ip -$1 route flush default dev $PORT
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -253,19 +269,25 @@ wifi_stop(){
|
||||
log "$DAEMON... No Wifi present."
|
||||
return
|
||||
fi
|
||||
IP=ipv4
|
||||
DHCP=$DHCP4
|
||||
DNS=$DNS4
|
||||
ipaddr_down
|
||||
SRV4=$DNS
|
||||
SRV6=
|
||||
ipaddr_down 4
|
||||
if [[ -n $DHCP6 ]]; then
|
||||
IP=ipv6
|
||||
DHCP=$DHCP6
|
||||
DNS=$DNS6
|
||||
ipaddr_down
|
||||
SRV6=$DNS
|
||||
ipaddr_down 6
|
||||
fi
|
||||
IPV4=$(ip -4 -br addr show scope global primary dev shim-$PORT | awk '{print $3,$4,$5;exit}')
|
||||
[[ -n $IPV4 ]] && run ip addr del $IPV4 dev shim-$PORT
|
||||
run ip addr flush dev $PORT
|
||||
run pkill wpa_supplicant
|
||||
run iw dev $PORT disconnect
|
||||
run rm -f $INI
|
||||
# restart services when static assignments
|
||||
[[ $SRV4 == no && (-z $SRV6 || $SRV6 == no) ]] && $SERVICES 5
|
||||
if ! wifi_running; then REPLY="Stopped"; else REPLY="Failed"; fi
|
||||
log "$DAEMON... $REPLY."
|
||||
}
|
||||
@@ -309,6 +331,8 @@ wifi_join(){
|
||||
IP=ipv4
|
||||
DHCP=$DHCP4
|
||||
DNS=$DNS4
|
||||
SRV4=$DNS
|
||||
SRV6=
|
||||
ipaddr_up
|
||||
# IPv6 address assignment (if enabled)
|
||||
if [[ -n $DHCP6 ]]; then
|
||||
@@ -316,10 +340,13 @@ wifi_join(){
|
||||
IP=ipv6
|
||||
DHCP=$DHCP6
|
||||
DNS=$DNS6
|
||||
SRV6=$DNS
|
||||
ipaddr_up
|
||||
else
|
||||
echo 1 >$CONF6/$PORT/disable_ipv6
|
||||
fi
|
||||
# restart services when static assignments
|
||||
[[ $SRV4 == no && (-z $SRV6 || $SRV6 == no) ]] && $SERVICES 5
|
||||
if wifi_running; then
|
||||
if [[ -z $CC ]]; then
|
||||
CC=($(iw reg get | grep -Po '^country \K..'))
|
||||
|
||||
@@ -13,23 +13,42 @@
|
||||
|
||||
[[ (-z $reason && -z $1) || (-n $reason && ! "BOUND6 IPV4LL EXPIRE" =~ $reason) ]] && exit 0
|
||||
|
||||
INI=/var/local/emhttp/network.ini.new
|
||||
CFG=/boot/config/network.cfg
|
||||
SYS=/sys/class/net
|
||||
INI="/var/local/emhttp/network.ini.new"
|
||||
STA="/var/local/emhttp/statics.ini.new"
|
||||
CFG="/boot/config/network.cfg"
|
||||
DOCKER="/boot/config/docker.cfg"
|
||||
SYSTEM="/sys/class/net"
|
||||
|
||||
declare -A VLANID USE_DHCP IPADDR NETMASK GATEWAY METRIC USE_DHCP6 IPADDR6 NETMASK6 GATEWAY6 PRIVACY6 METRIC6 DESCRIPTION PROTOCOL
|
||||
|
||||
# run & log functions
|
||||
. /etc/rc.d/rc.runlog
|
||||
|
||||
mask(){
|
||||
[[ -z $1 ]] && return
|
||||
# convert prefix to netmask
|
||||
set -- $((5-($1/8))) 255 255 255 255 $(((255<<(8-($1%8)))&255)) 0 0 0
|
||||
[[ $1 -gt 1 ]] && shift $1 || shift
|
||||
echo $1.$2.$3.$4
|
||||
# return variable value from file
|
||||
var(){
|
||||
[[ -r "$2" ]] && grep -Pom1 "^$1=\"\K[^\"]+" "$2"
|
||||
}
|
||||
|
||||
# return interface index
|
||||
index(){
|
||||
cat $SYSTEM/$1/ifindex 2>/dev/null
|
||||
}
|
||||
|
||||
# convert netmask to prefix
|
||||
mask2cidr(){
|
||||
[[ -z $1 ]] && return
|
||||
local MASK=$(eval eval echo "'\$((('{"${1//./,}"}'>>'{7..0}')%2))'")
|
||||
eval echo '$(('"${MASK// /+}"'))'
|
||||
}
|
||||
|
||||
# convert prefix to netmask
|
||||
cidr2mask(){
|
||||
[[ -z $1 ]] && return
|
||||
local MASK=$(eval echo '$(((1<<32)-1<<32-$1>>'{3..0}'*8&255))')
|
||||
echo "${MASK// /.}"
|
||||
}
|
||||
|
||||
# return dns nameserver entry
|
||||
dns() {
|
||||
[[ $1 == 4 ]] && ADDR='(\d{1,3}\.){3}\d+' || ADDR='([0-9a-fA-F]{1,4}::?){1,7}[0-9a-fA-F]*'
|
||||
grep -Po "^nameserver \K$ADDR" /etc/resolv.conf
|
||||
@@ -48,8 +67,10 @@ else
|
||||
BONDING=yes
|
||||
BRIDGING=yes
|
||||
fi
|
||||
|
||||
# prepare empty file
|
||||
echo -n >$INI
|
||||
echo -n >$STA
|
||||
|
||||
# loop thru all defined interfaces (=1 in case of legacy)
|
||||
for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
@@ -57,7 +78,7 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
ETH=${IFACE/#bond/eth}
|
||||
ETH=${ETH/#br/eth}
|
||||
# don't store when non-existing
|
||||
[[ -e $SYS/$ETH ]] || continue
|
||||
[[ -e $SYSTEM/$ETH ]] || continue
|
||||
echo "[$ETH]" >>$INI
|
||||
if [[ $i -eq 0 ]]; then
|
||||
# process legacy settings
|
||||
@@ -127,10 +148,10 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "USE_GW4:0=\"${USE_GW4[$i]}\"" >>$INI
|
||||
if [[ ${USE_DHCP[$i]} == yes ]]; then
|
||||
# get dhcp assigned ipv4 address & mask
|
||||
NET=($(ip -4 -br addr show $IFACE | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show default dev $IFACE | awk '{print $3;exit}')
|
||||
NET=($(ip -4 -br addr show scope global primary dev $IFACE | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show to default dev $IFACE | awk '{print $3;exit}')
|
||||
echo "IPADDR:0=\"${NET[0]}\"" >>$INI
|
||||
echo "NETMASK:0=\"$(mask ${NET[1]})\"" >>$INI
|
||||
echo "NETMASK:0=\"$(cidr2mask ${NET[1]})\"" >>$INI
|
||||
echo "GATEWAY:0=\"$GW\"" >>$INI
|
||||
echo "METRIC:0=\"${METRIC[$i]}\"" >>$INI
|
||||
else
|
||||
@@ -139,13 +160,16 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "NETMASK:0=\"${NETMASK[$i]}\"" >>$INI
|
||||
echo "GATEWAY:0=\"${GATEWAY[$i]}\"" >>$INI
|
||||
echo "METRIC:0=\"${METRIC[$i]}\"" >>$INI
|
||||
# store static ipv4 assignment
|
||||
IPV4="$(ip -4 -br addr show scope global primary dev $IFACE | awk '{$2="";print;exit}')"
|
||||
[[ -n $IPV4 ]] && echo "$IPV4" >>$STA
|
||||
fi
|
||||
echo "USE_DHCP6:0=\"${USE_DHCP6[$i]}\"" >>$INI
|
||||
echo "USE_GW6:0=\"${USE_GW6[$i]}\"" >>$INI
|
||||
if [[ ${USE_DHCP6[$i]} == yes ]]; then
|
||||
# get auto assigned ipv6 address & prefix
|
||||
NET6=($(ip -6 -br addr show $IFACE scope global -temporary -deprecated | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show default dev $IFACE | awk '{print $3;exit}')
|
||||
NET6=($(ip -6 -br addr show scope global primary -deprecated dev $IFACE | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show to default dev $IFACE | awk '{print $3;exit}')
|
||||
echo "IPADDR6:0=\"${NET6[0]}\"" >>$INI
|
||||
echo "NETMASK6:0=\"${NET6[1]}\"" >>$INI
|
||||
echo "GATEWAY6:0=\"$GW6\"" >>$INI
|
||||
@@ -158,6 +182,9 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "GATEWAY6:0=\"${GATEWAY6[$i]}\"" >>$INI
|
||||
echo "METRIC6:0=\"${METRIC6[$i]}\"" >>$INI
|
||||
echo "PRIVACY6:0=\"\"" >>$INI
|
||||
# store static ipv6 assignment
|
||||
IPV6="$(ip -6 -br addr show scope global primary -deprecated dev $IFACE | awk '{$2="";print;exit}')"
|
||||
[[ -n $IPV6 ]] && echo "$IPV6" >>$STA
|
||||
fi
|
||||
echo "USE_MTU=\"${USE_MTU[$i]}\"" >>$INI
|
||||
echo "MTU=\"${MTU[$i]}\"" >>$INI
|
||||
@@ -172,11 +199,11 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "USE_GW4:$j=\"${USE_GW4[$i,$j]}\"" >>$INI
|
||||
if [[ ${USE_DHCP[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# get dhcp assigned ipv4 address & mask
|
||||
NET=($(ip -4 -br addr show $DEV | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show default dev $DEV | awk '{print $3;exit}')
|
||||
# get dhcp assigned ipv4 address & cidr2mask
|
||||
NET=($(ip -4 -br addr show scope global primary dev $DEV | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show to default dev $DEV | awk '{print $3;exit}')
|
||||
echo "IPADDR:$j=\"${NET[0]}\"" >>$INI
|
||||
echo "NETMASK:$j=\"$(mask ${NET[1]})\"" >>$INI
|
||||
echo "NETMASK:$j=\"$(cidr2mask ${NET[1]})\"" >>$INI
|
||||
echo "GATEWAY:$j=\"$GW\"" >>$INI
|
||||
echo "METRIC:$j=\"${METRIC[$i,$j]}\"" >>$INI
|
||||
else
|
||||
@@ -185,14 +212,17 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "NETMASK:$j=\"${NETMASK[$i,$j]}\"" >>$INI
|
||||
echo "GATEWAY:$j=\"${GATEWAY[$i,$j]}\"" >>$INI
|
||||
echo "METRIC:$j=\"${METRIC[$i,$j]}\"" >>$INI
|
||||
# store static ipv4 assignment
|
||||
IPV4="$(ip -4 -br addr show scope global primary dev $DEV | awk '{$2="";print;exit}')"
|
||||
[[ -n $IPV4 ]] && echo "$IPV4" >>$STA
|
||||
fi
|
||||
echo "USE_DHCP6:$j=\"${USE_DHCP6[$i,$j]}\"" >>$INI
|
||||
echo "USE_GW6:$j=\"${USE_GW6[$i,$j]}\"" >>$INI
|
||||
if [[ ${USE_DHCP6[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# get auto assigned ipv6 address & prefix
|
||||
NET6=($(ip -6 -br addr show $DEV scope global -temporary -deprecated | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show default dev $DEV | awk '{print $3;exit}')
|
||||
NET6=($(ip -6 -br addr show scope global primary -deprecated dev $DEV | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show to default dev $DEV | awk '{print $3;exit}')
|
||||
echo "IPADDR6:$j=\"${NET6[0]}\"" >>$INI
|
||||
echo "NETMASK6:$j=\"${NET6[1]}\"" >>$INI
|
||||
echo "GATEWAY6:$j=\"$GW6\"" >>$INI
|
||||
@@ -205,6 +235,9 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "GATEWAY6:$j=\"${GATEWAY6[$i,$j]}\"" >>$INI
|
||||
echo "METRIC6:$j=\"${METRIC6[$i,$j]}\"" >>$INI
|
||||
echo "PRIVACY6:$j=\"\"" >>$INI
|
||||
# store static ipv6 assignment
|
||||
IPV6="$(ip -6 -br addr show scope global primary -deprecated dev $DEV | awk '{$2="";print;exit}')"
|
||||
[[ -n $IPV6 ]] && echo "$IPV6" >>$STA
|
||||
fi
|
||||
done
|
||||
else
|
||||
@@ -214,6 +247,25 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
done
|
||||
# atomically update file
|
||||
mv $INI ${INI%.*}
|
||||
mv $STA ${STA%.*}
|
||||
|
||||
# add or remove IPv4 assignment from attached interface when Docker custom network access is allowed
|
||||
[[ ${interface:0:2} == br || $interface == wlan0 ]] && LINK=shim-$interface || LINK=vhost${interface//[^0-9.]/}
|
||||
if [[ -e $SYSTEM/$LINK && $(var DOCKER_ALLOW_ACCESS $DOCKER) == yes ]]; then
|
||||
IPV4=$(ip -4 -br addr show scope global primary dev $interface | awk '{print $3;exit}')
|
||||
[[ $interface == wlan0 ]] && INDEX=3000 || INDEX=1000
|
||||
INDEX=$(($INDEX - 1 + $(index $interface)))
|
||||
case $reason in
|
||||
'BOUND' | 'BOUND6')
|
||||
# re-add IPv4 address of parent (if docker is running)
|
||||
[[ -S /var/run/docker.sock ]] && ip addr add $IPV4 metric $INDEX dev $LINK
|
||||
;;
|
||||
'EXPIRE')
|
||||
# remove IPv4 address of parent
|
||||
ip addr del $IPV4 metric $INDEX dev $LINK
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
log "interface=${interface:-$1}, reason=$reason, protocol=$protocol"
|
||||
# delayed execution
|
||||
@@ -224,19 +276,19 @@ if [[ -z $interface || "eth0 br0 bond0 wlan0" =~ $interface ]]; then
|
||||
. /etc/unraid-version
|
||||
echo -e "Unraid Server OS version: $version" >/etc/issue
|
||||
# find management interface
|
||||
[[ -e $SYS/bond0 ]] && dev=bond0 || dev=eth0
|
||||
[[ -e $SYS/br0 ]] && dev=br0
|
||||
IPv4=$(ip -4 -br addr show $dev scope global | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
IPv6=$(ip -6 -br addr show $dev scope global -temporary -deprecated | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
[[ -e $SYSTEM/bond0 ]] && DEV=bond0 || DEV=eth0
|
||||
[[ -e $SYSTEM/br0 ]] && DEV=br0
|
||||
IPV4=$(ip -4 -br addr show scope global primary dev $DEV | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $DEV | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
# show current IP assignment
|
||||
[[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue
|
||||
[[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue
|
||||
if [[ -e $SYS/wlan0 ]]; then
|
||||
[[ -n $IPV4 ]] && echo " IPv4 address: $IPV4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue
|
||||
[[ -n $IPV6 ]] && echo " IPv6 address: $IPV6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue
|
||||
if [[ -e $SYSTEM/wlan0 ]]; then
|
||||
echo "Wireless network:" >>/etc/issue
|
||||
IPv4=$(ip -4 -br addr show wlan0 scope global | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
IPv6=$(ip -6 -br addr show wlan0 scope global -temporary -deprecated | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
[[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue
|
||||
[[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue
|
||||
IPV4=$(ip -4 -br addr show scope global primary dev wlan0 | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
IPV6=$(ip -6 -br addr show scope global primary -deprecated dev wlan0 | awk '{print $3;exit}' | sed -r 's/\/[0-9]+//')
|
||||
[[ -n $IPV4 ]] && echo " IPv4 address: $IPV4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue
|
||||
[[ -n $IPV6 ]] && echo " IPv6 address: $IPV6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue
|
||||
fi
|
||||
echo >>/etc/issue
|
||||
fi
|
||||
|
||||
69
sbin/monitor_interface
Normal file
69
sbin/monitor_interface
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# script: monitor_interface
|
||||
#
|
||||
# Monitors a given list of interfaces and add or remove static IP addresses to these interfaces.
|
||||
# The list of interfaces is provided in the file '/var/local/emhttp/statics.ini'
|
||||
# This file is maintained by the script 'create_network_ini' which keep track of all IP assignments.
|
||||
#
|
||||
# By removing static IP addresses from inactive interfaces, these interfaces do not longer interfere with wireless.
|
||||
# In other words the wired connection can be pulled without consequences.
|
||||
#
|
||||
# Bergware - modified for Unraid OS, May 2025
|
||||
|
||||
FILE=/var/local/emhttp/statics.ini
|
||||
SYSTEM=/sys/class/net
|
||||
|
||||
state(){
|
||||
cat $SYSTEM/$1/operstate 2>/dev/null
|
||||
}
|
||||
|
||||
md5(){
|
||||
[[ -r $FILE ]] && md5sum $FILE | awk '{print $1;exit}'
|
||||
}
|
||||
|
||||
switch(){
|
||||
local n status
|
||||
[[ -z $1 ]] && return 1
|
||||
status=3
|
||||
# state should stay different for at least 3 seconds
|
||||
for n in {1..3}; do
|
||||
[[ $(state $1) != $2 ]] && ((status--))
|
||||
sleep 1
|
||||
done
|
||||
[[ $status -eq 0 ]]
|
||||
}
|
||||
|
||||
init(){
|
||||
PORT=(); STATE=();
|
||||
if [[ -r $FILE ]]; then
|
||||
# initialize values from file, maintained by 'create_network_ini'
|
||||
while IFS=$'\n' read -r ROW; do
|
||||
PORT+=("$ROW")
|
||||
STATE+=($(state ${ROW%% *}))
|
||||
done <$FILE
|
||||
fi
|
||||
MD5=$(md5)
|
||||
}
|
||||
|
||||
while :; do
|
||||
# monitor file content changes
|
||||
[[ $MD5 != $(md5) ]] && init
|
||||
LAST=
|
||||
for i in ${!PORT[@]}; do
|
||||
INT=${PORT[$i]%% *}
|
||||
# did interface state change?
|
||||
if switch $INT ${STATE[$i]}; then
|
||||
NEW=$(state $INT)
|
||||
STATE[$i]=$NEW
|
||||
if [[ $NEW == up ]]; then
|
||||
ip addr add dev ${PORT[$i]}
|
||||
elif [[ $NEW == down && $INT != $LAST ]]; then
|
||||
ip addr flush scope global dev $INT
|
||||
fi
|
||||
fi
|
||||
LAST=$INT
|
||||
done
|
||||
# check every 3 seconds
|
||||
sleep 3
|
||||
done &
|
||||
@@ -7,6 +7,21 @@ status=http://localhost/pub/session?buffer_length=1 # nchan information about G
|
||||
nchan_list=/tmp/nchan_list.tmp
|
||||
nchan_id=$(basename "$0")
|
||||
|
||||
nchan_subs(){
|
||||
curl -m2 --unix-socket $nginx $status 2>/dev/null | grep -Pom1 'subscribers: \K\d+'
|
||||
}
|
||||
|
||||
nchan_idle(){
|
||||
local n idle subs
|
||||
idle=3
|
||||
for n in {1..3}; do
|
||||
subs=$(nchan_subs)
|
||||
[[ -z $subs || $subs =~ ^[0-9]+$ && $subs -eq 0 ]] && ((idle--))
|
||||
sleep 3
|
||||
done
|
||||
[[ $idle -eq 0 ]]
|
||||
}
|
||||
|
||||
nchan_stop() {
|
||||
echo -n >$nchan_list
|
||||
while IFS=$'\n' read -r nchan; do
|
||||
@@ -49,26 +64,18 @@ start=$(date +%s)
|
||||
while :; do
|
||||
# only act when GUI registered nchan processes are running
|
||||
if [[ -s $nchan_pid ]]; then
|
||||
# get number of GUI nchan subscribers
|
||||
subs=$(curl --unix-socket $nginx $status 2>/dev/null | grep -Pom1 'subscribers: \K\d+')
|
||||
if [[ -z $subs || $subs -eq 0 ]]; then
|
||||
sleep 5
|
||||
# steady state?
|
||||
subs=$(curl --unix-socket $nginx $status 2>/dev/null | grep -Pom1 'subscribers: \K\d+')
|
||||
if [[ -z $subs || $subs -eq 0 ]]; then
|
||||
now=$(date +%s)
|
||||
# log at 1 hour interval
|
||||
if [[ $((now-start)) -ge 3600 ]]; then
|
||||
logger -t $nchan_id -- "Stop running nchan processes"
|
||||
start=$now
|
||||
fi
|
||||
nchan_stop
|
||||
# empty GUI registered list & statistics
|
||||
rm -f $nchan_pid $disk_load
|
||||
if nchan_idle; then
|
||||
now=$(date +%s)
|
||||
# log at 1 hour interval
|
||||
if [[ $((now-start)) -ge 3600 ]]; then
|
||||
logger -t $nchan_id -- "Stop running nchan processes"
|
||||
start=$now
|
||||
fi
|
||||
nchan_stop
|
||||
# empty GUI registered list & statistics
|
||||
rm -f $nchan_pid $disk_load
|
||||
fi
|
||||
fi
|
||||
# check every 30 seconds
|
||||
sleep 30
|
||||
done &
|
||||
disown %%
|
||||
|
||||
Reference in New Issue
Block a user