Resolve conflicts (pf from OpenBSD 3.7, kernel part).

This commit is contained in:
peter 2005-07-01 12:37:34 +00:00
parent 9493e4bf43
commit 9710741485
6 changed files with 856 additions and 176 deletions

600
sys/dist/pf/net/pf.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_if.c,v 1.8 2004/12/04 14:26:01 peter Exp $ */
/* $OpenBSD: pf_if.c,v 1.20 2004/08/15 15:31:46 henning Exp $ */
/* $NetBSD: pf_if.c,v 1.9 2005/07/01 12:37:35 peter Exp $ */
/* $OpenBSD: pf_if.c,v 1.23 2004/12/22 17:17:55 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -386,11 +386,14 @@ void
pfi_dynaddr_update(void *p)
{
struct pfi_dynaddr *dyn = (struct pfi_dynaddr *)p;
struct pfi_kif *kif = dyn->pfid_kif;
struct pfr_ktable *kt = dyn->pfid_kt;
struct pfi_kif *kif;
struct pfr_ktable *kt;
if (dyn == NULL || kif == NULL || kt == NULL)
if (dyn == NULL || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL)
panic("pfi_dynaddr_update");
kif = dyn->pfid_kif;
kt = dyn->pfid_kt;
if (kt->pfrkt_larg != pfi_update) {
/* this table needs to be brought up-to-date */
pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
@ -723,8 +726,8 @@ pfi_clr_istats(const char *name, int *nzero, int flags)
int n = 0, s;
long tzero = time_second;
s = splsoftnet();
ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
s = splsoftnet();
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
if (pfi_skip_if(name, p, flags))
continue;
@ -739,6 +742,44 @@ pfi_clr_istats(const char *name, int *nzero, int flags)
return (0);
}
int
pfi_set_flags(const char *name, int flags)
{
struct pfi_kif *p;
int s;
if (flags & ~PFI_IFLAG_SETABLE_MASK)
return (EINVAL);
s = splsoftnet();
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
if (pfi_skip_if(name, p, PFI_FLAG_GROUP|PFI_FLAG_INSTANCE))
continue;
p->pfik_flags |= flags;
}
splx(s);
return (0);
}
int
pfi_clear_flags(const char *name, int flags)
{
struct pfi_kif *p;
int s;
if (flags & ~PFI_IFLAG_SETABLE_MASK)
return (EINVAL);
s = splsoftnet();
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
if (pfi_skip_if(name, p, PFI_FLAG_GROUP|PFI_FLAG_INSTANCE))
continue;
p->pfik_flags &= ~flags;
}
splx(s);
return (0);
}
int
pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
{

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_ioctl.c,v 1.16 2005/03/15 18:08:59 peter Exp $ */
/* $OpenBSD: pf_ioctl.c,v 1.130.2.1 2004/12/19 19:01:50 brad Exp $ */
/* $NetBSD: pf_ioctl.c,v 1.17 2005/07/01 12:37:35 peter Exp $ */
/* $OpenBSD: pf_ioctl.c,v 1.139 2005/03/03 07:13:39 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -160,6 +160,9 @@ TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
static u_int16_t tagname2tag(struct pf_tags *, char *);
static void tag2tagname(struct pf_tags *, u_int16_t, char *);
static void tag_unref(struct pf_tags *, u_int16_t);
int pf_rtlabel_add(struct pf_addr_wrap *);
void pf_rtlabel_remove(struct pf_addr_wrap *);
void pf_rtlabel_copyout(struct pf_addr_wrap *);
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
@ -205,24 +208,24 @@ pfattach(int num)
pf_default_rule.nr = -1;
/* initialize default timeouts */
timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */
timeout[PFTM_TCP_OPENING] = 30; /* No response yet */
timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */
timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */
timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */
timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */
timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */
timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */
timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */
timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */
timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */
timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */
timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */
timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */
timeout[PFTM_FRAG] = 30; /* Fragment expire */
timeout[PFTM_INTERVAL] = 10; /* Expire interval */
timeout[PFTM_SRC_NODE] = 0; /* Source tracking */
timeout[PFTM_TS_DIFF] = 30; /* Allowed TS diff */
timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
#ifdef __OpenBSD__
timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to);
@ -384,6 +387,7 @@ pf_get_ruleset_number(u_int8_t action)
{
switch (action) {
case PF_SCRUB:
case PF_NOSCRUB:
return (PF_RULESET_SCRUB);
break;
case PF_PASS:
@ -702,6 +706,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
*/
pf_tbladdr_remove(&rule->src.addr);
pf_tbladdr_remove(&rule->dst.addr);
if (rule->overload_tbl)
pfr_detach_table(rule->overload_tbl);
}
TAILQ_REMOVE(rulequeue, rule, entries);
rule->entries.tqe_prev = NULL;
@ -718,11 +724,15 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
pf_qid_unref(rule->pqid);
pf_qid_unref(rule->qid);
#endif
pf_rtlabel_remove(&rule->src.addr);
pf_rtlabel_remove(&rule->dst.addr);
pfi_dynaddr_remove(&rule->src.addr);
pfi_dynaddr_remove(&rule->dst.addr);
if (rulequeue == NULL) {
pf_tbladdr_remove(&rule->src.addr);
pf_tbladdr_remove(&rule->dst.addr);
if (rule->overload_tbl)
pfr_detach_table(rule->overload_tbl);
}
pfi_detach_rule(rule->kif);
pf_anchor_remove(rule);
@ -819,12 +829,61 @@ pf_tag2tagname(u_int16_t tagid, char *p)
return (tag2tagname(&pf_tags, tagid, p));
}
void
pf_tag_ref(u_int16_t tag)
{
struct pf_tagname *t;
TAILQ_FOREACH(t, &pf_tags, entries)
if (t->tag == tag)
break;
if (t != NULL)
t->ref++;
}
void
pf_tag_unref(u_int16_t tag)
{
return (tag_unref(&pf_tags, tag));
}
int
pf_rtlabel_add(struct pf_addr_wrap *a)
{
#ifdef __OpenBSD__
if (a->type == PF_ADDR_RTLABEL &&
(a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
return (-1);
#endif
return (0);
}
void
pf_rtlabel_remove(struct pf_addr_wrap *a)
{
#ifdef __OpenBSD__
if (a->type == PF_ADDR_RTLABEL)
rtlabel_unref(a->v.rtlabel);
#endif
}
void
pf_rtlabel_copyout(struct pf_addr_wrap *a)
{
#ifdef __OpenBSD__
const char *name;
if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
strlcpy(a->v.rtlabelname, "?",
sizeof(a->v.rtlabelname));
else
strlcpy(a->v.rtlabelname, name,
sizeof(a->v.rtlabelname));
}
#endif
}
#ifdef ALTQ
u_int32_t
pf_qname2qid(char *qname)
@ -1115,6 +1174,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCCLRSRCNODES:
case DIOCIGETIFACES:
case DIOCICLRISTATS:
case DIOCSETIFFLAG:
case DIOCCLRIFFLAG:
break;
case DIOCRCLRTABLES:
case DIOCRADDTABLES:
@ -1301,6 +1362,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EBUSY;
if (rule->rt && !rule->direction)
error = EINVAL;
if (pf_rtlabel_add(&rule->src.addr) ||
pf_rtlabel_add(&rule->dst.addr))
error = EBUSY;
if (pfi_dynaddr_setup(&rule->src.addr, rule->af))
error = EINVAL;
if (pfi_dynaddr_setup(&rule->dst.addr, rule->af))
@ -1315,6 +1379,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (pf_tbladdr_setup(ruleset, &pa->addr))
error = EINVAL;
if (rule->overload_tblname[0]) {
if ((rule->overload_tbl = pfr_attach_table(ruleset,
rule->overload_tblname)) == NULL)
error = EINVAL;
else
rule->overload_tbl->pfrkt_flags |=
PFR_TFLAG_ACTIVE;
}
pf_mv_pool(&pf_pabuf, &rule->rpool.list);
if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
(rule->action == PF_BINAT)) && rule->anchor == NULL) ||
@ -1397,6 +1470,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pfi_dynaddr_copyout(&pr->rule.dst.addr);
pf_tbladdr_copyout(&pr->rule.src.addr);
pf_tbladdr_copyout(&pr->rule.dst.addr);
pf_rtlabel_copyout(&pr->rule.src.addr);
pf_rtlabel_copyout(&pr->rule.dst.addr);
for (i = 0; i < PF_SKIP_COUNT; ++i)
if (rule->skip[i].ptr == NULL)
pr->rule.skip[i].nr = -1;
@ -1508,9 +1583,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if ((newrule->match_tag = pf_tagname2tag(
newrule->match_tagname)) == 0)
error = EBUSY;
if (newrule->rt && !newrule->direction)
error = EINVAL;
if (pf_rtlabel_add(&newrule->src.addr) ||
pf_rtlabel_add(&newrule->dst.addr))
error = EBUSY;
if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af))
error = EINVAL;
if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af))
@ -1522,6 +1599,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
error = EINVAL;
if (newrule->overload_tblname[0]) {
if ((newrule->overload_tbl = pfr_attach_table(
ruleset, newrule->overload_tblname)) ==
NULL)
error = EINVAL;
else
newrule->overload_tbl->pfrkt_flags |=
PFR_TFLAG_ACTIVE;
}
pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
if (((((newrule->action == PF_NAT) ||
(newrule->action == PF_RDR) ||
@ -2177,6 +2264,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
pfi_dynaddr_copyout(&pp->addr.addr);
pf_tbladdr_copyout(&pp->addr.addr);
pf_rtlabel_copyout(&pp->addr.addr);
break;
}
@ -2757,7 +2845,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
p = psn->psn_src_nodes;
RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
int secs = time_second;
int secs = time_second, diff;
if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
break;
@ -2770,6 +2858,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pstore.expire -= secs;
else
pstore.expire = 0;
/* adjust the connection rate estimate */
diff = secs - n->conn_rate.last;
if (diff >= n->conn_rate.seconds)
pstore.conn_rate.count = 0;
else
pstore.conn_rate.count -=
n->conn_rate.count * diff /
n->conn_rate.seconds;
error = copyout(&pstore, p, sizeof(*p));
if (error)
goto fail;
@ -2800,11 +2898,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCSETHOSTID: {
u_int32_t *hostid = (u_int32_t *)addr;
if (*hostid == 0) {
error = EINVAL;
goto fail;
}
pf_status.hostid = *hostid;
if (*hostid == 0)
pf_status.hostid = arc4random();
else
pf_status.hostid = *hostid;
break;
}
@ -2832,6 +2929,20 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
case DIOCSETIFFLAG: {
struct pfioc_iface *io = (struct pfioc_iface *)addr;
error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
break;
}
case DIOCCLRIFFLAG: {
struct pfioc_iface *io = (struct pfioc_iface *)addr;
error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
break;
}
default:
error = ENODEV;
break;

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_norm.c,v 1.8 2005/06/08 11:50:46 yamt Exp $ */
/* $OpenBSD: pf_norm.c,v 1.96 2004/07/17 00:17:27 frantzen Exp $ */
/* $NetBSD: pf_norm.c,v 1.9 2005/07/01 12:37:35 peter Exp $ */
/* $OpenBSD: pf_norm.c,v 1.97 2004/09/21 16:59:12 aaron Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@ -646,11 +646,7 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
* than this mbuf magic. For my next trick,
* I'll pull a rabbit out of my laptop.
*/
#ifdef __OpenBSD__
*m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
#else
*m0 = m_dup(m, 0, h->ip_hl << 2, M_NOWAIT);
#endif
if (*m0 == NULL)
goto no_mem;
KASSERT((*m0)->m_next == NULL);
@ -1272,7 +1268,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
}
}
if (rm == NULL)
if (rm == NULL || rm->action == PF_NOSCRUB)
return (PF_PASS);
else
r->packets++;

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_table.c,v 1.5 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pf_table.c,v 1.59 2004/07/08 23:17:38 mcbride Exp $ */
/* $NetBSD: pf_table.c,v 1.6 2005/07/01 12:37:35 peter Exp $ */
/* $OpenBSD: pf_table.c,v 1.62 2004/12/07 18:02:04 mcbride Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@ -132,6 +132,7 @@ struct pfr_walktree {
struct pool pfr_ktable_pl;
struct pool pfr_kentry_pl;
struct pool pfr_kentry_pl2;
struct sockaddr_in pfr_sin;
struct sockaddr_in6 pfr_sin6;
union sockaddr_union pfr_mask;
@ -145,7 +146,7 @@ void pfr_enqueue_addrs(struct pfr_ktable *,
void pfr_mark_addrs(struct pfr_ktable *);
struct pfr_kentry *pfr_lookup_addr(struct pfr_ktable *,
struct pfr_addr *, int);
struct pfr_kentry *pfr_create_kentry(struct pfr_addr *);
struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int);
void pfr_destroy_kentries(struct pfr_kentryworkq *);
void pfr_destroy_kentry(struct pfr_kentry *);
void pfr_insert_kentries(struct pfr_ktable *,
@ -162,6 +163,7 @@ int pfr_unroute_kentry(struct pfr_ktable *,
struct pfr_kentry *);
int pfr_walktree(struct radix_node *, void *);
int pfr_validate_table(struct pfr_table *, int, int);
int pfr_fix_anchor(char *);
void pfr_commit_ktable(struct pfr_ktable *, long);
void pfr_insert_ktables(struct pfr_ktableworkq *);
void pfr_insert_ktable(struct pfr_ktable *);
@ -197,6 +199,8 @@ pfr_initialize(void)
"pfrktable", &pool_allocator_oldnointr);
pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
"pfrkentry", &pool_allocator_oldnointr);
pool_init(&pfr_kentry_pl2, sizeof(struct pfr_kentry), 0, 0, 0,
"pfrkentry2", NULL);
pfr_sin.sin_len = sizeof(pfr_sin);
pfr_sin.sin_family = AF_INET;
@ -212,6 +216,7 @@ pfr_destroy(void)
{
pool_destroy(&pfr_ktable_pl);
pool_destroy(&pfr_kentry_pl);
pool_destroy(&pfr_kentry_pl2);
}
#endif
@ -288,7 +293,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ad.pfra_fback = PFR_FB_NONE;
}
if (p == NULL && q == NULL) {
p = pfr_create_kentry(&ad);
p = pfr_create_kentry(&ad, 0);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(tmpkt, p)) {
@ -465,7 +470,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ad.pfra_fback = PFR_FB_DUPLICATE;
goto _skip;
}
p = pfr_create_kentry(&ad);
p = pfr_create_kentry(&ad, 0);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(tmpkt, p)) {
@ -806,11 +811,14 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
}
struct pfr_kentry *
pfr_create_kentry(struct pfr_addr *ad)
pfr_create_kentry(struct pfr_addr *ad, int intr)
{
struct pfr_kentry *ke;
ke = pool_get(&pfr_kentry_pl, PR_NOWAIT);
if (intr)
ke = pool_get(&pfr_kentry_pl2, PR_NOWAIT);
else
ke = pool_get(&pfr_kentry_pl, PR_NOWAIT);
if (ke == NULL)
return (NULL);
bzero(ke, sizeof(*ke));
@ -822,6 +830,7 @@ pfr_create_kentry(struct pfr_addr *ad)
ke->pfrke_af = ad->pfra_af;
ke->pfrke_net = ad->pfra_net;
ke->pfrke_not = ad->pfra_not;
ke->pfrke_intrpool = intr;
return (ke);
}
@ -839,7 +848,10 @@ pfr_destroy_kentries(struct pfr_kentryworkq *workq)
void
pfr_destroy_kentry(struct pfr_kentry *ke)
{
pool_put(&pfr_kentry_pl, ke);
if (ke->pfrke_intrpool)
pool_put(&pfr_kentry_pl2, ke);
else
pool_put(&pfr_kentry_pl, ke);
}
void
@ -862,6 +874,29 @@ pfr_insert_kentries(struct pfr_ktable *kt,
kt->pfrkt_cnt += n;
}
int
pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
{
struct pfr_kentry *p;
int rv;
p = pfr_lookup_addr(kt, ad, 1);
if (p != NULL)
return (0);
p = pfr_create_kentry(ad, 1);
if (p == NULL)
return (EINVAL);
rv = pfr_route_kentry(kt, p);
if (rv)
return (rv);
p->pfrke_tzero = tzero;
kt->pfrkt_cnt++;
return (0);
}
void
pfr_remove_kentries(struct pfr_ktable *kt,
struct pfr_kentryworkq *workq)
@ -1107,6 +1142,8 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
int s = 0, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ALLRSETS);
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
if (pfr_table_count(filter, flags) < 0)
return (ENOENT);
@ -1262,6 +1299,8 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
int n, nn;
ACCEPT_FLAGS(PFR_FLAG_ALLRSETS);
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
n = nn = pfr_table_count(filter, flags);
if (n < 0)
return (ENOENT);
@ -1296,6 +1335,8 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS);
/* XXX PFR_FLAG_CLSTATS disabled */
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
n = nn = pfr_table_count(filter, flags);
if (n < 0)
return (ENOENT);
@ -1518,7 +1559,7 @@ _skip:
senderr(EINVAL);
if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
continue;
p = pfr_create_kentry(&ad);
p = pfr_create_kentry(&ad, 0);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(shadow, p)) {
@ -1705,11 +1746,42 @@ pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
for (i = strlen(tbl->pfrt_name); i < PF_TABLE_NAME_SIZE; i++)
if (tbl->pfrt_name[i])
return (-1);
if (pfr_fix_anchor(tbl->pfrt_anchor))
return (-1);
if (tbl->pfrt_flags & ~allowedflags)
return (-1);
return (0);
}
/*
* Rewrite anchors referenced by tables to remove slashes
* and check for validity.
*/
int
pfr_fix_anchor(char *anchor)
{
size_t siz = MAXPATHLEN;
int i;
if (anchor[0] == '/') {
char *path;
int off;
path = anchor;
off = 1;
while (*++path == '/')
off++;
bcopy(path, anchor, siz - off);
memset(anchor + siz - off, 0, off);
}
if (anchor[siz - 1])
return (-1);
for (i = strlen(anchor); i < siz; i++)
if (anchor[i])
return (-1);
return (0);
}
int
pfr_table_count(struct pfr_table *filter, int flags)
{

View File

@ -1,5 +1,5 @@
/* $NetBSD: pfvar.h,v 1.8 2004/12/04 14:21:23 peter Exp $ */
/* $OpenBSD: pfvar.h,v 1.202 2004/07/12 00:50:22 itojun Exp $ */
/* $NetBSD: pfvar.h,v 1.9 2005/07/01 12:37:35 peter Exp $ */
/* $OpenBSD: pfvar.h,v 1.213 2005/03/03 07:13:39 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -41,6 +41,7 @@
#include <net/radix.h>
#ifdef __OpenBSD__
#include <net/route.h>
#include <netinet/ip_ipsp.h>
#endif
#include <netinet/tcp_fsm.h>
@ -60,7 +61,7 @@ struct ip;
enum { PF_INOUT, PF_IN, PF_OUT };
enum { PF_LAN_EXT, PF_EXT_GWY, PF_ID };
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NAT, PF_NONAT,
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP };
enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
PF_RULESET_BINAT, PF_RULESET_RDR, PF_RULESET_MAX };
@ -82,13 +83,34 @@ enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNTIL_PACKET };
/* PFTM default values */
#define PFTM_TCP_FIRST_PACKET_VAL 120 /* First TCP packet */
#define PFTM_TCP_OPENING_VAL 30 /* No response yet */
#define PFTM_TCP_ESTABLISHED_VAL 24*60*60/* Established */
#define PFTM_TCP_CLOSING_VAL 15 * 60 /* Half closed */
#define PFTM_TCP_FIN_WAIT_VAL 45 /* Got both FINs */
#define PFTM_TCP_CLOSED_VAL 90 /* Got a RST */
#define PFTM_UDP_FIRST_PACKET_VAL 60 /* First UDP packet */
#define PFTM_UDP_SINGLE_VAL 30 /* Unidirectional */
#define PFTM_UDP_MULTIPLE_VAL 60 /* Bidirectional */
#define PFTM_ICMP_FIRST_PACKET_VAL 20 /* First ICMP packet */
#define PFTM_ICMP_ERROR_REPLY_VAL 10 /* Got error response */
#define PFTM_OTHER_FIRST_PACKET_VAL 60 /* First packet */
#define PFTM_OTHER_SINGLE_VAL 30 /* Unidirectional */
#define PFTM_OTHER_MULTIPLE_VAL 60 /* Bidirectional */
#define PFTM_FRAG_VAL 30 /* Fragment expire */
#define PFTM_INTERVAL_VAL 10 /* Expire interval */
#define PFTM_SRC_NODE_VAL 0 /* Source tracking */
#define PFTM_TS_DIFF_VAL 30 /* Allowed TS diff */
enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_MAX };
#define PF_POOL_IDMASK 0x0f
enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
PF_ADDR_TABLE };
PF_ADDR_TABLE, PF_ADDR_RTLABEL };
#define PF_POOL_TYPEMASK 0x0f
#define PF_POOL_STICKYADDR 0x20
#define PF_WSCALE_FLAG 0x80
@ -117,6 +139,10 @@ struct pf_addr {
#define PFI_AFLAG_MODEMASK 0x07
#define PFI_AFLAG_NOALIAS 0x08
#ifndef RTLABEL_LEN
#define RTLABEL_LEN 32
#endif
struct pf_addr_wrap {
union {
struct {
@ -125,6 +151,8 @@ struct pf_addr_wrap {
} a;
char ifname[IFNAMSIZ];
char tblname[PF_TABLE_NAME_SIZE];
char rtlabelname[RTLABEL_LEN];
u_int32_t rtlabel;
} v;
union {
struct pfi_dynaddr *dyn;
@ -299,6 +327,8 @@ struct pfi_dynaddr {
( \
(((aw)->type == PF_ADDR_NOROUTE && \
pf_routable((x), (af))) || \
((aw)->type == PF_ADDR_RTLABEL && \
!pf_rtlabel_match((x), (af), (aw))) || \
((aw)->type == PF_ADDR_TABLE && \
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
((aw)->type == PF_ADDR_DYNIFTL && \
@ -490,6 +520,8 @@ struct pf_rule {
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
char overload_tblname[PF_TABLE_NAME_SIZE];
TAILQ_ENTRY(pf_rule) entries;
struct pf_pool rpool;
@ -499,6 +531,7 @@ struct pf_rule {
struct pfi_kif *kif;
struct pf_anchor *anchor;
struct pfr_ktable *overload_tbl;
pf_osfp_t os_fingerprint;
@ -508,6 +541,11 @@ struct pf_rule {
u_int32_t src_nodes;
u_int32_t max_src_nodes;
u_int32_t max_src_states;
u_int32_t max_src_conn;
struct {
u_int32_t limit;
u_int32_t seconds;
} max_src_conn_rate;
u_int32_t qid;
u_int32_t pqid;
u_int32_t rt_listid;
@ -549,6 +587,10 @@ struct pf_rule {
u_int8_t tos;
u_int8_t anchor_relative;
u_int8_t anchor_wildcard;
#define PF_FLUSH 0x01
#define PF_FLUSH_GLOBAL 0x02
u_int8_t flush;
};
/* rule flags */
@ -574,6 +616,16 @@ struct pf_rule {
#define PFSTATE_HIWAT 10000 /* default state table size */
struct pf_threshold {
u_int32_t limit;
#define PF_THRESHOLD_MULT 1000
#define PF_THRESHOLD_MAX 0xffffffff / PF_THRESHOLD_MULT
u_int32_t seconds;
u_int32_t count;
u_int32_t last;
};
struct pf_src_node {
RB_ENTRY(pf_src_node) entry;
struct pf_addr addr;
@ -583,6 +635,8 @@ struct pf_src_node {
u_int32_t bytes;
u_int32_t packets;
u_int32_t states;
u_int32_t conn;
struct pf_threshold conn_rate;
u_int32_t creation;
u_int32_t expire;
sa_family_t af;
@ -656,6 +710,7 @@ struct pf_state {
u_int32_t packets[2];
u_int32_t bytes[2];
u_int32_t creatorid;
u_int16_t tag;
sa_family_t af;
u_int8_t proto;
u_int8_t direction;
@ -665,6 +720,7 @@ struct pf_state {
u_int8_t sync_flags;
#define PFSTATE_NOSYNC 0x01
#define PFSTATE_FROMSYNC 0x02
#define PFSTATE_STALE 0x04
u_int8_t pad;
};
@ -776,6 +832,7 @@ struct pfr_kentry {
u_int8_t pfrke_net;
u_int8_t pfrke_not;
u_int8_t pfrke_mark;
u_int8_t pfrke_intrpool;
};
SLIST_HEAD(pfr_ktableworkq, pfr_ktable);
@ -861,6 +918,8 @@ struct pfi_kif {
#define PFI_IFLAG_CLONABLE 0x0010 /* clonable group */
#define PFI_IFLAG_DYNAMIC 0x0020 /* dynamic group */
#define PFI_IFLAG_ATTACHED 0x0040 /* interface attached */
#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
#define PFI_IFLAG_SETABLE_MASK 0x0100 /* setable via DIOC{SET,CLR}IFFLAG */
struct pf_pdesc {
u_int64_t tot_len; /* Make Mickey money */
@ -903,7 +962,15 @@ struct pf_pdesc {
#define PFRES_NORM 4 /* Dropping by normalizer */
#define PFRES_MEMORY 5 /* Dropped due to lacking mem */
#define PFRES_TS 6 /* Bad TCP Timestamp (RFC1323) */
#define PFRES_MAX 7 /* total+1 */
#define PFRES_CONGEST 7 /* Congestion (of ipintrq) */
#define PFRES_IPOPTIONS 8 /* IP option */
#define PFRES_PROTCKSUM 9 /* Protocol checksum invalid */
#define PFRES_BADSTATE 10 /* State mismatch */
#define PFRES_STATEINS 11 /* State insertion failure */
#define PFRES_MAXSTATES 12 /* State limit */
#define PFRES_SRCLIMIT 13 /* Source node/conn limit */
#define PFRES_SYNPROXY 14 /* SYN proxy */
#define PFRES_MAX 15 /* total+1 */
#define PFRES_NAMES { \
"match", \
@ -913,6 +980,35 @@ struct pf_pdesc {
"normalize", \
"memory", \
"bad-timestamp", \
"congestion", \
"ip-option", \
"proto-cksum", \
"state-mismatch", \
"state-insert", \
"state-limit", \
"src-limit", \
"synproxy", \
NULL \
}
/* Counters for other things we want to keep track of */
#define LCNT_STATES 0 /* states */
#define LCNT_SRCSTATES 1 /* max-src-states */
#define LCNT_SRCNODES 2 /* max-src-nodes */
#define LCNT_SRCCONN 3 /* max-src-conn */
#define LCNT_SRCCONNRATE 4 /* max-src-conn-rate */
#define LCNT_OVERLOAD_TABLE 5 /* entry added to overload table */
#define LCNT_OVERLOAD_FLUSH 6 /* state entries flushed */
#define LCNT_MAX 7 /* total+1 */
#define LCNT_NAMES { \
"max states per rule", \
"max-src-states", \
"max-src-nodes", \
"max-src-conn", \
"max-src-conn-rate", \
"overload table insertion", \
"overload flush states", \
NULL \
}
@ -970,6 +1066,7 @@ struct pf_pdesc {
struct pf_status {
u_int64_t counters[PFRES_MAX];
u_int64_t lcounters[LCNT_MAX]; /* limit counters */
u_int64_t fcounters[FCNT_MAX];
u_int64_t scounters[SCNT_MAX];
u_int64_t pcounters[2][2][3];
@ -1296,6 +1393,8 @@ struct pfioc_iface {
#define DIOCSETHOSTID _IOWR('D', 86, u_int32_t)
#define DIOCIGETIFACES _IOWR('D', 87, struct pfioc_iface)
#define DIOCICLRISTATS _IOWR('D', 88, struct pfioc_iface)
#define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface)
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
#ifdef _KERNEL
RB_HEAD(pf_src_tree, pf_src_node);
@ -1406,6 +1505,7 @@ u_int32_t
pf_state_expires(const struct pf_state *);
void pf_purge_expired_fragments(void);
int pf_routable(struct pf_addr *addr, sa_family_t af);
int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *);
void pfr_initialize(void);
#ifdef _LKM
void pfr_destroy(void);
@ -1427,6 +1527,7 @@ int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
int pfr_clr_tstats(struct pfr_table *, int, int *, int);
int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
int pfr_clr_addrs(struct pfr_table *, int *, int);
int pfr_insert_kentry(struct pfr_ktable *, struct pfr_addr *, long);
int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
int);
int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
@ -1465,6 +1566,8 @@ void pfi_dynaddr_remove(struct pf_addr_wrap *);
void pfi_fill_oldstatus(struct pf_status *);
int pfi_clr_istats(const char *, int *, int);
int pfi_get_ifaces(const char *, struct pfi_if *, int *, int);
int pfi_set_flags(const char *, int);
int pfi_clear_flags(const char *, int);
int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
sa_family_t);
@ -1472,6 +1575,7 @@ extern struct pfi_statehead pfi_statehead;
u_int16_t pf_tagname2tag(char *);
void pf_tag2tagname(u_int16_t, char *);
void pf_tag_ref(u_int16_t);
void pf_tag_unref(u_int16_t);
int pf_tag_packet(struct mbuf *, struct pf_tag *, int);
u_int32_t pf_qname2qid(char *);