Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_llatbl.c
Show First 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle, | ||||
memcpy(lle->r_linkdata, linkhdr, linkhdrsize); | memcpy(lle->r_linkdata, linkhdr, linkhdrsize); | ||||
lle->r_hdrlen = linkhdrsize; | lle->r_hdrlen = linkhdrsize; | ||||
lle->ll_addr = &lle->r_linkdata[lladdr_off]; | lle->ll_addr = &lle->r_linkdata[lladdr_off]; | ||||
lle->la_flags |= LLE_VALID; | lle->la_flags |= LLE_VALID; | ||||
lle->r_flags |= RLLE_VALID; | lle->r_flags |= RLLE_VALID; | ||||
} | } | ||||
/* | bool | ||||
* Tries to update @lle link-level address. | lltable_acquire_wlock(struct ifnet *ifp, struct llentry *lle) | ||||
* Since update requires AFDATA WLOCK, function | |||||
* drops @lle lock, acquires AFDATA lock and then acquires | |||||
* @lle lock to maintain lock order. | |||||
* | |||||
* Returns 1 on success. | |||||
*/ | |||||
int | |||||
lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle, | |||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off) | |||||
{ | { | ||||
NET_EPOCH_ASSERT(); | |||||
/* Perform real LLE update */ | /* Perform real LLE update */ | ||||
/* use afdata WLOCK to update fields */ | /* use afdata WLOCK to update fields */ | ||||
LLE_WLOCK_ASSERT(lle); | |||||
LLE_ADDREF(lle); | |||||
LLE_WUNLOCK(lle); | LLE_WUNLOCK(lle); | ||||
IF_AFDATA_WLOCK(ifp); | IF_AFDATA_WLOCK(ifp); | ||||
LLE_WLOCK(lle); | LLE_WLOCK(lle); | ||||
/* | /* | ||||
* Since we droppped LLE lock, other thread might have deleted | * Since we droppped LLE lock, other thread might have deleted | ||||
* this lle. Check and return | * this lle. Check and return | ||||
*/ | */ | ||||
if ((lle->la_flags & LLE_DELETED) != 0) { | if ((lle->la_flags & LLE_DELETED) != 0) { | ||||
IF_AFDATA_WUNLOCK(ifp); | IF_AFDATA_WUNLOCK(ifp); | ||||
LLE_FREE_LOCKED(lle); | return (false); | ||||
return (0); | |||||
} | } | ||||
return (true); | |||||
} | |||||
/* | |||||
* Tries to update @lle link-level address. | |||||
* Since update requires AFDATA WLOCK, function | |||||
* drops @lle lock, acquires AFDATA lock and then acquires | |||||
* @lle lock to maintain lock order. | |||||
* | |||||
* Returns 1 on success. | |||||
*/ | |||||
int | |||||
lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle, | |||||
const char *linkhdr, size_t linkhdrsize, int lladdr_off) | |||||
{ | |||||
if (!lltable_acquire_wlock(ifp, lle)) | |||||
return (0); | |||||
/* Update data */ | /* Update data */ | ||||
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize, lladdr_off); | lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize, lladdr_off); | ||||
IF_AFDATA_WUNLOCK(ifp); | IF_AFDATA_WUNLOCK(ifp); | ||||
LLE_REMREF(lle); | |||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Helper function used to pre-compute full/partial link-layer | * Helper function used to pre-compute full/partial link-layer | ||||
* header data suitable for feeding into if_output(). | * header data suitable for feeding into if_output(). | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 603 Lines • Show Last 20 Lines |