Author: ae
Date: Sat Jan  5 20:07:28 2013
New Revision: 245067
URL: http://svnweb.freebsd.org/changeset/base/245067

Log:
  MFC r244439:
    The selectroute function does own account of EHOSTUNREACH errors,
    no need to do it twice.
  
  MFC r244440:
    Make dst_sa initialization only when it is actually needed.
  
  MFC r244441:
    When we have some address to forward (e.g. it was specified with ipfw fwd),
    we should pass it as first argument into in6_selectroute_fib function to
    initiate new route lookup.
  
  Sponsored by: Yandex LLC

Modified:
  stable/9/sys/netinet6/ip6_output.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/netinet6/ip6_output.c
==============================================================================
--- stable/9/sys/netinet6/ip6_output.c  Sat Jan  5 19:18:50 2013        
(r245066)
+++ stable/9/sys/netinet6/ip6_output.c  Sat Jan  5 20:07:28 2013        
(r245067)
@@ -257,7 +257,7 @@ ip6_output(struct mbuf *m0, struct ip6_p
        int segleft_org = 0;
        struct secpolicy *sp = NULL;
 #endif /* IPSEC */
-       struct m_tag *fwd_tag;
+       struct m_tag *fwd_tag = NULL;
 
        ip6 = mtod(m, struct ip6_hdr *);
        if (ip6 == NULL) {
@@ -636,26 +636,23 @@ again:
        /* adjust pointer */
        ip6 = mtod(m, struct ip6_hdr *);
 
-       bzero(&dst_sa, sizeof(dst_sa));
-       dst_sa.sin6_family = AF_INET6;
-       dst_sa.sin6_len = sizeof(dst_sa);
-       dst_sa.sin6_addr = ip6->ip6_dst;
-       if (ro->ro_rt) {
+       if (ro->ro_rt && fwd_tag == NULL) {
                rt = ro->ro_rt;
                ifp = ro->ro_rt->rt_ifp;
-       } else if ((error = in6_selectroute_fib(&dst_sa, opt, im6o, ro,
-           &ifp, &rt, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m))) != 0) {
-               switch (error) {
-               case EHOSTUNREACH:
-                       V_ip6stat.ip6s_noroute++;
-                       break;
-               case EADDRNOTAVAIL:
-               default:
-                       break; /* XXX statistics? */
+       } else {
+               if (fwd_tag == NULL) {
+                       bzero(&dst_sa, sizeof(dst_sa));
+                       dst_sa.sin6_family = AF_INET6;
+                       dst_sa.sin6_len = sizeof(dst_sa);
+                       dst_sa.sin6_addr = ip6->ip6_dst;
+               }
+               error = in6_selectroute_fib(&dst_sa, opt, im6o, ro, &ifp,
+                   &rt, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
+               if (error != 0) {
+                       if (ifp != NULL)
+                               in6_ifstat_inc(ifp, ifs6_out_discard);
+                       goto bad;
                }
-               if (ifp != NULL)
-                       in6_ifstat_inc(ifp, ifs6_out_discard);
-               goto bad;
        }
        if (rt == NULL) {
                /*
@@ -933,7 +930,7 @@ again:
        if ((m->m_flags & M_IP6_NEXTHOP) &&
            (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
                dst = (struct sockaddr_in6 *)&ro->ro_dst;
-               bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in6));
+               bcopy((fwd_tag+1), &dst_sa, sizeof(struct sockaddr_in6));
                m->m_flags |= M_SKIP_FIREWALL;
                m->m_flags &= ~M_IP6_NEXTHOP;
                m_tag_delete(m, fwd_tag);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to