pf: remove DIOCGETSTATESNV

While nvlists are very useful in maximising flexibility for future
extensions their performance is simply unacceptably bad for the
getstates feature, where we can easily want to export a million states
or more.

The DIOCGETSTATESNV call has been MFCd, but has not hit a release on any
branch, so we can still remove it everywhere.

Reviewed by:	mjg
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D31099

(cherry picked from commit b69019c14c)
This commit is contained in:
Kristof Provost 2021-07-06 13:13:24 +02:00
parent 9757cfb9d2
commit 830afa2979
2 changed files with 0 additions and 87 deletions

View file

@ -1440,7 +1440,6 @@ struct pfioc_iface {
#define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook)
#define DIOCSETDEBUG _IOWR('D', 24, u_int32_t)
#define DIOCGETSTATES _IOWR('D', 25, struct pfioc_states)
#define DIOCGETSTATESNV _IOWR('D', 25, struct pfioc_nv)
#define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_rule)
/* XXX cut 26 - 28 */
#define DIOCSETTIMEOUT _IOWR('D', 29, struct pfioc_tm)

View file

@ -209,7 +209,6 @@ static int pf_killstates_row(struct pf_kstate_kill *,
static int pf_killstates_nv(struct pfioc_nv *);
static int pf_clearstates_nv(struct pfioc_nv *);
static int pf_getstate(struct pfioc_nv *);
static int pf_getstates(struct pfioc_nv *);
static int pf_clear_tables(void);
static void pf_clear_srcnodes(struct pf_ksrc_node *);
static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
@ -2119,7 +2118,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
case DIOCSETDEBUG:
case DIOCGETSTATES:
case DIOCGETSTATESV2:
case DIOCGETSTATESNV:
case DIOCGETTIMEOUT:
case DIOCCLRRULECTRS:
case DIOCGETLIMIT:
@ -2174,7 +2172,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
case DIOCGETSTATUS:
case DIOCGETSTATES:
case DIOCGETSTATESV2:
case DIOCGETSTATESNV:
case DIOCGETTIMEOUT:
case DIOCGETLIMIT:
case DIOCGETALTQSV0:
@ -2963,11 +2960,6 @@ DIOCGETSTATESV2_full:
break;
}
case DIOCGETSTATESNV: {
error = pf_getstates((struct pfioc_nv *)addr);
break;
}
case DIOCGETSTATUS: {
struct pf_status *s = (struct pf_status *)addr;
@ -5203,84 +5195,6 @@ errout:
return (error);
}
static int
pf_getstates(struct pfioc_nv *nv)
{
nvlist_t *nvl = NULL, *nvls;
void *nvlpacked = NULL;
struct pf_kstate *s = NULL;
int error = 0;
uint64_t count = 0;
#define ERROUT(x) ERROUT_FUNCTION(errout, x)
nvl = nvlist_create(0);
if (nvl == NULL)
ERROUT(ENOMEM);
nvlist_add_number(nvl, "count", uma_zone_get_cur(V_pf_state_z));
for (int i = 0; i < pf_hashmask; i++) {
struct pf_idhash *ih = &V_pf_idhash[i];
/* Avoid taking the lock if there are no states in the row. */
if (LIST_EMPTY(&ih->states))
continue;
PF_HASHROW_LOCK(ih);
LIST_FOREACH(s, &ih->states, entry) {
if (s->timeout == PFTM_UNLINKED)
continue;
if (SIGPENDING(curthread)) {
PF_HASHROW_UNLOCK(ih);
ERROUT(EINTR);
}
nvls = pf_state_to_nvstate(s);
if (nvls == NULL) {
PF_HASHROW_UNLOCK(ih);
ERROUT(ENOMEM);
}
if ((nvlist_size(nvl) + nvlist_size(nvls)) > nv->size) {
/* We've run out of room for more states. */
nvlist_destroy(nvls);
PF_HASHROW_UNLOCK(ih);
goto DIOCGETSTATESNV_full;
}
nvlist_append_nvlist_array(nvl, "states", nvls);
nvlist_destroy(nvls);
count++;
}
PF_HASHROW_UNLOCK(ih);
}
/* We've managed to put them all the available space. Let's make sure
* 'count' matches our array (that's racy, because we don't hold a lock
* over all states, only over each row individually. */
(void)nvlist_take_number(nvl, "count");
nvlist_add_number(nvl, "count", count);
DIOCGETSTATESNV_full:
nvlpacked = nvlist_pack(nvl, &nv->len);
if (nvlpacked == NULL)
ERROUT(ENOMEM);
if (nv->size == 0)
ERROUT(0);
else if (nv->size < nv->len)
ERROUT(ENOSPC);
error = copyout(nvlpacked, nv->data, nv->len);
#undef ERROUT
errout:
free(nvlpacked, M_NVLIST);
nvlist_destroy(nvl);
return (error);
}
/*
* XXX - Check for version missmatch!!!
*/