Menu="NetworkSettings:100" Title="_(Interface)_ eth0" Tag="icon-ethernet" --- $members = parse_ini_file('state/network.ini',true); $build = false; $template = "$docroot/webGui/EthX.page"; $ini = '/var/local/emhttp/network.ini'; $validIP4 = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}"; $validIP6 = "(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)"; $enable = _('Enable default gateway'); $metric = _('metric value, a lower value is more preferred'); $jumbo = _('Enable jumbo frames'); $jumbo_1 = _('Allows the use of ethernet frames larger than 1500 bytes'); $jumbo_2 = _('Connectivity issues may occur when other devices do not support this feature'); $jumbo_3 = _('Or if they are improperly configured, use this feature with care'); $masks = [ '255.0.0.0' => '8', '255.255.0.0' => '16', '255.255.128.0' => '17', '255.255.192.0' => '18', '255.255.224.0' => '19', '255.255.240.0' => '20', '255.255.248.0' => '21', '255.255.252.0' => '22', '255.255.254.0' => '23', '255.255.255.0' => '24', '255.255.255.128' => '25', '255.255.255.192' => '26', '255.255.255.224' => '27', '255.255.255.240' => '28', '255.255.255.248' => '29', '255.255.255.252' => '30' ]; // get available ethernet ports (excluding eth0) exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'",$ports); function locked($source, $port) { global $members; foreach ($members as $member => $value) { if ($member == $source) continue; if ($value['BONDING']=='yes' && in_array($port,explode(',',$value['BONDNICS']))) return $value['BONDNAME'].' '.$member; if ($value['BRIDGING']=='yes' && in_array($port,explode(',',$value['BRNICS']))) return $value['BRNAME'].' '.$member; } return false; } function vlanID($cfg) { return array_filter($cfg, function($key){return strpos($key, 'VLANID:')===0;}, ARRAY_FILTER_USE_KEY); } function index($key) { return filter_var($key, FILTER_SANITIZE_NUMBER_INT); } function metric($eth, $prot, $index) { $system = '/sys/class/net'; $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; } // remove non-existing ethernet ports foreach (glob("$docroot/webGui/Eth[1-9]*.page", GLOB_NOSORT) as $port) { if (!in_array(strtolower(basename($port, '.page')), $ports)) { @unlink($port); $build = true; } } // add new ethernet ports foreach ($ports as $ethX) { $file = "$docroot/webGui/".ucfirst($ethX).".page"; if (!file_exists($file)) { $X = filter_var($ethX, FILTER_SANITIZE_NUMBER_INT); file_put_contents($file, str_replace(['parentname:nnn','tabX','bondX','brX','ethX'],['NetworkSettings:'.($X+100),'tab'.($X+1),'bond'.$X,'br'.$X,$ethX], file_get_contents($template))); $build = true; } } // enable interface only when VMs and Docker are stopped $service = exec('pgrep --ns $$ libvirt') ? _('VM manager') : ''; $service .= exec('pgrep --ns $$ docker') ? ($service ? ' '._('and').' ' : '')._('Docker service') : ''; // eth0 port status $no_eth0 = exec("ip -br link show eth0 | awk '{print \$2;exit}'")=='DOWN'; // get VLAN interfaces $vlan_eth0 = $sort_eth0 = []; if (isset($eth0)) foreach (vlanID($eth0) as $key => $val) {$vlan_eth0[] = index($key); $sort_eth0[] = (int)$val;} array_multisort($sort_eth0, $vlan_eth0); ?>