]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/ddp_lap.c
xnu-792.2.4.tar.gz
[apple/xnu.git] / bsd / netat / ddp_lap.c
index 80a700a67c343a7837c2984f1753fa15797d5676..f2ed8d1b40bafffbab3af351bdf47ef9e1b9940e 100644 (file)
 #include <sys/mbuf.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <net/if_dl.h>
 #include <sys/socketvar.h>
 #include <sys/malloc.h>
+#include <sys/domain.h>
 #include <sys/sockio.h>
+#include <vm/vm_kern.h>         /* for kernel_map */
+
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -77,6 +81,8 @@
 #include <netat/adsp.h>
 #include <netat/adsp_internal.h>
 
+#include <sys/kern_event.h>
+
 /* globals */
 
 at_ifaddr_t at_interfaces[IF_TOTAL_MAX];
@@ -121,6 +127,7 @@ extern asp_scb_t *scb_used_list;
 extern CCB *adsp_inputQ[];
 extern CCB *ccb_used_list;
 extern at_ddp_stats_t at_ddp_stats;
+extern lck_mtx_t * atalk_mutex;
 
 /* protos */
 extern snmpAarpEnt_t * getAarp(int *);
@@ -301,7 +308,7 @@ int elap_wput(gref, m)
        register ioc_t          *iocbp;
        register at_if_cfg_t    *cfgp;
        at_elap_stats_t         *statsp;
-       int error, i;
+       int             i;
        int                     (*func)();
        gbuf_t          *tmpm;
        at_ifaddr_t *patp;
@@ -770,7 +777,7 @@ elap_dataput(m, elapp, addr_flag, addr)
      char *addr;
 {
        register int            size;
-       int                     error;
+       int                     error = 0;
        extern  int             zip_type_packet();
        struct  etalk_addr      dest_addr;
        struct  atalk_addr      dest_at_addr;
@@ -880,14 +887,28 @@ static int elap_online1(elapp)
        /* Get DDP started */
        if ((errno = ddp_add_if(elapp)))
                return(errno);
-
+       
+       // check if we still have an interface - can be lost when
+       // ddp_add_if calls malloc
+       // need to make check here after ddp_add_if completes because 
+       // lap_online will call ddp_rem_if if we fail here
+       if (elapp->aa_ifp == 0)
+               return ENOENT;
+               
        /* set up multicast address for cable-wide broadcasts */
        (void)at_reg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
 
+        // need to check again if interface is present
+        // can be lost in at_reg_mcast
+       if (elapp->aa_ifp == 0)
+               return ENOENT;
+
        elapp->startup_inprogress = TRUE;
-       if (! (elapp->startup_error = re_aarp(elapp)))
-               (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, 
+       if (! (elapp->startup_error = re_aarp(elapp))) {
+               lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
+               (void)msleep(&elapp->startup_inprogress, atalk_mutex, PSOCK | PCATCH, 
                             "elap_online1", 0);
+       }
 
        /* then later, after some timeouts AARPwakeup() is called */
 
@@ -948,7 +969,7 @@ static void elap_online2(elapp)
 
                elapp->ifState = LAP_ONLINE_ZONELESS;
                elapp->startup_inprogress = FALSE;
-               thread_wakeup(&elapp->startup_inprogress);
+               wakeup(&elapp->startup_inprogress);
                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n"));
                return;
        }
@@ -988,7 +1009,8 @@ int elap_online3(elapp)
 
        /* then later, after some timeouts AARPwakeup() is called */
 
-       (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, 
+       lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
+       (void)msleep(&elapp->startup_inprogress, atalk_mutex, PSOCK | PCATCH, 
                     "elap_online3", 0);
        return(elapp->startup_error);
 } /* elap_online3 */
@@ -1025,6 +1047,7 @@ void elap_offline(elapp)
                ATENABLE(s, ddpinp_lock);
 
                /* make sure no zip timeouts are left running */
+               elapp->ifGNIScheduled = 0;
                untimeout(zip_sched_getnetinfo, elapp);
        }
        ddp_rem_if(elapp);
@@ -1073,11 +1096,9 @@ int ddp_shutdown(count_only)
        struct atp_state *atp, *atp_next;
        CCB *sp, *sp_next;
        gref_t *gref;
-       int i, s,
-         active_skts = 0;      /* count of active pids for non-socketized
+       vm_offset_t temp_rcb_data, temp_state_data;
+       int i, s, active_skts = 0;      /* count of active pids for non-socketized
                                   AppleTalk protocols */
-       extern int aarp_sched_probe();
-
 
        /* Network is shutting down... send error messages up on each open
         * socket.
@@ -1196,6 +1217,8 @@ int ddp_shutdown(count_only)
        }          
 
        at_state.flags = 0;     /* make sure inits are done on restart */
+       
+       wakeup(&ifID_home->startup_inprogress); /* if rtmp_router_start still starting up */
 
        /* from original ddp_shutdown() */
        routershutdown();
@@ -1205,6 +1228,8 @@ int ddp_shutdown(count_only)
                CleanupGlobals();
                adspInited = 0;
        }
+       
+        
        dPrintf(D_M_DDP, D_L_VERBOSE, ("DDP shutdown completed"));
 
        /*
@@ -1223,7 +1248,7 @@ int ddp_shutdown(count_only)
                elap_offline(ifID);
        }
        ddp_start();
-
+       
        splx(s);
        return(0);
 } /* ddp_shutdown */
@@ -1233,6 +1258,7 @@ int routerStart(keP)
 {
        register at_ifaddr_t *ifID;
        int error;
+       struct timespec ts;
 
        if (! ifID_home)
                return(EINVAL);
@@ -1256,12 +1282,18 @@ int routerStart(keP)
        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                ("router_start: waiting 20 sec before starting up\n"));
 
+       lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
        /* sleep for 20 seconds */
+
+       /* the vaue of 10n terms of hz is 100ms */
+       ts.tv_sec = 20;
+       ts.tv_nsec = 0;
+       
        if ((error = 
             /* *** eventually this will be the ifID for the interface
                being brought up in router mode *** */
-            tsleep(&ifID_home->startup_inprogress, 
-                   PSOCK | PCATCH, "routerStart", 20 * SYS_HZ))
+               msleep(&ifID_home->startup_inprogress, atalk_mutex,
+                   PSOCK | PCATCH, "routerStart", &ts))
            != EWOULDBLOCK) {
 /*
                if (!error)
@@ -1291,6 +1323,10 @@ void ZIPwakeup(elapp, ZipError)
                switch (ZipError) {
                        case 0 : /* success */
                            elapp->ifState = LAP_ONLINE;
+
+                               /* Send event with zone info. */
+                               atalk_post_msg(elapp->aa_ifp, KEV_ATALK_ZONEUPDATED, 0, &(elapp->ifZoneName));
+                               
                            break;
                        case ZIP_RE_AARP :
                            /* instead of goto re_aarp; */
@@ -1298,7 +1334,7 @@ void ZIPwakeup(elapp, ZipError)
                               appletalk node addr */
                            if ((elapp->startup_error = re_aarp(elapp))) {
                                elapp->startup_inprogress = FALSE;
-                               thread_wakeup(&elapp->startup_inprogress);
+                               wakeup(&elapp->startup_inprogress);
                                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, 
                                        ("elap_online: ack 2\n"));
                            }
@@ -1309,7 +1345,7 @@ void ZIPwakeup(elapp, ZipError)
                if (ZipError != ZIP_RE_AARP) {
                        elapp->startup_error = error;
                        elapp->startup_inprogress = FALSE;
-                       thread_wakeup(&elapp->startup_inprogress);
+                       wakeup(&elapp->startup_inprogress);
                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                                ("elap_online: ifZipError=%d\n", error));
                }
@@ -1326,7 +1362,7 @@ void AARPwakeup(probe_cb)
 
        ATDISABLE(s, arpinp_lock);
        elapp = probe_cb->elapp;
-       if ( (elapp != NULL) && elapp->startup_inprogress ) {
+       if ( (elapp != NULL) && elapp->startup_inprogress && elapp->aa_ifp != 0) {
                ATENABLE(s, arpinp_lock);
 
                /* was AARPContinue */
@@ -1342,7 +1378,7 @@ void AARPwakeup(probe_cb)
                        ddp_rem_if(elapp);
                        elapp->startup_error = EADDRNOTAVAIL;
                        elapp->startup_inprogress = FALSE;
-                       thread_wakeup(&elapp->startup_inprogress);
+                       wakeup(&elapp->startup_inprogress);
                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n"));
                } else {
                        dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
@@ -1406,7 +1442,9 @@ static int elap_trackMcast(patp, func, addr)
        u_char c;
        switch(patp->aa_ifp->if_type) {
        case IFT_ETHER: 
-       case IFT_FDDI: 
+       case IFT_FDDI:
+       case IFT_L2VLAN:
+       case IFT_IEEE8023ADLAG: /* bonded ethernet */
                /* set addr to point to unique part of addr */
                c = addr[5];
 
@@ -1493,6 +1531,8 @@ static getSnmpCfg(snmp)
                        ifc->ifc_addrSize = getPhysAddrSize(i);
                        switch (elapp->aa_ifp->if_type) {
                                case IFT_ETHER:
+                                case IFT_L2VLAN:
+                               case IFT_IEEE8023ADLAG: /* bonded ethernet */
                                        ifc->ifc_type = SNMP_TYPE_ETHER2;
                                        break;
                                case IFT_ISO88025: /* token ring */
@@ -1548,7 +1588,7 @@ int at_reg_mcast(ifID, data)
      caddr_t data;
 {
        struct ifnet *nddp = ifID->aa_ifp;
-       struct sockaddr sa;
+       struct sockaddr_dl sdl;
 
        if (*(int *)data) {
                if (!nddp) {
@@ -1560,16 +1600,22 @@ int at_reg_mcast(ifID, data)
                        return(0);
 
                /* this is for ether_output */
-               sa.sa_family = AF_UNSPEC;
-               sa.sa_len = 2 + sizeof(struct etalk_addr);
-               bcopy (data, &sa.sa_data[0], sizeof(struct etalk_addr));
+               bzero(&sdl, sizeof(sdl));
+               sdl.sdl_family = AF_LINK;
+               sdl.sdl_alen = sizeof(struct etalk_addr);
+               sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data) 
+                   + sizeof(struct etalk_addr);
+               bcopy(data, sdl.sdl_data, sizeof(struct etalk_addr));
+               /* these next two lines should not really be needed XXX */
+               sdl.sdl_index = nddp->if_index;
+               sdl.sdl_type = IFT_ETHER;
 
                dPrintf(D_M_PAT, D_L_STARTUP,
                        ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
                         *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, 
                         (unsigned)ifID));
 
-               if (if_addmulti(nddp, &sa, 0))
+               if (if_addmulti(nddp, &sdl, 0))
                        return -1;
        }
        return 0;
@@ -1581,7 +1627,7 @@ int at_unreg_mcast(ifID, data)
      caddr_t data;
 {
        struct ifnet *nddp = ifID->aa_ifp;
-       struct sockaddr sa;
+       struct sockaddr_dl sdl;
 
        if (*(int *)data) {
                if (!nddp) {
@@ -1592,9 +1638,15 @@ int at_unreg_mcast(ifID, data)
                elap_trackMcast(ifID, MCAST_TRACK_DELETE, data);
 
                /* this is for ether_output */
-               sa.sa_family = AF_UNSPEC;
-               sa.sa_len = 2 + sizeof(struct etalk_addr);
-               bcopy (data, &sa.sa_data[0], sizeof(struct etalk_addr));
+               bzero(&sdl, sizeof(sdl));
+               sdl.sdl_family = AF_LINK;
+               sdl.sdl_alen = sizeof(struct etalk_addr);
+               sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data) 
+                   + sizeof(struct etalk_addr);
+               bcopy(data, sdl.sdl_data, sizeof(struct etalk_addr));
+               /* these next two lines should not really be needed XXX */
+               sdl.sdl_index = nddp->if_index;
+               sdl.sdl_type = IFT_ETHER;
 
                dPrintf(D_M_PAT, D_L_STARTUP,
                        ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
@@ -1602,7 +1654,7 @@ int at_unreg_mcast(ifID, data)
                         (unsigned)ifID));
                bzero(data, sizeof(struct etalk_addr));
 
-               if (if_delmulti(nddp, &sa))
+               if (if_delmulti(nddp, &sdl))
                        return -1;
        }
        return 0;