Index | Thread | Search

From:
YASUOKA Masahiko <yasuoka@openbsd.org>
Subject:
carp: arp request or nd for unicast when not using virtual mac
To:
tech@openbsd.org
Date:
Tue, 26 Nov 2024 09:17:11 +0900

Download raw body.

Thread
  • YASUOKA Masahiko:

    carp: arp request or nd for unicast when not using virtual mac

Hello,

This should have been included when I made carp(4) work without a
virtual mac.  carp doesn't reply for unicast ARP or ND on that config.

ok?


ARP request or neighbor solicitation was dropped mistakenly if it's
sent for a unicast address and the resolving target is an address of
carp interface configured without virtual MAC.  Add check for
arp_input() and nd6_ns_input() to handle such requests.

Index: sys/netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
diff -u -p -r1.267 if_ether.c
--- sys/netinet/if_ether.c	18 Dec 2023 13:30:44 -0000	1.267
+++ sys/netinet/if_ether.c	26 Nov 2024 00:08:37 -0000
@@ -586,9 +586,27 @@ in_arpinput(struct ifnet *ifp, struct mb
 	/* Check target against our interface addresses. */
 	sin.sin_addr = itaddr;
 	rt = rtalloc(sintosa(&sin), 0, rdomain);
-	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
-	    rt->rt_ifidx == ifp->if_index)
-		target = 1;
+	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) {
+		if (rt->rt_ifidx == ifp->if_index)
+			target = 1;
+#if NCARP > 0
+		/*
+		 * Pass if the request is for unicast and the target address is
+		 * configured for a carp but received on the parent interface.
+		 * This happens if the carp is configured without a virtual mac.
+		 */
+		else if ((m->m_flags & M_BCAST) == 0) {
+			struct ifnet *ifp0;
+
+			ifp0 = if_get(rt->rt_ifidx);
+			if (ifp0->if_type == IFT_CARP &&
+			    ifp0->if_carpdevidx == ifp->if_index &&
+			    carp_iamatch(ifp0))
+				target = 1;
+			if_put(ifp0);
+		}
+#endif
+	}
 	rtfree(rt);
 	rt = NULL;
 
Index: sys/netinet6/nd6_nbr.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v
diff -u -p -r1.153 nd6_nbr.c
--- sys/netinet6/nd6_nbr.c	14 Jul 2024 18:53:39 -0000	1.153
+++ sys/netinet6/nd6_nbr.c	26 Nov 2024 00:08:37 -0000
@@ -247,6 +247,26 @@ nd6_ns_input(struct mbuf *m, int off, in
 				i_am_router = 0;	/* XXX */
 			}
 		}
+#if NCARP > 0
+		/*
+		 * Pass if the request is for unicast and the target address is
+		 * configured for a carp but received on the parent interface.
+		 * This happens if the carp is configured without a virtual mac.
+		 */
+		if ((m->m_flags & M_MCAST) == 0 &&
+		    rt && (rt->rt_flags & RTF_LOCAL) != 0 &&
+		    rt->rt_gateway->sa_family == AF_LINK) {
+			struct ifnet *ifp0;
+
+			ifp0 = if_get(rt->rt_ifidx);
+			if (ifp0->if_type == IFT_CARP &&
+			    ifp0->if_carpdevidx == ifp->if_index &&
+			    carp_iamatch(ifp0))
+				ifa = &in6ifa_ifpwithaddr(
+				    ifp0, &taddr6)->ia_ifa;
+			if_put(ifp0);
+		}
+#endif
 		if (rt)
 			rtfree(rt);
 	}