The following reply was made to PR kern/121574; it has been noted by GNATS.

From: "Max Laier" <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED], [EMAIL PROTECTED]
Subject: Re: kern/121574: [carp] CARP hash dependent on order of IP 
     addresses on interface
Date: Tue, 11 Mar 2008 11:28:34 +0100 (CET)

 ------=_20080311112834_27075
 Content-Type: text/plain; charset="iso-8859-1"
 Content-Transfer-Encoding: 8bit
 
 (subject helps)
 
 Please try the attached patch (mostly OpenBSD rev. 1.114 plus follow-ups).
  This should fix the symptom.  I have no idea why your address lists would
 get skewed however.  They "should"[tm] be in the order in which you add
 aliases.
 
 -- Max
 ------=_20080311112834_27075
 Content-Type: text/x-diff; name="ip_carp.c.HEAD.diff"
 Content-Transfer-Encoding: 8bit
 Content-Disposition: attachment; filename="ip_carp.c.HEAD.diff"
 
 Index: ip_carp.c
 ===================================================================
 RCS file: /home/mlaier/fcvs/src/sys/netinet/ip_carp.c,v
 retrieving revision 1.27.2.12
 diff -u -r1.27.2.12 ip_carp.c
 --- ip_carp.c  1 Feb 2008 11:20:41 -0000       1.27.2.12
 +++ ip_carp.c  11 Mar 2008 10:16:12 -0000
 @@ -238,9 +238,12 @@
        u_int8_t version = CARP_VERSION, type = CARP_ADVERTISEMENT;
        u_int8_t vhid = sc->sc_vhid & 0xff;
        struct ifaddr *ifa;
 -      int i;
 +      int i, found;
 +#ifdef INET
 +      struct in_addr last, cur, in;
 +#endif
  #ifdef INET6
 -      struct in6_addr in6;
 +      struct in6_addr last6, cur6, in6;
  #endif
  
        if (sc->sc_carpdev)
 @@ -261,21 +264,44 @@
        SHA1Update(&sc->sc_sha1, (void *)&type, sizeof(type));
        SHA1Update(&sc->sc_sha1, (void *)&vhid, sizeof(vhid));
  #ifdef INET
 -      TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 -              if (ifa->ifa_addr->sa_family == AF_INET)
 -                      SHA1Update(&sc->sc_sha1,
 -                          (void *)&ifatoia(ifa)->ia_addr.sin_addr.s_addr,
 -                          sizeof(struct in_addr));
 -      }
 +      cur.s_addr = 0;
 +      do {
 +              found = 0;
 +              last = cur;
 +              cur.s_addr = 0xffffffff;
 +              TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 +                      in.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr;
 +                      if (ifa->ifa_addr->sa_family == AF_INET &&
 +                          ntohl(in.s_addr) > ntohl(last.s_addr) &&
 +                          ntohl(in.s_addr) < ntohl(cur.s_addr)) {
 +                              cur.s_addr = in.s_addr;
 +                              found++;
 +                      }
 +              }
 +              if (found)
 +                      SHA1Update(&sc->sc_sha1, (void *)&cur, sizeof(cur));
 +      } while (found);
  #endif /* INET */
  #ifdef INET6
 -      TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 -              if (ifa->ifa_addr->sa_family == AF_INET6) {
 +      memset(&cur6, 0, sizeof(cur6));
 +      do {
 +              found = 0;
 +              last6 = cur6;
 +              memset(&cur6, 0xff, sizeof(cur6));
 +              TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
                        in6 = ifatoia6(ifa)->ia_addr.sin6_addr;
 -                      in6_clearscope(&in6);
 -                      SHA1Update(&sc->sc_sha1, (void *)&in6, sizeof(in6));
 +                      if (IN6_IS_SCOPE_EMBED(&in6))
 +                              in6.s6_addr16[1] = 0;
 +                      if (ifa->ifa_addr->sa_family == AF_INET6 &&
 +                          memcmp(&in6, &last6, sizeof(in6)) > 0 &&
 +                          memcmp(&in6, &cur6, sizeof(in6)) < 0) {
 +                              cur6 = in6;
 +                              found++;
 +                      }
                }
 -      }
 +              if (found)
 +                      SHA1Update(&sc->sc_sha1, (void *)&cur6, sizeof(cur6));
 +      } while (found);
  #endif /* INET6 */
  
        /* convert ipad to opad */
 ------=_20080311112834_27075
 Content-Type: text/x-diff; name="ip_carp.c.RELENG_6.diff"
 Content-Transfer-Encoding: 8bit
 Content-Disposition: attachment; filename="ip_carp.c.RELENG_6.diff"
 
 Index: ip_carp.c
 ===================================================================
 RCS file: /home/mlaier/fcvs/src/sys/netinet/ip_carp.c,v
 retrieving revision 1.27.2.12
 diff -u -r1.27.2.12 ip_carp.c
 --- ip_carp.c  1 Feb 2008 11:20:41 -0000       1.27.2.12
 +++ ip_carp.c  11 Mar 2008 10:20:42 -0000
 @@ -238,9 +238,12 @@
        u_int8_t version = CARP_VERSION, type = CARP_ADVERTISEMENT;
        u_int8_t vhid = sc->sc_vhid & 0xff;
        struct ifaddr *ifa;
 -      int i;
 +      int i, found;
 +#ifdef INET
 +      struct in_addr last, cur, in;
 +#endif
  #ifdef INET6
 -      struct in6_addr in6;
 +      struct in6_addr last6, cur6, in6;
  #endif
  
        if (sc->sc_carpdev)
 @@ -261,21 +264,45 @@
        SHA1Update(&sc->sc_sha1, (void *)&type, sizeof(type));
        SHA1Update(&sc->sc_sha1, (void *)&vhid, sizeof(vhid));
  #ifdef INET
 -      TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 -              if (ifa->ifa_addr->sa_family == AF_INET)
 -                      SHA1Update(&sc->sc_sha1,
 -                          (void *)&ifatoia(ifa)->ia_addr.sin_addr.s_addr,
 -                          sizeof(struct in_addr));
 -      }
 +      cur.s_addr = 0;
 +      do {
 +              found = 0;
 +              last = cur;
 +              cur.s_addr = 0xffffffff;
 +              TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 +                      in.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr;
 +                      if (ifa->ifa_addr->sa_family == AF_INET &&
 +                          ntohl(in.s_addr) > ntohl(last.s_addr) &&
 +                          ntohl(in.s_addr) < ntohl(cur.s_addr)) {
 +                              cur.s_addr = in.s_addr;
 +                              found++;
 +                      }
 +              }
 +              if (found)
 +                      SHA1Update(&sc->sc_sha1, (void *)&cur, sizeof(cur));
 +      } while (found);
  #endif /* INET */
  #ifdef INET6
 -      TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
 -              if (ifa->ifa_addr->sa_family == AF_INET6) {
 +      memset(&cur6, 0, sizeof(cur6));
 +      do {
 +              found = 0;
 +              last6 = cur6;
 +              memset(&cur6, 0xff, sizeof(cur6));
 +              TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
                        in6 = ifatoia6(ifa)->ia_addr.sin6_addr;
 -                      in6_clearscope(&in6);
 -                      SHA1Update(&sc->sc_sha1, (void *)&in6, sizeof(in6));
 +                      if (IN6_IS_SCOPE_LINKLOCAL(&in6) ||
 +                          IN6_IS_ADDR_MC_INTFACELOCAL(&in6))
 +                              in6.s6_addr16[1] = 0;
 +                      if (ifa->ifa_addr->sa_family == AF_INET6 &&
 +                          memcmp(&in6, &last6, sizeof(in6)) > 0 &&
 +                          memcmp(&in6, &cur6, sizeof(in6)) < 0) {
 +                              cur6 = in6;
 +                              found++;
 +                      }
                }
 -      }
 +              if (found)
 +                      SHA1Update(&sc->sc_sha1, (void *)&cur6, sizeof(cur6));
 +      } while (found);
  #endif /* INET6 */
  
        /* convert ipad to opad */
 ------=_20080311112834_27075--
 
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to