From c45d6b0ec011d5c113e0f7dedfc0070e8464fbbc Mon Sep 17 00:00:00 2001 From: Kajetan Staszkiewicz Date: Mon, 29 May 2023 21:35:58 +0200 Subject: [PATCH] pfctl: Add missing state parameters in DIOCGETSTATESV2 Reviewed by: kp Sponsored by: InnoGames GmbH Different Revision: https://reviews.freebsd.org/D40259 --- lib/libpfctl/libpfctl.c | 16 +++++++++++-- lib/libpfctl/libpfctl.h | 12 ++++++++++ sbin/pfctl/pf_print_state.c | 45 ++++++++++++++++++++++++++++++++----- sys/net/pfvar.h | 15 +++++++++++-- sys/netpfil/pf/pf_ioctl.c | 20 +++++++++++++++-- 5 files changed, 97 insertions(+), 11 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 4f251e92d9aa..28ec89cd2aed 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -1111,6 +1111,7 @@ pf_state_export_to_state(struct pfctl_state *ps, const struct pf_state_export *s ps->id = s->id; strlcpy(ps->ifname, s->ifname, sizeof(ps->ifname)); strlcpy(ps->orig_ifname, s->orig_ifname, sizeof(ps->orig_ifname)); + strlcpy(ps->rt_ifname, s->rt_ifname, sizeof(ps->rt_ifname)); pf_state_key_export_to_state_key(&ps->key[0], &s->key[0]); pf_state_key_export_to_state_key(&ps->key[1], &s->key[1]); pf_state_peer_export_to_state_peer(&ps->src, &s->src); @@ -1131,8 +1132,19 @@ pf_state_export_to_state(struct pfctl_state *ps, const struct pf_state_export *s ps->key[0].af = s->af; ps->key[1].af = s->af; ps->direction = s->direction; - ps->state_flags = s->state_flags; - ps->sync_flags = s->sync_flags; + ps->state_flags = ntohs(s->state_flags); + ps->sync_flags = ntohs(s->sync_flags); + ps->qid = ntohs(s->qid); + ps->pqid = ntohs(s->pqid); + ps->dnpipe = ntohs(s->dnpipe); + ps->dnrpipe = ntohs(s->dnrpipe); + ps->rtableid = ntohl(s->rtableid); + ps->min_ttl = s->min_ttl; + ps->set_tos = s->set_tos; + ps->max_mss = ntohs(s->max_mss); + ps->rt = s->rt; + ps->set_prio[0] = s->set_prio[0]; + ps->set_prio[1] = s->set_prio[1]; } int diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 064adafcf3ed..1a22cb5b853c 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -353,6 +353,18 @@ struct pfctl_state { uint32_t pfsync_time; uint16_t state_flags; uint32_t sync_flags; + uint16_t qid; + uint16_t pqid; + uint16_t dnpipe; + uint16_t dnrpipe; + uint8_t log; + int32_t rtableid; + uint8_t min_ttl; + uint8_t set_tos; + uint16_t max_mss; + uint8_t set_prio[2]; + uint8_t rt; + char rt_ifname[IFNAMSIZ]; }; TAILQ_HEAD(pfctl_statelist, pfctl_state); diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c index d23a0154b70d..f0ad9a427006 100644 --- a/sbin/pfctl/pf_print_state.c +++ b/sbin/pfctl/pf_print_state.c @@ -350,17 +350,34 @@ print_state(struct pfctl_state *s, int opts) if (s->state_flags & PFSTATE_NODF) printf(", no-df"); if (s->state_flags & PFSTATE_SETTOS) - printf(", set-tos"); + printf(", set-tos 0x%2.2x", s->set_tos); if (s->state_flags & PFSTATE_RANDOMID) printf(", random-id"); if (s->state_flags & PFSTATE_SCRUB_TCP) - printf(", scrub-tcp"); + printf(", reassemble-tcp"); if (s->state_flags & PFSTATE_SETPRIO) - printf(", set-prio"); + printf(", set-prio (0x%02x 0x%02x)", + s->set_prio[0], s->set_prio[1]); + if (s->dnpipe || s->dnrpipe) { + if (s->state_flags & PFSTATE_DN_IS_PIPE) + printf(", dummynet pipe (%d %d)", + s->dnpipe, s->dnrpipe); + if (s->state_flags & PFSTATE_DN_IS_QUEUE) + printf(", dummynet queue (%d %d)", + s->dnpipe, s->dnrpipe); + } if (s->sync_flags & PFSYNC_FLAG_SRCNODE) printf(", source-track"); if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE) printf(", sticky-address"); + if (s->log) + printf(", log"); + if (s->log & PF_LOG_ALL) + printf(" (all)"); + if (s->min_ttl) + printf(", min-ttl %d", s->min_ttl); + if (s->max_mss) + printf(", max-mss %d", s->max_mss); printf("\n"); } if (opts & PF_OPT_VERBOSE2) { @@ -368,8 +385,26 @@ print_state(struct pfctl_state *s, int opts) bcopy(&s->id, &id, sizeof(u_int64_t)); printf(" id: %016jx creatorid: %08x", id, s->creatorid); - printf(" gateway: "); - print_host(&s->rt_addr, 0, af, opts); + if (s->rt) { + switch (s->rt) { + case PF_ROUTETO: + printf(" route-to: "); + break; + case PF_DUPTO: + printf(" dup-to: "); + break; + case PF_REPLYTO: + printf(" reply-to: "); + break; + default: + printf(" gateway: "); + } + print_host(&s->rt_addr, 0, af, opts); + if (s->rt_ifname[0]) + printf("@%s", s->rt_ifname); + } + if (s->rtableid != -1) + printf(" rtable: %d", s->rtableid); printf("\n"); if (strcmp(s->ifname, s->orig_ifname) != 0) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index c5923bc9abdf..2f2cc1632edc 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -976,7 +976,7 @@ _Static_assert(sizeof(struct pf_state_peer_export) == 32, "size incorrect"); struct pf_state_export { uint64_t version; -#define PF_STATE_VERSION 20210706 +#define PF_STATE_VERSION 20230404 uint64_t id; char ifname[IFNAMSIZ]; char orig_ifname[IFNAMSIZ]; @@ -1003,8 +1003,19 @@ struct pf_state_export { uint8_t sync_flags; uint8_t updates; uint16_t state_flags; + uint16_t qid; + uint16_t pqid; + uint16_t dnpipe; + uint16_t dnrpipe; + int32_t rtableid; + uint8_t min_ttl; + uint8_t set_tos; + uint16_t max_mss; + uint8_t set_prio[2]; + uint8_t rt; + char rt_ifname[IFNAMSIZ]; - uint8_t spare[110]; + uint8_t spare[72]; }; _Static_assert(sizeof(struct pf_state_export) == 384, "size incorrect"); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 665213b07bfe..db88c7d2dc0e 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -5787,9 +5787,9 @@ pf_state_export(struct pf_state_export *sp, struct pf_kstate *st) sp->direction = st->direction; sp->log = st->log; sp->timeout = st->timeout; - /* 8 bits for old peers, 16 bits for new peers */ + /* 8 bits for the old libpfctl, 16 bits for the new libpfctl */ sp->state_flags_compat = st->state_flags; - sp->state_flags = st->state_flags; + sp->state_flags = htons(st->state_flags); if (st->src_node) sp->sync_flags |= PFSYNC_FLAG_SRCNODE; if (st->nat_src_node) @@ -5817,6 +5817,22 @@ pf_state_export(struct pf_state_export *sp, struct pf_kstate *st) sp->packets[1] = st->packets[1]; sp->bytes[0] = st->bytes[0]; sp->bytes[1] = st->bytes[1]; + + sp->qid = htons(st->qid); + sp->pqid = htons(st->pqid); + sp->dnpipe = htons(st->dnpipe); + sp->dnrpipe = htons(st->dnrpipe); + sp->rtableid = htonl(st->rtableid); + sp->min_ttl = st->min_ttl; + sp->set_tos = st->set_tos; + sp->max_mss = htons(st->max_mss); + sp->rt = st->rt; + if (st->rt_kif) + strlcpy(sp->rt_ifname, st->rt_kif->pfik_name, + sizeof(sp->rt_ifname)); + sp->set_prio[0] = st->set_prio[0]; + sp->set_prio[1] = st->set_prio[1]; + } static void