Merge the projects/pf/head branch, that was worked on for last six months,

into head. The most significant achievements in the new code:

 o Fine grained locking, thus much better performance.
 o Fixes to many problems in pf, that were specific to FreeBSD port.

New code doesn't have that many ifdefs and much less OpenBSDisms, thus
is more attractive to our developers.

  Those interested in details, can browse through SVN log of the
projects/pf/head branch. And for reference, here is exact list of
revisions merged:

r232043, r232044, r232062, r232148, r232149, r232150, r232298, r232330,
r232332, r232340, r232386, r232390, r232391, r232605, r232655, r232656,
r232661, r232662, r232663, r232664, r232673, r232691, r233309, r233782,
r233829, r233830, r233834, r233835, r233836, r233865, r233866, r233868,
r233873, r234056, r234096, r234100, r234108, r234175, r234187, r234223,
r234271, r234272, r234282, r234307, r234309, r234382, r234384, r234456,
r234486, r234606, r234640, r234641, r234642, r234644, r234651, r235505,
r235506, r235535, r235605, r235606, r235826, r235991, r235993, r236168,
r236173, r236179, r236180, r236181, r236186, r236223, r236227, r236230,
r236252, r236254, r236298, r236299, r236300, r236301, r236397, r236398,
r236399, r236499, r236512, r236513, r236525, r236526, r236545, r236548,
r236553, r236554, r236556, r236557, r236561, r236570, r236630, r236672,
r236673, r236679, r236706, r236710, r236718, r237154, r237155, r237169,
r237314, r237363, r237364, r237368, r237369, r237376, r237440, r237442,
r237751, r237783, r237784, r237785, r237788, r237791, r238421, r238522,
r238523, r238524, r238525, r239173, r239186, r239644, r239652, r239661,
r239773, r240125, r240130, r240131, r240136, r240186, r240196, r240212.

I'd like to thank people who participated in early testing:

Tested by:	Florian Smeets <flo freebsd.org>
Tested by:	Chekaluk Vitaly <artemrts ukr.net>
Tested by:	Ben Wilber <ben desync.com>
Tested by:	Ian FREISLICH <ianf cloudseed.co.za>
This commit is contained in:
Gleb Smirnoff 2012-09-08 06:41:54 +00:00
parent 76af1a93c9
commit d6d3f01e0a
45 changed files with 4625 additions and 9674 deletions

View File

@ -24,6 +24,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20120908:
The pf(4) packet filter ABI has been changed. pfctl(8) and
snmp_pf module need to be recompiled to work with new kernel.
20120828:
A new ZFS feature flag "com.delphix:empty_bpobj" has been merged
to -HEAD. Pools that have empty_bpobj in active state can not be

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 17 2011
.Dd June 29 2012
.Dt PF 4
.Os
.Sh NAME
@ -75,6 +75,25 @@ separated by
characters, similar to how file system hierarchies are laid out.
The final component of the anchor path is the anchor under which
operations will be performed.
.Sh SYSCTL VARIABLES AND LOADER TUNABLES
The following
.Xr loader 8
tunables are available.
.Bl -tag -width indent
.It Va net.pf.states_hashsize
Size of hash tables that store states.
Should be power of 2.
Default value is 32768.
.It Va net.pf.source_nodes_hashsize
Size of hash table that store source nodes.
Should be power of 2.
Default value is 8192.
.El
.Pp
Read only
.Xr sysctl 8
variables with matching names are provided to obtain current values
at runtime.
.Sh IOCTL INTERFACE
.Nm
supports the following
@ -351,7 +370,6 @@ struct pf_status {
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;
@ -493,7 +511,7 @@ struct pfioc_limit {
};
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
.Ed
.It Dv DIOCGETLIMIT Fa "struct pfioc_limit *pl"
Get the hard

View File

@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 31 2009
.Dd June 29 2012
.Dt PF.CONF 5
.Os
.Sh NAME
@ -1421,7 +1421,7 @@ has the socket open where the packet is sourced from or destined to
(depending on which socket is local).
This is in addition to the normal information logged.
.Pp
Due to the problems described in the BUGS section only the first packet
Only the first packet
logged via
.Ar log (all, user)
will have the user credentials logged when using stateful matching.
@ -1479,13 +1479,6 @@ of the following keywords:
.Bl -tag -width xxxxxxxxxxxxxx -compact
.It Ar any
Any address.
.It Ar route Aq Ar label
Any address whose associated route has label
.Aq Ar label .
See
.Xr route 4
and
.Xr route 8 .
.It Ar no-route
Any address which is not currently routable.
.It Ar urpf-failed
@ -1594,7 +1587,6 @@ pass in proto tcp from any to any port 25
pass in proto tcp from 10.0.0.0/8 port \*(Gt 1024 \e
to ! 10.1.2.3 port != ssh
pass in proto tcp from any os "OpenBSD"
pass in proto tcp from route "DTAG"
.Ed
.It Ar all
This is equivalent to "from any to any".
@ -2949,9 +2941,9 @@ proto-list = ( proto-name | proto-number ) [ [ "," ] proto-list ]
hosts = "all" |
"from" ( "any" | "no-route" | "urpf-failed" | "self" | host |
"{" host-list "}" | "route" string ) [ port ] [ os ]
"{" host-list "}" ) [ port ] [ os ]
"to" ( "any" | "no-route" | "self" | host |
"{" host-list "}" | "route" string ) [ port ]
"{" host-list "}" ) [ port ]
ipspec = "any" | host | "{" host-list "}"
host = [ "!" ] ( address [ "/" mask-bits ] | "\*(Lt" string "\*(Gt" )
@ -3048,28 +3040,6 @@ Protocol name database.
.It Pa /etc/services
Service name database.
.El
.Sh BUGS
Due to a lock order reversal (LOR) with the socket layer, the use of the
.Ar group
and
.Ar user
filter parameter in conjuction with a Giant-free netstack
can result in a deadlock.
A workaround is available under the
.Va debug.pfugidhack
sysctl which is automatically enabled when a
.Ar user
/
.Ar group
rule is added or
.Ar log (user)
is specified.
.Pp
Route labels are not supported by the
.Fx
.Xr route 4
system.
Rules with a route label do not match any traffic.
.Sh SEE ALSO
.Xr altq 4 ,
.Xr carp 4 ,
@ -3080,7 +3050,6 @@ Rules with a route label do not match any traffic.
.Xr pf 4 ,
.Xr pflow 4 ,
.Xr pfsync 4 ,
.Xr route 4 ,
.Xr tcp 4 ,
.Xr udp 4 ,
.Xr hosts 5 ,
@ -3090,7 +3059,6 @@ Rules with a route label do not match any traffic.
.Xr ftp-proxy 8 ,
.Xr pfctl 8 ,
.Xr pflogd 8 ,
.Xr route 8
.Sh HISTORY
The
.Nm

View File

@ -159,8 +159,7 @@ enum { PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK,
PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY,
PF_STATE_OPT_PFLOW };
PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY, };
enum { PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
@ -451,7 +450,7 @@ int parseport(char *, struct range *r, int);
%token QUEUE PRIORITY QLIMIT RTABLE
%token LOAD RULESET_OPTIMIZATION
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
%token DIVERTTO DIVERTREPLY
%token <v.string> STRING
@ -2081,15 +2080,6 @@ pfrule : action dir logquick interface route af proto fromto
}
r.rule_flag |= PFRULE_STATESLOPPY;
break;
case PF_STATE_OPT_PFLOW:
if (r.rule_flag & PFRULE_PFLOW) {
yyerror("state pflow "
"option: multiple "
"definitions");
YYERROR;
}
r.rule_flag |= PFRULE_PFLOW;
break;
case PF_STATE_OPT_TIMEOUT:
if (o->data.timeout.number ==
PFTM_ADAPTIVE_START ||
@ -2909,26 +2899,6 @@ host : STRING {
$$->next = NULL;
$$->tail = $$;
}
| ROUTE STRING {
$$ = calloc(1, sizeof(struct node_host));
if ($$ == NULL) {
free($2);
err(1, "host: calloc");
}
$$->addr.type = PF_ADDR_RTLABEL;
if (strlcpy($$->addr.v.rtlabelname, $2,
sizeof($$->addr.v.rtlabelname)) >=
sizeof($$->addr.v.rtlabelname)) {
yyerror("route label too long, max %u chars",
sizeof($$->addr.v.rtlabelname) - 1);
free($2);
free($$);
YYERROR;
}
$$->next = NULL;
$$->tail = $$;
free($2);
}
;
number : NUMBER
@ -3597,14 +3567,6 @@ state_opt_item : MAXIMUM NUMBER {
$$->next = NULL;
$$->tail = $$;
}
| PFLOW {
$$ = calloc(1, sizeof(struct node_state_opt));
if ($$ == NULL)
err(1, "state_opt_item: calloc");
$$->type = PF_STATE_OPT_PFLOW;
$$->next = NULL;
$$->tail = $$;
}
| STRING NUMBER {
int i;
@ -5320,7 +5282,6 @@ lookup(char *s)
{ "out", OUT},
{ "overload", OVERLOAD},
{ "pass", PASS},
{ "pflow", PFLOW},
{ "port", PORT},
{ "priority", PRIORITY},
{ "priq", PRIQ},

View File

@ -119,9 +119,6 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
case PF_ADDR_URPFFAILED:
printf("urpf-failed");
return;
case PF_ADDR_RTLABEL:
printf("route \"%s\"", addr->v.rtlabelname);
return;
default:
printf("?");
return;
@ -339,8 +336,6 @@ print_state(struct pfsync_state *s, int opts)
printf(", rule %u", ntohl(s->rule));
if (s->state_flags & PFSTATE_SLOPPY)
printf(", sloppy");
if (s->state_flags & PFSTATE_PFLOW)
printf(", pflow");
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
printf(", source-track");
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)

View File

@ -144,7 +144,6 @@ static const struct {
{ "states", PF_LIMIT_STATES },
{ "src-nodes", PF_LIMIT_SRC_NODES },
{ "frags", PF_LIMIT_FRAGS },
{ "tables", PF_LIMIT_TABLES },
{ "table-entries", PF_LIMIT_TABLE_ENTRIES },
{ NULL, 0 }
};
@ -1553,9 +1552,6 @@ pfctl_fopen(const char *name, const char *mode)
void
pfctl_init_options(struct pfctl *pf)
{
int64_t mem;
int mib[2];
size_t size;
pf->timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
pf->timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
@ -1581,21 +1577,8 @@ pfctl_init_options(struct pfctl *pf)
pf->limit[PF_LIMIT_STATES] = PFSTATE_HIWAT;
pf->limit[PF_LIMIT_FRAGS] = PFFRAG_FRENT_HIWAT;
pf->limit[PF_LIMIT_SRC_NODES] = PFSNODE_HIWAT;
pf->limit[PF_LIMIT_TABLES] = PFR_KTABLE_HIWAT;
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT;
mib[0] = CTL_HW;
#ifdef __FreeBSD__
mib[1] = HW_PHYSMEM;
#else
mib[1] = HW_PHYSMEM64;
#endif
size = sizeof(mem);
if (sysctl(mib, 2, &mem, &size, NULL, 0) == -1)
err(1, "sysctl");
if (mem <= 100*1024*1024)
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT_SMALL;
pf->debug = PF_DEBUG_URGENT;
}

View File

@ -955,12 +955,6 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
printf("sloppy");
opts = 0;
}
if (r->rule_flag & PFRULE_PFLOW) {
if (!opts)
printf(", ");
printf("pflow");
opts = 0;
}
for (i = 0; i < PFTM_MAX; ++i)
if (r->timeout[i]) {
int j;

View File

@ -621,8 +621,7 @@ print_iface(struct pfi_kif *p, int opts)
if (!(opts & PF_OPT_VERBOSE2))
return;
printf("\tCleared: %s", ctime(&tzero));
printf("\tReferences: [ States: %-18d Rules: %-18d ]\n",
p->pfik_states, p->pfik_rules);
printf("\tReferences: %-18d\n", p->pfik_rulerefs);
for (i = 0; i < 8; i++) {
af = (i>>2) & 1;
dir = (i>>1) &1;

View File

@ -271,10 +271,9 @@ cbq_add_altq(struct pf_altq *a)
return (ENODEV);
/* allocate and initialize cbq_state_t */
cbqp = malloc(sizeof(cbq_state_t), M_DEVBUF, M_WAITOK);
cbqp = malloc(sizeof(cbq_state_t), M_DEVBUF, M_NOWAIT | M_ZERO);
if (cbqp == NULL)
return (ENOMEM);
bzero(cbqp, sizeof(cbq_state_t));
CALLOUT_INIT(&cbqp->cbq_callout);
cbqp->cbq_qlen = 0;
cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */

View File

@ -200,10 +200,9 @@ hfsc_add_altq(struct pf_altq *a)
if (!ALTQ_IS_READY(&ifp->if_snd))
return (ENODEV);
hif = malloc(sizeof(struct hfsc_if), M_DEVBUF, M_WAITOK);
hif = malloc(sizeof(struct hfsc_if), M_DEVBUF, M_NOWAIT | M_ZERO);
if (hif == NULL)
return (ENOMEM);
bzero(hif, sizeof(struct hfsc_if));
hif->hif_eligible = ellist_alloc();
if (hif->hif_eligible == NULL) {

View File

@ -132,11 +132,9 @@ priq_add_altq(struct pf_altq *a)
if (!ALTQ_IS_READY(&ifp->if_snd))
return (ENODEV);
pif = malloc(sizeof(struct priq_if),
M_DEVBUF, M_WAITOK);
pif = malloc(sizeof(struct priq_if), M_DEVBUF, M_NOWAIT | M_ZERO);
if (pif == NULL)
return (ENOMEM);
bzero(pif, sizeof(struct priq_if));
pif->pif_bandwidth = a->ifbandwidth;
pif->pif_maxpri = -1;
pif->pif_ifq = &ifp->if_snd;

View File

@ -401,14 +401,11 @@ tbr_set(ifq, profile)
return (0);
}
IFQ_UNLOCK(ifq);
tbr = malloc(sizeof(struct tb_regulator),
M_DEVBUF, M_WAITOK);
if (tbr == NULL) { /* can not happen */
tbr = malloc(sizeof(struct tb_regulator), M_DEVBUF, M_NOWAIT | M_ZERO);
if (tbr == NULL) {
IFQ_UNLOCK(ifq);
return (ENOMEM);
}
bzero(tbr, sizeof(struct tb_regulator));
tbr->tbr_rate = TBR_SCALE(profile->rate / 8) / machclk_freq;
tbr->tbr_depth = TBR_SCALE(profile->depth);
@ -420,7 +417,6 @@ tbr_set(ifq, profile)
tbr->tbr_last = read_machclk();
tbr->tbr_lastop = ALTDQ_REMOVE;
IFQ_LOCK(ifq);
otbr = ifq->altq_tbr;
ifq->altq_tbr = tbr; /* set the new tbr */

View File

@ -33,61 +33,34 @@
* PURPOSE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_bpf.h"
#include "opt_pf.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifdef DEV_BPF
#define NBPFILTER DEV_BPF
#else
#define NBPFILTER 0
#endif
#ifdef DEV_PFLOG
#define NPFLOG DEV_PFLOG
#else
#define NPFLOG 0
#endif
#else /* ! __FreeBSD__ */
#include "bpfilter.h"
#include "pflog.h"
#endif /* __FreeBSD__ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/socket.h>
#ifdef __FreeBSD__
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/sockio.h>
#else
#include <sys/ioctl.h>
#endif
#include <net/if.h>
#ifdef __FreeBSD__
#include <net/if_clone.h>
#endif
#include <net/if_types.h>
#include <net/route.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_clone.h>
#include <net/if_pflog.h>
#include <net/if_types.h>
#include <net/pfvar.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
#endif
#ifdef INET
#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif
@ -96,14 +69,9 @@ __FBSDID("$FreeBSD$");
#include <netinet6/nd6.h>
#endif /* INET6 */
#include <net/pfvar.h>
#include <net/if_pflog.h>
#ifdef __FreeBSD__
#ifdef INET
#include <machine/in_cksum.h>
#endif /* INET */
#endif /* __FreeBSD__ */
#define PFLOGMTU (32768 + MHLEN + MLEN)
@ -113,170 +81,82 @@ __FBSDID("$FreeBSD$");
#define DPRINTF(x)
#endif
void pflogattach(int);
int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
#ifdef __FreeBSD__
static int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct route *);
#else
struct rtentry *);
#endif
int pflogioctl(struct ifnet *, u_long, caddr_t);
void pflogstart(struct ifnet *);
#ifdef __FreeBSD__
static void pflogattach(int);
static int pflogioctl(struct ifnet *, u_long, caddr_t);
static void pflogstart(struct ifnet *);
static int pflog_clone_create(struct if_clone *, int, caddr_t);
static void pflog_clone_destroy(struct ifnet *);
#else
int pflog_clone_create(struct if_clone *, int);
int pflog_clone_destroy(struct ifnet *);
#endif
LIST_HEAD(, pflog_softc) pflogif_list;
#ifdef __FreeBSD__
IFC_SIMPLE_DECLARE(pflog, 1);
#else
struct if_clone pflog_cloner =
IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
#endif
struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
void
static void
pflogattach(int npflog)
{
int i;
LIST_INIT(&pflogif_list);
for (i = 0; i < PFLOGIFS_MAX; i++)
pflogifs[i] = NULL;
if_clone_attach(&pflog_cloner);
}
#ifdef __FreeBSD__
static int
pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
#else
int
pflog_clone_create(struct if_clone *ifc, int unit)
#endif
{
struct ifnet *ifp;
struct pflog_softc *pflogif;
int s;
if (unit >= PFLOGIFS_MAX)
return (EINVAL);
if ((pflogif = malloc(sizeof(*pflogif),
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
return (ENOMEM);
pflogif->sc_unit = unit;
#ifdef __FreeBSD__
ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
ifp = if_alloc(IFT_PFLOG);
if (ifp == NULL) {
free(pflogif, M_DEVBUF);
return (ENOSPC);
}
if_initname(ifp, ifc->ifc_name, unit);
#else
ifp = &pflogif->sc_if;
snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
#endif
ifp->if_softc = pflogif;
ifp->if_mtu = PFLOGMTU;
ifp->if_ioctl = pflogioctl;
ifp->if_output = pflogoutput;
ifp->if_start = pflogstart;
#ifndef __FreeBSD__
ifp->if_type = IFT_PFLOG;
#endif
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_hdrlen = PFLOG_HDRLEN;
if_attach(ifp);
#ifndef __FreeBSD__
if_alloc_sadl(ifp);
#endif
#if NBPFILTER > 0
#ifdef __FreeBSD__
bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
#else
bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
#endif
#endif
s = splnet();
#ifdef __FreeBSD__
/* XXX: Why pf(4) lock?! Better add a pflog lock?! */
PF_LOCK();
#endif
LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
pflogifs[unit] = ifp;
#ifdef __FreeBSD__
PF_UNLOCK();
#endif
splx(s);
return (0);
}
#ifdef __FreeBSD__
static void
pflog_clone_destroy(struct ifnet *ifp)
#else
int
pflog_clone_destroy(struct ifnet *ifp)
#endif
{
struct pflog_softc *pflogif = ifp->if_softc;
int s;
int i;
s = splnet();
#ifdef __FreeBSD__
PF_LOCK();
#endif
pflogifs[pflogif->sc_unit] = NULL;
LIST_REMOVE(pflogif, sc_list);
#ifdef __FreeBSD__
PF_UNLOCK();
#endif
splx(s);
for (i = 0; i < PFLOGIFS_MAX; i++)
if (pflogifs[i] == ifp)
pflogifs[i] = NULL;
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
if_detach(ifp);
#ifdef __FreeBSD__
if_free(ifp);
#endif
free(pflogif, M_DEVBUF);
#ifndef __FreeBSD__
return (0);
#endif
}
/*
* Start output on the pflog interface.
*/
void
static void
pflogstart(struct ifnet *ifp)
{
struct mbuf *m;
#ifndef __FreeBSD__
int s;
#endif
for (;;) {
#ifdef __FreeBSD__
IF_LOCK(&ifp->if_snd);
_IF_DROP(&ifp->if_snd);
_IF_DEQUEUE(&ifp->if_snd, m);
IF_UNLOCK(&ifp->if_snd);
#else
s = splnet();
IF_DROP(&ifp->if_snd);
IF_DEQUEUE(&ifp->if_snd, m);
splx(s);
#endif
if (m == NULL)
return;
@ -285,35 +165,24 @@ pflogstart(struct ifnet *ifp)
}
}
int
static int
pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
#ifdef __FreeBSD__
struct route *rt)
#else
struct rtentry *rt)
#endif
{
m_freem(m);
return (0);
}
/* ARGSUSED */
int
static int
pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
switch (cmd) {
case SIOCSIFFLAGS:
#ifdef __FreeBSD__
if (ifp->if_flags & IFF_UP)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
else
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
#else
if (ifp->if_flags & IFF_UP)
ifp->if_flags |= IFF_RUNNING;
else
ifp->if_flags &= ~IFF_RUNNING;
#endif
break;
default:
return (ENOTTY);
@ -322,12 +191,11 @@ pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
return (0);
}
int
static int
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, struct pf_pdesc *pd)
struct pf_ruleset *ruleset, struct pf_pdesc *pd, int lookupsafe)
{
#if NBPFILTER > 0
struct ifnet *ifn;
struct pfloghdr hdr;
@ -354,23 +222,18 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
strlcpy(hdr.ruleset, ruleset->anchor->name,
sizeof(hdr.ruleset));
}
if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
#ifdef __FreeBSD__
/*
* XXX: This should not happen as we force an early lookup
* via debug.pfugidhack
* XXXGL: we avoid pf_socket_lookup() when we are holding
* state lock, since this leads to unsafe LOR.
* These conditions are very very rare, however.
*/
; /* empty */
#else
pd->lookup.done = pf_socket_lookup(dir, pd);
#endif
if (pd->lookup.done > 0) {
if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done && lookupsafe)
pd->lookup.done = pf_socket_lookup(dir, pd, m);
if (pd->lookup.done > 0)
hdr.uid = pd->lookup.uid;
hdr.pid = pd->lookup.pid;
} else {
else
hdr.uid = UID_MAX;
hdr.pid = NO_PID;
}
hdr.rule_uid = rm->cuid;
hdr.rule_pid = rm->cpid;
hdr.dir = dir;
@ -387,18 +250,11 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
ifn->if_opackets++;
ifn->if_obytes += m->m_pkthdr.len;
#ifdef __FreeBSD__
BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
#else
bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
BPF_DIRECTION_OUT);
#endif
#endif
return (0);
}
#ifdef __FreeBSD__
static int
pflog_modevent(module_t mod, int type, void *data)
{
@ -407,14 +263,14 @@ pflog_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
pflogattach(1);
PF_LOCK();
PF_RULES_WLOCK();
pflog_packet_ptr = pflog_packet;
PF_UNLOCK();
PF_RULES_WUNLOCK();
break;
case MOD_UNLOAD:
PF_LOCK();
PF_RULES_WLOCK();
pflog_packet_ptr = NULL;
PF_UNLOCK();
PF_RULES_WUNLOCK();
if_clone_detach(&pflog_cloner);
break;
default:
@ -432,4 +288,3 @@ static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 };
DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
MODULE_VERSION(pflog, PFLOG_MODVER);
MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
#endif /* __FreeBSD__ */

View File

@ -29,16 +29,6 @@
#define PFLOGIFS_MAX 16
struct pflog_softc {
#ifdef __FreeBSD__
struct ifnet *sc_ifp; /* the interface pointer */
#else
struct ifnet sc_if; /* the interface */
#endif
int sc_unit;
LIST_ENTRY(pflog_softc) sc_list;
};
#define PFLOG_RULESET_NAME_SIZE 16
struct pfloghdr {
@ -62,40 +52,15 @@ struct pfloghdr {
/* minus pad, also used as a signature */
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
/* XXX remove later when old format logs are no longer needed */
struct old_pfloghdr {
u_int32_t af;
char ifname[IFNAMSIZ];
short rnr;
u_short reason;
u_short action;
u_short dir;
};
#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
#ifdef _KERNEL
#ifdef __FreeBSD__
struct pf_rule;
struct pf_ruleset;
struct pfi_kif;
struct pf_pdesc;
#if 0
typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
struct pf_ruleset *, struct pf_pdesc *);
extern pflog_packet_t *pflog_packet_ptr;
#endif
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
#define PFLOG_PACKET(i,a,b,c,d,e,f,g,h,di) do { \
if (pflog_packet_ptr != NULL) \
pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
pflog_packet_ptr(i,a,b,c,d,e,f,g,h,di); \
} while (0)
#else /* ! __FreeBSD__ */
#if NPFLOG > 0
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) pflog_packet(i,a,b,c,d,e,f,g,h)
#else
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0)
#endif /* NPFLOG > 0 */
#endif
#endif /* _KERNEL */
#endif /* _NET_IF_PFLOG_H_ */

View File

@ -1,126 +0,0 @@
/* $OpenBSD: if_pflow.h,v 1.5 2009/02/27 11:09:36 gollo Exp $ */
/*
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
* Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $FreeBSD$
*/
#ifndef _NET_IF_PFLOW_H_
#define _NET_IF_PFLOW_H_
#define PFLOW_ID_LEN sizeof(u_int64_t)
#define PFLOW_MAXFLOWS 30
#define PFLOW_VERSION 5
#define PFLOW_ENGINE_TYPE 42
#define PFLOW_ENGINE_ID 42
#define PFLOW_MAXBYTES 0xffffffff
#define PFLOW_TIMEOUT 30
struct pflow_flow {
u_int32_t src_ip;
u_int32_t dest_ip;
u_int32_t nexthop_ip;
u_int16_t if_index_in;
u_int16_t if_index_out;
u_int32_t flow_packets;
u_int32_t flow_octets;
u_int32_t flow_start;
u_int32_t flow_finish;
u_int16_t src_port;
u_int16_t dest_port;
u_int8_t pad1;
u_int8_t tcp_flags;
u_int8_t protocol;
u_int8_t tos;
u_int16_t src_as;
u_int16_t dest_as;
u_int8_t src_mask;
u_int8_t dest_mask;
u_int16_t pad2;
} __packed;
#ifdef _KERNEL
extern int pflow_ok;
struct pflow_softc {
struct ifnet sc_if;
struct ifnet *sc_pflow_ifp;
unsigned int sc_count;
unsigned int sc_maxcount;
u_int64_t sc_gcounter;
struct ip_moptions sc_imo;
#ifdef __FreeBSD__
struct callout sc_tmo;
#else
struct timeout sc_tmo;
#endif
struct in_addr sc_sender_ip;
u_int16_t sc_sender_port;
struct in_addr sc_receiver_ip;
u_int16_t sc_receiver_port;
struct mbuf *sc_mbuf; /* current cumulative mbuf */
SLIST_ENTRY(pflow_softc) sc_next;
};
extern struct pflow_softc *pflowif;
#endif /* _KERNEL */
struct pflow_header {
u_int16_t version;
u_int16_t count;
u_int32_t uptime_ms;
u_int32_t time_sec;
u_int32_t time_nanosec;
u_int32_t flow_sequence;
u_int8_t engine_type;
u_int8_t engine_id;
u_int8_t reserved1;
u_int8_t reserved2;
} __packed;
#define PFLOW_HDRLEN sizeof(struct pflow_header)
struct pflowstats {
u_int64_t pflow_flows;
u_int64_t pflow_packets;
u_int64_t pflow_onomem;
u_int64_t pflow_oerrors;
};
/*
* Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
*/
struct pflowreq {
struct in_addr sender_ip;
struct in_addr receiver_ip;
u_int16_t receiver_port;
u_int16_t addrmask;
#define PFLOW_MASK_SRCIP 0x01
#define PFLOW_MASK_DSTIP 0x02
#define PFLOW_MASK_DSTPRT 0x04
};
#ifdef _KERNEL
int export_pflow(struct pf_state *);
int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
#endif /* _KERNEL */
#endif /* _NET_IF_PFLOW_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -256,6 +256,9 @@ struct pfsyncstats {
u_int64_t pfsyncs_opackets6; /* total output packets, IPv6 */
u_int64_t pfsyncs_onomem; /* no memory for an mbuf */
u_int64_t pfsyncs_oerrors; /* ip output error */
u_int64_t pfsyncs_iacts[PFSYNC_ACT_MAX];
u_int64_t pfsyncs_oacts[PFSYNC_ACT_MAX];
};
/*
@ -268,10 +271,8 @@ struct pfsyncreq {
int pfsyncr_defer;
};
#ifdef __FreeBSD__
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
#endif
#ifdef _KERNEL
@ -288,37 +289,10 @@ struct pfsyncreq {
#define PFSYNC_S_DEFER 0xfe
#define PFSYNC_S_NONE 0xff
#ifdef __FreeBSD__
void pfsync_input(struct mbuf *, __unused int);
#else
void pfsync_input(struct mbuf *, ...);
#endif
int pfsync_sysctl(int *, u_int, void *, size_t *,
void *, size_t);
#define PFSYNC_SI_IOCTL 0x01
#define PFSYNC_SI_CKSUM 0x02
#define PFSYNC_SI_ACK 0x04
int pfsync_state_import(struct pfsync_state *, u_int8_t);
#ifndef __FreeBSD__
void pfsync_state_export(struct pfsync_state *,
struct pf_state *);
#endif
void pfsync_insert_state(struct pf_state *);
void pfsync_update_state(struct pf_state *);
void pfsync_delete_state(struct pf_state *);
void pfsync_clear_states(u_int32_t, const char *);
#ifdef notyet
void pfsync_update_tdb(struct tdb *, int);
void pfsync_delete_tdb(struct tdb *);
#endif
int pfsync_defer(struct pf_state *, struct mbuf *);
int pfsync_up(void);
int pfsync_state_in_use(struct pf_state *);
#endif
#endif /* _KERNEL */
#endif /* _NET_IF_PFSYNC_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -35,136 +35,31 @@
*
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_pf.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifdef __FreeBSD__
#include "opt_bpf.h"
#include "opt_pf.h"
#ifdef DEV_BPF
#define NBPFILTER DEV_BPF
#else
#define NBPFILTER 0
#endif
#ifdef DEV_PFLOG
#define NPFLOG DEV_PFLOG
#else
#define NPFLOG 0
#endif
#ifdef DEV_PFSYNC
#define NPFSYNC DEV_PFSYNC
#else
#define NPFSYNC 0
#endif
#ifdef DEV_PFLOW
#define NPFLOW DEV_PFLOW
#else
#define NPFLOW 0
#endif
#else
#include "bpfilter.h"
#include "pflog.h"
#include "pfsync.h"
#include "pflow.h"
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/filio.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/kernel.h>
#include <sys/time.h>
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#endif
#ifndef __FreeBSD__
#include <sys/pool.h>
#endif
#include <sys/proc.h>
#ifdef __FreeBSD__
#include <sys/kthread.h>
#include <sys/lock.h>
#include <sys/sx.h>
#else
#include <sys/rwlock.h>
#endif
#ifdef __FreeBSD__
#include <sys/md5.h>
#else
#include <crypto/md5.h>
#endif
#include <net/if.h>
#include <net/if_types.h>
#include <net/bpf.h>
#include <net/route.h>
#include <net/radix_mpath.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_seq.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <netinet/in_pcb.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/udp_var.h>
#include <netinet/icmp_var.h>
#include <netinet/if_ether.h>
#ifndef __FreeBSD__
#include <dev/rndvar.h>
#endif
#include <net/pfvar.h>
#include <net/if_pflog.h>
#include <net/if_pflow.h>
#include <net/pf_mtag.h>
#if NPFSYNC > 0
#include <net/if_pfsync.h>
#endif /* NPFSYNC > 0 */
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet/in_pcb.h>
#include <netinet/icmp6.h>
#include <netinet6/nd6.h>
#endif /* INET6 */
#ifdef __FreeBSD__
#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
#else
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
#endif
/*
* Global variables
*/
void pf_hash(struct pf_addr *, struct pf_addr *,
static void pf_hash(struct pf_addr *, struct pf_addr *,
struct pf_poolhashkey *, sa_family_t);
struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
static struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
int, int, struct pfi_kif *,
struct pf_addr *, u_int16_t, struct pf_addr *,
u_int16_t, int);
int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
static int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
struct pf_addr *, struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
struct pf_src_node **);
@ -185,7 +80,7 @@ int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
/*
* hash function based on bridge_hash in if_bridge.c
*/
void
static void
pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
struct pf_poolhashkey *key, sa_family_t af)
{
@ -226,7 +121,7 @@ pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
}
}
struct pf_rule *
static struct pf_rule *
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
struct pf_addr *daddr, u_int16_t dport, int rs_num)
@ -279,11 +174,8 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
!pf_match_port(dst->port_op, dst->port[0],
dst->port[1], dport))
r = r->skip[PF_SKIP_DST_PORT].ptr;
#ifdef __FreeBSD__
else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
#else
else if (r->match_tag && !pf_match_tag(m, r, &tag))
#endif
else if (r->match_tag && !pf_match_tag(m, r, &tag,
pd->pf_mtag ? pd->pf_mtag->tag : 0))
r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
@ -304,19 +196,19 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
NULL, NULL);
}
#ifdef __FreeBSD__
if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
#else
if (pf_tag_packet(m, tag, rtableid))
#endif
if (tag > 0 && pf_tag_packet(m, pd, tag))
return (NULL);
if (rtableid >= 0)
M_SETFIB(m, rtableid);
if (rm != NULL && (rm->action == PF_NONAT ||
rm->action == PF_NORDR || rm->action == PF_NOBINAT))
return (NULL);
return (rm);
}
int
static int
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
@ -370,20 +262,12 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
high = tmp;
}
/* low < high */
#ifdef __FreeBSD__
cut = htonl(arc4random()) % (1 + high - low) + low;
#else
cut = arc4random_uniform(1 + high - low) + low;
#endif
/* low <= cut <= high */
for (tmp = cut; tmp <= high; ++(tmp)) {
key.port[0] = htons(tmp);
if (pf_find_state_all(&key, PF_IN, NULL) ==
#ifdef __FreeBSD__
NULL) {
#else
NULL && !in_baddynamic(tmp, proto)) {
#endif
*nport = htons(tmp);
return (0);
}
@ -391,11 +275,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
for (tmp = cut - 1; tmp >= low; --(tmp)) {
key.port[0] = htons(tmp);
if (pf_find_state_all(&key, PF_IN, NULL) ==
#ifdef __FreeBSD__
NULL) {
#else
NULL && !in_baddynamic(tmp, proto)) {
#endif
*nport = htons(tmp);
return (0);
}
@ -422,38 +302,17 @@ int
pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
{
unsigned char hash[16];
struct pf_pool *rpool = &r->rpool;
struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
struct pf_pooladdr *acur = rpool->cur;
struct pf_src_node k;
struct pf_addr *raddr = NULL, *rmask = NULL;
if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
(r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
k.af = af;
PF_ACPY(&k.addr, saddr, af);
if (r->rule_flag & PFRULE_RULESRCTRACK ||
r->rpool.opts & PF_POOL_STICKYADDR)
k.rule.ptr = r;
else
k.rule.ptr = NULL;
#ifdef __FreeBSD__
V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
*sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
#else
pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
*sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
#endif
*sn = pf_find_src_node(saddr, r, af, 0);
if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
PF_ACPY(naddr, &(*sn)->raddr, af);
#ifdef __FreeBSD__
if (V_pf_status.debug >= PF_DEBUG_MISC) {
#else
if (pf_status.debug >= PF_DEBUG_MISC) {
#endif
printf("pf_map_addr: src tracking maps ");
pf_print_host(&k.addr, 0, af);
pf_print_host(saddr, 0, af);
printf(" to ");
pf_print_host(naddr, 0, af);
printf("\n");
@ -542,31 +401,58 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
}
break;
case PF_POOL_SRCHASH:
{
unsigned char hash[16];
pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
break;
}
case PF_POOL_ROUNDROBIN:
{
struct pf_pooladdr *acur = rpool->cur;
/*
* XXXGL: in the round-robin case we need to store
* the round-robin machine state in the rule, thus
* forwarding thread needs to modify rule.
*
* This is done w/o locking, because performance is assumed
* more important than round-robin precision.
*
* In the simpliest case we just update the "rpool->cur"
* pointer. However, if pool contains tables or dynamic
* addresses, then "tblidx" is also used to store machine
* state. Since "tblidx" is int, concurrent access to it can't
* lead to inconsistence, only to lost of precision.
*
* Things get worse, if table contains not hosts, but
* prefixes. In this case counter also stores machine state,
* and for IPv6 address, counter can't be updated atomically.
* Probably, using round-robin on a table containing IPv6
* prefixes (or even IPv4) would cause a panic.
*/
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if (!pfr_pool_get(rpool->cur->addr.p.tbl,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, af))
&rpool->tblidx, &rpool->counter, af))
goto get_addr;
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, af))
&rpool->tblidx, &rpool->counter, af))
goto get_addr;
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
goto get_addr;
try_next:
if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
if (TAILQ_NEXT(rpool->cur, entries) == NULL)
rpool->cur = TAILQ_FIRST(&rpool->list);
else
rpool->cur = TAILQ_NEXT(rpool->cur, entries);
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
rpool->tblidx = -1;
if (pfr_pool_get(rpool->cur->addr.p.tbl,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, af)) {
&rpool->tblidx, &rpool->counter, af)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
@ -575,8 +461,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
rpool->tblidx = -1;
if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, af)) {
&rpool->tblidx, &rpool->counter, af)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
@ -595,14 +480,11 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
PF_AINC(&rpool->counter, af);
break;
}
}
if (*sn != NULL)
PF_ACPY(&(*sn)->raddr, naddr, af);
#ifdef __FreeBSD__
if (V_pf_status.debug >= PF_DEBUG_MISC &&
#else
if (pf_status.debug >= PF_DEBUG_MISC &&
#endif
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
printf("pf_map_addr: selected address ");
pf_print_host(naddr, 0, af);
@ -615,13 +497,17 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
struct pf_rule *
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
struct pfi_kif *kif, struct pf_src_node **sn,
struct pf_state_key **skw, struct pf_state_key **sks,
struct pf_state_key **skp, struct pf_state_key **nkp,
struct pf_addr *saddr, struct pf_addr *daddr,
u_int16_t sport, u_int16_t dport)
{
struct pf_rule *r = NULL;
struct pf_addr *naddr;
uint16_t *nport;
PF_RULES_RASSERT();
KASSERT(*skp == NULL, ("*skp not NULL"));
KASSERT(*nkp == NULL, ("*nkp not NULL"));
if (direction == PF_OUT) {
r = pf_match_translation(pd, m, off, direction, kif, saddr,
@ -637,33 +523,39 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
saddr, sport, daddr, dport, PF_RULESET_BINAT);
}
if (r != NULL) {
struct pf_addr *naddr;
u_int16_t *nport;
if (pf_state_key_setup(pd, r, skw, sks, skp, nkp,
saddr, daddr, sport, dport))
return r;
/* XXX We only modify one side for now. */
naddr = &(*nkp)->addr[1];
nport = &(*nkp)->port[1];
if (r == NULL)
return (NULL);
switch (r->action) {
case PF_NONAT:
case PF_NOBINAT:
case PF_NORDR:
return (NULL);
}
*skp = pf_state_key_setup(pd, saddr, daddr, sport, dport);
if (*skp == NULL)
return (NULL);
*nkp = pf_state_key_clone(*skp);
if (*nkp == NULL) {
uma_zfree(V_pf_state_key_z, skp);
*skp = NULL;
return (NULL);
}
/* XXX We only modify one side for now. */
naddr = &(*nkp)->addr[1];
nport = &(*nkp)->port[1];
switch (r->action) {
case PF_NAT:
if (pf_get_sport(pd->af, pd->proto, r, saddr,
daddr, dport, naddr, nport, r->rpool.proxy_port[0],
if (pf_get_sport(pd->af, pd->proto, r, saddr, daddr, dport,
naddr, nport, r->rpool.proxy_port[0],
r->rpool.proxy_port[1], sn)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: NAT proxy port allocation "
"(%u-%u) failed\n",
r->rpool.proxy_port[0],
r->rpool.proxy_port[1]));
return (NULL);
("pf: NAT proxy port allocation (%u-%u) failed\n",
r->rpool.proxy_port[0], r->rpool.proxy_port[1]));
goto notrans;
}
break;
case PF_BINAT:
@ -675,119 +567,97 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
case AF_INET:
if (r->rpool.cur->addr.p.dyn->
pfid_acnt4 < 1)
return (NULL);
goto notrans;
PF_POOLMASK(naddr,
&r->rpool.cur->addr.p.dyn->
pfid_addr4,
&r->rpool.cur->addr.p.dyn->
pfid_mask4,
saddr, AF_INET);
pfid_mask4, saddr, AF_INET);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (r->rpool.cur->addr.p.dyn->
pfid_acnt6 < 1)
return (NULL);
goto notrans;
PF_POOLMASK(naddr,
&r->rpool.cur->addr.p.dyn->
pfid_addr6,
&r->rpool.cur->addr.p.dyn->
pfid_mask6,
saddr, AF_INET6);
pfid_mask6, saddr, AF_INET6);
break;
#endif /* INET6 */
}
} else
PF_POOLMASK(naddr,
&r->rpool.cur->addr.v.a.addr,
&r->rpool.cur->addr.v.a.mask,
saddr, pd->af);
&r->rpool.cur->addr.v.a.mask, saddr,
pd->af);
break;
case PF_IN:
if (r->src.addr.type == PF_ADDR_DYNIFTL) {
switch (pd->af) {
#ifdef INET
case AF_INET:
if (r->src.addr.p.dyn->
pfid_acnt4 < 1)
return (NULL);
if (r->src.addr.p.dyn-> pfid_acnt4 < 1)
goto notrans;
PF_POOLMASK(naddr,
&r->src.addr.p.dyn->
pfid_addr4,
&r->src.addr.p.dyn->
pfid_mask4,
&r->src.addr.p.dyn->pfid_addr4,
&r->src.addr.p.dyn->pfid_mask4,
daddr, AF_INET);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (r->src.addr.p.dyn->
pfid_acnt6 < 1)
return (NULL);
if (r->src.addr.p.dyn->pfid_acnt6 < 1)
goto notrans;
PF_POOLMASK(naddr,
&r->src.addr.p.dyn->
pfid_addr6,
&r->src.addr.p.dyn->
pfid_mask6,
&r->src.addr.p.dyn->pfid_addr6,
&r->src.addr.p.dyn->pfid_mask6,
daddr, AF_INET6);
break;
#endif /* INET6 */
}
} else
PF_POOLMASK(naddr,
&r->src.addr.v.a.addr,
&r->src.addr.v.a.mask, daddr,
pd->af);
PF_POOLMASK(naddr, &r->src.addr.v.a.addr,
&r->src.addr.v.a.mask, daddr, pd->af);
break;
}
break;
case PF_RDR: {
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
return (NULL);
if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
PF_POOL_BITMASK)
PF_POOLMASK(naddr, naddr,
&r->rpool.cur->addr.v.a.mask, daddr,
pd->af);
goto notrans;
if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask,
daddr, pd->af);
if (r->rpool.proxy_port[1]) {
u_int32_t tmp_nport;
uint32_t tmp_nport;
tmp_nport = ((ntohs(dport) -
ntohs(r->dst.port[0])) %
(r->rpool.proxy_port[1] -
r->rpool.proxy_port[0] + 1)) +
r->rpool.proxy_port[0];
tmp_nport = ((ntohs(dport) - ntohs(r->dst.port[0])) %
(r->rpool.proxy_port[1] - r->rpool.proxy_port[0] +
1)) + r->rpool.proxy_port[0];
/* wrap around if necessary */
/* Wrap around if necessary. */
if (tmp_nport > 65535)
tmp_nport -= 65535;
*nport = htons((u_int16_t)tmp_nport);
*nport = htons((uint16_t)tmp_nport);
} else if (r->rpool.proxy_port[0])
*nport = htons(r->rpool.proxy_port[0]);
break;
}
default:
return (NULL);
}
/*
* Translation was a NOP.
* Pretend there was no match.
*/
if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
#ifdef __FreeBSD__
pool_put(&V_pf_state_key_pl, *nkp);
pool_put(&V_pf_state_key_pl, *skp);
#else
pool_put(&pf_state_key_pl, *nkp);
pool_put(&pf_state_key_pl, *skp);
#endif
*skw = *sks = *nkp = *skp = NULL;
return (NULL);
}
panic("%s: unknown action %u", __func__, r->action);
}
/* Return success only if translation really happened. */
if (bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp)))
return (r);
}
notrans:
uma_zfree(V_pf_state_key_z, *nkp);
uma_zfree(V_pf_state_key_z, *skp);
*skp = *nkp = NULL;
return (NULL);
}

View File

@ -42,17 +42,12 @@
struct pf_mtag {
void *hdr; /* saved hdr pos in mbuf, for ECN */
void *statekey; /* pf stackside statekey */
u_int32_t qid; /* queue id */
u_int rtableid; /* alternate routing table id */
u_int16_t tag; /* tag id */
u_int8_t flags;
u_int8_t routed;
};
static __inline struct pf_mtag *pf_find_mtag(struct mbuf *);
static __inline struct pf_mtag *pf_get_mtag(struct mbuf *);
static __inline struct pf_mtag *
pf_find_mtag(struct mbuf *m)
{
@ -63,22 +58,5 @@ pf_find_mtag(struct mbuf *m)
return ((struct pf_mtag *)(mtag + 1));
}
static __inline struct pf_mtag *
pf_get_mtag(struct mbuf *m)
{
struct m_tag *mtag;
if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
M_NOWAIT);
if (mtag == NULL)
return (NULL);
bzero(mtag + 1, sizeof(struct pf_mtag));
m_tag_prepend(m, mtag);
}
return ((struct pf_mtag *)(mtag + 1));
}
#endif /* _KERNEL */
#endif /* _NET_PF_MTAG_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -17,23 +17,14 @@
*
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#ifdef _KERNEL
#include <sys/systm.h>
#ifndef __FreeBSD__
#include <sys/pool.h>
#endif
#endif /* _KERNEL */
#include <sys/mbuf.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
@ -41,77 +32,31 @@ __FBSDID("$FreeBSD$");
#include <net/pfvar.h>
#include <netinet/ip6.h>
#ifdef _KERNEL
#include <netinet6/in6_var.h>
#endif
#ifdef _KERNEL
#ifdef __FreeBSD__
static MALLOC_DEFINE(M_PFOSFP, "pf_osfp", "pf(4) operating system fingerprints");
#define DPFPRINTF(format, x...) \
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
printf(format , ##x)
#else
#define DPFPRINTF(format, x...) \
if (pf_status.debug >= PF_DEBUG_NOISY) \
printf(format , ##x)
#endif
#ifdef __FreeBSD__
typedef uma_zone_t pool_t;
#else
typedef struct pool pool_t;
#endif
#else
/* Userland equivalents so we can lend code to tcpdump et al. */
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#define pool_t int
#define pool_get(pool, flags) malloc(*(pool))
#define pool_put(pool, item) free(item)
#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
#ifdef __FreeBSD__
#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
#endif
#ifdef PFDEBUG
#include <sys/stdarg.h>
#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
#else
#define DPFPRINTF(format, x...) ((void)0)
#endif /* PFDEBUG */
#endif /* _KERNEL */
#ifdef __FreeBSD__
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint);
VNET_DEFINE(struct pf_osfp_list, pf_osfp_list);
static VNET_DEFINE(struct pf_osfp_list, pf_osfp_list) =
SLIST_HEAD_INITIALIZER();
#define V_pf_osfp_list VNET(pf_osfp_list)
VNET_DEFINE(pool_t, pf_osfp_entry_pl);
#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl)
VNET_DEFINE(pool_t, pf_osfp_pl);
#define pf_osfp_pl VNET(pf_osfp_pl)
#else
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list;
pool_t pf_osfp_entry_pl;
pool_t pf_osfp_pl;
static struct pf_osfp_enlist *pf_osfp_fingerprint_hdr(const struct ip *,
const struct ip6_hdr *,
const struct tcphdr *);
static struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
struct pf_os_fingerprint *, u_int8_t);
static struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *,
struct pf_os_fingerprint *);
static void pf_osfp_insert(struct pf_osfp_list *,
struct pf_os_fingerprint *);
#ifdef PFDEBUG
static struct pf_os_fingerprint *pf_osfp_validate(void);
#endif
struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
struct pf_os_fingerprint *, u_int8_t);
struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *,
struct pf_os_fingerprint *);
void pf_osfp_insert(struct pf_osfp_list *,
struct pf_os_fingerprint *);
#ifdef _KERNEL
/*
* Passively fingerprint the OS of the host (IPv4 TCP SYN packets only)
* Returns the list of possible OSes.
@ -140,19 +85,14 @@ pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));
}
#endif /* _KERNEL */
struct pf_osfp_enlist *
static struct pf_osfp_enlist *
pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp)
{
struct pf_os_fingerprint fp, *fpresult;
int cnt, optlen = 0;
const u_int8_t *optp;
#ifdef _KERNEL
char srcname[128];
#else
char srcname[NI_MAXHOST];
#endif
if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN)
return (NULL);
@ -164,49 +104,21 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
memset(&fp, 0, sizeof(fp));
if (ip) {
#ifndef _KERNEL
struct sockaddr_in sin;
#endif
fp.fp_psize = ntohs(ip->ip_len);
fp.fp_ttl = ip->ip_ttl;
if (ip->ip_off & htons(IP_DF))
fp.fp_flags |= PF_OSFP_DF;
#ifdef _KERNEL
strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
#else
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_addr = ip->ip_src;
(void)getnameinfo((struct sockaddr *)&sin,
sizeof(struct sockaddr_in), srcname, sizeof(srcname),
NULL, 0, NI_NUMERICHOST);
#endif
}
#ifdef INET6
else if (ip6) {
#ifndef _KERNEL
struct sockaddr_in6 sin6;
#endif
/* jumbo payload? */
fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
fp.fp_ttl = ip6->ip6_hlim;
fp.fp_flags |= PF_OSFP_DF;
fp.fp_flags |= PF_OSFP_INET6;
#ifdef _KERNEL
strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
sizeof(srcname));
#else
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_addr = ip6->ip6_src;
(void)getnameinfo((struct sockaddr *)&sin6,
sizeof(struct sockaddr_in6), srcname, sizeof(srcname),
NULL, 0, NI_NUMERICHOST);
#endif
}
#endif
else
@ -284,11 +196,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
(fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
fp.fp_wscale);
#ifdef __FreeBSD__
if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp,
#else
if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp,
#endif
PF_OSFP_MAXTTL_OFFSET)))
return (&fpresult->fp_oses);
return (NULL);
@ -324,52 +232,6 @@ pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os)
return (0);
}
/* Initialize the OS fingerprint system */
#ifdef __FreeBSD__
int
#else
void
#endif
pf_osfp_initialize(void)
{
#if defined(__FreeBSD__) && defined(_KERNEL)
int error = ENOMEM;
do {
pf_osfp_entry_pl = pf_osfp_pl = NULL;
UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen");
UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp");
error = 0;
} while(0);
SLIST_INIT(&V_pf_osfp_list);
#else
pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
"pfosfpen", &pool_allocator_nointr);
pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
"pfosfp", &pool_allocator_nointr);
SLIST_INIT(&pf_osfp_list);
#endif
#ifdef __FreeBSD__
#ifdef _KERNEL
return (error);
#else
return (0);
#endif
#endif
}
#if defined(__FreeBSD__) && (_KERNEL)
void
pf_osfp_cleanup(void)
{
UMA_DESTROY(pf_osfp_entry_pl);
UMA_DESTROY(pf_osfp_pl);
}
#endif
/* Flush the fingerprint list */
void
pf_osfp_flush(void)
@ -377,18 +239,13 @@ pf_osfp_flush(void)
struct pf_os_fingerprint *fp;
struct pf_osfp_entry *entry;
#ifdef __FreeBSD__
while ((fp = SLIST_FIRST(&V_pf_osfp_list))) {
SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next);
#else
while ((fp = SLIST_FIRST(&pf_osfp_list))) {
SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next);
#endif
while ((entry = SLIST_FIRST(&fp->fp_oses))) {
SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry);
pool_put(&pf_osfp_entry_pl, entry);
free(entry, M_PFOSFP);
}
pool_put(&pf_osfp_pl, fp);
free(fp, M_PFOSFP);
}
}
@ -400,6 +257,8 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
struct pf_os_fingerprint *fp, fpadd;
struct pf_osfp_entry *entry;
PF_RULES_WASSERT();
memset(&fpadd, 0, sizeof(fpadd));
fpadd.fp_tcpopts = fpioc->fp_tcpopts;
fpadd.fp_wsize = fpioc->fp_wsize;
@ -436,31 +295,18 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
fpioc->fp_os.fp_os);
#endif
#ifdef __FreeBSD__
if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) {
#else
if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) {
#endif
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os))
return (EEXIST);
}
if ((entry = pool_get(&pf_osfp_entry_pl,
#ifdef __FreeBSD__
PR_NOWAIT)) == NULL)
#else
PR_WAITOK|PR_LIMITFAIL)) == NULL)
#endif
if ((entry = malloc(sizeof(*entry), M_PFOSFP, M_NOWAIT))
== NULL)
return (ENOMEM);
} else {
if ((fp = pool_get(&pf_osfp_pl,
#ifdef __FreeBSD__
PR_NOWAIT)) == NULL)
#else
PR_WAITOK|PR_LIMITFAIL)) == NULL)
#endif
if ((fp = malloc(sizeof(*fp), M_PFOSFP, M_ZERO | M_NOWAIT))
== NULL)
return (ENOMEM);
memset(fp, 0, sizeof(*fp));
fp->fp_tcpopts = fpioc->fp_tcpopts;
fp->fp_wsize = fpioc->fp_wsize;
fp->fp_psize = fpioc->fp_psize;
@ -470,20 +316,12 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
fp->fp_wscale = fpioc->fp_wscale;
fp->fp_ttl = fpioc->fp_ttl;
SLIST_INIT(&fp->fp_oses);
if ((entry = pool_get(&pf_osfp_entry_pl,
#ifdef __FreeBSD__
PR_NOWAIT)) == NULL) {
#else
PR_WAITOK|PR_LIMITFAIL)) == NULL) {
#endif
pool_put(&pf_osfp_pl, fp);
if ((entry = malloc(sizeof(*entry), M_PFOSFP, M_NOWAIT))
== NULL) {
free(fp, M_PFOSFP);
return (ENOMEM);
}
#ifdef __FreeBSD__
pf_osfp_insert(&V_pf_osfp_list, fp);
#else
pf_osfp_insert(&pf_osfp_list, fp);
#endif
}
memcpy(entry, &fpioc->fp_os, sizeof(*entry));
@ -503,7 +341,7 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
/* Find a fingerprint in the list */
struct pf_os_fingerprint *
static struct pf_os_fingerprint *
pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
u_int8_t ttldiff)
{
@ -578,7 +416,7 @@ pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
}
/* Find an exact fingerprint in the list */
struct pf_os_fingerprint *
static struct pf_os_fingerprint *
pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find)
{
struct pf_os_fingerprint *f;
@ -599,7 +437,7 @@ pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find)
}
/* Insert a fingerprint into the list */
void
static void
pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins)
{
struct pf_os_fingerprint *f, *prev = NULL;
@ -625,11 +463,7 @@ pf_osfp_get(struct pf_osfp_ioctl *fpioc)
memset(fpioc, 0, sizeof(*fpioc));
#ifdef __FreeBSD__
SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) {
#else
SLIST_FOREACH(fp, &pf_osfp_list, fp_next) {
#endif
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
if (i++ == num) {
fpioc->fp_mss = fp->fp_mss;
@ -650,17 +484,14 @@ pf_osfp_get(struct pf_osfp_ioctl *fpioc)
}
#ifdef PFDEBUG
/* Validate that each signature is reachable */
struct pf_os_fingerprint *
static struct pf_os_fingerprint *
pf_osfp_validate(void)
{
struct pf_os_fingerprint *f, *f2, find;
#ifdef __FreeBSD__
SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) {
#else
SLIST_FOREACH(f, &pf_osfp_list, fp_next) {
#endif
memcpy(&find, f, sizeof(find));
/* We do a few MSS/th_win percolations to make things unique */
@ -672,11 +503,7 @@ pf_osfp_validate(void)
find.fp_wsize *= (find.fp_mss + 40);
else if (f->fp_flags & PF_OSFP_WSIZE_MOD)
find.fp_wsize *= 2;
#ifdef __FreeBSD__
if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) {
#else
if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) {
#endif
if (f2)
printf("Found \"%s %s %s\" instead of "
"\"%s %s %s\"\n",
@ -696,3 +523,4 @@ pf_osfp_validate(void)
}
return (NULL);
}
#endif /* PFDEBUG */

View File

@ -35,15 +35,14 @@
*
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <sys/param.h>
#include <sys/socket.h>
#ifdef _KERNEL
# include <sys/systm.h>
# include <sys/refcount.h>
#endif /* _KERNEL */
#include <sys/mbuf.h>
@ -61,20 +60,10 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#ifdef __FreeBSD__
#define DPFPRINTF(format, x...) \
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
printf(format , ##x)
#else
#define DPFPRINTF(format, x...) \
if (pf_status.debug >= PF_DEBUG_NOISY) \
printf(format , ##x)
#endif
#ifdef __FreeBSD__
#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
#else
#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
#endif
#define rs_free(x) free(x, M_TEMP)
#else
@ -96,24 +85,22 @@ __FBSDID("$FreeBSD$");
#endif /* PFDEBUG */
#endif /* _KERNEL */
#if defined(__FreeBSD__) && !defined(_KERNEL)
#undef V_pf_anchors
#define V_pf_anchors pf_anchors
#undef pf_main_ruleset
#define pf_main_ruleset pf_main_anchor.ruleset
#endif
#if defined(__FreeBSD__) && defined(_KERNEL)
#ifdef _KERNEL
VNET_DEFINE(struct pf_anchor_global, pf_anchors);
VNET_DEFINE(struct pf_anchor, pf_main_anchor);
#else
#else /* ! _KERNEL */
struct pf_anchor_global pf_anchors;
struct pf_anchor pf_main_anchor;
#endif
#undef V_pf_anchors
#define V_pf_anchors pf_anchors
#undef pf_main_ruleset
#define pf_main_ruleset pf_main_anchor.ruleset
#endif /* _KERNEL */
static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
static struct pf_anchor *pf_find_anchor(const char *);
RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
@ -169,7 +156,7 @@ pf_init_ruleset(struct pf_ruleset *ruleset)
}
}
struct pf_anchor *
static struct pf_anchor *
pf_find_anchor(const char *path)
{
struct pf_anchor *key, *found;
@ -178,11 +165,7 @@ pf_find_anchor(const char *path)
if (key == NULL)
return (NULL);
strlcpy(key->path, path, sizeof(key->path));
#ifdef __FreeBSD__
found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
#else
found = RB_FIND(pf_anchor_global, &pf_anchors, key);
#endif
rs_free(key);
return (found);
}
@ -208,11 +191,7 @@ pf_find_or_create_ruleset(const char *path)
{
char *p, *q, *r;
struct pf_ruleset *ruleset;
#ifdef __FreeBSD__
struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
#else
struct pf_anchor *anchor, *dup, *parent = NULL;
#endif
if (path[0] == 0)
return (&pf_main_ruleset);
@ -263,11 +242,7 @@ pf_find_or_create_ruleset(const char *path)
strlcat(anchor->path, "/", sizeof(anchor->path));
}
strlcat(anchor->path, anchor->name, sizeof(anchor->path));
#ifdef __FreeBSD__
if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
#else
if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
#endif
NULL) {
printf("pf_find_or_create_ruleset: RB_INSERT1 "
"'%s' '%s' collides with '%s' '%s'\n",
@ -284,11 +259,7 @@ pf_find_or_create_ruleset(const char *path)
"RB_INSERT2 '%s' '%s' collides with "
"'%s' '%s'\n", anchor->path, anchor->name,
dup->path, dup->name);
#ifdef __FreeBSD__
RB_REMOVE(pf_anchor_global, &V_pf_anchors,
#else
RB_REMOVE(pf_anchor_global, &pf_anchors,
#endif
anchor);
rs_free(anchor);
rs_free(p);
@ -324,11 +295,7 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
!TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
ruleset->rules[i].inactive.open)
return;
#ifdef __FreeBSD__
RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
#else
RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
#endif
if ((parent = ruleset->anchor->parent) != NULL)
RB_REMOVE(pf_anchor_node, &parent->children,
ruleset->anchor);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,8 @@
KMOD= pf
SRCS= pf.c pf_if.c pf_lb.c pf_osfp.c pf_ioctl.c pf_norm.c pf_table.c \
pf_ruleset.c \
in4_cksum.c \
pf_ruleset.c in4_cksum.c \
bus_if.h device_if.h \
opt_pf.h opt_inet.h opt_inet6.h opt_bpf.h opt_global.h
CFLAGS+= -I${.CURDIR}/../../contrib/pf
@ -33,7 +33,6 @@ opt_pf.h:
echo "#define DEV_PF 1" > ${.TARGET}
echo "#define DEV_PFLOG 1" >> ${.TARGET}
echo "#define DEV_PFSYNC 1" >> ${.TARGET}
echo "#define DEV_PFLOW 1" >> ${.TARGET}
.if defined(VIMAGE)
opt_global.h:

View File

@ -1084,6 +1084,7 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
struct ifg_list *ifgl;
struct ifg_group *ifg = NULL;
struct ifg_member *ifgm;
int new = 0;
if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' &&
groupname[strlen(groupname) - 1] <= '9')
@ -1124,8 +1125,8 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
ifg->ifg_refcnt = 0;
TAILQ_INIT(&ifg->ifg_members);
EVENTHANDLER_INVOKE(group_attach_event, ifg);
TAILQ_INSERT_TAIL(&V_ifg_head, ifg, ifg_next);
new = 1;
}
ifg->ifg_refcnt++;
@ -1139,6 +1140,8 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
IFNET_WUNLOCK();
if (new)
EVENTHANDLER_INVOKE(group_attach_event, ifg);
EVENTHANDLER_INVOKE(group_change_event, groupname);
return (0);
@ -1177,9 +1180,10 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
if (--ifgl->ifgl_group->ifg_refcnt == 0) {
TAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_next);
IFNET_WUNLOCK();
EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group);
free(ifgl->ifgl_group, M_TEMP);
}
} else
IFNET_WUNLOCK();
free(ifgl, M_TEMP);
@ -1221,10 +1225,11 @@ if_delgroups(struct ifnet *ifp)
if (--ifgl->ifgl_group->ifg_refcnt == 0) {
TAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_next);
IFNET_WUNLOCK();
EVENTHANDLER_INVOKE(group_detach_event,
ifgl->ifgl_group);
free(ifgl->ifgl_group, M_TEMP);
}
} else
IFNET_WUNLOCK();
free(ifgl, M_TEMP);

View File

@ -256,8 +256,6 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
#endif
}
m_addr_changed(m);
error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL);
if (!(GIF2IFP(sc)->if_flags & IFF_LINK0) &&

View File

@ -675,8 +675,6 @@ icmp_reflect(struct mbuf *m)
goto done; /* Ip_output() will check for broadcast */
}
m_addr_changed(m);
t = ip->ip_dst;
ip->ip_dst = ip->ip_src;

View File

@ -1698,20 +1698,30 @@ do { \
case O_ALTQ: {
struct pf_mtag *at;
struct m_tag *mtag;
ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
/*
* ALTQ uses mbuf tags from another
* packet filtering system - pf(4).
* We allocate a tag in its format
* and fill it in, pretending to be pf(4).
*/
match = 1;
at = pf_find_mtag(m);
if (at != NULL && at->qid != 0)
break;
at = pf_get_mtag(m);
if (at == NULL) {
mtag = m_tag_get(PACKET_TAG_PF,
sizeof(struct pf_mtag), M_NOWAIT | M_ZERO);
if (mtag == NULL) {
/*
* Let the packet fall back to the
* default ALTQ.
*/
break;
}
m_tag_prepend(m, mtag);
at = (struct pf_mtag *)(mtag + 1);
at->qid = altq->qid;
at->hdr = ip;
break;

View File

@ -100,9 +100,6 @@ void (*ip_divert_ptr)(struct mbuf *, int);
int (*ng_ipfw_input_p)(struct mbuf **, int,
struct ip_fw_args *, int);
/* Hook for telling pf that the destination address changed */
void (*m_addr_chg_pf_p)(struct mbuf *m);
#ifdef INET
/*
* Hooks for multicast routing. They all default to NULL, so leave them not

View File

@ -544,7 +544,6 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
m_freem(m->m_next);
m->m_next = NULL;
m->m_data = (caddr_t)ipgen;
m_addr_changed(m);
/* m_len is set later */
tlen = 0;
#define xchg(a,b,type) { type t; t=a; a=b; b=t; }

View File

@ -1177,8 +1177,6 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
ip6cp.ip6c_src = &icmp6src;
ip6cp.ip6c_nxt = nxt;
m_addr_changed(m);
if (icmp6type == ICMP6_PACKET_TOO_BIG) {
notifymtu = ntohl(icmp6->icmp6_mtu);
ip6cp.ip6c_cmdarg = (void *)&notifymtu;
@ -2298,8 +2296,6 @@ icmp6_reflect(struct mbuf *m, size_t off)
m->m_flags &= ~(M_BCAST|M_MCAST);
m_addr_changed(m);
ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
if (outif)
icmp6_ifoutstat_inc(outif, type, code);

View File

@ -264,8 +264,6 @@ in6_gif_output(struct ifnet *ifp,
#endif
}
m_addr_changed(m);
#ifdef IPV6_MINMTU
/*
* force fragmentation to minimum MTU, to avoid path MTU discovery.

View File

@ -473,8 +473,6 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
key_sa_recordxfer(sav, m); /* record data transfer */
m_addr_changed(m);
#ifdef DEV_ENC
encif->if_ipackets++;
encif->if_ibytes += m->m_pkthdr.len;

View File

@ -190,8 +190,6 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
}
key_sa_recordxfer(sav, m); /* record data transfer */
m_addr_changed(m);
/*
* We're done with IPsec processing, transmit the packet using the
* appropriate network protocol (IP or IPv6). SPD lookup will be

View File

@ -392,8 +392,6 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
panic("%s: bogus ip version %u", __func__, v>>4);
}
m_addr_changed(m);
if (netisr_queue(isr, m)) { /* (0) on success. */
V_ipipstat.ipips_qfull++;
DPRINTF(("%s: packet dropped because of full queue\n",

View File

@ -749,16 +749,6 @@ m_last(struct mbuf *m)
return (m);
}
extern void (*m_addr_chg_pf_p)(struct mbuf *m);
static __inline void
m_addr_changed(struct mbuf *m)
{
if (m_addr_chg_pf_p)
m_addr_chg_pf_p(m);
}
/*
* mbuf, cluster, and external object allocation macros (for compatibility
* purposes).
@ -998,7 +988,7 @@ struct mbuf *m_unshare(struct mbuf *, int how);
#define PACKET_TAG_DIVERT 17 /* divert info */
#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
#define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */
#define PACKET_TAG_PF 21 /* PF + ALTQ information */
#define PACKET_TAG_PF (21 | MTAG_PERSISTENT) /* PF/ALTQ information */
#define PACKET_TAG_RTSOCKFAM 25 /* rtsock sa family */
#define PACKET_TAG_IPOPTIONS 27 /* Saved IP options */
#define PACKET_TAG_CARP 28 /* CARP info */

View File

@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1000017 /* Master, propagated to newvers */
#define __FreeBSD_version 1000018 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -81,6 +81,32 @@ static void catchalarm(int);
static char addr_buf[NI_MAXHOST]; /* for getnameinfo() */
#endif
static const char* pfsyncacts[] = {
/* PFSYNC_ACT_CLR */ "clear all request",
/* PFSYNC_ACT_INS */ "state insert",
/* PFSYNC_ACT_INS_ACK */ "state inserted ack",
/* PFSYNC_ACT_UPD */ "state update",
/* PFSYNC_ACT_UPD_C */ "compressed state update",
/* PFSYNC_ACT_UPD_REQ */ "uncompressed state request",
/* PFSYNC_ACT_DEL */ "state delete",
/* PFSYNC_ACT_DEL_C */ "compressed state delete",
/* PFSYNC_ACT_INS_F */ "fragment insert",
/* PFSYNC_ACT_DEL_F */ "fragment delete",
/* PFSYNC_ACT_BUS */ "bulk update mark",
/* PFSYNC_ACT_TDB */ "TDB replay counter update",
/* PFSYNC_ACT_EOF */ "end of frame mark",
};
static void
pfsync_acts_stats(const char *fmt, uint64_t *a)
{
int i;
for (i = 0; i < PFSYNC_ACT_MAX; i++, a++)
if (*a || sflag <= 1)
printf(fmt, *a, pfsyncacts[i], plural(*a));
}
/*
* Dump pfsync statistics structure.
*/
@ -106,11 +132,11 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
#define p(f, m) if (pfsyncstat.f || sflag <= 1) \
printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f))
#define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
printf(m, (uintmax_t)pfsyncstat.f)
p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n");
p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n");
pfsync_acts_stats("\t %ju %s%s received\n",
&pfsyncstat.pfsyncs_iacts[0]);
p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n");
p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n");
p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n");
@ -123,10 +149,11 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n");
p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n");
p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n");
p2(pfsyncs_onomem, "\t\t%ju send failed due to mbuf memory error\n");
p2(pfsyncs_oerrors, "\t\t%ju send error\n");
pfsync_acts_stats("\t %ju %s%s sent\n",
&pfsyncstat.pfsyncs_oacts[0]);
p(pfsyncs_onomem, "\t\t%ju failure%s due to mbuf memory error\n");
p(pfsyncs_oerrors, "\t\t%ju send error%s\n");
#undef p
#undef p2
}
/*

View File

@ -585,7 +585,7 @@ PfInterfacesIfEntry ::= SEQUENCE {
pfInterfacesIfDescr OCTET STRING,
pfInterfacesIfType INTEGER,
pfInterfacesIfTZero TimeTicks,
pfInterfacesIfRefsState Unsigned32,
pfInterfacesIfRefsState Null,
pfInterfacesIfRefsRule Unsigned32,
pfInterfacesIf4BytesInPass Counter64,
pfInterfacesIf4BytesInBlock Counter64,

View File

@ -586,11 +586,8 @@ pf_iftable(struct snmp_context __unused *ctx, struct snmp_value *val,
val->v.uint32 =
(time(NULL) - e->pfi.pfik_tzero) * 100;
break;
case LEAF_pfInterfacesIfRefsState:
val->v.uint32 = e->pfi.pfik_states;
break;
case LEAF_pfInterfacesIfRefsRule:
val->v.uint32 = e->pfi.pfik_rules;
val->v.uint32 = e->pfi.pfik_rulerefs;
break;
case LEAF_pfInterfacesIf4BytesInPass:
val->v.counter64 =

View File

@ -108,7 +108,7 @@
(2 pfInterfacesIfDescr OCTETSTRING GET)
(3 pfInterfacesIfType ENUM ( 0 group 1 instance 2 detached ) GET)
(4 pfInterfacesIfTZero TIMETICKS GET)
(5 pfInterfacesIfRefsState UNSIGNED32 GET)
(5 pfInterfacesIfRefsState NULL GET)
(6 pfInterfacesIfRefsRule UNSIGNED32 GET)
(7 pfInterfacesIf4BytesInPass COUNTER64 GET)
(8 pfInterfacesIf4BytesInBlock COUNTER64 GET)