Hi Tech, I have noticed that CARP IP-Balancing is broken, so I am testing and fixing it.
The first problem came in with this commit: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_ethersubr.c.diff?r1=1.176&r2=1.177 It enforces that outgoing packets use the src mac of the carp interface instead the mac of its carpdev. That's a good idea for failover carp but it breaks balancing ip(-stealth), because the same source MAC is seen by multiple switchports now. That leads to continues MAC flapping at switches. My attached patch fixes the problem. Thanks Martin's refactoring, we can enforce the right MAC on a central place in carp_start() now. A second problem was introduced two weeks ago. Since we always check the destination MAC address of received unicast packets, not only when in promiscuous mode, carp balancing ip is always broken, not only when in promiscuous mode. The new check collides with "Clear mcast if received on a carp IP balanced address." in carp_input(). My fix in net/if_ethersubr.c is probably the wrong place to fix the problem, but I don't have a better idea for now. Maybe the fix is ok for now, because we don't have too much time before tagging 5.9. Both of my fixes are independent from each other. They can be separately committed. Thanks and Regards, Florian Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.233 diff -u -p -r1.233 if_ethersubr.c --- net/if_ethersubr.c 22 Jan 2016 17:09:05 -0000 1.233 +++ net/if_ethersubr.c 6 Feb 2016 08:15:44 -0000 @@ -354,7 +354,8 @@ ether_input(struct ifnet *ifp, struct mb * This check is required in promiscous mode, and for some hypervisors * where the MAC filter is 'best effort' only. */ - if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { + if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 && + ifp->if_type != IFT_CARP) { if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) { m_freem(m); return (1); Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.286 diff -u -p -r1.286 ip_carp.c --- netinet/ip_carp.c 21 Jan 2016 11:23:48 -0000 1.286 +++ netinet/ip_carp.c 6 Feb 2016 08:15:46 -0000 @@ -2275,9 +2275,15 @@ carp_start(struct ifnet *ifp) * advertisements in 'ip' and 'ip-stealth' balacing * modes. */ - if (sc->sc_balancing != CARP_BAL_IPSTEALTH && - sc->sc_balancing != CARP_BAL_IP && - (sc->cur_vhe && !sc->cur_vhe->vhe_leader)) { + if (sc->sc_balancing == CARP_BAL_IP || + sc->sc_balancing == CARP_BAL_IPSTEALTH) { + struct ether_header *eh; + uint8_t *esrc; + + eh = mtod(m, struct ether_header *); + esrc = ((struct arpcom*) ifp->if_carpdev)->ac_enaddr; + memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost)); + } else if (sc->cur_vhe && !sc->cur_vhe->vhe_leader) { struct ether_header *eh; uint8_t *esrc;