proc->thread stage 4: rework the VFS and DEVICE subsystems to take thread
[dragonfly.git] / sys / netinet6 / in6_ifattach.c
1 /*      $FreeBSD: src/sys/netinet6/in6_ifattach.c,v 1.2.2.6 2002/04/28 05:40:26 suz Exp $       */
2 /*      $DragonFly: src/sys/netinet6/in6_ifattach.c,v 1.2 2003/06/17 04:28:52 dillon Exp $      */
3 /*      $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $  */
4
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/socket.h>
38 #include <sys/sockio.h>
39 #include <sys/kernel.h>
40 #include <sys/syslog.h>
41 #include <sys/md5.h>
42
43 #include <net/if.h>
44 #include <net/if_dl.h>
45 #include <net/if_types.h>
46 #include <net/route.h>
47
48 #include <netinet/in.h>
49 #include <netinet/in_var.h>
50 #include <netinet/if_ether.h>
51 #include <netinet/in_pcb.h>
52
53 #include <netinet/ip6.h>
54 #include <netinet6/ip6_var.h>
55 #include <netinet6/in6_var.h>
56 #include <netinet6/in6_pcb.h>
57 #include <netinet6/in6_ifattach.h>
58 #include <netinet6/ip6_var.h>
59 #include <netinet6/nd6.h>
60 #include <netinet6/scope6_var.h>
61
62 #include <net/net_osdep.h>
63
64 struct in6_ifstat **in6_ifstat = NULL;
65 struct icmp6_ifstat **icmp6_ifstat = NULL;
66 size_t in6_ifstatmax = 0;
67 size_t icmp6_ifstatmax = 0;
68 unsigned long in6_maxmtu = 0;
69
70 #ifdef IP6_AUTO_LINKLOCAL
71 int ip6_auto_linklocal = IP6_AUTO_LINKLOCAL;
72 #else
73 int ip6_auto_linklocal = 1;     /* enable by default */
74 #endif
75
76 struct callout in6_tmpaddrtimer_ch;
77
78 extern struct inpcbinfo udbinfo;
79 extern struct inpcbinfo ripcbinfo;
80
81 static int get_rand_ifid __P((struct ifnet *, struct in6_addr *));
82 static int generate_tmp_ifid __P((u_int8_t *, const u_int8_t *, u_int8_t *));
83 static int get_hw_ifid __P((struct ifnet *, struct in6_addr *));
84 static int get_ifid __P((struct ifnet *, struct ifnet *, struct in6_addr *));
85 static int in6_ifattach_linklocal __P((struct ifnet *, struct ifnet *));
86 static int in6_ifattach_loopback __P((struct ifnet *));
87
88 #define EUI64_GBIT      0x01
89 #define EUI64_UBIT      0x02
90 #define EUI64_TO_IFID(in6)      do {(in6)->s6_addr[8] ^= EUI64_UBIT; } while (0)
91 #define EUI64_GROUP(in6)        ((in6)->s6_addr[8] & EUI64_GBIT)
92 #define EUI64_INDIVIDUAL(in6)   (!EUI64_GROUP(in6))
93 #define EUI64_LOCAL(in6)        ((in6)->s6_addr[8] & EUI64_UBIT)
94 #define EUI64_UNIVERSAL(in6)    (!EUI64_LOCAL(in6))
95
96 #define IFID_LOCAL(in6)         (!EUI64_LOCAL(in6))
97 #define IFID_UNIVERSAL(in6)     (!EUI64_UNIVERSAL(in6))
98
99 /*
100  * Generate a last-resort interface identifier, when the machine has no
101  * IEEE802/EUI64 address sources.
102  * The goal here is to get an interface identifier that is
103  * (1) random enough and (2) does not change across reboot.
104  * We currently use MD5(hostname) for it.
105  */
106 static int
107 get_rand_ifid(ifp, in6)
108         struct ifnet *ifp;
109         struct in6_addr *in6;   /* upper 64bits are preserved */
110 {
111         MD5_CTX ctxt;
112         u_int8_t digest[16];
113         int hostnamelen = strlen(hostname);
114
115 #if 0
116         /* we need at least several letters as seed for ifid */
117         if (hostnamelen < 3)
118                 return -1;
119 #endif
120
121         /* generate 8 bytes of pseudo-random value. */
122         bzero(&ctxt, sizeof(ctxt));
123         MD5Init(&ctxt);
124         MD5Update(&ctxt, hostname, hostnamelen);
125         MD5Final(digest, &ctxt);
126
127         /* assumes sizeof(digest) > sizeof(ifid) */
128         bcopy(digest, &in6->s6_addr[8], 8);
129
130         /* make sure to set "u" bit to local, and "g" bit to individual. */
131         in6->s6_addr[8] &= ~EUI64_GBIT; /* g bit to "individual" */
132         in6->s6_addr[8] |= EUI64_UBIT;  /* u bit to "local" */
133
134         /* convert EUI64 into IPv6 interface identifier */
135         EUI64_TO_IFID(in6);
136
137         return 0;
138 }
139
140 static int
141 generate_tmp_ifid(seed0, seed1, ret)
142         u_int8_t *seed0, *ret;
143         const u_int8_t *seed1;
144 {
145         MD5_CTX ctxt;
146         u_int8_t seed[16], digest[16], nullbuf[8];
147         u_int32_t val32;
148         struct timeval tv;
149
150         /* If there's no hisotry, start with a random seed. */
151         bzero(nullbuf, sizeof(nullbuf));
152         if (bcmp(nullbuf, seed0, sizeof(nullbuf)) == 0) {
153                 int i;
154
155                 for (i = 0; i < 2; i++) {
156                         microtime(&tv);
157                         val32 = random() ^ tv.tv_usec;
158                         bcopy(&val32, seed + sizeof(val32) * i, sizeof(val32));
159                 }
160         } else {
161                 bcopy(seed0, seed, 8);
162         }
163
164         /* copy the right-most 64-bits of the given address */
165         /* XXX assumption on the size of IFID */
166         bcopy(seed1, &seed[8], 8);
167
168         if (0) {                /* for debugging purposes only */
169                 int i;
170
171                 printf("generate_tmp_ifid: new randomized ID from: ");
172                 for (i = 0; i < 16; i++)
173                         printf("%02x", seed[i]);
174                 printf(" ");
175         }
176
177         /* generate 16 bytes of pseudo-random value. */
178         bzero(&ctxt, sizeof(ctxt));
179         MD5Init(&ctxt);
180         MD5Update(&ctxt, seed, sizeof(seed));
181         MD5Final(digest, &ctxt);
182
183         /*
184          * RFC 3041 3.2.1. (3)
185          * Take the left-most 64-bits of the MD5 digest and set bit 6 (the
186          * left-most bit is numbered 0) to zero.
187          */
188         bcopy(digest, ret, 8);
189         ret[0] &= ~EUI64_UBIT;
190
191         /*
192          * XXX: we'd like to ensure that the generated value is not zero
193          * for simplicity.  If the caclculated digest happens to be zero,
194          * use a random non-zero value as the last resort.
195          */
196         if (bcmp(nullbuf, ret, sizeof(nullbuf)) == 0) {
197                 log(LOG_INFO,
198                     "generate_tmp_ifid: computed MD5 value is zero.\n");
199
200                 microtime(&tv);
201                 val32 = random() ^ tv.tv_usec;
202                 val32 = 1 + (val32 % (0xffffffff - 1));
203         }
204
205         /*
206          * RFC 3041 3.2.1. (4)
207          * Take the rightmost 64-bits of the MD5 digest and save them in
208          * stable storage as the history value to be used in the next
209          * iteration of the algorithm. 
210          */
211         bcopy(&digest[8], seed0, 8);
212
213         if (0) {                /* for debugging purposes only */
214                 int i;
215
216                 printf("to: ");
217                 for (i = 0; i < 16; i++)
218                         printf("%02x", digest[i]);
219                 printf("\n");
220         }
221
222         return 0;
223 }
224
225 /*
226  * Get interface identifier for the specified interface.
227  * XXX assumes single sockaddr_dl (AF_LINK address) per an interface
228  */
229 static int
230 get_hw_ifid(ifp, in6)
231         struct ifnet *ifp;
232         struct in6_addr *in6;   /* upper 64bits are preserved */
233 {
234         struct ifaddr *ifa;
235         struct sockaddr_dl *sdl;
236         u_int8_t *addr;
237         size_t addrlen;
238         static u_int8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
239         static u_int8_t allone[8] =
240                 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
241
242         for (ifa = ifp->if_addrlist.tqh_first;
243              ifa;
244              ifa = ifa->ifa_list.tqe_next)
245         {
246                 if (ifa->ifa_addr->sa_family != AF_LINK)
247                         continue;
248                 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
249                 if (sdl == NULL)
250                         continue;
251                 if (sdl->sdl_alen == 0)
252                         continue;
253
254                 goto found;
255         }
256
257         return -1;
258
259 found:
260         addr = LLADDR(sdl);
261         addrlen = sdl->sdl_alen;
262
263         /* get EUI64 */
264         switch (ifp->if_type) {
265         case IFT_ETHER:
266         case IFT_FDDI:
267         case IFT_ATM:
268         case IFT_IEEE1394:
269 #ifdef IFT_IEEE80211
270         case IFT_IEEE80211:
271 #endif
272                 /* IEEE802/EUI64 cases - what others? */
273                 /* IEEE1394 uses 16byte length address starting with EUI64 */
274                 if (addrlen > 8)
275                         addrlen = 8;
276
277                 /* look at IEEE802/EUI64 only */
278                 if (addrlen != 8 && addrlen != 6)
279                         return -1;
280
281                 /*
282                  * check for invalid MAC address - on bsdi, we see it a lot
283                  * since wildboar configures all-zero MAC on pccard before
284                  * card insertion.
285                  */
286                 if (bcmp(addr, allzero, addrlen) == 0)
287                         return -1;
288                 if (bcmp(addr, allone, addrlen) == 0)
289                         return -1;
290
291                 /* make EUI64 address */
292                 if (addrlen == 8)
293                         bcopy(addr, &in6->s6_addr[8], 8);
294                 else if (addrlen == 6) {
295                         in6->s6_addr[8] = addr[0];
296                         in6->s6_addr[9] = addr[1];
297                         in6->s6_addr[10] = addr[2];
298                         in6->s6_addr[11] = 0xff;
299                         in6->s6_addr[12] = 0xfe;
300                         in6->s6_addr[13] = addr[3];
301                         in6->s6_addr[14] = addr[4];
302                         in6->s6_addr[15] = addr[5];
303                 }
304                 break;
305
306         case IFT_ARCNET:
307                 if (addrlen != 1)
308                         return -1;
309                 if (!addr[0])
310                         return -1;
311
312                 bzero(&in6->s6_addr[8], 8);
313                 in6->s6_addr[15] = addr[0];
314
315                 /*
316                  * due to insufficient bitwidth, we mark it local.
317                  */
318                 in6->s6_addr[8] &= ~EUI64_GBIT; /* g bit to "individual" */
319                 in6->s6_addr[8] |= EUI64_UBIT;  /* u bit to "local" */
320                 break;
321
322         case IFT_GIF:
323 #ifdef IFT_STF
324         case IFT_STF:
325 #endif
326                 /*
327                  * RFC2893 says: "SHOULD use IPv4 address as ifid source".
328                  * however, IPv4 address is not very suitable as unique
329                  * identifier source (can be renumbered).
330                  * we don't do this.
331                  */
332                 return -1;
333
334         default:
335                 return -1;
336         }
337
338         /* sanity check: g bit must not indicate "group" */
339         if (EUI64_GROUP(in6))
340                 return -1;
341
342         /* convert EUI64 into IPv6 interface identifier */
343         EUI64_TO_IFID(in6);
344
345         /*
346          * sanity check: ifid must not be all zero, avoid conflict with
347          * subnet router anycast
348          */
349         if ((in6->s6_addr[8] & ~(EUI64_GBIT | EUI64_UBIT)) == 0x00 &&
350             bcmp(&in6->s6_addr[9], allzero, 7) == 0) {
351                 return -1;
352         }
353
354         return 0;
355 }
356
357 /*
358  * Get interface identifier for the specified interface.  If it is not
359  * available on ifp0, borrow interface identifier from other information
360  * sources.
361  */
362 static int
363 get_ifid(ifp0, altifp, in6)
364         struct ifnet *ifp0;
365         struct ifnet *altifp;   /* secondary EUI64 source */
366         struct in6_addr *in6;
367 {
368         struct ifnet *ifp;
369
370         /* first, try to get it from the interface itself */
371         if (get_hw_ifid(ifp0, in6) == 0) {
372                 nd6log((LOG_DEBUG, "%s: got interface identifier from itself\n",
373                     if_name(ifp0)));
374                 goto success;
375         }
376
377         /* try secondary EUI64 source. this basically is for ATM PVC */
378         if (altifp && get_hw_ifid(altifp, in6) == 0) {
379                 nd6log((LOG_DEBUG, "%s: got interface identifier from %s\n",
380                     if_name(ifp0), if_name(altifp)));
381                 goto success;
382         }
383
384         /* next, try to get it from some other hardware interface */
385         for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
386         {
387                 if (ifp == ifp0)
388                         continue;
389                 if (get_hw_ifid(ifp, in6) != 0)
390                         continue;
391
392                 /*
393                  * to borrow ifid from other interface, ifid needs to be
394                  * globally unique
395                  */
396                 if (IFID_UNIVERSAL(in6)) {
397                         nd6log((LOG_DEBUG,
398                             "%s: borrow interface identifier from %s\n",
399                             if_name(ifp0), if_name(ifp)));
400                         goto success;
401                 }
402         }
403
404         /* last resort: get from random number source */
405         if (get_rand_ifid(ifp, in6) == 0) {
406                 nd6log((LOG_DEBUG,
407                     "%s: interface identifier generated by random number\n",
408                     if_name(ifp0)));
409                 goto success;
410         }
411
412         printf("%s: failed to get interface identifier\n", if_name(ifp0));
413         return -1;
414
415 success:
416         nd6log((LOG_INFO, "%s: ifid: "
417                 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
418                 if_name(ifp0),
419                 in6->s6_addr[8], in6->s6_addr[9],
420                 in6->s6_addr[10], in6->s6_addr[11],
421                 in6->s6_addr[12], in6->s6_addr[13],
422                 in6->s6_addr[14], in6->s6_addr[15]));
423         return 0;
424 }
425
426 static int
427 in6_ifattach_linklocal(ifp, altifp)
428         struct ifnet *ifp;
429         struct ifnet *altifp;   /* secondary EUI64 source */
430 {
431         struct in6_ifaddr *ia;
432         struct in6_aliasreq ifra;
433         struct nd_prefix pr0;
434         int i, error;
435
436         /*
437          * configure link-local address.
438          */
439         bzero(&ifra, sizeof(ifra));
440
441         /*
442          * in6_update_ifa() does not use ifra_name, but we accurately set it
443          * for safety.
444          */
445         strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
446
447         ifra.ifra_addr.sin6_family = AF_INET6;
448         ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
449         ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
450 #ifdef SCOPEDROUTING
451         ifra.ifra_addr.sin6_addr.s6_addr16[1] = 0
452 #else
453         ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); /* XXX */
454 #endif
455         ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0;
456         if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
457                 ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0;
458                 ifra.ifra_addr.sin6_addr.s6_addr32[3] = htonl(1);
459         } else {
460                 if (get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr) != 0) {
461                         nd6log((LOG_ERR,
462                             "%s: no ifid available\n", if_name(ifp)));
463                         return -1;
464                 }
465         }
466 #ifdef SCOPEDROUTING
467         ifra.ifra_addr.sin6_scope_id =
468                 in6_addr2scopeid(ifp,  &ifra.ifra_addr.sin6_addr);
469 #endif
470
471         ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
472         ifra.ifra_prefixmask.sin6_family = AF_INET6;
473         ifra.ifra_prefixmask.sin6_addr = in6mask64;
474 #ifdef SCOPEDROUTING
475         /* take into accound the sin6_scope_id field for routing */
476         ifra.ifra_prefixmask.sin6_scope_id = 0xffffffff;
477 #endif
478         /* link-local addresses should NEVER expire. */
479         ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
480         ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
481
482         /*
483          * Do not let in6_update_ifa() do DAD, since we need a random delay
484          * before sending an NS at the first time the interface becomes up.
485          * Instead, in6_if_up() will start DAD with a proper random delay.
486          */
487         ifra.ifra_flags |= IN6_IFF_NODAD;
488
489         /*
490          * Now call in6_update_ifa() to do a bunch of procedures to configure
491          * a link-local address. We can set NULL to the 3rd argument, because
492          * we know there's no other link-local address on the interface
493          * and therefore we are adding one (instead of updating one).
494          */
495         if ((error = in6_update_ifa(ifp, &ifra, NULL)) != 0) {
496                 /*
497                  * XXX: When the interface does not support IPv6, this call
498                  * would fail in the SIOCSIFADDR ioctl.  I believe the
499                  * notification is rather confusing in this case, so just
500                  * supress it.  (jinmei@kame.net 20010130)
501                  */
502                 if (error != EAFNOSUPPORT)
503                         log(LOG_NOTICE, "in6_ifattach_linklocal: failed to "
504                             "configure a link-local address on %s "
505                             "(errno=%d)\n",
506                             if_name(ifp), error);
507                 return(-1);
508         }
509
510         /*
511          * Adjust ia6_flags so that in6_if_up will perform DAD.
512          * XXX: Some P2P interfaces seem not to send packets just after
513          * becoming up, so we skip p2p interfaces for safety.
514          */
515         ia = in6ifa_ifpforlinklocal(ifp, 0); /* ia must not be NULL */
516 #ifdef DIAGNOSTIC
517         if (!ia) {
518                 panic("ia == NULL in in6_ifattach_linklocal");
519                 /* NOTREACHED */
520         }
521 #endif
522         if (in6if_do_dad(ifp) && (ifp->if_flags & IFF_POINTOPOINT) == 0) {
523                 ia->ia6_flags &= ~IN6_IFF_NODAD;
524                 ia->ia6_flags |= IN6_IFF_TENTATIVE;
525         }
526
527         /*
528          * Make the link-local prefix (fe80::/64%link) as on-link.
529          * Since we'd like to manage prefixes separately from addresses,
530          * we make an ND6 prefix structure for the link-local prefix,
531          * and add it to the prefix list as a never-expire prefix.
532          * XXX: this change might affect some existing code base...
533          */
534         bzero(&pr0, sizeof(pr0));
535         pr0.ndpr_ifp = ifp;
536         /* this should be 64 at this moment. */
537         pr0.ndpr_plen = in6_mask2len(&ifra.ifra_prefixmask.sin6_addr, NULL);
538         pr0.ndpr_mask = ifra.ifra_prefixmask.sin6_addr;
539         pr0.ndpr_prefix = ifra.ifra_addr;
540         /* apply the mask for safety. (nd6_prelist_add will apply it again) */
541         for (i = 0; i < 4; i++) {
542                 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
543                         in6mask64.s6_addr32[i];
544         }
545         /*
546          * Initialize parameters.  The link-local prefix must always be
547          * on-link, and its lifetimes never expire.
548          */
549         pr0.ndpr_raf_onlink = 1;
550         pr0.ndpr_raf_auto = 1;  /* probably meaningless */
551         pr0.ndpr_vltime = ND6_INFINITE_LIFETIME;
552         pr0.ndpr_pltime = ND6_INFINITE_LIFETIME;
553         /*
554          * Since there is no other link-local addresses, nd6_prefix_lookup()
555          * probably returns NULL.  However, we cannot always expect the result.
556          * For example, if we first remove the (only) existing link-local
557          * address, and then reconfigure another one, the prefix is still
558          * valid with referring to the old link-local address.
559          */
560         if (nd6_prefix_lookup(&pr0) == NULL) {
561                 if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0)
562                         return(error);
563         }
564
565         return 0;
566 }
567
568 static int
569 in6_ifattach_loopback(ifp)
570         struct ifnet *ifp;      /* must be IFT_LOOP */
571 {
572         struct in6_aliasreq ifra;
573         int error;
574
575         bzero(&ifra, sizeof(ifra));
576
577         /*
578          * in6_update_ifa() does not use ifra_name, but we accurately set it
579          * for safety.
580          */
581         strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
582
583         ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
584         ifra.ifra_prefixmask.sin6_family = AF_INET6;
585         ifra.ifra_prefixmask.sin6_addr = in6mask128;
586
587         /*
588          * Always initialize ia_dstaddr (= broadcast address) to loopback
589          * address.  Follows IPv4 practice - see in_ifinit().
590          */
591         ifra.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
592         ifra.ifra_dstaddr.sin6_family = AF_INET6;
593         ifra.ifra_dstaddr.sin6_addr = in6addr_loopback;
594
595         ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
596         ifra.ifra_addr.sin6_family = AF_INET6;
597         ifra.ifra_addr.sin6_addr = in6addr_loopback;
598
599         /* the loopback  address should NEVER expire. */
600         ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
601         ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
602
603         /* we don't need to perform DAD on loopback interfaces. */
604         ifra.ifra_flags |= IN6_IFF_NODAD;
605
606         /* skip registration to the prefix list. XXX should be temporary. */
607         ifra.ifra_flags |= IN6_IFF_NOPFX;
608
609         /*
610          * We are sure that this is a newly assigned address, so we can set
611          * NULL to the 3rd arg.
612          */
613         if ((error = in6_update_ifa(ifp, &ifra, NULL)) != 0) {
614                 log(LOG_ERR, "in6_ifattach_loopback: failed to configure "
615                     "the loopback address on %s (errno=%d)\n",
616                     if_name(ifp), error);
617                 return(-1);
618         }
619
620         return 0;
621 }
622
623 /*
624  * compute NI group address, based on the current hostname setting.
625  * see draft-ietf-ipngwg-icmp-name-lookup-* (04 and later).
626  *
627  * when ifp == NULL, the caller is responsible for filling scopeid.
628  */
629 int
630 in6_nigroup(ifp, name, namelen, in6)
631         struct ifnet *ifp;
632         const char *name;
633         int namelen;
634         struct in6_addr *in6;
635 {
636         const char *p;
637         u_char *q;
638         MD5_CTX ctxt;
639         u_int8_t digest[16];
640         char l;
641         char n[64];     /* a single label must not exceed 63 chars */
642
643         if (!namelen || !name)
644                 return -1;
645
646         p = name;
647         while (p && *p && *p != '.' && p - name < namelen)
648                 p++;
649         if (p - name > sizeof(n) - 1)
650                 return -1;      /* label too long */
651         l = p - name;
652         strncpy(n, name, l);
653         n[(int)l] = '\0';
654         for (q = n; *q; q++) {
655                 if ('A' <= *q && *q <= 'Z')
656                         *q = *q - 'A' + 'a';
657         }
658
659         /* generate 8 bytes of pseudo-random value. */
660         bzero(&ctxt, sizeof(ctxt));
661         MD5Init(&ctxt);
662         MD5Update(&ctxt, &l, sizeof(l));
663         MD5Update(&ctxt, n, l);
664         MD5Final(digest, &ctxt);
665
666         bzero(in6, sizeof(*in6));
667         in6->s6_addr16[0] = htons(0xff02);
668         if (ifp)
669                 in6->s6_addr16[1] = htons(ifp->if_index);
670         in6->s6_addr8[11] = 2;
671         bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
672
673         return 0;
674 }
675
676 void
677 in6_nigroup_attach(name, namelen)
678         const char *name;
679         int namelen;
680 {
681         struct ifnet *ifp;
682         struct sockaddr_in6 mltaddr;
683         struct in6_multi *in6m;
684         int error;
685
686         bzero(&mltaddr, sizeof(mltaddr));
687         mltaddr.sin6_family = AF_INET6;
688         mltaddr.sin6_len = sizeof(struct sockaddr_in6);
689         if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0)
690                 return;
691
692         for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
693         {
694                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
695                 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
696                 if (!in6m) {
697                         if (!in6_addmulti(&mltaddr.sin6_addr, ifp, &error)) {
698                                 nd6log((LOG_ERR, "%s: failed to join %s "
699                                     "(errno=%d)\n", if_name(ifp),
700                                     ip6_sprintf(&mltaddr.sin6_addr), 
701                                     error));
702                         }
703                 }
704         }
705 }
706
707 void
708 in6_nigroup_detach(name, namelen)
709         const char *name;
710         int namelen;
711 {
712         struct ifnet *ifp;
713         struct sockaddr_in6 mltaddr;
714         struct in6_multi *in6m;
715
716         bzero(&mltaddr, sizeof(mltaddr));
717         mltaddr.sin6_family = AF_INET6;
718         mltaddr.sin6_len = sizeof(struct sockaddr_in6);
719         if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0)
720                 return;
721
722         for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
723         {
724                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
725                 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
726                 if (in6m)
727                         in6_delmulti(in6m);
728         }
729 }
730
731 /*
732  * XXX multiple loopback interface needs more care.  for instance,
733  * nodelocal address needs to be configured onto only one of them.
734  * XXX multiple link-local address case
735  */
736 void
737 in6_ifattach(ifp, altifp)
738         struct ifnet *ifp;
739         struct ifnet *altifp;   /* secondary EUI64 source */
740 {
741         static size_t if_indexlim = 8;
742         struct in6_ifaddr *ia;
743         struct in6_addr in6;
744
745         /* some of the interfaces are inherently not IPv6 capable */
746         switch (ifp->if_type) {
747 #ifdef IFT_BRIDGE       /*OpenBSD 2.8*/
748         case IFT_BRIDGE:
749                 return;
750 #endif
751         }
752
753         /*
754          * We have some arrays that should be indexed by if_index.
755          * since if_index will grow dynamically, they should grow too.
756          *      struct in6_ifstat **in6_ifstat
757          *      struct icmp6_ifstat **icmp6_ifstat
758          */
759         if (in6_ifstat == NULL || icmp6_ifstat == NULL ||
760             if_index >= if_indexlim) {
761                 size_t n;
762                 caddr_t q;
763                 size_t olim;
764
765                 olim = if_indexlim;
766                 while (if_index >= if_indexlim)
767                         if_indexlim <<= 1;
768
769                 /* grow in6_ifstat */
770                 n = if_indexlim * sizeof(struct in6_ifstat *);
771                 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
772                 bzero(q, n);
773                 if (in6_ifstat) {
774                         bcopy((caddr_t)in6_ifstat, q,
775                                 olim * sizeof(struct in6_ifstat *));
776                         free((caddr_t)in6_ifstat, M_IFADDR);
777                 }
778                 in6_ifstat = (struct in6_ifstat **)q;
779                 in6_ifstatmax = if_indexlim;
780
781                 /* grow icmp6_ifstat */
782                 n = if_indexlim * sizeof(struct icmp6_ifstat *);
783                 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
784                 bzero(q, n);
785                 if (icmp6_ifstat) {
786                         bcopy((caddr_t)icmp6_ifstat, q,
787                                 olim * sizeof(struct icmp6_ifstat *));
788                         free((caddr_t)icmp6_ifstat, M_IFADDR);
789                 }
790                 icmp6_ifstat = (struct icmp6_ifstat **)q;
791                 icmp6_ifstatmax = if_indexlim;
792         }
793
794         /* initialize scope identifiers */
795         scope6_ifattach(ifp);
796
797         /*
798          * quirks based on interface type
799          */
800         switch (ifp->if_type) {
801 #ifdef IFT_STF
802         case IFT_STF:
803                 /*
804                  * 6to4 interface is a very special kind of beast.
805                  * no multicast, no linklocal.  RFC2529 specifies how to make
806                  * linklocals for 6to4 interface, but there's no use and
807                  * it is rather harmful to have one.
808                  */
809                 goto statinit;
810 #endif
811         default:
812                 break;
813         }
814
815         /*
816          * usually, we require multicast capability to the interface
817          */
818         if ((ifp->if_flags & IFF_MULTICAST) == 0) {
819                 log(LOG_INFO, "in6_ifattach: "
820                     "%s is not multicast capable, IPv6 not enabled\n",
821                     if_name(ifp));
822                 return;
823         }
824
825         /*
826          * assign loopback address for loopback interface.
827          * XXX multiple loopback interface case.
828          */
829         if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
830                 in6 = in6addr_loopback;
831                 if (in6ifa_ifpwithaddr(ifp, &in6) == NULL) {
832                         if (in6_ifattach_loopback(ifp) != 0)
833                                 return;
834                 }
835         }
836
837         /*
838          * assign a link-local address, if there's none. 
839          */
840         if (ip6_auto_linklocal) {
841                 ia = in6ifa_ifpforlinklocal(ifp, 0);
842                 if (ia == NULL) {
843                         if (in6_ifattach_linklocal(ifp, altifp) == 0) {
844                                 /* linklocal address assigned */
845                         } else {
846                                 /* failed to assign linklocal address. bark? */
847                         }
848                 }
849         }
850
851 #ifdef IFT_STF                  /* XXX */
852 statinit:       
853 #endif
854
855         /* update dynamically. */
856         if (in6_maxmtu < ifp->if_mtu)
857                 in6_maxmtu = ifp->if_mtu;
858
859         if (in6_ifstat[ifp->if_index] == NULL) {
860                 in6_ifstat[ifp->if_index] = (struct in6_ifstat *)
861                         malloc(sizeof(struct in6_ifstat), M_IFADDR, M_WAITOK);
862                 bzero(in6_ifstat[ifp->if_index], sizeof(struct in6_ifstat));
863         }
864         if (icmp6_ifstat[ifp->if_index] == NULL) {
865                 icmp6_ifstat[ifp->if_index] = (struct icmp6_ifstat *)
866                         malloc(sizeof(struct icmp6_ifstat), M_IFADDR, M_WAITOK);
867                 bzero(icmp6_ifstat[ifp->if_index], sizeof(struct icmp6_ifstat));
868         }
869
870         /* initialize NDP variables */
871         nd6_ifattach(ifp);
872 }
873
874 /*
875  * NOTE: in6_ifdetach() does not support loopback if at this moment.
876  * We don't need this function in bsdi, because interfaces are never removed
877  * from the ifnet list in bsdi.
878  */
879 void
880 in6_ifdetach(ifp)
881         struct ifnet *ifp;
882 {
883         struct in6_ifaddr *ia, *oia;
884         struct ifaddr *ifa, *next;
885         struct rtentry *rt;
886         short rtflags;
887         struct sockaddr_in6 sin6;
888         struct in6_multi *in6m;
889         struct in6_multi *in6m_next;
890
891         /* nuke prefix list.  this may try to remove some of ifaddrs as well */
892         in6_purgeprefix(ifp);
893
894         /* remove neighbor management table */
895         nd6_purge(ifp);
896
897         /* nuke any of IPv6 addresses we have */
898         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next)
899         {
900                 next = ifa->ifa_list.tqe_next;
901                 if (ifa->ifa_addr->sa_family != AF_INET6)
902                         continue;
903                 in6_purgeaddr(ifa);
904         }
905
906         /* undo everything done by in6_ifattach(), just in case */
907         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next)
908         {
909                 next = ifa->ifa_list.tqe_next;
910
911
912                 if (ifa->ifa_addr->sa_family != AF_INET6
913                  || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) {
914                         continue;
915                 }
916
917                 ia = (struct in6_ifaddr *)ifa;
918
919                 /* remove from the routing table */
920                 if ((ia->ia_flags & IFA_ROUTE)
921                  && (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
922                         rtflags = rt->rt_flags;
923                         rtfree(rt);
924                         rtrequest(RTM_DELETE,
925                                 (struct sockaddr *)&ia->ia_addr,
926                                 (struct sockaddr *)&ia->ia_addr,
927                                 (struct sockaddr *)&ia->ia_prefixmask,
928                                 rtflags, (struct rtentry **)0);
929                 }
930
931                 /* remove from the linked list */
932                 TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
933                 IFAFREE(&ia->ia_ifa);
934
935                 /* also remove from the IPv6 address chain(itojun&jinmei) */
936                 oia = ia;
937                 if (oia == (ia = in6_ifaddr))
938                         in6_ifaddr = ia->ia_next;
939                 else {
940                         while (ia->ia_next && (ia->ia_next != oia))
941                                 ia = ia->ia_next;
942                         if (ia->ia_next)
943                                 ia->ia_next = oia->ia_next;
944                         else {
945                                 nd6log((LOG_ERR, 
946                                     "%s: didn't unlink in6ifaddr from "
947                                     "list\n", if_name(ifp)));
948                         }
949                 }
950
951                 IFAFREE(&oia->ia_ifa);
952         }
953
954         /* leave from all multicast groups joined */
955         in6_pcbpurgeif0(LIST_FIRST(udbinfo.listhead), ifp);
956         in6_pcbpurgeif0(LIST_FIRST(ripcbinfo.listhead), ifp);
957         for (in6m = LIST_FIRST(&in6_multihead); in6m; in6m = in6m_next) {
958                 in6m_next = LIST_NEXT(in6m, in6m_entry);
959                 if (in6m->in6m_ifp != ifp)
960                         continue;
961                 in6_delmulti(in6m);
962                 in6m = NULL;
963         }
964
965         /*
966          * remove neighbor management table.  we call it twice just to make
967          * sure we nuke everything.  maybe we need just one call.
968          * XXX: since the first call did not release addresses, some prefixes
969          * might remain.  We should call nd6_purge() again to release the
970          * prefixes after removing all addresses above.
971          * (Or can we just delay calling nd6_purge until at this point?)
972          */
973         nd6_purge(ifp);
974
975         /* remove route to link-local allnodes multicast (ff02::1) */
976         bzero(&sin6, sizeof(sin6));
977         sin6.sin6_len = sizeof(struct sockaddr_in6);
978         sin6.sin6_family = AF_INET6;
979         sin6.sin6_addr = in6addr_linklocal_allnodes;
980         sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
981         rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
982         if (rt && rt->rt_ifp == ifp) {
983                 rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
984                         rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
985                 rtfree(rt);
986         }
987 }
988
989 void
990 in6_get_tmpifid(ifp, retbuf, baseid, generate)
991         struct ifnet *ifp;
992         u_int8_t *retbuf;
993         const u_int8_t *baseid;
994         int generate;
995 {
996         u_int8_t nullbuf[8];
997         struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
998
999         bzero(nullbuf, sizeof(nullbuf));
1000         if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) {
1001                 /* we've never created a random ID.  Create a new one. */
1002                 generate = 1;
1003         }
1004
1005         if (generate) {
1006                 bcopy(baseid, ndi->randomseed1, sizeof(ndi->randomseed1));
1007
1008                 /* generate_tmp_ifid will update seedn and buf */
1009                 (void)generate_tmp_ifid(ndi->randomseed0, ndi->randomseed1,
1010                                         ndi->randomid);
1011         }
1012         bcopy(ndi->randomid, retbuf, 8);
1013 }
1014
1015 void
1016 in6_tmpaddrtimer(ignored_arg)
1017         void *ignored_arg;
1018 {
1019         int i;
1020         struct nd_ifinfo *ndi;
1021         u_int8_t nullbuf[8];
1022         int s = splnet();
1023
1024         callout_reset(&in6_tmpaddrtimer_ch,
1025                       (ip6_temp_preferred_lifetime - ip6_desync_factor -
1026                        ip6_temp_regen_advance) * hz,
1027                       in6_tmpaddrtimer, NULL);
1028
1029         bzero(nullbuf, sizeof(nullbuf));
1030         for (i = 1; i < if_index + 1; i++) {
1031                 ndi = &nd_ifinfo[i];
1032                 if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
1033                         /*
1034                          * We've been generating a random ID on this interface.
1035                          * Create a new one.
1036                          */
1037                         (void)generate_tmp_ifid(ndi->randomseed0,
1038                                                 ndi->randomseed1,
1039                                                 ndi->randomid);
1040                 }
1041         }
1042
1043         splx(s);
1044 }