diff options
Diffstat (limited to 'freebsd/sys/net/if_llatbl.c')
-rw-r--r-- | freebsd/sys/net/if_llatbl.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/freebsd/sys/net/if_llatbl.c b/freebsd/sys/net/if_llatbl.c index 3ffcc21a..80888559 100644 --- a/freebsd/sys/net/if_llatbl.c +++ b/freebsd/sys/net/if_llatbl.c @@ -102,18 +102,35 @@ done: * This function is called by the timer functions * such as arptimer() and nd6_llinfo_timer(), and * the caller does the locking. + * + * Returns the number of held packets, if any, that were dropped. */ -void +size_t llentry_free(struct llentry *lle) { - + size_t pkts_dropped; + struct mbuf *next; + + pkts_dropped = 0; LLE_WLOCK_ASSERT(lle); LIST_REMOVE(lle, lle_next); - if (lle->la_hold != NULL) + while ((lle->la_numheld > 0) && (lle->la_hold != NULL)) { + next = lle->la_hold->m_nextpkt; m_freem(lle->la_hold); + lle->la_hold = next; + lle->la_numheld--; + pkts_dropped++; + } + + KASSERT(lle->la_numheld == 0, + ("%s: la_numheld %d > 0, pkts_droped %zd", __func__, + lle->la_numheld, pkts_dropped)); + lle->la_flags &= ~LLE_VALID; LLE_FREE_LOCKED(lle); + + return (pkts_dropped); } /* @@ -214,7 +231,8 @@ lltable_drain(int af) #endif void -lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask) +lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask, + u_int flags) { struct lltable *llt; @@ -223,7 +241,7 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask) if (llt->llt_af != af) continue; - llt->llt_prefix_free(llt, prefix, mask); + llt->llt_prefix_free(llt, prefix, mask, flags); } LLTABLE_RUNLOCK(); } @@ -414,6 +432,7 @@ llatbl_lle_show(struct llentry_sa *la) db_printf(" lle_tbl=%p\n", lle->lle_tbl); db_printf(" lle_head=%p\n", lle->lle_head); db_printf(" la_hold=%p\n", lle->la_hold); + db_printf(" la_numheld=%d\n", lle->la_numheld); db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire); db_printf(" la_flags=0x%04x\n", lle->la_flags); db_printf(" la_asked=%u\n", lle->la_asked); |