summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/if_llatbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net/if_llatbl.c')
-rw-r--r--freebsd/sys/net/if_llatbl.c29
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);