]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/bsd_tcpip/v2_0/src/sys/netinet6/in6_src.c
Initial revision
[karo-tx-redboot.git] / packages / net / bsd_tcpip / v2_0 / src / sys / netinet6 / in6_src.c
1 //==========================================================================
2 //
3 //      src/sys/netinet6/in6_src.c
4 //
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
7 //
8 // -------------------------------------------
9 //
10 // Portions of this software may have been derived from OpenBSD, 
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
13 //
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
16 //
17 // -------------------------------------------
18 //
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
21
22 /*      $KAME: in6_src.c,v 1.96 2001/12/24 10:39:29 jinmei Exp $        */
23
24 /*
25  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
26  * All rights reserved.
27  *
28  * Redistribution and use in source and binary forms, with or without
29  * modification, are permitted provided that the following conditions
30  * are met:
31  * 1. Redistributions of source code must retain the above copyright
32  *    notice, this list of conditions and the following disclaimer.
33  * 2. Redistributions in binary form must reproduce the above copyright
34  *    notice, this list of conditions and the following disclaimer in the
35  *    documentation and/or other materials provided with the distribution.
36  * 3. Neither the name of the project nor the names of its contributors
37  *    may be used to endorse or promote products derived from this software
38  *    without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */
52
53 /*
54  * Copyright (c) 1982, 1986, 1991, 1993
55  *      The Regents of the University of California.  All rights reserved.
56  *
57  * Redistribution and use in source and binary forms, with or without
58  * modification, are permitted provided that the following conditions
59  * are met:
60  * 1. Redistributions of source code must retain the above copyright
61  *    notice, this list of conditions and the following disclaimer.
62  * 2. Redistributions in binary form must reproduce the above copyright
63  *    notice, this list of conditions and the following disclaimer in the
64  *    documentation and/or other materials provided with the distribution.
65  * 3. All advertising materials mentioning features or use of this software
66  *    must display the following acknowledgement:
67  *      This product includes software developed by the University of
68  *      California, Berkeley and its contributors.
69  * 4. Neither the name of the University nor the names of its contributors
70  *    may be used to endorse or promote products derived from this software
71  *    without specific prior written permission.
72  *
73  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83  * SUCH DAMAGE.
84  *
85  *      @(#)in_pcb.c    8.2 (Berkeley) 1/4/94
86  */
87
88 #include <sys/param.h>
89 #include <sys/malloc.h>
90 #include <sys/mbuf.h>
91 #include <sys/protosw.h>
92 #include <sys/socket.h>
93 #include <sys/socketvar.h>
94 #include <sys/sockio.h>
95 #include <sys/errno.h>
96
97 #include <net/if.h>
98 #include <net/route.h>
99
100 #include <netinet/in.h>
101 #include <netinet/in_var.h>
102 #include <netinet/in_systm.h>
103 #include <netinet/ip.h>
104 #include <netinet/in_pcb.h>
105 #include <netinet6/in6_var.h>
106 #include <netinet/ip6.h>
107 #include <netinet6/ip6_var.h>
108 #include <netinet6/in6_pcb.h>
109 #include <netinet6/nd6.h>
110 #include <netinet6/scope6_var.h> 
111
112 #ifdef MIP6
113 #include <netinet6/mip6.h>
114 #endif /* MIP6 */
115
116 #if defined(__NetBSD__)
117 extern struct ifnet loif[NLOOP];
118 #endif
119
120 #define ADDR_LABEL_NOTAPP (-1)
121 struct in6_addrpolicy defaultaddrpolicy;
122
123 int ip6_prefer_tempaddr = 0;
124
125 #ifdef NEW_STRUCT_ROUTE
126 static int in6_selectif __P((struct sockaddr_in6 *, struct ip6_pktopts *,
127                              struct ip6_moptions *, 
128                              struct route *ro,
129                              struct ifnet **));
130 #else
131 static int in6_selectif __P((struct sockaddr_in6 *, struct ip6_pktopts *,
132                              struct ip6_moptions *, 
133                              struct route_in6 *ro,
134                              struct ifnet **));
135 #endif
136
137 static struct in6_addrpolicy *lookup_addrsel_policy __P((struct sockaddr_in6 *));
138
139 static void init_policy_queue __P((void));
140 static int add_addrsel_policyent __P((struct in6_addrpolicy *));
141 static int delete_addrsel_policyent __P((struct in6_addrpolicy *));
142 static struct in6_addrpolicy *match_addrsel_policy __P((struct sockaddr_in6 *));
143
144 /*
145  * Return an IPv6 address, which is the most appropriate for a given
146  * destination and user specified options.
147  * If necessary, this function lookups the routing table and returns
148  * an entry to the caller for later use.
149  */
150 #define REPLACE(r) do {\
151         if ((r) < sizeof(ip6stat.ip6s_sources_rule) / \
152                 sizeof(ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
153                 ip6stat.ip6s_sources_rule[(r)]++; \
154         /* printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(&ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(&ia->ia_addr.sin6_addr), (r)); */ \
155         goto replace; \
156 } while(0)
157 #define NEXT(r) do {\
158         if ((r) < sizeof(ip6stat.ip6s_sources_rule) / \
159                 sizeof(ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
160                 ip6stat.ip6s_sources_rule[(r)]++; \
161         /* printf("in6_selectsrc: keep %s against %s by %d\n", ia_best ? ip6_sprintf(&ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(&ia->ia_addr.sin6_addr), (r)); */ \
162         goto next;              /* XXX: we can't use 'continue' here */ \
163 } while(0)
164 #define BREAK(r) do { \
165         if ((r) < sizeof(ip6stat.ip6s_sources_rule) / \
166                 sizeof(ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
167                 ip6stat.ip6s_sources_rule[(r)]++; \
168         goto out;               /* XXX: we can't use 'break' here */ \
169 } while(0)
170
171 struct in6_addr *
172 in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
173               struct ip6_moptions *mopts, struct route *ro,
174               struct ifnet **ifpp, struct in6_addr *laddr,
175               int *errorp)
176 {
177         struct in6_addr *dst;
178         struct ifnet *ifp = NULL;
179         struct in6_ifaddr *ia = NULL, *ia_best = NULL;
180         struct in6_pktinfo *pi = NULL;
181         int dst_scope = -1, best_scope = -1, best_matchlen = -1;
182         struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL;
183 #ifdef MIP6
184         struct hif_softc *sc;
185 #ifdef MIP6_ALLOW_COA_FALLBACK
186         struct mip6_bu *mbu_dst;
187         u_int8_t coafallback = 0;
188 #endif
189 #endif
190
191         dst = &dstsock->sin6_addr;
192         *errorp = 0;
193         if (ifpp)
194                 *ifpp = NULL;
195
196         /*
197          * If the source address is explicitly specified by the caller,
198          * check if the requested source address is indeed a unicast address
199          * assigned to the node, and can be used as the packet's source
200          * address.  If everything is okay, use the address as source.
201          */
202         if (opts && (pi = opts->ip6po_pktinfo) &&
203             !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr)) {
204                 struct sockaddr_in6 srcsock;
205                 struct in6_ifaddr *ia6;
206
207                 /* get the outgoing interface */
208                 if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, &ifp))
209                     != 0) {
210                         return(NULL);
211                 }
212
213                 /*
214                  * determine the appropriate zone id of the source based on
215                  * the zone of the destination and the outgoing interface.
216                  */
217                 bzero(&srcsock, sizeof(srcsock));
218                 srcsock.sin6_family = AF_INET6;
219                 srcsock.sin6_len = sizeof(srcsock);
220                 srcsock.sin6_addr = pi->ipi6_addr;
221                 if (ifp) {
222                         int64_t zone;
223
224                         zone = in6_addr2zoneid(ifp, &pi->ipi6_addr);
225                         if (zone < 0) { /* XXX: this should not happen */
226                                 *errorp = EINVAL;
227                                 return(NULL);
228                         }
229                         srcsock.sin6_scope_id = zone;
230                 }
231                 if ((*errorp = in6_embedscope(&srcsock.sin6_addr, &srcsock))
232                     != 0) {
233                         return(NULL);
234                 }
235 #ifndef SCOPEDROUTING
236                 srcsock.sin6_scope_id = 0; /* XXX: ifa_ifwithaddr expects 0 */
237 #endif
238                 ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)(&srcsock));
239                 if (ia6 == NULL ||
240                     (ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) {
241                         *errorp = EADDRNOTAVAIL;
242                         return(NULL);
243                 }
244                 pi->ipi6_addr = srcsock.sin6_addr; /* XXX: this overrides pi */
245                 if (*ifpp)
246                         *ifpp = ifp;
247                 return(&pi->ipi6_addr);
248         }
249
250         /*
251          * Otherwise, if the socket has already bound the source, just use it.
252          */
253         if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
254                 return(laddr);
255
256         /*
257          * If the address is not specified, choose the best one based on
258          * the outgoing interface and the destination address.
259          */
260         /* get the outgoing interface */
261         if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, &ifp)) != 0)
262                 return(NULL);
263
264 #ifdef MIP6
265 #ifdef MIP6_ALLOW_COA_FALLBACK
266         for (sc = TAILQ_FIRST(&hif_softc_list);
267              sc;
268              sc = TAILQ_NEXT(sc, hif_entry)) {
269                 mbu_dst = mip6_bu_list_find_withpaddr(&sc->hif_bu_list, dst);
270                 if (mbu_dst != NULL)
271                         coafallback = mbu_dst->mbu_coafallback;
272         }
273 #endif /* MIP6_ALLOW_COA_FALLBACK */
274 #endif /* MIP6 */
275
276 #ifdef DIAGNOSTIC
277         if (ifp == NULL)        /* this should not happen */
278                 panic("in6_selectsrc: NULL ifp");
279 #endif
280         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
281                 int new_scope = -1, new_matchlen = -1;
282                 struct in6_addrpolicy *new_policy = NULL;
283                 int64_t srczone, dstzone;
284                 struct ifnet *ifp1 = ia->ia_ifp;
285
286                 /*
287                  * We'll never take an address that breaks the scope zone
288                  * of the destination.  We also skip an address if its zone
289                  * does not contain the outgoing interface.
290                  * XXX: we should probably use sin6_scope_id here.
291                  */
292                 if ((dstzone = in6_addr2zoneid(ifp1, dst)) < 0 ||
293                     dstzone != in6_addr2zoneid(ifp, dst)) {
294                         continue;
295                 }
296                 if ((srczone = in6_addr2zoneid(ifp1, &ia->ia_addr.sin6_addr))
297                     < 0 ||
298                     srczone != in6_addr2zoneid(ifp, &ia->ia_addr.sin6_addr)) {
299                         continue;
300                 }
301
302                 /* avoid unusable addresses */
303                 if ((ia->ia6_flags &
304                      (IN6_IFF_NOTREADY | IN6_IFF_ANYCAST | IN6_IFF_DETACHED))) {
305                                 continue;
306                 }
307                 if (!ip6_use_deprecated && IFA6_IS_DEPRECATED(ia))
308                         continue;
309
310                 /* Rule 1: Prefer same address */
311                 if (IN6_ARE_ADDR_EQUAL(dst, &ia->ia_addr.sin6_addr)) {
312                         ia_best = ia;
313                         BREAK(1); /* there should be no better candidate */
314                 }
315
316                 if (ia_best == NULL)
317                         REPLACE(0);
318
319                 /* Rule 2: Prefer appropriate scope */
320                 if (dst_scope < 0)
321                         dst_scope = in6_addrscope(dst);
322                 new_scope = in6_addrscope(&ia->ia_addr.sin6_addr);
323                 if (IN6_ARE_SCOPE_CMP(best_scope, new_scope) < 0) {
324                         if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0)
325                                 REPLACE(2);
326                         NEXT(2);
327                 } else if (IN6_ARE_SCOPE_CMP(new_scope, best_scope) < 0) {
328                         if (IN6_ARE_SCOPE_CMP(new_scope, dst_scope) < 0)
329                                 NEXT(2);
330                         REPLACE(2);
331                 }
332
333                 /*
334                  * Rule 3: Avoid deprecated addresses.  Note that the case of
335                  * !ip6_use_deprecated is already rejected above.
336                  */
337                 if (!IFA6_IS_DEPRECATED(ia_best) && IFA6_IS_DEPRECATED(ia))
338                         NEXT(3);
339                 if (IFA6_IS_DEPRECATED(ia_best) && !IFA6_IS_DEPRECATED(ia))
340                         REPLACE(3);
341
342                 /* Rule 4: Prefer home addresses */
343                 /*
344                  * XXX: This is a TODO.  We should probably merge the MIP6
345                  * case above.
346                  */
347 #ifdef MIP6
348                 /*
349                  * If SA is simultaneously a home address and care-of address
350                  * and SB is not, then prefer SA. Similarly, if SB is
351                  * simultaneously a home address and care-of address and SA is
352                  * not, then prefer SB.
353                  */
354                 {
355                         struct mip6_bu *mbu_ia_best = NULL, *mbu_ia = NULL;
356
357                         if (ia_best->ia6_flags & IN6_IFF_HOME) {
358                                 /*
359                                  * find a binding update entry for ia_best.
360                                  */
361                                 for (sc = TAILQ_FIRST(&hif_softc_list);
362                                      sc;
363                                      sc = TAILQ_NEXT(sc, hif_entry)) {
364                                         mbu_ia_best = mip6_bu_list_find_home_registration(
365                                                 &sc->hif_bu_list,
366                                                 &ia->ia_addr.sin6_addr);
367                                         if (mbu_ia_best)
368                                                 break;
369                                 }
370                         }
371                         if (ia->ia6_flags & IN6_IFF_HOME) {
372                                 /*
373                                  * find a binding update entry for ia.
374                                  */
375                                 for (sc = TAILQ_FIRST(&hif_softc_list);
376                                      sc;
377                                      sc = TAILQ_NEXT(sc, hif_entry)) {
378                                         mbu_ia = mip6_bu_list_find_home_registration(
379                                                 &sc->hif_bu_list,
380                                                 &ia->ia_addr.sin6_addr);
381                                         if (mbu_ia)
382                                                 break;
383                                 }
384                         }
385                         /*
386                          * if the binding update entry for a certain address
387                          * exists and its registration status is
388                          * MIP6_BU_REG_STATE_NOTREG, the address is a home
389                          * address and a care of addres simultaneously.
390                          */
391                         if ((mbu_ia_best &&
392                              (mbu_ia_best->mbu_reg_state
393                               == MIP6_BU_REG_STATE_NOTREG))
394                             &&
395                             !(mbu_ia &&
396                               (mbu_ia->mbu_reg_state
397                                == MIP6_BU_REG_STATE_NOTREG))) {
398                                 NEXT(4);
399                         }
400                         if (!(mbu_ia_best &&
401                               (mbu_ia_best->mbu_reg_state
402                                == MIP6_BU_REG_STATE_NOTREG))
403                             &&
404                             (mbu_ia &&
405                              (mbu_ia->mbu_reg_state
406                               == MIP6_BU_REG_STATE_NOTREG))) {
407                                 REPLACE(4);
408                         }
409                 }
410 #ifdef MIP6_ALLOW_COA_FALLBACK
411                 if (coafallback) {
412                         /*
413                          * if the peer doesn't recognize a home
414                          * address destination option, we will use a
415                          * CoA as a source address instead of a home
416                          * address we have registered before.  Though
417                          * this behavior may arouse a mip6 beleiver's
418                          * anger, is very useful in the current
419                          * transition period that many hosts don't
420                          * recognize a home address destination
421                          * option...
422                          */
423                         if ((ia_best->ia6_flags & IN6_IFF_HOME) == 0 &&
424                             (ia->ia6_flags & IN6_IFF_HOME) != 0) {
425                                 /* XXX will break stat! */
426                                 NEXT(0);
427                         }
428                         if ((ia_best->ia6_flags & IN6_IFF_HOME) != 0 &&
429                             (ia->ia6_flags & IN6_IFF_HOME) == 0) {
430                                 /* XXX will break stat! */
431                                 REPLACE(0);
432                         }
433                 } else
434 #endif
435                 {
436                         /*
437                          * If SA is just a home address and SB is just
438                          * a care-of address, then prefer
439                          * SA. Similarly, if SB is just a home address
440                          * and SA is just a care-of address, then
441                          * prefer SB.
442                          */
443                         if ((ia_best->ia6_flags & IN6_IFF_HOME) != 0 &&
444                             (ia->ia6_flags & IN6_IFF_HOME) == 0) {
445                                 NEXT(4);
446                         }
447                         if ((ia_best->ia6_flags & IN6_IFF_HOME) == 0 &&
448                             (ia->ia6_flags & IN6_IFF_HOME) != 0) {
449                                 REPLACE(4);
450                         }
451                 }
452 #endif /* MIP6 */
453
454                 /* Rule 5: Prefer outgoing interface */
455                 if (ia_best->ia_ifp == ifp && ia->ia_ifp != ifp)
456                         NEXT(5);
457                 if (ia_best->ia_ifp != ifp && ia->ia_ifp == ifp)
458                         REPLACE(5);
459
460                 /*
461                  * Rule 6: Prefer matching label
462                  * Note that best_policy should be non-NULL here.
463                  */
464                 if (dst_policy == NULL)
465                         dst_policy = lookup_addrsel_policy(dstsock);
466                 if (dst_policy->label != ADDR_LABEL_NOTAPP) {
467                         new_policy = lookup_addrsel_policy(&ia->ia_addr);
468                         if (dst_policy->label == best_policy->label &&
469                             dst_policy->label != new_policy->label)
470                                 NEXT(6);
471                         if (dst_policy->label != best_policy->label &&
472                             dst_policy->label == new_policy->label)
473                                 REPLACE(6);
474                 }
475
476                 /*
477                  * Rule 7: Prefer public addresses.
478                  * We allow users to reverse the logic by configuring
479                  * a sysctl variable, so that privacy conscious users can
480                  * always prefer temporary addresses.
481                  */
482                 if (!(ia_best->ia6_flags & IN6_IFF_TEMPORARY) &&
483                     (ia->ia6_flags & IN6_IFF_TEMPORARY)) {
484                         if (ip6_prefer_tempaddr)
485                                 REPLACE(7);
486                         else
487                                 NEXT(7);
488                 }
489                 if ((ia_best->ia6_flags & IN6_IFF_TEMPORARY) &&
490                     !(ia->ia6_flags & IN6_IFF_TEMPORARY)) {
491                         if (ip6_prefer_tempaddr)
492                                 NEXT(7);
493                         else
494                                 REPLACE(7);
495                 }
496
497                 /*
498                  * Rule 8: prefer addresses on alive interfaces.
499                  * This is a KAME specific rule.
500                  */
501                 if ((ia_best->ia_ifp->if_flags & IFF_UP) &&
502                     !(ia->ia_ifp->if_flags & IFF_UP))
503                         NEXT(8);
504                 if (!(ia_best->ia_ifp->if_flags & IFF_UP) &&
505                     (ia->ia_ifp->if_flags & IFF_UP))
506                         REPLACE(8);
507
508                 /*
509                  * Rule 9: prefer addresses on "preferred" interfaces.
510                  * This is a KAME specific rule.
511                  */
512 #define NDI_BEST (nd_ifinfo[ia_best->ia_ifp->if_index])
513 #define NDI_NEW  (nd_ifinfo[ia->ia_ifp->if_index])
514                 if ((NDI_BEST.flags & ND6_IFF_PREFER_SOURCE) &&
515                     !(NDI_NEW.flags & ND6_IFF_PREFER_SOURCE))
516                         NEXT(9);
517                 if (!(NDI_BEST.flags & ND6_IFF_PREFER_SOURCE) &&
518                     (NDI_NEW.flags & ND6_IFF_PREFER_SOURCE))
519                         REPLACE(9);
520 #undef NDI_BEST
521 #undef NDI_NEW
522
523                 /*
524                  * Rule 14: Use longest matching prefix.
525                  * Note: in the address selection draft, this rule is
526                  * documented as "Rule 8".  However, since it is also
527                  * documented that this rule can be overridden, we assign
528                  * a large number so that it is easy to assign smaller numbers
529                  * to more preferred rules.
530                  */
531                 new_matchlen = in6_matchlen(&ia->ia_addr.sin6_addr, dst);
532                 if (best_matchlen < new_matchlen)
533                         REPLACE(14);
534                 if (new_matchlen < best_matchlen)
535                         NEXT(14);
536
537                 /* Rule 15 is reserved. */
538
539                 /*
540                  * Last resort: just keep the current candidate.
541                  * Or, do we need more rules?
542                  */
543                 continue;
544
545           replace:
546                 ia_best = ia;
547                 best_scope = (new_scope >= 0 ? new_scope :
548                               in6_addrscope(&ia_best->ia_addr.sin6_addr));
549                 best_policy = (new_policy ? new_policy :
550                                lookup_addrsel_policy(&ia_best->ia_addr));
551                 best_matchlen = (new_matchlen >= 0 ? new_matchlen :
552                                  in6_matchlen(&ia_best->ia_addr.sin6_addr,
553                                               dst));
554
555           next:
556                 continue;
557
558           out:
559                 break;
560         }
561
562         if ((ia = ia_best) == NULL) {
563                 *errorp = EADDRNOTAVAIL;
564                 return(NULL);
565         }
566
567         if (ifpp)
568                 *ifpp = ifp;
569         return(&ia->ia_addr.sin6_addr);
570 }
571 #undef REPLACE
572 #undef BREAK
573 #undef NEXT
574
575 static int
576 in6_selectif(dstsock, opts, mopts, ro, retifp)
577         struct sockaddr_in6 *dstsock;
578         struct ip6_pktopts *opts;
579         struct ip6_moptions *mopts;
580 #ifdef NEW_STRUCT_ROUTE
581         struct route *ro;
582 #else
583         struct route_in6 *ro;
584 #endif
585         struct ifnet **retifp;
586 {
587         int error, clone;
588         struct rtentry *rt = NULL;
589
590         clone = IN6_IS_ADDR_MULTICAST(&dstsock->sin6_addr) ? 0 : 1;
591         if ((error = in6_selectroute(dstsock, opts, mopts, ro, retifp,
592                                      &rt, clone)) != 0) {
593                 return(error);
594         }
595         /*
596          * Adjust the "outgoing" interface.  If we're going to loop the packet
597          * back to ourselves, the ifp would be the loopback interface.
598          * However, we'd rather know the interface associated to the
599          * destination address (which should probably be one of our own
600          * addresses.)
601          */
602         if (rt && rt->rt_ifa && rt->rt_ifa->ifa_ifp)
603                 *retifp = rt->rt_ifa->ifa_ifp;
604
605         return(0);
606 }
607
608 int
609 in6_selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone)
610         struct sockaddr_in6 *dstsock;
611         struct ip6_pktopts *opts;
612         struct ip6_moptions *mopts;
613 #ifdef NEW_STRUCT_ROUTE
614         struct route *ro;
615 #else
616         struct route_in6 *ro;
617 #endif
618         struct ifnet **retifp;
619         struct rtentry **retrt;
620         int clone;              /* meaningful only for bsdi and freebsd. */
621 {
622         int error = 0;
623         struct ifnet *ifp = NULL;
624         struct rtentry *rt = NULL;
625         struct sockaddr_in6 *sin6_next;
626         struct in6_pktinfo *pi = NULL;
627         struct in6_addr *dst = &dstsock->sin6_addr;
628
629         /* If the caller specify the outgoing interface explicitly, use it. */
630         if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) {
631                 /* XXX boundary check is assumed to be already done. */
632 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
633                 ifp = ifnet_byindex(pi->ipi6_ifindex);
634 #else
635                 ifp = ifindex2ifnet[pi->ipi6_ifindex];
636 #endif
637                 if (ifp != NULL &&
638                     (retrt == NULL || IN6_IS_ADDR_MULTICAST(dst))) {
639                         /*
640                          * we do not have to check nor get the route for
641                          * multicast.
642                          */
643                         goto done;
644                 } else
645                         goto getroute;
646         }
647
648         /*
649          * If the destination address is a multicast address and the outgoing
650          * interface for the address is specified by the caller, use it.
651          */
652         if (IN6_IS_ADDR_MULTICAST(dst) &&
653             mopts != NULL && (ifp = mopts->im6o_multicast_ifp) != NULL) {
654                 goto done; /* we do not need a route for multicast. */
655         }
656
657   getroute:
658         /*
659          * If the next hop address for the packet is specified by the caller,
660          * use it as the gateway.
661          */
662         if (opts && opts->ip6po_nexthop) {
663 #ifdef NEW_STRUCT_ROUTE
664                 struct route *ron;
665 #else
666                 struct route_in6 *ron;
667 #endif
668
669                 sin6_next = satosin6(opts->ip6po_nexthop);
670
671                 /* at this moment, we only support AF_INET6 next hops */
672                 if (sin6_next->sin6_family != AF_INET6) {
673                         error = EAFNOSUPPORT; /* or should we proceed? */
674                         goto done;
675                 }
676
677                 /*
678                  * If the next hop is an IPv6 address, then the node identified
679                  * by that address must be a neighbor of the sending host.
680                  */
681                 ron = &opts->ip6po_nextroute;
682                 if ((ron->ro_rt &&
683                      (ron->ro_rt->rt_flags & (RTF_UP | RTF_LLINFO)) !=
684                      (RTF_UP | RTF_LLINFO)) ||
685                     !SA6_ARE_ADDR_EQUAL(satosin6(&ron->ro_dst), sin6_next)) {
686                         if (ron->ro_rt) {
687                                 RTFREE(ron->ro_rt);
688                                 ron->ro_rt = NULL;
689                         }
690                         *satosin6(&ron->ro_dst) = *sin6_next;
691                 }
692                 if (ron->ro_rt == NULL) {
693                         rtalloc((struct route *)ron); /* multi path case? */
694                         if (ron->ro_rt == NULL ||
695                             !(ron->ro_rt->rt_flags & RTF_LLINFO)) {
696                                 if (ron->ro_rt) {
697                                         RTFREE(ron->ro_rt);
698                                         ron->ro_rt = NULL;
699                                 }
700                                 error = EHOSTUNREACH;
701                                 goto done;
702                         }
703                 }
704                 rt = ron->ro_rt;
705                 ifp = rt->rt_ifp;
706
707                 /*
708                  * When cloning is required, try to allocate a route to the
709                  * destination so that the caller can store path MTU
710                  * information.
711                  */
712                 if (!clone)
713                         goto done;
714         }
715
716         /*
717          * Use a cached route if it exists and is valid, else try to allocate
718          * a new one.
719          */
720         if (ro) {
721                 int newroute = 0;
722
723                 if (ro->ro_rt &&
724                     (!(ro->ro_rt->rt_flags & RTF_UP) ||
725                      !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr,
726                                         dst))) {
727                         RTFREE(ro->ro_rt);
728                         ro->ro_rt = (struct rtentry *)NULL;
729                 }
730                 if (ro->ro_rt == (struct rtentry *)NULL) {
731                         struct sockaddr_in6 *sa6;
732
733                         /* No route yet, so try to acquire one */
734                         newroute = 1;
735                         bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
736                         sa6 = (struct sockaddr_in6 *)&ro->ro_dst;
737                         sa6->sin6_family = AF_INET6;
738                         sa6->sin6_len = sizeof(struct sockaddr_in6);
739                         sa6->sin6_addr = *dst;
740 #ifdef SCOPEDROUTING
741                         sa6->sin6_scope_id = dstsock->sin6_scope_id;
742 #endif
743                         if (clone) {
744 #ifdef __bsdi__
745                                 rtcalloc((struct route *)ro);
746 #else  /* !bsdi */
747 #ifdef RADIX_MPATH
748                                 rtalloc_mpath((struct route *)ro,
749                                     ntohl(dstsock->sin6_addr.s6_addr32[3]));
750 #else
751                                 rtalloc((struct route *)ro);
752 #endif /* RADIX_MPATH */
753 #endif /* bsdi */
754                         } else {
755 #ifdef __FreeBSD__
756                                 ro->ro_rt = rtalloc1(&((struct route *)ro)
757                                                      ->ro_dst, (int)NULL, 0UL);
758 #else
759 #ifdef RADIX_MPATH
760                                 rtalloc_mpath((struct route *)ro,
761                                     ntohl(dstsock->sin6_addr.s6_addr32[3]));
762 #else
763                                 ro->ro_rt = rtalloc1(&((struct route *)ro)
764                                                      ->ro_dst, NULL);
765 #endif /* RADIX_MPATH */
766 #endif /* __FreeBSD__ */
767                         }
768                 }
769
770                 /*
771                  * do not care about the result if we have the nexthop
772                  * explicitly specified.
773                  */
774                 if (opts && opts->ip6po_nexthop)
775                         goto done;
776
777                 if (ro->ro_rt) {
778                         ifp = ro->ro_rt->rt_ifp;
779
780                         if (ifp == NULL) { /* can this really happen? */
781                                 RTFREE(ro->ro_rt);
782                                 ro->ro_rt = NULL;
783                         }
784                 }
785                 if (ro->ro_rt == NULL)
786                         error = EHOSTUNREACH;
787                 rt = ro->ro_rt;
788
789                 /*
790                  * Check if the outgoing interface conflicts with
791                  * the interface specified by ipi6_ifindex (if specified).
792                  * Note that loopback interface is always okay.
793                  * (this may happen when we are sending a packet to one of
794                  *  our own addresses.)
795                  */
796                 if (opts && opts->ip6po_pktinfo
797                     && opts->ip6po_pktinfo->ipi6_ifindex) {
798                         if (!(ifp->if_flags & IFF_LOOPBACK) &&
799                             ifp->if_index !=
800                             opts->ip6po_pktinfo->ipi6_ifindex) {
801                                 error = EHOSTUNREACH;
802                                 goto done;
803                         }
804                 }
805         }
806
807   done:
808         if (error == EHOSTUNREACH)
809                 ip6stat.ip6s_noroute++;
810
811         if (retifp != NULL)
812                 *retifp = ifp;
813         if (retrt != NULL)
814                 *retrt = rt;    /* rt may be NULL */
815         
816         return(error);
817 }
818
819 /*
820  * Default hop limit selection. The precedence is as follows:
821  * 1. Hoplimit value specified via ioctl.
822  * 2. (If the outgoing interface is detected) the current
823  *     hop limit of the interface specified by router advertisement.
824  * 3. The system default hoplimit.
825 */
826 #ifdef HAVE_NRL_INPCB
827 #define in6pcb          inpcb
828 #define in6p_hops       inp_hops        
829 #endif
830 int
831 in6_selecthlim(struct in6pcb *in6p, struct ifnet *ifp)
832 {
833         if (in6p && in6p->in6p_hops >= 0)
834                 return(in6p->in6p_hops);
835         else if (ifp)
836                 return(nd_ifinfo[ifp->if_index].chlim);
837         else
838                 return(ip6_defhlim);
839 }
840 #ifdef HAVE_NRL_INPCB
841 #undef in6pcb
842 #undef in6p_hops
843 #endif
844
845 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__)
846 /*
847  * Find an empty port and set it to the specified PCB.
848  */
849 #ifdef HAVE_NRL_INPCB   /* XXX: I really hate such ugly macros...(jinmei) */
850 #define in6pcb          inpcb
851 #define in6p_socket     inp_socket
852 #define in6p_lport      inp_lport
853 #define in6p_head       inp_head
854 #define in6p_flags      inp_flags
855 #define IN6PLOOKUP_WILDCARD INPLOOKUP_WILDCARD
856 #endif
857 int
858 in6_pcbsetport(struct in6_addr *laddr, struct in6pcb *in6p)
859 {
860         struct socket *so = in6p->in6p_socket;
861         struct in6pcb *head = in6p->in6p_head;
862         u_int16_t last_port, lport = 0;
863         int wild = 0;
864         void *t;
865         u_int16_t min, max;
866
867         /* XXX: this is redundant when called from in6_pcbbind */
868         if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
869            ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
870             (so->so_options & SO_ACCEPTCONN) == 0))
871                 wild = IN6PLOOKUP_WILDCARD;
872
873         if (in6p->in6p_flags & IN6P_LOWPORT) {
874                 min = ip6_lowportmin;
875                 max = ip6_lowportmax;
876         } else {
877                 min = ip6_anonportmin;
878                 max = ip6_anonportmax;
879         }
880
881         /* value out of range */
882         if (head->in6p_lport < min)
883                 head->in6p_lport = min;
884         else if (head->in6p_lport > max)
885                 head->in6p_lport = min;
886         last_port = head->in6p_lport;
887         goto startover; /*to randomize*/
888         for (;;) {
889                 lport = htons(head->in6p_lport);
890                 if (IN6_IS_ADDR_V4MAPPED(laddr)) {
891 #ifdef HAVE_NRL_INPCB
892 #ifdef INPLOOKUP_WILDCARD6
893                         wild &= ~INPLOOKUP_WILDCARD6;
894 #endif
895 #endif
896 #if 0
897                         t = in_pcblookup_bind(&tcbtable,
898                                               (struct in_addr *)&in6p->in6p_laddr.s6_addr32[3],
899                                               lport);
900 #else
901                         t = NULL;
902 #endif
903                 } else {
904 #ifdef HAVE_NRL_INPCB
905 #ifdef INPLOOKUP_WILDCARD4
906                         wild &= ~INPLOOKUP_WILDCARD4;
907 #endif
908                         /* XXX: ugly cast... */
909                         t = in_pcblookup(head, (struct in_addr *)&zeroin6_addr,
910                                          0, (struct in_addr *)laddr,
911                                          lport, wild | INPLOOKUP_IPV6);
912 #else
913                         t = in6_pcblookup(head, &zeroin6_addr, 0, laddr,
914                                           lport, wild);
915 #endif
916                 }
917                 if (t == 0)
918                         break;
919           startover:
920                 if (head->in6p_lport >= max)
921                         head->in6p_lport = min;
922                 else
923                         head->in6p_lport++;
924                 if (head->in6p_lport == last_port)
925                         return (EADDRINUSE);
926         }
927
928         in6p->in6p_lport = lport;
929         return(0);              /* success */
930 }
931 #ifdef HAVE_NRL_INPCB
932 #undef in6pcb
933 #undef in6p_socket
934 #undef in6p_lport
935 #undef in6p_head
936 #undef in6p_flags
937 #undef IN6PLOOKUP_WILDCARD
938 #endif
939 #endif /* !FreeBSD3 && !OpenBSD*/
940
941 #if (defined(__FreeBSD__) && __FreeBSD__ >= 3)
942 /*
943  * XXX: this is borrowed from in6_pcbbind(). If possible, we should
944  * share this function by all *bsd*...
945  */
946 int
947 in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p)
948 {
949         struct socket *so = inp->inp_socket;
950         u_int16_t lport = 0, first, last, *lastport;
951         int count, wild = 0;
952         struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
953
954         /* XXX: this is redundant when called from in6_pcbbind */
955         if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
956                 wild = INPLOOKUP_WILDCARD;
957
958         inp->inp_flags |= INP_ANONPORT;
959
960         if (inp->inp_flags & INP_HIGHPORT) {
961                 first = ipport_hifirstauto;     /* sysctl */
962                 last  = ipport_hilastauto;
963                 lastport = &pcbinfo->lasthi;
964         } else if (inp->inp_flags & INP_LOWPORT) {
965                 first = ipport_lowfirstauto;    /* 1023 */
966                 last  = ipport_lowlastauto;     /* 600 */
967                 lastport = &pcbinfo->lastlow;
968         } else {
969                 first = ipport_firstauto;       /* sysctl */
970                 last  = ipport_lastauto;
971                 lastport = &pcbinfo->lastport;
972         }
973         /*
974          * Simple check to ensure all ports are not used up causing
975          * a deadlock here.
976          *
977          * We split the two cases (up and down) so that the direction
978          * is not being tested on each round of the loop.
979          */
980         if (first > last) {
981                 /*
982                  * counting down
983                  */
984                 count = first - last;
985
986                 do {
987                         if (count-- < 0) {      /* completely used? */
988                                 /*
989                                  * Undo any address bind that may have
990                                  * occurred above.
991                                  */
992                                 inp->in6p_laddr = in6addr_any;
993                                 return (EAGAIN);
994                         }
995                         --*lastport;
996                         if (*lastport > first || *lastport < last)
997                                 *lastport = first;
998                         lport = htons(*lastport);
999                 } while (in6_pcblookup_local(pcbinfo,
1000                                              &inp->in6p_laddr, lport, wild));
1001         } else {
1002                 /*
1003                          * counting up
1004                          */
1005                 count = last - first;
1006
1007                 do {
1008                         if (count-- < 0) {      /* completely used? */
1009                                 /*
1010                                  * Undo any address bind that may have
1011                                  * occurred above.
1012                                  */
1013                                 inp->in6p_laddr = in6addr_any;
1014                                 return (EAGAIN);
1015                         }
1016                         ++*lastport;
1017                         if (*lastport < first || *lastport > last)
1018                                 *lastport = first;
1019                         lport = htons(*lastport);
1020                 } while (in6_pcblookup_local(pcbinfo,
1021                                              &inp->in6p_laddr, lport, wild));
1022         }
1023
1024         inp->inp_lport = lport;
1025         if (in_pcbinshash(inp) != 0) {
1026                 inp->in6p_laddr = in6addr_any;
1027                 inp->inp_lport = 0;
1028                 return (EAGAIN);
1029         }
1030
1031         return(0);
1032 }
1033 #endif
1034
1035 /*
1036  * Generate kernel-internal form (scopeid embedded into s6_addr16[1]).
1037  * If the address scope of is interface-local or link-local, embed the
1038  * interface index in the address.
1039  *
1040  * This function should be nuked in the future, when we get rid of embedded
1041  * scopeid thing.
1042  */
1043 int
1044 in6_embedscope(in6, sin6)
1045         struct in6_addr *in6;
1046         const struct sockaddr_in6 *sin6;
1047 {
1048 #ifdef SCOPEDROUTING
1049         /*
1050          * XXX: the SCOPEDROUTING code path is NOT expected to work at this
1051          * moment (20011112).  We added this just in case.
1052          */
1053         return(0);              /* do nothing */
1054 #else
1055         struct ifnet *ifp;
1056         u_int32_t zoneid = sin6->sin6_scope_id;
1057
1058         *in6 = sin6->sin6_addr;
1059
1060         /*
1061          * don't try to read sin6->sin6_addr beyond here, since the caller may
1062          * ask us to overwrite existing sockaddr_in6
1063          */
1064
1065         if (IN6_IS_SCOPE_LINKLOCAL(in6) || IN6_IS_ADDR_MC_INTFACELOCAL(in6)) {
1066                 /* KAME assumption: link id == interface id */
1067                 if (zoneid) {
1068                         if (if_index < zoneid)
1069                                 return(ENXIO);  /* XXX EINVAL? */
1070 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
1071                         ifp = ifnet_byindex(zoneid);
1072 #else
1073                         ifp = ifindex2ifnet[zoneid];
1074 #endif
1075                         if (ifp == NULL) /* XXX: this can happen for some OS */
1076                                 return(ENXIO);
1077
1078                         /* XXX assignment to 16bit from 32bit variable */
1079                         in6->s6_addr16[1] = htons(zoneid & 0xffff);
1080                 }
1081         }
1082
1083         return 0;
1084 #endif
1085 }
1086
1087 /*
1088  * generate standard sockaddr_in6 from embedded form.
1089  * touches sin6_addr and sin6_scope_id only.
1090  *
1091  * this function should be nuked in the future, when we get rid of
1092  * embedded scopeid thing.
1093  */
1094 int
1095 in6_recoverscope(sin6, in6, ifp)
1096         struct sockaddr_in6 *sin6;
1097         const struct in6_addr *in6;
1098         struct ifnet *ifp;
1099 {
1100         u_int32_t zoneid;
1101
1102         sin6->sin6_addr = *in6;
1103
1104         /*
1105          * don't try to read *in6 beyond here, since the caller may
1106          * ask us to overwrite existing sockaddr_in6
1107          */
1108
1109         sin6->sin6_scope_id = 0;
1110         if (IN6_IS_SCOPE_LINKLOCAL(in6) || IN6_IS_ADDR_MC_INTFACELOCAL(in6)) {
1111                 /*
1112                  * KAME assumption: link id == interface id
1113                  */
1114                 zoneid = ntohs(sin6->sin6_addr.s6_addr16[1]);
1115                 if (zoneid) {
1116                         /* sanity check */
1117                         if (zoneid < 0 || if_index < zoneid)
1118                                 return ENXIO;
1119                         if (ifp && ifp->if_index != zoneid)
1120                                 return ENXIO;
1121                         sin6->sin6_addr.s6_addr16[1] = 0;
1122                         sin6->sin6_scope_id = zoneid;
1123                 }
1124         }
1125
1126         return 0;
1127 }
1128
1129 /*
1130  * just clear the embedded scope identifer.
1131  * XXX: currently used for bsdi4 only as a supplement function.
1132  */
1133 void
1134 in6_clearscope(addr)
1135         struct in6_addr *addr;
1136 {
1137         if (IN6_IS_SCOPE_LINKLOCAL(addr) || IN6_IS_ADDR_MC_INTFACELOCAL(addr))
1138                 addr->s6_addr16[1] = 0;
1139 }
1140
1141 void
1142 addrsel_policy_init()
1143 {
1144         init_policy_queue();
1145
1146         /* initialize the "last resort" policy */
1147         bzero(&defaultaddrpolicy, sizeof(defaultaddrpolicy));
1148         defaultaddrpolicy.label = ADDR_LABEL_NOTAPP;
1149 }
1150
1151 static struct in6_addrpolicy *
1152 lookup_addrsel_policy(key)
1153         struct sockaddr_in6 *key;
1154 {
1155         struct in6_addrpolicy *match = NULL;
1156
1157         match = match_addrsel_policy(key);
1158
1159         if (match == NULL)
1160                 match = &defaultaddrpolicy;
1161         else
1162                 match->use++;
1163
1164         return(match);
1165 }
1166
1167
1168 int
1169 in6_src_ioctl(cmd, data)
1170         u_long cmd;
1171         caddr_t data;
1172 {
1173         int i;
1174         struct in6_addrpolicy ent0;
1175
1176         if (cmd != SIOCAADDRCTL_POLICY && cmd != SIOCDADDRCTL_POLICY)
1177                 return(EOPNOTSUPP); /* check for safety */
1178
1179         ent0 = *(struct in6_addrpolicy *)data;
1180
1181         if (ent0.label == ADDR_LABEL_NOTAPP)
1182                 return(EINVAL);
1183         /* check if the prefix mask is consecutive. */
1184         if (in6_mask2len(&ent0.addrmask.sin6_addr, NULL) < 0)
1185                 return(EINVAL);
1186         /* clear trailing garbages (if any) of the prefix address. */
1187         for (i = 0; i < 4; i++) {
1188                 ent0.addr.sin6_addr.s6_addr32[i] &=
1189                         ent0.addrmask.sin6_addr.s6_addr32[i];
1190         }
1191         ent0.use = 0;
1192
1193         switch (cmd) {
1194         case SIOCAADDRCTL_POLICY:
1195                 return(add_addrsel_policyent(&ent0));
1196         case SIOCDADDRCTL_POLICY:
1197                 return(delete_addrsel_policyent(&ent0));
1198         }
1199
1200         return(0);              /* XXX: compromise compilers */
1201 }
1202
1203 /*
1204  * The followings are implementation of the policy table using a
1205  * simple tail queue.
1206  * XXX such details should be hidden.
1207  * XXX implementation using binary tree should be more efficient.
1208  */
1209 struct addrsel_policyent {
1210         TAILQ_ENTRY(addrsel_policyent) ape_entry;
1211         struct in6_addrpolicy ape_policy;
1212 };
1213
1214 TAILQ_HEAD(addrsel_policyhead, addrsel_policyent);
1215
1216 struct addrsel_policyhead addrsel_policytab;
1217
1218 static void
1219 init_policy_queue()
1220 {
1221         TAILQ_INIT(&addrsel_policytab);
1222 }
1223
1224 static int
1225 add_addrsel_policyent(newpolicy)
1226         struct in6_addrpolicy *newpolicy;
1227 {
1228         struct addrsel_policyent *new, *pol;
1229
1230         /* duplication check */
1231         for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
1232              pol = TAILQ_NEXT(pol, ape_entry)) {
1233                 if (SA6_ARE_ADDR_EQUAL(&newpolicy->addr,
1234                                        &pol->ape_policy.addr) &&
1235                     SA6_ARE_ADDR_EQUAL(&newpolicy->addrmask,
1236                                        &pol->ape_policy.addrmask)) {
1237                         return(EEXIST); /* or override it? */
1238                 }
1239         }
1240
1241         MALLOC(new, struct addrsel_policyent *, sizeof(*new), M_IFADDR,
1242                M_WAITOK);
1243         bzero(new, sizeof(*new));
1244
1245         /* XXX: should validate entry */
1246         new->ape_policy = *newpolicy;
1247
1248         TAILQ_INSERT_TAIL(&addrsel_policytab, new, ape_entry);
1249
1250         return(0);
1251 }
1252
1253 static int
1254 delete_addrsel_policyent(key)
1255         struct in6_addrpolicy *key;
1256 {
1257         struct addrsel_policyent *pol;
1258
1259         /* search for the entry in the table */
1260         for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
1261              pol = TAILQ_NEXT(pol, ape_entry)) {
1262                 if (SA6_ARE_ADDR_EQUAL(&key->addr, &pol->ape_policy.addr) &&
1263                     SA6_ARE_ADDR_EQUAL(&key->addrmask,
1264                                        &pol->ape_policy.addrmask)) {
1265                         break;
1266                 }
1267         }
1268         if (pol == NULL)
1269                 return(ESRCH);
1270
1271         TAILQ_REMOVE(&addrsel_policytab, pol, ape_entry);
1272
1273         return(0);
1274 }
1275
1276 void
1277 _show_addrsel_policy(void)
1278 {
1279         struct addrsel_policyent *pol;
1280
1281         log(LOG_ADDR, "IPv6 address policy table\n");
1282         for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
1283              pol = TAILQ_NEXT(pol, ape_entry)) {
1284             log(LOG_ADDR, "Addr: \n");
1285             log_dump(LOG_ADDR, &pol->ape_policy.addr, 16);
1286             log(LOG_ADDR, "Mask:\n");
1287             log_dump(LOG_ADDR, &pol->ape_policy.addrmask, 16);
1288         }
1289 }
1290
1291 static struct in6_addrpolicy *
1292 match_addrsel_policy(key)
1293         struct sockaddr_in6 *key;
1294 {
1295         struct addrsel_policyent *pent;
1296         struct in6_addrpolicy *bestpol = NULL, *pol;
1297         int matchlen, bestmatchlen = -1;
1298         u_char *mp, *ep, *k, *p, m;
1299
1300         for (pent = TAILQ_FIRST(&addrsel_policytab); pent;
1301              pent = TAILQ_NEXT(pent, ape_entry)) {
1302                 matchlen = 0;
1303
1304                 pol = &pent->ape_policy;
1305                 mp = (u_char *)&pol->addrmask.sin6_addr;
1306                 ep = mp + 16;   /* XXX: scope field? */
1307                 k = (u_char *)&key->sin6_addr;
1308                 p = (u_char *)&pol->addr.sin6_addr;
1309                 for (; mp < ep && *mp; mp++, k++, p++) {
1310                         m = *mp;
1311                         if ((*k & m) != *p)
1312                                 goto next; /* not match */
1313                         if (m == 0xff) /* short cut for a typical case */
1314                                 matchlen += 8;
1315                         else {
1316                                 while(m >= 0x80) {
1317                                         matchlen++;
1318                                         m <<= 1;
1319                                 }
1320                         }
1321                 }
1322
1323                 /* matched.  check if this is better than the current best. */
1324                 if (bestpol == NULL ||
1325                     matchlen > bestmatchlen) {
1326                         bestpol = pol;
1327                         bestmatchlen = matchlen;
1328                 }
1329
1330           next:
1331                 continue;
1332         }
1333
1334         return(bestpol);
1335 }