Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Aug 2012 17:25:23 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-current@freebsd.org
Cc:        Garrett Cooper <yanegomi@gmail.com>, lev@freebsd.org, current@freebsd.org, Peter Jeremy <peterjeremy@acm.org>
Subject:   Re: r239356: does it mean, that synchronous dhcp and dhcplcinet with disabled devd gone?
Message-ID:  <201208211725.23381.jhb@freebsd.org>
In-Reply-To: <201208210934.31484.jhb@freebsd.org>
References:  <20120821095527.GA33206@hell.ukr.net> <1959717636.20120821155308@serebryakov.spb.ru> <201208210934.31484.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, August 21, 2012 9:34:31 am John Baldwin wrote:
> On Tuesday, August 21, 2012 7:53:08 am Lev Serebryakov wrote:
> > Hello, Garrett.
> > You wrote 21 =E0=E2=E3=F3=F1=F2=E0 2012 =E3., 15:40:35:
> >=20
> > GC>> Try reverting r239356 -- if that works, then please let jhb@ know.
> > LS>   I'm confused by  this commit, because it seems (from comment alon=
e),
> > LS> that  dhclient  will not work without devd anymore (with "synchrono=
us
> > LS> dhcp" option in rc.conf).
> > LS>   Am I right?
> >   And if I'm right about understanding what this change does, it is
> >  POLA violation for sure. Both consequences: unable to use dhcclient
> >  without devd (user will need to restart it by hands after each cable
> >  unplugging event) and removing IP address from interface on cable
> >  unplugging or other interface down event but before lease is expired.
> >=20
> >   If I'm right in understanding this commit, I vote to back it out and
> >  find better solution, may be, two new options: one to remove IP and
> >  one to exit on interface down. And default behavior should be OLD
> >  ONE about IP address in any case and OLD ONE about exit in case when
> >  dhclient isn't started by devd, but by rc scripts directly.
>=20
> Humm.  devd is the more common case, and we explicitly don't use devd to =
start=20
> dhclient on boot even when devd is enabled (so out of the box dhcp would =
first=20
> be started by rc, but would be restarted by devd).
>=20
> Another option is to rework dhclient to work like it does on OpenBSD wher=
e it
> renews its lease if the link bounces, but to not exit when the link goes =
down. =20
> That case would fix the currently broken case that you unplug your cable,=
 take=20
> your laptop over to another network (e.g. take it home if suspend/resume=
=20
> works), then plug it back in and are still stuck with your old IP.

Ok, this is what I came up with, somewhat loosely based on OpenBSD's dhclie=
nt.
I tested that it survives the following:

=2D Unplugging/replugging does not kill an existing ssh session
=2D Using ifconfig down/up does not kill an existing ssh session
=2D Plugging into a different network does cause dhclient to negotiate
  a new lease on the new network

I've removed the bits to clear the old configuration if dhclient exits due =
to
'ifconfig down', and dhclient no longer exits on link down, but instead tra=
cks
the link state and enters the 'reboot' state when the link goes up.

Index: dhcpd.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2D-- dhcpd.h	(revision 239498)
+++ dhcpd.h	(working copy)
@@ -208,6 +208,7 @@
 	int			 errors;
 	int			 dead;
 	u_int16_t		 index;
+	int			 linkstat;
 };
=20
 struct timeout {
Index: dhclient.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2D-- dhclient.c	(revision 239498)
+++ dhclient.c	(working copy)
@@ -218,6 +218,7 @@
 	struct sockaddr *sa;
 	struct iaddr a;
 	ssize_t n;
+	int linkstat;
=20
 	n =3D read(routefd, &msg, sizeof(msg));
 	rtm =3D (struct rt_msghdr *)msg;
@@ -278,10 +279,14 @@
 			    ifi->name);
 			goto die;
 		}
=2D		if (!interface_link_status(ifi->name)) {
=2D			warning("Interface %s is down, dhclient exiting",
=2D			    ifi->name);
=2D			goto die;
+		linkstat =3D interface_link_status(ifi->name);
+		if (linkstat !=3D ifi->linkstat) {
+			debug("%s link state %s -> %s", ifi->name,
+			    ifi->linkstat ? "up" : "down",
+			    linkstat ? "up" : "down");
+			ifi->linkstat =3D linkstat;
+			if (linkstat)
+				state_reboot(ifi);
 		}
 		break;
 	case RTM_IFANNOUNCE:
@@ -321,8 +326,6 @@
=20
 die:
 	script_init("FAIL", NULL);
=2D	if (ifi->client->active)
=2D		script_write_params("old_", ifi->client->active);
 	if (ifi->client->alias)
 		script_write_params("alias_", ifi->client->alias);
 	script_go();
@@ -437,6 +440,7 @@
 		}
 		fprintf(stderr, " got link\n");
 	}
+	ifi->linkstat =3D 1;
=20
 	if ((nullfd =3D open(_PATH_DEVNULL, O_RDWR, 0)) =3D=3D -1)
 		error("cannot open %s: %m", _PATH_DEVNULL);

=2D-=20
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208211725.23381.jhb>