Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf_ioctl.c
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
static unsigned int pf_clear_states(const struct pf_kstate_kill *); | static unsigned int pf_clear_states(const struct pf_kstate_kill *); | ||||
static int pf_killstates(struct pf_kstate_kill *, | static int pf_killstates(struct pf_kstate_kill *, | ||||
unsigned int *); | unsigned int *); | ||||
static int pf_killstates_row(struct pf_kstate_kill *, | static int pf_killstates_row(struct pf_kstate_kill *, | ||||
struct pf_idhash *); | struct pf_idhash *); | ||||
static int pf_killstates_nv(struct pfioc_nv *); | static int pf_killstates_nv(struct pfioc_nv *); | ||||
static int pf_clearstates_nv(struct pfioc_nv *); | static int pf_clearstates_nv(struct pfioc_nv *); | ||||
static int pf_getstate(struct pfioc_nv *); | static int pf_getstate(struct pfioc_nv *); | ||||
static int pf_getstates(struct pfioc_nv *); | |||||
static int pf_clear_tables(void); | static int pf_clear_tables(void); | ||||
static void pf_clear_srcnodes(struct pf_ksrc_node *); | static void pf_clear_srcnodes(struct pf_ksrc_node *); | ||||
static void pf_kill_srcnodes(struct pfioc_src_node_kill *); | static void pf_kill_srcnodes(struct pfioc_src_node_kill *); | ||||
static int pf_keepcounters(struct pfioc_nv *); | static int pf_keepcounters(struct pfioc_nv *); | ||||
static void pf_tbladdr_copyout(struct pf_addr_wrap *); | static void pf_tbladdr_copyout(struct pf_addr_wrap *); | ||||
/* | /* | ||||
* Wrapper functions for pfil(9) hooks | * Wrapper functions for pfil(9) hooks | ||||
▲ Show 20 Lines • Show All 2,723 Lines • ▼ Show 20 Lines | if (securelevel_gt(td->td_ucred, 2)) | ||||
case DIOCGETSTATE: | case DIOCGETSTATE: | ||||
case DIOCGETSTATENV: | case DIOCGETSTATENV: | ||||
case DIOCSETSTATUSIF: | case DIOCSETSTATUSIF: | ||||
case DIOCGETSTATUS: | case DIOCGETSTATUS: | ||||
case DIOCCLRSTATUS: | case DIOCCLRSTATUS: | ||||
case DIOCNATLOOK: | case DIOCNATLOOK: | ||||
case DIOCSETDEBUG: | case DIOCSETDEBUG: | ||||
case DIOCGETSTATES: | case DIOCGETSTATES: | ||||
case DIOCGETSTATESNV: | |||||
case DIOCGETTIMEOUT: | case DIOCGETTIMEOUT: | ||||
case DIOCCLRRULECTRS: | case DIOCCLRRULECTRS: | ||||
case DIOCGETLIMIT: | case DIOCGETLIMIT: | ||||
case DIOCGETALTQSV0: | case DIOCGETALTQSV0: | ||||
case DIOCGETALTQSV1: | case DIOCGETALTQSV1: | ||||
case DIOCGETALTQV0: | case DIOCGETALTQV0: | ||||
case DIOCGETALTQV1: | case DIOCGETALTQV1: | ||||
case DIOCGETQSTATSV0: | case DIOCGETQSTATSV0: | ||||
Show All 36 Lines | if (!(flags & FWRITE)) | ||||
switch (cmd) { | switch (cmd) { | ||||
case DIOCGETRULES: | case DIOCGETRULES: | ||||
case DIOCGETADDRS: | case DIOCGETADDRS: | ||||
case DIOCGETADDR: | case DIOCGETADDR: | ||||
case DIOCGETSTATE: | case DIOCGETSTATE: | ||||
case DIOCGETSTATENV: | case DIOCGETSTATENV: | ||||
case DIOCGETSTATUS: | case DIOCGETSTATUS: | ||||
case DIOCGETSTATES: | case DIOCGETSTATES: | ||||
case DIOCGETSTATESNV: | |||||
case DIOCGETTIMEOUT: | case DIOCGETTIMEOUT: | ||||
case DIOCGETLIMIT: | case DIOCGETLIMIT: | ||||
case DIOCGETALTQSV0: | case DIOCGETALTQSV0: | ||||
case DIOCGETALTQSV1: | case DIOCGETALTQSV1: | ||||
case DIOCGETALTQV0: | case DIOCGETALTQV0: | ||||
case DIOCGETALTQV1: | case DIOCGETALTQV1: | ||||
case DIOCGETQSTATSV0: | case DIOCGETQSTATSV0: | ||||
case DIOCGETQSTATSV1: | case DIOCGETQSTATSV1: | ||||
▲ Show 20 Lines • Show All 693 Lines • ▼ Show 20 Lines | if (error) { | ||||
break; | break; | ||||
} | } | ||||
ps->ps_len = sizeof(struct pfsync_state) * nr; | ps->ps_len = sizeof(struct pfsync_state) * nr; | ||||
free(pstore, M_TEMP); | free(pstore, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCGETSTATESNV: { | |||||
error = pf_getstates((struct pfioc_nv *)addr); | |||||
break; | |||||
} | |||||
case DIOCGETSTATUS: { | case DIOCGETSTATUS: { | ||||
struct pf_status *s = (struct pf_status *)addr; | struct pf_status *s = (struct pf_status *)addr; | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
s->running = V_pf_status.running; | s->running = V_pf_status.running; | ||||
s->since = V_pf_status.since; | s->since = V_pf_status.since; | ||||
s->debug = V_pf_status.debug; | s->debug = V_pf_status.debug; | ||||
s->hostid = V_pf_status.hostid; | s->hostid = V_pf_status.hostid; | ||||
▲ Show 20 Lines • Show All 2,186 Lines • ▼ Show 20 Lines | else if (nv->size < nv->len) | ||||
ERROUT(ENOSPC); | ERROUT(ENOSPC); | ||||
error = copyout(nvlpacked, nv->data, nv->len); | error = copyout(nvlpacked, nv->data, nv->len); | ||||
#undef ERROUT | #undef ERROUT | ||||
errout: | errout: | ||||
if (s != NULL) | if (s != NULL) | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
free(nvlpacked, M_TEMP); | |||||
nvlist_destroy(nvl); | |||||
return (error); | |||||
} | |||||
static int | |||||
pf_getstates(struct pfioc_nv *nv) | |||||
{ | |||||
nvlist_t *nvl = NULL, *nvls; | |||||
void *nvlpacked = NULL; | |||||
struct pf_state *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]; | |||||
PF_HASHROW_LOCK(ih); | |||||
LIST_FOREACH(s, &ih->states, entry) { | |||||
if (s->timeout == PFTM_UNLINKED) | |||||
continue; | |||||
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); | |||||
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_TEMP); | free(nvlpacked, M_TEMP); | ||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* XXX - Check for version missmatch!!! | * XXX - Check for version missmatch!!! | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 406 Lines • Show Last 20 Lines |