Changeset 16740 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin
- Timestamp:
- Feb 13, 2009 2:59:48 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetAdapter-darwin.cpp
r16739 r16740 45 45 #include <sys/param.h> 46 46 47 #define VBOX TAP_MAX_INSTANCES 848 #define VBOX TAP_MAX_FAMILIES 449 #define VBOX TAP_NAME "vboxnet"50 #define VBOX TAP_MTU 150051 #define VBOX TAP_DETACH_TIMEOUT 50052 53 #define VBOX TAP_FROM_IFACE(iface) ((PVBOXTAP) ifnet_softc(iface))47 #define VBOXNETADA_MAX_INSTANCES 8 48 #define VBOXNETADA_MAX_FAMILIES 4 49 #define VBOXNETADA_NAME "vboxnet" 50 #define VBOXNETADA_MTU 1500 51 #define VBOXNETADA_DETACH_TIMEOUT 500 52 53 #define VBOXNETADA_FROM_IFACE(iface) ((PVBOXNETADA) ifnet_softc(iface)) 54 54 55 55 /** 56 * Void TAPs mark vacant slots in TAP array. Valid TAPs are busy slots.56 * Void NETADAs mark vacant slots in NETADA array. Valid NETADAs are busy slots. 57 57 * As soon as slot is being modified its state changes to transitional. 58 * TAPs in transitional state must only be accessed by the thread that58 * NETADAs in transitional state must only be accessed by the thread that 59 59 * put it to this state. 60 60 */ 61 enum VBox TapState62 { 63 VBOX TAP_ST_VOID,64 VBOX TAP_ST_TRANSITIONAL,65 VBOX TAP_ST_VALID61 enum VBoxNetAdaState 62 { 63 VBOXNETADA_ST_VOID, 64 VBOXNETADA_ST_TRANSITIONAL, 65 VBOXNETADA_ST_VALID 66 66 }; 67 typedef enum VBox TapState VBOXTAPSTATE;68 69 struct VBox Tap67 typedef enum VBoxNetAdaState VBOXNETADASTATE; 68 69 struct VBoxNetAda 70 70 { 71 71 /** Mutex protecting access to enmState. */ 72 72 RTSEMFASTMUTEX hStateMtx; 73 /** Denotes availability of this TAP. */74 VBOX TAPSTATE enmState;75 /** Corresponds to the digit at the end of TAPname. */73 /** Denotes availability of this NETADA. */ 74 VBOXNETADASTATE enmState; 75 /** Corresponds to the digit at the end of NETADA name. */ 76 76 uint8_t uUnit; 77 77 /** Event to signal detachment of interface. */ … … 80 80 ifnet_t pIface; 81 81 /* todo: MAC address? */ 82 /** Protocol families attached to this TAP. */83 protocol_family_t aAttachedFamilies[VBOX TAP_MAX_FAMILIES];82 /** Protocol families attached to this NETADA. */ 83 protocol_family_t aAttachedFamilies[VBOXNETADA_MAX_FAMILIES]; 84 84 }; 85 typedef struct VBox Tap VBOXTAP;86 typedef VBOX TAP *PVBOXTAP;87 88 VBOX TAP g_aTaps[VBOXTAP_MAX_INSTANCES];89 90 DECLINLINE(bool) vbox TAPIsValid(PVBOXTAP pTap)91 { 92 return p Tap->enmState == VBOXTAP_ST_VALID;93 } 94 95 DECLINLINE(bool) vbox TAPIsVoid(PVBOXTAP pTap)96 { 97 return p Tap->enmState == VBOXTAP_ST_VOID;98 } 99 100 static void vbox TAPComposeMACAddress(PVBOXTAP pTap, PCRTMAC pCustomMac, struct sockaddr_dl *pMac)85 typedef struct VBoxNetAda VBOXNETADA; 86 typedef VBOXNETADA *PVBOXNETADA; 87 88 VBOXNETADA g_aAdapters[VBOXNETADA_MAX_INSTANCES]; 89 90 DECLINLINE(bool) vboxNetAdaIsValid(PVBOXNETADA pAda) 91 { 92 return pAda->enmState == VBOXNETADA_ST_VALID; 93 } 94 95 DECLINLINE(bool) vboxNetAdaIsVoid(PVBOXNETADA pAda) 96 { 97 return pAda->enmState == VBOXNETADA_ST_VOID; 98 } 99 100 static void vboxNetAdaComposeMACAddress(PVBOXNETADA pAda, PCRTMAC pCustomMac, struct sockaddr_dl *pMac) 101 101 { 102 102 pMac->sdl_len = sizeof(*pMac); … … 110 110 { 111 111 memcpy(LLADDR(pMac), "\0vbox0", pMac->sdl_alen); 112 LLADDR(pMac)[ETHER_ADDR_LEN - 1] += p Tap->uUnit;113 } 114 } 115 116 static void vbox TAPComposeUUID(PVBOXTAP pTap, PRTUUID pUuid)112 LLADDR(pMac)[ETHER_ADDR_LEN - 1] += pAda->uUnit; 113 } 114 } 115 116 static void vboxNetAdaComposeUUID(PVBOXNETADA pAda, PRTUUID pUuid) 117 117 { 118 118 /* Generate UUID from name and MAC address. */ … … 121 121 pUuid->Gen.u8ClockSeqHiAndReserved = (pUuid->Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; 122 122 pUuid->Gen.u16TimeHiAndVersion = (pUuid->Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; 123 pUuid->Gen.u8ClockSeqLow = p Tap->uUnit;123 pUuid->Gen.u8ClockSeqLow = pAda->uUnit; 124 124 memcpy(pUuid->Gen.au8Node, "\0vbox0", sizeof(pUuid->Gen.au8Node)); 125 pUuid->Gen.au8Node[sizeof(pUuid->Gen.au8Node) - 1] += p Tap->uUnit;126 } 127 128 129 static errno_t vbox TAPOutput(ifnet_t pIface, mbuf_t pMBuf)125 pUuid->Gen.au8Node[sizeof(pUuid->Gen.au8Node) - 1] += pAda->uUnit; 126 } 127 128 129 static errno_t vboxNetAdaOutput(ifnet_t pIface, mbuf_t pMBuf) 130 130 { 131 131 mbuf_freem_list(pMBuf); … … 133 133 } 134 134 135 static void vbox TAPAttachFamily(PVBOXTAP pTap, protocol_family_t Family)135 static void vboxNetAdaAttachFamily(PVBOXNETADA pAda, protocol_family_t Family) 136 136 { 137 137 u_int32_t i; 138 for (i = 0; i < VBOX TAP_MAX_FAMILIES; i++)139 if (p Tap->aAttachedFamilies[i] == 0)138 for (i = 0; i < VBOXNETADA_MAX_FAMILIES; i++) 139 if (pAda->aAttachedFamilies[i] == 0) 140 140 { 141 p Tap->aAttachedFamilies[i] = Family;141 pAda->aAttachedFamilies[i] = Family; 142 142 break; 143 143 } 144 144 } 145 145 146 static void vbox TAPDetachFamily(PVBOXTAP pTap, protocol_family_t Family)146 static void vboxNetAdaDetachFamily(PVBOXNETADA pAda, protocol_family_t Family) 147 147 { 148 148 u_int32_t i; 149 for (i = 0; i < VBOX TAP_MAX_FAMILIES; i++)150 if (p Tap->aAttachedFamilies[i] == Family)151 p Tap->aAttachedFamilies[i] = 0;152 } 153 154 static errno_t vbox TAPAddProto(ifnet_t pIface, protocol_family_t Family, const struct ifnet_demux_desc *pDemuxDesc, u_int32_t nDesc)155 { 156 PVBOX TAP pTap = VBOXTAP_FROM_IFACE(pIface);157 Assert(p Tap);158 vbox TAPAttachFamily(pTap, Family);159 LogFlow(("vbox TAPAddProto: Family=%d.\n", Family));149 for (i = 0; i < VBOXNETADA_MAX_FAMILIES; i++) 150 if (pAda->aAttachedFamilies[i] == Family) 151 pAda->aAttachedFamilies[i] = 0; 152 } 153 154 static errno_t vboxNetAdaAddProto(ifnet_t pIface, protocol_family_t Family, const struct ifnet_demux_desc *pDemuxDesc, u_int32_t nDesc) 155 { 156 PVBOXNETADA pAda = VBOXNETADA_FROM_IFACE(pIface); 157 Assert(pAda); 158 vboxNetAdaAttachFamily(pAda, Family); 159 LogFlow(("vboxNetAdaAddProto: Family=%d.\n", Family)); 160 160 return ether_add_proto(pIface, Family, pDemuxDesc, nDesc); 161 161 } 162 162 163 static errno_t vbox TAPDelProto(ifnet_t pIface, protocol_family_t Family)164 { 165 PVBOX TAP pTap = VBOXTAP_FROM_IFACE(pIface);166 Assert(p Tap);167 LogFlow(("vbox TAPDelProto: Family=%d.\n", Family));168 vbox TAPDetachFamily(pTap, Family);163 static errno_t vboxNetAdaDelProto(ifnet_t pIface, protocol_family_t Family) 164 { 165 PVBOXNETADA pAda = VBOXNETADA_FROM_IFACE(pIface); 166 Assert(pAda); 167 LogFlow(("vboxNetAdaDelProto: Family=%d.\n", Family)); 168 vboxNetAdaDetachFamily(pAda, Family); 169 169 return ether_del_proto(pIface, Family); 170 170 } 171 171 172 static void vbox TAPDetach(ifnet_t pIface)173 { 174 PVBOX TAP pTap = VBOXTAP_FROM_IFACE(pIface);175 Assert(p Tap);176 Log(("vbox TAPDetach: Signaling detach to vboxTAPUnregisterDevice.\n"));177 /* Let vbox TAPUnregisterDevice know that the interface has been detached. */178 RTSemEventSignal(p Tap->hEvtDetached);179 } 180 181 182 static int vbox TAPRegisterDevice(PVBOXTAP pTap, const struct sockaddr_dl *pMACAddress)172 static void vboxNetAdaDetach(ifnet_t pIface) 173 { 174 PVBOXNETADA pAda = VBOXNETADA_FROM_IFACE(pIface); 175 Assert(pAda); 176 Log(("vboxNetAdaDetach: Signaling detach to vboxNetAdaUnregisterDevice.\n")); 177 /* Let vboxNetAdaUnregisterDevice know that the interface has been detached. */ 178 RTSemEventSignal(pAda->hEvtDetached); 179 } 180 181 182 static int vboxNetAdaRegisterDevice(PVBOXNETADA pAda, const struct sockaddr_dl *pMACAddress) 183 183 { 184 184 struct ifnet_init_params Params; 185 185 RTUUID uuid; 186 186 187 vbox TAPComposeUUID(pTap, &uuid);187 vboxNetAdaComposeUUID(pAda, &uuid); 188 188 Params.uniqueid = uuid.au8; 189 189 Params.uniqueid_len = sizeof(uuid); 190 Params.name = VBOX TAP_NAME;191 Params.unit = p Tap->uUnit;190 Params.name = VBOXNETADA_NAME; 191 Params.unit = pAda->uUnit; 192 192 Params.family = IFNET_FAMILY_ETHERNET; 193 193 Params.type = IFT_ETHER; 194 Params.output = vbox TAPOutput;194 Params.output = vboxNetAdaOutput; 195 195 Params.demux = ether_demux; 196 Params.add_proto = vbox TAPAddProto;197 Params.del_proto = vbox TAPDelProto;196 Params.add_proto = vboxNetAdaAddProto; 197 Params.del_proto = vboxNetAdaDelProto; 198 198 Params.check_multi = ether_check_multi; 199 199 Params.framer = ether_frameout; 200 Params.softc = p Tap;200 Params.softc = pAda; 201 201 Params.ioctl = ether_ioctl; 202 202 Params.set_bpf_tap = NULL; 203 Params.detach = vbox TAPDetach;203 Params.detach = vboxNetAdaDetach; 204 204 Params.event = NULL; 205 205 Params.broadcast_addr = "\xFF\xFF\xFF\xFF\xFF\xFF"; 206 206 Params.broadcast_len = ETHER_ADDR_LEN; 207 207 208 errno_t err = ifnet_allocate(&Params, &p Tap->pIface);208 errno_t err = ifnet_allocate(&Params, &pAda->pIface); 209 209 if (!err) 210 210 { 211 err = ifnet_attach(p Tap->pIface, pMACAddress);211 err = ifnet_attach(pAda->pIface, pMACAddress); 212 212 if (!err) 213 213 { 214 err = ifnet_set_flags(p Tap->pIface, IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, 0xFFFF);214 err = ifnet_set_flags(pAda->pIface, IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, 0xFFFF); 215 215 if (!err) 216 216 { 217 ifnet_set_mtu(p Tap->pIface, VBOXTAP_MTU);217 ifnet_set_mtu(pAda->pIface, VBOXNETADA_MTU); 218 218 return VINF_SUCCESS; 219 219 } 220 220 else 221 Log(("vbox TAPRegisterDevice: Failed to set flags (err=%d).\n", err));222 ifnet_detach(p Tap->pIface);221 Log(("vboxNetAdaRegisterDevice: Failed to set flags (err=%d).\n", err)); 222 ifnet_detach(pAda->pIface); 223 223 } 224 224 else 225 Log(("vbox TAPRegisterDevice: Failed to attach to interface (err=%d).\n", err));226 ifnet_release(p Tap->pIface);225 Log(("vboxNetAdaRegisterDevice: Failed to attach to interface (err=%d).\n", err)); 226 ifnet_release(pAda->pIface); 227 227 } 228 228 else 229 Log(("vbox TAPRegisterDevice: Failed to allocate interface (err=%d).\n", err));229 Log(("vboxNetAdaRegisterDevice: Failed to allocate interface (err=%d).\n", err)); 230 230 231 231 return RTErrConvertFromErrno(err); 232 232 } 233 233 234 static int vbox TAPUnregisterDevice(PVBOXTAP pTap)234 static int vboxNetAdaUnregisterDevice(PVBOXNETADA pAda) 235 235 { 236 236 u_int32_t i; 237 237 /* Bring down the interface */ 238 238 int rc = VINF_SUCCESS; 239 errno_t err = ifnet_set_flags(p Tap->pIface, 0, IFF_UP | IFF_RUNNING);239 errno_t err = ifnet_set_flags(pAda->pIface, 0, IFF_UP | IFF_RUNNING); 240 240 if (err) 241 Log(("vbox TAPUnregisterDevice: Failed to bring down interface "241 Log(("vboxNetAdaUnregisterDevice: Failed to bring down interface " 242 242 "(err=%d).\n", err)); 243 243 /* Detach all protocols. */ 244 for (i = 0; i < VBOX TAP_MAX_FAMILIES; i++)245 if (p Tap->aAttachedFamilies[i])246 ifnet_detach_protocol(p Tap->pIface, pTap->aAttachedFamilies[i]);244 for (i = 0; i < VBOXNETADA_MAX_FAMILIES; i++) 245 if (pAda->aAttachedFamilies[i]) 246 ifnet_detach_protocol(pAda->pIface, pAda->aAttachedFamilies[i]); 247 247 /* 248 248 * We acquire the lock twice: before and after ifnet_detach. … … 250 250 * is released in detach callback. 251 251 */ 252 err = ifnet_detach(p Tap->pIface);252 err = ifnet_detach(pAda->pIface); 253 253 if (err) 254 Log(("vbox TAPUnregisterDevice: Failed to detach interface "254 Log(("vboxNetAdaUnregisterDevice: Failed to detach interface " 255 255 "(err=%d).\n", err)); 256 Log2(("vbox TAPUnregisterDevice: Trying to acquire lock second time.\n"));257 rc = RTSemEventWait(p Tap->hEvtDetached, VBOXTAP_DETACH_TIMEOUT);256 Log2(("vboxNetAdaUnregisterDevice: Trying to acquire lock second time.\n")); 257 rc = RTSemEventWait(pAda->hEvtDetached, VBOXNETADA_DETACH_TIMEOUT); 258 258 if (rc == VERR_TIMEOUT) 259 LogRel(("VBox TAP: Failed to detach interface %s%d\n.",260 VBOX TAP_NAME, pTap->uUnit));261 err = ifnet_release(p Tap->pIface);259 LogRel(("VBoxNETADA: Failed to detach interface %s%d\n.", 260 VBOXNETADA_NAME, pAda->uUnit)); 261 err = ifnet_release(pAda->pIface); 262 262 if (err) 263 Log(("vbox TAPUnregisterDevice: Failed to release interface (err=%d).\n", err));263 Log(("vboxNetAdaUnregisterDevice: Failed to release interface (err=%d).\n", err)); 264 264 265 265 return rc; 266 266 } 267 267 268 int vbox TAPCreate (PVBOXTAP *ppTap, PCRTMAC pMac)268 int vboxNetAdaCreate (PVBOXNETADA *ppAda, PCRTMAC pMac) 269 269 { 270 270 int rc; 271 271 unsigned i; 272 272 273 for (i = 0; i < RT_ELEMENTS(g_a Taps); i++)274 { 275 PVBOX TAP pTap = &g_aTaps[i];276 RTSemFastMutexRequest(p Tap->hStateMtx);277 if (vbox TAPIsVoid(pTap))273 for (i = 0; i < RT_ELEMENTS(g_aAdapters); i++) 274 { 275 PVBOXNETADA pAda = &g_aAdapters[i]; 276 RTSemFastMutexRequest(pAda->hStateMtx); 277 if (vboxNetAdaIsVoid(pAda)) 278 278 { 279 p Tap->enmState = VBOXTAP_ST_TRANSITIONAL;280 RTSemFastMutexRelease(p Tap->hStateMtx);279 pAda->enmState = VBOXNETADA_ST_TRANSITIONAL; 280 RTSemFastMutexRelease(pAda->hStateMtx); 281 281 /* Found an empty slot -- use it. */ 282 282 struct sockaddr_dl mac; 283 Assert(p Tap->hEvtDetached == NIL_RTSEMEVENT);284 rc = RTSemEventCreate(&p Tap->hEvtDetached);283 Assert(pAda->hEvtDetached == NIL_RTSEMEVENT); 284 rc = RTSemEventCreate(&pAda->hEvtDetached); 285 285 if (RT_FAILURE(rc)) 286 286 return rc; 287 p Tap->uUnit = i;288 vbox TAPComposeMACAddress(pTap, pMac, &mac);289 rc = vbox TAPRegisterDevice(pTap, &mac);290 *pp Tap = pTap;291 RTSemFastMutexRequest(p Tap->hStateMtx);292 p Tap->enmState = VBOXTAP_ST_VALID;293 RTSemFastMutexRelease(p Tap->hStateMtx);287 pAda->uUnit = i; 288 vboxNetAdaComposeMACAddress(pAda, pMac, &mac); 289 rc = vboxNetAdaRegisterDevice(pAda, &mac); 290 *ppAda = pAda; 291 RTSemFastMutexRequest(pAda->hStateMtx); 292 pAda->enmState = VBOXNETADA_ST_VALID; 293 RTSemFastMutexRelease(pAda->hStateMtx); 294 294 return rc; 295 295 } 296 RTSemFastMutexRelease(p Tap->hStateMtx);297 } 298 299 /* All slots in TAParray are busy. */296 RTSemFastMutexRelease(pAda->hStateMtx); 297 } 298 299 /* All slots in NETADA array are busy. */ 300 300 return VERR_OUT_OF_RESOURCES; 301 301 } 302 302 303 int vbox TAPDestroy (PVBOXTAP pTap)303 int vboxNetAdaDestroy (PVBOXNETADA pAda) 304 304 { 305 305 int rc; 306 306 307 RTSemFastMutexRequest(p Tap->hStateMtx);308 if (!vbox TAPIsValid(pTap))309 { 310 RTSemFastMutexRelease(p Tap->hStateMtx);307 RTSemFastMutexRequest(pAda->hStateMtx); 308 if (!vboxNetAdaIsValid(pAda)) 309 { 310 RTSemFastMutexRelease(pAda->hStateMtx); 311 311 return VERR_INVALID_PARAMETER; 312 312 } 313 p Tap->enmState = VBOXTAP_ST_TRANSITIONAL;314 RTSemFastMutexRelease(p Tap->hStateMtx);315 316 rc = vbox TAPUnregisterDevice(pTap);313 pAda->enmState = VBOXNETADA_ST_TRANSITIONAL; 314 RTSemFastMutexRelease(pAda->hStateMtx); 315 316 rc = vboxNetAdaUnregisterDevice(pAda); 317 317 if (RT_FAILURE(rc)) 318 Log(("vbox TAPDestroy: Failed to unregister device (rc=%Rrc).\n", rc));319 320 RTSemEventDestroy(p Tap->hEvtDetached);321 p Tap->hEvtDetached = NIL_RTSEMEVENT;322 323 RTSemFastMutexRequest(p Tap->hStateMtx);324 p Tap->enmState = VBOXTAP_ST_VOID;325 RTSemFastMutexRelease(p Tap->hStateMtx);318 Log(("vboxNetAdaDestroy: Failed to unregister device (rc=%Rrc).\n", rc)); 319 320 RTSemEventDestroy(pAda->hEvtDetached); 321 pAda->hEvtDetached = NIL_RTSEMEVENT; 322 323 RTSemFastMutexRequest(pAda->hStateMtx); 324 pAda->enmState = VBOXNETADA_ST_VOID; 325 RTSemFastMutexRelease(pAda->hStateMtx); 326 326 327 327 return rc; 328 328 } 329 329 330 int vbox TAPModuleStart(void)331 { 332 memset(&g_a Taps, 0, sizeof(g_aTaps));333 for (unsigned i = 0; i < RT_ELEMENTS(g_a Taps); i++)334 { 335 int rc = RTSemFastMutexCreate(&g_a Taps[i].hStateMtx);330 int vboxNetAdaModuleStart(void) 331 { 332 memset(&g_aAdapters, 0, sizeof(g_aAdapters)); 333 for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++) 334 { 335 int rc = RTSemFastMutexCreate(&g_aAdapters[i].hStateMtx); 336 336 if (RT_FAILURE(rc)) 337 337 { 338 Log(("VBox TAP: Failed to create fast mutex (rc=%Rrc).\n", rc));338 Log(("VBoxNetAdapter: Failed to create fast mutex (rc=%Rrc).\n", rc)); 339 339 return rc; 340 340 } … … 344 344 } 345 345 346 int vbox TAPModuleStop(void)346 int vboxNetAdaModuleStop(void) 347 347 { 348 348 int rc; 349 349 unsigned i; 350 350 351 for (i = 0; i < RT_ELEMENTS(g_a Taps); i++)352 { 353 vbox TAPDestroy(&g_aTaps[i]);354 rc = RTSemFastMutexDestroy(g_a Taps[i].hStateMtx);351 for (i = 0; i < RT_ELEMENTS(g_aAdapters); i++) 352 { 353 vboxNetAdaDestroy(&g_aAdapters[i]); 354 rc = RTSemFastMutexDestroy(g_aAdapters[i].hStateMtx); 355 355 if (RT_FAILURE(rc)) 356 Log(("VBox TAP: Failed to destroy fast mutex (rc=%Rrc).\n", rc));356 Log(("VBoxNetAdapter: Failed to destroy fast mutex (rc=%Rrc).\n", rc)); 357 357 } 358 358
Note:
See TracChangeset
for help on using the changeset viewer.