FreeBSD/sys/net/if_llatbl.c
/*
 * (al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
 *
 * If found the llentry * is returned referenced and unlocked.
 */
(al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
If found the llentry * is returned referenced and unlocked.
( al ) locate an llentry for address dst ( equivalent to rtalloc for new - arp ) . If found the llentry * is returned referenced and unlocked .
struct llentry *
llentry_alloc(struct ifnet *ifp, struct lltable *lt,
    struct sockaddr_storage *dst)
{
	struct llentry *la, *la_tmp;
	IF_AFDATA_RLOCK(ifp);
	la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
	IF_AFDATA_RUNLOCK(ifp);
	if (la != NULL) {
		LLE_ADDREF(la);
		LLE_WUNLOCK(la);
		return (la);
	}
	if ((ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
		la = lltable_alloc_entry(lt, 0, (struct sockaddr *)dst);
		if (la == NULL)
			return (NULL);
		IF_AFDATA_WLOCK(ifp);
		LLE_WLOCK(la);
		la_tmp = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
		if (la_tmp == NULL)
			lltable_link_entry(lt, la);
		IF_AFDATA_WUNLOCK(ifp);
		if (la_tmp != NULL) {
			lltable_free_entry(lt, la);
			la = la_tmp;
		}
		LLE_ADDREF(la);
		LLE_WUNLOCK(la);
	}
	return (la);
}
struct llentry * llentry_alloc ( struct ifnet * ifp , struct lltable * lt , struct sockaddr_storage * dst ) { struct llentry * la , * la_tmp ; IF_AFDATA_RLOCK ( ifp ) ; la = lla_lookup ( lt , LLE_EXCLUSIVE , ( struct sockaddr * ) dst ) ; IF_AFDATA_RUNLOCK ( ifp ) ; if ( la != NULL ) { LLE_ADDREF ( la ) ; LLE_WUNLOCK ( la ) ; return ( la ) ; } if ( ( ifp -> if_flags & ( IFF_NOARP | IFF_STATICARP ) ) == 0 ) { la = lltable_alloc_entry ( lt , 0 , ( struct sockaddr * ) dst ) ; if ( la == NULL ) return ( NULL ) ; IF_AFDATA_WLOCK ( ifp ) ; LLE_WLOCK ( la ) ; la_tmp = lla_lookup ( lt , LLE_EXCLUSIVE , ( struct sockaddr * ) dst ) ; if ( la_tmp == NULL ) lltable_link_entry ( lt , la ) ; IF_AFDATA_WUNLOCK ( ifp ) ; if ( la_tmp != NULL ) { lltable_free_entry ( lt , la ) ; la = la_tmp ; } LLE_ADDREF ( la ) ; LLE_WUNLOCK ( la ) ; } return ( la ) ; }
(al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
( al ) locate an llentry for address dst ( equivalent to rtalloc for new - arp ) .
/* Prefer any existing LLE over newly-created one */