Ticket #7081: checksum.patch
| File checksum.patch, 14.0 KB (added by , 14 years ago) |
|---|
-
vboxnetflt/include/VBox/pdmnetinline.h
old new 39 39 #include <iprt/string.h> 40 40 41 41 42 /** 43 * Checksum type. 44 */ 45 typedef enum PDMNETCSUMTYPE 46 { 47 /** No checksum. */ 48 PDMNETCSUMTYPE_NONE = 0, 49 /** Normal TCP checksum. */ 50 PDMNETCSUMTYPE_COMPLETE, 51 /** Checksum on pseudo header (used with GSO). */ 52 PDMNETCSUMTYPE_PSEUDO, 53 /** The usual 32-bit hack. */ 54 PDMNETCSUMTYPE_32_BIT_HACK = 0x7fffffff 55 } PDMNETCSUMTYPE; 56 42 57 43 58 /** 44 59 * Validates the GSO context. … … 162 177 * @param pbPayload Pointer to the payload bytes. 163 178 * @param cbPayload The amount of payload. 164 179 * @param cbHdrs The size of all the headers. 165 * @param fPayloadChecksum Whether to checksum the payload or not. 180 * @param enmCsumType Whether to checksum the payload, the pseudo 181 * header or nothing. 166 182 * @internal 167 183 */ 168 184 DECLINLINE(void) pdmNetGsoUpdateUdpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offUdpHdr, 169 uint8_t const *pbPayload, uint32_t cbPayload, uint8_t cbHdrs, bool fPayloadChecksum) 185 uint8_t const *pbPayload, uint32_t cbPayload, uint8_t cbHdrs, 186 PDMNETCSUMTYPE enmCsumType) 170 187 { 171 188 PRTNETUDP pUdpHdr = (PRTNETUDP)&pbSegHdrs[offUdpHdr]; 172 189 pUdpHdr->uh_ulen = cbPayload + cbHdrs - offUdpHdr; 173 pUdpHdr->uh_sum = fPayloadChecksum ? RTNetUDPChecksum(u32PseudoSum, pUdpHdr) : 0; 190 switch (enmCsumType) 191 { 192 case PDMNETCSUMTYPE_NONE: 193 pUdpHdr->uh_sum = 0; 194 break; 195 case PDMNETCSUMTYPE_COMPLETE: 196 pUdpHdr->uh_sum = RTNetUDPChecksum(u32PseudoSum, pUdpHdr); 197 break; 198 case PDMNETCSUMTYPE_PSEUDO: 199 pUdpHdr->uh_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum); 200 break; 201 default: 202 AssertFailed(); 203 break; 204 } 174 205 } 175 206 176 207 … … 187 218 * immediately after the TCP header w/ options. 188 219 * @param cbHdrs The size of all the headers. 189 220 * @param fLastSeg Set if this is the last segment. 190 * @param fPayloadChecksum Whether to checksum the payload or not. 221 * @param enmCsumType Whether to checksum the payload, the pseudo 222 * header or nothing. 191 223 * @internal 192 224 */ 193 225 DECLINLINE(void) pdmNetGsoUpdateTcpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offTcpHdr, 194 226 uint8_t const *pbPayload, uint32_t cbPayload, uint32_t offPayload, uint8_t cbHdrs, 195 bool fLastSeg, bool fPayloadChecksum)227 bool fLastSeg, PDMNETCSUMTYPE enmCsumType) 196 228 { 197 229 PRTNETTCP pTcpHdr = (PRTNETTCP)&pbSegHdrs[offTcpHdr]; 198 230 pTcpHdr->th_seq = RT_H2N_U32(RT_N2H_U32(pTcpHdr->th_seq) + offPayload); 199 231 if (!fLastSeg) 200 232 pTcpHdr->th_flags &= ~(RTNETTCP_F_FIN | RTNETTCP_F_PSH); 201 pTcpHdr->th_sum = fPayloadChecksum ? RTNetTCPChecksum(u32PseudoSum, pTcpHdr, pbPayload, cbPayload) : 0; 233 switch (enmCsumType) 234 { 235 case PDMNETCSUMTYPE_NONE: 236 pTcpHdr->th_sum = 0; 237 break; 238 case PDMNETCSUMTYPE_COMPLETE: 239 pTcpHdr->th_sum = RTNetTCPChecksum(u32PseudoSum, pTcpHdr, pbPayload, cbPayload); 240 break; 241 case PDMNETCSUMTYPE_PSEUDO: 242 pTcpHdr->th_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum); 243 break; 244 default: 245 AssertFailed(); 246 break; 247 } 202 248 } 203 249 204 250 … … 305 351 case PDMNETWORKGSOTYPE_IPV4_TCP: 306 352 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), 307 353 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 308 pGso->cbHdrs, iSeg + 1 == cSegs, true);354 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 309 355 break; 310 356 case PDMNETWORKGSOTYPE_IPV4_UDP: 311 357 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), 312 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);358 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 313 359 break; 314 360 case PDMNETWORKGSOTYPE_IPV6_TCP: 315 361 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, 316 362 pGso->offHdr2, RTNETIPV4_PROT_TCP), 317 363 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 318 pGso->cbHdrs, iSeg + 1 == cSegs, true);364 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 319 365 break; 320 366 case PDMNETWORKGSOTYPE_IPV6_UDP: 321 367 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, 322 368 pGso->offHdr2, RTNETIPV4_PROT_UDP), 323 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);369 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 324 370 break; 325 371 case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: 326 372 pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); 327 373 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), 328 374 cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), 329 375 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 330 pGso->cbHdrs, iSeg + 1 == cSegs, true);376 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 331 377 break; 332 378 case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: 333 379 pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); 334 380 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), 335 381 cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), 336 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);382 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 337 383 break; 338 384 case PDMNETWORKGSOTYPE_INVALID: 339 385 case PDMNETWORKGSOTYPE_END: … … 398 444 case PDMNETWORKGSOTYPE_IPV4_TCP: 399 445 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), 400 446 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 401 pGso->cbHdrs, iSeg + 1 == cSegs, true);447 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 402 448 break; 403 449 case PDMNETWORKGSOTYPE_IPV4_UDP: 404 450 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), 405 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);451 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 406 452 break; 407 453 case PDMNETWORKGSOTYPE_IPV6_TCP: 408 454 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, 409 455 pGso->offHdr2, RTNETIPV4_PROT_TCP), 410 456 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 411 pGso->cbHdrs, iSeg + 1 == cSegs, true);457 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 412 458 break; 413 459 case PDMNETWORKGSOTYPE_IPV6_UDP: 414 460 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, 415 461 pGso->offHdr2, RTNETIPV4_PROT_UDP), 416 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);462 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 417 463 break; 418 464 case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: 419 465 pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); 420 466 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), 421 467 cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), 422 468 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, 423 pGso->cbHdrs, iSeg + 1 == cSegs, true);469 pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); 424 470 break; 425 471 case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: 426 472 pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); 427 473 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), 428 474 cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), 429 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true);475 pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); 430 476 break; 431 477 case PDMNETWORKGSOTYPE_INVALID: 432 478 case PDMNETWORKGSOTYPE_END: … … 445 491 * @param pGso The GSO context. 446 492 * @param pvFrame The frame to prepare. 447 493 * @param cbFrame The frame size. 448 * @param fPayloadChecksum Whether to checksum payload. 494 * @param enmCsumType Whether to checksum the payload, the pseudo 495 * header or nothing. 449 496 */ 450 DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, size_t cbFrame, bool fPayloadChecksum)497 DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, size_t cbFrame, PDMNETCSUMTYPE enmCsumType) 451 498 { 452 499 /* 453 500 * Figure out where the payload is and where the header starts before we … … 470 517 { 471 518 case PDMNETWORKGSOTYPE_IPV4_TCP: 472 519 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrs, 0, pGso->cbHdrs), 473 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum);520 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); 474 521 break; 475 522 case PDMNETWORKGSOTYPE_IPV4_UDP: 476 523 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrs, 0, pGso->cbHdrs), 477 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum);524 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); 478 525 break; 479 526 case PDMNETWORKGSOTYPE_IPV6_TCP: 480 527 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrs, 481 528 pGso->offHdr2, RTNETIPV4_PROT_TCP), 482 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum);529 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); 483 530 break; 484 531 case PDMNETWORKGSOTYPE_IPV6_UDP: 485 532 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrs, 486 533 pGso->offHdr2, RTNETIPV4_PROT_UDP), 487 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum);534 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); 488 535 break; 489 536 case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: 490 537 pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrs); 491 538 pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1), 492 539 cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), 493 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum);540 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); 494 541 break; 495 542 case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: 496 543 pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrs); 497 544 pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1), 498 545 cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), 499 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum);546 pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); 500 547 break; 501 548 case PDMNETWORKGSOTYPE_INVALID: 502 549 case PDMNETWORKGSOTYPE_END:

