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

Function tcpPacketsCanCoalesce

polyamide/tun/offload_linux.go:334–386  ·  view source on GitHub ↗

tcpPacketsCanCoalesce evaluates if pkt can be coalesced with the packet described by item. This function makes considerations that match the kernel's GRO self tests, which can be found in tools/testing/selftests/net/gro.c.

(pkt []byte, iphLen, tcphLen uint8, seq uint32, pshSet bool, gsoSize uint16, item tcpGROItem, bufs [][]byte, bufsOffset int)

Source from the content-addressed store, hash-verified

332// described by item. This function makes considerations that match the kernel's
333// GRO self tests, which can be found in tools/testing/selftests/net/gro.c.
334func tcpPacketsCanCoalesce(pkt []byte, iphLen, tcphLen uint8, seq uint32, pshSet bool, gsoSize uint16, item tcpGROItem, bufs [][]byte, bufsOffset int) canCoalesce {
335 pktTarget := bufs[item.bufsIndex][bufsOffset:]
336 if tcphLen != item.tcphLen {
337 // cannot coalesce with unequal tcp options len
338 return coalesceUnavailable
339 }
340 if tcphLen > 20 {
341 if !bytes.Equal(pkt[iphLen+20:iphLen+tcphLen], pktTarget[item.iphLen+20:iphLen+tcphLen]) {
342 // cannot coalesce with unequal tcp options
343 return coalesceUnavailable
344 }
345 }
346 if !ipHeadersCanCoalesce(pkt, pktTarget) {
347 return coalesceUnavailable
348 }
349 // seq adjacency
350 lhsLen := item.gsoSize
351 lhsLen += item.numMerged * item.gsoSize
352 if seq == item.sentSeq+uint32(lhsLen) { // pkt aligns following item from a seq num perspective
353 if item.pshSet {
354 // We cannot append to a segment that has the PSH flag set, PSH
355 // can only be set on the final segment in a reassembled group.
356 return coalesceUnavailable
357 }
358 if len(pktTarget[iphLen+tcphLen:])%int(item.gsoSize) != 0 {
359 // A smaller than gsoSize packet has been appended previously.
360 // Nothing can come after a smaller packet on the end.
361 return coalesceUnavailable
362 }
363 if gsoSize > item.gsoSize {
364 // We cannot have a larger packet following a smaller one.
365 return coalesceUnavailable
366 }
367 return coalesceAppend
368 } else if seq+uint32(gsoSize) == item.sentSeq { // pkt aligns in front of item from a seq num perspective
369 if pshSet {
370 // We cannot prepend with a segment that has the PSH flag set, PSH
371 // can only be set on the final segment in a reassembled group.
372 return coalesceUnavailable
373 }
374 if gsoSize < item.gsoSize {
375 // We cannot have a larger packet following a smaller one.
376 return coalesceUnavailable
377 }
378 if gsoSize > item.gsoSize && item.numMerged > 0 {
379 // There's at least one previous merge, and we're larger than all
380 // previous. This would put multiple smaller packets on the end.
381 return coalesceUnavailable
382 }
383 return coalescePrepend
384 }
385 return coalesceUnavailable
386}
387
388func checksumValid(pkt []byte, iphLen, proto uint8, isV6 bool) bool {
389 srcAddrAt := ipv4SrcAddrOffset

Callers 1

tcpGROFunction · 0.85

Calls 1

ipHeadersCanCoalesceFunction · 0.85

Tested by

no test coverage detected