[BACK]Return to in6_ifattach.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet6/in6_ifattach.c between version 1.1.2.2 and 1.2

version 1.1.2.2, 1999/11/30 13:35:50 version 1.2, 1999/07/01 08:12:54
Line 32 
Line 32 
 #include <sys/malloc.h>  #include <sys/malloc.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/sockio.h>  #include <sys/sockio.h>
 #include <sys/kernel.h>  
 #ifdef __bsdi__  
 #include <crypto/md5.h>  
 #elif defined(__OpenBSD__)  
 #include <sys/md5k.h>  
 #else  
 #include <sys/md5.h>  
 #endif  
   
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_dl.h>  #include <net/if_dl.h>
Line 52 
Line 44 
 #include <netinet/if_ether.h>  #include <netinet/if_ether.h>
 #endif  #endif
   
   #include <netinet6/in6.h>
 #include <netinet6/ip6.h>  #include <netinet6/ip6.h>
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
 #include <netinet6/in6_ifattach.h>  #include <netinet6/in6_ifattach.h>
Line 59 
Line 52 
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
 #include <netinet6/nd6.h>  #include <netinet6/nd6.h>
   
 #include <net/net_osdep.h>  
   
 static  struct in6_addr llsol;  static  struct in6_addr llsol;
   
 struct in6_ifstat **in6_ifstat = NULL;  struct in6_addr **in6_iflladdr = NULL;
 struct icmp6_ifstat **icmp6_ifstat = NULL;  
 size_t in6_ifstatmax = 0;  
 size_t icmp6_ifstatmax = 0;  
 unsigned long in6_maxmtu = 0;  unsigned long in6_maxmtu = 0;
   
 int found_first_ifid = 0;  int found_first_ifid = 0;
 #define IFID_LEN 8  #define IFID_LEN 8
 static char first_ifid[IFID_LEN];  static char first_ifid[IFID_LEN];
   
 static int laddr_to_eui64 __P((u_int8_t *, u_int8_t *, size_t));  static void ieee802_to_eui64 __P((u_int8_t *, u_int8_t *));
 static int gen_rand_eui64 __P((u_int8_t *));  
   
 static int  static void
 laddr_to_eui64(dst, src, len)  ieee802_to_eui64(dst, src)
         u_int8_t *dst;          u_int8_t *dst;
         u_int8_t *src;          u_int8_t *src;
         size_t len;  
 {  {
         static u_int8_t zero[8];          dst[0] = src[0];
           dst[1] = src[1];
         bzero(zero, sizeof(zero));          dst[2] = src[2];
           dst[3] = 0xff;
         switch (len) {          dst[4] = 0xfe;
         case 6:          dst[5] = src[3];
                 if (bcmp(zero, src, 6) == 0)          dst[6] = src[4];
                         return EINVAL;          dst[7] = src[5];
                 dst[0] = src[0];  
                 dst[1] = src[1];  
                 dst[2] = src[2];  
                 dst[3] = 0xff;  
                 dst[4] = 0xfe;  
                 dst[5] = src[3];  
                 dst[6] = src[4];  
                 dst[7] = src[5];  
                 break;  
         case 8:  
                 if (bcmp(zero, src, 8) == 0)  
                         return EINVAL;  
                 bcopy(src, dst, len);  
                 break;  
         default:  
                 return EINVAL;  
         }  
   
         return 0;  
 }  
   
 /*  
  * Generate a last-resort interface identifier, when the machine has no  
  * IEEE802/EUI64 address sources.  
  * The address should be random, and should not change across reboot.  
  */  
 static int  
 gen_rand_eui64(dst)  
         u_int8_t *dst;  
 {  
         MD5_CTX ctxt;  
         u_int8_t digest[16];  
 #ifdef __FreeBSD__  
         int hostnamelen = strlen(hostname);  
 #endif  
   
         /* generate 8bytes of pseudo-random value. */  
         bzero(&ctxt, sizeof(ctxt));  
         MD5Init(&ctxt);  
         MD5Update(&ctxt, hostname, hostnamelen);  
         MD5Final(digest, &ctxt);  
   
         /* assumes sizeof(digest) > sizeof(first_ifid) */  
         bcopy(digest, dst, 8);  
   
         /* make sure to set "u" bit to local, and "g" bit to individual. */  
         dst[0] &= 0xfe;  
         dst[0] |= 0x02;         /* EUI64 "local" */  
   
         return 0;  
 }  }
   
 /*  /*
  * Find first ifid on list of interfaces.   * find first ifid on list of interfaces.
  * This is assumed that ifp0's interface token (for example, IEEE802 MAC)  
  * is globally unique.  We may need to have a flag parameter in the future.  
  */   */
 int  int
 in6_ifattach_getifid(ifp0)  in6_ifattach_getifid(ifp0)
Line 160  in6_ifattach_getifid(ifp0)
Line 94  in6_ifattach_getifid(ifp0)
         if (found_first_ifid)          if (found_first_ifid)
                 return 0;                  return 0;
   
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)          for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) {
         for (ifp = ifnet; ifp; ifp = ifp->if_next)  
 #else  
         for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)  
 #endif  
         {  
                 if (ifp0 != NULL && ifp0 != ifp)                  if (ifp0 != NULL && ifp0 != ifp)
                         continue;                          continue;
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
                 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)  
 #else  
                 for (ifa = ifp->if_addrlist.tqh_first;                  for (ifa = ifp->if_addrlist.tqh_first;
                      ifa;                       ifa;
                      ifa = ifa->ifa_list.tqe_next)                       ifa = ifa->ifa_list.tqe_next) {
 #endif  
                 {  
                         if (ifa->ifa_addr->sa_family != AF_LINK)                          if (ifa->ifa_addr->sa_family != AF_LINK)
                                 continue;                                  continue;
                         sdl = (struct sockaddr_dl *)ifa->ifa_addr;                          sdl = (struct sockaddr_dl *)ifa->ifa_addr;
Line 187  in6_ifattach_getifid(ifp0)
Line 111  in6_ifattach_getifid(ifp0)
                         case IFT_ETHER:                          case IFT_ETHER:
                         case IFT_FDDI:                          case IFT_FDDI:
                         case IFT_ATM:                          case IFT_ATM:
                                 /* IEEE802/EUI64 cases - what others? */                          /* what others? */
                                 addr = LLADDR(sdl);                                  addr = LLADDR(sdl);
                                 addrlen = sdl->sdl_alen;                                  addrlen = sdl->sdl_alen;
                                 /*  
                                  * to copy ifid from IEEE802/EUI64 interface,  
                                  * u bit of the source needs to be 0.  
                                  */  
                                 if ((addr[0] & 0x02) != 0)  
                                         break;  
                                 goto found;                                  goto found;
                         case IFT_ARCNET:  
                                 /*  
                                  * ARCnet interface token cannot be used as  
                                  * globally unique identifier due to its  
                                  * small bitwidth.  
                                  */  
                                 break;  
                         default:                          default:
                                 break;                                  break;
                         }                          }
                 }                  }
         }          }
 #ifdef DEBUG          printf("failed to get EUI64");
         printf("in6_ifattach_getifid: failed to get EUI64");  
 #endif  
         return EADDRNOTAVAIL;          return EADDRNOTAVAIL;
   
 found:  found:
         if (laddr_to_eui64(first_ifid, addr, addrlen) == 0)          switch (addrlen) {
           case 6:
                   ieee802_to_eui64(first_ifid, addr);
                 found_first_ifid = 1;                  found_first_ifid = 1;
                   break;
           case 8:
                   bcopy(addr, first_ifid, 8);
                   found_first_ifid = 1;
                   break;
           default:
                   break;
           }
   
         if (found_first_ifid) {          if (found_first_ifid) {
                 printf("%s: supplying EUI64: "                  printf("got EUI64 from %s, "
                         "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",                          "value %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
                         if_name(ifp),                          ifp->if_xname,
                         first_ifid[0] & 0xff, first_ifid[1] & 0xff,                          first_ifid[0] & 0xff, first_ifid[1] & 0xff,
                         first_ifid[2] & 0xff, first_ifid[3] & 0xff,                          first_ifid[2] & 0xff, first_ifid[3] & 0xff,
                         first_ifid[4] & 0xff, first_ifid[5] & 0xff,                          first_ifid[4] & 0xff, first_ifid[5] & 0xff,
                         first_ifid[6] & 0xff, first_ifid[7] & 0xff);                          first_ifid[6] & 0xff, first_ifid[7] & 0xff);
   
                 /* invert u bit to convert EUI64 to RFC2373 interface ID. */  
                 first_ifid[0] ^= 0x02;  
   
                 return 0;                  return 0;
         } else {          } else {
 #ifdef DEBUG                  printf("failed to get EUI64");
                 printf("in6_ifattach_getifid: failed to get EUI64");  
 #endif  
                 return EADDRNOTAVAIL;                  return EADDRNOTAVAIL;
         }          }
 }  }
Line 242  found:
Line 155  found:
 /*  /*
  * add link-local address to *pseudo* p2p interfaces.   * add link-local address to *pseudo* p2p interfaces.
  * get called when the first MAC address is made available in in6_ifattach().   * get called when the first MAC address is made available in in6_ifattach().
  *  
  * XXX I start considering this loop as a bad idea. (itojun)  
  */   */
 void  void
 in6_ifattach_p2p()  in6_ifattach_p2p()
Line 251  in6_ifattach_p2p()
Line 162  in6_ifattach_p2p()
         struct ifnet *ifp;          struct ifnet *ifp;
   
         /* prevent infinite loop. just in case. */          /* prevent infinite loop. just in case. */
         if (found_first_ifid == 0)          if (! found_first_ifid)
                 return;                  return;
   
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)          for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) {
         for (ifp = ifnet; ifp; ifp = ifp->if_next)  
 #else  
         for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)  
 #endif  
         {  
                 switch (ifp->if_type) {                  switch (ifp->if_type) {
                 case IFT_GIF:                  case IFT_GIF:
                   case IFT_FAITH:
                         /* pseudo interfaces - safe to initialize here */                          /* pseudo interfaces - safe to initialize here */
                         in6_ifattach(ifp, IN6_IFT_P2P, 0, 0);                          in6_ifattach(ifp, IN6_IFT_P2P, 0, 0);
                         break;                          break;
                 case IFT_DUMMY:  
                 case IFT_FAITH:  
                         /* this mistakingly becomes IFF_UP */  
                         break;  
                 case IFT_SLIP:                  case IFT_SLIP:
                         /* IPv6 is not supported */                          /* IPv6 is not supported */
                         break;                          break;
Line 286  in6_ifattach(ifp, type, laddr, noloop)
Line 189  in6_ifattach(ifp, type, laddr, noloop)
         struct ifnet *ifp;          struct ifnet *ifp;
         u_int type;          u_int type;
         caddr_t laddr;          caddr_t laddr;
         /* size_t laddrlen; */  
         int noloop;          int noloop;
           /* xxx sizeof(laddr) */
 {  {
         static size_t if_indexlim = 8;          static size_t if_indexlim = 8;
         struct sockaddr_in6 mltaddr;          struct sockaddr_in6 mltaddr;
         struct sockaddr_in6 mltmask;          struct sockaddr_in6 mltmask;
         struct sockaddr_in6 gate;          struct sockaddr_in6 gate;
         struct sockaddr_in6 mask;          struct sockaddr_in6 mask;
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
         struct ifaddr **ifap;  
 #endif  
   
         struct in6_ifaddr *ia, *ib, *oia;          struct in6_ifaddr *ia, *ib, *oia;
         struct ifaddr *ifa;          struct ifaddr *ifa;
         int rtflag = 0;          int rtflag = 0;
   
         if (type == IN6_IFT_P2P && found_first_ifid == 0) {          if (type == IN6_IFT_P2P && found_first_ifid == 0) {
                 printf("%s: no ifid available for IPv6 link-local address\n",                  printf("%s: no ifid available yet for IPv6 link-local address\n",
                         if_name(ifp));                          ifp->if_xname);
 #if 0  
                 return;                  return;
 #else  
                 /* last resort */  
                 if (gen_rand_eui64(first_ifid) == 0) {  
                         printf("%s: using random value as EUI64: "  
                                 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",  
                                 if_name(ifp),  
                                 first_ifid[0] & 0xff, first_ifid[1] & 0xff,  
                                 first_ifid[2] & 0xff, first_ifid[3] & 0xff,  
                                 first_ifid[4] & 0xff, first_ifid[5] & 0xff,  
                                 first_ifid[6] & 0xff, first_ifid[7] & 0xff);  
                         /*  
                          * invert u bit to convert EUI64 to RFC2373 interface  
                          * ID.  
                          */  
                         first_ifid[0] ^= 0x02;  
   
                         found_first_ifid = 1;  
                 }  
 #endif  
         }          }
   
         if ((ifp->if_flags & IFF_MULTICAST) == 0) {          if ((ifp->if_flags & IFF_MULTICAST) == 0) {
                 printf("%s: not multicast capable, IPv6 not enabled\n",                  printf("%s: no multicast allowed, IPv6 is not enabled\n",
                         if_name(ifp));                          ifp->if_xname);
                 return;                  return;
         }          }
   
         /*          /*
          * We have some arrays that should be indexed by if_index.           * We have some arrays that should be indexed by if_index.
          * since if_index will grow dynamically, they should grow too.           * since if_index will grow dynamically, they should grow too.
          *      struct in6_ifstat **in6_ifstat           *      struct in6_addr **in6_iflladdr
          *      struct icmp6_ifstat **icmp6_ifstat  
          */           */
         if (in6_ifstat == NULL || icmp6_ifstat == NULL          if (in6_iflladdr == NULL || if_index >= if_indexlim) {
          || if_index >= if_indexlim) {  
                 size_t n;                  size_t n;
                 caddr_t q;                  caddr_t q;
                 size_t olim;  
   
                 olim = if_indexlim;                  while(if_index >= if_indexlim)
                 while (if_index >= if_indexlim)  
                         if_indexlim <<= 1;                          if_indexlim <<= 1;
   
                 /* grow in6_ifstat */                  /* grow in6_iflladdr */
                 n = if_indexlim * sizeof(struct in6_ifstat *);                  n = if_indexlim * sizeof(struct in6_addr *);
                 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);  
                 bzero(q, n);  
                 if (in6_ifstat) {  
                         bcopy((caddr_t)in6_ifstat, q,  
                                 olim * sizeof(struct in6_ifstat *));  
                         free((caddr_t)in6_ifstat, M_IFADDR);  
                 }  
                 in6_ifstat = (struct in6_ifstat **)q;  
                 in6_ifstatmax = if_indexlim;  
   
                 /* grow icmp6_ifstat */  
                 n = if_indexlim * sizeof(struct icmp6_ifstat *);  
                 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);                  q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
                 bzero(q, n);                  bzero(q, n);
                 if (icmp6_ifstat) {                  if (in6_iflladdr) {
                         bcopy((caddr_t)icmp6_ifstat, q,                          bcopy((caddr_t)in6_iflladdr, q, n/2);
                                 olim * sizeof(struct icmp6_ifstat *));                          free((caddr_t)in6_iflladdr, M_IFADDR);
                         free((caddr_t)icmp6_ifstat, M_IFADDR);  
                 }                  }
                 icmp6_ifstat = (struct icmp6_ifstat **)q;                  in6_iflladdr = (struct in6_addr **)q;
                 icmp6_ifstatmax = if_indexlim;  
         }          }
   
         /*          /*
Line 380  in6_ifattach(ifp, type, laddr, noloop)
Line 242  in6_ifattach(ifp, type, laddr, noloop)
          * cards multiple times.           * cards multiple times.
          * This is lengthy for P2P and LOOP but works.           * This is lengthy for P2P and LOOP but works.
          */           */
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
         ifa = ifp->if_addrlist;  
         if (ifa != NULL) {  
                 for ( ; ifa; ifa = ifa->ifa_next) {  
                         ifap = &ifa->ifa_next;  
                         if (ifa->ifa_addr->sa_family != AF_INET6)  
                                 continue;  
                         if (IN6_IS_ADDR_LINKLOCAL(&satosin6(ifa->ifa_addr)->sin6_addr))  
                                 return;  
                 }  
         } else  
                 ifap = &ifp->if_addrlist;  
 #else  
         ifa = TAILQ_FIRST(&ifp->if_addrlist);          ifa = TAILQ_FIRST(&ifp->if_addrlist);
         if (ifa != NULL) {          if (ifa != NULL) {
                 for ( ; ifa; ifa = TAILQ_NEXT(ifa, ifa_list)) {                  for ( ; ifa; ifa = TAILQ_NEXT(ifa, ifa_list)) {
Line 401  in6_ifattach(ifp, type, laddr, noloop)
Line 250  in6_ifattach(ifp, type, laddr, noloop)
                         if (IN6_IS_ADDR_LINKLOCAL(&satosin6(ifa->ifa_addr)->sin6_addr))                          if (IN6_IS_ADDR_LINKLOCAL(&satosin6(ifa->ifa_addr)->sin6_addr))
                                 return;                                  return;
                 }                  }
         } else {          } else
                 TAILQ_INIT(&ifp->if_addrlist);                  TAILQ_INIT(&ifp->if_addrlist);
         }  
 #endif  
   
         /*          /*
          * link-local address           * link-local address
Line 415  in6_ifattach(ifp, type, laddr, noloop)
Line 262  in6_ifattach(ifp, type, laddr, noloop)
         ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;          ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
         ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;          ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
         ia->ia_ifp = ifp;          ia->ia_ifp = ifp;
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
         *ifap = (struct ifaddr *)ia;  
 #else  
         TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);          TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
 #endif  
         /*          /*
          * Also link into the IPv6 address chain beginning with in6_ifaddr.           * Also link into the IPv6 address chain beginning with in6_ifaddr.
          * kazu opposed it, but itojun & jinmei wanted.           * kazu opposed it, but itojun & jinmei wanted.
Line 455  in6_ifattach(ifp, type, laddr, noloop)
Line 298  in6_ifattach(ifp, type, laddr, noloop)
         case IN6_IFT_P2P802:          case IN6_IFT_P2P802:
                 if (laddr == NULL)                  if (laddr == NULL)
                         break;                          break;
                 /* XXX use laddrlen */                  ieee802_to_eui64(&ia->ia_addr.sin6_addr.s6_addr8[8], laddr);
                 if (laddr_to_eui64(&ia->ia_addr.sin6_addr.s6_addr8[8],                  /* set global bit */
                                 laddr, 6) != 0) {                  ia->ia_addr.sin6_addr.s6_addr8[8] |= 0x02;
                         break;                  if (! found_first_ifid) {
                 }  
                 /* invert u bit to convert EUI64 to RFC2373 interface ID. */  
                 ia->ia_addr.sin6_addr.s6_addr8[8] ^= 0x02;  
                 if (found_first_ifid == 0) {  
                         if (in6_ifattach_getifid(ifp) == 0)                          if (in6_ifattach_getifid(ifp) == 0)
                                 in6_ifattach_p2p();                                  in6_ifattach_p2p();
                 }                  }
Line 472  in6_ifattach(ifp, type, laddr, noloop)
Line 311  in6_ifattach(ifp, type, laddr, noloop)
                       (caddr_t)&ia->ia_addr.sin6_addr.s6_addr8[8],                        (caddr_t)&ia->ia_addr.sin6_addr.s6_addr8[8],
                       IFID_LEN);                        IFID_LEN);
                 break;                  break;
         case IN6_IFT_ARCNET:  
                 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;  
                 ia->ia_ifa.ifa_flags |= RTF_CLONING;  
                 rtflag = RTF_CLONING;  
                 if (laddr == NULL)  
                         break;  
   
                 /* make non-global IF id out of link-level address */  
                 bzero(&ia->ia_addr.sin6_addr.s6_addr8[8], 7);  
                 ia->ia_addr.sin6_addr.s6_addr8[15] = *laddr;  
         }          }
   
         ia->ia_ifa.ifa_metric = ifp->if_metric;          ia->ia_ifa.ifa_metric = ifp->if_metric;
Line 501  in6_ifattach(ifp, type, laddr, noloop)
Line 330  in6_ifattach(ifp, type, laddr, noloop)
                 if (error) {                  if (error) {
                         switch (error) {                          switch (error) {
                         case EAFNOSUPPORT:                          case EAFNOSUPPORT:
                                 printf("%s: IPv6 not supported\n",                                  printf("%s: IPv6 is not supported\n",
                                         if_name(ifp));                                          ifp->if_xname);
                                 break;                                  break;
                         default:                          default:
                                 printf("%s: SIOCSIFADDR error %d\n",                                  printf("SIOCSIFADDR(%s) returned %d\n",
                                         if_name(ifp), error);                                          ifp->if_xname, error);
                                 break;                                  break;
                         }                          }
   
                         /* undo changes */                          /* undo changes */
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
                         *ifap = NULL;  
 #else  
                         TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);                          TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
 #endif  
                         if (oia)                          if (oia)
                                 oia->ia_next = ia->ia_next;                                  oia->ia_next = ia->ia_next;
                         else                          else
Line 534  in6_ifattach(ifp, type, laddr, noloop)
Line 359  in6_ifattach(ifp, type, laddr, noloop)
                   (struct rtentry **)0);                    (struct rtentry **)0);
         ia->ia_flags |= IFA_ROUTE;          ia->ia_flags |= IFA_ROUTE;
   
   
         if (type == IN6_IFT_P2P || type == IN6_IFT_P2P802) {          if (type == IN6_IFT_P2P || type == IN6_IFT_P2P802) {
                 /*                  /*
                  * route local address to loopback                   * route local address to loopback
Line 568  in6_ifattach(ifp, type, laddr, noloop)
Line 394  in6_ifattach(ifp, type, laddr, noloop)
                 ib->ia_ifp = ifp;                  ib->ia_ifp = ifp;
   
                 ia->ia_next = ib;                  ia->ia_next = ib;
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
                 ia->ia_ifa.ifa_next = (struct ifaddr *)ib;  
 #else  
                 TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ib,                  TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ib,
                         ifa_list);                          ifa_list);
 #endif  
   
                 ib->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6);                  ib->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
                 ib->ia_prefixmask.sin6_family = AF_INET6;                  ib->ia_prefixmask.sin6_family = AF_INET6;
Line 611  in6_ifattach(ifp, type, laddr, noloop)
Line 433  in6_ifattach(ifp, type, laddr, noloop)
         if (ifp->if_flags & IFF_MULTICAST) {          if (ifp->if_flags & IFF_MULTICAST) {
                 int error;      /* not used */                  int error;      /* not used */
   
 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)  #if !defined(__FreeBSD__) || __FreeBSD__ < 3
                 /* Restore saved multicast addresses(if any). */                  /* Restore saved multicast addresses(if any). */
                 in6_restoremkludge(ia, ifp);                  in6_restoremkludge(ia, ifp);
 #endif  #endif
Line 665  in6_ifattach(ifp, type, laddr, noloop)
Line 487  in6_ifattach(ifp, type, laddr, noloop)
         }          }
   
         /* update dynamically. */          /* update dynamically. */
           in6_iflladdr[ifp->if_index] = &ia->ia_addr.sin6_addr;
         if (in6_maxmtu < ifp->if_mtu)          if (in6_maxmtu < ifp->if_mtu)
                 in6_maxmtu = ifp->if_mtu;                  in6_maxmtu = ifp->if_mtu;
   
         if (in6_ifstat[ifp->if_index] == NULL) {  
                 in6_ifstat[ifp->if_index] = (struct in6_ifstat *)  
                         malloc(sizeof(struct in6_ifstat), M_IFADDR, M_WAITOK);  
                 bzero(in6_ifstat[ifp->if_index], sizeof(struct in6_ifstat));  
         }  
         if (icmp6_ifstat[ifp->if_index] == NULL) {  
                 icmp6_ifstat[ifp->if_index] = (struct icmp6_ifstat *)  
                         malloc(sizeof(struct icmp6_ifstat), M_IFADDR, M_WAITOK);  
                 bzero(icmp6_ifstat[ifp->if_index], sizeof(struct icmp6_ifstat));  
         }  
   
         /* initialize NDP variables */          /* initialize NDP variables */
         nd6_ifattach(ifp);          nd6_ifattach(ifp);
   
         /* mark the address TENTATIVE, if needed. */          /* mark the address TENTATIVE, if needed. */
         switch (ifp->if_type) {          switch (ifp->if_type) {
         case IFT_ARCNET:  
         case IFT_ETHER:          case IFT_ETHER:
         case IFT_FDDI:          case IFT_FDDI:
 #if 0  #if 0
Line 695  in6_ifattach(ifp, type, laddr, noloop)
Line 506  in6_ifattach(ifp, type, laddr, noloop)
                 ia->ia6_flags |= IN6_IFF_TENTATIVE;                  ia->ia6_flags |= IN6_IFF_TENTATIVE;
                 /* nd6_dad_start() will be called in in6_if_up */                  /* nd6_dad_start() will be called in in6_if_up */
                 break;                  break;
         case IFT_DUMMY:          case IFT_GIF:
         case IFT_GIF:   /*XXX*/  
         case IFT_LOOP:          case IFT_LOOP:
         case IFT_FAITH:          case IFT_FAITH:
         default:          default:
Line 712  in6_ifdetach(ifp)
Line 522  in6_ifdetach(ifp)
 {  {
         struct in6_ifaddr *ia, *oia;          struct in6_ifaddr *ia, *oia;
         struct ifaddr *ifa;          struct ifaddr *ifa;
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
         struct ifaddr *ifaprev = NULL;  
 #endif  
         struct rtentry *rt;          struct rtentry *rt;
         short rtflags;          short rtflags;
   
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)          for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {
         for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)  
 #else  
         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)  
 #endif  
         {  
                 if (ifa->ifa_addr->sa_family != AF_INET6                  if (ifa->ifa_addr->sa_family != AF_INET6
                  || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) {                   || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) {
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
                         ifaprev = ifa;  
 #endif  
                         continue;                          continue;
                 }                  }
   
Line 736  in6_ifdetach(ifp)
Line 535  in6_ifdetach(ifp)
   
                 /* remove from the routing table */                  /* remove from the routing table */
                 if ((ia->ia_flags & IFA_ROUTE)                  if ((ia->ia_flags & IFA_ROUTE)
                  && (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0                   && (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0))) {
 #ifdef __FreeBSD__  
                                 , 0UL  
 #endif  
                                 ))) {  
                         rtflags = rt->rt_flags;                          rtflags = rt->rt_flags;
                         rtfree(rt);                          rtfree(rt);
                         rtrequest(RTM_DELETE,                          rtrequest(RTM_DELETE,
Line 751  in6_ifdetach(ifp)
Line 546  in6_ifdetach(ifp)
                 }                  }
   
                 /* remove from the linked list */                  /* remove from the linked list */
 #if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)  
                 if (ifaprev)  
                         ifaprev->ifa_next = ifa->ifa_next;  
                 else  
                         ifp->if_addrlist = ifa->ifa_next;  
 #else  
                 TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);                  TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
 #endif  
   
                 /* also remove from the IPv6 address chain(itojun&jinmei) */                  /* also remove from the IPv6 address chain(itojun&jinmei) */
                 oia = ia;                  oia = ia;
Line 769  in6_ifdetach(ifp)
Line 557  in6_ifdetach(ifp)
                                 ia = ia->ia_next;                                  ia = ia->ia_next;
                         if (ia->ia_next)                          if (ia->ia_next)
                                 ia->ia_next = oia->ia_next;                                  ia->ia_next = oia->ia_next;
 #ifdef DEBUG  
                         else                          else
                                 printf("%s: didn't unlink in6ifaddr from "                                  printf("Didn't unlink in6ifaddr from list\n");
                                     "list\n", if_name(ifp));  
 #endif  
                 }                  }
   
                 free(ia, M_IFADDR);                  free(ia, M_IFADDR);

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.2

CVSweb <webmaster@jp.NetBSD.org>