On Mon, Nov 14, 2016 at 04:38:07PM +0100, Alexander Bluhm wrote: > Hi, > > The !r->rt case is only used by af-to. pf_route6() calls ip6_output() > to do the work while pf_route() has some custom implementation for > that. It is simpler to call ip_output() or ip6_output() from > pf_test() directly. > > ok?
anyone? > > bluhm > > Index: net/pf.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v > retrieving revision 1.998 > diff -u -p -r1.998 pf.c > --- net/pf.c 14 Nov 2016 13:25:00 -0000 1.998 > +++ net/pf.c 14 Nov 2016 14:08:57 -0000 > @@ -5820,50 +5820,34 @@ pf_route(struct pf_pdesc *pd, struct pf_ > dst->sin_addr = ip->ip_dst; > rtableid = m0->m_pkthdr.ph_rtableid; > > - if (!r->rt) { > - rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); > - if (rt == NULL) { > - ipstat_inc(ips_noroute); > + if (s == NULL) { > + bzero(sns, 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, > + "pf_route: pf_map_addr() failed."); > goto bad; > } > > - ifp = if_get(rt->rt_ifidx); > - > - if (rt->rt_flags & RTF_GATEWAY) > - dst = satosin(rt->rt_gateway); > - > - m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; > + 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 (s == NULL) { > - bzero(sns, 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, > - "pf_route: pf_map_addr() failed."); > - goto bad; > - } > - > - 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 (rt == NULL) { > - ipstat_inc(ips_noroute); > - goto bad; > - } > + 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; > } > if (ifp == NULL) > goto bad; > > + rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); > + if (rt == NULL) { > + ipstat_inc(ips_noroute); > + goto bad; > + } > > if (pd->kif->pfik_ifp != ifp) { > if (pf_test(AF_INET, PF_OUT, ifp, &m0) != PF_PASS) > @@ -5928,8 +5912,6 @@ pf_route(struct pf_pdesc *pd, struct pf_ > done: > if (r->rt != PF_DUPTO) > pd->m = NULL; > - if (!r->rt) > - if_put(ifp); > rtfree(rt); > return; > > @@ -5982,12 +5964,6 @@ pf_route6(struct pf_pdesc *pd, struct pf > dst->sin6_addr = ip6->ip6_dst; > rtableid = m0->m_pkthdr.ph_rtableid; > > - if (!r->rt) { > - m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; > - ip6_output(m0, NULL, NULL, 0, NULL, NULL); > - goto done; > - } > - > if (s == NULL) { > bzero(sns, sizeof(sns)); > if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, > @@ -6908,10 +6884,28 @@ done: > action = PF_DROP; > break; > } > - if (pd.naf == AF_INET) > - pf_route(&pd, r, s); > - if (pd.naf == AF_INET6) > - pf_route6(&pd, r, s); > + if (r->rt) { > + switch (pd.naf) { > + case AF_INET: > + pf_route(&pd, r, s); > + break; > + case AF_INET6: > + pf_route6(&pd, r, s); > + break; > + } > + } > + if (pd.m) { > + pd.m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; > + switch (pd.naf) { > + case AF_INET: > + ip_output(pd.m, NULL, NULL, 0, NULL, NULL, 0); > + break; > + case AF_INET6: > + ip6_output(pd.m, NULL, NULL, 0, NULL, NULL); > + break; > + } > + pd.m = NULL; > + } > action = PF_PASS; > break; > #endif /* INET6 */