net/packet: support full IPv6 decoding.

The packet filter still rejects all IPv6, but decodes enough from v6
packets to do something smarter in a followup.

name              time/op
Decode/tcp4-8     28.8ns ± 2%
Decode/tcp6-8     20.6ns ± 1%
Decode/udp4-8     28.2ns ± 1%
Decode/udp6-8     20.0ns ± 6%
Decode/icmp4-8    21.7ns ± 2%
Decode/icmp6-8    14.1ns ± 2%
Decode/unknown-8  9.43ns ± 2%

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson
2020-11-10 01:00:35 -08:00
committed by Dave Anderson
parent 89894c6930
commit 55b1221db2
11 changed files with 463 additions and 193 deletions

View File

@@ -34,7 +34,7 @@ const (
ICMP4NoCode ICMP4Code = 0
)
// ICMPHeader represents an ICMP packet header.
// ICMP4Header represents an ICMPv4 packet header.
type ICMP4Header struct {
IP4Header
Type ICMP4Type
@@ -42,24 +42,24 @@ type ICMP4Header struct {
}
const (
icmpHeaderLength = 4
// icmpTotalHeaderLength is the length of all headers in a ICMP packet.
icmpAllHeadersLength = ipHeaderLength + icmpHeaderLength
icmp4HeaderLength = 4
// icmp4AllHeadersLength is the length of all headers in a ICMPv4 packet.
icmp4AllHeadersLength = ip4HeaderLength + icmp4HeaderLength
)
func (ICMP4Header) Len() int {
return icmpAllHeadersLength
return icmp4AllHeadersLength
}
func (h ICMP4Header) Marshal(buf []byte) error {
if len(buf) < icmpAllHeadersLength {
if len(buf) < icmp4AllHeadersLength {
return errSmallBuffer
}
if len(buf) > maxPacketLength {
return errLargePacket
}
// The caller does not need to set this.
h.IPProto = ICMP
h.IPProto = ICMPv4
buf[20] = uint8(h.Type)
buf[21] = uint8(h.Code)