Page MenuHomeFreeBSD

D43108.id132818.diff
No OneTemporary

D43108.id132818.diff

diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -172,7 +172,8 @@
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_TIMEOUT, PF_STATE_OPT_SLOPPY,
+ PF_STATE_OPT_PFLOW };
enum { PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
@@ -512,7 +513,7 @@
%token DNPIPE DNQUEUE RIDENTIFIER
%token LOAD RULESET_OPTIMIZATION PRIO
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
-%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
+%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
%token DIVERTTO DIVERTREPLY BRIDGE_TO
%token <v.string> STRING
@@ -2615,6 +2616,14 @@
}
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 ||
@@ -4368,6 +4377,14 @@
$$->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;
@@ -6318,6 +6335,7 @@
{ "out", OUT},
{ "overload", OVERLOAD},
{ "pass", PASS},
+ { "pflow", PFLOW},
{ "port", PORT},
{ "prio", PRIO},
{ "priority", PRIORITY},
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -376,6 +376,8 @@
printf(", sloppy");
if (s->state_flags & PFSTATE_NOSYNC)
printf(", no-sync");
+ if (s->state_flags & PFSTATE_PFLOW)
+ printf(", pflow");
if (s->state_flags & PFSTATE_ACK)
printf(", psync-ack");
if (s->state_flags & PFSTATE_NODF)
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1051,6 +1051,8 @@
opts = 1;
if (r->rule_flag & PFRULE_STATESLOPPY)
opts = 1;
+ if (r->rule_flag & PFRULE_PFLOW)
+ opts = 1;
for (i = 0; !opts && i < PFTM_MAX; ++i)
if (r->timeout[i])
opts = 1;
@@ -1123,6 +1125,12 @@
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;
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -27,7 +27,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd November 17, 2023
+.Dd December 6, 2023
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -2429,6 +2429,10 @@
This is intended to be used in situations where one does not see all
packets of a connection, e.g. in asymmetric routing situations.
Cannot be used with modulate or synproxy state.
+.It Ar pflow
+States created by this rule are exported on the
+.Xr pflow 4
+interface.
.El
.Pp
Multiple options can be specified, separated by commas:
@@ -3345,7 +3349,7 @@
"max-src-conn" number |
"max-src-conn-rate" number "/" number |
"overload" "\*(Lt" string "\*(Gt" [ "flush" ] |
- "if-bound" | "floating" )
+ "if-bound" | "floating" | "pflow" )
fragmentation = [ "fragment reassemble" ]
@@ -3406,6 +3410,7 @@
.Xr ip 4 ,
.Xr ip6 4 ,
.Xr pf 4 ,
+.Xr pflow 4 ,
.Xr pfsync 4 ,
.Xr tcp 4 ,
.Xr sctp 4 ,
diff --git a/sys/net/pflow.h b/sys/net/pflow.h
--- a/sys/net/pflow.h
+++ b/sys/net/pflow.h
@@ -326,7 +326,6 @@
};
#ifdef _KERNEL
-int export_pflow(struct pf_kstate *);
int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
#endif /* _KERNEL */
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1186,6 +1186,7 @@
typedef void pfsync_clear_states_t(u_int32_t, const char *);
typedef int pfsync_defer_t(struct pf_kstate *, struct mbuf *);
typedef void pfsync_detach_ifnet_t(struct ifnet *);
+typedef void pflow_export_state_t(const struct pf_kstate *);
VNET_DECLARE(pfsync_state_import_t *, pfsync_state_import_ptr);
#define V_pfsync_state_import_ptr VNET(pfsync_state_import_ptr)
@@ -1199,6 +1200,8 @@
#define V_pfsync_clear_states_ptr VNET(pfsync_clear_states_ptr)
VNET_DECLARE(pfsync_defer_t *, pfsync_defer_ptr);
#define V_pfsync_defer_ptr VNET(pfsync_defer_ptr)
+VNET_DECLARE(pflow_export_state_t *, pflow_export_state_ptr);
+#define V_pflow_export_state_ptr VNET(pflow_export_state_ptr)
extern pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
void pfsync_state_export(union pfsync_state_union *,
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -614,6 +614,7 @@
#define PFRULE_SET_TOS 0x00002000
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
+#define PFRULE_PFLOW 0x00040000
#ifdef _KERNEL
#define PFRULE_REFS 0x0080 /* rule has references */
@@ -626,7 +627,7 @@
/* pf_state->state_flags, pf_rule_actions->flags, pf_krule->scrub_flags */
#define PFSTATE_ALLOWOPTS 0x0001
#define PFSTATE_SLOPPY 0x0002
-/* was PFSTATE_PFLOW 0x0004 */
+#define PFSTATE_PFLOW 0x0004
#define PFSTATE_NOSYNC 0x0008
#define PFSTATE_ACK 0x0010
#define PFSTATE_NODF 0x0020
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -1397,6 +1397,9 @@
pf_sctp_multihome_detach_addr(s);
+ if ((s->state_flags & PFSTATE_PFLOW) && V_pflow_export_state_ptr)
+ V_pflow_export_state_ptr(s);
+
if (sks != NULL) {
kh = &V_pf_keyhash[pf_hashkey(sks)];
PF_HASHROW_LOCK(kh);
@@ -4872,6 +4875,8 @@
s->state_flags |= PFSTATE_SLOPPY;
if (pd->flags & PFDESC_TCP_NORM) /* Set by old-style scrub rules */
s->state_flags |= PFSTATE_SCRUB_TCP;
+ if (r->rule_flag & PFRULE_PFLOW)
+ s->state_flags |= PFSTATE_PFLOW;
s->act.log = pd->act.log & PF_LOG_ALL;
s->sync_state = PFSYNC_S_NONE;
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -304,6 +304,7 @@
VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
+VNET_DEFINE(pflow_export_state_t *, pflow_export_state_ptr);
pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
/* pflog */
diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c
--- a/sys/netpfil/pf/pflow.c
+++ b/sys/netpfil/pf/pflow.c
@@ -87,18 +87,19 @@
static void pflow_timeout6(void *);
static void pflow_timeout_tmpl(void *);
static void copy_flow_data(struct pflow_flow *, struct pflow_flow *,
- struct pf_kstate *, struct pf_state_key *, int, int);
+ const struct pf_kstate *, struct pf_state_key *, int, int);
static void copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
- struct pflow_ipfix_flow4 *, struct pf_kstate *, struct pf_state_key *,
+ struct pflow_ipfix_flow4 *, const struct pf_kstate *, struct pf_state_key *,
struct pflow_softc *, int, int);
static void copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
- struct pflow_ipfix_flow6 *, struct pf_kstate *, struct pf_state_key *,
+ struct pflow_ipfix_flow6 *, const struct pf_kstate *, struct pf_state_key *,
struct pflow_softc *, int, int);
-static int pflow_pack_flow(struct pf_kstate *, struct pf_state_key *,
+static int pflow_pack_flow(const struct pf_kstate *, struct pf_state_key *,
struct pflow_softc *);
-static int pflow_pack_flow_ipfix(struct pf_kstate *, struct pf_state_key *,
+static int pflow_pack_flow_ipfix(const struct pf_kstate *, struct pf_state_key *,
struct pflow_softc *);
-static int export_pflow_if(struct pf_kstate*, struct pf_state_key *,
+static void export_pflow(const struct pf_kstate *);
+static int export_pflow_if(const struct pf_kstate*, struct pf_state_key *,
struct pflow_softc *);
static int copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
static int copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
@@ -323,6 +324,8 @@
CK_LIST_INSERT_HEAD(&V_pflowif_list, pflowif, sc_next);
mtx_unlock(&V_pflowif_list_mtx);
+ V_pflow_export_state_ptr = export_pflow;
+
return (0);
}
@@ -352,6 +355,8 @@
return (ENOENT);
}
CK_LIST_REMOVE(sc, sc_next);
+ if (CK_LIST_EMPTY(&V_pflowif_list))
+ V_pflow_export_state_ptr = NULL;
mtx_unlock(&V_pflowif_list_mtx);
sc->sc_dying = 1;
@@ -511,7 +516,7 @@
static void
copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
- struct pf_kstate *st, struct pf_state_key *sk, int src, int dst)
+ const struct pf_kstate *st, struct pf_state_key *sk, int src, int dst)
{
flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
flow1->src_port = flow2->dest_port = sk->port[src];
@@ -548,7 +553,7 @@
static void
copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
- struct pflow_ipfix_flow4 *flow2, struct pf_kstate *st,
+ struct pflow_ipfix_flow4 *flow2, const struct pf_kstate *st,
struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
{
flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
@@ -585,7 +590,7 @@
static void
copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
- struct pflow_ipfix_flow6 *flow2, struct pf_kstate *st,
+ struct pflow_ipfix_flow6 *flow2, const struct pf_kstate *st,
struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
{
bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
@@ -622,8 +627,8 @@
flow1->tos = flow2->tos = st->rule.ptr->tos;
}
-int
-export_pflow(struct pf_kstate *st)
+static void
+export_pflow(const struct pf_kstate *st)
{
struct pflow_softc *sc = NULL;
struct pf_state_key *sk;
@@ -648,12 +653,10 @@
}
PFLOW_UNLOCK(sc);
}
-
- return (0);
}
static int
-export_pflow_if(struct pf_kstate *st, struct pf_state_key *sk,
+export_pflow_if(const struct pf_kstate *st, struct pf_state_key *sk,
struct pflow_softc *sc)
{
struct pf_kstate pfs_copy;
@@ -787,7 +790,7 @@
}
static int
-pflow_pack_flow(struct pf_kstate *st, struct pf_state_key *sk,
+pflow_pack_flow(const struct pf_kstate *st, struct pf_state_key *sk,
struct pflow_softc *sc)
{
struct pflow_flow flow1;
@@ -812,7 +815,7 @@
}
static int
-pflow_pack_flow_ipfix(struct pf_kstate *st, struct pf_state_key *sk,
+pflow_pack_flow_ipfix(const struct pf_kstate *st, struct pf_state_key *sk,
struct pflow_softc *sc)
{
struct pflow_ipfix_flow4 flow4_1, flow4_2;

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 11, 3:11 PM (20 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15754948
Default Alt Text
D43108.id132818.diff (10 KB)

Event Timeline