Page MenuHomeFreeBSD

D29780.id87499.diff
No OneTemporary

D29780.id87499.diff

Index: lib/libpfctl/libpfctl.h
===================================================================
--- lib/libpfctl/libpfctl.h
+++ lib/libpfctl/libpfctl.h
@@ -190,5 +190,6 @@
const char *anchor, const char *anchor_call, u_int32_t ticket,
u_int32_t pool_ticket);
int pfctl_kill_schedule(int dev, const char *sched, int *killed);
+int pfctl_set_keepcounters(int dev, bool keep);
#endif
Index: lib/libpfctl/libpfctl.c
===================================================================
--- lib/libpfctl/libpfctl.c
+++ lib/libpfctl/libpfctl.c
@@ -610,3 +610,25 @@
return (0);
}
+
+int
+pfctl_set_keepcounters(int dev, bool keep)
+{
+ struct pfioc_nv nv;
+ nvlist_t *nvl;
+ int ret;
+
+ nvl = nvlist_create(0);
+
+ nvlist_add_bool(nvl, "keep_counters", keep);
+
+ nv.data = nvlist_pack(nvl, &nv.len);
+ nv.size = nv.len;
+
+ nvlist_destroy(nvl);
+
+ ret = ioctl(dev, DIOCKEEPCOUNTERS, &nv);
+
+ free(nv.data);
+ return (ret);
+}
Index: sbin/pfctl/parse.y
===================================================================
--- sbin/pfctl/parse.y
+++ sbin/pfctl/parse.y
@@ -463,7 +463,7 @@
%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY FAILPOLICY
%token RANDOMID REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
-%token ANTISPOOF FOR INCLUDE SCHEDULE
+%token ANTISPOOF FOR INCLUDE SCHEDULE KEEPCOUNTERS
%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
@@ -721,6 +721,9 @@
}
keep_state_defaults = $3;
}
+ | SET KEEPCOUNTERS {
+ pf->keep_counters = true;
+ }
;
stringall : STRING { $$ = $1; }
@@ -5618,6 +5621,7 @@
{ "inet6", INET6},
{ "interval", INTERVAL},
{ "keep", KEEP},
+ { "keepcounters", KEEPCOUNTERS},
{ "label", LABEL},
{ "limit", LIMIT},
{ "linkshare", LINKSHARE},
Index: sbin/pfctl/pfctl.c
===================================================================
--- sbin/pfctl/pfctl.c
+++ sbin/pfctl/pfctl.c
@@ -1746,6 +1746,10 @@
if (pfctl_load_hostid(pf, pf->hostid))
error = 1;
+ /* load keepcounters */
+ if (pfctl_set_keepcounters(pf->dev, pf->keep_counters))
+ error = 1;
+
return (error);
}
Index: sbin/pfctl/pfctl_parser.h
===================================================================
--- sbin/pfctl/pfctl_parser.h
+++ sbin/pfctl/pfctl_parser.h
@@ -98,6 +98,7 @@
u_int32_t debug;
u_int32_t hostid;
char *ifname;
+ bool keep_counters;
u_int8_t timeout_set[PFTM_MAX];
u_int8_t limit_set[PF_LIMIT_MAX];
Index: share/man/man5/pf.conf.5
===================================================================
--- share/man/man5/pf.conf.5
+++ share/man/man5/pf.conf.5
@@ -618,6 +618,13 @@
.It Ar loud
Generate debug messages for common conditions.
.El
+.It Ar set keepcounters
+Preserve rule counters across rule updates.
+Usually rule counters are reset to zero on every update of the ruleset.
+With
+.Ar keepcounters
+set pf will attempt to find matching rules between old and new rulesets
+and preserve the rule counters.
.El
.Sh TRAFFIC NORMALIZATION
Traffic normalization is used to sanitize packet content in such
Index: sys/net/pfvar.h
===================================================================
--- sys/net/pfvar.h
+++ sys/net/pfvar.h
@@ -997,6 +997,7 @@
uint32_t hostid;
char ifname[IFNAMSIZ];
uint8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
+ bool keep_counters;
};
struct pf_divert {
@@ -1303,6 +1304,7 @@
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
#define DIOCKILLSCHEDULE _IOWR('D', 92, struct pfioc_nv)
+#define DIOCKEEPCOUNTERS _IOWR('D', 93, struct pfioc_nv)
struct pf_ifspeed_v0 {
char ifname[IFNAMSIZ];
Index: sys/netpfil/pf/pf_ioctl.c
===================================================================
--- sys/netpfil/pf/pf_ioctl.c
+++ sys/netpfil/pf/pf_ioctl.c
@@ -198,6 +198,7 @@
static void pf_clear_srcnodes(struct pf_ksrc_node *);
static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
static int pf_kill_schedule(struct pfioc_nv *);
+static int pf_keepcounters(struct pfioc_nv *);
static void pf_tbladdr_copyout(struct pf_addr_wrap *);
/*
@@ -1023,11 +1024,27 @@
PF_MD5_UPD(rule, tos);
}
+static bool
+pf_krule_compare(struct pf_krule *a, struct pf_krule *b)
+{
+ MD5_CTX ctx[2];
+ u_int8_t digest[2][PF_MD5_DIGEST_LENGTH];
+
+ MD5Init(&ctx[0]);
+ MD5Init(&ctx[1]);
+ pf_hash_rule(&ctx[0], a);
+ pf_hash_rule(&ctx[1], b);
+ MD5Final(digest[0], &ctx[0]);
+ MD5Final(digest[1], &ctx[1]);
+
+ return (memcmp(digest[0], digest[1], PF_MD5_DIGEST_LENGTH) == 0);
+}
+
static int
pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
{
struct pf_kruleset *rs;
- struct pf_krule *rule, **old_array;
+ struct pf_krule *rule, **old_array, *tail;
struct pf_krulequeue *old_rules;
int error;
u_int32_t old_rcount;
@@ -1059,6 +1076,29 @@
rs->rules[rs_num].inactive.ptr_array;
rs->rules[rs_num].active.rcount =
rs->rules[rs_num].inactive.rcount;
+
+ /* Attempt to preserve counter information. */
+ if (V_pf_status.keep_counters) {
+ TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr,
+ entries) {
+ tail = TAILQ_FIRST(old_rules);
+ while ((tail != NULL) && ! pf_krule_compare(tail, rule))
+ tail = TAILQ_NEXT(tail, entries);
+ if (tail != NULL) {
+ counter_u64_add(rule->evaluations,
+ counter_u64_fetch(tail->evaluations));
+ counter_u64_add(rule->packets[0],
+ counter_u64_fetch(tail->packets[0]));
+ counter_u64_add(rule->packets[1],
+ counter_u64_fetch(tail->packets[1]));
+ counter_u64_add(rule->bytes[0],
+ counter_u64_fetch(tail->bytes[0]));
+ counter_u64_add(rule->bytes[1],
+ counter_u64_fetch(tail->bytes[1]));
+ }
+ }
+ }
+
rs->rules[rs_num].inactive.ptr = old_rules;
rs->rules[rs_num].inactive.ptr_array = old_array;
rs->rules[rs_num].inactive.rcount = old_rcount;
@@ -4423,6 +4463,10 @@
error = pf_kill_schedule((struct pfioc_nv *)addr);
break;
+ case DIOCKEEPCOUNTERS:
+ error = pf_keepcounters((struct pfioc_nv *)addr);
+ break;
+
case DIOCSETHOSTID: {
u_int32_t *hostid = (u_int32_t *)addr;
@@ -4770,6 +4814,41 @@
return (error);
}
+static int
+pf_keepcounters(struct pfioc_nv *nv)
+{
+ nvlist_t *nvl = NULL;
+ void *nvlpacked = NULL;
+ int error = 0;
+
+#define ERROUT(x) do { error = (x); goto on_error; } while (0)
+
+ if (nv->len > pf_ioctl_maxcount)
+ ERROUT(ENOMEM);
+
+ nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
+ if (nvlpacked == NULL)
+ ERROUT(ENOMEM);
+
+ error = copyin(nv->data, nvlpacked, nv->len);
+ if (error)
+ ERROUT(error);
+
+ nvl = nvlist_unpack(nvlpacked, nv->len, 0);
+ if (nvl == NULL)
+ ERROUT(EBADMSG);
+
+ if (! nvlist_exists_bool(nvl, "keep_counters"))
+ ERROUT(EBADMSG);
+
+ V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
+
+on_error:
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (error);
+}
+
/*
* XXX - Check for version missmatch!!!
*/

File Metadata

Mime Type
text/plain
Expires
Sun, Aug 16, 12:38 AM (13 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36808076
Default Alt Text
D29780.id87499.diff (7 KB)

Event Timeline