summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/pfctl/parse.y22
-rw-r--r--sbin/pfctl/pf_print_state.c13
-rw-r--r--sbin/pfctl/pfctl.h4
-rw-r--r--sbin/pfctl/pfctl_radix.c45
-rw-r--r--sbin/pfctl/pfctl_table.c26
-rw-r--r--sys/net/pf.c142
-rw-r--r--sys/net/pf_ioctl.c43
-rw-r--r--sys/net/pf_norm.c30
-rw-r--r--sys/net/pf_table.c223
-rw-r--r--sys/net/pfvar.h59
10 files changed, 229 insertions, 378 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index c3b55028a77..1c2edb43550 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.279 2003/01/06 11:30:10 mcbride Exp $ */
+/* $OpenBSD: parse.y,v 1.280 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -1479,23 +1479,19 @@ xhost : '!' host {
host : address
| STRING '/' number { $$ = host($1, $3); }
| PORTUNARY STRING PORTUNARY {
- struct pfr_table tbl;
- int exists = 0;
-
if ($1 != PF_OP_LT || $3 != PF_OP_GT)
YYERROR;
+ if (strlen($2) >= PF_TABLE_NAME_SIZE) {
+ yyerror("table name '%s' too long");
+ YYERROR;
+ }
$$ = calloc(1, sizeof(struct node_host));
if ($$ == NULL)
err(1, "host: calloc");
- $$->af = 0;
- bzero(&tbl, sizeof(tbl));
- strlcpy(tbl.pfrt_name, $2, sizeof(tbl.pfrt_name));
- if (pfr_wrap_table(&tbl, &$$->addr, &exists, 0))
- err(1, "pfr_wrap_table");
- if (!exists)
- fprintf(stderr, "warning: %s "
- "table is not currently defined\n",
- tbl.pfrt_name);
+ $$->addr.type = PF_ADDR_TABLE;
+ strlcpy($$->addr.v.tblname, $2, PF_TABLE_NAME_SIZE);
+ $$->next = NULL;
+ $$->tail = $$;
}
;
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
index bafcc1166b5..27fb9b19cb2 100644
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_print_state.c,v 1.17 2003/01/05 22:14:23 dhartmei Exp $ */
+/* $OpenBSD: pf_print_state.c,v 1.18 2003/01/07 00:21:08 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -62,17 +62,10 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af)
{
char buf[48];
- if (addr->v.a.mask.addr32[0] == PF_TABLE_MASK) {
- struct pfr_table tbl = { "?" };
-
- if (pfr_unwrap_table(&tbl, addr, 0))
- printf("<0x%08X>", addr->v.a.addr.addr32[0]);
- else
- printf("<%s>", tbl.pfrt_name);
- return;
- }
if (addr->type == PF_ADDR_DYNIFTL)
printf("(%s)", addr->v.ifname);
+ else if (addr->type == PF_ADDR_TABLE)
+ printf("<%s>", addr->v.tblname);
else {
if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
printf("?");
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 5346ab1a949..8111f407405 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.h,v 1.2 2003/01/04 22:42:14 henning Exp $ */
+/* $OpenBSD: pfctl.h,v 1.3 2003/01/07 00:21:08 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -50,8 +50,6 @@ int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
-int pfr_wrap_table(struct pfr_table *, struct pf_addr_wrap *, int *, int);
-int pfr_unwrap_table(struct pfr_table *, struct pf_addr_wrap *, int);
int pfctl_clear_tables(int);
int pfctl_show_tables(int);
int pfctl_command_tables(int, char *[], char *, char *, char *, int);
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 08de265eb5d..d5fdb825dac 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_radix.c,v 1.6 2003/01/04 00:01:34 deraadt Exp $ */
+/* $OpenBSD: pfctl_radix.c,v 1.7 2003/01/07 00:21:08 dhartmei Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -337,46 +337,3 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
*nmatch = io.pfrio_nmatch;
return (0);
}
-
-int
-pfr_wrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap,
- int *exists, int flags)
-{
- struct pfioc_table io;
-
- if (tbl == NULL) {
- errno = EINVAL;
- return -1;
- }
- bzero(&io, sizeof io);
- io.pfrio_flags = flags;
- io.pfrio_table = *tbl;
- io.pfrio_buffer = wrap;
- io.pfrio_size = wrap ? 1 : 0;
- io.pfrio_exists = exists ? 1 : 0;
- if (ioctl(dev, DIOCRWRAPTABLE, &io))
- return (-1);
- if (exists)
- *exists = io.pfrio_exists;
- return (0);
-}
-
-int
-pfr_unwrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, int flags)
-{
- struct pfioc_table io;
-
- if (wrap == NULL) {
- errno = EINVAL;
- return -1;
- }
- bzero(&io, sizeof io);
- io.pfrio_flags = flags;
- io.pfrio_buffer = wrap;
- io.pfrio_size = 1;
- if (ioctl(dev, DIOCRUNWRTABLE, &io))
- return (-1);
- if (tbl != NULL)
- *tbl = io.pfrio_table;
- return (0);
-}
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 7db623f3771..9957718b181 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_table.c,v 1.11 2003/01/04 00:01:34 deraadt Exp $ */
+/* $OpenBSD: pfctl_table.c,v 1.12 2003/01/07 00:21:08 dhartmei Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -60,8 +60,8 @@
extern void usage(void);
static int pfctl_table(int, char *[], char *, char *, char *, int);
static void grow_buffer(int, int);
-static void print_table(struct pfr_table *);
-static void print_tstats(struct pfr_tstats *);
+static void print_table(struct pfr_table *, int);
+static void print_tstats(struct pfr_tstats *, int);
static void load_addr(int, char *[], char *, int);
static int next_token(char [], FILE *);
static void append_addr(char *, int);
@@ -181,9 +181,11 @@ pfctl_table(int argc, char *argv[], char *tname, char *command,
}
for (i = 0; i < size; i++)
if (opts & PF_OPT_VERBOSE)
- print_tstats(buffer.tstats+i);
+ print_tstats(buffer.tstats+i,
+ opts & PF_OPT_VERBOSE2);
else
- print_table(buffer.tables+i);
+ print_table(buffer.tables+i,
+ opts & PF_OPT_VERBOSE2);
} else if (!strcmp(*p, "create")) {
if (argc || file != NULL)
usage();
@@ -358,19 +360,25 @@ grow_buffer(int bs, int minsize)
}
void
-print_table(struct pfr_table *ta)
+print_table(struct pfr_table *ta, int all)
{
- printf("%s\n", ta->pfrt_name);
+ if (!all && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
+ return;
+ printf(" %c%s\n", (ta->pfrt_flags & PFR_TFLAG_PERSIST)?'+':' ',
+ ta->pfrt_name);
}
void
-print_tstats(struct pfr_tstats *ts)
+print_tstats(struct pfr_tstats *ts, int all)
{
time_t time = ts->pfrts_tzero;
int dir, op;
- printf("%s\n", ts->pfrts_name);
+ if (!all && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE))
+ return;
+ print_table(&ts->pfrts_t, all);
printf("\tAddresses: %d\n", ts->pfrts_cnt);
+ printf("\tReferences: %d\n", ts->pfrts_refcnt);
printf("\tCleared: %s", ctime(&time));
printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n",
ts->pfrts_nomatch, ts->pfrts_match);
diff --git a/sys/net/pf.c b/sys/net/pf.c
index fa9eeaf1a71..7bdc9617f99 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.299 2003/01/06 10:08:36 deraadt Exp $ */
+/* $OpenBSD: pf.c,v 1.300 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -150,6 +150,8 @@ struct pf_state *pf_find_state(struct pf_state_tree *,
struct pf_tree_node *);
void pf_purge_expired_states(void);
void pf_purge_timeout(void *);
+int pf_tbladdr_setup(struct pf_addr_wrap *);
+void pf_tbladdr_remove(struct pf_addr_wrap *);
void pf_dynaddr_update(void *);
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
void pf_print_state(struct pf_state *);
@@ -508,6 +510,25 @@ pf_purge_expired_states(void)
}
int
+pf_tbladdr_setup(struct pf_addr_wrap *aw)
+{
+ if (aw->type != PF_ADDR_TABLE)
+ return (0);
+ if ((aw->p.tbl = pfr_attach_table(aw->v.tblname)) == NULL)
+ return (1);
+ return (0);
+}
+
+void
+pf_tbladdr_remove(struct pf_addr_wrap *aw)
+{
+ if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
+ return;
+ pfr_detach_table(aw->p.tbl);
+ aw->p.tbl = NULL;
+}
+
+int
pf_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
{
if (aw->type != PF_ADDR_DYNIFTL)
@@ -751,6 +772,8 @@ pf_calc_skip_steps(struct pf_rulequeue *rules)
PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
if (cur->src.addr.type == PF_ADDR_DYNIFTL ||
prev->src.addr.type == PF_ADDR_DYNIFTL ||
+ cur->src.addr.type == PF_ADDR_TABLE ||
+ prev->src.addr.type == PF_ADDR_TABLE ||
cur->src.not != prev->src.not ||
(cur->src.addr.type == PF_ADDR_NOROUTE) !=
(prev->src.addr.type == PF_ADDR_NOROUTE) ||
@@ -763,6 +786,8 @@ pf_calc_skip_steps(struct pf_rulequeue *rules)
PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
if (cur->dst.addr.type == PF_ADDR_DYNIFTL ||
prev->dst.addr.type == PF_ADDR_DYNIFTL ||
+ cur->dst.addr.type == PF_ADDR_TABLE ||
+ prev->dst.addr.type == PF_ADDR_TABLE ||
cur->dst.not != prev->dst.not ||
(cur->dst.addr.type == PF_ADDR_NOROUTE) !=
(prev->dst.addr.type == PF_ADDR_NOROUTE) ||
@@ -1168,9 +1193,6 @@ pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
{
int match = 0;
- if (m->addr32[0] == PF_TABLE_MASK)
- return (pfr_match_addr(a, m, b, af) != n);
-
switch (af) {
#ifdef INET
case AF_INET:
@@ -1411,6 +1433,9 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
struct pf_addr *raddr = &rpool->cur->addr.addr.v.a.addr;
struct pf_addr *rmask = &rpool->cur->addr.addr.v.a.mask;
+ if (cur->addr.addr.type == PF_ADDR_NOROUTE ||
+ cur->addr.addr.type == PF_ADDR_TABLE)
+ return (1);
if (cur->addr.addr.type == PF_ADDR_DYNIFTL &&
cur->addr.addr.p.dyn->undefined)
return (1);
@@ -1607,17 +1632,14 @@ pf_match_translation(int direction, struct ifnet *ifp, u_int8_t proto,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (src != NULL && !PF_AZERO(&src->addr.v.a.mask, af) &&
- !PF_MATCHA(src->not,
- &src->addr.v.a.addr, &src->addr.v.a.mask, saddr, af))
+ else if (src != NULL &&
+ PF_MISMATCHAW(&src->addr, saddr, af, src->not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (src != NULL && src->port_op &&
!pf_match_port(src->port_op, src->port[0],
src->port[1], sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (!PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not,
- &r->dst.addr.v.a.addr, &r->dst.addr.v.a.mask, daddr, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], dport))
@@ -1836,24 +1858,12 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != IPPROTO_TCP)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(saddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, saddr, af))
+ else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(daddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->dst.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, daddr, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
@@ -2093,24 +2103,12 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != IPPROTO_UDP)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(saddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, saddr, af))
+ else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], uh->uh_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(daddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->dst.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, daddr, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], uh->uh_dport))
@@ -2374,21 +2372,9 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(saddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, saddr, af))
+ else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(daddr, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->dst.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, daddr, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->type && r->type != icmptype + 1)
r = TAILQ_NEXT(r, entries);
@@ -2581,21 +2567,9 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->src, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, pd->src, af))
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->dst, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, pd->dst, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->tos && !(r->tos & pd->tos))
r = TAILQ_NEXT(r, entries);
@@ -2730,21 +2704,9 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->src, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, pd->src, af))
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->dst, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, pd->dst, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->tos && !(r->tos & pd->tos))
r = TAILQ_NEXT(r, entries);
@@ -4176,16 +4138,16 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
}
done:
- if (r != NULL && r->src.addr.v.a.mask.addr32[0] == PF_TABLE_MASK)
- pfr_update_stats(&r->src.addr.v.a.addr, &r->src.addr.v.a.mask,
- (r->direction == dir) ? pd.src : pd.dst,
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, r->src.not);
- if (r != NULL && r->dst.addr.v.a.mask.addr32[0] == PF_TABLE_MASK)
- pfr_update_stats(&r->dst.addr.v.a.addr, &r->dst.addr.v.a.mask,
- (r->direction == dir) ? pd.dst : pd.src,
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, r->dst.not);
+ if (r != NULL && r->src.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(r->src.addr.p.tbl,
+ (r->direction == dir) ? pd.src : pd.dst, pd.af,
+ pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
+ r->src.not);
+ if (r != NULL && r->dst.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(r->dst.addr.p.tbl,
+ (r->direction == dir) ? pd.dst : pd.src, pd.af,
+ pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
+ r->dst.not);
if (action != PF_DROP && h->ip_hl > 5 &&
!((s && s->allow_opts) || (r && r->allow_opts))) {
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 719f82ccc9b..6f75f10f72c 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.44 2003/01/06 14:19:40 cedric Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.45 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -364,6 +364,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
{
pf_dynaddr_remove(&rule->src.addr);
pf_dynaddr_remove(&rule->dst.addr);
+ pf_tbladdr_remove(&rule->src.addr);
+ pf_tbladdr_remove(&rule->dst.addr);
pf_empty_pool(&rule->rpool.list);
if (rulequeue != NULL)
TAILQ_REMOVE(rulequeue, rule, entries);
@@ -413,8 +415,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCRGETASTATS:
case DIOCRCLRASTATS:
case DIOCRTSTADDRS:
- case DIOCRWRAPTABLE:
- case DIOCRUNWRTABLE:
break;
default:
return (EPERM);
@@ -443,8 +443,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCRGETADDRS:
case DIOCRGETASTATS:
case DIOCRTSTADDRS:
- case DIOCRWRAPTABLE:
- case DIOCRUNWRTABLE:
break;
default:
return (EACCES);
@@ -572,6 +570,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_dynaddr_setup(&rule->dst.addr, rule->af))
error = EINVAL;
+ if (pf_tbladdr_setup(&rule->src.addr))
+ error = EINVAL;
+ if (pf_tbladdr_setup(&rule->dst.addr))
+ error = EINVAL;
pf_mv_pool(&pf_pabuf, &rule->rpool.list);
if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
@@ -793,6 +795,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_dynaddr_setup(&newrule->dst.addr, newrule->af))
error = EINVAL;
+ if (pf_tbladdr_setup(&newrule->src.addr))
+ error = EINVAL;
+ if (pf_tbladdr_setup(&newrule->dst.addr))
+ error = EINVAL;
pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
if (((((newrule->action == PF_NAT) ||
@@ -1461,6 +1467,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
#endif /* INET6 */
+ if (pp->addr.addr.addr.type != PF_ADDR_ADDRMASK &&
+ pp->addr.addr.addr.type != PF_ADDR_DYNIFTL) {
+ error = EINVAL;
+ break;
+ }
pa = pool_get(&pf_pooladdr_pl, PR_NOWAIT);
if (pa == NULL) {
error = ENOMEM;
@@ -1540,6 +1551,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
break;
}
+ if (pca->addr.addr.addr.type != PF_ADDR_ADDRMASK &&
+ pca->addr.addr.addr.type != PF_ADDR_DYNIFTL) {
+ error = EINVAL;
+ break;
+ }
pool = pf_get_pool(pca->anchor, pca->ruleset, 0,
pca->r_action, pca->r_num, pca->r_last, 1, 1);
@@ -1804,23 +1820,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- case DIOCRWRAPTABLE: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- error = pfr_wrap_table(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_exists ? &io->pfrio_exists : NULL,
- io->pfrio_flags);
- break;
- }
-
- case DIOCRUNWRTABLE: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- error = pfr_unwrap_table(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_flags);
- break;
- }
-
default:
error = ENODEV;
break;
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index e24b4bf680a..70c9cb0e627 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.49 2003/01/05 22:14:23 dhartmei Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.50 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -811,15 +811,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != h->ip_p)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (!PF_AZERO(&r->src.addr.v.a.mask, AF_INET) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, (struct pf_addr *)&h->ip_src.s_addr,
- AF_INET))
+ else if (PF_MISMATCHAW(&r->src.addr,
+ (struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (!PF_AZERO(&r->dst.addr.v.a.mask, AF_INET) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, (struct pf_addr *)&h->ip_dst.s_addr,
- AF_INET))
+ else if (PF_MISMATCHAW(&r->dst.addr,
+ (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else
break;
@@ -1016,24 +1012,12 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (r->src.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->src, af))
- r = TAILQ_NEXT(r, entries);
- else if (r->src.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->src.addr.v.a.mask, af) &&
- !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, pd->src, af))
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (r->dst.addr.type == PF_ADDR_NOROUTE &&
- pf_routable(pd->dst, af))
- r = TAILQ_NEXT(r, entries);
- else if (!r->dst.addr.type != PF_ADDR_NOROUTE &&
- !PF_AZERO(&r->dst.addr.v.a.mask, af) &&
- !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr,
- &r->dst.addr.v.a.mask, pd->dst, af))
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index 0775961c572..b363bebeaca 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.14 2003/01/06 14:19:40 cedric Exp $ */
+/* $OpenBSD: pf_table.c,v 1.15 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -42,8 +42,6 @@
#include <netinet/ip_ipsp.h>
#include <net/pfvar.h>
-#include <crypto/sha1.h>
-
#define ACCEPT_FLAGS(oklist) \
do { \
if ((flags & ~(oklist)) & \
@@ -89,9 +87,6 @@ struct pfr_walktree {
#define pfrw_workq pfrw_1.pfrw1_workq
#define pfrw_cnt pfrw_free
-#define PFR_HASH_BUCKETS 1024
-#define PFR_HASH_BUCKET(hash) ((hash).pfrh_int32[1] & (PFR_HASH_BUCKETS-1))
-
#define senderr(e) do { rv = (e); goto _bad; } while (0)
struct pool pfr_ktable_pl;
@@ -130,18 +125,11 @@ void pfr_destroy_ktable(struct pfr_ktable *);
void pfr_destroy_ktables(struct pfr_ktableworkq *);
int pfr_ktable_compare(struct pfr_ktable *,
struct pfr_ktable *);
-struct pfr_ktable *pfr_lookup_hash(union pfr_hash *);
struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
-int pfr_match_addr(struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t);
-void pfr_update_stats(struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t, u_int64_t, int, int,
- int);
RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
-struct pfr_ktablehashq pfr_ktablehash[PFR_HASH_BUCKETS];
struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
@@ -169,7 +157,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
rv = pfr_enqueue_addrs(kt, &workq, ndel);
if (rv)
@@ -202,7 +190,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
tmpkt = pfr_create_ktable(&pfr_nulltable, 0);
if (tmpkt == NULL)
@@ -265,7 +253,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
bzero(&w, sizeof(w));
@@ -328,7 +316,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
tmpkt = pfr_create_ktable(&pfr_nulltable, 0);
if (tmpkt == NULL)
@@ -444,7 +432,7 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ACCEPT_FLAGS(PFR_FLAG_REPLACE);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
for (i = 0; i < size; i++) {
@@ -479,7 +467,7 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
ACCEPT_FLAGS(0);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
if (kt->pfrkt_cnt > *size) {
*size = kt->pfrkt_cnt;
@@ -516,7 +504,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
if (kt->pfrkt_cnt > *size) {
*size = kt->pfrkt_cnt;
@@ -563,7 +551,7 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
kt = pfr_lookup_table(tbl);
- if (kt == NULL)
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
SLIST_INIT(&workq);
for (i = 0; i < size; i++) {
@@ -949,18 +937,20 @@ pfr_clr_tables(int *ndel, int flags)
int
pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
{
- struct pfr_ktableworkq workq;
+ struct pfr_ktableworkq workq, changeq;
struct pfr_ktable *p, *q, key;
int i, rv, s, xadd = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
SLIST_INIT(&workq);
+ SLIST_INIT(&changeq);
for (i = 0; i < size; i++) {
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
senderr(EFAULT);
if (key.pfrkt_name[PF_TABLE_NAME_SIZE-1])
senderr(EINVAL);
+ key.pfrkt_flags = PFR_TFLAG_ACTIVE+PFR_TFLAG_PERSIST;
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (p == NULL) {
p = pfr_create_ktable(&key.pfrkt_t, tzero);
@@ -969,19 +959,11 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
SLIST_FOREACH(q, &workq, pfrkt_workq) {
if (!strcmp(p->pfrkt_name, q->pfrkt_name))
goto _skip;
- if (!memcmp(&p->pfrkt_hash, &q->pfrkt_hash,
- sizeof(p->pfrkt_hash))) {
- printf("pfr_add_tables: "
- "sha collision\n");
- senderr(EEXIST);
- }
}
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- if (pfr_lookup_hash(&p->pfrkt_hash)) {
- printf("pfr_add_tables: sha collision\n");
- senderr(EEXIST);
- }
xadd++;
+ } else if (!(p->pfrkt_flags & PFR_TFLAG_PERSIST)) {
+ SLIST_INSERT_HEAD(&changeq, p, pfrkt_workq);
}
_skip:
}
@@ -989,6 +971,8 @@ _skip:
if (flags & PFR_FLAG_ATOMIC)
s = splsoftnet();
pfr_insert_ktables(&workq);
+ SLIST_FOREACH(p, &changeq, pfrkt_workq)
+ p->pfrkt_flags |= PFR_TFLAG_PERSIST;
if (flags & PFR_FLAG_ATOMIC)
splx(s);
} else
@@ -1004,22 +988,27 @@ _bad:
int
pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
{
- struct pfr_ktableworkq workq;
+ struct pfr_ktableworkq workq, changeq;
struct pfr_ktable *p, *q, key;
int i, s, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
SLIST_INIT(&workq);
+ SLIST_INIT(&changeq);
for (i = 0; i < size; i++) {
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
return (EFAULT);
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (p != NULL) {
- SLIST_FOREACH(q, &workq, pfrkt_workq)
+ struct pfr_ktableworkq *queue;
+
+ queue = (p->pfrkt_refcnt > 0) ? &changeq : &workq;
+ SLIST_FOREACH(q, queue, pfrkt_workq)
if (!strcmp(p->pfrkt_name, q->pfrkt_name))
goto _skip;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xdel++;
+ SLIST_INSERT_HEAD(queue, p, pfrkt_workq);
+ if (queue == &workq)
+ xdel++;
}
_skip:
}
@@ -1028,6 +1017,8 @@ _skip:
if (flags & PFR_FLAG_ATOMIC)
s = splsoftnet();
pfr_remove_ktables(&workq);
+ SLIST_FOREACH(p, &changeq, pfrkt_workq)
+ p->pfrkt_flags &= ~PFR_TFLAG_PERSIST;
if (flags & PFR_FLAG_ATOMIC)
splx(s);
}
@@ -1135,62 +1126,11 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
return (0);
}
-int
-pfr_wrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap,
- int *exists, int flags)
-{
- union pfr_hash hash;
- struct pf_addr_wrap w;
- SHA1_CTX sha1;
-
- ACCEPT_FLAGS(0);
- if (!*tbl->pfrt_name || tbl->pfrt_name[PF_TABLE_NAME_SIZE-1])
- return (EINVAL);
- SHA1Init(&sha1);
- SHA1Update(&sha1, tbl->pfrt_name, strlen(tbl->pfrt_name));
- SHA1Final(hash.pfrh_sha1, &sha1);
-
- bzero(&w, sizeof(w));
- bcopy(&hash, &w.v.a.addr, sizeof(w.v.a.addr));
- w.v.a.mask.addr32[0] = PF_TABLE_MASK;
- w.v.a.mask.addr32[1] = hash.pfrh_int32[4];
- if (copyout(&w, wrap, sizeof(*wrap)))
- return (EFAULT);
-
- if (exists != NULL)
- *exists = pfr_lookup_table(tbl) != NULL;
- return (0);
-}
-
-int
-pfr_unwrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, int flags)
-{
- union pfr_hash hash;
- struct pf_addr_wrap w;
- struct pfr_ktable *kt;
-
- ACCEPT_FLAGS(0);
- if (copyin(wrap, &w, sizeof(w)))
- return (EFAULT);
-
- if (w.v.a.mask.addr32[0] != PF_TABLE_MASK || w.v.a.mask.addr32[2] ||
- w.v.a.mask.addr32[3])
- return (EINVAL);
-
- bcopy(&w.v.a.addr, &hash, 16);
- hash.pfrh_int32[4] = w.v.a.mask.addr32[1];
- kt = pfr_lookup_hash(&hash);
- if (kt == NULL)
- return (ENOENT);
- *tbl = kt->pfrkt_t;
- return (0);
-}
-
void
pfr_insert_ktables(struct pfr_ktableworkq *workq)
{
struct pfr_ktable *p;
- int s, n = 0;
+ int n = 0;
/* insert into tree */
SLIST_FOREACH(p, workq, pfrkt_workq) {
@@ -1198,14 +1138,6 @@ pfr_insert_ktables(struct pfr_ktableworkq *workq)
n++;
}
pfr_ktable_cnt += n;
-
- SLIST_FOREACH(p, workq, pfrkt_workq) {
- s = splsoftnet();
- SLIST_INSERT_HEAD(pfr_ktablehash +
- PFR_HASH_BUCKET(p->pfrkt_hash),
- p, pfrkt_hashq);
- splx(s);
- }
}
void
@@ -1213,14 +1145,7 @@ pfr_remove_ktables(struct pfr_ktableworkq *workq)
{
struct pfr_kentryworkq addrq;
struct pfr_ktable *p;
- int s, n = 0;
-
- SLIST_FOREACH(p, workq, pfrkt_workq) {
- s = splsoftnet();
- SLIST_REMOVE(pfr_ktablehash + PFR_HASH_BUCKET(p->pfrkt_hash),
- p, pfr_ktable, pfrkt_hashq);
- splx(s);
- }
+ int n = 0;
SLIST_FOREACH(p, workq, pfrkt_workq) {
RB_REMOVE(pfr_ktablehead, &pfr_ktables, p);
@@ -1259,7 +1184,6 @@ struct pfr_ktable *
pfr_create_ktable(struct pfr_table *tbl, long tzero)
{
struct pfr_ktable *kt;
- SHA1_CTX sha1;
kt = pool_get(&pfr_ktable_pl, PR_NOWAIT);
if (kt == NULL)
@@ -1267,11 +1191,6 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero)
bzero(kt, sizeof(*kt));
kt->pfrkt_t = *tbl;
- /* compute secure hash */
- SHA1Init(&sha1);
- SHA1Update(&sha1, kt->pfrkt_name, strlen(kt->pfrkt_name));
- SHA1Final(kt->pfrkt_hash.pfrh_sha1, &sha1);
-
if (!rn_inithead((void **)&kt->pfrkt_ip4,
offsetof(struct sockaddr_in, sin_addr) * 8) ||
!rn_inithead((void **)&kt->pfrkt_ip6,
@@ -1314,17 +1233,6 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
}
struct pfr_ktable *
-pfr_lookup_hash(union pfr_hash *hash)
-{
- struct pfr_ktable *p;
-
- SLIST_FOREACH(p, pfr_ktablehash+PFR_HASH_BUCKET(*hash), pfrkt_hashq)
- if (!memcmp(p->pfrkt_hash.pfrh_sha1, hash->pfrh_sha1, 20))
- return (p);
- return (NULL);
-}
-
-struct pfr_ktable *
pfr_lookup_table(struct pfr_table *tbl)
{
/* struct pfr_ktable start like a struct pfr_table */
@@ -1338,26 +1246,18 @@ pfr_lookup_table(struct pfr_table *tbl)
* are different.
*/
int
-pfr_match_addr(struct pf_addr *a, struct pf_addr *m,
- struct pf_addr *b, sa_family_t af)
+pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
{
- union pfr_hash hash;
- struct pfr_ktable *kt;
struct pfr_kentry *ke = NULL;
int match;
- bcopy(a, &hash, 16);
- hash.pfrh_int32[4] = m->addr32[1];
- kt = pfr_lookup_hash(&hash);
- if (kt == NULL)
- return (0);
switch (af) {
case AF_INET:
- pfr_sin.sin_addr.s_addr = b->addr32[0];
+ pfr_sin.sin_addr.s_addr = a->addr32[0];
ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
break;
case AF_INET6:
- bcopy(&b, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
+ bcopy(&a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
break;
}
@@ -1370,27 +1270,18 @@ pfr_match_addr(struct pf_addr *a, struct pf_addr *m,
}
void
-pfr_update_stats(struct pf_addr *a, struct pf_addr *m,
- struct pf_addr *b, sa_family_t af, u_int64_t len,
- int dir_out, int op_pass, int notrule)
+pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
+ u_int64_t len, int dir_out, int op_pass, int notrule)
{
- union pfr_hash hash;
- struct pfr_ktable *kt;
struct pfr_kentry *ke = NULL;
- bcopy(a, &hash, 16);
- hash.pfrh_int32[4] = m->addr32[1];
- kt = pfr_lookup_hash(&hash);
- if (kt == NULL)
- return;
-
switch (af) {
case AF_INET:
- pfr_sin.sin_addr.s_addr = b->addr32[0];
+ pfr_sin.sin_addr.s_addr = a->addr32[0];
ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
break;
case AF_INET6:
- bcopy(&b, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
+ bcopy(&a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
break;
}
@@ -1406,3 +1297,45 @@ pfr_update_stats(struct pf_addr *a, struct pf_addr *m,
ke->pfrke_bytes[dir_out][op_pass] += len;
}
}
+
+struct pfr_ktable *
+pfr_attach_table(char *name)
+{
+ struct pfr_ktable *p, key;
+ struct pfr_ktableworkq workq;
+
+ bzero(&key, sizeof(key));
+ strlcpy(key.pfrkt_name, name, sizeof(key.pfrkt_name));
+ key.pfrkt_flags = PFR_TFLAG_ACTIVE;
+ p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (p == NULL) {
+ p = pfr_create_ktable(&key.pfrkt_t, time.tv_sec);
+ if (p == NULL)
+ return NULL;
+ SLIST_INIT(&workq);
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ pfr_insert_ktables(&workq);
+ }
+ p->pfrkt_refcnt++;
+ return p;
+}
+
+void
+pfr_detach_table(struct pfr_ktable *kt)
+{
+ struct pfr_ktableworkq workq;
+
+ if (kt->pfrkt_refcnt <= 0)
+ printf("pfr_detach_table, refcount = %d\n",
+ kt->pfrkt_refcnt);
+ else {
+ kt->pfrkt_refcnt--;
+ if (kt->pfrkt_refcnt == 0 &&
+ !(kt->pfrkt_flags & PFR_TFLAG_PERSIST)) {
+ kt->pfrkt_flags &= ~PFR_TFLAG_ACTIVE;
+ SLIST_INIT(&workq);
+ SLIST_INSERT_HEAD(&workq, kt, pfrkt_workq);
+ pfr_remove_ktables(&workq);
+ }
+ }
+}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 29910674357..2ce24b2abba 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.128 2003/01/06 14:19:40 cedric Exp $ */
+/* $OpenBSD: pfvar.h,v 1.129 2003/01/07 00:21:07 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -244,6 +244,24 @@ struct pf_addr_dyn {
#endif /* PF_INET6_ONLY */
#endif /* PF_INET_INET6 */
+#define PF_MISMATCHAW(aw, x, af, not) \
+ ( \
+ (((aw)->type == PF_ADDR_NOROUTE && \
+ pf_routable((x), (af))) || \
+ ((aw)->type == PF_ADDR_TABLE && \
+ !pfr_match_addr((aw)->p.tbl, (x), (af))) || \
+ ((aw)->type == PF_ADDR_DYNIFTL && \
+ ((aw)->p.dyn->undefined || \
+ (!PF_AZERO(&(aw)->v.a.mask, (af)) && \
+ !PF_MATCHA(0, &(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af))))) || \
+ ((aw)->type == PF_ADDR_ADDRMASK && \
+ !PF_AZERO(&(aw)->v.a.mask, (af)) && \
+ !PF_MATCHA(0, &(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af)))) != \
+ (not) \
+ )
+
struct pf_rule_uid {
uid_t uid[2];
u_int8_t op;
@@ -452,10 +470,15 @@ struct pf_anchor {
TAILQ_HEAD(pf_anchorqueue, pf_anchor);
-#define PF_TABLE_MASK 0xCAFEBABE
+#define PFR_TFLAG_PERSIST 0x00000001
+#define PFR_TFLAG_CONST 0x00000002
+#define PFR_TFLAG_ACTIVE 0x00000004
+#define PFR_TFLAG_INACTIVE 0x00000008
+#define PFR_TFLAG_ALLMASK 0x0000000F
struct pfr_table {
char pfrt_name[PF_TABLE_NAME_SIZE];
+ u_int32_t pfrt_flags;
};
enum { PFR_FB_NONE, PFR_FB_MATCH, PFR_FB_ADDED, PFR_FB_DELETED,
@@ -494,13 +517,10 @@ struct pfr_tstats {
u_int64_t pfrts_nomatch;
long pfrts_tzero;
int pfrts_cnt;
+ int pfrts_refcnt;
};
#define pfrts_name pfrts_t.pfrt_name
-
-union pfr_hash {
- char pfrh_sha1[20];
- u_int32_t pfrh_int32[5];
-};
+#define pfrts_flags pfrts_t.pfrt_flags
SLIST_HEAD(pfr_kentryworkq, pfr_kentry);
struct pfr_kentry {
@@ -516,21 +536,20 @@ struct pfr_kentry {
u_int8_t pfrke_mark;
};
-SLIST_HEAD(pfr_ktablehashq, pfr_ktable);
SLIST_HEAD(pfr_ktableworkq, pfr_ktable);
RB_HEAD(pfr_ktablehead, pfr_ktable);
struct pfr_ktable {
struct pfr_tstats pfrkt_ts;
- union pfr_hash pfrkt_hash;
RB_ENTRY(pfr_ktable) pfrkt_tree;
- SLIST_ENTRY(pfr_ktable) pfrkt_hashq;
SLIST_ENTRY(pfr_ktable) pfrkt_workq;
struct radix_node_head *pfrkt_ip4;
struct radix_node_head *pfrkt_ip6;
};
#define pfrkt_t pfrkt_ts.pfrts_t
#define pfrkt_name pfrkt_t.pfrt_name
+#define pfrkt_flags pfrkt_t.pfrt_flags
#define pfrkt_cnt pfrkt_ts.pfrts_cnt
+#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt
#define pfrkt_packets pfrkt_ts.pfrts_packets
#define pfrkt_bytes pfrkt_ts.pfrts_bytes
#define pfrkt_match pfrkt_ts.pfrts_match
@@ -896,8 +915,6 @@ struct pfioc_table {
#define DIOCRGETASTATS _IOWR('D', 71, struct pfioc_table)
#define DIOCRCLRASTATS _IOWR('D', 72, struct pfioc_table)
#define DIOCRTSTADDRS _IOWR('D', 73, struct pfioc_table)
-#define DIOCRWRAPTABLE _IOWR('D', 74, struct pfioc_table)
-#define DIOCRUNWRTABLE _IOWR('D', 75, struct pfioc_table)
#ifdef _KERNEL
@@ -921,12 +938,14 @@ extern struct pf_altqqueue *pf_altqs_active;
extern struct pf_altqqueue *pf_altqs_inactive;
extern struct pf_poolqueue *pf_pools_active;
extern struct pf_poolqueue *pf_pools_inactive;
-extern void pf_dynaddr_remove(struct pf_addr_wrap *);
+extern int pf_tbladdr_setup(struct pf_addr_wrap *);
+extern void pf_tbladdr_remove(struct pf_addr_wrap *);
extern int pf_dynaddr_setup(struct pf_addr_wrap *,
- u_int8_t);
+ sa_family_t);
+extern void pf_dynaddr_copyout(struct pf_addr_wrap *);
+extern void pf_dynaddr_remove(struct pf_addr_wrap *);
extern void pf_calc_skip_steps(struct pf_rulequeue *);
extern void pf_update_anchor_rules(void);
-extern void pf_dynaddr_copyout(struct pf_addr_wrap *);
extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl;
extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
extern void pf_purge_timeout(void *);
@@ -963,10 +982,12 @@ int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *);
void pf_purge_expired_fragments(void);
int pf_routable(struct pf_addr *addr, sa_family_t af);
void pfr_initialize(void);
-int pfr_match_addr(struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t);
-void pfr_update_stats(struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t, u_int64_t, int, int, int);
+int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
+void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
+ u_int64_t, int, int, int);
+struct pfr_ktable *
+ pfr_attach_table(char *);
+void pfr_detach_table(struct pfr_ktable *);
int pfr_clr_tables(int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);
int pfr_del_tables(struct pfr_table *, int, int *, int);