mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-10 09:45:08 +00:00
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:

committed by
Dave Anderson

parent
89894c6930
commit
55b1221db2
@@ -243,7 +243,7 @@ func (f *Filter) runIn(q *packet.Parsed) (r Response, why string) {
|
||||
}
|
||||
|
||||
switch q.IPProto {
|
||||
case packet.ICMP:
|
||||
case packet.ICMPv4:
|
||||
if q.IsEchoResponse() || q.IsError() {
|
||||
// ICMP responses are allowed.
|
||||
// TODO(apenwarr): consider using conntrack state.
|
||||
@@ -383,7 +383,7 @@ func omitDropLogging(p *packet.Parsed, dir direction) bool {
|
||||
// it doesn't know about, so parse it out ourselves if needed.
|
||||
ipProto := p.IPProto
|
||||
if ipProto == 0 && len(b) > 8 {
|
||||
ipProto = packet.IP4Proto(b[9])
|
||||
ipProto = packet.IPProto(b[9])
|
||||
}
|
||||
// Omit logging about outgoing IGMP.
|
||||
if ipProto == packet.IGMP {
|
||||
|
@@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
var Unknown = packet.Unknown
|
||||
var ICMP = packet.ICMP
|
||||
var ICMPv4 = packet.ICMPv4
|
||||
var TCP = packet.TCP
|
||||
var UDP = packet.UDP
|
||||
var Fragment = packet.Fragment
|
||||
@@ -140,7 +140,7 @@ func TestFilter(t *testing.T) {
|
||||
// Basic
|
||||
{Accept, parsed(TCP, 0x08010101, 0x01020304, 999, 22)},
|
||||
{Accept, parsed(UDP, 0x08010101, 0x01020304, 999, 22)},
|
||||
{Accept, parsed(ICMP, 0x08010101, 0x01020304, 0, 0)},
|
||||
{Accept, parsed(ICMPv4, 0x08010101, 0x01020304, 0, 0)},
|
||||
{Drop, parsed(TCP, 0x08010101, 0x01020304, 0, 0)},
|
||||
{Accept, parsed(TCP, 0x08010101, 0x01020304, 0, 22)},
|
||||
{Drop, parsed(TCP, 0x08010101, 0x01020304, 0, 21)},
|
||||
@@ -250,7 +250,7 @@ func BenchmarkFilter(b *testing.B) {
|
||||
|
||||
tcpPacket := rawpacket(TCP, 0x08010101, 0x01020304, 999, 22, 0)
|
||||
udpPacket := rawpacket(UDP, 0x08010101, 0x01020304, 999, 22, 0)
|
||||
icmpPacket := rawpacket(ICMP, 0x08010101, 0x01020304, 0, 0, 0)
|
||||
icmpPacket := rawpacket(ICMPv4, 0x08010101, 0x01020304, 0, 0, 0)
|
||||
|
||||
tcpSynPacket := rawpacket(TCP, 0x08010101, 0x01020304, 999, 22, 0)
|
||||
// TCP filtering is trivial (Accept) for non-SYN packets.
|
||||
@@ -299,7 +299,7 @@ func TestPreFilter(t *testing.T) {
|
||||
{"fragment", Accept, rawdefault(Fragment, 40)},
|
||||
{"tcp", noVerdict, rawdefault(TCP, 200)},
|
||||
{"udp", noVerdict, rawdefault(UDP, 200)},
|
||||
{"icmp", noVerdict, rawdefault(ICMP, 200)},
|
||||
{"icmp", noVerdict, rawdefault(ICMPv4, 200)},
|
||||
}
|
||||
f := NewAllowNone(t.Logf)
|
||||
for _, testPacket := range packets {
|
||||
@@ -312,7 +312,7 @@ func TestPreFilter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func parsed(proto packet.IP4Proto, src, dst packet.IP4, sport, dport uint16) packet.Parsed {
|
||||
func parsed(proto packet.IPProto, src, dst packet.IP4, sport, dport uint16) packet.Parsed {
|
||||
return packet.Parsed{
|
||||
IPProto: proto,
|
||||
SrcIP4: src,
|
||||
@@ -325,11 +325,11 @@ func parsed(proto packet.IP4Proto, src, dst packet.IP4, sport, dport uint16) pac
|
||||
|
||||
// rawpacket generates a packet with given source and destination ports and IPs
|
||||
// and resizes the header to trimLength if it is nonzero.
|
||||
func rawpacket(proto packet.IP4Proto, src, dst packet.IP4, sport, dport uint16, trimLength int) []byte {
|
||||
func rawpacket(proto packet.IPProto, src, dst packet.IP4, sport, dport uint16, trimLength int) []byte {
|
||||
var headerLength int
|
||||
|
||||
switch proto {
|
||||
case ICMP:
|
||||
case ICMPv4:
|
||||
headerLength = 24
|
||||
case TCP:
|
||||
headerLength = 40
|
||||
@@ -357,7 +357,7 @@ func rawpacket(proto packet.IP4Proto, src, dst packet.IP4, sport, dport uint16,
|
||||
bin.PutUint16(hdr[22:24], dport)
|
||||
|
||||
switch proto {
|
||||
case ICMP:
|
||||
case ICMPv4:
|
||||
hdr[9] = 1
|
||||
case TCP:
|
||||
hdr[9] = 6
|
||||
@@ -379,7 +379,7 @@ func rawpacket(proto packet.IP4Proto, src, dst packet.IP4, sport, dport uint16,
|
||||
}
|
||||
|
||||
// rawdefault calls rawpacket with default ports and IPs.
|
||||
func rawdefault(proto packet.IP4Proto, trimLength int) []byte {
|
||||
func rawdefault(proto packet.IPProto, trimLength int) []byte {
|
||||
ip := packet.IP4(0x08080808) // 8.8.8.8
|
||||
port := uint16(53)
|
||||
return rawpacket(proto, ip, ip, port, port, trimLength)
|
||||
|
Reference in New Issue
Block a user