Browse Source

save about 10MB of RAM by not importing gopacket except for tests (#1864)

* save about 10MB of RAM by not importing gopacket except for tests

* big ol find-replace
Jack Doan 1 tháng trước cách đây
mục cha
commit
dd8f660c0a
8 tập tin đã thay đổi với 103 bổ sung và 97 xóa
  1. 15 14
      firewall.go
  2. 7 10
      firewall/packet.go
  3. 34 33
      firewall_test.go
  4. 7 6
      inside_test.go
  5. 7 8
      iputil/checksum.go
  6. 7 0
      iputil/packet.go
  7. 6 7
      outside.go
  8. 20 19
      outside_test.go

+ 15 - 14
firewall.go

@@ -21,6 +21,7 @@ import (
 	"github.com/slackhq/nebula/cert"
 	"github.com/slackhq/nebula/cert"
 	"github.com/slackhq/nebula/config"
 	"github.com/slackhq/nebula/config"
 	"github.com/slackhq/nebula/firewall"
 	"github.com/slackhq/nebula/firewall"
+	"github.com/slackhq/nebula/iputil"
 )
 )
 
 
 type FirewallInterface interface {
 type FirewallInterface interface {
@@ -262,11 +263,11 @@ func (f *Firewall) AddRule(incoming bool, proto uint8, startPort int32, endPort
 	}
 	}
 
 
 	switch proto {
 	switch proto {
-	case firewall.ProtoTCP:
+	case iputil.IPProtocolTCP:
 		fp = ft.TCP
 		fp = ft.TCP
-	case firewall.ProtoUDP:
+	case iputil.IPProtocolUDP:
 		fp = ft.UDP
 		fp = ft.UDP
-	case firewall.ProtoICMP, firewall.ProtoICMPv6:
+	case iputil.IPProtocolICMP, iputil.IPProtocolICMPv6:
 		//ICMP traffic doesn't have ports, so we always coerce to "any", even if a value is provided
 		//ICMP traffic doesn't have ports, so we always coerce to "any", even if a value is provided
 		if startPort != firewall.PortAny {
 		if startPort != firewall.PortAny {
 			f.l.Warn("ignoring port specification for ICMP firewall rule", "startPort", startPort)
 			f.l.Warn("ignoring port specification for ICMP firewall rule", "startPort", startPort)
@@ -364,13 +365,13 @@ func AddFirewallRulesFromConfig(l *slog.Logger, inbound bool, c *config.C, fw Fi
 			proto = firewall.ProtoAny
 			proto = firewall.ProtoAny
 			startPort, endPort, err = parsePort(sPort)
 			startPort, endPort, err = parsePort(sPort)
 		case "tcp":
 		case "tcp":
-			proto = firewall.ProtoTCP
+			proto = iputil.IPProtocolTCP
 			startPort, endPort, err = parsePort(sPort)
 			startPort, endPort, err = parsePort(sPort)
 		case "udp":
 		case "udp":
-			proto = firewall.ProtoUDP
+			proto = iputil.IPProtocolUDP
 			startPort, endPort, err = parsePort(sPort)
 			startPort, endPort, err = parsePort(sPort)
 		case "icmp":
 		case "icmp":
-			proto = firewall.ProtoICMP
+			proto = iputil.IPProtocolICMP
 			startPort = firewall.PortAny
 			startPort = firewall.PortAny
 			endPort = firewall.PortAny
 			endPort = firewall.PortAny
 			if sPort != "" {
 			if sPort != "" {
@@ -560,9 +561,9 @@ func (f *Firewall) inConns(fp firewall.Packet, h *HostInfo, caPool *cert.CAPool,
 	}
 	}
 
 
 	switch fp.Protocol {
 	switch fp.Protocol {
-	case firewall.ProtoTCP:
+	case iputil.IPProtocolTCP:
 		c.Expires = time.Now().Add(f.TCPTimeout)
 		c.Expires = time.Now().Add(f.TCPTimeout)
-	case firewall.ProtoUDP:
+	case iputil.IPProtocolUDP:
 		c.Expires = time.Now().Add(f.UDPTimeout)
 		c.Expires = time.Now().Add(f.UDPTimeout)
 	default:
 	default:
 		c.Expires = time.Now().Add(f.DefaultTimeout)
 		c.Expires = time.Now().Add(f.DefaultTimeout)
@@ -582,9 +583,9 @@ func (f *Firewall) addConn(fp firewall.Packet, incoming bool) {
 	c := &conn{}
 	c := &conn{}
 
 
 	switch fp.Protocol {
 	switch fp.Protocol {
-	case firewall.ProtoTCP:
+	case iputil.IPProtocolTCP:
 		timeout = f.TCPTimeout
 		timeout = f.TCPTimeout
-	case firewall.ProtoUDP:
+	case iputil.IPProtocolUDP:
 		timeout = f.UDPTimeout
 		timeout = f.UDPTimeout
 	default:
 	default:
 		timeout = f.DefaultTimeout
 		timeout = f.DefaultTimeout
@@ -635,15 +636,15 @@ func (ft *FirewallTable) match(p firewall.Packet, incoming bool, c *cert.CachedC
 	}
 	}
 
 
 	switch p.Protocol {
 	switch p.Protocol {
-	case firewall.ProtoTCP:
+	case iputil.IPProtocolTCP:
 		if ft.TCP.match(p, incoming, c, caPool) {
 		if ft.TCP.match(p, incoming, c, caPool) {
 			return true
 			return true
 		}
 		}
-	case firewall.ProtoUDP:
+	case iputil.IPProtocolUDP:
 		if ft.UDP.match(p, incoming, c, caPool) {
 		if ft.UDP.match(p, incoming, c, caPool) {
 			return true
 			return true
 		}
 		}
-	case firewall.ProtoICMP, firewall.ProtoICMPv6:
+	case iputil.IPProtocolICMP, iputil.IPProtocolICMPv6:
 		if ft.ICMP.match(p, incoming, c, caPool) {
 		if ft.ICMP.match(p, incoming, c, caPool) {
 			return true
 			return true
 		}
 		}
@@ -680,7 +681,7 @@ func (fp firewallPort) match(p firewall.Packet, incoming bool, c *cert.CachedCer
 	}
 	}
 
 
 	// this branch is here to catch traffic from FirewallTable.Any.match and FirewallTable.ICMP.match
 	// this branch is here to catch traffic from FirewallTable.Any.match and FirewallTable.ICMP.match
-	if p.Protocol == firewall.ProtoICMP || p.Protocol == firewall.ProtoICMPv6 {
+	if p.Protocol == iputil.IPProtocolICMP || p.Protocol == iputil.IPProtocolICMPv6 {
 		// port numbers are re-used for connection tracking of ICMP,
 		// port numbers are re-used for connection tracking of ICMP,
 		// but we don't want to actually filter on them.
 		// but we don't want to actually filter on them.
 		return fp[firewall.PortAny].match(p, c, caPool)
 		return fp[firewall.PortAny].match(p, c, caPool)

+ 7 - 10
firewall/packet.go

@@ -4,17 +4,14 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"net/netip"
 	"net/netip"
+
+	"github.com/slackhq/nebula/iputil"
 )
 )
 
 
 type m = map[string]any
 type m = map[string]any
 
 
 const (
 const (
-	ProtoAny    = 0 // When we want to handle HOPOPT (0) we can change this, if ever
-	ProtoTCP    = 6
-	ProtoUDP    = 17
-	ProtoICMP   = 1
-	ProtoICMPv6 = 58
-
+	ProtoAny     = 0  // When we want to handle HOPOPT (0) we can change this, if ever
 	PortAny      = 0  // Special value for matching `port: any`
 	PortAny      = 0  // Special value for matching `port: any`
 	PortFragment = -1 // Special value for matching `port: fragment`
 	PortFragment = -1 // Special value for matching `port: fragment`
 )
 )
@@ -45,13 +42,13 @@ func (fp *Packet) Copy() *Packet {
 func (fp Packet) MarshalJSON() ([]byte, error) {
 func (fp Packet) MarshalJSON() ([]byte, error) {
 	var proto string
 	var proto string
 	switch fp.Protocol {
 	switch fp.Protocol {
-	case ProtoTCP:
+	case iputil.IPProtocolTCP:
 		proto = "tcp"
 		proto = "tcp"
-	case ProtoICMP:
+	case iputil.IPProtocolICMP:
 		proto = "icmp"
 		proto = "icmp"
-	case ProtoICMPv6:
+	case iputil.IPProtocolICMPv6:
 		proto = "icmpv6"
 		proto = "icmpv6"
-	case ProtoUDP:
+	case iputil.IPProtocolUDP:
 		proto = "udp"
 		proto = "udp"
 	default:
 	default:
 		proto = fmt.Sprintf("unknown %v", fp.Protocol)
 		proto = fmt.Sprintf("unknown %v", fp.Protocol)

+ 34 - 33
firewall_test.go

@@ -13,6 +13,7 @@ import (
 	"github.com/slackhq/nebula/cert"
 	"github.com/slackhq/nebula/cert"
 	"github.com/slackhq/nebula/config"
 	"github.com/slackhq/nebula/config"
 	"github.com/slackhq/nebula/firewall"
 	"github.com/slackhq/nebula/firewall"
+	"github.com/slackhq/nebula/iputil"
 	"github.com/slackhq/nebula/test"
 	"github.com/slackhq/nebula/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/require"
@@ -72,20 +73,20 @@ func TestFirewall_AddRule(t *testing.T) {
 	ti6, err := netip.ParsePrefix("fd12::34/128")
 	ti6, err := netip.ParsePrefix("fd12::34/128")
 	require.NoError(t, err)
 	require.NoError(t, err)
 
 
-	require.NoError(t, fw.AddRule(true, firewall.ProtoTCP, 1, 1, []string{}, "", "", "", "", ""))
+	require.NoError(t, fw.AddRule(true, iputil.IPProtocolTCP, 1, 1, []string{}, "", "", "", "", ""))
 	// An empty rule is any
 	// An empty rule is any
 	assert.True(t, fw.InRules.TCP[1].Any.Any.Any)
 	assert.True(t, fw.InRules.TCP[1].Any.Any.Any)
 	assert.Empty(t, fw.InRules.TCP[1].Any.Groups)
 	assert.Empty(t, fw.InRules.TCP[1].Any.Groups)
 	assert.Empty(t, fw.InRules.TCP[1].Any.Hosts)
 	assert.Empty(t, fw.InRules.TCP[1].Any.Hosts)
 
 
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
-	require.NoError(t, fw.AddRule(true, firewall.ProtoUDP, 1, 1, []string{"g1"}, "", "", "", "", ""))
+	require.NoError(t, fw.AddRule(true, iputil.IPProtocolUDP, 1, 1, []string{"g1"}, "", "", "", "", ""))
 	assert.Nil(t, fw.InRules.UDP[1].Any.Any)
 	assert.Nil(t, fw.InRules.UDP[1].Any.Any)
 	assert.Contains(t, fw.InRules.UDP[1].Any.Groups[0].Groups, "g1")
 	assert.Contains(t, fw.InRules.UDP[1].Any.Groups[0].Groups, "g1")
 	assert.Empty(t, fw.InRules.UDP[1].Any.Hosts)
 	assert.Empty(t, fw.InRules.UDP[1].Any.Hosts)
 
 
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
-	require.NoError(t, fw.AddRule(true, firewall.ProtoICMP, 1, 1, []string{}, "h1", "", "", "", ""))
+	require.NoError(t, fw.AddRule(true, iputil.IPProtocolICMP, 1, 1, []string{}, "h1", "", "", "", ""))
 	//no matter what port is given for icmp, it should end up as "any"
 	//no matter what port is given for icmp, it should end up as "any"
 	assert.Nil(t, fw.InRules.ICMP[firewall.PortAny].Any.Any)
 	assert.Nil(t, fw.InRules.ICMP[firewall.PortAny].Any.Any)
 	assert.Empty(t, fw.InRules.ICMP[firewall.PortAny].Any.Groups)
 	assert.Empty(t, fw.InRules.ICMP[firewall.PortAny].Any.Groups)
@@ -116,11 +117,11 @@ func TestFirewall_AddRule(t *testing.T) {
 	assert.True(t, ok)
 	assert.True(t, ok)
 
 
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
-	require.NoError(t, fw.AddRule(true, firewall.ProtoUDP, 1, 1, []string{"g1"}, "", "", "", "ca-name", ""))
+	require.NoError(t, fw.AddRule(true, iputil.IPProtocolUDP, 1, 1, []string{"g1"}, "", "", "", "ca-name", ""))
 	assert.Contains(t, fw.InRules.UDP[1].CANames, "ca-name")
 	assert.Contains(t, fw.InRules.UDP[1].CANames, "ca-name")
 
 
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
-	require.NoError(t, fw.AddRule(true, firewall.ProtoUDP, 1, 1, []string{"g1"}, "", "", "", "", "ca-sha"))
+	require.NoError(t, fw.AddRule(true, iputil.IPProtocolUDP, 1, 1, []string{"g1"}, "", "", "", "", "ca-sha"))
 	assert.Contains(t, fw.InRules.UDP[1].CAShas, "ca-sha")
 	assert.Contains(t, fw.InRules.UDP[1].CAShas, "ca-sha")
 
 
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
 	fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
@@ -185,7 +186,7 @@ func TestFirewall_Drop(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		LocalPort:  10,
 		LocalPort:  10,
 		RemotePort: 90,
 		RemotePort: 90,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
@@ -263,7 +264,7 @@ func TestFirewall_DropV6(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("fd12::34"),
 		RemoteAddr: netip.MustParseAddr("fd12::34"),
 		LocalPort:  10,
 		LocalPort:  10,
 		RemotePort: 90,
 		RemotePort: 90,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
@@ -350,7 +351,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			Certificate: &dummyCert{},
 			Certificate: &dummyCert{},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoUDP}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolUDP}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -360,7 +361,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			Certificate: &dummyCert{},
 			Certificate: &dummyCert{},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 1}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 1}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -370,7 +371,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 		}
 		}
 		ip := netip.MustParsePrefix("9.254.254.254/32")
 		ip := netip.MustParsePrefix("9.254.254.254/32")
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: ip.Addr()}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: ip.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 	b.Run("pass proto, port, fail on local CIDRv6", func(b *testing.B) {
 	b.Run("pass proto, port, fail on local CIDRv6", func(b *testing.B) {
@@ -379,7 +380,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 		}
 		}
 		ip := netip.MustParsePrefix("fd99::99/128")
 		ip := netip.MustParsePrefix("fd99::99/128")
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: ip.Addr()}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: ip.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -392,7 +393,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"nope": {}},
 			InvertedGroups: map[string]struct{}{"nope": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 10}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 10}, true, c, cp))
 		}
 		}
 	})
 	})
 	b.Run("pass proto, port, any local CIDRv6, fail all group, name, and cidr", func(b *testing.B) {
 	b.Run("pass proto, port, any local CIDRv6, fail all group, name, and cidr", func(b *testing.B) {
@@ -404,7 +405,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"nope": {}},
 			InvertedGroups: map[string]struct{}{"nope": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 10}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 10}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -417,7 +418,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"nope": {}},
 			InvertedGroups: map[string]struct{}{"nope": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: pfix.Addr()}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: pfix.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 	b.Run("pass proto, port, specific local CIDRv6, fail all group, name, and cidr", func(b *testing.B) {
 	b.Run("pass proto, port, specific local CIDRv6, fail all group, name, and cidr", func(b *testing.B) {
@@ -429,7 +430,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"nope": {}},
 			InvertedGroups: map[string]struct{}{"nope": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.False(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: pfix6.Addr()}, true, c, cp))
+			assert.False(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: pfix6.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -441,7 +442,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.True(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 10}, true, c, cp))
+			assert.True(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 10}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -453,7 +454,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.True(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: pfix.Addr()}, true, c, cp))
+			assert.True(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: pfix.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 	b.Run("pass on group on specific local cidr6", func(b *testing.B) {
 	b.Run("pass on group on specific local cidr6", func(b *testing.B) {
@@ -464,7 +465,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 			InvertedGroups: map[string]struct{}{"good-group": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			assert.True(b, ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 100, LocalAddr: pfix6.Addr()}, true, c, cp))
+			assert.True(b, ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 100, LocalAddr: pfix6.Addr()}, true, c, cp))
 		}
 		}
 	})
 	})
 
 
@@ -476,7 +477,7 @@ func BenchmarkFirewallTable_match(b *testing.B) {
 			InvertedGroups: map[string]struct{}{"nope": {}},
 			InvertedGroups: map[string]struct{}{"nope": {}},
 		}
 		}
 		for n := 0; n < b.N; n++ {
 		for n := 0; n < b.N; n++ {
-			ft.match(firewall.Packet{Protocol: firewall.ProtoTCP, LocalPort: 10}, true, c, cp)
+			ft.match(firewall.Packet{Protocol: iputil.IPProtocolTCP, LocalPort: 10}, true, c, cp)
 		}
 		}
 	})
 	})
 }
 }
@@ -492,7 +493,7 @@ func TestFirewall_Drop2(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		LocalPort:  10,
 		LocalPort:  10,
 		RemotePort: 90,
 		RemotePort: 90,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
@@ -550,7 +551,7 @@ func TestFirewall_Drop3(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		LocalPort:  1,
 		LocalPort:  1,
 		RemotePort: 1,
 		RemotePort: 1,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
@@ -638,7 +639,7 @@ func TestFirewall_Drop3V6(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("fd12::34"),
 		RemoteAddr: netip.MustParseAddr("fd12::34"),
 		LocalPort:  1,
 		LocalPort:  1,
 		RemotePort: 1,
 		RemotePort: 1,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
@@ -675,7 +676,7 @@ func TestFirewall_DropConntrackReload(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		LocalPort:  10,
 		LocalPort:  10,
 		RemotePort: 90,
 		RemotePort: 90,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 	network := netip.MustParsePrefix("1.2.3.4/24")
 	network := netip.MustParsePrefix("1.2.3.4/24")
@@ -758,13 +759,13 @@ func TestFirewall_ICMPPortBehavior(t *testing.T) {
 	templ := firewall.Packet{
 	templ := firewall.Packet{
 		LocalAddr:  netip.MustParseAddr("1.2.3.4"),
 		LocalAddr:  netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
 		RemoteAddr: netip.MustParseAddr("1.2.3.4"),
-		Protocol:   firewall.ProtoICMP,
+		Protocol:   iputil.IPProtocolICMP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 
 
 	t.Run("ICMP allowed", func(t *testing.T) {
 	t.Run("ICMP allowed", func(t *testing.T) {
 		fw := NewFirewall(l, time.Second, time.Minute, time.Hour, c.Certificate)
 		fw := NewFirewall(l, time.Second, time.Minute, time.Hour, c.Certificate)
-		require.NoError(t, fw.AddRule(true, firewall.ProtoICMP, 0, 0, []string{"any"}, "", "", "", "", ""))
+		require.NoError(t, fw.AddRule(true, iputil.IPProtocolICMP, 0, 0, []string{"any"}, "", "", "", "", ""))
 		t.Run("zero ports", func(t *testing.T) {
 		t.Run("zero ports", func(t *testing.T) {
 			p := templ.Copy()
 			p := templ.Copy()
 			p.LocalPort = 0
 			p.LocalPort = 0
@@ -910,7 +911,7 @@ func TestFirewall_DropIPSpoofing(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("192.0.2.3"),
 		RemoteAddr: netip.MustParseAddr("192.0.2.3"),
 		LocalPort:  1,
 		LocalPort:  1,
 		RemotePort: 1,
 		RemotePort: 1,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 	assert.Equal(t, fw.Drop(p, true, &h1, cp, nil), ErrInvalidRemoteIP)
 	assert.Equal(t, fw.Drop(p, true, &h1, cp, nil), ErrInvalidRemoteIP)
@@ -961,7 +962,7 @@ func TestFirewall_ConntrackSourceSpoofingAcrossPeers(t *testing.T) {
 		RemoteAddr: netip.MustParseAddr("192.0.2.2"),
 		RemoteAddr: netip.MustParseAddr("192.0.2.2"),
 		LocalPort:  443,
 		LocalPort:  443,
 		RemotePort: 55000,
 		RemotePort: 55000,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 	}
 	}
 
 
 	require.NoError(t, fw.Drop(flow, true, &victimHI, cp, nil),
 	require.NoError(t, fw.Drop(flow, true, &victimHI, cp, nil),
@@ -1031,7 +1032,7 @@ func BenchmarkFirewallDropConntrackHit(b *testing.B) {
 		RemoteAddr: netip.MustParseAddr("192.0.2.2"),
 		RemoteAddr: netip.MustParseAddr("192.0.2.2"),
 		LocalPort:  443,
 		LocalPort:  443,
 		RemotePort: 55000,
 		RemotePort: 55000,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 	}
 	}
 
 
 	cases := []struct {
 	cases := []struct {
@@ -1317,28 +1318,28 @@ func TestAddFirewallRulesFromConfig(t *testing.T) {
 	mf := &mockFirewall{}
 	mf := &mockFirewall{}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "tcp", "host": "a"}}}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "tcp", "host": "a"}}}
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
-	assert.Equal(t, addRuleCall{incoming: false, proto: firewall.ProtoTCP, startPort: 1, endPort: 1, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
+	assert.Equal(t, addRuleCall{incoming: false, proto: iputil.IPProtocolTCP, startPort: 1, endPort: 1, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
 
 
 	// Test adding udp rule
 	// Test adding udp rule
 	conf = config.NewC(test.NewLogger())
 	conf = config.NewC(test.NewLogger())
 	mf = &mockFirewall{}
 	mf = &mockFirewall{}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "udp", "host": "a"}}}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "udp", "host": "a"}}}
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
-	assert.Equal(t, addRuleCall{incoming: false, proto: firewall.ProtoUDP, startPort: 1, endPort: 1, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
+	assert.Equal(t, addRuleCall{incoming: false, proto: iputil.IPProtocolUDP, startPort: 1, endPort: 1, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
 
 
 	// Test adding icmp rule
 	// Test adding icmp rule
 	conf = config.NewC(test.NewLogger())
 	conf = config.NewC(test.NewLogger())
 	mf = &mockFirewall{}
 	mf = &mockFirewall{}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "icmp", "host": "a"}}}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"port": "1", "proto": "icmp", "host": "a"}}}
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
-	assert.Equal(t, addRuleCall{incoming: false, proto: firewall.ProtoICMP, startPort: firewall.PortAny, endPort: firewall.PortAny, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
+	assert.Equal(t, addRuleCall{incoming: false, proto: iputil.IPProtocolICMP, startPort: firewall.PortAny, endPort: firewall.PortAny, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
 
 
 	// Test adding icmp rule no port
 	// Test adding icmp rule no port
 	conf = config.NewC(test.NewLogger())
 	conf = config.NewC(test.NewLogger())
 	mf = &mockFirewall{}
 	mf = &mockFirewall{}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"proto": "icmp", "host": "a"}}}
 	conf.Settings["firewall"] = map[string]any{"outbound": []any{map[string]any{"proto": "icmp", "host": "a"}}}
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
 	require.NoError(t, AddFirewallRulesFromConfig(l, false, conf, mf))
-	assert.Equal(t, addRuleCall{incoming: false, proto: firewall.ProtoICMP, startPort: firewall.PortAny, endPort: firewall.PortAny, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
+	assert.Equal(t, addRuleCall{incoming: false, proto: iputil.IPProtocolICMP, startPort: firewall.PortAny, endPort: firewall.PortAny, groups: nil, host: "a", ip: "", localIp: ""}, mf.lastCall)
 
 
 	// Test adding any rule
 	// Test adding any rule
 	conf = config.NewC(test.NewLogger())
 	conf = config.NewC(test.NewLogger())
@@ -1582,7 +1583,7 @@ func buildTestCase(setup testsetup, err error, theirPrefixes ...netip.Prefix) te
 		RemoteAddr: theirPrefixes[0].Addr(),
 		RemoteAddr: theirPrefixes[0].Addr(),
 		LocalPort:  10,
 		LocalPort:  10,
 		RemotePort: 90,
 		RemotePort: 90,
-		Protocol:   firewall.ProtoUDP,
+		Protocol:   iputil.IPProtocolUDP,
 		Fragment:   false,
 		Fragment:   false,
 	}
 	}
 	return testcase{
 	return testcase{

+ 7 - 6
inside_test.go

@@ -8,6 +8,7 @@ import (
 
 
 	"github.com/gaissmai/bart"
 	"github.com/gaissmai/bart"
 	"github.com/slackhq/nebula/firewall"
 	"github.com/slackhq/nebula/firewall"
+	"github.com/slackhq/nebula/iputil"
 	"github.com/slackhq/nebula/overlay/tio"
 	"github.com/slackhq/nebula/overlay/tio"
 	"github.com/slackhq/nebula/test"
 	"github.com/slackhq/nebula/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/assert"
@@ -63,7 +64,7 @@ type l4Proto struct {
 }
 }
 
 
 var (
 var (
-	tcpSyn = l4Proto{"tcp", firewall.ProtoTCP, 16, func() []byte {
+	tcpSyn = l4Proto{"tcp", iputil.IPProtocolTCP, 16, func() []byte {
 		h := make([]byte, 20)
 		h := make([]byte, 20)
 		binary.BigEndian.PutUint16(h[0:2], 49152)
 		binary.BigEndian.PutUint16(h[0:2], 49152)
 		binary.BigEndian.PutUint16(h[2:4], 443)
 		binary.BigEndian.PutUint16(h[2:4], 443)
@@ -74,7 +75,7 @@ var (
 		return h
 		return h
 	}}
 	}}
 
 
-	udpDatagram = l4Proto{"udp", firewall.ProtoUDP, 6, func() []byte {
+	udpDatagram = l4Proto{"udp", iputil.IPProtocolUDP, 6, func() []byte {
 		h := make([]byte, 8+4)
 		h := make([]byte, 8+4)
 		binary.BigEndian.PutUint16(h[0:2], 49152)
 		binary.BigEndian.PutUint16(h[0:2], 49152)
 		binary.BigEndian.PutUint16(h[2:4], 53)
 		binary.BigEndian.PutUint16(h[2:4], 53)
@@ -83,8 +84,8 @@ var (
 		return h
 		return h
 	}}
 	}}
 
 
-	icmpEcho   = l4Proto{"icmp", firewall.ProtoICMP, 2, func() []byte { return echoRequest(8) }}
-	icmpv6Echo = l4Proto{"icmpv6", firewall.ProtoICMPv6, 2, func() []byte { return echoRequest(128) }}
+	icmpEcho   = l4Proto{"icmp", iputil.IPProtocolICMP, 2, func() []byte { return echoRequest(8) }}
+	icmpv6Echo = l4Proto{"icmpv6", iputil.IPProtocolICMPv6, 2, func() []byte { return echoRequest(128) }}
 )
 )
 
 
 // echoRequest builds an echo request body. The type differs between ICMP and
 // echoRequest builds an echo request body. The type differs between ICMP and
@@ -107,7 +108,7 @@ func buildIPv6(src, dst netip.Addr, p l4Proto) []byte {
 	copy(pkt[8:24], src.AsSlice())
 	copy(pkt[8:24], src.AsSlice())
 	copy(pkt[24:40], dst.AsSlice())
 	copy(pkt[24:40], dst.AsSlice())
 	copy(pkt[ipv6HeaderLen:], l4)
 	copy(pkt[ipv6HeaderLen:], l4)
-	if l4 := pkt[ipv6HeaderLen:]; p.nextHdr == firewall.ProtoTCP || p.nextHdr == firewall.ProtoUDP {
+	if l4 := pkt[ipv6HeaderLen:]; p.nextHdr == iputil.IPProtocolTCP || p.nextHdr == iputil.IPProtocolUDP {
 		sum := ipv6PseudoheaderSum(src, dst, uint32(p.nextHdr), uint32(len(l4)))
 		sum := ipv6PseudoheaderSum(src, dst, uint32(p.nextHdr), uint32(len(l4)))
 		binary.BigEndian.PutUint16(l4[p.cksumAt:], ^fold(sumBytes(l4, sum)))
 		binary.BigEndian.PutUint16(l4[p.cksumAt:], ^fold(sumBytes(l4, sum)))
 	}
 	}
@@ -124,7 +125,7 @@ func buildIPv4(src, dst netip.Addr, p l4Proto) []byte {
 	copy(pkt[12:16], src.AsSlice())
 	copy(pkt[12:16], src.AsSlice())
 	copy(pkt[16:20], dst.AsSlice())
 	copy(pkt[16:20], dst.AsSlice())
 	copy(pkt[ipv4HeaderLen:], l4)
 	copy(pkt[ipv4HeaderLen:], l4)
-	if l4 := pkt[ipv4HeaderLen:]; p.nextHdr == firewall.ProtoTCP || p.nextHdr == firewall.ProtoUDP {
+	if l4 := pkt[ipv4HeaderLen:]; p.nextHdr == iputil.IPProtocolTCP || p.nextHdr == iputil.IPProtocolUDP {
 		sum := sumBytes(pkt[12:20], uint32(p.nextHdr)+uint32(len(l4)))
 		sum := sumBytes(pkt[12:20], uint32(p.nextHdr)+uint32(len(l4)))
 		binary.BigEndian.PutUint16(l4[p.cksumAt:], ^fold(sumBytes(l4, sum)))
 		binary.BigEndian.PutUint16(l4[p.cksumAt:], ^fold(sumBytes(l4, sum)))
 	}
 	}

+ 7 - 8
iputil/checksum.go

@@ -3,7 +3,6 @@ package iputil
 import (
 import (
 	"encoding/binary"
 	"encoding/binary"
 
 
-	"github.com/google/gopacket/layers"
 	"github.com/slackhq/nebula/overlay/checksum"
 	"github.com/slackhq/nebula/overlay/checksum"
 	"golang.org/x/net/ipv4"
 	"golang.org/x/net/ipv4"
 	"golang.org/x/net/ipv6"
 	"golang.org/x/net/ipv6"
@@ -57,7 +56,7 @@ func setTransportChecksum4(packet []byte) {
 		return
 		return
 	}
 	}
 	csum := ipv4PseudoheaderChecksum(packet[12:16], packet[16:20], uint32(packet[9]), uint32(len(transport)))
 	csum := ipv4PseudoheaderChecksum(packet[12:16], packet[16:20], uint32(packet[9]), uint32(len(transport)))
-	writeTransportChecksum(transport, layers.IPProtocol(packet[9]), csum)
+	writeTransportChecksum(transport, packet[9], csum)
 }
 }
 
 
 func setTransportChecksum6(packet []byte) {
 func setTransportChecksum6(packet []byte) {
@@ -83,7 +82,7 @@ func setTransportChecksum6(packet []byte) {
 		return
 		return
 	}
 	}
 	csum := ipv6PseudoheaderChecksum(packet[8:24], packet[24:40], uint32(proto), uint32(len(transport)))
 	csum := ipv6PseudoheaderChecksum(packet[8:24], packet[24:40], uint32(proto), uint32(len(transport)))
-	writeTransportChecksum(transport, layers.IPProtocol(proto), csum)
+	writeTransportChecksum(transport, proto, csum)
 }
 }
 
 
 // transportExtent narrows a segment to the length its own header declares. UDP
 // transportExtent narrows a segment to the length its own header declares. UDP
@@ -94,7 +93,7 @@ func setTransportChecksum6(packet []byte) {
 // the IP payload. A Length that overruns the bytes IP delivered describes a
 // the IP payload. A Length that overruns the bytes IP delivered describes a
 // datagram that is not there.
 // datagram that is not there.
 func transportExtent(transport []byte, proto uint8) ([]byte, bool) {
 func transportExtent(transport []byte, proto uint8) ([]byte, bool) {
-	if layers.IPProtocol(proto) != layers.IPProtocolUDP {
+	if proto != IPProtocolUDP {
 		return transport, true
 		return transport, true
 	}
 	}
 	if len(transport) < udpHeaderLen {
 	if len(transport) < udpHeaderLen {
@@ -112,12 +111,12 @@ func transportExtent(transport []byte, proto uint8) ([]byte, bool) {
 // computes to zero goes on the wire as 0xffff: zero means no checksum was
 // computes to zero goes on the wire as 0xffff: zero means no checksum was
 // computed (RFC 768), and over IPv6 the checksum is mandatory (RFC 8200
 // computed (RFC 768), and over IPv6 the checksum is mandatory (RFC 8200
 // section 8.1).
 // section 8.1).
-func writeTransportChecksum(transport []byte, proto layers.IPProtocol, csum uint32) {
+func writeTransportChecksum(transport []byte, proto uint8, csum uint32) {
 	var at, minLen int
 	var at, minLen int
 	switch proto {
 	switch proto {
-	case layers.IPProtocolTCP:
+	case IPProtocolTCP:
 		at, minLen = 16, 20
 		at, minLen = 16, 20
-	case layers.IPProtocolUDP:
+	case IPProtocolUDP:
 		at, minLen = 6, udpHeaderLen
 		at, minLen = 6, udpHeaderLen
 	default:
 	default:
 		return
 		return
@@ -128,7 +127,7 @@ func writeTransportChecksum(transport []byte, proto layers.IPProtocol, csum uint
 
 
 	transport[at], transport[at+1] = 0, 0
 	transport[at], transport[at+1] = 0, 0
 	sum := ^checksum.Checksum(transport, fold(csum))
 	sum := ^checksum.Checksum(transport, fold(csum))
-	if sum == 0 && proto == layers.IPProtocolUDP {
+	if sum == 0 && proto == IPProtocolUDP {
 		sum = 0xffff
 		sum = 0xffff
 	}
 	}
 	binary.BigEndian.PutUint16(transport[at:], sum)
 	binary.BigEndian.PutUint16(transport[at:], sum)

+ 7 - 0
iputil/packet.go

@@ -27,6 +27,13 @@ const (
 	maxIPv6RejectPacketSize = ipv6.HeaderLen + 8 + 1000
 	maxIPv6RejectPacketSize = ipv6.HeaderLen + 8 + 1000
 
 
 	MaxRejectPacketSize = maxIPv6RejectPacketSize
 	MaxRejectPacketSize = maxIPv6RejectPacketSize
+
+	IPProtocolICMP        = 1
+	IPProtocolICMPv6      = 58
+	IPProtocolTCP         = 6
+	IPProtocolUDP         = 17
+	ICMPv6TypeEchoRequest = 128
+	ICMPv6TypeEchoReply   = 129
 )
 )
 
 
 func CreateRejectPacket(packet []byte, out []byte) []byte {
 func CreateRejectPacket(packet []byte, out []byte) []byte {

+ 6 - 7
outside.go

@@ -8,7 +8,6 @@ import (
 	"net/netip"
 	"net/netip"
 	"time"
 	"time"
 
 
-	"github.com/google/gopacket/layers"
 	"golang.org/x/net/ipv6"
 	"golang.org/x/net/ipv6"
 
 
 	"github.com/slackhq/nebula/firewall"
 	"github.com/slackhq/nebula/firewall"
@@ -369,15 +368,15 @@ func parseV6(data []byte, incoming bool, fp *firewall.ParsedPacket) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	switch layers.IPProtocol(proto) {
-	case layers.IPProtocolICMPv6:
+	switch proto {
+	case iputil.IPProtocolICMPv6:
 		// An ICMPv6 message is at least type, code and checksum, 4 bytes. Only echo carries more than we read.
 		// An ICMPv6 message is at least type, code and checksum, 4 bytes. Only echo carries more than we read.
 		if dataLen < offset+4 {
 		if dataLen < offset+4 {
 			return ErrIPv6PacketTooShort
 			return ErrIPv6PacketTooShort
 		}
 		}
 		fp.LocalPort = 0      //incoming vs outgoing doesn't matter for icmpv6
 		fp.LocalPort = 0      //incoming vs outgoing doesn't matter for icmpv6
 		switch data[offset] { //icmp type
 		switch data[offset] { //icmp type
-		case layers.ICMPv6TypeEchoRequest, layers.ICMPv6TypeEchoReply:
+		case iputil.ICMPv6TypeEchoRequest, iputil.ICMPv6TypeEchoReply:
 			if dataLen < offset+6 {
 			if dataLen < offset+6 {
 				return ErrIPv6PacketTooShort
 				return ErrIPv6PacketTooShort
 			}
 			}
@@ -386,7 +385,7 @@ func parseV6(data []byte, incoming bool, fp *firewall.ParsedPacket) error {
 			fp.RemotePort = 0
 			fp.RemotePort = 0
 		}
 		}
 
 
-	case layers.IPProtocolTCP, layers.IPProtocolUDP:
+	case iputil.IPProtocolTCP, iputil.IPProtocolUDP:
 		if dataLen < offset+4 {
 		if dataLen < offset+4 {
 			return ErrIPv6PacketTooShort
 			return ErrIPv6PacketTooShort
 		}
 		}
@@ -435,7 +434,7 @@ func parseV4(data []byte, incoming bool, fp *firewall.ParsedPacket) error {
 	// Accounting for a variable header length, do we have enough data for our src/dst tuples?
 	// Accounting for a variable header length, do we have enough data for our src/dst tuples?
 	minLen := ihl
 	minLen := ihl
 	if !fp.Fragment {
 	if !fp.Fragment {
-		if fp.Protocol == firewall.ProtoICMP {
+		if fp.Protocol == iputil.IPProtocolICMP {
 			minLen += minFwPacketLen + 2
 			minLen += minFwPacketLen + 2
 		} else {
 		} else {
 			minLen += minFwPacketLen
 			minLen += minFwPacketLen
@@ -457,7 +456,7 @@ func parseV4(data []byte, incoming bool, fp *firewall.ParsedPacket) error {
 	if fp.Fragment {
 	if fp.Fragment {
 		fp.RemotePort = 0
 		fp.RemotePort = 0
 		fp.LocalPort = 0
 		fp.LocalPort = 0
-	} else if fp.Protocol == firewall.ProtoICMP { //note that orientation doesn't matter on ICMP
+	} else if fp.Protocol == iputil.IPProtocolICMP { //note that orientation doesn't matter on ICMP
 		fp.RemotePort = binary.BigEndian.Uint16(data[ihl+4 : ihl+6]) //identifier
 		fp.RemotePort = binary.BigEndian.Uint16(data[ihl+4 : ihl+6]) //identifier
 		fp.LocalPort = 0                                             //code would be uint16(data[ihl+1])
 		fp.LocalPort = 0                                             //code would be uint16(data[ihl+1])
 	} else if incoming {
 	} else if incoming {

+ 20 - 19
outside_test.go

@@ -9,6 +9,7 @@ import (
 
 
 	"github.com/google/gopacket"
 	"github.com/google/gopacket"
 	"github.com/google/gopacket/layers"
 	"github.com/google/gopacket/layers"
+	"github.com/slackhq/nebula/iputil"
 
 
 	"github.com/slackhq/nebula/firewall"
 	"github.com/slackhq/nebula/firewall"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/assert"
@@ -58,7 +59,7 @@ func Test_newPacket(t *testing.T) {
 		Src:      net.IPv4(10, 0, 0, 1),
 		Src:      net.IPv4(10, 0, 0, 1),
 		Dst:      net.IPv4(10, 0, 0, 2),
 		Dst:      net.IPv4(10, 0, 0, 2),
 		Options:  []byte{0, 1, 0, 2},
 		Options:  []byte{0, 1, 0, 2},
-		Protocol: firewall.ProtoTCP,
+		Protocol: iputil.IPProtocolTCP,
 	}
 	}
 
 
 	b, _ = h.Marshal()
 	b, _ = h.Marshal()
@@ -66,7 +67,7 @@ func Test_newPacket(t *testing.T) {
 	err = newPacket(b, true, p)
 	err = newPacket(b, true, p)
 
 
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoTCP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolTCP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("10.0.0.2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("10.0.0.2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("10.0.0.1"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("10.0.0.1"), p.RemoteAddr)
 	assert.Equal(t, uint16(3), p.RemotePort)
 	assert.Equal(t, uint16(3), p.RemotePort)
@@ -239,7 +240,7 @@ func Test_newPacket_v6(t *testing.T) {
 	// A good UDP packet
 	// A good UDP packet
 	ip = layers.IPv6{
 	ip = layers.IPv6{
 		Version:    6,
 		Version:    6,
-		NextHeader: firewall.ProtoUDP,
+		NextHeader: iputil.IPProtocolUDP,
 		HopLimit:   128,
 		HopLimit:   128,
 		SrcIP:      net.IPv6linklocalallrouters,
 		SrcIP:      net.IPv6linklocalallrouters,
 		DstIP:      net.IPv6linklocalallnodes,
 		DstIP:      net.IPv6linklocalallnodes,
@@ -262,7 +263,7 @@ func Test_newPacket_v6(t *testing.T) {
 	// incoming
 	// incoming
 	err = newPacket(b, true, p)
 	err = newPacket(b, true, p)
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoUDP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolUDP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, uint16(36123), p.RemotePort)
 	assert.Equal(t, uint16(36123), p.RemotePort)
@@ -272,7 +273,7 @@ func Test_newPacket_v6(t *testing.T) {
 	// outgoing
 	// outgoing
 	err = newPacket(b, false, p)
 	err = newPacket(b, false, p)
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoUDP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolUDP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.RemoteAddr)
 	assert.Equal(t, uint16(36123), p.LocalPort)
 	assert.Equal(t, uint16(36123), p.LocalPort)
@@ -289,7 +290,7 @@ func Test_newPacket_v6(t *testing.T) {
 	// incoming
 	// incoming
 	err = newPacket(b, true, p)
 	err = newPacket(b, true, p)
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoTCP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolTCP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, uint16(36123), p.RemotePort)
 	assert.Equal(t, uint16(36123), p.RemotePort)
@@ -299,7 +300,7 @@ func Test_newPacket_v6(t *testing.T) {
 	// outgoing
 	// outgoing
 	err = newPacket(b, false, p)
 	err = newPacket(b, false, p)
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoTCP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolTCP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.RemoteAddr)
 	assert.Equal(t, uint16(36123), p.LocalPort)
 	assert.Equal(t, uint16(36123), p.LocalPort)
@@ -344,7 +345,7 @@ func Test_newPacket_v6(t *testing.T) {
 
 
 	err = newPacket(b, true, p)
 	err = newPacket(b, true, p)
 	require.NoError(t, err)
 	require.NoError(t, err)
-	assert.Equal(t, uint8(firewall.ProtoUDP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolUDP), p.Protocol)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::2"), p.RemoteAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, netip.MustParseAddr("ff02::1"), p.LocalAddr)
 	assert.Equal(t, uint16(36123), p.RemotePort)
 	assert.Equal(t, uint16(36123), p.RemotePort)
@@ -678,7 +679,7 @@ func Test_newPacket_v6ExtHeaderOverflow(t *testing.T) {
 	pkt := make([]byte, realTCPAt+4)
 	pkt := make([]byte, realTCPAt+4)
 	pkt[0] = 0x60                                   // version 6
 	pkt[0] = 0x60                                   // version 6
 	pkt[6] = byte(layers.IPProtocolIPv6Destination) // NextHeader -> Destination Options
 	pkt[6] = byte(layers.IPProtocolIPv6Destination) // NextHeader -> Destination Options
-	pkt[40] = byte(firewall.ProtoTCP)               // Dest-Options NextHeader -> TCP
+	pkt[40] = byte(iputil.IPProtocolTCP)            // Dest-Options NextHeader -> TCP
 	pkt[41] = 255                                   // HdrExtLen = 255
 	pkt[41] = 255                                   // HdrExtLen = 255
 
 
 	// Forged transport header at the pre-fix (wrong) offset: dst port 443.
 	// Forged transport header at the pre-fix (wrong) offset: dst port 443.
@@ -687,7 +688,7 @@ func Test_newPacket_v6ExtHeaderOverflow(t *testing.T) {
 	binary.BigEndian.PutUint16(pkt[realTCPAt+2:realTCPAt+4], 22)
 	binary.BigEndian.PutUint16(pkt[realTCPAt+2:realTCPAt+4], 22)
 
 
 	require.NoError(t, newPacket(pkt, true, p))
 	require.NoError(t, newPacket(pkt, true, p))
-	assert.Equal(t, uint8(firewall.ProtoTCP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolTCP), p.Protocol)
 	// LocalPort is the destination port for incoming traffic. It must be the real port (22)
 	// LocalPort is the destination port for incoming traffic. It must be the real port (22)
 	// the host delivers to, not the forged 443 at the overflowed offset.
 	// the host delivers to, not the forged 443 at the overflowed offset.
 	assert.Equal(t, uint16(22), p.LocalPort, "firewall must parse the real transport header, not the overflowed offset")
 	assert.Equal(t, uint16(22), p.LocalPort, "firewall must parse the real transport header, not the overflowed offset")
@@ -766,7 +767,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	// Plain IPv4 TCP, IHL 20: L4 offset 20, no fragment shape.
 	// Plain IPv4 TCP, IHL 20: L4 offset 20, no fragment shape.
 	v4 := make([]byte, 28)
 	v4 := make([]byte, 28)
 	v4[0] = 0x45
 	v4[0] = 0x45
-	v4[9] = firewall.ProtoTCP
+	v4[9] = iputil.IPProtocolTCP
 	binary.BigEndian.PutUint16(v4[6:8], 0x4000) // DF only
 	binary.BigEndian.PutUint16(v4[6:8], 0x4000) // DF only
 	require.NoError(t, newPacket(v4, true, p))
 	require.NoError(t, newPacket(v4, true, p))
 	assert.Equal(t, 20, p.IPHdrLen)
 	assert.Equal(t, 20, p.IPHdrLen)
@@ -777,7 +778,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	// (Fragment false) but the coalescer must not touch it (FragAny true).
 	// (Fragment false) but the coalescer must not touch it (FragAny true).
 	ff := make([]byte, 28)
 	ff := make([]byte, 28)
 	ff[0] = 0x45
 	ff[0] = 0x45
-	ff[9] = firewall.ProtoUDP
+	ff[9] = iputil.IPProtocolUDP
 	binary.BigEndian.PutUint16(ff[6:8], 0x2000) // MF, offset 0
 	binary.BigEndian.PutUint16(ff[6:8], 0x2000) // MF, offset 0
 	require.NoError(t, newPacket(ff, true, p))
 	require.NoError(t, newPacket(ff, true, p))
 	assert.False(t, p.Fragment)
 	assert.False(t, p.Fragment)
@@ -787,7 +788,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	// IPv4 non-first fragment (nonzero offset): both flags set.
 	// IPv4 non-first fragment (nonzero offset): both flags set.
 	nf := make([]byte, 28)
 	nf := make([]byte, 28)
 	nf[0] = 0x45
 	nf[0] = 0x45
-	nf[9] = firewall.ProtoUDP
+	nf[9] = iputil.IPProtocolUDP
 	binary.BigEndian.PutUint16(nf[6:8], 0x00b9)
 	binary.BigEndian.PutUint16(nf[6:8], 0x00b9)
 	require.NoError(t, newPacket(nf, true, p))
 	require.NoError(t, newPacket(nf, true, p))
 	assert.True(t, p.Fragment)
 	assert.True(t, p.Fragment)
@@ -796,7 +797,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	// IPv4 with options (IHL 24): IPHdrLen tracks the real L4 offset.
 	// IPv4 with options (IHL 24): IPHdrLen tracks the real L4 offset.
 	opts := make([]byte, 32)
 	opts := make([]byte, 32)
 	opts[0] = 0x46
 	opts[0] = 0x46
-	opts[9] = firewall.ProtoTCP
+	opts[9] = iputil.IPProtocolTCP
 	binary.BigEndian.PutUint16(opts[6:8], 0x4000)
 	binary.BigEndian.PutUint16(opts[6:8], 0x4000)
 	require.NoError(t, newPacket(opts, true, p))
 	require.NoError(t, newPacket(opts, true, p))
 	assert.Equal(t, 24, p.IPHdrLen)
 	assert.Equal(t, 24, p.IPHdrLen)
@@ -805,7 +806,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	// Plain IPv6 TCP: L4 at 40.
 	// Plain IPv6 TCP: L4 at 40.
 	v6 := make([]byte, 60)
 	v6 := make([]byte, 60)
 	v6[0] = 0x60
 	v6[0] = 0x60
-	v6[6] = firewall.ProtoTCP
+	v6[6] = iputil.IPProtocolTCP
 	require.NoError(t, newPacket(v6, true, p))
 	require.NoError(t, newPacket(v6, true, p))
 	assert.Equal(t, 40, p.IPHdrLen)
 	assert.Equal(t, 40, p.IPHdrLen)
 	assert.False(t, p.FragAny)
 	assert.False(t, p.FragAny)
@@ -814,7 +815,7 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	hbh := make([]byte, 60)
 	hbh := make([]byte, 60)
 	hbh[0] = 0x60
 	hbh[0] = 0x60
 	hbh[6] = 0 // hop-by-hop
 	hbh[6] = 0 // hop-by-hop
-	hbh[40] = firewall.ProtoTCP
+	hbh[40] = iputil.IPProtocolTCP
 	hbh[41] = 0 // HdrExtLen 0 -> 8-byte header
 	hbh[41] = 0 // HdrExtLen 0 -> 8-byte header
 	require.NoError(t, newPacket(hbh, true, p))
 	require.NoError(t, newPacket(hbh, true, p))
 	assert.Equal(t, 48, p.IPHdrLen)
 	assert.Equal(t, 48, p.IPHdrLen)
@@ -824,17 +825,17 @@ func Test_newPacket_parsedFields(t *testing.T) {
 	f6 := make([]byte, 60)
 	f6 := make([]byte, 60)
 	f6[0] = 0x60
 	f6[0] = 0x60
 	f6[6] = 44 // fragment extension header
 	f6[6] = 44 // fragment extension header
-	f6[40] = firewall.ProtoUDP
+	f6[40] = iputil.IPProtocolUDP
 	require.NoError(t, newPacket(f6, true, p))
 	require.NoError(t, newPacket(f6, true, p))
 	assert.True(t, p.FragAny)
 	assert.True(t, p.FragAny)
 	assert.False(t, p.Fragment)
 	assert.False(t, p.Fragment)
-	assert.Equal(t, uint8(firewall.ProtoUDP), p.Protocol)
+	assert.Equal(t, uint8(iputil.IPProtocolUDP), p.Protocol)
 
 
 	// IPv6 non-first fragment: both set, walk stops at the fragment header.
 	// IPv6 non-first fragment: both set, walk stops at the fragment header.
 	f6n := make([]byte, 60)
 	f6n := make([]byte, 60)
 	f6n[0] = 0x60
 	f6n[0] = 0x60
 	f6n[6] = 44
 	f6n[6] = 44
-	f6n[40] = firewall.ProtoUDP
+	f6n[40] = iputil.IPProtocolUDP
 	binary.BigEndian.PutUint16(f6n[42:44], 0x0008)
 	binary.BigEndian.PutUint16(f6n[42:44], 0x0008)
 	require.NoError(t, newPacket(f6n, true, p))
 	require.NoError(t, newPacket(f6n, true, p))
 	assert.True(t, p.Fragment)
 	assert.True(t, p.Fragment)