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
This commit is contained in:
Kristof Provost 2021-05-12 13:24:57 +02:00
parent bc94129147
commit d0fdf2b28f
7 changed files with 15 additions and 5 deletions

View File

@ -699,6 +699,8 @@ pf_nvstate_to_state(const nvlist_t *nvl, struct pfctl_state *s)
strlcpy(s->ifname, nvlist_get_string(nvl, "ifname"), strlcpy(s->ifname, nvlist_get_string(nvl, "ifname"),
sizeof(s->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); pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "rt_addr"), &s->rt_addr);
s->rule = nvlist_get_number(nvl, "rule"); s->rule = nvlist_get_number(nvl, "rule");

View File

@ -237,6 +237,7 @@ struct pfctl_state {
struct pf_addr rt_addr; struct pf_addr rt_addr;
struct pfctl_state_key key[2]; /* addresses stack and wire */ struct pfctl_state_key key[2]; /* addresses stack and wire */
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
char orig_ifname[IFNAMSIZ];
uint64_t packets[2]; uint64_t packets[2];
uint64_t bytes[2]; uint64_t bytes[2];
uint32_t creation; uint32_t creation;

View File

@ -352,9 +352,12 @@ print_state(struct pfctl_state *s, int opts)
bcopy(&s->id, &id, sizeof(u_int64_t)); bcopy(&s->id, &id, sizeof(u_int64_t));
printf(" id: %016jx creatorid: %08x", id, s->creatorid); printf(" id: %016jx creatorid: %08x", id, s->creatorid);
printf(" gateway: "); printf(" gateway: ");
print_host(&s->rt_addr, 0, af, opts); print_host(&s->rt_addr, 0, af, opts);
printf("\n"); printf("\n");
if (strcmp(s->ifname, s->orig_ifname) != 0)
printf(" origif: %s\n", s->orig_ifname);
} }
} }

View File

@ -522,6 +522,7 @@ struct pf_state {
struct pf_addr rt_addr; struct pf_addr rt_addr;
struct pf_state_key *key[2]; /* addresses stack and wire */ struct pf_state_key *key[2]; /* addresses stack and wire */
struct pfi_kkif *kif; 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 pfi_kkif *rt_kif;
struct pf_ksrc_node *src_node; struct pf_ksrc_node *src_node;
struct pf_ksrc_node *nat_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_ENTER_LOCKED 0x00000001
#define PF_RETURN_LOCKED 0x00000002 #define PF_RETURN_LOCKED 0x00000002
extern int pf_state_insert(struct pfi_kkif *, extern int pf_state_insert(struct pfi_kkif *,
struct pfi_kkif *,
struct pf_state_key *, struct pf_state_key *,
struct pf_state_key *, struct pf_state_key *,
struct pf_state *); struct pf_state *);

View File

@ -593,7 +593,7 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
if (!(flags & PFSYNC_SI_IOCTL)) if (!(flags & PFSYNC_SI_IOCTL))
st->state_flags |= PFSTATE_NOSYNC; 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; goto cleanup_state;
/* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */

View File

@ -1263,8 +1263,8 @@ pf_state_key_clone(struct pf_state_key *orig)
} }
int int
pf_state_insert(struct pfi_kkif *kif, struct pf_state_key *skw, pf_state_insert(struct pfi_kkif *kif, struct pfi_kkif *orig_kif,
struct pf_state_key *sks, struct pf_state *s) struct pf_state_key *skw, struct pf_state_key *sks, struct pf_state *s)
{ {
struct pf_idhash *ih; struct pf_idhash *ih;
struct pf_state *cur; 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__)); KASSERT(s->refs == 0, ("%s: state not pristine", __func__));
s->kif = kif; s->kif = kif;
s->orig_kif = orig_kif;
if (s->id == 0 && s->creatorid == 0) { if (s->id == 0 && s->creatorid == 0) {
/* XXX: should be atomic, but probability of collision low */ /* 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)); __func__, nr, sk, nk));
/* Swap sk/nk for PF_OUT. */ /* 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) ? sk : nk,
(pd->dir == PF_IN) ? nk : sk, s)) { (pd->dir == PF_IN) ? nk : sk, s)) {
if (pd->proto == IPPROTO_TCP) if (pd->proto == IPPROTO_TCP)

View File

@ -2562,6 +2562,7 @@ pf_state_to_nvstate(const struct pf_state *s)
nvlist_add_number(nvl, "id", s->id); nvlist_add_number(nvl, "id", s->id);
nvlist_add_string(nvl, "ifname", s->kif->pfik_name); 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]); tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_STACK]);
if (tmp == NULL) if (tmp == NULL)