Index: sys/net/if_pfsync.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_pfsync.c,v retrieving revision 1.279 diff -u -p -u -p -r1.279 if_pfsync.c --- sys/net/if_pfsync.c 12 Dec 2020 11:49:02 -0000 1.279 +++ sys/net/if_pfsync.c 3 Jan 2021 15:11:41 -0000 @@ -612,7 +612,8 @@ pfsync_state_import(struct pfsync_state st->rtableid[PF_SK_STACK] = ntohl(sp->rtableid[PF_SK_STACK]); /* copy to state */ - bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); + st->rt_addr = sp->rt_addr; + st->rt = sp->rt; st->creation = getuptime() - ntohl(sp->creation); st->expire = getuptime(); if (ntohl(sp->expire)) { @@ -643,7 +644,6 @@ pfsync_state_import(struct pfsync_state st->rule.ptr = r; st->anchor.ptr = NULL; - st->rt_kif = NULL; st->pfsync_time = getuptime(); st->sync_state = PFSYNC_S_NONE; @@ -1843,6 +1843,7 @@ pfsync_undefer(struct pfsync_deferral *p { struct pfsync_softc *sc = pfsyncif; struct pf_pdesc pdesc; + struct pf_state *s = pd->pd_st; NET_ASSERT_LOCKED(); @@ -1852,35 +1853,33 @@ pfsync_undefer(struct pfsync_deferral *p TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry); sc->sc_deferred--; - CLR(pd->pd_st->state_flags, PFSTATE_ACK); + CLR(s->state_flags, PFSTATE_ACK); if (drop) m_freem(pd->pd_m); else { - if (pd->pd_st->rule.ptr->rt == PF_ROUTETO) { + if (s->rt == PF_ROUTETO) { if (pf_setup_pdesc(&pdesc, - pd->pd_st->key[PF_SK_WIRE]->af, - pd->pd_st->direction, pd->pd_st->rt_kif, + s->key[PF_SK_WIRE]->af, + s->direction, s->kif, pd->pd_m, NULL) != PF_PASS) { m_freem(pd->pd_m); goto out; } - switch (pd->pd_st->key[PF_SK_WIRE]->af) { + switch (s->key[PF_SK_WIRE]->af) { case AF_INET: - pf_route(&pdesc, - pd->pd_st->rule.ptr, pd->pd_st); + pf_route(&pdesc, s); break; #ifdef INET6 case AF_INET6: - pf_route6(&pdesc, - pd->pd_st->rule.ptr, pd->pd_st); + pf_route6(&pdesc, s); break; #endif /* INET6 */ default: - unhandled_af(pd->pd_st->key[PF_SK_WIRE]->af); + unhandled_af(s->key[PF_SK_WIRE]->af); } pd->pd_m = pdesc.m; } else { - switch (pd->pd_st->key[PF_SK_WIRE]->af) { + switch (s->key[PF_SK_WIRE]->af) { case AF_INET: ip_output(pd->pd_m, NULL, NULL, 0, NULL, NULL, 0); @@ -1892,12 +1891,12 @@ pfsync_undefer(struct pfsync_deferral *p break; #endif /* INET6 */ default: - unhandled_af(pd->pd_st->key[PF_SK_WIRE]->af); + unhandled_af(s->key[PF_SK_WIRE]->af); } } } out: - pf_state_unref(pd->pd_st); + pf_state_unref(s); pool_put(&sc->sc_pool, pd); } Index: sys/net/pf.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/pf.c,v retrieving revision 1.1096 diff -u -p -u -p -r1.1096 pf.c --- sys/net/pf.c 10 Dec 2020 06:40:22 -0000 1.1096 +++ sys/net/pf.c 3 Jan 2021 15:11:42 -0000 @@ -1122,12 +1122,6 @@ pf_find_state(struct pf_pdesc *pd, struc } *state = s; - if (pd->dir == PF_OUT && s->rt_kif != NULL && s->rt_kif != pd->kif && - ((s->rule.ptr->rt == PF_ROUTETO && - s->rule.ptr->direction == PF_OUT) || - (s->rule.ptr->rt == PF_REPLYTO && - s->rule.ptr->direction == PF_IN))) - return (PF_PASS); return (PF_MATCH); } @@ -1186,7 +1180,8 @@ pf_state_export(struct pfsync_state *sp, /* copy from state */ strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); - memcpy(&sp->rt_addr, &st->rt_addr, sizeof(sp->rt_addr)); + sp->rt = st->rt; + sp->rt_addr = st->rt_addr; sp->creation = htonl(getuptime() - st->creation); expire = pf_state_expires(st); if (expire <= getuptime()) @@ -3433,29 +3428,13 @@ pf_set_rt_ifp(struct pf_state *s, struct struct pf_rule *r = s->rule.ptr; int rv; - s->rt_kif = NULL; - if (!r->rt) + if (r->rt == PF_NOPFROUTE) return (0); - switch (af) { - case AF_INET: - rv = pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, sns, - &r->route, PF_SN_ROUTE); - break; -#ifdef INET6 - case AF_INET6: - rv = pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, sns, - &r->route, PF_SN_ROUTE); - break; -#endif /* INET6 */ - default: - rv = 1; - } - - if (rv == 0) { - s->rt_kif = r->route.kif; - s->natrule.ptr = r; - } + rv = pf_map_addr(af, r, saddr, &s->rt_addr, NULL, sns, + &r->route, PF_SN_ROUTE); + if (rv == 0) + s->rt = r->rt; return (rv); } @@ -5986,15 +5965,13 @@ pf_rtlabel_match(struct pf_addr *addr, s /* pf_route() may change pd->m, adjust local copies after calling */ void -pf_route(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s) +pf_route(struct pf_pdesc *pd, struct pf_state *s) { struct mbuf *m0, *m1; struct sockaddr_in *dst, sin; struct rtentry *rt = NULL; struct ip *ip; struct ifnet *ifp = NULL; - struct pf_addr naddr; - struct pf_src_node *sns[PF_SN_MAX]; int error = 0; unsigned int rtableid; @@ -6004,11 +5981,11 @@ pf_route(struct pf_pdesc *pd, struct pf_ return; } - if (r->rt == PF_DUPTO) { + if (s->rt == PF_DUPTO) { if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL) return; } else { - if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir)) + if ((s->rt == PF_REPLYTO) == (s->direction == pd->dir)) return; m0 = pd->m; } @@ -6021,44 +5998,31 @@ pf_route(struct pf_pdesc *pd, struct pf_ ip = mtod(m0, struct ip *); - memset(&sin, 0, sizeof(sin)); - dst = &sin; - dst->sin_family = AF_INET; - dst->sin_len = sizeof(*dst); - dst->sin_addr = ip->ip_dst; - rtableid = m0->m_pkthdr.ph_rtableid; - if (pd->dir == PF_IN) { if (ip->ip_ttl <= IPTTLDEC) { - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pf_send_icmp(m0, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, - pd->af, r, pd->rdomain); + pd->af, s->rule.ptr, pd->rdomain); goto bad; } ip->ip_ttl -= IPTTLDEC; } - if (s == NULL) { - memset(sns, 0, sizeof(sns)); - if (pf_map_addr(AF_INET, r, - (struct pf_addr *)&ip->ip_src, - &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) { - DPFPRINTF(LOG_ERR, - "%s: pf_map_addr() failed", __func__); - goto bad; - } + memset(&sin, 0, sizeof(sin)); + dst = &sin; + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr.s_addr = s->rt_addr.v4.s_addr; + rtableid = m0->m_pkthdr.ph_rtableid; - if (!PF_AZERO(&naddr, AF_INET)) - dst->sin_addr.s_addr = naddr.v4.s_addr; - ifp = r->route.kif ? - r->route.kif->pfik_ifp : NULL; - } else { - 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; + rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); + if (!rtisvalid(rt)) { + ipstat_inc(ips_noroute); + goto bad; } + + ifp = if_get(rt->rt_ifidx); if (ifp == NULL) goto bad; @@ -6074,12 +6038,6 @@ pf_route(struct pf_pdesc *pd, struct pf_ } ip = mtod(m0, struct ip *); } - - rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); - if (!rtisvalid(rt)) { - ipstat_inc(ips_noroute); - goto bad; - } /* A locally generated packet may have invalid source address. */ if ((ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET && (ifp->if_flags & IFF_LOOPBACK) == 0) @@ -6105,9 +6063,9 @@ pf_route(struct pf_pdesc *pd, struct pf_ */ if (ip->ip_off & htons(IP_DF)) { ipstat_inc(ips_cantfrag); - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pf_send_icmp(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, - ifp->if_mtu, pd->af, r, pd->rdomain); + ifp->if_mtu, pd->af, s->rule.ptr, pd->rdomain); goto bad; } @@ -6131,8 +6089,9 @@ pf_route(struct pf_pdesc *pd, struct pf_ ipstat_inc(ips_fragmented); done: - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pd->m = NULL; + if_put(ifp); rtfree(rt); return; @@ -6144,15 +6103,13 @@ bad: #ifdef INET6 /* pf_route6() may change pd->m, adjust local copies after calling */ void -pf_route6(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s) +pf_route6(struct pf_pdesc *pd, struct pf_state *s) { struct mbuf *m0; struct sockaddr_in6 *dst, sin6; struct rtentry *rt = NULL; struct ip6_hdr *ip6; struct ifnet *ifp = NULL; - struct pf_addr naddr; - struct pf_src_node *sns[PF_SN_MAX]; struct m_tag *mtag; unsigned int rtableid; @@ -6162,11 +6119,11 @@ pf_route6(struct pf_pdesc *pd, struct pf return; } - if (r->rt == PF_DUPTO) { + if (s->rt == PF_DUPTO) { if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL) return; } else { - if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir)) + if ((s->rt == PF_REPLYTO) == (s->direction == pd->dir)) return; m0 = pd->m; } @@ -6178,42 +6135,31 @@ pf_route6(struct pf_pdesc *pd, struct pf } ip6 = mtod(m0, struct ip6_hdr *); - memset(&sin6, 0, sizeof(sin6)); - dst = &sin6; - dst->sin6_family = AF_INET6; - dst->sin6_len = sizeof(*dst); - dst->sin6_addr = ip6->ip6_dst; - rtableid = m0->m_pkthdr.ph_rtableid; - if (pd->dir == PF_IN) { if (ip6->ip6_hlim <= IPV6_HLIMDEC) { - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pf_send_icmp(m0, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT, 0, - pd->af, r, pd->rdomain); + pd->af, s->rule.ptr, pd->rdomain); goto bad; } ip6->ip6_hlim -= IPV6_HLIMDEC; } - if (s == NULL) { - memset(sns, 0, sizeof(sns)); - if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, - &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) { - DPFPRINTF(LOG_ERR, - "%s: pf_map_addr() failed", __func__); - goto bad; - } - if (!PF_AZERO(&naddr, AF_INET6)) - pf_addrcpy((struct pf_addr *)&dst->sin6_addr, - &naddr, AF_INET6); - ifp = r->route.kif ? r->route.kif->pfik_ifp : NULL; - } else { - if (!PF_AZERO(&s->rt_addr, AF_INET6)) - pf_addrcpy((struct pf_addr *)&dst->sin6_addr, - &s->rt_addr, AF_INET6); - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; + memset(&sin6, 0, sizeof(sin6)); + dst = &sin6; + dst->sin6_family = AF_INET6; + dst->sin6_len = sizeof(*dst); + pf_addrcpy((struct pf_addr *)&dst->sin6_addr, &s->rt_addr, AF_INET6); + rtableid = m0->m_pkthdr.ph_rtableid; + + rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid); + if (!rtisvalid(rt)) { + ip6stat_inc(ip6s_noroute); + goto bad; } + + ifp = if_get(rt->rt_ifidx); if (ifp == NULL) goto bad; @@ -6231,11 +6177,7 @@ pf_route6(struct pf_pdesc *pd, struct pf if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); - rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid); - if (!rtisvalid(rt)) { - ip6stat_inc(ip6s_noroute); - goto bad; - } + /* A locally generated packet may have invalid source address. */ if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) && (ifp->if_flags & IFF_LOOPBACK) == 0) @@ -6253,15 +6195,16 @@ pf_route6(struct pf_pdesc *pd, struct pf ifp->if_output(ifp, m0, sin6tosa(dst), rt); } else { ip6stat_inc(ip6s_cantfrag); - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0, - ifp->if_mtu, pd->af, r, pd->rdomain); + ifp->if_mtu, pd->af, s->rule.ptr, pd->rdomain); goto bad; } done: - if (r->rt != PF_DUPTO) + if (s->rt != PF_DUPTO) pd->m = NULL; + if_put(ifp); rtfree(rt); return; @@ -6271,7 +6214,6 @@ bad: } #endif /* INET6 */ - /* * check TCP checksum and set mbuf flag * off is the offset where the protocol header starts @@ -7289,14 +7231,14 @@ done: pd.m = NULL; break; default: - if (r->rt) { + if (s && s->rt) { switch (pd.af) { case AF_INET: - pf_route(&pd, r, s); + pf_route(&pd, s); break; #ifdef INET6 case AF_INET6: - pf_route6(&pd, r, s); + pf_route6(&pd, s); break; #endif /* INET6 */ } Index: sys/net/pfvar.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/pfvar.h,v retrieving revision 1.497 diff -u -p -u -p -r1.497 pfvar.h --- sys/net/pfvar.h 14 Oct 2020 19:22:14 -0000 1.497 +++ sys/net/pfvar.h 3 Jan 2021 15:11:42 -0000 @@ -762,7 +762,6 @@ struct pf_state { struct pf_sn_head src_nodes; struct pf_state_key *key[2]; /* addresses stack and wire */ struct pfi_kif *kif; - struct pfi_kif *rt_kif; u_int64_t packets[2]; u_int64_t bytes[2]; int32_t creation; @@ -797,6 +796,7 @@ struct pf_state { u_int16_t if_index_out; pf_refcnt_t refcnt; u_int16_t delay; + u_int8_t rt; }; /* @@ -852,7 +852,7 @@ struct pfsync_state { u_int8_t proto; u_int8_t direction; u_int8_t log; - u_int8_t pad0; + u_int8_t rt; u_int8_t timeout; u_int8_t sync_flags; u_int8_t updates; @@ -1798,8 +1798,8 @@ int pf_state_key_attach(struct pf_state_ int pf_translate(struct pf_pdesc *, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t, u_int16_t, int); int pf_translate_af(struct pf_pdesc *); -void pf_route(struct pf_pdesc *, struct pf_rule *, struct pf_state *); -void pf_route6(struct pf_pdesc *, struct pf_rule *, struct pf_state *); +void pf_route(struct pf_pdesc *, struct pf_state *); +void pf_route6(struct pf_pdesc *, struct pf_state *); void pf_init_threshold(struct pf_threshold *, u_int32_t, u_int32_t); int pf_delay_pkt(struct mbuf *, u_int);