git: bc6abdd97e95 - main - nd6: use CARP link level address in SLLAO for NS sent out

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 25 Jan 2022 05:03:25 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=bc6abdd97e951b54294d331698317a607246255d

commit bc6abdd97e951b54294d331698317a607246255d
Author:     Thomas Steen Rasmussen <thomas@gibfest.dk>
AuthorDate: 2022-01-25 05:02:47 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-01-25 05:02:47 +0000

    nd6: use CARP link level address in SLLAO for NS sent out
    
    When sending an NS, check if we are using a IPv6 CARP address
    and if we do, then put proper CARP link level address into
    ND_OPT_SOURCE_LINKADDR option and also put PACKET_TAG_CARP tag
    on the packet.  The latter will enforce CARP link level address
    at the data link layer too, which might be necessary for broken
    implementations.
    The code really follows what NA sending code has been doing since
    introduction of carp(4).  While here, bring to style(9) the whole
    block of code.
    
    PR:                     193280
    Differential revision:  https://reviews.freebsd.org/D33858
---
 sys/netinet6/nd6_nbr.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 2100700733ad..0c6dd9e0361f 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -411,7 +411,6 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
 	struct ip6_moptions im6o;
 	int icmp6len;
 	int maxlen;
-	caddr_t mac;
 
 	NET_EPOCH_ASSERT();
 
@@ -534,19 +533,30 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
 	 *	Multicast NS		MUST add one	add the option
 	 *	Unicast NS		SHOULD add one	add the option
 	 */
-	if (nonce == NULL && (mac = nd6_ifptomac(ifp))) {
-		int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
-		struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
-		/* 8 byte alignments... */
-		optlen = (optlen + 7) & ~7;
-
-		m->m_pkthdr.len += optlen;
-		m->m_len += optlen;
-		icmp6len += optlen;
-		bzero((caddr_t)nd_opt, optlen);
-		nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
-		nd_opt->nd_opt_len = optlen >> 3;
-		bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
+	if (nonce == NULL) {
+		struct nd_opt_hdr *nd_opt;
+		char *mac;
+		int optlen;
+
+		mac = NULL;
+		if (ifp->if_carp)
+			mac = (*carp_macmatch6_p)(ifp, m, &ip6->ip6_src);
+		if (mac == NULL)
+			mac = nd6_ifptomac(ifp);
+
+		if (mac != NULL) {
+			nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
+			optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
+			/* 8 byte alignments... */
+			optlen = (optlen + 7) & ~7;
+			m->m_pkthdr.len += optlen;
+			m->m_len += optlen;
+			icmp6len += optlen;
+			bzero(nd_opt, optlen);
+			nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
+			nd_opt->nd_opt_len = optlen >> 3;
+			bcopy(mac, nd_opt + 1, ifp->if_addrlen);
+		}
 	}
 	/*
 	 * Add a Nonce option (RFC 3971) to detect looped back NS messages.