MCPcopy Create free account
hub / github.com/encodeous/nylon / tcpGRO

Function tcpGRO

polyamide/tun/offload_linux.go:531–621  ·  view source on GitHub ↗

tcpGRO evaluates the TCP packet at pktI in bufs for coalescing with existing packets tracked in table. It returns a groResultNoop when no action was taken, groResultTableInsert when the evaluated packet was inserted into table, and groResultCoalesced when the evaluated packet was coalesced with anot

(bufs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool)

Source from the content-addressed store, hash-verified

529// inserted into table, and groResultCoalesced when the evaluated packet was
530// coalesced with another packet in table.
531func tcpGRO(bufs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool) groResult {
532 pkt := bufs[pktI][offset:]
533 if len(pkt) > maxUint16 {
534 // A valid IPv4 or IPv6 packet will never exceed this.
535 return groResultNoop
536 }
537 iphLen := int((pkt[0] & 0x0F) * 4)
538 if isV6 {
539 iphLen = 40
540 ipv6HPayloadLen := int(binary.BigEndian.Uint16(pkt[4:]))
541 if ipv6HPayloadLen != len(pkt)-iphLen {
542 return groResultNoop
543 }
544 } else {
545 totalLen := int(binary.BigEndian.Uint16(pkt[2:]))
546 if totalLen != len(pkt) {
547 return groResultNoop
548 }
549 }
550 if len(pkt) < iphLen {
551 return groResultNoop
552 }
553 tcphLen := int((pkt[iphLen+12] >> 4) * 4)
554 if tcphLen < 20 || tcphLen > 60 {
555 return groResultNoop
556 }
557 if len(pkt) < iphLen+tcphLen {
558 return groResultNoop
559 }
560 if !isV6 {
561 if pkt[6]&ipv4FlagMoreFragments != 0 || pkt[6]<<3 != 0 || pkt[7] != 0 {
562 // no GRO support for fragmented segments for now
563 return groResultNoop
564 }
565 }
566 tcpFlags := pkt[iphLen+tcpFlagsOffset]
567 var pshSet bool
568 // not a candidate if any non-ACK flags (except PSH+ACK) are set
569 if tcpFlags != tcpFlagACK {
570 if pkt[iphLen+tcpFlagsOffset] != tcpFlagACK|tcpFlagPSH {
571 return groResultNoop
572 }
573 pshSet = true
574 }
575 gsoSize := uint16(len(pkt) - tcphLen - iphLen)
576 // not a candidate if payload len is 0
577 if gsoSize < 1 {
578 return groResultNoop
579 }
580 seq := binary.BigEndian.Uint32(pkt[iphLen+4:])
581 srcAddrOffset := ipv4SrcAddrOffset
582 addrLen := 4
583 if isV6 {
584 srcAddrOffset = ipv6SrcAddrOffset
585 addrLen = 16
586 }
587 items, existing := table.lookupOrInsert(pkt, srcAddrOffset, srcAddrOffset+addrLen, iphLen, tcphLen, pktI)
588 if !existing {

Callers 1

handleGROFunction · 0.85

Calls 6

tcpPacketsCanCoalesceFunction · 0.85
coalesceTCPPacketsFunction · 0.85
deleteAtMethod · 0.80
lookupOrInsertMethod · 0.45
updateAtMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected