diff --git a/openwisp-config/files/lib/openwisp/net.lua b/openwisp-config/files/lib/openwisp/net.lua index cf97ce3..aedb1c1 100644 --- a/openwisp-config/files/lib/openwisp/net.lua +++ b/openwisp-config/files/lib/openwisp/net.lua @@ -2,9 +2,20 @@ local nixio = require('nixio') local uci = require('uci') local net = {} -function net.get_interface(name, family) +function net.get_interface(name, family, ula) local uci_cursor = uci.cursor() - local ip_family = family or 'inet' + local ip_family + if family == 'inet6' then + ip_family = 'inet6' + else + ip_family = 'inet' + end + local ip_ula + if ula == '1' then + ip_ula = true + else + ip_ula = false + end -- if UCI network name is a bridge, the ifname won't be the name of the bridge local is_bridge = uci_cursor:get('network', name, 'type') == 'bridge' local ifname @@ -15,11 +26,28 @@ function net.get_interface(name, family) -- default to supplied name if none is found ifname = uci_cursor:get('network', name, 'ifname') or name end - -- get list of interfaces and loop until found + -- get list of interfaces local interfaces = nixio.getifaddrs() + -- sort list of interfaces by addr (2001:xx:xx:xx::1,fd52:xx:xx::1,fe80::xx:xx:xx:901a) + table.sort(interfaces, function (left, right) + return left['addr'] < right['addr'] + end) + -- loop until found for _, interface in pairs(interfaces) do if interface.name == ifname and interface.family == ip_family then - return interface + if ip_family == 'inet6' then + -- check if limklocal fe80::xx:xx:xx:xx addr + if string.find(interface.addr,'fe') ~= 1 then + -- check if ula fd52:xx:xx::1 addr + if not ip_ula and string.find(interface.addr,'fd') ~= 1 then + return interface + elseif ip_ula then + return interface + end + end + else + return interface + end end end -- return nil if nothing is found diff --git a/openwisp-config/files/openwisp.agent b/openwisp-config/files/openwisp.agent index 797e63e..105d03a 100755 --- a/openwisp-config/files/openwisp.agent +++ b/openwisp-config/files/openwisp.agent @@ -101,6 +101,14 @@ while [ -n "$1" ]; do export MANAGEMENT_INTERFACE="$2" shift ;; + --management-interface-family) + export MANAGEMENT_INTERFACE_FAMILY="$2" + shift + ;; + --management-interface-ula) + export MANAGEMENT_INTERFACE_ULA="$2" + shift + ;; --default-hostname) export DEFAULT_HOSTNAME="$2" shift @@ -245,7 +253,7 @@ fi # if management interface is not ready, the ip will be empty but other # attempts at determining it will be done before the start-up is completed if [ -n "$MANAGEMENT_INTERFACE" ]; then - MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE") + MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE" "$MANAGEMENT_INTERFACE_FAMILY" "$MANAGEMENT_INTERFACE_ULA") fi get_model() { cat /tmp/sysinfo/model; } @@ -876,7 +884,7 @@ discover_management_ip() { unset REGISTER_CALLED return fi - MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE") + MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE" "$MANAGEMENT_INTERFACE_FAMILY" "$MANAGEMENT_INTERFACE_ULA") # if management interface is defined but its ip could not be determined # and the shared secret is not present anymore # (which means the device has been already registered) @@ -884,7 +892,7 @@ discover_management_ip() { if [ -z "$MANAGEMENT_IP" ] && [ -z "$SHARED_SECRET" ]; then MAX_ATTEMPTS=3 for attempt in $(seq $MAX_ATTEMPTS); do - MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE") + MANAGEMENT_IP=$(/usr/sbin/openwisp-get-address "$MANAGEMENT_INTERFACE" "$MANAGEMENT_INTERFACE_FAMILY" "$MANAGEMENT_INTERFACE_ULA") if [ -z "$MANAGEMENT_IP" ]; then logger -s "management interface not ready (attempt $attempt of $MAX_ATTEMPTS)" \ diff --git a/openwisp-config/files/openwisp.config b/openwisp-config/files/openwisp.config index 3721c75..72467a2 100644 --- a/openwisp-config/files/openwisp.config +++ b/openwisp-config/files/openwisp.config @@ -12,6 +12,11 @@ config controller 'http' #option mac_interface 'eth0' #option management_interface 'tun0' #option default_hostname 'OpenWrt' + # for IPv4 backward compatibility use "inet" or leave it blank. default prio is "inet" then "inet6" + # new installation starts with ipv6 as default by config. Year's later we can switch to inet6 by default :-) + option management_interface_family 'inet6' + # report IPv6 ula addr. default is 0 + #option management_interface_ula '1' #option merge_config '1' #option tags '' #option test_config '1' diff --git a/openwisp-config/files/openwisp.init b/openwisp-config/files/openwisp.init index 45f19dc..4468553 100755 --- a/openwisp-config/files/openwisp.init +++ b/openwisp-config/files/openwisp.init @@ -45,6 +45,8 @@ parse_config() { add_option "$cfg" "--cacert" cacert add_option "$cfg" "--mac-interface" mac_interface add_option "$cfg" "--management-interface" management_interface + add_option "$cfg" "--management-interface-family" management_interface_family + add_option "$cfg" "--management-interface-ula" management_interface_ula add_option "$cfg" "--default-hostname" default_hostname add_option "$cfg" "--pre-reload-hook" pre_reload_hook add_option "$cfg" "--post-reload-hook" post_reload_hook diff --git a/openwisp-config/files/sbin/openwisp-get-address.lua b/openwisp-config/files/sbin/openwisp-get-address.lua index 645d3cb..55366b1 100755 --- a/openwisp-config/files/sbin/openwisp-get-address.lua +++ b/openwisp-config/files/sbin/openwisp-get-address.lua @@ -2,13 +2,15 @@ -- gets the first useful address of the specified interface -- usage: --- * openwisp-get-address --- * openwisp-get-address +-- * openwisp-get-address ["inet"|"inet6"] [ula 1|0] +-- * openwisp-get-address ["inet"|"inet6"] [ula 1|0] local os = require('os') local net = require('openwisp.net') local name = arg[1] -local interface = net.get_interface(name, 'inet') -if not interface then +local family = arg[2] +local ula = arg[3] +local interface = net.get_interface(name, family, ula) +if not interface and family ~= 'inet6' then interface = net.get_interface(name, 'inet6') end