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:
parent
fb40c86f7f
commit
5190d38ee3
4
UPDATING
4
UPDATING
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $ */
|
||||
/*
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
@ -20,7 +20,7 @@
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
@ -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__
|
||||
struct route *);
|
||||
#else
|
||||
struct rtentry *);
|
||||
#endif
|
||||
int pflogioctl(struct ifnet *, u_long, caddr_t);
|
||||
void pflogstart(struct ifnet *);
|
||||
#ifdef __FreeBSD__
|
||||
static int pflog_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void pflog_clone_destroy(struct ifnet *);
|
||||
#else
|
||||
int pflog_clone_create(struct if_clone *, int);
|
||||
int pflog_clone_destroy(struct ifnet *);
|
||||
#endif
|
||||
static int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct route *);
|
||||
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 *);
|
||||
|
||||
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
|
||||
*/
|
||||
; /* empty */
|
||||
#else
|
||||
pd->lookup.done = pf_socket_lookup(dir, pd);
|
||||
#endif
|
||||
if (pd->lookup.done > 0) {
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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.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__ */
|
||||
|
@ -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_ */
|
||||
|
@ -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
@ -182,7 +182,7 @@ struct pfsync_del_c {
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
/*
|
||||
* INS_F, DEL_F
|
||||
*/
|
||||
|
||||
@ -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
@ -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;
|
||||
@ -594,15 +479,12 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
|
||||
PF_ACPY(init_addr, naddr, af);
|
||||
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,157 +523,141 @@ 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 (r == NULL)
|
||||
return (NULL);
|
||||
|
||||
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];
|
||||
|
||||
switch (r->action) {
|
||||
case PF_NONAT:
|
||||
case PF_NOBINAT:
|
||||
case PF_NORDR:
|
||||
return (NULL);
|
||||
case PF_NAT:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case PF_BINAT:
|
||||
switch (direction) {
|
||||
case PF_OUT:
|
||||
if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
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);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
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);
|
||||
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);
|
||||
PF_POOLMASK(naddr,
|
||||
&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);
|
||||
PF_POOLMASK(naddr,
|
||||
&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);
|
||||
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);
|
||||
|
||||
if (r->rpool.proxy_port[1]) {
|
||||
u_int32_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];
|
||||
|
||||
/* wrap around if necessary */
|
||||
if (tmp_nport > 65535)
|
||||
tmp_nport -= 65535;
|
||||
*nport = htons((u_int16_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);
|
||||
}
|
||||
switch (r->action) {
|
||||
case PF_NONAT:
|
||||
case PF_NOBINAT:
|
||||
case PF_NORDR:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
*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],
|
||||
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]));
|
||||
goto notrans;
|
||||
}
|
||||
break;
|
||||
case PF_BINAT:
|
||||
switch (direction) {
|
||||
case PF_OUT:
|
||||
if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
goto notrans;
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_mask4, saddr, AF_INET);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt6 < 1)
|
||||
goto notrans;
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
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);
|
||||
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)
|
||||
goto notrans;
|
||||
PF_POOLMASK(naddr,
|
||||
&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)
|
||||
goto notrans;
|
||||
PF_POOLMASK(naddr,
|
||||
&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);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PF_RDR: {
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
|
||||
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]) {
|
||||
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];
|
||||
|
||||
/* Wrap around if necessary. */
|
||||
if (tmp_nport > 65535)
|
||||
tmp_nport -= 65535;
|
||||
*nport = htons((uint16_t)tmp_nport);
|
||||
} else if (r->rpool.proxy_port[0])
|
||||
*nport = htons(r->rpool.proxy_port[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
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);
|
||||
}
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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
@ -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:
|
||||
|
15
sys/net/if.c
15
sys/net/if.c
@ -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,10 +1180,11 @@ 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);
|
||||
}
|
||||
IFNET_WUNLOCK();
|
||||
} else
|
||||
IFNET_WUNLOCK();
|
||||
|
||||
free(ifgl, M_TEMP);
|
||||
|
||||
@ -1221,11 +1225,12 @@ 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);
|
||||
}
|
||||
IFNET_WUNLOCK();
|
||||
} else
|
||||
IFNET_WUNLOCK();
|
||||
|
||||
free(ifgl, M_TEMP);
|
||||
|
||||
|
@ -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) &&
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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 *)¬ifymtu;
|
||||
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -585,7 +585,7 @@ PfInterfacesIfEntry ::= SEQUENCE {
|
||||
pfInterfacesIfDescr OCTET STRING,
|
||||
pfInterfacesIfType INTEGER,
|
||||
pfInterfacesIfTZero TimeTicks,
|
||||
pfInterfacesIfRefsState Unsigned32,
|
||||
pfInterfacesIfRefsState Null,
|
||||
pfInterfacesIfRefsRule Unsigned32,
|
||||
pfInterfacesIf4BytesInPass Counter64,
|
||||
pfInterfacesIf4BytesInBlock Counter64,
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user