From d0fdf2b28f9b981d2cb98e9da8a715e046ef1e92 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 12 May 2021 13:24:57 +0200 Subject: [PATCH] pf: Track the original kif for floating states Track (and display) the interface that created a state, even if it's a floating state (and thus uses virtual interface 'all'). MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D30245 --- lib/libpfctl/libpfctl.c | 2 ++ lib/libpfctl/libpfctl.h | 1 + sbin/pfctl/pf_print_state.c | 5 ++++- sys/net/pfvar.h | 2 ++ sys/netpfil/pf/if_pfsync.c | 2 +- sys/netpfil/pf/pf.c | 7 ++++--- sys/netpfil/pf/pf_ioctl.c | 1 + 7 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 6a6ecd8fb136..e207a55a8673 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -699,6 +699,8 @@ pf_nvstate_to_state(const nvlist_t *nvl, struct pfctl_state *s) strlcpy(s->ifname, nvlist_get_string(nvl, "ifname"), sizeof(s->ifname)); + strlcpy(s->orig_ifname, nvlist_get_string(nvl, "orig_ifname"), + sizeof(s->orig_ifname)); pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "rt_addr"), &s->rt_addr); s->rule = nvlist_get_number(nvl, "rule"); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 05447b5d8673..a54ee9db6ec7 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -237,6 +237,7 @@ struct pfctl_state { struct pf_addr rt_addr; struct pfctl_state_key key[2]; /* addresses stack and wire */ char ifname[IFNAMSIZ]; + char orig_ifname[IFNAMSIZ]; uint64_t packets[2]; uint64_t bytes[2]; uint32_t creation; diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c index 7119308d195b..b1f0079154cf 100644 --- a/sbin/pfctl/pf_print_state.c +++ b/sbin/pfctl/pf_print_state.c @@ -352,9 +352,12 @@ 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: "); + printf(" gateway: "); print_host(&s->rt_addr, 0, af, opts); printf("\n"); + + if (strcmp(s->ifname, s->orig_ifname) != 0) + printf(" origif: %s\n", s->orig_ifname); } } diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index d9e35dae753a..2202421086d2 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -522,6 +522,7 @@ struct pf_state { struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ struct pfi_kkif *kif; + struct pfi_kkif *orig_kif; /* The real kif, even if we're a floating state (i.e. if == V_pfi_all). */ struct pfi_kkif *rt_kif; struct pf_ksrc_node *src_node; struct pf_ksrc_node *nat_src_node; @@ -1475,6 +1476,7 @@ extern int pf_unlink_state(struct pf_state *, u_int); #define PF_ENTER_LOCKED 0x00000001 #define PF_RETURN_LOCKED 0x00000002 extern int pf_state_insert(struct pfi_kkif *, + struct pfi_kkif *, struct pf_state_key *, struct pf_state_key *, struct pf_state *); diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 96813fd11dc3..3514c922c361 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -593,7 +593,7 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) if (!(flags & PFSYNC_SI_IOCTL)) st->state_flags |= PFSTATE_NOSYNC; - if ((error = pf_state_insert(kif, skw, sks, st)) != 0) + if ((error = pf_state_insert(kif, kif, skw, sks, st)) != 0) goto cleanup_state; /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index a5c4ef6bfbb4..985b55af5263 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1263,8 +1263,8 @@ pf_state_key_clone(struct pf_state_key *orig) } int -pf_state_insert(struct pfi_kkif *kif, struct pf_state_key *skw, - struct pf_state_key *sks, struct pf_state *s) +pf_state_insert(struct pfi_kkif *kif, struct pfi_kkif *orig_kif, + struct pf_state_key *skw, struct pf_state_key *sks, struct pf_state *s) { struct pf_idhash *ih; struct pf_state *cur; @@ -1277,6 +1277,7 @@ pf_state_insert(struct pfi_kkif *kif, struct pf_state_key *skw, KASSERT(s->refs == 0, ("%s: state not pristine", __func__)); s->kif = kif; + s->orig_kif = orig_kif; if (s->id == 0 && s->creatorid == 0) { /* XXX: should be atomic, but probability of collision low */ @@ -3877,7 +3878,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, __func__, nr, sk, nk)); /* Swap sk/nk for PF_OUT. */ - if (pf_state_insert(BOUND_IFACE(r, kif), + if (pf_state_insert(BOUND_IFACE(r, kif), kif, (pd->dir == PF_IN) ? sk : nk, (pd->dir == PF_IN) ? nk : sk, s)) { if (pd->proto == IPPROTO_TCP) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 8424e0ce5689..62c1f35c3c3f 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2562,6 +2562,7 @@ pf_state_to_nvstate(const struct pf_state *s) nvlist_add_number(nvl, "id", s->id); nvlist_add_string(nvl, "ifname", s->kif->pfik_name); + nvlist_add_string(nvl, "orig_ifname", s->orig_kif->pfik_name); tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_STACK]); if (tmp == NULL)