summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
authorfriehm <friehm@openbsd.org>2017-05-30 12:09:27 +0000
committerfriehm <friehm@openbsd.org>2017-05-30 12:09:27 +0000
commit76dda2b0279f3c37adf1c059c3bab4d74bc96602 (patch)
treebe3f5816326845f93d728e4838ef1eabaaa45605 /sys/netinet/ip_carp.c
parentIntroduce a scary rc.conf(8) knob library_aslr=(YES|NO) to turn off the (diff)
downloadwireguard-openbsd-76dda2b0279f3c37adf1c059c3bab4d74bc96602.tar.xz
wireguard-openbsd-76dda2b0279f3c37adf1c059c3bab4d74bc96602.zip
Carp balancing ip does not work since there is a mac filter in
ether_input(). Now we use mbuf tags instead of modifying the MAC address. ok mpi@
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r--sys/netinet/ip_carp.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 44e2f9493a0..97af0d33f0d 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.311 2017/05/28 12:47:24 mpi Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.312 2017/05/30 12:09:27 friehm Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -1426,8 +1426,25 @@ carp_input(struct ifnet *ifp0, struct mbuf *m, void *cookie)
(IFF_UP|IFF_RUNNING))
continue;
- if (carp_vhe_match(sc, eh->ether_dhost))
+ if (carp_vhe_match(sc, eh->ether_dhost)) {
+ /*
+ * These packets look like layer 2 multicast but they
+ * are unicast at layer 3. With help of the tag the
+ * mbuf's M_MCAST flag can be removed by carp_lsdrop()
+ * after we have passed layer 2.
+ */
+ if (sc->sc_balancing == CARP_BAL_IP) {
+ struct m_tag *mtag;
+ mtag = m_tag_get(PACKET_TAG_CARP_BAL_IP, 0,
+ M_NOWAIT);
+ if (mtag == NULL) {
+ m_freem(m);
+ goto out;
+ }
+ m_tag_prepend(m, mtag);
+ }
break;
+ }
}
if (sc == NULL) {
@@ -1460,27 +1477,23 @@ carp_input(struct ifnet *ifp0, struct mbuf *m, void *cookie)
return (0);
}
- /*
- * Clear mcast if received on a carp IP balanced address.
- */
- if (sc->sc_balancing == CARP_BAL_IP &&
- ETHER_IS_MULTICAST(eh->ether_dhost))
- *(eh->ether_dhost) &= ~0x01;
-
ml_enqueue(&ml, m);
if_input(&sc->sc_if, &ml);
+out:
SRPL_LEAVE(&sr);
return (1);
}
int
-carp_lsdrop(struct mbuf *m, sa_family_t af, u_int32_t *src, u_int32_t *dst)
+carp_lsdrop(struct mbuf *m, sa_family_t af, u_int32_t *src, u_int32_t *dst,
+ int drop)
{
struct ifnet *ifp;
struct carp_softc *sc;
int match = 1;
u_int32_t fold;
+ struct m_tag *mtag;
ifp = if_get(m->m_pkthdr.ph_ifidx);
KASSERT(ifp != NULL);
@@ -1488,6 +1501,25 @@ carp_lsdrop(struct mbuf *m, sa_family_t af, u_int32_t *src, u_int32_t *dst)
sc = ifp->if_softc;
if (sc->sc_balancing == CARP_BAL_NONE)
goto done;
+
+ /*
+ * Remove M_MCAST flag from mbuf of balancing ip traffic, since the fact
+ * that it is layer 2 multicast does not implicate that it is also layer
+ * 3 multicast.
+ */
+ if (m->m_flags & M_MCAST &&
+ (mtag = m_tag_find(m, PACKET_TAG_CARP_BAL_IP, NULL))) {
+ m_tag_delete(m, mtag);
+ m->m_flags &= ~M_MCAST;
+ }
+
+ /*
+ * Return without making a drop decision. This allows to clear the
+ * M_MCAST flag and do nothing else.
+ */
+ if (!drop)
+ goto done;
+
/*
* Never drop carp advertisements.
* XXX Bad idea to pass all broadcast / multicast traffic?