From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=hKNFXqpT; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id 1EE885A0262 for ; Mon, 13 Apr 2026 02:53:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1776041608; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mQ/3NnLeb+ar5XfWOto1316AAwbWpwkSuQkHY5DrbXc=; b=hKNFXqpTc77bwpffy1xR8TuQDHKdbv+w1HyHW6Sm6pxtpi+c9WOnbIizWP5EXVy3cZdMcC EcJ7yCGb/TcnqPJ40eqTg3eLaCW9607eJIm0LsMTR8YBJrgRKVrDeUKKe7As4/unRfwarb aIx/VvbLJlyHYsiuELNKmpIjufnyU0Q= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-113-2wpkgGbHMLuELbWGOG3igw-1; Sun, 12 Apr 2026 20:53:24 -0400 X-MC-Unique: 2wpkgGbHMLuELbWGOG3igw-1 X-Mimecast-MFC-AGG-ID: 2wpkgGbHMLuELbWGOG3igw_1776041603 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 32E18195608F; Mon, 13 Apr 2026 00:53:23 +0000 (UTC) Received: from jmaloy-thinkpadp16vgen1.rmtcaqc.csb (unknown [10.22.64.70]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 127D43000C16; Mon, 13 Apr 2026 00:53:21 +0000 (UTC) From: Jon Maloy To: sbrivio@redhat.com, david@gibson.dropbear.id.au, jmaloy@redhat.com, passt-dev@passt.top Subject: [PATCH v7 01/13] dhcpv6: Fix reply destination to match client's source address Date: Sun, 12 Apr 2026 20:53:07 -0400 Message-ID: <20260413005319.3295910-2-jmaloy@redhat.com> In-Reply-To: <20260413005319.3295910-1-jmaloy@redhat.com> References: <20260413005319.3295910-1-jmaloy@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Ufc0tx3C_PYFDdq4QhKxT7GlJ_i6ygHJC4FL3qCTbaU_1776041603 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true Message-ID-Hash: HVENRM2EXYIF57XZVB46ZQLEG3ISXAXN X-Message-ID-Hash: HVENRM2EXYIF57XZVB46ZQLEG3ISXAXN X-MailFrom: jmaloy@redhat.com 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 X-Mailman-Version: 3.3.8 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: tap_ip6_daddr() selects the reply destination based on our source address type (link-local), so it always returns addr_ll_seen. But if the client sent from a global address, we would reply to an address different from what the client is expecting. Since RFC 8415 allows clients to use global addresses for DHCPv6, we now correct this, and always respond to the address the client was using. We also remove a redundant addr_ll_seen assignment, since this is already done by tap.c when processing IPv6 packets. Signed-off-by: Jon Maloy --- dhcpv6.c | 14 ++++++-------- dhcpv6.h | 2 +- tap.c | 15 --------------- tap.h | 2 -- 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/dhcpv6.c b/dhcpv6.c index 97c04e2..2db0944 100644 --- a/dhcpv6.c +++ b/dhcpv6.c @@ -370,12 +370,14 @@ notonlink: /** * dhcpv6_send_ia_notonlink() - Send NotOnLink status * @c: Execution context + * @saddr: Source address of client message (reply destination) * @ia_base: Non-appropriate IA_NA or IA_TA base * @client_id_base: Client ID message option base * @len: Client ID length * @xid: Transaction ID for message exchange */ static void dhcpv6_send_ia_notonlink(struct ctx *c, + const struct in6_addr *saddr, const struct iov_tail *ia_base, const struct iov_tail *client_id_base, int len, uint32_t xid) @@ -405,8 +407,7 @@ static void dhcpv6_send_ia_notonlink(struct ctx *c, resp_not_on_link.hdr.xid = xid; - tap_udp6_send(c, src, 547, tap_ip6_daddr(c, src), 546, - xid, &resp_not_on_link, n); + tap_udp6_send(c, src, 547, saddr, 546, xid, &resp_not_on_link, n); } /** @@ -543,7 +544,7 @@ static size_t dhcpv6_client_fqdn_fill(const struct iov_tail *data, * dhcpv6() - Check if this is a DHCPv6 message, reply as needed * @c: Execution context * @data: Single packet starting from UDP header - * @saddr: Source IPv6 address of original message + * @saddr: Source IPv6 address of original message (for reply destination) * @daddr: Destination IPv6 address of original message * * Return: 0 if it's not a DHCPv6 message, 1 if handled, -1 on failure @@ -590,8 +591,6 @@ int dhcpv6(struct ctx *c, struct iov_tail *data, if (mlen + sizeof(*uh) != ntohs(uh->len) || mlen < sizeof(*mh)) return -1; - c->ip6.addr_ll_seen = *saddr; - src = &c->ip6.our_tap_ll; mh = IOV_REMOVE_HEADER(data, mh_storage); @@ -630,7 +629,7 @@ int dhcpv6(struct ctx *c, struct iov_tail *data, if (dhcpv6_ia_notonlink(data, &c->ip6.addr)) { - dhcpv6_send_ia_notonlink(c, data, &client_id_base, + dhcpv6_send_ia_notonlink(c, saddr, data, &client_id_base, ntohs(client_id->l), mh->xid); return 1; @@ -680,8 +679,7 @@ int dhcpv6(struct ctx *c, struct iov_tail *data, resp.hdr.xid = mh->xid; - tap_udp6_send(c, src, 547, tap_ip6_daddr(c, src), 546, - mh->xid, &resp, n); + tap_udp6_send(c, src, 547, saddr, 546, mh->xid, &resp, n); c->ip6.addr_seen = c->ip6.addr; return 1; diff --git a/dhcpv6.h b/dhcpv6.h index c706dfd..1015a1a 100644 --- a/dhcpv6.h +++ b/dhcpv6.h @@ -7,7 +7,7 @@ #define DHCPV6_H int dhcpv6(struct ctx *c, struct iov_tail *data, - struct in6_addr *saddr, struct in6_addr *daddr); + const struct in6_addr *saddr, const struct in6_addr *daddr); void dhcpv6_init(const struct ctx *c); #endif /* DHCPV6_H */ diff --git a/tap.c b/tap.c index eaa6111..59c45a3 100644 --- a/tap.c +++ b/tap.c @@ -161,21 +161,6 @@ void tap_send_single(const struct ctx *c, const void *data, size_t l2len) } } -/** - * tap_ip6_daddr() - Normal IPv6 destination address for inbound packets - * @c: Execution context - * @src: Source address - * - * Return: pointer to IPv6 address - */ -const struct in6_addr *tap_ip6_daddr(const struct ctx *c, - const struct in6_addr *src) -{ - if (IN6_IS_ADDR_LINKLOCAL(src)) - return &c->ip6.addr_ll_seen; - return &c->ip6.addr_seen; -} - /** * tap_push_l2h() - Build an L2 header for an inbound packet * @c: Execution context diff --git a/tap.h b/tap.h index 07ca096..b335933 100644 --- a/tap.h +++ b/tap.h @@ -96,8 +96,6 @@ void tap_udp4_send(const struct ctx *c, struct in_addr src, in_port_t sport, const void *in, size_t dlen); void tap_icmp4_send(const struct ctx *c, struct in_addr src, struct in_addr dst, const void *in, const void *src_mac, size_t l4len); -const struct in6_addr *tap_ip6_daddr(const struct ctx *c, - const struct in6_addr *src); void *tap_push_ip6h(struct ipv6hdr *ip6h, const struct in6_addr *src, const struct in6_addr *dst, size_t l4len, uint8_t proto, uint32_t flow); -- 2.52.0