diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index aa30429..f91dc1a 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -328,6 +328,13 @@ in6_rtalloc(struct route_in6 *ro, u_int fibnum) rtalloc_ign_fib((struct route *)ro, 0ul, fibnum); } +int +in6_rtalloc_nolock(struct route_in6 *ro, u_int fibnum) +{ + + return (rtalloc_fib_nolock((struct route *)ro, 0, fibnum)); +} + void in6_rtalloc_ign(struct route_in6 *ro, u_long ignflags, u_int fibnum) { diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index bdb4cca..1f68e3f3 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -831,6 +831,7 @@ void in6_rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *, int in6_rtrequest(int, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, struct rtentry **, u_int); void in6_rtalloc(struct route_in6 *, u_int); +int in6_rtalloc_nolock(struct route_in6 *, u_int); void in6_rtalloc_ign(struct route_in6 *, u_long, u_int); struct rtentry *in6_rtalloc1(struct sockaddr *, int, u_long, u_int); #endif /* _KERNEL */ diff --git a/sys/netinet6/ip6_fastfwd.c b/sys/netinet6/ip6_fastfwd.c index b1a22b9..5131d9c 100644 --- a/sys/netinet6/ip6_fastfwd.c +++ b/sys/netinet6/ip6_fastfwd.c @@ -261,22 +261,23 @@ again: /* * Find route to destination. */ - in6_rtalloc(&ro, M_GETFIB(m)); + in6_rtalloc_nolock(&ro, M_GETFIB(m)); if (ro.ro_rt == NULL || (ro.ro_rt->rt_flags & RTF_REJECT)) { IP6STAT_INC(ip6s_noroute); in6_ifstat_inc(rcvif, ifs6_in_noroute); icmp6_error(mcopy, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE, 0); - RO_RTFREE(&ro); +// RO_RTFREE(&ro); mcopy = NULL; goto dropin; } - if (!(ro.ro_rt->rt_flags & RTF_UP)) { + if (!(ro.ro_rt->rt_flags & RTF_UP) || + !(ro.ro_rt->rt_ifp->if_flags & IFF_UP)) { IP6STAT_INC(ip6s_noroute); in6_ifstat_inc(rcvif, ifs6_in_noroute); icmp6_error(mcopy, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, 0); - RO_RTFREE(&ro); +// RO_RTFREE(&ro); mcopy = NULL; goto dropin; } @@ -288,7 +289,7 @@ again: if (m->m_pkthdr.len > IN6_LINKMTU(oif)) { in6_ifstat_inc(oif, ifs6_in_toobig); icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, IN6_LINKMTU(oif)); - RO_RTFREE(&ro); +// RO_RTFREE(&ro); mcopy = NULL; goto dropout; } @@ -297,7 +298,7 @@ again: */ if (ro.ro_rt->rt_flags & RTF_GATEWAY) ro.ro_dst = *(struct sockaddr_in6 *)ro.ro_rt->rt_gateway; - RO_RTFREE(&ro); +// RO_RTFREE(&ro); /* * Outgoing packet firewall processing. */