@@ -27,10 +27,12 @@ import (
27
27
28
28
kubespanadapter "github.com/siderolabs/talos/internal/app/machined/pkg/adapters/kubespan"
29
29
"github.com/siderolabs/talos/pkg/machinery/constants"
30
+ "github.com/siderolabs/talos/pkg/machinery/kernel"
30
31
"github.com/siderolabs/talos/pkg/machinery/nethelpers"
31
32
"github.com/siderolabs/talos/pkg/machinery/resources/config"
32
33
"github.com/siderolabs/talos/pkg/machinery/resources/kubespan"
33
34
"github.com/siderolabs/talos/pkg/machinery/resources/network"
35
+ "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
34
36
)
35
37
36
38
// DefaultPeerReconcileInterval is interval between peer status reconciliation on timer.
@@ -108,6 +110,10 @@ func (ctrl *ManagerController) Outputs() []controller.Output {
108
110
Type : kubespan .PeerStatusType ,
109
111
Kind : controller .OutputExclusive ,
110
112
},
113
+ {
114
+ Type : runtime .KernelParamSpecType ,
115
+ Kind : controller .OutputShared ,
116
+ },
111
117
}
112
118
}
113
119
@@ -371,13 +377,15 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
371
377
spec .Policy = nethelpers .VerdictAccept
372
378
373
379
spec .Rules = []network.NfTablesRule {
380
+ // Accept outgoing WireGuard packets.
374
381
{
375
382
MatchMark : & network.NfTablesMark {
376
383
Mask : constants .KubeSpanDefaultFirewallMask ,
377
384
Value : constants .KubeSpanDefaultFirewallMark ,
378
385
},
379
386
Verdict : pointer .To (nethelpers .VerdictAccept ),
380
387
},
388
+ // Mark packets to be sent over the KubeSpan link.
381
389
{
382
390
MatchDestinationAddress : & network.NfTablesAddressMatch {
383
391
IncludeSubnets : allowedIPsSet .Prefixes (),
@@ -388,6 +396,35 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
388
396
},
389
397
Verdict : pointer .To (nethelpers .VerdictAccept ),
390
398
},
399
+ // Remove KubeSpan mark from packets not sent to KubeSpan peers or received from them.
400
+ // This is typically the case when deencapsulated VXLAN packets retain envelope's fwmark, thus causing a routing loop.
401
+ {
402
+ MatchSourceAddress : & network.NfTablesAddressMatch {
403
+ Invert : true ,
404
+ IncludeSubnets : allowedIPsSet .Prefixes (),
405
+ },
406
+ MatchMark : & network.NfTablesMark {
407
+ Mask : constants .KubeSpanDefaultForceFirewallMark ,
408
+ Value : constants .KubeSpanDefaultForceFirewallMark ,
409
+ },
410
+ SetMark : & network.NfTablesMark {
411
+ Mask : 0xffffffff ,
412
+ Xor : constants .KubeSpanDefaultForceFirewallMark ,
413
+ },
414
+ Verdict : pointer .To (nethelpers .VerdictAccept ),
415
+ },
416
+ // Mark incoming packets from the KubeSpan link for rp_filter to find the correct routing table.
417
+ {
418
+ MatchIIfName : & network.NfTablesIfNameMatch {
419
+ InterfaceNames : []string {constants .KubeSpanLinkName },
420
+ Operator : nethelpers .OperatorEqual ,
421
+ },
422
+ SetMark : & network.NfTablesMark {
423
+ Mask : ^ uint32 (constants .KubeSpanDefaultFirewallMask ),
424
+ Xor : constants .KubeSpanDefaultForceFirewallMark ,
425
+ },
426
+ Verdict : pointer .To (nethelpers .VerdictAccept ),
427
+ },
391
428
}
392
429
393
430
return nil
@@ -554,6 +591,17 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
554
591
return fmt .Errorf ("error modifying link spec: %w" , err )
555
592
}
556
593
594
+ if err = safe .WriterModify (ctx , r , runtime .NewKernelParamSpec (
595
+ runtime .NamespaceName ,
596
+ kernel .Sysctl + ".net.ipv4.conf." + constants .KubeSpanLinkName + ".src_valid_mark" ,
597
+ ), func (res * runtime.KernelParamSpec ) error {
598
+ res .TypedSpec ().Value = "1"
599
+
600
+ return nil
601
+ }); err != nil {
602
+ return err
603
+ }
604
+
557
605
if rulesMgr == nil {
558
606
rulesMgr = ctrl .RulesManagerFactory (constants .KubeSpanDefaultRoutingTable , constants .KubeSpanDefaultForceFirewallMark , constants .KubeSpanDefaultFirewallMask )
559
607
@@ -591,6 +639,10 @@ func (ctrl *ManagerController) cleanup(ctx context.Context, r controller.Runtime
591
639
namespace : kubespan .NamespaceName ,
592
640
typ : kubespan .PeerStatusType ,
593
641
},
642
+ {
643
+ namespace : runtime .NamespaceName ,
644
+ typ : runtime .KernelParamSpecType ,
645
+ },
594
646
} {
595
647
// list keys for cleanup
596
648
list , err := r .List (ctx , resource .NewMetadata (item .namespace , item .typ , "" , resource .VersionUndefined ))
0 commit comments