util/linuxfw,wgengine/router: add new netfilter rules for HA ingresses (#15896)

Add new rules to update DNAT rules for Kubernetes operator's
HA ingress where it's expected that rules will be added/removed
frequently (so we don't want to keep old rules around or rewrite
existing rules unnecessarily):
- allow deleting DNAT rules using metadata lookup
- allow inserting DNAT rules if they don't already
exist (using metadata lookup)

Updates tailscale/tailscale#15895

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
Irbe Krumina
2025-05-12 17:26:23 +01:00
committed by GitHub
parent d6dd74fe0e
commit 2c16fcaa06
7 changed files with 559 additions and 40 deletions

View File

@@ -107,6 +107,12 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
if err != nil {
return err
}
rule := dnatRuleForChain(nat, preroutingCh, origDst, dst, nil)
n.conn.InsertRule(rule)
return n.conn.Flush()
}
func dnatRuleForChain(t *nftables.Table, ch *nftables.Chain, origDst, dst netip.Addr, meta []byte) *nftables.Rule {
var daddrOffset, fam, dadderLen uint32
if origDst.Is4() {
daddrOffset = 16
@@ -117,9 +123,9 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
dadderLen = 16
fam = unix.NFPROTO_IPV6
}
dnatRule := &nftables.Rule{
Table: nat,
Chain: preroutingCh,
rule := &nftables.Rule{
Table: t,
Chain: ch,
Exprs: []expr.Any{
&expr.Payload{
DestRegister: 1,
@@ -143,8 +149,10 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
},
},
}
n.conn.InsertRule(dnatRule)
return n.conn.Flush()
if len(meta) > 0 {
rule.UserData = meta
}
return rule
}
// DNATWithLoadBalancer currently just forwards all traffic destined for origDst
@@ -555,6 +563,8 @@ type NetfilterRunner interface {
EnsurePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error
DeletePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error
EnsureDNATRuleForSvc(svcName string, origDst, dst netip.Addr) error
DeleteDNATRuleForSvc(svcName string, origDst, dst netip.Addr) error
DeleteSvc(svc, tun string, targetIPs []netip.Addr, pm []PortMap) error