From ba0c169b003f9ade75c33e1f8169c3aa77466095 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 25 Feb 2025 14:36:01 +0100 Subject: [PATCH] Networking: smart default gateway implementation --- emhttp/plugins/dynamix/Eth0.page | 141 +++++++++++++++++++++---------- emhttp/plugins/dynamix/EthX.page | 37 +++++--- sbin/create_network_ini | 31 +++---- 3 files changed, 136 insertions(+), 73 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index bd2d1ab7c..601786835 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -15,14 +15,13 @@ Tag="icon-ethernet" */ ?> '8', '255.255.0.0' => '16', '255.255.128.0' => '17', '255.255.192.0' => '18', @@ -34,7 +33,7 @@ $masks = [ // 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) { +function locked($source, $port) { global $members; foreach ($members as $member => $value) { if ($member == $source) continue; @@ -43,12 +42,26 @@ function locked($source,$port) { } 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) { + $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 | grep -Pom1 ' metric \K\d+'"); + if ($metric) return $metric; + exec("ip -$prot route show default | grep -Po ' metric \K\d+'",$metrics); + return max($metrics) + 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)) { @@ -56,6 +69,7 @@ foreach (glob("$docroot/webGui/Eth[1-9]*.page",GLOB_NOSORT) as $port) { $build = true; } } + // add new ethernet ports foreach ($ports as $ethX) { $file = "$docroot/webGui/".ucfirst($ethX).".page"; @@ -97,10 +111,10 @@ function presetRun(form) { }); } -function signalRun(form,id) { +function signalRun(form, id) { switch (id) { case 1: - if (arg1.eth0=='none') arg1.eth0 = 'renew'; + if (arg1.eth0 == 'none') arg1.eth0 = 'renew'; break; case 2: var port = form.name.replace('_settings',''); @@ -112,7 +126,7 @@ function signalRun(form,id) { port = 'none'; } }); - if (port!='none') arg1[port] = port; + if (port != 'none') arg1[port] = port; break; } } @@ -141,8 +155,8 @@ function prepareSettings(form) { nic.value = form.BONDING.value=='yes' ? form.BONDNAME.value : brnics.join(','); nic.selected = true; nic.disabled = false; - if (brnics.length>1) form.BRSTP.value = 'yes'; - if ($(form).find('input[name="#arg[1]"]').val()=='none') return true; + if (brnics.length > 1) form.BRSTP.value = 'yes'; + if ($(form).find('input[name="#arg[1]"]').val() == 'none') return true; var metrics = [], metrics6 = []; $(form).find('input[name^="METRIC:"]').each(function(){if($(this).val()>0) metrics.push($(this).val());}); @@ -194,8 +208,8 @@ function prepareSettings(form) { var i = $(this).prop('name').split(':')[1]; var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4'; var metric = $(form).find('input[name="METRIC:'+i+'"]').val(); - var gw4 = (port=='eth0') ? true : $(form).find('input[name="USE_GW:'+i+'"]').prop('checked'); - if (protocol != 'ipv6' && $(this).val()=='yes') { + var gw4 = (port == 'eth0') ? true : $(form).find('input[name="USE_GW:'+i+'"]').prop('checked'); + if (protocol != 'ipv6' && $(this).val() != 'no') { $(form).find('input[name="IPADDR:'+i+'"]').prop('disabled',false).val(''); $(form).find('input[name="GATEWAY:'+i+'"]').prop('disabled',false).val(''); $(form).find('input[name="METRIC:'+i+'"]').prop('disabled',false).val(gw4?'':'0'); @@ -205,15 +219,15 @@ function prepareSettings(form) { var i = $(this).prop('name').split(':')[1]; var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4'; var metric = $(form).find('input[name="METRIC6:'+i+'"]').val(); - var gw6 = (port=='eth0') ? true : $(form).find('input[name="USE_GW6:'+i+'"]').prop('checked'); - if (protocol != 'ipv4' && $(this).val()=='yes') { + var gw6 = (port == 'eth0') ? true : $(form).find('input[name="USE_GW6:'+i+'"]').prop('checked'); + if (protocol != 'ipv4' && $(this).val() != 'no') { $(form).find('input[name="IPADDR6:'+i+'"]').prop('disabled',false).val(''); $(form).find('input[name="GATEWAY6:'+i+'"]').prop('disabled',false).val(''); $(form).find('input[name="METRIC6:'+i+'"]').prop('disabled',false).val(gw6?'':'0'); } - if ($(this).val()!='yes') $(form).find('input[name="PRIVACY6:'+i+'"]').prop('disabled',false).val(''); + if ($(this).val() != 'yes') $(form).find('input[name="PRIVACY6:'+i+'"]').prop('disabled',false).val(''); }); - if (port=='eth0') { + if (port == 'eth0') { $(dns).find('select,input').each(function(){ var name = $(this).prop('name'); var data = $(this).val(); @@ -221,11 +235,11 @@ function prepareSettings(form) { }); } $(form).find('input[name="#arg[1]"]').val(arg1[port]); - setTimeout(refresh,25000); + setTimeout(refresh, 25000); return true; } -function selectProtocol(form,index,step) { +function selectProtocol(form, index, step) { var port = form.name.replace('_settings',''); if (index == null) { $(form).find('select[name^="PROTOCOL:"]').each(function() { @@ -250,21 +264,21 @@ function selectProtocol(form,index,step) { var dhcp4 = $(form).find('select[name="USE_DHCP:'+i+'"]').val(); var dhcp6 = $(form).find('select[name="USE_DHCP6:'+i+'"]').val(); - if (dhcp4=='no') { + if (dhcp4 == 'no') { more4.show(); - gw4.hide(); - } else if (dhcp4=='yes') { + gw4.show(); + } else if (dhcp4 == 'yes') { more4.hide(); gw4.show(); } else { more4.hide(); gw4.hide(); } - if (dhcp6=='no') { + if (dhcp6 == 'no') { more6.show(); priv6.hide(); - gw6.hide(); - } else if (dhcp6=='yes') { + gw6.show(); + } else if (dhcp6 == 'yes') { more6.hide(); priv6.show(); gw6.show(); @@ -274,7 +288,7 @@ function selectProtocol(form,index,step) { gw6.hide(); } - checkNetworkSettings(form,i); + checkNetworkSettings(form, i); }); } else { var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4'; @@ -292,21 +306,21 @@ function selectProtocol(form,index,step) { } var dhcp4 = $(form).find('select[name="USE_DHCP:'+index+'"]').val(); var dhcp6 = $(form).find('select[name="USE_DHCP6:'+index+'"]').val(); - if (dhcp4=='no') { + if (dhcp4 == 'no') { more4.show(step); - gw4.hide(); - } else if (dhcp4=='yes') { + gw4.show(); + } else if (dhcp4 == 'yes') { more4.hide(step); gw4.show(); } else { more4.hide(step); gw4.hide(); } - if (dhcp6=='no') { + if (dhcp6 == 'no') { more6.show(step); priv6.hide(step); - gw6.hide(); - } else if (dhcp6=='yes') { + gw6.show(); + } else if (dhcp6 == 'yes') { more6.hide(step); priv6.show(step); gw6.show(); @@ -315,11 +329,33 @@ function selectProtocol(form,index,step) { priv6.hide(step); gw6.hide(); } - checkNetworkSettings(form,index); + checkNetworkSettings(form, index); } } -function checkNetworkSettings(form,index) { +function selectGW(form, prot, index, step) { + var port = form.name.replace('_settings',''); + if (prot == null) { + $(form).find('input[name^="USE_GW4:"]').each(function(){ + var i = $(this).prop('name').split(':')[1]; + var state = $(this).prop('checked'); + var gw = $('.more-gw4-'+port+'-'+i); + if (state) gw.show(); else gw.hide(); + }); + $(form).find('input[name^="USE_GW6"]').each(function(){ + var i = $(this).prop('name').split(':')[1]; + var state = $(this).prop('checked'); + var gw = $('.more-gw6-'+port+'-'+i); + if (state) gw.show(); else gw.hide(); + }); + } else { + var state = $(form).find('input[name="USE_GW'+prot+':'+index+'"]').prop('checked'); + var gw = $('.more-gw'+prot+'-'+port+'-'+index); + if (state) gw.show(step); else gw.hide(step); + } +} + +function checkNetworkSettings(form, index) { var disabled4 = $(form).find('select[name="USE_DHCP:'+index+'"]').val()!='no'; var disabled6 = $(form).find('select[name="USE_DHCP6:'+index+'"]').val()!='no'; var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4'; @@ -341,7 +377,7 @@ function checkNetworkSettings(form,index) { } } -function checkDNSsettings(form,step) { +function checkDNSsettings(form, step) { var dns = document.dns_settings; if ($(form).find('select[name="USE_DHCP:0"]').val()=='no') { dns.DHCP_KEEPRESOLV.value = 'yes'; @@ -358,7 +394,7 @@ function checkDNSsettings(form,step) { } } -function checkDNS6settings(form,step) { +function checkDNS6settings(form, step) { var dns = document.dns_settings; if ($(form).find('select[name="USE_DHCP6:0"]').val()=='no') { dns.DHCP6_KEEPRESOLV.value = 'yes'; @@ -375,7 +411,7 @@ function checkDNS6settings(form,step) { } } -function checkBondingSettings(form,ctrl) { +function checkBondingSettings(form, ctrl) { var disabled = form.BONDING.value=='no'; var mode = form.BONDING_MODE.value; var port = form.name.replace('_settings',''); @@ -392,7 +428,7 @@ function checkBondingSettings(form,ctrl) { if (mode==1 || mode>4 || disabled) {$('#attention0').hide();} else {$('#attention0').show();} } -function checkBridgingSettings(form,ctrl) { +function checkBridgingSettings(form, ctrl) { var port = form.name.replace('_settings',''); var step = ctrl==0 ? null : 'slow'; var i = 0; @@ -463,7 +499,7 @@ function portcheck(port) { }); } -function portToggle(port,cmd) { +function portToggle(port, cmd) { $.post('/webGui/include/PortToggle.php',{port:port,cmd:cmd},function(){refresh();}); } @@ -483,6 +519,7 @@ $(function() { checkBridgingSettings(form,0); checkNetworkAccess(form); selectProtocol(form); + selectGW(form); disableForm(form); $('#bond-eth0').dropdownchecklist('disable'); @@ -499,7 +536,7 @@ $(function() { });}); }); -function networkInfo(port,vlan) { +function networkInfo(port, vlan) { $.post('/webGui/include/NetworkInfo.php',{port:port,vlan:vlan},function(text) { swal({title:"_(Network Info)_",text:text,animation:'none',html:true,confirmButtonText:"_(Ok)_"}); }); @@ -679,7 +716,7 @@ _(IPv4 address)_: _(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* :eth_ipv4_default_gateway_help: @@ -702,7 +739,7 @@ _(IPv6 address)_: _(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* :eth_ipv6_default_gateway_help: @@ -764,6 +801,7 @@ _(IPv4 address assignment)_: + > :eth_ipv4_address_assignment_help: @@ -775,12 +813,14 @@ _(IPv4 address)_: :eth_ipv4_address_help: +
_(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* :eth_ipv4_default_gateway_help: +
@@ -792,6 +832,7 @@ _(IPv6 address assignment)_: + > :eth_ipv6_address_assignment_help: @@ -801,12 +842,14 @@ _(IPv6 address)_: :eth_ipv6_address_help: +
_(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* :eth_ipv6_default_gateway_help: +
_(IPv6 privacy extensions)_: @@ -853,6 +896,7 @@ _(IPv4 address assignment)_: + >
_(IPv4 address)_: @@ -860,10 +904,12 @@ _(IPv4 address)_: $prefix) echo mk_option(_var($eth0,"NETMASK:INDEX"), $mask, $prefix, $prefix=='24'?'selected':'');?> +
_(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* +
@@ -873,15 +919,18 @@ _(IPv6 address assignment)_: + >
_(IPv6 address)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_">/" class="slim"> +
_(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value is more preferred)_* +
_(IPv6 privacy extensions)_: diff --git a/emhttp/plugins/dynamix/EthX.page b/emhttp/plugins/dynamix/EthX.page index afa4b2fda..35a387807 100644 --- a/emhttp/plugins/dynamix/EthX.page +++ b/emhttp/plugins/dynamix/EthX.page @@ -57,6 +57,7 @@ $(function() { checkBridgingSettings(form,0); checkNetworkAccess(form); selectProtocol(form); + selectGW(form); $('div.slave-ethX').hide(); disableForm(form); @@ -169,7 +170,7 @@ _(IPv4 address assignment)_: - >_(Enable default gateway)_ + > :eth_ipv4_address_assignment_help: @@ -181,12 +182,14 @@ _(IPv4 address)_: :eth_ipv4_address_help: +
_(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* :eth_ipv4_default_gateway_help: +
@@ -196,7 +199,7 @@ _(IPv6 address assignment)_: - >_(Enable default gateway)_ + > :eth_ipv6_address_assignment_help: @@ -206,12 +209,14 @@ _(IPv6 address)_: :eth_ipv6_address_help: +
_(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* :eth_ipv6_default_gateway_help: +
_(IPv6 privacy extensions)_: @@ -271,7 +276,7 @@ _(IPv4 address assignment)_: - >_(Enable default gateway)_ + > :eth_ipv4_address_assignment_help: @@ -283,12 +288,14 @@ _(IPv4 address)_: :eth_ipv4_address_help: +
_(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* :eth_ipv4_default_gateway_help: +
@@ -298,7 +305,7 @@ _(IPv6 address assignment)_: - >_(Enable default gateway)_ + > :eth_ipv6_address_assignment_help: @@ -308,12 +315,14 @@ _(IPv6 address)_: :eth_ipv6_address_help: +
_(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* :eth_ipv6_default_gateway_help: +
_(IPv6 privacy extensions)_: @@ -361,7 +370,7 @@ _(IPv4 address assignment)_: - _(Enable default gateway)_ +
_(IPv4 address)_: @@ -369,10 +378,12 @@ _(IPv4 address)_: $prefix) echo mk_option(_var($ethX,"NETMASK:INDEX"), $mask, $prefix, $prefix=='24'?'selected':'');?> +
_(IPv4 default gateway)_: : " class="narrow" pattern="" title="_(IPv4 address A.B.C.D)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* +
@@ -382,16 +393,18 @@ _(IPv6 address assignment)_: - _(Enable default gateway)_ +
_(IPv6 address)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_">/" class="slim"> +
_(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* + " class="slim"> *_(metric value, a lower value gets preference)_* +
_(IPv6 privacy extensions)_: diff --git a/sbin/create_network_ini b/sbin/create_network_ini index 2e66c9b6b..7bb80a20b 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -23,8 +23,9 @@ declare -A VLANID USE_DHCP IPADDR NETMASK GATEWAY METRIC USE_DHCP6 IPADDR6 NETMA . /etc/rc.d/rc.runlog mask(){ + [[ -z $1 ]] && return # convert prefix to netmask - set -- $((5-(${1:-0}/8))) 255 255 255 255 $(((255<<(8-(${1:-0}%8)))&255)) 0 0 0 + 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 } @@ -123,11 +124,11 @@ 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_GW:0=\"${USE_GW[$i]}\"" >>$INI + echo "USE_GW4:0=\"${USE_GW4[$i]}\"" >>$INI if [[ ${USE_DHCP[$i]} == yes ]]; then # get dhcp assigned ipv4 address & mask - NET=($(ip -br -4 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 $IFACE | awk '{sub("/"," ",$3);print $3;exit}')) + GW=$(ip -4 route show default dev $IFACE | awk '{print $3;exit}') echo "IPADDR:0=\"${NET[0]}\"" >>$INI echo "NETMASK:0=\"$(mask ${NET[1]})\"" >>$INI echo "GATEWAY:0=\"$GW\"" >>$INI @@ -143,8 +144,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do echo "USE_GW6:0=\"${USE_GW6[$i]}\"" >>$INI if [[ ${USE_DHCP6[$i]} == yes ]]; then # get auto assigned ipv6 address & prefix - NET6=($(ip -br -6 addr show $IFACE scope global|awk '{sub("/"," ",$NF);print $NF;exit}')) - GW6=$(ip -6 route show default dev $IFACE|awk '{print $3;exit}') + 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}') echo "IPADDR6:0=\"${NET6[0]}\"" >>$INI echo "NETMASK6:0=\"${NET6[1]}\"" >>$INI echo "GATEWAY6:0=\"$GW6\"" >>$INI @@ -167,12 +168,12 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do 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_GW:$j=\"${USE_GW[$i,$j]}\"" >>$INI + 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 -br -4 addr show $DEV|awk '{sub("/"," ",$3);print $3;exit}')) - GW=$(ip -4 route show default dev $DEV|awk '{print $3;exit}') + 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}') echo "IPADDR:$j=\"${NET[0]}\"" >>$INI echo "NETMASK:$j=\"$(mask ${NET[1]})\"" >>$INI echo "GATEWAY:$j=\"$GW\"" >>$INI @@ -189,8 +190,8 @@ for ((i=0; i<${SYSNICS:-1}; i++)); do if [[ ${USE_DHCP6[$i,$j]} == yes ]]; then DEV=$IFACE.${VLANID[$i,$j]} # get auto assigned ipv6 address & prefix - NET6=($(ip -br -6 addr show $DEV scope global|awk '{sub("/"," ",$NF);print $NF;exit}')) - GW6=$(ip -6 route show default dev $DEV|awk '{print $3;exit}') + 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}') echo "IPADDR6:$j=\"${NET6[0]}\"" >>$INI echo "NETMASK6:$j=\"${NET6[1]}\"" >>$INI echo "GATEWAY6:$j=\"$GW6\"" >>$INI @@ -224,15 +225,15 @@ if [[ -z $interface || "eth0 br0 bond0 wlan0" =~ $interface ]]; then # find management interface [[ -e $SYS/bond0 ]] && dev=bond0 || dev=eth0 [[ -e $SYS/br0 ]] && dev=br0 - IPv4=$(ip -4 -br addr show $dev scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -6 -br addr show $dev scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + 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]+//') # 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 echo "Wireless network:" >>/etc/issue - IPv4=$(ip -4 -br addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -6 -br addr show wlan0 scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + 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 fi