Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf_ioctl.c
Show First 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* XXX - These are new and need to be checked when moveing to a new version | * XXX - These are new and need to be checked when moveing to a new version | ||||
*/ | */ | ||||
static void pf_clear_states(void); | static void pf_clear_states(void); | ||||
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 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 | ||||
*/ | */ | ||||
#ifdef INET | #ifdef INET | ||||
static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp, | static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp, | ||||
int flags, void *ruleset __unused, struct inpcb *inp); | int flags, void *ruleset __unused, struct inpcb *inp); | ||||
▲ Show 20 Lines • Show All 809 Lines • ▼ Show 20 Lines | pf_hash_rule(MD5_CTX *ctx, struct pf_krule *rule) | ||||
PF_MD5_UPD(rule, code); | PF_MD5_UPD(rule, code); | ||||
PF_MD5_UPD(rule, flags); | PF_MD5_UPD(rule, flags); | ||||
PF_MD5_UPD(rule, flagset); | PF_MD5_UPD(rule, flagset); | ||||
PF_MD5_UPD(rule, allow_opts); | PF_MD5_UPD(rule, allow_opts); | ||||
PF_MD5_UPD(rule, rt); | PF_MD5_UPD(rule, rt); | ||||
PF_MD5_UPD(rule, tos); | PF_MD5_UPD(rule, tos); | ||||
} | } | ||||
static bool | |||||
pf_krule_compare(struct pf_krule *a, struct pf_krule *b) | |||||
{ | |||||
MD5_CTX ctx[2]; | |||||
u_int8_t digest[2][PF_MD5_DIGEST_LENGTH]; | |||||
MD5Init(&ctx[0]); | |||||
MD5Init(&ctx[1]); | |||||
pf_hash_rule(&ctx[0], a); | |||||
pf_hash_rule(&ctx[1], b); | |||||
MD5Final(digest[0], &ctx[0]); | |||||
MD5Final(digest[1], &ctx[1]); | |||||
return (memcmp(digest[0], digest[1], PF_MD5_DIGEST_LENGTH) == 0); | |||||
} | |||||
static int | static int | ||||
pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) | pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) | ||||
{ | { | ||||
struct pf_kruleset *rs; | struct pf_kruleset *rs; | ||||
struct pf_krule *rule, **old_array; | struct pf_krule *rule, **old_array, *tail; | ||||
struct pf_krulequeue *old_rules; | struct pf_krulequeue *old_rules; | ||||
int error; | int error; | ||||
u_int32_t old_rcount; | u_int32_t old_rcount; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | ||||
return (EINVAL); | return (EINVAL); | ||||
Show All 15 Lines | pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) | ||||
old_array = rs->rules[rs_num].active.ptr_array; | old_array = rs->rules[rs_num].active.ptr_array; | ||||
rs->rules[rs_num].active.ptr = | rs->rules[rs_num].active.ptr = | ||||
rs->rules[rs_num].inactive.ptr; | rs->rules[rs_num].inactive.ptr; | ||||
rs->rules[rs_num].active.ptr_array = | rs->rules[rs_num].active.ptr_array = | ||||
rs->rules[rs_num].inactive.ptr_array; | rs->rules[rs_num].inactive.ptr_array; | ||||
rs->rules[rs_num].active.rcount = | rs->rules[rs_num].active.rcount = | ||||
rs->rules[rs_num].inactive.rcount; | rs->rules[rs_num].inactive.rcount; | ||||
/* Attempt to preserve counter information. */ | |||||
if (V_pf_status.keep_counters) { | |||||
TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr, | |||||
entries) { | |||||
tail = TAILQ_FIRST(old_rules); | |||||
while ((tail != NULL) && ! pf_krule_compare(tail, rule)) | |||||
tail = TAILQ_NEXT(tail, entries); | |||||
if (tail != NULL) { | |||||
counter_u64_add(rule->evaluations, | |||||
counter_u64_fetch(tail->evaluations)); | |||||
counter_u64_add(rule->packets[0], | |||||
counter_u64_fetch(tail->packets[0])); | |||||
counter_u64_add(rule->packets[1], | |||||
counter_u64_fetch(tail->packets[1])); | |||||
counter_u64_add(rule->bytes[0], | |||||
counter_u64_fetch(tail->bytes[0])); | |||||
counter_u64_add(rule->bytes[1], | |||||
counter_u64_fetch(tail->bytes[1])); | |||||
} | |||||
} | |||||
} | |||||
rs->rules[rs_num].inactive.ptr = old_rules; | rs->rules[rs_num].inactive.ptr = old_rules; | ||||
rs->rules[rs_num].inactive.ptr_array = old_array; | rs->rules[rs_num].inactive.ptr_array = old_array; | ||||
rs->rules[rs_num].inactive.rcount = old_rcount; | rs->rules[rs_num].inactive.rcount = old_rcount; | ||||
rs->rules[rs_num].active.ticket = | rs->rules[rs_num].active.ticket = | ||||
rs->rules[rs_num].inactive.ticket; | rs->rules[rs_num].inactive.ticket; | ||||
pf_calc_skip_steps(rs->rules[rs_num].active.ptr); | pf_calc_skip_steps(rs->rules[rs_num].active.ptr); | ||||
▲ Show 20 Lines • Show All 3,874 Lines • ▼ Show 20 Lines | case DIOCCLRSRCNODES: { | ||||
pf_purge_expired_src_nodes(); | pf_purge_expired_src_nodes(); | ||||
break; | break; | ||||
} | } | ||||
case DIOCKILLSRCNODES: | case DIOCKILLSRCNODES: | ||||
pf_kill_srcnodes((struct pfioc_src_node_kill *)addr); | pf_kill_srcnodes((struct pfioc_src_node_kill *)addr); | ||||
break; | break; | ||||
case DIOCKEEPCOUNTERS: | |||||
error = pf_keepcounters((struct pfioc_nv *)addr); | |||||
break; | |||||
case DIOCSETHOSTID: { | case DIOCSETHOSTID: { | ||||
u_int32_t *hostid = (u_int32_t *)addr; | u_int32_t *hostid = (u_int32_t *)addr; | ||||
PF_RULES_WLOCK(); | PF_RULES_WLOCK(); | ||||
if (*hostid == 0) | if (*hostid == 0) | ||||
V_pf_status.hostid = arc4random(); | V_pf_status.hostid = arc4random(); | ||||
else | else | ||||
V_pf_status.hostid = *hostid; | V_pf_status.hostid = *hostid; | ||||
▲ Show 20 Lines • Show All 261 Lines • ▼ Show 20 Lines | LIST_FOREACH(s, &ih->states, entry) { | ||||
s->src_node = NULL; | s->src_node = NULL; | ||||
if (s->nat_src_node && s->nat_src_node->expire == 1) | if (s->nat_src_node && s->nat_src_node->expire == 1) | ||||
s->nat_src_node = NULL; | s->nat_src_node = NULL; | ||||
} | } | ||||
PF_HASHROW_UNLOCK(ih); | PF_HASHROW_UNLOCK(ih); | ||||
} | } | ||||
psnk->psnk_killed = pf_free_src_nodes(&kill); | psnk->psnk_killed = pf_free_src_nodes(&kill); | ||||
} | |||||
static int | |||||
pf_keepcounters(struct pfioc_nv *nv) | |||||
{ | |||||
nvlist_t *nvl = NULL; | |||||
void *nvlpacked = NULL; | |||||
int error = 0; | |||||
#define ERROUT(x) do { error = (x); goto on_error; } while (0) | |||||
if (nv->len > pf_ioctl_maxcount) | |||||
ERROUT(ENOMEM); | |||||
nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK); | |||||
if (nvlpacked == NULL) | |||||
ERROUT(ENOMEM); | |||||
error = copyin(nv->data, nvlpacked, nv->len); | |||||
if (error) | |||||
ERROUT(error); | |||||
nvl = nvlist_unpack(nvlpacked, nv->len, 0); | |||||
if (nvl == NULL) | |||||
ERROUT(EBADMSG); | |||||
if (! nvlist_exists_bool(nvl, "keep_counters")) | |||||
ERROUT(EBADMSG); | |||||
V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters"); | |||||
on_error: | |||||
nvlist_destroy(nvl); | |||||
free(nvlpacked, M_TEMP); | |||||
return (error); | |||||
} | } | ||||
/* | /* | ||||
* XXX - Check for version missmatch!!! | * XXX - Check for version missmatch!!! | ||||
*/ | */ | ||||
/* | /* | ||||
* Duplicate pfctl -Fa operation to get rid of as much as we can. | * Duplicate pfctl -Fa operation to get rid of as much as we can. | ||||
▲ Show 20 Lines • Show All 403 Lines • Show Last 20 Lines |