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)));

Reply via email to