X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..cc9f6e38162d3c1bf6ca97536c2477f476c8e01b:/bsd/netat/ddp_lap.c diff --git a/bsd/netat/ddp_lap.c b/bsd/netat/ddp_lap.c index 80a700a67..f2ed8d1b4 100644 --- a/bsd/netat/ddp_lap.c +++ b/bsd/netat/ddp_lap.c @@ -53,9 +53,13 @@ #include #include #include +#include #include #include +#include #include +#include /* for kernel_map */ + #include #include @@ -77,6 +81,8 @@ #include #include +#include + /* 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;