From 029ad67989b2c46e6600efac3ba28e5f90ca6d11c5c1ed7c295f49b7314f8d01 Mon Sep 17 00:00:00 2001 From: Yan Gao Date: Wed, 28 Oct 2020 10:48:33 +0000 Subject: [PATCH] Accepting request 844361 from home:aburlakov:branches:network:ha-clustering:Factory - (Again) Fix bsc#1163460 Corosync does not support link-local IPv6 addresses Added: bug-1163460-totemip-Add-support-for-sin6_scope_id.patch Reason: This time the path will NOT cause problems when doing rolling upgrade, see bsc#1168771 OBS-URL: https://build.opensuse.org/request/show/844361 OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/corosync?expand=0&rev=175 --- ...otemip-Add-support-for-sin6_scope_id.patch | 200 ++++++++++++++++++ corosync.changes | 9 + corosync.spec | 2 + 3 files changed, 211 insertions(+) create mode 100644 bug-1163460-totemip-Add-support-for-sin6_scope_id.patch diff --git a/bug-1163460-totemip-Add-support-for-sin6_scope_id.patch b/bug-1163460-totemip-Add-support-for-sin6_scope_id.patch new file mode 100644 index 0000000..e3ce00e --- /dev/null +++ b/bug-1163460-totemip-Add-support-for-sin6_scope_id.patch @@ -0,0 +1,200 @@ +From d963c2ab6cac0bf18355159afd815c0eb78e4aa8 Mon Sep 17 00:00:00 2001 +From: Jan Friesse +Date: Mon, 27 Jul 2020 16:10:54 +0200 +Subject: [PATCH] totemip: Add support for sin6_scope_id + +sin6_scope_id is not present in totemip structure making impossible to +use link-local ipv6 address. + +Patch adds new call totemip_totemip_to_sockaddr_convert_with_scopeid +which can be instructed to fill scope id. This function calls +totemip_getif_scopeid which walks local addresses and returns +scope id if interface matches. + +Main difference between this patch and +934c47ed4384daf2819c26306bebba3225807499 is fact, that totemip +structure keeps unchanged so corosync stays wire compatible. + +This makes corosync work with link-local addresses fine for both UDPU +and UDP transport as long as there is only one matching interface with +this patch. + +Big thanks to Aleksei Burlakov who brought idea +(and implementation) of using totemip_getif_scopeid. + +Signed-off-by: Jan Friesse +Reviewed-by: Christine Caulfield +--- + exec/totemip.c | 69 ++++++++++++++++++++++++++++++-- + exec/totemudp.c | 7 ++-- + exec/totemudpu.c | 6 ++- + include/corosync/totem/totemip.h | 4 ++ + 4 files changed, 77 insertions(+), 9 deletions(-) + +diff --git a/exec/totemip.c b/exec/totemip.c +index f89c70a04..4f08f5375 100644 +--- a/exec/totemip.c ++++ b/exec/totemip.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -267,11 +268,58 @@ const char *totemip_print(const struct totem_ip_address *addr) + return (inet_ntop(addr->family, addr->addr, buf, sizeof(buf))); + } + +-/* Make a totem_ip_address into a usable sockaddr_storage */ +-int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, +- uint16_t port, struct sockaddr_storage *saddr, int *addrlen) ++static int totemip_getif_scopeid(const unsigned char *addr16, unsigned int *scopeid) ++{ ++ struct ifaddrs *ifa; ++ const struct sockaddr_in6 *sin6; ++ const socklen_t addr_len = sizeof(struct in6_addr); ++ int rc = -1; // 0 = found 1 match; -1 = found 0 matches; -2 = found >1 matches ++ struct ifaddrs *totemip_getif_scopeid_ifap; ++ ++ if (getifaddrs(&totemip_getif_scopeid_ifap) != 0) { ++ return (-1); ++ } ++ ++ for (ifa = totemip_getif_scopeid_ifap; ifa; ifa = ifa->ifa_next) { ++ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) ++ continue ; ++ ++ if ((ifa->ifa_addr->sa_family != AF_INET6) || ++ (ifa->ifa_netmask->sa_family != AF_INET6 && ++ ifa->ifa_netmask->sa_family != 0)) ++ continue ; ++ ++ sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr; ++ ++ if (memcmp(&sin6->sin6_addr, addr16, addr_len) == 0) { ++ *scopeid = sin6->sin6_scope_id; ++ ++ if (rc == -1) { ++ rc = 0; ++ } else { ++ rc = -2; ++ } ++ } ++ } ++ ++ if (rc == -2) { ++ log_printf(LOGSYS_LEVEL_WARNING, "(%s) exists on several interfaces." ++ " Use 'ip a' to see details.", ++ totemip_sa_print(ifa->ifa_addr)); ++ } ++ ++ freeifaddrs(totemip_getif_scopeid_ifap); ++ ++ return rc; ++} ++ ++ ++int totemip_totemip_to_sockaddr_convert_with_scopeid(const struct totem_ip_address *ip_addr, ++ uint16_t port, struct sockaddr_storage *saddr, int *addrlen, ++ int fill_scopeid) + { + int ret = -1; ++ unsigned int scopeid; + + if (ip_addr->family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; +@@ -296,7 +344,11 @@ int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, + #endif + sin->sin6_family = ip_addr->family; + sin->sin6_port = ntohs(port); +- sin->sin6_scope_id = 2; ++ if (fill_scopeid) { ++ if (totemip_getif_scopeid(ip_addr->addr, &scopeid) == 0) { ++ sin->sin6_scope_id = scopeid; ++ } ++ } + memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr)); + + *addrlen = sizeof(struct sockaddr_in6); +@@ -306,6 +358,15 @@ int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, + return ret; + } + ++/* Make a totem_ip_address into a usable sockaddr_storage */ ++int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, ++ uint16_t port, struct sockaddr_storage *saddr, int *addrlen) ++{ ++ ++ return (totemip_totemip_to_sockaddr_convert_with_scopeid(ip_addr, port, saddr, addrlen, 0)); ++} ++ ++ + /* Converts an address string string into a totem_ip_address. + family can be AF_INET, AF_INET6 or 0 ("for "don't care") + */ +diff --git a/exec/totemudp.c b/exec/totemudp.c +index 4b644aee3..c11bbe8e6 100644 +--- a/exec/totemudp.c ++++ b/exec/totemudp.c +@@ -834,8 +834,8 @@ static int totemudp_build_sockets_ip ( + return (-1); + } + +- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port - 1, +- &sockaddr, &addrlen); ++ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port - 1, ++ &sockaddr, &addrlen, 1); + + retries = 0; + while (1) { +@@ -890,7 +890,8 @@ static int totemudp_build_sockets_ip ( + * Bind to unicast socket used for token send/receives + * This has the side effect of binding to the correct interface + */ +- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen); ++ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port, ++ &sockaddr, &addrlen, 1); + + retries = 0; + while (1) { +diff --git a/exec/totemudpu.c b/exec/totemudpu.c +index f9d50af26..1d9410f65 100644 +--- a/exec/totemudpu.c ++++ b/exec/totemudpu.c +@@ -824,7 +824,9 @@ static int totemudpu_build_sockets_ip ( + * Bind to unicast socket used for token send/receives + * This has the side effect of binding to the correct interface + */ +- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen); ++ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port, ++ &sockaddr, &addrlen, 1); ++ + while (1) { + res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen); + if (res == 0) { +@@ -1331,7 +1333,7 @@ static int totemudpu_create_sending_socket( + /* + * Bind to sending interface + */ +- totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen); ++ totemip_totemip_to_sockaddr_convert_with_scopeid(&instance->my_id, 0, &sockaddr, &addrlen, 1); + res = bind (fd, (struct sockaddr *)&sockaddr, addrlen); + if (res == -1) { + LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning, +diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h +index 891a0524b..2a63317b1 100644 +--- a/include/corosync/totem/totemip.h ++++ b/include/corosync/totem/totemip.h +@@ -97,6 +97,10 @@ extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, + uint16_t port, struct sockaddr_storage *saddr, int *addrlen); + extern int totemip_parse(struct totem_ip_address *totemip, const char *addr, + int family); ++extern int totemip_totemip_to_sockaddr_convert_with_scopeid(const struct totem_ip_address *ip_addr, ++ uint16_t port, struct sockaddr_storage *saddr, int *addrlen, ++ int fill_scopeid); ++ + extern int totemip_iface_check(struct totem_ip_address *bindnet, + struct totem_ip_address *boundto, + int *interface_up, diff --git a/corosync.changes b/corosync.changes index bd4c622..cf63ea5 100644 --- a/corosync.changes +++ b/corosync.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Oct 27 14:25:29 UTC 2020 - Aleksei Burlakov + +- (Again) Fix bsc#1163460 Corosync does not support link-local IPv6 addresses + Added: bug-1163460-totemip-Add-support-for-sin6_scope_id.patch + + Reason: This time the path will NOT cause problems when doing rolling + upgrade, see bsc#1168771 + ------------------------------------------------------------------- Wed Aug 19 10:18:14 UTC 2020 - Dominique Leuenberger diff --git a/corosync.spec b/corosync.spec index a1e40e0..0ef95c2 100644 --- a/corosync.spec +++ b/corosync.spec @@ -63,6 +63,7 @@ Patch7: corosync-2.3.4-fix-bashisms.patch Patch8: corosync-init-lockfile-path-error.patch Patch9: corosync-start-stop-level.patch Patch10: bug-1166899-quorumtool-Fix-exit-status-codes.patch +Patch11: bug-1163460-totemip-Add-support-for-sin6_scope_id.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build # openais is indeed gone and should be uninstalled. Yes, we do not @@ -138,6 +139,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 %build %if %{with runautogen}