Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153535793
D31097.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D31097.diff
View Options
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -520,6 +520,65 @@
#define PFSTATE_SETPRIO 0x0200
#define PFSTATE_SETMASK (PFSTATE_SETPRIO)
+struct pf_state_scrub_export {
+ uint16_t pfss_flags;
+ uint8_t pfss_ttl; /* stashed TTL */
+#define PF_SCRUB_FLAG_VALID 0x01
+ uint8_t scrub_flag;
+ uint32_t pfss_ts_mod; /* timestamp modulation */
+};
+
+struct pf_state_key_export {
+ struct pf_addr addr[2];
+ uint16_t port[2];
+};
+
+struct pf_state_peer_export {
+ struct pf_state_scrub_export scrub; /* state is scrubbed */
+ uint32_t seqlo; /* Max sequence number sent */
+ uint32_t seqhi; /* Max the other end ACKd + win */
+ uint32_t seqdiff; /* Sequence number modulator */
+ uint16_t max_win; /* largest window (pre scaling) */
+ uint16_t mss; /* Maximum segment size option */
+ uint8_t state; /* active state level */
+ uint8_t wscale; /* window scaling factor */
+ uint8_t dummy[6];
+};
+_Static_assert(sizeof(struct pf_state_peer_export) == 32, "size incorrect");
+
+struct pf_state_export {
+ uint64_t version;
+#define PF_STATE_VERSION 20210706
+ uint64_t id;
+ char ifname[IFNAMSIZ];
+ char orig_ifname[IFNAMSIZ];
+ struct pf_state_key_export key[2];
+ struct pf_state_peer_export src;
+ struct pf_state_peer_export dst;
+ struct pf_addr rt_addr;
+ uint32_t rule;
+ uint32_t anchor;
+ uint32_t nat_rule;
+ uint32_t creation;
+ uint32_t expire;
+ uint32_t spare0;
+ uint64_t packets[2];
+ uint64_t bytes[2];
+ uint32_t creatorid;
+ uint32_t spare1;
+ sa_family_t af;
+ uint8_t proto;
+ uint8_t direction;
+ uint8_t log;
+ uint8_t state_flags;
+ uint8_t timeout;
+ uint8_t sync_flags;
+ uint8_t updates;
+
+ uint8_t spare[112];
+};
+_Static_assert(sizeof(struct pf_state_export) == 384, "size incorrect");
+
#ifdef _KERNEL
struct pf_kstate {
u_int64_t id;
@@ -646,6 +705,8 @@
void pfsync_state_export(struct pfsync_state *,
struct pf_kstate *);
+void pf_state_export(struct pf_state_export *,
+ struct pf_kstate *);
/* pflog */
struct pf_kruleset;
@@ -1187,6 +1248,17 @@
#define ps_states ps_u.psu_states
};
+struct pfioc_states_v2 {
+ int ps_len;
+ uint64_t ps_req_version;
+ union {
+ caddr_t psu_buf;
+ struct pf_state_export *psu_states;
+ } ps_u;
+#define ps_buf ps_u.psu_buf
+#define ps_states ps_u.psu_states
+};
+
struct pfioc_src_nodes {
int psn_len;
union {
@@ -1402,6 +1474,7 @@
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
#define DIOCKEEPCOUNTERS _IOWR('D', 92, struct pfioc_nv)
+#define DIOCGETSTATESV2 _IOWR('D', 93, struct pfioc_states_v2)
struct pf_ifspeed_v0 {
char ifname[IFNAMSIZ];
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
@@ -2108,6 +2108,7 @@
case DIOCNATLOOK:
case DIOCSETDEBUG:
case DIOCGETSTATES:
+ case DIOCGETSTATESV2:
case DIOCGETSTATESNV:
case DIOCGETTIMEOUT:
case DIOCCLRRULECTRS:
@@ -2161,6 +2162,7 @@
case DIOCGETSTATENV:
case DIOCGETSTATUS:
case DIOCGETSTATES:
+ case DIOCGETSTATESV2:
case DIOCGETSTATESNV:
case DIOCGETTIMEOUT:
case DIOCGETLIMIT:
@@ -2871,6 +2873,60 @@
break;
}
+ case DIOCGETSTATESV2: {
+ struct pfioc_states_v2 *ps = (struct pfioc_states_v2 *)addr;
+ struct pf_kstate *s;
+ struct pf_state_export *pstore, *p;
+ int i, nr;
+
+ if (ps->ps_req_version > PF_STATE_VERSION) {
+ error = ENOTSUP;
+ break;
+ }
+
+ if (ps->ps_len <= 0) {
+ nr = uma_zone_get_cur(V_pf_state_z);
+ ps->ps_len = sizeof(struct pf_state_export) * nr;
+ break;
+ }
+
+ p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK | M_ZERO);
+ nr = 0;
+
+ for (i = 0; i <= pf_hashmask; i++) {
+ struct pf_idhash *ih = &V_pf_idhash[i];
+
+ if (LIST_EMPTY(&ih->states))
+ continue;
+
+ PF_HASHROW_LOCK(ih);
+ LIST_FOREACH(s, &ih->states, entry) {
+ if (s->timeout == PFTM_UNLINKED)
+ continue;
+
+ if ((nr+1) * sizeof(*p) > ps->ps_len) {
+ PF_HASHROW_UNLOCK(ih);
+ goto DIOCGETSTATESV2_full;
+ }
+ pf_state_export(p, s);
+ p++;
+ nr++;
+ }
+ PF_HASHROW_UNLOCK(ih);
+ }
+DIOCGETSTATESV2_full:
+ error = copyout(pstore, ps->ps_states,
+ sizeof(struct pf_state_export) * nr);
+ if (error) {
+ free(pstore, M_TEMP);
+ break;
+ }
+ ps->ps_len = sizeof(struct pf_state_export) * nr;
+ free(pstore, M_TEMP);
+
+ break;
+ }
+
case DIOCGETSTATESNV: {
error = pf_getstates((struct pfioc_nv *)addr);
break;
@@ -4594,7 +4650,70 @@
pf_state_counter_hton(st->packets[1], sp->packets[1]);
pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
+}
+
+void
+pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
+{
+ bzero(sp, sizeof(*sp));
+
+ sp->version = PF_STATE_VERSION;
+
+ /* copy from state key */
+ sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
+ sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
+ sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
+ sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
+ sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
+ sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
+ sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
+ sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
+ sp->proto = st->key[PF_SK_WIRE]->proto;
+ sp->af = st->key[PF_SK_WIRE]->af;
+
+ /* copy from state */
+ strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+ strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
+ sizeof(sp->orig_ifname));
+ bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
+ sp->creation = htonl(time_uptime - st->creation);
+ sp->expire = pf_state_expires(st);
+ if (sp->expire <= time_uptime)
+ sp->expire = htonl(0);
+ else
+ sp->expire = htonl(sp->expire - time_uptime);
+
+ sp->direction = st->direction;
+ sp->log = st->log;
+ sp->timeout = st->timeout;
+ sp->state_flags = st->state_flags;
+ if (st->src_node)
+ sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (st->nat_src_node)
+ sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+
+ sp->id = st->id;
+ sp->creatorid = st->creatorid;
+ pf_state_peer_hton(&st->src, &sp->src);
+ pf_state_peer_hton(&st->dst, &sp->dst);
+
+ if (st->rule.ptr == NULL)
+ sp->rule = htonl(-1);
+ else
+ sp->rule = htonl(st->rule.ptr->nr);
+ if (st->anchor.ptr == NULL)
+ sp->anchor = htonl(-1);
+ else
+ sp->anchor = htonl(st->anchor.ptr->nr);
+ if (st->nat_rule.ptr == NULL)
+ sp->nat_rule = htonl(-1);
+ else
+ sp->nat_rule = htonl(st->nat_rule.ptr->nr);
+ sp->packets[0] = st->packets[0];
+ sp->packets[1] = st->packets[1];
+ sp->bytes[0] = st->bytes[0];
+ sp->bytes[1] = st->bytes[1];
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 5:49 PM (1 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31991905
Default Alt Text
D31097.diff (6 KB)
Attached To
Mode
D31097: pf: add DIOCGETSTATESV2
Attached
Detach File
Event Timeline
Log In to Comment