[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: important pf diff, needs lots of testiing and review



eh, apparently I managed to send a mangled diff somehow... pls try this 

? sys/net/if.c.2
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	21 May 2005 18:03:27 -0000
@@ -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	21 May 2005 18:03:28 -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	21 May 2005 18:03:28 -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,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) {
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	21 May 2005 18:03:29 -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	21 May 2005 18:03:29 -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_(_at_)_openbsd_(_dot_)_org>
+ * Copyright 2005 Ryan McBride <mcbride_(_at_)_openbsd_(_dot_)_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_tr
 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 *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 +318,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 +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		*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	21 May 2005 18:03:30 -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	21 May 2005 18:03:30 -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	21 May 2005 18:03:30 -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	21 May 2005 18:03:31 -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	21 May 2005 18:03:31 -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	21 May 2005 18:03:31 -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	21 May 2005 18:03:32 -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	21 May 2005 18:03:32 -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	21 May 2005 18:03:32 -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(")");
-}
-



Visit your host, monkey.org