Date: Fri, 16 Jul 2021 11:53:58 GMT From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: e540d078793b - stable/13 - pf: add DIOCGETSTATESV2 Message-ID: <202107161153.16GBrwLw016214@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=e540d078793bacd4a291b499c96a34e027b13d8a commit e540d078793bacd4a291b499c96a34e027b13d8a Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2021-07-06 10:12:12 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2021-07-16 09:08:27 +0000 pf: add DIOCGETSTATESV2 Add a new version of the DIOCGETSTATES call, which extends the struct to include the original interface information. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D31097 (cherry picked from commit c6bf20a2a46dc36bf881ac594454f71379828a9a) --- sys/net/pfvar.h | 73 ++++++++++++++++++++++++++++ sys/netpfil/pf/pf_ioctl.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index df86ce4f92c2..b6a2045473ec 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -517,6 +517,65 @@ struct pf_state_cmp { #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; @@ -643,6 +702,8 @@ extern pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr; 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; @@ -1184,6 +1245,17 @@ struct pfioc_states { #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 { @@ -1399,6 +1471,7 @@ struct pfioc_iface { #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 index bed3e8b057d1..24e40c1c716c 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2109,6 +2109,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCNATLOOK: case DIOCSETDEBUG: case DIOCGETSTATES: + case DIOCGETSTATESV2: case DIOCGETSTATESNV: case DIOCGETTIMEOUT: case DIOCCLRRULECTRS: @@ -2162,6 +2163,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCGETSTATENV: case DIOCGETSTATUS: case DIOCGETSTATES: + case DIOCGETSTATESV2: case DIOCGETSTATESNV: case DIOCGETTIMEOUT: case DIOCGETLIMIT: @@ -2872,6 +2874,60 @@ DIOCGETSTATES_full: 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; @@ -4595,7 +4651,70 @@ pfsync_state_export(struct pfsync_state *sp, struct pf_kstate *st) 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107161153.16GBrwLw016214>