| 2298 | } |
| 2299 | |
| 2300 | static struct llentry * |
| 2301 | in6_lltable_alloc(struct lltable *llt, u_int flags, |
| 2302 | const struct sockaddr *l3addr) |
| 2303 | { |
| 2304 | const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr; |
| 2305 | struct ifnet *ifp = llt->llt_ifp; |
| 2306 | struct llentry *lle; |
| 2307 | char linkhdr[LLE_MAX_LINKHDR]; |
| 2308 | size_t linkhdrsize; |
| 2309 | int lladdr_off; |
| 2310 | |
| 2311 | KASSERT(l3addr->sa_family == AF_INET6, |
| 2312 | ("sin_family %d", l3addr->sa_family)); |
| 2313 | |
| 2314 | /* |
| 2315 | * A route that covers the given address must have |
| 2316 | * been installed 1st because we are doing a resolution, |
| 2317 | * verify this. |
| 2318 | */ |
| 2319 | if (!(flags & LLE_IFADDR) && |
| 2320 | in6_lltable_rtcheck(ifp, flags, l3addr) != 0) |
| 2321 | return (NULL); |
| 2322 | |
| 2323 | lle = in6_lltable_new(&sin6->sin6_addr, flags); |
| 2324 | if (lle == NULL) { |
| 2325 | log(LOG_INFO, "lla_lookup: new lle malloc failed\n"); |
| 2326 | return (NULL); |
| 2327 | } |
| 2328 | lle->la_flags = flags; |
| 2329 | if ((flags & LLE_IFADDR) == LLE_IFADDR) { |
| 2330 | linkhdrsize = LLE_MAX_LINKHDR; |
| 2331 | if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp), |
| 2332 | linkhdr, &linkhdrsize, &lladdr_off) != 0) { |
| 2333 | NET_EPOCH_CALL(in6_lltable_destroy_lle_unlocked, &lle->lle_epoch_ctx); |
| 2334 | return (NULL); |
| 2335 | } |
| 2336 | lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize, |
| 2337 | lladdr_off); |
| 2338 | lle->la_flags |= LLE_STATIC; |
| 2339 | } |
| 2340 | |
| 2341 | if ((lle->la_flags & LLE_STATIC) != 0) |
| 2342 | lle->ln_state = ND6_LLINFO_REACHABLE; |
| 2343 | |
| 2344 | return (lle); |
| 2345 | } |
| 2346 | |
| 2347 | static struct llentry * |
| 2348 | in6_lltable_lookup(struct lltable *llt, u_int flags, |
nothing calls this directly
no test coverage detected