From bfcdaa5766cd2558e85b308bf78cd45dd8af5654 Mon Sep 17 00:00:00 2001 From: itojun Date: Tue, 22 Jun 2004 14:17:07 +0000 Subject: [PATCH] PF from openbsd 3.5. missing features: - pfsync (due to protocol # assignment issues) - carp (not really a PF portion, but thought important to mention) - PF and ALTQ are mutually-exclusive. this will be sorted out when kjc@csl.sony.co.jp updates ALTQ and PF (and API inbetween) reviewed by matt, christos, perry torture-test is very welcomed. --- sys/conf/files | 3 +- sys/dist/pf/net/if_pflog.c | 13 + sys/dist/pf/net/if_pflog.h | 1 + sys/dist/pf/net/if_pfsync.c | 1243 ----------------------------------- sys/dist/pf/net/if_pfsync.h | 280 -------- sys/dist/pf/net/pf.c | 219 ++++-- sys/dist/pf/net/pf_if.c | 98 +++ sys/dist/pf/net/pf_ioctl.c | 213 ++++++ sys/dist/pf/net/pf_norm.c | 30 +- sys/dist/pf/net/pf_osfp.c | 5 + sys/dist/pf/net/pf_table.c | 40 +- sys/dist/pf/net/pfvar.h | 28 + 12 files changed, 590 insertions(+), 1583 deletions(-) delete mode 100644 sys/dist/pf/net/if_pfsync.c delete mode 100644 sys/dist/pf/net/if_pfsync.h diff --git a/sys/conf/files b/sys/conf/files index bd797fb7f100..64ca228c47cb 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.676 2004/06/18 15:02:29 christos Exp $ +# $NetBSD: files,v 1.677 2004/06/22 14:17:07 itojun Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -127,6 +127,7 @@ include "netiso/files.netiso" include "netnatm/files.netnatm" include "netns/files.netns" include "netsmb/files.netsmb" +include "net/files.pf" defflag IPX # IPX network stack defflag PFIL_HOOKS # pfil(9) diff --git a/sys/dist/pf/net/if_pflog.c b/sys/dist/pf/net/if_pflog.c index 3b93226a439e..52d82280de77 100644 --- a/sys/dist/pf/net/if_pflog.c +++ b/sys/dist/pf/net/if_pflog.c @@ -1,3 +1,4 @@ +/* $NetBSD: if_pflog.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */ /* $OpenBSD: if_pflog.c,v 1.11 2003/12/31 11:18:25 cedric Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -33,6 +34,10 @@ * PURPOSE. */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#endif + #include "bpfilter.h" #include "pflog.h" @@ -106,8 +111,12 @@ pflogattach(int npflog) if_alloc_sadl(ifp); #if NBPFILTER > 0 +#ifdef __OpenBSD__ bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN); +#else + bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN); +#endif #endif } } @@ -122,7 +131,11 @@ pflogstart(struct ifnet *ifp) int s; for (;;) { +#ifdef __OpenBSD__ s = splimp(); +#else + s = splnet(); +#endif IF_DROP(&ifp->if_snd); IF_DEQUEUE(&ifp->if_snd, m); splx(s); diff --git a/sys/dist/pf/net/if_pflog.h b/sys/dist/pf/net/if_pflog.h index e4e603e37303..9c94cdd2c643 100644 --- a/sys/dist/pf/net/if_pflog.h +++ b/sys/dist/pf/net/if_pflog.h @@ -1,3 +1,4 @@ +/* $NetBSD: if_pflog.h,v 1.2 2004/06/22 14:17:07 itojun Exp $ */ /* $OpenBSD: if_pflog.h,v 1.10 2004/03/19 04:52:04 frantzen Exp $ */ /* * Copyright 2001 Niels Provos diff --git a/sys/dist/pf/net/if_pfsync.c b/sys/dist/pf/net/if_pfsync.c deleted file mode 100644 index e4840ff32d97..000000000000 --- a/sys/dist/pf/net/if_pfsync.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* $OpenBSD: if_pfsync.c,v 1.26 2004/03/28 18:14:20 mcbride Exp $ */ - -/* - * Copyright (c) 2002 Michael Shalayeff - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bpfilter.h" -#include "pfsync.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef INET -#include -#include -#include -#include -#include -#endif - -#ifdef INET6 -#ifndef INET -#include -#endif -#include -#endif /* INET6 */ - -#include -#include - -#define PFSYNC_MINMTU \ - (sizeof(struct pfsync_header) + sizeof(struct pf_state)) - -#ifdef PFSYNCDEBUG -#define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0) -int pfsyncdebug; -#else -#define DPRINTF(x) -#endif - -struct pfsync_softc pfsyncif; -int pfsync_sync_ok; -struct pfsyncstats pfsyncstats; - -void pfsyncattach(int); -void pfsync_setmtu(struct pfsync_softc *, int); -int pfsync_insert_net_state(struct pfsync_state *); -int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, - struct rtentry *); -int pfsyncioctl(struct ifnet *, u_long, caddr_t); -void pfsyncstart(struct ifnet *); - -struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **); -int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *); -int pfsync_sendout(struct pfsync_softc *); -void pfsync_timeout(void *); -void pfsync_send_bus(struct pfsync_softc *, u_int8_t); -void pfsync_bulk_update(void *); -void pfsync_bulkfail(void *); - -extern int ifqmaxlen; -extern struct timeval time; -extern struct timeval mono_time; -extern int hz; - -void -pfsyncattach(int npfsync) -{ - struct ifnet *ifp; - - pfsync_sync_ok = 1; - bzero(&pfsyncif, sizeof(pfsyncif)); - pfsyncif.sc_mbuf = NULL; - pfsyncif.sc_mbuf_net = NULL; - pfsyncif.sc_statep.s = NULL; - pfsyncif.sc_statep_net.s = NULL; - pfsyncif.sc_maxupdates = 128; - pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; - pfsyncif.sc_ureq_received = 0; - pfsyncif.sc_ureq_sent = 0; - ifp = &pfsyncif.sc_if; - strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname); - ifp->if_softc = &pfsyncif; - ifp->if_ioctl = pfsyncioctl; - ifp->if_output = pfsyncoutput; - ifp->if_start = pfsyncstart; - ifp->if_type = IFT_PFSYNC; - ifp->if_snd.ifq_maxlen = ifqmaxlen; - ifp->if_hdrlen = PFSYNC_HDRLEN; - pfsync_setmtu(&pfsyncif, MCLBYTES); - timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif); - timeout_set(&pfsyncif.sc_bulk_tmo, pfsync_bulk_update, &pfsyncif); - timeout_set(&pfsyncif.sc_bulkfail_tmo, pfsync_bulkfail, &pfsyncif); - if_attach(ifp); - if_alloc_sadl(ifp); - -#if NBPFILTER > 0 - bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); -#endif -} - -/* - * Start output on the pfsync interface. - */ -void -pfsyncstart(struct ifnet *ifp) -{ - struct mbuf *m; - int s; - - for (;;) { - s = splimp(); - IF_DROP(&ifp->if_snd); - IF_DEQUEUE(&ifp->if_snd, m); - splx(s); - - if (m == NULL) - return; - else - m_freem(m); - } -} - -int -pfsync_insert_net_state(struct pfsync_state *sp) -{ - struct pf_state *st = NULL; - struct pf_rule *r = NULL; - struct pfi_kif *kif; - - if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) { - printf("pfsync_insert_net_state: invalid creator id:" - " %08x\n", ntohl(sp->creatorid)); - return (EINVAL); - } - - kif = pfi_lookup_create(sp->ifname); - if (kif == NULL) { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_insert_net_state: " - "unknown interface: %s\n", sp->ifname); - /* skip this state */ - return (0); - } - - /* - * Just use the default rule until we have infrastructure to find the - * best matching rule. - */ - r = &pf_default_rule; - - if (!r->max_states || r->states < r->max_states) - st = pool_get(&pf_state_pl, PR_NOWAIT); - if (st == NULL) { - pfi_maybe_destroy(kif); - return (ENOMEM); - } - bzero(st, sizeof(*st)); - - st->rule.ptr = r; - /* XXX get pointers to nat_rule and anchor */ - - /* fill in the rest of the state entry */ - pf_state_host_ntoh(&sp->lan, &st->lan); - pf_state_host_ntoh(&sp->gwy, &st->gwy); - pf_state_host_ntoh(&sp->ext, &st->ext); - - pf_state_peer_ntoh(&sp->src, &st->src); - pf_state_peer_ntoh(&sp->dst, &st->dst); - - bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); - st->creation = ntohl(sp->creation) + time.tv_sec; - st->expire = ntohl(sp->expire) + time.tv_sec; - - st->af = sp->af; - st->proto = sp->proto; - st->direction = sp->direction; - st->log = sp->log; - st->timeout = sp->timeout; - st->allow_opts = sp->allow_opts; - - bcopy(sp->id, &st->id, sizeof(st->id)); - st->creatorid = sp->creatorid; - st->sync_flags = sp->sync_flags | PFSTATE_FROMSYNC; - - - if (pf_insert_state(kif, st)) { - pfi_maybe_destroy(kif); - pool_put(&pf_state_pl, st); - return (EINVAL); - } - - return (0); -} - -void -pfsync_input(struct mbuf *m, ...) -{ - struct ip *ip = mtod(m, struct ip *); - struct pfsync_header *ph; - struct pfsync_softc *sc = &pfsyncif; - struct pf_state *st, key; - struct pfsync_state *sp; - struct pfsync_state_upd *up; - struct pfsync_state_del *dp; - struct pfsync_state_clr *cp; - struct pfsync_state_upd_req *rup; - struct pfsync_state_bus *bus; - struct in_addr src; - struct mbuf *mp; - int iplen, action, error, i, s, count, offp; - - pfsyncstats.pfsyncs_ipackets++; - - /* verify that we have a sync interface configured */ - if (!sc->sc_sync_ifp || !pf_status.running) - goto done; - - /* verify that the packet came in on the right interface */ - if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) { - pfsyncstats.pfsyncs_badif++; - goto done; - } - - /* verify that the IP TTL is 255. */ - if (ip->ip_ttl != PFSYNC_DFLTTL) { - pfsyncstats.pfsyncs_badttl++; - goto done; - } - - iplen = ip->ip_hl << 2; - - if (m->m_pkthdr.len < iplen + sizeof(*ph)) { - pfsyncstats.pfsyncs_hdrops++; - goto done; - } - - if (iplen + sizeof(*ph) > m->m_len) { - if ((m = m_pullup(m, iplen + sizeof(*ph))) == NULL) { - pfsyncstats.pfsyncs_hdrops++; - goto done; - } - ip = mtod(m, struct ip *); - } - ph = (struct pfsync_header *)((char *)ip + iplen); - - /* verify the version */ - if (ph->version != PFSYNC_VERSION) { - pfsyncstats.pfsyncs_badver++; - goto done; - } - - action = ph->action; - count = ph->count; - - /* make sure it's a valid action code */ - if (action >= PFSYNC_ACT_MAX) { - pfsyncstats.pfsyncs_badact++; - goto done; - } - - /* Cheaper to grab this now than having to mess with mbufs later */ - src = ip->ip_src; - - switch (action) { - case PFSYNC_ACT_CLR: { - struct pfi_kif *kif; - u_int32_t creatorid; - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - sizeof(*cp), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - cp = (struct pfsync_state_clr *)(mp->m_data + offp); - creatorid = cp->creatorid; - - s = splsoftnet(); - if (cp->ifname[0] == '\0') { - RB_FOREACH(st, pf_state_tree_id, &tree_id) { - if (st->creatorid == creatorid) - st->timeout = PFTM_PURGE; - } - } else { - kif = pfi_lookup_if(cp->ifname); - if (kif == NULL) { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_input: PFSYNC_ACT_CLR " - "bad interface: %s\n", cp->ifname); - splx(s); - goto done; - } - RB_FOREACH(st, pf_state_tree_lan_ext, - &kif->pfik_lan_ext) { - if (st->creatorid == creatorid) - st->timeout = PFTM_PURGE; - } - } - pf_purge_expired_states(); - splx(s); - - break; - } - case PFSYNC_ACT_INS: - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*sp), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); - i < count; i++, sp++) { - /* check for invalid values */ - if (sp->timeout >= PFTM_MAX || - sp->src.state > PF_TCPS_PROXY_DST || - sp->dst.state > PF_TCPS_PROXY_DST || - sp->direction > PF_OUT || - (sp->af != AF_INET && sp->af != AF_INET6)) { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_insert: PFSYNC_ACT_INS: " - "invalid value\n"); - pfsyncstats.pfsyncs_badstate++; - continue; - } - - if ((error = pfsync_insert_net_state(sp))) { - if (error == ENOMEM) { - splx(s); - goto done; - } - continue; - } - } - splx(s); - break; - case PFSYNC_ACT_UPD: - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*sp), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); - i < count; i++, sp++) { - /* check for invalid values */ - if (sp->timeout >= PFTM_MAX || - sp->src.state > PF_TCPS_PROXY_DST || - sp->dst.state > PF_TCPS_PROXY_DST) { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_insert: PFSYNC_ACT_UPD: " - "invalid value\n"); - pfsyncstats.pfsyncs_badstate++; - continue; - } - - bcopy(sp->id, &key.id, sizeof(key.id)); - key.creatorid = sp->creatorid; - - st = pf_find_state_byid(&key); - if (st == NULL) { - /* insert the update */ - if (pfsync_insert_net_state(sp)) - pfsyncstats.pfsyncs_badstate++; - continue; - } - pf_state_peer_ntoh(&sp->src, &st->src); - pf_state_peer_ntoh(&sp->dst, &st->dst); - st->expire = ntohl(sp->expire) + time.tv_sec; - st->timeout = sp->timeout; - - } - splx(s); - break; - /* - * It's not strictly necessary for us to support the "uncompressed" - * delete action, but it's relatively simple and maintains consistency. - */ - case PFSYNC_ACT_DEL: - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*sp), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); - i < count; i++, sp++) { - bcopy(sp->id, &key.id, sizeof(key.id)); - key.creatorid = sp->creatorid; - - st = pf_find_state_byid(&key); - if (st == NULL) { - pfsyncstats.pfsyncs_badstate++; - continue; - } - /* - * XXX - * pf_purge_expired_states() is expensive, - * we really want to purge the state directly. - */ - st->timeout = PFTM_PURGE; - st->sync_flags |= PFSTATE_FROMSYNC; - } - pf_purge_expired_states(); - splx(s); - break; - case PFSYNC_ACT_UPD_C: { - int update_requested = 0; - - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*up), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - for (i = 0, up = (struct pfsync_state_upd *)(mp->m_data + offp); - i < count; i++, up++) { - /* check for invalid values */ - if (up->timeout >= PFTM_MAX || - up->src.state > PF_TCPS_PROXY_DST || - up->dst.state > PF_TCPS_PROXY_DST) { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_insert: " - "PFSYNC_ACT_UPD_C: " - "invalid value\n"); - pfsyncstats.pfsyncs_badstate++; - continue; - } - - bcopy(up->id, &key.id, sizeof(key.id)); - key.creatorid = up->creatorid; - - st = pf_find_state_byid(&key); - if (st == NULL) { - /* We don't have this state. Ask for it. */ - pfsync_request_update(up, &src); - update_requested = 1; - pfsyncstats.pfsyncs_badstate++; - continue; - } - pf_state_peer_ntoh(&up->src, &st->src); - pf_state_peer_ntoh(&up->dst, &st->dst); - st->expire = ntohl(up->expire) + time.tv_sec; - st->timeout = up->timeout; - } - if (update_requested) - pfsync_sendout(sc); - splx(s); - break; - } - case PFSYNC_ACT_DEL_C: - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*dp), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp); - i < count; i++, dp++) { - bcopy(dp->id, &key.id, sizeof(key.id)); - key.creatorid = dp->creatorid; - - st = pf_find_state_byid(&key); - if (st == NULL) { - pfsyncstats.pfsyncs_badstate++; - continue; - } - /* - * XXX - * pf_purge_expired_states() is expensive, - * we really want to purge the state directly. - */ - st->timeout = PFTM_PURGE; - st->sync_flags |= PFSTATE_FROMSYNC; - } - pf_purge_expired_states(); - splx(s); - break; - case PFSYNC_ACT_INS_F: - case PFSYNC_ACT_DEL_F: - /* not implemented */ - break; - case PFSYNC_ACT_UREQ: - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - count * sizeof(*rup), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - - s = splsoftnet(); - /* XXX send existing. pfsync_pack_state should handle this. */ - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - for (i = 0, - rup = (struct pfsync_state_upd_req *)(mp->m_data + offp); - i < count; i++, rup++) { - bcopy(rup->id, &key.id, sizeof(key.id)); - key.creatorid = rup->creatorid; - - if (key.id == 0 && key.creatorid == 0) { - sc->sc_ureq_received = mono_time.tv_sec; - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: received " - "bulk update request\n"); - pfsync_send_bus(sc, PFSYNC_BUS_START); - timeout_add(&sc->sc_bulk_tmo, 1 * hz); - } else { - st = pf_find_state_byid(&key); - if (st == NULL) { - pfsyncstats.pfsyncs_badstate++; - continue; - } - pfsync_pack_state(PFSYNC_ACT_UPD, st, 0); - } - } - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - splx(s); - break; - case PFSYNC_ACT_BUS: - /* If we're not waiting for a bulk update, who cares. */ - if (sc->sc_ureq_sent == 0) - break; - - if ((mp = m_pulldown(m, iplen + sizeof(*ph), - sizeof(*bus), &offp)) == NULL) { - pfsyncstats.pfsyncs_badlen++; - return; - } - bus = (struct pfsync_state_bus *)(mp->m_data + offp); - switch (bus->status) { - case PFSYNC_BUS_START: - timeout_add(&sc->sc_bulkfail_tmo, - pf_pool_limits[PF_LIMIT_STATES].limit / - (PFSYNC_BULKPACKETS * sc->sc_maxcount)); - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: received bulk " - "update start\n"); - break; - case PFSYNC_BUS_END: - if (mono_time.tv_sec - ntohl(bus->endtime) >= - sc->sc_ureq_sent) { - /* that's it, we're happy */ - sc->sc_ureq_sent = 0; - sc->sc_bulk_tries = 0; - timeout_del(&sc->sc_bulkfail_tmo); - pfsync_sync_ok = 1; - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: received valid " - "bulk update end\n"); - } else { - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: received invalid " - "bulk update end: bad timestamp\n"); - } - break; - } - break; - } - -done: - if (m) - m_freem(m); -} - -int -pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, - struct rtentry *rt) -{ - m_freem(m); - return (0); -} - -/* ARGSUSED */ -int -pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct proc *p = curproc; - struct pfsync_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct ip_moptions *imo = &sc->sc_imo; - struct pfsyncreq pfsyncr; - struct ifnet *sifp; - int s, error; - - switch (cmd) { - case SIOCSIFADDR: - case SIOCAIFADDR: - case SIOCSIFDSTADDR: - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) - ifp->if_flags |= IFF_RUNNING; - else - ifp->if_flags &= ~IFF_RUNNING; - break; - case SIOCSIFMTU: - if (ifr->ifr_mtu < PFSYNC_MINMTU) - return (EINVAL); - if (ifr->ifr_mtu > MCLBYTES) - ifr->ifr_mtu = MCLBYTES; - s = splnet(); - if (ifr->ifr_mtu < ifp->if_mtu) - pfsync_sendout(sc); - pfsync_setmtu(sc, ifr->ifr_mtu); - splx(s); - break; - case SIOCGETPFSYNC: - bzero(&pfsyncr, sizeof(pfsyncr)); - if (sc->sc_sync_ifp) - strlcpy(pfsyncr.pfsyncr_syncif, - sc->sc_sync_ifp->if_xname, IFNAMSIZ); - pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; - if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)))) - return (error); - break; - case SIOCSETPFSYNC: - if ((error = suser(p, p->p_acflag)) != 0) - return (error); - if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr)))) - return (error); - - if (pfsyncr.pfsyncr_maxupdates > 255) - return (EINVAL); - sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates; - - if (pfsyncr.pfsyncr_syncif[0] == 0) { - sc->sc_sync_ifp = NULL; - if (sc->sc_mbuf_net != NULL) { - /* Don't keep stale pfsync packets around. */ - s = splnet(); - m_freem(sc->sc_mbuf_net); - sc->sc_mbuf_net = NULL; - sc->sc_statep_net.s = NULL; - splx(s); - } - break; - } - if ((sifp = ifunit(pfsyncr.pfsyncr_syncif)) == NULL) - return (EINVAL); - else if (sifp == sc->sc_sync_ifp) - break; - - s = splnet(); - if (sifp->if_mtu < sc->sc_if.if_mtu || - (sc->sc_sync_ifp != NULL && - sifp->if_mtu < sc->sc_sync_ifp->if_mtu) || - sifp->if_mtu < MCLBYTES - sizeof(struct ip)) - pfsync_sendout(sc); - sc->sc_sync_ifp = sifp; - - pfsync_setmtu(sc, sc->sc_if.if_mtu); - - if (imo->imo_num_memberships > 0) { - in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); - imo->imo_multicast_ifp = NULL; - } - - if (sc->sc_sync_ifp) { - struct in_addr addr; - - addr.s_addr = INADDR_PFSYNC_GROUP; - if ((imo->imo_membership[0] = - in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) { - splx(s); - return (ENOBUFS); - } - imo->imo_num_memberships++; - imo->imo_multicast_ifp = sc->sc_sync_ifp; - imo->imo_multicast_ttl = PFSYNC_DFLTTL; - imo->imo_multicast_loop = 0; - - /* Request a full state table update. */ - sc->sc_ureq_sent = mono_time.tv_sec; - pfsync_sync_ok = 0; - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: requesting bulk update\n"); - timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); - pfsync_request_update(NULL, NULL); - pfsync_sendout(sc); - } - splx(s); - - break; - - default: - return (ENOTTY); - } - - return (0); -} - -void -pfsync_setmtu(struct pfsync_softc *sc, int mtu_req) -{ - int mtu; - - if (sc->sc_sync_ifp && sc->sc_sync_ifp->if_mtu < mtu_req) - mtu = sc->sc_sync_ifp->if_mtu; - else - mtu = mtu_req; - - sc->sc_maxcount = (mtu - sizeof(struct pfsync_header)) / - sizeof(struct pfsync_state); - if (sc->sc_maxcount > 254) - sc->sc_maxcount = 254; - sc->sc_if.if_mtu = sizeof(struct pfsync_header) + - sc->sc_maxcount * sizeof(struct pfsync_state); -} - -struct mbuf * -pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp) -{ - struct pfsync_header *h; - struct mbuf *m; - int len; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_if.if_oerrors++; - return (NULL); - } - - switch (action) { - case PFSYNC_ACT_CLR: - len = sizeof(struct pfsync_header) + - sizeof(struct pfsync_state_clr); - break; - case PFSYNC_ACT_UPD_C: - len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd)) + - sizeof(struct pfsync_header); - break; - case PFSYNC_ACT_DEL_C: - len = (sc->sc_maxcount * sizeof(struct pfsync_state_del)) + - sizeof(struct pfsync_header); - break; - case PFSYNC_ACT_UREQ: - len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd_req)) + - sizeof(struct pfsync_header); - break; - case PFSYNC_ACT_BUS: - len = sizeof(struct pfsync_header) + - sizeof(struct pfsync_state_bus); - break; - default: - len = (sc->sc_maxcount * sizeof(struct pfsync_state)) + - sizeof(struct pfsync_header); - break; - } - - if (len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - sc->sc_if.if_oerrors++; - return (NULL); - } - m->m_data += (MCLBYTES - len) &~ (sizeof(long) - 1); - } else - MH_ALIGN(m, len); - - m->m_pkthdr.rcvif = NULL; - m->m_pkthdr.len = m->m_len = sizeof(struct pfsync_header); - h = mtod(m, struct pfsync_header *); - h->version = PFSYNC_VERSION; - h->af = 0; - h->count = 0; - h->action = action; - - *sp = (void *)((char *)h + PFSYNC_HDRLEN); - timeout_add(&sc->sc_tmo, hz); - return (m); -} - -int -pfsync_pack_state(u_int8_t action, struct pf_state *st, int compress) -{ - struct ifnet *ifp = &pfsyncif.sc_if; - struct pfsync_softc *sc = ifp->if_softc; - struct pfsync_header *h, *h_net; - struct pfsync_state *sp = NULL; - struct pfsync_state_upd *up = NULL; - struct pfsync_state_del *dp = NULL; - struct pf_rule *r; - u_long secs; - int s, ret = 0; - u_int8_t i = 255, newaction = 0; - - /* - * If a packet falls in the forest and there's nobody around to - * hear, does it make a sound? - */ - if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL) { - /* Don't leave any stale pfsync packets hanging around. */ - if (sc->sc_mbuf != NULL) { - m_freem(sc->sc_mbuf); - sc->sc_mbuf = NULL; - sc->sc_statep.s = NULL; - } - return (0); - } - - if (action >= PFSYNC_ACT_MAX) - return (EINVAL); - - s = splnet(); - if (sc->sc_mbuf == NULL) { - if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action, - (void *)&sc->sc_statep.s)) == NULL) { - splx(s); - return (ENOMEM); - } - h = mtod(sc->sc_mbuf, struct pfsync_header *); - } else { - h = mtod(sc->sc_mbuf, struct pfsync_header *); - if (h->action != action) { - pfsync_sendout(sc); - if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action, - (void *)&sc->sc_statep.s)) == NULL) { - splx(s); - return (ENOMEM); - } - h = mtod(sc->sc_mbuf, struct pfsync_header *); - } else { - /* - * If it's an update, look in the packet to see if - * we already have an update for the state. - */ - if (action == PFSYNC_ACT_UPD && sc->sc_maxupdates) { - struct pfsync_state *usp = - (void *)((char *)h + PFSYNC_HDRLEN); - - for (i = 0; i < h->count; i++) { - if (!memcmp(usp->id, &st->id, - PFSYNC_ID_LEN) && - usp->creatorid == st->creatorid) { - sp = usp; - sp->updates++; - break; - } - usp++; - } - } - } - } - - secs = time.tv_sec; - - st->pfsync_time = mono_time.tv_sec; - TAILQ_REMOVE(&state_updates, st, u.s.entry_updates); - TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates); - - if (sp == NULL) { - /* not a "duplicate" update */ - i = 255; - sp = sc->sc_statep.s++; - sc->sc_mbuf->m_pkthdr.len = - sc->sc_mbuf->m_len += sizeof(struct pfsync_state); - h->count++; - bzero(sp, sizeof(*sp)); - - bcopy(&st->id, sp->id, sizeof(sp->id)); - sp->creatorid = st->creatorid; - - strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname)); - pf_state_host_hton(&st->lan, &sp->lan); - pf_state_host_hton(&st->gwy, &sp->gwy); - pf_state_host_hton(&st->ext, &sp->ext); - - bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); - - sp->creation = htonl(secs - st->creation); - sp->packets[0] = htonl(st->packets[0]); - sp->packets[1] = htonl(st->packets[1]); - sp->bytes[0] = htonl(st->bytes[0]); - sp->bytes[1] = htonl(st->bytes[1]); - if ((r = st->rule.ptr) == NULL) - sp->rule = htonl(-1); - else - sp->rule = htonl(r->nr); - if ((r = st->anchor.ptr) == NULL) - sp->anchor = htonl(-1); - else - sp->anchor = htonl(r->nr); - sp->af = st->af; - sp->proto = st->proto; - sp->direction = st->direction; - sp->log = st->log; - sp->allow_opts = st->allow_opts; - sp->timeout = st->timeout; - - sp->sync_flags = st->sync_flags & PFSTATE_NOSYNC; - } - - pf_state_peer_hton(&st->src, &sp->src); - pf_state_peer_hton(&st->dst, &sp->dst); - - if (st->expire <= secs) - sp->expire = htonl(0); - else - sp->expire = htonl(st->expire - secs); - - /* do we need to build "compressed" actions for network transfer? */ - if (sc->sc_sync_ifp && compress) { - switch (action) { - case PFSYNC_ACT_UPD: - newaction = PFSYNC_ACT_UPD_C; - break; - case PFSYNC_ACT_DEL: - newaction = PFSYNC_ACT_DEL_C; - break; - default: - /* by default we just send the uncompressed states */ - break; - } - } - - if (newaction) { - if (sc->sc_mbuf_net == NULL) { - if ((sc->sc_mbuf_net = pfsync_get_mbuf(sc, newaction, - (void *)&sc->sc_statep_net.s)) == NULL) { - splx(s); - return (ENOMEM); - } - } - h_net = mtod(sc->sc_mbuf_net, struct pfsync_header *); - - switch (newaction) { - case PFSYNC_ACT_UPD_C: - if (i != 255) { - up = (void *)((char *)h_net + - PFSYNC_HDRLEN + (i * sizeof(*up))); - up->updates++; - } else { - h_net->count++; - sc->sc_mbuf_net->m_pkthdr.len = - sc->sc_mbuf_net->m_len += sizeof(*up); - up = sc->sc_statep_net.u++; - - bzero(up, sizeof(*up)); - bcopy(&st->id, up->id, sizeof(up->id)); - up->creatorid = st->creatorid; - } - up->timeout = st->timeout; - up->expire = sp->expire; - up->src = sp->src; - up->dst = sp->dst; - break; - case PFSYNC_ACT_DEL_C: - sc->sc_mbuf_net->m_pkthdr.len = - sc->sc_mbuf_net->m_len += sizeof(*dp); - dp = sc->sc_statep_net.d++; - h_net->count++; - - bzero(dp, sizeof(*dp)); - bcopy(&st->id, dp->id, sizeof(dp->id)); - dp->creatorid = st->creatorid; - break; - } - } - - if (h->count == sc->sc_maxcount || - (sc->sc_maxupdates && (sp->updates >= sc->sc_maxupdates))) - ret = pfsync_sendout(sc); - - splx(s); - return (ret); -} - -/* This must be called in splnet() */ -int -pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src) -{ - struct ifnet *ifp = &pfsyncif.sc_if; - struct pfsync_header *h; - struct pfsync_softc *sc = ifp->if_softc; - struct pfsync_state_upd_req *rup; - int s, ret; - - if (sc->sc_mbuf == NULL) { - if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, - (void *)&sc->sc_statep.s)) == NULL) { - splx(s); - return (ENOMEM); - } - h = mtod(sc->sc_mbuf, struct pfsync_header *); - } else { - h = mtod(sc->sc_mbuf, struct pfsync_header *); - if (h->action != PFSYNC_ACT_UREQ) { - pfsync_sendout(sc); - if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, - (void *)&sc->sc_statep.s)) == NULL) { - splx(s); - return (ENOMEM); - } - h = mtod(sc->sc_mbuf, struct pfsync_header *); - } - } - - if (src != NULL) - sc->sc_sendaddr = *src; - sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup); - h->count++; - rup = sc->sc_statep.r++; - bzero(rup, sizeof(*rup)); - if (up != NULL) { - bcopy(up->id, rup->id, sizeof(rup->id)); - rup->creatorid = up->creatorid; - } - - if (h->count == sc->sc_maxcount) - ret = pfsync_sendout(sc); - - return (ret); -} - -int -pfsync_clear_states(u_int32_t creatorid, char *ifname) -{ - struct ifnet *ifp = &pfsyncif.sc_if; - struct pfsync_softc *sc = ifp->if_softc; - struct pfsync_state_clr *cp; - int s, ret; - - s = splnet(); - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR, - (void *)&sc->sc_statep.c)) == NULL) { - splx(s); - return (ENOMEM); - } - sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*cp); - cp = sc->sc_statep.c; - cp->creatorid = creatorid; - if (ifname != NULL) - strlcpy(cp->ifname, ifname, IFNAMSIZ); - - ret = (pfsync_sendout(sc)); - splx(s); - return (ret); -} - -void -pfsync_timeout(void *v) -{ - struct pfsync_softc *sc = v; - int s; - - s = splnet(); - pfsync_sendout(sc); - splx(s); -} - -void -pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status) -{ - struct pfsync_state_bus *bus; - - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - - if (pfsync_sync_ok && - (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS, - (void *)&sc->sc_statep.b)) != NULL) { - sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus); - bus = sc->sc_statep.b; - bus->creatorid = pf_status.hostid; - bus->status = status; - bus->endtime = htonl(mono_time.tv_sec - sc->sc_ureq_received); - pfsync_sendout(sc); - } -} - -void -pfsync_bulk_update(void *v) -{ - struct pfsync_softc *sc = v; - int s, i = 0; - struct pf_state *state; - - s = splnet(); - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - - /* - * Grab at most PFSYNC_BULKPACKETS worth of states which have not - * been sent since the latest request was made. - */ - while ((state = TAILQ_FIRST(&state_updates)) != NULL && - ++i < (sc->sc_maxcount * PFSYNC_BULKPACKETS)) { - if (state->pfsync_time > sc->sc_ureq_received) { - /* we're done */ - pfsync_send_bus(sc, PFSYNC_BUS_END); - sc->sc_ureq_received = 0; - timeout_del(&sc->sc_bulk_tmo); - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: bulk update complete\n"); - break; - } else { - /* send an update and move to end of list */ - if (!state->sync_flags) - pfsync_pack_state(PFSYNC_ACT_UPD, state, 0); - state->pfsync_time = mono_time.tv_sec; - TAILQ_REMOVE(&state_updates, state, u.s.entry_updates); - TAILQ_INSERT_TAIL(&state_updates, state, - u.s.entry_updates); - - /* look again for more in a bit */ - timeout_add(&sc->sc_bulk_tmo, 1); - } - } - if (sc->sc_mbuf != NULL) - pfsync_sendout(sc); - splx(s); -} - -void -pfsync_bulkfail(void *v) -{ - struct pfsync_softc *sc = v; - - if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { - /* Try again in a bit */ - timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); - pfsync_request_update(NULL, NULL); - pfsync_sendout(sc); - } else { - /* Pretend like the transfer was ok */ - sc->sc_ureq_sent = 0; - sc->sc_bulk_tries = 0; - pfsync_sync_ok = 1; - if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync: failed to receive " - "bulk update status\n"); - timeout_del(&sc->sc_bulkfail_tmo); - } -} - -int -pfsync_sendout(sc) - struct pfsync_softc *sc; -{ - struct ifnet *ifp = &sc->sc_if; - struct mbuf *m; - - timeout_del(&sc->sc_tmo); - - if (sc->sc_mbuf == NULL) - return (0); - m = sc->sc_mbuf; - sc->sc_mbuf = NULL; - sc->sc_statep.s = NULL; - -#if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m); -#endif - - if (sc->sc_mbuf_net) { - m_freem(m); - m = sc->sc_mbuf_net; - sc->sc_mbuf_net = NULL; - sc->sc_statep_net.s = NULL; - } - - if (sc->sc_sync_ifp) { - struct ip *ip; - struct ifaddr *ifa; - struct sockaddr sa; - - M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); - if (m == NULL) { - pfsyncstats.pfsyncs_onomem++; - return (0); - } - ip = mtod(m, struct ip *); - ip->ip_v = IPVERSION; - ip->ip_hl = sizeof(*ip) >> 2; - ip->ip_tos = IPTOS_LOWDELAY; - ip->ip_len = htons(m->m_pkthdr.len); - ip->ip_id = htons(ip_randomid()); - ip->ip_off = htons(IP_DF); - ip->ip_ttl = PFSYNC_DFLTTL; - ip->ip_p = IPPROTO_PFSYNC; - ip->ip_sum = 0; - - bzero(&sa, sizeof(sa)); - sa.sa_family = AF_INET; - ifa = ifaof_ifpforaddr(&sa, sc->sc_sync_ifp); - if (ifa == NULL) - return (0); - ip->ip_src.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr; - - if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP) - m->m_flags |= M_MCAST; - ip->ip_dst = sc->sc_sendaddr; - sc->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; - - pfsyncstats.pfsyncs_opackets++; - - if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) - pfsyncstats.pfsyncs_oerrors++; - } else - m_freem(m); - - return (0); -} diff --git a/sys/dist/pf/net/if_pfsync.h b/sys/dist/pf/net/if_pfsync.h deleted file mode 100644 index b3705c8dd2a2..000000000000 --- a/sys/dist/pf/net/if_pfsync.h +++ /dev/null @@ -1,280 +0,0 @@ -/* $OpenBSD: if_pfsync.h,v 1.13 2004/03/22 04:54:17 mcbride Exp $ */ - -/* - * Copyright (c) 2001 Michael Shalayeff - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_IF_PFSYNC_H_ -#define _NET_IF_PFSYNC_H_ - - -#define PFSYNC_ID_LEN sizeof(u_int64_t) - -struct pfsync_state_scrub { - u_int16_t pfss_flags; - u_int8_t pfss_ttl; /* stashed TTL */ - u_int8_t scrub_flag; - u_int32_t pfss_ts_mod; /* timestamp modulation */ -} __packed; - -struct pfsync_state_host { - struct pf_addr addr; - u_int16_t port; - u_int16_t pad[3]; -} __packed; - -struct pfsync_state_peer { - struct pfsync_state_scrub scrub; /* state is scrubbed */ - u_int32_t seqlo; /* Max sequence number sent */ - u_int32_t seqhi; /* Max the other end ACKd + win */ - u_int32_t seqdiff; /* Sequence number modulator */ - u_int16_t max_win; /* largest window (pre scaling) */ - u_int16_t mss; /* Maximum segment size option */ - u_int8_t state; /* active state level */ - u_int8_t wscale; /* window scaling factor */ - u_int8_t scrub_flag; - u_int8_t pad[5]; -} __packed; - -struct pfsync_state { - u_int32_t id[2]; - char ifname[IFNAMSIZ]; - struct pfsync_state_host lan; - struct pfsync_state_host gwy; - struct pfsync_state_host ext; - struct pfsync_state_peer src; - struct pfsync_state_peer dst; - struct pf_addr rt_addr; - u_int32_t rule; - u_int32_t anchor; - u_int32_t nat_rule; - u_int32_t creation; - u_int32_t expire; - u_int32_t packets[2]; - u_int32_t bytes[2]; - u_int32_t creatorid; - sa_family_t af; - u_int8_t proto; - u_int8_t direction; - u_int8_t log; - u_int8_t allow_opts; - u_int8_t timeout; - u_int8_t sync_flags; - u_int8_t updates; -} __packed; - -struct pfsync_state_upd { - u_int32_t id[2]; - struct pfsync_state_peer src; - struct pfsync_state_peer dst; - u_int32_t creatorid; - u_int32_t expire; - u_int8_t timeout; - u_int8_t updates; - u_int8_t pad[6]; -} __packed; - -struct pfsync_state_del { - u_int32_t id[2]; - u_int32_t creatorid; - struct { - u_int8_t state; - } src; - struct { - u_int8_t state; - } dst; - u_int8_t pad[2]; -} __packed; - -struct pfsync_state_upd_req { - u_int32_t id[2]; - u_int32_t creatorid; - u_int32_t pad; -} __packed; - -struct pfsync_state_clr { - char ifname[IFNAMSIZ]; - u_int32_t creatorid; - u_int32_t pad; -} __packed; - -struct pfsync_state_bus { - u_int32_t creatorid; - u_int32_t endtime; - u_int8_t status; -#define PFSYNC_BUS_START 1 -#define PFSYNC_BUS_END 2 - u_int8_t pad[7]; -} __packed; - -#ifdef _KERNEL - -union sc_statep { - struct pfsync_state *s; - struct pfsync_state_upd *u; - struct pfsync_state_del *d; - struct pfsync_state_clr *c; - struct pfsync_state_bus *b; - struct pfsync_state_upd_req *r; -}; - -extern int pfsync_sync_ok; - -struct pfsync_softc { - struct ifnet sc_if; - struct ifnet *sc_sync_ifp; - - struct ip_moptions sc_imo; - struct timeout sc_tmo; - struct timeout sc_bulk_tmo; - struct timeout sc_bulkfail_tmo; - struct in_addr sc_sendaddr; - struct mbuf *sc_mbuf; /* current cummulative mbuf */ - struct mbuf *sc_mbuf_net; /* current cummulative mbuf */ - union sc_statep sc_statep; - union sc_statep sc_statep_net; - u_int32_t sc_ureq_received; - u_int32_t sc_ureq_sent; - int sc_bulk_tries; - int sc_maxcount; /* number of states in mtu */ - int sc_maxupdates; /* number of updates/state */ -}; -#endif - - -struct pfsync_header { - u_int8_t version; -#define PFSYNC_VERSION 2 - u_int8_t af; - u_int8_t action; -#define PFSYNC_ACT_CLR 0 /* clear all states */ -#define PFSYNC_ACT_INS 1 /* insert state */ -#define PFSYNC_ACT_UPD 2 /* update state */ -#define PFSYNC_ACT_DEL 3 /* delete state */ -#define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */ -#define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */ -#define PFSYNC_ACT_INS_F 6 /* insert fragment */ -#define PFSYNC_ACT_DEL_F 7 /* delete fragments */ -#define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */ -#define PFSYNC_ACT_BUS 9 /* Bulk Update Status */ -#define PFSYNC_ACT_MAX 10 - u_int8_t count; -} __packed; - -#define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */ -#define PFSYNC_MAX_BULKTRIES 12 -#define PFSYNC_HDRLEN sizeof(struct pfsync_header) -#define PFSYNC_ACTIONS \ - "CLR ST", "INS ST", "UPD ST", "DEL ST", \ - "UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \ - "UPD REQ", "BLK UPD STAT" - -#define PFSYNC_DFLTTL 255 - -struct pfsyncstats { - u_long pfsyncs_ipackets; /* total input packets, IPv4 */ - u_long pfsyncs_ipackets6; /* total input packets, IPv6 */ - u_long pfsyncs_badif; /* not the right interface */ - u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */ - u_long pfsyncs_hdrops; /* packets shorter than header */ - u_long pfsyncs_badver; /* bad (incl unsupp) version */ - u_long pfsyncs_badact; /* bad action */ - u_long pfsyncs_badlen; /* data length does not match */ - u_long pfsyncs_badauth; /* bad authentication */ - u_long pfsyncs_badstate; /* insert/lookup failed */ - - u_long pfsyncs_opackets; /* total output packets, IPv4 */ - u_long pfsyncs_opackets6; /* total output packets, IPv6 */ - u_long pfsyncs_onomem; /* no memory for an mbuf for a send */ - u_long pfsyncs_oerrors; /* ip output error */ -}; - -/* - * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC - */ -struct pfsyncreq { - char pfsyncr_syncif[IFNAMSIZ]; - int pfsyncr_maxupdates; - int pfsyncr_authlevel; -}; -#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) -#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) - - -#define pf_state_peer_hton(s,d) do { \ - (d)->seqlo = htonl((s)->seqlo); \ - (d)->seqhi = htonl((s)->seqhi); \ - (d)->seqdiff = htonl((s)->seqdiff); \ - (d)->max_win = htons((s)->max_win); \ - (d)->mss = htons((s)->mss); \ - (d)->state = (s)->state; \ - (d)->wscale = (s)->wscale; \ -} while (0) - -#define pf_state_peer_ntoh(s,d) do { \ - (d)->seqlo = ntohl((s)->seqlo); \ - (d)->seqhi = ntohl((s)->seqhi); \ - (d)->seqdiff = ntohl((s)->seqdiff); \ - (d)->max_win = ntohs((s)->max_win); \ - (d)->mss = ntohs((s)->mss); \ - (d)->state = (s)->state; \ - (d)->wscale = (s)->wscale; \ -} while (0) - -#define pf_state_host_hton(s,d) do { \ - bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ - (d)->port = (s)->port; \ -} while (0) - -#define pf_state_host_ntoh(s,d) do { \ - bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ - (d)->port = (s)->port; \ -} while (0) - -#ifdef _KERNEL -void pfsync_input(struct mbuf *, ...); -int pfsync_clear_states(u_int32_t, char *); -int pfsync_pack_state(u_int8_t, struct pf_state *, int); -#define pfsync_insert_state(st) do { \ - if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \ - (st->proto == IPPROTO_PFSYNC)) \ - st->sync_flags |= PFSTATE_NOSYNC; \ - else if (!st->sync_flags) \ - pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \ - st->sync_flags &= ~PFSTATE_FROMSYNC; \ -} while (0) -#define pfsync_update_state(st) do { \ - if (!st->sync_flags) \ - pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1); \ - st->sync_flags &= ~PFSTATE_FROMSYNC; \ -} while (0) -#define pfsync_delete_state(st) do { \ - if (!st->sync_flags) \ - pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1); \ - st->sync_flags &= ~PFSTATE_FROMSYNC; \ -} while (0) -#endif - -#endif /* _NET_IF_PFSYNC_H_ */ diff --git a/sys/dist/pf/net/pf.c b/sys/dist/pf/net/pf.c index 82113ecbe1c4..3d61f635c255 100644 --- a/sys/dist/pf/net/pf.c +++ b/sys/dist/pf/net/pf.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */ /* $OpenBSD: pf.c,v 1.433 2004/03/26 22:20:57 dhartmei Exp $ */ /* @@ -37,7 +38,11 @@ #include "bpfilter.h" #include "pflog.h" +#ifdef __OpenBSD__ #include "pfsync.h" +#else +#define NPFSYNC 0 +#endif #include #include @@ -48,6 +53,9 @@ #include #include #include +#ifdef __NetBSD__ +#include +#endif #include #include @@ -69,7 +77,11 @@ #include #include +#ifdef __OpenBSD__ #include +#else +#include +#endif #include #include @@ -79,7 +91,10 @@ #ifdef INET6 #include -#include +#include +#ifdef __NetBSD__ +#include +#endif #include #include #endif /* INET6 */ @@ -104,7 +119,11 @@ u_int32_t ticket_altqs_inactive; int altqs_inactive_open; u_int32_t ticket_pabuf; +#ifdef __OpenBSD__ struct timeout pf_expire_to; /* expire timeout */ +#else +struct callout pf_expire_to; /* expire timeout */ +#endif struct pool pf_src_tree_pl, pf_rule_pl; struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; @@ -659,9 +678,15 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *state) } if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) { if (pf_status.debug >= PF_DEBUG_MISC) { +#ifdef __OpenBSD__ printf("pf: state insert failed: " "id: %016llx creatorid: %08x", betoh64(state->id), ntohl(state->creatorid)); +#else + printf("pf: state insert failed: " + "id: %016llx creatorid: %08x", + be64toh(state->id), ntohl(state->creatorid)); +#endif if (state->sync_flags & PFSTATE_FROMSYNC) printf(" (from sync)"); printf("\n"); @@ -684,7 +709,11 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *state) void pf_purge_timeout(void *arg) { +#ifdef __OpenBSD__ struct timeout *to = arg; +#else + struct callout *to = arg; +#endif int s; s = splsoftnet(); @@ -693,7 +722,11 @@ pf_purge_timeout(void *arg) pf_purge_expired_src_nodes(); splx(s); +#ifdef __OpenBSD__ timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); +#else + callout_schedule(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); +#endif } u_int32_t @@ -1181,7 +1214,7 @@ pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, /* Change inner protocol port, fix inner protocol checksum. */ if (ip != NULL) { u_int16_t oip = *ip; - u_int32_t opc; + u_int32_t opc = 0; if (pc != NULL) opc = *pc; @@ -1263,10 +1296,10 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, struct m_tag *mtag; int len, tlen; #ifdef INET - struct ip *h; + struct ip *h = NULL; #endif /* INET */ #ifdef INET6 - struct ip6_hdr *h6; + struct ip6_hdr *h6 = NULL; #endif /* INET6 */ struct tcphdr *th; char *opt; @@ -1287,6 +1320,8 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, len = sizeof(struct ip6_hdr) + tlen; break; #endif /* INET6 */ + default: + return; } /* create outgoing mbuf */ @@ -1345,6 +1380,9 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); break; #endif /* INET6 */ + default: + m_freem(m); + return; } /* TCP header */ @@ -1391,7 +1429,11 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, h6->ip6_vfc |= IPV6_VERSION; h6->ip6_hlim = IPV6_DEFHLIM; +#ifdef __OpenBSD__ ip6_output(m, NULL, NULL, 0, NULL, NULL); +#else + ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); +#endif break; #endif /* INET6 */ } @@ -2194,7 +2236,10 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) struct pf_addr *saddr, *daddr; u_int16_t sport, dport; struct inpcbtable *tb; - struct inpcb *inp; + struct inpcb *inp = NULL; +#ifdef __NetBSD__ + struct in6pcb *in6p = NULL; +#endif *uid = UID_MAX; *gid = GID_MAX; @@ -2226,15 +2271,26 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) } switch (pd->af) { case AF_INET: +#ifdef __OpenBSD__ inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); if (inp == NULL) { inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); if (inp == NULL) return (0); } +#else + inp = in_pcblookup_connect(tb, saddr->v4, sport, daddr->v4, + dport); + if (inp == NULL) { + inp = in_pcblookup_bind(tb, daddr->v4, dport); + if (inp == NULL) + return (0); + } +#endif break; #ifdef INET6 case AF_INET6: +#ifdef __OpenBSD__ inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, dport); if (inp == NULL) { @@ -2242,14 +2298,38 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) if (inp == NULL) return (0); } +#else + in6p = in6_pcblookup_connect(tb, &saddr->v6, sport, &daddr->v6, + dport, 0); + if (in6p == NULL) { + in6p = in6_pcblookup_bind(tb, &daddr->v6, dport, 0); + if (inp == NULL) + return (0); + } +#endif break; #endif /* INET6 */ default: return (0); } +#ifdef __OpenBSD__ *uid = inp->inp_socket->so_euid; *gid = inp->inp_socket->so_egid; +#else + switch (pd->af) { + case AF_INET: + *uid = inp->inp_socket->so_uid; + /* XXX gid */ + break; +#ifdef INET6 + case AF_INET6: + *uid = in6p->in6p_socket->so_uid; + /* XXX gid */ + break; +#endif + } +#endif return (1); } @@ -2354,7 +2434,11 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; +#ifdef __OpenBSD__ rtalloc_noclone(&ro, NO_CLONING); +#else + rtalloc(&ro); +#endif rt = ro.ro_rt; break; #endif /* INET */ @@ -2366,7 +2450,11 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) dst6->sin6_family = AF_INET6; dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = addr->v6; +#ifdef __OpenBSD__ rtalloc_noclone((struct route *)&ro6, NO_CLONING); +#else + rtalloc((struct route *)&ro6); +#endif rt = ro6.ro_rt; break; #endif /* INET6 */ @@ -2532,7 +2620,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, if (r->log) { if (rewrite) - m_copyback(m, off, sizeof(*th), th); + m_copyback(m, off, sizeof(*th), (caddr_t)th); PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); } @@ -2758,7 +2846,7 @@ cleanup: /* copy back packet headers if we performed NAT operations */ if (rewrite) - m_copyback(m, off, sizeof(*th), th); + m_copyback(m, off, sizeof(*th), (caddr_t)th); return (PF_PASS); } @@ -2883,7 +2971,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, if (r->log) { if (rewrite) - m_copyback(m, off, sizeof(*uh), uh); + m_copyback(m, off, sizeof(*uh), (caddr_t)uh); PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); } @@ -3021,7 +3109,7 @@ cleanup: /* copy back packet headers if we performed NAT operations */ if (rewrite) - m_copyback(m, off, sizeof(*uh), uh); + m_copyback(m, off, sizeof(*uh), (caddr_t)uh); return (PF_PASS); } @@ -3037,9 +3125,9 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, struct pf_ruleset *ruleset = NULL; struct pf_src_node *nsn = NULL; u_short reason; - u_int16_t icmpid; + u_int16_t icmpid = 0; sa_family_t af = pd->af; - u_int8_t icmptype, icmpcode; + u_int8_t icmptype = 0, icmpcode = 0; int state_icmp = 0; struct pf_tag *pftag = NULL; int tag = -1; @@ -3186,7 +3274,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, #ifdef INET6 if (rewrite) m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); #endif /* INET6 */ PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); } @@ -3298,7 +3386,7 @@ cleanup: /* copy back packet headers if we performed IPv6 NAT operations */ if (rewrite) m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); #endif /* INET6 */ return (PF_PASS); @@ -4029,10 +4117,10 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, &th->th_sum, &(*state)->lan.addr, (*state)->lan.port, 0, pd->af); - m_copyback(m, off, sizeof(*th), th); + m_copyback(m, off, sizeof(*th), (caddr_t)th); } else if (copyback) { /* Copyback sequence modulation or stateful scrub changes */ - m_copyback(m, off, sizeof(*th), th); + m_copyback(m, off, sizeof(*th), (caddr_t)th); } return (PF_PASS); @@ -4093,7 +4181,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, &uh->uh_sum, &(*state)->lan.addr, (*state)->lan.port, 1, pd->af); - m_copyback(m, off, sizeof(*uh), uh); + m_copyback(m, off, sizeof(*uh), (caddr_t)uh); } return (PF_PASS); @@ -4104,7 +4192,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd) { struct pf_addr *saddr = pd->src, *daddr = pd->dst; - u_int16_t icmpid, *icmpsum; + u_int16_t icmpid = 0, *icmpsum; u_int8_t icmptype; int state_icmp = 0; @@ -4183,7 +4271,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, &(*state)->gwy.addr, 0); m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); break; #endif /* INET6 */ } @@ -4203,7 +4291,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, &(*state)->lan.addr, 0); m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); break; #endif /* INET6 */ } @@ -4226,8 +4314,8 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, struct ip6_hdr h2_6; int terminal = 0; #endif /* INET6 */ - int ipoff2; - int off2; + int ipoff2 = 0; + int off2 = 0; pd2.af = pd->af; switch (pd->af) { @@ -4409,22 +4497,22 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, #ifdef INET case AF_INET: m_copyback(m, off, ICMP_MINLEN, - pd->hdr.icmp); + (caddr_t)pd->hdr.icmp); m_copyback(m, ipoff2, sizeof(h2), - &h2); + (caddr_t)&h2); break; #endif /* INET */ #ifdef INET6 case AF_INET6: m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); m_copyback(m, ipoff2, sizeof(h2_6), - &h2_6); + (caddr_t)&h2_6); break; #endif /* INET6 */ } - m_copyback(m, off2, 8, &th); + m_copyback(m, off2, 8, (caddr_t)&th); } return (PF_PASS); @@ -4476,21 +4564,22 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, #ifdef INET case AF_INET: m_copyback(m, off, ICMP_MINLEN, - pd->hdr.icmp); - m_copyback(m, ipoff2, sizeof(h2), &h2); + (caddr_t)pd->hdr.icmp); + m_copyback(m, ipoff2, sizeof(h2), + (caddr_t)&h2); break; #endif /* INET */ #ifdef INET6 case AF_INET6: m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); m_copyback(m, ipoff2, sizeof(h2_6), - &h2_6); + (caddr_t)&h2_6); break; #endif /* INET6 */ } - m_copyback(m, off2, sizeof(uh), &uh); + m_copyback(m, off2, sizeof(uh), (caddr_t)&uh); } return (PF_PASS); @@ -4539,9 +4628,10 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 0, AF_INET); } - m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp); - m_copyback(m, ipoff2, sizeof(h2), &h2); - m_copyback(m, off2, ICMP_MINLEN, &iih); + m_copyback(m, off, ICMP_MINLEN, + (caddr_t)pd->hdr.icmp); + m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); + m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih); } return (PF_PASS); @@ -4592,10 +4682,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd->ip_sum, 0, AF_INET6); } m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); - m_copyback(m, ipoff2, sizeof(h2_6), &h2_6); + (caddr_t)pd->hdr.icmp6); + m_copyback(m, ipoff2, sizeof(h2_6), + (caddr_t)&h2_6); m_copyback(m, off2, sizeof(struct icmp6_hdr), - &iih); + (caddr_t)&iih); } return (PF_PASS); @@ -4639,17 +4730,18 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, #ifdef INET case AF_INET: m_copyback(m, off, ICMP_MINLEN, - pd->hdr.icmp); - m_copyback(m, ipoff2, sizeof(h2), &h2); + (caddr_t)pd->hdr.icmp); + m_copyback(m, ipoff2, sizeof(h2), + (caddr_t)&h2); break; #endif /* INET */ #ifdef INET6 case AF_INET6: m_copyback(m, off, sizeof(struct icmp6_hdr), - pd->hdr.icmp6); + (caddr_t)pd->hdr.icmp6); m_copyback(m, ipoff2, sizeof(h2_6), - &h2_6); + (caddr_t)&h2_6); break; #endif /* INET6 */ } @@ -4806,7 +4898,11 @@ pf_routable(struct pf_addr *addr, sa_family_t af) dst->sin_family = af; dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; +#ifdef __OpenBSD__ rtalloc_noclone(&ro, NO_CLONING); +#else + rtalloc(&ro); +#endif if (ro.ro_rt != NULL) { ret = 1; @@ -4823,7 +4919,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, { struct mbuf *m0, *m1; struct route iproute; - struct route *ro; + struct route *ro = NULL; struct sockaddr_in *dst; struct ip *ip; struct ifnet *ifp = NULL; @@ -4831,6 +4927,9 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, struct pf_addr naddr; struct pf_src_node *sn = NULL; int error = 0; +#ifdef __NetBSD__ + struct tcphdr th; +#endif if (m == NULL || *m == NULL || r == NULL || (dir != PF_IN && dir != PF_OUT) || oifp == NULL) @@ -4845,7 +4944,11 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, goto bad; m_tag_prepend(m0, mtag); } +#ifdef __OpenBSD__ m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); +#else + m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT); +#endif if (m0 == NULL) return; } else { @@ -4933,6 +5036,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, #endif /* IPSEC */ /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ +#ifdef __OpenBSD__ if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) { if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || ifp->if_bridge != NULL) { @@ -4946,8 +5050,15 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ } } +#else + m_copydata(m0, sizeof(*ip), sizeof(th), (caddr_t)&th); + th.th_sum = 0; + m_copyback(m0, sizeof(*ip), sizeof(th), (caddr_t)&th); + in4_cksum(m0, IPPROTO_TCP, sizeof(*ip), m0->m_pkthdr.len - sizeof(*ip)); +#endif if (ntohs(ip->ip_len) <= ifp->if_mtu) { +#ifdef __OpenBSD__ if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && ifp->if_bridge == NULL) { m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; @@ -4956,11 +5067,17 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, ip->ip_sum = 0; ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); } +#else + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); +#endif +#ifdef __OpenBSD__ /* Update relevant hardware checksum stats for TCP/UDP */ if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) tcpstat.tcps_outhwcsum++; else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) udpstat.udps_outhwcsum++; +#endif error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); goto done; } @@ -5041,7 +5158,11 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, goto bad; m_tag_prepend(m0, mtag); } +#ifdef __OpenBSD__ m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); +#else + m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT); +#endif if (m0 == NULL) return; } else { @@ -5067,7 +5188,11 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, if (mtag == NULL) goto bad; m_tag_prepend(m0, mtag); +#ifdef __OpenBSD__ ip6_output(m0, NULL, NULL, 0, NULL, NULL); +#else + ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); +#endif return; } @@ -5142,9 +5267,12 @@ int pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) { +#ifdef __OpenBSD__ u_int16_t flag_ok, flag_bad; +#endif u_int16_t sum; +#ifdef __OpenBSD__ switch (p) { case IPPROTO_TCP: flag_ok = M_TCP_CSUM_IN_OK; @@ -5167,6 +5295,7 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, return (0); if (m->m_pkthdr.csum & flag_bad) return (1); +#endif if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) return (1); if (m->m_pkthdr.len < off + len) @@ -5198,7 +5327,9 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, return (1); } if (sum) { +#ifdef __OpenBSD__ m->m_pkthdr.csum |= flag_bad; +#endif switch (p) { case IPPROTO_TCP: tcpstat.tcps_rcvbadsum++; @@ -5217,7 +5348,9 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, } return (1); } +#ifdef __OpenBSD__ m->m_pkthdr.csum |= flag_ok; +#endif return (0); } @@ -5242,7 +5375,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) struct pfi_kif *kif; u_short action, reason = 0, log = 0; struct mbuf *m = *m0; - struct ip *h; + struct ip *h = NULL; struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; struct pf_state *s = NULL; struct pf_ruleset *ruleset = NULL; diff --git a/sys/dist/pf/net/pf_if.c b/sys/dist/pf/net/pf_if.c index cdc6e36962fd..c740ba3ef6ba 100644 --- a/sys/dist/pf/net/pf_if.c +++ b/sys/dist/pf/net/pf_if.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf_if.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */ /* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */ /* @@ -30,6 +31,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#endif + #include #include #include @@ -102,6 +107,18 @@ RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); #define PFI_BUFFER_MAX 0x10000 #define PFI_MTYPE M_IFADDR +#ifdef __NetBSD__ +static void *hook_establish(struct hook_desc_head *, int, void (*)(void *), + void *); +static void hook_disestablish(struct hook_desc_head *, void *); + +#define HOOK_REMOVE 0x01 +#define HOOK_FREE 0x02 + +POOL_INIT(pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl", + &pool_allocator_nointr); +#endif + void pfi_initialize(void) { @@ -109,8 +126,10 @@ pfi_initialize(void) return; TAILQ_INIT(&pfi_statehead); +#ifdef __OpenBSD__ pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl", &pool_allocator_nointr); +#endif pfi_buffer_max = 64; pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer), PFI_MTYPE, M_WAITOK); @@ -184,8 +203,13 @@ pfi_attach_ifnet(struct ifnet *ifp) q = p->pfik_parent; p->pfik_ifp = ifp; p->pfik_flags |= PFI_IFLAG_ATTACHED; +#ifdef __OpenBSD__ p->pfik_ah_cookie = hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p); +#else + p->pfik_ah_cookie = + hook_establish(p->pfik_ifaddrhooks, 1, pfi_kifaddr_update, p); +#endif pfi_index2kif[ifp->if_index] = p; pfi_dohooks(p); splx(s); @@ -207,7 +231,11 @@ pfi_detach_ifnet(struct ifnet *ifp) splx(s); return; } +#ifdef __OpenBSD__ hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie); +#else + hook_disestablish(p->pfik_ifaddrhooks, p->pfik_ah_cookie); +#endif q = p->pfik_parent; p->pfik_ifp = NULL; p->pfik_flags &= ~PFI_IFLAG_ATTACHED; @@ -563,8 +591,21 @@ pfi_if_create(const char *name, struct pfi_kif *q, int flags) return (NULL); } bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head)); +#ifdef __NetBSD__ + p->pfik_ifaddrhooks = malloc(sizeof(*p->pfik_ifaddrhooks), PFI_MTYPE, + M_DONTWAIT); + if (p->pfik_ifaddrhooks == NULL) { + free(p->pfik_ah_head, PFI_MTYPE); + free(p, PFI_MTYPE); + return (NULL); + } + bzero(p->pfik_ifaddrhooks, sizeof(*p->pfik_ifaddrhooks)); +#endif TAILQ_INIT(p->pfik_ah_head); TAILQ_INIT(&p->pfik_grouphead); +#ifdef __NetBSD__ + TAILQ_INIT(p->pfik_ifaddrhooks); +#endif strlcpy(p->pfik_name, name, sizeof(p->pfik_name)); RB_INIT(&p->pfik_lan_ext); RB_INIT(&p->pfik_ext_gwy); @@ -627,6 +668,7 @@ pfi_copy_group(char *p, const char *q, int m) void pfi_dynamic_drivers(void) { +#ifdef __OpenBSD__ char *buses[] = PFI_DYNAMIC_BUSES; int nbuses = sizeof(buses)/sizeof(buses[0]); int enabled[sizeof(buses)/sizeof(buses[0])]; @@ -662,6 +704,13 @@ pfi_dynamic_drivers(void) } } } +#else + struct if_clone *ifc; + extern LIST_HEAD(if_cloners, if_clone) if_cloners; + + LIST_FOREACH(ifc, &if_cloners, ifc_list) + pfi_newgroup(ifc->ifc_name, PFI_IFLAG_DYNAMIC); +#endif } void @@ -809,8 +858,11 @@ pfi_unmask(void *addr) void pfi_dohooks(struct pfi_kif *p) { + +#ifdef __OpenBSD__ for (; p != NULL; p = p->pfik_parent) dohooks(p->pfik_ah_head, 0); +#endif } int @@ -838,3 +890,49 @@ pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af) } } } + +/* from openbsd/sys/kern/kern_subr.c */ +#ifdef __NetBSD__ +static void * +hook_establish(head, tail, fn, arg) + struct hook_desc_head *head; + int tail; + void (*fn)(void *); + void *arg; +{ + struct hook_desc *hdp; + + hdp = (struct hook_desc *)malloc(sizeof (*hdp), M_DEVBUF, M_NOWAIT); + if (hdp == NULL) + return (NULL); + + hdp->hd_fn = fn; + hdp->hd_arg = arg; + if (tail) + TAILQ_INSERT_TAIL(head, hdp, hd_list); + else + TAILQ_INSERT_HEAD(head, hdp, hd_list); + + return (hdp); +} + +static void +hook_disestablish(head, vhook) + struct hook_desc_head *head; + void *vhook; +{ + struct hook_desc *hdp; + +#ifdef DIAGNOSTIC + for (hdp = TAILQ_FIRST(head); hdp != NULL; + hdp = TAILQ_NEXT(hdp, hd_list)) + if (hdp == vhook) + break; + if (hdp == NULL) + panic("hook_disestablish: hook not established"); +#endif + hdp = vhook; + TAILQ_REMOVE(head, hdp, hd_list); + free(hdp, M_DEVBUF); +} +#endif diff --git a/sys/dist/pf/net/pf_ioctl.c b/sys/dist/pf/net/pf_ioctl.c index dd25ce2babe3..2cc9d8e98bf7 100644 --- a/sys/dist/pf/net/pf_ioctl.c +++ b/sys/dist/pf/net/pf_ioctl.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf_ioctl.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */ /* $OpenBSD: pf_ioctl.c,v 1.112 2004/03/22 04:54:18 mcbride Exp $ */ /* @@ -35,7 +36,17 @@ * */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#include "opt_altq.h" +#include "opt_pfil_hooks.h" +#endif + +#ifdef __OpenBSD__ #include "pfsync.h" +#else +#define NPFSYNC 0 +#endif #include #include @@ -46,9 +57,16 @@ #include #include #include +#ifdef __OpenBSD__ #include +#else +#include +#endif #include #include +#ifdef __NetBSD__ +#include +#endif #include #include @@ -61,7 +79,9 @@ #include #include +#ifdef __OpenBSD__ #include +#endif #include #if NPFSYNC > 0 @@ -96,7 +116,30 @@ int pf_begin_rules(u_int32_t *, int, char *, char *); int pf_rollback_rules(u_int32_t, int, char *, char *); int pf_commit_rules(u_int32_t, int, char *, char *); +#ifdef __NetBSD__ +const struct cdevsw pf_cdevsw = { + pfopen, pfclose, noread, nowrite, pfioctl, + nostop, notty, nopoll, nommap, nokqfilter, +}; + +static int pf_pfil_attach(void); +static int pf_pfil_detach(void); + +POOL_INIT(pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl", + &pool_allocator_nointr); +POOL_INIT(pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0, + "pfsrctrpl", NULL); +POOL_INIT(pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl", NULL); +POOL_INIT(pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl", NULL); +POOL_INIT(pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0, + "pfpooladdrpl", NULL); +#endif + +#ifdef __OpenBSD__ extern struct timeout pf_expire_to; +#else +extern struct callout pf_expire_to; +#endif struct pf_rule pf_default_rule; @@ -113,11 +156,23 @@ static void tag_unref(struct pf_tags *, u_int16_t); #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x +#ifdef __NetBSD__ +struct pfil_head pf_ioctl_head; +struct pfil_head pf_newif_head; +extern struct pfil_head if_pfil; +#endif + void pfattach(int num) { u_int32_t *timeout = pf_default_rule.timeout; +#ifdef __NetBSD__ + pfil_head_register(&pf_ioctl_head); + pfil_head_register(&pf_newif_head); +#endif + +#ifdef __OpenBSD__ pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl", &pool_allocator_nointr); pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0, @@ -128,6 +183,7 @@ pfattach(int num) NULL); pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0, "pfpooladdrpl", NULL); +#endif pfr_initialize(); pfi_initialize(); pf_osfp_initialize(); @@ -169,8 +225,14 @@ pfattach(int num) timeout[PFTM_INTERVAL] = 10; /* Expire interval */ timeout[PFTM_SRC_NODE] = 0; /* Source tracking */ +#ifdef __OpenBSD__ timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to); timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz); +#else + callout_init(&pf_expire_to); + callout_reset(&pf_expire_to, timeout[PFTM_INTERVAL] * hz, + pf_purge_timeout, &pf_expire_to); +#endif pf_normalize_init(); bzero(&pf_status, sizeof(pf_status)); @@ -854,6 +916,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pf_status.running) error = EEXIST; else { +#ifdef __NetBSD__ + error = pf_pfil_attach(); + if (error) + break; +#endif pf_status.running = 1; pf_status.since = time.tv_sec; if (pf_status.stateid == 0) { @@ -868,6 +935,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (!pf_status.running) error = ENOENT; else { +#ifdef __NetBSD__ + error = pf_pfil_detach(); + if (error) + break; +#endif pf_status.running = 0; pf_status.since = time.tv_sec; DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n")); @@ -1606,11 +1678,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; goto fail; } +#ifdef __OpenBSD__ if (pool_sethardlimit(pf_pool_limits[pl->index].pp, pl->limit, NULL, 0) != 0) { error = EBUSY; goto fail; } +#else + pool_sethardlimit(pf_pool_limits[pl->index].pp, + pl->limit, NULL, 0); +#endif old_limit = pf_pool_limits[pl->index].limit; pf_pool_limits[pl->index].limit = pl->limit; pl->limit = old_limit; @@ -2653,3 +2730,139 @@ fail: return (error); } + +#ifdef __NetBSD__ +int +pfil4_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +{ + + /* + * If the packet is out-bound, we can't delay checksums + * here. For in-bound, the checksum has already been + * validated. + */ + if (dir == PFIL_OUT) { + if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) { + in_delayed_cksum(*mp); + (*mp)->m_pkthdr.csum_flags &= + ~(M_CSUM_TCPv4|M_CSUM_UDPv4); + } + } + + if (pf_test(dir == PFIL_OUT ? PF_OUT : PF_IN, ifp, mp) != PF_PASS) + return EHOSTUNREACH; + else + return (0); +} + +int +pfil6_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +{ + + if (pf_test6(dir == PFIL_OUT ? PF_OUT : PF_IN, ifp, mp) != PF_PASS) + return EHOSTUNREACH; + else + return (0); +} + +extern void pfi_kifaddr_update(void *); + +int +pfil_if_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +{ + u_long cmd = (u_long)mp; + + switch (cmd) { + case 0: + pfi_attach_ifnet(ifp); + break; + case SIOCSIFADDR: + case SIOCGIFALIAS: + case SIOCDIFADDR: + pfi_kifaddr_update((struct ifnet *)arg); + break; + default: + panic("unexpected ioctl"); + } + + return 0; +} + +static int +pf_pfil_attach(void) +{ + struct pfil_head *ph_inet; +#ifdef INET6 + struct pfil_head *ph_inet6; +#endif + int error; + int i; + + error = pfil_add_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF, + &if_pfil); + if (error) + return (error); + ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); + if (ph_inet) + error = pfil_add_hook((void *)pfil4_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet); + else + error = ENOENT; + if (error) { + pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF, + &if_pfil); + } +#ifdef INET6 + if (error) { + return (error); + } + ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); + if (ph_inet6) + error = pfil_add_hook((void *)pfil6_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet6); + else + error = ENOENT; + if (error) { + pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF, + &if_pfil); + pfil_remove_hook((void *)pfil4_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet); + } +#endif + if (!error) { + for (i = 0; i < if_indexlim; i++) { + if (ifindex2ifnet[i]) + pfi_attach_ifnet(ifindex2ifnet[i]); + } + } + return (error); +} + +int +pf_pfil_detach(void) +{ + struct pfil_head *ph_inet; +#ifdef INET6 + struct pfil_head *ph_inet6; +#endif + int i; + + for (i = 0; i < if_indexlim; i++) { + if (pfi_index2kif[i]) + pfi_detach_ifnet(ifindex2ifnet[i]); + } + pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF, + &if_pfil); + ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); + if (ph_inet) + pfil_remove_hook((void *)pfil4_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet); +#ifdef INET6 + ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); + if (ph_inet) + pfil_remove_hook((void *)pfil6_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet6); +#endif + return (0); +} +#endif diff --git a/sys/dist/pf/net/pf_norm.c b/sys/dist/pf/net/pf_norm.c index d2c6456d6537..a70ad82df7af 100644 --- a/sys/dist/pf/net/pf_norm.c +++ b/sys/dist/pf/net/pf_norm.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf_norm.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */ /* $OpenBSD: pf_norm.c,v 1.80 2004/03/09 21:44:41 mcbride Exp $ */ /* @@ -25,6 +26,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#endif + #include "pflog.h" #include @@ -37,7 +42,11 @@ #include #include +#ifdef __OpenBSD__ #include +#else +#include +#endif #include #include #include @@ -126,9 +135,19 @@ struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl; struct pool pf_state_scrub_pl; int pf_nfrents, pf_ncache; +#ifdef __NetBSD__ +POOL_INIT(pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent", NULL); +POOL_INIT(pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag", NULL); +POOL_INIT(pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrcache", NULL); +POOL_INIT(pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent", NULL); +POOL_INIT(pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0, + "pfstscr", NULL); +#endif + void pf_normalize_init(void) { +#ifdef __OpenBSD__ pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent", NULL); pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag", @@ -139,6 +158,7 @@ pf_normalize_init(void) NULL); pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0, "pfstscr", NULL); +#endif pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT); pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0); @@ -619,7 +639,11 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff, * than this mbuf magic. For my next trick, * I'll pull a rabbit out of my laptop. */ +#ifdef __OpenBSD__ *m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT); +#else + *m0 = m_dup(m, 0, h->ip_hl << 2, M_NOWAIT); +#endif if (*m0 == NULL) goto no_mem; KASSERT((*m0)->m_next == NULL); @@ -1290,7 +1314,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff, /* copy back packet headers if we sanitized */ if (rewrite) - m_copyback(m, off, sizeof(*th), th); + m_copyback(m, off, sizeof(*th), (caddr_t)th); return (PF_PASS); @@ -1482,8 +1506,8 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd, /* Copyback the options, caller copys back header */ *writeback = 1; m_copyback(m, off + sizeof(struct tcphdr), - (th->th_off << 2) - sizeof(struct tcphdr), hdr + - sizeof(struct tcphdr)); + (th->th_off << 2) - sizeof(struct tcphdr), + (caddr_t)hdr + sizeof(struct tcphdr)); } } diff --git a/sys/dist/pf/net/pf_osfp.c b/sys/dist/pf/net/pf_osfp.c index 98cc01ab1fb6..5348d2ef954a 100644 --- a/sys/dist/pf/net/pf_osfp.c +++ b/sys/dist/pf/net/pf_osfp.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf_osfp.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */ /* $OpenBSD: pf_osfp.c,v 1.9 2004/01/04 20:08:42 pvalchev Exp $ */ /* @@ -17,6 +18,10 @@ * */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#endif + #include #include #ifdef _KERNEL diff --git a/sys/dist/pf/net/pf_table.c b/sys/dist/pf/net/pf_table.c index 42d4cee0b7c3..d19b2d1fd3b9 100644 --- a/sys/dist/pf/net/pf_table.c +++ b/sys/dist/pf/net/pf_table.c @@ -1,3 +1,4 @@ +/* $NetBSD: pf_table.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */ /* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */ /* @@ -30,6 +31,10 @@ * */ +#ifdef _KERNEL_OPT +#include "opt_inet.h" +#endif + #include #include #include @@ -39,7 +44,9 @@ #include #include #include +#ifdef __OpenBSD__ #include +#endif #include #define ACCEPT_FLAGS(oklist) \ @@ -183,13 +190,20 @@ struct pfr_ktablehead pfr_ktables; struct pfr_table pfr_nulltable; int pfr_ktable_cnt; +#ifdef __NetBSD__ +POOL_INIT(pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0, "pfrktable", NULL); +POOL_INIT(pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0, "pfrkentry", NULL); +#endif + void pfr_initialize(void) { +#ifdef __OpenBSD__ pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0, "pfrktable", NULL); pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0, "pfrkentry", NULL); +#endif pfr_sin.sin_len = sizeof(pfr_sin); pfr_sin.sin_family = AF_INET; @@ -204,7 +218,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags) { struct pfr_ktable *kt; struct pfr_kentryworkq workq; - int s; + int s = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) @@ -239,7 +253,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentryworkq workq; struct pfr_kentry *p, *q; struct pfr_addr ad; - int i, rv, s, xadd = 0; + int i, rv, s = 0, xadd = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); @@ -317,7 +331,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentryworkq workq; struct pfr_kentry *p; struct pfr_addr ad; - int i, rv, s, xdel = 0; + int i, rv, s = 0, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) @@ -379,7 +393,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentryworkq addq, delq, changeq; struct pfr_kentry *p, *q; struct pfr_addr ad; - int i, rv, s, xadd = 0, xdel = 0, xchange = 0; + int i, rv, s = 0, xadd = 0, xdel = 0, xchange = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); @@ -567,7 +581,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, struct pfr_ktable *kt; struct pfr_walktree w; struct pfr_kentryworkq workq; - int rv, s; + int rv, s = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */ @@ -617,7 +631,7 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentryworkq workq; struct pfr_kentry *p; struct pfr_addr ad; - int i, rv, s, xzero = 0; + int i, rv, s = 0, xzero = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); if (pfr_validate_table(tbl, 0, 0)) @@ -1048,7 +1062,7 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) { struct pfr_ktableworkq workq; struct pfr_ktable *p; - int s, xdel = 0; + int s = 0, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ALLRSETS); if (pfr_table_count(filter, flags) < 0) @@ -1083,7 +1097,7 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) { struct pfr_ktableworkq addq, changeq; struct pfr_ktable *p, *q, *r, key; - int i, rv, s, xadd = 0; + int i, rv, s = 0, xadd = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); @@ -1164,7 +1178,7 @@ pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) { struct pfr_ktableworkq workq; struct pfr_ktable *p, *q, key; - int i, s, xdel = 0; + int i, s = 0, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); SLIST_INIT(&workq); @@ -1236,7 +1250,7 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, { struct pfr_ktable *p; struct pfr_ktableworkq workq; - int s, n, nn; + int s = 0, n, nn; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS); @@ -1284,7 +1298,7 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) { struct pfr_ktableworkq workq; struct pfr_ktable *p, key; - int i, s, xzero = 0; + int i, s = 0, xzero = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO); @@ -1318,7 +1332,7 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag, { struct pfr_ktableworkq workq; struct pfr_ktable *p, *q, key; - int i, s, xchange = 0, xdel = 0; + int i, s = 0, xchange = 0, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); if ((setflag & ~PFR_TFLAG_USRMASK) || @@ -1537,7 +1551,7 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, struct pfr_ktable *p; struct pfr_ktableworkq workq; struct pf_ruleset *rs; - int s, xadd = 0, xchange = 0; + int s = 0, xadd = 0, xchange = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); diff --git a/sys/dist/pf/net/pfvar.h b/sys/dist/pf/net/pfvar.h index d3dda46578e4..6886b931ac39 100644 --- a/sys/dist/pf/net/pfvar.h +++ b/sys/dist/pf/net/pfvar.h @@ -1,3 +1,4 @@ +/* $NetBSD: pfvar.h,v 1.2 2004/06/22 14:17:08 itojun Exp $ */ /* $OpenBSD: pfvar.h,v 1.187 2004/03/22 04:54:18 mcbride Exp $ */ /* @@ -38,9 +39,19 @@ #include #include +#ifdef __OpenBSD__ #include +#endif #include +#ifdef __NetBSD__ +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; +#endif + struct ip; #define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0) @@ -126,6 +137,15 @@ struct pf_addr_wrap { #ifdef _KERNEL +#ifdef __NetBSD__ +struct hook_desc { + TAILQ_ENTRY(hook_desc) hd_list; + void (*hd_fn)(void *); + void *hd_arg; +}; +TAILQ_HEAD(hook_desc_head, hook_desc); +#endif + struct pfi_dynaddr { struct pf_addr pfid_addr4; struct pf_addr pfid_mask4; @@ -811,6 +831,9 @@ struct pfi_kif { struct ifnet *pfik_ifp; int pfik_states; int pfik_rules; +#ifdef __NetBSD__ + struct hook_desc_head *pfik_ifaddrhooks; +#endif }; #define pfik_name pfik_if.pfif_name #define pfik_packets pfik_if.pfif_packets @@ -1449,6 +1472,11 @@ struct pf_pool_limit { }; extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; +#ifdef __NetBSD__ +int pfil4_wrapper(void *, struct mbuf **, struct ifnet *, int); +int pfil6_wrapper(void *, struct mbuf **, struct ifnet *, int); +int pfil_if_wrapper(void *, struct mbuf **, struct ifnet *, int); +#endif #endif /* _KERNEL */ /* The fingerprint functions can be linked into userland programs (tcpdump) */