pf: Introduce ridentifier
Allow users to set a number on rules which will be exposed as part of the pflog header. The intent behind this is to allow users to correlate rules across updates (remember that pf rules continue to exist and match existing states, even if they're removed from the active ruleset) and pflog. Obtained from: pfSense MFC after: 3 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D32750
This commit is contained in:
parent
80e5955b08
commit
76c5eecc34
@ -88,10 +88,12 @@ static const struct tok pf_directions[] = {
|
||||
static void
|
||||
pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
|
||||
{
|
||||
uint32_t rulenr, subrulenr;
|
||||
uint32_t rulenr, subrulenr, ridentifier;
|
||||
|
||||
rulenr = EXTRACT_32BITS(&hdr->rulenr);
|
||||
subrulenr = EXTRACT_32BITS(&hdr->subrulenr);
|
||||
ridentifier = EXTRACT_32BITS(&hdr->ridentifier);
|
||||
|
||||
if (subrulenr == (uint32_t)-1)
|
||||
ND_PRINT((ndo, "rule %u/", rulenr));
|
||||
else
|
||||
@ -102,6 +104,9 @@ pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
|
||||
if (hdr->uid != UID_MAX)
|
||||
ND_PRINT((ndo, " [uid %u]", (unsigned)hdr->uid));
|
||||
|
||||
if (ridentifier != 0)
|
||||
ND_PRINT((ndo, " [ridentifier %u]", ridentifier));
|
||||
|
||||
ND_PRINT((ndo, ": %s %s on %s: ",
|
||||
tok2str(pf_actions, "unkn(%u)", hdr->action),
|
||||
tok2str(pf_directions, "unkn(%u)", hdr->dir),
|
||||
|
@ -455,6 +455,7 @@ pf_nvrule_to_rule(const nvlist_t *nvl, struct pfctl_rule *rule)
|
||||
assert(labelcount <= PF_RULE_MAX_LABEL_COUNT);
|
||||
for (size_t i = 0; i < labelcount; i++)
|
||||
strlcpy(rule->label[i], labels[i], PF_RULE_LABEL_SIZE);
|
||||
rule->ridentifier = nvlist_get_number(nvl, "ridentifier");
|
||||
strlcpy(rule->ifname, nvlist_get_string(nvl, "ifname"), IFNAMSIZ);
|
||||
strlcpy(rule->qname, nvlist_get_string(nvl, "qname"), PF_QNAME_SIZE);
|
||||
strlcpy(rule->pqname, nvlist_get_string(nvl, "pqname"), PF_QNAME_SIZE);
|
||||
@ -569,6 +570,7 @@ pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor,
|
||||
r->label[labelcount]);
|
||||
labelcount++;
|
||||
}
|
||||
nvlist_add_number(nvlr, "ridentifier", r->ridentifier);
|
||||
|
||||
nvlist_add_string(nvlr, "ifname", r->ifname);
|
||||
nvlist_add_string(nvlr, "qname", r->qname);
|
||||
|
@ -81,6 +81,7 @@ struct pfctl_rule {
|
||||
struct pf_rule_addr dst;
|
||||
union pf_rule_ptr skip[PF_SKIP_COUNT];
|
||||
char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
|
||||
u_int32_t ridentifier;
|
||||
char ifname[IFNAMSIZ];
|
||||
char qname[PF_QNAME_SIZE];
|
||||
char pqname[PF_QNAME_SIZE];
|
||||
|
@ -236,6 +236,7 @@ static struct filter_opts {
|
||||
struct node_icmp *icmpspec;
|
||||
u_int32_t tos;
|
||||
u_int32_t prob;
|
||||
u_int32_t ridentifier;
|
||||
struct {
|
||||
int action;
|
||||
struct node_state_opt *options;
|
||||
@ -263,6 +264,7 @@ static struct filter_opts {
|
||||
static struct antispoof_opts {
|
||||
char *label[PF_RULE_MAX_LABEL_COUNT];
|
||||
int labelcount;
|
||||
u_int32_t ridentifier;
|
||||
u_int rtableid;
|
||||
} antispoof_opts;
|
||||
|
||||
@ -471,7 +473,7 @@ int parseport(char *, struct range *r, int);
|
||||
%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY MAPEPORTSET
|
||||
%token ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME
|
||||
%token UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL
|
||||
%token DNPIPE DNQUEUE
|
||||
%token DNPIPE DNQUEUE RIDENTIFIER
|
||||
%token LOAD RULESET_OPTIMIZATION PRIO
|
||||
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
|
||||
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
|
||||
@ -927,6 +929,7 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
|
||||
r.af = $6;
|
||||
r.prob = $9.prob;
|
||||
r.rtableid = $9.rtableid;
|
||||
r.ridentifier = $9.ridentifier;
|
||||
|
||||
if ($9.tag)
|
||||
if (strlcpy(r.tagname, $9.tag,
|
||||
@ -1326,6 +1329,7 @@ antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
|
||||
r.logif = $2.logif;
|
||||
r.quick = $2.quick;
|
||||
r.af = $4;
|
||||
r.ridentifier = $5.ridentifier;
|
||||
if (rule_label(&r, $5.label))
|
||||
YYERROR;
|
||||
r.rtableid = $5.rtableid;
|
||||
@ -1378,6 +1382,7 @@ antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
|
||||
r.logif = $2.logif;
|
||||
r.quick = $2.quick;
|
||||
r.af = $4;
|
||||
r.ridentifier = $5.ridentifier;
|
||||
if (rule_label(&r, $5.label))
|
||||
YYERROR;
|
||||
r.rtableid = $5.rtableid;
|
||||
@ -1440,6 +1445,9 @@ antispoof_opt : label {
|
||||
}
|
||||
antispoof_opts.label[antispoof_opts.labelcount++] = $1;
|
||||
}
|
||||
| RIDENTIFIER number {
|
||||
antispoof_opts.ridentifier = $2;
|
||||
}
|
||||
| RTABLE NUMBER {
|
||||
if ($2 < 0 || $2 > rt_tableid_max()) {
|
||||
yyerror("invalid rtable id");
|
||||
@ -2155,6 +2163,7 @@ pfrule : action dir logquick interface route af proto fromto
|
||||
YYERROR;
|
||||
for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
|
||||
free($9.label[i]);
|
||||
r.ridentifier = $9.ridentifier;
|
||||
r.flags = $9.flags.b1;
|
||||
r.flagset = $9.flags.b2;
|
||||
if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
|
||||
@ -2594,6 +2603,9 @@ filter_opt : USER uids {
|
||||
filter_opts.keep.action = $1.action;
|
||||
filter_opts.keep.options = $1.options;
|
||||
}
|
||||
| RIDENTIFIER number {
|
||||
filter_opts.ridentifier = $2;
|
||||
}
|
||||
| FRAGMENT {
|
||||
filter_opts.fragment = 1;
|
||||
}
|
||||
@ -5736,6 +5748,7 @@ lookup(char *s)
|
||||
{ "return-icmp", RETURNICMP},
|
||||
{ "return-icmp6", RETURNICMP6},
|
||||
{ "return-rst", RETURNRST},
|
||||
{ "ridentifier", RIDENTIFIER},
|
||||
{ "round-robin", ROUNDROBIN},
|
||||
{ "route", ROUTE},
|
||||
{ "route-to", ROUTETO},
|
||||
|
@ -1019,6 +1019,8 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer
|
||||
i = 0;
|
||||
while (r->label[i][0])
|
||||
printf(" label \"%s\"", r->label[i++]);
|
||||
if (r->ridentifier)
|
||||
printf(" ridentifier %u", r->ridentifier);
|
||||
/* Only dnrpipe as we might do (0, 42) to only queue return traffic. */
|
||||
if (r->dnrpipe)
|
||||
printf(" %s(%d, %d)",
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 18, 2019
|
||||
.Dd October 29, 2021
|
||||
.Dt PFLOG 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -84,6 +84,7 @@ struct pfloghdr {
|
||||
pid_t rule_pid;
|
||||
u_int8_t dir;
|
||||
u_int8_t pad[3];
|
||||
u_int32_t ridentifier;
|
||||
};
|
||||
.Ed
|
||||
.Sh EXAMPLES
|
||||
|
@ -1896,6 +1896,9 @@ pass in inet proto tcp from any to 1.2.3.5 \e
|
||||
The macro expansion for the
|
||||
.Ar label
|
||||
directive occurs only at configuration file parse time, not during runtime.
|
||||
.It Ar ridentifier Aq Ar number
|
||||
Add an identifier (number) to the rule, which can be used to correlate the rule
|
||||
to pflog entries, even after ruleset updates.
|
||||
.It Xo Ar queue Aq Ar queue
|
||||
.No \*(Ba ( Aq Ar queue ,
|
||||
.Aq Ar queue )
|
||||
@ -3000,7 +3003,8 @@ filteropt = user | group | flags | icmp-type | icmp6-type | "tos" tos |
|
||||
"queue" ( string | "(" string [ [ "," ] string ] ")" ) |
|
||||
"rtable" number | "probability" number"%" | "prio" number |
|
||||
"dnpipe" ( number | "(" number "," number ")" ) |
|
||||
"dnqueue" ( number | "(" number "," number ")" )
|
||||
"dnqueue" ( number | "(" number "," number ")" ) |
|
||||
"ridentifier" number
|
||||
|
||||
nat-rule = [ "no" ] "nat" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
|
||||
[ "on" ifspec ] [ af ]
|
||||
@ -3024,6 +3028,7 @@ rdr-rule = [ "no" ] "rdr" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
|
||||
|
||||
antispoof-rule = "antispoof" [ "log" ] [ "quick" ]
|
||||
"for" ifspec [ af ] [ "label" string ]
|
||||
[ "ridentifier" number ]
|
||||
|
||||
table-rule = "table" "\*(Lt" string "\*(Gt" [ tableopts-list ]
|
||||
tableopts-list = tableopts-list tableopts | tableopts
|
||||
|
@ -50,6 +50,7 @@ struct pfloghdr {
|
||||
pid_t rule_pid;
|
||||
u_int8_t dir;
|
||||
u_int8_t pad[3];
|
||||
u_int32_t ridentifier;
|
||||
};
|
||||
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
|
@ -578,6 +578,7 @@ struct pf_krule {
|
||||
struct pf_rule_addr dst;
|
||||
union pf_krule_ptr skip[PF_SKIP_COUNT];
|
||||
char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
|
||||
uint32_t ridentifier;
|
||||
char ifname[IFNAMSIZ];
|
||||
char qname[PF_QNAME_SIZE];
|
||||
char pqname[PF_QNAME_SIZE];
|
||||
|
@ -71,7 +71,7 @@ nat64clat_log(struct pfloghdr *plog, struct mbuf *m, sa_family_t family,
|
||||
static uint32_t pktid = 0;
|
||||
|
||||
memset(plog, 0, sizeof(*plog));
|
||||
plog->length = PFLOG_REAL_HDRLEN;
|
||||
plog->length = PFLOG_HDRLEN;
|
||||
plog->af = family;
|
||||
plog->action = PF_NAT;
|
||||
plog->dir = PF_IN;
|
||||
|
@ -181,7 +181,7 @@ nat64lsn_log(struct pfloghdr *plog, struct mbuf *m, sa_family_t family,
|
||||
{
|
||||
|
||||
memset(plog, 0, sizeof(*plog));
|
||||
plog->length = PFLOG_REAL_HDRLEN;
|
||||
plog->length = PFLOG_HDRLEN;
|
||||
plog->af = family;
|
||||
plog->action = PF_NAT;
|
||||
plog->dir = PF_IN;
|
||||
|
@ -70,7 +70,7 @@ nat64stl_log(struct pfloghdr *plog, struct mbuf *m, sa_family_t family,
|
||||
static uint32_t pktid = 0;
|
||||
|
||||
memset(plog, 0, sizeof(*plog));
|
||||
plog->length = PFLOG_REAL_HDRLEN;
|
||||
plog->length = PFLOG_HDRLEN;
|
||||
plog->af = family;
|
||||
plog->action = PF_NAT;
|
||||
plog->dir = PF_IN;
|
||||
|
@ -215,7 +215,7 @@ pflog_packet(struct pfi_kkif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
return (0);
|
||||
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
hdr.length = PFLOG_REAL_HDRLEN;
|
||||
hdr.length = PFLOG_HDRLEN;
|
||||
hdr.af = af;
|
||||
hdr.action = rm->action;
|
||||
hdr.reason = reason;
|
||||
@ -231,6 +231,7 @@ pflog_packet(struct pfi_kkif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
strlcpy(hdr.ruleset, ruleset->anchor->name,
|
||||
sizeof(hdr.ruleset));
|
||||
}
|
||||
hdr.ridentifier = htonl(rm->ridentifier);
|
||||
/*
|
||||
* XXXGL: we avoid pf_socket_lookup() when we are holding
|
||||
* state lock, since this leads to unsafe LOR.
|
||||
|
@ -531,6 +531,7 @@ pf_nvrule_to_krule(const nvlist_t *nvl, struct pf_krule *rule)
|
||||
}
|
||||
}
|
||||
|
||||
PFNV_CHK(pf_nvuint32_opt(nvl, "ridentifier", &rule->ridentifier, 0));
|
||||
PFNV_CHK(pf_nvstring(nvl, "ifname", rule->ifname,
|
||||
sizeof(rule->ifname)));
|
||||
PFNV_CHK(pf_nvstring(nvl, "qname", rule->qname, sizeof(rule->qname)));
|
||||
@ -696,6 +697,7 @@ pf_krule_to_nvrule(struct pf_krule *rule)
|
||||
nvlist_append_string_array(nvl, "labels", rule->label[i]);
|
||||
}
|
||||
nvlist_add_string(nvl, "label", rule->label[0]);
|
||||
nvlist_add_number(nvl, "ridentifier", rule->ridentifier);
|
||||
nvlist_add_string(nvl, "ifname", rule->ifname);
|
||||
nvlist_add_string(nvl, "qname", rule->qname);
|
||||
nvlist_add_string(nvl, "pqname", rule->pqname);
|
||||
|
Loading…
x
Reference in New Issue
Block a user