| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: nd6.c,v 1.143 2012/06/23 03:14:04 christos Exp $ */ | | 1 | /* $NetBSD: nd6.c,v 1.144 2013/01/24 14:23:09 joerg Exp $ */ |
2 | /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ | | 2 | /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | | 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
30 | * SUCH DAMAGE. | | 30 | * SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.143 2012/06/23 03:14:04 christos Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.144 2013/01/24 14:23:09 joerg Exp $"); |
35 | | | 35 | |
36 | #include "opt_ipsec.h" | | 36 | #include "opt_ipsec.h" |
37 | | | 37 | |
38 | #include <sys/param.h> | | 38 | #include <sys/param.h> |
39 | #include <sys/systm.h> | | 39 | #include <sys/systm.h> |
40 | #include <sys/callout.h> | | 40 | #include <sys/callout.h> |
41 | #include <sys/malloc.h> | | 41 | #include <sys/malloc.h> |
42 | #include <sys/mbuf.h> | | 42 | #include <sys/mbuf.h> |
43 | #include <sys/socket.h> | | 43 | #include <sys/socket.h> |
44 | #include <sys/socketvar.h> | | 44 | #include <sys/socketvar.h> |
45 | #include <sys/sockio.h> | | 45 | #include <sys/sockio.h> |
46 | #include <sys/time.h> | | 46 | #include <sys/time.h> |
47 | #include <sys/kernel.h> | | 47 | #include <sys/kernel.h> |
| @@ -1134,27 +1134,27 @@ nd6_nud_hint(struct rtentry *rt, struct | | | @@ -1134,27 +1134,27 @@ nd6_nud_hint(struct rtentry *rt, struct |
1134 | (long)ND_IFINFO(rt->rt_ifp)->reachable * hz); | | 1134 | (long)ND_IFINFO(rt->rt_ifp)->reachable * hz); |
1135 | } | | 1135 | } |
1136 | } | | 1136 | } |
1137 | | | 1137 | |
1138 | void | | 1138 | void |
1139 | nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) | | 1139 | nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) |
1140 | { | | 1140 | { |
1141 | struct sockaddr *gate = rt->rt_gateway; | | 1141 | struct sockaddr *gate = rt->rt_gateway; |
1142 | struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo; | | 1142 | struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo; |
1143 | struct ifnet *ifp = rt->rt_ifp; | | 1143 | struct ifnet *ifp = rt->rt_ifp; |
1144 | uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen; | | 1144 | uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen; |
1145 | struct ifaddr *ifa; | | 1145 | struct ifaddr *ifa; |
1146 | | | 1146 | |
1147 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1147 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1148 | | | 1148 | |
1149 | if (req == RTM_LLINFO_UPD) { | | 1149 | if (req == RTM_LLINFO_UPD) { |
1150 | int rc; | | 1150 | int rc; |
1151 | struct in6_addr *in6; | | 1151 | struct in6_addr *in6; |
1152 | struct in6_addr in6_all; | | 1152 | struct in6_addr in6_all; |
1153 | int anycast; | | 1153 | int anycast; |
1154 | | | 1154 | |
1155 | if ((ifa = info->rti_ifa) == NULL) | | 1155 | if ((ifa = info->rti_ifa) == NULL) |
1156 | return; | | 1156 | return; |
1157 | | | 1157 | |
1158 | in6 = &ifatoia6(ifa)->ia_addr.sin6_addr; | | 1158 | in6 = &ifatoia6(ifa)->ia_addr.sin6_addr; |
1159 | anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST; | | 1159 | anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST; |
1160 | | | 1160 | |
| @@ -1169,62 +1169,62 @@ nd6_rtrequest(int req, struct rtentry *r | | | @@ -1169,62 +1169,62 @@ nd6_rtrequest(int req, struct rtentry *r |
1169 | nd6_na_output(ifa->ifa_ifp, &in6_all, in6, | | 1169 | nd6_na_output(ifa->ifa_ifp, &in6_all, in6, |
1170 | (anycast ? 0 : ND_NA_FLAG_OVERRIDE) | | 1170 | (anycast ? 0 : ND_NA_FLAG_OVERRIDE) |
1171 | #if 0 | | 1171 | #if 0 |
1172 | | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) | | 1172 | | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) |
1173 | #endif | | 1173 | #endif |
1174 | , 1, NULL); | | 1174 | , 1, NULL); |
1175 | return; | | 1175 | return; |
1176 | } | | 1176 | } |
1177 | | | 1177 | |
1178 | if ((rt->rt_flags & RTF_GATEWAY) != 0) | | 1178 | if ((rt->rt_flags & RTF_GATEWAY) != 0) |
1179 | return; | | 1179 | return; |
1180 | | | 1180 | |
1181 | if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) { | | 1181 | if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) { |
1182 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1182 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1183 | /* | | 1183 | /* |
1184 | * This is probably an interface direct route for a link | | 1184 | * This is probably an interface direct route for a link |
1185 | * which does not need neighbor caches (e.g. fe80::%lo0/64). | | 1185 | * which does not need neighbor caches (e.g. fe80::%lo0/64). |
1186 | * We do not need special treatment below for such a route. | | 1186 | * We do not need special treatment below for such a route. |
1187 | * Moreover, the RTF_LLINFO flag which would be set below | | 1187 | * Moreover, the RTF_LLINFO flag which would be set below |
1188 | * would annoy the ndp(8) command. | | 1188 | * would annoy the ndp(8) command. |
1189 | */ | | 1189 | */ |
1190 | return; | | 1190 | return; |
1191 | } | | 1191 | } |
1192 | | | 1192 | |
1193 | if (req == RTM_RESOLVE && | | 1193 | if (req == RTM_RESOLVE && |
1194 | (nd6_need_cache(ifp) == 0 || /* stf case */ | | 1194 | (nd6_need_cache(ifp) == 0 || /* stf case */ |
1195 | !nd6_is_addr_neighbor(satocsin6(rt_getkey(rt)), ifp))) { | | 1195 | !nd6_is_addr_neighbor(satocsin6(rt_getkey(rt)), ifp))) { |
1196 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1196 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1197 | /* | | 1197 | /* |
1198 | * FreeBSD and BSD/OS often make a cloned host route based | | 1198 | * FreeBSD and BSD/OS often make a cloned host route based |
1199 | * on a less-specific route (e.g. the default route). | | 1199 | * on a less-specific route (e.g. the default route). |
1200 | * If the less specific route does not have a "gateway" | | 1200 | * If the less specific route does not have a "gateway" |
1201 | * (this is the case when the route just goes to a p2p or an | | 1201 | * (this is the case when the route just goes to a p2p or an |
1202 | * stf interface), we'll mistakenly make a neighbor cache for | | 1202 | * stf interface), we'll mistakenly make a neighbor cache for |
1203 | * the host route, and will see strange neighbor solicitation | | 1203 | * the host route, and will see strange neighbor solicitation |
1204 | * for the corresponding destination. In order to avoid the | | 1204 | * for the corresponding destination. In order to avoid the |
1205 | * confusion, we check if the destination of the route is | | 1205 | * confusion, we check if the destination of the route is |
1206 | * a neighbor in terms of neighbor discovery, and stop the | | 1206 | * a neighbor in terms of neighbor discovery, and stop the |
1207 | * process if not. Additionally, we remove the LLINFO flag | | 1207 | * process if not. Additionally, we remove the LLINFO flag |
1208 | * so that ndp(8) will not try to get the neighbor information | | 1208 | * so that ndp(8) will not try to get the neighbor information |
1209 | * of the destination. | | 1209 | * of the destination. |
1210 | */ | | 1210 | */ |
1211 | rt->rt_flags &= ~RTF_LLINFO; | | 1211 | rt->rt_flags &= ~RTF_LLINFO; |
1212 | return; | | 1212 | return; |
1213 | } | | 1213 | } |
1214 | | | 1214 | |
1215 | switch (req) { | | 1215 | switch (req) { |
1216 | case RTM_ADD: | | 1216 | case RTM_ADD: |
1217 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1217 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1218 | /* | | 1218 | /* |
1219 | * There is no backward compatibility :) | | 1219 | * There is no backward compatibility :) |
1220 | * | | 1220 | * |
1221 | * if ((rt->rt_flags & RTF_HOST) == 0 && | | 1221 | * if ((rt->rt_flags & RTF_HOST) == 0 && |
1222 | * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) | | 1222 | * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) |
1223 | * rt->rt_flags |= RTF_CLONING; | | 1223 | * rt->rt_flags |= RTF_CLONING; |
1224 | */ | | 1224 | */ |
1225 | if ((rt->rt_flags & RTF_CLONING) || | | 1225 | if ((rt->rt_flags & RTF_CLONING) || |
1226 | ((rt->rt_flags & RTF_LLINFO) && ln == NULL)) { | | 1226 | ((rt->rt_flags & RTF_LLINFO) && ln == NULL)) { |
1227 | union { | | 1227 | union { |
1228 | struct sockaddr sa; | | 1228 | struct sockaddr sa; |
1229 | struct sockaddr_dl sdl; | | 1229 | struct sockaddr_dl sdl; |
1230 | struct sockaddr_storage ss; | | 1230 | struct sockaddr_storage ss; |
| @@ -1234,34 +1234,34 @@ nd6_rtrequest(int req, struct rtentry *r | | | @@ -1234,34 +1234,34 @@ nd6_rtrequest(int req, struct rtentry *r |
1234 | * interface (RTF_CLONING case) or the route should be | | 1234 | * interface (RTF_CLONING case) or the route should be |
1235 | * treated as on-link but is currently not | | 1235 | * treated as on-link but is currently not |
1236 | * (RTF_LLINFO && ln == NULL case). | | 1236 | * (RTF_LLINFO && ln == NULL case). |
1237 | */ | | 1237 | */ |
1238 | if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), | | 1238 | if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), |
1239 | ifp->if_index, ifp->if_type, | | 1239 | ifp->if_index, ifp->if_type, |
1240 | NULL, namelen, NULL, addrlen) == NULL) { | | 1240 | NULL, namelen, NULL, addrlen) == NULL) { |
1241 | printf("%s.%d: sockaddr_dl_init(, %zu, ) " | | 1241 | printf("%s.%d: sockaddr_dl_init(, %zu, ) " |
1242 | "failed on %s\n", __func__, __LINE__, | | 1242 | "failed on %s\n", __func__, __LINE__, |
1243 | sizeof(u.ss), if_name(ifp)); | | 1243 | sizeof(u.ss), if_name(ifp)); |
1244 | } | | 1244 | } |
1245 | rt_setgate(rt, &u.sa); | | 1245 | rt_setgate(rt, &u.sa); |
1246 | gate = rt->rt_gateway; | | 1246 | gate = rt->rt_gateway; |
1247 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1247 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1248 | if (ln != NULL) | | 1248 | if (ln != NULL) |
1249 | nd6_llinfo_settimer(ln, 0); | | 1249 | nd6_llinfo_settimer(ln, 0); |
1250 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1250 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1251 | if ((rt->rt_flags & RTF_CLONING) != 0) | | 1251 | if ((rt->rt_flags & RTF_CLONING) != 0) |
1252 | break; | | 1252 | break; |
1253 | } | | 1253 | } |
1254 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1254 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1255 | /* | | 1255 | /* |
1256 | * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here. | | 1256 | * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here. |
1257 | * We don't do that here since llinfo is not ready yet. | | 1257 | * We don't do that here since llinfo is not ready yet. |
1258 | * | | 1258 | * |
1259 | * There are also couple of other things to be discussed: | | 1259 | * There are also couple of other things to be discussed: |
1260 | * - unsolicited NA code needs improvement beforehand | | 1260 | * - unsolicited NA code needs improvement beforehand |
1261 | * - RFC2461 says we MAY send multicast unsolicited NA | | 1261 | * - RFC2461 says we MAY send multicast unsolicited NA |
1262 | * (7.2.6 paragraph 4), however, it also says that we | | 1262 | * (7.2.6 paragraph 4), however, it also says that we |
1263 | * SHOULD provide a mechanism to prevent multicast NA storm. | | 1263 | * SHOULD provide a mechanism to prevent multicast NA storm. |
1264 | * we don't have anything like it right now. | | 1264 | * we don't have anything like it right now. |
1265 | * note that the mechanism needs a mutual agreement | | 1265 | * note that the mechanism needs a mutual agreement |
1266 | * between proxies, which means that we need to implement | | 1266 | * between proxies, which means that we need to implement |
1267 | * a new protocol, or a new kludge. | | 1267 | * a new protocol, or a new kludge. |
| @@ -1272,81 +1272,81 @@ nd6_rtrequest(int req, struct rtentry *r | | | @@ -1272,81 +1272,81 @@ nd6_rtrequest(int req, struct rtentry *r |
1272 | */ | | 1272 | */ |
1273 | #if 0 | | 1273 | #if 0 |
1274 | /* XXX it does not work */ | | 1274 | /* XXX it does not work */ |
1275 | if (rt->rt_flags & RTF_ANNOUNCE) | | 1275 | if (rt->rt_flags & RTF_ANNOUNCE) |
1276 | nd6_na_output(ifp, | | 1276 | nd6_na_output(ifp, |
1277 | &satocsin6(rt_getkey(rt))->sin6_addr, | | 1277 | &satocsin6(rt_getkey(rt))->sin6_addr, |
1278 | &satocsin6(rt_getkey(rt))->sin6_addr, | | 1278 | &satocsin6(rt_getkey(rt))->sin6_addr, |
1279 | ip6_forwarding ? ND_NA_FLAG_ROUTER : 0, | | 1279 | ip6_forwarding ? ND_NA_FLAG_ROUTER : 0, |
1280 | 1, NULL); | | 1280 | 1, NULL); |
1281 | #endif | | 1281 | #endif |
1282 | /* FALLTHROUGH */ | | 1282 | /* FALLTHROUGH */ |
1283 | case RTM_RESOLVE: | | 1283 | case RTM_RESOLVE: |
1284 | if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) { | | 1284 | if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) { |
1285 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1285 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1286 | /* | | 1286 | /* |
1287 | * Address resolution isn't necessary for a point to | | 1287 | * Address resolution isn't necessary for a point to |
1288 | * point link, so we can skip this test for a p2p link. | | 1288 | * point link, so we can skip this test for a p2p link. |
1289 | */ | | 1289 | */ |
1290 | if (gate->sa_family != AF_LINK || | | 1290 | if (gate->sa_family != AF_LINK || |
1291 | gate->sa_len < | | 1291 | gate->sa_len < |
1292 | sockaddr_dl_measure(namelen, addrlen)) { | | 1292 | sockaddr_dl_measure(namelen, addrlen)) { |
1293 | log(LOG_DEBUG, | | 1293 | log(LOG_DEBUG, |
1294 | "nd6_rtrequest: bad gateway value: %s\n", | | 1294 | "nd6_rtrequest: bad gateway value: %s\n", |
1295 | if_name(ifp)); | | 1295 | if_name(ifp)); |
1296 | break; | | 1296 | break; |
1297 | } | | 1297 | } |
1298 | satosdl(gate)->sdl_type = ifp->if_type; | | 1298 | satosdl(gate)->sdl_type = ifp->if_type; |
1299 | satosdl(gate)->sdl_index = ifp->if_index; | | 1299 | satosdl(gate)->sdl_index = ifp->if_index; |
1300 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1300 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1301 | } | | 1301 | } |
1302 | if (ln != NULL) | | 1302 | if (ln != NULL) |
1303 | break; /* This happens on a route change */ | | 1303 | break; /* This happens on a route change */ |
1304 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1304 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1305 | /* | | 1305 | /* |
1306 | * Case 2: This route may come from cloning, or a manual route | | 1306 | * Case 2: This route may come from cloning, or a manual route |
1307 | * add with a LL address. | | 1307 | * add with a LL address. |
1308 | */ | | 1308 | */ |
1309 | R_Malloc(ln, struct llinfo_nd6 *, sizeof(*ln)); | | 1309 | R_Malloc(ln, struct llinfo_nd6 *, sizeof(*ln)); |
1310 | rt->rt_llinfo = ln; | | 1310 | rt->rt_llinfo = ln; |
1311 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1311 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1312 | if (ln == NULL) { | | 1312 | if (ln == NULL) { |
1313 | log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n"); | | 1313 | log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n"); |
1314 | break; | | 1314 | break; |
1315 | } | | 1315 | } |
1316 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1316 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1317 | nd6_inuse++; | | 1317 | nd6_inuse++; |
1318 | nd6_allocated++; | | 1318 | nd6_allocated++; |
1319 | memset(ln, 0, sizeof(*ln)); | | 1319 | memset(ln, 0, sizeof(*ln)); |
1320 | ln->ln_rt = rt; | | 1320 | ln->ln_rt = rt; |
1321 | callout_init(&ln->ln_timer_ch, CALLOUT_MPSAFE); | | 1321 | callout_init(&ln->ln_timer_ch, CALLOUT_MPSAFE); |
1322 | /* this is required for "ndp" command. - shin */ | | 1322 | /* this is required for "ndp" command. - shin */ |
1323 | if (req == RTM_ADD) { | | 1323 | if (req == RTM_ADD) { |
1324 | /* | | 1324 | /* |
1325 | * gate should have some valid AF_LINK entry, | | 1325 | * gate should have some valid AF_LINK entry, |
1326 | * and ln->ln_expire should have some lifetime | | 1326 | * and ln->ln_expire should have some lifetime |
1327 | * which is specified by ndp command. | | 1327 | * which is specified by ndp command. |
1328 | */ | | 1328 | */ |
1329 | ln->ln_state = ND6_LLINFO_REACHABLE; | | 1329 | ln->ln_state = ND6_LLINFO_REACHABLE; |
1330 | ln->ln_byhint = 0; | | 1330 | ln->ln_byhint = 0; |
1331 | } else { | | 1331 | } else { |
1332 | /* | | 1332 | /* |
1333 | * When req == RTM_RESOLVE, rt is created and | | 1333 | * When req == RTM_RESOLVE, rt is created and |
1334 | * initialized in rtrequest(), so rt_expire is 0. | | 1334 | * initialized in rtrequest(), so rt_expire is 0. |
1335 | */ | | 1335 | */ |
1336 | ln->ln_state = ND6_LLINFO_NOSTATE; | | 1336 | ln->ln_state = ND6_LLINFO_NOSTATE; |
1337 | nd6_llinfo_settimer(ln, 0); | | 1337 | nd6_llinfo_settimer(ln, 0); |
1338 | } | | 1338 | } |
1339 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1339 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1340 | rt->rt_flags |= RTF_LLINFO; | | 1340 | rt->rt_flags |= RTF_LLINFO; |
1341 | ln->ln_next = llinfo_nd6.ln_next; | | 1341 | ln->ln_next = llinfo_nd6.ln_next; |
1342 | llinfo_nd6.ln_next = ln; | | 1342 | llinfo_nd6.ln_next = ln; |
1343 | ln->ln_prev = &llinfo_nd6; | | 1343 | ln->ln_prev = &llinfo_nd6; |
1344 | ln->ln_next->ln_prev = ln; | | 1344 | ln->ln_next->ln_prev = ln; |
1345 | | | 1345 | |
1346 | /* | | 1346 | /* |
1347 | * If we have too many cache entries, initiate immediate | | 1347 | * If we have too many cache entries, initiate immediate |
1348 | * purging for some "less recently used" entries. Note that | | 1348 | * purging for some "less recently used" entries. Note that |
1349 | * we cannot directly call nd6_free() here because it would | | 1349 | * we cannot directly call nd6_free() here because it would |
1350 | * cause re-entering rtable related routines triggering an LOR | | 1350 | * cause re-entering rtable related routines triggering an LOR |
1351 | * problem for FreeBSD. | | 1351 | * problem for FreeBSD. |
1352 | */ | | 1352 | */ |
| @@ -1362,34 +1362,34 @@ nd6_rtrequest(int req, struct rtentry *r | | | @@ -1362,34 +1362,34 @@ nd6_rtrequest(int req, struct rtentry *r |
1362 | LN_INSERTHEAD(ln_end); | | 1362 | LN_INSERTHEAD(ln_end); |
1363 | | | 1363 | |
1364 | if (ND6_LLINFO_PERMANENT(ln_end)) | | 1364 | if (ND6_LLINFO_PERMANENT(ln_end)) |
1365 | continue; | | 1365 | continue; |
1366 | | | 1366 | |
1367 | if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE) | | 1367 | if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE) |
1368 | ln_end->ln_state = ND6_LLINFO_STALE; | | 1368 | ln_end->ln_state = ND6_LLINFO_STALE; |
1369 | else | | 1369 | else |
1370 | ln_end->ln_state = ND6_LLINFO_PURGE; | | 1370 | ln_end->ln_state = ND6_LLINFO_PURGE; |
1371 | nd6_llinfo_settimer(ln_end, 0); | | 1371 | nd6_llinfo_settimer(ln_end, 0); |
1372 | } | | 1372 | } |
1373 | } | | 1373 | } |
1374 | | | 1374 | |
1375 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1375 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1376 | /* | | 1376 | /* |
1377 | * check if rt_getkey(rt) is an address assigned | | 1377 | * check if rt_getkey(rt) is an address assigned |
1378 | * to the interface. | | 1378 | * to the interface. |
1379 | */ | | 1379 | */ |
1380 | ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, | | 1380 | ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, |
1381 | &satocsin6(rt_getkey(rt))->sin6_addr); | | 1381 | &satocsin6(rt_getkey(rt))->sin6_addr); |
1382 | RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key); | | 1382 | RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); |
1383 | if (ifa != NULL) { | | 1383 | if (ifa != NULL) { |
1384 | const void *mac; | | 1384 | const void *mac; |
1385 | nd6_llinfo_settimer(ln, -1); | | 1385 | nd6_llinfo_settimer(ln, -1); |
1386 | ln->ln_state = ND6_LLINFO_REACHABLE; | | 1386 | ln->ln_state = ND6_LLINFO_REACHABLE; |
1387 | ln->ln_byhint = 0; | | 1387 | ln->ln_byhint = 0; |
1388 | if ((mac = nd6_ifptomac(ifp)) != NULL) { | | 1388 | if ((mac = nd6_ifptomac(ifp)) != NULL) { |
1389 | /* XXX check for error */ | | 1389 | /* XXX check for error */ |
1390 | if (sockaddr_dl_setaddr(satosdl(gate), | | 1390 | if (sockaddr_dl_setaddr(satosdl(gate), |
1391 | gate->sa_len, mac, | | 1391 | gate->sa_len, mac, |
1392 | ifp->if_addrlen) == NULL) { | | 1392 | ifp->if_addrlen) == NULL) { |
1393 | printf("%s.%d: " | | 1393 | printf("%s.%d: " |
1394 | "sockaddr_dl_setaddr(, %d, ) " | | 1394 | "sockaddr_dl_setaddr(, %d, ) " |
1395 | "failed on %s\n", __func__, | | 1395 | "failed on %s\n", __func__, |