PKG_NAME:=alfred
PKG_VERSION:=2019.2
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_HASH:=b656f0e9a97a99c7531b6d49ebfd663451c16cdd275bbf7d48ff8daed3880bf2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
enable=0
vis_enable=0
-wait_for_dir() {
- local ifce="$1" dir="$2"
-
- if ! [ -d "$dir" ] ; then
- timeout=30
- echo "waiting $timeout secs for $ifce interface..."
- for i in $(seq $timeout); do
- sleep 1
- [ -d "$dir" ] && break
- if [ $i = $timeout ] ; then
- echo "$ifce not detected, alfred not starting."
- return 1
- fi
- done
- fi
-
- return 0
-}
-
-wait_for_ll_address() {
- local iface="$1"
- local timeout=30
-
- echo "waiting $timeout secs for $iface address..."
- for i in $(seq $timeout); do
- # We look for
- # - the link-local address (starts with fe80)
- # - without tentative flag (bit 0x40 in the flags field; the first char of the fifth field is evaluated)
- # - on interface $iface
- if awk '
- BEGIN { RET=1 }
- $1 ~ /^fe80/ && $5 ~ /^[012389ab]/ && $6 == "'"$iface"'" { RET=0 }
- END { exit RET }
- ' /proc/net/if_inet6; then
- return 0
- fi
- sleep 1
- done
-
- echo "$iface address not detected, alfred not starting."
- return 1
-}
-
alfred_start() {
local args=""
local section="$1"
config_get_bool disabled "$section" disabled 0
[ $disabled = 0 ] || return 1
- args=""
+ args="-f"
config_get interface "$section" interface
append args "-i $interface"
config_get batmanif "$section" batmanif
append args "-b $batmanif"
- if [ "$batmanif" != "none" ]; then
- wait_for_dir "$batmanif" "/sys/devices/virtual/net/$batmanif" || return 1
- fi
-
- wait_for_ll_address "$interface"
-
append alfred_args "$args"
enable=1
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 15 Feb 2021 19:56:22 +0100
+Subject: alfred: Show error message for invalid batadv interface
+
+The alfred server process always stopped without any informational message
+when the provided batman-adv was not "none" and was not accessible. This
+made it extremely hard to debug the reason why alfred directly stopped
+after launching it.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-1-sven@narfation.org/
+
+diff --git a/server.c b/server.c
+index 18109cc76283484a67f54fbc34f88039b9602531..47e9ae28b703da23fb930756d2971161ab332bc1 100644
+--- a/server.c
++++ b/server.c
+@@ -385,8 +385,11 @@ int alfred_server(struct globals *globals)
+ }
+
+ if (strcmp(globals->mesh_iface, "none") != 0 &&
+- batadv_interface_check(globals->mesh_iface) < 0)
++ batadv_interface_check(globals->mesh_iface) < 0) {
++ fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
++ globals->mesh_iface);
+ return -1;
++ }
+
+ num_socks = netsock_open_all(globals);
+ if (num_socks <= 0) {
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 15 Feb 2021 20:16:15 +0100
+Subject: alfred: Allow exactly one interface for secondary mode
+
+A primary alfred daemon allows syncing over more than one interface. But
+the secondary alfred daemon needs exactly one interface. But the check for
+this property was insufficient because it allowed paramters like
+"-i wlan0,asd" when wlan0 is valid and asd is not valid.
+
+The better solution is to really use the number of interfaces given to
+alfred instead of the number of interfaces evaluated as "valid".
+
+Fixes: 67ae5f57eedd ("alfred: Add support for multiple interfaces per master")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-2-sven@narfation.org/
+
+diff --git a/alfred.h b/alfred.h
+index c7ee518eb9dc02c10fe1b19cea5c928915048d97..24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f 100644
+--- a/alfred.h
++++ b/alfred.h
+@@ -182,6 +182,7 @@ int unix_sock_req_data_finish(struct globals *globals,
+ int vis_update_data(struct globals *globals);
+ /* netsock.c */
+ int netsock_open_all(struct globals *globals);
++size_t netsocket_count_interfaces(struct globals *globals);
+ void netsock_close_all(struct globals *globals);
+ int netsock_set_interfaces(struct globals *globals, char *interfaces);
+ struct interface *netsock_first_interface(struct globals *globals);
+diff --git a/netsock.c b/netsock.c
+index fcbc20be34504e271187fa9e0a120f271e622140..418b378e43144a24d4ff53544b387b1a6e7642e9 100644
+--- a/netsock.c
++++ b/netsock.c
+@@ -471,6 +471,17 @@ int netsock_open_all(struct globals *globals)
+ return num_socks;
+ }
+
++size_t netsocket_count_interfaces(struct globals *globals)
++{
++ struct interface *interface;
++ size_t count = 0;
++
++ list_for_each_entry(interface, &globals->interfaces, list)
++ count++;
++
++ return count;
++}
++
+ void netsock_reopen(struct globals *globals)
+ {
+ struct interface *interface;
+diff --git a/server.c b/server.c
+index 47e9ae28b703da23fb930756d2971161ab332bc1..95fc3bc895bf46eb775bf64d963a6eec77399dba 100644
+--- a/server.c
++++ b/server.c
+@@ -371,6 +371,7 @@ int alfred_server(struct globals *globals)
+ int maxsock, ret, recvs;
+ struct timespec last_check, now, tv;
+ fd_set fds, errfds;
++ size_t num_interfaces;
+ int num_socks;
+
+ if (create_hashes(globals))
+@@ -397,7 +398,8 @@ int alfred_server(struct globals *globals)
+ return -1;
+ }
+
+- if (num_socks > 1 && globals->opmode == OPMODE_SLAVE) {
++ num_interfaces = netsocket_count_interfaces(globals);
++ if (num_interfaces > 1 && globals->opmode == OPMODE_SLAVE) {
+ fprintf(stderr, "More than one interface specified in slave mode\n");
+ return -1;
+ }
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 15 Feb 2021 20:34:54 +0100
+Subject: alfred: Save global mode flags in bitfield
+
+The verbose and ipv4mode entries in the globals structure is only used to
+save a boolean information. So just use a bit in a bitfield to store this
+information instead of a full int.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-3-sven@narfation.org/
+
+diff --git a/alfred.h b/alfred.h
+index 24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f..f09eb497a6efe62d38891dcac2149a6473f9215a 100644
+--- a/alfred.h
++++ b/alfred.h
+@@ -115,8 +115,8 @@ struct globals {
+ enum clientmode clientmode;
+ int clientmode_arg;
+ int clientmode_version;
+- int verbose;
+- int ipv4mode;
++ uint8_t verbose:1;
++ uint8_t ipv4mode:1;
+
+ int unix_sock;
+ const char *unix_path;
+diff --git a/main.c b/main.c
+index f633462bcc55b1ae3369c42ccf8f030e671ab268..c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1 100644
+--- a/main.c
++++ b/main.c
+@@ -9,6 +9,7 @@
+ #include <arpa/inet.h>
+ #include <getopt.h>
+ #include <signal.h>
++#include <stdbool.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -184,8 +185,8 @@ static struct globals *alfred_init(int argc, char *argv[])
+ globals->clientmode_version = 0;
+ globals->mesh_iface = "bat0";
+ globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
+- globals->verbose = 0;
+- globals->ipv4mode = 0;
++ globals->verbose = false;
++ globals->ipv4mode = false;
+ globals->update_command = NULL;
+ globals->sync_period.tv_sec = ALFRED_INTERVAL;
+ globals->sync_period.tv_nsec = 0;
+@@ -253,7 +254,7 @@ static struct globals *alfred_init(int argc, char *argv[])
+ globals->unix_path = optarg;
+ break;
+ case 'd':
+- globals->verbose++;
++ globals->verbose = true;
+ break;
+ case 'c':
+ globals->update_command = optarg;
+@@ -269,7 +270,7 @@ static struct globals *alfred_init(int argc, char *argv[])
+ printf(" ** Setting sync interval to: %.9f seconds (%ld.%09ld)\n", sync_period, globals->sync_period.tv_sec, globals->sync_period.tv_nsec);
+ break;
+ case '4':
+- globals->ipv4mode = 1;
++ globals->ipv4mode = true;
+ inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
+ printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
+ break;
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 15 Feb 2021 20:52:17 +0100
+Subject: alfred: Allow start of server without valid interface
+
+The alfred server always needs interfaces to operate on. But these
+interfaces might not exist at the moment when the daemon process is
+started. This caused an error and stopped the process.
+
+But alfred is able to deal with interfaces which disappeared at runtime but
+existed at startup. To force a similar behavior for the alfred startup, the
+parameter "--force" or "-f" is introduced.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-4-sven@narfation.org/
+
+diff --git a/alfred.h b/alfred.h
+index f09eb497a6efe62d38891dcac2149a6473f9215a..5bd118cbc6052932cfad9f3eb258ceb4ce06cdc3 100644
+--- a/alfred.h
++++ b/alfred.h
+@@ -117,6 +117,7 @@ struct globals {
+ int clientmode_version;
+ uint8_t verbose:1;
+ uint8_t ipv4mode:1;
++ uint8_t force:1;
+
+ int unix_sock;
+ const char *unix_path;
+diff --git a/main.c b/main.c
+index c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1..2f77e1eb524f621391bf8ea7d56335e927e5197e 100644
+--- a/main.c
++++ b/main.c
+@@ -164,6 +164,7 @@ static struct globals *alfred_init(int argc, char *argv[])
+ {"version", no_argument, NULL, 'v'},
+ {"verbose", no_argument, NULL, 'd'},
+ {"sync-period", required_argument, NULL, 'p'},
++ {"force", no_argument, NULL, 'f'},
+ {NULL, 0, NULL, 0},
+ };
+
+@@ -187,6 +188,7 @@ static struct globals *alfred_init(int argc, char *argv[])
+ globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
+ globals->verbose = false;
+ globals->ipv4mode = false;
++ globals->force = false;
+ globals->update_command = NULL;
+ globals->sync_period.tv_sec = ALFRED_INTERVAL;
+ globals->sync_period.tv_nsec = 0;
+@@ -194,7 +196,7 @@ static struct globals *alfred_init(int argc, char *argv[])
+
+ time_random_seed();
+
+- while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:", long_options,
++ while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:f", long_options,
+ &opt_ind)) != -1) {
+ switch (opt) {
+ case 'r':
+@@ -274,6 +276,9 @@ static struct globals *alfred_init(int argc, char *argv[])
+ inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
+ printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
+ break;
++ case 'f':
++ globals->force = true;
++ break;
+ case 'h':
+ default:
+ alfred_usage();
+diff --git a/man/alfred.8 b/man/alfred.8
+index 7e31e12df0b7254e517001be5964d8c5088881e6..424633d4bdb16d25ce7b1a573cc58ab9f0dd1371 100644
+--- a/man/alfred.8
++++ b/man/alfred.8
+@@ -72,6 +72,9 @@ Collect data from the network and prints it on the network
+ \fB\-d\fP, \fB\-\-verbose\fP
+ Show extra information in the data output
+ .TP
++\fB\-d\fP, \fB\-\-force\fP
++Start server even when batman-adv or interface(s) are not yet available.
++.TP
+ \fB\-V\fP, \fB\-\-req\-version\fP \fIversion\fP
+ Specify the data version set for \fB\-s\fP
+
+diff --git a/server.c b/server.c
+index 95fc3bc895bf46eb775bf64d963a6eec77399dba..de7ddcff2de8163457bd377c8da99ab3c66ff00e 100644
+--- a/server.c
++++ b/server.c
+@@ -386,14 +386,15 @@ int alfred_server(struct globals *globals)
+ }
+
+ if (strcmp(globals->mesh_iface, "none") != 0 &&
+- batadv_interface_check(globals->mesh_iface) < 0) {
++ batadv_interface_check(globals->mesh_iface) < 0 &&
++ !globals->force) {
+ fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
+ globals->mesh_iface);
+ return -1;
+ }
+
+ num_socks = netsock_open_all(globals);
+- if (num_socks <= 0) {
++ if (num_socks <= 0 && !globals->force) {
+ fprintf(stderr, "Failed to open interfaces\n");
+ return -1;
+ }