Index: contrib/ipfilter/netinet/ip_fil.c =================================================================== RCS file: /home/ncvs/src/sys/contrib/ipfilter/netinet/ip_fil.c,v retrieving revision 1.48 diff -u -r1.48 ip_fil.c --- contrib/ipfilter/netinet/ip_fil.c 27 Aug 2004 20:01:08 -0000 1.48 +++ contrib/ipfilter/netinet/ip_fil.c 24 Sep 2004 19:12:58 -0000 @@ -315,7 +315,8 @@ #if (__FreeBSD_version >= 501108) && defined(_KERNEL) static int -fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir, + struct inpcb *inp) { struct ip *ip = mtod(*mp, struct ip *); return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp); @@ -325,7 +326,8 @@ # include static int -fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir, + struct inpcb *inp) { return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp)); Index: contrib/pf/net/pf.c =================================================================== RCS file: /home/ncvs/src/sys/contrib/pf/net/pf.c,v retrieving revision 1.19 diff -u -r1.19 pf.c --- contrib/pf/net/pf.c 11 Sep 2004 11:18:25 -0000 1.19 +++ contrib/pf/net/pf.c 24 Sep 2004 19:13:01 -0000 @@ -65,6 +65,7 @@ #ifdef __FreeBSD__ #include #include +#include #else #include #endif @@ -185,11 +186,19 @@ int pf_test_tcp(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 inpcb *); +#else struct pf_ruleset **); +#endif int pf_test_udp(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 inpcb *); +#else struct pf_ruleset **); +#endif int pf_test_icmp(struct pf_rule **, struct pf_state **, int, struct pfi_kif *, struct mbuf *, int, void *, struct pf_pdesc *, struct pf_rule **, @@ -229,8 +238,13 @@ struct ifnet *, struct pf_state *); void pf_route6(struct mbuf **, struct pf_rule *, int, struct ifnet *, struct pf_state *); +#ifdef __FreeBSD__ +int pf_socket_lookup(uid_t *, gid_t *, + int, struct pf_pdesc *, struct inpcb *); +#else int pf_socket_lookup(uid_t *, gid_t *, 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, @@ -2183,6 +2197,9 @@ struct pf_rule *r, *rm = NULL, *anchorrule = NULL; struct pf_ruleset *ruleset = NULL; +#ifdef __FreeBSD__ + PF_ASSERT(PF_REF_LOCKED); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); while (r && rm == NULL) { struct pf_rule_addr *src = NULL, *dst = NULL; @@ -2376,7 +2393,12 @@ } int +#ifdef __FreeBSD__ +pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd, + struct inpcb *inp_arg) +#else pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) +#endif { struct pf_addr *saddr, *daddr; u_int16_t sport, dport; @@ -2387,6 +2409,13 @@ #endif struct inpcb *inp; +#ifdef __FreeBSD__ + if (inp_arg != NULL) { + *uid = inp_arg->inp_socket->so_cred->cr_uid; + *gid = inp_arg->inp_socket->so_cred->cr_groups[0]; + return (1); + } +#endif *uid = UID_MAX; *gid = GID_MAX; switch (pd->proto) { @@ -2663,7 +2692,12 @@ int pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, struct pfi_kif *kif, struct mbuf *m, int off, void *h, +#ifdef __FreeBSD__ + struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, + struct inpcb *inp) +#else struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) +#endif { struct pf_rule *nr = NULL; struct pf_addr *saddr = pd->src, *daddr = pd->dst; @@ -2682,6 +2716,9 @@ int tag = -1; u_int16_t mss = tcp_mssdflt; +#ifdef __FreeBSD__ + PF_ADDREF(); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); if (direction == PF_OUT) { @@ -2742,12 +2779,20 @@ else if ((r->flagset & th->th_flags) != r->flags) r = TAILQ_NEXT(r, entries); else if (r->uid.op && (lookup != -1 || (lookup = +#ifdef __FreeBSD__ + pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && +#else pf_socket_lookup(&uid, &gid, direction, pd), 1)) && +#endif !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], uid)) r = TAILQ_NEXT(r, entries); else if (r->gid.op && (lookup != -1 || (lookup = +#ifdef __FreeBSD__ + pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && +#else pf_socket_lookup(&uid, &gid, direction, pd), 1)) && +#endif !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], gid)) r = TAILQ_NEXT(r, entries); @@ -2779,6 +2824,9 @@ r = *rm; a = *am; ruleset = *rsm; +#ifdef __FreeBSD__ + PF_REMREF(r); +#endif REASON_SET(&reason, PFRES_MATCH); @@ -3023,7 +3071,12 @@ int pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, struct pfi_kif *kif, struct mbuf *m, int off, void *h, +#ifdef __FreeBSD__ + struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, + struct inpcb *inp) +#else struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) +#endif { struct pf_rule *nr = NULL; struct pf_addr *saddr = pd->src, *daddr = pd->dst; @@ -3041,6 +3094,9 @@ struct pf_tag *pftag = NULL; int tag = -1; +#ifdef __FreeBSD__ + PF_ADDREF(); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); if (direction == PF_OUT) { @@ -3099,12 +3155,20 @@ else if (r->rule_flag & PFRULE_FRAGMENT) r = TAILQ_NEXT(r, entries); else if (r->uid.op && (lookup != -1 || (lookup = +#ifdef __FreeBSD__ + pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && +#else pf_socket_lookup(&uid, &gid, direction, pd), 1)) && +#endif !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], uid)) r = TAILQ_NEXT(r, entries); else if (r->gid.op && (lookup != -1 || (lookup = +#ifdef __FreeBSD__ + pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && +#else pf_socket_lookup(&uid, &gid, direction, pd), 1)) && +#endif !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], gid)) r = TAILQ_NEXT(r, entries); @@ -3135,6 +3199,9 @@ r = *rm; a = *am; ruleset = *rsm; +#ifdef __FreeBSD__ + PF_REMREF(r); +#endif REASON_SET(&reason, PFRES_MATCH); @@ -3340,6 +3407,9 @@ #endif /* INET6 */ } +#ifdef __FreeBSD__ + PF_ADDREF(); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); if (direction == PF_OUT) { @@ -3442,6 +3512,9 @@ r = *rm; a = *am; ruleset = *rsm; +#ifdef __FreeBSD__ + PF_REMREF(r); +#endif REASON_SET(&reason, PFRES_MATCH); @@ -3587,6 +3660,9 @@ struct pf_tag *pftag = NULL; int tag = -1; +#ifdef __FreeBSD__ + PF_ADDREF(); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); if (direction == PF_OUT) { @@ -3681,6 +3757,9 @@ r = *rm; a = *am; ruleset = *rsm; +#ifdef __FreeBSD__ + PF_REMREF(r); +#endif REASON_SET(&reason, PFRES_MATCH); @@ -3840,6 +3919,9 @@ struct pf_tag *pftag = NULL; int tag = -1; +#ifdef __FreeBSD__ + PF_ADDREF(); +#endif r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); while (r != NULL) { r->evaluations++; @@ -3885,6 +3967,9 @@ r = *rm; a = *am; ruleset = *rsm; +#ifdef __FreeBSD__ + PF_REMREF(r); +#endif REASON_SET(&reason, PFRES_MATCH); @@ -5229,7 +5314,7 @@ if (oifp != ifp) { #ifdef __FreeBSD__ PF_UNLOCK(); - if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) { + if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) { PF_LOCK(); goto bad; } else if (m0 == NULL) { @@ -5519,7 +5604,7 @@ if (oifp != ifp) { #ifdef __FreeBSD__ PF_UNLOCK(); - if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) { + if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) { PF_LOCK(); goto bad; } else if (m0 == NULL) { @@ -5811,7 +5896,11 @@ #ifdef INET int +#ifdef __FreeBSD__ +pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) +#else pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) +#endif { struct pfi_kif *kif; u_short action, reason = 0, log = 0; @@ -5925,8 +6014,13 @@ a = s->anchor.ptr; log = s->log; } else if (s == NULL) +#ifdef __FreeBSD__ + action = pf_test_tcp(&r, &s, dir, kif, + m, off, h, &pd, &a, &ruleset, inp); +#else action = pf_test_tcp(&r, &s, dir, kif, m, off, h, &pd, &a, &ruleset); +#endif break; } @@ -5959,8 +6053,13 @@ a = s->anchor.ptr; log = s->log; } else if (s == NULL) +#ifdef __FreeBSD__ + action = pf_test_udp(&r, &s, dir, kif, + m, off, h, &pd, &a, &ruleset, inp); +#else action = pf_test_udp(&r, &s, dir, kif, m, off, h, &pd, &a, &ruleset); +#endif break; } @@ -6128,6 +6227,8 @@ pf_route(m0, r, dir, ifp, s); #ifdef __FreeBSD__ + if (r->refcount == 0) + pf_rm_rule(NULL, r); PF_UNLOCK(); #endif @@ -6137,7 +6238,11 @@ #ifdef INET6 int +#ifdef __FreeBSD__ +pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) +#else pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) +#endif { struct pfi_kif *kif; u_short action, reason = 0, log = 0; @@ -6274,8 +6379,13 @@ a = s->anchor.ptr; log = s->log; } else if (s == NULL) +#ifdef __FreeBSD__ + action = pf_test_tcp(&r, &s, dir, kif, + m, off, h, &pd, &a, &ruleset, inp); +#else action = pf_test_tcp(&r, &s, dir, kif, m, off, h, &pd, &a, &ruleset); +#endif break; } @@ -6308,8 +6418,13 @@ a = s->anchor.ptr; log = s->log; } else if (s == NULL) +#ifdef __FreeBSD__ + action = pf_test_udp(&r, &s, dir, kif, + m, off, h, &pd, &a, &ruleset, inp); +#else action = pf_test_udp(&r, &s, dir, kif, m, off, h, &pd, &a, &ruleset); +#endif break; } Index: contrib/pf/net/pf_ioctl.c =================================================================== RCS file: /home/ncvs/src/sys/contrib/pf/net/pf_ioctl.c,v retrieving revision 1.15 diff -u -r1.15 pf_ioctl.c --- contrib/pf/net/pf_ioctl.c 17 Sep 2004 02:15:05 -0000 1.15 +++ contrib/pf/net/pf_ioctl.c 24 Sep 2004 19:13:02 -0000 @@ -106,6 +106,7 @@ #include #include #include +#include #include #endif /* __FreeBSD__ */ @@ -182,14 +183,14 @@ * Wrapper functions for pfil(9) hooks */ static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, - int dir); + int dir, struct inpcb *inp); static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, - int dir); + int dir, struct inpcb *inp); #ifdef INET6 static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, - int dir); + int dir, struct inpcb *inp); static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, - int dir); + int dir, struct inpcb *inp); #endif static int hook_pf(void); @@ -204,13 +205,20 @@ .d_version = D_VERSION, }; -static volatile int pf_pfil_hooked = 0; -struct mtx pf_task_mtx; +static volatile int pf_pfil_hooked = 0; +struct mtx pf_task_mtx; +struct cv pf_write_cv; +struct cv pf_read_cv; +int pf_writer_cnt; +int pf_reader_cnt; void init_pf_mutex(void) { mtx_init(&pf_task_mtx, "pf task mtx", NULL, MTX_DEF); + cv_init(&pf_write_cv, "pf exclusive cv"); + cv_init(&pf_read_cv, "pf nonexclusive cv"); + pf_writer_cnt = pf_reader_cnt = 0; } void @@ -300,6 +308,7 @@ TAILQ_INIT(&state_updates); /* default rule should never be garbage collected */ + pf_default_rule.refcount = 1; pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; pf_default_rule.action = PF_PASS; pf_default_rule.nr = -1; @@ -665,13 +674,21 @@ pf_tbladdr_remove(&rule->src.addr); pf_tbladdr_remove(&rule->dst.addr); } +#ifdef __FreeBSD__ + rule->refcount--; +#endif TAILQ_REMOVE(rulequeue, rule, entries); rule->entries.tqe_prev = NULL; rule->nr = -1; } +#ifdef __FreeBSD__ + if (rule->states > 0 || rule->src_nodes > 0 || + rule->entries.tqe_prev != NULL || rule->refcount > 0) +#else if (rule->states > 0 || rule->src_nodes > 0 || rule->entries.tqe_prev != NULL) +#endif return; pf_tag_unref(rule->tag); pf_tag_unref(rule->match_tag); @@ -1024,6 +1041,9 @@ return (EBUSY); /* Swap rules, keep the old. */ +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); old_rules = rs->rules[rs_num].active.ptr; rs->rules[rs_num].active.ptr = @@ -1039,6 +1059,9 @@ rs->rules[rs_num].inactive.open = 0; pf_remove_if_empty_ruleset(rs); pf_update_anchor_rules(); +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); return (0); } @@ -1274,6 +1297,9 @@ rule->kif = NULL; TAILQ_INIT(&rule->rpool.list); /* initialize refcounting */ +#ifdef __FreeBSD__ + rule->refcount = 1; +#endif rule->states = 0; rule->src_nodes = 0; rule->entries.tqe_prev = NULL; @@ -1492,6 +1518,9 @@ bcopy(&pcr->rule, newrule, sizeof(struct pf_rule)); TAILQ_INIT(&newrule->rpool.list); /* initialize refcounting */ +#ifdef __FreeBSD__ + newrule->refcount = 1; +#endif newrule->states = 0; newrule->entries.tqe_prev = NULL; #ifndef INET @@ -1571,6 +1600,9 @@ } pf_empty_pool(&pf_pabuf); +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); if (pcr->action == PF_CHANGE_ADD_HEAD) @@ -1588,6 +1620,9 @@ if (newrule != NULL) pf_rm_rule(NULL, newrule); error = EINVAL; +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -1619,6 +1654,9 @@ pf_update_anchor_rules(); ruleset->rules[rs_num].active.ticket++; +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -2002,11 +2040,17 @@ struct pf_ruleset *ruleset = &pf_main_ruleset; struct pf_rule *rule; +#ifdef __FreeBSD__ + PF_XLOCK(); /* XXX: needed? */ +#endif s = splsoftnet(); TAILQ_FOREACH(rule, ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) rule->evaluations = rule->packets = rule->bytes = 0; +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -2387,6 +2431,9 @@ } } +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); if (pca->action == PF_CHANGE_ADD_HEAD) @@ -2403,6 +2450,9 @@ } if (oldpa == NULL) { error = EINVAL; +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -2428,6 +2478,9 @@ pool->cur = TAILQ_FIRST(&pool->list); PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af); +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -2724,16 +2777,28 @@ case DIOCOSFPADD: { struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); error = pf_osfp_add(io); +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } case DIOCOSFPGET: { struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); error = pf_osfp_get(io); +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; } @@ -3036,8 +3101,14 @@ } case DIOCOSFPFLUSH: +#ifdef __FreeBSD__ + PF_XLOCK(); +#endif s = splsoftnet(); pf_osfp_flush(); +#ifdef __FreeBSD__ + PF_XUNLOCK(); +#endif splx(s); break; @@ -3203,7 +3274,8 @@ } static int -pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) +pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, + struct inpcb *inp) { /* * XXX Wed Jul 9 22:03:16 2003 UTC @@ -3222,7 +3294,7 @@ HTONS(h->ip_len); HTONS(h->ip_off); } - chk = pf_test(PF_IN, ifp, m); + chk = pf_test(PF_IN, ifp, m, inp); if (chk && *m) { m_freem(*m); *m = NULL; @@ -3237,7 +3309,8 @@ } static int -pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) +pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, + struct inpcb *inp) { /* * XXX Wed Jul 9 22:03:16 2003 UTC @@ -3261,7 +3334,7 @@ HTONS(h->ip_len); HTONS(h->ip_off); } - chk = pf_test(PF_OUT, ifp, m); + chk = pf_test(PF_OUT, ifp, m, inp); if (chk && *m) { m_freem(*m); *m = NULL; @@ -3277,14 +3350,15 @@ #ifdef INET6 static int -pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) +pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, + struct inpcb *inp) { /* * IPv6 does not affected ip_len/ip_off byte order changes. */ int chk; - chk = pf_test6(PF_IN, ifp, m); + chk = pf_test6(PF_IN, ifp, m, inp); if (chk && *m) { m_freem(*m); *m = NULL; @@ -3293,7 +3367,8 @@ } static int -pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) +pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, + struct inpcb *inp) { /* * IPv6 does not affected ip_len/ip_off byte order changes. @@ -3305,7 +3380,7 @@ in_delayed_cksum(*m); (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } - chk = pf_test6(PF_OUT, ifp, m); + chk = pf_test6(PF_OUT, ifp, m, inp); if (chk && *m) { m_freem(*m); *m = NULL; Index: contrib/pf/net/pfvar.h =================================================================== RCS file: /home/ncvs/src/sys/contrib/pf/net/pfvar.h,v retrieving revision 1.9 diff -u -r1.9 pfvar.h --- contrib/pf/net/pfvar.h 23 Sep 2004 12:44:40 -0000 1.9 +++ contrib/pf/net/pfvar.h 24 Sep 2004 19:13:03 -0000 @@ -54,6 +54,9 @@ #include struct ip; +#ifdef __FreeBSD__ +struct inpcb; +#endif #define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0) #define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1) @@ -178,26 +181,74 @@ #define UMA_DESTROY(var) \ if(var) uma_zdestroy(var) -extern struct mtx pf_task_mtx; - -#define PF_ASSERT(h) mtx_assert(&pf_task_mtx, (h)) +extern struct mtx pf_task_mtx; +extern struct cv pf_write_cv; +extern struct cv pf_read_cv; +extern int pf_writer_cnt; +extern int pf_reader_cnt; + +#define PF_REF_LOCKED MA_RECURSED +#ifdef INVARIANTS +#define PF_ASSERT(h) do { \ + if ((h) == MA_OWNED || (h) == MA_NOTOWNED) \ + mtx_assert(&pf_task_mtx, (h)); \ + else if ((h) == PF_REF_LOCKED) { \ + mtx_assert(&pf_task_mtx, MA_NOTOWNED); \ + KASSERT(pf_reader_cnt > 0, ("No reference!")); \ + } \ +} while (0); +#else +#define PF_ASSERT(h) +#endif -#define PF_LOCK() do { \ - PF_ASSERT(MA_NOTOWNED); \ - mtx_lock(&pf_task_mtx); \ +#define PF_LOCK() do { \ + PF_ASSERT(MA_NOTOWNED); \ + mtx_lock(&pf_task_mtx); \ } while(0) -#define PF_UNLOCK() do { \ - PF_ASSERT(MA_OWNED); \ - mtx_unlock(&pf_task_mtx); \ +#define PF_UNLOCK() do { \ + PF_ASSERT(MA_OWNED); \ + KASSERT(pf_reader_cnt >= 0, \ + ("UNLOCK after XLOCK!")); \ + mtx_unlock(&pf_task_mtx); \ } while(0) - -#define PF_COPYIN(uaddr, kaddr, len, r) do { \ +#define PF_ADDREF() do { \ + PF_ASSERT(MA_OWNED); \ + while (pf_writer_cnt > 0) \ + cv_wait(&pf_read_cv, &pf_task_mtx); \ + pf_reader_cnt++; \ + PF_UNLOCK(); \ +} while (0) +#define PF_REMREF(r) do { \ + PF_LOCK(); \ + (r)->refcount++; \ + if (--pf_reader_cnt == 0 && pf_writer_cnt > 0) \ + cv_signal(&pf_write_cv); \ + (r)->refcount--; \ +} while (0) +#define PF_XLOCK() do { \ + PF_ASSERT(MA_OWNED); \ + pf_writer_cnt++; \ + if (pf_reader_cnt > 0) \ + cv_wait(&pf_write_cv, &pf_task_mtx); \ + pf_reader_cnt = -1; \ +} while (0) +#define PF_XUNLOCK() do { \ + PF_ASSERT(MA_OWNED); \ + if (--pf_writer_cnt > 0) \ + cv_signal(&pf_write_cv); \ + else { \ + pf_reader_cnt = 0; \ + cv_broadcast(&pf_read_cv); \ + } \ +} while (0) + +#define PF_COPYIN(uaddr, kaddr, len, r) do { \ PF_UNLOCK(); \ r = copyin((uaddr), (kaddr), (len)); \ PF_LOCK(); \ } while(0) -#define PF_COPYOUT(kaddr, uaddr, len, r) do { \ +#define PF_COPYOUT(kaddr, uaddr, len, r) do { \ PF_UNLOCK(); \ r = copyout((kaddr), (uaddr), (len)); \ PF_LOCK(); \ @@ -206,16 +257,16 @@ extern void init_pf_mutex(void); extern void destroy_pf_mutex(void); -#define PF_MODVER 1 -#define PFLOG_MODVER 1 -#define PFSYNC_MODVER 1 - -#define PFLOG_MINVER 1 -#define PFLOG_PREFVER PFLOG_MODVER -#define PFLOG_MAXVER 1 -#define PFSYNC_MINVER 1 -#define PFSYNC_PREFVER PFSYNC_MODVER -#define PFSYNC_MAXVER 1 +#define PF_MODVER 1 +#define PFLOG_MODVER 1 +#define PFSYNC_MODVER 1 + +#define PFLOG_MINVER 1 +#define PFLOG_PREFVER PFLOG_MODVER +#define PFLOG_MAXVER 1 +#define PFSYNC_MINVER 1 +#define PFSYNC_PREFVER PFSYNC_MODVER +#define PFSYNC_MAXVER 1 /* prototyped for pf_subr.c */ struct hook_desc { @@ -570,6 +621,9 @@ pf_osfp_t os_fingerprint; u_int32_t timeout[PFTM_MAX]; +#ifdef __FreeBSD__ + u_int32_t refcount; +#endif u_int32_t states; u_int32_t max_states; u_int32_t src_nodes; @@ -1453,11 +1507,19 @@ struct pf_rule *); #ifdef INET +#ifdef __FreeBSD__ +int pf_test(int, struct ifnet *, struct mbuf **, struct inpcb *); +#else int pf_test(int, struct ifnet *, struct mbuf **); +#endif #endif /* INET */ #ifdef INET6 +#ifdef __FreeBSD__ +int pf_test6(int, struct ifnet *, struct mbuf **, struct inpcb *); +#else int pf_test6(int, struct ifnet *, struct mbuf **); +#endif void pf_poolmask(struct pf_addr *, struct pf_addr*, struct pf_addr *, struct pf_addr *, u_int8_t); void pf_addr_inc(struct pf_addr *, sa_family_t); Index: net/bridge.c =================================================================== RCS file: /home/ncvs/src/sys/net/bridge.c,v retrieving revision 1.83 diff -u -r1.83 bridge.c --- net/bridge.c 27 Aug 2004 15:16:22 -0000 1.83 +++ net/bridge.c 24 Sep 2004 19:13:13 -0000 @@ -1009,7 +1009,7 @@ ip->ip_len = ntohs(ip->ip_len); ip->ip_off = ntohs(ip->ip_off); - if (pfil_run_hooks(&inet_pfil_hook, &m0, src, PFIL_IN) != 0) { + if (pfil_run_hooks(&inet_pfil_hook, &m0, src, PFIL_IN, NULL) != 0) { /* NB: hook should consume packet */ return NULL; } Index: net/pfil.c =================================================================== RCS file: /home/ncvs/src/sys/net/pfil.c,v retrieving revision 1.9 diff -u -r1.9 pfil.c --- net/pfil.c 22 Sep 2004 20:55:56 -0000 1.9 +++ net/pfil.c 24 Sep 2004 19:13:13 -0000 @@ -52,7 +52,7 @@ static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int); static int pfil_list_remove(pfil_list_t *, - int (*)(void *, struct mbuf **, struct ifnet *, int), void *); + int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *); LIST_HEAD(, pfil_head) pfil_head_list = LIST_HEAD_INITIALIZER(&pfil_head_list); @@ -113,7 +113,7 @@ */ int pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, - int dir) + int dir, struct inpcb *inp) { struct packet_filter_hook *pfh; struct mbuf *m = *mp; @@ -126,7 +126,7 @@ for (pfh = pfil_hook_get(dir, ph); pfh != NULL; pfh = TAILQ_NEXT(pfh, pfil_link)) { if (pfh->pfil_func != NULL) { - rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir); + rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp); if (rv != 0 || m == NULL) break; } @@ -233,7 +233,7 @@ * PFIL_WAITOK OK to call malloc with M_WAITOK. */ int -pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int), +pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg, int flags, struct pfil_head *ph) { struct packet_filter_hook *pfh1 = NULL; @@ -305,7 +305,7 @@ * hook list. */ int -pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int), +pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg, int flags, struct pfil_head *ph) { int err = 0; @@ -361,7 +361,7 @@ */ static int pfil_list_remove(pfil_list_t *list, - int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg) + int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg) { struct packet_filter_hook *pfh; Index: net/pfil.h =================================================================== RCS file: /home/ncvs/src/sys/net/pfil.h,v retrieving revision 1.11 diff -u -r1.11 pfil.h --- net/pfil.h 19 Jun 2004 14:58:34 -0000 1.11 +++ net/pfil.h 24 Sep 2004 19:13:13 -0000 @@ -40,6 +40,7 @@ struct mbuf; struct ifnet; +struct inpcb; /* * The packet filter hooks are designed for anything to call them to @@ -47,7 +48,7 @@ */ struct packet_filter_hook { TAILQ_ENTRY(packet_filter_hook) pfil_link; - int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int); + int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *); void *pfil_arg; int pfil_flags; }; @@ -84,12 +85,12 @@ }; int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, - int); + int, struct inpcb *inp); int pfil_add_hook(int (*func)(void *, struct mbuf **, - struct ifnet *, int), void *, int, struct pfil_head *); + struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *); int pfil_remove_hook(int (*func)(void *, struct mbuf **, - struct ifnet *, int), void *, int, struct pfil_head *); + struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *); int pfil_head_register(struct pfil_head *); int pfil_head_unregister(struct pfil_head *); Index: netinet/ip_fastfwd.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fastfwd.c,v retrieving revision 1.20 diff -u -r1.20 ip_fastfwd.c --- netinet/ip_fastfwd.c 13 Sep 2004 17:01:53 -0000 1.20 +++ netinet/ip_fastfwd.c 24 Sep 2004 19:13:14 -0000 @@ -359,7 +359,7 @@ if (inet_pfil_hook.ph_busy_count == -1) goto passin; - if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN) || + if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) || m == NULL) return 1; @@ -437,7 +437,7 @@ if (inet_pfil_hook.ph_busy_count == -1) goto passout; - if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT) || m == NULL) { + if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) { goto consumed; } Index: netinet/ip_fw.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v retrieving revision 1.90 diff -u -r1.90 ip_fw.h --- netinet/ip_fw.h 19 Aug 2004 17:38:47 -0000 1.90 +++ netinet/ip_fw.h 24 Sep 2004 19:13:15 -0000 @@ -425,6 +425,7 @@ struct ipfw_flow_id f_id; /* grabbed from IP header */ u_int32_t retval; + struct inpcb *inp; }; /* @@ -435,8 +436,8 @@ struct sockopt; struct dn_flow_set; -int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int); -int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int); +int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); +int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); int ipfw_chk(struct ip_fw_args *); Index: netinet/ip_fw2.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v retrieving revision 1.76 diff -u -r1.76 ip_fw2.c --- netinet/ip_fw2.c 13 Sep 2004 19:27:23 -0000 1.76 +++ netinet/ip_fw2.c 24 Sep 2004 19:13:16 -0000 @@ -47,6 +47,7 @@ #if IPFW2 #include #include +#include #include #include #include @@ -119,18 +120,54 @@ struct ip_fw *rules; /* list of rules */ struct ip_fw *reap; /* list of rules to reap */ struct mtx mtx; /* lock guarding rule list */ + int busy_count; /* busy count for rw locks */ + int want_write; + struct cv cv; }; #define IPFW_LOCK_INIT(_chain) \ mtx_init(&(_chain)->mtx, "IPFW static rules", NULL, \ MTX_DEF | MTX_RECURSE) #define IPFW_LOCK_DESTROY(_chain) mtx_destroy(&(_chain)->mtx) -#define IPFW_LOCK(_chain) mtx_lock(&(_chain)->mtx) -#define IPFW_UNLOCK(_chain) mtx_unlock(&(_chain)->mtx) -#define IPFW_LOCK_ASSERT(_chain) do { \ +#define IPFW_WLOCK_ASSERT(_chain) do { \ mtx_assert(&(_chain)->mtx, MA_OWNED); \ NET_ASSERT_GIANT(); \ } while (0) +static __inline void +IPFW_RLOCK(struct ip_fw_chain *chain) +{ + mtx_lock(&chain->mtx); + chain->busy_count++; + mtx_unlock(&chain->mtx); +} + +static __inline void +IPFW_RUNLOCK(struct ip_fw_chain *chain) +{ + mtx_lock(&chain->mtx); + chain->busy_count--; + if (chain->busy_count == 0 && chain->want_write) + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); +} + +static __inline void +IPFW_WLOCK(struct ip_fw_chain *chain) +{ + mtx_lock(&chain->mtx); + chain->want_write++; + while (chain->busy_count > 0) + cv_wait(&chain->cv, &chain->mtx); +} + +static __inline void +IPFW_WUNLOCK(struct ip_fw_chain *chain) +{ + chain->want_write--; + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); +} + /* * list of rules for layer 3 */ @@ -1533,20 +1570,47 @@ } static int +fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp) +{ + struct ucred *cr; + + if (inp->inp_socket != NULL) { + cr = inp->inp_socket->so_cred; + ugp->fw_prid = jailed(cr) ? + cr->cr_prison->pr_id : -1; + ugp->fw_uid = cr->cr_uid; + ugp->fw_ngroups = cr->cr_ngroups; + bcopy(cr->cr_groups, ugp->fw_groups, + sizeof(ugp->fw_groups)); + } + return (0); +} + +static int check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif, struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip, u_int16_t src_port, - struct ip_fw_ugid *ugp, int *lookup) + struct ip_fw_ugid *ugp, int *lookup, struct inpcb *inp) { struct inpcbinfo *pi; int wildcard; struct inpcb *pcb; int match; - struct ucred *cr; gid_t *gp; /* + * Check to see if the UDP or TCP stack supplied us with + * the PCB. If so, rather then holding a lock and looking + * up the PCB, we can use the one that was supplied. + */ + if (inp && *lookup == 0) { + if (inp->inp_socket != NULL) { + fill_ugid_cache(inp, ugp); + *lookup = 1; + } + } + /* * If we have already been here and the packet has no * PCB entry associated with it, then we can safely * assume that this is a no match. @@ -1563,7 +1627,7 @@ return 0; match = 0; if (*lookup == 0) { - INP_INFO_RLOCK(pi); /* XXX LOR with IPFW */ + INP_INFO_RLOCK(pi); pcb = (oif) ? in_pcblookup_hash(pi, dst_ip, htons(dst_port), @@ -1576,13 +1640,7 @@ if (pcb != NULL) { INP_LOCK(pcb); if (pcb->inp_socket != NULL) { - cr = pcb->inp_socket->so_cred; - ugp->fw_prid = jailed(cr) ? - cr->cr_prison->pr_id : -1; - ugp->fw_uid = cr->cr_uid; - ugp->fw_ngroups = cr->cr_ngroups; - bcopy(cr->cr_groups, ugp->fw_groups, - sizeof(ugp->fw_groups)); + fill_ugid_cache(pcb, ugp); *lookup = 1; } INP_UNLOCK(pcb); @@ -1821,7 +1879,7 @@ args->f_id.dst_port = dst_port = ntohs(dst_port); after_ip_checks: - IPFW_LOCK(chain); /* XXX expensive? can we run lock free? */ + IPFW_RLOCK(chain); mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL); if (args->rule) { /* @@ -1833,7 +1891,7 @@ * the caller. */ if (fw_one_pass) { - IPFW_UNLOCK(chain); /* XXX optimize */ + IPFW_RUNLOCK(chain); return 0; } @@ -1850,13 +1908,13 @@ f = chain->rules; if (args->eh == NULL && skipto != 0) { if (skipto >= IPFW_DEFAULT_RULE) { - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); return(IP_FW_PORT_DENY_FLAG); /* invalid */ } while (f && f->rulenum <= skipto) f = f->next; if (f == NULL) { /* drop packet */ - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); return(IP_FW_PORT_DENY_FLAG); } } @@ -1932,13 +1990,13 @@ if (offset!=0) break; if (proto == IPPROTO_TCP || - proto == IPPROTO_UDP) + proto == IPPROTO_UDP) match = check_uidgid( (ipfw_insn_u32 *)cmd, proto, oif, dst_ip, dst_port, src_ip, src_port, &fw_ugid_cache, - &ugid_lookup); + &ugid_lookup, args->inp); break; case O_RECV: @@ -2344,7 +2402,7 @@ if (mtag == NULL) { /* XXX statistic */ /* drop packet */ - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); return IP_FW_PORT_DENY_FLAG; } dt = (struct divert_tag *)(mtag+1); @@ -2420,7 +2478,7 @@ } /* end of outer for, scan rules */ printf("ipfw: ouch!, skip past end of rules, denying packet\n"); - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); return(IP_FW_PORT_DENY_FLAG); done: @@ -2428,7 +2486,7 @@ f->pcnt++; f->bcnt += pktlen; f->timestamp = time_second; - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); return retval; pullup_failed: @@ -2446,7 +2504,7 @@ { struct ip_fw *rule; - IPFW_LOCK_ASSERT(chain); + IPFW_WLOCK_ASSERT(chain); for (rule = chain->rules; rule; rule = rule->next) rule->next_rule = NULL; @@ -2461,7 +2519,7 @@ { struct ip_fw *rule; - IPFW_LOCK(&layer3_chain); + IPFW_WLOCK(&layer3_chain); for (rule = layer3_chain.rules; rule; rule = rule->next) { ipfw_insn_pipe *cmd = (ipfw_insn_pipe *)ACTION_PTR(rule); @@ -2477,7 +2535,7 @@ !bcmp(&cmd->pipe_ptr, &match, sizeof(match)) ) bzero(&cmd->pipe_ptr, sizeof(cmd->pipe_ptr)); } - IPFW_UNLOCK(&layer3_chain); + IPFW_WUNLOCK(&layer3_chain); } /* @@ -2507,8 +2565,7 @@ rule->bcnt = 0; rule->timestamp = 0; - IPFW_LOCK(chain); - + IPFW_WLOCK(chain); if (chain->rules == NULL) { /* default rule */ chain->rules = rule; goto done; @@ -2555,7 +2612,7 @@ done: static_count++; static_len += l; - IPFW_UNLOCK(chain); + IPFW_WUNLOCK(chain); DEB(printf("ipfw: installed rule %d, static count now %d\n", rule->rulenum, static_count);) return (0); @@ -2575,7 +2632,7 @@ struct ip_fw *n; int l = RULESIZE(rule); - IPFW_LOCK_ASSERT(chain); + IPFW_WLOCK_ASSERT(chain); n = rule->next; IPFW_DYN_LOCK(); @@ -2621,7 +2678,7 @@ { struct ip_fw *prev, *rule; - IPFW_LOCK_ASSERT(chain); + IPFW_WLOCK_ASSERT(chain); flush_rule_ptrs(chain); /* more efficient to do outside the loop */ for (prev = NULL, rule = chain->rules; rule ; ) @@ -2669,7 +2726,7 @@ return EINVAL; } - IPFW_LOCK(chain); + IPFW_WLOCK(chain); rule = chain->rules; chain->reap = NULL; switch (cmd) { @@ -2680,7 +2737,7 @@ for (; rule->rulenum < rulenum; prev = rule, rule = rule->next) ; if (rule->rulenum != rulenum) { - IPFW_UNLOCK(chain); + IPFW_WUNLOCK(chain); return EINVAL; } @@ -2733,7 +2790,7 @@ */ rule = chain->reap; chain->reap = NULL; - IPFW_UNLOCK(chain); + IPFW_WUNLOCK(chain); if (rule) reap_rules(rule); return 0; @@ -2768,7 +2825,7 @@ struct ip_fw *rule; char *msg; - IPFW_LOCK(chain); + IPFW_WLOCK(chain); if (rulenum == 0) { norule_counter = 0; for (rule = chain->rules; rule; rule = rule->next) @@ -2791,13 +2848,13 @@ break; } if (!cleared) { /* we did not find any matching rules */ - IPFW_UNLOCK(chain); + IPFW_WUNLOCK(chain); return (EINVAL); } msg = log_only ? "ipfw: Entry %d logging count reset.\n" : "ipfw: Entry %d cleared.\n"; } - IPFW_UNLOCK(chain); + IPFW_WUNLOCK(chain); if (fw_verbose) log(LOG_SECURITY | LOG_NOTICE, msg, rulenum); @@ -3023,7 +3080,7 @@ int i; /* XXX this can take a long time and locking will block packet flow */ - IPFW_LOCK(chain); + IPFW_RLOCK(chain); for (rule = chain->rules; rule ; rule = rule->next) { /* * Verify the entry fits in the buffer in case the @@ -3039,7 +3096,7 @@ bp += i; } } - IPFW_UNLOCK(chain); + IPFW_RUNLOCK(chain); if (ipfw_dyn_v) { ipfw_dyn_rule *p, *last = NULL; @@ -3150,11 +3207,11 @@ * the old list without the need for a lock. */ - IPFW_LOCK(&layer3_chain); + IPFW_WLOCK(&layer3_chain); layer3_chain.reap = NULL; free_chain(&layer3_chain, 0 /* keep default rule */); rule = layer3_chain.reap, layer3_chain.reap = NULL; - IPFW_UNLOCK(&layer3_chain); + IPFW_WUNLOCK(&layer3_chain); if (layer3_chain.reap != NULL) reap_rules(rule); break; @@ -3358,6 +3415,9 @@ int error; layer3_chain.rules = NULL; + layer3_chain.want_write = 0; + layer3_chain.busy_count = 0; + cv_init(&layer3_chain.cv, "Condition variable for IPFW rw locks"); IPFW_LOCK_INIT(&layer3_chain); IPFW_DYN_LOCK_INIT(); callout_init(&ipfw_timeout, debug_mpsafenet ? CALLOUT_MPSAFE : 0); @@ -3431,11 +3491,11 @@ ip_fw_chk_ptr = NULL; ip_fw_ctl_ptr = NULL; callout_drain(&ipfw_timeout); - IPFW_LOCK(&layer3_chain); + IPFW_WLOCK(&layer3_chain); layer3_chain.reap = NULL; free_chain(&layer3_chain, 1 /* kill default rule */); reap = layer3_chain.reap, layer3_chain.reap = NULL; - IPFW_UNLOCK(&layer3_chain); + IPFW_WUNLOCK(&layer3_chain); if (reap != NULL) reap_rules(reap); flush_tables(); Index: netinet/ip_fw_pfil.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw_pfil.c,v retrieving revision 1.9 diff -u -r1.9 ip_fw_pfil.c --- netinet/ip_fw_pfil.c 13 Sep 2004 19:20:14 -0000 1.9 +++ netinet/ip_fw_pfil.c 24 Sep 2004 19:13:16 -0000 @@ -73,7 +73,8 @@ static int ipfw_divert(struct mbuf **, int, int); int -ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) +ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, + struct inpcb *inp) { struct ip_fw_args args; struct m_tag *dn_tag; @@ -102,6 +103,7 @@ again: args.m = *m0; + args.inp = inp; ipfw = ipfw_chk(&args); *m0 = args.m; @@ -156,7 +158,8 @@ } int -ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) +ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, + struct inpcb *inp) { struct ip_fw_args args; struct m_tag *dn_tag; @@ -186,6 +189,7 @@ again: args.m = *m0; args.oif = ifp; + args.inp = inp; ipfw = ipfw_chk(&args); *m0 = args.m; Index: netinet/ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.290 diff -u -r1.290 ip_input.c --- netinet/ip_input.c 24 Sep 2004 12:18:40 -0000 1.290 +++ netinet/ip_input.c 24 Sep 2004 19:13:17 -0000 @@ -437,7 +437,7 @@ odst = ip->ip_dst; if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, - PFIL_IN) != 0) + PFIL_IN, NULL) != 0) return; if (m == NULL) /* consumed by filter */ return; Index: netinet/ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.231 diff -u -r1.231 ip_output.c --- netinet/ip_output.c 13 Sep 2004 17:09:06 -0000 1.231 +++ netinet/ip_output.c 24 Sep 2004 19:13:18 -0000 @@ -662,7 +662,7 @@ /* Run through list of hooks for output packets. */ odst.s_addr = ip->ip_dst.s_addr; - error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT); + error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, inp); if (error != 0 || m == NULL) goto done; Index: netinet6/ip6_forward.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/ip6_forward.c,v retrieving revision 1.26 diff -u -r1.26 ip6_forward.c --- netinet6/ip6_forward.c 27 Aug 2004 15:16:23 -0000 1.26 +++ netinet6/ip6_forward.c 24 Sep 2004 19:13:19 -0000 @@ -580,7 +580,7 @@ goto pass; /* Run through list of hooks for output packets. */ - error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT); + error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL); if (error != 0) goto senderr; if (m == NULL) Index: netinet6/ip6_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.77 diff -u -r1.77 ip6_input.c --- netinet6/ip6_input.c 27 Aug 2004 15:16:23 -0000 1.77 +++ netinet6/ip6_input.c 24 Sep 2004 19:13:19 -0000 @@ -424,7 +424,7 @@ if (inet6_pfil_hook.ph_busy_count == -1) goto passin; - if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN)) + if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL)) return; if (m == NULL) /* consumed by filter */ return; Index: netinet6/ip6_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/ip6_output.c,v retrieving revision 1.83 diff -u -r1.83 ip6_output.c --- netinet6/ip6_output.c 27 Aug 2004 15:16:23 -0000 1.83 +++ netinet6/ip6_output.c 24 Sep 2004 19:13:21 -0000 @@ -938,7 +938,7 @@ goto passout; /* Run through list of hooks for output packets. */ - error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT); + error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT, inp); if (error != 0 || m == NULL) goto done; ip6 = mtod(m, struct ip6_hdr *);