Date: Thu, 8 Oct 2009 18:55:12 +0000 (UTC) From: Ermal Luçi <eri@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r197866 - user/eri/net Message-ID: <200910081855.n98ItC5i030359@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: eri Date: Thu Oct 8 18:55:12 2009 New Revision: 197866 URL: http://svn.freebsd.org/changeset/base/197866 Log: Integrate all the changes needed to make pf(4) compile. Mark areas still needing work around ifdef notyet, though they are features as pfsync/pfflow/pflog. Modified: user/eri/net/if_pflog.c user/eri/net/if_pflog.h user/eri/net/pf.c user/eri/net/pf_if.c user/eri/net/pf_ioctl.c user/eri/net/pf_lb.c user/eri/net/pf_norm.c user/eri/net/pf_osfp.c user/eri/net/pf_ruleset.c user/eri/net/pf_table.c user/eri/net/pfvar.h Modified: user/eri/net/if_pflog.c ============================================================================== --- user/eri/net/if_pflog.c Thu Oct 8 18:44:15 2009 (r197865) +++ user/eri/net/if_pflog.c Thu Oct 8 18:55:12 2009 (r197866) @@ -2,7 +2,7 @@ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). + * Niels Provos (provos@physnet.uni hamburg.de). * * This code was written by John Ioannidis for BSD/OS in Athens, Greece, * in November 1995. @@ -33,17 +33,51 @@ * PURPOSE. */ + #ifdef __FreeBSD__ + #include "opt_inet.h" + #include "opt_inet6.h" + #include "opt_bpf.h" + #include "opt_pf.h" + + #include <sys/cdefs.h> + __FBSDID("$FreeBSD$"); + + #ifdef DEV_BPF + #define NBPFILTER DEV_BPF + #else + #define NBPFILTER 0 + #endif + + #ifdef DEV_PFLOG + #define NPFLOG DEV_PFLOG + #else + #define NPFLOG 0 + #endif + + #else /* ! __FreeBSD__ */ #include "bpfilter.h" #include "pflog.h" +#endif #include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/proc.h> #include <sys/socket.h> + #ifdef __FreeBSD__ + #include <sys/kernel.h> + #include <sys/limits.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/sockio.h> + #else #include <sys/ioctl.h> +#endif #include <net/if.h> + #ifdef __FreeBSD__ + #include <net/if_clone.h> + #endif #include <net/if_types.h> #include <net/route.h> #include <net/bpf.h> @@ -65,6 +99,12 @@ #include <net/pfvar.h> #include <net/if_pflog.h> + #ifdef INET + #ifdef __FreeBSD__ + #include <machine/in_cksum.h> + #endif + #endif + #define PFLOGMTU (32768 + MHLEN + MLEN) #ifdef PFLOGDEBUG @@ -78,12 +118,21 @@ int pflogoutput(struct ifnet *, struct m struct rtentry *); int pflogioctl(struct ifnet *, u_long, caddr_t); void pflogstart(struct ifnet *); + #ifdef __FreeBSD__ + static int pflog_clone_create(struct if_clone *, int, caddr_t); + static void pflog_clone_destroy(struct ifnet *); + #else int pflog_clone_create(struct if_clone *, int); int pflog_clone_destroy(struct ifnet *); +#endif LIST_HEAD(, pflog_softc) pflogif_list; + #ifdef __FreeBSD__ + IFC_SIMPLE_DECLARE(pflog, 1); + #else struct if_clone pflog_cloner = IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy); +#endif struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */ @@ -97,8 +146,13 @@ pflogattach(int npflog) if_clone_attach(&pflog_cloner); } + #ifdef __FreeBSD__ + static int + pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param) + #else int pflog_clone_create(struct if_clone *ifc, int unit) +#endif { struct ifnet *ifp; struct pflog_softc *pflogif; @@ -111,49 +165,85 @@ pflog_clone_create(struct if_clone *ifc, M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) return (ENOMEM); - pflogif->sc_unit = unit; - ifp = &pflogif->sc_if; - snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit); - ifp->if_softc = pflogif; - ifp->if_mtu = PFLOGMTU; - ifp->if_ioctl = pflogioctl; - ifp->if_output = pflogoutput; - ifp->if_start = pflogstart; - ifp->if_type = IFT_PFLOG; - ifp->if_snd.ifq_maxlen = ifqmaxlen; - ifp->if_hdrlen = PFLOG_HDRLEN; + pflogif >sc_unit = unit; + #ifdef __FreeBSD__ + ifp = pflogif >sc_ifp = if_alloc(IFT_PFLOG); + if (ifp == NULL) { + free(pflogif, M_DEVBUF); + return (ENOSPC); + } + if_initname(ifp, ifc >ifc_name, unit); + #else + ifp = &pflogif >sc_if; + snprintf(ifp >if_xname, sizeof ifp >if_xname, "pflog%d", unit); +#endif + ifp >if_softc = pflogif; + ifp >if_mtu = PFLOGMTU; + ifp >if_ioctl = pflogioctl; + ifp >if_output = pflogoutput; + ifp >if_start = pflogstart; +#ifndef __FreeBSD__ + ifp >if_type = IFT_PFLOG; +#endif + ifp >if_snd.ifq_maxlen = ifqmaxlen; + ifp >if_hdrlen = PFLOG_HDRLEN; if_attach(ifp); +#ifndef __FreeBSD__ if_alloc_sadl(ifp); +#endif #if NBPFILTER > 0 - bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN); + bpfattach(&pflogif >sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN); #endif s = splnet(); + #ifdef __FreeBSD__ + /* XXX: Why pf(4) lock?! Better add a pflog lock?! */ + PF_LOCK(); + #endif LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list); pflogifs[unit] = ifp; + #ifdef __FreeBSD__ + PF_UNLOCK(); + #endif splx(s); return (0); } + #ifdef __FreeBSD__ + static void + pflog_clone_destroy(struct ifnet *ifp) + #else int pflog_clone_destroy(struct ifnet *ifp) +#endif { - struct pflog_softc *pflogif = ifp->if_softc; + struct pflog_softc *pflogif = ifp >if_softc; int s; s = splnet(); - pflogifs[pflogif->sc_unit] = NULL; + #ifdef __FreeBSD__ + PF_LOCK(); + #endif + pflogifs[pflogif >sc_unit] = NULL; LIST_REMOVE(pflogif, sc_list); + #ifdef __FreeBSD__ + PF_UNLOCK(); + #endif splx(s); #if NBPFILTER > 0 bpfdetach(ifp); #endif if_detach(ifp); + #ifdef __FreeBSD__ + if_free(ifp); + #endif free(pflogif, M_DEVBUF); +#ifndef __FreeBSD__ return (0); +#endif } /* @@ -163,13 +253,22 @@ void pflogstart(struct ifnet *ifp) { struct mbuf *m; + #ifndef __FreeBSD__ int s; +#endif for (;;) { + #ifdef __FreeBSD__ + IF_LOCK(&ifp >if_snd); + _IF_DROP(&ifp >if_snd); + _IF_DEQUEUE(&ifp >if_snd, m); + IF_UNLOCK(&ifp >if_snd); + #else s = splnet(); - IF_DROP(&ifp->if_snd); - IF_DEQUEUE(&ifp->if_snd, m); + IF_DROP(&ifp >if_snd); + IF_DEQUEUE(&ifp >if_snd, m); splx(s); +#endif if (m == NULL) return; @@ -192,10 +291,17 @@ pflogioctl(struct ifnet *ifp, u_long cmd { switch (cmd) { case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) - ifp->if_flags |= IFF_RUNNING; + #ifdef __FreeBSD__ + if (ifp >if_flags & IFF_UP) + ifp >if_drv_flags |= IFF_DRV_RUNNING; + else + ifp >if_drv_flags &= ~IFF_DRV_RUNNING; + #else + if (ifp >if_flags & IFF_UP) + ifp >if_flags |= IFF_RUNNING; else - ifp->if_flags &= ~IFF_RUNNING; + ifp >if_flags &= ~IFF_RUNNING; +#endif break; default: return (ENOTTY); @@ -214,39 +320,47 @@ pflog_packet(struct pfi_kif *kif, struct struct pfloghdr hdr; if (kif == NULL || m == NULL || rm == NULL || pd == NULL) - return (-1); + return ( 1); - if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf) + if ((ifn = pflogifs[rm >logif]) == NULL || !ifn >if_bpf) return (0); bzero(&hdr, sizeof(hdr)); hdr.length = PFLOG_REAL_HDRLEN; hdr.af = af; - hdr.action = rm->action; + hdr.action = rm >action; hdr.reason = reason; - memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname)); + memcpy(hdr.ifname, kif >pfik_name, sizeof(hdr.ifname)); if (am == NULL) { - hdr.rulenr = htonl(rm->nr); - hdr.subrulenr = -1; + hdr.rulenr = htonl(rm >nr); + hdr.subrulenr = 1; } else { - hdr.rulenr = htonl(am->nr); - hdr.subrulenr = htonl(rm->nr); - if (ruleset != NULL && ruleset->anchor != NULL) - strlcpy(hdr.ruleset, ruleset->anchor->name, + hdr.rulenr = htonl(am >nr); + hdr.subrulenr = htonl(rm >nr); + if (ruleset != NULL && ruleset >anchor != NULL) + strlcpy(hdr.ruleset, ruleset >anchor >name, sizeof(hdr.ruleset)); } - if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done) - pd->lookup.done = pf_socket_lookup(dir, pd); - if (pd->lookup.done > 0) { - hdr.uid = pd->lookup.uid; - hdr.pid = pd->lookup.pid; + if (rm >log & PF_LOG_SOCKET_LOOKUP && !pd >lookup.done) + #ifdef __FreeBSD__ + /* + * XXX: This should not happen as we force an early lookup + * via debug.pfugidhack + */ + ; /* empty */ + #else + pd >lookup.done = pf_socket_lookup(dir, pd); +#endif + if (pd >lookup.done > 0) { + hdr.uid = pd >lookup.uid; + hdr.pid = pd >lookup.pid; } else { hdr.uid = UID_MAX; hdr.pid = NO_PID; } - hdr.rule_uid = rm->cuid; - hdr.rule_pid = rm->cpid; + hdr.rule_uid = rm >cuid; + hdr.rule_pid = rm >cpid; hdr.dir = dir; #ifdef INET @@ -254,16 +368,56 @@ pflog_packet(struct pfi_kif *kif, struct struct ip *ip; ip = mtod(m, struct ip *); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, ip->ip_hl << 2); + ip >ip_sum = 0; + ip >ip_sum = in_cksum(m, ip >ip_hl << 2); } #endif /* INET */ - ifn->if_opackets++; - ifn->if_obytes += m->m_pkthdr.len; - bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m, + ifn >if_opackets++; + ifn >if_obytes += m >m_pkthdr.len; + #ifdef __FreeBSD__ + BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m); + #else + bpf_mtap_hdr(ifn >if_bpf, (char *)&hdr, PFLOG_HDRLEN, m, BPF_DIRECTION_OUT); #endif +#endif return (0); } + + #ifdef __FreeBSD__ + static int + pflog_modevent(module_t mod, int type, void *data) + { + int error = 0; + + switch (type) { + case MOD_LOAD: + pflogattach(1); + PF_LOCK(); + pflog_packet_ptr = pflog_packet; + PF_UNLOCK(); + break; + case MOD_UNLOAD: + PF_LOCK(); + pflog_packet_ptr = NULL; + PF_UNLOCK(); + if_clone_detach(&pflog_cloner); + break; + default: + error = EINVAL; + break; + } + + return error; + } + + static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 }; + + #define PFLOG_MODVER 1 + + DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); + MODULE_VERSION(pflog, PFLOG_MODVER); + MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER); + #endif /* __FreeBSD__ */ Modified: user/eri/net/if_pflog.h ============================================================================== --- user/eri/net/if_pflog.h Thu Oct 8 18:44:15 2009 (r197865) +++ user/eri/net/if_pflog.h Thu Oct 8 18:55:12 2009 (r197866) @@ -30,7 +30,11 @@ #define PFLOGIFS_MAX 16 struct pflog_softc { +#ifdef __FreeBSD__ + struct ifnet *sc_ifp; /* the interface pointer */ +#else struct ifnet sc_if; /* the interface */ +#endif int sc_unit; LIST_ENTRY(pflog_softc) sc_list; }; @@ -70,11 +74,26 @@ struct old_pfloghdr { #define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr) #ifdef _KERNEL - +#ifdef __FreeBSD__ + struct pf_rule; + struct pf_ruleset; + struct pfi_kif; + struct pf_pdesc; + + typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t, + u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *, + struct pf_ruleset *, struct pf_pdesc *); + extern pflog_packet_t *pflog_packet_ptr; +#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \ + if (pflog_packet_ptr != NULL) \ + pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \ + } while (0) +#else /* ! __FreeBSD__ */ #if NPFLOG > 0 #define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) pflog_packet(i,a,b,c,d,e,f,g,h) #else #define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0) #endif /* NPFLOG > 0 */ +#endif #endif /* _KERNEL */ #endif /* _NET_IF_PFLOG_H_ */ Modified: user/eri/net/pf.c ============================================================================== --- user/eri/net/pf.c Thu Oct 8 18:44:15 2009 (r197865) +++ user/eri/net/pf.c Thu Oct 8 18:55:12 2009 (r197866) @@ -35,10 +35,46 @@ * */ + #ifdef __FreeBSD__ + #include "opt_inet.h" + #include "opt_inet6.h" + + #include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #endif + + #ifdef __FreeBSD__ + #include "opt_bpf.h" + #include "opt_pf.h" + + #ifdef DEV_BPF + #define NBPFILTER DEV_BPF + #else + #define NBPFILTER 0 + #endif + + #ifdef DEV_PFLOG + #define NPFLOG DEV_PFLOG + #else + #define NPFLOG 0 + #endif + + #ifdef DEV_PFSYNC + #define NPFSYNC DEV_PFSYNC + #else + #define NPFSYNC 0 + #endif + + /* XXX */ + #define NPFLOW 0 + #else #include "bpfilter.h" #include "pflog.h" #include "pfsync.h" +#endif +#ifdef notyet #include "pflow.h" +#endif #include <sys/param.h> #include <sys/systm.h> @@ -48,17 +84,40 @@ #include <sys/socketvar.h> #include <sys/kernel.h> #include <sys/time.h> + #ifdef __FreeBSD__ + #include <sys/random.h> + #include <sys/sysctl.h> + #include <sys/endian.h> + #define betoh64 be64toh + #else #include <sys/pool.h> +#endif #include <sys/proc.h> + #ifdef __FreeBSD__ + #include <sys/kthread.h> + #include <sys/lock.h> + #include <sys/sx.h> + #else #include <sys/rwlock.h> +#endif +#ifdef __FreeBSD__ +#include <sys/md5.h> +#else #include <crypto/md5.h> +#endif #include <net/if.h> #include <net/if_types.h> #include <net/bpf.h> #include <net/route.h> +#ifdef __FreeBSD__ +#ifdef RADIX_MPATH #include <net/radix_mpath.h> +#endif +#else +#include <net/radix_mpath.h> +#endif #include <netinet/in.h> #include <netinet/in_var.h> @@ -76,10 +135,14 @@ #include <netinet/icmp_var.h> #include <netinet/if_ether.h> +#ifndef __FreeBSD__ #include <dev/rndvar.h> +#endif #include <net/pfvar.h> #include <net/if_pflog.h> +#ifdef notyet #include <net/if_pflow.h> +#endif #if NPFSYNC > 0 #include <net/if_pfsync.h> @@ -90,8 +153,21 @@ #include <netinet/in_pcb.h> #include <netinet/icmp6.h> #include <netinet6/nd6.h> + #ifdef __FreeBSD__ + #include <netinet6/ip6_var.h> + #include <netinet6/in6_pcb.h> + #endif #endif /* INET6 */ +#ifdef __FreeBSD__ + #include <machine/in_cksum.h> + #include <sys/limits.h> + #include <sys/ucred.h> + #include <security/mac/mac_framework.h> + + extern int ip_optcopy(struct ip *, struct ip *); + extern int debug_pfugidhack; + #endif #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x @@ -125,9 +201,15 @@ struct pf_anchor_stackframe { struct pf_anchor *child; } pf_anchor_stack[64]; + #ifdef __FreeBSD__ + uma_zone_t pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl; + uma_zone_t pf_state_pl, pf_state_key_pl, pf_state_item_pl; +uma_zone_t pf_altq_pl; + #else struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl; struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl; struct pool pf_altq_pl; +#endif void pf_init_threshold(struct pf_threshold *, u_int32_t, u_int32_t); @@ -147,7 +229,12 @@ void pf_change_icmp(struct pf_addr *, struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t *, u_int16_t *, u_int16_t *, u_int16_t *, u_int8_t, sa_family_t); +#ifdef __FreeBSD__ + void pf_send_tcp(struct mbuf *, + const struct pf_rule *, sa_family_t, +#else void pf_send_tcp(const struct pf_rule *, sa_family_t, +#endif const struct pf_addr *, const struct pf_addr *, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, @@ -160,7 +247,12 @@ u_int32_t pf_tcp_iss(struct pf_pdesc * int pf_test_rule(struct pf_rule **, struct pf_state **, int, struct pfi_kif *, struct mbuf *, int, void *, struct pf_pdesc *, struct pf_rule **, +#ifdef __FreeBSD__ + struct pf_ruleset **, struct ifqueue *, + struct inpcb *); +#else struct pf_ruleset **, struct ifqueue *); +#endif static __inline int pf_create_state(struct pf_rule *, struct pf_rule *, struct pf_rule *, struct pf_pdesc *, struct pf_src_node *, struct pf_state_key *, @@ -197,7 +289,9 @@ void pf_route(struct mbuf **, struct void pf_route6(struct mbuf **, struct pf_rule *, int, struct ifnet *, struct pf_state *, struct pf_pdesc *); +#ifndef __FreeBSD__ int pf_socket_lookup(int, struct pf_pdesc *); +#endif u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, sa_family_t); u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, @@ -215,11 +309,24 @@ int pf_addr_wrap_neq(struct pf_addr_w struct pf_addr_wrap *); int pf_compare_state_keys(struct pf_state_key *, struct pf_state_key *, struct pfi_kif *, u_int); +#ifdef __FreeBSD__ +struct pf_state *pf_find_state(struct pfi_kif *, + struct pf_state_key_cmp *, u_int, struct mbuf *, + struct pf_mtag *); +#else struct pf_state *pf_find_state(struct pfi_kif *, struct pf_state_key_cmp *, u_int, struct mbuf *); +#endif int pf_src_connlimit(struct pf_state **); int pf_check_congestion(struct ifqueue *); +#ifdef __FreeBSD__ + int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); + + extern int pf_end_threads; + + struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; + #else extern struct pool pfr_ktable_pl; extern struct pool pfr_kentry_pl; @@ -230,10 +337,27 @@ struct pf_pool_limit pf_pool_limits[PF_L { &pfr_ktable_pl, PFR_KTABLE_HIWAT }, { &pfr_kentry_pl, PFR_KENTRY_HIWAT } }; +#endif +#ifdef __FreeBSD__ +#define STATE_LOOKUP(i, k, d, s, m, pt) \ + do { \ + s = pf_find_state(i, k, d, m, pt); \ + if (s == NULL || (s)->timeout == PFTM_PURGE) \ + return (PF_DROP); \ + if (d == PF_OUT && \ + (((s)->rule.ptr->rt == PF_ROUTETO && \ + (s)->rule.ptr->direction == PF_OUT) || \ + ((s)->rule.ptr->rt == PF_REPLYTO && \ + (s)->rule.ptr->direction == PF_IN)) && \ + (s)->rt_kif != NULL && \ + (s)->rt_kif != i) \ + return (PF_PASS); \ + } while (0) +#else #define STATE_LOOKUP(i, k, d, s, m) \ do { \ - s = pf_find_state(i, k, d, m); \ + s = pf_find_state(i, k, d, m); \ if (s == NULL || (s)->timeout == PFTM_PURGE) \ return (PF_DROP); \ if (d == PF_OUT && \ @@ -245,6 +369,7 @@ struct pf_pool_limit pf_pool_limits[PF_L (s)->rt_kif != i) \ return (PF_PASS); \ } while (0) +#endif #define BOUND_IFACE(r, k) \ ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all @@ -636,7 +761,11 @@ pf_state_key_attach(struct pf_state_key struct pf_state_key *cur; struct pf_state *olds = NULL; +#ifdef __FreeBSD__ + KASSERT(s->key[idx] == NULL, ("%s: key is null!", __FUNCTION__)); +#else KASSERT(s->key[idx] == NULL); /* XXX handle this? */ +#endif if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) { /* key exists. check for same kif, if none, add to key */ @@ -728,8 +857,12 @@ pf_state_key_detach(struct pf_state *s, RB_REMOVE(pf_state_tree, &pf_statetbl, s->key[idx]); if (s->key[idx]->reverse) s->key[idx]->reverse->reverse = NULL; +#ifdef __FreeBSD__ + /* XXX: implement this */ +#else if (s->key[idx]->inp) s->key[idx]->inp->inp_pf_sk = NULL; +#endif pool_put(&pf_state_key_pl, s->key[idx]); } s->key[idx] = NULL; @@ -754,7 +887,12 @@ pf_state_key_setup(struct pf_pdesc *pd, struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t sport, u_int16_t dport) { +#ifdef __FreeBSD__ + KASSERT((*skp == NULL && *nkp == NULL), + ("%s: skp == NULL && nkp == NULL", __FUNCTION__)); +#else KASSERT((*skp == NULL && *nkp == NULL)); +#endif if ((*skp = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL) return (ENOMEM); @@ -795,7 +933,9 @@ int pf_state_insert(struct pfi_kif *kif, struct pf_state_key *skw, struct pf_state_key *sks, struct pf_state *s) { +#ifndef __FreeBSD__ splassert(IPL_SOFTNET); +#endif s->kif = kif; @@ -878,14 +1018,36 @@ pf_compare_state_keys(struct pf_state_ke } struct pf_state * +#ifdef __FreeBSD__ +pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir, + struct mbuf *m, struct pf_mtag *pftag) +#else pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir, struct mbuf *m) +#endif { struct pf_state_key *sk; struct pf_state_item *si; pf_status.fcounters[FCNT_STATE_SEARCH]++; +#ifdef __FreeBSD__ + if (dir == PF_OUT && pftag->statekey && + ((struct pf_state_key *)pftag->statekey)->reverse) + sk = ((struct pf_state_key *)pftag->statekey)->reverse; + else { + if ((sk = RB_FIND(pf_state_tree, &pf_statetbl, + (struct pf_state_key *)key)) == NULL) + return (NULL); + if (dir == PF_OUT && pftag->statekey && + pf_compare_state_keys(pftag->statekey, sk, + kif, dir) == 0) { + ((struct pf_state_key *) + pftag->statekey)->reverse = sk; + sk->reverse = pftag->statekey; + } + } +#else if (dir == PF_OUT && m->m_pkthdr.pf.statekey && ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse) sk = ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse; @@ -901,9 +1063,14 @@ pf_find_state(struct pfi_kif *kif, struc sk->reverse = m->m_pkthdr.pf.statekey; } } +#endif if (dir == PF_OUT) +#ifdef __FreeBSD__ + pftag->statekey = NULL; +#else m->m_pkthdr.pf.statekey = NULL; +#endif /* list is sorted, if-bound states before floating ones */ TAILQ_FOREACH(si, &sk->states, entry) @@ -949,15 +1116,53 @@ void pf_purge_thread(void *v) { int nloops = 0, s; + #ifdef __FreeBSD__ + int locked; + #endif for (;;) { tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); + #ifdef __FreeBSD__ + sx_slock(&pf_consistency_lock); + PF_LOCK(); + locked = 0; + + if (pf_end_threads) { + PF_UNLOCK(); + sx_sunlock(&pf_consistency_lock); + sx_xlock(&pf_consistency_lock); + PF_LOCK(); + pf_purge_expired_states(pf_status.states, 1); + pf_purge_expired_fragments(); + pf_purge_expired_src_nodes(1); + pf_end_threads++; + + sx_xunlock(&pf_consistency_lock); + PF_UNLOCK(); + wakeup(pf_purge_thread); + kproc_exit(0); + } + #endif s = splsoftnet(); /* process a fraction of the state table every second */ + #ifdef __FreeBSD__ + if(!pf_purge_expired_states(1 + (pf_status.states + / pf_default_rule.timeout[PFTM_INTERVAL]), 0)) { + PF_UNLOCK(); + sx_sunlock(&pf_consistency_lock); + sx_xlock(&pf_consistency_lock); + PF_LOCK(); + locked = 1; + + pf_purge_expired_states(1 + (pf_status.states + / pf_default_rule.timeout[PFTM_INTERVAL]), 1); + } + #else pf_purge_expired_states(1 + (pf_status.states / pf_default_rule.timeout[PFTM_INTERVAL])); +#endif /* purge other expired types every PFTM_INTERVAL seconds */ if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { @@ -967,6 +1172,13 @@ pf_purge_thread(void *v) } splx(s); + #ifdef __FreeBSD__ + PF_UNLOCK(); + if (locked) + sx_xunlock(&pf_consistency_lock); + else + sx_sunlock(&pf_consistency_lock); + #endif } } @@ -983,8 +1195,15 @@ pf_state_expires(const struct pf_state * return (time_second); if (state->timeout == PFTM_UNTIL_PACKET) return (0); + #ifdef __FreeBSD__ + KASSERT(state->timeout != PFTM_UNLINKED, + ("pf_state_expires: timeout == PFTM_UNLINKED")); + KASSERT((state->timeout < PFTM_MAX), + ("pf_state_expires: timeout > PFTM_MAX")); + #else KASSERT(state->timeout != PFTM_UNLINKED); KASSERT(state->timeout < PFTM_MAX); +#endif timeout = state->rule.ptr->timeout[state->timeout]; if (!timeout) timeout = pf_default_rule.timeout[state->timeout]; @@ -1007,8 +1226,13 @@ pf_state_expires(const struct pf_state * return (state->expire + timeout); } + #ifdef __FreeBSD__ + int + pf_purge_expired_src_nodes(int waslocked) + #else void pf_purge_expired_src_nodes(int waslocked) +#endif { struct pf_src_node *cur, *next; int locked = waslocked; @@ -1018,7 +1242,12 @@ pf_purge_expired_src_nodes(int waslocked if (cur->states <= 0 && cur->expire <= time_second) { if (! locked) { + #ifdef __FreeBSD__ + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); + #else rw_enter_write(&pf_consistency_lock); +#endif next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); locked = 1; @@ -1037,7 +1266,14 @@ pf_purge_expired_src_nodes(int waslocked } if (locked && !waslocked) +#ifdef __FreeBSD__ + { + sx_downgrade(&pf_consistency_lock); + } + return (1); +#else rw_exit_write(&pf_consistency_lock); +#endif } void @@ -1072,11 +1308,21 @@ pf_src_tree_remove_state(struct pf_state void pf_unlink_state(struct pf_state *cur) { + #ifdef __FreeBSD__ + if (cur->local_flags & PFSTATE_EXPIRING) + return; + cur->local_flags |= PFSTATE_EXPIRING; +#else splassert(IPL_SOFTNET); + #endif if (cur->src.state == PF_TCPS_PROXY_DST) { /* XXX wire key the right one? */ + #ifdef __FreeBSD__ + pf_send_tcp(NULL, cur->rule.ptr, cur->key[PF_SK_WIRE]->af, + #else pf_send_tcp(cur->rule.ptr, cur->key[PF_SK_WIRE]->af, +#endif &cur->key[PF_SK_WIRE]->addr[1], &cur->key[PF_SK_WIRE]->addr[0], cur->key[PF_SK_WIRE]->port[1], @@ -1102,13 +1348,20 @@ pf_unlink_state(struct pf_state *cur) void pf_free_state(struct pf_state *cur) { +#ifndef __FreeBSD__ splassert(IPL_SOFTNET); +#endif #if NPFSYNC > 0 if (pfsync_state_in_use(cur)) return; #endif + #ifdef __FreeBSD__ + KASSERT(cur->timeout == PFTM_UNLINKED, + ("pf_free_state: cur->timeout != PFTM_UNLINKED")); + #else KASSERT(cur->timeout == PFTM_UNLINKED); +#endif if (--cur->rule.ptr->states_cur <= 0 && cur->rule.ptr->src_nodes <= 0) pf_rm_rule(NULL, cur->rule.ptr); @@ -1129,12 +1382,21 @@ pf_free_state(struct pf_state *cur) pf_status.states--; } + #ifdef __FreeBSD__ + int + pf_purge_expired_states(u_int32_t maxcheck, int waslocked) + #else void pf_purge_expired_states(u_int32_t maxcheck) +#endif { static struct pf_state *cur = NULL; struct pf_state *next; + #ifdef __FreeBSD__ + int locked = waslocked; + #else int locked = 0; +#endif while (maxcheck--) { /* wrap to start of list when we hit the end */ @@ -1150,7 +1412,12 @@ pf_purge_expired_states(u_int32_t maxche if (cur->timeout == PFTM_UNLINKED) { /* free unlinked state */ if (! locked) { + #ifdef __FreeBSD__ + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); + #else rw_enter_write(&pf_consistency_lock); +#endif locked = 1; } pf_free_state(cur); @@ -1158,7 +1425,12 @@ pf_purge_expired_states(u_int32_t maxche /* unlink and free expired state */ pf_unlink_state(cur); if (! locked) { + #ifdef __FreeBSD__ + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); + #else rw_enter_write(&pf_consistency_lock); +#endif locked = 1; } pf_free_state(cur); @@ -1166,8 +1438,15 @@ pf_purge_expired_states(u_int32_t maxche cur = next; } + #ifdef __FreeBSD__ + if (!waslocked && locked) + sx_downgrade(&pf_consistency_lock); + + return (1); + #else if (locked) rw_exit_write(&pf_consistency_lock); +#endif } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910081855.n98ItC5i030359>