mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-07 05:59:06 +02:00
[management] remove ingress ports (#8062)
This commit is contained in:
@@ -42,7 +42,6 @@ import (
|
||||
dnsconfig "github.com/netbirdio/netbird/client/internal/dns/config"
|
||||
"github.com/netbirdio/netbird/client/internal/dnsfwd"
|
||||
"github.com/netbirdio/netbird/client/internal/expose"
|
||||
"github.com/netbirdio/netbird/client/internal/ingressgw"
|
||||
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
||||
"github.com/netbirdio/netbird/client/internal/metrics"
|
||||
"github.com/netbirdio/netbird/client/internal/netflow"
|
||||
@@ -262,11 +261,10 @@ type Engine struct {
|
||||
|
||||
statusRecorder *peer.Status
|
||||
|
||||
firewall firewallManager.Manager
|
||||
routeManager routemanager.Manager
|
||||
acl acl.Manager
|
||||
dnsForwardMgr *dnsfwd.Manager
|
||||
ingressGatewayMgr *ingressgw.Manager
|
||||
firewall firewallManager.Manager
|
||||
routeManager routemanager.Manager
|
||||
acl acl.Manager
|
||||
dnsForwardMgr *dnsfwd.Manager
|
||||
|
||||
dnsServer dns.Server
|
||||
|
||||
@@ -448,13 +446,6 @@ func (e *Engine) stopLocked() {
|
||||
|
||||
e.cleanupSSHConfig()
|
||||
|
||||
if e.ingressGatewayMgr != nil {
|
||||
if err := e.ingressGatewayMgr.Close(); err != nil {
|
||||
log.Warnf("failed to cleanup forward rules: %v", err)
|
||||
}
|
||||
e.ingressGatewayMgr = nil
|
||||
}
|
||||
|
||||
if e.srWatcher != nil {
|
||||
e.srWatcher.Close()
|
||||
}
|
||||
@@ -1627,13 +1618,6 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
|
||||
e.updateDNSForwarder(dnsRouteFeatureFlag, fwdEntries)
|
||||
done()
|
||||
|
||||
// Ingress forward rules
|
||||
done = e.phase("forward_rules")
|
||||
if _, err := e.updateForwardRules(networkMap.GetForwardingRules()); err != nil {
|
||||
log.Errorf("failed to update forward rules, err: %v", err)
|
||||
}
|
||||
done()
|
||||
|
||||
log.Debugf("got peers update from Management Service, total peers to connect to = %d", len(networkMap.GetRemotePeers()))
|
||||
|
||||
done = e.phase("offline_peers")
|
||||
@@ -2733,74 +2717,6 @@ func (e *Engine) setForwarderCapture(pc device.PacketCapture) {
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Engine) updateForwardRules(rules []*mgmProto.ForwardingRule) ([]firewallManager.ForwardRule, error) {
|
||||
if e.firewall == nil {
|
||||
log.Warn("firewall is disabled, not updating forwarding rules")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(rules) == 0 {
|
||||
if e.ingressGatewayMgr == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
err := e.ingressGatewayMgr.Close()
|
||||
e.ingressGatewayMgr = nil
|
||||
e.statusRecorder.SetIngressGwMgr(nil)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if e.ingressGatewayMgr == nil {
|
||||
mgr := ingressgw.NewManager(e.firewall)
|
||||
e.ingressGatewayMgr = mgr
|
||||
e.statusRecorder.SetIngressGwMgr(mgr)
|
||||
}
|
||||
|
||||
var merr *multierror.Error
|
||||
forwardingRules := make([]firewallManager.ForwardRule, 0, len(rules))
|
||||
for _, rule := range rules {
|
||||
proto, err := acl.ConvertToFirewallProtocol(rule.GetProtocol())
|
||||
if err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("failed to convert protocol '%s': %w", rule.GetProtocol(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
dstPortInfo, err := convertPortInfo(rule.GetDestinationPort())
|
||||
if err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("invalid destination port '%v': %w", rule.GetDestinationPort(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
translateIP, err := convertToIP(rule.GetTranslatedAddress())
|
||||
if err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("failed to convert translated address '%s': %w", rule.GetTranslatedAddress(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
translatePort, err := convertPortInfo(rule.GetTranslatedPort())
|
||||
if err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("invalid translate port '%v': %w", rule.GetTranslatedPort(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
forwardRule := firewallManager.ForwardRule{
|
||||
Protocol: proto,
|
||||
DestinationPort: *dstPortInfo,
|
||||
TranslatedAddress: translateIP,
|
||||
TranslatedPort: *translatePort,
|
||||
}
|
||||
|
||||
forwardingRules = append(forwardingRules, forwardRule)
|
||||
}
|
||||
|
||||
log.Infof("updating forwarding rules: %d", len(forwardingRules))
|
||||
if err := e.ingressGatewayMgr.Update(forwardingRules); err != nil {
|
||||
log.Errorf("failed to update forwarding rules: %v", err)
|
||||
}
|
||||
|
||||
return forwardingRules, nberrors.FormatErrorOrNil(merr)
|
||||
}
|
||||
|
||||
// toExcludedLazyPeers returns the peers that must have an always-active
|
||||
// connection: those that are not lazy by policy (the per-peer lazy state or the
|
||||
// account flag, subject to the local override).
|
||||
|
||||
@@ -42,7 +42,6 @@ import (
|
||||
nbcache "github.com/netbirdio/netbird/management/server/cache"
|
||||
"github.com/netbirdio/netbird/management/server/groups"
|
||||
"github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator"
|
||||
"github.com/netbirdio/netbird/management/server/integrations/port_forwarding"
|
||||
"github.com/netbirdio/netbird/management/server/job"
|
||||
"github.com/netbirdio/netbird/management/server/permissions"
|
||||
"github.com/netbirdio/netbird/management/server/settings"
|
||||
@@ -523,8 +522,8 @@ func startManagement(t *testing.T, dataDir, testFile string) (*grpc.Server, stri
|
||||
|
||||
updateManager := update_channel.NewPeersUpdateManager(metrics)
|
||||
requestBuffer := server.NewAccountRequestBuffer(context.Background(), store)
|
||||
networkMapController := controller.NewController(context.Background(), store, metrics, updateManager, requestBuffer, server.MockIntegratedValidator{}, settingsMockManager, "netbird.selfhosted", port_forwarding.NewControllerMock(), manager.NewEphemeralManager(store, peersManager), config, nil)
|
||||
accountManager, err := server.BuildManager(context.Background(), config, store, networkMapController, jobManager, nil, "", eventStore, nil, false, ia, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false, cacheStore)
|
||||
networkMapController := controller.NewController(context.Background(), store, metrics, updateManager, requestBuffer, server.MockIntegratedValidator{}, settingsMockManager, "netbird.selfhosted", manager.NewEphemeralManager(store, peersManager), config, nil)
|
||||
accountManager, err := server.BuildManager(context.Background(), config, store, networkMapController, jobManager, nil, "", eventStore, nil, false, ia, metrics, settingsMockManager, permissionsManager, false, cacheStore)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
package ingressgw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
nberrors "github.com/netbirdio/netbird/client/errors"
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
)
|
||||
|
||||
type DNATFirewall interface {
|
||||
AddDNATRule(fwdRule firewall.ForwardRule) (firewall.Rule, error)
|
||||
DeleteDNATRule(rule firewall.Rule) error
|
||||
}
|
||||
|
||||
type RulePair struct {
|
||||
firewall.ForwardRule
|
||||
firewall.Rule
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
dnatFirewall DNATFirewall
|
||||
|
||||
rules map[firewall.RuleID]RulePair
|
||||
rulesMu sync.Mutex
|
||||
}
|
||||
|
||||
func NewManager(dnatFirewall DNATFirewall) *Manager {
|
||||
return &Manager{
|
||||
dnatFirewall: dnatFirewall,
|
||||
rules: make(map[firewall.RuleID]RulePair),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Manager) Update(forwardRules []firewall.ForwardRule) error {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
var mErr *multierror.Error
|
||||
|
||||
toDelete := make(map[firewall.RuleID]RulePair, len(h.rules))
|
||||
for id, r := range h.rules {
|
||||
toDelete[id] = r
|
||||
}
|
||||
|
||||
// Process new/updated rules
|
||||
for _, fwdRule := range forwardRules {
|
||||
id := fwdRule.ID()
|
||||
if _, ok := h.rules[id]; ok {
|
||||
delete(toDelete, id)
|
||||
continue
|
||||
}
|
||||
|
||||
rule, err := h.dnatFirewall.AddDNATRule(fwdRule)
|
||||
if err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("add forward rule '%s': %v", fwdRule.String(), err))
|
||||
continue
|
||||
}
|
||||
if rule == nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("add forward rule '%s': backend returned no rule", fwdRule.String()))
|
||||
continue
|
||||
}
|
||||
log.Infof("forward rule has been added '%s'", fwdRule)
|
||||
h.rules[id] = RulePair{
|
||||
ForwardRule: fwdRule,
|
||||
Rule: rule,
|
||||
}
|
||||
}
|
||||
|
||||
// Remove deleted rules
|
||||
for id, rulePair := range toDelete {
|
||||
if err := h.dnatFirewall.DeleteDNATRule(rulePair.Rule); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rulePair.ForwardRule.String(), err))
|
||||
}
|
||||
log.Infof("forward rule has been deleted '%s'", rulePair.ForwardRule)
|
||||
delete(h.rules, id)
|
||||
}
|
||||
|
||||
return nberrors.FormatErrorOrNil(mErr)
|
||||
}
|
||||
|
||||
func (h *Manager) Close() error {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
log.Infof("clean up all (%d) forward rules", len(h.rules))
|
||||
var mErr *multierror.Error
|
||||
for _, rule := range h.rules {
|
||||
if err := h.dnatFirewall.DeleteDNATRule(rule.Rule); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rule, err))
|
||||
}
|
||||
}
|
||||
|
||||
h.rules = make(map[firewall.RuleID]RulePair)
|
||||
return nberrors.FormatErrorOrNil(mErr)
|
||||
}
|
||||
|
||||
func (h *Manager) Rules() []firewall.ForwardRule {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
rules := make([]firewall.ForwardRule, 0, len(h.rules))
|
||||
for _, rulePair := range h.rules {
|
||||
rules = append(rules, rulePair.ForwardRule)
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
package ingressgw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
)
|
||||
|
||||
var (
|
||||
_ firewall.Rule = (*MocFwRule)(nil)
|
||||
_ DNATFirewall = &MockDNATFirewall{}
|
||||
)
|
||||
|
||||
type MocFwRule struct {
|
||||
id firewall.RuleID
|
||||
}
|
||||
|
||||
func (m *MocFwRule) ID() firewall.RuleID {
|
||||
return m.id
|
||||
}
|
||||
|
||||
type MockDNATFirewall struct {
|
||||
throwError bool
|
||||
}
|
||||
|
||||
func (m *MockDNATFirewall) AddDNATRule(fwdRule firewall.ForwardRule) (firewall.Rule, error) {
|
||||
if m.throwError {
|
||||
return nil, fmt.Errorf("moc error")
|
||||
}
|
||||
|
||||
fwRule := &MocFwRule{
|
||||
id: fwdRule.ID(),
|
||||
}
|
||||
return fwRule, nil
|
||||
}
|
||||
|
||||
func (m *MockDNATFirewall) DeleteDNATRule(rule firewall.Rule) error {
|
||||
if m.throwError {
|
||||
return fmt.Errorf("moc error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockDNATFirewall) forceToThrowErrors() {
|
||||
m.throwError = true
|
||||
}
|
||||
|
||||
func TestManager_AddRule(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
|
||||
updates := []firewall.ForwardRule{
|
||||
{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
},
|
||||
{
|
||||
Protocol: firewall.ProtocolUDP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}}
|
||||
|
||||
if err := mgr.Update(updates); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != len(updates) {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_UpdateRule(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
ruleUDP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolUDP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.2"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleUDP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 1 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
|
||||
if rules[0].TranslatedAddress.String() != ruleUDP.TranslatedAddress.String() {
|
||||
t.Errorf("unexpected rule: %v", rules[0])
|
||||
}
|
||||
|
||||
if rules[0].TranslatedPort.String() != ruleUDP.TranslatedPort.String() {
|
||||
t.Errorf("unexpected rule: %v", rules[0])
|
||||
}
|
||||
|
||||
if rules[0].DestinationPort.String() != ruleUDP.DestinationPort.String() {
|
||||
t.Errorf("unexpected rule: %v", rules[0])
|
||||
}
|
||||
|
||||
if rules[0].Protocol != ruleUDP.Protocol {
|
||||
t.Errorf("unexpected rule: %v", rules[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_ExtendRules(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
ruleUDP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolUDP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.2"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP, ruleUDP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 2 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_UnderlingError(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
ruleUDP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolUDP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.2"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fw.forceToThrowErrors()
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP, ruleUDP}); err == nil {
|
||||
t.Errorf("expected error")
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 1 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_Cleanup(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 0 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_DeleteBrokenRule(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
|
||||
// force to throw errors when Add DNAT Rule
|
||||
fw.forceToThrowErrors()
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err == nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 0 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
|
||||
// simulate that to remove a broken rule
|
||||
if err := mgr.Update([]firewall.ForwardRule{}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if err := mgr.Close(); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager_Close(t *testing.T) {
|
||||
fw := &MockDNATFirewall{}
|
||||
mgr := NewManager(fw)
|
||||
|
||||
port, _ := firewall.NewPort(8080)
|
||||
ruleTCP := firewall.ForwardRule{
|
||||
Protocol: firewall.ProtocolTCP,
|
||||
DestinationPort: *port,
|
||||
TranslatedAddress: netip.MustParseAddr("172.16.254.1"),
|
||||
TranslatedPort: *port,
|
||||
}
|
||||
|
||||
if err := mgr.Update([]firewall.ForwardRule{ruleTCP}); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if err := mgr.Close(); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rules := mgr.Rules()
|
||||
if len(rules) != 0 {
|
||||
t.Errorf("unexpected rules count: %d", len(rules))
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
firewallManager "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
mgmProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||
)
|
||||
|
||||
func convertPortInfo(portInfo *mgmProto.PortInfo) (*firewallManager.Port, error) {
|
||||
if portInfo == nil {
|
||||
return nil, errors.New("portInfo cannot be nil")
|
||||
}
|
||||
|
||||
if portInfo.GetPort() != 0 {
|
||||
return firewallManager.NewPort(int(portInfo.GetPort()))
|
||||
}
|
||||
|
||||
if portInfo.GetRange() != nil {
|
||||
return firewallManager.NewPort(int(portInfo.GetRange().Start), int(portInfo.GetRange().End))
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid portInfo: %v", portInfo)
|
||||
}
|
||||
|
||||
func convertToIP(rawIP []byte) (netip.Addr, error) {
|
||||
if rawIP == nil {
|
||||
return netip.Addr{}, errors.New("input bytes cannot be nil")
|
||||
}
|
||||
|
||||
if len(rawIP) != net.IPv4len && len(rawIP) != net.IPv6len {
|
||||
return netip.Addr{}, fmt.Errorf("invalid IP length: %d", len(rawIP))
|
||||
}
|
||||
|
||||
if len(rawIP) == net.IPv4len {
|
||||
return netip.AddrFrom4([4]byte(rawIP)), nil
|
||||
}
|
||||
|
||||
return netip.AddrFrom16([16]byte(rawIP)), nil
|
||||
}
|
||||
@@ -18,9 +18,7 @@ import (
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/iface/configurer"
|
||||
"github.com/netbirdio/netbird/client/internal/ingressgw"
|
||||
"github.com/netbirdio/netbird/client/internal/relay"
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
"github.com/netbirdio/netbird/route"
|
||||
@@ -161,7 +159,6 @@ type FullStatus struct {
|
||||
RosenpassState RosenpassState
|
||||
Relays []relay.ProbeResult
|
||||
NSGroupStates []NSGroupState
|
||||
NumOfForwardingRules int
|
||||
LazyConnectionEnabled bool
|
||||
Events []*proto.SystemEvent
|
||||
}
|
||||
@@ -247,8 +244,6 @@ type Status struct {
|
||||
// read it without taking mux.
|
||||
networksRevision atomic.Uint64
|
||||
|
||||
ingressGwMgr *ingressgw.Manager
|
||||
|
||||
routeIDLookup routeIDLookup
|
||||
wgIface WGIfaceStatus
|
||||
}
|
||||
@@ -276,12 +271,6 @@ func (d *Status) SetRelayMgr(manager *relayClient.Manager) {
|
||||
d.relayMgr = manager
|
||||
}
|
||||
|
||||
func (d *Status) SetIngressGwMgr(ingressGwMgr *ingressgw.Manager) {
|
||||
d.mux.Lock()
|
||||
defer d.mux.Unlock()
|
||||
d.ingressGwMgr = ingressGwMgr
|
||||
}
|
||||
|
||||
// ReplaceOfflinePeers replaces
|
||||
func (d *Status) ReplaceOfflinePeers(replacement []State) {
|
||||
d.mux.Lock()
|
||||
@@ -332,18 +321,6 @@ func (d *Status) GetPeer(peerPubKey string) (State, error) {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (d *Status) PeerByIP(ip string) (string, bool) {
|
||||
d.mux.RLock()
|
||||
defer d.mux.RUnlock()
|
||||
|
||||
for _, state := range d.peers {
|
||||
if state.IP == ip {
|
||||
return state.FQDN, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// PeerStateByIP returns the full peer State for the given tunnel IP.
|
||||
// Matches against either the IPv4 (State.IP) or IPv6 (State.IPv6) tunnel
|
||||
// address so dual-stack peers are reachable on either family. Only
|
||||
@@ -1163,16 +1140,6 @@ func (d *Status) GetRelayStates() []relay.ProbeResult {
|
||||
return relayStates
|
||||
}
|
||||
|
||||
func (d *Status) ForwardingRules() []firewall.ForwardRule {
|
||||
d.mux.RLock()
|
||||
defer d.mux.RUnlock()
|
||||
if d.ingressGwMgr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return d.ingressGwMgr.Rules()
|
||||
}
|
||||
|
||||
func (d *Status) GetDNSStates() []NSGroupState {
|
||||
d.mux.RLock()
|
||||
defer d.mux.RUnlock()
|
||||
@@ -1207,7 +1174,6 @@ func (d *Status) GetFullStatus() FullStatus {
|
||||
Relays: d.GetRelayStates(),
|
||||
RosenpassState: d.GetRosenpassState(),
|
||||
NSGroupStates: d.GetDNSStates(),
|
||||
NumOfForwardingRules: len(d.ForwardingRules()),
|
||||
LazyConnectionEnabled: d.GetLazyConnection(),
|
||||
}
|
||||
|
||||
@@ -1579,7 +1545,6 @@ func (fs FullStatus) ToProto() *proto.FullStatus {
|
||||
pbFullStatus.LocalPeerState.WgPort = int32(fs.LocalPeerState.WgPort)
|
||||
pbFullStatus.LocalPeerState.RosenpassPermissive = fs.RosenpassState.Permissive
|
||||
pbFullStatus.LocalPeerState.RosenpassEnabled = fs.RosenpassState.Enabled
|
||||
pbFullStatus.NumberOfForwardingRules = int32(fs.NumOfForwardingRules)
|
||||
pbFullStatus.LazyConnectionEnabled = fs.LazyConnectionEnabled
|
||||
|
||||
pbFullStatus.LocalPeerState.Networks = maps.Keys(fs.LocalPeerState.Routes)
|
||||
|
||||
@@ -19,8 +19,7 @@ type IPForwardingState struct {
|
||||
|
||||
// routingV4/routingV6 track whether the routing path currently holds a
|
||||
// reference, so repeated EnableRouting calls (one per network-map update)
|
||||
// hold at most one reference per family and an unpaired DisableRouting
|
||||
// can't release references held by DNAT rules.
|
||||
// hold at most one reference per family.
|
||||
routingV4 bool
|
||||
routingV6 bool
|
||||
|
||||
@@ -95,31 +94,6 @@ func (f *IPForwardingState) ReleaseRouting() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RequestForwarding enables the family's forwarding sysctl on first request.
|
||||
func (f *IPForwardingState) RequestForwarding(v6 bool) error {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
if v6 {
|
||||
return f.requestV6()
|
||||
}
|
||||
return f.requestV4()
|
||||
}
|
||||
|
||||
// ReleaseForwarding decrements the family counter. The last v6 release restores
|
||||
// what enable captured. v4 stays on: net.ipv4.ip_forward is co-owned by other
|
||||
// tooling (docker, k8s, libvirt).
|
||||
func (f *IPForwardingState) ReleaseForwarding(v6 bool) error {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
if v6 {
|
||||
return f.releaseV6()
|
||||
}
|
||||
f.releaseV4()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *IPForwardingState) requestV4() error {
|
||||
if f.v4Count == 0 {
|
||||
if err := systemops.EnableV4IPForwarding(); err != nil {
|
||||
|
||||
@@ -10,8 +10,7 @@ import (
|
||||
)
|
||||
|
||||
// TestRequestRoutingV6ToV4Transition verifies that a v4-only routing request
|
||||
// releases a previously held routing-owned v6 reference without touching
|
||||
// references held by DNAT rules.
|
||||
// releases a previously held routing-owned v6 reference.
|
||||
func TestRequestRoutingV6ToV4Transition(t *testing.T) {
|
||||
f := NewIPForwardingState("wt-fwd-test")
|
||||
|
||||
@@ -25,13 +24,6 @@ func TestRequestRoutingV6ToV4Transition(t *testing.T) {
|
||||
assert.Equal(t, 1, v4, "v4 reference kept")
|
||||
assert.Equal(t, 0, v6, "routing-owned v6 reference released")
|
||||
|
||||
// A DNAT-held reference survives a v4-only routing request.
|
||||
require.NoError(t, f.RequestForwarding(true), "dnat v6 reference")
|
||||
require.NoError(t, f.RequestRouting(false), "repeat v4-only request")
|
||||
_, v6 = f.Counts()
|
||||
assert.Equal(t, 1, v6, "dnat-held v6 reference survives")
|
||||
require.NoError(t, f.ReleaseForwarding(true), "release dnat v6 reference")
|
||||
|
||||
require.NoError(t, f.ReleaseRouting(), "release routing")
|
||||
v4, v6 = f.Counts()
|
||||
assert.Equal(t, 0, v4, "all v4 references released")
|
||||
|
||||
Reference in New Issue
Block a user