Subject: kern/10483: ipflow_fastforward() passes incorrect address to if_output (+fix)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 06/29/2000 23:39:13
>Number:         10483
>Category:       kern
>Synopsis:       ipflow_fastforward() passes incorrect address to if_output (+fix)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jun 29 23:40:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Zdenek Salvet
>Release:        1.4.2, -current of 6/29/2000
>Organization:
Masaryk University, Brno, Czech Republic
>Environment:
options GATEWAY

>Description:
  ipflow_fastforward() passes destination address instead of
  the address of the gateway when using route to gateway.
  The address is used to make the ARP requests after ARP table entry expires.
  If it is incorrect, ARP will fail and all traffic using the gateway
  will stop until correct ARP request is triggered (for tens of seconds
  in my situation).

>How-To-Repeat:

  machine1# route add -host machine2 router1-int1
  router1# route add -host machine2 router2-int1
  machine1# ttcp -t -u machine2
  router1# arp -d router2-int1         
               # or wait until ARP table entry expires (20 min)

>Fix:
  (diff against 1.4.2)

diff -u netinet/ip_flow.c.orig netinet/ip_flow.c
--- netinet/ip_flow.c.orig      Thu Jun 29 19:18:39 2000
+++ netinet/ip_flow.c   Thu Jun 29 19:32:19 2000
@@ -146,6 +146,7 @@
        struct ip *ip;
        struct ipflow *ipf;
        struct rtentry *rt;
+       struct sockaddr *dst;
        int error;
        int iplen;
 
@@ -226,8 +227,14 @@
         */
        ipf->ipf_uses++;
        PRT_SLOW_ARM(ipf->ipf_timer, IPFLOW_TIMER);
+
+       if (rt->rt_flags & RTF_GATEWAY)
+               dst = rt->rt_gateway;
+       else
+               dst = &ipf->ipf_ro.ro_dst;
+       
        if ((error = (*rt->rt_ifp->if_output)(rt->rt_ifp, m,
-           &ipf->ipf_ro.ro_dst, rt)) != 0) {
+           dst, rt)) != 0) {
                if (error == ENOBUFS)
                        ipf->ipf_dropped++;
                else


>Release-Note:
>Audit-Trail:
>Unformatted: