Add forwarding commandline command

This commit is contained in:
Zoltán Papp
2025-01-24 18:42:14 +01:00
parent cf0154d5fd
commit 8185614362
14 changed files with 1322 additions and 412 deletions

View File

@@ -0,0 +1,90 @@
package cmd
import (
"fmt"
"sort"
"strings"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/client/proto"
)
var forwardingRulesCmd = &cobra.Command{
Use: "forwarding",
Short: "List forwarding rules",
Long: `Commands to list forwarding rules.`,
RunE: listForwardingRules,
}
func listForwardingRules(cmd *cobra.Command, _ []string) error {
conn, err := getClient(cmd)
if err != nil {
return err
}
defer conn.Close()
client := proto.NewDaemonServiceClient(conn)
resp, err := client.ForwardingRules(cmd.Context(), &proto.EmptyRequest{})
if err != nil {
return fmt.Errorf("failed to list network: %v", status.Convert(err).Message())
}
if len(resp.GetRules()) == 0 {
cmd.Println("No forwarding rules available.")
return nil
}
printForwardingRules(cmd, resp.GetRules())
return nil
}
func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
cmd.Println("Available forwarding rules:")
// Sort rules by translated address
sort.Slice(rules, func(i, j int) bool {
if rules[i].GetTranslatedAddress() != rules[j].GetTranslatedAddress() {
return rules[i].GetTranslatedAddress() < rules[j].GetTranslatedAddress()
}
if rules[i].GetProtocol() != rules[j].GetProtocol() {
return rules[i].GetProtocol() < rules[j].GetProtocol()
}
return getFirstPort(rules[i].GetDestinationPort()) < getFirstPort(rules[j].GetDestinationPort())
})
var lastIP string
for _, rule := range rules {
dPort := portToString(rule.GetDestinationPort())
tPort := portToString(rule.GetTranslatedPort())
if lastIP != rule.GetTranslatedAddress() {
lastIP = rule.GetTranslatedAddress()
cmd.Printf("\nTranslated peer: %s\n", rule.GetTranslatedAddress())
}
cmd.Printf(" ports (%s): %s to %s\n", strings.ToUpper(rule.GetProtocol()), dPort, tPort)
}
}
func getFirstPort(portInfo *proto.PortInfo) int {
switch v := portInfo.PortSelection.(type) {
case *proto.PortInfo_Port:
return int(v.Port)
case *proto.PortInfo_Range_:
return int(v.Range.GetStart())
default:
return 0
}
}
func portToString(translatedPort *proto.PortInfo) string {
switch v := translatedPort.PortSelection.(type) {
case *proto.PortInfo_Port:
return fmt.Sprintf("%d", v.Port)
case *proto.PortInfo_Range_:
return fmt.Sprintf("%d:%d", v.Range.GetStart(), v.Range.GetEnd())
default:
return "No port specified"
}
}

View File

@@ -145,6 +145,7 @@ func init() {
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(sshCmd)
rootCmd.AddCommand(networksCMD)
rootCmd.AddCommand(forwardingRulesCmd)
rootCmd.AddCommand(debugCmd)
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service

View File

@@ -213,6 +213,15 @@ func (m *Manager) AllowNetbird() error {
// Flush doesn't need to be implemented for this manager
func (m *Manager) Flush() error { return nil }
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
return nil, fmt.Errorf("not implemented")
}
// DeleteDNATRule deletes a DNAT rule
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
return nil
}
func getConntrackEstablished() []string {
return []string{"-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}
}

View File

@@ -22,5 +22,5 @@ func (r ForwardRule) GetRuleID() string {
}
func (r ForwardRule) String() string {
return r.GetRuleID()
return fmt.Sprintf("protocol: %s, destinationPort: %s, translatedAddress: %s, translatedPort: %s", r.Protocol, r.DestinationPort.String(), r.TranslatedAddress.String(), r.TranslatedPort.String())
}

View File

@@ -329,6 +329,19 @@ func (m *Manager) Flush() error {
return m.aclManager.Flush()
}
// AddDNATRule adds a DNAT rule
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
r := &Rule{
ruleID: rule.GetRuleID(),
}
return r, nil
}
// DeleteDNATRule deletes a DNAT rule
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
return nil
}
func (m *Manager) createWorkTable() (*nftables.Table, error) {
tables, err := m.rConn.ListTablesOfFamily(nftables.TableFamilyIPv4)
if err != nil {

View File

@@ -253,6 +253,16 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
// Flush doesn't need to be implemented for this manager
func (m *Manager) Flush() error { return nil }
// AddDNATRule adds a DNAT rule
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
return nil, fmt.Errorf("not implemented")
}
// DeleteDNATRule deletes a DNAT rule
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
return nil
}
// DropOutgoing filter outgoing packets
func (m *Manager) DropOutgoing(packetData []byte) bool {
return m.processOutgoingHooks(packetData)

View File

@@ -935,7 +935,9 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
}
// Ingress forward rules
e.updateForwardRules(networkMap.GetForwardingRules())
if err := e.updateForwardRules(networkMap.GetForwardingRules()); err != nil {
log.Errorf("failed to update forward rules, err: %v", err)
}
log.Debugf("got peers update from Management Service, total peers to connect to = %d", len(networkMap.GetRemotePeers()))
@@ -1755,12 +1757,20 @@ func (e *Engine) updateForwardRules(rules []*mgmProto.ForwardingRule) error {
return nil
}
// todo delete this before merge
defer e.mocForwardRules()
if len(rules) == 0 && e.ingressGatewayMgr != nil {
return e.ingressGatewayMgr.Close()
err := e.ingressGatewayMgr.Close()
e.ingressGatewayMgr = nil
e.statusRecorder.SetIngressGwMgr(nil)
return err
}
if e.ingressGatewayMgr == nil {
e.ingressGatewayMgr = ingressgw.NewManager(e.firewall)
mgr := ingressgw.NewManager(e.firewall)
e.ingressGatewayMgr = mgr
e.statusRecorder.SetIngressGwMgr(mgr)
}
var merr *multierror.Error

View File

@@ -0,0 +1,210 @@
package internal
import (
"net/netip"
log "github.com/sirupsen/logrus"
firewallManager "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/internal/ingressgw"
)
func (e *Engine) mocForwardRules() {
if e.ingressGatewayMgr == nil {
e.ingressGatewayMgr = ingressgw.NewManager(e.firewall)
}
err := e.ingressGatewayMgr.Update(
[]firewallManager.ForwardRule{
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: false, Values: []int{10000}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: false, Values: []int{20000}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10100, 10199}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20100, 20199}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10200, 10299}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20200, 20299}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10300, 10399}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20300, 20399}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10100, 10199}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20100, 20199}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10400, 10499}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20400, 20499}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10500, 10599}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20500, 20599}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10600, 10699}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20600, 20699}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10700, 10799}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20700, 20799}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10800, 10899}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20800, 20899}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10900, 10999}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20900, 20999}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11000, 11099}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21000, 21099}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11100, 11199}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21100, 21199}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11200, 11299}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21200, 21299}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11300, 11399}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21300, 21399}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11400, 11499}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21400, 21499}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11500, 11599}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21500, 21599}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11600, 11699}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21600, 21699}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11700, 11799}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21700, 21799}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11800, 11899}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21800, 21899}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11900, 11999}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21900, 21999}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12000, 12099}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22000, 22099}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12100, 12199}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22100, 22199}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12200, 12299}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22200, 22299}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12300, 12399}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22300, 22399}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12400, 12499}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22400, 22499}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12500, 12599}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22500, 22599}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12600, 12699}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22600, 22699}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12700, 12799}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22700, 22799}},
},
{
Protocol: "tcp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12800, 12899}},
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22800, 22899}},
},
{
Protocol: "udp",
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12900, 12999}},
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22900, 22999}},
},
},
)
if err != nil {
log.Errorf("failed to update forwarding rules: %v", err)
}
}

View File

@@ -2,65 +2,97 @@ package ingressgw
import (
"fmt"
"sync"
"github.com/hashicorp/go-multierror"
log "github.com/sirupsen/logrus"
nberrors "github.com/netbirdio/netbird/client/errors"
firewallManager "github.com/netbirdio/netbird/client/firewall/manager"
)
type RulePair struct {
firewallManager.ForwardRule
firewallManager.Rule
}
type Manager struct {
firewallManager firewallManager.Manager
fwRules map[string]firewallManager.Rule
rules map[string]RulePair // keys is the ID of the ForwardRule
rulesMu sync.Mutex
}
func NewManager(firewall firewallManager.Manager) *Manager {
return &Manager{
firewallManager: firewall,
fwRules: make(map[string]firewallManager.Rule),
rules: make(map[string]RulePair),
}
}
func (h *Manager) Update(forwardRules []firewallManager.ForwardRule) error {
h.rulesMu.Lock()
defer h.rulesMu.Unlock()
var mErr *multierror.Error
toDelete := make(map[string]firewallManager.Rule)
for id, r := range h.fwRules {
toDelete := make(map[string]RulePair)
for id, r := range h.rules {
toDelete[id] = r
}
// Process new/updated rules
for _, rule := range forwardRules {
id := rule.GetRuleID()
if _, ok := h.fwRules[id]; ok {
for _, fwdRule := range forwardRules {
id := fwdRule.GetRuleID()
if _, ok := h.rules[id]; ok {
delete(toDelete, id)
continue
}
rule, err := h.firewallManager.AddDNATRule(rule)
rule, err := h.firewallManager.AddDNATRule(fwdRule)
if err != nil {
mErr = multierror.Append(mErr, fmt.Errorf("failed to add forward rule '%s': %v", rule, err))
mErr = multierror.Append(mErr, fmt.Errorf("failed to add forward rule '%s': %v", fwdRule.String(), err))
continue
}
h.fwRules[id] = rule
log.Infof("added forward rule '%s'", fwdRule)
h.rules[id] = RulePair{
ForwardRule: fwdRule,
Rule: rule,
}
}
// Remove deleted rules
for id, rule := range toDelete {
if err := h.firewallManager.DeleteDNATRule(rule); err != nil {
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rule, err))
for id, rulePair := range toDelete {
if err := h.firewallManager.DeleteDNATRule(rulePair.Rule); err != nil {
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rulePair.ForwardRule.String(), err))
}
delete(h.fwRules, id)
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 forward rules (%d)", len(h.rules))
var mErr *multierror.Error
for _, rule := range h.fwRules {
if err := h.firewallManager.DeleteDNATRule(rule); err != nil {
for _, rule := range h.rules {
if err := h.firewallManager.DeleteDNATRule(rule.Rule); err != nil {
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rule, err))
}
}
return nberrors.FormatErrorOrNil(mErr)
}
func (h *Manager) Rules() []firewallManager.ForwardRule {
h.rulesMu.Lock()
defer h.rulesMu.Unlock()
rules := make([]firewallManager.ForwardRule, 0, len(h.rules))
for _, rulePair := range h.rules {
rules = append(rules, rulePair.ForwardRule)
}
return rules
}

View File

@@ -11,7 +11,9 @@ import (
"google.golang.org/grpc/codes"
gstatus "google.golang.org/grpc/status"
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/management/domain"
relayClient "github.com/netbirdio/netbird/relay/client"
@@ -157,6 +159,8 @@ type Status struct {
peerListChangedForNotification bool
relayMgr *relayClient.Manager
ingressGwMgr *ingressgw.Manager
}
// NewRecorder returns a new Status instance
@@ -177,6 +181,12 @@ 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()
@@ -718,6 +728,16 @@ func (d *Status) GetRelayStates() []relay.ProbeResult {
return append(relayStates, relayState)
}
func (d *Status) ForwardingRules() []firewall.ForwardRule {
d.mux.Lock()
defer d.mux.Unlock()
if d.ingressGwMgr == nil {
return nil
}
return d.ingressGwMgr.Rules()
}
func (d *Status) GetDNSStates() []NSGroupState {
d.mux.Lock()
defer d.mux.Unlock()

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,8 @@ option go_package = "/proto";
package daemon;
message EmptyRequest {}
service DaemonService {
// Login uses setup key to prepare configuration for the daemon.
rpc Login(LoginRequest) returns (LoginResponse) {}
@@ -37,6 +39,8 @@ service DaemonService {
// Deselect specific routes
rpc DeselectNetworks(SelectNetworksRequest) returns (SelectNetworksResponse) {}
rpc ForwardingRules(EmptyRequest) returns (ForwardingRulesResponse) {}
// DebugBundle creates a debug bundle
rpc DebugBundle(DebugBundleRequest) returns (DebugBundleResponse) {}
@@ -251,6 +255,7 @@ message FullStatus {
repeated NSGroupState dns_servers = 6;
}
// Networks
message ListNetworksRequest {
}
@@ -271,7 +276,6 @@ message IPList {
repeated string ips = 1;
}
message Network {
string ID = 1;
string range = 2;
@@ -280,6 +284,32 @@ message Network {
map<string, IPList> resolvedIPs = 5;
}
// ForwardingRules
message PortInfo {
oneof portSelection {
uint32 port = 1;
Range range = 2;
}
message Range {
uint32 start = 1;
uint32 end = 2;
}
}
message ForwardingRule {
string protocol = 1;
PortInfo destinationPort = 2;
string translatedAddress = 3;
PortInfo translatedPort = 4;
}
message ForwardingRulesResponse {
repeated ForwardingRule rules = 1;
}
// DebugBundler
message DebugBundleRequest {
bool anonymize = 1;
string status = 2;

View File

@@ -37,6 +37,7 @@ type DaemonServiceClient interface {
SelectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error)
// Deselect specific routes
DeselectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error)
ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error)
// DebugBundle creates a debug bundle
DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error)
// GetLogLevel gets the log level of the daemon
@@ -142,6 +143,15 @@ func (c *daemonServiceClient) DeselectNetworks(ctx context.Context, in *SelectNe
return out, nil
}
func (c *daemonServiceClient) ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error) {
out := new(ForwardingRulesResponse)
err := c.cc.Invoke(ctx, "/daemon.DaemonService/ForwardingRules", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *daemonServiceClient) DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error) {
out := new(DebugBundleResponse)
err := c.cc.Invoke(ctx, "/daemon.DaemonService/DebugBundle", in, out, opts...)
@@ -228,6 +238,7 @@ type DaemonServiceServer interface {
SelectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error)
// Deselect specific routes
DeselectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error)
ForwardingRules(context.Context, *EmptyRequest) (*ForwardingRulesResponse, error)
// DebugBundle creates a debug bundle
DebugBundle(context.Context, *DebugBundleRequest) (*DebugBundleResponse, error)
// GetLogLevel gets the log level of the daemon
@@ -276,6 +287,9 @@ func (UnimplementedDaemonServiceServer) SelectNetworks(context.Context, *SelectN
func (UnimplementedDaemonServiceServer) DeselectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeselectNetworks not implemented")
}
func (UnimplementedDaemonServiceServer) ForwardingRules(context.Context, *EmptyRequest) (*ForwardingRulesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ForwardingRules not implemented")
}
func (UnimplementedDaemonServiceServer) DebugBundle(context.Context, *DebugBundleRequest) (*DebugBundleResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DebugBundle not implemented")
}
@@ -472,6 +486,24 @@ func _DaemonService_DeselectNetworks_Handler(srv interface{}, ctx context.Contex
return interceptor(ctx, in, info, handler)
}
func _DaemonService_ForwardingRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(EmptyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DaemonServiceServer).ForwardingRules(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/daemon.DaemonService/ForwardingRules",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DaemonServiceServer).ForwardingRules(ctx, req.(*EmptyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _DaemonService_DebugBundle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DebugBundleRequest)
if err := dec(in); err != nil {
@@ -641,6 +673,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeselectNetworks",
Handler: _DaemonService_DeselectNetworks_Handler,
},
{
MethodName: "ForwardingRules",
Handler: _DaemonService_ForwardingRules_Handler,
},
{
MethodName: "DebugBundle",
Handler: _DaemonService_DebugBundle_Handler,

View File

@@ -0,0 +1,46 @@
package server
import (
"context"
firewall "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/proto"
)
func (s *Server) ForwardingRules(context.Context, *proto.EmptyRequest) (*proto.ForwardingRulesResponse, error) {
s.mutex.Lock()
defer s.mutex.Unlock()
rules := s.statusRecorder.ForwardingRules()
responseRules := make([]*proto.ForwardingRule, 0, len(rules))
for _, rule := range rules {
respRule := &proto.ForwardingRule{
Protocol: string(rule.Protocol),
DestinationPort: portToProto(rule.DestinationPort),
TranslatedAddress: rule.TranslatedAddress.String(),
TranslatedPort: portToProto(rule.TranslatedPort),
}
responseRules = append(responseRules, respRule)
}
return &proto.ForwardingRulesResponse{Rules: responseRules}, nil
}
func portToProto(port firewall.Port) *proto.PortInfo {
var portInfo proto.PortInfo
if !port.IsRange {
portInfo.PortSelection = &proto.PortInfo_Port{Port: uint32(port.Values[0])}
} else {
portInfo.PortSelection = &proto.PortInfo_Range_{
Range: &proto.PortInfo_Range{
Start: uint32(port.Values[0]),
End: uint32(port.Values[1]),
},
}
}
return &portInfo
}