netinet6: Tear down IPv6 source address selection policies with rest of IPv6.

This may plug minor leaks which no-one has reported. The default IPv6 source
address selection policy list in FreeBSD is usually limited to 9 entries,
and can be readily inspected with ip6addrctl(8). The policy table is
however instantiated for each VNET.

The leak of a pol instance in delete_addrsel_policyent() was already
plugged by @ae in commit-id ecc5c73, so that change has not been merged.

Do not tear down the sxlocks as glebius has requested, and move the
addrsel_policyent{} declarations further up to avoid redundant forward
declarations as glebius requested for stylistic reasons.

Reviewed by:	ae, pouria
Sponsored by:	Cisco Systems, Inc.
Differential Revision: https://reviews.freebsd.org/D55599
This commit is contained in:
Bruce M Simpson committed 2026-07-28 19:35:02 +01:00
1 parent f7c08d8dd8
commit f884e820d8
3 files changed
+30 -16

No files matched your search

+1
View File
@@ -690,6 +690,7 @@ void in6_sin_2_v4mapsin6(const struct sockaddr_in *sin,
struct sockaddr_in6 *sin6);
void in6_sin6_2_sin_in_sock(struct sockaddr *nam);
extern void addrsel_policy_init(void);
void addrsel_policy_destroy(void);
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
+28 -16
View File
@@ -886,6 +886,22 @@ in6_selecthlim(struct inpcb *inp, struct ifnet *ifp)
return (V_ip6_defhlim);
}
/*
* The followings are implementation of the policy table using a
* simple tail queue.
* XXX such details should be hidden.
* XXX implementation using binary tree should be more efficient.
*/
struct addrsel_policyent {
TAILQ_ENTRY(addrsel_policyent) ape_entry;
struct in6_addrpolicy ape_policy;
};
TAILQ_HEAD(addrsel_policyhead, addrsel_policyent);
VNET_DEFINE_STATIC(struct addrsel_policyhead, addrsel_policytab);
#define V_addrsel_policytab VNET(addrsel_policytab)
void
addrsel_policy_init(void)
{
@@ -903,6 +919,18 @@ addrsel_policy_init(void)
ADDRSEL_SXLOCK_INIT();
}
void
addrsel_policy_destroy(void)
{
struct addrsel_policyent *pol, *tpol;
TAILQ_FOREACH_SAFE(pol, &V_addrsel_policytab, ape_entry, tpol) {
TAILQ_REMOVE(&V_addrsel_policytab, pol, ape_entry);
free(pol, M_IFADDR);
}
/* TODO: Perform matching destruction of locks elsewhere. */
}
static struct in6_addrpolicy *
lookup_addrsel_policy(struct sockaddr_in6 *key)
{
@@ -976,22 +1004,6 @@ in6_src_ioctl(u_long cmd, caddr_t data)
return (0); /* XXX: compromise compilers */
}
/*
* The followings are implementation of the policy table using a
* simple tail queue.
* XXX such details should be hidden.
* XXX implementation using binary tree should be more efficient.
*/
struct addrsel_policyent {
TAILQ_ENTRY(addrsel_policyent) ape_entry;
struct in6_addrpolicy ape_policy;
};
TAILQ_HEAD(addrsel_policyhead, addrsel_policyent);
VNET_DEFINE_STATIC(struct addrsel_policyhead, addrsel_policytab);
#define V_addrsel_policytab VNET(addrsel_policytab)
static void
init_policy_queue(void)
{
+1
View File
@@ -398,6 +398,7 @@ ip6_destroy(void *unused __unused)
frag6_destroy();
nd6_destroy();
addrsel_policy_destroy();
in6_ifattach_destroy();
hashdestroy(V_in6_ifaddrhashtbl, M_IFADDR, V_in6_ifaddrhmask);