macos104-not-yet-20050511
[openafs.git] / src / afs / afs_server.c
index 0723773..ed0ff1d 100644 (file)
  * 
  */
 #include <afsconfig.h>
-#include "../afs/param.h"
+#include "afs/param.h"
 
-RCSID("$Header$");
+RCSID
+    ("$Header$");
 
-#include "../afs/stds.h"
-#include "../afs/sysincludes.h"        /* Standard vendor system headers */
+#include "afs/stds.h"
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
 
 #if !defined(UKERNEL)
+#if !defined(AFS_LINUX20_ENV)
 #include <net/if.h>
+#endif
 #include <netinet/in.h>
 
 #ifdef AFS_SGI62_ENV
-#include "../h/hashing.h"
+#include "h/hashing.h"
 #endif
-#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV)
+#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN60_ENV)
 #include <netinet/in_var.h>
 #endif /* AFS_HPUX110_ENV */
+#ifdef AFS_DARWIN60_ENV
+#include <net/if_var.h>
+#endif
 #endif /* !defined(UKERNEL) */
 
-#include "../afs/afsincludes.h"        /* Afs-based standard headers */
-#include "../afs/afs_stats.h"   /* afs statistics */
+#include "afsincludes.h"       /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* afs statistics */
+#include "rx/rx_multi.h"
 
 #if    defined(AFS_SUN56_ENV)
 #include <inet/led.h>
@@ -66,21 +73,41 @@ RCSID("$Header$");
 #endif
 
 /* Exported variables */
-afs_rwlock_t afs_xserver;               /* allocation lock for servers */
-struct server *afs_setTimeHost=0;       /* last host we used for time */
-struct server *afs_servers[NSERVERS];    /* Hashed by server`s uuid & 1st ip */
-afs_rwlock_t afs_xsrvAddr;              /* allocation lock for srvAddrs */
-struct srvAddr *afs_srvAddrs[NSERVERS];  /* Hashed by server's ip */
+afs_rwlock_t afs_xserver;      /* allocation lock for servers */
+struct server *afs_setTimeHost = 0;    /* last host we used for time */
+struct server *afs_servers[NSERVERS];  /* Hashed by server`s uuid & 1st ip */
+afs_rwlock_t afs_xsrvAddr;     /* allocation lock for srvAddrs */
+struct srvAddr *afs_srvAddrs[NSERVERS];        /* Hashed by server's ip */
 
 
 /* debugging aids - number of alloc'd server and srvAddr structs. */
-int afs_reuseServers  = 0;
+int afs_reuseServers = 0;
 int afs_reuseSrvAddrs = 0;
-int afs_totalServers  = 0;
+int afs_totalServers = 0;
 int afs_totalSrvAddrs = 0;
 
 
 
+static struct afs_stats_SrvUpDownInfo *
+GetUpDownStats(struct server *srv)
+{
+    struct afs_stats_SrvUpDownInfo *upDownP;
+    u_short fsport = AFS_FSPORT;
+
+    if (srv->cell)
+       fsport = srv->cell->fsport;
+
+    if (srv->addr->sa_portal == fsport)
+       upDownP = afs_stats_cmperf.fs_UpDown;
+    else
+       upDownP = afs_stats_cmperf.vl_UpDown;
+
+    if (srv->cell && afs_IsPrimaryCell(srv->cell))
+       return &upDownP[AFS_STATS_UPDOWN_IDX_SAME_CELL];
+    else
+       return &upDownP[AFS_STATS_UPDOWN_IDX_DIFF_CELL];
+}
+
 
 /*------------------------------------------------------------------------
  * afs_MarkServerUpOrDown
@@ -102,20 +129,21 @@ int afs_totalSrvAddrs = 0;
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
+void
+afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
 {
     register struct server *a_serverP = sa->server;
     register struct srvAddr *sap;
-    osi_timeval_t currTime, *currTimeP;     /*Current time*/
-    afs_int32 downTime;                             /*Computed downtime, in seconds*/
-    struct afs_stats_SrvUpDownInfo *upDownP; /*Ptr to up/down info record*/
+    osi_timeval_t currTime, *currTimeP;        /*Current time */
+    afs_int32 downTime;                /*Computed downtime, in seconds */
+    struct afs_stats_SrvUpDownInfo *upDownP;   /*Ptr to up/down info record */
 
     /*
      * If the server record is marked the same as the new status we've
      * been fed, then there isn't much to be done.
      */
-    if (( a_isDown &&  (sa->sa_flags & SRVADDR_ISDOWN)) || 
-       (!a_isDown && !(sa->sa_flags & SRVADDR_ISDOWN)))
+    if ((a_isDown && (sa->sa_flags & SRVADDR_ISDOWN))
+       || (!a_isDown && !(sa->sa_flags & SRVADDR_ISDOWN)))
        return;
 
     if (a_isDown) {
@@ -126,7 +154,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
                 * server's up/down stats */
                return;
            }
-       }    
+       }
        /* 
         * All ips are down we treat the whole server down
         */
@@ -138,7 +166,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
            afs_setTimeHost = 0;
     } else {
        sa->sa_flags &= ~SRVADDR_ISDOWN;
-        /* If any ips are up, the server is also marked up */
+       /* If any ips are up, the server is also marked up */
        a_serverP->flags &= ~SRVR_ISDOWN;
        for (sap = a_serverP->addr; sap; sap = sap->next_sa) {
            if (sap->sa_flags & SRVADDR_ISDOWN) {
@@ -146,7 +174,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
                 * server's up/down stats */
                return;
            }
-       }    
+       }
     }
 #ifndef AFS_NOSTATS
     /*
@@ -156,16 +184,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
     currTimeP = &currTime;
     osi_GetuTime(currTimeP);
 
-    if (sa->sa_portal == AFS_FSPORT) {
-       upDownP = (a_serverP->cell->cell == 1) ?
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-    } /*File Server record*/
-    else {
-       upDownP = (a_serverP->cell->cell == 1) ?
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-    } /*VL Server record*/
+    upDownP = GetUpDownStats(a_serverP);
 
     if (a_isDown) {
        /*
@@ -176,7 +195,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
 
        (upDownP->numDownRecords)++;
        (upDownP->numUpRecords)--;
-    } /*Server being marked down*/
+    } /*Server being marked down */
     else {
        /*
         * Server going down -> up; remember everything about this
@@ -192,68 +211,65 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
        if (a_serverP->numDowntimeIncidents == 1)
            (upDownP->numRecordsNeverDown)--;
        upDownP->sumOfDowntimes += downTime;
-       if ((upDownP->shortestDowntime == 0) ||
-           (downTime < upDownP->shortestDowntime))
+       if ((upDownP->shortestDowntime == 0)
+           || (downTime < upDownP->shortestDowntime))
            upDownP->shortestDowntime = downTime;
-       if ((upDownP->longestDowntime == 0) ||
-           (downTime > upDownP->longestDowntime))
+       if ((upDownP->longestDowntime == 0)
+           || (downTime > upDownP->longestDowntime))
            upDownP->longestDowntime = downTime;
 
 
        if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET0)
            (upDownP->downDurations[0])++;
-       else
-           if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET1)
-               (upDownP->downDurations[1])++;
-       else
-           if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET2)
-               (upDownP->downDurations[2])++;
-       else
-           if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET3)
-               (upDownP->downDurations[3])++;
-       else
-           if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET4)
-               (upDownP->downDurations[4])++;
-       else
-           if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET5)
-               (upDownP->downDurations[5])++;
+       else if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET1)
+           (upDownP->downDurations[1])++;
+       else if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET2)
+           (upDownP->downDurations[2])++;
+       else if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET3)
+           (upDownP->downDurations[3])++;
+       else if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET4)
+           (upDownP->downDurations[4])++;
+       else if (downTime <= AFS_STATS_MAX_DOWNTIME_DURATION_BUCKET5)
+           (upDownP->downDurations[5])++;
        else
            (upDownP->downDurations[6])++;
 
-    } /*Server being marked up*/
+    }                          /*Server being marked up */
 #endif
-} /*MarkServerUpOrDown*/
+}                              /*MarkServerUpOrDown */
 
 
-void afs_ServerDown(struct srvAddr *sa)
+void
+afs_ServerDown(struct srvAddr *sa)
 {
     register struct server *aserver = sa->server;
-    register struct srvAddr *sap;
 
     AFS_STATCNT(ServerDown);
     if (aserver->flags & SRVR_ISDOWN || sa->sa_flags & SRVADDR_ISDOWN)
        return;
     afs_MarkServerUpOrDown(sa, SRVR_ISDOWN);
     if (sa->sa_portal == aserver->cell->vlport)
-        print_internet_address("afs: Lost contact with volume location server ",
-                              sa, "", 1);
+       print_internet_address
+           ("afs: Lost contact with volume location server ", sa, "", 1);
     else
-        print_internet_address("afs: Lost contact with file server ", sa, "", 1);
+       print_internet_address("afs: Lost contact with file server ", sa, "",
+                              1);
 
-} /*ServerDown*/
+}                              /*ServerDown */
 
 
 /* return true if we have any callback promises from this server */
-static int HaveCallBacksFrom(struct server *aserver)
+int
+afs_HaveCallBacksFrom(struct server *aserver)
 {
     register afs_int32 now;
     register int i;
     register struct vcache *tvc;
 
     AFS_STATCNT(HaveCallBacksFrom);
-    now        = osi_Time();       /* for checking for expired callbacks */
-    for(i=0;i<VCSIZE;i++) { /* for all guys in the hash table */
-       for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) {
+    now = osi_Time();          /* for checking for expired callbacks */
+    for (i = 0; i < VCSIZE; i++) {     /* for all guys in the hash table */
+       for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
            /*
             * Check to see if this entry has an unexpired callback promise
             * from the required host
@@ -265,10 +281,11 @@ static int HaveCallBacksFrom(struct server *aserver)
     }
     return 0;
 
-} /*HaveCallBacksFrom*/
+}                              /*HaveCallBacksFrom */
 
 
-static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
+static void
+CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
 {
     register struct server *aserver = sa->server;
     register struct conn *tc;
@@ -276,13 +293,14 @@ static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
 
     AFS_STATCNT(CheckVLServer);
     /* Ping dead servers to see if they're back */
-    if (!((aserver->flags & SRVR_ISDOWN) || (sa->sa_flags & SRVADDR_ISDOWN)) || (aserver->flags & SRVR_ISGONE))
+    if (!((aserver->flags & SRVR_ISDOWN) || (sa->sa_flags & SRVADDR_ISDOWN))
+       || (aserver->flags & SRVR_ISGONE))
        return;
     if (!aserver->cell)
-       return; /* can't do much */
+       return;                 /* can't do much */
 
-    tc = afs_ConnByHost(aserver, aserver->cell->vlport, 
-                       aserver->cell->cell, areq, 1, SHARED_LOCK);
+    tc = afs_ConnByHost(aserver, aserver->cell->vlport,
+                       aserver->cell->cellNum, areq, 1, SHARED_LOCK);
     if (!tc)
        return;
     rx_SetConnDeadTime(tc->id, 3);
@@ -290,7 +308,7 @@ static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
     RX_AFS_GUNLOCK();
     code = VL_ProbeServer(tc->id);
     RX_AFS_GLOCK();
-    rx_SetConnDeadTime(tc->id, AFS_RXDEADTIME);
+    rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
     afs_PutConn(tc, SHARED_LOCK);
     /*
      * If probe worked, or probe call not yet defined (for compatibility
@@ -299,15 +317,15 @@ static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
     if (code == 0 || (code <= -450 && code >= -470)) {
        if (tc->srvr == sa) {
            afs_MarkServerUpOrDown(sa, 0);
-           print_internet_address("afs: volume location server ",
-                                  sa, " is back up", 2);
+           print_internet_address("afs: volume location server ", sa,
+                                  " is back up", 2);
        }
     }
 
-} /*CheckVLServer*/
+}                              /*CheckVLServer */
 
 
-#ifndef        AFS_MINCHANGE   /* So that some can increase it in param.h */
+#ifndef        AFS_MINCHANGE           /* So that some can increase it in param.h */
 #define AFS_MINCHANGE 2                /* min change we'll bother with */
 #endif
 #ifndef AFS_MAXCHANGEBACK
@@ -338,16 +356,17 @@ static void CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
  *     entries.
  *------------------------------------------------------------------------*/
 
-void afs_CountServers(void)
+void
+afs_CountServers(void)
 {
-    int currIdx;                               /*Curr idx into srv table*/
-    struct server *currSrvP;                   /*Ptr to curr server record*/
-    afs_int32 currChainLen;                            /*Length of curr hash chain*/
-    osi_timeval_t currTime;                    /*Current time*/
-    osi_timeval_t *currTimeP;                  /*Ptr to above*/
-    afs_int32 srvRecordAge;                            /*Age of server record, in secs*/
+    int currIdx;               /*Curr idx into srv table */
+    struct server *currSrvP;   /*Ptr to curr server record */
+    afs_int32 currChainLen;    /*Length of curr hash chain */
+    osi_timeval_t currTime;    /*Current time */
+    osi_timeval_t *currTimeP;  /*Ptr to above */
+    afs_int32 srvRecordAge;    /*Age of server record, in secs */
     struct afs_stats_SrvUpDownInfo *upDownP;   /*Ptr to current up/down
-                                                 info being manipulated*/
+                                                * info being manipulated */
 
     /*
      * Write-lock the server table so we don't get any interference.
@@ -361,25 +380,29 @@ void afs_CountServers(void)
      */
     afs_stats_cmperf.srvMaxChainLength = 0;
 
-    afs_stats_cmperf.fs_UpDown[0].sumOfRecordAges     = 0;
+    afs_stats_cmperf.fs_UpDown[0].sumOfRecordAges = 0;
     afs_stats_cmperf.fs_UpDown[0].ageOfYoungestRecord = 0;
-    afs_stats_cmperf.fs_UpDown[0].ageOfOldestRecord   = 0;
-    memset((char *) afs_stats_cmperf.fs_UpDown[0].downIncidents, 0, AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
+    afs_stats_cmperf.fs_UpDown[0].ageOfOldestRecord = 0;
+    memset((char *)afs_stats_cmperf.fs_UpDown[0].downIncidents, 0,
+          AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
 
-    afs_stats_cmperf.fs_UpDown[1].sumOfRecordAges     = 0;
+    afs_stats_cmperf.fs_UpDown[1].sumOfRecordAges = 0;
     afs_stats_cmperf.fs_UpDown[1].ageOfYoungestRecord = 0;
-    afs_stats_cmperf.fs_UpDown[1].ageOfOldestRecord   = 0;
-    memset((char *) afs_stats_cmperf.fs_UpDown[1].downIncidents, 0, AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
+    afs_stats_cmperf.fs_UpDown[1].ageOfOldestRecord = 0;
+    memset((char *)afs_stats_cmperf.fs_UpDown[1].downIncidents, 0,
+          AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
 
-    afs_stats_cmperf.vl_UpDown[0].sumOfRecordAges     = 0;
+    afs_stats_cmperf.vl_UpDown[0].sumOfRecordAges = 0;
     afs_stats_cmperf.vl_UpDown[0].ageOfYoungestRecord = 0;
-    afs_stats_cmperf.vl_UpDown[0].ageOfOldestRecord   = 0;
-    memset((char *) afs_stats_cmperf.vl_UpDown[0].downIncidents, 0, AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
+    afs_stats_cmperf.vl_UpDown[0].ageOfOldestRecord = 0;
+    memset((char *)afs_stats_cmperf.vl_UpDown[0].downIncidents, 0,
+          AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
 
-    afs_stats_cmperf.vl_UpDown[1].sumOfRecordAges     = 0;
+    afs_stats_cmperf.vl_UpDown[1].sumOfRecordAges = 0;
     afs_stats_cmperf.vl_UpDown[1].ageOfYoungestRecord = 0;
-    afs_stats_cmperf.vl_UpDown[1].ageOfOldestRecord   = 0;
-    memset((char *) afs_stats_cmperf.vl_UpDown[1].downIncidents, 0, AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
+    afs_stats_cmperf.vl_UpDown[1].ageOfOldestRecord = 0;
+    memset((char *)afs_stats_cmperf.vl_UpDown[1].downIncidents, 0,
+          AFS_STATS_NUM_DOWNTIME_INCIDENTS_BUCKETS * sizeof(afs_int32));
 
     /*
      * Compute the current time, used to figure out server record ages.
@@ -392,7 +415,8 @@ void afs_CountServers(void)
      */
     for (currIdx = 0; currIdx < NSERVERS; currIdx++) {
        currChainLen = 0;
-       for (currSrvP = afs_servers[currIdx]; currSrvP; currSrvP = currSrvP->next) {
+       for (currSrvP = afs_servers[currIdx]; currSrvP;
+            currSrvP = currSrvP->next) {
            /*
             * Bump the current chain length.
             */
@@ -402,58 +426,44 @@ void afs_CountServers(void)
             * Any further tallying for this record will only be done if it has
             * been activated. 
             */
-           if ( (currSrvP->flags & AFS_SERVER_FLAG_ACTIVATED) &&
-                 currSrvP->addr && currSrvP->cell ) {
+           if ((currSrvP->flags & AFS_SERVER_FLAG_ACTIVATED)
+               && currSrvP->addr && currSrvP->cell) {
 
                /*
                 * Compute the current server record's age, then remember it
                 * in the appropriate places.
                 */
                srvRecordAge = currTime.tv_sec - currSrvP->activationTime;
-               if (currSrvP->addr->sa_portal == AFS_FSPORT) {
-                   upDownP = (currSrvP->cell->cell == 1) ?
-                       &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]):
-                       &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-               } /*File Server record*/
-               else {
-                   upDownP = (currSrvP->cell->cell == 1) ?
-                       &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]):
-                       &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-               } /*VL Server record*/
-
+               upDownP = GetUpDownStats(currSrvP);
                upDownP->sumOfRecordAges += srvRecordAge;
-               if ((upDownP->ageOfYoungestRecord == 0) ||
-                   (srvRecordAge < upDownP->ageOfYoungestRecord))
+               if ((upDownP->ageOfYoungestRecord == 0)
+                   || (srvRecordAge < upDownP->ageOfYoungestRecord))
                    upDownP->ageOfYoungestRecord = srvRecordAge;
-               if ((upDownP->ageOfOldestRecord == 0) ||
-                   (srvRecordAge > upDownP->ageOfOldestRecord))
+               if ((upDownP->ageOfOldestRecord == 0)
+                   || (srvRecordAge > upDownP->ageOfOldestRecord))
                    upDownP->ageOfOldestRecord = srvRecordAge;
 
-               if (currSrvP->numDowntimeIncidents <=
-                   AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET0)
-                   (upDownP->downIncidents[0])++;
-               else
-                    if (currSrvP->numDowntimeIncidents <=
-                       AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET1)
-                       (upDownP->downIncidents[1])++;
-               else
-                   if (currSrvP->numDowntimeIncidents <=
-                       AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET2)
-                       (upDownP->downIncidents[2])++;
-               else
-                   if (currSrvP->numDowntimeIncidents <=
-                       AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET3)
-                       (upDownP->downIncidents[3])++;
-               else
-                   if (currSrvP->numDowntimeIncidents <=
-                       AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET4)
-                       (upDownP->downIncidents[4])++;
-               else
-                   (upDownP->downIncidents[5])++;
-
-
-           } /*Current server has been active*/
-       } /*Walk this chain*/
+               if (currSrvP->numDowntimeIncidents <=
+                   AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET0)
+                   (upDownP->downIncidents[0])++;
+               else if (currSrvP->numDowntimeIncidents <=
+                        AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET1)
+                   (upDownP->downIncidents[1])++;
+               else if (currSrvP->numDowntimeIncidents <=
+                        AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET2)
+                   (upDownP->downIncidents[2])++;
+               else if (currSrvP->numDowntimeIncidents <=
+                        AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET3)
+                   (upDownP->downIncidents[3])++;
+               else if (currSrvP->numDowntimeIncidents <=
+                        AFS_STATS_MAX_DOWNTIME_INCIDENTS_BUCKET4)
+                   (upDownP->downIncidents[4])++;
+               else
+                   (upDownP->downIncidents[5])++;
+
+
+           }                   /*Current server has been active */
+       }                       /*Walk this chain */
 
        /*
         * Before advancing to the next chain, remember facts about this one.
@@ -467,19 +477,20 @@ void afs_CountServers(void)
            afs_stats_cmperf.srvMaxChainLength = currChainLen;
            if (currChainLen > afs_stats_cmperf.srvMaxChainLengthHWM)
                afs_stats_cmperf.srvMaxChainLengthHWM = currChainLen;
-       } /*Update chain length maximum*/
-    } /*For each hash chain*/
+       }                       /*Update chain length maximum */
+    }                          /*For each hash chain */
 
     /*
      * We're done.  Unlock the server table before returning to our caller.
      */
     ReleaseReadLock(&afs_xserver);
 
-} /*afs_CountServers*/
+}                              /*afs_CountServers */
 
 
 /* check down servers (if adown), or running servers (if !adown) */
-void afs_CheckServers(int adown, struct cell *acellp)
+void
+afs_CheckServers(int adown, struct cell *acellp)
 {
     struct vrequest treq;
     struct server *ts;
@@ -487,40 +498,57 @@ void afs_CheckServers(int adown, struct cell *acellp)
     struct conn *tc;
     afs_int32 i, j;
     afs_int32 code;
-    afs_int32 start, end, delta;
+    afs_int32 start, end = 0, delta;
     osi_timeval_t tv;
-    int setTimer;
     struct unixuser *tu;
     char tbuffer[CVBS];
     int srvAddrCount;
     struct srvAddr **addrs;
-    XSTATS_DECLS;
+    struct conn **conns;
+    int nconns;
+    struct rx_connection **rxconns;      
+    afs_int32 *conntimer, *deltas, *results;
 
     AFS_STATCNT(afs_CheckServers);
-    if ((code = afs_InitReq(&treq, &afs_osi_cred))) return;
-    ObtainReadLock(&afs_xserver);  /* Necessary? */
-    ObtainReadLock(&afs_xsrvAddr);     
+
+    conns = (struct conn **)0;
+    rxconns = (struct rx_connection **) 0;
+    conntimer = 0;
+    nconns = 0;
+
+    if ((code = afs_InitReq(&treq, afs_osi_credp)))
+       return;
+    ObtainReadLock(&afs_xserver);      /* Necessary? */
+    ObtainReadLock(&afs_xsrvAddr);
 
     srvAddrCount = 0;
-    for (i=0;i<NSERVERS;i++) {
-       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
+    for (i = 0; i < NSERVERS; i++) {
+       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
            srvAddrCount++;
        }
     }
 
     addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
     j = 0;
-    for (i=0;i<NSERVERS;i++) {
-       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
-           if (j >= srvAddrCount) break;
+    for (i = 0; i < NSERVERS; i++) {
+       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
+           if (j >= srvAddrCount)
+               break;
            addrs[j++] = sa;
        }
     }
 
-    ReleaseReadLock(&afs_xsrvAddr);    
+    ReleaseReadLock(&afs_xsrvAddr);
     ReleaseReadLock(&afs_xserver);
 
-    for (i=0; i<j; i++) {
+    conns = (struct conn **)afs_osi_Alloc(j * sizeof(struct conn *));
+    rxconns = (struct rx_connection **)afs_osi_Alloc(j * sizeof(struct rx_connection *));
+    conntimer = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+    deltas = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+    results = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+
+    for (i = 0; i < j; i++) {
+       deltas[i] = 0;
        sa = addrs[i];
        ts = sa->server;
        if (!ts)
@@ -532,8 +560,8 @@ void afs_CheckServers(int adown, struct cell *acellp)
        if (acellp && acellp != ts->cell)
            continue;
 
-       if ((!adown && (sa->sa_flags & SRVADDR_ISDOWN)) ||
-           (adown && !(sa->sa_flags & SRVADDR_ISDOWN)))
+       if ((!adown && (sa->sa_flags & SRVADDR_ISDOWN))
+           || (adown && !(sa->sa_flags & SRVADDR_ISDOWN)))
            continue;
 
        /* check vlserver with special code */
@@ -542,114 +570,158 @@ void afs_CheckServers(int adown, struct cell *acellp)
            continue;
        }
 
-       if (!ts->cell) /* not really an active server, anyway, it must */
-           continue;  /* have just been added by setsprefs */ 
+       if (!ts->cell)          /* not really an active server, anyway, it must */
+           continue;           /* have just been added by setsprefs */
 
        /* get a connection, even if host is down; bumps conn ref count */
-       tu = afs_GetUser(treq.uid, ts->cell->cell, SHARED_LOCK);
-       tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cell, tu,
-                         1/*force*/, 1/*create*/, SHARED_LOCK);
+       tu = afs_GetUser(treq.uid, ts->cell->cellNum, SHARED_LOCK);
+       tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cellNum, tu,
+                         1 /*force */ , 1 /*create */ , SHARED_LOCK);
        afs_PutUser(tu, SHARED_LOCK);
-       if (!tc) continue;
+       if (!tc)
+           continue;
 
-       if ((sa->sa_flags & SRVADDR_ISDOWN) || HaveCallBacksFrom(ts) ||
-           (tc->srvr->server == afs_setTimeHost)) {
+       if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(sa->server)
+           || (tc->srvr->server == afs_setTimeHost)) {
+           conns[nconns]=tc; 
+           rxconns[nconns]=tc->id;
            if (sa->sa_flags & SRVADDR_ISDOWN) {
                rx_SetConnDeadTime(tc->id, 3);
-               setTimer = 1;
+               conntimer[nconns]=1;
            } else {
-               setTimer = 0;
+               conntimer[nconns]=0;
            }
+           nconns++;
+       }
+    } /* Outer loop over addrs */
 
-           XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GETTIME);
-           start = osi_Time();         /* time the gettimeofday call */
-           RX_AFS_GUNLOCK();
-           code = RXAFS_GetTime(tc->id, (afs_int32 *)&tv.tv_sec, (afs_int32 *)&tv.tv_usec);
-           RX_AFS_GLOCK();
-           end = osi_Time();
-           XSTATS_END_TIME;
-           /*
-            * If we're supposed to set the time, and the call worked
-            * quickly (same second response) and this is the host we
-            * use for the time and the time is really different, then
-            * really set the time
-            */
-           if (code == 0 && start == end && afs_setTime != 0 &&
-               (tc->srvr->server == afs_setTimeHost ||
-               /*
-                * Sync only to a server in the local cell: cell(id)==1
-                * or CPrimary.
-                */
-               (afs_setTimeHost == (struct server *)0 &&
-                (ts->cell->cell == 1 || (ts->cell->states&CPrimary))))) {
+    start = osi_Time();         /* time the gettimeofday call */
+    AFS_GUNLOCK(); 
+    multi_Rx(rxconns,nconns)
+      {
+       tv.tv_sec = tv.tv_usec = 0;
+       multi_RXAFS_GetTime(&tv.tv_sec, &tv.tv_usec);
+       tc = conns[multi_i];
+       sa = tc->srvr;
+       if (conntimer[multi_i] == 0)
+         rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
+       end = osi_Time();
+       results[multi_i]=multi_error;
+       if ((start == end) && !multi_error)
+         deltas[multi_i] = end - tv.tv_sec;
+       
+      } multi_End;
+    AFS_GLOCK(); 
+    
+    for(i=0;i<nconns;i++){
+      tc = conns[i];
+      sa = tc->srvr;
+      
+      if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
+       /* server back up */
+       print_internet_address("afs: file server ", sa, " is back up", 2);
+       
+       ObtainWriteLock(&afs_xserver, 244);
+       ObtainWriteLock(&afs_xsrvAddr, 245);        
+       afs_MarkServerUpOrDown(sa, 0);
+       ReleaseWriteLock(&afs_xsrvAddr);
+       ReleaseWriteLock(&afs_xserver);
+       
+       if (afs_waitForeverCount) {
+         afs_osi_Wakeup(&afs_waitForever);
+       }
+      } else {
+       if (results[i] < 0) {
+         /* server crashed */
+         afs_ServerDown(sa);
+         ForceNewConnections(sa);  /* multi homed clients */
+       }
+      }
+    }
 
-               char msgbuf[90];  /* strlen("afs: setting clock...") + slop */
+    /*
+     * If we're supposed to set the time, and the call worked
+     * quickly (same second response) and this is the host we
+     * use for the time and the time is really different, then
+     * really set the time
+     */
+    if (afs_setTime != 0) {
+       for (i=0; i<nconns; i++) {
+           delta = deltas[i];
+           tc = conns[i];
+           sa = tc->srvr;
+           
+           if ((tc->srvr->server == afs_setTimeHost ||
+                /* Sync only to a server in the local cell */
+                (afs_setTimeHost == (struct server *)0 &&
+                 afs_IsPrimaryCell(sa->server->cell)))) {
                /* set the time */
+               char msgbuf[90];  /* strlen("afs: setting clock...") + slop */
                delta = end - tv.tv_sec;   /* how many secs fast we are */
+               
+               afs_setTimeHost = tc->srvr->server;
                /* see if clock has changed enough to make it worthwhile */
                if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) {
+                   end = osi_Time();
                    if (delta > AFS_MAXCHANGEBACK) {
                        /* setting clock too far back, just do it a little */
                        tv.tv_sec = end - AFS_MAXCHANGEBACK;
+                   } else {
+                       tv.tv_sec = end - delta;
                    }
                    afs_osi_SetTime(&tv);
                    if (delta > 0) {
                        strcpy(msgbuf, "afs: setting clock back ");
                        if (delta > AFS_MAXCHANGEBACK) {
-                           afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], AFS_MAXCHANGEBACK));
+                           afs_strcat(msgbuf, 
+                                      afs_cv2string(&tbuffer[CVBS], 
+                                                    AFS_MAXCHANGEBACK));
                            afs_strcat(msgbuf, " seconds (of ");
-                           afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta - AFS_MAXCHANGEBACK));
+                           afs_strcat(msgbuf, 
+                                      afs_cv2string(&tbuffer[CVBS], 
+                                                    delta - 
+                                                    AFS_MAXCHANGEBACK));
                            afs_strcat(msgbuf, ", via ");
-                           print_internet_address(msgbuf, sa, "); clock is still fast.", 0);
+                           print_internet_address(msgbuf, sa, 
+                                                  "); clock is still fast.",
+                                                  0);
                        } else {
-                           afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta));
+                           afs_strcat(msgbuf, 
+                                      afs_cv2string(&tbuffer[CVBS], delta));
                            afs_strcat(msgbuf, " seconds (via ");
                            print_internet_address(msgbuf, sa, ").", 0);
                        }
                    } else {
                        strcpy(msgbuf, "afs: setting clock ahead ");
-                       afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], -delta));
+                       afs_strcat(msgbuf, 
+                                  afs_cv2string(&tbuffer[CVBS], -delta));
                        afs_strcat(msgbuf, " seconds (via ");
                        print_internet_address(msgbuf, sa, ").", 0);
                    }
-               }
-               afs_setTimeHost = tc->srvr->server;
-           }
-           if (setTimer)
-               rx_SetConnDeadTime(tc->id, AFS_RXDEADTIME);
-           if (code >= 0 && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
-               /* server back up */
-               print_internet_address("afs: file server ", sa, " is back up", 2);
-
-               ObtainWriteLock(&afs_xserver, 244);
-               ObtainWriteLock(&afs_xsrvAddr, 245);    
-               afs_MarkServerUpOrDown(sa, 0);
-               ReleaseWriteLock(&afs_xsrvAddr);
-               ReleaseWriteLock(&afs_xserver);
-
-               if (afs_waitForeverCount) {
-                   afs_osi_Wakeup(&afs_waitForever);
-               }
-           } else {
-               if (code < 0) {
-                   /* server crashed */
-                   afs_ServerDown(sa);
-                   ForceNewConnections(sa);  /* multi homed clients */
+                    /* We're only going to set it once; why bother looping? */
+                   break; 
                }
            }
        }
-
-       afs_PutConn(tc, SHARED_LOCK);   /* done with it now */
-    } /* Outer loop over addrs */
-
+    }
+    for (i = 0; i < nconns; i++) {
+       afs_PutConn(conns[i], SHARED_LOCK);     /* done with it now */
+    }
+    
     afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
-
+    afs_osi_Free(conns, j * sizeof(struct conn *));
+    afs_osi_Free(rxconns, j * sizeof(struct rx_connection *));
+    afs_osi_Free(conntimer, j * sizeof(afs_int32));
+    afs_osi_Free(deltas, j * sizeof(afs_int32));
+    afs_osi_Free(results, j * sizeof(afs_int32));
+    
 } /*afs_CheckServers*/
 
 
 /* find a server structure given the host address */
-struct server *afs_FindServer (afs_int32 aserver, ushort aport,
-                              afsUUID *uuidp, afs_int32 locktype)
+struct server *
+afs_FindServer(afs_int32 aserver, afs_uint16 aport, afsUUID * uuidp,
+              afs_int32 locktype)
 {
     struct server *ts;
     struct srvAddr *sa;
@@ -659,22 +731,23 @@ struct server *afs_FindServer (afs_int32 aserver, ushort aport,
     if (uuidp) {
        i = afs_uuid_hash(uuidp) % NSERVERS;
        for (ts = afs_servers[i]; ts; ts = ts->next) {
-           if ( (ts->flags & SRVR_MULTIHOMED) &&
-                (memcmp((char *)uuidp, (char *)&ts->sr_uuid, sizeof(*uuidp)) == 0) &&
-                (!ts->addr || (ts->addr->sa_portal == aport)) )
+           if ((ts->flags & SRVR_MULTIHOMED)
+               &&
+               (memcmp((char *)uuidp, (char *)&ts->sr_uuid, sizeof(*uuidp))
+                == 0) && (!ts->addr || (ts->addr->sa_portal == aport)))
                return ts;
        }
     } else {
        i = SHash(aserver);
        for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
            if ((sa->sa_ip == aserver) && (sa->sa_portal == aport)) {
-             return sa->server;
+               return sa->server;
            }
        }
     }
     return NULL;
 
-} /*afs_FindServer*/
+}                              /*afs_FindServer */
 
 
 /* some code for creating new server structs and setting preferences follows
@@ -707,22 +780,23 @@ NB:  Has to be unsigned, since shifts on signed quantities may preserve
 
 #define        ranstage(x)     (x)= (afs_uint32) (3141592621U*((afs_uint32)x)+1)
 
-unsigned int afs_random(void)
+unsigned int
+afs_random(void)
 {
     static afs_int32 state = 0;
     register int i;
 
     AFS_STATCNT(afs_random);
     if (!state) {
-        osi_timeval_t t;
+       osi_timeval_t t;
        osi_GetTime(&t);
        /*
         * 0xfffffff0 was changed to (~0 << 4) since it works no matter how many
         * bits are in a tv_usec
         */
-       state = (t.tv_usec & (~0 << 4) ) + (rxi_getaddr() & 0xff); 
+       state = (t.tv_usec & (~0 << 4)) + (rxi_getaddr() & 0xff);
        state += (t.tv_sec & 0xff);
-       for (i=0;i<30;i++) {
+       for (i = 0; i < 30; i++) {
            ranstage(state);
        }
     }
@@ -730,7 +804,7 @@ unsigned int afs_random(void)
     ranstage(state);
     return (state);
 
-} /*afs_random*/
+}                              /*afs_random */
 
 /* returns int 0..14 using the high bits of a pseudo-random number instead of
    the low bits, as the low bits are "less random" than the high ones...
@@ -738,85 +812,90 @@ unsigned int afs_random(void)
    need to multiply by something with lots of ones in it, so multiply by 
    8 or 16 is right out.
  */
-int afs_randomMod15(void)
+int
+afs_randomMod15(void)
 {
-afs_uint32 temp;
+    afs_uint32 temp;
 
-temp = afs_random() >> 4;
-temp = (temp *15) >> 28;
+    temp = afs_random() >> 4;
+    temp = (temp * 15) >> 28;
 
-return temp;
+    return temp;
 }
 
-int afs_randomMod127(void)
+int
+afs_randomMod127(void)
 {
-afs_uint32 temp;
+    afs_uint32 temp;
 
-temp = afs_random() >> 7;
-temp = (temp *127) >> 25;
+    temp = afs_random() >> 7;
+    temp = (temp * 127) >> 25;
 
-return temp;
+    return temp;
 }
 
 /* afs_SortOneServer()
  * Sort all of the srvAddrs, of a server struct, by rank from low to high.
  */
-void afs_SortOneServer(struct server *asp)
+void
+afs_SortOneServer(struct server *asp)
 {
-   struct srvAddr **rootsa, *lowsa, *tsa, *lowprev;
-   int lowrank, rank;
-      
-   for (rootsa=&(asp->addr); *rootsa; rootsa=&(lowsa->next_sa)) {
-      lowprev = NULL;
-      lowsa   = *rootsa;             /* lowest sa is the first one */
-      lowrank = lowsa->sa_iprank;
-
-      for (tsa=*rootsa; tsa->next_sa; tsa=tsa->next_sa) {
-        rank = tsa->next_sa->sa_iprank;
-        if (rank < lowrank) {
-           lowprev = tsa;
-           lowsa   = tsa->next_sa;
-           lowrank = lowsa->sa_iprank;
-        }
-      }
-      if (lowprev) { /* found one lower, so rearrange them */
-        lowprev->next_sa = lowsa->next_sa;
-        lowsa->next_sa   = *rootsa;
-        *rootsa          = lowsa;
-      }
-   }
+    struct srvAddr **rootsa, *lowsa, *tsa, *lowprev;
+    int lowrank, rank;
+
+    for (rootsa = &(asp->addr); *rootsa; rootsa = &(lowsa->next_sa)) {
+       lowprev = NULL;
+       lowsa = *rootsa;        /* lowest sa is the first one */
+       lowrank = lowsa->sa_iprank;
+
+       for (tsa = *rootsa; tsa->next_sa; tsa = tsa->next_sa) {
+           rank = tsa->next_sa->sa_iprank;
+           if (rank < lowrank) {
+               lowprev = tsa;
+               lowsa = tsa->next_sa;
+               lowrank = lowsa->sa_iprank;
+           }
+       }
+       if (lowprev) {          /* found one lower, so rearrange them */
+           lowprev->next_sa = lowsa->next_sa;
+           lowsa->next_sa = *rootsa;
+           *rootsa = lowsa;
+       }
+    }
 }
-    
+
 /* afs_SortServer()
  * Sort the pointer to servers by the server's rank (its lowest rank).
  * It is assumed that the server already has its IP addrs sorted (the
  * first being its lowest rank: afs_GetServer() calls afs_SortOneServer()).
  */
-void afs_SortServers(struct server *aservers[], int count)
+void
+afs_SortServers(struct server *aservers[], int count)
 {
     struct server *ts;
     int i, j, low;
 
     AFS_STATCNT(afs_SortServers);
 
-    for (i=0; i<count; i++) {
-       if (!aservers[i]) break;
-       for (low=i,j=i+1; j<=count; j++) {
-          if ((!aservers[j]) || (!aservers[j]->addr)) 
-              break;
-          if ((!aservers[low]) || (!aservers[low]->addr))
-              break;
-          if (aservers[j]->addr->sa_iprank < aservers[low]->addr->sa_iprank) {
-              low = j;
-          }
-       }
-       if (low != i) {
-         ts = aservers[i]; 
-         aservers[i] = aservers[low];
-         aservers[low] = ts;
-       }
+    for (i = 0; i < count; i++) {
+       if (!aservers[i])
+           break;
+       for (low = i, j = i + 1; j <= count; j++) {
+           if ((!aservers[j]) || (!aservers[j]->addr))
+               break;
+           if ((!aservers[low]) || (!aservers[low]->addr))
+               break;
+           if (aservers[j]->addr->sa_iprank < aservers[low]->addr->sa_iprank) {
+               low = j;
+           }
+       }
+       if (low != i) {
+           ts = aservers[i];
+           aservers[i] = aservers[low];
+           aservers[low] = ts;
+       }
     }
-} /*afs_SortServers*/
+}                              /*afs_SortServers */
 
 /* afs_SetServerPrefs is rather system-dependent.  It pokes around in kernel
    data structures to determine what the local IP addresses and subnet masks 
@@ -863,111 +942,105 @@ void afs_SortServers(struct server *aservers[], int count)
 
 #define        USEIFADDR
 
+
 #if    defined(AFS_SUN5_ENV) && ! defined(AFS_SUN56_ENV)
 #include <inet/common.h>
 /* IP interface structure, one per local address */
-typedef struct ipif_s {                        /**/
-       struct ipif_s   * ipif_next;
-       struct ill_s    * ipif_ill;     /* Back pointer to our ill */
-       long    ipif_id;                /* Logical unit number */
-       u_int   ipif_mtu;               /* Starts at ipif_ill->ill_max_frag */
-       afs_int32       ipif_local_addr;        /* Local IP address for this if. */
-       afs_int32       ipif_net_mask;          /* Net mask for this interface. */
-       afs_int32       ipif_broadcast_addr;    /* Broadcast addr for this interface. */
-       afs_int32       ipif_pp_dst_addr;       /* Point-to-point dest address. */
-       u_int   ipif_flags;             /* Interface flags. */
-       u_int   ipif_metric;            /* BSD if metric, for compatibility. */
-       u_int   ipif_ire_type;          /* LOCAL or LOOPBACK */
-       mblk_t  * ipif_arp_down_mp;     /* Allocated at time arp comes up to
-                                        * prevent awkward out of mem condition
-                                        * later
-                                        */
-       mblk_t  * ipif_saved_ire_mp;    /* Allocated for each extra IRE_SUBNET/
-                                        * RESOLVER on this interface so that
-                                        * they can survive ifconfig down.
-                                        */
-       /*
-        * The packet counts in the ipif contain the sum of the
-        * packet counts in dead IREs that were affiliated with
-        * this ipif.
-        */
-       u_long  ipif_fo_pkt_count;      /* Forwarded thru our dead IREs */
-       u_long  ipif_ib_pkt_count;      /* Inbound packets for our dead IREs */
-       u_long  ipif_ob_pkt_count;      /* Outbound packets to our dead IREs */
-       unsigned int
-               ipif_multicast_up : 1,  /* We have joined the allhosts group */
-               : 0;
+typedef struct ipif_s {
+     /**/ struct ipif_s *ipif_next;
+    struct ill_s *ipif_ill;    /* Back pointer to our ill */
+    long ipif_id;              /* Logical unit number */
+    u_int ipif_mtu;            /* Starts at ipif_ill->ill_max_frag */
+    afs_int32 ipif_local_addr; /* Local IP address for this if. */
+    afs_int32 ipif_net_mask;   /* Net mask for this interface. */
+    afs_int32 ipif_broadcast_addr;     /* Broadcast addr for this interface. */
+    afs_int32 ipif_pp_dst_addr;        /* Point-to-point dest address. */
+    u_int ipif_flags;          /* Interface flags. */
+    u_int ipif_metric;         /* BSD if metric, for compatibility. */
+    u_int ipif_ire_type;       /* LOCAL or LOOPBACK */
+    mblk_t *ipif_arp_down_mp;  /* Allocated at time arp comes up to
+                                * prevent awkward out of mem condition
+                                * later
+                                */
+    mblk_t *ipif_saved_ire_mp; /* Allocated for each extra IRE_SUBNET/
+                                * RESOLVER on this interface so that
+                                * they can survive ifconfig down.
+                                */
+    /*
+     * The packet counts in the ipif contain the sum of the
+     * packet counts in dead IREs that were affiliated with
+     * this ipif.
+     */
+    u_long ipif_fo_pkt_count;  /* Forwarded thru our dead IREs */
+    u_long ipif_ib_pkt_count;  /* Inbound packets for our dead IREs */
+    u_long ipif_ob_pkt_count;  /* Outbound packets to our dead IREs */
+    unsigned int
+      ipif_multicast_up:1,     /* We have joined the allhosts group */
+    : 0;
 } ipif_t;
 
-typedef struct ipfb_s {                        /**/
-       struct ipf_s    * ipfb_ipf;     /* List of ... */
-       kmutex_t        ipfb_lock;      /* Protect all ipf in list */
+typedef struct ipfb_s {
+     /**/ struct ipf_s *ipfb_ipf;      /* List of ... */
+    kmutex_t ipfb_lock;                /* Protect all ipf in list */
 } ipfb_t;
 
-typedef struct ilm_s {                 /**/
-       afs_int32               ilm_addr;
-       int             ilm_refcnt;
-       u_int           ilm_timer;      /* IGMP */
-       struct ipif_s   * ilm_ipif;     /* Back pointer to ipif */
-       struct ilm_s    * ilm_next;     /* Linked list for each ill */
+typedef struct ilm_s {
+     /**/ afs_int32 ilm_addr;
+    int ilm_refcnt;
+    u_int ilm_timer;           /* IGMP */
+    struct ipif_s *ilm_ipif;   /* Back pointer to ipif */
+    struct ilm_s *ilm_next;    /* Linked list for each ill */
 } ilm_t;
 
-typedef struct ill_s {                 /**/
-       struct  ill_s   * ill_next;     /* Chained in at ill_g_head. */
-       struct  ill_s   ** ill_ptpn;    /* Pointer to previous next. */
-       queue_t * ill_rq;               /* Read queue. */
-       queue_t * ill_wq;               /* Write queue. */
-
-       int     ill_error;              /* Error value sent up by device. */
-
-       ipif_t  * ill_ipif;             /* Interface chain for this ILL. */
-       u_int   ill_ipif_up_count;      /* Number of IPIFs currently up. */
-       u_int   ill_max_frag;           /* Max IDU. */
-       char    * ill_name;             /* Our name. */
-       u_int   ill_name_length;        /* Name length, incl. terminator. */
-       u_int   ill_subnet_type;        /* IRE_RESOLVER or IRE_SUBNET. */
-       u_int   ill_ppa;                /* Physical Point of Attachment num. */
-       u_long  ill_sap;
-       int     ill_sap_length;         /* Including sign (for position) */
-       u_int   ill_phys_addr_length;   /* Excluding the sap. */
-       mblk_t  * ill_frag_timer_mp;    /* Reassembly timer state. */
-       ipfb_t  * ill_frag_hash_tbl;    /* Fragment hash list head. */
-
-       queue_t * ill_bind_pending_q;   /* Queue waiting for DL_BIND_ACK. */
-       ipif_t  * ill_ipif_pending;     /* IPIF waiting for DL_BIND_ACK. */
-
-       /* ill_hdr_length and ill_hdr_mp will be non zero if
-        * the underlying device supports the M_DATA fastpath
-        */
-       int     ill_hdr_length;
+typedef struct ill_s {
+     /**/ struct ill_s *ill_next;      /* Chained in at ill_g_head. */
+    struct ill_s **ill_ptpn;   /* Pointer to previous next. */
+    queue_t *ill_rq;           /* Read queue. */
+    queue_t *ill_wq;           /* Write queue. */
+
+    int ill_error;             /* Error value sent up by device. */
+
+    ipif_t *ill_ipif;          /* Interface chain for this ILL. */
+    u_int ill_ipif_up_count;   /* Number of IPIFs currently up. */
+    u_int ill_max_frag;                /* Max IDU. */
+    char *ill_name;            /* Our name. */
+    u_int ill_name_length;     /* Name length, incl. terminator. */
+    u_int ill_subnet_type;     /* IRE_RESOLVER or IRE_SUBNET. */
+    u_int ill_ppa;             /* Physical Point of Attachment num. */
+    u_long ill_sap;
+    int ill_sap_length;                /* Including sign (for position) */
+    u_int ill_phys_addr_length;        /* Excluding the sap. */
+    mblk_t *ill_frag_timer_mp; /* Reassembly timer state. */
+    ipfb_t *ill_frag_hash_tbl; /* Fragment hash list head. */
+
+    queue_t *ill_bind_pending_q;       /* Queue waiting for DL_BIND_ACK. */
+    ipif_t *ill_ipif_pending;  /* IPIF waiting for DL_BIND_ACK. */
+
+    /* ill_hdr_length and ill_hdr_mp will be non zero if
+     * the underlying device supports the M_DATA fastpath
+     */
+    int ill_hdr_length;
 
-       ilm_t   * ill_ilm;              /* Multicast mebership for lower ill */
+    ilm_t *ill_ilm;            /* Multicast mebership for lower ill */
 
-       /* All non-nil cells between 'ill_first_mp_to_free' and
-        * 'ill_last_mp_to_free' are freed in ill_delete.
-        */
+    /* All non-nil cells between 'ill_first_mp_to_free' and
+     * 'ill_last_mp_to_free' are freed in ill_delete.
+     */
 #define        ill_first_mp_to_free    ill_hdr_mp
-       mblk_t  * ill_hdr_mp;           /* Contains fastpath template */
-       mblk_t  * ill_bcast_mp;         /* DLPI header for broadcasts. */
-       mblk_t  * ill_bind_pending;     /* T_BIND_REQ awaiting completion. */
-       mblk_t  * ill_resolver_mp;      /* Resolver template. */
-       mblk_t  * ill_attach_mp;
-       mblk_t  * ill_bind_mp;
-       mblk_t  * ill_unbind_mp;
-       mblk_t  * ill_detach_mp;
+    mblk_t *ill_hdr_mp;                /* Contains fastpath template */
+    mblk_t *ill_bcast_mp;      /* DLPI header for broadcasts. */
+    mblk_t *ill_bind_pending;  /* T_BIND_REQ awaiting completion. */
+    mblk_t *ill_resolver_mp;   /* Resolver template. */
+    mblk_t *ill_attach_mp;
+    mblk_t *ill_bind_mp;
+    mblk_t *ill_unbind_mp;
+    mblk_t *ill_detach_mp;
 #define        ill_last_mp_to_free     ill_detach_mp
 
-       u_int
-               ill_frag_timer_running : 1,
-               ill_needs_attach : 1,
-               ill_is_ptp : 1,
-               ill_priv_stream : 1,
-               ill_unbind_pending : 1,
-
-               ill_pad_to_bit_31 : 27;
-       MI_HRT_DCL(ill_rtime)
-       MI_HRT_DCL(ill_rtmp)
+    u_int ill_frag_timer_running:1, ill_needs_attach:1, ill_is_ptp:1,
+       ill_priv_stream:1, ill_unbind_pending:1, ill_pad_to_bit_31:27;
+      MI_HRT_DCL(ill_rtime)
+      MI_HRT_DCL(ill_rtmp)
 } ill_t;
 #endif
 
@@ -986,109 +1059,207 @@ typedef struct ill_s {                 /**/
  * afs_uint32 subnetmask;         subnet mask of local addr in net order
  *
  */
-int afsi_SetServerIPRank(struct srvAddr *sa, afs_int32 addr, afs_uint32 subnetmask)
+void
+afsi_SetServerIPRank(struct srvAddr *sa, afs_int32 addr,
+                    afs_uint32 subnetmask)
 {
-   afs_uint32 myAddr, myNet, mySubnet, netMask;
-   afs_uint32 serverAddr ; 
-
-   myAddr = ntohl(addr);          /* one of my IP addr in host order */
-   serverAddr = ntohl(sa->sa_ip); /* server's IP addr in host order */
-   subnetmask = ntohl(subnetmask);/* subnet mask in host order */
-
-   if      ( IN_CLASSA(myAddr) ) netMask = IN_CLASSA_NET;
-   else if ( IN_CLASSB(myAddr) ) netMask = IN_CLASSB_NET;
-   else if ( IN_CLASSC(myAddr) ) netMask = IN_CLASSC_NET;
-   else                          netMask = 0;
-
-   myNet    =  myAddr & netMask;
-   mySubnet =  myAddr & subnetmask;
-
-   if ( (serverAddr & netMask ) == myNet ) {
-      if ( (serverAddr & subnetmask ) == mySubnet) {
-        if ( serverAddr == myAddr ) {    /* same machine */
-          sa->sa_iprank = afs_min(sa->sa_iprank, TOPR);
-        } else {                           /* same subnet */
-           sa->sa_iprank = afs_min(sa->sa_iprank, HI);
-        }
-      } else {                               /* same net */
-        sa->sa_iprank = afs_min(sa->sa_iprank, MED);
-      }
-   }
+    afs_uint32 myAddr, myNet, mySubnet, netMask;
+    afs_uint32 serverAddr;
+
+    myAddr = ntohl(addr);      /* one of my IP addr in host order */
+    serverAddr = ntohl(sa->sa_ip);     /* server's IP addr in host order */
+    subnetmask = ntohl(subnetmask);    /* subnet mask in host order */
+
+    if (IN_CLASSA(myAddr))
+       netMask = IN_CLASSA_NET;
+    else if (IN_CLASSB(myAddr))
+       netMask = IN_CLASSB_NET;
+    else if (IN_CLASSC(myAddr))
+       netMask = IN_CLASSC_NET;
+    else
+       netMask = 0;
+
+    myNet = myAddr & netMask;
+    mySubnet = myAddr & subnetmask;
+
+    if ((serverAddr & netMask) == myNet) {
+       if ((serverAddr & subnetmask) == mySubnet) {
+           if (serverAddr == myAddr) { /* same machine */
+               sa->sa_iprank = afs_min(sa->sa_iprank, TOPR);
+           } else {            /* same subnet */
+               sa->sa_iprank = afs_min(sa->sa_iprank, HI);
+           }
+       } else {                /* same net */
+           sa->sa_iprank = afs_min(sa->sa_iprank, MED);
+       }
+    }
 }
 #else /* AFS_USERSPACE_IP_ADDR */
-#if (! defined(AFS_SUN5_ENV)) && defined(USEIFADDR)
-void afsi_SetServerIPRank(struct srvAddr *sa, struct in_ifaddr *ifa)
+#if (! defined(AFS_SUN5_ENV)) && !defined(AFS_DARWIN60_ENV) && defined(USEIFADDR)
+void
+afsi_SetServerIPRank(struct srvAddr *sa, struct in_ifaddr *ifa)
 {
     struct sockaddr_in *sin;
     int t;
-    
+
     if ((ntohl(sa->sa_ip) & ifa->ia_netmask) == ifa->ia_net) {
        if ((ntohl(sa->sa_ip) & ifa->ia_subnetmask) == ifa->ia_subnet) {
-           sin=IA_SIN(ifa);
-           if ( SA2ULONG(sin) == ntohl(sa->sa_ip)) {   /* ie, ME!!!  */
+           sin = IA_SIN(ifa);
+           if (SA2ULONG(sin) == ntohl(sa->sa_ip)) {    /* ie, ME!!!  */
                sa->sa_iprank = TOPR;
-           } else { 
-               t = HI + ifa->ia_ifp->if_metric; /* case #2 */
+           } else {
+               t = HI + ifa->ia_ifp->if_metric;        /* case #2 */
                if (sa->sa_iprank > t)
                    sa->sa_iprank = t;
            }
        } else {
-           t = MED + ifa->ia_ifp->if_metric;/* case #3 */
+           t = MED + ifa->ia_ifp->if_metric;   /* case #3 */
            if (sa->sa_iprank > t)
                sa->sa_iprank = t;
        }
     }
 #ifdef  IFF_POINTTOPOINT
     /* check for case #4 -- point-to-point link */
-    if ((ifa->ia_ifp->if_flags & IFF_POINTOPOINT) &&
-       (SA2ULONG(IA_DST(ifa)) == ntohl(sa->sa_ip))) {
-       if (ifa->ia_ifp->if_metric >= (MAXDEFRANK - MED)/PPWEIGHT) 
+    if ((ifa->ia_ifp->if_flags & IFF_POINTOPOINT)
+       && (SA2ULONG(IA_DST(ifa)) == ntohl(sa->sa_ip))) {
+       if (ifa->ia_ifp->if_metric >= (MAXDEFRANK - MED) / PPWEIGHT)
            t = MAXDEFRANK;
-       else 
+       else
            t = MED + (PPWEIGHT << ifa->ia_ifp->if_metric);
        if (sa->sa_iprank > t)
            sa->sa_iprank = t;
     }
 #endif /* IFF_POINTTOPOINT */
 }
-#endif /*(!defined(AFS_SUN5_ENV)) && defined(USEIFADDR)*/
+#endif /*(!defined(AFS_SUN5_ENV)) && defined(USEIFADDR) */
+#if defined(AFS_DARWIN60_ENV) && defined(USEIFADDR)
+#ifndef afs_min
+#define afs_min(A,B) ((A)<(B)) ? (A) : (B)
+#endif
+void
+afsi_SetServerIPRank(sa, ifa)
+     struct srvAddr *sa;
+#ifdef AFS_DARWIN80_ENV
+     ifaddr_t ifa;
+#else
+     struct ifaddr *ifa;
+#endif
+{
+    struct sockaddr sout;
+    struct sockaddr_in *sin;
+    int t;
+
+    afs_uint32 subnetmask, myAddr, myNet, myDstaddr, mySubnet, netMask;
+    afs_uint32 serverAddr;
+
+    if (ifaddr_address_family(ifa) != AF_INET)
+       return;
+    t = ifaddr_address(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
+       myAddr = ntohl(sin->sin_addr.s_addr);   /* one of my IP addr in host order */
+    } else {
+       myAddr = 0;
+    }
+    serverAddr = ntohl(sa->sa_ip);     /* server's IP addr in host order */
+    t = ifaddr_netmask(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
+       subnetmask = ntohl(sin->sin_addr.s_addr);       /* subnet mask in host order */
+    } else {
+       subnetmask = 0;
+    }
+    t = ifaddr_dstaddress(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
+       myDstaddr = sin->sin_addr.s_addr;
+    } else {
+       myDstaddr = 0;
+    }
+
+    if (IN_CLASSA(myAddr))
+       netMask = IN_CLASSA_NET;
+    else if (IN_CLASSB(myAddr))
+       netMask = IN_CLASSB_NET;
+    else if (IN_CLASSC(myAddr))
+       netMask = IN_CLASSC_NET;
+    else
+       netMask = 0;
+
+    myNet = myAddr & netMask;
+    mySubnet = myAddr & subnetmask;
+
+    if ((serverAddr & netMask) == myNet) {
+       if ((serverAddr & subnetmask) == mySubnet) {
+           if (serverAddr == myAddr) { /* same machine */
+               sa->sa_iprank = afs_min(sa->sa_iprank, TOPR);
+           } else {            /* same subnet */
+               sa->sa_iprank = afs_min(sa->sa_iprank, HI + ifnet_metric(ifaddr_ifnet(ifa)));
+           }
+       } else {                /* same net */
+           sa->sa_iprank = afs_min(sa->sa_iprank, MED + ifnet_metric(ifaddr_ifnet(ifa)));
+       }
+    }
+#ifdef  IFF_POINTTOPOINT
+    /* check for case #4 -- point-to-point link */
+    if ((ifnet_flags(ifaddr_ifnet(ifa)) & IFF_POINTOPOINT)
+       && (myDstaddr == serverAddr)) {
+       if (ifnet_metric(ifaddr_ifnet(ifa)) >= (MAXDEFRANK - MED) / PPWEIGHT)
+           t = MAXDEFRANK;
+       else
+           t = MED + (PPWEIGHT << ifnet_metric(ifaddr_ifnet(ifa)));
+       if (sa->sa_iprank > t)
+           sa->sa_iprank = t;
+       }
+#endif /* IFF_POINTTOPOINT */
+}
+#endif /*(!defined(AFS_SUN5_ENV)) && defined(USEIFADDR) */
 #endif /* else AFS_USERSPACE_IP_ADDR */
 
 #ifdef AFS_SGI62_ENV
 static int
-afsi_enum_set_rank(struct hashbucket *h, caddr_t mkey, caddr_t arg1,
-               caddr_t arg2)
-{
-   afsi_SetServerIPRank((struct srvAddr *)arg1, (struct in_ifaddr*)h);
-   return 0; /* Never match, so we enumerate everyone */
-}
-#endif /* AFS_SGI62_ENV */
 
-static int afs_SetServerPrefs(struct srvAddr *sa)
-{
+  afsi_enum_set_rank(struct hashbucket *h, caddr_t mkey, caddr_t arg1,
+                    caddr_t arg2) {
+    afsi_SetServerIPRank((struct srvAddr *)arg1, (struct in_ifaddr *)h);
+    return 0;                  /* Never match, so we enumerate everyone */
+}
+#endif                         /* AFS_SGI62_ENV */
+static int afs_SetServerPrefs(struct srvAddr *sa) {
 #if     defined(AFS_USERSPACE_IP_ADDR)
     int i;
 
-    sa->sa_iprank = LO;
-    for (i=0; i<afs_cb_interface.numberOfInterfaces; i++) {
-       afsi_SetServerIPRank(sa, afs_cb_interface.addr_in[i],
-                               afs_cb_interface.subnetmask[i]);
+      sa->sa_iprank = LO;
+    for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
+       afsi_SetServerIPRank(sa, afs_cb_interface.addr_in[i],
+                            afs_cb_interface.subnetmask[i]);
     }
-#else   /* AFS_USERSPACE_IP_ADDR */
+#else                          /* AFS_USERSPACE_IP_ADDR */
 #if    defined(AFS_SUN5_ENV)
+#ifdef AFS_SUN510_ENV
+    ill_walk_context_t ctx;
+#else
     extern struct ill_s *ill_g_headp;
+    long *addr = (long *)ill_g_headp;
+#endif
     ill_t *ill;
-    ipif_t * ipif;
+    ipif_t *ipif;
     int subnet, subnetmask, net, netmask;
-    long *addr = (long *) ill_g_headp;
 
-    if (sa) sa->sa_iprank= 0;
-    for (ill = (struct ill_s *)*addr /*ill_g_headp*/; ill; ill = ill->ill_next ) {
+    if (sa)
+         sa->sa_iprank = 0;
+#ifdef AFS_SUN510_ENV
+    for (ill = ILL_START_WALK_ALL(&ctx) ; ill ; ill = ill_next(&ctx, ill)) {
+#else
+    for (ill = (struct ill_s *)*addr /*ill_g_headp */ ; ill;
+        ill = ill->ill_next) {
+#endif
 #ifdef AFS_SUN58_ENV
        /* Make sure this is an IPv4 ILL */
-       if (ill->ill_isv6) continue;
+       if (ill->ill_isv6)
+           continue;
 #endif
-       for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next ) {
+       for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
            subnet = ipif->ipif_local_addr & ipif->ipif_net_mask;
            subnetmask = ipif->ipif_net_mask;
            /*
@@ -1105,37 +1276,38 @@ static int afs_SetServerPrefs(struct srvAddr *sa)
                netmask = 0;
            }
            net = ipif->ipif_local_addr & netmask;
-#ifdef notdef 
+#ifdef notdef
            if (!s) {
-               if (ipif->ipif_local_addr != 0x7f000001) { /* ignore loopback */
+               if (ipif->ipif_local_addr != 0x7f000001) {      /* ignore loopback */
                    *cnt += 1;
-                   if (*cnt > 16) return;
+                   if (*cnt > 16)
+                       return;
                    *addrp++ = ipif->ipif_local_addr;
                }
            } else
 #endif /* notdef */
-             {
+           {
                /* XXXXXX Do the individual ip ranking below XXXXX */
                if ((sa->sa_ip & netmask) == net) {
                    if ((sa->sa_ip & subnetmask) == subnet) {
-                       if (ipif->ipif_local_addr == sa->sa_ip) {  /* ie, ME!  */
+                       if (ipif->ipif_local_addr == sa->sa_ip) {       /* ie, ME!  */
                            sa->sa_iprank = TOPR;
-                       } else { 
-                           sa->sa_iprank = HI + ipif->ipif_metric; /* case #2 */
+                       } else {
+                           sa->sa_iprank = HI + ipif->ipif_metric;     /* case #2 */
                        }
-                   }  else {
-                       sa->sa_iprank = MED + ipif->ipif_metric;   /* case #3 */
+                   } else {
+                       sa->sa_iprank = MED + ipif->ipif_metric;        /* case #3 */
                    }
                } else {
                    sa->sa_iprank = LO + ipif->ipif_metric;     /* case #4 */
                }
                /* check for case #5 -- point-to-point link */
-               if ((ipif->ipif_flags & IFF_POINTOPOINT) &&
-                   (ipif->ipif_pp_dst_addr == sa->sa_ip )) {
+               if ((ipif->ipif_flags & IFF_POINTOPOINT)
+                   && (ipif->ipif_pp_dst_addr == sa->sa_ip)) {
 
-                   if (ipif->ipif_metric >= (MAXDEFRANK - MED)/PPWEIGHT) 
+                   if (ipif->ipif_metric >= (MAXDEFRANK - MED) / PPWEIGHT)
                        sa->sa_iprank = MAXDEFRANK;
-                   else 
+                   else
                        sa->sa_iprank = MED + (PPWEIGHT << ipif->ipif_metric);
                }
            }
@@ -1144,93 +1316,122 @@ static int afs_SetServerPrefs(struct srvAddr *sa)
 #else
 #ifndef USEIFADDR
     struct ifnet *ifn = NULL;
-    struct in_ifaddr *ifad = (struct in_ifaddr *) 0;
+    struct in_ifaddr *ifad = (struct in_ifaddr *)0;
     struct sockaddr_in *sin;
 
     if (!sa) {
-#ifdef notdef /* clean up, remove this */
+#ifdef notdef                  /* clean up, remove this */
        for (ifn = ifnet; ifn != NULL; ifn = ifn->if_next) {
-           for (ifad = ifn->if_addrlist; ifad != NULL; ifad = ifad->ifa_next){
-              if ((IFADDR2SA(ifad)->sa_family == AF_INET) 
-                  && !(ifn->if_flags & IFF_LOOPBACK)) {
-                 *cnt += 1;
-                 if (*cnt > 16) return;
-                 *addrp++ = ((struct sockaddr_in *) IFADDR2SA(ifad))->sin_addr.s_addr;
+           for (ifad = ifn->if_addrlist; ifad != NULL; ifad = ifad->ifa_next) {
+               if ((IFADDR2SA(ifad)->sa_family == AF_INET)
+                   && !(ifn->if_flags & IFF_LOOPBACK)) {
+                   *cnt += 1;
+                   if (*cnt > 16)
+                       return;
+                   *addrp++ =
+                       ((struct sockaddr_in *)IFADDR2SA(ifad))->sin_addr.
+                       s_addr;
                }
-           }
-       }
-#endif /* notdef */
+       }}
+#endif                         /* notdef */
        return;
     }
-    sa->sa_iprank= 0;
+    sa->sa_iprank = 0;
 #ifdef ADAPT_MTU
     ifn = rxi_FindIfnet(sa->sa_ip, &ifad);
 #endif
-    if (ifn) {  /* local, more or less */
+    if (ifn) {                 /* local, more or less */
 #ifdef IFF_LOOPBACK
-      if (ifn->if_flags & IFF_LOOPBACK) {
-       sa->sa_iprank = TOPR;
-       goto end;
-      }
+       if (ifn->if_flags & IFF_LOOPBACK) {
+           sa->sa_iprank = TOPR;
+           goto end;
+       }
 #endif /* IFF_LOOPBACK */
-      sin = (struct sockaddr_in *) IA_SIN(ifad);
-      if (SA2ULONG(sin) == sa->sa_ip) {
-       sa->sa_iprank = TOPR;
-       goto end;
-      }
-#ifdef IFF_BROADCAST
-      if (ifn->if_flags & IFF_BROADCAST) {
-        if (sa->sa_ip == (sa->sa_ip & SA2ULONG(IA_BROAD(ifad)))) {
-           sa->sa_iprank = HI;
+       sin = (struct sockaddr_in *)IA_SIN(ifad);
+       if (SA2ULONG(sin) == sa->sa_ip) {
+           sa->sa_iprank = TOPR;
            goto end;
-         }
-       }
+       }
+#ifdef IFF_BROADCAST
+       if (ifn->if_flags & IFF_BROADCAST) {
+           if (sa->sa_ip == (sa->sa_ip & SA2ULONG(IA_BROAD(ifad)))) {
+               sa->sa_iprank = HI;
+               goto end;
+           }
+       }
 #endif /* IFF_BROADCAST */
 #ifdef IFF_POINTOPOINT
-      if (ifn->if_flags & IFF_POINTOPOINT) {
-       if (sa->sa_ip == SA2ULONG(IA_DST(ifad))) {
-         if (ifn->if_metric > 4) {
-           sa->sa_iprank = LO;
-           goto end;
-         }
-         else sa->sa_iprank = ifn->if_metric;
+       if (ifn->if_flags & IFF_POINTOPOINT) {
+           if (sa->sa_ip == SA2ULONG(IA_DST(ifad))) {
+               if (ifn->if_metric > 4) {
+                   sa->sa_iprank = LO;
+                   goto end;
+               } else
+                   sa->sa_iprank = ifn->if_metric;
+           }
        }
-      }
 #endif /* IFF_POINTOPOINT */
-      sa->sa_iprank += MED + ifn->if_metric;      /* couldn't find anything better */
+       sa->sa_iprank += MED + ifn->if_metric;  /* couldn't find anything better */
     }
-       
-#else /* USEIFADDR */
-    
-    if (sa) sa->sa_iprank= LO;
+#else                          /* USEIFADDR */
+
+    if (sa)
+       sa->sa_iprank = LO;
 #ifdef AFS_SGI62_ENV
-    (void) hash_enum(&hashinfo_inaddr, afsi_enum_set_rank, HTF_INET, NULL,
-                    (caddr_t)sa, NULL);
+    (void)hash_enum(&hashinfo_inaddr, afsi_enum_set_rank, HTF_INET, NULL,
+                   (caddr_t) sa, NULL);
+#elif defined(AFS_DARWIN80_ENV)
+    {
+       errno_t t;
+       int cnt=0;
+       ifaddr_t *addresses, address;
+       t = ifnet_get_address_list_family(NULL, &addresses, AF_INET);
+       if (t == 0) {
+           while(addresses[cnt] != NULL) {
+               afsi_SetServerIPRank(sa, address);
+               cnt++;
+           }
+           ifnet_free_address_list(addresses);
+       }
+    }
+#elif defined(AFS_DARWIN60_ENV)
+    {
+       struct ifnet *ifn;
+       struct ifaddr *ifa;
+         TAILQ_FOREACH(ifn, &ifnet, if_link) {
+           TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
+               afsi_SetServerIPRank(sa, ifa);
+    }}}
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     {
-        struct in_ifaddr *ifa;
-        TAILQ_FOREACH(ifa , &in_ifaddrhead, ia_link) {
-            afsi_SetServerIPRank(sa, ifa);
-        }
+       struct in_ifaddr *ifa;
+         TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
+           afsi_SetServerIPRank(sa, ifa);
+    }}
+#elif defined(AFS_OBSD_ENV)
+    {
+       extern struct in_ifaddrhead in_ifaddr;
+       struct in_ifaddr *ifa;
+       for (ifa = in_ifaddr.tqh_first; ifa; ifa = ifa->ia_list.tqe_next)
+           afsi_SetServerIPRank(sa, ifa);
     }
 #else
     {
        struct in_ifaddr *ifa;
-       for ( ifa = in_ifaddr; ifa; ifa = ifa->ia_next ) {
+       for (ifa = in_ifaddr; ifa; ifa = ifa->ia_next) {
            afsi_SetServerIPRank(sa, ifa);
-       }
-    }
+    }}
 #endif
+    end:
+#endif                         /* USEIFADDR */
+#endif                         /* AFS_SUN5_ENV */
+#endif                         /* else AFS_USERSPACE_IP_ADDR */
+    if (sa)
+         sa->sa_iprank += afs_randomMod15();
 
-#endif /* USEIFADDR */
-#endif /* AFS_SUN5_ENV */
-#endif /* else AFS_USERSPACE_IP_ADDR */
-
-  end: 
-    if (sa) sa->sa_iprank += afs_randomMod15();
+    return 0;
+}                              /* afs_SetServerPrefs */
 
-return 0;
-}  /* afs_SetServerPrefs */
 #undef TOPR
 #undef HI
 #undef MED
@@ -1242,50 +1443,51 @@ return 0;
  * clean up all other structures that may reference it.
  * The afs_xserver and afs_xsrvAddr locks are assumed taken.
  */
-void afs_FlushServer(struct server *srvp)
-{
-  afs_int32 i;
-  struct server  *ts, **pts;
-
-  /* Find any volumes residing on this server and flush their state */
-  afs_ResetVolumes(srvp);
-
-  /* Flush all callbacks in the all vcaches for this specific server */
-  afs_FlushServerCBs(srvp);
-
-  /* Remove all the callbacks structs */
-  if (srvp->cbrs) {
-     struct afs_cbr *cb, *cbnext;
-
-     MObtainWriteLock(&afs_xvcb, 300);
-     for (cb=srvp->cbrs; cb; cb=cbnext) {
-        cbnext = cb->next;
-       afs_FreeCBR(cb);
-     }
-     srvp->cbrs = (struct afs_cbr *)0;
-     ReleaseWriteLock(&afs_xvcb);
-  }
-  
-  /* If no more srvAddr structs hanging off of this server struct,
-   * then clean it up.
-   */
-  if (!srvp->addr) {
-     /* Remove the server structure from the cell list - if there */
-     afs_RemoveCellEntry(srvp);
-
-     /* Remove from the afs_servers hash chain */
-     for (i=0; i<NSERVERS; i++) {
-        for (pts=&(afs_servers[i]), ts=*pts; ts; pts=&(ts->next), ts=*pts) {
-          if (ts == srvp) break;
+void afs_FlushServer(struct server *srvp) {
+    afs_int32 i;
+    struct server *ts, **pts;
+
+    /* Find any volumes residing on this server and flush their state */
+      afs_ResetVolumes(srvp);
+
+    /* Flush all callbacks in the all vcaches for this specific server */
+      afs_FlushServerCBs(srvp);
+
+    /* Remove all the callbacks structs */
+    if (srvp->cbrs) {
+       struct afs_cbr *cb, *cbnext;
+
+         MObtainWriteLock(&afs_xvcb, 300);
+       for (cb = srvp->cbrs; cb; cb = cbnext) {
+           cbnext = cb->next;
+           afs_FreeCBR(cb);
+       } srvp->cbrs = (struct afs_cbr *)0;
+       ReleaseWriteLock(&afs_xvcb);
+    }
+
+    /* If no more srvAddr structs hanging off of this server struct,
+     * then clean it up.
+     */
+    if (!srvp->addr) {
+       /* Remove the server structure from the cell list - if there */
+       afs_RemoveCellEntry(srvp);
+
+       /* Remove from the afs_servers hash chain */
+       for (i = 0; i < NSERVERS; i++) {
+           for (pts = &(afs_servers[i]), ts = *pts; ts;
+                pts = &(ts->next), ts = *pts) {
+               if (ts == srvp)
+                   break;
+           }
+           if (ts)
+               break;
        }
-       if (ts) break;
-     }
-     if (ts) {
-        *pts = ts->next;                /* Found it. Remove it */
-       afs_osi_Free(ts, sizeof(struct server)); /* Free it */
-       afs_totalServers--;
-     }
-  }
+       if (ts) {
+           *pts = ts->next;    /* Found it. Remove it */
+           afs_osi_Free(ts, sizeof(struct server));    /* Free it */
+           afs_totalServers--;
+       }
+    }
 }
 
 /* afs_RemoveSrvAddr()
@@ -1296,26 +1498,26 @@ void afs_FlushServer(struct server *srvp)
  * The afs_xserver and afs_xsrvAddr locks are assumed taken.
  *    It is not removed from the afs_srvAddrs hash chain.
  */
-void afs_RemoveSrvAddr(struct srvAddr *sap)
-{
-  struct srvAddr **psa, *sa;
-  struct server  *srv;
-
-  if (!sap) return;
-  srv = sap->server;
-
-  /* Find the srvAddr in the server's list and remove it */
-  for (psa=&(srv->addr), sa=*psa; sa; psa=&(sa->next_sa), sa=*psa) {
-     if (sa == sap) break;
-  }
-  if (sa) {
-     *psa = sa->next_sa;
-     sa->next_sa = 0;
-     sa->server  = 0;
-
-     /* Flush the server struct since it's IP address has changed */
-     afs_FlushServer(srv);
-  }
+void afs_RemoveSrvAddr(struct srvAddr *sap) {
+    struct srvAddr **psa, *sa;
+    struct server *srv;
+
+    if (!sap)
+         return;
+      srv = sap->server;
+
+    /* Find the srvAddr in the server's list and remove it */
+    for (psa = &(srv->addr), sa = *psa; sa; psa = &(sa->next_sa), sa = *psa) {
+       if (sa == sap)
+           break;
+    } if (sa) {
+       *psa = sa->next_sa;
+       sa->next_sa = 0;
+       sa->server = 0;
+
+       /* Flush the server struct since it's IP address has changed */
+       afs_FlushServer(srv);
+    }
 }
 
 /* afs_GetServer()
@@ -1324,233 +1526,257 @@ void afs_RemoveSrvAddr(struct srvAddr *sap)
  * If one does not exist, then one will be created.
  * aserver and aport must be in NET byte order.
  */
-struct server *afs_GetServer(afs_uint32 *aserverp, afs_int32 nservers,
+struct server *afs_GetServer(afs_uint32 * aserverp, afs_int32 nservers,
                             afs_int32 acell, u_short aport,
-                            afs_int32 locktype, afsUUID *uuidp,
-                            afs_int32 addr_uniquifier)
-{
-    struct server  *oldts=0, *ts, *newts, *orphts=0;
-    struct srvAddr *oldsa, *sa, *newsa, *nextsa, *orphsa;
+                            afs_int32 locktype, afsUUID * uuidp,
+                            afs_int32 addr_uniquifier) {
+    struct server *oldts = 0, *ts, *newts, *orphts = 0;
+    struct srvAddr *oldsa, *newsa, *nextsa, *orphsa;
     u_short fsport;
-    afs_int32 iphash, k, srvcount=0;
+    afs_int32 iphash, k, srvcount = 0;
     unsigned int srvhash;
 
     AFS_STATCNT(afs_GetServer);
 
-    ObtainSharedLock(&afs_xserver,13);
+    ObtainSharedLock(&afs_xserver, 13);
 
     /* Check if the server struct exists and is up to date */
     if (!uuidp) {
-       if (nservers != 1) panic("afs_GetServer: incorect count of servers");
-       ObtainReadLock(&afs_xsrvAddr);  
-       ts = afs_FindServer(aserverp[0], aport, NULL, locktype);
-       ReleaseReadLock(&afs_xsrvAddr); 
-       if (ts && !(ts->flags & SRVR_MULTIHOMED)) {
-         /* Found a server struct that is not multihomed and has the
-          * IP address associated with it. A correct match.
-          */
-         ReleaseSharedLock(&afs_xserver);
-         return(ts);
-       }
+       if (nservers != 1)
+           panic("afs_GetServer: incorect count of servers");
+       ObtainReadLock(&afs_xsrvAddr);
+       ts = afs_FindServer(aserverp[0], aport, NULL, locktype);
+       ReleaseReadLock(&afs_xsrvAddr);
+       if (ts && !(ts->flags & SRVR_MULTIHOMED)) {
+           /* Found a server struct that is not multihomed and has the
+            * IP address associated with it. A correct match.
+            */
+           ReleaseSharedLock(&afs_xserver);
+           return (ts);
+       }
     } else {
-       if (nservers <= 0) panic("afs_GetServer: incorrect count of servers");
-       ts = afs_FindServer(0, aport, uuidp, locktype);
-       if (ts && (ts->sr_addr_uniquifier == addr_uniquifier) && ts->addr) {
-         /* Found a server struct that is multihomed and same
-          * uniqufier (same IP addrs). The above if statement is the
-          * same as in InstallUVolumeEntry().
-          */
-         ReleaseSharedLock(&afs_xserver);
-         return ts;
-       }
-       if (ts) oldts = ts;      /* Will reuse if same uuid */
+       if (nservers <= 0)
+           panic("afs_GetServer: incorrect count of servers");
+       ts = afs_FindServer(0, aport, uuidp, locktype);
+       if (ts && (ts->sr_addr_uniquifier == addr_uniquifier) && ts->addr) {
+           /* Found a server struct that is multihomed and same
+            * uniqufier (same IP addrs). The above if statement is the
+            * same as in InstallUVolumeEntry().
+            */
+           ReleaseSharedLock(&afs_xserver);
+           return ts;
+       }
+       if (ts)
+           oldts = ts;         /* Will reuse if same uuid */
     }
 
-    UpgradeSToWLock(&afs_xserver,36);
-    ObtainWriteLock(&afs_xsrvAddr,116);        
+    UpgradeSToWLock(&afs_xserver, 36);
+    ObtainWriteLock(&afs_xsrvAddr, 116);
 
     srvcount = afs_totalServers;
 
     /* Reuse/allocate a new server structure */
     if (oldts) {
-       newts = oldts; 
+       newts = oldts;
     } else {
-       newts = (struct server *) afs_osi_Alloc(sizeof(struct server));
-       if (!newts) panic("malloc of server struct");
-       afs_totalServers++;
-       memset((char *)newts, 0, sizeof(struct server));
-
-       /* Add the server struct to the afs_servers[] hash chain */
-       srvhash = (uuidp ? (afs_uuid_hash(uuidp)%NSERVERS) : SHash(aserverp[0]));
-       newts->next = afs_servers[srvhash];
-       afs_servers[srvhash] = newts;
+       newts = (struct server *)afs_osi_Alloc(sizeof(struct server));
+       if (!newts)
+           panic("malloc of server struct");
+       afs_totalServers++;
+       memset((char *)newts, 0, sizeof(struct server));
+
+       /* Add the server struct to the afs_servers[] hash chain */
+       srvhash =
+           (uuidp ? (afs_uuid_hash(uuidp) % NSERVERS) : SHash(aserverp[0]));
+       newts->next = afs_servers[srvhash];
+       afs_servers[srvhash] = newts;
     }
 
     /* Initialize the server structure */
-    if (uuidp) { /* Multihomed */
-       newts->sr_uuid            = *uuidp;
-       newts->sr_addr_uniquifier = addr_uniquifier;
-       newts->flags             |= SRVR_MULTIHOMED;
+    if (uuidp) {               /* Multihomed */
+       newts->sr_uuid = *uuidp;
+       newts->sr_addr_uniquifier = addr_uniquifier;
+       newts->flags |= SRVR_MULTIHOMED;
     }
-    if (acell) newts->cell = afs_GetCell(acell, 0);
+    if (acell)
+       newts->cell = afs_GetCell(acell, 0);
 
     fsport = (newts->cell ? newts->cell->fsport : AFS_FSPORT);
 
     /* For each IP address we are registering */
-    for (k=0; k<nservers; k++) {
-       iphash = SHash(aserverp[k]);
-
-       /* Check if the srvAddr structure already exists. If so, remove
-       * it from its server structure and add it to the new one.
-       */
-       for (oldsa=afs_srvAddrs[iphash]; oldsa; oldsa=oldsa->next_bkt) {
-         if ( (oldsa->sa_ip == aserverp[k]) && (oldsa->sa_portal == aport) ) break;
-       }
-       if (oldsa && (oldsa->server != newts)) {
-         afs_RemoveSrvAddr(oldsa);     /* Remove from its server struct */
-         oldsa->next_sa = newts->addr; /* Add to the  new server struct */
-         newts->addr    = oldsa;
-       }
-
-       /* Reuse/allocate a new srvAddr structure */
-       if (oldsa) {
-         newsa = oldsa;
-       } else {
-         newsa = (struct srvAddr *) afs_osi_Alloc(sizeof(struct srvAddr));
-         if (!newsa) panic("malloc of srvAddr struct");
-         afs_totalSrvAddrs++;
-         memset((char *)newsa, 0, sizeof(struct srvAddr));
-
-         /* Add the new srvAddr to the afs_srvAddrs[] hash chain */
-         newsa->next_bkt = afs_srvAddrs[iphash];
-         afs_srvAddrs[iphash] = newsa;
-
-         /* Hang off of the server structure  */
-         newsa->next_sa = newts->addr;
-         newts->addr    = newsa;
-
-         /* Initialize the srvAddr Structure */
-         newsa->sa_ip     = aserverp[k];
-         newsa->sa_portal = aport;
-       }
-
-       /* Update the srvAddr Structure */
-       newsa->server    = newts;
-       if (newts->flags & SRVR_ISDOWN)
-         newsa->sa_flags |= SRVADDR_ISDOWN;
-       if (uuidp) newsa->sa_flags |=  SRVADDR_MH;
-       else       newsa->sa_flags &= ~SRVADDR_MH;
-
-       /* Compute preference values and resort */
-       if (!newsa->sa_iprank) {
-         if (aport == fsport) { 
-            afs_SetServerPrefs(newsa);    /* new fileserver rank */
-         } else {
-            newsa->sa_iprank = 10000 + afs_randomMod127(); /* new vlserver rank */
-         }
-       }
+    for (k = 0; k < nservers; k++) {
+       iphash = SHash(aserverp[k]);
+
+       /* Check if the srvAddr structure already exists. If so, remove
+        * it from its server structure and add it to the new one.
+        */
+       for (oldsa = afs_srvAddrs[iphash]; oldsa; oldsa = oldsa->next_bkt) {
+           if ((oldsa->sa_ip == aserverp[k]) && (oldsa->sa_portal == aport))
+               break;
+       }
+       if (oldsa && (oldsa->server != newts)) {
+           afs_RemoveSrvAddr(oldsa);   /* Remove from its server struct */
+           oldsa->next_sa = newts->addr;       /* Add to the  new server struct */
+           newts->addr = oldsa;
+       }
+
+       /* Reuse/allocate a new srvAddr structure */
+       if (oldsa) {
+           newsa = oldsa;
+       } else {
+           newsa = (struct srvAddr *)afs_osi_Alloc(sizeof(struct srvAddr));
+           if (!newsa)
+               panic("malloc of srvAddr struct");
+           afs_totalSrvAddrs++;
+           memset((char *)newsa, 0, sizeof(struct srvAddr));
+
+           /* Add the new srvAddr to the afs_srvAddrs[] hash chain */
+           newsa->next_bkt = afs_srvAddrs[iphash];
+           afs_srvAddrs[iphash] = newsa;
+
+           /* Hang off of the server structure  */
+           newsa->next_sa = newts->addr;
+           newts->addr = newsa;
+
+           /* Initialize the srvAddr Structure */
+           newsa->sa_ip = aserverp[k];
+           newsa->sa_portal = aport;
+       }
+
+       /* Update the srvAddr Structure */
+       newsa->server = newts;
+       if (newts->flags & SRVR_ISDOWN)
+           newsa->sa_flags |= SRVADDR_ISDOWN;
+       if (uuidp)
+           newsa->sa_flags |= SRVADDR_MH;
+       else
+           newsa->sa_flags &= ~SRVADDR_MH;
+
+       /* Compute preference values and resort */
+       if (!newsa->sa_iprank) {
+           if (aport == fsport) {
+               afs_SetServerPrefs(newsa);      /* new fileserver rank */
+           } else {
+               newsa->sa_iprank = 10000 + afs_randomMod127();  /* new vlserver rank */
+           }
+       }
     }
-    afs_SortOneServer(newts);     /* Sort by rank */
+    afs_SortOneServer(newts);  /* Sort by rank */
 
     /* If we reused the server struct, remove any of its srvAddr
      * structs that will no longer be associated with this server.
      */
-    if (oldts) {    /* reused the server struct */
-       for (orphsa=newts->addr; orphsa; orphsa=nextsa) {
-         nextsa = orphsa->next_sa;
-         for (k=0; k<nservers; k++) {
-            if (orphsa->sa_ip == aserverp[k]) break; /* belongs */
-         }
-         if (k < nservers) continue;                 /* belongs */
-
-         /* Have a srvAddr struct. Now get a server struct (if not already) */
-         if (!orphts) {
-            orphts = (struct server *) afs_osi_Alloc(sizeof(struct server));
-            if (!orphts) panic("malloc of lo server struct");
-            memset((char *)orphts, 0, sizeof(struct server));
-            afs_totalServers++;
-
-            /* Add the orphaned server to the afs_servers[] hash chain.
-             * Its iphash does not matter since we never look up the server
-             * in the afs_servers table by its ip address (only by uuid - 
-             * which this has none).
-             */
-            iphash = SHash(aserverp[k]);
-            orphts->next = afs_servers[iphash];
-            afs_servers[iphash] = orphts;
-
-            if (acell) orphts->cell = afs_GetCell(acell, 0);
-         }
-
-         /* Hang the srvAddr struct off of the server structure. The server
-          * may have multiple srvAddrs, but it won't be marked multihomed.
-          */
-         afs_RemoveSrvAddr(orphsa);                 /* remove */
-         orphsa->next_sa   = orphts->addr;          /* hang off server struct */
-         orphts->addr      = orphsa;
-         orphsa->server    = orphts;
-         orphsa->sa_flags |= SRVADDR_NOUSE;         /* flag indicating not in use */
-         orphsa->sa_flags &= ~SRVADDR_MH;           /* Not multihomed */
-       }
+    if (oldts) {               /* reused the server struct */
+       for (orphsa = newts->addr; orphsa; orphsa = nextsa) {
+           nextsa = orphsa->next_sa;
+           for (k = 0; k < nservers; k++) {
+               if (orphsa->sa_ip == aserverp[k])
+                   break;      /* belongs */
+           }
+           if (k < nservers)
+               continue;       /* belongs */
+
+           /* Have a srvAddr struct. Now get a server struct (if not already) */
+           if (!orphts) {
+               orphts =
+                   (struct server *)afs_osi_Alloc(sizeof(struct server));
+               if (!orphts)
+                   panic("malloc of lo server struct");
+               memset((char *)orphts, 0, sizeof(struct server));
+               afs_totalServers++;
+
+               /* Add the orphaned server to the afs_servers[] hash chain.
+                * Its iphash does not matter since we never look up the server
+                * in the afs_servers table by its ip address (only by uuid - 
+                * which this has none).
+                */
+               iphash = SHash(aserverp[k]);
+               orphts->next = afs_servers[iphash];
+               afs_servers[iphash] = orphts;
+
+               if (acell)
+                   orphts->cell = afs_GetCell(acell, 0);
+           }
+
+           /* Hang the srvAddr struct off of the server structure. The server
+            * may have multiple srvAddrs, but it won't be marked multihomed.
+            */
+           afs_RemoveSrvAddr(orphsa);  /* remove */
+           orphsa->next_sa = orphts->addr;     /* hang off server struct */
+           orphts->addr = orphsa;
+           orphsa->server = orphts;
+           orphsa->sa_flags |= SRVADDR_NOUSE;  /* flag indicating not in use */
+           orphsa->sa_flags &= ~SRVADDR_MH;    /* Not multihomed */
+       }
     }
 
-    srvcount = afs_totalServers - srvcount;  /* # servers added and removed */
+    srvcount = afs_totalServers - srvcount;    /* # servers added and removed */
     if (srvcount) {
-       struct afs_stats_SrvUpDownInfo *upDownP;
-       /* With the introduction of this new record, we need to adjust the
-       * proper individual & global server up/down info.
-       */
-       if (aport == fsport) {   /* File Server record */
-         upDownP = (acell == 1) ?
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-       } else {                   /* VL Server record */
-         upDownP = (acell == 1) ?
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-           &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-       } 
-       (upDownP->numTtlRecords)    += srvcount;
-       afs_stats_cmperf.srvRecords += srvcount;
-       if (afs_stats_cmperf.srvRecords > afs_stats_cmperf.srvRecordsHWM)
-         afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords;
+       struct afs_stats_SrvUpDownInfo *upDownP;
+       /* With the introduction of this new record, we need to adjust the
+        * proper individual & global server up/down info.
+        */
+       upDownP = GetUpDownStats(newts);
+       upDownP->numTtlRecords += srvcount;
+       afs_stats_cmperf.srvRecords += srvcount;
+       if (afs_stats_cmperf.srvRecords > afs_stats_cmperf.srvRecordsHWM)
+           afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords;
     }
 
-    ReleaseWriteLock(&afs_xsrvAddr);   
+    ReleaseWriteLock(&afs_xsrvAddr);
     ReleaseWriteLock(&afs_xserver);
-    return(newts);
-} /* afs_GetServer */
+    return (newts);
+}                              /* afs_GetServer */
+
+void afs_ActivateServer(struct srvAddr *sap) {
+    osi_timeval_t currTime;    /*Filled with current time */
+    osi_timeval_t *currTimeP;  /*Ptr to above */
+    struct afs_stats_SrvUpDownInfo *upDownP;   /*Ptr to up/down info record */
+    struct server *aserver = sap->server;
+
+    if (!(aserver->flags & AFS_SERVER_FLAG_ACTIVATED)) {
+       /*
+        * This server record has not yet been activated.  Go for it,
+        * recording its ``birth''.
+        */
+       aserver->flags |= AFS_SERVER_FLAG_ACTIVATED;
+       currTimeP = &currTime;
+       osi_GetuTime(currTimeP);
+       aserver->activationTime = currTime.tv_sec;
+       upDownP = GetUpDownStats(aserver);
+       if (aserver->flags & SRVR_ISDOWN) {
+           upDownP->numDownRecords++;
+       } else {
+           upDownP->numUpRecords++;
+           upDownP->numRecordsNeverDown++;
+       }
+    }
+}
+
 
-void afs_ActivateServer(struct srvAddr *sap) 
+void shutdown_server()
 {
-   osi_timeval_t currTime;             /*Filled with current time*/
-   osi_timeval_t *currTimeP;           /*Ptr to above*/
-   struct afs_stats_SrvUpDownInfo *upDownP; /*Ptr to up/down info record*/
-   struct server *aserver = sap->server;
-
-   if (!(aserver->flags & AFS_SERVER_FLAG_ACTIVATED)) {
-      /*
-       * This server record has not yet been activated.  Go for it,
-       * recording its ``birth''.
-       */
-      aserver->flags |= AFS_SERVER_FLAG_ACTIVATED;
-      currTimeP = &currTime;
-      osi_GetuTime(currTimeP);
-      aserver->activationTime = currTime.tv_sec;
-      if (sap->sa_portal == AFS_FSPORT) {
-        upDownP = (aserver->cell->cell == 1) ?
-             &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-                  &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-      } /*File Server record*/
-      else {
-        upDownP = (aserver->cell->cell == 1) ?
-             &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) :
-                  &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]);
-      } /*VL Server record*/
-      if (aserver->flags & SRVR_ISDOWN)
-          (upDownP->numDownRecords)++;
-      else {
-        (upDownP->numUpRecords)++;
-        (upDownP->numRecordsNeverDown)++;
-      }
-   }
+    int i;
+
+    for (i = 0; i < NSERVERS; i++) {
+       struct server *ts, *next;
+
+        ts = afs_servers[i];
+        while(ts) {
+           next = ts->next;
+           afs_osi_Free(ts, sizeof(struct server));
+           ts = next;
+        }
+    }
+
+    for (i = 0; i < NSERVERS; i++) {
+       struct srvAddr *sa, *next;
+
+        sa = afs_srvAddrs[i];
+        while(sa) {
+           next = sa->next_bkt;
+           afs_osi_Free(sa, sizeof(struct srvAddr));
+           sa = next;
+        }
+    }
 }