Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf_table.c
Show First 20 Lines • Show All 1,425 Lines • ▼ Show 20 Lines | _skip: | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags) | pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags) | ||||
{ | { | ||||
struct pfr_ktableworkq workq; | struct pfr_ktableworkq workq; | ||||
struct pfr_ktable *p; | struct pfr_ktable *p; | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
int xdel = 0; | int xdel = 0; | ||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ||||
rs = pf_find_or_create_ruleset(trs->pfrt_anchor); | rs = pf_find_or_create_kruleset(trs->pfrt_anchor); | ||||
if (rs == NULL) | if (rs == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
SLIST_INIT(&workq); | SLIST_INIT(&workq); | ||||
RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | ||||
if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | ||||
pfr_skip_table(trs, p, 0)) | pfr_skip_table(trs, p, 0)) | ||||
continue; | continue; | ||||
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE; | p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE; | ||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | ||||
xdel++; | xdel++; | ||||
} | } | ||||
if (!(flags & PFR_FLAG_DUMMY)) { | if (!(flags & PFR_FLAG_DUMMY)) { | ||||
pfr_setflags_ktables(&workq); | pfr_setflags_ktables(&workq); | ||||
if (ticket != NULL) | if (ticket != NULL) | ||||
*ticket = ++rs->tticket; | *ticket = ++rs->tticket; | ||||
rs->topen = 1; | rs->topen = 1; | ||||
} else | } else | ||||
pf_remove_if_empty_ruleset(rs); | pf_remove_if_empty_kruleset(rs); | ||||
if (ndel != NULL) | if (ndel != NULL) | ||||
*ndel = xdel; | *ndel = xdel; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, | pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, | ||||
int *nadd, int *naddr, u_int32_t ticket, int flags) | int *nadd, int *naddr, u_int32_t ticket, int flags) | ||||
{ | { | ||||
struct pfr_ktableworkq tableq; | struct pfr_ktableworkq tableq; | ||||
struct pfr_kentryworkq addrq; | struct pfr_kentryworkq addrq; | ||||
struct pfr_ktable *kt, *rt, *shadow, key; | struct pfr_ktable *kt, *rt, *shadow, key; | ||||
struct pfr_kentry *p; | struct pfr_kentry *p; | ||||
struct pfr_addr *ad; | struct pfr_addr *ad; | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
int i, rv, xadd = 0, xaddr = 0; | int i, rv, xadd = 0, xaddr = 0; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO); | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO); | ||||
if (size && !(flags & PFR_FLAG_ADDRSTOO)) | if (size && !(flags & PFR_FLAG_ADDRSTOO)) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK, | if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK, | ||||
flags & PFR_FLAG_USERIOCTL)) | flags & PFR_FLAG_USERIOCTL)) | ||||
return (EINVAL); | return (EINVAL); | ||||
rs = pf_find_ruleset(tbl->pfrt_anchor); | rs = pf_find_kruleset(tbl->pfrt_anchor); | ||||
if (rs == NULL || !rs->topen || ticket != rs->tticket) | if (rs == NULL || !rs->topen || ticket != rs->tticket) | ||||
return (EBUSY); | return (EBUSY); | ||||
tbl->pfrt_flags |= PFR_TFLAG_INACTIVE; | tbl->pfrt_flags |= PFR_TFLAG_INACTIVE; | ||||
SLIST_INIT(&tableq); | SLIST_INIT(&tableq); | ||||
kt = RB_FIND(pfr_ktablehead, &V_pfr_ktables, (struct pfr_ktable *)tbl); | kt = RB_FIND(pfr_ktablehead, &V_pfr_ktables, (struct pfr_ktable *)tbl); | ||||
if (kt == NULL) { | if (kt == NULL) { | ||||
kt = pfr_create_ktable(tbl, 0, 1); | kt = pfr_create_ktable(tbl, 0, 1); | ||||
if (kt == NULL) | if (kt == NULL) | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | _bad: | ||||
return (rv); | return (rv); | ||||
} | } | ||||
int | int | ||||
pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags) | pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags) | ||||
{ | { | ||||
struct pfr_ktableworkq workq; | struct pfr_ktableworkq workq; | ||||
struct pfr_ktable *p; | struct pfr_ktable *p; | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
int xdel = 0; | int xdel = 0; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ||||
rs = pf_find_ruleset(trs->pfrt_anchor); | rs = pf_find_kruleset(trs->pfrt_anchor); | ||||
if (rs == NULL || !rs->topen || ticket != rs->tticket) | if (rs == NULL || !rs->topen || ticket != rs->tticket) | ||||
return (0); | return (0); | ||||
SLIST_INIT(&workq); | SLIST_INIT(&workq); | ||||
RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | ||||
if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | ||||
pfr_skip_table(trs, p, 0)) | pfr_skip_table(trs, p, 0)) | ||||
continue; | continue; | ||||
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE; | p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE; | ||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | ||||
xdel++; | xdel++; | ||||
} | } | ||||
if (!(flags & PFR_FLAG_DUMMY)) { | if (!(flags & PFR_FLAG_DUMMY)) { | ||||
pfr_setflags_ktables(&workq); | pfr_setflags_ktables(&workq); | ||||
rs->topen = 0; | rs->topen = 0; | ||||
pf_remove_if_empty_ruleset(rs); | pf_remove_if_empty_kruleset(rs); | ||||
} | } | ||||
if (ndel != NULL) | if (ndel != NULL) | ||||
*ndel = xdel; | *ndel = xdel; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, | pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, | ||||
int *nchange, int flags) | int *nchange, int flags) | ||||
{ | { | ||||
struct pfr_ktable *p, *q; | struct pfr_ktable *p, *q; | ||||
struct pfr_ktableworkq workq; | struct pfr_ktableworkq workq; | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
int xadd = 0, xchange = 0; | int xadd = 0, xchange = 0; | ||||
long tzero = time_second; | long tzero = time_second; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); | ||||
rs = pf_find_ruleset(trs->pfrt_anchor); | rs = pf_find_kruleset(trs->pfrt_anchor); | ||||
if (rs == NULL || !rs->topen || ticket != rs->tticket) | if (rs == NULL || !rs->topen || ticket != rs->tticket) | ||||
return (EBUSY); | return (EBUSY); | ||||
SLIST_INIT(&workq); | SLIST_INIT(&workq); | ||||
RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { | ||||
if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || | ||||
pfr_skip_table(trs, p, 0)) | pfr_skip_table(trs, p, 0)) | ||||
continue; | continue; | ||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); | ||||
if (p->pfrkt_flags & PFR_TFLAG_ACTIVE) | if (p->pfrkt_flags & PFR_TFLAG_ACTIVE) | ||||
xchange++; | xchange++; | ||||
else | else | ||||
xadd++; | xadd++; | ||||
} | } | ||||
if (!(flags & PFR_FLAG_DUMMY)) { | if (!(flags & PFR_FLAG_DUMMY)) { | ||||
for (p = SLIST_FIRST(&workq); p != NULL; p = q) { | for (p = SLIST_FIRST(&workq); p != NULL; p = q) { | ||||
q = SLIST_NEXT(p, pfrkt_workq); | q = SLIST_NEXT(p, pfrkt_workq); | ||||
pfr_commit_ktable(p, tzero); | pfr_commit_ktable(p, tzero); | ||||
} | } | ||||
rs->topen = 0; | rs->topen = 0; | ||||
pf_remove_if_empty_ruleset(rs); | pf_remove_if_empty_kruleset(rs); | ||||
} | } | ||||
if (nadd != NULL) | if (nadd != NULL) | ||||
*nadd = xadd; | *nadd = xadd; | ||||
if (nchange != NULL) | if (nchange != NULL) | ||||
*nchange = xchange; | *nchange = xchange; | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | for (i = strlen(anchor); i < siz; i++) | ||||
if (anchor[i]) | if (anchor[i]) | ||||
return (-1); | return (-1); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfr_table_count(struct pfr_table *filter, int flags) | pfr_table_count(struct pfr_table *filter, int flags) | ||||
{ | { | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
PF_RULES_ASSERT(); | PF_RULES_ASSERT(); | ||||
if (flags & PFR_FLAG_ALLRSETS) | if (flags & PFR_FLAG_ALLRSETS) | ||||
return (V_pfr_ktable_cnt); | return (V_pfr_ktable_cnt); | ||||
if (filter->pfrt_anchor[0]) { | if (filter->pfrt_anchor[0]) { | ||||
rs = pf_find_ruleset(filter->pfrt_anchor); | rs = pf_find_kruleset(filter->pfrt_anchor); | ||||
return ((rs != NULL) ? rs->tables : -1); | return ((rs != NULL) ? rs->tables : -1); | ||||
} | } | ||||
return (pf_main_ruleset.tables); | return (pf_main_ruleset.tables); | ||||
} | } | ||||
static int | static int | ||||
pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags) | pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | pfr_clstats_ktable(struct pfr_ktable *kt, long tzero, int recurse) | ||||
counter_u64_zero(kt->pfrkt_nomatch); | counter_u64_zero(kt->pfrkt_nomatch); | ||||
kt->pfrkt_tzero = tzero; | kt->pfrkt_tzero = tzero; | ||||
} | } | ||||
static struct pfr_ktable * | static struct pfr_ktable * | ||||
pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset) | pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset) | ||||
{ | { | ||||
struct pfr_ktable *kt; | struct pfr_ktable *kt; | ||||
struct pf_ruleset *rs; | struct pf_kruleset *rs; | ||||
int pfr_dir, pfr_op; | int pfr_dir, pfr_op; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
kt = malloc(sizeof(*kt), M_PFTABLE, M_NOWAIT|M_ZERO); | kt = malloc(sizeof(*kt), M_PFTABLE, M_NOWAIT|M_ZERO); | ||||
if (kt == NULL) | if (kt == NULL) | ||||
return (NULL); | return (NULL); | ||||
kt->pfrkt_t = *tbl; | kt->pfrkt_t = *tbl; | ||||
if (attachruleset) { | if (attachruleset) { | ||||
rs = pf_find_or_create_ruleset(tbl->pfrt_anchor); | rs = pf_find_or_create_kruleset(tbl->pfrt_anchor); | ||||
if (!rs) { | if (!rs) { | ||||
pfr_destroy_ktable(kt, 0); | pfr_destroy_ktable(kt, 0); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
kt->pfrkt_rs = rs; | kt->pfrkt_rs = rs; | ||||
rs->tables++; | rs->tables++; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr) | ||||
if (kt->pfrkt_ip4 != NULL) | if (kt->pfrkt_ip4 != NULL) | ||||
rn_detachhead((void **)&kt->pfrkt_ip4); | rn_detachhead((void **)&kt->pfrkt_ip4); | ||||
if (kt->pfrkt_ip6 != NULL) | if (kt->pfrkt_ip6 != NULL) | ||||
rn_detachhead((void **)&kt->pfrkt_ip6); | rn_detachhead((void **)&kt->pfrkt_ip6); | ||||
if (kt->pfrkt_shadow != NULL) | if (kt->pfrkt_shadow != NULL) | ||||
pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr); | pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr); | ||||
if (kt->pfrkt_rs != NULL) { | if (kt->pfrkt_rs != NULL) { | ||||
kt->pfrkt_rs->tables--; | kt->pfrkt_rs->tables--; | ||||
pf_remove_if_empty_ruleset(kt->pfrkt_rs); | pf_remove_if_empty_kruleset(kt->pfrkt_rs); | ||||
} | } | ||||
for (pfr_dir = 0; pfr_dir < PFR_DIR_MAX; pfr_dir ++) { | for (pfr_dir = 0; pfr_dir < PFR_DIR_MAX; pfr_dir ++) { | ||||
for (pfr_op = 0; pfr_op < PFR_OP_TABLE_MAX; pfr_op ++) { | for (pfr_op = 0; pfr_op < PFR_OP_TABLE_MAX; pfr_op ++) { | ||||
counter_u64_free(kt->pfrkt_packets[pfr_dir][pfr_op]); | counter_u64_free(kt->pfrkt_packets[pfr_dir][pfr_op]); | ||||
counter_u64_free(kt->pfrkt_bytes[pfr_dir][pfr_op]); | counter_u64_free(kt->pfrkt_bytes[pfr_dir][pfr_op]); | ||||
} | } | ||||
} | } | ||||
counter_u64_free(kt->pfrkt_match); | counter_u64_free(kt->pfrkt_match); | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | if (ke != NULL && op_pass != PFR_OP_XPASS && | ||||
counter_u64_add(pfr_kentry_counter(&ke->pfrke_counters, | counter_u64_add(pfr_kentry_counter(&ke->pfrke_counters, | ||||
dir_out, op_pass, PFR_TYPE_PACKETS), 1); | dir_out, op_pass, PFR_TYPE_PACKETS), 1); | ||||
counter_u64_add(pfr_kentry_counter(&ke->pfrke_counters, | counter_u64_add(pfr_kentry_counter(&ke->pfrke_counters, | ||||
dir_out, op_pass, PFR_TYPE_BYTES), len); | dir_out, op_pass, PFR_TYPE_BYTES), len); | ||||
} | } | ||||
} | } | ||||
struct pfr_ktable * | struct pfr_ktable * | ||||
pfr_attach_table(struct pf_ruleset *rs, char *name) | pfr_attach_table(struct pf_kruleset *rs, char *name) | ||||
{ | { | ||||
struct pfr_ktable *kt, *rt; | struct pfr_ktable *kt, *rt; | ||||
struct pfr_table tbl; | struct pfr_table tbl; | ||||
struct pf_anchor *ac = rs->anchor; | struct pf_kanchor *ac = rs->anchor; | ||||
PF_RULES_WASSERT(); | PF_RULES_WASSERT(); | ||||
bzero(&tbl, sizeof(tbl)); | bzero(&tbl, sizeof(tbl)); | ||||
strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)); | strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)); | ||||
if (ac != NULL) | if (ac != NULL) | ||||
strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor)); | strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor)); | ||||
kt = pfr_lookup_table(&tbl); | kt = pfr_lookup_table(&tbl); | ||||
▲ Show 20 Lines • Show All 176 Lines • Show Last 20 Lines |