|
|
|
|
@@ -16,6 +16,7 @@ import (
|
|
|
|
|
nberrors "github.com/netbirdio/netbird/client/errors"
|
|
|
|
|
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
|
|
|
|
"github.com/netbirdio/netbird/client/internal/acl/id"
|
|
|
|
|
"github.com/netbirdio/netbird/client/internal/routemanager/ipfwdstate"
|
|
|
|
|
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
|
|
|
|
|
"github.com/netbirdio/netbird/client/internal/statemanager"
|
|
|
|
|
nbnet "github.com/netbirdio/netbird/util/net"
|
|
|
|
|
@@ -23,22 +24,36 @@ import (
|
|
|
|
|
|
|
|
|
|
// constants needed to manage and create iptable rules
|
|
|
|
|
const (
|
|
|
|
|
tableFilter = "filter"
|
|
|
|
|
tableNat = "nat"
|
|
|
|
|
tableMangle = "mangle"
|
|
|
|
|
tableFilter = "filter"
|
|
|
|
|
tableNat = "nat"
|
|
|
|
|
tableMangle = "mangle"
|
|
|
|
|
|
|
|
|
|
chainPOSTROUTING = "POSTROUTING"
|
|
|
|
|
chainPREROUTING = "PREROUTING"
|
|
|
|
|
chainRTNAT = "NETBIRD-RT-NAT"
|
|
|
|
|
chainRTFWD = "NETBIRD-RT-FWD"
|
|
|
|
|
chainRTFWDIN = "NETBIRD-RT-FWD-IN"
|
|
|
|
|
chainRTFWDOUT = "NETBIRD-RT-FWD-OUT"
|
|
|
|
|
chainRTPRE = "NETBIRD-RT-PRE"
|
|
|
|
|
chainRTRDR = "NETBIRD-RT-RDR"
|
|
|
|
|
routingFinalForwardJump = "ACCEPT"
|
|
|
|
|
routingFinalNatJump = "MASQUERADE"
|
|
|
|
|
|
|
|
|
|
jumpPre = "jump-pre"
|
|
|
|
|
jumpNat = "jump-nat"
|
|
|
|
|
matchSet = "--match-set"
|
|
|
|
|
jumpManglePre = "jump-mangle-pre"
|
|
|
|
|
jumpNatPre = "jump-nat-pre"
|
|
|
|
|
jumpNatPost = "jump-nat-post"
|
|
|
|
|
matchSet = "--match-set"
|
|
|
|
|
|
|
|
|
|
dnatSuffix = "_dnat"
|
|
|
|
|
snatSuffix = "_snat"
|
|
|
|
|
fwdSuffix = "_fwd"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type ruleInfo struct {
|
|
|
|
|
chain string
|
|
|
|
|
table string
|
|
|
|
|
rule []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type routeFilteringRuleParams struct {
|
|
|
|
|
Sources []netip.Prefix
|
|
|
|
|
Destination netip.Prefix
|
|
|
|
|
@@ -62,6 +77,7 @@ type router struct {
|
|
|
|
|
legacyManagement bool
|
|
|
|
|
|
|
|
|
|
stateManager *statemanager.Manager
|
|
|
|
|
ipFwdState *ipfwdstate.IPForwardingState
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newRouter(iptablesClient *iptables.IPTables, wgIface iFaceMapper) (*router, error) {
|
|
|
|
|
@@ -69,6 +85,7 @@ func newRouter(iptablesClient *iptables.IPTables, wgIface iFaceMapper) (*router,
|
|
|
|
|
iptablesClient: iptablesClient,
|
|
|
|
|
rules: make(map[string][]string),
|
|
|
|
|
wgIface: wgIface,
|
|
|
|
|
ipFwdState: ipfwdstate.NewIPForwardingState(),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.ipsetCounter = refcounter.New(
|
|
|
|
|
@@ -139,9 +156,9 @@ func (r *router) AddRouteFiltering(
|
|
|
|
|
var err error
|
|
|
|
|
if action == firewall.ActionDrop {
|
|
|
|
|
// after the established rule
|
|
|
|
|
err = r.iptablesClient.Insert(tableFilter, chainRTFWD, 2, rule...)
|
|
|
|
|
err = r.iptablesClient.Insert(tableFilter, chainRTFWDIN, 2, rule...)
|
|
|
|
|
} else {
|
|
|
|
|
err = r.iptablesClient.Append(tableFilter, chainRTFWD, rule...)
|
|
|
|
|
err = r.iptablesClient.Append(tableFilter, chainRTFWDIN, rule...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
@@ -156,12 +173,12 @@ func (r *router) AddRouteFiltering(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) DeleteRouteRule(rule firewall.Rule) error {
|
|
|
|
|
ruleKey := rule.GetRuleID()
|
|
|
|
|
ruleKey := rule.ID()
|
|
|
|
|
|
|
|
|
|
if rule, exists := r.rules[ruleKey]; exists {
|
|
|
|
|
setName := r.findSetNameInRule(rule)
|
|
|
|
|
|
|
|
|
|
if err := r.iptablesClient.Delete(tableFilter, chainRTFWD, rule...); err != nil {
|
|
|
|
|
if err := r.iptablesClient.Delete(tableFilter, chainRTFWDIN, rule...); err != nil {
|
|
|
|
|
return fmt.Errorf("delete route rule: %v", err)
|
|
|
|
|
}
|
|
|
|
|
delete(r.rules, ruleKey)
|
|
|
|
|
@@ -212,6 +229,10 @@ func (r *router) deleteIpSet(setName string) error {
|
|
|
|
|
|
|
|
|
|
// AddNatRule inserts an iptables rule pair into the nat chain
|
|
|
|
|
func (r *router) AddNatRule(pair firewall.RouterPair) error {
|
|
|
|
|
if err := r.ipFwdState.RequestForwarding(); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.legacyManagement {
|
|
|
|
|
log.Warnf("This peer is connected to a NetBird Management service with an older version. Allowing all traffic for %s", pair.Destination)
|
|
|
|
|
if err := r.addLegacyRouteRule(pair); err != nil {
|
|
|
|
|
@@ -238,6 +259,10 @@ func (r *router) AddNatRule(pair firewall.RouterPair) error {
|
|
|
|
|
|
|
|
|
|
// RemoveNatRule removes an iptables rule pair from forwarding and nat chains
|
|
|
|
|
func (r *router) RemoveNatRule(pair firewall.RouterPair) error {
|
|
|
|
|
if err := r.ipFwdState.ReleaseForwarding(); err != nil {
|
|
|
|
|
log.Errorf("%v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := r.removeNatRule(pair); err != nil {
|
|
|
|
|
return fmt.Errorf("remove nat rule: %w", err)
|
|
|
|
|
}
|
|
|
|
|
@@ -264,7 +289,7 @@ func (r *router) addLegacyRouteRule(pair firewall.RouterPair) error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rule := []string{"-s", pair.Source.String(), "-d", pair.Destination.String(), "-j", routingFinalForwardJump}
|
|
|
|
|
if err := r.iptablesClient.Append(tableFilter, chainRTFWD, rule...); err != nil {
|
|
|
|
|
if err := r.iptablesClient.Append(tableFilter, chainRTFWDIN, rule...); err != nil {
|
|
|
|
|
return fmt.Errorf("add legacy forwarding rule %s -> %s: %v", pair.Source, pair.Destination, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -277,7 +302,7 @@ func (r *router) removeLegacyRouteRule(pair firewall.RouterPair) error {
|
|
|
|
|
ruleKey := firewall.GenKey(firewall.ForwardingFormat, pair)
|
|
|
|
|
|
|
|
|
|
if rule, exists := r.rules[ruleKey]; exists {
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWD, rule...); err != nil {
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWDIN, rule...); err != nil {
|
|
|
|
|
return fmt.Errorf("remove legacy forwarding rule %s -> %s: %v", pair.Source, pair.Destination, err)
|
|
|
|
|
}
|
|
|
|
|
delete(r.rules, ruleKey)
|
|
|
|
|
@@ -305,7 +330,7 @@ func (r *router) RemoveAllLegacyRouteRules() error {
|
|
|
|
|
if !strings.HasPrefix(k, firewall.ForwardingFormatPrefix) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWD, rule...); err != nil {
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWDIN, rule...); err != nil {
|
|
|
|
|
merr = multierror.Append(merr, fmt.Errorf("remove legacy forwarding rule: %v", err))
|
|
|
|
|
} else {
|
|
|
|
|
delete(r.rules, k)
|
|
|
|
|
@@ -343,9 +368,11 @@ func (r *router) cleanUpDefaultForwardRules() error {
|
|
|
|
|
chain string
|
|
|
|
|
table string
|
|
|
|
|
}{
|
|
|
|
|
{chainRTFWD, tableFilter},
|
|
|
|
|
{chainRTNAT, tableNat},
|
|
|
|
|
{chainRTFWDIN, tableFilter},
|
|
|
|
|
{chainRTFWDOUT, tableFilter},
|
|
|
|
|
{chainRTPRE, tableMangle},
|
|
|
|
|
{chainRTNAT, tableNat},
|
|
|
|
|
{chainRTRDR, tableNat},
|
|
|
|
|
} {
|
|
|
|
|
ok, err := r.iptablesClient.ChainExists(chainInfo.table, chainInfo.chain)
|
|
|
|
|
if err != nil {
|
|
|
|
|
@@ -365,16 +392,22 @@ func (r *router) createContainers() error {
|
|
|
|
|
chain string
|
|
|
|
|
table string
|
|
|
|
|
}{
|
|
|
|
|
{chainRTFWD, tableFilter},
|
|
|
|
|
{chainRTFWDIN, tableFilter},
|
|
|
|
|
{chainRTFWDOUT, tableFilter},
|
|
|
|
|
{chainRTPRE, tableMangle},
|
|
|
|
|
{chainRTNAT, tableNat},
|
|
|
|
|
{chainRTRDR, tableNat},
|
|
|
|
|
} {
|
|
|
|
|
if err := r.createAndSetupChain(chainInfo.chain); err != nil {
|
|
|
|
|
if err := r.iptablesClient.NewChain(chainInfo.table, chainInfo.chain); err != nil {
|
|
|
|
|
return fmt.Errorf("create chain %s in table %s: %w", chainInfo.chain, chainInfo.table, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := r.insertEstablishedRule(chainRTFWD); err != nil {
|
|
|
|
|
if err := r.insertEstablishedRule(chainRTFWDIN); err != nil {
|
|
|
|
|
return fmt.Errorf("insert established rule: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := r.insertEstablishedRule(chainRTFWDOUT); err != nil {
|
|
|
|
|
return fmt.Errorf("insert established rule: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -415,27 +448,6 @@ func (r *router) addPostroutingRules() error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) createAndSetupChain(chain string) error {
|
|
|
|
|
table := r.getTableForChain(chain)
|
|
|
|
|
|
|
|
|
|
if err := r.iptablesClient.NewChain(table, chain); err != nil {
|
|
|
|
|
return fmt.Errorf("failed creating chain %s, error: %v", chain, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) getTableForChain(chain string) string {
|
|
|
|
|
switch chain {
|
|
|
|
|
case chainRTNAT:
|
|
|
|
|
return tableNat
|
|
|
|
|
case chainRTPRE:
|
|
|
|
|
return tableMangle
|
|
|
|
|
default:
|
|
|
|
|
return tableFilter
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) insertEstablishedRule(chain string) error {
|
|
|
|
|
establishedRule := getConntrackEstablished()
|
|
|
|
|
|
|
|
|
|
@@ -454,28 +466,43 @@ func (r *router) addJumpRules() error {
|
|
|
|
|
// Jump to NAT chain
|
|
|
|
|
natRule := []string{"-j", chainRTNAT}
|
|
|
|
|
if err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil {
|
|
|
|
|
return fmt.Errorf("add nat jump rule: %v", err)
|
|
|
|
|
return fmt.Errorf("add nat postrouting jump rule: %v", err)
|
|
|
|
|
}
|
|
|
|
|
r.rules[jumpNat] = natRule
|
|
|
|
|
r.rules[jumpNatPost] = natRule
|
|
|
|
|
|
|
|
|
|
// Jump to prerouting chain
|
|
|
|
|
// Jump to mangle prerouting chain
|
|
|
|
|
preRule := []string{"-j", chainRTPRE}
|
|
|
|
|
if err := r.iptablesClient.Insert(tableMangle, chainPREROUTING, 1, preRule...); err != nil {
|
|
|
|
|
return fmt.Errorf("add prerouting jump rule: %v", err)
|
|
|
|
|
return fmt.Errorf("add mangle prerouting jump rule: %v", err)
|
|
|
|
|
}
|
|
|
|
|
r.rules[jumpPre] = preRule
|
|
|
|
|
r.rules[jumpManglePre] = preRule
|
|
|
|
|
|
|
|
|
|
// Jump to nat prerouting chain
|
|
|
|
|
rdrRule := []string{"-j", chainRTRDR}
|
|
|
|
|
if err := r.iptablesClient.Insert(tableNat, chainPREROUTING, 1, rdrRule...); err != nil {
|
|
|
|
|
return fmt.Errorf("add nat prerouting jump rule: %v", err)
|
|
|
|
|
}
|
|
|
|
|
r.rules[jumpNatPre] = rdrRule
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) cleanJumpRules() error {
|
|
|
|
|
for _, ruleKey := range []string{jumpNat, jumpPre} {
|
|
|
|
|
for _, ruleKey := range []string{jumpNatPost, jumpManglePre, jumpNatPre} {
|
|
|
|
|
if rule, exists := r.rules[ruleKey]; exists {
|
|
|
|
|
table := tableNat
|
|
|
|
|
chain := chainPOSTROUTING
|
|
|
|
|
if ruleKey == jumpPre {
|
|
|
|
|
var table, chain string
|
|
|
|
|
switch ruleKey {
|
|
|
|
|
case jumpNatPost:
|
|
|
|
|
table = tableNat
|
|
|
|
|
chain = chainPOSTROUTING
|
|
|
|
|
case jumpManglePre:
|
|
|
|
|
table = tableMangle
|
|
|
|
|
chain = chainPREROUTING
|
|
|
|
|
case jumpNatPre:
|
|
|
|
|
table = tableNat
|
|
|
|
|
chain = chainPREROUTING
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("unknown jump rule: %s", ruleKey)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(table, chain, rule...); err != nil {
|
|
|
|
|
@@ -520,6 +547,8 @@ func (r *router) addNatRule(pair firewall.RouterPair) error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.rules[ruleKey] = rule
|
|
|
|
|
|
|
|
|
|
r.updateState()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -535,6 +564,7 @@ func (r *router) removeNatRule(pair firewall.RouterPair) error {
|
|
|
|
|
log.Debugf("marking rule %s not found", ruleKey)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.updateState()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -564,6 +594,137 @@ func (r *router) updateState() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
|
|
|
|
|
if err := r.ipFwdState.RequestForwarding(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ruleKey := rule.ID()
|
|
|
|
|
if _, exists := r.rules[ruleKey+dnatSuffix]; exists {
|
|
|
|
|
return rule, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toDestination := rule.TranslatedAddress.String()
|
|
|
|
|
switch {
|
|
|
|
|
case len(rule.TranslatedPort.Values) == 0:
|
|
|
|
|
// no translated port, use original port
|
|
|
|
|
case len(rule.TranslatedPort.Values) == 1:
|
|
|
|
|
toDestination += fmt.Sprintf(":%d", rule.TranslatedPort.Values[0])
|
|
|
|
|
case rule.TranslatedPort.IsRange && len(rule.TranslatedPort.Values) == 2:
|
|
|
|
|
// need the "/originalport" suffix to avoid dnat port randomization
|
|
|
|
|
toDestination += fmt.Sprintf(":%d-%d/%d", rule.TranslatedPort.Values[0], rule.TranslatedPort.Values[1], rule.DestinationPort.Values[0])
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("invalid translated port: %v", rule.TranslatedPort)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
proto := strings.ToLower(string(rule.Protocol))
|
|
|
|
|
|
|
|
|
|
rules := make(map[string]ruleInfo, 3)
|
|
|
|
|
|
|
|
|
|
// DNAT rule
|
|
|
|
|
dnatRule := []string{
|
|
|
|
|
"!", "-i", r.wgIface.Name(),
|
|
|
|
|
"-p", proto,
|
|
|
|
|
"-j", "DNAT",
|
|
|
|
|
"--to-destination", toDestination,
|
|
|
|
|
}
|
|
|
|
|
dnatRule = append(dnatRule, applyPort("--dport", &rule.DestinationPort)...)
|
|
|
|
|
rules[ruleKey+dnatSuffix] = ruleInfo{
|
|
|
|
|
table: tableNat,
|
|
|
|
|
chain: chainRTRDR,
|
|
|
|
|
rule: dnatRule,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SNAT rule
|
|
|
|
|
snatRule := []string{
|
|
|
|
|
"-o", r.wgIface.Name(),
|
|
|
|
|
"-p", proto,
|
|
|
|
|
"-d", rule.TranslatedAddress.String(),
|
|
|
|
|
"-j", "MASQUERADE",
|
|
|
|
|
}
|
|
|
|
|
snatRule = append(snatRule, applyPort("--dport", &rule.TranslatedPort)...)
|
|
|
|
|
rules[ruleKey+snatSuffix] = ruleInfo{
|
|
|
|
|
table: tableNat,
|
|
|
|
|
chain: chainRTNAT,
|
|
|
|
|
rule: snatRule,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Forward filtering rule, if fwd policy is DROP
|
|
|
|
|
forwardRule := []string{
|
|
|
|
|
"-o", r.wgIface.Name(),
|
|
|
|
|
"-p", proto,
|
|
|
|
|
"-d", rule.TranslatedAddress.String(),
|
|
|
|
|
"-j", "ACCEPT",
|
|
|
|
|
}
|
|
|
|
|
forwardRule = append(forwardRule, applyPort("--dport", &rule.TranslatedPort)...)
|
|
|
|
|
rules[ruleKey+fwdSuffix] = ruleInfo{
|
|
|
|
|
table: tableFilter,
|
|
|
|
|
chain: chainRTFWDOUT,
|
|
|
|
|
rule: forwardRule,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for key, ruleInfo := range rules {
|
|
|
|
|
if err := r.iptablesClient.Append(ruleInfo.table, ruleInfo.chain, ruleInfo.rule...); err != nil {
|
|
|
|
|
if rollbackErr := r.rollbackRules(rules); rollbackErr != nil {
|
|
|
|
|
log.Errorf("rollback failed: %v", rollbackErr)
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("add rule %s: %w", key, err)
|
|
|
|
|
}
|
|
|
|
|
r.rules[key] = ruleInfo.rule
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.updateState()
|
|
|
|
|
return rule, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) rollbackRules(rules map[string]ruleInfo) error {
|
|
|
|
|
var merr *multierror.Error
|
|
|
|
|
for key, ruleInfo := range rules {
|
|
|
|
|
if err := r.iptablesClient.DeleteIfExists(ruleInfo.table, ruleInfo.chain, ruleInfo.rule...); err != nil {
|
|
|
|
|
merr = multierror.Append(merr, fmt.Errorf("rollback rule %s: %w", key, err))
|
|
|
|
|
// On rollback error, add to rules map for next cleanup
|
|
|
|
|
r.rules[key] = ruleInfo.rule
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if merr != nil {
|
|
|
|
|
r.updateState()
|
|
|
|
|
}
|
|
|
|
|
return nberrors.FormatErrorOrNil(merr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *router) DeleteDNATRule(rule firewall.Rule) error {
|
|
|
|
|
if err := r.ipFwdState.ReleaseForwarding(); err != nil {
|
|
|
|
|
log.Errorf("%v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ruleKey := rule.ID()
|
|
|
|
|
|
|
|
|
|
var merr *multierror.Error
|
|
|
|
|
if dnatRule, exists := r.rules[ruleKey+dnatSuffix]; exists {
|
|
|
|
|
if err := r.iptablesClient.Delete(tableNat, chainRTRDR, dnatRule...); err != nil {
|
|
|
|
|
merr = multierror.Append(merr, fmt.Errorf("delete DNAT rule: %w", err))
|
|
|
|
|
}
|
|
|
|
|
delete(r.rules, ruleKey+dnatSuffix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if snatRule, exists := r.rules[ruleKey+snatSuffix]; exists {
|
|
|
|
|
if err := r.iptablesClient.Delete(tableNat, chainRTNAT, snatRule...); err != nil {
|
|
|
|
|
merr = multierror.Append(merr, fmt.Errorf("delete SNAT rule: %w", err))
|
|
|
|
|
}
|
|
|
|
|
delete(r.rules, ruleKey+snatSuffix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if fwdRule, exists := r.rules[ruleKey+fwdSuffix]; exists {
|
|
|
|
|
if err := r.iptablesClient.Delete(tableFilter, chainRTFWDIN, fwdRule...); err != nil {
|
|
|
|
|
merr = multierror.Append(merr, fmt.Errorf("delete forward rule: %w", err))
|
|
|
|
|
}
|
|
|
|
|
delete(r.rules, ruleKey+fwdSuffix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.updateState()
|
|
|
|
|
return nberrors.FormatErrorOrNil(merr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func genRouteFilteringRuleSpec(params routeFilteringRuleParams) []string {
|
|
|
|
|
var rule []string
|
|
|
|
|
|
|
|
|
|
|