Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Aug 2003 10:45:18 +0200 (CEST)
From:      Martin Blapp <mb@imp.ch>
To:        current@freebsd.org
Subject:   Dhclient fix for systems with media settings
Message-ID:  <20030805103347.V31668@cvs.imp.ch>

next in thread | raw e-mail | index | archive | help

Hi all,

If you used wi(4) or en(4) wavelan cards and you had problems with dhclient,
you should try this patch, which treats interfaces with media settings
differently.

http://people.freebsd.org/~mbr/patches/dhclient-interfacepolling-fixup.diff

I'll produce a more clean patch this evening, and also adapt the patch to
the ISC style, so it can be submitted again.

--- src/contrib/isc-dhcp/includes/dhcpd.h.orig	Mon Aug  4 23:57:06 2003
+++ src/contrib/isc-dhcp/includes/dhcpd.h	Mon Aug  4 23:57:37 2003
@@ -782,6 +782,7 @@
 	char name [IFNAMSIZ];		/* Its name... */
 	int linkstatus;			/* Link status */
 	int ieee802;			/* True if media is ieee802 */
+	int mediaflag;			/* True if dhclient.conf has media settings */
 	int index;			/* Its index. */
 	int rfdesc;			/* Its read file descriptor. */
 	int wfdesc;			/* Its write file descriptor, if
--- src/contrib/isc-dhcp/client/dhclient.c.orig	Tue Aug  5 00:42:37 2003
+++ src/contrib/isc-dhcp/client/dhclient.c	Tue Aug  5 10:01:17 2003
@@ -257,7 +257,9 @@
 			    log_fatal ("%s: interface name too long (max %ld)",
 				       argv [i], (long)strlen (argv [i]));
  		    strlcpy (tmp -> name, argv [i], IFNAMSIZ);
-		    set_ieee802(tmp);
+#ifdef __FreeBSD__
+		    set_ieee80211(tmp);
+#endif
 		    tmp->linkstatus = interface_active(tmp);
 		    if (interfaces) {
 			    interface_reference (&tmp -> next,
@@ -412,7 +414,16 @@
 					     INTERFACE_AUTOMATIC)) !=
 			     INTERFACE_REQUESTED))
 				continue;
-			set_ieee802(ip);
+#ifdef __FreeBSD__
+			set_ieee80211(ip);
+#endif
+#ifdef ENABLE_POLLING_MODE
+			if (ip -> client -> config -> media != NULL)
+				ip->mediaflag = 1;
+			else
+				ip->mediaflag = 0;
+#endif /* ifdef ENABLE_POLLING_MODE */
+
 			script_init (ip -> client,
 				     "PREINIT", (struct string_list *)0);
 			if (ip -> client -> alias)
@@ -1385,9 +1396,6 @@
 	int interval;
 	int increase = 1;

-	if (interface_active(client -> interface) == 0)
-		return;
-
 	/* Figure out how long it's been since we started transmitting. */
 	interval = cur_time - client -> first_sending;

@@ -1427,6 +1435,9 @@
 		}
 	}

+	if (interface_active(client -> interface) == 0)
+		return;
+
 	/* If we're supposed to increase the interval, do so.  If it's
 	   currently zero (i.e., we haven't sent any packets yet), set
 	   it to one; otherwise, add to it a random number between
@@ -3215,14 +3226,29 @@
 	if (ifmr.ifm_status & IFM_AVALID) {
 		if (ip->ieee802) {
 			if ((IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) &&
-			     (ifmr.ifm_status & IFM_ACTIVE))
+			     (ifmr.ifm_status & IFM_ACTIVE)) {
+				if (ip->mediaflag &&
+				    ip -> client -> state != S_BOUND)
+					return (2);
 				return (1);
+			}
 		} else {
-			if (ifmr.ifm_status & IFM_ACTIVE)
+			if (ifmr.ifm_status & IFM_ACTIVE) {
+				if (ip->mediaflag &&
+				    ip -> client -> state != S_BOUND)
+					return (2);
 				return (1);
+			}
 		}
 	}

+	/*
+	 * If dhclient.conf contains media settings, we cannot
+	 * abort if the interface is not set to active mode.
+	 */
+	if (ip->mediaflag && ip -> client -> state != S_BOUND)
+		return (1);
+
 	return (0);
 #else /* ifdef __FreeBSD__ */

@@ -3231,7 +3257,7 @@
 }

 #ifdef __FreeBSD__
-set_ieee802 (struct interface_info *ip) {
+set_ieee80211 (struct interface_info *ip) {

 	struct ieee80211req     ireq;
 	u_int8_t                data[32];
@@ -3267,12 +3293,20 @@
 #endif /* __FreeBSD__ */

 #ifdef ENABLE_POLLING_MODE
+/* Go to background after some time */
+void state_background (cpp)
+	void *cpp;
+{
+	go_daemon ();
+}
+
 /* Check the state of the NICs if we have link */
 void state_link (cpp)
         void *cpp;
 {
 	struct interface_info *ip;
 	struct client_state *client;
+	int result;

 #ifdef DEBUG
 	printf("Polling interface status\n");
@@ -3281,7 +3315,11 @@
 		if (ip->linkstatus == 0 || doinitcheck == 0) {
 			if (interface_active(ip)) {
 #ifdef DEBUG
-				printf("%s: Found Link on interface\n", ip->name);
+				if (ip->mediaflag)
+					printf("%s: Trying different media settings on interface\n",
+						ip->name);
+				else
+					printf("%s: Found Link on interface\n", ip->name);
 #endif
 				for (client = ip -> client;
 				     client; client = client -> next) {
@@ -3310,18 +3348,29 @@
 					}
 			 	}
 				ip->linkstatus = 0;
+				if (! ip->mediaflag && ! doinitcheck) {
+					add_timeout(cur_time + (polling_interval * 2),
+					             state_background, client, 0, 0);
+				}
 			}
 		} else {
-			if (interface_active(ip) == 0) {
+			if ((result = interface_active(ip)) == 0) {
 #ifdef DEBUG
 				printf("%s: Lost Link on interface\n", ip->name);
 #endif
 				ip->linkstatus = 0;
 			}
+			if (result == 2) {
+				for (client = ip -> client;
+                                     client; client = client -> next) {
+					cancel_timeout(state_init, client);
+					add_timeout(cur_time + random () % 5,
+						state_reboot, client, 0, 0);
+                                }
+				ip->linkstatus = 1;
+			}
 		}
 	}
-	if (doinitcheck)
-		go_daemon ();
 	doinitcheck = 1;
 }
 #endif /* ifdef ENABLE_POLLING_MODE */



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