MCPcopy Create free account
hub / github.com/F-Stack/f-stack / nd6_resolve_slow

Function nd6_resolve_slow

freebsd/netinet6/nd6.c:2285–2427  ·  view source on GitHub ↗

* Do L2 address resolution for @sa_dst address. Stores found * address in @desten buffer. Copy of lle ln_flags can be also * saved in @pflags if @pflags is non-NULL. * * Heavy version. * Function assume that destination LLE does not exist, * is invalid or stale, so LLE_EXCLUSIVE lock needs to be acquired. * * Set noinline to be dtrace-friendly */

Source from the content-addressed store, hash-verified

2283 * Set noinline to be dtrace-friendly
2284 */
2285static __noinline int
2286nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
2287 const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags,
2288 struct llentry **plle)
2289{
2290 struct llentry *lle = NULL, *lle_tmp;
2291 struct in6_addr *psrc, src;
2292 int send_ns, ll_len;
2293 char *lladdr;
2294
2295 NET_EPOCH_ASSERT();
2296
2297 /*
2298 * Address resolution or Neighbor Unreachability Detection
2299 * for the next hop.
2300 * At this point, the destination of the packet must be a unicast
2301 * or an anycast address(i.e. not a multicast).
2302 */
2303 if (lle == NULL) {
2304 lle = nd6_lookup(&dst->sin6_addr, LLE_EXCLUSIVE, ifp);
2305 if ((lle == NULL) && nd6_is_addr_neighbor(dst, ifp)) {
2306 /*
2307 * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
2308 * the condition below is not very efficient. But we believe
2309 * it is tolerable, because this should be a rare case.
2310 */
2311 lle = nd6_alloc(&dst->sin6_addr, 0, ifp);
2312 if (lle == NULL) {
2313 char ip6buf[INET6_ADDRSTRLEN];
2314 log(LOG_DEBUG,
2315 "nd6_output: can't allocate llinfo for %s "
2316 "(ln=%p)\n",
2317 ip6_sprintf(ip6buf, &dst->sin6_addr), lle);
2318 m_freem(m);
2319 return (ENOBUFS);
2320 }
2321
2322 IF_AFDATA_WLOCK(ifp);
2323 LLE_WLOCK(lle);
2324 /* Prefer any existing entry over newly-created one */
2325 lle_tmp = nd6_lookup(&dst->sin6_addr, LLE_EXCLUSIVE, ifp);
2326 if (lle_tmp == NULL)
2327 lltable_link_entry(LLTABLE6(ifp), lle);
2328 IF_AFDATA_WUNLOCK(ifp);
2329 if (lle_tmp != NULL) {
2330 lltable_free_entry(LLTABLE6(ifp), lle);
2331 lle = lle_tmp;
2332 lle_tmp = NULL;
2333 }
2334 }
2335 }
2336 if (lle == NULL) {
2337 m_freem(m);
2338 return (ENOBUFS);
2339 }
2340
2341 LLE_WLOCK_ASSERT(lle);
2342

Callers 2

nd6_resolveFunction · 0.85
nd6_resolve_addrFunction · 0.85

Calls 11

nd6_lookupFunction · 0.85
nd6_is_addr_neighborFunction · 0.85
nd6_allocFunction · 0.85
ip6_sprintfFunction · 0.85
lltable_link_entryFunction · 0.85
lltable_free_entryFunction · 0.85
nd6_llinfo_setstateFunction · 0.85
nd6_llinfo_get_holdsrcFunction · 0.85
nd6_ns_outputFunction · 0.85
logFunction · 0.50
m_freemFunction · 0.50

Tested by

no test coverage detected