OpenSolaris

Printable Version Enter a New Search
Bug ID 6626652
Synopsis DHCP client's IFF_UP handling is not quite right
State 10-Fix Delivered (Fix available in build)
Category:Subcategory network:dhcp_client
Keywords
Responsible Engineer Peter Memishian
Reported Against
Duplicate Of
Introduced In solaris_nevada
Commit to Fix snv_78
Fixed In snv_78
Release Fixed solaris_nevada(snv_78)
Related Bugs 4354207
Submit Date 6-November-2007
Last Update Date 21-November-2007
Description
As part of 4354207, the DHCP client was changed to bring the interface
IFF_UP in open_ip_lif() (rather than configure_v4_lease()) so that
broadcast traffic could immediately be sent and received over the
interface.  In principle this is fine, but an oversight was made in the
implementation: lif_flags (which shadows the current interface flags)
was never updated.  As a result, after this:

                /*
                 * Start from a clean slate.
                 */
                canonize_lif(lif, B_FALSE);

                lifr.lifr_flags |= IFF_UP;
                if (ioctl(v4_sock_fd, SIOCSLIFFLAGS, &lifr) == -1) {
                        errmsg = "cannot bring up";
                        goto failure;
                }

SIOCGLIFFLAGS will include IFF_UP, but lif_flags will not.  Thus, any
calls to verify_lif() will hit this test and abandon the interface:

        if ((lif->lif_flags ^ lifr.lifr_flags) & IFF_UP) {
                dhcpmsg(MSG_DEBUG, "verify_lif: user has %s %s",
                    lifr.lifr_flags & IFF_UP ? "started up" : "shut down",
                    lif->lif_name);
                return (B_FALSE);
        }

In general, this doesn't occur because shortly after calling open_ip_lif(),
we call set_lif_dhcp() which reloads lif_flags.  However, in the paths where
that (or other similar reloads) do not occur, we'll eventually run afoul of
the check in verify_lif().

On a related note, the following code is still in configure_v4_lease():

        if (ioctl(v4_sock_fd, SIOCGLIFFLAGS, &lifr) == -1) {
                dhcpmsg(MSG_ERR, "configure_v4_lease: cannot get interface "
                    "flags for %s", lif->lif_name);
                return (B_FALSE);
        }

        lifr.lifr_flags |= IFF_UP;
        if (ioctl(v4_sock_fd, SIOCSLIFFLAGS, &lifr) == -1) {
                dhcpmsg(MSG_ERR, "configure_v4_lease: cannot set interface "
                    "flags for %s", lif->lif_name);
                return (B_FALSE);
        }
        lif->lif_flags = lifr.lifr_flags;

Since IFF_UP is now set as part of open_ip_lif(), this code is no longer
necessary and should be removed.
Work Around
N/A
Comments
N/A