From 457d1d43520d1d4ba5679eb54bf7b833ec1ff4ff Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Tue, 14 Jan 2025 19:12:25 +0100 Subject: [PATCH] fix: fix reverse routing for KubeSpan This allows it to not come down when rp_filter is enabled. Fixes #9814 Signed-off-by: Dmitry Sharshakov --- .../pkg/controllers/kubespan/manager.go | 30 +++++++++++++++++++ .../pkg/controllers/kubespan/manager_test.go | 19 ++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/internal/app/machined/pkg/controllers/kubespan/manager.go b/internal/app/machined/pkg/controllers/kubespan/manager.go index 1ca0e473d3..98c2a14d12 100644 --- a/internal/app/machined/pkg/controllers/kubespan/manager.go +++ b/internal/app/machined/pkg/controllers/kubespan/manager.go @@ -27,10 +27,12 @@ import ( kubespanadapter "github.com/siderolabs/talos/internal/app/machined/pkg/adapters/kubespan" "github.com/siderolabs/talos/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/kernel" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/config" "github.com/siderolabs/talos/pkg/machinery/resources/kubespan" "github.com/siderolabs/talos/pkg/machinery/resources/network" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) // DefaultPeerReconcileInterval is interval between peer status reconciliation on timer. @@ -108,6 +110,10 @@ func (ctrl *ManagerController) Outputs() []controller.Output { Type: kubespan.PeerStatusType, Kind: controller.OutputExclusive, }, + { + Type: runtime.KernelParamSpecType, + Kind: controller.OutputShared, + }, } } @@ -378,6 +384,7 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo }, Verdict: pointer.To(nethelpers.VerdictAccept), }, + // Mark packets to be sent over the KubeSpan link. { MatchDestinationAddress: &network.NfTablesAddressMatch{ IncludeSubnets: allowedIPsSet.Prefixes(), @@ -388,6 +395,18 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo }, Verdict: pointer.To(nethelpers.VerdictAccept), }, + // Mark incoming packets from the KubeSpan link for rp_filter to find the correct routing table. + { + MatchIIfName: &network.NfTablesIfNameMatch{ + InterfaceNames: []string{constants.KubeSpanLinkName}, + Operator: nethelpers.OperatorEqual, + }, + SetMark: &network.NfTablesMark{ + Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), + Xor: constants.KubeSpanDefaultForceFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, } return nil @@ -554,6 +573,17 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo return fmt.Errorf("error modifying link spec: %w", err) } + if err = safe.WriterModify(ctx, r, runtime.NewKernelParamSpec( + runtime.NamespaceName, + kernel.Sysctl+"."+"net.ipv4.conf."+constants.KubeSpanLinkName+".src_valid_mark", + ), func(res *runtime.KernelParamSpec) error { + res.TypedSpec().Value = "1" + + return nil + }); err != nil { + return err + } + if rulesMgr == nil { rulesMgr = ctrl.RulesManagerFactory(constants.KubeSpanDefaultRoutingTable, constants.KubeSpanDefaultForceFirewallMark, constants.KubeSpanDefaultFirewallMask) diff --git a/internal/app/machined/pkg/controllers/kubespan/manager_test.go b/internal/app/machined/pkg/controllers/kubespan/manager_test.go index 606c496709..819171164e 100644 --- a/internal/app/machined/pkg/controllers/kubespan/manager_test.go +++ b/internal/app/machined/pkg/controllers/kubespan/manager_test.go @@ -244,9 +244,9 @@ func (suite *ManagerSuite) TestReconcile() { asrt.Equal(nethelpers.ChainPriorityFilter, spec.Priority) asrt.Equal(nethelpers.VerdictAccept, spec.Policy) - asrt.Len(spec.Rules, 2) + asrt.Len(spec.Rules, 3) - if len(spec.Rules) != 2 { + if len(spec.Rules) != 3 { return } @@ -277,6 +277,21 @@ func (suite *ManagerSuite) TestReconcile() { }, spec.Rules[1], ) + + asrt.Equal( + network.NfTablesRule{ + MatchIIfName: &network.NfTablesIfNameMatch{ + InterfaceNames: []string{constants.KubeSpanLinkName}, + Operator: nethelpers.OperatorEqual, + }, + SetMark: &network.NfTablesMark{ + Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), + Xor: constants.KubeSpanDefaultForceFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + spec.Rules[2], + ) }, )