tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Two NetBSD networking stack questions



On Wed, Nov 9, 2011 at 11:38 AM, David Young <dyoung%pobox.com@localhost> wrote:
> On Tue, Nov 08, 2011 at 04:22:46PM -0700, Andrew Collins wrote:
>> I'm working on an embedded NetBSD product, and I've hit two issues
>> with the networking stack that I'm curious about.
>>
>> The first question is related to ether_output's route lookups.  In
>> cases where a route has RTF_GATEWAY is set, and there is no rt_gwroute
>> or rt_gwroute isn't RTF_UP, a route lookup is done, and after
>> obtaining a usable route for the gateway the rt_ifp is checked against
>> the current ifp to make sure the route is on the same interface we're
>> trying to send from.  What I find odd is that this is *not* done for
>> cases where we find a usable rt_gwroute right off the bat, and in
>> practice, I see certain situations where a cloned route on another
>> interface is picked up for rt_gwroute, then used during the ARP
>> request for the gateway.  It ends up sort of working, because
>> arpresolve uses the current ifp to make the ARP request so it gets
>> sent out the right interface, but we end up in this weird situation
>> where we have a route on a different ifp holding information about a
>> link level address for a host off of our ifp.  Is there a reason that
>> rt_gwroute isn't checked to ensure rt_ifp == ifp even when we don't do
>> a lookup?
>
> How does one reproduce this situation where rt_gwroute->rt_ifp != ifp?
>

The way I ran into was it was with a default route which was an
interface route on an interface capable of arp, and hence was cloning.
 A packet happened to get
sent to an address that later on ends up being the gateway for a route
on a separate interface.  When this packet gets sent we create a
cloned route on the original
interface.  Shortly afterwards, the route on the 2nd interface gets
created with a gateway pointing to that address, and rt_gwroute picks
up the cloned route on other
interface.

I can repro in a similar fashion:

Destination        Gateway            Flags    Refs      Use    Mtu  Interface
default            link#10            UCS         1        0      -  vlan1
192.168.0/24       link#10            UC          0        0      -  vlan1
192.168.10/24       link#7             UC          2        0      -  vlan2

In this setup, ping out to 192.168.20.100, get:

Destination        Gateway            Flags    Refs      Use    Mtu  Interface
default            link#10            UCS         1        0      -  vlan1
192.168.0/24       link#10            UC          0        0      -  vlan1
192.168.10/24       link#7             UC          2        0      -  vlan2
192.168.20.100       link#10            UHLc        1       38      -  vlan1

Now bring up an interface at 192.168.20.1/24, and then set up a
gateway route for an address reachable through this interface:

Destination        Gateway            Flags    Refs      Use    Mtu  Interface
default            link#10            UCS         1        0      -  vlan1
192.168.0/24       link#10            UC          0        0      -  vlan1
192.168.10/24       link#7             UC          2        0      -  vlan2
192.168.20/24      link#12            UC          0        0      -  vlan3
192.168.20.100       link#10            UHLc        1       38      -  vlan1
192.168.30.1       192.168.20.100      UGHS        0        0      -  vlan3

After doing this, if you ping 192.168.30.1,  you'll see arps out on
vlan3 for 192.168.20.100, but after dropping into ddb and looking in
arptab:

rtentry=0x8669b990 flags=0x807 refcnt=0 use=4 expire=0
 key=[16,2,0,0,192,168,30,1,0,0,0,0,0,0,0,0]
 mask=[NULL] gw=[16,2,0,0,192,168,20,100,0,0,0,0,0,0,0,0]
 ifp=0xcaf8e020 (vlan3) ifa=0xc01bce00
  ifa_addr=[16,2,0,0,192,168,20,1,0,0,0,0,0,0,0,0]
  ifa_dsta=[16,2,0,0,192,168,20,255,0,0,0,0,0,0,0,0]
  ifa_mask=[7,2,0,0,255,255,255]
  flags=0x101,refcnt=5,metric=0
 gwroute=0x8669baa0 llinfo=0x0

rtentry=0x8669baa0 flags=0x2405 refcnt=1 use=1 expire=1320944433
 key=[16,2,0,0,192,168,20,100,0,0,0,0,0,0,0,0]
 mask=[NULL] gw=[19,18,10,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
 ifp=0xc01bb800 (vlan1) ifa=0xc01bca00
  ifa_addr=[16,2,0,0,192,168,0,1,0,0,0,0,0,0,0,0]
  ifa_dsta=[16,2,0,0,192,168,0,255,0,0,0,0,0,0,0,0]
  ifa_mask=[7,2,0,0,255,255,255]
  flags=0x101,refcnt=6,metric=0
 gwroute=0x0 llinfo=0xc00253e0
  la_rt=0x8669baa0 la_hold=0x862b5300, la_asked=0x3

The gwroute of our route points to a route on vlan1, and we have the
cloned route on vlan1 holding llinfo and la_hold for information
meant for vlan3.

This is obviously a pretty weird setup, but since we check the other
cases for rt_ifp == ifp in ether_output, and it's *possible* to get
into this state,
I don't see why we don't check this for all cases.

>> The second question is related to PPP.  I'm running into a case where
>> packets getting sent to a local address are actually sent out on the
>> wire for PPP devices.  For example:
>>
>> pppoe1: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1492
>>         inet 192.168.150.1 -> 192.168.149.1 netmask 0xff000000
>>
>> If I ping 192.168.150.1, I actually see packets getting emitted on the
>> wire where the src addr == dst addr.  Is this espected behavior?
>
> What does 'route -n get 192.168.150.1' say?

# route -n get 192.168.150.1
   route to: 192.168.150.1
destination: default
       mask: default
    gateway: 192.168.149.1
 local addr: 192.168.150.1
  interface: pppoe1
      flags: <UP,GATEWAY,DONE,STATIC>
 recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
       0         0         0         0         0         0         0         0

# netstat -r -n
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use    Mtu  Interface
default            192.168.149.1      UGS         1        1      -  pppoe1
127.0.0.1          127.0.0.1          UH          2      458  33176  lo0
192.168.149.1      192.168.150.1      UH          1        0      -  pppoe1

I tried this is as an interface route as well and got the same result
(packets on the wire that is).  Am I just screwing up the default
route?

>
> Dave
>
> --
> David Young             OJC Technologies is now Pixo
> dyoung%pixotech.com@localhost     Urbana, IL   (217) 344-0444 x24
>


Home | Main Index | Thread Index | Old Index