On Mon, Jan 04, 2021 at 11:46:16AM +0100, Alexandr Nedvedicky wrote:
> > let's put this in and then i'll have a look. ok by me.
>     bluhm's diff is fine with me.

Refactoring is commited, here is the remaining kernel diff after merge.

bluhm

Index: net/if_pfsync.c
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.280
diff -u -p -r1.280 if_pfsync.c
--- net/if_pfsync.c     4 Jan 2021 12:48:27 -0000       1.280
+++ net/if_pfsync.c     4 Jan 2021 12:52:01 -0000
@@ -613,6 +613,7 @@ pfsync_state_import(struct pfsync_state 
 
        /* copy to state */
        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;
@@ -1857,7 +1857,7 @@ pfsync_undefer(struct pfsync_deferral *p
        if (drop)
                m_freem(pd->pd_m);
        else {
-               if (st->rule.ptr->rt == PF_ROUTETO) {
+               if (st->rt == PF_ROUTETO) {
                        if (pf_setup_pdesc(&pdesc, st->key[PF_SK_WIRE]->af,
                            st->direction, st->kif, pd->pd_m, NULL) !=
                            PF_PASS) {
@@ -1866,11 +1866,11 @@ pfsync_undefer(struct pfsync_deferral *p
                        }
                        switch (st->key[PF_SK_WIRE]->af) {
                        case AF_INET:
-                               pf_route(&pdesc, st->rule.ptr, st);
+                               pf_route(&pdesc, st);
                                break;
 #ifdef INET6
                        case AF_INET6:
-                               pf_route6(&pdesc, st->rule.ptr, st);
+                               pf_route6(&pdesc, st);
                                break;
 #endif /* INET6 */
                        default:
Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1097
diff -u -p -r1.1097 pf.c
--- net/pf.c    4 Jan 2021 12:48:27 -0000       1.1097
+++ net/pf.c    4 Jan 2021 12:52:02 -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,6 +1180,7 @@ pf_state_export(struct pfsync_state *sp,
 
        /* copy from state */
        strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+       sp->rt = st->rt;
        sp->rt_addr = st->rt_addr;
        sp->creation = htonl(getuptime() - st->creation);
        expire = pf_state_expires(st);
@@ -3433,16 +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);
 
        rv = pf_map_addr(af, r, saddr, &s->rt_addr, NULL, sns, 
            &r->route, PF_SN_ROUTE);
-       if (rv == 0) {
-               s->rt_kif = r->route.kif;
-               s->natrule.ptr = r;
-       }
+       if (rv == 0)
+               s->rt = r->rt;
 
        return (rv);
 }
@@ -5973,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;
 
@@ -5991,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;
        }
@@ -6008,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;
 
@@ -6061,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)
@@ -6092,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;
        }
 
@@ -6118,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;
 
@@ -6131,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;
 
@@ -6149,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;
        }
@@ -6165,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;
 
@@ -6218,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)
@@ -6240,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;
 
@@ -7275,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: net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.497
diff -u -p -r1.497 pfvar.h
--- net/pfvar.h 14 Oct 2020 19:22:14 -0000      1.497
+++ net/pfvar.h 4 Jan 2021 12:52:02 -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);
 

Reply via email to