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 */