Unix Technical Forum

important pf diff, needs lots of testiing and review

This is a discussion on important pf diff, needs lots of testiing and review within the mailing.openbsd.tech forums, part of the OpenBSD category; --> this diff is really important. it cleans up the interface abstraction code big time and is a prerequisite for ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 07:50 AM
Henning Brauer
 
Posts: n/a
Default important pf diff, needs lots of testiing and review

this diff is really important. it cleans up the interface abstraction
code big time and is a prerequisite for more changes coming. Ryan and
myself worked our asses off getting this right in montreal last week and
did quite a bit of testing on the flight to vancouver yesterday; please
help us to get this so well tested that we can get it in thursday
(we'll be mostly away 'til then).

known and expected breakage:
-interface groups are gone (i. e. "em" for em0, em1 ..., will be back
later, but different)
-I think the "self" handling is broken, needs verification

important to test (besides lots of general testing) is hotplugging
interfaces, and removal. load rulesets referring to not yet existant
interfaces and plug em later and verify the rules work as intended and
such.

thanks.

Index: sys/net/if.c
================================================== =================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.109
diff -u -p -r1.109 if.c
--- sys/net/if.c 9 May 2005 08:08:47 -0000 1.109
+++ sys/net/if.c 16 May 2005 16:26:32 -0000
@@ -293,7 +293,7 @@ if_alloc_sadl(struct ifnet *ifp)
if (ifp->if_sadl != NULL)
if_free_sadl(ifp);

- namelen = strlen(ifp->if_xname);
+ namelen = strlen(ifp->if_xname) + 1;
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
socksize = masklen + ifp->if_addrlen;
@@ -307,8 +307,8 @@ if_alloc_sadl(struct ifnet *ifp)
sdl = (struct sockaddr_dl *)(ifa + 1);
sdl->sdl_len = socksize;
sdl->sdl_family = AF_LINK;
- bcopy(ifp->if_xname, sdl->sdl_data, namelen);
- sdl->sdl_nlen = namelen;
+ strlcpy(sdl->sdl_data, ifp->if_xname, namelen);
+ sdl->sdl_nlen = namelen - 1;
sdl->sdl_alen = ifp->if_addrlen;
sdl->sdl_index = ifp->if_index;
sdl->sdl_type = ifp->if_type;
@@ -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
}

/*
Index: sys/net/if.h
================================================== =================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.65
diff -u -p -r1.65 if.h
--- sys/net/if.h 20 Apr 2005 23:00:40 -0000 1.65
+++ sys/net/if.h 16 May 2005 16:26:32 -0000
@@ -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) */
Index: sys/net/if_pfsync.c
================================================== =================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.46
diff -u -p -r1.46 if_pfsync.c
--- sys/net/if_pfsync.c 20 Feb 2005 15:58:38 -0000 1.46
+++ sys/net/if_pfsync.c 16 May 2005 16:26:33 -0000
@@ -173,7 +173,7 @@ pfsync_insert_net_state(struct pfsync_st
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_st
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_st


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,14 +330,7 @@ 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);
- splx(s);
- goto done;
- }
+ kif = pfi_kif_get(cp->ifname);
for (st = RB_MIN(pf_state_tree_lan_ext,
&kif->pfik_lan_ext); st; st = nexts) {
nexts = RB_NEXT(pf_state_tree_lan_ext,
Index: sys/net/pf.c
================================================== =================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.488
diff -u -p -r1.488 pf.c
--- sys/net/pf.c 25 Apr 2005 17:55:51 -0000 1.488
+++ sys/net/pf.c 16 May 2005 16:26:34 -0000
@@ -252,9 +252,8 @@ struct pf_pool_limit pf_pool_limits[PF_L
(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 *ki

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, str

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 *
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
}

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

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

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

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, struc

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, in
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, stru
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, str
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));
Index: sys/net/pf_if.c
================================================== =================
RCS file: /cvs/src/sys/net/pf_if.c,v
retrieving revision 1.24
diff -u -p -r1.24 pf_if.c
--- sys/net/pf_if.c 21 Apr 2005 13:34:45 -0000 1.24
+++ sys/net/pf_if.c 16 May 2005 16:26:34 -0000
@@ -1,6 +1,8 @@
/* $OpenBSD: pf_if.c,v 1.24 2005/04/21 13:34:45 pascoe 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,27 @@
#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_table_update(struct pfr_ktable *, struct pfi_kif *,
+ int, int);
void pfi_kifaddr_update(void *);
void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
int, int);
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 +88,7 @@ RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tr
void
pfi_initialize(void)
{
- if (pfi_self != NULL) /* already initialized */
+ if (pfi_all != NULL) /* already initialized */
return;

TAILQ_INIT(&pfi_statehead);
@@ -108,176 +97,187 @@ 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);
+ pfi_all = pfi_kif_get("all");
}

-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 == 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 +296,12 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a
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 +319,26 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a
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 +351,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);
@@ -375,21 +384,20 @@ pfi_table_update(struct pfr_ktable *kt,
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 *
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
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++;
+ p->pfik_tzero = time_second;
}
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;
- }
- 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
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 p
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);
- }
-}
Index: sys/net/pf_ioctl.c
================================================== =================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.140
diff -u -p -r1.140 pf_ioctl.c
--- sys/net/pf_ioctl.c 10 May 2005 13:15:15 -0000 1.140
+++ sys/net/pf_ioctl.c 16 May 2005 16:26:34 -0000
@@ -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 *rulequeu
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 a
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 a
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 a
}
#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 a
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 a
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 a
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 a
}
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 a
}
#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 a
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 a
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;
}

Index: sys/net/pf_norm.c
================================================== =================
RCS file: /cvs/src/sys/net/pf_norm.c,v
retrieving revision 1.97
diff -u -p -r1.97 pf_norm.c
--- sys/net/pf_norm.c 21 Sep 2004 16:59:12 -0000 1.97
+++ sys/net/pf_norm.c 16 May 2005 16:26:34 -0000
@@ -831,8 +831,7 @@ pf_normalize_ip(struct mbuf **m0, int di
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 d
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
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;
Index: sys/net/pfvar.h
================================================== =================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.213
diff -u -p -r1.213 pfvar.h
--- sys/net/pfvar.h 3 Mar 2005 07:13:39 -0000 1.213
+++ sys/net/pfvar.h 16 May 2005 16:26:35 -0000
@@ -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
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 *);
Index: sbin/pfctl/parse.y
================================================== =================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.483
diff -u -p -r1.483 parse.y
--- sbin/pfctl/parse.y 22 Apr 2005 11:05:36 -0000 1.483
+++ sbin/pfctl/parse.y 16 May 2005 16:26:35 -0000
@@ -410,7 +410,7 @@ typedef struct {
%token LOAD
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
-%token TAGGED TAG IFBOUND GRBOUND FLOATING STATEPOLICY ROUTE
+%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE
%token <v.string> STRING
%token <v.i> PORTBINARY
%type <v.interface> interface if_list if_item_not if_item
@@ -560,10 +560,6 @@ option : SET OPTIMIZATION STRING {
case PFRULE_IFBOUND:
printf("set state-policy if-bound\n");
break;
- case PFRULE_GRBOUND:
- printf("set state-policy "
- "group-bound\n");
- break;
}
default_statelock = $3;
}
@@ -2836,9 +2832,6 @@ sourcetrack : SOURCETRACK { $$ = PF_SRC
statelock : IFBOUND {
$$ = PFRULE_IFBOUND;
}
- | GRBOUND {
- $$ = PFRULE_GRBOUND;
- }
| FLOATING {
$$ = 0;
}
@@ -4602,7 +4595,6 @@ lookup(char *s)
{ "from", FROM},
{ "global", GLOBAL},
{ "group", GROUP},
- { "group-bound", GRBOUND},
{ "hfsc", HFSC},
{ "hostid", HOSTID},
{ "icmp-type", ICMPTYPE},
Index: sbin/pfctl/pfctl.c
================================================== =================
RCS file: /cvs/src/sbin/pfctl/pfctl.c,v
retrieving revision 1.235
diff -u -p -r1.235 pfctl.c
--- sbin/pfctl/pfctl.c 5 May 2005 04:00:26 -0000 1.235
+++ sbin/pfctl/pfctl.c 16 May 2005 16:26:36 -0000
@@ -268,7 +268,6 @@ pfctl_clear_interface_flags(int dev, int

if ((opts & PF_OPT_NOACTION) == 0) {
bzero(&pi, sizeof(pi));
- pi.pfiio_flags = PFI_IFLAG_SETABLE_MASK;

if (ioctl(dev, DIOCCLRIFFLAG, &pi))
err(1, "DIOCCLRIFFLAG");
Index: sbin/pfctl/pfctl.h
================================================== =================
RCS file: /cvs/src/sbin/pfctl/pfctl.h,v
retrieving revision 1.37
diff -u -p -r1.37 pfctl.h
--- sbin/pfctl/pfctl.h 5 Jan 2005 18:23:10 -0000 1.37
+++ sbin/pfctl/pfctl.h 16 May 2005 16:26:36 -0000
@@ -73,7 +73,7 @@ int pfr_buf_grow(struct pfr_buffer *, i
int pfr_buf_load(struct pfr_buffer *, char *, int,
int (*)(struct pfr_buffer *, char *, int));
char *pfr_strerror(int);
-int pfi_get_ifaces(const char *, struct pfi_if *, int *, int);
+int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
int pfi_clr_istats(const char *, int *, int);

void pfctl_print_title(char *);
Index: sbin/pfctl/pfctl_parser.c
================================================== =================
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.211
diff -u -p -r1.211 pfctl_parser.c
--- sbin/pfctl/pfctl_parser.c 7 Dec 2004 10:33:41 -0000 1.211
+++ sbin/pfctl/pfctl_parser.c 16 May 2005 16:26:36 -0000
@@ -820,7 +820,7 @@ print_rule(struct pf_rule *r, const char
opts = 1;
if (r->rule_flag & PFRULE_SRCTRACK)
opts = 1;
- if (r->rule_flag & (PFRULE_IFBOUND | PFRULE_GRBOUND))
+ if (r->rule_flag & PFRULE_IFBOUND)
opts = 1;
for (i = 0; !opts && i < PFTM_MAX; ++i)
if (r->timeout[i])
@@ -886,12 +886,6 @@ print_rule(struct pf_rule *r, const char
if (!opts)
printf(", ");
printf("if-bound");
- opts = 0;
- }
- if (r->rule_flag & PFRULE_GRBOUND) {
- if (!opts)
- printf(", ");
- printf("group-bound");
opts = 0;
}
for (i = 0; i < PFTM_MAX; ++i)
Index: sbin/pfctl/pfctl_radix.c
================================================== =================
RCS file: /cvs/src/sbin/pfctl/pfctl_radix.c,v
retrieving revision 1.26
diff -u -p -r1.26 pfctl_radix.c
--- sbin/pfctl/pfctl_radix.c 14 Jun 2004 20:44:22 -0000 1.26
+++ sbin/pfctl/pfctl_radix.c 16 May 2005 16:26:36 -0000
@@ -421,7 +421,7 @@ pfr_ina_define(struct pfr_table *tbl, st
/* interface management code */

int
-pfi_get_ifaces(const char *filter, struct pfi_if *buf, int *size, int flags)
+pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size)
{
struct pfioc_iface io;

@@ -430,7 +430,6 @@ pfi_get_ifaces(const char *filter, struc
return (-1);
}
bzero(&io, sizeof io);
- io.pfiio_flags = flags;
if (filter != NULL)
if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >=
sizeof(io.pfiio_name)) {
@@ -451,7 +450,7 @@ pfi_get_ifaces(const char *filter, struc
size_t buf_esize[PFRB_MAX] = { 0,
sizeof(struct pfr_table), sizeof(struct pfr_tstats),
sizeof(struct pfr_addr), sizeof(struct pfr_astats),
- sizeof(struct pfi_if), sizeof(struct pfioc_trans_e)
+ sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e)
};

/*
Index: sbin/pfctl/pfctl_table.c
================================================== =================
RCS file: /cvs/src/sbin/pfctl/pfctl_table.c,v
retrieving revision 1.62
diff -u -p -r1.62 pfctl_table.c
--- sbin/pfctl/pfctl_table.c 22 Dec 2004 17:17:55 -0000 1.62
+++ sbin/pfctl/pfctl_table.c 16 May 2005 16:26:36 -0000
@@ -61,8 +61,7 @@ static void print_addrx(struct pfr_addr
static void print_astats(struct pfr_astats *, int);
static void radix_perror(void);
static void xprintf(int, const char *, ...);
-static void print_iface(struct pfi_if *, int);
-static void oprintf(int, int, const char *, int *, int);
+static void print_iface(struct pfi_kif *, int);

static const char *stats_text[PFR_DIR_MAX][PFR_OP_TABLE_MAX] = {
{ "In/Block:", "In/Pass:", "In/XPass:" },
@@ -539,17 +538,15 @@ int
pfctl_show_ifaces(const char *filter, int opts)
{
struct pfr_buffer b;
- struct pfi_if *p;
- int i = 0, f = PFI_FLAG_GROUP|PFI_FLAG_INSTANCE;
+ struct pfi_kif *p;
+ int i = 0;

- if (filter != NULL && *filter && !isdigit(filter[strlen(filter)-1]))
- f &= ~PFI_FLAG_INSTANCE;
bzero(&b, sizeof(b));
b.pfrb_type = PFRB_IFACES;
for (; {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
- if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size, f)) {
+ if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size)) {
radix_perror();
return (1);
}
@@ -565,46 +562,26 @@ pfctl_show_ifaces(const char *filter, in
}

void
-print_iface(struct pfi_if *p, int opts)
+print_iface(struct pfi_kif *p, int opts)
{
- time_t tzero = p->pfif_tzero;
- int flags = (opts & PF_OPT_VERBOSE) ? p->pfif_flags : 0;
- int first = 1;
+ time_t tzero = p->pfik_tzero;
int i, af, dir, act;

- printf("%s", p->pfif_name);
- oprintf(flags, PFI_IFLAG_INSTANCE, "instance", &first, 0);
- oprintf(flags, PFI_IFLAG_GROUP, "group", &first, 0);
- oprintf(flags, PFI_IFLAG_CLONABLE, "clonable", &first, 0);
- oprintf(flags, PFI_IFLAG_DYNAMIC, "dynamic", &first, 0);
- oprintf(flags, PFI_IFLAG_ATTACHED, "attached", &first, 0);
- oprintf(flags, PFI_IFLAG_SKIP, "skipped", &first, 1);
+ printf("%s", p->pfik_name);
printf("\n");

if (!(opts & PF_OPT_VERBOSE2))
return;
printf("\tCleared: %s", ctime(&tzero));
printf("\tReferences: [ States: %-18d Rules: %-18d ]\n",
- p->pfif_states, p->pfif_rules);
+ p->pfik_states, p->pfik_rules);
for (i = 0; i < 8; i++) {
af = (i>>2) & 1;
dir = (i>>1) &1;
act = i & 1;
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
istats_text[af][dir][act],
- (unsigned long long)p->pfif_packets[af][dir][act],
- (unsigned long long)p->pfif_bytes[af][dir][act]);
+ (unsigned long long)p->pfik_packets[af][dir][act],
+ (unsigned long long)p->pfik_bytes[af][dir][act]);
}
}
-
-void
-oprintf(int flags, int flag, const char *s, int *first, int last)
-{
- if (flags & flag) {
- printf(*first ? "\t(%s" : ", %s", s);
- *first = 0;
- }
- if (last && !*first)
- printf(")");
-}
-

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:26 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com