Subject: kern/21903: in_addprefix() not handling RTF_HOST (pointtopoint) correctly.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <seanb@qnx.com>
List: netbsd-bugs
Date: 06/16/2003 13:43:21
>Number:         21903
>Category:       kern
>Synopsis:       in_addprefix() not handling RTF_HOST (pointtopoint) correctly.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 16 13:44:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Sean Boudreau
>Release:        1-6
>Organization:
QNX
>Environment:
NetBSD  1.6 NetBSD 1.6 (GENERIC) #0: Sun Sep  8 19:43:40 UTC 2002     autobuild@tgm.daemon.org:/autobuild/i386/OBJ/autobuild/src/sys/arch/i386/compile/GENERIC i386
>Description:
On a 1.6 box:


# ifconfig ex0
ex0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        capabilities=7<IP4CSUM,TCP4CSUM,UDP4CSUM>
        enabled=0<>
        address: 00:04:75:dc:7e:68
        media: Ethernet autoselect (100baseTX full-duplex)
        status: active
        inet 10.7.0.131 netmask 0xff000000 broadcast 10.255.255.255
        inet6 fe80::204:75ff:fedc:7e68%ex0 prefixlen 64 scopeid 0x2
# ifconfig gif0
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
# netstat -rnfinet
Routing tables

Internet:
Destination        Gateway            Flags     Refs     Use    Mtu  Interface
10                 link#2             UC          0        0      -  ex0
127                127.0.0.1          UGRS        0        0  33220  lo0
127.0.0.1          127.0.0.1          UH          1        2  33220  lo0
# ifconfig gif0 10.0.0.1 10.0.0.2
# netstat -rnfinet
Routing tables

Internet:
Destination        Gateway            Flags     Refs     Use    Mtu  Interface
10                 link#2             UC          0        0      -  ex0
127                127.0.0.1          UGRS        0        0  33220  lo0
127.0.0.1          127.0.0.1          UH          1        2  33220  lo0
# route add -host -iface 10.0.0.2 10.0.0.1
add host 10.0.0.2: gateway 10.0.0.1

^^^^^^^^^^^^^^^^^
This last step appears to be a regression from 1.5 as on that version
the route is added automatically by the kernel.


Here's a suggested diff:

-seanb



Index: netinet/in.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in.c,v
retrieving revision 1.76
diff -c -r1.76 in.c
*** netinet/in.c        2002/05/09 06:49:15     1.76
--- netinet/in.c        2003/06/04 14:16:20
***************
*** 897,922 ****
        int flags;
  {
        struct in_ifaddr *ia;
!       struct in_addr prefix, mask, p;
        int error;

        if ((flags & RTF_HOST) != 0)
                prefix = target->ia_dstaddr.sin_addr;
!       else
                prefix = target->ia_addr.sin_addr;
!       mask = target->ia_sockmask.sin_addr;
!       prefix.s_addr &= mask.s_addr;

        TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
-               /* easy one first */
-               if (mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
-                       continue;
-
                if (rtinitflags(ia))
                        p = ia->ia_dstaddr.sin_addr;
!               else
                        p = ia->ia_addr.sin_addr;
!               p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
                if (prefix.s_addr != p.s_addr)
                        continue;

--- 897,920 ----
        int flags;
  {
        struct in_ifaddr *ia;
!       struct in_addr prefix, p;
        int error;

        if ((flags & RTF_HOST) != 0)
                prefix = target->ia_dstaddr.sin_addr;
!       else {
                prefix = target->ia_addr.sin_addr;
!               prefix.s_addr &= target->ia_sockmask.sin_addr.s_addr;
!       }

        TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
                if (rtinitflags(ia))
                        p = ia->ia_dstaddr.sin_addr;
!               else {
                        p = ia->ia_addr.sin_addr;
!                       p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
!               }
!
                if (prefix.s_addr != p.s_addr)
                        continue;

***************
*** 947,953 ****
        struct in_ifaddr *target;
  {
        struct in_ifaddr *ia;
!       struct in_addr prefix, mask, p;
        int error;

        if ((target->ia_flags & IFA_ROUTE) == 0)
--- 945,951 ----
        struct in_ifaddr *target;
  {
        struct in_ifaddr *ia;
!       struct in_addr prefix, p;
        int error;

        if ((target->ia_flags & IFA_ROUTE) == 0)
***************
*** 955,975 ****

        if (rtinitflags(target))
                prefix = target->ia_dstaddr.sin_addr;
!       else
                prefix = target->ia_addr.sin_addr;
!       mask = target->ia_sockmask.sin_addr;
!       prefix.s_addr &= mask.s_addr;

        TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
-               /* easy one first */
-               if (mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
-                       continue;
-
                if (rtinitflags(ia))
                        p = ia->ia_dstaddr.sin_addr;
!               else
                        p = ia->ia_addr.sin_addr;
!               p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
                if (prefix.s_addr != p.s_addr)
                        continue;

--- 953,971 ----

        if (rtinitflags(target))
                prefix = target->ia_dstaddr.sin_addr;
!       else {
                prefix = target->ia_addr.sin_addr;
!               prefix.s_addr &= target->ia_sockmask.sin_addr.s_addr;
!       }

        TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
                if (rtinitflags(ia))
                        p = ia->ia_dstaddr.sin_addr;
!               else {
                        p = ia->ia_addr.sin_addr;
!                       p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
!               }
!
                if (prefix.s_addr != p.s_addr)
                        continue;
>How-To-Repeat:

>Fix:

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