Code cleaning in firewall package

This commit is contained in:
Zoltán Papp
2025-01-25 20:29:06 +01:00
parent 8185614362
commit efa8c17d27
42 changed files with 889 additions and 868 deletions
+22 -21
View File
@@ -13,7 +13,8 @@ import (
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
firewall "github.com/netbirdio/netbird/client/firewall/manager"
firewall "github.com/netbirdio/netbird/client/firewall/interface"
"github.com/netbirdio/netbird/client/firewall/types"
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
"github.com/netbirdio/netbird/client/iface"
"github.com/netbirdio/netbird/client/iface/device"
@@ -46,7 +47,7 @@ type Manager struct {
wgNetwork *net.IPNet
decoders sync.Pool
wgIface IFaceMapper
nativeFirewall firewall.Manager
nativeFirewall firewall.Firewall
mutex sync.RWMutex
@@ -74,7 +75,7 @@ func Create(iface IFaceMapper) (*Manager, error) {
return create(iface)
}
func CreateWithNativeFirewall(iface IFaceMapper, nativeFirewall firewall.Manager) (*Manager, error) {
func CreateWithNativeFirewall(iface IFaceMapper, nativeFirewall firewall.Firewall) (*Manager, error) {
mgr, err := create(iface)
if err != nil {
return nil, err
@@ -134,7 +135,7 @@ func (m *Manager) IsServerRouteSupported() bool {
}
}
func (m *Manager) AddNatRule(pair firewall.RouterPair) error {
func (m *Manager) AddNatRule(pair types.RouterPair) error {
if m.nativeFirewall == nil {
return errRouteNotSupported
}
@@ -142,7 +143,7 @@ func (m *Manager) AddNatRule(pair firewall.RouterPair) error {
}
// RemoveNatRule removes a routing firewall rule
func (m *Manager) RemoveNatRule(pair firewall.RouterPair) error {
func (m *Manager) RemoveNatRule(pair types.RouterPair) error {
if m.nativeFirewall == nil {
return errRouteNotSupported
}
@@ -155,19 +156,19 @@ func (m *Manager) RemoveNatRule(pair firewall.RouterPair) error {
// rule ID as comment for the rule
func (m *Manager) AddPeerFiltering(
ip net.IP,
proto firewall.Protocol,
sPort *firewall.Port,
dPort *firewall.Port,
action firewall.Action,
proto types.Protocol,
sPort *types.Port,
dPort *types.Port,
action types.Action,
_ string,
comment string,
) ([]firewall.Rule, error) {
) ([]types.Rule, error) {
r := Rule{
id: uuid.New().String(),
ip: ip,
ipLayer: layers.LayerTypeIPv6,
matchByIP: true,
drop: action == firewall.ActionDrop,
drop: action == types.ActionDrop,
comment: comment,
}
if ipNormalized := ip.To4(); ipNormalized != nil {
@@ -188,16 +189,16 @@ func (m *Manager) AddPeerFiltering(
}
switch proto {
case firewall.ProtocolTCP:
case types.ProtocolTCP:
r.protoLayer = layers.LayerTypeTCP
case firewall.ProtocolUDP:
case types.ProtocolUDP:
r.protoLayer = layers.LayerTypeUDP
case firewall.ProtocolICMP:
case types.ProtocolICMP:
r.protoLayer = layers.LayerTypeICMPv4
if r.ipLayer == layers.LayerTypeIPv6 {
r.protoLayer = layers.LayerTypeICMPv6
}
case firewall.ProtocolALL:
case types.ProtocolALL:
r.protoLayer = layerTypeAll
}
@@ -207,17 +208,17 @@ func (m *Manager) AddPeerFiltering(
}
m.incomingRules[r.ip.String()][r.id] = r
m.mutex.Unlock()
return []firewall.Rule{&r}, nil
return []types.Rule{&r}, nil
}
func (m *Manager) AddRouteFiltering(sources []netip.Prefix, destination netip.Prefix, proto firewall.Protocol, sPort *firewall.Port, dPort *firewall.Port, action firewall.Action) (firewall.Rule, error) {
func (m *Manager) AddRouteFiltering(sources []netip.Prefix, destination netip.Prefix, proto types.Protocol, sPort *types.Port, dPort *types.Port, action types.Action) (types.Rule, error) {
if m.nativeFirewall == nil {
return nil, errRouteNotSupported
}
return m.nativeFirewall.AddRouteFiltering(sources, destination, proto, sPort, dPort, action)
}
func (m *Manager) DeleteRouteRule(rule firewall.Rule) error {
func (m *Manager) DeleteRouteRule(rule types.Rule) error {
if m.nativeFirewall == nil {
return errRouteNotSupported
}
@@ -225,7 +226,7 @@ func (m *Manager) DeleteRouteRule(rule firewall.Rule) error {
}
// DeletePeerRule from the firewall by rule definition
func (m *Manager) DeletePeerRule(rule firewall.Rule) error {
func (m *Manager) DeletePeerRule(rule types.Rule) error {
m.mutex.Lock()
defer m.mutex.Unlock()
@@ -254,12 +255,12 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
func (m *Manager) Flush() error { return nil }
// AddDNATRule adds a DNAT rule
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
func (m *Manager) AddDNATRule(rule types.ForwardRule) (types.Rule, error) {
return nil, fmt.Errorf("not implemented")
}
// DeleteDNATRule deletes a DNAT rule
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
func (m *Manager) DeleteDNATRule(rule types.Rule) error {
return nil
}
@@ -12,7 +12,7 @@ import (
"github.com/google/gopacket/layers"
"github.com/stretchr/testify/require"
fw "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/firewall/types"
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
"github.com/netbirdio/netbird/client/iface/device"
)
@@ -90,8 +90,8 @@ func BenchmarkCoreFiltering(b *testing.B) {
stateful: false,
setupFunc: func(m *Manager) {
// Single rule allowing all traffic
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolALL, nil, nil,
fw.ActionAccept, "", "allow all")
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolALL, nil, nil,
types.ActionAccept, "", "allow all")
require.NoError(b, err)
},
desc: "Baseline: Single 'allow all' rule without connection tracking",
@@ -111,10 +111,10 @@ func BenchmarkCoreFiltering(b *testing.B) {
// Add explicit rules matching return traffic pattern
for i := 0; i < 1000; i++ { // Simulate realistic ruleset size
ip := generateRandomIPs(1)[0]
_, err := m.AddPeerFiltering(ip, fw.ProtocolTCP,
&fw.Port{Values: []int{1024 + i}},
&fw.Port{Values: []int{80}},
fw.ActionAccept, "", "explicit return")
_, err := m.AddPeerFiltering(ip, types.ProtocolTCP,
&types.Port{Values: []int{1024 + i}},
&types.Port{Values: []int{80}},
types.ActionAccept, "", "explicit return")
require.NoError(b, err)
}
},
@@ -125,8 +125,8 @@ func BenchmarkCoreFiltering(b *testing.B) {
stateful: true,
setupFunc: func(m *Manager) {
// Add some basic rules but rely on state for established connections
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP, nil, nil,
fw.ActionDrop, "", "default drop")
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP, nil, nil,
types.ActionDrop, "", "default drop")
require.NoError(b, err)
},
desc: "Connection tracking with established connections",
@@ -587,10 +587,10 @@ func BenchmarkLongLivedConnections(b *testing.B) {
// Setup initial state based on scenario
if sc.rules {
// Single rule to allow all return traffic from port 80
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
&fw.Port{Values: []int{80}},
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
&types.Port{Values: []int{80}},
nil,
fw.ActionAccept, "", "return traffic")
types.ActionAccept, "", "return traffic")
require.NoError(b, err)
}
@@ -678,10 +678,10 @@ func BenchmarkShortLivedConnections(b *testing.B) {
// Setup initial state based on scenario
if sc.rules {
// Single rule to allow all return traffic from port 80
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
&fw.Port{Values: []int{80}},
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
&types.Port{Values: []int{80}},
nil,
fw.ActionAccept, "", "return traffic")
types.ActionAccept, "", "return traffic")
require.NoError(b, err)
}
@@ -796,10 +796,10 @@ func BenchmarkParallelLongLivedConnections(b *testing.B) {
// Setup initial state based on scenario
if sc.rules {
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
&fw.Port{Values: []int{80}},
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
&types.Port{Values: []int{80}},
nil,
fw.ActionAccept, "", "return traffic")
types.ActionAccept, "", "return traffic")
require.NoError(b, err)
}
@@ -883,10 +883,10 @@ func BenchmarkParallelShortLivedConnections(b *testing.B) {
})
if sc.rules {
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
&fw.Port{Values: []int{80}},
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
&types.Port{Values: []int{80}},
nil,
fw.ActionAccept, "", "return traffic")
types.ActionAccept, "", "return traffic")
require.NoError(b, err)
}
+26 -26
View File
@@ -11,7 +11,7 @@ import (
"github.com/google/gopacket/layers"
"github.com/stretchr/testify/require"
fw "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/firewall/types"
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
"github.com/netbirdio/netbird/client/iface"
"github.com/netbirdio/netbird/client/iface/device"
@@ -43,12 +43,12 @@ func TestManagerCreate(t *testing.T) {
m, err := Create(ifaceMock)
if err != nil {
t.Errorf("failed to create Manager: %v", err)
t.Errorf("failed to create Firewall: %v", err)
return
}
if m == nil {
t.Error("Manager is nil")
t.Error("Firewall is nil")
}
}
@@ -63,14 +63,14 @@ func TestManagerAddPeerFiltering(t *testing.T) {
m, err := Create(ifaceMock)
if err != nil {
t.Errorf("failed to create Manager: %v", err)
t.Errorf("failed to create Firewall: %v", err)
return
}
ip := net.ParseIP("192.168.1.1")
proto := fw.ProtocolTCP
port := &fw.Port{Values: []int{80}}
action := fw.ActionDrop
proto := types.ProtocolTCP
port := &types.Port{Values: []int{80}}
action := types.ActionDrop
comment := "Test rule"
rule, err := m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
@@ -97,14 +97,14 @@ func TestManagerDeleteRule(t *testing.T) {
m, err := Create(ifaceMock)
if err != nil {
t.Errorf("failed to create Manager: %v", err)
t.Errorf("failed to create Firewall: %v", err)
return
}
ip := net.ParseIP("192.168.1.1")
proto := fw.ProtocolTCP
port := &fw.Port{Values: []int{80}}
action := fw.ActionDrop
proto := types.ProtocolTCP
port := &types.Port{Values: []int{80}}
action := types.ActionDrop
comment := "Test rule 2"
rule2, err := m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
@@ -138,7 +138,7 @@ func TestAddUDPPacketHook(t *testing.T) {
tests := []struct {
name string
in bool
expDir fw.RuleDirection
expDir types.RuleDirection
ip net.IP
dPort uint16
hook func([]byte) bool
@@ -147,7 +147,7 @@ func TestAddUDPPacketHook(t *testing.T) {
{
name: "Test Outgoing UDP Packet Hook",
in: false,
expDir: fw.RuleDirectionOUT,
expDir: types.RuleDirectionOUT,
ip: net.IPv4(10, 168, 0, 1),
dPort: 8000,
hook: func([]byte) bool { return true },
@@ -155,7 +155,7 @@ func TestAddUDPPacketHook(t *testing.T) {
{
name: "Test Incoming UDP Packet Hook",
in: true,
expDir: fw.RuleDirectionIN,
expDir: types.RuleDirectionIN,
ip: net.IPv6loopback,
dPort: 9000,
hook: func([]byte) bool { return false },
@@ -217,14 +217,14 @@ func TestManagerReset(t *testing.T) {
m, err := Create(ifaceMock)
if err != nil {
t.Errorf("failed to create Manager: %v", err)
t.Errorf("failed to create Firewall: %v", err)
return
}
ip := net.ParseIP("192.168.1.1")
proto := fw.ProtocolTCP
port := &fw.Port{Values: []int{80}}
action := fw.ActionDrop
proto := types.ProtocolTCP
port := &types.Port{Values: []int{80}}
action := types.ActionDrop
comment := "Test rule"
_, err = m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
@@ -235,7 +235,7 @@ func TestManagerReset(t *testing.T) {
err = m.Reset(nil)
if err != nil {
t.Errorf("failed to reset Manager: %v", err)
t.Errorf("failed to reset Firewall: %v", err)
return
}
@@ -251,7 +251,7 @@ func TestNotMatchByIP(t *testing.T) {
m, err := Create(ifaceMock)
if err != nil {
t.Errorf("failed to create Manager: %v", err)
t.Errorf("failed to create Firewall: %v", err)
return
}
m.wgNetwork = &net.IPNet{
@@ -260,8 +260,8 @@ func TestNotMatchByIP(t *testing.T) {
}
ip := net.ParseIP("0.0.0.0")
proto := fw.ProtocolUDP
action := fw.ActionAccept
proto := types.ProtocolUDP
action := types.ActionAccept
comment := "Test rule"
_, err = m.AddPeerFiltering(ip, proto, nil, nil, action, "", comment)
@@ -304,7 +304,7 @@ func TestNotMatchByIP(t *testing.T) {
}
if err = m.Reset(nil); err != nil {
t.Errorf("failed to reset Manager: %v", err)
t.Errorf("failed to reset Firewall: %v", err)
return
}
}
@@ -319,7 +319,7 @@ func TestRemovePacketHook(t *testing.T) {
// creating manager instance
manager, err := Create(iface)
if err != nil {
t.Fatalf("Failed to create Manager: %s", err)
t.Fatalf("Failed to create Firewall: %s", err)
}
defer func() {
require.NoError(t, manager.Reset(nil))
@@ -463,8 +463,8 @@ func TestUSPFilterCreatePerformance(t *testing.T) {
ip := net.ParseIP("10.20.0.100")
start := time.Now()
for i := 0; i < testMax; i++ {
port := &fw.Port{Values: []int{1000 + i}}
_, err = manager.AddPeerFiltering(ip, "tcp", nil, port, fw.ActionAccept, "", "accept HTTP traffic")
port := &types.Port{Values: []int{1000 + i}}
_, err = manager.AddPeerFiltering(ip, "tcp", nil, port, types.ActionAccept, "", "accept HTTP traffic")
require.NoError(t, err, "failed to add rule")
}