mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-03 21:10:50 +02:00
186 lines
4.0 KiB
Go
186 lines
4.0 KiB
Go
//go:build linux && !android
|
|
|
|
package debug
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"sort"
|
|
|
|
"github.com/netbirdio/netbird/client/anonymize"
|
|
"github.com/netbirdio/netbird/client/internal/routemanager/systemops"
|
|
)
|
|
|
|
func formatIPRulesTable(ipRules []systemops.IPRule, anonymize bool, anonymizer *anonymize.Anonymizer) string {
|
|
if len(ipRules) == 0 {
|
|
return "No IP rules found.\n"
|
|
}
|
|
|
|
sort.Slice(ipRules, func(i, j int) bool {
|
|
return ipRules[i].Priority < ipRules[j].Priority
|
|
})
|
|
|
|
columnConfig := detectIPRuleColumns(ipRules)
|
|
|
|
headers := buildIPRuleHeaders(columnConfig)
|
|
|
|
rows := buildIPRuleRows(ipRules, columnConfig, anonymize, anonymizer)
|
|
|
|
return formatTable("IP Rules:", headers, rows)
|
|
}
|
|
|
|
type ipRuleColumnConfig struct {
|
|
hasInvert, hasTo, hasMark, hasIIF, hasOIF, hasSuppressPlen bool
|
|
}
|
|
|
|
func detectIPRuleColumns(ipRules []systemops.IPRule) ipRuleColumnConfig {
|
|
var config ipRuleColumnConfig
|
|
for _, rule := range ipRules {
|
|
if rule.Invert {
|
|
config.hasInvert = true
|
|
}
|
|
if rule.To.IsValid() {
|
|
config.hasTo = true
|
|
}
|
|
if rule.Mark != 0 {
|
|
config.hasMark = true
|
|
}
|
|
if rule.IIF != "" {
|
|
config.hasIIF = true
|
|
}
|
|
if rule.OIF != "" {
|
|
config.hasOIF = true
|
|
}
|
|
if rule.SuppressPlen >= 0 {
|
|
config.hasSuppressPlen = true
|
|
}
|
|
}
|
|
return config
|
|
}
|
|
|
|
func buildIPRuleHeaders(config ipRuleColumnConfig) []string {
|
|
var headers []string
|
|
|
|
headers = append(headers, "Priority")
|
|
if config.hasInvert {
|
|
headers = append(headers, "Not")
|
|
}
|
|
headers = append(headers, "From")
|
|
if config.hasTo {
|
|
headers = append(headers, "To")
|
|
}
|
|
if config.hasMark {
|
|
headers = append(headers, "FWMark")
|
|
}
|
|
if config.hasIIF {
|
|
headers = append(headers, "IIF")
|
|
}
|
|
if config.hasOIF {
|
|
headers = append(headers, "OIF")
|
|
}
|
|
headers = append(headers, "Table")
|
|
headers = append(headers, "Action")
|
|
if config.hasSuppressPlen {
|
|
headers = append(headers, "SuppressPlen")
|
|
}
|
|
|
|
return headers
|
|
}
|
|
|
|
func buildIPRuleRows(ipRules []systemops.IPRule, config ipRuleColumnConfig, anonymize bool, anonymizer *anonymize.Anonymizer) [][]string {
|
|
var rows [][]string
|
|
for _, rule := range ipRules {
|
|
row := buildSingleIPRuleRow(rule, config, anonymize, anonymizer)
|
|
rows = append(rows, row)
|
|
}
|
|
return rows
|
|
}
|
|
|
|
func buildSingleIPRuleRow(rule systemops.IPRule, config ipRuleColumnConfig, anonymize bool, anonymizer *anonymize.Anonymizer) []string {
|
|
var row []string
|
|
|
|
row = append(row, fmt.Sprintf("%d", rule.Priority))
|
|
|
|
if config.hasInvert {
|
|
row = append(row, formatIPRuleInvert(rule.Invert))
|
|
}
|
|
|
|
row = append(row, formatIPRuleAddress(rule.From, "all", anonymize, anonymizer))
|
|
|
|
if config.hasTo {
|
|
row = append(row, formatIPRuleAddress(rule.To, "-", anonymize, anonymizer))
|
|
}
|
|
|
|
if config.hasMark {
|
|
row = append(row, formatIPRuleMark(rule.Mark, rule.Mask))
|
|
}
|
|
|
|
if config.hasIIF {
|
|
row = append(row, formatIPRuleInterface(rule.IIF))
|
|
}
|
|
|
|
if config.hasOIF {
|
|
row = append(row, formatIPRuleInterface(rule.OIF))
|
|
}
|
|
|
|
row = append(row, rule.Table)
|
|
|
|
row = append(row, formatIPRuleAction(rule.Action))
|
|
|
|
if config.hasSuppressPlen {
|
|
row = append(row, formatIPRuleSuppressPlen(rule.SuppressPlen))
|
|
}
|
|
|
|
return row
|
|
}
|
|
|
|
func formatIPRuleInvert(invert bool) string {
|
|
if invert {
|
|
return "not"
|
|
}
|
|
return "-"
|
|
}
|
|
|
|
func formatIPRuleAction(action string) string {
|
|
if action == "unspec" {
|
|
return "lookup"
|
|
}
|
|
return action
|
|
}
|
|
|
|
func formatIPRuleSuppressPlen(suppressPlen int) string {
|
|
if suppressPlen >= 0 {
|
|
return fmt.Sprintf("%d", suppressPlen)
|
|
}
|
|
return "-"
|
|
}
|
|
|
|
func formatIPRuleAddress(prefix netip.Prefix, defaultVal string, anonymize bool, anonymizer *anonymize.Anonymizer) string {
|
|
if !prefix.IsValid() {
|
|
return defaultVal
|
|
}
|
|
|
|
if anonymize {
|
|
anonymizedIP := anonymizer.AnonymizeIP(prefix.Addr())
|
|
return fmt.Sprintf("%s/%d", anonymizedIP, prefix.Bits())
|
|
}
|
|
return prefix.String()
|
|
}
|
|
|
|
func formatIPRuleMark(mark, mask uint32) string {
|
|
if mark == 0 {
|
|
return "-"
|
|
}
|
|
if mask != 0 {
|
|
return fmt.Sprintf("0x%x/0x%x", mark, mask)
|
|
}
|
|
return fmt.Sprintf("0x%x", mark)
|
|
}
|
|
|
|
func formatIPRuleInterface(iface string) string {
|
|
if iface == "" {
|
|
return "-"
|
|
}
|
|
return iface
|
|
}
|