NetBSD-Bugs archive

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

bin/40122: dhclient-script uses ineffective ping to test router reachability

>Number:         40122
>Category:       bin
>Synopsis:       dhclient-script uses ineffective ping to test router 
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Dec 06 18:35:00 +0000 2008
>Originator:     Robert Elz
>Release:        NetBSD 4.0_STABLE (applies in current within past 8 hours and 
>all previous systems, forever probably)
        Prince of Songkla University
System: NetBSD 4.0_STABLE NetBSD 4.0_STABLE 
(JADE-1.696-20080517) #9: Fri May 23 18:55:13 ICT 2008 i386
Architecture: i386
Machine: i386
        When dhclient fails to obtain a lease from a dhcp server, it
        attempts to verify a previous lease.  For that to work, the
        dhcp status of the lease needs to be OK (not expired etc), and
        then we need to be connected to the same network that we were
        connected to when the lease was obtained.

        dhclient (dhclient-script) tests the latter by attempting to
        ping the default router, if the router answers, then that's
        fairly good evidence that we're on that network, if it doesn't
        then the lease probably isn't going to be any good to us, and
        dhclient will look and see if it has some other valid lease
        that might work instead.

        All that is fine of itself.

        It may be that dhcpcd has similar behaviour, its man page's
        description of its -E option (or --lastlease) says ...

     -E, --lastlease
             If dhcpcd cannot obtain a lease, then try to use the last lease
             acquired for the interface.  If the -p, --persistent option is
             not given then the lease is used if it hasn't expired.

        Unfortunately, it does not say what "try to use" means - and I
        see no references to ping in its script files, so it may not
        have the problem I am seeing with dhclient.   Or it might.

        For the problem, I need to describe the network configuration
        I'm living in - which I suspect is a fairly common setup
        in may places these days.

        I have a laptop (notebok, whatever...) which has both wired and
        wireless interfaces.  My work environment has both wired and
        wireless networks available to use.  Typically I plug in the
        wire (it is faster), and the wireless is just "also there".
        All that's fine.

        The "common configuration" I'm referring to is that the wired
        and wireless networks are bridged together - they operate out
        of the same address space and (naturally) both have the same
        default router.

        The network uses WEP (yes, I know) and until recently I had
        just used a dhclient.conf file with a whole bunch of
                "ssid abce nwkey 1234"
        type clauses in its "media" statement for the interfaces,
        dhclient would cycle through those, trying them all one after
        another until the dhcp server responded.   Then we'd know what
        location we're at today, and everything works.  If there was a
        problem with the dhcp server, the chances that the media config
        would be something appropriate were small, and the wireless would
        just not work (though I am not sure why I never saw the current
        problem, maybe I did, and the obvious ssid messup made me
        ignore everything else).

        Recently, with the expectation of making all this go faster,
        I decided to try wpa_supplicant (again) - let it pick the ssid
        (etc) not have dhclient do any media config at all.  That was
        after a brief dialog with Steve Bellovin who had said on the
        list that it was working for him, whereas I'd had it fail with
        the same same basic hardware (same wireless ethernet controller).
        His suggestion was to upgrade wpa_supplicant, I'd had a fairly
        old one, and my previous test had been a while ago as well.
        I did that, and it now works much better.

        Better, but not perfect.   Right now, it has configured the
        correct ssid, but managed to "forget" the nwkey (other times
        this has worked, with the exact same wpa.conf, so I'm not
        sure what's happening there - and that's not the current issue).

        What "amused" me is that dhclient decided that the interface is
        working (without a key, it most certainly doesn't) and configured
        in a lease obtained yesterday.  In order to do that, without
        receiving a reply from the dhcp server over the interface, which
        it clearly cannot have done, it must have successfully pinged
        the default router.  In order to do that, without
        receiving a reply from the dhcp server over the interface, which
        it clearly cannot have done, it must have successfully pinged
        the default router.

        This is how dhclient-script does that ...

        eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
            $new_broadcast_arg $medium"
        sleep 1
                                ### That is, ifconfig the addr we're testing

        if [ ! -z "$new_routers" ]; then
                                ### if we know the defualt router
                set -- $new_routers
                                ### then ping it (one of them, just once)
                if ping -n -q -c 1 -w 1 $1; then
                                ### if ping says all OK, then
                        if [ \( ! -z "$alias_ip_address" \) -a \
                            \( "x$new_ip_address" != "x$alias_ip_address" \) ]
                                ### finish configuring the interface
                                ### if we need to configure any more
                                ### (other addresses from the lease)

                                ifconfig $interface inet alias \
                                    $alias_ip_address $alias_subnet_arg
                                route add $alias_ip_address

                        route add $new_ip_address >/dev/null 2>&1

                        ### and we're done - address assigned and working

                        exit_with_hooks 0

                        ### if any of that fails, undo the
                        ### config and we abandon that address...
                        ### (code for that not relevant now).

        Now I expect the actual problem is obvious to most people.
        The wired interface is configured already on the same
        network, and reaches the same default router.  The ping
        command included in the code fragment above will end up using
        the wired interface, ping works, and dhclient concludes that
        the wireless iterface is working fine, configures the wireless
        with the old address from the old lease, and says "I'm happy enough".

        This is, of course, all bogus, and should be fixed...

        Don't be absurd, don't try to repeat it, just
        believe me...

        This is not so easy, if ping had an option to choose a
        particular net interface to use, it would be a simple
        fix to dhclient-script to use that option.

        Ping does have the -I srcaddr option, but here that
        might make no difference (I guess I should test this
        sometime..., maybe it would help, as the replies have
        to come back to that address, and I hope that we wouldn't
        answer an arp for an address that's on the wireless interface
        when we see it arrive on the wired interface, so this might
        be enough to solve the current problem - maybe).

        Better, I think, would be to teach ping how to select a
        paticular iterface to use, and then teach dhclient-script to
        use that new option.

        ping6 has a -I option that selects the interface (rather than
        a source addr) (and -S that allows the source addr to be set).

        At this stage we can't really do the rational thing and
        make ping copy the option usage of ping6, so most probably
        we should use -S (currently unused in ping) to select the
        sending interface (you can almost imagine a way to justify
        that option choice, other than "inverted from ping6").

        With a way to make ping send only on the interface we're
        trying to test reachability of the default router out of,
        the ping will be acceptably good enough (as good as it ever
        was) for making this test, and dhclient could me made to
        use that.

        Without that (and if the -I option doesn't help) then I see no
        good way to overcome this, and as more and more people are
        in bridged wireless/wired networks, I expect ths problem to
        occur more frequently - its only real effect is probably
        endless confusion (how can my network be up and working
        without a WEP key when my AP required one ???)

        If dhcpcd also attempts to use old leases (perhaps only with
        its -E option - in DHCP doing this is optional, but generally
        regarded as a good thing, as it allows clients to continue
        working properly even if the dhcp server is down temporarily)
        then it might have a similar problem.  It all depends just what
        "try to use" really means.

Home | Main Index | Thread Index | Old Index