mirror of
https://github.com/unraid/webgui.git
synced 2026-01-05 17:20:04 -06:00
Backport miscellaneous fixes to Unraid 7.1
This commit is contained in:
@@ -25,23 +25,23 @@ exec("/etc/rc.d/rc.docker status >/dev/null",$dummy,$DockerStopped);
|
||||
|
||||
function strposX($s, $c, $n=1) {
|
||||
$p = 0;
|
||||
while ($n && $p=strpos($s,$c,$p)!==false) {$n--; $p+=strlen($c);}
|
||||
while ($n && $p = strpos($s,$c,$p) !== false) {$n--; $p += strlen($c);}
|
||||
return $p;
|
||||
}
|
||||
|
||||
unset($custom,$other);
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^br[0-9]'",$custom);
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^(bond|eth|wlan)[0-9]'",$other);
|
||||
$bridge = count($custom)>0;
|
||||
exec("ls --indicator-style=none /sys/class/net | grep -P '^br[0-9]'",$custom);
|
||||
exec("ls --indicator-style=none /sys/class/net | grep -P '^(bond|eth|wlan)[0-9]'",$other);
|
||||
$bridge = count($custom) > 0;
|
||||
$slaves = [];
|
||||
|
||||
foreach ($other as $network) {
|
||||
if (substr($network,0,4)=='bond') {
|
||||
if (substr($network,0,4) == 'bond') {
|
||||
$br = str_replace('bond','br',$network);
|
||||
$bond = "/sys/class/net/$network/bonding/slaves";
|
||||
if (file_exists($bond)) $slaves = array_merge($slaves,explode(' ',str_replace("\n","",file_get_contents($bond))));
|
||||
if (!in_array($br,$custom)) $custom[] = $network;
|
||||
} elseif (substr($network,0,3)=='eth') {
|
||||
} elseif ($bridge && substr($network,0,3) == 'eth') {
|
||||
$br = str_replace('eth','br',$network);
|
||||
$bond = str_replace('eth','bond',$network);
|
||||
if (!in_array($br,$custom) && !in_array($bond,$custom)) $custom[] = $network;
|
||||
@@ -50,18 +50,18 @@ foreach ($other as $network) {
|
||||
}
|
||||
}
|
||||
|
||||
$include = $include6 = $address = $address6 = $gateway = $gateway6 = $unset = $protocol = [];
|
||||
$wide = false;
|
||||
$wlan = (array)@parse_ini_file('/var/local/emhttp/wireless.ini');
|
||||
$include = $include6 = $address = $address6 = $gateway = $gateway6 = $unset = $protocol = [];
|
||||
$wide = false;
|
||||
$wlan = (array)@parse_ini_file('/var/local/emhttp/wireless.ini');
|
||||
|
||||
foreach ($custom as $network) {
|
||||
if (in_array($network,$slaves)) continue;
|
||||
$ip4 = exec("ip -4 -br addr show $network scope global | awk '{print $3;exit}'");
|
||||
$ip6 = exec("ip -6 -br addr show $network scope global -temporary -deprecated | awk '{print $3;exit}'");
|
||||
$gw4 = $ip4 ? exec("ip -4 route show dev $network default | awk '{print $3;exit}'") : '';
|
||||
$gw6 = $ip6 ? exec("ip -6 route show dev $network default | awk '{print $3;exit}'") : '';
|
||||
$route4 = $ip4 ? exec("ip -4 route show dev $network $ip4 | awk '{print $1;exit}'") : '';
|
||||
$route6 = $ip6 ? exec("ip -6 route show dev $network | awk '/^".substr($ip6,0,strposX($ip6,':',4))."/{print $1;exit}'") : '';
|
||||
$ip4 = exec("ip -4 -br addr show scope global primary dev $network | awk '{print $3;exit}'");
|
||||
$ip6 = exec("ip -6 -br addr show scope global primary -deprecated dev $network | awk '{print $3;exit}'");
|
||||
$gw4 = $ip4 ? exec("ip -4 route show to default dev $network | awk '{print $3;exit}'") : '';
|
||||
$gw6 = $ip6 ? exec("ip -6 route show to default dev $network | awk '{print $3;exit}'") : '';
|
||||
$route4 = $ip4 ? exec("ip -4 route show dev $network | awk '$1 !~ /^default/ {print $1;exit}'") : '';
|
||||
$route6 = $ip6 ? exec("ip -6 route show dev $network | awk '$1 !~ /^(default|f[a-f])/ {print $1;exit}'") : '';
|
||||
if (substr($network,0,4) != 'wlan') {
|
||||
[$eth,$vlan] = my_explode('.',$network);
|
||||
$eth = str_replace(['bond','br'],'eth',$eth);
|
||||
@@ -89,6 +89,7 @@ foreach ($custom as $network) {
|
||||
}
|
||||
if ($protocol[$network] != 'ipv4') $wide = true;
|
||||
}
|
||||
|
||||
$ip4class = $wide ? 'ip6' : 'ip4';
|
||||
$gw4class = $wide ? 'gw6' : 'gw4';
|
||||
|
||||
@@ -114,15 +115,6 @@ function base_net($route) {
|
||||
return substr(explode('/',$route)[0],0,-2);
|
||||
}
|
||||
|
||||
function hide_wlan($network) {
|
||||
return $network=='wlan0' && lan_port(DockerUtil::port(),true)==1;
|
||||
}
|
||||
|
||||
function hide_eth($network) {
|
||||
$mgmt_port = ['br0','bond0','eth0'];
|
||||
return in_array($network,$mgmt_port) && lan_port('wlan0',true)==1;
|
||||
}
|
||||
|
||||
$bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
|
||||
//Check if docker.cfg does exist
|
||||
@@ -275,8 +267,8 @@ _(Template Authoring Mode)_:
|
||||
|
||||
_(Docker custom network type)_:
|
||||
: <select name="DOCKER_NETWORK_TYPE">
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'), $bridge?'':'disabled')?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'), $bridge?'':'selected')?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'), $bridge ? '' : 'disabled')?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'), $bridge ? '' : 'selected')?>
|
||||
</select> _(Please read the Help carefully)_. _(Misconfiguration can cause problems)_.
|
||||
|
||||
:docker_custom_network_type_help:
|
||||
@@ -302,14 +294,9 @@ _(Preserve user defined networks)_:
|
||||
$net = normalize($network);
|
||||
$docker_auto = "DOCKER_AUTO_$net";
|
||||
$docker_dhcp = "DOCKER_DHCP_$net";
|
||||
$hide_wlan = hide_wlan($network);
|
||||
?>
|
||||
<input type="hidden" name="<?=$docker_auto?>" value="<?=_var($dockercfg,$docker_auto)?>">
|
||||
|
||||
<?if ($hide_wlan):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv4 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
<?
|
||||
$auto = _var($dockercfg,$docker_auto) == '' || str_contains(_var($dockercfg,$docker_auto), '4');
|
||||
@@ -336,27 +323,24 @@ _(IPv4 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
**_(DHCP pool)_:**<span id="<?=$docker_dhcp?>_net" class="net <?=$dhcpDisabled?>"><?=$prefix?>.</span>
|
||||
</span>
|
||||
<?
|
||||
for ($b=$box; $b<=3; $b++) {
|
||||
for ($b = $box; $b <= 3; $b++) {
|
||||
switch ($b) {
|
||||
case 1: $step = floor($size/65536)%256; break;
|
||||
case 2: $step = floor($size/256)%256; break;
|
||||
case 3: $step = $size%256; break;
|
||||
}
|
||||
if ($step===0) $step = 256;
|
||||
if ($step === 0) $step = 256;
|
||||
echo "<select id=\"{$docker_dhcp}_{$b}\" class=\"net\" $dhcpDisabled>";
|
||||
for ($n=$net[$b]; $n<=$max[$b]; $n++) echo mk_option($net_user[$b],$n,$n,$n%$step==0?'':'class="hide"');
|
||||
for ($n = $net[$b]; $n <= $max[$b]; $n++) echo mk_option($net_user[$b],$n,$n,$n%$step==0?'':'class="hide"');
|
||||
echo "</select>";
|
||||
}
|
||||
echo "/ ";
|
||||
echo "<select id=\"{$docker_dhcp}_mask\" class=\"mask\" onchange=\"changeMask(this.id,this.value)\" $dhcpDisabled>";
|
||||
for ($m=$mask+1; $m<=30; $m++) echo mk_option($mask_user,$m,$m);
|
||||
for ($m = $mask+1; $m <= 30; $m++) echo mk_option($mask_user,$m,$m);
|
||||
echo "</select><span id=\"{$docker_dhcp}_size\" style=\"".($dhcp?'':'display:none')."\">($size "._('hosts').")</span>";
|
||||
echo "<input type=\"hidden\" name=\"$docker_dhcp\" value=\"\">";
|
||||
?>
|
||||
|
||||
<?if ($hide_wlan):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
|
||||
<?if ($include):?>
|
||||
@@ -370,48 +354,35 @@ $port = normalize($network);
|
||||
[$range,$size] = my_explode('/',_var($dockercfg,"DOCKER_RANGE_$port"));
|
||||
$disabled = $subnet ? '':'disabled';
|
||||
$dhcpDisabled = $range ? '':'disabled';
|
||||
$hide_eth = hide_eth($network);
|
||||
?>
|
||||
<?if ($protocol[$network] != 'ipv6'):?>
|
||||
<?if ($hide_eth):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
<?if ($protocol[$network] != 'ipv6' && ($network != 'wlan0' || lan_port('wlan0',true) == 1)):?>
|
||||
|
||||
_(IPv4 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
: <input type="checkbox" id="DOCKER_CUSTOM_<?=$port?>_edit" onchange="changeCustom(this.id,4)"<?=$subnet?'checked':''?>><span id="DOCKER_CUSTOM_<?=$port?>_line" class="<?=$subnet?'':'disabled'?>">
|
||||
<span class="<?=$ip4class?>">**_(Subnet)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_net" name="DOCKER_SUBNET_<?=$port?>" class="ip4" value="<?=$subnet?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>>/
|
||||
<select id="DOCKER_CUSTOM_<?=$port?>_mask" name="DOCKER_MASK_<?=$port?>" class="mask"<?=$disabled?>>
|
||||
<?for ($m=25; $m<=30; $m++) echo mk_option($mask?:24,$m,$m)?></select>
|
||||
<?for ($m=16; $m<=30; $m++) echo mk_option($mask?:24,$m,$m)?></select>
|
||||
</span>
|
||||
<span class="<?=$gw4class?>">**_(Gateway)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_gw" name="DOCKER_GATEWAY_<?=$port?>" class="ip4" value="<?=htmlspecialchars(_var($dockercfg,"DOCKER_GATEWAY_$port"))?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>></span>
|
||||
<input type="checkbox" id="DOCKER_CUSTOM_<?=$port?>_dhcp" onchange="customDHCP(this.id,4)"<?=$subnet?'checked':''?><?=$dhcpDisabled?>>
|
||||
**_(DHCP pool)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_pool" name="DOCKER_RANGE_<?=$port?>" class="ip4" value="<?=$range?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>>/
|
||||
<select id="DOCKER_CUSTOM_<?=$port?>_size" name="DOCKER_SIZE_<?=$port?>" class="mask" onchange="changeHosts(this.id,this.value)"<?=$disabled?>>
|
||||
<?for ($m=16; $m<=30; $m++) echo mk_option($size?:25,$m,$m)?></select>
|
||||
<?for ($m=25; $m<=30; $m++) echo mk_option($size?:25,$m,$m)?></select>
|
||||
<span id="DOCKER_CUSTOM_<?=$port?>_hosts" style="<?=$subnet?'':'display:none'?>">(<?=pow(2,32-($size?:25))?> _(hosts)_)</span></span>
|
||||
|
||||
<?endif;?>
|
||||
<?if ($hide_eth):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?if ($unset && $protocol[$network] != 'ipv6'):?>
|
||||
:docker_exclude_interface_vlan_ipv4_help:
|
||||
|
||||
<?endif;?>
|
||||
<?if ($include6):?>
|
||||
<hr>
|
||||
<?endif;?>
|
||||
<?foreach ($include6 as $network => $route):?>
|
||||
<?
|
||||
$net = normalize($network);
|
||||
$docker_auto = "DOCKER_AUTO_$net";
|
||||
$docker_dhcp6 = "DOCKER_DHCP6_$net";
|
||||
$hide_wlan = hide_wlan($network);
|
||||
?>
|
||||
<?if ($hide_wlan):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
<?if ($network != 'wlan0' || lan_port('wlan0',true) == 1):?>
|
||||
|
||||
_(IPv6 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
<?
|
||||
@@ -429,8 +400,6 @@ _(IPv6 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
<span class="ip6">**_(Subnet)_:** <?=$route?></span>
|
||||
<span class="gw6">**_(Gateway)_:** <?=$gateway6[$network]?></span>
|
||||
|
||||
<?if ($hide_wlan):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?if ($include6):?>
|
||||
@@ -444,12 +413,8 @@ $port = normalize($network);
|
||||
[$range6,$size6] = my_explode('/',_var($dockercfg,"DOCKER_RANGE6_$port"));
|
||||
$disabled = $subnet6 ? '':'disabled';
|
||||
$dhcpDisabled = $range6 ? '':'disabled';
|
||||
$hide_eth = hide_eth($network);
|
||||
?>
|
||||
<?if ($protocol[$network] != 'ipv4'):?>
|
||||
<?if ($hide_eth):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv6 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
: <input type="checkbox" id="DOCKER_CUSTOM6_<?=$port?>_edit" onchange="changeCustom(this.id,6)"<?=$subnet6?'checked':''?>><span id="DOCKER_CUSTOM6_<?=$port?>_line" class="<?=$subnet6?'':'disabled'?>">
|
||||
@@ -458,9 +423,6 @@ _(IPv6 custom network on interface)_ <?=$network?> (_(optional)_):
|
||||
<?for ($m=64; $m<=120; $m+=8) echo mk_option($mask6?:64,$m,$m)?></select></span>
|
||||
<span class="gw6">**_(Gateway)_:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_gw" name="DOCKER_GATEWAY6_<?=$port?>" class="gw6" value="<?=_var($dockercfg,"DOCKER_GATEWAY6_$port")?>" title="_(IPv6 address nnnn:xxxx::yyyy)_"<?=$disabled?>></span>
|
||||
|
||||
<?if ($hide_eth):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?if ($unset && $protocol[$network] != 'ipv4'):?>
|
||||
@@ -518,32 +480,24 @@ _(Preserve user defined networks)_:
|
||||
|
||||
<?foreach ($include as $network => $route):?>
|
||||
<?
|
||||
$net = normalize($network);
|
||||
$net = normalize($network);
|
||||
$docker_dhcp = "DOCKER_DHCP_$net";
|
||||
$hide_wlan = hide_wlan($network);
|
||||
?>
|
||||
<?if (isset($dockercfg[$docker_dhcp]) || empty($dockercfg["DOCKER_AUTO_$net"]) || $dockercfg["DOCKER_AUTO_$net"] != 'no'):?>
|
||||
<?if ($hide_wlan):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv4 custom network on interface)_ <?=$network?>:
|
||||
: <span class="<?=$gw4class?>">**_(Subnet)_:** <?=$route?></span>
|
||||
<span class="<?=$gw4class?>">**_(Gateway)_:** <?=$gateway[$network]?></span>
|
||||
**_(DHCP pool)_:** <?=_var($dockercfg,$docker_dhcp) ?: "_(not set)_"?><?if (isset($dockercfg[$docker_dhcp])):?> (<?=pow(2,32-my_explode('/',$dockercfg[$docker_dhcp])[1])?> _(hosts)_)<?endif;?>
|
||||
|
||||
<?if ($hide_wlan):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?foreach ($unset as $network):?>
|
||||
<?
|
||||
$port = normalize($network);
|
||||
$hide_eth = hide_eth($network);
|
||||
$port = normalize($network);
|
||||
|
||||
if (substr($network,0,4) != 'wlan') {
|
||||
[$eth,$vlan] = my_explode('.',$network);
|
||||
[$eth, $vlan] = my_explode('.',$network);
|
||||
$eth = str_replace(['bond','br'],'eth',$eth);
|
||||
if (!$vlan) {
|
||||
$protocol = _var($$eth,'PROTOCOL:0','ipv4');
|
||||
@@ -556,52 +510,38 @@ if (substr($network,0,4) != 'wlan') {
|
||||
$protocol = empty($wlan['IP6']) ? 'ipv4' : 'ipv4+ipv6';
|
||||
}
|
||||
|
||||
[$subnet,$mask] = my_explode('/',_var($dockercfg,"DOCKER_SUBNET_$port"));
|
||||
[$range,$size] = my_explode('/',_var($dockercfg,"DOCKER_RANGE_$port"));
|
||||
[$subnet, $mask] = my_explode('/',_var($dockercfg,"DOCKER_SUBNET_$port"));
|
||||
[$range, $size] = my_explode('/',_var($dockercfg,"DOCKER_RANGE_$port"));
|
||||
?>
|
||||
<?if ($protocol != 'ipv6' && $subnet):?>
|
||||
<?if ($hide_eth):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv4 custom network on interface)_ <?=$network?>:
|
||||
: <span class="<?=$gw4class?>">**_(Subnet)_:** <?=$subnet?>/<?=$mask?></span>
|
||||
<span class="<?=$gw4class?>">**_(Gateway)_:** <?=_var($dockercfg,"DOCKER_GATEWAY_$port")?></span>
|
||||
**_(DHCP pool)_:** <?=$range ? "$range/$size" : "_(not set)_"?><?if ($range):?> (<?=pow(2,32-($size?:25))?> _(hosts)_)<?endif;?>
|
||||
|
||||
<?if ($hide_eth):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?foreach ($include6 as $network => $route):?>
|
||||
<?
|
||||
$net = normalize($network);
|
||||
$net = normalize($network);
|
||||
$docker_dhcp6 = "DOCKER_DHCP6_$net";
|
||||
$hide_wlan = hide_wlan($network);
|
||||
|
||||
if (isset($dockercfg[$docker_dhcp6]) || empty($dockercfg["DOCKER_AUTO_$net"])):?>
|
||||
if (isset($dockercfg[$docker_dhcp6]) || empty($dockercfg["DOCKER_AUTO_$net"]) || $dockercfg["DOCKER_AUTO_$net"] != 'no'):?>
|
||||
<?$wide = true;?>
|
||||
<?if ($hide_wlan):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv6 custom network on interface)_ <?=$network?>:
|
||||
: <span class="gw6">**_(Subnet)_:** <?=$route?></span>
|
||||
<span class="gw6">**_(Gateway)_:** <?=$gateway6[$network]?></span>
|
||||
|
||||
<?if ($hide_wlan):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?foreach ($unset as $network):?>
|
||||
<?
|
||||
$port = normalize($network);
|
||||
$hide_eth = hide_eth($network);
|
||||
$port = normalize($network);
|
||||
|
||||
if (substr($network,0,4) != 'wlan') {
|
||||
[$eth,$vlan] = my_explode('.',$network);
|
||||
[$eth, $vlan] = my_explode('.',$network);
|
||||
$eth = str_replace(['bond','br'],'eth',$eth);
|
||||
if (!$vlan) {
|
||||
$protocol = _var($$eth,'PROTOCOL:0','ipv4');
|
||||
@@ -614,21 +554,15 @@ if (substr($network,0,4) != 'wlan') {
|
||||
$protocol = empty($wlan['IP6']) ? 'ipv4' : 'ipv4+ipv6';
|
||||
}
|
||||
|
||||
[$subnet6,$mask6] = my_explode('/',_var($dockercfg,"DOCKER_SUBNET6_$port"));
|
||||
[$range6,$size6] = my_explode('/',_var($dockercfg,"DOCKER_RANGE6_$port"));
|
||||
[$subnet6, $mask6] = my_explode('/',_var($dockercfg,"DOCKER_SUBNET6_$port"));
|
||||
[$range6, $size6] = my_explode('/',_var($dockercfg,"DOCKER_RANGE6_$port"));
|
||||
?>
|
||||
<?if ($protocol != 'ipv4' && $subnet6):?>
|
||||
<?if ($hide_eth):?>
|
||||
<div markdown="1" style="display:none">
|
||||
<?endif;?>
|
||||
|
||||
_(IPv6 custom network on interface)_ <?=$network?>:
|
||||
: <span class="gw6">**_(Subnet)_:** <?=$subnet6?>/<?=$mask6?></span>
|
||||
<span class="gw6">**_(Gateway)_:** <?=_var($dockercfg,"DOCKER_GATEWAY6_$port")?></span>
|
||||
|
||||
<?if ($hide_eth):?>
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
</div>
|
||||
|
||||
@@ -1230,9 +1230,8 @@ class Array2XML {
|
||||
function getValidNetworks() {
|
||||
global $lv;
|
||||
$arrValidNetworks = [];
|
||||
exec("ls --indicator-style=none /sys/class/net | grep -Po '^virbr[0-9]+'",$arrBridges);
|
||||
exec("ls --indicator-style=none /sys/class/net | grep -Po '^(br|bond|eth|wlan)[0-9]+(\.[0-9]+)?'",$arrBridges);
|
||||
// add 'virbr0' as default first choice
|
||||
array_unshift($arrBridges, 'virbr0');
|
||||
// remove redundant references of bridge and bond interfaces
|
||||
$remove = [];
|
||||
foreach ($arrBridges as $name) {
|
||||
@@ -1240,7 +1239,7 @@ class Array2XML {
|
||||
$remove = array_merge($remove, (array)@file("/sys/class/net/$name/bonding/slaves",FILE_IGNORE_NEW_LINES));
|
||||
} elseif (substr($name,0,2) == 'br') {
|
||||
$remove = array_merge($remove, array_map(function($n){return end(explode('/',$n));}, glob("/sys/class/net/$name/brif/*")));
|
||||
}
|
||||
}
|
||||
}
|
||||
$arrValidNetworks['bridges'] = array_diff($arrBridges, $remove);
|
||||
|
||||
@@ -1845,15 +1844,15 @@ class Array2XML {
|
||||
$rtn = $lv->domain_define($xml);
|
||||
|
||||
if (is_resource($rtn)) {
|
||||
$arrResponse = ['success' => true];
|
||||
$arrResponse = ['success' => true];
|
||||
write("addLog\0".htmlspecialchars(_("Creating XML successful")));
|
||||
} else {
|
||||
} else {
|
||||
$lastvmerror = $lv->get_last_error();
|
||||
$arrResponse = ['xml' => $xml,'error' => $lastvmerror];
|
||||
write("addLog\0".htmlspecialchars(_("Creating XML Error:$lastvmerror")));
|
||||
file_put_contents("/tmp/vmclonertn.debug", json_encode($arrResponse,JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
|
||||
return($rtn);
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ $arrValidNetworks = getValidNetworks();
|
||||
$strCPUModel = getHostCPUModel();
|
||||
$templateslocation = "/boot/config/plugins/dynamix.vm.manager/savedtemplates.json";
|
||||
|
||||
// get MAC address of wireless interface (if existing)
|
||||
$mac = file_exists('/sys/class/net/wlan0/address') ? trim(file_get_contents('/sys/class/net/wlan0/address')) : '';
|
||||
|
||||
if (is_file($templateslocation)){
|
||||
$arrAllTemplates["User-templates"] = "";
|
||||
$ut = json_decode(file_get_contents($templateslocation),true);
|
||||
@@ -352,7 +355,7 @@ if ($snapshots!=null && count($snapshots) && !$boolNew) {
|
||||
<table>
|
||||
<tr class="<?=$snaphidden?>">
|
||||
<td></td>
|
||||
<td><span class="orange-text"><i class="fa fa-fw fa-warning"></i> _(Rename disabled, <?=$snapcount?> snapshot(s) exists)_.</span></td>
|
||||
<td><span class="orange-text"><i class="fa fa-fw fa-warning"></i> <?=sprintf(_('Rename disabled, %s snapshot(s) exists'), $snapcount)?>.</span></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="zfs-name" class="hidden">
|
||||
@@ -2017,13 +2020,17 @@ foreach ($arrConfig['evdev'] as $i => $arrEvdev) {
|
||||
var storageType = "<?=get_storage_fstype($arrConfig['template']['storage']);?>";
|
||||
var storageLoc = "<?=$arrConfig['template']['storage']?>";
|
||||
|
||||
function updateMAC(index,port) {
|
||||
$('input[name="nic['+index+'][mac]"').prop('disabled',port=='wlan0');
|
||||
$('i.mac_generate.'+index).prop('disabled',port=='wlan0');
|
||||
function updateMAC(index, port) {
|
||||
var wlan0 = '<?=$mac?>'; // mac address of wlan0
|
||||
var mac = $('input[name="nic['+index+'][mac]"');
|
||||
mac.prop('disabled', port=='wlan0');
|
||||
$('i.mac_generate.'+index).prop('disabled', port=='wlan0');
|
||||
$('span.wlan0').removeClass('hidden');
|
||||
if (port != 'wlan0') {
|
||||
if (port == 'wlan0') {
|
||||
mac.val(wlan0);
|
||||
} else {
|
||||
$('span.wlan0').addClass('hidden');
|
||||
$('i.mac_generate.'+index).click();
|
||||
if (wlan0 && mac.val()==wlan0) $('i.mac_generate.'+index).click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create new VM template
|
||||
if (isset($_POST['createvmtemplate'])) {
|
||||
$reply = addtemplatexml($_POST);
|
||||
@@ -116,7 +116,7 @@
|
||||
<input type="button" value="_(Create)_" busyvalue="_(Creating)_..." readyvalue="_(Create)_" id="btnSubmit" />
|
||||
<? } ?>
|
||||
<input type="button" value="_(Cancel)_" id="btnCancel" />
|
||||
|
||||
|
||||
<input type="button" value=" _(Create/Modify Template)_" busyvalue="_(Creating)_..." readyvalue="_(Create)_" id="btnTemplateSubmit" />
|
||||
|
||||
<? } else { ?>
|
||||
@@ -217,12 +217,12 @@ $(function() {
|
||||
$button.val($button.attr('busyvalue'));
|
||||
swal({
|
||||
title: "_(Template Name)_",
|
||||
text: "_(Enter name:\nIf name already exists it will be replaced.)_",
|
||||
text: "_(Enter name)_:\n_(If name already exists it will be replaced)_.",
|
||||
type: "input",
|
||||
showCancelButton: true,
|
||||
closeOnConfirm: false,
|
||||
//animation: "slide-from-top",
|
||||
inputPlaceholder: "_(Leaving blank will use OS name.)_"
|
||||
inputPlaceholder: "_(Leaving blank will use OS name)_."
|
||||
},
|
||||
function(inputValue){
|
||||
postdata=postdata+"&templatename="+inputValue;
|
||||
|
||||
@@ -47,19 +47,16 @@ var dfm_read = {};
|
||||
function dfm_footer(action, text) {
|
||||
switch (action) {
|
||||
case 'show':
|
||||
$('#countdown').show();
|
||||
$('#user-notice').show();
|
||||
break;
|
||||
case 'hide':
|
||||
$('#countdown').hide();
|
||||
$('#user-notice').hide();
|
||||
break;
|
||||
case 'write':
|
||||
if ($('#countdown').html() == '') $('#countdown').html('<a class="hand" onclick="dfm_openDialog(true)" title="_(File Manager)_"><i class="icon-u-duplicate dfm"></i></a>');
|
||||
$('#user-notice').html(text);
|
||||
let icon = '<a class="hand" onclick="dfm_openDialog(true)" title="_(File Manager)_"><i class="icon-u-duplicate dfm"></i></a>';
|
||||
$('#user-notice').html(icon + text);
|
||||
break;
|
||||
case 'clear':
|
||||
$('#countdown').html('');
|
||||
$('#user-notice').html('');
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Tag="icon-ethernet"
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$members = parse_ini_file('state/network.ini',true);
|
||||
$members = parse_ini_file('state/network.ini', true);
|
||||
$build = false;
|
||||
$template = "$docroot/webGui/EthX.page";
|
||||
$ini = '/var/local/emhttp/network.ini';
|
||||
@@ -35,7 +35,7 @@ $masks = [
|
||||
];
|
||||
|
||||
// get available ethernet ports (excluding eth0)
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'",$ports);
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'", $ports);
|
||||
|
||||
function locked($source, $port) {
|
||||
global $members;
|
||||
@@ -61,7 +61,7 @@ function metric($eth) {
|
||||
$bond = str_replace('eth', 'bond', $eth);
|
||||
$port = file_exists("$system/$bridge") ? $bridge : (file_exists("$system/$bond") ? $bond : $eth);
|
||||
$index = exec("cat $system/$port/ifindex 2>/dev/null");
|
||||
return 1000 + ($index ?: exec("cat $system/*/ifindex | sort -n | tail -1") + 1);
|
||||
return $index ?: exec("cat $system/*/ifindex | sort -n | tail -1") + 1;
|
||||
}
|
||||
|
||||
// remove non-existing ethernet ports
|
||||
@@ -204,7 +204,7 @@ function prepareSettings(form) {
|
||||
$(form).find('select[name^="USE_DHCP:"]').each(function() {
|
||||
var i = $(this).prop('name').split(':')[1];
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4';
|
||||
var gw4 = (port == 'eth0') ? true : $(form).find('input[name="USE_GW4:'+i+'"]').prop('checked');
|
||||
var gw4 = (port == 'eth0' && i == 0) ? true : $(form).find('input[name="USE_GW4:'+i+'"]').prop('checked');
|
||||
if (protocol != 'ipv6' && $(this).val() != 'no') {
|
||||
$(form).find('input[name="IPADDR:'+i+'"]').val('');
|
||||
$(form).find('input[name="GATEWAY:'+i+'"]').val('');
|
||||
@@ -214,7 +214,7 @@ function prepareSettings(form) {
|
||||
$(form).find('select[name^="USE_DHCP6:"]').each(function() {
|
||||
var i = $(this).prop('name').split(':')[1];
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4';
|
||||
var gw6 = (port == 'eth0') ? true : $(form).find('input[name="USE_GW6:'+i+'"]').prop('checked');
|
||||
var gw6 = (port == 'eth0' && i == 0) ? true : $(form).find('input[name="USE_GW6:'+i+'"]').prop('checked');
|
||||
if (protocol != 'ipv4' && $(this).val() != 'no') {
|
||||
$(form).find('input[name="IPADDR6:'+i+'"]').val('');
|
||||
$(form).find('input[name="GATEWAY6:'+i+'"]').val('');
|
||||
@@ -813,7 +813,7 @@ _(IPv4 address assignment)_:
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:$i"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:$i"), '', _('None'))?>
|
||||
</select>
|
||||
<span class="gw4-eth0-<?=$i?> hide"><input type="checkbox" name="USE_GW4:<?=$i?>" onchange="selectGW(this.form,4,<?=$i?>,'slow')" <?=_var($eth0,"USE_GW4:$i")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw4-eth0-<?=$i?> hide"><input type="checkbox" name="USE_GW4:<?=$i?>" onchange="selectGW(this.form,4,<?=$i?>,'slow')" <?=_var($eth0,"METRIC:$i") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
@@ -844,7 +844,7 @@ _(IPv6 address assignment)_:
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:$i"), '', _('None'))?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
<span class="gw6-eth0-<?=$i?> hide"><input type="checkbox" name="USE_GW6:<?=$i?>" onchange="selectGW(this.form,6,<?=$i?>,'slow')" <?=_var($eth0,"USE_GW6:$i")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw6-eth0-<?=$i?> hide"><input type="checkbox" name="USE_GW6:<?=$i?>" onchange="selectGW(this.form,6,<?=$i?>,'slow')" <?=_var($eth0,"METRIC6:$i") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ _(IPv4 address assignment)_:
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:0"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:0"), '', _('None'))?>
|
||||
</select>
|
||||
<span class="gw4-ethX-0 hide"><input type="checkbox" name="USE_GW4:0" onchange="selectGW(this.form,4,0,'slow')" <?=_var($ethX,"USE_GW4:0")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw4-ethX-0 hide"><input type="checkbox" name="USE_GW4:0" onchange="selectGW(this.form,4,0,'slow')" <?=_var($ethX,"METRIC:0") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
@@ -200,7 +200,7 @@ _(IPv6 address assignment)_:
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:0"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:0"), '', _('None'))?>
|
||||
</select>
|
||||
<span class="gw6-ethX-0 hide"><input type="checkbox" name="USE_GW6:0" onchange="selectGW(this.form,6,0,'slow')" <?=_var($ethX,"USE_GW6:0")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw6-ethX-0 hide"><input type="checkbox" name="USE_GW6:0" onchange="selectGW(this.form,6,0,'slow')" <?=_var($ethX,"METRIC6:0") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
@@ -278,7 +278,7 @@ _(IPv4 address assignment)_:
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:$i"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:$i"), '', _('None'))?>
|
||||
</select>
|
||||
<span class="gw4-ethX-<?=$i?> hide"><input type="checkbox" name="USE_GW4:<?=$i?>" onchange="selectGW(this.form,4,<?=$i?>,'slow')" <?=_var($ethX,"USE_GW4:$i")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw4-ethX-<?=$i?> hide"><input type="checkbox" name="USE_GW4:<?=$i?>" onchange="selectGW(this.form,4,<?=$i?>,'slow')" <?=_var($ethX,"METRIC:$i") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
@@ -307,7 +307,7 @@ _(IPv6 address assignment)_:
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:$i"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:$i"), '', _('None'))?>
|
||||
</select>
|
||||
<span class="gw6-ethX-<?=$i?> hide"><input type="checkbox" name="USE_GW6:<?=$i?>" onchange="selectGW(this.form,6,<?=$i?>,'slow')" <?=_var($ethX,"USE_GW6:$i")?'checked':''?>><?=$enable?></span>
|
||||
<span class="gw6-ethX-<?=$i?> hide"><input type="checkbox" name="USE_GW6:<?=$i?>" onchange="selectGW(this.form,6,<?=$i?>,'slow')" <?=_var($ethX,"METRIC6:$i") == 0 ? '' : 'checked'?>><?=$enable?></span>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
|
||||
@@ -35,11 +35,6 @@ 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
|
||||
@@ -346,7 +341,7 @@ docker_network_start(){
|
||||
SUBNET=; GATEWAY=; SERVER=; RANGE=;
|
||||
[[ -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 to $IPV4 dev $NETWORK | awk '{print $1;exit}')
|
||||
SUBNET=$(ip -4 route show dev $NETWORK | awk '$1 !~ /^default/ {print $1;exit}')
|
||||
SERVER=${IPV4%/*}
|
||||
DHCP=${NETWORK/./_}
|
||||
DHCP=DOCKER_DHCP_${DHCP^^}
|
||||
@@ -355,9 +350,9 @@ docker_network_start(){
|
||||
fi
|
||||
SUBNET6=; GATEWAY6=; SERVER6=;
|
||||
# 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=
|
||||
[[ -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 '^f[a-f]|^$') || IPV6=
|
||||
if [[ -n $IPV6 ]]; then
|
||||
SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')
|
||||
SUBNET6=$(ip -6 route show dev $NETWORK | awk '$1 !~ /^(default|f[a-f])/ {print $1;exit}')
|
||||
SERVER6=${IPV6%/*}
|
||||
GATEWAY6=$(ip -6 route show to default dev $NETWORK | awk '{print $3;exit}')
|
||||
# replace link local address for first address in subnet
|
||||
@@ -421,14 +416,13 @@ docker_network_start(){
|
||||
if [[ $TYPE == br ]]; then
|
||||
LINK=shim-$NETWORK
|
||||
if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
|
||||
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
|
||||
# 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 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
|
||||
@@ -440,22 +434,19 @@ docker_network_start(){
|
||||
else
|
||||
if [[ $TYPE == wlan ]]; then
|
||||
VHOST=shim-$NETWORK
|
||||
INDEX=3000
|
||||
else
|
||||
VHOST=vhost${NETWORK//[^0-9.]/}
|
||||
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
|
||||
[[ -z $(ipv4_exist $VHOST ${IPV4%/*}) ]] && run ip addr add $IPV4 dev $VHOST metric 0
|
||||
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
|
||||
run ip addr del $IPV4 dev $VHOST metric 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -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, May 2025
|
||||
# Bergware - modified for Unraid OS, June 2025
|
||||
|
||||
# Adapted by Bergware for use in Unraid OS - April 2016
|
||||
# - improved interface configuration
|
||||
@@ -84,6 +84,10 @@
|
||||
# Adapted by Bergware for use in Unraid OS - May 2025
|
||||
# - improved metric value to interface IP assignment
|
||||
|
||||
# Adapted by Bergware for use in Unraid OS - June 2025
|
||||
# - revert metric assignment to static addresses
|
||||
# - remove duplicate ipv6 parameters
|
||||
|
||||
###########
|
||||
# LOGGING #
|
||||
###########
|
||||
@@ -324,26 +328,26 @@ ipv6_up(){
|
||||
ipv6_ra(){
|
||||
echo $2 >$CONF6/$1/accept_ra
|
||||
echo $2 >$CONF6/$1/accept_ra_defrtr
|
||||
echo $3 >$CONF6/$1/autoconf
|
||||
echo $2 >$CONF6/$1/autoconf
|
||||
}
|
||||
|
||||
# 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
|
||||
[[ -d $CONF6/${IFACE/$1/$2} ]] && ipv6_ra ${IFACE/$1/$2} $4
|
||||
[[ -d $CONF6/${IFACE/$1/$3} ]] && ipv6_ra ${IFACE/$1/$3} $4
|
||||
}
|
||||
|
||||
# enable/disable ipv6 assignment per interface
|
||||
ipv6_addr(){
|
||||
[[ -d $CONF6/$IFACE ]] && ipv6_ra $IFACE $1 $2
|
||||
[[ -d $CONF6/$VHOST ]] && ipv6_ra $VHOST $1 $2
|
||||
[[ -d $CONF6/$IFACE ]] && ipv6_ra $IFACE $1
|
||||
[[ -d $CONF6/$VHOST ]] && ipv6_ra $VHOST $1
|
||||
# repeat action on related interfaces
|
||||
if [[ ${IFACE:0:4} == bond ]]; then
|
||||
ipv6_conf bond br eth $1 $2
|
||||
ipv6_conf bond br eth $1
|
||||
elif [[ ${IFACE:0:2} == br ]]; then
|
||||
ipv6_conf br bond eth $1 $2
|
||||
ipv6_conf br bond eth $1
|
||||
else
|
||||
ipv6_conf eth bond br $1 $2
|
||||
ipv6_conf eth bond br $1
|
||||
fi
|
||||
sleep 1
|
||||
}
|
||||
@@ -366,7 +370,7 @@ ipaddr_up(){
|
||||
fi
|
||||
if [[ $DHCP == yes ]]; then
|
||||
# bring up interface using DHCP/SLAAC
|
||||
[[ -z $RENEW ]] && ipv6_addr 1 1
|
||||
[[ -z $RENEW ]] && ipv6_addr 1
|
||||
DHCP_OPTIONS="-q -n -p -t ${DHCP_TIMEOUT[$i]:-10}"
|
||||
[[ -n $DHCP_HOSTNAME ]] && DHCP_OPTIONS="$DHCP_OPTIONS -h $DHCP_HOSTNAME"
|
||||
[[ $DHCP_KEEP_RESOLV == yes ]] && DHCP_OPTIONS="$DHCP_OPTIONS -C resolv.conf"
|
||||
@@ -393,27 +397,25 @@ ipaddr_up(){
|
||||
# bring up interface using static IP address
|
||||
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))}))
|
||||
ipv6_addr 0
|
||||
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 metric $INDEX dev $IFACE
|
||||
[[ -n $MASK ]] && run ip -4 addr add $(unzero $ADDR)/$MASK dev $IFACE metric 1
|
||||
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 metric $INDEX dev $IFACE
|
||||
[[ -n $MASK6 ]] && run ip -6 addr add $(unzero6 $ADDR6)/$MASK6 dev $IFACE metric 1
|
||||
[[ -n $PRIV6 && -d $CONF6/$IFACE ]] && echo 0 >$CONF6/$IFACE/use_tempaddr
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# bring up interface without IP address
|
||||
ipv6_addr 0 0
|
||||
ipv6_addr 0
|
||||
ipaddr_down
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#
|
||||
# Bergware - created for Unraid OS, January 2025
|
||||
|
||||
# Adapted by Bergware for use in Unraid OS - June 2025
|
||||
# - put metric value at end of assignment
|
||||
|
||||
DAEMON="WiFi network"
|
||||
CALLER="wifi"
|
||||
INI="/var/local/emhttp/wireless.ini"
|
||||
@@ -142,17 +145,17 @@ ipaddr_up(){
|
||||
INDEX=$((3000 + ${INDEX:-$(($(index * | sort -n | tail -1) + 1))}))
|
||||
if [[ $IP == ipv4 ]]; then
|
||||
if [[ -n $IP4 && -n $MASK4 ]]; then
|
||||
run ip -4 addr add $(unzero $IP4)/$MASK4 metric $INDEX dev $PORT
|
||||
run ip -4 addr add $(unzero $IP4)/$MASK4 dev $PORT metric $INDEX
|
||||
# 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
|
||||
ip addr add $(unzero $IP4)/$MASK4 dev shim-$PORT metric $(($INDEX - 1))
|
||||
fi
|
||||
fi
|
||||
[[ -n $GATEWAY4 ]] && run ip -4 route add default via $GATEWAY4 metric $INDEX dev $PORT
|
||||
[[ -n $GATEWAY4 ]] && run ip -4 route add default via $GATEWAY4 dev $PORT metric $INDEX
|
||||
fi
|
||||
if [[ $IP == ipv6 ]]; then
|
||||
[[ -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
|
||||
[[ -n $IP6 && -n $MASK6 ]] && run ip -6 addr add $(unzero6 $IP6)/$MASK6 dev $PORT metric $INDEX
|
||||
[[ -n $GATEWAY6 ]] && run ip -6 route add default via $GATEWAY6 dev $PORT metric $INDEX
|
||||
fi
|
||||
fi
|
||||
if [[ $DNS == yes ]]; then
|
||||
@@ -283,7 +286,7 @@ wifi_stop(){
|
||||
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 pkill --ns $$ wpa_supplicant
|
||||
run iw dev $PORT disconnect
|
||||
run rm -f $INI
|
||||
# restart services when static assignments
|
||||
|
||||
@@ -145,7 +145,6 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
echo "DESCRIPTION:0=\"${DESCRIPTION[$i]}\"" >>$INI
|
||||
echo "PROTOCOL:0=\"${PROTOCOL[$i]}\"" >>$INI
|
||||
echo "USE_DHCP:0=\"${USE_DHCP[$i]}\"" >>$INI
|
||||
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 scope global primary dev $IFACE | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
@@ -162,10 +161,12 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
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
|
||||
if [[ -n $IPV4 ]]; then
|
||||
echo "$IPV4" >>$STA
|
||||
echo "$IFACE GW4 $(ip -4 route show to default dev $IFACE)" >>$STA
|
||||
fi
|
||||
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 scope global primary -deprecated dev $IFACE | awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
@@ -184,21 +185,23 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
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
|
||||
if [[ -n $IPV6 ]]; then
|
||||
echo "$IPV6" >>$STA
|
||||
echo "$IFACE GW6 $(ip -6 route show to default dev $IFACE)" >>$STA
|
||||
fi
|
||||
fi
|
||||
echo "USE_MTU=\"${USE_MTU[$i]}\"" >>$INI
|
||||
echo "MTU=\"${MTU[$i]}\"" >>$INI
|
||||
if [[ -n ${VLANS[$i]} ]]; then
|
||||
# process VLAN interfaces
|
||||
echo "TYPE=\"trunk\"" >>$INI
|
||||
for ((j=1;j<${VLANS[$i]};j++)); do
|
||||
for ((j=1; j<${VLANS[$i]}; j++)); do
|
||||
echo "VLANID:$j=\"${VLANID[$i,$j]}\"" >>$INI
|
||||
echo "DESCRIPTION:$j=\"${DESCRIPTION[$i,$j]}\"" >>$INI
|
||||
echo "PROTOCOL:$j=\"${PROTOCOL[$i,$j]}\"" >>$INI
|
||||
echo "USE_DHCP:$j=\"${USE_DHCP[$i,$j]}\"" >>$INI
|
||||
echo "USE_GW4:$j=\"${USE_GW4[$i,$j]}\"" >>$INI
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
if [[ ${USE_DHCP[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# 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}')
|
||||
@@ -214,12 +217,14 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
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
|
||||
if [[ -n $IPV4 ]]; then
|
||||
echo "${IPV4/@$IFACE/}" >>$STA
|
||||
echo "$DEV GW4 $(ip -4 route show to default dev $DEV)" >>$STA
|
||||
fi
|
||||
fi
|
||||
echo "USE_DHCP6:$j=\"${USE_DHCP6[$i,$j]}\"" >>$INI
|
||||
echo "USE_GW6:$j=\"${USE_GW6[$i,$j]}\"" >>$INI
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
if [[ ${USE_DHCP6[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# get auto assigned ipv6 address & prefix
|
||||
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}')
|
||||
@@ -237,7 +242,10 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do
|
||||
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
|
||||
if [[ -n $IPV6 ]]; then
|
||||
echo "${IPV6/@$IFACE/}" >>$STA
|
||||
echo "$DEV GW6 $(ip -6 route show to default dev $DEV)" >>$STA
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
|
||||
@@ -14,56 +14,79 @@
|
||||
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--))
|
||||
wlan(){
|
||||
[[ -e $SYSTEM/wlan0 ]]
|
||||
}
|
||||
|
||||
carrier(){
|
||||
cat $SYSTEM/$1/carrier 2>/dev/null
|
||||
}
|
||||
|
||||
state(){
|
||||
local n NEW OLD HOLD
|
||||
OLD=$(carrier $1)
|
||||
HOLD=4
|
||||
# new state should hold for at least 4 seconds
|
||||
for n in {1..4}; do
|
||||
sleep 1
|
||||
NEW=$(carrier $1)
|
||||
[[ $NEW != $OLD ]] && ((HOLD--))
|
||||
done
|
||||
[[ $status -eq 0 ]]
|
||||
[[ $HOLD -eq 0 ]] && echo $NEW || echo $OLD
|
||||
}
|
||||
|
||||
init(){
|
||||
PORT=(); STATE=();
|
||||
TASK=()
|
||||
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%% *}))
|
||||
TASK+=("$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
|
||||
if wlan; then
|
||||
# monitor file content changes
|
||||
[[ $MD5 != $(md5) ]] && init
|
||||
LAST=
|
||||
for i in ${!TASK[@]}; do
|
||||
ADDR=(${TASK[$i]})
|
||||
PORT=${ADDR[0]}
|
||||
[[ $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/}
|
||||
;;
|
||||
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/}
|
||||
;;
|
||||
*)
|
||||
# IP address not present? create it
|
||||
[[ "$(ip -br addr show dev $PORT)" =~ "${ADDR[1]}" ]] || ip addr add dev ${TASK[$i]}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
0) # down
|
||||
# IP address present, remove it
|
||||
[[ "$(ip -br addr show dev $PORT)" =~ "${ADDR[1]}" ]] && ip addr del dev ${TASK[$i]}
|
||||
;;
|
||||
esac
|
||||
LAST=$PORT
|
||||
done
|
||||
fi
|
||||
# check every 3 seconds
|
||||
sleep 3
|
||||
done &
|
||||
|
||||
|
||||
Reference in New Issue
Block a user