Hi,

The source address tracking (sticky-address) is kept dulring there are
states which refer it.  This is mentioned in pf.conf(5).  This is true
for translation(nat-to, rdr-to) but it was not true for
routing(route-to).

ok?

Link the state and the source track to keep the source track while
there are states which refer it.

Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1081
diff -u -p -r1.1081 pf.c
--- sys/net/pf.c        20 Mar 2019 20:07:28 -0000      1.1081
+++ sys/net/pf.c        1 Jul 2019 05:15:37 -0000
@@ -222,7 +222,7 @@ int                  pf_test_state_icmp(struct pf_pdes
 u_int16_t               pf_calc_mss(struct pf_addr *, sa_family_t, int,
                            u_int16_t);
 static __inline int     pf_set_rt_ifp(struct pf_state *, struct pf_addr *,
-                           sa_family_t);
+                           sa_family_t, struct pf_src_node **);
 struct pf_divert       *pf_get_divert(struct mbuf *);
 int                     pf_walk_header(struct pf_pdesc *, struct ip *,
                            u_short *);
@@ -3410,17 +3410,16 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
 }
 
 static __inline int
-pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr, sa_family_t af)
+pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr, sa_family_t af,
+    struct pf_src_node **sns)
 {
        struct pf_rule *r = s->rule.ptr;
-       struct pf_src_node *sns[PF_SN_MAX];
        int     rv;
 
        s->rt_kif = NULL;
        if (!r->rt)
                return (0);
 
-       memset(sns, 0, sizeof(sns));
        switch (af) {
        case AF_INET:
                rv = pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, sns,
@@ -4089,6 +4088,11 @@ pf_create_state(struct pf_pdesc *pd, str
                goto csfailed;
        }
 
+       if (pf_set_rt_ifp(s, pd->src, (*skw)->af, sns) != 0) {
+               REASON_SET(&reason, PFRES_NOROUTE);
+               goto csfailed;
+       }
+
        for (i = 0; i < PF_SN_MAX; i++)
                if (sns[i] != NULL) {
                        struct pf_sn_item       *sni;
@@ -4102,11 +4106,6 @@ pf_create_state(struct pf_pdesc *pd, str
                        SLIST_INSERT_HEAD(&s->src_nodes, sni, next);
                        sni->sn->states++;
                }
-
-       if (pf_set_rt_ifp(s, pd->src, (*skw)->af) != 0) {
-               REASON_SET(&reason, PFRES_NOROUTE);
-               goto csfailed;
-       }
 
        if (pf_state_insert(BOUND_IFACE(r, pd->kif), skw, sks, s)) {
                pf_detach_state(s);

Reply via email to