From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 06DD25A005E for ; Wed, 16 Nov 2022 05:42:26 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4NBr4R4Gynz4xyP; Wed, 16 Nov 2022 15:42:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1668573735; bh=PVIqOY1TFiSxwfPm309sEuOTTA3iI0n+t3XQMK2LJ2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J3GZa60mH0i6SfBpmdWI7rdCbS+yLlzJci4CArXvRyPJJRDvLqBWSHP6/mdWyVLLe fJepeqwt0n9D1jxwshvF4U8yeVkK/rQ+w8k5KhutaC90hybv4gThPtbW39+Wo78YXj iYDGIMffPfkMx/mR7LkD4sOghpNR++ylpo1ZqMPg= From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 30/32] util: Allow sock_l4() to open dual stack sockets Date: Wed, 16 Nov 2022 15:42:10 +1100 Message-Id: <20221116044212.3876516-31-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221116044212.3876516-1-david@gibson.dropbear.id.au> References: <20221116044212.3876516-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: STHDRAYAVRUTRUF4QKHNBXGFJTS5E4K3 X-Message-ID-Hash: STHDRAYAVRUTRUF4QKHNBXGFJTS5E4K3 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.3 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Currently, when instructed to open an IPv6 socket, sock_l4() explicitly sets the IPV6_V6ONLY socket option so that the socket will only respond to IPv6 connections. Linux (and probably other platforms) allow "dual stack" sockets: IPv6 sockets which can also accept IPv4 connections. Extend sock_l4() to be able to make such sockets, by passing AF_UNSPEC as the address family and no bind address (binding to a specific address would defeat the purpose). We add a Makefile define 'DUAL_STACK_SOCKETS' to indicate availability of this feature on the target platform. Signed-off-by: David Gibson --- Makefile | 5 +++++ util.c | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ca453aa..0f92db5 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,10 @@ VERSION ?= $(shell git describe --tags HEAD 2>/dev/null || echo "unknown\ version") +# Does the target platform allow IPv4 connections to be handled via +# the IPv6 socket API? (Linux does) +DUAL_STACK_SOCKETS := 1 + RLIMIT_STACK_VAL := $(shell /bin/sh -c 'ulimit -s') ifeq ($(RLIMIT_STACK_VAL),unlimited) RLIMIT_STACK_VAL := 1024 @@ -34,6 +38,7 @@ FLAGS += -DPASST_AUDIT_ARCH=AUDIT_ARCH_$(AUDIT_ARCH) FLAGS += -DRLIMIT_STACK_VAL=$(RLIMIT_STACK_VAL) FLAGS += -DARCH=\"$(TARGET_ARCH)\" FLAGS += -DVERSION=\"$(VERSION)\" +FLAGS += -DDUAL_STACK_SOCKETS=$(DUAL_STACK_SOCKETS) PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c icmp.c igmp.c \ isolation.c lineread.c log.c mld.c ndp.c netlink.c packet.c passt.c \ diff --git a/util.c b/util.c index 514bd44..fc629ed 100644 --- a/util.c +++ b/util.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "util.h" #include "passt.h" @@ -112,6 +114,7 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, 0, IN6ADDR_ANY_INIT, 0, }; const struct sockaddr *sa; + bool dual_stack = false; struct epoll_event ev; int fd, sl, y = 1; @@ -119,6 +122,13 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6) return -1; /* Not implemented. */ + if (af == AF_UNSPEC) { + if (!DUAL_STACK_SOCKETS || bind_addr) + return -1; + dual_stack = true; + af = AF_INET6; + } + if (proto == IPPROTO_TCP) fd = socket(af, SOCK_STREAM | SOCK_NONBLOCK, proto); else @@ -158,8 +168,11 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, sa = (const struct sockaddr *)&addr6; sl = sizeof(addr6); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &y, sizeof(y))) - debug("Failed to set IPV6_V6ONLY on socket %i", fd); + if (!dual_stack) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, + &y, sizeof(y))) + debug("Failed to set IPV6_V6ONLY on socket %i", + fd); } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(y))) -- 2.38.1