On 26/11/14(Wed) 13:32, Martin Pieuchot wrote: > On 25/11/14(Tue) 15:16, Todd C. Miller wrote: > > On Tue, 25 Nov 2014 16:43:16 +0100, Martin Pieuchot wrote: > > > > > Diff below removes the non-needed usages of "struct route" & friends in > > > pf.c, any comment or ok? > > > > You are missing some initializations of rt to NULL, comments inline. > > Thanks for the reviews todd! This is much appreciated now that network > hacker is a critically endangered specie :) > > You'll find a corrected diff below. Since I was asked to give more > information about this change here's the story: > > We have currently two structures used to cache a route entry in order to > avoid supplementary route lookups: "struct route" and "struct route_in6". > > These structures store a pointer to a rtentry and the destination of > this route. Yes this is duplicated information. There are mainly two > problems with this design. First of all the fact that we have a > structure per AF, when a rtentry is AF agnostic, which results in a lot > of #ifdefs & cast. But the main reason to directly use a "struct rtentry" > instead of these structures is to strengthen & unify the code checking > for the validity of a route. I'd like at least to stop checking against > a cached destination, I'd like to add a check for stall ifa and I'd like > to add a check for reference counters. > > So the first move is to stop using such structure when we don't want to > keep a reference on a route entry, then I'll modify the APIs keeping a > reference and finally add more checks.
And know with the correct diff... Index: net/pf.c =================================================================== RCS file: /home/ncvs/src/sys/net/pf.c,v retrieving revision 1.896 diff -u -p -r1.896 pf.c --- net/pf.c 20 Nov 2014 13:54:24 -0000 1.896 +++ net/pf.c 26 Nov 2014 12:03:13 -0000 @@ -2952,42 +2952,36 @@ pf_calc_mss(struct pf_addr *addr, sa_fam { #ifdef INET struct sockaddr_in *dst; - struct route ro; #endif /* INET */ #ifdef INET6 struct sockaddr_in6 *dst6; - struct route_in6 ro6; #endif /* INET6 */ struct rtentry *rt = NULL; + struct sockaddr_storage ss; int hlen; u_int16_t mss = tcp_mssdflt; + memset(&ss, 0, sizeof(ss)); + switch (af) { #ifdef INET case AF_INET: hlen = sizeof(struct ip); - bzero(&ro, sizeof(ro)); - dst = (struct sockaddr_in *)&ro.ro_dst; + dst = (struct sockaddr_in *)&ss; dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; - ro.ro_tableid = rtableid; - ro.ro_rt = rtalloc(&ro.ro_dst, RT_REPORT, ro.ro_tableid); - rt = ro.ro_rt; + rt = rtalloc(sintosa(dst), RT_REPORT, rtableid); break; #endif /* INET */ #ifdef INET6 case AF_INET6: hlen = sizeof(struct ip6_hdr); - bzero(&ro6, sizeof(ro6)); - dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; + dst6 = (struct sockaddr_in6 *)&ss; dst6->sin6_family = AF_INET6; dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = addr->v6; - ro6.ro_tableid = rtableid; - ro6.ro_rt = rtalloc(sin6tosa(&ro6.ro_dst), RT_REPORT, - ro6.ro_tableid); - rt = ro6.ro_rt; + rt = rtalloc(sin6tosa(dst6), RT_REPORT, rtableid); break; #endif /* INET6 */ } @@ -5396,25 +5390,22 @@ int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, int rtableid) { + struct sockaddr_storage ss; struct sockaddr_in *dst; int ret = 1; int check_mpath; #ifdef INET6 struct sockaddr_in6 *dst6; - struct route_in6 ro; -#else - struct route ro; #endif - struct rtentry *rt; + struct rtentry *rt = NULL; struct ifnet *ifp; check_mpath = 0; - bzero(&ro, sizeof(ro)); - ro.ro_tableid = rtableid; + memset(&ss, 0, sizeof(ss)); switch (af) { #ifdef INET case AF_INET: - dst = (struct sockaddr_in *)&ro.ro_dst; + dst = (struct sockaddr_in *)&ss; dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; @@ -5430,7 +5421,7 @@ pf_routable(struct pf_addr *addr, sa_fam */ if (IN6_IS_SCOPE_EMBED(&addr->v6)) goto out; - dst6 = &ro.ro_dst; + dst6 = (struct sockaddr_in6 *)&ss; dst6->sin6_family = AF_INET6; dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = addr->v6; @@ -5444,10 +5435,8 @@ pf_routable(struct pf_addr *addr, sa_fam if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) goto out; - ro.ro_rt = rtalloc((struct sockaddr *)&ro.ro_dst, RT_REPORT, - ro.ro_tableid); - - if (ro.ro_rt != NULL) { + rt = rtalloc((struct sockaddr *)&ss, RT_REPORT, rtableid); + if (rt != NULL) { /* No interface given, this is a no-route check */ if (kif == NULL) goto out; @@ -5459,7 +5448,6 @@ pf_routable(struct pf_addr *addr, sa_fam /* Perform uRPF check if passed input interface */ ret = 0; - rt = ro.ro_rt; do { if (rt->rt_ifp->if_type == IFT_CARP) ifp = rt->rt_ifp->if_carpdev; @@ -5473,8 +5461,8 @@ pf_routable(struct pf_addr *addr, sa_fam } else ret = 0; out: - if (ro.ro_rt != NULL) - rtfree(ro.ro_rt); + if (rt != NULL) + rtfree(rt); return (ret); } @@ -5482,21 +5470,19 @@ int pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw, int rtableid) { + struct sockaddr_storage ss; struct sockaddr_in *dst; #ifdef INET6 struct sockaddr_in6 *dst6; - struct route_in6 ro; -#else - struct route ro; #endif + struct rtentry *rt; int ret = 0; - bzero(&ro, sizeof(ro)); - ro.ro_tableid = rtableid; + memset(&ss, 0, sizeof(ss)); switch (af) { #ifdef INET case AF_INET: - dst = (struct sockaddr_in *)(&ro.ro_dst); + dst = (struct sockaddr_in *)&ss; dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; @@ -5504,7 +5490,7 @@ pf_rtlabel_match(struct pf_addr *addr, s #endif /* INET */ #ifdef INET6 case AF_INET6: - dst6 = &ro.ro_dst; + dst6 = (struct sockaddr_in6 *)&ss; dst6->sin6_family = AF_INET6; dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = addr->v6; @@ -5512,13 +5498,11 @@ pf_rtlabel_match(struct pf_addr *addr, s #endif /* INET6 */ } - ro.ro_rt = rtalloc((struct sockaddr *)&ro.ro_dst, RT_REPORT, - ro.ro_tableid); - - if (ro.ro_rt != NULL) { - if (ro.ro_rt->rt_labelid == aw->v.rtlabel) + rt = rtalloc((struct sockaddr *)&ss, RT_REPORT|RT_RESOLVE, rtableid); + if (rt != NULL) { + if (rt->rt_labelid == aw->v.rtlabel) ret = 1; - rtfree(ro.ro_rt); + rtfree(rt); } return (ret); @@ -5530,14 +5514,14 @@ pf_route(struct mbuf **m, struct pf_rule struct pf_state *s) { struct mbuf *m0, *m1; - struct route iproute; - struct route *ro = NULL; - struct sockaddr_in *dst; + 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; #ifdef IPSEC struct m_tag *mtag; #endif /* IPSEC */ @@ -5569,27 +5553,25 @@ pf_route(struct mbuf **m, struct pf_rule ip = mtod(m0, struct ip *); - ro = &iproute; - bzero((caddr_t)ro, sizeof(*ro)); - dst = satosin(&ro->ro_dst); + memset(&sin, 0, sizeof(sin)); + dst = &sin; dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = ip->ip_dst; - ro->ro_tableid = m0->m_pkthdr.ph_rtableid; + rtableid = m0->m_pkthdr.ph_rtableid; if (!r->rt) { - ro->ro_rt = rtalloc(&ro->ro_dst, RT_REPORT|RT_RESOLVE, - ro->ro_tableid); - if (ro->ro_rt == 0) { + rt = rtalloc(sintosa(dst), RT_REPORT|RT_RESOLVE, rtableid); + if (rt == NULL) { ipstat.ips_noroute++; goto bad; } - ifp = ro->ro_rt->rt_ifp; - ro->ro_rt->rt_use++; + ifp = rt->rt_ifp; + rt->rt_use++; - if (ro->ro_rt->rt_flags & RTF_GATEWAY) - dst = satosin(ro->ro_rt->rt_gateway); + if (rt->rt_flags & RTF_GATEWAY) + dst = satosin(rt->rt_gateway); m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; } else { @@ -5695,8 +5677,8 @@ pf_route(struct mbuf **m, struct pf_rule done: if (r->rt != PF_DUPTO) *m = NULL; - if (ro == &iproute && ro->ro_rt) - rtfree(ro->ro_rt); + if (rt != NULL) + rtfree(rt); return; bad: @@ -5711,13 +5693,12 @@ pf_route6(struct mbuf **m, struct pf_rul struct pf_state *s) { struct mbuf *m0; - struct route_in6 ip6route; - struct route_in6 *ro; - struct sockaddr_in6 *dst; + struct sockaddr_in6 *dst, sin6; struct ip6_hdr *ip6; struct ifnet *ifp = NULL; struct pf_addr naddr; struct pf_src_node *sns[PF_SN_MAX]; + unsigned int rtableid; if (m == NULL || *m == NULL || r == NULL || (dir != PF_IN && dir != PF_OUT) || oifp == NULL) @@ -5745,13 +5726,12 @@ pf_route6(struct mbuf **m, struct pf_rul } ip6 = mtod(m0, struct ip6_hdr *); - ro = &ip6route; - bzero((caddr_t)ro, sizeof(*ro)); - dst = (struct sockaddr_in6 *)&ro->ro_dst; + memset(&sin6, 0, sizeof(sin6)); + dst = &sin6; dst->sin6_family = AF_INET6; dst->sin6_len = sizeof(*dst); dst->sin6_addr = ip6->ip6_dst; - ro->ro_tableid = m0->m_pkthdr.ph_rtableid; + rtableid = m0->m_pkthdr.ph_rtableid; if (!r->rt) { m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;