Download raw body.
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);
}
carp: arp request or nd for unicast when not using virtual mac