Commit pf version 3.5 and link additional files to the kernel build.
Version 3.5 brings: - Atomic commits of ruleset changes (reduce the chance of ending up in an inconsistent state). - A 30% reduction in the size of state table entries. - Source-tracking (limit number of clients and states per client). - Sticky-address (the flexibility of round-robin with the benefits of source-hash). - Significant improvements to interface handling. - and many more ...
This commit is contained in:
parent
779616355a
commit
7c1fe95333
@ -227,6 +227,8 @@ contrib/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet
|
||||
contrib/pf/net/if_pflog.c optional pflog
|
||||
contrib/pf/net/if_pfsync.c optional pfsync
|
||||
contrib/pf/net/pf.c optional pf
|
||||
contrib/pf/net/pf_if.c optional pf
|
||||
contrib/pf/net/pf_subr.c optional pf
|
||||
contrib/pf/net/pf_ioctl.c optional pf
|
||||
contrib/pf/net/pf_norm.c optional pf
|
||||
contrib/pf/net/pf_table.c optional pf
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.c,v 1.9 2003/05/14 08:42:00 canacar 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),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
@ -151,12 +151,7 @@ pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
|
||||
MALLOC(sc, struct pflog_softc *, sizeof(*sc), M_PFLOG, M_WAITOK|M_ZERO);
|
||||
|
||||
#if (__FreeBSD_version < 501113)
|
||||
sc->sc_if.if_name = PFLOGNAME;
|
||||
sc->sc_if.if_unit = unit;
|
||||
#else
|
||||
if_initname(&sc->sc_if, ifc->ifc_name, unit);
|
||||
#endif
|
||||
sc->sc_if.if_mtu = PFLOGMTU;
|
||||
sc->sc_if.if_ioctl = pflogioctl;
|
||||
sc->sc_if.if_output = pflogoutput;
|
||||
@ -165,12 +160,6 @@ pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
|
||||
sc->sc_if.if_hdrlen = PFLOG_HDRLEN;
|
||||
sc->sc_if.if_softc = sc;
|
||||
/*
|
||||
* We would get a message like
|
||||
* "in6_ifattach: pflog0 is not multicast capable, IPv6 not enabled".
|
||||
* We need a patch to in6_ifattach() to exclude interface type
|
||||
* IFT_PFLOG.
|
||||
*/
|
||||
if_attach(&sc->sc_if);
|
||||
|
||||
LIST_INSERT_HEAD(&pflog_list, sc, sc_next);
|
||||
@ -218,24 +207,32 @@ void
|
||||
pflogstart(struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
#ifndef __FreeBSD__
|
||||
int s;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
s = splimp();
|
||||
#ifdef __FreeBSD__
|
||||
IF_LOCK(&ifp->if_snd);
|
||||
_IF_DROP(&ifp->if_snd);
|
||||
_IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL) {
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_freem(m);
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
#else
|
||||
s = splimp();
|
||||
IF_DROP(&ifp->if_snd);
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
#endif
|
||||
splx(s);
|
||||
if (m == NULL)
|
||||
return;
|
||||
else
|
||||
m_freem(m);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,38 +274,34 @@ pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
}
|
||||
|
||||
int
|
||||
pflog_packet(struct ifnet *ifp, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
|
||||
struct pf_ruleset *ruleset)
|
||||
{
|
||||
#if NBPFILTER > 0
|
||||
struct ifnet *ifn;
|
||||
struct pfloghdr hdr;
|
||||
#ifndef __FreeBSD__
|
||||
struct mbuf m1;
|
||||
#endif
|
||||
|
||||
if (ifp == NULL || m == NULL || rm == NULL)
|
||||
if (kif == NULL || m == NULL || rm == NULL)
|
||||
return (-1);
|
||||
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
hdr.length = PFLOG_REAL_HDRLEN;
|
||||
hdr.af = af;
|
||||
hdr.action = rm->action;
|
||||
hdr.reason = reason;
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version < 501113)
|
||||
snprintf(hdr.ifname, IFNAMSIZ, "%s%d", ifp->if_name, ifp->if_unit);
|
||||
#else
|
||||
memcpy(hdr.ifname, ifp->if_xname, sizeof(hdr.ifname));
|
||||
#endif
|
||||
memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
|
||||
|
||||
if (am == NULL) {
|
||||
hdr.rulenr = htonl(rm->nr);
|
||||
hdr.subrulenr = -1;
|
||||
bzero(hdr.ruleset, sizeof(hdr.ruleset));
|
||||
} else {
|
||||
hdr.rulenr = htonl(am->nr);
|
||||
hdr.subrulenr = htonl(rm->nr);
|
||||
if (ruleset == NULL)
|
||||
bzero(hdr.ruleset, sizeof(hdr.ruleset));
|
||||
else
|
||||
if (ruleset != NULL)
|
||||
memcpy(hdr.ruleset, ruleset->name,
|
||||
sizeof(hdr.ruleset));
|
||||
|
||||
@ -326,19 +319,22 @@ pflog_packet(struct ifnet *ifp, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
}
|
||||
#endif /* INET */
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
m1.m_next = m;
|
||||
m1.m_len = PFLOG_HDRLEN;
|
||||
m1.m_data = (char *) &hdr;
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
KASSERT((!LIST_EMPTY(&pflog_list)), ("pflog: no interface"));
|
||||
ifn = &LIST_FIRST(&pflog_list)->sc_if;
|
||||
BPF_MTAP2(ifn, &hdr, sizeof(hdr), m);
|
||||
#else
|
||||
ifn = &(pflogif[0].sc_if);
|
||||
#endif
|
||||
|
||||
if (ifn->if_bpf)
|
||||
bpf_mtap(ifn->if_bpf, &m1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.10 2004/03/19 04:52:04 frantzen Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
@ -55,7 +55,7 @@ struct pfloghdr {
|
||||
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
/* minus pad, also used as a signature */
|
||||
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad);
|
||||
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
|
||||
|
||||
/* XXX remove later when old format logs are no longer needed */
|
||||
struct old_pfloghdr {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.2 2002/12/11 18:31:26 mickey Exp $ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.13 2004/03/22 04:54:17 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Michael Shalayeff
|
||||
@ -30,47 +30,217 @@
|
||||
#ifndef _NET_IF_PFSYNC_H_
|
||||
#define _NET_IF_PFSYNC_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct pfsync_softc {
|
||||
struct ifnet sc_if;
|
||||
|
||||
#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;
|
||||
#ifdef __FreeBSD__
|
||||
struct callout sc_tmo;
|
||||
struct callout sc_tmo;
|
||||
struct callout sc_bulk_tmo;
|
||||
struct callout sc_bulkfail_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
struct timeout sc_tmo;
|
||||
struct timeout sc_bulk_tmo;
|
||||
struct timeout sc_bulkfail_tmo;
|
||||
#endif
|
||||
struct mbuf *sc_mbuf; /* current cummulative mbuf */
|
||||
struct pf_state *sc_ptr; /* current ongoing state */
|
||||
int sc_count; /* number of states in one mtu */
|
||||
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 */
|
||||
#ifdef __FreeBSD__
|
||||
LIST_ENTRY(pfsync_softc) sc_next;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
#define PFSYNC_VERSION 1
|
||||
#define PFSYNC_VERSION 2
|
||||
u_int8_t af;
|
||||
u_int8_t action;
|
||||
#define PFSYNC_ACT_CLR 0
|
||||
#define PFSYNC_ACT_INS 1
|
||||
#define PFSYNC_ACT_UPD 2
|
||||
#define PFSYNC_ACT_DEL 3
|
||||
#define PFSYNC_ACT_MAX 4
|
||||
#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"
|
||||
"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 { \
|
||||
@ -78,15 +248,47 @@ struct pfsync_header {
|
||||
(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
|
||||
int pfsync_clear_state(struct pf_state *);
|
||||
int pfsync_pack_state(u_int8_t, struct pf_state *);
|
||||
#define pfsync_insert_state(st) pfsync_pack_state(PFSYNC_ACT_INS, (st))
|
||||
#define pfsync_update_state(st) pfsync_pack_state(PFSYNC_ACT_UPD, (st))
|
||||
#define pfsync_delete_state(st) pfsync_pack_state(PFSYNC_ACT_DEL, (st))
|
||||
#ifdef __FreeBSD__
|
||||
void pfsync_input(struct mbuf *, __unused int);
|
||||
#else
|
||||
void pfsync_input(struct mbuf *, ...);
|
||||
#endif
|
||||
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_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
|
||||
|
||||
/*
|
||||
@ -30,14 +31,24 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/malloc.h>
|
||||
#endif
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/kernel.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/device.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
@ -65,12 +76,16 @@
|
||||
#define senderr(e) do { rv = (e); goto _bad; } while (0)
|
||||
|
||||
struct pfi_kif **pfi_index2kif;
|
||||
struct pfi_kif *pfi_self;
|
||||
struct pfi_kif *pfi_self, *pfi_dummy;
|
||||
int pfi_indexlim;
|
||||
struct pfi_ifhead pfi_ifs;
|
||||
struct pfi_statehead pfi_statehead;
|
||||
int pfi_ifcnt;
|
||||
#ifdef __FreeBSD__
|
||||
uma_zone_t pfi_addr_pl;
|
||||
#else
|
||||
struct pool pfi_addr_pl;
|
||||
#endif
|
||||
long pfi_update = 1;
|
||||
struct pfr_addr *pfi_buffer;
|
||||
int pfi_buffer_cnt;
|
||||
@ -79,6 +94,11 @@ char pfi_reserved_anchor[PF_ANCHOR_NAME_SIZE] =
|
||||
PF_RESERVED_ANCHOR;
|
||||
char pfi_interface_ruleset[PF_RULESET_NAME_SIZE] =
|
||||
PF_INTERFACE_RULESET;
|
||||
#ifdef __FreeBSD__
|
||||
eventhandler_tag pfi_clone_cookie = NULL;
|
||||
eventhandler_tag pfi_attach_cookie = NULL;
|
||||
eventhandler_tag pfi_detach_cookie = NULL;
|
||||
#endif
|
||||
|
||||
void pfi_dynaddr_update(void *);
|
||||
void pfi_kifaddr_update(void *);
|
||||
@ -94,30 +114,152 @@ void pfi_newgroup(const char *, int);
|
||||
int pfi_skip_if(const char *, struct pfi_kif *, int);
|
||||
int pfi_unmask(void *);
|
||||
void pfi_dohooks(struct pfi_kif *);
|
||||
#ifdef __FreeBSD__
|
||||
void pfi_kifaddr_update_event(void *, struct ifnet *);
|
||||
void pfi_attach_clone_event(void * __unused, struct if_clone *);
|
||||
void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
|
||||
void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
|
||||
#endif
|
||||
|
||||
RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
|
||||
RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
|
||||
|
||||
#define PFI_DYNAMIC_BUSES { "pcmcia", "cardbus", "uhub" }
|
||||
#define PFI_BUFFER_MAX 0x10000
|
||||
#ifdef __FreeBSD__
|
||||
MALLOC_DEFINE(PFI_MTYPE, "pf_if", "pf interface table");
|
||||
#else
|
||||
#define PFI_MTYPE M_IFADDR
|
||||
#endif
|
||||
|
||||
void
|
||||
pfi_initialize(void)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *ifp;
|
||||
#endif
|
||||
|
||||
if (pfi_self != NULL) /* already initialized */
|
||||
return;
|
||||
|
||||
TAILQ_INIT(&pfi_statehead);
|
||||
#ifndef __FreeBSD__
|
||||
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);
|
||||
pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP);
|
||||
pfi_dynamic_drivers();
|
||||
#ifdef __FreeBSD__
|
||||
PF_LOCK();
|
||||
IFNET_RLOCK();
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_link)
|
||||
if (ifp->if_dunit != IF_DUNIT_NONE) {
|
||||
IFNET_RUNLOCK();
|
||||
pfi_attach_ifnet(ifp);
|
||||
IFNET_RLOCK();
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
PF_UNLOCK();
|
||||
pfi_dummy = pfi_if_create("notyet", pfi_self,
|
||||
PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC);
|
||||
pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_arrival_event,
|
||||
pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||
pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_clone_cookie = EVENTHANDLER_REGISTER(if_clone_event,
|
||||
pfi_attach_clone_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
void
|
||||
pfi_cleanup(void)
|
||||
{
|
||||
struct pfi_kif *p, key;
|
||||
struct ifnet *ifp;
|
||||
|
||||
PF_ASSERT(MA_OWNED);
|
||||
PF_UNLOCK();
|
||||
|
||||
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, pfi_attach_cookie);
|
||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event, pfi_detach_cookie);
|
||||
EVENTHANDLER_DEREGISTER(if_clone_event, pfi_clone_cookie);
|
||||
|
||||
IFNET_RLOCK();
|
||||
/* release PFI_IFLAG_INSTANCE */
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_link) {
|
||||
strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
|
||||
p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
|
||||
if (p != NULL) {
|
||||
PF_LOCK();
|
||||
pfi_detach_ifnet(ifp);
|
||||
PF_UNLOCK();
|
||||
}
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
|
||||
PF_LOCK();
|
||||
/* XXX clear all other interface group */
|
||||
while ((p = RB_MIN(pfi_ifhead, &pfi_ifs))) {
|
||||
RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
|
||||
|
||||
free(p->pfik_ah_head, PFI_MTYPE);
|
||||
free(p, PFI_MTYPE);
|
||||
}
|
||||
free(pfi_index2kif, PFI_MTYPE);
|
||||
free(pfi_buffer, PFI_MTYPE);
|
||||
pfi_index2kif = NULL;
|
||||
pfi_buffer = NULL;
|
||||
pfi_self = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper functions for FreeBSD eventhandler
|
||||
*/
|
||||
void
|
||||
pfi_kifaddr_update_event(void *arg, struct ifnet *ifp)
|
||||
{
|
||||
struct pfi_kif *p = arg;
|
||||
|
||||
PF_LOCK();
|
||||
/*
|
||||
* Check to see if it is 'our' interface as we do not have per
|
||||
* interface hooks and thus get an update for every interface.
|
||||
*/
|
||||
if (p && p->pfik_ifp == ifp)
|
||||
pfi_kifaddr_update(p);
|
||||
PF_UNLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_attach_clone_event(void *arg __unused, struct if_clone *ifc)
|
||||
{
|
||||
PF_LOCK();
|
||||
pfi_attach_clone(ifc);
|
||||
PF_UNLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
PF_LOCK();
|
||||
if (ifp->if_dunit != IF_DUNIT_NONE)
|
||||
pfi_attach_ifnet(ifp);
|
||||
PF_UNLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
PF_LOCK();
|
||||
pfi_detach_ifnet(ifp);
|
||||
PF_UNLOCK();
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
void
|
||||
pfi_attach_clone(struct if_clone *ifc)
|
||||
{
|
||||
@ -130,6 +272,9 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
{
|
||||
struct pfi_kif *p, *q, key;
|
||||
int s;
|
||||
#ifdef __FreeBSD__
|
||||
int realname;
|
||||
#endif
|
||||
|
||||
pfi_initialize();
|
||||
s = splsoftnet();
|
||||
@ -150,7 +295,11 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
m = oldlim * sizeof(struct pfi_kif *);
|
||||
mp = pfi_index2kif;
|
||||
n = pfi_indexlim * sizeof(struct pfi_kif *);
|
||||
#ifdef __FreeBSD__
|
||||
np = malloc(n, PFI_MTYPE, M_NOWAIT);
|
||||
#else
|
||||
np = malloc(n, PFI_MTYPE, M_DONTWAIT);
|
||||
#endif
|
||||
if (np == NULL)
|
||||
panic("pfi_attach_ifnet: "
|
||||
"cannot allocate translation table");
|
||||
@ -164,6 +313,54 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
|
||||
strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
|
||||
p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
|
||||
#ifdef __FreeBSD__
|
||||
/* some additional trickery for placeholders */
|
||||
if ((p == NULL) || (p->pfik_parent == pfi_dummy)) {
|
||||
/* are we looking at a renamed instance or not? */
|
||||
pfi_copy_group(key.pfik_name, ifp->if_xname,
|
||||
sizeof(key.pfik_name));
|
||||
realname = (strncmp(key.pfik_name, ifp->if_dname,
|
||||
sizeof(key.pfik_name)) == 0);
|
||||
/* add group */
|
||||
/* we can change if_xname, hence use if_dname as group id */
|
||||
pfi_copy_group(key.pfik_name, ifp->if_dname,
|
||||
sizeof(key.pfik_name));
|
||||
q = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
|
||||
if (q == NULL)
|
||||
q = pfi_if_create(key.pfik_name, pfi_self,
|
||||
PFI_IFLAG_GROUP|PFI_IFLAG_DYNAMIC);
|
||||
else if (q->pfik_parent == pfi_dummy) {
|
||||
q->pfik_parent = pfi_self;
|
||||
q->pfik_flags = (PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC);
|
||||
}
|
||||
if (q == NULL)
|
||||
panic("pfi_attach_ifnet: "
|
||||
"cannot allocate '%s' group", key.pfik_name);
|
||||
|
||||
/* add/modify interface */
|
||||
if (p == NULL)
|
||||
p = pfi_if_create(ifp->if_xname, q,
|
||||
realname?PFI_IFLAG_INSTANCE:PFI_IFLAG_PLACEHOLDER);
|
||||
else {
|
||||
/* remove from the dummy group */
|
||||
/* XXX: copy stats? We should not have any!!! */
|
||||
pfi_dummy->pfik_delcnt++;
|
||||
TAILQ_REMOVE(&pfi_dummy->pfik_grouphead, p,
|
||||
pfik_instances);
|
||||
/* move to the right group */
|
||||
p->pfik_parent = q;
|
||||
q->pfik_addcnt++;
|
||||
TAILQ_INSERT_TAIL(&q->pfik_grouphead, p,
|
||||
pfik_instances);
|
||||
if (realname) {
|
||||
p->pfik_flags &= ~PFI_IFLAG_PLACEHOLDER;
|
||||
p->pfik_flags |= PFI_IFLAG_INSTANCE;
|
||||
}
|
||||
}
|
||||
if (p == NULL)
|
||||
panic("pfi_attach_ifnet: "
|
||||
"cannot allocate '%s' interface", ifp->if_xname);
|
||||
#else
|
||||
if (p == NULL) {
|
||||
/* add group */
|
||||
pfi_copy_group(key.pfik_name, ifp->if_xname,
|
||||
@ -171,6 +368,10 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
q = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
|
||||
if (q == NULL)
|
||||
q = pfi_if_create(key.pfik_name, pfi_self, PFI_IFLAG_GROUP);
|
||||
else if (q->pfik_parent == pfi_dummy) {
|
||||
q->pfik_parent = pfi_self;
|
||||
q->pfik_flags = (PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC);
|
||||
}
|
||||
if (q == NULL)
|
||||
panic("pfi_attach_ifnet: "
|
||||
"cannot allocate '%s' group", key.pfik_name);
|
||||
@ -180,12 +381,20 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
if (p == NULL)
|
||||
panic("pfi_attach_ifnet: "
|
||||
"cannot allocate '%s' interface", ifp->if_xname);
|
||||
#endif
|
||||
} else
|
||||
q = p->pfik_parent;
|
||||
p->pfik_ifp = ifp;
|
||||
p->pfik_flags |= PFI_IFLAG_ATTACHED;
|
||||
#ifdef __FreeBSD__
|
||||
PF_UNLOCK();
|
||||
p->pfik_ah_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
|
||||
pfi_kifaddr_update_event, p, EVENTHANDLER_PRI_ANY);
|
||||
PF_LOCK();
|
||||
#else
|
||||
p->pfik_ah_cookie =
|
||||
hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p);
|
||||
#endif
|
||||
pfi_index2kif[ifp->if_index] = p;
|
||||
pfi_dohooks(p);
|
||||
splx(s);
|
||||
@ -207,7 +416,13 @@ pfi_detach_ifnet(struct ifnet *ifp)
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
PF_UNLOCK();
|
||||
EVENTHANDLER_DEREGISTER(ifaddr_event, p->pfik_ah_cookie);
|
||||
PF_LOCK();
|
||||
#else
|
||||
hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie);
|
||||
#endif
|
||||
q = p->pfik_parent;
|
||||
p->pfik_ifp = NULL;
|
||||
p->pfik_flags &= ~PFI_IFLAG_ATTACHED;
|
||||
@ -228,8 +443,19 @@ pfi_lookup_create(const char *name)
|
||||
if (p == NULL) {
|
||||
pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name));
|
||||
q = pfi_lookup_if(key.pfik_name);
|
||||
#ifdef __FreeBSD__
|
||||
if ((q != NULL) && (q->pfik_parent != pfi_dummy))
|
||||
p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE);
|
||||
else {
|
||||
if (pfi_dummy == NULL)
|
||||
panic("no 'notyet' dummy group");
|
||||
p = pfi_if_create(name, pfi_dummy,
|
||||
PFI_IFLAG_PLACEHOLDER);
|
||||
}
|
||||
#else
|
||||
if (q != NULL)
|
||||
p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE);
|
||||
#endif
|
||||
}
|
||||
splx(s);
|
||||
return (p);
|
||||
@ -467,8 +693,13 @@ pfi_address_add(struct sockaddr *sa, int af, int net)
|
||||
pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
return;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE,
|
||||
M_NOWAIT);
|
||||
#else
|
||||
p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE,
|
||||
M_DONTWAIT);
|
||||
#endif
|
||||
if (p == NULL) {
|
||||
printf("pfi_address_add: no memory to grow buffer "
|
||||
"(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
@ -552,12 +783,21 @@ pfi_if_create(const char *name, struct pfi_kif *q, int flags)
|
||||
{
|
||||
struct pfi_kif *p;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
p = malloc(sizeof(*p), PFI_MTYPE, M_NOWAIT);
|
||||
#else
|
||||
p = malloc(sizeof(*p), PFI_MTYPE, M_DONTWAIT);
|
||||
#endif
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
bzero(p, sizeof(*p));
|
||||
#ifdef __FreeBSD__
|
||||
p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE,
|
||||
M_NOWAIT);
|
||||
#else
|
||||
p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE,
|
||||
M_DONTWAIT);
|
||||
#endif
|
||||
if (p->pfik_ah_head == NULL) {
|
||||
free(p, PFI_MTYPE);
|
||||
return (NULL);
|
||||
@ -570,7 +810,11 @@ pfi_if_create(const char *name, struct pfi_kif *q, int flags)
|
||||
RB_INIT(&p->pfik_ext_gwy);
|
||||
p->pfik_flags = flags;
|
||||
p->pfik_parent = q;
|
||||
#ifdef __FreeBSD__
|
||||
p->pfik_tzero = time_second;
|
||||
#else
|
||||
p->pfik_tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
RB_INSERT(pfi_ifhead, &pfi_ifs, p);
|
||||
if (q != NULL) {
|
||||
@ -589,6 +833,9 @@ pfi_maybe_destroy(struct pfi_kif *p)
|
||||
|
||||
if ((p->pfik_flags & (PFI_IFLAG_ATTACHED | PFI_IFLAG_GROUP)) ||
|
||||
p->pfik_rules > 0 || p->pfik_states > 0)
|
||||
#ifdef __FreeBSD__
|
||||
if (!(p->pfik_flags & PFI_IFLAG_PLACEHOLDER))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
s = splsoftnet();
|
||||
@ -600,10 +847,25 @@ pfi_maybe_destroy(struct pfi_kif *p)
|
||||
p->pfik_bytes[i][j][k];
|
||||
q->pfik_packets[i][j][k] +=
|
||||
p->pfik_packets[i][j][k];
|
||||
#ifdef __FreeBSD__
|
||||
/* clear stats in case we return to the dummy group */
|
||||
p->pfik_bytes[i][j][k] = 0;
|
||||
p->pfik_packets[i][j][k] = 0;
|
||||
#endif
|
||||
}
|
||||
q->pfik_delcnt++;
|
||||
TAILQ_REMOVE(&q->pfik_grouphead, p, pfik_instances);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (p->pfik_rules > 0 || p->pfik_states > 0) {
|
||||
/* move back to the dummy group */
|
||||
p->pfik_parent = pfi_dummy;
|
||||
pfi_dummy->pfik_addcnt++;
|
||||
TAILQ_INSERT_TAIL(&pfi_dummy->pfik_grouphead, p,
|
||||
pfik_instances);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
pfi_ifcnt--;
|
||||
RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
|
||||
splx(s);
|
||||
@ -627,6 +889,22 @@ pfi_copy_group(char *p, const char *q, int m)
|
||||
void
|
||||
pfi_dynamic_drivers(void)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *ifp;
|
||||
|
||||
/*
|
||||
* For FreeBSD basically every interface is "dynamic" as we can unload
|
||||
* modules e.g.
|
||||
*/
|
||||
|
||||
IFNET_RLOCK();
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_link) {
|
||||
if (ifp->if_dunit == IF_DUNIT_NONE)
|
||||
continue;
|
||||
pfi_newgroup(ifp->if_dname, PFI_IFLAG_DYNAMIC);
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
#else
|
||||
char *buses[] = PFI_DYNAMIC_BUSES;
|
||||
int nbuses = sizeof(buses)/sizeof(buses[0]);
|
||||
int enabled[sizeof(buses)/sizeof(buses[0])];
|
||||
@ -662,6 +940,7 @@ pfi_dynamic_drivers(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -710,7 +989,11 @@ pfi_clr_istats(const char *name, int *nzero, int flags)
|
||||
{
|
||||
struct pfi_kif *p;
|
||||
int n = 0, s;
|
||||
#ifdef __FreeBSD__
|
||||
long tzero = time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
|
||||
@ -733,6 +1016,9 @@ pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
|
||||
{
|
||||
struct pfi_kif *p;
|
||||
int s, n = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
|
||||
s = splsoftnet();
|
||||
@ -742,7 +1028,12 @@ pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
|
||||
if (*size > n++) {
|
||||
if (!p->pfik_tzero)
|
||||
p->pfik_tzero = boottime.tv_sec;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(p, buf++, sizeof(*buf), ec);
|
||||
if (ec) {
|
||||
#else
|
||||
if (copyout(p, buf++, sizeof(*buf))) {
|
||||
#endif
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.75.2.1 2004/04/30 23:28:36 brad Exp $ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.80 2004/03/09 21:44:41 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -502,7 +502,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
|
||||
if (frep != NULL &&
|
||||
FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl *
|
||||
4 > off)
|
||||
4 > off)
|
||||
{
|
||||
u_int16_t precut;
|
||||
|
||||
@ -797,13 +797,16 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
h = mtod(m, struct ip *);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
KASSERT(((int)m->m_len == ntohs(h->ip_len) - precut),
|
||||
KASSERT(((int)m->m_len ==
|
||||
ntohs(h->ip_len) - precut),
|
||||
("m->m_len != ntohs(h->ip_len) - precut: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT((int)m->m_len == ntohs(h->ip_len) - precut);
|
||||
KASSERT((int)m->m_len ==
|
||||
ntohs(h->ip_len) - precut);
|
||||
#endif
|
||||
h->ip_off = htons(ntohs(h->ip_off) + (precut >> 3));
|
||||
h->ip_off = htons(ntohs(h->ip_off) +
|
||||
(precut >> 3));
|
||||
h->ip_len = htons(ntohs(h->ip_len) - precut);
|
||||
} else {
|
||||
hosed++;
|
||||
@ -862,7 +865,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
("m->m_len != ntohs(h->ip_len) - aftercut: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT((int)m->m_len == ntohs(h->ip_len) - aftercut);
|
||||
KASSERT((int)m->m_len ==
|
||||
ntohs(h->ip_len) - aftercut);
|
||||
#endif
|
||||
h->ip_len = htons(ntohs(h->ip_len) - aftercut);
|
||||
} else {
|
||||
@ -982,7 +986,7 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
}
|
||||
|
||||
int
|
||||
pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct pf_rule *r;
|
||||
@ -999,7 +1003,8 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->ifp != NULL && r->ifp != ifp)
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -1162,13 +1167,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
no_mem:
|
||||
REASON_SET(reason, PFRES_MEMORY);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
|
||||
drop:
|
||||
REASON_SET(reason, PFRES_NORM);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
|
||||
bad:
|
||||
@ -1180,14 +1185,15 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
|
||||
REASON_SET(reason, PFRES_FRAG);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
|
||||
return (PF_DROP);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
int
|
||||
pf_normalize_ip6(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
u_short *reason)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct pf_rule *r;
|
||||
@ -1207,7 +1213,8 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->ifp != NULL && r->ifp != ifp)
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -1341,25 +1348,25 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
|
||||
shortpkt:
|
||||
REASON_SET(reason, PFRES_SHORT);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
|
||||
drop:
|
||||
REASON_SET(reason, PFRES_NORM);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
|
||||
badfrag:
|
||||
REASON_SET(reason, PFRES_FRAG);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
|
||||
pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
int off, void *h, struct pf_pdesc *pd)
|
||||
{
|
||||
struct pf_rule *r, *rm = NULL;
|
||||
@ -1372,7 +1379,8 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->ifp != NULL && r->ifp != ifp)
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -1465,7 +1473,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
|
||||
tcp_drop:
|
||||
REASON_SET(&reason, PFRES_NORM);
|
||||
if (rm != NULL && r->log)
|
||||
PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL);
|
||||
return (PF_DROP);
|
||||
}
|
||||
|
||||
@ -1511,7 +1519,7 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
* the connections. They must all set an enabled bit in pfss_flags
|
||||
*/
|
||||
if ((th->th_flags & TH_SYN) == 0)
|
||||
return 0;
|
||||
return (0);
|
||||
|
||||
|
||||
if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
|
||||
@ -1535,8 +1543,8 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
hlen -= MAX(opt[1], 2);
|
||||
opt += MAX(opt[1], 2);
|
||||
hlen -= opt[1];
|
||||
opt += opt[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1591,7 +1599,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6: {
|
||||
if (dst->scrub) {
|
||||
if (src->scrub) {
|
||||
struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
|
||||
if (h->ip6_hlim > src->scrub->pfss_ttl)
|
||||
src->scrub->pfss_ttl = h->ip6_hlim;
|
||||
@ -1635,11 +1643,13 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
&th->th_sum, ts_value, 0);
|
||||
copyback = 1;
|
||||
}
|
||||
if (dst->scrub &&
|
||||
|
||||
/* Modulate TS reply iff valid (!0) */
|
||||
memcpy(&ts_value, &opt[6],
|
||||
sizeof(u_int32_t));
|
||||
if (ts_value && dst->scrub &&
|
||||
(dst->scrub->pfss_flags &
|
||||
PFSS_TIMESTAMP)) {
|
||||
memcpy(&ts_value, &opt[6],
|
||||
sizeof(u_int32_t));
|
||||
ts_value = htonl(ntohl(ts_value)
|
||||
- dst->scrub->pfss_ts_mod);
|
||||
pf_change_a(&opt[6],
|
||||
@ -1649,8 +1659,8 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
hlen -= MAX(opt[1], 2);
|
||||
opt += MAX(opt[1], 2);
|
||||
hlen -= opt[1];
|
||||
opt += opt[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.3 2003/08/27 18:23:36 frantzen Exp $ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.9 2004/01/04 20:08:42 pvalchev Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
@ -54,6 +54,7 @@ typedef struct pool pool_t;
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# define pool_t int
|
||||
# define pool_get(pool, flags) malloc(*(pool))
|
||||
# define pool_put(pool, item) free(item)
|
||||
@ -64,7 +65,7 @@ typedef struct pool pool_t;
|
||||
# endif
|
||||
|
||||
# ifdef PFDEBUG
|
||||
# include <stdarg.h>
|
||||
# include <sys/stdarg.h>
|
||||
# define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
# else
|
||||
# define DPFPRINTF(format, x...) ((void)0)
|
||||
|
127
sys/contrib/pf/net/pf_subr.c
Normal file
127
sys/contrib/pf/net/pf_subr.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* $FreeBSD$ */
|
||||
/* from $OpenBSD: kern_subr.c,v 1.26 2003/10/31 11:10:41 markus Exp $ */
|
||||
/* $NetBSD: kern_subr.c,v 1.15 1996/04/09 17:21:56 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 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.
|
||||
*
|
||||
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/resourcevar.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <net/pfvar.h>
|
||||
|
||||
/*
|
||||
* This implements additional functions used by pf which can not be ported
|
||||
* easyly. At this point it boils down to mostly the Net/OpenBSD hook
|
||||
* implementation.
|
||||
*
|
||||
* BEWARE: this is not locked! Required locking is done by the caller.
|
||||
*/
|
||||
|
||||
void *
|
||||
hook_establish(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);
|
||||
}
|
||||
|
||||
void
|
||||
hook_disestablish(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run hooks. Startup hooks are invoked right after scheduler_start but
|
||||
* before root is mounted. Shutdown hooks are invoked immediately before the
|
||||
* system is halted or rebooted, i.e. after file systems unmounted,
|
||||
* after crash dump done, etc.
|
||||
*/
|
||||
void
|
||||
dohooks(struct hook_desc_head *head, int flags)
|
||||
{
|
||||
struct hook_desc *hdp;
|
||||
|
||||
if ((flags & HOOK_REMOVE) == 0) {
|
||||
TAILQ_FOREACH(hdp, head, hd_list) {
|
||||
(*hdp->hd_fn)(hdp->hd_arg);
|
||||
}
|
||||
} else {
|
||||
while ((hdp = TAILQ_FIRST(head)) != NULL) {
|
||||
TAILQ_REMOVE(head, hdp, hd_list);
|
||||
(*hdp->hd_fn)(hdp->hd_arg);
|
||||
if ((flags & HOOK_FREE) != 0)
|
||||
free(hdp, M_DEVBUF);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_table.c,v 1.41 2003/08/22 15:19:23 henning Exp $ */
|
||||
/* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -61,6 +61,55 @@
|
||||
return (EINVAL); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static inline int
|
||||
_copyin(const void *uaddr, void *kaddr, size_t len)
|
||||
{
|
||||
int r;
|
||||
|
||||
PF_UNLOCK();
|
||||
r = copyin(uaddr, kaddr, len);
|
||||
PF_LOCK();
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_copyout(const void *uaddr, void *kaddr, size_t len)
|
||||
{
|
||||
int r;
|
||||
|
||||
PF_UNLOCK();
|
||||
r = copyout(uaddr, kaddr, len);
|
||||
PF_LOCK();
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
#define COPYIN(from, to, size) \
|
||||
((flags & PFR_FLAG_USERIOCTL) ? \
|
||||
_copyin((from), (to), (size)) : \
|
||||
(bcopy((from), (to), (size)), 0))
|
||||
|
||||
#define COPYOUT(from, to, size) \
|
||||
((flags & PFR_FLAG_USERIOCTL) ? \
|
||||
_copyout((from), (to), (size)) : \
|
||||
(bcopy((from), (to), (size)), 0))
|
||||
|
||||
#else
|
||||
|
||||
#define COPYIN(from, to, size) \
|
||||
((flags & PFR_FLAG_USERIOCTL) ? \
|
||||
copyin((from), (to), (size)) : \
|
||||
(bcopy((from), (to), (size)), 0))
|
||||
|
||||
#define COPYOUT(from, to, size) \
|
||||
((flags & PFR_FLAG_USERIOCTL) ? \
|
||||
copyout((from), (to), (size)) : \
|
||||
(bcopy((from), (to), (size)), 0))
|
||||
|
||||
#endif
|
||||
|
||||
#define FILLIN_SIN(sin, addr) \
|
||||
do { \
|
||||
(sin).sin_len = sizeof(sin); \
|
||||
@ -83,8 +132,8 @@
|
||||
} while (0)
|
||||
|
||||
#define SUNION2PF(su, af) (((af)==AF_INET) ? \
|
||||
(struct pf_addr *)&(su)->sin.sin_addr : \
|
||||
(struct pf_addr *)&(su)->sin6.sin6_addr)
|
||||
(struct pf_addr *)&(su)->sin.sin_addr : \
|
||||
(struct pf_addr *)&(su)->sin6.sin6_addr)
|
||||
|
||||
#define AF_BITS(af) (((af)==AF_INET)?32:128)
|
||||
#define ADDR_NETWORK(ad) ((ad)->pfra_net < AF_BITS((ad)->pfra_af))
|
||||
@ -103,20 +152,24 @@ struct pfr_walktree {
|
||||
PFRW_ENQUEUE,
|
||||
PFRW_GET_ADDRS,
|
||||
PFRW_GET_ASTATS,
|
||||
PFRW_POOL_GET
|
||||
PFRW_POOL_GET,
|
||||
PFRW_DYNADDR_UPDATE
|
||||
} pfrw_op;
|
||||
union {
|
||||
struct pfr_addr *pfrw1_addr;
|
||||
struct pfr_astats *pfrw1_astats;
|
||||
struct pfr_kentryworkq *pfrw1_workq;
|
||||
struct pfr_kentry *pfrw1_kentry;
|
||||
struct pfi_dynaddr *pfrw1_dyn;
|
||||
} pfrw_1;
|
||||
int pfrw_free;
|
||||
int pfrw_flags;
|
||||
};
|
||||
#define pfrw_addr pfrw_1.pfrw1_addr
|
||||
#define pfrw_astats pfrw_1.pfrw1_astats
|
||||
#define pfrw_workq pfrw_1.pfrw1_workq
|
||||
#define pfrw_kentry pfrw_1.pfrw1_kentry
|
||||
#define pfrw_dyn pfrw_1.pfrw1_dyn
|
||||
#define pfrw_cnt pfrw_free
|
||||
|
||||
#define senderr(e) do { rv = (e); goto _bad; } while (0)
|
||||
@ -130,7 +183,7 @@ struct pool pfr_kentry_pl;
|
||||
#endif
|
||||
struct sockaddr_in pfr_sin;
|
||||
struct sockaddr_in6 pfr_sin6;
|
||||
union sockaddr_union pfr_mask;
|
||||
union sockaddr_union pfr_mask;
|
||||
struct pf_addr pfr_ffaddr;
|
||||
|
||||
void pfr_copyout_addr(struct pfr_addr *,
|
||||
@ -150,14 +203,14 @@ void pfr_remove_kentries(struct pfr_ktable *,
|
||||
struct pfr_kentryworkq *);
|
||||
void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
|
||||
int);
|
||||
void pfr_reset_feedback(struct pfr_addr *, int);
|
||||
void pfr_reset_feedback(struct pfr_addr *, int, int);
|
||||
void pfr_prepare_network(union sockaddr_union *, int, int);
|
||||
int pfr_route_kentry(struct pfr_ktable *,
|
||||
struct pfr_kentry *);
|
||||
int pfr_unroute_kentry(struct pfr_ktable *,
|
||||
struct pfr_kentry *);
|
||||
int pfr_walktree(struct radix_node *, void *);
|
||||
int pfr_validate_table(struct pfr_table *, int);
|
||||
int pfr_validate_table(struct pfr_table *, int, int);
|
||||
void pfr_commit_ktable(struct pfr_ktable *, long);
|
||||
void pfr_insert_ktables(struct pfr_ktableworkq *);
|
||||
void pfr_insert_ktable(struct pfr_ktable *);
|
||||
@ -172,12 +225,12 @@ void pfr_destroy_ktable(struct pfr_ktable *, int);
|
||||
int pfr_ktable_compare(struct pfr_ktable *,
|
||||
struct pfr_ktable *);
|
||||
struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
|
||||
void pfr_clean_node_mask(struct pfr_ktable *,
|
||||
void pfr_clean_node_mask(struct pfr_ktable *,
|
||||
struct pfr_kentryworkq *);
|
||||
int pfr_table_count(struct pfr_table *, int);
|
||||
int pfr_skip_table(struct pfr_table *,
|
||||
struct pfr_ktable *, int);
|
||||
struct pfr_kentry *pfr_kentry_byidx(struct pfr_ktable *, int, int);
|
||||
struct pfr_kentry *pfr_kentry_byidx(struct pfr_ktable *, int, int);
|
||||
|
||||
RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
|
||||
RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
|
||||
@ -212,7 +265,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
|
||||
int s;
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -246,7 +299,6 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xadd = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
@ -256,7 +308,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -268,14 +320,8 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (ENOMEM);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
@ -302,17 +348,10 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
xadd++;
|
||||
}
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
pfr_clean_node_mask(tmpkt, &workq);
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
@ -331,7 +370,7 @@ _bad:
|
||||
pfr_clean_node_mask(tmpkt, &workq);
|
||||
pfr_destroy_kentries(&workq);
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
pfr_reset_feedback(addr, size);
|
||||
pfr_reset_feedback(addr, size, flags);
|
||||
pfr_destroy_ktable(tmpkt, 0);
|
||||
return (rv);
|
||||
}
|
||||
@ -345,12 +384,9 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xdel = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -360,14 +396,8 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
pfr_mark_addrs(kt);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
@ -387,17 +417,9 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
|
||||
xdel++;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
if (flags & PFR_FLAG_ATOMIC)
|
||||
@ -411,7 +433,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (0);
|
||||
_bad:
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
pfr_reset_feedback(addr, size);
|
||||
pfr_reset_feedback(addr, size, flags);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -425,7 +447,6 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xadd = 0, xdel = 0, xchange = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
@ -435,7 +456,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -450,14 +471,8 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
SLIST_INIT(&delq);
|
||||
SLIST_INIT(&changeq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
ad.pfra_fback = PFR_FB_NONE;
|
||||
@ -492,17 +507,9 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
}
|
||||
}
|
||||
_skip:
|
||||
#ifdef __FreeBSD__
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
pfr_enqueue_addrs(kt, &delq, &xdel, ENQUEUE_UNMARKED_ONLY);
|
||||
if ((flags & PFR_FLAG_FEEDBACK) && *size2) {
|
||||
@ -514,14 +521,8 @@ _skip:
|
||||
SLIST_FOREACH(p, &delq, pfrke_workq) {
|
||||
pfr_copyout_addr(&ad, p);
|
||||
ad.pfra_fback = PFR_FB_DELETED;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&ad, addr+size+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&ad, addr+size+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+size+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -542,7 +543,7 @@ _skip:
|
||||
*ndel = xdel;
|
||||
if (nchange != NULL)
|
||||
*nchange = xchange;
|
||||
if ((flags & PFR_FLAG_FEEDBACK) && *size2)
|
||||
if ((flags & PFR_FLAG_FEEDBACK) && size2)
|
||||
*size2 = size+xdel;
|
||||
pfr_destroy_ktable(tmpkt, 0);
|
||||
return (0);
|
||||
@ -550,7 +551,7 @@ _bad:
|
||||
pfr_clean_node_mask(tmpkt, &addq);
|
||||
pfr_destroy_kentries(&addq);
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
pfr_reset_feedback(addr, size);
|
||||
pfr_reset_feedback(addr, size, flags);
|
||||
pfr_destroy_ktable(tmpkt, 0);
|
||||
return (rv);
|
||||
}
|
||||
@ -563,26 +564,17 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, xmatch = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_REPLACE);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, 0))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
return (ESRCH);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
return (EINVAL);
|
||||
if (ADDR_NETWORK(&ad))
|
||||
@ -594,14 +586,8 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
(p->pfrke_not ? PFR_FB_NOTMATCH : PFR_FB_MATCH);
|
||||
if (p != NULL && !p->pfrke_not)
|
||||
xmatch++;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (nmatch != NULL)
|
||||
*nmatch = xmatch;
|
||||
@ -617,7 +603,7 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
|
||||
int rv;
|
||||
|
||||
ACCEPT_FLAGS(0);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, 0))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -631,6 +617,7 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
|
||||
w.pfrw_op = PFRW_GET_ADDRS;
|
||||
w.pfrw_addr = addr;
|
||||
w.pfrw_free = kt->pfrkt_cnt;
|
||||
w.pfrw_flags = flags;
|
||||
#ifdef __FreeBSD__
|
||||
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
@ -673,7 +660,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, 0))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -687,6 +674,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
|
||||
w.pfrw_op = PFRW_GET_ASTATS;
|
||||
w.pfrw_astats = addr;
|
||||
w.pfrw_free = kt->pfrkt_cnt;
|
||||
w.pfrw_flags = flags;
|
||||
if (flags & PFR_FLAG_ATOMIC)
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
@ -728,40 +716,25 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xzero = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
if (pfr_validate_table(tbl, 0, 0))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
return (ESRCH);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
ad.pfra_fback = (p != NULL) ?
|
||||
PFR_FB_CLEARED : PFR_FB_NONE;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (p != NULL) {
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
|
||||
@ -781,7 +754,7 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (0);
|
||||
_bad:
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
pfr_reset_feedback(addr, size);
|
||||
pfr_reset_feedback(addr, size, flags);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -982,10 +955,10 @@ void
|
||||
pfr_clean_node_mask(struct pfr_ktable *kt,
|
||||
struct pfr_kentryworkq *workq)
|
||||
{
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_kentry *p;
|
||||
|
||||
SLIST_FOREACH(p, workq, pfrke_workq)
|
||||
pfr_unroute_kentry(kt, p);
|
||||
SLIST_FOREACH(p, workq, pfrke_workq)
|
||||
pfr_unroute_kentry(kt, p);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1006,32 +979,17 @@ pfr_clstats_kentries(struct pfr_kentryworkq *workq, long tzero, int negchange)
|
||||
}
|
||||
|
||||
void
|
||||
pfr_reset_feedback(struct pfr_addr *addr, int size)
|
||||
pfr_reset_feedback(struct pfr_addr *addr, int size, int flags)
|
||||
{
|
||||
struct pfr_addr ad;
|
||||
int i;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
break;
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
break;
|
||||
#endif
|
||||
ad.pfra_fback = PFR_FB_NONE;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&ad, addr+i, sizeof(ad)))
|
||||
break;
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1145,10 +1103,7 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
{
|
||||
struct pfr_kentry *ke = (struct pfr_kentry *)rn;
|
||||
struct pfr_walktree *w = arg;
|
||||
int s;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
int s, flags = w->pfrw_flags;
|
||||
|
||||
switch (w->pfrw_op) {
|
||||
case PFRW_MARK:
|
||||
@ -1157,7 +1112,7 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
case PFRW_SWEEP:
|
||||
if (ke->pfrke_mark)
|
||||
break;
|
||||
/* fall trough */
|
||||
/* FALLTHROUGH */
|
||||
case PFRW_ENQUEUE:
|
||||
SLIST_INSERT_HEAD(w->pfrw_workq, ke, pfrke_workq);
|
||||
w->pfrw_cnt++;
|
||||
@ -1167,14 +1122,8 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
struct pfr_addr ad;
|
||||
|
||||
pfr_copyout_addr(&ad, ke);
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&ad, w->pfrw_addr, sizeof(ad), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, w->pfrw_addr, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
w->pfrw_addr++;
|
||||
}
|
||||
break;
|
||||
@ -1192,14 +1141,8 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
splx(s);
|
||||
as.pfras_tzero = ke->pfrke_tzero;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&as, w->pfrw_astats, sizeof(as), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&as, w->pfrw_astats, sizeof(as)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&as, w->pfrw_astats, sizeof(as)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
w->pfrw_astats++;
|
||||
}
|
||||
break;
|
||||
@ -1211,6 +1154,25 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
return (1); /* finish search */
|
||||
}
|
||||
break;
|
||||
case PFRW_DYNADDR_UPDATE:
|
||||
if (ke->pfrke_af == AF_INET) {
|
||||
if (w->pfrw_dyn->pfid_acnt4++ > 0)
|
||||
break;
|
||||
pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
|
||||
w->pfrw_dyn->pfid_addr4 = *SUNION2PF(
|
||||
&ke->pfrke_sa, AF_INET);
|
||||
w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
|
||||
&pfr_mask, AF_INET);
|
||||
} else {
|
||||
if (w->pfrw_dyn->pfid_acnt6++ > 0)
|
||||
break;
|
||||
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
|
||||
w->pfrw_dyn->pfid_addr6 = *SUNION2PF(
|
||||
&ke->pfrke_sa, AF_INET6);
|
||||
w->pfrw_dyn->pfid_mask6 = *SUNION2PF(
|
||||
&pfr_mask, AF_INET6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -1230,6 +1192,8 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
|
||||
RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
|
||||
if (pfr_skip_table(filter, p, flags))
|
||||
continue;
|
||||
if (!strcmp(p->pfrkt_anchor, PF_RESERVED_ANCHOR))
|
||||
continue;
|
||||
if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
continue;
|
||||
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
|
||||
@ -1255,7 +1219,6 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
|
||||
struct pfr_ktable *p, *q, *r, key;
|
||||
int i, rv, s, xadd = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
@ -1268,15 +1231,10 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
|
||||
SLIST_INIT(&addq);
|
||||
SLIST_INIT(&changeq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK))
|
||||
if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK,
|
||||
flags & PFR_FLAG_USERIOCTL))
|
||||
senderr(EINVAL);
|
||||
key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
@ -1348,22 +1306,14 @@ 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;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0,
|
||||
flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
|
||||
@ -1396,9 +1346,6 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
|
||||
{
|
||||
struct pfr_ktable *p;
|
||||
int n, nn;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ALLRSETS);
|
||||
n = nn = pfr_table_count(filter, flags);
|
||||
@ -1413,14 +1360,8 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
|
||||
continue;
|
||||
if (n-- <= 0)
|
||||
continue;
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl), ec);
|
||||
if (ec)
|
||||
if (COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&p->pfrkt_t, tbl++, sizeof(*tbl)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (n) {
|
||||
printf("pfr_get_tables: corruption detected (%d).\n", n);
|
||||
@ -1438,7 +1379,6 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
|
||||
struct pfr_ktableworkq workq;
|
||||
int s, n, nn;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
@ -1466,18 +1406,10 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
|
||||
continue;
|
||||
if (!(flags & PFR_FLAG_ATOMIC))
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl), ec);
|
||||
if (ec) {
|
||||
if (COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl))) {
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
#else
|
||||
if (copyout(&p->pfrkt_ts, tbl++, sizeof(*tbl))) {
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
#endif
|
||||
if (!(flags & PFR_FLAG_ATOMIC))
|
||||
splx(s);
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
|
||||
@ -1502,7 +1434,6 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
|
||||
struct pfr_ktable *p, key;
|
||||
int i, s, xzero = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
@ -1514,15 +1445,9 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0, 0))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
if (p != NULL) {
|
||||
@ -1549,9 +1474,6 @@ 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;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
if ((setflag & ~PFR_TFLAG_USRMASK) ||
|
||||
@ -1560,15 +1482,10 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
|
||||
return (EINVAL);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0,
|
||||
flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
|
||||
@ -1648,14 +1565,12 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_addr ad;
|
||||
struct pf_ruleset *rs;
|
||||
int i, rv, xadd = 0, xaddr = 0;
|
||||
#ifdef __FreeBSD__
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_DUMMY|PFR_FLAG_ADDRSTOO);
|
||||
if (size && !(flags & PFR_FLAG_ADDRSTOO))
|
||||
return (EINVAL);
|
||||
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK))
|
||||
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK,
|
||||
flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
rs = pf_find_ruleset(tbl->pfrt_anchor, tbl->pfrt_ruleset);
|
||||
if (rs == NULL || !rs->topen || ticket != rs->tticket)
|
||||
@ -1697,14 +1612,8 @@ _skip:
|
||||
}
|
||||
SLIST_INIT(&addrq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#ifdef __FreeBSD__
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
if (COPYIN(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
|
||||
@ -1745,6 +1654,37 @@ _bad:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
|
||||
{
|
||||
struct pfr_ktableworkq workq;
|
||||
struct pfr_ktable *p;
|
||||
struct pf_ruleset *rs;
|
||||
int xdel = 0;
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_DUMMY);
|
||||
rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
|
||||
if (rs == NULL || !rs->topen || ticket != rs->tticket)
|
||||
return (0);
|
||||
SLIST_INIT(&workq);
|
||||
RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
|
||||
if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
|
||||
pfr_skip_table(trs, p, 0))
|
||||
continue;
|
||||
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
|
||||
xdel++;
|
||||
}
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
pfr_setflags_ktables(&workq);
|
||||
rs->topen = 0;
|
||||
pf_remove_if_empty_ruleset(rs);
|
||||
}
|
||||
if (ndel != NULL)
|
||||
*ndel = xdel;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
|
||||
int *nchange, int flags)
|
||||
@ -1857,12 +1797,14 @@ pfr_commit_ktable(struct pfr_ktable *kt, long tzero)
|
||||
}
|
||||
|
||||
int
|
||||
pfr_validate_table(struct pfr_table *tbl, int allowedflags)
|
||||
pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!tbl->pfrt_name[0])
|
||||
return (-1);
|
||||
if (no_reserved && !strcmp(tbl->pfrt_anchor, PF_RESERVED_ANCHOR))
|
||||
return (-1);
|
||||
if (tbl->pfrt_name[PF_TABLE_NAME_SIZE-1])
|
||||
return (-1);
|
||||
for (i = strlen(tbl->pfrt_name); i < PF_TABLE_NAME_SIZE; i++)
|
||||
@ -2091,15 +2033,16 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
|
||||
if ((d = strncmp(p->pfrkt_anchor, q->pfrkt_anchor,
|
||||
PF_ANCHOR_NAME_SIZE)))
|
||||
return (d);
|
||||
return strncmp(p->pfrkt_ruleset, q->pfrkt_ruleset,
|
||||
PF_RULESET_NAME_SIZE);
|
||||
return (strncmp(p->pfrkt_ruleset, q->pfrkt_ruleset,
|
||||
PF_RULESET_NAME_SIZE));
|
||||
}
|
||||
|
||||
struct pfr_ktable *
|
||||
pfr_lookup_table(struct pfr_table *tbl)
|
||||
{
|
||||
/* struct pfr_ktable start like a struct pfr_table */
|
||||
return RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
|
||||
return (RB_FIND(pfr_ktablehead, &pfr_ktables,
|
||||
(struct pfr_ktable *)tbl));
|
||||
}
|
||||
|
||||
int
|
||||
@ -2111,7 +2054,7 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
|
||||
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
|
||||
kt = kt->pfrkt_root;
|
||||
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
return 0;
|
||||
return (0);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@ -2216,7 +2159,7 @@ pfr_attach_table(struct pf_ruleset *rs, char *name)
|
||||
}
|
||||
if (!kt->pfrkt_refcnt[PFR_REFCNT_RULE]++)
|
||||
pfr_setflags_ktable(kt, kt->pfrkt_flags|PFR_TFLAG_REFERENCED);
|
||||
return kt;
|
||||
return (kt);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2283,7 +2226,7 @@ _next_block:
|
||||
}
|
||||
for (;;) {
|
||||
/* we don't want to use a nested block */
|
||||
ke2 = (struct pfr_kentry *)(af == AF_INET ?
|
||||
ke2 = (struct pfr_kentry *)(af == AF_INET ?
|
||||
rn_match(&pfr_sin, kt->pfrkt_ip4) :
|
||||
rn_match(&pfr_sin6, kt->pfrkt_ip6));
|
||||
/* no need to check KENTRY_RNF_ROOT() here */
|
||||
@ -2313,26 +2256,54 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
|
||||
{
|
||||
struct pfr_walktree w;
|
||||
|
||||
bzero(&w, sizeof(w));
|
||||
w.pfrw_op = PFRW_POOL_GET;
|
||||
w.pfrw_cnt = idx;
|
||||
bzero(&w, sizeof(w));
|
||||
w.pfrw_op = PFRW_POOL_GET;
|
||||
w.pfrw_cnt = idx;
|
||||
|
||||
switch(af) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
#ifdef __FreeBSD__
|
||||
kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#endif
|
||||
return w.pfrw_kentry;
|
||||
return (w.pfrw_kentry);
|
||||
case AF_INET6:
|
||||
#ifdef __FreeBSD__
|
||||
kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#endif
|
||||
return w.pfrw_kentry;
|
||||
return (w.pfrw_kentry);
|
||||
default:
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
|
||||
{
|
||||
struct pfr_walktree w;
|
||||
int s;
|
||||
|
||||
bzero(&w, sizeof(w));
|
||||
w.pfrw_op = PFRW_DYNADDR_UPDATE;
|
||||
w.pfrw_dyn = dyn;
|
||||
|
||||
s = splsoftnet();
|
||||
dyn->pfid_acnt4 = 0;
|
||||
dyn->pfid_acnt6 = 0;
|
||||
if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
|
||||
#ifdef __FreeBSD__
|
||||
kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#endif
|
||||
if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
|
||||
#ifdef __FreeBSD__
|
||||
kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */
|
||||
/* $OpenBSD: pfvar.h,v 1.187 2004/03/22 04:54:18 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -67,6 +67,7 @@ struct ip;
|
||||
#define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1)
|
||||
|
||||
enum { PF_INOUT, PF_IN, PF_OUT };
|
||||
enum { PF_LAN_EXT, PF_EXT_GWY, PF_ID };
|
||||
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NAT, PF_NONAT,
|
||||
PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP };
|
||||
enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
|
||||
@ -87,16 +88,17 @@ enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
|
||||
PFTM_ICMP_FIRST_PACKET, PFTM_ICMP_ERROR_REPLY,
|
||||
PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE,
|
||||
PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
|
||||
PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_MAX,
|
||||
PFTM_PURGE, PFTM_UNTIL_PACKET };
|
||||
PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
|
||||
PFTM_MAX, PFTM_PURGE, PFTM_UNTIL_PACKET };
|
||||
enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
|
||||
enum { PF_LIMIT_STATES, PF_LIMIT_FRAGS, PF_LIMIT_MAX };
|
||||
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_MAX };
|
||||
#define PF_POOL_IDMASK 0x0f
|
||||
enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
|
||||
PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
|
||||
enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
|
||||
PF_ADDR_TABLE };
|
||||
#define PF_POOL_TYPEMASK 0x0f
|
||||
#define PF_POOL_STICKYADDR 0x20
|
||||
#define PF_WSCALE_FLAG 0x80
|
||||
#define PF_WSCALE_MASK 0x0f
|
||||
|
||||
@ -117,6 +119,12 @@ struct pf_addr {
|
||||
|
||||
#define PF_TABLE_NAME_SIZE 32
|
||||
|
||||
#define PFI_AFLAG_NETWORK 0x01
|
||||
#define PFI_AFLAG_BROADCAST 0x02
|
||||
#define PFI_AFLAG_PEER 0x04
|
||||
#define PFI_AFLAG_MODEMASK 0x07
|
||||
#define PFI_AFLAG_NOALIAS 0x08
|
||||
|
||||
struct pf_addr_wrap {
|
||||
union {
|
||||
struct {
|
||||
@ -127,26 +135,30 @@ struct pf_addr_wrap {
|
||||
char tblname[PF_TABLE_NAME_SIZE];
|
||||
} v;
|
||||
union {
|
||||
struct pf_addr_dyn *dyn;
|
||||
struct pfi_dynaddr *dyn;
|
||||
struct pfr_ktable *tbl;
|
||||
int dyncnt;
|
||||
int tblcnt;
|
||||
} p;
|
||||
u_int8_t type; /* PF_ADDR_* */
|
||||
u_int8_t iflags; /* PFI_AFLAG_* */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct pf_addr_dyn {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct ifnet *ifp;
|
||||
struct pf_addr *addr;
|
||||
sa_family_t af;
|
||||
#ifdef __FreeBSD__
|
||||
eventhandler_tag hook_cookie;
|
||||
#else
|
||||
void *hook_cookie;
|
||||
#endif
|
||||
u_int8_t undefined;
|
||||
struct pfi_dynaddr {
|
||||
struct pf_addr pfid_addr4;
|
||||
struct pf_addr pfid_mask4;
|
||||
struct pf_addr pfid_addr6;
|
||||
struct pf_addr pfid_mask6;
|
||||
struct pfr_ktable *pfid_kt;
|
||||
struct pfi_kif *pfid_kif;
|
||||
void *pfid_hook_cookie;
|
||||
int pfid_net; /* optional mask, or 128 */
|
||||
int pfid_acnt4; /* address count, IPv4 */
|
||||
int pfid_acnt6; /* address count, IPv6 */
|
||||
sa_family_t pfid_af; /* rule address family */
|
||||
u_int8_t pfid_iflags; /* PFI_AFLAG_* */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -212,7 +224,22 @@ extern void destroy_pf_mutex(void);
|
||||
#define PFSYNC_MINVER 1
|
||||
#define PFSYNC_PREFVER PFSYNC_MODVER
|
||||
#define PFSYNC_MAXVER 1
|
||||
#endif
|
||||
|
||||
/* prototyped for pf_subr.c */
|
||||
struct hook_desc {
|
||||
TAILQ_ENTRY(hook_desc) hd_list;
|
||||
void (*hd_fn)(void *);
|
||||
void *hd_arg;
|
||||
};
|
||||
TAILQ_HEAD(hook_desc_head, hook_desc);
|
||||
|
||||
void *hook_establish(struct hook_desc_head *, int, void (*)(void *), void *);
|
||||
void hook_disestablish(struct hook_desc_head *, void *);
|
||||
void dohooks(struct hook_desc_head *, int);
|
||||
|
||||
#define HOOK_REMOVE 0x01
|
||||
#define HOOK_FREE 0x02
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#ifdef INET
|
||||
#ifndef INET6
|
||||
@ -350,10 +377,7 @@ extern void destroy_pf_mutex(void);
|
||||
((aw)->type == PF_ADDR_TABLE && \
|
||||
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_DYNIFTL && \
|
||||
((aw)->p.dyn->undefined || \
|
||||
(!PF_AZERO(&(aw)->v.a.mask, (af)) && \
|
||||
!PF_MATCHA(0, &(aw)->v.a.addr, \
|
||||
&(aw)->v.a.mask, (x), (af))))) || \
|
||||
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_ADDRMASK && \
|
||||
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
|
||||
!PF_MATCHA(0, &(aw)->v.a.addr, \
|
||||
@ -382,7 +406,7 @@ struct pf_pooladdr {
|
||||
struct pf_addr_wrap addr;
|
||||
TAILQ_ENTRY(pf_pooladdr) entries;
|
||||
char ifname[IFNAMSIZ];
|
||||
struct ifnet *ifp;
|
||||
struct pfi_kif *kif;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pf_palist, pf_pooladdr);
|
||||
@ -531,7 +555,6 @@ struct pf_rule {
|
||||
union pf_rule_ptr skip[PF_SKIP_COUNT];
|
||||
#define PF_RULE_LABEL_SIZE 64
|
||||
char label[PF_RULE_LABEL_SIZE];
|
||||
u_int32_t timeout[PFTM_MAX];
|
||||
#define PF_QNAME_SIZE 16
|
||||
char ifname[IFNAMSIZ];
|
||||
char qname[PF_QNAME_SIZE];
|
||||
@ -549,12 +572,17 @@ struct pf_rule {
|
||||
u_int64_t packets;
|
||||
u_int64_t bytes;
|
||||
|
||||
struct ifnet *ifp;
|
||||
struct pfi_kif *kif;
|
||||
struct pf_anchor *anchor;
|
||||
|
||||
pf_osfp_t os_fingerprint;
|
||||
|
||||
u_int32_t timeout[PFTM_MAX];
|
||||
u_int32_t states;
|
||||
u_int32_t max_states;
|
||||
u_int32_t src_nodes;
|
||||
u_int32_t max_src_nodes;
|
||||
u_int32_t max_src_states;
|
||||
u_int32_t qid;
|
||||
u_int32_t pqid;
|
||||
u_int32_t rt_listid;
|
||||
@ -601,6 +629,9 @@ struct pf_rule {
|
||||
#define PFRULE_FRAGMENT 0x0002
|
||||
#define PFRULE_RETURNICMP 0x0004
|
||||
#define PFRULE_RETURN 0x0008
|
||||
#define PFRULE_NOSYNC 0x0010
|
||||
#define PFRULE_SRCTRACK 0x0020 /* track source states */
|
||||
#define PFRULE_RULESRCTRACK 0x0040 /* per rule */
|
||||
|
||||
/* scrub flags */
|
||||
#define PFRULE_NODF 0x0100
|
||||
@ -609,8 +640,28 @@ struct pf_rule {
|
||||
#define PFRULE_RANDOMID 0x0800
|
||||
#define PFRULE_REASSEMBLE_TCP 0x1000
|
||||
|
||||
/* rule flags again */
|
||||
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
|
||||
#define PFRULE_GRBOUND 0x00020000 /* group-bound */
|
||||
|
||||
#define PFSTATE_HIWAT 10000 /* default state table size */
|
||||
|
||||
struct pf_src_node {
|
||||
RB_ENTRY(pf_src_node) entry;
|
||||
struct pf_addr addr;
|
||||
struct pf_addr raddr;
|
||||
union pf_rule_ptr rule;
|
||||
struct pfi_kif *kif;
|
||||
u_int32_t bytes;
|
||||
u_int32_t packets;
|
||||
u_int32_t states;
|
||||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
sa_family_t af;
|
||||
u_int8_t ruletype;
|
||||
};
|
||||
|
||||
#define PFSNODE_HIWAT 10000 /* default source node table size */
|
||||
|
||||
struct pf_state_scrub {
|
||||
u_int16_t pfss_flags;
|
||||
@ -637,7 +688,20 @@ struct pf_state_peer {
|
||||
struct pf_state_scrub *scrub; /* state is scrubbed */
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pf_state_queue, pf_state);
|
||||
|
||||
struct pf_state {
|
||||
u_int64_t id;
|
||||
union {
|
||||
struct {
|
||||
RB_ENTRY(pf_state) entry_lan_ext;
|
||||
RB_ENTRY(pf_state) entry_ext_gwy;
|
||||
RB_ENTRY(pf_state) entry_id;
|
||||
TAILQ_ENTRY(pf_state) entry_updates;
|
||||
struct pfi_kif *kif;
|
||||
} s;
|
||||
char ifname[IFNAMSIZ];
|
||||
} u;
|
||||
struct pf_state_host lan;
|
||||
struct pf_state_host gwy;
|
||||
struct pf_state_host ext;
|
||||
@ -647,27 +711,25 @@ struct pf_state {
|
||||
union pf_rule_ptr anchor;
|
||||
union pf_rule_ptr nat_rule;
|
||||
struct pf_addr rt_addr;
|
||||
struct ifnet *rt_ifp;
|
||||
struct pfi_kif *rt_kif;
|
||||
struct pf_src_node *src_node;
|
||||
struct pf_src_node *nat_src_node;
|
||||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
u_int32_t pfsync_time;
|
||||
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 pad[2];
|
||||
};
|
||||
|
||||
struct pf_tree_node {
|
||||
RB_ENTRY(pf_tree_node) entry;
|
||||
struct pf_state *state;
|
||||
struct pf_addr addr[2];
|
||||
u_int16_t port[2];
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
u_int8_t sync_flags;
|
||||
#define PFSTATE_NOSYNC 0x01
|
||||
#define PFSTATE_FROMSYNC 0x02
|
||||
u_int8_t pad;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pf_rulequeue, pf_rule);
|
||||
@ -683,6 +745,7 @@ struct pf_ruleset {
|
||||
struct {
|
||||
struct pf_rulequeue *ptr;
|
||||
u_int32_t ticket;
|
||||
int open;
|
||||
} active, inactive;
|
||||
} rules[PF_RULESET_MAX];
|
||||
struct pf_anchor *anchor;
|
||||
@ -702,6 +765,9 @@ struct pf_anchor {
|
||||
|
||||
TAILQ_HEAD(pf_anchorqueue, pf_anchor);
|
||||
|
||||
#define PF_RESERVED_ANCHOR "_pf"
|
||||
#define PF_INTERFACE_RULESET "_if"
|
||||
|
||||
#define PFR_TFLAG_PERSIST 0x00000001
|
||||
#define PFR_TFLAG_CONST 0x00000002
|
||||
#define PFR_TFLAG_ACTIVE 0x00000004
|
||||
@ -788,12 +854,13 @@ struct pfr_ktable {
|
||||
struct pfr_ktable *pfrkt_shadow;
|
||||
struct pfr_ktable *pfrkt_root;
|
||||
struct pf_ruleset *pfrkt_rs;
|
||||
long pfrkt_larg;
|
||||
int pfrkt_nflags;
|
||||
};
|
||||
#define pfrkt_t pfrkt_ts.pfrts_t
|
||||
#define pfrkt_name pfrkt_t.pfrt_name
|
||||
#define pfrkt_anchor pfrkt_t.pfrt_anchor
|
||||
#define pfrkt_ruleset pfrkt_t.pfrt_ruleset
|
||||
#define pfrkt_anchor pfrkt_t.pfrt_anchor
|
||||
#define pfrkt_ruleset pfrkt_t.pfrt_ruleset
|
||||
#define pfrkt_flags pfrkt_t.pfrt_flags
|
||||
#define pfrkt_cnt pfrkt_ts.pfrts_cnt
|
||||
#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt
|
||||
@ -803,6 +870,61 @@ struct pfr_ktable {
|
||||
#define pfrkt_nomatch pfrkt_ts.pfrts_nomatch
|
||||
#define pfrkt_tzero pfrkt_ts.pfrts_tzero
|
||||
|
||||
RB_HEAD(pf_state_tree_lan_ext, pf_state);
|
||||
RB_PROTOTYPE(pf_state_tree_lan_ext, pf_state,
|
||||
u.s.entry_lan_ext, pf_state_compare_lan_ext);
|
||||
|
||||
RB_HEAD(pf_state_tree_ext_gwy, pf_state);
|
||||
RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state,
|
||||
u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
|
||||
|
||||
struct pfi_if {
|
||||
char pfif_name[IFNAMSIZ];
|
||||
u_int64_t pfif_packets[2][2][2];
|
||||
u_int64_t pfif_bytes[2][2][2];
|
||||
u_int64_t pfif_addcnt;
|
||||
u_int64_t pfif_delcnt;
|
||||
long pfif_tzero;
|
||||
int pfif_states;
|
||||
int pfif_rules;
|
||||
int pfif_flags;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pfi_grouphead, pfi_kif);
|
||||
TAILQ_HEAD(pfi_statehead, pfi_kif);
|
||||
RB_HEAD(pfi_ifhead, pfi_kif);
|
||||
struct pfi_kif {
|
||||
struct pfi_if pfik_if;
|
||||
RB_ENTRY(pfi_kif) pfik_tree;
|
||||
struct pf_state_tree_lan_ext pfik_lan_ext;
|
||||
struct pf_state_tree_ext_gwy pfik_ext_gwy;
|
||||
struct pfi_grouphead pfik_grouphead;
|
||||
TAILQ_ENTRY(pfi_kif) pfik_instances;
|
||||
TAILQ_ENTRY(pfi_kif) pfik_w_states;
|
||||
struct hook_desc_head *pfik_ah_head;
|
||||
void *pfik_ah_cookie;
|
||||
struct pfi_kif *pfik_parent;
|
||||
struct ifnet *pfik_ifp;
|
||||
int pfik_states;
|
||||
int pfik_rules;
|
||||
};
|
||||
#define pfik_name pfik_if.pfif_name
|
||||
#define pfik_packets pfik_if.pfif_packets
|
||||
#define pfik_bytes pfik_if.pfif_bytes
|
||||
#define pfik_tzero pfik_if.pfif_tzero
|
||||
#define pfik_flags pfik_if.pfif_flags
|
||||
#define pfik_addcnt pfik_if.pfif_addcnt
|
||||
#define pfik_delcnt pfik_if.pfif_delcnt
|
||||
#define pfik_states pfik_if.pfif_states
|
||||
#define pfik_rules pfik_if.pfif_rules
|
||||
|
||||
#define PFI_IFLAG_GROUP 0x0001 /* group of interfaces */
|
||||
#define PFI_IFLAG_INSTANCE 0x0002 /* single instance */
|
||||
#define PFI_IFLAG_CLONABLE 0x0010 /* clonable group */
|
||||
#define PFI_IFLAG_DYNAMIC 0x0020 /* dynamic group */
|
||||
#define PFI_IFLAG_ATTACHED 0x0040 /* interface attached */
|
||||
#define PFI_IFLAG_PLACEHOLDER 0x8000 /* placeholder group/interface */
|
||||
|
||||
struct pf_pdesc {
|
||||
u_int64_t tot_len; /* Make Mickey money */
|
||||
union {
|
||||
@ -814,6 +936,9 @@ struct pf_pdesc {
|
||||
#endif /* INET6 */
|
||||
void *any;
|
||||
} hdr;
|
||||
struct pf_addr baddr; /* address before translation */
|
||||
struct pf_addr naddr; /* address after translation */
|
||||
struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */
|
||||
struct pf_addr *src;
|
||||
struct pf_addr *dst;
|
||||
u_int16_t *ip_sum;
|
||||
@ -882,6 +1007,10 @@ struct pf_pdesc {
|
||||
#define FCNT_STATE_REMOVALS 2
|
||||
#define FCNT_MAX 3
|
||||
|
||||
#define SCNT_SRC_NODE_SEARCH 0
|
||||
#define SCNT_SRC_NODE_INSERT 1
|
||||
#define SCNT_SRC_NODE_REMOVALS 2
|
||||
#define SCNT_MAX 3
|
||||
|
||||
#define ACTION_SET(a, x) \
|
||||
do { \
|
||||
@ -900,12 +1029,16 @@ struct pf_pdesc {
|
||||
struct pf_status {
|
||||
u_int64_t counters[PFRES_MAX];
|
||||
u_int64_t fcounters[FCNT_MAX];
|
||||
u_int64_t scounters[SCNT_MAX];
|
||||
u_int64_t pcounters[2][2][3];
|
||||
u_int64_t bcounters[2][2];
|
||||
u_int64_t stateid;
|
||||
u_int32_t running;
|
||||
u_int32_t states;
|
||||
u_int32_t src_nodes;
|
||||
u_int32_t since;
|
||||
u_int32_t debug;
|
||||
u_int32_t hostid;
|
||||
char ifname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
@ -1037,6 +1170,7 @@ struct pfioc_state_kill {
|
||||
int psk_proto;
|
||||
struct pf_rule_addr psk_src;
|
||||
struct pf_rule_addr psk_dst;
|
||||
char psk_ifname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct pfioc_states {
|
||||
@ -1049,6 +1183,16 @@ struct pfioc_states {
|
||||
#define ps_states ps_u.psu_states
|
||||
};
|
||||
|
||||
struct pfioc_src_nodes {
|
||||
int psn_len;
|
||||
union {
|
||||
caddr_t psu_buf;
|
||||
struct pf_src_node *psu_src_nodes;
|
||||
} psn_u;
|
||||
#define psn_buf psn_u.psu_buf
|
||||
#define psn_src_nodes psn_u.psu_src_nodes
|
||||
};
|
||||
|
||||
struct pfioc_if {
|
||||
char ifname[IFNAMSIZ];
|
||||
};
|
||||
@ -1089,6 +1233,19 @@ struct pfioc_ruleset {
|
||||
char name[PF_RULESET_NAME_SIZE];
|
||||
};
|
||||
|
||||
#define PF_RULESET_ALTQ (PF_RULESET_MAX)
|
||||
#define PF_RULESET_TABLE (PF_RULESET_MAX+1)
|
||||
struct pfioc_trans {
|
||||
int size; /* number of elements */
|
||||
int esize; /* size of each element in bytes */
|
||||
struct pfioc_trans_e {
|
||||
int rs_num;
|
||||
char anchor[PF_ANCHOR_NAME_SIZE];
|
||||
char ruleset[PF_RULESET_NAME_SIZE];
|
||||
u_int32_t ticket;
|
||||
} *array;
|
||||
};
|
||||
|
||||
#define PFR_FLAG_ATOMIC 0x00000001
|
||||
#define PFR_FLAG_DUMMY 0x00000002
|
||||
#define PFR_FLAG_FEEDBACK 0x00000004
|
||||
@ -1097,6 +1254,9 @@ struct pfioc_ruleset {
|
||||
#define PFR_FLAG_REPLACE 0x00000020
|
||||
#define PFR_FLAG_ALLRSETS 0x00000040
|
||||
#define PFR_FLAG_ALLMASK 0x0000007F
|
||||
#ifdef _KERNEL
|
||||
#define PFR_FLAG_USERIOCTL 0x10000000
|
||||
#endif
|
||||
|
||||
struct pfioc_table {
|
||||
struct pfr_table pfrio_table;
|
||||
@ -1118,6 +1278,20 @@ struct pfioc_table {
|
||||
#define pfrio_clrflag pfrio_nadd
|
||||
|
||||
|
||||
#define PFI_FLAG_GROUP 0x0001 /* gets groups of interfaces */
|
||||
#define PFI_FLAG_INSTANCE 0x0002 /* gets single interfaces */
|
||||
#define PFI_FLAG_ALLMASK 0x0003
|
||||
|
||||
struct pfioc_iface {
|
||||
char pfiio_name[IFNAMSIZ];
|
||||
void *pfiio_buffer;
|
||||
int pfiio_esize;
|
||||
int pfiio_size;
|
||||
int pfiio_nzero;
|
||||
int pfiio_flags;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ioctl operations
|
||||
*/
|
||||
@ -1130,7 +1304,7 @@ struct pfioc_table {
|
||||
#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
|
||||
#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
|
||||
/* XXX cut 8 - 17 */
|
||||
#define DIOCCLRSTATES _IO ('D', 18)
|
||||
#define DIOCCLRSTATES _IOWR('D', 18, struct pfioc_state_kill)
|
||||
#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
|
||||
#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
|
||||
#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
|
||||
@ -1186,30 +1360,45 @@ struct pfioc_table {
|
||||
#define DIOCOSFPFLUSH _IO('D', 78)
|
||||
#define DIOCOSFPADD _IOWR('D', 79, struct pf_osfp_ioctl)
|
||||
#define DIOCOSFPGET _IOWR('D', 80, struct pf_osfp_ioctl)
|
||||
#define DIOCXBEGIN _IOWR('D', 81, struct pfioc_trans)
|
||||
#define DIOCXCOMMIT _IOWR('D', 82, struct pfioc_trans)
|
||||
#define DIOCXROLLBACK _IOWR('D', 83, struct pfioc_trans)
|
||||
#define DIOCGETSRCNODES _IOWR('D', 84, struct pfioc_src_nodes)
|
||||
#define DIOCCLRSRCNODES _IO('D', 85)
|
||||
#define DIOCSETHOSTID _IOWR('D', 86, u_int32_t)
|
||||
#define DIOCIGETIFACES _IOWR('D', 87, struct pfioc_iface)
|
||||
#define DIOCICLRISTATS _IOWR('D', 88, struct pfioc_iface)
|
||||
#ifdef __FreeBSD__
|
||||
struct pf_ifspeed {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t baudrate;
|
||||
};
|
||||
#define DIOCGIFSPEED _IOWR('D', 81, struct pf_ifspeed)
|
||||
#define DIOCGIFSPEED _IOWR('D', 89, struct pf_ifspeed)
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
RB_HEAD(pf_state_tree, pf_tree_node);
|
||||
RB_PROTOTYPE(pf_state_tree, pf_tree_node, entry, pf_state_compare);
|
||||
extern struct pf_state_tree tree_lan_ext, tree_ext_gwy;
|
||||
RB_HEAD(pf_src_tree, pf_src_node);
|
||||
RB_PROTOTYPE(pf_src_tree, pf_src_node, entry, pf_src_compare);
|
||||
extern struct pf_src_tree tree_src_tracking;
|
||||
|
||||
extern struct pf_anchorqueue pf_anchors;
|
||||
extern struct pf_ruleset pf_main_ruleset;
|
||||
RB_HEAD(pf_state_tree_id, pf_state);
|
||||
RB_PROTOTYPE(pf_state_tree_id, pf_state,
|
||||
entry_id, pf_state_compare_id);
|
||||
extern struct pf_state_tree_id tree_id;
|
||||
extern struct pf_state_queue state_updates;
|
||||
|
||||
extern struct pf_anchorqueue pf_anchors;
|
||||
extern struct pf_ruleset pf_main_ruleset;
|
||||
TAILQ_HEAD(pf_poolqueue, pf_pool);
|
||||
extern struct pf_poolqueue pf_pools[2];
|
||||
extern struct pf_poolqueue pf_pools[2];
|
||||
TAILQ_HEAD(pf_altqqueue, pf_altq);
|
||||
extern struct pf_altqqueue pf_altqs[2];
|
||||
extern struct pf_palist pf_pabuf;
|
||||
|
||||
extern struct pf_altqqueue pf_altqs[2];
|
||||
extern struct pf_palist pf_pabuf;
|
||||
extern struct pfi_kif **pfi_index2kif;
|
||||
|
||||
extern u_int32_t ticket_altqs_active;
|
||||
extern u_int32_t ticket_altqs_inactive;
|
||||
extern int altqs_inactive_open;
|
||||
extern u_int32_t ticket_pabuf;
|
||||
extern struct pf_altqqueue *pf_altqs_active;
|
||||
extern struct pf_altqqueue *pf_altqs_inactive;
|
||||
@ -1219,37 +1408,41 @@ extern int pf_tbladdr_setup(struct pf_ruleset *,
|
||||
struct pf_addr_wrap *);
|
||||
extern void pf_tbladdr_remove(struct pf_addr_wrap *);
|
||||
extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
|
||||
extern int pf_dynaddr_setup(struct pf_addr_wrap *,
|
||||
sa_family_t);
|
||||
extern void pf_dynaddr_copyout(struct pf_addr_wrap *);
|
||||
extern void pf_dynaddr_remove(struct pf_addr_wrap *);
|
||||
extern void pf_calc_skip_steps(struct pf_rulequeue *);
|
||||
extern void pf_rule_set_qid(struct pf_rulequeue *);
|
||||
extern u_int32_t pf_qname_to_qid(char *);
|
||||
extern void pf_update_anchor_rules(void);
|
||||
#ifdef __FreeBSD__
|
||||
extern uma_zone_t pf_tree_pl, pf_rule_pl, pf_addr_pl;
|
||||
extern uma_zone_t pf_src_tree_pl, pf_rule_pl;
|
||||
extern uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
|
||||
extern uma_zone_t pfr_ktable_pl, pfr_kentry_pl;
|
||||
extern uma_zone_t pf_cache_pl, pf_cent_pl;
|
||||
extern uma_zone_t pf_state_scrub_pl;
|
||||
extern uma_zone_t pfi_addr_pl;
|
||||
#else
|
||||
extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl;
|
||||
extern struct pool pf_src_tree_pl, pf_rule_pl;
|
||||
extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
|
||||
extern struct pool pf_state_scrub_pl;
|
||||
#endif
|
||||
extern void pf_purge_timeout(void *);
|
||||
extern void pf_purge_expired_src_nodes(void);
|
||||
extern void pf_purge_expired_states(void);
|
||||
extern int pf_insert_state(struct pf_state *);
|
||||
extern struct pf_state *pf_find_state(struct pf_state_tree *,
|
||||
struct pf_tree_node *);
|
||||
extern int pf_insert_state(struct pfi_kif *,
|
||||
struct pf_state *);
|
||||
extern int pf_insert_src_node(struct pf_src_node **,
|
||||
struct pf_rule *, struct pf_addr *,
|
||||
sa_family_t);
|
||||
void pf_src_tree_remove_state(struct pf_state *);
|
||||
extern struct pf_state *pf_find_state_byid(struct pf_state *);
|
||||
extern struct pf_state *pf_find_state_all(struct pf_state *key,
|
||||
u_int8_t tree, int *more);
|
||||
extern struct pf_anchor *pf_find_anchor(const char *);
|
||||
extern struct pf_ruleset *pf_find_ruleset(char *, char *);
|
||||
extern struct pf_ruleset *pf_find_or_create_ruleset(char *, char *);
|
||||
extern struct pf_ruleset *pf_find_or_create_ruleset(
|
||||
char[PF_ANCHOR_NAME_SIZE],
|
||||
char[PF_RULESET_NAME_SIZE]);
|
||||
extern void pf_remove_if_empty_ruleset(
|
||||
struct pf_ruleset *);
|
||||
|
||||
extern struct ifnet *status_ifp;
|
||||
extern struct ifnet *sync_ifp;
|
||||
extern struct pf_rule pf_default_rule;
|
||||
extern void pf_addrcpy(struct pf_addr *, struct pf_addr *,
|
||||
u_int8_t);
|
||||
@ -1270,7 +1463,7 @@ void pf_addr_inc(struct pf_addr *, sa_family_t);
|
||||
void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *,
|
||||
sa_family_t);
|
||||
void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
|
||||
int pflog_packet(struct ifnet *, struct mbuf *, sa_family_t, u_int8_t,
|
||||
int pflog_packet(struct pfi_kif *, struct mbuf *, sa_family_t, u_int8_t,
|
||||
u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *);
|
||||
int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
|
||||
struct pf_addr *, sa_family_t);
|
||||
@ -1280,9 +1473,9 @@ int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);
|
||||
int pf_match_gid(u_int8_t, gid_t, gid_t, gid_t);
|
||||
|
||||
void pf_normalize_init(void);
|
||||
int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *);
|
||||
int pf_normalize_ip6(struct mbuf **, int, struct ifnet *, u_short *);
|
||||
int pf_normalize_tcp(int, struct ifnet *, struct mbuf *, int, int, void *,
|
||||
int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *);
|
||||
int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *);
|
||||
int pf_normalize_tcp(int, struct pfi_kif *, struct mbuf *, int, int, void *,
|
||||
struct pf_pdesc *);
|
||||
void pf_normalize_tcp_cleanup(struct pf_state *);
|
||||
int pf_normalize_tcp_init(struct mbuf *, int, struct pf_pdesc *,
|
||||
@ -1300,6 +1493,7 @@ void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
|
||||
u_int64_t, int, int, int);
|
||||
int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
|
||||
struct pf_addr **, struct pf_addr **, sa_family_t);
|
||||
void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
|
||||
struct pfr_ktable *
|
||||
pfr_attach_table(struct pf_ruleset *, char *);
|
||||
void pfr_detach_table(struct pfr_ktable *);
|
||||
@ -1324,14 +1518,43 @@ int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int);
|
||||
int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int);
|
||||
int pfr_ina_rollback(struct pfr_table *, u_int32_t, int *, int);
|
||||
int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
|
||||
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int *, u_int32_t, int);
|
||||
|
||||
void pfi_initialize(void);
|
||||
#ifdef __FreeBSD__
|
||||
void pfi_cleanup(void);
|
||||
#endif
|
||||
void pfi_attach_clone(struct if_clone *);
|
||||
void pfi_attach_ifnet(struct ifnet *);
|
||||
void pfi_detach_ifnet(struct ifnet *);
|
||||
struct pfi_kif *pfi_lookup_create(const char *);
|
||||
struct pfi_kif *pfi_lookup_if(const char *);
|
||||
int pfi_maybe_destroy(struct pfi_kif *);
|
||||
struct pfi_kif *pfi_attach_rule(const char *);
|
||||
void pfi_detach_rule(struct pfi_kif *);
|
||||
void pfi_attach_state(struct pfi_kif *);
|
||||
void pfi_detach_state(struct pfi_kif *);
|
||||
int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
|
||||
void pfi_dynaddr_copyout(struct pf_addr_wrap *);
|
||||
void pfi_dynaddr_remove(struct pf_addr_wrap *);
|
||||
void pfi_fill_oldstatus(struct pf_status *);
|
||||
int pfi_clr_istats(const char *, int *, int);
|
||||
int pfi_get_ifaces(const char *, struct pfi_if *, int *, int);
|
||||
int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
|
||||
sa_family_t);
|
||||
|
||||
extern struct pfi_statehead pfi_statehead;
|
||||
|
||||
u_int16_t pf_tagname2tag(char *);
|
||||
void pf_tag2tagname(u_int16_t, char *);
|
||||
void pf_tag_unref(u_int16_t);
|
||||
int pf_tag_packet(struct mbuf *, struct pf_tag *, int);
|
||||
u_int32_t pf_qname2qid(char *);
|
||||
void pf_qid2qname(u_int32_t, char *);
|
||||
void pf_qid_unref(u_int32_t);
|
||||
|
||||
extern struct pf_status pf_status;
|
||||
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
.PATH: ${.CURDIR}/../../contrib/pf/net
|
||||
.PATH: ${.CURDIR}/../../contrib/pf/netinet
|
||||
.PATH: ${.CURDIR}/../../netinet
|
||||
|
||||
KMOD= pf
|
||||
SRCS = pf.c pf_osfp.c pf_ioctl.c pf_norm.c pf_table.c \
|
||||
in4_cksum.c \
|
||||
SRCS = pf.c pf_if.c pf_subr.c pf_osfp.c pf_ioctl.c pf_norm.c pf_table.c \
|
||||
if_pflog.c \
|
||||
in4_cksum.c ip_id.c \
|
||||
opt_pf.h opt_inet.h opt_inet6.h opt_bpf.h opt_random_ip_id.h
|
||||
|
||||
CFLAGS+= -Wall -I${.CURDIR}/../../contrib/pf
|
||||
@ -13,7 +15,6 @@ CFLAGS+= -Wall -I${.CURDIR}/../../contrib/pf
|
||||
opt_pf.h:
|
||||
echo "#define DEV_PF 1" > opt_pf.h
|
||||
echo "#define DEV_PFLOG 1" >> opt_pf.h
|
||||
echo "#define DEV_PFSYNC 1" >> opt_pf.h
|
||||
|
||||
opt_inet.h:
|
||||
echo "#define INET 1" > opt_inet.h
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_pf.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -86,6 +87,11 @@
|
||||
#include <netipx/ipx_ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFSYNC
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pfsync.h>
|
||||
#endif
|
||||
|
||||
extern struct domain inetdomain;
|
||||
static struct pr_usrreqs nousrreqs;
|
||||
|
||||
@ -225,6 +231,14 @@ struct protosw inetsw[] = {
|
||||
&rip_usrreqs
|
||||
},
|
||||
#endif /* PIM */
|
||||
#ifdef DEV_PFSYNC
|
||||
{ SOCK_RAW, &inetdomain, IPPROTO_PFSYNC, PR_ATOMIC|PR_ADDR,
|
||||
pfsync_input, 0, 0, rip_ctloutput,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&rip_usrreqs
|
||||
},
|
||||
#endif /* DEV_PFSYNC */
|
||||
/* raw wildcard */
|
||||
{ SOCK_RAW, &inetdomain, 0, PR_ATOMIC|PR_ADDR,
|
||||
rip_input, 0, 0, rip_ctloutput,
|
||||
|
Loading…
x
Reference in New Issue
Block a user