Generally, when a NA is received we check if the receiving interface has the target address advertised and if it's the case we warn about duplicate addresses and bail.
But in the case of a carp interface in BACKUP state it's different. In this case we have a hack that sets the ifa to NULL and continue. This hack relies on the fact that no cache entry will be found later on (because it was removed when the state switch to BACKUP) or that there is no lladdr change in the NA (like it is right now) to work properly. So instead of expecting such things, simply ignore NAs with matching address on carp BACKUP nodes since they are more likely to come from the carp MASTER. Less is more, ok? Index: nd6_nbr.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/nd6_nbr.c,v retrieving revision 1.75 diff -u -p -r1.75 nd6_nbr.c --- nd6_nbr.c 24 Jan 2014 12:20:22 -0000 1.75 +++ nd6_nbr.c 13 Feb 2014 11:14:04 -0000 @@ -570,9 +570,6 @@ nd6_na_input(struct mbuf *m, int off, in struct rtentry *rt; struct sockaddr_dl *sdl; union nd_opts ndopts; -#if NCARP > 0 - struct sockaddr_dl *proxydl = NULL; -#endif char addr[INET6_ADDRSTRLEN], addr0[INET6_ADDRSTRLEN]; if (ip6->ip6_hlim != 255) { @@ -632,11 +629,6 @@ nd6_na_input(struct mbuf *m, int off, in } ifa = &in6ifa_ifpwithaddr(ifp, &taddr6)->ia_ifa; -#if NCARP > 0 - if (ifp->if_type == IFT_CARP && ifa && - !carp_iamatch6(ifp, lladdr, &proxydl)) - ifa = NULL; -#endif /* * Target address matches one of my interface address. @@ -652,8 +644,18 @@ nd6_na_input(struct mbuf *m, int off, in goto freeit; } - /* Just for safety, maybe unnecessary. */ if (ifa) { +#if NCARP > 0 + struct sockaddr_dl *proxydl = NULL; + + /* + * Ignore NAs silently for carp addresses if we're not + * the CARP master. + */ + if (ifp->if_type == IFT_CARP || + !carp_iamatch6(ifp, lladdr, &proxydl)) + goto freeit; +#endif log(LOG_ERR, "nd6_na_input: duplicate IP6 address %s\n", inet_ntop(AF_INET6, &taddr6, addr, sizeof(addr)));