Subject: Re: works in progress: route cache invalidation, RADIX_MPATH
To: None <tech-net@NetBSD.org>
From: David Young <dyoung@pobox.com>
List: tech-net
Date: 12/09/2006 03:04:30
--oTHb8nViIGeoXxdp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Fri, Dec 08, 2006 at 11:21:00PM -0600, David Young wrote:
> On Sat, Dec 09, 2006 at 01:09:16AM +0100, Joerg Sonnenberger wrote:
> > On Thu, Nov 16, 2006 at 01:33:30PM -0600, David Young wrote:
> > > * Route-cache invalidation
> >
> > ftp://ftp.netbsd.org/pub/NetBSD/misc/joerg/rtcache.diff
> >
> > This is part one to actually do this. The difference to David's approach
> > is that I want to actually abstract the route cache (re)validation and
> > ultimately avoid doing the domain specific flushing.
> >
> > The patch starts this by changing all the proper rtfree calls to the new
> > API and starts to adjust the various updates. The next part will add
> > rtcache_check() calls in the various places where the cached route is
> > accessed and enforcing the calls to rtcache_init().
>
> Joerg,
>
> I like what you have done here, but your work (and by that I mean the
> analysis of the code, and to a lesser extent, the subroutines extracted)
> and mine appear to be essentially the same. I am going to commit my
> work, which I have tested and found to solve the problem it was designed
> to solve, and then begin the mechanical changes that are necessary to
> reconcile your patches with mine. I hope to avoid impeding your work
> at abstracting the route cache, which is very desirable, but it may be
> necessary for me to sleep before I finish reconciling the patches.
I applied your patch manually. Here are diffs against -current of
9 December. I can compile GENERIC/i386, but that's not the best
compile-test. I haven't tried running these patches, yet.
Dave
--
David Young OJC Technologies
dyoung@ojctech.com Urbana, IL * (217) 278-3933
--oTHb8nViIGeoXxdp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="rtcache-2.diff"
Index: dist/ipf/netinet/ip_fil_netbsd.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_fil_netbsd.c,v
retrieving revision 1.29
diff -p -u -u -p -r1.29 ip_fil_netbsd.c
--- dist/ipf/netinet/ip_fil_netbsd.c 9 Dec 2006 05:33:06 -0000 1.29
+++ dist/ipf/netinet/ip_fil_netbsd.c 9 Dec 2006 08:56:26 -0000
@@ -1424,9 +1424,7 @@ done:
else
fr_frouteok[1]++;
- if (ro->ro_rt != NULL) {
- rtflush(ro);
- }
+ rtcache_free(ro);
*mpp = NULL;
return error;
bad:
@@ -1521,9 +1519,7 @@ frdest_t *fdp;
}
}
bad:
- if (ro->ro_rt != NULL) {
- rtflush((struct route *)ro);
- }
+ rtcache_free((struct route *)ro);
return error;
}
#endif
Index: dist/pf/net/pf.c
===================================================================
RCS file: /cvsroot/src/sys/dist/pf/net/pf.c,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 pf.c
--- dist/pf/net/pf.c 9 Dec 2006 05:33:06 -0000 1.32
+++ dist/pf/net/pf.c 9 Dec 2006 08:56:28 -0000
@@ -2736,14 +2736,14 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
#ifdef __OpenBSD__
rtalloc_noclone(rop, NO_CLONING);
#else
- rtalloc(rop);
+ rtcache_init(rop);
#endif
- rt = rop->ro_rt;
+ rt = rt;
- if (rt && rt->rt_ifp) {
- mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
+ if (rop->ro_rt != NULL) {
+ mss = rop->ro_rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
mss = max(tcp_mssdflt, mss);
- RTFREE(rt);
+ rtcache_free(rop);
}
mss = min(mss, offer);
mss = max(mss, 64); /* sanity - at least max opt space */
@@ -5302,14 +5302,18 @@ pf_routable(struct pf_addr *addr, sa_fam
#ifdef __OpenBSD__
rtalloc_noclone((struct route *)&ro, NO_CLONING);
-#else
- rtalloc((struct route *)&ro);
-#endif
if (ro.ro_rt != NULL) {
- rtflush((struct route *)&ro);
+ RTFREE((struct route *)&ro);
return (1);
}
+#else
+ rtcache_init((struct route *)&ro);
+ if (ro.ro_rt != NULL) {
+ rtcache_free((struct route *)&ro);
+ return (1);
+ }
+#endif
return (0);
}
@@ -5318,6 +5322,7 @@ int
pf_rtlabel_match(struct pf_addr *addr, sa_family_t af,
struct pf_addr_wrap *aw)
{
+#if 0
struct sockaddr_in *dst;
#ifdef INET6
struct sockaddr_in6 *dst6;
@@ -5350,7 +5355,7 @@ pf_rtlabel_match(struct pf_addr *addr, s
#ifdef __OpenBSD__
rtalloc_noclone((struct route *)&ro, NO_CLONING);
#else
- rtalloc((struct route *)&ro);
+ rtcache_init((struct route *)&ro);
#endif
if (ro.ro_rt != NULL) {
@@ -5362,6 +5367,9 @@ pf_rtlabel_match(struct pf_addr *addr, s
}
return (ret);
+#else
+ return 0;
+#endif
}
#ifdef INET
@@ -5427,8 +5435,8 @@ pf_route(struct mbuf **m, struct pf_rule
dst->sin_addr = ip->ip_dst;
if (r->rt == PF_FASTROUTE) {
- rtalloc(ro);
- if (ro->ro_rt == 0) {
+ rtcache_init(ro);
+ if (ro->ro_rt == NULL) {
ipstat.ips_noroute++;
goto bad;
}
@@ -5575,8 +5583,8 @@ pf_route(struct mbuf **m, struct pf_rule
done:
if (r->rt != PF_DUPTO)
*m = NULL;
- if (ro == &iproute && ro->ro_rt)
- rtflush(ro);
+ if (ro != NULL)
+ rtcache_free(ro);
return;
bad:
Index: net/if_etherip.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_etherip.c,v
retrieving revision 1.3
diff -p -u -u -p -r1.3 if_etherip.c
--- net/if_etherip.c 24 Nov 2006 01:04:30 -0000 1.3
+++ net/if_etherip.c 9 Dec 2006 08:56:29 -0000
@@ -216,7 +216,6 @@ etherip_attach(struct device *parent, st
#endif
sc->sc_src = NULL;
sc->sc_dst = NULL;
- sc->sc_route_expire = 0;
/*
* In order to obtain unique initial Ethernet address on a host,
Index: net/if_etherip.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_etherip.h,v
retrieving revision 1.1
diff -p -u -u -p -r1.1 if_etherip.h
--- net/if_etherip.h 23 Nov 2006 04:07:07 -0000 1.1
+++ net/if_etherip.h 9 Dec 2006 08:56:29 -0000
@@ -56,7 +56,6 @@ struct etherip_softc {
struct route_in6 scr_ro6; /* cached inet6 route */
#endif
} sc_scr;
- long sc_route_expire;
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
void *sc_si; /* softintr handle */
#endif
Index: net/if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.79
diff -p -u -u -p -r1.79 if_gre.c
--- net/if_gre.c 9 Dec 2006 06:32:58 -0000 1.79
+++ net/if_gre.c 9 Dec 2006 08:56:29 -0000
@@ -1023,8 +1023,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd,
closef(sc->sc_fp, l);
sc->sc_fp = NULL;
}
- if (sc->route.ro_rt != NULL)
- rtflush(&sc->route);
+ rtcache_free(&sc->route);
if (sc->sc_proto == IPPROTO_UDP)
error = gre_kick(sc);
else if (gre_compute_route(sc) == 0)
Index: net/if_stf.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_stf.c,v
retrieving revision 1.55
diff -p -u -u -p -r1.55 if_stf.c
--- net/if_stf.c 9 Dec 2006 05:33:06 -0000 1.55
+++ net/if_stf.c 9 Dec 2006 08:56:29 -0000
@@ -418,17 +418,16 @@ stf_output(struct ifnet *ifp, struct mbu
dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst;
if (dst4->sin_family != AF_INET ||
- bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) {
- /* cache route doesn't match */
+ bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0)
+ rtcache_free(&sc->sc_ro);
+ else
+ rtcache_check(&sc->sc_ro);
+
+ if (sc->sc_ro.ro_rt == NULL) {
dst4->sin_family = AF_INET;
dst4->sin_len = sizeof(struct sockaddr_in);
bcopy(&ip->ip_dst, &dst4->sin_addr, sizeof(dst4->sin_addr));
- if (sc->sc_ro.ro_rt != NULL)
- rtflush(&sc->sc_ro);
- }
-
- if (sc->sc_ro.ro_rt == NULL) {
- rtalloc(&sc->sc_ro);
+ rtcache_init(&sc->sc_ro);
if (sc->sc_ro.ro_rt == NULL) {
m_freem(m);
ifp->if_oerrors++;
@@ -436,6 +435,14 @@ stf_output(struct ifnet *ifp, struct mbu
}
}
+ /* If the route constitutes infinite encapsulation, punt. */
+ if (sc->sc_ro.ro_rt->rt_ifp == ifp) {
+ rtcache_free(&sc->sc_ro);
+ m_freem(m);
+ ifp->if_oerrors++;
+ return ENETUNREACH;
+ }
+
ifp->if_opackets++;
return ip_output(m, NULL, &sc->sc_ro, 0,
(struct ip_moptions *)NULL, (struct socket *)NULL);
Index: net/route.c
===================================================================
RCS file: /cvsroot/src/sys/net/route.c,v
retrieving revision 1.82
diff -p -u -u -p -r1.82 route.c
--- net/route.c 9 Dec 2006 05:33:06 -0000 1.82
+++ net/route.c 9 Dec 2006 08:56:32 -0000
@@ -1084,3 +1084,30 @@ rt_timer_timer(void *arg)
callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
}
+
+void
+rtcache_init(struct route *ro)
+{
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 1);
+}
+
+void
+rtcache_init_noclone(struct route *ro)
+{
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 0);
+}
+
+void
+rtcache_free(struct route *ro)
+{
+ if (ro->ro_rt != NULL)
+ rtfree(ro->ro_rt);
+ ro->ro_rt = NULL;
+}
+
+void
+rtcache_update(struct route *ro)
+{
+ rtcache_free(ro);
+ rtcache_init(ro);
+}
Index: net/route.h
===================================================================
RCS file: /cvsroot/src/sys/net/route.h,v
retrieving revision 1.48
diff -p -u -u -p -r1.48 route.h
--- net/route.h 9 Dec 2006 05:33:06 -0000 1.48
+++ net/route.h 9 Dec 2006 08:56:32 -0000
@@ -334,5 +334,21 @@ RTFREE(struct rtentry *rt)
struct ifaddr *rt_get_ifa(struct rtentry *);
void rt_replace_ifa(struct rtentry *, struct ifaddr *);
+void rtcache_init(struct route *);
+void rtcache_init_noclone(struct route *);
+void rtcache_update(struct route *);
+void rtcache_free(struct route *);
+
+static inline void
+rtcache_check(struct route *ro)
+{
+ /* XXX The rt_ifp check should be asserted. */
+ if (ro->ro_rt != NULL &&
+ ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
+ ro->ro_rt->rt_ifp == NULL))
+ rtcache_update(ro);
+ KASSERT(ro->ro_rt == NULL || ro->ro_rt->rt_ifp != NULL);
+}
+
#endif /* _KERNEL */
#endif /* !_NET_ROUTE_H_ */
Index: netatalk/ddp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netatalk/ddp_input.c,v
retrieving revision 1.11
diff -p -u -u -p -r1.11 ddp_input.c
--- netatalk/ddp_input.c 11 Dec 2005 12:24:54 -0000 1.11
+++ netatalk/ddp_input.c 9 Dec 2006 08:56:33 -0000
@@ -267,16 +267,12 @@ ddp_input(m, ifp, elh, phase)
m_freem(m);
return;
}
- if (forwro.ro_rt &&
- (satosat(&forwro.ro_dst)->sat_addr.s_net !=
- to.sat_addr.s_net ||
- satosat(&forwro.ro_dst)->sat_addr.s_node !=
- to.sat_addr.s_node)) {
- RTFREE(forwro.ro_rt);
- forwro.ro_rt = (struct rtentry *) 0;
- }
- if (forwro.ro_rt == (struct rtentry *) 0 ||
- forwro.ro_rt->rt_ifp == (struct ifnet *) 0) {
+ if (satosat(&forwro.ro_dst)->sat_addr.s_net != to.sat_addr.s_net ||
+ satosat(&forwro.ro_dst)->sat_addr.s_node != to.sat_addr.s_node)
+ rtcache_free(&forwro);
+ else
+ rtcache_check(&forwro);
+ if (forwro.ro_rt == NULL) {
bzero(&forwro.ro_dst, sizeof(struct sockaddr_at));
forwro.ro_dst.sa_len = sizeof(struct sockaddr_at);
forwro.ro_dst.sa_family = AF_APPLETALK;
@@ -284,7 +280,7 @@ ddp_input(m, ifp, elh, phase)
to.sat_addr.s_net;
satosat(&forwro.ro_dst)->sat_addr.s_node =
to.sat_addr.s_node;
- rtalloc(&forwro);
+ rtcache_init(&forwro);
}
if (to.sat_addr.s_net !=
satosat(&forwro.ro_dst)->sat_addr.s_net &&
Index: netinet/in_gif.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_gif.c,v
retrieving revision 1.52
diff -p -u -u -p -r1.52 in_gif.c
--- netinet/in_gif.c 9 Dec 2006 05:33:04 -0000 1.52
+++ netinet/in_gif.c 9 Dec 2006 08:56:33 -0000
@@ -180,28 +180,27 @@ in_gif_output(struct ifnet *ifp, int fam
bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
if (dst->sin_family != sin_dst->sin_family ||
- !in_hosteq(dst->sin_addr, sin_dst->sin_addr)) {
- /* cache route doesn't match */
+ !in_hosteq(dst->sin_addr, sin_dst->sin_addr))
+ rtcache_free(&sc->gif_ro);
+ else
+ rtcache_check(&sc->gif_ro);
+
+ if (sc->gif_ro.ro_rt == NULL) {
bzero(dst, sizeof(*dst));
dst->sin_family = sin_dst->sin_family;
dst->sin_len = sizeof(struct sockaddr_in);
dst->sin_addr = sin_dst->sin_addr;
- if (sc->gif_ro.ro_rt != NULL)
- rtflush(&sc->gif_ro);
- }
-
- if (sc->gif_ro.ro_rt == NULL) {
- rtalloc(&sc->gif_ro);
+ rtcache_init(&sc->gif_ro);
if (sc->gif_ro.ro_rt == NULL) {
m_freem(m);
return ENETUNREACH;
}
+ }
- /* if it constitutes infinite encapsulation, punt. */
- if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
- m_freem(m);
- return ENETUNREACH; /*XXX*/
- }
+ /* if it constitutes infinite encapsulation, punt. */
+ if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
+ m_freem(m);
+ return ENETUNREACH; /*XXX*/
}
error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL);
@@ -409,8 +408,7 @@ in_gif_detach(struct gif_softc *sc)
if (error == 0)
sc->encap_cookie4 = NULL;
- if (sc->gif_ro.ro_rt != NULL)
- rtflush(&sc->gif_ro);
+ rtcache_free(&sc->gif_ro);
return error;
}
Index: netinet/in_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_pcb.c,v
retrieving revision 1.111
diff -p -u -u -p -r1.111 in_pcb.c
--- netinet/in_pcb.c 9 Dec 2006 05:33:04 -0000 1.111
+++ netinet/in_pcb.c 9 Dec 2006 08:56:33 -0000
@@ -495,8 +495,7 @@ in_pcbdetach(void *v)
sofree(so);
if (inp->inp_options)
(void)m_free(inp->inp_options);
- if (inp->inp_route.ro_rt != NULL)
- rtflush(&inp->inp_route);
+ rtcache_free(&inp->inp_route);
ip_freemoptions(inp->inp_moptions);
s = splnet();
in_pcbstate(inp, INP_ATTACHED);
@@ -688,7 +687,7 @@ in_losing(struct inpcb *inp)
* A new route can be allocated
* the next time output is attempted.
*/
- rtflush(&inp->inp_route);
+ rtcache_free(&inp->inp_route);
}
}
@@ -703,8 +702,7 @@ in_rtchange(struct inpcb *inp, int errno
if (inp->inp_af != AF_INET)
return;
- if (inp->inp_route.ro_rt != NULL)
- rtflush(&inp->inp_route);
+ rtcache_free(&inp->inp_route);
/* XXX SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */
}
@@ -881,15 +879,16 @@ in_pcbrtentry(struct inpcb *inp)
ro = &inp->inp_route;
- if (ro->ro_rt != NULL && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- !in_hosteq(satosin(&ro->ro_dst)->sin_addr, inp->inp_faddr)))
- rtflush(ro);
+ if (!in_hosteq(satosin(&ro->ro_dst)->sin_addr, inp->inp_faddr))
+ rtcache_free(ro);
+ else
+ rtcache_check(ro);
if (ro->ro_rt == NULL && !in_nullhost(inp->inp_faddr)) {
bzero(&ro->ro_dst, sizeof(struct sockaddr_in));
ro->ro_dst.sa_family = AF_INET;
ro->ro_dst.sa_len = sizeof(ro->ro_dst);
satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
- rtalloc(ro);
+ rtcache_init(ro);
}
return ro->ro_rt;
}
@@ -907,19 +906,20 @@ in_selectsrc(struct sockaddr_in *sin, st
* Note that we should check the address family of the cached
* destination, in case of sharing the cache with IPv6.
*/
- if (ro->ro_rt != NULL &&
- (ro->ro_dst.sa_family != AF_INET ||
+ if (ro->ro_dst.sa_family != AF_INET ||
!in_hosteq(satosin(&ro->ro_dst)->sin_addr, sin->sin_addr) ||
- soopts & SO_DONTROUTE))
- rtflush(ro);
+ soopts & SO_DONTROUTE)
+ rtcache_free(ro);
+ else
+ rtcache_check(ro);
if ((soopts & SO_DONTROUTE) == 0 && /*XXX*/
- (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL)) {
+ ro->ro_rt == NULL) {
/* No route yet, so try to acquire one */
bzero(&ro->ro_dst, sizeof(struct sockaddr_in));
ro->ro_dst.sa_family = AF_INET;
ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
- rtalloc(ro);
+ rtcache_init(ro);
}
/*
* If we found a route, use the address
Index: netinet/ip_etherip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_etherip.c,v
retrieving revision 1.2
diff -p -u -u -p -r1.2 ip_etherip.c
--- netinet/ip_etherip.c 6 Dec 2006 21:42:38 -0000 1.2
+++ netinet/ip_etherip.c 9 Dec 2006 08:56:33 -0000
@@ -153,34 +153,30 @@ ip_etherip_output(struct ifnet *ifp, str
m = m_pullup(m, sizeof(struct ip));
memcpy(mtod(m, struct ip *), &iphdr, sizeof(struct ip));
- if (sc->sc_route_expire - time_second <= 0 ||
- dst->sin_family != sin_dst->sin_family ||
+ if (dst->sin_family != sin_dst->sin_family ||
!in_hosteq(dst->sin_addr, sin_dst->sin_addr)) {
- /* cache route doesn't match */
+ rtcache_free(&sc->sc_ro);
+ } else {
+ rtcache_check(&sc->sc_ro);
+ }
+
+ if (sc->sc_ro.ro_rt == NULL) {
memset(dst, 0, sizeof(struct sockaddr_in));
dst->sin_family = sin_dst->sin_family;
dst->sin_len = sizeof(struct sockaddr_in);
dst->sin_addr = sin_dst->sin_addr;
- if (sc->sc_ro.ro_rt) {
- RTFREE(sc->sc_ro.ro_rt);
- sc->sc_ro.ro_rt = NULL;
- }
- }
-
- if (sc->sc_ro.ro_rt == NULL) {
- rtalloc(&sc->sc_ro);
+ rtcache_init(&sc->sc_ro);
if (sc->sc_ro.ro_rt == NULL) {
m_freem(m);
return ENETUNREACH ;
}
+ }
- /* if it constitutes infinite encapsulation, punt. */
- if (sc->sc_ro.ro_rt->rt_ifp == ifp) {
- m_freem(m);
- return ENETUNREACH; /*XXX*/
- }
-
- sc->sc_route_expire = time_second + ETHERIP_ROUTE_TTL;
+ /* if it constitutes infinite encapsulation, punt. */
+ if (sc->sc_ro.ro_rt->rt_ifp == ifp) {
+ rtcache_free(&sc->sc_ro);
+ m_freem(m);
+ return ENETUNREACH; /*XXX*/
}
error = ip_output(m, NULL, &sc->sc_ro, 0, NULL, NULL);
Index: netinet/ip_flow.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_flow.c,v
retrieving revision 1.37
diff -p -u -u -p -r1.37 ip_flow.c
--- netinet/ip_flow.c 9 Dec 2006 05:33:04 -0000 1.37
+++ netinet/ip_flow.c 9 Dec 2006 08:56:33 -0000
@@ -196,9 +196,9 @@ ipflow_fastforward(struct mbuf *m)
/*
* Route and interface still up?
*/
+ rtcache_check(&ipf->ipf_ro);
rt = ipf->ipf_ro.ro_rt;
- if (rt == NULL || (rt->rt_flags & RTF_UP) == 0 ||
- (rt->rt_ifp->if_flags & IFF_UP) == 0)
+ if (rt == NULL || (rt->rt_ifp->if_flags & IFF_UP) == 0)
return 0;
/*
@@ -269,6 +269,7 @@ ipflow_fastforward(struct mbuf *m)
static void
ipflow_addstats(struct ipflow *ipf)
{
+ rtcache_check(&ipf->ipf_ro);
if (ipf->ipf_ro.ro_rt != NULL)
ipf->ipf_ro.ro_rt->rt_use += ipf->ipf_uses;
ipstat.ips_cantforward += ipf->ipf_errors + ipf->ipf_dropped;
@@ -290,8 +291,7 @@ ipflow_free(struct ipflow *ipf)
IPFLOW_REMOVE(ipf);
splx(s);
ipflow_addstats(ipf);
- if (ipf->ipf_ro.ro_rt != NULL)
- rtflush(&ipf->ipf_ro);
+ rtcache_free(&ipf->ipf_ro);
ipflow_inuse--;
s = splnet();
pool_put(&ipflow_pool, ipf);
@@ -307,14 +307,12 @@ ipflow_reap(int just_one)
ipf = LIST_FIRST(&ipflowlist);
while (ipf != NULL) {
- struct route *ro = &ipf->ipf_ro;
-
/*
* If this no longer points to a valid route
* reclaim it.
*/
- if (ro->ro_rt == NULL ||
- (ro->ro_rt->rt_flags & RTF_UP) == 0)
+ rtcache_check(&ipf->ipf_ro);
+ if (ipf->ipf_ro.ro_rt == NULL)
goto done;
/*
* choose the one that's been least recently
@@ -339,8 +337,7 @@ ipflow_reap(int just_one)
IPFLOW_REMOVE(ipf);
splx(s);
ipflow_addstats(ipf);
- if (ipf->ipf_ro.ro_rt != NULL)
- rtflush(&ipf->ipf_ro);
+ rtcache_free(&ipf->ipf_ro);
if (just_one)
return ipf;
pool_put(&ipflow_pool, ipf);
@@ -356,6 +353,7 @@ ipflow_slowtimo(void)
for (ipf = LIST_FIRST(&ipflowlist); ipf != NULL; ipf = next_ipf) {
next_ipf = LIST_NEXT(ipf, ipf_list);
+ rtcache_check(&ipf->ipf_ro);
if (PRT_SLOW_ISEXPIRED(ipf->ipf_timer) ||
ipf->ipf_ro.ro_rt == NULL) {
ipflow_free(ipf);
@@ -406,8 +404,7 @@ ipflow_create(const struct route *ro, st
IPFLOW_REMOVE(ipf);
splx(s);
ipflow_addstats(ipf);
- if (ipf->ipf_ro.ro_rt != NULL)
- rtflush(&ipf->ipf_ro);
+ rtcache_free(&ipf->ipf_ro);
ipf->ipf_uses = ipf->ipf_last_uses = 0;
ipf->ipf_errors = ipf->ipf_dropped = 0;
}
Index: netinet/ip_icmp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.106
diff -p -u -u -p -r1.106 ip_icmp.c
--- netinet/ip_icmp.c 9 Dec 2006 05:33:04 -0000 1.106
+++ netinet/ip_icmp.c 9 Dec 2006 08:56:34 -0000
@@ -730,8 +730,7 @@ icmp_reflect(struct mbuf *m)
errornum = 0;
sin = in_selectsrc(&sin_dst, &icmproute, 0, NULL, &errornum);
/* errornum is never used */
- if (icmproute.ro_rt != NULL)
- rtflush(&icmproute);
+ rtcache_free(&icmproute);
/* check to make sure sin is a source address on rcvif */
if (sin) {
t = sin->sin_addr;
Index: netinet/ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.239
diff -p -u -u -p -r1.239 ip_input.c
--- netinet/ip_input.c 9 Dec 2006 05:33:04 -0000 1.239
+++ netinet/ip_input.c 9 Dec 2006 08:56:34 -0000
@@ -1679,17 +1679,19 @@ ip_rtaddr(struct in_addr dst)
sin = satosin(&ipforward_rt.ro_dst);
- if (ipforward_rt.ro_rt == NULL || !in_hosteq(dst, sin->sin_addr)) {
- if (ipforward_rt.ro_rt != NULL)
- rtflush(&ipforward_rt);
+ if (!in_hosteq(dst, sin->sin_addr))
+ rtcache_free(&ipforward_rt);
+ else
+ rtcache_check(&ipforward_rt);
+ if (ipforward_rt.ro_rt != NULL) {
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_addr = dst;
- rtalloc(&ipforward_rt);
+ rtcache_init(&ipforward_rt);
+ if (ipforward_rt.ro_rt == NULL)
+ return NULL;
}
- if (ipforward_rt.ro_rt == NULL)
- return NULL;
return ifatoia(ipforward_rt.ro_rt->rt_ifa);
}
@@ -1871,21 +1873,22 @@ ip_forward(struct mbuf *m, int srcrt)
}
sin = satosin(&ipforward_rt.ro_dst);
- if ((rt = ipforward_rt.ro_rt) == NULL ||
- !in_hosteq(ip->ip_dst, sin->sin_addr)) {
- if (ipforward_rt.ro_rt != NULL)
- rtflush(&ipforward_rt);
+ if (!in_hosteq(ip->ip_dst, sin->sin_addr))
+ rtcache_free(&ipforward_rt);
+ else
+ rtcache_check(&ipforward_rt);
+ if (ipforward_rt.ro_rt == NULL) {
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr = ip->ip_dst;
- rtalloc(&ipforward_rt);
+ rtcache_init(&ipforward_rt);
if (ipforward_rt.ro_rt == NULL) {
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0);
return;
}
- rt = ipforward_rt.ro_rt;
}
+ rt = ipforward_rt.ro_rt;
/*
* Save at most 68 bytes of the packet in case
Index: netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.170
diff -p -u -u -p -r1.170 ip_output.c
--- netinet/ip_output.c 9 Dec 2006 05:33:04 -0000 1.170
+++ netinet/ip_output.c 9 Dec 2006 08:56:34 -0000
@@ -299,10 +299,10 @@ ip_output(struct mbuf *m0, ...)
* The address family should also be checked in case of sharing the
* cache with IPv6.
*/
- if (ro->ro_rt != NULL && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- dst->sin_family != AF_INET ||
- !in_hosteq(dst->sin_addr, ip->ip_dst)))
- rtflush(ro);
+ if (dst->sin_family != AF_INET || !in_hosteq(dst->sin_addr, ip->ip_dst))
+ rtcache_free(ro);
+ else
+ rtcache_check(ro);
if (ro->ro_rt == NULL) {
bzero(dst, sizeof(*dst));
dst->sin_family = AF_INET;
@@ -330,7 +330,7 @@ ip_output(struct mbuf *m0, ...)
IFP_TO_IA(ifp, ia);
} else {
if (ro->ro_rt == NULL)
- rtalloc(ro);
+ rtcache_init(ro);
if (ro->ro_rt == NULL) {
ipstat.ips_noroute++;
error = EHOSTUNREACH;
@@ -963,8 +963,8 @@ spd_done:
if (error == 0)
ipstat.ips_fragmented++;
done:
- if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt != NULL)
- rtflush(ro);
+ if (ro == &iproute && (flags & IP_ROUTETOIF) == 0)
+ rtcache_free(ro);
#ifdef IPSEC
if (sp != NULL) {
@@ -1764,13 +1764,13 @@ ip_setmoptions(int optname, struct ip_mo
dst->sin_len = sizeof(*dst);
dst->sin_family = AF_INET;
dst->sin_addr = mreq->imr_multiaddr;
- rtalloc(&ro);
+ rtcache_init(&ro);
if (ro.ro_rt == NULL) {
error = EADDRNOTAVAIL;
break;
}
ifp = ro.ro_rt->rt_ifp;
- rtflush(&ro);
+ rtcache_free(&ro);
} else {
ifp = ip_multicast_if(&mreq->imr_interface, NULL);
}
Index: netinet/tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.258
diff -p -u -u -p -r1.258 tcp_input.c
--- netinet/tcp_input.c 9 Dec 2006 05:33:04 -0000 1.258
+++ netinet/tcp_input.c 9 Dec 2006 08:56:35 -0000
@@ -3208,8 +3208,7 @@ do { \
do { \
if ((sc)->sc_ipopts) \
(void) m_free((sc)->sc_ipopts); \
- if ((sc)->sc_route4.ro_rt != NULL) \
- rtflush(&(sc)->sc_route4); \
+ rtcache_free(&(sc)->sc_route4); \
if (callout_invoking(&(sc)->sc_timer)) \
(sc)->sc_flags |= SCF_DEAD; \
else \
Index: netinet6/frag6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/frag6.c,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 frag6.c
--- netinet6/frag6.c 9 Dec 2006 05:33:07 -0000 1.32
+++ netinet6/frag6.c 9 Dec 2006 08:56:35 -0000
@@ -200,17 +200,17 @@ frag6_input(struct mbuf **mp, int *offp,
#ifdef IN6_IFSTAT_STRICT
/* find the destination interface of the packet. */
dst = (struct sockaddr_in6 *)&ro.ro_dst;
- if (ro.ro_rt != NULL &&
- ((ro.ro_rt->rt_flags & RTF_UP) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst)))
- rtflush((struct route *)&ro);
+ if (!IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))
+ rtcache_free((struct route *)&ro);
+ else
+ rtcache_check((struct route *)&ro);
if (ro.ro_rt == NULL) {
bzero(dst, sizeof(*dst));
dst->sin6_family = AF_INET6;
dst->sin6_len = sizeof(struct sockaddr_in6);
dst->sin6_addr = ip6->ip6_dst;
+ rtcache_init((struct route *)&ro);
}
- rtalloc((struct route *)&ro);
if (ro.ro_rt != NULL && ro.ro_rt->rt_ifa != NULL)
dstifp = ((struct in6_ifaddr *)ro.ro_rt->rt_ifa)->ia_ifp;
#else
@@ -738,10 +738,8 @@ frag6_slowtimo()
* make sure we notice eventually, even if forwarding only for one
* destination and the cache is never replaced.
*/
- if (ip6_forward_rt.ro_rt != NULL)
- rtflush(&ip6_forward_rt);
- if (ipsrcchk_rt.ro_rt != NULL)
- rtflush(&ipsrcchk_rt);
+ rtcache_free(&ip6_forward_rt);
+ rtcache_free(&ipsrcchk_rt);
#endif
splx(s);
Index: netinet6/icmp6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/icmp6.c,v
retrieving revision 1.124
diff -p -u -u -p -r1.124 icmp6.c
--- netinet6/icmp6.c 9 Dec 2006 05:33:07 -0000 1.124
+++ netinet6/icmp6.c 9 Dec 2006 08:56:36 -0000
@@ -2066,8 +2066,7 @@ icmp6_reflect(m, off)
bzero(&ro, sizeof(ro));
src = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &e);
- if (ro.ro_rt != NULL)
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
if (src == NULL) {
nd6log((LOG_DEBUG,
"icmp6_reflect: source can't be determined: "
Index: netinet6/in6_gif.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_gif.c,v
retrieving revision 1.46
diff -p -u -u -p -r1.46 in6_gif.c
--- netinet6/in6_gif.c 9 Dec 2006 05:33:07 -0000 1.46
+++ netinet6/in6_gif.c 9 Dec 2006 08:56:36 -0000
@@ -184,28 +184,27 @@ in6_gif_output(ifp, family, m)
ip6->ip6_flow |= htonl((u_int32_t)otos << 20);
if (dst->sin6_family != sin6_dst->sin6_family ||
- !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) {
- /* cache route doesn't match */
+ !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr))
+ rtcache_free((struct route *)&sc->gif_ro6);
+ else
+ rtcache_check((struct route *)&sc->gif_ro6);
+
+ if (sc->gif_ro6.ro_rt == NULL) {
bzero(dst, sizeof(*dst));
dst->sin6_family = sin6_dst->sin6_family;
dst->sin6_len = sizeof(struct sockaddr_in6);
dst->sin6_addr = sin6_dst->sin6_addr;
- if (sc->gif_ro6.ro_rt != NULL)
- rtflush((struct route *)&sc->gif_ro6);
- }
-
- if (sc->gif_ro6.ro_rt == NULL) {
- rtalloc((struct route *)&sc->gif_ro6);
+ rtcache_init((struct route *)&sc->gif_ro6);
if (sc->gif_ro6.ro_rt == NULL) {
m_freem(m);
return ENETUNREACH;
}
+ }
- /* if it constitutes infinite encapsulation, punt. */
- if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
- m_freem(m);
- return ENETUNREACH; /* XXX */
- }
+ /* if it constitutes infinite encapsulation, punt. */
+ if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
+ m_freem(m);
+ return ENETUNREACH; /* XXX */
}
#ifdef IPV6_MINMTU
@@ -418,8 +417,7 @@ in6_gif_detach(sc)
if (error == 0)
sc->encap_cookie6 = NULL;
- if (sc->gif_ro6.ro_rt != NULL)
- rtflush((struct route *)&sc->gif_ro6);
+ rtcache_free((struct route *)&sc->gif_ro6);
return error;
}
@@ -474,6 +472,6 @@ in6_gif_ctlinput(cmd, sa, d)
dst6 = (struct sockaddr_in6 *)&sc->gif_ro6.ro_dst;
/* XXX scope */
if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst6->sin6_addr))
- rtflush((struct route *)&sc->gif_ro6);
+ rtcache_free((struct route *)&sc->gif_ro6);
}
}
Index: netinet6/in6_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.79
diff -p -u -u -p -r1.79 in6_pcb.c
--- netinet6/in6_pcb.c 9 Dec 2006 05:33:07 -0000 1.79
+++ netinet6/in6_pcb.c 9 Dec 2006 08:56:36 -0000
@@ -513,15 +513,13 @@ in6_pcbdetach(in6p)
if (in6p->in6p_options)
m_freem(in6p->in6p_options);
if (in6p->in6p_outputopts) {
- if (in6p->in6p_outputopts->ip6po_rthdr &&
- in6p->in6p_outputopts->ip6po_route.ro_rt != NULL)
- rtflush((struct route *)&in6p->in6p_outputopts->ip6po_route);
+ if (in6p->in6p_outputopts->ip6po_rthdr != NULL)
+ rtcache_free((struct route *)&in6p->in6p_outputopts->ip6po_route);
if (in6p->in6p_outputopts->ip6po_m)
(void)m_free(in6p->in6p_outputopts->ip6po_m);
free(in6p->in6p_outputopts, M_IP6OPT);
}
- if (in6p->in6p_route.ro_rt != NULL)
- rtflush((struct route *)&in6p->in6p_route);
+ rtcache_free((struct route *)&in6p->in6p_route);
ip6_freemoptions(in6p->in6p_moptions);
s = splnet();
in6_pcbstate(in6p, IN6P_ATTACHED);
@@ -825,7 +823,7 @@ in6_losing(in6p)
* A new route can be allocated
* the next time output is attempted.
*/
- rtflush((struct route *)&in6p->in6p_route);
+ rtcache_free((struct route *)&in6p->in6p_route);
}
}
@@ -839,8 +837,7 @@ in6_rtchange(struct in6pcb *in6p, int er
if (in6p->in6p_af != AF_INET6)
return;
- if (in6p->in6p_route.ro_rt != NULL)
- rtflush((struct route *)&in6p->in6p_route);
+ rtcache_free((struct route *)&in6p->in6p_route);
}
struct in6pcb *
@@ -944,9 +941,10 @@ in6_pcbrtentry(in6p)
if (in6p->in6p_af != AF_INET6)
return (NULL);
- if (ro->ro_rt != NULL && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &in6p->in6p_faddr)))
- rtflush((struct route *)ro);
+ if (!IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &in6p->in6p_faddr))
+ rtcache_free((struct route *)ro);
+ else
+ rtcache_check((struct route *)ro);
#ifdef INET
if (ro->ro_rt == NULL && IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) {
struct sockaddr_in *dst = (struct sockaddr_in *)&ro->ro_dst;
@@ -956,7 +954,7 @@ in6_pcbrtentry(in6p)
dst->sin_len = sizeof(struct sockaddr_in);
bcopy(&in6p->in6p_faddr.s6_addr32[3], &dst->sin_addr,
sizeof(dst->sin_addr));
- rtalloc((struct route *)ro);
+ rtcache_init((struct route *)ro);
} else
#endif
if (ro->ro_rt == NULL && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
@@ -964,7 +962,7 @@ in6_pcbrtentry(in6p)
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(struct sockaddr_in6);
dst6->sin6_addr = in6p->in6p_faddr;
- rtalloc((struct route *)ro);
+ rtcache_init((struct route *)ro);
}
return ro->ro_rt;
}
Index: netinet6/in6_src.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_src.c,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 in6_src.c
--- netinet6/in6_src.c 9 Dec 2006 05:33:08 -0000 1.32
+++ netinet6/in6_src.c 9 Dec 2006 08:56:36 -0000
@@ -667,27 +667,22 @@ selectroute(dstsock, opts, mopts, ro, re
* by that address must be a neighbor of the sending host.
*/
ron = &opts->ip6po_nextroute;
+ /* XXX Careful, Joerg, this checks RTF_GATEWAY! --dyoung */
if ((ron->ro_rt != NULL &&
- (ron->ro_rt->rt_flags & (RTF_UP | RTF_GATEWAY)) !=
- RTF_UP) ||
+ (ron->ro_rt->rt_flags & RTF_GATEWAY) != 0) ||
!IN6_ARE_ADDR_EQUAL(&satosin6(&ron->ro_dst)->sin6_addr,
&sin6_next->sin6_addr)) {
- if (ron->ro_rt != NULL)
- rtflush((struct route *)ron);
- *satosin6(&ron->ro_dst) = *sin6_next;
- }
+ rtcache_free((struct route *)ron);
+ } else
+ rtcache_check((struct route *)ron);
if (ron->ro_rt == NULL) {
- rtalloc((struct route *)ron); /* multi path case? */
- if (ron->ro_rt == NULL ||
- (ron->ro_rt->rt_flags & RTF_GATEWAY)) {
- if (ron->ro_rt != NULL)
- rtflush((struct route *)ron);
- error = EHOSTUNREACH;
- goto done;
- }
+ *satosin6(&ron->ro_dst) = *sin6_next;
+ rtcache_init((struct route *)ron); /* multi path case?*/
}
- if (!nd6_is_addr_neighbor(sin6_next, ron->ro_rt->rt_ifp)) {
- rtflush((struct route *)ron);
+ if (ron->ro_rt == NULL ||
+ (ron->ro_rt->rt_flags & RTF_GATEWAY) != 0 ||
+ !nd6_is_addr_neighbor(sin6_next, ron->ro_rt->rt_ifp)) {
+ rtcache_free((struct route *)ron);
error = EHOSTUNREACH;
goto done;
}
@@ -709,12 +704,11 @@ selectroute(dstsock, opts, mopts, ro, re
* cached destination, in case of sharing the cache with IPv4.
*/
if (ro != NULL) {
- if (ro->ro_rt != NULL &&
- (!(ro->ro_rt->rt_flags & RTF_UP) ||
- ((struct sockaddr *)(&ro->ro_dst))->sa_family != AF_INET6 ||
- !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr,
- dst)))
- rtflush((struct route *)ro);
+ if (((struct sockaddr *)(&ro->ro_dst))->sa_family != AF_INET6 ||
+ !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst))
+ rtcache_free((struct route *)ro);
+ else
+ rtcache_check((struct route *)ro);
if (ro->ro_rt == NULL) {
struct sockaddr_in6 *sa6;
@@ -723,25 +717,21 @@ selectroute(dstsock, opts, mopts, ro, re
sa6 = (struct sockaddr_in6 *)&ro->ro_dst;
*sa6 = *dstsock;
sa6->sin6_scope_id = 0;
- if (clone) {
#ifdef RADIX_MPATH
+ if (clone) {
rtalloc_mpath((struct route *)ro,
ntohl(sa6->sin6_addr.s6_addr32[3]));
-#else
- rtalloc((struct route *)ro);
-#endif /* RADIX_MPATH */
} else {
-#ifdef RADIX_MPATH
/* XXX rtalloc_mpath1(, 0) */
rtalloc_mpath((struct route *)ro,
ntohl(sa6->sin6_addr.s6_addr32[3]));
+ }
#else
- ro->ro_rt =
- rtalloc1(&((struct route *)ro)->ro_dst, 0);
- if (ro->ro_rt != NULL)
- rtcache((struct route *)ro);
+ if (clone)
+ rtcache_init((struct route *)ro);
+ else
+ rtcache_init_noclone((struct route *)ro);
#endif /* RADIX_MPATH */
- }
}
/*
@@ -751,14 +741,10 @@ selectroute(dstsock, opts, mopts, ro, re
if (opts && opts->ip6po_nexthop)
goto done;
- if (ro->ro_rt != NULL) {
- ifp = ro->ro_rt->rt_ifp;
-
- if (ifp == NULL) /* can this really happen? */
- rtflush((struct route *)ro);
- }
if (ro->ro_rt == NULL)
error = EHOSTUNREACH;
+ else
+ ifp = ro->ro_rt->rt_ifp;
rt = ro->ro_rt;
/*
Index: netinet6/ip6_etherip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_etherip.c,v
retrieving revision 1.2
diff -p -u -u -p -r1.2 ip6_etherip.c
--- netinet6/ip6_etherip.c 6 Dec 2006 21:42:38 -0000 1.2
+++ netinet6/ip6_etherip.c 9 Dec 2006 08:56:36 -0000
@@ -158,34 +158,28 @@ ip6_etherip_output(struct ifnet *ifp, st
return ENETUNREACH;
}
- if (sc->sc_route_expire - time_second <= 0 ||
- dst->sin6_family != sin6_dst->sin6_family ||
- !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) {
- /* cache route doesn't match */
+ if (dst->sin6_family != sin6_dst->sin6_family ||
+ !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr))
+ rtcache_free((struct route *)&sc->sc_ro6);
+ else
+ rtcache_check((struct route *)&sc->sc_ro6);
+
+ if (sc->sc_ro6.ro_rt == NULL) {
memset(dst, 0, sizeof(*dst));
dst->sin6_family = sin6_dst->sin6_family;
dst->sin6_len = sizeof(struct sockaddr_in6);
dst->sin6_addr = sin6_dst->sin6_addr;
- if (sc->sc_ro6.ro_rt) {
- RTFREE(sc->sc_ro6.ro_rt);
- sc->sc_ro6.ro_rt = NULL;
- }
- }
-
- if (sc->sc_ro6.ro_rt == NULL) {
- rtalloc((struct route *)&sc->sc_ro6);
+ rtcache_init((struct route *)&sc->sc_ro6);
if (sc->sc_ro6.ro_rt == NULL) {
m_freem(m);
return ENETUNREACH;
}
-
- /* if it constitutes infinite encapsulation, punt. */
- if (sc->sc_ro.ro_rt->rt_ifp == ifp) {
- m_freem(m);
- return ENETUNREACH; /* XXX */
- }
-
- sc->sc_route_expire = time_second + ETHERIP_ROUTE_TTL;
+ }
+ /* if it constitutes infinite encapsulation, punt. */
+ if (sc->sc_ro.ro_rt->rt_ifp == ifp) {
+ rtcache_free((struct route *)&sc->sc_ro6);
+ m_freem(m);
+ return ENETUNREACH; /* XXX */
}
/*
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.51
diff -p -u -u -p -r1.51 ip6_forward.c
--- netinet6/ip6_forward.c 9 Dec 2006 05:33:08 -0000 1.51
+++ netinet6/ip6_forward.c 9 Dec 2006 08:56:36 -0000
@@ -338,14 +338,10 @@ ip6_forward(m, srcrt)
/*
* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
*/
- if (ip6_forward_rt.ro_rt == NULL ||
- (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0) {
- if (ip6_forward_rt.ro_rt != NULL)
- rtflush((struct route *)&ip6_forward_rt);
- /* this probably fails but give it a try again */
- rtalloc((struct route *)&ip6_forward_rt);
- }
+ rtcache_check((struct route *)&ip6_forward_rt);
+ if (ip6_forward_rt.ro_rt == NULL)
+ rtcache_init((struct route *)&ip6_forward_rt);
if (ip6_forward_rt.ro_rt == NULL) {
ip6stat.ip6s_noroute++;
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
@@ -356,16 +352,19 @@ ip6_forward(m, srcrt)
m_freem(m);
return;
}
- } else if ((rt = ip6_forward_rt.ro_rt) == NULL ||
- !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
- if (ip6_forward_rt.ro_rt != NULL)
- rtflush((struct route *)&ip6_forward_rt);
- bzero(dst, sizeof(*dst));
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_family = AF_INET6;
- dst->sin6_addr = ip6->ip6_dst;
+ } else {
+ if (!IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr))
+ rtcache_free((struct route *)&ip6_forward_rt);
+ else
+ rtcache_check((struct route *)&ip6_forward_rt);
+ if (ip6_forward_rt.ro_rt == NULL) {
+ bzero(dst, sizeof(*dst));
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = ip6->ip6_dst;
+ rtcache_init((struct route *)&ip6_forward_rt);
+ }
- rtalloc((struct route *)&ip6_forward_rt);
if (ip6_forward_rt.ro_rt == NULL) {
ip6stat.ip6s_noroute++;
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.92
diff -p -u -u -p -r1.92 ip6_input.c
--- netinet6/ip6_input.c 9 Dec 2006 05:33:08 -0000 1.92
+++ netinet6/ip6_input.c 9 Dec 2006 08:56:36 -0000
@@ -461,7 +461,7 @@ ip6_input(m)
if (ip6_forward_rt.ro_rt != NULL) {
/* route is down or destination is different */
ip6stat.ip6s_forward_cachemiss++;
- rtflush((struct route *)&ip6_forward_rt);
+ rtcache_free((struct route *)&ip6_forward_rt);
}
bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.108
diff -p -u -u -p -r1.108 ip6_output.c
--- netinet6/ip6_output.c 9 Dec 2006 05:33:08 -0000 1.108
+++ netinet6/ip6_output.c 9 Dec 2006 08:56:37 -0000
@@ -1137,10 +1137,11 @@ sendorfree:
ip6stat.ip6s_fragmented++;
done:
- if (ro == &ip6route && ro->ro_rt != NULL)
- rtflush((struct route *)ro);
- else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt != NULL)
- rtflush((struct route *)ro_pmtu);
+ /* XXX Second if is invariant? */
+ if (ro == &ip6route)
+ rtcache_free((struct route *)ro);
+ else if (ro_pmtu == &ip6route)
+ rtcache_free((struct route *)ro_pmtu);
#ifdef IPSEC
if (sp != NULL)
@@ -1376,17 +1377,16 @@ ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup,
/* The first hop and the final destination may differ. */
struct sockaddr_in6 *sa6_dst =
(struct sockaddr_in6 *)&ro_pmtu->ro_dst;
- if (ro_pmtu->ro_rt != NULL &&
- ((ro_pmtu->ro_rt->rt_flags & RTF_UP) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&sa6_dst->sin6_addr, dst)))
- rtflush((struct route *)ro_pmtu);
+ if (!IN6_ARE_ADDR_EQUAL(&sa6_dst->sin6_addr, dst))
+ rtcache_free((struct route *)ro_pmtu);
+ else
+ rtcache_check((struct route *)ro_pmtu);
if (ro_pmtu->ro_rt == NULL) {
bzero(sa6_dst, sizeof(*sa6_dst)); /* for safety */
sa6_dst->sin6_family = AF_INET6;
sa6_dst->sin6_len = sizeof(struct sockaddr_in6);
sa6_dst->sin6_addr = *dst;
-
- rtalloc((struct route *)ro_pmtu);
+ rtcache_init((struct route *)ro_pmtu);
}
}
if (ro_pmtu->ro_rt != NULL) {
@@ -2330,8 +2330,7 @@ ip6_clearpktopts(struct ip6_pktopts *pkt
if (optname == -1 || optname == IPV6_TCLASS)
pktopt->ip6po_tclass = -1;
if (optname == -1 || optname == IPV6_NEXTHOP) {
- if (pktopt->ip6po_nextroute.ro_rt != NULL)
- rtflush((struct route *)&pktopt->ip6po_nextroute);
+ rtcache_free((struct route *)&pktopt->ip6po_nextroute);
if (pktopt->ip6po_nexthop)
free(pktopt->ip6po_nexthop, M_IP6OPT);
pktopt->ip6po_nexthop = NULL;
@@ -2350,8 +2349,7 @@ ip6_clearpktopts(struct ip6_pktopts *pkt
if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
- if (pktopt->ip6po_route.ro_rt != NULL)
- rtflush((struct route *)&pktopt->ip6po_route);
+ rtcache_free((struct route *)&pktopt->ip6po_route);
}
if (optname == -1 || optname == IPV6_DSTOPTS) {
if (pktopt->ip6po_dest2)
@@ -2588,7 +2586,7 @@ ip6_setmoptions(optname, im6op, m)
break;
}
ifp = ro.ro_rt->rt_ifp;
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
} else {
/*
* If the interface is specified, validate it.
Index: netinet6/ipsec.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ipsec.c,v
retrieving revision 1.112
diff -p -u -u -p -r1.112 ipsec.c
--- netinet6/ipsec.c 9 Dec 2006 05:33:08 -0000 1.112
+++ netinet6/ipsec.c 9 Dec 2006 08:56:37 -0000
@@ -2732,20 +2732,20 @@ ipsec4_output(struct ipsec_output_state
state->ro = &isr->sav->sah->sa_route;
state->dst = (struct sockaddr *)&state->ro->ro_dst;
dst4 = (struct sockaddr_in *)state->dst;
- if (state->ro->ro_rt != NULL &&
- ((state->ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- dst4->sin_addr.s_addr != ip->ip_dst.s_addr))
- rtflush((struct route *)state->ro);
+ if (dst4->sin_addr.s_addr != ip->ip_dst.s_addr)
+ rtcache_free((struct route *)state->ro);
+ else
+ rtcache_check((struct route *)state->ro);
if (state->ro->ro_rt == NULL) {
dst4->sin_family = AF_INET;
dst4->sin_len = sizeof(*dst4);
dst4->sin_addr = ip->ip_dst;
- rtalloc(state->ro);
- }
- if (state->ro->ro_rt == NULL) {
- ipstat.ips_noroute++;
- error = EHOSTUNREACH;
- goto bad;
+ rtcache_init(state->ro);
+ if (state->ro->ro_rt == NULL) {
+ ipstat.ips_noroute++;
+ error = EHOSTUNREACH;
+ goto bad;
+ }
}
/* adjust state->dst if tunnel endpoint is offlink */
@@ -3120,23 +3120,22 @@ ipsec6_output_tunnel(struct ipsec_output
state->ro = &isr->sav->sah->sa_route;
state->dst = (struct sockaddr *)&state->ro->ro_dst;
dst6 = (struct sockaddr_in6 *)state->dst;
- if (state->ro->ro_rt != NULL &&
- ((state->ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr,
- &ip6->ip6_dst)))
- rtflush((struct route *)state->ro);
+ if (!IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))
+ rtcache_free((struct route *)state->ro);
+ else
+ rtcache_check((struct route *)state->ro);
if (state->ro->ro_rt == NULL) {
bzero(dst6, sizeof(*dst6));
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(*dst6);
dst6->sin6_addr = ip6->ip6_dst;
- rtalloc(state->ro);
- }
- if (state->ro->ro_rt == NULL) {
- ip6stat.ip6s_noroute++;
- ipsec6stat.out_noroute++;
- error = EHOSTUNREACH;
- goto bad;
+ rtcache_init(state->ro);
+ if (state->ro->ro_rt == NULL) {
+ ip6stat.ip6s_noroute++;
+ ipsec6stat.out_noroute++;
+ error = EHOSTUNREACH;
+ goto bad;
+ }
}
/* adjust state->dst if tunnel endpoint is offlink */
Index: netinet6/nd6_nbr.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/nd6_nbr.c,v
retrieving revision 1.67
diff -p -u -u -p -r1.67 nd6_nbr.c
--- netinet6/nd6_nbr.c 9 Dec 2006 05:33:08 -0000 1.67
+++ netinet6/nd6_nbr.c 9 Dec 2006 08:56:37 -0000
@@ -527,13 +527,11 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, d
icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
- if (ro.ro_rt != NULL) /* we don't cache this route. */
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
return;
bad:
- if (ro.ro_rt != NULL)
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
m_freem(m);
return;
}
@@ -1005,13 +1003,11 @@ nd6_na_output(ifp, daddr6_0, taddr6, fla
icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
- if (ro.ro_rt != NULL) /* we don't cache this route. */
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
return;
bad:
- if (ro.ro_rt != NULL)
- rtflush((struct route *)&ro);
+ rtcache_free((struct route *)&ro);
m_freem(m);
return;
}
Index: netipsec/ipsec_output.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/ipsec_output.c,v
retrieving revision 1.18
diff -p -u -u -p -r1.18 ipsec_output.c
--- netipsec/ipsec_output.c 9 Dec 2006 05:33:09 -0000 1.18
+++ netipsec/ipsec_output.c 9 Dec 2006 08:56:38 -0000
@@ -741,22 +741,22 @@ ipsec6_output_tunnel(
state->ro = &isr->sav->sah->sa_route;
state->dst = (struct sockaddr *)&state->ro->ro_dst;
dst6 = (struct sockaddr_in6 *)state->dst;
- if (state->ro->ro_rt != NULL &&
- ((state->ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst)))
- rtflush(state->ro);
+ if (!IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))
+ rtcache_free(state->ro);
+ else
+ rtcache_check(state->ro);
if (state->ro->ro_rt == NULL) {
bzero(dst6, sizeof(*dst6));
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(*dst6);
dst6->sin6_addr = ip6->ip6_dst;
- rtalloc(state->ro);
- }
- if (state->ro->ro_rt == NULL) {
- ip6stat.ip6s_noroute++;
- newipsecstat.ips_out_noroute++;
- error = EHOSTUNREACH;
- goto bad;
+ rtcache_init(state->ro);
+ if (state->ro->ro_rt == NULL) {
+ ip6stat.ip6s_noroute++;
+ newipsecstat.ips_out_noroute++;
+ error = EHOSTUNREACH;
+ goto bad;
+ }
}
/* adjust state->dst if tunnel endpoint is offlink */
Index: netipsec/key.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/key.c,v
retrieving revision 1.31
diff -p -u -u -p -r1.31 key.c
--- netipsec/key.c 9 Dec 2006 05:33:09 -0000 1.31
+++ netipsec/key.c 9 Dec 2006 08:56:39 -0000
@@ -2818,8 +2818,7 @@ key_delsah(sah)
return;
}
- if (sah->sa_route.ro_rt != NULL)
- rtflush(&sah->sa_route);
+ rtcache_free(&sah->sa_route);
/* remove from tree of SA index */
if (__LIST_CHAINED(sah))
@@ -7537,9 +7536,9 @@ key_sa_routechange(dst)
LIST_FOREACH(sah, &sahtree, chain) {
ro = &sah->sa_route;
- if (ro->ro_rt != NULL && dst->sa_len == ro->ro_dst.sa_len
- && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0)
- rtflush(ro);
+ if (dst->sa_len == ro->ro_dst.sa_len &&
+ bcmp(dst, &ro->ro_dst, dst->sa_len) == 0)
+ rtcache_free(ro);
}
return;
Index: netiso/clnp_er.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/clnp_er.c,v
retrieving revision 1.19
diff -p -u -u -p -r1.19 clnp_er.c
--- netiso/clnp_er.c 9 Dec 2006 05:33:09 -0000 1.19
+++ netiso/clnp_er.c 9 Dec 2006 08:56:39 -0000
@@ -378,8 +378,7 @@ bad:
done:
/* free route if it is a temp */
- if (route.ro_rt != NULL)
- rtflush((struct route *)&route);
+ rtcache_free((struct route *)&route);
}
int
Index: netiso/clnp_raw.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/clnp_raw.c,v
retrieving revision 1.25
diff -p -u -u -p -r1.25 clnp_raw.c
--- netiso/clnp_raw.c 9 Dec 2006 05:33:09 -0000 1.25
+++ netiso/clnp_raw.c 9 Dec 2006 08:56:39 -0000
@@ -313,8 +313,7 @@ clnp_usrreq(struct socket *so, int req,
case PRU_DETACH:
if (rp->risop_isop.isop_options)
m_freem(rp->risop_isop.isop_options);
- if (rp->risop_isop.isop_route.ro_rt != NULL)
- rtflush((struct route *)&rp->risop_isop.isop_route);
+ rtcache_free((struct route *)&rp->risop_isop.isop_route);
if (rp->risop_rcb.rcb_laddr)
rp->risop_rcb.rcb_laddr = 0;
/* free clnp cached hdr if necessary */
Index: netiso/clnp_subr.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/clnp_subr.c,v
retrieving revision 1.23
diff -p -u -u -p -r1.23 clnp_subr.c
--- netiso/clnp_subr.c 9 Dec 2006 05:33:09 -0000 1.23
+++ netiso/clnp_subr.c 9 Dec 2006 08:56:39 -0000
@@ -402,8 +402,7 @@ done:
/*
* Free route
*/
- if (route.ro_rt != NULL)
- rtflush((struct route *)&route);
+ rtcache_free((struct route *)&route);
}
#ifdef notdef
@@ -468,8 +467,7 @@ clnp_route(
if (flags & SO_DONTROUTE) {
struct iso_ifaddr *ia;
- if (ro->ro_rt != NULL)
- rtflush((struct route *)ro);
+ rtcache_free((struct route *)ro);
bzero((caddr_t) & ro->ro_dst, sizeof(ro->ro_dst));
bcopy((caddr_t) dst, (caddr_t) & ro->ro_dst.siso_addr,
1 + (unsigned) dst->isoa_len);
@@ -488,26 +486,10 @@ clnp_route(
* If there is a cached route, check that it is still up and to
* the same destination. If not, free it and try again.
*/
- if (ro->ro_rt != NULL && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- (Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) {
-#ifdef ARGO_DEBUG
- if (argo_debug[D_ROUTE]) {
- printf("clnp_route: freeing old route: ro->ro_rt %p\n",
- ro->ro_rt);
- printf("clnp_route: old route refcnt: 0x%x\n",
- ro->ro_rt->rt_refcnt);
- }
-#endif
-
- /* free old route entry */
- rtflush((struct route *)ro);
- } else {
-#ifdef ARGO_DEBUG
- if (argo_debug[D_ROUTE]) {
- printf("clnp_route: OK route exists\n");
- }
-#endif
- }
+ if (bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len) != 0)
+ rtcache_free((struct route *)ro);
+ else
+ rtcache_check((struct route *)ro);
if (ro->ro_rt == NULL) {
/* set up new route structure */
@@ -522,10 +504,10 @@ clnp_route(
clnp_iso_addrp(dst));
}
#endif
- rtalloc((struct route *)ro);
+ rtcache_init((struct route *)ro);
+ if (ro->ro_rt == NULL)
+ return (ENETUNREACH); /* rtalloc failed */
}
- if (ro->ro_rt == NULL)
- return (ENETUNREACH); /* rtalloc failed */
ro->ro_rt->rt_use++;
if (ifa)
if ((*ifa = (struct iso_ifaddr *)ro->ro_rt->rt_ifa) == 0)
Index: netiso/if_eon.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/if_eon.c,v
retrieving revision 1.53
diff -p -u -u -p -r1.53 if_eon.c
--- netiso/if_eon.c 9 Dec 2006 05:33:09 -0000 1.53
+++ netiso/if_eon.c 9 Dec 2006 08:56:39 -0000
@@ -221,18 +221,15 @@ eoniphdr(struct eon_iphdr *hdr, const vo
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
(void)memcpy(&sin->sin_addr, loc, sizeof(struct in_addr));
- /*
- * If there is a cached route,
- * check that it is to the same destination
- * and is still up. If not, free it and try again.
- */
+ /* XXX Does this check make any sense? */
+ rtcache_check(ro);
if (ro->ro_rt != NULL) {
struct sockaddr_in *dst = satosin(rt_key(ro->ro_rt));
- if ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
- sin->sin_addr.s_addr != dst->sin_addr.s_addr)
- rtflush(ro);
+ if (sin->sin_addr.s_addr != dst->sin_addr.s_addr)
+ rtcache_free(ro);
}
- rtalloc(ro);
+ if (ro->ro_rt == NULL)
+ rtcache_init(ro);
if (ro->ro_rt != NULL)
ro->ro_rt->rt_use++;
hdr->ei_ip.ip_dst = sin->sin_addr;
@@ -277,8 +274,7 @@ eonrtrequest(int cmd, struct rtentry *rt
case RTM_DELETE:
if (el) {
remque(&(el->el_qhdr));
- if (el->el_iproute.ro_rt != NULL)
- rtflush(&el->el_iproute);
+ rtcache_free(&el->el_iproute);
Free(el);
rt->rt_llinfo = 0;
}
Index: netiso/iso_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/iso_pcb.c,v
retrieving revision 1.34
diff -p -u -u -p -r1.34 iso_pcb.c
--- netiso/iso_pcb.c 9 Dec 2006 05:33:09 -0000 1.34
+++ netiso/iso_pcb.c 9 Dec 2006 08:56:39 -0000
@@ -511,8 +511,7 @@ iso_pcbdetach(void *v)
printf("iso_pcbdetach 3 \n");
}
#endif
- if (isop->isop_route.ro_rt != NULL)
- rtflush((struct route *)&isop->isop_route);
+ rtcache_free((struct route *)&isop->isop_route);
#ifdef ARGO_DEBUG
if (argo_debug[D_ISO]) {
printf("iso_pcbdetach 3.1\n");
Index: netiso/tp_iso.c
===================================================================
RCS file: /cvsroot/src/sys/netiso/tp_iso.c,v
retrieving revision 1.26
diff -p -u -u -p -r1.26 tp_iso.c
--- netiso/tp_iso.c 9 Dec 2006 05:33:09 -0000 1.26
+++ netiso/tp_iso.c 9 Dec 2006 08:56:39 -0000
@@ -467,8 +467,7 @@ tpclnp_output_dg(struct mbuf *m0, ...)
/*
* Free route allocated by clnp (if the route was indeed allocated)
*/
- if (tmppcb.isop_route.ro_rt != NULL)
- rtflush((struct route *)&tmppcb.isop_route);
+ rtcache_free((struct route *)&tmppcb.isop_route);
return (err);
}
Index: netkey/key.c
===================================================================
RCS file: /cvsroot/src/sys/netkey/key.c,v
retrieving revision 1.147
diff -p -u -u -p -r1.147 key.c
--- netkey/key.c 9 Dec 2006 05:33:09 -0000 1.147
+++ netkey/key.c 9 Dec 2006 08:56:40 -0000
@@ -2829,8 +2829,7 @@ key_delsah(sah)
return;
}
- if (sah->sa_route.ro_rt != NULL)
- rtflush(&(struct route *)sah->sa_route);
+ rtcache_free(&(struct route *)sah->sa_route);
/* remove from tree of SA index */
if (__LIST_CHAINED(sah))
@@ -8232,9 +8231,9 @@ key_sa_routechange(dst)
LIST_FOREACH(sah, &sahtree, chain) {
ro = &sah->sa_route;
- if (ro->ro_rt != NULL && dst->sa_len == ro->ro_dst.sa_len &&
+ if (dst->sa_len == ro->ro_dst.sa_len &&
bcmp(dst, &ro->ro_dst, dst->sa_len) == 0)
- rtflush(ro);
+ rtcache_free(ro);
}
return;
--oTHb8nViIGeoXxdp--