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
This commit is contained in:
Yan Gao 2020-10-28 10:48:33 +00:00 committed by Git OBS Bridge
parent 64213a0370
commit 029ad67989
3 changed files with 211 additions and 0 deletions

View File

@ -0,0 +1,200 @@
From d963c2ab6cac0bf18355159afd815c0eb78e4aa8 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
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 <aburlakov@suse.com> who brought idea
(and implementation) of using totemip_getif_scopeid.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
---
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 <stdlib.h>
#include <unistd.h>
#include <ifaddrs.h>
+#include <corosync/logsys.h>
#include <corosync/totem/totemip.h>
#include <corosync/swab.h>
@@ -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,

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Tue Oct 27 14:25:29 UTC 2020 - Aleksei Burlakov <aburlakov@suse.com>
- (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 <dimstar@opensuse.org>

View File

@ -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}