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