From b90d214da9926f2a351e411359d2c5e955e39ef8 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Mon, 5 Nov 2018 20:53:05 +0100 Subject: [PATCH 1/8] gluon-iptables-clamp-mss-to-pmtu: clamp mss on all mesh interfaces for all destinations to pmtu --- .../files/lib/gluon/mesh-vpn/iptables-mss.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a4ff50b1..a61a900d 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 From bd96bd40246883c0a4d53e95e9c03a3bb43740e4 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Sat, 1 Sep 2018 00:39:44 +0200 Subject: [PATCH 2/8] gluon-mesh-babel: explicitly specify the use of the busybox netcat --- package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e902f8cb..338bc453 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,7 +22,7 @@ start_service() { echotobabel() { local count=0 local line="$1" - while ! (echo -e "$line" | nc ::1 "$PORT" >/dev/null 2>&1) + 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 From c23e6e4b531e3245ffc7b2c026bc511d4c6a7e55 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Mon, 3 Sep 2018 00:52:30 +0200 Subject: [PATCH 3/8] gluon-mesh-babel: babel-respond: stop relying on mac addresses and instead obtain ll-address from nic --- package/gluon-mesh-babel/src/respondd.c | 86 ++++++++++--------------- 1 file changed, 35 insertions(+), 51 deletions(-) diff --git a/package/gluon-mesh-babel/src/respondd.c b/package/gluon-mesh-babel/src/respondd.c index 733e9abb..075aa064 100644 --- a/package/gluon-mesh-babel/src/respondd.c +++ b/package/gluon-mesh-babel/src/respondd.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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; - 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; + 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; + } + + 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,18 +212,11 @@ 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)) { + char str_ip[NI_MAXHOST] = {}; + obtain_if_addr( (const char*)data[IF], str_ip ); + nif = json_object_new_object(); - unsigned char ifmac[6] = {}; - char str_ip[INET6_ADDRSTRLEN] = {}; - - 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); - json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip)); json_object_object_add(nif, "protocol", json_object_new_string("babel")); json_object_object_add(obj, data[IF], nif); From 171c293ebeb267917d8c804b67c49ba9e5aa906e Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Wed, 3 Oct 2018 18:33:00 +0200 Subject: [PATCH 4/8] gluon-core, gluon-mesh-babel: move lua functions that generate ll-addresses from a mac into gluon-core --- .../luasrc/usr/lib/lua/gluon/iputil.lua | 96 +++++++++++++++++++ .../gluon/upgrade/300-gluon-mesh-babel-ip6 | 95 +----------------- 2 files changed, 98 insertions(+), 93 deletions(-) create mode 100644 package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua 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 00000000..39e0897a --- /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 + (c) 2008 Steven Barth + + 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-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 7ab3f5ec..1d3f5381 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 - (c) 2008 Steven Barth - - 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') From a3d9446a3a539b5d5ca312fbef37a5bf83b865d4 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Wed, 3 Oct 2018 15:15:48 +0200 Subject: [PATCH 5/8] modules: update packages 2703207 libbabelhelper: bump version, correct error handling on babel socket 8e768b3 mmfd: bump version, include babeld reconnect fix 9e0b9bb l3roamd: allow to del_meshif for initially specified interfaces and get_meshifs on socket 54fac53 micrond: add PKG_LICENSE value d2c162f bump libbabelhelper version 9eb42b8 bump mmfd version 8fcc217 libbabelhelper: bump version a5815a3 bump mmfd 50874ee respondd: add documentation for some protocol related functions (#194) 00c6b72 uc: add new package (#192) c56ec3a mmfd: bump version 521246b l3roamd: bump version, fixing a crash, increasing efficiency and roaming stability by introducing ACK --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 87b1f179..d033e85d 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 From 89b7612fdbabd92ccfd0496fce568187d4e11081 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Mon, 19 Nov 2018 07:21:02 +0100 Subject: [PATCH 6/8] gluon-l3roamd: init: dynamically configure mesh interfaces gracefully during reload This patch makes use of the new feature in l3roamd to gracefully add, remove and list the mesh interfaces that are currently in use. This helps when changing mesh interfaces often - a characteristic of the wireguard protocol implementation as in the previous behavior all local clients are dropped when adjusting mesh interfaces. --- .../files/etc/init.d/gluon-l3roamd | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd b/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd index c64f3b1d..fb1ecdfc 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 From e5b238e04aa3400777b95735af784316e6dc0e27 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Thu, 22 Nov 2018 23:51:54 +0100 Subject: [PATCH 7/8] gluon-mesh-babel: exit with error if unable to connect to babeld --- package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel | 4 ++++ 1 file changed, 4 insertions(+) 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 338bc453..2d04ff53 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" + 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 } From 62406509fc0c88d7a152613486195a82413e6982 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Mon, 26 Nov 2018 00:21:24 +0100 Subject: [PATCH 8/8] gluon-core: enable ECN --- package/gluon-core/files/etc/sysctl.d/30-gluon-core.conf | 1 + 1 file changed, 1 insertion(+) 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 12d569a0..c4013fe8 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