Repository: netbirdio/netbird

Issue:
Implement BROWSER env variable
Netbird cli (in Linux at least) doen't support BROWSER env variable. It always opens the verification url with the default browser.

I'd like to be able to specify a the env variable to chose which browser to use, for example ```BROWSER=/usr/bin/google-chrome netbird up```.

Hints from issue comments:
@nazarewk: while not a direct fulfillment we have recently added a `--no-browser` flag to the `netbird up` command:
```
      --no-browser                      do not open the browser for SSO login
```
https://github.com/netbirdio/netbird/pull/3610

Solution patch:
diff --git a/client/cmd/login.go b/client/cmd/login.go
index 3ac21180..40b55f85 100644
--- a/client/cmd/login.go
+++ b/client/cmd/login.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"os"
+	"os/exec"
 	"os/user"
 	"runtime"
 	"strings"
@@ -356,13 +357,21 @@ func openURL(cmd *cobra.Command, verificationURIComplete, userCode string, noBro
 	cmd.Println("")
 
 	if !noBrowser {
-		if err := open.Run(verificationURIComplete); err != nil {
+		if err := openBrowser(verificationURIComplete); err != nil {
 			cmd.Println("\nAlternatively, you may want to use a setup key, see:\n\n" +
 				"https://docs.netbird.io/how-to/register-machines-using-setup-keys")
 		}
 	}
 }
 
+// openBrowser opens the URL in a browser, respecting the BROWSER environment variable.
+func openBrowser(url string) error {
+	if browser := os.Getenv("BROWSER"); browser != "" {
+		return exec.Command(browser, url).Start()
+	}
+	return open.Run(url)
+}
+
 // isUnixRunningDesktop checks if a Linux OS is running desktop environment
 func isUnixRunningDesktop() bool {
 	if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
diff --git a/client/firewall/iptables/acl_linux.go b/client/firewall/iptables/acl_linux.go
index ed8a7403..d78372c9 100644
--- a/client/firewall/iptables/acl_linux.go
+++ b/client/firewall/iptables/acl_linux.go
@@ -400,7 +400,6 @@ func transformIPsetName(ipsetName string, sPort, dPort *firewall.Port, action fi
 		return ""
 	}
 
-	// Include action in the ipset name to prevent squashing rules with different actions
 	actionSuffix := ""
 	if action == firewall.ActionDrop {
 		actionSuffix = "-drop"
diff --git a/client/internal/acl/manager.go b/client/internal/acl/manager.go
index 5ca95029..965decc7 100644
--- a/client/internal/acl/manager.go
+++ b/client/internal/acl/manager.go
@@ -29,11 +29,6 @@ type Manager interface {
 	ApplyFiltering(networkMap *mgmProto.NetworkMap, dnsRouteFeatureFlag bool)
 }
 
-type protoMatch struct {
-	ips      map[string]int
-	policyID []byte
-}
-
 // DefaultManager uses firewall manager to handle
 type DefaultManager struct {
 	firewall       firewall.Manager
@@ -86,21 +81,14 @@ func (d *DefaultManager) ApplyFiltering(networkMap *mgmProto.NetworkMap, dnsRout
 }
 
 func (d *DefaultManager) applyPeerACLs(networkMap *mgmProto.NetworkMap) {
-	rules, squashedProtocols := d.squashAcceptRules(networkMap)
+	rules := networkMap.FirewallRules
 
 	enableSSH := networkMap.PeerConfig != nil &&
 		networkMap.PeerConfig.SshConfig != nil &&
 		networkMap.PeerConfig.SshConfig.SshEnabled
-	if _, ok := squashedProtocols[mgmProto.RuleProtocol_ALL]; ok {
-		enableSSH = enableSSH && !ok
-	}
-	if _, ok := squashedProtocols[mgmProto.RuleProtocol_TCP]; ok {
-		enableSSH = enableSSH && !ok
-	}
 
-	// if TCP protocol rules not squashed and SSH enabled
-	// we add default firewall rule which accepts connection to any peer
-	// in the network by SSH (TCP 22 port).
+	// If SSH enabled, add default firewall rule which accepts connection to any peer
+	// in the network by SSH (TCP port defined by ssh.DefaultSSHPort).
 	if enableSSH {
 		rules = append(rules, &mgmProto.FirewallRule{
 			PeerIP:    "0.0.0.0",
@@ -368,145 +356,6 @@ func (d *DefaultManager) getPeerRuleID(
 	return id.RuleID(hex.EncodeToString(md5.New().Sum([]byte(idStr))))
 }
 
-// squashAcceptRules does complex logic to convert many rules which allows connection by traffic type
-// to all peers in the network map to one rule which just accepts that type of the traffic.
-//
-// NOTE: It will not squash two rules for same protocol if one covers all peers in the network,
-// but other has port definitions or has drop policy.
-func (d *DefaultManager) squashAcceptRules(
-	networkMap *mgmProto.NetworkMap,
-) ([]*mgmProto.FirewallRule, map[mgmProto.RuleProtocol]struct{}) {
-	totalIPs := 0
-	for _, p := range append(networkMap.RemotePeers, networkMap.OfflinePeers...) {
-		for range p.AllowedIps {
-			totalIPs++
-		}
-	}
-
-	in := map[mgmProto.RuleProtocol]*protoMatch{}
-	out := map[mgmProto.RuleProtocol]*protoMatch{}
-
-	// trace which type of protocols was squashed
-	squashedRules := []*mgmProto.FirewallRule{}
-	squashedProtocols := map[mgmProto.RuleProtocol]struct{}{}
-
-	// this function we use to do calculation, can we squash the rules by protocol or not.
-	// We summ amount of Peers IP for given protocol we found in original rules list.
-	// But we zeroed the IP's for protocol if:
-	// 1. Any of the rule has DROP action type.
-	// 2. Any of rule contains Port.
-	//
-	// We zeroed this to notify squash function that this protocol can't be squashed.
-	addRuleToCalculationMap := func(i int, r *mgmProto.FirewallRule, protocols map[mgmProto.RuleProtocol]*protoMatch) {
-		hasPortRestrictions := r.Action == mgmProto.RuleAction_DROP ||
-			r.Port != "" || !portInfoEmpty(r.PortInfo)
-
-		if hasPortRestrictions {
-			// Don't squash rules with port restrictions
-			protocols[r.Protocol] = &protoMatch{ips: map[string]int{}}
-			return
-		}
-
-		if _, ok := protocols[r.Protocol]; !ok {
-			protocols[r.Protocol] = &protoMatch{
-				ips: map[string]int{},
-				// store the first encountered PolicyID for this protocol
-				policyID: r.PolicyID,
-			}
-		}
-
-		// special case, when we receive this all network IP address
-		// it means that rules for that protocol was already optimized on the
-		// management side
-		if r.PeerIP == "0.0.0.0" {
-			squashedRules = append(squashedRules, r)
-			squashedProtocols[r.Protocol] = struct{}{}
-			return
-		}
-
-		ipset := protocols[r.Protocol].ips
-
-		if _, ok := ipset[r.PeerIP]; ok {
-			return
-		}
-		ipset[r.PeerIP] = i
-	}
-
-	for i, r := range networkMap.FirewallRules {
-		// calculate squash for different directions
-		if r.Direction == mgmProto.RuleDirection_IN {
-			addRuleToCalculationMap(i, r, in)
-		} else {
-			addRuleToCalculationMap(i, r, out)
-		}
-	}
-
-	// order of squashing by protocol is important
-	// only for their first element ALL, it must be done first
-	protocolOrders := []mgmProto.RuleProtocol{
-		mgmProto.RuleProtocol_ALL,
-		mgmProto.RuleProtocol_ICMP,
-		mgmProto.RuleProtocol_TCP,
-		mgmProto.RuleProtocol_UDP,
-	}
-
-	squash := func(matches map[mgmProto.RuleProtocol]*protoMatch, direction mgmProto.RuleDirection) {
-		for _, protocol := range protocolOrders {
-			match, ok := matches[protocol]
-			if !ok || len(match.ips) != totalIPs || len(match.ips) < 2 {
-				// don't squash if :
-				// 1. Rules not cover all peers in the network
-				// 2. Rules cover only one peer in the network.
-				continue
-			}
-
-			// add special rule 0.0.0.0 which allows all IP's in our firewall implementations
-			squashedRules = append(squashedRules, &mgmProto.FirewallRule{
-				PeerIP:    "0.0.0.0",
-				Direction: direction,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  protocol,
-				PolicyID:  match.policyID,
-			})
-			squashedProtocols[protocol] = struct{}{}
-
-			if protocol == mgmProto.RuleProtocol_ALL {
-				// if we have ALL traffic type squashed rule
-				// it allows all other type of traffic, so we can stop processing
-				break
-			}
-		}
-	}
-
-	squash(in, mgmProto.RuleDirection_IN)
-	squash(out, mgmProto.RuleDirection_OUT)
-
-	// if all protocol was squashed everything is allow and we can ignore all other rules
-	if _, ok := squashedProtocols[mgmProto.RuleProtocol_ALL]; ok {
-		return squashedRules, squashedProtocols
-	}
-
-	if len(squashedRules) == 0 {
-		return networkMap.FirewallRules, squashedProtocols
-	}
-
-	var rules []*mgmProto.FirewallRule
-	// filter out rules which was squashed from final list
-	// if we also have other not squashed rules.
-	for i, r := range networkMap.FirewallRules {
-		if _, ok := squashedProtocols[r.Protocol]; ok {
-			if m, ok := in[r.Protocol]; ok && m.ips[r.PeerIP] == i {
-				continue
-			} else if m, ok := out[r.Protocol]; ok && m.ips[r.PeerIP] == i {
-				continue
-			}
-		}
-		rules = append(rules, r)
-	}
-
-	return append(rules, squashedRules...), squashedProtocols
-}
-
 // getRuleGroupingSelector takes all rule properties except IP address to build selector
 func (d *DefaultManager) getRuleGroupingSelector(rule *mgmProto.FirewallRule) string {
 	return fmt.Sprintf("%v:%v:%v:%s:%v", strconv.Itoa(int(rule.Direction)), rule.Action, rule.Protocol, rule.Port, rule.PortInfo)
diff --git a/client/ui/client_ui.go b/client/ui/client_ui.go
index 7c2000a9..0043f228 100644
--- a/client/ui/client_ui.go
+++ b/client/ui/client_ui.go
@@ -31,7 +31,6 @@ import (
 	"fyne.io/systray"
 	"github.com/cenkalti/backoff/v4"
 	log "github.com/sirupsen/logrus"
-	"github.com/skratchdot/open-golang/open"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
@@ -633,7 +632,7 @@ func (s *serviceClient) login(openURL bool) (*proto.LoginResponse, error) {
 }
 
 func (s *serviceClient) handleSSOLogin(loginResp *proto.LoginResponse, conn proto.DaemonServiceClient) error {
-	err := open.Run(loginResp.VerificationURIComplete)
+	err := openURL(loginResp.VerificationURIComplete)
 	if err != nil {
 		log.Errorf("opening the verification uri in the browser failed: %v", err)
 		return err
@@ -1487,6 +1486,10 @@ func (s *serviceClient) showLoginURL() context.CancelFunc {
 }
 
 func openURL(url string) error {
+	if browser := os.Getenv("BROWSER"); browser != "" {
+		return exec.Command(browser, url).Start()
+	}
+
 	var err error
 	switch runtime.GOOS {
 	case "windows":



Test patch:
diff --git a/client/internal/acl/manager_test.go b/client/internal/acl/manager_test.go
index 664476ef..daf4979c 100644
--- a/client/internal/acl/manager_test.go
+++ b/client/internal/acl/manager_test.go
@@ -188,492 +188,6 @@ func TestDefaultManagerStateless(t *testing.T) {
 	})
 }
 
-func TestDefaultManagerSquashRules(t *testing.T) {
-	networkMap := &mgmProto.NetworkMap{
-		RemotePeers: []*mgmProto.RemotePeerConfig{
-			{AllowedIps: []string{"10.93.0.1"}},
-			{AllowedIps: []string{"10.93.0.2"}},
-			{AllowedIps: []string{"10.93.0.3"}},
-			{AllowedIps: []string{"10.93.0.4"}},
-		},
-		FirewallRules: []*mgmProto.FirewallRule{
-			{
-				PeerIP:    "10.93.0.1",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.2",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.3",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.4",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.1",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.2",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.3",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.4",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-		},
-	}
-
-	manager := &DefaultManager{}
-	rules, _ := manager.squashAcceptRules(networkMap)
-	assert.Equal(t, 2, len(rules))
-
-	r := rules[0]
-	assert.Equal(t, "0.0.0.0", r.PeerIP)
-	assert.Equal(t, mgmProto.RuleDirection_IN, r.Direction)
-	assert.Equal(t, mgmProto.RuleProtocol_ALL, r.Protocol)
-	assert.Equal(t, mgmProto.RuleAction_ACCEPT, r.Action)
-
-	r = rules[1]
-	assert.Equal(t, "0.0.0.0", r.PeerIP)
-	assert.Equal(t, mgmProto.RuleDirection_OUT, r.Direction)
-	assert.Equal(t, mgmProto.RuleProtocol_ALL, r.Protocol)
-	assert.Equal(t, mgmProto.RuleAction_ACCEPT, r.Action)
-}
-
-func TestDefaultManagerSquashRulesNoAffect(t *testing.T) {
-	networkMap := &mgmProto.NetworkMap{
-		RemotePeers: []*mgmProto.RemotePeerConfig{
-			{AllowedIps: []string{"10.93.0.1"}},
-			{AllowedIps: []string{"10.93.0.2"}},
-			{AllowedIps: []string{"10.93.0.3"}},
-			{AllowedIps: []string{"10.93.0.4"}},
-		},
-		FirewallRules: []*mgmProto.FirewallRule{
-			{
-				PeerIP:    "10.93.0.1",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.2",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.3",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.4",
-				Direction: mgmProto.RuleDirection_IN,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_TCP,
-			},
-			{
-				PeerIP:    "10.93.0.1",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.2",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.3",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_ALL,
-			},
-			{
-				PeerIP:    "10.93.0.4",
-				Direction: mgmProto.RuleDirection_OUT,
-				Action:    mgmProto.RuleAction_ACCEPT,
-				Protocol:  mgmProto.RuleProtocol_UDP,
-			},
-		},
-	}
-
-	manager := &DefaultManager{}
-	rules, _ := manager.squashAcceptRules(networkMap)
-	assert.Equal(t, len(networkMap.FirewallRules), len(rules))
-}
-
-func TestDefaultManagerSquashRulesWithPortRestrictions(t *testing.T) {
-	tests := []struct {
-		name          string
-		rules         []*mgmProto.FirewallRule
-		expectedCount int
-		description   string
-	}{
-		{
-			name: "should not squash rules with port ranges",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Range_{
-							Range: &mgmProto.PortInfo_Range{
-								Start: 8080,
-								End:   8090,
-							},
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Range_{
-							Range: &mgmProto.PortInfo_Range{
-								Start: 8080,
-								End:   8090,
-							},
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Range_{
-							Range: &mgmProto.PortInfo_Range{
-								Start: 8080,
-								End:   8090,
-							},
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Range_{
-							Range: &mgmProto.PortInfo_Range{
-								Start: 8080,
-								End:   8090,
-							},
-						},
-					},
-				},
-			},
-			expectedCount: 4,
-			description:   "Rules with port ranges should not be squashed even if they cover all peers",
-		},
-		{
-			name: "should not squash rules with specific ports",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Port{
-							Port: 80,
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Port{
-							Port: 80,
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Port{
-							Port: 80,
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Port{
-							Port: 80,
-						},
-					},
-				},
-			},
-			expectedCount: 4,
-			description:   "Rules with specific ports should not be squashed even if they cover all peers",
-		},
-		{
-			name: "should not squash rules with legacy port field",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-			},
-			expectedCount: 4,
-			description:   "Rules with legacy port field should not be squashed",
-		},
-		{
-			name: "should not squash rules with DROP action",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_DROP,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_DROP,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_DROP,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_DROP,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-			},
-			expectedCount: 4,
-			description:   "Rules with DROP action should not be squashed",
-		},
-		{
-			name: "should squash rules without port restrictions",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-			},
-			expectedCount: 1,
-			description:   "Rules without port restrictions should be squashed into a single 0.0.0.0 rule",
-		},
-		{
-			name: "mixed rules should not squash protocol with port restrictions",
-			rules: []*mgmProto.FirewallRule{
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					PortInfo: &mgmProto.PortInfo{
-						PortSelection: &mgmProto.PortInfo_Port{
-							Port: 80,
-						},
-					},
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-				},
-			},
-			expectedCount: 4,
-			description:   "TCP should not be squashed because one rule has port restrictions",
-		},
-		{
-			name: "should squash UDP but not TCP when TCP has port restrictions",
-			rules: []*mgmProto.FirewallRule{
-				// TCP rules with port restrictions - should NOT be squashed
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_TCP,
-					Port:      "443",
-				},
-				// UDP rules without port restrictions - SHOULD be squashed
-				{
-					PeerIP:    "10.93.0.1",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_UDP,
-				},
-				{
-					PeerIP:    "10.93.0.2",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_UDP,
-				},
-				{
-					PeerIP:    "10.93.0.3",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_UDP,
-				},
-				{
-					PeerIP:    "10.93.0.4",
-					Direction: mgmProto.RuleDirection_IN,
-					Action:    mgmProto.RuleAction_ACCEPT,
-					Protocol:  mgmProto.RuleProtocol_UDP,
-				},
-			},
-			expectedCount: 5, // 4 TCP rules + 1 squashed UDP rule (0.0.0.0)
-			description:   "UDP should be squashed to 0.0.0.0 rule, but TCP should remain as individual rules due to port restrictions",
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			networkMap := &mgmProto.NetworkMap{
-				RemotePeers: []*mgmProto.RemotePeerConfig{
-					{AllowedIps: []string{"10.93.0.1"}},
-					{AllowedIps: []string{"10.93.0.2"}},
-					{AllowedIps: []string{"10.93.0.3"}},
-					{AllowedIps: []string{"10.93.0.4"}},
-				},
-				FirewallRules: tt.rules,
-			}
-
-			manager := &DefaultManager{}
-			rules, _ := manager.squashAcceptRules(networkMap)
-
-			assert.Equal(t, tt.expectedCount, len(rules), tt.description)
-
-			// For squashed rules, verify we get the expected 0.0.0.0 rule
-			if tt.expectedCount == 1 {
-				assert.Equal(t, "0.0.0.0", rules[0].PeerIP)
-				assert.Equal(t, mgmProto.RuleDirection_IN, rules[0].Direction)
-				assert.Equal(t, mgmProto.RuleAction_ACCEPT, rules[0].Action)
-			}
-		})
-	}
-}
-
 func TestPortInfoEmpty(t *testing.T) {
 	tests := []struct {
 		name     string