xref: /freebsd/sys/netinet6/scope6.c (revision 31b1bfe1b0a6223ca75c72fd80c2a02c33a1fd20)
1686cdd19SJun-ichiro itojun Hagino /*	$FreeBSD$	*/
233841545SHajimu UMEMOTO /*	$KAME: scope6.c,v 1.10 2000/07/24 13:29:31 itojun Exp $	*/
3686cdd19SJun-ichiro itojun Hagino 
4686cdd19SJun-ichiro itojun Hagino /*
5686cdd19SJun-ichiro itojun Hagino  * Copyright (C) 2000 WIDE Project.
6686cdd19SJun-ichiro itojun Hagino  * All rights reserved.
7686cdd19SJun-ichiro itojun Hagino  *
8686cdd19SJun-ichiro itojun Hagino  * Redistribution and use in source and binary forms, with or without
9686cdd19SJun-ichiro itojun Hagino  * modification, are permitted provided that the following conditions
10686cdd19SJun-ichiro itojun Hagino  * are met:
11686cdd19SJun-ichiro itojun Hagino  * 1. Redistributions of source code must retain the above copyright
12686cdd19SJun-ichiro itojun Hagino  *    notice, this list of conditions and the following disclaimer.
13686cdd19SJun-ichiro itojun Hagino  * 2. Redistributions in binary form must reproduce the above copyright
14686cdd19SJun-ichiro itojun Hagino  *    notice, this list of conditions and the following disclaimer in the
15686cdd19SJun-ichiro itojun Hagino  *    documentation and/or other materials provided with the distribution.
16686cdd19SJun-ichiro itojun Hagino  * 3. Neither the name of the project nor the names of its contributors
17686cdd19SJun-ichiro itojun Hagino  *    may be used to endorse or promote products derived from this software
18686cdd19SJun-ichiro itojun Hagino  *    without specific prior written permission.
19686cdd19SJun-ichiro itojun Hagino  *
20686cdd19SJun-ichiro itojun Hagino  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21686cdd19SJun-ichiro itojun Hagino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22686cdd19SJun-ichiro itojun Hagino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23686cdd19SJun-ichiro itojun Hagino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24686cdd19SJun-ichiro itojun Hagino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25686cdd19SJun-ichiro itojun Hagino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26686cdd19SJun-ichiro itojun Hagino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27686cdd19SJun-ichiro itojun Hagino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28686cdd19SJun-ichiro itojun Hagino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29686cdd19SJun-ichiro itojun Hagino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30686cdd19SJun-ichiro itojun Hagino  * SUCH DAMAGE.
31686cdd19SJun-ichiro itojun Hagino  */
32686cdd19SJun-ichiro itojun Hagino 
33686cdd19SJun-ichiro itojun Hagino #include <sys/param.h>
34686cdd19SJun-ichiro itojun Hagino #include <sys/malloc.h>
35686cdd19SJun-ichiro itojun Hagino #include <sys/mbuf.h>
36686cdd19SJun-ichiro itojun Hagino #include <sys/socket.h>
37686cdd19SJun-ichiro itojun Hagino #include <sys/systm.h>
3833841545SHajimu UMEMOTO #include <sys/queue.h>
39686cdd19SJun-ichiro itojun Hagino 
40686cdd19SJun-ichiro itojun Hagino #include <net/route.h>
41686cdd19SJun-ichiro itojun Hagino #include <net/if.h>
42686cdd19SJun-ichiro itojun Hagino 
43686cdd19SJun-ichiro itojun Hagino #include <netinet/in.h>
44686cdd19SJun-ichiro itojun Hagino 
45686cdd19SJun-ichiro itojun Hagino #include <netinet6/in6_var.h>
46686cdd19SJun-ichiro itojun Hagino #include <netinet6/scope6_var.h>
47686cdd19SJun-ichiro itojun Hagino 
4831b1bfe1SHajimu UMEMOTO static struct scope6_id sid_default;
4931b1bfe1SHajimu UMEMOTO #define SID(ifp) \
5031b1bfe1SHajimu UMEMOTO 	(((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id)
51686cdd19SJun-ichiro itojun Hagino 
52686cdd19SJun-ichiro itojun Hagino void
5331b1bfe1SHajimu UMEMOTO scope6_init()
5431b1bfe1SHajimu UMEMOTO {
5531b1bfe1SHajimu UMEMOTO 
5631b1bfe1SHajimu UMEMOTO 	bzero(&sid_default, sizeof(sid_default));
5731b1bfe1SHajimu UMEMOTO }
5831b1bfe1SHajimu UMEMOTO 
5931b1bfe1SHajimu UMEMOTO struct scope6_id *
60686cdd19SJun-ichiro itojun Hagino scope6_ifattach(ifp)
61686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
62686cdd19SJun-ichiro itojun Hagino {
63686cdd19SJun-ichiro itojun Hagino 	int s = splnet();
6431b1bfe1SHajimu UMEMOTO 	struct scope6_id *sid;
65686cdd19SJun-ichiro itojun Hagino 
6631b1bfe1SHajimu UMEMOTO 	sid = (struct scope6_id *)malloc(sizeof(*sid), M_IFADDR, M_WAITOK);
6731b1bfe1SHajimu UMEMOTO 	bzero(sid, sizeof(*sid));
68686cdd19SJun-ichiro itojun Hagino 
69686cdd19SJun-ichiro itojun Hagino 	/*
70686cdd19SJun-ichiro itojun Hagino 	 * XXX: IPV6_ADDR_SCOPE_xxx macros are not standard.
71686cdd19SJun-ichiro itojun Hagino 	 * Should we rather hardcode here?
72686cdd19SJun-ichiro itojun Hagino 	 */
7331b1bfe1SHajimu UMEMOTO 	sid->s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] = ifp->if_index;
7431b1bfe1SHajimu UMEMOTO 	sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = ifp->if_index;
75686cdd19SJun-ichiro itojun Hagino #ifdef MULTI_SCOPE
76686cdd19SJun-ichiro itojun Hagino 	/* by default, we don't care about scope boundary for these scopes. */
7731b1bfe1SHajimu UMEMOTO 	sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL] = 1;
7831b1bfe1SHajimu UMEMOTO 	sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL] = 1;
79686cdd19SJun-ichiro itojun Hagino #endif
80686cdd19SJun-ichiro itojun Hagino 
81686cdd19SJun-ichiro itojun Hagino 	splx(s);
8231b1bfe1SHajimu UMEMOTO 	return sid;
8331b1bfe1SHajimu UMEMOTO }
8431b1bfe1SHajimu UMEMOTO 
8531b1bfe1SHajimu UMEMOTO void
8631b1bfe1SHajimu UMEMOTO scope6_ifdetach(sid)
8731b1bfe1SHajimu UMEMOTO 	struct scope6_id *sid;
8831b1bfe1SHajimu UMEMOTO {
8931b1bfe1SHajimu UMEMOTO 
9031b1bfe1SHajimu UMEMOTO 	free(sid, M_IFADDR);
91686cdd19SJun-ichiro itojun Hagino }
92686cdd19SJun-ichiro itojun Hagino 
93686cdd19SJun-ichiro itojun Hagino int
94686cdd19SJun-ichiro itojun Hagino scope6_set(ifp, idlist)
95686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
9631b1bfe1SHajimu UMEMOTO 	struct scope6_id *idlist;
97686cdd19SJun-ichiro itojun Hagino {
98686cdd19SJun-ichiro itojun Hagino 	int i, s;
99686cdd19SJun-ichiro itojun Hagino 	int error = 0;
10031b1bfe1SHajimu UMEMOTO 	struct scope6_id *sid = SID(ifp);
101686cdd19SJun-ichiro itojun Hagino 
10231b1bfe1SHajimu UMEMOTO 	if (!sid)	/* paranoid? */
103686cdd19SJun-ichiro itojun Hagino 		return (EINVAL);
104686cdd19SJun-ichiro itojun Hagino 
105686cdd19SJun-ichiro itojun Hagino 	/*
106686cdd19SJun-ichiro itojun Hagino 	 * XXX: We need more consistency checks of the relationship among
107686cdd19SJun-ichiro itojun Hagino 	 * scopes (e.g. an organization should be larger than a site).
108686cdd19SJun-ichiro itojun Hagino 	 */
109686cdd19SJun-ichiro itojun Hagino 
110686cdd19SJun-ichiro itojun Hagino 	/*
111686cdd19SJun-ichiro itojun Hagino 	 * TODO(XXX): after setting, we should reflect the changes to
112686cdd19SJun-ichiro itojun Hagino 	 * interface addresses, routing table entries, PCB entries...
113686cdd19SJun-ichiro itojun Hagino 	 */
114686cdd19SJun-ichiro itojun Hagino 
115686cdd19SJun-ichiro itojun Hagino 	s = splnet();
116686cdd19SJun-ichiro itojun Hagino 
117686cdd19SJun-ichiro itojun Hagino 	for (i = 0; i < 16; i++) {
11831b1bfe1SHajimu UMEMOTO 		if (idlist->s6id_list[i] &&
11931b1bfe1SHajimu UMEMOTO 		    idlist->s6id_list[i] != sid->s6id_list[i]) {
120686cdd19SJun-ichiro itojun Hagino 			if (i == IPV6_ADDR_SCOPE_LINKLOCAL &&
12131b1bfe1SHajimu UMEMOTO 			    idlist->s6id_list[i] > if_index) {
122686cdd19SJun-ichiro itojun Hagino 				/*
123686cdd19SJun-ichiro itojun Hagino 				 * XXX: theoretically, there should be no
124686cdd19SJun-ichiro itojun Hagino 				 * relationship between link IDs and interface
125686cdd19SJun-ichiro itojun Hagino 				 * IDs, but we check the consistency for
126686cdd19SJun-ichiro itojun Hagino 				 * safety in later use.
127686cdd19SJun-ichiro itojun Hagino 				 */
128686cdd19SJun-ichiro itojun Hagino 				splx(s);
129686cdd19SJun-ichiro itojun Hagino 				return (EINVAL);
130686cdd19SJun-ichiro itojun Hagino 			}
131686cdd19SJun-ichiro itojun Hagino 
132686cdd19SJun-ichiro itojun Hagino 			/*
133686cdd19SJun-ichiro itojun Hagino 			 * XXX: we must need lots of work in this case,
134686cdd19SJun-ichiro itojun Hagino 			 * but we simply set the new value in this initial
135686cdd19SJun-ichiro itojun Hagino 			 * implementation.
136686cdd19SJun-ichiro itojun Hagino 			 */
13731b1bfe1SHajimu UMEMOTO 			sid->s6id_list[i] = idlist->s6id_list[i];
138686cdd19SJun-ichiro itojun Hagino 		}
139686cdd19SJun-ichiro itojun Hagino 	}
140686cdd19SJun-ichiro itojun Hagino 	splx(s);
141686cdd19SJun-ichiro itojun Hagino 
142686cdd19SJun-ichiro itojun Hagino 	return (error);
143686cdd19SJun-ichiro itojun Hagino }
144686cdd19SJun-ichiro itojun Hagino 
145686cdd19SJun-ichiro itojun Hagino int
146686cdd19SJun-ichiro itojun Hagino scope6_get(ifp, idlist)
147686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;
14831b1bfe1SHajimu UMEMOTO 	struct scope6_id *idlist;
149686cdd19SJun-ichiro itojun Hagino {
15031b1bfe1SHajimu UMEMOTO 	struct scope6_id *sid = SID(ifp);
15131b1bfe1SHajimu UMEMOTO 
15231b1bfe1SHajimu UMEMOTO 	if (sid == NULL)	/* paranoid? */
153686cdd19SJun-ichiro itojun Hagino 		return (EINVAL);
154686cdd19SJun-ichiro itojun Hagino 
15531b1bfe1SHajimu UMEMOTO 	*idlist = *sid;
156686cdd19SJun-ichiro itojun Hagino 
157686cdd19SJun-ichiro itojun Hagino 	return (0);
158686cdd19SJun-ichiro itojun Hagino }
159686cdd19SJun-ichiro itojun Hagino 
160686cdd19SJun-ichiro itojun Hagino 
161686cdd19SJun-ichiro itojun Hagino /*
162686cdd19SJun-ichiro itojun Hagino  * Get a scope of the address. Node-local, link-local, site-local or global.
163686cdd19SJun-ichiro itojun Hagino  */
164686cdd19SJun-ichiro itojun Hagino int
165686cdd19SJun-ichiro itojun Hagino in6_addrscope(addr)
166686cdd19SJun-ichiro itojun Hagino 	struct in6_addr *addr;
167686cdd19SJun-ichiro itojun Hagino {
168686cdd19SJun-ichiro itojun Hagino 	int scope;
169686cdd19SJun-ichiro itojun Hagino 
170686cdd19SJun-ichiro itojun Hagino 	if (addr->s6_addr8[0] == 0xfe) {
171686cdd19SJun-ichiro itojun Hagino 		scope = addr->s6_addr8[1] & 0xc0;
172686cdd19SJun-ichiro itojun Hagino 
173686cdd19SJun-ichiro itojun Hagino 		switch (scope) {
174686cdd19SJun-ichiro itojun Hagino 		case 0x80:
175686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
176686cdd19SJun-ichiro itojun Hagino 			break;
177686cdd19SJun-ichiro itojun Hagino 		case 0xc0:
178686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_SITELOCAL;
179686cdd19SJun-ichiro itojun Hagino 			break;
180686cdd19SJun-ichiro itojun Hagino 		default:
181686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
182686cdd19SJun-ichiro itojun Hagino 			break;
183686cdd19SJun-ichiro itojun Hagino 		}
184686cdd19SJun-ichiro itojun Hagino 	}
185686cdd19SJun-ichiro itojun Hagino 
186686cdd19SJun-ichiro itojun Hagino 
187686cdd19SJun-ichiro itojun Hagino 	if (addr->s6_addr8[0] == 0xff) {
188686cdd19SJun-ichiro itojun Hagino 		scope = addr->s6_addr8[1] & 0x0f;
189686cdd19SJun-ichiro itojun Hagino 
190686cdd19SJun-ichiro itojun Hagino 		/*
191686cdd19SJun-ichiro itojun Hagino 		 * due to other scope such as reserved,
192686cdd19SJun-ichiro itojun Hagino 		 * return scope doesn't work.
193686cdd19SJun-ichiro itojun Hagino 		 */
194686cdd19SJun-ichiro itojun Hagino 		switch (scope) {
195686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_NODELOCAL:
196686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_NODELOCAL;
197686cdd19SJun-ichiro itojun Hagino 			break;
198686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_LINKLOCAL:
199686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
200686cdd19SJun-ichiro itojun Hagino 			break;
201686cdd19SJun-ichiro itojun Hagino 		case IPV6_ADDR_SCOPE_SITELOCAL:
202686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_SITELOCAL;
203686cdd19SJun-ichiro itojun Hagino 			break;
204686cdd19SJun-ichiro itojun Hagino 		default:
205686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_GLOBAL;
206686cdd19SJun-ichiro itojun Hagino 			break;
207686cdd19SJun-ichiro itojun Hagino 		}
208686cdd19SJun-ichiro itojun Hagino 	}
209686cdd19SJun-ichiro itojun Hagino 
210ddebd678SHajimu UMEMOTO 	if (bcmp(&in6addr_loopback, addr, sizeof(*addr) - 1) == 0) {
211686cdd19SJun-ichiro itojun Hagino 		if (addr->s6_addr8[15] == 1) /* loopback */
212686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_NODELOCAL;
213686cdd19SJun-ichiro itojun Hagino 		if (addr->s6_addr8[15] == 0) /* unspecified */
214686cdd19SJun-ichiro itojun Hagino 			return IPV6_ADDR_SCOPE_LINKLOCAL;
215686cdd19SJun-ichiro itojun Hagino 	}
216686cdd19SJun-ichiro itojun Hagino 
217686cdd19SJun-ichiro itojun Hagino 	return IPV6_ADDR_SCOPE_GLOBAL;
218686cdd19SJun-ichiro itojun Hagino }
219686cdd19SJun-ichiro itojun Hagino 
220686cdd19SJun-ichiro itojun Hagino int
221686cdd19SJun-ichiro itojun Hagino in6_addr2scopeid(ifp, addr)
222686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;	/* must not be NULL */
223686cdd19SJun-ichiro itojun Hagino 	struct in6_addr *addr;	/* must not be NULL */
224686cdd19SJun-ichiro itojun Hagino {
22531b1bfe1SHajimu UMEMOTO 	int scope;
22631b1bfe1SHajimu UMEMOTO 	struct scope6_id *sid = SID(ifp);
227686cdd19SJun-ichiro itojun Hagino 
22831b1bfe1SHajimu UMEMOTO #ifdef DIAGNOSTIC
22931b1bfe1SHajimu UMEMOTO 	if (sid == NULL) { /* should not happen */
23031b1bfe1SHajimu UMEMOTO 		panic("in6_addr2zoneid: scope array is NULL");
23131b1bfe1SHajimu UMEMOTO 		/* NOTREACHED */
23231b1bfe1SHajimu UMEMOTO 	}
23331b1bfe1SHajimu UMEMOTO #endif
234686cdd19SJun-ichiro itojun Hagino 
23531b1bfe1SHajimu UMEMOTO 	/*
23631b1bfe1SHajimu UMEMOTO 	 * special case: the loopback address can only belong to a loopback
23731b1bfe1SHajimu UMEMOTO 	 * interface.
23831b1bfe1SHajimu UMEMOTO 	 */
23931b1bfe1SHajimu UMEMOTO 	if (IN6_IS_ADDR_LOOPBACK(addr)) {
24031b1bfe1SHajimu UMEMOTO 		if (!(ifp->if_flags & IFF_LOOPBACK))
24131b1bfe1SHajimu UMEMOTO 			return (-1);
24231b1bfe1SHajimu UMEMOTO 		else
24331b1bfe1SHajimu UMEMOTO 			return (0); /* there's no ambiguity */
24431b1bfe1SHajimu UMEMOTO 	}
24531b1bfe1SHajimu UMEMOTO 
24631b1bfe1SHajimu UMEMOTO 	scope = in6_addrscope(addr);
24731b1bfe1SHajimu UMEMOTO 
248686cdd19SJun-ichiro itojun Hagino 	switch(scope) {
249686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_NODELOCAL:
250686cdd19SJun-ichiro itojun Hagino 		return (-1);	/* XXX: is this an appropriate value? */
251686cdd19SJun-ichiro itojun Hagino 
252686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_LINKLOCAL:
25331b1bfe1SHajimu UMEMOTO 		return (sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]);
254686cdd19SJun-ichiro itojun Hagino 
255686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_SITELOCAL:
25631b1bfe1SHajimu UMEMOTO 		return (sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL]);
257686cdd19SJun-ichiro itojun Hagino 
258686cdd19SJun-ichiro itojun Hagino 	case IPV6_ADDR_SCOPE_ORGLOCAL:
25931b1bfe1SHajimu UMEMOTO 		return (sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL]);
260686cdd19SJun-ichiro itojun Hagino 
261686cdd19SJun-ichiro itojun Hagino 	default:
262686cdd19SJun-ichiro itojun Hagino 		return (0);	/* XXX: treat as global. */
263686cdd19SJun-ichiro itojun Hagino 	}
264686cdd19SJun-ichiro itojun Hagino }
265686cdd19SJun-ichiro itojun Hagino 
266686cdd19SJun-ichiro itojun Hagino void
267686cdd19SJun-ichiro itojun Hagino scope6_setdefault(ifp)
268686cdd19SJun-ichiro itojun Hagino 	struct ifnet *ifp;	/* note that this might be NULL */
269686cdd19SJun-ichiro itojun Hagino {
270686cdd19SJun-ichiro itojun Hagino 	/*
27131b1bfe1SHajimu UMEMOTO 	 * Currently, this function just set the default "interfaces"
27231b1bfe1SHajimu UMEMOTO 	 * and "links" according to the given interface.
273686cdd19SJun-ichiro itojun Hagino 	 * We might eventually have to separate the notion of "link" from
274686cdd19SJun-ichiro itojun Hagino 	 * "interface" and provide a user interface to set the default.
275686cdd19SJun-ichiro itojun Hagino 	 */
276686cdd19SJun-ichiro itojun Hagino 	if (ifp) {
27731b1bfe1SHajimu UMEMOTO 		sid_default.s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] =
27831b1bfe1SHajimu UMEMOTO 			ifp->if_index;
27931b1bfe1SHajimu UMEMOTO 		sid_default.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] =
280686cdd19SJun-ichiro itojun Hagino 			ifp->if_index;
28107eb2995SHajimu UMEMOTO 	} else {
28231b1bfe1SHajimu UMEMOTO 		sid_default.s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] = 0;
28331b1bfe1SHajimu UMEMOTO 		sid_default.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0;
284686cdd19SJun-ichiro itojun Hagino 	}
28507eb2995SHajimu UMEMOTO }
286686cdd19SJun-ichiro itojun Hagino 
287686cdd19SJun-ichiro itojun Hagino int
288686cdd19SJun-ichiro itojun Hagino scope6_get_default(idlist)
28931b1bfe1SHajimu UMEMOTO 	struct scope6_id *idlist;
290686cdd19SJun-ichiro itojun Hagino {
29131b1bfe1SHajimu UMEMOTO 	*idlist = sid_default;
292686cdd19SJun-ichiro itojun Hagino 
293686cdd19SJun-ichiro itojun Hagino 	return (0);
294686cdd19SJun-ichiro itojun Hagino }
295686cdd19SJun-ichiro itojun Hagino 
296686cdd19SJun-ichiro itojun Hagino u_int32_t
297686cdd19SJun-ichiro itojun Hagino scope6_addr2default(addr)
298686cdd19SJun-ichiro itojun Hagino 	struct in6_addr *addr;
299686cdd19SJun-ichiro itojun Hagino {
30031b1bfe1SHajimu UMEMOTO 	/*
30131b1bfe1SHajimu UMEMOTO 	 * special case: The loopback address should be considered as
30231b1bfe1SHajimu UMEMOTO 	 * link-local, but there's no ambiguity in the syntax.
30331b1bfe1SHajimu UMEMOTO 	 */
30431b1bfe1SHajimu UMEMOTO 	if (IN6_IS_ADDR_LOOPBACK(addr))
30531b1bfe1SHajimu UMEMOTO 		return (0);
30631b1bfe1SHajimu UMEMOTO 
30731b1bfe1SHajimu UMEMOTO 	return (sid_default.s6id_list[in6_addrscope(addr)]);
308686cdd19SJun-ichiro itojun Hagino }
309