From 418a04b4676ef1730c653057e7bea6e0d8ff06aa Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 4 Jul 2012 07:37:53 +0000 Subject: When ip_output()/ip6_output() is supplied a struct route *ro argument, it skips FLOWTABLE lookup. However, the non-NULL ro has dual meaning here: it may be supplied to provide route, and it may be supplied to store and return to caller the route that ip_output()/ip6_output() finds. In the latter case skipping FLOWTABLE lookup is pessimisation. The difference between struct route filled by FLOWTABLE and filled by rtalloc() family is that the former doesn't hold a reference on its rtentry. Reference is hold by flow entry, and it is about to be released in future. Thus, route filled by FLOWTABLE shouldn't be passed to RTFREE() macro. - Introduce new flag for struct route/route_in6, that marks route not holding a reference on rtentry. - Introduce new macro RO_RTFREE() that cleans up a struct route depending on its kind. - All callers to ip_output()/ip6_output() that do supply non-NULL but empty route should use RO_RTFREE() to free results of lookup. - ip_output()/ip6_output() now do FLOWTABLE lookup always when ro->ro_rt == NULL. Tested by: tuexen (SCTP part) --- sys/netinet6/nd6_nbr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sys/netinet6/nd6_nbr.c') diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 4b80dc2..a203558 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -595,9 +595,9 @@ nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6, icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); ICMP6STAT_INC(icp6s_outhist[ND_NEIGHBOR_SOLICIT]); - if (ro.ro_rt) { /* we don't cache this route. */ - RTFREE(ro.ro_rt); - } + /* We don't cache this route. */ + RO_RTFREE(&ro); + return; bad: @@ -1124,9 +1124,9 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); ICMP6STAT_INC(icp6s_outhist[ND_NEIGHBOR_ADVERT]); - if (ro.ro_rt) { /* we don't cache this route. */ - RTFREE(ro.ro_rt); - } + /* We don't cache this route. */ + RO_RTFREE(&ro); + return; bad: -- cgit v1.1