summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-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 *);