netinet6: embed struct mld_ifsoftc into struct in6_ifextra

In mld_domifdetach() don't search the global list.

Reviewed by:		tuexen
Differential Revision:	https://reviews.freebsd.org/D54727
This commit is contained in:
Gleb Smirnoff
2026-01-23 14:18:12 -08:00
parent aa3bbc06e5
commit cba9f88105
5 changed files with 31 additions and 65 deletions
+1 -2
View File
@@ -2613,11 +2613,10 @@ in6_ifarrival(void *arg __unused, struct ifnet *ifp)
COUNTER_ARRAY_ALLOC(ext->icmp6_ifstat,
sizeof(struct icmp6_ifstat) / sizeof(uint64_t), M_WAITOK);
nd6_ifattach(ifp);
mld_domifattach(ifp);
scope6_ifattach(ifp);
ext->lltable = in6_lltattach(ifp);
ext->mld_ifinfo = mld_domifattach(ifp);
}
EVENTHANDLER_DEFINE(ifnet_arrival_event, in6_ifarrival, NULL,
EVENTHANDLER_PRI_ANY);
+15 -1
View File
@@ -506,6 +506,21 @@ struct in6_ifextra {
u_int nd_dad_failures;
uint8_t nd_curhoplimit;
struct mld_ifsoftc {
/* Timers and invervals measured in seconds. */
LIST_ENTRY(mld_ifsoftc) mli_link;
struct ifnet *mli_ifp; /* interface this instance belongs to */
uint32_t mli_version; /* MLDv1 Host Compatibility Mode */
uint32_t mli_v1_timer; /* MLDv1 Querier Present timer */
uint32_t mli_v2_timer; /* MLDv2 General Query timer */
uint32_t mli_flags; /* MLD per-interface flags */
uint32_t mli_rv; /* MLDv2 Robustness Variable */
uint32_t mli_qi; /* MLDv2 Query Interval */
uint32_t mli_qri; /* MLDv2 Query Response Interval */
uint32_t mli_uri; /* MLDv2 Unsolicited Report Interval */
struct mbufq mli_gq; /* queue of general query responses */
} mld_ifsoftc;
struct scope6_id {
/*
* 16 is correspondent to 4bit multicast scope field. i.e. from
@@ -516,7 +531,6 @@ struct in6_ifextra {
} scope6_id;
struct lltable *lltable;
struct mld_ifsoftc *mld_ifinfo;
};
#define LLTABLE6(ifp) ((ifp)->if_inet6->lltable)
-1
View File
@@ -390,7 +390,6 @@ ip6_destroy(void *unused __unused)
}
/* IF_ADDR_UNLOCK(ifp); */
in6_ifdetach_destroy(ifp);
mld_domifdetach(ifp);
}
IFNET_RUNLOCK();
+13 -41
View File
@@ -99,7 +99,6 @@
#define KTR_MLD KTR_INET6
#endif
static void mli_delete_locked(struct ifnet *);
static void mld_dispatch_packet(struct mbuf *);
static void mld_dispatch_queue(struct mbufq *, int);
static void mld_final_leave(struct in6_multi *, struct mld_ifsoftc *);
@@ -465,21 +464,21 @@ mld_is_addr_reported(const struct in6_addr *addr)
* Attach MLD when PF_INET6 is attached to an interface. Assumes that the
* current VNET is set by the caller.
*/
struct mld_ifsoftc *
void
mld_domifattach(struct ifnet *ifp)
{
struct mld_ifsoftc *mli;
struct mld_ifsoftc *mli = MLD_IFINFO(ifp);
CTR3(KTR_MLD, "%s: called for ifp %p(%s)", __func__, ifp, if_name(ifp));
mli = malloc(sizeof(struct mld_ifsoftc), M_MLD, M_WAITOK | M_ZERO);
mli->mli_ifp = ifp;
mli->mli_version = MLD_VERSION_2;
mli->mli_flags = 0;
mli->mli_rv = MLD_RV_INIT;
mli->mli_qi = MLD_QI_INIT;
mli->mli_qri = MLD_QRI_INIT;
mli->mli_uri = MLD_URI_INIT;
*mli = (struct mld_ifsoftc){
.mli_ifp = ifp,
.mli_version = MLD_VERSION_2,
.mli_rv = MLD_RV_INIT,
.mli_qi = MLD_QI_INIT,
.mli_qri = MLD_QRI_INIT,
.mli_uri = MLD_URI_INIT,
};
mbufq_init(&mli->mli_gq, MLD_MAX_RESPONSE_PACKETS);
if ((ifp->if_flags & IFF_MULTICAST) == 0)
mli->mli_flags |= MLIF_SILENT;
@@ -489,8 +488,6 @@ mld_domifattach(struct ifnet *ifp)
MLD_LOCK();
LIST_INSERT_HEAD(&V_mli_head, mli, mli_link);
MLD_UNLOCK();
return (mli);
}
/*
@@ -552,44 +549,19 @@ mld_ifdetach(struct ifnet *ifp, struct in6_multi_head *inmh)
/*
* Hook for domifdetach.
* Runs after link-layer cleanup; free MLD state.
*
* SMPng: Normally called with LLTABLE_LOCK held.
*/
void
mld_domifdetach(struct ifnet *ifp)
{
struct mld_ifsoftc *mli = MLD_IFINFO(ifp);
CTR3(KTR_MLD, "%s: called for ifp %p(%s)",
__func__, ifp, if_name(ifp));
MLD_LOCK();
mli_delete_locked(ifp);
LIST_REMOVE(mli, mli_link);
MLD_UNLOCK();
}
static void
mli_delete_locked(struct ifnet *ifp)
{
struct mld_ifsoftc *mli, *tmli;
CTR3(KTR_MLD, "%s: freeing mld_ifsoftc for ifp %p(%s)",
__func__, ifp, if_name(ifp));
MLD_LOCK_ASSERT();
LIST_FOREACH_SAFE(mli, &V_mli_head, mli_link, tmli) {
if (mli->mli_ifp == ifp) {
/*
* Free deferred General Query responses.
*/
mbufq_drain(&mli->mli_gq);
LIST_REMOVE(mli, mli_link);
free(mli, M_MLD);
return;
}
}
mbufq_drain(&mli->mli_gq);
}
/*
+2 -20
View File
@@ -120,23 +120,6 @@ struct mld_ifinfo {
};
#ifdef _KERNEL
/*
* Per-link MLD state.
*/
struct mld_ifsoftc {
LIST_ENTRY(mld_ifsoftc) mli_link;
struct ifnet *mli_ifp; /* interface this instance belongs to */
uint32_t mli_version; /* MLDv1 Host Compatibility Mode */
uint32_t mli_v1_timer; /* MLDv1 Querier Present timer (s) */
uint32_t mli_v2_timer; /* MLDv2 General Query (interface) timer (s)*/
uint32_t mli_flags; /* MLD per-interface flags */
uint32_t mli_rv; /* MLDv2 Robustness Variable */
uint32_t mli_qi; /* MLDv2 Query Interval (s) */
uint32_t mli_qri; /* MLDv2 Query Response Interval (s) */
uint32_t mli_uri; /* MLDv2 Unsolicited Report Interval (s) */
struct mbufq mli_gq; /* queue of general query responses */
};
#define MLD_RANDOM_DELAY(X) (arc4random() % (X) + 1)
#define MLD_MAX_STATE_CHANGES 24 /* Max pending changes per group */
@@ -155,12 +138,11 @@ struct mld_ifsoftc {
/*
* Per-link MLD context.
*/
#define MLD_IFINFO(ifp) ((ifp)->if_inet6->mld_ifinfo)
#define MLD_IFINFO(ifp) (&(ifp)->if_inet6->mld_ifsoftc)
struct in6_multi_head;
int mld_change_state(struct in6_multi *, const int);
struct mld_ifsoftc *
mld_domifattach(struct ifnet *);
void mld_domifattach(struct ifnet *);
void mld_domifdetach(struct ifnet *);
void mld_ifdetach(struct ifnet *, struct in6_multi_head *);
int mld_input(struct mbuf **, int, int);