summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2005-05-21 21:03:59 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2005-05-21 21:03:59 +0000
commit823a05ae47a745ef7ba8b8c768901bd1ab31a80e (patch)
treea6154d85d95e05e54cd5d62771771bc47a845866 /sys
parent1a239e77bd4b99fac7d032554a8f026108682215 (diff)
clean up and rework the interface absraction code big time, rip out multiple
useless layers of indirection and make the code way cleaner overall. this is just the start, more to come... worked very hard on by Ryan and me in Montreal last week, on the airplane to vancouver and yesterday here in calgary. it hurt. ok ryan theo
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c5
-rw-r--r--sys/net/if.h3
-rw-r--r--sys/net/if_pfsync.c16
-rw-r--r--sys/net/pf.c57
-rw-r--r--sys/net/pf_if.c599
-rw-r--r--sys/net/pf_ioctl.c44
-rw-r--r--sys/net/pf_norm.c11
-rw-r--r--sys/net/pfvar.h83
8 files changed, 307 insertions, 511 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 6c45564ab07..7f7d7afb32a 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.109 2005/05/09 08:08:47 mpf Exp $ */
+/* $OpenBSD: if.c,v 1.110 2005/05/21 21:03:57 henning Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -776,9 +776,6 @@ if_clone_attach(struct if_clone *ifc)
{
LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
if_cloners_count++;
-#if NPF > 0
- pfi_attach_clone(ifc);
-#endif
}
/*
diff --git a/sys/net/if.h b/sys/net/if.h
index ef402f7a1fb..89b1e843fff 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.65 2005/04/20 23:00:40 mpf Exp $ */
+/* $OpenBSD: if.h,v 1.66 2005/05/21 21:03:57 henning Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -181,6 +181,7 @@ struct ifnet { /* and the entries */
int if_pcount; /* number of promiscuous listeners */
caddr_t if_bpf; /* packet filter structure */
caddr_t if_bridge; /* bridge structure */
+ caddr_t if_pf_kif; /* pf interface abstraction */
union {
caddr_t carp_s; /* carp structure (used by !carp ifs) */
struct ifnet *carp_d; /* ptr to carpdev (used by carp ifs) */
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index d0f56d096a7..350172fad55 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.46 2005/02/20 15:58:38 mcbride Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.47 2005/05/21 21:03:57 henning Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -173,7 +173,7 @@ pfsync_insert_net_state(struct pfsync_state *sp)
return (EINVAL);
}
- kif = pfi_lookup_create(sp->ifname);
+ kif = pfi_kif_get(sp->ifname);
if (kif == NULL) {
if (pf_status.debug >= PF_DEBUG_MISC)
printf("pfsync_insert_net_state: "
@@ -191,7 +191,7 @@ pfsync_insert_net_state(struct pfsync_state *sp)
if (!r->max_states || r->states < r->max_states)
st = pool_get(&pf_state_pl, PR_NOWAIT);
if (st == NULL) {
- pfi_maybe_destroy(kif);
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
return (ENOMEM);
}
bzero(st, sizeof(*st));
@@ -227,7 +227,7 @@ pfsync_insert_net_state(struct pfsync_state *sp)
if (pf_insert_state(kif, st)) {
- pfi_maybe_destroy(kif);
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
/* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
r->states--;
pool_put(&pf_state_pl, st);
@@ -330,13 +330,9 @@ pfsync_input(struct mbuf *m, ...)
}
}
} else {
- kif = pfi_lookup_if(cp->ifname);
- if (kif == NULL) {
- if (pf_status.debug >= PF_DEBUG_MISC)
- printf("pfsync_input: PFSYNC_ACT_CLR "
- "bad interface: %s\n", cp->ifname);
+ if ((kif = pfi_kif_get(cp->ifname)) == NULL) {
splx(s);
- goto done;
+ return;
}
for (st = RB_MIN(pf_state_tree_lan_ext,
&kif->pfik_lan_ext); st; st = nexts) {
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 198adb419c8..86c220cd25e 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.488 2005/04/25 17:55:51 brad Exp $ */
+/* $OpenBSD: pf.c,v 1.489 2005/05/21 21:03:57 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -252,9 +252,8 @@ struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
(s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
(s)->lan.port != (s)->gwy.port
-#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \
- ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \
- (k)->pfik_parent->pfik_parent)
+#define BOUND_IFACE(r, k) \
+ ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
#define STATE_INC_COUNTERS(s) \
do { \
@@ -537,20 +536,20 @@ pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree)
switch (tree) {
case PF_LAN_EXT:
- for (; kif != NULL; kif = kif->pfik_parent) {
- s = RB_FIND(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext, key);
- if (s != NULL)
- return (s);
- }
+ if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
+ key)) != NULL)
+ return (s);
+ if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
+ key)) != NULL)
+ return (s);
return (NULL);
case PF_EXT_GWY:
- for (; kif != NULL; kif = kif->pfik_parent) {
- s = RB_FIND(pf_state_tree_ext_gwy,
- &kif->pfik_ext_gwy, key);
- if (s != NULL)
- return (s);
- }
+ if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
+ key)) != NULL)
+ return (s);
+ if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
+ key)) != NULL)
+ return (s);
return (NULL);
default:
panic("pf_find_state_recurse");
@@ -849,7 +848,7 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
pf_status.fcounters[FCNT_STATE_INSERT]++;
pf_status.states++;
- pfi_attach_state(kif);
+ pfi_kif_ref(kif, PFI_KIF_REF_STATE);
#if NPFSYNC
pfsync_insert_state(state);
#endif
@@ -990,7 +989,7 @@ pf_purge_expired_state(struct pf_state *cur)
if (--cur->anchor.ptr->states <= 0)
pf_rm_rule(NULL, cur->anchor.ptr);
pf_normalize_tcp_cleanup(cur);
- pfi_detach_state(cur->u.s.kif);
+ pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE);
TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
if (cur->tag)
pf_tag_unref(cur->tag);
@@ -2255,8 +2254,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
}
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -2737,8 +2735,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -3112,8 +3109,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -3440,8 +3436,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -3692,8 +3687,7 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -3902,8 +3896,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != direction)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -5708,7 +5701,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
ifp = ifp->if_carpdev;
- kif = pfi_index2kif[ifp->if_index];
+ kif = (struct pfi_kif *)ifp->if_pf_kif;
if (kif == NULL) {
DPFPRINTF(PF_DEBUG_URGENT,
("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
@@ -6027,7 +6020,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
ifp = ifp->if_carpdev;
- kif = pfi_index2kif[ifp->if_index];
+ kif = (struct pfi_kif *)ifp->if_pf_kif;
if (kif == NULL) {
DPFPRINTF(PF_DEBUG_URGENT,
("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
diff --git a/sys/net/pf_if.c b/sys/net/pf_if.c
index 4e03b185509..d74a65034b7 100644
--- a/sys/net/pf_if.c
+++ b/sys/net/pf_if.c
@@ -1,6 +1,8 @@
-/* $OpenBSD: pf_if.c,v 1.24 2005/04/21 13:34:45 pascoe Exp $ */
+/* $OpenBSD: pf_if.c,v 1.25 2005/05/21 21:03:57 henning Exp $ */
/*
+ * Copyright 2005 Henning Brauer <henning@openbsd.org>
+ * Copyright 2005 Ryan McBride <mcbride@openbsd.org>
* Copyright (c) 2001 Daniel Hartmeier
* Copyright (c) 2003 Cedric Berger
* All rights reserved.
@@ -55,40 +57,25 @@
#include <netinet/ip6.h>
#endif /* INET6 */
-#define ACCEPT_FLAGS(oklist) \
- do { \
- if ((flags & ~(oklist)) & \
- PFI_FLAG_ALLMASK) \
- return (EINVAL); \
- } while (0)
-
-#define senderr(e) do { rv = (e); goto _bad; } while (0)
-
-struct pfi_kif **pfi_index2kif;
-struct pfi_kif *pfi_self;
-int pfi_indexlim;
+struct pfi_kif *pfi_all = NULL;
struct pfi_ifhead pfi_ifs;
struct pfi_statehead pfi_statehead;
-int pfi_ifcnt;
struct pool pfi_addr_pl;
+struct pfi_ifhead pfi_ifs;
long pfi_update = 1;
struct pfr_addr *pfi_buffer;
int pfi_buffer_cnt;
int pfi_buffer_max;
void pfi_dynaddr_update(void *);
-void pfi_kifaddr_update(void *);
void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
int, int);
+void pfi_kifaddr_update(void *);
void pfi_instance_add(struct ifnet *, int, int);
void pfi_address_add(struct sockaddr *, int, int);
int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
-struct pfi_kif *pfi_if_create(const char *, struct pfi_kif *, int);
-void pfi_copy_group(char *, const char *, int);
-void pfi_newgroup(const char *, int);
-int pfi_skip_if(const char *, struct pfi_kif *, int);
+int pfi_skip_if(const char *, struct pfi_kif *);
int pfi_unmask(void *);
-void pfi_dohooks(struct pfi_kif *);
RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
@@ -99,7 +86,7 @@ RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
void
pfi_initialize(void)
{
- if (pfi_self != NULL) /* already initialized */
+ if (pfi_all != NULL) /* already initialized */
return;
TAILQ_INIT(&pfi_statehead);
@@ -108,176 +95,188 @@ pfi_initialize(void)
pfi_buffer_max = 64;
pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
PFI_MTYPE, M_WAITOK);
- pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP);
-}
-void
-pfi_attach_clone(struct if_clone *ifc)
-{
- pfi_initialize();
- pfi_newgroup(ifc->ifc_name, PFI_IFLAG_CLONABLE);
+ if ((pfi_all = pfi_kif_get("all")) == NULL)
+ panic("pfi_kif_get for pfi_all failed");
}
-void
-pfi_attach_ifnet(struct ifnet *ifp)
+struct pfi_kif *
+pfi_kif_get(char *kif_name)
{
- struct pfi_kif *p, *q, key;
- int s;
+ struct pfi_kif s, *kif;
- pfi_initialize();
- s = splsoftnet();
- pfi_update++;
- if (ifp->if_index >= pfi_indexlim) {
- /*
- * grow pfi_index2kif, similar to ifindex2ifnet code in if.c
- */
- size_t m, n, oldlim;
- struct pfi_kif **mp, **np;
-
- oldlim = pfi_indexlim;
- if (pfi_indexlim == 0)
- pfi_indexlim = 64;
- while (ifp->if_index >= pfi_indexlim)
- pfi_indexlim <<= 1;
-
- m = oldlim * sizeof(struct pfi_kif *);
- mp = pfi_index2kif;
- n = pfi_indexlim * sizeof(struct pfi_kif *);
- np = malloc(n, PFI_MTYPE, M_DONTWAIT);
- if (np == NULL)
- panic("pfi_attach_ifnet: "
- "cannot allocate translation table");
- bzero(np, n);
- if (mp != NULL)
- bcopy(mp, np, m);
- pfi_index2kif = np;
- if (mp != NULL)
- free(mp, PFI_MTYPE);
+ bzero(&s, sizeof(s));
+ strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
+ if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, &s)) != NULL)
+ return (kif);
+
+ /* create new one */
+ if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT)) == NULL)
+ return (NULL);
+
+ bzero(kif, sizeof(*kif));
+ strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
+ kif->pfik_tzero = time_second;
+
+ if ((kif->pfik_ah_head = malloc(sizeof(*kif->pfik_ah_head), PFI_MTYPE,
+ M_DONTWAIT)) == NULL) {
+ free(kif, PFI_MTYPE);
+ return (NULL);
}
- strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
- p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
- if (p == NULL) {
- /* add group */
- pfi_copy_group(key.pfik_name, ifp->if_xname,
- sizeof(key.pfik_name));
- q = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
- if (q == NULL)
- q = pfi_if_create(key.pfik_name, pfi_self, PFI_IFLAG_GROUP);
- if (q == NULL)
- panic("pfi_attach_ifnet: "
- "cannot allocate '%s' group", key.pfik_name);
-
- /* add interface */
- p = pfi_if_create(ifp->if_xname, q, PFI_IFLAG_INSTANCE);
- if (p == NULL)
- panic("pfi_attach_ifnet: "
- "cannot allocate '%s' interface", ifp->if_xname);
- } else
- q = p->pfik_parent;
- p->pfik_ifp = ifp;
- p->pfik_flags |= PFI_IFLAG_ATTACHED;
- p->pfik_ah_cookie =
- hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p);
- if (p->pfik_ah_cookie == NULL)
- panic("pfi_attach_ifnet: cannot allocate '%s' address hook",
- ifp->if_xname);
- pfi_index2kif[ifp->if_index] = p;
- pfi_dohooks(p);
- splx(s);
+ bzero(kif->pfik_ah_head, sizeof(*kif->pfik_ah_head));
+ TAILQ_INIT(kif->pfik_ah_head);
+
+ RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
+
+ return (kif);
}
void
-pfi_detach_ifnet(struct ifnet *ifp)
+pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
{
- struct pfi_kif *p, *q, key;
- int s;
-
- strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
-
- s = splsoftnet();
- pfi_update++;
- p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
- if (p == NULL) {
- printf("pfi_detach_ifnet: cannot find %s", ifp->if_xname);
- splx(s);
- return;
+ switch (what) {
+ case PFI_KIF_REF_RULE:
+ kif->pfik_rules++;
+ break;
+ case PFI_KIF_REF_STATE:
+ if (!kif->pfik_states++)
+ TAILQ_INSERT_TAIL(&pfi_statehead, kif, pfik_w_states);
+ break;
+ default:
+ panic("pfi_kif_ref with unknown type");
}
- hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie);
- q = p->pfik_parent;
- p->pfik_ifp = NULL;
- p->pfik_flags &= ~PFI_IFLAG_ATTACHED;
- pfi_index2kif[ifp->if_index] = NULL;
- pfi_dohooks(p);
- pfi_maybe_destroy(p);
- splx(s);
}
-struct pfi_kif *
-pfi_lookup_create(const char *name)
+void
+pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
{
- struct pfi_kif *p, *q, key;
- int s;
+ if (kif == NULL)
+ return;
- s = splsoftnet();
- p = pfi_lookup_if(name);
- if (p == NULL) {
- pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name));
- q = pfi_lookup_if(key.pfik_name);
- if (q == NULL) {
- pfi_newgroup(key.pfik_name, PFI_IFLAG_DYNAMIC);
- q = pfi_lookup_if(key.pfik_name);
+ switch (what) {
+ case PFI_KIF_REF_NONE:
+ break;
+ case PFI_KIF_REF_RULE:
+ if (kif->pfik_rules <= 0) {
+ printf("pfi_kif_unref: rules refcount <= 0\n");
+ return;
+ }
+ kif->pfik_rules--;
+ break;
+ case PFI_KIF_REF_STATE:
+ if (kif->pfik_states <= 0) {
+ printf("pfi_kif_unref: state refcount <= 0\n");
+ return;
}
- p = pfi_lookup_if(name);
- if (p == NULL && q != NULL)
- p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE);
+ if (!--kif->pfik_states)
+ TAILQ_REMOVE(&pfi_statehead, kif, pfik_w_states);
+ break;
+ default:
+ panic("pfi_kif_unref with unknown type");
}
- splx(s);
- return (p);
+
+ /* XXX check for ifgroups ptr too */
+ if (kif->pfik_ifp != NULL || kif == pfi_all)
+ return;
+
+ if (kif->pfik_rules || kif->pfik_states)
+ return;
+
+ RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
+ free(kif->pfik_ah_head, PFI_MTYPE);
+ free(kif, PFI_MTYPE);
}
-struct pfi_kif *
-pfi_attach_rule(const char *name)
+int
+pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
{
- struct pfi_kif *p;
+ if (rule_kif == NULL || rule_kif == packet_kif)
+ return (1);
+
+ /* XXX walk rule_kif's ifgroups and check for match */
- p = pfi_lookup_create(name);
- if (p != NULL)
- p->pfik_rules++;
- return (p);
+ return (0);
}
void
-pfi_detach_rule(struct pfi_kif *p)
+pfi_attach_ifnet(struct ifnet *ifp)
{
- if (p == NULL)
- return;
- if (p->pfik_rules > 0)
- p->pfik_rules--;
- else
- printf("pfi_detach_rule: reference count at 0\n");
- pfi_maybe_destroy(p);
+ struct pfi_kif *kif, key;
+ int s;
+
+ pfi_initialize();
+ s = splsoftnet();
+
+ strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
+ if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, &key)) == NULL)
+ if ((kif = pfi_kif_get(ifp->if_xname)) == NULL)
+ panic("pfi_kif_get failed");
+
+ kif->pfik_ifp = ifp;
+ ifp->if_pf_kif = (caddr_t)kif;
+
+ if ((kif->pfik_ah_cookie = hook_establish(ifp->if_addrhooks, 1,
+ pfi_kifaddr_update, kif)) == NULL)
+ panic("pfi_attach_ifnet: cannot allocate '%s' address hook",
+ ifp->if_xname);
+ dohooks(kif->pfik_ah_head, 0);
+
+ splx(s);
}
void
-pfi_attach_state(struct pfi_kif *p)
+pfi_detach_ifnet(struct ifnet *ifp)
{
- if (!p->pfik_states++)
- TAILQ_INSERT_TAIL(&pfi_statehead, p, pfik_w_states);
+ int s;
+ struct pfi_kif *kif;
+
+ if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL)
+ return;
+
+ s = splsoftnet();
+ hook_disestablish(ifp->if_addrhooks, kif->pfik_ah_cookie);
+ dohooks(kif->pfik_ah_head, 0);
+
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ kif->pfik_ifp = NULL;
+ ifp->if_pf_kif = NULL;
+ splx(s);
}
-void
-pfi_detach_state(struct pfi_kif *p)
+int
+pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
{
- if (p == NULL)
- return;
- if (p->pfik_states <= 0) {
- printf("pfi_detach_state: reference count <= 0\n");
- return;
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ switch (dyn->pfid_acnt4) {
+ case 0:
+ return (0);
+ case 1:
+ return (PF_MATCHA(0, &dyn->pfid_addr4,
+ &dyn->pfid_mask4, a, AF_INET));
+ default:
+ return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ switch (dyn->pfid_acnt6) {
+ case 0:
+ return (0);
+ case 1:
+ return (PF_MATCHA(0, &dyn->pfid_addr6,
+ &dyn->pfid_mask6, a, AF_INET6));
+ default:
+ return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
+ }
+ break;
+#endif /* INET6 */
+ default:
+ return (0);
}
- if (!--p->pfik_states)
- TAILQ_REMOVE(&pfi_statehead, p, pfik_w_states);
- pfi_maybe_destroy(p);
}
int
@@ -296,9 +295,12 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
bzero(dyn, sizeof(*dyn));
s = splsoftnet();
- dyn->pfid_kif = pfi_attach_rule(aw->v.ifname);
- if (dyn->pfid_kif == NULL)
- senderr(1);
+ dyn->pfid_kif = pfi_kif_get(aw->v.ifname);
+ if (dyn->pfid_kif == NULL) {
+ rv = 1;
+ goto _bad;
+ }
+ pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
if (af == AF_INET && dyn->pfid_net == 32)
@@ -316,20 +318,26 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
snprintf(tblname + strlen(tblname),
sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR);
- if (ruleset == NULL)
- senderr(1);
+ if (ruleset == NULL) {
+ rv = 1;
+ goto _bad;
+ }
dyn->pfid_kt = pfr_attach_table(ruleset, tblname);
- if (dyn->pfid_kt == NULL)
- senderr(1);
+ if (dyn->pfid_kt == NULL) {
+ rv = 1;
+ goto _bad;
+ }
dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
dyn->pfid_iflags = aw->iflags;
dyn->pfid_af = af;
dyn->pfid_hook_cookie = hook_establish(dyn->pfid_kif->pfik_ah_head, 1,
pfi_dynaddr_update, dyn);
- if (dyn->pfid_hook_cookie == NULL)
- senderr(1);
+ if (dyn->pfid_hook_cookie == NULL) {
+ rv = 1;
+ goto _bad;
+ }
aw->p.dyn = dyn;
pfi_dynaddr_update(aw->p.dyn);
@@ -342,7 +350,7 @@ _bad:
if (ruleset != NULL)
pf_remove_if_empty_ruleset(ruleset);
if (dyn->pfid_kif != NULL)
- pfi_detach_rule(dyn->pfid_kif);
+ pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
pool_put(&pfi_addr_pl, dyn);
splx(s);
return (rv);
@@ -360,6 +368,7 @@ pfi_dynaddr_update(void *p)
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);
@@ -375,21 +384,20 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
struct pfi_kif *p;
struct pfr_table t;
- if ((kif->pfik_flags & PFI_IFLAG_INSTANCE) && kif->pfik_ifp == NULL) {
+ if (kif->pfik_ifp == NULL) {
pfr_clr_addrs(&kt->pfrkt_t, NULL, 0);
return;
}
pfi_buffer_cnt = 0;
- if ((kif->pfik_flags & PFI_IFLAG_INSTANCE))
+
+ /* XXXXXX bugs bugs bugs ? */
+ if (kif->pfik_ifp != NULL)
pfi_instance_add(kif->pfik_ifp, net, flags);
- else if (strcmp(kif->pfik_name, "self")) {
- TAILQ_FOREACH(p, &kif->pfik_grouphead, pfik_instances)
- pfi_instance_add(p->pfik_ifp, net, flags);
- } else {
+ else
RB_FOREACH(p, pfi_ifhead, &pfi_ifs)
- if (p->pfik_flags & PFI_IFLAG_INSTANCE)
+ if (p->pfik_ifp != NULL)
pfi_instance_add(p->pfik_ifp, net, flags);
- }
+
t = kt->pfrkt_t;
t.pfrt_flags = 0;
if ((e = pfr_set_addrs(&t, pfi_buffer, pfi_buffer_cnt, &size2,
@@ -515,7 +523,7 @@ pfi_dynaddr_remove(struct pf_addr_wrap *aw)
s = splsoftnet();
hook_disestablish(aw->p.dyn->pfid_kif->pfik_ah_head,
aw->p.dyn->pfid_hook_cookie);
- pfi_detach_rule(aw->p.dyn->pfid_kif);
+ pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
aw->p.dyn->pfid_kif = NULL;
pfr_detach_table(aw->p.dyn->pfid_kt);
aw->p.dyn->pfid_kt = NULL;
@@ -539,8 +547,7 @@ pfi_kifaddr_update(void *v)
int s;
s = splsoftnet();
- pfi_update++;
- pfi_dohooks(v);
+ dohooks(((struct pfi_kif *)v)->pfik_ah_head, 0);
splx(s);
}
@@ -550,98 +557,6 @@ pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
}
-struct pfi_kif *
-pfi_if_create(const char *name, struct pfi_kif *q, int flags)
-{
- struct pfi_kif *p;
-
- p = malloc(sizeof(*p), PFI_MTYPE, M_DONTWAIT);
- if (p == NULL)
- return (NULL);
- bzero(p, sizeof(*p));
- p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE,
- M_DONTWAIT);
- if (p->pfik_ah_head == NULL) {
- free(p, PFI_MTYPE);
- return (NULL);
- }
- bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head));
- TAILQ_INIT(p->pfik_ah_head);
- TAILQ_INIT(&p->pfik_grouphead);
- strlcpy(p->pfik_name, name, sizeof(p->pfik_name));
- RB_INIT(&p->pfik_lan_ext);
- RB_INIT(&p->pfik_ext_gwy);
- p->pfik_flags = flags;
- p->pfik_parent = q;
- p->pfik_tzero = time_second;
-
- RB_INSERT(pfi_ifhead, &pfi_ifs, p);
- if (q != NULL) {
- q->pfik_addcnt++;
- TAILQ_INSERT_TAIL(&q->pfik_grouphead, p, pfik_instances);
- }
- pfi_ifcnt++;
- return (p);
-}
-
-int
-pfi_maybe_destroy(struct pfi_kif *p)
-{
- int i, j, k, s;
- struct pfi_kif *q = p->pfik_parent;
-
- if ((p->pfik_flags & (PFI_IFLAG_ATTACHED | PFI_IFLAG_GROUP)) ||
- p->pfik_rules > 0 || p->pfik_states > 0)
- return (0);
-
- s = splsoftnet();
- if (q != NULL) {
- for (i = 0; i < 2; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++) {
- q->pfik_bytes[i][j][k] +=
- p->pfik_bytes[i][j][k];
- q->pfik_packets[i][j][k] +=
- p->pfik_packets[i][j][k];
- }
- q->pfik_delcnt++;
- TAILQ_REMOVE(&q->pfik_grouphead, p, pfik_instances);
- }
- pfi_ifcnt--;
- RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
- splx(s);
-
- free(p->pfik_ah_head, PFI_MTYPE);
- free(p, PFI_MTYPE);
- return (1);
-}
-
-void
-pfi_copy_group(char *p, const char *q, int m)
-{
- while (m > 1 && *q && !(*q >= '0' && *q <= '9')) {
- *p++ = *q++;
- m--;
- }
- if (m > 0)
- *p++ = '\0';
-}
-
-void
-pfi_newgroup(const char *name, int flags)
-{
- struct pfi_kif *p;
-
- p = pfi_lookup_if(name);
- if (p == NULL)
- p = pfi_if_create(name, pfi_self, PFI_IFLAG_GROUP);
- if (p == NULL) {
- printf("pfi_newgroup: cannot allocate '%s' group", name);
- return;
- }
- p->pfik_flags |= flags;
-}
-
void
pfi_fill_oldstatus(struct pf_status *pfs)
{
@@ -669,76 +584,33 @@ pfi_fill_oldstatus(struct pf_status *pfs)
}
int
-pfi_clr_istats(const char *name, int *nzero, int flags)
+pfi_clr_istats(const char *name)
{
struct pfi_kif *p;
- int n = 0, s;
- long tzero = time_second;
+ int s;
- ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
s = splsoftnet();
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
- if (pfi_skip_if(name, p, flags))
+ if (pfi_skip_if(name, p))
continue;
bzero(p->pfik_packets, sizeof(p->pfik_packets));
bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
- p->pfik_tzero = tzero;
- n++;
- }
- splx(s);
- if (nzero != NULL)
- *nzero = n;
- 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;
+ p->pfik_tzero = time_second;
}
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)
+pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
{
struct pfi_kif *p;
int s, n = 0;
- ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
s = splsoftnet();
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
- if (pfi_skip_if(name, p, flags))
+ if (pfi_skip_if(name, p))
continue;
if (*size > n++) {
if (!p->pfik_tzero)
@@ -754,25 +626,11 @@ pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
return (0);
}
-struct pfi_kif *
-pfi_lookup_if(const char *name)
-{
- struct pfi_kif *p, key;
-
- strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
- p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
- return (p);
-}
-
int
-pfi_skip_if(const char *filter, struct pfi_kif *p, int f)
+pfi_skip_if(const char *filter, struct pfi_kif *p)
{
int n;
- if ((p->pfik_flags & PFI_IFLAG_GROUP) && !(f & PFI_FLAG_GROUP))
- return (1);
- if ((p->pfik_flags & PFI_IFLAG_INSTANCE) && !(f & PFI_FLAG_INSTANCE))
- return (1);
if (filter == NULL || !*filter)
return (0);
if (!strcmp(p->pfik_name, filter))
@@ -787,6 +645,38 @@ pfi_skip_if(const char *filter, struct pfi_kif *p, int f)
return (p->pfik_name[n] < '0' || p->pfik_name[n] > '9');
}
+int
+pfi_set_flags(const char *name, int flags)
+{
+ struct pfi_kif *p;
+ int s;
+
+ s = splsoftnet();
+ RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
+ if (pfi_skip_if(name, p))
+ continue;
+ p->pfik_flags |= flags;
+ }
+ splx(s);
+ return (0);
+}
+
+int
+pfi_clear_flags(const char *name, int flags)
+{
+ struct pfi_kif *p;
+ int s;
+
+ s = splsoftnet();
+ RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
+ if (pfi_skip_if(name, p))
+ continue;
+ p->pfik_flags &= ~flags;
+ }
+ splx(s);
+ return (0);
+}
+
/* from pf_print_state.c */
int
pfi_unmask(void *addr)
@@ -807,44 +697,3 @@ pfi_unmask(void *addr)
return (b);
}
-void
-pfi_dohooks(struct pfi_kif *p)
-{
- for (; p != NULL; p = p->pfik_parent)
- dohooks(p->pfik_ah_head, 0);
-}
-
-int
-pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- switch (dyn->pfid_acnt4) {
- case 0:
- return (0);
- case 1:
- return (PF_MATCHA(0, &dyn->pfid_addr4,
- &dyn->pfid_mask4, a, AF_INET));
- default:
- return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
- }
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- switch (dyn->pfid_acnt6) {
- case 0:
- return (0);
- case 1:
- return (PF_MATCHA(0, &dyn->pfid_addr6,
- &dyn->pfid_mask6, a, AF_INET6));
- default:
- return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
- }
- break;
-#endif /* INET6 */
- default:
- return (0);
- }
-}
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index a0670a22cb1..ce16ce4bda1 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.140 2005/05/10 13:15:15 joel Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.141 2005/05/21 21:03:57 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -560,7 +560,7 @@ pf_empty_pool(struct pf_palist *poola)
while ((empty_pool_pa = TAILQ_FIRST(poola)) != NULL) {
pfi_dynaddr_remove(&empty_pool_pa->addr);
pf_tbladdr_remove(&empty_pool_pa->addr);
- pfi_detach_rule(empty_pool_pa->kif);
+ pfi_kif_unref(empty_pool_pa->kif, PFI_KIF_REF_RULE);
TAILQ_REMOVE(poola, empty_pool_pa, entries);
pool_put(&pf_pooladdr_pl, empty_pool_pa);
}
@@ -606,7 +606,7 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
if (rule->overload_tbl)
pfr_detach_table(rule->overload_tbl);
}
- pfi_detach_rule(rule->kif);
+ pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
pf_anchor_remove(rule);
pf_empty_pool(&rule->rpool.list);
pool_put(&pf_rule_pl, rule);
@@ -1039,7 +1039,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETSRCNODES:
case DIOCCLRSRCNODES:
case DIOCIGETIFACES:
- case DIOCICLRISTATS:
case DIOCSETIFFLAG:
case DIOCCLRIFFLAG:
break;
@@ -1188,12 +1187,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
else
rule->nr = 0;
if (rule->ifname[0]) {
- rule->kif = pfi_attach_rule(rule->ifname);
+ rule->kif = pfi_kif_get(rule->ifname);
if (rule->kif == NULL) {
pool_put(&pf_rule_pl, rule);
error = EINVAL;
break;
}
+ pfi_kif_ref(rule->kif, PFI_KIF_REF_RULE);
}
#ifdef ALTQ
@@ -1408,12 +1408,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
#endif /* INET6 */
if (newrule->ifname[0]) {
- newrule->kif = pfi_attach_rule(newrule->ifname);
+ newrule->kif = pfi_kif_get(newrule->ifname);
if (newrule->kif == NULL) {
pool_put(&pf_rule_pl, newrule);
error = EINVAL;
break;
}
+ pfi_kif_ref(newrule->kif, PFI_KIF_REF_RULE);
} else
newrule->kif = NULL;
@@ -1616,7 +1617,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENOMEM;
break;
}
- kif = pfi_lookup_create(ps->state.u.ifname);
+ kif = pfi_kif_get(ps->state.u.ifname);
if (kif == NULL) {
pool_put(&pf_state_pl, state);
error = ENOENT;
@@ -1634,7 +1635,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
state->bytes[0] = state->bytes[1] = 0;
if (pf_insert_state(kif, state)) {
- pfi_maybe_destroy(kif);
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
pool_put(&pf_state_pl, state);
error = ENOMEM;
}
@@ -1745,8 +1746,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bzero(pf_status.fcounters, sizeof(pf_status.fcounters));
bzero(pf_status.scounters, sizeof(pf_status.scounters));
if (*pf_status.ifname)
- pfi_clr_istats(pf_status.ifname, NULL,
- PFI_FLAG_INSTANCE);
+ pfi_clr_istats(pf_status.ifname);
break;
}
@@ -2068,16 +2068,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr));
if (pa->ifname[0]) {
- pa->kif = pfi_attach_rule(pa->ifname);
+ pa->kif = pfi_kif_get(pa->ifname);
if (pa->kif == NULL) {
pool_put(&pf_pooladdr_pl, pa);
error = EINVAL;
break;
}
+ pfi_kif_ref(pa->kif, PFI_KIF_REF_RULE);
}
if (pfi_dynaddr_setup(&pa->addr, pp->af)) {
pfi_dynaddr_remove(&pa->addr);
- pfi_detach_rule(pa->kif);
+ pfi_kif_unref(pa->kif, PFI_KIF_REF_RULE);
pool_put(&pf_pooladdr_pl, pa);
error = EINVAL;
break;
@@ -2177,18 +2178,19 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
#endif /* INET6 */
if (newpa->ifname[0]) {
- newpa->kif = pfi_attach_rule(newpa->ifname);
+ newpa->kif = pfi_kif_get(newpa->ifname);
if (newpa->kif == NULL) {
pool_put(&pf_pooladdr_pl, newpa);
error = EINVAL;
break;
}
+ pfi_kif_ref(newpa->kif, PFI_KIF_REF_RULE);
} else
newpa->kif = NULL;
if (pfi_dynaddr_setup(&newpa->addr, pca->af) ||
pf_tbladdr_setup(ruleset, &newpa->addr)) {
pfi_dynaddr_remove(&newpa->addr);
- pfi_detach_rule(newpa->kif);
+ pfi_kif_unref(newpa->kif, PFI_KIF_REF_RULE);
pool_put(&pf_pooladdr_pl, newpa);
error = EINVAL;
break;
@@ -2217,7 +2219,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
TAILQ_REMOVE(&pool->list, oldpa, entries);
pfi_dynaddr_remove(&oldpa->addr);
pf_tbladdr_remove(&oldpa->addr);
- pfi_detach_rule(oldpa->kif);
+ pfi_kif_unref(oldpa->kif, PFI_KIF_REF_RULE);
pool_put(&pf_pooladdr_pl, oldpa);
} else {
if (oldpa == NULL)
@@ -2771,20 +2773,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCIGETIFACES: {
struct pfioc_iface *io = (struct pfioc_iface *)addr;
- if (io->pfiio_esize != sizeof(struct pfi_if)) {
+ if (io->pfiio_esize != sizeof(struct pfi_kif)) {
error = ENODEV;
break;
}
error = pfi_get_ifaces(io->pfiio_name, io->pfiio_buffer,
- &io->pfiio_size, io->pfiio_flags);
- break;
- }
-
- case DIOCICLRISTATS: {
- struct pfioc_iface *io = (struct pfioc_iface *)addr;
-
- error = pfi_clr_istats(io->pfiio_name, &io->pfiio_nzero,
- io->pfiio_flags);
+ &io->pfiio_size);
break;
}
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index 3c3dbc062ca..0c592f1f6f1 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.97 2004/09/21 16:59:12 aaron Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.98 2005/05/21 21:03:57 henning Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -831,8 +831,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -1048,8 +1047,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -1215,8 +1213,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index d27d01d2323..5aad97035b7 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.213 2005/03/03 07:13:39 dhartmei Exp $ */
+/* $OpenBSD: pfvar.h,v 1.214 2005/05/21 21:03:57 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -588,7 +588,6 @@ struct pf_rule {
/* rule flags again */
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
-#define PFRULE_GRBOUND 0x00020000 /* group-bound */
#define PFSTATE_HIWAT 10000 /* default state table size */
@@ -846,53 +845,33 @@ RB_HEAD(pf_state_tree_ext_gwy, pf_state);
RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state,
u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
-struct pfi_if {
- char pfif_name[IFNAMSIZ];
- u_int64_t pfif_packets[2][2][2];
- u_int64_t pfif_bytes[2][2][2];
- u_int64_t pfif_addcnt;
- u_int64_t pfif_delcnt;
- long pfif_tzero;
- int pfif_states;
- int pfif_rules;
- int pfif_flags;
-};
-
-TAILQ_HEAD(pfi_grouphead, pfi_kif);
TAILQ_HEAD(pfi_statehead, pfi_kif);
RB_HEAD(pfi_ifhead, pfi_kif);
+
struct pfi_kif {
- struct pfi_if pfik_if;
RB_ENTRY(pfi_kif) pfik_tree;
+ char pfik_name[IFNAMSIZ];
+ u_int64_t pfik_packets[2][2][2];
+ u_int64_t pfik_bytes[2][2][2];
+ u_int32_t pfik_tzero; /* XXX */
+ int pfik_flags;
struct pf_state_tree_lan_ext pfik_lan_ext;
struct pf_state_tree_ext_gwy pfik_ext_gwy;
- struct pfi_grouphead pfik_grouphead;
- TAILQ_ENTRY(pfi_kif) pfik_instances;
TAILQ_ENTRY(pfi_kif) pfik_w_states;
struct hook_desc_head *pfik_ah_head;
void *pfik_ah_cookie;
- struct pfi_kif *pfik_parent;
struct ifnet *pfik_ifp;
int pfik_states;
int pfik_rules;
};
-#define pfik_name pfik_if.pfif_name
-#define pfik_packets pfik_if.pfif_packets
-#define pfik_bytes pfik_if.pfif_bytes
-#define pfik_tzero pfik_if.pfif_tzero
-#define pfik_flags pfik_if.pfif_flags
-#define pfik_addcnt pfik_if.pfif_addcnt
-#define pfik_delcnt pfik_if.pfif_delcnt
-#define pfik_states pfik_if.pfif_states
-#define pfik_rules pfik_if.pfif_rules
-
-#define PFI_IFLAG_GROUP 0x0001 /* group of interfaces */
-#define PFI_IFLAG_INSTANCE 0x0002 /* single instance */
-#define PFI_IFLAG_CLONABLE 0x0010 /* clonable group */
-#define PFI_IFLAG_DYNAMIC 0x0020 /* dynamic group */
-#define PFI_IFLAG_ATTACHED 0x0040 /* interface attached */
+
+enum pfi_kif_refs {
+ PFI_KIF_REF_NONE,
+ PFI_KIF_REF_STATE,
+ PFI_KIF_REF_RULE
+};
+
#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 */
@@ -1282,11 +1261,6 @@ struct pfioc_table {
#define pfrio_setflag pfrio_size2
#define pfrio_clrflag pfrio_nadd
-
-#define PFI_FLAG_GROUP 0x0001 /* gets groups of interfaces */
-#define PFI_FLAG_INSTANCE 0x0002 /* gets single interfaces */
-#define PFI_FLAG_ALLMASK 0x0003
-
struct pfioc_iface {
char pfiio_name[IFNAMSIZ];
void *pfiio_buffer;
@@ -1365,7 +1339,6 @@ struct pfioc_iface {
#define DIOCCLRSRCNODES _IO('D', 85)
#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)
@@ -1387,7 +1360,6 @@ extern struct pf_poolqueue pf_pools[2];
TAILQ_HEAD(pf_altqqueue, pf_altq);
extern struct pf_altqqueue pf_altqs[2];
extern struct pf_palist pf_pabuf;
-extern struct pfi_kif **pfi_index2kif;
extern u_int32_t ticket_altqs_active;
extern u_int32_t ticket_altqs_inactive;
@@ -1513,29 +1485,26 @@ int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, u_int32_t, int);
+extern struct pfi_statehead pfi_statehead;
+extern struct pfi_kif *pfi_all;
+
void pfi_initialize(void);
-void pfi_attach_clone(struct if_clone *);
+struct pfi_kif *pfi_kif_get(char *);
+void pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs);
+void pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs);
+int pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
void pfi_attach_ifnet(struct ifnet *);
void pfi_detach_ifnet(struct ifnet *);
-struct pfi_kif *pfi_lookup_create(const char *);
-struct pfi_kif *pfi_lookup_if(const char *);
-int pfi_maybe_destroy(struct pfi_kif *);
-struct pfi_kif *pfi_attach_rule(const char *);
-void pfi_detach_rule(struct pfi_kif *);
-void pfi_attach_state(struct pfi_kif *);
-void pfi_detach_state(struct pfi_kif *);
+int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
+ sa_family_t);
int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
-void pfi_dynaddr_copyout(struct pf_addr_wrap *);
void pfi_dynaddr_remove(struct pf_addr_wrap *);
+void pfi_dynaddr_copyout(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_clr_istats(const char *);
+int pfi_get_ifaces(const char *, struct pfi_kif *, 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);
-
-extern struct pfi_statehead pfi_statehead;
u_int16_t pf_tagname2tag(char *);
void pf_tag2tagname(u_int16_t, char *);