diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -648,17 +648,20 @@ }; struct pf_rule_actions { + struct pf_addr rt_addr; + struct pfi_kkif *rt_kif; int32_t rtableid; + uint32_t flags; uint16_t qid; uint16_t pqid; uint16_t max_mss; + uint16_t dnpipe; + uint16_t dnrpipe; /* Reverse direction pipe */ uint8_t log; uint8_t set_tos; uint8_t min_ttl; - uint16_t dnpipe; - uint16_t dnrpipe; /* Reverse direction pipe */ - uint32_t flags; uint8_t set_prio[2]; + uint8_t rt; }; union pf_keth_rule_ptr { @@ -1088,12 +1091,10 @@ struct pf_krule *rule; struct pf_krule *anchor; struct pf_krule *nat_rule; - struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ struct pf_udp_mapping *udp_mapping; 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; u_int64_t packets[2]; @@ -1103,7 +1104,6 @@ u_int32_t pfsync_time; struct pf_rule_actions act; u_int16_t tag; - u_int8_t rt; u_int16_t if_index_in; u_int16_t if_index_out; }; @@ -1111,7 +1111,7 @@ /* * Size <= fits 11 objects per page on LP64. Try to not grow the struct beyond that. */ -_Static_assert(sizeof(struct pf_kstate) <= 372, "pf_kstate size crosses 372 bytes"); +_Static_assert(sizeof(struct pf_kstate) <= 368, "pf_kstate size crosses 368 bytes"); #endif /* diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -611,7 +611,7 @@ } /* copy to state */ - bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr)); + bcopy(&sp->pfs_1301.rt_addr, &st->act.rt_addr, sizeof(st->act.rt_addr)); st->creation = (time_uptime - ntohl(sp->pfs_1301.creation)) * 1000; st->expire = pf_get_uptime(); if (sp->pfs_1301.expire) { @@ -680,8 +680,8 @@ st->act.max_mss = ntohs(sp->pfs_1400.max_mss); st->act.set_prio[0] = sp->pfs_1400.set_prio[0]; st->act.set_prio[1] = sp->pfs_1400.set_prio[1]; - st->rt = sp->pfs_1400.rt; - if (st->rt && (st->rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) { + st->act.rt = sp->pfs_1400.rt; + if (st->act.rt && (st->act.rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) { if (V_pf_status.debug >= PF_DEBUG_MISC) printf("%s: unknown route interface: %s\n", __func__, sp->pfs_1400.rt_ifname); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -379,7 +379,8 @@ static void pf_overload_task(void *v, int pending); static u_short pf_insert_src_node(struct pf_ksrc_node **, struct pf_srchash **, struct pf_krule *, - struct pf_addr *, sa_family_t); + struct pf_addr *, sa_family_t, struct pf_addr *, + struct pfi_kkif *); static u_int pf_purge_expired_states(u_int, int); static void pf_purge_unlinked_rules(void); static int pf_mtag_uminit(void *, int, int); @@ -453,11 +454,11 @@ return (k); /* No route-to, so don't overrule. */ - if (st->rt != PF_ROUTETO) + if (st->act.rt != PF_ROUTETO) return (k); /* Bind to the route-to interface. */ - return (st->rt_kif); + return (st->act.rt_kif); } #define STATE_INC_COUNTERS(s) \ @@ -1020,7 +1021,8 @@ static u_short pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_srchash **sh, - struct pf_krule *rule, struct pf_addr *src, sa_family_t af) + struct pf_krule *rule, struct pf_addr *src, sa_family_t af, + struct pf_addr *raddr, struct pfi_kkif *rkif) { u_short reason = 0; @@ -1071,6 +1073,8 @@ (*sn)->af = af; (*sn)->rule = rule; PF_ACPY(&(*sn)->addr, src, af); + PF_ACPY(&(*sn)->raddr, raddr, af); + (*sn)->rkif = rkif; LIST_INSERT_HEAD(&(*sh)->nodes, *sn, entry); (*sn)->creation = time_uptime; (*sn)->ruletype = rule->action; @@ -2709,8 +2713,8 @@ s->kif->pfik_flags |= PFI_IFLAG_REFS; SLIST_FOREACH(mrm, &s->match_rules, entry) mrm->r->rule_ref |= PFRULE_REFS; - if (s->rt_kif) - s->rt_kif->pfik_flags |= PFI_IFLAG_REFS; + if (s->act.rt_kif) + s->act.rt_kif->pfik_flags |= PFI_IFLAG_REFS; count++; } PF_HASHROW_UNLOCK(ih); @@ -5305,6 +5309,21 @@ if (pd->act.rtableid >= 0) M_SETFIB(pd->m, pd->act.rtableid); + if (r->rt) { + struct pf_ksrc_node *sn = NULL; + struct pf_srchash *snh = NULL; + /* + * Set act.rt here instead of in pf_rule_to_actions() because + * it is applied only from the last pass rule. + */ + pd->act.rt = r->rt; + /* Don't use REASON_SET, pf_map_addr increases the reason counters */ + reason = pf_map_addr_sn(pd->af, r, pd->src, &pd->act.rt_addr, + &pd->act.rt_kif, NULL, &sn, &snh); + if (reason != 0) + goto cleanup; + } + if (pd->virtual_proto != PF_VPROTO_FRAGMENT && (!state_icmp && (r->keep_state || nr != NULL || (pd->flags & PFDESC_TCP_NORM)))) { @@ -5389,14 +5408,15 @@ /* src node for filter rule */ if ((r->rule_flag & PFRULE_SRCTRACK || r->rpool.opts & PF_POOL_STICKYADDR) && - (sn_reason = pf_insert_src_node(&sn, &snh, r, pd->src, pd->af)) != 0) { + (sn_reason = pf_insert_src_node(&sn, &snh, r, pd->src, pd->af, + &pd->act.rt_addr, pd->act.rt_kif)) != 0) { REASON_SET(&reason, sn_reason); goto csfailed; } /* src node for translation rule */ if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && (sn_reason = pf_insert_src_node(&nsn, &nsnh, nr, &sk->addr[pd->sidx], - pd->af)) != 0 ) { + pd->af, &nk->addr[1], NULL)) != 0 ) { REASON_SET(&reason, sn_reason); goto csfailed; } @@ -5486,14 +5506,6 @@ s->timeout = PFTM_OTHER_FIRST_PACKET; } - if (r->rt) { - /* pf_map_addr increases the reason counters */ - if ((reason = pf_map_addr_sn(pd->af, r, pd->src, &s->rt_addr, - &s->rt_kif, NULL, &sn, &snh)) != 0) - goto csfailed; - s->rt = r->rt; - } - s->creation = s->expire = pf_get_uptime(); if (pd->proto == IPPROTO_TCP) { @@ -5550,8 +5562,6 @@ PF_HASHROW_UNLOCK(snh); } if (pf_src_node_exists(&nsn, nsnh)) { - /* XXX We only modify one side for now. */ - PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); s->nat_src_node = nsn; PF_HASHROW_UNLOCK(nsnh); } @@ -7684,23 +7694,20 @@ struct mbuf *m0, *m1, *md; struct sockaddr_in dst; struct ip *ip; - struct pfi_kkif *nkif = NULL; struct ifnet *ifp = NULL; struct pf_addr naddr; int error = 0; uint16_t ip_len, ip_off; uint16_t tmp; - int r_rt, r_dir; + int r_dir; KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); SDT_PROBE4(pf, ip, route_to, entry, *m, pd, s, oifp); if (s) { - r_rt = s->rt; r_dir = s->direction; } else { - r_rt = r->rt; r_dir = r->direction; } @@ -7717,17 +7724,14 @@ goto bad_locked; } - if (r_rt == PF_DUPTO) { + if (pd->act.rt == PF_DUPTO) { if ((pd->pf_mtag->flags & PF_MTAG_FLAG_DUPLICATED)) { - if (s == NULL) { + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; + /* If pfsync'd from FreeBSD < 14 */ + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; - } else { - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - /* If pfsync'd */ - if (ifp == NULL && r->rpool.cur != NULL) - ifp = r->rpool.cur->kif ? - r->rpool.cur->kif->pfik_ifp : NULL; + if (s != NULL) { PF_STATE_UNLOCK(s); } if (ifp == oifp) { @@ -7748,7 +7752,7 @@ } } } else { - if ((r_rt == PF_REPLYTO) == (r_dir == pd->dir)) { + if ((pd->act.rt == PF_REPLYTO) == (r_dir == pd->dir)) { pf_dummynet(pd, s, r, m); if (s) PF_STATE_UNLOCK(s); @@ -7763,30 +7767,16 @@ dst.sin_family = AF_INET; dst.sin_len = sizeof(dst); dst.sin_addr = ip->ip_dst; + dst.sin_addr.s_addr = pd->act.rt_addr.v4.s_addr; + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; bzero(&naddr, sizeof(naddr)); - if (s == NULL) { - if (TAILQ_EMPTY(&r->rpool.list)) { - DPFPRINTF(PF_DEBUG_URGENT, - ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); - SDT_PROBE1(pf, ip, route_to, drop, __LINE__); - goto bad_locked; - } - pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, - &naddr, &nkif, NULL); - if (!PF_AZERO(&naddr, AF_INET)) - dst.sin_addr.s_addr = naddr.v4.s_addr; - ifp = nkif ? nkif->pfik_ifp : NULL; - } else { + if (s != NULL){ struct pfi_kkif *kif; - if (!PF_AZERO(&s->rt_addr, AF_INET)) - dst.sin_addr.s_addr = - s->rt_addr.v4.s_addr; - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - kif = s->rt_kif; - /* If pfsync'd */ + kif = pd->act.rt_kif; + /* If pfsync'd from FreeBSD < 14 */ if (ifp == NULL && r->rpool.cur != NULL) { ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; @@ -7794,7 +7784,7 @@ } if (ifp != NULL && kif != NULL && r->rule_flag & PFRULE_IFBOUND && - r->rt == PF_REPLYTO && + pd->act.rt == PF_REPLYTO && s->kif == V_pfi_all) { s->kif = kif; s->orig_kif = oifp->if_pf_kif; @@ -7890,7 +7880,7 @@ if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) { error = EMSGSIZE; KMOD_IPSTAT_INC(ips_cantfrag); - if (r_rt != PF_DUPTO) { + if (pd->act.rt != PF_DUPTO) { if (s && s->nat_rule != NULL) PACKET_UNDO_NAT(m0, pd, (ip->ip_hl << 2) + (ip_off & IP_OFFMASK), @@ -7934,7 +7924,7 @@ KMOD_IPSTAT_INC(ips_fragmented); done: - if (r_rt != PF_DUPTO) + if (pd->act.rt != PF_DUPTO) *m = NULL; return; @@ -7956,20 +7946,17 @@ struct m_tag *mtag; struct sockaddr_in6 dst; struct ip6_hdr *ip6; - struct pfi_kkif *nkif = NULL; struct ifnet *ifp = NULL; struct pf_addr naddr; - int r_rt, r_dir; + int r_dir; KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); SDT_PROBE4(pf, ip6, route_to, entry, *m, pd, s, oifp); if (s) { - r_rt = s->rt; r_dir = s->direction; } else { - r_rt = r->rt; r_dir = r->direction; } @@ -7986,17 +7973,14 @@ goto bad_locked; } - if (r_rt == PF_DUPTO) { + if (pd->act.rt == PF_DUPTO) { if ((pd->pf_mtag->flags & PF_MTAG_FLAG_DUPLICATED)) { - if (s == NULL) { + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; + /* If pfsync'd from FreeBSD < 14 */ + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; - } else { - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - /* If pfsync'd */ - if (ifp == NULL && r->rpool.cur != NULL) - ifp = r->rpool.cur->kif ? - r->rpool.cur->kif->pfik_ifp : NULL; + if (s != NULL) { PF_STATE_UNLOCK(s); } if (ifp == oifp) { @@ -8017,7 +8001,7 @@ } } } else { - if ((r_rt == PF_REPLYTO) == (r_dir == pd->dir)) { + if ((pd->act.rt == PF_REPLYTO) == (r_dir == pd->dir)) { pf_dummynet(pd, s, r, m); if (s) PF_STATE_UNLOCK(s); @@ -8032,31 +8016,15 @@ dst.sin6_family = AF_INET6; dst.sin6_len = sizeof(dst); dst.sin6_addr = ip6->ip6_dst; - + PF_ACPY((struct pf_addr *)&dst.sin6_addr, &pd->act.rt_addr, AF_INET6); bzero(&naddr, sizeof(naddr)); + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; - if (s == NULL) { - if (TAILQ_EMPTY(&r->rpool.list)) { - DPFPRINTF(PF_DEBUG_URGENT, - ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); - SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); - goto bad_locked; - } - pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, - &naddr, &nkif, NULL); - if (!PF_AZERO(&naddr, AF_INET6)) - PF_ACPY((struct pf_addr *)&dst.sin6_addr, - &naddr, AF_INET6); - ifp = nkif ? nkif->pfik_ifp : NULL; - } else { + if (s != NULL) { struct pfi_kkif *kif; - if (!PF_AZERO(&s->rt_addr, AF_INET6)) - PF_ACPY((struct pf_addr *)&dst.sin6_addr, - &s->rt_addr, AF_INET6); - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - kif = s->rt_kif; - /* If pfsync'd */ + kif = pd->act.rt_kif; + /* If pfsync'd from FreeBSD < 14 */ if (ifp == NULL && r->rpool.cur != NULL) { ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; @@ -8064,7 +8032,7 @@ } if (ifp != NULL && kif != NULL && r->rule_flag & PFRULE_IFBOUND && - r->rt == PF_REPLYTO && + pd->act.rt == PF_REPLYTO && s->kif == V_pfi_all) { s->kif = kif; s->orig_kif = oifp->if_pf_kif; @@ -8133,7 +8101,7 @@ } else { in6_ifstat_inc(ifp, ifs6_in_toobig); - if (r_rt != PF_DUPTO) { + if (pd->act.rt != PF_DUPTO) { if (s && s->nat_rule != NULL) PACKET_UNDO_NAT(m0, pd, ((caddr_t)ip6 - m0->m_data) + @@ -8148,7 +8116,7 @@ } done: - if (r_rt != PF_DUPTO) + if (pd->act.rt != PF_DUPTO) *m = NULL; return; @@ -9034,7 +9002,6 @@ struct pf_pdesc pd; int use_2nd_queue = 0; uint16_t tag; - uint8_t rt; PF_RULES_RLOCK_TRACKER; KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir)); @@ -9326,10 +9293,8 @@ memcpy(&pd.act, &s->act, sizeof(struct pf_rule_actions)); pd.act.log |= log; tag = s->tag; - rt = s->rt; } else { tag = r->tag; - rt = r->rt; } if (tag > 0 && pf_tag_packet(&pd, tag)) { @@ -9472,7 +9437,7 @@ *m0 = NULL; break; default: - if (rt) { + if (pd.act.rt) { switch (af) { #ifdef INET case AF_INET: 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 @@ -2341,7 +2341,7 @@ if (! PF_MATCHA(psk->psk_rt_addr.neg, &psk->psk_rt_addr.addr.v.a.addr, &psk->psk_rt_addr.addr.v.a.mask, - &s->rt_addr, sk->af)) + &s->act.rt_addr, sk->af)) continue; if (psk->psk_src.port_op != 0 && @@ -5587,7 +5587,7 @@ /* copy from state */ strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname)); - bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr)); + bcopy(&st->act.rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr)); sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000)); sp->pfs_1301.expire = pf_state_expires(st); if (sp->pfs_1301.expire <= time_uptime) @@ -5615,10 +5615,10 @@ sp->pfs_1400.max_mss = htons(st->act.max_mss); sp->pfs_1400.set_prio[0] = st->act.set_prio[0]; sp->pfs_1400.set_prio[1] = st->act.set_prio[1]; - sp->pfs_1400.rt = st->rt; - if (st->rt_kif) + sp->pfs_1400.rt = st->act.rt; + if (st->act.rt_kif) strlcpy(sp->pfs_1400.rt_ifname, - st->rt_kif->pfik_name, + st->act.rt_kif->pfik_name, sizeof(sp->pfs_1400.rt_ifname)); break; default: @@ -5678,7 +5678,7 @@ 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)); + bcopy(&st->act.rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); sp->creation = htonl(time_uptime - (st->creation / 1000)); sp->expire = pf_state_expires(st); if (sp->expire <= time_uptime) @@ -5728,9 +5728,9 @@ sp->min_ttl = st->act.min_ttl; sp->set_tos = st->act.set_tos; sp->max_mss = htons(st->act.max_mss); - sp->rt = st->rt; - if (st->rt_kif) - strlcpy(sp->rt_ifname, st->rt_kif->pfik_name, + sp->rt = st->act.rt; + if (st->act.rt_kif) + strlcpy(sp->rt_ifname, st->act.rt_kif->pfik_name, sizeof(sp->rt_ifname)); sp->set_prio[0] = st->act.set_prio[0]; sp->set_prio[1] = st->act.set_prio[1]; diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -631,24 +631,18 @@ u_short reason = 0; struct pf_kpool *rpool = &r->rpool; - /* - * Try to find a src_node if none was given and this is - * a sticky-address rule. Request the sh to be unlocked if - * sn was not found, as here we never insert a new sn. - */ - if (*sn == NULL) { - if (r->rpool.opts & PF_POOL_STICKYADDR && - (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) - *sn = pf_find_src_node(saddr, r, af, sh, false); - } else { - pf_src_node_exists(sn, *sh); - } + KASSERT(*sn == NULL, ("*sn not NULL")); - /* If a src_node was found or explicitly given and it has a non-zero - route address, use this address. A zeroed address is found if the - src node was created just a moment ago in pf_create_state and it - needs to be filled in with routing decision calculated here. */ - if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { + /* + * If this is a sticky-address rule, try to find an existing src_node. + * Request the sh to be unlocked if sn was not found, as we never + * insert a new sn when parsing the ruleset. + */ + if (r->rpool.opts & PF_POOL_STICKYADDR && + (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) + *sn = pf_find_src_node(saddr, r, af, sh, false); + + if (*sn != NULL) { PF_SRC_NODE_LOCK_ASSERT(*sn); /* If the supplied address is the same as the current one we've @@ -683,14 +677,6 @@ goto done; } - if (*sn != NULL) { - PF_SRC_NODE_LOCK_ASSERT(*sn); - - PF_ACPY(&(*sn)->raddr, naddr, af); - if (nkif) - (*sn)->rkif = *nkif; - } - if (V_pf_status.debug >= PF_DEBUG_NOISY && (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { printf("pf_map_addr: selected address "); diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -173,7 +173,7 @@ nlattr_add_string(nw, PF_ST_IFNAME, s->kif->pfik_name); nlattr_add_string(nw, PF_ST_ORIG_IFNAME, s->orig_kif->pfik_name); - dump_addr(nw, PF_ST_RT_ADDR, &s->rt_addr, af); + dump_addr(nw, PF_ST_RT_ADDR, &s->act.rt_addr, af); nlattr_add_u32(nw, PF_ST_CREATION, time_uptime - (s->creation / 1000)); uint32_t expire = pf_state_expires(s); if (expire > time_uptime) @@ -205,9 +205,9 @@ nlattr_add_u16(nw, PF_ST_MAX_MSS, s->act.max_mss); nlattr_add_u16(nw, PF_ST_DNPIPE, s->act.dnpipe); nlattr_add_u16(nw, PF_ST_DNRPIPE, s->act.dnrpipe); - nlattr_add_u8(nw, PF_ST_RT, s->rt); - if (s->rt_kif != NULL) - nlattr_add_string(nw, PF_ST_RT_IFNAME, s->rt_kif->pfik_name); + nlattr_add_u8(nw, PF_ST_RT, s->act.rt); + if (s->act.rt_kif != NULL) + nlattr_add_string(nw, PF_ST_RT_IFNAME, s->act.rt_kif->pfik_name); if (!dump_state_peer(nw, PF_ST_PEER_SRC, &s->src)) goto enomem; diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -963,7 +963,7 @@ nvlist_add_nvlist(nvl, "dst", tmp); nvlist_destroy(tmp); - tmp = pf_addr_to_nvaddr(&s->rt_addr); + tmp = pf_addr_to_nvaddr(&s->act.rt_addr); if (tmp == NULL) goto errout; nvlist_add_nvlist(nvl, "rt_addr", tmp);