diff --git a/alfred/Makefile b/alfred/Makefile index 8ca6ecb..8ab26e1 100644 --- a/alfred/Makefile +++ b/alfred/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=alfred PKG_VERSION:=2021.0 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/alfred/files/alfred.init b/alfred/files/alfred.init index e439be1..f191827 100755 --- a/alfred/files/alfred.init +++ b/alfred/files/alfred.init @@ -13,53 +13,9 @@ facters_dir="/etc/alfred" 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 -} - append_interface() { append "interfaces" "$1" "," - wait_for_ll_address "$1" } alfred_start() { @@ -72,7 +28,7 @@ alfred_start() { config_get_bool disabled "$section" disabled 0 [ $disabled = 0 ] || return 1 - args="" + args="-f" config_list_foreach "$section" "interface" append_interface if [ -z "$interfaces" ]; then @@ -87,10 +43,6 @@ alfred_start() { 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 - append alfred_args "$args" enable=1 diff --git a/alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch b/alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch new file mode 100644 index 0000000..cfab598 --- /dev/null +++ b/alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch @@ -0,0 +1,29 @@ +From: Sven Eckelmann +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 +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 fc27246b845af75bd1f459f8bb553aef87cc24d5..efac5ad399df52f8c444711a14bcf4814e38a3bf 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) { diff --git a/alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch b/alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch new file mode 100644 index 0000000..27d3a05 --- /dev/null +++ b/alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch @@ -0,0 +1,72 @@ +From: Sven Eckelmann +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 +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 1e2c05835cbfba02ebabefe55afc29f7ef8e12b1..7d6b0b35b5c8b8c3b087589880c390eb035584be 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 367b20730500a1c24448200a24149b64059f3381..84b0ec3827e491eead997f58b2b8f26c5b18b843 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 efac5ad399df52f8c444711a14bcf4814e38a3bf..eb2bc8aeb787e4bf028c8f9e3a523a18c6992be1 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_SECONDARY) { ++ num_interfaces = netsocket_count_interfaces(globals); ++ if (num_interfaces > 1 && globals->opmode == OPMODE_SECONDARY) { + fprintf(stderr, "More than one interface specified in secondary mode\n"); + return -1; + } diff --git a/alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch b/alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch new file mode 100644 index 0000000..a7da7df --- /dev/null +++ b/alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch @@ -0,0 +1,67 @@ +From: Sven Eckelmann +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 +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 7d6b0b35b5c8b8c3b087589880c390eb035584be..c64ff17ab9be8a16b3e1c86070b93235c226a004 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 7b866cc4275797beb7f614dd1a19ea0099e1281b..f25b6cc11975b8523abf6c59b77a86e94684b03b 100644 +--- a/main.c ++++ b/main.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -181,8 +182,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; +@@ -252,7 +253,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; +@@ -268,7 +269,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; diff --git a/alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch b/alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch new file mode 100644 index 0000000..3471dde --- /dev/null +++ b/alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch @@ -0,0 +1,102 @@ +From: Sven Eckelmann +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 +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 c64ff17ab9be8a16b3e1c86070b93235c226a004..ac082536bd6565756835489194be9b80fe0dd653 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 f25b6cc11975b8523abf6c59b77a86e94684b03b..e190d4274a0fe2abdb2c462a5bdefb3e199d4797 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}, + }; + +@@ -184,6 +185,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; +@@ -191,7 +193,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': +@@ -273,6 +275,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 25591be9ece1f8de572be8f639576861e318005f..e965db8260086cc83bc78ad95f97bc368a6cb170 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 eb2bc8aeb787e4bf028c8f9e3a523a18c6992be1..b4925e7e16ba7465662a5dbf12432916fed8bd03 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; + }