ether_output() needs the source Ethernet address in order to construct the frame. When the output interface is a carp(4) interface in balancing mode we might end up changing the source Ethernet address.
But doing it after checking for the Ethernet destination address of before does not matter. So this diff merge two "#ifdef NCARP" blocks into one. I appreciate if somebody can test, I'm away from my CARP setup. Ok? Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.188 diff -u -p -r1.188 if_ethersubr.c --- net/if_ethersubr.c 9 Feb 2015 00:21:58 -0000 1.188 +++ net/if_ethersubr.c 12 Feb 2015 06:15:32 -0000 @@ -283,6 +283,9 @@ ether_output(struct ifnet *ifp0, struct (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); } + + if (ifp0 != ifp && ifp0->if_type == IFT_CARP) + esrc = carp_get_srclladdr(ifp0, esrc); #endif /* NCARP > 0 */ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) @@ -361,11 +364,6 @@ ether_output(struct ifnet *ifp0, struct /* XXX Should we feed-back an unencrypted IPsec packet ? */ if (mcopy) (void) looutput(ifp, mcopy, dst, rt); - -#if NCARP > 0 - if (ifp0 != ifp && ifp0->if_type == IFT_CARP) - esrc = carp_get_srclladdr(ifp0, esrc); -#endif if (ether_addheader(&m, ifp, etype, esrc, edst) == -1) senderr(ENOBUFS);