diff --git a/modules b/modules index 767695e3de6e1ea04aa74f260bcb70a9dc300bbd..e44f5244f59d248fb0f3ce4e6b410ab18214957a 100644 --- a/modules +++ b/modules @@ -17,4 +17,4 @@ PACKAGES_LUCI_BRANCH=openwrt-18.06 PACKAGES_LUCI_COMMIT=4ba85e3d82b684262c570e38a72d2dc3bb712a13 PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git -PACKAGES_GLUON_COMMIT=be2c35785994e443d895225c7240474a46f64f5e +PACKAGES_GLUON_COMMIT=270320709166620d6f7ed0fdeb9a140966ae3fec diff --git a/package/gluon-core/files/etc/sysctl.d/30-gluon-core.conf b/package/gluon-core/files/etc/sysctl.d/30-gluon-core.conf index 12d569a0f449eb9c4b25c6778fb3f9ac6cb26b9f..c4013fe873884945a7c39f663cdf2b06e2df3143 100644 --- a/package/gluon-core/files/etc/sysctl.d/30-gluon-core.conf +++ b/package/gluon-core/files/etc/sysctl.d/30-gluon-core.conf @@ -1 +1,2 @@ vm.panic_on_oom=1 +net.ipv4.tcp_ecn=1 diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua new file mode 100644 index 0000000000000000000000000000000000000000..39e0897afda7f609dd4406fd10f77d9c029d012e --- /dev/null +++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua @@ -0,0 +1,96 @@ +local bit = require 'bit' +local string = string +local tonumber = tonumber +local table = table +module 'gluon.iputil' + +function IPv6(address) + --[[ + (c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> + (c) 2008 Steven Barth <steven@midlink.org> + + Licensed under the Apache License, Version 2.0 (the "License"). + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + ]]-- + local data = {} + + local borderl = address:sub(1, 1) == ":" and 2 or 1 + local borderh, zeroh, chunk, block + + if #address > 45 then return nil end + + repeat + borderh = address:find(":", borderl, true) + if not borderh then break end + + block = tonumber(address:sub(borderl, borderh - 1), 16) + if block and block <= 0xFFFF then + data[#data+1] = block + else + if zeroh or borderh - borderl > 1 then return nil end + zeroh = #data + 1 + end + + borderl = borderh + 1 + until #data == 7 + + chunk = address:sub(borderl) + if #chunk > 0 and #chunk <= 4 then + block = tonumber(chunk, 16) + if not block or block > 0xFFFF then return nil end + + data[#data+1] = block + elseif #chunk > 4 then + if #data == 7 or #chunk > 15 then return nil end + borderl = 1 + for i=1, 4 do + borderh = chunk:find(".", borderl, true) + if not borderh and i < 4 then return nil end + borderh = borderh and borderh - 1 + + block = tonumber(chunk:sub(borderl, borderh)) + if not block or block > 255 then return nil end + + if i == 1 or i == 3 then + data[#data+1] = block * 256 + else + data[#data] = data[#data] + block + end + + borderl = borderh and borderh + 2 + end + end + + if zeroh then + if #data == 8 then return nil end + while #data < 8 do + table.insert(data, zeroh, 0) + end + end + + if #data == 8 then + return data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] + end +end + +function mac_to_ip(prefix, mac) + local m1, m2, m3, m6, m7, m8 = string.match(mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)') + local m4 = 0xff + local m5 = 0xfe + m1 = bit.bxor(tonumber(m1, 16), 0x02) + + local h1 = 0x100 * m1 + tonumber(m2, 16) + local h2 = 0x100 * tonumber(m3, 16) + m4 + local h3 = 0x100 * m5 + tonumber(m6, 16) + local h4 = 0x100 * tonumber(m7, 16) + tonumber(m8, 16) + + local prefix, plen = string.match(prefix, '(.*)/(%d+)') + plen = tonumber(plen, 10) + + local p1, p2, p3, p4, p5, p6, p7, p8 = IPv6(prefix) + + return string.format("%x:%x:%x:%x:%x:%x:%x:%x/%d", p1, p2, p3, p4, h1, h2, h3, h4, 128) +end + diff --git a/package/gluon-iptables-clamp-mss-to-pmtu/files/lib/gluon/mesh-vpn/iptables-mss.rules b/package/gluon-iptables-clamp-mss-to-pmtu/files/lib/gluon/mesh-vpn/iptables-mss.rules index a4ff50b13dd02d05250a8a4d300e56b95ad71a20..a61a900df5ccded0d164d43fac1c3567fada6443 100644 --- a/package/gluon-iptables-clamp-mss-to-pmtu/files/lib/gluon/mesh-vpn/iptables-mss.rules +++ b/package/gluon-iptables-clamp-mss-to-pmtu/files/lib/gluon/mesh-vpn/iptables-mss.rules @@ -1,3 +1,3 @@ *mangle --A FORWARD -o mesh-vpn -p tcp -m tcp --tcp-flags SYN,RST SYN -d 64:ff9b::/96 -j TCPMSS --clamp-mss-to-pmtu +-A FORWARD -o mesh-vpn+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu COMMIT diff --git a/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd b/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd index c64f3b1d8b5a1e2a7e841cb9d859420ceca1299d..fb1ecdfc04897bb053c4bbc85bad6db368716da7 100755 --- a/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd +++ b/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd @@ -5,10 +5,39 @@ START=55 USE_PROCD=1 PROG=/usr/sbin/l3roamd +echotol3roamd() { + local count=0 + local line="$1" + while ! (echo -e "$line" | uc /var/run/l3roamd.sock >/dev/null 2>&1) + do + sleep 1 + echo retrying to connect to l3roamd in PID $$, waited ${count}s >&2 + count=$((count+1)) + done + return 0 +} + + + +reload_service() { + for i in $(ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device") + do + echotol3roamd "add_meshif $i" + done + + for i in $(echotol3roamd "get_meshifs"| jsonfilter -e "@.mesh_interfaces[@]") + do + if ! ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device"|grep -q $i + then + echotol3roamd "del_meshif $i" + fi + done +} + start_service () { local interfaces=$( - for dev in $(gluon-list-mesh-interfaces); do echo " -m $dev"; done - [ "$(ifstatus local_node | jsonfilter -e '@.up')" = 'true' ] && echo ' -i local-node' + for dev in $(gluon-list-mesh-interfaces); do echo " -m $dev"; done + [ "$(ifstatus local_node | jsonfilter -e '@.up')" = 'true' ] && echo ' -i local-node' ) /sbin/sysctl -w net.ipv6.neigh.default.gc_thresh1=2 /sbin/sysctl -w net.ipv4.neigh.default.gc_thresh1=2 diff --git a/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel b/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel index e902f8cb468fa8cf61974b1988669b959f889c23..2d04ff5386b053b45d4ca56ecfd4c98016711825 100755 --- a/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel +++ b/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel @@ -22,11 +22,15 @@ start_service() { echotobabel() { local count=0 local line="$1" - while ! (echo -e "$line" | nc ::1 "$PORT" >/dev/null 2>&1) + local maxretries=10 + while ! (echo -e "$line" | busybox nc ::1 "$PORT" >/dev/null 2>&1) do sleep 1 echo retrying to connect to babeld in PID $$, waited ${count}s >&2 count=$((count+1)) + if [ $count -gt $maxretries ]; then + return 1 + fi done return 0 } diff --git a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 index 7ab3f5ec25c6fa1445825a9a2a60e017f0a2c348..1d3f538176f573965fc0aebc935217b8b36d5bdf 100755 --- a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 +++ b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 @@ -1,102 +1,11 @@ #!/usr/bin/lua -local bit = require 'bit' local sysconfig = require 'gluon.sysconfig' local uci = require('simple-uci').cursor() local site = require 'gluon.site' +local iputil = require 'gluon.iputil' - -function IPv6(address) - --[[ - (c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - (c) 2008 Steven Barth <steven@midlink.org> - - Licensed under the Apache License, Version 2.0 (the "License"). - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - ]]-- - local data = {} - - local borderl = address:sub(1, 1) == ":" and 2 or 1 - local borderh, zeroh, chunk, block - - if #address > 45 then return nil end - - repeat - borderh = address:find(":", borderl, true) - if not borderh then break end - - block = tonumber(address:sub(borderl, borderh - 1), 16) - if block and block <= 0xFFFF then - data[#data+1] = block - else - if zeroh or borderh - borderl > 1 then return nil end - zeroh = #data + 1 - end - - borderl = borderh + 1 - until #data == 7 - - chunk = address:sub(borderl) - if #chunk > 0 and #chunk <= 4 then - block = tonumber(chunk, 16) - if not block or block > 0xFFFF then return nil end - - data[#data+1] = block - elseif #chunk > 4 then - if #data == 7 or #chunk > 15 then return nil end - borderl = 1 - for i=1, 4 do - borderh = chunk:find(".", borderl, true) - if not borderh and i < 4 then return nil end - borderh = borderh and borderh - 1 - - block = tonumber(chunk:sub(borderl, borderh)) - if not block or block > 255 then return nil end - - if i == 1 or i == 3 then - data[#data+1] = block * 256 - else - data[#data] = data[#data] + block - end - - borderl = borderh and borderh + 2 - end - end - - if zeroh then - if #data == 8 then return nil end - while #data < 8 do - table.insert(data, zeroh, 0) - end - end - - if #data == 8 then - return data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] - end -end - -function mac_to_ip(prefix, mac) - local m1, m2, m3, m6, m7, m8 = string.match(mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)') - local m4 = 0xff - local m5 = 0xfe - m1 = bit.bxor(tonumber(m1, 16), 0x02) - - local h1 = 0x100 * m1 + tonumber(m2, 16) - local h2 = 0x100 * tonumber(m3, 16) + m4 - local h3 = 0x100 * m5 + tonumber(m6, 16) - local h4 = 0x100 * tonumber(m7, 16) + tonumber(m8, 16) - - local prefix, plen = string.match(prefix, '(.*)/(%d+)') - plen = tonumber(plen, 10) - - local p1, p2, p3, p4, p5, p6, p7, p8 = IPv6(prefix) - - return string.format("%x:%x:%x:%x:%x:%x:%x:%x/%d", p1, p2, p3, p4, h1, h2, h3, h4, 128) -end - -local ip = mac_to_ip(site.node_prefix6(), sysconfig.primary_mac) +local ip = iputil.mac_to_ip(site.node_prefix6(), sysconfig.primary_mac) uci:set('network', 'loopback', 'ip6addr', ip) uci:save('network') diff --git a/package/gluon-mesh-babel/src/respondd.c b/package/gluon-mesh-babel/src/respondd.c index 733e9abb795dd4e0eb0393994698401aa86565f7..075aa0649951bd6ab33db5533cf14795da6f9cdb 100644 --- a/package/gluon-mesh-babel/src/respondd.c +++ b/package/gluon-mesh-babel/src/respondd.c @@ -47,6 +47,7 @@ #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/un.h> +#include <ifaddrs.h> #include <linux/ethtool.h> #include <linux/if_addr.h> @@ -78,30 +79,41 @@ static struct babelhelper_ctx bhelper_ctx = {}; -static int obtain_ifmac(unsigned char *ifmac, const char *ifname) { - struct ifreq ifr = {}; - int sock; +static void obtain_if_addr(const char *ifname, char *lladdr) { + struct ifaddrs *ifaddr, *ifa; + int family, n; - sock=socket(PF_INET, SOCK_STREAM, 0); - if (-1==sock) { - perror("socket() "); - return 1; + if (getifaddrs(&ifaddr) == -1) { + perror("getifaddrs"); + exit(EXIT_FAILURE); } - strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); + for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { + if (ifa->ifa_addr == NULL) + continue; + + family = ifa->ifa_addr->sa_family; + + if ( (family == AF_INET6) && ( ! strncmp(ifname, ifa->ifa_name, strlen(ifname)) ) ) { + char lhost[INET6_ADDRSTRLEN]; + struct in6_addr *address = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr; + if (inet_ntop(AF_INET6, address, lhost, INET6_ADDRSTRLEN) == NULL) { + fprintf(stderr, "obtain_if_addr: could not convert ip to string\n"); + goto cleanup; + } - printf("obtaining hw address for nic: %s %s\n", ifname, ifr.ifr_name); - if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { - perror("ioctl(SIOCGIFHWADDR) "); - close(sock); - return 1; + if (! strncmp("fe80:", lhost, 5) ) { + snprintf( lladdr, NI_MAXHOST, "%s", lhost ); + goto cleanup; + } + } } - close(sock); - memcpy(ifmac, ifr.ifr_hwaddr.sa_data, 6); - return 0; +cleanup: + freeifaddrs(ifaddr); } + static char* get_line_from_run(const char* command) { FILE *fp; char *line = NULL; @@ -167,34 +179,11 @@ static bool interface_file_exists(const char *ifname, const char *name) { return !access(path, F_OK); } -struct in6_addr mac2ipv6(uint8_t mac[6], char * prefix) { - struct in6_addr address = {}; - inet_pton(AF_INET6, prefix, &address); - - address.s6_addr[8] = mac[0] ^ 0x02; - address.s6_addr[9] = mac[1]; - address.s6_addr[10] = mac[2]; - address.s6_addr[11] = 0xff; - address.s6_addr[12] = 0xfe; - address.s6_addr[13] = mac[3]; - address.s6_addr[14] = mac[4]; - address.s6_addr[15] = mac[5]; - - return address; -} - static void mesh_add_if(const char *ifname, struct json_object *wireless, struct json_object *tunnel, struct json_object *other) { - char str_ip[INET6_ADDRSTRLEN] = {}; - unsigned char mac[6] = {}; + char str_ip[NI_MAXHOST] = {}; - if (obtain_ifmac(mac, ifname)) { - printf("could not obtain mac for device: %s", ifname); - return; - } - - struct in6_addr lladdr = mac2ipv6(mac, "fe80::"); - inet_ntop(AF_INET6, &lladdr.s6_addr, str_ip, INET6_ADDRSTRLEN); + obtain_if_addr(ifname, str_ip); struct json_object *address = json_object_new_string(str_ip); @@ -206,6 +195,8 @@ static void mesh_add_if(const char *ifname, struct json_object *wireless, json_object_array_add(other, address); } + + static bool handle_neighbour(char **data, void *obj) { if (data[NEIGHBOUR]) { struct json_object *neigh = json_object_new_object(); @@ -221,17 +212,10 @@ static bool handle_neighbour(char **data, void *obj) { struct json_object *nif = 0; if (data[IF] && !json_object_object_get_ex(obj, data[IF], &nif)) { - nif = json_object_new_object(); - - unsigned char ifmac[6] = {}; - char str_ip[INET6_ADDRSTRLEN] = {}; + char str_ip[NI_MAXHOST] = {}; + obtain_if_addr( (const char*)data[IF], str_ip ); - if (obtain_ifmac(ifmac, (const char*)data[IF])) { - printf("could not obtain mac for device: %s", data[IF]); - return false; - } - struct in6_addr lladdr = mac2ipv6(ifmac, "fe80::"); - inet_ntop(AF_INET6, &lladdr.s6_addr, str_ip, INET6_ADDRSTRLEN); + nif = json_object_new_object(); json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip)); json_object_object_add(nif, "protocol", json_object_new_string("babel"));