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 */
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to